8000 AD9213 driver by danmois · Pull Request #2804 · analogdevicesinc/linux · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

AD9213 driver #2804

wants to merge 8 commits into from

Conversation

danmois
Copy link
Contributor
@danmois danmois commented May 26, 2025

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

  • Bug fix (a change that fixes an issue)
  • New feature (a change that adds new functionality)
  • Breaking change (a change that affects other repos or cause CIs to fail)

PR Checklist

  • I have conducted a self-review of my own code changes
  • I have tested the changes on the relevant hardware
  • I have updated the documentation outside this repo accordingly (if there is the case)

@danmois danmois force-pushed the 9213 branch 7 times, most recently from 6eab46b to a6a3f96 Compare May 27, 2025 06:53

MODULE_AUTHOR("Dragos Bogdan <dragos.bogdan@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD9213 ADC");
MODULE_LICENSE("GPL v2");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("IIO_BACKEND")

@danmois danmois force-pushed the 10000 9213 branch 15 times, most recently from d1d695c to a6753c4 Compare May 27, 2025 16:13
@danmois danmois marked this pull request as ready for review May 28, 2025 06:08
Copy link
Collaborator
@nunojsa nunojsa left a 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: ...

if (IS_ERR(st->clkin)) {
dev_err(&spi->dev, "failed to get clkin\n");
return PTR_ERR(st->clkin);
}
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Copy link
Collaborator

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.

Copy link
Contributor Author

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);

Copy link
Collaborator

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.

Copy link
Contributor Author

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!

if (ch->num == 14)
return (hmc->vcxo_freq / ch->divider);
else
return hmc7044_get_clk_attr(hw, IIO_CHAN_INFO_FREQUENCY);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant else


return 0;
} else {
return hmc7044_set_clk_attr(hw, IIO_CHAN_INFO_FREQUENCY, rate);
Copy link
Collaborator

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;
}
Copy link
Collaborator

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.

/* protect against device accesses */
struct mutex lock;
u64 adc_frequency_hz;
struct iio_backend *back;
Copy link
Collaborator

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.

/* Power up the AD9213. */
/* Assert a Pin Reset. */
gpiod_set_value_cansleep(adc->reset_gpio, 0);
mdelay(1);
Copy link
Collaborator

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

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);
Copy link
Collaborator

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

}

adc->syncinb_cmos_en =
of_property_read_bool(np, "adi,syncinb-cmos-enable");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use device properties

static struct spi_driver ad9213_driver = {
.driver = {
.name = "ad9213",
.of_match_table = of_match_ptr(ad9213_of_match),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop of_match_ptr()

struct iio_dev *indio_dev = spi_get_drvdata(spi);

iio_device_unregister(indio_dev);
}
Copy link
Collaborator

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()

@danmois
Copy link
Contributor Author
danmois commented Jun 2, 2025

V2

  • remove devm_clk_get in ADF4371 driver
  • make OSCOUT1 IIO channel
  • update AD9213 driver to use regmap, device properties, cleanup.h, error handling

@danmois
Copy link
Contributor Author
danmois commented Jun 2, 2025

V3

  • remove HMC7044 unused code

@danmois
Copy link
Contributor Author
danmois commented Jun 3, 2025

V4

  • remove HMC7044 unused code in hmc7044_clk_set_rate

danmois and others added 8 commits June 4, 2025 09:12
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>
@danmois
Copy link
Contributor Author
danmois commented Jun 4, 2025

V5

  • formatting adjustments


case AD9213_JESD204_FSM_STATE:
if (!adc->jdev)
ret = -EOPNOTSUPP;
Copy link
Contributor

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.

Suggested change
ret = -EOPNOTSUPP;
return -EOPNOTSUPP;

Copy link
Collaborator
@nunojsa nunojsa left a 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);
Copy link
Collaborator

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.

Copy link
Contributor Author

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,
},
Copy link
Collaborator

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);
Copy link
Collaborator

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;
Copy link
Collaborator

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);
Copy link
Collaborator

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);
Copy link
Collaborator

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) {
Copy link
Collaborator

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);
Copy link
Collaborator

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);
Copy link
Collaborator

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);

Copy link
Collaborator

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 :)

@danmois
Copy link
Contributor Author
danmois commented Jun 11, 2025

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

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.

@nunojsa
Copy link
Collaborator
nunojsa commented Jun 12, 2025

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0