diff --git a/drivers/iio/adc/ad9361.c b/drivers/iio/adc/ad9361.c index 67a04883afe8de..68cf18a0fb3c19 100644 --- a/drivers/iio/adc/ad9361.c +++ b/drivers/iio/adc/ad9361.c @@ -1585,11 +1585,10 @@ static int ad9361_get_rx_gain(struct ad9361_rf_phy *phy, return rc; } -u8 ad9361_ensm_get_state(struct ad9361_rf_phy *phy) +static u8 ad9361_ensm_get_state(struct ad9361_rf_phy *phy) { return ad9361_spi_readf(phy->spi, REG_STATE, ENSM_STATE(~0)); } -EXPORT_SYMBOL(ad9361_ensm_get_state); void ad9361_ensm_force_state(struct ad9361_rf_phy *phy, u8 ensm_state) { @@ -4030,6 +4029,19 @@ bool ad9361_uses_rx2tx2(struct ad9361_rf_phy *phy) } EXPORT_SYMBOL(ad9361_uses_rx2tx2); +int ad9361_get_dig_tune_data(struct ad9361_rf_phy *phy, + struct ad9361_dig_tune_data *data) +{ + if (!phy || !data) + return -EINVAL; + data->ensm_state = ad9361_ensm_get_state(phy); + data->bist_loopback_mode = phy->bist_loopback_mode; + data->skip_mode = phy->pdata->dig_interface_tune_skipmode; + data->bist_config = phy->bist_config; + return 0; +} +EXPORT_SYMBOL(ad9361_get_dig_tune_data); + static int ad9361_get_trx_clock_chain(struct ad9361_rf_phy *phy, unsigned long *rx_path_clks, unsigned long *tx_path_clks) { diff --git a/drivers/iio/adc/ad9361.h b/drivers/iio/adc/ad9361.h index 99685d29a708e5..e15ae81df91a52 100644 --- a/drivers/iio/adc/ad9361.h +++ b/drivers/iio/adc/ad9361.h @@ -480,6 +480,12 @@ enum { ID_AD9363A, }; +enum digital_tune_skip_mode { + TUNE_RX_TX, + SKIP_TX, + SKIP_ALL, +}; + struct ad9361_rf_phy; struct ad9361_debugfs_entry { struct ad9361_rf_phy *phy; @@ -503,6 +509,13 @@ struct ad9361_fastlock { struct ad9361_fastlock_entry entry[2][8]; }; +struct ad9361_dig_tune_data { + u32 bist_loopback_mode; + u32 bist_config; + u32 ensm_state; + u8 skip_mode; +}; + struct refclk_scale { struct clk_hw hw; struct spi_device *spi; @@ -603,7 +616,6 @@ int ad9361_find_opt(u8 *field, u32 size, u32 *ret_start); int ad9361_ensm_mode_disable_pinctrl(struct ad9361_rf_phy *phy); int ad9361_ensm_mode_restore_pinctrl(struct ad9361_rf_phy *phy); void ad9361_ensm_force_state(struct ad9361_rf_phy *phy, u8 ensm_state); -u8 ad9361_ensm_get_state(struct ad9361_rf_phy *phy); void ad9361_ensm_restore_state(struct ad9361_rf_phy *phy, u8 ensm_state); void ad9361_ensm_restore_prev_state(struct ad9361_rf_phy *phy); int ad9361_set_trx_clock_chain_freq(struct ad9361_rf_phy *phy, @@ -614,6 +626,8 @@ int ad9361_dig_tune(struct ad9361_rf_phy *phy, unsigned long max_freq, int ad9361_tx_mute(struct ad9361_rf_phy *phy, u32 state); int ad9361_write_bist_reg(struct ad9361_rf_phy *phy, u32 val); bool ad9361_uses_rx2tx2(struct ad9361_rf_phy *phy); +int ad9361_get_dig_tune_data(struct ad9361_rf_phy *phy, + struct ad9361_dig_tune_data *data); #endif diff --git a/drivers/iio/adc/ad9361_conv.c b/drivers/iio/adc/ad9361_conv.c index 3f641353e922d8..f70a0b0b88f835 100644 --- a/drivers/iio/adc/ad9361_conv.c +++ b/drivers/iio/adc/ad9361_conv.c @@ -77,19 +77,21 @@ ssize_t ad9361_dig_interface_timing_analysis(struct ad9361_rf_phy *phy, char *buf, unsigned buflen) { struct axiadc_converter *conv = spi_get_drvdata(phy->spi); - unsigned int loopback, bist, ensm_state; + struct ad9361_dig_tune_data data; int i, j, len = 0; + int ret; u8 field[16][16]; u8 rx; if (!conv) return -ENODEV; + ret = ad9361_get_dig_tune_data(phy, &data); + if (ret < 0) + return ret; + dev_dbg(&phy->spi->dev, "%s:\n", __func__); - loopback = phy->bist_loopback_mode; - bist = phy->bist_config; - ensm_state = ad9361_ensm_get_state(phy); rx = ad9361_spi_read(phy->spi, REG_RX_CLOCK_DATA_DELAY); /* Mute TX, we don't want to transmit the PRBS */ @@ -109,11 +111,11 @@ ssize_t ad9361_dig_interface_timing_analysis(struct ad9361_rf_phy *phy, ad9361_ensm_force_state(phy, ENSM_STATE_ALERT); ad9361_spi_write(phy->spi, REG_RX_CLOCK_DATA_DELAY, rx); - ad9361_bist_loopback(phy, loopback); - ad9361_write_bist_reg(phy, bist); + ad9361_bist_loopback(phy, data.bist_loopback_mode); + ad9361_write_bist_reg(phy, data.bist_config); ad9361_ensm_mode_restore_pinctrl(phy); - ad9361_ensm_restore_state(phy, ensm_state); + ad9361_ensm_restore_state(phy, data.ensm_state); ad9361_tx_mute(phy, 0); @@ -605,7 +607,7 @@ int ad9361_dig_tune(struct ad9361_rf_phy *phy, unsigned long max_freq, enum dig_tune_flags flags) { struct axiadc_converter *conv = spi_get_drvdata(phy->spi); - unsigned int loopback, bist, ensm_state; + struct ad9361_dig_tune_data data; struct axiadc_state *st; bool restore = false; int ret = 0; @@ -613,20 +615,20 @@ int ad9361_dig_tune(struct ad9361_rf_phy *phy, unsigned long max_freq, if (!conv) return -ENODEV; + ret = ad9361_get_dig_tune_data(phy, &data); + if (ret < 0) + return ret; + dev_dbg(&phy->spi->dev, "%s: freq %lu flags 0x%X\n", __func__, max_freq, flags); st = iio_priv(conv->indio_dev); - ensm_state = ad9361_ensm_get_state(phy); - if (phy->pdata->dig_interface_tune_skipmode == 2 || + if ((data.skip_mode == SKIP_ALL) || (flags & RESTORE_DEFAULT)) { /* skip completely and use defaults */ restore = true; } else { - loopback = phy->bist_loopback_mode; - bist = phy->bist_config; - /* Mute TX, we don't want to transmit the PRBS */ ad9361_tx_mute(phy, 1); @@ -639,11 +641,11 @@ int ad9361_dig_tune(struct ad9361_rf_phy *phy, unsigned long max_freq, ad9361_midscale_iodelay(phy, true); ret = ad9361_dig_tune_rx(phy, max_freq, flags); - if (ret == 0 && !phy->pdata->dig_interface_tune_skipmode) + if (ret == 0 && (data.skip_mode != TUNE_RX_TX)) ret = ad9361_dig_tune_tx(phy, max_freq, flags); - ad9361_bist_loopback(phy, loopback); - ad9361_write_bist_reg(phy, bist); + ad9361_bist_loopback(phy, data.bist_loopback_mode); + ad9361_write_bist_reg(phy, data.bist_config); if (ret == -EIO) restore = true; @@ -665,7 +667,7 @@ int ad9361_dig_tune(struct ad9361_rf_phy *phy, unsigned long max_freq, } ad9361_ensm_mode_restore_pinctrl(phy); - ad9361_ensm_restore_state(phy, ensm_state); + ad9361_ensm_restore_state(phy, data.ensm_state); axiadc_write(st, ADI_REG_RSTN, ADI_MMCM_RSTN); axiadc_write(st, ADI_REG_RSTN, ADI_RSTN | ADI_MMCM_RSTN);