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
50 * @data: transfer buffer
53 struct spi_device
*spi
;
54 struct regulator
*reg
;
55 unsigned short vref_mv
;
56 unsigned pwr_down_mask
;
57 unsigned pwr_down_mode
;
59 __be16 data
[2] ____cacheline_aligned
;
63 * ad5504_supported_device_ids:
66 enum ad5504_supported_device_ids
{
71 static int ad5504_spi_write(struct ad5504_state
*st
, u8 addr
, u16 val
)
73 st
->data
[0] = cpu_to_be16(AD5504_CMD_WRITE
| AD5504_ADDR(addr
) |
74 (val
& AD5504_RES_MASK
));
76 return spi_write(st
->spi
, &st
->data
[0], 2);
79 static int ad5504_spi_read(struct ad5504_state
*st
, u8 addr
)
82 struct spi_transfer t
= {
83 .tx_buf
= &st
->data
[0],
84 .rx_buf
= &st
->data
[1],
88 st
->data
[0] = cpu_to_be16(AD5504_CMD_READ
| AD5504_ADDR(addr
));
89 ret
= spi_sync_transfer(st
->spi
, &t
, 1);
93 return be16_to_cpu(st
->data
[1]) & AD5504_RES_MASK
;
96 static int ad5504_read_raw(struct iio_dev
*indio_dev
,
97 struct iio_chan_spec
const *chan
,
102 struct ad5504_state
*st
= iio_priv(indio_dev
);
106 case IIO_CHAN_INFO_RAW
:
107 ret
= ad5504_spi_read(st
, chan
->address
);
114 case IIO_CHAN_INFO_SCALE
:
116 *val2
= chan
->scan_type
.realbits
;
117 return IIO_VAL_FRACTIONAL_LOG2
;
122 static int ad5504_write_raw(struct iio_dev
*indio_dev
,
123 struct iio_chan_spec
const *chan
,
128 struct ad5504_state
*st
= iio_priv(indio_dev
);
132 case IIO_CHAN_INFO_RAW
:
133 if (val
>= (1 << chan
->scan_type
.realbits
) || val
< 0)
136 return ad5504_spi_write(st
, chan
->address
, val
);
144 static const char * const ad5504_powerdown_modes
[] = {
149 static int ad5504_get_powerdown_mode(struct iio_dev
*indio_dev
,
150 const struct iio_chan_spec
*chan
)
152 struct ad5504_state
*st
= iio_priv(indio_dev
);
154 return st
->pwr_down_mode
;
157 static int ad5504_set_powerdown_mode(struct iio_dev
*indio_dev
,
158 const struct iio_chan_spec
*chan
, unsigned int mode
)
160 struct ad5504_state
*st
= iio_priv(indio_dev
);
162 st
->pwr_down_mode
= mode
;
167 static const struct iio_enum ad5504_powerdown_mode_enum
= {
168 .items
= ad5504_powerdown_modes
,
169 .num_items
= ARRAY_SIZE(ad5504_powerdown_modes
),
170 .get
= ad5504_get_powerdown_mode
,
171 .set
= ad5504_set_powerdown_mode
,
174 static ssize_t
ad5504_read_dac_powerdown(struct iio_dev
*indio_dev
,
175 uintptr_t private, const struct iio_chan_spec
*chan
, char *buf
)
177 struct ad5504_state
*st
= iio_priv(indio_dev
);
179 return sprintf(buf
, "%d\n",
180 !(st
->pwr_down_mask
& (1 << chan
->channel
)));
183 static ssize_t
ad5504_write_dac_powerdown(struct iio_dev
*indio_dev
,
184 uintptr_t private, const struct iio_chan_spec
*chan
, const char *buf
,
189 struct ad5504_state
*st
= iio_priv(indio_dev
);
191 ret
= strtobool(buf
, &pwr_down
);
196 st
->pwr_down_mask
|= (1 << chan
->channel
);
198 st
->pwr_down_mask
&= ~(1 << chan
->channel
);
200 ret
= ad5504_spi_write(st
, AD5504_ADDR_CTRL
,
201 AD5504_DAC_PWRDWN_MODE(st
->pwr_down_mode
) |
202 AD5504_DAC_PWR(st
->pwr_down_mask
));
204 /* writes to the CTRL register must be followed by a NOOP */
205 ad5504_spi_write(st
, AD5504_ADDR_NOOP
, 0);
207 return ret
? ret
: len
;
210 static IIO_CONST_ATTR(temp0_thresh_rising_value
, "110000");
211 static IIO_CONST_ATTR(temp0_thresh_rising_en
, "1");
213 static struct attribute
*ad5504_ev_attributes
[] = {
214 &iio_const_attr_temp0_thresh_rising_value
.dev_attr
.attr
,
215 &iio_const_attr_temp0_thresh_rising_en
.dev_attr
.attr
,
219 static struct attribute_group ad5504_ev_attribute_group
= {
220 .attrs
= ad5504_ev_attributes
,
224 static irqreturn_t
ad5504_event_handler(int irq
, void *private)
226 iio_push_event(private,
227 IIO_UNMOD_EVENT_CODE(IIO_TEMP
,
236 static const struct iio_info ad5504_info
= {
237 .write_raw
= ad5504_write_raw
,
238 .read_raw
= ad5504_read_raw
,
239 .event_attrs
= &ad5504_ev_attribute_group
,
240 .driver_module
= THIS_MODULE
,
243 static const struct iio_chan_spec_ext_info ad5504_ext_info
[] = {
246 .read
= ad5504_read_dac_powerdown
,
247 .write
= ad5504_write_dac_powerdown
,
248 .shared
= IIO_SEPARATE
,
250 IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE
,
251 &ad5504_powerdown_mode_enum
),
252 IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum
),
256 #define AD5504_CHANNEL(_chan) { \
257 .type = IIO_VOLTAGE, \
260 .channel = (_chan), \
261 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
262 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
263 .address = AD5504_ADDR_DAC(_chan), \
269 .ext_info = ad5504_ext_info, \
272 static const struct iio_chan_spec ad5504_channels
[] = {
279 static int ad5504_probe(struct spi_device
*spi
)
281 struct ad5504_platform_data
*pdata
= spi
->dev
.platform_data
;
282 struct iio_dev
*indio_dev
;
283 struct ad5504_state
*st
;
284 struct regulator
*reg
;
285 int ret
, voltage_uv
= 0;
287 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*st
));
290 reg
= devm_regulator_get(&spi
->dev
, "vcc");
292 ret
= regulator_enable(reg
);
296 ret
= regulator_get_voltage(reg
);
298 goto error_disable_reg
;
303 spi_set_drvdata(spi
, indio_dev
);
304 st
= iio_priv(indio_dev
);
306 st
->vref_mv
= voltage_uv
/ 1000;
308 st
->vref_mv
= pdata
->vref_mv
;
310 dev_warn(&spi
->dev
, "reference voltage unspecified\n");
314 indio_dev
->dev
.parent
= &spi
->dev
;
315 indio_dev
->name
= spi_get_device_id(st
->spi
)->name
;
316 indio_dev
->info
= &ad5504_info
;
317 if (spi_get_device_id(st
->spi
)->driver_data
== ID_AD5501
)
318 indio_dev
->num_channels
= 1;
320 indio_dev
->num_channels
= 4;
321 indio_dev
->channels
= ad5504_channels
;
322 indio_dev
->modes
= INDIO_DIRECT_MODE
;
325 ret
= devm_request_threaded_irq(&spi
->dev
, spi
->irq
,
327 &ad5504_event_handler
,
328 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
329 spi_get_device_id(st
->spi
)->name
,
332 goto error_disable_reg
;
335 ret
= iio_device_register(indio_dev
);
337 goto error_disable_reg
;
343 regulator_disable(reg
);
348 static int ad5504_remove(struct spi_device
*spi
)
350 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
351 struct ad5504_state
*st
= iio_priv(indio_dev
);
353 iio_device_unregister(indio_dev
);
355 if (!IS_ERR(st
->reg
))
356 regulator_disable(st
->reg
);
361 static const struct spi_device_id ad5504_id
[] = {
362 {"ad5504", ID_AD5504
},
363 {"ad5501", ID_AD5501
},
366 MODULE_DEVICE_TABLE(spi
, ad5504_id
);
368 static struct spi_driver ad5504_driver
= {
371 .owner
= THIS_MODULE
,
373 .probe
= ad5504_probe
,
374 .remove
= ad5504_remove
,
375 .id_table
= ad5504_id
,
377 module_spi_driver(ad5504_driver
);
379 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
380 MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
381 MODULE_LICENSE("GPL v2");