brintos

brintos / linux-shallow public Read only

0
0
Text · 18.7 KiB · 67f1404 Raw
737 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * LTC2664 4 channel, 12-/16-Bit Voltage Output SoftSpan DAC driver4 * LTC2672 5 channel, 12-/16-Bit Current Output Softspan DAC driver5 *6 * Copyright 2024 Analog Devices Inc.7 */8 9#include <linux/bitfield.h>10#include <linux/cleanup.h>11#include <linux/device.h>12#include <linux/gpio/consumer.h>13#include <linux/iio/iio.h>14#include <linux/kernel.h>15#include <linux/math64.h>16#include <linux/module.h>17#include <linux/mod_devicetable.h>18#include <linux/mutex.h>19#include <linux/property.h>20#include <linux/regmap.h>21#include <linux/regulator/consumer.h>22#include <linux/spi/spi.h>23 24#define LTC2664_CMD_WRITE_N(n)		(0x00 + (n))25#define LTC2664_CMD_UPDATE_N(n)		(0x10 + (n))26#define LTC2664_CMD_WRITE_N_UPDATE_ALL	0x2027#define LTC2664_CMD_WRITE_N_UPDATE_N(n)	(0x30 + (n))28#define LTC2664_CMD_POWER_DOWN_N(n)	(0x40 + (n))29#define LTC2664_CMD_POWER_DOWN_ALL	0x5030#define LTC2664_CMD_SPAN_N(n)		(0x60 + (n))31#define LTC2664_CMD_CONFIG		0x7032#define LTC2664_CMD_MUX			0xB033#define LTC2664_CMD_TOGGLE_SEL		0xC034#define LTC2664_CMD_GLOBAL_TOGGLE	0xD035#define LTC2664_CMD_NO_OPERATION	0xF036#define LTC2664_REF_DISABLE		0x000137#define LTC2664_MSPAN_SOFTSPAN		738 39#define LTC2672_MAX_CHANNEL		540#define LTC2672_MAX_SPAN		741#define LTC2672_SCALE_MULTIPLIER(n)	(50 * BIT(n))42 43enum {44	LTC2664_SPAN_RANGE_0V_5V,45	LTC2664_SPAN_RANGE_0V_10V,46	LTC2664_SPAN_RANGE_M5V_5V,47	LTC2664_SPAN_RANGE_M10V_10V,48	LTC2664_SPAN_RANGE_M2V5_2V5,49};50 51enum {52	LTC2664_INPUT_A,53	LTC2664_INPUT_B,54	LTC2664_INPUT_B_AVAIL,55	LTC2664_POWERDOWN,56	LTC2664_POWERDOWN_MODE,57	LTC2664_TOGGLE_EN,58	LTC2664_GLOBAL_TOGGLE,59};60 61static const u16 ltc2664_mspan_lut[8][2] = {62	{ LTC2664_SPAN_RANGE_M10V_10V, 32768 }, /* MPS2=0, MPS1=0, MSP0=0 (0)*/63	{ LTC2664_SPAN_RANGE_M5V_5V, 32768 }, /* MPS2=0, MPS1=0, MSP0=1 (1)*/64	{ LTC2664_SPAN_RANGE_M2V5_2V5, 32768 }, /* MPS2=0, MPS1=1, MSP0=0 (2)*/65	{ LTC2664_SPAN_RANGE_0V_10V, 0 }, /* MPS2=0, MPS1=1, MSP0=1 (3)*/66	{ LTC2664_SPAN_RANGE_0V_10V, 32768 }, /* MPS2=1, MPS1=0, MSP0=0 (4)*/67	{ LTC2664_SPAN_RANGE_0V_5V, 0 }, /* MPS2=1, MPS1=0, MSP0=1 (5)*/68	{ LTC2664_SPAN_RANGE_0V_5V, 32768 }, /* MPS2=1, MPS1=1, MSP0=0 (6)*/69	{ LTC2664_SPAN_RANGE_0V_5V, 0 } /* MPS2=1, MPS1=1, MSP0=1 (7)*/70};71 72struct ltc2664_state;73 74struct ltc2664_chip_info {75	const char *name;76	int (*scale_get)(const struct ltc2664_state *st, int c);77	int (*offset_get)(const struct ltc2664_state *st, int c);78	int measurement_type;79	unsigned int num_channels;80	const int (*span_helper)[2];81	unsigned int num_span;82	unsigned int internal_vref_mv;83	bool manual_span_support;84	bool rfsadj_support;85};86 87struct ltc2664_chan {88	/* indicates if the channel should be toggled */89	bool toggle_chan;90	/* indicates if the channel is in powered down state */91	bool powerdown;92	/* span code of the channel */93	u8 span;94	/* raw data of the current state of the chip registers (A/B) */95	u16 raw[2];96};97 98struct ltc2664_state {99	struct spi_device *spi;100	struct regmap *regmap;101	struct ltc2664_chan channels[LTC2672_MAX_CHANNEL];102	/* lock to protect against multiple access to the device and shared data */103	struct mutex lock;104	const struct ltc2664_chip_info *chip_info;105	struct iio_chan_spec *iio_channels;106	int vref_mv;107	u32 rfsadj_ohms;108	u32 toggle_sel;109	bool global_toggle;110};111 112static const int ltc2664_span_helper[][2] = {113	{ 0, 5000 },114	{ 0, 10000 },115	{ -5000, 5000 },116	{ -10000, 10000 },117	{ -2500, 2500 },118};119 120static const int ltc2672_span_helper[][2] = {121	{ 0, 0 },122	{ 0, 3125 },123	{ 0, 6250 },124	{ 0, 12500 },125	{ 0, 25000 },126	{ 0, 50000 },127	{ 0, 100000 },128	{ 0, 200000 },129	{ 0, 300000 },130};131 132static int ltc2664_scale_get(const struct ltc2664_state *st, int c)133{134	const struct ltc2664_chan *chan = &st->channels[c];135	const int (*span_helper)[2] = st->chip_info->span_helper;136	int span, fs;137 138	span = chan->span;139	if (span < 0)140		return span;141 142	fs = span_helper[span][1] - span_helper[span][0];143 144	return fs * st->vref_mv / 2500;145}146 147static int ltc2672_scale_get(const struct ltc2664_state *st, int c)148{149	const struct ltc2664_chan *chan = &st->channels[c];150	int span, fs;151 152	span = chan->span - 1;153	if (span < 0)154		return span;155 156	fs = 1000 * st->vref_mv;157 158	if (span == LTC2672_MAX_SPAN)159		return mul_u64_u32_div(4800, fs, st->rfsadj_ohms);160 161	return mul_u64_u32_div(LTC2672_SCALE_MULTIPLIER(span), fs, st->rfsadj_ohms);162}163 164static int ltc2664_offset_get(const struct ltc2664_state *st, int c)165{166	const struct ltc2664_chan *chan = &st->channels[c];167	int span;168 169	span = chan->span;170	if (span < 0)171		return span;172 173	if (st->chip_info->span_helper[span][0] < 0)174		return -32768;175 176	return 0;177}178 179static int ltc2664_dac_code_write(struct ltc2664_state *st, u32 chan, u32 input,180				  u16 code)181{182	struct ltc2664_chan *c = &st->channels[chan];183	int ret, reg;184 185	guard(mutex)(&st->lock);186	/* select the correct input register to write to */187	if (c->toggle_chan) {188		ret = regmap_write(st->regmap, LTC2664_CMD_TOGGLE_SEL,189				   input << chan);190		if (ret)191			return ret;192	}193	/*194	 * If in toggle mode the dac should be updated by an195	 * external signal (or sw toggle) and not here.196	 */197	if (st->toggle_sel & BIT(chan))198		reg = LTC2664_CMD_WRITE_N(chan);199	else200		reg = LTC2664_CMD_WRITE_N_UPDATE_N(chan);201 202	ret = regmap_write(st->regmap, reg, code);203	if (ret)204		return ret;205 206	c->raw[input] = code;207 208	if (c->toggle_chan) {209		ret = regmap_write(st->regmap, LTC2664_CMD_TOGGLE_SEL,210				   st->toggle_sel);211		if (ret)212			return ret;213	}214 215	return 0;216}217 218static void ltc2664_dac_code_read(struct ltc2664_state *st, u32 chan, u32 input,219				  u32 *code)220{221	guard(mutex)(&st->lock);222	*code = st->channels[chan].raw[input];223}224 225static const int ltc2664_raw_range[] = { 0, 1, U16_MAX };226 227static int ltc2664_read_avail(struct iio_dev *indio_dev,228			      struct iio_chan_spec const *chan,229			      const int **vals, int *type, int *length,230			      long info)231{232	switch (info) {233	case IIO_CHAN_INFO_RAW:234		*vals = ltc2664_raw_range;235		*type = IIO_VAL_INT;236 237		return IIO_AVAIL_RANGE;238	default:239		return -EINVAL;240	}241}242 243static int ltc2664_read_raw(struct iio_dev *indio_dev,244			    struct iio_chan_spec const *chan, int *val,245			    int *val2, long info)246{247	struct ltc2664_state *st = iio_priv(indio_dev);248 249	switch (info) {250	case IIO_CHAN_INFO_RAW:251		ltc2664_dac_code_read(st, chan->channel, LTC2664_INPUT_A, val);252 253		return IIO_VAL_INT;254	case IIO_CHAN_INFO_OFFSET:255		*val = st->chip_info->offset_get(st, chan->channel);256 257		return IIO_VAL_INT;258	case IIO_CHAN_INFO_SCALE:259		*val = st->chip_info->scale_get(st, chan->channel);260 261		*val2 = 16;262		return IIO_VAL_FRACTIONAL_LOG2;263	default:264		return -EINVAL;265	}266}267 268static int ltc2664_write_raw(struct iio_dev *indio_dev,269			     struct iio_chan_spec const *chan, int val,270			     int val2, long info)271{272	struct ltc2664_state *st = iio_priv(indio_dev);273 274	switch (info) {275	case IIO_CHAN_INFO_RAW:276		if (val > U16_MAX || val < 0)277			return -EINVAL;278 279		return ltc2664_dac_code_write(st, chan->channel,280					      LTC2664_INPUT_A, val);281	default:282		return -EINVAL;283	}284}285 286static ssize_t ltc2664_reg_bool_get(struct iio_dev *indio_dev,287				    uintptr_t private,288				    const struct iio_chan_spec *chan,289				    char *buf)290{291	struct ltc2664_state *st = iio_priv(indio_dev);292	u32 val;293 294	guard(mutex)(&st->lock);295	switch (private) {296	case LTC2664_POWERDOWN:297		val = st->channels[chan->channel].powerdown;298 299		return sysfs_emit(buf, "%u\n", val);300	case LTC2664_POWERDOWN_MODE:301		return sysfs_emit(buf, "42kohm_to_gnd\n");302	case LTC2664_TOGGLE_EN:303		val = !!(st->toggle_sel & BIT(chan->channel));304 305		return sysfs_emit(buf, "%u\n", val);306	case LTC2664_GLOBAL_TOGGLE:307		val = st->global_toggle;308 309		return sysfs_emit(buf, "%u\n", val);310	default:311		return -EINVAL;312	}313}314 315static ssize_t ltc2664_reg_bool_set(struct iio_dev *indio_dev,316				    uintptr_t private,317				    const struct iio_chan_spec *chan,318				    const char *buf, size_t len)319{320	struct ltc2664_state *st = iio_priv(indio_dev);321	int ret;322	bool en;323 324	ret = kstrtobool(buf, &en);325	if (ret)326		return ret;327 328	guard(mutex)(&st->lock);329	switch (private) {330	case LTC2664_POWERDOWN:331		ret = regmap_write(st->regmap,332				   en ? LTC2664_CMD_POWER_DOWN_N(chan->channel) :333				   LTC2664_CMD_UPDATE_N(chan->channel), en);334		if (ret)335			return ret;336 337		st->channels[chan->channel].powerdown = en;338 339		return len;340	case LTC2664_TOGGLE_EN:341		if (en)342			st->toggle_sel |= BIT(chan->channel);343		else344			st->toggle_sel &= ~BIT(chan->channel);345 346		ret = regmap_write(st->regmap, LTC2664_CMD_TOGGLE_SEL,347				   st->toggle_sel);348		if (ret)349			return ret;350 351		return len;352	case LTC2664_GLOBAL_TOGGLE:353		ret = regmap_write(st->regmap, LTC2664_CMD_GLOBAL_TOGGLE, en);354		if (ret)355			return ret;356 357		st->global_toggle = en;358 359		return len;360	default:361		return -EINVAL;362	}363}364 365static ssize_t ltc2664_dac_input_read(struct iio_dev *indio_dev,366				      uintptr_t private,367				      const struct iio_chan_spec *chan,368				      char *buf)369{370	struct ltc2664_state *st = iio_priv(indio_dev);371	u32 val;372 373	if (private == LTC2664_INPUT_B_AVAIL)374		return sysfs_emit(buf, "[%u %u %u]\n", ltc2664_raw_range[0],375				  ltc2664_raw_range[1],376				  ltc2664_raw_range[2] / 4);377 378	ltc2664_dac_code_read(st, chan->channel, private, &val);379 380	return sysfs_emit(buf, "%u\n", val);381}382 383static ssize_t ltc2664_dac_input_write(struct iio_dev *indio_dev,384				       uintptr_t private,385				       const struct iio_chan_spec *chan,386				       const char *buf, size_t len)387{388	struct ltc2664_state *st = iio_priv(indio_dev);389	int ret;390	u16 val;391 392	if (private == LTC2664_INPUT_B_AVAIL)393		return -EINVAL;394 395	ret = kstrtou16(buf, 10, &val);396	if (ret)397		return ret;398 399	ret = ltc2664_dac_code_write(st, chan->channel, private, val);400	if (ret)401		return ret;402 403	return len;404}405 406static int ltc2664_reg_access(struct iio_dev *indio_dev,407			      unsigned int reg,408			      unsigned int writeval,409			      unsigned int *readval)410{411	struct ltc2664_state *st = iio_priv(indio_dev);412 413	if (readval)414		return -EOPNOTSUPP;415 416	return regmap_write(st->regmap, reg, writeval);417}418 419#define LTC2664_CHAN_EXT_INFO(_name, _what, _shared, _read, _write) {	\420	.name = _name,							\421	.read = (_read),						\422	.write = (_write),						\423	.private = (_what),						\424	.shared = (_shared),						\425}426 427/*428 * For toggle mode we only expose the symbol attr (sw_toggle) in case a TGPx is429 * not provided in dts.430 */431static const struct iio_chan_spec_ext_info ltc2664_toggle_sym_ext_info[] = {432	LTC2664_CHAN_EXT_INFO("raw0", LTC2664_INPUT_A, IIO_SEPARATE,433			      ltc2664_dac_input_read, ltc2664_dac_input_write),434	LTC2664_CHAN_EXT_INFO("raw1", LTC2664_INPUT_B, IIO_SEPARATE,435			      ltc2664_dac_input_read, ltc2664_dac_input_write),436	LTC2664_CHAN_EXT_INFO("powerdown", LTC2664_POWERDOWN, IIO_SEPARATE,437			      ltc2664_reg_bool_get, ltc2664_reg_bool_set),438	LTC2664_CHAN_EXT_INFO("powerdown_mode", LTC2664_POWERDOWN_MODE,439			      IIO_SEPARATE, ltc2664_reg_bool_get, NULL),440	LTC2664_CHAN_EXT_INFO("symbol", LTC2664_GLOBAL_TOGGLE, IIO_SEPARATE,441			      ltc2664_reg_bool_get, ltc2664_reg_bool_set),442	LTC2664_CHAN_EXT_INFO("toggle_en", LTC2664_TOGGLE_EN,443			      IIO_SEPARATE, ltc2664_reg_bool_get,444			      ltc2664_reg_bool_set),445	{ }446};447 448static const struct iio_chan_spec_ext_info ltc2664_ext_info[] = {449	LTC2664_CHAN_EXT_INFO("powerdown", LTC2664_POWERDOWN, IIO_SEPARATE,450			      ltc2664_reg_bool_get, ltc2664_reg_bool_set),451	LTC2664_CHAN_EXT_INFO("powerdown_mode", LTC2664_POWERDOWN_MODE,452			      IIO_SEPARATE, ltc2664_reg_bool_get, NULL),453	{ }454};455 456static const struct iio_chan_spec ltc2664_channel_template = {457	.indexed = 1,458	.output = 1,459	.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) |460			      BIT(IIO_CHAN_INFO_OFFSET) |461			      BIT(IIO_CHAN_INFO_RAW),462	.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),463	.ext_info = ltc2664_ext_info,464};465 466static const struct ltc2664_chip_info ltc2664_chip = {467	.name = "ltc2664",468	.scale_get = ltc2664_scale_get,469	.offset_get = ltc2664_offset_get,470	.measurement_type = IIO_VOLTAGE,471	.num_channels = 4,472	.span_helper = ltc2664_span_helper,473	.num_span = ARRAY_SIZE(ltc2664_span_helper),474	.internal_vref_mv = 2500,475	.manual_span_support = true,476	.rfsadj_support = false,477};478 479static const struct ltc2664_chip_info ltc2672_chip = {480	.name = "ltc2672",481	.scale_get = ltc2672_scale_get,482	.offset_get = ltc2664_offset_get,483	.measurement_type = IIO_CURRENT,484	.num_channels = 5,485	.span_helper = ltc2672_span_helper,486	.num_span = ARRAY_SIZE(ltc2672_span_helper),487	.internal_vref_mv = 1250,488	.manual_span_support = false,489	.rfsadj_support = true,490};491 492static int ltc2664_set_span(const struct ltc2664_state *st, int min, int max,493			    int chan)494{495	const struct ltc2664_chip_info *chip_info = st->chip_info;496	const int (*span_helper)[2] = chip_info->span_helper;497	int span, ret;498 499	for (span = 0; span < chip_info->num_span; span++) {500		if (min == span_helper[span][0] && max == span_helper[span][1])501			break;502	}503 504	if (span == chip_info->num_span)505		return -EINVAL;506 507	ret = regmap_write(st->regmap, LTC2664_CMD_SPAN_N(chan), span);508	if (ret)509		return ret;510 511	return span;512}513 514static int ltc2664_channel_config(struct ltc2664_state *st)515{516	const struct ltc2664_chip_info *chip_info = st->chip_info;517	struct device *dev = &st->spi->dev;518	u32 reg, tmp[2], mspan;519	int ret;520 521	mspan = LTC2664_MSPAN_SOFTSPAN;522	ret = device_property_read_u32(dev, "adi,manual-span-operation-config",523				       &mspan);524	if (!ret) {525		if (!chip_info->manual_span_support)526			return dev_err_probe(dev, -EINVAL,527			       "adi,manual-span-operation-config not supported\n");528 529		if (mspan >= ARRAY_SIZE(ltc2664_mspan_lut))530			return dev_err_probe(dev, -EINVAL,531			       "adi,manual-span-operation-config not in range\n");532	}533 534	st->rfsadj_ohms = 20000;535	ret = device_property_read_u32(dev, "adi,rfsadj-ohms", &st->rfsadj_ohms);536	if (!ret) {537		if (!chip_info->rfsadj_support)538			return dev_err_probe(dev, -EINVAL,539					     "adi,rfsadj-ohms not supported\n");540 541		if (st->rfsadj_ohms < 19000 || st->rfsadj_ohms > 41000)542			return dev_err_probe(dev, -EINVAL,543					     "adi,rfsadj-ohms not in range\n");544	}545 546	device_for_each_child_node_scoped(dev, child) {547		struct ltc2664_chan *chan;548 549		ret = fwnode_property_read_u32(child, "reg", &reg);550		if (ret)551			return dev_err_probe(dev, ret,552					     "Failed to get reg property\n");553 554		if (reg >= chip_info->num_channels)555			return dev_err_probe(dev, -EINVAL,556					     "reg bigger than: %d\n",557					     chip_info->num_channels);558 559		chan = &st->channels[reg];560 561		if (fwnode_property_read_bool(child, "adi,toggle-mode")) {562			chan->toggle_chan = true;563			/* assume sw toggle ABI */564			st->iio_channels[reg].ext_info = ltc2664_toggle_sym_ext_info;565 566			/*567			 * Clear IIO_CHAN_INFO_RAW bit as toggle channels expose568			 * out_voltage/current_raw{0|1} files.569			 */570			__clear_bit(IIO_CHAN_INFO_RAW,571				    &st->iio_channels[reg].info_mask_separate);572		}573 574		chan->raw[0] = ltc2664_mspan_lut[mspan][1];575		chan->raw[1] = ltc2664_mspan_lut[mspan][1];576 577		chan->span = ltc2664_mspan_lut[mspan][0];578 579		ret = fwnode_property_read_u32_array(child, "output-range-microvolt",580						     tmp, ARRAY_SIZE(tmp));581		if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) {582			ret = ltc2664_set_span(st, tmp[0] / 1000, tmp[1] / 1000, reg);583			if (ret < 0)584				return dev_err_probe(dev, ret,585						     "Failed to set span\n");586			chan->span = ret;587		}588 589		ret = fwnode_property_read_u32_array(child, "output-range-microamp",590						     tmp, ARRAY_SIZE(tmp));591		if (!ret) {592			ret = ltc2664_set_span(st, 0, tmp[1] / 1000, reg);593			if (ret < 0)594				return dev_err_probe(dev, ret,595						     "Failed to set span\n");596			chan->span = ret;597		}598	}599 600	return 0;601}602 603static int ltc2664_setup(struct ltc2664_state *st)604{605	const struct ltc2664_chip_info *chip_info = st->chip_info;606	struct gpio_desc *gpio;607	int ret, i;608 609	/* If we have a clr/reset pin, use that to reset the chip. */610	gpio = devm_gpiod_get_optional(&st->spi->dev, "reset", GPIOD_OUT_HIGH);611	if (IS_ERR(gpio))612		return dev_err_probe(&st->spi->dev, PTR_ERR(gpio),613				     "Failed to get reset gpio");614	if (gpio) {615		fsleep(1000);616		gpiod_set_value_cansleep(gpio, 0);617	}618 619	/*620	 * Duplicate the default channel configuration as it can change during621	 * @ltc2664_channel_config()622	 */623	st->iio_channels = devm_kcalloc(&st->spi->dev,624					chip_info->num_channels,625					sizeof(struct iio_chan_spec),626					GFP_KERNEL);627	if (!st->iio_channels)628		return -ENOMEM;629 630	for (i = 0; i < chip_info->num_channels; i++) {631		st->iio_channels[i] = ltc2664_channel_template;632		st->iio_channels[i].type = chip_info->measurement_type;633		st->iio_channels[i].channel = i;634	}635 636	ret = ltc2664_channel_config(st);637	if (ret)638		return ret;639 640	return regmap_set_bits(st->regmap, LTC2664_CMD_CONFIG, LTC2664_REF_DISABLE);641}642 643static const struct regmap_config ltc2664_regmap_config = {644	.reg_bits = 8,645	.val_bits = 16,646	.max_register = LTC2664_CMD_NO_OPERATION,647};648 649static const struct iio_info ltc2664_info = {650	.write_raw = ltc2664_write_raw,651	.read_raw = ltc2664_read_raw,652	.read_avail = ltc2664_read_avail,653	.debugfs_reg_access = ltc2664_reg_access,654};655 656static int ltc2664_probe(struct spi_device *spi)657{658	static const char * const regulators[] = { "vcc", "iovcc", "v-neg" };659	const struct ltc2664_chip_info *chip_info;660	struct device *dev = &spi->dev;661	struct iio_dev *indio_dev;662	struct ltc2664_state *st;663	int ret;664 665	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));666	if (!indio_dev)667		return -ENOMEM;668 669	st = iio_priv(indio_dev);670	st->spi = spi;671 672	chip_info = spi_get_device_match_data(spi);673	if (!chip_info)674		return -ENODEV;675 676	st->chip_info = chip_info;677 678	mutex_init(&st->lock);679 680	st->regmap = devm_regmap_init_spi(spi, &ltc2664_regmap_config);681	if (IS_ERR(st->regmap))682		return dev_err_probe(dev, PTR_ERR(st->regmap),683				     "Failed to init regmap");684 685	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators),686					     regulators);687	if (ret)688		return dev_err_probe(dev, ret, "Failed to enable regulators\n");689 690	ret = devm_regulator_get_enable_read_voltage(dev, "ref");691	if (ret < 0 && ret != -ENODEV)692		return ret;693 694	st->vref_mv = ret > 0 ? ret / 1000 :  chip_info->internal_vref_mv;695 696	ret = ltc2664_setup(st);697	if (ret)698		return ret;699 700	indio_dev->name = chip_info->name;701	indio_dev->info = &ltc2664_info;702	indio_dev->modes = INDIO_DIRECT_MODE;703	indio_dev->channels = st->iio_channels;704	indio_dev->num_channels = chip_info->num_channels;705 706	return devm_iio_device_register(dev, indio_dev);707}708 709static const struct spi_device_id ltc2664_id[] = {710	{ "ltc2664", (kernel_ulong_t)&ltc2664_chip },711	{ "ltc2672", (kernel_ulong_t)&ltc2672_chip },712	{ }713};714MODULE_DEVICE_TABLE(spi, ltc2664_id);715 716static const struct of_device_id ltc2664_of_id[] = {717	{ .compatible = "adi,ltc2664", .data = &ltc2664_chip },718	{ .compatible = "adi,ltc2672", .data = &ltc2672_chip },719	{ }720};721MODULE_DEVICE_TABLE(of, ltc2664_of_id);722 723static struct spi_driver ltc2664_driver = {724	.driver = {725		.name = "ltc2664",726		.of_match_table = ltc2664_of_id,727	},728	.probe = ltc2664_probe,729	.id_table = ltc2664_id,730};731module_spi_driver(ltc2664_driver);732 733MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");734MODULE_AUTHOR("Kim Seer Paller <kimseer.paller@analog.com>");735MODULE_DESCRIPTION("Analog Devices LTC2664 and LTC2672 DAC");736MODULE_LICENSE("GPL");737