ad5624r_spi.c 7.5 KB
Newer Older
1 2 3
/*
 * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver
 *
4
 * Copyright 2010-2011 Analog Devices Inc.
5
 *
6
 * Licensed under the GPL-2.
7 8 9 10 11 12 13 14 15
 */

#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>
16
#include <linux/regulator/consumer.h>
17
#include <linux/module.h>
18

19 20
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
21

22 23
#include "ad5624r.h"

24 25
static int ad5624r_spi_write(struct spi_device *spi,
			     u8 cmd, u8 addr, u16 val, u8 len)
26 27 28 29 30
{
	u32 data;
	u8 msg[3];

	/*
31 32 33 34 35 36
	 * The input shift register is 24 bits wide. The first two bits are
	 * don't care bits. The next three are the command bits, C2 to C0,
	 * followed by the 3-bit DAC address, A2 to A0, and then the
	 * 16-, 14-, 12-bit data-word. The data-word comprises the 16-,
	 * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits,
	 * for the AD5664R, AD5644R, and AD5624R, respectively.
37 38 39 40 41 42
	 */
	data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len));
	msg[0] = data >> 16;
	msg[1] = data >> 8;
	msg[2] = data;

43
	return spi_write(spi, msg, 3);
44 45
}

46 47 48 49 50
static int ad5624r_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val,
			   int *val2,
			   long m)
51
{
52
	struct ad5624r_state *st = iio_priv(indio_dev);
53
	unsigned long scale_uv;
54

55 56 57 58 59 60
	switch (m) {
	case IIO_CHAN_INFO_SCALE:
		scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
		*val =  scale_uv / 1000;
		*val2 = (scale_uv % 1000) * 1000;
		return IIO_VAL_INT_PLUS_MICRO;
61

62 63 64 65 66 67 68 69 70 71 72 73 74 75
	}
	return -EINVAL;
}

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

	switch (mask) {
76
	case IIO_CHAN_INFO_RAW:
77 78 79 80 81 82 83 84 85 86 87 88
		if (val >= (1 << chan->scan_type.realbits) || val < 0)
			return -EINVAL;

		return ad5624r_spi_write(st->us,
				AD5624R_CMD_WRITE_INPUT_N_UPDATE_N,
				chan->address, val,
				chan->scan_type.shift);
	default:
		ret = -EINVAL;
	}

	return -EINVAL;
89 90
}

91 92 93 94 95 96 97 98
static const char * const ad5624r_powerdown_modes[] = {
	"1kohm_to_gnd",
	"100kohm_to_gnd",
	"three_state"
};

static int ad5624r_get_powerdown_mode(struct iio_dev *indio_dev,
	const struct iio_chan_spec *chan)
99
{
100
	struct ad5624r_state *st = iio_priv(indio_dev);
101

102
	return st->pwr_down_mode;
103 104
}

105 106
static int ad5624r_set_powerdown_mode(struct iio_dev *indio_dev,
	const struct iio_chan_spec *chan, unsigned int mode)
107
{
108
	struct ad5624r_state *st = iio_priv(indio_dev);
109

110
	st->pwr_down_mode = mode;
111

112
	return 0;
113 114
}

115 116 117 118 119 120 121 122 123
static const struct iio_enum ad5624r_powerdown_mode_enum = {
	.items = ad5624r_powerdown_modes,
	.num_items = ARRAY_SIZE(ad5624r_powerdown_modes),
	.get = ad5624r_get_powerdown_mode,
	.set = ad5624r_set_powerdown_mode,
};

static ssize_t ad5624r_read_dac_powerdown(struct iio_dev *indio_dev,
	uintptr_t private, const struct iio_chan_spec *chan, char *buf)
124
{
125
	struct ad5624r_state *st = iio_priv(indio_dev);
126

127
	return sprintf(buf, "%d\n",
128
			!!(st->pwr_down_mask & (1 << chan->channel)));
129 130
}

131 132 133
static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev,
	uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
	size_t len)
134
{
135
	bool pwr_down;
136
	int ret;
137
	struct ad5624r_state *st = iio_priv(indio_dev);
138

139
	ret = strtobool(buf, &pwr_down);
140 141 142
	if (ret)
		return ret;

143
	if (pwr_down)
144
		st->pwr_down_mask |= (1 << chan->channel);
145
	else
146
		st->pwr_down_mask &= ~(1 << chan->channel);
147

148 149 150
	ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0,
				(st->pwr_down_mode << 4) |
				st->pwr_down_mask, 16);
151 152 153 154

	return ret ? ret : len;
}

155
static const struct iio_info ad5624r_info = {
156 157
	.write_raw = ad5624r_write_raw,
	.read_raw = ad5624r_read_raw,
158 159 160
	.driver_module = THIS_MODULE,
};

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
	{
		.name = "powerdown",
		.read = ad5624r_read_dac_powerdown,
		.write = ad5624r_write_dac_powerdown,
	},
	IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
	IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
	{ },
};

#define AD5624R_CHANNEL(_chan, _bits) { \
	.type = IIO_VOLTAGE, \
	.indexed = 1, \
	.output = 1, \
	.channel = (_chan), \
	.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
		     IIO_CHAN_INFO_SCALE_SHARED_BIT, \
	.address = (_chan), \
	.scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \
	.ext_info = ad5624r_ext_info, \
}

#define DECLARE_AD5624R_CHANNELS(_name, _bits) \
	const struct iio_chan_spec _name##_channels[] = { \
		AD5624R_CHANNEL(0, _bits), \
		AD5624R_CHANNEL(1, _bits), \
		AD5624R_CHANNEL(2, _bits), \
		AD5624R_CHANNEL(3, _bits), \
}

static DECLARE_AD5624R_CHANNELS(ad5624r, 12);
static DECLARE_AD5624R_CHANNELS(ad5644r, 14);
static DECLARE_AD5624R_CHANNELS(ad5664r, 16);

static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = {
	[ID_AD5624R3] = {
		.channels = ad5624r_channels,
		.int_vref_mv = 1250,
	},
	[ID_AD5624R5] = {
		.channels = ad5624r_channels,
		.int_vref_mv = 2500,
	},
	[ID_AD5644R3] = {
		.channels = ad5644r_channels,
		.int_vref_mv = 1250,
	},
	[ID_AD5644R5] = {
		.channels = ad5644r_channels,
		.int_vref_mv = 2500,
	},
	[ID_AD5664R3] = {
		.channels = ad5664r_channels,
		.int_vref_mv = 1250,
	},
	[ID_AD5664R5] = {
		.channels = ad5664r_channels,
		.int_vref_mv = 2500,
	},
};

223
static int ad5624r_probe(struct spi_device *spi)
224 225
{
	struct ad5624r_state *st;
226
	struct iio_dev *indio_dev;
227
	int ret, voltage_uv = 0;
228

229
	indio_dev = iio_device_alloc(sizeof(*st));
230 231
	if (indio_dev == NULL) {
		ret = -ENOMEM;
232
		goto error_ret;
233 234
	}
	st = iio_priv(indio_dev);
235 236 237 238 239 240 241 242 243
	st->reg = regulator_get(&spi->dev, "vcc");
	if (!IS_ERR(st->reg)) {
		ret = regulator_enable(st->reg);
		if (ret)
			goto error_put_reg;

		voltage_uv = regulator_get_voltage(st->reg);
	}

244
	spi_set_drvdata(spi, indio_dev);
245 246 247 248 249 250 251
	st->chip_info =
		&ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data];

	if (voltage_uv)
		st->vref_mv = voltage_uv / 1000;
	else
		st->vref_mv = st->chip_info->int_vref_mv;
252 253 254

	st->us = spi;

255 256 257 258
	indio_dev->dev.parent = &spi->dev;
	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->info = &ad5624r_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
259 260
	indio_dev->channels = st->chip_info->channels;
	indio_dev->num_channels = AD5624R_DAC_CHANNELS;
261

262 263
	ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0,
				!!voltage_uv, 16);
264
	if (ret)
265
		goto error_disable_reg;
266

267
	ret = iio_device_register(indio_dev);
268
	if (ret)
269
		goto error_disable_reg;
270 271 272

	return 0;

273
error_disable_reg:
274 275
	if (!IS_ERR(st->reg))
		regulator_disable(st->reg);
276
error_put_reg:
277 278
	if (!IS_ERR(st->reg))
		regulator_put(st->reg);
279
	iio_device_free(indio_dev);
280
error_ret:
281

282 283 284
	return ret;
}

285
static int ad5624r_remove(struct spi_device *spi)
286
{
287 288 289
	struct iio_dev *indio_dev = spi_get_drvdata(spi);
	struct ad5624r_state *st = iio_priv(indio_dev);

290
	iio_device_unregister(indio_dev);
291 292 293
	if (!IS_ERR(st->reg)) {
		regulator_disable(st->reg);
		regulator_put(st->reg);
294
	}
295
	iio_device_free(indio_dev);
296

297 298 299
	return 0;
}

300
static const struct spi_device_id ad5624r_id[] = {
301 302 303 304 305 306
	{"ad5624r3", ID_AD5624R3},
	{"ad5644r3", ID_AD5644R3},
	{"ad5664r3", ID_AD5664R3},
	{"ad5624r5", ID_AD5624R5},
	{"ad5644r5", ID_AD5644R5},
	{"ad5664r5", ID_AD5664R5},
307 308
	{}
};
309
MODULE_DEVICE_TABLE(spi, ad5624r_id);
310

311 312
static struct spi_driver ad5624r_driver = {
	.driver = {
313 314 315
		   .name = "ad5624r",
		   .owner = THIS_MODULE,
		   },
316
	.probe = ad5624r_probe,
317
	.remove = ad5624r_remove,
318
	.id_table = ad5624r_id,
319
};
320
module_spi_driver(ad5624r_driver);
321 322 323 324

MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
MODULE_DESCRIPTION("Analog Devices AD5624/44/64R DAC spi driver");
MODULE_LICENSE("GPL v2");