Commit 4b24ff71108164e047cf2c95990b77651163e315

Authored by Linus Torvalds

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

Pull battery updates from Anton Vorontsov:
 "The tag contains just a few battery-related changes for v3.6.  It's is
  all pretty straightforward, except one thing.

  One of our patches added thermal support for power supply class, but
  thermal/ subsystem changed under our feet.  We (well, Stephen, that
  is) caught the issue and it was decided[1] that I'd just delay the
  battery pull request, and then will fix it up by merging upstream back
  into battery tree at the specific commit.

  That's not all though: another[2] small fixup for thermal subsystem
  was needed to get rid of a warning in power supply subsystem (the
  warning was not drivers/power's "fault", the thermal registration
  function just needed a proper const annotation, which is also done by
  a small commit on top of the merge.

  So, to sum this up:
   - The 'master' branch of the battery tree was in the -next tree for
     weeks, was never rebased, altered etc.  It should be all OK;
   - Although, for-v3.6 tag contains the 'master' branch + merge + the
     warning fix.

  [1] http://lkml.org/lkml/2012/6/19/23
  [2] http://lkml.org/lkml/2012/6/18/28"

* tag 'for-v3.6' of git://git.infradead.org/battery-2.6: (23 commits)
  thermal: Constify 'type' argument for the registration routine
  olpc-battery: update CHARGE_FULL_DESIGN property for BYD LiFe batteries
  olpc-battery: Add VOLTAGE_MAX_DESIGN property
  charger-manager: Fix build break related to EXTCON
  lp8727_charger: Move header file into platform_data directory
  power_supply: Add min/max alert properties for CAPACITY, TEMP, TEMP_AMBIENT
  bq27x00_battery: Add support for BQ27425 chip
  charger-manager: Set current limit of regulator for over current protection
  charger-manager: Use EXTCON Subsystem to detect charger cables for charging
  test_power: Add VOLTAGE_NOW and BATTERY_TEMP properties
  test_power: Add support for USB AC source
  gpio-charger: Use cansleep version of gpio_set_value
  bq27x00_battery: Add support for power average and health properties
  sbs-battery: Don't trigger false supply_changed event
  twl4030_charger: Allow charger to control the regulator that feeds it
  twl4030_charger: Add backup-battery charging
  twl4030_charger: Fix some typos
  max17042_battery: Support CHARGE_COUNTER power supply attribute
  smb347-charger: Add constant charge and current properties
  power_supply: Add constant charge_current and charge_voltage properties
  ...

Showing 24 changed files Side-by-side Diff

Documentation/power/power_supply_class.txt
... ... @@ -112,14 +112,24 @@
112 112 be negative; there is no empty or full value. It is only useful for
113 113 relative, time-based measurements.
114 114  
  115 +CONSTANT_CHARGE_CURRENT - constant charge current programmed by charger.
  116 +
  117 +CONSTANT_CHARGE_VOLTAGE - constant charge voltage programmed by charger.
  118 +
115 119 ENERGY_FULL, ENERGY_EMPTY - same as above but for energy.
116 120  
117 121 CAPACITY - capacity in percents.
  122 +CAPACITY_ALERT_MIN - minimum capacity alert value in percents.
  123 +CAPACITY_ALERT_MAX - maximum capacity alert value in percents.
118 124 CAPACITY_LEVEL - capacity level. This corresponds to
119 125 POWER_SUPPLY_CAPACITY_LEVEL_*.
120 126  
121 127 TEMP - temperature of the power supply.
  128 +TEMP_ALERT_MIN - minimum battery temperature alert value in milli centigrade.
  129 +TEMP_ALERT_MAX - maximum battery temperature alert value in milli centigrade.
122 130 TEMP_AMBIENT - ambient temperature.
  131 +TEMP_AMBIENT_ALERT_MIN - minimum ambient temperature alert value in milli centigrade.
  132 +TEMP_AMBIENT_ALERT_MAX - maximum ambient temperature alert value in milli centigrade.
123 133  
124 134 TIME_TO_EMPTY - seconds left for battery to be considered empty (i.e.
125 135 while battery powers a load)
drivers/mfd/twl-core.c
... ... @@ -717,8 +717,9 @@
717 717 static struct regulator_consumer_supply usb1v8 = {
718 718 .supply = "usb1v8",
719 719 };
720   - static struct regulator_consumer_supply usb3v1 = {
721   - .supply = "usb3v1",
  720 + static struct regulator_consumer_supply usb3v1[] = {
  721 + { .supply = "usb3v1" },
  722 + { .supply = "bci3v1" },
722 723 };
723 724  
724 725 /* First add the regulators so that they can be used by transceiver */
... ... @@ -746,7 +747,7 @@
746 747 return PTR_ERR(child);
747 748  
748 749 child = add_regulator_linked(TWL4030_REG_VUSB3V1,
749   - &usb_fixed, &usb3v1, 1,
  750 + &usb_fixed, usb3v1, 2,
750 751 features);
751 752 if (IS_ERR(child))
752 753 return PTR_ERR(child);
... ... @@ -767,7 +768,7 @@
767 768 if (twl_has_regulator() && child) {
768 769 usb1v5.dev_name = dev_name(child);
769 770 usb1v8.dev_name = dev_name(child);
770   - usb3v1.dev_name = dev_name(child);
  771 + usb3v1[0].dev_name = dev_name(child);
771 772 }
772 773 }
773 774 if (twl_has_usb() && pdata->usb && twl_class_is_6030()) {
drivers/power/Kconfig
... ... @@ -268,6 +268,7 @@
268 268 config CHARGER_MANAGER
269 269 bool "Battery charger manager for multiple chargers"
270 270 depends on REGULATOR && RTC_CLASS
  271 + select EXTCON
271 272 help
272 273 Say Y to enable charger-manager support, which allows multiple
273 274 chargers attached to a battery and multiple batteries attached to a
drivers/power/bq27x00_battery.c
... ... @@ -22,6 +22,7 @@
22 22 * Datasheets:
23 23 * http://focus.ti.com/docs/prod/folders/print/bq27000.html
24 24 * http://focus.ti.com/docs/prod/folders/print/bq27500.html
  25 + * http://www.ti.com/product/bq27425-g1
25 26 */
26 27  
27 28 #include <linux/module.h>
... ... @@ -51,6 +52,7 @@
51 52 #define BQ27x00_REG_LMD 0x12 /* Last measured discharge */
52 53 #define BQ27x00_REG_CYCT 0x2A /* Cycle count total */
53 54 #define BQ27x00_REG_AE 0x22 /* Available energy */
  55 +#define BQ27x00_POWER_AVG 0x24
54 56  
55 57 #define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */
56 58 #define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */
57 59  
58 60  
59 61  
... ... @@ -66,15 +68,21 @@
66 68 #define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */
67 69 #define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */
68 70 #define BQ27500_FLAG_FC BIT(9)
  71 +#define BQ27500_FLAG_OTC BIT(15)
69 72  
  73 +/* bq27425 register addresses are same as bq27x00 addresses minus 4 */
  74 +#define BQ27425_REG_OFFSET 0x04
  75 +#define BQ27425_REG_SOC 0x18 /* Register address plus offset */
  76 +
70 77 #define BQ27000_RS 20 /* Resistor sense */
  78 +#define BQ27x00_POWER_CONSTANT (256 * 29200 / 1000)
71 79  
72 80 struct bq27x00_device_info;
73 81 struct bq27x00_access_methods {
74 82 int (*read)(struct bq27x00_device_info *di, u8 reg, bool single);
75 83 };
76 84  
77   -enum bq27x00_chip { BQ27000, BQ27500 };
  85 +enum bq27x00_chip { BQ27000, BQ27500, BQ27425};
78 86  
79 87 struct bq27x00_reg_cache {
80 88 int temperature;
... ... @@ -86,6 +94,8 @@
86 94 int capacity;
87 95 int energy;
88 96 int flags;
  97 + int power_avg;
  98 + int health;
89 99 };
90 100  
91 101 struct bq27x00_device_info {
92 102  
... ... @@ -123,8 +133,24 @@
123 133 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
124 134 POWER_SUPPLY_PROP_CYCLE_COUNT,
125 135 POWER_SUPPLY_PROP_ENERGY_NOW,
  136 + POWER_SUPPLY_PROP_POWER_AVG,
  137 + POWER_SUPPLY_PROP_HEALTH,
126 138 };
127 139  
  140 +static enum power_supply_property bq27425_battery_props[] = {
  141 + POWER_SUPPLY_PROP_STATUS,
  142 + POWER_SUPPLY_PROP_PRESENT,
  143 + POWER_SUPPLY_PROP_VOLTAGE_NOW,
  144 + POWER_SUPPLY_PROP_CURRENT_NOW,
  145 + POWER_SUPPLY_PROP_CAPACITY,
  146 + POWER_SUPPLY_PROP_CAPACITY_LEVEL,
  147 + POWER_SUPPLY_PROP_TEMP,
  148 + POWER_SUPPLY_PROP_TECHNOLOGY,
  149 + POWER_SUPPLY_PROP_CHARGE_FULL,
  150 + POWER_SUPPLY_PROP_CHARGE_NOW,
  151 + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
  152 +};
  153 +
128 154 static unsigned int poll_interval = 360;
129 155 module_param(poll_interval, uint, 0644);
130 156 MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \
131 157  
... ... @@ -137,10 +163,24 @@
137 163 static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg,
138 164 bool single)
139 165 {
  166 + if (di->chip == BQ27425)
  167 + return di->bus.read(di, reg - BQ27425_REG_OFFSET, single);
140 168 return di->bus.read(di, reg, single);
141 169 }
142 170  
143 171 /*
  172 + * Higher versions of the chip like BQ27425 and BQ27500
  173 + * differ from BQ27000 and BQ27200 in calculation of certain
  174 + * parameters. Hence we need to check for the chip type.
  175 + */
  176 +static bool bq27xxx_is_chip_version_higher(struct bq27x00_device_info *di)
  177 +{
  178 + if (di->chip == BQ27425 || di->chip == BQ27500)
  179 + return true;
  180 + return false;
  181 +}
  182 +
  183 +/*
144 184 * Return the battery Relative State-of-Charge
145 185 * Or < 0 if something fails.
146 186 */
... ... @@ -150,6 +190,8 @@
150 190  
151 191 if (di->chip == BQ27500)
152 192 rsoc = bq27x00_read(di, BQ27500_REG_SOC, false);
  193 + else if (di->chip == BQ27425)
  194 + rsoc = bq27x00_read(di, BQ27425_REG_SOC, false);
153 195 else
154 196 rsoc = bq27x00_read(di, BQ27000_REG_RSOC, true);
155 197  
... ... @@ -174,7 +216,7 @@
174 216 return charge;
175 217 }
176 218  
177   - if (di->chip == BQ27500)
  219 + if (bq27xxx_is_chip_version_higher(di))
178 220 charge *= 1000;
179 221 else
180 222 charge = charge * 3570 / BQ27000_RS;
... ... @@ -208,7 +250,7 @@
208 250 {
209 251 int ilmd;
210 252  
211   - if (di->chip == BQ27500)
  253 + if (bq27xxx_is_chip_version_higher(di))
212 254 ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false);
213 255 else
214 256 ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true);
... ... @@ -218,7 +260,7 @@
218 260 return ilmd;
219 261 }
220 262  
221   - if (di->chip == BQ27500)
  263 + if (bq27xxx_is_chip_version_higher(di))
222 264 ilmd *= 1000;
223 265 else
224 266 ilmd = ilmd * 256 * 3570 / BQ27000_RS;
... ... @@ -262,7 +304,7 @@
262 304 return temp;
263 305 }
264 306  
265   - if (di->chip == BQ27500)
  307 + if (bq27xxx_is_chip_version_higher(di))
266 308 temp -= 2731;
267 309 else
268 310 temp = ((temp * 5) - 5463) / 2;
269 311  
270 312  
... ... @@ -306,14 +348,70 @@
306 348 return tval * 60;
307 349 }
308 350  
  351 +/*
  352 + * Read a power avg register.
  353 + * Return < 0 if something fails.
  354 + */
  355 +static int bq27x00_battery_read_pwr_avg(struct bq27x00_device_info *di, u8 reg)
  356 +{
  357 + int tval;
  358 +
  359 + tval = bq27x00_read(di, reg, false);
  360 + if (tval < 0) {
  361 + dev_err(di->dev, "error reading power avg rgister %02x: %d\n",
  362 + reg, tval);
  363 + return tval;
  364 + }
  365 +
  366 + if (di->chip == BQ27500)
  367 + return tval;
  368 + else
  369 + return (tval * BQ27x00_POWER_CONSTANT) / BQ27000_RS;
  370 +}
  371 +
  372 +/*
  373 + * Read flag register.
  374 + * Return < 0 if something fails.
  375 + */
  376 +static int bq27x00_battery_read_health(struct bq27x00_device_info *di)
  377 +{
  378 + int tval;
  379 +
  380 + tval = bq27x00_read(di, BQ27x00_REG_FLAGS, false);
  381 + if (tval < 0) {
  382 + dev_err(di->dev, "error reading flag register:%d\n", tval);
  383 + return tval;
  384 + }
  385 +
  386 + if ((di->chip == BQ27500)) {
  387 + if (tval & BQ27500_FLAG_SOCF)
  388 + tval = POWER_SUPPLY_HEALTH_DEAD;
  389 + else if (tval & BQ27500_FLAG_OTC)
  390 + tval = POWER_SUPPLY_HEALTH_OVERHEAT;
  391 + else
  392 + tval = POWER_SUPPLY_HEALTH_GOOD;
  393 + return tval;
  394 + } else {
  395 + if (tval & BQ27000_FLAG_EDV1)
  396 + tval = POWER_SUPPLY_HEALTH_DEAD;
  397 + else
  398 + tval = POWER_SUPPLY_HEALTH_GOOD;
  399 + return tval;
  400 + }
  401 +
  402 + return -1;
  403 +}
  404 +
309 405 static void bq27x00_update(struct bq27x00_device_info *di)
310 406 {
311 407 struct bq27x00_reg_cache cache = {0, };
312 408 bool is_bq27500 = di->chip == BQ27500;
  409 + bool is_bq27425 = di->chip == BQ27425;
313 410  
314 411 cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
315 412 if (cache.flags >= 0) {
316   - if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) {
  413 + if (!is_bq27500 && !is_bq27425
  414 + && (cache.flags & BQ27000_FLAG_CI)) {
317 415 dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n");
318 416 cache.capacity = -ENODATA;
319 417 cache.energy = -ENODATA;
320 418  
321 419  
322 420  
323 421  
... ... @@ -321,16 +419,30 @@
321 419 cache.time_to_empty_avg = -ENODATA;
322 420 cache.time_to_full = -ENODATA;
323 421 cache.charge_full = -ENODATA;
  422 + cache.health = -ENODATA;
324 423 } else {
325 424 cache.capacity = bq27x00_battery_read_rsoc(di);
326   - cache.energy = bq27x00_battery_read_energy(di);
327   - cache.time_to_empty = bq27x00_battery_read_time(di, BQ27x00_REG_TTE);
328   - cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP);
329   - cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF);
  425 + if (!is_bq27425) {
  426 + cache.energy = bq27x00_battery_read_energy(di);
  427 + cache.time_to_empty =
  428 + bq27x00_battery_read_time(di,
  429 + BQ27x00_REG_TTE);
  430 + cache.time_to_empty_avg =
  431 + bq27x00_battery_read_time(di,
  432 + BQ27x00_REG_TTECP);
  433 + cache.time_to_full =
  434 + bq27x00_battery_read_time(di,
  435 + BQ27x00_REG_TTF);
  436 + }
330 437 cache.charge_full = bq27x00_battery_read_lmd(di);
  438 + cache.health = bq27x00_battery_read_health(di);
331 439 }
332 440 cache.temperature = bq27x00_battery_read_temperature(di);
  441 + if (!is_bq27425)
  442 + cache.cycle_count = bq27x00_battery_read_cyct(di);
333 443 cache.cycle_count = bq27x00_battery_read_cyct(di);
  444 + cache.power_avg =
  445 + bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG);
334 446  
335 447 /* We only have to read charge design full once */
336 448 if (di->charge_design_full <= 0)
... ... @@ -376,7 +488,7 @@
376 488 return curr;
377 489 }
378 490  
379   - if (di->chip == BQ27500) {
  491 + if (bq27xxx_is_chip_version_higher(di)) {
380 492 /* bq27500 returns signed value */
381 493 val->intval = (int)((s16)curr) * 1000;
382 494 } else {
... ... @@ -397,7 +509,7 @@
397 509 {
398 510 int status;
399 511  
400   - if (di->chip == BQ27500) {
  512 + if (bq27xxx_is_chip_version_higher(di)) {
401 513 if (di->cache.flags & BQ27500_FLAG_FC)
402 514 status = POWER_SUPPLY_STATUS_FULL;
403 515 else if (di->cache.flags & BQ27500_FLAG_DSC)
... ... @@ -425,7 +537,7 @@
425 537 {
426 538 int level;
427 539  
428   - if (di->chip == BQ27500) {
  540 + if (bq27xxx_is_chip_version_higher(di)) {
429 541 if (di->cache.flags & BQ27500_FLAG_FC)
430 542 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
431 543 else if (di->cache.flags & BQ27500_FLAG_SOC1)
... ... @@ -550,6 +662,12 @@
550 662 case POWER_SUPPLY_PROP_ENERGY_NOW:
551 663 ret = bq27x00_simple_value(di->cache.energy, val);
552 664 break;
  665 + case POWER_SUPPLY_PROP_POWER_AVG:
  666 + ret = bq27x00_simple_value(di->cache.power_avg, val);
  667 + break;
  668 + case POWER_SUPPLY_PROP_HEALTH:
  669 + ret = bq27x00_simple_value(di->cache.health, val);
  670 + break;
553 671 default:
554 672 return -EINVAL;
555 673 }
... ... @@ -570,8 +688,14 @@
570 688 int ret;
571 689  
572 690 di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
573   - di->bat.properties = bq27x00_battery_props;
574   - di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
  691 + di->chip = BQ27425;
  692 + if (di->chip == BQ27425) {
  693 + di->bat.properties = bq27425_battery_props;
  694 + di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props);
  695 + } else {
  696 + di->bat.properties = bq27x00_battery_props;
  697 + di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
  698 + }
575 699 di->bat.get_property = bq27x00_battery_get_property;
576 700 di->bat.external_power_changed = bq27x00_external_power_changed;
577 701  
... ... @@ -729,6 +853,7 @@
729 853 static const struct i2c_device_id bq27x00_id[] = {
730 854 { "bq27200", BQ27000 }, /* bq27200 is same as bq27000, but with i2c */
731 855 { "bq27500", BQ27500 },
  856 + { "bq27425", BQ27425 },
732 857 {},
733 858 };
734 859 MODULE_DEVICE_TABLE(i2c, bq27x00_id);
drivers/power/charger-manager.c
... ... @@ -271,16 +271,13 @@
271 271 if (enable) {
272 272 if (cm->emergency_stop)
273 273 return -EAGAIN;
274   - err = regulator_bulk_enable(desc->num_charger_regulators,
275   - desc->charger_regulators);
  274 + for (i = 0 ; i < desc->num_charger_regulators ; i++)
  275 + regulator_enable(desc->charger_regulators[i].consumer);
276 276 } else {
277 277 /*
278 278 * Abnormal battery state - Stop charging forcibly,
279 279 * even if charger was enabled at the other places
280 280 */
281   - err = regulator_bulk_disable(desc->num_charger_regulators,
282   - desc->charger_regulators);
283   -
284 281 for (i = 0; i < desc->num_charger_regulators; i++) {
285 282 if (regulator_is_enabled(
286 283 desc->charger_regulators[i].consumer)) {
... ... @@ -288,7 +285,7 @@
288 285 desc->charger_regulators[i].consumer);
289 286 dev_warn(cm->dev,
290 287 "Disable regulator(%s) forcibly.\n",
291   - desc->charger_regulators[i].supply);
  288 + desc->charger_regulators[i].regulator_name);
292 289 }
293 290 }
294 291 }
295 292  
... ... @@ -994,11 +991,92 @@
994 991 }
995 992 EXPORT_SYMBOL_GPL(setup_charger_manager);
996 993  
  994 +/**
  995 + * charger_extcon_work - enable/diable charger according to the state
  996 + * of charger cable
  997 + *
  998 + * @work: work_struct of the function charger_extcon_work.
  999 + */
  1000 +static void charger_extcon_work(struct work_struct *work)
  1001 +{
  1002 + struct charger_cable *cable =
  1003 + container_of(work, struct charger_cable, wq);
  1004 + int ret;
  1005 +
  1006 + if (cable->attached && cable->min_uA != 0 && cable->max_uA != 0) {
  1007 + ret = regulator_set_current_limit(cable->charger->consumer,
  1008 + cable->min_uA, cable->max_uA);
  1009 + if (ret < 0) {
  1010 + pr_err("Cannot set current limit of %s (%s)\n",
  1011 + cable->charger->regulator_name, cable->name);
  1012 + return;
  1013 + }
  1014 +
  1015 + pr_info("Set current limit of %s : %duA ~ %duA\n",
  1016 + cable->charger->regulator_name,
  1017 + cable->min_uA, cable->max_uA);
  1018 + }
  1019 +
  1020 + try_charger_enable(cable->cm, cable->attached);
  1021 +}
  1022 +
  1023 +/**
  1024 + * charger_extcon_notifier - receive the state of charger cable
  1025 + * when registered cable is attached or detached.
  1026 + *
  1027 + * @self: the notifier block of the charger_extcon_notifier.
  1028 + * @event: the cable state.
  1029 + * @ptr: the data pointer of notifier block.
  1030 + */
  1031 +static int charger_extcon_notifier(struct notifier_block *self,
  1032 + unsigned long event, void *ptr)
  1033 +{
  1034 + struct charger_cable *cable =
  1035 + container_of(self, struct charger_cable, nb);
  1036 +
  1037 + cable->attached = event;
  1038 + schedule_work(&cable->wq);
  1039 +
  1040 + return NOTIFY_DONE;
  1041 +}
  1042 +
  1043 +/**
  1044 + * charger_extcon_init - register external connector to use it
  1045 + * as the charger cable
  1046 + *
  1047 + * @cm: the Charger Manager representing the battery.
  1048 + * @cable: the Charger cable representing the external connector.
  1049 + */
  1050 +static int charger_extcon_init(struct charger_manager *cm,
  1051 + struct charger_cable *cable)
  1052 +{
  1053 + int ret = 0;
  1054 +
  1055 + /*
  1056 + * Charger manager use Extcon framework to identify
  1057 + * the charger cable among various external connector
  1058 + * cable (e.g., TA, USB, MHL, Dock).
  1059 + */
  1060 + INIT_WORK(&cable->wq, charger_extcon_work);
  1061 + cable->nb.notifier_call = charger_extcon_notifier;
  1062 + ret = extcon_register_interest(&cable->extcon_dev,
  1063 + cable->extcon_name, cable->name, &cable->nb);
  1064 + if (ret < 0) {
  1065 + pr_info("Cannot register extcon_dev for %s(cable: %s).\n",
  1066 + cable->extcon_name,
  1067 + cable->name);
  1068 + ret = -EINVAL;
  1069 + }
  1070 +
  1071 + return ret;
  1072 +}
  1073 +
997 1074 static int charger_manager_probe(struct platform_device *pdev)
998 1075 {
999 1076 struct charger_desc *desc = dev_get_platdata(&pdev->dev);
1000 1077 struct charger_manager *cm;
1001 1078 int ret = 0, i = 0;
  1079 + int j = 0;
1002 1080 union power_supply_propval val;
1003 1081  
1004 1082 if (g_desc && !rtc_dev && g_desc->rtc_name) {
... ... @@ -1167,11 +1245,31 @@
1167 1245 goto err_register;
1168 1246 }
1169 1247  
1170   - ret = regulator_bulk_get(&pdev->dev, desc->num_charger_regulators,
1171   - desc->charger_regulators);
1172   - if (ret) {
1173   - dev_err(&pdev->dev, "Cannot get charger regulators.\n");
1174   - goto err_bulk_get;
  1248 + for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  1249 + struct charger_regulator *charger
  1250 + = &desc->charger_regulators[i];
  1251 +
  1252 + charger->consumer = regulator_get(&pdev->dev,
  1253 + charger->regulator_name);
  1254 + if (charger->consumer == NULL) {
  1255 + dev_err(&pdev->dev, "Cannot find charger(%s)n",
  1256 + charger->regulator_name);
  1257 + ret = -EINVAL;
  1258 + goto err_chg_get;
  1259 + }
  1260 +
  1261 + for (j = 0 ; j < charger->num_cables ; j++) {
  1262 + struct charger_cable *cable = &charger->cables[j];
  1263 +
  1264 + ret = charger_extcon_init(cm, cable);
  1265 + if (ret < 0) {
  1266 + dev_err(&pdev->dev, "Cannot find charger(%s)n",
  1267 + charger->regulator_name);
  1268 + goto err_extcon;
  1269 + }
  1270 + cable->charger = charger;
  1271 + cable->cm = cm;
  1272 + }
1175 1273 }
1176 1274  
1177 1275 ret = try_charger_enable(cm, true);
... ... @@ -1197,9 +1295,19 @@
1197 1295 return 0;
1198 1296  
1199 1297 err_chg_enable:
1200   - regulator_bulk_free(desc->num_charger_regulators,
1201   - desc->charger_regulators);
1202   -err_bulk_get:
  1298 +err_extcon:
  1299 + for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  1300 + struct charger_regulator *charger
  1301 + = &desc->charger_regulators[i];
  1302 + for (j = 0 ; j < charger->num_cables ; j++) {
  1303 + struct charger_cable *cable = &charger->cables[j];
  1304 + extcon_unregister_interest(&cable->extcon_dev);
  1305 + }
  1306 + }
  1307 +err_chg_get:
  1308 + for (i = 0 ; i < desc->num_charger_regulators ; i++)
  1309 + regulator_put(desc->charger_regulators[i].consumer);
  1310 +
1203 1311 power_supply_unregister(&cm->charger_psy);
1204 1312 err_register:
1205 1313 kfree(cm->charger_psy.properties);
... ... @@ -1218,6 +1326,8 @@
1218 1326 {
1219 1327 struct charger_manager *cm = platform_get_drvdata(pdev);
1220 1328 struct charger_desc *desc = cm->desc;
  1329 + int i = 0;
  1330 + int j = 0;
1221 1331  
1222 1332 /* Remove from the list */
1223 1333 mutex_lock(&cm_list_mtx);
... ... @@ -1229,8 +1339,18 @@
1229 1339 if (delayed_work_pending(&cm_monitor_work))
1230 1340 cancel_delayed_work_sync(&cm_monitor_work);
1231 1341  
1232   - regulator_bulk_free(desc->num_charger_regulators,
1233   - desc->charger_regulators);
  1342 + for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  1343 + struct charger_regulator *charger
  1344 + = &desc->charger_regulators[i];
  1345 + for (j = 0 ; j < charger->num_cables ; j++) {
  1346 + struct charger_cable *cable = &charger->cables[j];
  1347 + extcon_unregister_interest(&cable->extcon_dev);
  1348 + }
  1349 + }
  1350 +
  1351 + for (i = 0 ; i < desc->num_charger_regulators ; i++)
  1352 + regulator_put(desc->charger_regulators[i].consumer);
  1353 +
1234 1354 power_supply_unregister(&cm->charger_psy);
1235 1355  
1236 1356 try_charger_enable(cm, false);
drivers/power/ds2781_battery.c
... ... @@ -64,7 +64,7 @@
64 64 return w1_ds2781_io(dev_info->w1_dev, buf, addr, count, io);
65 65 }
66 66  
67   -int w1_ds2781_read(struct ds2781_device_info *dev_info, char *buf,
  67 +static int w1_ds2781_read(struct ds2781_device_info *dev_info, char *buf,
68 68 int addr, size_t count)
69 69 {
70 70 return ds2781_battery_io(dev_info, buf, addr, count, 0);
drivers/power/gpio-charger.c
... ... @@ -54,7 +54,7 @@
54 54  
55 55 switch (psp) {
56 56 case POWER_SUPPLY_PROP_ONLINE:
57   - val->intval = gpio_get_value(pdata->gpio);
  57 + val->intval = gpio_get_value_cansleep(pdata->gpio);
58 58 val->intval ^= pdata->gpio_active_low;
59 59 break;
60 60 default:
drivers/power/lp8727_charger.c
... ... @@ -15,7 +15,7 @@
15 15 #include <linux/interrupt.h>
16 16 #include <linux/i2c.h>
17 17 #include <linux/power_supply.h>
18   -#include <linux/lp8727.h>
  18 +#include <linux/platform_data/lp8727.h>
19 19  
20 20 #define DEBOUNCE_MSEC 270
21 21  
drivers/power/max17042_battery.c
... ... @@ -113,6 +113,7 @@
113 113 POWER_SUPPLY_PROP_VOLTAGE_OCV,
114 114 POWER_SUPPLY_PROP_CAPACITY,
115 115 POWER_SUPPLY_PROP_CHARGE_FULL,
  116 + POWER_SUPPLY_PROP_CHARGE_COUNTER,
116 117 POWER_SUPPLY_PROP_TEMP,
117 118 POWER_SUPPLY_PROP_CURRENT_NOW,
118 119 POWER_SUPPLY_PROP_CURRENT_AVG,
... ... @@ -196,6 +197,13 @@
196 197 break;
197 198 case POWER_SUPPLY_PROP_CHARGE_FULL:
198 199 ret = max17042_read_reg(chip->client, MAX17042_FullCAP);
  200 + if (ret < 0)
  201 + return ret;
  202 +
  203 + val->intval = ret * 1000 / 2;
  204 + break;
  205 + case POWER_SUPPLY_PROP_CHARGE_COUNTER:
  206 + ret = max17042_read_reg(chip->client, MAX17042_QH);
199 207 if (ret < 0)
200 208 return ret;
201 209  
drivers/power/olpc_battery.c
... ... @@ -231,12 +231,10 @@
231 231  
232 232 case POWER_SUPPLY_TECHNOLOGY_LiFe:
233 233 switch (mfr) {
234   - case 1: /* Gold Peak */
  234 + case 1: /* Gold Peak, fall through */
  235 + case 2: /* BYD */
235 236 val->intval = 2800000;
236 237 break;
237   - case 2: /* BYD */
238   - val->intval = 3100000;
239   - break;
240 238 default:
241 239 return -EIO;
242 240 }
... ... @@ -267,6 +265,55 @@
267 265 return 0;
268 266 }
269 267  
  268 +static int olpc_bat_get_voltage_max_design(union power_supply_propval *val)
  269 +{
  270 + uint8_t ec_byte;
  271 + union power_supply_propval tech;
  272 + int mfr;
  273 + int ret;
  274 +
  275 + ret = olpc_bat_get_tech(&tech);
  276 + if (ret)
  277 + return ret;
  278 +
  279 + ec_byte = BAT_ADDR_MFR_TYPE;
  280 + ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &ec_byte, 1);
  281 + if (ret)
  282 + return ret;
  283 +
  284 + mfr = ec_byte >> 4;
  285 +
  286 + switch (tech.intval) {
  287 + case POWER_SUPPLY_TECHNOLOGY_NiMH:
  288 + switch (mfr) {
  289 + case 1: /* Gold Peak */
  290 + val->intval = 6000000;
  291 + break;
  292 + default:
  293 + return -EIO;
  294 + }
  295 + break;
  296 +
  297 + case POWER_SUPPLY_TECHNOLOGY_LiFe:
  298 + switch (mfr) {
  299 + case 1: /* Gold Peak */
  300 + val->intval = 6400000;
  301 + break;
  302 + case 2: /* BYD */
  303 + val->intval = 6500000;
  304 + break;
  305 + default:
  306 + return -EIO;
  307 + }
  308 + break;
  309 +
  310 + default:
  311 + return -EIO;
  312 + }
  313 +
  314 + return ret;
  315 +}
  316 +
270 317 /*********************************************************************
271 318 * Battery properties
272 319 *********************************************************************/
... ... @@ -401,6 +448,11 @@
401 448 sprintf(bat_serial, "%016llx", (long long)be64_to_cpu(ser_buf));
402 449 val->strval = bat_serial;
403 450 break;
  451 + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
  452 + ret = olpc_bat_get_voltage_max_design(val);
  453 + if (ret)
  454 + return ret;
  455 + break;
404 456 default:
405 457 ret = -EINVAL;
406 458 break;
... ... @@ -428,6 +480,7 @@
428 480 POWER_SUPPLY_PROP_MANUFACTURER,
429 481 POWER_SUPPLY_PROP_SERIAL_NUMBER,
430 482 POWER_SUPPLY_PROP_CHARGE_COUNTER,
  483 + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
431 484 };
432 485  
433 486 /* XO-1.5 does not have ambient temperature property */
... ... @@ -449,6 +502,7 @@
449 502 POWER_SUPPLY_PROP_MANUFACTURER,
450 503 POWER_SUPPLY_PROP_SERIAL_NUMBER,
451 504 POWER_SUPPLY_PROP_CHARGE_COUNTER,
  505 + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
452 506 };
453 507  
454 508 /* EEPROM reading goes completely around the power_supply API, sadly */
drivers/power/pda_power.c
... ... @@ -134,13 +134,13 @@
134 134 regulator_set_current_limit(ac_draw, max_uA, max_uA);
135 135 if (!regulator_enabled) {
136 136 dev_dbg(dev, "charger on (AC)\n");
137   - regulator_enable(ac_draw);
  137 + WARN_ON(regulator_enable(ac_draw));
138 138 regulator_enabled = 1;
139 139 }
140 140 } else {
141 141 if (regulator_enabled) {
142 142 dev_dbg(dev, "charger off\n");
143   - regulator_disable(ac_draw);
  143 + WARN_ON(regulator_disable(ac_draw));
144 144 regulator_enabled = 0;
145 145 }
146 146 }
drivers/power/power_supply_core.c
... ... @@ -17,6 +17,7 @@
17 17 #include <linux/device.h>
18 18 #include <linux/err.h>
19 19 #include <linux/power_supply.h>
  20 +#include <linux/thermal.h>
20 21 #include "power_supply.h"
21 22  
22 23 /* exported for the APM Power driver, APM emulation */
... ... @@ -169,6 +170,63 @@
169 170 kfree(dev);
170 171 }
171 172  
  173 +#ifdef CONFIG_THERMAL
  174 +static int power_supply_read_temp(struct thermal_zone_device *tzd,
  175 + unsigned long *temp)
  176 +{
  177 + struct power_supply *psy;
  178 + union power_supply_propval val;
  179 + int ret;
  180 +
  181 + WARN_ON(tzd == NULL);
  182 + psy = tzd->devdata;
  183 + ret = psy->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
  184 +
  185 + /* Convert tenths of degree Celsius to milli degree Celsius. */
  186 + if (!ret)
  187 + *temp = val.intval * 100;
  188 +
  189 + return ret;
  190 +}
  191 +
  192 +static struct thermal_zone_device_ops psy_tzd_ops = {
  193 + .get_temp = power_supply_read_temp,
  194 +};
  195 +
  196 +static int psy_register_thermal(struct power_supply *psy)
  197 +{
  198 + int i;
  199 +
  200 + /* Register battery zone device psy reports temperature */
  201 + for (i = 0; i < psy->num_properties; i++) {
  202 + if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
  203 + psy->tzd = thermal_zone_device_register(psy->name, 0, 0,
  204 + psy, &psy_tzd_ops, 0, 0, 0, 0);
  205 + if (IS_ERR(psy->tzd))
  206 + return PTR_ERR(psy->tzd);
  207 + break;
  208 + }
  209 + }
  210 + return 0;
  211 +}
  212 +
  213 +static void psy_unregister_thermal(struct power_supply *psy)
  214 +{
  215 + if (IS_ERR_OR_NULL(psy->tzd))
  216 + return;
  217 + thermal_zone_device_unregister(psy->tzd);
  218 +}
  219 +#else
  220 +static int psy_register_thermal(struct power_supply *psy)
  221 +{
  222 + return 0;
  223 +}
  224 +
  225 +static void psy_unregister_thermal(struct power_supply *psy)
  226 +{
  227 +}
  228 +#endif
  229 +
172 230 int power_supply_register(struct device *parent, struct power_supply *psy)
173 231 {
174 232 struct device *dev;
... ... @@ -197,6 +255,10 @@
197 255 if (rc)
198 256 goto device_add_failed;
199 257  
  258 + rc = psy_register_thermal(psy);
  259 + if (rc)
  260 + goto register_thermal_failed;
  261 +
200 262 rc = power_supply_create_triggers(psy);
201 263 if (rc)
202 264 goto create_triggers_failed;
... ... @@ -206,6 +268,8 @@
206 268 goto success;
207 269  
208 270 create_triggers_failed:
  271 + psy_unregister_thermal(psy);
  272 +register_thermal_failed:
209 273 device_del(dev);
210 274 kobject_set_name_failed:
211 275 device_add_failed:
... ... @@ -220,6 +284,7 @@
220 284 cancel_work_sync(&psy->changed_work);
221 285 sysfs_remove_link(&psy->dev->kobj, "powers");
222 286 power_supply_remove_triggers(psy);
  287 + psy_unregister_thermal(psy);
223 288 device_unregister(psy->dev);
224 289 }
225 290 EXPORT_SYMBOL_GPL(power_supply_unregister);
drivers/power/power_supply_sysfs.c
... ... @@ -159,6 +159,8 @@
159 159 POWER_SUPPLY_ATTR(charge_now),
160 160 POWER_SUPPLY_ATTR(charge_avg),
161 161 POWER_SUPPLY_ATTR(charge_counter),
  162 + POWER_SUPPLY_ATTR(constant_charge_current),
  163 + POWER_SUPPLY_ATTR(constant_charge_voltage),
162 164 POWER_SUPPLY_ATTR(energy_full_design),
163 165 POWER_SUPPLY_ATTR(energy_empty_design),
164 166 POWER_SUPPLY_ATTR(energy_full),
165 167  
166 168  
... ... @@ -166,9 +168,15 @@
166 168 POWER_SUPPLY_ATTR(energy_now),
167 169 POWER_SUPPLY_ATTR(energy_avg),
168 170 POWER_SUPPLY_ATTR(capacity),
  171 + POWER_SUPPLY_ATTR(capacity_alert_min),
  172 + POWER_SUPPLY_ATTR(capacity_alert_max),
169 173 POWER_SUPPLY_ATTR(capacity_level),
170 174 POWER_SUPPLY_ATTR(temp),
  175 + POWER_SUPPLY_ATTR(temp_alert_min),
  176 + POWER_SUPPLY_ATTR(temp_alert_max),
171 177 POWER_SUPPLY_ATTR(temp_ambient),
  178 + POWER_SUPPLY_ATTR(temp_ambient_alert_min),
  179 + POWER_SUPPLY_ATTR(temp_ambient_alert_max),
172 180 POWER_SUPPLY_ATTR(time_to_empty_now),
173 181 POWER_SUPPLY_ATTR(time_to_empty_avg),
174 182 POWER_SUPPLY_ATTR(time_to_full_now),
drivers/power/sbs-battery.c
... ... @@ -469,7 +469,7 @@
469 469  
470 470 case POWER_SUPPLY_PROP_TECHNOLOGY:
471 471 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
472   - break;
  472 + goto done; /* don't trigger power_supply_changed()! */
473 473  
474 474 case POWER_SUPPLY_PROP_ENERGY_NOW:
475 475 case POWER_SUPPLY_PROP_ENERGY_FULL:
drivers/power/smb347-charger.c
... ... @@ -196,6 +196,14 @@
196 196 1200000,
197 197 };
198 198  
  199 +/* Convert register value to current using lookup table */
  200 +static int hw_to_current(const unsigned int *tbl, size_t size, unsigned int val)
  201 +{
  202 + if (val >= size)
  203 + return -EINVAL;
  204 + return tbl[val];
  205 +}
  206 +
199 207 /* Convert current to register value using lookup table */
200 208 static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val)
201 209 {
202 210  
203 211  
204 212  
205 213  
206 214  
... ... @@ -841,22 +849,101 @@
841 849 return ret;
842 850 }
843 851  
  852 +/*
  853 + * Returns the constant charge current programmed
  854 + * into the charger in uA.
  855 + */
  856 +static int get_const_charge_current(struct smb347_charger *smb)
  857 +{
  858 + int ret, intval;
  859 + unsigned int v;
  860 +
  861 + if (!smb347_is_ps_online(smb))
  862 + return -ENODATA;
  863 +
  864 + ret = regmap_read(smb->regmap, STAT_B, &v);
  865 + if (ret < 0)
  866 + return ret;
  867 +
  868 + /*
  869 + * The current value is composition of FCC and PCC values
  870 + * and we can detect which table to use from bit 5.
  871 + */
  872 + if (v & 0x20) {
  873 + intval = hw_to_current(fcc_tbl, ARRAY_SIZE(fcc_tbl), v & 7);
  874 + } else {
  875 + v >>= 3;
  876 + intval = hw_to_current(pcc_tbl, ARRAY_SIZE(pcc_tbl), v & 7);
  877 + }
  878 +
  879 + return intval;
  880 +}
  881 +
  882 +/*
  883 + * Returns the constant charge voltage programmed
  884 + * into the charger in uV.
  885 + */
  886 +static int get_const_charge_voltage(struct smb347_charger *smb)
  887 +{
  888 + int ret, intval;
  889 + unsigned int v;
  890 +
  891 + if (!smb347_is_ps_online(smb))
  892 + return -ENODATA;
  893 +
  894 + ret = regmap_read(smb->regmap, STAT_A, &v);
  895 + if (ret < 0)
  896 + return ret;
  897 +
  898 + v &= STAT_A_FLOAT_VOLTAGE_MASK;
  899 + if (v > 0x3d)
  900 + v = 0x3d;
  901 +
  902 + intval = 3500000 + v * 20000;
  903 +
  904 + return intval;
  905 +}
  906 +
844 907 static int smb347_mains_get_property(struct power_supply *psy,
845 908 enum power_supply_property prop,
846 909 union power_supply_propval *val)
847 910 {
848 911 struct smb347_charger *smb =
849 912 container_of(psy, struct smb347_charger, mains);
  913 + int ret;
850 914  
851   - if (prop == POWER_SUPPLY_PROP_ONLINE) {
  915 + switch (prop) {
  916 + case POWER_SUPPLY_PROP_ONLINE:
852 917 val->intval = smb->mains_online;
853   - return 0;
  918 + break;
  919 +
  920 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
  921 + ret = get_const_charge_voltage(smb);
  922 + if (ret < 0)
  923 + return ret;
  924 + else
  925 + val->intval = ret;
  926 + break;
  927 +
  928 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
  929 + ret = get_const_charge_current(smb);
  930 + if (ret < 0)
  931 + return ret;
  932 + else
  933 + val->intval = ret;
  934 + break;
  935 +
  936 + default:
  937 + return -EINVAL;
854 938 }
855   - return -EINVAL;
  939 +
  940 + return 0;
856 941 }
857 942  
858 943 static enum power_supply_property smb347_mains_properties[] = {
859 944 POWER_SUPPLY_PROP_ONLINE,
  945 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
  946 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
860 947 };
861 948  
862 949 static int smb347_usb_get_property(struct power_supply *psy,
863 950  
864 951  
865 952  
866 953  
... ... @@ -865,16 +952,40 @@
865 952 {
866 953 struct smb347_charger *smb =
867 954 container_of(psy, struct smb347_charger, usb);
  955 + int ret;
868 956  
869   - if (prop == POWER_SUPPLY_PROP_ONLINE) {
  957 + switch (prop) {
  958 + case POWER_SUPPLY_PROP_ONLINE:
870 959 val->intval = smb->usb_online;
871   - return 0;
  960 + break;
  961 +
  962 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
  963 + ret = get_const_charge_voltage(smb);
  964 + if (ret < 0)
  965 + return ret;
  966 + else
  967 + val->intval = ret;
  968 + break;
  969 +
  970 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
  971 + ret = get_const_charge_current(smb);
  972 + if (ret < 0)
  973 + return ret;
  974 + else
  975 + val->intval = ret;
  976 + break;
  977 +
  978 + default:
  979 + return -EINVAL;
872 980 }
873   - return -EINVAL;
  981 +
  982 + return 0;
874 983 }
875 984  
876 985 static enum power_supply_property smb347_usb_properties[] = {
877 986 POWER_SUPPLY_PROP_ONLINE,
  987 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
  988 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
878 989 };
879 990  
880 991 static int smb347_battery_get_property(struct power_supply *psy,
drivers/power/test_power.c
... ... @@ -22,11 +22,13 @@
22 22 #include <linux/vermagic.h>
23 23  
24 24 static int ac_online = 1;
  25 +static int usb_online = 1;
25 26 static int battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
26 27 static int battery_health = POWER_SUPPLY_HEALTH_GOOD;
27 28 static int battery_present = 1; /* true */
28 29 static int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION;
29 30 static int battery_capacity = 50;
  31 +static int battery_voltage = 3300;
30 32  
31 33 static int test_power_get_ac_property(struct power_supply *psy,
32 34 enum power_supply_property psp,
... ... @@ -42,6 +44,20 @@
42 44 return 0;
43 45 }
44 46  
  47 +static int test_power_get_usb_property(struct power_supply *psy,
  48 + enum power_supply_property psp,
  49 + union power_supply_propval *val)
  50 +{
  51 + switch (psp) {
  52 + case POWER_SUPPLY_PROP_ONLINE:
  53 + val->intval = usb_online;
  54 + break;
  55 + default:
  56 + return -EINVAL;
  57 + }
  58 + return 0;
  59 +}
  60 +
45 61 static int test_power_get_battery_property(struct power_supply *psy,
46 62 enum power_supply_property psp,
47 63 union power_supply_propval *val)
... ... @@ -86,6 +102,12 @@
86 102 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
87 103 val->intval = 3600;
88 104 break;
  105 + case POWER_SUPPLY_PROP_TEMP:
  106 + val->intval = 26;
  107 + break;
  108 + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  109 + val->intval = battery_voltage;
  110 + break;
89 111 default:
90 112 pr_info("%s: some properties deliberately report errors.\n",
91 113 __func__);
... ... @@ -114,6 +136,8 @@
114 136 POWER_SUPPLY_PROP_MODEL_NAME,
115 137 POWER_SUPPLY_PROP_MANUFACTURER,
116 138 POWER_SUPPLY_PROP_SERIAL_NUMBER,
  139 + POWER_SUPPLY_PROP_TEMP,
  140 + POWER_SUPPLY_PROP_VOLTAGE_NOW,
117 141 };
118 142  
119 143 static char *test_power_ac_supplied_to[] = {
... ... @@ -135,6 +159,14 @@
135 159 .properties = test_power_battery_props,
136 160 .num_properties = ARRAY_SIZE(test_power_battery_props),
137 161 .get_property = test_power_get_battery_property,
  162 + }, {
  163 + .name = "test_usb",
  164 + .type = POWER_SUPPLY_TYPE_USB,
  165 + .supplied_to = test_power_ac_supplied_to,
  166 + .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to),
  167 + .properties = test_power_ac_props,
  168 + .num_properties = ARRAY_SIZE(test_power_ac_props),
  169 + .get_property = test_power_get_usb_property,
138 170 },
139 171 };
140 172  
... ... @@ -167,6 +199,7 @@
167 199  
168 200 /* Let's see how we handle changes... */
169 201 ac_online = 0;
  202 + usb_online = 0;
170 203 battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
171 204 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++)
172 205 power_supply_changed(&test_power_supplies[i]);
... ... @@ -275,6 +308,19 @@
275 308 return strlen(buffer);
276 309 }
277 310  
  311 +static int param_set_usb_online(const char *key, const struct kernel_param *kp)
  312 +{
  313 + usb_online = map_get_value(map_ac_online, key, usb_online);
  314 + power_supply_changed(&test_power_supplies[2]);
  315 + return 0;
  316 +}
  317 +
  318 +static int param_get_usb_online(char *buffer, const struct kernel_param *kp)
  319 +{
  320 + strcpy(buffer, map_get_key(map_ac_online, usb_online, "unknown"));
  321 + return strlen(buffer);
  322 +}
  323 +
278 324 static int param_set_battery_status(const char *key,
279 325 const struct kernel_param *kp)
280 326 {
281 327  
282 328  
283 329  
... ... @@ -350,13 +396,31 @@
350 396  
351 397 #define param_get_battery_capacity param_get_int
352 398  
  399 +static int param_set_battery_voltage(const char *key,
  400 + const struct kernel_param *kp)
  401 +{
  402 + int tmp;
353 403  
  404 + if (1 != sscanf(key, "%d", &tmp))
  405 + return -EINVAL;
354 406  
  407 + battery_voltage = tmp;
  408 + power_supply_changed(&test_power_supplies[1]);
  409 + return 0;
  410 +}
  411 +
  412 +#define param_get_battery_voltage param_get_int
  413 +
355 414 static struct kernel_param_ops param_ops_ac_online = {
356 415 .set = param_set_ac_online,
357 416 .get = param_get_ac_online,
358 417 };
359 418  
  419 +static struct kernel_param_ops param_ops_usb_online = {
  420 + .set = param_set_usb_online,
  421 + .get = param_get_usb_online,
  422 +};
  423 +
360 424 static struct kernel_param_ops param_ops_battery_status = {
361 425 .set = param_set_battery_status,
362 426 .get = param_get_battery_status,
363 427  
364 428  
365 429  
... ... @@ -382,18 +446,27 @@
382 446 .get = param_get_battery_capacity,
383 447 };
384 448  
  449 +static struct kernel_param_ops param_ops_battery_voltage = {
  450 + .set = param_set_battery_voltage,
  451 + .get = param_get_battery_voltage,
  452 +};
385 453  
386 454 #define param_check_ac_online(name, p) __param_check(name, p, void);
  455 +#define param_check_usb_online(name, p) __param_check(name, p, void);
387 456 #define param_check_battery_status(name, p) __param_check(name, p, void);
388 457 #define param_check_battery_present(name, p) __param_check(name, p, void);
389 458 #define param_check_battery_technology(name, p) __param_check(name, p, void);
390 459 #define param_check_battery_health(name, p) __param_check(name, p, void);
391 460 #define param_check_battery_capacity(name, p) __param_check(name, p, void);
  461 +#define param_check_battery_voltage(name, p) __param_check(name, p, void);
392 462  
393 463  
394 464 module_param(ac_online, ac_online, 0644);
395 465 MODULE_PARM_DESC(ac_online, "AC charging state <on|off>");
396 466  
  467 +module_param(usb_online, usb_online, 0644);
  468 +MODULE_PARM_DESC(usb_online, "USB charging state <on|off>");
  469 +
397 470 module_param(battery_status, battery_status, 0644);
398 471 MODULE_PARM_DESC(battery_status,
399 472 "battery status <charging|discharging|not-charging|full>");
... ... @@ -413,6 +486,8 @@
413 486 module_param(battery_capacity, battery_capacity, 0644);
414 487 MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)");
415 488  
  489 +module_param(battery_voltage, battery_voltage, 0644);
  490 +MODULE_PARM_DESC(battery_voltage, "battery voltage (millivolts)");
416 491  
417 492 MODULE_DESCRIPTION("Power supply driver for testing");
418 493 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
drivers/power/twl4030_charger.c
... ... @@ -22,6 +22,7 @@
22 22 #include <linux/power_supply.h>
23 23 #include <linux/notifier.h>
24 24 #include <linux/usb/otg.h>
  25 +#include <linux/regulator/machine.h>
25 26  
26 27 #define TWL4030_BCIMSTATEC 0x02
27 28 #define TWL4030_BCIICHG 0x08
... ... @@ -29,6 +30,7 @@
29 30 #define TWL4030_BCIVBUS 0x0c
30 31 #define TWL4030_BCIMFSTS4 0x10
31 32 #define TWL4030_BCICTL1 0x23
  33 +#define TWL4030_BB_CFG 0x12
32 34  
33 35 #define TWL4030_BCIAUTOWEN BIT(5)
34 36 #define TWL4030_CONFIG_DONE BIT(4)
... ... @@ -38,6 +40,17 @@
38 40 #define TWL4030_USBFASTMCHG BIT(2)
39 41 #define TWL4030_STS_VBUS BIT(7)
40 42 #define TWL4030_STS_USB_ID BIT(2)
  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
41 54  
42 55 /* BCI interrupts */
43 56 #define TWL4030_WOVF BIT(0) /* Watchdog overflow */
... ... @@ -75,6 +88,8 @@
75 88 struct work_struct work;
76 89 int irq_chg;
77 90 int irq_bci;
  91 + struct regulator *usb_reg;
  92 + int usb_enabled;
78 93  
79 94 unsigned long event;
80 95 };
... ... @@ -104,7 +119,7 @@
104 119  
105 120 static int twl4030_clear_set_boot_bci(u8 clear, u8 set)
106 121 {
107   - return twl4030_clear_set(TWL4030_MODULE_PM_MASTER, 0,
  122 + return twl4030_clear_set(TWL4030_MODULE_PM_MASTER, clear,
108 123 TWL4030_CONFIG_DONE | TWL4030_BCIAUTOWEN | set,
109 124 TWL4030_PM_MASTER_BOOT_BCI);
110 125 }
111 126  
... ... @@ -152,14 +167,14 @@
152 167 }
153 168  
154 169 /*
155   - * Enable/Disable USB Charge funtionality.
  170 + * Enable/Disable USB Charge functionality.
156 171 */
157 172 static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
158 173 {
159 174 int ret;
160 175  
161 176 if (enable) {
162   - /* Check for USB charger conneted */
  177 + /* Check for USB charger connected */
163 178 if (!twl4030_bci_have_vbus(bci))
164 179 return -ENODEV;
165 180  
... ... @@ -172,6 +187,12 @@
172 187 return -EACCES;
173 188 }
174 189  
  190 + /* Need to keep regulator on */
  191 + if (!bci->usb_enabled) {
  192 + regulator_enable(bci->usb_reg);
  193 + bci->usb_enabled = 1;
  194 + }
  195 +
175 196 /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
176 197 ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
177 198 if (ret < 0)
... ... @@ -182,6 +203,10 @@
182 203 TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4);
183 204 } else {
184 205 ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0);
  206 + if (bci->usb_enabled) {
  207 + regulator_disable(bci->usb_reg);
  208 + bci->usb_enabled = 0;
  209 + }
185 210 }
186 211  
187 212 return ret;
... ... @@ -203,6 +228,49 @@
203 228 }
204 229  
205 230 /*
  231 + * Enable/Disable charging of Backup Battery.
  232 + */
  233 +static int twl4030_charger_enable_backup(int uvolt, int uamp)
  234 +{
  235 + int ret;
  236 + u8 flags;
  237 +
  238 + if (uvolt < 2500000 ||
  239 + uamp < 25) {
  240 + /* disable charging of backup battery */
  241 + ret = twl4030_clear_set(TWL4030_MODULE_PM_RECEIVER,
  242 + TWL4030_BBCHEN, 0, TWL4030_BB_CFG);
  243 + return ret;
  244 + }
  245 +
  246 + flags = TWL4030_BBCHEN;
  247 + if (uvolt >= 3200000)
  248 + flags |= TWL4030_BBSEL_3V2;
  249 + else if (uvolt >= 3100000)
  250 + flags |= TWL4030_BBSEL_3V1;
  251 + else if (uvolt >= 3000000)
  252 + flags |= TWL4030_BBSEL_3V0;
  253 + else
  254 + flags |= TWL4030_BBSEL_2V5;
  255 +
  256 + if (uamp >= 1000)
  257 + flags |= TWL4030_BBISEL_1000uA;
  258 + else if (uamp >= 500)
  259 + flags |= TWL4030_BBISEL_500uA;
  260 + else if (uamp >= 150)
  261 + flags |= TWL4030_BBISEL_150uA;
  262 + else
  263 + flags |= TWL4030_BBISEL_25uA;
  264 +
  265 + ret = twl4030_clear_set(TWL4030_MODULE_PM_RECEIVER,
  266 + TWL4030_BBSEL_MASK | TWL4030_BBISEL_MASK,
  267 + flags,
  268 + TWL4030_BB_CFG);
  269 +
  270 + return ret;
  271 +}
  272 +
  273 +/*
206 274 * TWL4030 CHG_PRES (AC charger presence) events
207 275 */
208 276 static irqreturn_t twl4030_charger_interrupt(int irq, void *arg)
... ... @@ -425,6 +493,7 @@
425 493 static int __init twl4030_bci_probe(struct platform_device *pdev)
426 494 {
427 495 struct twl4030_bci *bci;
  496 + struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data;
428 497 int ret;
429 498 u32 reg;
430 499  
... ... @@ -456,6 +525,8 @@
456 525 bci->usb.num_properties = ARRAY_SIZE(twl4030_charger_props);
457 526 bci->usb.get_property = twl4030_bci_get_property;
458 527  
  528 + bci->usb_reg = regulator_get(bci->dev, "bci3v1");
  529 +
459 530 ret = power_supply_register(&pdev->dev, &bci->usb);
460 531 if (ret) {
461 532 dev_err(&pdev->dev, "failed to register usb: %d\n", ret);
... ... @@ -504,6 +575,8 @@
504 575  
505 576 twl4030_charger_enable_ac(true);
506 577 twl4030_charger_enable_usb(bci, true);
  578 + twl4030_charger_enable_backup(pdata->bb_uvolt,
  579 + pdata->bb_uamp);
507 580  
508 581 return 0;
509 582  
... ... @@ -532,6 +605,7 @@
532 605  
533 606 twl4030_charger_enable_ac(false);
534 607 twl4030_charger_enable_usb(bci, false);
  608 + twl4030_charger_enable_backup(0, 0);
535 609  
536 610 /* mask interrupts */
537 611 twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
drivers/thermal/thermal_sys.c
... ... @@ -1251,7 +1251,7 @@
1251 1251 * longer needed. The passive cooling formula uses tc1 and tc2 as described in
1252 1252 * section 11.1.5.1 of the ACPI specification 3.0.
1253 1253 */
1254   -struct thermal_zone_device *thermal_zone_device_register(char *type,
  1254 +struct thermal_zone_device *thermal_zone_device_register(const char *type,
1255 1255 int trips, int mask, void *devdata,
1256 1256 const struct thermal_zone_device_ops *ops,
1257 1257 int tc1, int tc2, int passive_delay, int polling_delay)
include/linux/i2c/twl.h
... ... @@ -555,6 +555,8 @@
555 555 struct twl4030_bci_platform_data {
556 556 int *battery_tmp_tbl;
557 557 unsigned int tblsize;
  558 + int bb_uvolt; /* voltage to charge backup battery */
  559 + int bb_uamp; /* current for backup battery charging */
558 560 };
559 561  
560 562 /* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */
include/linux/lp8727.h
1   -/*
2   - * LP8727 Micro/Mini USB IC with integrated charger
3   - *
4   - * Copyright (C) 2011 Texas Instruments
5   - * Copyright (C) 2011 National Semiconductor
6   - *
7   - * This program is free software; you can redistribute it and/or modify
8   - * it under the terms of the GNU General Public License version 2 as
9   - * published by the Free Software Foundation.
10   - */
11   -
12   -#ifndef _LP8727_H
13   -#define _LP8727_H
14   -
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,
23   -};
24   -
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,
36   -};
37   -
38   -/**
39   - * struct lp8727_chg_param
40   - * @eoc_level : end of charge level setting
41   - * @ichg : charging current
42   - */
43   -struct lp8727_chg_param {
44   - enum lp8727_eoc_level eoc_level;
45   - enum lp8727_ichg ichg;
46   -};
47   -
48   -/**
49   - * struct lp8727_platform_data
50   - * @get_batt_present : check battery status - exists or not
51   - * @get_batt_level : get battery voltage (mV)
52   - * @get_batt_capacity : get battery capacity (%)
53   - * @get_batt_temp : get battery temperature
54   - * @ac, @usb : charging parameters each charger type
55   - */
56   -struct lp8727_platform_data {
57   - u8 (*get_batt_present)(void);
58   - u16 (*get_batt_level)(void);
59   - u8 (*get_batt_capacity)(void);
60   - u8 (*get_batt_temp)(void);
61   - struct lp8727_chg_param ac;
62   - struct lp8727_chg_param usb;
63   -};
64   -
65   -#endif
include/linux/platform_data/lp8727.h
  1 +/*
  2 + * LP8727 Micro/Mini USB IC with integrated charger
  3 + *
  4 + * Copyright (C) 2011 Texas Instruments
  5 + * Copyright (C) 2011 National Semiconductor
  6 + *
  7 + * This program is free software; you can redistribute it and/or modify
  8 + * it under the terms of the GNU General Public License version 2 as
  9 + * published by the Free Software Foundation.
  10 + */
  11 +
  12 +#ifndef _LP8727_H
  13 +#define _LP8727_H
  14 +
  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,
  23 +};
  24 +
  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,
  36 +};
  37 +
  38 +/**
  39 + * struct lp8727_chg_param
  40 + * @eoc_level : end of charge level setting
  41 + * @ichg : charging current
  42 + */
  43 +struct lp8727_chg_param {
  44 + enum lp8727_eoc_level eoc_level;
  45 + enum lp8727_ichg ichg;
  46 +};
  47 +
  48 +/**
  49 + * struct lp8727_platform_data
  50 + * @get_batt_present : check battery status - exists or not
  51 + * @get_batt_level : get battery voltage (mV)
  52 + * @get_batt_capacity : get battery capacity (%)
  53 + * @get_batt_temp : get battery temperature
  54 + * @ac, @usb : charging parameters each charger type
  55 + */
  56 +struct lp8727_platform_data {
  57 + u8 (*get_batt_present)(void);
  58 + u16 (*get_batt_level)(void);
  59 + u8 (*get_batt_capacity)(void);
  60 + u8 (*get_batt_temp)(void);
  61 + struct lp8727_chg_param ac;
  62 + struct lp8727_chg_param usb;
  63 +};
  64 +
  65 +#endif
include/linux/power/charger-manager.h
... ... @@ -16,6 +16,7 @@
16 16 #define _CHARGER_MANAGER_H
17 17  
18 18 #include <linux/power_supply.h>
  19 +#include <linux/extcon.h>
19 20  
20 21 enum data_source {
21 22 CM_BATTERY_PRESENT,
... ... @@ -65,6 +66,70 @@
65 66 };
66 67  
67 68 /**
  69 + * struct charger_cable
  70 + * @extcon_name: the name of extcon device.
  71 + * @name: the name of charger cable(external connector).
  72 + * @extcon_dev: the extcon device.
  73 + * @wq: the workqueue to control charger according to the state of
  74 + * charger cable. If charger cable is attached, enable charger.
  75 + * But if charger cable is detached, disable charger.
  76 + * @nb: the notifier block to receive changed state from EXTCON
  77 + * (External Connector) when charger cable is attached/detached.
  78 + * @attached: the state of charger cable.
  79 + * true: the charger cable is attached
  80 + * false: the charger cable is detached
  81 + * @charger: the instance of struct charger_regulator.
  82 + * @cm: the Charger Manager representing the battery.
  83 + */
  84 +struct charger_cable {
  85 + const char *extcon_name;
  86 + const char *name;
  87 +
  88 + /* The charger-manager use Exton framework*/
  89 + struct extcon_specific_cable_nb extcon_dev;
  90 + struct work_struct wq;
  91 + struct notifier_block nb;
  92 +
  93 + /* The state of charger cable */
  94 + bool attached;
  95 +
  96 + struct charger_regulator *charger;
  97 +
  98 + /*
  99 + * Set min/max current of regulator to protect over-current issue
  100 + * according to a kind of charger cable when cable is attached.
  101 + */
  102 + int min_uA;
  103 + int max_uA;
  104 +
  105 + struct charger_manager *cm;
  106 +};
  107 +
  108 +/**
  109 + * struct charger_regulator
  110 + * @regulator_name: the name of regulator for using charger.
  111 + * @consumer: the regulator consumer for the charger.
  112 + * @cables:
  113 + * the array of charger cables to enable/disable charger
  114 + * and set current limit according to constratint data of
  115 + * struct charger_cable if only charger cable included
  116 + * in the array of charger cables is attached/detached.
  117 + * @num_cables: the number of charger cables.
  118 + */
  119 +struct charger_regulator {
  120 + /* The name of regulator for charging */
  121 + const char *regulator_name;
  122 + struct regulator *consumer;
  123 +
  124 + /*
  125 + * Store constraint information related to current limit,
  126 + * each cable have different condition for charging.
  127 + */
  128 + struct charger_cable *cables;
  129 + int num_cables;
  130 +};
  131 +
  132 +/**
68 133 * struct charger_desc
69 134 * @psy_name: the name of power-supply-class for charger manager
70 135 * @polling_mode:
... ... @@ -109,7 +174,7 @@
109 174 char **psy_charger_stat;
110 175  
111 176 int num_charger_regulators;
112   - struct regulator_bulk_data *charger_regulators;
  177 + struct charger_regulator *charger_regulators;
113 178  
114 179 char *psy_fuel_gauge;
115 180  
include/linux/power_supply.h
... ... @@ -109,6 +109,8 @@
109 109 POWER_SUPPLY_PROP_CHARGE_NOW,
110 110 POWER_SUPPLY_PROP_CHARGE_AVG,
111 111 POWER_SUPPLY_PROP_CHARGE_COUNTER,
  112 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
  113 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
112 114 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
113 115 POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN,
114 116 POWER_SUPPLY_PROP_ENERGY_FULL,
115 117  
116 118  
... ... @@ -116,9 +118,15 @@
116 118 POWER_SUPPLY_PROP_ENERGY_NOW,
117 119 POWER_SUPPLY_PROP_ENERGY_AVG,
118 120 POWER_SUPPLY_PROP_CAPACITY, /* in percents! */
  121 + POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, /* in percents! */
  122 + POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX, /* in percents! */
119 123 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
120 124 POWER_SUPPLY_PROP_TEMP,
  125 + POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
  126 + POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
121 127 POWER_SUPPLY_PROP_TEMP_AMBIENT,
  128 + POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN,
  129 + POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX,
122 130 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
123 131 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
124 132 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
... ... @@ -173,6 +181,9 @@
173 181 /* private */
174 182 struct device *dev;
175 183 struct work_struct changed_work;
  184 +#ifdef CONFIG_THERMAL
  185 + struct thermal_zone_device *tzd;
  186 +#endif
176 187  
177 188 #ifdef CONFIG_LEDS_TRIGGERS
178 189 struct led_trigger *charging_full_trig;
... ... @@ -236,6 +247,7 @@
236 247 case POWER_SUPPLY_PROP_CHARGE_NOW:
237 248 case POWER_SUPPLY_PROP_CHARGE_AVG:
238 249 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
  250 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
239 251 case POWER_SUPPLY_PROP_CURRENT_MAX:
240 252 case POWER_SUPPLY_PROP_CURRENT_NOW:
241 253 case POWER_SUPPLY_PROP_CURRENT_AVG:
... ... @@ -263,6 +275,7 @@
263 275 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
264 276 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
265 277 case POWER_SUPPLY_PROP_VOLTAGE_OCV:
  278 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
266 279 case POWER_SUPPLY_PROP_POWER_NOW:
267 280 return 1;
268 281 default:
include/linux/thermal.h
... ... @@ -151,7 +151,7 @@
151 151 };
152 152 #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
153 153  
154   -struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
  154 +struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
155 155 void *, const struct thermal_zone_device_ops *, int tc1,
156 156 int tc2, int passive_freq, int polling_freq);
157 157 void thermal_zone_device_unregister(struct thermal_zone_device *);