Lines Matching +full:sbs +full:- +full:battery

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for SBS compliant Smart Battery System Managers
10 * Datasheet SBSM: http://sbs-forum.org/specs/sbsm100b.pdf
13 * Karl-Heinz Schneider <karl-heinz@schneider-inet.de>
19 #include <linux/i2c-mux.h>
62 for (retries = SBSM_RETRY_CNT; retries > 0; retries--) { in sbsm_read_word()
69 dev_err(&client->dev, "failed to read register 0x%02x\n", in sbsm_read_word()
80 for (retries = SBSM_RETRY_CNT; retries > 0; retries--) { in sbsm_write_word()
86 dev_err(&client->dev, "failed to write to register 0x%02x\n", in sbsm_write_word()
101 regval = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATECONT); in sbsm_get_property()
104 val->intval = !!(regval & SBSM_BIT_AC_PRESENT); in sbsm_get_property()
108 regval = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATE); in sbsm_get_property()
113 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; in sbsm_get_property()
116 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; in sbsm_get_property()
118 if (data->is_ltc1760) { in sbsm_get_property()
120 regval = sbsm_read_word(data->client, SBSM_CMD_LTC); in sbsm_get_property()
124 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; in sbsm_get_property()
129 return -EINVAL; in sbsm_get_property()
140 return (psp == POWER_SUPPLY_PROP_CHARGE_TYPE) && data->is_ltc1760; in sbsm_prop_is_writeable()
148 int ret = -EINVAL; in sbsm_set_property()
154 if (!data->is_ltc1760) in sbsm_set_property()
156 regval = val->intval == in sbsm_set_property()
158 ret = sbsm_write_word(data->client, SBSM_CMD_LTC, regval); in sbsm_set_property()
169 * Switch to battery
175 struct device *dev = &data->client->dev; in sbsm_select()
179 if (data->cur_chan == chan) in sbsm_select()
184 ret = sbsm_write_word(data->client, SBSM_CMD_BATSYSSTATE, reg); in sbsm_select()
188 data->cur_chan = chan; in sbsm_select()
198 ret = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATE); in sbsm_gpio_get_value()
219 if (!client || client->addr != 0x0b) in sbsm_do_alert()
223 if (client->dev.driver) { in sbsm_do_alert()
224 driver = to_i2c_driver(client->dev.driver); in sbsm_do_alert()
225 if (driver->alert) in sbsm_do_alert()
226 driver->alert(client, I2C_PROTOCOL_SMBUS_ALERT, 0); in sbsm_do_alert()
228 dev_warn(&client->dev, "no driver alert()!\n"); in sbsm_do_alert()
230 dev_dbg(&client->dev, "alert with no driver\n"); in sbsm_do_alert()
234 return -EBUSY; in sbsm_do_alert()
244 ret = sbsm_read_word(sbsm->client, SBSM_CMD_BATSYSSTATE); in sbsm_alert()
246 irq_bat = ret ^ sbsm->last_state; in sbsm_alert()
247 sbsm->last_state = ret; in sbsm_alert()
251 ret = sbsm_read_word(sbsm->client, SBSM_CMD_BATSYSSTATECONT); in sbsm_alert()
253 ((ret ^ sbsm->last_state_cont) & SBSM_BIT_AC_PRESENT)) { in sbsm_alert()
254 irq_bat |= sbsm->supported_bats & state; in sbsm_alert()
255 power_supply_changed(sbsm->psy); in sbsm_alert()
257 sbsm->last_state_cont = ret; in sbsm_alert()
261 device_for_each_child(&sbsm->muxc->adapter[i]->dev, in sbsm_alert()
269 struct gpio_chip *gc = &data->chip; in sbsm_gpio_setup()
270 struct i2c_client *client = data->client; in sbsm_gpio_setup()
271 struct device *dev = &client->dev; in sbsm_gpio_setup()
274 if (!device_property_present(dev, "gpio-controller")) in sbsm_gpio_setup()
280 data->last_state = ret; in sbsm_gpio_setup()
285 data->last_state_cont = ret; in sbsm_gpio_setup()
287 gc->get = sbsm_gpio_get_value; in sbsm_gpio_setup()
288 gc->direction_input = sbsm_gpio_direction_input; in sbsm_gpio_setup()
289 gc->can_sleep = true; in sbsm_gpio_setup()
290 gc->base = -1; in sbsm_gpio_setup()
291 gc->ngpio = SBSM_MAX_BATS; in sbsm_gpio_setup()
292 gc->label = client->name; in sbsm_gpio_setup()
293 gc->parent = dev; in sbsm_gpio_setup()
294 gc->owner = THIS_MODULE; in sbsm_gpio_setup()
317 struct i2c_adapter *adapter = client->adapter; in sbsm_probe()
319 struct device *dev = &client->dev; in sbsm_probe()
325 if (client->addr != 0x0a) in sbsm_probe()
326 return -EINVAL; in sbsm_probe()
329 return -EPFNOSUPPORT; in sbsm_probe()
333 return -ENOMEM; in sbsm_probe()
337 data->client = client; in sbsm_probe()
338 data->is_ltc1760 = !!strstr(id->name, "ltc1760"); in sbsm_probe()
343 data->supported_bats = ret & SBSM_MASK_BAT_SUPPORTED; in sbsm_probe()
344 data->muxc = i2c_mux_alloc(adapter, dev, SBSM_MAX_BATS, 0, in sbsm_probe()
346 if (!data->muxc) { in sbsm_probe()
348 ret = -ENOMEM; in sbsm_probe()
351 data->muxc->priv = data; in sbsm_probe()
353 /* register muxed i2c channels. One for each supported battery */ in sbsm_probe()
355 if (data->supported_bats & BIT(i)) { in sbsm_probe()
356 ret = i2c_mux_add_adapter(data->muxc, 0, i + 1, 0); in sbsm_probe()
370 ret = -ENOMEM; in sbsm_probe()
374 psy_desc->name = devm_kasprintf(dev, GFP_KERNEL, "sbsm-%s", in sbsm_probe()
375 dev_name(&client->dev)); in sbsm_probe()
376 if (!psy_desc->name) { in sbsm_probe()
377 ret = -ENOMEM; in sbsm_probe()
385 psy_cfg.of_node = dev->of_node; in sbsm_probe()
386 data->psy = devm_power_supply_register(dev, psy_desc, &psy_cfg); in sbsm_probe()
387 if (IS_ERR(data->psy)) { in sbsm_probe()
388 ret = PTR_ERR(data->psy); in sbsm_probe()
390 psy_desc->name); in sbsm_probe()
398 i2c_mux_del_adapters(data->muxc); in sbsm_probe()
408 i2c_mux_del_adapters(data->muxc); in sbsm_remove()
413 { "sbs-manager", 0 },
421 { .compatible = "sbs,sbs-manager" },
441 MODULE_AUTHOR("Karl-Heinz Schneider <karl-heinz@schneider-inet.de>");
442 MODULE_DESCRIPTION("SBSM Smart Battery System Manager");