-
Notifications
You must be signed in to change notification settings - Fork 904
iio: dac: Add AD5413 support #2786
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?
iio: dac: Add AD5413 support #2786
Conversation
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.
Added the warnings that caused the ci to exit with an error but were not logged
ba5d87d to
1401608
Compare
|
Hi, sorry for the pr failure, I updated the checkout strategy to retry by deepening the fetch until the rebase succeeds. please see CI output, checkpatch is failing for example |
|
Hi @dlech, @mhennerich, @nunojsa, All feedback so far has been addressed in the latest commits. Could you kindly take a look and let me know if anything else is required for approval? Thanks! |
15694b1 to
8174327
Compare
8174327 to
b224d69
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.
I think this is looking in pretty good shape now.
It looks like there are some defconfig changes that were made that should not be here that is causing CI to fail.
Also, there might be something wrong with the way you are running checkpatch.pl if it is passing for you event with --strict. There are clearly still some issues with spaces vs. tabs and there was one // comment that checkpatch should have caught.
drivers/iio/dac/ad5413.c
Outdated
| return PTR_ERR(st->gpio_reset); | ||
|
|
||
| /* Disable CRC checks */ | ||
| ret = ad5413_crc_disable(st); |
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 think this could use some comments to explain why it is necessary to do it this way since it doesn't follow the usual pattern.
However, This would make more sense to me:
st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(st->gpio_reset))
return PTR_ERR(st->gpio_reset);
if (st->gpio_reset) {
/* Reset pin is wired - finish the hard reset. */
fsleep(100);
gpiod_set_value(st->gpio_reset, 0);
} else {
/* No reset pin - best we can do is soft reset. */
/*
* If chip was left with CRC enabled, the reset command won't work
* so we need to disable it first.
*/
ret = ad5413_crc_disable(st);
if (ret)
return ret;
/* TODO: replace this with regmap_bulk_write(). */
ret = ad5413_spi_reg_write(st, AD5413_REG_KEY, AD5413_REG_KEY_CODE_RESET_1);
if (ret)
return ret;
ret = ad5413_spi_reg_write(st, AD5413_REG_KEY, AD5413_REG_KEY_CODE_RESET_2);
if (ret)
return ret;
}
fsleep(100);If we can do a hard reset, we shouldn't need to bother disabling the CRC or do a soft reset.
fb3697f to
8b0e6f5
Compare
5bfd6a8 to
4e5b988
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.
Here it goes my first round of review. Also since it's the first time I see you contributing here, the normal expectation (unless there's a very good reason not to) is for the driver to be first upstreamed before merging it in our tree.
| dvdd-supply = <&dvdd>; | ||
| avss-supply = <&avss>; | ||
| adi,range-microamp = <0 24000>; | ||
| adi,slew-time-us = <125>; |
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.
The bindings patch should be one separate commit.
| imply AD5360 | ||
| imply AD5380 | ||
| imply AD5421 | ||
| imply AD5413 |
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.
Also a separate commit. The last one typically...
drivers/iio/dac/ad5413.c
Outdated
| int max_uv; | ||
| }; | ||
|
|
||
| /* struct ad5413_state - driver instance specific data */ |
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 comment does not really add much. It could be removed...
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.
Thanks for pointing this out. The redundant comment has been removed in the latest revision.
| * Output ranges corresponding to bits [3:0] from DAC_CONFIG register | ||
| * 0011: ±10.5 V voltage range | ||
| * 1001: 0 mA to 24 mA current range | ||
| */ |
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.
Instead of the binary I would use the identifiers. That's how it's done typically
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.
Thanks for catching that! The comment now references the symbolic identifiers (AD5413_RANGE_PLUSMINUS_10_5V and AD5413_RANGE_0MA_24MA) instead of the binary values, matching the typical convention in other IIO drivers.
| AD5413_RANGE_PLUSMINUS_10_5V, | ||
| -10500000, | ||
| 10500000, | ||
| } }; |
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.
In the kernel we typically use designated initializer. So:
static const struct ad5413_range ad5413_voltage_range[] = {
. reg = AD5413_RANGE_PLUSMINUS_10_5V,
.min_uv = -10500000,
.max_uv = 10500000,
};
Ditto for the other places where this applies.
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.
Thanks for the feedback!
The struct ad5413_range has been cleaned up and made unit-agnostic (.reg, .min, .max) so it can be shared between voltage and current modes.
The ad5413_read_raw() function has been updated accordingly to use these new fields for calculating the scale and offset.
drivers/iio/dac/ad5413.c
Outdated
| if (ret == -ENODATA || ret == -EINVAL) { | ||
| slew_time_us = 0; | ||
| } else if (ret < 0) { | ||
| dev_err(&st->spi->dev, "Failed to read adi,slew-time-us: %d\n", |
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.
dev_err_probe()
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.
Updated this section to use dev_err_probe() properly — removed the explicit %d since the helper already prints the error code automatically. The function now directly returns the result of dev_err_probe() for cleaner error handling.
drivers/iio/dac/ad5413.c
Outdated
| const struct ad5413_range *range, | ||
| unsigned int size, int min, int max) | ||
| { | ||
| int i; |
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.
unsigned
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.
Good point—updated the loop index to unsigned int to match the size parameter (while keeping min/max as signed since ranges can be negative).
drivers/iio/dac/ad5413.c
Outdated
| unsigned int mask; | ||
|
|
||
| mask = (AD5413_WR_FLAG_MSK(AD5413_REG_DIGITAL_DIAG_CONFIG) << 24) | | ||
| AD5413_DIGITAL_DIAG_CRC_DISABLE_VAL; |
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.
The above could be a macro right? Also I would expect this to a normal ad5413_spi_reg_write() call
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.
Updated this function to use the regular ad5413_spi_reg_write() helper instead of manually composing the SPI frame. Also introduced a macro (AD5413_CRC_DISABLE_CMD) to hold the constant for clarity, as suggested.
| IIO_VOLTAGE) }; | ||
|
|
||
| static const struct iio_chan_spec ad5413_current_ch[] = { AD5413_DAC_CHAN( | ||
| IIO_CURRENT) }; |
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.
please fixup style
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.
Fixed the channel array formatting to follow kernel style — each array element is now on its own line without breaking the macro call.
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.
Am i missing something? It does not look fixed...
drivers/iio/dac/ad5413.c
Outdated
| case IIO_CHAN_INFO_RAW: | ||
| mutex_lock(&st->lock); | ||
| ret = ad5413_spi_reg_write(st, AD5413_REG_DAC_INPUT, val); | ||
| mutex_unlock(&st->lock); |
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.
be consistent. Use the cleanup logic everywhere. Here you might need scoped_guard()
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.
Updated the critical sections to use guard(mutex) for consistency with the rest of the driver. This keeps the lock/unlock handling automatic without requiring <linux/cleanup.h>, and aligns with the existing style used elsewhere in the code.
Add device-tree schema for AD5413: - Supplies (avdd/dvdd/avss), SPI, optional reset GPIO. - Range properties with quoted keys when listed in arrays (e.g. 'adi,range-microamp'). - Example node. Signed-off-by: Bruce Tsao <bruce.tsao@analog.com>
Introduce AD5413 IIO DAC driver: - guard(mutex) for locking - dev_err_probe() on probe-path failures - Unit-agnostic range tables (.min/.max) with designated initializers - CRC disable/refactor via helpers and macros - Wire into drivers/iio/dac/Kconfig and Makefile Signed-off-by: Bruce Tsao <bruce.tsao@analog.com>
Make the meta option imply AD5413 so it is built when selecting all ADI IIO drivers. Signed-off-by: Bruce Tsao <bruce.tsao@analog.com>
4e5b988 to
84479a5
Compare
|
Hi @nunojsa
|
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.
Hi Bruce,
I still see a lot of comments I've done not handled at all. Please address those or argue back why you think you should not change it.
Also, take care about over commenting your code. Save comments for non obvious things
| required: | ||
| - compatible | ||
| - reg | ||
| - spi-max-frequency |
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 this really mandatory? Typically not...
| adi,range-microamp = <0 24000>; | ||
| adi,slew-time-us = <125>; | ||
| }; | ||
| }; |
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.
Just about the commit message. Do not mention "bindings" in the git subject, that's implied :). Instead, something like
"dt-bindings: iio: dac: Document AD5413 properties"
| static const struct of_device_id ad5413_of_match[] = { { .compatible = | ||
| "adi,ad5413" }, | ||
| {} }; | ||
| MODULE_DEVICE_TABLE(of, ad5413_of_match); |
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.
still not addressed
| return devm_iio_device_register(&spi->dev, indio_dev); | ||
| } | ||
|
|
||
| static const struct spi_device_id ad5413_id[] = { { "ad5413", 0 }, {} }; |
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.
ditto
| if (ret < 0) | ||
| return ret; | ||
|
|
||
| /* By output range, decide voltage or current channel */ |
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.
the comment does not bring any value IMO
| if (st->gpio_reset) { | ||
| /* Hard reset via GPIO (active low) */ | ||
| fsleep(100); | ||
| gpiod_set_value(st->gpio_reset, 0); /* assert reset */ |
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.
de-assert
| /* Finally, enable the voltage/current output */ | ||
| return ad5413_spi_write_mask( | ||
| st, AD5413_REG_DAC_CONFIG, AD5413_REG_DAC_CONFIG_OUT_EN_MSK, | ||
| FIELD_PREP(AD5413_REG_DAC_CONFIG_OUT_EN_MSK, 1)); |
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.
the lines breaks are not really ok. Also don´t comment every line of code. Comments are for non obvious stuff
|
|
||
| /* 1) voltage or current range */ | ||
| ret = device_property_read_u32_array( | ||
| &st->spi->dev, "adi,range-microvolt", tmparray, 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.
line breaking also nok.
| } else { | ||
| /* current path */ | ||
| ret = device_property_read_u32_array( | ||
| &st->spi->dev, "adi,range-microamp", tmparray, 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.
line breaking again
| IIO_VOLTAGE) }; | ||
|
|
||
| static const struct iio_chan_spec ad5413_current_ch[] = { AD5413_DAC_CHAN( | ||
| IIO_CURRENT) }; |
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.
Am i missing something? It does not look fixed...
|
Also, for the driver commit message, do not specify changes you've made on the PR. Since it's the first patch for this driver just add some information about the HW itself. Typically I use the datasheet for this. Every this some uncommon or that you feel that really stands out in the code, then mention it. |
Summary
This PR adds initial support for the Analog Devices AD5413, a 14-bit single-channel DAC capable of voltage and current output.
Key changes
ad5413.cunderdrivers/iio/dac/adi,ad5413.yamlunderDocumentation/devicetree/bindings/iio/dac/Datasheet:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad5413.pdf
PR Description
necessary to understand them. List any dependencies required for this change.
any space), or simply check them after publishing the PR.
description and try to push all related PRs simultaneously.
PR Type
PR Checklist