13 #include <linux/kernel.h>
14 #include <linux/module.h>
16 #include <linux/slab.h>
21 #include <asm/div64.h>
24 #define STATUS2_CHG (1 << 2)
27 #define RESET_SW_PD (1 << 7)
30 #define PREREG1_90MA (0x0)
31 #define PREREG1_180MA (0x1)
32 #define PREREG1_450MA (0x4)
33 #define PREREG1_540MA (0x5)
34 #define PREREG1_1350MA (0xE)
35 #define PREREG1_VSYS_4_5V (3 << 4)
38 #define CC1_MODE_OFF (0)
39 #define CC1_MODE_PRECHARGE (1)
40 #define CC1_MODE_FASTCHARGE (2)
41 #define CC1_MODE_PULSECHARGE (3)
42 #define CC1_ITERM_20MA (0 << 2)
43 #define CC1_ITERM_60MA (2 << 2)
44 #define CC1_VFCHG_4_2V (9 << 4)
47 #define CC2_ICHG_100MA (0x1)
48 #define CC2_ICHG_500MA (0x9)
49 #define CC2_ICHG_1000MA (0x13)
52 #define CC3_180MIN_TIMEOUT (0x6 << 4)
53 #define CC3_270MIN_TIMEOUT (0x7 << 4)
54 #define CC3_360MIN_TIMEOUT (0xA << 4)
55 #define CC3_DISABLE_TIMEOUT (0xF << 4)
58 #define CC4_IPRE_40MA (7)
59 #define CC4_VPCHG_3_2V (3 << 4)
60 #define CC4_IFCHG_MON_EN (1 << 6)
61 #define CC4_BTEMP_MON_EN (1 << 7)
64 #define CC6_BAT_OV_EN (1 << 2)
65 #define CC6_BAT_UV_EN (1 << 3)
66 #define CC6_UV_VBAT_SET (0x3 << 6)
69 #define CC7_BAT_REM_EN (1 << 3)
70 #define CC7_IFSM_EN (1 << 7)
73 #define MEAS1_VBAT (1 << 0)
76 #define MEAS3_IBAT_EN (1 << 0)
77 #define MEAS3_CC_EN (1 << 2)
80 #define FSM_DISCHARGE 1
81 #define FSM_PRECHARGE 2
82 #define FSM_FASTCHARGE 3
84 #define PRECHARGE_THRESHOLD 3100
85 #define POWEROFF_THRESHOLD 3400
86 #define CHARGE_THRESHOLD 4000
87 #define DISCHARGE_THRESHOLD 4180
90 #define OVER_TEMP_FLAG (1 << 6)
91 #define OVTEMP_AUTORECOVER (1 << 3)
94 #define VCHG_NORMAL_LOW 4200
95 #define VCHG_NORMAL_CHECK 5800
96 #define VCHG_NORMAL_HIGH 6000
97 #define VCHG_OVP_LOW 5500
115 static char *pm860x_supplied_to[] = {
121 unsigned char buf[2];
128 *data = ((buf[0] & 0xff) << 4) | (buf[1] & 0x0f);
130 *data = ((*data & 0xfff) * 9 * 125) >> 9;
132 dev_dbg(info->
dev,
"%s, vchg: %d mv\n", __func__, *data);
146 data = (min << 5) / 1125;
148 dev_dbg(info->
dev,
"VCHG_LOWTH:%dmv, 0x%x\n", min, data);
153 data = (max << 5) / 1125;
155 dev_dbg(info->
dev,
"VCHG_HIGHTH:%dmv, 0x%x\n", max, data);
168 data = (min << 5) / 675;
170 dev_dbg(info->
dev,
"VBAT Min:%dmv, LOWTH:0x%x\n", min, data);
175 data = (max << 5) / 675;
177 dev_dbg(info->
dev,
"VBAT Max:%dmv, HIGHTH:0x%x\n", max, data);
187 set_vbatt_threshold(info, 0, 0);
283 dev_dbg(info->
dev,
"Power-off notification!\n");
290 unsigned char fsm_state[][16] = {
"init",
"discharge",
"precharge",
302 vbatt = data.intval / 1000;
311 dev_dbg(info->
dev,
"Entering FSM:%s, Charger:%s, Battery:%s, "
313 &fsm_state[info->
state][0],
314 (info->
online) ?
"online" :
"N/A",
316 dev_dbg(info->
dev,
"set_charging_fsm:vbatt:%d(mV)\n", vbatt);
318 switch (info->
state) {
323 start_precharge(info);
326 stop_charge(info, vbatt);
329 start_fastcharge(info);
333 power_off_notification(info);
336 stop_charge(info, vbatt);
344 start_fastcharge(info);
348 stop_charge(info, vbatt);
355 start_precharge(info);
359 stop_charge(info, vbatt);
366 start_precharge(info);
369 start_fastcharge(info);
373 power_off_notification(info);
384 "Out FSM:%s, Charger:%s, Battery:%s, Allowed:%d\n",
385 &fsm_state[info->
state][0],
386 (info->
online) ?
"online" :
"N/A",
393 static irqreturn_t pm860x_charger_handler(
int irq,
void *data)
412 dev_dbg(info->
dev,
"%s, Charger:%s, Allowed:%d\n", __func__,
415 set_charging_fsm(info);
422 static irqreturn_t pm860x_temp_handler(
int irq,
void *data)
436 value =
temp.intval / 10;
440 if (value < -10 || value > 40)
447 set_charging_fsm(info);
452 static irqreturn_t pm860x_exception_handler(
int irq,
void *data)
459 dev_dbg(info->
dev,
"%s, irq: %d\n", __func__, irq);
461 set_charging_fsm(info);
465 static irqreturn_t pm860x_done_handler(
int irq,
void *data)
491 vbatt =
val.intval / 1000;
508 set_charging_fsm(info);
513 static irqreturn_t pm860x_vbattery_handler(
int irq,
void *data)
519 set_vbatt_threshold(info, 0, 0);
528 set_charging_fsm(info);
533 static irqreturn_t pm860x_vchg_handler(
int irq,
void *data)
541 measure_vchg(info, &vchg);
551 OVER_TEMP_FLAG, OVER_TEMP_FLAG);
557 "%s, pm8606 over-temp occure\n", __func__);
565 "%s,pm8607 over-vchg occure,vchg = %dmv\n",
572 "%s,pm8607 over-vchg recover,vchg = %dmv\n",
578 set_charging_fsm(info);
583 static int pm860x_usb_get_prop(
struct power_supply *psy,
622 if (ret & STATUS2_CHG) {
631 set_charging_fsm(info);
635 static struct pm860x_irq_desc {
638 } pm860x_irq_descs[] = {
639 {
"usb supply detect", pm860x_charger_handler },
640 {
"charge done", pm860x_done_handler },
641 {
"charge timeout", pm860x_exception_handler },
642 {
"charge fault", pm860x_exception_handler },
643 {
"temperature", pm860x_temp_handler },
644 {
"vbatt", pm860x_vbattery_handler },
645 {
"vchg", pm860x_vchg_handler },
662 for (i = 0, j = 0; i <
count; i++) {
664 if (info->
irq[j] < 0)
676 dev_err(&pdev->
dev,
"Missed I2C address of 88PM8606!\n");
686 platform_set_drvdata(pdev, info);
688 info->
usb.name =
"usb";
690 info->
usb.supplied_to = pm860x_supplied_to;
692 info->
usb.properties = pm860x_usb_props;
694 info->
usb.get_property = pm860x_usb_get_prop;
699 pm860x_init_charger(info);
703 pm860x_irq_descs[i].handler,
706 dev_err(chip->
dev,
"Failed to request IRQ: #%d: %d\n",
726 platform_set_drvdata(pdev,
NULL);
729 for (i = 0; i < info->
irq_nums; i++)
737 .name =
"88pm860x-charger",
740 .probe = pm860x_charger_probe,