cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ad5758.c (22722B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * AD5758 Digital to analog converters driver
      4 *
      5 * Copyright 2018 Analog Devices Inc.
      6 *
      7 * TODO: Currently CRC is not supported in this driver
      8 */
      9#include <linux/bsearch.h>
     10#include <linux/delay.h>
     11#include <linux/kernel.h>
     12#include <linux/module.h>
     13#include <linux/mod_devicetable.h>
     14#include <linux/property.h>
     15#include <linux/spi/spi.h>
     16#include <linux/gpio/consumer.h>
     17
     18#include <linux/iio/iio.h>
     19#include <linux/iio/sysfs.h>
     20
     21/* AD5758 registers definition */
     22#define AD5758_NOP				0x00
     23#define AD5758_DAC_INPUT			0x01
     24#define AD5758_DAC_OUTPUT			0x02
     25#define AD5758_CLEAR_CODE			0x03
     26#define AD5758_USER_GAIN			0x04
     27#define AD5758_USER_OFFSET			0x05
     28#define AD5758_DAC_CONFIG			0x06
     29#define AD5758_SW_LDAC				0x07
     30#define AD5758_KEY				0x08
     31#define AD5758_GP_CONFIG1			0x09
     32#define AD5758_GP_CONFIG2			0x0A
     33#define AD5758_DCDC_CONFIG1			0x0B
     34#define AD5758_DCDC_CONFIG2			0x0C
     35#define AD5758_WDT_CONFIG			0x0F
     36#define AD5758_DIGITAL_DIAG_CONFIG		0x10
     37#define AD5758_ADC_CONFIG			0x11
     38#define AD5758_FAULT_PIN_CONFIG			0x12
     39#define AD5758_TWO_STAGE_READBACK_SELECT	0x13
     40#define AD5758_DIGITAL_DIAG_RESULTS		0x14
     41#define AD5758_ANALOG_DIAG_RESULTS		0x15
     42#define AD5758_STATUS				0x16
     43#define AD5758_CHIP_ID				0x17
     44#define AD5758_FREQ_MONITOR			0x18
     45#define AD5758_DEVICE_ID_0			0x19
     46#define AD5758_DEVICE_ID_1			0x1A
     47#define AD5758_DEVICE_ID_2			0x1B
     48#define AD5758_DEVICE_ID_3			0x1C
     49
     50/* AD5758_DAC_CONFIG */
     51#define AD5758_DAC_CONFIG_RANGE_MSK		GENMASK(3, 0)
     52#define AD5758_DAC_CONFIG_RANGE_MODE(x)		(((x) & 0xF) << 0)
     53#define AD5758_DAC_CONFIG_INT_EN_MSK		BIT(5)
     54#define AD5758_DAC_CONFIG_INT_EN_MODE(x)	(((x) & 0x1) << 5)
     55#define AD5758_DAC_CONFIG_OUT_EN_MSK		BIT(6)
     56#define AD5758_DAC_CONFIG_OUT_EN_MODE(x)	(((x) & 0x1) << 6)
     57#define AD5758_DAC_CONFIG_SR_EN_MSK		BIT(8)
     58#define AD5758_DAC_CONFIG_SR_EN_MODE(x)		(((x) & 0x1) << 8)
     59#define AD5758_DAC_CONFIG_SR_CLOCK_MSK		GENMASK(12, 9)
     60#define AD5758_DAC_CONFIG_SR_CLOCK_MODE(x)	(((x) & 0xF) << 9)
     61#define AD5758_DAC_CONFIG_SR_STEP_MSK		GENMASK(15, 13)
     62#define AD5758_DAC_CONFIG_SR_STEP_MODE(x)	(((x) & 0x7) << 13)
     63
     64/* AD5758_KEY */
     65#define AD5758_KEY_CODE_RESET_1			0x15FA
     66#define AD5758_KEY_CODE_RESET_2			0xAF51
     67#define AD5758_KEY_CODE_SINGLE_ADC_CONV		0x1ADC
     68#define AD5758_KEY_CODE_RESET_WDT		0x0D06
     69#define AD5758_KEY_CODE_CALIB_MEM_REFRESH	0xFCBA
     70
     71/* AD5758_DCDC_CONFIG1 */
     72#define AD5758_DCDC_CONFIG1_DCDC_VPROG_MSK	GENMASK(4, 0)
     73#define AD5758_DCDC_CONFIG1_DCDC_VPROG_MODE(x)	(((x) & 0x1F) << 0)
     74#define AD5758_DCDC_CONFIG1_DCDC_MODE_MSK	GENMASK(6, 5)
     75#define AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(x)	(((x) & 0x3) << 5)
     76
     77/* AD5758_DCDC_CONFIG2 */
     78#define AD5758_DCDC_CONFIG2_ILIMIT_MSK		GENMASK(3, 1)
     79#define AD5758_DCDC_CONFIG2_ILIMIT_MODE(x)	(((x) & 0x7) << 1)
     80#define AD5758_DCDC_CONFIG2_INTR_SAT_3WI_MSK	BIT(11)
     81#define AD5758_DCDC_CONFIG2_BUSY_3WI_MSK	BIT(12)
     82
     83/* AD5758_DIGITAL_DIAG_RESULTS */
     84#define AD5758_CAL_MEM_UNREFRESHED_MSK		BIT(15)
     85
     86/* AD5758_ADC_CONFIG */
     87#define AD5758_ADC_CONFIG_PPC_BUF_EN(x)		(((x) & 0x1) << 11)
     88#define AD5758_ADC_CONFIG_PPC_BUF_MSK		BIT(11)
     89
     90#define AD5758_WR_FLAG_MSK(x)		(0x80 | ((x) & 0x1F))
     91
     92#define AD5758_FULL_SCALE_MICRO	65535000000ULL
     93
     94struct ad5758_range {
     95	int reg;
     96	int min;
     97	int max;
     98};
     99
    100/**
    101 * struct ad5758_state - driver instance specific data
    102 * @spi:	spi_device
    103 * @lock:	mutex lock
    104 * @gpio_reset:	gpio descriptor for the reset line
    105 * @out_range:	struct which stores the output range
    106 * @dc_dc_mode:	variable which stores the mode of operation
    107 * @dc_dc_ilim:	variable which stores the dc-to-dc converter current limit
    108 * @slew_time:	variable which stores the target slew time
    109 * @pwr_down:	variable which contains whether a channel is powered down or not
    110 * @d32:	spi transfer buffers
    111 */
    112struct ad5758_state {
    113	struct spi_device *spi;
    114	struct mutex lock;
    115	struct gpio_desc *gpio_reset;
    116	struct ad5758_range out_range;
    117	unsigned int dc_dc_mode;
    118	unsigned int dc_dc_ilim;
    119	unsigned int slew_time;
    120	bool pwr_down;
    121	__be32 d32[3];
    122};
    123
    124/*
    125 * Output ranges corresponding to bits [3:0] from DAC_CONFIG register
    126 * 0000: 0 V to 5 V voltage range
    127 * 0001: 0 V to 10 V voltage range
    128 * 0010: ±5 V voltage range
    129 * 0011: ±10 V voltage range
    130 * 1000: 0 mA to 20 mA current range
    131 * 1001: 0 mA to 24 mA current range
    132 * 1010: 4 mA to 20 mA current range
    133 * 1011: ±20 mA current range
    134 * 1100: ±24 mA current range
    135 * 1101: -1 mA to +22 mA current range
    136 */
    137enum ad5758_output_range {
    138	AD5758_RANGE_0V_5V,
    139	AD5758_RANGE_0V_10V,
    140	AD5758_RANGE_PLUSMINUS_5V,
    141	AD5758_RANGE_PLUSMINUS_10V,
    142	AD5758_RANGE_0mA_20mA = 8,
    143	AD5758_RANGE_0mA_24mA,
    144	AD5758_RANGE_4mA_24mA,
    145	AD5758_RANGE_PLUSMINUS_20mA,
    146	AD5758_RANGE_PLUSMINUS_24mA,
    147	AD5758_RANGE_MINUS_1mA_PLUS_22mA,
    148};
    149
    150enum ad5758_dc_dc_mode {
    151	AD5758_DCDC_MODE_POWER_OFF,
    152	AD5758_DCDC_MODE_DPC_CURRENT,
    153	AD5758_DCDC_MODE_DPC_VOLTAGE,
    154	AD5758_DCDC_MODE_PPC_CURRENT,
    155};
    156
    157static const struct ad5758_range ad5758_voltage_range[] = {
    158	{ AD5758_RANGE_0V_5V, 0, 5000000 },
    159	{ AD5758_RANGE_0V_10V, 0, 10000000 },
    160	{ AD5758_RANGE_PLUSMINUS_5V, -5000000, 5000000 },
    161	{ AD5758_RANGE_PLUSMINUS_10V, -10000000, 10000000 }
    162};
    163
    164static const struct ad5758_range ad5758_current_range[] = {
    165	{ AD5758_RANGE_0mA_20mA, 0, 20000},
    166	{ AD5758_RANGE_0mA_24mA, 0, 24000 },
    167	{ AD5758_RANGE_4mA_24mA, 4, 24000 },
    168	{ AD5758_RANGE_PLUSMINUS_20mA, -20000, 20000 },
    169	{ AD5758_RANGE_PLUSMINUS_24mA, -24000, 24000 },
    170	{ AD5758_RANGE_MINUS_1mA_PLUS_22mA, -1000, 22000 },
    171};
    172
    173static const int ad5758_sr_clk[16] = {
    174	240000, 200000, 150000, 128000, 64000, 32000, 16000, 8000, 4000, 2000,
    175	1000, 512, 256, 128, 64, 16
    176};
    177
    178static const int ad5758_sr_step[8] = {
    179	4, 12, 64, 120, 256, 500, 1820, 2048
    180};
    181
    182static const int ad5758_dc_dc_ilim[6] = {
    183	150000, 200000, 250000, 300000, 350000, 400000
    184};
    185
    186static int ad5758_spi_reg_read(struct ad5758_state *st, unsigned int addr)
    187{
    188	struct spi_transfer t[] = {
    189		{
    190			.tx_buf = &st->d32[0],
    191			.len = 4,
    192			.cs_change = 1,
    193		}, {
    194			.tx_buf = &st->d32[1],
    195			.rx_buf = &st->d32[2],
    196			.len = 4,
    197		},
    198	};
    199	int ret;
    200
    201	st->d32[0] = cpu_to_be32(
    202		(AD5758_WR_FLAG_MSK(AD5758_TWO_STAGE_READBACK_SELECT) << 24) |
    203		(addr << 8));
    204	st->d32[1] = cpu_to_be32(AD5758_WR_FLAG_MSK(AD5758_NOP) << 24);
    205
    206	ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
    207	if (ret < 0)
    208		return ret;
    209
    210	return (be32_to_cpu(st->d32[2]) >> 8) & 0xFFFF;
    211}
    212
    213static int ad5758_spi_reg_write(struct ad5758_state *st,
    214				unsigned int addr,
    215				unsigned int val)
    216{
    217	st->d32[0] = cpu_to_be32((AD5758_WR_FLAG_MSK(addr) << 24) |
    218				 ((val & 0xFFFF) << 8));
    219
    220	return spi_write(st->spi, &st->d32[0], sizeof(st->d32[0]));
    221}
    222
    223static int ad5758_spi_write_mask(struct ad5758_state *st,
    224				 unsigned int addr,
    225				 unsigned long int mask,
    226				 unsigned int val)
    227{
    228	int regval;
    229
    230	regval = ad5758_spi_reg_read(st, addr);
    231	if (regval < 0)
    232		return regval;
    233
    234	regval &= ~mask;
    235	regval |= val;
    236
    237	return ad5758_spi_reg_write(st, addr, regval);
    238}
    239
    240static int cmpfunc(const void *a, const void *b)
    241{
    242	return *(int *)a - *(int *)b;
    243}
    244
    245static int ad5758_find_closest_match(const int *array,
    246				     unsigned int size, int val)
    247{
    248	int i;
    249
    250	for (i = 0; i < size; i++) {
    251		if (val <= array[i])
    252			return i;
    253	}
    254
    255	return size - 1;
    256}
    257
    258static int ad5758_wait_for_task_complete(struct ad5758_state *st,
    259					 unsigned int reg,
    260					 unsigned int mask)
    261{
    262	unsigned int timeout;
    263	int ret;
    264
    265	timeout = 10;
    266	do {
    267		ret = ad5758_spi_reg_read(st, reg);
    268		if (ret < 0)
    269			return ret;
    270
    271		if (!(ret & mask))
    272			return 0;
    273
    274		usleep_range(100, 1000);
    275	} while (--timeout);
    276
    277	dev_err(&st->spi->dev,
    278		"Error reading bit 0x%x in 0x%x register\n", mask, reg);
    279
    280	return -EIO;
    281}
    282
    283static int ad5758_calib_mem_refresh(struct ad5758_state *st)
    284{
    285	int ret;
    286
    287	ret = ad5758_spi_reg_write(st, AD5758_KEY,
    288				   AD5758_KEY_CODE_CALIB_MEM_REFRESH);
    289	if (ret < 0) {
    290		dev_err(&st->spi->dev,
    291			"Failed to initiate a calibration memory refresh\n");
    292		return ret;
    293	}
    294
    295	/* Wait to allow time for the internal calibrations to complete */
    296	return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
    297					     AD5758_CAL_MEM_UNREFRESHED_MSK);
    298}
    299
    300static int ad5758_soft_reset(struct ad5758_state *st)
    301{
    302	int ret;
    303
    304	ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_1);
    305	if (ret < 0)
    306		return ret;
    307
    308	ret = ad5758_spi_reg_write(st, AD5758_KEY, AD5758_KEY_CODE_RESET_2);
    309
    310	/* Perform a software reset and wait at least 100us */
    311	usleep_range(100, 1000);
    312
    313	return ret;
    314}
    315
    316static int ad5758_set_dc_dc_conv_mode(struct ad5758_state *st,
    317				      enum ad5758_dc_dc_mode mode)
    318{
    319	int ret;
    320
    321	/*
    322	 * The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current
    323	 * mode.
    324	 */
    325	if (mode == AD5758_DCDC_MODE_PPC_CURRENT) {
    326		ret  = ad5758_spi_write_mask(st, AD5758_ADC_CONFIG,
    327				    AD5758_ADC_CONFIG_PPC_BUF_MSK,
    328				    AD5758_ADC_CONFIG_PPC_BUF_EN(1));
    329		if (ret < 0)
    330			return ret;
    331	}
    332
    333	ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1,
    334				    AD5758_DCDC_CONFIG1_DCDC_MODE_MSK,
    335				    AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode));
    336	if (ret < 0)
    337		return ret;
    338
    339	/*
    340	 * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.
    341	 * This allows the 3-wire interface communication to complete.
    342	 */
    343	ret = ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,
    344					    AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);
    345	if (ret < 0)
    346		return ret;
    347
    348	st->dc_dc_mode = mode;
    349
    350	return ret;
    351}
    352
    353static int ad5758_set_dc_dc_ilim(struct ad5758_state *st, unsigned int ilim)
    354{
    355	int ret;
    356
    357	ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG2,
    358				    AD5758_DCDC_CONFIG2_ILIMIT_MSK,
    359				    AD5758_DCDC_CONFIG2_ILIMIT_MODE(ilim));
    360	if (ret < 0)
    361		return ret;
    362	/*
    363	 * Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.
    364	 * This allows the 3-wire interface communication to complete.
    365	 */
    366	return ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,
    367					     AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);
    368}
    369
    370static int ad5758_slew_rate_set(struct ad5758_state *st,
    371				unsigned int sr_clk_idx,
    372				unsigned int sr_step_idx)
    373{
    374	unsigned int mode;
    375	unsigned long int mask;
    376	int ret;
    377
    378	mask = AD5758_DAC_CONFIG_SR_EN_MSK |
    379	       AD5758_DAC_CONFIG_SR_CLOCK_MSK |
    380	       AD5758_DAC_CONFIG_SR_STEP_MSK;
    381	mode = AD5758_DAC_CONFIG_SR_EN_MODE(1) |
    382	       AD5758_DAC_CONFIG_SR_STEP_MODE(sr_step_idx) |
    383	       AD5758_DAC_CONFIG_SR_CLOCK_MODE(sr_clk_idx);
    384
    385	ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG, mask, mode);
    386	if (ret < 0)
    387		return ret;
    388
    389	/* Wait to allow time for the internal calibrations to complete */
    390	return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
    391					     AD5758_CAL_MEM_UNREFRESHED_MSK);
    392}
    393
    394static int ad5758_slew_rate_config(struct ad5758_state *st)
    395{
    396	unsigned int sr_clk_idx, sr_step_idx;
    397	int i, res;
    398	s64 diff_new, diff_old;
    399	u64 sr_step, calc_slew_time;
    400
    401	sr_clk_idx = 0;
    402	sr_step_idx = 0;
    403	diff_old = S64_MAX;
    404	/*
    405	 * The slew time can be determined by using the formula:
    406	 * Slew Time = (Full Scale Out / (Step Size x Update Clk Freq))
    407	 * where Slew time is expressed in microseconds
    408	 * Given the desired slew time, the following algorithm determines the
    409	 * best match for the step size and the update clock frequency.
    410	 */
    411	for (i = 0; i < ARRAY_SIZE(ad5758_sr_clk); i++) {
    412		/*
    413		 * Go through each valid update clock freq and determine a raw
    414		 * value for the step size by using the formula:
    415		 * Step Size = Full Scale Out / (Update Clk Freq * Slew Time)
    416		 */
    417		sr_step = AD5758_FULL_SCALE_MICRO;
    418		do_div(sr_step, ad5758_sr_clk[i]);
    419		do_div(sr_step, st->slew_time);
    420		/*
    421		 * After a raw value for step size was determined, find the
    422		 * closest valid match
    423		 */
    424		res = ad5758_find_closest_match(ad5758_sr_step,
    425						ARRAY_SIZE(ad5758_sr_step),
    426						sr_step);
    427		/* Calculate the slew time */
    428		calc_slew_time = AD5758_FULL_SCALE_MICRO;
    429		do_div(calc_slew_time, ad5758_sr_step[res]);
    430		do_div(calc_slew_time, ad5758_sr_clk[i]);
    431		/*
    432		 * Determine with how many microseconds the calculated slew time
    433		 * is different from the desired slew time and store the diff
    434		 * for the next iteration
    435		 */
    436		diff_new = abs(st->slew_time - calc_slew_time);
    437		if (diff_new < diff_old) {
    438			diff_old = diff_new;
    439			sr_clk_idx = i;
    440			sr_step_idx = res;
    441		}
    442	}
    443
    444	return ad5758_slew_rate_set(st, sr_clk_idx, sr_step_idx);
    445}
    446
    447static int ad5758_set_out_range(struct ad5758_state *st, int range)
    448{
    449	int ret;
    450
    451	ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
    452				    AD5758_DAC_CONFIG_RANGE_MSK,
    453				    AD5758_DAC_CONFIG_RANGE_MODE(range));
    454	if (ret < 0)
    455		return ret;
    456
    457	/* Wait to allow time for the internal calibrations to complete */
    458	return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
    459					     AD5758_CAL_MEM_UNREFRESHED_MSK);
    460}
    461
    462static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable)
    463{
    464	int ret;
    465
    466	ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
    467				    AD5758_DAC_CONFIG_INT_EN_MSK,
    468				    AD5758_DAC_CONFIG_INT_EN_MODE(enable));
    469	if (ret < 0)
    470		return ret;
    471
    472	/* Wait to allow time for the internal calibrations to complete */
    473	return ad5758_wait_for_task_complete(st, AD5758_DIGITAL_DIAG_RESULTS,
    474					     AD5758_CAL_MEM_UNREFRESHED_MSK);
    475}
    476
    477static int ad5758_reset(struct ad5758_state *st)
    478{
    479	if (st->gpio_reset) {
    480		gpiod_set_value(st->gpio_reset, 0);
    481		usleep_range(100, 1000);
    482		gpiod_set_value(st->gpio_reset, 1);
    483		usleep_range(100, 1000);
    484
    485		return 0;
    486	} else {
    487		/* Perform a software reset */
    488		return ad5758_soft_reset(st);
    489	}
    490}
    491
    492static int ad5758_reg_access(struct iio_dev *indio_dev,
    493			     unsigned int reg,
    494			     unsigned int writeval,
    495			     unsigned int *readval)
    496{
    497	struct ad5758_state *st = iio_priv(indio_dev);
    498	int ret;
    499
    500	mutex_lock(&st->lock);
    501	if (readval) {
    502		ret = ad5758_spi_reg_read(st, reg);
    503		if (ret < 0) {
    504			mutex_unlock(&st->lock);
    505			return ret;
    506		}
    507
    508		*readval = ret;
    509		ret = 0;
    510	} else {
    511		ret = ad5758_spi_reg_write(st, reg, writeval);
    512	}
    513	mutex_unlock(&st->lock);
    514
    515	return ret;
    516}
    517
    518static int ad5758_read_raw(struct iio_dev *indio_dev,
    519			   struct iio_chan_spec const *chan,
    520			   int *val, int *val2, long info)
    521{
    522	struct ad5758_state *st = iio_priv(indio_dev);
    523	int max, min, ret;
    524
    525	switch (info) {
    526	case IIO_CHAN_INFO_RAW:
    527		mutex_lock(&st->lock);
    528		ret = ad5758_spi_reg_read(st, AD5758_DAC_INPUT);
    529		mutex_unlock(&st->lock);
    530		if (ret < 0)
    531			return ret;
    532
    533		*val = ret;
    534		return IIO_VAL_INT;
    535	case IIO_CHAN_INFO_SCALE:
    536		min = st->out_range.min;
    537		max = st->out_range.max;
    538		*val = (max - min) / 1000;
    539		*val2 = 16;
    540		return IIO_VAL_FRACTIONAL_LOG2;
    541	case IIO_CHAN_INFO_OFFSET:
    542		min = st->out_range.min;
    543		max = st->out_range.max;
    544		*val = ((min * (1 << 16)) / (max - min)) / 1000;
    545		return IIO_VAL_INT;
    546	default:
    547		return -EINVAL;
    548	}
    549}
    550
    551static int ad5758_write_raw(struct iio_dev *indio_dev,
    552			    struct iio_chan_spec const *chan,
    553			    int val, int val2, long info)
    554{
    555	struct ad5758_state *st = iio_priv(indio_dev);
    556	int ret;
    557
    558	switch (info) {
    559	case IIO_CHAN_INFO_RAW:
    560		mutex_lock(&st->lock);
    561		ret = ad5758_spi_reg_write(st, AD5758_DAC_INPUT, val);
    562		mutex_unlock(&st->lock);
    563		return ret;
    564	default:
    565		return -EINVAL;
    566	}
    567}
    568
    569static ssize_t ad5758_read_powerdown(struct iio_dev *indio_dev,
    570				     uintptr_t priv,
    571				     const struct iio_chan_spec *chan,
    572				     char *buf)
    573{
    574	struct ad5758_state *st = iio_priv(indio_dev);
    575
    576	return sysfs_emit(buf, "%d\n", st->pwr_down);
    577}
    578
    579static ssize_t ad5758_write_powerdown(struct iio_dev *indio_dev,
    580				      uintptr_t priv,
    581				      struct iio_chan_spec const *chan,
    582				      const char *buf, size_t len)
    583{
    584	struct ad5758_state *st = iio_priv(indio_dev);
    585	bool pwr_down;
    586	unsigned int dac_config_mode, val;
    587	unsigned long int dac_config_msk;
    588	int ret;
    589
    590	ret = kstrtobool(buf, &pwr_down);
    591	if (ret)
    592		return ret;
    593
    594	mutex_lock(&st->lock);
    595	if (pwr_down)
    596		val = 0;
    597	else
    598		val = 1;
    599
    600	dac_config_mode = AD5758_DAC_CONFIG_OUT_EN_MODE(val) |
    601			  AD5758_DAC_CONFIG_INT_EN_MODE(val);
    602	dac_config_msk = AD5758_DAC_CONFIG_OUT_EN_MSK |
    603			 AD5758_DAC_CONFIG_INT_EN_MSK;
    604
    605	ret = ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
    606				    dac_config_msk,
    607				    dac_config_mode);
    608	if (ret < 0)
    609		goto err_unlock;
    610
    611	st->pwr_down = pwr_down;
    612
    613err_unlock:
    614	mutex_unlock(&st->lock);
    615
    616	return ret ? ret : len;
    617}
    618
    619static const struct iio_info ad5758_info = {
    620	.read_raw = ad5758_read_raw,
    621	.write_raw = ad5758_write_raw,
    622	.debugfs_reg_access = &ad5758_reg_access,
    623};
    624
    625static const struct iio_chan_spec_ext_info ad5758_ext_info[] = {
    626	{
    627		.name = "powerdown",
    628		.read = ad5758_read_powerdown,
    629		.write = ad5758_write_powerdown,
    630		.shared = IIO_SHARED_BY_TYPE,
    631	},
    632	{ }
    633};
    634
    635#define AD5758_DAC_CHAN(_chan_type) {				\
    636	.type = (_chan_type),					\
    637	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_RAW) |	\
    638		BIT(IIO_CHAN_INFO_SCALE) |			\
    639		BIT(IIO_CHAN_INFO_OFFSET),			\
    640	.indexed = 1,						\
    641	.output = 1,						\
    642	.ext_info = ad5758_ext_info,				\
    643}
    644
    645static const struct iio_chan_spec ad5758_voltage_ch[] = {
    646	AD5758_DAC_CHAN(IIO_VOLTAGE)
    647};
    648
    649static const struct iio_chan_spec ad5758_current_ch[] = {
    650	AD5758_DAC_CHAN(IIO_CURRENT)
    651};
    652
    653static bool ad5758_is_valid_mode(enum ad5758_dc_dc_mode mode)
    654{
    655	switch (mode) {
    656	case AD5758_DCDC_MODE_DPC_CURRENT:
    657	case AD5758_DCDC_MODE_DPC_VOLTAGE:
    658	case AD5758_DCDC_MODE_PPC_CURRENT:
    659		return true;
    660	default:
    661		return false;
    662	}
    663}
    664
    665static int ad5758_crc_disable(struct ad5758_state *st)
    666{
    667	unsigned int mask;
    668
    669	mask = (AD5758_WR_FLAG_MSK(AD5758_DIGITAL_DIAG_CONFIG) << 24) | 0x5C3A;
    670	st->d32[0] = cpu_to_be32(mask);
    671
    672	return spi_write(st->spi, &st->d32[0], 4);
    673}
    674
    675static int ad5758_find_out_range(struct ad5758_state *st,
    676				 const struct ad5758_range *range,
    677				 unsigned int size,
    678				 int min, int max)
    679{
    680	int i;
    681
    682	for (i = 0; i < size; i++) {
    683		if ((min == range[i].min) && (max == range[i].max)) {
    684			st->out_range.reg = range[i].reg;
    685			st->out_range.min = range[i].min;
    686			st->out_range.max = range[i].max;
    687
    688			return 0;
    689		}
    690	}
    691
    692	return -EINVAL;
    693}
    694
    695static int ad5758_parse_dt(struct ad5758_state *st)
    696{
    697	unsigned int tmp, tmparray[2], size;
    698	const struct ad5758_range *range;
    699	int *index, ret;
    700
    701	st->dc_dc_ilim = 0;
    702	ret = device_property_read_u32(&st->spi->dev,
    703				       "adi,dc-dc-ilim-microamp", &tmp);
    704	if (ret) {
    705		dev_dbg(&st->spi->dev,
    706			"Missing \"dc-dc-ilim-microamp\" property\n");
    707	} else {
    708		index = bsearch(&tmp, ad5758_dc_dc_ilim,
    709				ARRAY_SIZE(ad5758_dc_dc_ilim),
    710				sizeof(int), cmpfunc);
    711		if (!index)
    712			dev_dbg(&st->spi->dev, "dc-dc-ilim out of range\n");
    713		else
    714			st->dc_dc_ilim = index - ad5758_dc_dc_ilim;
    715	}
    716
    717	ret = device_property_read_u32(&st->spi->dev, "adi,dc-dc-mode",
    718				       &st->dc_dc_mode);
    719	if (ret) {
    720		dev_err(&st->spi->dev, "Missing \"dc-dc-mode\" property\n");
    721		return ret;
    722	}
    723
    724	if (!ad5758_is_valid_mode(st->dc_dc_mode))
    725		return -EINVAL;
    726
    727	if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE) {
    728		ret = device_property_read_u32_array(&st->spi->dev,
    729						     "adi,range-microvolt",
    730						     tmparray, 2);
    731		if (ret) {
    732			dev_err(&st->spi->dev,
    733				"Missing \"range-microvolt\" property\n");
    734			return ret;
    735		}
    736		range = ad5758_voltage_range;
    737		size = ARRAY_SIZE(ad5758_voltage_range);
    738	} else {
    739		ret = device_property_read_u32_array(&st->spi->dev,
    740						     "adi,range-microamp",
    741						     tmparray, 2);
    742		if (ret) {
    743			dev_err(&st->spi->dev,
    744				"Missing \"range-microamp\" property\n");
    745			return ret;
    746		}
    747		range = ad5758_current_range;
    748		size = ARRAY_SIZE(ad5758_current_range);
    749	}
    750
    751	ret = ad5758_find_out_range(st, range, size, tmparray[0], tmparray[1]);
    752	if (ret) {
    753		dev_err(&st->spi->dev, "range invalid\n");
    754		return ret;
    755	}
    756
    757	ret = device_property_read_u32(&st->spi->dev, "adi,slew-time-us", &tmp);
    758	if (ret) {
    759		dev_dbg(&st->spi->dev, "Missing \"slew-time-us\" property\n");
    760		st->slew_time = 0;
    761	} else {
    762		st->slew_time = tmp;
    763	}
    764
    765	return 0;
    766}
    767
    768static int ad5758_init(struct ad5758_state *st)
    769{
    770	int regval, ret;
    771
    772	st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",
    773						 GPIOD_OUT_HIGH);
    774	if (IS_ERR(st->gpio_reset))
    775		return PTR_ERR(st->gpio_reset);
    776
    777	/* Disable CRC checks */
    778	ret = ad5758_crc_disable(st);
    779	if (ret < 0)
    780		return ret;
    781
    782	/* Perform a reset */
    783	ret = ad5758_reset(st);
    784	if (ret < 0)
    785		return ret;
    786
    787	/* Disable CRC checks */
    788	ret = ad5758_crc_disable(st);
    789	if (ret < 0)
    790		return ret;
    791
    792	/* Perform a calibration memory refresh */
    793	ret = ad5758_calib_mem_refresh(st);
    794	if (ret < 0)
    795		return ret;
    796
    797	regval = ad5758_spi_reg_read(st, AD5758_DIGITAL_DIAG_RESULTS);
    798	if (regval < 0)
    799		return regval;
    800
    801	/* Clear all the error flags */
    802	ret = ad5758_spi_reg_write(st, AD5758_DIGITAL_DIAG_RESULTS, regval);
    803	if (ret < 0)
    804		return ret;
    805
    806	/* Set the dc-to-dc current limit */
    807	ret = ad5758_set_dc_dc_ilim(st, st->dc_dc_ilim);
    808	if (ret < 0)
    809		return ret;
    810
    811	/* Configure the dc-to-dc controller mode */
    812	ret = ad5758_set_dc_dc_conv_mode(st, st->dc_dc_mode);
    813	if (ret < 0)
    814		return ret;
    815
    816	/* Configure the output range */
    817	ret = ad5758_set_out_range(st, st->out_range.reg);
    818	if (ret < 0)
    819		return ret;
    820
    821	/* Enable Slew Rate Control, set the slew rate clock and step */
    822	if (st->slew_time) {
    823		ret = ad5758_slew_rate_config(st);
    824		if (ret < 0)
    825			return ret;
    826	}
    827
    828	/* Power up the DAC and internal (INT) amplifiers */
    829	ret = ad5758_internal_buffers_en(st, 1);
    830	if (ret < 0)
    831		return ret;
    832
    833	/* Enable VIOUT */
    834	return ad5758_spi_write_mask(st, AD5758_DAC_CONFIG,
    835				     AD5758_DAC_CONFIG_OUT_EN_MSK,
    836				     AD5758_DAC_CONFIG_OUT_EN_MODE(1));
    837}
    838
    839static int ad5758_probe(struct spi_device *spi)
    840{
    841	struct ad5758_state *st;
    842	struct iio_dev *indio_dev;
    843	int ret;
    844
    845	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
    846	if (!indio_dev)
    847		return -ENOMEM;
    848
    849	st = iio_priv(indio_dev);
    850	spi_set_drvdata(spi, indio_dev);
    851
    852	st->spi = spi;
    853
    854	mutex_init(&st->lock);
    855
    856	indio_dev->name = spi_get_device_id(spi)->name;
    857	indio_dev->info = &ad5758_info;
    858	indio_dev->modes = INDIO_DIRECT_MODE;
    859	indio_dev->num_channels = 1;
    860
    861	ret = ad5758_parse_dt(st);
    862	if (ret < 0)
    863		return ret;
    864
    865	if (st->dc_dc_mode == AD5758_DCDC_MODE_DPC_VOLTAGE)
    866		indio_dev->channels = ad5758_voltage_ch;
    867	else
    868		indio_dev->channels = ad5758_current_ch;
    869
    870	ret = ad5758_init(st);
    871	if (ret < 0) {
    872		dev_err(&spi->dev, "AD5758 init failed\n");
    873		return ret;
    874	}
    875
    876	return devm_iio_device_register(&st->spi->dev, indio_dev);
    877}
    878
    879static const struct spi_device_id ad5758_id[] = {
    880	{ "ad5758", 0 },
    881	{}
    882};
    883MODULE_DEVICE_TABLE(spi, ad5758_id);
    884
    885static const struct of_device_id ad5758_of_match[] = {
    886        { .compatible = "adi,ad5758" },
    887        { },
    888};
    889MODULE_DEVICE_TABLE(of, ad5758_of_match);
    890
    891static struct spi_driver ad5758_driver = {
    892	.driver = {
    893		.name = KBUILD_MODNAME,
    894		.of_match_table = ad5758_of_match,
    895	},
    896	.probe = ad5758_probe,
    897	.id_table = ad5758_id,
    898};
    899
    900module_spi_driver(ad5758_driver);
    901
    902MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
    903MODULE_DESCRIPTION("Analog Devices AD5758 DAC");
    904MODULE_LICENSE("GPL v2");