Lines Matching +full:battery +full:- +full:powered

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for Richtek RT9455WSC battery charger.
22 #define RT9455_DRIVER_NAME "rt9455-charger"
166 #define GET_MASK(fid) (BIT(rt9455_reg_fields[fid].msb + 1) - \
170 * Each array initialised below shows the possible real-world values for a
172 * ascending order. The index of each real-world value represents the value
181 * When the charger is in charge mode, REG02[7:2] represent battery regulation
264 for (i = 0; i < tbl_size - 1; i++) in rt9455_find_idx()
268 return (tbl_size - 1); in rt9455_find_idx()
278 ret = regmap_field_read(info->regmap_fields[field], &v); in rt9455_get_field_val()
282 v = (v >= tbl_size) ? (tbl_size - 1) : v; in rt9455_get_field_val()
294 return regmap_field_write(info->regmap_fields[field], idx); in rt9455_set_field_val()
299 struct device *dev = &info->client->dev; in rt9455_register_reset()
303 ret = regmap_field_write(info->regmap_fields[F_RST], 0x01); in rt9455_register_reset()
314 ret = regmap_field_read(info->regmap_fields[F_RST], &v); in rt9455_register_reset()
324 } while (--limit); in rt9455_register_reset()
327 return -EIO; in rt9455_register_reset()
349 "main-battery",
358 ret = regmap_field_read(info->regmap_fields[F_PWR_RDY], in rt9455_charger_get_status()
361 dev_err(&info->client->dev, "Failed to read PWR_RDY bit\n"); in rt9455_charger_get_status()
366 * If PWR_RDY bit is unset, the battery is discharging. Otherwise, in rt9455_charger_get_status()
370 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; in rt9455_charger_get_status()
374 ret = regmap_field_read(info->regmap_fields[F_STAT], &v); in rt9455_charger_get_status()
376 dev_err(&info->client->dev, "Failed to read STAT bits\n"); in rt9455_charger_get_status()
386 * 2. CHG_EN bit is 1 but the battery is not connected. in rt9455_charger_get_status()
390 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in rt9455_charger_get_status()
393 val->intval = POWER_SUPPLY_STATUS_CHARGING; in rt9455_charger_get_status()
396 val->intval = POWER_SUPPLY_STATUS_FULL; in rt9455_charger_get_status()
399 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in rt9455_charger_get_status()
407 struct device *dev = &info->client->dev; in rt9455_charger_get_health()
411 val->intval = POWER_SUPPLY_HEALTH_GOOD; in rt9455_charger_get_health()
413 ret = regmap_read(info->regmap, RT9455_REG_IRQ1, &v); in rt9455_charger_get_health()
420 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; in rt9455_charger_get_health()
424 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; in rt9455_charger_get_health()
428 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
432 ret = regmap_read(info->regmap, RT9455_REG_IRQ2, &v); in rt9455_charger_get_health()
439 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
443 val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; in rt9455_charger_get_health()
447 ret = regmap_read(info->regmap, RT9455_REG_IRQ3, &v); in rt9455_charger_get_health()
454 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
458 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; in rt9455_charger_get_health()
462 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
466 val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; in rt9455_charger_get_health()
470 ret = regmap_field_read(info->regmap_fields[F_STAT], &v); in rt9455_charger_get_health()
477 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in rt9455_charger_get_health()
490 ret = regmap_field_read(info->regmap_fields[F_BATAB], &v); in rt9455_charger_get_battery_presence()
492 dev_err(&info->client->dev, "Failed to read BATAB bit\n"); in rt9455_charger_get_battery_presence()
497 * Since BATAB is 1 when battery is NOT present and 0 otherwise, in rt9455_charger_get_battery_presence()
500 val->intval = !v; in rt9455_charger_get_battery_presence()
511 ret = regmap_field_read(info->regmap_fields[F_PWR_RDY], &v); in rt9455_charger_get_online()
513 dev_err(&info->client->dev, "Failed to read PWR_RDY bit\n"); in rt9455_charger_get_online()
517 val->intval = (int)v; in rt9455_charger_get_online()
533 dev_err(&info->client->dev, "Failed to read ICHRG value\n"); in rt9455_charger_get_current()
537 val->intval = curr; in rt9455_charger_get_current()
545 int idx = ARRAY_SIZE(rt9455_ichrg_values) - 1; in rt9455_charger_get_current_max()
547 val->intval = rt9455_ichrg_values[idx]; in rt9455_charger_get_current_max()
563 dev_err(&info->client->dev, "Failed to read VOREG value\n"); in rt9455_charger_get_voltage()
567 val->intval = voltage; in rt9455_charger_get_voltage()
575 int idx = ARRAY_SIZE(rt9455_vmreg_values) - 1; in rt9455_charger_get_voltage_max()
577 val->intval = rt9455_vmreg_values[idx]; in rt9455_charger_get_voltage_max()
585 struct device *dev = &info->client->dev; in rt9455_charger_get_term_current()
606 val->intval = ichrg * ieoc_percentage / 100; in rt9455_charger_get_term_current()
635 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; in rt9455_charger_get_property()
640 val->strval = RT9455_MODEL_NAME; in rt9455_charger_get_property()
643 val->strval = RT9455_MANUFACTURER; in rt9455_charger_get_property()
646 return -ENODATA; in rt9455_charger_get_property()
654 struct device *dev = &info->client->dev; in rt9455_hw_init()
664 ret = regmap_field_write(info->regmap_fields[F_TE], 1); in rt9455_hw_init()
671 ret = regmap_field_write(info->regmap_fields[F_TE_SHDN_EN], 1); in rt9455_hw_init()
678 * Set BATD_EN bit in order to enable battery detection in rt9455_hw_init()
681 ret = regmap_field_write(info->regmap_fields[F_BATD_EN], 1); in rt9455_hw_init()
696 * the battery. in rt9455_hw_init()
698 ret = regmap_field_write(info->regmap_fields[F_TMR_EN], 0x00); in rt9455_hw_init()
704 /* Set ICHRG to value retrieved from device-specific data */ in rt9455_hw_init()
713 /* Set IEOC Percentage to value retrieved from device-specific data */ in rt9455_hw_init()
723 /* Set VOREG to value retrieved from device-specific data */ in rt9455_hw_init()
727 info->voreg); in rt9455_hw_init()
734 idx = ARRAY_SIZE(rt9455_vmreg_values) - 1; in rt9455_hw_init()
745 * Set MIVR to value retrieved from device-specific data. in rt9455_hw_init()
748 if (mivr == -1) in rt9455_hw_init()
760 * Set IAICR to value retrieved from device-specific data. in rt9455_hw_init()
763 if (iaicr == -1) in rt9455_hw_init()
778 ret = regmap_field_write(info->regmap_fields[F_IAICR_INT], 0x01); in rt9455_hw_init()
789 ret = regmap_field_write(info->regmap_fields[F_CHMIVRIM], 0x01); in rt9455_hw_init()
801 * set. This is needed because boost output voltage may differ from battery
802 * regulation voltage. F_VOREG bits represent either battery regulation voltage
803 * or boost output voltage, depending on the mode the charger is. Both battery
809 struct device *dev = &info->client->dev; in rt9455_set_boost_voltage_before_boost_mode()
815 info->boost_voltage); in rt9455_set_boost_voltage_before_boost_mode()
826 * Before setting the charger into charge mode, battery regulation voltage is
827 * set. This is needed because boost output voltage may differ from battery
828 * regulation voltage. F_VOREG bits represent either battery regulation voltage
829 * or boost output voltage, depending on the mode the charger is. Both battery
835 struct device *dev = &info->client->dev; in rt9455_set_voreg_before_charge_mode()
841 info->voreg); in rt9455_set_voreg_before_charge_mode()
855 struct device *dev = &info->client->dev; in rt9455_irq_handler_check_irq1_register()
860 ret = regmap_read(info->regmap, RT9455_REG_IRQ1, &irq1); in rt9455_irq_handler_check_irq1_register()
866 ret = regmap_read(info->regmap, RT9455_REG_MASK1, &mask1); in rt9455_irq_handler_check_irq1_register()
883 dev_err(dev, "Battery absence occurred\n"); in rt9455_irq_handler_check_irq1_register()
888 ret = regmap_field_write(info->regmap_fields[F_BATABM], in rt9455_irq_handler_check_irq1_register()
896 ret = regmap_read(info->regmap, RT9455_REG_MASK2, &mask2); in rt9455_irq_handler_check_irq1_register()
904 info->regmap_fields[F_CHTERMIM], 0x00); in rt9455_irq_handler_check_irq1_register()
913 info->regmap_fields[F_CHRCHGIM], 0x00); in rt9455_irq_handler_check_irq1_register()
921 * When the battery is absent, max_charging_time_work is in rt9455_irq_handler_check_irq1_register()
924 cancel_delayed_work_sync(&info->max_charging_time_work); in rt9455_irq_handler_check_irq1_register()
926 * Since no interrupt is triggered when the battery is in rt9455_irq_handler_check_irq1_register()
929 * the battery is still absent or not. in rt9455_irq_handler_check_irq1_register()
932 &info->batt_presence_work, in rt9455_irq_handler_check_irq1_register()
949 struct device *dev = &info->client->dev; in rt9455_irq_handler_check_irq2_register()
953 ret = regmap_read(info->regmap, RT9455_REG_IRQ2, &irq2); in rt9455_irq_handler_check_irq2_register()
959 ret = regmap_read(info->regmap, RT9455_REG_MASK2, &mask2); in rt9455_irq_handler_check_irq2_register()
979 &info->pwr_rdy_work, in rt9455_irq_handler_check_irq2_register()
983 dev_err(dev, "Battery OVP occurred\n"); in rt9455_irq_handler_check_irq2_register()
991 info->regmap_fields[F_CHTERMIM], 0x01); in rt9455_irq_handler_check_irq2_register()
1002 cancel_delayed_work_sync(&info->max_charging_time_work); in rt9455_irq_handler_check_irq2_register()
1008 ret = regmap_field_write(info->regmap_fields[F_CHG_EN], in rt9455_irq_handler_check_irq2_register()
1016 info->regmap_fields[F_CHTERMIM], 0x00); in rt9455_irq_handler_check_irq2_register()
1032 &info->max_charging_time_work, in rt9455_irq_handler_check_irq2_register()
1061 struct device *dev = &info->client->dev; in rt9455_irq_handler_check_irq3_register()
1065 ret = regmap_read(info->regmap, RT9455_REG_IRQ3, &irq3); in rt9455_irq_handler_check_irq3_register()
1071 ret = regmap_read(info->regmap, RT9455_REG_MASK3, &mask3); in rt9455_irq_handler_check_irq3_register()
1086 dev_err(dev, "Boost fault. Battery voltage too low\n"); in rt9455_irq_handler_check_irq3_register()
1101 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_irq_handler_check_irq3_register()
1125 dev = &info->client->dev; in rt9455_irq_handler_thread()
1127 if (irq != info->client->irq) { in rt9455_irq_handler_thread()
1132 ret = regmap_field_read(info->regmap_fields[F_STAT], &status); in rt9455_irq_handler_thread()
1176 if (info->charger) in rt9455_irq_handler_thread()
1177 power_supply_changed(info->charger); in rt9455_irq_handler_thread()
1187 struct device *dev = &info->client->dev; in rt9455_discover_charger()
1190 if (!dev->of_node && !ACPI_HANDLE(dev)) { in rt9455_discover_charger()
1192 return -EINVAL; in rt9455_discover_charger()
1198 ret = device_property_read_u32(dev, "richtek,output-charge-current", in rt9455_discover_charger()
1201 dev_err(dev, "Error: missing \"output-charge-current\" property\n"); in rt9455_discover_charger()
1205 ret = device_property_read_u32(dev, "richtek,end-of-charge-percentage", in rt9455_discover_charger()
1208 dev_err(dev, "Error: missing \"end-of-charge-percentage\" property\n"); in rt9455_discover_charger()
1213 "richtek,battery-regulation-voltage", in rt9455_discover_charger()
1214 &info->voreg); in rt9455_discover_charger()
1216 dev_err(dev, "Error: missing \"battery-regulation-voltage\" property\n"); in rt9455_discover_charger()
1220 ret = device_property_read_u32(dev, "richtek,boost-output-voltage", in rt9455_discover_charger()
1221 &info->boost_voltage); in rt9455_discover_charger()
1223 dev_err(dev, "Error: missing \"boost-output-voltage\" property\n"); in rt9455_discover_charger()
1231 device_property_read_u32(dev, "richtek,min-input-voltage-regulation", in rt9455_discover_charger()
1233 device_property_read_u32(dev, "richtek,avg-input-current-regulation", in rt9455_discover_charger()
1243 struct device *dev = &info->client->dev; in rt9455_usb_event_none()
1254 * USB_EVENT_NONE, this means the consumer device powered by the in rt9455_usb_event_none()
1259 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_none()
1269 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_none()
1283 struct device *dev = &info->client->dev; in rt9455_usb_event_vbus()
1294 * USB_EVENT_VBUS, this means the consumer device powered by the in rt9455_usb_event_vbus()
1299 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_vbus()
1309 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_vbus()
1323 struct device *dev = &info->client->dev; in rt9455_usb_event_id()
1335 * it should be powered by the charger. in rt9455_usb_event_id()
1339 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_id()
1349 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_id()
1363 struct device *dev = &info->client->dev; in rt9455_usb_event_charger()
1374 * USB_EVENT_CHARGER, this means the consumer device powered by in rt9455_usb_event_charger()
1379 ret = regmap_field_write(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event_charger()
1389 ret = regmap_field_write(info->regmap_fields[F_IAICR], in rt9455_usb_event_charger()
1404 struct device *dev = &info->client->dev; in rt9455_usb_event()
1412 ret = regmap_field_read(info->regmap_fields[F_OPA_MODE], in rt9455_usb_event()
1419 ret = regmap_field_read(info->regmap_fields[F_IAICR], in rt9455_usb_event()
1447 struct device *dev = &info->client->dev; in rt9455_pwr_rdy_work_callback()
1451 ret = regmap_field_read(info->regmap_fields[F_PWR_RDY], &pwr_rdy); in rt9455_pwr_rdy_work_callback()
1459 cancel_delayed_work_sync(&info->max_charging_time_work); in rt9455_pwr_rdy_work_callback()
1463 ret = regmap_field_write(info->regmap_fields[F_CHG_EN], in rt9455_pwr_rdy_work_callback()
1470 &info->max_charging_time_work, in rt9455_pwr_rdy_work_callback()
1478 power_supply_changed(info->charger); in rt9455_pwr_rdy_work_callback()
1485 struct device *dev = &info->client->dev; in rt9455_max_charging_time_work_callback()
1488 …dev_err(dev, "Battery has been charging for at least 6 hours and is not yet fully charged. Battery in rt9455_max_charging_time_work_callback()
1489 ret = regmap_field_write(info->regmap_fields[F_CHG_EN], in rt9455_max_charging_time_work_callback()
1499 struct device *dev = &info->client->dev; in rt9455_batt_presence_work_callback()
1503 ret = regmap_read(info->regmap, RT9455_REG_IRQ1, &irq1); in rt9455_batt_presence_work_callback()
1510 * If the battery is still absent, batt_presence_work is rescheduled. in rt9455_batt_presence_work_callback()
1515 &info->batt_presence_work, in rt9455_batt_presence_work_callback()
1519 &info->max_charging_time_work, in rt9455_batt_presence_work_callback()
1522 ret = regmap_read(info->regmap, RT9455_REG_MASK1, &mask1); in rt9455_batt_presence_work_callback()
1529 ret = regmap_field_write(info->regmap_fields[F_BATABM], in rt9455_batt_presence_work_callback()
1535 * Notify userspace that the battery is now connected to the in rt9455_batt_presence_work_callback()
1538 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()
1755 MODULE_AUTHOR("Anda-Maria Nicolae <anda-maria.nicolae@intel.com>");