1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | // |
3 | // Fuel gauge driver for Maxim 17042 / 8966 / 8997 |
4 | // Note that Maxim 8966 and 8997 are mfd and this is its subdevice. |
5 | // |
6 | // Copyright (C) 2011 Samsung Electronics |
7 | // MyungJoo Ham <myungjoo.ham@samsung.com> |
8 | // |
9 | // This driver is based on max17040_battery.c |
10 | |
11 | #include <linux/acpi.h> |
12 | #include <linux/devm-helpers.h> |
13 | #include <linux/init.h> |
14 | #include <linux/module.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/i2c.h> |
17 | #include <linux/delay.h> |
18 | #include <linux/interrupt.h> |
19 | #include <linux/pm.h> |
20 | #include <linux/mod_devicetable.h> |
21 | #include <linux/power_supply.h> |
22 | #include <linux/power/max17042_battery.h> |
23 | #include <linux/of.h> |
24 | #include <linux/regmap.h> |
25 | |
26 | /* Status register bits */ |
27 | #define STATUS_POR_BIT (1 << 1) |
28 | #define STATUS_BST_BIT (1 << 3) |
29 | #define STATUS_VMN_BIT (1 << 8) |
30 | #define STATUS_TMN_BIT (1 << 9) |
31 | #define STATUS_SMN_BIT (1 << 10) |
32 | #define STATUS_BI_BIT (1 << 11) |
33 | #define STATUS_VMX_BIT (1 << 12) |
34 | #define STATUS_TMX_BIT (1 << 13) |
35 | #define STATUS_SMX_BIT (1 << 14) |
36 | #define STATUS_BR_BIT (1 << 15) |
37 | |
38 | /* Interrupt mask bits */ |
39 | #define CFG_ALRT_BIT_ENBL (1 << 2) |
40 | |
41 | #define VFSOC0_LOCK 0x0000 |
42 | #define VFSOC0_UNLOCK 0x0080 |
43 | #define MODEL_UNLOCK1 0X0059 |
44 | #define MODEL_UNLOCK2 0X00C4 |
45 | #define MODEL_LOCK1 0X0000 |
46 | #define MODEL_LOCK2 0X0000 |
47 | |
48 | #define dQ_ACC_DIV 0x4 |
49 | #define dP_ACC_100 0x1900 |
50 | #define dP_ACC_200 0x3200 |
51 | |
52 | #define MAX17042_VMAX_TOLERANCE 50 /* 50 mV */ |
53 | |
54 | struct max17042_chip { |
55 | struct i2c_client *client; |
56 | struct regmap *regmap; |
57 | struct power_supply *battery; |
58 | enum max170xx_chip_type chip_type; |
59 | struct max17042_platform_data *pdata; |
60 | struct work_struct work; |
61 | int init_complete; |
62 | }; |
63 | |
64 | static enum power_supply_property max17042_battery_props[] = { |
65 | POWER_SUPPLY_PROP_STATUS, |
66 | POWER_SUPPLY_PROP_PRESENT, |
67 | POWER_SUPPLY_PROP_TECHNOLOGY, |
68 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
69 | POWER_SUPPLY_PROP_VOLTAGE_MAX, |
70 | POWER_SUPPLY_PROP_VOLTAGE_MIN, |
71 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
72 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
73 | POWER_SUPPLY_PROP_VOLTAGE_AVG, |
74 | POWER_SUPPLY_PROP_VOLTAGE_OCV, |
75 | POWER_SUPPLY_PROP_CAPACITY, |
76 | POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, |
77 | POWER_SUPPLY_PROP_CHARGE_FULL, |
78 | POWER_SUPPLY_PROP_CHARGE_NOW, |
79 | POWER_SUPPLY_PROP_CHARGE_COUNTER, |
80 | POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, |
81 | POWER_SUPPLY_PROP_TEMP, |
82 | POWER_SUPPLY_PROP_TEMP_ALERT_MIN, |
83 | POWER_SUPPLY_PROP_TEMP_ALERT_MAX, |
84 | POWER_SUPPLY_PROP_TEMP_MIN, |
85 | POWER_SUPPLY_PROP_TEMP_MAX, |
86 | POWER_SUPPLY_PROP_HEALTH, |
87 | POWER_SUPPLY_PROP_SCOPE, |
88 | POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, |
89 | // these two have to be at the end on the list |
90 | POWER_SUPPLY_PROP_CURRENT_NOW, |
91 | POWER_SUPPLY_PROP_CURRENT_AVG, |
92 | }; |
93 | |
94 | static int max17042_get_temperature(struct max17042_chip *chip, int *temp) |
95 | { |
96 | int ret; |
97 | u32 data; |
98 | struct regmap *map = chip->regmap; |
99 | |
100 | ret = regmap_read(map, reg: MAX17042_TEMP, val: &data); |
101 | if (ret < 0) |
102 | return ret; |
103 | |
104 | *temp = sign_extend32(value: data, index: 15); |
105 | /* The value is converted into deci-centigrade scale */ |
106 | /* Units of LSB = 1 / 256 degree Celsius */ |
107 | *temp = *temp * 10 / 256; |
108 | return 0; |
109 | } |
110 | |
111 | static int max17042_get_status(struct max17042_chip *chip, int *status) |
112 | { |
113 | int ret, charge_full, charge_now; |
114 | int avg_current; |
115 | u32 data; |
116 | |
117 | ret = power_supply_am_i_supplied(psy: chip->battery); |
118 | if (ret < 0) { |
119 | *status = POWER_SUPPLY_STATUS_UNKNOWN; |
120 | return 0; |
121 | } |
122 | if (ret == 0) { |
123 | *status = POWER_SUPPLY_STATUS_DISCHARGING; |
124 | return 0; |
125 | } |
126 | |
127 | /* |
128 | * The MAX170xx has builtin end-of-charge detection and will update |
129 | * FullCAP to match RepCap when it detects end of charging. |
130 | * |
131 | * When this cycle the battery gets charged to a higher (calculated) |
132 | * capacity then the previous cycle then FullCAP will get updated |
133 | * continuously once end-of-charge detection kicks in, so allow the |
134 | * 2 to differ a bit. |
135 | */ |
136 | |
137 | ret = regmap_read(map: chip->regmap, reg: MAX17042_FullCAP, val: &charge_full); |
138 | if (ret < 0) |
139 | return ret; |
140 | |
141 | ret = regmap_read(map: chip->regmap, reg: MAX17042_RepCap, val: &charge_now); |
142 | if (ret < 0) |
143 | return ret; |
144 | |
145 | if ((charge_full - charge_now) <= MAX17042_FULL_THRESHOLD) { |
146 | *status = POWER_SUPPLY_STATUS_FULL; |
147 | return 0; |
148 | } |
149 | |
150 | /* |
151 | * Even though we are supplied, we may still be discharging if the |
152 | * supply is e.g. only delivering 5V 0.5A. Check current if available. |
153 | */ |
154 | if (!chip->pdata->enable_current_sense) { |
155 | *status = POWER_SUPPLY_STATUS_CHARGING; |
156 | return 0; |
157 | } |
158 | |
159 | ret = regmap_read(map: chip->regmap, reg: MAX17042_AvgCurrent, val: &data); |
160 | if (ret < 0) |
161 | return ret; |
162 | |
163 | avg_current = sign_extend32(value: data, index: 15); |
164 | avg_current *= 1562500 / chip->pdata->r_sns; |
165 | |
166 | if (avg_current > 0) |
167 | *status = POWER_SUPPLY_STATUS_CHARGING; |
168 | else |
169 | *status = POWER_SUPPLY_STATUS_DISCHARGING; |
170 | |
171 | return 0; |
172 | } |
173 | |
174 | static int max17042_get_battery_health(struct max17042_chip *chip, int *health) |
175 | { |
176 | int temp, vavg, vbatt, ret; |
177 | u32 val; |
178 | |
179 | ret = regmap_read(map: chip->regmap, reg: MAX17042_AvgVCELL, val: &val); |
180 | if (ret < 0) |
181 | goto health_error; |
182 | |
183 | /* bits [0-3] unused */ |
184 | vavg = val * 625 / 8; |
185 | /* Convert to millivolts */ |
186 | vavg /= 1000; |
187 | |
188 | ret = regmap_read(map: chip->regmap, reg: MAX17042_VCELL, val: &val); |
189 | if (ret < 0) |
190 | goto health_error; |
191 | |
192 | /* bits [0-3] unused */ |
193 | vbatt = val * 625 / 8; |
194 | /* Convert to millivolts */ |
195 | vbatt /= 1000; |
196 | |
197 | if (vavg < chip->pdata->vmin) { |
198 | *health = POWER_SUPPLY_HEALTH_DEAD; |
199 | goto out; |
200 | } |
201 | |
202 | if (vbatt > chip->pdata->vmax + MAX17042_VMAX_TOLERANCE) { |
203 | *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; |
204 | goto out; |
205 | } |
206 | |
207 | ret = max17042_get_temperature(chip, temp: &temp); |
208 | if (ret < 0) |
209 | goto health_error; |
210 | |
211 | if (temp < chip->pdata->temp_min) { |
212 | *health = POWER_SUPPLY_HEALTH_COLD; |
213 | goto out; |
214 | } |
215 | |
216 | if (temp > chip->pdata->temp_max) { |
217 | *health = POWER_SUPPLY_HEALTH_OVERHEAT; |
218 | goto out; |
219 | } |
220 | |
221 | *health = POWER_SUPPLY_HEALTH_GOOD; |
222 | |
223 | out: |
224 | return 0; |
225 | |
226 | health_error: |
227 | return ret; |
228 | } |
229 | |
230 | static int max17042_get_property(struct power_supply *psy, |
231 | enum power_supply_property psp, |
232 | union power_supply_propval *val) |
233 | { |
234 | struct max17042_chip *chip = power_supply_get_drvdata(psy); |
235 | struct regmap *map = chip->regmap; |
236 | int ret; |
237 | u32 data; |
238 | u64 data64; |
239 | |
240 | if (!chip->init_complete) |
241 | return -EAGAIN; |
242 | |
243 | switch (psp) { |
244 | case POWER_SUPPLY_PROP_STATUS: |
245 | ret = max17042_get_status(chip, status: &val->intval); |
246 | if (ret < 0) |
247 | return ret; |
248 | break; |
249 | case POWER_SUPPLY_PROP_PRESENT: |
250 | ret = regmap_read(map, reg: MAX17042_STATUS, val: &data); |
251 | if (ret < 0) |
252 | return ret; |
253 | |
254 | if (data & MAX17042_STATUS_BattAbsent) |
255 | val->intval = 0; |
256 | else |
257 | val->intval = 1; |
258 | break; |
259 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
260 | val->intval = POWER_SUPPLY_TECHNOLOGY_LION; |
261 | break; |
262 | case POWER_SUPPLY_PROP_CYCLE_COUNT: |
263 | ret = regmap_read(map, reg: MAX17042_Cycles, val: &data); |
264 | if (ret < 0) |
265 | return ret; |
266 | |
267 | val->intval = data; |
268 | break; |
269 | case POWER_SUPPLY_PROP_VOLTAGE_MAX: |
270 | ret = regmap_read(map, reg: MAX17042_MinMaxVolt, val: &data); |
271 | if (ret < 0) |
272 | return ret; |
273 | |
274 | val->intval = data >> 8; |
275 | val->intval *= 20000; /* Units of LSB = 20mV */ |
276 | break; |
277 | case POWER_SUPPLY_PROP_VOLTAGE_MIN: |
278 | ret = regmap_read(map, reg: MAX17042_MinMaxVolt, val: &data); |
279 | if (ret < 0) |
280 | return ret; |
281 | |
282 | val->intval = (data & 0xff) * 20000; /* Units of 20mV */ |
283 | break; |
284 | case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: |
285 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) |
286 | ret = regmap_read(map, reg: MAX17042_V_empty, val: &data); |
287 | else |
288 | ret = regmap_read(map, reg: MAX17047_V_empty, val: &data); |
289 | if (ret < 0) |
290 | return ret; |
291 | |
292 | val->intval = data >> 7; |
293 | val->intval *= 10000; /* Units of LSB = 10mV */ |
294 | break; |
295 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
296 | ret = regmap_read(map, reg: MAX17042_VCELL, val: &data); |
297 | if (ret < 0) |
298 | return ret; |
299 | |
300 | val->intval = data * 625 / 8; |
301 | break; |
302 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: |
303 | ret = regmap_read(map, reg: MAX17042_AvgVCELL, val: &data); |
304 | if (ret < 0) |
305 | return ret; |
306 | |
307 | val->intval = data * 625 / 8; |
308 | break; |
309 | case POWER_SUPPLY_PROP_VOLTAGE_OCV: |
310 | ret = regmap_read(map, reg: MAX17042_OCVInternal, val: &data); |
311 | if (ret < 0) |
312 | return ret; |
313 | |
314 | val->intval = data * 625 / 8; |
315 | break; |
316 | case POWER_SUPPLY_PROP_CAPACITY: |
317 | if (chip->pdata->enable_current_sense) |
318 | ret = regmap_read(map, reg: MAX17042_RepSOC, val: &data); |
319 | else |
320 | ret = regmap_read(map, reg: MAX17042_VFSOC, val: &data); |
321 | if (ret < 0) |
322 | return ret; |
323 | |
324 | val->intval = data >> 8; |
325 | break; |
326 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: |
327 | ret = regmap_read(map, reg: MAX17042_DesignCap, val: &data); |
328 | if (ret < 0) |
329 | return ret; |
330 | |
331 | data64 = data * 5000000ll; |
332 | do_div(data64, chip->pdata->r_sns); |
333 | val->intval = data64; |
334 | break; |
335 | case POWER_SUPPLY_PROP_CHARGE_FULL: |
336 | ret = regmap_read(map, reg: MAX17042_FullCAP, val: &data); |
337 | if (ret < 0) |
338 | return ret; |
339 | |
340 | data64 = data * 5000000ll; |
341 | do_div(data64, chip->pdata->r_sns); |
342 | val->intval = data64; |
343 | break; |
344 | case POWER_SUPPLY_PROP_CHARGE_NOW: |
345 | ret = regmap_read(map, reg: MAX17042_RepCap, val: &data); |
346 | if (ret < 0) |
347 | return ret; |
348 | |
349 | data64 = data * 5000000ll; |
350 | do_div(data64, chip->pdata->r_sns); |
351 | val->intval = data64; |
352 | break; |
353 | case POWER_SUPPLY_PROP_CHARGE_COUNTER: |
354 | ret = regmap_read(map, reg: MAX17042_QH, val: &data); |
355 | if (ret < 0) |
356 | return ret; |
357 | |
358 | data64 = sign_extend64(value: data, index: 15) * 5000000ll; |
359 | val->intval = div_s64(dividend: data64, divisor: chip->pdata->r_sns); |
360 | break; |
361 | case POWER_SUPPLY_PROP_TEMP: |
362 | ret = max17042_get_temperature(chip, temp: &val->intval); |
363 | if (ret < 0) |
364 | return ret; |
365 | break; |
366 | case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: |
367 | ret = regmap_read(map, reg: MAX17042_TALRT_Th, val: &data); |
368 | if (ret < 0) |
369 | return ret; |
370 | /* LSB is Alert Minimum. In deci-centigrade */ |
371 | val->intval = sign_extend32(value: data & 0xff, index: 7) * 10; |
372 | break; |
373 | case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: |
374 | ret = regmap_read(map, reg: MAX17042_TALRT_Th, val: &data); |
375 | if (ret < 0) |
376 | return ret; |
377 | /* MSB is Alert Maximum. In deci-centigrade */ |
378 | val->intval = sign_extend32(value: data >> 8, index: 7) * 10; |
379 | break; |
380 | case POWER_SUPPLY_PROP_TEMP_MIN: |
381 | val->intval = chip->pdata->temp_min; |
382 | break; |
383 | case POWER_SUPPLY_PROP_TEMP_MAX: |
384 | val->intval = chip->pdata->temp_max; |
385 | break; |
386 | case POWER_SUPPLY_PROP_HEALTH: |
387 | ret = max17042_get_battery_health(chip, health: &val->intval); |
388 | if (ret < 0) |
389 | return ret; |
390 | break; |
391 | case POWER_SUPPLY_PROP_SCOPE: |
392 | val->intval = POWER_SUPPLY_SCOPE_SYSTEM; |
393 | break; |
394 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
395 | if (chip->pdata->enable_current_sense) { |
396 | ret = regmap_read(map, reg: MAX17042_Current, val: &data); |
397 | if (ret < 0) |
398 | return ret; |
399 | |
400 | data64 = sign_extend64(value: data, index: 15) * 1562500ll; |
401 | val->intval = div_s64(dividend: data64, divisor: chip->pdata->r_sns); |
402 | } else { |
403 | return -EINVAL; |
404 | } |
405 | break; |
406 | case POWER_SUPPLY_PROP_CURRENT_AVG: |
407 | if (chip->pdata->enable_current_sense) { |
408 | ret = regmap_read(map, reg: MAX17042_AvgCurrent, val: &data); |
409 | if (ret < 0) |
410 | return ret; |
411 | |
412 | data64 = sign_extend64(value: data, index: 15) * 1562500ll; |
413 | val->intval = div_s64(dividend: data64, divisor: chip->pdata->r_sns); |
414 | } else { |
415 | return -EINVAL; |
416 | } |
417 | break; |
418 | case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: |
419 | ret = regmap_read(map, reg: MAX17042_ICHGTerm, val: &data); |
420 | if (ret < 0) |
421 | return ret; |
422 | |
423 | data64 = data * 1562500ll; |
424 | val->intval = div_s64(dividend: data64, divisor: chip->pdata->r_sns); |
425 | break; |
426 | case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: |
427 | ret = regmap_read(map, reg: MAX17042_TTE, val: &data); |
428 | if (ret < 0) |
429 | return ret; |
430 | |
431 | val->intval = data * 5625 / 1000; |
432 | break; |
433 | default: |
434 | return -EINVAL; |
435 | } |
436 | return 0; |
437 | } |
438 | |
439 | static int max17042_set_property(struct power_supply *psy, |
440 | enum power_supply_property psp, |
441 | const union power_supply_propval *val) |
442 | { |
443 | struct max17042_chip *chip = power_supply_get_drvdata(psy); |
444 | struct regmap *map = chip->regmap; |
445 | int ret = 0; |
446 | u32 data; |
447 | int8_t temp; |
448 | |
449 | switch (psp) { |
450 | case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: |
451 | ret = regmap_read(map, reg: MAX17042_TALRT_Th, val: &data); |
452 | if (ret < 0) |
453 | return ret; |
454 | |
455 | /* Input in deci-centigrade, convert to centigrade */ |
456 | temp = val->intval / 10; |
457 | /* force min < max */ |
458 | if (temp >= (int8_t)(data >> 8)) |
459 | temp = (int8_t)(data >> 8) - 1; |
460 | /* Write both MAX and MIN ALERT */ |
461 | data = (data & 0xff00) + temp; |
462 | ret = regmap_write(map, reg: MAX17042_TALRT_Th, val: data); |
463 | break; |
464 | case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: |
465 | ret = regmap_read(map, reg: MAX17042_TALRT_Th, val: &data); |
466 | if (ret < 0) |
467 | return ret; |
468 | |
469 | /* Input in Deci-Centigrade, convert to centigrade */ |
470 | temp = val->intval / 10; |
471 | /* force max > min */ |
472 | if (temp <= (int8_t)(data & 0xff)) |
473 | temp = (int8_t)(data & 0xff) + 1; |
474 | /* Write both MAX and MIN ALERT */ |
475 | data = (data & 0xff) + (temp << 8); |
476 | ret = regmap_write(map, reg: MAX17042_TALRT_Th, val: data); |
477 | break; |
478 | default: |
479 | ret = -EINVAL; |
480 | } |
481 | |
482 | return ret; |
483 | } |
484 | |
485 | static int max17042_property_is_writeable(struct power_supply *psy, |
486 | enum power_supply_property psp) |
487 | { |
488 | int ret; |
489 | |
490 | switch (psp) { |
491 | case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: |
492 | case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: |
493 | ret = 1; |
494 | break; |
495 | default: |
496 | ret = 0; |
497 | } |
498 | |
499 | return ret; |
500 | } |
501 | |
502 | static int max17042_write_verify_reg(struct regmap *map, u8 reg, u32 value) |
503 | { |
504 | int retries = 8; |
505 | int ret; |
506 | u32 read_value; |
507 | |
508 | do { |
509 | ret = regmap_write(map, reg, val: value); |
510 | regmap_read(map, reg, val: &read_value); |
511 | if (read_value != value) { |
512 | ret = -EIO; |
513 | retries--; |
514 | } |
515 | } while (retries && read_value != value); |
516 | |
517 | if (ret < 0) |
518 | pr_err("%s: err %d\n" , __func__, ret); |
519 | |
520 | return ret; |
521 | } |
522 | |
523 | static inline void max17042_override_por(struct regmap *map, |
524 | u8 reg, u16 value) |
525 | { |
526 | if (value) |
527 | regmap_write(map, reg, val: value); |
528 | } |
529 | |
530 | static inline void max17042_unlock_model(struct max17042_chip *chip) |
531 | { |
532 | struct regmap *map = chip->regmap; |
533 | |
534 | regmap_write(map, reg: MAX17042_MLOCKReg1, MODEL_UNLOCK1); |
535 | regmap_write(map, reg: MAX17042_MLOCKReg2, MODEL_UNLOCK2); |
536 | } |
537 | |
538 | static inline void max17042_lock_model(struct max17042_chip *chip) |
539 | { |
540 | struct regmap *map = chip->regmap; |
541 | |
542 | regmap_write(map, reg: MAX17042_MLOCKReg1, MODEL_LOCK1); |
543 | regmap_write(map, reg: MAX17042_MLOCKReg2, MODEL_LOCK2); |
544 | } |
545 | |
546 | static inline void max17042_write_model_data(struct max17042_chip *chip, |
547 | u8 addr, int size) |
548 | { |
549 | struct regmap *map = chip->regmap; |
550 | int i; |
551 | |
552 | for (i = 0; i < size; i++) |
553 | regmap_write(map, reg: addr + i, |
554 | val: chip->pdata->config_data->cell_char_tbl[i]); |
555 | } |
556 | |
557 | static inline void max17042_read_model_data(struct max17042_chip *chip, |
558 | u8 addr, u16 *data, int size) |
559 | { |
560 | struct regmap *map = chip->regmap; |
561 | int i; |
562 | u32 tmp; |
563 | |
564 | for (i = 0; i < size; i++) { |
565 | regmap_read(map, reg: addr + i, val: &tmp); |
566 | data[i] = (u16)tmp; |
567 | } |
568 | } |
569 | |
570 | static inline int max17042_model_data_compare(struct max17042_chip *chip, |
571 | u16 *data1, u16 *data2, int size) |
572 | { |
573 | int i; |
574 | |
575 | if (memcmp(p: data1, q: data2, size)) { |
576 | dev_err(&chip->client->dev, "%s compare failed\n" , __func__); |
577 | for (i = 0; i < size; i++) |
578 | dev_info(&chip->client->dev, "0x%x, 0x%x" , |
579 | data1[i], data2[i]); |
580 | dev_info(&chip->client->dev, "\n" ); |
581 | return -EINVAL; |
582 | } |
583 | return 0; |
584 | } |
585 | |
586 | static int max17042_init_model(struct max17042_chip *chip) |
587 | { |
588 | int ret; |
589 | int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); |
590 | u16 *temp_data; |
591 | |
592 | temp_data = kcalloc(n: table_size, size: sizeof(*temp_data), GFP_KERNEL); |
593 | if (!temp_data) |
594 | return -ENOMEM; |
595 | |
596 | max17042_unlock_model(chip); |
597 | max17042_write_model_data(chip, addr: MAX17042_MODELChrTbl, |
598 | size: table_size); |
599 | max17042_read_model_data(chip, addr: MAX17042_MODELChrTbl, data: temp_data, |
600 | size: table_size); |
601 | |
602 | ret = max17042_model_data_compare( |
603 | chip, |
604 | data1: chip->pdata->config_data->cell_char_tbl, |
605 | data2: temp_data, |
606 | size: table_size); |
607 | |
608 | max17042_lock_model(chip); |
609 | kfree(objp: temp_data); |
610 | |
611 | return ret; |
612 | } |
613 | |
614 | static int max17042_verify_model_lock(struct max17042_chip *chip) |
615 | { |
616 | int i; |
617 | int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl); |
618 | u16 *temp_data; |
619 | int ret = 0; |
620 | |
621 | temp_data = kcalloc(n: table_size, size: sizeof(*temp_data), GFP_KERNEL); |
622 | if (!temp_data) |
623 | return -ENOMEM; |
624 | |
625 | max17042_read_model_data(chip, addr: MAX17042_MODELChrTbl, data: temp_data, |
626 | size: table_size); |
627 | for (i = 0; i < table_size; i++) |
628 | if (temp_data[i]) |
629 | ret = -EINVAL; |
630 | |
631 | kfree(objp: temp_data); |
632 | return ret; |
633 | } |
634 | |
635 | static void max17042_write_config_regs(struct max17042_chip *chip) |
636 | { |
637 | struct max17042_config_data *config = chip->pdata->config_data; |
638 | struct regmap *map = chip->regmap; |
639 | |
640 | regmap_write(map, reg: MAX17042_CONFIG, val: config->config); |
641 | regmap_write(map, reg: MAX17042_LearnCFG, val: config->learn_cfg); |
642 | regmap_write(map, reg: MAX17042_FilterCFG, |
643 | val: config->filter_cfg); |
644 | regmap_write(map, reg: MAX17042_RelaxCFG, val: config->relax_cfg); |
645 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047 || |
646 | chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050 || |
647 | chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055) |
648 | regmap_write(map, reg: MAX17047_FullSOCThr, |
649 | val: config->full_soc_thresh); |
650 | } |
651 | |
652 | static void max17042_write_custom_regs(struct max17042_chip *chip) |
653 | { |
654 | struct max17042_config_data *config = chip->pdata->config_data; |
655 | struct regmap *map = chip->regmap; |
656 | |
657 | max17042_write_verify_reg(map, reg: MAX17042_RCOMP0, value: config->rcomp0); |
658 | max17042_write_verify_reg(map, reg: MAX17042_TempCo, value: config->tcompc0); |
659 | max17042_write_verify_reg(map, reg: MAX17042_ICHGTerm, value: config->ichgt_term); |
660 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) { |
661 | regmap_write(map, reg: MAX17042_EmptyTempCo, val: config->empty_tempco); |
662 | max17042_write_verify_reg(map, reg: MAX17042_K_empty0, |
663 | value: config->kempty0); |
664 | } else { |
665 | max17042_write_verify_reg(map, reg: MAX17047_QRTbl00, |
666 | value: config->qrtbl00); |
667 | max17042_write_verify_reg(map, reg: MAX17047_QRTbl10, |
668 | value: config->qrtbl10); |
669 | max17042_write_verify_reg(map, reg: MAX17047_QRTbl20, |
670 | value: config->qrtbl20); |
671 | max17042_write_verify_reg(map, reg: MAX17047_QRTbl30, |
672 | value: config->qrtbl30); |
673 | } |
674 | } |
675 | |
676 | static void max17042_update_capacity_regs(struct max17042_chip *chip) |
677 | { |
678 | struct max17042_config_data *config = chip->pdata->config_data; |
679 | struct regmap *map = chip->regmap; |
680 | |
681 | max17042_write_verify_reg(map, reg: MAX17042_FullCAP, |
682 | value: config->fullcap); |
683 | regmap_write(map, reg: MAX17042_DesignCap, val: config->design_cap); |
684 | max17042_write_verify_reg(map, reg: MAX17042_FullCAPNom, |
685 | value: config->fullcapnom); |
686 | } |
687 | |
688 | static void max17042_reset_vfsoc0_reg(struct max17042_chip *chip) |
689 | { |
690 | unsigned int vfSoc; |
691 | struct regmap *map = chip->regmap; |
692 | |
693 | regmap_read(map, reg: MAX17042_VFSOC, val: &vfSoc); |
694 | regmap_write(map, reg: MAX17042_VFSOC0Enable, VFSOC0_UNLOCK); |
695 | max17042_write_verify_reg(map, reg: MAX17042_VFSOC0, value: vfSoc); |
696 | regmap_write(map, reg: MAX17042_VFSOC0Enable, VFSOC0_LOCK); |
697 | } |
698 | |
699 | static void max17042_load_new_capacity_params(struct max17042_chip *chip) |
700 | { |
701 | u32 full_cap0, rep_cap, dq_acc, vfSoc; |
702 | u32 rem_cap; |
703 | |
704 | struct max17042_config_data *config = chip->pdata->config_data; |
705 | struct regmap *map = chip->regmap; |
706 | |
707 | regmap_read(map, reg: MAX17042_FullCAP0, val: &full_cap0); |
708 | regmap_read(map, reg: MAX17042_VFSOC, val: &vfSoc); |
709 | |
710 | /* fg_vfSoc needs to shifted by 8 bits to get the |
711 | * perc in 1% accuracy, to get the right rem_cap multiply |
712 | * full_cap0, fg_vfSoc and devide by 100 |
713 | */ |
714 | rem_cap = ((vfSoc >> 8) * full_cap0) / 100; |
715 | max17042_write_verify_reg(map, reg: MAX17042_RemCap, value: rem_cap); |
716 | |
717 | rep_cap = rem_cap; |
718 | max17042_write_verify_reg(map, reg: MAX17042_RepCap, value: rep_cap); |
719 | |
720 | /* Write dQ_acc to 200% of Capacity and dP_acc to 200% */ |
721 | dq_acc = config->fullcap / dQ_ACC_DIV; |
722 | max17042_write_verify_reg(map, reg: MAX17042_dQacc, value: dq_acc); |
723 | max17042_write_verify_reg(map, reg: MAX17042_dPacc, dP_ACC_200); |
724 | |
725 | max17042_write_verify_reg(map, reg: MAX17042_FullCAP, |
726 | value: config->fullcap); |
727 | regmap_write(map, reg: MAX17042_DesignCap, |
728 | val: config->design_cap); |
729 | max17042_write_verify_reg(map, reg: MAX17042_FullCAPNom, |
730 | value: config->fullcapnom); |
731 | /* Update SOC register with new SOC */ |
732 | regmap_write(map, reg: MAX17042_RepSOC, val: vfSoc); |
733 | } |
734 | |
735 | /* |
736 | * Block write all the override values coming from platform data. |
737 | * This function MUST be called before the POR initialization procedure |
738 | * specified by maxim. |
739 | */ |
740 | static inline void max17042_override_por_values(struct max17042_chip *chip) |
741 | { |
742 | struct regmap *map = chip->regmap; |
743 | struct max17042_config_data *config = chip->pdata->config_data; |
744 | |
745 | max17042_override_por(map, reg: MAX17042_TGAIN, value: config->tgain); |
746 | max17042_override_por(map, reg: MAX17042_TOFF, value: config->toff); |
747 | max17042_override_por(map, reg: MAX17042_CGAIN, value: config->cgain); |
748 | max17042_override_por(map, reg: MAX17042_COFF, value: config->coff); |
749 | |
750 | max17042_override_por(map, reg: MAX17042_VALRT_Th, value: config->valrt_thresh); |
751 | max17042_override_por(map, reg: MAX17042_TALRT_Th, value: config->talrt_thresh); |
752 | max17042_override_por(map, reg: MAX17042_SALRT_Th, |
753 | value: config->soc_alrt_thresh); |
754 | max17042_override_por(map, reg: MAX17042_CONFIG, value: config->config); |
755 | max17042_override_por(map, reg: MAX17042_SHDNTIMER, value: config->shdntimer); |
756 | |
757 | max17042_override_por(map, reg: MAX17042_DesignCap, value: config->design_cap); |
758 | max17042_override_por(map, reg: MAX17042_ICHGTerm, value: config->ichgt_term); |
759 | |
760 | max17042_override_por(map, reg: MAX17042_AtRate, value: config->at_rate); |
761 | max17042_override_por(map, reg: MAX17042_LearnCFG, value: config->learn_cfg); |
762 | max17042_override_por(map, reg: MAX17042_FilterCFG, value: config->filter_cfg); |
763 | max17042_override_por(map, reg: MAX17042_RelaxCFG, value: config->relax_cfg); |
764 | max17042_override_por(map, reg: MAX17042_MiscCFG, value: config->misc_cfg); |
765 | |
766 | max17042_override_por(map, reg: MAX17042_FullCAP, value: config->fullcap); |
767 | max17042_override_por(map, reg: MAX17042_FullCAPNom, value: config->fullcapnom); |
768 | max17042_override_por(map, reg: MAX17042_dQacc, value: config->dqacc); |
769 | max17042_override_por(map, reg: MAX17042_dPacc, value: config->dpacc); |
770 | |
771 | max17042_override_por(map, reg: MAX17042_RCOMP0, value: config->rcomp0); |
772 | max17042_override_por(map, reg: MAX17042_TempCo, value: config->tcompc0); |
773 | |
774 | if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) { |
775 | max17042_override_por(map, reg: MAX17042_MaskSOC, value: config->masksoc); |
776 | max17042_override_por(map, reg: MAX17042_SOC_empty, value: config->socempty); |
777 | max17042_override_por(map, reg: MAX17042_V_empty, value: config->vempty); |
778 | max17042_override_por(map, reg: MAX17042_EmptyTempCo, value: config->empty_tempco); |
779 | max17042_override_por(map, reg: MAX17042_K_empty0, value: config->kempty0); |
780 | } |
781 | |
782 | if ((chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) || |
783 | (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047) || |
784 | (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050)) { |
785 | max17042_override_por(map, reg: MAX17042_IAvg_empty, value: config->iavg_empty); |
786 | max17042_override_por(map, reg: MAX17042_TempNom, value: config->temp_nom); |
787 | max17042_override_por(map, reg: MAX17042_TempLim, value: config->temp_lim); |
788 | max17042_override_por(map, reg: MAX17042_FCTC, value: config->fctc); |
789 | } |
790 | |
791 | if ((chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047) || |
792 | (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050) || |
793 | (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055)) { |
794 | max17042_override_por(map, reg: MAX17047_V_empty, value: config->vempty); |
795 | } |
796 | } |
797 | |
798 | static int max17042_init_chip(struct max17042_chip *chip) |
799 | { |
800 | struct regmap *map = chip->regmap; |
801 | int ret; |
802 | |
803 | max17042_override_por_values(chip); |
804 | /* After Power up, the MAX17042 requires 500mS in order |
805 | * to perform signal debouncing and initial SOC reporting |
806 | */ |
807 | msleep(msecs: 500); |
808 | |
809 | /* Initialize configuration */ |
810 | max17042_write_config_regs(chip); |
811 | |
812 | /* write cell characterization data */ |
813 | ret = max17042_init_model(chip); |
814 | if (ret) { |
815 | dev_err(&chip->client->dev, "%s init failed\n" , |
816 | __func__); |
817 | return -EIO; |
818 | } |
819 | |
820 | ret = max17042_verify_model_lock(chip); |
821 | if (ret) { |
822 | dev_err(&chip->client->dev, "%s lock verify failed\n" , |
823 | __func__); |
824 | return -EIO; |
825 | } |
826 | /* write custom parameters */ |
827 | max17042_write_custom_regs(chip); |
828 | |
829 | /* update capacity params */ |
830 | max17042_update_capacity_regs(chip); |
831 | |
832 | /* delay must be atleast 350mS to allow VFSOC |
833 | * to be calculated from the new configuration |
834 | */ |
835 | msleep(msecs: 350); |
836 | |
837 | /* reset vfsoc0 reg */ |
838 | max17042_reset_vfsoc0_reg(chip); |
839 | |
840 | /* load new capacity params */ |
841 | max17042_load_new_capacity_params(chip); |
842 | |
843 | /* Init complete, Clear the POR bit */ |
844 | regmap_update_bits(map, reg: MAX17042_STATUS, STATUS_POR_BIT, val: 0x0); |
845 | return 0; |
846 | } |
847 | |
848 | static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off) |
849 | { |
850 | struct regmap *map = chip->regmap; |
851 | u32 soc, soc_tr; |
852 | |
853 | /* program interrupt thresholds such that we should |
854 | * get interrupt for every 'off' perc change in the soc |
855 | */ |
856 | regmap_read(map, reg: MAX17042_RepSOC, val: &soc); |
857 | soc >>= 8; |
858 | soc_tr = (soc + off) << 8; |
859 | if (off < soc) |
860 | soc_tr |= soc - off; |
861 | regmap_write(map, reg: MAX17042_SALRT_Th, val: soc_tr); |
862 | } |
863 | |
864 | static irqreturn_t max17042_thread_handler(int id, void *dev) |
865 | { |
866 | struct max17042_chip *chip = dev; |
867 | u32 val; |
868 | int ret; |
869 | |
870 | ret = regmap_read(map: chip->regmap, reg: MAX17042_STATUS, val: &val); |
871 | if (ret) |
872 | return IRQ_HANDLED; |
873 | |
874 | if ((val & STATUS_SMN_BIT) || (val & STATUS_SMX_BIT)) { |
875 | dev_dbg(&chip->client->dev, "SOC threshold INTR\n" ); |
876 | max17042_set_soc_threshold(chip, off: 1); |
877 | } |
878 | |
879 | /* we implicitly handle all alerts via power_supply_changed */ |
880 | regmap_clear_bits(map: chip->regmap, reg: MAX17042_STATUS, |
881 | bits: 0xFFFF & ~(STATUS_POR_BIT | STATUS_BST_BIT)); |
882 | |
883 | power_supply_changed(psy: chip->battery); |
884 | return IRQ_HANDLED; |
885 | } |
886 | |
887 | static void max17042_init_worker(struct work_struct *work) |
888 | { |
889 | struct max17042_chip *chip = container_of(work, |
890 | struct max17042_chip, work); |
891 | int ret; |
892 | |
893 | /* Initialize registers according to values from the platform data */ |
894 | if (chip->pdata->enable_por_init && chip->pdata->config_data) { |
895 | ret = max17042_init_chip(chip); |
896 | if (ret) |
897 | return; |
898 | } |
899 | |
900 | chip->init_complete = 1; |
901 | } |
902 | |
903 | #ifdef CONFIG_OF |
904 | static struct max17042_platform_data * |
905 | max17042_get_of_pdata(struct max17042_chip *chip) |
906 | { |
907 | struct device *dev = &chip->client->dev; |
908 | struct device_node *np = dev->of_node; |
909 | u32 prop; |
910 | struct max17042_platform_data *pdata; |
911 | |
912 | pdata = devm_kzalloc(dev, size: sizeof(*pdata), GFP_KERNEL); |
913 | if (!pdata) |
914 | return NULL; |
915 | |
916 | /* |
917 | * Require current sense resistor value to be specified for |
918 | * current-sense functionality to be enabled at all. |
919 | */ |
920 | if (of_property_read_u32(np, propname: "maxim,rsns-microohm" , out_value: &prop) == 0) { |
921 | pdata->r_sns = prop; |
922 | pdata->enable_current_sense = true; |
923 | } |
924 | |
925 | if (of_property_read_s32(np, propname: "maxim,cold-temp" , out_value: &pdata->temp_min)) |
926 | pdata->temp_min = INT_MIN; |
927 | if (of_property_read_s32(np, propname: "maxim,over-heat-temp" , out_value: &pdata->temp_max)) |
928 | pdata->temp_max = INT_MAX; |
929 | if (of_property_read_s32(np, propname: "maxim,dead-volt" , out_value: &pdata->vmin)) |
930 | pdata->vmin = INT_MIN; |
931 | if (of_property_read_s32(np, propname: "maxim,over-volt" , out_value: &pdata->vmax)) |
932 | pdata->vmax = INT_MAX; |
933 | |
934 | return pdata; |
935 | } |
936 | #endif |
937 | |
938 | static struct max17042_reg_data max17047_default_pdata_init_regs[] = { |
939 | /* |
940 | * Some firmwares do not set FullSOCThr, Enable End-of-Charge Detection |
941 | * when the voltage FG reports 95%, as recommended in the datasheet. |
942 | */ |
943 | { MAX17047_FullSOCThr, MAX17042_BATTERY_FULL << 8 }, |
944 | }; |
945 | |
946 | static struct max17042_platform_data * |
947 | max17042_get_default_pdata(struct max17042_chip *chip) |
948 | { |
949 | struct device *dev = &chip->client->dev; |
950 | struct max17042_platform_data *pdata; |
951 | int ret, misc_cfg; |
952 | |
953 | /* |
954 | * The MAX17047 gets used on x86 where we might not have pdata, assume |
955 | * the firmware will already have initialized the fuel-gauge and provide |
956 | * default values for the non init bits to make things work. |
957 | */ |
958 | pdata = devm_kzalloc(dev, size: sizeof(*pdata), GFP_KERNEL); |
959 | if (!pdata) |
960 | return pdata; |
961 | |
962 | if ((chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047) || |
963 | (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050)) { |
964 | pdata->init_data = max17047_default_pdata_init_regs; |
965 | pdata->num_init_data = |
966 | ARRAY_SIZE(max17047_default_pdata_init_regs); |
967 | } |
968 | |
969 | ret = regmap_read(map: chip->regmap, reg: MAX17042_MiscCFG, val: &misc_cfg); |
970 | if (ret < 0) |
971 | return NULL; |
972 | |
973 | /* If bits 0-1 are set to 3 then only Voltage readings are used */ |
974 | if ((misc_cfg & 0x3) == 0x3) |
975 | pdata->enable_current_sense = false; |
976 | else |
977 | pdata->enable_current_sense = true; |
978 | |
979 | pdata->vmin = MAX17042_DEFAULT_VMIN; |
980 | pdata->vmax = MAX17042_DEFAULT_VMAX; |
981 | pdata->temp_min = MAX17042_DEFAULT_TEMP_MIN; |
982 | pdata->temp_max = MAX17042_DEFAULT_TEMP_MAX; |
983 | |
984 | return pdata; |
985 | } |
986 | |
987 | static struct max17042_platform_data * |
988 | max17042_get_pdata(struct max17042_chip *chip) |
989 | { |
990 | struct device *dev = &chip->client->dev; |
991 | |
992 | #ifdef CONFIG_OF |
993 | if (dev->of_node) |
994 | return max17042_get_of_pdata(chip); |
995 | #endif |
996 | if (dev->platform_data) |
997 | return dev->platform_data; |
998 | |
999 | return max17042_get_default_pdata(chip); |
1000 | } |
1001 | |
1002 | static const struct regmap_config max17042_regmap_config = { |
1003 | .reg_bits = 8, |
1004 | .val_bits = 16, |
1005 | .val_format_endian = REGMAP_ENDIAN_NATIVE, |
1006 | }; |
1007 | |
1008 | static const struct power_supply_desc max17042_psy_desc = { |
1009 | .name = "max170xx_battery" , |
1010 | .type = POWER_SUPPLY_TYPE_BATTERY, |
1011 | .get_property = max17042_get_property, |
1012 | .set_property = max17042_set_property, |
1013 | .property_is_writeable = max17042_property_is_writeable, |
1014 | .external_power_changed = power_supply_changed, |
1015 | .properties = max17042_battery_props, |
1016 | .num_properties = ARRAY_SIZE(max17042_battery_props), |
1017 | }; |
1018 | |
1019 | static const struct power_supply_desc max17042_no_current_sense_psy_desc = { |
1020 | .name = "max170xx_battery" , |
1021 | .type = POWER_SUPPLY_TYPE_BATTERY, |
1022 | .get_property = max17042_get_property, |
1023 | .set_property = max17042_set_property, |
1024 | .property_is_writeable = max17042_property_is_writeable, |
1025 | .properties = max17042_battery_props, |
1026 | .num_properties = ARRAY_SIZE(max17042_battery_props) - 2, |
1027 | }; |
1028 | |
1029 | static int max17042_probe(struct i2c_client *client) |
1030 | { |
1031 | const struct i2c_device_id *id = i2c_client_get_device_id(client); |
1032 | struct i2c_adapter *adapter = client->adapter; |
1033 | const struct power_supply_desc *max17042_desc = &max17042_psy_desc; |
1034 | struct power_supply_config psy_cfg = {}; |
1035 | const struct acpi_device_id *acpi_id = NULL; |
1036 | struct device *dev = &client->dev; |
1037 | struct max17042_chip *chip; |
1038 | int ret; |
1039 | int i; |
1040 | u32 val; |
1041 | |
1042 | if (!i2c_check_functionality(adap: adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
1043 | return -EIO; |
1044 | |
1045 | chip = devm_kzalloc(dev: &client->dev, size: sizeof(*chip), GFP_KERNEL); |
1046 | if (!chip) |
1047 | return -ENOMEM; |
1048 | |
1049 | chip->client = client; |
1050 | if (id) { |
1051 | chip->chip_type = id->driver_data; |
1052 | } else { |
1053 | acpi_id = acpi_match_device(ids: dev->driver->acpi_match_table, dev); |
1054 | if (!acpi_id) |
1055 | return -ENODEV; |
1056 | |
1057 | chip->chip_type = acpi_id->driver_data; |
1058 | } |
1059 | chip->regmap = devm_regmap_init_i2c(client, &max17042_regmap_config); |
1060 | if (IS_ERR(ptr: chip->regmap)) { |
1061 | dev_err(&client->dev, "Failed to initialize regmap\n" ); |
1062 | return -EINVAL; |
1063 | } |
1064 | |
1065 | chip->pdata = max17042_get_pdata(chip); |
1066 | if (!chip->pdata) { |
1067 | dev_err(&client->dev, "no platform data provided\n" ); |
1068 | return -EINVAL; |
1069 | } |
1070 | |
1071 | i2c_set_clientdata(client, data: chip); |
1072 | psy_cfg.drv_data = chip; |
1073 | psy_cfg.of_node = dev->of_node; |
1074 | |
1075 | /* When current is not measured, |
1076 | * CURRENT_NOW and CURRENT_AVG properties should be invisible. */ |
1077 | if (!chip->pdata->enable_current_sense) |
1078 | max17042_desc = &max17042_no_current_sense_psy_desc; |
1079 | |
1080 | if (chip->pdata->r_sns == 0) |
1081 | chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR; |
1082 | |
1083 | if (chip->pdata->init_data) |
1084 | for (i = 0; i < chip->pdata->num_init_data; i++) |
1085 | regmap_write(map: chip->regmap, |
1086 | reg: chip->pdata->init_data[i].addr, |
1087 | val: chip->pdata->init_data[i].data); |
1088 | |
1089 | if (!chip->pdata->enable_current_sense) { |
1090 | regmap_write(map: chip->regmap, reg: MAX17042_CGAIN, val: 0x0000); |
1091 | regmap_write(map: chip->regmap, reg: MAX17042_MiscCFG, val: 0x0003); |
1092 | regmap_write(map: chip->regmap, reg: MAX17042_LearnCFG, val: 0x0007); |
1093 | } |
1094 | |
1095 | chip->battery = devm_power_supply_register(parent: &client->dev, desc: max17042_desc, |
1096 | cfg: &psy_cfg); |
1097 | if (IS_ERR(ptr: chip->battery)) { |
1098 | dev_err(&client->dev, "failed: power supply register\n" ); |
1099 | return PTR_ERR(ptr: chip->battery); |
1100 | } |
1101 | |
1102 | if (client->irq) { |
1103 | unsigned int flags = IRQF_ONESHOT; |
1104 | |
1105 | /* |
1106 | * On ACPI systems the IRQ may be handled by ACPI-event code, |
1107 | * so we need to share (if the ACPI code is willing to share). |
1108 | */ |
1109 | if (acpi_id) |
1110 | flags |= IRQF_SHARED | IRQF_PROBE_SHARED; |
1111 | |
1112 | ret = devm_request_threaded_irq(dev: &client->dev, irq: client->irq, |
1113 | NULL, |
1114 | thread_fn: max17042_thread_handler, irqflags: flags, |
1115 | devname: chip->battery->desc->name, |
1116 | dev_id: chip); |
1117 | if (!ret) { |
1118 | regmap_update_bits(map: chip->regmap, reg: MAX17042_CONFIG, |
1119 | CFG_ALRT_BIT_ENBL, |
1120 | CFG_ALRT_BIT_ENBL); |
1121 | max17042_set_soc_threshold(chip, off: 1); |
1122 | } else { |
1123 | client->irq = 0; |
1124 | if (ret != -EBUSY) |
1125 | dev_err(&client->dev, "Failed to get IRQ\n" ); |
1126 | } |
1127 | } |
1128 | /* Not able to update the charge threshold when exceeded? -> disable */ |
1129 | if (!client->irq) |
1130 | regmap_write(map: chip->regmap, reg: MAX17042_SALRT_Th, val: 0xff00); |
1131 | |
1132 | regmap_read(map: chip->regmap, reg: MAX17042_STATUS, val: &val); |
1133 | if (val & STATUS_POR_BIT) { |
1134 | ret = devm_work_autocancel(dev: &client->dev, w: &chip->work, |
1135 | worker: max17042_init_worker); |
1136 | if (ret) |
1137 | return ret; |
1138 | schedule_work(work: &chip->work); |
1139 | } else { |
1140 | chip->init_complete = 1; |
1141 | } |
1142 | |
1143 | return 0; |
1144 | } |
1145 | |
1146 | #ifdef CONFIG_PM_SLEEP |
1147 | static int max17042_suspend(struct device *dev) |
1148 | { |
1149 | struct max17042_chip *chip = dev_get_drvdata(dev); |
1150 | |
1151 | /* |
1152 | * disable the irq and enable irq_wake |
1153 | * capability to the interrupt line. |
1154 | */ |
1155 | if (chip->client->irq) { |
1156 | disable_irq(irq: chip->client->irq); |
1157 | enable_irq_wake(irq: chip->client->irq); |
1158 | } |
1159 | |
1160 | return 0; |
1161 | } |
1162 | |
1163 | static int max17042_resume(struct device *dev) |
1164 | { |
1165 | struct max17042_chip *chip = dev_get_drvdata(dev); |
1166 | |
1167 | if (chip->client->irq) { |
1168 | disable_irq_wake(irq: chip->client->irq); |
1169 | enable_irq(irq: chip->client->irq); |
1170 | /* re-program the SOC thresholds to 1% change */ |
1171 | max17042_set_soc_threshold(chip, off: 1); |
1172 | } |
1173 | |
1174 | return 0; |
1175 | } |
1176 | #endif |
1177 | |
1178 | static SIMPLE_DEV_PM_OPS(max17042_pm_ops, max17042_suspend, |
1179 | max17042_resume); |
1180 | |
1181 | #ifdef CONFIG_ACPI |
1182 | static const struct acpi_device_id max17042_acpi_match[] = { |
1183 | { .id: "MAX17047" , .driver_data: MAXIM_DEVICE_TYPE_MAX17047 }, |
1184 | { } |
1185 | }; |
1186 | MODULE_DEVICE_TABLE(acpi, max17042_acpi_match); |
1187 | #endif |
1188 | |
1189 | #ifdef CONFIG_OF |
1190 | static const struct of_device_id max17042_dt_match[] = { |
1191 | { .compatible = "maxim,max17042" }, |
1192 | { .compatible = "maxim,max17047" }, |
1193 | { .compatible = "maxim,max17050" }, |
1194 | { .compatible = "maxim,max17055" }, |
1195 | { .compatible = "maxim,max77849-battery" }, |
1196 | { }, |
1197 | }; |
1198 | MODULE_DEVICE_TABLE(of, max17042_dt_match); |
1199 | #endif |
1200 | |
1201 | static const struct i2c_device_id max17042_id[] = { |
1202 | { "max17042" , MAXIM_DEVICE_TYPE_MAX17042 }, |
1203 | { "max17047" , MAXIM_DEVICE_TYPE_MAX17047 }, |
1204 | { "max17050" , MAXIM_DEVICE_TYPE_MAX17050 }, |
1205 | { "max17055" , MAXIM_DEVICE_TYPE_MAX17055 }, |
1206 | { "max77849-battery" , MAXIM_DEVICE_TYPE_MAX17047 }, |
1207 | { } |
1208 | }; |
1209 | MODULE_DEVICE_TABLE(i2c, max17042_id); |
1210 | |
1211 | static struct i2c_driver max17042_i2c_driver = { |
1212 | .driver = { |
1213 | .name = "max17042" , |
1214 | .acpi_match_table = ACPI_PTR(max17042_acpi_match), |
1215 | .of_match_table = of_match_ptr(max17042_dt_match), |
1216 | .pm = &max17042_pm_ops, |
1217 | }, |
1218 | .probe = max17042_probe, |
1219 | .id_table = max17042_id, |
1220 | }; |
1221 | module_i2c_driver(max17042_i2c_driver); |
1222 | |
1223 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>" ); |
1224 | MODULE_DESCRIPTION("MAX17042 Fuel Gauge" ); |
1225 | MODULE_LICENSE("GPL" ); |
1226 | |