-
Notifications
You must be signed in to change notification settings - Fork 891
AD9213 driver #2804
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?
AD9213 driver #2804
Conversation
6eab46b
to
a6a3f96
Compare
drivers/iio/adc/ad9213.c
Outdated
|
||
MODULE_AUTHOR("Dragos Bogdan <dragos.bogdan@analog.com>"); | ||
MODULE_DESCRIPTION("Analog Devices AD9213 ADC"); | ||
MODULE_LICENSE("GPL 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.
MODULE_LICENSE("GPL v2"); | |
MODULE_LICENSE("GPL"); | |
MODULE_IMPORT_NS("IIO_BACKEND") |
d1d695c
to
a6753c4
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.
The driver seems to be an old one that you're now adding. Please make sure to update it and make use of new kernel APIs and helpers.
Also, your commit subjects are not really good. Don't include file suffixes like .h or .c and do not include drivers: ...
. Just iio: ...
drivers/iio/frequency/adf4371.c
Outdated
if (IS_ERR(st->clkin)) { | ||
dev_err(&spi->dev, "failed to get clkin\n"); | ||
return PTR_ERR(st->clkin); | ||
} |
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 makes the clock effectively required now... Shouldn't this still work without jesd?
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, it should. This if will 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.
Don't remove the error check. AFAICT, the clock is indeed mandatory when this device is part of the JESD topology. Hence, I would move the above code into the if (jdev)
block.
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 wonder if the clock isn't in fact required, since we have below: st->clkin_freq = clk_get_rate(st->clkin);
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.
Oh, I just did not looked to the rest of the code. The clock is indeed required but why are you getting it again? You have the above change and right below yo have a call to devm_clk_get_enabled()
. So not sure why the above is 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.
True, not needed. Thank you!
drivers/iio/frequency/hmc7044.c
Outdated
if (ch->num == 14) | ||
return (hmc->vcxo_freq / ch->divider); | ||
else | ||
return hmc7044_get_clk_attr(hw, IIO_CHAN_INFO_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.
redundant else
drivers/iio/frequency/hmc7044.c
Outdated
|
||
return 0; | ||
} else { | ||
return hmc7044_set_clk_attr(hw, IIO_CHAN_INFO_FREQUENCY, rate); |
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
HMC7044_CH_EN); | ||
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.
Hmm, oscout looks like an output clock signal. Or is it something else? This feels like it should be using the clock subsystem.
drivers/iio/adc/ad9213.c
Outdated
/* protect against device accesses */ | ||
struct mutex lock; | ||
u64 adc_frequency_hz; | ||
struct iio_backend *back; |
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, please just use spaces for the fields. This kind of indentation often leads to unnecessary changes when new elements are added.
drivers/iio/adc/ad9213.c
Outdated
/* Power up the AD9213. */ | ||
/* Assert a Pin Reset. */ | ||
gpiod_set_value_cansleep(adc->reset_gpio, 0); | ||
mdelay(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.
do we really need mdelay() here? Also, it seems we have lots of comments in this function. Make sure they follow kernel style comments and are really needed
drivers/iio/adc/ad9213.c
Outdated
ad9213_write(adc, AD9213_REG_PLL_ENABLE_CTRL, 0x00); | ||
|
||
/* Write Register 0x570, Bit 0 = 1, powers up JESD204B PLL. */ | ||
ad9213_write(adc, AD9213_REG_PLL_ENABLE_CTRL, AD9213_PWRUP_LCPLL); |
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.
None of the calls to ad9213_write() check error codes
drivers/iio/adc/ad9213.c
Outdated
} | ||
|
||
adc->syncinb_cmos_en = | ||
of_property_read_bool(np, "adi,syncinb-cmos-enable"); |
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 device properties
drivers/iio/adc/ad9213.c
Outdated
static struct spi_driver ad9213_driver = { | ||
.driver = { | ||
.name = "ad9213", | ||
.of_match_table = of_match_ptr(ad9213_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.
drop of_match_ptr()
drivers/iio/adc/ad9213.c
Outdated
struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
|
||
iio_device_unregister(indio_dev); | ||
} |
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.
no need for a .remove()
V2
|
V3
|
V4
|
Add JESD FSM ops. These modifications are required if the device is added to a JESD topology. Required by the AD9213 driver, so that the initialization sequence is synchronized with the AD9213 operation. Signed-off-by: George Mois <george.mois@analog.com>
Add OSCOUT1 as an output channel to the driver. The OSCOUT1 output is used a an input for the ADF4371 on the AD9213_EVB, and is used for synchronizing the initalization of the two devices in this setup. Signed-off-by: George Mois <george.mois@analog.com>
Remove the adi,divider-ratio defines, as they are no longer used. Signed-off-by: George Mois <george.mois@analog.com>
This adds device tree bindings for the AD9213 ADC. Signed-off-by: George Mois <george.mois@analog.com>
Add driver for AD9213. Signed-off-by: AndrDragomir <andrei.dragomir@analog.com> Signed-off-by: George Mois <george.mois@analog.com>
Add AD9213 driver to adi_mb_defconfig. Signed-off-by: George Mois <george.mois@analog.com>
Make sure the AD9213 ADC is built. Signed-off-by: George Mois <george.mois@analog.com>
Add devicetree for AD9213_EVB. Signed-off-by: AndrDragomir <andrei.dragomir@analog.com> Signed-off-by: George Mois <george.mois@analog.com>
V5
|
|
||
case AD9213_JESD204_FSM_STATE: | ||
if (!adc->jdev) | ||
ret = -EOPNOTSUPP; |
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 error case is overwritten right below on jesd204_get_active_links_num error or always by jesd204_get_links_data.
At jesd204_get_active_links_num a NULL pointer dereference would occur if the method itself didn't check if (!jdev)
, but it does.
I suggest to direct return on all ret =
of this method, it saves some lines and avoids that.
ret = -EOPNOTSUPP; | |
return -EOPNOTSUPP; |
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 look at my comment about commit subjects in the first version of the series. Also, can we have this without JESD FSM? What I'm thinking is to upstream the driver without FSM and then backport it with it. At least, the driver would not be completely out of tree
|
||
hmc->oscout1_driver_impedance = HMC7044_DRIVER_IMPEDANCE_DISABLE; | ||
of_property_read_u32(np, "adi,oscillator-output1-driver-impedance", | ||
&hmc->oscout1_driver_impedance); |
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 removing the DT properties? I'm aware this is now done during runtime but removing these properties now will break old DTs (users) that rely on them to have an initial OSCOUT value. So, most likely having this controlled at runtime should have be done from the beginning but I would say that we're now stuck with these 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.
In the first version, this output was treated separately. Now, it is treated as an additional channel of HMC7044. This is the only project using OSCOUT1, so no old DTs have this property.
.driver = { | ||
.name = "ad9213", | ||
.of_match_table = ad9213_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.
odd indentation...
if (ret) | ||
return ret; | ||
|
||
dev_info(&adc->spi->dev, "%s Probed\n", indio_dev->name); |
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.
drop the above
} | ||
|
||
indio_dev->dev.parent = &spi->dev; | ||
indio_dev->name = spi->dev.of_node->name; |
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.
drop the above. Give it the real part name
if (ret) | ||
return ret; | ||
|
||
regmap_read(adc->regmap, AD9213_REG_PLL_STATUS, &status); |
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.
no error check
break; | ||
} | ||
|
||
ret = sprintf(buf, "%d\n", adc->is_initialized); |
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 sysfs_emit(). Ditto for all other places
break; | ||
|
||
case AD9213_JESD204_FSM_CTRL: | ||
if (!adc->jdev) { |
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 wonder if we can make this slightly better. Don't expose these attrs in the first place if jdev is NULL
break; | ||
} | ||
} | ||
ret = sprintf(buf, "%d\n", paused); |
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 is big enough that deserves an helper function
ret = -EOPNOTSUPP; | ||
break; | ||
} | ||
ret = strtobool(buf, &enable); |
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.
kstrtobool()
ret = regmap_read(adc->regmap, reg, read_val); | ||
else | ||
ret = regmap_write(adc->regmap, reg, write_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 can be done much better. Will let you figure it out :)
I doubt that this can be done without the FSM. It assures that the correct probing order is maintained. Will experiment if removing it is possible. |
Yeah, it would be just so we could upstream a version of the driver without it :) |
PR Description
The AD9213 is a single, 12-bit, 6 GSPS/10.25 GSPS, radio frequency (RF) analog-to-digital converter (ADC) with a 6.5 GHz input bandwidth. The AD9213 supports high dynamic range frequency and time domain applications requiring wide instantaneous bandwidth and low conversion error rates (CER). The AD9213 features a 16-lane JESD204B interface to support maximum bandwidth capability.
PR Type
PR Checklist