2 * AD5504, AD5501 High Voltage Digital to Analog Converter
4 * Copyright 2011 Analog Devices Inc.
6 * Licensed under the GPL-2.
9 #include <linux/interrupt.h>
10 #include <linux/gpio.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>
24 static int ad5504_spi_write(struct spi_device
*spi
, u8 addr
, u16 val
)
26 u16 tmp
= cpu_to_be16(AD5504_CMD_WRITE
|
28 (val
& AD5504_RES_MASK
));
30 return spi_write(spi
, (u8
*)&tmp
, 2);
33 static int ad5504_spi_read(struct spi_device
*spi
, u8 addr
, u16
*val
)
35 u16 tmp
= cpu_to_be16(AD5504_CMD_READ
| AD5504_ADDR(addr
));
37 struct spi_transfer t
= {
45 spi_message_add_tail(&t
, &m
);
46 ret
= spi_sync(spi
, &m
);
48 *val
= be16_to_cpu(*val
) & AD5504_RES_MASK
;
53 static ssize_t
ad5504_write_dac(struct device
*dev
,
54 struct device_attribute
*attr
,
55 const char *buf
, size_t len
)
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
);
63 ret
= strict_strtol(buf
, 10, &readin
);
67 ret
= ad5504_spi_write(st
->spi
, this_attr
->address
, readin
);
68 return ret
? ret
: len
;
71 static ssize_t
ad5504_read_dac(struct device
*dev
,
72 struct device_attribute
*attr
,
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
);
81 ret
= ad5504_spi_read(st
->spi
, this_attr
->address
, &val
);
85 return sprintf(buf
, "%d\n", val
);
88 static ssize_t
ad5504_read_powerdown_mode(struct device
*dev
,
89 struct device_attribute
*attr
, char *buf
)
91 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
92 struct ad5504_state
*st
= iio_priv(indio_dev
);
94 const char mode
[][14] = {"20kohm_to_gnd", "three_state"};
96 return sprintf(buf
, "%s\n", mode
[st
->pwr_down_mode
]);
99 static ssize_t
ad5504_write_powerdown_mode(struct device
*dev
,
100 struct device_attribute
*attr
,
101 const char *buf
, size_t len
)
103 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
104 struct ad5504_state
*st
= iio_priv(indio_dev
);
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
;
114 return ret
? ret
: len
;
117 static ssize_t
ad5504_read_dac_powerdown(struct device
*dev
,
118 struct device_attribute
*attr
,
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
);
125 return sprintf(buf
, "%d\n",
126 !(st
->pwr_down_mask
& (1 << this_attr
->address
)));
129 static ssize_t
ad5504_write_dac_powerdown(struct device
*dev
,
130 struct device_attribute
*attr
,
131 const char *buf
, size_t len
)
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
);
139 ret
= strict_strtol(buf
, 10, &readin
);
144 st
->pwr_down_mask
|= (1 << this_attr
->address
);
145 else if (readin
== 1)
146 st
->pwr_down_mask
&= ~(1 << this_attr
->address
);
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
));
154 /* writes to the CTRL register must be followed by a NOOP */
155 ad5504_spi_write(st
->spi
, AD5504_ADDR_NOOP
, 0);
157 return ret
? ret
: len
;
160 static ssize_t
ad5504_show_scale(struct device
*dev
,
161 struct device_attribute
*attr
,
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
;
169 return sprintf(buf
, "%d.%03d\n", scale_uv
/ 1000, scale_uv
% 1000);
171 static IIO_DEVICE_ATTR(out_scale
, S_IRUGO
, ad5504_show_scale
, NULL
, 0);
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)
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
);
186 static IIO_DEVICE_ATTR(out_powerdown_mode
, S_IRUGO
|
187 S_IWUSR
, ad5504_read_powerdown_mode
,
188 ad5504_write_powerdown_mode
, 0);
190 static IIO_CONST_ATTR(out_powerdown_mode_available
,
191 "20kohm_to_gnd three_state");
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)
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);
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
,
221 static const struct attribute_group ad5504_attribute_group
= {
222 .attrs
= ad5504_attributes
,
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
,
234 static const struct attribute_group ad5501_attribute_group
= {
235 .attrs
= ad5501_attributes
,
238 static IIO_CONST_ATTR(temp0_thresh_rising_value
, "110000");
239 static IIO_CONST_ATTR(temp0_thresh_rising_en
, "1");
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
,
247 static struct attribute_group ad5504_ev_attribute_group
= {
248 .attrs
= ad5504_ev_attributes
,
251 static irqreturn_t
ad5504_event_handler(int irq
, void *private)
253 iio_push_event(private, 0,
254 IIO_UNMOD_EVENT_CODE(IIO_TEMP
,
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
,
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
,
277 static int __devinit
ad5504_probe(struct spi_device
*spi
)
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;
285 reg
= regulator_get(&spi
->dev
, "vcc");
287 ret
= regulator_enable(reg
);
291 voltage_uv
= regulator_get_voltage(reg
);
294 indio_dev
= iio_allocate_device(sizeof(*st
));
295 if (indio_dev
== NULL
) {
297 goto error_disable_reg
;
299 spi_set_drvdata(spi
, indio_dev
);
300 st
= iio_priv(indio_dev
);
302 st
->vref_mv
= voltage_uv
/ 1000;
304 st
->vref_mv
= pdata
->vref_mv
;
306 dev_warn(&spi
->dev
, "reference voltage unspecified\n");
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
;
315 indio_dev
->info
= &ad5504_info
;
316 indio_dev
->modes
= INDIO_DIRECT_MODE
;
318 ret
= iio_device_register(indio_dev
);
323 ret
= request_threaded_irq(spi
->irq
,
325 &ad5504_event_handler
,
326 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
327 spi_get_device_id(st
->spi
)->name
,
330 goto error_unreg_iio_device
;
335 error_unreg_iio_device
:
336 iio_device_unregister(indio_dev
);
338 iio_free_device(indio_dev
);
341 regulator_disable(reg
);
349 static int __devexit
ad5504_remove(struct spi_device
*spi
)
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
;
355 free_irq(spi
->irq
, indio_dev
);
357 iio_device_unregister(indio_dev
);
360 regulator_disable(reg
);
367 static const struct spi_device_id ad5504_id
[] = {
368 {"ad5504", ID_AD5504
},
369 {"ad5501", ID_AD5501
},
373 static struct spi_driver ad5504_driver
= {
376 .owner
= THIS_MODULE
,
378 .probe
= ad5504_probe
,
379 .remove
= __devexit_p(ad5504_remove
),
380 .id_table
= ad5504_id
,
383 static __init
int ad5504_spi_init(void)
385 return spi_register_driver(&ad5504_driver
);
387 module_init(ad5504_spi_init
);
389 static __exit
void ad5504_spi_exit(void)
391 spi_unregister_driver(&ad5504_driver
);
393 module_exit(ad5504_spi_exit
);
395 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
396 MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
397 MODULE_LICENSE("GPL v2");