Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-v3.7' of git://git.infradead.org/battery-2.6

Pull battery updates from Anton Vorontsov:
"1. New drivers:
- Marvell 88pm860x charger and battery drivers;
- Texas Instruments LP8788 charger driver;
2. Two new power supply properties: whether a battery is authentic,
and chargers' maximal currents and voltages;
3. A lot of TI LP8727 Charger cleanups;
4. New features for Charger Manager, mainly now we can disable
specific regulators;
5. Random fixes and cleanups for other drivers."

Fix up trivial conflicts in <linux/mfd/88pm860x.h>

* tag 'for-v3.7' of git://git.infradead.org/battery-2.6: (52 commits)
pda_power: Remove ac_draw_failed goto and label
charger-manager: Add support sysfs entry for charger
charger-manager: Support limit of maximum possible
charger-manager: Check fully charged state of battery periodically
lp8727_charger: More pure cosmetic improvements
lp8727_charger: Fix checkpatch warning
lp8727_charger: Add description in the private data
lp8727_charger: Fix a typo - chg_parm to chg_param
lp8727_charger: Make some cosmetic changes in lp8727_delayed_func()
lp8727_charger: Clean up lp8727_charger_changed()
lp8727_charger: Return if the battery is discharging
lp8727_charger: Make lp8727_charger_get_propery() simpler
lp8727_charger: Make lp8727_ctrl_switch() inline
lp8727_charger: Make lp8727_init_device() shorter
lp8727_charger: Clean up lp8727_is_charger_attached()
lp8727_charger: Use specific definition
lp8727_charger: Clean up lp8727 definitions
lp8727_charger: Use the definition rather than enum
lp8727_charger: Fix code for getting battery temp
lp8727_charger: Clear interrrupts at inital time
...

+3519 -297
+7
Documentation/power/power_supply_class.txt
··· 81 81 are already charged or discharging, 'n/a' can be displayed (or 82 82 'unknown', if the status is not known). 83 83 84 + AUTHENTIC - indicates the power supply (battery or charger) connected 85 + to the platform is authentic(1) or non authentic(0). 86 + 84 87 HEALTH - represents health of the battery, values corresponds to 85 88 POWER_SUPPLY_HEALTH_*, defined in battery.h. 86 89 ··· 116 113 relative, time-based measurements. 117 114 118 115 CONSTANT_CHARGE_CURRENT - constant charge current programmed by charger. 116 + CONSTANT_CHARGE_CURRENT_MAX - maximum charge current supported by the 117 + power supply object. 119 118 120 119 CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger. 120 + CONSTANT_CHARGE_VOLTAGE_MAX - maximum charge voltage supported by the 121 + power supply object. 121 122 122 123 ENERGY_FULL, ENERGY_EMPTY - same as above but for energy. 123 124
+21 -1
drivers/mfd/88pm860x-core.c
··· 24 24 #include <linux/mfd/core.h> 25 25 #include <linux/mfd/88pm860x.h> 26 26 #include <linux/regulator/machine.h> 27 + #include <linux/power/charger-manager.h> 27 28 28 29 #define INT_STATUS_NUM 3 29 30 ··· 151 150 static struct resource charger_resources[] __devinitdata = { 152 151 {PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,}, 153 152 {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,}, 154 - {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout", IORESOURCE_IRQ,}, 153 + {PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout", IORESOURCE_IRQ,}, 154 + {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging fault", IORESOURCE_IRQ,}, 155 155 {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,}, 156 156 {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,}, 157 157 {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, ··· 320 318 .consumer_supplies = &preg_supply[0], 321 319 }; 322 320 321 + static struct charger_regulator chg_desc_regulator_data[] = { 322 + { .regulator_name = "preg", }, 323 + }; 324 + 323 325 static struct mfd_cell power_devs[] = { 324 326 {"88pm860x-battery", -1,}, 325 327 {"88pm860x-charger", -1,}, 326 328 {"88pm860x-preg", -1,}, 329 + {"charger-manager", -1,}, 327 330 }; 328 331 329 332 static struct mfd_cell rtc_devs[] = { ··· 936 929 NULL, chip->irq_base, NULL); 937 930 if (ret < 0) 938 931 dev_err(chip->dev, "Failed to add preg subdev\n"); 932 + 933 + if (pdata->chg_desc) { 934 + pdata->chg_desc->charger_regulators = 935 + &chg_desc_regulator_data[0]; 936 + pdata->chg_desc->num_charger_regulators = 937 + ARRAY_SIZE(chg_desc_regulator_data), 938 + power_devs[3].platform_data = pdata->chg_desc; 939 + power_devs[3].pdata_size = sizeof(*pdata->chg_desc); 940 + ret = mfd_add_devices(chip->dev, 0, &power_devs[3], 1, 941 + NULL, chip->irq_base, NULL); 942 + if (ret < 0) 943 + dev_err(chip->dev, "Failed to add chg-manager subdev\n"); 944 + } 939 945 } 940 946 941 947 static void __devinit device_onkey_init(struct pm860x_chip *chip,
+1041
drivers/power/88pm860x_battery.c
··· 1 + /* 2 + * Battery driver for Marvell 88PM860x PMIC 3 + * 4 + * Copyright (c) 2012 Marvell International Ltd. 5 + * Author: Jett Zhou <jtzhou@marvell.com> 6 + * Haojian Zhuang <haojian.zhuang@marvell.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/slab.h> 17 + #include <linux/mutex.h> 18 + #include <linux/string.h> 19 + #include <linux/power_supply.h> 20 + #include <linux/mfd/88pm860x.h> 21 + #include <linux/delay.h> 22 + 23 + /* bit definitions of Status Query Interface 2 */ 24 + #define STATUS2_CHG (1 << 2) 25 + #define STATUS2_BAT (1 << 3) 26 + #define STATUS2_VBUS (1 << 4) 27 + 28 + /* bit definitions of Measurement Enable 1 Register */ 29 + #define MEAS1_TINT (1 << 3) 30 + #define MEAS1_GP1 (1 << 5) 31 + 32 + /* bit definitions of Measurement Enable 3 Register */ 33 + #define MEAS3_IBAT (1 << 0) 34 + #define MEAS3_BAT_DET (1 << 1) 35 + #define MEAS3_CC (1 << 2) 36 + 37 + /* bit definitions of Measurement Off Time Register */ 38 + #define MEAS_OFF_SLEEP_EN (1 << 1) 39 + 40 + /* bit definitions of GPADC Bias Current 2 Register */ 41 + #define GPBIAS2_GPADC1_SET (2 << 4) 42 + /* GPADC1 Bias Current value in uA unit */ 43 + #define GPBIAS2_GPADC1_UA ((GPBIAS2_GPADC1_SET >> 4) * 5 + 1) 44 + 45 + /* bit definitions of GPADC Misc 1 Register */ 46 + #define GPMISC1_GPADC_EN (1 << 0) 47 + 48 + /* bit definitions of Charger Control 6 Register */ 49 + #define CC6_BAT_DET_GPADC1 1 50 + 51 + /* bit definitions of Coulomb Counter Reading Register */ 52 + #define CCNT_AVG_SEL (4 << 3) 53 + 54 + /* bit definitions of RTC miscellaneous Register1 */ 55 + #define RTC_SOC_5LSB (0x1F << 3) 56 + 57 + /* bit definitions of RTC Register1 */ 58 + #define RTC_SOC_3MSB (0x7) 59 + 60 + /* bit definitions of Power up Log register */ 61 + #define BAT_WU_LOG (1<<6) 62 + 63 + /* coulomb counter index */ 64 + #define CCNT_POS1 0 65 + #define CCNT_POS2 1 66 + #define CCNT_NEG1 2 67 + #define CCNT_NEG2 3 68 + #define CCNT_SPOS 4 69 + #define CCNT_SNEG 5 70 + 71 + /* OCV -- Open Circuit Voltage */ 72 + #define OCV_MODE_ACTIVE 0 73 + #define OCV_MODE_SLEEP 1 74 + 75 + /* Vbat range of CC for measuring Rbat */ 76 + #define LOW_BAT_THRESHOLD 3600 77 + #define VBATT_RESISTOR_MIN 3800 78 + #define VBATT_RESISTOR_MAX 4100 79 + 80 + /* TBAT for batt, TINT for chip itself */ 81 + #define PM860X_TEMP_TINT (0) 82 + #define PM860X_TEMP_TBAT (1) 83 + 84 + /* 85 + * Battery temperature based on NTC resistor, defined 86 + * corresponding resistor value -- Ohm / C degeree. 87 + */ 88 + #define TBAT_NEG_25D 127773 /* -25 */ 89 + #define TBAT_NEG_10D 54564 /* -10 */ 90 + #define TBAT_0D 32330 /* 0 */ 91 + #define TBAT_10D 19785 /* 10 */ 92 + #define TBAT_20D 12468 /* 20 */ 93 + #define TBAT_30D 8072 /* 30 */ 94 + #define TBAT_40D 5356 /* 40 */ 95 + 96 + struct pm860x_battery_info { 97 + struct pm860x_chip *chip; 98 + struct i2c_client *i2c; 99 + struct device *dev; 100 + 101 + struct power_supply battery; 102 + struct mutex lock; 103 + int status; 104 + int irq_cc; 105 + int irq_batt; 106 + int max_capacity; 107 + int resistor; /* Battery Internal Resistor */ 108 + int last_capacity; 109 + int start_soc; 110 + unsigned present:1; 111 + unsigned temp_type:1; /* TINT or TBAT */ 112 + }; 113 + 114 + struct ccnt { 115 + unsigned long long int pos; 116 + unsigned long long int neg; 117 + unsigned int spos; 118 + unsigned int sneg; 119 + 120 + int total_chg; /* mAh(3.6C) */ 121 + int total_dischg; /* mAh(3.6C) */ 122 + }; 123 + 124 + /* 125 + * State of Charge. 126 + * The first number is mAh(=3.6C), and the second number is percent point. 127 + */ 128 + static int array_soc[][2] = { 129 + {4170, 100}, {4154, 99}, {4136, 98}, {4122, 97}, {4107, 96}, 130 + {4102, 95}, {4088, 94}, {4081, 93}, {4070, 92}, {4060, 91}, 131 + {4053, 90}, {4044, 89}, {4035, 88}, {4028, 87}, {4019, 86}, 132 + {4013, 85}, {4006, 84}, {3995, 83}, {3987, 82}, {3982, 81}, 133 + {3976, 80}, {3968, 79}, {3962, 78}, {3954, 77}, {3946, 76}, 134 + {3941, 75}, {3934, 74}, {3929, 73}, {3922, 72}, {3916, 71}, 135 + {3910, 70}, {3904, 69}, {3898, 68}, {3892, 67}, {3887, 66}, 136 + {3880, 65}, {3874, 64}, {3868, 63}, {3862, 62}, {3854, 61}, 137 + {3849, 60}, {3843, 59}, {3840, 58}, {3833, 57}, {3829, 56}, 138 + {3824, 55}, {3818, 54}, {3815, 53}, {3810, 52}, {3808, 51}, 139 + {3804, 50}, {3801, 49}, {3798, 48}, {3796, 47}, {3792, 46}, 140 + {3789, 45}, {3785, 44}, {3784, 43}, {3782, 42}, {3780, 41}, 141 + {3777, 40}, {3776, 39}, {3774, 38}, {3772, 37}, {3771, 36}, 142 + {3769, 35}, {3768, 34}, {3764, 33}, {3763, 32}, {3760, 31}, 143 + {3760, 30}, {3754, 29}, {3750, 28}, {3749, 27}, {3744, 26}, 144 + {3740, 25}, {3734, 24}, {3732, 23}, {3728, 22}, {3726, 21}, 145 + {3720, 20}, {3716, 19}, {3709, 18}, {3703, 17}, {3698, 16}, 146 + {3692, 15}, {3683, 14}, {3675, 13}, {3670, 12}, {3665, 11}, 147 + {3661, 10}, {3649, 9}, {3637, 8}, {3622, 7}, {3609, 6}, 148 + {3580, 5}, {3558, 4}, {3540, 3}, {3510, 2}, {3429, 1}, 149 + }; 150 + 151 + static struct ccnt ccnt_data; 152 + 153 + /* 154 + * register 1 bit[7:0] -- bit[11:4] of measured value of voltage 155 + * register 0 bit[3:0] -- bit[3:0] of measured value of voltage 156 + */ 157 + static int measure_12bit_voltage(struct pm860x_battery_info *info, 158 + int offset, int *data) 159 + { 160 + unsigned char buf[2]; 161 + int ret; 162 + 163 + ret = pm860x_bulk_read(info->i2c, offset, 2, buf); 164 + if (ret < 0) 165 + return ret; 166 + 167 + *data = ((buf[0] & 0xff) << 4) | (buf[1] & 0x0f); 168 + /* V_MEAS(mV) = data * 1.8 * 1000 / (2^12) */ 169 + *data = ((*data & 0xfff) * 9 * 25) >> 9; 170 + return 0; 171 + } 172 + 173 + static int measure_vbatt(struct pm860x_battery_info *info, int state, 174 + int *data) 175 + { 176 + unsigned char buf[5]; 177 + int ret; 178 + 179 + switch (state) { 180 + case OCV_MODE_ACTIVE: 181 + ret = measure_12bit_voltage(info, PM8607_VBAT_MEAS1, data); 182 + if (ret) 183 + return ret; 184 + /* V_BATT_MEAS(mV) = value * 3 * 1.8 * 1000 / (2^12) */ 185 + *data *= 3; 186 + break; 187 + case OCV_MODE_SLEEP: 188 + /* 189 + * voltage value of VBATT in sleep mode is saved in different 190 + * registers. 191 + * bit[11:10] -- bit[7:6] of LDO9(0x18) 192 + * bit[9:8] -- bit[7:6] of LDO8(0x17) 193 + * bit[7:6] -- bit[7:6] of LDO7(0x16) 194 + * bit[5:4] -- bit[7:6] of LDO6(0x15) 195 + * bit[3:0] -- bit[7:4] of LDO5(0x14) 196 + */ 197 + ret = pm860x_bulk_read(info->i2c, PM8607_LDO5, 5, buf); 198 + if (ret < 0) 199 + return ret; 200 + ret = ((buf[4] >> 6) << 10) | ((buf[3] >> 6) << 8) 201 + | ((buf[2] >> 6) << 6) | ((buf[1] >> 6) << 4) 202 + | (buf[0] >> 4); 203 + /* V_BATT_MEAS(mV) = data * 3 * 1.8 * 1000 / (2^12) */ 204 + *data = ((*data & 0xff) * 27 * 25) >> 9; 205 + break; 206 + default: 207 + return -EINVAL; 208 + } 209 + return 0; 210 + } 211 + 212 + /* 213 + * Return value is signed data. 214 + * Negative value means discharging, and positive value means charging. 215 + */ 216 + static int measure_current(struct pm860x_battery_info *info, int *data) 217 + { 218 + unsigned char buf[2]; 219 + short s; 220 + int ret; 221 + 222 + ret = pm860x_bulk_read(info->i2c, PM8607_IBAT_MEAS1, 2, buf); 223 + if (ret < 0) 224 + return ret; 225 + 226 + s = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff); 227 + /* current(mA) = value * 0.125 */ 228 + *data = s >> 3; 229 + return 0; 230 + } 231 + 232 + static int set_charger_current(struct pm860x_battery_info *info, int data, 233 + int *old) 234 + { 235 + int ret; 236 + 237 + if (data < 50 || data > 1600 || !old) 238 + return -EINVAL; 239 + 240 + data = ((data - 50) / 50) & 0x1f; 241 + *old = pm860x_reg_read(info->i2c, PM8607_CHG_CTRL2); 242 + *old = (*old & 0x1f) * 50 + 50; 243 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL2, 0x1f, data); 244 + if (ret < 0) 245 + return ret; 246 + return 0; 247 + } 248 + 249 + static int read_ccnt(struct pm860x_battery_info *info, int offset, 250 + int *ccnt) 251 + { 252 + unsigned char buf[2]; 253 + int ret; 254 + 255 + ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7, offset & 7); 256 + if (ret < 0) 257 + goto out; 258 + ret = pm860x_bulk_read(info->i2c, PM8607_CCNT_MEAS1, 2, buf); 259 + if (ret < 0) 260 + goto out; 261 + *ccnt = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff); 262 + return 0; 263 + out: 264 + return ret; 265 + } 266 + 267 + static int calc_ccnt(struct pm860x_battery_info *info, struct ccnt *ccnt) 268 + { 269 + unsigned int sum; 270 + int ret; 271 + int data; 272 + 273 + ret = read_ccnt(info, CCNT_POS1, &data); 274 + if (ret) 275 + goto out; 276 + sum = data & 0xffff; 277 + ret = read_ccnt(info, CCNT_POS2, &data); 278 + if (ret) 279 + goto out; 280 + sum |= (data & 0xffff) << 16; 281 + ccnt->pos += sum; 282 + 283 + ret = read_ccnt(info, CCNT_NEG1, &data); 284 + if (ret) 285 + goto out; 286 + sum = data & 0xffff; 287 + ret = read_ccnt(info, CCNT_NEG2, &data); 288 + if (ret) 289 + goto out; 290 + sum |= (data & 0xffff) << 16; 291 + sum = ~sum + 1; /* since it's negative */ 292 + ccnt->neg += sum; 293 + 294 + ret = read_ccnt(info, CCNT_SPOS, &data); 295 + if (ret) 296 + goto out; 297 + ccnt->spos += data; 298 + ret = read_ccnt(info, CCNT_SNEG, &data); 299 + if (ret) 300 + goto out; 301 + 302 + /* 303 + * charge(mAh) = count * 1.6984 * 1e(-8) 304 + * = count * 16984 * 1.024 * 1.024 * 1.024 / (2 ^ 40) 305 + * = count * 18236 / (2 ^ 40) 306 + */ 307 + ccnt->total_chg = (int) ((ccnt->pos * 18236) >> 40); 308 + ccnt->total_dischg = (int) ((ccnt->neg * 18236) >> 40); 309 + return 0; 310 + out: 311 + return ret; 312 + } 313 + 314 + static int clear_ccnt(struct pm860x_battery_info *info, struct ccnt *ccnt) 315 + { 316 + int data; 317 + 318 + memset(ccnt, 0, sizeof(*ccnt)); 319 + /* read to clear ccnt */ 320 + read_ccnt(info, CCNT_POS1, &data); 321 + read_ccnt(info, CCNT_POS2, &data); 322 + read_ccnt(info, CCNT_NEG1, &data); 323 + read_ccnt(info, CCNT_NEG2, &data); 324 + read_ccnt(info, CCNT_SPOS, &data); 325 + read_ccnt(info, CCNT_SNEG, &data); 326 + return 0; 327 + } 328 + 329 + /* Calculate Open Circuit Voltage */ 330 + static int calc_ocv(struct pm860x_battery_info *info, int *ocv) 331 + { 332 + int ret; 333 + int i; 334 + int data; 335 + int vbatt_avg; 336 + int vbatt_sum; 337 + int ibatt_avg; 338 + int ibatt_sum; 339 + 340 + if (!ocv) 341 + return -EINVAL; 342 + 343 + for (i = 0, ibatt_sum = 0, vbatt_sum = 0; i < 10; i++) { 344 + ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data); 345 + if (ret) 346 + goto out; 347 + vbatt_sum += data; 348 + ret = measure_current(info, &data); 349 + if (ret) 350 + goto out; 351 + ibatt_sum += data; 352 + } 353 + vbatt_avg = vbatt_sum / 10; 354 + ibatt_avg = ibatt_sum / 10; 355 + 356 + mutex_lock(&info->lock); 357 + if (info->present) 358 + *ocv = vbatt_avg - ibatt_avg * info->resistor / 1000; 359 + else 360 + *ocv = vbatt_avg; 361 + mutex_unlock(&info->lock); 362 + dev_dbg(info->dev, "VBAT average:%d, OCV:%d\n", vbatt_avg, *ocv); 363 + return 0; 364 + out: 365 + return ret; 366 + } 367 + 368 + /* Calculate State of Charge (percent points) */ 369 + static int calc_soc(struct pm860x_battery_info *info, int state, int *soc) 370 + { 371 + int i; 372 + int ocv; 373 + int count; 374 + int ret = -EINVAL; 375 + 376 + if (!soc) 377 + return -EINVAL; 378 + 379 + switch (state) { 380 + case OCV_MODE_ACTIVE: 381 + ret = calc_ocv(info, &ocv); 382 + break; 383 + case OCV_MODE_SLEEP: 384 + ret = measure_vbatt(info, OCV_MODE_SLEEP, &ocv); 385 + break; 386 + } 387 + if (ret) 388 + return ret; 389 + 390 + count = ARRAY_SIZE(array_soc); 391 + if (ocv < array_soc[count - 1][0]) { 392 + *soc = 0; 393 + return 0; 394 + } 395 + 396 + for (i = 0; i < count; i++) { 397 + if (ocv >= array_soc[i][0]) { 398 + *soc = array_soc[i][1]; 399 + break; 400 + } 401 + } 402 + return 0; 403 + } 404 + 405 + static irqreturn_t pm860x_coulomb_handler(int irq, void *data) 406 + { 407 + struct pm860x_battery_info *info = data; 408 + 409 + calc_ccnt(info, &ccnt_data); 410 + return IRQ_HANDLED; 411 + } 412 + 413 + static irqreturn_t pm860x_batt_handler(int irq, void *data) 414 + { 415 + struct pm860x_battery_info *info = data; 416 + int ret; 417 + 418 + mutex_lock(&info->lock); 419 + ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); 420 + if (ret & STATUS2_BAT) { 421 + info->present = 1; 422 + info->temp_type = PM860X_TEMP_TBAT; 423 + } else { 424 + info->present = 0; 425 + info->temp_type = PM860X_TEMP_TINT; 426 + } 427 + mutex_unlock(&info->lock); 428 + /* clear ccnt since battery is attached or dettached */ 429 + clear_ccnt(info, &ccnt_data); 430 + return IRQ_HANDLED; 431 + } 432 + 433 + static void pm860x_init_battery(struct pm860x_battery_info *info) 434 + { 435 + unsigned char buf[2]; 436 + int ret; 437 + int data; 438 + int bat_remove; 439 + int soc; 440 + 441 + /* measure enable on GPADC1 */ 442 + data = MEAS1_GP1; 443 + if (info->temp_type == PM860X_TEMP_TINT) 444 + data |= MEAS1_TINT; 445 + ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN1, data, data); 446 + if (ret) 447 + goto out; 448 + 449 + /* measure enable on IBAT, BAT_DET, CC. IBAT is depend on CC. */ 450 + data = MEAS3_IBAT | MEAS3_BAT_DET | MEAS3_CC; 451 + ret = pm860x_set_bits(info->i2c, PM8607_MEAS_EN3, data, data); 452 + if (ret) 453 + goto out; 454 + 455 + /* measure disable CC in sleep time */ 456 + ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME1, 0x82); 457 + if (ret) 458 + goto out; 459 + ret = pm860x_reg_write(info->i2c, PM8607_MEAS_OFF_TIME2, 0x6c); 460 + if (ret) 461 + goto out; 462 + 463 + /* enable GPADC */ 464 + ret = pm860x_set_bits(info->i2c, PM8607_GPADC_MISC1, 465 + GPMISC1_GPADC_EN, GPMISC1_GPADC_EN); 466 + if (ret < 0) 467 + goto out; 468 + 469 + /* detect battery via GPADC1 */ 470 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL6, 471 + CC6_BAT_DET_GPADC1, CC6_BAT_DET_GPADC1); 472 + if (ret < 0) 473 + goto out; 474 + 475 + ret = pm860x_set_bits(info->i2c, PM8607_CCNT, 7 << 3, 476 + CCNT_AVG_SEL); 477 + if (ret < 0) 478 + goto out; 479 + 480 + /* set GPADC1 bias */ 481 + ret = pm860x_set_bits(info->i2c, PM8607_GP_BIAS2, 0xF << 4, 482 + GPBIAS2_GPADC1_SET); 483 + if (ret < 0) 484 + goto out; 485 + 486 + /* check whether battery present) */ 487 + mutex_lock(&info->lock); 488 + ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); 489 + if (ret < 0) { 490 + mutex_unlock(&info->lock); 491 + goto out; 492 + } 493 + if (ret & STATUS2_BAT) { 494 + info->present = 1; 495 + info->temp_type = PM860X_TEMP_TBAT; 496 + } else { 497 + info->present = 0; 498 + info->temp_type = PM860X_TEMP_TINT; 499 + } 500 + mutex_unlock(&info->lock); 501 + 502 + calc_soc(info, OCV_MODE_ACTIVE, &soc); 503 + 504 + data = pm860x_reg_read(info->i2c, PM8607_POWER_UP_LOG); 505 + bat_remove = data & BAT_WU_LOG; 506 + 507 + dev_dbg(info->dev, "battery wake up? %s\n", 508 + bat_remove != 0 ? "yes" : "no"); 509 + 510 + /* restore SOC from RTC domain register */ 511 + if (bat_remove == 0) { 512 + buf[0] = pm860x_reg_read(info->i2c, PM8607_RTC_MISC2); 513 + buf[1] = pm860x_reg_read(info->i2c, PM8607_RTC1); 514 + data = ((buf[1] & 0x3) << 5) | ((buf[0] >> 3) & 0x1F); 515 + if (data > soc + 15) 516 + info->start_soc = soc; 517 + else if (data < soc - 15) 518 + info->start_soc = soc; 519 + else 520 + info->start_soc = data; 521 + dev_dbg(info->dev, "soc_rtc %d, soc_ocv :%d\n", data, soc); 522 + } else { 523 + pm860x_set_bits(info->i2c, PM8607_POWER_UP_LOG, 524 + BAT_WU_LOG, BAT_WU_LOG); 525 + info->start_soc = soc; 526 + } 527 + info->last_capacity = info->start_soc; 528 + dev_dbg(info->dev, "init soc : %d\n", info->last_capacity); 529 + out: 530 + return; 531 + } 532 + 533 + static void set_temp_threshold(struct pm860x_battery_info *info, 534 + int min, int max) 535 + { 536 + int data; 537 + 538 + /* (tmp << 8) / 1800 */ 539 + if (min <= 0) 540 + data = 0; 541 + else 542 + data = (min << 8) / 1800; 543 + pm860x_reg_write(info->i2c, PM8607_GPADC1_HIGHTH, data); 544 + dev_dbg(info->dev, "TEMP_HIGHTH : min: %d, 0x%x\n", min, data); 545 + 546 + if (max <= 0) 547 + data = 0xff; 548 + else 549 + data = (max << 8) / 1800; 550 + pm860x_reg_write(info->i2c, PM8607_GPADC1_LOWTH, data); 551 + dev_dbg(info->dev, "TEMP_LOWTH:max : %d, 0x%x\n", max, data); 552 + } 553 + 554 + static int measure_temp(struct pm860x_battery_info *info, int *data) 555 + { 556 + int ret; 557 + int temp; 558 + int min; 559 + int max; 560 + 561 + if (info->temp_type == PM860X_TEMP_TINT) { 562 + ret = measure_12bit_voltage(info, PM8607_TINT_MEAS1, data); 563 + if (ret) 564 + return ret; 565 + *data = (*data - 884) * 1000 / 3611; 566 + } else { 567 + ret = measure_12bit_voltage(info, PM8607_GPADC1_MEAS1, data); 568 + if (ret) 569 + return ret; 570 + /* meausered Vtbat(mV) / Ibias_current(11uA)*/ 571 + *data = (*data * 1000) / GPBIAS2_GPADC1_UA; 572 + 573 + if (*data > TBAT_NEG_25D) { 574 + temp = -30; /* over cold , suppose -30 roughly */ 575 + max = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000; 576 + set_temp_threshold(info, 0, max); 577 + } else if (*data > TBAT_NEG_10D) { 578 + temp = -15; /* -15 degree, code */ 579 + max = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000; 580 + set_temp_threshold(info, 0, max); 581 + } else if (*data > TBAT_0D) { 582 + temp = -5; /* -5 degree */ 583 + min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000; 584 + max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000; 585 + set_temp_threshold(info, min, max); 586 + } else if (*data > TBAT_10D) { 587 + temp = 5; /* in range of (0, 10) */ 588 + min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000; 589 + max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000; 590 + set_temp_threshold(info, min, max); 591 + } else if (*data > TBAT_20D) { 592 + temp = 15; /* in range of (10, 20) */ 593 + min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000; 594 + max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000; 595 + set_temp_threshold(info, min, max); 596 + } else if (*data > TBAT_30D) { 597 + temp = 25; /* in range of (20, 30) */ 598 + min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000; 599 + max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000; 600 + set_temp_threshold(info, min, max); 601 + } else if (*data > TBAT_40D) { 602 + temp = 35; /* in range of (30, 40) */ 603 + min = TBAT_NEG_10D * GPBIAS2_GPADC1_UA / 1000; 604 + max = TBAT_40D * GPBIAS2_GPADC1_UA / 1000; 605 + set_temp_threshold(info, min, max); 606 + } else { 607 + min = TBAT_40D * GPBIAS2_GPADC1_UA / 1000; 608 + set_temp_threshold(info, min, 0); 609 + temp = 45; /* over heat ,suppose 45 roughly */ 610 + } 611 + 612 + dev_dbg(info->dev, "temp_C:%d C,temp_mv:%d mv\n", temp, *data); 613 + *data = temp; 614 + } 615 + return 0; 616 + } 617 + 618 + static int calc_resistor(struct pm860x_battery_info *info) 619 + { 620 + int vbatt_sum1; 621 + int vbatt_sum2; 622 + int chg_current; 623 + int ibatt_sum1; 624 + int ibatt_sum2; 625 + int data; 626 + int ret; 627 + int i; 628 + 629 + ret = measure_current(info, &data); 630 + /* make sure that charging is launched by data > 0 */ 631 + if (ret || data < 0) 632 + goto out; 633 + 634 + ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data); 635 + if (ret) 636 + goto out; 637 + /* calculate resistor only in CC charge mode */ 638 + if (data < VBATT_RESISTOR_MIN || data > VBATT_RESISTOR_MAX) 639 + goto out; 640 + 641 + /* current is saved */ 642 + if (set_charger_current(info, 500, &chg_current)) 643 + goto out; 644 + 645 + /* 646 + * set charge current as 500mA, wait about 500ms till charging 647 + * process is launched and stable with the newer charging current. 648 + */ 649 + msleep(500); 650 + 651 + for (i = 0, vbatt_sum1 = 0, ibatt_sum1 = 0; i < 10; i++) { 652 + ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data); 653 + if (ret) 654 + goto out_meas; 655 + vbatt_sum1 += data; 656 + ret = measure_current(info, &data); 657 + if (ret) 658 + goto out_meas; 659 + 660 + if (data < 0) 661 + ibatt_sum1 = ibatt_sum1 - data; /* discharging */ 662 + else 663 + ibatt_sum1 = ibatt_sum1 + data; /* charging */ 664 + } 665 + 666 + if (set_charger_current(info, 100, &ret)) 667 + goto out_meas; 668 + /* 669 + * set charge current as 100mA, wait about 500ms till charging 670 + * process is launched and stable with the newer charging current. 671 + */ 672 + msleep(500); 673 + 674 + for (i = 0, vbatt_sum2 = 0, ibatt_sum2 = 0; i < 10; i++) { 675 + ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data); 676 + if (ret) 677 + goto out_meas; 678 + vbatt_sum2 += data; 679 + ret = measure_current(info, &data); 680 + if (ret) 681 + goto out_meas; 682 + 683 + if (data < 0) 684 + ibatt_sum2 = ibatt_sum2 - data; /* discharging */ 685 + else 686 + ibatt_sum2 = ibatt_sum2 + data; /* charging */ 687 + } 688 + 689 + /* restore current setting */ 690 + if (set_charger_current(info, chg_current, &ret)) 691 + goto out_meas; 692 + 693 + if ((vbatt_sum1 > vbatt_sum2) && (ibatt_sum1 > ibatt_sum2) && 694 + (ibatt_sum2 > 0)) { 695 + /* calculate resistor in discharging case */ 696 + data = 1000 * (vbatt_sum1 - vbatt_sum2) 697 + / (ibatt_sum1 - ibatt_sum2); 698 + if ((data - info->resistor > 0) && 699 + (data - info->resistor < info->resistor)) 700 + info->resistor = data; 701 + if ((info->resistor - data > 0) && 702 + (info->resistor - data < data)) 703 + info->resistor = data; 704 + } 705 + return 0; 706 + 707 + out_meas: 708 + set_charger_current(info, chg_current, &ret); 709 + out: 710 + return -EINVAL; 711 + } 712 + 713 + static int calc_capacity(struct pm860x_battery_info *info, int *cap) 714 + { 715 + int ret; 716 + int data; 717 + int ibat; 718 + int cap_ocv = 0; 719 + int cap_cc = 0; 720 + 721 + ret = calc_ccnt(info, &ccnt_data); 722 + if (ret) 723 + goto out; 724 + soc: 725 + data = info->max_capacity * info->start_soc / 100; 726 + if (ccnt_data.total_dischg - ccnt_data.total_chg <= data) { 727 + cap_cc = 728 + data + ccnt_data.total_chg - ccnt_data.total_dischg; 729 + } else { 730 + clear_ccnt(info, &ccnt_data); 731 + calc_soc(info, OCV_MODE_ACTIVE, &info->start_soc); 732 + dev_dbg(info->dev, "restart soc = %d !\n", 733 + info->start_soc); 734 + goto soc; 735 + } 736 + 737 + cap_cc = cap_cc * 100 / info->max_capacity; 738 + if (cap_cc < 0) 739 + cap_cc = 0; 740 + else if (cap_cc > 100) 741 + cap_cc = 100; 742 + 743 + dev_dbg(info->dev, "%s, last cap : %d", __func__, 744 + info->last_capacity); 745 + 746 + ret = measure_current(info, &ibat); 747 + if (ret) 748 + goto out; 749 + /* Calculate the capacity when discharging(ibat < 0) */ 750 + if (ibat < 0) { 751 + ret = calc_soc(info, OCV_MODE_ACTIVE, &cap_ocv); 752 + if (ret) 753 + cap_ocv = info->last_capacity; 754 + ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data); 755 + if (ret) 756 + goto out; 757 + if (data <= LOW_BAT_THRESHOLD) { 758 + /* choose the lower capacity value to report 759 + * between vbat and CC when vbat < 3.6v; 760 + * than 3.6v; 761 + */ 762 + *cap = min(cap_ocv, cap_cc); 763 + } else { 764 + /* when detect vbat > 3.6v, but cap_cc < 15,and 765 + * cap_ocv is 10% larger than cap_cc, we can think 766 + * CC have some accumulation error, switch to OCV 767 + * to estimate capacity; 768 + * */ 769 + if (cap_cc < 15 && cap_ocv - cap_cc > 10) 770 + *cap = cap_ocv; 771 + else 772 + *cap = cap_cc; 773 + } 774 + /* when discharging, make sure current capacity 775 + * is lower than last*/ 776 + if (*cap > info->last_capacity) 777 + *cap = info->last_capacity; 778 + } else { 779 + *cap = cap_cc; 780 + } 781 + info->last_capacity = *cap; 782 + 783 + dev_dbg(info->dev, "%s, cap_ocv:%d cap_cc:%d, cap:%d\n", 784 + (ibat < 0) ? "discharging" : "charging", 785 + cap_ocv, cap_cc, *cap); 786 + /* 787 + * store the current capacity to RTC domain register, 788 + * after next power up , it will be restored. 789 + */ 790 + pm860x_set_bits(info->i2c, PM8607_RTC_MISC2, RTC_SOC_5LSB, 791 + (*cap & 0x1F) << 3); 792 + pm860x_set_bits(info->i2c, PM8607_RTC1, RTC_SOC_3MSB, 793 + ((*cap >> 5) & 0x3)); 794 + return 0; 795 + out: 796 + return ret; 797 + } 798 + 799 + static void pm860x_external_power_changed(struct power_supply *psy) 800 + { 801 + struct pm860x_battery_info *info; 802 + 803 + info = container_of(psy, struct pm860x_battery_info, battery); 804 + calc_resistor(info); 805 + } 806 + 807 + static int pm860x_batt_get_prop(struct power_supply *psy, 808 + enum power_supply_property psp, 809 + union power_supply_propval *val) 810 + { 811 + struct pm860x_battery_info *info = dev_get_drvdata(psy->dev->parent); 812 + int data; 813 + int ret; 814 + 815 + switch (psp) { 816 + case POWER_SUPPLY_PROP_PRESENT: 817 + val->intval = info->present; 818 + break; 819 + case POWER_SUPPLY_PROP_CAPACITY: 820 + ret = calc_capacity(info, &data); 821 + if (ret) 822 + return ret; 823 + if (data < 0) 824 + data = 0; 825 + else if (data > 100) 826 + data = 100; 827 + /* return 100 if battery is not attached */ 828 + if (!info->present) 829 + data = 100; 830 + val->intval = data; 831 + break; 832 + case POWER_SUPPLY_PROP_TECHNOLOGY: 833 + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 834 + break; 835 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 836 + /* return real vbatt Voltage */ 837 + ret = measure_vbatt(info, OCV_MODE_ACTIVE, &data); 838 + if (ret) 839 + return ret; 840 + val->intval = data * 1000; 841 + break; 842 + case POWER_SUPPLY_PROP_VOLTAGE_AVG: 843 + /* return Open Circuit Voltage (not measured voltage) */ 844 + ret = calc_ocv(info, &data); 845 + if (ret) 846 + return ret; 847 + val->intval = data * 1000; 848 + break; 849 + case POWER_SUPPLY_PROP_CURRENT_NOW: 850 + ret = measure_current(info, &data); 851 + if (ret) 852 + return ret; 853 + val->intval = data; 854 + break; 855 + case POWER_SUPPLY_PROP_TEMP: 856 + if (info->present) { 857 + ret = measure_temp(info, &data); 858 + if (ret) 859 + return ret; 860 + data *= 10; 861 + } else { 862 + /* Fake Temp 25C Without Battery */ 863 + data = 250; 864 + } 865 + val->intval = data; 866 + break; 867 + default: 868 + return -ENODEV; 869 + } 870 + return 0; 871 + } 872 + 873 + static int pm860x_batt_set_prop(struct power_supply *psy, 874 + enum power_supply_property psp, 875 + const union power_supply_propval *val) 876 + { 877 + struct pm860x_battery_info *info = dev_get_drvdata(psy->dev->parent); 878 + 879 + switch (psp) { 880 + case POWER_SUPPLY_PROP_CHARGE_FULL: 881 + clear_ccnt(info, &ccnt_data); 882 + info->start_soc = 100; 883 + dev_dbg(info->dev, "chg done, update soc = %d\n", 884 + info->start_soc); 885 + break; 886 + default: 887 + return -EPERM; 888 + } 889 + 890 + return 0; 891 + } 892 + 893 + 894 + static enum power_supply_property pm860x_batt_props[] = { 895 + POWER_SUPPLY_PROP_PRESENT, 896 + POWER_SUPPLY_PROP_CAPACITY, 897 + POWER_SUPPLY_PROP_TECHNOLOGY, 898 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 899 + POWER_SUPPLY_PROP_VOLTAGE_AVG, 900 + POWER_SUPPLY_PROP_CURRENT_NOW, 901 + POWER_SUPPLY_PROP_TEMP, 902 + }; 903 + 904 + static __devinit int pm860x_battery_probe(struct platform_device *pdev) 905 + { 906 + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 907 + struct pm860x_battery_info *info; 908 + struct pm860x_power_pdata *pdata; 909 + int ret; 910 + 911 + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 912 + if (!info) 913 + return -ENOMEM; 914 + 915 + info->irq_cc = platform_get_irq(pdev, 0); 916 + if (info->irq_cc <= 0) { 917 + dev_err(&pdev->dev, "No IRQ resource!\n"); 918 + ret = -EINVAL; 919 + goto out; 920 + } 921 + 922 + info->irq_batt = platform_get_irq(pdev, 1); 923 + if (info->irq_batt <= 0) { 924 + dev_err(&pdev->dev, "No IRQ resource!\n"); 925 + ret = -EINVAL; 926 + goto out; 927 + } 928 + 929 + info->chip = chip; 930 + info->i2c = 931 + (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 932 + info->dev = &pdev->dev; 933 + info->status = POWER_SUPPLY_STATUS_UNKNOWN; 934 + pdata = pdev->dev.platform_data; 935 + 936 + mutex_init(&info->lock); 937 + platform_set_drvdata(pdev, info); 938 + 939 + pm860x_init_battery(info); 940 + 941 + info->battery.name = "battery-monitor"; 942 + info->battery.type = POWER_SUPPLY_TYPE_BATTERY; 943 + info->battery.properties = pm860x_batt_props; 944 + info->battery.num_properties = ARRAY_SIZE(pm860x_batt_props); 945 + info->battery.get_property = pm860x_batt_get_prop; 946 + info->battery.set_property = pm860x_batt_set_prop; 947 + info->battery.external_power_changed = pm860x_external_power_changed; 948 + 949 + if (pdata && pdata->max_capacity) 950 + info->max_capacity = pdata->max_capacity; 951 + else 952 + info->max_capacity = 1500; /* set default capacity */ 953 + if (pdata && pdata->resistor) 954 + info->resistor = pdata->resistor; 955 + else 956 + info->resistor = 300; /* set default internal resistor */ 957 + 958 + ret = power_supply_register(&pdev->dev, &info->battery); 959 + if (ret) 960 + goto out; 961 + info->battery.dev->parent = &pdev->dev; 962 + 963 + ret = request_threaded_irq(info->irq_cc, NULL, 964 + pm860x_coulomb_handler, IRQF_ONESHOT, 965 + "coulomb", info); 966 + if (ret < 0) { 967 + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", 968 + info->irq_cc, ret); 969 + goto out_reg; 970 + } 971 + 972 + ret = request_threaded_irq(info->irq_batt, NULL, pm860x_batt_handler, 973 + IRQF_ONESHOT, "battery", info); 974 + if (ret < 0) { 975 + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", 976 + info->irq_batt, ret); 977 + goto out_coulomb; 978 + } 979 + 980 + 981 + return 0; 982 + 983 + out_coulomb: 984 + free_irq(info->irq_cc, info); 985 + out_reg: 986 + power_supply_unregister(&info->battery); 987 + out: 988 + kfree(info); 989 + return ret; 990 + } 991 + 992 + static int __devexit pm860x_battery_remove(struct platform_device *pdev) 993 + { 994 + struct pm860x_battery_info *info = platform_get_drvdata(pdev); 995 + 996 + power_supply_unregister(&info->battery); 997 + free_irq(info->irq_batt, info); 998 + free_irq(info->irq_cc, info); 999 + kfree(info); 1000 + platform_set_drvdata(pdev, NULL); 1001 + return 0; 1002 + } 1003 + 1004 + #ifdef CONFIG_PM_SLEEP 1005 + static int pm860x_battery_suspend(struct device *dev) 1006 + { 1007 + struct platform_device *pdev = to_platform_device(dev); 1008 + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 1009 + 1010 + if (device_may_wakeup(dev)) 1011 + chip->wakeup_flag |= 1 << PM8607_IRQ_CC; 1012 + return 0; 1013 + } 1014 + 1015 + static int pm860x_battery_resume(struct device *dev) 1016 + { 1017 + struct platform_device *pdev = to_platform_device(dev); 1018 + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 1019 + 1020 + if (device_may_wakeup(dev)) 1021 + chip->wakeup_flag &= ~(1 << PM8607_IRQ_CC); 1022 + return 0; 1023 + } 1024 + #endif 1025 + 1026 + static SIMPLE_DEV_PM_OPS(pm860x_battery_pm_ops, 1027 + pm860x_battery_suspend, pm860x_battery_resume); 1028 + 1029 + static struct platform_driver pm860x_battery_driver = { 1030 + .driver = { 1031 + .name = "88pm860x-battery", 1032 + .owner = THIS_MODULE, 1033 + .pm = &pm860x_battery_pm_ops, 1034 + }, 1035 + .probe = pm860x_battery_probe, 1036 + .remove = __devexit_p(pm860x_battery_remove), 1037 + }; 1038 + module_platform_driver(pm860x_battery_driver); 1039 + 1040 + MODULE_DESCRIPTION("Marvell 88PM860x Battery driver"); 1041 + MODULE_LICENSE("GPL");
+746
drivers/power/88pm860x_charger.c
··· 1 + /* 2 + * Battery driver for Marvell 88PM860x PMIC 3 + * 4 + * Copyright (c) 2012 Marvell International Ltd. 5 + * Author: Jett Zhou <jtzhou@marvell.com> 6 + * Haojian Zhuang <haojian.zhuang@marvell.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/slab.h> 17 + #include <linux/power_supply.h> 18 + #include <linux/mfd/88pm860x.h> 19 + #include <linux/delay.h> 20 + #include <linux/uaccess.h> 21 + #include <asm/div64.h> 22 + 23 + /* bit definitions of Status Query Interface 2 */ 24 + #define STATUS2_CHG (1 << 2) 25 + 26 + /* bit definitions of Reset Out Register */ 27 + #define RESET_SW_PD (1 << 7) 28 + 29 + /* bit definitions of PreReg 1 */ 30 + #define PREREG1_90MA (0x0) 31 + #define PREREG1_180MA (0x1) 32 + #define PREREG1_450MA (0x4) 33 + #define PREREG1_540MA (0x5) 34 + #define PREREG1_1350MA (0xE) 35 + #define PREREG1_VSYS_4_5V (3 << 4) 36 + 37 + /* bit definitions of Charger Control 1 Register */ 38 + #define CC1_MODE_OFF (0) 39 + #define CC1_MODE_PRECHARGE (1) 40 + #define CC1_MODE_FASTCHARGE (2) 41 + #define CC1_MODE_PULSECHARGE (3) 42 + #define CC1_ITERM_20MA (0 << 2) 43 + #define CC1_ITERM_60MA (2 << 2) 44 + #define CC1_VFCHG_4_2V (9 << 4) 45 + 46 + /* bit definitions of Charger Control 2 Register */ 47 + #define CC2_ICHG_100MA (0x1) 48 + #define CC2_ICHG_500MA (0x9) 49 + #define CC2_ICHG_1000MA (0x13) 50 + 51 + /* bit definitions of Charger Control 3 Register */ 52 + #define CC3_180MIN_TIMEOUT (0x6 << 4) 53 + #define CC3_270MIN_TIMEOUT (0x7 << 4) 54 + #define CC3_360MIN_TIMEOUT (0xA << 4) 55 + #define CC3_DISABLE_TIMEOUT (0xF << 4) 56 + 57 + /* bit definitions of Charger Control 4 Register */ 58 + #define CC4_IPRE_40MA (7) 59 + #define CC4_VPCHG_3_2V (3 << 4) 60 + #define CC4_IFCHG_MON_EN (1 << 6) 61 + #define CC4_BTEMP_MON_EN (1 << 7) 62 + 63 + /* bit definitions of Charger Control 6 Register */ 64 + #define CC6_BAT_OV_EN (1 << 2) 65 + #define CC6_BAT_UV_EN (1 << 3) 66 + #define CC6_UV_VBAT_SET (0x3 << 6) /* 2.8v */ 67 + 68 + /* bit definitions of Charger Control 7 Register */ 69 + #define CC7_BAT_REM_EN (1 << 3) 70 + #define CC7_IFSM_EN (1 << 7) 71 + 72 + /* bit definitions of Measurement Enable 1 Register */ 73 + #define MEAS1_VBAT (1 << 0) 74 + 75 + /* bit definitions of Measurement Enable 3 Register */ 76 + #define MEAS3_IBAT_EN (1 << 0) 77 + #define MEAS3_CC_EN (1 << 2) 78 + 79 + #define FSM_INIT 0 80 + #define FSM_DISCHARGE 1 81 + #define FSM_PRECHARGE 2 82 + #define FSM_FASTCHARGE 3 83 + 84 + #define PRECHARGE_THRESHOLD 3100 85 + #define POWEROFF_THRESHOLD 3400 86 + #define CHARGE_THRESHOLD 4000 87 + #define DISCHARGE_THRESHOLD 4180 88 + 89 + /* over-temperature on PM8606 setting */ 90 + #define OVER_TEMP_FLAG (1 << 6) 91 + #define OVTEMP_AUTORECOVER (1 << 3) 92 + 93 + /* over-voltage protect on vchg setting mv */ 94 + #define VCHG_NORMAL_LOW 4200 95 + #define VCHG_NORMAL_CHECK 5800 96 + #define VCHG_NORMAL_HIGH 6000 97 + #define VCHG_OVP_LOW 5500 98 + 99 + struct pm860x_charger_info { 100 + struct pm860x_chip *chip; 101 + struct i2c_client *i2c; 102 + struct i2c_client *i2c_8606; 103 + struct device *dev; 104 + 105 + struct power_supply usb; 106 + struct mutex lock; 107 + int irq_nums; 108 + int irq[7]; 109 + unsigned state:3; /* fsm state */ 110 + unsigned online:1; /* usb charger */ 111 + unsigned present:1; /* battery present */ 112 + unsigned allowed:1; 113 + }; 114 + 115 + static char *pm860x_supplied_to[] = { 116 + "battery-monitor", 117 + }; 118 + 119 + static int measure_vchg(struct pm860x_charger_info *info, int *data) 120 + { 121 + unsigned char buf[2]; 122 + int ret = 0; 123 + 124 + ret = pm860x_bulk_read(info->i2c, PM8607_VCHG_MEAS1, 2, buf); 125 + if (ret < 0) 126 + return ret; 127 + 128 + *data = ((buf[0] & 0xff) << 4) | (buf[1] & 0x0f); 129 + /* V_BATT_MEAS(mV) = value * 5 * 1.8 * 1000 / (2^12) */ 130 + *data = ((*data & 0xfff) * 9 * 125) >> 9; 131 + 132 + dev_dbg(info->dev, "%s, vchg: %d mv\n", __func__, *data); 133 + 134 + return ret; 135 + } 136 + 137 + static void set_vchg_threshold(struct pm860x_charger_info *info, 138 + int min, int max) 139 + { 140 + int data; 141 + 142 + /* (tmp << 8) * / 5 / 1800 */ 143 + if (min <= 0) 144 + data = 0; 145 + else 146 + data = (min << 5) / 1125; 147 + pm860x_reg_write(info->i2c, PM8607_VCHG_LOWTH, data); 148 + dev_dbg(info->dev, "VCHG_LOWTH:%dmv, 0x%x\n", min, data); 149 + 150 + if (max <= 0) 151 + data = 0xff; 152 + else 153 + data = (max << 5) / 1125; 154 + pm860x_reg_write(info->i2c, PM8607_VCHG_HIGHTH, data); 155 + dev_dbg(info->dev, "VCHG_HIGHTH:%dmv, 0x%x\n", max, data); 156 + 157 + } 158 + 159 + static void set_vbatt_threshold(struct pm860x_charger_info *info, 160 + int min, int max) 161 + { 162 + int data; 163 + 164 + /* (tmp << 8) * 3 / 1800 */ 165 + if (min <= 0) 166 + data = 0; 167 + else 168 + data = (min << 5) / 675; 169 + pm860x_reg_write(info->i2c, PM8607_VBAT_LOWTH, data); 170 + dev_dbg(info->dev, "VBAT Min:%dmv, LOWTH:0x%x\n", min, data); 171 + 172 + if (max <= 0) 173 + data = 0xff; 174 + else 175 + data = (max << 5) / 675; 176 + pm860x_reg_write(info->i2c, PM8607_VBAT_HIGHTH, data); 177 + dev_dbg(info->dev, "VBAT Max:%dmv, HIGHTH:0x%x\n", max, data); 178 + 179 + return; 180 + } 181 + 182 + static int start_precharge(struct pm860x_charger_info *info) 183 + { 184 + int ret; 185 + 186 + dev_dbg(info->dev, "Start Pre-charging!\n"); 187 + set_vbatt_threshold(info, 0, 0); 188 + 189 + ret = pm860x_reg_write(info->i2c_8606, PM8606_PREREGULATORA, 190 + PREREG1_1350MA | PREREG1_VSYS_4_5V); 191 + if (ret < 0) 192 + goto out; 193 + /* stop charging */ 194 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3, 195 + CC1_MODE_OFF); 196 + if (ret < 0) 197 + goto out; 198 + /* set 270 minutes timeout */ 199 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL3, (0xf << 4), 200 + CC3_270MIN_TIMEOUT); 201 + if (ret < 0) 202 + goto out; 203 + /* set precharge current, termination voltage, IBAT & TBAT monitor */ 204 + ret = pm860x_reg_write(info->i2c, PM8607_CHG_CTRL4, 205 + CC4_IPRE_40MA | CC4_VPCHG_3_2V | 206 + CC4_IFCHG_MON_EN | CC4_BTEMP_MON_EN); 207 + if (ret < 0) 208 + goto out; 209 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL7, 210 + CC7_BAT_REM_EN | CC7_IFSM_EN, 211 + CC7_BAT_REM_EN | CC7_IFSM_EN); 212 + if (ret < 0) 213 + goto out; 214 + /* trigger precharge */ 215 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3, 216 + CC1_MODE_PRECHARGE); 217 + out: 218 + return ret; 219 + } 220 + 221 + static int start_fastcharge(struct pm860x_charger_info *info) 222 + { 223 + int ret; 224 + 225 + dev_dbg(info->dev, "Start Fast-charging!\n"); 226 + 227 + /* set fastcharge termination current & voltage, disable charging */ 228 + ret = pm860x_reg_write(info->i2c, PM8607_CHG_CTRL1, 229 + CC1_MODE_OFF | CC1_ITERM_60MA | 230 + CC1_VFCHG_4_2V); 231 + if (ret < 0) 232 + goto out; 233 + ret = pm860x_reg_write(info->i2c_8606, PM8606_PREREGULATORA, 234 + PREREG1_540MA | PREREG1_VSYS_4_5V); 235 + if (ret < 0) 236 + goto out; 237 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL2, 0x1f, 238 + CC2_ICHG_500MA); 239 + if (ret < 0) 240 + goto out; 241 + /* set 270 minutes timeout */ 242 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL3, (0xf << 4), 243 + CC3_270MIN_TIMEOUT); 244 + if (ret < 0) 245 + goto out; 246 + /* set IBAT & TBAT monitor */ 247 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL4, 248 + CC4_IFCHG_MON_EN | CC4_BTEMP_MON_EN, 249 + CC4_IFCHG_MON_EN | CC4_BTEMP_MON_EN); 250 + if (ret < 0) 251 + goto out; 252 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL6, 253 + CC6_BAT_OV_EN | CC6_BAT_UV_EN | 254 + CC6_UV_VBAT_SET, 255 + CC6_BAT_OV_EN | CC6_BAT_UV_EN | 256 + CC6_UV_VBAT_SET); 257 + if (ret < 0) 258 + goto out; 259 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL7, 260 + CC7_BAT_REM_EN | CC7_IFSM_EN, 261 + CC7_BAT_REM_EN | CC7_IFSM_EN); 262 + if (ret < 0) 263 + goto out; 264 + /* launch fast-charge */ 265 + ret = pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3, 266 + CC1_MODE_FASTCHARGE); 267 + /* vchg threshold setting */ 268 + set_vchg_threshold(info, VCHG_NORMAL_LOW, VCHG_NORMAL_HIGH); 269 + out: 270 + return ret; 271 + } 272 + 273 + static void stop_charge(struct pm860x_charger_info *info, int vbatt) 274 + { 275 + dev_dbg(info->dev, "Stop charging!\n"); 276 + pm860x_set_bits(info->i2c, PM8607_CHG_CTRL1, 3, CC1_MODE_OFF); 277 + if (vbatt > CHARGE_THRESHOLD && info->online) 278 + set_vbatt_threshold(info, CHARGE_THRESHOLD, 0); 279 + } 280 + 281 + static void power_off_notification(struct pm860x_charger_info *info) 282 + { 283 + dev_dbg(info->dev, "Power-off notification!\n"); 284 + } 285 + 286 + static int set_charging_fsm(struct pm860x_charger_info *info) 287 + { 288 + struct power_supply *psy; 289 + union power_supply_propval data; 290 + unsigned char fsm_state[][16] = { "init", "discharge", "precharge", 291 + "fastcharge", 292 + }; 293 + int ret; 294 + int vbatt; 295 + 296 + psy = power_supply_get_by_name(pm860x_supplied_to[0]); 297 + if (!psy) 298 + return -EINVAL; 299 + ret = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &data); 300 + if (ret) 301 + return ret; 302 + vbatt = data.intval / 1000; 303 + 304 + ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT, &data); 305 + if (ret) 306 + return ret; 307 + 308 + mutex_lock(&info->lock); 309 + info->present = data.intval; 310 + 311 + dev_dbg(info->dev, "Entering FSM:%s, Charger:%s, Battery:%s, " 312 + "Allowed:%d\n", 313 + &fsm_state[info->state][0], 314 + (info->online) ? "online" : "N/A", 315 + (info->present) ? "present" : "N/A", info->allowed); 316 + dev_dbg(info->dev, "set_charging_fsm:vbatt:%d(mV)\n", vbatt); 317 + 318 + switch (info->state) { 319 + case FSM_INIT: 320 + if (info->online && info->present && info->allowed) { 321 + if (vbatt < PRECHARGE_THRESHOLD) { 322 + info->state = FSM_PRECHARGE; 323 + start_precharge(info); 324 + } else if (vbatt > DISCHARGE_THRESHOLD) { 325 + info->state = FSM_DISCHARGE; 326 + stop_charge(info, vbatt); 327 + } else if (vbatt < DISCHARGE_THRESHOLD) { 328 + info->state = FSM_FASTCHARGE; 329 + start_fastcharge(info); 330 + } 331 + } else { 332 + if (vbatt < POWEROFF_THRESHOLD) { 333 + power_off_notification(info); 334 + } else { 335 + info->state = FSM_DISCHARGE; 336 + stop_charge(info, vbatt); 337 + } 338 + } 339 + break; 340 + case FSM_PRECHARGE: 341 + if (info->online && info->present && info->allowed) { 342 + if (vbatt > PRECHARGE_THRESHOLD) { 343 + info->state = FSM_FASTCHARGE; 344 + start_fastcharge(info); 345 + } 346 + } else { 347 + info->state = FSM_DISCHARGE; 348 + stop_charge(info, vbatt); 349 + } 350 + break; 351 + case FSM_FASTCHARGE: 352 + if (info->online && info->present && info->allowed) { 353 + if (vbatt < PRECHARGE_THRESHOLD) { 354 + info->state = FSM_PRECHARGE; 355 + start_precharge(info); 356 + } 357 + } else { 358 + info->state = FSM_DISCHARGE; 359 + stop_charge(info, vbatt); 360 + } 361 + break; 362 + case FSM_DISCHARGE: 363 + if (info->online && info->present && info->allowed) { 364 + if (vbatt < PRECHARGE_THRESHOLD) { 365 + info->state = FSM_PRECHARGE; 366 + start_precharge(info); 367 + } else if (vbatt < DISCHARGE_THRESHOLD) { 368 + info->state = FSM_FASTCHARGE; 369 + start_fastcharge(info); 370 + } 371 + } else { 372 + if (vbatt < POWEROFF_THRESHOLD) 373 + power_off_notification(info); 374 + else if (vbatt > CHARGE_THRESHOLD && info->online) 375 + set_vbatt_threshold(info, CHARGE_THRESHOLD, 0); 376 + } 377 + break; 378 + default: 379 + dev_warn(info->dev, "FSM meets wrong state:%d\n", 380 + info->state); 381 + break; 382 + } 383 + dev_dbg(info->dev, 384 + "Out FSM:%s, Charger:%s, Battery:%s, Allowed:%d\n", 385 + &fsm_state[info->state][0], 386 + (info->online) ? "online" : "N/A", 387 + (info->present) ? "present" : "N/A", info->allowed); 388 + mutex_unlock(&info->lock); 389 + 390 + return 0; 391 + } 392 + 393 + static irqreturn_t pm860x_charger_handler(int irq, void *data) 394 + { 395 + struct pm860x_charger_info *info = data; 396 + int ret; 397 + 398 + mutex_lock(&info->lock); 399 + ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); 400 + if (ret < 0) { 401 + mutex_unlock(&info->lock); 402 + goto out; 403 + } 404 + if (ret & STATUS2_CHG) { 405 + info->online = 1; 406 + info->allowed = 1; 407 + } else { 408 + info->online = 0; 409 + info->allowed = 0; 410 + } 411 + mutex_unlock(&info->lock); 412 + dev_dbg(info->dev, "%s, Charger:%s, Allowed:%d\n", __func__, 413 + (info->online) ? "online" : "N/A", info->allowed); 414 + 415 + set_charging_fsm(info); 416 + 417 + power_supply_changed(&info->usb); 418 + out: 419 + return IRQ_HANDLED; 420 + } 421 + 422 + static irqreturn_t pm860x_temp_handler(int irq, void *data) 423 + { 424 + struct power_supply *psy; 425 + struct pm860x_charger_info *info = data; 426 + union power_supply_propval temp; 427 + int value; 428 + int ret; 429 + 430 + psy = power_supply_get_by_name(pm860x_supplied_to[0]); 431 + if (!psy) 432 + goto out; 433 + ret = psy->get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp); 434 + if (ret) 435 + goto out; 436 + value = temp.intval / 10; 437 + 438 + mutex_lock(&info->lock); 439 + /* Temperature < -10 C or >40 C, Will not allow charge */ 440 + if (value < -10 || value > 40) 441 + info->allowed = 0; 442 + else 443 + info->allowed = 1; 444 + dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed); 445 + mutex_unlock(&info->lock); 446 + 447 + set_charging_fsm(info); 448 + out: 449 + return IRQ_HANDLED; 450 + } 451 + 452 + static irqreturn_t pm860x_exception_handler(int irq, void *data) 453 + { 454 + struct pm860x_charger_info *info = data; 455 + 456 + mutex_lock(&info->lock); 457 + info->allowed = 0; 458 + mutex_unlock(&info->lock); 459 + dev_dbg(info->dev, "%s, irq: %d\n", __func__, irq); 460 + 461 + set_charging_fsm(info); 462 + return IRQ_HANDLED; 463 + } 464 + 465 + static irqreturn_t pm860x_done_handler(int irq, void *data) 466 + { 467 + struct pm860x_charger_info *info = data; 468 + struct power_supply *psy; 469 + union power_supply_propval val; 470 + int ret; 471 + int vbatt; 472 + 473 + mutex_lock(&info->lock); 474 + /* pre-charge done, will transimit to fast-charge stage */ 475 + if (info->state == FSM_PRECHARGE) { 476 + info->allowed = 1; 477 + goto out; 478 + } 479 + /* 480 + * Fast charge done, delay to read 481 + * the correct status of CHG_DET. 482 + */ 483 + mdelay(5); 484 + info->allowed = 0; 485 + psy = power_supply_get_by_name(pm860x_supplied_to[0]); 486 + if (!psy) 487 + goto out; 488 + ret = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); 489 + if (ret) 490 + goto out; 491 + vbatt = val.intval / 1000; 492 + /* 493 + * CHG_DONE interrupt is faster than CHG_DET interrupt when 494 + * plug in/out usb, So we can not rely on info->online, we 495 + * need check pm8607 status register to check usb is online 496 + * or not, then we can decide it is real charge done 497 + * automatically or it is triggered by usb plug out; 498 + */ 499 + ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); 500 + if (ret < 0) 501 + goto out; 502 + if (vbatt > CHARGE_THRESHOLD && ret & STATUS2_CHG) 503 + psy->set_property(psy, POWER_SUPPLY_PROP_CHARGE_FULL, &val); 504 + 505 + out: 506 + mutex_unlock(&info->lock); 507 + dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed); 508 + set_charging_fsm(info); 509 + 510 + return IRQ_HANDLED; 511 + } 512 + 513 + static irqreturn_t pm860x_vbattery_handler(int irq, void *data) 514 + { 515 + struct pm860x_charger_info *info = data; 516 + 517 + mutex_lock(&info->lock); 518 + 519 + set_vbatt_threshold(info, 0, 0); 520 + 521 + if (info->present && info->online) 522 + info->allowed = 1; 523 + else 524 + info->allowed = 0; 525 + mutex_unlock(&info->lock); 526 + dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed); 527 + 528 + set_charging_fsm(info); 529 + 530 + return IRQ_HANDLED; 531 + } 532 + 533 + static irqreturn_t pm860x_vchg_handler(int irq, void *data) 534 + { 535 + struct pm860x_charger_info *info = data; 536 + int vchg = 0; 537 + 538 + if (info->present) 539 + goto out; 540 + 541 + measure_vchg(info, &vchg); 542 + 543 + mutex_lock(&info->lock); 544 + if (!info->online) { 545 + int status; 546 + /* check if over-temp on pm8606 or not */ 547 + status = pm860x_reg_read(info->i2c_8606, PM8606_FLAGS); 548 + if (status & OVER_TEMP_FLAG) { 549 + /* clear over temp flag and set auto recover */ 550 + pm860x_set_bits(info->i2c_8606, PM8606_FLAGS, 551 + OVER_TEMP_FLAG, OVER_TEMP_FLAG); 552 + pm860x_set_bits(info->i2c_8606, 553 + PM8606_VSYS, 554 + OVTEMP_AUTORECOVER, 555 + OVTEMP_AUTORECOVER); 556 + dev_dbg(info->dev, 557 + "%s, pm8606 over-temp occure\n", __func__); 558 + } 559 + } 560 + 561 + if (vchg > VCHG_NORMAL_CHECK) { 562 + set_vchg_threshold(info, VCHG_OVP_LOW, 0); 563 + info->allowed = 0; 564 + dev_dbg(info->dev, 565 + "%s,pm8607 over-vchg occure,vchg = %dmv\n", 566 + __func__, vchg); 567 + } else if (vchg < VCHG_OVP_LOW) { 568 + set_vchg_threshold(info, VCHG_NORMAL_LOW, 569 + VCHG_NORMAL_HIGH); 570 + info->allowed = 1; 571 + dev_dbg(info->dev, 572 + "%s,pm8607 over-vchg recover,vchg = %dmv\n", 573 + __func__, vchg); 574 + } 575 + mutex_unlock(&info->lock); 576 + 577 + dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed); 578 + set_charging_fsm(info); 579 + out: 580 + return IRQ_HANDLED; 581 + } 582 + 583 + static int pm860x_usb_get_prop(struct power_supply *psy, 584 + enum power_supply_property psp, 585 + union power_supply_propval *val) 586 + { 587 + struct pm860x_charger_info *info = 588 + dev_get_drvdata(psy->dev->parent); 589 + 590 + switch (psp) { 591 + case POWER_SUPPLY_PROP_STATUS: 592 + if (info->state == FSM_FASTCHARGE || 593 + info->state == FSM_PRECHARGE) 594 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 595 + else 596 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 597 + break; 598 + case POWER_SUPPLY_PROP_ONLINE: 599 + val->intval = info->online; 600 + break; 601 + default: 602 + return -ENODEV; 603 + } 604 + return 0; 605 + } 606 + 607 + static enum power_supply_property pm860x_usb_props[] = { 608 + POWER_SUPPLY_PROP_STATUS, 609 + POWER_SUPPLY_PROP_ONLINE, 610 + }; 611 + 612 + static int pm860x_init_charger(struct pm860x_charger_info *info) 613 + { 614 + int ret; 615 + 616 + ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2); 617 + if (ret < 0) 618 + return ret; 619 + 620 + mutex_lock(&info->lock); 621 + info->state = FSM_INIT; 622 + if (ret & STATUS2_CHG) { 623 + info->online = 1; 624 + info->allowed = 1; 625 + } else { 626 + info->online = 0; 627 + info->allowed = 0; 628 + } 629 + mutex_unlock(&info->lock); 630 + 631 + set_charging_fsm(info); 632 + return 0; 633 + } 634 + 635 + static struct pm860x_irq_desc { 636 + const char *name; 637 + irqreturn_t (*handler)(int irq, void *data); 638 + } pm860x_irq_descs[] = { 639 + { "usb supply detect", pm860x_charger_handler }, 640 + { "charge done", pm860x_done_handler }, 641 + { "charge timeout", pm860x_exception_handler }, 642 + { "charge fault", pm860x_exception_handler }, 643 + { "temperature", pm860x_temp_handler }, 644 + { "vbatt", pm860x_vbattery_handler }, 645 + { "vchg", pm860x_vchg_handler }, 646 + }; 647 + 648 + static __devinit int pm860x_charger_probe(struct platform_device *pdev) 649 + { 650 + struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 651 + struct pm860x_charger_info *info; 652 + int ret; 653 + int count; 654 + int i; 655 + int j; 656 + 657 + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 658 + if (!info) 659 + return -ENOMEM; 660 + 661 + count = pdev->num_resources; 662 + for (i = 0, j = 0; i < count; i++) { 663 + info->irq[j] = platform_get_irq(pdev, i); 664 + if (info->irq[j] < 0) 665 + continue; 666 + j++; 667 + } 668 + info->irq_nums = j; 669 + 670 + info->chip = chip; 671 + info->i2c = 672 + (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 673 + info->i2c_8606 = 674 + (chip->id == CHIP_PM8607) ? chip->companion : chip->client; 675 + if (!info->i2c_8606) { 676 + dev_err(&pdev->dev, "Missed I2C address of 88PM8606!\n"); 677 + ret = -EINVAL; 678 + goto out; 679 + } 680 + info->dev = &pdev->dev; 681 + 682 + /* set init value for the case we are not using battery */ 683 + set_vchg_threshold(info, VCHG_NORMAL_LOW, VCHG_OVP_LOW); 684 + 685 + mutex_init(&info->lock); 686 + platform_set_drvdata(pdev, info); 687 + 688 + info->usb.name = "usb"; 689 + info->usb.type = POWER_SUPPLY_TYPE_USB; 690 + info->usb.supplied_to = pm860x_supplied_to; 691 + info->usb.num_supplicants = ARRAY_SIZE(pm860x_supplied_to); 692 + info->usb.properties = pm860x_usb_props; 693 + info->usb.num_properties = ARRAY_SIZE(pm860x_usb_props); 694 + info->usb.get_property = pm860x_usb_get_prop; 695 + ret = power_supply_register(&pdev->dev, &info->usb); 696 + if (ret) 697 + goto out; 698 + 699 + pm860x_init_charger(info); 700 + 701 + for (i = 0; i < ARRAY_SIZE(info->irq); i++) { 702 + ret = request_threaded_irq(info->irq[i], NULL, 703 + pm860x_irq_descs[i].handler, 704 + IRQF_ONESHOT, pm860x_irq_descs[i].name, info); 705 + if (ret < 0) { 706 + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", 707 + info->irq[i], ret); 708 + goto out_irq; 709 + } 710 + } 711 + return 0; 712 + 713 + out_irq: 714 + while (--i >= 0) 715 + free_irq(info->irq[i], info); 716 + out: 717 + kfree(info); 718 + return ret; 719 + } 720 + 721 + static int __devexit pm860x_charger_remove(struct platform_device *pdev) 722 + { 723 + struct pm860x_charger_info *info = platform_get_drvdata(pdev); 724 + int i; 725 + 726 + platform_set_drvdata(pdev, NULL); 727 + power_supply_unregister(&info->usb); 728 + free_irq(info->irq[0], info); 729 + for (i = 0; i < info->irq_nums; i++) 730 + free_irq(info->irq[i], info); 731 + kfree(info); 732 + return 0; 733 + } 734 + 735 + static struct platform_driver pm860x_charger_driver = { 736 + .driver = { 737 + .name = "88pm860x-charger", 738 + .owner = THIS_MODULE, 739 + }, 740 + .probe = pm860x_charger_probe, 741 + .remove = __devexit_p(pm860x_charger_remove), 742 + }; 743 + module_platform_driver(pm860x_charger_driver); 744 + 745 + MODULE_DESCRIPTION("Marvell 88PM860x Charger driver"); 746 + MODULE_LICENSE("GPL");
+19 -1
drivers/power/Kconfig
··· 69 69 help 70 70 This driver is used for testing. It's safe to say M here. 71 71 72 + config BATTERY_88PM860X 73 + tristate "Marvell 88PM860x battery driver" 74 + depends on MFD_88PM860X 75 + help 76 + Say Y here to enable battery monitor for Marvell 88PM860x chip. 77 + 72 78 config BATTERY_DS2760 73 79 tristate "DS2760 battery driver (HP iPAQ & others)" 74 80 depends on W1 && W1_SLAVE_DS2760 ··· 180 174 config BATTERY_DA9052 181 175 tristate "Dialog DA9052 Battery" 182 176 depends on PMIC_DA9052 183 - depends on BROKEN 184 177 help 185 178 Say Y here to enable support for batteries charger integrated into 186 179 DA9052 PMIC. ··· 214 209 depends on S3C_ADC 215 210 help 216 211 Say Y here to enable support for iPAQ h1930/h1940/rx1950 battery 212 + 213 + config CHARGER_88PM860X 214 + tristate "Marvell 88PM860x Charger driver" 215 + depends on MFD_88PM860X && BATTERY_88PM860X 216 + help 217 + Say Y here to enable charger for Marvell 88PM860x chip. 217 218 218 219 config CHARGER_PCF50633 219 220 tristate "NXP PCF50633 MBC" ··· 272 261 depends on I2C 273 262 help 274 263 Say Y here to enable support for LP8727 Charger Driver. 264 + 265 + config CHARGER_LP8788 266 + tristate "TI LP8788 charger driver" 267 + depends on MFD_LP8788 268 + depends on LP8788_ADC 269 + help 270 + Say Y to enable support for the LP8788 linear charger. 275 271 276 272 config CHARGER_GPIO 277 273 tristate "GPIO charger"
+3
drivers/power/Makefile
··· 15 15 obj-$(CONFIG_WM8350_POWER) += wm8350_power.o 16 16 obj-$(CONFIG_TEST_POWER) += test_power.o 17 17 18 + obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o 18 19 obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o 19 20 obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o 20 21 obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o ··· 33 32 obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o 34 33 obj-$(CONFIG_BATTERY_Z2) += z2_battery.o 35 34 obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o 35 + obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o 36 36 obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o 37 37 obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o 38 38 obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o ··· 42 40 obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o 43 41 obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o 44 42 obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o 43 + obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o 45 44 obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o 46 45 obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o 47 46 obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
+1
drivers/power/ab8500_btemp.c
··· 1014 1014 create_singlethread_workqueue("ab8500_btemp_wq"); 1015 1015 if (di->btemp_wq == NULL) { 1016 1016 dev_err(di->dev, "failed to create work queue\n"); 1017 + ret = -ENOMEM; 1017 1018 goto free_device_info; 1018 1019 } 1019 1020
+1
drivers/power/ab8500_charger.c
··· 2614 2614 create_singlethread_workqueue("ab8500_charger_wq"); 2615 2615 if (di->charger_wq == NULL) { 2616 2616 dev_err(di->dev, "failed to create work queue\n"); 2617 + ret = -ENOMEM; 2617 2618 goto free_device_info; 2618 2619 } 2619 2620
+1
drivers/power/ab8500_fg.c
··· 2506 2506 di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq"); 2507 2507 if (di->fg_wq == NULL) { 2508 2508 dev_err(di->dev, "failed to create work queue\n"); 2509 + ret = -ENOMEM; 2509 2510 goto free_device_info; 2510 2511 } 2511 2512
+2 -1
drivers/power/bq27x00_battery.c
··· 814 814 di->bat.name = name; 815 815 di->bus.read = &bq27x00_read_i2c; 816 816 817 - if (bq27x00_powersupply_init(di)) 817 + retval = bq27x00_powersupply_init(di); 818 + if (retval) 818 819 goto batt_failed_3; 819 820 820 821 i2c_set_clientdata(client, di);
+385 -49
drivers/power/charger-manager.c
··· 22 22 #include <linux/platform_device.h> 23 23 #include <linux/power/charger-manager.h> 24 24 #include <linux/regulator/consumer.h> 25 + #include <linux/sysfs.h> 25 26 26 27 static const char * const default_event_names[] = { 27 28 [CM_EVENT_UNKNOWN] = "Unknown", ··· 228 227 } 229 228 230 229 /** 230 + * is_full_charged - Returns true if the battery is fully charged. 231 + * @cm: the Charger Manager representing the battery. 232 + */ 233 + static bool is_full_charged(struct charger_manager *cm) 234 + { 235 + struct charger_desc *desc = cm->desc; 236 + union power_supply_propval val; 237 + int ret = 0; 238 + int uV; 239 + 240 + /* If there is no battery, it cannot be charged */ 241 + if (!is_batt_present(cm)) { 242 + val.intval = 0; 243 + goto out; 244 + } 245 + 246 + if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) { 247 + /* Not full if capacity of fuel gauge isn't full */ 248 + ret = cm->fuel_gauge->get_property(cm->fuel_gauge, 249 + POWER_SUPPLY_PROP_CHARGE_FULL, &val); 250 + if (!ret && val.intval > desc->fullbatt_full_capacity) { 251 + val.intval = 1; 252 + goto out; 253 + } 254 + } 255 + 256 + /* Full, if it's over the fullbatt voltage */ 257 + if (desc->fullbatt_uV > 0) { 258 + ret = get_batt_uV(cm, &uV); 259 + if (!ret && uV >= desc->fullbatt_uV) { 260 + val.intval = 1; 261 + goto out; 262 + } 263 + } 264 + 265 + /* Full, if the capacity is more than fullbatt_soc */ 266 + if (cm->fuel_gauge && desc->fullbatt_soc > 0) { 267 + ret = cm->fuel_gauge->get_property(cm->fuel_gauge, 268 + POWER_SUPPLY_PROP_CAPACITY, &val); 269 + if (!ret && val.intval >= desc->fullbatt_soc) { 270 + val.intval = 1; 271 + goto out; 272 + } 273 + } 274 + 275 + val.intval = 0; 276 + 277 + out: 278 + return val.intval ? true : false; 279 + } 280 + 281 + /** 231 282 * is_polling_required - Return true if need to continue polling for this CM. 232 283 * @cm: the Charger Manager representing the battery. 233 284 */ ··· 324 271 if (enable) { 325 272 if (cm->emergency_stop) 326 273 return -EAGAIN; 327 - for (i = 0 ; i < desc->num_charger_regulators ; i++) 328 - regulator_enable(desc->charger_regulators[i].consumer); 274 + 275 + /* 276 + * Save start time of charging to limit 277 + * maximum possible charging time. 278 + */ 279 + cm->charging_start_time = ktime_to_ms(ktime_get()); 280 + cm->charging_end_time = 0; 281 + 282 + for (i = 0 ; i < desc->num_charger_regulators ; i++) { 283 + if (desc->charger_regulators[i].externally_control) 284 + continue; 285 + 286 + err = regulator_enable(desc->charger_regulators[i].consumer); 287 + if (err < 0) { 288 + dev_warn(cm->dev, 289 + "Cannot enable %s regulator\n", 290 + desc->charger_regulators[i].regulator_name); 291 + } 292 + } 329 293 } else { 294 + /* 295 + * Save end time of charging to maintain fully charged state 296 + * of battery after full-batt. 297 + */ 298 + cm->charging_start_time = 0; 299 + cm->charging_end_time = ktime_to_ms(ktime_get()); 300 + 301 + for (i = 0 ; i < desc->num_charger_regulators ; i++) { 302 + if (desc->charger_regulators[i].externally_control) 303 + continue; 304 + 305 + err = regulator_disable(desc->charger_regulators[i].consumer); 306 + if (err < 0) { 307 + dev_warn(cm->dev, 308 + "Cannot disable %s regulator\n", 309 + desc->charger_regulators[i].regulator_name); 310 + } 311 + } 312 + 330 313 /* 331 314 * Abnormal battery state - Stop charging forcibly, 332 315 * even if charger was enabled at the other places ··· 489 400 return; 490 401 } 491 402 492 - diff = cm->fullbatt_vchk_uV; 403 + diff = desc->fullbatt_uV; 493 404 diff -= batt_uV; 494 405 495 - dev_dbg(cm->dev, "VBATT dropped %duV after full-batt.\n", diff); 406 + dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff); 496 407 497 408 if (diff > desc->fullbatt_vchkdrop_uV) { 498 409 try_charger_restart(cm); 499 - uevent_notify(cm, "Recharge"); 410 + uevent_notify(cm, "Recharging"); 500 411 } 412 + } 413 + 414 + /** 415 + * check_charging_duration - Monitor charging/discharging duration 416 + * @cm: the Charger Manager representing the battery. 417 + * 418 + * If whole charging duration exceed 'charging_max_duration_ms', 419 + * cm stop charging to prevent overcharge/overheat. If discharging 420 + * duration exceed 'discharging _max_duration_ms', charger cable is 421 + * attached, after full-batt, cm start charging to maintain fully 422 + * charged state for battery. 423 + */ 424 + static int check_charging_duration(struct charger_manager *cm) 425 + { 426 + struct charger_desc *desc = cm->desc; 427 + u64 curr = ktime_to_ms(ktime_get()); 428 + u64 duration; 429 + int ret = false; 430 + 431 + if (!desc->charging_max_duration_ms && 432 + !desc->discharging_max_duration_ms) 433 + return ret; 434 + 435 + if (cm->charger_enabled) { 436 + duration = curr - cm->charging_start_time; 437 + 438 + if (duration > desc->charging_max_duration_ms) { 439 + dev_info(cm->dev, "Charging duration exceed %lldms", 440 + desc->charging_max_duration_ms); 441 + uevent_notify(cm, "Discharging"); 442 + try_charger_enable(cm, false); 443 + ret = true; 444 + } 445 + } else if (is_ext_pwr_online(cm) && !cm->charger_enabled) { 446 + duration = curr - cm->charging_end_time; 447 + 448 + if (duration > desc->charging_max_duration_ms && 449 + is_ext_pwr_online(cm)) { 450 + dev_info(cm->dev, "DisCharging duration exceed %lldms", 451 + desc->discharging_max_duration_ms); 452 + uevent_notify(cm, "Recharing"); 453 + try_charger_enable(cm, true); 454 + ret = true; 455 + } 456 + } 457 + 458 + return ret; 501 459 } 502 460 503 461 /** ··· 562 426 dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n", 563 427 cm->last_temp_mC / 1000, cm->last_temp_mC % 1000); 564 428 565 - /* It has been stopped or charging already */ 566 - if (!!temp == !!cm->emergency_stop) 429 + /* It has been stopped already */ 430 + if (temp && cm->emergency_stop) 567 431 return false; 568 432 433 + /* 434 + * Check temperature whether overheat or cold. 435 + * If temperature is out of range normal state, stop charging. 436 + */ 569 437 if (temp) { 570 438 cm->emergency_stop = temp; 571 439 if (!try_charger_enable(cm, false)) { ··· 578 438 else 579 439 uevent_notify(cm, "COLD"); 580 440 } 441 + 442 + /* 443 + * Check whole charging duration and discharing duration 444 + * after full-batt. 445 + */ 446 + } else if (!cm->emergency_stop && check_charging_duration(cm)) { 447 + dev_dbg(cm->dev, 448 + "Charging/Discharging duration is out of range"); 449 + /* 450 + * Check dropped voltage of battery. If battery voltage is more 451 + * dropped than fullbatt_vchkdrop_uV after fully charged state, 452 + * charger-manager have to recharge battery. 453 + */ 454 + } else if (!cm->emergency_stop && is_ext_pwr_online(cm) && 455 + !cm->charger_enabled) { 456 + fullbatt_vchk(&cm->fullbatt_vchk_work.work); 457 + 458 + /* 459 + * Check whether fully charged state to protect overcharge 460 + * if charger-manager is charging for battery. 461 + */ 462 + } else if (!cm->emergency_stop && is_full_charged(cm) && 463 + cm->charger_enabled) { 464 + dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n"); 465 + uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]); 466 + 467 + try_charger_enable(cm, false); 468 + 469 + fullbatt_vchk(&cm->fullbatt_vchk_work.work); 581 470 } else { 582 471 cm->emergency_stop = 0; 583 - if (!try_charger_enable(cm, true)) 584 - uevent_notify(cm, "CHARGING"); 472 + if (is_ext_pwr_online(cm)) { 473 + if (!try_charger_enable(cm, true)) 474 + uevent_notify(cm, "CHARGING"); 475 + } 585 476 } 586 477 587 478 return true; ··· 872 701 val->intval = 0; 873 702 break; 874 703 case POWER_SUPPLY_PROP_CHARGE_FULL: 875 - if (cm->fuel_gauge) { 876 - if (cm->fuel_gauge->get_property(cm->fuel_gauge, 877 - POWER_SUPPLY_PROP_CHARGE_FULL, val) == 0) 878 - break; 879 - } 880 - 881 - if (is_ext_pwr_online(cm)) { 882 - /* Not full if it's charging. */ 883 - if (is_charging(cm)) { 884 - val->intval = 0; 885 - break; 886 - } 887 - /* 888 - * Full if it's powered but not charging andi 889 - * not forced stop by emergency 890 - */ 891 - if (!cm->emergency_stop) { 892 - val->intval = 1; 893 - break; 894 - } 895 - } 896 - 897 - /* Full if it's over the fullbatt voltage */ 898 - ret = get_batt_uV(cm, &uV); 899 - if (!ret && desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV && 900 - !is_charging(cm)) { 704 + if (is_full_charged(cm)) 901 705 val->intval = 1; 902 - break; 903 - } 904 - 905 - /* Full if the cap is 100 */ 906 - if (cm->fuel_gauge) { 907 - ret = cm->fuel_gauge->get_property(cm->fuel_gauge, 908 - POWER_SUPPLY_PROP_CAPACITY, val); 909 - if (!ret && val->intval >= 100 && !is_charging(cm)) { 910 - val->intval = 1; 911 - break; 912 - } 913 - } 914 - 915 - val->intval = 0; 706 + else 707 + val->intval = 0; 916 708 ret = 0; 917 709 break; 918 710 case POWER_SUPPLY_PROP_CHARGE_NOW: ··· 1165 1031 struct charger_cable *cable = 1166 1032 container_of(self, struct charger_cable, nb); 1167 1033 1034 + /* 1035 + * The newly state of charger cable. 1036 + * If cable is attached, cable->attached is true. 1037 + */ 1168 1038 cable->attached = event; 1039 + 1040 + /* 1041 + * Setup monitoring to check battery state 1042 + * when charger cable is attached. 1043 + */ 1044 + if (cable->attached && is_polling_required(cable->cm)) { 1045 + if (work_pending(&setup_polling)) 1046 + cancel_work_sync(&setup_polling); 1047 + schedule_work(&setup_polling); 1048 + } 1049 + 1050 + /* 1051 + * Setup work for controlling charger(regulator) 1052 + * according to charger cable. 1053 + */ 1169 1054 schedule_work(&cable->wq); 1170 1055 1171 1056 return NOTIFY_DONE; ··· 1221 1068 return ret; 1222 1069 } 1223 1070 1071 + /* help function of sysfs node to control charger(regulator) */ 1072 + static ssize_t charger_name_show(struct device *dev, 1073 + struct device_attribute *attr, char *buf) 1074 + { 1075 + struct charger_regulator *charger 1076 + = container_of(attr, struct charger_regulator, attr_name); 1077 + 1078 + return sprintf(buf, "%s\n", charger->regulator_name); 1079 + } 1080 + 1081 + static ssize_t charger_state_show(struct device *dev, 1082 + struct device_attribute *attr, char *buf) 1083 + { 1084 + struct charger_regulator *charger 1085 + = container_of(attr, struct charger_regulator, attr_state); 1086 + int state = 0; 1087 + 1088 + if (!charger->externally_control) 1089 + state = regulator_is_enabled(charger->consumer); 1090 + 1091 + return sprintf(buf, "%s\n", state ? "enabled" : "disabled"); 1092 + } 1093 + 1094 + static ssize_t charger_externally_control_show(struct device *dev, 1095 + struct device_attribute *attr, char *buf) 1096 + { 1097 + struct charger_regulator *charger = container_of(attr, 1098 + struct charger_regulator, attr_externally_control); 1099 + 1100 + return sprintf(buf, "%d\n", charger->externally_control); 1101 + } 1102 + 1103 + static ssize_t charger_externally_control_store(struct device *dev, 1104 + struct device_attribute *attr, const char *buf, 1105 + size_t count) 1106 + { 1107 + struct charger_regulator *charger 1108 + = container_of(attr, struct charger_regulator, 1109 + attr_externally_control); 1110 + struct charger_manager *cm = charger->cm; 1111 + struct charger_desc *desc = cm->desc; 1112 + int i; 1113 + int ret; 1114 + int externally_control; 1115 + int chargers_externally_control = 1; 1116 + 1117 + ret = sscanf(buf, "%d", &externally_control); 1118 + if (ret == 0) { 1119 + ret = -EINVAL; 1120 + return ret; 1121 + } 1122 + 1123 + if (!externally_control) { 1124 + charger->externally_control = 0; 1125 + return count; 1126 + } 1127 + 1128 + for (i = 0; i < desc->num_charger_regulators; i++) { 1129 + if (&desc->charger_regulators[i] != charger && 1130 + !desc->charger_regulators[i].externally_control) { 1131 + /* 1132 + * At least, one charger is controlled by 1133 + * charger-manager 1134 + */ 1135 + chargers_externally_control = 0; 1136 + break; 1137 + } 1138 + } 1139 + 1140 + if (!chargers_externally_control) { 1141 + if (cm->charger_enabled) { 1142 + try_charger_enable(charger->cm, false); 1143 + charger->externally_control = externally_control; 1144 + try_charger_enable(charger->cm, true); 1145 + } else { 1146 + charger->externally_control = externally_control; 1147 + } 1148 + } else { 1149 + dev_warn(cm->dev, 1150 + "'%s' regulator should be controlled " 1151 + "in charger-manager because charger-manager " 1152 + "must need at least one charger for charging\n", 1153 + charger->regulator_name); 1154 + } 1155 + 1156 + return count; 1157 + } 1158 + 1224 1159 static int charger_manager_probe(struct platform_device *pdev) 1225 1160 { 1226 1161 struct charger_desc *desc = dev_get_platdata(&pdev->dev); 1227 1162 struct charger_manager *cm; 1228 1163 int ret = 0, i = 0; 1229 1164 int j = 0; 1165 + int chargers_externally_control = 1; 1230 1166 union power_supply_propval val; 1231 1167 1232 1168 if (g_desc && !rtc_dev && g_desc->rtc_name) { ··· 1366 1124 "checking mechanism as it is not supplied."); 1367 1125 desc->fullbatt_vchkdrop_ms = 0; 1368 1126 desc->fullbatt_vchkdrop_uV = 0; 1127 + } 1128 + if (desc->fullbatt_soc == 0) { 1129 + dev_info(&pdev->dev, "Ignoring full-battery soc(state of" 1130 + " charge) threshold as it is not" 1131 + " supplied."); 1132 + } 1133 + if (desc->fullbatt_full_capacity == 0) { 1134 + dev_info(&pdev->dev, "Ignoring full-battery full capacity" 1135 + " threshold as it is not supplied."); 1369 1136 } 1370 1137 1371 1138 if (!desc->charger_regulators || desc->num_charger_regulators < 1) { ··· 1431 1180 dev_err(&pdev->dev, "there is no temperature_out_of_range\n"); 1432 1181 ret = -EINVAL; 1433 1182 goto err_chg_stat; 1183 + } 1184 + 1185 + if (!desc->charging_max_duration_ms || 1186 + !desc->discharging_max_duration_ms) { 1187 + dev_info(&pdev->dev, "Cannot limit charging duration " 1188 + "checking mechanism to prevent overcharge/overheat " 1189 + "and control discharging duration"); 1190 + desc->charging_max_duration_ms = 0; 1191 + desc->discharging_max_duration_ms = 0; 1434 1192 } 1435 1193 1436 1194 platform_set_drvdata(pdev, cm); ··· 1505 1245 for (i = 0 ; i < desc->num_charger_regulators ; i++) { 1506 1246 struct charger_regulator *charger 1507 1247 = &desc->charger_regulators[i]; 1248 + char buf[11]; 1249 + char *str; 1508 1250 1509 1251 charger->consumer = regulator_get(&pdev->dev, 1510 1252 charger->regulator_name); ··· 1516 1254 ret = -EINVAL; 1517 1255 goto err_chg_get; 1518 1256 } 1257 + charger->cm = cm; 1519 1258 1520 1259 for (j = 0 ; j < charger->num_cables ; j++) { 1521 1260 struct charger_cable *cable = &charger->cables[j]; ··· 1530 1267 cable->charger = charger; 1531 1268 cable->cm = cm; 1532 1269 } 1270 + 1271 + /* Create sysfs entry to control charger(regulator) */ 1272 + snprintf(buf, 10, "charger.%d", i); 1273 + str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); 1274 + if (!str) { 1275 + for (i--; i >= 0; i--) { 1276 + charger = &desc->charger_regulators[i]; 1277 + kfree(charger->attr_g.name); 1278 + } 1279 + ret = -ENOMEM; 1280 + 1281 + goto err_extcon; 1282 + } 1283 + strcpy(str, buf); 1284 + 1285 + charger->attrs[0] = &charger->attr_name.attr; 1286 + charger->attrs[1] = &charger->attr_state.attr; 1287 + charger->attrs[2] = &charger->attr_externally_control.attr; 1288 + charger->attrs[3] = NULL; 1289 + charger->attr_g.name = str; 1290 + charger->attr_g.attrs = charger->attrs; 1291 + 1292 + sysfs_attr_init(&charger->attr_name.attr); 1293 + charger->attr_name.attr.name = "name"; 1294 + charger->attr_name.attr.mode = 0444; 1295 + charger->attr_name.show = charger_name_show; 1296 + 1297 + sysfs_attr_init(&charger->attr_state.attr); 1298 + charger->attr_state.attr.name = "state"; 1299 + charger->attr_state.attr.mode = 0444; 1300 + charger->attr_state.show = charger_state_show; 1301 + 1302 + sysfs_attr_init(&charger->attr_externally_control.attr); 1303 + charger->attr_externally_control.attr.name 1304 + = "externally_control"; 1305 + charger->attr_externally_control.attr.mode = 0644; 1306 + charger->attr_externally_control.show 1307 + = charger_externally_control_show; 1308 + charger->attr_externally_control.store 1309 + = charger_externally_control_store; 1310 + 1311 + if (!desc->charger_regulators[i].externally_control || 1312 + !chargers_externally_control) { 1313 + chargers_externally_control = 0; 1314 + } 1315 + dev_info(&pdev->dev, "'%s' regulator's externally_control" 1316 + "is %d\n", charger->regulator_name, 1317 + charger->externally_control); 1318 + 1319 + ret = sysfs_create_group(&cm->charger_psy.dev->kobj, 1320 + &charger->attr_g); 1321 + if (ret < 0) { 1322 + dev_info(&pdev->dev, "Cannot create sysfs entry" 1323 + "of %s regulator\n", 1324 + charger->regulator_name); 1325 + } 1326 + } 1327 + 1328 + if (chargers_externally_control) { 1329 + dev_err(&pdev->dev, "Cannot register regulator because " 1330 + "charger-manager must need at least " 1331 + "one charger for charging battery\n"); 1332 + 1333 + ret = -EINVAL; 1334 + goto err_chg_enable; 1533 1335 } 1534 1336 1535 1337 ret = try_charger_enable(cm, true); ··· 1620 1292 return 0; 1621 1293 1622 1294 err_chg_enable: 1295 + for (i = 0; i < desc->num_charger_regulators; i++) { 1296 + struct charger_regulator *charger; 1297 + 1298 + charger = &desc->charger_regulators[i]; 1299 + sysfs_remove_group(&cm->charger_psy.dev->kobj, 1300 + &charger->attr_g); 1301 + kfree(charger->attr_g.name); 1302 + } 1623 1303 err_extcon: 1624 1304 for (i = 0 ; i < desc->num_charger_regulators ; i++) { 1625 1305 struct charger_regulator *charger
+2 -2
drivers/power/da9030_battery.c
··· 187 187 188 188 static struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger) 189 189 { 190 - charger->debug_file = debugfs_create_file("charger", 0666, 0, charger, 191 - &bat_debug_fops); 190 + charger->debug_file = debugfs_create_file("charger", 0666, NULL, 191 + charger, &bat_debug_fops); 192 192 return charger->debug_file; 193 193 } 194 194
+9 -2
drivers/power/da9052-battery.c
··· 327 327 return tmp; 328 328 } 329 329 330 - unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp) 330 + static unsigned char da9052_determine_vc_tbl_index(unsigned char adc_temp) 331 331 { 332 332 int i; 333 333 ··· 345 345 && (adc_temp <= vc_tbl_ref[i])) 346 346 return i + 1; 347 347 } 348 + /* 349 + * For some reason authors of the driver didn't presume that we can 350 + * end up here. It might be OK, but might be not, no one knows for 351 + * sure. Go check your battery, is it on fire? 352 + */ 353 + WARN_ON(1); 354 + return 0; 348 355 } 349 356 350 357 static int da9052_bat_read_capacity(struct da9052_battery *bat, int *capacity) ··· 623 616 return 0; 624 617 625 618 err: 626 - for (; i >= 0; i--) { 619 + while (--i >= 0) { 627 620 irq = platform_get_irq_byname(pdev, da9052_bat_irqs[i]); 628 621 free_irq(bat->da9052->irq_base + irq, bat); 629 622 }
+5 -23
drivers/power/ds2781_battery.c
··· 755 755 int ret = 0; 756 756 struct ds2781_device_info *dev_info; 757 757 758 - dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); 759 - if (!dev_info) { 760 - ret = -ENOMEM; 761 - goto fail; 762 - } 758 + dev_info = devm_kzalloc(&pdev->dev, sizeof(*dev_info), GFP_KERNEL); 759 + if (!dev_info) 760 + return -ENOMEM; 763 761 764 762 platform_set_drvdata(pdev, dev_info); 765 763 ··· 772 774 ret = power_supply_register(&pdev->dev, &dev_info->bat); 773 775 if (ret) { 774 776 dev_err(dev_info->dev, "failed to register battery\n"); 775 - goto fail_free_info; 777 + goto fail; 776 778 } 777 779 778 780 ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); ··· 806 808 sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2781_attr_group); 807 809 fail_unregister: 808 810 power_supply_unregister(&dev_info->bat); 809 - fail_free_info: 810 - kfree(dev_info); 811 811 fail: 812 812 return ret; 813 813 } ··· 819 823 820 824 power_supply_unregister(&dev_info->bat); 821 825 822 - kfree(dev_info); 823 826 return 0; 824 827 } 825 828 ··· 829 834 .probe = ds2781_battery_probe, 830 835 .remove = __devexit_p(ds2781_battery_remove), 831 836 }; 832 - 833 - static int __init ds2781_battery_init(void) 834 - { 835 - return platform_driver_register(&ds2781_battery_driver); 836 - } 837 - 838 - static void __exit ds2781_battery_exit(void) 839 - { 840 - platform_driver_unregister(&ds2781_battery_driver); 841 - } 842 - 843 - module_init(ds2781_battery_init); 844 - module_exit(ds2781_battery_exit); 845 - 837 + module_platform_driver(ds2781_battery_driver); 846 838 847 839 MODULE_LICENSE("GPL"); 848 840 MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>");
+207 -153
drivers/power/lp8727_charger.c
··· 17 17 #include <linux/power_supply.h> 18 18 #include <linux/platform_data/lp8727.h> 19 19 20 - #define DEBOUNCE_MSEC 270 20 + #define LP8788_NUM_INTREGS 2 21 + #define DEFAULT_DEBOUNCE_MSEC 270 21 22 22 23 /* Registers */ 23 - #define CTRL1 0x1 24 - #define CTRL2 0x2 25 - #define SWCTRL 0x3 26 - #define INT1 0x4 27 - #define INT2 0x5 28 - #define STATUS1 0x6 29 - #define STATUS2 0x7 30 - #define CHGCTRL2 0x9 24 + #define LP8727_CTRL1 0x1 25 + #define LP8727_CTRL2 0x2 26 + #define LP8727_SWCTRL 0x3 27 + #define LP8727_INT1 0x4 28 + #define LP8727_INT2 0x5 29 + #define LP8727_STATUS1 0x6 30 + #define LP8727_STATUS2 0x7 31 + #define LP8727_CHGCTRL2 0x9 31 32 32 33 /* CTRL1 register */ 33 - #define CP_EN (1 << 0) 34 - #define ADC_EN (1 << 1) 35 - #define ID200_EN (1 << 4) 34 + #define LP8727_CP_EN BIT(0) 35 + #define LP8727_ADC_EN BIT(1) 36 + #define LP8727_ID200_EN BIT(4) 36 37 37 38 /* CTRL2 register */ 38 - #define CHGDET_EN (1 << 1) 39 - #define INT_EN (1 << 6) 39 + #define LP8727_CHGDET_EN BIT(1) 40 + #define LP8727_INT_EN BIT(6) 40 41 41 42 /* SWCTRL register */ 42 - #define SW_DM1_DM (0x0 << 0) 43 - #define SW_DM1_U1 (0x1 << 0) 44 - #define SW_DM1_HiZ (0x7 << 0) 45 - #define SW_DP2_DP (0x0 << 3) 46 - #define SW_DP2_U2 (0x1 << 3) 47 - #define SW_DP2_HiZ (0x7 << 3) 43 + #define LP8727_SW_DM1_DM (0x0 << 0) 44 + #define LP8727_SW_DM1_HiZ (0x7 << 0) 45 + #define LP8727_SW_DP2_DP (0x0 << 3) 46 + #define LP8727_SW_DP2_HiZ (0x7 << 3) 48 47 49 48 /* INT1 register */ 50 - #define IDNO (0xF << 0) 51 - #define VBUS (1 << 4) 49 + #define LP8727_IDNO (0xF << 0) 50 + #define LP8727_VBUS BIT(4) 52 51 53 52 /* STATUS1 register */ 54 - #define CHGSTAT (3 << 4) 55 - #define CHPORT (1 << 6) 56 - #define DCPORT (1 << 7) 53 + #define LP8727_CHGSTAT (3 << 4) 54 + #define LP8727_CHPORT BIT(6) 55 + #define LP8727_DCPORT BIT(7) 56 + #define LP8727_STAT_EOC 0x30 57 57 58 58 /* STATUS2 register */ 59 - #define TEMP_STAT (3 << 5) 59 + #define LP8727_TEMP_STAT (3 << 5) 60 + #define LP8727_TEMP_SHIFT 5 61 + 62 + /* CHGCTRL2 register */ 63 + #define LP8727_ICHG_SHIFT 4 60 64 61 65 enum lp8727_dev_id { 62 - ID_NONE, 63 - ID_TA, 64 - ID_DEDICATED_CHG, 65 - ID_USB_CHG, 66 - ID_USB_DS, 67 - ID_MAX, 66 + LP8727_ID_NONE, 67 + LP8727_ID_TA, 68 + LP8727_ID_DEDICATED_CHG, 69 + LP8727_ID_USB_CHG, 70 + LP8727_ID_USB_DS, 71 + LP8727_ID_MAX, 68 72 }; 69 73 70 - enum lp8727_chg_stat { 71 - PRECHG, 72 - CC, 73 - CV, 74 - EOC, 74 + enum lp8727_die_temp { 75 + LP8788_TEMP_75C, 76 + LP8788_TEMP_95C, 77 + LP8788_TEMP_115C, 78 + LP8788_TEMP_135C, 75 79 }; 76 80 77 81 struct lp8727_psy { ··· 88 84 struct device *dev; 89 85 struct i2c_client *client; 90 86 struct mutex xfer_lock; 91 - struct delayed_work work; 92 - struct workqueue_struct *irqthread; 93 - struct lp8727_platform_data *pdata; 94 87 struct lp8727_psy *psy; 95 - struct lp8727_chg_param *chg_parm; 88 + struct lp8727_platform_data *pdata; 89 + 90 + /* Charger Data */ 96 91 enum lp8727_dev_id devid; 92 + struct lp8727_chg_param *chg_param; 93 + 94 + /* Interrupt Handling */ 95 + int irq; 96 + struct delayed_work work; 97 + unsigned long debounce_jiffies; 97 98 }; 98 99 99 100 static int lp8727_read_bytes(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) ··· 128 119 return ret; 129 120 } 130 121 131 - static int lp8727_is_charger_attached(const char *name, int id) 122 + static bool lp8727_is_charger_attached(const char *name, int id) 132 123 { 133 - if (name) { 134 - if (!strcmp(name, "ac")) 135 - return (id == ID_TA || id == ID_DEDICATED_CHG) ? 1 : 0; 136 - else if (!strcmp(name, "usb")) 137 - return (id == ID_USB_CHG) ? 1 : 0; 138 - } 124 + if (!strcmp(name, "ac")) 125 + return id == LP8727_ID_TA || id == LP8727_ID_DEDICATED_CHG; 126 + else if (!strcmp(name, "usb")) 127 + return id == LP8727_ID_USB_CHG; 139 128 140 - return (id >= ID_TA && id <= ID_USB_CHG) ? 1 : 0; 129 + return id >= LP8727_ID_TA && id <= LP8727_ID_USB_CHG; 141 130 } 142 131 143 132 static int lp8727_init_device(struct lp8727_chg *pchg) 144 133 { 145 134 u8 val; 146 135 int ret; 136 + u8 intstat[LP8788_NUM_INTREGS]; 147 137 148 - val = ID200_EN | ADC_EN | CP_EN; 149 - ret = lp8727_write_byte(pchg, CTRL1, val); 138 + /* clear interrupts */ 139 + ret = lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS); 150 140 if (ret) 151 141 return ret; 152 142 153 - val = INT_EN | CHGDET_EN; 154 - ret = lp8727_write_byte(pchg, CTRL2, val); 143 + val = LP8727_ID200_EN | LP8727_ADC_EN | LP8727_CP_EN; 144 + ret = lp8727_write_byte(pchg, LP8727_CTRL1, val); 155 145 if (ret) 156 146 return ret; 157 147 158 - return 0; 148 + val = LP8727_INT_EN | LP8727_CHGDET_EN; 149 + return lp8727_write_byte(pchg, LP8727_CTRL2, val); 159 150 } 160 151 161 152 static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg) 162 153 { 163 154 u8 val; 164 - lp8727_read_byte(pchg, STATUS1, &val); 165 - return val & DCPORT; 155 + 156 + lp8727_read_byte(pchg, LP8727_STATUS1, &val); 157 + return val & LP8727_DCPORT; 166 158 } 167 159 168 160 static int lp8727_is_usb_charger(struct lp8727_chg *pchg) 169 161 { 170 162 u8 val; 171 - lp8727_read_byte(pchg, STATUS1, &val); 172 - return val & CHPORT; 163 + 164 + lp8727_read_byte(pchg, LP8727_STATUS1, &val); 165 + return val & LP8727_CHPORT; 173 166 } 174 167 175 - static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw) 168 + static inline void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw) 176 169 { 177 - lp8727_write_byte(pchg, SWCTRL, sw); 170 + lp8727_write_byte(pchg, LP8727_SWCTRL, sw); 178 171 } 179 172 180 173 static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin) 181 174 { 182 - u8 devid = ID_NONE; 183 - u8 swctrl = SW_DM1_HiZ | SW_DP2_HiZ; 175 + struct lp8727_platform_data *pdata = pchg->pdata; 176 + u8 devid = LP8727_ID_NONE; 177 + u8 swctrl = LP8727_SW_DM1_HiZ | LP8727_SW_DP2_HiZ; 184 178 185 179 switch (id) { 186 180 case 0x5: 187 - devid = ID_TA; 188 - pchg->chg_parm = &pchg->pdata->ac; 181 + devid = LP8727_ID_TA; 182 + pchg->chg_param = pdata ? pdata->ac : NULL; 189 183 break; 190 184 case 0xB: 191 185 if (lp8727_is_dedicated_charger(pchg)) { 192 - pchg->chg_parm = &pchg->pdata->ac; 193 - devid = ID_DEDICATED_CHG; 186 + pchg->chg_param = pdata ? pdata->ac : NULL; 187 + devid = LP8727_ID_DEDICATED_CHG; 194 188 } else if (lp8727_is_usb_charger(pchg)) { 195 - pchg->chg_parm = &pchg->pdata->usb; 196 - devid = ID_USB_CHG; 197 - swctrl = SW_DM1_DM | SW_DP2_DP; 189 + pchg->chg_param = pdata ? pdata->usb : NULL; 190 + devid = LP8727_ID_USB_CHG; 191 + swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP; 198 192 } else if (vbusin) { 199 - devid = ID_USB_DS; 200 - swctrl = SW_DM1_DM | SW_DP2_DP; 193 + devid = LP8727_ID_USB_DS; 194 + swctrl = LP8727_SW_DM1_DM | LP8727_SW_DP2_DP; 201 195 } 202 196 break; 203 197 default: 204 - devid = ID_NONE; 205 - pchg->chg_parm = NULL; 198 + devid = LP8727_ID_NONE; 199 + pchg->chg_param = NULL; 206 200 break; 207 201 } 208 202 ··· 217 205 { 218 206 u8 val; 219 207 220 - lp8727_read_byte(pchg, CTRL2, &val); 221 - val |= CHGDET_EN; 222 - lp8727_write_byte(pchg, CTRL2, val); 208 + lp8727_read_byte(pchg, LP8727_CTRL2, &val); 209 + val |= LP8727_CHGDET_EN; 210 + lp8727_write_byte(pchg, LP8727_CTRL2, val); 223 211 } 224 212 225 213 static void lp8727_delayed_func(struct work_struct *_work) 226 214 { 227 - u8 intstat[2], idno, vbus; 228 - struct lp8727_chg *pchg = 229 - container_of(_work, struct lp8727_chg, work.work); 215 + struct lp8727_chg *pchg = container_of(_work, struct lp8727_chg, 216 + work.work); 217 + u8 intstat[LP8788_NUM_INTREGS]; 218 + u8 idno; 219 + u8 vbus; 230 220 231 - if (lp8727_read_bytes(pchg, INT1, intstat, 2)) { 221 + if (lp8727_read_bytes(pchg, LP8727_INT1, intstat, LP8788_NUM_INTREGS)) { 232 222 dev_err(pchg->dev, "can not read INT registers\n"); 233 223 return; 234 224 } 235 225 236 - idno = intstat[0] & IDNO; 237 - vbus = intstat[0] & VBUS; 226 + idno = intstat[0] & LP8727_IDNO; 227 + vbus = intstat[0] & LP8727_VBUS; 238 228 239 229 lp8727_id_detection(pchg, idno, vbus); 240 230 lp8727_enable_chgdet(pchg); ··· 249 235 static irqreturn_t lp8727_isr_func(int irq, void *ptr) 250 236 { 251 237 struct lp8727_chg *pchg = ptr; 252 - unsigned long delay = msecs_to_jiffies(DEBOUNCE_MSEC); 253 238 254 - queue_delayed_work(pchg->irqthread, &pchg->work, delay); 255 - 239 + schedule_delayed_work(&pchg->work, pchg->debounce_jiffies); 256 240 return IRQ_HANDLED; 257 241 } 258 242 259 - static int lp8727_intr_config(struct lp8727_chg *pchg) 243 + static int lp8727_setup_irq(struct lp8727_chg *pchg) 260 244 { 245 + int ret; 246 + int irq = pchg->client->irq; 247 + unsigned delay_msec = pchg->pdata ? pchg->pdata->debounce_msec : 248 + DEFAULT_DEBOUNCE_MSEC; 249 + 261 250 INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func); 262 251 263 - pchg->irqthread = create_singlethread_workqueue("lp8727-irqthd"); 264 - if (!pchg->irqthread) { 265 - dev_err(pchg->dev, "can not create thread for lp8727\n"); 266 - return -ENOMEM; 252 + if (irq <= 0) { 253 + dev_warn(pchg->dev, "invalid irq number: %d\n", irq); 254 + return 0; 267 255 } 268 256 269 - return request_threaded_irq(pchg->client->irq, 270 - NULL, 271 - lp8727_isr_func, 272 - IRQF_TRIGGER_FALLING, 273 - "lp8727_irq", 274 - pchg); 257 + ret = request_threaded_irq(irq, NULL, lp8727_isr_func, 258 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 259 + "lp8727_irq", pchg); 260 + 261 + if (ret) 262 + return ret; 263 + 264 + pchg->irq = irq; 265 + pchg->debounce_jiffies = msecs_to_jiffies(delay_msec); 266 + 267 + return 0; 268 + } 269 + 270 + static void lp8727_release_irq(struct lp8727_chg *pchg) 271 + { 272 + cancel_delayed_work_sync(&pchg->work); 273 + 274 + if (pchg->irq) 275 + free_irq(pchg->irq, pchg); 275 276 } 276 277 277 278 static enum power_supply_property lp8727_charger_prop[] = { ··· 312 283 { 313 284 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 314 285 315 - if (psp == POWER_SUPPLY_PROP_ONLINE) 316 - val->intval = lp8727_is_charger_attached(psy->name, 317 - pchg->devid); 286 + if (psp != POWER_SUPPLY_PROP_ONLINE) 287 + return -EINVAL; 288 + 289 + val->intval = lp8727_is_charger_attached(psy->name, pchg->devid); 318 290 319 291 return 0; 292 + } 293 + 294 + static bool lp8727_is_high_temperature(enum lp8727_die_temp temp) 295 + { 296 + switch (temp) { 297 + case LP8788_TEMP_95C: 298 + case LP8788_TEMP_115C: 299 + case LP8788_TEMP_135C: 300 + return true; 301 + default: 302 + return false; 303 + } 320 304 } 321 305 322 306 static int lp8727_battery_get_property(struct power_supply *psy, ··· 337 295 union power_supply_propval *val) 338 296 { 339 297 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 298 + struct lp8727_platform_data *pdata = pchg->pdata; 299 + enum lp8727_die_temp temp; 340 300 u8 read; 341 301 342 302 switch (psp) { 343 303 case POWER_SUPPLY_PROP_STATUS: 344 - if (lp8727_is_charger_attached(psy->name, pchg->devid)) { 345 - lp8727_read_byte(pchg, STATUS1, &read); 346 - if (((read & CHGSTAT) >> 4) == EOC) 347 - val->intval = POWER_SUPPLY_STATUS_FULL; 348 - else 349 - val->intval = POWER_SUPPLY_STATUS_CHARGING; 350 - } else { 304 + if (!lp8727_is_charger_attached(psy->name, pchg->devid)) { 351 305 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 306 + return 0; 352 307 } 308 + 309 + lp8727_read_byte(pchg, LP8727_STATUS1, &read); 310 + 311 + val->intval = (read & LP8727_CHGSTAT) == LP8727_STAT_EOC ? 312 + POWER_SUPPLY_STATUS_FULL : 313 + POWER_SUPPLY_STATUS_CHARGING; 353 314 break; 354 315 case POWER_SUPPLY_PROP_HEALTH: 355 - lp8727_read_byte(pchg, STATUS2, &read); 356 - read = (read & TEMP_STAT) >> 5; 357 - if (read >= 0x1 && read <= 0x3) 358 - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 359 - else 360 - val->intval = POWER_SUPPLY_HEALTH_GOOD; 316 + lp8727_read_byte(pchg, LP8727_STATUS2, &read); 317 + temp = (read & LP8727_TEMP_STAT) >> LP8727_TEMP_SHIFT; 318 + 319 + val->intval = lp8727_is_high_temperature(temp) ? 320 + POWER_SUPPLY_HEALTH_OVERHEAT : 321 + POWER_SUPPLY_HEALTH_GOOD; 361 322 break; 362 323 case POWER_SUPPLY_PROP_PRESENT: 363 - if (pchg->pdata->get_batt_present) 324 + if (!pdata) 325 + return -EINVAL; 326 + 327 + if (pdata->get_batt_present) 364 328 val->intval = pchg->pdata->get_batt_present(); 365 329 break; 366 330 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 367 - if (pchg->pdata->get_batt_level) 331 + if (!pdata) 332 + return -EINVAL; 333 + 334 + if (pdata->get_batt_level) 368 335 val->intval = pchg->pdata->get_batt_level(); 369 336 break; 370 337 case POWER_SUPPLY_PROP_CAPACITY: 371 - if (pchg->pdata->get_batt_capacity) 338 + if (!pdata) 339 + return -EINVAL; 340 + 341 + if (pdata->get_batt_capacity) 372 342 val->intval = pchg->pdata->get_batt_capacity(); 373 343 break; 374 344 case POWER_SUPPLY_PROP_TEMP: 375 - if (pchg->pdata->get_batt_temp) 345 + if (!pdata) 346 + return -EINVAL; 347 + 348 + if (pdata->get_batt_temp) 376 349 val->intval = pchg->pdata->get_batt_temp(); 377 350 break; 378 351 default: ··· 400 343 static void lp8727_charger_changed(struct power_supply *psy) 401 344 { 402 345 struct lp8727_chg *pchg = dev_get_drvdata(psy->dev->parent); 346 + u8 eoc_level; 347 + u8 ichg; 403 348 u8 val; 404 - u8 eoc_level, ichg; 405 349 406 - if (lp8727_is_charger_attached(psy->name, pchg->devid)) { 407 - if (pchg->chg_parm) { 408 - eoc_level = pchg->chg_parm->eoc_level; 409 - ichg = pchg->chg_parm->ichg; 410 - val = (ichg << 4) | eoc_level; 411 - lp8727_write_byte(pchg, CHGCTRL2, val); 412 - } 350 + /* skip if no charger exists */ 351 + if (!lp8727_is_charger_attached(psy->name, pchg->devid)) 352 + return; 353 + 354 + /* update charging parameters */ 355 + if (pchg->chg_param) { 356 + eoc_level = pchg->chg_param->eoc_level; 357 + ichg = pchg->chg_param->ichg; 358 + val = (ichg << LP8727_ICHG_SHIFT) | eoc_level; 359 + lp8727_write_byte(pchg, LP8727_CHGCTRL2, val); 413 360 } 414 361 } 415 362 ··· 421 360 { 422 361 struct lp8727_psy *psy; 423 362 424 - psy = kzalloc(sizeof(*psy), GFP_KERNEL); 363 + psy = devm_kzalloc(pchg->dev, sizeof(*psy), GFP_KERNEL); 425 364 if (!psy) 426 - goto err_mem; 365 + return -ENOMEM; 427 366 428 367 pchg->psy = psy; 429 368 ··· 436 375 psy->ac.num_supplicants = ARRAY_SIZE(battery_supplied_to); 437 376 438 377 if (power_supply_register(pchg->dev, &psy->ac)) 439 - goto err_psy; 378 + goto err_psy_ac; 440 379 441 380 psy->usb.name = "usb"; 442 381 psy->usb.type = POWER_SUPPLY_TYPE_USB; ··· 447 386 psy->usb.num_supplicants = ARRAY_SIZE(battery_supplied_to); 448 387 449 388 if (power_supply_register(pchg->dev, &psy->usb)) 450 - goto err_psy; 389 + goto err_psy_usb; 451 390 452 391 psy->batt.name = "main_batt"; 453 392 psy->batt.type = POWER_SUPPLY_TYPE_BATTERY; ··· 457 396 psy->batt.external_power_changed = lp8727_charger_changed; 458 397 459 398 if (power_supply_register(pchg->dev, &psy->batt)) 460 - goto err_psy; 399 + goto err_psy_batt; 461 400 462 401 return 0; 463 402 464 - err_mem: 465 - return -ENOMEM; 466 - err_psy: 467 - kfree(psy); 403 + err_psy_batt: 404 + power_supply_unregister(&psy->usb); 405 + err_psy_usb: 406 + power_supply_unregister(&psy->ac); 407 + err_psy_ac: 468 408 return -EPERM; 469 409 } 470 410 ··· 479 417 power_supply_unregister(&psy->ac); 480 418 power_supply_unregister(&psy->usb); 481 419 power_supply_unregister(&psy->batt); 482 - kfree(psy); 483 420 } 484 421 485 422 static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) ··· 489 428 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 490 429 return -EIO; 491 430 492 - pchg = kzalloc(sizeof(*pchg), GFP_KERNEL); 431 + pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL); 493 432 if (!pchg) 494 433 return -ENOMEM; 495 434 ··· 503 442 ret = lp8727_init_device(pchg); 504 443 if (ret) { 505 444 dev_err(pchg->dev, "i2c communication err: %d", ret); 506 - goto error; 507 - } 508 - 509 - ret = lp8727_intr_config(pchg); 510 - if (ret) { 511 - dev_err(pchg->dev, "irq handler err: %d", ret); 512 - goto error; 445 + return ret; 513 446 } 514 447 515 448 ret = lp8727_register_psy(pchg); 516 449 if (ret) { 517 450 dev_err(pchg->dev, "power supplies register err: %d", ret); 518 - goto error; 451 + return ret; 452 + } 453 + 454 + ret = lp8727_setup_irq(pchg); 455 + if (ret) { 456 + dev_err(pchg->dev, "irq handler err: %d", ret); 457 + lp8727_unregister_psy(pchg); 458 + return ret; 519 459 } 520 460 521 461 return 0; 522 - 523 - error: 524 - kfree(pchg); 525 - return ret; 526 462 } 527 463 528 464 static int __devexit lp8727_remove(struct i2c_client *cl) 529 465 { 530 466 struct lp8727_chg *pchg = i2c_get_clientdata(cl); 531 467 468 + lp8727_release_irq(pchg); 532 469 lp8727_unregister_psy(pchg); 533 - free_irq(pchg->client->irq, pchg); 534 - flush_workqueue(pchg->irqthread); 535 - destroy_workqueue(pchg->irqthread); 536 - kfree(pchg); 537 470 return 0; 538 471 } 539 472 ··· 548 493 module_i2c_driver(lp8727_driver); 549 494 550 495 MODULE_DESCRIPTION("TI/National Semiconductor LP8727 charger driver"); 551 - MODULE_AUTHOR("Woogyom Kim <milo.kim@ti.com>, " 552 - "Daniel Jeong <daniel.jeong@ti.com>"); 496 + MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>"); 553 497 MODULE_LICENSE("GPL");
+795
drivers/power/lp8788-charger.c
··· 1 + /* 2 + * TI LP8788 MFD - battery charger driver 3 + * 4 + * Copyright 2012 Texas Instruments 5 + * 6 + * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + */ 13 + 14 + #include <linux/err.h> 15 + #include <linux/iio/consumer.h> 16 + #include <linux/interrupt.h> 17 + #include <linux/irqdomain.h> 18 + #include <linux/mfd/lp8788.h> 19 + #include <linux/module.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/power_supply.h> 22 + #include <linux/slab.h> 23 + #include <linux/workqueue.h> 24 + 25 + /* register address */ 26 + #define LP8788_CHG_STATUS 0x07 27 + #define LP8788_CHG_IDCIN 0x13 28 + #define LP8788_CHG_IBATT 0x14 29 + #define LP8788_CHG_VTERM 0x15 30 + #define LP8788_CHG_EOC 0x16 31 + 32 + /* mask/shift bits */ 33 + #define LP8788_CHG_INPUT_STATE_M 0x03 /* Addr 07h */ 34 + #define LP8788_CHG_STATE_M 0x3C 35 + #define LP8788_CHG_STATE_S 2 36 + #define LP8788_NO_BATT_M BIT(6) 37 + #define LP8788_BAD_BATT_M BIT(7) 38 + #define LP8788_CHG_IBATT_M 0x1F /* Addr 14h */ 39 + #define LP8788_CHG_VTERM_M 0x0F /* Addr 15h */ 40 + #define LP8788_CHG_EOC_LEVEL_M 0x30 /* Addr 16h */ 41 + #define LP8788_CHG_EOC_LEVEL_S 4 42 + #define LP8788_CHG_EOC_TIME_M 0x0E 43 + #define LP8788_CHG_EOC_TIME_S 1 44 + #define LP8788_CHG_EOC_MODE_M BIT(0) 45 + 46 + #define LP8788_CHARGER_NAME "charger" 47 + #define LP8788_BATTERY_NAME "main_batt" 48 + 49 + #define LP8788_CHG_START 0x11 50 + #define LP8788_CHG_END 0x1C 51 + 52 + #define LP8788_BUF_SIZE 40 53 + #define LP8788_ISEL_MAX 23 54 + #define LP8788_ISEL_STEP 50 55 + #define LP8788_VTERM_MIN 4100 56 + #define LP8788_VTERM_STEP 25 57 + #define LP8788_MAX_BATT_CAPACITY 100 58 + #define LP8788_MAX_CHG_IRQS 11 59 + 60 + enum lp8788_charging_state { 61 + LP8788_OFF, 62 + LP8788_WARM_UP, 63 + LP8788_LOW_INPUT = 0x3, 64 + LP8788_PRECHARGE, 65 + LP8788_CC, 66 + LP8788_CV, 67 + LP8788_MAINTENANCE, 68 + LP8788_BATTERY_FAULT, 69 + LP8788_SYSTEM_SUPPORT = 0xC, 70 + LP8788_HIGH_CURRENT = 0xF, 71 + LP8788_MAX_CHG_STATE, 72 + }; 73 + 74 + enum lp8788_charger_adc_sel { 75 + LP8788_VBATT, 76 + LP8788_BATT_TEMP, 77 + LP8788_NUM_CHG_ADC, 78 + }; 79 + 80 + enum lp8788_charger_input_state { 81 + LP8788_SYSTEM_SUPPLY = 1, 82 + LP8788_FULL_FUNCTION, 83 + }; 84 + 85 + /* 86 + * struct lp8788_chg_irq 87 + * @which : lp8788 interrupt id 88 + * @virq : Linux IRQ number from irq_domain 89 + */ 90 + struct lp8788_chg_irq { 91 + enum lp8788_int_id which; 92 + int virq; 93 + }; 94 + 95 + /* 96 + * struct lp8788_charger 97 + * @lp : used for accessing the registers of mfd lp8788 device 98 + * @charger : power supply driver for the battery charger 99 + * @battery : power supply driver for the battery 100 + * @charger_work : work queue for charger input interrupts 101 + * @chan : iio channels for getting adc values 102 + * eg) battery voltage, capacity and temperature 103 + * @irqs : charger dedicated interrupts 104 + * @num_irqs : total numbers of charger interrupts 105 + * @pdata : charger platform specific data 106 + */ 107 + struct lp8788_charger { 108 + struct lp8788 *lp; 109 + struct power_supply charger; 110 + struct power_supply battery; 111 + struct work_struct charger_work; 112 + struct iio_channel *chan[LP8788_NUM_CHG_ADC]; 113 + struct lp8788_chg_irq irqs[LP8788_MAX_CHG_IRQS]; 114 + int num_irqs; 115 + struct lp8788_charger_platform_data *pdata; 116 + }; 117 + 118 + static char *battery_supplied_to[] = { 119 + LP8788_BATTERY_NAME, 120 + }; 121 + 122 + static enum power_supply_property lp8788_charger_prop[] = { 123 + POWER_SUPPLY_PROP_ONLINE, 124 + POWER_SUPPLY_PROP_CURRENT_MAX, 125 + }; 126 + 127 + static enum power_supply_property lp8788_battery_prop[] = { 128 + POWER_SUPPLY_PROP_STATUS, 129 + POWER_SUPPLY_PROP_HEALTH, 130 + POWER_SUPPLY_PROP_PRESENT, 131 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 132 + POWER_SUPPLY_PROP_CAPACITY, 133 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 134 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 135 + POWER_SUPPLY_PROP_TEMP, 136 + }; 137 + 138 + static bool lp8788_is_charger_detected(struct lp8788_charger *pchg) 139 + { 140 + u8 data; 141 + 142 + lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 143 + data &= LP8788_CHG_INPUT_STATE_M; 144 + 145 + return data == LP8788_SYSTEM_SUPPLY || data == LP8788_FULL_FUNCTION; 146 + } 147 + 148 + static int lp8788_charger_get_property(struct power_supply *psy, 149 + enum power_supply_property psp, 150 + union power_supply_propval *val) 151 + { 152 + struct lp8788_charger *pchg = dev_get_drvdata(psy->dev->parent); 153 + u8 read; 154 + 155 + switch (psp) { 156 + case POWER_SUPPLY_PROP_ONLINE: 157 + val->intval = lp8788_is_charger_detected(pchg); 158 + break; 159 + case POWER_SUPPLY_PROP_CURRENT_MAX: 160 + lp8788_read_byte(pchg->lp, LP8788_CHG_IDCIN, &read); 161 + val->intval = LP8788_ISEL_STEP * 162 + (min_t(int, read, LP8788_ISEL_MAX) + 1); 163 + break; 164 + default: 165 + return -EINVAL; 166 + } 167 + 168 + return 0; 169 + } 170 + 171 + static int lp8788_get_battery_status(struct lp8788_charger *pchg, 172 + union power_supply_propval *val) 173 + { 174 + enum lp8788_charging_state state; 175 + u8 data; 176 + int ret; 177 + 178 + ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 179 + if (ret) 180 + return ret; 181 + 182 + state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S; 183 + switch (state) { 184 + case LP8788_OFF: 185 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 186 + break; 187 + case LP8788_PRECHARGE: 188 + case LP8788_CC: 189 + case LP8788_CV: 190 + case LP8788_HIGH_CURRENT: 191 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 192 + break; 193 + case LP8788_MAINTENANCE: 194 + val->intval = POWER_SUPPLY_STATUS_FULL; 195 + break; 196 + default: 197 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 198 + break; 199 + } 200 + 201 + return 0; 202 + } 203 + 204 + static int lp8788_get_battery_health(struct lp8788_charger *pchg, 205 + union power_supply_propval *val) 206 + { 207 + u8 data; 208 + int ret; 209 + 210 + ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 211 + if (ret) 212 + return ret; 213 + 214 + if (data & LP8788_NO_BATT_M) 215 + val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 216 + else if (data & LP8788_BAD_BATT_M) 217 + val->intval = POWER_SUPPLY_HEALTH_DEAD; 218 + else 219 + val->intval = POWER_SUPPLY_HEALTH_GOOD; 220 + 221 + return 0; 222 + } 223 + 224 + static int lp8788_get_battery_present(struct lp8788_charger *pchg, 225 + union power_supply_propval *val) 226 + { 227 + u8 data; 228 + int ret; 229 + 230 + ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 231 + if (ret) 232 + return ret; 233 + 234 + val->intval = !(data & LP8788_NO_BATT_M); 235 + return 0; 236 + } 237 + 238 + static int lp8788_get_vbatt_adc(struct lp8788_charger *pchg, 239 + unsigned int *result) 240 + { 241 + struct iio_channel *channel = pchg->chan[LP8788_VBATT]; 242 + int scaleint; 243 + int scalepart; 244 + int ret; 245 + 246 + if (!channel) 247 + return -EINVAL; 248 + 249 + ret = iio_read_channel_scale(channel, &scaleint, &scalepart); 250 + if (ret != IIO_VAL_INT_PLUS_MICRO) 251 + return -EINVAL; 252 + 253 + /* unit: mV */ 254 + *result = (scaleint + scalepart * 1000000) / 1000; 255 + 256 + return 0; 257 + } 258 + 259 + static int lp8788_get_battery_voltage(struct lp8788_charger *pchg, 260 + union power_supply_propval *val) 261 + { 262 + return lp8788_get_vbatt_adc(pchg, &val->intval); 263 + } 264 + 265 + static int lp8788_get_battery_capacity(struct lp8788_charger *pchg, 266 + union power_supply_propval *val) 267 + { 268 + struct lp8788 *lp = pchg->lp; 269 + struct lp8788_charger_platform_data *pdata = pchg->pdata; 270 + unsigned int max_vbatt; 271 + unsigned int vbatt; 272 + enum lp8788_charging_state state; 273 + u8 data; 274 + int ret; 275 + 276 + if (!pdata) 277 + return -EINVAL; 278 + 279 + max_vbatt = pdata->max_vbatt_mv; 280 + if (max_vbatt == 0) 281 + return -EINVAL; 282 + 283 + ret = lp8788_read_byte(lp, LP8788_CHG_STATUS, &data); 284 + if (ret) 285 + return ret; 286 + 287 + state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S; 288 + 289 + if (state == LP8788_MAINTENANCE) { 290 + val->intval = LP8788_MAX_BATT_CAPACITY; 291 + } else { 292 + ret = lp8788_get_vbatt_adc(pchg, &vbatt); 293 + if (ret) 294 + return ret; 295 + 296 + val->intval = (vbatt * LP8788_MAX_BATT_CAPACITY) / max_vbatt; 297 + val->intval = min(val->intval, LP8788_MAX_BATT_CAPACITY); 298 + } 299 + 300 + return 0; 301 + } 302 + 303 + static int lp8788_get_battery_temperature(struct lp8788_charger *pchg, 304 + union power_supply_propval *val) 305 + { 306 + struct iio_channel *channel = pchg->chan[LP8788_BATT_TEMP]; 307 + int scaleint; 308 + int scalepart; 309 + int ret; 310 + 311 + if (!channel) 312 + return -EINVAL; 313 + 314 + ret = iio_read_channel_scale(channel, &scaleint, &scalepart); 315 + if (ret != IIO_VAL_INT_PLUS_MICRO) 316 + return -EINVAL; 317 + 318 + /* unit: 0.1 'C */ 319 + val->intval = (scaleint + scalepart * 1000000) / 100; 320 + 321 + return 0; 322 + } 323 + 324 + static int lp8788_get_battery_charging_current(struct lp8788_charger *pchg, 325 + union power_supply_propval *val) 326 + { 327 + u8 read; 328 + 329 + lp8788_read_byte(pchg->lp, LP8788_CHG_IBATT, &read); 330 + read &= LP8788_CHG_IBATT_M; 331 + val->intval = LP8788_ISEL_STEP * 332 + (min_t(int, read, LP8788_ISEL_MAX) + 1); 333 + 334 + return 0; 335 + } 336 + 337 + static int lp8788_get_charging_termination_voltage(struct lp8788_charger *pchg, 338 + union power_supply_propval *val) 339 + { 340 + u8 read; 341 + 342 + lp8788_read_byte(pchg->lp, LP8788_CHG_VTERM, &read); 343 + read &= LP8788_CHG_VTERM_M; 344 + val->intval = LP8788_VTERM_MIN + LP8788_VTERM_STEP * read; 345 + 346 + return 0; 347 + } 348 + 349 + static int lp8788_battery_get_property(struct power_supply *psy, 350 + enum power_supply_property psp, 351 + union power_supply_propval *val) 352 + { 353 + struct lp8788_charger *pchg = dev_get_drvdata(psy->dev->parent); 354 + 355 + switch (psp) { 356 + case POWER_SUPPLY_PROP_STATUS: 357 + return lp8788_get_battery_status(pchg, val); 358 + case POWER_SUPPLY_PROP_HEALTH: 359 + return lp8788_get_battery_health(pchg, val); 360 + case POWER_SUPPLY_PROP_PRESENT: 361 + return lp8788_get_battery_present(pchg, val); 362 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 363 + return lp8788_get_battery_voltage(pchg, val); 364 + case POWER_SUPPLY_PROP_CAPACITY: 365 + return lp8788_get_battery_capacity(pchg, val); 366 + case POWER_SUPPLY_PROP_TEMP: 367 + return lp8788_get_battery_temperature(pchg, val); 368 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 369 + return lp8788_get_battery_charging_current(pchg, val); 370 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 371 + return lp8788_get_charging_termination_voltage(pchg, val); 372 + default: 373 + return -EINVAL; 374 + } 375 + } 376 + 377 + static inline bool lp8788_is_valid_charger_register(u8 addr) 378 + { 379 + return addr >= LP8788_CHG_START && addr <= LP8788_CHG_END; 380 + } 381 + 382 + static int lp8788_update_charger_params(struct lp8788_charger *pchg) 383 + { 384 + struct lp8788 *lp = pchg->lp; 385 + struct lp8788_charger_platform_data *pdata = pchg->pdata; 386 + struct lp8788_chg_param *param; 387 + int i; 388 + int ret; 389 + 390 + if (!pdata || !pdata->chg_params) { 391 + dev_info(lp->dev, "skip updating charger parameters\n"); 392 + return 0; 393 + } 394 + 395 + /* settting charging parameters */ 396 + for (i = 0; i < pdata->num_chg_params; i++) { 397 + param = pdata->chg_params + i; 398 + 399 + if (!param) 400 + continue; 401 + 402 + if (lp8788_is_valid_charger_register(param->addr)) { 403 + ret = lp8788_write_byte(lp, param->addr, param->val); 404 + if (ret) 405 + return ret; 406 + } 407 + } 408 + 409 + return 0; 410 + } 411 + 412 + static int lp8788_psy_register(struct platform_device *pdev, 413 + struct lp8788_charger *pchg) 414 + { 415 + pchg->charger.name = LP8788_CHARGER_NAME; 416 + pchg->charger.type = POWER_SUPPLY_TYPE_MAINS; 417 + pchg->charger.properties = lp8788_charger_prop; 418 + pchg->charger.num_properties = ARRAY_SIZE(lp8788_charger_prop); 419 + pchg->charger.get_property = lp8788_charger_get_property; 420 + pchg->charger.supplied_to = battery_supplied_to; 421 + pchg->charger.num_supplicants = ARRAY_SIZE(battery_supplied_to); 422 + 423 + if (power_supply_register(&pdev->dev, &pchg->charger)) 424 + return -EPERM; 425 + 426 + pchg->battery.name = LP8788_BATTERY_NAME; 427 + pchg->battery.type = POWER_SUPPLY_TYPE_BATTERY; 428 + pchg->battery.properties = lp8788_battery_prop; 429 + pchg->battery.num_properties = ARRAY_SIZE(lp8788_battery_prop); 430 + pchg->battery.get_property = lp8788_battery_get_property; 431 + 432 + if (power_supply_register(&pdev->dev, &pchg->battery)) 433 + return -EPERM; 434 + 435 + return 0; 436 + } 437 + 438 + static void lp8788_psy_unregister(struct lp8788_charger *pchg) 439 + { 440 + power_supply_unregister(&pchg->battery); 441 + power_supply_unregister(&pchg->charger); 442 + } 443 + 444 + static void lp8788_charger_event(struct work_struct *work) 445 + { 446 + struct lp8788_charger *pchg = 447 + container_of(work, struct lp8788_charger, charger_work); 448 + struct lp8788_charger_platform_data *pdata = pchg->pdata; 449 + enum lp8788_charger_event event = lp8788_is_charger_detected(pchg); 450 + 451 + pdata->charger_event(pchg->lp, event); 452 + } 453 + 454 + static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id) 455 + { 456 + bool found; 457 + int i; 458 + 459 + for (i = 0; i < pchg->num_irqs; i++) { 460 + if (pchg->irqs[i].virq == virq) { 461 + *id = pchg->irqs[i].which; 462 + found = true; 463 + break; 464 + } 465 + } 466 + 467 + return found; 468 + } 469 + 470 + static irqreturn_t lp8788_charger_irq_thread(int virq, void *ptr) 471 + { 472 + struct lp8788_charger *pchg = ptr; 473 + struct lp8788_charger_platform_data *pdata = pchg->pdata; 474 + int id = -1; 475 + 476 + if (!lp8788_find_irq_id(pchg, virq, &id)) 477 + return IRQ_NONE; 478 + 479 + switch (id) { 480 + case LP8788_INT_CHG_INPUT_STATE: 481 + case LP8788_INT_CHG_STATE: 482 + case LP8788_INT_EOC: 483 + case LP8788_INT_BATT_LOW: 484 + case LP8788_INT_NO_BATT: 485 + power_supply_changed(&pchg->charger); 486 + power_supply_changed(&pchg->battery); 487 + break; 488 + default: 489 + break; 490 + } 491 + 492 + /* report charger dectection event if used */ 493 + if (!pdata) 494 + goto irq_handled; 495 + 496 + if (pdata->charger_event && id == LP8788_INT_CHG_INPUT_STATE) 497 + schedule_work(&pchg->charger_work); 498 + 499 + irq_handled: 500 + return IRQ_HANDLED; 501 + } 502 + 503 + static int lp8788_set_irqs(struct platform_device *pdev, 504 + struct lp8788_charger *pchg, const char *name) 505 + { 506 + struct resource *r; 507 + struct irq_domain *irqdm = pchg->lp->irqdm; 508 + int irq_start; 509 + int irq_end; 510 + int virq; 511 + int nr_irq; 512 + int i; 513 + int ret; 514 + 515 + /* no error even if no irq resource */ 516 + r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, name); 517 + if (!r) 518 + return 0; 519 + 520 + irq_start = r->start; 521 + irq_end = r->end; 522 + 523 + for (i = irq_start; i <= irq_end; i++) { 524 + nr_irq = pchg->num_irqs; 525 + 526 + virq = irq_create_mapping(irqdm, i); 527 + pchg->irqs[nr_irq].virq = virq; 528 + pchg->irqs[nr_irq].which = i; 529 + pchg->num_irqs++; 530 + 531 + ret = request_threaded_irq(virq, NULL, 532 + lp8788_charger_irq_thread, 533 + 0, name, pchg); 534 + if (ret) 535 + break; 536 + } 537 + 538 + if (i <= irq_end) 539 + goto err_free_irq; 540 + 541 + return 0; 542 + 543 + err_free_irq: 544 + for (i = 0; i < pchg->num_irqs; i++) 545 + free_irq(pchg->irqs[i].virq, pchg); 546 + return ret; 547 + } 548 + 549 + static int lp8788_irq_register(struct platform_device *pdev, 550 + struct lp8788_charger *pchg) 551 + { 552 + struct lp8788 *lp = pchg->lp; 553 + const char *name[] = { 554 + LP8788_CHG_IRQ, LP8788_PRSW_IRQ, LP8788_BATT_IRQ 555 + }; 556 + int i; 557 + int ret; 558 + 559 + INIT_WORK(&pchg->charger_work, lp8788_charger_event); 560 + pchg->num_irqs = 0; 561 + 562 + for (i = 0; i < ARRAY_SIZE(name); i++) { 563 + ret = lp8788_set_irqs(pdev, pchg, name[i]); 564 + if (ret) { 565 + dev_warn(lp->dev, "irq setup failed: %s\n", name[i]); 566 + return ret; 567 + } 568 + } 569 + 570 + if (pchg->num_irqs > LP8788_MAX_CHG_IRQS) { 571 + dev_err(lp->dev, "invalid total number of irqs: %d\n", 572 + pchg->num_irqs); 573 + return -EINVAL; 574 + } 575 + 576 + 577 + return 0; 578 + } 579 + 580 + static void lp8788_irq_unregister(struct platform_device *pdev, 581 + struct lp8788_charger *pchg) 582 + { 583 + int i; 584 + int irq; 585 + 586 + for (i = 0; i < pchg->num_irqs; i++) { 587 + irq = pchg->irqs[i].virq; 588 + if (!irq) 589 + continue; 590 + 591 + free_irq(irq, pchg); 592 + } 593 + } 594 + 595 + static void lp8788_setup_adc_channel(struct lp8788_charger *pchg) 596 + { 597 + struct lp8788_charger_platform_data *pdata = pchg->pdata; 598 + struct device *dev = pchg->lp->dev; 599 + struct iio_channel *chan; 600 + enum lp8788_adc_id id; 601 + const char *chan_name[LPADC_MAX] = { 602 + [LPADC_VBATT_5P5] = "vbatt-5p5", 603 + [LPADC_VBATT_6P0] = "vbatt-6p0", 604 + [LPADC_VBATT_5P0] = "vbatt-5p0", 605 + [LPADC_ADC1] = "adc1", 606 + [LPADC_ADC2] = "adc2", 607 + [LPADC_ADC3] = "adc3", 608 + [LPADC_ADC4] = "adc4", 609 + }; 610 + 611 + if (!pdata) 612 + return; 613 + 614 + id = pdata->vbatt_adc; 615 + switch (id) { 616 + case LPADC_VBATT_5P5: 617 + case LPADC_VBATT_6P0: 618 + case LPADC_VBATT_5P0: 619 + chan = iio_channel_get(NULL, chan_name[id]); 620 + pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan; 621 + break; 622 + default: 623 + dev_err(dev, "invalid ADC id for VBATT: %d\n", id); 624 + pchg->chan[LP8788_VBATT] = NULL; 625 + break; 626 + } 627 + 628 + id = pdata->batt_temp_adc; 629 + switch (id) { 630 + case LPADC_ADC1: 631 + case LPADC_ADC2: 632 + case LPADC_ADC3: 633 + case LPADC_ADC4: 634 + chan = iio_channel_get(NULL, chan_name[id]); 635 + pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan; 636 + break; 637 + default: 638 + dev_err(dev, "invalid ADC id for BATT_TEMP : %d\n", id); 639 + pchg->chan[LP8788_BATT_TEMP] = NULL; 640 + break; 641 + } 642 + } 643 + 644 + static void lp8788_release_adc_channel(struct lp8788_charger *pchg) 645 + { 646 + int i; 647 + 648 + for (i = 0; i < LP8788_NUM_CHG_ADC; i++) { 649 + if (!pchg->chan[i]) 650 + continue; 651 + 652 + iio_channel_release(pchg->chan[i]); 653 + pchg->chan[i] = NULL; 654 + } 655 + } 656 + 657 + static ssize_t lp8788_show_charger_status(struct device *dev, 658 + struct device_attribute *attr, char *buf) 659 + { 660 + struct lp8788_charger *pchg = dev_get_drvdata(dev); 661 + enum lp8788_charging_state state; 662 + char *desc[LP8788_MAX_CHG_STATE] = { 663 + [LP8788_OFF] = "CHARGER OFF", 664 + [LP8788_WARM_UP] = "WARM UP", 665 + [LP8788_LOW_INPUT] = "LOW INPUT STATE", 666 + [LP8788_PRECHARGE] = "CHARGING - PRECHARGE", 667 + [LP8788_CC] = "CHARGING - CC", 668 + [LP8788_CV] = "CHARGING - CV", 669 + [LP8788_MAINTENANCE] = "NO CHARGING - MAINTENANCE", 670 + [LP8788_BATTERY_FAULT] = "BATTERY FAULT", 671 + [LP8788_SYSTEM_SUPPORT] = "SYSTEM SUPPORT", 672 + [LP8788_HIGH_CURRENT] = "HIGH CURRENT", 673 + }; 674 + u8 data; 675 + 676 + lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 677 + state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S; 678 + 679 + return scnprintf(buf, LP8788_BUF_SIZE, "%s\n", desc[state]); 680 + } 681 + 682 + static ssize_t lp8788_show_eoc_time(struct device *dev, 683 + struct device_attribute *attr, char *buf) 684 + { 685 + struct lp8788_charger *pchg = dev_get_drvdata(dev); 686 + char *stime[] = { "400ms", "5min", "10min", "15min", 687 + "20min", "25min", "30min" "No timeout" }; 688 + u8 val; 689 + 690 + lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val); 691 + val = (val & LP8788_CHG_EOC_TIME_M) >> LP8788_CHG_EOC_TIME_S; 692 + 693 + return scnprintf(buf, LP8788_BUF_SIZE, "End Of Charge Time: %s\n", 694 + stime[val]); 695 + } 696 + 697 + static ssize_t lp8788_show_eoc_level(struct device *dev, 698 + struct device_attribute *attr, char *buf) 699 + { 700 + struct lp8788_charger *pchg = dev_get_drvdata(dev); 701 + char *abs_level[] = { "25mA", "49mA", "75mA", "98mA" }; 702 + char *relative_level[] = { "5%", "10%", "15%", "20%" }; 703 + char *level; 704 + u8 val; 705 + u8 mode; 706 + 707 + lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val); 708 + 709 + mode = val & LP8788_CHG_EOC_MODE_M; 710 + val = (val & LP8788_CHG_EOC_LEVEL_M) >> LP8788_CHG_EOC_LEVEL_S; 711 + level = mode ? abs_level[val] : relative_level[val]; 712 + 713 + return scnprintf(buf, LP8788_BUF_SIZE, "End Of Charge Level: %s\n", 714 + level); 715 + } 716 + 717 + static DEVICE_ATTR(charger_status, S_IRUSR, lp8788_show_charger_status, NULL); 718 + static DEVICE_ATTR(eoc_time, S_IRUSR, lp8788_show_eoc_time, NULL); 719 + static DEVICE_ATTR(eoc_level, S_IRUSR, lp8788_show_eoc_level, NULL); 720 + 721 + static struct attribute *lp8788_charger_attr[] = { 722 + &dev_attr_charger_status.attr, 723 + &dev_attr_eoc_time.attr, 724 + &dev_attr_eoc_level.attr, 725 + NULL, 726 + }; 727 + 728 + static const struct attribute_group lp8788_attr_group = { 729 + .attrs = lp8788_charger_attr, 730 + }; 731 + 732 + static __devinit int lp8788_charger_probe(struct platform_device *pdev) 733 + { 734 + struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); 735 + struct lp8788_charger *pchg; 736 + int ret; 737 + 738 + pchg = devm_kzalloc(lp->dev, sizeof(struct lp8788_charger), GFP_KERNEL); 739 + if (!pchg) 740 + return -ENOMEM; 741 + 742 + pchg->lp = lp; 743 + pchg->pdata = lp->pdata ? lp->pdata->chg_pdata : NULL; 744 + platform_set_drvdata(pdev, pchg); 745 + 746 + ret = lp8788_update_charger_params(pchg); 747 + if (ret) 748 + return ret; 749 + 750 + lp8788_setup_adc_channel(pchg); 751 + 752 + ret = lp8788_psy_register(pdev, pchg); 753 + if (ret) 754 + return ret; 755 + 756 + ret = sysfs_create_group(&pdev->dev.kobj, &lp8788_attr_group); 757 + if (ret) { 758 + lp8788_psy_unregister(pchg); 759 + return ret; 760 + } 761 + 762 + ret = lp8788_irq_register(pdev, pchg); 763 + if (ret) 764 + dev_warn(lp->dev, "failed to register charger irq: %d\n", ret); 765 + 766 + return 0; 767 + } 768 + 769 + static int __devexit lp8788_charger_remove(struct platform_device *pdev) 770 + { 771 + struct lp8788_charger *pchg = platform_get_drvdata(pdev); 772 + 773 + flush_work(&pchg->charger_work); 774 + lp8788_irq_unregister(pdev, pchg); 775 + sysfs_remove_group(&pdev->dev.kobj, &lp8788_attr_group); 776 + lp8788_psy_unregister(pchg); 777 + lp8788_release_adc_channel(pchg); 778 + 779 + return 0; 780 + } 781 + 782 + static struct platform_driver lp8788_charger_driver = { 783 + .probe = lp8788_charger_probe, 784 + .remove = __devexit_p(lp8788_charger_remove), 785 + .driver = { 786 + .name = LP8788_DEV_CHARGER, 787 + .owner = THIS_MODULE, 788 + }, 789 + }; 790 + module_platform_driver(lp8788_charger_driver); 791 + 792 + MODULE_DESCRIPTION("TI LP8788 Charger Driver"); 793 + MODULE_AUTHOR("Milo Kim"); 794 + MODULE_LICENSE("GPL"); 795 + MODULE_ALIAS("platform:lp8788-charger");
+6 -7
drivers/power/pda_power.c
··· 281 281 goto init_failed; 282 282 } 283 283 284 + ac_draw = regulator_get(dev, "ac_draw"); 285 + if (IS_ERR(ac_draw)) { 286 + dev_dbg(dev, "couldn't get ac_draw regulator\n"); 287 + ac_draw = NULL; 288 + } 289 + 284 290 update_status(); 285 291 update_charger(); 286 292 ··· 313 307 pda_psy_ac.num_supplicants = pdata->num_supplicants; 314 308 pda_psy_usb.supplied_to = pdata->supplied_to; 315 309 pda_psy_usb.num_supplicants = pdata->num_supplicants; 316 - } 317 - 318 - ac_draw = regulator_get(dev, "ac_draw"); 319 - if (IS_ERR(ac_draw)) { 320 - dev_dbg(dev, "couldn't get ac_draw regulator\n"); 321 - ac_draw = NULL; 322 - ret = PTR_ERR(ac_draw); 323 310 } 324 311 325 312 #ifdef CONFIG_USB_OTG_UTILS
+3
drivers/power/power_supply_sysfs.c
··· 138 138 POWER_SUPPLY_ATTR(health), 139 139 POWER_SUPPLY_ATTR(present), 140 140 POWER_SUPPLY_ATTR(online), 141 + POWER_SUPPLY_ATTR(authentic), 141 142 POWER_SUPPLY_ATTR(technology), 142 143 POWER_SUPPLY_ATTR(cycle_count), 143 144 POWER_SUPPLY_ATTR(voltage_max), ··· 161 160 POWER_SUPPLY_ATTR(charge_avg), 162 161 POWER_SUPPLY_ATTR(charge_counter), 163 162 POWER_SUPPLY_ATTR(constant_charge_current), 163 + POWER_SUPPLY_ATTR(constant_charge_current_max), 164 164 POWER_SUPPLY_ATTR(constant_charge_voltage), 165 + POWER_SUPPLY_ATTR(constant_charge_voltage_max), 165 166 POWER_SUPPLY_ATTR(energy_full_design), 166 167 POWER_SUPPLY_ATTR(energy_empty_design), 167 168 POWER_SUPPLY_ATTR(energy_full),
+10
drivers/power/sbs-battery.c
··· 759 759 chip->irq = irq; 760 760 761 761 skip_gpio: 762 + /* 763 + * Before we register, we need to make sure we can actually talk 764 + * to the battery. 765 + */ 766 + rc = sbs_read_word_data(client, sbs_data[REG_STATUS].addr); 767 + if (rc < 0) { 768 + dev_err(&client->dev, "%s: Failed to get device status\n", 769 + __func__); 770 + goto exit_psupply; 771 + } 762 772 763 773 rc = power_supply_register(&client->dev, &chip->power_supply); 764 774 if (rc) {
+82 -15
drivers/power/smb347-charger.c
··· 80 80 #define CFG_FAULT_IRQ_DCIN_UV BIT(2) 81 81 #define CFG_STATUS_IRQ 0x0d 82 82 #define CFG_STATUS_IRQ_TERMINATION_OR_TAPER BIT(4) 83 + #define CFG_STATUS_IRQ_CHARGE_TIMEOUT BIT(7) 83 84 #define CFG_ADDRESS 0x0e 84 85 85 86 /* Command registers */ ··· 97 96 #define IRQSTAT_C_TERMINATION_STAT BIT(0) 98 97 #define IRQSTAT_C_TERMINATION_IRQ BIT(1) 99 98 #define IRQSTAT_C_TAPER_IRQ BIT(3) 99 + #define IRQSTAT_D 0x38 100 + #define IRQSTAT_D_CHARGE_TIMEOUT_STAT BIT(2) 101 + #define IRQSTAT_D_CHARGE_TIMEOUT_IRQ BIT(3) 100 102 #define IRQSTAT_E 0x39 101 103 #define IRQSTAT_E_USBIN_UV_STAT BIT(0) 102 104 #define IRQSTAT_E_USBIN_UV_IRQ BIT(1) ··· 113 109 #define STAT_B 0x3c 114 110 #define STAT_C 0x3d 115 111 #define STAT_C_CHG_ENABLED BIT(0) 112 + #define STAT_C_HOLDOFF_STAT BIT(3) 116 113 #define STAT_C_CHG_MASK 0x06 117 114 #define STAT_C_CHG_SHIFT 1 115 + #define STAT_C_CHG_TERM BIT(5) 118 116 #define STAT_C_CHARGER_ERROR BIT(6) 119 117 #define STAT_E 0x3f 120 118 ··· 707 701 static irqreturn_t smb347_interrupt(int irq, void *data) 708 702 { 709 703 struct smb347_charger *smb = data; 710 - unsigned int stat_c, irqstat_e, irqstat_c; 704 + unsigned int stat_c, irqstat_c, irqstat_d, irqstat_e; 711 705 bool handled = false; 712 706 int ret; 713 707 ··· 723 717 return IRQ_NONE; 724 718 } 725 719 720 + ret = regmap_read(smb->regmap, IRQSTAT_D, &irqstat_d); 721 + if (ret < 0) { 722 + dev_warn(smb->dev, "reading IRQSTAT_D failed\n"); 723 + return IRQ_NONE; 724 + } 725 + 726 726 ret = regmap_read(smb->regmap, IRQSTAT_E, &irqstat_e); 727 727 if (ret < 0) { 728 728 dev_warn(smb->dev, "reading IRQSTAT_E failed\n"); ··· 736 724 } 737 725 738 726 /* 739 - * If we get charger error we report the error back to user and 740 - * disable charging. 727 + * If we get charger error we report the error back to user. 728 + * If the error is recovered charging will resume again. 741 729 */ 742 730 if (stat_c & STAT_C_CHARGER_ERROR) { 743 - dev_err(smb->dev, "error in charger, disabling charging\n"); 744 - 745 - smb347_charging_disable(smb); 731 + dev_err(smb->dev, "charging stopped due to charger error\n"); 746 732 power_supply_changed(&smb->battery); 747 733 handled = true; 748 734 } ··· 753 743 if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { 754 744 if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) 755 745 power_supply_changed(&smb->battery); 746 + dev_dbg(smb->dev, "going to HW maintenance mode\n"); 747 + handled = true; 748 + } 749 + 750 + /* 751 + * If we got a charger timeout INT that means the charge 752 + * full is not detected with in charge timeout value. 753 + */ 754 + if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_IRQ) { 755 + dev_dbg(smb->dev, "total Charge Timeout INT received\n"); 756 + 757 + if (irqstat_d & IRQSTAT_D_CHARGE_TIMEOUT_STAT) 758 + dev_warn(smb->dev, "charging stopped due to timeout\n"); 759 + power_supply_changed(&smb->battery); 756 760 handled = true; 757 761 } 758 762 ··· 800 776 * Enable/disable interrupts for: 801 777 * - under voltage 802 778 * - termination current reached 779 + * - charger timeout 803 780 * - charger error 804 781 */ 805 782 ret = regmap_update_bits(smb->regmap, CFG_FAULT_IRQ, 0xff, ··· 809 784 goto fail; 810 785 811 786 ret = regmap_update_bits(smb->regmap, CFG_STATUS_IRQ, 0xff, 812 - enable ? CFG_STATUS_IRQ_TERMINATION_OR_TAPER : 0); 787 + enable ? (CFG_STATUS_IRQ_TERMINATION_OR_TAPER | 788 + CFG_STATUS_IRQ_CHARGE_TIMEOUT) : 0); 813 789 if (ret < 0) 814 790 goto fail; 815 791 ··· 1014 988 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 1015 989 }; 1016 990 991 + static int smb347_get_charging_status(struct smb347_charger *smb) 992 + { 993 + int ret, status; 994 + unsigned int val; 995 + 996 + if (!smb347_is_ps_online(smb)) 997 + return POWER_SUPPLY_STATUS_DISCHARGING; 998 + 999 + ret = regmap_read(smb->regmap, STAT_C, &val); 1000 + if (ret < 0) 1001 + return ret; 1002 + 1003 + if ((val & STAT_C_CHARGER_ERROR) || 1004 + (val & STAT_C_HOLDOFF_STAT)) { 1005 + /* 1006 + * set to NOT CHARGING upon charger error 1007 + * or charging has stopped. 1008 + */ 1009 + status = POWER_SUPPLY_STATUS_NOT_CHARGING; 1010 + } else { 1011 + if ((val & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT) { 1012 + /* 1013 + * set to charging if battery is in pre-charge, 1014 + * fast charge or taper charging mode. 1015 + */ 1016 + status = POWER_SUPPLY_STATUS_CHARGING; 1017 + } else if (val & STAT_C_CHG_TERM) { 1018 + /* 1019 + * set the status to FULL if battery is not in pre 1020 + * charge, fast charge or taper charging mode AND 1021 + * charging is terminated at least once. 1022 + */ 1023 + status = POWER_SUPPLY_STATUS_FULL; 1024 + } else { 1025 + /* 1026 + * in this case no charger error or termination 1027 + * occured but charging is not in progress!!! 1028 + */ 1029 + status = POWER_SUPPLY_STATUS_NOT_CHARGING; 1030 + } 1031 + } 1032 + 1033 + return status; 1034 + } 1035 + 1017 1036 static int smb347_battery_get_property(struct power_supply *psy, 1018 1037 enum power_supply_property prop, 1019 1038 union power_supply_propval *val) ··· 1074 1003 1075 1004 switch (prop) { 1076 1005 case POWER_SUPPLY_PROP_STATUS: 1077 - if (!smb347_is_ps_online(smb)) { 1078 - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 1079 - break; 1080 - } 1081 - if (smb347_charging_status(smb)) 1082 - val->intval = POWER_SUPPLY_STATUS_CHARGING; 1083 - else 1084 - val->intval = POWER_SUPPLY_STATUS_FULL; 1006 + ret = smb347_get_charging_status(smb); 1007 + if (ret < 0) 1008 + return ret; 1009 + val->intval = ret; 1085 1010 break; 1086 1011 1087 1012 case POWER_SUPPLY_PROP_CHARGE_TYPE:
+13 -12
drivers/power/twl4030_charger.c
··· 41 41 #define TWL4030_STS_VBUS BIT(7) 42 42 #define TWL4030_STS_USB_ID BIT(2) 43 43 #define TWL4030_BBCHEN BIT(4) 44 - #define TWL4030_BBSEL_MASK 0b1100 45 - #define TWL4030_BBSEL_2V5 0b0000 46 - #define TWL4030_BBSEL_3V0 0b0100 47 - #define TWL4030_BBSEL_3V1 0b1000 48 - #define TWL4030_BBSEL_3V2 0b1100 49 - #define TWL4030_BBISEL_MASK 0b11 50 - #define TWL4030_BBISEL_25uA 0b00 51 - #define TWL4030_BBISEL_150uA 0b01 52 - #define TWL4030_BBISEL_500uA 0b10 53 - #define TWL4030_BBISEL_1000uA 0b11 44 + #define TWL4030_BBSEL_MASK 0x0c 45 + #define TWL4030_BBSEL_2V5 0x00 46 + #define TWL4030_BBSEL_3V0 0x04 47 + #define TWL4030_BBSEL_3V1 0x08 48 + #define TWL4030_BBSEL_3V2 0x0c 49 + #define TWL4030_BBISEL_MASK 0x03 50 + #define TWL4030_BBISEL_25uA 0x00 51 + #define TWL4030_BBISEL_150uA 0x01 52 + #define TWL4030_BBISEL_500uA 0x02 53 + #define TWL4030_BBISEL_1000uA 0x03 54 54 55 55 /* BCI interrupts */ 56 56 #define TWL4030_WOVF BIT(0) /* Watchdog overflow */ ··· 534 534 } 535 535 536 536 ret = request_threaded_irq(bci->irq_chg, NULL, 537 - twl4030_charger_interrupt, 0, pdev->name, bci); 537 + twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name, 538 + bci); 538 539 if (ret < 0) { 539 540 dev_err(&pdev->dev, "could not request irq %d, status %d\n", 540 541 bci->irq_chg, ret); ··· 543 542 } 544 543 545 544 ret = request_threaded_irq(bci->irq_bci, NULL, 546 - twl4030_bci_interrupt, 0, pdev->name, bci); 545 + twl4030_bci_interrupt, IRQF_ONESHOT, pdev->name, bci); 547 546 if (ret < 0) { 548 547 dev_err(&pdev->dev, "could not request irq %d, status %d\n", 549 548 bci->irq_bci, ret);
+3 -1
drivers/power/wm97xx_battery.c
··· 212 212 props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ 213 213 214 214 prop = kzalloc(props * sizeof(*prop), GFP_KERNEL); 215 - if (!prop) 215 + if (!prop) { 216 + ret = -ENOMEM; 216 217 goto err3; 218 + } 217 219 218 220 prop[i++] = POWER_SUPPLY_PROP_PRESENT; 219 221 if (pdata->charge_gpio >= 0)
+83 -1
include/linux/mfd/88pm860x.h
··· 39 39 #define PM8606_DCM_BOOST (0x00) 40 40 #define PM8606_PWM (0x01) 41 41 42 + #define PM8607_MISC2 (0x42) 43 + 44 + /* Power Up Log Register */ 45 + #define PM8607_POWER_UP_LOG (0x3F) 46 + 47 + /* Charger Control Registers */ 48 + #define PM8607_CCNT (0x47) 49 + #define PM8607_CHG_CTRL1 (0x48) 50 + #define PM8607_CHG_CTRL2 (0x49) 51 + #define PM8607_CHG_CTRL3 (0x4A) 52 + #define PM8607_CHG_CTRL4 (0x4B) 53 + #define PM8607_CHG_CTRL5 (0x4C) 54 + #define PM8607_CHG_CTRL6 (0x4D) 55 + #define PM8607_CHG_CTRL7 (0x4E) 56 + 42 57 /* Backlight Registers */ 43 58 #define PM8606_WLED1A (0x02) 44 59 #define PM8606_WLED1B (0x03) ··· 203 188 #define PM8607_TSI_PREBIAS (0x55) /* prebias time */ 204 189 #define PM8607_PD_PREBIAS (0x56) /* prebias time */ 205 190 #define PM8607_GPADC_MISC1 (0x57) 191 + 192 + /* bit definitions of MEAS_EN1*/ 193 + #define PM8607_MEAS_EN1_VBAT (1 << 0) 194 + #define PM8607_MEAS_EN1_VCHG (1 << 1) 195 + #define PM8607_MEAS_EN1_VSYS (1 << 2) 196 + #define PM8607_MEAS_EN1_TINT (1 << 3) 197 + #define PM8607_MEAS_EN1_RFTMP (1 << 4) 198 + #define PM8607_MEAS_EN1_TBAT (1 << 5) 199 + #define PM8607_MEAS_EN1_GPADC2 (1 << 6) 200 + #define PM8607_MEAS_EN1_GPADC3 (1 << 7) 201 + 202 + /* Battery Monitor Registers */ 203 + #define PM8607_GP_BIAS2 (0x5A) 204 + #define PM8607_VBAT_LOWTH (0x5B) 205 + #define PM8607_VCHG_LOWTH (0x5C) 206 + #define PM8607_VSYS_LOWTH (0x5D) 207 + #define PM8607_TINT_LOWTH (0x5E) 208 + #define PM8607_GPADC0_LOWTH (0x5F) 209 + #define PM8607_GPADC1_LOWTH (0x60) 210 + #define PM8607_GPADC2_LOWTH (0x61) 211 + #define PM8607_GPADC3_LOWTH (0x62) 212 + #define PM8607_VBAT_HIGHTH (0x63) 213 + #define PM8607_VCHG_HIGHTH (0x64) 214 + #define PM8607_VSYS_HIGHTH (0x65) 215 + #define PM8607_TINT_HIGHTH (0x66) 216 + #define PM8607_GPADC0_HIGHTH (0x67) 217 + #define PM8607_GPADC1_HIGHTH (0x68) 218 + #define PM8607_GPADC2_HIGHTH (0x69) 219 + #define PM8607_GPADC3_HIGHTH (0x6A) 220 + #define PM8607_IBAT_MEAS1 (0x6B) 221 + #define PM8607_IBAT_MEAS2 (0x6C) 222 + #define PM8607_VBAT_MEAS1 (0x6D) 223 + #define PM8607_VBAT_MEAS2 (0x6E) 224 + #define PM8607_VCHG_MEAS1 (0x6F) 225 + #define PM8607_VCHG_MEAS2 (0x70) 226 + #define PM8607_VSYS_MEAS1 (0x71) 227 + #define PM8607_VSYS_MEAS2 (0x72) 228 + #define PM8607_TINT_MEAS1 (0x73) 229 + #define PM8607_TINT_MEAS2 (0x74) 230 + #define PM8607_GPADC0_MEAS1 (0x75) 231 + #define PM8607_GPADC0_MEAS2 (0x76) 232 + #define PM8607_GPADC1_MEAS1 (0x77) 233 + #define PM8607_GPADC1_MEAS2 (0x78) 234 + #define PM8607_GPADC2_MEAS1 (0x79) 235 + #define PM8607_GPADC2_MEAS2 (0x7A) 236 + #define PM8607_GPADC3_MEAS1 (0x7B) 237 + #define PM8607_GPADC3_MEAS2 (0x7C) 238 + #define PM8607_CCNT_MEAS1 (0x95) 239 + #define PM8607_CCNT_MEAS2 (0x96) 240 + #define PM8607_VBAT_AVG (0x97) 241 + #define PM8607_VCHG_AVG (0x98) 242 + #define PM8607_VSYS_AVG (0x99) 243 + #define PM8607_VBAT_MIN (0x9A) 244 + #define PM8607_VCHG_MIN (0x9B) 245 + #define PM8607_VSYS_MIN (0x9C) 246 + #define PM8607_VBAT_MAX (0x9D) 247 + #define PM8607_VCHG_MAX (0x9E) 248 + #define PM8607_VSYS_MAX (0x9F) 249 + 250 + #define PM8607_GPADC_MISC2 (0x59) 251 + #define PM8607_GPADC0_GP_BIAS_A0 (1 << 0) 252 + #define PM8607_GPADC1_GP_BIAS_A1 (1 << 1) 253 + #define PM8607_GPADC2_GP_BIAS_A2 (1 << 2) 254 + #define PM8607_GPADC3_GP_BIAS_A3 (1 << 3) 255 + #define PM8607_GPADC2_GP_BIAS_OUT2 (1 << 6) 206 256 207 257 /* RTC Control Registers */ 208 258 #define PM8607_RTC1 (0xA0) ··· 430 350 }; 431 351 432 352 struct pm860x_power_pdata { 433 - unsigned fast_charge; /* charge current */ 353 + int max_capacity; 354 + int resistor; 434 355 }; 435 356 436 357 struct pm860x_platform_data { ··· 456 375 struct regulator_init_data *ldo12; 457 376 struct regulator_init_data *ldo_vibrator; 458 377 struct regulator_init_data *ldo14; 378 + struct charger_desc *chg_desc; 459 379 460 380 int companion_addr; /* I2C address of companion chip */ 461 381 int i2c_port; /* Controlled by GI2C or PI2C */
+27 -24
include/linux/platform_data/lp8727.h
··· 13 13 #define _LP8727_H 14 14 15 15 enum lp8727_eoc_level { 16 - EOC_5P, 17 - EOC_10P, 18 - EOC_16P, 19 - EOC_20P, 20 - EOC_25P, 21 - EOC_33P, 22 - EOC_50P, 16 + LP8727_EOC_5P, 17 + LP8727_EOC_10P, 18 + LP8727_EOC_16P, 19 + LP8727_EOC_20P, 20 + LP8727_EOC_25P, 21 + LP8727_EOC_33P, 22 + LP8727_EOC_50P, 23 23 }; 24 24 25 25 enum lp8727_ichg { 26 - ICHG_90mA, 27 - ICHG_100mA, 28 - ICHG_400mA, 29 - ICHG_450mA, 30 - ICHG_500mA, 31 - ICHG_600mA, 32 - ICHG_700mA, 33 - ICHG_800mA, 34 - ICHG_900mA, 35 - ICHG_1000mA, 26 + LP8727_ICHG_90mA, 27 + LP8727_ICHG_100mA, 28 + LP8727_ICHG_400mA, 29 + LP8727_ICHG_450mA, 30 + LP8727_ICHG_500mA, 31 + LP8727_ICHG_600mA, 32 + LP8727_ICHG_700mA, 33 + LP8727_ICHG_800mA, 34 + LP8727_ICHG_900mA, 35 + LP8727_ICHG_1000mA, 36 36 }; 37 37 38 38 /** 39 39 * struct lp8727_chg_param 40 40 * @eoc_level : end of charge level setting 41 - * @ichg : charging current 41 + * @ichg : charging current 42 42 */ 43 43 struct lp8727_chg_param { 44 44 enum lp8727_eoc_level eoc_level; ··· 47 47 48 48 /** 49 49 * struct lp8727_platform_data 50 - * @get_batt_present : check battery status - exists or not 51 - * @get_batt_level : get battery voltage (mV) 50 + * @get_batt_present : check battery status - exists or not 51 + * @get_batt_level : get battery voltage (mV) 52 52 * @get_batt_capacity : get battery capacity (%) 53 - * @get_batt_temp : get battery temperature 54 - * @ac, @usb : charging parameters each charger type 53 + * @get_batt_temp : get battery temperature 54 + * @ac : charging parameters for AC type charger 55 + * @usb : charging parameters for USB type charger 56 + * @debounce_msec : interrupt debounce time 55 57 */ 56 58 struct lp8727_platform_data { 57 59 u8 (*get_batt_present)(void); 58 60 u16 (*get_batt_level)(void); 59 61 u8 (*get_batt_capacity)(void); 60 62 u8 (*get_batt_temp)(void); 61 - struct lp8727_chg_param ac; 62 - struct lp8727_chg_param usb; 63 + struct lp8727_chg_param *ac; 64 + struct lp8727_chg_param *usb; 65 + unsigned int debounce_msec; 63 66 }; 64 67 65 68 #endif
+42 -5
include/linux/power/charger-manager.h
··· 109 109 * struct charger_regulator 110 110 * @regulator_name: the name of regulator for using charger. 111 111 * @consumer: the regulator consumer for the charger. 112 + * @externally_control: 113 + * Set if the charger-manager cannot control charger, 114 + * the charger will be maintained with disabled state. 112 115 * @cables: 113 116 * the array of charger cables to enable/disable charger 114 117 * and set current limit according to constratint data of 115 118 * struct charger_cable if only charger cable included 116 119 * in the array of charger cables is attached/detached. 117 120 * @num_cables: the number of charger cables. 121 + * @attr_g: Attribute group for the charger(regulator) 122 + * @attr_name: "name" sysfs entry 123 + * @attr_state: "state" sysfs entry 124 + * @attr_externally_control: "externally_control" sysfs entry 125 + * @attrs: Arrays pointing to attr_name/state/externally_control for attr_g 118 126 */ 119 127 struct charger_regulator { 120 128 /* The name of regulator for charging */ 121 129 const char *regulator_name; 122 130 struct regulator *consumer; 131 + 132 + /* charger never on when system is on */ 133 + int externally_control; 123 134 124 135 /* 125 136 * Store constraint information related to current limit, ··· 138 127 */ 139 128 struct charger_cable *cables; 140 129 int num_cables; 130 + 131 + struct attribute_group attr_g; 132 + struct device_attribute attr_name; 133 + struct device_attribute attr_state; 134 + struct device_attribute attr_externally_control; 135 + struct attribute *attrs[4]; 136 + 137 + struct charger_manager *cm; 141 138 }; 142 139 143 140 /** ··· 159 140 * If it has dropped more than fullbatt_vchkdrop_uV after 160 141 * fullbatt_vchkdrop_ms, CM will restart charging. 161 142 * @fullbatt_uV: voltage in microvolt 162 - * If it is not being charged and VBATT >= fullbatt_uV, 143 + * If VBATT >= fullbatt_uV, it is assumed to be full. 144 + * @fullbatt_soc: state of Charge in % 145 + * If state of Charge >= fullbatt_soc, it is assumed to be full. 146 + * @fullbatt_full_capacity: full capacity measure 147 + * If full capacity of battery >= fullbatt_full_capacity, 163 148 * it is assumed to be full. 164 149 * @polling_interval_ms: interval in millisecond at which 165 150 * charger manager will monitor battery health ··· 171 148 * Specify where information for existance of battery can be obtained 172 149 * @psy_charger_stat: the names of power-supply for chargers 173 150 * @num_charger_regulator: the number of entries in charger_regulators 174 - * @charger_regulators: array of regulator_bulk_data for chargers 151 + * @charger_regulators: array of charger regulators 175 152 * @psy_fuel_gauge: the name of power-supply for fuel gauge 176 153 * @temperature_out_of_range: 177 154 * Determine whether the status is overheat or cold or normal. ··· 181 158 * @measure_battery_temp: 182 159 * true: measure battery temperature 183 160 * false: measure ambient temperature 161 + * @charging_max_duration_ms: Maximum possible duration for charging 162 + * If whole charging duration exceed 'charging_max_duration_ms', 163 + * cm stop charging. 164 + * @discharging_max_duration_ms: 165 + * Maximum possible duration for discharging with charger cable 166 + * after full-batt. If discharging duration exceed 'discharging 167 + * max_duration_ms', cm start charging. 184 168 */ 185 169 struct charger_desc { 186 170 char *psy_name; ··· 198 168 unsigned int fullbatt_vchkdrop_ms; 199 169 unsigned int fullbatt_vchkdrop_uV; 200 170 unsigned int fullbatt_uV; 171 + unsigned int fullbatt_soc; 172 + unsigned int fullbatt_full_capacity; 201 173 202 174 enum data_source battery_present; 203 175 ··· 212 180 213 181 int (*temperature_out_of_range)(int *mC); 214 182 bool measure_battery_temp; 183 + 184 + u64 charging_max_duration_ms; 185 + u64 discharging_max_duration_ms; 215 186 }; 216 187 217 188 #define PSY_NAME_MAX 30 ··· 229 194 * @charger_enabled: the state of charger 230 195 * @fullbatt_vchk_jiffies_at: 231 196 * jiffies at the time full battery check will occur. 232 - * @fullbatt_vchk_uV: voltage in microvolt 233 - * criteria for full battery 234 197 * @fullbatt_vchk_work: work queue for full battery check 235 198 * @emergency_stop: 236 199 * When setting true, stop charging ··· 239 206 * saved status of external power before entering suspend-to-RAM 240 207 * @status_save_batt: 241 208 * saved status of battery before entering suspend-to-RAM 209 + * @charging_start_time: saved start time of enabling charging 210 + * @charging_end_time: saved end time of disabling charging 242 211 */ 243 212 struct charger_manager { 244 213 struct list_head entry; ··· 253 218 bool charger_enabled; 254 219 255 220 unsigned long fullbatt_vchk_jiffies_at; 256 - unsigned int fullbatt_vchk_uV; 257 221 struct delayed_work fullbatt_vchk_work; 258 222 259 223 int emergency_stop; ··· 263 229 264 230 bool status_save_ext_pwr_inserted; 265 231 bool status_save_batt; 232 + 233 + u64 charging_start_time; 234 + u64 charging_end_time; 266 235 }; 267 236 268 237 #ifdef CONFIG_CHARGER_MANAGER
+5
include/linux/power_supply.h
··· 88 88 POWER_SUPPLY_PROP_HEALTH, 89 89 POWER_SUPPLY_PROP_PRESENT, 90 90 POWER_SUPPLY_PROP_ONLINE, 91 + POWER_SUPPLY_PROP_AUTHENTIC, 91 92 POWER_SUPPLY_PROP_TECHNOLOGY, 92 93 POWER_SUPPLY_PROP_CYCLE_COUNT, 93 94 POWER_SUPPLY_PROP_VOLTAGE_MAX, ··· 111 110 POWER_SUPPLY_PROP_CHARGE_AVG, 112 111 POWER_SUPPLY_PROP_CHARGE_COUNTER, 113 112 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 113 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 114 114 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 115 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 115 116 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 116 117 POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN, 117 118 POWER_SUPPLY_PROP_ENERGY_FULL, ··· 251 248 case POWER_SUPPLY_PROP_CHARGE_AVG: 252 249 case POWER_SUPPLY_PROP_CHARGE_COUNTER: 253 250 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 251 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 254 252 case POWER_SUPPLY_PROP_CURRENT_MAX: 255 253 case POWER_SUPPLY_PROP_CURRENT_NOW: 256 254 case POWER_SUPPLY_PROP_CURRENT_AVG: ··· 280 276 case POWER_SUPPLY_PROP_VOLTAGE_AVG: 281 277 case POWER_SUPPLY_PROP_VOLTAGE_OCV: 282 278 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 279 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 283 280 case POWER_SUPPLY_PROP_POWER_NOW: 284 281 return 1; 285 282 default: