-
Notifications
You must be signed in to change notification settings - Fork 845
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
Add support for adaq776x-1 series and add missing features #2587
base: main
Are you sure you want to change the base?
Conversation
4a14e55
to
9432dff
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.
First round of review... There#s some stuff with ABI that needs to be figured. In your second patch, you also have:
"It also fixes sampling frequency calculation, sync pulse using registers
and data acquisition with iio."
Please don't mix fixes with new code being added. Fixes need to come first and be as standalone as possible.
Also note that I'm aware this driver already diverged from the upstream version but it would very nice (and it would make a lot of sense) if you could send these patches upstream with the new devices and new ABI. Naturally you would have to ommit the spi offload part of it but the new ABI would be very important to have it discussed (and agreed) upstream. Otherwise, what it will most likely happen is that we merge something in here that will then change when upstreaming the missing bits of this driver upstream.
drivers/iio/adc/ad7768-1.c
Outdated
[SINC5_DEC_X8] = "SINC5_DEC_X8", | ||
[SINC5_DEC_X16] = "SINC5_DEC_X16", | ||
[SINC3] = "SINC3", | ||
[WIDEBAND] = "WIDEBAND", |
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 something to bother when trying to upstream but take a look at this ABI:
I'm fairly sure that when upstreaming we will be asked to put this ABI in a more a generic file. Hence, it makes sense to see if there's something on that file that makes sense to be used in here.
drivers/iio/adc/ad7768-1.c
Outdated
[AD7768_ECO_MODE] = "AD7768_ECO_MODE", | ||
[AD7768_MED_MODE] = "AD7768_MED_MODE", | ||
[AD7768_FAST_MODE] = "AD7768_FAST_MODE", | ||
}; |
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 guess we could implement the above with runtime PM but I'll defer this discussion for usptream...
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 will take a look at the Power management module.
drivers/iio/adc/ad7768-1.c
Outdated
IIO_ENUM("dec_rate", IIO_SHARED_BY_ALL, &ad7768_dec_rate_iio_enum), | ||
IIO_ENUM_AVAILABLE("dec_rate", IIO_SHARED_BY_ALL, &ad7768_dec_rate_iio_enum), | ||
IIO_ENUM("mclk_div", IIO_SHARED_BY_ALL, &ad7768_mclk_div_iio_enum), | ||
IIO_ENUM_AVAILABLE("mclk_div", IIO_SHARED_BY_ALL, &ad7768_mclk_div_iio_enum), |
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.
What's the mclk_div
about? Is this an internal divider for an output clock? Or is it for an input clk? If it's an input clock do we really need to change this at runtime or a DT parameter would be enough?
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.
MCLK is an input clock generated by a Crystal. mclk_div
is set by a configuration register to control the sampling 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.
Could we then somehow implement this as part of the sampling_frequency attr?
drivers/iio/adc/ad7768-1.c
Outdated
indio_dev->name = spi_get_device_id(spi)->name; | ||
ret = device_property_read_u32(&spi->dev, "adi,low-latency", &val); | ||
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.
I don't think this needs to be a mandatory property at all... Also seems like a boolean one. But more importantly, it raises the question about this being a DT property? It's at the very least not too coherent with the power_modes attr? Is this somehow related with those modes?
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.
Yes, that could be a boolean. We need something like this in the devicetree to set the IIO channel to either 16 or 24 bits.
In Sinc5 Decimation x8 mode, the sample width is set to 16 bits, while in other filter modes, the sample width is 24 bits.. Since we cannot change the IIO channel in runtime, we need a property in the device tree to choose between the two cases.
When this property is "enabled," the device will operate exclusively in Sinc5 Dec8 mode (16-bit samples). If the property is disabled, the filter mode can be chosen between the other options, and the sample width will default to 24 bits.
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 Sinc5 Decimation x8 mode, the sample width is set to 16 bits, while in other filter modes, the sample width is 24 bits.. Since we cannot change the IIO channel in runtime, we need a property in the device tree to choose between the two cases.
If I'm understanding correctly, you can now change the scan elements at run time... take a look at
https://elixir.bootlin.com/linux/v6.11/source/include/linux/iio/iio.h#L839
and how it's being used...
drivers/iio/adc/ad7768-1.c
Outdated
st->aaf_gain = AD7768_AAF_IN1; | ||
|
||
if (device_property_present(&spi->dev, "adi,aaf-gain") | ||
&& st->chip->has_variable_aaf) { |
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.
Don't check for presence... Instead, do it like this:
ret = device_property_read_u32(&spi->dev, "adi,aaf-gain", &val);
if (!ret) {
if (!st->chip->has_variable_aaf)
return dev_err_probe(...);
// proceed with code validating the prop value
...
}
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.
noted
* Request the SPI controller to make MOSI idle high. | ||
*/ | ||
spi->mode |= SPI_MOSI_IDLE_HIGH; | ||
ret = spi_setup(spi); |
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 should have a Fixes tag and be the first patch in the pull. Fixes should always come first in case we want to backport them.
Also wondering why this was never caught...
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.
Ok, i will separate the fixes and move them to the beginning.
without that the device works, but not consistently. So I guess this slipped through.
drivers/iio/adc/ad7768-1.c
Outdated
@@ -4,6 +4,7 @@ | |||
* | |||
* Copyright 2017 Analog Devices Inc. | |||
*/ | |||
#include "linux/byteorder/little_endian.h" |
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 seems like an header being auto added by clangd 😅
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.
Indeed, i will check this out
drivers/iio/adc/ad7768-1.c
Outdated
tx_data[0] = AD7768_RD_FLAG_MSK(addr); | ||
xfer.tx_buf = tx_data; | ||
ret = spi_sync_transfer(st->spi, &xfer, 1); | ||
if (ret < 0) | ||
return ret; | ||
*data = (len == 1 ? st->data.buf[0] : st->data.word); | ||
*data = (len == 1 ? st->data.buf[1] : cpu_to_be32(st->data.word)); |
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.
are the above changes needed?
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.
It is necessary for the new spi-engine integration
Thanks for the feedback, I will re-arrange the commits and take a look at the ABI issue. I am sending these patches now to get a preliminar review before sending them upstream. So, when it is good enough, we can hold off this PR until they are upstreamed. |
b8a52d0
to
c9f4f32
Compare
v2:
|
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 PR adds support for a lot of stuff.
In some patch I saw something like Co-authored-by
when the official tag is Co-developed-by
. See Documentation/process/submitting-patches.rst.
The dt-bindings patch should come before the updates to the dts files.
dts files should follow the documentation provided by the dt (binding) doc.
Patches can probably become more concise and cleaner.
Anyways, looks like you're on the right track for it.
drivers/iio/adc/ad7768-1.c
Outdated
@@ -898,14 +1141,19 @@ static int ad7768_setup(struct ad7768_state *st) | |||
return ret; | |||
|
|||
st->gpio_sync_in = devm_gpiod_get(&st->spi->dev, "adi,sync-in", | |||
GPIOD_OUT_LOW); | |||
GPIOD_IN); |
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 @jonathanns, sync_in (adi,sync-in-gpios
) is already defined in upstream dt doc and driver as an output pin (GPO). Changing it to input now would break users of the current upstream implementation (if any). Datasheet page 21 says "SYNC_IN receives the synchronization signal from SYNC_OUT or from the main controller." So, maybe define some dt property e.g. adi,sync-out-to-sync-in
(name up to you), then check for that. If adi,sync-out-to-sync-in
is absent, get and activate gpio_sync_in
when appropriate (current implementation). If the property is present, do not touch gpio_sync_in
and do things the new way.
drivers/iio/adc/ad7768-1.c
Outdated
unsigned int val, mclk_div_value; | ||
int ret; | ||
|
||
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.
unlocking the mutex before reg read? mutex_lock(&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.
My mistake. I will fix that
drivers/iio/adc/ad7768-1.c
Outdated
ret = ad7768_spi_reg_read(st, AD7768_REG_POWER_CLOCK, &val, 1); | ||
if (ret) | ||
goto out; | ||
mclk_div_value = (val & 0xcf) | AD7768_PWR_MCLK_DIV(mclk_div); |
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 do we bit and with 0xCF?
Wondering if FIELD_PREP() could be used here.
e.g.
#define AD7768_IMPORTANT_REG_FIELD 0xCF
...
ret = ad7768_spi_reg_read(st, AD7768_REG_POWER_CLOCK, &val, 1);
if (ret)
goto out;
mclk_div_value &= ~AD7768_IMPORTANT_REG_FIELD
mclk_div_value |= FIELD_PREP(AD7768_IMPORTANT_REG_FIELD, val);
see include/linux/bitfield.h for more examples.
drivers/iio/adc/ad7768-1.c
Outdated
if (ret < 0) | ||
goto out; | ||
ret = ad7768_spi_reg_write(st, AD7768_REG_SINC3_DEC_RATE_LSB, dec_rate_lsb); | ||
|
||
out: | ||
mutex_unlock(&st->lock); | ||
|
||
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.
nitpick: blank lines after error returns make it easier to spot what is error handling code and what is not.
If you don't want too many blank lines in the code, it's better to bring statements at same indentation level closer. e.g.
if (ret < 0)
goto out;
ret = ad7768_spi_reg_write(st, AD7768_REG_SINC3_DEC_RATE_LSB, dec_rate_lsb);
out:
mutex_unlock(&st->lock);
return ret;
drivers/iio/adc/ad7768-1.c
Outdated
if (ret) | ||
goto out; | ||
mode = (val & 0x8f) | AD7768_DIG_FIL_FIL(filter_mode); |
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.
What about using FIELD_PREP()
here too?
@@ -83,7 +83,7 @@ | |||
spi-cpol; | |||
spi-cpha; | |||
vref-supply = <&vref>; | |||
adi,sync-in-gpios = <&gpio0 88 GPIO_ACTIVE_LOW>; | |||
adi,sync-in-gpios = <&gpio0 92 GPIO_ACTIVE_LOW>; |
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 do you need to update this?
Didn't you say sync-out was connected to sync-in?
spi-cpol; | ||
spi-cpha; | ||
vref-supply = <&vref>; | ||
adi,sync-in-gpios = <&gpio0 92 GPIO_ACTIVE_LOW>; |
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.
Will the sync-in GPIO be needed if SYNC_OUT is connected to SYNC_IN?
spi-cpol; | ||
spi-cpha; | ||
vref-supply = <&vref>; | ||
adi,sync-in-gpios = <&gpio0 92 GPIO_ACTIVE_LOW>; |
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 question here, sync-in needed?
spi-cpol; | ||
spi-cpha; | ||
vref-supply = <&vref>; | ||
adi,sync-in-gpios = <&gpio0 92 GPIO_ACTIVE_LOW>; |
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.
sync-in needed?
with IN1_AAF, IN2_AAF, or IN3_AAF on the ADAQ7769-1. | ||
$ref: /schemas/types.yaml#/definitions/uint16 | ||
enum: [143, 364, 1000] | ||
|
||
adi,sync-in-gpios: | ||
maxItems: 1 | ||
description: |
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 to also have a dt check for the gain property.
allOf:
# Gain property only applies to ADAQ devices
- if:
properties:
compatible:
not:
contains:
enum:
- adi,adaq7767-1
- adi,adaq7768-1
- adi,adaq7769-1
then:
properties:
adi,gain-milli: false
Also, FWIW, the updates to adaq7768-1 driver use the new MOSI idle feature which is not included in this PR but is included in #2621. So that's probably the cause of some of the CI checks never passing here. |
Get Outlook for Android<https://aka.ms/AAb9ysg>
________________________________
From: Jonathan Santos ***@***.***>
Sent: Monday, October 21, 2024 12:40:54 PM
To: analogdevicesinc/linux ***@***.***>
Cc: Schmitt, Marcelo ***@***.***>; Review requested ***@***.***>
Subject: Re: [analogdevicesinc/linux] Add support for adaq776x-1 series and add missing features (PR #2587)
[External]
@jonathanns commented on this pull request.
________________________________
In drivers/iio/adc/ad7768-1.c<https://urldefense.com/v3/__https://github.com/analogdevicesinc/linux/pull/2587*discussion_r1809063399__;Iw!!A3Ni8CS0y2Y!_gq45BQs1W4FdBJIyq6hlxteUGYfF3_B7SOw931waHjWBSgxpYR3SsAkJqR6ow7DhpNRHK-nuOSGyvVHylUE8I_vUnB2$>:
@@ -898,14 +1141,19 @@ static int ad7768_setup(struct ad7768_state *st)
return ret;
st->gpio_sync_in = devm_gpiod_get(&st->spi->dev, "adi,sync-in",
- GPIOD_OUT_LOW);
+ GPIOD_IN);
I see. What if I remove the adi,sync-in-gpios from the required properties and if it is not present, I use the SPI SYNC instead? Of course that would require the SYNC_IN to be connected to SYNC_OUT in the board.
The dt-binding can have a allOf/oneOf clause. Something like:
required:
allOf:
- reg
- other required props ...
- oneOf:
- adi,sync-in-gpios
- adi,sync-out-to-sync-in
correct syntax may be different from the above.
Additional checks may be included if needed or wanted. Example:
allOf:
- if
adi,sync-in-gpios;
- then
adi,sync-out-to-sync-in: false;
Have a look at other bindings to get the correct syntax for those checks.
—
Reply to this email directly, view it on GitHub<https://urldefense.com/v3/__https://github.com/analogdevicesinc/linux/pull/2587*discussion_r1809063399__;Iw!!A3Ni8CS0y2Y!_gq45BQs1W4FdBJIyq6hlxteUGYfF3_B7SOw931waHjWBSgxpYR3SsAkJqR6ow7DhpNRHK-nuOSGyvVHylUE8I_vUnB2$>, or unsubscribe<https://urldefense.com/v3/__https://github.com/notifications/unsubscribe-auth/A5OAY4CBDX3CQKMIA6VGYIDZ4UOABAVCNFSM6AAAAABNHCV5FWVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDGOBSGUYTEMBUGA__;!!A3Ni8CS0y2Y!_gq45BQs1W4FdBJIyq6hlxteUGYfF3_B7SOw931waHjWBSgxpYR3SsAkJqR6ow7DhpNRHK-nuOSGyvVHylUE8McodytN$>.
You are receiving this because your review was requested.Message ID: ***@***.***>
|
c9f4f32
to
fb7cb23
Compare
v3:
|
drivers/iio/adc/ad7768-1.c
Outdated
if (st->en_spi_sync) | ||
ret = ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x00); |
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 not returning here?
return ad7768_spi_reg_write(st, AD7768_REG_SYNC_RESET, 0x00);
drivers/iio/adc/ad7768-1.c
Outdated
gpiod_set_value(st->gpio_sync_in, 1); | ||
gpiod_set_value(st->gpio_sync_in, 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.
Use gpiod_set_value_cansleep()
, unless this can be called from interrupt context.
drivers/iio/adc/ad7768-1.c
Outdated
st->filter_mode = filter_mode; | ||
ret = ad7768_spi_reg_read(st, AD7768_REG_DIGITAL_FILTER, &mode, 1); | ||
if (ret) | ||
goto out; |
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.
If the read fails a filter mode different from the actual one would the shown to user space.
My suggestion is to update ad7768_state
only after reg write succeeded.
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.
Sure
drivers/iio/adc/ad7768-1.c
Outdated
|
||
mutex_lock(&st->lock); | ||
|
||
st->pwrmode = pwr_mode; |
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, updating the state prior to running the transfers can lead to inconsistent device state in software.
tx_data[0] = AD7768_RD_FLAG_MSK(AD7768_REG_ADC_DATA) << 24; | ||
xfer.tx_buf = tx_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.
Why? high-speed / 16-bit transfers don't need a write buffer? It would be nice to have a comment nearby explaining it if that's the case. Also, what if the transfer is 24-bit? Is the tx buffer set and shifter somewhere else?
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.
Both cases actually don't require the address byte if continuous read mode is enabled. However, for 16-bit mode to work correctly, it’s mandatory to remove the address byte, so we had to adjust for that.
There is already a comment in this same function regarding the continuos read mode, so I don't know why we were using the tx_data
before
/*
* Write a 1 to the LSB of the INTERFACE_FORMAT register to enter
* continuous read mode. Subsequent data reads do not require an
* initial 8-bit write to query the ADC_DATA register.
*/
ret = ad7768_spi_reg_write(st, AD7768_REG_INTERFACE_FORMAT, 0x01);
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.
ok, makes sense. I would do the tx_buf
remove in a separate patch since this isn't really dependent on the scan_type and add this explanation you provided as commit description/body.
drivers/iio/adc/ad7768-1.c
Outdated
tx_data[0] = AD7768_WR_FLAG_MSK(addr); | ||
tx_data[1] = val & 0xFF; | ||
tx_data[1] = AD7768_WR_FLAG_MSK(addr); | ||
tx_data[0] = val & 0xFF; |
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.
hmmm, suspicious. This changes the tx buffer from big endian to little endian. I think you want to do it because of the DMA buffer format that is in CPU endianness (little endian for our arm based test boards). Note, though, this would break users who connect the ADC to conventional SPI controllers (without offload or DMA support).
In the patch adding multiple scan_type, set BE endianness to the scan_type used without spi-engine.
.scan_type = { \
.endianness = IIO_BE \
and set CPU endianness in the scan_type that uses spi-engine with offload/DMA support.
.scan_type = { \
.endianness = IIO_CPU \
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.
Yes, indeed. I will try this, Thanks!
drivers/iio/adc/ad7768-1.c
Outdated
tx_data[0] = AD7768_RD_FLAG_MSK(addr); | ||
tx_data[len] = AD7768_RD_FLAG_MSK(addr); |
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.
Undo this too when proper endianness handling is set in scan_type struct.
drivers/iio/adc/ad7768-1.c
Outdated
@@ -1276,6 +1525,7 @@ static int ad7768_probe(struct spi_device *spi) | |||
st->mclk_freq = clk_get_rate(st->mclk); | |||
st->spi_is_dma_mapped = spi_engine_ex_offload_supported(spi); | |||
st->irq = spi->irq; | |||
st->vref = regulator_get_voltage(st->regulator); |
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.
looks like st->regulator
is only to get the ADC reference voltage (vref). If that's the case, you can simplify this with devm_regulator_get_enable_read_voltage()
now in ADI main.
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.
Right!
@@ -65,7 +106,21 @@ required: | |||
- vref-supply | |||
- spi-cpol | |||
- spi-cpha | |||
- adi,sync-in-gpios |
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.
don't do it all together. One patch for the new parts, another one for the updates to sync pins.
Also, the dt-binding patches should come before the driver changes that use the new dt properties.
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.
noted
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.
put the gain property and related checks in the same patch that adds the new parts and put the changes related to adi,sync-in-spi
property in a separate patch. That's what I wanted to say previously.
Hi @jonathanns, the series is looking better. A few more comments: The patches for multiple scan_types have been ported to ADI main. Rebase on top of main so you won't need to carry them in this PR anymore. Tip: try to add at least one imperative sentence to concisely state what patches do.
ADC input type naming is confusing. I've been trying to clarify the relation between ADC input configuration and IIO support for them in this candidate doc 1373835. I still need to verify the how accurate (or not) those concepts are with other ADI engineers though. The goal is to have something to help us be less uncertain about IIO channel configuration in the future. Answering your question, an ADC channel is considered bipolar if its configuration allows it to output data that represents a negative quantity. For example, if a differential ADC has a pair of inputs (IN+ and IN-) working as a differential input, then a negative value must be provided to user space when IN+ < IN- to indicate that IN+ is below/smaller than IN-. Note that can happen when inputs are above or even below GND. When inputs can go below GND they are called true bipolar but the most important characteristic is whether the input configuration allows/requires negative values to be expressed. |
fb7cb23
to
a105f7c
Compare
v4:
|
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.
Looking much better this version.
Though, there is still room for improvement.
minor commit log neat:
would avoid the word "fix" and try to be more informative when possible. e.g.
"iio: adc: ad7768-1: fix MOSI idle state" -> "iio: adc: ad7768-1: Set MOSI idle state to high"
clock-names = "mclk"; | ||
dmas = <&rx_dma 0>; | ||
dma-names = "rx"; | ||
#io-channel-cells = <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.
Add
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
label = "channel_0";
};
as documented in Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml
clock-names = "mclk"; | ||
dmas = <&rx_dma 0>; | ||
dma-names = "rx"; | ||
#io-channel-cells = <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.
same here, add channel subnode.
clock-names = "mclk"; | ||
dmas = <&rx_dma 0>; | ||
dma-names = "rx"; | ||
#io-channel-cells = <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.
ditto
drivers/iio/adc/ad7768-1.c
Outdated
st->gpio_sync_in = devm_gpiod_get(&st->spi->dev, "adi,sync-in", | ||
if (device_property_present(&st->spi->dev, "adi,sync-in-gpios")) { | ||
st->en_gpio_sync = true; | ||
st->gpio_sync_in = devm_gpiod_get(&st->spi->dev, "adi,sync-in", | ||
GPIOD_OUT_LOW); | ||
if (IS_ERR(st->gpio_sync_in)) | ||
return PTR_ERR(st->gpio_sync_in); | ||
if (IS_ERR(st->gpio_sync_in)) | ||
return PTR_ERR(st->gpio_sync_in); | ||
|
||
} | ||
|
||
if (device_property_present(&st->spi->dev, "adi,sync-in-spi")) | ||
st->en_spi_sync = true; |
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.
Your dt doc comment says "adi,sync-in-gpios and adi,sync-in-spi are mutually exclusive".
The code here does not guarantee they are mutually exclusive, though.
Does this fulfill the requirements?
st->en_gpio_sync = false;
st->gpio_sync_in = devm_gpiod_get(&st->spi->dev, "adi,sync-in",
GPIOD_OUT_LOW);
if (!IS_ERR(st->gpio_sync_in))
st->en_gpio_sync = true;
if (!st->en_gpio_sync && device_property_present(&st->spi->dev, "adi,sync-in-spi"))
st->en_spi_sync = true;
drivers/iio/adc/ad7768-1.c
Outdated
mclk_div_value &= ~(AD7768_PWR_MCLK_DIV_MSK | AD7768_PWR_PWRMODE_MSK); | ||
/* Set mclk_div value */ | ||
mclk_div_value |= AD7768_PWR_MCLK_DIV(mclk_div); | ||
/* Set power mode based on mclk_div value |
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.
neat, IIO maintainer prefers multiline comments with an empty starting line.
/*
* comments ...
*/
https://lore.kernel.org/linux-iio/20241005174151.4bcd55f6@jic23-huawei/ (first patch that appeared when searching the string multiline comment
in IIO mailing list).
drivers/iio/adc/ad7768-1.c
Outdated
|
||
switch (info) { | ||
case IIO_CHAN_INFO_SAMP_FREQ: | ||
return ad7768_set_freq(st, val); | ||
case IIO_CHAN_INFO_SCALE: | ||
if (!st->chip->has_pga) | ||
return -EPERM; |
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.
add a blank line after return -EPERM
for better code readability.
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.
ok
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.
actually, I think -EOPNOTSUPP
would be more appropriate error code 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.
Right!
drivers/iio/adc/ad7768-1.c
Outdated
static const struct ad7768_chip_info adaq7768_chip_info = { | ||
.name = "adaq7768-1", | ||
.channel_spec = adaq776x_channels, | ||
.num_channels = 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.
use ARRAY_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.
ok.
drivers/iio/adc/ad7768-1.c
Outdated
st->aaf_gain = AD7768_AAF_IN1; | ||
ret = device_property_read_u32(&spi->dev, "adi,aaf-gain", &val); | ||
if (!ret) { | ||
if (!st->chip->has_variable_aaf) | ||
return dev_err_probe(&spi->dev, -EINVAL, | ||
"This device does not support AAF"); | ||
|
||
switch (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.
does it makes to first check for the AAF support and ignore adi,aaf-gain
if device doesn't support it?
st->aaf_gain = AD7768_AAF_IN1;
if (st->chip->has_variable_aaf) {
ret = device_property_read_u32(&spi->dev, "adi,aaf-gain", &val);
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.
humm... We could go this way too. since we are setting a default value, this property is not required. The only check is for parts that do not support this feature, but I guess we could also avoid it.
drivers/iio/adc/ad7768-1.c
Outdated
struct spi_device *spi; | ||
struct regulator *vref; | ||
int vref; |
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_uv
is preferred so it is clear what voltage unit is stored.
@@ -65,7 +106,21 @@ required: | |||
- vref-supply | |||
- spi-cpol | |||
- spi-cpha | |||
- adi,sync-in-gpios |
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.
put the gain property and related checks in the same patch that adds the new parts and put the changes related to adi,sync-in-spi
property in a separate patch. That's what I wanted to say previously.
a105f7c
to
fa7bfca
Compare
v5:
|
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.
A few more comments. Most of them would be minor changes to the driver.
@@ -1,21 +1,30 @@ | |||
# SPDX-License-Identifier: GPL-2.0 | |||
# Copyright 2024 Analog Devices Inc. |
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.
remove the copyright line
spi-cpha; | ||
vref-supply = <&vref>; | ||
adi,sync-in-spi; | ||
adi,aaf-gain = <143>; |
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 may have missed it but, where is the documentation for the adi,aaf-gain
property?
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.
Sorry, At some point I changed from adi,gain-milli
to adi,aaf-gain
. Is the first option more adequate? I can replace it
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.
It depends on how the gain is applied. adi,gain-milli
is used to describe the hardware gain applied to the ADC inputs. For ad4000 series, the gain provided by the ADC input scaler is defined by the hardware connections between chip pins OUT+, R1K-, R1K1-, R1K+, R1K1+, and OUT-. For gains set through register configuration or runtime (software) settings, IIO interfaces should be used (_scale, _callibscale). What is this AAF about? Is it related to datasheet AFE_GAIN?
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.
AFE_gain is the combination of Anti-Aliasing Filter (AAF) gain and PGA gain. AAF is an analogic filter with three inputs, each one lead to a specific gain and bandwidth rejection. The user must connect the output of the first filter (PGA), for the case of adaq7769-1, to one of these AAF inputs by inserting a resistor in the corresponding pin:
Only the ADAQ7769-1 and ADAQ7767-1 have variable AAF gain. The second one does not have PGIA, so the AAF input is directly connected to the signal input and AFE gain is the AAF gain.
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.
Hmm, that's a bit different than adi,gain-milli
in that it also defines a bandwidth rejection. Though, to our luck, there is no IIO ABI for exposing bandwidth rejection settings to user space so I think it's okay to reuse adi,gain-milli
to describe the AFF gain. Alternatively, if you want, you can instead provide a property with a different name (e.g. adi,aaf-gain
) documenting it specifies both input gain and bandwidth rejection. In either case, include the documentation for it in Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml.
Edit: just recall linux is not the only user of device tree docs. Other systems may export different properties to users. Better to fully describe the analog gain and bandwidth rejection with a specific property name for it.
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.
About the device that doesn't have variable AAF gain, I think it may be nice to add a check for it. e.g.
# Variable AAF only applicable to ADAQ7769-1 and ADAQ7767-1
- if:
properties:
compatible:
not:
contains:
enum:
- adi,adaq7767-1
- adi,adaq7769-1
then:
properties:
adi,aaf-gain: false
drivers/iio/adc/ad7768-1.c
Outdated
long long val; | ||
struct ad7768_state *st = iio_priv(indio_dev); | ||
|
||
mutex_lock(&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.
Also wouldn't lock on anything here. It's just a read from memory. If some other thread changes st->dec_rate
after the user issues an attribute read, then they will just get a more up to date value.
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.
ok!
if (ret) | ||
goto out; | ||
|
||
if (st->filter_mode == SINC3) { |
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.
SINC3, SINC5, WIDEBAND are also enum elements. Does it make any difference if we use a switch here 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.
SINC5 also includes SINC5_DEC_X8
and SINC5_DEC_X16
cases, if i use switch i have to move it to "default: ". The "else" is considering the those three values of filter_mode.
drivers/iio/adc/ad7768-1.c
Outdated
/* Set Default Decimation rate */ | ||
ret = ad7768_set_dec_rate(st, 32); | ||
if (ret < 0) | ||
return ret; | ||
|
||
/* Set Default Filter mode */ | ||
ret = ad7768_set_dig_fil(indio_dev, SINC5); | ||
if (ret < 0) | ||
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.
Didn't read much into the datasheet but, if I understand it correctly, the device can apply one of 3 digital filters to the signal, sinc5, sinc3, or wideband. Then, the decimation rates available depend on the choice of filter. Wouldn't it be more natural to first have ad7768_set_dig_fil()
then ad7768_set_dec_rate()
. Probalbly no practical difference in changing the call order, just trying to better understand how the device works.
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.
Yes, we have two type of decimation, one for sinc5 and wideband and other for sinc3. We can call them in this order as well, it makes sense
drivers/iio/adc/ad7768-1.c
Outdated
struct ad7768_clk_configuration { | ||
enum ad7768_mclk_div mclk_div; | ||
enum ad7768_dec_rate dec_rate; | ||
unsigned int clk_div; | ||
}; |
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.
Hmm, this is not used in this commit. Should it have gone into a previous commit?
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 must be a leftover from the time I remade all commits. I will remove it, thanks
.name = "ad7768-1", | ||
.channel_spec = ad7768_channels, | ||
.num_channels = ARRAY_SIZE(ad7768_channels), | ||
.available_masks = ad7768_channel_masks, |
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.
where is this available_masks
read from chip_info?
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.
Rigth, I am going to add it
drivers/iio/adc/ad7768-1.c
Outdated
goto out; | ||
} | ||
|
||
/* Write GPIOs 0-2 with the gain mode equivalente value */ |
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.
minor neat: write English comments
"Write GPIOs 0-2 with the gain mode equivalente value" -> "Write the respective gain values to GPIOs 0, 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.
noted
drivers/iio/adc/ad7768-1.c
Outdated
|
||
switch (info) { | ||
case IIO_CHAN_INFO_SAMP_FREQ: | ||
return ad7768_set_freq(st, val); | ||
case IIO_CHAN_INFO_SCALE: | ||
if (!st->chip->has_pga) | ||
return -EPERM; |
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.
actually, I think -EOPNOTSUPP
would be more appropriate error code here.
Add compatibles for supported parts in the ad7768-1 family: ADAQ7767-1, ADAQ7768-1 and ADAQ7769-1 Add property and checks for AFF gain, supported by ADAQ7767-1 and ADAQ7769-1 parts: adi,aaf-gain Signed-off-by: Jonathan Santos <[email protected]>
Add adi,sync-in-spi property to enable synchronization over SPI. This should be used in the case when the GPIO cannot provide a pulse synchronous with the base MCLK signal. User can choose between SPI, GPIO synchronization or neither of them, but only if a external pulse can be provided, for example, by another device in a multidevice setup. Signed-off-by: Jonathan Santos <[email protected]>
Use compatible for new spi-engine implementation. Signed-off-by: Jonathan Santos <[email protected]>
Enables using the ADAQ7767-1 device on ZedBoard with FMC connector. Signed-off-by: Jonathan Santos <[email protected]>
Enables using the ADAQ7768-1 device on ZedBoard with FMC connector. Signed-off-by: Jonathan Santos <[email protected]>
Enables using the ADAQ7769-1 device on ZedBoard with FMC connector. Signed-off-by: Jonathan Santos <[email protected]>
All supported parts require that the MOSI line stays high while in idle. Configure SPI controller to set MOSI idle state to high. Fixes: 8a15c73 ("iio: adc: Add AD7768-1 ADC basic support") Signed-off-by: Jonathan Santos <[email protected]>
The synchronization method using GPIO requires the generated pulse to be truly synchronous with the base MCLK signal. When it is not possible to do that in hardware, the datasheet recommends using synchronization over SPI, where the generated pulse is already synchronous with MCLK. This requires the SYNC_OUT pin to be connected to SYNC_IN pin. Add the option to handle device synchronization over SPI. Signed-off-by: Jonathan Santos <[email protected]>
Separate filter mode and decimation rate from the sampling frequency attribute. The new filter mode attribute enables SINC3 and WIDEBAND filters, which were previously unavailable. Previously, combining decimation and MCLK divider in the sampling frequency obscured performance trade-offs. Lower MCLK divider settings increase power usage, while lower decimation rates reduce precision by decreasing averaging. By creating a decimation attribute, users gain finer control over performance. The addition of those attributes allows a wider range of sampling frequencies and more access to the device features. Co-developed-by: PopPaul2021 <[email protected]> Signed-off-by: PopPaul2021 <[email protected]> Signed-off-by: Jonathan Santos <[email protected]>
When the device is configured to Sinc5 filter and decimation x8, output data is reduced to 16-bits in order to support 1 MHz of sampling frequency due to clock limitation. Use multiple scan types feature to enable the driver to switch scan type in runtime, making possible to support both 24-bit and 16-bit resolution. Signed-off-by: Jonathan Santos <[email protected]>
The address byte is not needed in the SPI transfer if continuous read mode is enabled. In this case, data readback occurs on the application of SCLK. Remove tx_buf from IIO buffer read transfer to reduce the duration of each transfer and enable the sample rate of 1.024 MHz at 16-bit resolution, given the maximum supported SCLK rate of 20 MHz: - With address byte: (16-bit data + 8-bit address) * 1.024 MHz > 20 MHZ. Insufficient SCLK cycles to drive out the output. - Without address byte: (16-bit data) * 1.024 MHz < 20 MHz. Signed-off-by: Jonathan Santos <[email protected]>
Add support for new spi-engine implementation on ad7768-1 driver, optimizing offload transfers by reducing CS delay and minimizing the number of commands in the offload FIFO. Without the otimization, there's not enough time between the end of a transfer and the start of the next one, reducing the actual sample rate. Adjust 'tx_data' buffer handling in SPI register read and write functions to ensure endianness consistency with the new spi-engine. Signed-off-by: Jonathan Santos <[email protected]>
Add Chip info struct in SPI device to store channel information for each supported part. Signed-off-by: Jonathan Santos <[email protected]>
Use devm_regulator_get_enable_read_voltage function as a standard and concise way of reading the voltage from the regulator and keep the regulator enabled. Replace the regulator descriptor with the direct voltage value in the device struct. Signed-off-by: Jonathan Santos <[email protected]>
Add support for ADAQ7767/68/69-1 series, which includes PGIA and Anti-aliasing filter (AAF) gains. The PGA gain is configured in run-time through the scale attribute, if supported by the device. The scale options are updated according to the output data width. The AAF gain is configured in the devicetree and it should correspond to the AAF channel selected in hardware. Signed-off-by: Jonathan Santos <[email protected]>
fa7bfca
to
fd9c009
Compare
v6:
|
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.
Looks good overall.
It will certainly change much more if submitted upstream but, for now, I think this is fairly good. With the last of my comments addressed,
Reviewed-by: Marcelo Schmitt [email protected]
spi-cpha; | ||
vref-supply = <&vref>; | ||
adi,sync-in-spi; | ||
adi,aaf-gain = <143>; |
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.
adi,aaf-gain = /bits/ 16 <143>;
since dt-binding specifies it is 16-bit
@@ -1168,14 +1167,19 @@ static int ad7768_buffer_postenable(struct iio_dev *indio_dev) | |||
return ret; | |||
|
|||
if (st->spi_is_dma_mapped) { | |||
st->offload_xfer.rx_buf = rx_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.
Don't know the detailed explanation for it but I've been told to set buffers with a hacky pointer when the data is expected to travel through DMA. I suppose that would apply to the offload buffer here as well.
/* HACK: invalid pointer indicates read data from SPI offload DMA */
st->offload_xfer.rx_buf = (void*)(-1);
*val = st->vref_uv / 1000; | ||
if (st->chip->has_variable_aaf) | ||
*val = (*val * MILLI) / ad7768_aaf_gains[st->aaf_gain]; | ||
*val2 = scan_type->realbits - 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.
Was about to suggest something like
if (scan_type->sign == 's')
*val2 = scan_type->realbits - 1;
else
*val2 = scan_type->realbits;
but the ADC output code is always in two's complement format so the current *val2
assignment is correct.
If you think appropriate, add a comment like
/* ADC output code is two's complement so only (realbits - 1) bits express voltage magnitude */
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 some comments on top of @machschmitt . Please go ahead and usptream the bits that can be upstreamed.
properties: | ||
compatible: | ||
not: | ||
contains: |
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 if the contains is needed...
adi,sync-in-spi: false | ||
- if: | ||
required: | ||
- adi,sync-in-spi |
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.
Would this be something that we could assume in the absence of adi,sync-in-gpios
or do we really need to be explicit?
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's what we have decided for the synchronization:
- Using GPIO: We define
adi,sync-in-gpios
and route the GPIO pin to the SYNC_IN pin on the board. - Using SPI command: We define the
adi,sync-in-spi
and route the SYNC_OUT pin to the SYNC_IN pin in the eval board. - We also have the option to do use none of them, but in this case the SYNC_IN pulse should be providaded by an external device or another source (e.g., when multiple devices are involved).
If you believe the third option doesn’t need support, we could consider the absence of adi,sync-in-gpios as indicative of the SPI command synchronization. I think it’s good to include the adi,sync-in-spi option, because it clarifies the need to route SYNC_OUT to SYNC_IN for proper operation.
#size-cells = <0x0>; | ||
|
||
adaq7768_1: adc@0 { | ||
compatible = "adi,adaq7768-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.
I didn't really checked but can we have a common dtsi and then dedicated dts files just for different pieces?
@@ -689,10 +701,17 @@ static int ad7768_setup(struct ad7768_state *st) | |||
if (ret) | |||
return ret; | |||
|
|||
st->en_gpio_sync = false; | |||
st->en_spi_sync = false; |
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 should not be needed assuming you don't touch it after allocating your structure...
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.
Ok!
if (IS_ERR(st->gpio_sync_in)) | ||
return PTR_ERR(st->gpio_sync_in); | ||
if (!IS_ERR(st->gpio_sync_in)) | ||
st->en_gpio_sync = true; |
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're ignoring possible error. Seems to me the gpio is now optional so treat it as such and use devm_gpiod_get_optional(). Then check for errors and for the pointer not being NULL.
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, that is better
val = st->dec_rate; | ||
break; | ||
default: | ||
ret = -EINVAL; |
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.
return -EINVAL
goto out; | ||
|
||
/* update clk_div and power mode */ | ||
ret = ad7768_set_freq(st, st->samp_freq); |
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 would likely have the above in an helper function...
if (st->spi_is_dma_mapped) | ||
return st->filter_mode == SINC5_DEC_X8 ? AD7768_SCAN_TYPE_DMA_HIGH_SPEED : | ||
AD7768_SCAN_TYPE_DMA_NORMAL; | ||
else |
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.
redundant else
.storagebits = 32, | ||
.endianness = IIO_CPU, | ||
}, | ||
}; |
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 one thing that I don't understand... The filter mode was implemented in the previous patch right? So if I'm not missing nothing it seems the previous patch has a bug for some filter or decimation values? If I'm right, this should be a precursor patch...
if (st->chip->has_variable_aaf) { | ||
numerator *= ad7768_aaf_gains[st->aaf_gain]; | ||
denominator *= MILLI; | ||
} |
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.
nit: newline
PR Description
This adds support for ADAQ7768-1, ADAQ7769-1 and ADAQ7767-1 devices from the AD7768-1 family. It also includes:
PR Type
PR Checklist