• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #define pr_fmt(x) KBUILD_MODNAME ": " x "\n"
2 
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/init.h>
6 #include "linux/irq.h"
7 #include <linux/slab.h>
8 #include <linux/interrupt.h>
9 #include <linux/device.h>
10 #include <linux/mutex.h>
11 #include <linux/param.h>
12 #include <linux/jiffies.h>
13 #include <linux/platform_device.h>
14 #include <linux/power_supply.h>
15 #include <linux/fs.h>
16 #include <linux/kernel.h>
17 #include <linux/ktime.h>
18 #include <linux/of.h>
19 #include <linux/timekeeping.h>
20 #include <linux/types.h>
21 #include <linux/string.h>
22 #include <asm/irq.h>
23 #include <linux/cdev.h>
24 #include <linux/delay.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/kthread.h>
27 #include <linux/freezer.h>
28 #include <linux/err.h>
29 #include "power/axp2101.h"
30 
31 #include <linux/err.h>
32 #include "axp2202_charger.h"
33 
34 
35 struct axp2202_bat_power {
36 	char                      *name;
37 	struct device             *dev;
38 	struct regmap             *regmap;
39 	struct power_supply       *bat_supply;
40 	struct delayed_work        bat_supply_mon;
41 	struct axp_config_info     dts_info;
42 };
43 
44 static enum power_supply_property axp2202_bat_props[] = {
45 	POWER_SUPPLY_PROP_PRESENT,
46 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
47 	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
48 	POWER_SUPPLY_PROP_STATUS,
49 	POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN,
50 	POWER_SUPPLY_PROP_TEMP,
51 	POWER_SUPPLY_PROP_CAPACITY,
52 	POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
53 	POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
54 	POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN,
55 	POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX,
56 	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
57 	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
58 	POWER_SUPPLY_PROP_MANUFACTURER,
59 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
60 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
61 	POWER_SUPPLY_PROP_HEALTH,
62 	POWER_SUPPLY_PROP_CHARGE_COUNTER,
63 	POWER_SUPPLY_PROP_CHARGE_FULL,
64 };
65 
axp2202_get_vbat_vol(struct power_supply * ps,union power_supply_propval * val)66 static int axp2202_get_vbat_vol(struct power_supply *ps,
67 			     union power_supply_propval *val)
68 {
69 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
70 	struct regmap *regmap = bat_power->regmap;
71 	uint8_t data[2];
72 	uint16_t vtemp[3], tempv;
73 	int ret = 0;
74 	uint8_t i;
75 
76 	for (i = 0; i < 3; i++) {
77 		ret = regmap_bulk_read(regmap, AXP2202_VBAT_H, data, 2);
78 		if (ret < 0)
79 			return ret;
80 
81 		vtemp[i] = (((data[0] & GENMASK(5, 0)) << 0x08) | (data[1]));
82 	}
83 	if (vtemp[0] > vtemp[1]) {
84 		tempv = vtemp[0];
85 		vtemp[0] = vtemp[1];
86 		vtemp[1] = tempv;
87 	}
88 	if (vtemp[1] > vtemp[2]) {
89 		tempv = vtemp[1];
90 		vtemp[1] = vtemp[2];
91 		vtemp[2] = tempv;
92 	}
93 	if (vtemp[0] > vtemp[1]) {
94 		tempv = vtemp[0];
95 		vtemp[0] = vtemp[1];
96 		vtemp[1] = tempv;
97 	} /* Why three times? */
98 	/*incase vtemp[1] exceed AXP2202_VBAT_MAX */
99 	if ((vtemp[1] > AXP2202_VBAT_MAX) || (vtemp[1] < AXP2202_VBAT_MIN)) {
100 		val->intval = 0;
101 		return 0;
102 	}
103 
104 	val->intval = vtemp[1] * 1000;
105 
106 	return 0;
107 }
108 
axp2202_get_bat_health(struct power_supply * ps,union power_supply_propval * val)109 static int axp2202_get_bat_health(struct power_supply *ps,
110 			     union power_supply_propval *val)
111 {
112 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
113 	struct regmap *regmap = bat_power->regmap;
114 
115 	unsigned int reg_value, reg_value2;
116 	int ret = 0;
117 
118 	ret = regmap_read(regmap, AXP2202_COMM_STAT0, &reg_value);
119 	ret = regmap_read(regmap, AXP2202_COMM_FAULT, &reg_value2);
120 
121 	if (reg_value & AXP2202_MASK_BAT_STAT) {
122 		if (reg_value & AXP2202_MASK_BAT_ACT_STAT)
123 			val->intval = POWER_SUPPLY_HEALTH_DEAD;
124 		else if (reg_value2 & AXP2202_MASK_BAT_WOT)
125 			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
126 		else if (reg_value2 & AXP2202_MASK_BAT_WUT)
127 			val->intval = POWER_SUPPLY_HEALTH_COLD;
128 		else
129 			val->intval = POWER_SUPPLY_HEALTH_GOOD;
130 	} else {
131 		val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
132 	}
133 	return val->intval;
134 }
135 
axp_vts_to_temp(int data,const struct axp_config_info * axp_config)136 static inline int axp_vts_to_temp(int data,
137 		const struct axp_config_info *axp_config)
138 {
139 	int temp;
140 
141 	if (!axp_config->pmu_bat_temp_enable)
142 		return 300;
143 	else if (data < axp_config->pmu_bat_temp_para16)
144 		return 800;
145 	else if (data <= axp_config->pmu_bat_temp_para15) {
146 		temp = 700 + (axp_config->pmu_bat_temp_para15-data)*100/
147 		(axp_config->pmu_bat_temp_para15-axp_config->pmu_bat_temp_para16);
148 	} else if (data <= axp_config->pmu_bat_temp_para14) {
149 		temp = 600 + (axp_config->pmu_bat_temp_para14-data)*100/
150 		(axp_config->pmu_bat_temp_para14-axp_config->pmu_bat_temp_para15);
151 	} else if (data <= axp_config->pmu_bat_temp_para13) {
152 		temp = 550 + (axp_config->pmu_bat_temp_para13-data)*50/
153 		(axp_config->pmu_bat_temp_para13-axp_config->pmu_bat_temp_para14);
154 	} else if (data <= axp_config->pmu_bat_temp_para12) {
155 		temp = 500 + (axp_config->pmu_bat_temp_para12-data)*50/
156 		(axp_config->pmu_bat_temp_para12-axp_config->pmu_bat_temp_para13);
157 	} else if (data <= axp_config->pmu_bat_temp_para11) {
158 		temp = 450 + (axp_config->pmu_bat_temp_para11-data)*50/
159 		(axp_config->pmu_bat_temp_para11-axp_config->pmu_bat_temp_para12);
160 	} else if (data <= axp_config->pmu_bat_temp_para10) {
161 		temp = 400 + (axp_config->pmu_bat_temp_para10-data)*50/
162 		(axp_config->pmu_bat_temp_para10-axp_config->pmu_bat_temp_para11);
163 	} else if (data <= axp_config->pmu_bat_temp_para9) {
164 		temp = 300 + (axp_config->pmu_bat_temp_para9-data)*100/
165 		(axp_config->pmu_bat_temp_para9-axp_config->pmu_bat_temp_para10);
166 	} else if (data <= axp_config->pmu_bat_temp_para8) {
167 		temp = 200 + (axp_config->pmu_bat_temp_para8-data)*100/
168 		(axp_config->pmu_bat_temp_para8-axp_config->pmu_bat_temp_para9);
169 	} else if (data <= axp_config->pmu_bat_temp_para7) {
170 		temp = 100 + (axp_config->pmu_bat_temp_para7-data)*100/
171 		(axp_config->pmu_bat_temp_para7-axp_config->pmu_bat_temp_para8);
172 	} else if (data <= axp_config->pmu_bat_temp_para6) {
173 		temp = 50 + (axp_config->pmu_bat_temp_para6-data)*50/
174 		(axp_config->pmu_bat_temp_para6-axp_config->pmu_bat_temp_para7);
175 	} else if (data <= axp_config->pmu_bat_temp_para5) {
176 		temp = 0 + (axp_config->pmu_bat_temp_para5-data)*50/
177 		(axp_config->pmu_bat_temp_para5-axp_config->pmu_bat_temp_para6);
178 	} else if (data <= axp_config->pmu_bat_temp_para4) {
179 		temp = -50 + (axp_config->pmu_bat_temp_para4-data)*50/
180 		(axp_config->pmu_bat_temp_para4-axp_config->pmu_bat_temp_para5);
181 	} else if (data <= axp_config->pmu_bat_temp_para3) {
182 		temp = -100 + (axp_config->pmu_bat_temp_para3-data)*50/
183 		(axp_config->pmu_bat_temp_para3-axp_config->pmu_bat_temp_para4);
184 	} else if (data <= axp_config->pmu_bat_temp_para2) {
185 		temp = -150 + (axp_config->pmu_bat_temp_para2-data)*50/
186 		(axp_config->pmu_bat_temp_para2-axp_config->pmu_bat_temp_para3);
187 	} else if (data <= axp_config->pmu_bat_temp_para1) {
188 		temp = -250 + (axp_config->pmu_bat_temp_para1-data)*100/
189 		(axp_config->pmu_bat_temp_para1-axp_config->pmu_bat_temp_para2);
190 	} else
191 		temp = -250;
192 	return temp;
193 }
194 
195 /* read temperature */
axp2202_get_temp(struct power_supply * ps,union power_supply_propval * val)196 static int axp2202_get_temp(struct power_supply *ps,
197 			     union power_supply_propval *val)
198 {
199 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
200 	struct regmap *regmap = bat_power->regmap;
201 	struct axp_config_info *axp_config = &bat_power->dts_info;
202 
203 	uint8_t data[2];
204 	uint16_t temp;
205 	int ret = 0, tmp;
206 
207 	ret = regmap_update_bits(regmap, AXP2202_ADC_DATA_SEL, 0x03, AXP2202_ADC_TS_SEL); /* ADC channel select */
208 	if (ret < 0)
209 		return ret;
210 	mdelay(1);
211 
212 	ret = regmap_bulk_read(regmap, AXP2202_ADC_DATA_H, data, 2);
213 	if (ret < 0)
214 		return ret;
215 	temp = (((data[0] & GENMASK(5, 0)) << 0x08) | (data[1]));
216 	tmp = temp * 500 / 1000;
217 	val->intval = axp_vts_to_temp(tmp, axp_config);
218 
219 	return 0;
220 }
221 
222 
axp2202_bat_get_max_voltage(struct power_supply * ps,union power_supply_propval * val)223 static int axp2202_bat_get_max_voltage(struct power_supply *ps,
224 			     union power_supply_propval *val)
225 {
226 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
227 	struct regmap *regmap = bat_power->regmap;
228 
229 	int ret, reg_value;
230 
231 	ret = regmap_read(regmap, AXP2202_VTERM_CFG, &reg_value);
232 	if (ret)
233 		return ret;
234 
235 	switch (reg_value & AXP2202_CHRG_TGT_VOLT) {
236 	case AXP2202_CHRG_CTRL1_TGT_4_0V:
237 		val->intval = 4000000;
238 		break;
239 	case AXP2202_CHRG_CTRL1_TGT_4_1V:
240 		val->intval = 4100000;
241 		break;
242 	case AXP2202_CHRG_CTRL1_TGT_4_2V:
243 		val->intval = 4200000;
244 		break;
245 	case AXP2202_CHRG_CTRL1_TGT_4_35V:
246 		val->intval = 4350000;
247 		break;
248 	case AXP2202_CHRG_CTRL1_TGT_4_4V:
249 		val->intval = 4400000;
250 		break;
251 	case AXP2202_CHRG_CTRL1_TGT_5_0V:
252 		val->intval = 5000000;
253 		break;
254 	default:
255 		return -EINVAL;
256 	}
257 
258 	return 0;
259 }
260 
axp2202_get_ichg(struct power_supply * ps,union power_supply_propval * val)261 static int axp2202_get_ichg(struct power_supply *ps,
262 			     union power_supply_propval *val)
263 {
264 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
265 	struct regmap *regmap = bat_power->regmap;
266 
267 	uint8_t data[2];
268 	uint16_t ichg;
269 	int ret = 0;
270 
271 	ret = regmap_bulk_read(regmap, AXP2202_ICHG_H, data, 2);
272 	if (ret < 0)
273 		return ret;
274 	ichg = (((data[0] & GENMASK(5, 0)) << 8) | (data[1])); /* mA */
275 	ichg = ichg / 2;
276 	val->intval = ichg;
277 
278 	return 0;
279 }
280 
axp2202_get_soc(struct power_supply * ps,union power_supply_propval * val)281 static int axp2202_get_soc(struct power_supply *ps,
282 			    union power_supply_propval *val)
283 {
284 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
285 	struct regmap *regmap = bat_power->regmap;
286 	unsigned int data;
287 	int ret = 0;
288 
289 	ret = regmap_read(regmap, AXP2202_GAUGE_SOC, &data);
290 	if (ret < 0)
291 		return ret;
292 
293 	if (data > AXP2202_SOC_MAX)
294 		data = AXP2202_SOC_MAX;
295 	else if (data < AXP2202_SOC_MIN)
296 		data = AXP2202_SOC_MIN;
297 
298 	val->intval = data;
299 
300 	return 0;
301 }
302 
axp2202_get_charger_count(struct power_supply * ps,union power_supply_propval * val)303 static int axp2202_get_charger_count(struct power_supply *ps,
304 		union power_supply_propval *val)
305 {
306 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
307 	struct axp_config_info *axp_config = &bat_power->dts_info;
308 	unsigned int data;
309 
310 	data = axp_config->pmu_battery_cap;
311 	val->intval = data;
312 	return 0;
313 }
314 
axp2202_get_charger_count_current(struct power_supply * ps,union power_supply_propval * val)315 static int axp2202_get_charger_count_current(struct power_supply *ps,
316 		union power_supply_propval *val)
317 {
318 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
319 	struct axp_config_info *axp_config = &bat_power->dts_info;
320 	unsigned int data[2];
321 	int ret = 0;
322 
323 	data[0] = axp_config->pmu_battery_cap;
324 
325 	ret = axp2202_get_soc(ps, val);
326 	if (ret < 0)
327 		return ret;
328 	data[1] = val->intval;
329 	data[1] = data[1] * data[0] / 100;
330 
331 	val->intval = data[1];
332 	return 0;
333 }
334 
axp2202_get_time2empty(struct power_supply * ps,union power_supply_propval * val)335 static int axp2202_get_time2empty(struct power_supply *ps,
336 				   union power_supply_propval *val)
337 {
338 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
339 	struct regmap *regmap = bat_power->regmap;
340 	uint8_t data[2];
341 	uint16_t ttemp[3], tempt;
342 	int ret = 0;
343 	uint8_t i;
344 
345 	for (i = 0; i < 3; i++) {
346 		ret = regmap_bulk_read(regmap, AXP2202_GAUGE_TIME2EMPTY_H, data,
347 				       2);
348 		if (ret < 0)
349 			return ret;
350 
351 		ttemp[i] = ((data[0] << 0x08) | (data[1]));
352 	}
353 
354 	if (ttemp[0] > ttemp[1]) {
355 		tempt = ttemp[0];
356 		ttemp[0] = ttemp[1];
357 		ttemp[1] = tempt;
358 	}
359 	if (ttemp[1] > ttemp[2]) {
360 		tempt = ttemp[1];
361 		ttemp[1] = ttemp[2];
362 		ttemp[2] = tempt;
363 	}
364 	if (ttemp[0] > ttemp[1]) {
365 		tempt = ttemp[0];
366 		ttemp[0] = ttemp[1];
367 		ttemp[1] = tempt;
368 	}
369 
370 	val->intval = ttemp[1] * 60;
371 
372 	return 0;
373 }
374 
375 
axp2202_get_time2full(struct power_supply * ps,union power_supply_propval * val)376 static int axp2202_get_time2full(struct power_supply *ps,
377 				  union power_supply_propval *val)
378 {
379 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
380 	struct regmap *regmap = bat_power->regmap;
381 	uint16_t ttemp[3], tempt;
382 	uint8_t data[2];
383 	int ret = 0;
384 	uint8_t i;
385 
386 	for (i = 0; i < 3; i++) {
387 		ret = regmap_bulk_read(regmap, AXP2202_GAUGE_TIME2FULL_H, data, 2);
388 		if (ret < 0)
389 			return ret;
390 
391 		ttemp[i] = ((data[0] << 0x08) | (data[1]));
392 	}
393 
394 	if (ttemp[0] > ttemp[1]) {
395 		tempt = ttemp[0];
396 		ttemp[0] = ttemp[1];
397 		ttemp[1] = tempt;
398 	}
399 	if (ttemp[1] > ttemp[2]) {
400 		tempt = ttemp[1];
401 		ttemp[1] = ttemp[2];
402 		ttemp[2] = tempt;
403 	}
404 	if (ttemp[0] > ttemp[1]) {
405 		tempt = ttemp[0];
406 		ttemp[0] = ttemp[1];
407 		ttemp[1] = tempt;
408 	}
409 
410 	val->intval = ttemp[1] * 60;
411 
412 	return 0;
413 }
414 
415 
axp2202_get_bat_present(struct power_supply * ps,union power_supply_propval * val)416 static int axp2202_get_bat_present(struct power_supply *ps,
417 				  union power_supply_propval *val)
418 {
419 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
420 	struct regmap *regmap = bat_power->regmap;
421 	unsigned int data;
422 	int ret;
423 
424 	ret = regmap_read(regmap, AXP2202_COMM_STAT0, &data);
425 	if (ret < 0) {
426 		dev_dbg(&ps->dev, "error read AXP2202_COM_STAT1\n");
427 		return ret;
428 	}
429 
430 	if (data & AXP2202_MASK_BAT_STAT)
431 		val->intval = 1;
432 	else
433 		val->intval = 0;
434 	return 0;
435 }
436 
437 
438 
439 
axp2202_get_bat_status(struct power_supply * ps,union power_supply_propval * val)440 static int axp2202_get_bat_status(struct power_supply *ps,
441 				  union power_supply_propval *val)
442 {
443 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
444 	struct regmap *regmap = bat_power->regmap;
445 	unsigned int data;
446 	int ret;
447 
448 	ret = regmap_read(regmap, AXP2202_COMM_STAT1, &data);
449 	if (ret < 0) {
450 		dev_dbg(&ps->dev, "error read AXP2202_COM_STAT1\n");
451 		return ret;
452 	}
453 
454 	/* chg_stat = bit[2:0] */
455 	switch (data & 0x07) {
456 	case AXP2202_CHARGING_TRI:
457 	case AXP2202_CHARGING_NCHG:
458 		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
459 		break;
460 	case AXP2202_CHARGING_PRE:
461 	case AXP2202_CHARGING_CC:
462 	case AXP2202_CHARGING_CV:
463 		val->intval = POWER_SUPPLY_STATUS_CHARGING;
464 		break;
465 	case AXP2202_CHARGING_DONE:
466 		val->intval = POWER_SUPPLY_STATUS_FULL;
467 		break;
468 	default:
469 		val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
470 		break;
471 	}
472 
473 	return 0;
474 }
475 
476 
axp2202_get_lowsocth(struct power_supply * ps,union power_supply_propval * val)477 static int axp2202_get_lowsocth(struct power_supply *ps,
478 				 union power_supply_propval *val)
479 {
480 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
481 	struct regmap *regmap = bat_power->regmap;
482 	unsigned int data;
483 	int ret = 0;
484 
485 	ret = regmap_read(regmap, AXP2202_GAUGE_THLD, &data);
486 	if (ret < 0)
487 		return ret;
488 
489 	val->intval = (data >> 4) + 5;
490 
491 	return 0;
492 }
493 
494 
axp2202_set_lowsocth(struct regmap * regmap,int v)495 static int axp2202_set_lowsocth(struct regmap *regmap, int v)
496 {
497 	unsigned int data;
498 	int ret = 0;
499 
500 	data = v;
501 
502 	if (data > 20 || data < 5)
503 		return -EINVAL;
504 
505 	data = (data - 5);
506 	ret = regmap_update_bits(regmap, AXP2202_GAUGE_THLD, GENMASK(7, 4),
507 				 data);
508 	if (ret < 0)
509 		return ret;
510 
511 	return 0;
512 }
513 
axp2202_set_ichg(struct regmap * regmap,int mA)514 static int axp2202_set_ichg(struct regmap *regmap, int mA)
515 {
516 	unsigned int data;
517 	int ret = 0;
518 
519 	data = mA;
520 
521 	if (data > 3072)
522 		data = 3072;
523 	if	(data < 0)
524 		data = 0;
525 	else {
526 	data = (data / 64);
527 	ret = regmap_update_bits(regmap, AXP2202_ICC_CFG, GENMASK(5, 0),
528 				 data);
529 	if (ret < 0)
530 		return ret;
531 	}
532 
533 	return 0;
534 }
535 
axp2202_set_bat_max_voltage(struct regmap * regmap,int mV)536 static int axp2202_set_bat_max_voltage(struct regmap *regmap, int mV)
537 {
538 	unsigned int data;
539 	int ret = 0;
540 
541 	data = mV;
542 
543 	if (data > 5000)	{
544 		data = 5000;
545 		ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
546 					 AXP2202_CHRG_CTRL1_TGT_5_0V);
547 	} else if	(data < 4100) {
548 		data = 4000;
549 		ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
550 					 AXP2202_CHRG_CTRL1_TGT_4_0V);
551 	} else if	(data > 4100 && data < 4200) {
552 		data = 4100;
553 		ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
554 					 AXP2202_CHRG_CTRL1_TGT_4_1V);
555 	} else if	(data > 4200 && data < 4350) {
556 		data = 4200;
557 		ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
558 					 AXP2202_CHRG_CTRL1_TGT_4_2V);
559 	} else if	(data > 4350 && data < 4400) {
560 		data = 4350;
561 		ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
562 					 AXP2202_CHRG_CTRL1_TGT_4_35V);
563 	} else if	(data > 4400 && data < 5000) {
564 		data = 4400;
565 		ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
566 					 AXP2202_CHRG_CTRL1_TGT_4_4V);
567 	} else
568 		ret = 0;
569 	return 0;
570 }
571 
572 
axp2202_reset_mcu(struct regmap * regmap)573 static int axp2202_reset_mcu(struct regmap *regmap)
574 {
575 	int ret = 0;
576 
577 	ret = regmap_update_bits(regmap, AXP2202_RESET_CFG, AXP2202_MODE_RSTMCU,
578 				 AXP2202_MODE_RSTMCU);
579 	if (ret < 0)
580 		return ret;
581 
582 	ret = regmap_update_bits(regmap, AXP2202_RESET_CFG, AXP2202_MODE_RSTMCU,
583 				 0);
584 	if (ret < 0)
585 		return ret;
586 
587 	return 0;
588 }
589 
590 /**
591  * axp2202_get_param - get battery config from dts
592  *
593  * is not get battery config parameter from dts,
594  * then it use the default config.
595  */
axp2202_get_param(struct axp2202_bat_power * bat_power,uint8_t * para,unsigned int * len)596 static int axp2202_get_param(struct axp2202_bat_power *bat_power, uint8_t *para,
597 			     unsigned int *len)
598 {
599 	struct device_node *n_para, *r_para;
600 	const char *pparam;
601 	int cnt;
602 
603 	n_para = of_parse_phandle(bat_power->dev->of_node, "param", 0);
604 	if (!n_para)
605 		goto e_n_para;
606 
607 	if (of_property_read_string(n_para, "select", &pparam))
608 		goto e_para;
609 
610 	r_para = of_get_child_by_name(n_para, pparam);
611 	if (!r_para)
612 		goto e_para;
613 
614 	cnt = of_property_read_variable_u8_array(r_para, "parameter", para, 1,
615 						 *len);
616 	if (cnt <= 0)
617 		goto e_n_parameter;
618 	*len = cnt;
619 
620 	of_node_put(r_para);
621 	of_node_put(n_para);
622 
623 	return 0;
624 
625 e_n_parameter:
626 	of_node_put(r_para);
627 e_para:
628 	of_node_put(n_para);
629 e_n_para:
630 	return -ENODATA;
631 }
632 
axp2202_model_update(struct axp2202_bat_power * bat_power)633 static int axp2202_model_update(struct axp2202_bat_power *bat_power)
634 {
635 	struct regmap *regmap = bat_power->regmap;
636 	int i1, ret = 0;
637 	unsigned int data;
638 	unsigned int len;
639 	uint8_t i;
640 	uint8_t *param;
641 
642 	/* reset_mcu */
643 	ret = axp2202_reset_mcu(bat_power->regmap);
644 	if (ret < 0)
645 		goto UPDATE_ERR;
646 
647 	/* reset and open brom */
648 	ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
649 				 AXP2202_BROMUP_EN, 0);
650 	if (ret < 0)
651 		goto UPDATE_ERR;
652 
653 	ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
654 				 AXP2202_BROMUP_EN, AXP2202_BROMUP_EN);
655 	if (ret < 0)
656 		goto UPDATE_ERR;
657 
658 	/* down load battery parameters */
659 	len = AXP2202_MAX_PARAM;
660 	param = devm_kzalloc(bat_power->dev, AXP2202_MAX_PARAM, GFP_KERNEL);
661 	if (!param) {
662 		pr_err("can not find memory for param\n");
663 		goto UPDATE_ERR;
664 	}
665 	ret = axp2202_get_param(bat_power, param, &len);
666 	if (ret < 0)
667 		goto err_param;
668 
669 	for (i = 0; i < len; i++) {
670 		ret = regmap_write(regmap, AXP2202_GAUGE_BROM, param[i]);
671 		if (ret < 0)
672 			goto err_param;
673 	}
674 	/* reset and open brom */
675 	ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
676 				 AXP2202_BROMUP_EN, 0);
677 	if (ret < 0)
678 		goto err_param;
679 
680 	ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
681 				 AXP2202_BROMUP_EN, AXP2202_BROMUP_EN);
682 	if (ret < 0)
683 		goto err_param;
684 
685 	/* check battery parameters is ok ? */
686 	for (i = 0; i < len; i++) {
687 		ret = regmap_read(regmap, AXP2202_GAUGE_BROM, &data);
688 		if (ret < 0)
689 			goto err_param;
690 
691 		if (data != param[i]) {
692 			pr_err("model param check %02x error!\n", i);
693 			goto err_param;
694 		}
695 	}
696 
697 	devm_kfree(bat_power->dev, param);
698 
699 	/* close brom and set battery update flag */
700 	ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG, AXP2202_BROMUP_EN,
701 				 0);
702 	if (ret < 0)
703 		goto UPDATE_ERR;
704 
705 	ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
706 				 AXP2202_CFG_UPDATE_MARK,
707 				 AXP2202_CFG_UPDATE_MARK);
708 	if (ret < 0)
709 		goto UPDATE_ERR;
710 
711 	ret = regmap_read(regmap, AXP2202_GAUGE_CONFIG, &data);
712 	if (ret < 0)
713 		goto UPDATE_ERR;
714 
715 	/* reset mcu with chgcur = 0mA */
716 	regmap_read(regmap, AXP2202_COMM_STAT0, &i1);
717 	if (i1 & BIT(5)) {
718 		pr_warn("reset gauge\n");
719 		axp2202_set_ichg(regmap, 0);
720 		msleep(200);
721 		axp2202_reset_mcu(regmap);
722 		msleep(50);
723 		}
724 	axp2202_set_ichg(regmap, bat_power->dts_info.pmu_runtime_chgcur);
725 
726 	/* reset_mcu */
727 	ret = axp2202_reset_mcu(regmap);
728 	if (ret < 0)
729 		goto UPDATE_ERR;
730 
731 	/* update ok */
732 	return 0;
733 
734 err_param:
735 	devm_kfree(bat_power->dev, param);
736 
737 UPDATE_ERR:
738 	regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG, AXP2202_BROMUP_EN, 0);
739 	axp2202_reset_mcu(regmap);
740 
741 	return ret;
742 }
743 
744 
axp2202_model_update_check(struct regmap * regmap)745 static bool axp2202_model_update_check(struct regmap *regmap)
746 {
747 	int ret = 0;
748 	unsigned int data;
749 
750 	ret = regmap_read(regmap, AXP2202_GAUGE_CONFIG, &data);
751 	if (ret < 0)
752 		goto CHECK_ERR;
753 
754 	if ((data & AXP2202_CFG_UPDATE_MARK) == 0)
755 		goto CHECK_ERR;
756 
757 
758 	return true;
759 
760 CHECK_ERR:
761 	regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG, AXP2202_BROMUP_EN, 0);
762 	axp2202_reset_mcu(regmap);
763 	return false;
764 }
765 
766 
767 
axp2202_bat_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)768 static int axp2202_bat_get_property(struct power_supply *psy,
769 				enum power_supply_property psp,
770 				union power_supply_propval *val)
771 {
772 	int ret = 0;
773 
774 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(psy);
775 
776 	switch (psp) {
777 	case POWER_SUPPLY_PROP_MODEL_NAME:
778 		val->strval = psy->desc->name;
779 		break;
780 	case POWER_SUPPLY_PROP_TECHNOLOGY:
781 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
782 		break;
783 	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
784 		ret = axp2202_bat_get_max_voltage(psy, val);
785 		if (ret < 0)
786 			return ret;
787 		break;
788 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL: // customer modify
789 		ret = axp2202_get_bat_present(psy, val);
790 		if (ret < 0)
791 			return ret;
792 
793 		if (val->intval) {
794 			ret = axp2202_get_soc(psy, val);
795 			if (ret < 0)
796 				return ret;
797 
798 			if (val->intval == 100)
799 				val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
800 			else if (val->intval > 80)
801 				val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
802 			else if (val->intval > bat_power->dts_info.pmu_battery_warning_level1)
803 				val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
804 			else if (val->intval > bat_power->dts_info.pmu_battery_warning_level2)
805 				val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
806 			else if (val->intval >= 0)
807 				val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
808 			else
809 				val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
810 			}
811 		else
812 			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
813 		break;
814 	case POWER_SUPPLY_PROP_STATUS:
815 		ret = axp2202_get_bat_status(psy, val);
816 		if (ret < 0)
817 			return ret;
818 		break;
819 	case POWER_SUPPLY_PROP_PRESENT:
820 		ret = axp2202_get_bat_present(psy, val);
821 		if (ret < 0)
822 			return ret;
823 		break;
824 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
825 		ret = axp2202_get_vbat_vol(psy, val);
826 		if (ret < 0)
827 			return ret;
828 		break;
829 	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
830 		val->intval = bat_power->dts_info.pmu_battery_cap;
831 		break;
832 	case POWER_SUPPLY_PROP_CAPACITY:
833 		ret = axp2202_get_soc(psy, val); // unit %;
834 		if (ret < 0)
835 			return ret;
836 		break;
837 	case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
838 		ret = axp2202_get_lowsocth(psy, val);
839 		if (ret < 0)
840 			return ret;
841 		break;
842 	case POWER_SUPPLY_PROP_TEMP:
843 		ret = axp2202_get_temp(psy, val);
844 		if (ret < 0)
845 			return ret;
846 		break;
847 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
848 		ret = axp2202_get_ichg(psy, val);
849 		if (ret < 0)
850 			return ret;
851 		break;
852 	case POWER_SUPPLY_PROP_HEALTH:
853 		ret = axp2202_get_bat_health(psy, val);
854 		if (ret < 0)
855 			return ret;
856 		break;
857 	case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
858 		ret = bat_power->dts_info.pmu_bat_shutdown_ltf;
859 		val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
860 		if (!bat_power->dts_info.pmu_bat_temp_enable)
861 			val->intval = -200000;
862 		break;
863 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
864 		ret = bat_power->dts_info.pmu_bat_shutdown_htf;
865 		val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
866 		if (!bat_power->dts_info.pmu_bat_temp_enable)
867 			val->intval = 200000;
868 		break;
869 	case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
870 		ret = bat_power->dts_info.pmu_bat_charge_ltf;
871 		val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
872 		if (!bat_power->dts_info.pmu_bat_temp_enable)
873 			val->intval = -200000;
874 		break;
875 	case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
876 		ret = bat_power->dts_info.pmu_bat_charge_htf;
877 		val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
878 		if (!bat_power->dts_info.pmu_bat_temp_enable)
879 			val->intval = 200000;
880 		break;
881 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
882 		ret = axp2202_get_time2empty(psy, val);
883 		if (ret < 0)
884 			return ret;
885 		break;
886 	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
887 		ret = axp2202_get_time2full(psy, val);
888 		if (ret < 0)
889 			return ret;
890 		break;
891 	case POWER_SUPPLY_PROP_MANUFACTURER:
892 		val->strval = AXP2202_MANUFACTURER;
893 		break;
894 	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
895 		ret = axp2202_get_charger_count_current(psy, val);
896 		if (ret < 0)
897 			return ret;
898 		break;
899 	case POWER_SUPPLY_PROP_CHARGE_FULL:
900 		ret = axp2202_get_charger_count(psy, val);
901 		if (ret < 0)
902 			return ret;
903 		break;
904 	default:
905 		return -EINVAL;
906 	}
907 	return ret;
908 }
909 
axp2202_bat_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)910 static int axp2202_bat_set_property(struct power_supply *psy,
911 				enum power_supply_property psp,
912 				const union power_supply_propval *val)
913 {
914 	struct axp2202_bat_power *bat_power = power_supply_get_drvdata(psy);
915 	struct regmap *regmap = bat_power->regmap;
916 	int ret = 0;
917 
918 	switch (psp) {
919 	case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
920 		ret = axp2202_set_lowsocth(regmap, val->intval);
921 		break;
922 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
923 		ret = axp2202_set_ichg(regmap, val->intval);
924 		break;
925 	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
926 		ret = axp2202_set_bat_max_voltage(regmap, val->intval);
927 		break;
928 	default:
929 		ret = -EINVAL;
930 	}
931 
932 	return ret;
933 }
934 
axp2202_usb_power_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)935 static int axp2202_usb_power_property_is_writeable(struct power_supply *psy,
936 			     enum power_supply_property psp)
937 {
938 	int ret = 0;
939 	switch (psp) {
940 	case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
941 		ret = 0;
942 		break;
943 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
944 		ret = 0;
945 		break;
946 	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
947 		ret = 0;
948 		break;
949 	default:
950 		ret = -EINVAL;
951 	}
952 	return ret;
953 
954 }
955 
956 static const struct power_supply_desc axp2202_bat_desc = {
957 	.name = "axp2202-battery",
958 	.type = POWER_SUPPLY_TYPE_BATTERY,
959 	.get_property = axp2202_bat_get_property,
960 	.set_property = axp2202_bat_set_property,
961 	.properties = axp2202_bat_props,
962 	.num_properties = ARRAY_SIZE(axp2202_bat_props),
963 	.property_is_writeable = axp2202_usb_power_property_is_writeable,
964 };
965 
axp2202_init_chip(struct axp2202_bat_power * bat_power)966 static int axp2202_init_chip(struct axp2202_bat_power *bat_power)
967 {
968 	struct axp_config_info *axp_config = &bat_power->dts_info;
969 	int ret = 0;
970 	int val, vbat, soc;
971 	unsigned int reg_value;
972 	unsigned char temp_val[2];
973 
974 	if (bat_power == NULL) {
975 		dev_err(bat_power->dev, "axp2202_info is invalid!\n");
976 		return -ENODEV;
977 	}
978 
979 	if (ret < 0) {
980 		dev_err(bat_power->dev, "axp2202 reg update, i2c communication err!\n");
981 		return ret;
982 	}
983 
984 	/* update battery model*/
985 	if (!axp2202_model_update_check(bat_power->regmap)) {
986 		ret = axp2202_model_update(bat_power);
987 		if (ret < 0) {
988 			dev_err(bat_power->dev, "axp2202 model update fail!\n");
989 			return ret;
990 		}
991 	}
992 	dev_dbg(bat_power->dev, "axp2202 model update ok\n");
993 	/*end of update battery model*/
994 
995 
996 	/* set pre-charge current to 128mA*/
997 	val = 0x02;
998 	regmap_update_bits(bat_power->regmap, AXP2202_IPRECHG_CFG, 0x0f, val);
999 
1000 	/* set terminal charge current */
1001 	if (axp_config->pmu_terminal_chgcur < 64)
1002 		val = 0;
1003 	else if (axp_config->pmu_terminal_chgcur > 1024)
1004 		val = 0x0f;
1005 	else
1006 		val = axp_config->pmu_terminal_chgcur / 64 - 1;
1007 	regmap_update_bits(bat_power->regmap, AXP2202_ITERM_CFG, 0x0f, val);
1008 
1009 	/* enable ntc */
1010 	if (axp_config->pmu_bat_temp_enable) {
1011 		regmap_update_bits(bat_power->regmap, AXP2202_TS_CFG, AXP2202_TS_ENABLE_MARK, 0);
1012 
1013 		/* set ntc curr */
1014 		regmap_read(bat_power->regmap, AXP2202_TS_CFG, &val);
1015 		val &= 0xFC;
1016 		if (axp_config->pmu_bat_ts_current < 40)
1017 			val |= 0x00;
1018 		else if (axp_config->pmu_bat_ts_current < 50)
1019 			val |= 0x01;
1020 		else if (axp_config->pmu_bat_ts_current < 60)
1021 			val |= 0x02;
1022 		else
1023 			val |= 0x03;
1024 		regmap_write(bat_power->regmap, AXP2202_TS_CFG, val);
1025 
1026 		/* set ntc vol */
1027 		if (axp_config->pmu_bat_charge_ltf) {
1028 			if (axp_config->pmu_bat_charge_ltf < axp_config->pmu_bat_charge_htf)
1029 				axp_config->pmu_bat_charge_ltf = axp_config->pmu_bat_charge_htf;
1030 
1031 			val = axp_config->pmu_bat_charge_ltf / 32;
1032 			regmap_write(bat_power->regmap, AXP2202_VLTF_CHG, val);
1033 		}
1034 
1035 		if (axp_config->pmu_bat_charge_htf) {
1036 			if (axp_config->pmu_bat_charge_htf > 510)
1037 				axp_config->pmu_bat_charge_htf = 510;
1038 
1039 			val = axp_config->pmu_bat_charge_htf / 2;
1040 			regmap_write(bat_power->regmap, AXP2202_VHTF_CHG, val);
1041 		}
1042 
1043 		/* set work vol */
1044 		if (axp_config->pmu_bat_shutdown_ltf) {
1045 			if (axp_config->pmu_bat_shutdown_ltf < axp_config->pmu_bat_charge_ltf)
1046 				axp_config->pmu_bat_shutdown_ltf = axp_config->pmu_bat_charge_ltf;
1047 
1048 			val = axp_config->pmu_bat_shutdown_ltf / 32;
1049 			regmap_write(bat_power->regmap, AXP2202_VLTF_WORK, val);
1050 		}
1051 
1052 		if (axp_config->pmu_bat_shutdown_htf) {
1053 			if (axp_config->pmu_bat_shutdown_htf > axp_config->pmu_bat_charge_htf)
1054 				axp_config->pmu_bat_shutdown_htf = axp_config->pmu_bat_charge_htf;
1055 
1056 			val = axp_config->pmu_bat_shutdown_htf / 2;
1057 			regmap_write(bat_power->regmap, AXP2202_VHTF_WORK, val);
1058 		}
1059 
1060 	} else {
1061 		regmap_update_bits(bat_power->regmap, AXP2202_TS_CFG, AXP2202_TS_ENABLE_MARK, AXP2202_TS_ENABLE_MARK);
1062 	}
1063 
1064 	/* set jeita enable */
1065 	if (axp_config->pmu_jetia_en) {
1066 		regmap_update_bits(bat_power->regmap, AXP2202_JEITA_CFG, AXP2202_JEITA_ENABLE_MARK, 1);
1067 
1068 		/* set jeita cool vol */
1069 		if (axp_config->pmu_jetia_cool) {
1070 			if (axp_config->pmu_jetia_cool < axp_config->pmu_jetia_warm)
1071 				axp_config->pmu_jetia_cool = axp_config->pmu_jetia_warm;
1072 
1073 			val = axp_config->pmu_jetia_cool / 16;
1074 			regmap_write(bat_power->regmap, AXP2202_JEITA_COOL, val);
1075 		}
1076 
1077 		/* set jeita warm vol */
1078 		if (axp_config->pmu_jetia_warm) {
1079 			if (axp_config->pmu_jetia_warm > 2040)
1080 				axp_config->pmu_jetia_warm = 2040;
1081 
1082 			val = axp_config->pmu_jetia_warm/8;
1083 			regmap_write(bat_power->regmap, AXP2202_JEITA_WARM, val);
1084 		}
1085 
1086 		/* set jeita config */
1087 		regmap_read(bat_power->regmap, AXP2202_JEITA_CV_CFG, &val);
1088 		val &= 0x0F;
1089 		if (axp_config->pmu_jwarm_ifall)
1090 			val |= axp_config->pmu_jwarm_ifall << 6;
1091 
1092 		if (axp_config->pmu_jcool_ifall)
1093 			val |= axp_config->pmu_jcool_ifall << 4;
1094 
1095 		regmap_write(bat_power->regmap, AXP2202_JEITA_CV_CFG, val);
1096 
1097 	} else {
1098 		regmap_update_bits(bat_power->regmap, AXP2202_JEITA_CFG, AXP2202_JEITA_ENABLE_MARK, 0);
1099 	}
1100 
1101 	/* set CHGLED */
1102 	regmap_read(bat_power->regmap, AXP2202_CHGLED_CFG, &reg_value);
1103 	reg_value &= 0xf8;
1104 	if (axp_config->pmu_chgled_func) {
1105 		reg_value |= axp_config->pmu_chgled_type;
1106 		regmap_write(bat_power->regmap, AXP2202_CHGLED_CFG, reg_value);
1107 		}
1108 
1109 	/* set charger voltage limit */
1110 	if (axp_config->pmu_init_chgvol < 4100) {
1111 		regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_0V);
1112 	} else if (axp_config->pmu_init_chgvol < 4200) {
1113 		regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_1V);
1114 	} else if (axp_config->pmu_init_chgvol < 4350) {
1115 		regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_2V);
1116 	} else if (axp_config->pmu_init_chgvol < 4400) {
1117 		regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_35V);
1118 	} else if (axp_config->pmu_init_chgvol < 5000) {
1119 		regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_4V);
1120 	} else {
1121 		regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_5_0V);
1122 	}
1123 
1124 	/*  set charger charge current */
1125 	axp_config->pmu_runtime_chgcur = clamp_val(axp_config->pmu_runtime_chgcur, 0, 3072);
1126 	val = axp_config->pmu_runtime_chgcur / 64;
1127 	regmap_update_bits(bat_power->regmap, AXP2202_ICC_CFG, GENMASK(5, 0),
1128 				   val);
1129 
1130 	/* set gauge_thld */
1131 	val = clamp_val(axp_config->pmu_battery_warning_level1 - 5, 0, 15) << 4;
1132 	val |= clamp_val(axp_config->pmu_battery_warning_level2, 0, 15);
1133 	regmap_write(bat_power->regmap, AXP2202_GAUGE_THLD, val);
1134 
1135 	/* check soc & vbat*/
1136 	ret = regmap_bulk_read(bat_power->regmap, AXP2202_VBAT_H, temp_val, 2);
1137 	if (ret < 0)
1138 		return ret;
1139 	vbat = (((temp_val[0]) << 8) + temp_val[1]);
1140 	ret = regmap_read(bat_power->regmap, AXP2202_GAUGE_SOC, &reg_value);
1141 	if (ret < 0)
1142 		return ret;
1143 	soc = (int)(reg_value);
1144 	ret = regmap_read(bat_power->regmap, AXP2202_COMM_STAT0, &reg_value);
1145 	if (ret < 0)
1146 		return ret;
1147 	if (soc == 0) {
1148 		if (reg_value & BIT(5)) {
1149 			if (vbat > 3800) {
1150 				axp2202_reset_mcu(bat_power->regmap);
1151 				pr_warn("adapt reset gauge: soc = 0\n");
1152 			}
1153 		} else {
1154 			if (vbat > 3700) {
1155 				axp2202_reset_mcu(bat_power->regmap);
1156 				pr_warn("only battery reset gauge: soc = 0\n");
1157 			}
1158 		}
1159 	}
1160 	if (vbat < 3900 && soc > 98) {
1161 		axp2202_reset_mcu(bat_power->regmap);
1162 		pr_warn("reset gauge: vbat < 3900, soc > 98\n");
1163 	}
1164 
1165 	return ret;
1166 }
1167 
1168 
axp2202_irq_handler_bat_stat_change(int irq,void * data)1169 static irqreturn_t axp2202_irq_handler_bat_stat_change(int irq, void *data)
1170 {
1171 	struct irq_desc *id = irq_to_desc(irq);
1172 	struct axp2202_bat_power *bat_power = data;
1173 
1174 	pr_debug("%s: enter interrupt %d\n", __func__, irq);
1175 
1176 	power_supply_changed(bat_power->bat_supply);
1177 
1178 	switch (id->irq_data.hwirq) {
1179 	case AXP2202_IRQ_CHGDN:
1180 		pr_debug("interrupt:charger done");
1181 		break;
1182 	case AXP2202_IRQ_CHGST:
1183 		pr_debug("interrutp:charger start");
1184 		break;
1185 	case AXP2202_IRQ_BINSERT:
1186 		pr_debug("interrupt:battery insert");
1187 		break;
1188 	case AXP2202_IRQ_BREMOVE:
1189 		pr_debug("interrupt:battery remove");
1190 		break;
1191 	default:
1192 		pr_debug("interrupt:others");
1193 		break;
1194 	}
1195 
1196 	return IRQ_HANDLED;
1197 }
1198 
1199 enum axp2202_bat_virq_index {
1200 	AXP2202_VIRQ_BAT_IN,
1201 	AXP2202_VIRQ_BAT_OUT,
1202 	AXP2202_VIRQ_CHARGING,
1203 	AXP2202_VIRQ_CHARGE_OVER,
1204 	AXP2202_VIRQ_LOW_WARNING1,
1205 	AXP2202_VIRQ_LOW_WARNING2,
1206 	AXP2202_VIRQ_BAT_UNTEMP_WORK,
1207 	AXP2202_VIRQ_BAT_OVTEMP_WORK,
1208 	AXP2202_VIRQ_BAT_UNTEMP_CHG,
1209 	AXP2202_VIRQ_BAT_OVTEMP_CHG,
1210 	AXP2202_VIRQ_BAT_OV,
1211 	AXP2202_VIRQ_MAX_VIRQ,
1212 };
1213 
1214 static struct axp_interrupts axp_bat_irq[] = {
1215 	[AXP2202_VIRQ_BAT_IN] = { "battery_insert",
1216 				  axp2202_irq_handler_bat_stat_change },
1217 	[AXP2202_VIRQ_BAT_OUT] = { "battery_remove",
1218 				   axp2202_irq_handler_bat_stat_change },
1219 	[AXP2202_VIRQ_CHARGING] = { "charge_start",
1220 				    axp2202_irq_handler_bat_stat_change },
1221 	[AXP2202_VIRQ_CHARGE_OVER] = { "charge_done",
1222 				       axp2202_irq_handler_bat_stat_change },
1223 	[AXP2202_VIRQ_LOW_WARNING1] = { "SOC_low_warning1",
1224 					axp2202_irq_handler_bat_stat_change },
1225 	[AXP2202_VIRQ_LOW_WARNING2] = { "SOC_low_warning2",
1226 					axp2202_irq_handler_bat_stat_change },
1227 	[AXP2202_VIRQ_BAT_UNTEMP_WORK] = { "bat_work_under_temp",
1228 					   axp2202_irq_handler_bat_stat_change },
1229 	[AXP2202_VIRQ_BAT_OVTEMP_WORK] = { "bat_work_over_temp",
1230 					   axp2202_irq_handler_bat_stat_change },
1231 	[AXP2202_VIRQ_BAT_UNTEMP_CHG] = { "bat_chg_under_temp",
1232 					  axp2202_irq_handler_bat_stat_change },
1233 	[AXP2202_VIRQ_BAT_OVTEMP_CHG] = { "bat_chg_over_temp",
1234 					  axp2202_irq_handler_bat_stat_change },
1235 	[AXP2202_VIRQ_BAT_OV] = { "battery_over_voltage",
1236 					  axp2202_irq_handler_bat_stat_change },
1237 
1238 };
1239 
axp2202_bat_dt_parse(struct device_node * node,struct axp_config_info * axp_config)1240 int axp2202_bat_dt_parse(struct device_node *node,
1241 			 struct axp_config_info *axp_config)
1242 {
1243 	if (!of_device_is_available(node)) {
1244 		pr_err("%s: failed\n", __func__);
1245 		return -1;
1246 	}
1247 
1248 	AXP_OF_PROP_READ(pmu_battery_cap,                4000);
1249 	AXP_OF_PROP_READ(pmu_chg_ic_temp,                   0);
1250 	AXP_OF_PROP_READ(pmu_runtime_chgcur,              500);
1251 	AXP_OF_PROP_READ(pmu_suspend_chgcur,             1200);
1252 	AXP_OF_PROP_READ(pmu_shutdown_chgcur,            1200);
1253 	AXP_OF_PROP_READ(pmu_prechg_chgcur,               100);
1254 	AXP_OF_PROP_READ(pmu_terminal_chgcur,              50);
1255 	AXP_OF_PROP_READ(pmu_init_chgvol,                4200);
1256 	AXP_OF_PROP_READ(pmu_battery_warning_level1,       15);
1257 	AXP_OF_PROP_READ(pmu_battery_warning_level2,        0);
1258 	AXP_OF_PROP_READ(pmu_chgled_func,                   1);
1259 	AXP_OF_PROP_READ(pmu_chgled_type,                   0);
1260 	AXP_OF_PROP_READ(pmu_batdeten,                      1);
1261 
1262 	AXP_OF_PROP_READ(pmu_bat_ts_current,               50);
1263 	AXP_OF_PROP_READ(pmu_bat_charge_ltf,             1312);
1264 	AXP_OF_PROP_READ(pmu_bat_charge_htf,              176);
1265 	AXP_OF_PROP_READ(pmu_bat_shutdown_ltf,           1984);
1266 	AXP_OF_PROP_READ(pmu_bat_shutdown_htf,            152);
1267 
1268 	AXP_OF_PROP_READ(pmu_jetia_en,                      0);
1269 	AXP_OF_PROP_READ(pmu_jetia_cool,                  880);
1270 	AXP_OF_PROP_READ(pmu_jetia_warm,                  240);
1271 	AXP_OF_PROP_READ(pmu_jcool_ifall,                   1);
1272 	AXP_OF_PROP_READ(pmu_jwarm_ifall,                   0);
1273 
1274 	AXP_OF_PROP_READ(pmu_bat_temp_enable,               0);
1275 	AXP_OF_PROP_READ(pmu_bat_temp_para1,                0);
1276 	AXP_OF_PROP_READ(pmu_bat_temp_para2,                0);
1277 	AXP_OF_PROP_READ(pmu_bat_temp_para3,                0);
1278 	AXP_OF_PROP_READ(pmu_bat_temp_para4,                0);
1279 	AXP_OF_PROP_READ(pmu_bat_temp_para5,                0);
1280 	AXP_OF_PROP_READ(pmu_bat_temp_para6,                0);
1281 	AXP_OF_PROP_READ(pmu_bat_temp_para7,                0);
1282 	AXP_OF_PROP_READ(pmu_bat_temp_para8,                0);
1283 	AXP_OF_PROP_READ(pmu_bat_temp_para9,                0);
1284 	AXP_OF_PROP_READ(pmu_bat_temp_para10,               0);
1285 	AXP_OF_PROP_READ(pmu_bat_temp_para11,               0);
1286 	AXP_OF_PROP_READ(pmu_bat_temp_para12,               0);
1287 	AXP_OF_PROP_READ(pmu_bat_temp_para13,               0);
1288 	AXP_OF_PROP_READ(pmu_bat_temp_para14,               0);
1289 	AXP_OF_PROP_READ(pmu_bat_temp_para15,               0);
1290 	AXP_OF_PROP_READ(pmu_bat_temp_para16,               0);
1291 
1292 	axp_config->wakeup_bat_in =
1293 		of_property_read_bool(node, "wakeup_bat_in");
1294 	axp_config->wakeup_bat_out =
1295 		of_property_read_bool(node, "wakeup_bat_out");
1296 	axp_config->wakeup_bat_charging =
1297 		of_property_read_bool(node, "wakeup_bat_charging");
1298 	axp_config->wakeup_bat_charge_over =
1299 		of_property_read_bool(node, "wakeup_bat_charge_over");
1300 	axp_config->wakeup_low_warning1 =
1301 		of_property_read_bool(node, "wakeup_low_warning1");
1302 	axp_config->wakeup_low_warning2 =
1303 		of_property_read_bool(node, "wakeup_low_warning2");
1304 	axp_config->wakeup_bat_untemp_work =
1305 		of_property_read_bool(node, "wakeup_bat_untemp_work");
1306 	axp_config->wakeup_bat_ovtemp_work =
1307 		of_property_read_bool(node, "wakeup_bat_ovtemp_work");
1308 	axp_config->wakeup_untemp_chg =
1309 		of_property_read_bool(node, "wakeup_bat_untemp_chg");
1310 	axp_config->wakeup_ovtemp_chg =
1311 		of_property_read_bool(node, "wakeup_bat_ovtemp_chg");
1312 	axp_config->wakeup_bat_ov =
1313 		of_property_read_bool(node, "wakeup_bat_ov");
1314 
1315 
1316 	return 0;
1317 }
1318 
axp2202_bat_parse_device_tree(struct axp2202_bat_power * bat_power)1319 static void axp2202_bat_parse_device_tree(struct axp2202_bat_power *bat_power)
1320 {
1321 	int ret;
1322 	struct axp_config_info *axp_config;
1323 
1324 	/* set input current limit */
1325 	if (!bat_power->dev->of_node) {
1326 		pr_info("can not find device tree\n");
1327 		return;
1328 	}
1329 
1330 	axp_config = &bat_power->dts_info;
1331 	ret = axp2202_bat_dt_parse(bat_power->dev->of_node, axp_config);
1332 	if (ret) {
1333 		pr_info("can not parse device tree err\n");
1334 		return;
1335 	}
1336 }
1337 
axp2202_bat_power_monitor(struct work_struct * work)1338 static void axp2202_bat_power_monitor(struct work_struct *work)
1339 {
1340 	struct axp2202_bat_power *bat_power =
1341 		container_of(work, typeof(*bat_power), bat_supply_mon.work);
1342 	unsigned char temp_val[2];
1343 	unsigned int reg_value;
1344 	int ret;
1345 
1346 	power_supply_changed(bat_power->bat_supply);
1347 
1348 	 /* 0xb2, 0xb3 return mcoul high 16 bit value */
1349 	reg_value = 0x2e;
1350 	ret = regmap_write(bat_power->regmap, AXP2202_GAUGE_FG_ADDR, reg_value);
1351 
1352 	regmap_read(bat_power->regmap, AXP2202_GAUGE_CONFIG, &reg_value);
1353 	if (reg_value & BIT(4)) {
1354 		regmap_read(bat_power->regmap, AXP2202_GAUGE_FG_ADDR, &reg_value);
1355 		if (reg_value == 0x2e) {
1356 		/* reset gauge if  is overflow */
1357 		regmap_bulk_read(bat_power->regmap, AXP2202_GAUGE_FG_DATA_H, temp_val, 2);
1358 		reg_value = (temp_val[0] << 8) + temp_val[1];
1359 			if ((reg_value != 0xffff) && (reg_value != 0x0000)) {
1360 				axp2202_reset_mcu(bat_power->regmap);
1361 				pr_warn("reset gauge:mcoul overflow\n");
1362 			}
1363 		}
1364 	}
1365 
1366 	schedule_delayed_work(&bat_power->bat_supply_mon, msecs_to_jiffies(10 * 1000));
1367 }
1368 
1369 
axp2202_battery_probe(struct platform_device * pdev)1370 static int axp2202_battery_probe(struct platform_device *pdev)
1371 {
1372 	int ret = 0;
1373 	int i = 0, irq;
1374 
1375 	struct axp2202_bat_power *bat_power;
1376 	struct power_supply_config psy_cfg = {};
1377 	struct axp20x_dev *axp_dev = dev_get_drvdata(pdev->dev.parent);
1378 
1379 	if (!axp_dev->irq) {
1380 		pr_err("can not register axp2202-battery without irq\n");
1381 		return -EINVAL;
1382 	}
1383 
1384 	bat_power = devm_kzalloc(&pdev->dev, sizeof(*bat_power), GFP_KERNEL);
1385 	if (bat_power == NULL) {
1386 		pr_err("axp2202_bat_power alloc failed\n");
1387 		ret = -ENOMEM;
1388 		goto err;
1389 	}
1390 
1391 	bat_power->name = "axp2202_battery";
1392 	bat_power->dev = &pdev->dev;
1393 	bat_power->regmap = axp_dev->regmap;
1394 
1395 	/* for device tree parse */
1396 	axp2202_bat_parse_device_tree(bat_power);
1397 
1398 	ret = axp2202_init_chip(bat_power);
1399 	if (ret < 0) {
1400 		dev_err(bat_power->dev, "axp2202 init chip fail!\n");
1401 		ret = -ENODEV;
1402 		goto err;
1403 	}
1404 
1405 	psy_cfg.of_node = pdev->dev.of_node;
1406 	psy_cfg.drv_data = bat_power;
1407 
1408 	bat_power->bat_supply = devm_power_supply_register(bat_power->dev,
1409 			&axp2202_bat_desc, &psy_cfg);
1410 
1411 	if (IS_ERR(bat_power->bat_supply)) {
1412 		pr_err("axp2202 failed to register bat power\n");
1413 		ret = PTR_ERR(bat_power->bat_supply);
1414 		return ret;
1415 	}
1416 
1417 	for (i = 0; i < ARRAY_SIZE(axp_bat_irq); i++) {
1418 		irq = platform_get_irq_byname(pdev, axp_bat_irq[i].name);
1419 		if (irq < 0)
1420 			continue;
1421 
1422 		irq = regmap_irq_get_virq(axp_dev->regmap_irqc, irq);
1423 		if (irq < 0) {
1424 			dev_err(&pdev->dev, "can not get irq\n");
1425 			return irq;
1426 		}
1427 		/* we use this variable to suspend irq */
1428 		axp_bat_irq[i].irq = irq;
1429 		ret = devm_request_any_context_irq(&pdev->dev, irq,
1430 						   axp_bat_irq[i].isr, 0,
1431 						   axp_bat_irq[i].name, bat_power);
1432 		if (ret < 0) {
1433 			dev_err(&pdev->dev, "failed to request %s IRQ %d: %d\n",
1434 				axp_bat_irq[i].name, irq, ret);
1435 			return ret;
1436 		} else {
1437 			ret = 0;
1438 		}
1439 
1440 		dev_dbg(&pdev->dev, "Requested %s IRQ %d: %d\n",
1441 			axp_bat_irq[i].name, irq, ret);
1442 	}
1443 	platform_set_drvdata(pdev, bat_power);
1444 
1445 	INIT_DELAYED_WORK(&bat_power->bat_supply_mon, axp2202_bat_power_monitor);
1446 	schedule_delayed_work(&bat_power->bat_supply_mon, msecs_to_jiffies(500));
1447 
1448 	return ret;
1449 
1450 err:
1451 	pr_err("%s,probe fail, ret = %d\n", __func__, ret);
1452 
1453 	return ret;
1454 }
1455 
axp2202_battery_remove(struct platform_device * pdev)1456 static int axp2202_battery_remove(struct platform_device *pdev)
1457 {
1458 	struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1459 
1460 	dev_dbg(&pdev->dev, "==============AXP2202 unegister==============\n");
1461 	if (bat_power->bat_supply)
1462 		power_supply_unregister(bat_power->bat_supply);
1463 	dev_dbg(&pdev->dev, "axp2202 teardown battery dev\n");
1464 
1465 	return 0;
1466 }
1467 
axp2202_charger_ichg_set(struct axp2202_bat_power * bat_power,int mA)1468 static void axp2202_charger_ichg_set(struct axp2202_bat_power *bat_power, int mA)
1469 {
1470 
1471 	mA = clamp_val(mA, 0, 3072);
1472 	mA = mA / 64;
1473 	/* bit 5:0 is the ctrl bit */
1474 	regmap_update_bits(bat_power->regmap, AXP2202_ICC_CFG, GENMASK(5, 0), mA);
1475 }
1476 
axp2202_bat_irq_set(unsigned int irq,bool enable)1477 static inline void axp2202_bat_irq_set(unsigned int irq, bool enable)
1478 {
1479 	if (enable)
1480 		enable_irq(irq);
1481 	else
1482 		disable_irq(irq);
1483 }
1484 
axp2202_bat_virq_dts_set(struct axp2202_bat_power * bat_power,bool enable)1485 static void axp2202_bat_virq_dts_set(struct axp2202_bat_power *bat_power, bool enable)
1486 {
1487 	struct axp_config_info *dts_info = &bat_power->dts_info;
1488 
1489 	if (!dts_info->wakeup_bat_in)
1490 		axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_BAT_IN].irq,
1491 				enable);
1492 	if (!dts_info->wakeup_bat_out)
1493 		axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_BAT_OUT].irq,
1494 				enable);
1495 	if (!dts_info->wakeup_bat_charging)
1496 		axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_CHARGING].irq,
1497 				enable);
1498 	if (!dts_info->wakeup_bat_charge_over)
1499 		axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_CHARGE_OVER].irq,
1500 				enable);
1501 	if (!dts_info->wakeup_low_warning1)
1502 		axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_LOW_WARNING1].irq,
1503 				enable);
1504 	if (!dts_info->wakeup_low_warning2)
1505 		axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_LOW_WARNING2].irq,
1506 				enable);
1507 	if (!dts_info->wakeup_bat_untemp_work)
1508 		axp2202_bat_irq_set(
1509 			axp_bat_irq[AXP2202_VIRQ_BAT_UNTEMP_WORK].irq,
1510 			enable);
1511 	if (!dts_info->wakeup_bat_ovtemp_work)
1512 		axp2202_bat_irq_set(
1513 			axp_bat_irq[AXP2202_VIRQ_BAT_OVTEMP_WORK].irq,
1514 			enable);
1515 	if (!dts_info->wakeup_untemp_chg)
1516 		axp2202_bat_irq_set(
1517 			axp_bat_irq[AXP2202_VIRQ_BAT_UNTEMP_CHG].irq,
1518 			enable);
1519 	if (!dts_info->wakeup_ovtemp_chg)
1520 		axp2202_bat_irq_set(
1521 			axp_bat_irq[AXP2202_VIRQ_BAT_OVTEMP_CHG].irq,
1522 			enable);
1523 	if (!dts_info->wakeup_bat_ov)
1524 		axp2202_bat_irq_set(
1525 			axp_bat_irq[AXP2202_VIRQ_BAT_OV].irq,
1526 			enable);
1527 
1528 }
1529 
axp2202_bat_shutdown(struct platform_device * pdev)1530 static void axp2202_bat_shutdown(struct platform_device *pdev)
1531 {
1532 	struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1533 
1534 	axp2202_charger_ichg_set(bat_power, bat_power->dts_info.pmu_shutdown_chgcur);
1535 
1536 }
1537 
axp2202_bat_suspend(struct platform_device * pdev,pm_message_t state)1538 static int axp2202_bat_suspend(struct platform_device *pdev, pm_message_t state)
1539 {
1540 	struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1541 
1542 	axp2202_charger_ichg_set(bat_power, bat_power->dts_info.pmu_suspend_chgcur);
1543 
1544 	axp2202_bat_virq_dts_set(bat_power, false);
1545 	return 0;
1546 }
1547 
axp2202_bat_resume(struct platform_device * pdev)1548 static int axp2202_bat_resume(struct platform_device *pdev)
1549 {
1550 	struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1551 
1552 	power_supply_changed(bat_power->bat_supply);
1553 
1554 	axp2202_charger_ichg_set(bat_power, bat_power->dts_info.pmu_runtime_chgcur);
1555 
1556 	axp2202_bat_virq_dts_set(bat_power, true);
1557 
1558 	return 0;
1559 }
1560 
1561 static const struct of_device_id axp2202_bat_power_match[] = {
1562 	{
1563 		.compatible = "x-powers,axp2202-bat-power-supply",
1564 		.data = (void *)AXP2202_ID,
1565 	}, {/* sentinel */}
1566 };
1567 MODULE_DEVICE_TABLE(of, axp2202_bat_power_match);
1568 
1569 static struct platform_driver axp2202_bat_power_driver = {
1570 	.driver = {
1571 		.name = "axp2202-bat-power-supply",
1572 		.of_match_table = axp2202_bat_power_match,
1573 	},
1574 	.probe = axp2202_battery_probe,
1575 	.remove = axp2202_battery_remove,
1576 	.shutdown = axp2202_bat_shutdown,
1577 	.suspend = axp2202_bat_suspend,
1578 	.resume = axp2202_bat_resume,
1579 };
1580 
1581 module_platform_driver(axp2202_bat_power_driver);
1582 
1583 MODULE_AUTHOR("wangxiaoliang <wangxiaoliang@x-powers.com>");
1584 MODULE_DESCRIPTION("axp2202 battery driver");
1585 MODULE_LICENSE("GPL");
1586 
1587 
1588