root/drivers/power/supply/bq27xxx_battery_i2c.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bq27xxx_battery_irq_handler_thread
  2. bq27xxx_battery_i2c_read
  3. bq27xxx_battery_i2c_write
  4. bq27xxx_battery_i2c_bulk_read
  5. bq27xxx_battery_i2c_bulk_write
  6. bq27xxx_battery_i2c_probe
  7. bq27xxx_battery_i2c_remove

   1 /*
   2  * BQ27xxx battery monitor I2C driver
   3  *
   4  * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
   5  *      Andrew F. Davis <afd@ti.com>
   6  *
   7  * This program is free software; you can redistribute it and/or modify
   8  * it under the terms of the GNU General Public License version 2 as
   9  * published by the Free Software Foundation.
  10  *
  11  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  12  * kind, whether express or implied; without even the implied warranty
  13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  * GNU General Public License for more details.
  15  */
  16 
  17 #include <linux/i2c.h>
  18 #include <linux/interrupt.h>
  19 #include <linux/module.h>
  20 #include <asm/unaligned.h>
  21 
  22 #include <linux/power/bq27xxx_battery.h>
  23 
  24 static DEFINE_IDR(battery_id);
  25 static DEFINE_MUTEX(battery_mutex);
  26 
  27 static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data)
  28 {
  29         struct bq27xxx_device_info *di = data;
  30 
  31         bq27xxx_battery_update(di);
  32 
  33         return IRQ_HANDLED;
  34 }
  35 
  36 static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg,
  37                                     bool single)
  38 {
  39         struct i2c_client *client = to_i2c_client(di->dev);
  40         struct i2c_msg msg[2];
  41         u8 data[2];
  42         int ret;
  43 
  44         if (!client->adapter)
  45                 return -ENODEV;
  46 
  47         msg[0].addr = client->addr;
  48         msg[0].flags = 0;
  49         msg[0].buf = &reg;
  50         msg[0].len = sizeof(reg);
  51         msg[1].addr = client->addr;
  52         msg[1].flags = I2C_M_RD;
  53         msg[1].buf = data;
  54         if (single)
  55                 msg[1].len = 1;
  56         else
  57                 msg[1].len = 2;
  58 
  59         ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
  60         if (ret < 0)
  61                 return ret;
  62 
  63         if (!single)
  64                 ret = get_unaligned_le16(data);
  65         else
  66                 ret = data[0];
  67 
  68         return ret;
  69 }
  70 
  71 static int bq27xxx_battery_i2c_write(struct bq27xxx_device_info *di, u8 reg,
  72                                      int value, bool single)
  73 {
  74         struct i2c_client *client = to_i2c_client(di->dev);
  75         struct i2c_msg msg;
  76         u8 data[4];
  77         int ret;
  78 
  79         if (!client->adapter)
  80                 return -ENODEV;
  81 
  82         data[0] = reg;
  83         if (single) {
  84                 data[1] = (u8) value;
  85                 msg.len = 2;
  86         } else {
  87                 put_unaligned_le16(value, &data[1]);
  88                 msg.len = 3;
  89         }
  90 
  91         msg.buf = data;
  92         msg.addr = client->addr;
  93         msg.flags = 0;
  94 
  95         ret = i2c_transfer(client->adapter, &msg, 1);
  96         if (ret < 0)
  97                 return ret;
  98         if (ret != 1)
  99                 return -EINVAL;
 100         return 0;
 101 }
 102 
 103 static int bq27xxx_battery_i2c_bulk_read(struct bq27xxx_device_info *di, u8 reg,
 104                                          u8 *data, int len)
 105 {
 106         struct i2c_client *client = to_i2c_client(di->dev);
 107         int ret;
 108 
 109         if (!client->adapter)
 110                 return -ENODEV;
 111 
 112         ret = i2c_smbus_read_i2c_block_data(client, reg, len, data);
 113         if (ret < 0)
 114                 return ret;
 115         if (ret != len)
 116                 return -EINVAL;
 117         return 0;
 118 }
 119 
 120 static int bq27xxx_battery_i2c_bulk_write(struct bq27xxx_device_info *di,
 121                                           u8 reg, u8 *data, int len)
 122 {
 123         struct i2c_client *client = to_i2c_client(di->dev);
 124         struct i2c_msg msg;
 125         u8 buf[33];
 126         int ret;
 127 
 128         if (!client->adapter)
 129                 return -ENODEV;
 130 
 131         buf[0] = reg;
 132         memcpy(&buf[1], data, len);
 133 
 134         msg.buf = buf;
 135         msg.addr = client->addr;
 136         msg.flags = 0;
 137         msg.len = len + 1;
 138 
 139         ret = i2c_transfer(client->adapter, &msg, 1);
 140         if (ret < 0)
 141                 return ret;
 142         if (ret != 1)
 143                 return -EINVAL;
 144         return 0;
 145 }
 146 
 147 static int bq27xxx_battery_i2c_probe(struct i2c_client *client,
 148                                      const struct i2c_device_id *id)
 149 {
 150         struct bq27xxx_device_info *di;
 151         int ret;
 152         char *name;
 153         int num;
 154 
 155         /* Get new ID for the new battery device */
 156         mutex_lock(&battery_mutex);
 157         num = idr_alloc(&battery_id, client, 0, 0, GFP_KERNEL);
 158         mutex_unlock(&battery_mutex);
 159         if (num < 0)
 160                 return num;
 161 
 162         name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num);
 163         if (!name)
 164                 goto err_mem;
 165 
 166         di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL);
 167         if (!di)
 168                 goto err_mem;
 169 
 170         di->id = num;
 171         di->dev = &client->dev;
 172         di->chip = id->driver_data;
 173         di->name = name;
 174 
 175         di->bus.read = bq27xxx_battery_i2c_read;
 176         di->bus.write = bq27xxx_battery_i2c_write;
 177         di->bus.read_bulk = bq27xxx_battery_i2c_bulk_read;
 178         di->bus.write_bulk = bq27xxx_battery_i2c_bulk_write;
 179 
 180         ret = bq27xxx_battery_setup(di);
 181         if (ret)
 182                 goto err_failed;
 183 
 184         /* Schedule a polling after about 1 min */
 185         schedule_delayed_work(&di->work, 60 * HZ);
 186 
 187         i2c_set_clientdata(client, di);
 188 
 189         if (client->irq) {
 190                 ret = devm_request_threaded_irq(&client->dev, client->irq,
 191                                 NULL, bq27xxx_battery_irq_handler_thread,
 192                                 IRQF_ONESHOT,
 193                                 di->name, di);
 194                 if (ret) {
 195                         dev_err(&client->dev,
 196                                 "Unable to register IRQ %d error %d\n",
 197                                 client->irq, ret);
 198                         return ret;
 199                 }
 200         }
 201 
 202         return 0;
 203 
 204 err_mem:
 205         ret = -ENOMEM;
 206 
 207 err_failed:
 208         mutex_lock(&battery_mutex);
 209         idr_remove(&battery_id, num);
 210         mutex_unlock(&battery_mutex);
 211 
 212         return ret;
 213 }
 214 
 215 static int bq27xxx_battery_i2c_remove(struct i2c_client *client)
 216 {
 217         struct bq27xxx_device_info *di = i2c_get_clientdata(client);
 218 
 219         bq27xxx_battery_teardown(di);
 220 
 221         mutex_lock(&battery_mutex);
 222         idr_remove(&battery_id, di->id);
 223         mutex_unlock(&battery_mutex);
 224 
 225         return 0;
 226 }
 227 
 228 static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
 229         { "bq27200", BQ27000 },
 230         { "bq27210", BQ27010 },
 231         { "bq27500", BQ2750X },
 232         { "bq27510", BQ2751X },
 233         { "bq27520", BQ2752X },
 234         { "bq27500-1", BQ27500 },
 235         { "bq27510g1", BQ27510G1 },
 236         { "bq27510g2", BQ27510G2 },
 237         { "bq27510g3", BQ27510G3 },
 238         { "bq27520g1", BQ27520G1 },
 239         { "bq27520g2", BQ27520G2 },
 240         { "bq27520g3", BQ27520G3 },
 241         { "bq27520g4", BQ27520G4 },
 242         { "bq27521", BQ27521 },
 243         { "bq27530", BQ27530 },
 244         { "bq27531", BQ27531 },
 245         { "bq27541", BQ27541 },
 246         { "bq27542", BQ27542 },
 247         { "bq27546", BQ27546 },
 248         { "bq27742", BQ27742 },
 249         { "bq27545", BQ27545 },
 250         { "bq27411", BQ27411 },
 251         { "bq27421", BQ27421 },
 252         { "bq27425", BQ27425 },
 253         { "bq27426", BQ27426 },
 254         { "bq27441", BQ27441 },
 255         { "bq27621", BQ27621 },
 256         {},
 257 };
 258 MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
 259 
 260 #ifdef CONFIG_OF
 261 static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
 262         { .compatible = "ti,bq27200" },
 263         { .compatible = "ti,bq27210" },
 264         { .compatible = "ti,bq27500" },
 265         { .compatible = "ti,bq27510" },
 266         { .compatible = "ti,bq27520" },
 267         { .compatible = "ti,bq27500-1" },
 268         { .compatible = "ti,bq27510g1" },
 269         { .compatible = "ti,bq27510g2" },
 270         { .compatible = "ti,bq27510g3" },
 271         { .compatible = "ti,bq27520g1" },
 272         { .compatible = "ti,bq27520g2" },
 273         { .compatible = "ti,bq27520g3" },
 274         { .compatible = "ti,bq27520g4" },
 275         { .compatible = "ti,bq27521" },
 276         { .compatible = "ti,bq27530" },
 277         { .compatible = "ti,bq27531" },
 278         { .compatible = "ti,bq27541" },
 279         { .compatible = "ti,bq27542" },
 280         { .compatible = "ti,bq27546" },
 281         { .compatible = "ti,bq27742" },
 282         { .compatible = "ti,bq27545" },
 283         { .compatible = "ti,bq27411" },
 284         { .compatible = "ti,bq27421" },
 285         { .compatible = "ti,bq27425" },
 286         { .compatible = "ti,bq27426" },
 287         { .compatible = "ti,bq27441" },
 288         { .compatible = "ti,bq27621" },
 289         {},
 290 };
 291 MODULE_DEVICE_TABLE(of, bq27xxx_battery_i2c_of_match_table);
 292 #endif
 293 
 294 static struct i2c_driver bq27xxx_battery_i2c_driver = {
 295         .driver = {
 296                 .name = "bq27xxx-battery",
 297                 .of_match_table = of_match_ptr(bq27xxx_battery_i2c_of_match_table),
 298         },
 299         .probe = bq27xxx_battery_i2c_probe,
 300         .remove = bq27xxx_battery_i2c_remove,
 301         .id_table = bq27xxx_i2c_id_table,
 302 };
 303 module_i2c_driver(bq27xxx_battery_i2c_driver);
 304 
 305 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
 306 MODULE_DESCRIPTION("BQ27xxx battery monitor i2c driver");
 307 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */