1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2022 Richtek Technology Corp.
5 * Author: ChiaEn Wu <chiaen_wu@richtek.com>
8 #include <linux/bitfield.h>
9 #include <linux/bits.h>
10 #include <linux/devm-helpers.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/iio/consumer.h>
13 #include <linux/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16 #include <linux/linear_range.h>
17 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/power_supply.h>
21 #include <linux/regmap.h>
22 #include <linux/regulator/driver.h>
23 #include <linux/workqueue.h>
25 #define MT6370_REG_CHG_CTRL1 0x111
26 #define MT6370_REG_CHG_CTRL2 0x112
27 #define MT6370_REG_CHG_CTRL3 0x113
28 #define MT6370_REG_CHG_CTRL4 0x114
29 #define MT6370_REG_CHG_CTRL5 0x115
30 #define MT6370_REG_CHG_CTRL6 0x116
31 #define MT6370_REG_CHG_CTRL7 0x117
32 #define MT6370_REG_CHG_CTRL8 0x118
33 #define MT6370_REG_CHG_CTRL9 0x119
34 #define MT6370_REG_CHG_CTRL10 0x11A
35 #define MT6370_REG_DEVICE_TYPE 0x122
36 #define MT6370_REG_USB_STATUS1 0x127
37 #define MT6370_REG_CHG_STAT 0x14A
38 #define MT6370_REG_FLED_EN 0x17E
39 #define MT6370_REG_CHG_STAT1 0X1D0
40 #define MT6370_REG_OVPCTRL_STAT 0x1D8
42 #define MT6370_VOBST_MASK GENMASK(7, 2)
43 #define MT6370_OTG_PIN_EN_MASK BIT(1)
44 #define MT6370_OPA_MODE_MASK BIT(0)
45 #define MT6370_OTG_OC_MASK GENMASK(2, 0)
47 #define MT6370_MIVR_IBUS_TH_100_mA 100000
48 #define MT6370_ADC_CHAN_IBUS 5
49 #define MT6370_ADC_CHAN_MAX 9
51 enum mt6370_chg_reg_field
{
52 /* MT6370_REG_CHG_CTRL2 */
53 F_IINLMTSEL
, F_CFO_EN
, F_CHG_EN
,
54 /* MT6370_REG_CHG_CTRL3 */
55 F_IAICR
, F_AICR_EN
, F_ILIM_EN
,
56 /* MT6370_REG_CHG_CTRL4 */
58 /* MT6370_REG_CHG_CTRL6 */
60 /* MT6370_REG_CHG_CTRL7 */
62 /* MT6370_REG_CHG_CTRL8 */
64 /* MT6370_REG_CHG_CTRL9 */
66 /* MT6370_REG_DEVICE_TYPE */
68 /* MT6370_REG_USB_STATUS1 */
70 /* MT6370_REG_CHG_STAT */
71 F_CHG_STAT
, F_BOOST_STAT
, F_VBAT_LVL
,
72 /* MT6370_REG_FLED_EN */
74 /* MT6370_REG_CHG_STAT1 */
76 /* MT6370_REG_OVPCTRL_STAT */
82 MT6370_IRQ_ATTACH_I
= 0,
90 struct iio_channel
*iio_adcs
;
91 struct mutex attach_lock
;
92 struct power_supply
*psy
;
93 struct regmap
*regmap
;
94 struct regmap_field
*rmap_fields
[F_MAX
];
95 struct regulator_dev
*rdev
;
96 struct workqueue_struct
*wq
;
97 struct work_struct bc12_work
;
98 struct delayed_work mivr_dwork
;
99 unsigned int irq_nums
[MT6370_IRQ_MAX
];
105 enum mt6370_usb_status
{
106 MT6370_USB_STAT_NO_VBUS
= 0,
107 MT6370_USB_STAT_VBUS_FLOW_IS_UNDER_GOING
,
109 MT6370_USB_STAT_SDP_NSTD
,
115 struct mt6370_chg_field
{
117 const struct linear_range
*range
;
118 struct reg_field field
;
122 MT6370_RANGE_F_IAICR
= 0,
123 MT6370_RANGE_F_VOREG
,
124 MT6370_RANGE_F_VMIVR
,
126 MT6370_RANGE_F_IPREC
,
131 static const struct linear_range mt6370_chg_ranges
[MT6370_RANGE_F_MAX
] = {
132 LINEAR_RANGE_IDX(MT6370_RANGE_F_IAICR
, 100000, 0x0, 0x3F, 50000),
133 LINEAR_RANGE_IDX(MT6370_RANGE_F_VOREG
, 3900000, 0x0, 0x51, 10000),
134 LINEAR_RANGE_IDX(MT6370_RANGE_F_VMIVR
, 3900000, 0x0, 0x5F, 100000),
135 LINEAR_RANGE_IDX(MT6370_RANGE_F_ICHG
, 900000, 0x08, 0x31, 100000),
136 LINEAR_RANGE_IDX(MT6370_RANGE_F_IPREC
, 100000, 0x0, 0x0F, 50000),
137 LINEAR_RANGE_IDX(MT6370_RANGE_F_IEOC
, 100000, 0x0, 0x0F, 50000),
140 #define MT6370_CHG_FIELD(_fd, _reg, _lsb, _msb) \
144 .field = REG_FIELD(_reg, _lsb, _msb), \
147 #define MT6370_CHG_FIELD_RANGE(_fd, _reg, _lsb, _msb) \
150 .range = &mt6370_chg_ranges[MT6370_RANGE_##_fd], \
151 .field = REG_FIELD(_reg, _lsb, _msb), \
154 static const struct mt6370_chg_field mt6370_chg_fields
[F_MAX
] = {
155 MT6370_CHG_FIELD(F_IINLMTSEL
, MT6370_REG_CHG_CTRL2
, 2, 3),
156 MT6370_CHG_FIELD(F_CFO_EN
, MT6370_REG_CHG_CTRL2
, 1, 1),
157 MT6370_CHG_FIELD(F_CHG_EN
, MT6370_REG_CHG_CTRL2
, 0, 0),
158 MT6370_CHG_FIELD_RANGE(F_IAICR
, MT6370_REG_CHG_CTRL3
, 2, 7),
159 MT6370_CHG_FIELD(F_AICR_EN
, MT6370_REG_CHG_CTRL3
, 1, 1),
160 MT6370_CHG_FIELD(F_ILIM_EN
, MT6370_REG_CHG_CTRL3
, 0, 0),
161 MT6370_CHG_FIELD_RANGE(F_VOREG
, MT6370_REG_CHG_CTRL4
, 1, 7),
162 MT6370_CHG_FIELD_RANGE(F_VMIVR
, MT6370_REG_CHG_CTRL6
, 1, 7),
163 MT6370_CHG_FIELD_RANGE(F_ICHG
, MT6370_REG_CHG_CTRL7
, 2, 7),
164 MT6370_CHG_FIELD_RANGE(F_IPREC
, MT6370_REG_CHG_CTRL8
, 0, 3),
165 MT6370_CHG_FIELD_RANGE(F_IEOC
, MT6370_REG_CHG_CTRL9
, 4, 7),
166 MT6370_CHG_FIELD(F_USBCHGEN
, MT6370_REG_DEVICE_TYPE
, 7, 7),
167 MT6370_CHG_FIELD(F_USB_STAT
, MT6370_REG_USB_STATUS1
, 4, 6),
168 MT6370_CHG_FIELD(F_CHGDET
, MT6370_REG_USB_STATUS1
, 3, 3),
169 MT6370_CHG_FIELD(F_CHG_STAT
, MT6370_REG_CHG_STAT
, 6, 7),
170 MT6370_CHG_FIELD(F_BOOST_STAT
, MT6370_REG_CHG_STAT
, 3, 3),
171 MT6370_CHG_FIELD(F_VBAT_LVL
, MT6370_REG_CHG_STAT
, 5, 5),
172 MT6370_CHG_FIELD(F_FL_STROBE
, MT6370_REG_FLED_EN
, 2, 2),
173 MT6370_CHG_FIELD(F_CHG_MIVR_STAT
, MT6370_REG_CHG_STAT1
, 6, 6),
174 MT6370_CHG_FIELD(F_UVP_D_STAT
, MT6370_REG_OVPCTRL_STAT
, 4, 4),
177 static inline int mt6370_chg_field_get(struct mt6370_priv
*priv
,
178 enum mt6370_chg_reg_field fd
,
182 unsigned int reg_val
;
184 ret
= regmap_field_read(priv
->rmap_fields
[fd
], ®_val
);
188 if (mt6370_chg_fields
[fd
].range
)
189 return linear_range_get_value(mt6370_chg_fields
[fd
].range
,
196 static inline int mt6370_chg_field_set(struct mt6370_priv
*priv
,
197 enum mt6370_chg_reg_field fd
,
202 const struct linear_range
*r
;
204 if (mt6370_chg_fields
[fd
].range
) {
205 r
= mt6370_chg_fields
[fd
].range
;
208 ret
= linear_range_get_selector_high(r
, val
, &val
, &f
);
212 linear_range_get_selector_within(r
, val
, &val
);
216 return regmap_field_write(priv
->rmap_fields
[fd
], val
);
220 MT6370_CHG_STAT_READY
= 0,
221 MT6370_CHG_STAT_CHARGE_IN_PROGRESS
,
222 MT6370_CHG_STAT_DONE
,
223 MT6370_CHG_STAT_FAULT
,
228 MT6370_ATTACH_STAT_DETACH
= 0,
229 MT6370_ATTACH_STAT_ATTACH_WAIT_FOR_BC12
,
230 MT6370_ATTACH_STAT_ATTACH_BC12_DONE
,
231 MT6370_ATTACH_STAT_ATTACH_MAX
234 static int mt6370_chg_otg_of_parse_cb(struct device_node
*of
,
235 const struct regulator_desc
*rdesc
,
236 struct regulator_config
*rcfg
)
238 struct mt6370_priv
*priv
= rcfg
->driver_data
;
240 rcfg
->ena_gpiod
= fwnode_gpiod_get_index(of_fwnode_handle(of
),
241 "enable", 0, GPIOD_OUT_LOW
|
242 GPIOD_FLAGS_BIT_NONEXCLUSIVE
,
244 if (IS_ERR(rcfg
->ena_gpiod
)) {
245 rcfg
->ena_gpiod
= NULL
;
249 return regmap_update_bits(priv
->regmap
, MT6370_REG_CHG_CTRL1
,
250 MT6370_OTG_PIN_EN_MASK
,
251 MT6370_OTG_PIN_EN_MASK
);
254 static void mt6370_chg_bc12_work_func(struct work_struct
*work
)
256 struct mt6370_priv
*priv
= container_of(work
, struct mt6370_priv
,
259 bool rpt_psy
= false;
260 unsigned int attach
, usb_stat
;
262 mutex_lock(&priv
->attach_lock
);
263 attach
= priv
->attach
;
266 case MT6370_ATTACH_STAT_DETACH
:
269 case MT6370_ATTACH_STAT_ATTACH_WAIT_FOR_BC12
:
270 ret
= mt6370_chg_field_set(priv
, F_USBCHGEN
, attach
);
272 dev_err(priv
->dev
, "Failed to enable USB CHG EN\n");
273 goto bc12_work_func_out
;
274 case MT6370_ATTACH_STAT_ATTACH_BC12_DONE
:
275 ret
= mt6370_chg_field_get(priv
, F_USB_STAT
, &usb_stat
);
277 dev_err(priv
->dev
, "Failed to get USB status\n");
278 goto bc12_work_func_out
;
282 dev_err(priv
->dev
, "Invalid attach state\n");
283 goto bc12_work_func_out
;
289 case MT6370_USB_STAT_SDP
:
290 case MT6370_USB_STAT_SDP_NSTD
:
291 priv
->psy_usb_type
= POWER_SUPPLY_USB_TYPE_SDP
;
293 case MT6370_USB_STAT_DCP
:
294 priv
->psy_usb_type
= POWER_SUPPLY_USB_TYPE_DCP
;
296 case MT6370_USB_STAT_CDP
:
297 priv
->psy_usb_type
= POWER_SUPPLY_USB_TYPE_CDP
;
299 case MT6370_USB_STAT_NO_VBUS
:
300 case MT6370_USB_STAT_VBUS_FLOW_IS_UNDER_GOING
:
302 priv
->psy_usb_type
= POWER_SUPPLY_USB_TYPE_UNKNOWN
;
307 mutex_unlock(&priv
->attach_lock
);
310 power_supply_changed(priv
->psy
);
313 static int mt6370_chg_toggle_cfo(struct mt6370_priv
*priv
)
316 unsigned int fl_strobe
;
318 /* check if flash led in strobe mode */
319 ret
= mt6370_chg_field_get(priv
, F_FL_STROBE
, &fl_strobe
);
321 dev_err(priv
->dev
, "Failed to get FL_STROBE_EN\n");
326 dev_err(priv
->dev
, "Flash led is still in strobe mode\n");
331 ret
= mt6370_chg_field_set(priv
, F_CFO_EN
, 0);
333 dev_err(priv
->dev
, "Failed to disable CFO_EN\n");
338 ret
= mt6370_chg_field_set(priv
, F_CFO_EN
, 1);
340 dev_err(priv
->dev
, "Failed to enable CFO_EN\n");
345 static int mt6370_chg_read_adc_chan(struct mt6370_priv
*priv
, unsigned int chan
,
350 if (chan
>= MT6370_ADC_CHAN_MAX
)
353 ret
= iio_read_channel_processed(&priv
->iio_adcs
[chan
], val
);
355 dev_err(priv
->dev
, "Failed to read ADC\n");
360 static void mt6370_chg_mivr_dwork_func(struct work_struct
*work
)
362 struct mt6370_priv
*priv
= container_of(work
, struct mt6370_priv
,
365 unsigned int mivr_stat
, ibus
;
367 ret
= mt6370_chg_field_get(priv
, F_CHG_MIVR_STAT
, &mivr_stat
);
369 dev_err(priv
->dev
, "Failed to get mivr state\n");
370 goto mivr_handler_out
;
374 goto mivr_handler_out
;
376 ret
= mt6370_chg_read_adc_chan(priv
, MT6370_ADC_CHAN_IBUS
, &ibus
);
378 dev_err(priv
->dev
, "Failed to get ibus\n");
379 goto mivr_handler_out
;
382 if (ibus
< MT6370_MIVR_IBUS_TH_100_mA
) {
383 ret
= mt6370_chg_toggle_cfo(priv
);
385 dev_err(priv
->dev
, "Failed to toggle cfo\n");
389 enable_irq(priv
->irq_nums
[MT6370_IRQ_MIVR
]);
393 static void mt6370_chg_pwr_rdy_check(struct mt6370_priv
*priv
)
396 unsigned int opposite_pwr_rdy
, otg_en
;
397 union power_supply_propval val
;
399 /* Check in OTG mode or not */
400 ret
= mt6370_chg_field_get(priv
, F_BOOST_STAT
, &otg_en
);
402 dev_err(priv
->dev
, "Failed to get OTG state\n");
409 ret
= mt6370_chg_field_get(priv
, F_UVP_D_STAT
, &opposite_pwr_rdy
);
411 dev_err(priv
->dev
, "Failed to get opposite power ready state\n");
415 val
.intval
= opposite_pwr_rdy
?
416 MT6370_ATTACH_STAT_DETACH
:
417 MT6370_ATTACH_STAT_ATTACH_WAIT_FOR_BC12
;
419 ret
= power_supply_set_property(priv
->psy
, POWER_SUPPLY_PROP_ONLINE
,
422 dev_err(priv
->dev
, "Failed to start attach/detach flow\n");
425 static int mt6370_chg_get_online(struct mt6370_priv
*priv
,
426 union power_supply_propval
*val
)
428 mutex_lock(&priv
->attach_lock
);
429 val
->intval
= !!priv
->attach
;
430 mutex_unlock(&priv
->attach_lock
);
435 static int mt6370_chg_get_status(struct mt6370_priv
*priv
,
436 union power_supply_propval
*val
)
439 unsigned int chg_stat
;
440 union power_supply_propval online
;
442 ret
= power_supply_get_property(priv
->psy
, POWER_SUPPLY_PROP_ONLINE
,
445 dev_err(priv
->dev
, "Failed to get online status\n");
449 if (!online
.intval
) {
450 val
->intval
= POWER_SUPPLY_STATUS_DISCHARGING
;
454 ret
= mt6370_chg_field_get(priv
, F_CHG_STAT
, &chg_stat
);
459 case MT6370_CHG_STAT_READY
:
460 case MT6370_CHG_STAT_FAULT
:
461 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
463 case MT6370_CHG_STAT_CHARGE_IN_PROGRESS
:
464 val
->intval
= POWER_SUPPLY_STATUS_CHARGING
;
466 case MT6370_CHG_STAT_DONE
:
467 val
->intval
= POWER_SUPPLY_STATUS_FULL
;
470 val
->intval
= POWER_SUPPLY_STATUS_UNKNOWN
;
475 static int mt6370_chg_get_charge_type(struct mt6370_priv
*priv
,
476 union power_supply_propval
*val
)
479 unsigned int chg_stat
, vbat_lvl
;
481 ret
= mt6370_chg_field_get(priv
, F_CHG_STAT
, &chg_stat
);
485 ret
= mt6370_chg_field_get(priv
, F_VBAT_LVL
, &vbat_lvl
);
490 case MT6370_CHG_STAT_CHARGE_IN_PROGRESS
:
492 type
= POWER_SUPPLY_CHARGE_TYPE_FAST
;
494 type
= POWER_SUPPLY_CHARGE_TYPE_TRICKLE
;
496 case MT6370_CHG_STAT_READY
:
497 case MT6370_CHG_STAT_DONE
:
498 case MT6370_CHG_STAT_FAULT
:
500 type
= POWER_SUPPLY_CHARGE_TYPE_NONE
;
509 static int mt6370_chg_set_online(struct mt6370_priv
*priv
,
510 const union power_supply_propval
*val
)
512 bool pwr_rdy
= !!val
->intval
;
514 mutex_lock(&priv
->attach_lock
);
515 if (pwr_rdy
== !!priv
->attach
) {
516 dev_err(priv
->dev
, "pwr_rdy is same(%d)\n", pwr_rdy
);
517 mutex_unlock(&priv
->attach_lock
);
521 priv
->attach
= pwr_rdy
;
522 mutex_unlock(&priv
->attach_lock
);
524 if (!queue_work(priv
->wq
, &priv
->bc12_work
))
525 dev_err(priv
->dev
, "bc12 work has already queued\n");
530 static int mt6370_chg_get_property(struct power_supply
*psy
,
531 enum power_supply_property psp
,
532 union power_supply_propval
*val
)
534 struct mt6370_priv
*priv
= power_supply_get_drvdata(psy
);
537 case POWER_SUPPLY_PROP_ONLINE
:
538 return mt6370_chg_get_online(priv
, val
);
539 case POWER_SUPPLY_PROP_STATUS
:
540 return mt6370_chg_get_status(priv
, val
);
541 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
542 return mt6370_chg_get_charge_type(priv
, val
);
543 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
544 return mt6370_chg_field_get(priv
, F_ICHG
, &val
->intval
);
545 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
546 val
->intval
= linear_range_get_max_value(&mt6370_chg_ranges
[MT6370_RANGE_F_ICHG
]);
548 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
549 return mt6370_chg_field_get(priv
, F_VOREG
, &val
->intval
);
550 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
:
551 val
->intval
= linear_range_get_max_value(&mt6370_chg_ranges
[MT6370_RANGE_F_VOREG
]);
553 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
554 return mt6370_chg_field_get(priv
, F_IAICR
, &val
->intval
);
555 case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT
:
556 return mt6370_chg_field_get(priv
, F_VMIVR
, &val
->intval
);
557 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT
:
558 return mt6370_chg_field_get(priv
, F_IPREC
, &val
->intval
);
559 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
560 return mt6370_chg_field_get(priv
, F_IEOC
, &val
->intval
);
561 case POWER_SUPPLY_PROP_USB_TYPE
:
562 val
->intval
= priv
->psy_usb_type
;
569 static int mt6370_chg_set_property(struct power_supply
*psy
,
570 enum power_supply_property psp
,
571 const union power_supply_propval
*val
)
573 struct mt6370_priv
*priv
= power_supply_get_drvdata(psy
);
576 case POWER_SUPPLY_PROP_ONLINE
:
577 return mt6370_chg_set_online(priv
, val
);
578 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
579 return mt6370_chg_field_set(priv
, F_ICHG
, val
->intval
);
580 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
581 return mt6370_chg_field_set(priv
, F_VOREG
, val
->intval
);
582 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
583 return mt6370_chg_field_set(priv
, F_IAICR
, val
->intval
);
584 case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT
:
585 return mt6370_chg_field_set(priv
, F_VMIVR
, val
->intval
);
586 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT
:
587 return mt6370_chg_field_set(priv
, F_IPREC
, val
->intval
);
588 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
589 return mt6370_chg_field_set(priv
, F_IEOC
, val
->intval
);
595 static int mt6370_chg_property_is_writeable(struct power_supply
*psy
,
596 enum power_supply_property psp
)
599 case POWER_SUPPLY_PROP_ONLINE
:
600 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
601 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
602 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
603 case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT
:
604 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT
:
605 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
612 static enum power_supply_property mt6370_chg_properties
[] = {
613 POWER_SUPPLY_PROP_ONLINE
,
614 POWER_SUPPLY_PROP_STATUS
,
615 POWER_SUPPLY_PROP_CHARGE_TYPE
,
616 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
,
617 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
,
618 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
,
619 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
,
620 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
,
621 POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT
,
622 POWER_SUPPLY_PROP_PRECHARGE_CURRENT
,
623 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
,
624 POWER_SUPPLY_PROP_USB_TYPE
,
627 static const struct power_supply_desc mt6370_chg_psy_desc
= {
628 .name
= "mt6370-charger",
629 .type
= POWER_SUPPLY_TYPE_USB
,
630 .properties
= mt6370_chg_properties
,
631 .num_properties
= ARRAY_SIZE(mt6370_chg_properties
),
632 .get_property
= mt6370_chg_get_property
,
633 .set_property
= mt6370_chg_set_property
,
634 .property_is_writeable
= mt6370_chg_property_is_writeable
,
635 .usb_types
= BIT(POWER_SUPPLY_USB_TYPE_SDP
) |
636 BIT(POWER_SUPPLY_USB_TYPE_CDP
) |
637 BIT(POWER_SUPPLY_USB_TYPE_DCP
) |
638 BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN
),
641 static const struct regulator_ops mt6370_chg_otg_ops
= {
642 .list_voltage
= regulator_list_voltage_linear
,
643 .enable
= regulator_enable_regmap
,
644 .disable
= regulator_disable_regmap
,
645 .is_enabled
= regulator_is_enabled_regmap
,
646 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
647 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
648 .set_current_limit
= regulator_set_current_limit_regmap
,
649 .get_current_limit
= regulator_get_current_limit_regmap
,
652 static const u32 mt6370_chg_otg_oc_ma
[] = {
653 500000, 700000, 1100000, 1300000, 1800000, 2100000, 2400000,
656 static const struct regulator_desc mt6370_chg_otg_rdesc
= {
657 .of_match
= "usb-otg-vbus-regulator",
658 .of_parse_cb
= mt6370_chg_otg_of_parse_cb
,
659 .name
= "mt6370-usb-otg-vbus",
660 .ops
= &mt6370_chg_otg_ops
,
661 .owner
= THIS_MODULE
,
662 .type
= REGULATOR_VOLTAGE
,
666 .vsel_reg
= MT6370_REG_CHG_CTRL5
,
667 .vsel_mask
= MT6370_VOBST_MASK
,
668 .enable_reg
= MT6370_REG_CHG_CTRL1
,
669 .enable_mask
= MT6370_OPA_MODE_MASK
,
670 .curr_table
= mt6370_chg_otg_oc_ma
,
671 .n_current_limits
= ARRAY_SIZE(mt6370_chg_otg_oc_ma
),
672 .csel_reg
= MT6370_REG_CHG_CTRL10
,
673 .csel_mask
= MT6370_OTG_OC_MASK
,
676 static int mt6370_chg_init_rmap_fields(struct mt6370_priv
*priv
)
679 const struct mt6370_chg_field
*fds
= mt6370_chg_fields
;
681 for (i
= 0; i
< F_MAX
; i
++) {
682 priv
->rmap_fields
[i
] = devm_regmap_field_alloc(priv
->dev
,
685 if (IS_ERR(priv
->rmap_fields
[i
]))
686 return dev_err_probe(priv
->dev
,
687 PTR_ERR(priv
->rmap_fields
[i
]),
688 "Failed to allocate regmapfield[%s]\n",
695 static int mt6370_chg_init_setting(struct mt6370_priv
*priv
)
699 /* Disable usb_chg_en */
700 ret
= mt6370_chg_field_set(priv
, F_USBCHGEN
, 0);
702 dev_err(priv
->dev
, "Failed to disable usb_chg_en\n");
706 /* Disable input current limit */
707 ret
= mt6370_chg_field_set(priv
, F_ILIM_EN
, 0);
709 dev_err(priv
->dev
, "Failed to disable input current limit\n");
713 /* ICHG/IEOC Workaround, ICHG can not be set less than 900mA */
714 ret
= mt6370_chg_field_set(priv
, F_ICHG
, 900000);
716 dev_err(priv
->dev
, "Failed to set ICHG to 900mA");
720 /* Change input current limit selection to using IAICR results */
721 ret
= mt6370_chg_field_set(priv
, F_IINLMTSEL
, 2);
723 dev_err(priv
->dev
, "Failed to set IINLMTSEL\n");
730 #define MT6370_CHG_DT_PROP_DECL(_name, _type, _field) \
732 .name = "mediatek,chg-" #_name, \
733 .type = MT6370_PARSE_TYPE_##_type, \
737 static int mt6370_chg_init_otg_regulator(struct mt6370_priv
*priv
)
739 struct regulator_config rcfg
= {
741 .regmap
= priv
->regmap
,
745 priv
->rdev
= devm_regulator_register(priv
->dev
, &mt6370_chg_otg_rdesc
,
748 return PTR_ERR_OR_ZERO(priv
->rdev
);
751 static int mt6370_chg_init_psy(struct mt6370_priv
*priv
)
753 struct power_supply_config cfg
= {
755 .of_node
= dev_of_node(priv
->dev
),
758 priv
->psy
= devm_power_supply_register(priv
->dev
, &mt6370_chg_psy_desc
,
761 return PTR_ERR_OR_ZERO(priv
->psy
);
764 static void mt6370_chg_destroy_attach_lock(void *data
)
766 struct mutex
*attach_lock
= data
;
768 mutex_destroy(attach_lock
);
771 static void mt6370_chg_destroy_wq(void *data
)
773 struct workqueue_struct
*wq
= data
;
776 destroy_workqueue(wq
);
779 static irqreturn_t
mt6370_attach_i_handler(int irq
, void *data
)
781 struct mt6370_priv
*priv
= data
;
785 /* Check in OTG mode or not */
786 ret
= mt6370_chg_field_get(priv
, F_BOOST_STAT
, &otg_en
);
788 dev_err(priv
->dev
, "Failed to get OTG state\n");
795 mutex_lock(&priv
->attach_lock
);
796 priv
->attach
= MT6370_ATTACH_STAT_ATTACH_BC12_DONE
;
797 mutex_unlock(&priv
->attach_lock
);
799 if (!queue_work(priv
->wq
, &priv
->bc12_work
))
800 dev_err(priv
->dev
, "bc12 work has already queued\n");
805 static irqreturn_t
mt6370_uvp_d_evt_handler(int irq
, void *data
)
807 struct mt6370_priv
*priv
= data
;
809 mt6370_chg_pwr_rdy_check(priv
);
814 static irqreturn_t
mt6370_mivr_handler(int irq
, void *data
)
816 struct mt6370_priv
*priv
= data
;
818 pm_stay_awake(priv
->dev
);
819 disable_irq_nosync(priv
->irq_nums
[MT6370_IRQ_MIVR
]);
820 schedule_delayed_work(&priv
->mivr_dwork
, msecs_to_jiffies(200));
825 #define MT6370_CHG_IRQ(_name) \
828 .handler = mt6370_##_name##_handler, \
831 static int mt6370_chg_init_irq(struct mt6370_priv
*priv
)
836 irq_handler_t handler
;
837 } mt6370_chg_irqs
[] = {
838 MT6370_CHG_IRQ(attach_i
),
839 MT6370_CHG_IRQ(uvp_d_evt
),
840 MT6370_CHG_IRQ(mivr
),
843 for (i
= 0; i
< ARRAY_SIZE(mt6370_chg_irqs
); i
++) {
844 ret
= platform_get_irq_byname(to_platform_device(priv
->dev
),
845 mt6370_chg_irqs
[i
].name
);
849 priv
->irq_nums
[i
] = ret
;
850 ret
= devm_request_threaded_irq(priv
->dev
, ret
, NULL
,
851 mt6370_chg_irqs
[i
].handler
,
852 IRQF_TRIGGER_FALLING
,
853 dev_name(priv
->dev
), priv
);
855 return dev_err_probe(priv
->dev
, ret
,
856 "Failed to request irq %s\n",
857 mt6370_chg_irqs
[i
].name
);
863 static int mt6370_chg_probe(struct platform_device
*pdev
)
865 struct device
*dev
= &pdev
->dev
;
866 struct mt6370_priv
*priv
;
869 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
873 priv
->dev
= &pdev
->dev
;
875 priv
->regmap
= dev_get_regmap(pdev
->dev
.parent
, NULL
);
877 return dev_err_probe(dev
, -ENODEV
, "Failed to get regmap\n");
879 ret
= mt6370_chg_init_rmap_fields(priv
);
881 return dev_err_probe(dev
, ret
, "Failed to init regmap fields\n");
883 platform_set_drvdata(pdev
, priv
);
885 priv
->iio_adcs
= devm_iio_channel_get_all(priv
->dev
);
886 if (IS_ERR(priv
->iio_adcs
))
887 return dev_err_probe(dev
, PTR_ERR(priv
->iio_adcs
),
888 "Failed to get iio adc\n");
890 ret
= mt6370_chg_init_otg_regulator(priv
);
892 return dev_err_probe(dev
, ret
, "Failed to init OTG regulator\n");
894 ret
= mt6370_chg_init_psy(priv
);
896 return dev_err_probe(dev
, ret
, "Failed to init psy\n");
898 mutex_init(&priv
->attach_lock
);
899 ret
= devm_add_action_or_reset(dev
, mt6370_chg_destroy_attach_lock
,
902 return dev_err_probe(dev
, ret
, "Failed to init attach lock\n");
904 priv
->attach
= MT6370_ATTACH_STAT_DETACH
;
906 priv
->wq
= create_singlethread_workqueue(dev_name(priv
->dev
));
908 return dev_err_probe(dev
, -ENOMEM
,
909 "Failed to create workqueue\n");
911 ret
= devm_add_action_or_reset(dev
, mt6370_chg_destroy_wq
, priv
->wq
);
913 return dev_err_probe(dev
, ret
, "Failed to init wq\n");
915 ret
= devm_work_autocancel(dev
, &priv
->bc12_work
, mt6370_chg_bc12_work_func
);
917 return dev_err_probe(dev
, ret
, "Failed to init bc12 work\n");
919 ret
= devm_delayed_work_autocancel(dev
, &priv
->mivr_dwork
, mt6370_chg_mivr_dwork_func
);
921 return dev_err_probe(dev
, ret
, "Failed to init mivr delayed work\n");
923 ret
= mt6370_chg_init_setting(priv
);
925 return dev_err_probe(dev
, ret
,
926 "Failed to init mt6370 charger setting\n");
928 ret
= mt6370_chg_init_irq(priv
);
932 mt6370_chg_pwr_rdy_check(priv
);
937 static const struct of_device_id mt6370_chg_of_match
[] = {
938 { .compatible
= "mediatek,mt6370-charger", },
941 MODULE_DEVICE_TABLE(of
, mt6370_chg_of_match
);
943 static struct platform_driver mt6370_chg_driver
= {
944 .probe
= mt6370_chg_probe
,
946 .name
= "mt6370-charger",
947 .of_match_table
= mt6370_chg_of_match
,
950 module_platform_driver(mt6370_chg_driver
);
952 MODULE_AUTHOR("ChiaEn Wu <chiaen_wu@richtek.com>");
953 MODULE_DESCRIPTION("MediaTek MT6370 Charger Driver");
954 MODULE_LICENSE("GPL v2");