Lines Matching +full:i2c +full:- +full:retry +full:- +full:count

1 // SPDX-License-Identifier: GPL-2.0-or-later
12 #include <linux/i2c.h>
19 #include <linux/power/sbs-battery.h>
100 SBS_DATA(-1, 0x03, 0, 65535),
106 SBS_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 32767),
108 SBS_DATA(POWER_SUPPLY_PROP_CURRENT_AVG, 0x0B, -32768, 32767),
216 int val = sbs_read_word_data(chip->client, BATTERY_MODE_OFFSET); in sbs_disable_charger_broadcasts()
222 val = sbs_write_word_data(chip->client, BATTERY_MODE_OFFSET, val); in sbs_disable_charger_broadcasts()
226 dev_err(&chip->client->dev, in sbs_disable_charger_broadcasts()
229 dev_dbg(&chip->client->dev, "%s\n", __func__); in sbs_disable_charger_broadcasts()
234 struct i2c_client *client = chip->client; in sbs_update_presence()
235 int retries = chip->i2c_retry_count; in sbs_update_presence()
239 if (chip->is_present == is_present) in sbs_update_presence()
243 chip->is_present = false; in sbs_update_presence()
245 client->flags &= ~I2C_CLIENT_PEC; in sbs_update_presence()
257 * I2C bus is properly connected. This works around the in sbs_update_presence()
262 retries--; in sbs_update_presence()
266 dev_dbg(&client->dev, "failed to read spec info: %d\n", ret); in sbs_update_presence()
269 client->flags &= ~I2C_CLIENT_PEC; in sbs_update_presence()
270 chip->is_present = true; in sbs_update_presence()
278 client->flags |= I2C_CLIENT_PEC; in sbs_update_presence()
280 client->flags &= ~I2C_CLIENT_PEC; in sbs_update_presence()
282 if (of_device_is_compatible(client->dev.parent->of_node, "google,cros-ec-i2c-tunnel") in sbs_update_presence()
283 && client->flags & I2C_CLIENT_PEC) { in sbs_update_presence()
284 dev_info(&client->dev, "Disabling PEC because of broken Cros-EC implementation\n"); in sbs_update_presence()
285 client->flags &= ~I2C_CLIENT_PEC; in sbs_update_presence()
288 dev_dbg(&client->dev, "PEC: %s\n", (client->flags & I2C_CLIENT_PEC) ? in sbs_update_presence()
291 if (!chip->is_present && is_present && !chip->charger_broadcasts) in sbs_update_presence()
294 chip->is_present = true; in sbs_update_presence()
302 int retries = chip->i2c_retry_count; in sbs_read_word_data()
309 retries--; in sbs_read_word_data()
313 dev_dbg(&client->dev, in sbs_read_word_data()
314 "%s: i2c read at address 0x%x failed\n", in sbs_read_word_data()
329 retries_length = chip->i2c_retry_count; in sbs_read_string_data_fallback()
330 retries_block = chip->i2c_retry_count; in sbs_read_string_data_fallback()
332 dev_warn_once(&client->dev, "I2C adapter does not support I2C_FUNC_SMBUS_READ_BLOCK_DATA.\n" in sbs_read_string_data_fallback()
336 if (!i2c_check_functionality(client->adapter, in sbs_read_string_data_fallback()
339 return -ENODEV; in sbs_read_string_data_fallback()
347 retries_length--; in sbs_read_string_data_fallback()
351 dev_dbg(&client->dev, in sbs_read_string_data_fallback()
352 "%s: i2c read at address 0x%x failed\n", in sbs_read_string_data_fallback()
360 dev_err(&client->dev, in sbs_read_string_data_fallback()
363 return -EINVAL; in sbs_read_string_data_fallback()
373 retries_block--; in sbs_read_string_data_fallback()
377 dev_dbg(&client->dev, in sbs_read_string_data_fallback()
378 "%s: i2c read at address 0x%x failed\n", in sbs_read_string_data_fallback()
393 int retries = chip->i2c_retry_count; in sbs_read_string_data()
396 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { in sbs_read_string_data()
397 bool pec = client->flags & I2C_CLIENT_PEC; in sbs_read_string_data()
398 client->flags &= ~I2C_CLIENT_PEC; in sbs_read_string_data()
401 client->flags |= I2C_CLIENT_PEC; in sbs_read_string_data()
409 retries--; in sbs_read_string_data()
413 dev_dbg(&client->dev, "failed to read block 0x%x: %d\n", address, ret); in sbs_read_string_data()
426 int retries = chip->i2c_retry_count; in sbs_write_word_data()
433 retries--; in sbs_write_word_data()
437 dev_dbg(&client->dev, in sbs_write_word_data()
438 "%s: i2c write to address 0x%x failed\n", in sbs_write_word_data()
456 /* Not drawing current -> not charging (i.e. idle) */ in sbs_status_correct()
496 val->intval = 0; /* battery removed */ in sbs_get_ti_battery_presence_and_health()
503 val->intval = 0; /* battery removed */ in sbs_get_ti_battery_presence_and_health()
509 val->intval = 0; in sbs_get_ti_battery_presence_and_health()
521 val->intval = 0; in sbs_get_ti_battery_presence_and_health()
523 val->intval = 1; in sbs_get_ti_battery_presence_and_health()
526 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; in sbs_get_ti_battery_presence_and_health()
528 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; in sbs_get_ti_battery_presence_and_health()
530 val->intval = POWER_SUPPLY_HEALTH_DEAD; in sbs_get_ti_battery_presence_and_health()
532 val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED; in sbs_get_ti_battery_presence_and_health()
534 val->intval = POWER_SUPPLY_HEALTH_GOOD; in sbs_get_ti_battery_presence_and_health()
547 if (chip->flags & SBS_FLAGS_TI_BQ20ZX5) in sbs_get_battery_presence_and_health()
555 val->intval = 0; in sbs_get_battery_presence_and_health()
562 val->intval = 1; /* battery present */ in sbs_get_battery_presence_and_health()
565 val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED; in sbs_get_battery_presence_and_health()
568 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; in sbs_get_battery_presence_and_health()
592 val->intval = ret; in sbs_get_battery_property()
595 val->intval = in sbs_get_battery_property()
598 val->intval = in sbs_get_battery_property()
601 val->intval = in sbs_get_battery_property()
604 val->intval = in sbs_get_battery_property()
612 val->intval = POWER_SUPPLY_STATUS_FULL; in sbs_get_battery_property()
614 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; in sbs_get_battery_property()
616 val->intval = POWER_SUPPLY_STATUS_CHARGING; in sbs_get_battery_property()
618 sbs_status_correct(client, &val->intval); in sbs_get_battery_property()
620 if (chip->poll_time == 0) in sbs_get_battery_property()
621 chip->last_state = val->intval; in sbs_get_battery_property()
622 else if (chip->last_state != val->intval) { in sbs_get_battery_property()
623 cancel_delayed_work_sync(&chip->work); in sbs_get_battery_property()
624 power_supply_changed(chip->power_supply); in sbs_get_battery_property()
625 chip->poll_time = 0; in sbs_get_battery_property()
629 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; in sbs_get_battery_property()
634 val->intval = min(ret, 100); in sbs_get_battery_property()
636 val->intval = 0; in sbs_get_battery_property()
669 val->intval *= BATTERY_MODE_CAP_MULT_WATT; in sbs_unit_adjustment()
682 val->intval *= BASE_UNIT_CONVERSION; in sbs_unit_adjustment()
689 val->intval -= TEMP_KELVIN_TO_CELSIUS; in sbs_unit_adjustment()
697 val->intval *= TIME_UNIT_CONVERSION; in sbs_unit_adjustment()
701 dev_dbg(&client->dev, in sbs_unit_adjustment()
750 val->intval = ret; in sbs_get_battery_capacity()
770 val->strval = sbs_serial; in sbs_get_battery_serial_number()
778 int count; in sbs_get_property_index() local
779 for (count = 0; count < ARRAY_SIZE(sbs_data); count++) in sbs_get_property_index()
780 if (psp == sbs_data[count].psp) in sbs_get_property_index()
781 return count; in sbs_get_property_index()
783 dev_warn(&client->dev, in sbs_get_property_index()
784 "%s: Invalid Property - %d\n", __func__, psp); in sbs_get_property_index()
786 return -EINVAL; in sbs_get_property_index()
805 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; in sbs_get_chemistry()
807 val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; in sbs_get_chemistry()
809 val->intval = POWER_SUPPLY_TECHNOLOGY_NiCd; in sbs_get_chemistry()
811 val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH; in sbs_get_chemistry()
813 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; in sbs_get_chemistry()
815 if (val->intval == POWER_SUPPLY_TECHNOLOGY_UNKNOWN) in sbs_get_chemistry()
816 dev_warn(&client->dev, "Unknown chemistry: %s\n", chemistry); in sbs_get_chemistry()
838 val->intval = year; in sbs_get_battery_manufacture_date()
841 val->intval = month; in sbs_get_battery_manufacture_date()
844 val->intval = day; in sbs_get_battery_manufacture_date()
847 return -EINVAL; in sbs_get_battery_manufacture_date()
859 struct i2c_client *client = chip->client; in sbs_get_property()
861 if (chip->gpio_detect) { in sbs_get_property()
862 ret = gpiod_get_value_cansleep(chip->gpio_detect); in sbs_get_property()
866 val->intval = ret; in sbs_get_property()
871 return -ENODATA; in sbs_get_property()
905 mutex_lock(&chip->mode_lock); in sbs_get_property()
907 mutex_unlock(&chip->mode_lock); in sbs_get_property()
943 val->strval = model_name; in sbs_get_property()
953 val->strval = manufacturer; in sbs_get_property()
963 dev_err(&client->dev, in sbs_get_property()
965 return -EINVAL; in sbs_get_property()
968 if (!chip->gpio_detect && chip->is_present != (ret >= 0)) { in sbs_get_property()
969 bool old_present = chip->is_present; in sbs_get_property()
976 if (old_present != chip->is_present) in sbs_get_property()
977 power_supply_changed(chip->power_supply); in sbs_get_property()
984 dev_dbg(&client->dev, in sbs_get_property()
986 psp, val->intval); in sbs_get_property()
987 } else if (!chip->is_present) { in sbs_get_property()
989 ret = -ENODATA; in sbs_get_property()
996 struct power_supply *battery = chip->power_supply; in sbs_supply_changed()
999 ret = gpiod_get_value_cansleep(chip->gpio_detect); in sbs_supply_changed()
1023 cancel_delayed_work_sync(&chip->work); in sbs_external_power_changed()
1025 schedule_delayed_work(&chip->work, HZ); in sbs_external_power_changed()
1026 chip->poll_time = chip->poll_retry_count; in sbs_external_power_changed()
1036 ret = sbs_read_word_data(chip->client, sbs_data[REG_STATUS].addr); in sbs_delayed_work()
1039 chip->poll_time = 0; in sbs_delayed_work()
1050 sbs_status_correct(chip->client, &ret); in sbs_delayed_work()
1052 if (chip->last_state != ret) { in sbs_delayed_work()
1053 chip->poll_time = 0; in sbs_delayed_work()
1054 power_supply_changed(chip->power_supply); in sbs_delayed_work()
1057 if (chip->poll_time > 0) { in sbs_delayed_work()
1058 schedule_delayed_work(&chip->work, HZ); in sbs_delayed_work()
1059 chip->poll_time--; in sbs_delayed_work()
1076 struct sbs_platform_data *pdata = client->dev.platform_data; in sbs_probe()
1081 sbs_desc = devm_kmemdup(&client->dev, &sbs_default_desc, in sbs_probe()
1084 return -ENOMEM; in sbs_probe()
1086 sbs_desc->name = devm_kasprintf(&client->dev, GFP_KERNEL, "sbs-%s", in sbs_probe()
1087 dev_name(&client->dev)); in sbs_probe()
1088 if (!sbs_desc->name) in sbs_probe()
1089 return -ENOMEM; in sbs_probe()
1091 chip = devm_kzalloc(&client->dev, sizeof(struct sbs_info), GFP_KERNEL); in sbs_probe()
1093 return -ENOMEM; in sbs_probe()
1095 chip->flags = (u32)(uintptr_t)device_get_match_data(&client->dev); in sbs_probe()
1096 chip->client = client; in sbs_probe()
1097 psy_cfg.of_node = client->dev.of_node; in sbs_probe()
1099 chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN; in sbs_probe()
1100 mutex_init(&chip->mode_lock); in sbs_probe()
1105 rc = device_property_read_u32(&client->dev, "sbs,i2c-retry-count", in sbs_probe()
1106 &chip->i2c_retry_count); in sbs_probe()
1108 chip->i2c_retry_count = 0; in sbs_probe()
1110 rc = device_property_read_u32(&client->dev, "sbs,poll-retry-count", in sbs_probe()
1111 &chip->poll_retry_count); in sbs_probe()
1113 chip->poll_retry_count = 0; in sbs_probe()
1116 chip->poll_retry_count = pdata->poll_retry_count; in sbs_probe()
1117 chip->i2c_retry_count = pdata->i2c_retry_count; in sbs_probe()
1119 chip->i2c_retry_count = chip->i2c_retry_count + 1; in sbs_probe()
1121 chip->charger_broadcasts = !device_property_read_bool(&client->dev, in sbs_probe()
1122 "sbs,disable-charger-broadcasts"); in sbs_probe()
1124 chip->gpio_detect = devm_gpiod_get_optional(&client->dev, in sbs_probe()
1125 "sbs,battery-detect", GPIOD_IN); in sbs_probe()
1126 if (IS_ERR(chip->gpio_detect)) { in sbs_probe()
1127 dev_err(&client->dev, "Failed to get gpio: %ld\n", in sbs_probe()
1128 PTR_ERR(chip->gpio_detect)); in sbs_probe()
1129 return PTR_ERR(chip->gpio_detect); in sbs_probe()
1134 if (!chip->gpio_detect) in sbs_probe()
1137 irq = gpiod_to_irq(chip->gpio_detect); in sbs_probe()
1139 dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq); in sbs_probe()
1143 rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq, in sbs_probe()
1145 dev_name(&client->dev), chip); in sbs_probe()
1147 dev_warn(&client->dev, "Failed to request irq: %d\n", rc); in sbs_probe()
1156 if (!(force_load || chip->gpio_detect)) { in sbs_probe()
1162 dev_err(&client->dev, "Failed to get present status\n"); in sbs_probe()
1163 rc = -ENODEV; in sbs_probe()
1168 INIT_DELAYED_WORK(&chip->work, sbs_delayed_work); in sbs_probe()
1170 chip->power_supply = devm_power_supply_register(&client->dev, sbs_desc, in sbs_probe()
1172 if (IS_ERR(chip->power_supply)) { in sbs_probe()
1173 dev_err(&client->dev, in sbs_probe()
1175 rc = PTR_ERR(chip->power_supply); in sbs_probe()
1179 dev_info(&client->dev, in sbs_probe()
1180 "%s: battery gas gauge device registered\n", client->name); in sbs_probe()
1192 cancel_delayed_work_sync(&chip->work); in sbs_remove()
1205 if (chip->poll_time > 0) in sbs_suspend()
1206 cancel_delayed_work_sync(&chip->work); in sbs_suspend()
1208 if (chip->flags & SBS_FLAGS_TI_BQ20ZX5) { in sbs_suspend()
1213 if (chip->is_present && ret < 0) in sbs_suspend()
1230 { "sbs-battery", 1 },
1233 MODULE_DEVICE_TABLE(i2c, sbs_id);
1236 { .compatible = "sbs,sbs-battery" },
1255 .name = "sbs-battery",