| /* | 
 |  * AD5755, AD5755-1, AD5757, AD5735, AD5737 Digital to analog converters driver | 
 |  * | 
 |  * Copyright 2012 Analog Devices Inc. | 
 |  * | 
 |  * Licensed under the GPL-2. | 
 |  */ | 
 |  | 
 | #include <linux/device.h> | 
 | #include <linux/err.h> | 
 | #include <linux/module.h> | 
 | #include <linux/kernel.h> | 
 | #include <linux/spi/spi.h> | 
 | #include <linux/slab.h> | 
 | #include <linux/sysfs.h> | 
 | #include <linux/delay.h> | 
 | #include <linux/of.h> | 
 | #include <linux/iio/iio.h> | 
 | #include <linux/iio/sysfs.h> | 
 | #include <linux/platform_data/ad5755.h> | 
 |  | 
 | #define AD5755_NUM_CHANNELS 4 | 
 |  | 
 | #define AD5755_ADDR(x)			((x) << 16) | 
 |  | 
 | #define AD5755_WRITE_REG_DATA(chan)	(chan) | 
 | #define AD5755_WRITE_REG_GAIN(chan)	(0x08 | (chan)) | 
 | #define AD5755_WRITE_REG_OFFSET(chan)	(0x10 | (chan)) | 
 | #define AD5755_WRITE_REG_CTRL(chan)	(0x1c | (chan)) | 
 |  | 
 | #define AD5755_READ_REG_DATA(chan)	(chan) | 
 | #define AD5755_READ_REG_CTRL(chan)	(0x4 | (chan)) | 
 | #define AD5755_READ_REG_GAIN(chan)	(0x8 | (chan)) | 
 | #define AD5755_READ_REG_OFFSET(chan)	(0xc | (chan)) | 
 | #define AD5755_READ_REG_CLEAR(chan)	(0x10 | (chan)) | 
 | #define AD5755_READ_REG_SLEW(chan)	(0x14 | (chan)) | 
 | #define AD5755_READ_REG_STATUS		0x18 | 
 | #define AD5755_READ_REG_MAIN		0x19 | 
 | #define AD5755_READ_REG_DC_DC		0x1a | 
 |  | 
 | #define AD5755_CTRL_REG_SLEW	0x0 | 
 | #define AD5755_CTRL_REG_MAIN	0x1 | 
 | #define AD5755_CTRL_REG_DAC	0x2 | 
 | #define AD5755_CTRL_REG_DC_DC	0x3 | 
 | #define AD5755_CTRL_REG_SW	0x4 | 
 |  | 
 | #define AD5755_READ_FLAG 0x800000 | 
 |  | 
 | #define AD5755_NOOP 0x1CE000 | 
 |  | 
 | #define AD5755_DAC_INT_EN			BIT(8) | 
 | #define AD5755_DAC_CLR_EN			BIT(7) | 
 | #define AD5755_DAC_OUT_EN			BIT(6) | 
 | #define AD5755_DAC_INT_CURRENT_SENSE_RESISTOR	BIT(5) | 
 | #define AD5755_DAC_DC_DC_EN			BIT(4) | 
 | #define AD5755_DAC_VOLTAGE_OVERRANGE_EN		BIT(3) | 
 |  | 
 | #define AD5755_DC_DC_MAXV			0 | 
 | #define AD5755_DC_DC_FREQ_SHIFT			2 | 
 | #define AD5755_DC_DC_PHASE_SHIFT		4 | 
 | #define AD5755_EXT_DC_DC_COMP_RES		BIT(6) | 
 |  | 
 | #define AD5755_SLEW_STEP_SIZE_SHIFT		0 | 
 | #define AD5755_SLEW_RATE_SHIFT			3 | 
 | #define AD5755_SLEW_ENABLE			BIT(12) | 
 |  | 
 | /** | 
 |  * struct ad5755_chip_info - chip specific information | 
 |  * @channel_template:	channel specification | 
 |  * @calib_shift:	shift for the calibration data registers | 
 |  * @has_voltage_out:	whether the chip has voltage outputs | 
 |  */ | 
 | struct ad5755_chip_info { | 
 | 	const struct iio_chan_spec channel_template; | 
 | 	unsigned int calib_shift; | 
 | 	bool has_voltage_out; | 
 | }; | 
 |  | 
 | /** | 
 |  * struct ad5755_state - driver instance specific data | 
 |  * @spi:	spi device the driver is attached to | 
 |  * @chip_info:	chip model specific constants, available modes etc | 
 |  * @pwr_down:	bitmask which contains  hether a channel is powered down or not | 
 |  * @ctrl:	software shadow of the channel ctrl registers | 
 |  * @channels:	iio channel spec for the device | 
 |  * @data:	spi transfer buffers | 
 |  */ | 
 | struct ad5755_state { | 
 | 	struct spi_device		*spi; | 
 | 	const struct ad5755_chip_info	*chip_info; | 
 | 	unsigned int			pwr_down; | 
 | 	unsigned int			ctrl[AD5755_NUM_CHANNELS]; | 
 | 	struct iio_chan_spec		channels[AD5755_NUM_CHANNELS]; | 
 |  | 
 | 	/* | 
 | 	 * DMA (thus cache coherency maintenance) requires the | 
 | 	 * transfer buffers to live in their own cache lines. | 
 | 	 */ | 
 |  | 
 | 	union { | 
 | 		__be32 d32; | 
 | 		u8 d8[4]; | 
 | 	} data[2] ____cacheline_aligned; | 
 | }; | 
 |  | 
 | enum ad5755_type { | 
 | 	ID_AD5755, | 
 | 	ID_AD5757, | 
 | 	ID_AD5735, | 
 | 	ID_AD5737, | 
 | }; | 
 |  | 
 | #ifdef CONFIG_OF | 
 | static const int ad5755_dcdc_freq_table[][2] = { | 
 | 	{ 250000, AD5755_DC_DC_FREQ_250kHZ }, | 
 | 	{ 410000, AD5755_DC_DC_FREQ_410kHZ }, | 
 | 	{ 650000, AD5755_DC_DC_FREQ_650kHZ } | 
 | }; | 
 |  | 
 | static const int ad5755_dcdc_maxv_table[][2] = { | 
 | 	{ 23000000, AD5755_DC_DC_MAXV_23V }, | 
 | 	{ 24500000, AD5755_DC_DC_MAXV_24V5 }, | 
 | 	{ 27000000, AD5755_DC_DC_MAXV_27V }, | 
 | 	{ 29500000, AD5755_DC_DC_MAXV_29V5 }, | 
 | }; | 
 |  | 
 | static const int ad5755_slew_rate_table[][2] = { | 
 | 	{ 64000, AD5755_SLEW_RATE_64k }, | 
 | 	{ 32000, AD5755_SLEW_RATE_32k }, | 
 | 	{ 16000, AD5755_SLEW_RATE_16k }, | 
 | 	{ 8000, AD5755_SLEW_RATE_8k }, | 
 | 	{ 4000, AD5755_SLEW_RATE_4k }, | 
 | 	{ 2000, AD5755_SLEW_RATE_2k }, | 
 | 	{ 1000, AD5755_SLEW_RATE_1k }, | 
 | 	{ 500, AD5755_SLEW_RATE_500 }, | 
 | 	{ 250, AD5755_SLEW_RATE_250 }, | 
 | 	{ 125, AD5755_SLEW_RATE_125 }, | 
 | 	{ 64, AD5755_SLEW_RATE_64 }, | 
 | 	{ 32, AD5755_SLEW_RATE_32 }, | 
 | 	{ 16, AD5755_SLEW_RATE_16 }, | 
 | 	{ 8, AD5755_SLEW_RATE_8 }, | 
 | 	{ 4, AD5755_SLEW_RATE_4 }, | 
 | 	{ 0, AD5755_SLEW_RATE_0_5 }, | 
 | }; | 
 |  | 
 | static const int ad5755_slew_step_table[][2] = { | 
 | 	{ 256, AD5755_SLEW_STEP_SIZE_256 }, | 
 | 	{ 128, AD5755_SLEW_STEP_SIZE_128 }, | 
 | 	{ 64, AD5755_SLEW_STEP_SIZE_64 }, | 
 | 	{ 32, AD5755_SLEW_STEP_SIZE_32 }, | 
 | 	{ 16, AD5755_SLEW_STEP_SIZE_16 }, | 
 | 	{ 4, AD5755_SLEW_STEP_SIZE_4 }, | 
 | 	{ 2, AD5755_SLEW_STEP_SIZE_2 }, | 
 | 	{ 1, AD5755_SLEW_STEP_SIZE_1 }, | 
 | }; | 
 | #endif | 
 |  | 
 | static int ad5755_write_unlocked(struct iio_dev *indio_dev, | 
 | 	unsigned int reg, unsigned int val) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 |  | 
 | 	st->data[0].d32 = cpu_to_be32((reg << 16) | val); | 
 |  | 
 | 	return spi_write(st->spi, &st->data[0].d8[1], 3); | 
 | } | 
 |  | 
 | static int ad5755_write_ctrl_unlocked(struct iio_dev *indio_dev, | 
 | 	unsigned int channel, unsigned int reg, unsigned int val) | 
 | { | 
 | 	return ad5755_write_unlocked(indio_dev, | 
 | 		AD5755_WRITE_REG_CTRL(channel), (reg << 13) | val); | 
 | } | 
 |  | 
 | static int ad5755_write(struct iio_dev *indio_dev, unsigned int reg, | 
 | 	unsigned int val) | 
 | { | 
 | 	int ret; | 
 |  | 
 | 	mutex_lock(&indio_dev->mlock); | 
 | 	ret = ad5755_write_unlocked(indio_dev, reg, val); | 
 | 	mutex_unlock(&indio_dev->mlock); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | static int ad5755_write_ctrl(struct iio_dev *indio_dev, unsigned int channel, | 
 | 	unsigned int reg, unsigned int val) | 
 | { | 
 | 	int ret; | 
 |  | 
 | 	mutex_lock(&indio_dev->mlock); | 
 | 	ret = ad5755_write_ctrl_unlocked(indio_dev, channel, reg, val); | 
 | 	mutex_unlock(&indio_dev->mlock); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | static int ad5755_read(struct iio_dev *indio_dev, unsigned int addr) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 | 	int ret; | 
 | 	struct spi_transfer t[] = { | 
 | 		{ | 
 | 			.tx_buf = &st->data[0].d8[1], | 
 | 			.len = 3, | 
 | 			.cs_change = 1, | 
 | 		}, { | 
 | 			.tx_buf = &st->data[1].d8[1], | 
 | 			.rx_buf = &st->data[1].d8[1], | 
 | 			.len = 3, | 
 | 		}, | 
 | 	}; | 
 |  | 
 | 	mutex_lock(&indio_dev->mlock); | 
 |  | 
 | 	st->data[0].d32 = cpu_to_be32(AD5755_READ_FLAG | (addr << 16)); | 
 | 	st->data[1].d32 = cpu_to_be32(AD5755_NOOP); | 
 |  | 
 | 	ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t)); | 
 | 	if (ret >= 0) | 
 | 		ret = be32_to_cpu(st->data[1].d32) & 0xffff; | 
 |  | 
 | 	mutex_unlock(&indio_dev->mlock); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | static int ad5755_update_dac_ctrl(struct iio_dev *indio_dev, | 
 | 	unsigned int channel, unsigned int set, unsigned int clr) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 | 	int ret; | 
 |  | 
 | 	st->ctrl[channel] |= set; | 
 | 	st->ctrl[channel] &= ~clr; | 
 |  | 
 | 	ret = ad5755_write_ctrl_unlocked(indio_dev, channel, | 
 | 		AD5755_CTRL_REG_DAC, st->ctrl[channel]); | 
 |  | 
 | 	return ret; | 
 | } | 
 |  | 
 | static int ad5755_set_channel_pwr_down(struct iio_dev *indio_dev, | 
 | 	unsigned int channel, bool pwr_down) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 | 	unsigned int mask = BIT(channel); | 
 |  | 
 | 	mutex_lock(&indio_dev->mlock); | 
 |  | 
 | 	if ((bool)(st->pwr_down & mask) == pwr_down) | 
 | 		goto out_unlock; | 
 |  | 
 | 	if (!pwr_down) { | 
 | 		st->pwr_down &= ~mask; | 
 | 		ad5755_update_dac_ctrl(indio_dev, channel, | 
 | 			AD5755_DAC_INT_EN | AD5755_DAC_DC_DC_EN, 0); | 
 | 		udelay(200); | 
 | 		ad5755_update_dac_ctrl(indio_dev, channel, | 
 | 			AD5755_DAC_OUT_EN, 0); | 
 | 	} else { | 
 | 		st->pwr_down |= mask; | 
 | 		ad5755_update_dac_ctrl(indio_dev, channel, | 
 | 			0, AD5755_DAC_INT_EN | AD5755_DAC_OUT_EN | | 
 | 				AD5755_DAC_DC_DC_EN); | 
 | 	} | 
 |  | 
 | out_unlock: | 
 | 	mutex_unlock(&indio_dev->mlock); | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static const int ad5755_min_max_table[][2] = { | 
 | 	[AD5755_MODE_VOLTAGE_0V_5V] = { 0, 5000 }, | 
 | 	[AD5755_MODE_VOLTAGE_0V_10V] = { 0, 10000 }, | 
 | 	[AD5755_MODE_VOLTAGE_PLUSMINUS_5V] = { -5000, 5000 }, | 
 | 	[AD5755_MODE_VOLTAGE_PLUSMINUS_10V] = { -10000, 10000 }, | 
 | 	[AD5755_MODE_CURRENT_4mA_20mA] = { 4, 20 }, | 
 | 	[AD5755_MODE_CURRENT_0mA_20mA] = { 0, 20 }, | 
 | 	[AD5755_MODE_CURRENT_0mA_24mA] = { 0, 24 }, | 
 | }; | 
 |  | 
 | static void ad5755_get_min_max(struct ad5755_state *st, | 
 | 	struct iio_chan_spec const *chan, int *min, int *max) | 
 | { | 
 | 	enum ad5755_mode mode = st->ctrl[chan->channel] & 7; | 
 | 	*min = ad5755_min_max_table[mode][0]; | 
 | 	*max = ad5755_min_max_table[mode][1]; | 
 | } | 
 |  | 
 | static inline int ad5755_get_offset(struct ad5755_state *st, | 
 | 	struct iio_chan_spec const *chan) | 
 | { | 
 | 	int min, max; | 
 |  | 
 | 	ad5755_get_min_max(st, chan, &min, &max); | 
 | 	return (min * (1 << chan->scan_type.realbits)) / (max - min); | 
 | } | 
 |  | 
 | static int ad5755_chan_reg_info(struct ad5755_state *st, | 
 | 	struct iio_chan_spec const *chan, long info, bool write, | 
 | 	unsigned int *reg, unsigned int *shift, unsigned int *offset) | 
 | { | 
 | 	switch (info) { | 
 | 	case IIO_CHAN_INFO_RAW: | 
 | 		if (write) | 
 | 			*reg = AD5755_WRITE_REG_DATA(chan->address); | 
 | 		else | 
 | 			*reg = AD5755_READ_REG_DATA(chan->address); | 
 | 		*shift = chan->scan_type.shift; | 
 | 		*offset = 0; | 
 | 		break; | 
 | 	case IIO_CHAN_INFO_CALIBBIAS: | 
 | 		if (write) | 
 | 			*reg = AD5755_WRITE_REG_OFFSET(chan->address); | 
 | 		else | 
 | 			*reg = AD5755_READ_REG_OFFSET(chan->address); | 
 | 		*shift = st->chip_info->calib_shift; | 
 | 		*offset = 32768; | 
 | 		break; | 
 | 	case IIO_CHAN_INFO_CALIBSCALE: | 
 | 		if (write) | 
 | 			*reg =  AD5755_WRITE_REG_GAIN(chan->address); | 
 | 		else | 
 | 			*reg =  AD5755_READ_REG_GAIN(chan->address); | 
 | 		*shift = st->chip_info->calib_shift; | 
 | 		*offset = 0; | 
 | 		break; | 
 | 	default: | 
 | 		return -EINVAL; | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static int ad5755_read_raw(struct iio_dev *indio_dev, | 
 | 	const struct iio_chan_spec *chan, int *val, int *val2, long info) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 | 	unsigned int reg, shift, offset; | 
 | 	int min, max; | 
 | 	int ret; | 
 |  | 
 | 	switch (info) { | 
 | 	case IIO_CHAN_INFO_SCALE: | 
 | 		ad5755_get_min_max(st, chan, &min, &max); | 
 | 		*val = max - min; | 
 | 		*val2 = chan->scan_type.realbits; | 
 | 		return IIO_VAL_FRACTIONAL_LOG2; | 
 | 	case IIO_CHAN_INFO_OFFSET: | 
 | 		*val = ad5755_get_offset(st, chan); | 
 | 		return IIO_VAL_INT; | 
 | 	default: | 
 | 		ret = ad5755_chan_reg_info(st, chan, info, false, | 
 | 						®, &shift, &offset); | 
 | 		if (ret) | 
 | 			return ret; | 
 |  | 
 | 		ret = ad5755_read(indio_dev, reg); | 
 | 		if (ret < 0) | 
 | 			return ret; | 
 |  | 
 | 		*val = (ret - offset) >> shift; | 
 |  | 
 | 		return IIO_VAL_INT; | 
 | 	} | 
 |  | 
 | 	return -EINVAL; | 
 | } | 
 |  | 
 | static int ad5755_write_raw(struct iio_dev *indio_dev, | 
 | 	const struct iio_chan_spec *chan, int val, int val2, long info) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 | 	unsigned int shift, reg, offset; | 
 | 	int ret; | 
 |  | 
 | 	ret = ad5755_chan_reg_info(st, chan, info, true, | 
 | 					®, &shift, &offset); | 
 | 	if (ret) | 
 | 		return ret; | 
 |  | 
 | 	val <<= shift; | 
 | 	val += offset; | 
 |  | 
 | 	if (val < 0 || val > 0xffff) | 
 | 		return -EINVAL; | 
 |  | 
 | 	return ad5755_write(indio_dev, reg, val); | 
 | } | 
 |  | 
 | static ssize_t ad5755_read_powerdown(struct iio_dev *indio_dev, uintptr_t priv, | 
 | 	const struct iio_chan_spec *chan, char *buf) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 |  | 
 | 	return sprintf(buf, "%d\n", | 
 | 		       (bool)(st->pwr_down & (1 << chan->channel))); | 
 | } | 
 |  | 
 | static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv, | 
 | 	struct iio_chan_spec const *chan, const char *buf, size_t len) | 
 | { | 
 | 	bool pwr_down; | 
 | 	int ret; | 
 |  | 
 | 	ret = strtobool(buf, &pwr_down); | 
 | 	if (ret) | 
 | 		return ret; | 
 |  | 
 | 	ret = ad5755_set_channel_pwr_down(indio_dev, chan->channel, pwr_down); | 
 | 	return ret ? ret : len; | 
 | } | 
 |  | 
 | static const struct iio_info ad5755_info = { | 
 | 	.read_raw = ad5755_read_raw, | 
 | 	.write_raw = ad5755_write_raw, | 
 | }; | 
 |  | 
 | static const struct iio_chan_spec_ext_info ad5755_ext_info[] = { | 
 | 	{ | 
 | 		.name = "powerdown", | 
 | 		.read = ad5755_read_powerdown, | 
 | 		.write = ad5755_write_powerdown, | 
 | 		.shared = IIO_SEPARATE, | 
 | 	}, | 
 | 	{ }, | 
 | }; | 
 |  | 
 | #define AD5755_CHANNEL(_bits) {					\ | 
 | 	.indexed = 1,						\ | 
 | 	.output = 1,						\ | 
 | 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\ | 
 | 		BIT(IIO_CHAN_INFO_SCALE) |			\ | 
 | 		BIT(IIO_CHAN_INFO_OFFSET) |			\ | 
 | 		BIT(IIO_CHAN_INFO_CALIBSCALE) |			\ | 
 | 		BIT(IIO_CHAN_INFO_CALIBBIAS),			\ | 
 | 	.scan_type = {						\ | 
 | 		.sign = 'u',					\ | 
 | 		.realbits = (_bits),				\ | 
 | 		.storagebits = 16,				\ | 
 | 		.shift = 16 - (_bits),				\ | 
 | 	},							\ | 
 | 	.ext_info = ad5755_ext_info,				\ | 
 | } | 
 |  | 
 | static const struct ad5755_chip_info ad5755_chip_info_tbl[] = { | 
 | 	[ID_AD5735] = { | 
 | 		.channel_template = AD5755_CHANNEL(14), | 
 | 		.has_voltage_out = true, | 
 | 		.calib_shift = 4, | 
 | 	}, | 
 | 	[ID_AD5737] = { | 
 | 		.channel_template = AD5755_CHANNEL(14), | 
 | 		.has_voltage_out = false, | 
 | 		.calib_shift = 4, | 
 | 	}, | 
 | 	[ID_AD5755] = { | 
 | 		.channel_template = AD5755_CHANNEL(16), | 
 | 		.has_voltage_out = true, | 
 | 		.calib_shift = 0, | 
 | 	}, | 
 | 	[ID_AD5757] = { | 
 | 		.channel_template = AD5755_CHANNEL(16), | 
 | 		.has_voltage_out = false, | 
 | 		.calib_shift = 0, | 
 | 	}, | 
 | }; | 
 |  | 
 | static bool ad5755_is_valid_mode(struct ad5755_state *st, enum ad5755_mode mode) | 
 | { | 
 | 	switch (mode) { | 
 | 	case AD5755_MODE_VOLTAGE_0V_5V: | 
 | 	case AD5755_MODE_VOLTAGE_0V_10V: | 
 | 	case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: | 
 | 	case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: | 
 | 		return st->chip_info->has_voltage_out; | 
 | 	case AD5755_MODE_CURRENT_4mA_20mA: | 
 | 	case AD5755_MODE_CURRENT_0mA_20mA: | 
 | 	case AD5755_MODE_CURRENT_0mA_24mA: | 
 | 		return true; | 
 | 	default: | 
 | 		return false; | 
 | 	} | 
 | } | 
 |  | 
 | static int ad5755_setup_pdata(struct iio_dev *indio_dev, | 
 | 			      const struct ad5755_platform_data *pdata) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 | 	unsigned int val; | 
 | 	unsigned int i; | 
 | 	int ret; | 
 |  | 
 | 	if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE || | 
 | 		pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ || | 
 | 		pdata->dc_dc_maxv > AD5755_DC_DC_MAXV_29V5) | 
 | 		return -EINVAL; | 
 |  | 
 | 	val = pdata->dc_dc_maxv << AD5755_DC_DC_MAXV; | 
 | 	val |= pdata->dc_dc_freq << AD5755_DC_DC_FREQ_SHIFT; | 
 | 	val |= pdata->dc_dc_phase << AD5755_DC_DC_PHASE_SHIFT; | 
 | 	if (pdata->ext_dc_dc_compenstation_resistor) | 
 | 		val |= AD5755_EXT_DC_DC_COMP_RES; | 
 |  | 
 | 	ret = ad5755_write_ctrl(indio_dev, 0, AD5755_CTRL_REG_DC_DC, val); | 
 | 	if (ret < 0) | 
 | 		return ret; | 
 |  | 
 | 	for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { | 
 | 		val = pdata->dac[i].slew.step_size << | 
 | 			AD5755_SLEW_STEP_SIZE_SHIFT; | 
 | 		val |= pdata->dac[i].slew.rate << | 
 | 			AD5755_SLEW_RATE_SHIFT; | 
 | 		if (pdata->dac[i].slew.enable) | 
 | 			val |= AD5755_SLEW_ENABLE; | 
 |  | 
 | 		ret = ad5755_write_ctrl(indio_dev, i, | 
 | 					AD5755_CTRL_REG_SLEW, val); | 
 | 		if (ret < 0) | 
 | 			return ret; | 
 | 	} | 
 |  | 
 | 	for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { | 
 | 		if (!ad5755_is_valid_mode(st, pdata->dac[i].mode)) | 
 | 			return -EINVAL; | 
 |  | 
 | 		val = 0; | 
 | 		if (!pdata->dac[i].ext_current_sense_resistor) | 
 | 			val |= AD5755_DAC_INT_CURRENT_SENSE_RESISTOR; | 
 | 		if (pdata->dac[i].enable_voltage_overrange) | 
 | 			val |= AD5755_DAC_VOLTAGE_OVERRANGE_EN; | 
 | 		val |= pdata->dac[i].mode; | 
 |  | 
 | 		ret = ad5755_update_dac_ctrl(indio_dev, i, val, 0); | 
 | 		if (ret < 0) | 
 | 			return ret; | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static bool ad5755_is_voltage_mode(enum ad5755_mode mode) | 
 | { | 
 | 	switch (mode) { | 
 | 	case AD5755_MODE_VOLTAGE_0V_5V: | 
 | 	case AD5755_MODE_VOLTAGE_0V_10V: | 
 | 	case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: | 
 | 	case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: | 
 | 		return true; | 
 | 	default: | 
 | 		return false; | 
 | 	} | 
 | } | 
 |  | 
 | static int ad5755_init_channels(struct iio_dev *indio_dev, | 
 | 				const struct ad5755_platform_data *pdata) | 
 | { | 
 | 	struct ad5755_state *st = iio_priv(indio_dev); | 
 | 	struct iio_chan_spec *channels = st->channels; | 
 | 	unsigned int i; | 
 |  | 
 | 	for (i = 0; i < AD5755_NUM_CHANNELS; ++i) { | 
 | 		channels[i] = st->chip_info->channel_template; | 
 | 		channels[i].channel = i; | 
 | 		channels[i].address = i; | 
 | 		if (pdata && ad5755_is_voltage_mode(pdata->dac[i].mode)) | 
 | 			channels[i].type = IIO_VOLTAGE; | 
 | 		else | 
 | 			channels[i].type = IIO_CURRENT; | 
 | 	} | 
 |  | 
 | 	indio_dev->channels = channels; | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | #define AD5755_DEFAULT_DAC_PDATA { \ | 
 | 		.mode = AD5755_MODE_CURRENT_4mA_20mA, \ | 
 | 		.ext_current_sense_resistor = true, \ | 
 | 		.enable_voltage_overrange = false, \ | 
 | 		.slew = { \ | 
 | 			.enable = false, \ | 
 | 			.rate = AD5755_SLEW_RATE_64k, \ | 
 | 			.step_size = AD5755_SLEW_STEP_SIZE_1, \ | 
 | 		}, \ | 
 | 	} | 
 |  | 
 | static const struct ad5755_platform_data ad5755_default_pdata = { | 
 | 	.ext_dc_dc_compenstation_resistor = false, | 
 | 	.dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE, | 
 | 	.dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ, | 
 | 	.dc_dc_maxv = AD5755_DC_DC_MAXV_23V, | 
 | 	.dac = { | 
 | 		[0] = AD5755_DEFAULT_DAC_PDATA, | 
 | 		[1] = AD5755_DEFAULT_DAC_PDATA, | 
 | 		[2] = AD5755_DEFAULT_DAC_PDATA, | 
 | 		[3] = AD5755_DEFAULT_DAC_PDATA, | 
 | 	}, | 
 | }; | 
 |  | 
 | #ifdef CONFIG_OF | 
 | static struct ad5755_platform_data *ad5755_parse_dt(struct device *dev) | 
 | { | 
 | 	struct device_node *np = dev->of_node; | 
 | 	struct device_node *pp; | 
 | 	struct ad5755_platform_data *pdata; | 
 | 	unsigned int tmp; | 
 | 	unsigned int tmparray[3]; | 
 | 	int devnr, i; | 
 |  | 
 | 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 
 | 	if (!pdata) | 
 | 		return NULL; | 
 |  | 
 | 	pdata->ext_dc_dc_compenstation_resistor = | 
 | 	    of_property_read_bool(np, "adi,ext-dc-dc-compenstation-resistor"); | 
 |  | 
 | 	if (!of_property_read_u32(np, "adi,dc-dc-phase", &tmp)) | 
 | 		pdata->dc_dc_phase = tmp; | 
 | 	else | 
 | 		pdata->dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE; | 
 |  | 
 | 	pdata->dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ; | 
 | 	if (!of_property_read_u32(np, "adi,dc-dc-freq-hz", &tmp)) { | 
 | 		for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_freq_table); i++) { | 
 | 			if (tmp == ad5755_dcdc_freq_table[i][0]) { | 
 | 				pdata->dc_dc_freq = ad5755_dcdc_freq_table[i][1]; | 
 | 				break; | 
 | 			} | 
 | 		} | 
 |  | 
 | 		if (i == ARRAY_SIZE(ad5755_dcdc_freq_table)) { | 
 | 			dev_err(dev, | 
 | 				"adi,dc-dc-freq out of range selecting 410kHz"); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	pdata->dc_dc_maxv = AD5755_DC_DC_MAXV_23V; | 
 | 	if (!of_property_read_u32(np, "adi,dc-dc-max-microvolt", &tmp)) { | 
 | 		for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_maxv_table); i++) { | 
 | 			if (tmp == ad5755_dcdc_maxv_table[i][0]) { | 
 | 				pdata->dc_dc_maxv = ad5755_dcdc_maxv_table[i][1]; | 
 | 				break; | 
 | 			} | 
 | 		} | 
 | 		if (i == ARRAY_SIZE(ad5755_dcdc_maxv_table)) { | 
 | 				dev_err(dev, | 
 | 					"adi,dc-dc-maxv out of range selecting 23V"); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	devnr = 0; | 
 | 	for_each_child_of_node(np, pp) { | 
 | 		if (devnr >= AD5755_NUM_CHANNELS) { | 
 | 			dev_err(dev, | 
 | 				"There is to many channels defined in DT\n"); | 
 | 			goto error_out; | 
 | 		} | 
 |  | 
 | 		if (!of_property_read_u32(pp, "adi,mode", &tmp)) | 
 | 			pdata->dac[devnr].mode = tmp; | 
 | 		else | 
 | 			pdata->dac[devnr].mode = AD5755_MODE_CURRENT_4mA_20mA; | 
 |  | 
 | 		pdata->dac[devnr].ext_current_sense_resistor = | 
 | 		    of_property_read_bool(pp, "adi,ext-current-sense-resistor"); | 
 |  | 
 | 		pdata->dac[devnr].enable_voltage_overrange = | 
 | 		    of_property_read_bool(pp, "adi,enable-voltage-overrange"); | 
 |  | 
 | 		if (!of_property_read_u32_array(pp, "adi,slew", tmparray, 3)) { | 
 | 			pdata->dac[devnr].slew.enable = tmparray[0]; | 
 |  | 
 | 			pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k; | 
 | 			for (i = 0; i < ARRAY_SIZE(ad5755_slew_rate_table); i++) { | 
 | 				if (tmparray[1] == ad5755_slew_rate_table[i][0]) { | 
 | 					pdata->dac[devnr].slew.rate = | 
 | 						ad5755_slew_rate_table[i][1]; | 
 | 					break; | 
 | 				} | 
 | 			} | 
 | 			if (i == ARRAY_SIZE(ad5755_slew_rate_table)) { | 
 | 				dev_err(dev, | 
 | 					"channel %d slew rate out of range selecting 64kHz", | 
 | 					devnr); | 
 | 			} | 
 |  | 
 | 			pdata->dac[devnr].slew.step_size = AD5755_SLEW_STEP_SIZE_1; | 
 | 			for (i = 0; i < ARRAY_SIZE(ad5755_slew_step_table); i++) { | 
 | 				if (tmparray[2] == ad5755_slew_step_table[i][0]) { | 
 | 					pdata->dac[devnr].slew.step_size = | 
 | 						ad5755_slew_step_table[i][1]; | 
 | 					break; | 
 | 				} | 
 | 			} | 
 | 			if (i == ARRAY_SIZE(ad5755_slew_step_table)) { | 
 | 				dev_err(dev, | 
 | 					"channel %d slew step size out of range selecting 1 LSB", | 
 | 					devnr); | 
 | 			} | 
 | 		} else { | 
 | 			pdata->dac[devnr].slew.enable = false; | 
 | 			pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k; | 
 | 			pdata->dac[devnr].slew.step_size = | 
 | 			    AD5755_SLEW_STEP_SIZE_1; | 
 | 		} | 
 | 		devnr++; | 
 | 	} | 
 |  | 
 | 	return pdata; | 
 |  | 
 |  error_out: | 
 | 	devm_kfree(dev, pdata); | 
 | 	return NULL; | 
 | } | 
 | #else | 
 | static | 
 | struct ad5755_platform_data *ad5755_parse_dt(struct device *dev) | 
 | { | 
 | 	return NULL; | 
 | } | 
 | #endif | 
 |  | 
 | static int ad5755_probe(struct spi_device *spi) | 
 | { | 
 | 	enum ad5755_type type = spi_get_device_id(spi)->driver_data; | 
 | 	const struct ad5755_platform_data *pdata = dev_get_platdata(&spi->dev); | 
 | 	struct iio_dev *indio_dev; | 
 | 	struct ad5755_state *st; | 
 | 	int ret; | 
 |  | 
 | 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | 
 | 	if (indio_dev == NULL) { | 
 | 		dev_err(&spi->dev, "Failed to allocate iio device\n"); | 
 | 		return  -ENOMEM; | 
 | 	} | 
 |  | 
 | 	st = iio_priv(indio_dev); | 
 | 	spi_set_drvdata(spi, indio_dev); | 
 |  | 
 | 	st->chip_info = &ad5755_chip_info_tbl[type]; | 
 | 	st->spi = spi; | 
 | 	st->pwr_down = 0xf; | 
 |  | 
 | 	indio_dev->dev.parent = &spi->dev; | 
 | 	indio_dev->name = spi_get_device_id(spi)->name; | 
 | 	indio_dev->info = &ad5755_info; | 
 | 	indio_dev->modes = INDIO_DIRECT_MODE; | 
 | 	indio_dev->num_channels = AD5755_NUM_CHANNELS; | 
 |  | 
 | 	if (spi->dev.of_node) | 
 | 		pdata = ad5755_parse_dt(&spi->dev); | 
 | 	else | 
 | 		pdata = spi->dev.platform_data; | 
 |  | 
 | 	if (!pdata) { | 
 | 		dev_warn(&spi->dev, "no platform data? using default\n"); | 
 | 		pdata = &ad5755_default_pdata; | 
 | 	} | 
 |  | 
 | 	ret = ad5755_init_channels(indio_dev, pdata); | 
 | 	if (ret) | 
 | 		return ret; | 
 |  | 
 | 	ret = ad5755_setup_pdata(indio_dev, pdata); | 
 | 	if (ret) | 
 | 		return ret; | 
 |  | 
 | 	return devm_iio_device_register(&spi->dev, indio_dev); | 
 | } | 
 |  | 
 | static const struct spi_device_id ad5755_id[] = { | 
 | 	{ "ad5755", ID_AD5755 }, | 
 | 	{ "ad5755-1", ID_AD5755 }, | 
 | 	{ "ad5757", ID_AD5757 }, | 
 | 	{ "ad5735", ID_AD5735 }, | 
 | 	{ "ad5737", ID_AD5737 }, | 
 | 	{} | 
 | }; | 
 | MODULE_DEVICE_TABLE(spi, ad5755_id); | 
 |  | 
 | static const struct of_device_id ad5755_of_match[] = { | 
 | 	{ .compatible = "adi,ad5755" }, | 
 | 	{ .compatible = "adi,ad5755-1" }, | 
 | 	{ .compatible = "adi,ad5757" }, | 
 | 	{ .compatible = "adi,ad5735" }, | 
 | 	{ .compatible = "adi,ad5737" }, | 
 | 	{ } | 
 | }; | 
 | MODULE_DEVICE_TABLE(of, ad5755_of_match); | 
 |  | 
 | static struct spi_driver ad5755_driver = { | 
 | 	.driver = { | 
 | 		.name = "ad5755", | 
 | 	}, | 
 | 	.probe = ad5755_probe, | 
 | 	.id_table = ad5755_id, | 
 | }; | 
 | module_spi_driver(ad5755_driver); | 
 |  | 
 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 
 | MODULE_DESCRIPTION("Analog Devices AD5755/55-1/57/35/37 DAC"); | 
 | MODULE_LICENSE("GPL v2"); |