#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>
#include <linux/gpio/consumer.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/frequency/ad9523.h>
#define AD9523_READ …
#define AD9523_WRITE …
#define AD9523_CNT(x) …
#define AD9523_ADDR(x) …
#define AD9523_R1B …
#define AD9523_R2B …
#define AD9523_R3B …
#define AD9523_TRANSF_LEN(x) …
#define AD9523_SERIAL_PORT_CONFIG …
#define AD9523_VERSION_REGISTER …
#define AD9523_PART_REGISTER …
#define AD9523_READBACK_CTRL …
#define AD9523_EEPROM_CUSTOMER_VERSION_ID …
#define AD9523_PLL1_REF_A_DIVIDER …
#define AD9523_PLL1_REF_B_DIVIDER …
#define AD9523_PLL1_REF_TEST_DIVIDER …
#define AD9523_PLL1_FEEDBACK_DIVIDER …
#define AD9523_PLL1_CHARGE_PUMP_CTRL …
#define AD9523_PLL1_INPUT_RECEIVERS_CTRL …
#define AD9523_PLL1_REF_CTRL …
#define AD9523_PLL1_MISC_CTRL …
#define AD9523_PLL1_LOOP_FILTER_CTRL …
#define AD9523_PLL2_CHARGE_PUMP …
#define AD9523_PLL2_FEEDBACK_DIVIDER_AB …
#define AD9523_PLL2_CTRL …
#define AD9523_PLL2_VCO_CTRL …
#define AD9523_PLL2_VCO_DIVIDER …
#define AD9523_PLL2_LOOP_FILTER_CTRL …
#define AD9523_PLL2_R2_DIVIDER …
#define AD9523_CHANNEL_CLOCK_DIST(ch) …
#define AD9523_PLL1_OUTPUT_CTRL …
#define AD9523_PLL1_OUTPUT_CHANNEL_CTRL …
#define AD9523_READBACK_0 …
#define AD9523_READBACK_1 …
#define AD9523_STATUS_SIGNALS …
#define AD9523_POWER_DOWN_CTRL …
#define AD9523_IO_UPDATE …
#define AD9523_EEPROM_DATA_XFER_STATUS …
#define AD9523_EEPROM_ERROR_READBACK …
#define AD9523_EEPROM_CTRL1 …
#define AD9523_EEPROM_CTRL2 …
#define AD9523_SER_CONF_SDO_ACTIVE …
#define AD9523_SER_CONF_SOFT_RESET …
#define AD9523_READBACK_CTRL_READ_BUFFERED …
#define AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(x) …
#define AD9523_PLL1_CHARGE_PUMP_TRISTATE …
#define AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL …
#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_DOWN …
#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_UP …
#define AD9523_PLL1_CHARGE_PUMP_MODE_TRISTATE …
#define AD9523_PLL1_BACKLASH_PW_MIN …
#define AD9523_PLL1_BACKLASH_PW_LOW …
#define AD9523_PLL1_BACKLASH_PW_HIGH …
#define AD9523_PLL1_BACKLASH_PW_MAX …
#define AD9523_PLL1_REF_TEST_RCV_EN …
#define AD9523_PLL1_REFB_DIFF_RCV_EN …
#define AD9523_PLL1_REFA_DIFF_RCV_EN …
#define AD9523_PLL1_REFB_RCV_EN …
#define AD9523_PLL1_REFA_RCV_EN …
#define AD9523_PLL1_REFA_REFB_PWR_CTRL_EN …
#define AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN …
#define AD9523_PLL1_OSC_IN_DIFF_EN …
#define AD9523_PLL1_BYPASS_REF_TEST_DIV_EN …
#define AD9523_PLL1_BYPASS_FEEDBACK_DIV_EN …
#define AD9523_PLL1_ZERO_DELAY_MODE_INT …
#define AD9523_PLL1_ZERO_DELAY_MODE_EXT …
#define AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN …
#define AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN …
#define AD9523_PLL1_ZD_IN_DIFF_EN …
#define AD9523_PLL1_REFB_CMOS_NEG_INP_EN …
#define AD9523_PLL1_REFA_CMOS_NEG_INP_EN …
#define AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN …
#define AD9523_PLL1_OSC_CTRL_FAIL_VCC_BY2_EN …
#define AD9523_PLL1_REF_MODE(x) …
#define AD9523_PLL1_BYPASS_REFB_DIV …
#define AD9523_PLL1_BYPASS_REFA_DIV …
#define AD9523_PLL1_LOOP_FILTER_RZERO(x) …
#define AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(x) …
#define AD9523_PLL2_FB_NDIV_A_CNT(x) …
#define AD9523_PLL2_FB_NDIV_B_CNT(x) …
#define AD9523_PLL2_FB_NDIV(a, b) …
#define AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL …
#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_DOWN …
#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_UP …
#define AD9523_PLL2_CHARGE_PUMP_MODE_TRISTATE …
#define AD9523_PLL2_BACKLASH_PW_MIN …
#define AD9523_PLL2_BACKLASH_PW_LOW …
#define AD9523_PLL2_BACKLASH_PW_HIGH …
#define AD9523_PLL2_BACKLASH_PW_MAX …
#define AD9523_PLL2_BACKLASH_CTRL_EN …
#define AD9523_PLL2_FREQ_DOUBLER_EN …
#define AD9523_PLL2_LOCK_DETECT_PWR_DOWN_EN …
#define AD9523_PLL2_VCO_CALIBRATE …
#define AD9523_PLL2_FORCE_VCO_MIDSCALE …
#define AD9523_PLL2_FORCE_REFERENCE_VALID …
#define AD9523_PLL2_FORCE_RELEASE_SYNC …
#define AD9523_PLL2_VCO_DIV_M1(x) …
#define AD9523_PLL2_VCO_DIV_M2(x) …
#define AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN …
#define AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN …
#define AD9523_PLL2_LOOP_FILTER_CPOLE1(x) …
#define AD9523_PLL2_LOOP_FILTER_RZERO(x) …
#define AD9523_PLL2_LOOP_FILTER_RPOLE2(x) …
#define AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN …
#define AD9523_PLL2_R2_DIVIDER_VAL(x) …
#define AD9523_CLK_DIST_DIV_PHASE(x) …
#define AD9523_CLK_DIST_DIV_PHASE_REV(x) …
#define AD9523_CLK_DIST_DIV(x) …
#define AD9523_CLK_DIST_DIV_REV(x) …
#define AD9523_CLK_DIST_INV_DIV_OUTPUT_EN …
#define AD9523_CLK_DIST_IGNORE_SYNC_EN …
#define AD9523_CLK_DIST_PWR_DOWN_EN …
#define AD9523_CLK_DIST_LOW_PWR_MODE_EN …
#define AD9523_CLK_DIST_DRIVER_MODE(x) …
#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH6_M2 …
#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH5_M2 …
#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 …
#define AD9523_PLL1_OUTP_CTRL_CMOS_DRV_WEAK …
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_1 …
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_2 …
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_4 …
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_8 …
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_16 …
#define AD9523_PLL1_OUTP_CH_CTRL_OUTPUT_PWR_DOWN_EN …
#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH9_M2 …
#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH8_M2 …
#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 …
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH3 …
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH2 …
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH1 …
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 …
#define AD9523_READBACK_0_STAT_PLL2_REF_CLK …
#define AD9523_READBACK_0_STAT_PLL2_FB_CLK …
#define AD9523_READBACK_0_STAT_VCXO …
#define AD9523_READBACK_0_STAT_REF_TEST …
#define AD9523_READBACK_0_STAT_REFB …
#define AD9523_READBACK_0_STAT_REFA …
#define AD9523_READBACK_0_STAT_PLL2_LD …
#define AD9523_READBACK_0_STAT_PLL1_LD …
#define AD9523_READBACK_1_HOLDOVER_ACTIVE …
#define AD9523_READBACK_1_AUTOMODE_SEL_REFB …
#define AD9523_READBACK_1_VCO_CALIB_IN_PROGRESS …
#define AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL …
#define AD9523_STATUS_MONITOR_01_PLL12_LOCKED …
#define AD9523_POWER_DOWN_CTRL_PLL1_PWR_DOWN …
#define AD9523_POWER_DOWN_CTRL_PLL2_PWR_DOWN …
#define AD9523_POWER_DOWN_CTRL_DIST_PWR_DOWN …
#define AD9523_IO_UPDATE_EN …
#define AD9523_EEPROM_DATA_XFER_IN_PROGRESS …
#define AD9523_EEPROM_ERROR_READBACK_FAIL …
#define AD9523_EEPROM_CTRL1_SOFT_EEPROM …
#define AD9523_EEPROM_CTRL1_EEPROM_WRITE_PROT_DIS …
#define AD9523_EEPROM_CTRL2_REG2EEPROM …
#define AD9523_NUM_CHAN …
#define AD9523_NUM_CHAN_ALT_CLK_SRC …
#define AD_IFE(_pde, _a, _b) …
#define AD_IF(_pde, _a) …
enum { … };
enum { … };
struct ad9523_state { … };
static int ad9523_read(struct iio_dev *indio_dev, unsigned int addr)
{
struct ad9523_state *st = iio_priv(indio_dev);
int ret;
struct spi_transfer t[] = {
{
.tx_buf = &st->data[0].d8[2],
.len = 2,
}, {
.rx_buf = &st->data[1].d8[4 - AD9523_TRANSF_LEN(addr)],
.len = AD9523_TRANSF_LEN(addr),
},
};
st->data[0].d32 = cpu_to_be32(AD9523_READ |
AD9523_CNT(AD9523_TRANSF_LEN(addr)) |
AD9523_ADDR(addr));
ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
if (ret < 0)
dev_err(&indio_dev->dev, "read failed (%d)", ret);
else
ret = be32_to_cpu(st->data[1].d32) & (0xFFFFFF >>
(8 * (3 - AD9523_TRANSF_LEN(addr))));
return ret;
};
static int ad9523_write(struct iio_dev *indio_dev,
unsigned int addr, unsigned int val)
{ … }
static int ad9523_io_update(struct iio_dev *indio_dev)
{ … }
static int ad9523_vco_out_map(struct iio_dev *indio_dev,
unsigned int ch, unsigned int out)
{ … }
static int ad9523_set_clock_provider(struct iio_dev *indio_dev,
unsigned int ch, unsigned long freq)
{ … }
static int ad9523_store_eeprom(struct iio_dev *indio_dev)
{ … }
static int ad9523_sync(struct iio_dev *indio_dev)
{ … }
static ssize_t ad9523_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{ … }
static ssize_t ad9523_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static IIO_DEVICE_ATTR(pll1_locked, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_PLL1_LD);
static IIO_DEVICE_ATTR(pll2_locked, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_PLL2_LD);
static IIO_DEVICE_ATTR(pll1_reference_clk_a_present, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_REFA);
static IIO_DEVICE_ATTR(pll1_reference_clk_b_present, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_REFB);
static IIO_DEVICE_ATTR(pll1_reference_clk_test_present, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_REF_TEST);
static IIO_DEVICE_ATTR(vcxo_clk_present, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_VCXO);
static IIO_DEVICE_ATTR(pll2_feedback_clk_present, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_PLL2_FB_CLK);
static IIO_DEVICE_ATTR(pll2_reference_clk_present, S_IRUGO,
ad9523_show,
NULL,
AD9523_STAT_PLL2_REF_CLK);
static IIO_DEVICE_ATTR(sync_dividers, S_IWUSR,
NULL,
ad9523_store,
AD9523_SYNC);
static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR,
NULL,
ad9523_store,
AD9523_EEPROM);
static struct attribute *ad9523_attributes[] = …;
static const struct attribute_group ad9523_attribute_group = …;
static int ad9523_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
int *val2,
long m)
{
struct ad9523_state *st = iio_priv(indio_dev);
unsigned int code;
int ret;
mutex_lock(&st->lock);
ret = ad9523_read(indio_dev, AD9523_CHANNEL_CLOCK_DIST(chan->channel));
mutex_unlock(&st->lock);
if (ret < 0)
return ret;
switch (m) {
case IIO_CHAN_INFO_RAW:
*val = !(ret & AD9523_CLK_DIST_PWR_DOWN_EN);
return IIO_VAL_INT;
case IIO_CHAN_INFO_FREQUENCY:
*val = st->vco_out_freq[st->vco_out_map[chan->channel]] /
AD9523_CLK_DIST_DIV_REV(ret);
return IIO_VAL_INT;
case IIO_CHAN_INFO_PHASE:
code = (AD9523_CLK_DIST_DIV_PHASE_REV(ret) * 3141592) /
AD9523_CLK_DIST_DIV_REV(ret);
*val = code / 1000000;
*val2 = code % 1000000;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
};
static int ad9523_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val,
int val2,
long mask)
{ … }
static int ad9523_reg_access(struct iio_dev *indio_dev,
unsigned int reg, unsigned int writeval,
unsigned int *readval)
{ … }
static const struct iio_info ad9523_info = …;
static int ad9523_setup(struct iio_dev *indio_dev)
{ … }
static int ad9523_probe(struct spi_device *spi)
{ … }
static const struct spi_device_id ad9523_id[] = …;
MODULE_DEVICE_TABLE(spi, ad9523_id);
static struct spi_driver ad9523_driver = …;
module_spi_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;