Lines Matching +full:usb +full:- +full:charger

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Battery charger driver for RT5033
9 #include <linux/devm-helpers.h>
18 #include <linux/mfd/rt5033-private.h>
43 static int rt5033_get_charger_state(struct rt5033_charger *charger) in rt5033_get_charger_state() argument
45 struct regmap *regmap = charger->regmap; in rt5033_get_charger_state()
72 if (charger->otg) in rt5033_get_charger_state()
78 static int rt5033_get_charger_type(struct rt5033_charger *charger) in rt5033_get_charger_type() argument
80 struct regmap *regmap = charger->regmap; in rt5033_get_charger_type()
100 static int rt5033_get_charger_current_limit(struct rt5033_charger *charger) in rt5033_get_charger_current_limit() argument
102 struct regmap *regmap = charger->regmap; in rt5033_get_charger_current_limit()
116 static int rt5033_get_charger_const_voltage(struct rt5033_charger *charger) in rt5033_get_charger_const_voltage() argument
118 struct regmap *regmap = charger->regmap; in rt5033_get_charger_const_voltage()
132 static inline int rt5033_init_const_charge(struct rt5033_charger *charger) in rt5033_init_const_charge() argument
134 struct rt5033_charger_data *chg = &charger->chg; in rt5033_init_const_charge()
140 if (chg->const_uvolt < RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN || in rt5033_init_const_charge()
141 chg->const_uvolt > RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX) { in rt5033_init_const_charge()
142 dev_err(charger->dev, in rt5033_init_const_charge()
143 "Value 'constant-charge-voltage-max-microvolt' out of range\n"); in rt5033_init_const_charge()
144 return -EINVAL; in rt5033_init_const_charge()
147 if (chg->const_uvolt == RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN) in rt5033_init_const_charge()
149 else if (chg->const_uvolt == RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MAX) in rt5033_init_const_charge()
152 val = chg->const_uvolt; in rt5033_init_const_charge()
153 val -= RT5033_CHARGER_CONST_VOLTAGE_LIMIT_MIN; in rt5033_init_const_charge()
158 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL2, in rt5033_init_const_charge()
162 dev_err(charger->dev, "Failed regmap update\n"); in rt5033_init_const_charge()
163 return -EINVAL; in rt5033_init_const_charge()
167 charger->cv_regval = reg_data; in rt5033_init_const_charge()
170 if (chg->eoc_uamp < RT5033_CHARGER_EOC_MIN || in rt5033_init_const_charge()
171 chg->eoc_uamp > RT5033_CHARGER_EOC_MAX) { in rt5033_init_const_charge()
172 dev_err(charger->dev, in rt5033_init_const_charge()
173 "Value 'charge-term-current-microamp' out of range\n"); in rt5033_init_const_charge()
174 return -EINVAL; in rt5033_init_const_charge()
177 if (chg->eoc_uamp == RT5033_CHARGER_EOC_MIN) in rt5033_init_const_charge()
179 else if (chg->eoc_uamp == RT5033_CHARGER_EOC_MAX) in rt5033_init_const_charge()
182 val = chg->eoc_uamp; in rt5033_init_const_charge()
184 val -= RT5033_CHARGER_EOC_MIN; in rt5033_init_const_charge()
188 val -= RT5033_CHARGER_EOC_REF; in rt5033_init_const_charge()
196 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL4, in rt5033_init_const_charge()
199 dev_err(charger->dev, "Failed regmap update\n"); in rt5033_init_const_charge()
200 return -EINVAL; in rt5033_init_const_charge()
206 static inline int rt5033_init_fast_charge(struct rt5033_charger *charger) in rt5033_init_fast_charge() argument
208 struct rt5033_charger_data *chg = &charger->chg; in rt5033_init_fast_charge()
214 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL1, in rt5033_init_fast_charge()
217 dev_err(charger->dev, "Failed regmap update\n"); in rt5033_init_fast_charge()
218 return -EINVAL; in rt5033_init_fast_charge()
221 /* Set fast-charge mode charging current */ in rt5033_init_fast_charge()
222 if (chg->fast_uamp < RT5033_CHARGER_FAST_CURRENT_MIN || in rt5033_init_fast_charge()
223 chg->fast_uamp > RT5033_CHARGER_FAST_CURRENT_MAX) { in rt5033_init_fast_charge()
224 dev_err(charger->dev, in rt5033_init_fast_charge()
225 "Value 'constant-charge-current-max-microamp' out of range\n"); in rt5033_init_fast_charge()
226 return -EINVAL; in rt5033_init_fast_charge()
229 if (chg->fast_uamp == RT5033_CHARGER_FAST_CURRENT_MIN) in rt5033_init_fast_charge()
231 else if (chg->fast_uamp == RT5033_CHARGER_FAST_CURRENT_MAX) in rt5033_init_fast_charge()
234 val = chg->fast_uamp; in rt5033_init_fast_charge()
235 val -= RT5033_CHARGER_FAST_CURRENT_MIN; in rt5033_init_fast_charge()
240 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL5, in rt5033_init_fast_charge()
244 dev_err(charger->dev, "Failed regmap update\n"); in rt5033_init_fast_charge()
245 return -EINVAL; in rt5033_init_fast_charge()
251 static inline int rt5033_init_pre_charge(struct rt5033_charger *charger) in rt5033_init_pre_charge() argument
253 struct rt5033_charger_data *chg = &charger->chg; in rt5033_init_pre_charge()
258 /* Set pre-charge threshold voltage */ in rt5033_init_pre_charge()
259 if (chg->pre_uvolt < RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN || in rt5033_init_pre_charge()
260 chg->pre_uvolt > RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX) { in rt5033_init_pre_charge()
261 dev_err(charger->dev, in rt5033_init_pre_charge()
262 "Value 'precharge-upper-limit-microvolt' out of range\n"); in rt5033_init_pre_charge()
263 return -EINVAL; in rt5033_init_pre_charge()
266 if (chg->pre_uvolt == RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN) in rt5033_init_pre_charge()
268 else if (chg->pre_uvolt == RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX) in rt5033_init_pre_charge()
271 val = chg->pre_uvolt; in rt5033_init_pre_charge()
272 val -= RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN; in rt5033_init_pre_charge()
277 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL5, in rt5033_init_pre_charge()
280 dev_err(charger->dev, "Failed regmap update\n"); in rt5033_init_pre_charge()
281 return -EINVAL; in rt5033_init_pre_charge()
284 /* Set pre-charge mode charging current */ in rt5033_init_pre_charge()
285 if (chg->pre_uamp < RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN || in rt5033_init_pre_charge()
286 chg->pre_uamp > RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX) { in rt5033_init_pre_charge()
287 dev_err(charger->dev, in rt5033_init_pre_charge()
288 "Value 'precharge-current-microamp' out of range\n"); in rt5033_init_pre_charge()
289 return -EINVAL; in rt5033_init_pre_charge()
292 if (chg->pre_uamp == RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN) in rt5033_init_pre_charge()
294 else if (chg->pre_uamp == RT5033_CHARGER_PRE_CURRENT_LIMIT_MAX) in rt5033_init_pre_charge()
297 val = chg->pre_uamp; in rt5033_init_pre_charge()
298 val -= RT5033_CHARGER_PRE_CURRENT_LIMIT_MIN; in rt5033_init_pre_charge()
303 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL4, in rt5033_init_pre_charge()
307 dev_err(charger->dev, "Failed regmap update\n"); in rt5033_init_pre_charge()
308 return -EINVAL; in rt5033_init_pre_charge()
314 static int rt5033_charger_reg_init(struct rt5033_charger *charger) in rt5033_charger_reg_init() argument
319 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL1, in rt5033_charger_reg_init()
322 dev_err(charger->dev, "Failed to enable charging termination.\n"); in rt5033_charger_reg_init()
323 return -EINVAL; in rt5033_charger_reg_init()
330 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL4, in rt5033_charger_reg_init()
333 dev_err(charger->dev, "Failed to disable MIVR.\n"); in rt5033_charger_reg_init()
334 return -EINVAL; in rt5033_charger_reg_init()
337 ret = rt5033_init_pre_charge(charger); in rt5033_charger_reg_init()
341 ret = rt5033_init_fast_charge(charger); in rt5033_charger_reg_init()
345 ret = rt5033_init_const_charge(charger); in rt5033_charger_reg_init()
352 static int rt5033_charger_set_otg(struct rt5033_charger *charger) in rt5033_charger_set_otg() argument
356 mutex_lock(&charger->lock); in rt5033_charger_set_otg()
359 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL2, in rt5033_charger_set_otg()
363 dev_err(charger->dev, "Failed set OTG boost v_out\n"); in rt5033_charger_set_otg()
364 ret = -EINVAL; in rt5033_charger_set_otg()
369 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL1, in rt5033_charger_set_otg()
372 dev_err(charger->dev, "Failed to update OTG mode.\n"); in rt5033_charger_set_otg()
373 ret = -EINVAL; in rt5033_charger_set_otg()
378 if (charger->online) in rt5033_charger_set_otg()
379 charger->online = false; in rt5033_charger_set_otg()
381 charger->otg = true; in rt5033_charger_set_otg()
384 mutex_unlock(&charger->lock); in rt5033_charger_set_otg()
389 static int rt5033_charger_unset_otg(struct rt5033_charger *charger) in rt5033_charger_unset_otg() argument
395 data = charger->cv_regval; in rt5033_charger_unset_otg()
396 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL2, in rt5033_charger_unset_otg()
400 dev_err(charger->dev, "Failed to restore constant voltage\n"); in rt5033_charger_unset_otg()
401 return -EINVAL; in rt5033_charger_unset_otg()
405 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL1, in rt5033_charger_unset_otg()
408 dev_err(charger->dev, "Failed to update charger mode.\n"); in rt5033_charger_unset_otg()
409 return -EINVAL; in rt5033_charger_unset_otg()
412 charger->otg = false; in rt5033_charger_unset_otg()
417 static int rt5033_charger_set_charging(struct rt5033_charger *charger) in rt5033_charger_set_charging() argument
421 mutex_lock(&charger->lock); in rt5033_charger_set_charging()
424 if (charger->otg) { in rt5033_charger_set_charging()
425 ret = rt5033_charger_unset_otg(charger); in rt5033_charger_set_charging()
427 mutex_unlock(&charger->lock); in rt5033_charger_set_charging()
428 return -EINVAL; in rt5033_charger_set_charging()
432 charger->online = true; in rt5033_charger_set_charging()
434 mutex_unlock(&charger->lock); in rt5033_charger_set_charging()
439 static int rt5033_charger_set_mivr(struct rt5033_charger *charger) in rt5033_charger_set_mivr() argument
443 mutex_lock(&charger->lock); in rt5033_charger_set_mivr()
446 * When connected via USB connector type SDP (Standard Downstream Port), in rt5033_charger_set_mivr()
449 * by the adapter or USB input. As a downside, it may reduces the in rt5033_charger_set_mivr()
452 ret = regmap_update_bits(charger->regmap, RT5033_REG_CHG_CTRL4, in rt5033_charger_set_mivr()
455 dev_err(charger->dev, "Failed to set MIVR level.\n"); in rt5033_charger_set_mivr()
456 mutex_unlock(&charger->lock); in rt5033_charger_set_mivr()
457 return -EINVAL; in rt5033_charger_set_mivr()
460 charger->mivr_enabled = true; in rt5033_charger_set_mivr()
462 mutex_unlock(&charger->lock); in rt5033_charger_set_mivr()
465 rt5033_charger_set_charging(charger); in rt5033_charger_set_mivr()
470 static int rt5033_charger_set_disconnect(struct rt5033_charger *charger) in rt5033_charger_set_disconnect() argument
474 mutex_lock(&charger->lock); in rt5033_charger_set_disconnect()
477 if (charger->mivr_enabled) { in rt5033_charger_set_disconnect()
478 ret = regmap_update_bits(charger->regmap, in rt5033_charger_set_disconnect()
483 dev_err(charger->dev, "Failed to disable MIVR.\n"); in rt5033_charger_set_disconnect()
484 ret = -EINVAL; in rt5033_charger_set_disconnect()
488 charger->mivr_enabled = false; in rt5033_charger_set_disconnect()
491 if (charger->otg) { in rt5033_charger_set_disconnect()
492 ret = rt5033_charger_unset_otg(charger); in rt5033_charger_set_disconnect()
494 ret = -EINVAL; in rt5033_charger_set_disconnect()
499 if (charger->online) in rt5033_charger_set_disconnect()
500 charger->online = false; in rt5033_charger_set_disconnect()
503 mutex_unlock(&charger->lock); in rt5033_charger_set_disconnect()
522 struct rt5033_charger *charger = power_supply_get_drvdata(psy); in rt5033_charger_get_property() local
526 val->intval = rt5033_get_charger_state(charger); in rt5033_charger_get_property()
529 val->intval = rt5033_get_charger_type(charger); in rt5033_charger_get_property()
532 val->intval = rt5033_get_charger_current_limit(charger); in rt5033_charger_get_property()
535 val->intval = rt5033_get_charger_const_voltage(charger); in rt5033_charger_get_property()
538 val->strval = RT5033_CHARGER_MODEL; in rt5033_charger_get_property()
541 val->strval = RT5033_MANUFACTURER; in rt5033_charger_get_property()
544 val->intval = charger->online; in rt5033_charger_get_property()
547 return -EINVAL; in rt5033_charger_get_property()
553 static int rt5033_charger_dt_init(struct rt5033_charger *charger) in rt5033_charger_dt_init() argument
555 struct rt5033_charger_data *chg = &charger->chg; in rt5033_charger_dt_init()
559 ret = power_supply_get_battery_info(charger->psy, &info); in rt5033_charger_dt_init()
561 return dev_err_probe(charger->dev, -EINVAL, in rt5033_charger_dt_init()
565 chg->pre_uamp = info->precharge_current_ua; in rt5033_charger_dt_init()
566 chg->fast_uamp = info->constant_charge_current_max_ua; in rt5033_charger_dt_init()
567 chg->eoc_uamp = info->charge_term_current_ua; in rt5033_charger_dt_init()
568 chg->pre_uvolt = info->precharge_voltage_max_uv; in rt5033_charger_dt_init()
569 chg->const_uvolt = info->constant_charge_voltage_max_uv; in rt5033_charger_dt_init()
576 struct rt5033_charger *charger = in rt5033_charger_extcon_work() local
578 struct extcon_dev *edev = charger->edev; in rt5033_charger_extcon_work()
599 ret = rt5033_charger_set_mivr(charger); in rt5033_charger_extcon_work()
601 dev_err(charger->dev, "failed to set USB mode\n"); in rt5033_charger_extcon_work()
604 dev_info(charger->dev, "USB mode. connector type: %d\n", in rt5033_charger_extcon_work()
614 ret = rt5033_charger_set_charging(charger); in rt5033_charger_extcon_work()
616 dev_err(charger->dev, "failed to set charging\n"); in rt5033_charger_extcon_work()
619 dev_info(charger->dev, "charging. connector type: %d\n", in rt5033_charger_extcon_work()
623 ret = rt5033_charger_set_otg(charger); in rt5033_charger_extcon_work()
625 dev_err(charger->dev, "failed to set OTG\n"); in rt5033_charger_extcon_work()
628 dev_info(charger->dev, "OTG enabled\n"); in rt5033_charger_extcon_work()
631 ret = rt5033_charger_set_disconnect(charger); in rt5033_charger_extcon_work()
633 dev_err(charger->dev, "failed to set disconnect\n"); in rt5033_charger_extcon_work()
636 dev_info(charger->dev, "disconnected\n"); in rt5033_charger_extcon_work()
640 power_supply_changed(charger->psy); in rt5033_charger_extcon_work()
646 struct rt5033_charger *charger = in rt5033_charger_extcon_notifier() local
649 schedule_work(&charger->extcon_work); in rt5033_charger_extcon_notifier()
655 .name = "rt5033-charger",
664 struct rt5033_charger *charger; in rt5033_charger_probe() local
669 charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); in rt5033_charger_probe()
670 if (!charger) in rt5033_charger_probe()
671 return -ENOMEM; in rt5033_charger_probe()
673 platform_set_drvdata(pdev, charger); in rt5033_charger_probe()
674 charger->dev = &pdev->dev; in rt5033_charger_probe()
675 charger->regmap = dev_get_regmap(pdev->dev.parent, NULL); in rt5033_charger_probe()
676 mutex_init(&charger->lock); in rt5033_charger_probe()
678 psy_cfg.of_node = pdev->dev.of_node; in rt5033_charger_probe()
679 psy_cfg.drv_data = charger; in rt5033_charger_probe()
681 charger->psy = devm_power_supply_register(charger->dev, in rt5033_charger_probe()
684 if (IS_ERR(charger->psy)) in rt5033_charger_probe()
685 return dev_err_probe(charger->dev, PTR_ERR(charger->psy), in rt5033_charger_probe()
688 ret = rt5033_charger_dt_init(charger); in rt5033_charger_probe()
692 ret = rt5033_charger_reg_init(charger); in rt5033_charger_probe()
697 * Extcon support is not vital for the charger to work. If no extcon in rt5033_charger_probe()
700 np_conn = of_parse_phandle(pdev->dev.of_node, "richtek,usb-connector", 0); in rt5033_charger_probe()
702 charger->edev = extcon_find_edev_by_node(np_edev); in rt5033_charger_probe()
703 if (IS_ERR(charger->edev)) { in rt5033_charger_probe()
704 dev_warn(charger->dev, "no extcon device found in device-tree\n"); in rt5033_charger_probe()
708 ret = devm_work_autocancel(charger->dev, &charger->extcon_work, in rt5033_charger_probe()
711 dev_err(charger->dev, "failed to initialize extcon work\n"); in rt5033_charger_probe()
715 charger->extcon_nb.notifier_call = rt5033_charger_extcon_notifier; in rt5033_charger_probe()
716 ret = devm_extcon_register_notifier_all(charger->dev, charger->edev, in rt5033_charger_probe()
717 &charger->extcon_nb); in rt5033_charger_probe()
719 dev_err(charger->dev, "failed to register extcon notifier\n"); in rt5033_charger_probe()
727 { "rt5033-charger", },
733 { .compatible = "richtek,rt5033-charger", },
740 .name = "rt5033-charger",
748 MODULE_DESCRIPTION("Richtek RT5033 charger driver");