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>
11 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/spi/spi.h>
14 #include <linux/slab.h>
15 #include <linux/sysfs.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/module.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21 #include <linux/iio/events.h>
22 #include <linux/iio/dac/ad5504.h>
24 #define AD5505_BITS 12
25 #define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1)
27 #define AD5504_CMD_READ (1 << 15)
28 #define AD5504_CMD_WRITE (0 << 15)
29 #define AD5504_ADDR(addr) ((addr) << 12)
32 #define AD5504_ADDR_NOOP 0
33 #define AD5504_ADDR_DAC(x) ((x) + 1)
34 #define AD5504_ADDR_ALL_DAC 5
35 #define AD5504_ADDR_CTRL 7
37 /* Control Register */
38 #define AD5504_DAC_PWR(ch) ((ch) << 2)
39 #define AD5504_DAC_PWRDWN_MODE(mode) ((mode) << 6)
40 #define AD5504_DAC_PWRDN_20K 0
41 #define AD5504_DAC_PWRDN_3STATE 1
44 * struct ad5446_state - driver instance specific data
46 * @reg: supply regulator
47 * @vref_mv: actual reference voltage used
48 * @pwr_down_mask power down mask
49 * @pwr_down_mode current power down mode
53 struct spi_device
*spi
;
54 struct regulator
*reg
;
55 unsigned short vref_mv
;
56 unsigned pwr_down_mask
;
57 unsigned pwr_down_mode
;
61 * ad5504_supported_device_ids:
64 enum ad5504_supported_device_ids
{
69 static int ad5504_spi_write(struct spi_device
*spi
, u8 addr
, u16 val
)
71 u16 tmp
= cpu_to_be16(AD5504_CMD_WRITE
|
73 (val
& AD5504_RES_MASK
));
75 return spi_write(spi
, (u8
*)&tmp
, 2);
78 static int ad5504_spi_read(struct spi_device
*spi
, u8 addr
)
80 u16 tmp
= cpu_to_be16(AD5504_CMD_READ
| AD5504_ADDR(addr
));
83 struct spi_transfer t
= {
91 spi_message_add_tail(&t
, &m
);
92 ret
= spi_sync(spi
, &m
);
97 return be16_to_cpu(val
) & AD5504_RES_MASK
;
100 static int ad5504_read_raw(struct iio_dev
*indio_dev
,
101 struct iio_chan_spec
const *chan
,
106 struct ad5504_state
*st
= iio_priv(indio_dev
);
107 unsigned long scale_uv
;
111 case IIO_CHAN_INFO_RAW
:
112 ret
= ad5504_spi_read(st
->spi
, chan
->address
);
119 case IIO_CHAN_INFO_SCALE
:
120 scale_uv
= (st
->vref_mv
* 1000) >> chan
->scan_type
.realbits
;
121 *val
= scale_uv
/ 1000;
122 *val2
= (scale_uv
% 1000) * 1000;
123 return IIO_VAL_INT_PLUS_MICRO
;
129 static int ad5504_write_raw(struct iio_dev
*indio_dev
,
130 struct iio_chan_spec
const *chan
,
135 struct ad5504_state
*st
= iio_priv(indio_dev
);
139 case IIO_CHAN_INFO_RAW
:
140 if (val
>= (1 << chan
->scan_type
.realbits
) || val
< 0)
143 return ad5504_spi_write(st
->spi
, chan
->address
, val
);
151 static const char * const ad5504_powerdown_modes
[] = {
156 static int ad5504_get_powerdown_mode(struct iio_dev
*indio_dev
,
157 const struct iio_chan_spec
*chan
)
159 struct ad5504_state
*st
= iio_priv(indio_dev
);
161 return st
->pwr_down_mode
;
164 static int ad5504_set_powerdown_mode(struct iio_dev
*indio_dev
,
165 const struct iio_chan_spec
*chan
, unsigned int mode
)
167 struct ad5504_state
*st
= iio_priv(indio_dev
);
169 st
->pwr_down_mode
= mode
;
174 static const struct iio_enum ad5504_powerdown_mode_enum
= {
175 .items
= ad5504_powerdown_modes
,
176 .num_items
= ARRAY_SIZE(ad5504_powerdown_modes
),
177 .get
= ad5504_get_powerdown_mode
,
178 .set
= ad5504_set_powerdown_mode
,
181 static ssize_t
ad5504_read_dac_powerdown(struct iio_dev
*indio_dev
,
182 uintptr_t private, const struct iio_chan_spec
*chan
, char *buf
)
184 struct ad5504_state
*st
= iio_priv(indio_dev
);
186 return sprintf(buf
, "%d\n",
187 !(st
->pwr_down_mask
& (1 << chan
->channel
)));
190 static ssize_t
ad5504_write_dac_powerdown(struct iio_dev
*indio_dev
,
191 uintptr_t private, const struct iio_chan_spec
*chan
, const char *buf
,
196 struct ad5504_state
*st
= iio_priv(indio_dev
);
198 ret
= strtobool(buf
, &pwr_down
);
203 st
->pwr_down_mask
|= (1 << chan
->channel
);
205 st
->pwr_down_mask
&= ~(1 << chan
->channel
);
207 ret
= ad5504_spi_write(st
->spi
, AD5504_ADDR_CTRL
,
208 AD5504_DAC_PWRDWN_MODE(st
->pwr_down_mode
) |
209 AD5504_DAC_PWR(st
->pwr_down_mask
));
211 /* writes to the CTRL register must be followed by a NOOP */
212 ad5504_spi_write(st
->spi
, AD5504_ADDR_NOOP
, 0);
214 return ret
? ret
: len
;
217 static IIO_CONST_ATTR(temp0_thresh_rising_value
, "110000");
218 static IIO_CONST_ATTR(temp0_thresh_rising_en
, "1");
220 static struct attribute
*ad5504_ev_attributes
[] = {
221 &iio_const_attr_temp0_thresh_rising_value
.dev_attr
.attr
,
222 &iio_const_attr_temp0_thresh_rising_en
.dev_attr
.attr
,
226 static struct attribute_group ad5504_ev_attribute_group
= {
227 .attrs
= ad5504_ev_attributes
,
231 static irqreturn_t
ad5504_event_handler(int irq
, void *private)
233 iio_push_event(private,
234 IIO_UNMOD_EVENT_CODE(IIO_TEMP
,
243 static const struct iio_info ad5504_info
= {
244 .write_raw
= ad5504_write_raw
,
245 .read_raw
= ad5504_read_raw
,
246 .event_attrs
= &ad5504_ev_attribute_group
,
247 .driver_module
= THIS_MODULE
,
250 static const struct iio_chan_spec_ext_info ad5504_ext_info
[] = {
253 .read
= ad5504_read_dac_powerdown
,
254 .write
= ad5504_write_dac_powerdown
,
256 IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum
),
257 IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum
),
261 #define AD5504_CHANNEL(_chan) { \
262 .type = IIO_VOLTAGE, \
265 .channel = (_chan), \
266 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
267 IIO_CHAN_INFO_SCALE_SHARED_BIT, \
268 .address = AD5504_ADDR_DAC(_chan), \
269 .scan_type = IIO_ST('u', 12, 16, 0), \
270 .ext_info = ad5504_ext_info, \
273 static const struct iio_chan_spec ad5504_channels
[] = {
280 static int __devinit
ad5504_probe(struct spi_device
*spi
)
282 struct ad5504_platform_data
*pdata
= spi
->dev
.platform_data
;
283 struct iio_dev
*indio_dev
;
284 struct ad5504_state
*st
;
285 struct regulator
*reg
;
286 int ret
, voltage_uv
= 0;
288 indio_dev
= iio_device_alloc(sizeof(*st
));
289 if (indio_dev
== NULL
) {
293 reg
= regulator_get(&spi
->dev
, "vcc");
295 ret
= regulator_enable(reg
);
299 voltage_uv
= regulator_get_voltage(reg
);
302 spi_set_drvdata(spi
, indio_dev
);
303 st
= iio_priv(indio_dev
);
305 st
->vref_mv
= voltage_uv
/ 1000;
307 st
->vref_mv
= pdata
->vref_mv
;
309 dev_warn(&spi
->dev
, "reference voltage unspecified\n");
313 indio_dev
->dev
.parent
= &spi
->dev
;
314 indio_dev
->name
= spi_get_device_id(st
->spi
)->name
;
315 indio_dev
->info
= &ad5504_info
;
316 if (spi_get_device_id(st
->spi
)->driver_data
== ID_AD5501
)
317 indio_dev
->num_channels
= 1;
319 indio_dev
->num_channels
= 4;
320 indio_dev
->channels
= ad5504_channels
;
321 indio_dev
->modes
= INDIO_DIRECT_MODE
;
324 ret
= request_threaded_irq(spi
->irq
,
326 &ad5504_event_handler
,
327 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
328 spi_get_device_id(st
->spi
)->name
,
331 goto error_disable_reg
;
334 ret
= iio_device_register(indio_dev
);
342 free_irq(spi
->irq
, indio_dev
);
345 regulator_disable(reg
);
350 iio_device_free(indio_dev
);
355 static int __devexit
ad5504_remove(struct spi_device
*spi
)
357 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
358 struct ad5504_state
*st
= iio_priv(indio_dev
);
360 iio_device_unregister(indio_dev
);
362 free_irq(spi
->irq
, indio_dev
);
364 if (!IS_ERR(st
->reg
)) {
365 regulator_disable(st
->reg
);
366 regulator_put(st
->reg
);
368 iio_device_free(indio_dev
);
373 static const struct spi_device_id ad5504_id
[] = {
374 {"ad5504", ID_AD5504
},
375 {"ad5501", ID_AD5501
},
378 MODULE_DEVICE_TABLE(spi
, ad5504_id
);
380 static struct spi_driver ad5504_driver
= {
383 .owner
= THIS_MODULE
,
385 .probe
= ad5504_probe
,
386 .remove
= __devexit_p(ad5504_remove
),
387 .id_table
= ad5504_id
,
389 module_spi_driver(ad5504_driver
);
391 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
392 MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
393 MODULE_LICENSE("GPL v2");