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 = ® 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"); 308