Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sensor: bq274xx: add support for bq27427 and various improvements #60117

Merged
merged 13 commits into from
Jul 21, 2023

Conversation

fabiobaltieri
Copy link
Member

Add support for BQ27247 and do various improvements to the driver while at it.

Add the bq274xx_ back to the static function prefixes for the bq274xx
driver.

These have been removed recently but every other sensor and most Zephyr
driver have static function prefixed, this helps avoiding ambiguity in
list files, stack traces, setting debugging breakpoints etc.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Drop unnecessary casting from uint16_t to uint8_t.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Move bq274xx_gauge_configure up in the code, remove the forward
declaration.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
@zephyrbot zephyrbot added the area: Sensors Sensors label Jul 6, 2023
@fabiobaltieri fabiobaltieri changed the title Bq sensor: bq274xx: add support for bq27427 and various improvements Jul 6, 2023
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
@fabiobaltieri
Copy link
Member Author

Excellent comments @henrikbrixandersen, all done.

Drop various unnecessarily initialized variables from the driver.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Control reg write seems to support two bytes mode (the technical
reference shows example of that), so use a single i2c_write_dt there.
Also drop a couple alias variables from bq274xx_cmd_reg_write.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
@fabiobaltieri
Copy link
Member Author

fabiobaltieri commented Jul 9, 2023

  • dropped the block zeroing/memset entirely, they are just re-read from the flash anyway, no point zeroing that data
  • realized the -247 variant that I'm adding has different configuration register offsets, so I've reworked the support patch to add offset support, ported over the original one and added the ones for the variant I'm working on, cross checked between the technical reference manuals [1][2] and the Linux driver [3].

Notes: I've opted for doing the device detection and set the offset table at runtime, the table is just 4 bytes of flash so I think no harm doing that and it's convenient to have a single compatible. If it was bigger it would have made sense to have the part specific compatible and only load the right table at build time, but from what I see there's not that many variants to deal with.

Now bq274xx_gauge_configure is a bit messed up, tmp_checksum is calculated and then not used and discarded down the code, read again and still not used. checksum_old is just read and never used. I tried to clean that part, deleting the stale code but then I was getting erroneous data from the fuel gauge (seems like the configuration change was not being loaded or gets corrupted). I suspect that those stale checksum code were an initial implementation of a setup code that does not require reading the whole block (which is described in the technical reference manual), then it got changed for a full recalculation of the checksum but the previous code was left over. Removing those read though appear to break the setup code, and I think it's because it's lacking some sleep in the right places, and those extra i2c operations happen to compensate for that. The delay story is also inconsistent, the driver defines BQ274XX_SUBCLASS_DELAY_MS but then uses it for every sleep but the subclass selection. Also the Linux driver has some scary comments in it: https://lxr.missinglinkelectronics.com/linux/drivers/power/supply/bq27xxx_battery.c#L1404.

So at this point the driver seems to work, I think I'll leave this PR at this: cleaning up the coding style errors and adding the support for the new variant. Then on a second stage I'll (maybe) look into studying the Linux driver a bit more and fixing up the setup sequence.

[1] https://www.ti.com/lit/ug/sluuac5c/sluuac5c.pdf
[2] https://www.ti.com/lit/ug/sluucd5/sluucd5.pdf
[3] https://lxr.missinglinkelectronics.com/linux/drivers/power/supply/bq27xxx_battery.c#L931

Add a couple of define for the data memory block size and config flag
bit.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
drivers/sensor/bq274xx/bq274xx.c Show resolved Hide resolved
if (id == BQ27421_DEVICE_ID) {
data->regs = &bq27421_regs;
} else if (id == BQ27427_DEVICE_ID) {
data->regs = &bq27427_regs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to do this at compile time to reduce flash usage?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be quite a few variations to potentially support: https://lxr.missinglinkelectronics.com/linux/drivers/power/supply/bq27xxx_battery.c#L136

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm unsure about it, with these two we can get away with just 4 bytes of flash. If we introduce build time variations we'd have to go for part number specific compatibles and rework the driver a bit more and have downstream user change it in their application. I was thinking about trying to go with this, keep it simple for now and see if there's demand for the other chips in the family.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could easily be done based on compatible at instantiation time, but can be done later, this PR is already doing a good cleanup

Copy link
Member Author

@fabiobaltieri fabiobaltieri Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I was starting to like the idea of keeping this in runtime: the two p/n right now are a pin-to-pin compatible, as it is now you can drop the new one and it should work with the same firmware image, if the cost for that is only few bytes of flash I'd say it may be worth it.

@fabiobaltieri
Copy link
Member Author

Thanks folks, all addressed, great feedback.

@fabiobaltieri
Copy link
Member Author

  • fixed the delay definitions properly

Copy link
Member

@nixward nixward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job! I'm loving with the new variant support and I2C improvements, all achieved with less lines of code!

drivers/sensor/bq274xx/bq274xx.c Outdated Show resolved Hide resolved
@fabiobaltieri
Copy link
Member Author

One more thought about this: the configuration function currently issue a soft reset every time, the right way to do would be to check if the configuration changed and leave the device alone if it's been set up already. The Linux driver has that logic, that'll be good to keep in mind for followup work on this driver.

Fix the calculation for designenergy_mwh, as right now it's using a
float casted straight to an int, which results in the factor rounded
from 3.7 to 3. Also rework both that and taperrate so that they don't
use floating point.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Add a retry count limit to config update mode loops, this way the system
can still boot if there's an issue with the device. The normal sleep
should be enough for correct operation, adding a conservative limit.

Rework the delays to be unambiguous while at it.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
The device technical reference manual says "The Sealed to Unsealed key
has two identical words". Use two different defines with the same value
in the code so it's somewhat less ambiguous that the double write is
intentional.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Change bq274xx_sample_fetch to support SENSOR_CHAN_ALL. This makes it
possible to get the sensor data using the sensor shell, besides being
generally convenient.

Also drop a redundant comment.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Use i2c_reg_write_byte_dt instead of bq274xx_cmd_reg_write. The wrapper
does not add anything anyway.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
The current ID for BQ274XX_DEVICE_ID is actually the one for the
BQ27421. The driver seems to work with the BQ27427 as well, at least the
common and extended commands are the same, so add that variant as well,
rename the existing one and print the currently read ID when the ID
check fails.

The configuration registers have a different offset though, so add a
register offset table and make the device rcognize the right one un
runtime based on the device ID.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Use a combination of sys_cpu_to_be16 and i2c_burst_write_dt for setting
16 bits registers. Get rid of a bunch of temporary variables, custom
conversions and few bus writes.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
@fabiobaltieri
Copy link
Member Author

fabiobaltieri commented Jul 13, 2023

@marco85mars20 @nixward hey you both have quite few contributions kicking around, I'd suggest filing https://github.com/zephyrproject-rtos/zephyr/issues/new?assignees=&labels=Role+Nomination&projects=&template=006_nomination.md&title= to get triage permissions.

Comment on lines +57 to +58
subcommand & 0xff,
subcommand >> 8,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: we should likely be using sys/byteorder API

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll followup on this, I forsee another stack of fixes anyway.

if (id == BQ27421_DEVICE_ID) {
data->regs = &bq27421_regs;
} else if (id == BQ27427_DEVICE_ID) {
data->regs = &bq27427_regs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could easily be done based on compatible at instantiation time, but can be done later, this PR is already doing a good cleanup

@MaureenHelm MaureenHelm merged commit bb0135b into zephyrproject-rtos:main Jul 21, 2023
@fabiobaltieri fabiobaltieri deleted the bq branch July 21, 2023 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants