/* MOD1 is a 24-bit primary modulus with fixed value of 2^25 */ #define ADF4371_MODULUS1 33554432ULL /* MOD2 is the programmable, 14-bit auxiliary fractional modulus */ #define ADF4371_MAX_MODULUS2 BIT(14)
struct adf4371_state { struct spi_device *spi; struct regmap *regmap; /* * Lock for accessing device registers. Some operations require * multiple consecutive R/W operations, during which the device * shouldn't be interrupted. The buffers are also shared across * all operations so need to be protected on stand alone reads and * writes.
*/ struct mutex lock; conststruct adf4371_chip_info *chip_info; unsignedlong clkin_freq; unsignedlong fpfd; unsignedint integer; unsignedint fract1; unsignedint fract2; unsignedint mod2; unsignedint rf_div_sel; unsignedint ref_div_factor; bool ref_diff_en;
u8 buf[10] __aligned(IIO_DMA_MINALIGN);
};
ret = regmap_bulk_write(st->regmap, ADF4371_REG(0x11), st->buf, 10); if (ret < 0) return ret; /* * The R counter allows the input reference frequency to be * divided down to produce the reference clock to the PFD
*/
ret = regmap_write(st->regmap, ADF4371_REG(0x1F), st->ref_div_factor); if (ret < 0) return ret;
ret = regmap_update_bits(st->regmap, ADF4371_REG(0x24),
ADF4371_RF_DIV_SEL_MSK,
ADF4371_RF_DIV_SEL(st->rf_div_sel)); if (ret < 0) return ret;
cp_bleed = DIV_ROUND_UP(400 * 1750, st->integer * 375);
cp_bleed = clamp(cp_bleed, 1U, 255U);
ret = regmap_write(st->regmap, ADF4371_REG(0x26), cp_bleed); if (ret < 0) return ret; /* * Set to 1 when in INT mode (when FRAC1 = FRAC2 = 0), * and set to 0 when in FRAC mode.
*/ if (st->fract1 == 0 && st->fract2 == 0)
int_mode = 0x01;
ret = regmap_write(st->regmap, ADF4371_REG(0x2B), int_mode); if (ret < 0) return ret;
switch ((u32)private) { case ADF4371_FREQ:
val = adf4371_pll_fract_n_get_rate(st, chan->channel);
ret = regmap_read(st->regmap, ADF4371_REG(0x7C), &readval); if (ret < 0) break;
if (readval == 0x00) {
dev_dbg(&st->spi->dev, "PLL un-locked\n");
ret = -EBUSY;
} break; case ADF4371_POWER_DOWN:
reg = adf4371_pwrdown_ch[chan->channel].reg;
bit = adf4371_pwrdown_ch[chan->channel].bit;
ret = regmap_read(st->regmap, reg, &readval); if (ret < 0) break;
val = !(readval & BIT(bit)); break; case ADF4371_CHANNEL_NAME: return sprintf(buf, "%s\n", adf4371_ch_names[chan->channel]); default:
ret = -EINVAL;
val = 0; break;
}
return ret < 0 ? ret : sprintf(buf, "%llu\n", val);
}
staticconststruct iio_chan_spec_ext_info adf4371_ext_info[] = { /* * Ideally we use IIO_CHAN_INFO_FREQUENCY, but there are * values > 2^32 in order to support the entire frequency range * in Hz. Using scale is a bit ugly.
*/
_ADF4371_EXT_INFO("frequency", ADF4371_FREQ),
_ADF4371_EXT_INFO("powerdown", ADF4371_POWER_DOWN),
_ADF4371_EXT_INFO("name", ADF4371_CHANNEL_NAME),
{ }
};
/* Perform a software reset */
ret = regmap_write(st->regmap, ADF4371_REG(0x0), ADF4371_RESET_CMD); if (ret < 0) return ret;
ret = regmap_multi_reg_write(st->regmap, adf4371_reg_defaults,
ARRAY_SIZE(adf4371_reg_defaults)); if (ret < 0) return ret;
/* Mute to Lock Detect */ if (device_property_read_bool(&st->spi->dev, "adi,mute-till-lock-en")) {
ret = regmap_update_bits(st->regmap, ADF4371_REG(0x25),
ADF4371_MUTE_LD_MSK,
ADF4371_MUTE_LD(1)); if (ret < 0) return ret;
}
/* Set address in ascending order, so the bulk_write() will work */
ret = regmap_update_bits(st->regmap, ADF4371_REG(0x0),
ADF4371_ADDR_ASC_MSK | ADF4371_ADDR_ASC_R_MSK,
ADF4371_ADDR_ASC(1) | ADF4371_ADDR_ASC_R(1)); if (ret < 0) return ret;
ret = regmap_update_bits(st->regmap, ADF4371_REG(0x22),
ADF4371_REF_DOUB_MASK |
ADF4371_REFIN_MODE_MASK,
ADF4371_REF_DOUB(ref_doubler_en) |
ADF4371_REFIN_MODE(st->ref_diff_en)); if (ret < 0) return ret;
/* * Calculate and maximize PFD frequency * fPFD = REFIN × ((1 + D)/(R × (1 + T))) * Where D is the REFIN doubler bit, T is the reference divide by 2, * R is the reference division factor * TODO: it is assumed D and T equal 0.
*/ do {
st->ref_div_factor++;
st->fpfd = st->clkin_freq * (1 + ref_doubler_en) /
st->ref_div_factor;
} while (st->fpfd > ADF4371_MAX_FREQ_PFD);
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.