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

Merge git://git.infradead.org/battery-2.6

* git://git.infradead.org/battery-2.6:
PXA: Use dev_pm_ops in z2_battery
ds2760_battery: Fix rated capacity of the hx4700 1800mAh battery
ds2760_battery: Fix indexing of the 4 active full EEPROM registers
power: Make test_power driver more dynamic.
bq27x00_battery: Name of cycle count property
max8903_charger: Add GENERIC_HARDIRQS as a dependency (fixes S390 build)
ARM: RX-51: Enable isp1704 power on/off
isp1704_charger: Allow board specific powering routine
gpio-charger: Add gpio_charger_resume
power_supply: Add driver for MAX8903 charger

+841 -25
+26 -3
arch/arm/mach-omap2/board-rx51-peripherals.c
··· 23 23 #include <linux/gpio.h> 24 24 #include <linux/gpio_keys.h> 25 25 #include <linux/mmc/host.h> 26 + #include <linux/power/isp1704_charger.h> 26 27 27 28 #include <plat/mcspi.h> 28 29 #include <plat/board.h> ··· 53 52 #define RX51_WL1251_IRQ_GPIO 42 54 53 #define RX51_FMTX_RESET_GPIO 163 55 54 #define RX51_FMTX_IRQ 53 55 + 56 + #define RX51_USB_TRANSCEIVER_RST_GPIO 67 56 57 57 58 /* list all spi devices here */ 58 59 enum { ··· 114 111 }, 115 112 }; 116 113 117 - static struct platform_device rx51_charger_device = { 118 - .name = "isp1704_charger", 114 + static void rx51_charger_set_power(bool on) 115 + { 116 + gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on); 117 + } 118 + 119 + static struct isp1704_charger_data rx51_charger_data = { 120 + .set_power = rx51_charger_set_power, 119 121 }; 122 + 123 + static struct platform_device rx51_charger_device = { 124 + .name = "isp1704_charger", 125 + .dev = { 126 + .platform_data = &rx51_charger_data, 127 + }, 128 + }; 129 + 130 + static void __init rx51_charger_init(void) 131 + { 132 + WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, 133 + GPIOF_OUT_INIT_LOW, "isp1704_reset")); 134 + 135 + platform_device_register(&rx51_charger_device); 136 + } 120 137 121 138 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) 122 139 ··· 984 961 if (partition) 985 962 omap2_hsmmc_init(mmc); 986 963 987 - platform_device_register(&rx51_charger_device); 964 + rx51_charger_init(); 988 965 } 989 966
+9
drivers/power/Kconfig
··· 210 210 Say Y to enable support for USB Charger Detection with 211 211 ISP1707/ISP1704 USB transceivers. 212 212 213 + config CHARGER_MAX8903 214 + tristate "MAX8903 Battery DC-DC Charger for USB and Adapter Power" 215 + depends on GENERIC_HARDIRQS 216 + help 217 + Say Y to enable support for the MAX8903 DC-DC charger and sysfs. 218 + The driver supports controlling charger-enable and current-limit 219 + pins based on the status of charger connections with interrupt 220 + handlers. 221 + 213 222 config CHARGER_TWL4030 214 223 tristate "OMAP TWL4030 BCI charger driver" 215 224 depends on TWL4030_CORE
+1
drivers/power/Makefile
··· 33 33 obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o 34 34 obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o 35 35 obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o 36 + obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o 36 37 obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o 37 38 obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
+6 -5
drivers/power/bq27x00_battery.c
··· 4 4 * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it> 5 5 * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it> 6 6 * Copyright (C) 2010-2011 Lars-Peter Clausen <lars@metafoo.de> 7 + * Copyright (C) 2011 Pali Rohár <pali.rohar@gmail.com> 7 8 * 8 9 * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. 9 10 * ··· 77 76 int time_to_empty_avg; 78 77 int time_to_full; 79 78 int charge_full; 80 - int charge_counter; 79 + int cycle_count; 81 80 int capacity; 82 81 int flags; 83 82 ··· 116 115 POWER_SUPPLY_PROP_CHARGE_FULL, 117 116 POWER_SUPPLY_PROP_CHARGE_NOW, 118 117 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 119 - POWER_SUPPLY_PROP_CHARGE_COUNTER, 118 + POWER_SUPPLY_PROP_CYCLE_COUNT, 120 119 POWER_SUPPLY_PROP_ENERGY_NOW, 121 120 }; 122 121 ··· 268 267 cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP); 269 268 cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF); 270 269 cache.charge_full = bq27x00_battery_read_lmd(di); 271 - cache.charge_counter = bq27x00_battery_read_cyct(di); 270 + cache.cycle_count = bq27x00_battery_read_cyct(di); 272 271 273 272 if (!is_bq27500) 274 273 cache.current_now = bq27x00_read(di, BQ27x00_REG_AI, false); ··· 497 496 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 498 497 ret = bq27x00_simple_value(di->charge_design_full, val); 499 498 break; 500 - case POWER_SUPPLY_PROP_CHARGE_COUNTER: 501 - ret = bq27x00_simple_value(di->cache.charge_counter, val); 499 + case POWER_SUPPLY_PROP_CYCLE_COUNT: 500 + ret = bq27x00_simple_value(di->cache.cycle_count, val); 502 501 break; 503 502 case POWER_SUPPLY_PROP_ENERGY_NOW: 504 503 ret = bq27x00_battery_energy(di, val);
+5 -1
drivers/power/ds2760_battery.c
··· 86 86 920, /* NEC */ 87 87 1440, /* Samsung */ 88 88 1440, /* BYD */ 89 + #ifdef CONFIG_MACH_H4700 90 + 1800, /* HP iPAQ hx4700 3.7V 1800mAh (359113-001) */ 91 + #else 89 92 1440, /* Lishen */ 93 + #endif 90 94 1440, /* NEC */ 91 95 2880, /* Samsung */ 92 96 2880, /* BYD */ ··· 190 186 191 187 scale[0] = di->full_active_uAh; 192 188 for (i = 1; i < 5; i++) 193 - scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i]; 189 + scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 1 + i]; 194 190 195 191 di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10); 196 192 di->full_active_uAh *= 1000; /* convert to µAh */
+15
drivers/power/gpio-charger.c
··· 161 161 return 0; 162 162 } 163 163 164 + #ifdef CONFIG_PM_SLEEP 165 + static int gpio_charger_resume(struct device *dev) 166 + { 167 + struct platform_device *pdev = to_platform_device(dev); 168 + struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); 169 + 170 + power_supply_changed(&gpio_charger->charger); 171 + 172 + return 0; 173 + } 174 + #endif 175 + 176 + static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, NULL, gpio_charger_resume); 177 + 164 178 static struct platform_driver gpio_charger_driver = { 165 179 .probe = gpio_charger_probe, 166 180 .remove = __devexit_p(gpio_charger_remove), 167 181 .driver = { 168 182 .name = "gpio-charger", 169 183 .owner = THIS_MODULE, 184 + .pm = &gpio_charger_pm_ops, 170 185 }, 171 186 }; 172 187
+22
drivers/power/isp1704_charger.c
··· 33 33 #include <linux/usb/ulpi.h> 34 34 #include <linux/usb/ch9.h> 35 35 #include <linux/usb/gadget.h> 36 + #include <linux/power/isp1704_charger.h> 36 37 37 38 /* Vendor specific Power Control register */ 38 39 #define ISP1704_PWR_CTRL 0x3d ··· 70 69 unsigned long event; 71 70 unsigned max_power; 72 71 }; 72 + 73 + /* 74 + * Disable/enable the power from the isp1704 if a function for it 75 + * has been provided with platform data. 76 + */ 77 + static void isp1704_charger_set_power(struct isp1704_charger *isp, bool on) 78 + { 79 + struct isp1704_charger_data *board = isp->dev->platform_data; 80 + 81 + if (board->set_power) 82 + board->set_power(on); 83 + } 73 84 74 85 /* 75 86 * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB ··· 235 222 236 223 mutex_lock(&lock); 237 224 225 + if (event != USB_EVENT_NONE) 226 + isp1704_charger_set_power(isp, 1); 227 + 238 228 switch (event) { 239 229 case USB_EVENT_VBUS: 240 230 isp->online = true; ··· 285 269 */ 286 270 if (isp->otg->gadget) 287 271 usb_gadget_disconnect(isp->otg->gadget); 272 + 273 + isp1704_charger_set_power(isp, 0); 288 274 break; 289 275 case USB_EVENT_ENUMERATED: 290 276 if (isp->present) ··· 412 394 isp->dev = &pdev->dev; 413 395 platform_set_drvdata(pdev, isp); 414 396 397 + isp1704_charger_set_power(isp, 1); 398 + 415 399 ret = isp1704_test_ulpi(isp); 416 400 if (ret < 0) 417 401 goto fail1; ··· 454 434 455 435 /* Detect charger if VBUS is valid (the cable was already plugged). */ 456 436 ret = otg_io_read(isp->otg, ULPI_USB_INT_STS); 437 + isp1704_charger_set_power(isp, 0); 457 438 if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) { 458 439 isp->event = USB_EVENT_VBUS; 459 440 schedule_work(&isp->work); ··· 480 459 otg_unregister_notifier(isp->otg, &isp->nb); 481 460 power_supply_unregister(&isp->psy); 482 461 otg_put_transceiver(isp->otg); 462 + isp1704_charger_set_power(isp, 0); 483 463 kfree(isp); 484 464 485 465 return 0;
+391
drivers/power/max8903_charger.c
··· 1 + /* 2 + * max8903_charger.c - Maxim 8903 USB/Adapter Charger Driver 3 + * 4 + * Copyright (C) 2011 Samsung Electronics 5 + * MyungJoo Ham <myungjoo.ham@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + * 21 + */ 22 + 23 + #include <linux/gpio.h> 24 + #include <linux/interrupt.h> 25 + #include <linux/slab.h> 26 + #include <linux/power_supply.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/power/max8903_charger.h> 29 + 30 + struct max8903_data { 31 + struct max8903_pdata *pdata; 32 + struct device *dev; 33 + struct power_supply psy; 34 + bool fault; 35 + bool usb_in; 36 + bool ta_in; 37 + }; 38 + 39 + static enum power_supply_property max8903_charger_props[] = { 40 + POWER_SUPPLY_PROP_STATUS, /* Charger status output */ 41 + POWER_SUPPLY_PROP_ONLINE, /* External power source */ 42 + POWER_SUPPLY_PROP_HEALTH, /* Fault or OK */ 43 + }; 44 + 45 + static int max8903_get_property(struct power_supply *psy, 46 + enum power_supply_property psp, 47 + union power_supply_propval *val) 48 + { 49 + struct max8903_data *data = container_of(psy, 50 + struct max8903_data, psy); 51 + 52 + switch (psp) { 53 + case POWER_SUPPLY_PROP_STATUS: 54 + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 55 + if (data->pdata->chg) { 56 + if (gpio_get_value(data->pdata->chg) == 0) 57 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 58 + else if (data->usb_in || data->ta_in) 59 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 60 + else 61 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 62 + } 63 + break; 64 + case POWER_SUPPLY_PROP_ONLINE: 65 + val->intval = 0; 66 + if (data->usb_in || data->ta_in) 67 + val->intval = 1; 68 + break; 69 + case POWER_SUPPLY_PROP_HEALTH: 70 + val->intval = POWER_SUPPLY_HEALTH_GOOD; 71 + if (data->fault) 72 + val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 73 + break; 74 + default: 75 + return -EINVAL; 76 + } 77 + return 0; 78 + } 79 + 80 + static irqreturn_t max8903_dcin(int irq, void *_data) 81 + { 82 + struct max8903_data *data = _data; 83 + struct max8903_pdata *pdata = data->pdata; 84 + bool ta_in; 85 + enum power_supply_type old_type; 86 + 87 + ta_in = gpio_get_value(pdata->dok) ? false : true; 88 + 89 + if (ta_in == data->ta_in) 90 + return IRQ_HANDLED; 91 + 92 + data->ta_in = ta_in; 93 + 94 + /* Set Current-Limit-Mode 1:DC 0:USB */ 95 + if (pdata->dcm) 96 + gpio_set_value(pdata->dcm, ta_in ? 1 : 0); 97 + 98 + /* Charger Enable / Disable (cen is negated) */ 99 + if (pdata->cen) 100 + gpio_set_value(pdata->cen, ta_in ? 0 : 101 + (data->usb_in ? 0 : 1)); 102 + 103 + dev_dbg(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ? 104 + "Connected" : "Disconnected"); 105 + 106 + old_type = data->psy.type; 107 + 108 + if (data->ta_in) 109 + data->psy.type = POWER_SUPPLY_TYPE_MAINS; 110 + else if (data->usb_in) 111 + data->psy.type = POWER_SUPPLY_TYPE_USB; 112 + else 113 + data->psy.type = POWER_SUPPLY_TYPE_BATTERY; 114 + 115 + if (old_type != data->psy.type) 116 + power_supply_changed(&data->psy); 117 + 118 + return IRQ_HANDLED; 119 + } 120 + 121 + static irqreturn_t max8903_usbin(int irq, void *_data) 122 + { 123 + struct max8903_data *data = _data; 124 + struct max8903_pdata *pdata = data->pdata; 125 + bool usb_in; 126 + enum power_supply_type old_type; 127 + 128 + usb_in = gpio_get_value(pdata->uok) ? false : true; 129 + 130 + if (usb_in == data->usb_in) 131 + return IRQ_HANDLED; 132 + 133 + data->usb_in = usb_in; 134 + 135 + /* Do not touch Current-Limit-Mode */ 136 + 137 + /* Charger Enable / Disable (cen is negated) */ 138 + if (pdata->cen) 139 + gpio_set_value(pdata->cen, usb_in ? 0 : 140 + (data->ta_in ? 0 : 1)); 141 + 142 + dev_dbg(data->dev, "USB Charger %s.\n", usb_in ? 143 + "Connected" : "Disconnected"); 144 + 145 + old_type = data->psy.type; 146 + 147 + if (data->ta_in) 148 + data->psy.type = POWER_SUPPLY_TYPE_MAINS; 149 + else if (data->usb_in) 150 + data->psy.type = POWER_SUPPLY_TYPE_USB; 151 + else 152 + data->psy.type = POWER_SUPPLY_TYPE_BATTERY; 153 + 154 + if (old_type != data->psy.type) 155 + power_supply_changed(&data->psy); 156 + 157 + return IRQ_HANDLED; 158 + } 159 + 160 + static irqreturn_t max8903_fault(int irq, void *_data) 161 + { 162 + struct max8903_data *data = _data; 163 + struct max8903_pdata *pdata = data->pdata; 164 + bool fault; 165 + 166 + fault = gpio_get_value(pdata->flt) ? false : true; 167 + 168 + if (fault == data->fault) 169 + return IRQ_HANDLED; 170 + 171 + data->fault = fault; 172 + 173 + if (fault) 174 + dev_err(data->dev, "Charger suffers a fault and stops.\n"); 175 + else 176 + dev_err(data->dev, "Charger recovered from a fault.\n"); 177 + 178 + return IRQ_HANDLED; 179 + } 180 + 181 + static __devinit int max8903_probe(struct platform_device *pdev) 182 + { 183 + struct max8903_data *data; 184 + struct device *dev = &pdev->dev; 185 + struct max8903_pdata *pdata = pdev->dev.platform_data; 186 + int ret = 0; 187 + int gpio; 188 + int ta_in = 0; 189 + int usb_in = 0; 190 + 191 + data = kzalloc(sizeof(struct max8903_data), GFP_KERNEL); 192 + if (data == NULL) { 193 + dev_err(dev, "Cannot allocate memory.\n"); 194 + return -ENOMEM; 195 + } 196 + data->pdata = pdata; 197 + data->dev = dev; 198 + platform_set_drvdata(pdev, data); 199 + 200 + if (pdata->dc_valid == false && pdata->usb_valid == false) { 201 + dev_err(dev, "No valid power sources.\n"); 202 + ret = -EINVAL; 203 + goto err; 204 + } 205 + 206 + if (pdata->dc_valid) { 207 + if (pdata->dok && gpio_is_valid(pdata->dok) && 208 + pdata->dcm && gpio_is_valid(pdata->dcm)) { 209 + gpio = pdata->dok; /* PULL_UPed Interrupt */ 210 + ta_in = gpio_get_value(gpio) ? 0 : 1; 211 + 212 + gpio = pdata->dcm; /* Output */ 213 + gpio_set_value(gpio, ta_in); 214 + } else { 215 + dev_err(dev, "When DC is wired, DOK and DCM should" 216 + " be wired as well.\n"); 217 + ret = -EINVAL; 218 + goto err; 219 + } 220 + } else { 221 + if (pdata->dcm) { 222 + if (gpio_is_valid(pdata->dcm)) 223 + gpio_set_value(pdata->dcm, 0); 224 + else { 225 + dev_err(dev, "Invalid pin: dcm.\n"); 226 + ret = -EINVAL; 227 + goto err; 228 + } 229 + } 230 + } 231 + 232 + if (pdata->usb_valid) { 233 + if (pdata->uok && gpio_is_valid(pdata->uok)) { 234 + gpio = pdata->uok; 235 + usb_in = gpio_get_value(gpio) ? 0 : 1; 236 + } else { 237 + dev_err(dev, "When USB is wired, UOK should be wired." 238 + "as well.\n"); 239 + ret = -EINVAL; 240 + goto err; 241 + } 242 + } 243 + 244 + if (pdata->cen) { 245 + if (gpio_is_valid(pdata->cen)) { 246 + gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1); 247 + } else { 248 + dev_err(dev, "Invalid pin: cen.\n"); 249 + ret = -EINVAL; 250 + goto err; 251 + } 252 + } 253 + 254 + if (pdata->chg) { 255 + if (!gpio_is_valid(pdata->chg)) { 256 + dev_err(dev, "Invalid pin: chg.\n"); 257 + ret = -EINVAL; 258 + goto err; 259 + } 260 + } 261 + 262 + if (pdata->flt) { 263 + if (!gpio_is_valid(pdata->flt)) { 264 + dev_err(dev, "Invalid pin: flt.\n"); 265 + ret = -EINVAL; 266 + goto err; 267 + } 268 + } 269 + 270 + if (pdata->usus) { 271 + if (!gpio_is_valid(pdata->usus)) { 272 + dev_err(dev, "Invalid pin: usus.\n"); 273 + ret = -EINVAL; 274 + goto err; 275 + } 276 + } 277 + 278 + data->fault = false; 279 + data->ta_in = ta_in; 280 + data->usb_in = usb_in; 281 + 282 + data->psy.name = "max8903_charger"; 283 + data->psy.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS : 284 + ((usb_in) ? POWER_SUPPLY_TYPE_USB : 285 + POWER_SUPPLY_TYPE_BATTERY); 286 + data->psy.get_property = max8903_get_property; 287 + data->psy.properties = max8903_charger_props; 288 + data->psy.num_properties = ARRAY_SIZE(max8903_charger_props); 289 + 290 + ret = power_supply_register(dev, &data->psy); 291 + if (ret) { 292 + dev_err(dev, "failed: power supply register.\n"); 293 + goto err; 294 + } 295 + 296 + if (pdata->dc_valid) { 297 + ret = request_threaded_irq(gpio_to_irq(pdata->dok), 298 + NULL, max8903_dcin, 299 + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 300 + "MAX8903 DC IN", data); 301 + if (ret) { 302 + dev_err(dev, "Cannot request irq %d for DC (%d)\n", 303 + gpio_to_irq(pdata->dok), ret); 304 + goto err_psy; 305 + } 306 + } 307 + 308 + if (pdata->usb_valid) { 309 + ret = request_threaded_irq(gpio_to_irq(pdata->uok), 310 + NULL, max8903_usbin, 311 + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 312 + "MAX8903 USB IN", data); 313 + if (ret) { 314 + dev_err(dev, "Cannot request irq %d for USB (%d)\n", 315 + gpio_to_irq(pdata->uok), ret); 316 + goto err_dc_irq; 317 + } 318 + } 319 + 320 + if (pdata->flt) { 321 + ret = request_threaded_irq(gpio_to_irq(pdata->flt), 322 + NULL, max8903_fault, 323 + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 324 + "MAX8903 Fault", data); 325 + if (ret) { 326 + dev_err(dev, "Cannot request irq %d for Fault (%d)\n", 327 + gpio_to_irq(pdata->flt), ret); 328 + goto err_usb_irq; 329 + } 330 + } 331 + 332 + return 0; 333 + 334 + err_usb_irq: 335 + if (pdata->usb_valid) 336 + free_irq(gpio_to_irq(pdata->uok), data); 337 + err_dc_irq: 338 + if (pdata->dc_valid) 339 + free_irq(gpio_to_irq(pdata->dok), data); 340 + err_psy: 341 + power_supply_unregister(&data->psy); 342 + err: 343 + kfree(data); 344 + return ret; 345 + } 346 + 347 + static __devexit int max8903_remove(struct platform_device *pdev) 348 + { 349 + struct max8903_data *data = platform_get_drvdata(pdev); 350 + 351 + if (data) { 352 + struct max8903_pdata *pdata = data->pdata; 353 + 354 + if (pdata->flt) 355 + free_irq(gpio_to_irq(pdata->flt), data); 356 + if (pdata->usb_valid) 357 + free_irq(gpio_to_irq(pdata->uok), data); 358 + if (pdata->dc_valid) 359 + free_irq(gpio_to_irq(pdata->dok), data); 360 + power_supply_unregister(&data->psy); 361 + kfree(data); 362 + } 363 + 364 + return 0; 365 + } 366 + 367 + static struct platform_driver max8903_driver = { 368 + .probe = max8903_probe, 369 + .remove = __devexit_p(max8903_remove), 370 + .driver = { 371 + .name = "max8903-charger", 372 + .owner = THIS_MODULE, 373 + }, 374 + }; 375 + 376 + static int __init max8903_init(void) 377 + { 378 + return platform_driver_register(&max8903_driver); 379 + } 380 + module_init(max8903_init); 381 + 382 + static void __exit max8903_exit(void) 383 + { 384 + platform_driver_unregister(&max8903_driver); 385 + } 386 + module_exit(max8903_exit); 387 + 388 + MODULE_LICENSE("GPL"); 389 + MODULE_DESCRIPTION("MAX8903 Charger Driver"); 390 + MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 391 + MODULE_ALIAS("max8903-charger");
+266 -10
drivers/power/test_power.c
··· 3 3 * 4 4 * Copyright 2010 Anton Vorontsov <cbouatmailru@gmail.com> 5 5 * 6 + * Dynamic module parameter code from the Virtual Battery Driver 7 + * Copyright (C) 2008 Pylone, Inc. 8 + * By: Masashi YOKOTA <yokota@pylone.jp> 9 + * Originally found here: 10 + * http://downloads.pylone.jp/src/virtual_battery/virtual_battery-0.0.1.tar.bz2 11 + * 6 12 * This program is free software; you can redistribute it and/or modify 7 13 * it under the terms of the GNU General Public License version 2 as 8 14 * published by the Free Software Foundation. ··· 21 15 #include <linux/delay.h> 22 16 #include <linux/vermagic.h> 23 17 24 - static int test_power_ac_online = 1; 25 - static int test_power_battery_status = POWER_SUPPLY_STATUS_CHARGING; 18 + static int ac_online = 1; 19 + static int battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 20 + static int battery_health = POWER_SUPPLY_HEALTH_GOOD; 21 + static int battery_present = 1; /* true */ 22 + static int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION; 23 + static int battery_capacity = 50; 26 24 27 25 static int test_power_get_ac_property(struct power_supply *psy, 28 26 enum power_supply_property psp, ··· 34 24 { 35 25 switch (psp) { 36 26 case POWER_SUPPLY_PROP_ONLINE: 37 - val->intval = test_power_ac_online; 27 + val->intval = ac_online; 38 28 break; 39 29 default: 40 30 return -EINVAL; ··· 57 47 val->strval = UTS_RELEASE; 58 48 break; 59 49 case POWER_SUPPLY_PROP_STATUS: 60 - val->intval = test_power_battery_status; 50 + val->intval = battery_status; 61 51 break; 62 52 case POWER_SUPPLY_PROP_CHARGE_TYPE: 63 53 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 64 54 break; 65 55 case POWER_SUPPLY_PROP_HEALTH: 66 - val->intval = POWER_SUPPLY_HEALTH_GOOD; 56 + val->intval = battery_health; 57 + break; 58 + case POWER_SUPPLY_PROP_PRESENT: 59 + val->intval = battery_present; 67 60 break; 68 61 case POWER_SUPPLY_PROP_TECHNOLOGY: 69 - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 62 + val->intval = battery_technology; 70 63 break; 71 64 case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 72 65 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 73 66 break; 74 67 case POWER_SUPPLY_PROP_CAPACITY: 75 - val->intval = 50; 68 + case POWER_SUPPLY_PROP_CHARGE_NOW: 69 + val->intval = battery_capacity; 70 + break; 71 + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 72 + case POWER_SUPPLY_PROP_CHARGE_FULL: 73 + val->intval = 100; 76 74 break; 77 75 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 78 76 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: ··· 102 84 POWER_SUPPLY_PROP_STATUS, 103 85 POWER_SUPPLY_PROP_CHARGE_TYPE, 104 86 POWER_SUPPLY_PROP_HEALTH, 87 + POWER_SUPPLY_PROP_PRESENT, 105 88 POWER_SUPPLY_PROP_TECHNOLOGY, 89 + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 106 90 POWER_SUPPLY_PROP_CHARGE_FULL, 107 - POWER_SUPPLY_PROP_CHARGE_EMPTY, 91 + POWER_SUPPLY_PROP_CHARGE_NOW, 108 92 POWER_SUPPLY_PROP_CAPACITY, 109 93 POWER_SUPPLY_PROP_CAPACITY_LEVEL, 110 94 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, ··· 138 118 }, 139 119 }; 140 120 121 + 141 122 static int __init test_power_init(void) 142 123 { 143 124 int i; ··· 166 145 int i; 167 146 168 147 /* Let's see how we handle changes... */ 169 - test_power_ac_online = 0; 170 - test_power_battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 148 + ac_online = 0; 149 + battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 171 150 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 172 151 power_supply_changed(&test_power_supplies[i]); 173 152 pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", ··· 178 157 power_supply_unregister(&test_power_supplies[i]); 179 158 } 180 159 module_exit(test_power_exit); 160 + 161 + 162 + 163 + #define MAX_KEYLENGTH 256 164 + struct battery_property_map { 165 + int value; 166 + char const *key; 167 + }; 168 + 169 + static struct battery_property_map map_ac_online[] = { 170 + { 0, "on" }, 171 + { 1, "off" }, 172 + { -1, NULL }, 173 + }; 174 + 175 + static struct battery_property_map map_status[] = { 176 + { POWER_SUPPLY_STATUS_CHARGING, "charging" }, 177 + { POWER_SUPPLY_STATUS_DISCHARGING, "discharging" }, 178 + { POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" }, 179 + { POWER_SUPPLY_STATUS_FULL, "full" }, 180 + { -1, NULL }, 181 + }; 182 + 183 + static struct battery_property_map map_health[] = { 184 + { POWER_SUPPLY_HEALTH_GOOD, "good" }, 185 + { POWER_SUPPLY_HEALTH_OVERHEAT, "overheat" }, 186 + { POWER_SUPPLY_HEALTH_DEAD, "dead" }, 187 + { POWER_SUPPLY_HEALTH_OVERVOLTAGE, "overvoltage" }, 188 + { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure" }, 189 + { -1, NULL }, 190 + }; 191 + 192 + static struct battery_property_map map_present[] = { 193 + { 0, "false" }, 194 + { 1, "true" }, 195 + { -1, NULL }, 196 + }; 197 + 198 + static struct battery_property_map map_technology[] = { 199 + { POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" }, 200 + { POWER_SUPPLY_TECHNOLOGY_LION, "LION" }, 201 + { POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" }, 202 + { POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" }, 203 + { POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" }, 204 + { POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" }, 205 + { -1, NULL }, 206 + }; 207 + 208 + 209 + static int map_get_value(struct battery_property_map *map, const char *key, 210 + int def_val) 211 + { 212 + char buf[MAX_KEYLENGTH]; 213 + int cr; 214 + 215 + strncpy(buf, key, MAX_KEYLENGTH); 216 + buf[MAX_KEYLENGTH-1] = '\0'; 217 + 218 + cr = strnlen(buf, MAX_KEYLENGTH) - 1; 219 + if (buf[cr] == '\n') 220 + buf[cr] = '\0'; 221 + 222 + while (map->key) { 223 + if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0) 224 + return map->value; 225 + map++; 226 + } 227 + 228 + return def_val; 229 + } 230 + 231 + 232 + static const char *map_get_key(struct battery_property_map *map, int value, 233 + const char *def_key) 234 + { 235 + while (map->key) { 236 + if (map->value == value) 237 + return map->key; 238 + map++; 239 + } 240 + 241 + return def_key; 242 + } 243 + 244 + static int param_set_ac_online(const char *key, const struct kernel_param *kp) 245 + { 246 + ac_online = map_get_value(map_ac_online, key, ac_online); 247 + power_supply_changed(&test_power_supplies[0]); 248 + return 0; 249 + } 250 + 251 + static int param_get_ac_online(char *buffer, const struct kernel_param *kp) 252 + { 253 + strcpy(buffer, map_get_key(map_ac_online, ac_online, "unknown")); 254 + return strlen(buffer); 255 + } 256 + 257 + static int param_set_battery_status(const char *key, 258 + const struct kernel_param *kp) 259 + { 260 + battery_status = map_get_value(map_status, key, battery_status); 261 + power_supply_changed(&test_power_supplies[1]); 262 + return 0; 263 + } 264 + 265 + static int param_get_battery_status(char *buffer, const struct kernel_param *kp) 266 + { 267 + strcpy(buffer, map_get_key(map_status, battery_status, "unknown")); 268 + return strlen(buffer); 269 + } 270 + 271 + static int param_set_battery_health(const char *key, 272 + const struct kernel_param *kp) 273 + { 274 + battery_health = map_get_value(map_health, key, battery_health); 275 + power_supply_changed(&test_power_supplies[1]); 276 + return 0; 277 + } 278 + 279 + static int param_get_battery_health(char *buffer, const struct kernel_param *kp) 280 + { 281 + strcpy(buffer, map_get_key(map_health, battery_health, "unknown")); 282 + return strlen(buffer); 283 + } 284 + 285 + static int param_set_battery_present(const char *key, 286 + const struct kernel_param *kp) 287 + { 288 + battery_present = map_get_value(map_present, key, battery_present); 289 + power_supply_changed(&test_power_supplies[0]); 290 + return 0; 291 + } 292 + 293 + static int param_get_battery_present(char *buffer, 294 + const struct kernel_param *kp) 295 + { 296 + strcpy(buffer, map_get_key(map_present, battery_present, "unknown")); 297 + return strlen(buffer); 298 + } 299 + 300 + static int param_set_battery_technology(const char *key, 301 + const struct kernel_param *kp) 302 + { 303 + battery_technology = map_get_value(map_technology, key, 304 + battery_technology); 305 + power_supply_changed(&test_power_supplies[1]); 306 + return 0; 307 + } 308 + 309 + static int param_get_battery_technology(char *buffer, 310 + const struct kernel_param *kp) 311 + { 312 + strcpy(buffer, 313 + map_get_key(map_technology, battery_technology, "unknown")); 314 + return strlen(buffer); 315 + } 316 + 317 + static int param_set_battery_capacity(const char *key, 318 + const struct kernel_param *kp) 319 + { 320 + int tmp; 321 + 322 + if (1 != sscanf(key, "%d", &tmp)) 323 + return -EINVAL; 324 + 325 + battery_capacity = tmp; 326 + power_supply_changed(&test_power_supplies[1]); 327 + return 0; 328 + } 329 + 330 + #define param_get_battery_capacity param_get_int 331 + 332 + 333 + 334 + static struct kernel_param_ops param_ops_ac_online = { 335 + .set = param_set_ac_online, 336 + .get = param_get_ac_online, 337 + }; 338 + 339 + static struct kernel_param_ops param_ops_battery_status = { 340 + .set = param_set_battery_status, 341 + .get = param_get_battery_status, 342 + }; 343 + 344 + static struct kernel_param_ops param_ops_battery_present = { 345 + .set = param_set_battery_present, 346 + .get = param_get_battery_present, 347 + }; 348 + 349 + static struct kernel_param_ops param_ops_battery_technology = { 350 + .set = param_set_battery_technology, 351 + .get = param_get_battery_technology, 352 + }; 353 + 354 + static struct kernel_param_ops param_ops_battery_health = { 355 + .set = param_set_battery_health, 356 + .get = param_get_battery_health, 357 + }; 358 + 359 + static struct kernel_param_ops param_ops_battery_capacity = { 360 + .set = param_set_battery_capacity, 361 + .get = param_get_battery_capacity, 362 + }; 363 + 364 + 365 + #define param_check_ac_online(name, p) __param_check(name, p, void); 366 + #define param_check_battery_status(name, p) __param_check(name, p, void); 367 + #define param_check_battery_present(name, p) __param_check(name, p, void); 368 + #define param_check_battery_technology(name, p) __param_check(name, p, void); 369 + #define param_check_battery_health(name, p) __param_check(name, p, void); 370 + #define param_check_battery_capacity(name, p) __param_check(name, p, void); 371 + 372 + 373 + module_param(ac_online, ac_online, 0644); 374 + MODULE_PARM_DESC(ac_online, "AC charging state <on|off>"); 375 + 376 + module_param(battery_status, battery_status, 0644); 377 + MODULE_PARM_DESC(battery_status, 378 + "battery status <charging|discharging|not-charging|full>"); 379 + 380 + module_param(battery_present, battery_present, 0644); 381 + MODULE_PARM_DESC(battery_present, 382 + "battery presence state <good|overheat|dead|overvoltage|failure>"); 383 + 384 + module_param(battery_technology, battery_technology, 0644); 385 + MODULE_PARM_DESC(battery_technology, 386 + "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>"); 387 + 388 + module_param(battery_health, battery_health, 0644); 389 + MODULE_PARM_DESC(battery_health, 390 + "battery health state <good|overheat|dead|overvoltage|failure>"); 391 + 392 + module_param(battery_capacity, battery_capacity, 0644); 393 + MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)"); 394 + 181 395 182 396 MODULE_DESCRIPTION("Power supply driver for testing"); 183 397 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
+14 -6
drivers/power/z2_battery.c
··· 271 271 } 272 272 273 273 #ifdef CONFIG_PM 274 - static int z2_batt_suspend(struct i2c_client *client, pm_message_t state) 274 + static int z2_batt_suspend(struct device *dev) 275 275 { 276 + struct i2c_client *client = to_i2c_client(dev); 276 277 struct z2_charger *charger = i2c_get_clientdata(client); 277 278 278 279 flush_work_sync(&charger->bat_work); 279 280 return 0; 280 281 } 281 282 282 - static int z2_batt_resume(struct i2c_client *client) 283 + static int z2_batt_resume(struct device *dev) 283 284 { 285 + struct i2c_client *client = to_i2c_client(dev); 284 286 struct z2_charger *charger = i2c_get_clientdata(client); 285 287 286 288 schedule_work(&charger->bat_work); 287 289 return 0; 288 290 } 291 + 292 + static const struct dev_pm_ops z2_battery_pm_ops = { 293 + .suspend = z2_batt_suspend, 294 + .resume = z2_batt_resume, 295 + }; 296 + 297 + #define Z2_BATTERY_PM_OPS (&z2_battery_pm_ops) 298 + 289 299 #else 290 - #define z2_batt_suspend NULL 291 - #define z2_batt_resume NULL 300 + #define Z2_BATTERY_PM_OPS (NULL) 292 301 #endif 293 302 294 303 static const struct i2c_device_id z2_batt_id[] = { ··· 310 301 .driver = { 311 302 .name = "z2-battery", 312 303 .owner = THIS_MODULE, 304 + .pm = Z2_BATTERY_PM_OPS 313 305 }, 314 306 .probe = z2_batt_probe, 315 307 .remove = z2_batt_remove, 316 - .suspend = z2_batt_suspend, 317 - .resume = z2_batt_resume, 318 308 .id_table = z2_batt_id, 319 309 }; 320 310
+29
include/linux/power/isp1704_charger.h
··· 1 + /* 2 + * ISP1704 USB Charger Detection driver 3 + * 4 + * Copyright (C) 2011 Nokia Corporation 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + 22 + #ifndef __ISP1704_CHARGER_H 23 + #define __ISP1704_CHARGER_H 24 + 25 + struct isp1704_charger_data { 26 + void (*set_power)(bool on); 27 + }; 28 + 29 + #endif
+57
include/linux/power/max8903_charger.h
··· 1 + /* 2 + * max8903_charger.h - Maxim 8903 USB/Adapter Charger Driver 3 + * 4 + * Copyright (C) 2011 Samsung Electronics 5 + * MyungJoo Ham <myungjoo.ham@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + * 21 + */ 22 + 23 + #ifndef __MAX8903_CHARGER_H__ 24 + #define __MAX8903_CHARGER_H__ 25 + 26 + struct max8903_pdata { 27 + /* 28 + * GPIOs 29 + * cen, chg, flt, and usus are optional. 30 + * dok, dcm, and uok are not optional depending on the status of 31 + * dc_valid and usb_valid. 32 + */ 33 + int cen; /* Charger Enable input */ 34 + int dok; /* DC(Adapter) Power OK output */ 35 + int uok; /* USB Power OK output */ 36 + int chg; /* Charger status output */ 37 + int flt; /* Fault output */ 38 + int dcm; /* Current-Limit Mode input (1: DC, 2: USB) */ 39 + int usus; /* USB Suspend Input (1: suspended) */ 40 + 41 + /* 42 + * DC(Adapter/TA) is wired 43 + * When dc_valid is true, 44 + * dok and dcm should be valid. 45 + * 46 + * At least one of dc_valid or usb_valid should be true. 47 + */ 48 + bool dc_valid; 49 + /* 50 + * USB is wired 51 + * When usb_valid is true, 52 + * uok should be valid. 53 + */ 54 + bool usb_valid; 55 + }; 56 + 57 + #endif /* __MAX8903_CHARGER_H__ */