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 <pali@kernel.org>
82 /* current register */
172 int autotimer; /* 1 - if driver automatically reset timer, 0 - not */
173 int automode; /* 1 - enabled, 0 - disabled; -1 - not supported */
189 struct i2c_client *client = to_i2c_client(bq->dev); in bq2415x_i2c_read()
194 if (!client->adapter) in bq2415x_i2c_read()
195 return -ENODEV; in bq2415x_i2c_read()
197 msg[0].addr = client->addr; in bq2415x_i2c_read()
201 msg[1].addr = client->addr; in bq2415x_i2c_read()
207 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); in bq2415x_i2c_read()
223 return -EINVAL; in bq2415x_i2c_read_mask()
235 return -EINVAL; in bq2415x_i2c_read_bit()
244 struct i2c_client *client = to_i2c_client(bq->dev); in bq2415x_i2c_write()
252 msg[0].addr = client->addr; in bq2415x_i2c_write()
258 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); in bq2415x_i2c_write()
265 return -EIO; in bq2415x_i2c_write()
277 return -EINVAL; in bq2415x_i2c_write_mask()
294 return -EINVAL; in bq2415x_i2c_write_bit()
401 return -EINVAL; in bq2415x_exec_command()
407 struct i2c_client *client = to_i2c_client(bq->dev); in bq2415x_detect_chip()
413 switch (client->addr) { in bq2415x_detect_chip()
417 if (bq->chip == BQ24151A) in bq2415x_detect_chip()
418 return bq->chip; in bq2415x_detect_chip()
421 if (bq->chip == BQ24150A || in bq2415x_detect_chip()
422 bq->chip == BQ24152 || in bq2415x_detect_chip()
423 bq->chip == BQ24155) in bq2415x_detect_chip()
424 return bq->chip; in bq2415x_detect_chip()
427 if (bq->chip == BQ24153A) in bq2415x_detect_chip()
428 return bq->chip; in bq2415x_detect_chip()
438 if (bq->chip == BQ24156A) in bq2415x_detect_chip()
439 return bq->chip; in bq2415x_detect_chip()
442 if (bq->chip == BQ24157S) in bq2415x_detect_chip()
443 return bq->chip; in bq2415x_detect_chip()
461 return -1; in bq2415x_detect_revision()
471 return -1; in bq2415x_detect_revision()
482 return -1; in bq2415x_detect_revision()
486 return -1; in bq2415x_detect_revision()
488 return -1; in bq2415x_detect_revision()
491 return -1; in bq2415x_detect_revision()
516 bq->timer_error = NULL; in bq2415x_reset_chip()
521 /* set current limit in mA */
539 /* get current limit in mA */
556 return -EINVAL; in bq2415x_get_current_limit()
594 int val = (mV/10 - 350) / 2; in bq2415x_set_battery_regulation_voltage()
603 return -EINVAL; in bq2415x_set_battery_regulation_voltage()
620 /* set charge current in mA (platform data must provide resistor sense) */
625 if (bq->init_data.resistor_sense <= 0) in bq2415x_set_charge_current()
626 return -EINVAL; in bq2415x_set_charge_current()
628 val = (mA * bq->init_data.resistor_sense - 37400) / 6800; in bq2415x_set_charge_current()
639 /* get charge current in mA (platform data must provide resistor sense) */
644 if (bq->init_data.resistor_sense <= 0) in bq2415x_get_charge_current()
645 return -EINVAL; in bq2415x_get_charge_current()
651 return (37400 + 6800*ret) / bq->init_data.resistor_sense; in bq2415x_get_charge_current()
654 /* set termination current in mA (platform data must provide resistor sense) */
659 if (bq->init_data.resistor_sense <= 0) in bq2415x_set_termination_current()
660 return -EINVAL; in bq2415x_set_termination_current()
662 val = (mA * bq->init_data.resistor_sense - 3400) / 3400; in bq2415x_set_termination_current()
673 /* get termination current in mA (platform data must provide resistor sense) */
678 if (bq->init_data.resistor_sense <= 0) in bq2415x_get_termination_current()
679 return -EINVAL; in bq2415x_get_termination_current()
685 return (3400 + 3400*ret) / bq->init_data.resistor_sense; in bq2415x_get_termination_current()
692 if (bq->init_data.prop != -1) \
693 ret = bq2415x_set_##prop(bq, bq->init_data.prop); \
709 if (bq->init_data.resistor_sense > 0) { in bq2415x_set_defaults()
726 int boost = 0; in bq2415x_set_mode() local
729 boost = 1; in bq2415x_set_mode()
736 if (!boost) in bq2415x_set_mode()
744 dev_dbg(bq->dev, "changing mode to: Offline\n"); in bq2415x_set_mode()
748 dev_dbg(bq->dev, "changing mode to: N/A\n"); in bq2415x_set_mode()
752 dev_dbg(bq->dev, "changing mode to: Host/HUB charger\n"); in bq2415x_set_mode()
756 dev_dbg(bq->dev, "changing mode to: Dedicated charger\n"); in bq2415x_set_mode()
759 case BQ2415X_MODE_BOOST: /* Boost mode */ in bq2415x_set_mode()
760 dev_dbg(bq->dev, "changing mode to: Boost\n"); in bq2415x_set_mode()
770 else if (boost) in bq2415x_set_mode()
779 bq->mode = mode; in bq2415x_set_mode()
780 sysfs_notify(&bq->charger->dev.kobj, NULL, "mode"); in bq2415x_set_mode()
799 if (bq->reported_mode == mode) in bq2415x_update_reported_mode()
802 bq->reported_mode = mode; in bq2415x_update_reported_mode()
819 if (bq->notify_node) { in bq2415x_notifier_call()
820 if (!psy->dev.parent || in bq2415x_notifier_call()
821 psy->dev.parent->of_node != bq->notify_node) in bq2415x_notifier_call()
823 } else if (bq->init_data.notify_device) { in bq2415x_notifier_call()
824 if (strcmp(psy->desc->name, bq->init_data.notify_device) != 0) in bq2415x_notifier_call()
828 dev_dbg(bq->dev, "notifier call was called\n"); in bq2415x_notifier_call()
839 if (bq->automode < 1) in bq2415x_notifier_call()
842 schedule_delayed_work(&bq->work, 0); in bq2415x_notifier_call()
854 if (bq->autotimer == state) { in bq2415x_set_autotimer()
859 bq->autotimer = state; in bq2415x_set_autotimer()
862 schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ); in bq2415x_set_autotimer()
864 bq->timer_error = NULL; in bq2415x_set_autotimer()
866 cancel_delayed_work_sync(&bq->work); in bq2415x_set_autotimer()
875 bq->timer_error = msg; in bq2415x_timer_error()
876 sysfs_notify(&bq->charger->dev.kobj, NULL, "timer"); in bq2415x_timer_error()
877 dev_err(bq->dev, "%s\n", msg); in bq2415x_timer_error()
878 if (bq->automode > 0) in bq2415x_timer_error()
879 bq->automode = 0; in bq2415x_timer_error()
891 int boost; in bq2415x_timer_work() local
893 if (bq->automode > 0 && (bq->reported_mode != bq->mode)) { in bq2415x_timer_work()
894 sysfs_notify(&bq->charger->dev.kobj, NULL, "reported_mode"); in bq2415x_timer_work()
895 bq2415x_set_mode(bq, bq->reported_mode); in bq2415x_timer_work()
898 if (!bq->autotimer) in bq2415x_timer_work()
907 boost = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_STATUS); in bq2415x_timer_work()
908 if (boost < 0) { in bq2415x_timer_work()
919 if (boost) { in bq2415x_timer_work()
925 dev_err(bq->dev, "Timer expired\n"); in bq2415x_timer_work()
928 dev_err(bq->dev, "Battery voltage to low\n"); in bq2415x_timer_work()
957 dev_err(bq->dev, "Sleep mode\n"); in bq2415x_timer_work()
960 dev_err(bq->dev, "Poor input source\n"); in bq2415x_timer_work()
963 dev_err(bq->dev, "Timer expired\n"); in bq2415x_timer_work()
966 dev_err(bq->dev, "No battery\n"); in bq2415x_timer_work()
985 schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ); in bq2415x_timer_work()
1009 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in bq2415x_power_supply_get_property()
1011 val->intval = POWER_SUPPLY_STATUS_CHARGING; in bq2415x_power_supply_get_property()
1013 val->intval = POWER_SUPPLY_STATUS_FULL; in bq2415x_power_supply_get_property()
1015 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in bq2415x_power_supply_get_property()
1018 val->strval = bq->model; in bq2415x_power_supply_get_property()
1021 return -EINVAL; in bq2415x_power_supply_get_property()
1028 bq->autotimer = 0; in bq2415x_power_supply_exit()
1029 if (bq->automode > 0) in bq2415x_power_supply_exit()
1030 bq->automode = 0; in bq2415x_power_supply_exit()
1031 cancel_delayed_work_sync(&bq->work); in bq2415x_power_supply_exit()
1032 power_supply_unregister(bq->charger); in bq2415x_power_supply_exit()
1033 kfree(bq->model); in bq2415x_power_supply_exit()
1048 if (strcmp(attr->attr.name, "otg_status") == 0) in bq2415x_sysfs_show_status()
1050 else if (strcmp(attr->attr.name, "charge_status") == 0) in bq2415x_sysfs_show_status()
1052 else if (strcmp(attr->attr.name, "boost_status") == 0) in bq2415x_sysfs_show_status()
1054 else if (strcmp(attr->attr.name, "fault_status") == 0) in bq2415x_sysfs_show_status()
1057 return -EINVAL; in bq2415x_sysfs_show_status()
1067 * auto - enable auto mode
1068 * off - disable auto mode
1069 * (other values) - reset chip timer
1100 if (bq->timer_error) in bq2415x_sysfs_show_timer()
1101 return sysfs_emit(buf, "%s\n", bq->timer_error); in bq2415x_sysfs_show_timer()
1103 if (bq->autotimer) in bq2415x_sysfs_show_timer()
1110 * auto - if automode is supported, enable it and set mode to reported
1111 * none - disable charger and boost mode
1112 * host - charging mode for host/hub chargers (current limit 500mA)
1113 * dedicated - charging mode for dedicated chargers (unlimited current limit)
1114 * boost - disable charger and enable boost mode
1127 if (bq->automode < 0) in bq2415x_sysfs_set_mode()
1128 return -EINVAL; in bq2415x_sysfs_set_mode()
1129 bq->automode = 1; in bq2415x_sysfs_set_mode()
1130 mode = bq->reported_mode; in bq2415x_sysfs_set_mode()
1132 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1133 bq->automode = 0; in bq2415x_sysfs_set_mode()
1136 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1137 bq->automode = 0; in bq2415x_sysfs_set_mode()
1140 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1141 bq->automode = 0; in bq2415x_sysfs_set_mode()
1144 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1145 bq->automode = 0; in bq2415x_sysfs_set_mode()
1147 } else if (strncmp(buf, "boost", 5) == 0) { in bq2415x_sysfs_set_mode()
1148 if (bq->automode > 0) in bq2415x_sysfs_set_mode()
1149 bq->automode = 0; in bq2415x_sysfs_set_mode()
1154 if (bq->automode <= 0) in bq2415x_sysfs_set_mode()
1156 bq->automode = 1; in bq2415x_sysfs_set_mode()
1157 mode = bq->reported_mode; in bq2415x_sysfs_set_mode()
1159 return -EINVAL; in bq2415x_sysfs_set_mode()
1168 /* show mode entry (auto, none, host, dedicated or boost) */
1177 if (bq->automode > 0) in bq2415x_sysfs_show_mode()
1180 switch (bq->mode) { in bq2415x_sysfs_show_mode()
1194 ret += sysfs_emit_at(buf, ret, "boost"); in bq2415x_sysfs_show_mode()
1198 if (bq->automode > 0) in bq2415x_sysfs_show_mode()
1205 /* show reported_mode entry (none, host, dedicated or boost) */
1213 if (bq->automode < 0) in bq2415x_sysfs_show_reported_mode()
1214 return -EINVAL; in bq2415x_sysfs_show_reported_mode()
1216 switch (bq->reported_mode) { in bq2415x_sysfs_show_reported_mode()
1226 return sysfs_emit(buf, "boost\n"); in bq2415x_sysfs_show_reported_mode()
1229 return -EINVAL; in bq2415x_sysfs_show_reported_mode()
1245 return -EINVAL; in bq2415x_sysfs_set_registers()
1248 return -EINVAL; in bq2415x_sysfs_set_registers()
1285 /* set current and voltage limit entries (in mA or mV) */
1297 return -EINVAL; in bq2415x_sysfs_set_limit()
1299 if (strcmp(attr->attr.name, "current_limit") == 0) in bq2415x_sysfs_set_limit()
1301 else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0) in bq2415x_sysfs_set_limit()
1303 else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0) in bq2415x_sysfs_set_limit()
1305 else if (strcmp(attr->attr.name, "charge_current") == 0) in bq2415x_sysfs_set_limit()
1307 else if (strcmp(attr->attr.name, "termination_current") == 0) in bq2415x_sysfs_set_limit()
1310 return -EINVAL; in bq2415x_sysfs_set_limit()
1317 /* show current and voltage limit entries (in mA or mV) */
1326 if (strcmp(attr->attr.name, "current_limit") == 0) in bq2415x_sysfs_show_limit()
1328 else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0) in bq2415x_sysfs_show_limit()
1330 else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0) in bq2415x_sysfs_show_limit()
1332 else if (strcmp(attr->attr.name, "charge_current") == 0) in bq2415x_sysfs_show_limit()
1334 else if (strcmp(attr->attr.name, "termination_current") == 0) in bq2415x_sysfs_show_limit()
1337 return -EINVAL; in bq2415x_sysfs_show_limit()
1357 return -EINVAL; in bq2415x_sysfs_set_enable()
1359 if (strcmp(attr->attr.name, "charge_termination_enable") == 0) in bq2415x_sysfs_set_enable()
1362 else if (strcmp(attr->attr.name, "high_impedance_enable") == 0) in bq2415x_sysfs_set_enable()
1365 else if (strcmp(attr->attr.name, "otg_pin_enable") == 0) in bq2415x_sysfs_set_enable()
1368 else if (strcmp(attr->attr.name, "stat_pin_enable") == 0) in bq2415x_sysfs_set_enable()
1372 return -EINVAL; in bq2415x_sysfs_set_enable()
1390 if (strcmp(attr->attr.name, "charge_termination_enable") == 0) in bq2415x_sysfs_show_enable()
1392 else if (strcmp(attr->attr.name, "high_impedance_enable") == 0) in bq2415x_sysfs_show_enable()
1394 else if (strcmp(attr->attr.name, "otg_pin_enable") == 0) in bq2415x_sysfs_show_enable()
1396 else if (strcmp(attr->attr.name, "stat_pin_enable") == 0) in bq2415x_sysfs_show_enable()
1399 return -EINVAL; in bq2415x_sysfs_show_enable()
1480 .of_node = bq->dev->of_node, in bq2415x_power_supply_init()
1484 bq->charger_desc.name = bq->name; in bq2415x_power_supply_init()
1485 bq->charger_desc.type = POWER_SUPPLY_TYPE_USB; in bq2415x_power_supply_init()
1486 bq->charger_desc.properties = bq2415x_power_supply_props; in bq2415x_power_supply_init()
1487 bq->charger_desc.num_properties = in bq2415x_power_supply_init()
1489 bq->charger_desc.get_property = bq2415x_power_supply_get_property; in bq2415x_power_supply_init()
1503 bq->model = kasprintf(GFP_KERNEL, in bq2415x_power_supply_init()
1507 if (!bq->model) { in bq2415x_power_supply_init()
1508 dev_err(bq->dev, "failed to allocate model name\n"); in bq2415x_power_supply_init()
1509 return -ENOMEM; in bq2415x_power_supply_init()
1512 bq->charger = power_supply_register(bq->dev, &bq->charger_desc, in bq2415x_power_supply_init()
1514 if (IS_ERR(bq->charger)) { in bq2415x_power_supply_init()
1515 kfree(bq->model); in bq2415x_power_supply_init()
1516 return PTR_ERR(bq->charger); in bq2415x_power_supply_init()
1530 struct device_node *np = client->dev.of_node; in bq2415x_probe()
1531 struct bq2415x_platform_data *pdata = client->dev.platform_data; in bq2415x_probe()
1536 if (!np && !pdata && !ACPI_HANDLE(&client->dev)) { in bq2415x_probe()
1537 dev_err(&client->dev, "Neither devicetree, nor platform data, nor ACPI support\n"); in bq2415x_probe()
1538 return -ENODEV; in bq2415x_probe()
1549 name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num); in bq2415x_probe()
1550 } else if (ACPI_HANDLE(&client->dev)) { in bq2415x_probe()
1552 acpi_match_device(client->dev.driver->acpi_match_table, in bq2415x_probe()
1553 &client->dev); in bq2415x_probe()
1555 dev_err(&client->dev, "failed to match device name\n"); in bq2415x_probe()
1556 ret = -ENODEV; in bq2415x_probe()
1559 name = kasprintf(GFP_KERNEL, "%s-%d", acpi_id->id, num); in bq2415x_probe()
1562 dev_err(&client->dev, "failed to allocate device name\n"); in bq2415x_probe()
1563 ret = -ENOMEM; in bq2415x_probe()
1567 bq = devm_kzalloc(&client->dev, sizeof(*bq), GFP_KERNEL); in bq2415x_probe()
1569 ret = -ENOMEM; in bq2415x_probe()
1575 bq->id = num; in bq2415x_probe()
1576 bq->dev = &client->dev; in bq2415x_probe()
1578 bq->chip = id->driver_data; in bq2415x_probe()
1579 else if (ACPI_HANDLE(bq->dev)) in bq2415x_probe()
1580 bq->chip = acpi_id->driver_data; in bq2415x_probe()
1581 bq->name = name; in bq2415x_probe()
1582 bq->mode = BQ2415X_MODE_OFF; in bq2415x_probe()
1583 bq->reported_mode = BQ2415X_MODE_OFF; in bq2415x_probe()
1584 bq->autotimer = 0; in bq2415x_probe()
1585 bq->automode = 0; in bq2415x_probe()
1587 if (np || ACPI_HANDLE(bq->dev)) { in bq2415x_probe()
1588 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1589 "ti,current-limit", in bq2415x_probe()
1590 &bq->init_data.current_limit); in bq2415x_probe()
1593 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1594 "ti,weak-battery-voltage", in bq2415x_probe()
1595 &bq->init_data.weak_battery_voltage); in bq2415x_probe()
1598 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1599 "ti,battery-regulation-voltage", in bq2415x_probe()
1600 &bq->init_data.battery_regulation_voltage); in bq2415x_probe()
1603 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1604 "ti,charge-current", in bq2415x_probe()
1605 &bq->init_data.charge_current); in bq2415x_probe()
1608 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1609 "ti,termination-current", in bq2415x_probe()
1610 &bq->init_data.termination_current); in bq2415x_probe()
1613 ret = device_property_read_u32(bq->dev, in bq2415x_probe()
1614 "ti,resistor-sense", in bq2415x_probe()
1615 &bq->init_data.resistor_sense); in bq2415x_probe()
1619 bq->notify_node = of_parse_phandle(np, in bq2415x_probe()
1620 "ti,usb-charger-detection", 0); in bq2415x_probe()
1622 memcpy(&bq->init_data, pdata, sizeof(bq->init_data)); in bq2415x_probe()
1629 dev_err(bq->dev, "failed to register power supply: %d\n", ret); in bq2415x_probe()
1635 dev_err(bq->dev, "failed to set default values: %d\n", ret); in bq2415x_probe()
1639 if (bq->notify_node || bq->init_data.notify_device) { in bq2415x_probe()
1640 bq->nb.notifier_call = bq2415x_notifier_call; in bq2415x_probe()
1641 ret = power_supply_reg_notifier(&bq->nb); in bq2415x_probe()
1643 dev_err(bq->dev, "failed to reg notifier: %d\n", ret); in bq2415x_probe()
1647 bq->automode = 1; in bq2415x_probe()
1648 dev_info(bq->dev, "automode supported, waiting for events\n"); in bq2415x_probe()
1650 bq->automode = -1; in bq2415x_probe()
1651 dev_info(bq->dev, "automode not supported\n"); in bq2415x_probe()
1655 if (bq->nb.notifier_call) { in bq2415x_probe()
1658 "ti,usb-charger-detection"); in bq2415x_probe()
1661 } else if (bq->init_data.notify_device) { in bq2415x_probe()
1663 bq->init_data.notify_device); in bq2415x_probe()
1673 bq2415x_set_mode(bq, bq->reported_mode); in bq2415x_probe()
1677 INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work); in bq2415x_probe()
1680 dev_info(bq->dev, "driver registered\n"); in bq2415x_probe()
1687 of_node_put(bq->notify_node); in bq2415x_probe()
1703 if (bq->nb.notifier_call) in bq2415x_remove()
1704 power_supply_unreg_notifier(&bq->nb); in bq2415x_remove()
1706 of_node_put(bq->notify_node); in bq2415x_remove()
1712 idr_remove(&bq2415x_id, bq->id); in bq2415x_remove()
1715 dev_info(bq->dev, "driver unregistered\n"); in bq2415x_remove()
1717 kfree(bq->name); in bq2415x_remove()
1779 .name = "bq2415x-charger",