123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Analog Devices ADF4371 SPI Wideband Synthesizer driver
- *
- * Copyright 2019 Analog Devices Inc.
- */
- #include <linux/bitfield.h>
- #include <linux/clk.h>
- #include <linux/device.h>
- #include <linux/err.h>
- #include <linux/gcd.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/regmap.h>
- #include <linux/sysfs.h>
- #include <linux/spi/spi.h>
- #include <linux/iio/iio.h>
- /* Registers address macro */
- #define ADF4371_REG(x) (x)
- /* ADF4371_REG0 */
- #define ADF4371_ADDR_ASC_MSK BIT(2)
- #define ADF4371_ADDR_ASC(x) FIELD_PREP(ADF4371_ADDR_ASC_MSK, x)
- #define ADF4371_ADDR_ASC_R_MSK BIT(5)
- #define ADF4371_ADDR_ASC_R(x) FIELD_PREP(ADF4371_ADDR_ASC_R_MSK, x)
- #define ADF4371_RESET_CMD 0x81
- /* ADF4371_REG17 */
- #define ADF4371_FRAC2WORD_L_MSK GENMASK(7, 1)
- #define ADF4371_FRAC2WORD_L(x) FIELD_PREP(ADF4371_FRAC2WORD_L_MSK, x)
- #define ADF4371_FRAC1WORD_MSK BIT(0)
- #define ADF4371_FRAC1WORD(x) FIELD_PREP(ADF4371_FRAC1WORD_MSK, x)
- /* ADF4371_REG18 */
- #define ADF4371_FRAC2WORD_H_MSK GENMASK(6, 0)
- #define ADF4371_FRAC2WORD_H(x) FIELD_PREP(ADF4371_FRAC2WORD_H_MSK, x)
- /* ADF4371_REG1A */
- #define ADF4371_MOD2WORD_MSK GENMASK(5, 0)
- #define ADF4371_MOD2WORD(x) FIELD_PREP(ADF4371_MOD2WORD_MSK, x)
- /* ADF4371_REG24 */
- #define ADF4371_RF_DIV_SEL_MSK GENMASK(6, 4)
- #define ADF4371_RF_DIV_SEL(x) FIELD_PREP(ADF4371_RF_DIV_SEL_MSK, x)
- /* ADF4371_REG25 */
- #define ADF4371_MUTE_LD_MSK BIT(7)
- #define ADF4371_MUTE_LD(x) FIELD_PREP(ADF4371_MUTE_LD_MSK, x)
- /* ADF4371_REG32 */
- #define ADF4371_TIMEOUT_MSK GENMASK(1, 0)
- #define ADF4371_TIMEOUT(x) FIELD_PREP(ADF4371_TIMEOUT_MSK, x)
- /* ADF4371_REG34 */
- #define ADF4371_VCO_ALC_TOUT_MSK GENMASK(4, 0)
- #define ADF4371_VCO_ALC_TOUT(x) FIELD_PREP(ADF4371_VCO_ALC_TOUT_MSK, x)
- /* Specifications */
- #define ADF4371_MIN_VCO_FREQ 4000000000ULL /* 4000 MHz */
- #define ADF4371_MAX_VCO_FREQ 8000000000ULL /* 8000 MHz */
- #define ADF4371_MAX_OUT_RF8_FREQ ADF4371_MAX_VCO_FREQ /* Hz */
- #define ADF4371_MIN_OUT_RF8_FREQ (ADF4371_MIN_VCO_FREQ / 64) /* Hz */
- #define ADF4371_MAX_OUT_RF16_FREQ (ADF4371_MAX_VCO_FREQ * 2) /* Hz */
- #define ADF4371_MIN_OUT_RF16_FREQ (ADF4371_MIN_VCO_FREQ * 2) /* Hz */
- #define ADF4371_MAX_OUT_RF32_FREQ (ADF4371_MAX_VCO_FREQ * 4) /* Hz */
- #define ADF4371_MIN_OUT_RF32_FREQ (ADF4371_MIN_VCO_FREQ * 4) /* Hz */
- #define ADF4371_MAX_FREQ_PFD 250000000UL /* Hz */
- #define ADF4371_MAX_FREQ_REFIN 600000000UL /* Hz */
- /* 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)
- #define ADF4371_CHECK_RANGE(freq, range) \
- ((freq > ADF4371_MAX_ ## range) || (freq < ADF4371_MIN_ ## range))
- enum {
- ADF4371_FREQ,
- ADF4371_POWER_DOWN,
- ADF4371_CHANNEL_NAME
- };
- enum {
- ADF4371_CH_RF8,
- ADF4371_CH_RFAUX8,
- ADF4371_CH_RF16,
- ADF4371_CH_RF32
- };
- enum adf4371_variant {
- ADF4371,
- ADF4372
- };
- struct adf4371_pwrdown {
- unsigned int reg;
- unsigned int bit;
- };
- static const char * const adf4371_ch_names[] = {
- "RF8x", "RFAUX8x", "RF16x", "RF32x"
- };
- static const struct adf4371_pwrdown adf4371_pwrdown_ch[4] = {
- [ADF4371_CH_RF8] = { ADF4371_REG(0x25), 2 },
- [ADF4371_CH_RFAUX8] = { ADF4371_REG(0x72), 3 },
- [ADF4371_CH_RF16] = { ADF4371_REG(0x25), 3 },
- [ADF4371_CH_RF32] = { ADF4371_REG(0x25), 4 },
- };
- static const struct reg_sequence adf4371_reg_defaults[] = {
- { ADF4371_REG(0x0), 0x18 },
- { ADF4371_REG(0x12), 0x40 },
- { ADF4371_REG(0x1E), 0x48 },
- { ADF4371_REG(0x20), 0x14 },
- { ADF4371_REG(0x22), 0x00 },
- { ADF4371_REG(0x23), 0x00 },
- { ADF4371_REG(0x24), 0x80 },
- { ADF4371_REG(0x25), 0x07 },
- { ADF4371_REG(0x27), 0xC5 },
- { ADF4371_REG(0x28), 0x83 },
- { ADF4371_REG(0x2C), 0x44 },
- { ADF4371_REG(0x2D), 0x11 },
- { ADF4371_REG(0x2E), 0x12 },
- { ADF4371_REG(0x2F), 0x94 },
- { ADF4371_REG(0x32), 0x04 },
- { ADF4371_REG(0x35), 0xFA },
- { ADF4371_REG(0x36), 0x30 },
- { ADF4371_REG(0x39), 0x07 },
- { ADF4371_REG(0x3A), 0x55 },
- { ADF4371_REG(0x3E), 0x0C },
- { ADF4371_REG(0x3F), 0x80 },
- { ADF4371_REG(0x40), 0x50 },
- { ADF4371_REG(0x41), 0x28 },
- { ADF4371_REG(0x47), 0xC0 },
- { ADF4371_REG(0x52), 0xF4 },
- { ADF4371_REG(0x70), 0x03 },
- { ADF4371_REG(0x71), 0x60 },
- { ADF4371_REG(0x72), 0x32 },
- };
- static const struct regmap_config adf4371_regmap_config = {
- .reg_bits = 16,
- .val_bits = 8,
- .read_flag_mask = BIT(7),
- };
- struct adf4371_chip_info {
- unsigned int num_channels;
- const struct iio_chan_spec *channels;
- };
- struct adf4371_state {
- struct spi_device *spi;
- struct regmap *regmap;
- struct clk *clkin;
- /*
- * 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;
- const struct adf4371_chip_info *chip_info;
- unsigned long clkin_freq;
- unsigned long fpfd;
- unsigned int integer;
- unsigned int fract1;
- unsigned int fract2;
- unsigned int mod2;
- unsigned int rf_div_sel;
- unsigned int ref_div_factor;
- u8 buf[10] __aligned(IIO_DMA_MINALIGN);
- };
- static unsigned long long adf4371_pll_fract_n_get_rate(struct adf4371_state *st,
- u32 channel)
- {
- unsigned long long val, tmp;
- unsigned int ref_div_sel;
- val = (((u64)st->integer * ADF4371_MODULUS1) + st->fract1) * st->fpfd;
- tmp = (u64)st->fract2 * st->fpfd;
- do_div(tmp, st->mod2);
- val += tmp + ADF4371_MODULUS1 / 2;
- if (channel == ADF4371_CH_RF8 || channel == ADF4371_CH_RFAUX8)
- ref_div_sel = st->rf_div_sel;
- else
- ref_div_sel = 0;
- do_div(val, ADF4371_MODULUS1 * (1 << ref_div_sel));
- if (channel == ADF4371_CH_RF16)
- val <<= 1;
- else if (channel == ADF4371_CH_RF32)
- val <<= 2;
- return val;
- }
- static void adf4371_pll_fract_n_compute(unsigned long long vco,
- unsigned long long pfd,
- unsigned int *integer,
- unsigned int *fract1,
- unsigned int *fract2,
- unsigned int *mod2)
- {
- unsigned long long tmp;
- u32 gcd_div;
- tmp = do_div(vco, pfd);
- tmp = tmp * ADF4371_MODULUS1;
- *fract2 = do_div(tmp, pfd);
- *integer = vco;
- *fract1 = tmp;
- *mod2 = pfd;
- while (*mod2 > ADF4371_MAX_MODULUS2) {
- *mod2 >>= 1;
- *fract2 >>= 1;
- }
- gcd_div = gcd(*fract2, *mod2);
- *mod2 /= gcd_div;
- *fract2 /= gcd_div;
- }
- static int adf4371_set_freq(struct adf4371_state *st, unsigned long long freq,
- unsigned int channel)
- {
- u32 cp_bleed;
- u8 int_mode = 0;
- int ret;
- switch (channel) {
- case ADF4371_CH_RF8:
- case ADF4371_CH_RFAUX8:
- if (ADF4371_CHECK_RANGE(freq, OUT_RF8_FREQ))
- return -EINVAL;
- st->rf_div_sel = 0;
- while (freq < ADF4371_MIN_VCO_FREQ) {
- freq <<= 1;
- st->rf_div_sel++;
- }
- break;
- case ADF4371_CH_RF16:
- /* ADF4371 RF16 8000...16000 MHz */
- if (ADF4371_CHECK_RANGE(freq, OUT_RF16_FREQ))
- return -EINVAL;
- freq >>= 1;
- break;
- case ADF4371_CH_RF32:
- /* ADF4371 RF32 16000...32000 MHz */
- if (ADF4371_CHECK_RANGE(freq, OUT_RF32_FREQ))
- return -EINVAL;
- freq >>= 2;
- break;
- default:
- return -EINVAL;
- }
- adf4371_pll_fract_n_compute(freq, st->fpfd, &st->integer, &st->fract1,
- &st->fract2, &st->mod2);
- st->buf[0] = st->integer >> 8;
- st->buf[1] = 0x40; /* REG12 default */
- st->buf[2] = 0x00;
- st->buf[3] = st->fract1 & 0xFF;
- st->buf[4] = st->fract1 >> 8;
- st->buf[5] = st->fract1 >> 16;
- st->buf[6] = ADF4371_FRAC2WORD_L(st->fract2 & 0x7F) |
- ADF4371_FRAC1WORD(st->fract1 >> 24);
- st->buf[7] = ADF4371_FRAC2WORD_H(st->fract2 >> 7);
- st->buf[8] = st->mod2 & 0xFF;
- st->buf[9] = ADF4371_MOD2WORD(st->mod2 >> 8);
- 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;
- return regmap_write(st->regmap, ADF4371_REG(0x10), st->integer & 0xFF);
- }
- static ssize_t adf4371_read(struct iio_dev *indio_dev,
- uintptr_t private,
- const struct iio_chan_spec *chan,
- char *buf)
- {
- struct adf4371_state *st = iio_priv(indio_dev);
- unsigned long long val = 0;
- unsigned int readval, reg, bit;
- int 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);
- }
- static ssize_t adf4371_write(struct iio_dev *indio_dev,
- uintptr_t private,
- const struct iio_chan_spec *chan,
- const char *buf, size_t len)
- {
- struct adf4371_state *st = iio_priv(indio_dev);
- unsigned long long freq;
- bool power_down;
- unsigned int bit, readval, reg;
- int ret;
- mutex_lock(&st->lock);
- switch ((u32)private) {
- case ADF4371_FREQ:
- ret = kstrtoull(buf, 10, &freq);
- if (ret)
- break;
- ret = adf4371_set_freq(st, freq, chan->channel);
- break;
- case ADF4371_POWER_DOWN:
- ret = kstrtobool(buf, &power_down);
- if (ret)
- break;
- 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;
- readval &= ~BIT(bit);
- readval |= (!power_down << bit);
- ret = regmap_write(st->regmap, reg, readval);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- mutex_unlock(&st->lock);
- return ret ? ret : len;
- }
- #define _ADF4371_EXT_INFO(_name, _ident) { \
- .name = _name, \
- .read = adf4371_read, \
- .write = adf4371_write, \
- .private = _ident, \
- .shared = IIO_SEPARATE, \
- }
- static const struct 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),
- { },
- };
- #define ADF4371_CHANNEL(index) { \
- .type = IIO_ALTVOLTAGE, \
- .output = 1, \
- .channel = index, \
- .ext_info = adf4371_ext_info, \
- .indexed = 1, \
- }
- static const struct iio_chan_spec adf4371_chan[] = {
- ADF4371_CHANNEL(ADF4371_CH_RF8),
- ADF4371_CHANNEL(ADF4371_CH_RFAUX8),
- ADF4371_CHANNEL(ADF4371_CH_RF16),
- ADF4371_CHANNEL(ADF4371_CH_RF32),
- };
- static const struct adf4371_chip_info adf4371_chip_info[] = {
- [ADF4371] = {
- .channels = adf4371_chan,
- .num_channels = 4,
- },
- [ADF4372] = {
- .channels = adf4371_chan,
- .num_channels = 3,
- }
- };
- static int adf4371_reg_access(struct iio_dev *indio_dev,
- unsigned int reg,
- unsigned int writeval,
- unsigned int *readval)
- {
- struct adf4371_state *st = iio_priv(indio_dev);
- if (readval)
- return regmap_read(st->regmap, reg, readval);
- else
- return regmap_write(st->regmap, reg, writeval);
- }
- static const struct iio_info adf4371_info = {
- .debugfs_reg_access = &adf4371_reg_access,
- };
- static int adf4371_setup(struct adf4371_state *st)
- {
- unsigned int synth_timeout = 2, timeout = 1, vco_alc_timeout = 1;
- unsigned int vco_band_div, tmp;
- int ret;
- /* 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;
- /*
- * 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 / st->ref_div_factor;
- } while (st->fpfd > ADF4371_MAX_FREQ_PFD);
- /* Calculate Timeouts */
- vco_band_div = DIV_ROUND_UP(st->fpfd, 2400000U);
- tmp = DIV_ROUND_CLOSEST(st->fpfd, 1000000U);
- do {
- timeout++;
- if (timeout > 1023) {
- timeout = 2;
- synth_timeout++;
- }
- } while (synth_timeout * 1024 + timeout <= 20 * tmp);
- do {
- vco_alc_timeout++;
- } while (vco_alc_timeout * 1024 - timeout <= 50 * tmp);
- st->buf[0] = vco_band_div;
- st->buf[1] = timeout & 0xFF;
- st->buf[2] = ADF4371_TIMEOUT(timeout >> 8) | 0x04;
- st->buf[3] = synth_timeout;
- st->buf[4] = ADF4371_VCO_ALC_TOUT(vco_alc_timeout);
- return regmap_bulk_write(st->regmap, ADF4371_REG(0x30), st->buf, 5);
- }
- static int adf4371_probe(struct spi_device *spi)
- {
- const struct spi_device_id *id = spi_get_device_id(spi);
- struct iio_dev *indio_dev;
- struct adf4371_state *st;
- struct regmap *regmap;
- int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
- regmap = devm_regmap_init_spi(spi, &adf4371_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
- PTR_ERR(regmap));
- return PTR_ERR(regmap);
- }
- st = iio_priv(indio_dev);
- spi_set_drvdata(spi, indio_dev);
- st->spi = spi;
- st->regmap = regmap;
- mutex_init(&st->lock);
- st->chip_info = &adf4371_chip_info[id->driver_data];
- indio_dev->name = id->name;
- indio_dev->info = &adf4371_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = st->chip_info->channels;
- indio_dev->num_channels = st->chip_info->num_channels;
- st->clkin = devm_clk_get_enabled(&spi->dev, "clkin");
- if (IS_ERR(st->clkin))
- return PTR_ERR(st->clkin);
- st->clkin_freq = clk_get_rate(st->clkin);
- ret = adf4371_setup(st);
- if (ret < 0) {
- dev_err(&spi->dev, "ADF4371 setup failed\n");
- return ret;
- }
- return devm_iio_device_register(&spi->dev, indio_dev);
- }
- static const struct spi_device_id adf4371_id_table[] = {
- { "adf4371", ADF4371 },
- { "adf4372", ADF4372 },
- {}
- };
- MODULE_DEVICE_TABLE(spi, adf4371_id_table);
- static const struct of_device_id adf4371_of_match[] = {
- { .compatible = "adi,adf4371" },
- { .compatible = "adi,adf4372" },
- { },
- };
- MODULE_DEVICE_TABLE(of, adf4371_of_match);
- static struct spi_driver adf4371_driver = {
- .driver = {
- .name = "adf4371",
- .of_match_table = adf4371_of_match,
- },
- .probe = adf4371_probe,
- .id_table = adf4371_id_table,
- };
- module_spi_driver(adf4371_driver);
- MODULE_AUTHOR("Stefan Popa <[email protected]>");
- MODULE_DESCRIPTION("Analog Devices ADF4371 SPI PLL");
- MODULE_LICENSE("GPL");
|