brintos

brintos / linux-shallow public Read only

0
0
Text · 22.2 KiB · 98771e3 Raw
905 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * AD5758 Digital to analog converters driver4 *5 * Copyright 2018 Analog Devices Inc.6 *7 * TODO: Currently CRC is not supported in this driver8 */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				0x0023#define AD5758_DAC_INPUT			0x0124#define AD5758_DAC_OUTPUT			0x0225#define AD5758_CLEAR_CODE			0x0326#define AD5758_USER_GAIN			0x0427#define AD5758_USER_OFFSET			0x0528#define AD5758_DAC_CONFIG			0x0629#define AD5758_SW_LDAC				0x0730#define AD5758_KEY				0x0831#define AD5758_GP_CONFIG1			0x0932#define AD5758_GP_CONFIG2			0x0A33#define AD5758_DCDC_CONFIG1			0x0B34#define AD5758_DCDC_CONFIG2			0x0C35#define AD5758_WDT_CONFIG			0x0F36#define AD5758_DIGITAL_DIAG_CONFIG		0x1037#define AD5758_ADC_CONFIG			0x1138#define AD5758_FAULT_PIN_CONFIG			0x1239#define AD5758_TWO_STAGE_READBACK_SELECT	0x1340#define AD5758_DIGITAL_DIAG_RESULTS		0x1441#define AD5758_ANALOG_DIAG_RESULTS		0x1542#define AD5758_STATUS				0x1643#define AD5758_CHIP_ID				0x1744#define AD5758_FREQ_MONITOR			0x1845#define AD5758_DEVICE_ID_0			0x1946#define AD5758_DEVICE_ID_1			0x1A47#define AD5758_DEVICE_ID_2			0x1B48#define AD5758_DEVICE_ID_3			0x1C49 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			0x15FA66#define AD5758_KEY_CODE_RESET_2			0xAF5167#define AD5758_KEY_CODE_SINGLE_ADC_CONV		0x1ADC68#define AD5758_KEY_CODE_RESET_WDT		0x0D0669#define AD5758_KEY_CODE_CALIB_MEM_REFRESH	0xFCBA70 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	65535000000ULL93 94struct ad5758_range {95	int reg;96	int min;97	int max;98};99 100/**101 * struct ad5758_state - driver instance specific data102 * @spi:	spi_device103 * @lock:	mutex lock104 * @gpio_reset:	gpio descriptor for the reset line105 * @out_range:	struct which stores the output range106 * @dc_dc_mode:	variable which stores the mode of operation107 * @dc_dc_ilim:	variable which stores the dc-to-dc converter current limit108 * @slew_time:	variable which stores the target slew time109 * @pwr_down:	variable which contains whether a channel is powered down or not110 * @d32:	spi transfer buffers111 */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 register126 * 0000: 0 V to 5 V voltage range127 * 0001: 0 V to 10 V voltage range128 * 0010: ±5 V voltage range129 * 0011: ±10 V voltage range130 * 1000: 0 mA to 20 mA current range131 * 1001: 0 mA to 24 mA current range132 * 1010: 4 mA to 20 mA current range133 * 1011: ±20 mA current range134 * 1100: ±24 mA current range135 * 1101: -1 mA to +22 mA current range136 */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, 16176};177 178static const int ad5758_sr_step[8] = {179	4, 12, 64, 120, 256, 500, 1820, 2048180};181 182static const int ad5758_dc_dc_ilim[6] = {183	150000, 200000, 250000, 300000, 350000, 400000184};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 current323	 * 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 microseconds408	 * Given the desired slew time, the following algorithm determines the409	 * 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 raw414		 * 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 the422		 * closest valid match423		 */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 time433		 * is different from the desired slew time and store the diff434		 * for the next iteration435		 */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	else598		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		else714			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	else868		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");905