aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-25 09:28:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-25 09:28:08 -0400
commitdf132e4062afe06ddc9938802243d704906a884a (patch)
treed7fd08f6bea2c431440fb965f7c43335ce12c391
parent96f2f66a985699d201b3a84222b8dd42262a71fe (diff)
parentcfb347979e71d3ce6be59a988b3357f541c9eacf (diff)
Merge tag 'for-v4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset updates from Sebastian Reichel: - Add Spreadtrum SC2731 charger driver - bq25890-charger: Add BQ25896 support - bq27xxx-battery: Add support for BQ27411 - qcom-pon: Add pms405 pon support - cros-charger: add support for dedicated port - misc fixes * tag 'for-v4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (28 commits) power: max8925: mark expected switch fall-through power: supply: fix spelling mistake "Gauage" -> "Gauge" power: reset: qcom-pon: Add pms405 pon support power: supply: bq27xxx: Add support for BQ27411 power: supply: Add Spreadtrum SC2731 charger support dt-bindings: power: Add Spreadtrum SC2731 charger documentation power: supply: twl4030_charger: disable eoc interrupt on linear charge power: supply: twl4030_charger: fix charging current out-of-bounds power: supply: bq25890_charger: fix semicolon.cocci warnings power: supply: max8998-charger: Fix platform data retrieval power: supply: cros: add support for dedicated port mfd: cros: add charger port count command definition power: reset: at91-poweroff: do not procede if at91_shdwc is allocated power: reset: at91-poweroff: rename at91_shdwc_base member of struct shdwc power: reset: at91-poweroff: make sclk part of struct shdwc power: reset: at91-poweroff: make mpddrc_base part of struct shdwc power: reset: at91-poweroff: use only one poweroff function power: reset: at91-poweroff: switch to slow clock before shutdown power: reset: convert to SPDX identifiers power: supply: ab8500_fg: silence uninitialized variable warnings ...
-rw-r--r--Documentation/devicetree/bindings/power/reset/qcom,pon.txt5
-rw-r--r--Documentation/devicetree/bindings/power/supply/bq25890.txt3
-rw-r--r--Documentation/devicetree/bindings/power/supply/bq27xxx.txt1
-rw-r--r--Documentation/devicetree/bindings/power/supply/sc2731_charger.txt40
-rw-r--r--arch/arm/mach-at91/pm_suspend.S8
-rw-r--r--drivers/power/reset/at91-sama5d2_shdwc.c119
-rw-r--r--drivers/power/reset/qcom-pon.c1
-rw-r--r--drivers/power/reset/rmobile-reset.c5
-rw-r--r--drivers/power/supply/Kconfig7
-rw-r--r--drivers/power/supply/Makefile1
-rw-r--r--drivers/power/supply/ab8500_fg.c52
-rw-r--r--drivers/power/supply/bq25890_charger.c62
-rw-r--r--drivers/power/supply/bq27xxx_battery.c9
-rw-r--r--drivers/power/supply/bq27xxx_battery_i2c.c2
-rw-r--r--drivers/power/supply/cros_usbpd-charger.c117
-rw-r--r--drivers/power/supply/ds2780_battery.c2
-rw-r--r--drivers/power/supply/ds2781_battery.c2
-rw-r--r--drivers/power/supply/ds2782_battery.c2
-rw-r--r--drivers/power/supply/max14577_charger.c22
-rw-r--r--drivers/power/supply/max17040_battery.c18
-rw-r--r--drivers/power/supply/max17042_battery.c32
-rw-r--r--drivers/power/supply/max77693_charger.c22
-rw-r--r--drivers/power/supply/max8925_power.c1
-rw-r--r--drivers/power/supply/max8997_charger.c26
-rw-r--r--drivers/power/supply/max8998_charger.c28
-rw-r--r--drivers/power/supply/power_supply_sysfs.c3
-rw-r--r--drivers/power/supply/sc2731_charger.c504
-rw-r--r--drivers/power/supply/twl4030_charger.c30
-rw-r--r--include/linux/mfd/cros_ec_commands.h10
-rw-r--r--include/linux/power/bq27xxx_battery.h1
30 files changed, 922 insertions, 213 deletions
diff --git a/Documentation/devicetree/bindings/power/reset/qcom,pon.txt b/Documentation/devicetree/bindings/power/reset/qcom,pon.txt
index 651491bb63b7..5705f575862d 100644
--- a/Documentation/devicetree/bindings/power/reset/qcom,pon.txt
+++ b/Documentation/devicetree/bindings/power/reset/qcom,pon.txt
@@ -6,7 +6,10 @@ and resin along with the Android reboot-mode.
6This DT node has pwrkey and resin as sub nodes. 6This DT node has pwrkey and resin as sub nodes.
7 7
8Required Properties: 8Required Properties:
9-compatible: "qcom,pm8916-pon" 9-compatible: Must be one of:
10 "qcom,pm8916-pon"
11 "qcom,pms405-pon"
12
10-reg: Specifies the physical address of the pon register 13-reg: Specifies the physical address of the pon register
11 14
12Optional subnode: 15Optional subnode:
diff --git a/Documentation/devicetree/bindings/power/supply/bq25890.txt b/Documentation/devicetree/bindings/power/supply/bq25890.txt
index c9dd17d142ad..dc0568933359 100644
--- a/Documentation/devicetree/bindings/power/supply/bq25890.txt
+++ b/Documentation/devicetree/bindings/power/supply/bq25890.txt
@@ -1,5 +1,8 @@
1Binding for TI bq25890 Li-Ion Charger 1Binding for TI bq25890 Li-Ion Charger
2 2
3This driver will support the bq25896 and the bq25890. There are other ICs
4in the same family but those have not been tested.
5
3Required properties: 6Required properties:
4- compatible: Should contain one of the following: 7- compatible: Should contain one of the following:
5 * "ti,bq25890" 8 * "ti,bq25890"
diff --git a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
index 37994fdb18ca..4fa8e08df2b6 100644
--- a/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
+++ b/Documentation/devicetree/bindings/power/supply/bq27xxx.txt
@@ -23,6 +23,7 @@ Required properties:
23 * "ti,bq27546" - BQ27546 23 * "ti,bq27546" - BQ27546
24 * "ti,bq27742" - BQ27742 24 * "ti,bq27742" - BQ27742
25 * "ti,bq27545" - BQ27545 25 * "ti,bq27545" - BQ27545
26 * "ti,bq27411" - BQ27411
26 * "ti,bq27421" - BQ27421 27 * "ti,bq27421" - BQ27421
27 * "ti,bq27425" - BQ27425 28 * "ti,bq27425" - BQ27425
28 * "ti,bq27426" - BQ27426 29 * "ti,bq27426" - BQ27426
diff --git a/Documentation/devicetree/bindings/power/supply/sc2731_charger.txt b/Documentation/devicetree/bindings/power/supply/sc2731_charger.txt
new file mode 100644
index 000000000000..5266fab16575
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/sc2731_charger.txt
@@ -0,0 +1,40 @@
1Spreadtrum SC2731 PMIC battery charger binding
2
3Required properties:
4 - compatible: Should be "sprd,sc2731-charger".
5 - reg: Address offset of charger register.
6 - phys: Contains a phandle to the USB phy.
7
8Optional Properties:
9- monitored-battery: phandle of battery characteristics devicetree node.
10 The charger uses the following battery properties:
11- charge-term-current-microamp: current for charge termination phase.
12- constant-charge-voltage-max-microvolt: maximum constant input voltage.
13 See Documentation/devicetree/bindings/power/supply/battery.txt
14
15Example:
16
17 bat: battery {
18 compatible = "simple-battery";
19 charge-term-current-microamp = <120000>;
20 constant-charge-voltage-max-microvolt = <4350000>;
21 ......
22 };
23
24 sc2731_pmic: pmic@0 {
25 compatible = "sprd,sc2731";
26 reg = <0>;
27 spi-max-frequency = <26000000>;
28 interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
29 interrupt-controller;
30 #interrupt-cells = <2>;
31 #address-cells = <1>;
32 #size-cells = <0>;
33
34 charger@0 {
35 compatible = "sprd,sc2731-charger";
36 reg = <0x0>;
37 phys = <&ssphy>;
38 monitored-battery = <&bat>;
39 };
40 };
diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index a7c6ae13c945..bfe1c4d06901 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -149,6 +149,14 @@ exit_suspend:
149ENDPROC(at91_pm_suspend_in_sram) 149ENDPROC(at91_pm_suspend_in_sram)
150 150
151ENTRY(at91_backup_mode) 151ENTRY(at91_backup_mode)
152 /* Switch the master clock source to slow clock. */
153 ldr pmc, .pmc_base
154 ldr tmp1, [pmc, #AT91_PMC_MCKR]
155 bic tmp1, tmp1, #AT91_PMC_CSS
156 str tmp1, [pmc, #AT91_PMC_MCKR]
157
158 wait_mckrdy
159
152 /*BUMEN*/ 160 /*BUMEN*/
153 ldr r0, .sfr 161 ldr r0, .sfr
154 mov tmp1, #0x1 162 mov tmp1, #0x1
diff --git a/drivers/power/reset/at91-sama5d2_shdwc.c b/drivers/power/reset/at91-sama5d2_shdwc.c
index 0206cce328b3..2b686c55b717 100644
--- a/drivers/power/reset/at91-sama5d2_shdwc.c
+++ b/drivers/power/reset/at91-sama5d2_shdwc.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/clk/at91_pmc.h>
22#include <linux/io.h> 23#include <linux/io.h>
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/of.h> 25#include <linux/of.h>
@@ -69,7 +70,10 @@ struct shdwc_config {
69 70
70struct shdwc { 71struct shdwc {
71 const struct shdwc_config *cfg; 72 const struct shdwc_config *cfg;
72 void __iomem *at91_shdwc_base; 73 struct clk *sclk;
74 void __iomem *shdwc_base;
75 void __iomem *mpddrc_base;
76 void __iomem *pmc_base;
73}; 77};
74 78
75/* 79/*
@@ -77,8 +81,6 @@ struct shdwc {
77 * since pm_power_off itself is global. 81 * since pm_power_off itself is global.
78 */ 82 */
79static struct shdwc *at91_shdwc; 83static struct shdwc *at91_shdwc;
80static struct clk *sclk;
81static void __iomem *mpddrc_base;
82 84
83static const unsigned long long sdwc_dbc_period[] = { 85static const unsigned long long sdwc_dbc_period[] = {
84 0, 3, 32, 512, 4096, 32768, 86 0, 3, 32, 512, 4096, 32768,
@@ -90,7 +92,7 @@ static void __init at91_wakeup_status(struct platform_device *pdev)
90 u32 reg; 92 u32 reg;
91 char *reason = "unknown"; 93 char *reason = "unknown";
92 94
93 reg = readl(shdw->at91_shdwc_base + AT91_SHDW_SR); 95 reg = readl(shdw->shdwc_base + AT91_SHDW_SR);
94 96
95 dev_dbg(&pdev->dev, "%s: status = %#x\n", __func__, reg); 97 dev_dbg(&pdev->dev, "%s: status = %#x\n", __func__, reg);
96 98
@@ -108,12 +110,6 @@ static void __init at91_wakeup_status(struct platform_device *pdev)
108 110
109static void at91_poweroff(void) 111static void at91_poweroff(void)
110{ 112{
111 writel(AT91_SHDW_KEY | AT91_SHDW_SHDW,
112 at91_shdwc->at91_shdwc_base + AT91_SHDW_CR);
113}
114
115static void at91_lpddr_poweroff(void)
116{
117 asm volatile( 113 asm volatile(
118 /* Align to cache lines */ 114 /* Align to cache lines */
119 ".balign 32\n\t" 115 ".balign 32\n\t"
@@ -122,16 +118,29 @@ static void at91_lpddr_poweroff(void)
122 " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t" 118 " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
123 119
124 /* Power down SDRAM0 */ 120 /* Power down SDRAM0 */
121 " tst %0, #0\n\t"
122 " beq 1f\n\t"
125 " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t" 123 " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
124
125 /* Switch the master clock source to slow clock. */
126 "1: ldr r6, [%4, #" __stringify(AT91_PMC_MCKR) "]\n\t"
127 " bic r6, r6, #" __stringify(AT91_PMC_CSS) "\n\t"
128 " str r6, [%4, #" __stringify(AT91_PMC_MCKR) "]\n\t"
129 /* Wait for clock switch. */
130 "2: ldr r6, [%4, #" __stringify(AT91_PMC_SR) "]\n\t"
131 " tst r6, #" __stringify(AT91_PMC_MCKRDY) "\n\t"
132 " beq 2b\n\t"
133
126 /* Shutdown CPU */ 134 /* Shutdown CPU */
127 " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t" 135 " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
128 136
129 " b .\n\t" 137 " b .\n\t"
130 : 138 :
131 : "r" (mpddrc_base), 139 : "r" (at91_shdwc->mpddrc_base),
132 "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF), 140 "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
133 "r" (at91_shdwc->at91_shdwc_base), 141 "r" (at91_shdwc->shdwc_base),
134 "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW) 142 "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW),
143 "r" (at91_shdwc->pmc_base)
135 : "r6"); 144 : "r6");
136} 145}
137 146
@@ -213,10 +222,10 @@ static void at91_shdwc_dt_configure(struct platform_device *pdev)
213 mode |= SHDW_RTCWKEN(shdw->cfg); 222 mode |= SHDW_RTCWKEN(shdw->cfg);
214 223
215 dev_dbg(&pdev->dev, "%s: mode = %#x\n", __func__, mode); 224 dev_dbg(&pdev->dev, "%s: mode = %#x\n", __func__, mode);
216 writel(mode, shdw->at91_shdwc_base + AT91_SHDW_MR); 225 writel(mode, shdw->shdwc_base + AT91_SHDW_MR);
217 226
218 input = at91_shdwc_get_wakeup_input(pdev, np); 227 input = at91_shdwc_get_wakeup_input(pdev, np);
219 writel(input, shdw->at91_shdwc_base + AT91_SHDW_WUIR); 228 writel(input, shdw->shdwc_base + AT91_SHDW_WUIR);
220} 229}
221 230
222static const struct shdwc_config sama5d2_shdwc_config = { 231static const struct shdwc_config sama5d2_shdwc_config = {
@@ -246,6 +255,9 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
246 if (!pdev->dev.of_node) 255 if (!pdev->dev.of_node)
247 return -ENODEV; 256 return -ENODEV;
248 257
258 if (at91_shdwc)
259 return -EBUSY;
260
249 at91_shdwc = devm_kzalloc(&pdev->dev, sizeof(*at91_shdwc), GFP_KERNEL); 261 at91_shdwc = devm_kzalloc(&pdev->dev, sizeof(*at91_shdwc), GFP_KERNEL);
250 if (!at91_shdwc) 262 if (!at91_shdwc)
251 return -ENOMEM; 263 return -ENOMEM;
@@ -253,20 +265,20 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
253 platform_set_drvdata(pdev, at91_shdwc); 265 platform_set_drvdata(pdev, at91_shdwc);
254 266
255 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 267 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
256 at91_shdwc->at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res); 268 at91_shdwc->shdwc_base = devm_ioremap_resource(&pdev->dev, res);
257 if (IS_ERR(at91_shdwc->at91_shdwc_base)) { 269 if (IS_ERR(at91_shdwc->shdwc_base)) {
258 dev_err(&pdev->dev, "Could not map reset controller address\n"); 270 dev_err(&pdev->dev, "Could not map reset controller address\n");
259 return PTR_ERR(at91_shdwc->at91_shdwc_base); 271 return PTR_ERR(at91_shdwc->shdwc_base);
260 } 272 }
261 273
262 match = of_match_node(at91_shdwc_of_match, pdev->dev.of_node); 274 match = of_match_node(at91_shdwc_of_match, pdev->dev.of_node);
263 at91_shdwc->cfg = match->data; 275 at91_shdwc->cfg = match->data;
264 276
265 sclk = devm_clk_get(&pdev->dev, NULL); 277 at91_shdwc->sclk = devm_clk_get(&pdev->dev, NULL);
266 if (IS_ERR(sclk)) 278 if (IS_ERR(at91_shdwc->sclk))
267 return PTR_ERR(sclk); 279 return PTR_ERR(at91_shdwc->sclk);
268 280
269 ret = clk_prepare_enable(sclk); 281 ret = clk_prepare_enable(at91_shdwc->sclk);
270 if (ret) { 282 if (ret) {
271 dev_err(&pdev->dev, "Could not enable slow clock\n"); 283 dev_err(&pdev->dev, "Could not enable slow clock\n");
272 return ret; 284 return ret;
@@ -276,41 +288,70 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
276 288
277 at91_shdwc_dt_configure(pdev); 289 at91_shdwc_dt_configure(pdev);
278 290
279 pm_power_off = at91_poweroff; 291 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-pmc");
292 if (!np) {
293 ret = -ENODEV;
294 goto clk_disable;
295 }
296
297 at91_shdwc->pmc_base = of_iomap(np, 0);
298 of_node_put(np);
299
300 if (!at91_shdwc->pmc_base) {
301 ret = -ENOMEM;
302 goto clk_disable;
303 }
280 304
281 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc"); 305 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
282 if (!np) 306 if (!np) {
283 return 0; 307 ret = -ENODEV;
308 goto unmap;
309 }
284 310
285 mpddrc_base = of_iomap(np, 0); 311 at91_shdwc->mpddrc_base = of_iomap(np, 0);
286 of_node_put(np); 312 of_node_put(np);
287 313
288 if (!mpddrc_base) 314 if (!at91_shdwc->mpddrc_base) {
289 return 0; 315 ret = -ENOMEM;
316 goto unmap;
317 }
290 318
291 ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD; 319 pm_power_off = at91_poweroff;
292 if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) || 320
293 (ddr_type == AT91_DDRSDRC_MD_LPDDR3)) 321 ddr_type = readl(at91_shdwc->mpddrc_base + AT91_DDRSDRC_MDR) &
294 pm_power_off = at91_lpddr_poweroff; 322 AT91_DDRSDRC_MD;
295 else 323 if (ddr_type != AT91_DDRSDRC_MD_LPDDR2 &&
296 iounmap(mpddrc_base); 324 ddr_type != AT91_DDRSDRC_MD_LPDDR3) {
325 iounmap(at91_shdwc->mpddrc_base);
326 at91_shdwc->mpddrc_base = NULL;
327 }
297 328
298 return 0; 329 return 0;
330
331unmap:
332 iounmap(at91_shdwc->pmc_base);
333clk_disable:
334 clk_disable_unprepare(at91_shdwc->sclk);
335
336 return ret;
299} 337}
300 338
301static int __exit at91_shdwc_remove(struct platform_device *pdev) 339static int __exit at91_shdwc_remove(struct platform_device *pdev)
302{ 340{
303 struct shdwc *shdw = platform_get_drvdata(pdev); 341 struct shdwc *shdw = platform_get_drvdata(pdev);
304 342
305 if (pm_power_off == at91_poweroff || 343 if (pm_power_off == at91_poweroff)
306 pm_power_off == at91_lpddr_poweroff)
307 pm_power_off = NULL; 344 pm_power_off = NULL;
308 345
309 /* Reset values to disable wake-up features */ 346 /* Reset values to disable wake-up features */
310 writel(0, shdw->at91_shdwc_base + AT91_SHDW_MR); 347 writel(0, shdw->shdwc_base + AT91_SHDW_MR);
311 writel(0, shdw->at91_shdwc_base + AT91_SHDW_WUIR); 348 writel(0, shdw->shdwc_base + AT91_SHDW_WUIR);
349
350 if (shdw->mpddrc_base)
351 iounmap(shdw->mpddrc_base);
352 iounmap(shdw->pmc_base);
312 353
313 clk_disable_unprepare(sclk); 354 clk_disable_unprepare(shdw->sclk);
314 355
315 return 0; 356 return 0;
316} 357}
diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c
index 0c4caaa7e88f..3fa1642d4c54 100644
--- a/drivers/power/reset/qcom-pon.c
+++ b/drivers/power/reset/qcom-pon.c
@@ -74,6 +74,7 @@ static int pm8916_pon_probe(struct platform_device *pdev)
74 74
75static const struct of_device_id pm8916_pon_id_table[] = { 75static const struct of_device_id pm8916_pon_id_table[] = {
76 { .compatible = "qcom,pm8916-pon" }, 76 { .compatible = "qcom,pm8916-pon" },
77 { .compatible = "qcom,pms405-pon" },
77 { } 78 { }
78}; 79};
79MODULE_DEVICE_TABLE(of, pm8916_pon_id_table); 80MODULE_DEVICE_TABLE(of, pm8916_pon_id_table);
diff --git a/drivers/power/reset/rmobile-reset.c b/drivers/power/reset/rmobile-reset.c
index e6569df76941..bd3b396558e0 100644
--- a/drivers/power/reset/rmobile-reset.c
+++ b/drivers/power/reset/rmobile-reset.c
@@ -1,11 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Renesas R-Mobile Reset Driver 3 * Renesas R-Mobile Reset Driver
3 * 4 *
4 * Copyright (C) 2014 Glider bvba 5 * Copyright (C) 2014 Glider bvba
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */ 6 */
10 7
11#include <linux/io.h> 8#include <linux/io.h>
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index ff6dab0bf0dd..f27cf0709500 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -645,4 +645,11 @@ config CHARGER_CROS_USBPD
645 what is connected to USB PD ports from the EC and converts 645 what is connected to USB PD ports from the EC and converts
646 that into power_supply properties. 646 that into power_supply properties.
647 647
648config CHARGER_SC2731
649 tristate "Spreadtrum SC2731 charger driver"
650 depends on MFD_SC27XX_PMIC || COMPILE_TEST
651 help
652 Say Y here to enable support for battery charging with SC2731
653 PMIC chips.
654
648endif # POWER_SUPPLY 655endif # POWER_SUPPLY
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index a26b402c45d9..767105b88d00 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -85,3 +85,4 @@ obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
85obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o 85obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o
86obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o 86obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o
87obj-$(CONFIG_CHARGER_CROS_USBPD) += cros_usbpd-charger.o 87obj-$(CONFIG_CHARGER_CROS_USBPD) += cros_usbpd-charger.o
88obj-$(CONFIG_CHARGER_SC2731) += sc2731_charger.o
diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
index 02356f9b5f22..776102c31305 100644
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -2433,17 +2433,14 @@ static ssize_t charge_full_store(struct ab8500_fg *di, const char *buf,
2433 size_t count) 2433 size_t count)
2434{ 2434{
2435 unsigned long charge_full; 2435 unsigned long charge_full;
2436 ssize_t ret; 2436 int ret;
2437 2437
2438 ret = kstrtoul(buf, 10, &charge_full); 2438 ret = kstrtoul(buf, 10, &charge_full);
2439 if (ret)
2440 return ret;
2439 2441
2440 dev_dbg(di->dev, "Ret %zd charge_full %lu", ret, charge_full); 2442 di->bat_cap.max_mah = (int) charge_full;
2441 2443 return count;
2442 if (!ret) {
2443 di->bat_cap.max_mah = (int) charge_full;
2444 ret = count;
2445 }
2446 return ret;
2447} 2444}
2448 2445
2449static ssize_t charge_now_show(struct ab8500_fg *di, char *buf) 2446static ssize_t charge_now_show(struct ab8500_fg *di, char *buf)
@@ -2455,20 +2452,16 @@ static ssize_t charge_now_store(struct ab8500_fg *di, const char *buf,
2455 size_t count) 2452 size_t count)
2456{ 2453{
2457 unsigned long charge_now; 2454 unsigned long charge_now;
2458 ssize_t ret; 2455 int ret;
2459 2456
2460 ret = kstrtoul(buf, 10, &charge_now); 2457 ret = kstrtoul(buf, 10, &charge_now);
2458 if (ret)
2459 return ret;
2461 2460
2462 dev_dbg(di->dev, "Ret %zd charge_now %lu was %d", 2461 di->bat_cap.user_mah = (int) charge_now;
2463 ret, charge_now, di->bat_cap.prev_mah); 2462 di->flags.user_cap = true;
2464 2463 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0);
2465 if (!ret) { 2464 return count;
2466 di->bat_cap.user_mah = (int) charge_now;
2467 di->flags.user_cap = true;
2468 ret = count;
2469 queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0);
2470 }
2471 return ret;
2472} 2465}
2473 2466
2474static struct ab8500_fg_sysfs_entry charge_full_attr = 2467static struct ab8500_fg_sysfs_entry charge_full_attr =
@@ -2582,11 +2575,12 @@ static ssize_t ab8505_powercut_flagtime_write(struct device *dev,
2582 const char *buf, size_t count) 2575 const char *buf, size_t count)
2583{ 2576{
2584 int ret; 2577 int ret;
2585 long unsigned reg_value; 2578 int reg_value;
2586 struct power_supply *psy = dev_get_drvdata(dev); 2579 struct power_supply *psy = dev_get_drvdata(dev);
2587 struct ab8500_fg *di = power_supply_get_drvdata(psy); 2580 struct ab8500_fg *di = power_supply_get_drvdata(psy);
2588 2581
2589 reg_value = simple_strtoul(buf, NULL, 10); 2582 if (kstrtoint(buf, 10, &reg_value))
2583 goto fail;
2590 2584
2591 if (reg_value > 0x7F) { 2585 if (reg_value > 0x7F) {
2592 dev_err(dev, "Incorrect parameter, echo 0 (1.98s) - 127 (15.625ms) for flagtime\n"); 2586 dev_err(dev, "Incorrect parameter, echo 0 (1.98s) - 127 (15.625ms) for flagtime\n");
@@ -2636,7 +2630,9 @@ static ssize_t ab8505_powercut_maxtime_write(struct device *dev,
2636 struct power_supply *psy = dev_get_drvdata(dev); 2630 struct power_supply *psy = dev_get_drvdata(dev);
2637 struct ab8500_fg *di = power_supply_get_drvdata(psy); 2631 struct ab8500_fg *di = power_supply_get_drvdata(psy);
2638 2632
2639 reg_value = simple_strtoul(buf, NULL, 10); 2633 if (kstrtoint(buf, 10, &reg_value))
2634 goto fail;
2635
2640 if (reg_value > 0x7F) { 2636 if (reg_value > 0x7F) {
2641 dev_err(dev, "Incorrect parameter, echo 0 (0.0s) - 127 (1.98s) for maxtime\n"); 2637 dev_err(dev, "Incorrect parameter, echo 0 (0.0s) - 127 (1.98s) for maxtime\n");
2642 goto fail; 2638 goto fail;
@@ -2684,7 +2680,9 @@ static ssize_t ab8505_powercut_restart_write(struct device *dev,
2684 struct power_supply *psy = dev_get_drvdata(dev); 2680 struct power_supply *psy = dev_get_drvdata(dev);
2685 struct ab8500_fg *di = power_supply_get_drvdata(psy); 2681 struct ab8500_fg *di = power_supply_get_drvdata(psy);
2686 2682
2687 reg_value = simple_strtoul(buf, NULL, 10); 2683 if (kstrtoint(buf, 10, &reg_value))
2684 goto fail;
2685
2688 if (reg_value > 0xF) { 2686 if (reg_value > 0xF) {
2689 dev_err(dev, "Incorrect parameter, echo 0 - 15 for number of restart\n"); 2687 dev_err(dev, "Incorrect parameter, echo 0 - 15 for number of restart\n");
2690 goto fail; 2688 goto fail;
@@ -2777,7 +2775,9 @@ static ssize_t ab8505_powercut_write(struct device *dev,
2777 struct power_supply *psy = dev_get_drvdata(dev); 2775 struct power_supply *psy = dev_get_drvdata(dev);
2778 struct ab8500_fg *di = power_supply_get_drvdata(psy); 2776 struct ab8500_fg *di = power_supply_get_drvdata(psy);
2779 2777
2780 reg_value = simple_strtoul(buf, NULL, 10); 2778 if (kstrtoint(buf, 10, &reg_value))
2779 goto fail;
2780
2781 if (reg_value > 0x1) { 2781 if (reg_value > 0x1) {
2782 dev_err(dev, "Incorrect parameter, echo 0/1 to disable/enable Pcut feature\n"); 2782 dev_err(dev, "Incorrect parameter, echo 0/1 to disable/enable Pcut feature\n");
2783 goto fail; 2783 goto fail;
@@ -2849,7 +2849,9 @@ static ssize_t ab8505_powercut_debounce_write(struct device *dev,
2849 struct power_supply *psy = dev_get_drvdata(dev); 2849 struct power_supply *psy = dev_get_drvdata(dev);
2850 struct ab8500_fg *di = power_supply_get_drvdata(psy); 2850 struct ab8500_fg *di = power_supply_get_drvdata(psy);
2851 2851
2852 reg_value = simple_strtoul(buf, NULL, 10); 2852 if (kstrtoint(buf, 10, &reg_value))
2853 goto fail;
2854
2853 if (reg_value > 0x7) { 2855 if (reg_value > 0x7) {
2854 dev_err(dev, "Incorrect parameter, echo 0 to 7 for debounce setting\n"); 2856 dev_err(dev, "Incorrect parameter, echo 0 to 7 for debounce setting\n");
2855 goto fail; 2857 goto fail;
diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c
index 8e2c41ded171..70b90db5ae38 100644
--- a/drivers/power/supply/bq25890_charger.c
+++ b/drivers/power/supply/bq25890_charger.c
@@ -32,6 +32,7 @@
32#define BQ25890_IRQ_PIN "bq25890_irq" 32#define BQ25890_IRQ_PIN "bq25890_irq"
33 33
34#define BQ25890_ID 3 34#define BQ25890_ID 3
35#define BQ25896_ID 0
35 36
36enum bq25890_fields { 37enum bq25890_fields {
37 F_EN_HIZ, F_EN_ILIM, F_IILIM, /* Reg00 */ 38 F_EN_HIZ, F_EN_ILIM, F_IILIM, /* Reg00 */
@@ -153,8 +154,8 @@ static const struct reg_field bq25890_reg_fields[] = {
153 [F_CONV_RATE] = REG_FIELD(0x02, 6, 6), 154 [F_CONV_RATE] = REG_FIELD(0x02, 6, 6),
154 [F_BOOSTF] = REG_FIELD(0x02, 5, 5), 155 [F_BOOSTF] = REG_FIELD(0x02, 5, 5),
155 [F_ICO_EN] = REG_FIELD(0x02, 4, 4), 156 [F_ICO_EN] = REG_FIELD(0x02, 4, 4),
156 [F_HVDCP_EN] = REG_FIELD(0x02, 3, 3), 157 [F_HVDCP_EN] = REG_FIELD(0x02, 3, 3), // reserved on BQ25896
157 [F_MAXC_EN] = REG_FIELD(0x02, 2, 2), 158 [F_MAXC_EN] = REG_FIELD(0x02, 2, 2), // reserved on BQ25896
158 [F_FORCE_DPM] = REG_FIELD(0x02, 1, 1), 159 [F_FORCE_DPM] = REG_FIELD(0x02, 1, 1),
159 [F_AUTO_DPDM_EN] = REG_FIELD(0x02, 0, 0), 160 [F_AUTO_DPDM_EN] = REG_FIELD(0x02, 0, 0),
160 /* REG03 */ 161 /* REG03 */
@@ -163,6 +164,7 @@ static const struct reg_field bq25890_reg_fields[] = {
163 [F_OTG_CFG] = REG_FIELD(0x03, 5, 5), 164 [F_OTG_CFG] = REG_FIELD(0x03, 5, 5),
164 [F_CHG_CFG] = REG_FIELD(0x03, 4, 4), 165 [F_CHG_CFG] = REG_FIELD(0x03, 4, 4),
165 [F_SYSVMIN] = REG_FIELD(0x03, 1, 3), 166 [F_SYSVMIN] = REG_FIELD(0x03, 1, 3),
167 /* MIN_VBAT_SEL on BQ25896 */
166 /* REG04 */ 168 /* REG04 */
167 [F_PUMPX_EN] = REG_FIELD(0x04, 7, 7), 169 [F_PUMPX_EN] = REG_FIELD(0x04, 7, 7),
168 [F_ICHG] = REG_FIELD(0x04, 0, 6), 170 [F_ICHG] = REG_FIELD(0x04, 0, 6),
@@ -181,7 +183,7 @@ static const struct reg_field bq25890_reg_fields[] = {
181 [F_CHG_TMR] = REG_FIELD(0x07, 1, 2), 183 [F_CHG_TMR] = REG_FIELD(0x07, 1, 2),
182 [F_JEITA_ISET] = REG_FIELD(0x07, 0, 0), 184 [F_JEITA_ISET] = REG_FIELD(0x07, 0, 0),
183 /* REG08 */ 185 /* REG08 */
184 [F_BATCMP] = REG_FIELD(0x08, 6, 7), 186 [F_BATCMP] = REG_FIELD(0x08, 6, 7), // 5-7 on BQ25896
185 [F_VCLAMP] = REG_FIELD(0x08, 2, 4), 187 [F_VCLAMP] = REG_FIELD(0x08, 2, 4),
186 [F_TREG] = REG_FIELD(0x08, 0, 1), 188 [F_TREG] = REG_FIELD(0x08, 0, 1),
187 /* REG09 */ 189 /* REG09 */
@@ -195,12 +197,13 @@ static const struct reg_field bq25890_reg_fields[] = {
195 [F_PUMPX_DN] = REG_FIELD(0x09, 0, 0), 197 [F_PUMPX_DN] = REG_FIELD(0x09, 0, 0),
196 /* REG0A */ 198 /* REG0A */
197 [F_BOOSTV] = REG_FIELD(0x0A, 4, 7), 199 [F_BOOSTV] = REG_FIELD(0x0A, 4, 7),
200 /* PFM_OTG_DIS 3 on BQ25896 */
198 [F_BOOSTI] = REG_FIELD(0x0A, 0, 2), 201 [F_BOOSTI] = REG_FIELD(0x0A, 0, 2),
199 /* REG0B */ 202 /* REG0B */
200 [F_VBUS_STAT] = REG_FIELD(0x0B, 5, 7), 203 [F_VBUS_STAT] = REG_FIELD(0x0B, 5, 7),
201 [F_CHG_STAT] = REG_FIELD(0x0B, 3, 4), 204 [F_CHG_STAT] = REG_FIELD(0x0B, 3, 4),
202 [F_PG_STAT] = REG_FIELD(0x0B, 2, 2), 205 [F_PG_STAT] = REG_FIELD(0x0B, 2, 2),
203 [F_SDP_STAT] = REG_FIELD(0x0B, 1, 1), 206 [F_SDP_STAT] = REG_FIELD(0x0B, 1, 1), // reserved on BQ25896
204 [F_VSYS_STAT] = REG_FIELD(0x0B, 0, 0), 207 [F_VSYS_STAT] = REG_FIELD(0x0B, 0, 0),
205 /* REG0C */ 208 /* REG0C */
206 [F_WD_FAULT] = REG_FIELD(0x0C, 7, 7), 209 [F_WD_FAULT] = REG_FIELD(0x0C, 7, 7),
@@ -244,10 +247,7 @@ enum bq25890_table_ids {
244 /* range tables */ 247 /* range tables */
245 TBL_ICHG, 248 TBL_ICHG,
246 TBL_ITERM, 249 TBL_ITERM,
247 TBL_IPRECHG,
248 TBL_VREG, 250 TBL_VREG,
249 TBL_BATCMP,
250 TBL_VCLAMP,
251 TBL_BOOSTV, 251 TBL_BOOSTV,
252 TBL_SYSVMIN, 252 TBL_SYSVMIN,
253 253
@@ -287,8 +287,6 @@ static const union {
287 [TBL_ICHG] = { .rt = {0, 5056000, 64000} }, /* uA */ 287 [TBL_ICHG] = { .rt = {0, 5056000, 64000} }, /* uA */
288 [TBL_ITERM] = { .rt = {64000, 1024000, 64000} }, /* uA */ 288 [TBL_ITERM] = { .rt = {64000, 1024000, 64000} }, /* uA */
289 [TBL_VREG] = { .rt = {3840000, 4608000, 16000} }, /* uV */ 289 [TBL_VREG] = { .rt = {3840000, 4608000, 16000} }, /* uV */
290 [TBL_BATCMP] = { .rt = {0, 140, 20} }, /* mOhm */
291 [TBL_VCLAMP] = { .rt = {0, 224000, 32000} }, /* uV */
292 [TBL_BOOSTV] = { .rt = {4550000, 5510000, 64000} }, /* uV */ 290 [TBL_BOOSTV] = { .rt = {4550000, 5510000, 64000} }, /* uV */
293 [TBL_SYSVMIN] = { .rt = {3000000, 3700000, 100000} }, /* uV */ 291 [TBL_SYSVMIN] = { .rt = {3000000, 3700000, 100000} }, /* uV */
294 292
@@ -401,6 +399,16 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
401 val->strval = BQ25890_MANUFACTURER; 399 val->strval = BQ25890_MANUFACTURER;
402 break; 400 break;
403 401
402 case POWER_SUPPLY_PROP_MODEL_NAME:
403 if (bq->chip_id == BQ25890_ID)
404 val->strval = "BQ25890";
405 else if (bq->chip_id == BQ25896_ID)
406 val->strval = "BQ25896";
407 else
408 val->strval = "UNKNOWN";
409
410 break;
411
404 case POWER_SUPPLY_PROP_ONLINE: 412 case POWER_SUPPLY_PROP_ONLINE:
405 val->intval = state.online; 413 val->intval = state.online;
406 break; 414 break;
@@ -453,6 +461,15 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
453 val->intval = bq25890_find_val(bq->init_data.iterm, TBL_ITERM); 461 val->intval = bq25890_find_val(bq->init_data.iterm, TBL_ITERM);
454 break; 462 break;
455 463
464 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
465 ret = bq25890_field_read(bq, F_SYSV); /* read measured value */
466 if (ret < 0)
467 return ret;
468
469 /* converted_val = 2.304V + ADC_val * 20mV (table 10.3.15) */
470 val->intval = 2304000 + ret * 20000;
471 break;
472
456 default: 473 default:
457 return -EINVAL; 474 return -EINVAL;
458 } 475 }
@@ -608,30 +625,40 @@ static int bq25890_hw_init(struct bq25890_device *bq)
608 }; 625 };
609 626
610 ret = bq25890_chip_reset(bq); 627 ret = bq25890_chip_reset(bq);
611 if (ret < 0) 628 if (ret < 0) {
629 dev_dbg(bq->dev, "Reset failed %d\n", ret);
612 return ret; 630 return ret;
631 }
613 632
614 /* disable watchdog */ 633 /* disable watchdog */
615 ret = bq25890_field_write(bq, F_WD, 0); 634 ret = bq25890_field_write(bq, F_WD, 0);
616 if (ret < 0) 635 if (ret < 0) {
636 dev_dbg(bq->dev, "Disabling watchdog failed %d\n", ret);
617 return ret; 637 return ret;
638 }
618 639
619 /* initialize currents/voltages and other parameters */ 640 /* initialize currents/voltages and other parameters */
620 for (i = 0; i < ARRAY_SIZE(init_data); i++) { 641 for (i = 0; i < ARRAY_SIZE(init_data); i++) {
621 ret = bq25890_field_write(bq, init_data[i].id, 642 ret = bq25890_field_write(bq, init_data[i].id,
622 init_data[i].value); 643 init_data[i].value);
623 if (ret < 0) 644 if (ret < 0) {
645 dev_dbg(bq->dev, "Writing init data failed %d\n", ret);
624 return ret; 646 return ret;
647 }
625 } 648 }
626 649
627 /* Configure ADC for continuous conversions. This does not enable it. */ 650 /* Configure ADC for continuous conversions. This does not enable it. */
628 ret = bq25890_field_write(bq, F_CONV_RATE, 1); 651 ret = bq25890_field_write(bq, F_CONV_RATE, 1);
629 if (ret < 0) 652 if (ret < 0) {
653 dev_dbg(bq->dev, "Config ADC failed %d\n", ret);
630 return ret; 654 return ret;
655 }
631 656
632 ret = bq25890_get_chip_state(bq, &state); 657 ret = bq25890_get_chip_state(bq, &state);
633 if (ret < 0) 658 if (ret < 0) {
659 dev_dbg(bq->dev, "Get state failed %d\n", ret);
634 return ret; 660 return ret;
661 }
635 662
636 mutex_lock(&bq->lock); 663 mutex_lock(&bq->lock);
637 bq->state = state; 664 bq->state = state;
@@ -642,6 +669,7 @@ static int bq25890_hw_init(struct bq25890_device *bq)
642 669
643static enum power_supply_property bq25890_power_supply_props[] = { 670static enum power_supply_property bq25890_power_supply_props[] = {
644 POWER_SUPPLY_PROP_MANUFACTURER, 671 POWER_SUPPLY_PROP_MANUFACTURER,
672 POWER_SUPPLY_PROP_MODEL_NAME,
645 POWER_SUPPLY_PROP_STATUS, 673 POWER_SUPPLY_PROP_STATUS,
646 POWER_SUPPLY_PROP_ONLINE, 674 POWER_SUPPLY_PROP_ONLINE,
647 POWER_SUPPLY_PROP_HEALTH, 675 POWER_SUPPLY_PROP_HEALTH,
@@ -650,6 +678,7 @@ static enum power_supply_property bq25890_power_supply_props[] = {
650 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 678 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
651 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 679 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
652 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, 680 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
681 POWER_SUPPLY_PROP_VOLTAGE_NOW,
653}; 682};
654 683
655static char *bq25890_charger_supplied_to[] = { 684static char *bq25890_charger_supplied_to[] = {
@@ -767,6 +796,9 @@ static int bq25890_fw_read_u32_props(struct bq25890_device *bq)
767 if (props[i].optional) 796 if (props[i].optional)
768 continue; 797 continue;
769 798
799 dev_err(bq->dev, "Unable to read property %d %s\n", ret,
800 props[i].name);
801
770 return ret; 802 return ret;
771 } 803 }
772 804
@@ -840,7 +872,7 @@ static int bq25890_probe(struct i2c_client *client,
840 return bq->chip_id; 872 return bq->chip_id;
841 } 873 }
842 874
843 if (bq->chip_id != BQ25890_ID) { 875 if ((bq->chip_id != BQ25890_ID) && (bq->chip_id != BQ25896_ID)) {
844 dev_err(dev, "Chip with ID=%d, not supported!\n", bq->chip_id); 876 dev_err(dev, "Chip with ID=%d, not supported!\n", bq->chip_id);
845 return -ENODEV; 877 return -ENODEV;
846 } 878 }
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index f022e1b550df..6dbbe95844a3 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -432,6 +432,7 @@ static u8
432 [BQ27XXX_REG_AP] = 0x18, 432 [BQ27XXX_REG_AP] = 0x18,
433 BQ27XXX_DM_REG_ROWS, 433 BQ27XXX_DM_REG_ROWS,
434 }; 434 };
435#define bq27411_regs bq27421_regs
435#define bq27425_regs bq27421_regs 436#define bq27425_regs bq27421_regs
436#define bq27426_regs bq27421_regs 437#define bq27426_regs bq27421_regs
437#define bq27441_regs bq27421_regs 438#define bq27441_regs bq27421_regs
@@ -665,6 +666,7 @@ static enum power_supply_property bq27421_props[] = {
665 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 666 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
666 POWER_SUPPLY_PROP_MANUFACTURER, 667 POWER_SUPPLY_PROP_MANUFACTURER,
667}; 668};
669#define bq27411_props bq27421_props
668#define bq27425_props bq27421_props 670#define bq27425_props bq27421_props
669#define bq27426_props bq27421_props 671#define bq27426_props bq27421_props
670#define bq27441_props bq27421_props 672#define bq27441_props bq27421_props
@@ -725,6 +727,12 @@ static struct bq27xxx_dm_reg bq27545_dm_regs[] = {
725#define bq27545_dm_regs 0 727#define bq27545_dm_regs 0
726#endif 728#endif
727 729
730static struct bq27xxx_dm_reg bq27411_dm_regs[] = {
731 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 32767 },
732 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 },
733 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 16, 2, 2800, 3700 },
734};
735
728static struct bq27xxx_dm_reg bq27421_dm_regs[] = { 736static struct bq27xxx_dm_reg bq27421_dm_regs[] = {
729 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 8000 }, 737 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 8000 },
730 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 }, 738 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 },
@@ -802,6 +810,7 @@ static struct {
802 [BQ27546] = BQ27XXX_DATA(bq27546, 0 , BQ27XXX_O_OTDC), 810 [BQ27546] = BQ27XXX_DATA(bq27546, 0 , BQ27XXX_O_OTDC),
803 [BQ27742] = BQ27XXX_DATA(bq27742, 0 , BQ27XXX_O_OTDC), 811 [BQ27742] = BQ27XXX_DATA(bq27742, 0 , BQ27XXX_O_OTDC),
804 [BQ27545] = BQ27XXX_DATA(bq27545, 0x04143672, BQ27XXX_O_OTDC), 812 [BQ27545] = BQ27XXX_DATA(bq27545, 0x04143672, BQ27XXX_O_OTDC),
813 [BQ27411] = BQ27XXX_DATA(bq27411, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
805 [BQ27421] = BQ27XXX_DATA(bq27421, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM), 814 [BQ27421] = BQ27XXX_DATA(bq27421, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
806 [BQ27425] = BQ27XXX_DATA(bq27425, 0x04143672, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP), 815 [BQ27425] = BQ27XXX_DATA(bq27425, 0x04143672, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP),
807 [BQ27426] = BQ27XXX_DATA(bq27426, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM), 816 [BQ27426] = BQ27XXX_DATA(bq27426, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 40069128ad44..2677c38a8a42 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -247,6 +247,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
247 { "bq27546", BQ27546 }, 247 { "bq27546", BQ27546 },
248 { "bq27742", BQ27742 }, 248 { "bq27742", BQ27742 },
249 { "bq27545", BQ27545 }, 249 { "bq27545", BQ27545 },
250 { "bq27411", BQ27411 },
250 { "bq27421", BQ27421 }, 251 { "bq27421", BQ27421 },
251 { "bq27425", BQ27425 }, 252 { "bq27425", BQ27425 },
252 { "bq27426", BQ27426 }, 253 { "bq27426", BQ27426 },
@@ -279,6 +280,7 @@ static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
279 { .compatible = "ti,bq27546" }, 280 { .compatible = "ti,bq27546" },
280 { .compatible = "ti,bq27742" }, 281 { .compatible = "ti,bq27742" },
281 { .compatible = "ti,bq27545" }, 282 { .compatible = "ti,bq27545" },
283 { .compatible = "ti,bq27411" },
282 { .compatible = "ti,bq27421" }, 284 { .compatible = "ti,bq27421" },
283 { .compatible = "ti,bq27425" }, 285 { .compatible = "ti,bq27425" },
284 { .compatible = "ti,bq27426" }, 286 { .compatible = "ti,bq27426" },
diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c
index 688a16bacfbb..7e9c3984ef6a 100644
--- a/drivers/power/supply/cros_usbpd-charger.c
+++ b/drivers/power/supply/cros_usbpd-charger.c
@@ -12,8 +12,12 @@
12#include <linux/power_supply.h> 12#include <linux/power_supply.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14 14
15#define CHARGER_DIR_NAME "CROS_USBPD_CHARGER%d" 15#define CHARGER_USBPD_DIR_NAME "CROS_USBPD_CHARGER%d"
16#define CHARGER_DIR_NAME_LENGTH sizeof(CHARGER_DIR_NAME) 16#define CHARGER_DEDICATED_DIR_NAME "CROS_DEDICATED_CHARGER"
17#define CHARGER_DIR_NAME_LENGTH (sizeof(CHARGER_USBPD_DIR_NAME) >= \
18 sizeof(CHARGER_DEDICATED_DIR_NAME) ? \
19 sizeof(CHARGER_USBPD_DIR_NAME) : \
20 sizeof(CHARGER_DEDICATED_DIR_NAME))
17#define CHARGER_CACHE_UPDATE_DELAY msecs_to_jiffies(500) 21#define CHARGER_CACHE_UPDATE_DELAY msecs_to_jiffies(500)
18#define CHARGER_MANUFACTURER_MODEL_LENGTH 32 22#define CHARGER_MANUFACTURER_MODEL_LENGTH 32
19 23
@@ -42,6 +46,7 @@ struct charger_data {
42 struct cros_ec_dev *ec_dev; 46 struct cros_ec_dev *ec_dev;
43 struct cros_ec_device *ec_device; 47 struct cros_ec_device *ec_device;
44 int num_charger_ports; 48 int num_charger_ports;
49 int num_usbpd_ports;
45 int num_registered_psy; 50 int num_registered_psy;
46 struct port_data *ports[EC_USB_PD_MAX_PORTS]; 51 struct port_data *ports[EC_USB_PD_MAX_PORTS];
47 struct notifier_block notifier; 52 struct notifier_block notifier;
@@ -58,6 +63,12 @@ static enum power_supply_property cros_usbpd_charger_props[] = {
58 POWER_SUPPLY_PROP_USB_TYPE 63 POWER_SUPPLY_PROP_USB_TYPE
59}; 64};
60 65
66static enum power_supply_property cros_usbpd_dedicated_charger_props[] = {
67 POWER_SUPPLY_PROP_ONLINE,
68 POWER_SUPPLY_PROP_STATUS,
69 POWER_SUPPLY_PROP_VOLTAGE_NOW,
70};
71
61static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = { 72static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
62 POWER_SUPPLY_USB_TYPE_UNKNOWN, 73 POWER_SUPPLY_USB_TYPE_UNKNOWN,
63 POWER_SUPPLY_USB_TYPE_SDP, 74 POWER_SUPPLY_USB_TYPE_SDP,
@@ -69,6 +80,11 @@ static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
69 POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID 80 POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID
70}; 81};
71 82
83static bool cros_usbpd_charger_port_is_dedicated(struct port_data *port)
84{
85 return port->port_number >= port->charger->num_usbpd_ports;
86}
87
72static int cros_usbpd_charger_ec_command(struct charger_data *charger, 88static int cros_usbpd_charger_ec_command(struct charger_data *charger,
73 unsigned int version, 89 unsigned int version,
74 unsigned int command, 90 unsigned int command,
@@ -103,6 +119,23 @@ static int cros_usbpd_charger_ec_command(struct charger_data *charger,
103 119
104static int cros_usbpd_charger_get_num_ports(struct charger_data *charger) 120static int cros_usbpd_charger_get_num_ports(struct charger_data *charger)
105{ 121{
122 struct ec_response_charge_port_count resp;
123 int ret;
124
125 ret = cros_usbpd_charger_ec_command(charger, 0,
126 EC_CMD_CHARGE_PORT_COUNT,
127 NULL, 0, &resp, sizeof(resp));
128 if (ret < 0) {
129 dev_err(charger->dev,
130 "Unable to get the number of ports (err:0x%x)\n", ret);
131 return ret;
132 }
133
134 return resp.port_count;
135}
136
137static int cros_usbpd_charger_get_usbpd_num_ports(struct charger_data *charger)
138{
106 struct ec_response_usb_pd_ports resp; 139 struct ec_response_usb_pd_ports resp;
107 int ret; 140 int ret;
108 141
@@ -246,7 +279,10 @@ static int cros_usbpd_charger_get_power_info(struct port_data *port)
246 port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP; 279 port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
247 } 280 }
248 281
249 port->psy_desc.type = POWER_SUPPLY_TYPE_USB; 282 if (cros_usbpd_charger_port_is_dedicated(port))
283 port->psy_desc.type = POWER_SUPPLY_TYPE_MAINS;
284 else
285 port->psy_desc.type = POWER_SUPPLY_TYPE_USB;
250 286
251 dev_dbg(dev, 287 dev_dbg(dev,
252 "Port %d: type=%d vmax=%d vnow=%d cmax=%d clim=%d pmax=%d\n", 288 "Port %d: type=%d vmax=%d vnow=%d cmax=%d clim=%d pmax=%d\n",
@@ -281,7 +317,8 @@ static int cros_usbpd_charger_get_port_status(struct port_data *port,
281 if (ret < 0) 317 if (ret < 0)
282 return ret; 318 return ret;
283 319
284 ret = cros_usbpd_charger_get_discovery_info(port); 320 if (!cros_usbpd_charger_port_is_dedicated(port))
321 ret = cros_usbpd_charger_get_discovery_info(port);
285 port->last_update = jiffies; 322 port->last_update = jiffies;
286 323
287 return ret; 324 return ret;
@@ -378,12 +415,10 @@ static int cros_usbpd_charger_ec_event(struct notifier_block *nb,
378{ 415{
379 struct cros_ec_device *ec_device; 416 struct cros_ec_device *ec_device;
380 struct charger_data *charger; 417 struct charger_data *charger;
381 struct device *dev;
382 u32 host_event; 418 u32 host_event;
383 419
384 charger = container_of(nb, struct charger_data, notifier); 420 charger = container_of(nb, struct charger_data, notifier);
385 ec_device = charger->ec_device; 421 ec_device = charger->ec_device;
386 dev = charger->dev;
387 422
388 host_event = cros_ec_get_host_event(ec_device); 423 host_event = cros_ec_get_host_event(ec_device);
389 if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU)) { 424 if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU)) {
@@ -426,17 +461,56 @@ static int cros_usbpd_charger_probe(struct platform_device *pd)
426 461
427 platform_set_drvdata(pd, charger); 462 platform_set_drvdata(pd, charger);
428 463
464 /*
465 * We need to know the number of USB PD ports in order to know whether
466 * there is a dedicated port. The dedicated port will always be
467 * after the USB PD ports, and there should be only one.
468 */
469 charger->num_usbpd_ports =
470 cros_usbpd_charger_get_usbpd_num_ports(charger);
471 if (charger->num_usbpd_ports <= 0) {
472 /*
473 * This can happen on a system that doesn't support USB PD.
474 * Log a message, but no need to warn.
475 */
476 dev_info(dev, "No USB PD charging ports found\n");
477 }
478
429 charger->num_charger_ports = cros_usbpd_charger_get_num_ports(charger); 479 charger->num_charger_ports = cros_usbpd_charger_get_num_ports(charger);
430 if (charger->num_charger_ports <= 0) { 480 if (charger->num_charger_ports < 0) {
431 /* 481 /*
432 * This can happen on a system that doesn't support USB PD. 482 * This can happen on a system that doesn't support USB PD.
433 * Log a message, but no need to warn. 483 * Log a message, but no need to warn.
484 * Older ECs do not support the above command, in that case
485 * let's set up the number of charger ports equal to the number
486 * of USB PD ports
487 */
488 dev_info(dev, "Could not get charger port count\n");
489 charger->num_charger_ports = charger->num_usbpd_ports;
490 }
491
492 if (charger->num_charger_ports <= 0) {
493 /*
494 * This can happen on a system that doesn't support USB PD and
495 * doesn't have a dedicated port.
496 * Log a message, but no need to warn.
434 */ 497 */
435 dev_info(dev, "No charging ports found\n"); 498 dev_info(dev, "No charging ports found\n");
436 ret = -ENODEV; 499 ret = -ENODEV;
437 goto fail_nowarn; 500 goto fail_nowarn;
438 } 501 }
439 502
503 /*
504 * Sanity checks on the number of ports:
505 * there should be at most 1 dedicated port
506 */
507 if (charger->num_charger_ports < charger->num_usbpd_ports ||
508 charger->num_charger_ports > (charger->num_usbpd_ports + 1)) {
509 dev_err(dev, "Unexpected number of charge port count\n");
510 ret = -EPROTO;
511 goto fail_nowarn;
512 }
513
440 for (i = 0; i < charger->num_charger_ports; i++) { 514 for (i = 0; i < charger->num_charger_ports; i++) {
441 struct power_supply_config psy_cfg = {}; 515 struct power_supply_config psy_cfg = {};
442 516
@@ -448,22 +522,33 @@ static int cros_usbpd_charger_probe(struct platform_device *pd)
448 522
449 port->charger = charger; 523 port->charger = charger;
450 port->port_number = i; 524 port->port_number = i;
451 sprintf(port->name, CHARGER_DIR_NAME, i);
452 525
453 psy_desc = &port->psy_desc; 526 psy_desc = &port->psy_desc;
454 psy_desc->name = port->name;
455 psy_desc->type = POWER_SUPPLY_TYPE_USB;
456 psy_desc->get_property = cros_usbpd_charger_get_prop; 527 psy_desc->get_property = cros_usbpd_charger_get_prop;
457 psy_desc->external_power_changed = 528 psy_desc->external_power_changed =
458 cros_usbpd_charger_power_changed; 529 cros_usbpd_charger_power_changed;
459 psy_desc->properties = cros_usbpd_charger_props;
460 psy_desc->num_properties =
461 ARRAY_SIZE(cros_usbpd_charger_props);
462 psy_desc->usb_types = cros_usbpd_charger_usb_types;
463 psy_desc->num_usb_types =
464 ARRAY_SIZE(cros_usbpd_charger_usb_types);
465 psy_cfg.drv_data = port; 530 psy_cfg.drv_data = port;
466 531
532 if (cros_usbpd_charger_port_is_dedicated(port)) {
533 sprintf(port->name, CHARGER_DEDICATED_DIR_NAME);
534 psy_desc->type = POWER_SUPPLY_TYPE_MAINS;
535 psy_desc->properties =
536 cros_usbpd_dedicated_charger_props;
537 psy_desc->num_properties =
538 ARRAY_SIZE(cros_usbpd_dedicated_charger_props);
539 } else {
540 sprintf(port->name, CHARGER_USBPD_DIR_NAME, i);
541 psy_desc->type = POWER_SUPPLY_TYPE_USB;
542 psy_desc->properties = cros_usbpd_charger_props;
543 psy_desc->num_properties =
544 ARRAY_SIZE(cros_usbpd_charger_props);
545 psy_desc->usb_types = cros_usbpd_charger_usb_types;
546 psy_desc->num_usb_types =
547 ARRAY_SIZE(cros_usbpd_charger_usb_types);
548 }
549
550 psy_desc->name = port->name;
551
467 psy = devm_power_supply_register_no_ws(dev, psy_desc, 552 psy = devm_power_supply_register_no_ws(dev, psy_desc,
468 &psy_cfg); 553 &psy_cfg);
469 if (IS_ERR(psy)) { 554 if (IS_ERR(psy)) {
diff --git a/drivers/power/supply/ds2780_battery.c b/drivers/power/supply/ds2780_battery.c
index 370e9109342b..cad14ba1b648 100644
--- a/drivers/power/supply/ds2780_battery.c
+++ b/drivers/power/supply/ds2780_battery.c
@@ -829,5 +829,5 @@ module_platform_driver(ds2780_battery_driver);
829 829
830MODULE_LICENSE("GPL"); 830MODULE_LICENSE("GPL");
831MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>"); 831MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>");
832MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver"); 832MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauge IC driver");
833MODULE_ALIAS("platform:ds2780-battery"); 833MODULE_ALIAS("platform:ds2780-battery");
diff --git a/drivers/power/supply/ds2781_battery.c b/drivers/power/supply/ds2781_battery.c
index d1b5a19aae7c..5e794607f732 100644
--- a/drivers/power/supply/ds2781_battery.c
+++ b/drivers/power/supply/ds2781_battery.c
@@ -829,6 +829,6 @@ module_platform_driver(ds2781_battery_driver);
829 829
830MODULE_LICENSE("GPL"); 830MODULE_LICENSE("GPL");
831MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>"); 831MODULE_AUTHOR("Renata Sayakhova <renata@oktetlabs.ru>");
832MODULE_DESCRIPTION("Maxim/Dallas DS2781 Stand-Alone Fuel Gauage IC driver"); 832MODULE_DESCRIPTION("Maxim/Dallas DS2781 Stand-Alone Fuel Gauge IC driver");
833MODULE_ALIAS("platform:ds2781-battery"); 833MODULE_ALIAS("platform:ds2781-battery");
834 834
diff --git a/drivers/power/supply/ds2782_battery.c b/drivers/power/supply/ds2782_battery.c
index a1b7e0592245..019c58493e3d 100644
--- a/drivers/power/supply/ds2782_battery.c
+++ b/drivers/power/supply/ds2782_battery.c
@@ -471,5 +471,5 @@ static struct i2c_driver ds278x_battery_driver = {
471module_i2c_driver(ds278x_battery_driver); 471module_i2c_driver(ds278x_battery_driver);
472 472
473MODULE_AUTHOR("Ryan Mallon"); 473MODULE_AUTHOR("Ryan Mallon");
474MODULE_DESCRIPTION("Maxim/Dallas DS2782 Stand-Alone Fuel Gauage IC driver"); 474MODULE_DESCRIPTION("Maxim/Dallas DS2782 Stand-Alone Fuel Gauge IC driver");
475MODULE_LICENSE("GPL"); 475MODULE_LICENSE("GPL");
diff --git a/drivers/power/supply/max14577_charger.c b/drivers/power/supply/max14577_charger.c
index 449fc56f09eb..8a59feac6468 100644
--- a/drivers/power/supply/max14577_charger.c
+++ b/drivers/power/supply/max14577_charger.c
@@ -1,19 +1,9 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max14577_charger.c - Battery charger driver for the Maxim 14577/77836 2//
3 * 3// max14577_charger.c - Battery charger driver for the Maxim 14577/77836
4 * Copyright (C) 2013,2014 Samsung Electronics 4//
5 * Krzysztof Kozlowski <krzk@kernel.org> 5// Copyright (C) 2013,2014 Samsung Electronics
6 * 6// Krzysztof Kozlowski <krzk@kernel.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17 7
18#include <linux/module.h> 8#include <linux/module.h>
19#include <linux/platform_device.h> 9#include <linux/platform_device.h>
diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c
index 33c40f79d23d..91cafc7bed30 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -1,14 +1,10 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * max17040_battery.c 2//
3 * fuel-gauge systems for lithium-ion (Li+) batteries 3// max17040_battery.c
4 * 4// fuel-gauge systems for lithium-ion (Li+) batteries
5 * Copyright (C) 2009 Samsung Electronics 5//
6 * Minkyu Kang <mk7.kang@samsung.com> 6// Copyright (C) 2009 Samsung Electronics
7 * 7// Minkyu Kang <mk7.kang@samsung.com>
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 8
13#include <linux/module.h> 9#include <linux/module.h>
14#include <linux/init.h> 10#include <linux/init.h>
diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c
index 1a568df383db..2a8d75e5e930 100644
--- a/drivers/power/supply/max17042_battery.c
+++ b/drivers/power/supply/max17042_battery.c
@@ -1,26 +1,12 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * Fuel gauge driver for Maxim 17042 / 8966 / 8997 2//
3 * Note that Maxim 8966 and 8997 are mfd and this is its subdevice. 3// Fuel gauge driver for Maxim 17042 / 8966 / 8997
4 * 4// Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
5 * Copyright (C) 2011 Samsung Electronics 5//
6 * MyungJoo Ham <myungjoo.ham@samsung.com> 6// Copyright (C) 2011 Samsung Electronics
7 * 7// MyungJoo Ham <myungjoo.ham@samsung.com>
8 * This program is free software; you can redistribute it and/or modify 8//
9 * it under the terms of the GNU General Public License as published by 9// This driver is based on max17040_battery.c
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * This driver is based on max17040_battery.c
23 */
24 10
25#include <linux/acpi.h> 11#include <linux/acpi.h>
26#include <linux/init.h> 12#include <linux/init.h>
diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c
index 749c7926e3c9..a2c5c9858639 100644
--- a/drivers/power/supply/max77693_charger.c
+++ b/drivers/power/supply/max77693_charger.c
@@ -1,19 +1,9 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max77693_charger.c - Battery charger driver for the Maxim 77693 2//
3 * 3// max77693_charger.c - Battery charger driver for the Maxim 77693
4 * Copyright (C) 2014 Samsung Electronics 4//
5 * Krzysztof Kozlowski <krzk@kernel.org> 5// Copyright (C) 2014 Samsung Electronics
6 * 6// Krzysztof Kozlowski <krzk@kernel.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17 7
18#include <linux/module.h> 8#include <linux/module.h>
19#include <linux/platform_device.h> 9#include <linux/platform_device.h>
diff --git a/drivers/power/supply/max8925_power.c b/drivers/power/supply/max8925_power.c
index 3b94620ce5c1..39b4d5b6ac39 100644
--- a/drivers/power/supply/max8925_power.c
+++ b/drivers/power/supply/max8925_power.c
@@ -124,6 +124,7 @@ static irqreturn_t max8925_charger_handler(int irq, void *data)
124 case MAX8925_IRQ_VCHG_THM_OK_F: 124 case MAX8925_IRQ_VCHG_THM_OK_F:
125 /* Battery is not ready yet */ 125 /* Battery is not ready yet */
126 dev_dbg(chip->dev, "Battery temperature is out of range\n"); 126 dev_dbg(chip->dev, "Battery temperature is out of range\n");
127 /* Fall through */
127 case MAX8925_IRQ_VCHG_DC_OVP: 128 case MAX8925_IRQ_VCHG_DC_OVP:
128 dev_dbg(chip->dev, "Error detection\n"); 129 dev_dbg(chip->dev, "Error detection\n");
129 __set_charger(info, 0); 130 __set_charger(info, 0);
diff --git a/drivers/power/supply/max8997_charger.c b/drivers/power/supply/max8997_charger.c
index c73fb4221695..f5e84cd47924 100644
--- a/drivers/power/supply/max8997_charger.c
+++ b/drivers/power/supply/max8997_charger.c
@@ -1,23 +1,9 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max8997_charger.c - Power supply consumer driver for the Maxim 8997/8966 2//
3 * 3// max8997_charger.c - Power supply consumer driver for the Maxim 8997/8966
4 * Copyright (C) 2011 Samsung Electronics 4//
5 * MyungJoo Ham <myungjoo.ham@samsung.com> 5// Copyright (C) 2011 Samsung Electronics
6 * 6// MyungJoo Ham <myungjoo.ham@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 7
22#include <linux/err.h> 8#include <linux/err.h>
23#include <linux/module.h> 9#include <linux/module.h>
diff --git a/drivers/power/supply/max8998_charger.c b/drivers/power/supply/max8998_charger.c
index cad7d1a8feec..9a926c7c0f22 100644
--- a/drivers/power/supply/max8998_charger.c
+++ b/drivers/power/supply/max8998_charger.c
@@ -1,23 +1,9 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max8998_charger.c - Power supply consumer driver for the Maxim 8998/LP3974 2//
3 * 3// max8998_charger.c - Power supply consumer driver for the Maxim 8998/LP3974
4 * Copyright (C) 2009-2010 Samsung Electronics 4//
5 * MyungJoo Ham <myungjoo.ham@samsung.com> 5// Copyright (C) 2009-2010 Samsung Electronics
6 * 6// MyungJoo Ham <myungjoo.ham@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 7
22#include <linux/err.h> 8#include <linux/err.h>
23#include <linux/module.h> 9#include <linux/module.h>
@@ -86,7 +72,7 @@ static const struct power_supply_desc max8998_battery_desc = {
86static int max8998_battery_probe(struct platform_device *pdev) 72static int max8998_battery_probe(struct platform_device *pdev)
87{ 73{
88 struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); 74 struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
89 struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); 75 struct max8998_platform_data *pdata = iodev->pdata;
90 struct power_supply_config psy_cfg = {}; 76 struct power_supply_config psy_cfg = {};
91 struct max8998_battery_data *max8998; 77 struct max8998_battery_data *max8998;
92 struct i2c_client *i2c; 78 struct i2c_client *i2c;
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index 6170ed8b6854..dce24f596160 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -131,7 +131,8 @@ static ssize_t power_supply_show_property(struct device *dev,
131 dev_dbg(dev, "driver has no data for `%s' property\n", 131 dev_dbg(dev, "driver has no data for `%s' property\n",
132 attr->attr.name); 132 attr->attr.name);
133 else if (ret != -ENODEV && ret != -EAGAIN) 133 else if (ret != -ENODEV && ret != -EAGAIN)
134 dev_err(dev, "driver failed to report `%s' property: %zd\n", 134 dev_err_ratelimited(dev,
135 "driver failed to report `%s' property: %zd\n",
135 attr->attr.name, ret); 136 attr->attr.name, ret);
136 return ret; 137 return ret;
137 } 138 }
diff --git a/drivers/power/supply/sc2731_charger.c b/drivers/power/supply/sc2731_charger.c
new file mode 100644
index 000000000000..525a820537bf
--- /dev/null
+++ b/drivers/power/supply/sc2731_charger.c
@@ -0,0 +1,504 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 Spreadtrum Communications Inc.
3
4#include <linux/module.h>
5#include <linux/platform_device.h>
6#include <linux/power_supply.h>
7#include <linux/usb/phy.h>
8#include <linux/regmap.h>
9#include <linux/notifier.h>
10#include <linux/of.h>
11
12/* PMIC global registers definition */
13#define SC2731_CHARGE_STATUS 0xedc
14#define SC2731_CHARGE_FULL BIT(4)
15#define SC2731_MODULE_EN1 0xc0c
16#define SC2731_CHARGE_EN BIT(5)
17
18/* SC2731 switch charger registers definition */
19#define SC2731_CHG_CFG0 0x0
20#define SC2731_CHG_CFG1 0x4
21#define SC2731_CHG_CFG2 0x8
22#define SC2731_CHG_CFG3 0xc
23#define SC2731_CHG_CFG4 0x10
24#define SC2731_CHG_CFG5 0x28
25
26/* SC2731_CHG_CFG0 register definition */
27#define SC2731_PRECHG_RNG_SHIFT 11
28#define SC2731_PRECHG_RNG_MASK GENMASK(12, 11)
29
30#define SC2731_TERMINATION_VOL_MASK GENMASK(2, 1)
31#define SC2731_TERMINATION_VOL_SHIFT 1
32#define SC2731_TERMINATION_VOL_CAL_MASK GENMASK(8, 3)
33#define SC2731_TERMINATION_VOL_CAL_SHIFT 3
34#define SC2731_TERMINATION_CUR_MASK GENMASK(2, 0)
35
36#define SC2731_CC_EN BIT(13)
37#define SC2731_CHARGER_PD BIT(0)
38
39/* SC2731_CHG_CFG1 register definition */
40#define SC2731_CUR_MASK GENMASK(5, 0)
41
42/* SC2731_CHG_CFG5 register definition */
43#define SC2731_CUR_LIMIT_SHIFT 8
44#define SC2731_CUR_LIMIT_MASK GENMASK(9, 8)
45
46/* Default current definition (unit is mA) */
47#define SC2731_CURRENT_LIMIT_100 100
48#define SC2731_CURRENT_LIMIT_500 500
49#define SC2731_CURRENT_LIMIT_900 900
50#define SC2731_CURRENT_LIMIT_2000 2000
51#define SC2731_CURRENT_PRECHG 450
52#define SC2731_CURRENT_STEP 50
53
54struct sc2731_charger_info {
55 struct device *dev;
56 struct regmap *regmap;
57 struct usb_phy *usb_phy;
58 struct notifier_block usb_notify;
59 struct power_supply *psy_usb;
60 struct mutex lock;
61 bool charging;
62 u32 base;
63};
64
65static void sc2731_charger_stop_charge(struct sc2731_charger_info *info)
66{
67 regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
68 SC2731_CC_EN, 0);
69
70 regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
71 SC2731_CHARGER_PD, SC2731_CHARGER_PD);
72}
73
74static int sc2731_charger_start_charge(struct sc2731_charger_info *info)
75{
76 int ret;
77
78 /* Enable charger constant current mode */
79 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
80 SC2731_CC_EN, SC2731_CC_EN);
81 if (ret)
82 return ret;
83
84 /* Start charging */
85 return regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
86 SC2731_CHARGER_PD, 0);
87}
88
89static int sc2731_charger_set_current_limit(struct sc2731_charger_info *info,
90 u32 limit)
91{
92 u32 val;
93
94 if (limit <= SC2731_CURRENT_LIMIT_100)
95 val = 0;
96 else if (limit <= SC2731_CURRENT_LIMIT_500)
97 val = 3;
98 else if (limit <= SC2731_CURRENT_LIMIT_900)
99 val = 2;
100 else
101 val = 1;
102
103 return regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG5,
104 SC2731_CUR_LIMIT_MASK,
105 val << SC2731_CUR_LIMIT_SHIFT);
106}
107
108static int sc2731_charger_set_current(struct sc2731_charger_info *info, u32 cur)
109{
110 u32 val;
111 int ret;
112
113 if (cur > SC2731_CURRENT_LIMIT_2000)
114 cur = SC2731_CURRENT_LIMIT_2000;
115 else if (cur < SC2731_CURRENT_PRECHG)
116 cur = SC2731_CURRENT_PRECHG;
117
118 /* Calculate the step value, each step is 50 mA */
119 val = (cur - SC2731_CURRENT_PRECHG) / SC2731_CURRENT_STEP;
120
121 /* Set pre-charge current as 450 mA */
122 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
123 SC2731_PRECHG_RNG_MASK,
124 0x3 << SC2731_PRECHG_RNG_SHIFT);
125 if (ret)
126 return ret;
127
128 return regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG1,
129 SC2731_CUR_MASK, val);
130}
131
132static int sc2731_charger_get_status(struct sc2731_charger_info *info)
133{
134 u32 val;
135 int ret;
136
137 ret = regmap_read(info->regmap, SC2731_CHARGE_STATUS, &val);
138 if (ret)
139 return ret;
140
141 if (val & SC2731_CHARGE_FULL)
142 return POWER_SUPPLY_STATUS_FULL;
143
144 return POWER_SUPPLY_STATUS_CHARGING;
145}
146
147static int sc2731_charger_get_current(struct sc2731_charger_info *info,
148 u32 *cur)
149{
150 int ret;
151 u32 val;
152
153 ret = regmap_read(info->regmap, info->base + SC2731_CHG_CFG1, &val);
154 if (ret)
155 return ret;
156
157 val &= SC2731_CUR_MASK;
158 *cur = val * SC2731_CURRENT_STEP + SC2731_CURRENT_PRECHG;
159
160 return 0;
161}
162
163static int sc2731_charger_get_current_limit(struct sc2731_charger_info *info,
164 u32 *cur)
165{
166 int ret;
167 u32 val;
168
169 ret = regmap_read(info->regmap, info->base + SC2731_CHG_CFG5, &val);
170 if (ret)
171 return ret;
172
173 val = (val & SC2731_CUR_LIMIT_MASK) >> SC2731_CUR_LIMIT_SHIFT;
174
175 switch (val) {
176 case 0:
177 *cur = SC2731_CURRENT_LIMIT_100;
178 break;
179
180 case 1:
181 *cur = SC2731_CURRENT_LIMIT_2000;
182 break;
183
184 case 2:
185 *cur = SC2731_CURRENT_LIMIT_900;
186 break;
187
188 case 3:
189 *cur = SC2731_CURRENT_LIMIT_500;
190 break;
191
192 default:
193 return -EINVAL;
194 }
195
196 return 0;
197}
198
199static int
200sc2731_charger_usb_set_property(struct power_supply *psy,
201 enum power_supply_property psp,
202 const union power_supply_propval *val)
203{
204 struct sc2731_charger_info *info = power_supply_get_drvdata(psy);
205 int ret;
206
207 mutex_lock(&info->lock);
208
209 if (!info->charging) {
210 mutex_unlock(&info->lock);
211 return -ENODEV;
212 }
213
214 switch (psp) {
215 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
216 ret = sc2731_charger_set_current(info, val->intval / 1000);
217 if (ret < 0)
218 dev_err(info->dev, "set charge current failed\n");
219 break;
220
221 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
222 ret = sc2731_charger_set_current_limit(info,
223 val->intval / 1000);
224 if (ret < 0)
225 dev_err(info->dev, "set input current limit failed\n");
226 break;
227
228 default:
229 ret = -EINVAL;
230 }
231
232 mutex_unlock(&info->lock);
233 return ret;
234}
235
236static int sc2731_charger_usb_get_property(struct power_supply *psy,
237 enum power_supply_property psp,
238 union power_supply_propval *val)
239{
240 struct sc2731_charger_info *info = power_supply_get_drvdata(psy);
241 int ret = 0;
242 u32 cur;
243
244 mutex_lock(&info->lock);
245
246 switch (psp) {
247 case POWER_SUPPLY_PROP_STATUS:
248 if (info->charging)
249 val->intval = sc2731_charger_get_status(info);
250 else
251 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
252 break;
253
254 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
255 if (!info->charging) {
256 val->intval = 0;
257 } else {
258 ret = sc2731_charger_get_current(info, &cur);
259 if (ret)
260 goto out;
261
262 val->intval = cur * 1000;
263 }
264 break;
265
266 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
267 if (!info->charging) {
268 val->intval = 0;
269 } else {
270 ret = sc2731_charger_get_current_limit(info, &cur);
271 if (ret)
272 goto out;
273
274 val->intval = cur * 1000;
275 }
276 break;
277
278 default:
279 ret = -EINVAL;
280 }
281
282out:
283 mutex_unlock(&info->lock);
284 return ret;
285}
286
287static int sc2731_charger_property_is_writeable(struct power_supply *psy,
288 enum power_supply_property psp)
289{
290 int ret;
291
292 switch (psp) {
293 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
294 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
295 ret = 1;
296 break;
297
298 default:
299 ret = 0;
300 }
301
302 return ret;
303}
304
305static enum power_supply_property sc2731_usb_props[] = {
306 POWER_SUPPLY_PROP_STATUS,
307 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
308 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
309};
310
311static const struct power_supply_desc sc2731_charger_desc = {
312 .name = "sc2731_charger",
313 .type = POWER_SUPPLY_TYPE_USB,
314 .properties = sc2731_usb_props,
315 .num_properties = ARRAY_SIZE(sc2731_usb_props),
316 .get_property = sc2731_charger_usb_get_property,
317 .set_property = sc2731_charger_usb_set_property,
318 .property_is_writeable = sc2731_charger_property_is_writeable,
319};
320
321static int sc2731_charger_usb_change(struct notifier_block *nb,
322 unsigned long limit, void *data)
323{
324 struct sc2731_charger_info *info =
325 container_of(nb, struct sc2731_charger_info, usb_notify);
326 int ret = 0;
327
328 mutex_lock(&info->lock);
329
330 if (limit > 0) {
331 /* set current limitation and start to charge */
332 ret = sc2731_charger_set_current_limit(info, limit);
333 if (ret)
334 goto out;
335
336 ret = sc2731_charger_set_current(info, limit);
337 if (ret)
338 goto out;
339
340 ret = sc2731_charger_start_charge(info);
341 if (ret)
342 goto out;
343
344 info->charging = true;
345 } else {
346 /* Stop charging */
347 info->charging = false;
348 sc2731_charger_stop_charge(info);
349 }
350
351out:
352 mutex_unlock(&info->lock);
353 return ret;
354}
355
356static int sc2731_charger_hw_init(struct sc2731_charger_info *info)
357{
358 struct power_supply_battery_info bat_info = { };
359 u32 term_currrent, term_voltage, cur_val, vol_val;
360 int ret;
361
362 /* Enable charger module */
363 ret = regmap_update_bits(info->regmap, SC2731_MODULE_EN1,
364 SC2731_CHARGE_EN, SC2731_CHARGE_EN);
365 if (ret)
366 return ret;
367
368 ret = power_supply_get_battery_info(info->psy_usb, &bat_info);
369 if (ret) {
370 dev_warn(info->dev, "no battery information is supplied\n");
371
372 /*
373 * If no battery information is supplied, we should set
374 * default charge termination current to 120 mA, and default
375 * charge termination voltage to 4.35V.
376 */
377 cur_val = 0x2;
378 vol_val = 0x1;
379 } else {
380 term_currrent = bat_info.charge_term_current_ua / 1000;
381
382 if (term_currrent <= 90)
383 cur_val = 0;
384 else if (term_currrent >= 265)
385 cur_val = 0x7;
386 else
387 cur_val = ((term_currrent - 90) / 25) + 1;
388
389 term_voltage = bat_info.constant_charge_voltage_max_uv / 1000;
390
391 if (term_voltage > 4500)
392 term_voltage = 4500;
393
394 if (term_voltage > 4200)
395 vol_val = (term_voltage - 4200) / 100;
396 else
397 vol_val = 0;
398 }
399
400 /* Set charge termination current */
401 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG2,
402 SC2731_TERMINATION_CUR_MASK, cur_val);
403 if (ret)
404 goto error;
405
406 /* Set charge termination voltage */
407 ret = regmap_update_bits(info->regmap, info->base + SC2731_CHG_CFG0,
408 SC2731_TERMINATION_VOL_MASK |
409 SC2731_TERMINATION_VOL_CAL_MASK,
410 (vol_val << SC2731_TERMINATION_VOL_SHIFT) |
411 (0x6 << SC2731_TERMINATION_VOL_CAL_SHIFT));
412 if (ret)
413 goto error;
414
415 return 0;
416
417error:
418 regmap_update_bits(info->regmap, SC2731_MODULE_EN1, SC2731_CHARGE_EN, 0);
419 return ret;
420}
421
422static int sc2731_charger_probe(struct platform_device *pdev)
423{
424 struct device_node *np = pdev->dev.of_node;
425 struct sc2731_charger_info *info;
426 struct power_supply_config charger_cfg = { };
427 int ret;
428
429 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
430 if (!info)
431 return -ENOMEM;
432
433 mutex_init(&info->lock);
434 info->dev = &pdev->dev;
435
436 info->regmap = dev_get_regmap(pdev->dev.parent, NULL);
437 if (!info->regmap) {
438 dev_err(&pdev->dev, "failed to get charger regmap\n");
439 return -ENODEV;
440 }
441
442 ret = of_property_read_u32(np, "reg", &info->base);
443 if (ret) {
444 dev_err(&pdev->dev, "failed to get register address\n");
445 return -ENODEV;
446 }
447
448 charger_cfg.drv_data = info;
449 charger_cfg.of_node = np;
450 info->psy_usb = devm_power_supply_register(&pdev->dev,
451 &sc2731_charger_desc,
452 &charger_cfg);
453 if (IS_ERR(info->psy_usb)) {
454 dev_err(&pdev->dev, "failed to register power supply\n");
455 return PTR_ERR(info->psy_usb);
456 }
457
458 ret = sc2731_charger_hw_init(info);
459 if (ret)
460 return ret;
461
462 info->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "phys", 0);
463 if (IS_ERR(info->usb_phy)) {
464 dev_err(&pdev->dev, "failed to find USB phy\n");
465 return PTR_ERR(info->usb_phy);
466 }
467
468 info->usb_notify.notifier_call = sc2731_charger_usb_change;
469 ret = usb_register_notifier(info->usb_phy, &info->usb_notify);
470 if (ret) {
471 dev_err(&pdev->dev, "failed to register notifier: %d\n", ret);
472 return ret;
473 }
474
475 return 0;
476}
477
478static int sc2731_charger_remove(struct platform_device *pdev)
479{
480 struct sc2731_charger_info *info = platform_get_drvdata(pdev);
481
482 usb_unregister_notifier(info->usb_phy, &info->usb_notify);
483
484 return 0;
485}
486
487static const struct of_device_id sc2731_charger_of_match[] = {
488 { .compatible = "sprd,sc2731-charger", },
489 { }
490};
491
492static struct platform_driver sc2731_charger_driver = {
493 .driver = {
494 .name = "sc2731-charger",
495 .of_match_table = sc2731_charger_of_match,
496 },
497 .probe = sc2731_charger_probe,
498 .remove = sc2731_charger_remove,
499};
500
501module_platform_driver(sc2731_charger_driver);
502
503MODULE_DESCRIPTION("Spreadtrum SC2731 Charger Driver");
504MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
index bbcaee56db9d..80582c8f98fa 100644
--- a/drivers/power/supply/twl4030_charger.c
+++ b/drivers/power/supply/twl4030_charger.c
@@ -420,7 +420,8 @@ static void twl4030_current_worker(struct work_struct *data)
420 420
421 if (v < USB_MIN_VOLT) { 421 if (v < USB_MIN_VOLT) {
422 /* Back up and stop adjusting. */ 422 /* Back up and stop adjusting. */
423 bci->usb_cur -= USB_CUR_STEP; 423 if (bci->usb_cur >= USB_CUR_STEP)
424 bci->usb_cur -= USB_CUR_STEP;
424 bci->usb_cur_target = bci->usb_cur; 425 bci->usb_cur_target = bci->usb_cur;
425 } else if (bci->usb_cur >= bci->usb_cur_target || 426 } else if (bci->usb_cur >= bci->usb_cur_target ||
426 bci->usb_cur + USB_CUR_STEP > USB_MAX_CURRENT) { 427 bci->usb_cur + USB_CUR_STEP > USB_MAX_CURRENT) {
@@ -439,6 +440,7 @@ static void twl4030_current_worker(struct work_struct *data)
439static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable) 440static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
440{ 441{
441 int ret; 442 int ret;
443 u32 reg;
442 444
443 if (bci->usb_mode == CHARGE_OFF) 445 if (bci->usb_mode == CHARGE_OFF)
444 enable = false; 446 enable = false;
@@ -452,14 +454,38 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
452 bci->usb_enabled = 1; 454 bci->usb_enabled = 1;
453 } 455 }
454 456
455 if (bci->usb_mode == CHARGE_AUTO) 457 if (bci->usb_mode == CHARGE_AUTO) {
458 /* Enable interrupts now. */
459 reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC |
460 TWL4030_TBATOR2 | TWL4030_TBATOR1 |
461 TWL4030_BATSTS);
462 ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
463 TWL4030_INTERRUPTS_BCIIMR1A);
464 if (ret < 0) {
465 dev_err(bci->dev,
466 "failed to unmask interrupts: %d\n",
467 ret);
468 return ret;
469 }
456 /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */ 470 /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
457 ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB); 471 ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
472 }
458 473
459 /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */ 474 /* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
460 ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0, 475 ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0,
461 TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4); 476 TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4);
462 if (bci->usb_mode == CHARGE_LINEAR) { 477 if (bci->usb_mode == CHARGE_LINEAR) {
478 /* Enable interrupts now. */
479 reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_TBATOR2 |
480 TWL4030_TBATOR1 | TWL4030_BATSTS);
481 ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg,
482 TWL4030_INTERRUPTS_BCIIMR1A);
483 if (ret < 0) {
484 dev_err(bci->dev,
485 "failed to unmask interrupts: %d\n",
486 ret);
487 return ret;
488 }
463 twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0); 489 twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0);
464 /* Watch dog key: WOVF acknowledge */ 490 /* Watch dog key: WOVF acknowledge */
465 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33, 491 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33,
diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
index 7690f0793965..5fd0e429f472 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -3103,6 +3103,16 @@ struct ec_params_usb_pd_info_request {
3103 uint8_t port; 3103 uint8_t port;
3104} __packed; 3104} __packed;
3105 3105
3106/*
3107 * This command will return the number of USB PD charge port + the number
3108 * of dedicated port present.
3109 * EC_CMD_USB_PD_PORTS does NOT include the dedicated ports
3110 */
3111#define EC_CMD_CHARGE_PORT_COUNT 0x0105
3112struct ec_response_charge_port_count {
3113 uint8_t port_count;
3114} __packed;
3115
3106/* Read USB-PD Device discovery info */ 3116/* Read USB-PD Device discovery info */
3107#define EC_CMD_USB_PD_DISCOVERY 0x0113 3117#define EC_CMD_USB_PD_DISCOVERY 0x0113
3108struct ec_params_usb_pd_discovery_entry { 3118struct ec_params_usb_pd_discovery_entry {
diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
index d6355f49fbae..507c5e214c42 100644
--- a/include/linux/power/bq27xxx_battery.h
+++ b/include/linux/power/bq27xxx_battery.h
@@ -24,6 +24,7 @@ enum bq27xxx_chip {
24 BQ27546, 24 BQ27546,
25 BQ27742, 25 BQ27742,
26 BQ27545, /* bq27545 */ 26 BQ27545, /* bq27545 */
27 BQ27411,
27 BQ27421, /* bq27421, bq27441, bq27621 */ 28 BQ27421, /* bq27421, bq27441, bq27621 */
28 BQ27425, 29 BQ27425,
29 BQ27426, 30 BQ27426,