Commit ea0ca3a843babd50c22dfbb5cf2d9a14df821b2b
Exists in
master
and in
4 other branches
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
Showing 12 changed files Side-by-side Diff
- arch/arm/mach-omap2/board-rx51-peripherals.c
- drivers/power/Kconfig
- drivers/power/Makefile
- drivers/power/bq27x00_battery.c
- drivers/power/ds2760_battery.c
- drivers/power/gpio-charger.c
- drivers/power/isp1704_charger.c
- drivers/power/max8903_charger.c
- drivers/power/test_power.c
- drivers/power/z2_battery.c
- include/linux/power/isp1704_charger.h
- include/linux/power/max8903_charger.h
arch/arm/mach-omap2/board-rx51-peripherals.c
... | ... | @@ -23,6 +23,7 @@ |
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,6 +54,8 @@ |
53 | 54 | #define RX51_FMTX_RESET_GPIO 163 |
54 | 55 | #define RX51_FMTX_IRQ 53 |
55 | 56 | |
57 | +#define RX51_USB_TRANSCEIVER_RST_GPIO 67 | |
58 | + | |
56 | 59 | /* list all spi devices here */ |
57 | 60 | enum { |
58 | 61 | RX51_SPI_WL1251, |
59 | 62 | |
60 | 63 | |
... | ... | @@ -111,10 +114,30 @@ |
111 | 114 | }, |
112 | 115 | }; |
113 | 116 | |
117 | +static void rx51_charger_set_power(bool on) | |
118 | +{ | |
119 | + gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on); | |
120 | +} | |
121 | + | |
122 | +static struct isp1704_charger_data rx51_charger_data = { | |
123 | + .set_power = rx51_charger_set_power, | |
124 | +}; | |
125 | + | |
114 | 126 | static struct platform_device rx51_charger_device = { |
115 | - .name = "isp1704_charger", | |
127 | + .name = "isp1704_charger", | |
128 | + .dev = { | |
129 | + .platform_data = &rx51_charger_data, | |
130 | + }, | |
116 | 131 | }; |
117 | 132 | |
133 | +static void __init rx51_charger_init(void) | |
134 | +{ | |
135 | + WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, | |
136 | + GPIOF_OUT_INIT_LOW, "isp1704_reset")); | |
137 | + | |
138 | + platform_device_register(&rx51_charger_device); | |
139 | +} | |
140 | + | |
118 | 141 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) |
119 | 142 | |
120 | 143 | #define RX51_GPIO_CAMERA_LENS_COVER 110 |
... | ... | @@ -961,6 +984,6 @@ |
961 | 984 | if (partition) |
962 | 985 | omap2_hsmmc_init(mmc); |
963 | 986 | |
964 | - platform_device_register(&rx51_charger_device); | |
987 | + rx51_charger_init(); | |
965 | 988 | } |
drivers/power/Kconfig
... | ... | @@ -210,6 +210,15 @@ |
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 |
drivers/power/Makefile
... | ... | @@ -33,6 +33,7 @@ |
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 |
drivers/power/bq27x00_battery.c
... | ... | @@ -4,6 +4,7 @@ |
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 | * |
... | ... | @@ -76,7 +77,7 @@ |
76 | 77 | int time_to_empty_avg; |
77 | 78 | int time_to_full; |
78 | 79 | int charge_full; |
79 | - int charge_counter; | |
80 | + int cycle_count; | |
80 | 81 | int capacity; |
81 | 82 | int flags; |
82 | 83 | |
... | ... | @@ -115,7 +116,7 @@ |
115 | 116 | POWER_SUPPLY_PROP_CHARGE_FULL, |
116 | 117 | POWER_SUPPLY_PROP_CHARGE_NOW, |
117 | 118 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, |
118 | - POWER_SUPPLY_PROP_CHARGE_COUNTER, | |
119 | + POWER_SUPPLY_PROP_CYCLE_COUNT, | |
119 | 120 | POWER_SUPPLY_PROP_ENERGY_NOW, |
120 | 121 | }; |
121 | 122 | |
... | ... | @@ -267,7 +268,7 @@ |
267 | 268 | cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP); |
268 | 269 | cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF); |
269 | 270 | cache.charge_full = bq27x00_battery_read_lmd(di); |
270 | - cache.charge_counter = bq27x00_battery_read_cyct(di); | |
271 | + cache.cycle_count = bq27x00_battery_read_cyct(di); | |
271 | 272 | |
272 | 273 | if (!is_bq27500) |
273 | 274 | cache.current_now = bq27x00_read(di, BQ27x00_REG_AI, false); |
... | ... | @@ -496,8 +497,8 @@ |
496 | 497 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: |
497 | 498 | ret = bq27x00_simple_value(di->charge_design_full, val); |
498 | 499 | break; |
499 | - case POWER_SUPPLY_PROP_CHARGE_COUNTER: | |
500 | - ret = bq27x00_simple_value(di->cache.charge_counter, val); | |
500 | + case POWER_SUPPLY_PROP_CYCLE_COUNT: | |
501 | + ret = bq27x00_simple_value(di->cache.cycle_count, val); | |
501 | 502 | break; |
502 | 503 | case POWER_SUPPLY_PROP_ENERGY_NOW: |
503 | 504 | ret = bq27x00_battery_energy(di, val); |
drivers/power/ds2760_battery.c
... | ... | @@ -86,7 +86,11 @@ |
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 */ |
... | ... | @@ -186,7 +190,7 @@ |
186 | 190 | |
187 | 191 | scale[0] = di->full_active_uAh; |
188 | 192 | for (i = 1; i < 5; i++) |
189 | - scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i]; | |
193 | + scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 1 + i]; | |
190 | 194 | |
191 | 195 | di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10); |
192 | 196 | di->full_active_uAh *= 1000; /* convert to ยตAh */ |
drivers/power/gpio-charger.c
... | ... | @@ -161,12 +161,27 @@ |
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 |
drivers/power/isp1704_charger.c
... | ... | @@ -33,6 +33,7 @@ |
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 |
... | ... | @@ -71,6 +72,18 @@ |
71 | 72 | }; |
72 | 73 | |
73 | 74 | /* |
75 | + * Disable/enable the power from the isp1704 if a function for it | |
76 | + * has been provided with platform data. | |
77 | + */ | |
78 | +static void isp1704_charger_set_power(struct isp1704_charger *isp, bool on) | |
79 | +{ | |
80 | + struct isp1704_charger_data *board = isp->dev->platform_data; | |
81 | + | |
82 | + if (board->set_power) | |
83 | + board->set_power(on); | |
84 | +} | |
85 | + | |
86 | +/* | |
74 | 87 | * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB |
75 | 88 | * chargers). |
76 | 89 | * |
... | ... | @@ -222,6 +235,9 @@ |
222 | 235 | |
223 | 236 | mutex_lock(&lock); |
224 | 237 | |
238 | + if (event != USB_EVENT_NONE) | |
239 | + isp1704_charger_set_power(isp, 1); | |
240 | + | |
225 | 241 | switch (event) { |
226 | 242 | case USB_EVENT_VBUS: |
227 | 243 | isp->online = true; |
... | ... | @@ -269,6 +285,8 @@ |
269 | 285 | */ |
270 | 286 | if (isp->otg->gadget) |
271 | 287 | usb_gadget_disconnect(isp->otg->gadget); |
288 | + | |
289 | + isp1704_charger_set_power(isp, 0); | |
272 | 290 | break; |
273 | 291 | case USB_EVENT_ENUMERATED: |
274 | 292 | if (isp->present) |
... | ... | @@ -394,6 +412,8 @@ |
394 | 412 | isp->dev = &pdev->dev; |
395 | 413 | platform_set_drvdata(pdev, isp); |
396 | 414 | |
415 | + isp1704_charger_set_power(isp, 1); | |
416 | + | |
397 | 417 | ret = isp1704_test_ulpi(isp); |
398 | 418 | if (ret < 0) |
399 | 419 | goto fail1; |
... | ... | @@ -434,6 +454,7 @@ |
434 | 454 | |
435 | 455 | /* Detect charger if VBUS is valid (the cable was already plugged). */ |
436 | 456 | ret = otg_io_read(isp->otg, ULPI_USB_INT_STS); |
457 | + isp1704_charger_set_power(isp, 0); | |
437 | 458 | if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) { |
438 | 459 | isp->event = USB_EVENT_VBUS; |
439 | 460 | schedule_work(&isp->work); |
... | ... | @@ -459,6 +480,7 @@ |
459 | 480 | otg_unregister_notifier(isp->otg, &isp->nb); |
460 | 481 | power_supply_unregister(&isp->psy); |
461 | 482 | otg_put_transceiver(isp->otg); |
483 | + isp1704_charger_set_power(isp, 0); | |
462 | 484 | kfree(isp); |
463 | 485 | |
464 | 486 | return 0; |
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"); |
drivers/power/test_power.c
... | ... | @@ -3,6 +3,12 @@ |
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. |
... | ... | @@ -15,8 +21,12 @@ |
15 | 21 | #include <linux/delay.h> |
16 | 22 | #include <linux/vermagic.h> |
17 | 23 | |
18 | -static int test_power_ac_online = 1; | |
19 | -static int test_power_battery_status = POWER_SUPPLY_STATUS_CHARGING; | |
24 | +static int ac_online = 1; | |
25 | +static int battery_status = POWER_SUPPLY_STATUS_DISCHARGING; | |
26 | +static int battery_health = POWER_SUPPLY_HEALTH_GOOD; | |
27 | +static int battery_present = 1; /* true */ | |
28 | +static int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION; | |
29 | +static int battery_capacity = 50; | |
20 | 30 | |
21 | 31 | static int test_power_get_ac_property(struct power_supply *psy, |
22 | 32 | enum power_supply_property psp, |
... | ... | @@ -24,7 +34,7 @@ |
24 | 34 | { |
25 | 35 | switch (psp) { |
26 | 36 | case POWER_SUPPLY_PROP_ONLINE: |
27 | - val->intval = test_power_ac_online; | |
37 | + val->intval = ac_online; | |
28 | 38 | break; |
29 | 39 | default: |
30 | 40 | return -EINVAL; |
31 | 41 | |
32 | 42 | |
33 | 43 | |
34 | 44 | |
35 | 45 | |
... | ... | @@ -47,23 +57,31 @@ |
47 | 57 | val->strval = UTS_RELEASE; |
48 | 58 | break; |
49 | 59 | case POWER_SUPPLY_PROP_STATUS: |
50 | - val->intval = test_power_battery_status; | |
60 | + val->intval = battery_status; | |
51 | 61 | break; |
52 | 62 | case POWER_SUPPLY_PROP_CHARGE_TYPE: |
53 | 63 | val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; |
54 | 64 | break; |
55 | 65 | case POWER_SUPPLY_PROP_HEALTH: |
56 | - val->intval = POWER_SUPPLY_HEALTH_GOOD; | |
66 | + val->intval = battery_health; | |
57 | 67 | break; |
68 | + case POWER_SUPPLY_PROP_PRESENT: | |
69 | + val->intval = battery_present; | |
70 | + break; | |
58 | 71 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
59 | - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; | |
72 | + val->intval = battery_technology; | |
60 | 73 | break; |
61 | 74 | case POWER_SUPPLY_PROP_CAPACITY_LEVEL: |
62 | 75 | val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; |
63 | 76 | break; |
64 | 77 | case POWER_SUPPLY_PROP_CAPACITY: |
65 | - val->intval = 50; | |
78 | + case POWER_SUPPLY_PROP_CHARGE_NOW: | |
79 | + val->intval = battery_capacity; | |
66 | 80 | break; |
81 | + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | |
82 | + case POWER_SUPPLY_PROP_CHARGE_FULL: | |
83 | + val->intval = 100; | |
84 | + break; | |
67 | 85 | case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: |
68 | 86 | case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: |
69 | 87 | val->intval = 3600; |
70 | 88 | |
71 | 89 | |
... | ... | @@ -84,9 +102,11 @@ |
84 | 102 | POWER_SUPPLY_PROP_STATUS, |
85 | 103 | POWER_SUPPLY_PROP_CHARGE_TYPE, |
86 | 104 | POWER_SUPPLY_PROP_HEALTH, |
105 | + POWER_SUPPLY_PROP_PRESENT, | |
87 | 106 | POWER_SUPPLY_PROP_TECHNOLOGY, |
107 | + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | |
88 | 108 | POWER_SUPPLY_PROP_CHARGE_FULL, |
89 | - POWER_SUPPLY_PROP_CHARGE_EMPTY, | |
109 | + POWER_SUPPLY_PROP_CHARGE_NOW, | |
90 | 110 | POWER_SUPPLY_PROP_CAPACITY, |
91 | 111 | POWER_SUPPLY_PROP_CAPACITY_LEVEL, |
92 | 112 | POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, |
... | ... | @@ -118,6 +138,7 @@ |
118 | 138 | }, |
119 | 139 | }; |
120 | 140 | |
141 | + | |
121 | 142 | static int __init test_power_init(void) |
122 | 143 | { |
123 | 144 | int i; |
... | ... | @@ -145,8 +166,8 @@ |
145 | 166 | int i; |
146 | 167 | |
147 | 168 | /* Let's see how we handle changes... */ |
148 | - test_power_ac_online = 0; | |
149 | - test_power_battery_status = POWER_SUPPLY_STATUS_DISCHARGING; | |
169 | + ac_online = 0; | |
170 | + battery_status = POWER_SUPPLY_STATUS_DISCHARGING; | |
150 | 171 | for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) |
151 | 172 | power_supply_changed(&test_power_supplies[i]); |
152 | 173 | pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", |
... | ... | @@ -157,6 +178,241 @@ |
157 | 178 | power_supply_unregister(&test_power_supplies[i]); |
158 | 179 | } |
159 | 180 | module_exit(test_power_exit); |
181 | + | |
182 | + | |
183 | + | |
184 | +#define MAX_KEYLENGTH 256 | |
185 | +struct battery_property_map { | |
186 | + int value; | |
187 | + char const *key; | |
188 | +}; | |
189 | + | |
190 | +static struct battery_property_map map_ac_online[] = { | |
191 | + { 0, "on" }, | |
192 | + { 1, "off" }, | |
193 | + { -1, NULL }, | |
194 | +}; | |
195 | + | |
196 | +static struct battery_property_map map_status[] = { | |
197 | + { POWER_SUPPLY_STATUS_CHARGING, "charging" }, | |
198 | + { POWER_SUPPLY_STATUS_DISCHARGING, "discharging" }, | |
199 | + { POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" }, | |
200 | + { POWER_SUPPLY_STATUS_FULL, "full" }, | |
201 | + { -1, NULL }, | |
202 | +}; | |
203 | + | |
204 | +static struct battery_property_map map_health[] = { | |
205 | + { POWER_SUPPLY_HEALTH_GOOD, "good" }, | |
206 | + { POWER_SUPPLY_HEALTH_OVERHEAT, "overheat" }, | |
207 | + { POWER_SUPPLY_HEALTH_DEAD, "dead" }, | |
208 | + { POWER_SUPPLY_HEALTH_OVERVOLTAGE, "overvoltage" }, | |
209 | + { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure" }, | |
210 | + { -1, NULL }, | |
211 | +}; | |
212 | + | |
213 | +static struct battery_property_map map_present[] = { | |
214 | + { 0, "false" }, | |
215 | + { 1, "true" }, | |
216 | + { -1, NULL }, | |
217 | +}; | |
218 | + | |
219 | +static struct battery_property_map map_technology[] = { | |
220 | + { POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" }, | |
221 | + { POWER_SUPPLY_TECHNOLOGY_LION, "LION" }, | |
222 | + { POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" }, | |
223 | + { POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" }, | |
224 | + { POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" }, | |
225 | + { POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" }, | |
226 | + { -1, NULL }, | |
227 | +}; | |
228 | + | |
229 | + | |
230 | +static int map_get_value(struct battery_property_map *map, const char *key, | |
231 | + int def_val) | |
232 | +{ | |
233 | + char buf[MAX_KEYLENGTH]; | |
234 | + int cr; | |
235 | + | |
236 | + strncpy(buf, key, MAX_KEYLENGTH); | |
237 | + buf[MAX_KEYLENGTH-1] = '\0'; | |
238 | + | |
239 | + cr = strnlen(buf, MAX_KEYLENGTH) - 1; | |
240 | + if (buf[cr] == '\n') | |
241 | + buf[cr] = '\0'; | |
242 | + | |
243 | + while (map->key) { | |
244 | + if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0) | |
245 | + return map->value; | |
246 | + map++; | |
247 | + } | |
248 | + | |
249 | + return def_val; | |
250 | +} | |
251 | + | |
252 | + | |
253 | +static const char *map_get_key(struct battery_property_map *map, int value, | |
254 | + const char *def_key) | |
255 | +{ | |
256 | + while (map->key) { | |
257 | + if (map->value == value) | |
258 | + return map->key; | |
259 | + map++; | |
260 | + } | |
261 | + | |
262 | + return def_key; | |
263 | +} | |
264 | + | |
265 | +static int param_set_ac_online(const char *key, const struct kernel_param *kp) | |
266 | +{ | |
267 | + ac_online = map_get_value(map_ac_online, key, ac_online); | |
268 | + power_supply_changed(&test_power_supplies[0]); | |
269 | + return 0; | |
270 | +} | |
271 | + | |
272 | +static int param_get_ac_online(char *buffer, const struct kernel_param *kp) | |
273 | +{ | |
274 | + strcpy(buffer, map_get_key(map_ac_online, ac_online, "unknown")); | |
275 | + return strlen(buffer); | |
276 | +} | |
277 | + | |
278 | +static int param_set_battery_status(const char *key, | |
279 | + const struct kernel_param *kp) | |
280 | +{ | |
281 | + battery_status = map_get_value(map_status, key, battery_status); | |
282 | + power_supply_changed(&test_power_supplies[1]); | |
283 | + return 0; | |
284 | +} | |
285 | + | |
286 | +static int param_get_battery_status(char *buffer, const struct kernel_param *kp) | |
287 | +{ | |
288 | + strcpy(buffer, map_get_key(map_status, battery_status, "unknown")); | |
289 | + return strlen(buffer); | |
290 | +} | |
291 | + | |
292 | +static int param_set_battery_health(const char *key, | |
293 | + const struct kernel_param *kp) | |
294 | +{ | |
295 | + battery_health = map_get_value(map_health, key, battery_health); | |
296 | + power_supply_changed(&test_power_supplies[1]); | |
297 | + return 0; | |
298 | +} | |
299 | + | |
300 | +static int param_get_battery_health(char *buffer, const struct kernel_param *kp) | |
301 | +{ | |
302 | + strcpy(buffer, map_get_key(map_health, battery_health, "unknown")); | |
303 | + return strlen(buffer); | |
304 | +} | |
305 | + | |
306 | +static int param_set_battery_present(const char *key, | |
307 | + const struct kernel_param *kp) | |
308 | +{ | |
309 | + battery_present = map_get_value(map_present, key, battery_present); | |
310 | + power_supply_changed(&test_power_supplies[0]); | |
311 | + return 0; | |
312 | +} | |
313 | + | |
314 | +static int param_get_battery_present(char *buffer, | |
315 | + const struct kernel_param *kp) | |
316 | +{ | |
317 | + strcpy(buffer, map_get_key(map_present, battery_present, "unknown")); | |
318 | + return strlen(buffer); | |
319 | +} | |
320 | + | |
321 | +static int param_set_battery_technology(const char *key, | |
322 | + const struct kernel_param *kp) | |
323 | +{ | |
324 | + battery_technology = map_get_value(map_technology, key, | |
325 | + battery_technology); | |
326 | + power_supply_changed(&test_power_supplies[1]); | |
327 | + return 0; | |
328 | +} | |
329 | + | |
330 | +static int param_get_battery_technology(char *buffer, | |
331 | + const struct kernel_param *kp) | |
332 | +{ | |
333 | + strcpy(buffer, | |
334 | + map_get_key(map_technology, battery_technology, "unknown")); | |
335 | + return strlen(buffer); | |
336 | +} | |
337 | + | |
338 | +static int param_set_battery_capacity(const char *key, | |
339 | + const struct kernel_param *kp) | |
340 | +{ | |
341 | + int tmp; | |
342 | + | |
343 | + if (1 != sscanf(key, "%d", &tmp)) | |
344 | + return -EINVAL; | |
345 | + | |
346 | + battery_capacity = tmp; | |
347 | + power_supply_changed(&test_power_supplies[1]); | |
348 | + return 0; | |
349 | +} | |
350 | + | |
351 | +#define param_get_battery_capacity param_get_int | |
352 | + | |
353 | + | |
354 | + | |
355 | +static struct kernel_param_ops param_ops_ac_online = { | |
356 | + .set = param_set_ac_online, | |
357 | + .get = param_get_ac_online, | |
358 | +}; | |
359 | + | |
360 | +static struct kernel_param_ops param_ops_battery_status = { | |
361 | + .set = param_set_battery_status, | |
362 | + .get = param_get_battery_status, | |
363 | +}; | |
364 | + | |
365 | +static struct kernel_param_ops param_ops_battery_present = { | |
366 | + .set = param_set_battery_present, | |
367 | + .get = param_get_battery_present, | |
368 | +}; | |
369 | + | |
370 | +static struct kernel_param_ops param_ops_battery_technology = { | |
371 | + .set = param_set_battery_technology, | |
372 | + .get = param_get_battery_technology, | |
373 | +}; | |
374 | + | |
375 | +static struct kernel_param_ops param_ops_battery_health = { | |
376 | + .set = param_set_battery_health, | |
377 | + .get = param_get_battery_health, | |
378 | +}; | |
379 | + | |
380 | +static struct kernel_param_ops param_ops_battery_capacity = { | |
381 | + .set = param_set_battery_capacity, | |
382 | + .get = param_get_battery_capacity, | |
383 | +}; | |
384 | + | |
385 | + | |
386 | +#define param_check_ac_online(name, p) __param_check(name, p, void); | |
387 | +#define param_check_battery_status(name, p) __param_check(name, p, void); | |
388 | +#define param_check_battery_present(name, p) __param_check(name, p, void); | |
389 | +#define param_check_battery_technology(name, p) __param_check(name, p, void); | |
390 | +#define param_check_battery_health(name, p) __param_check(name, p, void); | |
391 | +#define param_check_battery_capacity(name, p) __param_check(name, p, void); | |
392 | + | |
393 | + | |
394 | +module_param(ac_online, ac_online, 0644); | |
395 | +MODULE_PARM_DESC(ac_online, "AC charging state <on|off>"); | |
396 | + | |
397 | +module_param(battery_status, battery_status, 0644); | |
398 | +MODULE_PARM_DESC(battery_status, | |
399 | + "battery status <charging|discharging|not-charging|full>"); | |
400 | + | |
401 | +module_param(battery_present, battery_present, 0644); | |
402 | +MODULE_PARM_DESC(battery_present, | |
403 | + "battery presence state <good|overheat|dead|overvoltage|failure>"); | |
404 | + | |
405 | +module_param(battery_technology, battery_technology, 0644); | |
406 | +MODULE_PARM_DESC(battery_technology, | |
407 | + "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>"); | |
408 | + | |
409 | +module_param(battery_health, battery_health, 0644); | |
410 | +MODULE_PARM_DESC(battery_health, | |
411 | + "battery health state <good|overheat|dead|overvoltage|failure>"); | |
412 | + | |
413 | +module_param(battery_capacity, battery_capacity, 0644); | |
414 | +MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)"); | |
415 | + | |
160 | 416 | |
161 | 417 | MODULE_DESCRIPTION("Power supply driver for testing"); |
162 | 418 | MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); |
drivers/power/z2_battery.c
... | ... | @@ -271,24 +271,33 @@ |
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[] = { |
295 | 304 | |
... | ... | @@ -301,11 +310,10 @@ |
301 | 310 | .driver = { |
302 | 311 | .name = "z2-battery", |
303 | 312 | .owner = THIS_MODULE, |
313 | + .pm = Z2_BATTERY_PM_OPS | |
304 | 314 | }, |
305 | 315 | .probe = z2_batt_probe, |
306 | 316 | .remove = z2_batt_remove, |
307 | - .suspend = z2_batt_suspend, | |
308 | - .resume = z2_batt_resume, | |
309 | 317 | .id_table = z2_batt_id, |
310 | 318 | }; |
311 | 319 |
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 |
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__ */ |