1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* ROHM BD71815, BD71828 and BD71878 Charger driver */
3
4 #include <linux/interrupt.h>
5 #include <linux/kernel.h>
6 #include <linux/mfd/rohm-bd71815.h>
7 #include <linux/mfd/rohm-bd71828.h>
8 #include <linux/mfd/rohm-bd72720.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/property.h>
12 #include <linux/power_supply.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15
16 /* common defines */
17 #define BD7182x_MASK_VBAT_U 0x1f
18 #define BD7182x_MASK_VDCIN_U 0x0f
19 #define BD7182x_MASK_IBAT_U 0x3f
20 #define BD7182x_MASK_CURDIR_DISCHG 0x80
21 #define BD7182x_MASK_CHG_STATE 0x7f
22 #define BD7182x_MASK_BAT_TEMP 0x07
23 #define BD7182x_MASK_DCIN_DET BIT(0)
24 #define BD7182x_MASK_CONF_PON BIT(0)
25 #define BD71815_MASK_CONF_XSTB BIT(1)
26 #define BD7182x_MASK_BAT_STAT 0x3f
27 #define BD7182x_MASK_ILIM 0x3f
28 #define BD71828_MASK_ILIM_DCIN_EN BIT(6)
29 #define BD7182x_MASK_DCIN_STAT 0x07
30
31 #define BD7182x_MASK_WDT_AUTO 0x40
32 #define BD7182x_MASK_VBAT_ALM_LIMIT_U 0x01
33 #define BD7182x_MASK_CHG_EN 0x01
34
35 #define BD7182x_DCIN_COLLAPSE_DEFAULT 0x36
36
37 #define MAX_CURRENT_DEFAULT 890000 /* uA */
38 #define AC_NAME "bd71828_ac"
39 #define BAT_NAME "bd71828_bat"
40
41 #define BAT_OPEN 0x7
42
43 /*
44 * VBAT Low voltage detection Threshold
45 * 0x00D4*16mV = 212*0.016 = 3.392v
46 */
47 #define VBAT_LOW_TH 0x00D4
48
49 struct pwr_regs {
50 unsigned int vbat_avg;
51 unsigned int ibat;
52 unsigned int ibat_avg;
53 unsigned int ilim_stat;
54 unsigned int btemp_vth;
55 unsigned int chg_state;
56 unsigned int bat_temp;
57 unsigned int dcin_set;
58 unsigned int dcin_stat;
59 unsigned int dcin_online_mask;
60 unsigned int dcin_collapse_limit;
61 unsigned int chg_set1;
62 unsigned int chg_en;
63 unsigned int vbat_alm_limit_u;
64 unsigned int conf;
65 unsigned int vdcin;
66 unsigned int vdcin_himask;
67 };
68
69 static const struct pwr_regs pwr_regs_bd71828 = {
70 .vbat_avg = BD71828_REG_VBAT_U,
71 .ibat = BD71828_REG_IBAT_U,
72 .ibat_avg = BD71828_REG_IBAT_AVG_U,
73 .ilim_stat = BD71828_REG_ILIM_STAT,
74 .btemp_vth = BD71828_REG_VM_BTMP_U,
75 .chg_state = BD71828_REG_CHG_STATE,
76 .bat_temp = BD71828_REG_BAT_TEMP,
77 .dcin_set = BD71828_REG_DCIN_SET,
78 .dcin_stat = BD71828_REG_DCIN_STAT,
79 .dcin_online_mask = BD7182x_MASK_DCIN_DET,
80 .dcin_collapse_limit = BD71828_REG_DCIN_CLPS,
81 .chg_set1 = BD71828_REG_CHG_SET1,
82 .chg_en = BD71828_REG_CHG_EN,
83 .vbat_alm_limit_u = BD71828_REG_ALM_VBAT_LIMIT_U,
84 .conf = BD71828_REG_CONF,
85 .vdcin = BD71828_REG_VDCIN_U,
86 .vdcin_himask = BD7182x_MASK_VDCIN_U,
87 };
88
89 static const struct pwr_regs pwr_regs_bd71815 = {
90 .vbat_avg = BD71815_REG_VM_SA_VBAT_U,
91 /* BD71815 does not have separate current and current avg */
92 .ibat = BD71815_REG_CC_CURCD_U,
93 .ibat_avg = BD71815_REG_CC_CURCD_U,
94
95 .btemp_vth = BD71815_REG_VM_BTMP,
96 .chg_state = BD71815_REG_CHG_STATE,
97 .bat_temp = BD71815_REG_BAT_TEMP,
98 .dcin_stat = BD71815_REG_DCIN_STAT,
99 .dcin_online_mask = BD7182x_MASK_DCIN_DET,
100 .dcin_collapse_limit = BD71815_REG_DCIN_CLPS,
101 .chg_set1 = BD71815_REG_CHG_SET1,
102 .chg_en = BD71815_REG_CHG_SET1,
103 .vbat_alm_limit_u = BD71815_REG_ALM_VBAT_TH_U,
104 .conf = BD71815_REG_CONF,
105
106 .vdcin = BD71815_REG_VM_DCIN_U,
107 .vdcin_himask = BD7182x_MASK_VDCIN_U,
108 };
109
110 static struct pwr_regs pwr_regs_bd72720 = {
111 .vbat_avg = BD72720_REG_VM_SA_VBAT_U,
112 .ibat = BD72720_REG_CC_CURCD_U,
113 .ibat_avg = BD72720_REG_CC_SA_CURCD_U,
114 .btemp_vth = BD72720_REG_VM_BTMP_U,
115 /*
116 * Note, state 0x40 IMP_CHK. not documented
117 * on other variants but was still handled in
118 * existing code. No memory traces as to why.
119 */
120 .chg_state = BD72720_REG_CHG_STATE,
121 .bat_temp = BD72720_REG_CHG_BAT_TEMP_STAT,
122 .dcin_stat = BD72720_REG_INT_VBUS_SRC,
123 .dcin_online_mask = BD72720_MASK_DCIN_DET,
124 .dcin_collapse_limit = -1, /* Automatic. Setting not supported */
125 .chg_set1 = BD72720_REG_CHG_SET_1,
126 .chg_en = BD72720_REG_CHG_EN,
127 /* 15mV note in data-sheet */
128 .vbat_alm_limit_u = BD72720_REG_ALM_VBAT_TH_U,
129 .conf = BD72720_REG_CONF, /* o XSTB, only PON. Seprate slave addr */
130 .vdcin = BD72720_REG_VM_VBUS_U, /* 10 bits not 11 as with other ICs */
131 .vdcin_himask = BD72720_MASK_VDCIN_U,
132 };
133
134 struct bd71828_power {
135 struct regmap *regmap;
136 enum rohm_chip_type chip_type;
137 struct device *dev;
138 struct power_supply *ac;
139 struct power_supply *bat;
140
141 const struct pwr_regs *regs;
142 /* Reg val to uA */
143 int curr_factor;
144 int rsens;
145 int (*get_temp)(struct bd71828_power *pwr, int *temp);
146 int (*bat_inserted)(struct bd71828_power *pwr);
147 };
148
bd7182x_write16(struct bd71828_power * pwr,int reg,u16 val)149 static int bd7182x_write16(struct bd71828_power *pwr, int reg, u16 val)
150 {
151 __be16 tmp;
152
153 tmp = cpu_to_be16(val);
154
155 return regmap_bulk_write(pwr->regmap, reg, &tmp, sizeof(tmp));
156 }
157
bd7182x_read16_himask(struct bd71828_power * pwr,int reg,int himask,u16 * val)158 static int bd7182x_read16_himask(struct bd71828_power *pwr, int reg, int himask,
159 u16 *val)
160 {
161 struct regmap *regmap = pwr->regmap;
162 int ret;
163 __be16 rvals;
164 u8 *tmp = (u8 *)&rvals;
165
166 ret = regmap_bulk_read(regmap, reg, &rvals, sizeof(*val));
167 if (!ret) {
168 *tmp &= himask;
169 *val = be16_to_cpu(rvals);
170 }
171
172 return ret;
173 }
174
bd71828_get_vbat(struct bd71828_power * pwr,int * vcell)175 static int bd71828_get_vbat(struct bd71828_power *pwr, int *vcell)
176 {
177 u16 tmp_vcell;
178 int ret;
179
180 ret = bd7182x_read16_himask(pwr, pwr->regs->vbat_avg,
181 BD7182x_MASK_VBAT_U, &tmp_vcell);
182 if (ret)
183 dev_err(pwr->dev, "Failed to read battery average voltage\n");
184 else
185 *vcell = ((int)tmp_vcell) * 1000;
186
187 return ret;
188 }
189
bd71828_get_current_ds_adc(struct bd71828_power * pwr,int * curr,int * curr_avg)190 static int bd71828_get_current_ds_adc(struct bd71828_power *pwr, int *curr, int *curr_avg)
191 {
192 __be16 tmp_curr;
193 char *tmp = (char *)&tmp_curr;
194 int dir = 1;
195 int regs[] = { pwr->regs->ibat, pwr->regs->ibat_avg };
196 int *vals[] = { curr, curr_avg };
197 int ret, i;
198
199 for (dir = 1, i = 0; i < ARRAY_SIZE(regs); i++) {
200 ret = regmap_bulk_read(pwr->regmap, regs[i], &tmp_curr,
201 sizeof(tmp_curr));
202 if (ret)
203 break;
204
205 if (*tmp & BD7182x_MASK_CURDIR_DISCHG)
206 dir = -1;
207
208 *tmp &= BD7182x_MASK_IBAT_U;
209
210 *vals[i] = dir * ((int)be16_to_cpu(tmp_curr)) * pwr->curr_factor;
211 }
212
213 return ret;
214 }
215
216 /* Unit is tenths of degree C */
bd71815_get_temp(struct bd71828_power * pwr,int * temp)217 static int bd71815_get_temp(struct bd71828_power *pwr, int *temp)
218 {
219 struct regmap *regmap = pwr->regmap;
220 int ret;
221 int t;
222
223 ret = regmap_read(regmap, pwr->regs->btemp_vth, &t);
224 if (ret)
225 return ret;
226
227 t = 200 - t;
228
229 if (t > 200) {
230 dev_err(pwr->dev, "Failed to read battery temperature\n");
231 return -ENODATA;
232 }
233
234 return 0;
235 }
236
237 /* Unit is tenths of degree C */
bd71828_get_temp(struct bd71828_power * pwr,int * temp)238 static int bd71828_get_temp(struct bd71828_power *pwr, int *temp)
239 {
240 u16 t;
241 int ret;
242 int tmp = 200 * 10000;
243
244 ret = bd7182x_read16_himask(pwr, pwr->regs->btemp_vth,
245 BD71828_MASK_VM_BTMP_U, &t);
246 if (ret)
247 return ret;
248
249 if (t > 3200) {
250 dev_err(pwr->dev,
251 "Failed to read battery temperature\n");
252 return -ENODATA;
253 }
254
255 tmp -= 625ULL * (unsigned int)t;
256 *temp = tmp / 1000;
257
258 return ret;
259 }
260
bd71828_charge_status(struct bd71828_power * pwr,int * s,int * h)261 static int bd71828_charge_status(struct bd71828_power *pwr,
262 int *s, int *h)
263 {
264 unsigned int state;
265 int status, health;
266 int ret = 1;
267
268 ret = regmap_read(pwr->regmap, pwr->regs->chg_state, &state);
269 if (ret) {
270 dev_err(pwr->dev, "charger status reading failed (%d)\n", ret);
271 return ret;
272 }
273
274 state &= BD7182x_MASK_CHG_STATE;
275
276 dev_dbg(pwr->dev, "CHG_STATE %d\n", state);
277
278 switch (state) {
279 case 0x00:
280 status = POWER_SUPPLY_STATUS_DISCHARGING;
281 health = POWER_SUPPLY_HEALTH_GOOD;
282 break;
283 case 0x01:
284 case 0x02:
285 case 0x03:
286 case 0x0E:
287 status = POWER_SUPPLY_STATUS_CHARGING;
288 health = POWER_SUPPLY_HEALTH_GOOD;
289 break;
290 case 0x0F:
291 status = POWER_SUPPLY_STATUS_FULL;
292 health = POWER_SUPPLY_HEALTH_GOOD;
293 break;
294 case 0x10:
295 case 0x11:
296 case 0x12:
297 case 0x13:
298 case 0x14:
299 case 0x20:
300 case 0x21:
301 case 0x22:
302 case 0x23:
303 case 0x24:
304 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
305 health = POWER_SUPPLY_HEALTH_OVERHEAT;
306 break;
307 case 0x30:
308 case 0x31:
309 case 0x32:
310 case 0x40:
311 status = POWER_SUPPLY_STATUS_DISCHARGING;
312 health = POWER_SUPPLY_HEALTH_GOOD;
313 break;
314 case 0x7f:
315 default:
316 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
317 health = POWER_SUPPLY_HEALTH_DEAD;
318 break;
319 }
320
321 if (s)
322 *s = status;
323 if (h)
324 *h = health;
325
326 return ret;
327 }
328
get_chg_online(struct bd71828_power * pwr,int * chg_online)329 static int get_chg_online(struct bd71828_power *pwr, int *chg_online)
330 {
331 int r, ret;
332
333 ret = regmap_read(pwr->regmap, pwr->regs->dcin_stat, &r);
334 if (ret) {
335 dev_err(pwr->dev, "Failed to read DCIN status\n");
336 return ret;
337 }
338 *chg_online = ((r & pwr->regs->dcin_online_mask) != 0);
339
340 return 0;
341 }
342
get_bat_online(struct bd71828_power * pwr,int * bat_online)343 static int get_bat_online(struct bd71828_power *pwr, int *bat_online)
344 {
345 int r, ret;
346
347 ret = regmap_read(pwr->regmap, pwr->regs->bat_temp, &r);
348 if (ret) {
349 dev_err(pwr->dev, "Failed to read battery temperature\n");
350 return ret;
351 }
352 *bat_online = ((r & BD7182x_MASK_BAT_TEMP) != BAT_OPEN);
353
354 return 0;
355 }
356
bd71828_bat_inserted(struct bd71828_power * pwr)357 static int bd71828_bat_inserted(struct bd71828_power *pwr)
358 {
359 int ret, val;
360
361 ret = regmap_read(pwr->regmap, pwr->regs->conf, &val);
362 if (ret) {
363 dev_err(pwr->dev, "Failed to read CONF register\n");
364 return 0;
365 }
366 ret = val & BD7182x_MASK_CONF_PON;
367
368 if (ret)
369 if (regmap_update_bits(pwr->regmap, pwr->regs->conf, BD7182x_MASK_CONF_PON, 0))
370 dev_err(pwr->dev, "Failed to write CONF register\n");
371
372 return ret;
373 }
374
bd71815_bat_inserted(struct bd71828_power * pwr)375 static int bd71815_bat_inserted(struct bd71828_power *pwr)
376 {
377 int ret, val;
378
379 ret = regmap_read(pwr->regmap, pwr->regs->conf, &val);
380 if (ret) {
381 dev_err(pwr->dev, "Failed to read CONF register\n");
382 return ret;
383 }
384
385 ret = !(val & BD71815_MASK_CONF_XSTB);
386 if (ret)
387 regmap_write(pwr->regmap, pwr->regs->conf, val |
388 BD71815_MASK_CONF_XSTB);
389
390 return ret;
391 }
392
bd71828_init_hardware(struct bd71828_power * pwr)393 static int bd71828_init_hardware(struct bd71828_power *pwr)
394 {
395 int ret;
396
397 /* TODO: Collapse limit should come from device-tree ? */
398 if (pwr->regs->dcin_collapse_limit != (unsigned int)-1) {
399 ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit,
400 BD7182x_DCIN_COLLAPSE_DEFAULT);
401 if (ret) {
402 dev_err(pwr->dev, "Failed to write DCIN collapse limit\n");
403 return ret;
404 }
405 }
406
407 ret = pwr->bat_inserted(pwr);
408 if (ret < 0)
409 return ret;
410
411 if (ret) {
412 /* WDT_FST auto set */
413 ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_set1,
414 BD7182x_MASK_WDT_AUTO,
415 BD7182x_MASK_WDT_AUTO);
416 if (ret)
417 return ret;
418
419 ret = bd7182x_write16(pwr, pwr->regs->vbat_alm_limit_u,
420 VBAT_LOW_TH);
421 if (ret)
422 return ret;
423
424 /*
425 * On BD71815 "we mask the power-state" from relax detection.
426 * I am unsure what the impact of the power-state would be if
427 * we didn't - but this is what the vendor driver did - and
428 * that driver has been used in few projects so I just assume
429 * this is needed.
430 */
431 if (pwr->chip_type == ROHM_CHIP_TYPE_BD71815) {
432 ret = regmap_set_bits(pwr->regmap,
433 BD71815_REG_REX_CTRL_1,
434 REX_PMU_STATE_MASK);
435 if (ret)
436 return ret;
437 }
438 }
439
440 return 0;
441 }
442
bd71828_charger_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)443 static int bd71828_charger_get_property(struct power_supply *psy,
444 enum power_supply_property psp,
445 union power_supply_propval *val)
446 {
447 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
448 u32 vot;
449 u16 tmp;
450 int t;
451 int online;
452 int ret;
453
454 switch (psp) {
455 case POWER_SUPPLY_PROP_ONLINE:
456 ret = get_chg_online(pwr, &online);
457 if (!ret)
458 val->intval = online;
459 break;
460 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
461 ret = bd7182x_read16_himask(pwr, pwr->regs->vdcin,
462 pwr->regs->vdcin_himask, &tmp);
463 if (ret)
464 return ret;
465
466 vot = tmp;
467 /* 5 milli volt steps */
468 val->intval = 5000 * vot;
469 break;
470 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
471 if (!pwr->regs->ilim_stat)
472 return -ENODATA;
473
474 ret = regmap_read(pwr->regmap, pwr->regs->ilim_stat, &t);
475 if (ret)
476 return ret;
477
478 t++;
479 val->intval = (t & BD7182x_MASK_ILIM) * 50000;
480 if (val->intval > 2000000)
481 val->intval = 2000000;
482
483 break;
484 default:
485 return -EINVAL;
486 }
487
488 return 0;
489 }
490
bd71828_charger_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)491 static int bd71828_charger_set_property(struct power_supply *psy,
492 enum power_supply_property psp,
493 const union power_supply_propval *val)
494 {
495 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
496
497 switch (psp) {
498 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
499 if (val->intval > 2000000)
500 return -EINVAL;
501
502 if (val->intval < 50000)
503 return -EINVAL;
504
505 if (!pwr->regs->dcin_set)
506 return -EINVAL;
507
508 return regmap_update_bits(pwr->regmap, pwr->regs->dcin_set,
509 BD7182x_MASK_ILIM,
510 val->intval / 50000 - 1);
511 break;
512 default:
513 return -EINVAL;
514 }
515 }
516
bd71828_charger_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)517 static int bd71828_charger_property_is_writeable(struct power_supply *psy,
518 enum power_supply_property psp)
519 {
520 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
521
522 switch (psp) {
523 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
524 return !!(pwr->regs->dcin_set);
525 default:
526 return false;
527 }
528 }
529
bd71828_battery_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)530 static int bd71828_battery_get_property(struct power_supply *psy,
531 enum power_supply_property psp,
532 union power_supply_propval *val)
533 {
534 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
535 int ret = 0;
536 int status, health, tmp, curr, curr_avg, chg_en;
537
538 if (psp == POWER_SUPPLY_PROP_STATUS ||
539 psp == POWER_SUPPLY_PROP_HEALTH ||
540 psp == POWER_SUPPLY_PROP_CHARGE_TYPE)
541 ret = bd71828_charge_status(pwr, &status, &health);
542 else if (psp == POWER_SUPPLY_PROP_CURRENT_AVG ||
543 psp == POWER_SUPPLY_PROP_CURRENT_NOW)
544 ret = bd71828_get_current_ds_adc(pwr, &curr, &curr_avg);
545 if (ret)
546 return ret;
547
548 switch (psp) {
549 case POWER_SUPPLY_PROP_STATUS:
550 val->intval = status;
551 break;
552 case POWER_SUPPLY_PROP_HEALTH:
553 val->intval = health;
554 break;
555 case POWER_SUPPLY_PROP_PRESENT:
556 ret = get_bat_online(pwr, &tmp);
557 if (!ret)
558 val->intval = tmp;
559 break;
560 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
561 ret = bd71828_get_vbat(pwr, &tmp);
562 val->intval = tmp;
563 break;
564 case POWER_SUPPLY_PROP_TECHNOLOGY:
565 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
566 break;
567 case POWER_SUPPLY_PROP_CURRENT_AVG:
568 val->intval = curr_avg;
569 break;
570 case POWER_SUPPLY_PROP_CURRENT_NOW:
571 val->intval = curr;
572 break;
573 case POWER_SUPPLY_PROP_CURRENT_MAX:
574 val->intval = MAX_CURRENT_DEFAULT;
575 break;
576 case POWER_SUPPLY_PROP_TEMP:
577 ret = pwr->get_temp(pwr, &val->intval);
578 break;
579 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
580 ret = regmap_read(pwr->regmap, pwr->regs->chg_en, &chg_en);
581 if (ret)
582 return ret;
583
584 val->intval = (chg_en & BD7182x_MASK_CHG_EN) ?
585 POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO :
586 POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
587 break;
588 default:
589 ret = -EINVAL;
590 break;
591 }
592
593 return ret;
594 }
595
bd71828_battery_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)596 static int bd71828_battery_set_property(struct power_supply *psy,
597 enum power_supply_property psp,
598 const union power_supply_propval *val)
599 {
600 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
601 int ret = 0;
602
603 switch (psp) {
604 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
605 if (val->intval == POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO)
606 ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en,
607 BD7182x_MASK_CHG_EN,
608 BD7182x_MASK_CHG_EN);
609 else
610 ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en,
611 BD7182x_MASK_CHG_EN,
612 0);
613 break;
614 default:
615 return -EINVAL;
616 }
617
618 return ret;
619 }
620
bd71828_battery_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)621 static int bd71828_battery_property_is_writeable(struct power_supply *psy,
622 enum power_supply_property psp)
623 {
624 switch (psp) {
625 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
626 return true;
627 default:
628 return false;
629 }
630 }
631
632 /** @brief ac properties */
633 static const enum power_supply_property bd71828_charger_props[] = {
634 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
635 POWER_SUPPLY_PROP_ONLINE,
636 POWER_SUPPLY_PROP_VOLTAGE_NOW,
637 };
638
639 static const enum power_supply_property bd71828_battery_props[] = {
640 POWER_SUPPLY_PROP_STATUS,
641 POWER_SUPPLY_PROP_HEALTH,
642 POWER_SUPPLY_PROP_VOLTAGE_NOW,
643 POWER_SUPPLY_PROP_HEALTH,
644 POWER_SUPPLY_PROP_PRESENT,
645 POWER_SUPPLY_PROP_TECHNOLOGY,
646 POWER_SUPPLY_PROP_TEMP,
647 POWER_SUPPLY_PROP_CURRENT_AVG,
648 POWER_SUPPLY_PROP_CURRENT_NOW,
649 POWER_SUPPLY_PROP_CURRENT_MAX,
650 POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
651 };
652
653 /** @brief powers supplied by bd71828_ac */
654 static char *bd71828_ac_supplied_to[] = {
655 BAT_NAME,
656 };
657
658 static const struct power_supply_desc bd71828_ac_desc = {
659 .name = AC_NAME,
660 .type = POWER_SUPPLY_TYPE_MAINS,
661 .properties = bd71828_charger_props,
662 .num_properties = ARRAY_SIZE(bd71828_charger_props),
663 .get_property = bd71828_charger_get_property,
664 .set_property = bd71828_charger_set_property,
665 .property_is_writeable = bd71828_charger_property_is_writeable,
666 };
667
668 static const struct power_supply_desc bd71828_bat_desc = {
669 .name = BAT_NAME,
670 .type = POWER_SUPPLY_TYPE_BATTERY,
671 .charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) |
672 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE),
673 .properties = bd71828_battery_props,
674 .num_properties = ARRAY_SIZE(bd71828_battery_props),
675 .get_property = bd71828_battery_get_property,
676 .set_property = bd71828_battery_set_property,
677 .property_is_writeable = bd71828_battery_property_is_writeable,
678 };
679
680 #define RSENS_CURR 10000000LLU
681
682 #define BD_ISR_NAME(name) \
683 bd7181x_##name##_isr
684
685 #define BD_ISR_BAT(name, print, run_gauge) \
686 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data) \
687 { \
688 struct bd71828_power *pwr = (struct bd71828_power *)data; \
689 \
690 dev_dbg(pwr->dev, "%s\n", print); \
691 power_supply_changed(pwr->bat); \
692 \
693 return IRQ_HANDLED; \
694 }
695
696 #define BD_ISR_AC(name, print, run_gauge) \
697 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data) \
698 { \
699 struct bd71828_power *pwr = (struct bd71828_power *)data; \
700 \
701 power_supply_changed(pwr->ac); \
702 dev_dbg(pwr->dev, "%s\n", print); \
703 power_supply_changed(pwr->bat); \
704 \
705 return IRQ_HANDLED; \
706 }
707
708 #define BD_ISR_DUMMY(name, print) \
709 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data) \
710 { \
711 struct bd71828_power *pwr = (struct bd71828_power *)data; \
712 \
713 dev_dbg(pwr->dev, "%s\n", print); \
714 \
715 return IRQ_HANDLED; \
716 }
717
718 BD_ISR_BAT(chg_state_changed, "CHG state changed", true)
719 /* DCIN voltage changes */
720 BD_ISR_AC(dcin_removed, "DCIN removed", true)
721 BD_ISR_AC(clps_out, "DCIN voltage back to normal", true)
722 BD_ISR_AC(clps_in, "DCIN voltage collapsed", false)
723 BD_ISR_AC(dcin_ovp_res, "DCIN voltage normal", true)
724 BD_ISR_AC(dcin_ovp_det, "DCIN OVER VOLTAGE", true)
725
726 BD_ISR_DUMMY(dcin_mon_det, "DCIN voltage below threshold")
727 BD_ISR_DUMMY(dcin_mon_res, "DCIN voltage above threshold")
728
729 BD_ISR_DUMMY(vbus_curr_limit, "VBUS current limited")
730 BD_ISR_DUMMY(vsys_ov_res, "VSYS over-voltage cleared")
731 BD_ISR_DUMMY(vsys_ov_det, "VSYS over-voltage")
732 BD_ISR_DUMMY(vsys_uv_res, "VSYS under-voltage cleared")
733 BD_ISR_DUMMY(vsys_uv_det, "VSYS under-voltage")
734 BD_ISR_DUMMY(vsys_low_res, "'VSYS low' cleared")
735 BD_ISR_DUMMY(vsys_low_det, "VSYS low")
736 BD_ISR_DUMMY(vsys_mon_res, "VSYS mon - resumed")
737 BD_ISR_DUMMY(vsys_mon_det, "VSYS mon - detected")
738 BD_ISR_BAT(chg_wdg_temp, "charger temperature watchdog triggered", true)
739 BD_ISR_BAT(chg_wdg, "charging watchdog triggered", true)
740 BD_ISR_BAT(bat_removed, "Battery removed", true)
741 BD_ISR_BAT(bat_det, "Battery detected", true)
742 /* TODO: Verify the meaning of these interrupts */
743 BD_ISR_BAT(rechg_det, "Recharging", true)
744 BD_ISR_BAT(rechg_res, "Recharge ending", true)
745 BD_ISR_DUMMY(temp_transit, "Temperature transition")
746 BD_ISR_BAT(therm_rmv, "bd71815-therm-rmv", false)
747 BD_ISR_BAT(therm_det, "bd71815-therm-det", true)
748 BD_ISR_BAT(bat_dead, "bd71815-bat-dead", false)
749 BD_ISR_BAT(bat_short_res, "bd71815-bat-short-res", true)
750 BD_ISR_BAT(bat_short, "bd71815-bat-short-det", false)
751 BD_ISR_BAT(bat_low_res, "bd71815-bat-low-res", true)
752 BD_ISR_BAT(bat_low, "bd71815-bat-low-det", true)
753 BD_ISR_BAT(bat_ov_res, "bd71815-bat-over-res", true)
754 /* What should we do here? */
755 BD_ISR_BAT(bat_ov, "bd71815-bat-over-det", false)
756 BD_ISR_BAT(bat_mon_res, "bd71815-bat-mon-res", true)
757 BD_ISR_BAT(bat_mon, "bd71815-bat-mon-det", true)
758 BD_ISR_BAT(bat_cc_mon, "bd71815-bat-cc-mon2", false)
759 BD_ISR_BAT(bat_oc1_res, "bd71815-bat-oc1-res", true)
760 BD_ISR_BAT(bat_oc1, "bd71815-bat-oc1-det", false)
761 BD_ISR_BAT(bat_oc2_res, "bd71815-bat-oc2-res", true)
762 BD_ISR_BAT(bat_oc2, "bd71815-bat-oc2-det", false)
763 BD_ISR_BAT(bat_oc3_res, "bd71815-bat-oc3-res", true)
764 BD_ISR_BAT(bat_oc3, "bd71815-bat-oc3-det", false)
765 BD_ISR_BAT(temp_bat_low_res, "bd71815-temp-bat-low-res", true)
766 BD_ISR_BAT(temp_bat_low, "bd71815-temp-bat-low-det", true)
767 BD_ISR_BAT(temp_bat_hi_res, "bd71815-temp-bat-hi-res", true)
768 BD_ISR_BAT(temp_bat_hi, "bd71815-temp-bat-hi-det", true)
769
bd7182x_dcin_removed(int irq,void * data)770 static irqreturn_t bd7182x_dcin_removed(int irq, void *data)
771 {
772 struct bd71828_power *pwr = (struct bd71828_power *)data;
773
774 power_supply_changed(pwr->ac);
775 dev_dbg(pwr->dev, "DCIN removed\n");
776
777 return IRQ_HANDLED;
778 }
779
bd718x7_chg_done(int irq,void * data)780 static irqreturn_t bd718x7_chg_done(int irq, void *data)
781 {
782 struct bd71828_power *pwr = (struct bd71828_power *)data;
783
784 power_supply_changed(pwr->bat);
785
786 return IRQ_HANDLED;
787 }
788
bd7182x_dcin_detected(int irq,void * data)789 static irqreturn_t bd7182x_dcin_detected(int irq, void *data)
790 {
791 struct bd71828_power *pwr = (struct bd71828_power *)data;
792
793 dev_dbg(pwr->dev, "DCIN inserted\n");
794 power_supply_changed(pwr->ac);
795
796 return IRQ_HANDLED;
797 }
798
bd71828_vbat_low_res(int irq,void * data)799 static irqreturn_t bd71828_vbat_low_res(int irq, void *data)
800 {
801 struct bd71828_power *pwr = (struct bd71828_power *)data;
802
803 dev_dbg(pwr->dev, "VBAT LOW Resumed\n");
804
805 return IRQ_HANDLED;
806 }
807
bd71828_vbat_low_det(int irq,void * data)808 static irqreturn_t bd71828_vbat_low_det(int irq, void *data)
809 {
810 struct bd71828_power *pwr = (struct bd71828_power *)data;
811
812 dev_dbg(pwr->dev, "VBAT LOW Detected\n");
813
814 return IRQ_HANDLED;
815 }
816
bd71828_temp_bat_hi_det(int irq,void * data)817 static irqreturn_t bd71828_temp_bat_hi_det(int irq, void *data)
818 {
819 struct bd71828_power *pwr = (struct bd71828_power *)data;
820
821 dev_warn(pwr->dev, "Overtemp Detected\n");
822 power_supply_changed(pwr->bat);
823
824 return IRQ_HANDLED;
825 }
826
bd71828_temp_bat_hi_res(int irq,void * data)827 static irqreturn_t bd71828_temp_bat_hi_res(int irq, void *data)
828 {
829 struct bd71828_power *pwr = (struct bd71828_power *)data;
830
831 dev_dbg(pwr->dev, "Overtemp Resumed\n");
832 power_supply_changed(pwr->bat);
833
834 return IRQ_HANDLED;
835 }
836
bd71828_temp_bat_low_det(int irq,void * data)837 static irqreturn_t bd71828_temp_bat_low_det(int irq, void *data)
838 {
839 struct bd71828_power *pwr = (struct bd71828_power *)data;
840
841 dev_dbg(pwr->dev, "Lowtemp Detected\n");
842 power_supply_changed(pwr->bat);
843
844 return IRQ_HANDLED;
845 }
846
bd71828_temp_bat_low_res(int irq,void * data)847 static irqreturn_t bd71828_temp_bat_low_res(int irq, void *data)
848 {
849 struct bd71828_power *pwr = (struct bd71828_power *)data;
850
851 dev_dbg(pwr->dev, "Lowtemp Resumed\n");
852 power_supply_changed(pwr->bat);
853
854 return IRQ_HANDLED;
855 }
856
bd71828_temp_vf_det(int irq,void * data)857 static irqreturn_t bd71828_temp_vf_det(int irq, void *data)
858 {
859 struct bd71828_power *pwr = (struct bd71828_power *)data;
860
861 dev_dbg(pwr->dev, "VF Detected\n");
862 power_supply_changed(pwr->bat);
863
864 return IRQ_HANDLED;
865 }
866
bd71828_temp_vf_res(int irq,void * data)867 static irqreturn_t bd71828_temp_vf_res(int irq, void *data)
868 {
869 struct bd71828_power *pwr = (struct bd71828_power *)data;
870
871 dev_dbg(pwr->dev, "VF Resumed\n");
872 power_supply_changed(pwr->bat);
873
874 return IRQ_HANDLED;
875 }
876
bd71828_temp_vf125_det(int irq,void * data)877 static irqreturn_t bd71828_temp_vf125_det(int irq, void *data)
878 {
879 struct bd71828_power *pwr = (struct bd71828_power *)data;
880
881 dev_dbg(pwr->dev, "VF125 Detected\n");
882 power_supply_changed(pwr->bat);
883
884 return IRQ_HANDLED;
885 }
886
bd71828_temp_vf125_res(int irq,void * data)887 static irqreturn_t bd71828_temp_vf125_res(int irq, void *data)
888 {
889 struct bd71828_power *pwr = (struct bd71828_power *)data;
890
891 dev_dbg(pwr->dev, "VF125 Resumed\n");
892 power_supply_changed(pwr->bat);
893
894 return IRQ_HANDLED;
895 }
896
897 struct bd7182x_irq_res {
898 const char *name;
899 irq_handler_t handler;
900 };
901
902 #define BDIRQ(na, hn) { .name = (na), .handler = (hn) }
903
bd7182x_get_irqs(struct platform_device * pdev,struct bd71828_power * pwr)904 static int bd7182x_get_irqs(struct platform_device *pdev,
905 struct bd71828_power *pwr)
906 {
907 int i, irq, ret;
908 static const struct bd7182x_irq_res bd71815_irqs[] = {
909 BDIRQ("bd71815-dcin-rmv", BD_ISR_NAME(dcin_removed)),
910 BDIRQ("bd71815-dcin-clps-out", BD_ISR_NAME(clps_out)),
911 BDIRQ("bd71815-dcin-clps-in", BD_ISR_NAME(clps_in)),
912 BDIRQ("bd71815-dcin-ovp-res", BD_ISR_NAME(dcin_ovp_res)),
913 BDIRQ("bd71815-dcin-ovp-det", BD_ISR_NAME(dcin_ovp_det)),
914 BDIRQ("bd71815-dcin-mon-res", BD_ISR_NAME(dcin_mon_res)),
915 BDIRQ("bd71815-dcin-mon-det", BD_ISR_NAME(dcin_mon_det)),
916
917 BDIRQ("bd71815-vsys-uv-res", BD_ISR_NAME(vsys_uv_res)),
918 BDIRQ("bd71815-vsys-uv-det", BD_ISR_NAME(vsys_uv_det)),
919 BDIRQ("bd71815-vsys-low-res", BD_ISR_NAME(vsys_low_res)),
920 BDIRQ("bd71815-vsys-low-det", BD_ISR_NAME(vsys_low_det)),
921 BDIRQ("bd71815-vsys-mon-res", BD_ISR_NAME(vsys_mon_res)),
922 BDIRQ("bd71815-vsys-mon-det", BD_ISR_NAME(vsys_mon_det)),
923 BDIRQ("bd71815-chg-wdg-temp", BD_ISR_NAME(chg_wdg_temp)),
924 BDIRQ("bd71815-chg-wdg", BD_ISR_NAME(chg_wdg)),
925 BDIRQ("bd71815-rechg-det", BD_ISR_NAME(rechg_det)),
926 BDIRQ("bd71815-rechg-res", BD_ISR_NAME(rechg_res)),
927 BDIRQ("bd71815-ranged-temp-transit", BD_ISR_NAME(temp_transit)),
928 BDIRQ("bd71815-chg-state-change", BD_ISR_NAME(chg_state_changed)),
929 BDIRQ("bd71815-bat-temp-normal", bd71828_temp_bat_hi_res),
930 BDIRQ("bd71815-bat-temp-erange", bd71828_temp_bat_hi_det),
931 BDIRQ("bd71815-bat-rmv", BD_ISR_NAME(bat_removed)),
932 BDIRQ("bd71815-bat-det", BD_ISR_NAME(bat_det)),
933
934 /* Add ISRs for these */
935 BDIRQ("bd71815-therm-rmv", BD_ISR_NAME(therm_rmv)),
936 BDIRQ("bd71815-therm-det", BD_ISR_NAME(therm_det)),
937 BDIRQ("bd71815-bat-dead", BD_ISR_NAME(bat_dead)),
938 BDIRQ("bd71815-bat-short-res", BD_ISR_NAME(bat_short_res)),
939 BDIRQ("bd71815-bat-short-det", BD_ISR_NAME(bat_short)),
940 BDIRQ("bd71815-bat-low-res", BD_ISR_NAME(bat_low_res)),
941 BDIRQ("bd71815-bat-low-det", BD_ISR_NAME(bat_low)),
942 BDIRQ("bd71815-bat-over-res", BD_ISR_NAME(bat_ov_res)),
943 BDIRQ("bd71815-bat-over-det", BD_ISR_NAME(bat_ov)),
944 BDIRQ("bd71815-bat-mon-res", BD_ISR_NAME(bat_mon_res)),
945 BDIRQ("bd71815-bat-mon-det", BD_ISR_NAME(bat_mon)),
946 /* cc-mon 1 & 3 ? */
947 BDIRQ("bd71815-bat-cc-mon2", BD_ISR_NAME(bat_cc_mon)),
948 BDIRQ("bd71815-bat-oc1-res", BD_ISR_NAME(bat_oc1_res)),
949 BDIRQ("bd71815-bat-oc1-det", BD_ISR_NAME(bat_oc1)),
950 BDIRQ("bd71815-bat-oc2-res", BD_ISR_NAME(bat_oc2_res)),
951 BDIRQ("bd71815-bat-oc2-det", BD_ISR_NAME(bat_oc2)),
952 BDIRQ("bd71815-bat-oc3-res", BD_ISR_NAME(bat_oc3_res)),
953 BDIRQ("bd71815-bat-oc3-det", BD_ISR_NAME(bat_oc3)),
954 BDIRQ("bd71815-temp-bat-low-res", BD_ISR_NAME(temp_bat_low_res)),
955 BDIRQ("bd71815-temp-bat-low-det", BD_ISR_NAME(temp_bat_low)),
956 BDIRQ("bd71815-temp-bat-hi-res", BD_ISR_NAME(temp_bat_hi_res)),
957 BDIRQ("bd71815-temp-bat-hi-det", BD_ISR_NAME(temp_bat_hi)),
958 /*
959 * TODO: add rest of the IRQs and re-check the handling.
960 * Check the bd71815-bat-cc-mon1, bd71815-bat-cc-mon3,
961 * bd71815-bat-low-res, bd71815-bat-low-det,
962 * bd71815-bat-hi-res, bd71815-bat-hi-det.
963 */
964 };
965 static const struct bd7182x_irq_res bd71828_irqs[] = {
966 BDIRQ("bd71828-chg-done", bd718x7_chg_done),
967 BDIRQ("bd71828-pwr-dcin-in", bd7182x_dcin_detected),
968 BDIRQ("bd71828-pwr-dcin-out", bd7182x_dcin_removed),
969 BDIRQ("bd71828-vbat-normal", bd71828_vbat_low_res),
970 BDIRQ("bd71828-vbat-low", bd71828_vbat_low_det),
971 BDIRQ("bd71828-btemp-hi", bd71828_temp_bat_hi_det),
972 BDIRQ("bd71828-btemp-cool", bd71828_temp_bat_hi_res),
973 BDIRQ("bd71828-btemp-lo", bd71828_temp_bat_low_det),
974 BDIRQ("bd71828-btemp-warm", bd71828_temp_bat_low_res),
975 BDIRQ("bd71828-temp-hi", bd71828_temp_vf_det),
976 BDIRQ("bd71828-temp-norm", bd71828_temp_vf_res),
977 BDIRQ("bd71828-temp-125-over", bd71828_temp_vf125_det),
978 BDIRQ("bd71828-temp-125-under", bd71828_temp_vf125_res),
979 };
980 static const struct bd7182x_irq_res bd72720_irqs[] = {
981 BDIRQ("bd72720_int_vbus_rmv", BD_ISR_NAME(dcin_removed)),
982 BDIRQ("bd72720_int_vbus_det", bd7182x_dcin_detected),
983 BDIRQ("bd72720_int_vbus_mon_res", BD_ISR_NAME(dcin_mon_res)),
984 BDIRQ("bd72720_int_vbus_mon_det", BD_ISR_NAME(dcin_mon_det)),
985 BDIRQ("bd72720_int_vsys_mon_res", BD_ISR_NAME(vsys_mon_res)),
986 BDIRQ("bd72720_int_vsys_mon_det", BD_ISR_NAME(vsys_mon_det)),
987 BDIRQ("bd72720_int_vsys_uv_res", BD_ISR_NAME(vsys_uv_res)),
988 BDIRQ("bd72720_int_vsys_uv_det", BD_ISR_NAME(vsys_uv_det)),
989 BDIRQ("bd72720_int_vsys_lo_res", BD_ISR_NAME(vsys_low_res)),
990 BDIRQ("bd72720_int_vsys_lo_det", BD_ISR_NAME(vsys_low_det)),
991 BDIRQ("bd72720_int_vsys_ov_res", BD_ISR_NAME(vsys_ov_res)),
992 BDIRQ("bd72720_int_vsys_ov_det", BD_ISR_NAME(vsys_ov_det)),
993 BDIRQ("bd72720_int_bat_ilim", BD_ISR_NAME(vbus_curr_limit)),
994 BDIRQ("bd72720_int_chg_done", bd718x7_chg_done),
995 BDIRQ("bd72720_int_extemp_tout", BD_ISR_NAME(chg_wdg_temp)),
996 BDIRQ("bd72720_int_chg_wdt_exp", BD_ISR_NAME(chg_wdg)),
997 BDIRQ("bd72720_int_bat_mnt_out", BD_ISR_NAME(rechg_res)),
998 BDIRQ("bd72720_int_bat_mnt_in", BD_ISR_NAME(rechg_det)),
999 BDIRQ("bd72720_int_chg_trns", BD_ISR_NAME(chg_state_changed)),
1000
1001 BDIRQ("bd72720_int_vbat_mon_res", BD_ISR_NAME(bat_mon_res)),
1002 BDIRQ("bd72720_int_vbat_mon_det", BD_ISR_NAME(bat_mon)),
1003 BDIRQ("bd72720_int_vbat_sht_res", BD_ISR_NAME(bat_short_res)),
1004 BDIRQ("bd72720_int_vbat_sht_det", BD_ISR_NAME(bat_short)),
1005 BDIRQ("bd72720_int_vbat_lo_res", BD_ISR_NAME(bat_low_res)),
1006 BDIRQ("bd72720_int_vbat_lo_det", BD_ISR_NAME(bat_low)),
1007 BDIRQ("bd72720_int_vbat_ov_res", BD_ISR_NAME(bat_ov_res)),
1008 BDIRQ("bd72720_int_vbat_ov_det", BD_ISR_NAME(bat_ov)),
1009 BDIRQ("bd72720_int_bat_rmv", BD_ISR_NAME(bat_removed)),
1010 BDIRQ("bd72720_int_bat_det", BD_ISR_NAME(bat_det)),
1011 BDIRQ("bd72720_int_dbat_det", BD_ISR_NAME(bat_dead)),
1012 BDIRQ("bd72720_int_bat_temp_trns", BD_ISR_NAME(temp_transit)),
1013 BDIRQ("bd72720_int_lobtmp_res", BD_ISR_NAME(temp_bat_low_res)),
1014 BDIRQ("bd72720_int_lobtmp_det", BD_ISR_NAME(temp_bat_low)),
1015 BDIRQ("bd72720_int_ovbtmp_res", BD_ISR_NAME(temp_bat_hi_res)),
1016 BDIRQ("bd72720_int_ovbtmp_det", BD_ISR_NAME(temp_bat_hi)),
1017 BDIRQ("bd72720_int_ocur1_res", BD_ISR_NAME(bat_oc1_res)),
1018 BDIRQ("bd72720_int_ocur1_det", BD_ISR_NAME(bat_oc1)),
1019 BDIRQ("bd72720_int_ocur2_res", BD_ISR_NAME(bat_oc2_res)),
1020 BDIRQ("bd72720_int_ocur2_det", BD_ISR_NAME(bat_oc2)),
1021 BDIRQ("bd72720_int_ocur3_res", BD_ISR_NAME(bat_oc3_res)),
1022 BDIRQ("bd72720_int_ocur3_det", BD_ISR_NAME(bat_oc3)),
1023 BDIRQ("bd72720_int_cc_mon2_det", BD_ISR_NAME(bat_cc_mon)),
1024 };
1025 int num_irqs;
1026 const struct bd7182x_irq_res *irqs;
1027
1028 switch (pwr->chip_type) {
1029 case ROHM_CHIP_TYPE_BD71828:
1030 irqs = &bd71828_irqs[0];
1031 num_irqs = ARRAY_SIZE(bd71828_irqs);
1032 break;
1033 case ROHM_CHIP_TYPE_BD71815:
1034 irqs = &bd71815_irqs[0];
1035 num_irqs = ARRAY_SIZE(bd71815_irqs);
1036 break;
1037 case ROHM_CHIP_TYPE_BD72720:
1038 irqs = &bd72720_irqs[0];
1039 num_irqs = ARRAY_SIZE(bd72720_irqs);
1040 break;
1041 default:
1042 return -EINVAL;
1043 }
1044
1045 for (i = 0; i < num_irqs; i++) {
1046 irq = platform_get_irq_byname(pdev, irqs[i].name);
1047
1048 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1049 irqs[i].handler, 0,
1050 irqs[i].name, pwr);
1051 if (ret)
1052 break;
1053 }
1054
1055 return ret;
1056 }
1057
1058 #define RSENS_DEFAULT_30MOHM 30000 /* 30 mOhm in uOhms*/
1059
bd7182x_get_rsens(struct bd71828_power * pwr)1060 static int bd7182x_get_rsens(struct bd71828_power *pwr)
1061 {
1062 u64 tmp = RSENS_CURR;
1063 int rsens_ohm = RSENS_DEFAULT_30MOHM;
1064 struct fwnode_handle *node = NULL;
1065
1066 if (pwr->dev->parent)
1067 node = dev_fwnode(pwr->dev->parent);
1068
1069 if (node) {
1070 int ret;
1071 u32 rs;
1072
1073 ret = fwnode_property_read_u32(node,
1074 "rohm,charger-sense-resistor-micro-ohms",
1075 &rs);
1076 if (ret) {
1077 if (ret == -EINVAL) {
1078 rs = RSENS_DEFAULT_30MOHM;
1079 } else {
1080 dev_err(pwr->dev, "Bad RSENS dt property\n");
1081 return ret;
1082 }
1083 }
1084 if (!rs) {
1085 dev_err(pwr->dev, "Bad RSENS value\n");
1086 return -EINVAL;
1087 }
1088
1089 rsens_ohm = (int)rs;
1090 }
1091
1092 /* Reg val to uA */
1093 do_div(tmp, rsens_ohm);
1094
1095 pwr->curr_factor = tmp;
1096 pwr->rsens = rsens_ohm;
1097 dev_dbg(pwr->dev, "Setting rsens to %u micro ohm\n", pwr->rsens);
1098 dev_dbg(pwr->dev, "Setting curr-factor to %u\n", pwr->curr_factor);
1099
1100 return 0;
1101 }
1102
auto_dcin_limit_show(struct device * dev,struct device_attribute * attr,char * buf)1103 static ssize_t auto_dcin_limit_show(struct device *dev,
1104 struct device_attribute *attr,
1105 char *buf)
1106 {
1107 struct bd71828_power *pwr = dev_get_drvdata(dev->parent);
1108 int ret;
1109 unsigned int v;
1110
1111 ret = regmap_read(pwr->regmap, pwr->regs->dcin_set, &v);
1112 if (ret)
1113 return ret;
1114
1115 return sysfs_emit(buf, "%d\n", !!(v & BD71828_MASK_ILIM_DCIN_EN));
1116 }
1117
auto_dcin_limit_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)1118 static ssize_t auto_dcin_limit_store(struct device *dev,
1119 struct device_attribute *attr,
1120 const char *buf, size_t len)
1121 {
1122 struct bd71828_power *pwr = dev_get_drvdata(dev->parent);
1123 int ret;
1124 bool v;
1125
1126 ret = kstrtobool(buf, &v);
1127 if (ret < 0)
1128 return ret;
1129
1130 ret = regmap_update_bits(pwr->regmap, BD71828_REG_DCIN_SET,
1131 BD71828_MASK_ILIM_DCIN_EN,
1132 v ? BD71828_MASK_ILIM_DCIN_EN : 0);
1133 if (ret < 0)
1134 return ret;
1135
1136 return len;
1137 }
1138
1139 static DEVICE_ATTR_RW(auto_dcin_limit);
1140
1141 static struct attribute *bd71828_ac_sysfs_attrs[] = {
1142 &dev_attr_auto_dcin_limit.attr,
1143 NULL,
1144 };
1145
bd71828_ac_sysfs_group_visible(struct kobject * kobj)1146 static bool bd71828_ac_sysfs_group_visible(struct kobject *kobj)
1147 {
1148 struct device *dev = kobj_to_dev(kobj);
1149 struct bd71828_power *pwr = dev_get_drvdata(dev->parent);
1150
1151 return !!pwr->regs->dcin_set;
1152 }
1153
1154 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(bd71828_ac_sysfs);
1155
1156 static const struct attribute_group bd71828_ac_sysfs_group = {
1157 .attrs = bd71828_ac_sysfs_attrs,
1158 .is_visible = SYSFS_GROUP_VISIBLE(bd71828_ac_sysfs)
1159 };
1160
1161 static const struct attribute_group *bd71828_ac_sysfs_groups[] = {
1162 &bd71828_ac_sysfs_group,
1163 NULL
1164 };
1165
bd71828_power_probe(struct platform_device * pdev)1166 static int bd71828_power_probe(struct platform_device *pdev)
1167 {
1168 struct bd71828_power *pwr;
1169 struct power_supply_config ac_cfg = {
1170 .attr_grp = bd71828_ac_sysfs_groups,
1171 };
1172 struct power_supply_config bat_cfg = {};
1173 int ret;
1174
1175 pwr = devm_kzalloc(&pdev->dev, sizeof(*pwr), GFP_KERNEL);
1176 if (!pwr)
1177 return -ENOMEM;
1178
1179 /*
1180 * The BD72720 MFD device registers two regmaps. Power-supply driver
1181 * uses the "wrap-map", which provides access to both of the I2C slave
1182 * addresses used by the BD72720
1183 */
1184 pwr->chip_type = platform_get_device_id(pdev)->driver_data;
1185 if (pwr->chip_type != ROHM_CHIP_TYPE_BD72720)
1186 pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1187 else
1188 pwr->regmap = dev_get_regmap(pdev->dev.parent, "wrap-map");
1189 if (!pwr->regmap)
1190 return dev_err_probe(&pdev->dev, -EINVAL, "No parent regmap\n");
1191
1192 pwr->dev = &pdev->dev;
1193
1194 switch (pwr->chip_type) {
1195 case ROHM_CHIP_TYPE_BD71828:
1196 pwr->bat_inserted = bd71828_bat_inserted;
1197 pwr->get_temp = bd71828_get_temp;
1198 pwr->regs = &pwr_regs_bd71828;
1199 break;
1200 case ROHM_CHIP_TYPE_BD71815:
1201 pwr->bat_inserted = bd71815_bat_inserted;
1202 pwr->get_temp = bd71815_get_temp;
1203 pwr->regs = &pwr_regs_bd71815;
1204 break;
1205 case ROHM_CHIP_TYPE_BD72720:
1206 pwr->bat_inserted = bd71828_bat_inserted;
1207 pwr->regs = &pwr_regs_bd72720;
1208 pwr->get_temp = bd71828_get_temp;
1209 dev_dbg(pwr->dev, "Found ROHM BD72720\n");
1210 break;
1211 default:
1212 return dev_err_probe(pwr->dev, -EINVAL, "Unknown PMIC\n");
1213 }
1214
1215 ret = bd7182x_get_rsens(pwr);
1216 if (ret)
1217 return dev_err_probe(&pdev->dev, ret, "sense resistor missing\n");
1218
1219 dev_set_drvdata(&pdev->dev, pwr);
1220 bd71828_init_hardware(pwr);
1221
1222 bat_cfg.drv_data = pwr;
1223 bat_cfg.fwnode = dev_fwnode(&pdev->dev);
1224
1225 ac_cfg.supplied_to = bd71828_ac_supplied_to;
1226 ac_cfg.num_supplicants = ARRAY_SIZE(bd71828_ac_supplied_to);
1227 ac_cfg.drv_data = pwr;
1228
1229 pwr->ac = devm_power_supply_register(&pdev->dev, &bd71828_ac_desc,
1230 &ac_cfg);
1231 if (IS_ERR(pwr->ac))
1232 return dev_err_probe(&pdev->dev, PTR_ERR(pwr->ac),
1233 "failed to register ac\n");
1234
1235 pwr->bat = devm_power_supply_register(&pdev->dev, &bd71828_bat_desc,
1236 &bat_cfg);
1237 if (IS_ERR(pwr->bat))
1238 return dev_err_probe(&pdev->dev, PTR_ERR(pwr->bat),
1239 "failed to register bat\n");
1240
1241 ret = bd7182x_get_irqs(pdev, pwr);
1242 if (ret)
1243 return dev_err_probe(&pdev->dev, ret, "failed to request IRQs");
1244
1245 /* Configure wakeup capable */
1246 device_set_wakeup_capable(pwr->dev, 1);
1247 device_set_wakeup_enable(pwr->dev, 1);
1248
1249 return 0;
1250 }
1251
1252 static const struct platform_device_id bd71828_charger_id[] = {
1253 { .name = "bd71815-power", .driver_data = ROHM_CHIP_TYPE_BD71815 },
1254 { .name = "bd71828-power", .driver_data = ROHM_CHIP_TYPE_BD71828 },
1255 { .name = "bd72720-power", .driver_data = ROHM_CHIP_TYPE_BD72720 },
1256 { }
1257 };
1258 MODULE_DEVICE_TABLE(platform, bd71828_charger_id);
1259
1260 static struct platform_driver bd71828_power_driver = {
1261 .driver = {
1262 .name = "bd718xx-power",
1263 },
1264 .probe = bd71828_power_probe,
1265 .id_table = bd71828_charger_id,
1266 };
1267
1268 module_platform_driver(bd71828_power_driver);
1269
1270 MODULE_AUTHOR("Cong Pham <cpham2403@gmail.com>");
1271 MODULE_DESCRIPTION("ROHM BD718(15/28/78) PMIC Battery Charger driver");
1272 MODULE_LICENSE("GPL");
1273