]>
Commit | Line | Data |
---|---|---|
11cb8da0 CM |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Charger Driver for Rockchip rk817 | |
4 | * | |
5 | * Copyright (c) 2021 Maya Matuszczyk <maccraft123mc@gmail.com> | |
6 | * | |
7 | * Authors: Maya Matuszczyk <maccraft123mc@gmail.com> | |
8 | * Chris Morgan <macromorgan@hotmail.com> | |
9 | */ | |
10 | ||
11 | #include <asm/unaligned.h> | |
12 | #include <linux/devm-helpers.h> | |
13 | #include <linux/mfd/rk808.h> | |
14 | #include <linux/irq.h> | |
15 | #include <linux/of.h> | |
16 | #include <linux/platform_device.h> | |
17 | #include <linux/power_supply.h> | |
18 | #include <linux/regmap.h> | |
19 | ||
20 | /* Charging statuses reported by hardware register */ | |
21 | enum rk817_charge_status { | |
22 | CHRG_OFF, | |
23 | DEAD_CHRG, | |
24 | TRICKLE_CHRG, | |
25 | CC_OR_CV_CHRG, | |
26 | CHARGE_FINISH, | |
27 | USB_OVER_VOL, | |
28 | BAT_TMP_ERR, | |
29 | BAT_TIM_ERR, | |
30 | }; | |
31 | ||
32 | /* | |
33 | * Max charging current read to/written from hardware register. | |
34 | * Note how highest value corresponding to 0x7 is the lowest | |
35 | * current, this is per the datasheet. | |
36 | */ | |
37 | enum rk817_chg_cur { | |
38 | CHG_1A, | |
39 | CHG_1_5A, | |
40 | CHG_2A, | |
41 | CHG_2_5A, | |
42 | CHG_2_75A, | |
43 | CHG_3A, | |
44 | CHG_3_5A, | |
45 | CHG_0_5A, | |
46 | }; | |
47 | ||
48 | struct rk817_charger { | |
49 | struct device *dev; | |
50 | struct rk808 *rk808; | |
51 | ||
52 | struct power_supply *bat_ps; | |
53 | struct power_supply *chg_ps; | |
54 | bool plugged_in; | |
55 | bool battery_present; | |
56 | ||
57 | /* | |
58 | * voltage_k and voltage_b values are used to calibrate the ADC | |
59 | * voltage readings. While they are documented in the BSP kernel and | |
60 | * datasheet as voltage_k and voltage_b, there is no further | |
61 | * information explaining them in more detail. | |
62 | */ | |
63 | ||
64 | uint32_t voltage_k; | |
65 | uint32_t voltage_b; | |
66 | ||
67 | /* | |
68 | * soc - state of charge - like the BSP this is stored as a percentage, | |
69 | * to the thousandth. BSP has a display state of charge (dsoc) and a | |
70 | * remaining state of charge (rsoc). This value will be used for both | |
71 | * purposes here so we don't do any fancy math to try and "smooth" the | |
72 | * charge and just report it as it is. Note for example an soc of 100 | |
73 | * is stored as 100000, an soc of 50 is stored as 50000, etc. | |
74 | */ | |
75 | int soc; | |
76 | ||
77 | /* | |
78 | * Capacity of battery when fully charged, equal or less than design | |
79 | * capacity depending upon wear. BSP kernel saves to nvram in mAh, | |
80 | * so this value is in mAh not the standard uAh. | |
81 | */ | |
82 | int fcc_mah; | |
83 | ||
84 | /* | |
85 | * Calibrate the SOC on a fully charged battery, this way we can use | |
86 | * the calibrated SOC value to correct for columb counter drift. | |
87 | */ | |
88 | bool soc_cal; | |
89 | ||
90 | /* Implementation specific immutable properties from device tree */ | |
91 | int res_div; | |
92 | int sleep_enter_current_ua; | |
93 | int sleep_filter_current_ua; | |
94 | int bat_charge_full_design_uah; | |
95 | int bat_voltage_min_design_uv; | |
96 | int bat_voltage_max_design_uv; | |
97 | ||
98 | /* Values updated periodically by driver for display. */ | |
99 | int charge_now_uah; | |
100 | int volt_avg_uv; | |
101 | int cur_avg_ua; | |
102 | int max_chg_cur_ua; | |
103 | int max_chg_volt_uv; | |
104 | int charge_status; | |
105 | int charger_input_volt_avg_uv; | |
106 | ||
107 | /* Work queue to periodically update values. */ | |
108 | struct delayed_work work; | |
109 | }; | |
110 | ||
111 | /* ADC coefficients extracted from BSP kernel */ | |
112 | #define ADC_TO_CURRENT(adc_value, res_div) \ | |
113 | (adc_value * 172 / res_div) | |
114 | ||
115 | #define CURRENT_TO_ADC(current, samp_res) \ | |
116 | (current * samp_res / 172) | |
117 | ||
118 | #define CHARGE_TO_ADC(capacity, res_div) \ | |
119 | (capacity * res_div * 3600 / 172 * 1000) | |
120 | ||
121 | #define ADC_TO_CHARGE_UAH(adc_value, res_div) \ | |
122 | (adc_value / 3600 * 172 / res_div) | |
123 | ||
883babd4 | 124 | static int rk817_chg_cur_to_reg(u32 chg_cur_ma) |
11cb8da0 CM |
125 | { |
126 | if (chg_cur_ma >= 3500) | |
127 | return CHG_3_5A; | |
128 | else if (chg_cur_ma >= 3000) | |
129 | return CHG_3A; | |
130 | else if (chg_cur_ma >= 2750) | |
131 | return CHG_2_75A; | |
132 | else if (chg_cur_ma >= 2500) | |
133 | return CHG_2_5A; | |
134 | else if (chg_cur_ma >= 2000) | |
135 | return CHG_2A; | |
136 | else if (chg_cur_ma >= 1500) | |
137 | return CHG_1_5A; | |
138 | else if (chg_cur_ma >= 1000) | |
139 | return CHG_1A; | |
140 | else if (chg_cur_ma >= 500) | |
141 | return CHG_0_5A; | |
142 | else | |
143 | return -EINVAL; | |
144 | } | |
145 | ||
146 | static int rk817_chg_cur_from_reg(u8 reg) | |
147 | { | |
148 | switch (reg) { | |
149 | case CHG_0_5A: | |
150 | return 500000; | |
151 | case CHG_1A: | |
152 | return 1000000; | |
153 | case CHG_1_5A: | |
154 | return 1500000; | |
155 | case CHG_2A: | |
156 | return 2000000; | |
157 | case CHG_2_5A: | |
158 | return 2500000; | |
159 | case CHG_2_75A: | |
160 | return 2750000; | |
161 | case CHG_3A: | |
162 | return 3000000; | |
163 | case CHG_3_5A: | |
164 | return 3500000; | |
165 | default: | |
166 | return -EINVAL; | |
167 | } | |
168 | } | |
169 | ||
170 | static void rk817_bat_calib_vol(struct rk817_charger *charger) | |
171 | { | |
172 | uint32_t vcalib0 = 0; | |
173 | uint32_t vcalib1 = 0; | |
174 | u8 bulk_reg[2]; | |
175 | ||
176 | /* calibrate voltage */ | |
177 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB0_H, | |
178 | bulk_reg, 2); | |
179 | vcalib0 = get_unaligned_be16(bulk_reg); | |
180 | ||
181 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB1_H, | |
182 | bulk_reg, 2); | |
183 | vcalib1 = get_unaligned_be16(bulk_reg); | |
184 | ||
185 | /* values were taken from BSP kernel */ | |
186 | charger->voltage_k = (4025 - 2300) * 1000 / | |
187 | ((vcalib1 - vcalib0) ? (vcalib1 - vcalib0) : 1); | |
188 | charger->voltage_b = 4025 - (charger->voltage_k * vcalib1) / 1000; | |
189 | } | |
190 | ||
191 | static void rk817_bat_calib_cur(struct rk817_charger *charger) | |
192 | { | |
193 | u8 bulk_reg[2]; | |
194 | ||
195 | /* calibrate current */ | |
196 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_IOFFSET_H, | |
197 | bulk_reg, 2); | |
198 | regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_CAL_OFFSET_H, | |
199 | bulk_reg, 2); | |
200 | } | |
201 | ||
202 | /* | |
203 | * note that only the fcc_mah is really used by this driver, the other values | |
204 | * are to ensure we can remain backwards compatible with the BSP kernel. | |
205 | */ | |
206 | static int rk817_record_battery_nvram_values(struct rk817_charger *charger) | |
207 | { | |
208 | u8 bulk_reg[3]; | |
209 | int ret, rsoc; | |
210 | ||
211 | /* | |
212 | * write the soc value to the nvram location used by the BSP kernel | |
213 | * for the dsoc value. | |
214 | */ | |
215 | put_unaligned_le24(charger->soc, bulk_reg); | |
216 | ret = regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_R1, | |
217 | bulk_reg, 3); | |
218 | if (ret < 0) | |
219 | return ret; | |
220 | /* | |
221 | * write the remaining capacity in mah to the nvram location used by | |
222 | * the BSP kernel for the rsoc value. | |
223 | */ | |
224 | rsoc = (charger->soc * charger->fcc_mah) / 100000; | |
225 | put_unaligned_le24(rsoc, bulk_reg); | |
226 | ret = regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_DATA0, | |
227 | bulk_reg, 3); | |
228 | if (ret < 0) | |
229 | return ret; | |
230 | /* write the fcc_mah in mAh, just as the BSP kernel does. */ | |
231 | put_unaligned_le24(charger->fcc_mah, bulk_reg); | |
232 | ret = regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_DATA3, | |
233 | bulk_reg, 3); | |
234 | if (ret < 0) | |
235 | return ret; | |
236 | ||
237 | return 0; | |
238 | } | |
239 | ||
240 | static int rk817_bat_calib_cap(struct rk817_charger *charger) | |
241 | { | |
242 | struct rk808 *rk808 = charger->rk808; | |
243 | int tmp, charge_now, charge_now_adc, volt_avg; | |
244 | u8 bulk_reg[4]; | |
245 | ||
246 | /* Calibrate the soc and fcc on a fully charged battery */ | |
247 | ||
248 | if (charger->charge_status == CHARGE_FINISH && (!charger->soc_cal)) { | |
249 | /* | |
250 | * soc should be 100000 and columb counter should show the full | |
251 | * charge capacity. Note that if the device is unplugged for a | |
252 | * period of several days the columb counter will have a large | |
253 | * margin of error, so setting it back to the full charge on | |
254 | * a completed charge cycle should correct this (my device was | |
255 | * showing 33% battery after 3 days unplugged when it should | |
256 | * have been closer to 95% based on voltage and charge | |
257 | * current). | |
258 | */ | |
259 | ||
260 | charger->soc = 100000; | |
261 | charge_now_adc = CHARGE_TO_ADC(charger->fcc_mah, | |
262 | charger->res_div); | |
263 | put_unaligned_be32(charge_now_adc, bulk_reg); | |
264 | regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3, | |
265 | bulk_reg, 4); | |
266 | ||
267 | charger->soc_cal = 1; | |
268 | dev_dbg(charger->dev, | |
269 | "Fully charged. SOC is %d, full capacity is %d\n", | |
270 | charger->soc, charger->fcc_mah * 1000); | |
271 | } | |
272 | ||
273 | /* | |
274 | * The columb counter can drift up slightly, so we should correct for | |
275 | * it. But don't correct it until we're at 100% soc. | |
276 | */ | |
277 | if (charger->charge_status == CHARGE_FINISH && charger->soc_cal) { | |
278 | regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, | |
279 | bulk_reg, 4); | |
280 | charge_now_adc = get_unaligned_be32(bulk_reg); | |
281 | if (charge_now_adc < 0) | |
282 | return charge_now_adc; | |
283 | charge_now = ADC_TO_CHARGE_UAH(charge_now_adc, | |
284 | charger->res_div); | |
285 | ||
286 | /* | |
287 | * Re-init columb counter with updated values to correct drift. | |
288 | */ | |
289 | if (charge_now / 1000 > charger->fcc_mah) { | |
290 | dev_dbg(charger->dev, | |
291 | "Recalibrating columb counter to %d uah\n", | |
292 | charge_now); | |
293 | /* | |
294 | * Order of operations matters here to ensure we keep | |
295 | * enough precision until the last step to keep from | |
296 | * making needless updates to columb counter. | |
297 | */ | |
298 | charge_now_adc = CHARGE_TO_ADC(charger->fcc_mah, | |
299 | charger->res_div); | |
300 | put_unaligned_be32(charge_now_adc, bulk_reg); | |
301 | regmap_bulk_write(rk808->regmap, | |
302 | RK817_GAS_GAUGE_Q_INIT_H3, | |
303 | bulk_reg, 4); | |
304 | } | |
305 | } | |
306 | ||
307 | /* | |
308 | * Calibrate the fully charged capacity when we previously had a full | |
309 | * battery (soc_cal = 1) and are now empty (at or below minimum design | |
310 | * voltage). If our columb counter is still positive, subtract that | |
311 | * from our fcc value to get a calibrated fcc, and if our columb | |
312 | * counter is negative add that to our fcc (but not to exceed our | |
313 | * design capacity). | |
314 | */ | |
315 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H, | |
316 | bulk_reg, 2); | |
317 | tmp = get_unaligned_be16(bulk_reg); | |
318 | volt_avg = (charger->voltage_k * tmp) + 1000 * charger->voltage_b; | |
319 | if (volt_avg <= charger->bat_voltage_min_design_uv && | |
320 | charger->soc_cal) { | |
321 | regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, | |
322 | bulk_reg, 4); | |
323 | charge_now_adc = get_unaligned_be32(bulk_reg); | |
324 | charge_now = ADC_TO_CHARGE_UAH(charge_now_adc, | |
325 | charger->res_div); | |
326 | /* | |
327 | * Note, if charge_now is negative this will add it (what we | |
328 | * want) and if it's positive this will subtract (also what | |
329 | * we want). | |
330 | */ | |
331 | charger->fcc_mah = charger->fcc_mah - (charge_now / 1000); | |
332 | ||
333 | dev_dbg(charger->dev, | |
334 | "Recalibrating full charge capacity to %d uah\n", | |
335 | charger->fcc_mah * 1000); | |
336 | } | |
337 | ||
baba1315 CM |
338 | /* |
339 | * Set the SOC to 0 if we are below the minimum system voltage. | |
340 | */ | |
341 | if (volt_avg <= charger->bat_voltage_min_design_uv) { | |
342 | charger->soc = 0; | |
343 | charge_now_adc = CHARGE_TO_ADC(0, charger->res_div); | |
344 | put_unaligned_be32(charge_now_adc, bulk_reg); | |
345 | regmap_bulk_write(rk808->regmap, | |
346 | RK817_GAS_GAUGE_Q_INIT_H3, bulk_reg, 4); | |
347 | dev_warn(charger->dev, | |
348 | "Battery voltage %d below minimum voltage %d\n", | |
349 | volt_avg, charger->bat_voltage_min_design_uv); | |
350 | } | |
351 | ||
11cb8da0 CM |
352 | rk817_record_battery_nvram_values(charger); |
353 | ||
354 | return 0; | |
355 | } | |
356 | ||
357 | static void rk817_read_props(struct rk817_charger *charger) | |
358 | { | |
359 | int tmp, reg; | |
360 | u8 bulk_reg[4]; | |
361 | ||
362 | /* | |
363 | * Recalibrate voltage and current readings if we need to BSP does both | |
364 | * on CUR_CALIB_UPD, ignoring VOL_CALIB_UPD. Curiously enough, both | |
365 | * documentation and the BSP show that you perform an update if bit 7 | |
366 | * is 1, but you clear the status by writing a 1 to bit 7. | |
367 | */ | |
368 | regmap_read(charger->rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1, ®); | |
369 | if (reg & RK817_VOL_CUR_CALIB_UPD) { | |
370 | rk817_bat_calib_cur(charger); | |
371 | rk817_bat_calib_vol(charger); | |
372 | regmap_write_bits(charger->rk808->regmap, | |
373 | RK817_GAS_GAUGE_ADC_CONFIG1, | |
374 | RK817_VOL_CUR_CALIB_UPD, | |
375 | RK817_VOL_CUR_CALIB_UPD); | |
376 | } | |
377 | ||
378 | /* Update reported charge. */ | |
379 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, | |
380 | bulk_reg, 4); | |
381 | tmp = get_unaligned_be32(bulk_reg); | |
382 | charger->charge_now_uah = ADC_TO_CHARGE_UAH(tmp, charger->res_div); | |
383 | if (charger->charge_now_uah < 0) | |
384 | charger->charge_now_uah = 0; | |
385 | if (charger->charge_now_uah > charger->fcc_mah * 1000) | |
386 | charger->charge_now_uah = charger->fcc_mah * 1000; | |
387 | ||
388 | /* Update soc based on reported charge. */ | |
389 | charger->soc = charger->charge_now_uah * 100 / charger->fcc_mah; | |
390 | ||
391 | /* Update reported voltage. */ | |
392 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H, | |
393 | bulk_reg, 2); | |
394 | tmp = get_unaligned_be16(bulk_reg); | |
395 | charger->volt_avg_uv = (charger->voltage_k * tmp) + 1000 * | |
396 | charger->voltage_b; | |
397 | ||
398 | /* | |
399 | * Update reported current. Note value from registers is a signed 16 | |
400 | * bit int. | |
401 | */ | |
402 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_CUR_H, | |
403 | bulk_reg, 2); | |
404 | tmp = (short int)get_unaligned_be16(bulk_reg); | |
405 | charger->cur_avg_ua = ADC_TO_CURRENT(tmp, charger->res_div); | |
406 | ||
407 | /* | |
408 | * Update the max charge current. This value shouldn't change, but we | |
409 | * can read it to report what the PMIC says it is instead of simply | |
410 | * returning the default value. | |
411 | */ | |
412 | regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_OUT, ®); | |
413 | charger->max_chg_cur_ua = | |
414 | rk817_chg_cur_from_reg(reg & RK817_CHRG_CUR_SEL); | |
415 | ||
416 | /* | |
417 | * Update max charge voltage. Like the max charge current this value | |
418 | * shouldn't change, but we can report what the PMIC says. | |
419 | */ | |
420 | regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_OUT, ®); | |
421 | charger->max_chg_volt_uv = ((((reg & RK817_CHRG_VOL_SEL) >> 4) * | |
422 | 50000) + 4100000); | |
423 | ||
424 | /* Check if battery still present. */ | |
425 | regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_STS, ®); | |
426 | charger->battery_present = (reg & RK817_BAT_EXS); | |
427 | ||
428 | /* Get which type of charge we are using (if any). */ | |
429 | regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_STS, ®); | |
430 | charger->charge_status = (reg >> 4) & 0x07; | |
431 | ||
432 | /* | |
433 | * Get charger input voltage. Note that on my example hardware (an | |
434 | * Odroid Go Advance) the voltage of the power connector is measured | |
435 | * on the register labelled USB in the datasheet; I don't know if this | |
436 | * is how it is designed or just a quirk of the implementation. I | |
437 | * believe this will also measure the voltage of the USB output when in | |
438 | * OTG mode, if that is the case we may need to change this in the | |
439 | * future to return 0 if the power supply status is offline (I can't | |
440 | * test this with my current implementation. Also, when the voltage | |
441 | * should be zero sometimes the ADC still shows a single bit (which | |
442 | * would register as 20000uv). When this happens set it to 0. | |
443 | */ | |
444 | regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_USB_VOL_H, | |
445 | bulk_reg, 2); | |
446 | reg = get_unaligned_be16(bulk_reg); | |
447 | if (reg > 1) { | |
448 | tmp = ((charger->voltage_k * reg / 1000 + charger->voltage_b) * | |
449 | 60 / 46); | |
450 | charger->charger_input_volt_avg_uv = tmp * 1000; | |
451 | } else { | |
452 | charger->charger_input_volt_avg_uv = 0; | |
453 | } | |
454 | ||
455 | /* Calibrate battery capacity and soc. */ | |
456 | rk817_bat_calib_cap(charger); | |
457 | } | |
458 | ||
459 | static int rk817_bat_get_prop(struct power_supply *ps, | |
460 | enum power_supply_property prop, | |
461 | union power_supply_propval *val) | |
462 | { | |
463 | struct rk817_charger *charger = power_supply_get_drvdata(ps); | |
464 | ||
465 | switch (prop) { | |
466 | case POWER_SUPPLY_PROP_PRESENT: | |
467 | val->intval = charger->battery_present; | |
468 | break; | |
469 | case POWER_SUPPLY_PROP_STATUS: | |
470 | if (charger->cur_avg_ua < 0) { | |
471 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | |
472 | break; | |
473 | } | |
474 | switch (charger->charge_status) { | |
475 | case CHRG_OFF: | |
476 | val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; | |
477 | break; | |
478 | /* | |
479 | * Dead charge is documented, but not explained. I never | |
480 | * observed it but assume it's a pre-charge for a dead | |
481 | * battery. | |
482 | */ | |
483 | case DEAD_CHRG: | |
484 | case TRICKLE_CHRG: | |
485 | case CC_OR_CV_CHRG: | |
486 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | |
487 | break; | |
488 | case CHARGE_FINISH: | |
489 | val->intval = POWER_SUPPLY_STATUS_FULL; | |
490 | break; | |
491 | default: | |
492 | val->intval = POWER_SUPPLY_STATUS_UNKNOWN; | |
493 | return -EINVAL; | |
494 | ||
495 | } | |
496 | break; | |
497 | case POWER_SUPPLY_PROP_CHARGE_TYPE: | |
498 | switch (charger->charge_status) { | |
499 | case CHRG_OFF: | |
500 | case CHARGE_FINISH: | |
501 | val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; | |
502 | break; | |
503 | case TRICKLE_CHRG: | |
504 | val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; | |
505 | break; | |
506 | case DEAD_CHRG: | |
507 | case CC_OR_CV_CHRG: | |
508 | val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD; | |
509 | break; | |
510 | default: | |
511 | val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; | |
512 | break; | |
513 | } | |
514 | break; | |
515 | case POWER_SUPPLY_PROP_CHARGE_FULL: | |
516 | val->intval = charger->fcc_mah * 1000; | |
517 | break; | |
518 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | |
519 | val->intval = charger->bat_charge_full_design_uah; | |
520 | break; | |
521 | case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: | |
522 | val->intval = 0; | |
523 | break; | |
524 | case POWER_SUPPLY_PROP_CHARGE_NOW: | |
525 | val->intval = charger->charge_now_uah; | |
526 | break; | |
527 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | |
528 | val->intval = charger->bat_voltage_min_design_uv; | |
529 | break; | |
530 | case POWER_SUPPLY_PROP_CAPACITY: | |
531 | /* Add 500 so that values like 99999 are 100% not 99%. */ | |
532 | val->intval = (charger->soc + 500) / 1000; | |
533 | if (val->intval > 100) | |
534 | val->intval = 100; | |
535 | if (val->intval < 0) | |
536 | val->intval = 0; | |
537 | break; | |
538 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | |
539 | val->intval = charger->volt_avg_uv; | |
540 | break; | |
541 | case POWER_SUPPLY_PROP_CURRENT_AVG: | |
542 | val->intval = charger->cur_avg_ua; | |
543 | break; | |
544 | case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: | |
545 | val->intval = charger->max_chg_cur_ua; | |
546 | break; | |
547 | case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: | |
548 | val->intval = charger->max_chg_volt_uv; | |
549 | break; | |
550 | case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: | |
551 | val->intval = charger->bat_voltage_max_design_uv; | |
552 | break; | |
553 | default: | |
554 | return -EINVAL; | |
555 | } | |
556 | return 0; | |
557 | } | |
558 | ||
559 | static int rk817_chg_get_prop(struct power_supply *ps, | |
560 | enum power_supply_property prop, | |
561 | union power_supply_propval *val) | |
562 | { | |
563 | struct rk817_charger *charger = power_supply_get_drvdata(ps); | |
564 | ||
565 | switch (prop) { | |
566 | case POWER_SUPPLY_PROP_ONLINE: | |
567 | val->intval = charger->plugged_in; | |
568 | break; | |
569 | case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: | |
570 | /* max voltage from datasheet at 5.5v (default 5.0v) */ | |
571 | val->intval = 5500000; | |
572 | break; | |
573 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: | |
574 | /* min voltage from datasheet at 3.8v (default 5.0v) */ | |
575 | val->intval = 3800000; | |
576 | break; | |
577 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | |
578 | val->intval = charger->charger_input_volt_avg_uv; | |
579 | break; | |
580 | /* | |
581 | * While it's possible that other implementations could use different | |
582 | * USB types, the current implementation for this PMIC (the Odroid Go | |
583 | * Advance) only uses a dedicated charging port with no rx/tx lines. | |
584 | */ | |
585 | case POWER_SUPPLY_PROP_USB_TYPE: | |
586 | val->intval = POWER_SUPPLY_USB_TYPE_DCP; | |
587 | break; | |
588 | default: | |
589 | return -EINVAL; | |
590 | } | |
591 | return 0; | |
592 | ||
593 | } | |
594 | ||
595 | static irqreturn_t rk817_plug_in_isr(int irq, void *cg) | |
596 | { | |
597 | struct rk817_charger *charger; | |
598 | ||
599 | charger = (struct rk817_charger *)cg; | |
600 | charger->plugged_in = 1; | |
601 | power_supply_changed(charger->chg_ps); | |
602 | power_supply_changed(charger->bat_ps); | |
603 | /* try to recalibrate capacity if we hit full charge. */ | |
604 | charger->soc_cal = 0; | |
605 | ||
606 | rk817_read_props(charger); | |
607 | ||
608 | dev_dbg(charger->dev, "Power Cord Inserted\n"); | |
609 | ||
610 | return IRQ_HANDLED; | |
611 | } | |
612 | ||
613 | static irqreturn_t rk817_plug_out_isr(int irq, void *cg) | |
614 | { | |
615 | struct rk817_charger *charger; | |
616 | struct rk808 *rk808; | |
617 | ||
618 | charger = (struct rk817_charger *)cg; | |
619 | rk808 = charger->rk808; | |
620 | charger->plugged_in = 0; | |
621 | power_supply_changed(charger->bat_ps); | |
622 | power_supply_changed(charger->chg_ps); | |
623 | ||
624 | /* | |
625 | * For some reason the bits of RK817_PMIC_CHRG_IN reset whenever the | |
626 | * power cord is unplugged. This was not documented in the BSP kernel | |
627 | * or the datasheet and only discovered by trial and error. Set minimum | |
628 | * USB input voltage to 4.5v and enable USB voltage input limit. | |
629 | */ | |
630 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, | |
631 | RK817_USB_VLIM_SEL, (0x05 << 4)); | |
632 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN, | |
633 | (0x01 << 7)); | |
634 | ||
635 | /* | |
636 | * Set average USB input current limit to 1.5A and enable USB current | |
637 | * input limit. | |
638 | */ | |
639 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, | |
640 | RK817_USB_ILIM_SEL, 0x03); | |
641 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN, | |
642 | (0x01 << 3)); | |
643 | ||
644 | rk817_read_props(charger); | |
645 | ||
646 | dev_dbg(charger->dev, "Power Cord Removed\n"); | |
647 | ||
648 | return IRQ_HANDLED; | |
649 | } | |
650 | ||
651 | static enum power_supply_property rk817_bat_props[] = { | |
652 | POWER_SUPPLY_PROP_PRESENT, | |
653 | POWER_SUPPLY_PROP_STATUS, | |
654 | POWER_SUPPLY_PROP_CHARGE_TYPE, | |
655 | POWER_SUPPLY_PROP_CHARGE_FULL, | |
656 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, | |
657 | POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, | |
658 | POWER_SUPPLY_PROP_CHARGE_NOW, | |
659 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, | |
660 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | |
661 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, | |
662 | POWER_SUPPLY_PROP_CURRENT_AVG, | |
663 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | |
664 | POWER_SUPPLY_PROP_CAPACITY, | |
665 | POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, | |
666 | }; | |
667 | ||
668 | static enum power_supply_property rk817_chg_props[] = { | |
669 | POWER_SUPPLY_PROP_ONLINE, | |
670 | POWER_SUPPLY_PROP_USB_TYPE, | |
671 | POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, | |
672 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | |
673 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | |
674 | }; | |
675 | ||
676 | static enum power_supply_usb_type rk817_usb_type[] = { | |
677 | POWER_SUPPLY_USB_TYPE_DCP, | |
678 | POWER_SUPPLY_USB_TYPE_UNKNOWN, | |
679 | }; | |
680 | ||
681 | static const struct power_supply_desc rk817_bat_desc = { | |
682 | .name = "rk817-battery", | |
683 | .type = POWER_SUPPLY_TYPE_BATTERY, | |
684 | .properties = rk817_bat_props, | |
685 | .num_properties = ARRAY_SIZE(rk817_bat_props), | |
686 | .get_property = rk817_bat_get_prop, | |
687 | }; | |
688 | ||
689 | static const struct power_supply_desc rk817_chg_desc = { | |
690 | .name = "rk817-charger", | |
691 | .type = POWER_SUPPLY_TYPE_USB, | |
692 | .usb_types = rk817_usb_type, | |
693 | .num_usb_types = ARRAY_SIZE(rk817_usb_type), | |
694 | .properties = rk817_chg_props, | |
695 | .num_properties = ARRAY_SIZE(rk817_chg_props), | |
696 | .get_property = rk817_chg_get_prop, | |
697 | }; | |
698 | ||
699 | static int rk817_read_battery_nvram_values(struct rk817_charger *charger) | |
700 | { | |
701 | u8 bulk_reg[3]; | |
702 | int ret; | |
703 | ||
704 | /* Read the nvram data for full charge capacity. */ | |
705 | ret = regmap_bulk_read(charger->rk808->regmap, | |
706 | RK817_GAS_GAUGE_DATA3, bulk_reg, 3); | |
707 | if (ret < 0) | |
708 | return ret; | |
709 | charger->fcc_mah = get_unaligned_le24(bulk_reg); | |
710 | ||
711 | /* | |
712 | * Sanity checking for values equal to zero or less than would be | |
713 | * practical for this device (BSP Kernel assumes 500mAH or less) for | |
714 | * practicality purposes. Also check if the value is too large and | |
715 | * correct it. | |
716 | */ | |
717 | if ((charger->fcc_mah < 500) || | |
718 | ((charger->fcc_mah * 1000) > charger->bat_charge_full_design_uah)) { | |
719 | dev_info(charger->dev, | |
720 | "Invalid NVRAM max charge, setting to %u uAH\n", | |
721 | charger->bat_charge_full_design_uah); | |
722 | charger->fcc_mah = charger->bat_charge_full_design_uah / 1000; | |
723 | } | |
724 | ||
725 | /* | |
726 | * Read the nvram for state of charge. Sanity check for values greater | |
baba1315 CM |
727 | * than 100 (10000) or less than 0, because other things (BSP kernels, |
728 | * U-Boot, or even i2cset) can write to this register. If the value is | |
729 | * off it should get corrected automatically when the voltage drops to | |
730 | * the min (soc is 0) or when the battery is full (soc is 100). | |
11cb8da0 CM |
731 | */ |
732 | ret = regmap_bulk_read(charger->rk808->regmap, | |
733 | RK817_GAS_GAUGE_BAT_R1, bulk_reg, 3); | |
734 | if (ret < 0) | |
735 | return ret; | |
736 | charger->soc = get_unaligned_le24(bulk_reg); | |
737 | if (charger->soc > 10000) | |
738 | charger->soc = 10000; | |
baba1315 CM |
739 | if (charger->soc < 0) |
740 | charger->soc = 0; | |
11cb8da0 CM |
741 | |
742 | return 0; | |
743 | } | |
744 | ||
745 | static int | |
746 | rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger, | |
747 | struct power_supply_battery_info *bat_info) | |
748 | { | |
749 | struct rk808 *rk808 = charger->rk808; | |
750 | u8 bulk_reg[4]; | |
baba1315 CM |
751 | u32 boot_voltage, boot_charge_mah; |
752 | int ret, reg, off_time, tmp; | |
11cb8da0 CM |
753 | bool first_boot; |
754 | ||
755 | /* | |
756 | * Check if the battery is uninitalized. If it is, the columb counter | |
757 | * needs to be set up. | |
758 | */ | |
759 | ret = regmap_read(rk808->regmap, RK817_GAS_GAUGE_GG_STS, ®); | |
760 | if (ret < 0) | |
761 | return ret; | |
762 | first_boot = reg & RK817_BAT_CON; | |
763 | /* | |
764 | * If the battery is uninitialized, use the poweron voltage and an ocv | |
765 | * lookup to guess our charge. The number won't be very accurate until | |
766 | * we hit either our minimum voltage (0%) or full charge (100%). | |
767 | */ | |
768 | if (first_boot) { | |
769 | regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_PWRON_VOL_H, | |
770 | bulk_reg, 2); | |
771 | tmp = get_unaligned_be16(bulk_reg); | |
772 | boot_voltage = (charger->voltage_k * tmp) + | |
773 | 1000 * charger->voltage_b; | |
774 | /* | |
775 | * Since only implementation has no working thermistor, assume | |
776 | * 20C for OCV lookup. If lookup fails, report error with OCV | |
777 | * table. | |
778 | */ | |
779 | charger->soc = power_supply_batinfo_ocv2cap(bat_info, | |
780 | boot_voltage, | |
781 | 20) * 1000; | |
782 | if (charger->soc < 0) | |
783 | charger->soc = 0; | |
784 | ||
785 | /* Guess that full charge capacity is the design capacity */ | |
786 | charger->fcc_mah = charger->bat_charge_full_design_uah / 1000; | |
787 | /* | |
788 | * Set battery as "set up". BSP driver uses this value even | |
789 | * though datasheet claims it's a read-only value. | |
790 | */ | |
791 | regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_GG_STS, | |
792 | RK817_BAT_CON, 0); | |
793 | /* Save nvram values */ | |
794 | ret = rk817_record_battery_nvram_values(charger); | |
795 | if (ret < 0) | |
796 | return ret; | |
797 | } else { | |
798 | ret = rk817_read_battery_nvram_values(charger); | |
799 | if (ret < 0) | |
800 | return ret; | |
801 | ||
802 | regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, | |
803 | bulk_reg, 4); | |
804 | tmp = get_unaligned_be32(bulk_reg); | |
baba1315 CM |
805 | if (tmp < 0) |
806 | tmp = 0; | |
11cb8da0 CM |
807 | boot_charge_mah = ADC_TO_CHARGE_UAH(tmp, |
808 | charger->res_div) / 1000; | |
809 | /* | |
baba1315 | 810 | * Check if the columb counter has been off for more than 30 |
11cb8da0 CM |
811 | * minutes as it tends to drift downward. If so, re-init soc |
812 | * with the boot voltage instead. Note the unit values for the | |
813 | * OFF_CNT register appear to be in decaminutes and stops | |
814 | * counting at 2550 (0xFF) minutes. BSP kernel used OCV, but | |
815 | * for me occasionally that would show invalid values. Boot | |
816 | * voltage is only accurate for me on first poweron (not | |
817 | * reboots), but we shouldn't ever encounter an OFF_CNT more | |
818 | * than 0 on a reboot anyway. | |
819 | */ | |
820 | regmap_read(rk808->regmap, RK817_GAS_GAUGE_OFF_CNT, &off_time); | |
baba1315 | 821 | if (off_time >= 3) { |
11cb8da0 CM |
822 | regmap_bulk_read(rk808->regmap, |
823 | RK817_GAS_GAUGE_PWRON_VOL_H, | |
824 | bulk_reg, 2); | |
825 | tmp = get_unaligned_be16(bulk_reg); | |
826 | boot_voltage = (charger->voltage_k * tmp) + | |
827 | 1000 * charger->voltage_b; | |
828 | charger->soc = | |
829 | power_supply_batinfo_ocv2cap(bat_info, | |
830 | boot_voltage, | |
831 | 20) * 1000; | |
832 | } else { | |
833 | charger->soc = (boot_charge_mah * 1000 * 100 / | |
834 | charger->fcc_mah); | |
835 | } | |
836 | } | |
837 | ||
11cb8da0 CM |
838 | /* |
839 | * Now we have our full charge capacity and soc, init the columb | |
840 | * counter. | |
841 | */ | |
842 | boot_charge_mah = charger->soc * charger->fcc_mah / 100 / 1000; | |
843 | if (boot_charge_mah > charger->fcc_mah) | |
844 | boot_charge_mah = charger->fcc_mah; | |
845 | tmp = CHARGE_TO_ADC(boot_charge_mah, charger->res_div); | |
846 | put_unaligned_be32(tmp, bulk_reg); | |
847 | ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3, | |
848 | bulk_reg, 4); | |
849 | if (ret < 0) | |
850 | return ret; | |
851 | ||
852 | /* Set QMAX value to max design capacity. */ | |
853 | tmp = CHARGE_TO_ADC((charger->bat_charge_full_design_uah / 1000), | |
854 | charger->res_div); | |
855 | put_unaligned_be32(tmp, bulk_reg); | |
856 | ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_MAX_H3, | |
857 | bulk_reg, 4); | |
858 | if (ret < 0) | |
859 | return ret; | |
860 | ||
861 | return 0; | |
862 | } | |
863 | ||
864 | static int rk817_battery_init(struct rk817_charger *charger, | |
865 | struct power_supply_battery_info *bat_info) | |
866 | { | |
867 | struct rk808 *rk808 = charger->rk808; | |
868 | u32 tmp, max_chg_vol_mv, max_chg_cur_ma; | |
883babd4 CM |
869 | u8 max_chg_vol_reg, chg_term_i_reg; |
870 | int ret, chg_term_ma, max_chg_cur_reg; | |
11cb8da0 CM |
871 | u8 bulk_reg[2]; |
872 | ||
873 | /* Get initial plug state */ | |
874 | regmap_read(rk808->regmap, RK817_SYS_STS, &tmp); | |
875 | charger->plugged_in = (tmp & RK817_PLUG_IN_STS); | |
876 | ||
877 | /* | |
878 | * Turn on all ADC functions to measure battery, USB, and sys voltage, | |
879 | * as well as batt temp. Note only tested implementation so far does | |
880 | * not use a battery with a thermistor. | |
881 | */ | |
882 | regmap_write(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG0, 0xfc); | |
883 | ||
884 | /* | |
885 | * Set relax mode voltage sampling interval and ADC offset calibration | |
886 | * interval to 8 minutes to mirror BSP kernel. Set voltage and current | |
887 | * modes to average to mirror BSP kernel. | |
888 | */ | |
889 | regmap_write(rk808->regmap, RK817_GAS_GAUGE_GG_CON, 0x04); | |
890 | ||
891 | /* Calibrate voltage like the BSP does here. */ | |
892 | rk817_bat_calib_vol(charger); | |
893 | ||
894 | /* Write relax threshold, derived from sleep enter current. */ | |
895 | tmp = CURRENT_TO_ADC(charger->sleep_enter_current_ua, | |
896 | charger->res_div); | |
897 | put_unaligned_be16(tmp, bulk_reg); | |
898 | regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_RELAX_THRE_H, | |
899 | bulk_reg, 2); | |
900 | ||
901 | /* Write sleep sample current, derived from sleep filter current. */ | |
902 | tmp = CURRENT_TO_ADC(charger->sleep_filter_current_ua, | |
903 | charger->res_div); | |
904 | put_unaligned_be16(tmp, bulk_reg); | |
905 | regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H, | |
906 | bulk_reg, 2); | |
907 | ||
908 | /* Restart battery relax voltage */ | |
909 | regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_GG_STS, | |
910 | RK817_RELAX_VOL_UPD, (0x0 << 2)); | |
911 | ||
912 | /* | |
913 | * Set OCV Threshold Voltage to 127.5mV. This was hard coded like this | |
914 | * in the BSP. | |
915 | */ | |
916 | regmap_write(rk808->regmap, RK817_GAS_GAUGE_OCV_THRE_VOL, 0xff); | |
917 | ||
918 | /* | |
919 | * Set maximum charging voltage to battery max voltage. Trying to be | |
920 | * incredibly safe with these value, as setting them wrong could | |
921 | * overcharge the battery, which would be very bad. | |
922 | */ | |
923 | max_chg_vol_mv = bat_info->constant_charge_voltage_max_uv / 1000; | |
924 | max_chg_cur_ma = bat_info->constant_charge_current_max_ua / 1000; | |
925 | ||
926 | if (max_chg_vol_mv < 4100) { | |
927 | return dev_err_probe(charger->dev, -EINVAL, | |
928 | "invalid max charger voltage, value %u unsupported\n", | |
929 | max_chg_vol_mv * 1000); | |
930 | } | |
931 | if (max_chg_vol_mv > 4450) { | |
932 | dev_info(charger->dev, | |
933 | "Setting max charge voltage to 4450000uv\n"); | |
934 | max_chg_vol_mv = 4450; | |
935 | } | |
936 | ||
937 | if (max_chg_cur_ma < 500) { | |
938 | return dev_err_probe(charger->dev, -EINVAL, | |
939 | "invalid max charger current, value %u unsupported\n", | |
940 | max_chg_cur_ma * 1000); | |
941 | } | |
942 | if (max_chg_cur_ma > 3500) | |
943 | dev_info(charger->dev, | |
944 | "Setting max charge current to 3500000ua\n"); | |
945 | ||
946 | /* | |
947 | * Now that the values are sanity checked, if we subtract 4100 from the | |
948 | * max voltage and divide by 50, we conviently get the exact value for | |
949 | * the registers, which are 4.1v, 4.15v, 4.2v, 4.25v, 4.3v, 4.35v, | |
950 | * 4.4v, and 4.45v; these correspond to values 0x00 through 0x07. | |
951 | */ | |
952 | max_chg_vol_reg = (max_chg_vol_mv - 4100) / 50; | |
953 | ||
954 | max_chg_cur_reg = rk817_chg_cur_to_reg(max_chg_cur_ma); | |
955 | ||
956 | if (max_chg_vol_reg < 0 || max_chg_vol_reg > 7) { | |
957 | return dev_err_probe(charger->dev, -EINVAL, | |
958 | "invalid max charger voltage, value %u unsupported\n", | |
959 | max_chg_vol_mv * 1000); | |
960 | } | |
961 | if (max_chg_cur_reg < 0 || max_chg_cur_reg > 7) { | |
962 | return dev_err_probe(charger->dev, -EINVAL, | |
963 | "invalid max charger current, value %u unsupported\n", | |
964 | max_chg_cur_ma * 1000); | |
965 | } | |
966 | ||
967 | /* | |
968 | * Write the values to the registers, and deliver an emergency warning | |
969 | * in the event they are not written correctly. | |
970 | */ | |
971 | ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT, | |
972 | RK817_CHRG_VOL_SEL, (max_chg_vol_reg << 4)); | |
973 | if (ret) { | |
974 | dev_emerg(charger->dev, | |
975 | "Danger, unable to set max charger voltage: %u\n", | |
976 | ret); | |
977 | } | |
978 | ||
979 | ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT, | |
980 | RK817_CHRG_CUR_SEL, max_chg_cur_reg); | |
981 | if (ret) { | |
982 | dev_emerg(charger->dev, | |
983 | "Danger, unable to set max charger current: %u\n", | |
984 | ret); | |
985 | } | |
986 | ||
987 | /* Set charge finishing mode to analog */ | |
988 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM, | |
989 | RK817_CHRG_TERM_ANA_DIG, (0x0 << 2)); | |
990 | ||
991 | /* | |
992 | * Set charge finish current, warn if value not in range and keep | |
993 | * default. | |
994 | */ | |
995 | chg_term_ma = bat_info->charge_term_current_ua / 1000; | |
996 | if (chg_term_ma < 150 || chg_term_ma > 400) { | |
997 | dev_warn(charger->dev, | |
998 | "Invalid charge termination %u, keeping default\n", | |
999 | chg_term_ma * 1000); | |
1000 | chg_term_ma = 200; | |
1001 | } | |
1002 | ||
1003 | /* | |
1004 | * Values of 150ma, 200ma, 300ma, and 400ma correspond to 00, 01, 10, | |
1005 | * and 11. | |
1006 | */ | |
1007 | chg_term_i_reg = (chg_term_ma - 100) / 100; | |
1008 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM, | |
1009 | RK817_CHRG_TERM_ANA_SEL, chg_term_i_reg); | |
1010 | ||
1011 | ret = rk817_read_or_set_full_charge_on_boot(charger, bat_info); | |
1012 | if (ret < 0) | |
1013 | return ret; | |
1014 | ||
1015 | /* | |
1016 | * Set minimum USB input voltage to 4.5v and enable USB voltage input | |
1017 | * limit. | |
1018 | */ | |
1019 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, | |
1020 | RK817_USB_VLIM_SEL, (0x05 << 4)); | |
1021 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN, | |
1022 | (0x01 << 7)); | |
1023 | ||
1024 | /* | |
1025 | * Set average USB input current limit to 1.5A and enable USB current | |
1026 | * input limit. | |
1027 | */ | |
1028 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, | |
1029 | RK817_USB_ILIM_SEL, 0x03); | |
1030 | regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN, | |
1031 | (0x01 << 3)); | |
1032 | ||
1033 | return 0; | |
1034 | } | |
1035 | ||
1036 | static void rk817_charging_monitor(struct work_struct *work) | |
1037 | { | |
1038 | struct rk817_charger *charger; | |
1039 | ||
1040 | charger = container_of(work, struct rk817_charger, work.work); | |
1041 | ||
1042 | rk817_read_props(charger); | |
1043 | ||
1044 | /* Run every 8 seconds like the BSP driver did. */ | |
1045 | queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); | |
1046 | } | |
1047 | ||
488ef44c CM |
1048 | static void rk817_cleanup_node(void *data) |
1049 | { | |
1050 | struct device_node *node = data; | |
1051 | ||
1052 | of_node_put(node); | |
1053 | } | |
1054 | ||
11cb8da0 CM |
1055 | static int rk817_charger_probe(struct platform_device *pdev) |
1056 | { | |
1057 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | |
1058 | struct rk817_charger *charger; | |
1059 | struct device_node *node; | |
1060 | struct power_supply_battery_info *bat_info; | |
1061 | struct device *dev = &pdev->dev; | |
1062 | struct power_supply_config pscfg = {}; | |
1063 | int plugin_irq, plugout_irq; | |
1064 | int of_value; | |
1065 | int ret; | |
1066 | ||
1067 | node = of_get_child_by_name(dev->parent->of_node, "charger"); | |
1068 | if (!node) | |
1069 | return -ENODEV; | |
1070 | ||
488ef44c CM |
1071 | ret = devm_add_action_or_reset(&pdev->dev, rk817_cleanup_node, node); |
1072 | if (ret) | |
1073 | return ret; | |
1074 | ||
11cb8da0 | 1075 | charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); |
488ef44c | 1076 | if (!charger) |
11cb8da0 CM |
1077 | return -ENOMEM; |
1078 | ||
1079 | charger->rk808 = rk808; | |
1080 | ||
1081 | charger->dev = &pdev->dev; | |
1082 | platform_set_drvdata(pdev, charger); | |
1083 | ||
1084 | rk817_bat_calib_vol(charger); | |
1085 | ||
1086 | pscfg.drv_data = charger; | |
1087 | pscfg.of_node = node; | |
1088 | ||
1089 | /* | |
1090 | * Get sample resistor value. Note only values of 10000 or 20000 | |
1091 | * microohms are allowed. Schematic for my test implementation (an | |
1092 | * Odroid Go Advance) shows a 10 milliohm resistor for reference. | |
1093 | */ | |
1094 | ret = of_property_read_u32(node, "rockchip,resistor-sense-micro-ohms", | |
1095 | &of_value); | |
1096 | if (ret < 0) { | |
1097 | return dev_err_probe(dev, ret, | |
1098 | "Error reading sample resistor value\n"); | |
1099 | } | |
1100 | /* | |
1101 | * Store as a 1 or a 2, since all we really use the value for is as a | |
1102 | * divisor in some calculations. | |
1103 | */ | |
1104 | charger->res_div = (of_value == 20000) ? 2 : 1; | |
1105 | ||
1106 | /* | |
1107 | * Get sleep enter current value. Not sure what this value is for | |
1108 | * other than to help calibrate the relax threshold. | |
1109 | */ | |
1110 | ret = of_property_read_u32(node, | |
1111 | "rockchip,sleep-enter-current-microamp", | |
1112 | &of_value); | |
1113 | if (ret < 0) { | |
1114 | return dev_err_probe(dev, ret, | |
1115 | "Error reading sleep enter cur value\n"); | |
1116 | } | |
1117 | charger->sleep_enter_current_ua = of_value; | |
1118 | ||
1119 | /* Get sleep filter current value */ | |
1120 | ret = of_property_read_u32(node, | |
1121 | "rockchip,sleep-filter-current-microamp", | |
1122 | &of_value); | |
1123 | if (ret < 0) { | |
1124 | return dev_err_probe(dev, ret, | |
1125 | "Error reading sleep filter cur value\n"); | |
1126 | } | |
1127 | ||
1128 | charger->sleep_filter_current_ua = of_value; | |
1129 | ||
1130 | charger->bat_ps = devm_power_supply_register(&pdev->dev, | |
1131 | &rk817_bat_desc, &pscfg); | |
172c65e6 | 1132 | if (IS_ERR(charger->bat_ps)) |
11cb8da0 CM |
1133 | return dev_err_probe(dev, -EINVAL, |
1134 | "Battery failed to probe\n"); | |
1135 | ||
172c65e6 DC |
1136 | charger->chg_ps = devm_power_supply_register(&pdev->dev, |
1137 | &rk817_chg_desc, &pscfg); | |
11cb8da0 CM |
1138 | if (IS_ERR(charger->chg_ps)) |
1139 | return dev_err_probe(dev, -EINVAL, | |
1140 | "Charger failed to probe\n"); | |
1141 | ||
1142 | ret = power_supply_get_battery_info(charger->bat_ps, | |
1143 | &bat_info); | |
1144 | if (ret) { | |
1145 | return dev_err_probe(dev, ret, | |
3cc52437 | 1146 | "Unable to get battery info\n"); |
11cb8da0 CM |
1147 | } |
1148 | ||
1149 | if ((bat_info->charge_full_design_uah <= 0) || | |
1150 | (bat_info->voltage_min_design_uv <= 0) || | |
1151 | (bat_info->voltage_max_design_uv <= 0) || | |
1152 | (bat_info->constant_charge_voltage_max_uv <= 0) || | |
1153 | (bat_info->constant_charge_current_max_ua <= 0) || | |
1154 | (bat_info->charge_term_current_ua <= 0)) { | |
1155 | return dev_err_probe(dev, -EINVAL, | |
1156 | "Required bat info missing or invalid\n"); | |
1157 | } | |
1158 | ||
1159 | charger->bat_charge_full_design_uah = bat_info->charge_full_design_uah; | |
1160 | charger->bat_voltage_min_design_uv = bat_info->voltage_min_design_uv; | |
1161 | charger->bat_voltage_max_design_uv = bat_info->voltage_max_design_uv; | |
1162 | ||
1163 | /* | |
1164 | * Has to run after power_supply_get_battery_info as it depends on some | |
1165 | * values discovered from that routine. | |
1166 | */ | |
1167 | ret = rk817_battery_init(charger, bat_info); | |
1168 | if (ret) | |
1169 | return ret; | |
1170 | ||
1171 | power_supply_put_battery_info(charger->bat_ps, bat_info); | |
1172 | ||
1173 | plugin_irq = platform_get_irq(pdev, 0); | |
1174 | if (plugin_irq < 0) | |
1175 | return plugin_irq; | |
1176 | ||
1177 | plugout_irq = platform_get_irq(pdev, 1); | |
1178 | if (plugout_irq < 0) | |
1179 | return plugout_irq; | |
1180 | ||
1181 | ret = devm_request_threaded_irq(charger->dev, plugin_irq, NULL, | |
1182 | rk817_plug_in_isr, | |
1183 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | |
1184 | "rk817_plug_in", charger); | |
1185 | if (ret) { | |
1186 | return dev_err_probe(&pdev->dev, ret, | |
1187 | "plug_in_irq request failed!\n"); | |
1188 | } | |
1189 | ||
1190 | ret = devm_request_threaded_irq(charger->dev, plugout_irq, NULL, | |
1191 | rk817_plug_out_isr, | |
1192 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | |
1193 | "rk817_plug_out", charger); | |
1194 | if (ret) { | |
1195 | return dev_err_probe(&pdev->dev, ret, | |
1196 | "plug_out_irq request failed!\n"); | |
1197 | } | |
1198 | ||
1199 | ret = devm_delayed_work_autocancel(&pdev->dev, &charger->work, | |
1200 | rk817_charging_monitor); | |
1201 | if (ret) | |
1202 | return ret; | |
1203 | ||
1204 | /* Force the first update immediately. */ | |
1205 | mod_delayed_work(system_wq, &charger->work, 0); | |
1206 | ||
1207 | return 0; | |
1208 | } | |
1209 | ||
1210 | ||
1211 | static struct platform_driver rk817_charger_driver = { | |
1212 | .probe = rk817_charger_probe, | |
1213 | .driver = { | |
1214 | .name = "rk817-charger", | |
1215 | }, | |
1216 | }; | |
1217 | module_platform_driver(rk817_charger_driver); | |
1218 | ||
1219 | MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC"); | |
1220 | MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc@gmail.com>"); | |
1221 | MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); | |
1222 | MODULE_LICENSE("GPL"); | |
cbcdfbf5 | 1223 | MODULE_ALIAS("platform:rk817-charger"); |