1 /*
2  * Driver for SBS compliant Smart Battery System Managers
3  *
4  * The device communicates via i2c at address 0x0a and multiplexes access to up
5  * to four smart batteries at address 0x0b.
6  *
7  * Via sysfs interface the online state and charge type are presented.
8  *
9  * Datasheet SBSM:    http://sbs-forum.org/specs/sbsm100b.pdf
10  * Datasheet LTC1760: http://cds.linear.com/docs/en/datasheet/1760fb.pdf
11  *
12  * Karl-Heinz Schneider <karl-heinz@schneider-inet.de>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License version 2 as
16  * published by the Free Software Foundation.
17  */
18 
19 #include <linux/gpio.h>
20 #include <linux/module.h>
21 #include <linux/i2c.h>
22 #include <linux/i2c-mux.h>
23 #include <linux/power_supply.h>
24 #include <linux/property.h>
25 
26 #define SBSM_MAX_BATS  4
27 #define SBSM_RETRY_CNT 3
28 
29 /* registers addresses */
30 #define SBSM_CMD_BATSYSSTATE     0x01
31 #define SBSM_CMD_BATSYSSTATECONT 0x02
32 #define SBSM_CMD_BATSYSINFO      0x04
33 #define SBSM_CMD_LTC             0x3c
34 
35 #define SBSM_MASK_BAT_SUPPORTED  GENMASK(3, 0)
36 #define SBSM_MASK_CHARGE_BAT     GENMASK(7, 4)
37 #define SBSM_BIT_AC_PRESENT      BIT(0)
38 #define SBSM_BIT_TURBO           BIT(7)
39 
40 #define SBSM_SMB_BAT_OFFSET      11
41 struct sbsm_data {
42 	struct i2c_client *client;
43 	struct i2c_mux_core *muxc;
44 
45 	struct power_supply *psy;
46 
47 	u8 cur_chan;          /* currently selected channel */
48 	struct gpio_chip chip;
49 	bool is_ltc1760;      /* special capabilities */
50 
51 	unsigned int supported_bats;
52 	unsigned int last_state;
53 	unsigned int last_state_cont;
54 };
55 
56 static enum power_supply_property sbsm_props[] = {
57 	POWER_SUPPLY_PROP_ONLINE,
58 	POWER_SUPPLY_PROP_CHARGE_TYPE,
59 };
60 
61 static int sbsm_read_word(struct i2c_client *client, u8 address)
62 {
63 	int reg, retries;
64 
65 	for (retries = SBSM_RETRY_CNT; retries > 0; retries--) {
66 		reg = i2c_smbus_read_word_data(client, address);
67 		if (reg >= 0)
68 			break;
69 	}
70 
71 	if (reg < 0) {
72 		dev_err(&client->dev, "failed to read register 0x%02x\n",
73 			address);
74 	}
75 
76 	return reg;
77 }
78 
79 static int sbsm_write_word(struct i2c_client *client, u8 address, u16 word)
80 {
81 	int ret, retries;
82 
83 	for (retries = SBSM_RETRY_CNT; retries > 0; retries--) {
84 		ret = i2c_smbus_write_word_data(client, address, word);
85 		if (ret >= 0)
86 			break;
87 	}
88 	if (ret < 0)
89 		dev_err(&client->dev, "failed to write to register 0x%02x\n",
90 			address);
91 
92 	return ret;
93 }
94 
95 static int sbsm_get_property(struct power_supply *psy,
96 			     enum power_supply_property psp,
97 			     union power_supply_propval *val)
98 {
99 	struct sbsm_data *data = power_supply_get_drvdata(psy);
100 	int regval = 0;
101 
102 	switch (psp) {
103 	case POWER_SUPPLY_PROP_ONLINE:
104 		regval = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATECONT);
105 		if (regval < 0)
106 			return regval;
107 		val->intval = !!(regval & SBSM_BIT_AC_PRESENT);
108 		break;
109 
110 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
111 		regval = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATE);
112 		if (regval < 0)
113 			return regval;
114 
115 		if ((regval & SBSM_MASK_CHARGE_BAT) == 0) {
116 			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
117 			return 0;
118 		}
119 		val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
120 
121 		if (data->is_ltc1760) {
122 			/* charge mode fast if turbo is active */
123 			regval = sbsm_read_word(data->client, SBSM_CMD_LTC);
124 			if (regval < 0)
125 				return regval;
126 			else if (regval & SBSM_BIT_TURBO)
127 				val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
128 		}
129 		break;
130 
131 	default:
132 		return -EINVAL;
133 	}
134 
135 	return 0;
136 }
137 
138 static int sbsm_prop_is_writeable(struct power_supply *psy,
139 				  enum power_supply_property psp)
140 {
141 	struct sbsm_data *data = power_supply_get_drvdata(psy);
142 
143 	return (psp == POWER_SUPPLY_PROP_CHARGE_TYPE) && data->is_ltc1760;
144 }
145 
146 static int sbsm_set_property(struct power_supply *psy,
147 			     enum power_supply_property psp,
148 			     const union power_supply_propval *val)
149 {
150 	struct sbsm_data *data = power_supply_get_drvdata(psy);
151 	int ret = -EINVAL;
152 	u16 regval;
153 
154 	switch (psp) {
155 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
156 		/* write 1 to TURBO if type fast is given */
157 		if (!data->is_ltc1760)
158 			break;
159 		regval = val->intval ==
160 			 POWER_SUPPLY_CHARGE_TYPE_FAST ? SBSM_BIT_TURBO : 0;
161 		ret = sbsm_write_word(data->client, SBSM_CMD_LTC, regval);
162 		break;
163 
164 	default:
165 		break;
166 	}
167 
168 	return ret;
169 }
170 
171 /*
172  * Switch to battery
173  * Parameter chan is directly the content of SMB_BAT* nibble
174  */
175 static int sbsm_select(struct i2c_mux_core *muxc, u32 chan)
176 {
177 	struct sbsm_data *data = i2c_mux_priv(muxc);
178 	struct device *dev = &data->client->dev;
179 	int ret = 0;
180 	u16 reg;
181 
182 	if (data->cur_chan == chan)
183 		return ret;
184 
185 	/* chan goes from 1 ... 4 */
186 	reg = BIT(SBSM_SMB_BAT_OFFSET + chan);
187 	ret = sbsm_write_word(data->client, SBSM_CMD_BATSYSSTATE, reg);
188 	if (ret)
189 		dev_err(dev, "Failed to select channel %i\n", chan);
190 	else
191 		data->cur_chan = chan;
192 
193 	return ret;
194 }
195 
196 static int sbsm_gpio_get_value(struct gpio_chip *gc, unsigned int off)
197 {
198 	struct sbsm_data *data = gpiochip_get_data(gc);
199 	int ret;
200 
201 	ret = sbsm_read_word(data->client, SBSM_CMD_BATSYSSTATE);
202 	if (ret < 0)
203 		return ret;
204 
205 	return ret & BIT(off);
206 }
207 
208 /*
209  * This needs to be defined or the GPIO lib fails to register the pin.
210  * But the 'gpio' is always an input.
211  */
212 static int sbsm_gpio_direction_input(struct gpio_chip *gc, unsigned int off)
213 {
214 	return 0;
215 }
216 
217 static int sbsm_do_alert(struct device *dev, void *d)
218 {
219 	struct i2c_client *client = i2c_verify_client(dev);
220 	struct i2c_driver *driver;
221 
222 	if (!client || client->addr != 0x0b)
223 		return 0;
224 
225 	device_lock(dev);
226 	if (client->dev.driver) {
227 		driver = to_i2c_driver(client->dev.driver);
228 		if (driver->alert)
229 			driver->alert(client, I2C_PROTOCOL_SMBUS_ALERT, 0);
230 		else
231 			dev_warn(&client->dev, "no driver alert()!\n");
232 	} else {
233 		dev_dbg(&client->dev, "alert with no driver\n");
234 	}
235 	device_unlock(dev);
236 
237 	return -EBUSY;
238 }
239 
240 static void sbsm_alert(struct i2c_client *client, enum i2c_alert_protocol prot,
241 		       unsigned int d)
242 {
243 	struct sbsm_data *sbsm = i2c_get_clientdata(client);
244 
245 	int ret, i, irq_bat = 0, state = 0;
246 
247 	ret = sbsm_read_word(sbsm->client, SBSM_CMD_BATSYSSTATE);
248 	if (ret >= 0) {
249 		irq_bat = ret ^ sbsm->last_state;
250 		sbsm->last_state = ret;
251 		state = ret;
252 	}
253 
254 	ret = sbsm_read_word(sbsm->client, SBSM_CMD_BATSYSSTATECONT);
255 	if ((ret >= 0) &&
256 	    ((ret ^ sbsm->last_state_cont) & SBSM_BIT_AC_PRESENT)) {
257 		irq_bat |= sbsm->supported_bats & state;
258 		power_supply_changed(sbsm->psy);
259 	}
260 	sbsm->last_state_cont = ret;
261 
262 	for (i = 0; i < SBSM_MAX_BATS; i++) {
263 		if (irq_bat & BIT(i)) {
264 			device_for_each_child(&sbsm->muxc->adapter[i]->dev,
265 					      NULL, sbsm_do_alert);
266 		}
267 	}
268 }
269 
270 static int sbsm_gpio_setup(struct sbsm_data *data)
271 {
272 	struct gpio_chip *gc = &data->chip;
273 	struct i2c_client *client = data->client;
274 	struct device *dev = &client->dev;
275 	int ret;
276 
277 	if (!device_property_present(dev, "gpio-controller"))
278 		return 0;
279 
280 	ret  = sbsm_read_word(client, SBSM_CMD_BATSYSSTATE);
281 	if (ret < 0)
282 		return ret;
283 	data->last_state = ret;
284 
285 	ret  = sbsm_read_word(client, SBSM_CMD_BATSYSSTATECONT);
286 	if (ret < 0)
287 		return ret;
288 	data->last_state_cont = ret;
289 
290 	gc->get = sbsm_gpio_get_value;
291 	gc->direction_input  = sbsm_gpio_direction_input;
292 	gc->can_sleep = true;
293 	gc->base = -1;
294 	gc->ngpio = SBSM_MAX_BATS;
295 	gc->label = client->name;
296 	gc->parent = dev;
297 	gc->owner = THIS_MODULE;
298 
299 	ret = devm_gpiochip_add_data(dev, gc, data);
300 	if (ret) {
301 		dev_err(dev, "devm_gpiochip_add_data failed: %d\n", ret);
302 		return ret;
303 	}
304 
305 	return ret;
306 }
307 
308 static const struct power_supply_desc sbsm_default_psy_desc = {
309 	.type = POWER_SUPPLY_TYPE_MAINS,
310 	.properties = sbsm_props,
311 	.num_properties = ARRAY_SIZE(sbsm_props),
312 	.get_property = &sbsm_get_property,
313 	.set_property = &sbsm_set_property,
314 	.property_is_writeable = &sbsm_prop_is_writeable,
315 };
316 
317 static int sbsm_probe(struct i2c_client *client,
318 		      const struct i2c_device_id *id)
319 {
320 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
321 	struct sbsm_data *data;
322 	struct device *dev = &client->dev;
323 	struct power_supply_desc *psy_desc;
324 	struct power_supply_config psy_cfg = {};
325 	int ret = 0, i;
326 
327 	/* Device listens only at address 0x0a */
328 	if (client->addr != 0x0a)
329 		return -EINVAL;
330 
331 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
332 		return -EPFNOSUPPORT;
333 
334 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
335 	if (!data)
336 		return -ENOMEM;
337 
338 	i2c_set_clientdata(client, data);
339 
340 	data->client = client;
341 	data->is_ltc1760 = !!strstr(id->name, "ltc1760");
342 
343 	ret  = sbsm_read_word(client, SBSM_CMD_BATSYSINFO);
344 	if (ret < 0)
345 		return ret;
346 	data->supported_bats = ret & SBSM_MASK_BAT_SUPPORTED;
347 	data->muxc = i2c_mux_alloc(adapter, dev, SBSM_MAX_BATS, 0,
348 				   I2C_MUX_LOCKED, &sbsm_select, NULL);
349 	if (!data->muxc) {
350 		dev_err(dev, "failed to alloc i2c mux\n");
351 		ret = -ENOMEM;
352 		goto err_mux_alloc;
353 	}
354 	data->muxc->priv = data;
355 
356 	/* register muxed i2c channels. One for each supported battery */
357 	for (i = 0; i < SBSM_MAX_BATS; ++i) {
358 		if (data->supported_bats & BIT(i)) {
359 			ret = i2c_mux_add_adapter(data->muxc, 0, i + 1, 0);
360 			if (ret)
361 				break;
362 		}
363 	}
364 	if (ret) {
365 		dev_err(dev, "failed to register i2c mux channel %d\n", i + 1);
366 		goto err_mux_register;
367 	}
368 
369 	psy_desc = devm_kmemdup(dev, &sbsm_default_psy_desc,
370 				sizeof(struct power_supply_desc),
371 				GFP_KERNEL);
372 	if (!psy_desc) {
373 		ret = -ENOMEM;
374 		goto err_psy;
375 	}
376 
377 	psy_desc->name = devm_kasprintf(dev, GFP_KERNEL, "sbsm-%s",
378 					dev_name(&client->dev));
379 	if (!psy_desc->name) {
380 		ret = -ENOMEM;
381 		goto err_psy;
382 	}
383 	ret = sbsm_gpio_setup(data);
384 	if (ret < 0)
385 		goto err_psy;
386 
387 	psy_cfg.drv_data = data;
388 	psy_cfg.of_node = dev->of_node;
389 	data->psy = devm_power_supply_register(dev, psy_desc, &psy_cfg);
390 	if (IS_ERR(data->psy)) {
391 		ret = PTR_ERR(data->psy);
392 		dev_err(dev, "failed to register power supply %s\n",
393 			psy_desc->name);
394 		goto err_psy;
395 	}
396 
397 	return 0;
398 
399 err_psy:
400 err_mux_register:
401 	i2c_mux_del_adapters(data->muxc);
402 
403 err_mux_alloc:
404 	return ret;
405 }
406 
407 static int sbsm_remove(struct i2c_client *client)
408 {
409 	struct sbsm_data *data = i2c_get_clientdata(client);
410 
411 	i2c_mux_del_adapters(data->muxc);
412 	return 0;
413 }
414 
415 static const struct i2c_device_id sbsm_ids[] = {
416 	{ "sbs-manager", 0 },
417 	{ "ltc1760",     0 },
418 	{ }
419 };
420 MODULE_DEVICE_TABLE(i2c, sbsm_ids);
421 
422 #ifdef CONFIG_OF
423 static const struct of_device_id sbsm_dt_ids[] = {
424 	{ .compatible = "sbs,sbs-manager" },
425 	{ .compatible = "lltc,ltc1760" },
426 	{ }
427 };
428 MODULE_DEVICE_TABLE(of, sbsm_dt_ids);
429 #endif
430 
431 static struct i2c_driver sbsm_driver = {
432 	.driver = {
433 		.name = "sbsm",
434 		.of_match_table = of_match_ptr(sbsm_dt_ids),
435 	},
436 	.probe		= sbsm_probe,
437 	.remove		= sbsm_remove,
438 	.alert		= sbsm_alert,
439 	.id_table	= sbsm_ids
440 };
441 module_i2c_driver(sbsm_driver);
442 
443 MODULE_LICENSE("GPL");
444 MODULE_AUTHOR("Karl-Heinz Schneider <karl-heinz@schneider-inet.de>");
445 MODULE_DESCRIPTION("SBSM Smart Battery System Manager");
446