diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-31 12:24:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-31 12:24:50 -0400 |
commit | f0d15c96d4ddcf32b6f910c4c2487ee705e4d493 (patch) | |
tree | 07c715e05527545e40cbc57d4377f95247c20ebe /drivers/power | |
parent | 4d8a93c7e542c364b1c2ad1dd406ede85080eab9 (diff) | |
parent | f8c63918c9a3004bd052fa4af08aa1cefbcd79ac (diff) |
Merge git://git.infradead.org/battery-2.6
* git://git.infradead.org/battery-2.6:
gpio-charger: Fix checking return value of request_any_context_irq
power_supply: MAX17042: Support additional properties
max8903_charger: Allow platform data to be __initdata
power_supply: Add charger driver for MAX8998/LP3974
power_supply: Add charger driver for MAX8997/8966
max17042_battery: Remove obsolete cleanup for clientdata
twl4030_charger: Fix warnings
wm831x_power: Support multiple instances
wm831x_backup: Support multiple instances
apm_power: Fix style error in macros
s3c_adc_battery: Fix annotation for s3c_adc_battery_probe()
bq20z75: Enable detection after registering
bq20z75: Add support for external notification
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/Kconfig | 14 | ||||
-rw-r--r-- | drivers/power/Makefile | 2 | ||||
-rw-r--r-- | drivers/power/apm_power.c | 8 | ||||
-rw-r--r-- | drivers/power/bq20z75.c | 103 | ||||
-rw-r--r-- | drivers/power/gpio-charger.c | 2 | ||||
-rw-r--r-- | drivers/power/max17042_battery.c | 175 | ||||
-rw-r--r-- | drivers/power/max8903_charger.c | 16 | ||||
-rw-r--r-- | drivers/power/max8997_charger.c | 206 | ||||
-rw-r--r-- | drivers/power/max8998_charger.c | 218 | ||||
-rw-r--r-- | drivers/power/s3c_adc_battery.c | 2 | ||||
-rw-r--r-- | drivers/power/twl4030_charger.c | 10 | ||||
-rw-r--r-- | drivers/power/wm831x_backup.c | 12 | ||||
-rw-r--r-- | drivers/power/wm831x_power.c | 26 |
13 files changed, 692 insertions, 102 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index e57b50b38565..57de051a74b3 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
@@ -235,4 +235,18 @@ config CHARGER_GPIO | |||
235 | This driver can be build as a module. If so, the module will be | 235 | This driver can be build as a module. If so, the module will be |
236 | called gpio-charger. | 236 | called gpio-charger. |
237 | 237 | ||
238 | config CHARGER_MAX8997 | ||
239 | tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver" | ||
240 | depends on MFD_MAX8997 && REGULATOR_MAX8997 | ||
241 | help | ||
242 | Say Y to enable support for the battery charger control sysfs and | ||
243 | platform data of MAX8997/LP3974 PMICs. | ||
244 | |||
245 | config CHARGER_MAX8998 | ||
246 | tristate "Maxim MAX8998/LP3974 PMIC battery charger driver" | ||
247 | depends on MFD_MAX8998 && REGULATOR_MAX8998 | ||
248 | help | ||
249 | Say Y to enable support for the battery charger control sysfs and | ||
250 | platform data of MAX8998/LP3974 PMICs. | ||
251 | |||
238 | endif # POWER_SUPPLY | 252 | endif # POWER_SUPPLY |
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 009a90fa8ac9..b4af13dd8b66 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile | |||
@@ -36,3 +36,5 @@ obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o | |||
36 | obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o | 36 | obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o |
37 | obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o | 37 | obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o |
38 | obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o | 38 | obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o |
39 | obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o | ||
40 | obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o | ||
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c index dc628cb2e762..8a612dec9139 100644 --- a/drivers/power/apm_power.c +++ b/drivers/power/apm_power.c | |||
@@ -14,11 +14,11 @@ | |||
14 | #include <linux/apm-emulation.h> | 14 | #include <linux/apm-emulation.h> |
15 | 15 | ||
16 | 16 | ||
17 | #define PSY_PROP(psy, prop, val) psy->get_property(psy, \ | 17 | #define PSY_PROP(psy, prop, val) (psy->get_property(psy, \ |
18 | POWER_SUPPLY_PROP_##prop, val) | 18 | POWER_SUPPLY_PROP_##prop, val)) |
19 | 19 | ||
20 | #define _MPSY_PROP(prop, val) main_battery->get_property(main_battery, \ | 20 | #define _MPSY_PROP(prop, val) (main_battery->get_property(main_battery, \ |
21 | prop, val) | 21 | prop, val)) |
22 | 22 | ||
23 | #define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) | 23 | #define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) |
24 | 24 | ||
diff --git a/drivers/power/bq20z75.c b/drivers/power/bq20z75.c index 506585e31a5b..9c5e5beda3a8 100644 --- a/drivers/power/bq20z75.c +++ b/drivers/power/bq20z75.c | |||
@@ -152,6 +152,10 @@ struct bq20z75_info { | |||
152 | bool gpio_detect; | 152 | bool gpio_detect; |
153 | bool enable_detection; | 153 | bool enable_detection; |
154 | int irq; | 154 | int irq; |
155 | int last_state; | ||
156 | int poll_time; | ||
157 | struct delayed_work work; | ||
158 | int ignore_changes; | ||
155 | }; | 159 | }; |
156 | 160 | ||
157 | static int bq20z75_read_word_data(struct i2c_client *client, u8 address) | 161 | static int bq20z75_read_word_data(struct i2c_client *client, u8 address) |
@@ -279,6 +283,7 @@ static int bq20z75_get_battery_property(struct i2c_client *client, | |||
279 | int reg_offset, enum power_supply_property psp, | 283 | int reg_offset, enum power_supply_property psp, |
280 | union power_supply_propval *val) | 284 | union power_supply_propval *val) |
281 | { | 285 | { |
286 | struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); | ||
282 | s32 ret; | 287 | s32 ret; |
283 | 288 | ||
284 | ret = bq20z75_read_word_data(client, | 289 | ret = bq20z75_read_word_data(client, |
@@ -293,15 +298,24 @@ static int bq20z75_get_battery_property(struct i2c_client *client, | |||
293 | if (ret >= bq20z75_data[reg_offset].min_value && | 298 | if (ret >= bq20z75_data[reg_offset].min_value && |
294 | ret <= bq20z75_data[reg_offset].max_value) { | 299 | ret <= bq20z75_data[reg_offset].max_value) { |
295 | val->intval = ret; | 300 | val->intval = ret; |
296 | if (psp == POWER_SUPPLY_PROP_STATUS) { | 301 | if (psp != POWER_SUPPLY_PROP_STATUS) |
297 | if (ret & BATTERY_FULL_CHARGED) | 302 | return 0; |
298 | val->intval = POWER_SUPPLY_STATUS_FULL; | 303 | |
299 | else if (ret & BATTERY_FULL_DISCHARGED) | 304 | if (ret & BATTERY_FULL_CHARGED) |
300 | val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; | 305 | val->intval = POWER_SUPPLY_STATUS_FULL; |
301 | else if (ret & BATTERY_DISCHARGING) | 306 | else if (ret & BATTERY_FULL_DISCHARGED) |
302 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 307 | val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; |
303 | else | 308 | else if (ret & BATTERY_DISCHARGING) |
304 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 309 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
310 | else | ||
311 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | ||
312 | |||
313 | if (bq20z75_device->poll_time == 0) | ||
314 | bq20z75_device->last_state = val->intval; | ||
315 | else if (bq20z75_device->last_state != val->intval) { | ||
316 | cancel_delayed_work_sync(&bq20z75_device->work); | ||
317 | power_supply_changed(&bq20z75_device->power_supply); | ||
318 | bq20z75_device->poll_time = 0; | ||
305 | } | 319 | } |
306 | } else { | 320 | } else { |
307 | if (psp == POWER_SUPPLY_PROP_STATUS) | 321 | if (psp == POWER_SUPPLY_PROP_STATUS) |
@@ -545,6 +559,60 @@ static irqreturn_t bq20z75_irq(int irq, void *devid) | |||
545 | return IRQ_HANDLED; | 559 | return IRQ_HANDLED; |
546 | } | 560 | } |
547 | 561 | ||
562 | static void bq20z75_external_power_changed(struct power_supply *psy) | ||
563 | { | ||
564 | struct bq20z75_info *bq20z75_device; | ||
565 | |||
566 | bq20z75_device = container_of(psy, struct bq20z75_info, power_supply); | ||
567 | |||
568 | if (bq20z75_device->ignore_changes > 0) { | ||
569 | bq20z75_device->ignore_changes--; | ||
570 | return; | ||
571 | } | ||
572 | |||
573 | /* cancel outstanding work */ | ||
574 | cancel_delayed_work_sync(&bq20z75_device->work); | ||
575 | |||
576 | schedule_delayed_work(&bq20z75_device->work, HZ); | ||
577 | bq20z75_device->poll_time = bq20z75_device->pdata->poll_retry_count; | ||
578 | } | ||
579 | |||
580 | static void bq20z75_delayed_work(struct work_struct *work) | ||
581 | { | ||
582 | struct bq20z75_info *bq20z75_device; | ||
583 | s32 ret; | ||
584 | |||
585 | bq20z75_device = container_of(work, struct bq20z75_info, work.work); | ||
586 | |||
587 | ret = bq20z75_read_word_data(bq20z75_device->client, | ||
588 | bq20z75_data[REG_STATUS].addr); | ||
589 | /* if the read failed, give up on this work */ | ||
590 | if (ret < 0) { | ||
591 | bq20z75_device->poll_time = 0; | ||
592 | return; | ||
593 | } | ||
594 | |||
595 | if (ret & BATTERY_FULL_CHARGED) | ||
596 | ret = POWER_SUPPLY_STATUS_FULL; | ||
597 | else if (ret & BATTERY_FULL_DISCHARGED) | ||
598 | ret = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
599 | else if (ret & BATTERY_DISCHARGING) | ||
600 | ret = POWER_SUPPLY_STATUS_DISCHARGING; | ||
601 | else | ||
602 | ret = POWER_SUPPLY_STATUS_CHARGING; | ||
603 | |||
604 | if (bq20z75_device->last_state != ret) { | ||
605 | bq20z75_device->poll_time = 0; | ||
606 | power_supply_changed(&bq20z75_device->power_supply); | ||
607 | return; | ||
608 | } | ||
609 | if (bq20z75_device->poll_time > 0) { | ||
610 | schedule_delayed_work(&bq20z75_device->work, HZ); | ||
611 | bq20z75_device->poll_time--; | ||
612 | return; | ||
613 | } | ||
614 | } | ||
615 | |||
548 | static int __devinit bq20z75_probe(struct i2c_client *client, | 616 | static int __devinit bq20z75_probe(struct i2c_client *client, |
549 | const struct i2c_device_id *id) | 617 | const struct i2c_device_id *id) |
550 | { | 618 | { |
@@ -566,6 +634,13 @@ static int __devinit bq20z75_probe(struct i2c_client *client, | |||
566 | bq20z75_device->power_supply.num_properties = | 634 | bq20z75_device->power_supply.num_properties = |
567 | ARRAY_SIZE(bq20z75_properties); | 635 | ARRAY_SIZE(bq20z75_properties); |
568 | bq20z75_device->power_supply.get_property = bq20z75_get_property; | 636 | bq20z75_device->power_supply.get_property = bq20z75_get_property; |
637 | /* ignore first notification of external change, it is generated | ||
638 | * from the power_supply_register call back | ||
639 | */ | ||
640 | bq20z75_device->ignore_changes = 1; | ||
641 | bq20z75_device->last_state = POWER_SUPPLY_STATUS_UNKNOWN; | ||
642 | bq20z75_device->power_supply.external_power_changed = | ||
643 | bq20z75_external_power_changed; | ||
569 | 644 | ||
570 | if (pdata) { | 645 | if (pdata) { |
571 | bq20z75_device->gpio_detect = | 646 | bq20z75_device->gpio_detect = |
@@ -625,6 +700,10 @@ skip_gpio: | |||
625 | dev_info(&client->dev, | 700 | dev_info(&client->dev, |
626 | "%s: battery gas gauge device registered\n", client->name); | 701 | "%s: battery gas gauge device registered\n", client->name); |
627 | 702 | ||
703 | INIT_DELAYED_WORK(&bq20z75_device->work, bq20z75_delayed_work); | ||
704 | |||
705 | bq20z75_device->enable_detection = true; | ||
706 | |||
628 | return 0; | 707 | return 0; |
629 | 708 | ||
630 | exit_psupply: | 709 | exit_psupply: |
@@ -648,6 +727,9 @@ static int __devexit bq20z75_remove(struct i2c_client *client) | |||
648 | gpio_free(bq20z75_device->pdata->battery_detect); | 727 | gpio_free(bq20z75_device->pdata->battery_detect); |
649 | 728 | ||
650 | power_supply_unregister(&bq20z75_device->power_supply); | 729 | power_supply_unregister(&bq20z75_device->power_supply); |
730 | |||
731 | cancel_delayed_work_sync(&bq20z75_device->work); | ||
732 | |||
651 | kfree(bq20z75_device); | 733 | kfree(bq20z75_device); |
652 | bq20z75_device = NULL; | 734 | bq20z75_device = NULL; |
653 | 735 | ||
@@ -661,6 +743,9 @@ static int bq20z75_suspend(struct i2c_client *client, | |||
661 | struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); | 743 | struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client); |
662 | s32 ret; | 744 | s32 ret; |
663 | 745 | ||
746 | if (bq20z75_device->poll_time > 0) | ||
747 | cancel_delayed_work_sync(&bq20z75_device->work); | ||
748 | |||
664 | /* write to manufacturer access with sleep command */ | 749 | /* write to manufacturer access with sleep command */ |
665 | ret = bq20z75_write_word_data(client, | 750 | ret = bq20z75_write_word_data(client, |
666 | bq20z75_data[REG_MANUFACTURER_DATA].addr, | 751 | bq20z75_data[REG_MANUFACTURER_DATA].addr, |
diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index 718f2c537827..a64b8854cfd5 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c | |||
@@ -127,7 +127,7 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev) | |||
127 | ret = request_any_context_irq(irq, gpio_charger_irq, | 127 | ret = request_any_context_irq(irq, gpio_charger_irq, |
128 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 128 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
129 | dev_name(&pdev->dev), charger); | 129 | dev_name(&pdev->dev), charger); |
130 | if (ret) | 130 | if (ret < 0) |
131 | dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret); | 131 | dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret); |
132 | else | 132 | else |
133 | gpio_charger->irq = irq; | 133 | gpio_charger->irq = irq; |
diff --git a/drivers/power/max17042_battery.c b/drivers/power/max17042_battery.c index c5c8805156cb..98bfab35b8e9 100644 --- a/drivers/power/max17042_battery.c +++ b/drivers/power/max17042_battery.c | |||
@@ -29,74 +29,6 @@ | |||
29 | #include <linux/power_supply.h> | 29 | #include <linux/power_supply.h> |
30 | #include <linux/power/max17042_battery.h> | 30 | #include <linux/power/max17042_battery.h> |
31 | 31 | ||
32 | enum max17042_register { | ||
33 | MAX17042_STATUS = 0x00, | ||
34 | MAX17042_VALRT_Th = 0x01, | ||
35 | MAX17042_TALRT_Th = 0x02, | ||
36 | MAX17042_SALRT_Th = 0x03, | ||
37 | MAX17042_AtRate = 0x04, | ||
38 | MAX17042_RepCap = 0x05, | ||
39 | MAX17042_RepSOC = 0x06, | ||
40 | MAX17042_Age = 0x07, | ||
41 | MAX17042_TEMP = 0x08, | ||
42 | MAX17042_VCELL = 0x09, | ||
43 | MAX17042_Current = 0x0A, | ||
44 | MAX17042_AvgCurrent = 0x0B, | ||
45 | MAX17042_Qresidual = 0x0C, | ||
46 | MAX17042_SOC = 0x0D, | ||
47 | MAX17042_AvSOC = 0x0E, | ||
48 | MAX17042_RemCap = 0x0F, | ||
49 | MAX17402_FullCAP = 0x10, | ||
50 | MAX17042_TTE = 0x11, | ||
51 | MAX17042_V_empty = 0x12, | ||
52 | |||
53 | MAX17042_RSLOW = 0x14, | ||
54 | |||
55 | MAX17042_AvgTA = 0x16, | ||
56 | MAX17042_Cycles = 0x17, | ||
57 | MAX17042_DesignCap = 0x18, | ||
58 | MAX17042_AvgVCELL = 0x19, | ||
59 | MAX17042_MinMaxTemp = 0x1A, | ||
60 | MAX17042_MinMaxVolt = 0x1B, | ||
61 | MAX17042_MinMaxCurr = 0x1C, | ||
62 | MAX17042_CONFIG = 0x1D, | ||
63 | MAX17042_ICHGTerm = 0x1E, | ||
64 | MAX17042_AvCap = 0x1F, | ||
65 | MAX17042_ManName = 0x20, | ||
66 | MAX17042_DevName = 0x21, | ||
67 | MAX17042_DevChem = 0x22, | ||
68 | |||
69 | MAX17042_TempNom = 0x24, | ||
70 | MAX17042_TempCold = 0x25, | ||
71 | MAX17042_TempHot = 0x26, | ||
72 | MAX17042_AIN = 0x27, | ||
73 | MAX17042_LearnCFG = 0x28, | ||
74 | MAX17042_SHFTCFG = 0x29, | ||
75 | MAX17042_RelaxCFG = 0x2A, | ||
76 | MAX17042_MiscCFG = 0x2B, | ||
77 | MAX17042_TGAIN = 0x2C, | ||
78 | MAx17042_TOFF = 0x2D, | ||
79 | MAX17042_CGAIN = 0x2E, | ||
80 | MAX17042_COFF = 0x2F, | ||
81 | |||
82 | MAX17042_Q_empty = 0x33, | ||
83 | MAX17042_T_empty = 0x34, | ||
84 | |||
85 | MAX17042_RCOMP0 = 0x38, | ||
86 | MAX17042_TempCo = 0x39, | ||
87 | MAX17042_Rx = 0x3A, | ||
88 | MAX17042_T_empty0 = 0x3B, | ||
89 | MAX17042_TaskPeriod = 0x3C, | ||
90 | MAX17042_FSTAT = 0x3D, | ||
91 | |||
92 | MAX17042_SHDNTIMER = 0x3F, | ||
93 | |||
94 | MAX17042_VFRemCap = 0x4A, | ||
95 | |||
96 | MAX17042_QH = 0x4D, | ||
97 | MAX17042_QL = 0x4E, | ||
98 | }; | ||
99 | |||
100 | struct max17042_chip { | 32 | struct max17042_chip { |
101 | struct i2c_client *client; | 33 | struct i2c_client *client; |
102 | struct power_supply battery; | 34 | struct power_supply battery; |
@@ -123,10 +55,27 @@ static int max17042_read_reg(struct i2c_client *client, u8 reg) | |||
123 | return ret; | 55 | return ret; |
124 | } | 56 | } |
125 | 57 | ||
58 | static void max17042_set_reg(struct i2c_client *client, | ||
59 | struct max17042_reg_data *data, int size) | ||
60 | { | ||
61 | int i; | ||
62 | |||
63 | for (i = 0; i < size; i++) | ||
64 | max17042_write_reg(client, data[i].addr, data[i].data); | ||
65 | } | ||
66 | |||
126 | static enum power_supply_property max17042_battery_props[] = { | 67 | static enum power_supply_property max17042_battery_props[] = { |
68 | POWER_SUPPLY_PROP_PRESENT, | ||
69 | POWER_SUPPLY_PROP_CYCLE_COUNT, | ||
70 | POWER_SUPPLY_PROP_VOLTAGE_MAX, | ||
71 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | ||
127 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 72 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
128 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | 73 | POWER_SUPPLY_PROP_VOLTAGE_AVG, |
129 | POWER_SUPPLY_PROP_CAPACITY, | 74 | POWER_SUPPLY_PROP_CAPACITY, |
75 | POWER_SUPPLY_PROP_CHARGE_FULL, | ||
76 | POWER_SUPPLY_PROP_TEMP, | ||
77 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
78 | POWER_SUPPLY_PROP_CURRENT_AVG, | ||
130 | }; | 79 | }; |
131 | 80 | ||
132 | static int max17042_get_property(struct power_supply *psy, | 81 | static int max17042_get_property(struct power_supply *psy, |
@@ -137,6 +86,30 @@ static int max17042_get_property(struct power_supply *psy, | |||
137 | struct max17042_chip, battery); | 86 | struct max17042_chip, battery); |
138 | 87 | ||
139 | switch (psp) { | 88 | switch (psp) { |
89 | case POWER_SUPPLY_PROP_PRESENT: | ||
90 | val->intval = max17042_read_reg(chip->client, | ||
91 | MAX17042_STATUS); | ||
92 | if (val->intval & MAX17042_STATUS_BattAbsent) | ||
93 | val->intval = 0; | ||
94 | else | ||
95 | val->intval = 1; | ||
96 | break; | ||
97 | case POWER_SUPPLY_PROP_CYCLE_COUNT: | ||
98 | val->intval = max17042_read_reg(chip->client, | ||
99 | MAX17042_Cycles); | ||
100 | break; | ||
101 | case POWER_SUPPLY_PROP_VOLTAGE_MAX: | ||
102 | val->intval = max17042_read_reg(chip->client, | ||
103 | MAX17042_MinMaxVolt); | ||
104 | val->intval >>= 8; | ||
105 | val->intval *= 20000; /* Units of LSB = 20mV */ | ||
106 | break; | ||
107 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | ||
108 | val->intval = max17042_read_reg(chip->client, | ||
109 | MAX17042_V_empty); | ||
110 | val->intval >>= 7; | ||
111 | val->intval *= 10000; /* Units of LSB = 10mV */ | ||
112 | break; | ||
140 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | 113 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
141 | val->intval = max17042_read_reg(chip->client, | 114 | val->intval = max17042_read_reg(chip->client, |
142 | MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */ | 115 | MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */ |
@@ -149,6 +122,57 @@ static int max17042_get_property(struct power_supply *psy, | |||
149 | val->intval = max17042_read_reg(chip->client, | 122 | val->intval = max17042_read_reg(chip->client, |
150 | MAX17042_SOC) / 256; | 123 | MAX17042_SOC) / 256; |
151 | break; | 124 | break; |
125 | case POWER_SUPPLY_PROP_CHARGE_FULL: | ||
126 | val->intval = max17042_read_reg(chip->client, | ||
127 | MAX17042_RepSOC); | ||
128 | if ((val->intval / 256) >= MAX17042_BATTERY_FULL) | ||
129 | val->intval = 1; | ||
130 | else if (val->intval >= 0) | ||
131 | val->intval = 0; | ||
132 | break; | ||
133 | case POWER_SUPPLY_PROP_TEMP: | ||
134 | val->intval = max17042_read_reg(chip->client, | ||
135 | MAX17042_TEMP); | ||
136 | /* The value is signed. */ | ||
137 | if (val->intval & 0x8000) { | ||
138 | val->intval = (0x7fff & ~val->intval) + 1; | ||
139 | val->intval *= -1; | ||
140 | } | ||
141 | /* The value is converted into deci-centigrade scale */ | ||
142 | /* Units of LSB = 1 / 256 degree Celsius */ | ||
143 | val->intval = val->intval * 10 / 256; | ||
144 | break; | ||
145 | case POWER_SUPPLY_PROP_CURRENT_NOW: | ||
146 | if (chip->pdata->enable_current_sense) { | ||
147 | val->intval = max17042_read_reg(chip->client, | ||
148 | MAX17042_Current); | ||
149 | if (val->intval & 0x8000) { | ||
150 | /* Negative */ | ||
151 | val->intval = ~val->intval & 0x7fff; | ||
152 | val->intval++; | ||
153 | val->intval *= -1; | ||
154 | } | ||
155 | val->intval >>= 4; | ||
156 | val->intval *= 1000000 * 25 / chip->pdata->r_sns; | ||
157 | } else { | ||
158 | return -EINVAL; | ||
159 | } | ||
160 | break; | ||
161 | case POWER_SUPPLY_PROP_CURRENT_AVG: | ||
162 | if (chip->pdata->enable_current_sense) { | ||
163 | val->intval = max17042_read_reg(chip->client, | ||
164 | MAX17042_AvgCurrent); | ||
165 | if (val->intval & 0x8000) { | ||
166 | /* Negative */ | ||
167 | val->intval = ~val->intval & 0x7fff; | ||
168 | val->intval++; | ||
169 | val->intval *= -1; | ||
170 | } | ||
171 | val->intval *= 1562500 / chip->pdata->r_sns; | ||
172 | } else { | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | break; | ||
152 | default: | 176 | default: |
153 | return -EINVAL; | 177 | return -EINVAL; |
154 | } | 178 | } |
@@ -180,18 +204,30 @@ static int __devinit max17042_probe(struct i2c_client *client, | |||
180 | chip->battery.properties = max17042_battery_props; | 204 | chip->battery.properties = max17042_battery_props; |
181 | chip->battery.num_properties = ARRAY_SIZE(max17042_battery_props); | 205 | chip->battery.num_properties = ARRAY_SIZE(max17042_battery_props); |
182 | 206 | ||
207 | /* When current is not measured, | ||
208 | * CURRENT_NOW and CURRENT_AVG properties should be invisible. */ | ||
209 | if (!chip->pdata->enable_current_sense) | ||
210 | chip->battery.num_properties -= 2; | ||
211 | |||
183 | ret = power_supply_register(&client->dev, &chip->battery); | 212 | ret = power_supply_register(&client->dev, &chip->battery); |
184 | if (ret) { | 213 | if (ret) { |
185 | dev_err(&client->dev, "failed: power supply register\n"); | 214 | dev_err(&client->dev, "failed: power supply register\n"); |
186 | i2c_set_clientdata(client, NULL); | ||
187 | kfree(chip); | 215 | kfree(chip); |
188 | return ret; | 216 | return ret; |
189 | } | 217 | } |
190 | 218 | ||
219 | /* Initialize registers according to values from the platform data */ | ||
220 | if (chip->pdata->init_data) | ||
221 | max17042_set_reg(client, chip->pdata->init_data, | ||
222 | chip->pdata->num_init_data); | ||
223 | |||
191 | if (!chip->pdata->enable_current_sense) { | 224 | if (!chip->pdata->enable_current_sense) { |
192 | max17042_write_reg(client, MAX17042_CGAIN, 0x0000); | 225 | max17042_write_reg(client, MAX17042_CGAIN, 0x0000); |
193 | max17042_write_reg(client, MAX17042_MiscCFG, 0x0003); | 226 | max17042_write_reg(client, MAX17042_MiscCFG, 0x0003); |
194 | max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); | 227 | max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); |
228 | } else { | ||
229 | if (chip->pdata->r_sns == 0) | ||
230 | chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR; | ||
195 | } | 231 | } |
196 | 232 | ||
197 | return 0; | 233 | return 0; |
@@ -202,7 +238,6 @@ static int __devexit max17042_remove(struct i2c_client *client) | |||
202 | struct max17042_chip *chip = i2c_get_clientdata(client); | 238 | struct max17042_chip *chip = i2c_get_clientdata(client); |
203 | 239 | ||
204 | power_supply_unregister(&chip->battery); | 240 | power_supply_unregister(&chip->battery); |
205 | i2c_set_clientdata(client, NULL); | ||
206 | kfree(chip); | 241 | kfree(chip); |
207 | return 0; | 242 | return 0; |
208 | } | 243 | } |
diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c index 33ff0e37809e..a9b0209a2f55 100644 --- a/drivers/power/max8903_charger.c +++ b/drivers/power/max8903_charger.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/power/max8903_charger.h> | 28 | #include <linux/power/max8903_charger.h> |
29 | 29 | ||
30 | struct max8903_data { | 30 | struct max8903_data { |
31 | struct max8903_pdata *pdata; | 31 | struct max8903_pdata pdata; |
32 | struct device *dev; | 32 | struct device *dev; |
33 | struct power_supply psy; | 33 | struct power_supply psy; |
34 | bool fault; | 34 | bool fault; |
@@ -52,8 +52,8 @@ static int max8903_get_property(struct power_supply *psy, | |||
52 | switch (psp) { | 52 | switch (psp) { |
53 | case POWER_SUPPLY_PROP_STATUS: | 53 | case POWER_SUPPLY_PROP_STATUS: |
54 | val->intval = POWER_SUPPLY_STATUS_UNKNOWN; | 54 | val->intval = POWER_SUPPLY_STATUS_UNKNOWN; |
55 | if (data->pdata->chg) { | 55 | if (data->pdata.chg) { |
56 | if (gpio_get_value(data->pdata->chg) == 0) | 56 | if (gpio_get_value(data->pdata.chg) == 0) |
57 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 57 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
58 | else if (data->usb_in || data->ta_in) | 58 | else if (data->usb_in || data->ta_in) |
59 | val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; | 59 | val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; |
@@ -80,7 +80,7 @@ static int max8903_get_property(struct power_supply *psy, | |||
80 | static irqreturn_t max8903_dcin(int irq, void *_data) | 80 | static irqreturn_t max8903_dcin(int irq, void *_data) |
81 | { | 81 | { |
82 | struct max8903_data *data = _data; | 82 | struct max8903_data *data = _data; |
83 | struct max8903_pdata *pdata = data->pdata; | 83 | struct max8903_pdata *pdata = &data->pdata; |
84 | bool ta_in; | 84 | bool ta_in; |
85 | enum power_supply_type old_type; | 85 | enum power_supply_type old_type; |
86 | 86 | ||
@@ -121,7 +121,7 @@ static irqreturn_t max8903_dcin(int irq, void *_data) | |||
121 | static irqreturn_t max8903_usbin(int irq, void *_data) | 121 | static irqreturn_t max8903_usbin(int irq, void *_data) |
122 | { | 122 | { |
123 | struct max8903_data *data = _data; | 123 | struct max8903_data *data = _data; |
124 | struct max8903_pdata *pdata = data->pdata; | 124 | struct max8903_pdata *pdata = &data->pdata; |
125 | bool usb_in; | 125 | bool usb_in; |
126 | enum power_supply_type old_type; | 126 | enum power_supply_type old_type; |
127 | 127 | ||
@@ -160,7 +160,7 @@ static irqreturn_t max8903_usbin(int irq, void *_data) | |||
160 | static irqreturn_t max8903_fault(int irq, void *_data) | 160 | static irqreturn_t max8903_fault(int irq, void *_data) |
161 | { | 161 | { |
162 | struct max8903_data *data = _data; | 162 | struct max8903_data *data = _data; |
163 | struct max8903_pdata *pdata = data->pdata; | 163 | struct max8903_pdata *pdata = &data->pdata; |
164 | bool fault; | 164 | bool fault; |
165 | 165 | ||
166 | fault = gpio_get_value(pdata->flt) ? false : true; | 166 | fault = gpio_get_value(pdata->flt) ? false : true; |
@@ -193,7 +193,7 @@ static __devinit int max8903_probe(struct platform_device *pdev) | |||
193 | dev_err(dev, "Cannot allocate memory.\n"); | 193 | dev_err(dev, "Cannot allocate memory.\n"); |
194 | return -ENOMEM; | 194 | return -ENOMEM; |
195 | } | 195 | } |
196 | data->pdata = pdata; | 196 | memcpy(&data->pdata, pdata, sizeof(struct max8903_pdata)); |
197 | data->dev = dev; | 197 | data->dev = dev; |
198 | platform_set_drvdata(pdev, data); | 198 | platform_set_drvdata(pdev, data); |
199 | 199 | ||
@@ -349,7 +349,7 @@ static __devexit int max8903_remove(struct platform_device *pdev) | |||
349 | struct max8903_data *data = platform_get_drvdata(pdev); | 349 | struct max8903_data *data = platform_get_drvdata(pdev); |
350 | 350 | ||
351 | if (data) { | 351 | if (data) { |
352 | struct max8903_pdata *pdata = data->pdata; | 352 | struct max8903_pdata *pdata = &data->pdata; |
353 | 353 | ||
354 | if (pdata->flt) | 354 | if (pdata->flt) |
355 | free_irq(gpio_to_irq(pdata->flt), data); | 355 | free_irq(gpio_to_irq(pdata->flt), data); |
diff --git a/drivers/power/max8997_charger.c b/drivers/power/max8997_charger.c new file mode 100644 index 000000000000..7106b49b26e4 --- /dev/null +++ b/drivers/power/max8997_charger.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | * max8997_charger.c - Power supply consumer driver for the Maxim 8997/8966 | ||
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 | #include <linux/err.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/power_supply.h> | ||
26 | #include <linux/mfd/max8997.h> | ||
27 | #include <linux/mfd/max8997-private.h> | ||
28 | |||
29 | struct charger_data { | ||
30 | struct device *dev; | ||
31 | struct max8997_dev *iodev; | ||
32 | struct power_supply battery; | ||
33 | }; | ||
34 | |||
35 | static enum power_supply_property max8997_battery_props[] = { | ||
36 | POWER_SUPPLY_PROP_STATUS, /* "FULL" or "NOT FULL" only. */ | ||
37 | POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */ | ||
38 | POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */ | ||
39 | }; | ||
40 | |||
41 | /* Note that the charger control is done by a current regulator "CHARGER" */ | ||
42 | static int max8997_battery_get_property(struct power_supply *psy, | ||
43 | enum power_supply_property psp, | ||
44 | union power_supply_propval *val) | ||
45 | { | ||
46 | struct charger_data *charger = container_of(psy, | ||
47 | struct charger_data, battery); | ||
48 | struct i2c_client *i2c = charger->iodev->i2c; | ||
49 | int ret; | ||
50 | u8 reg; | ||
51 | |||
52 | switch (psp) { | ||
53 | case POWER_SUPPLY_PROP_STATUS: | ||
54 | val->intval = 0; | ||
55 | ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, ®); | ||
56 | if (ret) | ||
57 | return ret; | ||
58 | if ((reg & (1 << 0)) == 0x1) | ||
59 | val->intval = POWER_SUPPLY_STATUS_FULL; | ||
60 | |||
61 | break; | ||
62 | case POWER_SUPPLY_PROP_PRESENT: | ||
63 | val->intval = 0; | ||
64 | ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, ®); | ||
65 | if (ret) | ||
66 | return ret; | ||
67 | if ((reg & (1 << 2)) == 0x0) | ||
68 | val->intval = 1; | ||
69 | |||
70 | break; | ||
71 | case POWER_SUPPLY_PROP_ONLINE: | ||
72 | val->intval = 0; | ||
73 | ret = max8997_read_reg(i2c, MAX8997_REG_STATUS4, ®); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | /* DCINOK */ | ||
77 | if (reg & (1 << 1)) | ||
78 | val->intval = 1; | ||
79 | |||
80 | break; | ||
81 | default: | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static __devinit int max8997_battery_probe(struct platform_device *pdev) | ||
89 | { | ||
90 | int ret = 0; | ||
91 | struct charger_data *charger; | ||
92 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
93 | struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
94 | |||
95 | if (!pdata) | ||
96 | return -EINVAL; | ||
97 | |||
98 | if (pdata->eoc_mA) { | ||
99 | u8 val = (pdata->eoc_mA - 50) / 10; | ||
100 | if (val < 0) | ||
101 | val = 0; | ||
102 | if (val > 0xf) | ||
103 | val = 0xf; | ||
104 | |||
105 | ret = max8997_update_reg(iodev->i2c, | ||
106 | MAX8997_REG_MBCCTRL5, val, 0xf); | ||
107 | if (ret < 0) { | ||
108 | dev_err(&pdev->dev, "Cannot use i2c bus.\n"); | ||
109 | return ret; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | switch (pdata->timeout) { | ||
114 | case 5: | ||
115 | ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1, | ||
116 | 0x2 << 4, 0x7 << 4); | ||
117 | break; | ||
118 | case 6: | ||
119 | ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1, | ||
120 | 0x3 << 4, 0x7 << 4); | ||
121 | break; | ||
122 | case 7: | ||
123 | ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1, | ||
124 | 0x4 << 4, 0x7 << 4); | ||
125 | break; | ||
126 | case 0: | ||
127 | ret = max8997_update_reg(iodev->i2c, MAX8997_REG_MBCCTRL1, | ||
128 | 0x7 << 4, 0x7 << 4); | ||
129 | break; | ||
130 | default: | ||
131 | dev_err(&pdev->dev, "incorrect timeout value (%d)\n", | ||
132 | pdata->timeout); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | if (ret < 0) { | ||
136 | dev_err(&pdev->dev, "Cannot use i2c bus.\n"); | ||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | charger = kzalloc(sizeof(struct charger_data), GFP_KERNEL); | ||
141 | if (charger == NULL) { | ||
142 | dev_err(&pdev->dev, "Cannot allocate memory.\n"); | ||
143 | return -ENOMEM; | ||
144 | } | ||
145 | |||
146 | platform_set_drvdata(pdev, charger); | ||
147 | |||
148 | charger->battery.name = "max8997_pmic"; | ||
149 | charger->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
150 | charger->battery.get_property = max8997_battery_get_property; | ||
151 | charger->battery.properties = max8997_battery_props; | ||
152 | charger->battery.num_properties = ARRAY_SIZE(max8997_battery_props); | ||
153 | |||
154 | charger->dev = &pdev->dev; | ||
155 | charger->iodev = iodev; | ||
156 | |||
157 | ret = power_supply_register(&pdev->dev, &charger->battery); | ||
158 | if (ret) { | ||
159 | dev_err(&pdev->dev, "failed: power supply register\n"); | ||
160 | goto err; | ||
161 | } | ||
162 | |||
163 | return 0; | ||
164 | err: | ||
165 | kfree(charger); | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | static int __devexit max8997_battery_remove(struct platform_device *pdev) | ||
170 | { | ||
171 | struct charger_data *charger = platform_get_drvdata(pdev); | ||
172 | |||
173 | power_supply_unregister(&charger->battery); | ||
174 | kfree(charger); | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static const struct platform_device_id max8997_battery_id[] = { | ||
179 | { "max8997-battery", 0 }, | ||
180 | }; | ||
181 | |||
182 | static struct platform_driver max8997_battery_driver = { | ||
183 | .driver = { | ||
184 | .name = "max8997-battery", | ||
185 | .owner = THIS_MODULE, | ||
186 | }, | ||
187 | .probe = max8997_battery_probe, | ||
188 | .remove = __devexit_p(max8997_battery_remove), | ||
189 | .id_table = max8997_battery_id, | ||
190 | }; | ||
191 | |||
192 | static int __init max8997_battery_init(void) | ||
193 | { | ||
194 | return platform_driver_register(&max8997_battery_driver); | ||
195 | } | ||
196 | subsys_initcall(max8997_battery_init); | ||
197 | |||
198 | static void __exit max8997_battery_cleanup(void) | ||
199 | { | ||
200 | platform_driver_unregister(&max8997_battery_driver); | ||
201 | } | ||
202 | module_exit(max8997_battery_cleanup); | ||
203 | |||
204 | MODULE_DESCRIPTION("MAXIM 8997/8966 battery control driver"); | ||
205 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | ||
206 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c new file mode 100644 index 000000000000..cc21fa2120be --- /dev/null +++ b/drivers/power/max8998_charger.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | * max8998_charger.c - Power supply consumer driver for the Maxim 8998/LP3974 | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 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 | #include <linux/err.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/power_supply.h> | ||
26 | #include <linux/mfd/max8998.h> | ||
27 | #include <linux/mfd/max8998-private.h> | ||
28 | |||
29 | struct max8998_battery_data { | ||
30 | struct device *dev; | ||
31 | struct max8998_dev *iodev; | ||
32 | struct power_supply battery; | ||
33 | }; | ||
34 | |||
35 | static enum power_supply_property max8998_battery_props[] = { | ||
36 | POWER_SUPPLY_PROP_PRESENT, /* the presence of battery */ | ||
37 | POWER_SUPPLY_PROP_ONLINE, /* charger is active or not */ | ||
38 | }; | ||
39 | |||
40 | /* Note that the charger control is done by a current regulator "CHARGER" */ | ||
41 | static int max8998_battery_get_property(struct power_supply *psy, | ||
42 | enum power_supply_property psp, | ||
43 | union power_supply_propval *val) | ||
44 | { | ||
45 | struct max8998_battery_data *max8998 = container_of(psy, | ||
46 | struct max8998_battery_data, battery); | ||
47 | struct i2c_client *i2c = max8998->iodev->i2c; | ||
48 | int ret; | ||
49 | u8 reg; | ||
50 | |||
51 | switch (psp) { | ||
52 | case POWER_SUPPLY_PROP_PRESENT: | ||
53 | ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, ®); | ||
54 | if (ret) | ||
55 | return ret; | ||
56 | if (reg & (1 << 4)) | ||
57 | val->intval = 0; | ||
58 | else | ||
59 | val->intval = 1; | ||
60 | break; | ||
61 | case POWER_SUPPLY_PROP_ONLINE: | ||
62 | ret = max8998_read_reg(i2c, MAX8998_REG_STATUS2, ®); | ||
63 | if (ret) | ||
64 | return ret; | ||
65 | if (reg & (1 << 3)) | ||
66 | val->intval = 0; | ||
67 | else | ||
68 | val->intval = 1; | ||
69 | break; | ||
70 | default: | ||
71 | return -EINVAL; | ||
72 | } | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static __devinit int max8998_battery_probe(struct platform_device *pdev) | ||
78 | { | ||
79 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
80 | struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
81 | struct max8998_battery_data *max8998; | ||
82 | struct i2c_client *i2c; | ||
83 | int ret = 0; | ||
84 | |||
85 | if (!pdata) { | ||
86 | dev_err(pdev->dev.parent, "No platform init data supplied\n"); | ||
87 | return -ENODEV; | ||
88 | } | ||
89 | |||
90 | max8998 = kzalloc(sizeof(struct max8998_battery_data), GFP_KERNEL); | ||
91 | if (!max8998) | ||
92 | return -ENOMEM; | ||
93 | |||
94 | max8998->dev = &pdev->dev; | ||
95 | max8998->iodev = iodev; | ||
96 | platform_set_drvdata(pdev, max8998); | ||
97 | i2c = max8998->iodev->i2c; | ||
98 | |||
99 | /* Setup "End of Charge" */ | ||
100 | /* If EOC value equals 0, | ||
101 | * remain value set from bootloader or default value */ | ||
102 | if (pdata->eoc >= 10 && pdata->eoc <= 45) { | ||
103 | max8998_update_reg(i2c, MAX8998_REG_CHGR1, | ||
104 | (pdata->eoc / 5 - 2) << 5, 0x7 << 5); | ||
105 | } else if (pdata->eoc == 0) { | ||
106 | dev_dbg(max8998->dev, | ||
107 | "EOC value not set: leave it unchanged.\n"); | ||
108 | } else { | ||
109 | dev_err(max8998->dev, "Invalid EOC value\n"); | ||
110 | ret = -EINVAL; | ||
111 | goto err; | ||
112 | } | ||
113 | |||
114 | /* Setup Charge Restart Level */ | ||
115 | switch (pdata->restart) { | ||
116 | case 100: | ||
117 | max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x1 << 3, 0x3 << 3); | ||
118 | break; | ||
119 | case 150: | ||
120 | max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x0 << 3, 0x3 << 3); | ||
121 | break; | ||
122 | case 200: | ||
123 | max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x2 << 3, 0x3 << 3); | ||
124 | break; | ||
125 | case -1: | ||
126 | max8998_update_reg(i2c, MAX8998_REG_CHGR1, 0x3 << 3, 0x3 << 3); | ||
127 | break; | ||
128 | case 0: | ||
129 | dev_dbg(max8998->dev, | ||
130 | "Restart Level not set: leave it unchanged.\n"); | ||
131 | break; | ||
132 | default: | ||
133 | dev_err(max8998->dev, "Invalid Restart Level\n"); | ||
134 | ret = -EINVAL; | ||
135 | goto err; | ||
136 | } | ||
137 | |||
138 | /* Setup Charge Full Timeout */ | ||
139 | switch (pdata->timeout) { | ||
140 | case 5: | ||
141 | max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x0 << 4, 0x3 << 4); | ||
142 | break; | ||
143 | case 6: | ||
144 | max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x1 << 4, 0x3 << 4); | ||
145 | break; | ||
146 | case 7: | ||
147 | max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x2 << 4, 0x3 << 4); | ||
148 | break; | ||
149 | case -1: | ||
150 | max8998_update_reg(i2c, MAX8998_REG_CHGR2, 0x3 << 4, 0x3 << 4); | ||
151 | break; | ||
152 | case 0: | ||
153 | dev_dbg(max8998->dev, | ||
154 | "Full Timeout not set: leave it unchanged.\n"); | ||
155 | default: | ||
156 | dev_err(max8998->dev, "Invalid Full Timeout value\n"); | ||
157 | ret = -EINVAL; | ||
158 | goto err; | ||
159 | } | ||
160 | |||
161 | max8998->battery.name = "max8998_pmic"; | ||
162 | max8998->battery.type = POWER_SUPPLY_TYPE_BATTERY; | ||
163 | max8998->battery.get_property = max8998_battery_get_property; | ||
164 | max8998->battery.properties = max8998_battery_props; | ||
165 | max8998->battery.num_properties = ARRAY_SIZE(max8998_battery_props); | ||
166 | |||
167 | ret = power_supply_register(max8998->dev, &max8998->battery); | ||
168 | if (ret) { | ||
169 | dev_err(max8998->dev, "failed: power supply register\n"); | ||
170 | goto err; | ||
171 | } | ||
172 | |||
173 | return 0; | ||
174 | err: | ||
175 | kfree(max8998); | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int __devexit max8998_battery_remove(struct platform_device *pdev) | ||
180 | { | ||
181 | struct max8998_battery_data *max8998 = platform_get_drvdata(pdev); | ||
182 | |||
183 | power_supply_unregister(&max8998->battery); | ||
184 | kfree(max8998); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static const struct platform_device_id max8998_battery_id[] = { | ||
190 | { "max8998-battery", TYPE_MAX8998 }, | ||
191 | }; | ||
192 | |||
193 | static struct platform_driver max8998_battery_driver = { | ||
194 | .driver = { | ||
195 | .name = "max8998-battery", | ||
196 | .owner = THIS_MODULE, | ||
197 | }, | ||
198 | .probe = max8998_battery_probe, | ||
199 | .remove = __devexit_p(max8998_battery_remove), | ||
200 | .id_table = max8998_battery_id, | ||
201 | }; | ||
202 | |||
203 | static int __init max8998_battery_init(void) | ||
204 | { | ||
205 | return platform_driver_register(&max8998_battery_driver); | ||
206 | } | ||
207 | module_init(max8998_battery_init); | ||
208 | |||
209 | static void __exit max8998_battery_cleanup(void) | ||
210 | { | ||
211 | platform_driver_unregister(&max8998_battery_driver); | ||
212 | } | ||
213 | module_exit(max8998_battery_cleanup); | ||
214 | |||
215 | MODULE_DESCRIPTION("MAXIM 8998 battery control driver"); | ||
216 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | ||
217 | MODULE_LICENSE("GPL"); | ||
218 | MODULE_ALIAS("platform:max8998-battery"); | ||
diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index d36c289aaef5..a675e31b4f13 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c | |||
@@ -266,7 +266,7 @@ static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id) | |||
266 | return IRQ_HANDLED; | 266 | return IRQ_HANDLED; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int __init s3c_adc_bat_probe(struct platform_device *pdev) | 269 | static int __devinit s3c_adc_bat_probe(struct platform_device *pdev) |
270 | { | 270 | { |
271 | struct s3c_adc_client *client; | 271 | struct s3c_adc_client *client; |
272 | struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; | 272 | struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; |
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index 92c16e1677bd..54b9198fa576 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #define TWL4030_MSTATEC_COMPLETE4 0x0e | 62 | #define TWL4030_MSTATEC_COMPLETE4 0x0e |
63 | 63 | ||
64 | static bool allow_usb; | 64 | static bool allow_usb; |
65 | module_param(allow_usb, bool, 1); | 65 | module_param(allow_usb, bool, 0644); |
66 | MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current"); | 66 | MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current"); |
67 | 67 | ||
68 | struct twl4030_bci { | 68 | struct twl4030_bci { |
@@ -425,7 +425,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
425 | { | 425 | { |
426 | struct twl4030_bci *bci; | 426 | struct twl4030_bci *bci; |
427 | int ret; | 427 | int ret; |
428 | int reg; | 428 | u32 reg; |
429 | 429 | ||
430 | bci = kzalloc(sizeof(*bci), GFP_KERNEL); | 430 | bci = kzalloc(sizeof(*bci), GFP_KERNEL); |
431 | if (bci == NULL) | 431 | if (bci == NULL) |
@@ -486,7 +486,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
486 | } | 486 | } |
487 | 487 | ||
488 | /* Enable interrupts now. */ | 488 | /* Enable interrupts now. */ |
489 | reg = ~(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 | | 489 | reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 | |
490 | TWL4030_TBATOR1 | TWL4030_BATSTS); | 490 | TWL4030_TBATOR1 | TWL4030_BATSTS); |
491 | ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, | 491 | ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, |
492 | TWL4030_INTERRUPTS_BCIIMR1A); | 492 | TWL4030_INTERRUPTS_BCIIMR1A); |
@@ -495,7 +495,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
495 | goto fail_unmask_interrupts; | 495 | goto fail_unmask_interrupts; |
496 | } | 496 | } |
497 | 497 | ||
498 | reg = ~(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV); | 498 | reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV); |
499 | ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, | 499 | ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, |
500 | TWL4030_INTERRUPTS_BCIIMR2A); | 500 | TWL4030_INTERRUPTS_BCIIMR2A); |
501 | if (ret < 0) | 501 | if (ret < 0) |
@@ -572,7 +572,7 @@ static void __exit twl4030_bci_exit(void) | |||
572 | } | 572 | } |
573 | module_exit(twl4030_bci_exit); | 573 | module_exit(twl4030_bci_exit); |
574 | 574 | ||
575 | MODULE_AUTHOR("Gražydas Ignotas"); | 575 | MODULE_AUTHOR("Gražvydas Ignotas"); |
576 | MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver"); | 576 | MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver"); |
577 | MODULE_LICENSE("GPL"); | 577 | MODULE_LICENSE("GPL"); |
578 | MODULE_ALIAS("platform:twl4030_bci"); | 578 | MODULE_ALIAS("platform:twl4030_bci"); |
diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index 0fd130d80f5d..e648cbea1e6a 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c | |||
@@ -22,6 +22,7 @@ | |||
22 | struct wm831x_backup { | 22 | struct wm831x_backup { |
23 | struct wm831x *wm831x; | 23 | struct wm831x *wm831x; |
24 | struct power_supply backup; | 24 | struct power_supply backup; |
25 | char name[20]; | ||
25 | }; | 26 | }; |
26 | 27 | ||
27 | static int wm831x_backup_read_voltage(struct wm831x *wm831x, | 28 | static int wm831x_backup_read_voltage(struct wm831x *wm831x, |
@@ -163,6 +164,7 @@ static enum power_supply_property wm831x_backup_props[] = { | |||
163 | static __devinit int wm831x_backup_probe(struct platform_device *pdev) | 164 | static __devinit int wm831x_backup_probe(struct platform_device *pdev) |
164 | { | 165 | { |
165 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 166 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
167 | struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; | ||
166 | struct wm831x_backup *devdata; | 168 | struct wm831x_backup *devdata; |
167 | struct power_supply *backup; | 169 | struct power_supply *backup; |
168 | int ret; | 170 | int ret; |
@@ -182,7 +184,14 @@ static __devinit int wm831x_backup_probe(struct platform_device *pdev) | |||
182 | */ | 184 | */ |
183 | wm831x_config_backup(wm831x); | 185 | wm831x_config_backup(wm831x); |
184 | 186 | ||
185 | backup->name = "wm831x-backup"; | 187 | if (wm831x_pdata && wm831x_pdata->wm831x_num) |
188 | snprintf(devdata->name, sizeof(devdata->name), | ||
189 | "wm831x-backup.%d", wm831x_pdata->wm831x_num); | ||
190 | else | ||
191 | snprintf(devdata->name, sizeof(devdata->name), | ||
192 | "wm831x-backup"); | ||
193 | |||
194 | backup->name = devdata->name; | ||
186 | backup->type = POWER_SUPPLY_TYPE_BATTERY; | 195 | backup->type = POWER_SUPPLY_TYPE_BATTERY; |
187 | backup->properties = wm831x_backup_props; | 196 | backup->properties = wm831x_backup_props; |
188 | backup->num_properties = ARRAY_SIZE(wm831x_backup_props); | 197 | backup->num_properties = ARRAY_SIZE(wm831x_backup_props); |
@@ -203,6 +212,7 @@ static __devexit int wm831x_backup_remove(struct platform_device *pdev) | |||
203 | struct wm831x_backup *devdata = platform_get_drvdata(pdev); | 212 | struct wm831x_backup *devdata = platform_get_drvdata(pdev); |
204 | 213 | ||
205 | power_supply_unregister(&devdata->backup); | 214 | power_supply_unregister(&devdata->backup); |
215 | kfree(devdata->backup.name); | ||
206 | kfree(devdata); | 216 | kfree(devdata); |
207 | 217 | ||
208 | return 0; | 218 | return 0; |
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index ddf8cf5f3204..6cc2ca6427f3 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c | |||
@@ -24,6 +24,9 @@ struct wm831x_power { | |||
24 | struct power_supply wall; | 24 | struct power_supply wall; |
25 | struct power_supply usb; | 25 | struct power_supply usb; |
26 | struct power_supply battery; | 26 | struct power_supply battery; |
27 | char wall_name[20]; | ||
28 | char usb_name[20]; | ||
29 | char battery_name[20]; | ||
27 | }; | 30 | }; |
28 | 31 | ||
29 | static int wm831x_power_check_online(struct wm831x *wm831x, int supply, | 32 | static int wm831x_power_check_online(struct wm831x *wm831x, int supply, |
@@ -486,6 +489,7 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data) | |||
486 | static __devinit int wm831x_power_probe(struct platform_device *pdev) | 489 | static __devinit int wm831x_power_probe(struct platform_device *pdev) |
487 | { | 490 | { |
488 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 491 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
492 | struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data; | ||
489 | struct wm831x_power *power; | 493 | struct wm831x_power *power; |
490 | struct power_supply *usb; | 494 | struct power_supply *usb; |
491 | struct power_supply *battery; | 495 | struct power_supply *battery; |
@@ -503,12 +507,28 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) | |||
503 | battery = &power->battery; | 507 | battery = &power->battery; |
504 | wall = &power->wall; | 508 | wall = &power->wall; |
505 | 509 | ||
510 | if (wm831x_pdata && wm831x_pdata->wm831x_num) { | ||
511 | snprintf(power->wall_name, sizeof(power->wall_name), | ||
512 | "wm831x-wall.%d", wm831x_pdata->wm831x_num); | ||
513 | snprintf(power->battery_name, sizeof(power->wall_name), | ||
514 | "wm831x-battery.%d", wm831x_pdata->wm831x_num); | ||
515 | snprintf(power->usb_name, sizeof(power->wall_name), | ||
516 | "wm831x-usb.%d", wm831x_pdata->wm831x_num); | ||
517 | } else { | ||
518 | snprintf(power->wall_name, sizeof(power->wall_name), | ||
519 | "wm831x-wall"); | ||
520 | snprintf(power->battery_name, sizeof(power->wall_name), | ||
521 | "wm831x-battery"); | ||
522 | snprintf(power->usb_name, sizeof(power->wall_name), | ||
523 | "wm831x-usb"); | ||
524 | } | ||
525 | |||
506 | /* We ignore configuration failures since we can still read back | 526 | /* We ignore configuration failures since we can still read back |
507 | * the status without enabling the charger. | 527 | * the status without enabling the charger. |
508 | */ | 528 | */ |
509 | wm831x_config_battery(wm831x); | 529 | wm831x_config_battery(wm831x); |
510 | 530 | ||
511 | wall->name = "wm831x-wall"; | 531 | wall->name = power->wall_name; |
512 | wall->type = POWER_SUPPLY_TYPE_MAINS; | 532 | wall->type = POWER_SUPPLY_TYPE_MAINS; |
513 | wall->properties = wm831x_wall_props; | 533 | wall->properties = wm831x_wall_props; |
514 | wall->num_properties = ARRAY_SIZE(wm831x_wall_props); | 534 | wall->num_properties = ARRAY_SIZE(wm831x_wall_props); |
@@ -517,7 +537,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) | |||
517 | if (ret) | 537 | if (ret) |
518 | goto err_kmalloc; | 538 | goto err_kmalloc; |
519 | 539 | ||
520 | battery->name = "wm831x-battery"; | 540 | battery->name = power->battery_name; |
521 | battery->properties = wm831x_bat_props; | 541 | battery->properties = wm831x_bat_props; |
522 | battery->num_properties = ARRAY_SIZE(wm831x_bat_props); | 542 | battery->num_properties = ARRAY_SIZE(wm831x_bat_props); |
523 | battery->get_property = wm831x_bat_get_prop; | 543 | battery->get_property = wm831x_bat_get_prop; |
@@ -526,7 +546,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) | |||
526 | if (ret) | 546 | if (ret) |
527 | goto err_wall; | 547 | goto err_wall; |
528 | 548 | ||
529 | usb->name = "wm831x-usb", | 549 | usb->name = power->usb_name, |
530 | usb->type = POWER_SUPPLY_TYPE_USB; | 550 | usb->type = POWER_SUPPLY_TYPE_USB; |
531 | usb->properties = wm831x_usb_props; | 551 | usb->properties = wm831x_usb_props; |
532 | usb->num_properties = ARRAY_SIZE(wm831x_usb_props); | 552 | usb->num_properties = ARRAY_SIZE(wm831x_usb_props); |