treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174
[sfrench/cifs-2.6.git] / drivers / power / supply / axp288_charger.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * axp288_charger.c - X-power AXP288 PMIC Charger driver
4  *
5  * Copyright (C) 2016-2017 Hans de Goede <hdegoede@redhat.com>
6  * Copyright (C) 2014 Intel Corporation
7  * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
8  */
9
10 #include <linux/acpi.h>
11 #include <linux/bitops.h>
12 #include <linux/module.h>
13 #include <linux/device.h>
14 #include <linux/regmap.h>
15 #include <linux/workqueue.h>
16 #include <linux/delay.h>
17 #include <linux/platform_device.h>
18 #include <linux/usb/otg.h>
19 #include <linux/notifier.h>
20 #include <linux/power_supply.h>
21 #include <linux/property.h>
22 #include <linux/mfd/axp20x.h>
23 #include <linux/extcon.h>
24
25 #define PS_STAT_VBUS_TRIGGER            BIT(0)
26 #define PS_STAT_BAT_CHRG_DIR            BIT(2)
27 #define PS_STAT_VBAT_ABOVE_VHOLD        BIT(3)
28 #define PS_STAT_VBUS_VALID              BIT(4)
29 #define PS_STAT_VBUS_PRESENT            BIT(5)
30
31 #define CHRG_STAT_BAT_SAFE_MODE         BIT(3)
32 #define CHRG_STAT_BAT_VALID             BIT(4)
33 #define CHRG_STAT_BAT_PRESENT           BIT(5)
34 #define CHRG_STAT_CHARGING              BIT(6)
35 #define CHRG_STAT_PMIC_OTP              BIT(7)
36
37 #define VBUS_ISPOUT_CUR_LIM_MASK        0x03
38 #define VBUS_ISPOUT_CUR_LIM_BIT_POS     0
39 #define VBUS_ISPOUT_CUR_LIM_900MA       0x0     /* 900mA */
40 #define VBUS_ISPOUT_CUR_LIM_1500MA      0x1     /* 1500mA */
41 #define VBUS_ISPOUT_CUR_LIM_2000MA      0x2     /* 2000mA */
42 #define VBUS_ISPOUT_CUR_NO_LIM          0x3     /* 2500mA */
43 #define VBUS_ISPOUT_VHOLD_SET_MASK      0x31
44 #define VBUS_ISPOUT_VHOLD_SET_BIT_POS   0x3
45 #define VBUS_ISPOUT_VHOLD_SET_OFFSET    4000    /* 4000mV */
46 #define VBUS_ISPOUT_VHOLD_SET_LSB_RES   100     /* 100mV */
47 #define VBUS_ISPOUT_VHOLD_SET_4300MV    0x3     /* 4300mV */
48 #define VBUS_ISPOUT_VBUS_PATH_DIS       BIT(7)
49
50 #define CHRG_CCCV_CC_MASK               0xf             /* 4 bits */
51 #define CHRG_CCCV_CC_BIT_POS            0
52 #define CHRG_CCCV_CC_OFFSET             200             /* 200mA */
53 #define CHRG_CCCV_CC_LSB_RES            200             /* 200mA */
54 #define CHRG_CCCV_ITERM_20P             BIT(4)          /* 20% of CC */
55 #define CHRG_CCCV_CV_MASK               0x60            /* 2 bits */
56 #define CHRG_CCCV_CV_BIT_POS            5
57 #define CHRG_CCCV_CV_4100MV             0x0             /* 4.10V */
58 #define CHRG_CCCV_CV_4150MV             0x1             /* 4.15V */
59 #define CHRG_CCCV_CV_4200MV             0x2             /* 4.20V */
60 #define CHRG_CCCV_CV_4350MV             0x3             /* 4.35V */
61 #define CHRG_CCCV_CHG_EN                BIT(7)
62
63 #define CNTL2_CC_TIMEOUT_MASK           0x3     /* 2 bits */
64 #define CNTL2_CC_TIMEOUT_OFFSET         6       /* 6 Hrs */
65 #define CNTL2_CC_TIMEOUT_LSB_RES        2       /* 2 Hrs */
66 #define CNTL2_CC_TIMEOUT_12HRS          0x3     /* 12 Hrs */
67 #define CNTL2_CHGLED_TYPEB              BIT(4)
68 #define CNTL2_CHG_OUT_TURNON            BIT(5)
69 #define CNTL2_PC_TIMEOUT_MASK           0xC0
70 #define CNTL2_PC_TIMEOUT_OFFSET         40      /* 40 mins */
71 #define CNTL2_PC_TIMEOUT_LSB_RES        10      /* 10 mins */
72 #define CNTL2_PC_TIMEOUT_70MINS         0x3
73
74 #define CHRG_ILIM_TEMP_LOOP_EN          BIT(3)
75 #define CHRG_VBUS_ILIM_MASK             0xf0
76 #define CHRG_VBUS_ILIM_BIT_POS          4
77 #define CHRG_VBUS_ILIM_100MA            0x0     /* 100mA */
78 #define CHRG_VBUS_ILIM_500MA            0x1     /* 500mA */
79 #define CHRG_VBUS_ILIM_900MA            0x2     /* 900mA */
80 #define CHRG_VBUS_ILIM_1500MA           0x3     /* 1500mA */
81 #define CHRG_VBUS_ILIM_2000MA           0x4     /* 2000mA */
82 #define CHRG_VBUS_ILIM_2500MA           0x5     /* 2500mA */
83 #define CHRG_VBUS_ILIM_3000MA           0x6     /* 3000mA */
84 #define CHRG_VBUS_ILIM_3500MA           0x7     /* 3500mA */
85 #define CHRG_VBUS_ILIM_4000MA           0x8     /* 4000mA */
86
87 #define CHRG_VLTFC_0C                   0xA5    /* 0 DegC */
88 #define CHRG_VHTFC_45C                  0x1F    /* 45 DegC */
89
90 #define FG_CNTL_OCV_ADJ_EN              BIT(3)
91
92 #define CV_4100MV                       4100    /* 4100mV */
93 #define CV_4150MV                       4150    /* 4150mV */
94 #define CV_4200MV                       4200    /* 4200mV */
95 #define CV_4350MV                       4350    /* 4350mV */
96
97 #define AXP288_EXTCON_DEV_NAME          "axp288_extcon"
98 #define USB_HOST_EXTCON_HID             "INT3496"
99 #define USB_HOST_EXTCON_NAME            "INT3496:00"
100
101 enum {
102         VBUS_OV_IRQ = 0,
103         CHARGE_DONE_IRQ,
104         CHARGE_CHARGING_IRQ,
105         BAT_SAFE_QUIT_IRQ,
106         BAT_SAFE_ENTER_IRQ,
107         QCBTU_IRQ,
108         CBTU_IRQ,
109         QCBTO_IRQ,
110         CBTO_IRQ,
111         CHRG_INTR_END,
112 };
113
114 struct axp288_chrg_info {
115         struct platform_device *pdev;
116         struct regmap *regmap;
117         struct regmap_irq_chip_data *regmap_irqc;
118         int irq[CHRG_INTR_END];
119         struct power_supply *psy_usb;
120
121         /* OTG/Host mode */
122         struct {
123                 struct work_struct work;
124                 struct extcon_dev *cable;
125                 struct notifier_block id_nb;
126                 bool id_short;
127         } otg;
128
129         /* SDP/CDP/DCP USB charging cable notifications */
130         struct {
131                 struct extcon_dev *edev;
132                 struct notifier_block nb;
133                 struct work_struct work;
134         } cable;
135
136         int cc;
137         int cv;
138         int max_cc;
139         int max_cv;
140 };
141
142 static inline int axp288_charger_set_cc(struct axp288_chrg_info *info, int cc)
143 {
144         u8 reg_val;
145         int ret;
146
147         if (cc < CHRG_CCCV_CC_OFFSET)
148                 cc = CHRG_CCCV_CC_OFFSET;
149         else if (cc > info->max_cc)
150                 cc = info->max_cc;
151
152         reg_val = (cc - CHRG_CCCV_CC_OFFSET) / CHRG_CCCV_CC_LSB_RES;
153         cc = (reg_val * CHRG_CCCV_CC_LSB_RES) + CHRG_CCCV_CC_OFFSET;
154         reg_val = reg_val << CHRG_CCCV_CC_BIT_POS;
155
156         ret = regmap_update_bits(info->regmap,
157                                 AXP20X_CHRG_CTRL1,
158                                 CHRG_CCCV_CC_MASK, reg_val);
159         if (ret >= 0)
160                 info->cc = cc;
161
162         return ret;
163 }
164
165 static inline int axp288_charger_set_cv(struct axp288_chrg_info *info, int cv)
166 {
167         u8 reg_val;
168         int ret;
169
170         if (cv <= CV_4100MV) {
171                 reg_val = CHRG_CCCV_CV_4100MV;
172                 cv = CV_4100MV;
173         } else if (cv <= CV_4150MV) {
174                 reg_val = CHRG_CCCV_CV_4150MV;
175                 cv = CV_4150MV;
176         } else if (cv <= CV_4200MV) {
177                 reg_val = CHRG_CCCV_CV_4200MV;
178                 cv = CV_4200MV;
179         } else {
180                 reg_val = CHRG_CCCV_CV_4350MV;
181                 cv = CV_4350MV;
182         }
183
184         reg_val = reg_val << CHRG_CCCV_CV_BIT_POS;
185
186         ret = regmap_update_bits(info->regmap,
187                                 AXP20X_CHRG_CTRL1,
188                                 CHRG_CCCV_CV_MASK, reg_val);
189
190         if (ret >= 0)
191                 info->cv = cv;
192
193         return ret;
194 }
195
196 static int axp288_charger_get_vbus_inlmt(struct axp288_chrg_info *info)
197 {
198         unsigned int val;
199         int ret;
200
201         ret = regmap_read(info->regmap, AXP20X_CHRG_BAK_CTRL, &val);
202         if (ret < 0)
203                 return ret;
204
205         val >>= CHRG_VBUS_ILIM_BIT_POS;
206         switch (val) {
207         case CHRG_VBUS_ILIM_100MA:
208                 return 100000;
209         case CHRG_VBUS_ILIM_500MA:
210                 return 500000;
211         case CHRG_VBUS_ILIM_900MA:
212                 return 900000;
213         case CHRG_VBUS_ILIM_1500MA:
214                 return 1500000;
215         case CHRG_VBUS_ILIM_2000MA:
216                 return 2000000;
217         case CHRG_VBUS_ILIM_2500MA:
218                 return 2500000;
219         case CHRG_VBUS_ILIM_3000MA:
220                 return 3000000;
221         case CHRG_VBUS_ILIM_3500MA:
222                 return 3500000;
223         default:
224                 /* All b1xxx values map to 4000 mA */
225                 return 4000000;
226         }
227 }
228
229 static inline int axp288_charger_set_vbus_inlmt(struct axp288_chrg_info *info,
230                                            int inlmt)
231 {
232         int ret;
233         u8 reg_val;
234
235         if (inlmt >= 4000000)
236                 reg_val = CHRG_VBUS_ILIM_4000MA << CHRG_VBUS_ILIM_BIT_POS;
237         else if (inlmt >= 3500000)
238                 reg_val = CHRG_VBUS_ILIM_3500MA << CHRG_VBUS_ILIM_BIT_POS;
239         else if (inlmt >= 3000000)
240                 reg_val = CHRG_VBUS_ILIM_3000MA << CHRG_VBUS_ILIM_BIT_POS;
241         else if (inlmt >= 2500000)
242                 reg_val = CHRG_VBUS_ILIM_2500MA << CHRG_VBUS_ILIM_BIT_POS;
243         else if (inlmt >= 2000000)
244                 reg_val = CHRG_VBUS_ILIM_2000MA << CHRG_VBUS_ILIM_BIT_POS;
245         else if (inlmt >= 1500000)
246                 reg_val = CHRG_VBUS_ILIM_1500MA << CHRG_VBUS_ILIM_BIT_POS;
247         else if (inlmt >= 900000)
248                 reg_val = CHRG_VBUS_ILIM_900MA << CHRG_VBUS_ILIM_BIT_POS;
249         else if (inlmt >= 500000)
250                 reg_val = CHRG_VBUS_ILIM_500MA << CHRG_VBUS_ILIM_BIT_POS;
251         else
252                 reg_val = CHRG_VBUS_ILIM_100MA << CHRG_VBUS_ILIM_BIT_POS;
253
254         ret = regmap_update_bits(info->regmap, AXP20X_CHRG_BAK_CTRL,
255                                  CHRG_VBUS_ILIM_MASK, reg_val);
256         if (ret < 0)
257                 dev_err(&info->pdev->dev, "charger BAK control %d\n", ret);
258
259         return ret;
260 }
261
262 static int axp288_charger_vbus_path_select(struct axp288_chrg_info *info,
263                                                                 bool enable)
264 {
265         int ret;
266
267         if (enable)
268                 ret = regmap_update_bits(info->regmap, AXP20X_VBUS_IPSOUT_MGMT,
269                                         VBUS_ISPOUT_VBUS_PATH_DIS, 0);
270         else
271                 ret = regmap_update_bits(info->regmap, AXP20X_VBUS_IPSOUT_MGMT,
272                         VBUS_ISPOUT_VBUS_PATH_DIS, VBUS_ISPOUT_VBUS_PATH_DIS);
273
274         if (ret < 0)
275                 dev_err(&info->pdev->dev, "axp288 vbus path select %d\n", ret);
276
277         return ret;
278 }
279
280 static int axp288_charger_enable_charger(struct axp288_chrg_info *info,
281                                                                 bool enable)
282 {
283         int ret;
284
285         if (enable)
286                 ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1,
287                                 CHRG_CCCV_CHG_EN, CHRG_CCCV_CHG_EN);
288         else
289                 ret = regmap_update_bits(info->regmap, AXP20X_CHRG_CTRL1,
290                                 CHRG_CCCV_CHG_EN, 0);
291         if (ret < 0)
292                 dev_err(&info->pdev->dev, "axp288 enable charger %d\n", ret);
293
294         return ret;
295 }
296
297 static int axp288_charger_is_present(struct axp288_chrg_info *info)
298 {
299         int ret, present = 0;
300         unsigned int val;
301
302         ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val);
303         if (ret < 0)
304                 return ret;
305
306         if (val & PS_STAT_VBUS_PRESENT)
307                 present = 1;
308         return present;
309 }
310
311 static int axp288_charger_is_online(struct axp288_chrg_info *info)
312 {
313         int ret, online = 0;
314         unsigned int val;
315
316         ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val);
317         if (ret < 0)
318                 return ret;
319
320         if (val & PS_STAT_VBUS_VALID)
321                 online = 1;
322         return online;
323 }
324
325 static int axp288_get_charger_health(struct axp288_chrg_info *info)
326 {
327         int ret, pwr_stat, chrg_stat;
328         int health = POWER_SUPPLY_HEALTH_UNKNOWN;
329         unsigned int val;
330
331         ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val);
332         if ((ret < 0) || !(val & PS_STAT_VBUS_PRESENT))
333                 goto health_read_fail;
334         else
335                 pwr_stat = val;
336
337         ret = regmap_read(info->regmap, AXP20X_PWR_OP_MODE, &val);
338         if (ret < 0)
339                 goto health_read_fail;
340         else
341                 chrg_stat = val;
342
343         if (!(pwr_stat & PS_STAT_VBUS_VALID))
344                 health = POWER_SUPPLY_HEALTH_DEAD;
345         else if (chrg_stat & CHRG_STAT_PMIC_OTP)
346                 health = POWER_SUPPLY_HEALTH_OVERHEAT;
347         else if (chrg_stat & CHRG_STAT_BAT_SAFE_MODE)
348                 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
349         else
350                 health = POWER_SUPPLY_HEALTH_GOOD;
351
352 health_read_fail:
353         return health;
354 }
355
356 static int axp288_charger_usb_set_property(struct power_supply *psy,
357                                     enum power_supply_property psp,
358                                     const union power_supply_propval *val)
359 {
360         struct axp288_chrg_info *info = power_supply_get_drvdata(psy);
361         int ret = 0;
362         int scaled_val;
363
364         switch (psp) {
365         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
366                 scaled_val = min(val->intval, info->max_cc);
367                 scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000);
368                 ret = axp288_charger_set_cc(info, scaled_val);
369                 if (ret < 0)
370                         dev_warn(&info->pdev->dev, "set charge current failed\n");
371                 break;
372         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
373                 scaled_val = min(val->intval, info->max_cv);
374                 scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000);
375                 ret = axp288_charger_set_cv(info, scaled_val);
376                 if (ret < 0)
377                         dev_warn(&info->pdev->dev, "set charge voltage failed\n");
378                 break;
379         case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
380                 ret = axp288_charger_set_vbus_inlmt(info, val->intval);
381                 if (ret < 0)
382                         dev_warn(&info->pdev->dev, "set input current limit failed\n");
383                 break;
384         default:
385                 ret = -EINVAL;
386         }
387
388         return ret;
389 }
390
391 static int axp288_charger_usb_get_property(struct power_supply *psy,
392                                     enum power_supply_property psp,
393                                     union power_supply_propval *val)
394 {
395         struct axp288_chrg_info *info = power_supply_get_drvdata(psy);
396         int ret;
397
398         switch (psp) {
399         case POWER_SUPPLY_PROP_PRESENT:
400                 /* Check for OTG case first */
401                 if (info->otg.id_short) {
402                         val->intval = 0;
403                         break;
404                 }
405                 ret = axp288_charger_is_present(info);
406                 if (ret < 0)
407                         return ret;
408                 val->intval = ret;
409                 break;
410         case POWER_SUPPLY_PROP_ONLINE:
411                 /* Check for OTG case first */
412                 if (info->otg.id_short) {
413                         val->intval = 0;
414                         break;
415                 }
416                 ret = axp288_charger_is_online(info);
417                 if (ret < 0)
418                         return ret;
419                 val->intval = ret;
420                 break;
421         case POWER_SUPPLY_PROP_HEALTH:
422                 val->intval = axp288_get_charger_health(info);
423                 break;
424         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
425                 val->intval = info->cc * 1000;
426                 break;
427         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
428                 val->intval = info->max_cc * 1000;
429                 break;
430         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
431                 val->intval = info->cv * 1000;
432                 break;
433         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
434                 val->intval = info->max_cv * 1000;
435                 break;
436         case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
437                 ret = axp288_charger_get_vbus_inlmt(info);
438                 if (ret < 0)
439                         return ret;
440                 val->intval = ret;
441                 break;
442         default:
443                 return -EINVAL;
444         }
445
446         return 0;
447 }
448
449 static int axp288_charger_property_is_writeable(struct power_supply *psy,
450                 enum power_supply_property psp)
451 {
452         int ret;
453
454         switch (psp) {
455         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
456         case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
457         case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
458                 ret = 1;
459                 break;
460         default:
461                 ret = 0;
462         }
463
464         return ret;
465 }
466
467 static enum power_supply_property axp288_usb_props[] = {
468         POWER_SUPPLY_PROP_PRESENT,
469         POWER_SUPPLY_PROP_ONLINE,
470         POWER_SUPPLY_PROP_TYPE,
471         POWER_SUPPLY_PROP_HEALTH,
472         POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
473         POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
474         POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
475         POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
476         POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
477 };
478
479 static const struct power_supply_desc axp288_charger_desc = {
480         .name                   = "axp288_charger",
481         .type                   = POWER_SUPPLY_TYPE_USB,
482         .properties             = axp288_usb_props,
483         .num_properties         = ARRAY_SIZE(axp288_usb_props),
484         .get_property           = axp288_charger_usb_get_property,
485         .set_property           = axp288_charger_usb_set_property,
486         .property_is_writeable  = axp288_charger_property_is_writeable,
487 };
488
489 static irqreturn_t axp288_charger_irq_thread_handler(int irq, void *dev)
490 {
491         struct axp288_chrg_info *info = dev;
492         int i;
493
494         for (i = 0; i < CHRG_INTR_END; i++) {
495                 if (info->irq[i] == irq)
496                         break;
497         }
498
499         if (i >= CHRG_INTR_END) {
500                 dev_warn(&info->pdev->dev, "spurious interrupt!!\n");
501                 return IRQ_NONE;
502         }
503
504         switch (i) {
505         case VBUS_OV_IRQ:
506                 dev_dbg(&info->pdev->dev, "VBUS Over Voltage INTR\n");
507                 break;
508         case CHARGE_DONE_IRQ:
509                 dev_dbg(&info->pdev->dev, "Charging Done INTR\n");
510                 break;
511         case CHARGE_CHARGING_IRQ:
512                 dev_dbg(&info->pdev->dev, "Start Charging IRQ\n");
513                 break;
514         case BAT_SAFE_QUIT_IRQ:
515                 dev_dbg(&info->pdev->dev,
516                         "Quit Safe Mode(restart timer) Charging IRQ\n");
517                 break;
518         case BAT_SAFE_ENTER_IRQ:
519                 dev_dbg(&info->pdev->dev,
520                         "Enter Safe Mode(timer expire) Charging IRQ\n");
521                 break;
522         case QCBTU_IRQ:
523                 dev_dbg(&info->pdev->dev,
524                         "Quit Battery Under Temperature(CHRG) INTR\n");
525                 break;
526         case CBTU_IRQ:
527                 dev_dbg(&info->pdev->dev,
528                         "Hit Battery Under Temperature(CHRG) INTR\n");
529                 break;
530         case QCBTO_IRQ:
531                 dev_dbg(&info->pdev->dev,
532                         "Quit Battery Over Temperature(CHRG) INTR\n");
533                 break;
534         case CBTO_IRQ:
535                 dev_dbg(&info->pdev->dev,
536                         "Hit Battery Over Temperature(CHRG) INTR\n");
537                 break;
538         default:
539                 dev_warn(&info->pdev->dev, "Spurious Interrupt!!!\n");
540                 goto out;
541         }
542
543         power_supply_changed(info->psy_usb);
544 out:
545         return IRQ_HANDLED;
546 }
547
548 static void axp288_charger_extcon_evt_worker(struct work_struct *work)
549 {
550         struct axp288_chrg_info *info =
551             container_of(work, struct axp288_chrg_info, cable.work);
552         int ret, current_limit;
553         struct extcon_dev *edev = info->cable.edev;
554         unsigned int val;
555
556         ret = regmap_read(info->regmap, AXP20X_PWR_INPUT_STATUS, &val);
557         if (ret < 0) {
558                 dev_err(&info->pdev->dev, "Error reading status (%d)\n", ret);
559                 return;
560         }
561
562         /* Offline? Disable charging and bail */
563         if (!(val & PS_STAT_VBUS_VALID)) {
564                 dev_dbg(&info->pdev->dev, "USB charger disconnected\n");
565                 axp288_charger_enable_charger(info, false);
566                 power_supply_changed(info->psy_usb);
567                 return;
568         }
569
570         /* Determine cable/charger type */
571         if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0) {
572                 dev_dbg(&info->pdev->dev, "USB SDP charger is connected\n");
573                 current_limit = 500000;
574         } else if (extcon_get_state(edev, EXTCON_CHG_USB_CDP) > 0) {
575                 dev_dbg(&info->pdev->dev, "USB CDP charger is connected\n");
576                 current_limit = 1500000;
577         } else if (extcon_get_state(edev, EXTCON_CHG_USB_DCP) > 0) {
578                 dev_dbg(&info->pdev->dev, "USB DCP charger is connected\n");
579                 current_limit = 2000000;
580         } else {
581                 /* Charger type detection still in progress, bail. */
582                 return;
583         }
584
585         /* Set vbus current limit first, then enable charger */
586         ret = axp288_charger_set_vbus_inlmt(info, current_limit);
587         if (ret == 0)
588                 axp288_charger_enable_charger(info, true);
589         else
590                 dev_err(&info->pdev->dev,
591                         "error setting current limit (%d)\n", ret);
592
593         power_supply_changed(info->psy_usb);
594 }
595
596 static int axp288_charger_handle_cable_evt(struct notifier_block *nb,
597                                            unsigned long event, void *param)
598 {
599         struct axp288_chrg_info *info =
600                 container_of(nb, struct axp288_chrg_info, cable.nb);
601         schedule_work(&info->cable.work);
602         return NOTIFY_OK;
603 }
604
605 static void axp288_charger_otg_evt_worker(struct work_struct *work)
606 {
607         struct axp288_chrg_info *info =
608             container_of(work, struct axp288_chrg_info, otg.work);
609         struct extcon_dev *edev = info->otg.cable;
610         int ret, usb_host = extcon_get_state(edev, EXTCON_USB_HOST);
611
612         dev_dbg(&info->pdev->dev, "external connector USB-Host is %s\n",
613                                 usb_host ? "attached" : "detached");
614
615         /*
616          * Set usb_id_short flag to avoid running charger detection logic
617          * in case usb host.
618          */
619         info->otg.id_short = usb_host;
620
621         /* Disable VBUS path before enabling the 5V boost */
622         ret = axp288_charger_vbus_path_select(info, !info->otg.id_short);
623         if (ret < 0)
624                 dev_warn(&info->pdev->dev, "vbus path disable failed\n");
625 }
626
627 static int axp288_charger_handle_otg_evt(struct notifier_block *nb,
628                                    unsigned long event, void *param)
629 {
630         struct axp288_chrg_info *info =
631             container_of(nb, struct axp288_chrg_info, otg.id_nb);
632
633         schedule_work(&info->otg.work);
634
635         return NOTIFY_OK;
636 }
637
638 static int charger_init_hw_regs(struct axp288_chrg_info *info)
639 {
640         int ret, cc, cv;
641         unsigned int val;
642
643         /* Program temperature thresholds */
644         ret = regmap_write(info->regmap, AXP20X_V_LTF_CHRG, CHRG_VLTFC_0C);
645         if (ret < 0) {
646                 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n",
647                                                         AXP20X_V_LTF_CHRG, ret);
648                 return ret;
649         }
650
651         ret = regmap_write(info->regmap, AXP20X_V_HTF_CHRG, CHRG_VHTFC_45C);
652         if (ret < 0) {
653                 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n",
654                                                         AXP20X_V_HTF_CHRG, ret);
655                 return ret;
656         }
657
658         /* Do not turn-off charger o/p after charge cycle ends */
659         ret = regmap_update_bits(info->regmap,
660                                 AXP20X_CHRG_CTRL2,
661                                 CNTL2_CHG_OUT_TURNON, CNTL2_CHG_OUT_TURNON);
662         if (ret < 0) {
663                 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n",
664                                                 AXP20X_CHRG_CTRL2, ret);
665                 return ret;
666         }
667
668         /* Setup ending condition for charging to be 10% of I(chrg) */
669         ret = regmap_update_bits(info->regmap,
670                                 AXP20X_CHRG_CTRL1,
671                                 CHRG_CCCV_ITERM_20P, 0);
672         if (ret < 0) {
673                 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n",
674                                                 AXP20X_CHRG_CTRL1, ret);
675                 return ret;
676         }
677
678         /* Disable OCV-SOC curve calibration */
679         ret = regmap_update_bits(info->regmap,
680                                 AXP20X_CC_CTRL,
681                                 FG_CNTL_OCV_ADJ_EN, 0);
682         if (ret < 0) {
683                 dev_err(&info->pdev->dev, "register(%x) write error(%d)\n",
684                                                 AXP20X_CC_CTRL, ret);
685                 return ret;
686         }
687
688         /* Read current charge voltage and current limit */
689         ret = regmap_read(info->regmap, AXP20X_CHRG_CTRL1, &val);
690         if (ret < 0) {
691                 dev_err(&info->pdev->dev, "register(%x) read error(%d)\n",
692                         AXP20X_CHRG_CTRL1, ret);
693                 return ret;
694         }
695
696         /* Determine charge voltage */
697         cv = (val & CHRG_CCCV_CV_MASK) >> CHRG_CCCV_CV_BIT_POS;
698         switch (cv) {
699         case CHRG_CCCV_CV_4100MV:
700                 info->cv = CV_4100MV;
701                 break;
702         case CHRG_CCCV_CV_4150MV:
703                 info->cv = CV_4150MV;
704                 break;
705         case CHRG_CCCV_CV_4200MV:
706                 info->cv = CV_4200MV;
707                 break;
708         case CHRG_CCCV_CV_4350MV:
709                 info->cv = CV_4350MV;
710                 break;
711         }
712
713         /* Determine charge current limit */
714         cc = (val & CHRG_CCCV_CC_MASK) >> CHRG_CCCV_CC_BIT_POS;
715         cc = (cc * CHRG_CCCV_CC_LSB_RES) + CHRG_CCCV_CC_OFFSET;
716         info->cc = cc;
717
718         /*
719          * Do not allow the user to configure higher settings then those
720          * set by the firmware
721          */
722         info->max_cv = info->cv;
723         info->max_cc = info->cc;
724
725         return 0;
726 }
727
728 static void axp288_charger_cancel_work(void *data)
729 {
730         struct axp288_chrg_info *info = data;
731
732         cancel_work_sync(&info->otg.work);
733         cancel_work_sync(&info->cable.work);
734 }
735
736 static int axp288_charger_probe(struct platform_device *pdev)
737 {
738         int ret, i, pirq;
739         struct axp288_chrg_info *info;
740         struct device *dev = &pdev->dev;
741         struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
742         struct power_supply_config charger_cfg = {};
743         unsigned int val;
744
745         /*
746          * On some devices the fuelgauge and charger parts of the axp288 are
747          * not used, check that the fuelgauge is enabled (CC_CTRL != 0).
748          */
749         ret = regmap_read(axp20x->regmap, AXP20X_CC_CTRL, &val);
750         if (ret < 0)
751                 return ret;
752         if (val == 0)
753                 return -ENODEV;
754
755         info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
756         if (!info)
757                 return -ENOMEM;
758
759         info->pdev = pdev;
760         info->regmap = axp20x->regmap;
761         info->regmap_irqc = axp20x->regmap_irqc;
762
763         info->cable.edev = extcon_get_extcon_dev(AXP288_EXTCON_DEV_NAME);
764         if (info->cable.edev == NULL) {
765                 dev_dbg(&pdev->dev, "%s is not ready, probe deferred\n",
766                         AXP288_EXTCON_DEV_NAME);
767                 return -EPROBE_DEFER;
768         }
769
770         if (acpi_dev_present(USB_HOST_EXTCON_HID, NULL, -1)) {
771                 info->otg.cable = extcon_get_extcon_dev(USB_HOST_EXTCON_NAME);
772                 if (info->otg.cable == NULL) {
773                         dev_dbg(dev, "EXTCON_USB_HOST is not ready, probe deferred\n");
774                         return -EPROBE_DEFER;
775                 }
776                 dev_info(&pdev->dev,
777                          "Using " USB_HOST_EXTCON_HID " extcon for usb-id\n");
778         }
779
780         platform_set_drvdata(pdev, info);
781
782         ret = charger_init_hw_regs(info);
783         if (ret)
784                 return ret;
785
786         /* Register with power supply class */
787         charger_cfg.drv_data = info;
788         info->psy_usb = devm_power_supply_register(dev, &axp288_charger_desc,
789                                                    &charger_cfg);
790         if (IS_ERR(info->psy_usb)) {
791                 ret = PTR_ERR(info->psy_usb);
792                 dev_err(dev, "failed to register power supply: %d\n", ret);
793                 return ret;
794         }
795
796         /* Cancel our work on cleanup, register this before the notifiers */
797         ret = devm_add_action(dev, axp288_charger_cancel_work, info);
798         if (ret)
799                 return ret;
800
801         /* Register for extcon notification */
802         INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker);
803         info->cable.nb.notifier_call = axp288_charger_handle_cable_evt;
804         ret = devm_extcon_register_notifier_all(dev, info->cable.edev,
805                                                 &info->cable.nb);
806         if (ret) {
807                 dev_err(dev, "failed to register cable extcon notifier\n");
808                 return ret;
809         }
810         schedule_work(&info->cable.work);
811
812         /* Register for OTG notification */
813         INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker);
814         info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt;
815         if (info->otg.cable) {
816                 ret = devm_extcon_register_notifier(&pdev->dev, info->otg.cable,
817                                         EXTCON_USB_HOST, &info->otg.id_nb);
818                 if (ret) {
819                         dev_err(dev, "failed to register EXTCON_USB_HOST notifier\n");
820                         return ret;
821                 }
822                 schedule_work(&info->otg.work);
823         }
824
825         /* Register charger interrupts */
826         for (i = 0; i < CHRG_INTR_END; i++) {
827                 pirq = platform_get_irq(info->pdev, i);
828                 if (pirq < 0) {
829                         dev_err(&pdev->dev, "Failed to get IRQ: %d\n", pirq);
830                         return pirq;
831                 }
832                 info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
833                 if (info->irq[i] < 0) {
834                         dev_warn(&info->pdev->dev,
835                                 "failed to get virtual interrupt=%d\n", pirq);
836                         return info->irq[i];
837                 }
838                 ret = devm_request_threaded_irq(&info->pdev->dev, info->irq[i],
839                                         NULL, axp288_charger_irq_thread_handler,
840                                         IRQF_ONESHOT, info->pdev->name, info);
841                 if (ret) {
842                         dev_err(&pdev->dev, "failed to request interrupt=%d\n",
843                                                                 info->irq[i]);
844                         return ret;
845                 }
846         }
847
848         return 0;
849 }
850
851 static const struct platform_device_id axp288_charger_id_table[] = {
852         { .name = "axp288_charger" },
853         {},
854 };
855 MODULE_DEVICE_TABLE(platform, axp288_charger_id_table);
856
857 static struct platform_driver axp288_charger_driver = {
858         .probe = axp288_charger_probe,
859         .id_table = axp288_charger_id_table,
860         .driver = {
861                 .name = "axp288_charger",
862         },
863 };
864
865 module_platform_driver(axp288_charger_driver);
866
867 MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>");
868 MODULE_DESCRIPTION("X-power AXP288 Charger Driver");
869 MODULE_LICENSE("GPL v2");