From 3f1ec8a4651cb210be280f0df5b13bf4d7f823ba Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 10 Nov 2020 15:59:46 +0100 Subject: [PATCH 01/15] iio: frequency: hmc7044: Try to handle periodic LMFC rates When rounding periodic numbers, gcd calculation fails badly. For example 3G/18 = 166.6666666666666, while gcd(3G,166.666667) = 1 Ideally we solve the approximate greatest common divisor problem. But this doesn't look feasible. If we seem to be close use min() In most real world configurations, this should work equally well. Signed-off-by: Michael Hennerich --- drivers/iio/frequency/hmc7044.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index 27b7b32f6d231c..02a9b7ec97bfb7 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -1561,6 +1561,32 @@ static int hmc7044_continuous_chan_sync_enable(struct iio_dev *indio_dev, bool e return 0; } +static int hmc7044_lmfc_lemc_validate(struct hmc7044 *hmc, u64 dividend, u32 divisor) +{ + u32 rem, rem_l, rem_u; + + div_u64_rem(hmc->pll2_freq, divisor, &rem); + + if (rem == 0) { + hmc->jdev_lmfc_lemc_gcd = gcd(dividend, divisor); + return 0; + } + + div_u64_rem(dividend, divisor, &rem); + div_u64_rem(dividend, divisor - 1, &rem_l); + div_u64_rem(dividend, divisor + 1, &rem_u); + + if ((rem_l > rem) && (rem_u > rem)) { + if (hmc->jdev_lmfc_lemc_gcd) + hmc->jdev_lmfc_lemc_gcd = min(hmc->jdev_lmfc_lemc_gcd, divisor); + else + hmc->jdev_lmfc_lemc_gcd = divisor; + return 0; + } + + return -EINVAL; +} + static int hmc7044_jesd204_link_supported(struct jesd204_dev *jdev, enum jesd204_state_op_reason reason, struct jesd204_link *lnk) @@ -1586,15 +1612,17 @@ static int hmc7044_jesd204_link_supported(struct jesd204_dev *jdev, if (hmc->jdev_lmfc_lemc_rate) { hmc->jdev_lmfc_lemc_rate = min(hmc->jdev_lmfc_lemc_rate, (u32)rate); - hmc->jdev_lmfc_lemc_gcd = gcd(hmc->jdev_lmfc_lemc_gcd, rate); + ret = hmc7044_lmfc_lemc_validate(hmc, hmc->jdev_lmfc_lemc_gcd, (u32)rate); } else { hmc->jdev_lmfc_lemc_rate = rate; - hmc->jdev_lmfc_lemc_gcd = gcd(hmc->pll2_freq, rate); + ret = hmc7044_lmfc_lemc_validate(hmc, hmc->pll2_freq, (u32)rate); } dev_dbg(dev, "%s:%d link_num %u LMFC/LEMC %u/%lu gcd %u\n", __func__, __LINE__, lnk->link_id, hmc->jdev_lmfc_lemc_rate, rate, hmc->jdev_lmfc_lemc_gcd); + if (ret) + return ret; return JESD204_STATE_CHANGE_DONE; } From 059ac964f8d0f043b8e7d2a11286b23b0baff691 Mon Sep 17 00:00:00 2001 From: Dragos Bogdan Date: Thu, 14 Jan 2021 16:49:58 +0200 Subject: [PATCH 02/15] iio: frequency: hmc7044: Improve the pfd1 calculation In the previous implementation, by multiplying r1 and n1 by 2 instead of incrementing one and recalculating the other, many possible pfd1 values were omitted. Signed-off-by: Dragos Bogdan --- drivers/iio/frequency/hmc7044.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index 02a9b7ec97bfb7..c70e16eba3aeb3 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -780,6 +780,7 @@ static int hmc7044_setup(struct iio_dev *indio_dev) unsigned int in_prescaler[5]; unsigned long pll1_lock_detect; unsigned long n1, r1; + unsigned long n, r; unsigned long pfd1_freq; unsigned long vco_limit; unsigned long n2[2], r2[2]; @@ -821,12 +822,22 @@ static int hmc7044_setup(struct iio_dev *indio_dev) &n1, &r1); pfd1_freq = vcxo_freq / n1; - while ((pfd1_freq > hmc->pfd1_limit) && - (n1 <= HMC7044_N1_MAX / 2) && - (r1 <= HMC7044_R1_MAX / 2)) { - pfd1_freq /= 2; - n1 *= 2; - r1 *= 2; + + n = n1; + r = r1; + while (pfd1_freq > hmc->pfd1_limit) { + do { + n++; + } while (((vcxo_freq % n) || (lcm_freq * n % vcxo_freq)) && + (n <= HMC7044_N1_MAX)); + r = lcm_freq * n / vcxo_freq; + + if ((n > HMC7044_N1_MAX) || (r > HMC7044_R1_MAX)) + break; + + n1 = n; + r1 = r; + pfd1_freq = vcxo_freq / n1; } hmc->pll1_pfd = pfd1_freq; From aa499f1e7ead989b1c407e2c5b673fd136151ce9 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 21 Apr 2021 11:03:15 +0200 Subject: [PATCH 03/15] iio: frequency: hmc7044: lmfc_lemc_validate() use GCD when in range Let's use the GCD when greater than the min output divider frequency. Signed-off-by: Michael Hennerich --- drivers/iio/frequency/hmc7044.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index c70e16eba3aeb3..6ae2dd8f47495d 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -1574,15 +1574,26 @@ static int hmc7044_continuous_chan_sync_enable(struct iio_dev *indio_dev, bool e static int hmc7044_lmfc_lemc_validate(struct hmc7044 *hmc, u64 dividend, u32 divisor) { - u32 rem, rem_l, rem_u; + u32 rem, rem_l, rem_u, gcd_val, min; - div_u64_rem(hmc->pll2_freq, divisor, &rem); + gcd_val = gcd(dividend, divisor); + min = DIV_ROUND_CLOSEST(hmc->pll2_freq, HMC7044_OUT_DIV_MAX); + + if (gcd_val >= min) { + dev_dbg(&hmc->spi->dev, + "%s: dividend=%llu divisor=%u GCD=%u (hmc->pll2_freq=%u, min=%u)", + __func__, dividend, divisor, gcd_val, hmc->pll2_freq, min); - if (rem == 0) { - hmc->jdev_lmfc_lemc_gcd = gcd(dividend, divisor); + hmc->jdev_lmfc_lemc_gcd = gcd_val; return 0; } + div_u64_rem(hmc->pll2_freq, divisor, &rem); + + dev_dbg(&hmc->spi->dev, + "%s: dividend=%llu divisor=%u GCD=%u rem=%u (hmc->pll2_freq=%u)", + __func__, dividend, divisor, gcd_val, rem, hmc->pll2_freq); + div_u64_rem(dividend, divisor, &rem); div_u64_rem(dividend, divisor - 1, &rem_l); div_u64_rem(dividend, divisor + 1, &rem_u); From 09c4ffa8a5ae5ad1b25c2dce997640a453c22ce8 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 1 Jul 2021 16:05:13 +0200 Subject: [PATCH 04/15] iio: frequency: hmc7044: jesd204-fsm add support for desired SYSREF The framework allows to specify a max SYSREF frequency. The drivers then divide by powers of 2 the lmfc rate. This leaves out some possible rates in between. Add an option to specify the SYSREF frequency. Signed-off-by: Michael Hennerich --- drivers/iio/frequency/hmc7044.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index 6ae2dd8f47495d..149c16b6f18655 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -318,6 +318,7 @@ struct hmc7044 { u32 jdev_lmfc_lemc_rate; u32 jdev_lmfc_lemc_gcd; u32 jdev_max_sysref_freq; + u32 jdev_desired_sysref_freq; bool is_sysref_provider; bool hmc_two_level_tree_sync_en; }; @@ -1350,6 +1351,9 @@ static int hmc7044_parse_dt(struct device *dev, of_property_read_u32(np, "adi,jesd204-max-sysref-frequency-hz", &hmc->jdev_max_sysref_freq); + of_property_read_u32(np, "adi,jesd204-desired-sysref-frequency-hz", + &hmc->jdev_desired_sysref_freq); + hmc->rf_reseeder_en = !of_property_read_bool(np, "adi,rf-reseeder-disable"); @@ -1804,10 +1808,15 @@ static int hmc7044_jesd204_link_pre_setup(struct jesd204_dev *jdev, dev_dbg(dev, "%s:%d link_num %u\n", __func__, __LINE__, lnk->link_id); - while ((hmc->jdev_lmfc_lemc_gcd > hmc->jdev_max_sysref_freq) && - (hmc->jdev_lmfc_lemc_gcd % (hmc->jdev_lmfc_lemc_gcd >> 1) == 0)) - hmc->jdev_lmfc_lemc_gcd >>= 1; - + if (hmc->jdev_desired_sysref_freq && (hmc->jdev_lmfc_lemc_gcd % + hmc->jdev_desired_sysref_freq == 0)) { + hmc->jdev_lmfc_lemc_gcd = hmc->jdev_desired_sysref_freq; + } else { + while ((hmc->jdev_lmfc_lemc_gcd > hmc->jdev_max_sysref_freq) && + (hmc->jdev_lmfc_lemc_gcd % + (hmc->jdev_lmfc_lemc_gcd >> 1) == 0)) + hmc->jdev_lmfc_lemc_gcd >>= 1; + } /* Program the output channels */ for (i = 0; i < hmc->num_channels; i++) { if (hmc->channels[i].start_up_mode_dynamic_enable || hmc->channels[i].is_sysref) { From 8d862050e1ad10a3b3adecee67247b7c5cc1883f Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 6 Jul 2021 09:49:29 +0200 Subject: [PATCH 05/15] iio: frequency: hmc7044: Check SPI read support Given the 3-wire nature of this device, there might be still some users without proper read support. Check SPI read support. Warn and avoid bogus reads. Signed-off-by: Michael Hennerich --- drivers/iio/frequency/hmc7044.c | 57 ++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index 149c16b6f18655..8d7bcc63924639 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -63,6 +63,8 @@ #define HMC7044_VCOIN_MODE_EN BIT(5) #define HMC7044_SYNC_PIN_MODE(x) (((x) & 0x3) << 6) +#define HMC7044_REG_SCRATCHPAD 0x0008 + /* PLL1 */ #define HMC7044_REG_CLKIN0_BUF_CTRL 0x000A #define HMC7044_REG_CLKIN1_BUF_CTRL 0x000B @@ -321,6 +323,7 @@ struct hmc7044 { u32 jdev_desired_sysref_freq; bool is_sysref_provider; bool hmc_two_level_tree_sync_en; + bool read_write_confirmed; }; static const char * const hmc7044_input_clk_names[] = { @@ -366,6 +369,21 @@ static int hmc7044_read(struct iio_dev *indio_dev, return ret; } +static void hmc7044_read_write_check(struct iio_dev *indio_dev) +{ + struct hmc7044 *hmc = iio_priv(indio_dev); + unsigned int val; + + hmc7044_write(indio_dev, HMC7044_REG_SCRATCHPAD, 0xAD); + hmc7044_read(indio_dev, HMC7044_REG_SCRATCHPAD, &val); + + hmc->read_write_confirmed = (val == 0xAD); + + if (!hmc->read_write_confirmed) + dev_warn(&hmc->spi->dev, + "Read/Write check failed (0x%X)\n", val); +} + static unsigned int hmc7044_calc_out_div(unsigned long parent_rate, unsigned long rate) { @@ -521,17 +539,24 @@ static ssize_t hmc7044_show(struct device *dev, static int hmc7044_sync_pin_set(struct iio_dev *indio_dev, unsigned mode) { + struct hmc7044 *hmc = iio_priv(indio_dev); u32 val; int ret; - ret = hmc7044_read(indio_dev, HMC7044_REG_GLOB_MODE, &val); - if (ret < 0) - return ret; + if (hmc->read_write_confirmed) { + ret = hmc7044_read(indio_dev, HMC7044_REG_GLOB_MODE, &val); + if (ret < 0) + return ret; + } else { + val = (hmc->clkin0_rfsync_en ? HMC7044_RFSYNC_EN : 0) | + (hmc->clkin1_vcoin_en ? HMC7044_VCOIN_MODE_EN : 0) | + HMC7044_REF_PATH_EN(0xF); + } val &= ~HMC7044_SYNC_PIN_MODE(~0); val |= HMC7044_SYNC_PIN_MODE(mode); - return hmc7044_write(indio_dev, HMC7044_REG_GLOB_MODE, val); + return hmc7044_write(indio_dev, HMC7044_REG_GLOB_MODE, val); } static ssize_t hmc7044_sync_pin_mode_store(struct device *dev, @@ -884,6 +909,7 @@ static int hmc7044_setup(struct iio_dev *indio_dev) mdelay(10); hmc7044_write(indio_dev, HMC7044_REG_SOFT_RESET, 0); mdelay(10); + hmc7044_read_write_check(indio_dev); /* Disable all channels */ for (i = 0; i < HMC7044_NUM_CHAN; i++) @@ -1133,6 +1159,7 @@ static int hmc7043_setup(struct iio_dev *indio_dev) mdelay(10); hmc7044_write(indio_dev, HMC7044_REG_SOFT_RESET, 0); mdelay(10); + hmc7044_read_write_check(indio_dev); /* Load the configuration updates (provided by Analog Devices) */ hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d); @@ -1500,6 +1527,9 @@ static int hmc7044_status_show(struct seq_file *file, void *offset) int ret; u32 alarm_stat, pll1_stat, pll2_autotune_val, clkin_freq, active; + if (!hmc->read_write_confirmed) + return -EIO; + ret = hmc7044_read(indio_dev, HMC7044_REG_PLL1_STATUS, &pll1_stat); if (ret < 0) return ret; @@ -1762,7 +1792,6 @@ static int hmc7044_jesd204_clks_sync3(struct jesd204_dev *jdev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct hmc7044 *hmc = iio_priv(indio_dev); unsigned val; - int ret; if (!hmc->hmc_two_level_tree_sync_en) return JESD204_STATE_CHANGE_DONE; @@ -1775,14 +1804,18 @@ static int hmc7044_jesd204_clks_sync3(struct jesd204_dev *jdev, if (hmc->is_sysref_provider) return JESD204_STATE_CHANGE_DONE; - ret = hmc7044_read(indio_dev, HMC7044_REG_ALARM_READBACK, &val); - if (ret < 0) - return ret; + if (hmc->read_write_confirmed) { + int ret; + + ret = hmc7044_read(indio_dev, HMC7044_REG_ALARM_READBACK, &val); + if (ret < 0) + return ret; - if (!HMC7044_CLK_OUT_PH_STATUS(val)) - dev_err(dev, - "%s: SYSREF of the HMC7044 is not valid; that is, its phase output is not stable (0x%X)\n", - __func__, val & 0xFF); + if (!HMC7044_CLK_OUT_PH_STATUS(val)) + dev_warn(dev, + "%s: SYSREF of the HMC7044 is not valid; that is, its phase output is not stable (0x%X)\n", + __func__, val & 0xFF); + } if (hmc->device_id == HMC7044 && !hmc->clkin0_rfsync_en && !hmc->clkin1_vcoin_en) hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_PULSE_GEN_REQ); From 3e7b5545c5890ef8dcde22d0e135e0d8b995bb98 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 6 Jul 2021 09:50:09 +0200 Subject: [PATCH 06/15] iio: frequency: hmc7044: After RESTART_DIV_FSM always issue RESEED_REQ After RESTART_DIV_FSM command always issue a RESEED_REQ. Introduce hmc7044_toggle_bit() function to simply code paths. Signed-off-by: Michael Hennerich --- drivers/iio/frequency/hmc7044.c | 103 +++++++++++++++++--------------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index 8d7bcc63924639..f04d4b79b9a138 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -369,6 +369,39 @@ static int hmc7044_read(struct iio_dev *indio_dev, return ret; } +static int hmc7044_toggle_bit(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int mask, + unsigned int us_delay) +{ + struct hmc7044 *hmc = iio_priv(indio_dev); + unsigned int val; + int ret; + + if (hmc->read_write_confirmed) { + ret = hmc7044_read(indio_dev, reg, &val); + if (ret < 0) + return ret; + } else { + val = 0; + } + + ret = hmc7044_write(indio_dev, reg, val | mask); + if (ret < 0) + return ret; + + val &= ~mask; + + ret = hmc7044_write(indio_dev, reg, val); + if (ret < 0) + return ret; + + if (us_delay) + usleep_range(us_delay, us_delay * 2); + + return 0; +} + static void hmc7044_read_write_check(struct iio_dev *indio_dev) { struct hmc7044 *hmc = iio_priv(indio_dev); @@ -905,10 +938,9 @@ static int hmc7044_setup(struct iio_dev *indio_dev) return -EINVAL; /* Resets all registers to default values */ - hmc7044_write(indio_dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET); - mdelay(10); - hmc7044_write(indio_dev, HMC7044_REG_SOFT_RESET, 0); - mdelay(10); + hmc7044_toggle_bit(indio_dev, HMC7044_REG_SOFT_RESET, + HMC7044_SOFT_RESET, 100); + hmc7044_read_write_check(indio_dev); /* Disable all channels */ @@ -1097,13 +1129,14 @@ static int hmc7044_setup(struct iio_dev *indio_dev) mdelay(10); /* Do a restart to reset the system and initiate calibration */ - hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, - HMC7044_RESTART_DIV_FSM); - mdelay(1); + hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESTART_DIV_FSM, 10000); + hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESEED_REQ, 1000); + hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, (hmc->high_performance_mode_clock_dist_en ? HMC7044_HIGH_PERF_DISTRIB_PATH : 0)); - mdelay(1); if (!hmc->clkin1_vcoin_en) { u32 pll1_stat; @@ -1155,10 +1188,9 @@ static int hmc7043_setup(struct iio_dev *indio_dev) } /* Resets all registers to default values */ - hmc7044_write(indio_dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET); - mdelay(10); - hmc7044_write(indio_dev, HMC7044_REG_SOFT_RESET, 0); - mdelay(10); + hmc7044_toggle_bit(indio_dev, HMC7044_REG_SOFT_RESET, + HMC7044_SOFT_RESET, 100); + hmc7044_read_write_check(indio_dev); /* Load the configuration updates (provided by Analog Devices) */ @@ -1249,13 +1281,14 @@ static int hmc7043_setup(struct iio_dev *indio_dev) mdelay(10); /* Do a restart to reset the system and initiate calibration */ - hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, - HMC7044_RESTART_DIV_FSM); - mdelay(1); + hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESTART_DIV_FSM, 1000); + hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESEED_REQ, 1000); + hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, (hmc->high_performance_mode_clock_dist_en ? HMC7044_HIGH_PERF_DISTRIB_PATH : 0)); - mdelay(1); for (i = 0; i < hmc->num_channels; i++) { chan = &hmc->channels[i]; @@ -1689,23 +1722,12 @@ static int hmc7044_jesd204_sysref(struct jesd204_dev *jdev) struct iio_dev *indio_dev = dev_get_drvdata(dev); struct hmc7044 *hmc = iio_priv(indio_dev); int ret; - u32 val; dev_dbg(dev, "%s:%d\n", __func__, __LINE__); mutex_lock(&hmc->lock); - - ret = hmc7044_read(indio_dev, HMC7044_REG_REQ_MODE_0, &val); - if (ret < 0) { - mutex_unlock(&hmc->lock); - return ret; - } - - hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, - val | HMC7044_PULSE_GEN_REQ); - - ret = hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, val); - + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + HMC7044_PULSE_GEN_REQ, 0); mutex_unlock(&hmc->lock); return ret; @@ -1717,8 +1739,6 @@ static int hmc7044_jesd204_clks_sync1(struct jesd204_dev *jdev, struct device *dev = jesd204_dev_to_device(jdev); struct iio_dev *indio_dev = dev_get_drvdata(dev); struct hmc7044 *hmc = iio_priv(indio_dev); - int ret; - unsigned mask, val; if (!hmc->hmc_two_level_tree_sync_en) return JESD204_STATE_CHANGE_DONE; @@ -1731,30 +1751,19 @@ static int hmc7044_jesd204_clks_sync1(struct jesd204_dev *jdev, if (hmc->is_sysref_provider) { if (hmc->device_id == HMC7044) hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_DISABLED); - - mask = HMC7044_RESTART_DIV_FSM; } else { if (hmc->device_id == HMC7044 && !hmc->clkin0_rfsync_en && !hmc->clkin1_vcoin_en) hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_SYNC); else hmc7044_continuous_chan_sync_enable(indio_dev, 1); - - - mask = HMC7044_RESTART_DIV_FSM | HMC7044_RESEED_REQ; } - ret = hmc7044_read(indio_dev, HMC7044_REG_REQ_MODE_0, &val); - if (ret < 0) - return ret; - - hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, - val | mask); - - ret = hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, val); - if (ret) - return ret; + hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESTART_DIV_FSM, (hmc->device_id == HMC7044 && + !hmc->clkin1_vcoin_en) ? 10000 : 1000); - msleep(1); + hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + HMC7044_RESEED_REQ, 1000); return JESD204_STATE_CHANGE_DONE; } From a1fec9f4c918ddf20e5cee60029480632ba98b07 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 6 Jul 2021 09:50:32 +0200 Subject: [PATCH 07/15] iio: frequency: hmc7044: Add some vital probing info Provide some device status information during boot. Signed-off-by: Michael Hennerich --- drivers/iio/frequency/hmc7044.c | 67 +++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index f04d4b79b9a138..4c680d8147a8c1 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -827,6 +827,65 @@ static int hmc7044_clk_register(struct iio_dev *indio_dev, return 0; } +static int hmc7044_info(struct iio_dev *indio_dev) +{ + struct hmc7044 *hmc = iio_priv(indio_dev); + u32 alarm_stat = 0, pll1_stat = 0, clkin_freq, active; + int ret; + + if (!hmc->read_write_confirmed) { + dev_info(&hmc->spi->dev, + "Probed, SPI read support failed\n"); + return 0; + } + + if (hmc->device_id == HMC7044 && !hmc->clkin1_vcoin_en) { + ret = hmc7044_read(indio_dev, + HMC7044_REG_PLL1_STATUS, &pll1_stat); + if (ret < 0) + return ret; + + if (HMC7044_PLL1_FSM_STATE(pll1_stat) != 2) { /* Lock */ + msleep(DIV_ROUND_UP(5000, hmc->pll1_loop_bw)); + ret = hmc7044_read(indio_dev, + HMC7044_REG_PLL1_STATUS, &pll1_stat); + if (ret < 0) + return ret; + } + + ret = hmc7044_read(indio_dev, + HMC7044_REG_ALARM_READBACK, &alarm_stat); + if (ret < 0) + return ret; + + active = HMC7044_PLL1_ACTIVE_CLKIN(pll1_stat); + } else { + active = 1; + } + + if (hmc->device_id == HMC7043) + active = 0; + + if (hmc->clkin_freq_ccf[active]) + clkin_freq = hmc->clkin_freq_ccf[active]; + else + clkin_freq = hmc->clkin_freq[active]; + + if (hmc->device_id == HMC7044 && !hmc->clkin1_vcoin_en) + dev_info(&hmc->spi->dev, + "PLL1: %s, CLKIN%u @ %u Hz, PFD: %u kHz - PLL2: %s @ %u.%06u MHz\n", + pll1_fsm_states[HMC7044_PLL1_FSM_STATE(pll1_stat)], + active, clkin_freq, hmc->pll1_pfd, + HMC7044_PLL2_LOCK_DETECT(alarm_stat) ? + "Locked" : "Unlocked", hmc->pll2_freq / 1000000, + hmc->pll2_freq % 1000000); + else + dev_info(&hmc->spi->dev, "CLKIN%u @ %u.%06u MHz\n", active, + clkin_freq / 1000000, clkin_freq % 1000000); + + return 0; +} + static int hmc7044_setup(struct iio_dev *indio_dev) { struct hmc7044 *hmc = iio_priv(indio_dev); @@ -1165,6 +1224,10 @@ static int hmc7044_setup(struct iio_dev *indio_dev) hmc->clk_data.clks = hmc->clks; hmc->clk_data.clk_num = HMC7044_NUM_CHAN; + ret = hmc7044_info(indio_dev); + if (ret) + return ret; + return of_clk_add_provider(hmc->spi->dev.of_node, of_clk_src_onecell_get, &hmc->clk_data); @@ -1305,6 +1368,10 @@ static int hmc7043_setup(struct iio_dev *indio_dev) hmc->clk_data.clks = hmc->clks; hmc->clk_data.clk_num = HMC7044_NUM_CHAN; + ret = hmc7044_info(indio_dev); + if (ret) + return ret; + return of_clk_add_provider(hmc->spi->dev.of_node, of_clk_src_onecell_get, &hmc->clk_data); From 28bd7087dbc149a1fa85c9719940225cf9641c4e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 6 Jul 2021 10:27:09 +0200 Subject: [PATCH 08/15] iio: frequency: hmc7044: Handle error codes Handle error codes returned by SPI master. Signed-off-by: Michael Hennerich --- drivers/iio/frequency/hmc7044.c | 369 +++++++++++++++++++++++--------- 1 file changed, 263 insertions(+), 106 deletions(-) diff --git a/drivers/iio/frequency/hmc7044.c b/drivers/iio/frequency/hmc7044.c index 4c680d8147a8c1..b6ca795b8a4278 100644 --- a/drivers/iio/frequency/hmc7044.c +++ b/drivers/iio/frequency/hmc7044.c @@ -997,28 +997,45 @@ static int hmc7044_setup(struct iio_dev *indio_dev) return -EINVAL; /* Resets all registers to default values */ - hmc7044_toggle_bit(indio_dev, HMC7044_REG_SOFT_RESET, + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET, 100); + if (ret) + return ret; hmc7044_read_write_check(indio_dev); /* Disable all channels */ - for (i = 0; i < HMC7044_NUM_CHAN; i++) - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0); + for (i = 0; i < HMC7044_NUM_CHAN; i++) { + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0); + if (ret) + return ret; + } /* Load the configuration updates (provided by Analog Devices) */ - hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d); - hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf); - hmc7044_write(indio_dev, HMC7044_REG_PLL1_DELAY, 0x06); - hmc7044_write(indio_dev, HMC7044_REG_PLL1_HOLDOVER, 0x06); - hmc7044_write(indio_dev, HMC7044_REG_VTUNE_PRESET, 0x04); + ret = hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d); + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf); + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_DELAY, 0x06); + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_HOLDOVER, 0x06); + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_VTUNE_PRESET, 0x04); + if (ret) + return ret; - hmc7044_write(indio_dev, HMC7044_REG_GLOB_MODE, + ret = hmc7044_write(indio_dev, HMC7044_REG_GLOB_MODE, HMC7044_SYNC_PIN_MODE(hmc->sync_pin_mode) | (hmc->clkin0_rfsync_en ? HMC7044_RFSYNC_EN : 0) | (hmc->clkin1_vcoin_en ? HMC7044_VCOIN_MODE_EN : 0) | HMC7044_REF_PATH_EN(ref_en)); + if (ret) + return ret; /* Program PLL2 */ @@ -1028,115 +1045,166 @@ static int hmc7044_setup(struct iio_dev *indio_dev) hmc->pll2_freq = hmc->clkin_freq_ccf[1] ? hmc->clkin_freq_ccf[1] : hmc->clkin_freq[1]; - if (hmc->pll2_freq < 1000000000U) - hmc7044_write(indio_dev, HMC7044_CLK_INPUT_CTRL, + if (hmc->pll2_freq < 1000000000U) { + ret = hmc7044_write(indio_dev, HMC7044_CLK_INPUT_CTRL, HMC7044_LOW_FREQ_INPUT_MODE); + if (ret) + return ret; + } - hmc7044_write(indio_dev, HMC7044_REG_EN_CTRL_0, + ret = hmc7044_write(indio_dev, HMC7044_REG_EN_CTRL_0, (hmc->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) | HMC7044_VCO_SEL(0) | HMC7044_SYSREF_TIMER_EN); + if (ret) + return ret; - hmc7044_write(indio_dev, HMC7044_REG_SYNC, HMC7044_SYNC_RETIME); + ret = hmc7044_write(indio_dev, HMC7044_REG_SYNC, HMC7044_SYNC_RETIME); + if (ret) + return ret; } else { - hmc7044_write(indio_dev, HMC7044_REG_EN_CTRL_0, + ret = hmc7044_write(indio_dev, HMC7044_REG_EN_CTRL_0, (hmc->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) | HMC7044_VCO_SEL(high_vco_en ? HMC7044_VCO_HIGH : HMC7044_VCO_LOW) | HMC7044_SYSREF_TIMER_EN | HMC7044_PLL2_EN | HMC7044_PLL1_EN); + if (ret) + return ret; } - if (hmc->pll2_cap_bank_sel != ~0) - hmc7044_write(indio_dev, HMC7044_REG_FORCE_CAPVAL, + if (hmc->pll2_cap_bank_sel != ~0) { + ret = hmc7044_write(indio_dev, HMC7044_REG_FORCE_CAPVAL, HMC7044_FORCE_CAP_VALUE(hmc->pll2_cap_bank_sel) | HMC7044_FORCE_CAPS_FROM_SPI_EN); + if (ret) + return ret; + } /* Program the dividers */ - hmc7044_write(indio_dev, HMC7044_REG_PLL2_R_LSB, + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL2_R_LSB, HMC7044_R2_LSB(r2[0])); - hmc7044_write(indio_dev, HMC7044_REG_PLL2_R_MSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL2_R_MSB, HMC7044_R2_MSB(r2[0])); - hmc7044_write(indio_dev, HMC7044_REG_PLL2_N_LSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL2_N_LSB, HMC7044_N2_LSB(n2[0])); - hmc7044_write(indio_dev, HMC7044_REG_PLL2_N_MSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL2_N_MSB, HMC7044_N2_MSB(n2[0])); + if (ret) + return ret; /* Program the reference doubler */ - hmc7044_write(indio_dev, HMC7044_REG_PLL2_FREQ_DOUBLER, + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL2_FREQ_DOUBLER, pll2_freq_doubler_en ? 0 : HMC7044_PLL2_FREQ_DOUBLER_DIS); - + if (ret) + return ret; /* Program PLL1 */ - hmc7044_write(indio_dev, HMC7044_REG_PLL1_CP_CTRL, + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_CP_CTRL, HMC7044_PLL1_CP_CURRENT(hmc->pll1_cp_current / HMC7044_CP_CURRENT_STEP - 1)); - + if (ret) + return ret; /* Set the lock detect timer threshold */ - hmc7044_write(indio_dev, HMC7044_REG_PLL1_LOCK_DETECT, + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_LOCK_DETECT, HMC7044_LOCK_DETECT_TIMER(pll1_lock_detect)); /* Set the LCM */ for (i = 0; i < ARRAY_SIZE(clkin_freq); i++) { - hmc7044_write(indio_dev, HMC7044_REG_CLKIN_PRESCALER(i), + ret = hmc7044_write(indio_dev, HMC7044_REG_CLKIN_PRESCALER(i), in_prescaler[i]); + if (ret) + return ret; } - hmc7044_write(indio_dev, HMC7044_REG_OSCIN_PRESCALER, + ret = hmc7044_write(indio_dev, HMC7044_REG_OSCIN_PRESCALER, in_prescaler[4]); - + if (ret) + return ret; /* Program the dividers */ - hmc7044_write(indio_dev, HMC7044_REG_PLL1_R_LSB, + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_R_LSB, HMC7044_R2_LSB(r1)); - hmc7044_write(indio_dev, HMC7044_REG_PLL1_R_MSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_R_MSB, HMC7044_R2_MSB(r1)); - hmc7044_write(indio_dev, HMC7044_REG_PLL1_N_LSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_N_LSB, HMC7044_N2_LSB(n1)); - hmc7044_write(indio_dev, HMC7044_REG_PLL1_N_MSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_N_MSB, HMC7044_N2_MSB(n1)); - - hmc7044_write(indio_dev, HMC7044_REG_PLL1_REF_PRIO_CTRL, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_REF_PRIO_CTRL, hmc->pll1_ref_prio_ctrl); - - hmc7044_write(indio_dev, HMC7044_REG_PLL1_REF_SWITCH, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_PLL1_REF_SWITCH, HMC7044_HOLDOVER_DAC | (hmc->pll1_ref_autorevert_en ? HMC7044_AUTO_REVERT_SWITCH : 0) | HMC7044_AUTO_MODE_SWITCH); - + if (ret) + return ret; /* Program the SYSREF timer */ /* Set the divide ratio */ - hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_LSB, + ret = hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_LSB, HMC7044_SYSREF_TIMER_LSB(hmc->sysref_timer_div)); - hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_MSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_MSB, HMC7044_SYSREF_TIMER_MSB(hmc->sysref_timer_div)); - + if (ret) + return ret; /* Set the pulse generator mode configuration */ - hmc7044_write(indio_dev, HMC7044_REG_PULSE_GEN, + ret = hmc7044_write(indio_dev, HMC7044_REG_PULSE_GEN, HMC7044_PULSE_GEN_MODE(hmc->pulse_gen_mode)); - + if (ret) + return ret; /* Enable the input buffers */ - hmc7044_write(indio_dev, HMC7044_REG_CLKIN0_BUF_CTRL, + ret = hmc7044_write(indio_dev, HMC7044_REG_CLKIN0_BUF_CTRL, hmc->in_buf_mode[0]); - hmc7044_write(indio_dev, HMC7044_REG_CLKIN1_BUF_CTRL, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CLKIN1_BUF_CTRL, hmc->in_buf_mode[1]); - hmc7044_write(indio_dev, HMC7044_REG_CLKIN2_BUF_CTRL, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CLKIN2_BUF_CTRL, hmc->in_buf_mode[2]); - hmc7044_write(indio_dev, HMC7044_REG_CLKIN3_BUF_CTRL, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CLKIN3_BUF_CTRL, hmc->in_buf_mode[3]); - hmc7044_write(indio_dev, HMC7044_REG_OSCIN_BUF_CTRL, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_OSCIN_BUF_CTRL, hmc->in_buf_mode[4]); - + if (ret) + return ret; /* Set GPIOs */ for (i = 0; i < ARRAY_SIZE(hmc->gpi_ctrl); i++) { - hmc7044_write(indio_dev, HMC7044_REG_GPI_CTRL(i), + ret = hmc7044_write(indio_dev, HMC7044_REG_GPI_CTRL(i), hmc->gpi_ctrl[i]); + if (ret) + return ret; } for (i = 0; i < ARRAY_SIZE(hmc->gpo_ctrl); i++) { - hmc7044_write(indio_dev, HMC7044_REG_GPO_CTRL(i), + ret = hmc7044_write(indio_dev, HMC7044_REG_GPO_CTRL(i), hmc->gpo_ctrl[i]); + if (ret) + return ret; } mdelay(10); @@ -1148,33 +1216,44 @@ static int hmc7044_setup(struct iio_dev *indio_dev) if (chan->num >= HMC7044_NUM_CHAN || chan->disable) continue; - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num), + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num), HMC7044_DIV_LSB(chan->divider)); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num), HMC7044_DIV_MSB(chan->divider)); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num), HMC7044_DRIVER_MODE(chan->driver_mode) | HMC7044_DRIVER_Z_MODE(chan->driver_impedance) | (chan->dynamic_driver_enable ? HMC7044_DYN_DRIVER_EN : 0) | (chan->force_mute_enable ? HMC7044_FORCE_MUTE_EN : 0)); - - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num), chan->fine_delay & 0x1F); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num), chan->coarse_delay & 0x1F); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num), chan->out_mux_mode & 0x3); - - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num), (chan->start_up_mode_dynamic_enable ? HMC7044_START_UP_MODE_DYN_EN : 0) | (chan->output_control0_rb4_enable ? BIT(4) : 0) | (chan->high_performance_mode_dis ? 0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN | HMC7044_CH_EN); - + if (ret) + return ret; hmc->iio_channels[i].type = IIO_ALTVOLTAGE; hmc->iio_channels[i].output = 1; hmc->iio_channels[i].indexed = 1; @@ -1188,14 +1267,21 @@ static int hmc7044_setup(struct iio_dev *indio_dev) mdelay(10); /* Do a restart to reset the system and initiate calibration */ - hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, HMC7044_RESTART_DIV_FSM, 10000); - hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + if (ret) + return ret; + + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, HMC7044_RESEED_REQ, 1000); + if (ret) + return ret; - hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, + ret = hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, (hmc->high_performance_mode_clock_dist_en ? HMC7044_HIGH_PERF_DISTRIB_PATH : 0)); + if (ret) + return ret; if (!hmc->clkin1_vcoin_en) { u32 pll1_stat; @@ -1251,51 +1337,79 @@ static int hmc7043_setup(struct iio_dev *indio_dev) } /* Resets all registers to default values */ - hmc7044_toggle_bit(indio_dev, HMC7044_REG_SOFT_RESET, + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_SOFT_RESET, HMC7044_SOFT_RESET, 100); + if (ret) + return ret; hmc7044_read_write_check(indio_dev); /* Load the configuration updates (provided by Analog Devices) */ - hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d); - hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf); + ret = hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_LOW_PW, 0x4d); + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CLK_OUT_DRV_HIGH_PW, 0xdf); + if (ret) + return ret; /* Disable all channels */ - for (i = 0; i < HMC7044_NUM_CHAN; i++) - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0); + for (i = 0; i < HMC7044_NUM_CHAN; i++) { + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(i), 0); + if (ret) + return ret; + } - if (hmc->pll2_freq < 1000000000U) - hmc7044_write(indio_dev, HMC7044_CLK_INPUT_CTRL, + if (hmc->pll2_freq < 1000000000U) { + ret = hmc7044_write(indio_dev, HMC7044_CLK_INPUT_CTRL, HMC7044_LOW_FREQ_INPUT_MODE); + if (ret) + return ret; + } - hmc7044_write(indio_dev, HMC7044_REG_EN_CTRL_0, + ret = hmc7044_write(indio_dev, HMC7044_REG_EN_CTRL_0, (hmc->rf_reseeder_en ? HMC7044_RF_RESEEDER_EN : 0) | HMC7044_SYSREF_TIMER_EN); + if (ret) + return ret; /* Program the SYSREF timer */ /* Set the divide ratio */ - hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_LSB, + ret = hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_LSB, HMC7044_SYSREF_TIMER_LSB(hmc->sysref_timer_div)); - hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_MSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_MSB, HMC7044_SYSREF_TIMER_MSB(hmc->sysref_timer_div)); + if (ret) + return ret; /* Set the pulse generator mode configuration */ - hmc7044_write(indio_dev, HMC7044_REG_PULSE_GEN, + ret = hmc7044_write(indio_dev, HMC7044_REG_PULSE_GEN, HMC7044_PULSE_GEN_MODE(hmc->pulse_gen_mode)); + if (ret) + return ret; /* Enable the input buffers */ - hmc7044_write(indio_dev, HMC7044_REG_CLKIN0_BUF_CTRL, + ret = hmc7044_write(indio_dev, HMC7044_REG_CLKIN0_BUF_CTRL, hmc->in_buf_mode[0]); - hmc7044_write(indio_dev, HMC7044_REG_CLKIN1_BUF_CTRL, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CLKIN1_BUF_CTRL, hmc->in_buf_mode[1]); + if (ret) + return ret; /* Set GPIOs */ - hmc7044_write(indio_dev, HMC7044_REG_GPI_CTRL(0), + ret = hmc7044_write(indio_dev, HMC7044_REG_GPI_CTRL(0), hmc->gpi_ctrl[0]); + if (ret) + return ret; - hmc7044_write(indio_dev, HMC7044_REG_GPO_CTRL(0), + ret = hmc7044_write(indio_dev, HMC7044_REG_GPO_CTRL(0), hmc->gpo_ctrl[0]); + if (ret) + return ret; /* Program the output channels */ for (i = 0; i < hmc->num_channels; i++) { @@ -1304,32 +1418,45 @@ static int hmc7043_setup(struct iio_dev *indio_dev) if (chan->num >= HMC7044_NUM_CHAN || chan->disable) continue; - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num), + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_1(chan->num), HMC7044_DIV_LSB(chan->divider)); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_2(chan->num), HMC7044_DIV_MSB(chan->divider)); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_8(chan->num), HMC7044_DRIVER_MODE(chan->driver_mode) | HMC7044_DRIVER_Z_MODE(chan->driver_impedance) | (chan->dynamic_driver_enable ? HMC7044_DYN_DRIVER_EN : 0) | (chan->force_mute_enable ? HMC7044_FORCE_MUTE_EN : 0)); - - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_3(chan->num), chan->fine_delay & 0x1F); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_4(chan->num), chan->coarse_delay & 0x1F); - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num), + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_7(chan->num), chan->out_mux_mode & 0x3); + if (ret) + return ret; - hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num), + ret = hmc7044_write(indio_dev, HMC7044_REG_CH_OUT_CRTL_0(chan->num), (chan->start_up_mode_dynamic_enable ? HMC7044_START_UP_MODE_DYN_EN : 0) | (chan->output_control0_rb4_enable ? BIT(4) : 0) | (chan->high_performance_mode_dis ? 0 : HMC7044_HI_PERF_MODE) | HMC7044_SYNC_EN | HMC7044_CH_EN); + if (ret) + return ret; hmc->iio_channels[i].type = IIO_ALTVOLTAGE; hmc->iio_channels[i].output = 1; @@ -1344,14 +1471,21 @@ static int hmc7043_setup(struct iio_dev *indio_dev) mdelay(10); /* Do a restart to reset the system and initiate calibration */ - hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, HMC7044_RESTART_DIV_FSM, 1000); - hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + if (ret) + return ret; + + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, HMC7044_RESEED_REQ, 1000); + if (ret) + return ret; - hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, + ret = hmc7044_write(indio_dev, HMC7044_REG_REQ_MODE_0, (hmc->high_performance_mode_clock_dist_en ? HMC7044_HIGH_PERF_DISTRIB_PATH : 0)); + if (ret) + return ret; for (i = 0; i < hmc->num_channels; i++) { chan = &hmc->channels[i]; @@ -1806,6 +1940,7 @@ static int hmc7044_jesd204_clks_sync1(struct jesd204_dev *jdev, struct device *dev = jesd204_dev_to_device(jdev); struct iio_dev *indio_dev = dev_get_drvdata(dev); struct hmc7044 *hmc = iio_priv(indio_dev); + int ret; if (!hmc->hmc_two_level_tree_sync_en) return JESD204_STATE_CHANGE_DONE; @@ -1816,21 +1951,33 @@ static int hmc7044_jesd204_clks_sync1(struct jesd204_dev *jdev, dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); if (hmc->is_sysref_provider) { - if (hmc->device_id == HMC7044) - hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_DISABLED); + if (hmc->device_id == HMC7044) { + ret = hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_DISABLED); + if (ret) + return ret; + } } else { - if (hmc->device_id == HMC7044 && !hmc->clkin0_rfsync_en && !hmc->clkin1_vcoin_en) - hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_SYNC); - else - hmc7044_continuous_chan_sync_enable(indio_dev, 1); + if (hmc->device_id == HMC7044 && !hmc->clkin0_rfsync_en && !hmc->clkin1_vcoin_en) { + ret = hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_SYNC); + if (ret) + return ret; + } else { + ret = hmc7044_continuous_chan_sync_enable(indio_dev, 1); + if (ret) + return ret; + } } - hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, HMC7044_RESTART_DIV_FSM, (hmc->device_id == HMC7044 && !hmc->clkin1_vcoin_en) ? 10000 : 1000); + if (ret) + return ret; - hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, + ret = hmc7044_toggle_bit(indio_dev, HMC7044_REG_REQ_MODE_0, HMC7044_RESEED_REQ, 1000); + if (ret) + return ret; return JESD204_STATE_CHANGE_DONE; } @@ -1868,6 +2015,7 @@ static int hmc7044_jesd204_clks_sync3(struct jesd204_dev *jdev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct hmc7044 *hmc = iio_priv(indio_dev); unsigned val; + int ret; if (!hmc->hmc_two_level_tree_sync_en) return JESD204_STATE_CHANGE_DONE; @@ -1893,11 +2041,15 @@ static int hmc7044_jesd204_clks_sync3(struct jesd204_dev *jdev, __func__, val & 0xFF); } - if (hmc->device_id == HMC7044 && !hmc->clkin0_rfsync_en && !hmc->clkin1_vcoin_en) - hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_PULSE_GEN_REQ); - else - hmc7044_continuous_chan_sync_enable(indio_dev, 0); - + if (hmc->device_id == HMC7044 && !hmc->clkin0_rfsync_en && !hmc->clkin1_vcoin_en) { + ret = hmc7044_sync_pin_set(indio_dev, HMC7044_SYNC_PIN_PULSE_GEN_REQ); + if (ret) + return ret; + } else { + ret = hmc7044_continuous_chan_sync_enable(indio_dev, 0); + if (ret) + return ret; + } return JESD204_STATE_CHANGE_DONE; } @@ -1961,10 +2113,14 @@ static int hmc7044_jesd204_link_pre_setup(struct jesd204_dev *jdev, sysref_timer = hmc->pll2_freq / sysref_timer; /* Set the divide ratio */ - hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_LSB, + ret = hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_LSB, HMC7044_SYSREF_TIMER_LSB(sysref_timer)); - hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_MSB, + if (ret) + return ret; + ret = hmc7044_write(indio_dev, HMC7044_REG_SYSREF_TIMER_MSB, HMC7044_SYSREF_TIMER_MSB(sysref_timer)); + if (ret) + return ret; if (lnk->sysref.mode == JESD204_SYSREF_CONTINUOUS) { /* Set the pulse generator mode configuration */ @@ -1972,11 +2128,12 @@ static int hmc7044_jesd204_link_pre_setup(struct jesd204_dev *jdev, dev_warn(dev, "%s: Link%u forcing continuous SYSREF mode\n", __func__, lnk->link_id); - hmc7044_write(indio_dev, HMC7044_REG_PULSE_GEN, + ret = hmc7044_write(indio_dev, HMC7044_REG_PULSE_GEN, HMC7044_PULSE_GEN_MODE(HMC7044_PULSE_GEN_CONT_PULSE)); + if (ret) + return ret; } - return JESD204_STATE_CHANGE_DONE; } From 313f0ae49789a2406263e084566b62b1c8ae5d2b Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Fri, 11 Dec 2020 12:21:32 +0200 Subject: [PATCH 09/15] iio: adc: adrv9009: move debug prints before reason check For debugging issues with the JESD204 FSM, it's useful to see these callbacks being called, even if they don't do anything during uninit. Mostly to see that the FSM behaves correctly. Signed-off-by: Alexandru Ardelean --- drivers/iio/adc/adrv9009.c | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/iio/adc/adrv9009.c b/drivers/iio/adc/adrv9009.c index 503623050d1287..17effc75fb2c63 100644 --- a/drivers/iio/adc/adrv9009.c +++ b/drivers/iio/adc/adrv9009.c @@ -5401,6 +5401,8 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, struct adrv9009_jesd204_priv *priv = jesd204_dev_priv(jdev); + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + switch (reason) { case JESD204_STATE_OP_REASON_INIT: break; @@ -5408,8 +5410,6 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, return JESD204_STATE_CHANGE_DONE; } - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); - priv->phy = phy; switch (lnk->link_id) { @@ -5496,11 +5496,11 @@ static int adrv9009_jesd204_clks_enable(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); - if (!lnk->num_converters) return JESD204_STATE_CHANGE_DONE; @@ -5548,11 +5548,11 @@ static int adrv9009_jesd204_link_enable(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); - if (!lnk->num_converters) return JESD204_STATE_CHANGE_DONE; @@ -5668,11 +5668,11 @@ int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, int ret = TALACT_NO_ACTION; long dev_clk; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - /**********************************************************/ /**********************************************************/ /************ Talise Initialization Sequence *************/ @@ -5764,11 +5764,11 @@ static int adrv9009_jesd204_setup_stage1(struct jesd204_dev *jdev, int ret; u8 mcsStatus; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - ret = TALISE_enableMultichipSync(phy->talDevice, 0, &mcsStatus); if (ret != TALACT_NO_ACTION) return -EFAULT; @@ -5792,11 +5792,11 @@ static int adrv9009_jesd204_setup_stage2(struct jesd204_dev *jdev, u8 pllLockStatus_mask, pllLockStatus = 0; int ret; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - /*******************/ /**** Verify MCS ***/ /*******************/ @@ -5898,11 +5898,11 @@ static int adrv9009_jesd204_setup_stage3(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - ret = TALISE_enableMultichipRfLOPhaseSync(phy->talDevice, 0); if (ret != TALACT_NO_ACTION) { @@ -5922,11 +5922,11 @@ static int adrv9009_jesd204_setup_stage4(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - /* Parallelization stage ... */ /****************************************************/ @@ -5955,11 +5955,11 @@ static int adrv9009_jesd204_setup_stage5(struct jesd204_dev *jdev, int ret; u8 errorFlag; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - ret = TALISE_waitInitCals(phy->talDevice, 20000, &errorFlag); if (ret == TALACT_ERR_RERUN_INIT_CALS) { @@ -6011,13 +6011,13 @@ static int adrv9009_jesd204_post_running_stage(struct jesd204_dev *jdev, u32 trackingCalMask = phy->tracking_cal_mask = TAL_TRACK_NONE; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) { phy->is_initialized = 0; return JESD204_STATE_CHANGE_DONE; } - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - /*********************************************** * Allow Rx1/2 QEC tracking and Tx1/2 QEC * * tracking to run when in the radioOn state * From 76206b0c4d378835fc51303c743c5272e076c86b Mon Sep 17 00:00:00 2001 From: Alexandru Ardelean Date: Thu, 17 Dec 2020 14:28:35 +0200 Subject: [PATCH 10/15] iio: adc: adrv9009: move debug prints before reason checks For some functions, this was omitted. Signed-off-by: Alexandru Ardelean --- drivers/iio/adc/adrv9009.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/adrv9009.c b/drivers/iio/adc/adrv9009.c index 17effc75fb2c63..f27d9511ca978f 100644 --- a/drivers/iio/adc/adrv9009.c +++ b/drivers/iio/adc/adrv9009.c @@ -5606,11 +5606,11 @@ static int adrv9009_jesd204_link_running(struct jesd204_dev *jdev, uint16_t deframerStatus = 0; uint8_t framerStatus = 0; + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); - if (!lnk->num_converters) return JESD204_STATE_CHANGE_DONE; @@ -5647,11 +5647,11 @@ int adrv9009_jesd204_uninit(struct jesd204_dev *jdev, struct adrv9009_jesd204_priv *priv = jesd204_dev_priv(jdev); struct adrv9009_rf_phy *phy = priv->phy; + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + if (reason != JESD204_STATE_OP_REASON_UNINIT) return JESD204_STATE_CHANGE_DONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - adrv9009_shutdown(phy); return JESD204_STATE_CHANGE_DONE; From 5e35275875336fa14fff0031597d7ba07189c68a Mon Sep 17 00:00:00 2001 From: Laszlo Nagy Date: Wed, 13 Jan 2021 15:18:15 +0000 Subject: [PATCH 11/15] iio/adc/adrv9009: Fix octets per frame calculation for NP=12 case Signed-off-by: Laszlo Nagy --- drivers/iio/adc/adrv9009.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/adrv9009.c b/drivers/iio/adc/adrv9009.c index f27d9511ca978f..4f34bb5760112b 100644 --- a/drivers/iio/adc/adrv9009.c +++ b/drivers/iio/adc/adrv9009.c @@ -5471,7 +5471,7 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, } else if (deframer) { lnk->num_converters = deframer->M; lnk->num_lanes = hweight8(deframer->deserializerLanesEnabled); - lnk->octets_per_frame = (2 * lnk->num_converters) / lnk->num_lanes; + lnk->octets_per_frame = (deframer->Np * lnk->num_converters) / (8 * lnk->num_lanes); lnk->frames_per_multiframe = deframer->K; lnk->device_id = deframer->deviceId; lnk->bank_id = deframer->bankId; From b0890c604683f135fd09a1c546b56bdb604e8657 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 19 Apr 2021 09:43:42 +0200 Subject: [PATCH 12/15] iio: adc: adrv9009: Fix mutex unlock issue upon return This fixes some unlocked mutex issues in the return path. Signed-off-by: Michael Hennerich --- drivers/iio/adc/adrv9009.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/iio/adc/adrv9009.c b/drivers/iio/adc/adrv9009.c index 4f34bb5760112b..a3f8e7e9548535 100644 --- a/drivers/iio/adc/adrv9009.c +++ b/drivers/iio/adc/adrv9009.c @@ -1613,12 +1613,15 @@ static ssize_t adrv9009_phy_show(struct device *dev, } num_links = jesd204_get_active_links_num(jdev); - if (num_links < 0) - return num_links; + if (num_links < 0) { + ret = num_links; + break; + } ret = jesd204_get_links_data(jdev, links, num_links); if (ret) - return ret; + break; + err = 0; for (i = 0; i < num_links; i++) { if (links[i]->error) { @@ -1635,12 +1638,14 @@ static ssize_t adrv9009_phy_show(struct device *dev, } num_links = jesd204_get_active_links_num(jdev); - if (num_links < 0) - return num_links; + if (num_links < 0) { + ret = num_links; + break; + } ret = jesd204_get_links_data(jdev, links, num_links); if (ret) - return ret; + break; /* * Take the slowest link; if there are N links and one is paused, all are paused. * Not sure if this can happen yet, but best design it like this here. @@ -1661,12 +1666,14 @@ static ssize_t adrv9009_phy_show(struct device *dev, } num_links = jesd204_get_active_links_num(jdev); - if (num_links < 0) - return num_links; + if (num_links < 0) { + ret = num_links; + break; + } ret = jesd204_get_links_data(jdev, links, num_links); if (ret) - return ret; + break; /* * just get the first link state; we're assuming that all 3 are in sync * and that ADRV9009_JESD204_FSM_PAUSED was called before From 759c266c0a5f83f9e98bd3591f0e8599cddabb33 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 12 Jul 2021 14:34:59 +0200 Subject: [PATCH 13/15] iio: adc: adrv9009: Move jesd204-fsm priv init from cb to probe This should be done in probe(). Signed-off-by: Michael Hennerich --- drivers/iio/adc/adrv9009.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/iio/adc/adrv9009.c b/drivers/iio/adc/adrv9009.c index a3f8e7e9548535..ff3fa1bc9556dc 100644 --- a/drivers/iio/adc/adrv9009.c +++ b/drivers/iio/adc/adrv9009.c @@ -5400,14 +5400,12 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, struct jesd204_link *lnk) { struct device *dev = jesd204_dev_to_device(jdev); - struct spi_device *spi = to_spi_device(dev); - struct adrv9009_rf_phy *phy = adrv9009_spi_to_phy(spi); + struct adrv9009_jesd204_priv *priv = jesd204_dev_priv(jdev); + struct adrv9009_rf_phy *phy = priv->phy; taliseJesd204bFramerConfig_t *framer = NULL; taliseJesd204bDeframerConfig_t *deframer = NULL; bool orx_adc_stitching_enabled; - struct adrv9009_jesd204_priv *priv = jesd204_dev_priv(jdev); - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); switch (reason) { @@ -5417,8 +5415,6 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, return JESD204_STATE_CHANGE_DONE; } - priv->phy = phy; - switch (lnk->link_id) { case DEFRAMER_LINK_TX: deframer = &phy->talInit.jesd204Settings.deframerA; @@ -6381,6 +6377,10 @@ static int adrv9009_probe(struct spi_device *spi) } } else { + struct adrv9009_jesd204_priv *priv; + + priv = jesd204_dev_priv(jdev); + priv->phy = phy; phy->dev_clk = clk; } From 8a0e6bc5044eb028061a8d0893aad119e4c87cc4 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 12 Jul 2021 14:41:43 +0200 Subject: [PATCH 14/15] iio: adc: adrv9009: Introduce jesd204-fsm link_pre_setup cb() Make sure the device_clk is set prior to the clk_sync states. This will ensure that all clocks are synced. Remove unused device_init cb(). Signed-off-by: Michael Hennerich --- drivers/iio/adc/adrv9009.c | 93 +++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/drivers/iio/adc/adrv9009.c b/drivers/iio/adc/adrv9009.c index ff3fa1bc9556dc..2e5007697a6e92 100644 --- a/drivers/iio/adc/adrv9009.c +++ b/drivers/iio/adc/adrv9009.c @@ -5395,6 +5395,44 @@ struct adrv9009_jesd204_priv { struct adrv9009_jesd204_link link[3]; }; +int adrv9009_jesd204_link_pre_setup(struct jesd204_dev *jdev, + enum jesd204_state_op_reason reason) +{ + struct device *dev = jesd204_dev_to_device(jdev); + struct adrv9009_jesd204_priv *priv = jesd204_dev_priv(jdev); + struct adrv9009_rf_phy *phy = priv->phy; + long dev_clk; + + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); + + if (reason == JESD204_STATE_OP_REASON_UNINIT) { + TALISE_shutdown(phy->talDevice); + TALISE_closeHw(phy->talDevice); + phy->is_initialized = 0; + + memset(&phy->talise_device.devStateInfo, 0, + sizeof(phy->talise_device.devStateInfo)); + + return JESD204_STATE_CHANGE_DONE; + } + + dev_clk = clk_round_rate(phy->dev_clk, + phy->talInit.clocks.deviceClock_kHz * 1000); + + if (dev_clk > 0 && ((dev_clk / 1000) == + phy->talInit.clocks.deviceClock_kHz)) { + clk_set_rate(phy->dev_clk, (unsigned long) dev_clk); + } else { + dev_err(&phy->spi->dev, + "Requesting device clock %u failed got %ld", + phy->talInit.clocks.deviceClock_kHz * 1000, dev_clk); + return -EINVAL; + } + + return JESD204_STATE_CHANGE_DONE; +} + static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, enum jesd204_state_op_reason reason, struct jesd204_link *lnk) @@ -5643,23 +5681,6 @@ static int adrv9009_jesd204_link_running(struct jesd204_dev *jdev, return JESD204_STATE_CHANGE_DONE; } -int adrv9009_jesd204_uninit(struct jesd204_dev *jdev, - enum jesd204_state_op_reason reason) -{ - struct device *dev = jesd204_dev_to_device(jdev); - struct adrv9009_jesd204_priv *priv = jesd204_dev_priv(jdev); - struct adrv9009_rf_phy *phy = priv->phy; - - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); - - if (reason != JESD204_STATE_OP_REASON_UNINIT) - return JESD204_STATE_CHANGE_DONE; - - adrv9009_shutdown(phy); - - return JESD204_STATE_CHANGE_DONE; -} - int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, enum jesd204_state_op_reason reason) { @@ -5669,35 +5690,12 @@ int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, uint8_t mcsStatus = 0; u8 pllLockStatus = 0; int ret = TALACT_NO_ACTION; - long dev_clk; dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; - /**********************************************************/ - /**********************************************************/ - /************ Talise Initialization Sequence *************/ - /**********************************************************/ - /**********************************************************/ - - /** < Insert User System Clock(s) Initialization Code Here > - * System Clock should provide a device clock and SYSREF signal - * to the Talise device. - **/ - - dev_clk = clk_round_rate(phy->dev_clk, - phy->talInit.clocks.deviceClock_kHz * 1000); - - if (dev_clk > 0 && ((dev_clk / 1000) == phy->talInit.clocks.deviceClock_kHz)) { - clk_set_rate(phy->dev_clk, (unsigned long) dev_clk); - } else { - dev_err(&phy->spi->dev, "Requesting device clock %u failed got %ld", - phy->talInit.clocks.deviceClock_kHz * 1000, dev_clk); - return -EINVAL; - } - /*** < Insert User BBIC JESD204B Initialization Code Here > ***/ /*******************************/ @@ -6110,8 +6108,9 @@ static int adrv9009_jesd204_post_running_stage(struct jesd204_dev *jdev, static const struct jesd204_dev_data jesd204_adrv9009_init = { .state_ops = { - [JESD204_OP_DEVICE_INIT] = { - .per_device = adrv9009_jesd204_uninit, + [JESD204_OP_LINK_PRE_SETUP] = { + .per_device = adrv9009_jesd204_link_pre_setup, + .mode = JESD204_STATE_OP_MODE_PER_DEVICE, }, [JESD204_OP_LINK_INIT] = { .per_link = adrv9009_jesd204_link_init, @@ -6166,8 +6165,9 @@ static const struct jesd204_dev_data jesd204_adrv9009_init = { static const struct jesd204_dev_data jesd204_adrv90081_init = { .state_ops = { - [JESD204_OP_DEVICE_INIT] = { - .per_device = adrv9009_jesd204_uninit, + [JESD204_OP_LINK_PRE_SETUP] = { + .per_device = adrv9009_jesd204_link_pre_setup, + .mode = JESD204_STATE_OP_MODE_PER_DEVICE, }, [JESD204_OP_LINK_INIT] = { .per_link = adrv9009_jesd204_link_init, @@ -6222,8 +6222,9 @@ static const struct jesd204_dev_data jesd204_adrv90081_init = { static const struct jesd204_dev_data jesd204_adrv90082_init = { .state_ops = { - [JESD204_OP_DEVICE_INIT] = { - .per_device = adrv9009_jesd204_uninit, + [JESD204_OP_LINK_PRE_SETUP] = { + .per_device = adrv9009_jesd204_link_pre_setup, + .mode = JESD204_STATE_OP_MODE_PER_DEVICE, }, [JESD204_OP_LINK_INIT] = { .per_link = adrv9009_jesd204_link_init, From 64cb19f46cf9099bdaeb06db0410c8cd57c6643c Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 12 Jul 2021 15:02:32 +0200 Subject: [PATCH 15/15] iio: adc: adrv9009: Coding style fixes - no functional changes This fixes some indention and line limit issues. In addition we remove some commented code. Signed-off-by: Michael Hennerich --- drivers/iio/adc/adrv9009.c | 268 +++++++++++++++++++++++-------------- 1 file changed, 164 insertions(+), 104 deletions(-) diff --git a/drivers/iio/adc/adrv9009.c b/drivers/iio/adc/adrv9009.c index 2e5007697a6e92..936f19345b8aed 100644 --- a/drivers/iio/adc/adrv9009.c +++ b/drivers/iio/adc/adrv9009.c @@ -5444,7 +5444,8 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, taliseJesd204bDeframerConfig_t *deframer = NULL; bool orx_adc_stitching_enabled; - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, + lnk->link_id, jesd204_state_op_reason_str(reason)); switch (reason) { case JESD204_STATE_OP_REASON_INIT: @@ -5507,12 +5508,14 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, lnk->converter_resolution = 16; lnk->ctrl_bits_per_sample = 0; lnk->jesd_version = JESD204_VERSION_B; - lnk->subclass = framer->externalSysref ? JESD204_SUBCLASS_1 : JESD204_SUBCLASS_0; + lnk->subclass = framer->externalSysref ? + JESD204_SUBCLASS_1 : JESD204_SUBCLASS_0; lnk->is_transmit = false; } else if (deframer) { lnk->num_converters = deframer->M; lnk->num_lanes = hweight8(deframer->deserializerLanesEnabled); - lnk->octets_per_frame = (deframer->Np * lnk->num_converters) / (8 * lnk->num_lanes); + lnk->octets_per_frame = (deframer->Np * lnk->num_converters) / + (8 * lnk->num_lanes); lnk->frames_per_multiframe = deframer->K; lnk->device_id = deframer->deviceId; lnk->bank_id = deframer->bankId; @@ -5521,7 +5524,8 @@ static int adrv9009_jesd204_link_init(struct jesd204_dev *jdev, lnk->converter_resolution = 16; lnk->ctrl_bits_per_sample = 0; lnk->jesd_version = JESD204_VERSION_B; - lnk->subclass = deframer->externalSysref ? JESD204_SUBCLASS_1 : JESD204_SUBCLASS_0; + lnk->subclass = deframer->externalSysref ? + JESD204_SUBCLASS_1 : JESD204_SUBCLASS_0; lnk->is_transmit = true; }; @@ -5537,7 +5541,8 @@ static int adrv9009_jesd204_clks_enable(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, + lnk->link_id, jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5546,35 +5551,37 @@ static int adrv9009_jesd204_clks_enable(struct jesd204_dev *jdev, return JESD204_STATE_CHANGE_DONE; if (priv->link[lnk->link_id].is_framer) { - ret = TALISE_enableSysrefToFramer(phy->talDevice, priv->link[lnk->link_id].source_id, 0); - if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); - ret = -EFAULT; - } + ret = TALISE_enableSysrefToFramer(phy->talDevice, + priv->link[lnk->link_id].source_id, 0); + if (ret != TALACT_NO_ACTION) { + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); + ret = -EFAULT; + } - ret = TALISE_enableFramerLink(phy->talDevice, priv->link[lnk->link_id].source_id, 0); - if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); - ret = -EFAULT; - } + ret = TALISE_enableFramerLink(phy->talDevice, + priv->link[lnk->link_id].source_id, 0); + if (ret != TALACT_NO_ACTION) { + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); + ret = -EFAULT; + } } else { - // u8 phy_ctrl; - // phy_ctrl = adrv9009_spi_read(phy->spi, TALISE_ADDR_DES_PHY_GENERAL_CTL_1); - // adrv9009_spi_write(phy->spi, TALISE_ADDR_DES_PHY_GENERAL_CTL_1, phy_ctrl & ~BIT(7)); - // adrv9009_spi_write(phy->spi, TALISE_ADDR_DES_PHY_GENERAL_CTL_1, phy_ctrl); - - ret = TALISE_enableSysrefToDeframer(phy->talDevice, priv->link[lnk->link_id].source_id, 0); - if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); - ret = -EFAULT; - } - - ret = TALISE_enableDeframerLink(phy->talDevice, priv->link[lnk->link_id].source_id, 0); - if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); - ret = -EFAULT; - } + ret = TALISE_enableSysrefToDeframer(phy->talDevice, + priv->link[lnk->link_id].source_id, 0); + if (ret != TALACT_NO_ACTION) { + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); + ret = -EFAULT; + } + ret = TALISE_enableDeframerLink(phy->talDevice, + priv->link[lnk->link_id].source_id, 0); + if (ret != TALACT_NO_ACTION) { + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); + ret = -EFAULT; + } }; return JESD204_STATE_CHANGE_DONE; @@ -5589,7 +5596,8 @@ static int adrv9009_jesd204_link_enable(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, + lnk->link_id, jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5598,37 +5606,40 @@ static int adrv9009_jesd204_link_enable(struct jesd204_dev *jdev, return JESD204_STATE_CHANGE_DONE; if (priv->link[lnk->link_id].is_framer) { - ret = TALISE_enableFramerLink(phy->talDevice, priv->link[lnk->link_id].source_id, 1); + ret = TALISE_enableFramerLink(phy->talDevice, + priv->link[lnk->link_id].source_id, 1); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } /*************************************************/ /**** Enable SYSREF to Talise JESD204B Framer ***/ /*************************************************/ /*** < User: Make sure SYSREF is stopped/disabled > ***/ - ret = TALISE_enableSysrefToFramer(phy->talDevice, priv->link[lnk->link_id].source_id, 1); + ret = TALISE_enableSysrefToFramer(phy->talDevice, + priv->link[lnk->link_id].source_id, 1); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } } else { - // u8 phy_ctrl; - // phy_ctrl = adrv9009_spi_read(phy->spi, TALISE_ADDR_DES_PHY_GENERAL_CTL_1); - // adrv9009_spi_write(phy->spi, TALISE_ADDR_DES_PHY_GENERAL_CTL_1, phy_ctrl & ~BIT(7)); - // adrv9009_spi_write(phy->spi, TALISE_ADDR_DES_PHY_GENERAL_CTL_1, phy_ctrl); - - ret = TALISE_enableDeframerLink(phy->talDevice, priv->link[lnk->link_id].source_id, 1); + ret = TALISE_enableDeframerLink(phy->talDevice, + priv->link[lnk->link_id].source_id, 1); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } /***************************************************/ /**** Enable SYSREF to Talise JESD204B Deframer ***/ /***************************************************/ - ret = TALISE_enableSysrefToDeframer(phy->talDevice, priv->link[lnk->link_id].source_id, 1); + ret = TALISE_enableSysrefToDeframer(phy->talDevice, + priv->link[lnk->link_id].source_id, 1); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } }; @@ -5647,7 +5658,8 @@ static int adrv9009_jesd204_link_running(struct jesd204_dev *jdev, uint16_t deframerStatus = 0; uint8_t framerStatus = 0; - dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, lnk->link_id, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d link_num %u reason %s\n", __func__, __LINE__, + lnk->link_id, jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5656,26 +5668,31 @@ static int adrv9009_jesd204_link_running(struct jesd204_dev *jdev, return JESD204_STATE_CHANGE_DONE; if (priv->link[lnk->link_id].is_framer) { - ret = TALISE_readFramerStatus(phy->talDevice, priv->link[lnk->link_id].source_id, &framerStatus); + ret = TALISE_readFramerStatus(phy->talDevice, + priv->link[lnk->link_id].source_id, &framerStatus); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); ret = -EFAULT; } if ((framerStatus & 0x07) != 0x05) - dev_warn(&phy->spi->dev, "Link%u TAL_FRAMER_A framerStatus 0x%X", lnk->link_id, framerStatus); - - //jesd204_sysref_async(phy->jdev, 0, NULL); + dev_warn(&phy->spi->dev, + "Link%u TAL_FRAMER_A framerStatus 0x%X", + lnk->link_id, framerStatus); } else { - ret = TALISE_readDeframerStatus(phy->talDevice, priv->link[lnk->link_id].source_id, - &deframerStatus); + ret = TALISE_readDeframerStatus(phy->talDevice, + priv->link[lnk->link_id].source_id, &deframerStatus); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); ret = -EFAULT; } if ((deframerStatus & 0xF7) != 0x86) - dev_warn(&phy->spi->dev, "Link%u TAL_DEFRAMER_A deframerStatus 0x%X", lnk->link_id, deframerStatus); + dev_warn(&phy->spi->dev, + "Link%u TAL_DEFRAMER_A deframerStatus 0x%X", + lnk->link_id, deframerStatus); }; return JESD204_STATE_CHANGE_DONE; @@ -5691,7 +5708,8 @@ int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, u8 pllLockStatus = 0; int ret = TALACT_NO_ACTION; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5705,13 +5723,15 @@ int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, /*Open Talise Hw Device*/ ret = TALISE_openHw(phy->talDevice); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } /* Toggle RESETB pin on Talise device */ ret = TALISE_resetDevice(phy->talDevice); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5723,7 +5743,8 @@ int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, */ ret = TALISE_initialize(phy->talDevice, &phy->talInit); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5733,7 +5754,8 @@ int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, ret = TALISE_getPllsLockStatus(phy->talDevice, &pllLockStatus); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5749,7 +5771,8 @@ int adrv9009_jesd204_link_setup(struct jesd204_dev *jdev, /*******************************************************/ ret = TALISE_enableMultichipSync(phy->talDevice, 1, &mcsStatus); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5765,7 +5788,8 @@ static int adrv9009_jesd204_setup_stage1(struct jesd204_dev *jdev, int ret; u8 mcsStatus; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5775,7 +5799,8 @@ static int adrv9009_jesd204_setup_stage1(struct jesd204_dev *jdev, return -EFAULT; if ((mcsStatus & 0x08) != 0x08) { - dev_err(&phy->spi->dev, "%s:%d Unexpected MCS sync status (0x%X)", + dev_err(&phy->spi->dev, + "%s:%d Unexpected MCS sync status (0x%X)", __func__, __LINE__, mcsStatus); return -EFAULT; } @@ -5793,7 +5818,8 @@ static int adrv9009_jesd204_setup_stage2(struct jesd204_dev *jdev, u8 pllLockStatus_mask, pllLockStatus = 0; int ret; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5803,7 +5829,8 @@ static int adrv9009_jesd204_setup_stage2(struct jesd204_dev *jdev, /*******************/ ret = TALISE_enableMultichipSync(phy->talDevice, 0, &mcsStatus); if ((mcsStatus & 0x0B) != 0x0B) { - dev_err(&phy->spi->dev, "%s:%d Unexpected MCS sync status (0x%X)", + dev_err(&phy->spi->dev, + "%s:%d Unexpected MCS sync status (0x%X)", __func__, __LINE__, mcsStatus); return -EFAULT; } @@ -5815,20 +5842,24 @@ static int adrv9009_jesd204_setup_stage2(struct jesd204_dev *jdev, ret = TALISE_initArm(phy->talDevice, &phy->talInit); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } - ret = TALISE_loadStreamFromBinary(phy->talDevice, (u8 *) phy->stream->data); + ret = TALISE_loadStreamFromBinary(phy->talDevice, + (u8 *) phy->stream->data); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } ret = TALISE_loadArmFromBinary(phy->talDevice, (u8 *) phy->fw->data, phy->fw->size); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5837,13 +5868,15 @@ static int adrv9009_jesd204_setup_stage2(struct jesd204_dev *jdev, */ ret = TALISE_verifyArmChecksum(phy->talDevice); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } ret = TALISE_setArmGpioPins(phy->talDevice, &phy->arm_gpio_config); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5852,17 +5885,20 @@ static int adrv9009_jesd204_setup_stage2(struct jesd204_dev *jdev, /*******************************/ phy->current_loopBandwidth_kHz[0] = 50; - ret = TALISE_setRfPllLoopFilter(phy->talDevice, phy->current_loopBandwidth_kHz[0], - phy->loopFilter_stability); + ret = TALISE_setRfPllLoopFilter(phy->talDevice, + phy->current_loopBandwidth_kHz[0], + phy->loopFilter_stability); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } ret = TALISE_setRfPllFrequency(phy->talDevice, TAL_RF_PLL, phy->trx_lo_frequency); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5884,7 +5920,8 @@ static int adrv9009_jesd204_setup_stage2(struct jesd204_dev *jdev, ret = TALISE_enableMultichipRfLOPhaseSync(phy->talDevice, 1); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5899,7 +5936,8 @@ static int adrv9009_jesd204_setup_stage3(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5907,7 +5945,8 @@ static int adrv9009_jesd204_setup_stage3(struct jesd204_dev *jdev, ret = TALISE_enableMultichipRfLOPhaseSync(phy->talDevice, 0); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5923,7 +5962,8 @@ static int adrv9009_jesd204_setup_stage4(struct jesd204_dev *jdev, struct adrv9009_rf_phy *phy = priv->phy; int ret; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5936,9 +5976,10 @@ static int adrv9009_jesd204_setup_stage4(struct jesd204_dev *jdev, /*** < User: Turn ON the PA (if any), and open any switches on ORx input used to isolate it for calibrations > ***/ /*** < User: Open any switches on the Rx input (if used) to isolate Rx input and provide required VSWR at input > ***/ ret = TALISE_runInitCals(phy->talDevice, - phy->initCalMask & ~TAL_TX_LO_LEAKAGE_EXTERNAL); + phy->initCalMask & ~TAL_TX_LO_LEAKAGE_EXTERNAL); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5956,7 +5997,8 @@ static int adrv9009_jesd204_setup_stage5(struct jesd204_dev *jdev, int ret; u8 errorFlag; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) return JESD204_STATE_CHANGE_DONE; @@ -5966,9 +6008,10 @@ static int adrv9009_jesd204_setup_stage5(struct jesd204_dev *jdev, if (ret == TALACT_ERR_RERUN_INIT_CALS) { /* Try once more */ ret = TALISE_runInitCals(phy->talDevice, - phy->initCalMask & ~TAL_TX_LO_LEAKAGE_EXTERNAL); + phy->initCalMask & ~TAL_TX_LO_LEAKAGE_EXTERNAL); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } @@ -5987,9 +6030,11 @@ static int adrv9009_jesd204_setup_stage5(struct jesd204_dev *jdev, /*************************************************************************/ /*** < Action: Please ensure PA is enabled operational at this time > ***/ if (phy->initCalMask & TAL_TX_LO_LEAKAGE_EXTERNAL) { - ret = TALISE_runInitCals(phy->talDevice, TAL_TX_LO_LEAKAGE_EXTERNAL); + ret = TALISE_runInitCals(phy->talDevice, + TAL_TX_LO_LEAKAGE_EXTERNAL); if (ret != TALACT_NO_ACTION) - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); ret = TALISE_waitInitCals(phy->talDevice, 20000, &errorFlag); if ((ret != TALACT_NO_ACTION) || errorFlag) { @@ -6003,7 +6048,7 @@ static int adrv9009_jesd204_setup_stage5(struct jesd204_dev *jdev, } static int adrv9009_jesd204_post_running_stage(struct jesd204_dev *jdev, - enum jesd204_state_op_reason reason) + enum jesd204_state_op_reason reason) { struct device *dev = jesd204_dev_to_device(jdev); struct adrv9009_jesd204_priv *priv = jesd204_dev_priv(jdev); @@ -6012,7 +6057,8 @@ static int adrv9009_jesd204_post_running_stage(struct jesd204_dev *jdev, u32 trackingCalMask = phy->tracking_cal_mask = TAL_TRACK_NONE; - dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, jesd204_state_op_reason_str(reason)); + dev_dbg(dev, "%s:%d reason %s\n", __func__, __LINE__, + jesd204_state_op_reason_str(reason)); if (reason != JESD204_STATE_OP_REASON_INIT) { phy->is_initialized = 0; @@ -6027,30 +6073,37 @@ static int adrv9009_jesd204_post_running_stage(struct jesd204_dev *jdev, * **********************************************/ ret = TALISE_setGpIntMask(phy->talDevice, TAL_GP_MASK_AUX_SYNTH_UNLOCK); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } ret = TALISE_enableTrackingCals(phy->talDevice, trackingCalMask); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } if (has_rx_and_en(phy)) { ret = TALISE_setupRxAgc(phy->talDevice, &phy->rxAgcCtrl); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } } if (has_tx_and_en(phy)) { - ret = TALISE_setTxAttenCtrlPin(phy->talDevice, TAL_TX1, &phy->tx1_atten_ctrl_pin); + ret = TALISE_setTxAttenCtrlPin(phy->talDevice, + TAL_TX1, &phy->tx1_atten_ctrl_pin); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } - ret = TALISE_setTxAttenCtrlPin(phy->talDevice, TAL_TX2, &phy->tx2_atten_ctrl_pin); + ret = TALISE_setTxAttenCtrlPin(phy->talDevice, + TAL_TX2, &phy->tx2_atten_ctrl_pin); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } } @@ -6058,14 +6111,16 @@ static int adrv9009_jesd204_post_running_stage(struct jesd204_dev *jdev, /* that were setup during TALISE_initialize() */ ret = TALISE_radioOn(phy->talDevice); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } ret = TALISE_setRxTxEnable(phy->talDevice, - has_rx_and_en(phy) ? phy->talInit.rx.rxChannels : 0, - has_tx_and_en(phy) ? phy->talInit.tx.txChannels : 0); + has_rx_and_en(phy) ? phy->talInit.rx.rxChannels : 0, + has_tx_and_en(phy) ? phy->talInit.tx.txChannels : 0); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } if (has_rx(phy)) @@ -6079,22 +6134,27 @@ static int adrv9009_jesd204_post_running_stage(struct jesd204_dev *jdev, } ret = TALISE_setupAuxDacs(phy->talDevice, &phy->auxdac); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } if (phy->gpio3v3SrcCtrl) { - ret = TALISE_setGpio3v3SourceCtrl(phy->talDevice, phy->gpio3v3SrcCtrl); + ret = TALISE_setGpio3v3SourceCtrl(phy->talDevice, + phy->gpio3v3SrcCtrl); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } TALISE_setGpio3v3PinLevel(phy->talDevice, phy->gpio3v3PinLevel); TALISE_setGpio3v3Oe(phy->talDevice, phy->gpio3v3OutEn, 0xFFF); } if (has_tx(phy)) { - ret = TALISE_setPaProtectionCfg(phy->talDevice, &phy->tx_pa_protection); + ret = TALISE_setPaProtectionCfg(phy->talDevice, + &phy->tx_pa_protection); if (ret != TALACT_NO_ACTION) { - dev_err(&phy->spi->dev, "%s:%d (ret %d)", __func__, __LINE__, ret); + dev_err(&phy->spi->dev, + "%s:%d (ret %d)", __func__, __LINE__, ret); return -EFAULT; } }