-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Adxl345 refac and FIFO #97500
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
base: main
Are you sure you want to change the base?
Adxl345 refac and FIFO #97500
Conversation
Add a dedicated devicetree binding to configure the interrupt line, INT1 or INT2, used for FIFO events. FIFO events can be data ready, watermark or overrun. Signed-off-by: Lothar Rubusch <[email protected]>
The FIFO is used either to buffer values in Analog's "stream mode" or to record a set of measurements triggered by a specific sensor event in Analog's "trigger mode". Since sensor event handling is not yet implemented in this driver, only stream mode is applicable. In both cases - especially in stream mode - setting the watermark to 1 is not practical. Doing so would generate an interrupt for every single measured value. If capturing every measurement in real time is the goal, Analog's "bypass mode" is more appropriate, as it avoids the additional overhead of handling interrupts like watermark or data ready. Moreover, generating frequent interrupts can easily cause overrun issues. Therefore, the minimum configurable watermark should be changed to 2. Signed-off-by: Lothar Rubusch <[email protected]>
It does not make sense to prioritize one interrupt line over the other on the ADXL345. Once interrupt events are implemented, each event can be individually mapped to either INT1 or INT2. In such configurations, both interrupt lines must be physically connected, and the mapping should be defined accordingly. Remove that comment line. Signed-off-by: Lothar Rubusch <[email protected]>
Adjustment in the driver according to the minimum change for the devicetree. Signed-off-by: Lothar Rubusch <[email protected]>
Use more consistent naming conventions. A significant number of the current defines in this driver are unused. Clarify that this define refers to a configuration register by adding the _REG suffix to its name. Signed-off-by: Lothar Rubusch <[email protected]>
Use more consistent naming conventions. A significant number of the current defines in this driver are unused. Clarify that this define refers to a configuration register by adding the _REG suffix to its name. Signed-off-by: Lothar Rubusch <[email protected]>
Use more consistent naming conventions. A significant number of the current defines in this driver are unused. Clarify that this define refers to a configuration register by adding the _REG suffix to its name. Signed-off-by: Lothar Rubusch <[email protected]>
The current name neither accurately represents its purpose nor indicates its context when viewed in debug symbols. Therefore, prefix the define with ADXL345_ and apply consistent naming for clarity. Signed-off-by: Lothar Rubusch <[email protected]>
The current name neither accurately represents its purpose nor indicates its context when viewed in debug symbols. Therefore, prefix the define with ADXL345_ and apply consistent naming for clarity. Signed-off-by: Lothar Rubusch <[email protected]>
Use a descriptive and complete name for this constant. It represents a field within the FIFO_CTL register and is part of the ADXL345 sensor driver. Signed-off-by: Lothar Rubusch <[email protected]>
Since the variable is used as a boolean, it should be defined as a bool. Signed-off-by: Lothar Rubusch <[email protected]>
The FIFO sample count is stored within a portion of an 8-bit register. Since only 8-bit configuration registers are involved, it's better to use uint8_t to avoid unnecessary mixing with uint16_t. Signed-off-by: Lothar Rubusch <[email protected]>
The function is intended to update only the selected, i.e. masked, bits. However, it doesn't currently behave as expected. Update it to function correctly, following the typical behavior of a *_assign_bits() helper. Signed-off-by: Lothar Rubusch <[email protected]>
Remove dead code. Signed-off-by: Lothar Rubusch <[email protected]>
Remove dead code. Signed-off-by: Lothar Rubusch <[email protected]>
Introduce a function to handle enabling and standby mode for measurements. According to the datasheet, placing the sensor in standby is recommended before applying certain configurations. This function will manage enabling and disabling measurement in subsequent patches. Introduce a helper function to conditionally set or clear specific masked bits. This change prepares the codebase for upcoming patches in this series. Signed-off-by: Lothar Rubusch <[email protected]>
Currently, this function performs two distinct tasks: it retrieves both "status" and "status1" i.e. the interrupt status and a field used to indicate the number of FIFO entries. In upcoming patches, these two pieces of information are not always required together. When only one is needed, the current implementation forces the use of a dummy variable as a workaround. To improve clarity and efficiency, it's better to split get_status() into two separate functions - one that retrieves the interrupt status (as the name suggests), and another that retrieves the current number of entries in the sensor's FIFO. Signed-off-by: Lothar Rubusch <[email protected]>
…tree The ADXL345 sensor provides two configurable interrupt lines that can be mapped to various sensor events such as data ready, overrun, and watermark. The previous hardcoded approach wiring only INT2, and the subsequent quickfix using INT1 with a "routed_to_int2" boolean flag, may served as a temporary solution. However, dynamically checking what is essentially a soldered (or jumpered) interrupt configuration at every function call introduces unnecessary complexity and bus traffic. The use of ternary operators for determining the active interrupt line also reduces code readability and consistency, making the interrupt mapping logic easy to overlook. This commit aims to implement support for the FIFO interrupt lines via the devicetree drdy-pin and keeps this setting in the constant driver configuration. Mapping shall happen only once at probing, thus does not need to be rechecked either. Additionally, introduce generic functions to enable interrupt lines and implements logic to determine which line is currently in use. This refactoring lays the groundwork for upcoming changes in this series. While Zephyr’s trigger mode will compile with this commit, its runtime behavior will be finalized in subsequent patches. Signed-off-by: Lothar Rubusch <[email protected]>
Cosmetical change to simplify local variable name. Signed-off-by: Lothar Rubusch <[email protected]>
Currently, the ODR supposed to be configured in the devicetree, then at the start of the adxl345_init() re-written to hardcoded ADXL345_RATE_25HZ, and at the end of the adxl345_init() set again to data->odr. Why?! Refactor sensor ODR initialization and define a reasonable default in case devicetree configuration fails. In adxl345_init(), use the ODR value already provided in the config to update the corresponding register, ensuring that only the relevant field is modified. Use FIELD_GET() on the ODR mask when setting the value, and write directly to the register both during sensor initialization and within the attribute function. This removes an unnecessary layer of indirection, allowing the setter function to be dropped entirely. Signed-off-by: Lothar Rubusch <[email protected]>
Refactor the configuration of the g-range settings. Group together the setup of g-range selection, the full_res field, implicit clearing of the justify bit, and interrupt inversion handling. Also refactor the initialization probe function accordingly. Signed-off-by: Lothar Rubusch <[email protected]>
Remove default values for FIFO mode, FIFO trigger and samples (the fifo watermark) in the driver config. Defaulting the fifo_watermark value to 0 is meaningless and potentially problematic (see ADXL345 Data Sheet (Rev. G, p. 28: "undesired operation may occur"), especially in a fixed configuration. In the best case, the sensor would immediately trigger a watermark interrupt, effectively disabling the FIFO buffer functionality. FIFO mode is derrived from available interrupt and watermark (e.g. drdy_pin) configuration. FIFO trigger is actually senseless, since it would initialize the corresponding field in the ADXL345 register. This implements Analog's trigger mode, which is not implemented here and most likely does not make sense to be implemented. Note: Analog trigger mode is not Zephyr trigger mode, pls. consult the ADXL345 datasheet for the details. Signed-off-by: Lothar Rubusch <[email protected]>
Rename ADXL345_X_AXIS_DATA_0_REG to ADXL345_REG_DATA_XYZ_REGS for better clarity. This sensor is to be read always in block read over all directions, thus naming individual axis fields does actually not make sense. According to the datasheet, this register corresponds to the first x-axis data byte, followed by the second x-axis byte, then the y-axis, and finally the z-axis data in a similar sequence. The sensor does not provide an option to selectively enable or disable specific axes for FIFO usage. Consequently, all three axis data must be fetched together for a single FIFO sample line. By using this register as the starting point for the fetch, it is always used to retrieve x-, y-, and z-axis samples in a single operation. Therefore, renaming it to ADXL345_REG_DATA_XYZ_REGS would be more appropriate and meaningful for the driver implementation. Signed-off-by: Lothar Rubusch <[email protected]>
Remove the adxl345_interrupt_config() function entirely. Move the initialization of interrupt-to-GPIO mapping directly into adxl345_init(). Eliminate the redundant reads of ADXL345_INT_MAP_REG and ADXL345_INT_ENABLE_REG, as the function neither used the retrieved data nor evaluated the return values. Configure the FIFO mode based on the availability of interrupt lines, selecting either FIFO_STREAM or FIFO_BYPASSED. Clean up the mode fields and add clarifying comments. Current FIFO setup behavior: A) If Zephyr’s .config includes CONFIG_ADXL345_TRIGGER or STREAM set to 'y': * If INT1 or INT2 are defined in the devicetree: use FIFO_STREAM * If no interrupt lines are defined: use FIFO_BYPASSED B) If Zephyr’s .config does not include CONFIG_ADXL345_TRIGGER or STREAM: * Interrupt lines are ignored: use FIFO_BYPASSED Note that FIFO_STREAM, FIFO_BYPASSED, and FIFO_TRIGGER are hardware operation modes of the Analog Devices ADXL345 sensor. They are unrelated to Zephyr's "STREAM" or "TRIGGER" APIs. Past versions of this driver incorrectly mixed these concepts (e.g. initializing a trigger interrupt when FIFO_STREAM mode was set). To implement FIFO_TRIGGER (where the sensor stores samples upon being triggered) or FIFO_FIFO (an alternative retention mode), refer to the ADXL345 datasheet. In most cases, STREAM and BYPASS modes are sufficient. Lastly, note that reading from the FIFO queue in FIFO_STREAM mode is currently broken in this driver; this issue is addressed in one of the subsequent patches in this series. Signed-off-by: Lothar Rubusch <[email protected]>
The FIFO configuration has to be configured based on the configuration but also on the availability of interrupt lines. Since both interrupt lines are available, this configuration cannot be done in the constant static sensor config anymore. Signed-off-by: Lothar Rubusch <[email protected]>
This event loop is unused and was likely copied from similar accelerometer drivers. Remove dead code. Signed-off-by: Lothar Rubusch <[email protected]>
Remove unused defines and masks that reference fields in the interrupt registers which are neither specified nor accessed anywhere in the code. Signed-off-by: Lothar Rubusch <[email protected]>
For the simplified fetch-and-get implementation, clean up the trigger source by removing the unnecessary re-mapping of interrupt lines left over from the old trigger logic. Allow applications to register handlers for data-ready, overrun, and watermark sensor events, as also activity. Provide a mechanism for applications to register these handlers, and alternatively offer default handling that clears and resets the FIFO after an interrupt is received. Additionally, introduce a dedicated function to flush and reset the FIFO. Signed-off-by: Lothar Rubusch <[email protected]>
In Analog Devices' FIFO modes (e.g. STREAM), samples are stored in the sensor's internal buffer, and a watermark interrupt signals when enough samples are ready. The driver should then fetch all available samples in a burst read. Currently, the driver handles interrupts but reads only a single sample each time, regardless of FIFO mode. This effectively reduces all modes (FIFO, TRIGGER, STREAM) to BYPASS behavior. Additionally, fetch operations only returned the last sample repeatedly instead of the full FIFO contents. This commit restores proper FIFO operation by converting sample storage back to an array, but fixing the fetch logic to read and return all configured FIFO entries. Signed-off-by: Lothar Rubusch <[email protected]>
Reorganize function order to simplify future refactoring. Structure the source so that generic helper functions appear first, API-level functions with RTIO calls and callbacks are placed in the middle, and consumer-facing functions are positioned at the end. Signed-off-by: Lothar Rubusch <[email protected]>
The fifo_total_bytes driver data variable is only used as a local calculation and can therefore be removed entirely. Signed-off-by: Lothar Rubusch <[email protected]>
Clarify what is actually meant and handled-whether it refers to entries or samples. Remove any unnecessary handling of these variables. According to the datasheet, fifo_entries represents the number of entries required to trigger a watermark interrupt, while fifo_samples indicates the number of samples collected. Also, avoid using status1, since the ADXL345 has only a single interrupt status field. Signed-off-by: Lothar Rubusch <[email protected]>
Add a way for dynamic FIFO watermark configuration from the app when using the memory-efficient fetch-and-get implementation. Implement this consistently with the stream implementation using only the devicetree configuration of fifo_watermark. Correspondingly, update the memory configuration to allocate sufficient space for the fifo_watermark number of samples in the RTIO/stream implementation. Signed-off-by: Lothar Rubusch <[email protected]>
Eliminate the use of status1 for the RTIO/stream implementation of this driver. Using status1 here is misleading, especially when it refers to a register rather than a status field. Improve member variable naming for better clarity and consistency. Signed-off-by: Lothar Rubusch <[email protected]>
Introduce the function adxl345_sqe_done() in the RTIO/stream implementation to improve and refactor error handling in the streaming component of the ADXL345 driver. Signed-off-by: Lothar Rubusch <[email protected]>
For both stream/RTIO and fetch-and-get, provide a generic bus access interface. Implement simple caching of configuration registers to reduce bus traffic, especially when updating specific bits. This approach maintains a more generic driver implementation for common functionality and avoids redundant reimplementations that depend solely on either fetch-and-get or RTIO calls. Additionally, to efficiently update register bits without reading configuration registers that cannot be modified externally, maintain cached copies of written settings and avoid reading their values from the bus again. Signed-off-by: Lothar Rubusch <[email protected]>
For the stream/RTIO implementation, add the function adxl345_rtio_init_hdr() to initialize the stream driver header. Also, add the function adxl345_rtio_init_buffer() to allocate the buffer using rtio_sqe_rx_buf(), based on the initialized header. Signed-off-by: Lothar Rubusch <[email protected]>
For the stream/RTIO implementation, add the function adxl345_rtio_cqe_consume() to consume any remaining CQEs that have not yet been processed. Signed-off-by: Lothar Rubusch <[email protected]>
Introduce adxl345_check_streaming() in the stream/RTIO implementation to handle the standard streaming check routines. Signed-off-by: Lothar Rubusch <[email protected]>
Provide a function to flush the FIFO using both RTIO and fetch-and-get mechanisms. In both cases, the FIFO must be flushed from Analog’s FIFO_STREAM mode, which according to the datasheet, requires a complete readout of all elements in order to reset both the interrupt source register and the FIFO status register. Currently, FIFO flushing is implemented by switching to FIFO_BYPASS mode and then back again - the approach recommended by the datasheet for FIFO_TRIGGER mode. However, Analog's FIFO_TRIGGER mode is a very specific case and is typically not implemented in a generic ADXL345 drivers, including this one. Switching over to FIFO_BYPASS might not reset the interrupt register, when it comes to interrupt events. Signed-off-by: Lothar Rubusch <[email protected]>
Extends the coverage of sensor events to overrun and watermark for the stream/RTIO implementation. Signed-off-by: Lothar Rubusch <[email protected]>
Restrict the RTIO stream handler to the kconfig condition. Signed-off-by: Lothar Rubusch <[email protected]>
b447685
to
29365ff
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boy, going over 42 patches was painful, and I can only say this is a first-pass review.
I agree this driver could use some love, and the fact that you took the time to go over the whole thing and make this number of patches (+ filing and re-opening multiple PRs for this driver) says a lot of your interest in contributing/improving this driver. I appreciate it and I hope we can channel it in helping you land a contribution.
However, in order to do that, we need to objectivize the conversation so we filter out the noise. I see read statements both in the body of this PR and in some patches that are stale, unclear or just not true. For instance:
- This PR says the FIFO has been broken for months, yet I see no Bugs filed, and I happen to have used it in the last 6-months (although I will admit it has been only in prototyping). In what way is this driver broken?
- The PR states a burst readout is performed, but it's not implemented (nor I think is possible AFAIK).
I also get a bit of NIH in some of these changes (for instance, changing the way the int1-gpios, int2-gpios dts-props map the corresponding pin to use, or by saying FIFO_WATERMARK=1 is an issue). It's okay to rename variables or reformat code so it's cleaner or more concise/readable, but let's call these things by their name; otherwise we'll get confused and/or look at the other changes (which do objectively provide value) with a hesitant mindset.
All in all, my suggestions to get this moving forward:
- Simplify the "story" of this PR so it's easier for us to follow-along: What is it fixing, what is a new "feature" and what are just style improvements, nitpicks or formatting changes.
- Definitely suggest bringing the patch-count down a bit: I'm positive you can summarize some of these changes in less than 20 patches.
- If you have any questions or would like to discuss specific details in a more direct fashion, feel free to reach out in Discord or join the Sensor WG meetings (every other monday).
Either this or INT2 will be used to route interrupts. If both | ||
are defined, then int1 is prioritized. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is merely a way to handle an use-case where both are defined: an alternative is to add a BUILD_ASSERT to prevent both being present. The point is that this driver routes interrupts through one pin, and not both.
I disagree that adding another property to decide which is used when both are defined is better than what's already implemented.
description: | | ||
Specify the FIFO watermark level in frame count. | ||
Valid range: 1 - 31 | ||
Valid range: 2 - 31 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is setting fifo-watemark = <1>;
an invalid or unsupported configuration by the sensor? I don't understand the value of limiting the driver, beyond its capabilities; irrespective of having a clear-cut use-case.
drdy-pin: | ||
type: int | ||
enum: [1, 2] | ||
description: | | ||
This property selects the interrupt line (INT1 or INT2) used to deliver | ||
the data ready signal, if enabled. | ||
- 1 | ||
- 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this being helpful, when this can already be inferred based on the existence of either int1-gpios
or int2-gpios
drivers/sensor/adi/adxl345/adxl345.c
Outdated
.odr = DT_INST_PROP(inst, odr), \ | ||
.odr = DT_INST_PROP_OR(inst, odr, ADXL345_RATE_25HZ), \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make instead odr a required dt-property. Let's not double-down on the already questionable arbitrary 25-Hz ODR choice.
if (ret < 0) { | ||
if (ret) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
for (uint8_t s = 0; s < count; s++) { | ||
rc = adxl345_read_sample(dev, &data->sample[s]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sensor: adxl345: fix fetch and get to correctly read the FIFO samples
In Analog Devices' FIFO modes (e.g. STREAM), samples are stored in the
sensor's internal buffer, and a watermark interrupt signals when enough
samples are ready. The driver should then fetch all available samples in a
burst read.Currently, the driver handles interrupts but reads only a single sample
each time, regardless of FIFO mode. This effectively reduces all modes
(FIFO, TRIGGER, STREAM) to BYPASS behavior. Additionally, fetch operations
only returned the last sample repeatedly instead of the full FIFO contents.This commit restores proper FIFO operation by converting sample storage
back to an array, but fixing the fetch logic to read and return all
configured FIFO entries.
Two things:
- I don't see the described burst-read change. All I see is code formatted, additional checks and asserts and then the same for-loop performed.
- Please confirm whether your proposition is even possible: AFAIK - The datasheet specifies the sensor only places the new sample once the previous sample is read. This is the reason why this comment is captured in the driver:
zephyr/drivers/sensor/adi/adxl345/adxl345.c
Lines 532 to 539 in 6b8fcae
/** RTIO SQE/CQE pool size depends on the fifo-watermark because we * can't just burst-read all the fifo data at once. Datasheet specifies * we need to get one frame at a time (through the Data registers), * therefore, we set all the sequence at once to properly pull each * frame, and then end up calling the completion event so the * application receives it). */ #define ADXL345_RTIO_DEFINE(inst) \
RETRIEVING DATA FROM FIFO
The FIFO data is read through the DATAX, DATAY, and DATAZ
registers (Address 0x32 to Address 0x37). When the FIFO is in
FIFO, stream, or trigger mode, reads to the DATAX, DATAY, and
DATAZ registers read data stored in the FIFO. Each time data is
read from the FIFO, the oldest x-, y-, and z-axes data are placed
into the DATAX, DATAY, and DATAZ registers.
RTIO_DEFINE(adxl345_rtio_ctx_##inst, \ | ||
2 * DT_INST_PROP(inst, fifo_watermark) + 2, \ | ||
2 * DT_INST_PROP(inst, fifo_watermark) + 2); | ||
RTIO_DEFINE(adxl345_rtio_ctx_##inst, \ | ||
4 * ADXL345_MAX_FIFO_SIZE, \ | ||
4 * ADXL345_MAX_FIFO_SIZE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why from 2X+2 to 4X?
static void adxl345_sqe_done(const struct device *dev, | ||
struct rtio_iodev_sqe *iodev_sqe, int res) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't iodev_sqe
already contained in dev->data
? Why are we passing it as another argument?
#if defined(CONFIG_ADXL345_STREAM) | ||
const struct adxl345_dev_config *cfg = dev->config; | ||
struct rtio_sqe *write_reg_sqe = rtio_sqe_acquire(data->rtio_ctx); | ||
|
||
rtio_sqe_prep_tiny_write(write_reg_sqe, data->iodev, RTIO_PRIO_NORM, | ||
&addr, sizeof(addr), NULL); | ||
write_reg_sqe->flags |= RTIO_SQE_TRANSACTION; | ||
|
||
/* | ||
* Use a tiny write for register and an additional write for register | ||
* content. It's not possible to pass two byte directly as tiny write, | ||
* since the sqe buffer was defined holding just one byte. | ||
*/ | ||
struct rtio_sqe *write_buf_sqe = rtio_sqe_acquire(data->rtio_ctx); | ||
|
||
rtio_sqe_prep_tiny_write(write_buf_sqe, data->iodev, RTIO_PRIO_NORM, | ||
&val, sizeof(val), NULL); | ||
|
||
if (cfg->bus_type == ADXL345_BUS_I2C) { | ||
write_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART; | ||
} | ||
|
||
rtio_submit(data->rtio_ctx, 2); /* keep control commands blocking */ | ||
|
||
return 0; | ||
#else | ||
return adxl345_reg_write(dev, addr, &val, 1); | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want to go this ifdefry route. If you want to go the route of everything working over RTIO, I suggest looking into other drivers that define the _bus.h/.c module to abstract this away, OR don't have the fetch-get code depend on RTIO.
TL;DR
I tried to refac this driver, fix some of the FIFO related issues and introduce an approach to cover trigger/fetch&get and stream/RTIO bus access.
Long story
In my opinion, the ADXL345 driver in Zephyr still has room for improvement. Having worked on parts of the ADXL345 driver for the Linux kernel, I found it a familiar starting point when getting into Zephyr.
Current State of the ADXL345 Driver in Zephyr:
FIFO Mode Configuration
The driver currently (at least) offers setting up Analog Devices' FIFO_TRIGGER mode. However, this appears to be a misunderstanding of its purpose, especially when viewed in the context of Zephyr’s Trigger API versus a Stream/RTIO-based approach. It's important to note that Analog Devices did not define the FIFO_TRIGGER bit with Zephyr’s trigger model in mind - Analog's FIFO_TRIGGER serves a different function entirely. For typical usage in Zephyr, starting with either FIFO_STREAM or FIFO_BYPASSED modes would be more appropriate, in my opinion.
Broken FIFO Handling
FIFO functionality has been broken for several months and remains so. Currently, a FIFO watermark event is triggered once, but the driver only fetches the most recent measurement(s), rather than reading out the entire FIFO buffer. As a result, no further watermark interrupts are generated after the initial one, since the FIFO is never properly emptied.
Additional Issues
The FIFO watermark should ideally trigger at 2 stored samples, not just 1.
The current FIFO flush mechanism relies on the process described for FIFO_TRIGGER mode in the datasheet. However, when using FIFO_STREAM mode - as recommended - the FIFO should be flushed by reading out all entries manually, as per the datasheet.
Initialization in stream/RTIO mode uses direct bus writes, which makes later fetch/get operations or RTIO usage somewhat redundant. A better approach would be to consolidate these accesses under shared functions that abstract the bus type (RTIO or plain bus).
For register updates where only a few bits need changing, using an _update_bits() function with cached register values could reduce bus traffic. Since configuration registers are not expected to change externally, this kind of caching (similar to the regmap cache mechanism in Linux) could be beneficial. I'm not sure if Zephyr has a general caching mechanism like this, but it could be worth considering.
General Refactoring Needed
Overall, the driver would benefit from a thorough refactoring. There are inconsistencies in naming, instances of dead code, and unnecessarily complex implementations - likely due to the driver evolving without consistent maintenance. In my view, many of these parts are no longer robust or maintainable and need cleanup.
@MaureenHelm : I had a chat with you as the Analog Devices maintainer during OSS in Amsterdam this year. I'm not sure if you remember, anyway you had suggested that I first submit the full series as-is, so that we could later decide how to proceed—whether to split, squash, accept, or drop parts of it. Since it's generally easier to squash commits than to separate them after the fact, I tried to break the series down as much as possible from the beginning. That’s why you're now seeing over 40 commits. I’m also aware that some maintainers prefer this level of granularity.
Please let me know if this approach is excessive or if it's aligned with your expectations. All commits build successfully and pass strict checkpatch. For verification, I used my own test applications for fetch&get, device handler registration, and stream/RTIO integration, as the existing samples didn’t provide enough coverage in those areas. Does the set - all or in pieces - qualify for upstreaming? What should be squashed? What is missing? What needs to be improved? Actually I pretend writing drivers for similar accelerometers by this kind of approach. So, this is kind of a proposal to get a bit into discussion, too.
In a summary of the main topics of this series, I'd like to address:
refac: comments, simplify variable names, adjust variable types, removal of dead code, remove redundant code
refac: control measurement on/off by dedicate function and mech
refac: separate function get_status() into get_fifo_entries() and get_status() for interrupt status
refac: introduce an api to use common function calls diverting to use underlying either triggered/fetch&get or stream/RTIO implementation
refac: make interrupt lines configurable over devicetree, and remove rechecking over and over again in the running code for such constant setting
refac: simplify overly complicated ODR setup, as then also g ranges
refac: stream handler registration
fix: change minimum watermark to 2
fix: stream initialization using direct register write, while partly using RTIO
fix: stream flush FIFO performs the action documented for reset Analog Device's trigger mode (switch to FIFO BYPASS and back), in Analyg Device's FIFO STREAM mode, entries need actually to be read, to reset fifo status register and interrupt status register (would come much more into play when implementing sensor events)
fix: fetch&get using FIFO did actually fetch the recent measurements, but did not read out fifo entries
fix: rework FIFO mode setup - Analog Device's "FIFO TRIGGER" mode seems to be confused with Zephyr's "triggered" config?
fix/add: let FIFO watermark being configured also dynamically by attribute for fetch&get
fix/add: overrun and data ready handler, optionally to be overwritten in application
NB: I used AI to elaborate code comments and improve the English descriptions, simply because I'm not a native speaker. I did not use AI / Copilots or the like for sources.