diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-22 15:04:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-22 15:04:59 -0400 |
commit | 619e17cf75dd58905aa67ccd494a6ba5f19d6cc6 (patch) | |
tree | 512e53d9d05366d48eea681ad7b29ba30537b263 | |
parent | 57f1c3caf5137d4493fcd1d07c3ae4a5636f4949 (diff) | |
parent | 7f7378618b4103c083db7de5017df958f8ada070 (diff) |
Merge tag 'for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset updates from Sebastian Reichel:
"Core:
- Ensure HWMON devices are registered with valid names
- Fix device wakeup code
Drivers:
- bq25890_charger: Add BQ25895 support
- axp288_fuel_gauge: Add Minix Neo Z83-4 to blacklist
- sc27xx: improve battery calibration
- misc small fixes all over drivers"
* tag 'for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (24 commits)
power: supply: cpcap-charger: Enable vbus boost voltage
power: supply: sc27xx: Add POWER_SUPPLY_PROP_CALIBRATE attribute
power: supply: sc27xx: Optimize the battery capacity calibration
power: supply: sc27xx: Make sure the alarm capacity is larger than 0
power: supply: sc27xx: Fix the the accuracy issue of coulomb calculation
power: supply: sc27xx: Fix conditon to enable the FGU interrupt
power: supply: sc27xx: Add POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN attribute
power: supply: max77650: add MODULE_ALIAS()
power: supply: isp1704: remove redundant assignment to variable ret
power: supply: bq25890_charger: Add the BQ25895 part
power: supply: sc27xx: Replace devm_add_action() followed by failure action with devm_add_action_or_reset()
power: supply: sc27xx: Introduce local variable 'struct device *dev'
power: reset: reboot-mode: Fix author email format
power: supply: ab8500: remove set but not used variables 'vbup33_vrtcn' and 'bup_vch_range'
power: supply: max17042_battery: Fix a typo in function names
power: reset: gpio-restart: Fix typo when gpio reset is not found
power: supply: Init device wakeup after device_add()
power: supply: ab8500_charger: Mark expected switch fall-through
power: supply: sbs-battery: only return health when battery present
MAINTAINERS: N900: Remove isp1704_charger.h record
...
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/phy/motorola/phy-cpcap-usb.c | 8 | ||||
-rw-r--r-- | drivers/power/reset/gpio-restart.c | 2 | ||||
-rw-r--r-- | drivers/power/reset/reboot-mode.c | 2 | ||||
-rw-r--r-- | drivers/power/supply/ab8500_charger.c | 9 | ||||
-rw-r--r-- | drivers/power/supply/axp288_fuel_gauge.c | 14 | ||||
-rw-r--r-- | drivers/power/supply/bq25890_charger.c | 12 | ||||
-rw-r--r-- | drivers/power/supply/cpcap-charger.c | 23 | ||||
-rw-r--r-- | drivers/power/supply/isp1704_charger.c | 2 | ||||
-rw-r--r-- | drivers/power/supply/max17042_battery.c | 8 | ||||
-rw-r--r-- | drivers/power/supply/max77650-charger.c | 1 | ||||
-rw-r--r-- | drivers/power/supply/power_supply_core.c | 10 | ||||
-rw-r--r-- | drivers/power/supply/power_supply_hwmon.c | 15 | ||||
-rw-r--r-- | drivers/power/supply/sbs-battery.c | 27 | ||||
-rw-r--r-- | drivers/power/supply/sc27xx_fuel_gauge.c | 223 |
15 files changed, 237 insertions, 120 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 9267a42655cc..a400af0501c9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -11511,7 +11511,6 @@ NOKIA N900 POWER SUPPLY DRIVERS | |||
11511 | R: Pali Rohár <pali.rohar@gmail.com> | 11511 | R: Pali Rohár <pali.rohar@gmail.com> |
11512 | F: include/linux/power/bq2415x_charger.h | 11512 | F: include/linux/power/bq2415x_charger.h |
11513 | F: include/linux/power/bq27xxx_battery.h | 11513 | F: include/linux/power/bq27xxx_battery.h |
11514 | F: include/linux/power/isp1704_charger.h | ||
11515 | F: drivers/power/supply/bq2415x_charger.c | 11514 | F: drivers/power/supply/bq2415x_charger.c |
11516 | F: drivers/power/supply/bq27xxx_battery.c | 11515 | F: drivers/power/supply/bq27xxx_battery.c |
11517 | F: drivers/power/supply/bq27xxx_battery_i2c.c | 11516 | F: drivers/power/supply/bq27xxx_battery_i2c.c |
diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c index 6601ad0dfb3a..ead06c6c2601 100644 --- a/drivers/phy/motorola/phy-cpcap-usb.c +++ b/drivers/phy/motorola/phy-cpcap-usb.c | |||
@@ -231,8 +231,9 @@ static void cpcap_usb_detect(struct work_struct *work) | |||
231 | goto out_err; | 231 | goto out_err; |
232 | 232 | ||
233 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, | 233 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, |
234 | CPCAP_BIT_VBUSSTBY_EN, | 234 | CPCAP_BIT_VBUSSTBY_EN | |
235 | CPCAP_BIT_VBUSSTBY_EN); | 235 | CPCAP_BIT_VBUSEN_SPI, |
236 | CPCAP_BIT_VBUSEN_SPI); | ||
236 | if (error) | 237 | if (error) |
237 | goto out_err; | 238 | goto out_err; |
238 | 239 | ||
@@ -240,7 +241,8 @@ static void cpcap_usb_detect(struct work_struct *work) | |||
240 | } | 241 | } |
241 | 242 | ||
242 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, | 243 | error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, |
243 | CPCAP_BIT_VBUSSTBY_EN, 0); | 244 | CPCAP_BIT_VBUSSTBY_EN | |
245 | CPCAP_BIT_VBUSEN_SPI, 0); | ||
244 | if (error) | 246 | if (error) |
245 | goto out_err; | 247 | goto out_err; |
246 | 248 | ||
diff --git a/drivers/power/reset/gpio-restart.c b/drivers/power/reset/gpio-restart.c index 2880cd5ae0d2..308ca9d9d276 100644 --- a/drivers/power/reset/gpio-restart.c +++ b/drivers/power/reset/gpio-restart.c | |||
@@ -65,7 +65,7 @@ static int gpio_restart_probe(struct platform_device *pdev) | |||
65 | gpio_restart->reset_gpio = devm_gpiod_get(&pdev->dev, NULL, | 65 | gpio_restart->reset_gpio = devm_gpiod_get(&pdev->dev, NULL, |
66 | open_source ? GPIOD_IN : GPIOD_OUT_LOW); | 66 | open_source ? GPIOD_IN : GPIOD_OUT_LOW); |
67 | if (IS_ERR(gpio_restart->reset_gpio)) { | 67 | if (IS_ERR(gpio_restart->reset_gpio)) { |
68 | dev_err(&pdev->dev, "Could net get reset GPIO\n"); | 68 | dev_err(&pdev->dev, "Could not get reset GPIO\n"); |
69 | return PTR_ERR(gpio_restart->reset_gpio); | 69 | return PTR_ERR(gpio_restart->reset_gpio); |
70 | } | 70 | } |
71 | 71 | ||
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c index 06ff035b57f5..b4076b10b893 100644 --- a/drivers/power/reset/reboot-mode.c +++ b/drivers/power/reset/reboot-mode.c | |||
@@ -190,6 +190,6 @@ void devm_reboot_mode_unregister(struct device *dev, | |||
190 | } | 190 | } |
191 | EXPORT_SYMBOL_GPL(devm_reboot_mode_unregister); | 191 | EXPORT_SYMBOL_GPL(devm_reboot_mode_unregister); |
192 | 192 | ||
193 | MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com"); | 193 | MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>"); |
194 | MODULE_DESCRIPTION("System reboot mode core library"); | 194 | MODULE_DESCRIPTION("System reboot mode core library"); |
195 | MODULE_LICENSE("GPL v2"); | 195 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index 86d88aec94a1..e51d0e72beea 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c | |||
@@ -742,7 +742,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
742 | USB_CH_IP_CUR_LVL_1P5; | 742 | USB_CH_IP_CUR_LVL_1P5; |
743 | break; | 743 | break; |
744 | } | 744 | } |
745 | /* Else, fall through */ | 745 | /* else, fall through */ |
746 | case USB_STAT_HM_IDGND: | 746 | case USB_STAT_HM_IDGND: |
747 | dev_err(di->dev, "USB Type - Charging not allowed\n"); | 747 | dev_err(di->dev, "USB Type - Charging not allowed\n"); |
748 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; | 748 | di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05; |
@@ -3011,7 +3011,6 @@ static int ab8500_charger_usb_get_property(struct power_supply *psy, | |||
3011 | static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | 3011 | static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) |
3012 | { | 3012 | { |
3013 | int ret = 0; | 3013 | int ret = 0; |
3014 | u8 bup_vch_range = 0, vbup33_vrtcn = 0; | ||
3015 | 3014 | ||
3016 | /* Setup maximum charger current and voltage for ABB cut2.0 */ | 3015 | /* Setup maximum charger current and voltage for ABB cut2.0 */ |
3017 | if (!is_ab8500_1p1_or_earlier(di->parent)) { | 3016 | if (!is_ab8500_1p1_or_earlier(di->parent)) { |
@@ -3112,12 +3111,6 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
3112 | goto out; | 3111 | goto out; |
3113 | } | 3112 | } |
3114 | 3113 | ||
3115 | /* Backup battery voltage and current */ | ||
3116 | if (di->bm->bkup_bat_v > BUP_VCH_SEL_3P1V) | ||
3117 | bup_vch_range = BUP_VCH_RANGE; | ||
3118 | if (di->bm->bkup_bat_v == BUP_VCH_SEL_3P3V) | ||
3119 | vbup33_vrtcn = VBUP33_VRTCN; | ||
3120 | |||
3121 | ret = abx500_set_register_interruptible(di->dev, | 3114 | ret = abx500_set_register_interruptible(di->dev, |
3122 | AB8500_RTC, | 3115 | AB8500_RTC, |
3123 | AB8500_RTC_BACKUP_CHG_REG, | 3116 | AB8500_RTC_BACKUP_CHG_REG, |
diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c index 44169dabb705..e1bc4e6e6f30 100644 --- a/drivers/power/supply/axp288_fuel_gauge.c +++ b/drivers/power/supply/axp288_fuel_gauge.c | |||
@@ -674,6 +674,7 @@ intr_failed: | |||
674 | /* | 674 | /* |
675 | * Some devices have no battery (HDMI sticks) and the axp288 battery's | 675 | * Some devices have no battery (HDMI sticks) and the axp288 battery's |
676 | * detection reports one despite it not being there. | 676 | * detection reports one despite it not being there. |
677 | * Please keep this listed sorted alphabetically. | ||
677 | */ | 678 | */ |
678 | static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = { | 679 | static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = { |
679 | { | 680 | { |
@@ -697,6 +698,12 @@ static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = { | |||
697 | }, | 698 | }, |
698 | }, | 699 | }, |
699 | { | 700 | { |
701 | /* ECS EF20EA */ | ||
702 | .matches = { | ||
703 | DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), | ||
704 | }, | ||
705 | }, | ||
706 | { | ||
700 | /* Intel Cherry Trail Compute Stick, Windows version */ | 707 | /* Intel Cherry Trail Compute Stick, Windows version */ |
701 | .matches = { | 708 | .matches = { |
702 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), | 709 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), |
@@ -720,10 +727,11 @@ static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = { | |||
720 | }, | 727 | }, |
721 | }, | 728 | }, |
722 | { | 729 | { |
723 | /* ECS EF20EA */ | 730 | /* Minix Neo Z83-4 mini PC */ |
724 | .matches = { | 731 | .matches = { |
725 | DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), | 732 | DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), |
726 | }, | 733 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), |
734 | } | ||
727 | }, | 735 | }, |
728 | {} | 736 | {} |
729 | }; | 737 | }; |
diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c index d333f2b321b9..9d1ec8d677de 100644 --- a/drivers/power/supply/bq25890_charger.c +++ b/drivers/power/supply/bq25890_charger.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #define BQ25890_IRQ_PIN "bq25890_irq" | 22 | #define BQ25890_IRQ_PIN "bq25890_irq" |
23 | 23 | ||
24 | #define BQ25890_ID 3 | 24 | #define BQ25890_ID 3 |
25 | #define BQ25895_ID 7 | ||
25 | #define BQ25896_ID 0 | 26 | #define BQ25896_ID 0 |
26 | 27 | ||
27 | enum bq25890_fields { | 28 | enum bq25890_fields { |
@@ -171,7 +172,7 @@ static const struct reg_field bq25890_reg_fields[] = { | |||
171 | [F_WD] = REG_FIELD(0x07, 4, 5), | 172 | [F_WD] = REG_FIELD(0x07, 4, 5), |
172 | [F_TMR_EN] = REG_FIELD(0x07, 3, 3), | 173 | [F_TMR_EN] = REG_FIELD(0x07, 3, 3), |
173 | [F_CHG_TMR] = REG_FIELD(0x07, 1, 2), | 174 | [F_CHG_TMR] = REG_FIELD(0x07, 1, 2), |
174 | [F_JEITA_ISET] = REG_FIELD(0x07, 0, 0), | 175 | [F_JEITA_ISET] = REG_FIELD(0x07, 0, 0), // reserved on BQ25895 |
175 | /* REG08 */ | 176 | /* REG08 */ |
176 | [F_BATCMP] = REG_FIELD(0x08, 5, 7), | 177 | [F_BATCMP] = REG_FIELD(0x08, 5, 7), |
177 | [F_VCLAMP] = REG_FIELD(0x08, 2, 4), | 178 | [F_VCLAMP] = REG_FIELD(0x08, 2, 4), |
@@ -180,7 +181,7 @@ static const struct reg_field bq25890_reg_fields[] = { | |||
180 | [F_FORCE_ICO] = REG_FIELD(0x09, 7, 7), | 181 | [F_FORCE_ICO] = REG_FIELD(0x09, 7, 7), |
181 | [F_TMR2X_EN] = REG_FIELD(0x09, 6, 6), | 182 | [F_TMR2X_EN] = REG_FIELD(0x09, 6, 6), |
182 | [F_BATFET_DIS] = REG_FIELD(0x09, 5, 5), | 183 | [F_BATFET_DIS] = REG_FIELD(0x09, 5, 5), |
183 | [F_JEITA_VSET] = REG_FIELD(0x09, 4, 4), | 184 | [F_JEITA_VSET] = REG_FIELD(0x09, 4, 4), // reserved on BQ25895 |
184 | [F_BATFET_DLY] = REG_FIELD(0x09, 3, 3), | 185 | [F_BATFET_DLY] = REG_FIELD(0x09, 3, 3), |
185 | [F_BATFET_RST_EN] = REG_FIELD(0x09, 2, 2), | 186 | [F_BATFET_RST_EN] = REG_FIELD(0x09, 2, 2), |
186 | [F_PUMPX_UP] = REG_FIELD(0x09, 1, 1), | 187 | [F_PUMPX_UP] = REG_FIELD(0x09, 1, 1), |
@@ -188,7 +189,7 @@ static const struct reg_field bq25890_reg_fields[] = { | |||
188 | /* REG0A */ | 189 | /* REG0A */ |
189 | [F_BOOSTV] = REG_FIELD(0x0A, 4, 7), | 190 | [F_BOOSTV] = REG_FIELD(0x0A, 4, 7), |
190 | /* PFM_OTG_DIS 3 on BQ25896 */ | 191 | /* PFM_OTG_DIS 3 on BQ25896 */ |
191 | [F_BOOSTI] = REG_FIELD(0x0A, 0, 2), | 192 | [F_BOOSTI] = REG_FIELD(0x0A, 0, 2), // reserved on BQ25895 |
192 | /* REG0B */ | 193 | /* REG0B */ |
193 | [F_VBUS_STAT] = REG_FIELD(0x0B, 5, 7), | 194 | [F_VBUS_STAT] = REG_FIELD(0x0B, 5, 7), |
194 | [F_CHG_STAT] = REG_FIELD(0x0B, 3, 4), | 195 | [F_CHG_STAT] = REG_FIELD(0x0B, 3, 4), |
@@ -392,6 +393,8 @@ static int bq25890_power_supply_get_property(struct power_supply *psy, | |||
392 | case POWER_SUPPLY_PROP_MODEL_NAME: | 393 | case POWER_SUPPLY_PROP_MODEL_NAME: |
393 | if (bq->chip_id == BQ25890_ID) | 394 | if (bq->chip_id == BQ25890_ID) |
394 | val->strval = "BQ25890"; | 395 | val->strval = "BQ25890"; |
396 | else if (bq->chip_id == BQ25895_ID) | ||
397 | val->strval = "BQ25895"; | ||
395 | else if (bq->chip_id == BQ25896_ID) | 398 | else if (bq->chip_id == BQ25896_ID) |
396 | val->strval = "BQ25896"; | 399 | val->strval = "BQ25896"; |
397 | else | 400 | else |
@@ -862,7 +865,8 @@ static int bq25890_probe(struct i2c_client *client, | |||
862 | return bq->chip_id; | 865 | return bq->chip_id; |
863 | } | 866 | } |
864 | 867 | ||
865 | if ((bq->chip_id != BQ25890_ID) && (bq->chip_id != BQ25896_ID)) { | 868 | if ((bq->chip_id != BQ25890_ID) && (bq->chip_id != BQ25895_ID) |
869 | && (bq->chip_id != BQ25896_ID)) { | ||
866 | dev_err(dev, "Chip with ID=%d, not supported!\n", bq->chip_id); | 870 | dev_err(dev, "Chip with ID=%d, not supported!\n", bq->chip_id); |
867 | return -ENODEV; | 871 | return -ENODEV; |
868 | } | 872 | } |
diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c index cc546bc40a78..74258c7fe17d 100644 --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c | |||
@@ -108,6 +108,9 @@ | |||
108 | #define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe) | 108 | #define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe) |
109 | #define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf) | 109 | #define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf) |
110 | 110 | ||
111 | /* CPCAP_REG_VUSBC register bits needed for VBUS */ | ||
112 | #define CPCAP_BIT_VBUS_SWITCH BIT(0) /* VBUS boost to 5V */ | ||
113 | |||
111 | enum { | 114 | enum { |
112 | CPCAP_CHARGER_IIO_BATTDET, | 115 | CPCAP_CHARGER_IIO_BATTDET, |
113 | CPCAP_CHARGER_IIO_VOLTAGE, | 116 | CPCAP_CHARGER_IIO_VOLTAGE, |
@@ -130,7 +133,8 @@ struct cpcap_charger_ddata { | |||
130 | struct power_supply *usb; | 133 | struct power_supply *usb; |
131 | 134 | ||
132 | struct phy_companion comparator; /* For USB VBUS */ | 135 | struct phy_companion comparator; /* For USB VBUS */ |
133 | bool vbus_enabled; | 136 | unsigned int vbus_enabled:1; |
137 | unsigned int feeding_vbus:1; | ||
134 | atomic_t active; | 138 | atomic_t active; |
135 | 139 | ||
136 | int status; | 140 | int status; |
@@ -325,7 +329,6 @@ static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata) | |||
325 | } | 329 | } |
326 | 330 | ||
327 | /* VBUS control functions for the USB PHY companion */ | 331 | /* VBUS control functions for the USB PHY companion */ |
328 | |||
329 | static void cpcap_charger_vbus_work(struct work_struct *work) | 332 | static void cpcap_charger_vbus_work(struct work_struct *work) |
330 | { | 333 | { |
331 | struct cpcap_charger_ddata *ddata; | 334 | struct cpcap_charger_ddata *ddata; |
@@ -343,6 +346,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work) | |||
343 | return; | 346 | return; |
344 | } | 347 | } |
345 | 348 | ||
349 | ddata->feeding_vbus = true; | ||
346 | cpcap_charger_set_cable_path(ddata, false); | 350 | cpcap_charger_set_cable_path(ddata, false); |
347 | cpcap_charger_set_inductive_path(ddata, false); | 351 | cpcap_charger_set_inductive_path(ddata, false); |
348 | 352 | ||
@@ -350,12 +354,23 @@ static void cpcap_charger_vbus_work(struct work_struct *work) | |||
350 | if (error) | 354 | if (error) |
351 | goto out_err; | 355 | goto out_err; |
352 | 356 | ||
357 | error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC, | ||
358 | CPCAP_BIT_VBUS_SWITCH, | ||
359 | CPCAP_BIT_VBUS_SWITCH); | ||
360 | if (error) | ||
361 | goto out_err; | ||
362 | |||
353 | error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, | 363 | error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, |
354 | CPCAP_REG_CRM_RVRSMODE, | 364 | CPCAP_REG_CRM_RVRSMODE, |
355 | CPCAP_REG_CRM_RVRSMODE); | 365 | CPCAP_REG_CRM_RVRSMODE); |
356 | if (error) | 366 | if (error) |
357 | goto out_err; | 367 | goto out_err; |
358 | } else { | 368 | } else { |
369 | error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC, | ||
370 | CPCAP_BIT_VBUS_SWITCH, 0); | ||
371 | if (error) | ||
372 | goto out_err; | ||
373 | |||
359 | error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, | 374 | error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM, |
360 | CPCAP_REG_CRM_RVRSMODE, 0); | 375 | CPCAP_REG_CRM_RVRSMODE, 0); |
361 | if (error) | 376 | if (error) |
@@ -363,6 +378,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work) | |||
363 | 378 | ||
364 | cpcap_charger_set_cable_path(ddata, true); | 379 | cpcap_charger_set_cable_path(ddata, true); |
365 | cpcap_charger_set_inductive_path(ddata, true); | 380 | cpcap_charger_set_inductive_path(ddata, true); |
381 | ddata->feeding_vbus = false; | ||
366 | } | 382 | } |
367 | 383 | ||
368 | return; | 384 | return; |
@@ -431,7 +447,8 @@ static void cpcap_usb_detect(struct work_struct *work) | |||
431 | if (error) | 447 | if (error) |
432 | return; | 448 | return; |
433 | 449 | ||
434 | if (cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) { | 450 | if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) && |
451 | s.chrgcurr1) { | ||
435 | int max_current; | 452 | int max_current; |
436 | 453 | ||
437 | if (cpcap_charger_battery_found(ddata)) | 454 | if (cpcap_charger_battery_found(ddata)) |
diff --git a/drivers/power/supply/isp1704_charger.c b/drivers/power/supply/isp1704_charger.c index b48cb7aba97b..4812ac1ff2df 100644 --- a/drivers/power/supply/isp1704_charger.c +++ b/drivers/power/supply/isp1704_charger.c | |||
@@ -342,7 +342,7 @@ static inline int isp1704_test_ulpi(struct isp1704_charger *isp) | |||
342 | int vendor; | 342 | int vendor; |
343 | int product; | 343 | int product; |
344 | int i; | 344 | int i; |
345 | int ret = -ENODEV; | 345 | int ret; |
346 | 346 | ||
347 | /* Test ULPI interface */ | 347 | /* Test ULPI interface */ |
348 | ret = isp1704_write(isp, ULPI_SCRATCH, 0xaa); | 348 | ret = isp1704_write(isp, ULPI_SCRATCH, 0xaa); |
diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index 64f3358eaa3c..0dfad2cf13fe 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c | |||
@@ -511,7 +511,7 @@ static inline void max17042_override_por(struct regmap *map, | |||
511 | regmap_write(map, reg, value); | 511 | regmap_write(map, reg, value); |
512 | } | 512 | } |
513 | 513 | ||
514 | static inline void max10742_unlock_model(struct max17042_chip *chip) | 514 | static inline void max17042_unlock_model(struct max17042_chip *chip) |
515 | { | 515 | { |
516 | struct regmap *map = chip->regmap; | 516 | struct regmap *map = chip->regmap; |
517 | 517 | ||
@@ -519,7 +519,7 @@ static inline void max10742_unlock_model(struct max17042_chip *chip) | |||
519 | regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2); | 519 | regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2); |
520 | } | 520 | } |
521 | 521 | ||
522 | static inline void max10742_lock_model(struct max17042_chip *chip) | 522 | static inline void max17042_lock_model(struct max17042_chip *chip) |
523 | { | 523 | { |
524 | struct regmap *map = chip->regmap; | 524 | struct regmap *map = chip->regmap; |
525 | 525 | ||
@@ -577,7 +577,7 @@ static int max17042_init_model(struct max17042_chip *chip) | |||
577 | if (!temp_data) | 577 | if (!temp_data) |
578 | return -ENOMEM; | 578 | return -ENOMEM; |
579 | 579 | ||
580 | max10742_unlock_model(chip); | 580 | max17042_unlock_model(chip); |
581 | max17042_write_model_data(chip, MAX17042_MODELChrTbl, | 581 | max17042_write_model_data(chip, MAX17042_MODELChrTbl, |
582 | table_size); | 582 | table_size); |
583 | max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data, | 583 | max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data, |
@@ -589,7 +589,7 @@ static int max17042_init_model(struct max17042_chip *chip) | |||
589 | temp_data, | 589 | temp_data, |
590 | table_size); | 590 | table_size); |
591 | 591 | ||
592 | max10742_lock_model(chip); | 592 | max17042_lock_model(chip); |
593 | kfree(temp_data); | 593 | kfree(temp_data); |
594 | 594 | ||
595 | return ret; | 595 | return ret; |
diff --git a/drivers/power/supply/max77650-charger.c b/drivers/power/supply/max77650-charger.c index e34714cb05ec..5f9477c5cf5a 100644 --- a/drivers/power/supply/max77650-charger.c +++ b/drivers/power/supply/max77650-charger.c | |||
@@ -366,3 +366,4 @@ module_platform_driver(max77650_charger_driver); | |||
366 | MODULE_DESCRIPTION("MAXIM 77650/77651 charger driver"); | 366 | MODULE_DESCRIPTION("MAXIM 77650/77651 charger driver"); |
367 | MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>"); | 367 | MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>"); |
368 | MODULE_LICENSE("GPL v2"); | 368 | MODULE_LICENSE("GPL v2"); |
369 | MODULE_ALIAS("platform:max77650-charger"); | ||
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 82e84801264c..5c36c430ce8b 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c | |||
@@ -1051,14 +1051,14 @@ __power_supply_register(struct device *parent, | |||
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | spin_lock_init(&psy->changed_lock); | 1053 | spin_lock_init(&psy->changed_lock); |
1054 | rc = device_init_wakeup(dev, ws); | ||
1055 | if (rc) | ||
1056 | goto wakeup_init_failed; | ||
1057 | |||
1058 | rc = device_add(dev); | 1054 | rc = device_add(dev); |
1059 | if (rc) | 1055 | if (rc) |
1060 | goto device_add_failed; | 1056 | goto device_add_failed; |
1061 | 1057 | ||
1058 | rc = device_init_wakeup(dev, ws); | ||
1059 | if (rc) | ||
1060 | goto wakeup_init_failed; | ||
1061 | |||
1062 | rc = psy_register_thermal(psy); | 1062 | rc = psy_register_thermal(psy); |
1063 | if (rc) | 1063 | if (rc) |
1064 | goto register_thermal_failed; | 1064 | goto register_thermal_failed; |
@@ -1101,8 +1101,8 @@ register_cooler_failed: | |||
1101 | psy_unregister_thermal(psy); | 1101 | psy_unregister_thermal(psy); |
1102 | register_thermal_failed: | 1102 | register_thermal_failed: |
1103 | device_del(dev); | 1103 | device_del(dev); |
1104 | device_add_failed: | ||
1105 | wakeup_init_failed: | 1104 | wakeup_init_failed: |
1105 | device_add_failed: | ||
1106 | check_supplies_failed: | 1106 | check_supplies_failed: |
1107 | dev_set_name_failed: | 1107 | dev_set_name_failed: |
1108 | put_device(dev); | 1108 | put_device(dev); |
diff --git a/drivers/power/supply/power_supply_hwmon.c b/drivers/power/supply/power_supply_hwmon.c index 51fe60440d12..75cf861ba492 100644 --- a/drivers/power/supply/power_supply_hwmon.c +++ b/drivers/power/supply/power_supply_hwmon.c | |||
@@ -284,6 +284,7 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy) | |||
284 | struct device *dev = &psy->dev; | 284 | struct device *dev = &psy->dev; |
285 | struct device *hwmon; | 285 | struct device *hwmon; |
286 | int ret, i; | 286 | int ret, i; |
287 | const char *name; | ||
287 | 288 | ||
288 | if (!devres_open_group(dev, power_supply_add_hwmon_sysfs, | 289 | if (!devres_open_group(dev, power_supply_add_hwmon_sysfs, |
289 | GFP_KERNEL)) | 290 | GFP_KERNEL)) |
@@ -334,7 +335,19 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy) | |||
334 | } | 335 | } |
335 | } | 336 | } |
336 | 337 | ||
337 | hwmon = devm_hwmon_device_register_with_info(dev, psy->desc->name, | 338 | name = psy->desc->name; |
339 | if (strchr(name, '-')) { | ||
340 | char *new_name; | ||
341 | |||
342 | new_name = devm_kstrdup(dev, name, GFP_KERNEL); | ||
343 | if (!new_name) { | ||
344 | ret = -ENOMEM; | ||
345 | goto error; | ||
346 | } | ||
347 | strreplace(new_name, '-', '_'); | ||
348 | name = new_name; | ||
349 | } | ||
350 | hwmon = devm_hwmon_device_register_with_info(dev, name, | ||
338 | psyhw, | 351 | psyhw, |
339 | &power_supply_hwmon_chip_info, | 352 | &power_supply_hwmon_chip_info, |
340 | NULL); | 353 | NULL); |
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c index 048d205d7074..f8d74e9f7931 100644 --- a/drivers/power/supply/sbs-battery.c +++ b/drivers/power/supply/sbs-battery.c | |||
@@ -314,17 +314,22 @@ static int sbs_get_battery_presence_and_health( | |||
314 | { | 314 | { |
315 | int ret; | 315 | int ret; |
316 | 316 | ||
317 | if (psp == POWER_SUPPLY_PROP_PRESENT) { | 317 | /* Dummy command; if it succeeds, battery is present. */ |
318 | /* Dummy command; if it succeeds, battery is present. */ | 318 | ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr); |
319 | ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr); | 319 | |
320 | if (ret < 0) | 320 | if (ret < 0) { /* battery not present*/ |
321 | val->intval = 0; /* battery disconnected */ | 321 | if (psp == POWER_SUPPLY_PROP_PRESENT) { |
322 | else | 322 | val->intval = 0; |
323 | val->intval = 1; /* battery present */ | 323 | return 0; |
324 | } else { /* POWER_SUPPLY_PROP_HEALTH */ | 324 | } |
325 | return ret; | ||
326 | } | ||
327 | |||
328 | if (psp == POWER_SUPPLY_PROP_PRESENT) | ||
329 | val->intval = 1; /* battery present */ | ||
330 | else /* POWER_SUPPLY_PROP_HEALTH */ | ||
325 | /* SBS spec doesn't have a general health command. */ | 331 | /* SBS spec doesn't have a general health command. */ |
326 | val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; | 332 | val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; |
327 | } | ||
328 | 333 | ||
329 | return 0; | 334 | return 0; |
330 | } | 335 | } |
@@ -620,12 +625,14 @@ static int sbs_get_property(struct power_supply *psy, | |||
620 | switch (psp) { | 625 | switch (psp) { |
621 | case POWER_SUPPLY_PROP_PRESENT: | 626 | case POWER_SUPPLY_PROP_PRESENT: |
622 | case POWER_SUPPLY_PROP_HEALTH: | 627 | case POWER_SUPPLY_PROP_HEALTH: |
623 | if (client->flags & SBS_FLAGS_TI_BQ20Z75) | 628 | if (chip->flags & SBS_FLAGS_TI_BQ20Z75) |
624 | ret = sbs_get_ti_battery_presence_and_health(client, | 629 | ret = sbs_get_ti_battery_presence_and_health(client, |
625 | psp, val); | 630 | psp, val); |
626 | else | 631 | else |
627 | ret = sbs_get_battery_presence_and_health(client, psp, | 632 | ret = sbs_get_battery_presence_and_health(client, psp, |
628 | val); | 633 | val); |
634 | |||
635 | /* this can only be true if no gpio is used */ | ||
629 | if (psp == POWER_SUPPLY_PROP_PRESENT) | 636 | if (psp == POWER_SUPPLY_PROP_PRESENT) |
630 | return 0; | 637 | return 0; |
631 | break; | 638 | break; |
diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c index 24895cc3b41e..bc8f5bda5762 100644 --- a/drivers/power/supply/sc27xx_fuel_gauge.c +++ b/drivers/power/supply/sc27xx_fuel_gauge.c | |||
@@ -109,6 +109,9 @@ struct sc27xx_fgu_data { | |||
109 | }; | 109 | }; |
110 | 110 | ||
111 | static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity); | 111 | static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity); |
112 | static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data, | ||
113 | int cap, bool int_mode); | ||
114 | static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap); | ||
112 | 115 | ||
113 | static const char * const sc27xx_charger_supply_name[] = { | 116 | static const char * const sc27xx_charger_supply_name[] = { |
114 | "sc2731_charger", | 117 | "sc2731_charger", |
@@ -326,8 +329,6 @@ static int sc27xx_fgu_set_clbcnt(struct sc27xx_fgu_data *data, int clbcnt) | |||
326 | { | 329 | { |
327 | int ret; | 330 | int ret; |
328 | 331 | ||
329 | clbcnt *= SC27XX_FGU_SAMPLE_HZ; | ||
330 | |||
331 | ret = regmap_update_bits(data->regmap, | 332 | ret = regmap_update_bits(data->regmap, |
332 | data->base + SC27XX_FGU_CLBCNT_SETL, | 333 | data->base + SC27XX_FGU_CLBCNT_SETL, |
333 | SC27XX_FGU_CLBCNT_MASK, clbcnt); | 334 | SC27XX_FGU_CLBCNT_MASK, clbcnt); |
@@ -362,7 +363,6 @@ static int sc27xx_fgu_get_clbcnt(struct sc27xx_fgu_data *data, int *clb_cnt) | |||
362 | 363 | ||
363 | *clb_cnt = ccl & SC27XX_FGU_CLBCNT_MASK; | 364 | *clb_cnt = ccl & SC27XX_FGU_CLBCNT_MASK; |
364 | *clb_cnt |= (cch & SC27XX_FGU_CLBCNT_MASK) << SC27XX_FGU_CLBCNT_SHIFT; | 365 | *clb_cnt |= (cch & SC27XX_FGU_CLBCNT_MASK) << SC27XX_FGU_CLBCNT_SHIFT; |
365 | *clb_cnt /= SC27XX_FGU_SAMPLE_HZ; | ||
366 | 366 | ||
367 | return 0; | 367 | return 0; |
368 | } | 368 | } |
@@ -380,10 +380,10 @@ static int sc27xx_fgu_get_capacity(struct sc27xx_fgu_data *data, int *cap) | |||
380 | 380 | ||
381 | /* | 381 | /* |
382 | * Convert coulomb counter to delta capacity (mAh), and set multiplier | 382 | * Convert coulomb counter to delta capacity (mAh), and set multiplier |
383 | * as 100 to improve the precision. | 383 | * as 10 to improve the precision. |
384 | */ | 384 | */ |
385 | temp = DIV_ROUND_CLOSEST(delta_clbcnt, 360); | 385 | temp = DIV_ROUND_CLOSEST(delta_clbcnt * 10, 36 * SC27XX_FGU_SAMPLE_HZ); |
386 | temp = sc27xx_fgu_adc_to_current(data, temp); | 386 | temp = sc27xx_fgu_adc_to_current(data, temp / 1000); |
387 | 387 | ||
388 | /* | 388 | /* |
389 | * Convert to capacity percent of the battery total capacity, | 389 | * Convert to capacity percent of the battery total capacity, |
@@ -392,6 +392,9 @@ static int sc27xx_fgu_get_capacity(struct sc27xx_fgu_data *data, int *cap) | |||
392 | delta_cap = DIV_ROUND_CLOSEST(temp * 100, data->total_cap); | 392 | delta_cap = DIV_ROUND_CLOSEST(temp * 100, data->total_cap); |
393 | *cap = delta_cap + data->init_cap; | 393 | *cap = delta_cap + data->init_cap; |
394 | 394 | ||
395 | /* Calibrate the battery capacity in a normal range. */ | ||
396 | sc27xx_fgu_capacity_calibration(data, *cap, false); | ||
397 | |||
395 | return 0; | 398 | return 0; |
396 | } | 399 | } |
397 | 400 | ||
@@ -587,6 +590,10 @@ static int sc27xx_fgu_get_property(struct power_supply *psy, | |||
587 | val->intval = value * 1000; | 590 | val->intval = value * 1000; |
588 | break; | 591 | break; |
589 | 592 | ||
593 | case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: | ||
594 | val->intval = data->total_cap * 1000; | ||
595 | break; | ||
596 | |||
590 | default: | 597 | default: |
591 | ret = -EINVAL; | 598 | ret = -EINVAL; |
592 | break; | 599 | break; |
@@ -604,17 +611,25 @@ static int sc27xx_fgu_set_property(struct power_supply *psy, | |||
604 | struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); | 611 | struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); |
605 | int ret; | 612 | int ret; |
606 | 613 | ||
607 | if (psp != POWER_SUPPLY_PROP_CAPACITY) | ||
608 | return -EINVAL; | ||
609 | |||
610 | mutex_lock(&data->lock); | 614 | mutex_lock(&data->lock); |
611 | 615 | ||
612 | ret = sc27xx_fgu_save_last_cap(data, val->intval); | 616 | switch (psp) { |
617 | case POWER_SUPPLY_PROP_CAPACITY: | ||
618 | ret = sc27xx_fgu_save_last_cap(data, val->intval); | ||
619 | if (ret < 0) | ||
620 | dev_err(data->dev, "failed to save battery capacity\n"); | ||
621 | break; | ||
613 | 622 | ||
614 | mutex_unlock(&data->lock); | 623 | case POWER_SUPPLY_PROP_CALIBRATE: |
624 | sc27xx_fgu_adjust_cap(data, val->intval); | ||
625 | ret = 0; | ||
626 | break; | ||
615 | 627 | ||
616 | if (ret < 0) | 628 | default: |
617 | dev_err(data->dev, "failed to save battery capacity\n"); | 629 | ret = -EINVAL; |
630 | } | ||
631 | |||
632 | mutex_unlock(&data->lock); | ||
618 | 633 | ||
619 | return ret; | 634 | return ret; |
620 | } | 635 | } |
@@ -629,7 +644,8 @@ static void sc27xx_fgu_external_power_changed(struct power_supply *psy) | |||
629 | static int sc27xx_fgu_property_is_writeable(struct power_supply *psy, | 644 | static int sc27xx_fgu_property_is_writeable(struct power_supply *psy, |
630 | enum power_supply_property psp) | 645 | enum power_supply_property psp) |
631 | { | 646 | { |
632 | return psp == POWER_SUPPLY_PROP_CAPACITY; | 647 | return psp == POWER_SUPPLY_PROP_CAPACITY || |
648 | psp == POWER_SUPPLY_PROP_CALIBRATE; | ||
633 | } | 649 | } |
634 | 650 | ||
635 | static enum power_supply_property sc27xx_fgu_props[] = { | 651 | static enum power_supply_property sc27xx_fgu_props[] = { |
@@ -644,6 +660,8 @@ static enum power_supply_property sc27xx_fgu_props[] = { | |||
644 | POWER_SUPPLY_PROP_CURRENT_NOW, | 660 | POWER_SUPPLY_PROP_CURRENT_NOW, |
645 | POWER_SUPPLY_PROP_CURRENT_AVG, | 661 | POWER_SUPPLY_PROP_CURRENT_AVG, |
646 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, | 662 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, |
663 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | ||
664 | POWER_SUPPLY_PROP_CALIBRATE, | ||
647 | }; | 665 | }; |
648 | 666 | ||
649 | static const struct power_supply_desc sc27xx_fgu_desc = { | 667 | static const struct power_supply_desc sc27xx_fgu_desc = { |
@@ -659,50 +677,62 @@ static const struct power_supply_desc sc27xx_fgu_desc = { | |||
659 | 677 | ||
660 | static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap) | 678 | static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap) |
661 | { | 679 | { |
680 | int ret; | ||
681 | |||
662 | data->init_cap = cap; | 682 | data->init_cap = cap; |
663 | data->init_clbcnt = sc27xx_fgu_cap_to_clbcnt(data, data->init_cap); | 683 | ret = sc27xx_fgu_get_clbcnt(data, &data->init_clbcnt); |
684 | if (ret) | ||
685 | dev_err(data->dev, "failed to get init coulomb counter\n"); | ||
664 | } | 686 | } |
665 | 687 | ||
666 | static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id) | 688 | static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data, |
689 | int cap, bool int_mode) | ||
667 | { | 690 | { |
668 | struct sc27xx_fgu_data *data = dev_id; | 691 | int ret, ocv, chg_sts, adc; |
669 | int ret, cap, ocv, adc; | ||
670 | u32 status; | ||
671 | 692 | ||
672 | mutex_lock(&data->lock); | 693 | ret = sc27xx_fgu_get_vbat_ocv(data, &ocv); |
673 | 694 | if (ret) { | |
674 | ret = regmap_read(data->regmap, data->base + SC27XX_FGU_INT_STS, | 695 | dev_err(data->dev, "get battery ocv error.\n"); |
675 | &status); | 696 | return; |
676 | if (ret) | 697 | } |
677 | goto out; | ||
678 | 698 | ||
679 | ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_CLR, | 699 | ret = sc27xx_fgu_get_status(data, &chg_sts); |
680 | status, status); | 700 | if (ret) { |
681 | if (ret) | 701 | dev_err(data->dev, "get charger status error.\n"); |
682 | goto out; | 702 | return; |
703 | } | ||
683 | 704 | ||
684 | /* | 705 | /* |
685 | * When low overload voltage interrupt happens, we should calibrate the | 706 | * If we are in charging mode, then we do not need to calibrate the |
686 | * battery capacity in lower voltage stage. | 707 | * lower capacity. |
687 | */ | 708 | */ |
688 | if (!(status & SC27XX_FGU_LOW_OVERLOAD_INT)) | 709 | if (chg_sts == POWER_SUPPLY_STATUS_CHARGING) |
689 | goto out; | 710 | return; |
690 | |||
691 | ret = sc27xx_fgu_get_capacity(data, &cap); | ||
692 | if (ret) | ||
693 | goto out; | ||
694 | 711 | ||
695 | ret = sc27xx_fgu_get_vbat_ocv(data, &ocv); | 712 | if ((ocv > data->cap_table[0].ocv && cap < 100) || cap > 100) { |
696 | if (ret) | 713 | /* |
697 | goto out; | 714 | * If current OCV value is larger than the max OCV value in |
698 | 715 | * OCV table, or the current capacity is larger than 100, | |
699 | /* | 716 | * we should force the inititial capacity to 100. |
700 | * If current OCV value is less than the minimum OCV value in OCV table, | 717 | */ |
701 | * which means now battery capacity is 0%, and we should adjust the | 718 | sc27xx_fgu_adjust_cap(data, 100); |
702 | * inititial capacity to 0. | 719 | } else if (ocv <= data->cap_table[data->table_len - 1].ocv) { |
703 | */ | 720 | /* |
704 | if (ocv <= data->cap_table[data->table_len - 1].ocv) { | 721 | * If current OCV value is leass than the minimum OCV value in |
722 | * OCV table, we should force the inititial capacity to 0. | ||
723 | */ | ||
705 | sc27xx_fgu_adjust_cap(data, 0); | 724 | sc27xx_fgu_adjust_cap(data, 0); |
725 | } else if ((ocv > data->cap_table[data->table_len - 1].ocv && cap <= 0) || | ||
726 | (ocv > data->min_volt && cap <= data->alarm_cap)) { | ||
727 | /* | ||
728 | * If current OCV value is not matchable with current capacity, | ||
729 | * we should re-calculate current capacity by looking up the | ||
730 | * OCV table. | ||
731 | */ | ||
732 | int cur_cap = power_supply_ocv2cap_simple(data->cap_table, | ||
733 | data->table_len, ocv); | ||
734 | |||
735 | sc27xx_fgu_adjust_cap(data, cur_cap); | ||
706 | } else if (ocv <= data->min_volt) { | 736 | } else if (ocv <= data->min_volt) { |
707 | /* | 737 | /* |
708 | * If current OCV value is less than the low alarm voltage, but | 738 | * If current OCV value is less than the low alarm voltage, but |
@@ -711,7 +741,7 @@ static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id) | |||
711 | */ | 741 | */ |
712 | if (cap > data->alarm_cap) { | 742 | if (cap > data->alarm_cap) { |
713 | sc27xx_fgu_adjust_cap(data, data->alarm_cap); | 743 | sc27xx_fgu_adjust_cap(data, data->alarm_cap); |
714 | } else if (cap <= 0) { | 744 | } else { |
715 | int cur_cap; | 745 | int cur_cap; |
716 | 746 | ||
717 | /* | 747 | /* |
@@ -726,15 +756,55 @@ static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id) | |||
726 | sc27xx_fgu_adjust_cap(data, cur_cap); | 756 | sc27xx_fgu_adjust_cap(data, cur_cap); |
727 | } | 757 | } |
728 | 758 | ||
759 | if (!int_mode) | ||
760 | return; | ||
761 | |||
729 | /* | 762 | /* |
730 | * After adjusting the battery capacity, we should set the | 763 | * After adjusting the battery capacity, we should set the |
731 | * lowest alarm voltage instead. | 764 | * lowest alarm voltage instead. |
732 | */ | 765 | */ |
733 | data->min_volt = data->cap_table[data->table_len - 1].ocv; | 766 | data->min_volt = data->cap_table[data->table_len - 1].ocv; |
767 | data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table, | ||
768 | data->table_len, | ||
769 | data->min_volt); | ||
770 | |||
734 | adc = sc27xx_fgu_voltage_to_adc(data, data->min_volt / 1000); | 771 | adc = sc27xx_fgu_voltage_to_adc(data, data->min_volt / 1000); |
735 | regmap_update_bits(data->regmap, data->base + SC27XX_FGU_LOW_OVERLOAD, | 772 | regmap_update_bits(data->regmap, |
773 | data->base + SC27XX_FGU_LOW_OVERLOAD, | ||
736 | SC27XX_FGU_LOW_OVERLOAD_MASK, adc); | 774 | SC27XX_FGU_LOW_OVERLOAD_MASK, adc); |
737 | } | 775 | } |
776 | } | ||
777 | |||
778 | static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id) | ||
779 | { | ||
780 | struct sc27xx_fgu_data *data = dev_id; | ||
781 | int ret, cap; | ||
782 | u32 status; | ||
783 | |||
784 | mutex_lock(&data->lock); | ||
785 | |||
786 | ret = regmap_read(data->regmap, data->base + SC27XX_FGU_INT_STS, | ||
787 | &status); | ||
788 | if (ret) | ||
789 | goto out; | ||
790 | |||
791 | ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_CLR, | ||
792 | status, status); | ||
793 | if (ret) | ||
794 | goto out; | ||
795 | |||
796 | /* | ||
797 | * When low overload voltage interrupt happens, we should calibrate the | ||
798 | * battery capacity in lower voltage stage. | ||
799 | */ | ||
800 | if (!(status & SC27XX_FGU_LOW_OVERLOAD_INT)) | ||
801 | goto out; | ||
802 | |||
803 | ret = sc27xx_fgu_get_capacity(data, &cap); | ||
804 | if (ret) | ||
805 | goto out; | ||
806 | |||
807 | sc27xx_fgu_capacity_calibration(data, cap, true); | ||
738 | 808 | ||
739 | out: | 809 | out: |
740 | mutex_unlock(&data->lock); | 810 | mutex_unlock(&data->lock); |
@@ -785,7 +855,7 @@ static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity) | |||
785 | * Convert current capacity (mAh) to coulomb counter according to the | 855 | * Convert current capacity (mAh) to coulomb counter according to the |
786 | * formula: 1 mAh =3.6 coulomb. | 856 | * formula: 1 mAh =3.6 coulomb. |
787 | */ | 857 | */ |
788 | return DIV_ROUND_CLOSEST(cur_cap * 36 * data->cur_1000ma_adc, 10); | 858 | return DIV_ROUND_CLOSEST(cur_cap * 36 * data->cur_1000ma_adc * SC27XX_FGU_SAMPLE_HZ, 10); |
789 | } | 859 | } |
790 | 860 | ||
791 | static int sc27xx_fgu_calibration(struct sc27xx_fgu_data *data) | 861 | static int sc27xx_fgu_calibration(struct sc27xx_fgu_data *data) |
@@ -856,6 +926,8 @@ static int sc27xx_fgu_hw_init(struct sc27xx_fgu_data *data) | |||
856 | data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table, | 926 | data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table, |
857 | data->table_len, | 927 | data->table_len, |
858 | data->min_volt); | 928 | data->min_volt); |
929 | if (!data->alarm_cap) | ||
930 | data->alarm_cap += 1; | ||
859 | 931 | ||
860 | power_supply_put_battery_info(data->battery, &info); | 932 | power_supply_put_battery_info(data->battery, &info); |
861 | 933 | ||
@@ -957,81 +1029,81 @@ disable_fgu: | |||
957 | 1029 | ||
958 | static int sc27xx_fgu_probe(struct platform_device *pdev) | 1030 | static int sc27xx_fgu_probe(struct platform_device *pdev) |
959 | { | 1031 | { |
960 | struct device_node *np = pdev->dev.of_node; | 1032 | struct device *dev = &pdev->dev; |
1033 | struct device_node *np = dev->of_node; | ||
961 | struct power_supply_config fgu_cfg = { }; | 1034 | struct power_supply_config fgu_cfg = { }; |
962 | struct sc27xx_fgu_data *data; | 1035 | struct sc27xx_fgu_data *data; |
963 | int ret, irq; | 1036 | int ret, irq; |
964 | 1037 | ||
965 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 1038 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); |
966 | if (!data) | 1039 | if (!data) |
967 | return -ENOMEM; | 1040 | return -ENOMEM; |
968 | 1041 | ||
969 | data->regmap = dev_get_regmap(pdev->dev.parent, NULL); | 1042 | data->regmap = dev_get_regmap(dev->parent, NULL); |
970 | if (!data->regmap) { | 1043 | if (!data->regmap) { |
971 | dev_err(&pdev->dev, "failed to get regmap\n"); | 1044 | dev_err(dev, "failed to get regmap\n"); |
972 | return -ENODEV; | 1045 | return -ENODEV; |
973 | } | 1046 | } |
974 | 1047 | ||
975 | ret = device_property_read_u32(&pdev->dev, "reg", &data->base); | 1048 | ret = device_property_read_u32(dev, "reg", &data->base); |
976 | if (ret) { | 1049 | if (ret) { |
977 | dev_err(&pdev->dev, "failed to get fgu address\n"); | 1050 | dev_err(dev, "failed to get fgu address\n"); |
978 | return ret; | 1051 | return ret; |
979 | } | 1052 | } |
980 | 1053 | ||
981 | data->channel = devm_iio_channel_get(&pdev->dev, "bat-temp"); | 1054 | data->channel = devm_iio_channel_get(dev, "bat-temp"); |
982 | if (IS_ERR(data->channel)) { | 1055 | if (IS_ERR(data->channel)) { |
983 | dev_err(&pdev->dev, "failed to get IIO channel\n"); | 1056 | dev_err(dev, "failed to get IIO channel\n"); |
984 | return PTR_ERR(data->channel); | 1057 | return PTR_ERR(data->channel); |
985 | } | 1058 | } |
986 | 1059 | ||
987 | data->charge_chan = devm_iio_channel_get(&pdev->dev, "charge-vol"); | 1060 | data->charge_chan = devm_iio_channel_get(dev, "charge-vol"); |
988 | if (IS_ERR(data->charge_chan)) { | 1061 | if (IS_ERR(data->charge_chan)) { |
989 | dev_err(&pdev->dev, "failed to get charge IIO channel\n"); | 1062 | dev_err(dev, "failed to get charge IIO channel\n"); |
990 | return PTR_ERR(data->charge_chan); | 1063 | return PTR_ERR(data->charge_chan); |
991 | } | 1064 | } |
992 | 1065 | ||
993 | data->gpiod = devm_gpiod_get(&pdev->dev, "bat-detect", GPIOD_IN); | 1066 | data->gpiod = devm_gpiod_get(dev, "bat-detect", GPIOD_IN); |
994 | if (IS_ERR(data->gpiod)) { | 1067 | if (IS_ERR(data->gpiod)) { |
995 | dev_err(&pdev->dev, "failed to get battery detection GPIO\n"); | 1068 | dev_err(dev, "failed to get battery detection GPIO\n"); |
996 | return PTR_ERR(data->gpiod); | 1069 | return PTR_ERR(data->gpiod); |
997 | } | 1070 | } |
998 | 1071 | ||
999 | ret = gpiod_get_value_cansleep(data->gpiod); | 1072 | ret = gpiod_get_value_cansleep(data->gpiod); |
1000 | if (ret < 0) { | 1073 | if (ret < 0) { |
1001 | dev_err(&pdev->dev, "failed to get gpio state\n"); | 1074 | dev_err(dev, "failed to get gpio state\n"); |
1002 | return ret; | 1075 | return ret; |
1003 | } | 1076 | } |
1004 | 1077 | ||
1005 | data->bat_present = !!ret; | 1078 | data->bat_present = !!ret; |
1006 | mutex_init(&data->lock); | 1079 | mutex_init(&data->lock); |
1007 | data->dev = &pdev->dev; | 1080 | data->dev = dev; |
1008 | platform_set_drvdata(pdev, data); | 1081 | platform_set_drvdata(pdev, data); |
1009 | 1082 | ||
1010 | fgu_cfg.drv_data = data; | 1083 | fgu_cfg.drv_data = data; |
1011 | fgu_cfg.of_node = np; | 1084 | fgu_cfg.of_node = np; |
1012 | data->battery = devm_power_supply_register(&pdev->dev, &sc27xx_fgu_desc, | 1085 | data->battery = devm_power_supply_register(dev, &sc27xx_fgu_desc, |
1013 | &fgu_cfg); | 1086 | &fgu_cfg); |
1014 | if (IS_ERR(data->battery)) { | 1087 | if (IS_ERR(data->battery)) { |
1015 | dev_err(&pdev->dev, "failed to register power supply\n"); | 1088 | dev_err(dev, "failed to register power supply\n"); |
1016 | return PTR_ERR(data->battery); | 1089 | return PTR_ERR(data->battery); |
1017 | } | 1090 | } |
1018 | 1091 | ||
1019 | ret = sc27xx_fgu_hw_init(data); | 1092 | ret = sc27xx_fgu_hw_init(data); |
1020 | if (ret) { | 1093 | if (ret) { |
1021 | dev_err(&pdev->dev, "failed to initialize fgu hardware\n"); | 1094 | dev_err(dev, "failed to initialize fgu hardware\n"); |
1022 | return ret; | 1095 | return ret; |
1023 | } | 1096 | } |
1024 | 1097 | ||
1025 | ret = devm_add_action(&pdev->dev, sc27xx_fgu_disable, data); | 1098 | ret = devm_add_action_or_reset(dev, sc27xx_fgu_disable, data); |
1026 | if (ret) { | 1099 | if (ret) { |
1027 | sc27xx_fgu_disable(data); | 1100 | dev_err(dev, "failed to add fgu disable action\n"); |
1028 | dev_err(&pdev->dev, "failed to add fgu disable action\n"); | ||
1029 | return ret; | 1101 | return ret; |
1030 | } | 1102 | } |
1031 | 1103 | ||
1032 | irq = platform_get_irq(pdev, 0); | 1104 | irq = platform_get_irq(pdev, 0); |
1033 | if (irq < 0) { | 1105 | if (irq < 0) { |
1034 | dev_err(&pdev->dev, "no irq resource specified\n"); | 1106 | dev_err(dev, "no irq resource specified\n"); |
1035 | return irq; | 1107 | return irq; |
1036 | } | 1108 | } |
1037 | 1109 | ||
@@ -1046,17 +1118,17 @@ static int sc27xx_fgu_probe(struct platform_device *pdev) | |||
1046 | 1118 | ||
1047 | irq = gpiod_to_irq(data->gpiod); | 1119 | irq = gpiod_to_irq(data->gpiod); |
1048 | if (irq < 0) { | 1120 | if (irq < 0) { |
1049 | dev_err(&pdev->dev, "failed to translate GPIO to IRQ\n"); | 1121 | dev_err(dev, "failed to translate GPIO to IRQ\n"); |
1050 | return irq; | 1122 | return irq; |
1051 | } | 1123 | } |
1052 | 1124 | ||
1053 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 1125 | ret = devm_request_threaded_irq(dev, irq, NULL, |
1054 | sc27xx_fgu_bat_detection, | 1126 | sc27xx_fgu_bat_detection, |
1055 | IRQF_ONESHOT | IRQF_TRIGGER_RISING | | 1127 | IRQF_ONESHOT | IRQF_TRIGGER_RISING | |
1056 | IRQF_TRIGGER_FALLING, | 1128 | IRQF_TRIGGER_FALLING, |
1057 | pdev->name, data); | 1129 | pdev->name, data); |
1058 | if (ret) { | 1130 | if (ret) { |
1059 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 1131 | dev_err(dev, "failed to request IRQ\n"); |
1060 | return ret; | 1132 | return ret; |
1061 | } | 1133 | } |
1062 | 1134 | ||
@@ -1093,7 +1165,8 @@ static int sc27xx_fgu_suspend(struct device *dev) | |||
1093 | * If we are charging, then no need to enable the FGU interrupts to | 1165 | * If we are charging, then no need to enable the FGU interrupts to |
1094 | * adjust the battery capacity. | 1166 | * adjust the battery capacity. |
1095 | */ | 1167 | */ |
1096 | if (status != POWER_SUPPLY_STATUS_NOT_CHARGING) | 1168 | if (status != POWER_SUPPLY_STATUS_NOT_CHARGING && |
1169 | status != POWER_SUPPLY_STATUS_DISCHARGING) | ||
1097 | return 0; | 1170 | return 0; |
1098 | 1171 | ||
1099 | ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_EN, | 1172 | ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_EN, |