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 | |
124 | static int rk817_chg_cur_to_reg(u32 chg_cur_ma) |
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(map: charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB0_H, |
178 | val: bulk_reg, val_count: 2); |
179 | vcalib0 = get_unaligned_be16(p: bulk_reg); |
180 | |
181 | regmap_bulk_read(map: charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB1_H, |
182 | val: bulk_reg, val_count: 2); |
183 | vcalib1 = get_unaligned_be16(p: 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(map: charger->rk808->regmap, RK817_GAS_GAUGE_IOFFSET_H, |
197 | val: bulk_reg, val_count: 2); |
198 | regmap_bulk_write(map: charger->rk808->regmap, RK817_GAS_GAUGE_CAL_OFFSET_H, |
199 | val: bulk_reg, val_count: 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(val: charger->soc, p: bulk_reg); |
216 | ret = regmap_bulk_write(map: charger->rk808->regmap, RK817_GAS_GAUGE_BAT_R1, |
217 | val: bulk_reg, val_count: 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(val: rsoc, p: bulk_reg); |
226 | ret = regmap_bulk_write(map: charger->rk808->regmap, RK817_GAS_GAUGE_DATA0, |
227 | val: bulk_reg, val_count: 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(val: charger->fcc_mah, p: bulk_reg); |
232 | ret = regmap_bulk_write(map: charger->rk808->regmap, RK817_GAS_GAUGE_DATA3, |
233 | val: bulk_reg, val_count: 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(val: charge_now_adc, p: bulk_reg); |
264 | regmap_bulk_write(map: rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3, |
265 | val: bulk_reg, val_count: 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(map: rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, |
279 | val: bulk_reg, val_count: 4); |
280 | charge_now_adc = get_unaligned_be32(p: 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(val: charge_now_adc, p: bulk_reg); |
301 | regmap_bulk_write(map: rk808->regmap, |
302 | RK817_GAS_GAUGE_Q_INIT_H3, |
303 | val: bulk_reg, val_count: 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(map: charger->rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H, |
316 | val: bulk_reg, val_count: 2); |
317 | tmp = get_unaligned_be16(p: 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(map: rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, |
322 | val: bulk_reg, val_count: 4); |
323 | charge_now_adc = get_unaligned_be32(p: 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 | |
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(val: charge_now_adc, p: bulk_reg); |
345 | regmap_bulk_write(map: rk808->regmap, |
346 | RK817_GAS_GAUGE_Q_INIT_H3, val: bulk_reg, val_count: 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 | |
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(map: charger->rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1, val: ®); |
369 | if (reg & RK817_VOL_CUR_CALIB_UPD) { |
370 | rk817_bat_calib_cur(charger); |
371 | rk817_bat_calib_vol(charger); |
372 | regmap_write_bits(map: 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(map: charger->rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, |
380 | val: bulk_reg, val_count: 4); |
381 | tmp = get_unaligned_be32(p: 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(map: charger->rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H, |
393 | val: bulk_reg, val_count: 2); |
394 | tmp = get_unaligned_be16(p: 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(map: charger->rk808->regmap, RK817_GAS_GAUGE_BAT_CUR_H, |
403 | val: bulk_reg, val_count: 2); |
404 | tmp = (short int)get_unaligned_be16(p: 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(map: charger->rk808->regmap, RK817_PMIC_CHRG_OUT, val: ®); |
413 | charger->max_chg_cur_ua = |
414 | rk817_chg_cur_from_reg(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(map: charger->rk808->regmap, RK817_PMIC_CHRG_OUT, val: ®); |
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(map: charger->rk808->regmap, RK817_PMIC_CHRG_STS, val: ®); |
426 | charger->battery_present = (reg & RK817_BAT_EXS); |
427 | |
428 | /* Get which type of charge we are using (if any). */ |
429 | regmap_read(map: charger->rk808->regmap, RK817_PMIC_CHRG_STS, val: ®); |
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(map: charger->rk808->regmap, RK817_GAS_GAUGE_USB_VOL_H, |
445 | val: bulk_reg, val_count: 2); |
446 | reg = get_unaligned_be16(p: 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(psy: 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(psy: 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(psy: charger->chg_ps); |
602 | power_supply_changed(psy: 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(psy: charger->bat_ps); |
622 | power_supply_changed(psy: 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(map: rk808->regmap, RK817_PMIC_CHRG_IN, |
631 | RK817_USB_VLIM_SEL, val: (0x05 << 4)); |
632 | regmap_write_bits(map: rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN, |
633 | val: (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(map: rk808->regmap, RK817_PMIC_CHRG_IN, |
640 | RK817_USB_ILIM_SEL, val: 0x03); |
641 | regmap_write_bits(map: rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN, |
642 | val: (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(map: charger->rk808->regmap, |
706 | RK817_GAS_GAUGE_DATA3, val: bulk_reg, val_count: 3); |
707 | if (ret < 0) |
708 | return ret; |
709 | charger->fcc_mah = get_unaligned_le24(p: 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 |
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). |
731 | */ |
732 | ret = regmap_bulk_read(map: charger->rk808->regmap, |
733 | RK817_GAS_GAUGE_BAT_R1, val: bulk_reg, val_count: 3); |
734 | if (ret < 0) |
735 | return ret; |
736 | charger->soc = get_unaligned_le24(p: bulk_reg); |
737 | if (charger->soc > 10000) |
738 | charger->soc = 10000; |
739 | if (charger->soc < 0) |
740 | charger->soc = 0; |
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]; |
751 | u32 boot_voltage, boot_charge_mah; |
752 | int ret, reg, off_time, tmp; |
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(map: rk808->regmap, RK817_GAS_GAUGE_GG_STS, val: ®); |
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(map: rk808->regmap, RK817_GAS_GAUGE_PWRON_VOL_H, |
770 | val: bulk_reg, val_count: 2); |
771 | tmp = get_unaligned_be16(p: 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(info: bat_info, |
780 | ocv: boot_voltage, |
781 | temp: 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(map: rk808->regmap, RK817_GAS_GAUGE_GG_STS, |
792 | RK817_BAT_CON, val: 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(map: rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, |
803 | val: bulk_reg, val_count: 4); |
804 | tmp = get_unaligned_be32(p: bulk_reg); |
805 | if (tmp < 0) |
806 | tmp = 0; |
807 | boot_charge_mah = ADC_TO_CHARGE_UAH(tmp, |
808 | charger->res_div) / 1000; |
809 | /* |
810 | * Check if the columb counter has been off for more than 30 |
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(map: rk808->regmap, RK817_GAS_GAUGE_OFF_CNT, val: &off_time); |
821 | if (off_time >= 3) { |
822 | regmap_bulk_read(map: rk808->regmap, |
823 | RK817_GAS_GAUGE_PWRON_VOL_H, |
824 | val: bulk_reg, val_count: 2); |
825 | tmp = get_unaligned_be16(p: bulk_reg); |
826 | boot_voltage = (charger->voltage_k * tmp) + |
827 | 1000 * charger->voltage_b; |
828 | charger->soc = |
829 | power_supply_batinfo_ocv2cap(info: bat_info, |
830 | ocv: boot_voltage, |
831 | temp: 20) * 1000; |
832 | } else { |
833 | charger->soc = (boot_charge_mah * 1000 * 100 / |
834 | charger->fcc_mah); |
835 | } |
836 | } |
837 | |
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(val: tmp, p: bulk_reg); |
847 | ret = regmap_bulk_write(map: rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3, |
848 | val: bulk_reg, val_count: 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(val: tmp, p: bulk_reg); |
856 | ret = regmap_bulk_write(map: rk808->regmap, RK817_GAS_GAUGE_Q_MAX_H3, |
857 | val: bulk_reg, val_count: 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; |
869 | u8 max_chg_vol_reg, chg_term_i_reg; |
870 | int ret, chg_term_ma, max_chg_cur_reg; |
871 | u8 bulk_reg[2]; |
872 | |
873 | /* Get initial plug state */ |
874 | regmap_read(map: rk808->regmap, RK817_SYS_STS, val: &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(map: rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG0, val: 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(map: rk808->regmap, RK817_GAS_GAUGE_GG_CON, val: 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(val: tmp, p: bulk_reg); |
898 | regmap_bulk_write(map: rk808->regmap, RK817_GAS_GAUGE_RELAX_THRE_H, |
899 | val: bulk_reg, val_count: 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(val: tmp, p: bulk_reg); |
905 | regmap_bulk_write(map: rk808->regmap, RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H, |
906 | val: bulk_reg, val_count: 2); |
907 | |
908 | /* Restart battery relax voltage */ |
909 | regmap_write_bits(map: rk808->regmap, RK817_GAS_GAUGE_GG_STS, |
910 | RK817_RELAX_VOL_UPD, val: (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(map: rk808->regmap, RK817_GAS_GAUGE_OCV_THRE_VOL, val: 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(dev: charger->dev, err: -EINVAL, |
928 | fmt: "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(dev: charger->dev, err: -EINVAL, |
939 | fmt: "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(chg_cur_ma: max_chg_cur_ma); |
955 | |
956 | if (max_chg_vol_reg < 0 || max_chg_vol_reg > 7) { |
957 | return dev_err_probe(dev: charger->dev, err: -EINVAL, |
958 | fmt: "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(dev: charger->dev, err: -EINVAL, |
963 | fmt: "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(map: rk808->regmap, RK817_PMIC_CHRG_OUT, |
972 | RK817_CHRG_VOL_SEL, val: (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(map: rk808->regmap, RK817_PMIC_CHRG_OUT, |
980 | RK817_CHRG_CUR_SEL, val: 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(map: rk808->regmap, RK817_PMIC_CHRG_TERM, |
989 | RK817_CHRG_TERM_ANA_DIG, val: (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(map: rk808->regmap, RK817_PMIC_CHRG_TERM, |
1009 | RK817_CHRG_TERM_ANA_SEL, val: 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(map: rk808->regmap, RK817_PMIC_CHRG_IN, |
1020 | RK817_USB_VLIM_SEL, val: (0x05 << 4)); |
1021 | regmap_write_bits(map: rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN, |
1022 | val: (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(map: rk808->regmap, RK817_PMIC_CHRG_IN, |
1029 | RK817_USB_ILIM_SEL, val: 0x03); |
1030 | regmap_write_bits(map: rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN, |
1031 | val: (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(wq: system_wq, dwork: &charger->work, delay: msecs_to_jiffies(m: 8000)); |
1046 | } |
1047 | |
1048 | static void rk817_cleanup_node(void *data) |
1049 | { |
1050 | struct device_node *node = data; |
1051 | |
1052 | of_node_put(node); |
1053 | } |
1054 | |
1055 | static int rk817_charger_probe(struct platform_device *pdev) |
1056 | { |
1057 | struct rk808 *rk808 = dev_get_drvdata(dev: 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(node: dev->parent->of_node, name: "charger" ); |
1068 | if (!node) |
1069 | return -ENODEV; |
1070 | |
1071 | ret = devm_add_action_or_reset(&pdev->dev, rk817_cleanup_node, node); |
1072 | if (ret) |
1073 | return ret; |
1074 | |
1075 | charger = devm_kzalloc(dev: &pdev->dev, size: sizeof(*charger), GFP_KERNEL); |
1076 | if (!charger) |
1077 | return -ENOMEM; |
1078 | |
1079 | charger->rk808 = rk808; |
1080 | |
1081 | charger->dev = &pdev->dev; |
1082 | platform_set_drvdata(pdev, data: 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(np: node, propname: "rockchip,resistor-sense-micro-ohms" , |
1095 | out_value: &of_value); |
1096 | if (ret < 0) { |
1097 | return dev_err_probe(dev, err: ret, |
1098 | fmt: "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(np: node, |
1111 | propname: "rockchip,sleep-enter-current-microamp" , |
1112 | out_value: &of_value); |
1113 | if (ret < 0) { |
1114 | return dev_err_probe(dev, err: ret, |
1115 | fmt: "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(np: node, |
1121 | propname: "rockchip,sleep-filter-current-microamp" , |
1122 | out_value: &of_value); |
1123 | if (ret < 0) { |
1124 | return dev_err_probe(dev, err: ret, |
1125 | fmt: "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(parent: &pdev->dev, |
1131 | desc: &rk817_bat_desc, cfg: &pscfg); |
1132 | if (IS_ERR(ptr: charger->bat_ps)) |
1133 | return dev_err_probe(dev, err: -EINVAL, |
1134 | fmt: "Battery failed to probe\n" ); |
1135 | |
1136 | charger->chg_ps = devm_power_supply_register(parent: &pdev->dev, |
1137 | desc: &rk817_chg_desc, cfg: &pscfg); |
1138 | if (IS_ERR(ptr: charger->chg_ps)) |
1139 | return dev_err_probe(dev, err: -EINVAL, |
1140 | fmt: "Charger failed to probe\n" ); |
1141 | |
1142 | ret = power_supply_get_battery_info(psy: charger->bat_ps, |
1143 | info_out: &bat_info); |
1144 | if (ret) { |
1145 | return dev_err_probe(dev, err: ret, |
1146 | fmt: "Unable to get battery info\n" ); |
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, err: -EINVAL, |
1156 | fmt: "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(psy: charger->bat_ps, info: 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(dev: charger->dev, irq: plugin_irq, NULL, |
1182 | thread_fn: rk817_plug_in_isr, |
1183 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
1184 | devname: "rk817_plug_in" , dev_id: charger); |
1185 | if (ret) { |
1186 | return dev_err_probe(dev: &pdev->dev, err: ret, |
1187 | fmt: "plug_in_irq request failed!\n" ); |
1188 | } |
1189 | |
1190 | ret = devm_request_threaded_irq(dev: charger->dev, irq: plugout_irq, NULL, |
1191 | thread_fn: rk817_plug_out_isr, |
1192 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
1193 | devname: "rk817_plug_out" , dev_id: charger); |
1194 | if (ret) { |
1195 | return dev_err_probe(dev: &pdev->dev, err: ret, |
1196 | fmt: "plug_out_irq request failed!\n" ); |
1197 | } |
1198 | |
1199 | ret = devm_delayed_work_autocancel(dev: &pdev->dev, w: &charger->work, |
1200 | worker: rk817_charging_monitor); |
1201 | if (ret) |
1202 | return ret; |
1203 | |
1204 | /* Force the first update immediately. */ |
1205 | mod_delayed_work(wq: system_wq, dwork: &charger->work, delay: 0); |
1206 | |
1207 | return 0; |
1208 | } |
1209 | |
1210 | static int __maybe_unused rk817_resume(struct device *dev) |
1211 | { |
1212 | |
1213 | struct rk817_charger *charger = dev_get_drvdata(dev); |
1214 | |
1215 | /* force an immediate update */ |
1216 | mod_delayed_work(wq: system_wq, dwork: &charger->work, delay: 0); |
1217 | |
1218 | return 0; |
1219 | } |
1220 | |
1221 | static SIMPLE_DEV_PM_OPS(rk817_charger_pm, NULL, rk817_resume); |
1222 | |
1223 | static struct platform_driver rk817_charger_driver = { |
1224 | .probe = rk817_charger_probe, |
1225 | .driver = { |
1226 | .name = "rk817-charger" , |
1227 | .pm = &rk817_charger_pm, |
1228 | }, |
1229 | }; |
1230 | module_platform_driver(rk817_charger_driver); |
1231 | |
1232 | MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC" ); |
1233 | MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc@gmail.com>" ); |
1234 | MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>" ); |
1235 | MODULE_LICENSE("GPL" ); |
1236 | MODULE_ALIAS("platform:rk817-charger" ); |
1237 | |