Merge branch 'for-linus' of git://neil.brown.name/md
[deliverable/linux.git] / drivers / staging / iio / dac / ad5504.c
1 /*
2 * AD5504, AD5501 High Voltage Digital to Analog Converter
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9 #include <linux/interrupt.h>
10 #include <linux/gpio.h>
11 #include <linux/fs.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/spi/spi.h>
15 #include <linux/slab.h>
16 #include <linux/sysfs.h>
17 #include <linux/regulator/consumer.h>
18
19 #include "../iio.h"
20 #include "../sysfs.h"
21 #include "dac.h"
22 #include "ad5504.h"
23
24 static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val)
25 {
26 u16 tmp = cpu_to_be16(AD5504_CMD_WRITE |
27 AD5504_ADDR(addr) |
28 (val & AD5504_RES_MASK));
29
30 return spi_write(spi, (u8 *)&tmp, 2);
31 }
32
33 static int ad5504_spi_read(struct spi_device *spi, u8 addr, u16 *val)
34 {
35 u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
36 int ret;
37 struct spi_transfer t = {
38 .tx_buf = &tmp,
39 .rx_buf = val,
40 .len = 2,
41 };
42 struct spi_message m;
43
44 spi_message_init(&m);
45 spi_message_add_tail(&t, &m);
46 ret = spi_sync(spi, &m);
47
48 *val = be16_to_cpu(*val) & AD5504_RES_MASK;
49
50 return ret;
51 }
52
53 static ssize_t ad5504_write_dac(struct device *dev,
54 struct device_attribute *attr,
55 const char *buf, size_t len)
56 {
57 struct iio_dev *indio_dev = dev_get_drvdata(dev);
58 struct ad5504_state *st = iio_priv(indio_dev);
59 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
60 long readin;
61 int ret;
62
63 ret = strict_strtol(buf, 10, &readin);
64 if (ret)
65 return ret;
66
67 ret = ad5504_spi_write(st->spi, this_attr->address, readin);
68 return ret ? ret : len;
69 }
70
71 static ssize_t ad5504_read_dac(struct device *dev,
72 struct device_attribute *attr,
73 char *buf)
74 {
75 struct iio_dev *indio_dev = dev_get_drvdata(dev);
76 struct ad5504_state *st = iio_priv(indio_dev);
77 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
78 int ret;
79 u16 val;
80
81 ret = ad5504_spi_read(st->spi, this_attr->address, &val);
82 if (ret)
83 return ret;
84
85 return sprintf(buf, "%d\n", val);
86 }
87
88 static ssize_t ad5504_read_powerdown_mode(struct device *dev,
89 struct device_attribute *attr, char *buf)
90 {
91 struct iio_dev *indio_dev = dev_get_drvdata(dev);
92 struct ad5504_state *st = iio_priv(indio_dev);
93
94 const char mode[][14] = {"20kohm_to_gnd", "three_state"};
95
96 return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
97 }
98
99 static ssize_t ad5504_write_powerdown_mode(struct device *dev,
100 struct device_attribute *attr,
101 const char *buf, size_t len)
102 {
103 struct iio_dev *indio_dev = dev_get_drvdata(dev);
104 struct ad5504_state *st = iio_priv(indio_dev);
105 int ret;
106
107 if (sysfs_streq(buf, "20kohm_to_gnd"))
108 st->pwr_down_mode = AD5504_DAC_PWRDN_20K;
109 else if (sysfs_streq(buf, "three_state"))
110 st->pwr_down_mode = AD5504_DAC_PWRDN_3STATE;
111 else
112 ret = -EINVAL;
113
114 return ret ? ret : len;
115 }
116
117 static ssize_t ad5504_read_dac_powerdown(struct device *dev,
118 struct device_attribute *attr,
119 char *buf)
120 {
121 struct iio_dev *indio_dev = dev_get_drvdata(dev);
122 struct ad5504_state *st = iio_priv(indio_dev);
123 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
124
125 return sprintf(buf, "%d\n",
126 !(st->pwr_down_mask & (1 << this_attr->address)));
127 }
128
129 static ssize_t ad5504_write_dac_powerdown(struct device *dev,
130 struct device_attribute *attr,
131 const char *buf, size_t len)
132 {
133 long readin;
134 int ret;
135 struct iio_dev *indio_dev = dev_get_drvdata(dev);
136 struct ad5504_state *st = iio_priv(indio_dev);
137 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
138
139 ret = strict_strtol(buf, 10, &readin);
140 if (ret)
141 return ret;
142
143 if (readin == 0)
144 st->pwr_down_mask |= (1 << this_attr->address);
145 else if (readin == 1)
146 st->pwr_down_mask &= ~(1 << this_attr->address);
147 else
148 ret = -EINVAL;
149
150 ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL,
151 AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) |
152 AD5504_DAC_PWR(st->pwr_down_mask));
153
154 /* writes to the CTRL register must be followed by a NOOP */
155 ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0);
156
157 return ret ? ret : len;
158 }
159
160 static ssize_t ad5504_show_scale(struct device *dev,
161 struct device_attribute *attr,
162 char *buf)
163 {
164 struct iio_dev *indio_dev = dev_get_drvdata(dev);
165 struct ad5504_state *st = iio_priv(indio_dev);
166 /* Corresponds to Vref / 2^(bits) */
167 unsigned int scale_uv = (st->vref_mv * 1000) >> AD5505_BITS;
168
169 return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
170 }
171 static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5504_show_scale, NULL, 0);
172
173 #define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr) \
174 IIO_DEVICE_ATTR(out##_num##_raw, \
175 S_IRUGO | S_IWUSR, _show, _store, _addr)
176
177 static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5504_read_dac,
178 ad5504_write_dac, AD5504_ADDR_DAC0);
179 static IIO_DEV_ATTR_OUT_RW_RAW(1, ad5504_read_dac,
180 ad5504_write_dac, AD5504_ADDR_DAC1);
181 static IIO_DEV_ATTR_OUT_RW_RAW(2, ad5504_read_dac,
182 ad5504_write_dac, AD5504_ADDR_DAC2);
183 static IIO_DEV_ATTR_OUT_RW_RAW(3, ad5504_read_dac,
184 ad5504_write_dac, AD5504_ADDR_DAC3);
185
186 static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
187 S_IWUSR, ad5504_read_powerdown_mode,
188 ad5504_write_powerdown_mode, 0);
189
190 static IIO_CONST_ATTR(out_powerdown_mode_available,
191 "20kohm_to_gnd three_state");
192
193 #define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \
194 IIO_DEVICE_ATTR(out##_num##_powerdown, \
195 S_IRUGO | S_IWUSR, _show, _store, _addr)
196
197 static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5504_read_dac_powerdown,
198 ad5504_write_dac_powerdown, 0);
199 static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5504_read_dac_powerdown,
200 ad5504_write_dac_powerdown, 1);
201 static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5504_read_dac_powerdown,
202 ad5504_write_dac_powerdown, 2);
203 static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5504_read_dac_powerdown,
204 ad5504_write_dac_powerdown, 3);
205
206 static struct attribute *ad5504_attributes[] = {
207 &iio_dev_attr_out0_raw.dev_attr.attr,
208 &iio_dev_attr_out1_raw.dev_attr.attr,
209 &iio_dev_attr_out2_raw.dev_attr.attr,
210 &iio_dev_attr_out3_raw.dev_attr.attr,
211 &iio_dev_attr_out0_powerdown.dev_attr.attr,
212 &iio_dev_attr_out1_powerdown.dev_attr.attr,
213 &iio_dev_attr_out2_powerdown.dev_attr.attr,
214 &iio_dev_attr_out3_powerdown.dev_attr.attr,
215 &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
216 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
217 &iio_dev_attr_out_scale.dev_attr.attr,
218 NULL,
219 };
220
221 static const struct attribute_group ad5504_attribute_group = {
222 .attrs = ad5504_attributes,
223 };
224
225 static struct attribute *ad5501_attributes[] = {
226 &iio_dev_attr_out0_raw.dev_attr.attr,
227 &iio_dev_attr_out0_powerdown.dev_attr.attr,
228 &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
229 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
230 &iio_dev_attr_out_scale.dev_attr.attr,
231 NULL,
232 };
233
234 static const struct attribute_group ad5501_attribute_group = {
235 .attrs = ad5501_attributes,
236 };
237
238 static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000");
239 static IIO_CONST_ATTR(temp0_thresh_rising_en, "1");
240
241 static struct attribute *ad5504_ev_attributes[] = {
242 &iio_const_attr_temp0_thresh_rising_value.dev_attr.attr,
243 &iio_const_attr_temp0_thresh_rising_en.dev_attr.attr,
244 NULL,
245 };
246
247 static struct attribute_group ad5504_ev_attribute_group = {
248 .attrs = ad5504_ev_attributes,
249 };
250
251 static irqreturn_t ad5504_event_handler(int irq, void *private)
252 {
253 iio_push_event(private, 0,
254 IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP,
255 0,
256 IIO_EV_TYPE_THRESH,
257 IIO_EV_DIR_RISING),
258 iio_get_time_ns());
259
260 return IRQ_HANDLED;
261 }
262
263 static const struct iio_info ad5504_info = {
264 .attrs = &ad5504_attribute_group,
265 .num_interrupt_lines = 1,
266 .event_attrs = &ad5504_ev_attribute_group,
267 .driver_module = THIS_MODULE,
268 };
269
270 static const struct iio_info ad5501_info = {
271 .attrs = &ad5501_attribute_group,
272 .num_interrupt_lines = 1,
273 .event_attrs = &ad5504_ev_attribute_group,
274 .driver_module = THIS_MODULE,
275 };
276
277 static int __devinit ad5504_probe(struct spi_device *spi)
278 {
279 struct ad5504_platform_data *pdata = spi->dev.platform_data;
280 struct iio_dev *indio_dev;
281 struct ad5504_state *st;
282 struct regulator *reg;
283 int ret, voltage_uv = 0;
284
285 reg = regulator_get(&spi->dev, "vcc");
286 if (!IS_ERR(reg)) {
287 ret = regulator_enable(reg);
288 if (ret)
289 goto error_put_reg;
290
291 voltage_uv = regulator_get_voltage(reg);
292 }
293
294 indio_dev = iio_allocate_device(sizeof(*st));
295 if (indio_dev == NULL) {
296 ret = -ENOMEM;
297 goto error_disable_reg;
298 }
299 spi_set_drvdata(spi, indio_dev);
300 st = iio_priv(indio_dev);
301 if (voltage_uv)
302 st->vref_mv = voltage_uv / 1000;
303 else if (pdata)
304 st->vref_mv = pdata->vref_mv;
305 else
306 dev_warn(&spi->dev, "reference voltage unspecified\n");
307
308 st->reg = reg;
309 st->spi = spi;
310 indio_dev->dev.parent = &spi->dev;
311 indio_dev->name = spi_get_device_id(st->spi)->name;
312 if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
313 indio_dev->info = &ad5501_info;
314 else
315 indio_dev->info = &ad5504_info;
316 indio_dev->modes = INDIO_DIRECT_MODE;
317
318 ret = iio_device_register(indio_dev);
319 if (ret)
320 goto error_free_dev;
321
322 if (spi->irq) {
323 ret = request_threaded_irq(spi->irq,
324 NULL,
325 &ad5504_event_handler,
326 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
327 spi_get_device_id(st->spi)->name,
328 indio_dev);
329 if (ret)
330 goto error_unreg_iio_device;
331 }
332
333 return 0;
334
335 error_unreg_iio_device:
336 iio_device_unregister(indio_dev);
337 error_free_dev:
338 iio_free_device(indio_dev);
339 error_disable_reg:
340 if (!IS_ERR(reg))
341 regulator_disable(st->reg);
342 error_put_reg:
343 if (!IS_ERR(reg))
344 regulator_put(reg);
345
346 return ret;
347 }
348
349 static int __devexit ad5504_remove(struct spi_device *spi)
350 {
351 struct iio_dev *indio_dev = spi_get_drvdata(spi);
352 struct ad5504_state *st = iio_priv(indio_dev);
353 struct regulator *reg = st->reg;
354 if (spi->irq)
355 free_irq(spi->irq, indio_dev);
356
357 iio_device_unregister(indio_dev);
358
359 if (!IS_ERR(reg)) {
360 regulator_disable(reg);
361 regulator_put(reg);
362 }
363
364 return 0;
365 }
366
367 static const struct spi_device_id ad5504_id[] = {
368 {"ad5504", ID_AD5504},
369 {"ad5501", ID_AD5501},
370 {}
371 };
372
373 static struct spi_driver ad5504_driver = {
374 .driver = {
375 .name = "ad5504",
376 .owner = THIS_MODULE,
377 },
378 .probe = ad5504_probe,
379 .remove = __devexit_p(ad5504_remove),
380 .id_table = ad5504_id,
381 };
382
383 static __init int ad5504_spi_init(void)
384 {
385 return spi_register_driver(&ad5504_driver);
386 }
387 module_init(ad5504_spi_init);
388
389 static __exit void ad5504_spi_exit(void)
390 {
391 spi_unregister_driver(&ad5504_driver);
392 }
393 module_exit(ad5504_spi_exit);
394
395 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
396 MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
397 MODULE_LICENSE("GPL v2");
This page took 0.040401 seconds and 6 git commands to generate.