1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * I2C client/driver for the Maxim/Dallas DS2782 Stand-Alone Fuel Gauge IC 4 * 5 * Copyright (C) 2009 Bluewater Systems Ltd 6 * 7 * Author: Ryan Mallon 8 * 9 * DS2786 added by Yulia Vilensky <vilensky@compulab.co.il> 10 * 11 * UEvent sending added by Evgeny Romanov <romanov@neurosoft.ru> 12 */ 13 14 #include <linux/devm-helpers.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/types.h> 18 #include <linux/errno.h> 19 #include <linux/swab.h> 20 #include <linux/i2c.h> 21 #include <linux/delay.h> 22 #include <linux/idr.h> 23 #include <linux/power_supply.h> 24 #include <linux/slab.h> 25 #include <linux/ds2782_battery.h> 26 27 #define DS2782_REG_RARC 0x06 /* Remaining active relative capacity */ 28 29 #define DS278x_REG_VOLT_MSB 0x0c 30 #define DS278x_REG_TEMP_MSB 0x0a 31 #define DS278x_REG_CURRENT_MSB 0x0e 32 33 /* EEPROM Block */ 34 #define DS2782_REG_RSNSP 0x69 /* Sense resistor value */ 35 36 /* Current unit measurement in uA for a 1 milli-ohm sense resistor */ 37 #define DS2782_CURRENT_UNITS 1563 38 39 #define DS2786_REG_RARC 0x02 /* Remaining active relative capacity */ 40 41 #define DS2786_CURRENT_UNITS 25 42 43 #define DS278x_DELAY 1000 44 45 struct ds278x_info; 46 47 struct ds278x_battery_ops { 48 int (*get_battery_current)(struct ds278x_info *info, int *current_uA); 49 int (*get_battery_voltage)(struct ds278x_info *info, int *voltage_uV); 50 int (*get_battery_capacity)(struct ds278x_info *info, int *capacity); 51 }; 52 53 #define to_ds278x_info(x) power_supply_get_drvdata(x) 54 55 struct ds278x_info { 56 struct i2c_client *client; 57 struct power_supply *battery; 58 struct power_supply_desc battery_desc; 59 const struct ds278x_battery_ops *ops; 60 struct delayed_work bat_work; 61 int rsns; 62 int capacity; 63 int status; /* State Of Charge */ 64 }; 65 66 static DEFINE_IDA(battery_id); 67 68 static inline int ds278x_read_reg(struct ds278x_info *info, int reg, u8 *val) 69 { 70 int ret; 71 72 ret = i2c_smbus_read_byte_data(info->client, reg); 73 if (ret < 0) { 74 dev_err(&info->client->dev, "register read failed\n"); 75 return ret; 76 } 77 78 *val = ret; 79 return 0; 80 } 81 82 static inline int ds278x_read_reg16(struct ds278x_info *info, int reg_msb, 83 s16 *val) 84 { 85 int ret; 86 87 ret = i2c_smbus_read_word_data(info->client, reg_msb); 88 if (ret < 0) { 89 dev_err(&info->client->dev, "register read failed\n"); 90 return ret; 91 } 92 93 *val = swab16(ret); 94 return 0; 95 } 96 97 static int ds278x_get_temp(struct ds278x_info *info, int *temp) 98 { 99 s16 raw; 100 int err; 101 102 /* 103 * Temperature is measured in units of 0.125 degrees celcius, the 104 * power_supply class measures temperature in tenths of degrees 105 * celsius. The temperature value is stored as a 10 bit number, plus 106 * sign in the upper bits of a 16 bit register. 107 */ 108 err = ds278x_read_reg16(info, DS278x_REG_TEMP_MSB, &raw); 109 if (err) 110 return err; 111 *temp = ((raw / 32) * 125) / 100; 112 return 0; 113 } 114 115 static int ds2782_get_current(struct ds278x_info *info, int *current_uA) 116 { 117 int sense_res; 118 int err; 119 u8 sense_res_raw; 120 s16 raw; 121 122 /* 123 * The units of measurement for current are dependent on the value of 124 * the sense resistor. 125 */ 126 err = ds278x_read_reg(info, DS2782_REG_RSNSP, &sense_res_raw); 127 if (err) 128 return err; 129 if (sense_res_raw == 0) { 130 dev_err(&info->client->dev, "sense resistor value is 0\n"); 131 return -ENXIO; 132 } 133 sense_res = 1000 / sense_res_raw; 134 135 dev_dbg(&info->client->dev, "sense resistor = %d milli-ohms\n", 136 sense_res); 137 err = ds278x_read_reg16(info, DS278x_REG_CURRENT_MSB, &raw); 138 if (err) 139 return err; 140 *current_uA = raw * (DS2782_CURRENT_UNITS / sense_res); 141 return 0; 142 } 143 144 static int ds2782_get_voltage(struct ds278x_info *info, int *voltage_uV) 145 { 146 s16 raw; 147 int err; 148 149 /* 150 * Voltage is measured in units of 4.88mV. The voltage is stored as 151 * a 10-bit number plus sign, in the upper bits of a 16-bit register 152 */ 153 err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); 154 if (err) 155 return err; 156 *voltage_uV = (raw / 32) * 4800; 157 return 0; 158 } 159 160 static int ds2782_get_capacity(struct ds278x_info *info, int *capacity) 161 { 162 int err; 163 u8 raw; 164 165 err = ds278x_read_reg(info, DS2782_REG_RARC, &raw); 166 if (err) 167 return err; 168 *capacity = raw; 169 return 0; 170 } 171 172 static int ds2786_get_current(struct ds278x_info *info, int *current_uA) 173 { 174 int err; 175 s16 raw; 176 177 err = ds278x_read_reg16(info, DS278x_REG_CURRENT_MSB, &raw); 178 if (err) 179 return err; 180 *current_uA = (raw / 16) * (DS2786_CURRENT_UNITS / info->rsns); 181 return 0; 182 } 183 184 static int ds2786_get_voltage(struct ds278x_info *info, int *voltage_uV) 185 { 186 s16 raw; 187 int err; 188 189 /* 190 * Voltage is measured in units of 1.22mV. The voltage is stored as 191 * a 12-bit number plus sign, in the upper bits of a 16-bit register 192 */ 193 err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); 194 if (err) 195 return err; 196 *voltage_uV = (raw / 8) * 1220; 197 return 0; 198 } 199 200 static int ds2786_get_capacity(struct ds278x_info *info, int *capacity) 201 { 202 int err; 203 u8 raw; 204 205 err = ds278x_read_reg(info, DS2786_REG_RARC, &raw); 206 if (err) 207 return err; 208 /* Relative capacity is displayed with resolution 0.5 % */ 209 *capacity = raw/2 ; 210 return 0; 211 } 212 213 static int ds278x_get_status(struct ds278x_info *info, int *status) 214 { 215 int err; 216 int current_uA; 217 int capacity; 218 219 err = info->ops->get_battery_current(info, ¤t_uA); 220 if (err) 221 return err; 222 223 err = info->ops->get_battery_capacity(info, &capacity); 224 if (err) 225 return err; 226 227 info->capacity = capacity; 228 229 if (capacity == 100) 230 *status = POWER_SUPPLY_STATUS_FULL; 231 else if (current_uA == 0) 232 *status = POWER_SUPPLY_STATUS_NOT_CHARGING; 233 else if (current_uA < 0) 234 *status = POWER_SUPPLY_STATUS_DISCHARGING; 235 else 236 *status = POWER_SUPPLY_STATUS_CHARGING; 237 238 return 0; 239 } 240 241 static int ds278x_battery_get_property(struct power_supply *psy, 242 enum power_supply_property prop, 243 union power_supply_propval *val) 244 { 245 struct ds278x_info *info = to_ds278x_info(psy); 246 int ret; 247 248 switch (prop) { 249 case POWER_SUPPLY_PROP_STATUS: 250 ret = ds278x_get_status(info, &val->intval); 251 break; 252 253 case POWER_SUPPLY_PROP_CAPACITY: 254 ret = info->ops->get_battery_capacity(info, &val->intval); 255 break; 256 257 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 258 ret = info->ops->get_battery_voltage(info, &val->intval); 259 break; 260 261 case POWER_SUPPLY_PROP_CURRENT_NOW: 262 ret = info->ops->get_battery_current(info, &val->intval); 263 break; 264 265 case POWER_SUPPLY_PROP_TEMP: 266 ret = ds278x_get_temp(info, &val->intval); 267 break; 268 269 default: 270 ret = -EINVAL; 271 } 272 273 return ret; 274 } 275 276 static void ds278x_bat_update(struct ds278x_info *info) 277 { 278 int old_status = info->status; 279 int old_capacity = info->capacity; 280 281 ds278x_get_status(info, &info->status); 282 283 if ((old_status != info->status) || (old_capacity != info->capacity)) 284 power_supply_changed(info->battery); 285 } 286 287 static void ds278x_bat_work(struct work_struct *work) 288 { 289 struct ds278x_info *info; 290 291 info = container_of(work, struct ds278x_info, bat_work.work); 292 ds278x_bat_update(info); 293 294 schedule_delayed_work(&info->bat_work, DS278x_DELAY); 295 } 296 297 static enum power_supply_property ds278x_battery_props[] = { 298 POWER_SUPPLY_PROP_STATUS, 299 POWER_SUPPLY_PROP_CAPACITY, 300 POWER_SUPPLY_PROP_VOLTAGE_NOW, 301 POWER_SUPPLY_PROP_CURRENT_NOW, 302 POWER_SUPPLY_PROP_TEMP, 303 }; 304 305 static void ds278x_power_supply_init(struct power_supply_desc *battery) 306 { 307 battery->type = POWER_SUPPLY_TYPE_BATTERY; 308 battery->properties = ds278x_battery_props; 309 battery->num_properties = ARRAY_SIZE(ds278x_battery_props); 310 battery->get_property = ds278x_battery_get_property; 311 battery->external_power_changed = NULL; 312 } 313 314 #ifdef CONFIG_PM_SLEEP 315 316 static int ds278x_suspend(struct device *dev) 317 { 318 struct i2c_client *client = to_i2c_client(dev); 319 struct ds278x_info *info = i2c_get_clientdata(client); 320 321 cancel_delayed_work(&info->bat_work); 322 return 0; 323 } 324 325 static int ds278x_resume(struct device *dev) 326 { 327 struct i2c_client *client = to_i2c_client(dev); 328 struct ds278x_info *info = i2c_get_clientdata(client); 329 330 schedule_delayed_work(&info->bat_work, DS278x_DELAY); 331 return 0; 332 } 333 #endif /* CONFIG_PM_SLEEP */ 334 335 static SIMPLE_DEV_PM_OPS(ds278x_battery_pm_ops, ds278x_suspend, ds278x_resume); 336 337 enum ds278x_num_id { 338 DS2782 = 0, 339 DS2786, 340 }; 341 342 static const struct ds278x_battery_ops ds278x_ops[] = { 343 [DS2782] = { 344 .get_battery_current = ds2782_get_current, 345 .get_battery_voltage = ds2782_get_voltage, 346 .get_battery_capacity = ds2782_get_capacity, 347 }, 348 [DS2786] = { 349 .get_battery_current = ds2786_get_current, 350 .get_battery_voltage = ds2786_get_voltage, 351 .get_battery_capacity = ds2786_get_capacity, 352 } 353 }; 354 355 static void ds278x_free_ida(void *data) 356 { 357 int num = (uintptr_t)data; 358 359 ida_free(&battery_id, num); 360 } 361 362 static int ds278x_battery_probe(struct i2c_client *client) 363 { 364 const struct i2c_device_id *id = i2c_client_get_device_id(client); 365 struct ds278x_platform_data *pdata = client->dev.platform_data; 366 struct power_supply_config psy_cfg = {}; 367 struct ds278x_info *info; 368 int ret; 369 int num; 370 371 /* 372 * ds2786 should have the sense resistor value set 373 * in the platform data 374 */ 375 if (id->driver_data == DS2786 && !pdata) { 376 dev_err(&client->dev, "missing platform data for ds2786\n"); 377 return -EINVAL; 378 } 379 380 /* Get an ID for this battery */ 381 num = ida_alloc(&battery_id, GFP_KERNEL); 382 if (num < 0) 383 return num; 384 ret = devm_add_action_or_reset(&client->dev, ds278x_free_ida, (void *)(uintptr_t)num); 385 if (ret) 386 return ret; 387 388 info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); 389 if (!info) 390 return -ENOMEM; 391 392 info->battery_desc.name = devm_kasprintf(&client->dev, GFP_KERNEL, 393 "%s-%d", client->name, num); 394 if (!info->battery_desc.name) 395 return -ENOMEM; 396 397 if (id->driver_data == DS2786) 398 info->rsns = pdata->rsns; 399 400 i2c_set_clientdata(client, info); 401 info->client = client; 402 info->ops = &ds278x_ops[id->driver_data]; 403 ds278x_power_supply_init(&info->battery_desc); 404 psy_cfg.drv_data = info; 405 406 info->capacity = 100; 407 info->status = POWER_SUPPLY_STATUS_FULL; 408 409 info->battery = devm_power_supply_register(&client->dev, 410 &info->battery_desc, 411 &psy_cfg); 412 if (IS_ERR(info->battery)) { 413 dev_err(&client->dev, "failed to register battery\n"); 414 return PTR_ERR(info->battery); 415 } 416 417 ret = devm_delayed_work_autocancel(&client->dev, &info->bat_work, ds278x_bat_work); 418 if (ret) 419 return ret; 420 schedule_delayed_work(&info->bat_work, DS278x_DELAY); 421 422 return 0; 423 } 424 425 static const struct i2c_device_id ds278x_id[] = { 426 {"ds2782", DS2782}, 427 {"ds2786", DS2786}, 428 {}, 429 }; 430 MODULE_DEVICE_TABLE(i2c, ds278x_id); 431 432 static struct i2c_driver ds278x_battery_driver = { 433 .driver = { 434 .name = "ds2782-battery", 435 .pm = &ds278x_battery_pm_ops, 436 }, 437 .probe = ds278x_battery_probe, 438 .id_table = ds278x_id, 439 }; 440 module_i2c_driver(ds278x_battery_driver); 441 442 MODULE_AUTHOR("Ryan Mallon"); 443 MODULE_DESCRIPTION("Maxim/Dallas DS2782 Stand-Alone Fuel Gauge IC driver"); 444 MODULE_LICENSE("GPL"); 445