Skip to content

Commit

Permalink
iio: adc: ad9361: Validate MAX Half Band filter rates
Browse files Browse the repository at this point in the history
The Half Band decimation and interpolation filters do have some max rate
they can run on. Typically the driver itself or AD9361 filter wizard
takes these into account. However recently we discovered a corner case
where max TX_HB1 rate of 160MSPS could have been exceed by using a
interpolate by 4 FIR filter and a Baseband rate of > 40 MSPS.

This patch adds a check for all max ratings of BBPPL, ADC, DAC, HB3, HB2
and HB1 filters in the system.


Signed-off-by: Michael Hennerich <[email protected]>
  • Loading branch information
mhennerich authored and commodo committed Apr 10, 2018
1 parent d1883e4 commit a7c5b67
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
27 changes: 25 additions & 2 deletions drivers/iio/adc/ad9361.c
Original file line number Diff line number Diff line change
Expand Up @@ -3882,8 +3882,13 @@ static int ad9361_ensm_set_state(struct ad9361_rf_phy *phy, u8 ensm_state,
}

static int ad9361_validate_trx_clock_chain(struct ad9361_rf_phy *phy,
unsigned long *rx_path_clks)
unsigned long *rx_path_clks,
unsigned long *tx_path_clks)
{
const unsigned long max_rx_rates[] = {MAX_BBPLL_FREQ, MAX_ADC_CLK,
MAX_RX_HB3, MAX_RX_HB2, MAX_RX_HB1, MAX_BASEBAND_RATE};
const unsigned long max_tx_rates[] = {MAX_BBPLL_FREQ, MAX_DAC_CLK,
MAX_TX_HB3, MAX_TX_HB2, MAX_TX_HB1, MAX_BASEBAND_RATE};
int i, data_clk;

data_clk = (phy->pdata->rx2tx2 ? 4 : 2) /
Expand All @@ -3898,6 +3903,24 @@ static int ad9361_validate_trx_clock_chain(struct ad9361_rf_phy *phy,
return -EINVAL;
}

/* Validate MAX PLL, ADC, DAC and HB filter rates */
for (i = 0; i < ARRAY_SIZE(max_rx_rates); i++) {
if (rx_path_clks[i] > max_rx_rates[i]) {
dev_err(&phy->spi->dev,
"%s: Failed RX max rate check (%lu > %lu)",
__func__, rx_path_clks[i], max_rx_rates[i]);
return -EINVAL;
}

if (tx_path_clks[i] > max_tx_rates[i]) {
dev_err(&phy->spi->dev,
"%s: Failed TX max rate check (%lu > %lu)",
__func__, tx_path_clks[i], max_tx_rates[i]);
return -EINVAL;
}
}

/* Validate that DATA_CLK exist within the clock chain */
for (i = 1; i <= 3; i++) {
if (abs(rx_path_clks[ADC_FREQ] / i - data_clk) < 4)
return 0;
Expand Down Expand Up @@ -3936,7 +3959,7 @@ int ad9361_set_trx_clock_chain(struct ad9361_rf_phy *phy,
tx_path_clks[R2_FREQ], tx_path_clks[R1_FREQ],
tx_path_clks[CLKRF_FREQ], tx_path_clks[RX_SAMPL_FREQ]);

ret = ad9361_validate_trx_clock_chain(phy, rx_path_clks);
ret = ad9361_validate_trx_clock_chain(phy, rx_path_clks, tx_path_clks);
if (ret < 0)
return ret;

Expand Down
11 changes: 11 additions & 0 deletions drivers/iio/adc/ad9361.h
Original file line number Diff line number Diff line change
Expand Up @@ -2797,6 +2797,17 @@
#define MAX_ADC_CLK 640000000UL /* 640 MHz */
#define MAX_DAC_CLK (MAX_ADC_CLK / 2)

/* Associated with outputs of stage */
#define MAX_RX_HB1 245760000UL
#define MAX_RX_HB2 320000000UL
#define MAX_RX_HB3 640000000UL
/* Associated with inputs of stage */
#define MAX_TX_HB1 160000000UL
#define MAX_TX_HB2 320000000UL
#define MAX_TX_HB3 320000000UL

#define MAX_BASEBAND_RATE 61440000UL

#define MAX_MBYTE_SPI 8

#define RFPLL_MODULUS 8388593UL
Expand Down

0 comments on commit a7c5b67

Please sign in to comment.