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