ad5791.c 11.0 KB
Newer Older
1
/*
2 3
 * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog
 * Converter
4 5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * Copyright 2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2.
 */

#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/regulator/consumer.h>
18
#include <linux/module.h>
19
#include <linux/bitops.h>
20

21 22
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
23
#include <linux/iio/dac/ad5791.h>
24

25
#define AD5791_DAC_MASK			GENMASK(19, 0)
26

27 28
#define AD5791_CMD_READ			BIT(23)
#define AD5791_CMD_WRITE		0
29 30 31 32 33 34 35 36 37 38
#define AD5791_ADDR(addr)		((addr) << 20)

/* Registers */
#define AD5791_ADDR_NOOP		0
#define AD5791_ADDR_DAC0		1
#define AD5791_ADDR_CTRL		2
#define AD5791_ADDR_CLRCODE		3
#define AD5791_ADDR_SW_CTRL		4

/* Control Register */
39 40 41 42 43
#define AD5791_CTRL_RBUF		BIT(1)
#define AD5791_CTRL_OPGND		BIT(2)
#define AD5791_CTRL_DACTRI		BIT(3)
#define AD5791_CTRL_BIN2SC		BIT(4)
#define AD5791_CTRL_SDODIS		BIT(5)
44 45 46 47 48 49 50 51 52 53 54 55
#define AD5761_CTRL_LINCOMP(x)		((x) << 6)

#define AD5791_LINCOMP_0_10		0
#define AD5791_LINCOMP_10_12		1
#define AD5791_LINCOMP_12_16		2
#define AD5791_LINCOMP_16_19		3
#define AD5791_LINCOMP_19_20		12

#define AD5780_LINCOMP_0_10		0
#define AD5780_LINCOMP_10_20		12

/* Software Control Register */
56 57 58
#define AD5791_SWCTRL_LDAC		BIT(0)
#define AD5791_SWCTRL_CLR		BIT(1)
#define AD5791_SWCTRL_RESET		BIT(2)
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

#define AD5791_DAC_PWRDN_6K		0
#define AD5791_DAC_PWRDN_3STATE		1

/**
 * struct ad5791_chip_info - chip specific information
 * @get_lin_comp:	function pointer to the device specific function
 */

struct ad5791_chip_info {
	int (*get_lin_comp)	(unsigned int span);
};

/**
 * struct ad5791_state - driver instance specific data
74
 * @spi:			spi_device
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
 * @reg_vdd:		positive supply regulator
 * @reg_vss:		negative supply regulator
 * @chip_info:		chip model specific constants
 * @vref_mv:		actual reference voltage used
 * @vref_neg_mv:	voltage of the negative supply
 * @pwr_down_mode	current power down mode
 */

struct ad5791_state {
	struct spi_device		*spi;
	struct regulator		*reg_vdd;
	struct regulator		*reg_vss;
	const struct ad5791_chip_info	*chip_info;
	unsigned short			vref_mv;
	unsigned int			vref_neg_mv;
	unsigned			ctrl;
	unsigned			pwr_down_mode;
	bool				pwr_down;
93 94 95 96 97

	union {
		__be32 d32;
		u8 d8[4];
	} data[3] ____cacheline_aligned;
98 99 100 101 102 103 104 105 106 107 108 109 110
};

/**
 * ad5791_supported_device_ids:
 */

enum ad5791_supported_device_ids {
	ID_AD5760,
	ID_AD5780,
	ID_AD5781,
	ID_AD5791,
};

111
static int ad5791_spi_write(struct ad5791_state *st, u8 addr, u32 val)
112
{
113
	st->data[0].d32 = cpu_to_be32(AD5791_CMD_WRITE |
114 115 116
			      AD5791_ADDR(addr) |
			      (val & AD5791_DAC_MASK));

117
	return spi_write(st->spi, &st->data[0].d8[1], 3);
118 119
}

120
static int ad5791_spi_read(struct ad5791_state *st, u8 addr, u32 *val)
121 122 123 124
{
	int ret;
	struct spi_transfer xfers[] = {
		{
125
			.tx_buf = &st->data[0].d8[1],
126 127 128 129
			.bits_per_word = 8,
			.len = 3,
			.cs_change = 1,
		}, {
130 131
			.tx_buf = &st->data[1].d8[1],
			.rx_buf = &st->data[2].d8[1],
132 133 134 135 136
			.bits_per_word = 8,
			.len = 3,
		},
	};

137
	st->data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
138
			      AD5791_ADDR(addr));
139
	st->data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
140

141
	ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
142

143
	*val = be32_to_cpu(st->data[2].d32);
144 145 146 147

	return ret;
}

148 149 150
static const char * const ad5791_powerdown_modes[] = {
	"6kohm_to_gnd",
	"three_state",
151
};
152

153 154
static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev,
	const struct iio_chan_spec *chan)
155
{
156
	struct ad5791_state *st = iio_priv(indio_dev);
157

158
	return st->pwr_down_mode;
159 160
}

161 162
static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev,
	const struct iio_chan_spec *chan, unsigned int mode)
163
{
164
	struct ad5791_state *st = iio_priv(indio_dev);
165

166
	st->pwr_down_mode = mode;
167

168
	return 0;
169 170
}

171 172 173 174 175 176 177 178 179
static const struct iio_enum ad5791_powerdown_mode_enum = {
	.items = ad5791_powerdown_modes,
	.num_items = ARRAY_SIZE(ad5791_powerdown_modes),
	.get = ad5791_get_powerdown_mode,
	.set = ad5791_set_powerdown_mode,
};

static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev,
	uintptr_t private, const struct iio_chan_spec *chan, char *buf)
180
{
181
	struct ad5791_state *st = iio_priv(indio_dev);
182 183 184 185

	return sprintf(buf, "%d\n", st->pwr_down);
}

186 187 188
static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev,
	 uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
	 size_t len)
189
{
190
	bool pwr_down;
191
	int ret;
192
	struct ad5791_state *st = iio_priv(indio_dev);
193

194
	ret = strtobool(buf, &pwr_down);
195 196 197
	if (ret)
		return ret;

198
	if (!pwr_down) {
199
		st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
200
	} else {
201 202 203 204
		if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
			st->ctrl |= AD5791_CTRL_OPGND;
		else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
			st->ctrl |= AD5791_CTRL_DACTRI;
205 206
	}
	st->pwr_down = pwr_down;
207

208
	ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl);
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

	return ret ? ret : len;
}

static int ad5791_get_lin_comp(unsigned int span)
{
	if (span <= 10000)
		return AD5791_LINCOMP_0_10;
	else if (span <= 12000)
		return AD5791_LINCOMP_10_12;
	else if (span <= 16000)
		return AD5791_LINCOMP_12_16;
	else if (span <= 19000)
		return AD5791_LINCOMP_16_19;
	else
		return AD5791_LINCOMP_19_20;
}

227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
static int ad5780_get_lin_comp(unsigned int span)
{
	if (span <= 10000)
		return AD5780_LINCOMP_0_10;
	else
		return AD5780_LINCOMP_10_20;
}
static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
	[ID_AD5760] = {
		.get_lin_comp = ad5780_get_lin_comp,
	},
	[ID_AD5780] = {
		.get_lin_comp = ad5780_get_lin_comp,
	},
	[ID_AD5781] = {
		.get_lin_comp = ad5791_get_lin_comp,
	},
	[ID_AD5791] = {
		.get_lin_comp = ad5791_get_lin_comp,
	},
};

249 250 251 252 253 254 255
static int ad5791_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val,
			   int *val2,
			   long m)
{
	struct ad5791_state *st = iio_priv(indio_dev);
256
	u64 val64;
257 258 259
	int ret;

	switch (m) {
260
	case IIO_CHAN_INFO_RAW:
261
		ret = ad5791_spi_read(st, chan->address, val);
262 263 264 265 266
		if (ret)
			return ret;
		*val &= AD5791_DAC_MASK;
		*val >>= chan->scan_type.shift;
		return IIO_VAL_INT;
267
	case IIO_CHAN_INFO_SCALE:
268 269 270
		*val = st->vref_mv;
		*val2 = (1 << chan->scan_type.realbits) - 1;
		return IIO_VAL_FRACTIONAL;
271
	case IIO_CHAN_INFO_OFFSET:
272 273 274 275
		val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
		do_div(val64, st->vref_mv);
		*val = -val64;
		return IIO_VAL_INT;
276 277 278 279 280 281
	default:
		return -EINVAL;
	}

};

282 283 284
static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
	{
		.name = "powerdown",
285
		.shared = IIO_SHARED_BY_TYPE,
286 287 288
		.read = ad5791_read_dac_powerdown,
		.write = ad5791_write_dac_powerdown,
	},
289 290
	IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
		 &ad5791_powerdown_mode_enum),
291 292 293 294
	IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
	{ },
};

295
#define AD5791_CHAN(bits, _shift) {			\
296 297 298 299 300
	.type = IIO_VOLTAGE,				\
	.output = 1,					\
	.indexed = 1,					\
	.address = AD5791_ADDR_DAC0,			\
	.channel = 0,					\
301 302 303
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
		BIT(IIO_CHAN_INFO_OFFSET),		\
304 305 306 307 308 309
	.scan_type = {					\
		.sign = 'u',				\
		.realbits = (bits),			\
		.storagebits = 24,			\
		.shift = (_shift),			\
	},						\
310 311 312 313 314 315 316 317 318
	.ext_info = ad5791_ext_info,			\
}

static const struct iio_chan_spec ad5791_channels[] = {
	[ID_AD5760] = AD5791_CHAN(16, 4),
	[ID_AD5780] = AD5791_CHAN(18, 2),
	[ID_AD5781] = AD5791_CHAN(18, 2),
	[ID_AD5791] = AD5791_CHAN(20, 0)
};
319 320 321 322 323 324 325 326 327 328

static int ad5791_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int val,
			    int val2,
			    long mask)
{
	struct ad5791_state *st = iio_priv(indio_dev);

	switch (mask) {
329
	case IIO_CHAN_INFO_RAW:
330
		val &= GENMASK(chan->scan_type.realbits - 1, 0);
331 332
		val <<= chan->scan_type.shift;

333
		return ad5791_spi_write(st, chan->address, val);
334 335 336 337 338 339

	default:
		return -EINVAL;
	}
}

340
static const struct iio_info ad5791_info = {
341 342
	.read_raw = &ad5791_read_raw,
	.write_raw = &ad5791_write_raw,
343 344
};

345
static int ad5791_probe(struct spi_device *spi)
346 347
{
	struct ad5791_platform_data *pdata = spi->dev.platform_data;
348
	struct iio_dev *indio_dev;
349 350 351
	struct ad5791_state *st;
	int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;

S
Sachin Kamat 已提交
352 353 354
	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
	if (!indio_dev)
		return -ENOMEM;
355
	st = iio_priv(indio_dev);
S
Sachin Kamat 已提交
356
	st->reg_vdd = devm_regulator_get(&spi->dev, "vdd");
357 358
	if (!IS_ERR(st->reg_vdd)) {
		ret = regulator_enable(st->reg_vdd);
359
		if (ret)
S
Sachin Kamat 已提交
360
			return ret;
361

362 363 364 365 366
		ret = regulator_get_voltage(st->reg_vdd);
		if (ret < 0)
			goto error_disable_reg_pos;

		pos_voltage_uv = ret;
367 368
	}

S
Sachin Kamat 已提交
369
	st->reg_vss = devm_regulator_get(&spi->dev, "vss");
370 371
	if (!IS_ERR(st->reg_vss)) {
		ret = regulator_enable(st->reg_vss);
372
		if (ret)
S
Sachin Kamat 已提交
373
			goto error_disable_reg_pos;
374

375 376 377 378 379
		ret = regulator_get_voltage(st->reg_vss);
		if (ret < 0)
			goto error_disable_reg_neg;

		neg_voltage_uv = ret;
380 381
	}

382 383 384
	st->pwr_down = true;
	st->spi = spi;

385 386 387 388 389 390 391
	if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
		st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
		st->vref_neg_mv = neg_voltage_uv / 1000;
	} else if (pdata) {
		st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
		st->vref_neg_mv = pdata->vref_neg_mv;
	} else {
392
		dev_warn(&spi->dev, "reference voltage unspecified\n");
393
	}
394

395
	ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
396
	if (ret)
397
		goto error_disable_reg_neg;
398

399 400
	st->chip_info =	&ad5791_chip_info_tbl[spi_get_device_id(spi)
					      ->driver_data];
401 402


403 404
	st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
		  | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
405 406
		  AD5791_CTRL_BIN2SC;

407
	ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl |
408 409
		AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
	if (ret)
410
		goto error_disable_reg_neg;
411

412 413 414 415
	spi_set_drvdata(spi, indio_dev);
	indio_dev->dev.parent = &spi->dev;
	indio_dev->info = &ad5791_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
416 417 418 419
	indio_dev->channels
		= &ad5791_channels[spi_get_device_id(spi)->driver_data];
	indio_dev->num_channels = 1;
	indio_dev->name = spi_get_device_id(st->spi)->name;
420
	ret = iio_device_register(indio_dev);
421
	if (ret)
422
		goto error_disable_reg_neg;
423 424 425 426

	return 0;

error_disable_reg_neg:
427 428
	if (!IS_ERR(st->reg_vss))
		regulator_disable(st->reg_vss);
429
error_disable_reg_pos:
430 431
	if (!IS_ERR(st->reg_vdd))
		regulator_disable(st->reg_vdd);
432 433 434
	return ret;
}

435
static int ad5791_remove(struct spi_device *spi)
436
{
437 438
	struct iio_dev *indio_dev = spi_get_drvdata(spi);
	struct ad5791_state *st = iio_priv(indio_dev);
439

440
	iio_device_unregister(indio_dev);
S
Sachin Kamat 已提交
441
	if (!IS_ERR(st->reg_vdd))
442
		regulator_disable(st->reg_vdd);
443

S
Sachin Kamat 已提交
444
	if (!IS_ERR(st->reg_vss))
445
		regulator_disable(st->reg_vss);
446

447 448 449 450
	return 0;
}

static const struct spi_device_id ad5791_id[] = {
451 452
	{"ad5760", ID_AD5760},
	{"ad5780", ID_AD5780},
453
	{"ad5781", ID_AD5781},
454
	{"ad5790", ID_AD5791},
455
	{"ad5791", ID_AD5791},
456 457
	{}
};
458
MODULE_DEVICE_TABLE(spi, ad5791_id);
459 460 461 462 463 464

static struct spi_driver ad5791_driver = {
	.driver = {
		   .name = "ad5791",
		   },
	.probe = ad5791_probe,
465
	.remove = ad5791_remove,
466 467
	.id_table = ad5791_id,
};
468
module_spi_driver(ad5791_driver);
469 470

MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
471
MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
472
MODULE_LICENSE("GPL v2");