Example #1
0
/**
* Setup the AD9361 device.
* @param phy The AD9361 state structure.
* @return 0 in case of success, negative error code otherwise.
*/
int32_t ad9361_post_setup(struct ad9361_rf_phy *phy)
{
	struct axiadc_converter *conv = phy->adc_conv;
	struct axiadc_state *st = phy->adc_state;
	int32_t rx2tx2 = phy->pdata->rx2tx2;
	int32_t tmp, num_chan, flags;
	int32_t i, ret;

	num_chan = (conv->chip_info->num_channels > 4) ? 4 : conv->chip_info->num_channels;

	axiadc_write(st, ADI_REG_CNTRL, rx2tx2 ? 0 : ADI_R1_MODE);
	tmp = axiadc_read(st, 0x4048);

	if (!rx2tx2) {
		axiadc_write(st, 0x4048, tmp | BIT(5)); /* R1_MODE */
		axiadc_write(st, 0x404c,
			     (phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) ? 1 : 0); /* RATE */
	}
	else {
		tmp &= ~BIT(5);
		axiadc_write(st, 0x4048, tmp);
		axiadc_write(st, 0x404c,
			     (phy->pdata->port_ctrl.pp_conf[2] & LVDS_MODE) ? 3 : 1); /* RATE */
	}

#ifdef ALTERA_PLATFORM
	axiadc_write(st, 0x404c, 1);
#endif

	for (i = 0; i < num_chan; i++) {
		axiadc_write(st, ADI_REG_CHAN_CNTRL_1(i),
			ADI_DCFILT_OFFSET(0));
		axiadc_write(st, ADI_REG_CHAN_CNTRL_2(i),
			(i & 1) ? 0x00004000 : 0x40000000);
		axiadc_write(st, ADI_REG_CHAN_CNTRL(i),
			ADI_FORMAT_SIGNEXT | ADI_FORMAT_ENABLE |
			ADI_ENABLE | ADI_IQCOR_ENB);
	}

	flags = 0x0;

	ret = ad9361_dig_tune(phy, ((conv->chip_info->num_channels > 4) ||
		axiadc_read(st, 0x0004)) ? 0 : 61440000, flags);
	if (ret < 0)
		return ret;

	if (flags & (DO_IDELAY | DO_ODELAY)) {
		ret = ad9361_dig_tune(phy, (axiadc_read(st, ADI_REG_ID)) ?
			0 : 61440000, flags & BE_VERBOSE);
		if (ret < 0)
			return ret;
	}

	ret = ad9361_set_trx_clock_chain(phy,
					 phy->pdata->rx_path_clks,
					 phy->pdata->tx_path_clks);

	ad9361_ensm_force_state(phy, ENSM_STATE_ALERT);
	ad9361_ensm_restore_prev_state(phy);

	return ret;
}
Example #2
0
static int axiadc_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val,
			   int *val2,
			   long m)
{
	struct axiadc_state *st = iio_priv(indio_dev);
	struct axiadc_converter *conv = to_converter(st->dev_spi);
	int ret, sign;
	unsigned tmp, phase = 0;
	unsigned long long llval;

	switch (m) {
	case IIO_CHAN_INFO_CALIBPHASE:
		phase = 1;
	case IIO_CHAN_INFO_CALIBSCALE:
		tmp = axiadc_read(st, ADI_REG_CHAN_CNTRL_2(chan->channel));
		/*  format is 1.1.14 (sign, integer and fractional bits) */

		if (!((phase + chan->channel) % 2)) {
			tmp = ADI_TO_IQCOR_COEFF_1(tmp);
		} else {
			tmp = ADI_TO_IQCOR_COEFF_2(tmp);
		}

		if (tmp & 0x8000)
			sign = -1;
		else
			sign = 1;

		if (tmp & 0x4000)
			*val = 1 * sign;
		else
			*val = 0;

		tmp &= ~0xC000;

		llval = tmp * 1000000ULL + (0x4000 / 2);
		do_div(llval, 0x4000);
		if (*val == 0)
			*val2 = llval * sign;
		else
			*val2 = llval;

		return IIO_VAL_INT_PLUS_MICRO;

	case IIO_CHAN_INFO_CALIBBIAS:
		tmp = axiadc_read(st, ADI_REG_CHAN_CNTRL_1(chan->channel));
		*val = (short)ADI_TO_DCFILT_OFFSET(tmp);

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
		/*
		 * approx: F_cut = C * Fsample / (2 * pi)
		 */

		tmp = axiadc_read(st, ADI_REG_CHAN_CNTRL(chan->channel));
		if (!(tmp & ADI_DCFILT_ENB)) {
			*val = 0;
			return IIO_VAL_INT;
		}

		tmp = axiadc_read(st, ADI_REG_CHAN_CNTRL_1(chan->channel));
		llval = ADI_TO_DCFILT_COEFF(tmp) * (unsigned long long)conv->adc_clk;
		do_div(llval, 102944); /* 2 * pi * 0x4000 */
		*val = llval;

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SAMP_FREQ:
		ret = conv->read_raw(indio_dev, chan, val, val2, m);
		if (ret < 0 || !*val) {
			tmp = ADI_TO_CLK_FREQ(axiadc_read(st, ADI_REG_CLK_FREQ));
			llval = tmp * 100000000ULL /* FIXME */ * ADI_TO_CLK_RATIO(axiadc_read(st, ADI_REG_CLK_RATIO));
			*val = llval >> 16;
		}

		if (chan->extend_name) {
			tmp = axiadc_read(st,
				ADI_REG_CHAN_USR_CNTRL_2(chan->channel));

			llval = ADI_TO_USR_DECIMATION_M(tmp) * conv->adc_clk;
			do_div(llval, ADI_TO_USR_DECIMATION_N(tmp));
			*val = llval;
		}
		return IIO_VAL_INT;
	default:
		return conv->read_raw(indio_dev, chan, val, val2, m);

	}