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

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2011-2013 Pali Rohár <[email protected]>
82 /* current register */
172 int autotimer; /* 1 - if driver automatically reset timer, 0 - not */
173 int automode; /* 1 - enabled, 0 - disabled; -1 - not supported */
190 struct i2c_client *client = to_i2c_client(bq->dev); in bq2415x_i2c_read()
195 if (!client->adapter) in bq2415x_i2c_read()
196 return -ENODEV; in bq2415x_i2c_read()
198 msg[0].addr = client->addr; in bq2415x_i2c_read()
202 msg[1].addr = client->addr; in bq2415x_i2c_read()
208 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); in bq2415x_i2c_read()
224 return -EINVAL; in bq2415x_i2c_read_mask()
236 return -EINVAL; in bq2415x_i2c_read_bit()
245 struct i2c_client *client = to_i2c_client(bq->dev); in bq2415x_i2c_write()
253 msg[0].addr = client->addr; in bq2415x_i2c_write()
259 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); in bq2415x_i2c_write()
266 return -EIO; in bq2415x_i2c_write()
278 return -EINVAL; in bq2415x_i2c_write_mask()
295 return -EINVAL; in bq2415x_i2c_write_bit()
402 return -EINVAL; in bq2415x_exec_command()
408 struct i2c_client *client = to_i2c_client(bq->dev); in bq2415x_detect_chip()
414 switch (client->addr) { in bq2415x_detect_chip()
418 if (bq->chip == BQ24151A) in bq2415x_detect_chip()
419 return bq->chip; in bq2415x_detect_chip()
422 if (bq->chip == BQ24150A || in bq2415x_detect_chip()
423 bq->chip == BQ24152 || in bq2415x_detect_chip()
424 bq->chip == BQ24155) in bq2415x_detect_chip()
425 return bq->chip; in bq2415x_detect_chip()
428 if (bq->chip == BQ24153A) in bq2415x_detect_chip()
429 return bq->chip; in bq2415x_detect_chip()
439 if (bq->chip == BQ24156A) in bq2415x_detect_chip()
440 return bq->chip; in bq2415x_detect_chip()
443 if (bq->chip == BQ24157S) in bq2415x_detect_chip()
444 return bq->chip; in bq2415x_detect_chip()
462 return -1; in bq2415x_detect_revision()
472 return -1; in bq2415x_detect_revision()
483 return -1; in bq2415x_detect_revision()
487 return -1; in bq2415x_detect_revision()
489 return -1; in bq2415x_detect_revision()
492 return -1; in bq2415x_detect_revision()
517 bq->timer_error = NULL; in bq2415x_reset_chip()
522 /* set current limit in mA */
540 /* get current limit in mA */
557 return -EINVAL; in bq2415x_get_current_limit()
595 int val = (mV/10 - 350) / 2; in bq2415x_set_battery_regulation_voltage()
604 return -EINVAL; in bq2415x_set_battery_regulation_voltage()
621 /* set charge current in mA (platform data must provide resistor sense) */
626 if (bq->init_data.resistor_sense <= 0) in bq2415x_set_charge_current()
627 return -EINVAL; in bq2415x_set_charge_current()
629 val = (mA * bq->init_data.resistor_sense - 37400) / 6800; in bq2415x_set_charge_current()
640 /* get charge current in mA (platform data must provide resistor sense) */
645 if (bq->init_data.resistor_sense <= 0) in bq2415x_get_charge_current()
646 return -EINVAL; in bq2415x_get_charge_current()
652 return (37400 + 6800*ret) / bq->init_data.resistor_sense; in bq2415x_get_charge_current()
655 /* set termination current in mA (platform data must provide resistor sense) */
660 if (bq->init_data.resistor_sense <= 0) in bq2415x_set_termination_current()
661 return -EINVAL; in bq2415x_set_termination_current()
663 val = (mA * bq->init_data.resistor_sense - 3400) / 3400; in bq2415x_set_termination_current()
674 /* get termination current in mA (platform data must provide resistor sense) */
679 if (bq->init_data.resistor_sense <= 0) in bq2415x_get_termination_current()
680 return -EINVAL; in bq2415x_get_termination_current()
686 return (3400 + 3400*ret) / bq->init_data.resistor_sense; in bq2415x_get_termination_current()
693 if (bq->init_data.prop != -1) \
694 ret = bq2415x_set_##prop(bq, bq->init_data.prop); \
710 if (bq->init_data.resistor_sense > 0) { in bq2415x_set_defaults()
727 int boost = 0; in bq2415x_set_mode() local
730 boost = 1; in bq2415x_set_mode()
737 if (!boost) in bq2415x_set_mode()
745 dev_dbg(bq->dev, "changing mode to: Offline\n"); in bq2415x_set_mode()
749 dev_dbg(bq->dev, "changing mode to: N/A\n"); in bq2415x_set_mode()
753 dev_dbg(bq->dev, "changing mode to: Host/HUB charger\n"); in bq2415x_set_mode()
757 dev_dbg(bq->dev, "changing mode to: Dedicated charger\n"); in bq2415x_set_mode()
760 case BQ2415X_MODE_BOOST: /* Boost mode */ in bq2415x_set_mode()
761 dev_dbg(bq->dev, "changing mode to: Boost\n"); in bq2415x_set_mode()
771 else if (boost) in bq2415x_set_mode()
780 bq->mode = mode; in bq2415x_set_mode()
781 sysfs_notify(&bq->charger->dev.kobj, NULL, "mode"); in bq2415x_set_mode()
800 if (bq->reported_mode == mode) in bq2415x_update_reported_mode()
803 bq->reported_mode = mode; in bq2415x_update_reported_mode()
820 if (bq->notify_node) { in bq2415x_notifier_call()
821 if (!psy->dev.parent || in bq2415x_notifier_call()
822 psy->dev.parent->of_node != bq->notify_node) in bq2415x_notifier_call()
824 } else if (bq->init_data.notify_device) { in bq2415x_notifier_call()
825 if (strcmp(psy->desc->name, bq->init_data.notify_device) != 0) in bq2415x_notifier_call()
829 dev_dbg(bq->dev, "notifier call was called\n"); in bq2415x_notifier_call()
839 power_supply_changed(bq->charger); in bq2415x_notifier_call()
842 if (bq->automode < 1) in bq2415x_notifier_call()
845 mod_delayed_work(system_wq, &bq->work, 0); in bq2415x_notifier_call()
857 if (bq->autotimer == state) { in bq2415x_set_autotimer()
862 bq->autotimer = state; in bq2415x_set_autotimer()
865 schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ); in bq2415x_set_autotimer()
867 bq->timer_error = NULL; in bq2415x_set_autotimer()
869 cancel_delayed_work_sync(&bq->work); in bq2415x_set_autotimer()
878 bq->timer_error = msg; in bq2415x_timer_error()
879 sysfs_notify(&bq->charger->dev.kobj, NULL, "timer"); in bq2415x_timer_error()
880 dev_err(bq->dev, "%s\n", msg); in bq2415x_timer_error()
881 if (bq->automode > 0) in bq2415x_timer_error()
882 bq->automode = 0; in bq2415x_timer_error()
894 int boost; in bq2415x_timer_work() local
897 if (bq->automode > 0 && (bq->reported_mode != bq->mode)) { in bq2415x_timer_work()
898 sysfs_notify(&bq->charger->dev.kobj, NULL, "reported_mode"); in bq2415x_timer_work()
899 bq2415x_set_mode(bq, bq->reported_mode); in bq2415x_timer_work()
903 if (bq->charge_status != charge) { in bq2415x_timer_work()
904 power_supply_changed(bq->charger); in bq2415x_timer_work()
905 bq->charge_status = charge; in bq2415x_timer_work()
908 if (!bq->autotimer) in bq2415x_timer_work()
917 boost = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_STATUS); in bq2415x_timer_work()
918 if (boost < 0) { in bq2415x_timer_work()
929 if (boost) { in bq2415x_timer_work()
935 dev_err(bq->dev, "Timer expired\n"); in bq2415x_timer_work()
938 dev_err(bq->dev, "Battery voltage to low\n"); in bq2415x_timer_work()
967 dev_err(bq->dev, "Sleep mode\n"); in bq2415x_timer_work()
970 dev_err(bq->dev, "Poor input source\n"); in bq2415x_timer_work()
973 dev_err(bq->dev, "Timer expired\n"); in bq2415x_timer_work()
976 dev_err(bq->dev, "No battery\n"); in bq2415x_timer_work()
995 schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ); in bq2415x_timer_work()
1020 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in bq2415x_power_supply_get_property()
1022 val->intval = POWER_SUPPLY_STATUS_CHARGING; in bq2415x_power_supply_get_property()
1024 val->intval = POWER_SUPPLY_STATUS_FULL; in bq2415x_power_supply_get_property()
1026 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in bq2415x_power_supply_get_property()
1029 val->strval = bq->model; in bq2415x_power_supply_get_property()
1038 val->intval = ret > 0; in bq2415x_power_supply_get_property()
1041 return -EINVAL; in bq2415x_power_supply_get_property()
1048 bq->autotimer = 0; in bq2415x_power_supply_exit()
1049 if (bq->automode > 0) in bq2415x_power_supply_exit()
1050 bq->automode = 0; in bq2415x_power_supply_exit()
1051 cancel_delayed_work_sync(&bq->work); in bq2415x_power_supply_exit()
1052 power_supply_unregister(bq->charger); in bq2415x_power_supply_exit()
1053 kfree(bq->model); in bq2415x_power_supply_exit()
1068 if (strcmp(attr->attr.name, "otg_status") == 0) in bq2415x_sysfs_show_status()
1070 else if (strcmp(attr->attr.name, "charge_status") == 0) in bq2415x_sysfs_show_status()
1072 else if (strcmp(attr->attr.name, "boost_status") == 0) in bq2415x_sysfs_show_status()
1074 else if (strcmp(attr->attr.name, "fault_status") == 0) in bq2415x_sysfs_show_status()
1077 return -EINVAL; in bq2415x_sysfs_show_status()
1087 * auto - enable auto mode
1088 * off - disable auto mode
1089 * (other values) - reset chip timer
1120 if (bq->timer_error) in bq2415x_sysfs_show_timer()
1121 return sysfs_emit(buf, "%s\n", bq->timer_error); in bq2415x_sysfs_show_timer()
1123 if (bq->autotimer) in bq2415x_sysfs_show_timer()
1130 * auto - if automode is supported, enable it and set mode to reported
1131 * none - disable charger and boost mode
1132 * host - charging mode for host/hub chargers (current limit 500mA)
1133 * dedicated - charging mode for dedicated chargers (unlimited current limit)
1134 * boost - disable charger and enable boost mode
1147 if (bq->automode < 0) in bq2415x_sysfs_set_mode()
1148 return -EINVAL; in bq2415x_sysfs_set_mode()
1149 bq->automode = 1; in bq2415x_sysfs_set_mode()
1150 mode = bq->reported_mode; in bq2415x_sysfs_set_mode()
1152 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1153 bq->automode = 0; in bq2415x_sysfs_set_mode()
1156 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1157 bq->automode = 0; in bq2415x_sysfs_set_mode()
1160 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1161 bq->automode = 0; in bq2415x_sysfs_set_mode()
1164 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1165 bq->automode = 0; in bq2415x_sysfs_set_mode()
1167 } else if (strncmp(buf, "boost", 5) == 0) { in bq2415x_sysfs_set_mode()
1168 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1169 bq->automode = 0; in bq2415x_sysfs_set_mode()
1174 if (bq->automode <= 0) in bq2415x_sysfs_set_mode()
1176 bq->automode = 1; in bq2415x_sysfs_set_mode()
1177 mode = bq->reported_mode; in bq2415x_sysfs_set_mode()
1179 return -EINVAL; in bq2415x_sysfs_set_mode()
1188 /* show mode entry (auto, none, host, dedicated or boost) */
1197 if (bq->automode > 0) in bq2415x_sysfs_show_mode()
1200 switch (bq->mode) { in bq2415x_sysfs_show_mode()
1214 ret += sysfs_emit_at(buf, ret, "boost"); in bq2415x_sysfs_show_mode()
1218 if (bq->automode > 0) in bq2415x_sysfs_show_mode()
1225 /* show reported_mode entry (none, host, dedicated or boost) */
1233 if (bq->automode < 0) in bq2415x_sysfs_show_reported_mode()
1234 return -EINVAL; in bq2415x_sysfs_show_reported_mode()
1236 switch (bq->reported_mode) { in bq2415x_sysfs_show_reported_mode()
1246 return sysfs_emit(buf, "boost\n"); in bq2415x_sysfs_show_reported_mode()
1249 return -EINVAL; in bq2415x_sysfs_show_reported_mode()
1265 return -EINVAL; in bq2415x_sysfs_set_registers()
1268 return -EINVAL; in bq2415x_sysfs_set_registers()
1305 /* set current and voltage limit entries (in mA or mV) */
1317 return -EINVAL; in bq2415x_sysfs_set_limit()
1319 if (strcmp(attr->attr.name, "current_limit") == 0) in bq2415x_sysfs_set_limit()
1321 else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0) in bq2415x_sysfs_set_limit()
1323 else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0) in bq2415x_sysfs_set_limit()
1325 else if (strcmp(attr->attr.name, "charge_current") == 0) in bq2415x_sysfs_set_limit()
1327 else if (strcmp(attr->attr.name, "termination_current") == 0) in bq2415x_sysfs_set_limit()
1330 return -EINVAL; in bq2415x_sysfs_set_limit()
1337 /* show current and voltage limit entries (in mA or mV) */
1346 if (strcmp(attr->attr.name, "current_limit") == 0) in bq2415x_sysfs_show_limit()
1348 else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0) in bq2415x_sysfs_show_limit()
1350 else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0) in bq2415x_sysfs_show_limit()
1352 else if (strcmp(attr->attr.name, "charge_current") == 0) in bq2415x_sysfs_show_limit()
1354 else if (strcmp(attr->attr.name, "termination_current") == 0) in bq2415x_sysfs_show_limit()
1357 return -EINVAL; in bq2415x_sysfs_show_limit()
1377 return -EINVAL; in bq2415x_sysfs_set_enable()
1379 if (strcmp(attr->attr.name, "charge_termination_enable") == 0) in bq2415x_sysfs_set_enable()
1382 else if (strcmp(attr->attr.name, "high_impedance_enable") == 0) in bq2415x_sysfs_set_enable()
1385 else if (strcmp(attr->attr.name, "otg_pin_enable") == 0) in bq2415x_sysfs_set_enable()
1388 else if (strcmp(attr->attr.name, "stat_pin_enable") == 0) in bq2415x_sysfs_set_enable()
1392 return -EINVAL; in bq2415x_sysfs_set_enable()
1410 if (strcmp(attr->attr.name, "charge_termination_enable") == 0) in bq2415x_sysfs_show_enable()
1412 else if (strcmp(attr->attr.name, "high_impedance_enable") == 0) in bq2415x_sysfs_show_enable()
1414 else if (strcmp(attr->attr.name, "otg_pin_enable") == 0) in bq2415x_sysfs_show_enable()
1416 else if (strcmp(attr->attr.name, "stat_pin_enable") == 0) in bq2415x_sysfs_show_enable()
1419 return -EINVAL; in bq2415x_sysfs_show_enable()
1500 .of_node = bq->dev->of_node, in bq2415x_power_supply_init()
1504 bq->charger_desc.name = bq->name; in bq2415x_power_supply_init()
1505 bq->charger_desc.type = POWER_SUPPLY_TYPE_USB; in bq2415x_power_supply_init()
1506 bq->charger_desc.properties = bq2415x_power_supply_props; in bq2415x_power_supply_init()
1507 bq->charger_desc.num_properties = in bq2415x_power_supply_init()
1509 bq->charger_desc.get_property = bq2415x_power_supply_get_property; in bq2415x_power_supply_init()
1523 bq->model = kasprintf(GFP_KERNEL, in bq2415x_power_supply_init()
1527 if (!bq->model) { in bq2415x_power_supply_init()
1528 dev_err(bq->dev, "failed to allocate model name\n"); in bq2415x_power_supply_init()
1529 return -ENOMEM; in bq2415x_power_supply_init()
1532 bq->charger = power_supply_register(bq->dev, &bq->charger_desc, in bq2415x_power_supply_init()
1534 if (IS_ERR(bq->charger)) { in bq2415x_power_supply_init()
1535 kfree(bq->model); in bq2415x_power_supply_init()
1536 return PTR_ERR(bq->charger); in bq2415x_power_supply_init()
1550 struct device_node *np = client->dev.of_node; in bq2415x_probe()
1551 struct bq2415x_platform_data *pdata = client->dev.platform_data; in bq2415x_probe()
1556 if (!np && !pdata && !ACPI_HANDLE(&client->dev)) { in bq2415x_probe()
1557 dev_err(&client->dev, "Neither devicetree, nor platform data, nor ACPI support\n"); in bq2415x_probe()
1558 return -ENODEV; in bq2415x_probe()
1569 name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num); in bq2415x_probe()
1570 } else if (ACPI_HANDLE(&client->dev)) { in bq2415x_probe()
1572 acpi_match_device(client->dev.driver->acpi_match_table, in bq2415x_probe()
1573 &client->dev); in bq2415x_probe()
1575 dev_err(&client->dev, "failed to match device name\n"); in bq2415x_probe()
1576 ret = -ENODEV; in bq2415x_probe()
1579 name = kasprintf(GFP_KERNEL, "%s-%d", acpi_id->id, num); in bq2415x_probe()
1582 dev_err(&client->dev, "failed to allocate device name\n"); in bq2415x_probe()
1583 ret = -ENOMEM; in bq2415x_probe()
1587 bq = devm_kzalloc(&client->dev, sizeof(*bq), GFP_KERNEL); in bq2415x_probe()
1589 ret = -ENOMEM; in bq2415x_probe()
1595 bq->id = num; in bq2415x_probe()
1596 bq->dev = &client->dev; in bq2415x_probe()
1598 bq->chip = id->driver_data; in bq2415x_probe()
1599 else if (ACPI_HANDLE(bq->dev)) in bq2415x_probe()
1600 bq->chip = acpi_id->driver_data; in bq2415x_probe()
1601 bq->name = name; in bq2415x_probe()
1602 bq->mode = BQ2415X_MODE_OFF; in bq2415x_probe()
1603 bq->reported_mode = BQ2415X_MODE_OFF; in bq2415x_probe()
1604 bq->autotimer = 0; in bq2415x_probe()
1605 bq->automode = 0; in bq2415x_probe()
1607 if (np || ACPI_HANDLE(bq->dev)) { in bq2415x_probe()
1608 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1609 "ti,current-limit", in bq2415x_probe()
1610 &bq->init_data.current_limit); in bq2415x_probe()
1613 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1614 "ti,weak-battery-voltage", in bq2415x_probe()
1615 &bq->init_data.weak_battery_voltage); in bq2415x_probe()
1618 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1619 "ti,battery-regulation-voltage", in bq2415x_probe()
1620 &bq->init_data.battery_regulation_voltage); in bq2415x_probe()
1623 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1624 "ti,charge-current", in bq2415x_probe()
1625 &bq->init_data.charge_current); in bq2415x_probe()
1628 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1629 "ti,termination-current", in bq2415x_probe()
1630 &bq->init_data.termination_current); in bq2415x_probe()
1633 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1634 "ti,resistor-sense", in bq2415x_probe()
1635 &bq->init_data.resistor_sense); in bq2415x_probe()
1639 bq->notify_node = of_parse_phandle(np, in bq2415x_probe()
1640 "ti,usb-charger-detection", 0); in bq2415x_probe()
1642 memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); in bq2415x_probe()
1649 dev_err(bq->dev, "failed to register power supply: %d\n", ret); in bq2415x_probe()
1655 dev_err(bq->dev, "failed to set default values: %d\n", ret); in bq2415x_probe()
1659 if (bq->notify_node || bq->init_data.notify_device) { in bq2415x_probe()
1660 bq->nb.notifier_call = bq2415x_notifier_call; in bq2415x_probe()
1661 ret = power_supply_reg_notifier(&bq->nb); in bq2415x_probe()
1663 dev_err(bq->dev, "failed to reg notifier: %d\n", ret); in bq2415x_probe()
1667 bq->automode = 1; in bq2415x_probe()
1668 dev_info(bq->dev, "automode supported, waiting for events\n"); in bq2415x_probe()
1670 bq->automode = -1; in bq2415x_probe()
1671 dev_info(bq->dev, "automode not supported\n"); in bq2415x_probe()
1675 if (bq->nb.notifier_call) { in bq2415x_probe()
1678 "ti,usb-charger-detection"); in bq2415x_probe()
1681 } else if (bq->init_data.notify_device) { in bq2415x_probe()
1683 bq->init_data.notify_device); in bq2415x_probe()
1693 bq2415x_set_mode(bq, bq->reported_mode); in bq2415x_probe()
1697 INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work); in bq2415x_probe()
1700 dev_info(bq->dev, "driver registered\n"); in bq2415x_probe()
1707 of_node_put(bq->notify_node); in bq2415x_probe()
1723 if (bq->nb.notifier_call) in bq2415x_remove()
1724 power_supply_unreg_notifier(&bq->nb); in bq2415x_remove()
1726 of_node_put(bq->notify_node); in bq2415x_remove()
1732 idr_remove(&bq2415x_id, bq->id); in bq2415x_remove()
1735 dev_info(bq->dev, "driver unregistered\n"); in bq2415x_remove()
1737 kfree(bq->name); in bq2415x_remove()
1799 .name = "bq2415x-charger",