From 8d6ccd9316093e8ad04dacfcdfb2942679f900a0 Mon Sep 17 00:00:00 2001 From: Nuno Sa Date: Mon, 25 Nov 2024 15:47:58 +0100 Subject: [PATCH 1/2] iio: adc: ad7768: Fix scale reading ad7768_scale() is dependent on the st->vref voltage. Hence, simplify the code and get the voltage only during probe (as it should not change at runtime) with devm_regulator_get_enable_read_voltage() [nsa: devm_regulator_get_enable_read_voltage() is not available in 2023_R2, so do it by hand to get the voltage during probe] Fixes: 92cc452e8f13 ("iio: adc: ad7768: simplify probe") Co-developed-by: Dragos Bogdan Signed-off-by: Dragos Bogdan Signed-off-by: Nuno Sa (cherry picked from commit 44e7ac12dffbfd544668d3c216f82f78d92bcbb0) --- drivers/iio/adc/ad7768.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c index c3a8df0d637116..9819e59f0798f5 100644 --- a/drivers/iio/adc/ad7768.c +++ b/drivers/iio/adc/ad7768.c @@ -103,9 +103,9 @@ struct ad7768_avail_freq { struct ad7768_state { struct spi_device *spi; struct mutex lock; - struct regulator *vref; struct clk *mclk; struct gpio_chip gpiochip; + u64 vref_nv; unsigned int datalines; unsigned int sampling_freq; enum ad7768_power_modes power_mode; @@ -473,16 +473,9 @@ static ssize_t ad7768_scale(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); const struct iio_chan_spec *chan = &indio_dev->channels[0]; struct ad7768_state *st = ad7768_get_data(indio_dev); - u64 vref_nv; u64 scale; - int ret; - - ret = regulator_get_voltage(st->vref); - if (ret < 0) - return ret; - vref_nv = (u64)ret * NANO * 2; - scale = div64_ul(vref_nv, BIT(chan->scan_type.realbits)); + scale = div64_ul(st->vref_nv, BIT(chan->scan_type.realbits)); return scnprintf(buf, PAGE_SIZE, "0.%012llu\n", scale); } @@ -789,10 +782,16 @@ int ad7768_gpio_setup(struct ad7768_state *st) return devm_gpiochip_add_data(&st->spi->dev, &st->gpiochip, st); } +static void ad7768_regulator_disable(void *reg) +{ + regulator_disable(reg); +} + static int ad7768_probe(struct spi_device *spi) { struct gpio_desc *gpio_reset; struct ad7768_state *st; + struct regulator *vref; struct iio_dev *indio_dev; int ret; @@ -806,10 +805,25 @@ static int ad7768_probe(struct spi_device *spi) if (!st->chip_info) return -ENODEV; - ret = devm_regulator_get_enable(&spi->dev, "vref"); + vref = devm_regulator_get(&spi->dev, "vref"); + if (IS_ERR(vref)) + return PTR_ERR(vref); + + ret = regulator_enable(vref); + if (ret) + return ret; + + ret = devm_add_action_or_reset(&spi->dev, ad7768_regulator_disable, + vref); if (ret) return ret; + ret = regulator_get_voltage(vref); + if (ret < 0) + return ret; + + st->vref_nv = (u64)ret * NANO * 2; + st->mclk = devm_clk_get_enabled(&spi->dev, "mclk"); if (IS_ERR(st->mclk)) return PTR_ERR(st->mclk); From 014cff97e49ce8afadb7b2c8b4b7bdba1336d4f1 Mon Sep 17 00:00:00 2001 From: Nuno Sa Date: Mon, 18 Nov 2024 09:57:42 +0100 Subject: [PATCH 2/2] iio: adc: adrv9002: fix tx2 scale for rx2tx2 Similar to commit 7ebe866977d4 ("iio: adc: adrv9002: fixup tx2 power level") we need to apply the same fixup even in rx2tx2. The reasoning for not doing it at the time was that if the channels are tuned together and have the same SSI delays, it should not be needed. Well... While at it (and as advised by HW folks), we're now doing the fixup for all TX channels. Signed-off-by: Nuno Sa (cherry picked from commit 13a58d5e765f039000310cfb927a474bf010cd42) --- drivers/iio/adc/navassa/adrv9002.c | 25 +++++++++++++++++++------ drivers/iio/adc/navassa/adrv9002.h | 3 ++- drivers/iio/adc/navassa/adrv9002_conv.c | 11 ++++++----- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/iio/adc/navassa/adrv9002.c b/drivers/iio/adc/navassa/adrv9002.c index 3d53e73f399e1b..d9275a10c9a6a2 100644 --- a/drivers/iio/adc/navassa/adrv9002.c +++ b/drivers/iio/adc/navassa/adrv9002.c @@ -3768,22 +3768,35 @@ static void adrv9002_fill_profile_read(struct adrv9002_rf_phy *phy) * Obviuosly, this is an awful workaround and we need to understand the root cause of * the issue and properly fix things. Hopefully this won't one those things where * "we fix it later" means never! + * + * Update: Now we do the fixup for all TX channels and for rx2tx2 mode. */ -int adrv9002_tx2_fixup(const struct adrv9002_rf_phy *phy) +int adrv9002_tx_fixup(const struct adrv9002_rf_phy *phy, unsigned int chan) { - const struct adrv9002_chan *tx = &phy->tx_channels[ADRV9002_CHANN_2].channel; + const struct adrv9002_chan *tx = &phy->tx_channels[chan].channel; struct adi_adrv9001_TxSsiTestModeCfg ssi_cfg = { .testData = ADI_ADRV9001_SSI_TESTMODE_DATA_FIXED_PATTERN, }; struct adi_adrv9001_TxSsiTestModeStatus dummy; - if (phy->chip->n_tx < ADRV9002_CHANN_MAX || phy->rx2tx2) - return 0; - return api_call(phy, adi_adrv9001_Ssi_Tx_TestMode_Status_Inspect, tx->number, phy->ssi_type, ADI_ADRV9001_SSI_FORMAT_16_BIT_I_Q_DATA, &ssi_cfg, &dummy); } +int adrv9002_tx_fixup_all(const struct adrv9002_rf_phy *phy) +{ + int ret; + u32 c; + + for (c = 0; c < phy->chip->n_tx; c++) { + ret = adrv9002_tx_fixup(phy, c); + if (ret) + return ret; + } + + return 0; +} + int adrv9002_init(struct adrv9002_rf_phy *phy, struct adi_adrv9001_Init *profile) { int ret, c; @@ -3834,7 +3847,7 @@ int adrv9002_init(struct adrv9002_rf_phy *phy, struct adi_adrv9001_Init *profile adrv9002_fill_profile_read(phy); - return adrv9002_tx2_fixup(phy); + return adrv9002_tx_fixup_all(phy); error: /* * Leave the device in a reset state in case of error. There's not much we can do if diff --git a/drivers/iio/adc/navassa/adrv9002.h b/drivers/iio/adc/navassa/adrv9002.h index 40b3d0674d7058..6c61f79e491f2a 100644 --- a/drivers/iio/adc/navassa/adrv9002.h +++ b/drivers/iio/adc/navassa/adrv9002.h @@ -309,7 +309,8 @@ int adrv9002_intf_test_cfg(const struct adrv9002_rf_phy *phy, const int chann, c int adrv9002_check_tx_test_pattern(const struct adrv9002_rf_phy *phy, const int chann); int adrv9002_intf_change_delay(const struct adrv9002_rf_phy *phy, const int channel, u8 clk_delay, u8 data_delay, const bool tx); -int adrv9002_tx2_fixup(const struct adrv9002_rf_phy *phy); +int adrv9002_tx_fixup(const struct adrv9002_rf_phy *phy, unsigned int chan); +int adrv9002_tx_fixup_all(const struct adrv9002_rf_phy *phy); adi_adrv9001_SsiTestModeData_e adrv9002_get_test_pattern(const struct adrv9002_rf_phy *phy, unsigned int chan, bool rx, bool stop); /* phy lock must be held before entering the API */ diff --git a/drivers/iio/adc/navassa/adrv9002_conv.c b/drivers/iio/adc/navassa/adrv9002_conv.c index 59c1ee832bfc66..7cd586a7f4be85 100644 --- a/drivers/iio/adc/navassa/adrv9002_conv.c +++ b/drivers/iio/adc/navassa/adrv9002_conv.c @@ -516,11 +516,12 @@ int adrv9002_axi_intf_tune(const struct adrv9002_rf_phy *phy, const bool tx, con return ret; if (tx) { - if (chann) { - ret = adrv9002_tx2_fixup(phy); - if (ret) - return ret; - } + if (phy->rx2tx2) + ret = adrv9002_tx_fixup_all(phy); + else + ret = adrv9002_tx_fixup(phy, chann); + if (ret) + return ret; /* * we need to restart the tx test for every iteration since it's * the only way to reset the counters.