diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-31 18:25:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-31 18:25:16 -0400 |
commit | c8192ba416397ad6ce493f186da40767ce086c3b (patch) | |
tree | 2872bdbf2e40d5709e246fff8f3456b639f1bb79 | |
parent | 9c6a019c6edf8591e34ae9da51bac7684131d905 (diff) | |
parent | b68c3161430a4c7c0a001e658188bfea6a2fe5bd (diff) |
Merge tag 'for-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset changes from Sebastian Reichel:
- new reset driver for ZTE SoCs
- add support for sama5d3 reset handling
- overhaul of twl4030 charger driver
- misc fixes and cleanups
* tag 'for-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (35 commits)
bq2415x_charger: Allow to load and use driver even if notify device is not registered yet
twl4030_charger: fix compile error when TWL4030_MADC not available.
power: bq24190_charger: Fix charge type sysfs property
power: Allow compile test of GPIO consumers if !GPIOLIB
power: Export I2C module alias information in missing drivers
twl4030_charger: Increase current carefully while watching voltage.
twl4030_charger: add ac/mode to match usb/mode
twl4030_charger: add software controlled linear charging mode.
twl4030_charger: enable manual enable/disable of usb charging.
twl4030_charger: allow max_current to be managed via sysfs.
twl4030_charger: distinguish between USB current and 'AC' current
twl4030_charger: allow fine control of charger current.
twl4030_charger: split uA calculation into a function.
twl4030_charger: trust phy to determine when USB power is available.
twl4030_charger: correctly handle -EPROBE_DEFER from devm_usb_get_phy_by_node
twl4030_charger: convert to module_platform_driver instead of ..._probe.
twl4030_charger: use runtime_pm to keep usb phy active while charging.
rx51-battery: Set name to rx51-battery
MAINTAINERS: AVS is not maintained via power supply tree
power: olpc_battery: clean up eeprom read function
...
-rw-r--r-- | Documentation/ABI/testing/sysfs-class-power-twl4030 | 45 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/arm/atmel-at91.txt | 2 | ||||
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/mfd/twl-core.c | 9 | ||||
-rw-r--r-- | drivers/power/Kconfig | 17 | ||||
-rw-r--r-- | drivers/power/bq2415x_charger.c | 143 | ||||
-rw-r--r-- | drivers/power/bq24190_charger.c | 4 | ||||
-rw-r--r-- | drivers/power/bq24735-charger.c | 52 | ||||
-rw-r--r-- | drivers/power/bq27x00_battery.c | 123 | ||||
-rw-r--r-- | drivers/power/ds2780_battery.c | 20 | ||||
-rw-r--r-- | drivers/power/ds2781_battery.c | 8 | ||||
-rw-r--r-- | drivers/power/ltc2941-battery-gauge.c | 54 | ||||
-rw-r--r-- | drivers/power/olpc_battery.c | 7 | ||||
-rw-r--r-- | drivers/power/pm2301_charger.c | 1 | ||||
-rw-r--r-- | drivers/power/reset/Kconfig | 7 | ||||
-rw-r--r-- | drivers/power/reset/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/reset/at91-reset.c | 26 | ||||
-rw-r--r-- | drivers/power/reset/zx-reboot.c | 80 | ||||
-rw-r--r-- | drivers/power/rt5033_battery.c | 2 | ||||
-rw-r--r-- | drivers/power/rt9455_charger.c | 16 | ||||
-rw-r--r-- | drivers/power/rx51_battery.c | 2 | ||||
-rw-r--r-- | drivers/power/twl4030_charger.c | 598 |
22 files changed, 862 insertions, 356 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-power-twl4030 b/Documentation/ABI/testing/sysfs-class-power-twl4030 new file mode 100644 index 000000000000..be26af0f1895 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-power-twl4030 | |||
@@ -0,0 +1,45 @@ | |||
1 | What: /sys/class/power_supply/twl4030_ac/max_current | ||
2 | /sys/class/power_supply/twl4030_usb/max_current | ||
3 | Description: | ||
4 | Read/Write limit on current which may | ||
5 | be drawn from the ac (Accessory Charger) or | ||
6 | USB port. | ||
7 | |||
8 | Value is in micro-Amps. | ||
9 | |||
10 | Value is set automatically to an appropriate | ||
11 | value when a cable is plugged or unplugged. | ||
12 | |||
13 | Value can the set by writing to the attribute. | ||
14 | The change will only persist until the next | ||
15 | plug event. These event are reported via udev. | ||
16 | |||
17 | |||
18 | What: /sys/class/power_supply/twl4030_usb/mode | ||
19 | Description: | ||
20 | Changing mode for USB port. | ||
21 | Writing to this can disable charging. | ||
22 | |||
23 | Possible values are: | ||
24 | "auto" - draw power as appropriate for detected | ||
25 | power source and battery status. | ||
26 | "off" - do not draw any power. | ||
27 | "continuous" | ||
28 | - activate mode described as "linear" in | ||
29 | TWL data sheets. This uses whatever | ||
30 | current is available and doesn't switch off | ||
31 | when voltage drops. | ||
32 | |||
33 | This is useful for unstable power sources | ||
34 | such as bicycle dynamo, but care should | ||
35 | be taken that battery is not over-charged. | ||
36 | |||
37 | What: /sys/class/power_supply/twl4030_ac/mode | ||
38 | Description: | ||
39 | Changing mode for 'ac' port. | ||
40 | Writing to this can disable charging. | ||
41 | |||
42 | Possible values are: | ||
43 | "auto" - draw power as appropriate for detected | ||
44 | power source and battery status. | ||
45 | "off" - do not draw any power. | ||
diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt index 424ac8cbfa08..dd998b9c0433 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt | |||
@@ -87,7 +87,7 @@ One interrupt per TC channel in a TC block: | |||
87 | 87 | ||
88 | RSTC Reset Controller required properties: | 88 | RSTC Reset Controller required properties: |
89 | - compatible: Should be "atmel,<chip>-rstc". | 89 | - compatible: Should be "atmel,<chip>-rstc". |
90 | <chip> can be "at91sam9260" or "at91sam9g45" | 90 | <chip> can be "at91sam9260" or "at91sam9g45" or "sama5d3" |
91 | - reg: Should contain registers location and length | 91 | - reg: Should contain registers location and length |
92 | 92 | ||
93 | Example: | 93 | Example: |
diff --git a/MAINTAINERS b/MAINTAINERS index 8b3115cd762e..d53955790f7e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -8093,6 +8093,7 @@ T: git git://git.infradead.org/battery-2.6.git | |||
8093 | S: Maintained | 8093 | S: Maintained |
8094 | F: include/linux/power_supply.h | 8094 | F: include/linux/power_supply.h |
8095 | F: drivers/power/ | 8095 | F: drivers/power/ |
8096 | X: drivers/power/avs/ | ||
8096 | 8097 | ||
8097 | PNP SUPPORT | 8098 | PNP SUPPORT |
8098 | M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> | 8099 | M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 489674a2497e..831696ee2472 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -788,9 +788,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
788 | static struct regulator_consumer_supply usb1v8 = { | 788 | static struct regulator_consumer_supply usb1v8 = { |
789 | .supply = "usb1v8", | 789 | .supply = "usb1v8", |
790 | }; | 790 | }; |
791 | static struct regulator_consumer_supply usb3v1[] = { | 791 | static struct regulator_consumer_supply usb3v1 = { |
792 | { .supply = "usb3v1" }, | 792 | .supply = "usb3v1", |
793 | { .supply = "bci3v1" }, | ||
794 | }; | 793 | }; |
795 | 794 | ||
796 | /* First add the regulators so that they can be used by transceiver */ | 795 | /* First add the regulators so that they can be used by transceiver */ |
@@ -818,7 +817,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
818 | return PTR_ERR(child); | 817 | return PTR_ERR(child); |
819 | 818 | ||
820 | child = add_regulator_linked(TWL4030_REG_VUSB3V1, | 819 | child = add_regulator_linked(TWL4030_REG_VUSB3V1, |
821 | &usb_fixed, usb3v1, 2, | 820 | &usb_fixed, &usb3v1, 1, |
822 | features); | 821 | features); |
823 | if (IS_ERR(child)) | 822 | if (IS_ERR(child)) |
824 | return PTR_ERR(child); | 823 | return PTR_ERR(child); |
@@ -838,7 +837,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, | |||
838 | if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) { | 837 | if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) { |
839 | usb1v5.dev_name = dev_name(child); | 838 | usb1v5.dev_name = dev_name(child); |
840 | usb1v8.dev_name = dev_name(child); | 839 | usb1v8.dev_name = dev_name(child); |
841 | usb3v1[0].dev_name = dev_name(child); | 840 | usb3v1.dev_name = dev_name(child); |
842 | } | 841 | } |
843 | } | 842 | } |
844 | 843 | ||
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 08beeed5485d..f8758d6febf8 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
@@ -333,7 +333,7 @@ config CHARGER_LP8788 | |||
333 | 333 | ||
334 | config CHARGER_GPIO | 334 | config CHARGER_GPIO |
335 | tristate "GPIO charger" | 335 | tristate "GPIO charger" |
336 | depends on GPIOLIB | 336 | depends on GPIOLIB || COMPILE_TEST |
337 | help | 337 | help |
338 | Say Y to include support for chargers which report their online status | 338 | Say Y to include support for chargers which report their online status |
339 | through a GPIO pin. | 339 | through a GPIO pin. |
@@ -391,26 +391,30 @@ config CHARGER_BQ2415X | |||
391 | 391 | ||
392 | config CHARGER_BQ24190 | 392 | config CHARGER_BQ24190 |
393 | tristate "TI BQ24190 battery charger driver" | 393 | tristate "TI BQ24190 battery charger driver" |
394 | depends on I2C && GPIOLIB | 394 | depends on I2C |
395 | depends on GPIOLIB || COMPILE_TEST | ||
395 | help | 396 | help |
396 | Say Y to enable support for the TI BQ24190 battery charger. | 397 | Say Y to enable support for the TI BQ24190 battery charger. |
397 | 398 | ||
398 | config CHARGER_BQ24257 | 399 | config CHARGER_BQ24257 |
399 | tristate "TI BQ24257 battery charger driver" | 400 | tristate "TI BQ24257 battery charger driver" |
400 | depends on I2C && GPIOLIB | 401 | depends on I2C |
402 | depends on GPIOLIB || COMPILE_TEST | ||
401 | depends on REGMAP_I2C | 403 | depends on REGMAP_I2C |
402 | help | 404 | help |
403 | Say Y to enable support for the TI BQ24257 battery charger. | 405 | Say Y to enable support for the TI BQ24257 battery charger. |
404 | 406 | ||
405 | config CHARGER_BQ24735 | 407 | config CHARGER_BQ24735 |
406 | tristate "TI BQ24735 battery charger support" | 408 | tristate "TI BQ24735 battery charger support" |
407 | depends on I2C && GPIOLIB | 409 | depends on I2C |
410 | depends on GPIOLIB || COMPILE_TEST | ||
408 | help | 411 | help |
409 | Say Y to enable support for the TI BQ24735 battery charger. | 412 | Say Y to enable support for the TI BQ24735 battery charger. |
410 | 413 | ||
411 | config CHARGER_BQ25890 | 414 | config CHARGER_BQ25890 |
412 | tristate "TI BQ25890 battery charger driver" | 415 | tristate "TI BQ25890 battery charger driver" |
413 | depends on I2C && GPIOLIB | 416 | depends on I2C |
417 | depends on GPIOLIB || COMPILE_TEST | ||
414 | select REGMAP_I2C | 418 | select REGMAP_I2C |
415 | help | 419 | help |
416 | Say Y to enable support for the TI BQ25890 battery charger. | 420 | Say Y to enable support for the TI BQ25890 battery charger. |
@@ -462,7 +466,8 @@ config BATTERY_RT5033 | |||
462 | 466 | ||
463 | config CHARGER_RT9455 | 467 | config CHARGER_RT9455 |
464 | tristate "Richtek RT9455 battery charger driver" | 468 | tristate "Richtek RT9455 battery charger driver" |
465 | depends on I2C && GPIOLIB | 469 | depends on I2C |
470 | depends on GPIOLIB || COMPILE_TEST | ||
466 | select REGMAP_I2C | 471 | select REGMAP_I2C |
467 | help | 472 | help |
468 | Say Y to enable support for Richtek RT9455 battery charger. | 473 | Say Y to enable support for Richtek RT9455 battery charger. |
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c index e98dcb661cc9..ec212b5be755 100644 --- a/drivers/power/bq2415x_charger.c +++ b/drivers/power/bq2415x_charger.c | |||
@@ -170,7 +170,7 @@ struct bq2415x_device { | |||
170 | struct power_supply *charger; | 170 | struct power_supply *charger; |
171 | struct power_supply_desc charger_desc; | 171 | struct power_supply_desc charger_desc; |
172 | struct delayed_work work; | 172 | struct delayed_work work; |
173 | struct power_supply *notify_psy; | 173 | struct device_node *notify_node; |
174 | struct notifier_block nb; | 174 | struct notifier_block nb; |
175 | enum bq2415x_mode reported_mode;/* mode reported by hook function */ | 175 | enum bq2415x_mode reported_mode;/* mode reported by hook function */ |
176 | enum bq2415x_mode mode; /* currently configured mode */ | 176 | enum bq2415x_mode mode; /* currently configured mode */ |
@@ -792,22 +792,47 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode) | |||
792 | 792 | ||
793 | } | 793 | } |
794 | 794 | ||
795 | static bool bq2415x_update_reported_mode(struct bq2415x_device *bq, int mA) | ||
796 | { | ||
797 | enum bq2415x_mode mode; | ||
798 | |||
799 | if (mA == 0) | ||
800 | mode = BQ2415X_MODE_OFF; | ||
801 | else if (mA < 500) | ||
802 | mode = BQ2415X_MODE_NONE; | ||
803 | else if (mA < 1800) | ||
804 | mode = BQ2415X_MODE_HOST_CHARGER; | ||
805 | else | ||
806 | mode = BQ2415X_MODE_DEDICATED_CHARGER; | ||
807 | |||
808 | if (bq->reported_mode == mode) | ||
809 | return false; | ||
810 | |||
811 | bq->reported_mode = mode; | ||
812 | return true; | ||
813 | } | ||
814 | |||
795 | static int bq2415x_notifier_call(struct notifier_block *nb, | 815 | static int bq2415x_notifier_call(struct notifier_block *nb, |
796 | unsigned long val, void *v) | 816 | unsigned long val, void *v) |
797 | { | 817 | { |
798 | struct bq2415x_device *bq = | 818 | struct bq2415x_device *bq = |
799 | container_of(nb, struct bq2415x_device, nb); | 819 | container_of(nb, struct bq2415x_device, nb); |
800 | struct power_supply *psy = v; | 820 | struct power_supply *psy = v; |
801 | enum bq2415x_mode mode; | ||
802 | union power_supply_propval prop; | 821 | union power_supply_propval prop; |
803 | int ret; | 822 | int ret; |
804 | int mA; | ||
805 | 823 | ||
806 | if (val != PSY_EVENT_PROP_CHANGED) | 824 | if (val != PSY_EVENT_PROP_CHANGED) |
807 | return NOTIFY_OK; | 825 | return NOTIFY_OK; |
808 | 826 | ||
809 | if (psy != bq->notify_psy) | 827 | /* Ignore event if it was not send by notify_node/notify_device */ |
810 | return NOTIFY_OK; | 828 | if (bq->notify_node) { |
829 | if (!psy->dev.parent || | ||
830 | psy->dev.parent->of_node != bq->notify_node) | ||
831 | return NOTIFY_OK; | ||
832 | } else if (bq->init_data.notify_device) { | ||
833 | if (strcmp(psy->desc->name, bq->init_data.notify_device) != 0) | ||
834 | return NOTIFY_OK; | ||
835 | } | ||
811 | 836 | ||
812 | dev_dbg(bq->dev, "notifier call was called\n"); | 837 | dev_dbg(bq->dev, "notifier call was called\n"); |
813 | 838 | ||
@@ -816,22 +841,9 @@ static int bq2415x_notifier_call(struct notifier_block *nb, | |||
816 | if (ret != 0) | 841 | if (ret != 0) |
817 | return NOTIFY_OK; | 842 | return NOTIFY_OK; |
818 | 843 | ||
819 | mA = prop.intval; | 844 | if (!bq2415x_update_reported_mode(bq, prop.intval)) |
820 | |||
821 | if (mA == 0) | ||
822 | mode = BQ2415X_MODE_OFF; | ||
823 | else if (mA < 500) | ||
824 | mode = BQ2415X_MODE_NONE; | ||
825 | else if (mA < 1800) | ||
826 | mode = BQ2415X_MODE_HOST_CHARGER; | ||
827 | else | ||
828 | mode = BQ2415X_MODE_DEDICATED_CHARGER; | ||
829 | |||
830 | if (bq->reported_mode == mode) | ||
831 | return NOTIFY_OK; | 845 | return NOTIFY_OK; |
832 | 846 | ||
833 | bq->reported_mode = mode; | ||
834 | |||
835 | /* if automode is not enabled do not tell about reported_mode */ | 847 | /* if automode is not enabled do not tell about reported_mode */ |
836 | if (bq->automode < 1) | 848 | if (bq->automode < 1) |
837 | return NOTIFY_OK; | 849 | return NOTIFY_OK; |
@@ -1536,6 +1548,8 @@ static int bq2415x_probe(struct i2c_client *client, | |||
1536 | struct device_node *np = client->dev.of_node; | 1548 | struct device_node *np = client->dev.of_node; |
1537 | struct bq2415x_platform_data *pdata = client->dev.platform_data; | 1549 | struct bq2415x_platform_data *pdata = client->dev.platform_data; |
1538 | const struct acpi_device_id *acpi_id = NULL; | 1550 | const struct acpi_device_id *acpi_id = NULL; |
1551 | struct power_supply *notify_psy = NULL; | ||
1552 | union power_supply_propval prop; | ||
1539 | 1553 | ||
1540 | if (!np && !pdata && !ACPI_HANDLE(&client->dev)) { | 1554 | if (!np && !pdata && !ACPI_HANDLE(&client->dev)) { |
1541 | dev_err(&client->dev, "Neither devicetree, nor platform data, nor ACPI support\n"); | 1555 | dev_err(&client->dev, "Neither devicetree, nor platform data, nor ACPI support\n"); |
@@ -1569,25 +1583,6 @@ static int bq2415x_probe(struct i2c_client *client, | |||
1569 | goto error_2; | 1583 | goto error_2; |
1570 | } | 1584 | } |
1571 | 1585 | ||
1572 | if (np) { | ||
1573 | bq->notify_psy = power_supply_get_by_phandle(np, | ||
1574 | "ti,usb-charger-detection"); | ||
1575 | |||
1576 | if (IS_ERR(bq->notify_psy)) { | ||
1577 | dev_info(&client->dev, | ||
1578 | "no 'ti,usb-charger-detection' property (err=%ld)\n", | ||
1579 | PTR_ERR(bq->notify_psy)); | ||
1580 | bq->notify_psy = NULL; | ||
1581 | } else if (!bq->notify_psy) { | ||
1582 | ret = -EPROBE_DEFER; | ||
1583 | goto error_2; | ||
1584 | } | ||
1585 | } else if (pdata && pdata->notify_device) { | ||
1586 | bq->notify_psy = power_supply_get_by_name(pdata->notify_device); | ||
1587 | } else { | ||
1588 | bq->notify_psy = NULL; | ||
1589 | } | ||
1590 | |||
1591 | i2c_set_clientdata(client, bq); | 1586 | i2c_set_clientdata(client, bq); |
1592 | 1587 | ||
1593 | bq->id = num; | 1588 | bq->id = num; |
@@ -1607,32 +1602,35 @@ static int bq2415x_probe(struct i2c_client *client, | |||
1607 | "ti,current-limit", | 1602 | "ti,current-limit", |
1608 | &bq->init_data.current_limit); | 1603 | &bq->init_data.current_limit); |
1609 | if (ret) | 1604 | if (ret) |
1610 | goto error_3; | 1605 | goto error_2; |
1611 | ret = device_property_read_u32(bq->dev, | 1606 | ret = device_property_read_u32(bq->dev, |
1612 | "ti,weak-battery-voltage", | 1607 | "ti,weak-battery-voltage", |
1613 | &bq->init_data.weak_battery_voltage); | 1608 | &bq->init_data.weak_battery_voltage); |
1614 | if (ret) | 1609 | if (ret) |
1615 | goto error_3; | 1610 | goto error_2; |
1616 | ret = device_property_read_u32(bq->dev, | 1611 | ret = device_property_read_u32(bq->dev, |
1617 | "ti,battery-regulation-voltage", | 1612 | "ti,battery-regulation-voltage", |
1618 | &bq->init_data.battery_regulation_voltage); | 1613 | &bq->init_data.battery_regulation_voltage); |
1619 | if (ret) | 1614 | if (ret) |
1620 | goto error_3; | 1615 | goto error_2; |
1621 | ret = device_property_read_u32(bq->dev, | 1616 | ret = device_property_read_u32(bq->dev, |
1622 | "ti,charge-current", | 1617 | "ti,charge-current", |
1623 | &bq->init_data.charge_current); | 1618 | &bq->init_data.charge_current); |
1624 | if (ret) | 1619 | if (ret) |
1625 | goto error_3; | 1620 | goto error_2; |
1626 | ret = device_property_read_u32(bq->dev, | 1621 | ret = device_property_read_u32(bq->dev, |
1627 | "ti,termination-current", | 1622 | "ti,termination-current", |
1628 | &bq->init_data.termination_current); | 1623 | &bq->init_data.termination_current); |
1629 | if (ret) | 1624 | if (ret) |
1630 | goto error_3; | 1625 | goto error_2; |
1631 | ret = device_property_read_u32(bq->dev, | 1626 | ret = device_property_read_u32(bq->dev, |
1632 | "ti,resistor-sense", | 1627 | "ti,resistor-sense", |
1633 | &bq->init_data.resistor_sense); | 1628 | &bq->init_data.resistor_sense); |
1634 | if (ret) | 1629 | if (ret) |
1635 | goto error_3; | 1630 | goto error_2; |
1631 | if (np) | ||
1632 | bq->notify_node = of_parse_phandle(np, | ||
1633 | "ti,usb-charger-detection", 0); | ||
1636 | } else { | 1634 | } else { |
1637 | memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); | 1635 | memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); |
1638 | } | 1636 | } |
@@ -1642,56 +1640,72 @@ static int bq2415x_probe(struct i2c_client *client, | |||
1642 | ret = bq2415x_power_supply_init(bq); | 1640 | ret = bq2415x_power_supply_init(bq); |
1643 | if (ret) { | 1641 | if (ret) { |
1644 | dev_err(bq->dev, "failed to register power supply: %d\n", ret); | 1642 | dev_err(bq->dev, "failed to register power supply: %d\n", ret); |
1645 | goto error_3; | 1643 | goto error_2; |
1646 | } | 1644 | } |
1647 | 1645 | ||
1648 | ret = bq2415x_sysfs_init(bq); | 1646 | ret = bq2415x_sysfs_init(bq); |
1649 | if (ret) { | 1647 | if (ret) { |
1650 | dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret); | 1648 | dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret); |
1651 | goto error_4; | 1649 | goto error_3; |
1652 | } | 1650 | } |
1653 | 1651 | ||
1654 | ret = bq2415x_set_defaults(bq); | 1652 | ret = bq2415x_set_defaults(bq); |
1655 | if (ret) { | 1653 | if (ret) { |
1656 | dev_err(bq->dev, "failed to set default values: %d\n", ret); | 1654 | dev_err(bq->dev, "failed to set default values: %d\n", ret); |
1657 | goto error_5; | 1655 | goto error_4; |
1658 | } | 1656 | } |
1659 | 1657 | ||
1660 | if (bq->notify_psy) { | 1658 | if (bq->notify_node || bq->init_data.notify_device) { |
1661 | bq->nb.notifier_call = bq2415x_notifier_call; | 1659 | bq->nb.notifier_call = bq2415x_notifier_call; |
1662 | ret = power_supply_reg_notifier(&bq->nb); | 1660 | ret = power_supply_reg_notifier(&bq->nb); |
1663 | if (ret) { | 1661 | if (ret) { |
1664 | dev_err(bq->dev, "failed to reg notifier: %d\n", ret); | 1662 | dev_err(bq->dev, "failed to reg notifier: %d\n", ret); |
1665 | goto error_6; | 1663 | goto error_4; |
1666 | } | 1664 | } |
1667 | 1665 | ||
1668 | /* Query for initial reported_mode and set it */ | ||
1669 | bq2415x_notifier_call(&bq->nb, PSY_EVENT_PROP_CHANGED, | ||
1670 | bq->notify_psy); | ||
1671 | bq2415x_set_mode(bq, bq->reported_mode); | ||
1672 | |||
1673 | bq->automode = 1; | 1666 | bq->automode = 1; |
1674 | dev_info(bq->dev, "automode enabled\n"); | 1667 | dev_info(bq->dev, "automode supported, waiting for events\n"); |
1675 | } else { | 1668 | } else { |
1676 | bq->automode = -1; | 1669 | bq->automode = -1; |
1677 | dev_info(bq->dev, "automode not supported\n"); | 1670 | dev_info(bq->dev, "automode not supported\n"); |
1678 | } | 1671 | } |
1679 | 1672 | ||
1673 | /* Query for initial reported_mode and set it */ | ||
1674 | if (bq->nb.notifier_call) { | ||
1675 | if (np) { | ||
1676 | notify_psy = power_supply_get_by_phandle(np, | ||
1677 | "ti,usb-charger-detection"); | ||
1678 | if (IS_ERR(notify_psy)) | ||
1679 | notify_psy = NULL; | ||
1680 | } else if (bq->init_data.notify_device) { | ||
1681 | notify_psy = power_supply_get_by_name( | ||
1682 | bq->init_data.notify_device); | ||
1683 | } | ||
1684 | } | ||
1685 | if (notify_psy) { | ||
1686 | ret = power_supply_get_property(notify_psy, | ||
1687 | POWER_SUPPLY_PROP_CURRENT_MAX, &prop); | ||
1688 | power_supply_put(notify_psy); | ||
1689 | |||
1690 | if (ret == 0) { | ||
1691 | bq2415x_update_reported_mode(bq, prop.intval); | ||
1692 | bq2415x_set_mode(bq, bq->reported_mode); | ||
1693 | } | ||
1694 | } | ||
1695 | |||
1680 | INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work); | 1696 | INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work); |
1681 | bq2415x_set_autotimer(bq, 1); | 1697 | bq2415x_set_autotimer(bq, 1); |
1682 | 1698 | ||
1683 | dev_info(bq->dev, "driver registered\n"); | 1699 | dev_info(bq->dev, "driver registered\n"); |
1684 | return 0; | 1700 | return 0; |
1685 | 1701 | ||
1686 | error_6: | ||
1687 | error_5: | ||
1688 | bq2415x_sysfs_exit(bq); | ||
1689 | error_4: | 1702 | error_4: |
1690 | bq2415x_power_supply_exit(bq); | 1703 | bq2415x_sysfs_exit(bq); |
1691 | error_3: | 1704 | error_3: |
1692 | if (bq->notify_psy) | 1705 | bq2415x_power_supply_exit(bq); |
1693 | power_supply_put(bq->notify_psy); | ||
1694 | error_2: | 1706 | error_2: |
1707 | if (bq->notify_node) | ||
1708 | of_node_put(bq->notify_node); | ||
1695 | kfree(name); | 1709 | kfree(name); |
1696 | error_1: | 1710 | error_1: |
1697 | mutex_lock(&bq2415x_id_mutex); | 1711 | mutex_lock(&bq2415x_id_mutex); |
@@ -1707,10 +1721,11 @@ static int bq2415x_remove(struct i2c_client *client) | |||
1707 | { | 1721 | { |
1708 | struct bq2415x_device *bq = i2c_get_clientdata(client); | 1722 | struct bq2415x_device *bq = i2c_get_clientdata(client); |
1709 | 1723 | ||
1710 | if (bq->notify_psy) { | 1724 | if (bq->nb.notifier_call) |
1711 | power_supply_unreg_notifier(&bq->nb); | 1725 | power_supply_unreg_notifier(&bq->nb); |
1712 | power_supply_put(bq->notify_psy); | 1726 | |
1713 | } | 1727 | if (bq->notify_node) |
1728 | of_node_put(bq->notify_node); | ||
1714 | 1729 | ||
1715 | bq2415x_sysfs_exit(bq); | 1730 | bq2415x_sysfs_exit(bq); |
1716 | bq2415x_power_supply_exit(bq); | 1731 | bq2415x_power_supply_exit(bq); |
diff --git a/drivers/power/bq24190_charger.c b/drivers/power/bq24190_charger.c index 052db78c3736..469a452cbe10 100644 --- a/drivers/power/bq24190_charger.c +++ b/drivers/power/bq24190_charger.c | |||
@@ -902,7 +902,7 @@ static int bq24190_charger_property_is_writeable(struct power_supply *psy, | |||
902 | } | 902 | } |
903 | 903 | ||
904 | static enum power_supply_property bq24190_charger_properties[] = { | 904 | static enum power_supply_property bq24190_charger_properties[] = { |
905 | POWER_SUPPLY_PROP_TYPE, | 905 | POWER_SUPPLY_PROP_CHARGE_TYPE, |
906 | POWER_SUPPLY_PROP_HEALTH, | 906 | POWER_SUPPLY_PROP_HEALTH, |
907 | POWER_SUPPLY_PROP_ONLINE, | 907 | POWER_SUPPLY_PROP_ONLINE, |
908 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, | 908 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, |
@@ -1515,6 +1515,7 @@ static const struct i2c_device_id bq24190_i2c_ids[] = { | |||
1515 | { "bq24190", BQ24190_REG_VPRS_PN_24190 }, | 1515 | { "bq24190", BQ24190_REG_VPRS_PN_24190 }, |
1516 | { }, | 1516 | { }, |
1517 | }; | 1517 | }; |
1518 | MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids); | ||
1518 | 1519 | ||
1519 | #ifdef CONFIG_OF | 1520 | #ifdef CONFIG_OF |
1520 | static const struct of_device_id bq24190_of_match[] = { | 1521 | static const struct of_device_id bq24190_of_match[] = { |
@@ -1534,7 +1535,6 @@ static struct i2c_driver bq24190_driver = { | |||
1534 | .id_table = bq24190_i2c_ids, | 1535 | .id_table = bq24190_i2c_ids, |
1535 | .driver = { | 1536 | .driver = { |
1536 | .name = "bq24190-charger", | 1537 | .name = "bq24190-charger", |
1537 | .owner = THIS_MODULE, | ||
1538 | .pm = &bq24190_pm_ops, | 1538 | .pm = &bq24190_pm_ops, |
1539 | .of_match_table = of_match_ptr(bq24190_of_match), | 1539 | .of_match_table = of_match_ptr(bq24190_of_match), |
1540 | }, | 1540 | }, |
diff --git a/drivers/power/bq24735-charger.c b/drivers/power/bq24735-charger.c index 961a18930027..eb2b3689de97 100644 --- a/drivers/power/bq24735-charger.c +++ b/drivers/power/bq24735-charger.c | |||
@@ -267,8 +267,9 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
267 | 267 | ||
268 | name = (char *)charger->pdata->name; | 268 | name = (char *)charger->pdata->name; |
269 | if (!name) { | 269 | if (!name) { |
270 | name = kasprintf(GFP_KERNEL, "bq24735@%s", | 270 | name = devm_kasprintf(&client->dev, GFP_KERNEL, |
271 | dev_name(&client->dev)); | 271 | "bq24735@%s", |
272 | dev_name(&client->dev)); | ||
272 | if (!name) { | 273 | if (!name) { |
273 | dev_err(&client->dev, "Failed to alloc device name\n"); | 274 | dev_err(&client->dev, "Failed to alloc device name\n"); |
274 | return -ENOMEM; | 275 | return -ENOMEM; |
@@ -296,23 +297,21 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
296 | if (ret < 0) { | 297 | if (ret < 0) { |
297 | dev_err(&client->dev, "Failed to read manufacturer id : %d\n", | 298 | dev_err(&client->dev, "Failed to read manufacturer id : %d\n", |
298 | ret); | 299 | ret); |
299 | goto err_free_name; | 300 | return ret; |
300 | } else if (ret != 0x0040) { | 301 | } else if (ret != 0x0040) { |
301 | dev_err(&client->dev, | 302 | dev_err(&client->dev, |
302 | "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret); | 303 | "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret); |
303 | ret = -ENODEV; | 304 | return -ENODEV; |
304 | goto err_free_name; | ||
305 | } | 305 | } |
306 | 306 | ||
307 | ret = bq24735_read_word(client, BQ24735_DEVICE_ID); | 307 | ret = bq24735_read_word(client, BQ24735_DEVICE_ID); |
308 | if (ret < 0) { | 308 | if (ret < 0) { |
309 | dev_err(&client->dev, "Failed to read device id : %d\n", ret); | 309 | dev_err(&client->dev, "Failed to read device id : %d\n", ret); |
310 | goto err_free_name; | 310 | return ret; |
311 | } else if (ret != 0x000B) { | 311 | } else if (ret != 0x000B) { |
312 | dev_err(&client->dev, | 312 | dev_err(&client->dev, |
313 | "device id mismatch. 0x000b != 0x%04x\n", ret); | 313 | "device id mismatch. 0x000b != 0x%04x\n", ret); |
314 | ret = -ENODEV; | 314 | return -ENODEV; |
315 | goto err_free_name; | ||
316 | } | 315 | } |
317 | 316 | ||
318 | if (gpio_is_valid(charger->pdata->status_gpio)) { | 317 | if (gpio_is_valid(charger->pdata->status_gpio)) { |
@@ -331,7 +330,7 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
331 | ret = bq24735_config_charger(charger); | 330 | ret = bq24735_config_charger(charger); |
332 | if (ret < 0) { | 331 | if (ret < 0) { |
333 | dev_err(&client->dev, "failed in configuring charger"); | 332 | dev_err(&client->dev, "failed in configuring charger"); |
334 | goto err_free_name; | 333 | return ret; |
335 | } | 334 | } |
336 | 335 | ||
337 | /* check for AC adapter presence */ | 336 | /* check for AC adapter presence */ |
@@ -339,17 +338,17 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
339 | ret = bq24735_enable_charging(charger); | 338 | ret = bq24735_enable_charging(charger); |
340 | if (ret < 0) { | 339 | if (ret < 0) { |
341 | dev_err(&client->dev, "Failed to enable charging\n"); | 340 | dev_err(&client->dev, "Failed to enable charging\n"); |
342 | goto err_free_name; | 341 | return ret; |
343 | } | 342 | } |
344 | } | 343 | } |
345 | 344 | ||
346 | charger->charger = power_supply_register(&client->dev, supply_desc, | 345 | charger->charger = devm_power_supply_register(&client->dev, supply_desc, |
347 | &psy_cfg); | 346 | &psy_cfg); |
348 | if (IS_ERR(charger->charger)) { | 347 | if (IS_ERR(charger->charger)) { |
349 | ret = PTR_ERR(charger->charger); | 348 | ret = PTR_ERR(charger->charger); |
350 | dev_err(&client->dev, "Failed to register power supply: %d\n", | 349 | dev_err(&client->dev, "Failed to register power supply: %d\n", |
351 | ret); | 350 | ret); |
352 | goto err_free_name; | 351 | return ret; |
353 | } | 352 | } |
354 | 353 | ||
355 | if (client->irq) { | 354 | if (client->irq) { |
@@ -364,34 +363,11 @@ static int bq24735_charger_probe(struct i2c_client *client, | |||
364 | dev_err(&client->dev, | 363 | dev_err(&client->dev, |
365 | "Unable to register IRQ %d err %d\n", | 364 | "Unable to register IRQ %d err %d\n", |
366 | client->irq, ret); | 365 | client->irq, ret); |
367 | goto err_unregister_supply; | 366 | return ret; |
368 | } | 367 | } |
369 | } | 368 | } |
370 | 369 | ||
371 | return 0; | 370 | return 0; |
372 | err_unregister_supply: | ||
373 | power_supply_unregister(charger->charger); | ||
374 | err_free_name: | ||
375 | if (name != charger->pdata->name) | ||
376 | kfree(name); | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | |||
381 | static int bq24735_charger_remove(struct i2c_client *client) | ||
382 | { | ||
383 | struct bq24735 *charger = i2c_get_clientdata(client); | ||
384 | |||
385 | if (charger->client->irq) | ||
386 | devm_free_irq(&charger->client->dev, charger->client->irq, | ||
387 | &charger->charger); | ||
388 | |||
389 | power_supply_unregister(charger->charger); | ||
390 | |||
391 | if (charger->charger_desc.name != charger->pdata->name) | ||
392 | kfree(charger->charger_desc.name); | ||
393 | |||
394 | return 0; | ||
395 | } | 371 | } |
396 | 372 | ||
397 | static const struct i2c_device_id bq24735_charger_id[] = { | 373 | static const struct i2c_device_id bq24735_charger_id[] = { |
@@ -409,11 +385,9 @@ MODULE_DEVICE_TABLE(of, bq24735_match_ids); | |||
409 | static struct i2c_driver bq24735_charger_driver = { | 385 | static struct i2c_driver bq24735_charger_driver = { |
410 | .driver = { | 386 | .driver = { |
411 | .name = "bq24735-charger", | 387 | .name = "bq24735-charger", |
412 | .owner = THIS_MODULE, | ||
413 | .of_match_table = bq24735_match_ids, | 388 | .of_match_table = bq24735_match_ids, |
414 | }, | 389 | }, |
415 | .probe = bq24735_charger_probe, | 390 | .probe = bq24735_charger_probe, |
416 | .remove = bq24735_charger_remove, | ||
417 | .id_table = bq24735_charger_id, | 391 | .id_table = bq24735_charger_id, |
418 | }; | 392 | }; |
419 | 393 | ||
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index b6b98378faa3..8287261fd978 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c | |||
@@ -39,47 +39,49 @@ | |||
39 | 39 | ||
40 | #include <linux/power/bq27x00_battery.h> | 40 | #include <linux/power/bq27x00_battery.h> |
41 | 41 | ||
42 | #define DRIVER_VERSION "1.2.0" | 42 | #define DRIVER_VERSION "1.2.0" |
43 | 43 | ||
44 | #define BQ27x00_REG_TEMP 0x06 | 44 | #define BQ27XXX_MANUFACTURER "Texas Instruments" |
45 | #define BQ27x00_REG_VOLT 0x08 | 45 | |
46 | #define BQ27x00_REG_AI 0x14 | 46 | #define BQ27x00_REG_TEMP 0x06 |
47 | #define BQ27x00_REG_FLAGS 0x0A | 47 | #define BQ27x00_REG_VOLT 0x08 |
48 | #define BQ27x00_REG_TTE 0x16 | 48 | #define BQ27x00_REG_AI 0x14 |
49 | #define BQ27x00_REG_TTF 0x18 | 49 | #define BQ27x00_REG_FLAGS 0x0A |
50 | #define BQ27x00_REG_TTECP 0x26 | 50 | #define BQ27x00_REG_TTE 0x16 |
51 | #define BQ27x00_REG_NAC 0x0C /* Nominal available capacity */ | 51 | #define BQ27x00_REG_TTF 0x18 |
52 | #define BQ27x00_REG_LMD 0x12 /* Last measured discharge */ | 52 | #define BQ27x00_REG_TTECP 0x26 |
53 | #define BQ27x00_REG_CYCT 0x2A /* Cycle count total */ | 53 | #define BQ27x00_REG_NAC 0x0C /* Nominal available capacity */ |
54 | #define BQ27x00_REG_AE 0x22 /* Available energy */ | 54 | #define BQ27x00_REG_LMD 0x12 /* Last measured discharge */ |
55 | #define BQ27x00_POWER_AVG 0x24 | 55 | #define BQ27x00_REG_CYCT 0x2A /* Cycle count total */ |
56 | 56 | #define BQ27x00_REG_AE 0x22 /* Available energy */ | |
57 | #define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */ | 57 | #define BQ27x00_POWER_AVG 0x24 |
58 | #define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */ | 58 | |
59 | #define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */ | 59 | #define BQ27000_REG_RSOC 0x0B /* Relative State-of-Charge */ |
60 | #define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */ | 60 | #define BQ27000_REG_ILMD 0x76 /* Initial last measured discharge */ |
61 | #define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */ | 61 | #define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */ |
62 | #define BQ27000_FLAG_FC BIT(5) | 62 | #define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */ |
63 | #define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */ | 63 | #define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */ |
64 | 64 | #define BQ27000_FLAG_FC BIT(5) | |
65 | #define BQ27500_REG_SOC 0x2C | 65 | #define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */ |
66 | #define BQ27500_REG_DCAP 0x3C /* Design capacity */ | 66 | |
67 | #define BQ27500_FLAG_DSC BIT(0) | 67 | #define BQ27500_REG_SOC 0x2C |
68 | #define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */ | 68 | #define BQ27500_REG_DCAP 0x3C /* Design capacity */ |
69 | #define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */ | 69 | #define BQ27500_FLAG_DSC BIT(0) |
70 | #define BQ27500_FLAG_FC BIT(9) | 70 | #define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */ |
71 | #define BQ27500_FLAG_OTC BIT(15) | 71 | #define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */ |
72 | 72 | #define BQ27500_FLAG_FC BIT(9) | |
73 | #define BQ27742_POWER_AVG 0x76 | 73 | #define BQ27500_FLAG_OTC BIT(15) |
74 | 74 | ||
75 | #define BQ27510_REG_SOC 0x20 | 75 | #define BQ27742_POWER_AVG 0x76 |
76 | #define BQ27510_REG_DCAP 0x2E /* Design capacity */ | 76 | |
77 | #define BQ27510_REG_CYCT 0x1E /* Cycle count total */ | 77 | #define BQ27510_REG_SOC 0x20 |
78 | #define BQ27510_REG_DCAP 0x2E /* Design capacity */ | ||
79 | #define BQ27510_REG_CYCT 0x1E /* Cycle count total */ | ||
78 | 80 | ||
79 | /* bq27425 register addresses are same as bq27x00 addresses minus 4 */ | 81 | /* bq27425 register addresses are same as bq27x00 addresses minus 4 */ |
80 | #define BQ27425_REG_OFFSET 0x04 | 82 | #define BQ27425_REG_OFFSET 0x04 |
81 | #define BQ27425_REG_SOC (0x1C + BQ27425_REG_OFFSET) | 83 | #define BQ27425_REG_SOC (0x1C + BQ27425_REG_OFFSET) |
82 | #define BQ27425_REG_DCAP (0x3C + BQ27425_REG_OFFSET) | 84 | #define BQ27425_REG_DCAP (0x3C + BQ27425_REG_OFFSET) |
83 | 85 | ||
84 | #define BQ27000_RS 20 /* Resistor sense */ | 86 | #define BQ27000_RS 20 /* Resistor sense */ |
85 | #define BQ27x00_POWER_CONSTANT (256 * 29200 / 1000) | 87 | #define BQ27x00_POWER_CONSTANT (256 * 29200 / 1000) |
@@ -106,7 +108,7 @@ struct bq27x00_reg_cache { | |||
106 | }; | 108 | }; |
107 | 109 | ||
108 | struct bq27x00_device_info { | 110 | struct bq27x00_device_info { |
109 | struct device *dev; | 111 | struct device *dev; |
110 | int id; | 112 | int id; |
111 | enum bq27x00_chip chip; | 113 | enum bq27x00_chip chip; |
112 | 114 | ||
@@ -142,6 +144,7 @@ static enum power_supply_property bq27x00_battery_props[] = { | |||
142 | POWER_SUPPLY_PROP_ENERGY_NOW, | 144 | POWER_SUPPLY_PROP_ENERGY_NOW, |
143 | POWER_SUPPLY_PROP_POWER_AVG, | 145 | POWER_SUPPLY_PROP_POWER_AVG, |
144 | POWER_SUPPLY_PROP_HEALTH, | 146 | POWER_SUPPLY_PROP_HEALTH, |
147 | POWER_SUPPLY_PROP_MANUFACTURER, | ||
145 | }; | 148 | }; |
146 | 149 | ||
147 | static enum power_supply_property bq27425_battery_props[] = { | 150 | static enum power_supply_property bq27425_battery_props[] = { |
@@ -156,6 +159,7 @@ static enum power_supply_property bq27425_battery_props[] = { | |||
156 | POWER_SUPPLY_PROP_CHARGE_FULL, | 159 | POWER_SUPPLY_PROP_CHARGE_FULL, |
157 | POWER_SUPPLY_PROP_CHARGE_NOW, | 160 | POWER_SUPPLY_PROP_CHARGE_NOW, |
158 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | 161 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, |
162 | POWER_SUPPLY_PROP_MANUFACTURER, | ||
159 | }; | 163 | }; |
160 | 164 | ||
161 | static enum power_supply_property bq27742_battery_props[] = { | 165 | static enum power_supply_property bq27742_battery_props[] = { |
@@ -174,6 +178,7 @@ static enum power_supply_property bq27742_battery_props[] = { | |||
174 | POWER_SUPPLY_PROP_CYCLE_COUNT, | 178 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
175 | POWER_SUPPLY_PROP_POWER_AVG, | 179 | POWER_SUPPLY_PROP_POWER_AVG, |
176 | POWER_SUPPLY_PROP_HEALTH, | 180 | POWER_SUPPLY_PROP_HEALTH, |
181 | POWER_SUPPLY_PROP_MANUFACTURER, | ||
177 | }; | 182 | }; |
178 | 183 | ||
179 | static enum power_supply_property bq27510_battery_props[] = { | 184 | static enum power_supply_property bq27510_battery_props[] = { |
@@ -192,19 +197,20 @@ static enum power_supply_property bq27510_battery_props[] = { | |||
192 | POWER_SUPPLY_PROP_CYCLE_COUNT, | 197 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
193 | POWER_SUPPLY_PROP_POWER_AVG, | 198 | POWER_SUPPLY_PROP_POWER_AVG, |
194 | POWER_SUPPLY_PROP_HEALTH, | 199 | POWER_SUPPLY_PROP_HEALTH, |
200 | POWER_SUPPLY_PROP_MANUFACTURER, | ||
195 | }; | 201 | }; |
196 | 202 | ||
197 | static unsigned int poll_interval = 360; | 203 | static unsigned int poll_interval = 360; |
198 | module_param(poll_interval, uint, 0644); | 204 | module_param(poll_interval, uint, 0644); |
199 | MODULE_PARM_DESC(poll_interval, "battery poll interval in seconds - " \ | 205 | MODULE_PARM_DESC(poll_interval, |
200 | "0 disables polling"); | 206 | "battery poll interval in seconds - 0 disables polling"); |
201 | 207 | ||
202 | /* | 208 | /* |
203 | * Common code for BQ27x00 devices | 209 | * Common code for BQ27x00 devices |
204 | */ | 210 | */ |
205 | 211 | ||
206 | static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg, | 212 | static inline int bq27x00_read(struct bq27x00_device_info *di, u8 reg, |
207 | bool single) | 213 | bool single) |
208 | { | 214 | { |
209 | if (di->chip == BQ27425) | 215 | if (di->chip == BQ27425) |
210 | return di->bus.read(di, reg - BQ27425_REG_OFFSET, single); | 216 | return di->bus.read(di, reg - BQ27425_REG_OFFSET, single); |
@@ -313,8 +319,9 @@ static int bq27x00_battery_read_ilmd(struct bq27x00_device_info *di) | |||
313 | ilmd = bq27x00_read(di, BQ27510_REG_DCAP, false); | 319 | ilmd = bq27x00_read(di, BQ27510_REG_DCAP, false); |
314 | else | 320 | else |
315 | ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false); | 321 | ilmd = bq27x00_read(di, BQ27500_REG_DCAP, false); |
316 | } else | 322 | } else { |
317 | ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true); | 323 | ilmd = bq27x00_read(di, BQ27000_REG_ILMD, true); |
324 | } | ||
318 | 325 | ||
319 | if (ilmd < 0) { | 326 | if (ilmd < 0) { |
320 | dev_dbg(di->dev, "error reading initial last measured discharge\n"); | 327 | dev_dbg(di->dev, "error reading initial last measured discharge\n"); |
@@ -445,7 +452,7 @@ static int bq27x00_battery_read_health(struct bq27x00_device_info *di) | |||
445 | return tval; | 452 | return tval; |
446 | } | 453 | } |
447 | 454 | ||
448 | if ((di->chip == BQ27500)) { | 455 | if (di->chip == BQ27500) { |
449 | if (tval & BQ27500_FLAG_SOCF) | 456 | if (tval & BQ27500_FLAG_SOCF) |
450 | tval = POWER_SUPPLY_HEALTH_DEAD; | 457 | tval = POWER_SUPPLY_HEALTH_DEAD; |
451 | else if (tval & BQ27500_FLAG_OTC) | 458 | else if (tval & BQ27500_FLAG_OTC) |
@@ -559,7 +566,7 @@ static void bq27x00_battery_poll(struct work_struct *work) | |||
559 | * Or 0 if something fails. | 566 | * Or 0 if something fails. |
560 | */ | 567 | */ |
561 | static int bq27x00_battery_current(struct bq27x00_device_info *di, | 568 | static int bq27x00_battery_current(struct bq27x00_device_info *di, |
562 | union power_supply_propval *val) | 569 | union power_supply_propval *val) |
563 | { | 570 | { |
564 | int curr; | 571 | int curr; |
565 | int flags; | 572 | int flags; |
@@ -587,7 +594,7 @@ static int bq27x00_battery_current(struct bq27x00_device_info *di, | |||
587 | } | 594 | } |
588 | 595 | ||
589 | static int bq27x00_battery_status(struct bq27x00_device_info *di, | 596 | static int bq27x00_battery_status(struct bq27x00_device_info *di, |
590 | union power_supply_propval *val) | 597 | union power_supply_propval *val) |
591 | { | 598 | { |
592 | int status; | 599 | int status; |
593 | 600 | ||
@@ -615,7 +622,7 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di, | |||
615 | } | 622 | } |
616 | 623 | ||
617 | static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di, | 624 | static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di, |
618 | union power_supply_propval *val) | 625 | union power_supply_propval *val) |
619 | { | 626 | { |
620 | int level; | 627 | int level; |
621 | 628 | ||
@@ -649,7 +656,7 @@ static int bq27x00_battery_capacity_level(struct bq27x00_device_info *di, | |||
649 | * Or < 0 if something fails. | 656 | * Or < 0 if something fails. |
650 | */ | 657 | */ |
651 | static int bq27x00_battery_voltage(struct bq27x00_device_info *di, | 658 | static int bq27x00_battery_voltage(struct bq27x00_device_info *di, |
652 | union power_supply_propval *val) | 659 | union power_supply_propval *val) |
653 | { | 660 | { |
654 | int volt; | 661 | int volt; |
655 | 662 | ||
@@ -665,7 +672,7 @@ static int bq27x00_battery_voltage(struct bq27x00_device_info *di, | |||
665 | } | 672 | } |
666 | 673 | ||
667 | static int bq27x00_simple_value(int value, | 674 | static int bq27x00_simple_value(int value, |
668 | union power_supply_propval *val) | 675 | union power_supply_propval *val) |
669 | { | 676 | { |
670 | if (value < 0) | 677 | if (value < 0) |
671 | return value; | 678 | return value; |
@@ -749,6 +756,9 @@ static int bq27x00_battery_get_property(struct power_supply *psy, | |||
749 | case POWER_SUPPLY_PROP_HEALTH: | 756 | case POWER_SUPPLY_PROP_HEALTH: |
750 | ret = bq27x00_simple_value(di->cache.health, val); | 757 | ret = bq27x00_simple_value(di->cache.health, val); |
751 | break; | 758 | break; |
759 | case POWER_SUPPLY_PROP_MANUFACTURER: | ||
760 | val->strval = BQ27XXX_MANUFACTURER; | ||
761 | break; | ||
752 | default: | 762 | default: |
753 | return -EINVAL; | 763 | return -EINVAL; |
754 | } | 764 | } |
@@ -827,7 +837,6 @@ static void bq27x00_powersupply_unregister(struct bq27x00_device_info *di) | |||
827 | mutex_destroy(&di->lock); | 837 | mutex_destroy(&di->lock); |
828 | } | 838 | } |
829 | 839 | ||
830 | |||
831 | /* i2c specific code */ | 840 | /* i2c specific code */ |
832 | #ifdef CONFIG_BATTERY_BQ27X00_I2C | 841 | #ifdef CONFIG_BATTERY_BQ27X00_I2C |
833 | 842 | ||
@@ -888,14 +897,12 @@ static int bq27x00_battery_probe(struct i2c_client *client, | |||
888 | 897 | ||
889 | name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num); | 898 | name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s-%d", id->name, num); |
890 | if (!name) { | 899 | if (!name) { |
891 | dev_err(&client->dev, "failed to allocate device name\n"); | ||
892 | retval = -ENOMEM; | 900 | retval = -ENOMEM; |
893 | goto batt_failed; | 901 | goto batt_failed; |
894 | } | 902 | } |
895 | 903 | ||
896 | di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); | 904 | di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL); |
897 | if (!di) { | 905 | if (!di) { |
898 | dev_err(&client->dev, "failed to allocate device info data\n"); | ||
899 | retval = -ENOMEM; | 906 | retval = -ENOMEM; |
900 | goto batt_failed; | 907 | goto batt_failed; |
901 | } | 908 | } |
@@ -956,8 +963,9 @@ static struct i2c_driver bq27x00_battery_driver = { | |||
956 | static inline int bq27x00_battery_i2c_init(void) | 963 | static inline int bq27x00_battery_i2c_init(void) |
957 | { | 964 | { |
958 | int ret = i2c_add_driver(&bq27x00_battery_driver); | 965 | int ret = i2c_add_driver(&bq27x00_battery_driver); |
966 | |||
959 | if (ret) | 967 | if (ret) |
960 | printk(KERN_ERR "Unable to register BQ27x00 i2c driver\n"); | 968 | pr_err("Unable to register BQ27x00 i2c driver\n"); |
961 | 969 | ||
962 | return ret; | 970 | return ret; |
963 | } | 971 | } |
@@ -978,7 +986,7 @@ static inline void bq27x00_battery_i2c_exit(void) {}; | |||
978 | #ifdef CONFIG_BATTERY_BQ27X00_PLATFORM | 986 | #ifdef CONFIG_BATTERY_BQ27X00_PLATFORM |
979 | 987 | ||
980 | static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg, | 988 | static int bq27000_read_platform(struct bq27x00_device_info *di, u8 reg, |
981 | bool single) | 989 | bool single) |
982 | { | 990 | { |
983 | struct device *dev = di->dev; | 991 | struct device *dev = di->dev; |
984 | struct bq27000_platform_data *pdata = dev->platform_data; | 992 | struct bq27000_platform_data *pdata = dev->platform_data; |
@@ -1028,10 +1036,8 @@ static int bq27000_battery_probe(struct platform_device *pdev) | |||
1028 | } | 1036 | } |
1029 | 1037 | ||
1030 | di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); | 1038 | di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); |
1031 | if (!di) { | 1039 | if (!di) |
1032 | dev_err(&pdev->dev, "failed to allocate device info data\n"); | ||
1033 | return -ENOMEM; | 1040 | return -ENOMEM; |
1034 | } | ||
1035 | 1041 | ||
1036 | platform_set_drvdata(pdev, di); | 1042 | platform_set_drvdata(pdev, di); |
1037 | 1043 | ||
@@ -1064,8 +1070,9 @@ static struct platform_driver bq27000_battery_driver = { | |||
1064 | static inline int bq27x00_battery_platform_init(void) | 1070 | static inline int bq27x00_battery_platform_init(void) |
1065 | { | 1071 | { |
1066 | int ret = platform_driver_register(&bq27000_battery_driver); | 1072 | int ret = platform_driver_register(&bq27000_battery_driver); |
1073 | |||
1067 | if (ret) | 1074 | if (ret) |
1068 | printk(KERN_ERR "Unable to register BQ27000 platform driver\n"); | 1075 | pr_err("Unable to register BQ27000 platform driver\n"); |
1069 | 1076 | ||
1070 | return ret; | 1077 | return ret; |
1071 | } | 1078 | } |
diff --git a/drivers/power/ds2780_battery.c b/drivers/power/ds2780_battery.c index a7a0427343f3..d3743d0ad55b 100644 --- a/drivers/power/ds2780_battery.c +++ b/drivers/power/ds2780_battery.c | |||
@@ -637,10 +637,6 @@ static ssize_t ds2780_read_param_eeprom_bin(struct file *filp, | |||
637 | struct power_supply *psy = to_power_supply(dev); | 637 | struct power_supply *psy = to_power_supply(dev); |
638 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); | 638 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); |
639 | 639 | ||
640 | count = min_t(loff_t, count, | ||
641 | DS2780_EEPROM_BLOCK1_END - | ||
642 | DS2780_EEPROM_BLOCK1_START + 1 - off); | ||
643 | |||
644 | return ds2780_read_block(dev_info, buf, | 640 | return ds2780_read_block(dev_info, buf, |
645 | DS2780_EEPROM_BLOCK1_START + off, count); | 641 | DS2780_EEPROM_BLOCK1_START + off, count); |
646 | } | 642 | } |
@@ -655,10 +651,6 @@ static ssize_t ds2780_write_param_eeprom_bin(struct file *filp, | |||
655 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); | 651 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); |
656 | int ret; | 652 | int ret; |
657 | 653 | ||
658 | count = min_t(loff_t, count, | ||
659 | DS2780_EEPROM_BLOCK1_END - | ||
660 | DS2780_EEPROM_BLOCK1_START + 1 - off); | ||
661 | |||
662 | ret = ds2780_write(dev_info, buf, | 654 | ret = ds2780_write(dev_info, buf, |
663 | DS2780_EEPROM_BLOCK1_START + off, count); | 655 | DS2780_EEPROM_BLOCK1_START + off, count); |
664 | if (ret < 0) | 656 | if (ret < 0) |
@@ -676,7 +668,7 @@ static struct bin_attribute ds2780_param_eeprom_bin_attr = { | |||
676 | .name = "param_eeprom", | 668 | .name = "param_eeprom", |
677 | .mode = S_IRUGO | S_IWUSR, | 669 | .mode = S_IRUGO | S_IWUSR, |
678 | }, | 670 | }, |
679 | .size = DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_START + 1, | 671 | .size = DS2780_PARAM_EEPROM_SIZE, |
680 | .read = ds2780_read_param_eeprom_bin, | 672 | .read = ds2780_read_param_eeprom_bin, |
681 | .write = ds2780_write_param_eeprom_bin, | 673 | .write = ds2780_write_param_eeprom_bin, |
682 | }; | 674 | }; |
@@ -690,10 +682,6 @@ static ssize_t ds2780_read_user_eeprom_bin(struct file *filp, | |||
690 | struct power_supply *psy = to_power_supply(dev); | 682 | struct power_supply *psy = to_power_supply(dev); |
691 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); | 683 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); |
692 | 684 | ||
693 | count = min_t(loff_t, count, | ||
694 | DS2780_EEPROM_BLOCK0_END - | ||
695 | DS2780_EEPROM_BLOCK0_START + 1 - off); | ||
696 | |||
697 | return ds2780_read_block(dev_info, buf, | 685 | return ds2780_read_block(dev_info, buf, |
698 | DS2780_EEPROM_BLOCK0_START + off, count); | 686 | DS2780_EEPROM_BLOCK0_START + off, count); |
699 | } | 687 | } |
@@ -708,10 +696,6 @@ static ssize_t ds2780_write_user_eeprom_bin(struct file *filp, | |||
708 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); | 696 | struct ds2780_device_info *dev_info = to_ds2780_device_info(psy); |
709 | int ret; | 697 | int ret; |
710 | 698 | ||
711 | count = min_t(loff_t, count, | ||
712 | DS2780_EEPROM_BLOCK0_END - | ||
713 | DS2780_EEPROM_BLOCK0_START + 1 - off); | ||
714 | |||
715 | ret = ds2780_write(dev_info, buf, | 699 | ret = ds2780_write(dev_info, buf, |
716 | DS2780_EEPROM_BLOCK0_START + off, count); | 700 | DS2780_EEPROM_BLOCK0_START + off, count); |
717 | if (ret < 0) | 701 | if (ret < 0) |
@@ -729,7 +713,7 @@ static struct bin_attribute ds2780_user_eeprom_bin_attr = { | |||
729 | .name = "user_eeprom", | 713 | .name = "user_eeprom", |
730 | .mode = S_IRUGO | S_IWUSR, | 714 | .mode = S_IRUGO | S_IWUSR, |
731 | }, | 715 | }, |
732 | .size = DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_START + 1, | 716 | .size = DS2780_USER_EEPROM_SIZE, |
733 | .read = ds2780_read_user_eeprom_bin, | 717 | .read = ds2780_read_user_eeprom_bin, |
734 | .write = ds2780_write_user_eeprom_bin, | 718 | .write = ds2780_write_user_eeprom_bin, |
735 | }; | 719 | }; |
diff --git a/drivers/power/ds2781_battery.c b/drivers/power/ds2781_battery.c index 56d583dae908..c3680024f399 100644 --- a/drivers/power/ds2781_battery.c +++ b/drivers/power/ds2781_battery.c | |||
@@ -639,8 +639,6 @@ static ssize_t ds2781_read_param_eeprom_bin(struct file *filp, | |||
639 | struct power_supply *psy = to_power_supply(dev); | 639 | struct power_supply *psy = to_power_supply(dev); |
640 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); | 640 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); |
641 | 641 | ||
642 | count = min_t(loff_t, count, DS2781_PARAM_EEPROM_SIZE - off); | ||
643 | |||
644 | return ds2781_read_block(dev_info, buf, | 642 | return ds2781_read_block(dev_info, buf, |
645 | DS2781_EEPROM_BLOCK1_START + off, count); | 643 | DS2781_EEPROM_BLOCK1_START + off, count); |
646 | } | 644 | } |
@@ -655,8 +653,6 @@ static ssize_t ds2781_write_param_eeprom_bin(struct file *filp, | |||
655 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); | 653 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); |
656 | int ret; | 654 | int ret; |
657 | 655 | ||
658 | count = min_t(loff_t, count, DS2781_PARAM_EEPROM_SIZE - off); | ||
659 | |||
660 | ret = ds2781_write(dev_info, buf, | 656 | ret = ds2781_write(dev_info, buf, |
661 | DS2781_EEPROM_BLOCK1_START + off, count); | 657 | DS2781_EEPROM_BLOCK1_START + off, count); |
662 | if (ret < 0) | 658 | if (ret < 0) |
@@ -688,8 +684,6 @@ static ssize_t ds2781_read_user_eeprom_bin(struct file *filp, | |||
688 | struct power_supply *psy = to_power_supply(dev); | 684 | struct power_supply *psy = to_power_supply(dev); |
689 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); | 685 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); |
690 | 686 | ||
691 | count = min_t(loff_t, count, DS2781_USER_EEPROM_SIZE - off); | ||
692 | |||
693 | return ds2781_read_block(dev_info, buf, | 687 | return ds2781_read_block(dev_info, buf, |
694 | DS2781_EEPROM_BLOCK0_START + off, count); | 688 | DS2781_EEPROM_BLOCK0_START + off, count); |
695 | 689 | ||
@@ -705,8 +699,6 @@ static ssize_t ds2781_write_user_eeprom_bin(struct file *filp, | |||
705 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); | 699 | struct ds2781_device_info *dev_info = to_ds2781_device_info(psy); |
706 | int ret; | 700 | int ret; |
707 | 701 | ||
708 | count = min_t(loff_t, count, DS2781_USER_EEPROM_SIZE - off); | ||
709 | |||
710 | ret = ds2781_write(dev_info, buf, | 702 | ret = ds2781_write(dev_info, buf, |
711 | DS2781_EEPROM_BLOCK0_START + off, count); | 703 | DS2781_EEPROM_BLOCK0_START + off, count); |
712 | if (ret < 0) | 704 | if (ret < 0) |
diff --git a/drivers/power/ltc2941-battery-gauge.c b/drivers/power/ltc2941-battery-gauge.c index daeb0860736c..4adf2ba021ce 100644 --- a/drivers/power/ltc2941-battery-gauge.c +++ b/drivers/power/ltc2941-battery-gauge.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/swab.h> | 14 | #include <linux/swab.h> |
15 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/idr.h> | ||
18 | #include <linux/power_supply.h> | 17 | #include <linux/power_supply.h> |
19 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
20 | 19 | ||
@@ -63,15 +62,11 @@ struct ltc294x_info { | |||
63 | struct power_supply_desc supply_desc; /* Supply description */ | 62 | struct power_supply_desc supply_desc; /* Supply description */ |
64 | struct delayed_work work; /* Work scheduler */ | 63 | struct delayed_work work; /* Work scheduler */ |
65 | int num_regs; /* Number of registers (chip type) */ | 64 | int num_regs; /* Number of registers (chip type) */ |
66 | int id; /* Identifier of ltc294x chip */ | ||
67 | int charge; /* Last charge register content */ | 65 | int charge; /* Last charge register content */ |
68 | int r_sense; /* mOhm */ | 66 | int r_sense; /* mOhm */ |
69 | int Qlsb; /* nAh */ | 67 | int Qlsb; /* nAh */ |
70 | }; | 68 | }; |
71 | 69 | ||
72 | static DEFINE_IDR(ltc294x_id); | ||
73 | static DEFINE_MUTEX(ltc294x_lock); | ||
74 | |||
75 | static inline int convert_bin_to_uAh( | 70 | static inline int convert_bin_to_uAh( |
76 | const struct ltc294x_info *info, int Q) | 71 | const struct ltc294x_info *info, int Q) |
77 | { | 72 | { |
@@ -371,10 +366,6 @@ static int ltc294x_i2c_remove(struct i2c_client *client) | |||
371 | 366 | ||
372 | cancel_delayed_work(&info->work); | 367 | cancel_delayed_work(&info->work); |
373 | power_supply_unregister(info->supply); | 368 | power_supply_unregister(info->supply); |
374 | kfree(info->supply_desc.name); | ||
375 | mutex_lock(<c294x_lock); | ||
376 | idr_remove(<c294x_id, info->id); | ||
377 | mutex_unlock(<c294x_lock); | ||
378 | return 0; | 369 | return 0; |
379 | } | 370 | } |
380 | 371 | ||
@@ -384,44 +375,28 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
384 | struct power_supply_config psy_cfg = {}; | 375 | struct power_supply_config psy_cfg = {}; |
385 | struct ltc294x_info *info; | 376 | struct ltc294x_info *info; |
386 | int ret; | 377 | int ret; |
387 | int num; | ||
388 | u32 prescaler_exp; | 378 | u32 prescaler_exp; |
389 | s32 r_sense; | 379 | s32 r_sense; |
390 | struct device_node *np; | 380 | struct device_node *np; |
391 | 381 | ||
392 | mutex_lock(<c294x_lock); | ||
393 | ret = idr_alloc(<c294x_id, client, 0, 0, GFP_KERNEL); | ||
394 | mutex_unlock(<c294x_lock); | ||
395 | if (ret < 0) | ||
396 | goto fail_id; | ||
397 | |||
398 | num = ret; | ||
399 | |||
400 | info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); | 382 | info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); |
401 | if (info == NULL) { | 383 | if (info == NULL) |
402 | ret = -ENOMEM; | 384 | return -ENOMEM; |
403 | goto fail_info; | ||
404 | } | ||
405 | 385 | ||
406 | i2c_set_clientdata(client, info); | 386 | i2c_set_clientdata(client, info); |
407 | 387 | ||
408 | info->num_regs = id->driver_data; | ||
409 | info->supply_desc.name = kasprintf(GFP_KERNEL, "%s-%d", client->name, | ||
410 | num); | ||
411 | if (!info->supply_desc.name) { | ||
412 | ret = -ENOMEM; | ||
413 | goto fail_name; | ||
414 | } | ||
415 | |||
416 | np = of_node_get(client->dev.of_node); | 388 | np = of_node_get(client->dev.of_node); |
417 | 389 | ||
390 | info->num_regs = id->driver_data; | ||
391 | info->supply_desc.name = np->name; | ||
392 | |||
418 | /* r_sense can be negative, when sense+ is connected to the battery | 393 | /* r_sense can be negative, when sense+ is connected to the battery |
419 | * instead of the sense-. This results in reversed measurements. */ | 394 | * instead of the sense-. This results in reversed measurements. */ |
420 | ret = of_property_read_u32(np, "lltc,resistor-sense", &r_sense); | 395 | ret = of_property_read_u32(np, "lltc,resistor-sense", &r_sense); |
421 | if (ret < 0) { | 396 | if (ret < 0) { |
422 | dev_err(&client->dev, | 397 | dev_err(&client->dev, |
423 | "Could not find lltc,resistor-sense in devicetree\n"); | 398 | "Could not find lltc,resistor-sense in devicetree\n"); |
424 | goto fail_name; | 399 | return ret; |
425 | } | 400 | } |
426 | info->r_sense = r_sense; | 401 | info->r_sense = r_sense; |
427 | 402 | ||
@@ -446,7 +421,6 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
446 | } | 421 | } |
447 | 422 | ||
448 | info->client = client; | 423 | info->client = client; |
449 | info->id = num; | ||
450 | info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; | 424 | info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
451 | info->supply_desc.properties = ltc294x_properties; | 425 | info->supply_desc.properties = ltc294x_properties; |
452 | if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB) | 426 | if (info->num_regs >= LTC294X_REG_TEMPERATURE_LSB) |
@@ -473,31 +447,19 @@ static int ltc294x_i2c_probe(struct i2c_client *client, | |||
473 | ret = ltc294x_reset(info, prescaler_exp); | 447 | ret = ltc294x_reset(info, prescaler_exp); |
474 | if (ret < 0) { | 448 | if (ret < 0) { |
475 | dev_err(&client->dev, "Communication with chip failed\n"); | 449 | dev_err(&client->dev, "Communication with chip failed\n"); |
476 | goto fail_comm; | 450 | return ret; |
477 | } | 451 | } |
478 | 452 | ||
479 | info->supply = power_supply_register(&client->dev, &info->supply_desc, | 453 | info->supply = power_supply_register(&client->dev, &info->supply_desc, |
480 | &psy_cfg); | 454 | &psy_cfg); |
481 | if (IS_ERR(info->supply)) { | 455 | if (IS_ERR(info->supply)) { |
482 | dev_err(&client->dev, "failed to register ltc2941\n"); | 456 | dev_err(&client->dev, "failed to register ltc2941\n"); |
483 | ret = PTR_ERR(info->supply); | 457 | return PTR_ERR(info->supply); |
484 | goto fail_register; | ||
485 | } else { | 458 | } else { |
486 | schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ); | 459 | schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ); |
487 | } | 460 | } |
488 | 461 | ||
489 | return 0; | 462 | return 0; |
490 | |||
491 | fail_register: | ||
492 | kfree(info->supply_desc.name); | ||
493 | fail_comm: | ||
494 | fail_name: | ||
495 | fail_info: | ||
496 | mutex_lock(<c294x_lock); | ||
497 | idr_remove(<c294x_id, num); | ||
498 | mutex_unlock(<c294x_lock); | ||
499 | fail_id: | ||
500 | return ret; | ||
501 | } | 463 | } |
502 | 464 | ||
503 | #ifdef CONFIG_PM_SLEEP | 465 | #ifdef CONFIG_PM_SLEEP |
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index a944338a39de..9e29b1321648 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c | |||
@@ -521,11 +521,6 @@ static ssize_t olpc_bat_eeprom_read(struct file *filp, struct kobject *kobj, | |||
521 | int ret; | 521 | int ret; |
522 | int i; | 522 | int i; |
523 | 523 | ||
524 | if (off >= EEPROM_SIZE) | ||
525 | return 0; | ||
526 | if (off + count > EEPROM_SIZE) | ||
527 | count = EEPROM_SIZE - off; | ||
528 | |||
529 | for (i = 0; i < count; i++) { | 524 | for (i = 0; i < count; i++) { |
530 | ec_byte = EEPROM_START + off + i; | 525 | ec_byte = EEPROM_START + off + i; |
531 | ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &buf[i], 1); | 526 | ret = olpc_ec_cmd(EC_BAT_EEPROM, &ec_byte, 1, &buf[i], 1); |
@@ -545,7 +540,7 @@ static struct bin_attribute olpc_bat_eeprom = { | |||
545 | .name = "eeprom", | 540 | .name = "eeprom", |
546 | .mode = S_IRUGO, | 541 | .mode = S_IRUGO, |
547 | }, | 542 | }, |
548 | .size = 0, | 543 | .size = EEPROM_SIZE, |
549 | .read = olpc_bat_eeprom_read, | 544 | .read = olpc_bat_eeprom_read, |
550 | }; | 545 | }; |
551 | 546 | ||
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index cc0893ffbf7e..3a45cc0c4dce 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c | |||
@@ -1244,7 +1244,6 @@ static struct i2c_driver pm2xxx_charger_driver = { | |||
1244 | .remove = pm2xxx_wall_charger_remove, | 1244 | .remove = pm2xxx_wall_charger_remove, |
1245 | .driver = { | 1245 | .driver = { |
1246 | .name = "pm2xxx-wall_charger", | 1246 | .name = "pm2xxx-wall_charger", |
1247 | .owner = THIS_MODULE, | ||
1248 | .pm = PM2XXX_PM_OPS, | 1247 | .pm = PM2XXX_PM_OPS, |
1249 | }, | 1248 | }, |
1250 | .id_table = pm2xxx_id, | 1249 | .id_table = pm2xxx_id, |
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 17d93a73c513..5a0189bf19bb 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig | |||
@@ -166,5 +166,12 @@ config POWER_RESET_RMOBILE | |||
166 | help | 166 | help |
167 | Reboot support for Renesas R-Mobile and SH-Mobile SoCs. | 167 | Reboot support for Renesas R-Mobile and SH-Mobile SoCs. |
168 | 168 | ||
169 | config POWER_RESET_ZX | ||
170 | tristate "ZTE SoCs reset driver" | ||
171 | depends on ARCH_ZX || COMPILE_TEST | ||
172 | depends on HAS_IOMEM | ||
173 | help | ||
174 | Reboot support for ZTE SoCs. | ||
175 | |||
169 | endif | 176 | endif |
170 | 177 | ||
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index dbe06c368743..096fa67047f6 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile | |||
@@ -19,3 +19,4 @@ obj-$(CONFIG_POWER_RESET_KEYSTONE) += keystone-reset.o | |||
19 | obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o | 19 | obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o |
20 | obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o | 20 | obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o |
21 | obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o | 21 | obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o |
22 | obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o | ||
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 36dc52fb2ec8..c378d4ec826f 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c | |||
@@ -123,6 +123,15 @@ static int at91sam9g45_restart(struct notifier_block *this, unsigned long mode, | |||
123 | return NOTIFY_DONE; | 123 | return NOTIFY_DONE; |
124 | } | 124 | } |
125 | 125 | ||
126 | static int sama5d3_restart(struct notifier_block *this, unsigned long mode, | ||
127 | void *cmd) | ||
128 | { | ||
129 | writel(cpu_to_le32(AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST), | ||
130 | at91_rstc_base); | ||
131 | |||
132 | return NOTIFY_DONE; | ||
133 | } | ||
134 | |||
126 | static void __init at91_reset_status(struct platform_device *pdev) | 135 | static void __init at91_reset_status(struct platform_device *pdev) |
127 | { | 136 | { |
128 | u32 reg = readl(at91_rstc_base + AT91_RSTC_SR); | 137 | u32 reg = readl(at91_rstc_base + AT91_RSTC_SR); |
@@ -155,13 +164,13 @@ static void __init at91_reset_status(struct platform_device *pdev) | |||
155 | static const struct of_device_id at91_ramc_of_match[] = { | 164 | static const struct of_device_id at91_ramc_of_match[] = { |
156 | { .compatible = "atmel,at91sam9260-sdramc", }, | 165 | { .compatible = "atmel,at91sam9260-sdramc", }, |
157 | { .compatible = "atmel,at91sam9g45-ddramc", }, | 166 | { .compatible = "atmel,at91sam9g45-ddramc", }, |
158 | { .compatible = "atmel,sama5d3-ddramc", }, | ||
159 | { /* sentinel */ } | 167 | { /* sentinel */ } |
160 | }; | 168 | }; |
161 | 169 | ||
162 | static const struct of_device_id at91_reset_of_match[] = { | 170 | static const struct of_device_id at91_reset_of_match[] = { |
163 | { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart }, | 171 | { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart }, |
164 | { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, | 172 | { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, |
173 | { .compatible = "atmel,sama5d3-rstc", .data = sama5d3_restart }, | ||
165 | { /* sentinel */ } | 174 | { /* sentinel */ } |
166 | }; | 175 | }; |
167 | 176 | ||
@@ -181,13 +190,16 @@ static int at91_reset_of_probe(struct platform_device *pdev) | |||
181 | return -ENODEV; | 190 | return -ENODEV; |
182 | } | 191 | } |
183 | 192 | ||
184 | for_each_matching_node(np, at91_ramc_of_match) { | 193 | if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) { |
185 | at91_ramc_base[idx] = of_iomap(np, 0); | 194 | /* we need to shutdown the ddr controller, so get ramc base */ |
186 | if (!at91_ramc_base[idx]) { | 195 | for_each_matching_node(np, at91_ramc_of_match) { |
187 | dev_err(&pdev->dev, "Could not map ram controller address\n"); | 196 | at91_ramc_base[idx] = of_iomap(np, 0); |
188 | return -ENODEV; | 197 | if (!at91_ramc_base[idx]) { |
198 | dev_err(&pdev->dev, "Could not map ram controller address\n"); | ||
199 | return -ENODEV; | ||
200 | } | ||
201 | idx++; | ||
189 | } | 202 | } |
190 | idx++; | ||
191 | } | 203 | } |
192 | 204 | ||
193 | match = of_match_node(at91_reset_of_match, pdev->dev.of_node); | 205 | match = of_match_node(at91_reset_of_match, pdev->dev.of_node); |
diff --git a/drivers/power/reset/zx-reboot.c b/drivers/power/reset/zx-reboot.c new file mode 100644 index 000000000000..a5b009673d0e --- /dev/null +++ b/drivers/power/reset/zx-reboot.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * ZTE zx296702 SoC reset code | ||
3 | * | ||
4 | * Copyright (c) 2015 Linaro Ltd. | ||
5 | * | ||
6 | * Author: Jun Nie <jun.nie@linaro.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/delay.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/notifier.h> | ||
17 | #include <linux/of_address.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/reboot.h> | ||
20 | |||
21 | static void __iomem *base; | ||
22 | static void __iomem *pcu_base; | ||
23 | |||
24 | static int zx_restart_handler(struct notifier_block *this, | ||
25 | unsigned long mode, void *cmd) | ||
26 | { | ||
27 | writel_relaxed(1, base + 0xb0); | ||
28 | writel_relaxed(1, pcu_base + 0x34); | ||
29 | |||
30 | mdelay(50); | ||
31 | pr_emerg("Unable to restart system\n"); | ||
32 | |||
33 | return NOTIFY_DONE; | ||
34 | } | ||
35 | |||
36 | static struct notifier_block zx_restart_nb = { | ||
37 | .notifier_call = zx_restart_handler, | ||
38 | .priority = 128, | ||
39 | }; | ||
40 | |||
41 | static int zx_reboot_probe(struct platform_device *pdev) | ||
42 | { | ||
43 | struct device_node *np = pdev->dev.of_node; | ||
44 | int err; | ||
45 | |||
46 | base = of_iomap(np, 0); | ||
47 | if (!base) { | ||
48 | WARN(1, "failed to map base address"); | ||
49 | return -ENODEV; | ||
50 | } | ||
51 | |||
52 | np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu"); | ||
53 | pcu_base = of_iomap(np, 0); | ||
54 | if (!pcu_base) { | ||
55 | iounmap(base); | ||
56 | WARN(1, "failed to map pcu_base address"); | ||
57 | return -ENODEV; | ||
58 | } | ||
59 | |||
60 | err = register_restart_handler(&zx_restart_nb); | ||
61 | if (err) | ||
62 | dev_err(&pdev->dev, "Register restart handler failed(err=%d)\n", | ||
63 | err); | ||
64 | |||
65 | return err; | ||
66 | } | ||
67 | |||
68 | static const struct of_device_id zx_reboot_of_match[] = { | ||
69 | { .compatible = "zte,sysctrl" }, | ||
70 | {} | ||
71 | }; | ||
72 | |||
73 | static struct platform_driver zx_reboot_driver = { | ||
74 | .probe = zx_reboot_probe, | ||
75 | .driver = { | ||
76 | .name = "zx-reboot", | ||
77 | .of_match_table = zx_reboot_of_match, | ||
78 | }, | ||
79 | }; | ||
80 | module_platform_driver(zx_reboot_driver); | ||
diff --git a/drivers/power/rt5033_battery.c b/drivers/power/rt5033_battery.c index a7a6877b4e16..bcdd83048492 100644 --- a/drivers/power/rt5033_battery.c +++ b/drivers/power/rt5033_battery.c | |||
@@ -165,7 +165,7 @@ static const struct i2c_device_id rt5033_battery_id[] = { | |||
165 | { "rt5033-battery", }, | 165 | { "rt5033-battery", }, |
166 | { } | 166 | { } |
167 | }; | 167 | }; |
168 | MODULE_DEVICE_TABLE(platform, rt5033_battery_id); | 168 | MODULE_DEVICE_TABLE(i2c, rt5033_battery_id); |
169 | 169 | ||
170 | static struct i2c_driver rt5033_battery_driver = { | 170 | static struct i2c_driver rt5033_battery_driver = { |
171 | .driver = { | 171 | .driver = { |
diff --git a/drivers/power/rt9455_charger.c b/drivers/power/rt9455_charger.c index 08baac6e3ada..a49a9d44bdda 100644 --- a/drivers/power/rt9455_charger.c +++ b/drivers/power/rt9455_charger.c | |||
@@ -973,7 +973,6 @@ static int rt9455_irq_handler_check_irq2_register(struct rt9455_info *info, | |||
973 | 973 | ||
974 | if (irq2 & GET_MASK(F_CHRVPI)) { | 974 | if (irq2 & GET_MASK(F_CHRVPI)) { |
975 | dev_dbg(dev, "Charger fault occurred\n"); | 975 | dev_dbg(dev, "Charger fault occurred\n"); |
976 | alert_userspace = true; | ||
977 | /* | 976 | /* |
978 | * CHRVPI bit is set in 2 cases: | 977 | * CHRVPI bit is set in 2 cases: |
979 | * 1. when the power source is connected to the charger. | 978 | * 1. when the power source is connected to the charger. |
@@ -981,6 +980,9 @@ static int rt9455_irq_handler_check_irq2_register(struct rt9455_info *info, | |||
981 | * To identify the case, PWR_RDY bit is checked. Because | 980 | * To identify the case, PWR_RDY bit is checked. Because |
982 | * PWR_RDY bit is set / cleared after CHRVPI interrupt is | 981 | * PWR_RDY bit is set / cleared after CHRVPI interrupt is |
983 | * triggered, it is used delayed_work to later read PWR_RDY bit. | 982 | * triggered, it is used delayed_work to later read PWR_RDY bit. |
983 | * Also, do not set to true alert_userspace, because there is no | ||
984 | * need to notify userspace when CHRVPI interrupt has occurred. | ||
985 | * Userspace will be notified after PWR_RDY bit is read. | ||
984 | */ | 986 | */ |
985 | queue_delayed_work(system_power_efficient_wq, | 987 | queue_delayed_work(system_power_efficient_wq, |
986 | &info->pwr_rdy_work, | 988 | &info->pwr_rdy_work, |
@@ -1178,7 +1180,7 @@ static irqreturn_t rt9455_irq_handler_thread(int irq, void *data) | |||
1178 | /* | 1180 | /* |
1179 | * Sometimes, an interrupt occurs while rt9455_probe() function | 1181 | * Sometimes, an interrupt occurs while rt9455_probe() function |
1180 | * is executing and power_supply_register() is not yet called. | 1182 | * is executing and power_supply_register() is not yet called. |
1181 | * Do not call power_supply_charged() in this case. | 1183 | * Do not call power_supply_changed() in this case. |
1182 | */ | 1184 | */ |
1183 | if (info->charger) | 1185 | if (info->charger) |
1184 | power_supply_changed(info->charger); | 1186 | power_supply_changed(info->charger); |
@@ -1478,6 +1480,11 @@ static void rt9455_pwr_rdy_work_callback(struct work_struct *work) | |||
1478 | RT9455_MAX_CHARGING_TIME * HZ); | 1480 | RT9455_MAX_CHARGING_TIME * HZ); |
1479 | break; | 1481 | break; |
1480 | } | 1482 | } |
1483 | /* | ||
1484 | * Notify userspace that the charger has been either connected to or | ||
1485 | * disconnected from the power source. | ||
1486 | */ | ||
1487 | power_supply_changed(info->charger); | ||
1481 | } | 1488 | } |
1482 | 1489 | ||
1483 | static void rt9455_max_charging_time_work_callback(struct work_struct *work) | 1490 | static void rt9455_max_charging_time_work_callback(struct work_struct *work) |
@@ -1533,6 +1540,11 @@ static void rt9455_batt_presence_work_callback(struct work_struct *work) | |||
1533 | if (ret) | 1540 | if (ret) |
1534 | dev_err(dev, "Failed to unmask BATAB interrupt\n"); | 1541 | dev_err(dev, "Failed to unmask BATAB interrupt\n"); |
1535 | } | 1542 | } |
1543 | /* | ||
1544 | * Notify userspace that the battery is now connected to the | ||
1545 | * charger. | ||
1546 | */ | ||
1547 | power_supply_changed(info->charger); | ||
1536 | } | 1548 | } |
1537 | } | 1549 | } |
1538 | 1550 | ||
diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c index ac6206951d58..af9383d23d12 100644 --- a/drivers/power/rx51_battery.c +++ b/drivers/power/rx51_battery.c | |||
@@ -215,7 +215,7 @@ static int rx51_battery_probe(struct platform_device *pdev) | |||
215 | platform_set_drvdata(pdev, di); | 215 | platform_set_drvdata(pdev, di); |
216 | 216 | ||
217 | di->dev = &pdev->dev; | 217 | di->dev = &pdev->dev; |
218 | di->bat_desc.name = dev_name(&pdev->dev); | 218 | di->bat_desc.name = "rx51-battery"; |
219 | di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; | 219 | di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
220 | di->bat_desc.properties = rx51_battery_props; | 220 | di->bat_desc.properties = rx51_battery_props; |
221 | di->bat_desc.num_properties = ARRAY_SIZE(rx51_battery_props); | 221 | di->bat_desc.num_properties = ARRAY_SIZE(rx51_battery_props); |
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index 022b8910e443..f4f2c1f76c32 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c | |||
@@ -22,8 +22,10 @@ | |||
22 | #include <linux/power_supply.h> | 22 | #include <linux/power_supply.h> |
23 | #include <linux/notifier.h> | 23 | #include <linux/notifier.h> |
24 | #include <linux/usb/otg.h> | 24 | #include <linux/usb/otg.h> |
25 | #include <linux/regulator/machine.h> | 25 | #include <linux/i2c/twl4030-madc.h> |
26 | 26 | ||
27 | #define TWL4030_BCIMDEN 0x00 | ||
28 | #define TWL4030_BCIMDKEY 0x01 | ||
27 | #define TWL4030_BCIMSTATEC 0x02 | 29 | #define TWL4030_BCIMSTATEC 0x02 |
28 | #define TWL4030_BCIICHG 0x08 | 30 | #define TWL4030_BCIICHG 0x08 |
29 | #define TWL4030_BCIVAC 0x0a | 31 | #define TWL4030_BCIVAC 0x0a |
@@ -32,11 +34,19 @@ | |||
32 | #define TWL4030_BCIMFSTS4 0x10 | 34 | #define TWL4030_BCIMFSTS4 0x10 |
33 | #define TWL4030_BCICTL1 0x23 | 35 | #define TWL4030_BCICTL1 0x23 |
34 | #define TWL4030_BB_CFG 0x12 | 36 | #define TWL4030_BB_CFG 0x12 |
37 | #define TWL4030_BCIIREF1 0x27 | ||
38 | #define TWL4030_BCIIREF2 0x28 | ||
39 | #define TWL4030_BCIMFKEY 0x11 | ||
40 | #define TWL4030_BCIMFEN3 0x14 | ||
41 | #define TWL4030_BCIMFTH8 0x1d | ||
42 | #define TWL4030_BCIMFTH9 0x1e | ||
43 | #define TWL4030_BCIWDKEY 0x21 | ||
35 | 44 | ||
36 | #define TWL4030_BCIMFSTS1 0x01 | 45 | #define TWL4030_BCIMFSTS1 0x01 |
37 | 46 | ||
38 | #define TWL4030_BCIAUTOWEN BIT(5) | 47 | #define TWL4030_BCIAUTOWEN BIT(5) |
39 | #define TWL4030_CONFIG_DONE BIT(4) | 48 | #define TWL4030_CONFIG_DONE BIT(4) |
49 | #define TWL4030_CVENAC BIT(2) | ||
40 | #define TWL4030_BCIAUTOUSB BIT(1) | 50 | #define TWL4030_BCIAUTOUSB BIT(1) |
41 | #define TWL4030_BCIAUTOAC BIT(0) | 51 | #define TWL4030_BCIAUTOAC BIT(0) |
42 | #define TWL4030_CGAIN BIT(5) | 52 | #define TWL4030_CGAIN BIT(5) |
@@ -81,6 +91,21 @@ | |||
81 | #define TWL4030_MSTATEC_COMPLETE1 0x0b | 91 | #define TWL4030_MSTATEC_COMPLETE1 0x0b |
82 | #define TWL4030_MSTATEC_COMPLETE4 0x0e | 92 | #define TWL4030_MSTATEC_COMPLETE4 0x0e |
83 | 93 | ||
94 | #if IS_ENABLED(CONFIG_TWL4030_MADC) | ||
95 | /* | ||
96 | * If AC (Accessory Charger) voltage exceeds 4.5V (MADC 11) | ||
97 | * then AC is available. | ||
98 | */ | ||
99 | static inline int ac_available(void) | ||
100 | { | ||
101 | return twl4030_get_madc_conversion(11) > 4500; | ||
102 | } | ||
103 | #else | ||
104 | static inline int ac_available(void) | ||
105 | { | ||
106 | return 0; | ||
107 | } | ||
108 | #endif | ||
84 | static bool allow_usb; | 109 | static bool allow_usb; |
85 | module_param(allow_usb, bool, 0644); | 110 | module_param(allow_usb, bool, 0644); |
86 | MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current"); | 111 | MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current"); |
@@ -94,12 +119,39 @@ struct twl4030_bci { | |||
94 | struct work_struct work; | 119 | struct work_struct work; |
95 | int irq_chg; | 120 | int irq_chg; |
96 | int irq_bci; | 121 | int irq_bci; |
97 | struct regulator *usb_reg; | ||
98 | int usb_enabled; | 122 | int usb_enabled; |
99 | 123 | ||
124 | /* | ||
125 | * ichg_* and *_cur values in uA. If any are 'large', we set | ||
126 | * CGAIN to '1' which doubles the range for half the | ||
127 | * precision. | ||
128 | */ | ||
129 | unsigned int ichg_eoc, ichg_lo, ichg_hi; | ||
130 | unsigned int usb_cur, ac_cur; | ||
131 | bool ac_is_active; | ||
132 | int usb_mode, ac_mode; /* charging mode requested */ | ||
133 | #define CHARGE_OFF 0 | ||
134 | #define CHARGE_AUTO 1 | ||
135 | #define CHARGE_LINEAR 2 | ||
136 | |||
137 | /* When setting the USB current we slowly increase the | ||
138 | * requested current until target is reached or the voltage | ||
139 | * drops below 4.75V. In the latter case we step back one | ||
140 | * step. | ||
141 | */ | ||
142 | unsigned int usb_cur_target; | ||
143 | struct delayed_work current_worker; | ||
144 | #define USB_CUR_STEP 20000 /* 20mA at a time */ | ||
145 | #define USB_MIN_VOLT 4750000 /* 4.75V */ | ||
146 | #define USB_CUR_DELAY msecs_to_jiffies(100) | ||
147 | #define USB_MAX_CURRENT 1700000 /* TWL4030 caps at 1.7A */ | ||
148 | |||
100 | unsigned long event; | 149 | unsigned long event; |
101 | }; | 150 | }; |
102 | 151 | ||
152 | /* strings for 'usb_mode' values */ | ||
153 | static char *modes[] = { "off", "auto", "continuous" }; | ||
154 | |||
103 | /* | 155 | /* |
104 | * clear and set bits on an given register on a given module | 156 | * clear and set bits on an given register on a given module |
105 | */ | 157 | */ |
@@ -180,27 +232,233 @@ static int twl4030_is_battery_present(struct twl4030_bci *bci) | |||
180 | } | 232 | } |
181 | 233 | ||
182 | /* | 234 | /* |
183 | * Check if VBUS power is present | 235 | * TI provided formulas: |
236 | * CGAIN == 0: ICHG = (BCIICHG * 1.7) / (2^10 - 1) - 0.85 | ||
237 | * CGAIN == 1: ICHG = (BCIICHG * 3.4) / (2^10 - 1) - 1.7 | ||
238 | * Here we use integer approximation of: | ||
239 | * CGAIN == 0: val * 1.6618 - 0.85 * 1000 | ||
240 | * CGAIN == 1: (val * 1.6618 - 0.85 * 1000) * 2 | ||
241 | */ | ||
242 | /* | ||
243 | * convert twl register value for currents into uA | ||
244 | */ | ||
245 | static int regval2ua(int regval, bool cgain) | ||
246 | { | ||
247 | if (cgain) | ||
248 | return (regval * 16618 - 8500 * 1000) / 5; | ||
249 | else | ||
250 | return (regval * 16618 - 8500 * 1000) / 10; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * convert uA currents into twl register value | ||
184 | */ | 255 | */ |
185 | static int twl4030_bci_have_vbus(struct twl4030_bci *bci) | 256 | static int ua2regval(int ua, bool cgain) |
186 | { | 257 | { |
187 | int ret; | 258 | int ret; |
188 | u8 hwsts; | 259 | if (cgain) |
260 | ua /= 2; | ||
261 | ret = (ua * 10 + 8500 * 1000) / 16618; | ||
262 | /* rounding problems */ | ||
263 | if (ret < 512) | ||
264 | ret = 512; | ||
265 | return ret; | ||
266 | } | ||
189 | 267 | ||
190 | ret = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &hwsts, | 268 | static int twl4030_charger_update_current(struct twl4030_bci *bci) |
191 | TWL4030_PM_MASTER_STS_HW_CONDITIONS); | 269 | { |
192 | if (ret < 0) | 270 | int status; |
193 | return 0; | 271 | int cur; |
272 | unsigned reg, cur_reg; | ||
273 | u8 bcictl1, oldreg, fullreg; | ||
274 | bool cgain = false; | ||
275 | u8 boot_bci; | ||
194 | 276 | ||
195 | dev_dbg(bci->dev, "check_vbus: HW_CONDITIONS %02x\n", hwsts); | 277 | /* |
278 | * If AC (Accessory Charger) voltage exceeds 4.5V (MADC 11) | ||
279 | * and AC is enabled, set current for 'ac' | ||
280 | */ | ||
281 | if (ac_available()) { | ||
282 | cur = bci->ac_cur; | ||
283 | bci->ac_is_active = true; | ||
284 | } else { | ||
285 | cur = bci->usb_cur; | ||
286 | bci->ac_is_active = false; | ||
287 | if (cur > bci->usb_cur_target) { | ||
288 | cur = bci->usb_cur_target; | ||
289 | bci->usb_cur = cur; | ||
290 | } | ||
291 | if (cur < bci->usb_cur_target) | ||
292 | schedule_delayed_work(&bci->current_worker, USB_CUR_DELAY); | ||
293 | } | ||
294 | |||
295 | /* First, check thresholds and see if cgain is needed */ | ||
296 | if (bci->ichg_eoc >= 200000) | ||
297 | cgain = true; | ||
298 | if (bci->ichg_lo >= 400000) | ||
299 | cgain = true; | ||
300 | if (bci->ichg_hi >= 820000) | ||
301 | cgain = true; | ||
302 | if (cur > 852000) | ||
303 | cgain = true; | ||
304 | |||
305 | status = twl4030_bci_read(TWL4030_BCICTL1, &bcictl1); | ||
306 | if (status < 0) | ||
307 | return status; | ||
308 | if (twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &boot_bci, | ||
309 | TWL4030_PM_MASTER_BOOT_BCI) < 0) | ||
310 | boot_bci = 0; | ||
311 | boot_bci &= 7; | ||
312 | |||
313 | if ((!!cgain) != !!(bcictl1 & TWL4030_CGAIN)) | ||
314 | /* Need to turn for charging while we change the | ||
315 | * CGAIN bit. Leave it off while everything is | ||
316 | * updated. | ||
317 | */ | ||
318 | twl4030_clear_set_boot_bci(boot_bci, 0); | ||
319 | |||
320 | /* | ||
321 | * For ichg_eoc, the hardware only supports reg values matching | ||
322 | * 100XXXX000, and requires the XXXX be stored in the high nibble | ||
323 | * of TWL4030_BCIMFTH8. | ||
324 | */ | ||
325 | reg = ua2regval(bci->ichg_eoc, cgain); | ||
326 | if (reg > 0x278) | ||
327 | reg = 0x278; | ||
328 | if (reg < 0x200) | ||
329 | reg = 0x200; | ||
330 | reg = (reg >> 3) & 0xf; | ||
331 | fullreg = reg << 4; | ||
332 | |||
333 | /* | ||
334 | * For ichg_lo, reg value must match 10XXXX0000. | ||
335 | * XXXX is stored in low nibble of TWL4030_BCIMFTH8. | ||
336 | */ | ||
337 | reg = ua2regval(bci->ichg_lo, cgain); | ||
338 | if (reg > 0x2F0) | ||
339 | reg = 0x2F0; | ||
340 | if (reg < 0x200) | ||
341 | reg = 0x200; | ||
342 | reg = (reg >> 4) & 0xf; | ||
343 | fullreg |= reg; | ||
344 | |||
345 | /* ichg_eoc and ichg_lo live in same register */ | ||
346 | status = twl4030_bci_read(TWL4030_BCIMFTH8, &oldreg); | ||
347 | if (status < 0) | ||
348 | return status; | ||
349 | if (oldreg != fullreg) { | ||
350 | status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xF4, | ||
351 | TWL4030_BCIMFKEY); | ||
352 | if (status < 0) | ||
353 | return status; | ||
354 | twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, | ||
355 | fullreg, TWL4030_BCIMFTH8); | ||
356 | } | ||
196 | 357 | ||
197 | /* in case we also have STS_USB_ID, VBUS is driven by TWL itself */ | 358 | /* ichg_hi threshold must be 1XXXX01100 (I think) */ |
198 | if ((hwsts & TWL4030_STS_VBUS) && !(hwsts & TWL4030_STS_USB_ID)) | 359 | reg = ua2regval(bci->ichg_hi, cgain); |
199 | return 1; | 360 | if (reg > 0x3E0) |
361 | reg = 0x3E0; | ||
362 | if (reg < 0x200) | ||
363 | reg = 0x200; | ||
364 | fullreg = (reg >> 5) & 0xF; | ||
365 | fullreg <<= 4; | ||
366 | status = twl4030_bci_read(TWL4030_BCIMFTH9, &oldreg); | ||
367 | if (status < 0) | ||
368 | return status; | ||
369 | if ((oldreg & 0xF0) != fullreg) { | ||
370 | fullreg |= (oldreg & 0x0F); | ||
371 | status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xE7, | ||
372 | TWL4030_BCIMFKEY); | ||
373 | if (status < 0) | ||
374 | return status; | ||
375 | twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, | ||
376 | fullreg, TWL4030_BCIMFTH9); | ||
377 | } | ||
200 | 378 | ||
379 | /* | ||
380 | * And finally, set the current. This is stored in | ||
381 | * two registers. | ||
382 | */ | ||
383 | reg = ua2regval(cur, cgain); | ||
384 | /* we have only 10 bits */ | ||
385 | if (reg > 0x3ff) | ||
386 | reg = 0x3ff; | ||
387 | status = twl4030_bci_read(TWL4030_BCIIREF1, &oldreg); | ||
388 | if (status < 0) | ||
389 | return status; | ||
390 | cur_reg = oldreg; | ||
391 | status = twl4030_bci_read(TWL4030_BCIIREF2, &oldreg); | ||
392 | if (status < 0) | ||
393 | return status; | ||
394 | cur_reg |= oldreg << 8; | ||
395 | if (reg != oldreg) { | ||
396 | /* disable write protection for one write access for | ||
397 | * BCIIREF */ | ||
398 | status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xE7, | ||
399 | TWL4030_BCIMFKEY); | ||
400 | if (status < 0) | ||
401 | return status; | ||
402 | status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, | ||
403 | (reg & 0x100) ? 3 : 2, | ||
404 | TWL4030_BCIIREF2); | ||
405 | if (status < 0) | ||
406 | return status; | ||
407 | /* disable write protection for one write access for | ||
408 | * BCIIREF */ | ||
409 | status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xE7, | ||
410 | TWL4030_BCIMFKEY); | ||
411 | if (status < 0) | ||
412 | return status; | ||
413 | status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, | ||
414 | reg & 0xff, | ||
415 | TWL4030_BCIIREF1); | ||
416 | } | ||
417 | if ((!!cgain) != !!(bcictl1 & TWL4030_CGAIN)) { | ||
418 | /* Flip CGAIN and re-enable charging */ | ||
419 | bcictl1 ^= TWL4030_CGAIN; | ||
420 | twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, | ||
421 | bcictl1, TWL4030_BCICTL1); | ||
422 | twl4030_clear_set_boot_bci(0, boot_bci); | ||
423 | } | ||
201 | return 0; | 424 | return 0; |
202 | } | 425 | } |
203 | 426 | ||
427 | static int twl4030_charger_get_current(void); | ||
428 | |||
429 | static void twl4030_current_worker(struct work_struct *data) | ||
430 | { | ||
431 | int v, curr; | ||
432 | int res; | ||
433 | struct twl4030_bci *bci = container_of(data, struct twl4030_bci, | ||
434 | current_worker.work); | ||
435 | |||
436 | res = twl4030bci_read_adc_val(TWL4030_BCIVBUS); | ||
437 | if (res < 0) | ||
438 | v = 0; | ||
439 | else | ||
440 | /* BCIVBUS uses ADCIN8, 7/1023 V/step */ | ||
441 | v = res * 6843; | ||
442 | curr = twl4030_charger_get_current(); | ||
443 | |||
444 | dev_dbg(bci->dev, "v=%d cur=%d limit=%d target=%d\n", v, curr, | ||
445 | bci->usb_cur, bci->usb_cur_target); | ||
446 | |||
447 | if (v < USB_MIN_VOLT) { | ||
448 | /* Back up and stop adjusting. */ | ||
449 | bci->usb_cur -= USB_CUR_STEP; | ||
450 | bci->usb_cur_target = bci->usb_cur; | ||
451 | } else if (bci->usb_cur >= bci->usb_cur_target || | ||
452 | bci->usb_cur + USB_CUR_STEP > USB_MAX_CURRENT) { | ||
453 | /* Reached target and voltage is OK - stop */ | ||
454 | return; | ||
455 | } else { | ||
456 | bci->usb_cur += USB_CUR_STEP; | ||
457 | schedule_delayed_work(&bci->current_worker, USB_CUR_DELAY); | ||
458 | } | ||
459 | twl4030_charger_update_current(bci); | ||
460 | } | ||
461 | |||
204 | /* | 462 | /* |
205 | * Enable/Disable USB Charge functionality. | 463 | * Enable/Disable USB Charge functionality. |
206 | */ | 464 | */ |
@@ -208,45 +466,60 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable) | |||
208 | { | 466 | { |
209 | int ret; | 467 | int ret; |
210 | 468 | ||
211 | if (enable) { | 469 | if (bci->usb_mode == CHARGE_OFF) |
212 | /* Check for USB charger connected */ | 470 | enable = false; |
213 | if (!twl4030_bci_have_vbus(bci)) | 471 | if (enable && !IS_ERR_OR_NULL(bci->transceiver)) { |
214 | return -ENODEV; | ||
215 | 472 | ||
216 | /* | 473 | twl4030_charger_update_current(bci); |
217 | * Until we can find out what current the device can provide, | ||
218 | * require a module param to enable USB charging. | ||
219 | */ | ||
220 | if (!allow_usb) { | ||
221 | dev_warn(bci->dev, "USB charging is disabled.\n"); | ||
222 | return -EACCES; | ||
223 | } | ||
224 | 474 | ||
225 | /* Need to keep regulator on */ | 475 | /* Need to keep phy powered */ |
226 | if (!bci->usb_enabled) { | 476 | if (!bci->usb_enabled) { |
227 | ret = regulator_enable(bci->usb_reg); | 477 | pm_runtime_get_sync(bci->transceiver->dev); |
228 | if (ret) { | ||
229 | dev_err(bci->dev, | ||
230 | "Failed to enable regulator\n"); | ||
231 | return ret; | ||
232 | } | ||
233 | bci->usb_enabled = 1; | 478 | bci->usb_enabled = 1; |
234 | } | 479 | } |
235 | 480 | ||
236 | /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */ | 481 | if (bci->usb_mode == CHARGE_AUTO) |
237 | ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB); | 482 | /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */ |
238 | if (ret < 0) | 483 | ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB); |
239 | return ret; | ||
240 | 484 | ||
241 | /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */ | 485 | /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */ |
242 | ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0, | 486 | ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0, |
243 | TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4); | 487 | TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4); |
488 | if (bci->usb_mode == CHARGE_LINEAR) { | ||
489 | twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0); | ||
490 | /* Watch dog key: WOVF acknowledge */ | ||
491 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33, | ||
492 | TWL4030_BCIWDKEY); | ||
493 | /* 0x24 + EKEY6: off mode */ | ||
494 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a, | ||
495 | TWL4030_BCIMDKEY); | ||
496 | /* EKEY2: Linear charge: USB path */ | ||
497 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x26, | ||
498 | TWL4030_BCIMDKEY); | ||
499 | /* WDKEY5: stop watchdog count */ | ||
500 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xf3, | ||
501 | TWL4030_BCIWDKEY); | ||
502 | /* enable MFEN3 access */ | ||
503 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x9c, | ||
504 | TWL4030_BCIMFKEY); | ||
505 | /* ICHGEOCEN - end-of-charge monitor (current < 80mA) | ||
506 | * (charging continues) | ||
507 | * ICHGLOWEN - current level monitor (charge continues) | ||
508 | * don't monitor over-current or heat save | ||
509 | */ | ||
510 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xf0, | ||
511 | TWL4030_BCIMFEN3); | ||
512 | } | ||
244 | } else { | 513 | } else { |
245 | ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0); | 514 | ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0); |
515 | ret |= twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a, | ||
516 | TWL4030_BCIMDKEY); | ||
246 | if (bci->usb_enabled) { | 517 | if (bci->usb_enabled) { |
247 | regulator_disable(bci->usb_reg); | 518 | pm_runtime_mark_last_busy(bci->transceiver->dev); |
519 | pm_runtime_put_autosuspend(bci->transceiver->dev); | ||
248 | bci->usb_enabled = 0; | 520 | bci->usb_enabled = 0; |
249 | } | 521 | } |
522 | bci->usb_cur = 0; | ||
250 | } | 523 | } |
251 | 524 | ||
252 | return ret; | 525 | return ret; |
@@ -255,10 +528,13 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable) | |||
255 | /* | 528 | /* |
256 | * Enable/Disable AC Charge funtionality. | 529 | * Enable/Disable AC Charge funtionality. |
257 | */ | 530 | */ |
258 | static int twl4030_charger_enable_ac(bool enable) | 531 | static int twl4030_charger_enable_ac(struct twl4030_bci *bci, bool enable) |
259 | { | 532 | { |
260 | int ret; | 533 | int ret; |
261 | 534 | ||
535 | if (bci->ac_mode == CHARGE_OFF) | ||
536 | enable = false; | ||
537 | |||
262 | if (enable) | 538 | if (enable) |
263 | ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOAC); | 539 | ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOAC); |
264 | else | 540 | else |
@@ -318,6 +594,9 @@ static irqreturn_t twl4030_charger_interrupt(int irq, void *arg) | |||
318 | struct twl4030_bci *bci = arg; | 594 | struct twl4030_bci *bci = arg; |
319 | 595 | ||
320 | dev_dbg(bci->dev, "CHG_PRES irq\n"); | 596 | dev_dbg(bci->dev, "CHG_PRES irq\n"); |
597 | /* reset current on each 'plug' event */ | ||
598 | bci->ac_cur = 500000; | ||
599 | twl4030_charger_update_current(bci); | ||
321 | power_supply_changed(bci->ac); | 600 | power_supply_changed(bci->ac); |
322 | power_supply_changed(bci->usb); | 601 | power_supply_changed(bci->usb); |
323 | 602 | ||
@@ -350,6 +629,7 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void *arg) | |||
350 | power_supply_changed(bci->ac); | 629 | power_supply_changed(bci->ac); |
351 | power_supply_changed(bci->usb); | 630 | power_supply_changed(bci->usb); |
352 | } | 631 | } |
632 | twl4030_charger_update_current(bci); | ||
353 | 633 | ||
354 | /* various monitoring events, for now we just log them here */ | 634 | /* various monitoring events, for now we just log them here */ |
355 | if (irqs1 & (TWL4030_TBATOR2 | TWL4030_TBATOR1)) | 635 | if (irqs1 & (TWL4030_TBATOR2 | TWL4030_TBATOR1)) |
@@ -370,6 +650,63 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void *arg) | |||
370 | return IRQ_HANDLED; | 650 | return IRQ_HANDLED; |
371 | } | 651 | } |
372 | 652 | ||
653 | /* | ||
654 | * Provide "max_current" attribute in sysfs. | ||
655 | */ | ||
656 | static ssize_t | ||
657 | twl4030_bci_max_current_store(struct device *dev, struct device_attribute *attr, | ||
658 | const char *buf, size_t n) | ||
659 | { | ||
660 | struct twl4030_bci *bci = dev_get_drvdata(dev->parent); | ||
661 | int cur = 0; | ||
662 | int status = 0; | ||
663 | status = kstrtoint(buf, 10, &cur); | ||
664 | if (status) | ||
665 | return status; | ||
666 | if (cur < 0) | ||
667 | return -EINVAL; | ||
668 | if (dev == &bci->ac->dev) | ||
669 | bci->ac_cur = cur; | ||
670 | else | ||
671 | bci->usb_cur_target = cur; | ||
672 | |||
673 | twl4030_charger_update_current(bci); | ||
674 | return n; | ||
675 | } | ||
676 | |||
677 | /* | ||
678 | * sysfs max_current show | ||
679 | */ | ||
680 | static ssize_t twl4030_bci_max_current_show(struct device *dev, | ||
681 | struct device_attribute *attr, char *buf) | ||
682 | { | ||
683 | int status = 0; | ||
684 | int cur = -1; | ||
685 | u8 bcictl1; | ||
686 | struct twl4030_bci *bci = dev_get_drvdata(dev->parent); | ||
687 | |||
688 | if (dev == &bci->ac->dev) { | ||
689 | if (!bci->ac_is_active) | ||
690 | cur = bci->ac_cur; | ||
691 | } else { | ||
692 | if (bci->ac_is_active) | ||
693 | cur = bci->usb_cur_target; | ||
694 | } | ||
695 | if (cur < 0) { | ||
696 | cur = twl4030bci_read_adc_val(TWL4030_BCIIREF1); | ||
697 | if (cur < 0) | ||
698 | return cur; | ||
699 | status = twl4030_bci_read(TWL4030_BCICTL1, &bcictl1); | ||
700 | if (status < 0) | ||
701 | return status; | ||
702 | cur = regval2ua(cur, bcictl1 & TWL4030_CGAIN); | ||
703 | } | ||
704 | return scnprintf(buf, PAGE_SIZE, "%u\n", cur); | ||
705 | } | ||
706 | |||
707 | static DEVICE_ATTR(max_current, 0644, twl4030_bci_max_current_show, | ||
708 | twl4030_bci_max_current_store); | ||
709 | |||
373 | static void twl4030_bci_usb_work(struct work_struct *data) | 710 | static void twl4030_bci_usb_work(struct work_struct *data) |
374 | { | 711 | { |
375 | struct twl4030_bci *bci = container_of(data, struct twl4030_bci, work); | 712 | struct twl4030_bci *bci = container_of(data, struct twl4030_bci, work); |
@@ -392,6 +729,12 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, unsigned long val, | |||
392 | 729 | ||
393 | dev_dbg(bci->dev, "OTG notify %lu\n", val); | 730 | dev_dbg(bci->dev, "OTG notify %lu\n", val); |
394 | 731 | ||
732 | /* reset current on each 'plug' event */ | ||
733 | if (allow_usb) | ||
734 | bci->usb_cur_target = 500000; | ||
735 | else | ||
736 | bci->usb_cur_target = 100000; | ||
737 | |||
395 | bci->event = val; | 738 | bci->event = val; |
396 | schedule_work(&bci->work); | 739 | schedule_work(&bci->work); |
397 | 740 | ||
@@ -399,13 +742,66 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, unsigned long val, | |||
399 | } | 742 | } |
400 | 743 | ||
401 | /* | 744 | /* |
402 | * TI provided formulas: | 745 | * sysfs charger enabled store |
403 | * CGAIN == 0: ICHG = (BCIICHG * 1.7) / (2^10 - 1) - 0.85 | 746 | */ |
404 | * CGAIN == 1: ICHG = (BCIICHG * 3.4) / (2^10 - 1) - 1.7 | 747 | static ssize_t |
405 | * Here we use integer approximation of: | 748 | twl4030_bci_mode_store(struct device *dev, struct device_attribute *attr, |
406 | * CGAIN == 0: val * 1.6618 - 0.85 | 749 | const char *buf, size_t n) |
407 | * CGAIN == 1: (val * 1.6618 - 0.85) * 2 | 750 | { |
751 | struct twl4030_bci *bci = dev_get_drvdata(dev->parent); | ||
752 | int mode; | ||
753 | int status; | ||
754 | |||
755 | if (sysfs_streq(buf, modes[0])) | ||
756 | mode = 0; | ||
757 | else if (sysfs_streq(buf, modes[1])) | ||
758 | mode = 1; | ||
759 | else if (sysfs_streq(buf, modes[2])) | ||
760 | mode = 2; | ||
761 | else | ||
762 | return -EINVAL; | ||
763 | if (dev == &bci->ac->dev) { | ||
764 | if (mode == 2) | ||
765 | return -EINVAL; | ||
766 | twl4030_charger_enable_ac(bci, false); | ||
767 | bci->ac_mode = mode; | ||
768 | status = twl4030_charger_enable_ac(bci, true); | ||
769 | } else { | ||
770 | twl4030_charger_enable_usb(bci, false); | ||
771 | bci->usb_mode = mode; | ||
772 | status = twl4030_charger_enable_usb(bci, true); | ||
773 | } | ||
774 | return (status == 0) ? n : status; | ||
775 | } | ||
776 | |||
777 | /* | ||
778 | * sysfs charger enabled show | ||
408 | */ | 779 | */ |
780 | static ssize_t | ||
781 | twl4030_bci_mode_show(struct device *dev, | ||
782 | struct device_attribute *attr, char *buf) | ||
783 | { | ||
784 | struct twl4030_bci *bci = dev_get_drvdata(dev->parent); | ||
785 | int len = 0; | ||
786 | int i; | ||
787 | int mode = bci->usb_mode; | ||
788 | |||
789 | if (dev == &bci->ac->dev) | ||
790 | mode = bci->ac_mode; | ||
791 | |||
792 | for (i = 0; i < ARRAY_SIZE(modes); i++) | ||
793 | if (mode == i) | ||
794 | len += snprintf(buf+len, PAGE_SIZE-len, | ||
795 | "[%s] ", modes[i]); | ||
796 | else | ||
797 | len += snprintf(buf+len, PAGE_SIZE-len, | ||
798 | "%s ", modes[i]); | ||
799 | buf[len-1] = '\n'; | ||
800 | return len; | ||
801 | } | ||
802 | static DEVICE_ATTR(mode, 0644, twl4030_bci_mode_show, | ||
803 | twl4030_bci_mode_store); | ||
804 | |||
409 | static int twl4030_charger_get_current(void) | 805 | static int twl4030_charger_get_current(void) |
410 | { | 806 | { |
411 | int curr; | 807 | int curr; |
@@ -420,11 +816,7 @@ static int twl4030_charger_get_current(void) | |||
420 | if (ret) | 816 | if (ret) |
421 | return ret; | 817 | return ret; |
422 | 818 | ||
423 | ret = (curr * 16618 - 850 * 10000) / 10; | 819 | return regval2ua(curr, bcictl1 & TWL4030_CGAIN); |
424 | if (bcictl1 & TWL4030_CGAIN) | ||
425 | ret *= 2; | ||
426 | |||
427 | return ret; | ||
428 | } | 820 | } |
429 | 821 | ||
430 | /* | 822 | /* |
@@ -476,6 +868,17 @@ static int twl4030_bci_get_property(struct power_supply *psy, | |||
476 | is_charging = state & TWL4030_MSTATEC_USB; | 868 | is_charging = state & TWL4030_MSTATEC_USB; |
477 | else | 869 | else |
478 | is_charging = state & TWL4030_MSTATEC_AC; | 870 | is_charging = state & TWL4030_MSTATEC_AC; |
871 | if (!is_charging) { | ||
872 | u8 s; | ||
873 | twl4030_bci_read(TWL4030_BCIMDEN, &s); | ||
874 | if (psy->desc->type == POWER_SUPPLY_TYPE_USB) | ||
875 | is_charging = s & 1; | ||
876 | else | ||
877 | is_charging = s & 2; | ||
878 | if (is_charging) | ||
879 | /* A little white lie */ | ||
880 | state = TWL4030_MSTATEC_QUICK1; | ||
881 | } | ||
479 | 882 | ||
480 | switch (psp) { | 883 | switch (psp) { |
481 | case POWER_SUPPLY_PROP_STATUS: | 884 | case POWER_SUPPLY_PROP_STATUS: |
@@ -574,20 +977,31 @@ static const struct power_supply_desc twl4030_bci_usb_desc = { | |||
574 | .get_property = twl4030_bci_get_property, | 977 | .get_property = twl4030_bci_get_property, |
575 | }; | 978 | }; |
576 | 979 | ||
577 | static int __init twl4030_bci_probe(struct platform_device *pdev) | 980 | static int twl4030_bci_probe(struct platform_device *pdev) |
578 | { | 981 | { |
579 | struct twl4030_bci *bci; | 982 | struct twl4030_bci *bci; |
580 | const struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; | 983 | const struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; |
581 | int ret; | 984 | int ret; |
582 | u32 reg; | 985 | u32 reg; |
583 | 986 | ||
584 | bci = kzalloc(sizeof(*bci), GFP_KERNEL); | 987 | bci = devm_kzalloc(&pdev->dev, sizeof(*bci), GFP_KERNEL); |
585 | if (bci == NULL) | 988 | if (bci == NULL) |
586 | return -ENOMEM; | 989 | return -ENOMEM; |
587 | 990 | ||
588 | if (!pdata) | 991 | if (!pdata) |
589 | pdata = twl4030_bci_parse_dt(&pdev->dev); | 992 | pdata = twl4030_bci_parse_dt(&pdev->dev); |
590 | 993 | ||
994 | bci->ichg_eoc = 80100; /* Stop charging when current drops to here */ | ||
995 | bci->ichg_lo = 241000; /* Low threshold */ | ||
996 | bci->ichg_hi = 500000; /* High threshold */ | ||
997 | bci->ac_cur = 500000; /* 500mA */ | ||
998 | if (allow_usb) | ||
999 | bci->usb_cur_target = 500000; /* 500mA */ | ||
1000 | else | ||
1001 | bci->usb_cur_target = 100000; /* 100mA */ | ||
1002 | bci->usb_mode = CHARGE_AUTO; | ||
1003 | bci->ac_mode = CHARGE_AUTO; | ||
1004 | |||
591 | bci->dev = &pdev->dev; | 1005 | bci->dev = &pdev->dev; |
592 | bci->irq_chg = platform_get_irq(pdev, 0); | 1006 | bci->irq_chg = platform_get_irq(pdev, 0); |
593 | bci->irq_bci = platform_get_irq(pdev, 1); | 1007 | bci->irq_bci = platform_get_irq(pdev, 1); |
@@ -596,47 +1010,46 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
596 | ret = twl4030_is_battery_present(bci); | 1010 | ret = twl4030_is_battery_present(bci); |
597 | if (ret) { | 1011 | if (ret) { |
598 | dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret); | 1012 | dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret); |
599 | goto fail_no_battery; | 1013 | return ret; |
600 | } | 1014 | } |
601 | 1015 | ||
602 | platform_set_drvdata(pdev, bci); | 1016 | platform_set_drvdata(pdev, bci); |
603 | 1017 | ||
604 | bci->ac = power_supply_register(&pdev->dev, &twl4030_bci_ac_desc, | 1018 | bci->ac = devm_power_supply_register(&pdev->dev, &twl4030_bci_ac_desc, |
605 | NULL); | 1019 | NULL); |
606 | if (IS_ERR(bci->ac)) { | 1020 | if (IS_ERR(bci->ac)) { |
607 | ret = PTR_ERR(bci->ac); | 1021 | ret = PTR_ERR(bci->ac); |
608 | dev_err(&pdev->dev, "failed to register ac: %d\n", ret); | 1022 | dev_err(&pdev->dev, "failed to register ac: %d\n", ret); |
609 | goto fail_register_ac; | 1023 | return ret; |
610 | } | 1024 | } |
611 | 1025 | ||
612 | bci->usb_reg = regulator_get(bci->dev, "bci3v1"); | 1026 | bci->usb = devm_power_supply_register(&pdev->dev, &twl4030_bci_usb_desc, |
613 | 1027 | NULL); | |
614 | bci->usb = power_supply_register(&pdev->dev, &twl4030_bci_usb_desc, | ||
615 | NULL); | ||
616 | if (IS_ERR(bci->usb)) { | 1028 | if (IS_ERR(bci->usb)) { |
617 | ret = PTR_ERR(bci->usb); | 1029 | ret = PTR_ERR(bci->usb); |
618 | dev_err(&pdev->dev, "failed to register usb: %d\n", ret); | 1030 | dev_err(&pdev->dev, "failed to register usb: %d\n", ret); |
619 | goto fail_register_usb; | 1031 | return ret; |
620 | } | 1032 | } |
621 | 1033 | ||
622 | ret = request_threaded_irq(bci->irq_chg, NULL, | 1034 | ret = devm_request_threaded_irq(&pdev->dev, bci->irq_chg, NULL, |
623 | twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name, | 1035 | twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name, |
624 | bci); | 1036 | bci); |
625 | if (ret < 0) { | 1037 | if (ret < 0) { |
626 | dev_err(&pdev->dev, "could not request irq %d, status %d\n", | 1038 | dev_err(&pdev->dev, "could not request irq %d, status %d\n", |
627 | bci->irq_chg, ret); | 1039 | bci->irq_chg, ret); |
628 | goto fail_chg_irq; | 1040 | return ret; |
629 | } | 1041 | } |
630 | 1042 | ||
631 | ret = request_threaded_irq(bci->irq_bci, NULL, | 1043 | ret = devm_request_threaded_irq(&pdev->dev, bci->irq_bci, NULL, |
632 | twl4030_bci_interrupt, IRQF_ONESHOT, pdev->name, bci); | 1044 | twl4030_bci_interrupt, IRQF_ONESHOT, pdev->name, bci); |
633 | if (ret < 0) { | 1045 | if (ret < 0) { |
634 | dev_err(&pdev->dev, "could not request irq %d, status %d\n", | 1046 | dev_err(&pdev->dev, "could not request irq %d, status %d\n", |
635 | bci->irq_bci, ret); | 1047 | bci->irq_bci, ret); |
636 | goto fail_bci_irq; | 1048 | return ret; |
637 | } | 1049 | } |
638 | 1050 | ||
639 | INIT_WORK(&bci->work, twl4030_bci_usb_work); | 1051 | INIT_WORK(&bci->work, twl4030_bci_usb_work); |
1052 | INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker); | ||
640 | 1053 | ||
641 | bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; | 1054 | bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; |
642 | if (bci->dev->of_node) { | 1055 | if (bci->dev->of_node) { |
@@ -644,9 +1057,13 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
644 | 1057 | ||
645 | phynode = of_find_compatible_node(bci->dev->of_node->parent, | 1058 | phynode = of_find_compatible_node(bci->dev->of_node->parent, |
646 | NULL, "ti,twl4030-usb"); | 1059 | NULL, "ti,twl4030-usb"); |
647 | if (phynode) | 1060 | if (phynode) { |
648 | bci->transceiver = devm_usb_get_phy_by_node( | 1061 | bci->transceiver = devm_usb_get_phy_by_node( |
649 | bci->dev, phynode, &bci->usb_nb); | 1062 | bci->dev, phynode, &bci->usb_nb); |
1063 | if (IS_ERR(bci->transceiver) && | ||
1064 | PTR_ERR(bci->transceiver) == -EPROBE_DEFER) | ||
1065 | return -EPROBE_DEFER; | ||
1066 | } | ||
650 | } | 1067 | } |
651 | 1068 | ||
652 | /* Enable interrupts now. */ | 1069 | /* Enable interrupts now. */ |
@@ -656,7 +1073,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
656 | TWL4030_INTERRUPTS_BCIIMR1A); | 1073 | TWL4030_INTERRUPTS_BCIIMR1A); |
657 | if (ret < 0) { | 1074 | if (ret < 0) { |
658 | dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret); | 1075 | dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret); |
659 | goto fail_unmask_interrupts; | 1076 | return ret; |
660 | } | 1077 | } |
661 | 1078 | ||
662 | reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV); | 1079 | reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV); |
@@ -665,8 +1082,23 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
665 | if (ret < 0) | 1082 | if (ret < 0) |
666 | dev_warn(&pdev->dev, "failed to unmask interrupts: %d\n", ret); | 1083 | dev_warn(&pdev->dev, "failed to unmask interrupts: %d\n", ret); |
667 | 1084 | ||
668 | twl4030_charger_enable_ac(true); | 1085 | twl4030_charger_update_current(bci); |
669 | twl4030_charger_enable_usb(bci, true); | 1086 | if (device_create_file(&bci->usb->dev, &dev_attr_max_current)) |
1087 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | ||
1088 | if (device_create_file(&bci->usb->dev, &dev_attr_mode)) | ||
1089 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | ||
1090 | if (device_create_file(&bci->ac->dev, &dev_attr_mode)) | ||
1091 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | ||
1092 | if (device_create_file(&bci->ac->dev, &dev_attr_max_current)) | ||
1093 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | ||
1094 | |||
1095 | twl4030_charger_enable_ac(bci, true); | ||
1096 | if (!IS_ERR_OR_NULL(bci->transceiver)) | ||
1097 | twl4030_bci_usb_ncb(&bci->usb_nb, | ||
1098 | bci->transceiver->last_event, | ||
1099 | NULL); | ||
1100 | else | ||
1101 | twl4030_charger_enable_usb(bci, false); | ||
670 | if (pdata) | 1102 | if (pdata) |
671 | twl4030_charger_enable_backup(pdata->bb_uvolt, | 1103 | twl4030_charger_enable_backup(pdata->bb_uvolt, |
672 | pdata->bb_uamp); | 1104 | pdata->bb_uamp); |
@@ -674,42 +1106,26 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) | |||
674 | twl4030_charger_enable_backup(0, 0); | 1106 | twl4030_charger_enable_backup(0, 0); |
675 | 1107 | ||
676 | return 0; | 1108 | return 0; |
677 | |||
678 | fail_unmask_interrupts: | ||
679 | free_irq(bci->irq_bci, bci); | ||
680 | fail_bci_irq: | ||
681 | free_irq(bci->irq_chg, bci); | ||
682 | fail_chg_irq: | ||
683 | power_supply_unregister(bci->usb); | ||
684 | fail_register_usb: | ||
685 | power_supply_unregister(bci->ac); | ||
686 | fail_register_ac: | ||
687 | fail_no_battery: | ||
688 | kfree(bci); | ||
689 | |||
690 | return ret; | ||
691 | } | 1109 | } |
692 | 1110 | ||
693 | static int __exit twl4030_bci_remove(struct platform_device *pdev) | 1111 | static int __exit twl4030_bci_remove(struct platform_device *pdev) |
694 | { | 1112 | { |
695 | struct twl4030_bci *bci = platform_get_drvdata(pdev); | 1113 | struct twl4030_bci *bci = platform_get_drvdata(pdev); |
696 | 1114 | ||
697 | twl4030_charger_enable_ac(false); | 1115 | twl4030_charger_enable_ac(bci, false); |
698 | twl4030_charger_enable_usb(bci, false); | 1116 | twl4030_charger_enable_usb(bci, false); |
699 | twl4030_charger_enable_backup(0, 0); | 1117 | twl4030_charger_enable_backup(0, 0); |
700 | 1118 | ||
1119 | device_remove_file(&bci->usb->dev, &dev_attr_max_current); | ||
1120 | device_remove_file(&bci->usb->dev, &dev_attr_mode); | ||
1121 | device_remove_file(&bci->ac->dev, &dev_attr_max_current); | ||
1122 | device_remove_file(&bci->ac->dev, &dev_attr_mode); | ||
701 | /* mask interrupts */ | 1123 | /* mask interrupts */ |
702 | twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, | 1124 | twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, |
703 | TWL4030_INTERRUPTS_BCIIMR1A); | 1125 | TWL4030_INTERRUPTS_BCIIMR1A); |
704 | twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, | 1126 | twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, |
705 | TWL4030_INTERRUPTS_BCIIMR2A); | 1127 | TWL4030_INTERRUPTS_BCIIMR2A); |
706 | 1128 | ||
707 | free_irq(bci->irq_bci, bci); | ||
708 | free_irq(bci->irq_chg, bci); | ||
709 | power_supply_unregister(bci->usb); | ||
710 | power_supply_unregister(bci->ac); | ||
711 | kfree(bci); | ||
712 | |||
713 | return 0; | 1129 | return 0; |
714 | } | 1130 | } |
715 | 1131 | ||
@@ -720,14 +1136,14 @@ static const struct of_device_id twl_bci_of_match[] = { | |||
720 | MODULE_DEVICE_TABLE(of, twl_bci_of_match); | 1136 | MODULE_DEVICE_TABLE(of, twl_bci_of_match); |
721 | 1137 | ||
722 | static struct platform_driver twl4030_bci_driver = { | 1138 | static struct platform_driver twl4030_bci_driver = { |
1139 | .probe = twl4030_bci_probe, | ||
723 | .driver = { | 1140 | .driver = { |
724 | .name = "twl4030_bci", | 1141 | .name = "twl4030_bci", |
725 | .of_match_table = of_match_ptr(twl_bci_of_match), | 1142 | .of_match_table = of_match_ptr(twl_bci_of_match), |
726 | }, | 1143 | }, |
727 | .remove = __exit_p(twl4030_bci_remove), | 1144 | .remove = __exit_p(twl4030_bci_remove), |
728 | }; | 1145 | }; |
729 | 1146 | module_platform_driver(twl4030_bci_driver); | |
730 | module_platform_driver_probe(twl4030_bci_driver, twl4030_bci_probe); | ||
731 | 1147 | ||
732 | MODULE_AUTHOR("Gražvydas Ignotas"); | 1148 | MODULE_AUTHOR("Gražvydas Ignotas"); |
733 | MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver"); | 1149 | MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver"); |