Skip to content

Commit

Permalink
iio: adc: ad9361: add accessor for getting device's digital tune data
Browse files Browse the repository at this point in the history
Currently, the `ad9361_conv.c` file accesses a few bits of state
information from the phy struct.
This is not great.

For the digital tune functions, this info can be grouped into a struct and
a single [accessor] call.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
  • Loading branch information
commodo committed Apr 18, 2018
1 parent 8d30532 commit dec20d2
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 20 deletions.
16 changes: 14 additions & 2 deletions drivers/iio/adc/ad9361.c
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down
16 changes: 15 additions & 1 deletion drivers/iio/adc/ad9361.h
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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

36 changes: 19 additions & 17 deletions drivers/iio/adc/ad9361_conv.c
Expand Up @@ -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 */
Expand All @@ -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);

Expand Down Expand Up @@ -605,28 +607,28 @@ 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;

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

Expand All @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit dec20d2

Please sign in to comment.