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