aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/twl4030_charger.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index f14108844e1a..2598c588006e 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -28,10 +28,13 @@
28#define TWL4030_BCIICHG 0x08 28#define TWL4030_BCIICHG 0x08
29#define TWL4030_BCIVAC 0x0a 29#define TWL4030_BCIVAC 0x0a
30#define TWL4030_BCIVBUS 0x0c 30#define TWL4030_BCIVBUS 0x0c
31#define TWL4030_BCIMFSTS3 0x0F
31#define TWL4030_BCIMFSTS4 0x10 32#define TWL4030_BCIMFSTS4 0x10
32#define TWL4030_BCICTL1 0x23 33#define TWL4030_BCICTL1 0x23
33#define TWL4030_BB_CFG 0x12 34#define TWL4030_BB_CFG 0x12
34 35
36#define TWL4030_BCIMFSTS1 0x01
37
35#define TWL4030_BCIAUTOWEN BIT(5) 38#define TWL4030_BCIAUTOWEN BIT(5)
36#define TWL4030_CONFIG_DONE BIT(4) 39#define TWL4030_CONFIG_DONE BIT(4)
37#define TWL4030_BCIAUTOUSB BIT(1) 40#define TWL4030_BCIAUTOUSB BIT(1)
@@ -52,6 +55,9 @@
52#define TWL4030_BBISEL_500uA 0x02 55#define TWL4030_BBISEL_500uA 0x02
53#define TWL4030_BBISEL_1000uA 0x03 56#define TWL4030_BBISEL_1000uA 0x03
54 57
58#define TWL4030_BATSTSPCHG BIT(2)
59#define TWL4030_BATSTSMCHG BIT(6)
60
55/* BCI interrupts */ 61/* BCI interrupts */
56#define TWL4030_WOVF BIT(0) /* Watchdog overflow */ 62#define TWL4030_WOVF BIT(0) /* Watchdog overflow */
57#define TWL4030_TMOVF BIT(1) /* Timer overflow */ 63#define TWL4030_TMOVF BIT(1) /* Timer overflow */
@@ -145,6 +151,35 @@ static int twl4030bci_read_adc_val(u8 reg)
145} 151}
146 152
147/* 153/*
154 * Check if Battery Pack was present
155 */
156static int twl4030_is_battery_present(struct twl4030_bci *bci)
157{
158 int ret;
159 u8 val = 0;
160
161 /* Battery presence in Main charge? */
162 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val, TWL4030_BCIMFSTS3);
163 if (ret)
164 return ret;
165 if (val & TWL4030_BATSTSMCHG)
166 return 0;
167
168 /*
169 * OK, It could be that bootloader did not enable main charger,
170 * pre-charge is h/w auto. So, Battery presence in Pre-charge?
171 */
172 ret = twl_i2c_read_u8(TWL4030_MODULE_PRECHARGE, &val,
173 TWL4030_BCIMFSTS1);
174 if (ret)
175 return ret;
176 if (val & TWL4030_BATSTSPCHG)
177 return 0;
178
179 return -ENODEV;
180}
181
182/*
148 * Check if VBUS power is present 183 * Check if VBUS power is present
149 */ 184 */
150static int twl4030_bci_have_vbus(struct twl4030_bci *bci) 185static int twl4030_bci_have_vbus(struct twl4030_bci *bci)
@@ -541,8 +576,14 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
541 bci->irq_chg = platform_get_irq(pdev, 0); 576 bci->irq_chg = platform_get_irq(pdev, 0);
542 bci->irq_bci = platform_get_irq(pdev, 1); 577 bci->irq_bci = platform_get_irq(pdev, 1);
543 578
544 platform_set_drvdata(pdev, bci); 579 /* Only proceed further *IF* battery is physically present */
580 ret = twl4030_is_battery_present(bci);
581 if (ret) {
582 dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret);
583 goto fail_no_battery;
584 }
545 585
586 platform_set_drvdata(pdev, bci);
546 bci->ac.name = "twl4030_ac"; 587 bci->ac.name = "twl4030_ac";
547 bci->ac.type = POWER_SUPPLY_TYPE_MAINS; 588 bci->ac.type = POWER_SUPPLY_TYPE_MAINS;
548 bci->ac.properties = twl4030_charger_props; 589 bci->ac.properties = twl4030_charger_props;
@@ -633,6 +674,7 @@ fail_chg_irq:
633fail_register_usb: 674fail_register_usb:
634 power_supply_unregister(&bci->ac); 675 power_supply_unregister(&bci->ac);
635fail_register_ac: 676fail_register_ac:
677fail_no_battery:
636 kfree(bci); 678 kfree(bci);
637 679
638 return ret; 680 return ret;