-
Notifications
You must be signed in to change notification settings - Fork 896
iio: adc: Add initial driver support for MAX22531 #2854
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: rpi-6.6.y_GSOC_2025_MAX22531
Are you sure you want to change the base?
iio: adc: Add initial driver support for MAX22531 #2854
Conversation
Signed-off-by: Abhinav Jain <[email protected]>
Signed-off-by: Abhinav Jain <[email protected]>
Signed-off-by: Abhinav Jain <[email protected]>
Signed-off-by: Abhinav Jain <[email protected]>
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 @KernelShinobi , a few comments about this initial driver version.
Note that, aside from the comments above, there are still some improvements that need to be made to make this driver usable (e.g. read ADC sample data, provide scale to convert output codes to mV). Those features shall be implemented next. Though, overall, this looks good to me as an initial driver version.
/plugin/; | ||
|
||
/ { | ||
compatible = "brcm,bcm2835-spi", "brcm,bcm2711"; |
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.
You may need to add brcm,bcm2712
to this list to actually indicate this overlay is compatible with rpi5.
- compatible = "brcm,bcm2835-spi", "brcm,bcm2711";
+ compatible = "brcm,bcm2712", "brcm,bcm2835-spi", "brcm,bcm2711";
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.
Ack.
max22531@0 { | ||
compatible = "maxim,max22531"; | ||
reg = <0>; /* Using CS0 on spi0 */ | ||
spi-max-frequency = <10000000>; |
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.
10 MHz is relatively fast for a rpi SPI controller. If you observe transfers bringing strange results or failing when you receive the hw, then consider decreasing the SPI clock 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.
Ack, will drop to 5 MHz.
drivers/iio/adc/Kconfig
Outdated
tristate "Analog Devices MAX22531 ADC Driver" | ||
depends on SPI | ||
help | ||
Say yes here to build support for this driver. |
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.
Not a thing crucial for the moment, but I'd add the usual config help text boilerplate here. Upstream folks may request it, and there's nothing preventing us from adding a few more lines of text here.
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.
Ack.
drivers/iio/adc/max22531.c
Outdated
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | ||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | ||
.scan_index = ch, \ | ||
.output = 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.
not needed
- .output = 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.
Ack
drivers/iio/adc/max22531.c
Outdated
MAX22531_CHANNEL(1), | ||
MAX22531_CHANNEL(2), | ||
MAX22531_CHANNEL(3), | ||
IIO_CHAN_SOFT_TIMESTAMP(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.
Let's leave the timestamp channel for after buffer support is implemented. Timestamp channels are not very useful on their own.
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.
Ack
drivers/iio/adc/max22531.c
Outdated
adc = iio_priv(indio_dev); | ||
adc->spi_dev = spi; | ||
|
||
indio_dev->name = "max22531"; |
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 can be better set according to the specific device (max22530, max22531, or max22532) if a chip_info struct is implemented. See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/iio/adc/ad7124.c?h=v6.16-rc6#n196 for an example.
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.
Ack
drivers/iio/adc/max22531.c
Outdated
} | ||
|
||
static const struct spi_device_id max22531_id[] = { | ||
{ "max22531" }, |
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.
provide entries for max22530, and max22532 too
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.
Ack
drivers/iio/adc/max22531.c
Outdated
MODULE_DEVICE_TABLE(spi, max22531_id); | ||
|
||
static const struct of_device_id max22531_spi_of_id[] = { | ||
{ .compatible = "adi,max22531" }, |
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.
same here, add OF entries for matching with max22530 and max22532.
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.
Ack
drivers/iio/adc/max22531.c
Outdated
adc->vref = devm_regulator_get(&spi->dev, "vref"); | ||
if (IS_ERR(adc->vref)) | ||
dev_err(&spi->dev, "Failed to retrieve vref\n"); | ||
|
||
ret = regulator_enable(adc->vref); | ||
if (ret) | ||
return 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.
vref is an internal voltage reference that is always on/enabled. If I'm not missing anything, we can just use vref. E.g.
#define MAX22531_VREF_MV 1800
thus we don't need to keep a vref regulator field in struct max22351
.
For regulators, the driver should request VDDL and VDDPL regulators, as those must be supplied to power the MAX22531 chip.
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.
Ack, in case of VDDL and VDDPL, I am declaring VDDL as the external supply and pointing VDDPL’s supply to the same regulator as VDDL since it’s not a separate external rail. The data sheet lists VDDL as the REF SUPPLY for VDDPL under pin description.
https://www.analog.com/media/en/technical-documentation/data-sheets/max22530-max22532.pdf
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 case of VDDL and VDDPL, I am declaring VDDL as the external supply and pointing VDDPL’s supply to the same regulator as VDDL since it’s not a separate external rail.
That may be reasonable for the device tree overlay if the eval board uses the same power supply for VDDL and VDDPL. Though, the diagram on page 11 (https://www.analog.com/media/en/technical-documentation/data-sheets/MAX22530EVKIT-MAX22531EVKIT.pdf) shows VDDL and VDDPL being supplied with different sources.
The data sheet lists VDDL as the REF SUPPLY for VDDPL under pin description.
Hmm, that's strange. I didn't even notice that REF SUPPLY column until now. Still, I don't think VDDL supplies VDDPL. If we look at MAX22531 datasheet (link you provided above), we can see at page 14 that there are distinct pin descriptions for VDDL and VDDPL. Also, if we follow this logic of pins listed in the REF SUPPLY column to be voltage supplies, we would also have VDDF as a supply, which would not be correct since VDDF is an output.
At datasheet page 18 it is stated that:
The logic-side supply VDDPL powers an integrated, inductively coupled DC-DC converter that generates a
nominal field supply VDDF of 3.1V with just enough output current to power the field-side of the
MAX22530– MAX22532 family.
The Power Supply Decoupling section at page 24 treats both VDDL and VDDPL as power supplies. The diagram at page 36 shows both VDDL and VDDPL being provided with power supplies.
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.
You are right, thank you for confirming. I will read more on what the REF SUPPLY column means. For now, I have submitted improvements based on your suggestions.
drivers/iio/adc/max22531.c
Outdated
}; | ||
|
||
static const struct regmap_config regmap_config = { | ||
.reg_bits = 16, |
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 SPI read/write commands (datasheet Table 1 and Table 2) have 8-bit header so we would have .reg_bits = 8
(or reg_bits = 6
maybe).
Though, the header also contains the W/R and burst bits.
I think the W/R can be handled with
.write_flag_mask = BIT(1)
the burst bit skipped with
.pad_bits = 1
See https://elixir.bootlin.com/linux/v6.15.6/source/include/linux/regmap.h#L254
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.
Ack
drivers/iio/adc/max22531.c
Outdated
|
||
adc->regmap = devm_regmap_init_spi(spi, ®map_config); | ||
if (IS_ERR(adc->regmap)) | ||
dev_err(&spi->dev, "regmap init failure\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.
Usually when something critical fails in the probe it is better to stop and return, like:
return dev_err_probe(&spi->dev, PTR_ERR(adc->regmap), "regmap init failure\n")
Same for other similar cases here.
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.
Ack.
Hello, so I've set up MAX2531_EVKIT_A and tested the initial MAX22531 driver version. I've added "brcm,bcm2712" to device tree overlay compatible list and added another @KernelShinobi , please, update the PR code according to the provided suggestions. Despite the message printed to kernel logs, the MAX22531_REG_PROD_ID read is clearly not successful, as we should get 0x0001 from that register. As we talked about in a previous meeting, drop the regmap implementation and make direct use of SPI transfers to comply with the protocol described on datasheet page 19 correctly. I'll test it again after you update the driver code and register access functions accordingly. |
Improve initial DT Overlay for MAX22530-MAX22532. Add MAX22530-MAX22532 device tree documentation. Signed-off-by: Abhinav Jain <[email protected]>
Add device entries for MAX22530 and MAX22532. Retrieve logic and DC-DC power supplies post fixes in DT overlay. Add chip_info structure for the device. Fix regmap_config for SPI read/write commands as per the datasheet. Implement scale in max22531_read_raw function. Add boilerplate text to Kconfig for the driver. Signed-off-by: Abhinav Jain <[email protected]>
MAX22531 is a galvanically isolated, field-side self-powered, 4-channel, multiplexed, 12-bit ADC.
PR Description
Basic IIO ADC max22531 driver features:
PR Type
PR Checklist