ad5791.c 11.1 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

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

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
#define AD5791_RES_MASK(x)		((1 << (x)) - 1)
#define AD5791_DAC_MASK			AD5791_RES_MASK(20)
#define AD5791_DAC_MSB			(1 << 19)

#define AD5791_CMD_READ			(1 << 23)
#define AD5791_CMD_WRITE		(0 << 23)
#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 */
#define AD5791_CTRL_RBUF		(1 << 1)
#define AD5791_CTRL_OPGND		(1 << 2)
#define AD5791_CTRL_DACTRI		(1 << 3)
#define AD5791_CTRL_BIN2SC		(1 << 4)
#define AD5791_CTRL_SDODIS		(1 << 5)
#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 */
#define AD5791_SWCTRL_LDAC		(1 << 0)
#define AD5791_SWCTRL_CLR		(1 << 1)
#define AD5791_SWCTRL_RESET		(1 << 2)

#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
 * @us:			spi_device
 * @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;
94 95 96 97 98

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

/**
 * ad5791_supported_device_ids:
 */

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

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

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

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

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

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

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

	return ret;
}

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

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

159
	return st->pwr_down_mode;
160 161
}

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

167
	st->pwr_down_mode = mode;
168

169
	return 0;
170 171
}

172 173 174 175 176 177 178 179 180
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)
181
{
182
	struct ad5791_state *st = iio_priv(indio_dev);
183 184 185 186

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

187 188 189
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)
190
{
191
	bool pwr_down;
192
	int ret;
193
	struct ad5791_state *st = iio_priv(indio_dev);
194

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

199
	if (!pwr_down) {
200
		st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
201
	} else {
202 203 204 205
		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;
206 207
	}
	st->pwr_down = pwr_down;
208

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

	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;
}

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
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,
	},
};

250 251 252 253 254 255 256
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);
257
	u64 val64;
258 259 260
	int ret;

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

};

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

296
#define AD5791_CHAN(bits, _shift) {			\
297 298 299 300 301
	.type = IIO_VOLTAGE,				\
	.output = 1,					\
	.indexed = 1,					\
	.address = AD5791_ADDR_DAC0,			\
	.channel = 0,					\
302 303 304
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
		BIT(IIO_CHAN_INFO_OFFSET),		\
305 306 307 308 309 310
	.scan_type = {					\
		.sign = 'u',				\
		.realbits = (bits),			\
		.storagebits = 24,			\
		.shift = (_shift),			\
	},						\
311 312 313 314 315 316 317 318 319
	.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)
};
320 321 322 323 324 325 326 327 328 329

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) {
330
	case IIO_CHAN_INFO_RAW:
331
		val &= AD5791_RES_MASK(chan->scan_type.realbits);
332 333
		val <<= chan->scan_type.shift;

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

	default:
		return -EINVAL;
	}
}

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

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

354 355 356
	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
	if (!indio_dev)
		return -ENOMEM;
357
	st = iio_priv(indio_dev);
358
	st->reg_vdd = devm_regulator_get(&spi->dev, "vdd");
359 360
	if (!IS_ERR(st->reg_vdd)) {
		ret = regulator_enable(st->reg_vdd);
361
		if (ret)
362
			return ret;
363

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

		pos_voltage_uv = ret;
369 370
	}

371
	st->reg_vss = devm_regulator_get(&spi->dev, "vss");
372 373
	if (!IS_ERR(st->reg_vss)) {
		ret = regulator_enable(st->reg_vss);
374
		if (ret)
375
			goto error_disable_reg_pos;
376

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

		neg_voltage_uv = ret;
382 383
	}

384 385 386
	st->pwr_down = true;
	st->spi = spi;

387 388 389 390 391 392 393
	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 {
394
		dev_warn(&spi->dev, "reference voltage unspecified\n");
395
	}
396

397
	ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
398
	if (ret)
399
		goto error_disable_reg_neg;
400

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


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

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

414 415 416 417
	spi_set_drvdata(spi, indio_dev);
	indio_dev->dev.parent = &spi->dev;
	indio_dev->info = &ad5791_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
418 419 420 421
	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;
422
	ret = iio_device_register(indio_dev);
423
	if (ret)
424
		goto error_disable_reg_neg;
425 426 427 428

	return 0;

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

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

442
	iio_device_unregister(indio_dev);
443
	if (!IS_ERR(st->reg_vdd))
444
		regulator_disable(st->reg_vdd);
445

446
	if (!IS_ERR(st->reg_vss))
447
		regulator_disable(st->reg_vss);
448

449 450 451 452
	return 0;
}

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

static struct spi_driver ad5791_driver = {
	.driver = {
		   .name = "ad5791",
		   .owner = THIS_MODULE,
		   },
	.probe = ad5791_probe,
468
	.remove = ad5791_remove,
469 470
	.id_table = ad5791_id,
};
471
module_spi_driver(ad5791_driver);
472 473

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