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