Lines Matching +full:charger +full:- +full:sense +full:- +full:resistor +full:- +full:ohms

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * TI BQ25890 charger driver
86 u8 rbatcomp; /* IBAT sense resistor value */
102 struct power_supply *charger; member
251 * Most of the val -> idx conversions can be computed, given the minimum,
320 ret = regmap_field_read(bq->rmap_fields[field_id], &val); in bq25890_field_read()
330 return regmap_field_write(bq->rmap_fields[field_id], val); in bq25890_field_write()
347 rtbl_size = (rtbl->max - rtbl->min) / rtbl->step + 1; in bq25890_find_idx()
350 idx < rtbl_size && (idx * rtbl->step + rtbl->min <= value); in bq25890_find_idx()
355 return idx - 1; in bq25890_find_idx()
369 return (rtbl->min + idx * rtbl->step); in bq25890_find_val()
409 mutex_lock(&bq->lock); in bq25890_power_supply_get_property()
412 state = bq->state; in bq25890_power_supply_get_property()
416 mutex_unlock(&bq->lock); in bq25890_power_supply_get_property()
419 regmap_field_read_poll_timeout(bq->rmap_fields[F_CONV_START], in bq25890_power_supply_get_property()
425 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; in bq25890_power_supply_get_property()
427 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in bq25890_power_supply_get_property()
430 val->intval = POWER_SUPPLY_STATUS_CHARGING; in bq25890_power_supply_get_property()
432 val->intval = POWER_SUPPLY_STATUS_FULL; in bq25890_power_supply_get_property()
434 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in bq25890_power_supply_get_property()
441 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; in bq25890_power_supply_get_property()
443 val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD; in bq25890_power_supply_get_property()
445 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; in bq25890_power_supply_get_property()
447 val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; in bq25890_power_supply_get_property()
451 val->strval = BQ25890_MANUFACTURER; in bq25890_power_supply_get_property()
455 val->strval = bq25890_chip_name[bq->chip_version]; in bq25890_power_supply_get_property()
459 val->intval = state.online; in bq25890_power_supply_get_property()
464 val->intval = POWER_SUPPLY_HEALTH_GOOD; in bq25890_power_supply_get_property()
466 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; in bq25890_power_supply_get_property()
468 val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; in bq25890_power_supply_get_property()
470 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; in bq25890_power_supply_get_property()
472 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in bq25890_power_supply_get_property()
476 val->intval = bq25890_find_val(bq->init_data.ichg, TBL_ICHG); in bq25890_power_supply_get_property()
481 val->intval = 0; in bq25890_power_supply_get_property()
490 val->intval = 2304000 + ret * 20000; in bq25890_power_supply_get_property()
494 val->intval = bq25890_find_val(bq->init_data.vreg, TBL_VREG); in bq25890_power_supply_get_property()
498 val->intval = bq25890_find_val(bq->init_data.iprechg, TBL_ITERM); in bq25890_power_supply_get_property()
502 val->intval = bq25890_find_val(bq->init_data.iterm, TBL_ITERM); in bq25890_power_supply_get_property()
510 val->intval = bq25890_find_val(ret, TBL_IILIM); in bq25890_power_supply_get_property()
519 val->intval = 2304000 + ret * 20000; in bq25890_power_supply_get_property()
528 val->intval = ret * -50000; in bq25890_power_supply_get_property()
532 return -EINVAL; in bq25890_power_supply_get_property()
547 {F_CHG_STAT, &state->chrg_status}, in bq25890_get_chip_state()
548 {F_PG_STAT, &state->online}, in bq25890_get_chip_state()
549 {F_VSYS_STAT, &state->vsys_status}, in bq25890_get_chip_state()
550 {F_BOOST_FAULT, &state->boost_fault}, in bq25890_get_chip_state()
551 {F_BAT_FAULT, &state->bat_fault}, in bq25890_get_chip_state()
552 {F_CHG_FAULT, &state->chrg_fault} in bq25890_get_chip_state()
563 dev_dbg(bq->dev, "S:CHG/PG/VSYS=%d/%d/%d, F:CHG/BOOST/BAT=%d/%d/%d\n", in bq25890_get_chip_state()
564 state->chrg_status, state->online, state->vsys_status, in bq25890_get_chip_state()
565 state->chrg_fault, state->boost_fault, state->bat_fault); in bq25890_get_chip_state()
579 if (!memcmp(&bq->state, &new_state, sizeof(new_state))) in __bq25890_handle_irq()
582 if (!new_state.online && bq->state.online) { /* power removed */ in __bq25890_handle_irq()
587 } else if (new_state.online && !bq->state.online) { /* power inserted */ in __bq25890_handle_irq()
594 bq->state = new_state; in __bq25890_handle_irq()
595 power_supply_changed(bq->charger); in __bq25890_handle_irq()
599 dev_err(bq->dev, "Error communicating with the chip: %pe\n", in __bq25890_handle_irq()
609 mutex_lock(&bq->lock); in bq25890_irq_handler_thread()
611 mutex_unlock(&bq->lock); in bq25890_irq_handler_thread()
631 } while (ret == 1 && --rst_check_counter); in bq25890_chip_reset()
634 return -ETIMEDOUT; in bq25890_chip_reset()
648 {F_ICHG, bq->init_data.ichg}, in bq25890_hw_init()
649 {F_VREG, bq->init_data.vreg}, in bq25890_hw_init()
650 {F_ITERM, bq->init_data.iterm}, in bq25890_hw_init()
651 {F_IPRECHG, bq->init_data.iprechg}, in bq25890_hw_init()
652 {F_SYSVMIN, bq->init_data.sysvmin}, in bq25890_hw_init()
653 {F_BOOSTV, bq->init_data.boostv}, in bq25890_hw_init()
654 {F_BOOSTI, bq->init_data.boosti}, in bq25890_hw_init()
655 {F_BOOSTF, bq->init_data.boostf}, in bq25890_hw_init()
656 {F_EN_ILIM, bq->init_data.ilim_en}, in bq25890_hw_init()
657 {F_TREG, bq->init_data.treg}, in bq25890_hw_init()
658 {F_BATCMP, bq->init_data.rbatcomp}, in bq25890_hw_init()
659 {F_VCLAMP, bq->init_data.vclamp}, in bq25890_hw_init()
664 dev_dbg(bq->dev, "Reset failed %d\n", ret); in bq25890_hw_init()
671 dev_dbg(bq->dev, "Disabling watchdog failed %d\n", ret); in bq25890_hw_init()
680 dev_dbg(bq->dev, "Writing init data failed %d\n", ret); in bq25890_hw_init()
686 ret = bq25890_field_write(bq, F_CONV_RATE, !!bq->state.online); in bq25890_hw_init()
688 dev_dbg(bq->dev, "Config ADC failed %d\n", ret); in bq25890_hw_init()
692 ret = bq25890_get_chip_state(bq, &bq->state); in bq25890_hw_init()
694 dev_dbg(bq->dev, "Get state failed %d\n", ret); in bq25890_hw_init()
719 "main-battery",
723 .name = "bq25890-charger",
737 bq->charger = power_supply_register(bq->dev, &bq25890_power_supply_desc, in bq25890_power_supply_init()
740 return PTR_ERR_OR_ZERO(bq->charger); in bq25890_power_supply_init()
749 switch (bq->usb_event) { in bq25890_usb_work()
763 power_supply_changed(bq->charger); in bq25890_usb_work()
770 dev_err(bq->dev, "Error switching to boost/charger mode.\n"); in bq25890_usb_work()
779 bq->usb_event = val; in bq25890_usb_notifier()
780 queue_work(system_power_efficient_wq, &bq->usb_work); in bq25890_usb_notifier()
791 dev_err(bq->dev, "Cannot read chip ID.\n"); in bq25890_get_chip_version()
797 dev_err(bq->dev, "Cannot read chip revision.\n"); in bq25890_get_chip_version()
803 bq->chip_version = BQ25890; in bq25890_get_chip_version()
810 bq->chip_version = BQ25896; in bq25890_get_chip_version()
813 bq->chip_version = BQ25892; in bq25890_get_chip_version()
816 dev_err(bq->dev, in bq25890_get_chip_version()
819 bq->chip_version = BQ25892; in bq25890_get_chip_version()
824 bq->chip_version = BQ25895; in bq25890_get_chip_version()
828 dev_err(bq->dev, "Unknown chip ID %d\n", id); in bq25890_get_chip_version()
829 return -ENODEV; in bq25890_get_chip_version()
839 irq = devm_gpiod_get(bq->dev, BQ25890_IRQ_PIN, GPIOD_IN); in bq25890_irq_probe()
841 dev_err(bq->dev, "Could not probe irq pin.\n"); in bq25890_irq_probe()
853 struct bq25890_init_data *init = &bq->init_data; in bq25890_fw_read_u32_props()
861 {"ti,charge-current", false, TBL_ICHG, &init->ichg}, in bq25890_fw_read_u32_props()
862 {"ti,battery-regulation-voltage", false, TBL_VREG, &init->vreg}, in bq25890_fw_read_u32_props()
863 {"ti,termination-current", false, TBL_ITERM, &init->iterm}, in bq25890_fw_read_u32_props()
864 {"ti,precharge-current", false, TBL_ITERM, &init->iprechg}, in bq25890_fw_read_u32_props()
865 {"ti,minimum-sys-voltage", false, TBL_SYSVMIN, &init->sysvmin}, in bq25890_fw_read_u32_props()
866 {"ti,boost-voltage", false, TBL_BOOSTV, &init->boostv}, in bq25890_fw_read_u32_props()
867 {"ti,boost-max-current", false, TBL_BOOSTI, &init->boosti}, in bq25890_fw_read_u32_props()
870 {"ti,thermal-regulation-threshold", true, TBL_TREG, &init->treg}, in bq25890_fw_read_u32_props()
871 {"ti,ibatcomp-micro-ohms", true, TBL_RBATCOMP, &init->rbatcomp}, in bq25890_fw_read_u32_props()
872 {"ti,ibatcomp-clamp-microvolt", true, TBL_VBATCOMP, &init->vclamp}, in bq25890_fw_read_u32_props()
876 init->treg = 3; /* 120 degrees Celsius */ in bq25890_fw_read_u32_props()
877 init->rbatcomp = init->vclamp = 0; /* IBAT compensation disabled */ in bq25890_fw_read_u32_props()
880 ret = device_property_read_u32(bq->dev, props[i].name, in bq25890_fw_read_u32_props()
886 dev_err(bq->dev, "Unable to read property %d %s\n", ret, in bq25890_fw_read_u32_props()
902 struct bq25890_init_data *init = &bq->init_data; in bq25890_fw_probe()
908 init->ilim_en = device_property_read_bool(bq->dev, "ti,use-ilim-pin"); in bq25890_fw_probe()
909 init->boostf = device_property_read_bool(bq->dev, "ti,boost-low-freq"); in bq25890_fw_probe()
917 struct device *dev = &client->dev; in bq25890_probe()
924 return -ENOMEM; in bq25890_probe()
926 bq->client = client; in bq25890_probe()
927 bq->dev = dev; in bq25890_probe()
929 mutex_init(&bq->lock); in bq25890_probe()
931 bq->rmap = devm_regmap_init_i2c(client, &bq25890_regmap_config); in bq25890_probe()
932 if (IS_ERR(bq->rmap)) { in bq25890_probe()
934 return PTR_ERR(bq->rmap); in bq25890_probe()
940 bq->rmap_fields[i] = devm_regmap_field_alloc(dev, bq->rmap, in bq25890_probe()
942 if (IS_ERR(bq->rmap_fields[i])) { in bq25890_probe()
944 return PTR_ERR(bq->rmap_fields[i]); in bq25890_probe()
956 if (!dev->platform_data) { in bq25890_probe()
963 return -ENODEV; in bq25890_probe()
972 if (client->irq <= 0) in bq25890_probe()
973 client->irq = bq25890_irq_probe(bq); in bq25890_probe()
975 if (client->irq < 0) { in bq25890_probe()
977 return client->irq; in bq25890_probe()
981 bq->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); in bq25890_probe()
982 if (!IS_ERR_OR_NULL(bq->usb_phy)) { in bq25890_probe()
983 INIT_WORK(&bq->usb_work, bq25890_usb_work); in bq25890_probe()
984 bq->usb_nb.notifier_call = bq25890_usb_notifier; in bq25890_probe()
985 usb_register_notifier(bq->usb_phy, &bq->usb_nb); in bq25890_probe()
988 ret = devm_request_threaded_irq(dev, client->irq, NULL, in bq25890_probe()
1004 if (!IS_ERR_OR_NULL(bq->usb_phy)) in bq25890_probe()
1005 usb_unregister_notifier(bq->usb_phy, &bq->usb_nb); in bq25890_probe()
1014 power_supply_unregister(bq->charger); in bq25890_remove()
1016 if (!IS_ERR_OR_NULL(bq->usb_phy)) in bq25890_remove()
1017 usb_unregister_notifier(bq->usb_phy, &bq->usb_nb); in bq25890_remove()
1031 * If charger is removed, while in suspend, make sure ADC is diabled in bq25890_suspend()
1042 mutex_lock(&bq->lock); in bq25890_resume()
1044 ret = bq25890_get_chip_state(bq, &bq->state); in bq25890_resume()
1048 /* Re-enable ADC only if charger is plugged in. */ in bq25890_resume()
1049 if (bq->state.online) { in bq25890_resume()
1056 power_supply_changed(bq->charger); in bq25890_resume()
1059 mutex_unlock(&bq->lock); in bq25890_resume()
1097 .name = "bq25890-charger",
1109 MODULE_DESCRIPTION("bq25890 charger driver");