1 /*
2  * Copyright (c) 2020 Linumiz
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Relevant documents:
7  * - BQ27441
8  *   Datasheet: https://www.ti.com/lit/gpn/bq27441-g1
9  *   Technical reference manual: https://www.ti.com/lit/pdf/sluuac9
10  * - BQ27421
11  *   Datasheet: https://www.ti.com/lit/gpn/bq27421-g1
12  *   Technical reference manual: https://www.ti.com/lit/pdf/sluuac5
13  * - BQ27427
14  *   Datasheet: https://www.ti.com/lit/gpn/bq27427
15  *   Technical reference manual: https://www.ti.com/lit/pdf/sluucd5
16  */
17 
18 #define DT_DRV_COMPAT ti_bq274xx
19 
20 #include <zephyr/drivers/i2c.h>
21 #include <zephyr/init.h>
22 #include <zephyr/drivers/sensor.h>
23 #include <zephyr/pm/device.h>
24 #include <zephyr/sys/__assert.h>
25 #include <string.h>
26 #include <zephyr/sys/byteorder.h>
27 #include <zephyr/drivers/gpio.h>
28 #include <zephyr/logging/log.h>
29 
30 #include "bq274xx.h"
31 
32 LOG_MODULE_REGISTER(bq274xx, CONFIG_SENSOR_LOG_LEVEL);
33 
34 /* subclass 64 & 82 needs 5ms delay */
35 #define BQ274XX_SUBCLASS_DELAY K_MSEC(5)
36 
37 /* Time to wait for CFGUP bit to be set, up to 1 second according to the
38  * technical reference manual, keep some headroom like the Linux driver.
39  */
40 #define BQ274XX_CFGUP_DELAY K_MSEC(25)
41 #define BQ274XX_CFGUP_MAX_TRIES 100
42 
43 /* Time to set pin in order to exit shutdown mode */
44 #define PIN_DELAY_TIME K_MSEC(1)
45 
46 /* Delay from power up or shutdown exit to chip entering active state, this is
47  * defined as 250ms typical in the datasheet (Power-up communication delay).
48  */
49 #define POWER_UP_DELAY_MS 300
50 
51 /* Data memory size */
52 #define BQ27XXX_DM_SZ 32
53 
54 /* Config update mode flag */
55 #define BQ27XXX_FLAG_CFGUP BIT(4)
56 
57 /* BQ27427 CC Gain */
58 #define BQ27427_CC_GAIN BQ274XX_EXT_BLKDAT(5)
59 #define BQ27427_CC_GAIN_SIGN_BIT BIT(7)
60 
61 /* Subclasses */
62 #define BQ274XX_SUBCLASS_82 82
63 #define BQ274XX_SUBCLASS_105 105
64 
65 /* For temperature conversion */
66 #define KELVIN_OFFSET 273.15
67 
68 static const struct bq274xx_regs bq27421_regs = {
69 	.dm_design_capacity = 10,
70 	.dm_design_energy = 12,
71 	.dm_terminate_voltage = 16,
72 	.dm_taper_rate = 27,
73 };
74 
75 static const struct bq274xx_regs bq27427_regs = {
76 	.dm_design_capacity = 6,
77 	.dm_design_energy = 8,
78 	.dm_terminate_voltage = 10,
79 	.dm_taper_rate = 21,
80 };
81 
bq274xx_cmd_reg_read(const struct device * dev,uint8_t reg_addr,int16_t * val)82 static int bq274xx_cmd_reg_read(const struct device *dev, uint8_t reg_addr,
83 				int16_t *val)
84 {
85 	const struct bq274xx_config *config = dev->config;
86 	uint8_t i2c_data[2];
87 	int ret;
88 
89 	ret = i2c_burst_read_dt(&config->i2c, reg_addr, i2c_data, sizeof(i2c_data));
90 	if (ret < 0) {
91 		LOG_ERR("Unable to read register");
92 		return -EIO;
93 	}
94 
95 	*val = sys_get_le16(i2c_data);
96 
97 	return 0;
98 }
99 
bq274xx_ctrl_reg_write(const struct device * dev,uint16_t subcommand)100 static int bq274xx_ctrl_reg_write(const struct device *dev, uint16_t subcommand)
101 {
102 	const struct bq274xx_config *config = dev->config;
103 	int ret;
104 
105 	uint8_t tx_buf[3];
106 
107 	tx_buf[0] = BQ274XX_CMD_CONTROL;
108 	sys_put_le16(subcommand, &tx_buf[1]);
109 
110 	ret = i2c_write_dt(&config->i2c, tx_buf, sizeof(tx_buf));
111 	if (ret < 0) {
112 		LOG_ERR("Failed to write into control register");
113 		return -EIO;
114 	}
115 
116 	return 0;
117 }
118 
bq274xx_get_device_type(const struct device * dev,uint16_t * val)119 static int bq274xx_get_device_type(const struct device *dev, uint16_t *val)
120 {
121 	int ret;
122 
123 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_DEVICE_TYPE);
124 	if (ret < 0) {
125 		LOG_ERR("Unable to write control register");
126 		return -EIO;
127 	}
128 
129 	ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_CONTROL, val);
130 	if (ret < 0) {
131 		LOG_ERR("Unable to read register");
132 		return -EIO;
133 	}
134 
135 	return 0;
136 }
137 
bq274xx_read_block(const struct device * dev,uint8_t subclass,uint8_t * block,uint8_t num_bytes)138 static int bq274xx_read_block(const struct device *dev,
139 			      uint8_t subclass,
140 			      uint8_t *block, uint8_t num_bytes)
141 {
142 	const struct bq274xx_config *const config = dev->config;
143 	int ret;
144 
145 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_DATA_CLASS, subclass);
146 	if (ret < 0) {
147 		LOG_ERR("Failed to update state subclass");
148 		return -EIO;
149 	}
150 
151 	/* DataBlock(), 0 for the first 32 bytes. */
152 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_DATA_BLOCK, 0x00);
153 	if (ret < 0) {
154 		LOG_ERR("Failed to update block offset");
155 		return -EIO;
156 	}
157 
158 	k_sleep(BQ274XX_SUBCLASS_DELAY);
159 
160 	ret = i2c_burst_read_dt(&config->i2c, BQ274XX_EXT_BLKDAT_START, block, num_bytes);
161 	if (ret < 0) {
162 		LOG_ERR("Unable to read block data");
163 		return -EIO;
164 	}
165 
166 	return 0;
167 }
168 
bq274xx_write_block(const struct device * dev,uint8_t * block,uint8_t num_bytes)169 static int bq274xx_write_block(const struct device *dev,
170 			       uint8_t *block, uint8_t num_bytes)
171 {
172 	const struct bq274xx_config *const config = dev->config;
173 	uint8_t checksum = 0;
174 	int ret;
175 	uint8_t buf[1 + BQ27XXX_DM_SZ];
176 
177 	__ASSERT_NO_MSG(num_bytes <= BQ27XXX_DM_SZ);
178 
179 	buf[0] = BQ274XX_EXT_BLKDAT_START;
180 	memcpy(&buf[1], block, num_bytes);
181 
182 	ret = i2c_write_dt(&config->i2c, buf, 1 + num_bytes);
183 	if (ret < 0) {
184 		LOG_ERR("Unable to write block data");
185 		return -EIO;
186 	}
187 
188 	for (uint8_t i = 0; i < num_bytes; i++) {
189 		checksum += block[i];
190 	}
191 	checksum = 0xff - checksum;
192 
193 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_CHECKSUM, checksum);
194 	if (ret < 0) {
195 		LOG_ERR("Failed to update block checksum");
196 		return -EIO;
197 	}
198 
199 	k_sleep(BQ274XX_SUBCLASS_DELAY);
200 
201 	return 0;
202 }
203 
bq274xx_update_block(uint8_t * block,uint8_t offset,uint16_t val,bool * block_modified)204 static void bq274xx_update_block(uint8_t *block,
205 				 uint8_t offset, uint16_t val,
206 				 bool *block_modified)
207 {
208 	uint16_t old_val;
209 
210 	old_val = sys_get_be16(&block[offset]);
211 
212 	LOG_DBG("update block: off=%d old=%d new=%d\n", offset, old_val, val);
213 
214 	if (val == old_val) {
215 		return;
216 	}
217 
218 	sys_put_be16(val, &block[offset]);
219 
220 	*block_modified = true;
221 }
222 
bq274xx_mode_cfgupdate(const struct device * dev,bool enabled)223 static int bq274xx_mode_cfgupdate(const struct device *dev, bool enabled)
224 {
225 	uint16_t flags;
226 	uint8_t try;
227 	int ret;
228 	uint16_t val = enabled ? BQ274XX_CTRL_SET_CFGUPDATE : BQ274XX_CTRL_SOFT_RESET;
229 	bool enabled_flag;
230 
231 	ret = bq274xx_ctrl_reg_write(dev, val);
232 	if (ret < 0) {
233 		LOG_ERR("Unable to set device mode to %02x", val);
234 		return -EIO;
235 	}
236 
237 	for (try = 0; try < BQ274XX_CFGUP_MAX_TRIES; try++) {
238 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_FLAGS, &flags);
239 		if (ret < 0) {
240 			LOG_ERR("Unable to read flags");
241 			return -EIO;
242 		}
243 
244 		enabled_flag =  !!(flags & BQ27XXX_FLAG_CFGUP);
245 		if (enabled_flag == enabled) {
246 			LOG_DBG("CFGUP ready, try %u", try);
247 			break;
248 		}
249 
250 		k_sleep(BQ274XX_CFGUP_DELAY);
251 	}
252 
253 	if (try >= BQ274XX_CFGUP_MAX_TRIES) {
254 		LOG_ERR("Config mode change timeout");
255 		return -EIO;
256 	}
257 
258 	return 0;
259 }
260 
261 /*
262  * BQ27427 needs the CC Gain polarity swapped from the ROM value.
263  * The details are currently only documented in the TI E2E support forum:
264  * https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1215460/bq27427evm-misbehaving-stateofcharge
265  */
bq27427_ccgain_quirk(const struct device * dev)266 static int bq27427_ccgain_quirk(const struct device *dev)
267 {
268 	const struct bq274xx_config *const config = dev->config;
269 	int ret;
270 	uint8_t val, checksum;
271 
272 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_DATA_CLASS,
273 				    BQ274XX_SUBCLASS_105);
274 	if (ret < 0) {
275 		LOG_ERR("Failed to update state subclass");
276 		return -EIO;
277 	}
278 
279 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_DATA_BLOCK, 0x00);
280 	if (ret < 0) {
281 		LOG_ERR("Failed to update block offset");
282 		return -EIO;
283 	}
284 
285 	k_sleep(BQ274XX_SUBCLASS_DELAY);
286 
287 	ret = i2c_reg_read_byte_dt(&config->i2c, BQ27427_CC_GAIN, &val);
288 	if (ret < 0) {
289 		LOG_ERR("Failed to read ccgain");
290 		return -EIO;
291 	}
292 
293 	if (!(val & BQ27427_CC_GAIN_SIGN_BIT)) {
294 		LOG_DBG("bq27427 quirk already applied");
295 		return 0;
296 	}
297 
298 	ret = i2c_reg_read_byte_dt(&config->i2c, BQ274XX_EXT_CHECKSUM, &checksum);
299 	if (ret < 0) {
300 		LOG_ERR("Failed to read block checksum");
301 		return -EIO;
302 	}
303 
304 	/* Flip the sign bit on both value and checksum. */
305 	val ^= BQ27427_CC_GAIN_SIGN_BIT;
306 	checksum ^= BQ27427_CC_GAIN_SIGN_BIT;
307 
308 	LOG_DBG("bq27427: val=%02x checksum=%02x", val, checksum);
309 
310 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ27427_CC_GAIN, val);
311 	if (ret < 0) {
312 		LOG_ERR("Failed to update ccgain");
313 		return -EIO;
314 	}
315 
316 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_CHECKSUM, checksum);
317 	if (ret < 0) {
318 		LOG_ERR("Failed to update block checksum");
319 		return -EIO;
320 	}
321 
322 	k_sleep(BQ274XX_SUBCLASS_DELAY);
323 
324 	return 0;
325 }
326 
bq274xx_ensure_chemistry(const struct device * dev)327 static int bq274xx_ensure_chemistry(const struct device *dev)
328 {
329 	struct bq274xx_data *data = dev->data;
330 	const struct bq274xx_config *const config = dev->config;
331 	uint16_t chem_id = config->chemistry_id;
332 
333 	if (chem_id == 0) {
334 		/* No chemistry ID set, rely on the default of the device.*/
335 		return 0;
336 	}
337 	int ret;
338 	uint16_t val;
339 
340 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_CHEM_ID);
341 	if (ret < 0) {
342 		LOG_ERR("Unable to write control register");
343 		return -EIO;
344 	}
345 
346 	ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_CONTROL, &val);
347 	if (ret < 0) {
348 		LOG_ERR("Unable to read register");
349 		return -EIO;
350 	}
351 
352 	LOG_DBG("Chem ID: %04x", val);
353 
354 	if (val != chem_id) {
355 		/* Only the bq27427 has a configurable Chemistry ID. On bq27421, it depends on the
356 		 * variant of the chip, so just error out if the chemistry ID is wrong.
357 		 */
358 		if (data->regs != &bq27427_regs) {
359 			LOG_ERR("Unable to confirm chemistry ID 0x%04x. Device reported 0x%04x",
360 				chem_id, val);
361 			return -EIO;
362 		}
363 
364 		uint16_t cmd;
365 
366 		switch (val) {
367 		case BQ27427_CHEM_ID_A:
368 			cmd = BQ27427_CTRL_CHEM_A;
369 			break;
370 		case BQ27427_CHEM_ID_B:
371 			cmd = BQ27427_CTRL_CHEM_B;
372 			break;
373 		case BQ27427_CHEM_ID_C:
374 			cmd = BQ27427_CTRL_CHEM_C;
375 			break;
376 		default:
377 			LOG_ERR("Unsupported chemistry ID 0x%04x", val);
378 			return -EINVAL;
379 		}
380 
381 		ret = bq274xx_ctrl_reg_write(dev, cmd);
382 		if (ret < 0) {
383 			LOG_ERR("Unable to configure chemistry");
384 			return -EIO;
385 		}
386 	}
387 	return 0;
388 }
389 
bq274xx_gauge_configure(const struct device * dev)390 static int bq274xx_gauge_configure(const struct device *dev)
391 {
392 	const struct bq274xx_config *const config = dev->config;
393 	struct bq274xx_data *data = dev->data;
394 	const struct bq274xx_regs *regs;
395 	int ret;
396 	uint16_t designenergy_mwh, taperrate;
397 	uint8_t block[BQ27XXX_DM_SZ];
398 	bool block_modified = false;
399 	uint16_t id;
400 
401 	if (data->regs == NULL) {
402 		k_sleep(K_TIMEOUT_ABS_MS(POWER_UP_DELAY_MS));
403 
404 		ret = bq274xx_get_device_type(dev, &id);
405 		if (ret < 0) {
406 			LOG_ERR("Unable to get device ID");
407 			return -EIO;
408 		}
409 
410 		if (id == BQ27421_DEVICE_ID) {
411 			data->regs = &bq27421_regs;
412 		} else if (id == BQ27427_DEVICE_ID) {
413 			data->regs = &bq27427_regs;
414 		} else {
415 			LOG_ERR("Unsupported device ID: 0x%04x", id);
416 			return -ENOTSUP;
417 		}
418 	}
419 	regs = data->regs;
420 
421 	designenergy_mwh = (uint32_t)config->design_capacity * 37 / 10; /* x3.7 */
422 	taperrate = config->design_capacity * 10 / config->taper_current;
423 
424 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_UNSEAL_KEY_A);
425 	if (ret < 0) {
426 		LOG_ERR("Unable to unseal the battery");
427 		return -EIO;
428 	}
429 
430 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_UNSEAL_KEY_B);
431 	if (ret < 0) {
432 		LOG_ERR("Unable to unseal the battery");
433 		return -EIO;
434 	}
435 
436 	ret = bq274xx_mode_cfgupdate(dev, true);
437 	if (ret < 0) {
438 		return ret;
439 	}
440 
441 	ret = i2c_reg_write_byte_dt(&config->i2c, BQ274XX_EXT_DATA_CONTROL, 0x00);
442 	if (ret < 0) {
443 		LOG_ERR("Failed to enable block data memory");
444 		return -EIO;
445 	}
446 
447 	ret = bq274xx_read_block(dev, BQ274XX_SUBCLASS_82, block, sizeof(block));
448 	if (ret < 0) {
449 		return ret;
450 	}
451 
452 	bq274xx_update_block(block,
453 			     regs->dm_design_capacity, config->design_capacity,
454 			     &block_modified);
455 	bq274xx_update_block(block,
456 			     regs->dm_design_energy, designenergy_mwh,
457 			     &block_modified);
458 	bq274xx_update_block(block,
459 			     regs->dm_terminate_voltage, config->terminate_voltage,
460 			     &block_modified);
461 	bq274xx_update_block(block,
462 			     regs->dm_taper_rate, taperrate,
463 			     &block_modified);
464 
465 	if (block_modified) {
466 		LOG_INF("bq274xx: updating fuel gauge parameters");
467 
468 		ret = bq274xx_write_block(dev, block, sizeof(block));
469 		if (ret < 0) {
470 			return ret;
471 		}
472 
473 		if (data->regs == &bq27427_regs) {
474 			ret = bq27427_ccgain_quirk(dev);
475 			if (ret < 0) {
476 				return ret;
477 			}
478 		}
479 
480 		ret = bq274xx_ensure_chemistry(dev);
481 		if (ret < 0) {
482 			return ret;
483 		}
484 
485 		ret = bq274xx_mode_cfgupdate(dev, false);
486 		if (ret < 0) {
487 			return ret;
488 		}
489 	}
490 
491 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_SEALED);
492 	if (ret < 0) {
493 		LOG_ERR("Failed to seal the gauge");
494 		return -EIO;
495 	}
496 
497 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_BAT_INSERT);
498 	if (ret < 0) {
499 		LOG_ERR("Unable to configure BAT Detect");
500 		return -EIO;
501 	}
502 
503 	data->configured = true;
504 
505 	return 0;
506 }
507 
bq274xx_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)508 static int bq274xx_channel_get(const struct device *dev, enum sensor_channel chan,
509 			       struct sensor_value *val)
510 {
511 	struct bq274xx_data *data = dev->data;
512 	int32_t int_temp;
513 
514 	switch (chan) {
515 	case SENSOR_CHAN_GAUGE_VOLTAGE:
516 		val->val1 = ((data->voltage / 1000));
517 		val->val2 = ((data->voltage % 1000) * 1000U);
518 		break;
519 
520 	case SENSOR_CHAN_GAUGE_AVG_CURRENT:
521 		val->val1 = ((data->avg_current / 1000));
522 		val->val2 = ((data->avg_current % 1000) * 1000U);
523 		break;
524 
525 	case SENSOR_CHAN_GAUGE_STDBY_CURRENT:
526 		val->val1 = ((data->stdby_current / 1000));
527 		val->val2 = ((data->stdby_current % 1000) * 1000U);
528 		break;
529 
530 	case SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT:
531 		val->val1 = ((data->max_load_current / 1000));
532 		val->val2 = ((data->max_load_current % 1000) * 1000U);
533 		break;
534 
535 	case SENSOR_CHAN_GAUGE_TEMP:
536 		/* Convert units from 0.1K to 0.01K */
537 		int_temp = data->internal_temperature * 10;
538 		/* Convert to 0.01C */
539 		int_temp -= (int32_t)(100.0 * KELVIN_OFFSET);
540 		val->val1 = int_temp / 100;
541 		val->val2 = (int_temp % 100) * 10000;
542 		break;
543 
544 	case SENSOR_CHAN_GAUGE_STATE_OF_CHARGE:
545 		val->val1 = data->state_of_charge;
546 		val->val2 = 0;
547 		break;
548 
549 	case SENSOR_CHAN_GAUGE_STATE_OF_HEALTH:
550 		val->val1 = data->state_of_health;
551 		val->val2 = 0;
552 		break;
553 
554 	case SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY:
555 		val->val1 = data->full_charge_capacity;
556 		val->val2 = 0;
557 		break;
558 
559 	case SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY:
560 		val->val1 = data->remaining_charge_capacity;
561 		val->val2 = 0;
562 		break;
563 
564 	case SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY:
565 		val->val1 = data->nom_avail_capacity;
566 		val->val2 = 0;
567 		break;
568 
569 	case SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY:
570 		val->val1 = data->full_avail_capacity;
571 		val->val2 = 0;
572 		break;
573 
574 	case SENSOR_CHAN_GAUGE_AVG_POWER:
575 		val->val1 = data->avg_power;
576 		val->val2 = 0;
577 		break;
578 
579 	default:
580 		return -ENOTSUP;
581 	}
582 
583 	return 0;
584 }
585 
bq274xx_sample_fetch(const struct device * dev,enum sensor_channel chan)586 static int bq274xx_sample_fetch(const struct device *dev, enum sensor_channel chan)
587 {
588 	struct bq274xx_data *data = dev->data;
589 	int ret = -ENOTSUP;
590 
591 	if (!data->configured) {
592 		ret = bq274xx_gauge_configure(dev);
593 		if (ret < 0) {
594 			return ret;
595 		}
596 	}
597 
598 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_VOLTAGE) {
599 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_VOLTAGE,
600 					   &data->voltage);
601 		if (ret < 0) {
602 			LOG_ERR("Failed to read voltage");
603 			return -EIO;
604 		}
605 	}
606 
607 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_AVG_CURRENT) {
608 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_AVG_CURRENT,
609 					   &data->avg_current);
610 		if (ret < 0) {
611 			LOG_ERR("Failed to read average current ");
612 			return -EIO;
613 		}
614 	}
615 
616 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_TEMP) {
617 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_INT_TEMP,
618 					   &data->internal_temperature);
619 		if (ret < 0) {
620 			LOG_ERR("Failed to read internal temperature");
621 			return -EIO;
622 		}
623 	}
624 
625 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_STDBY_CURRENT) {
626 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_STDBY_CURRENT,
627 					   &data->stdby_current);
628 		if (ret < 0) {
629 			LOG_ERR("Failed to read standby current");
630 			return -EIO;
631 		}
632 	}
633 
634 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT) {
635 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_MAX_CURRENT,
636 					   &data->max_load_current);
637 		if (ret < 0) {
638 			LOG_ERR("Failed to read maximum current");
639 			return -EIO;
640 		}
641 	}
642 
643 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_STATE_OF_CHARGE) {
644 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_SOC,
645 					   &data->state_of_charge);
646 		if (ret < 0) {
647 			LOG_ERR("Failed to read state of charge");
648 			return -EIO;
649 		}
650 	}
651 
652 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY) {
653 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_FULL_CAPACITY,
654 				   &data->full_charge_capacity);
655 		if (ret < 0) {
656 			LOG_ERR("Failed to read full charge capacity");
657 			return -EIO;
658 		}
659 	}
660 
661 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY) {
662 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_REM_CAPACITY,
663 				   &data->remaining_charge_capacity);
664 		if (ret < 0) {
665 			LOG_ERR("Failed to read remaining charge capacity");
666 			return -EIO;
667 		}
668 	}
669 
670 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY) {
671 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_NOM_CAPACITY,
672 				   &data->nom_avail_capacity);
673 		if (ret < 0) {
674 			LOG_ERR("Failed to read nominal available capacity");
675 			return -EIO;
676 		}
677 	}
678 
679 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY) {
680 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_AVAIL_CAPACITY,
681 				   &data->full_avail_capacity);
682 		if (ret < 0) {
683 			LOG_ERR("Failed to read full available capacity");
684 			return -EIO;
685 		}
686 	}
687 
688 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_AVG_POWER) {
689 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_AVG_POWER,
690 					   &data->avg_power);
691 		if (ret < 0) {
692 			LOG_ERR("Failed to read battery average power");
693 			return -EIO;
694 		}
695 	}
696 
697 	if (chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_GAUGE_STATE_OF_HEALTH) {
698 		ret = bq274xx_cmd_reg_read(dev, BQ274XX_CMD_SOH,
699 					   &data->state_of_health);
700 
701 		data->state_of_health = (data->state_of_health) & 0x00FF;
702 
703 		if (ret < 0) {
704 			LOG_ERR("Failed to read state of health");
705 			return -EIO;
706 		}
707 	}
708 
709 	return ret;
710 }
711 
712 /**
713  * @brief initialise the fuel gauge
714  *
715  * @return 0 for success
716  */
bq274xx_gauge_init(const struct device * dev)717 static int bq274xx_gauge_init(const struct device *dev)
718 {
719 	const struct bq274xx_config *const config = dev->config;
720 	int ret = 0;
721 
722 	if (!device_is_ready(config->i2c.bus)) {
723 		LOG_ERR("I2C bus device not ready");
724 		return -ENODEV;
725 	}
726 
727 #if defined(CONFIG_BQ274XX_PM) || defined(CONFIG_BQ274XX_TRIGGER)
728 	if (!gpio_is_ready_dt(&config->int_gpios)) {
729 		LOG_ERR("GPIO device pointer is not ready to be used");
730 		return -ENODEV;
731 	}
732 #endif
733 
734 #ifdef CONFIG_BQ274XX_TRIGGER
735 	ret = bq274xx_trigger_mode_init(dev);
736 	if (ret < 0) {
737 		LOG_ERR("Unable set up trigger mode.");
738 		return ret;
739 	}
740 #endif
741 
742 	if (!config->lazy_loading) {
743 		ret = bq274xx_gauge_configure(dev);
744 	}
745 
746 	return ret;
747 }
748 
749 #ifdef CONFIG_BQ274XX_PM
bq274xx_enter_shutdown_mode(const struct device * dev)750 static int bq274xx_enter_shutdown_mode(const struct device *dev)
751 {
752 	int ret;
753 
754 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_UNSEAL_KEY_A);
755 	if (ret < 0) {
756 		LOG_ERR("Unable to unseal the battery");
757 		return ret;
758 	}
759 
760 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_UNSEAL_KEY_B);
761 	if (ret < 0) {
762 		LOG_ERR("Unable to unseal the battery");
763 		return ret;
764 	}
765 
766 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_SHUTDOWN_ENABLE);
767 	if (ret < 0) {
768 		LOG_ERR("Unable to enable shutdown mode");
769 		return ret;
770 	}
771 
772 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_SHUTDOWN);
773 	if (ret < 0) {
774 		LOG_ERR("Unable to enter shutdown mode");
775 		return ret;
776 	}
777 
778 	ret = bq274xx_ctrl_reg_write(dev, BQ274XX_CTRL_SEALED);
779 	if (ret < 0) {
780 		LOG_ERR("Failed to seal the gauge");
781 		return ret;
782 	}
783 
784 	return 0;
785 }
786 
bq274xx_exit_shutdown_mode(const struct device * dev)787 static int bq274xx_exit_shutdown_mode(const struct device *dev)
788 {
789 	const struct bq274xx_config *const config = dev->config;
790 	int ret;
791 
792 	ret = gpio_pin_configure_dt(&config->int_gpios, GPIO_OUTPUT | GPIO_OPEN_DRAIN);
793 	if (ret < 0) {
794 		LOG_ERR("Unable to configure interrupt pin to output and open drain");
795 		return ret;
796 	}
797 
798 	ret = gpio_pin_set_dt(&config->int_gpios, 0);
799 	if (ret < 0) {
800 		LOG_ERR("Unable to set interrupt pin to low");
801 		return ret;
802 	}
803 
804 	k_sleep(PIN_DELAY_TIME);
805 
806 	ret = gpio_pin_configure_dt(&config->int_gpios, GPIO_INPUT);
807 	if (ret < 0) {
808 		LOG_ERR("Unable to configure interrupt pin to input");
809 		return ret;
810 	}
811 
812 	if (!config->lazy_loading) {
813 		k_sleep(K_MSEC(POWER_UP_DELAY_MS));
814 
815 		ret = bq274xx_gauge_configure(dev);
816 		if (ret < 0) {
817 			LOG_ERR("Unable to configure bq274xx gauge");
818 			return ret;
819 		}
820 	}
821 
822 	return 0;
823 }
824 
bq274xx_pm_action(const struct device * dev,enum pm_device_action action)825 static int bq274xx_pm_action(const struct device *dev,
826 			     enum pm_device_action action)
827 {
828 	int ret;
829 
830 	switch (action) {
831 	case PM_DEVICE_ACTION_TURN_OFF:
832 		ret = bq274xx_enter_shutdown_mode(dev);
833 		break;
834 	case PM_DEVICE_ACTION_RESUME:
835 		ret = bq274xx_exit_shutdown_mode(dev);
836 		break;
837 	default:
838 		ret = -ENOTSUP;
839 		break;
840 	}
841 
842 	return ret;
843 }
844 #endif /* CONFIG_BQ274XX_PM */
845 
846 static DEVICE_API(sensor, bq274xx_battery_driver_api) = {
847 	.sample_fetch = bq274xx_sample_fetch,
848 	.channel_get = bq274xx_channel_get,
849 #ifdef CONFIG_BQ274XX_TRIGGER
850 	.trigger_set = bq274xx_trigger_set,
851 #endif
852 };
853 
854 #if defined(CONFIG_BQ274XX_PM) || defined(CONFIG_BQ274XX_TRIGGER)
855 #define BQ274XX_INT_CFG(index)							\
856 	.int_gpios = GPIO_DT_SPEC_INST_GET(index, int_gpios),
857 #define PM_BQ274XX_DT_INST_DEFINE(index, bq274xx_pm_action)			\
858 	PM_DEVICE_DT_INST_DEFINE(index, bq274xx_pm_action)
859 #define PM_BQ274XX_DT_INST_GET(index) PM_DEVICE_DT_INST_GET(index)
860 #else
861 #define BQ274XX_INT_CFG(index)
862 #define PM_BQ274XX_DT_INST_DEFINE(index, bq274xx_pm_action)
863 #define PM_BQ274XX_DT_INST_GET(index) NULL
864 #endif
865 
866 #define BQ274XX_INIT(index)							\
867 	static struct bq274xx_data bq274xx_driver_##index;			\
868 										\
869 	static const struct bq274xx_config bq274xx_config_##index = {		\
870 		.i2c = I2C_DT_SPEC_INST_GET(index),				\
871 		BQ274XX_INT_CFG(index)						\
872 		.design_voltage = DT_INST_PROP(index, design_voltage),		\
873 		.design_capacity = DT_INST_PROP(index, design_capacity),	\
874 		.taper_current = DT_INST_PROP(index, taper_current),		\
875 		.terminate_voltage = DT_INST_PROP(index, terminate_voltage),	\
876 		.chemistry_id = DT_INST_PROP_OR(index, chemistry_id, 0),			\
877 		.lazy_loading = DT_INST_PROP(index, zephyr_lazy_load),		\
878 	};									\
879 										\
880 	PM_BQ274XX_DT_INST_DEFINE(index, bq274xx_pm_action);			\
881 										\
882 	SENSOR_DEVICE_DT_INST_DEFINE(index, &bq274xx_gauge_init,		\
883 			    PM_BQ274XX_DT_INST_GET(index),			\
884 			    &bq274xx_driver_##index,				\
885 			    &bq274xx_config_##index, POST_KERNEL,		\
886 			    CONFIG_SENSOR_INIT_PRIORITY,			\
887 			    &bq274xx_battery_driver_api);
888 
889 DT_INST_FOREACH_STATUS_OKAY(BQ274XX_INIT)
890