Lines Matching +full:usb +full:- +full:current +full:- +full:limit +full:- +full:microamp
1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
15 #include <linux/usb/phy.h>
153 * struct bq256xx_init_data -
154 * @ichg: fast charge current
155 * @iindpm: input current limit
157 * @iterm: termination current
158 * @iprechg: precharge current
159 * @vindpm: input voltage limit
160 * @ichg_max: maximum fast charge current
177 * struct bq256xx_state -
209 * struct bq256xx_device -
220 * @usb_work: usb work queue
253 * struct bq256xx_chip_info -
280 * @bq256xx_max_ichg: maximum charge current in microamps
350 return i - 1; in bq256xx_array_parse()
352 if (val >= array[array_size - 1]) in bq256xx_array_parse()
353 return array_size - 1; in bq256xx_array_parse()
359 if (val > array[i - 1] && val < array[i]) { in bq256xx_array_parse()
361 return i - 1; in bq256xx_array_parse()
366 return -EINVAL; in bq256xx_array_parse()
375 bq->usb_event = val; in bq256xx_usb_notifier()
376 queue_work(system_power_efficient_wq, &bq->usb_work); in bq256xx_usb_notifier()
386 switch (bq->usb_event) { in bq256xx_usb_work()
390 power_supply_changed(bq->charger); in bq256xx_usb_work()
393 dev_err(bq->dev, "Error switching to charger mode.\n"); in bq256xx_usb_work()
442 ret = regmap_read(bq->regmap, BQ256XX_CHARGER_STATUS_0, in bq256xx_get_state()
447 ret = regmap_read(bq->regmap, BQ256XX_CHARGER_STATUS_1, in bq256xx_get_state()
452 state->vbus_stat = charger_status_0 & BQ256XX_VBUS_STAT_MASK; in bq256xx_get_state()
453 state->chrg_stat = charger_status_0 & BQ256XX_CHRG_STAT_MASK; in bq256xx_get_state()
454 state->online = charger_status_0 & BQ256XX_PG_STAT_MASK; in bq256xx_get_state()
456 state->wdt_fault = charger_status_1 & BQ256XX_WDT_FAULT_MASK; in bq256xx_get_state()
457 state->bat_fault = charger_status_1 & BQ256XX_BAT_FAULT_MASK; in bq256xx_get_state()
458 state->chrg_fault = charger_status_1 & BQ256XX_CHRG_FAULT_MASK; in bq256xx_get_state()
459 state->ntc_fault = charger_status_1 & BQ256XX_NTC_FAULT_MASK; in bq256xx_get_state()
477 return -EINVAL; in bq256xx_set_charge_type()
480 return regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_0, in bq256xx_set_charge_type()
491 ret = regmap_read(bq->regmap, BQ256XX_CHARGE_CURRENT_LIMIT, in bq256xx_get_ichg_curr()
507 ret = regmap_read(bq->regmap, BQ256XX_CHARGE_CURRENT_LIMIT, in bq25618_619_get_ichg_curr()
517 return bq25618_619_ichg_values[ichg_reg_code - BQ25618_ICHG_THRESH]; in bq25618_619_get_ichg_curr()
523 int ichg_max = bq->init_data.ichg_max; in bq256xx_set_ichg_curr()
528 return regmap_update_bits(bq->regmap, BQ256XX_CHARGE_CURRENT_LIMIT, in bq256xx_set_ichg_curr()
536 int ichg_max = bq->init_data.ichg_max; in bq25618_619_set_ichg_curr()
547 return regmap_update_bits(bq->regmap, BQ256XX_CHARGE_CURRENT_LIMIT, in bq25618_619_set_ichg_curr()
557 ret = regmap_read(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq25618_619_get_chrg_volt()
567 return ((vbatreg_reg_code - BQ2561X_VBATREG_THRESH) * in bq25618_619_get_chrg_volt()
580 ret = regmap_read(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq25611d_get_chrg_volt()
589 return ((vbatreg_reg_code - BQ2561X_VBATREG_THRESH) * in bq25611d_get_chrg_volt()
602 ret = regmap_read(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq2560x_get_chrg_volt()
620 ret = regmap_read(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq25601d_get_chrg_volt()
636 int vbatreg_max = bq->init_data.vbatreg_max; in bq25618_619_set_chrg_volt()
641 vbatreg_reg_code = ((vbatreg - in bq25618_619_set_chrg_volt()
649 return regmap_update_bits(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq25618_619_set_chrg_volt()
658 int vbatreg_max = bq->init_data.vbatreg_max; in bq25611d_set_chrg_volt()
663 vbatreg_reg_code = ((vbatreg - in bq25611d_set_chrg_volt()
671 return regmap_update_bits(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq25611d_set_chrg_volt()
679 int vbatreg_max = bq->init_data.vbatreg_max; in bq2560x_set_chrg_volt()
683 vbatreg_reg_code = (vbatreg - BQ2560X_VBATREG_OFFSET_uV) / in bq2560x_set_chrg_volt()
686 return regmap_update_bits(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq2560x_set_chrg_volt()
694 int vbatreg_max = bq->init_data.vbatreg_max; in bq25601d_set_chrg_volt()
698 vbatreg_reg_code = (vbatreg - BQ25601D_VBATREG_OFFSET_uV) / in bq25601d_set_chrg_volt()
701 return regmap_update_bits(bq->regmap, BQ256XX_BATTERY_VOLTAGE_LIMIT, in bq25601d_set_chrg_volt()
708 return regmap_update_bits(bq->regmap, BQ256XX_INPUT_CURRENT_LIMIT, in bq256xx_set_ts_ignore()
718 ret = regmap_read(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq256xx_get_prechrg_curr()
737 iprechg_reg_code = ((iprechg - BQ256XX_IPRECHG_OFFSET_uA) / in bq256xx_set_prechrg_curr()
740 return regmap_update_bits(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq256xx_set_prechrg_curr()
750 ret = regmap_read(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq25618_619_get_prechrg_curr()
769 iprechg_reg_code = ((iprechg - BQ25618_IPRECHG_OFFSET_uA) / in bq25618_619_set_prechrg_curr()
772 return regmap_update_bits(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq25618_619_set_prechrg_curr()
782 ret = regmap_read(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq256xx_get_term_curr()
799 iterm_reg_code = (iterm - BQ256XX_ITERM_OFFSET_uA) / in bq256xx_set_term_curr()
802 return regmap_update_bits(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq256xx_set_term_curr()
812 ret = regmap_read(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq25618_619_get_term_curr()
829 iterm_reg_code = (iterm - BQ25618_ITERM_OFFSET_uA) / in bq25618_619_set_term_curr()
832 return regmap_update_bits(bq->regmap, BQ256XX_PRECHG_AND_TERM_CURR_LIM, in bq25618_619_set_term_curr()
842 ret = regmap_read(bq->regmap, BQ256XX_CHARGER_CONTROL_2, in bq256xx_get_input_volt_lim()
859 vindpm_reg_code = (vindpm - BQ256XX_VINDPM_OFFSET_uV) / in bq256xx_set_input_volt_lim()
862 return regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_2, in bq256xx_set_input_volt_lim()
872 ret = regmap_read(bq->regmap, BQ256XX_INPUT_CURRENT_LIMIT, in bq256xx_get_input_curr_lim()
889 iindpm_reg_code = (iindpm - BQ256XX_IINDPM_OFFSET_uA) / in bq256xx_set_input_curr_lim()
892 return regmap_update_bits(bq->regmap, BQ256XX_INPUT_CURRENT_LIMIT, in bq256xx_set_input_curr_lim()
900 regmap_update_bits(bq->regmap, BQ256XX_PART_INFORMATION, in bq256xx_charger_reset()
903 if (!IS_ERR_OR_NULL(bq->usb2_phy)) in bq256xx_charger_reset()
904 usb_unregister_notifier(bq->usb2_phy, &bq->usb_nb); in bq256xx_charger_reset()
906 if (!IS_ERR_OR_NULL(bq->usb3_phy)) in bq256xx_charger_reset()
907 usb_unregister_notifier(bq->usb3_phy, &bq->usb_nb); in bq256xx_charger_reset()
915 int ret = -EINVAL; in bq256xx_set_charger_property()
919 ret = bq->chip_info->bq256xx_set_iindpm(bq, val->intval); in bq256xx_set_charger_property()
928 ret = bq->chip_info->bq256xx_set_vbatreg(bq, val->intval); in bq256xx_set_charger_property()
934 ret = bq->chip_info->bq256xx_set_ichg(bq, val->intval); in bq256xx_set_charger_property()
940 ret = bq->chip_info->bq256xx_set_iprechg(bq, val->intval); in bq256xx_set_charger_property()
946 ret = bq->chip_info->bq256xx_set_iterm(bq, val->intval); in bq256xx_set_charger_property()
952 ret = bq->chip_info->bq256xx_set_vindpm(bq, val->intval); in bq256xx_set_charger_property()
958 ret = bq->chip_info->bq256xx_set_charge_type(bq, val->intval); in bq256xx_set_charger_property()
979 val->intval = bq->init_data.ichg_max; in bq256xx_get_battery_property()
983 val->intval = bq->init_data.vbatreg_max; in bq256xx_get_battery_property()
987 return -EINVAL; in bq256xx_get_battery_property()
1001 mutex_lock(&bq->lock); in bq256xx_get_charger_property()
1003 mutex_unlock(&bq->lock); in bq256xx_get_charger_property()
1011 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; in bq256xx_get_charger_property()
1013 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in bq256xx_get_charger_property()
1015 val->intval = POWER_SUPPLY_STATUS_FULL; in bq256xx_get_charger_property()
1017 val->intval = POWER_SUPPLY_STATUS_CHARGING; in bq256xx_get_charger_property()
1021 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; in bq256xx_get_charger_property()
1023 val->intval = in bq256xx_get_charger_property()
1026 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; in bq256xx_get_charger_property()
1030 val->intval = in bq256xx_get_charger_property()
1034 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; in bq256xx_get_charger_property()
1037 val->intval = in bq256xx_get_charger_property()
1046 val->intval = POWER_SUPPLY_HEALTH_WARM; in bq256xx_get_charger_property()
1049 val->intval = POWER_SUPPLY_HEALTH_COOL; in bq256xx_get_charger_property()
1052 val->intval = POWER_SUPPLY_HEALTH_COLD; in bq256xx_get_charger_property()
1055 val->intval = POWER_SUPPLY_HEALTH_HOT; in bq256xx_get_charger_property()
1058 val->intval = POWER_SUPPLY_HEALTH_GOOD; in bq256xx_get_charger_property()
1065 if (bq->chip_info->has_usb_detect) { in bq256xx_get_charger_property()
1068 val->intval = POWER_SUPPLY_USB_TYPE_SDP; in bq256xx_get_charger_property()
1071 val->intval = POWER_SUPPLY_USB_TYPE_CDP; in bq256xx_get_charger_property()
1074 val->intval = POWER_SUPPLY_USB_TYPE_DCP; in bq256xx_get_charger_property()
1077 val->intval = POWER_SUPPLY_USB_TYPE_ACA; in bq256xx_get_charger_property()
1080 val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN; in bq256xx_get_charger_property()
1086 val->intval = POWER_SUPPLY_USB_TYPE_SDP; in bq256xx_get_charger_property()
1089 val->intval = POWER_SUPPLY_USB_TYPE_ACA; in bq256xx_get_charger_property()
1092 val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN; in bq256xx_get_charger_property()
1101 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; in bq256xx_get_charger_property()
1104 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; in bq256xx_get_charger_property()
1107 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; in bq256xx_get_charger_property()
1110 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; in bq256xx_get_charger_property()
1113 val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; in bq256xx_get_charger_property()
1118 val->strval = BQ256XX_MANUFACTURER; in bq256xx_get_charger_property()
1122 val->strval = bq->model_name; in bq256xx_get_charger_property()
1126 val->intval = state.online; in bq256xx_get_charger_property()
1130 ret = bq->chip_info->bq256xx_get_vindpm(bq); in bq256xx_get_charger_property()
1133 val->intval = ret; in bq256xx_get_charger_property()
1137 ret = bq->chip_info->bq256xx_get_iindpm(bq); in bq256xx_get_charger_property()
1140 val->intval = ret; in bq256xx_get_charger_property()
1144 ret = bq->chip_info->bq256xx_get_vbatreg(bq); in bq256xx_get_charger_property()
1147 val->intval = ret; in bq256xx_get_charger_property()
1151 ret = bq->chip_info->bq256xx_get_ichg(bq); in bq256xx_get_charger_property()
1154 val->intval = ret; in bq256xx_get_charger_property()
1158 ret = bq->chip_info->bq256xx_get_iprechg(bq); in bq256xx_get_charger_property()
1161 val->intval = ret; in bq256xx_get_charger_property()
1165 ret = bq->chip_info->bq256xx_get_iterm(bq); in bq256xx_get_charger_property()
1168 val->intval = ret; in bq256xx_get_charger_property()
1172 return -EINVAL; in bq256xx_get_charger_property()
1183 mutex_lock(&bq->lock); in bq256xx_state_changed()
1184 old_state = bq->state; in bq256xx_state_changed()
1185 mutex_unlock(&bq->lock); in bq256xx_state_changed()
1203 mutex_lock(&bq->lock); in bq256xx_irq_handler_thread()
1204 bq->state = state; in bq256xx_irq_handler_thread()
1205 mutex_unlock(&bq->lock); in bq256xx_irq_handler_thread()
1207 power_supply_changed(bq->charger); in bq256xx_irq_handler_thread()
1253 .name = "bq256xx-charger",
1265 .name = "bq256xx-battery",
1547 bq->charger = devm_power_supply_register(bq->dev, in bq256xx_power_supply_init()
1550 if (IS_ERR(bq->charger)) { in bq256xx_power_supply_init()
1552 return PTR_ERR(bq->charger); in bq256xx_power_supply_init()
1555 bq->battery = devm_power_supply_register(bq->dev, in bq256xx_power_supply_init()
1558 if (IS_ERR(bq->battery)) { in bq256xx_power_supply_init()
1560 return PTR_ERR(bq->battery); in bq256xx_power_supply_init()
1573 if (bq->watchdog_timer == bq256xx_watchdog_time[i]) { in bq256xx_hw_init()
1577 if (bq->watchdog_timer > bq256xx_watchdog_time[i] && in bq256xx_hw_init()
1578 bq->watchdog_timer < bq256xx_watchdog_time[i + 1]) in bq256xx_hw_init()
1581 ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1, in bq256xx_hw_init()
1585 ret = power_supply_get_battery_info(bq->charger, &bat_info); in bq256xx_hw_init()
1586 if (ret == -ENOMEM) in bq256xx_hw_init()
1590 dev_warn(bq->dev, "battery info missing, default values will be applied\n"); in bq256xx_hw_init()
1592 bat_info->constant_charge_current_max_ua = in bq256xx_hw_init()
1593 bq->chip_info->bq256xx_def_ichg; in bq256xx_hw_init()
1595 bat_info->constant_charge_voltage_max_uv = in bq256xx_hw_init()
1596 bq->chip_info->bq256xx_def_vbatreg; in bq256xx_hw_init()
1598 bat_info->precharge_current_ua = in bq256xx_hw_init()
1599 bq->chip_info->bq256xx_def_iprechg; in bq256xx_hw_init()
1601 bat_info->charge_term_current_ua = in bq256xx_hw_init()
1602 bq->chip_info->bq256xx_def_iterm; in bq256xx_hw_init()
1604 bq->init_data.ichg_max = in bq256xx_hw_init()
1605 bq->chip_info->bq256xx_max_ichg; in bq256xx_hw_init()
1607 bq->init_data.vbatreg_max = in bq256xx_hw_init()
1608 bq->chip_info->bq256xx_max_vbatreg; in bq256xx_hw_init()
1610 bq->init_data.ichg_max = in bq256xx_hw_init()
1611 bat_info->constant_charge_current_max_ua; in bq256xx_hw_init()
1613 bq->init_data.vbatreg_max = in bq256xx_hw_init()
1614 bat_info->constant_charge_voltage_max_uv; in bq256xx_hw_init()
1617 ret = bq->chip_info->bq256xx_set_vindpm(bq, bq->init_data.vindpm); in bq256xx_hw_init()
1621 ret = bq->chip_info->bq256xx_set_iindpm(bq, bq->init_data.iindpm); in bq256xx_hw_init()
1625 ret = bq->chip_info->bq256xx_set_ichg(bq, in bq256xx_hw_init()
1626 bq->chip_info->bq256xx_def_ichg); in bq256xx_hw_init()
1630 ret = bq->chip_info->bq256xx_set_iprechg(bq, in bq256xx_hw_init()
1631 bat_info->precharge_current_ua); in bq256xx_hw_init()
1635 ret = bq->chip_info->bq256xx_set_vbatreg(bq, in bq256xx_hw_init()
1636 bq->chip_info->bq256xx_def_vbatreg); in bq256xx_hw_init()
1640 ret = bq->chip_info->bq256xx_set_iterm(bq, in bq256xx_hw_init()
1641 bat_info->charge_term_current_ua); in bq256xx_hw_init()
1645 if (bq->chip_info->bq256xx_set_ts_ignore) { in bq256xx_hw_init()
1646 ret = bq->chip_info->bq256xx_set_ts_ignore(bq, bq->init_data.ts_ignore); in bq256xx_hw_init()
1651 power_supply_put_battery_info(bq->charger, bat_info); in bq256xx_hw_init()
1661 psy_cfg->drv_data = bq; in bq256xx_parse_dt()
1662 psy_cfg->of_node = dev->of_node; in bq256xx_parse_dt()
1664 ret = device_property_read_u32(bq->dev, "ti,watchdog-timeout-ms", in bq256xx_parse_dt()
1665 &bq->watchdog_timer); in bq256xx_parse_dt()
1667 bq->watchdog_timer = BQ256XX_WATCHDOG_DIS; in bq256xx_parse_dt()
1669 if (bq->watchdog_timer > BQ256XX_WATCHDOG_MAX || in bq256xx_parse_dt()
1670 bq->watchdog_timer < BQ256XX_WATCHDOG_DIS) in bq256xx_parse_dt()
1671 return -EINVAL; in bq256xx_parse_dt()
1673 ret = device_property_read_u32(bq->dev, in bq256xx_parse_dt()
1674 "input-voltage-limit-microvolt", in bq256xx_parse_dt()
1675 &bq->init_data.vindpm); in bq256xx_parse_dt()
1677 bq->init_data.vindpm = bq->chip_info->bq256xx_def_vindpm; in bq256xx_parse_dt()
1679 ret = device_property_read_u32(bq->dev, in bq256xx_parse_dt()
1680 "input-current-limit-microamp", in bq256xx_parse_dt()
1681 &bq->init_data.iindpm); in bq256xx_parse_dt()
1683 bq->init_data.iindpm = bq->chip_info->bq256xx_def_iindpm; in bq256xx_parse_dt()
1685 bq->init_data.ts_ignore = device_property_read_bool(bq->dev, "ti,no-thermistor"); in bq256xx_parse_dt()
1693 struct device *dev = &client->dev; in bq256xx_probe()
1701 return -ENOMEM; in bq256xx_probe()
1703 bq->client = client; in bq256xx_probe()
1704 bq->dev = dev; in bq256xx_probe()
1705 bq->chip_info = &bq256xx_chip_info_tbl[id->driver_data]; in bq256xx_probe()
1707 mutex_init(&bq->lock); in bq256xx_probe()
1709 strncpy(bq->model_name, id->name, I2C_NAME_SIZE); in bq256xx_probe()
1711 bq->regmap = devm_regmap_init_i2c(client, in bq256xx_probe()
1712 bq->chip_info->bq256xx_regmap_config); in bq256xx_probe()
1714 if (IS_ERR(bq->regmap)) { in bq256xx_probe()
1716 return PTR_ERR(bq->regmap); in bq256xx_probe()
1732 bq->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); in bq256xx_probe()
1733 if (!IS_ERR_OR_NULL(bq->usb2_phy)) { in bq256xx_probe()
1734 INIT_WORK(&bq->usb_work, bq256xx_usb_work); in bq256xx_probe()
1735 bq->usb_nb.notifier_call = bq256xx_usb_notifier; in bq256xx_probe()
1736 usb_register_notifier(bq->usb2_phy, &bq->usb_nb); in bq256xx_probe()
1739 bq->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3); in bq256xx_probe()
1740 if (!IS_ERR_OR_NULL(bq->usb3_phy)) { in bq256xx_probe()
1741 INIT_WORK(&bq->usb_work, bq256xx_usb_work); in bq256xx_probe()
1742 bq->usb_nb.notifier_call = bq256xx_usb_notifier; in bq256xx_probe()
1743 usb_register_notifier(bq->usb3_phy, &bq->usb_nb); in bq256xx_probe()
1746 if (client->irq) { in bq256xx_probe()
1747 ret = devm_request_threaded_irq(dev, client->irq, NULL, in bq256xx_probe()
1751 dev_name(&client->dev), bq); in bq256xx_probe()
1811 .name = "bq256xx-charger",
1820 MODULE_AUTHOR("Ricardo Rivera-Matos <r-rivera-matos@ti.com>");