1 /*
2  * Copyright (c) 2020 Linumiz
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ti_bq274xx
8 
9 #include <drivers/i2c.h>
10 #include <init.h>
11 #include <drivers/sensor.h>
12 #include <sys/__assert.h>
13 #include <string.h>
14 #include <sys/byteorder.h>
15 #include <drivers/gpio.h>
16 
17 #include "bq274xx.h"
18 
19 #define BQ274XX_SUBCLASS_DELAY 5 /* subclass 64 & 82 needs 5ms delay */
20 /* Time to set pin in order to exit shutdown mode */
21 #define PIN_DELAY_TIME 1U
22 /* Time it takes device to initialize before doing any configuration */
23 #define INIT_TIME 100U
24 
25 static int bq274xx_gauge_configure(const struct device *dev);
26 
bq274xx_command_reg_read(struct bq274xx_data * bq274xx,uint8_t reg_addr,int16_t * val)27 static int bq274xx_command_reg_read(struct bq274xx_data *bq274xx, uint8_t reg_addr,
28 				    int16_t *val)
29 {
30 	uint8_t i2c_data[2];
31 	int status;
32 
33 	status = i2c_burst_read(bq274xx->i2c, DT_INST_REG_ADDR(0), reg_addr,
34 				i2c_data, 2);
35 	if (status < 0) {
36 		LOG_ERR("Unable to read register");
37 		return -EIO;
38 	}
39 
40 	*val = (i2c_data[1] << 8) | i2c_data[0];
41 
42 	return 0;
43 }
44 
bq274xx_control_reg_write(struct bq274xx_data * bq274xx,uint16_t subcommand)45 static int bq274xx_control_reg_write(struct bq274xx_data *bq274xx,
46 				     uint16_t subcommand)
47 {
48 	uint8_t i2c_data, reg_addr;
49 	int status = 0;
50 
51 	reg_addr = BQ274XX_COMMAND_CONTROL_LOW;
52 	i2c_data = (uint8_t)((subcommand)&0x00FF);
53 
54 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0), reg_addr,
55 				    i2c_data);
56 	if (status < 0) {
57 		LOG_ERR("Failed to write into control low register");
58 		return -EIO;
59 	}
60 
61 	k_msleep(BQ274XX_SUBCLASS_DELAY);
62 
63 	reg_addr = BQ274XX_COMMAND_CONTROL_HIGH;
64 	i2c_data = (uint8_t)((subcommand >> 8) & 0x00FF);
65 
66 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0), reg_addr,
67 				    i2c_data);
68 	if (status < 0) {
69 		LOG_ERR("Failed to write into control high register");
70 		return -EIO;
71 	}
72 
73 	return 0;
74 }
75 
bq274xx_command_reg_write(struct bq274xx_data * bq274xx,uint8_t command,uint8_t data)76 static int bq274xx_command_reg_write(struct bq274xx_data *bq274xx, uint8_t command,
77 				     uint8_t data)
78 {
79 	uint8_t i2c_data, reg_addr;
80 	int status = 0;
81 
82 	reg_addr = command;
83 	i2c_data = data;
84 
85 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0), reg_addr,
86 				    i2c_data);
87 	if (status < 0) {
88 		LOG_ERR("Failed to write into control register");
89 		return -EIO;
90 	}
91 
92 	return 0;
93 }
94 
bq274xx_read_data_block(struct bq274xx_data * bq274xx,uint8_t offset,uint8_t * data,uint8_t bytes)95 static int bq274xx_read_data_block(struct bq274xx_data *bq274xx, uint8_t offset,
96 				   uint8_t *data, uint8_t bytes)
97 {
98 	uint8_t i2c_data;
99 	int status = 0;
100 
101 	i2c_data = BQ274XX_EXTENDED_BLOCKDATA_START + offset;
102 
103 	status = i2c_burst_read(bq274xx->i2c, DT_INST_REG_ADDR(0), i2c_data,
104 				data, bytes);
105 	if (status < 0) {
106 		LOG_ERR("Failed to read block");
107 		return -EIO;
108 	}
109 
110 	k_msleep(BQ274XX_SUBCLASS_DELAY);
111 
112 	return 0;
113 }
114 
bq274xx_get_device_type(struct bq274xx_data * bq274xx,uint16_t * val)115 static int bq274xx_get_device_type(struct bq274xx_data *bq274xx, uint16_t *val)
116 {
117 	int status;
118 
119 	status =
120 		bq274xx_control_reg_write(bq274xx, BQ274XX_CONTROL_DEVICE_TYPE);
121 	if (status < 0) {
122 		LOG_ERR("Unable to write control register");
123 		return -EIO;
124 	}
125 
126 	status = bq274xx_command_reg_read(bq274xx, BQ274XX_COMMAND_CONTROL_LOW,
127 					  val);
128 
129 	if (status < 0) {
130 		LOG_ERR("Unable to read register");
131 		return -EIO;
132 	}
133 
134 	return 0;
135 }
136 
137 /**
138  * @brief sensor value get
139  *
140  * @return -ENOTSUP for unsupported channels
141  */
bq274xx_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)142 static int bq274xx_channel_get(const struct device *dev,
143 			       enum sensor_channel chan,
144 			       struct sensor_value *val)
145 {
146 	struct bq274xx_data *bq274xx = dev->data;
147 	float int_temp;
148 
149 	switch (chan) {
150 	case SENSOR_CHAN_GAUGE_VOLTAGE:
151 		val->val1 = ((bq274xx->voltage / 1000));
152 		val->val2 = ((bq274xx->voltage % 1000) * 1000U);
153 		break;
154 
155 	case SENSOR_CHAN_GAUGE_AVG_CURRENT:
156 		val->val1 = ((bq274xx->avg_current / 1000));
157 		val->val2 = ((bq274xx->avg_current % 1000) * 1000U);
158 		break;
159 
160 	case SENSOR_CHAN_GAUGE_STDBY_CURRENT:
161 		val->val1 = ((bq274xx->stdby_current / 1000));
162 		val->val2 = ((bq274xx->stdby_current % 1000) * 1000U);
163 		break;
164 
165 	case SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT:
166 		val->val1 = ((bq274xx->max_load_current / 1000));
167 		val->val2 = ((bq274xx->max_load_current % 1000) * 1000U);
168 		break;
169 
170 	case SENSOR_CHAN_GAUGE_TEMP:
171 		int_temp = (bq274xx->internal_temperature * 0.1);
172 		int_temp = int_temp - 273.15;
173 		val->val1 = (int32_t)int_temp;
174 		val->val2 = (int_temp - (int32_t)int_temp) * 1000000;
175 		break;
176 
177 	case SENSOR_CHAN_GAUGE_STATE_OF_CHARGE:
178 		val->val1 = bq274xx->state_of_charge;
179 		val->val2 = 0;
180 		break;
181 
182 	case SENSOR_CHAN_GAUGE_STATE_OF_HEALTH:
183 		val->val1 = bq274xx->state_of_health;
184 		val->val2 = 0;
185 		break;
186 
187 	case SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY:
188 		val->val1 = (bq274xx->full_charge_capacity / 1000);
189 		val->val2 = ((bq274xx->full_charge_capacity % 1000) * 1000U);
190 		break;
191 
192 	case SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY:
193 		val->val1 = (bq274xx->remaining_charge_capacity / 1000);
194 		val->val2 =
195 			((bq274xx->remaining_charge_capacity % 1000) * 1000U);
196 		break;
197 
198 	case SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY:
199 		val->val1 = (bq274xx->nom_avail_capacity / 1000);
200 		val->val2 = ((bq274xx->nom_avail_capacity % 1000) * 1000U);
201 		break;
202 
203 	case SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY:
204 		val->val1 = (bq274xx->full_avail_capacity / 1000);
205 		val->val2 = ((bq274xx->full_avail_capacity % 1000) * 1000U);
206 		break;
207 
208 	case SENSOR_CHAN_GAUGE_AVG_POWER:
209 		val->val1 = (bq274xx->avg_power / 1000);
210 		val->val2 = ((bq274xx->avg_power % 1000) * 1000U);
211 		break;
212 
213 	default:
214 		return -ENOTSUP;
215 	}
216 
217 	return 0;
218 }
219 
bq274xx_sample_fetch(const struct device * dev,enum sensor_channel chan)220 static int bq274xx_sample_fetch(const struct device *dev,
221 				enum sensor_channel chan)
222 {
223 	struct bq274xx_data *bq274xx = dev->data;
224 	int status = 0;
225 
226 #ifdef CONFIG_BQ274XX_LAZY_CONFIGURE
227 	if (!bq274xx->lazy_loaded) {
228 		status = bq274xx_gauge_configure(dev);
229 
230 		if (status < 0) {
231 			return status;
232 		}
233 		bq274xx->lazy_loaded = true;
234 	}
235 #endif
236 
237 	switch (chan) {
238 	case SENSOR_CHAN_GAUGE_VOLTAGE:
239 		status = bq274xx_command_reg_read(
240 			bq274xx, BQ274XX_COMMAND_VOLTAGE, &bq274xx->voltage);
241 		if (status < 0) {
242 			LOG_ERR("Failed to read voltage");
243 			return -EIO;
244 		}
245 		break;
246 
247 	case SENSOR_CHAN_GAUGE_AVG_CURRENT:
248 		status = bq274xx_command_reg_read(bq274xx,
249 						  BQ274XX_COMMAND_AVG_CURRENT,
250 						  &bq274xx->avg_current);
251 		if (status < 0) {
252 			LOG_ERR("Failed to read average current ");
253 			return -EIO;
254 		}
255 		break;
256 
257 	case SENSOR_CHAN_GAUGE_TEMP:
258 		status = bq274xx_command_reg_read(
259 			bq274xx, BQ274XX_COMMAND_INT_TEMP,
260 			&bq274xx->internal_temperature);
261 		if (status < 0) {
262 			LOG_ERR("Failed to read internal temperature");
263 			return -EIO;
264 		}
265 		break;
266 
267 	case SENSOR_CHAN_GAUGE_STDBY_CURRENT:
268 		status = bq274xx_command_reg_read(bq274xx,
269 						  BQ274XX_COMMAND_STDBY_CURRENT,
270 						  &bq274xx->stdby_current);
271 		if (status < 0) {
272 			LOG_ERR("Failed to read standby current");
273 			return -EIO;
274 		}
275 		break;
276 
277 	case SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT:
278 		status = bq274xx_command_reg_read(bq274xx,
279 						  BQ274XX_COMMAND_MAX_CURRENT,
280 						  &bq274xx->max_load_current);
281 		if (status < 0) {
282 			LOG_ERR("Failed to read maximum current");
283 			return -EIO;
284 		}
285 		break;
286 
287 	case SENSOR_CHAN_GAUGE_STATE_OF_CHARGE:
288 		status = bq274xx_command_reg_read(bq274xx, BQ274XX_COMMAND_SOC,
289 						  &bq274xx->state_of_charge);
290 		if (status < 0) {
291 			LOG_ERR("Failed to read state of charge");
292 			return -EIO;
293 		}
294 		break;
295 
296 	case SENSOR_CHAN_GAUGE_FULL_CHARGE_CAPACITY:
297 		status = bq274xx_command_reg_read(
298 			bq274xx, BQ274XX_COMMAND_FULL_CAPACITY,
299 			&bq274xx->full_charge_capacity);
300 		if (status < 0) {
301 			LOG_ERR("Failed to read full charge capacity");
302 			return -EIO;
303 		}
304 		break;
305 
306 	case SENSOR_CHAN_GAUGE_REMAINING_CHARGE_CAPACITY:
307 		status = bq274xx_command_reg_read(
308 			bq274xx, BQ274XX_COMMAND_REM_CAPACITY,
309 			&bq274xx->remaining_charge_capacity);
310 		if (status < 0) {
311 			LOG_ERR("Failed to read remaining charge capacity");
312 			return -EIO;
313 		}
314 		break;
315 
316 	case SENSOR_CHAN_GAUGE_NOM_AVAIL_CAPACITY:
317 		status = bq274xx_command_reg_read(bq274xx,
318 						  BQ274XX_COMMAND_NOM_CAPACITY,
319 						  &bq274xx->nom_avail_capacity);
320 		if (status < 0) {
321 			LOG_ERR("Failed to read nominal available capacity");
322 			return -EIO;
323 		}
324 		break;
325 
326 	case SENSOR_CHAN_GAUGE_FULL_AVAIL_CAPACITY:
327 		status =
328 			bq274xx_command_reg_read(bq274xx,
329 						 BQ274XX_COMMAND_AVAIL_CAPACITY,
330 						 &bq274xx->full_avail_capacity);
331 		if (status < 0) {
332 			LOG_ERR("Failed to read full available capacity");
333 			return -EIO;
334 		}
335 		break;
336 
337 	case SENSOR_CHAN_GAUGE_AVG_POWER:
338 		status = bq274xx_command_reg_read(bq274xx,
339 						  BQ274XX_COMMAND_AVG_POWER,
340 						  &bq274xx->avg_power);
341 		if (status < 0) {
342 			LOG_ERR("Failed to read battery average power");
343 			return -EIO;
344 		}
345 		break;
346 
347 	case SENSOR_CHAN_GAUGE_STATE_OF_HEALTH:
348 		status = bq274xx_command_reg_read(bq274xx, BQ274XX_COMMAND_SOH,
349 						  &bq274xx->state_of_health);
350 
351 		bq274xx->state_of_health = (bq274xx->state_of_health) & 0x00FF;
352 
353 		if (status < 0) {
354 			LOG_ERR("Failed to read state of health");
355 			return -EIO;
356 		}
357 		break;
358 
359 	default:
360 		return -ENOTSUP;
361 	}
362 
363 	return 0;
364 }
365 
366 /**
367  * @brief initialise the fuel gauge
368  *
369  * @return 0 for success
370  */
bq274xx_gauge_init(const struct device * dev)371 static int bq274xx_gauge_init(const struct device *dev)
372 {
373 	struct bq274xx_data *bq274xx = dev->data;
374 	const struct bq274xx_config *const config = dev->config;
375 	int status = 0;
376 	uint16_t id;
377 
378 #ifdef CONFIG_PM_DEVICE
379 	if (!device_is_ready(config->int_gpios.port)) {
380 		LOG_ERR("GPIO device pointer is not ready to be used");
381 		return -ENODEV;
382 	}
383 #endif
384 
385 	bq274xx->i2c = device_get_binding(config->bus_name);
386 	if (bq274xx->i2c == NULL) {
387 		LOG_ERR("Could not get pointer to %s device.",
388 			config->bus_name);
389 		return -EINVAL;
390 	}
391 
392 	status = bq274xx_get_device_type(bq274xx, &id);
393 	if (status < 0) {
394 		LOG_ERR("Unable to get device ID");
395 		return -EIO;
396 	}
397 
398 	if (id != BQ274XX_DEVICE_ID) {
399 		LOG_ERR("Invalid Device");
400 		return -EINVAL;
401 	}
402 
403 #ifdef CONFIG_BQ274XX_LAZY_CONFIGURE
404 	bq274xx->lazy_loaded = false;
405 #else
406 	status = bq274xx_gauge_configure(dev);
407 #endif
408 
409 	return status;
410 }
411 
bq274xx_gauge_configure(const struct device * dev)412 static int bq274xx_gauge_configure(const struct device *dev)
413 {
414 	struct bq274xx_data *bq274xx = dev->data;
415 	const struct bq274xx_config *const config = dev->config;
416 	int status = 0;
417 	uint8_t tmp_checksum = 0, checksum_old = 0, checksum_new = 0;
418 	uint16_t flags = 0, designenergy_mwh = 0, taperrate = 0;
419 	uint8_t designcap_msb, designcap_lsb, designenergy_msb, designenergy_lsb,
420 		terminatevolt_msb, terminatevolt_lsb, taperrate_msb,
421 		taperrate_lsb;
422 	uint8_t block[32];
423 
424 	designenergy_mwh = (uint16_t)3.7 * config->design_capacity;
425 	taperrate =
426 		(uint16_t)config->design_capacity / (0.1 * config->taper_current);
427 
428 	/** Unseal the battery control register **/
429 	status = bq274xx_control_reg_write(bq274xx, BQ274XX_UNSEAL_KEY);
430 	if (status < 0) {
431 		LOG_ERR("Unable to unseal the battery");
432 		return -EIO;
433 	}
434 
435 	status = bq274xx_control_reg_write(bq274xx, BQ274XX_UNSEAL_KEY);
436 	if (status < 0) {
437 		LOG_ERR("Unable to unseal the battery");
438 		return -EIO;
439 	}
440 
441 	/* Send CFG_UPDATE */
442 	status = bq274xx_control_reg_write(bq274xx,
443 					   BQ274XX_CONTROL_SET_CFGUPDATE);
444 	if (status < 0) {
445 		LOG_ERR("Unable to set CFGUpdate");
446 		return -EIO;
447 	}
448 
449 	/** Step to place the Gauge into CONFIG UPDATE Mode **/
450 	do {
451 		status = bq274xx_command_reg_read(
452 			bq274xx, BQ274XX_COMMAND_FLAGS, &flags);
453 		if (status < 0) {
454 			LOG_ERR("Unable to read flags");
455 			return -EIO;
456 		}
457 
458 		if (!(flags & 0x0010)) {
459 			k_msleep(BQ274XX_SUBCLASS_DELAY * 10);
460 		}
461 
462 	} while (!(flags & 0x0010));
463 
464 	status = bq274xx_command_reg_write(bq274xx,
465 					   BQ274XX_EXTENDED_DATA_CONTROL, 0x00);
466 	if (status < 0) {
467 		LOG_ERR("Failed to enable block data memory");
468 		return -EIO;
469 	}
470 
471 	/* Access State subclass */
472 	status = bq274xx_command_reg_write(bq274xx, BQ274XX_EXTENDED_DATA_CLASS,
473 					   0x52);
474 	if (status < 0) {
475 		LOG_ERR("Failed to update state subclass");
476 		return -EIO;
477 	}
478 
479 	/* Write the block offset */
480 	status = bq274xx_command_reg_write(bq274xx, BQ274XX_EXTENDED_DATA_BLOCK,
481 					   0x00);
482 	if (status < 0) {
483 		LOG_ERR("Failed to update block offset");
484 		return -EIO;
485 	}
486 
487 	for (uint8_t i = 0; i < 32; i++) {
488 		block[i] = 0;
489 	}
490 
491 	status = bq274xx_read_data_block(bq274xx, 0x00, block, 32);
492 	if (status < 0) {
493 		LOG_ERR("Unable to read block data");
494 		return -EIO;
495 	}
496 
497 	tmp_checksum = 0;
498 	for (uint8_t i = 0; i < 32; i++) {
499 		tmp_checksum += block[i];
500 	}
501 	tmp_checksum = 255 - tmp_checksum;
502 
503 	/* Read the block checksum */
504 	status = i2c_reg_read_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
505 				   BQ274XX_EXTENDED_CHECKSUM, &checksum_old);
506 	if (status < 0) {
507 		LOG_ERR("Unable to read block checksum");
508 		return -EIO;
509 	}
510 
511 	designcap_msb = config->design_capacity >> 8;
512 	designcap_lsb = config->design_capacity & 0x00FF;
513 	designenergy_msb = designenergy_mwh >> 8;
514 	designenergy_lsb = designenergy_mwh & 0x00FF;
515 	terminatevolt_msb = config->terminate_voltage >> 8;
516 	terminatevolt_lsb = config->terminate_voltage & 0x00FF;
517 	taperrate_msb = taperrate >> 8;
518 	taperrate_lsb = taperrate & 0x00FF;
519 
520 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
521 				    BQ274XX_EXTENDED_BLOCKDATA_DESIGN_CAP_HIGH,
522 				    designcap_msb);
523 	if (status < 0) {
524 		LOG_ERR("Failed to write designCAP MSB");
525 		return -EIO;
526 	}
527 
528 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
529 				    BQ274XX_EXTENDED_BLOCKDATA_DESIGN_CAP_LOW,
530 				    designcap_lsb);
531 	if (status < 0) {
532 		LOG_ERR("Failed to erite designCAP LSB");
533 		return -EIO;
534 	}
535 
536 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
537 				    BQ274XX_EXTENDED_BLOCKDATA_DESIGN_ENR_HIGH,
538 				    designenergy_msb);
539 	if (status < 0) {
540 		LOG_ERR("Failed to write designEnergy MSB");
541 		return -EIO;
542 	}
543 
544 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
545 				    BQ274XX_EXTENDED_BLOCKDATA_DESIGN_ENR_LOW,
546 				    designenergy_lsb);
547 	if (status < 0) {
548 		LOG_ERR("Failed to erite designEnergy LSB");
549 		return -EIO;
550 	}
551 
552 	status = i2c_reg_write_byte(
553 		bq274xx->i2c, DT_INST_REG_ADDR(0),
554 		BQ274XX_EXTENDED_BLOCKDATA_TERMINATE_VOLT_HIGH,
555 		terminatevolt_msb);
556 	if (status < 0) {
557 		LOG_ERR("Failed to write terminateVolt MSB");
558 		return -EIO;
559 	}
560 
561 	status = i2c_reg_write_byte(
562 		bq274xx->i2c, DT_INST_REG_ADDR(0),
563 		BQ274XX_EXTENDED_BLOCKDATA_TERMINATE_VOLT_LOW,
564 		terminatevolt_lsb);
565 	if (status < 0) {
566 		LOG_ERR("Failed to write terminateVolt LSB");
567 		return -EIO;
568 	}
569 
570 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
571 				    BQ274XX_EXTENDED_BLOCKDATA_TAPERRATE_HIGH,
572 				    taperrate_msb);
573 	if (status < 0) {
574 		LOG_ERR("Failed to write taperRate MSB");
575 		return -EIO;
576 	}
577 
578 	status = i2c_reg_write_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
579 				    BQ274XX_EXTENDED_BLOCKDATA_TAPERRATE_LOW,
580 				    taperrate_lsb);
581 	if (status < 0) {
582 		LOG_ERR("Failed to erite taperRate LSB");
583 		return -EIO;
584 	}
585 
586 	for (uint8_t i = 0; i < 32; i++) {
587 		block[i] = 0;
588 	}
589 
590 	status = bq274xx_read_data_block(bq274xx, 0x00, block, 32);
591 	if (status < 0) {
592 		LOG_ERR("Unable to read block data");
593 		return -EIO;
594 	}
595 
596 	checksum_new = 0;
597 	for (uint8_t i = 0; i < 32; i++) {
598 		checksum_new += block[i];
599 	}
600 	checksum_new = 255 - checksum_new;
601 
602 	status = bq274xx_command_reg_write(bq274xx, BQ274XX_EXTENDED_CHECKSUM,
603 					   checksum_new);
604 	if (status < 0) {
605 		LOG_ERR("Failed to update new checksum");
606 		return -EIO;
607 	}
608 
609 	tmp_checksum = 0;
610 	status = i2c_reg_read_byte(bq274xx->i2c, DT_INST_REG_ADDR(0),
611 				   BQ274XX_EXTENDED_CHECKSUM, &tmp_checksum);
612 	if (status < 0) {
613 		LOG_ERR("Failed to read checksum");
614 		return -EIO;
615 	}
616 
617 	status = bq274xx_control_reg_write(bq274xx, BQ274XX_CONTROL_BAT_INSERT);
618 	if (status < 0) {
619 		LOG_ERR("Unable to configure BAT Detect");
620 		return -EIO;
621 	}
622 
623 	status = bq274xx_control_reg_write(bq274xx, BQ274XX_CONTROL_SOFT_RESET);
624 	if (status < 0) {
625 		LOG_ERR("Failed to soft reset the gauge");
626 		return -EIO;
627 	}
628 
629 	flags = 0;
630 	/* Poll Flags   */
631 	do {
632 		status = bq274xx_command_reg_read(
633 			bq274xx, BQ274XX_COMMAND_FLAGS, &flags);
634 		if (status < 0) {
635 			LOG_ERR("Unable to read flags");
636 			return -EIO;
637 		}
638 
639 		if (flags & 0x0010) {
640 			k_msleep(BQ274XX_SUBCLASS_DELAY * 10);
641 		}
642 	} while (flags & 0x0010);
643 
644 	/* Seal the gauge */
645 	status = bq274xx_control_reg_write(bq274xx, BQ274XX_CONTROL_SEALED);
646 	if (status < 0) {
647 		LOG_ERR("Failed to seal the gauge");
648 		return -EIO;
649 	}
650 
651 #ifdef CONFIG_PM_DEVICE
652 	bq274xx->pm_state = PM_DEVICE_STATE_ACTIVE;
653 #endif
654 
655 	return 0;
656 }
657 
658 #ifdef CONFIG_PM_DEVICE
bq274xx_enter_shutdown_mode(struct bq274xx_data * data)659 static int bq274xx_enter_shutdown_mode(struct bq274xx_data *data)
660 {
661 	int status;
662 
663 	status = bq274xx_control_reg_write(data, BQ274XX_UNSEAL_KEY);
664 	if (status < 0) {
665 		LOG_ERR("Unable to unseal the battery");
666 		return status;
667 	}
668 
669 	status = bq274xx_control_reg_write(data, BQ274XX_UNSEAL_KEY);
670 	if (status < 0) {
671 		LOG_ERR("Unable to unseal the battery");
672 		return status;
673 	}
674 
675 	status = bq274xx_control_reg_write(data,
676 					   BQ274XX_CONTROL_SHUTDOWN_ENABLE);
677 	if (status < 0) {
678 		LOG_ERR("Unable to enable shutdown mode");
679 		return status;
680 	}
681 
682 	status = bq274xx_control_reg_write(data, BQ274XX_CONTROL_SHUTDOWN);
683 	if (status < 0) {
684 		LOG_ERR("Unable to enter shutdown mode");
685 		return status;
686 	}
687 
688 	status = bq274xx_control_reg_write(data, BQ274XX_CONTROL_SEALED);
689 	if (status < 0) {
690 		LOG_ERR("Failed to seal the gauge");
691 		return status;
692 	}
693 
694 	return 0;
695 }
696 
bq274xx_exit_shutdown_mode(const struct device * dev)697 static int bq274xx_exit_shutdown_mode(const struct device *dev)
698 {
699 	const struct bq274xx_config *const config = dev->config;
700 	int status = 0;
701 
702 	status = gpio_pin_configure_dt(&config->int_gpios,
703 			   GPIO_OUTPUT | GPIO_OPEN_DRAIN);
704 	if (status < 0) {
705 		LOG_ERR("Unable to configure interrupt pin to output and open drain");
706 		return status;
707 	}
708 
709 	status = gpio_pin_set_dt(&config->int_gpios, 0);
710 	if (status < 0) {
711 		LOG_ERR("Unable to set interrupt pin to low");
712 		return status;
713 	}
714 
715 	k_msleep(PIN_DELAY_TIME);
716 
717 	status = gpio_pin_configure_dt(&config->int_gpios, GPIO_INPUT);
718 	if (status < 0) {
719 		LOG_ERR("Unable to configure interrupt pin to input");
720 		return status;
721 	}
722 
723 	k_msleep(INIT_TIME);
724 
725 	status = bq274xx_gauge_configure(dev);
726 	if (status < 0) {
727 		LOG_ERR("Unable to configure bq274xx gauge");
728 		return status;
729 	}
730 
731 	return 0;
732 }
733 
bq274xx_pm_control(const struct device * dev,enum pm_device_action action)734 static int bq274xx_pm_control(const struct device *dev,
735 			      enum pm_device_action action)
736 {
737 	int ret;
738 	struct bq274xx_data *data = dev->data;
739 
740 	switch (action) {
741 	case PM_DEVICE_ACTION_TURN_OFF:
742 		ret = bq274xx_enter_shutdown_mode(data);
743 		break;
744 	case PM_DEVICE_ACTION_RESUME:
745 		ret = bq274xx_exit_shutdown_mode(dev);
746 		break;
747 	default:
748 		ret = -ENOTSUP;
749 		break;
750 	}
751 
752 	return ret;
753 }
754 #endif /* CONFIG_PM_DEVICE */
755 
756 static const struct sensor_driver_api bq274xx_battery_driver_api = {
757 	.sample_fetch = bq274xx_sample_fetch,
758 	.channel_get = bq274xx_channel_get,
759 };
760 
761 #ifdef CONFIG_PM_DEVICE
762 #define BQ274XX_INT_CFG(index)						      \
763 	.int_gpios = GPIO_DT_SPEC_INST_GET(index, int_gpios),
764 #else
765 #define BQ274XX_INT_CFG(index)
766 #endif
767 
768 #define BQ274XX_INIT(index)                                                    \
769 	static struct bq274xx_data bq274xx_driver_##index;                     \
770 									       \
771 	static const struct bq274xx_config bq274xx_config_##index = {          \
772 		BQ274XX_INT_CFG(index)                                         \
773 		.bus_name = DT_INST_BUS_LABEL(index),                          \
774 		.design_voltage = DT_INST_PROP(index, design_voltage),         \
775 		.design_capacity = DT_INST_PROP(index, design_capacity),       \
776 		.taper_current = DT_INST_PROP(index, taper_current),           \
777 		.terminate_voltage = DT_INST_PROP(index, terminate_voltage),   \
778 	};                                                                     \
779 									       \
780 	DEVICE_DT_INST_DEFINE(index, &bq274xx_gauge_init, bq274xx_pm_control,  \
781 			    &bq274xx_driver_##index,                           \
782 			    &bq274xx_config_##index, POST_KERNEL,              \
783 			    CONFIG_SENSOR_INIT_PRIORITY,                       \
784 			    &bq274xx_battery_driver_api);
785 
786 DT_INST_FOREACH_STATUS_OKAY(BQ274XX_INIT)
787