1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for SBS compliant Smart Battery System Managers
5 * The device communicates via i2c at address 0x0a and multiplexes access to up
6 * to four smart batteries at address 0x0b.
8 * Via sysfs interface the online state and charge type are presented.
10 * Datasheet SBSM: http://sbs-forum.org/specs/sbsm100b.pdf
11 * Datasheet LTC1760: http://cds.linear.com/docs/en/datasheet/1760fb.pdf
13 * Karl-Heinz Schneider <karl-heinz@schneider-inet.de>
16 #include <linux/gpio.h>
17 #include <linux/module.h>
18 #include <linux/i2c.h>
19 #include <linux/i2c-mux.h>
20 #include <linux/power_supply.h>
21 #include <linux/property.h>
23 #define SBSM_MAX_BATS 4
24 #define SBSM_RETRY_CNT 3
26 /* registers addresses */
27 #define SBSM_CMD_BATSYSSTATE 0x01
28 #define SBSM_CMD_BATSYSSTATECONT 0x02
29 #define SBSM_CMD_BATSYSINFO 0x04
30 #define SBSM_CMD_LTC 0x3c
32 #define SBSM_MASK_BAT_SUPPORTED GENMASK(3, 0)
33 #define SBSM_MASK_CHARGE_BAT GENMASK(7, 4)
34 #define SBSM_BIT_AC_PRESENT BIT(0)
35 #define SBSM_BIT_TURBO BIT(7)
37 #define SBSM_SMB_BAT_OFFSET 11
39 struct i2c_client
*client
;
40 struct i2c_mux_core
*muxc
;
42 struct power_supply
*psy
;
44 u8 cur_chan
; /* currently selected channel */
45 struct gpio_chip chip
;
46 bool is_ltc1760
; /* special capabilities */
48 unsigned int supported_bats
;
49 unsigned int last_state
;
50 unsigned int last_state_cont
;
53 static enum power_supply_property sbsm_props
[] = {
54 POWER_SUPPLY_PROP_ONLINE
,
55 POWER_SUPPLY_PROP_CHARGE_TYPE
,
58 static int sbsm_read_word(struct i2c_client
*client
, u8 address
)
62 for (retries
= SBSM_RETRY_CNT
; retries
> 0; retries
--) {
63 reg
= i2c_smbus_read_word_data(client
, address
);
69 dev_err(&client
->dev
, "failed to read register 0x%02x\n",
76 static int sbsm_write_word(struct i2c_client
*client
, u8 address
, u16 word
)
80 for (retries
= SBSM_RETRY_CNT
; retries
> 0; retries
--) {
81 ret
= i2c_smbus_write_word_data(client
, address
, word
);
86 dev_err(&client
->dev
, "failed to write to register 0x%02x\n",
92 static int sbsm_get_property(struct power_supply
*psy
,
93 enum power_supply_property psp
,
94 union power_supply_propval
*val
)
96 struct sbsm_data
*data
= power_supply_get_drvdata(psy
);
100 case POWER_SUPPLY_PROP_ONLINE
:
101 regval
= sbsm_read_word(data
->client
, SBSM_CMD_BATSYSSTATECONT
);
104 val
->intval
= !!(regval
& SBSM_BIT_AC_PRESENT
);
107 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
108 regval
= sbsm_read_word(data
->client
, SBSM_CMD_BATSYSSTATE
);
112 if ((regval
& SBSM_MASK_CHARGE_BAT
) == 0) {
113 val
->intval
= POWER_SUPPLY_CHARGE_TYPE_NONE
;
116 val
->intval
= POWER_SUPPLY_CHARGE_TYPE_TRICKLE
;
118 if (data
->is_ltc1760
) {
119 /* charge mode fast if turbo is active */
120 regval
= sbsm_read_word(data
->client
, SBSM_CMD_LTC
);
123 else if (regval
& SBSM_BIT_TURBO
)
124 val
->intval
= POWER_SUPPLY_CHARGE_TYPE_FAST
;
135 static int sbsm_prop_is_writeable(struct power_supply
*psy
,
136 enum power_supply_property psp
)
138 struct sbsm_data
*data
= power_supply_get_drvdata(psy
);
140 return (psp
== POWER_SUPPLY_PROP_CHARGE_TYPE
) && data
->is_ltc1760
;
143 static int sbsm_set_property(struct power_supply
*psy
,
144 enum power_supply_property psp
,
145 const union power_supply_propval
*val
)
147 struct sbsm_data
*data
= power_supply_get_drvdata(psy
);
152 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
153 /* write 1 to TURBO if type fast is given */
154 if (!data
->is_ltc1760
)
156 regval
= val
->intval
==
157 POWER_SUPPLY_CHARGE_TYPE_FAST
? SBSM_BIT_TURBO
: 0;
158 ret
= sbsm_write_word(data
->client
, SBSM_CMD_LTC
, regval
);
170 * Parameter chan is directly the content of SMB_BAT* nibble
172 static int sbsm_select(struct i2c_mux_core
*muxc
, u32 chan
)
174 struct sbsm_data
*data
= i2c_mux_priv(muxc
);
175 struct device
*dev
= &data
->client
->dev
;
179 if (data
->cur_chan
== chan
)
182 /* chan goes from 1 ... 4 */
183 reg
= BIT(SBSM_SMB_BAT_OFFSET
+ chan
);
184 ret
= sbsm_write_word(data
->client
, SBSM_CMD_BATSYSSTATE
, reg
);
186 dev_err(dev
, "Failed to select channel %i\n", chan
);
188 data
->cur_chan
= chan
;
193 static int sbsm_gpio_get_value(struct gpio_chip
*gc
, unsigned int off
)
195 struct sbsm_data
*data
= gpiochip_get_data(gc
);
198 ret
= sbsm_read_word(data
->client
, SBSM_CMD_BATSYSSTATE
);
202 return ret
& BIT(off
);
206 * This needs to be defined or the GPIO lib fails to register the pin.
207 * But the 'gpio' is always an input.
209 static int sbsm_gpio_direction_input(struct gpio_chip
*gc
, unsigned int off
)
214 static int sbsm_do_alert(struct device
*dev
, void *d
)
216 struct i2c_client
*client
= i2c_verify_client(dev
);
217 struct i2c_driver
*driver
;
219 if (!client
|| client
->addr
!= 0x0b)
223 if (client
->dev
.driver
) {
224 driver
= to_i2c_driver(client
->dev
.driver
);
226 driver
->alert(client
, I2C_PROTOCOL_SMBUS_ALERT
, 0);
228 dev_warn(&client
->dev
, "no driver alert()!\n");
230 dev_dbg(&client
->dev
, "alert with no driver\n");
237 static void sbsm_alert(struct i2c_client
*client
, enum i2c_alert_protocol prot
,
240 struct sbsm_data
*sbsm
= i2c_get_clientdata(client
);
242 int ret
, i
, irq_bat
= 0, state
= 0;
244 ret
= sbsm_read_word(sbsm
->client
, SBSM_CMD_BATSYSSTATE
);
246 irq_bat
= ret
^ sbsm
->last_state
;
247 sbsm
->last_state
= ret
;
251 ret
= sbsm_read_word(sbsm
->client
, SBSM_CMD_BATSYSSTATECONT
);
253 ((ret
^ sbsm
->last_state_cont
) & SBSM_BIT_AC_PRESENT
)) {
254 irq_bat
|= sbsm
->supported_bats
& state
;
255 power_supply_changed(sbsm
->psy
);
257 sbsm
->last_state_cont
= ret
;
259 for (i
= 0; i
< SBSM_MAX_BATS
; i
++) {
260 if (irq_bat
& BIT(i
)) {
261 device_for_each_child(&sbsm
->muxc
->adapter
[i
]->dev
,
262 NULL
, sbsm_do_alert
);
267 static int sbsm_gpio_setup(struct sbsm_data
*data
)
269 struct gpio_chip
*gc
= &data
->chip
;
270 struct i2c_client
*client
= data
->client
;
271 struct device
*dev
= &client
->dev
;
274 if (!device_property_present(dev
, "gpio-controller"))
277 ret
= sbsm_read_word(client
, SBSM_CMD_BATSYSSTATE
);
280 data
->last_state
= ret
;
282 ret
= sbsm_read_word(client
, SBSM_CMD_BATSYSSTATECONT
);
285 data
->last_state_cont
= ret
;
287 gc
->get
= sbsm_gpio_get_value
;
288 gc
->direction_input
= sbsm_gpio_direction_input
;
289 gc
->can_sleep
= true;
291 gc
->ngpio
= SBSM_MAX_BATS
;
292 gc
->label
= client
->name
;
294 gc
->owner
= THIS_MODULE
;
296 ret
= devm_gpiochip_add_data(dev
, gc
, data
);
298 dev_err(dev
, "devm_gpiochip_add_data failed: %d\n", ret
);
305 static const struct power_supply_desc sbsm_default_psy_desc
= {
306 .type
= POWER_SUPPLY_TYPE_MAINS
,
307 .properties
= sbsm_props
,
308 .num_properties
= ARRAY_SIZE(sbsm_props
),
309 .get_property
= &sbsm_get_property
,
310 .set_property
= &sbsm_set_property
,
311 .property_is_writeable
= &sbsm_prop_is_writeable
,
314 static int sbsm_probe(struct i2c_client
*client
,
315 const struct i2c_device_id
*id
)
317 struct i2c_adapter
*adapter
= client
->adapter
;
318 struct sbsm_data
*data
;
319 struct device
*dev
= &client
->dev
;
320 struct power_supply_desc
*psy_desc
;
321 struct power_supply_config psy_cfg
= {};
324 /* Device listens only at address 0x0a */
325 if (client
->addr
!= 0x0a)
328 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_WORD_DATA
))
329 return -EPFNOSUPPORT
;
331 data
= devm_kzalloc(dev
, sizeof(*data
), GFP_KERNEL
);
335 i2c_set_clientdata(client
, data
);
337 data
->client
= client
;
338 data
->is_ltc1760
= !!strstr(id
->name
, "ltc1760");
340 ret
= sbsm_read_word(client
, SBSM_CMD_BATSYSINFO
);
343 data
->supported_bats
= ret
& SBSM_MASK_BAT_SUPPORTED
;
344 data
->muxc
= i2c_mux_alloc(adapter
, dev
, SBSM_MAX_BATS
, 0,
345 I2C_MUX_LOCKED
, &sbsm_select
, NULL
);
347 dev_err(dev
, "failed to alloc i2c mux\n");
351 data
->muxc
->priv
= data
;
353 /* register muxed i2c channels. One for each supported battery */
354 for (i
= 0; i
< SBSM_MAX_BATS
; ++i
) {
355 if (data
->supported_bats
& BIT(i
)) {
356 ret
= i2c_mux_add_adapter(data
->muxc
, 0, i
+ 1, 0);
362 dev_err(dev
, "failed to register i2c mux channel %d\n", i
+ 1);
363 goto err_mux_register
;
366 psy_desc
= devm_kmemdup(dev
, &sbsm_default_psy_desc
,
367 sizeof(struct power_supply_desc
),
374 psy_desc
->name
= devm_kasprintf(dev
, GFP_KERNEL
, "sbsm-%s",
375 dev_name(&client
->dev
));
376 if (!psy_desc
->name
) {
380 ret
= sbsm_gpio_setup(data
);
384 psy_cfg
.drv_data
= data
;
385 psy_cfg
.of_node
= dev
->of_node
;
386 data
->psy
= devm_power_supply_register(dev
, psy_desc
, &psy_cfg
);
387 if (IS_ERR(data
->psy
)) {
388 ret
= PTR_ERR(data
->psy
);
389 dev_err(dev
, "failed to register power supply %s\n",
398 i2c_mux_del_adapters(data
->muxc
);
404 static int sbsm_remove(struct i2c_client
*client
)
406 struct sbsm_data
*data
= i2c_get_clientdata(client
);
408 i2c_mux_del_adapters(data
->muxc
);
412 static const struct i2c_device_id sbsm_ids
[] = {
413 { "sbs-manager", 0 },
417 MODULE_DEVICE_TABLE(i2c
, sbsm_ids
);
420 static const struct of_device_id sbsm_dt_ids
[] = {
421 { .compatible
= "sbs,sbs-manager" },
422 { .compatible
= "lltc,ltc1760" },
425 MODULE_DEVICE_TABLE(of
, sbsm_dt_ids
);
428 static struct i2c_driver sbsm_driver
= {
431 .of_match_table
= of_match_ptr(sbsm_dt_ids
),
434 .remove
= sbsm_remove
,
438 module_i2c_driver(sbsm_driver
);
440 MODULE_LICENSE("GPL");
441 MODULE_AUTHOR("Karl-Heinz Schneider <karl-heinz@schneider-inet.de>");
442 MODULE_DESCRIPTION("SBSM Smart Battery System Manager");