ret = regmap_read(st->regmap, AD9739A_REG_DEC_CNT, &mode); if (ret) return ret;
mode = FIELD_GET(AD9739A_DAC_DEC, mode); /* sanity check we get valid values from the HW */ if (mode != AD9739A_NORMAL_MODE && mode != AD9739A_MIXED_MODE) return -EIO; if (!mode) return AD9739A_NORMAL_MODE;
/* * We get 2 from the device but for IIO modes, that means 1. Hence the * minus 1.
*/ return AD9739A_MIXED_MODE - 1;
}
/* * On the IIO interface we have 0 and 1 for mode. But for mixed_mode, we * need to write 2 in the device. That's what the below check is about.
*/ if (mode == AD9739A_MIXED_MODE - 1)
mode = AD9739A_MIXED_MODE;
/* * Recommended values (as per datasheet) for the dac clk common mode voltage * and Mu controller. Look at table 29.
*/ staticconststruct reg_sequence ad9739a_clk_mu_ctrl[] = { /* DAC clk common mode voltage */
{ AD9739A_REG_CROSS_CNT1, 0x0f },
{ AD9739A_REG_CROSS_CNT2, 0x0f }, /* Mu controller configuration */
{ AD9739A_REG_PHS_DET, 0x30 },
{ AD9739A_REG_MU_DUTY, 0x80 },
{ AD9739A_REG_MU_CNT2, 0x44 },
{ AD9739A_REG_MU_CNT3, 0x6c },
};
staticint ad9739a_init(struct device *dev, conststruct ad9739a_state *st)
{ unsignedint i = 0, lock, fsc;
u32 fsc_raw; int ret;
ret = regmap_multi_reg_write(st->regmap, ad9739a_clk_mu_ctrl,
ARRAY_SIZE(ad9739a_clk_mu_ctrl)); if (ret) return ret;
/* * Try to get the Mu lock. Repeat the below steps AD9739A_LOCK_N_TRIES * (as specified by the datasheet) until we get the lock.
*/ do {
ret = regmap_write(st->regmap, AD9739A_REG_MU_CNT4,
AD9739A_MU_CNT4_DEFAULT); if (ret) return ret;
/* Enable the Mu controller search and track mode. */
ret = regmap_write(st->regmap, AD9739A_REG_MU_CNT1,
AD9739A_MU_EN_MASK | AD9739A_MU_GAIN_MASK); if (ret) return ret;
/* Ensure the DLL loop is locked */
ret = regmap_read_poll_timeout(st->regmap, AD9739A_REG_MU_STAT1,
lock, lock & AD9739A_MU_LOCK_MASK,
0, 1000); if (ret && ret != -ETIMEDOUT) return ret;
} while (ret && ++i < AD9739A_LOCK_N_TRIES);
if (i == AD9739A_LOCK_N_TRIES) return dev_err_probe(dev, ret, "Mu lock timeout\n");
/* Receiver tracking and lock. Same deal as the Mu controller */
i = 0; do {
ret = regmap_update_bits(st->regmap, AD9739A_REG_LVDS_REC_CNT4,
AD9739A_FINE_DEL_SKW_MASK,
FIELD_PREP(AD9739A_FINE_DEL_SKW_MASK, 2)); if (ret) return ret;
/* Disable the receiver and the loop. */
ret = regmap_write(st->regmap, AD9739A_REG_LVDS_REC_CNT1, 0); if (ret) return ret;
/* * Re-enable the loop so it falls out of lock and begins the * search/track routine again.
*/
ret = regmap_set_bits(st->regmap, AD9739A_REG_LVDS_REC_CNT1,
AD9739A_RCVR_LOOP_EN_MASK); if (ret) return ret;
/* Ensure the DLL loop is locked */
ret = regmap_read_poll_timeout(st->regmap,
AD9739A_REG_LVDS_REC_STAT9, lock,
lock == AD9739A_RCVR_TRACK_AND_LOCK,
0, 1000); if (ret && ret != -ETIMEDOUT) return ret;
} while (ret && ++i < AD9739A_LOCK_N_TRIES);
if (i == AD9739A_LOCK_N_TRIES) return dev_err_probe(dev, ret, "Receiver lock timeout\n");
ret = device_property_read_u32(dev, "adi,full-scale-microamp", &fsc); if (ret && ret == -EINVAL) return 0; if (ret) return ret; if (!in_range(fsc, AD9739A_FSC_MIN, AD9739A_FSC_RANGE)) return dev_err_probe(dev, -EINVAL, "Invalid full scale current(%u) [%u %u]\n",
fsc, AD9739A_FSC_MIN, AD9739A_FSC_MAX); /* * IOUTFS is given by * Ioutfs = 0.0226 * FSC + 8.58 * and is given in mA. Hence we'll have to multiply by 10 * MILLI in * order to get rid of the fractional.
*/
fsc_raw = DIV_ROUND_CLOSEST(fsc * 10 - 85800, 226);
ret = regmap_write(st->regmap, AD9739A_REG_FSC_1, fsc_raw & 0xff); if (ret) return ret;
/* * The reason for having two different channels is because we have, in reality, * two sources of data: * ALTVOLTAGE: It's a Continuous Wave that's internally generated by the * backend device. * VOLTAGE: It's the typical data we can have in a DAC device and the source * of it has nothing to do with the backend. The backend will only * forward it into our data interface to be sent out.
*/ staticstruct iio_chan_spec ad9739a_channels[] = {
{
.type = IIO_ALTVOLTAGE,
.indexed = 1,
.output = 1,
.scan_index = -1,
},
{
.type = IIO_VOLTAGE,
.indexed = 1,
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.output = 1,
.ext_info = ad9739a_ext_info,
.scan_type = {
.sign = 's',
.storagebits = 16,
.realbits = 16,
},
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.