1 /* 2 * Driver for the TI bq24190 battery charger. 3 * 4 * Author: Mark A. Greer <mgreer@animalcreek.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11 #include <linux/module.h> 12 #include <linux/interrupt.h> 13 #include <linux/delay.h> 14 #include <linux/of_irq.h> 15 #include <linux/of_device.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/power_supply.h> 18 #include <linux/gpio.h> 19 #include <linux/i2c.h> 20 21 #include <linux/power/bq24190_charger.h> 22 23 24 #define BQ24190_MANUFACTURER "Texas Instruments" 25 26 #define BQ24190_REG_ISC 0x00 /* Input Source Control */ 27 #define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7) 28 #define BQ24190_REG_ISC_EN_HIZ_SHIFT 7 29 #define BQ24190_REG_ISC_VINDPM_MASK (BIT(6) | BIT(5) | BIT(4) | \ 30 BIT(3)) 31 #define BQ24190_REG_ISC_VINDPM_SHIFT 3 32 #define BQ24190_REG_ISC_IINLIM_MASK (BIT(2) | BIT(1) | BIT(0)) 33 #define BQ24190_REG_ISC_IINLIM_SHIFT 0 34 35 #define BQ24190_REG_POC 0x01 /* Power-On Configuration */ 36 #define BQ24190_REG_POC_RESET_MASK BIT(7) 37 #define BQ24190_REG_POC_RESET_SHIFT 7 38 #define BQ24190_REG_POC_WDT_RESET_MASK BIT(6) 39 #define BQ24190_REG_POC_WDT_RESET_SHIFT 6 40 #define BQ24190_REG_POC_CHG_CONFIG_MASK (BIT(5) | BIT(4)) 41 #define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4 42 #define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1)) 43 #define BQ24190_REG_POC_SYS_MIN_SHIFT 1 44 #define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0) 45 #define BQ24190_REG_POC_BOOST_LIM_SHIFT 0 46 47 #define BQ24190_REG_CCC 0x02 /* Charge Current Control */ 48 #define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \ 49 BIT(4) | BIT(3) | BIT(2)) 50 #define BQ24190_REG_CCC_ICHG_SHIFT 2 51 #define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0) 52 #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0 53 54 #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */ 55 #define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \ 56 BIT(4)) 57 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4 58 #define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \ 59 BIT(0)) 60 #define BQ24190_REG_PCTCC_ITERM_SHIFT 0 61 62 #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */ 63 #define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \ 64 BIT(4) | BIT(3) | BIT(2)) 65 #define BQ24190_REG_CVC_VREG_SHIFT 2 66 #define BQ24190_REG_CVC_BATLOWV_MASK BIT(1) 67 #define BQ24190_REG_CVC_BATLOWV_SHIFT 1 68 #define BQ24190_REG_CVC_VRECHG_MASK BIT(0) 69 #define BQ24190_REG_CVC_VRECHG_SHIFT 0 70 71 #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */ 72 #define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7) 73 #define BQ24190_REG_CTTC_EN_TERM_SHIFT 7 74 #define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6) 75 #define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6 76 #define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4)) 77 #define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4 78 #define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3) 79 #define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3 80 #define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1)) 81 #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1 82 #define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0) 83 #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0 84 85 #define BQ24190_REG_ICTRC 0x06 /* IR Comp/Thermal Regulation Control */ 86 #define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5)) 87 #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5 88 #define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2)) 89 #define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2 90 #define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0)) 91 #define BQ24190_REG_ICTRC_TREG_SHIFT 0 92 93 #define BQ24190_REG_MOC 0x07 /* Misc. Operation Control */ 94 #define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7) 95 #define BQ24190_REG_MOC_DPDM_EN_SHIFT 7 96 #define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6) 97 #define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6 98 #define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5) 99 #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5 100 #define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4) 101 #define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4 102 #define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0)) 103 #define BQ24190_REG_MOC_INT_MASK_SHIFT 0 104 105 #define BQ24190_REG_SS 0x08 /* System Status */ 106 #define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6)) 107 #define BQ24190_REG_SS_VBUS_STAT_SHIFT 6 108 #define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4)) 109 #define BQ24190_REG_SS_CHRG_STAT_SHIFT 4 110 #define BQ24190_REG_SS_DPM_STAT_MASK BIT(3) 111 #define BQ24190_REG_SS_DPM_STAT_SHIFT 3 112 #define BQ24190_REG_SS_PG_STAT_MASK BIT(2) 113 #define BQ24190_REG_SS_PG_STAT_SHIFT 2 114 #define BQ24190_REG_SS_THERM_STAT_MASK BIT(1) 115 #define BQ24190_REG_SS_THERM_STAT_SHIFT 1 116 #define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0) 117 #define BQ24190_REG_SS_VSYS_STAT_SHIFT 0 118 119 #define BQ24190_REG_F 0x09 /* Fault */ 120 #define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7) 121 #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7 122 #define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6) 123 #define BQ24190_REG_F_BOOST_FAULT_SHIFT 6 124 #define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4)) 125 #define BQ24190_REG_F_CHRG_FAULT_SHIFT 4 126 #define BQ24190_REG_F_BAT_FAULT_MASK BIT(3) 127 #define BQ24190_REG_F_BAT_FAULT_SHIFT 3 128 #define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0)) 129 #define BQ24190_REG_F_NTC_FAULT_SHIFT 0 130 131 #define BQ24190_REG_VPRS 0x0A /* Vendor/Part/Revision Status */ 132 #define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3)) 133 #define BQ24190_REG_VPRS_PN_SHIFT 3 134 #define BQ24190_REG_VPRS_PN_24190 0x4 135 #define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193 */ 136 #define BQ24190_REG_VPRS_PN_24192I 0x3 137 #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2) 138 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2 139 #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0)) 140 #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0 141 142 /* 143 * The FAULT register is latched by the bq24190 (except for NTC_FAULT) 144 * so the first read after a fault returns the latched value and subsequent 145 * reads return the current value. In order to return the fault status 146 * to the user, have the interrupt handler save the reg's value and retrieve 147 * it in the appropriate health/status routine. 148 */ 149 struct bq24190_dev_info { 150 struct i2c_client *client; 151 struct device *dev; 152 struct power_supply *charger; 153 struct power_supply *battery; 154 char model_name[I2C_NAME_SIZE]; 155 kernel_ulong_t model; 156 unsigned int gpio_int; 157 unsigned int irq; 158 struct mutex f_reg_lock; 159 u8 f_reg; 160 u8 ss_reg; 161 u8 watchdog; 162 }; 163 164 /* 165 * The tables below provide a 2-way mapping for the value that goes in 166 * the register field and the real-world value that it represents. 167 * The index of the array is the value that goes in the register; the 168 * number at that index in the array is the real-world value that it 169 * represents. 170 */ 171 /* REG02[7:2] (ICHG) in uAh */ 172 static const int bq24190_ccc_ichg_values[] = { 173 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000, 174 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000, 175 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000, 176 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000, 177 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000, 178 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000, 179 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000, 180 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000 181 }; 182 183 /* REG04[7:2] (VREG) in uV */ 184 static const int bq24190_cvc_vreg_values[] = { 185 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000, 186 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000, 187 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000, 188 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000, 189 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000, 190 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000, 191 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000, 192 4400000 193 }; 194 195 /* REG06[1:0] (TREG) in tenths of degrees Celsius */ 196 static const int bq24190_ictrc_treg_values[] = { 197 600, 800, 1000, 1200 198 }; 199 200 /* 201 * Return the index in 'tbl' of greatest value that is less than or equal to 202 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that 203 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size' 204 * is less than 2^8. 205 */ 206 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v) 207 { 208 int i; 209 210 for (i = 1; i < tbl_size; i++) 211 if (v < tbl[i]) 212 break; 213 214 return i - 1; 215 } 216 217 /* Basic driver I/O routines */ 218 219 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data) 220 { 221 int ret; 222 223 ret = i2c_smbus_read_byte_data(bdi->client, reg); 224 if (ret < 0) 225 return ret; 226 227 *data = ret; 228 return 0; 229 } 230 231 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data) 232 { 233 return i2c_smbus_write_byte_data(bdi->client, reg, data); 234 } 235 236 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg, 237 u8 mask, u8 shift, u8 *data) 238 { 239 u8 v; 240 int ret; 241 242 ret = bq24190_read(bdi, reg, &v); 243 if (ret < 0) 244 return ret; 245 246 v &= mask; 247 v >>= shift; 248 *data = v; 249 250 return 0; 251 } 252 253 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg, 254 u8 mask, u8 shift, u8 data) 255 { 256 u8 v; 257 int ret; 258 259 ret = bq24190_read(bdi, reg, &v); 260 if (ret < 0) 261 return ret; 262 263 v &= ~mask; 264 v |= ((data << shift) & mask); 265 266 return bq24190_write(bdi, reg, v); 267 } 268 269 static int bq24190_get_field_val(struct bq24190_dev_info *bdi, 270 u8 reg, u8 mask, u8 shift, 271 const int tbl[], int tbl_size, 272 int *val) 273 { 274 u8 v; 275 int ret; 276 277 ret = bq24190_read_mask(bdi, reg, mask, shift, &v); 278 if (ret < 0) 279 return ret; 280 281 v = (v >= tbl_size) ? (tbl_size - 1) : v; 282 *val = tbl[v]; 283 284 return 0; 285 } 286 287 static int bq24190_set_field_val(struct bq24190_dev_info *bdi, 288 u8 reg, u8 mask, u8 shift, 289 const int tbl[], int tbl_size, 290 int val) 291 { 292 u8 idx; 293 294 idx = bq24190_find_idx(tbl, tbl_size, val); 295 296 return bq24190_write_mask(bdi, reg, mask, shift, idx); 297 } 298 299 #ifdef CONFIG_SYSFS 300 /* 301 * There are a numerous options that are configurable on the bq24190 302 * that go well beyond what the power_supply properties provide access to. 303 * Provide sysfs access to them so they can be examined and possibly modified 304 * on the fly. They will be provided for the charger power_supply object only 305 * and will be prefixed by 'f_' to make them easier to recognize. 306 */ 307 308 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \ 309 { \ 310 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \ 311 .reg = BQ24190_REG_##r, \ 312 .mask = BQ24190_REG_##r##_##f##_MASK, \ 313 .shift = BQ24190_REG_##r##_##f##_SHIFT, \ 314 } 315 316 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \ 317 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \ 318 bq24190_sysfs_store) 319 320 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \ 321 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL) 322 323 static ssize_t bq24190_sysfs_show(struct device *dev, 324 struct device_attribute *attr, char *buf); 325 static ssize_t bq24190_sysfs_store(struct device *dev, 326 struct device_attribute *attr, const char *buf, size_t count); 327 328 struct bq24190_sysfs_field_info { 329 struct device_attribute attr; 330 u8 reg; 331 u8 mask; 332 u8 shift; 333 }; 334 335 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */ 336 #undef SS 337 338 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = { 339 /* sysfs name reg field in reg */ 340 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ), 341 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM), 342 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM), 343 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG), 344 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN), 345 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM), 346 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG), 347 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT), 348 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG), 349 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM), 350 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG), 351 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV), 352 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG), 353 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM), 354 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT), 355 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG), 356 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER), 357 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER), 358 BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET), 359 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP), 360 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP), 361 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG), 362 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN), 363 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN), 364 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE), 365 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET), 366 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK), 367 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT), 368 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT), 369 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT), 370 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT), 371 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT), 372 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT), 373 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT), 374 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT), 375 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT), 376 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT), 377 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT), 378 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN), 379 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE), 380 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG), 381 }; 382 383 static struct attribute * 384 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1]; 385 386 static const struct attribute_group bq24190_sysfs_attr_group = { 387 .attrs = bq24190_sysfs_attrs, 388 }; 389 390 static void bq24190_sysfs_init_attrs(void) 391 { 392 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl); 393 394 for (i = 0; i < limit; i++) 395 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr; 396 397 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */ 398 } 399 400 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup( 401 const char *name) 402 { 403 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl); 404 405 for (i = 0; i < limit; i++) 406 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name)) 407 break; 408 409 if (i >= limit) 410 return NULL; 411 412 return &bq24190_sysfs_field_tbl[i]; 413 } 414 415 static ssize_t bq24190_sysfs_show(struct device *dev, 416 struct device_attribute *attr, char *buf) 417 { 418 struct power_supply *psy = dev_get_drvdata(dev); 419 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 420 struct bq24190_sysfs_field_info *info; 421 int ret; 422 u8 v; 423 424 info = bq24190_sysfs_field_lookup(attr->attr.name); 425 if (!info) 426 return -EINVAL; 427 428 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v); 429 if (ret) 430 return ret; 431 432 return scnprintf(buf, PAGE_SIZE, "%hhx\n", v); 433 } 434 435 static ssize_t bq24190_sysfs_store(struct device *dev, 436 struct device_attribute *attr, const char *buf, size_t count) 437 { 438 struct power_supply *psy = dev_get_drvdata(dev); 439 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 440 struct bq24190_sysfs_field_info *info; 441 int ret; 442 u8 v; 443 444 info = bq24190_sysfs_field_lookup(attr->attr.name); 445 if (!info) 446 return -EINVAL; 447 448 ret = kstrtou8(buf, 0, &v); 449 if (ret < 0) 450 return ret; 451 452 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v); 453 if (ret) 454 return ret; 455 456 return count; 457 } 458 459 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi) 460 { 461 bq24190_sysfs_init_attrs(); 462 463 return sysfs_create_group(&bdi->charger->dev.kobj, 464 &bq24190_sysfs_attr_group); 465 } 466 467 static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) 468 { 469 sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group); 470 } 471 #else 472 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi) 473 { 474 return 0; 475 } 476 477 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {} 478 #endif 479 480 /* 481 * According to the "Host Mode and default Mode" section of the 482 * manual, a write to any register causes the bq24190 to switch 483 * from default mode to host mode. It will switch back to default 484 * mode after a WDT timeout unless the WDT is turned off as well. 485 * So, by simply turning off the WDT, we accomplish both with the 486 * same write. 487 */ 488 static int bq24190_set_mode_host(struct bq24190_dev_info *bdi) 489 { 490 int ret; 491 u8 v; 492 493 ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v); 494 if (ret < 0) 495 return ret; 496 497 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >> 498 BQ24190_REG_CTTC_WATCHDOG_SHIFT); 499 v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK; 500 501 return bq24190_write(bdi, BQ24190_REG_CTTC, v); 502 } 503 504 static int bq24190_register_reset(struct bq24190_dev_info *bdi) 505 { 506 int ret, limit = 100; 507 u8 v; 508 509 /* Reset the registers */ 510 ret = bq24190_write_mask(bdi, BQ24190_REG_POC, 511 BQ24190_REG_POC_RESET_MASK, 512 BQ24190_REG_POC_RESET_SHIFT, 513 0x1); 514 if (ret < 0) 515 return ret; 516 517 /* Reset bit will be cleared by hardware so poll until it is */ 518 do { 519 ret = bq24190_read_mask(bdi, BQ24190_REG_POC, 520 BQ24190_REG_POC_RESET_MASK, 521 BQ24190_REG_POC_RESET_SHIFT, 522 &v); 523 if (ret < 0) 524 return ret; 525 526 if (!v) 527 break; 528 529 udelay(10); 530 } while (--limit); 531 532 if (!limit) 533 return -EIO; 534 535 return 0; 536 } 537 538 /* Charger power supply property routines */ 539 540 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi, 541 union power_supply_propval *val) 542 { 543 u8 v; 544 int type, ret; 545 546 ret = bq24190_read_mask(bdi, BQ24190_REG_POC, 547 BQ24190_REG_POC_CHG_CONFIG_MASK, 548 BQ24190_REG_POC_CHG_CONFIG_SHIFT, 549 &v); 550 if (ret < 0) 551 return ret; 552 553 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */ 554 if (!v) { 555 type = POWER_SUPPLY_CHARGE_TYPE_NONE; 556 } else { 557 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC, 558 BQ24190_REG_CCC_FORCE_20PCT_MASK, 559 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, 560 &v); 561 if (ret < 0) 562 return ret; 563 564 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE : 565 POWER_SUPPLY_CHARGE_TYPE_FAST; 566 } 567 568 val->intval = type; 569 570 return 0; 571 } 572 573 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi, 574 const union power_supply_propval *val) 575 { 576 u8 chg_config, force_20pct, en_term; 577 int ret; 578 579 /* 580 * According to the "Termination when REG02[0] = 1" section of 581 * the bq24190 manual, the trickle charge could be less than the 582 * termination current so it recommends turning off the termination 583 * function. 584 * 585 * Note: AFAICT from the datasheet, the user will have to manually 586 * turn off the charging when in 20% mode. If its not turned off, 587 * there could be battery damage. So, use this mode at your own risk. 588 */ 589 switch (val->intval) { 590 case POWER_SUPPLY_CHARGE_TYPE_NONE: 591 chg_config = 0x0; 592 break; 593 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE: 594 chg_config = 0x1; 595 force_20pct = 0x1; 596 en_term = 0x0; 597 break; 598 case POWER_SUPPLY_CHARGE_TYPE_FAST: 599 chg_config = 0x1; 600 force_20pct = 0x0; 601 en_term = 0x1; 602 break; 603 default: 604 return -EINVAL; 605 } 606 607 if (chg_config) { /* Enabling the charger */ 608 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC, 609 BQ24190_REG_CCC_FORCE_20PCT_MASK, 610 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, 611 force_20pct); 612 if (ret < 0) 613 return ret; 614 615 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC, 616 BQ24190_REG_CTTC_EN_TERM_MASK, 617 BQ24190_REG_CTTC_EN_TERM_SHIFT, 618 en_term); 619 if (ret < 0) 620 return ret; 621 } 622 623 return bq24190_write_mask(bdi, BQ24190_REG_POC, 624 BQ24190_REG_POC_CHG_CONFIG_MASK, 625 BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config); 626 } 627 628 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi, 629 union power_supply_propval *val) 630 { 631 u8 v; 632 int health; 633 634 mutex_lock(&bdi->f_reg_lock); 635 v = bdi->f_reg; 636 mutex_unlock(&bdi->f_reg_lock); 637 638 if (v & BQ24190_REG_F_BOOST_FAULT_MASK) { 639 /* 640 * This could be over-current or over-voltage but there's 641 * no way to tell which. Return 'OVERVOLTAGE' since there 642 * isn't an 'OVERCURRENT' value defined that we can return 643 * even if it was over-current. 644 */ 645 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 646 } else { 647 v &= BQ24190_REG_F_CHRG_FAULT_MASK; 648 v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT; 649 650 switch (v) { 651 case 0x0: /* Normal */ 652 health = POWER_SUPPLY_HEALTH_GOOD; 653 break; 654 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */ 655 /* 656 * This could be over-voltage or under-voltage 657 * and there's no way to tell which. Instead 658 * of looking foolish and returning 'OVERVOLTAGE' 659 * when its really under-voltage, just return 660 * 'UNSPEC_FAILURE'. 661 */ 662 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 663 break; 664 case 0x2: /* Thermal Shutdown */ 665 health = POWER_SUPPLY_HEALTH_OVERHEAT; 666 break; 667 case 0x3: /* Charge Safety Timer Expiration */ 668 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 669 break; 670 default: 671 health = POWER_SUPPLY_HEALTH_UNKNOWN; 672 } 673 } 674 675 val->intval = health; 676 677 return 0; 678 } 679 680 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi, 681 union power_supply_propval *val) 682 { 683 u8 v; 684 int ret; 685 686 ret = bq24190_read_mask(bdi, BQ24190_REG_SS, 687 BQ24190_REG_SS_PG_STAT_MASK, 688 BQ24190_REG_SS_PG_STAT_SHIFT, &v); 689 if (ret < 0) 690 return ret; 691 692 val->intval = v; 693 return 0; 694 } 695 696 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi, 697 union power_supply_propval *val) 698 { 699 u8 v; 700 int curr, ret; 701 702 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC, 703 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT, 704 bq24190_ccc_ichg_values, 705 ARRAY_SIZE(bq24190_ccc_ichg_values), &curr); 706 if (ret < 0) 707 return ret; 708 709 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC, 710 BQ24190_REG_CCC_FORCE_20PCT_MASK, 711 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v); 712 if (ret < 0) 713 return ret; 714 715 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */ 716 if (v) 717 curr /= 5; 718 719 val->intval = curr; 720 return 0; 721 } 722 723 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi, 724 union power_supply_propval *val) 725 { 726 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1; 727 728 val->intval = bq24190_ccc_ichg_values[idx]; 729 return 0; 730 } 731 732 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi, 733 const union power_supply_propval *val) 734 { 735 u8 v; 736 int ret, curr = val->intval; 737 738 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC, 739 BQ24190_REG_CCC_FORCE_20PCT_MASK, 740 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v); 741 if (ret < 0) 742 return ret; 743 744 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */ 745 if (v) 746 curr *= 5; 747 748 return bq24190_set_field_val(bdi, BQ24190_REG_CCC, 749 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT, 750 bq24190_ccc_ichg_values, 751 ARRAY_SIZE(bq24190_ccc_ichg_values), curr); 752 } 753 754 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi, 755 union power_supply_propval *val) 756 { 757 int voltage, ret; 758 759 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC, 760 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT, 761 bq24190_cvc_vreg_values, 762 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage); 763 if (ret < 0) 764 return ret; 765 766 val->intval = voltage; 767 return 0; 768 } 769 770 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi, 771 union power_supply_propval *val) 772 { 773 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1; 774 775 val->intval = bq24190_cvc_vreg_values[idx]; 776 return 0; 777 } 778 779 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi, 780 const union power_supply_propval *val) 781 { 782 return bq24190_set_field_val(bdi, BQ24190_REG_CVC, 783 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT, 784 bq24190_cvc_vreg_values, 785 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval); 786 } 787 788 static int bq24190_charger_get_property(struct power_supply *psy, 789 enum power_supply_property psp, union power_supply_propval *val) 790 { 791 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 792 int ret; 793 794 dev_dbg(bdi->dev, "prop: %d\n", psp); 795 796 pm_runtime_get_sync(bdi->dev); 797 798 switch (psp) { 799 case POWER_SUPPLY_PROP_CHARGE_TYPE: 800 ret = bq24190_charger_get_charge_type(bdi, val); 801 break; 802 case POWER_SUPPLY_PROP_HEALTH: 803 ret = bq24190_charger_get_health(bdi, val); 804 break; 805 case POWER_SUPPLY_PROP_ONLINE: 806 ret = bq24190_charger_get_online(bdi, val); 807 break; 808 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 809 ret = bq24190_charger_get_current(bdi, val); 810 break; 811 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 812 ret = bq24190_charger_get_current_max(bdi, val); 813 break; 814 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 815 ret = bq24190_charger_get_voltage(bdi, val); 816 break; 817 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 818 ret = bq24190_charger_get_voltage_max(bdi, val); 819 break; 820 case POWER_SUPPLY_PROP_SCOPE: 821 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; 822 ret = 0; 823 break; 824 case POWER_SUPPLY_PROP_MODEL_NAME: 825 val->strval = bdi->model_name; 826 ret = 0; 827 break; 828 case POWER_SUPPLY_PROP_MANUFACTURER: 829 val->strval = BQ24190_MANUFACTURER; 830 ret = 0; 831 break; 832 default: 833 ret = -ENODATA; 834 } 835 836 pm_runtime_put_sync(bdi->dev); 837 return ret; 838 } 839 840 static int bq24190_charger_set_property(struct power_supply *psy, 841 enum power_supply_property psp, 842 const union power_supply_propval *val) 843 { 844 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 845 int ret; 846 847 dev_dbg(bdi->dev, "prop: %d\n", psp); 848 849 pm_runtime_get_sync(bdi->dev); 850 851 switch (psp) { 852 case POWER_SUPPLY_PROP_CHARGE_TYPE: 853 ret = bq24190_charger_set_charge_type(bdi, val); 854 break; 855 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 856 ret = bq24190_charger_set_current(bdi, val); 857 break; 858 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 859 ret = bq24190_charger_set_voltage(bdi, val); 860 break; 861 default: 862 ret = -EINVAL; 863 } 864 865 pm_runtime_put_sync(bdi->dev); 866 return ret; 867 } 868 869 static int bq24190_charger_property_is_writeable(struct power_supply *psy, 870 enum power_supply_property psp) 871 { 872 int ret; 873 874 switch (psp) { 875 case POWER_SUPPLY_PROP_CHARGE_TYPE: 876 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 877 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 878 ret = 1; 879 break; 880 default: 881 ret = 0; 882 } 883 884 return ret; 885 } 886 887 static enum power_supply_property bq24190_charger_properties[] = { 888 POWER_SUPPLY_PROP_CHARGE_TYPE, 889 POWER_SUPPLY_PROP_HEALTH, 890 POWER_SUPPLY_PROP_ONLINE, 891 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 892 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 893 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 894 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 895 POWER_SUPPLY_PROP_SCOPE, 896 POWER_SUPPLY_PROP_MODEL_NAME, 897 POWER_SUPPLY_PROP_MANUFACTURER, 898 }; 899 900 static char *bq24190_charger_supplied_to[] = { 901 "main-battery", 902 }; 903 904 static const struct power_supply_desc bq24190_charger_desc = { 905 .name = "bq24190-charger", 906 .type = POWER_SUPPLY_TYPE_USB, 907 .properties = bq24190_charger_properties, 908 .num_properties = ARRAY_SIZE(bq24190_charger_properties), 909 .get_property = bq24190_charger_get_property, 910 .set_property = bq24190_charger_set_property, 911 .property_is_writeable = bq24190_charger_property_is_writeable, 912 }; 913 914 /* Battery power supply property routines */ 915 916 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi, 917 union power_supply_propval *val) 918 { 919 u8 ss_reg, chrg_fault; 920 int status, ret; 921 922 mutex_lock(&bdi->f_reg_lock); 923 chrg_fault = bdi->f_reg; 924 mutex_unlock(&bdi->f_reg_lock); 925 926 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK; 927 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT; 928 929 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg); 930 if (ret < 0) 931 return ret; 932 933 /* 934 * The battery must be discharging when any of these are true: 935 * - there is no good power source; 936 * - there is a charge fault. 937 * Could also be discharging when in "supplement mode" but 938 * there is no way to tell when its in that mode. 939 */ 940 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) { 941 status = POWER_SUPPLY_STATUS_DISCHARGING; 942 } else { 943 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK; 944 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT; 945 946 switch (ss_reg) { 947 case 0x0: /* Not Charging */ 948 status = POWER_SUPPLY_STATUS_NOT_CHARGING; 949 break; 950 case 0x1: /* Pre-charge */ 951 case 0x2: /* Fast Charging */ 952 status = POWER_SUPPLY_STATUS_CHARGING; 953 break; 954 case 0x3: /* Charge Termination Done */ 955 status = POWER_SUPPLY_STATUS_FULL; 956 break; 957 default: 958 ret = -EIO; 959 } 960 } 961 962 if (!ret) 963 val->intval = status; 964 965 return ret; 966 } 967 968 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi, 969 union power_supply_propval *val) 970 { 971 u8 v; 972 int health; 973 974 mutex_lock(&bdi->f_reg_lock); 975 v = bdi->f_reg; 976 mutex_unlock(&bdi->f_reg_lock); 977 978 if (v & BQ24190_REG_F_BAT_FAULT_MASK) { 979 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 980 } else { 981 v &= BQ24190_REG_F_NTC_FAULT_MASK; 982 v >>= BQ24190_REG_F_NTC_FAULT_SHIFT; 983 984 switch (v) { 985 case 0x0: /* Normal */ 986 health = POWER_SUPPLY_HEALTH_GOOD; 987 break; 988 case 0x1: /* TS1 Cold */ 989 case 0x3: /* TS2 Cold */ 990 case 0x5: /* Both Cold */ 991 health = POWER_SUPPLY_HEALTH_COLD; 992 break; 993 case 0x2: /* TS1 Hot */ 994 case 0x4: /* TS2 Hot */ 995 case 0x6: /* Both Hot */ 996 health = POWER_SUPPLY_HEALTH_OVERHEAT; 997 break; 998 default: 999 health = POWER_SUPPLY_HEALTH_UNKNOWN; 1000 } 1001 } 1002 1003 val->intval = health; 1004 return 0; 1005 } 1006 1007 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi, 1008 union power_supply_propval *val) 1009 { 1010 u8 batfet_disable; 1011 int ret; 1012 1013 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC, 1014 BQ24190_REG_MOC_BATFET_DISABLE_MASK, 1015 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable); 1016 if (ret < 0) 1017 return ret; 1018 1019 val->intval = !batfet_disable; 1020 return 0; 1021 } 1022 1023 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi, 1024 const union power_supply_propval *val) 1025 { 1026 return bq24190_write_mask(bdi, BQ24190_REG_MOC, 1027 BQ24190_REG_MOC_BATFET_DISABLE_MASK, 1028 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval); 1029 } 1030 1031 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi, 1032 union power_supply_propval *val) 1033 { 1034 int temp, ret; 1035 1036 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC, 1037 BQ24190_REG_ICTRC_TREG_MASK, 1038 BQ24190_REG_ICTRC_TREG_SHIFT, 1039 bq24190_ictrc_treg_values, 1040 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp); 1041 if (ret < 0) 1042 return ret; 1043 1044 val->intval = temp; 1045 return 0; 1046 } 1047 1048 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi, 1049 const union power_supply_propval *val) 1050 { 1051 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC, 1052 BQ24190_REG_ICTRC_TREG_MASK, 1053 BQ24190_REG_ICTRC_TREG_SHIFT, 1054 bq24190_ictrc_treg_values, 1055 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval); 1056 } 1057 1058 static int bq24190_battery_get_property(struct power_supply *psy, 1059 enum power_supply_property psp, union power_supply_propval *val) 1060 { 1061 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 1062 int ret; 1063 1064 dev_dbg(bdi->dev, "prop: %d\n", psp); 1065 1066 pm_runtime_get_sync(bdi->dev); 1067 1068 switch (psp) { 1069 case POWER_SUPPLY_PROP_STATUS: 1070 ret = bq24190_battery_get_status(bdi, val); 1071 break; 1072 case POWER_SUPPLY_PROP_HEALTH: 1073 ret = bq24190_battery_get_health(bdi, val); 1074 break; 1075 case POWER_SUPPLY_PROP_ONLINE: 1076 ret = bq24190_battery_get_online(bdi, val); 1077 break; 1078 case POWER_SUPPLY_PROP_TECHNOLOGY: 1079 /* Could be Li-on or Li-polymer but no way to tell which */ 1080 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 1081 ret = 0; 1082 break; 1083 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 1084 ret = bq24190_battery_get_temp_alert_max(bdi, val); 1085 break; 1086 case POWER_SUPPLY_PROP_SCOPE: 1087 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; 1088 ret = 0; 1089 break; 1090 default: 1091 ret = -ENODATA; 1092 } 1093 1094 pm_runtime_put_sync(bdi->dev); 1095 return ret; 1096 } 1097 1098 static int bq24190_battery_set_property(struct power_supply *psy, 1099 enum power_supply_property psp, 1100 const union power_supply_propval *val) 1101 { 1102 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy); 1103 int ret; 1104 1105 dev_dbg(bdi->dev, "prop: %d\n", psp); 1106 1107 pm_runtime_get_sync(bdi->dev); 1108 1109 switch (psp) { 1110 case POWER_SUPPLY_PROP_ONLINE: 1111 ret = bq24190_battery_set_online(bdi, val); 1112 break; 1113 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 1114 ret = bq24190_battery_set_temp_alert_max(bdi, val); 1115 break; 1116 default: 1117 ret = -EINVAL; 1118 } 1119 1120 pm_runtime_put_sync(bdi->dev); 1121 return ret; 1122 } 1123 1124 static int bq24190_battery_property_is_writeable(struct power_supply *psy, 1125 enum power_supply_property psp) 1126 { 1127 int ret; 1128 1129 switch (psp) { 1130 case POWER_SUPPLY_PROP_ONLINE: 1131 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 1132 ret = 1; 1133 break; 1134 default: 1135 ret = 0; 1136 } 1137 1138 return ret; 1139 } 1140 1141 static enum power_supply_property bq24190_battery_properties[] = { 1142 POWER_SUPPLY_PROP_STATUS, 1143 POWER_SUPPLY_PROP_HEALTH, 1144 POWER_SUPPLY_PROP_ONLINE, 1145 POWER_SUPPLY_PROP_TECHNOLOGY, 1146 POWER_SUPPLY_PROP_TEMP_ALERT_MAX, 1147 POWER_SUPPLY_PROP_SCOPE, 1148 }; 1149 1150 static const struct power_supply_desc bq24190_battery_desc = { 1151 .name = "bq24190-battery", 1152 .type = POWER_SUPPLY_TYPE_BATTERY, 1153 .properties = bq24190_battery_properties, 1154 .num_properties = ARRAY_SIZE(bq24190_battery_properties), 1155 .get_property = bq24190_battery_get_property, 1156 .set_property = bq24190_battery_set_property, 1157 .property_is_writeable = bq24190_battery_property_is_writeable, 1158 }; 1159 1160 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) 1161 { 1162 struct bq24190_dev_info *bdi = data; 1163 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK; 1164 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK 1165 | BQ24190_REG_F_NTC_FAULT_MASK; 1166 bool alert_charger = false, alert_battery = false; 1167 u8 ss_reg = 0, f_reg = 0; 1168 int i, ret; 1169 1170 pm_runtime_get_sync(bdi->dev); 1171 1172 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg); 1173 if (ret < 0) { 1174 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret); 1175 goto out; 1176 } 1177 1178 i = 0; 1179 do { 1180 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg); 1181 if (ret < 0) { 1182 dev_err(bdi->dev, "Can't read F reg: %d\n", ret); 1183 goto out; 1184 } 1185 } while (f_reg && ++i < 2); 1186 1187 if (f_reg != bdi->f_reg) { 1188 dev_info(bdi->dev, 1189 "Fault: boost %d, charge %d, battery %d, ntc %d\n", 1190 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK), 1191 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK), 1192 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK), 1193 !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK)); 1194 1195 mutex_lock(&bdi->f_reg_lock); 1196 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f)) 1197 alert_battery = true; 1198 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f)) 1199 alert_charger = true; 1200 bdi->f_reg = f_reg; 1201 mutex_unlock(&bdi->f_reg_lock); 1202 } 1203 1204 if (ss_reg != bdi->ss_reg) { 1205 /* 1206 * The device is in host mode so when PG_STAT goes from 1->0 1207 * (i.e., power removed) HIZ needs to be disabled. 1208 */ 1209 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) && 1210 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) { 1211 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC, 1212 BQ24190_REG_ISC_EN_HIZ_MASK, 1213 BQ24190_REG_ISC_EN_HIZ_SHIFT, 1214 0); 1215 if (ret < 0) 1216 dev_err(bdi->dev, "Can't access ISC reg: %d\n", 1217 ret); 1218 } 1219 1220 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss)) 1221 alert_battery = true; 1222 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) 1223 alert_charger = true; 1224 bdi->ss_reg = ss_reg; 1225 } 1226 1227 if (alert_charger) 1228 power_supply_changed(bdi->charger); 1229 if (alert_battery) 1230 power_supply_changed(bdi->battery); 1231 1232 out: 1233 pm_runtime_put_sync(bdi->dev); 1234 1235 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg); 1236 1237 return IRQ_HANDLED; 1238 } 1239 1240 static int bq24190_hw_init(struct bq24190_dev_info *bdi) 1241 { 1242 u8 v; 1243 int ret; 1244 1245 pm_runtime_get_sync(bdi->dev); 1246 1247 /* First check that the device really is what its supposed to be */ 1248 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS, 1249 BQ24190_REG_VPRS_PN_MASK, 1250 BQ24190_REG_VPRS_PN_SHIFT, 1251 &v); 1252 if (ret < 0) 1253 goto out; 1254 1255 if (v != bdi->model) { 1256 ret = -ENODEV; 1257 goto out; 1258 } 1259 1260 ret = bq24190_register_reset(bdi); 1261 if (ret < 0) 1262 goto out; 1263 1264 ret = bq24190_set_mode_host(bdi); 1265 if (ret < 0) 1266 goto out; 1267 1268 ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); 1269 out: 1270 pm_runtime_put_sync(bdi->dev); 1271 return ret; 1272 } 1273 1274 #ifdef CONFIG_OF 1275 static int bq24190_setup_dt(struct bq24190_dev_info *bdi) 1276 { 1277 bdi->irq = irq_of_parse_and_map(bdi->dev->of_node, 0); 1278 if (bdi->irq <= 0) 1279 return -1; 1280 1281 return 0; 1282 } 1283 #else 1284 static int bq24190_setup_dt(struct bq24190_dev_info *bdi) 1285 { 1286 return -1; 1287 } 1288 #endif 1289 1290 static int bq24190_setup_pdata(struct bq24190_dev_info *bdi, 1291 struct bq24190_platform_data *pdata) 1292 { 1293 int ret; 1294 1295 if (!gpio_is_valid(pdata->gpio_int)) 1296 return -1; 1297 1298 ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev)); 1299 if (ret < 0) 1300 return -1; 1301 1302 ret = gpio_direction_input(pdata->gpio_int); 1303 if (ret < 0) 1304 goto out; 1305 1306 bdi->irq = gpio_to_irq(pdata->gpio_int); 1307 if (!bdi->irq) 1308 goto out; 1309 1310 bdi->gpio_int = pdata->gpio_int; 1311 return 0; 1312 1313 out: 1314 gpio_free(pdata->gpio_int); 1315 return -1; 1316 } 1317 1318 static int bq24190_probe(struct i2c_client *client, 1319 const struct i2c_device_id *id) 1320 { 1321 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1322 struct device *dev = &client->dev; 1323 struct bq24190_platform_data *pdata = client->dev.platform_data; 1324 struct power_supply_config charger_cfg = {}, battery_cfg = {}; 1325 struct bq24190_dev_info *bdi; 1326 int ret; 1327 1328 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1329 dev_err(dev, "No support for SMBUS_BYTE_DATA\n"); 1330 return -ENODEV; 1331 } 1332 1333 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL); 1334 if (!bdi) { 1335 dev_err(dev, "Can't alloc bdi struct\n"); 1336 return -ENOMEM; 1337 } 1338 1339 bdi->client = client; 1340 bdi->dev = dev; 1341 bdi->model = id->driver_data; 1342 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE); 1343 mutex_init(&bdi->f_reg_lock); 1344 bdi->f_reg = 0; 1345 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ 1346 1347 i2c_set_clientdata(client, bdi); 1348 1349 if (dev->of_node) 1350 ret = bq24190_setup_dt(bdi); 1351 else 1352 ret = bq24190_setup_pdata(bdi, pdata); 1353 1354 if (ret) { 1355 dev_err(dev, "Can't get irq info\n"); 1356 return -EINVAL; 1357 } 1358 1359 pm_runtime_enable(dev); 1360 pm_runtime_resume(dev); 1361 1362 ret = bq24190_hw_init(bdi); 1363 if (ret < 0) { 1364 dev_err(dev, "Hardware init failed\n"); 1365 goto out1; 1366 } 1367 1368 charger_cfg.drv_data = bdi; 1369 charger_cfg.supplied_to = bq24190_charger_supplied_to; 1370 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to), 1371 bdi->charger = power_supply_register(dev, &bq24190_charger_desc, 1372 &charger_cfg); 1373 if (IS_ERR(bdi->charger)) { 1374 dev_err(dev, "Can't register charger\n"); 1375 ret = PTR_ERR(bdi->charger); 1376 goto out1; 1377 } 1378 1379 battery_cfg.drv_data = bdi; 1380 bdi->battery = power_supply_register(dev, &bq24190_battery_desc, 1381 &battery_cfg); 1382 if (IS_ERR(bdi->battery)) { 1383 dev_err(dev, "Can't register battery\n"); 1384 ret = PTR_ERR(bdi->battery); 1385 goto out2; 1386 } 1387 1388 ret = bq24190_sysfs_create_group(bdi); 1389 if (ret) { 1390 dev_err(dev, "Can't create sysfs entries\n"); 1391 goto out3; 1392 } 1393 1394 ret = devm_request_threaded_irq(dev, bdi->irq, NULL, 1395 bq24190_irq_handler_thread, 1396 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 1397 "bq24190-charger", bdi); 1398 if (ret < 0) { 1399 dev_err(dev, "Can't set up irq handler\n"); 1400 goto out4; 1401 } 1402 1403 return 0; 1404 1405 out4: 1406 bq24190_sysfs_remove_group(bdi); 1407 1408 out3: 1409 power_supply_unregister(bdi->battery); 1410 1411 out2: 1412 power_supply_unregister(bdi->charger); 1413 1414 out1: 1415 pm_runtime_disable(dev); 1416 if (bdi->gpio_int) 1417 gpio_free(bdi->gpio_int); 1418 return ret; 1419 } 1420 1421 static int bq24190_remove(struct i2c_client *client) 1422 { 1423 struct bq24190_dev_info *bdi = i2c_get_clientdata(client); 1424 1425 pm_runtime_get_sync(bdi->dev); 1426 bq24190_register_reset(bdi); 1427 pm_runtime_put_sync(bdi->dev); 1428 1429 bq24190_sysfs_remove_group(bdi); 1430 power_supply_unregister(bdi->battery); 1431 power_supply_unregister(bdi->charger); 1432 pm_runtime_disable(bdi->dev); 1433 1434 if (bdi->gpio_int) 1435 gpio_free(bdi->gpio_int); 1436 1437 return 0; 1438 } 1439 1440 #ifdef CONFIG_PM_SLEEP 1441 static int bq24190_pm_suspend(struct device *dev) 1442 { 1443 struct i2c_client *client = to_i2c_client(dev); 1444 struct bq24190_dev_info *bdi = i2c_get_clientdata(client); 1445 1446 pm_runtime_get_sync(bdi->dev); 1447 bq24190_register_reset(bdi); 1448 pm_runtime_put_sync(bdi->dev); 1449 1450 return 0; 1451 } 1452 1453 static int bq24190_pm_resume(struct device *dev) 1454 { 1455 struct i2c_client *client = to_i2c_client(dev); 1456 struct bq24190_dev_info *bdi = i2c_get_clientdata(client); 1457 1458 bdi->f_reg = 0; 1459 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ 1460 1461 pm_runtime_get_sync(bdi->dev); 1462 bq24190_register_reset(bdi); 1463 bq24190_set_mode_host(bdi); 1464 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); 1465 pm_runtime_put_sync(bdi->dev); 1466 1467 /* Things may have changed while suspended so alert upper layer */ 1468 power_supply_changed(bdi->charger); 1469 power_supply_changed(bdi->battery); 1470 1471 return 0; 1472 } 1473 #endif 1474 1475 static SIMPLE_DEV_PM_OPS(bq24190_pm_ops, bq24190_pm_suspend, bq24190_pm_resume); 1476 1477 /* 1478 * Only support the bq24190 right now. The bq24192, bq24192i, and bq24193 1479 * are similar but not identical so the driver needs to be extended to 1480 * support them. 1481 */ 1482 static const struct i2c_device_id bq24190_i2c_ids[] = { 1483 { "bq24190", BQ24190_REG_VPRS_PN_24190 }, 1484 { }, 1485 }; 1486 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids); 1487 1488 #ifdef CONFIG_OF 1489 static const struct of_device_id bq24190_of_match[] = { 1490 { .compatible = "ti,bq24190", }, 1491 { }, 1492 }; 1493 MODULE_DEVICE_TABLE(of, bq24190_of_match); 1494 #else 1495 static const struct of_device_id bq24190_of_match[] = { 1496 { }, 1497 }; 1498 #endif 1499 1500 static struct i2c_driver bq24190_driver = { 1501 .probe = bq24190_probe, 1502 .remove = bq24190_remove, 1503 .id_table = bq24190_i2c_ids, 1504 .driver = { 1505 .name = "bq24190-charger", 1506 .pm = &bq24190_pm_ops, 1507 .of_match_table = of_match_ptr(bq24190_of_match), 1508 }, 1509 }; 1510 module_i2c_driver(bq24190_driver); 1511 1512 MODULE_LICENSE("GPL"); 1513 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>"); 1514 MODULE_DESCRIPTION("TI BQ24190 Charger Driver"); 1515