Lines Matching +full:current +full:- +full:boost +full:- +full:limit

1 // SPDX-License-Identifier: GPL-2.0-or-later
21 #define RT9455_DRIVER_NAME "rt9455-charger"
165 #define GET_MASK(fid) (BIT(rt9455_reg_fields[fid].msb + 1) - \
169 * Each array initialised below shows the possible real-world values for a
171 * ascending order. The index of each real-world value represents the value
197 * When the charger is in boost mode, REG02[7:2] represent boost output
200 /* REG02[7:2] (Boost output voltage) in uV */
265 for (i = 0; i < tbl_size - 1; i++) in rt9455_find_idx()
269 return (tbl_size - 1); in rt9455_find_idx()
279 ret = regmap_field_read(info->regmap_fields[field], &v); in rt9455_get_field_val()
283 v = (v >= tbl_size) ? (tbl_size - 1) : v; in rt9455_get_field_val()
295 return regmap_field_write(info->regmap_fields[field], idx); in rt9455_set_field_val()
300 struct device *dev = &info->client->dev; in rt9455_register_reset()
302 int ret, limit = 100; in rt9455_register_reset() local
304 ret = regmap_field_write(info->regmap_fields[F_RST], 0x01); in rt9455_register_reset()
315 ret = regmap_field_read(info->regmap_fields[F_RST], &v); in rt9455_register_reset()
325 } while (--limit); in rt9455_register_reset()
327 if (!limit) in rt9455_register_reset()
328 return -EIO; in rt9455_register_reset()
350 "main-battery",
359 ret = regmap_field_read(info->regmap_fields[F_PWR_RDY], in rt9455_charger_get_status()
362 dev_err(&info->client->dev, "Failed to read PWR_RDY bit\n"); in rt9455_charger_get_status()
371 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; in rt9455_charger_get_status()
375 ret = regmap_field_read(info->regmap_fields[F_STAT], &v); in rt9455_charger_get_status()
377 dev_err(&info->client->dev, "Failed to read STAT bits\n"); in rt9455_charger_get_status()
391 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in rt9455_charger_get_status()
394 val->intval = POWER_SUPPLY_STATUS_CHARGING; in rt9455_charger_get_status()
397 val->intval = POWER_SUPPLY_STATUS_FULL; in rt9455_charger_get_status()
400 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in rt9455_charger_get_status()
408 struct device *dev = &info->client->dev; in rt9455_charger_get_health()
412 val->intval = POWER_SUPPLY_HEALTH_GOOD; in rt9455_charger_get_health()
414 ret = regmap_read(info->regmap, RT9455_REG_IRQ1, &v); in rt9455_charger_get_health()
421 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; in rt9455_charger_get_health()
425 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; in rt9455_charger_get_health()
429 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
433 ret = regmap_read(info->regmap, RT9455_REG_IRQ2, &v); in rt9455_charger_get_health()
440 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
444 val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; in rt9455_charger_get_health()
448 ret = regmap_read(info->regmap, RT9455_REG_IRQ3, &v); in rt9455_charger_get_health()
455 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
459 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; in rt9455_charger_get_health()
463 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
467 val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; in rt9455_charger_get_health()
471 ret = regmap_field_read(info->regmap_fields[F_STAT], &v); in rt9455_charger_get_health()
478 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
491 ret = regmap_field_read(info->regmap_fields[F_BATAB], &v); in rt9455_charger_get_battery_presence()
493 dev_err(&info->client->dev, "Failed to read BATAB bit\n"); in rt9455_charger_get_battery_presence()
501 val->intval = !v; in rt9455_charger_get_battery_presence()
512 ret = regmap_field_read(info->regmap_fields[F_PWR_RDY], &v); in rt9455_charger_get_online()
514 dev_err(&info->client->dev, "Failed to read PWR_RDY bit\n"); in rt9455_charger_get_online()
518 val->intval = (int)v; in rt9455_charger_get_online()
534 dev_err(&info->client->dev, "Failed to read ICHRG value\n"); in rt9455_charger_get_current()
538 val->intval = curr; in rt9455_charger_get_current()
546 int idx = ARRAY_SIZE(rt9455_ichrg_values) - 1; in rt9455_charger_get_current_max()
548 val->intval = rt9455_ichrg_values[idx]; in rt9455_charger_get_current_max()
564 dev_err(&info->client->dev, "Failed to read VOREG value\n"); in rt9455_charger_get_voltage()
568 val->intval = voltage; in rt9455_charger_get_voltage()
576 int idx = ARRAY_SIZE(rt9455_vmreg_values) - 1; in rt9455_charger_get_voltage_max()
578 val->intval = rt9455_vmreg_values[idx]; in rt9455_charger_get_voltage_max()
586 struct device *dev = &info->client->dev; in rt9455_charger_get_term_current()
607 val->intval = ichrg * ieoc_percentage / 100; in rt9455_charger_get_term_current()
636 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; in rt9455_charger_get_property()
641 val->strval = RT9455_MODEL_NAME; in rt9455_charger_get_property()
644 val->strval = RT9455_MANUFACTURER; in rt9455_charger_get_property()
647 return -ENODATA; in rt9455_charger_get_property()
655 struct device *dev = &info->client->dev; in rt9455_hw_init()
665 ret = regmap_field_write(info->regmap_fields[F_TE], 1); in rt9455_hw_init()
672 ret = regmap_field_write(info->regmap_fields[F_TE_SHDN_EN], 1); in rt9455_hw_init()
682 ret = regmap_field_write(info->regmap_fields[F_BATD_EN], 1); in rt9455_hw_init()
693 * In boost mode, this timer triggers BST32SI interrupt if no read or in rt9455_hw_init()
699 ret = regmap_field_write(info->regmap_fields[F_TMR_EN], 0x00); in rt9455_hw_init()
705 /* Set ICHRG to value retrieved from device-specific data */ in rt9455_hw_init()
714 /* Set IEOC Percentage to value retrieved from device-specific data */ in rt9455_hw_init()
724 /* Set VOREG to value retrieved from device-specific data */ in rt9455_hw_init()
728 info->voreg); in rt9455_hw_init()
735 idx = ARRAY_SIZE(rt9455_vmreg_values) - 1; in rt9455_hw_init()
746 * Set MIVR to value retrieved from device-specific data. in rt9455_hw_init()
749 if (mivr == -1) in rt9455_hw_init()
761 * Set IAICR to value retrieved from device-specific data. in rt9455_hw_init()
764 if (iaicr == -1) in rt9455_hw_init()
779 ret = regmap_field_write(info->regmap_fields[F_IAICR_INT], 0x01); in rt9455_hw_init()
790 ret = regmap_field_write(info->regmap_fields[F_CHMIVRIM], 0x01); in rt9455_hw_init()
801 * Before setting the charger into boost mode, boost output voltage is
802 * set. This is needed because boost output voltage may differ from battery
804 * or boost output voltage, depending on the mode the charger is. Both battery
805 * regulation voltage and boost output voltage are read from DT/ACPI during
810 struct device *dev = &info->client->dev; in rt9455_set_boost_voltage_before_boost_mode()
816 info->boost_voltage); in rt9455_set_boost_voltage_before_boost_mode()
818 dev_err(dev, "Failed to set boost output voltage value\n"); in rt9455_set_boost_voltage_before_boost_mode()
828 * set. This is needed because boost output voltage may differ from battery
830 * or boost output voltage, depending on the mode the charger is. Both battery
831 * regulation voltage and boost output voltage are read from DT/ACPI during
836 struct device *dev = &info->client->dev; in rt9455_set_voreg_before_charge_mode()
842 info->voreg); in rt9455_set_voreg_before_charge_mode()
856 struct device *dev = &info->client->dev; in rt9455_irq_handler_check_irq1_register()
861 ret = regmap_read(info->regmap, RT9455_REG_IRQ1, &irq1); in rt9455_irq_handler_check_irq1_register()
867 ret = regmap_read(info->regmap, RT9455_REG_MASK1, &mask1); in rt9455_irq_handler_check_irq1_register()
889 ret = regmap_field_write(info->regmap_fields[F_BATABM], in rt9455_irq_handler_check_irq1_register()
897 ret = regmap_read(info->regmap, RT9455_REG_MASK2, &mask2); in rt9455_irq_handler_check_irq1_register()
905 info->regmap_fields[F_CHTERMIM], 0x00); in rt9455_irq_handler_check_irq1_register()
914 info->regmap_fields[F_CHRCHGIM], 0x00); in rt9455_irq_handler_check_irq1_register()
925 cancel_delayed_work_sync(&info->max_charging_time_work); in rt9455_irq_handler_check_irq1_register()
933 &info->batt_presence_work, in rt9455_irq_handler_check_irq1_register()
950 struct device *dev = &info->client->dev; in rt9455_irq_handler_check_irq2_register()
954 ret = regmap_read(info->regmap, RT9455_REG_IRQ2, &irq2); in rt9455_irq_handler_check_irq2_register()
960 ret = regmap_read(info->regmap, RT9455_REG_MASK2, &mask2); in rt9455_irq_handler_check_irq2_register()
980 &info->pwr_rdy_work, in rt9455_irq_handler_check_irq2_register()
992 info->regmap_fields[F_CHTERMIM], 0x01); in rt9455_irq_handler_check_irq2_register()
1003 cancel_delayed_work_sync(&info->max_charging_time_work); in rt9455_irq_handler_check_irq2_register()
1009 ret = regmap_field_write(info->regmap_fields[F_CHG_EN], in rt9455_irq_handler_check_irq2_register()
1017 info->regmap_fields[F_CHTERMIM], 0x00); in rt9455_irq_handler_check_irq2_register()
1033 &info->max_charging_time_work, in rt9455_irq_handler_check_irq2_register()
1062 struct device *dev = &info->client->dev; in rt9455_irq_handler_check_irq3_register()
1066 ret = regmap_read(info->regmap, RT9455_REG_IRQ3, &irq3); in rt9455_irq_handler_check_irq3_register()
1072 ret = regmap_read(info->regmap, RT9455_REG_MASK3, &mask3); in rt9455_irq_handler_check_irq3_register()
1079 dev_err(dev, "Boost fault. Overvoltage input occurred\n"); in rt9455_irq_handler_check_irq3_register()
1083 dev_err(dev, "Boost fault. Overload\n"); in rt9455_irq_handler_check_irq3_register()
1087 dev_err(dev, "Boost fault. Battery voltage too low\n"); in rt9455_irq_handler_check_irq3_register()
1091 dev_err(dev, "Boost fault. 32 seconds timeout occurred.\n"); in rt9455_irq_handler_check_irq3_register()
1096 dev_info(dev, "Boost fault occurred, therefore the charger goes into charge mode\n"); in rt9455_irq_handler_check_irq3_register()
1102 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_irq_handler_check_irq3_register()
1126 dev = &info->client->dev; in rt9455_irq_handler_thread()
1128 if (irq != info->client->irq) { in rt9455_irq_handler_thread()
1133 ret = regmap_field_read(info->regmap_fields[F_STAT], &status); in rt9455_irq_handler_thread()
1177 if (info->charger) in rt9455_irq_handler_thread()
1178 power_supply_changed(info->charger); in rt9455_irq_handler_thread()
1188 struct device *dev = &info->client->dev; in rt9455_discover_charger()
1191 if (!dev->of_node && !ACPI_HANDLE(dev)) { in rt9455_discover_charger()
1193 return -EINVAL; in rt9455_discover_charger()
1196 * ICHRG, IEOC_PERCENTAGE, VOREG and boost output voltage are mandatory in rt9455_discover_charger()
1199 ret = device_property_read_u32(dev, "richtek,output-charge-current", in rt9455_discover_charger()
1202 dev_err(dev, "Error: missing \"output-charge-current\" property\n"); in rt9455_discover_charger()
1206 ret = device_property_read_u32(dev, "richtek,end-of-charge-percentage", in rt9455_discover_charger()
1209 dev_err(dev, "Error: missing \"end-of-charge-percentage\" property\n"); in rt9455_discover_charger()
1214 "richtek,battery-regulation-voltage", in rt9455_discover_charger()
1215 &info->voreg); in rt9455_discover_charger()
1217 dev_err(dev, "Error: missing \"battery-regulation-voltage\" property\n"); in rt9455_discover_charger()
1221 ret = device_property_read_u32(dev, "richtek,boost-output-voltage", in rt9455_discover_charger()
1222 &info->boost_voltage); in rt9455_discover_charger()
1224 dev_err(dev, "Error: missing \"boost-output-voltage\" property\n"); in rt9455_discover_charger()
1232 device_property_read_u32(dev, "richtek,min-input-voltage-regulation", in rt9455_discover_charger()
1234 device_property_read_u32(dev, "richtek,avg-input-current-regulation", in rt9455_discover_charger()
1244 struct device *dev = &info->client->dev; in rt9455_usb_event_none()
1254 * If the charger is in boost mode, and it has received in rt9455_usb_event_none()
1260 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_none()
1270 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_none()
1284 struct device *dev = &info->client->dev; in rt9455_usb_event_vbus()
1294 * If the charger is in boost mode, and it has received in rt9455_usb_event_vbus()
1300 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_vbus()
1310 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_vbus()
1324 struct device *dev = &info->client->dev; in rt9455_usb_event_id()
1330 dev_err(dev, "Failed to set boost output voltage before entering boost mode\n"); in rt9455_usb_event_id()
1337 * In this case, the charger goes into boost mode. in rt9455_usb_event_id()
1339 dev_dbg(dev, "USB_EVENT_ID received, therefore the charger goes into boost mode\n"); in rt9455_usb_event_id()
1340 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_id()
1343 dev_err(dev, "Failed to set charger in boost mode\n"); in rt9455_usb_event_id()
1350 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_id()
1364 struct device *dev = &info->client->dev; in rt9455_usb_event_charger()
1374 * If the charger is in boost mode, and it has received in rt9455_usb_event_charger()
1380 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_charger()
1388 dev_dbg(dev, "USB_EVENT_CHARGER received, therefore IAICR is set to no current limit\n"); in rt9455_usb_event_charger()
1390 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_charger()
1405 struct device *dev = &info->client->dev; in rt9455_usb_event()
1411 * or in boost mode. in rt9455_usb_event()
1413 ret = regmap_field_read(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event()
1420 ret = regmap_field_read(info->regmap_fields[F_IAICR], in rt9455_usb_event()
1448 struct device *dev = &info->client->dev; in rt9455_pwr_rdy_work_callback()
1452 ret = regmap_field_read(info->regmap_fields[F_PWR_RDY], &pwr_rdy); in rt9455_pwr_rdy_work_callback()
1460 cancel_delayed_work_sync(&info->max_charging_time_work); in rt9455_pwr_rdy_work_callback()
1464 ret = regmap_field_write(info->regmap_fields[F_CHG_EN], in rt9455_pwr_rdy_work_callback()
1471 &info->max_charging_time_work, in rt9455_pwr_rdy_work_callback()
1479 power_supply_changed(info->charger); in rt9455_pwr_rdy_work_callback()
1486 struct device *dev = &info->client->dev; in rt9455_max_charging_time_work_callback()
1490 ret = regmap_field_write(info->regmap_fields[F_CHG_EN], in rt9455_max_charging_time_work_callback()
1500 struct device *dev = &info->client->dev; in rt9455_batt_presence_work_callback()
1504 ret = regmap_read(info->regmap, RT9455_REG_IRQ1, &irq1); in rt9455_batt_presence_work_callback()
1516 &info->batt_presence_work, in rt9455_batt_presence_work_callback()
1520 &info->max_charging_time_work, in rt9455_batt_presence_work_callback()
1523 ret = regmap_read(info->regmap, RT9455_REG_MASK1, &mask1); in rt9455_batt_presence_work_callback()
1530 ret = regmap_field_write(info->regmap_fields[F_BATABM], in rt9455_batt_presence_work_callback()
1539 power_supply_changed(info->charger); in rt9455_batt_presence_work_callback()
1587 struct i2c_adapter *adapter = client->adapter; in rt9455_probe()
1588 struct device *dev = &client->dev; in rt9455_probe()
1592 * Mandatory device-specific data values. Also, VOREG and boost output in rt9455_probe()
1597 /* Optional device-specific data values. */ in rt9455_probe()
1598 u32 mivr = -1, iaicr = -1; in rt9455_probe()
1603 return -ENODEV; in rt9455_probe()
1607 return -ENOMEM; in rt9455_probe()
1609 info->client = client; in rt9455_probe()
1612 info->regmap = devm_regmap_init_i2c(client, in rt9455_probe()
1614 if (IS_ERR(info->regmap)) { in rt9455_probe()
1616 return -EINVAL; in rt9455_probe()
1620 info->regmap_fields[i] = in rt9455_probe()
1621 devm_regmap_field_alloc(dev, info->regmap, in rt9455_probe()
1623 if (IS_ERR(info->regmap_fields[i])) { in rt9455_probe()
1626 return PTR_ERR(info->regmap_fields[i]); in rt9455_probe()
1638 info->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); in rt9455_probe()
1639 if (IS_ERR(info->usb_phy)) { in rt9455_probe()
1642 info->nb.notifier_call = rt9455_usb_event; in rt9455_probe()
1643 ret = usb_register_notifier(info->usb_phy, &info->nb); in rt9455_probe()
1650 info->nb.notifier_call = NULL; in rt9455_probe()
1655 INIT_DEFERRABLE_WORK(&info->pwr_rdy_work, rt9455_pwr_rdy_work_callback); in rt9455_probe()
1656 INIT_DEFERRABLE_WORK(&info->max_charging_time_work, in rt9455_probe()
1658 INIT_DEFERRABLE_WORK(&info->batt_presence_work, in rt9455_probe()
1661 rt9455_charger_config.of_node = dev->of_node; in rt9455_probe()
1666 ret = devm_request_threaded_irq(dev, client->irq, NULL, in rt9455_probe()
1681 info->charger = devm_power_supply_register(dev, &rt9455_charger_desc, in rt9455_probe()
1683 if (IS_ERR(info->charger)) { in rt9455_probe()
1685 ret = PTR_ERR(info->charger); in rt9455_probe()
1693 if (info->nb.notifier_call) { in rt9455_probe()
1694 usb_unregister_notifier(info->usb_phy, &info->nb); in rt9455_probe()
1695 info->nb.notifier_call = NULL; in rt9455_probe()
1708 dev_err(&info->client->dev, "Failed to set charger to its default values\n"); in rt9455_remove()
1711 if (info->nb.notifier_call) in rt9455_remove()
1712 usb_unregister_notifier(info->usb_phy, &info->nb); in rt9455_remove()
1715 cancel_delayed_work_sync(&info->pwr_rdy_work); in rt9455_remove()
1716 cancel_delayed_work_sync(&info->max_charging_time_work); in rt9455_remove()
1717 cancel_delayed_work_sync(&info->batt_presence_work); in rt9455_remove()
1753 MODULE_AUTHOR("Anda-Maria Nicolae <anda-maria.nicolae@intel.com>");