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>
18 #include <linux/bitops.h>
20 #include <linux/iio/iio.h>
21 #include <linux/iio/sysfs.h>
22 #include <linux/iio/events.h>
23 #include <linux/iio/dac/ad5504.h>
25 #define AD5504_RES_MASK GENMASK(11, 0)
26 #define AD5504_CMD_READ BIT(15)
27 #define AD5504_CMD_WRITE 0
28 #define AD5504_ADDR(addr) ((addr) << 12)
31 #define AD5504_ADDR_NOOP 0
32 #define AD5504_ADDR_DAC(x) ((x) + 1)
33 #define AD5504_ADDR_ALL_DAC 5
34 #define AD5504_ADDR_CTRL 7
36 /* Control Register */
37 #define AD5504_DAC_PWR(ch) ((ch) << 2)
38 #define AD5504_DAC_PWRDWN_MODE(mode) ((mode) << 6)
39 #define AD5504_DAC_PWRDN_20K 0
40 #define AD5504_DAC_PWRDN_3STATE 1
43 * struct ad5446_state - driver instance specific data
45 * @reg: supply regulator
46 * @vref_mv: actual reference voltage used
47 * @pwr_down_mask power down mask
48 * @pwr_down_mode current power down mode
49 * @data: transfer buffer
52 struct spi_device
*spi
;
53 struct regulator
*reg
;
54 unsigned short vref_mv
;
55 unsigned pwr_down_mask
;
56 unsigned pwr_down_mode
;
58 __be16 data
[2] ____cacheline_aligned
;
62 * ad5504_supported_device_ids:
65 enum ad5504_supported_device_ids
{
70 static int ad5504_spi_write(struct ad5504_state
*st
, u8 addr
, u16 val
)
72 st
->data
[0] = cpu_to_be16(AD5504_CMD_WRITE
| AD5504_ADDR(addr
) |
73 (val
& AD5504_RES_MASK
));
75 return spi_write(st
->spi
, &st
->data
[0], 2);
78 static int ad5504_spi_read(struct ad5504_state
*st
, u8 addr
)
81 struct spi_transfer t
= {
82 .tx_buf
= &st
->data
[0],
83 .rx_buf
= &st
->data
[1],
87 st
->data
[0] = cpu_to_be16(AD5504_CMD_READ
| AD5504_ADDR(addr
));
88 ret
= spi_sync_transfer(st
->spi
, &t
, 1);
92 return be16_to_cpu(st
->data
[1]) & AD5504_RES_MASK
;
95 static int ad5504_read_raw(struct iio_dev
*indio_dev
,
96 struct iio_chan_spec
const *chan
,
101 struct ad5504_state
*st
= iio_priv(indio_dev
);
105 case IIO_CHAN_INFO_RAW
:
106 ret
= ad5504_spi_read(st
, chan
->address
);
113 case IIO_CHAN_INFO_SCALE
:
115 *val2
= chan
->scan_type
.realbits
;
116 return IIO_VAL_FRACTIONAL_LOG2
;
121 static int ad5504_write_raw(struct iio_dev
*indio_dev
,
122 struct iio_chan_spec
const *chan
,
127 struct ad5504_state
*st
= iio_priv(indio_dev
);
130 case IIO_CHAN_INFO_RAW
:
131 if (val
>= (1 << chan
->scan_type
.realbits
) || val
< 0)
134 return ad5504_spi_write(st
, chan
->address
, val
);
140 static const char * const ad5504_powerdown_modes
[] = {
145 static int ad5504_get_powerdown_mode(struct iio_dev
*indio_dev
,
146 const struct iio_chan_spec
*chan
)
148 struct ad5504_state
*st
= iio_priv(indio_dev
);
150 return st
->pwr_down_mode
;
153 static int ad5504_set_powerdown_mode(struct iio_dev
*indio_dev
,
154 const struct iio_chan_spec
*chan
, unsigned int mode
)
156 struct ad5504_state
*st
= iio_priv(indio_dev
);
158 st
->pwr_down_mode
= mode
;
163 static const struct iio_enum ad5504_powerdown_mode_enum
= {
164 .items
= ad5504_powerdown_modes
,
165 .num_items
= ARRAY_SIZE(ad5504_powerdown_modes
),
166 .get
= ad5504_get_powerdown_mode
,
167 .set
= ad5504_set_powerdown_mode
,
170 static ssize_t
ad5504_read_dac_powerdown(struct iio_dev
*indio_dev
,
171 uintptr_t private, const struct iio_chan_spec
*chan
, char *buf
)
173 struct ad5504_state
*st
= iio_priv(indio_dev
);
175 return sprintf(buf
, "%d\n",
176 !(st
->pwr_down_mask
& (1 << chan
->channel
)));
179 static ssize_t
ad5504_write_dac_powerdown(struct iio_dev
*indio_dev
,
180 uintptr_t private, const struct iio_chan_spec
*chan
, const char *buf
,
185 struct ad5504_state
*st
= iio_priv(indio_dev
);
187 ret
= strtobool(buf
, &pwr_down
);
192 st
->pwr_down_mask
|= (1 << chan
->channel
);
194 st
->pwr_down_mask
&= ~(1 << chan
->channel
);
196 ret
= ad5504_spi_write(st
, AD5504_ADDR_CTRL
,
197 AD5504_DAC_PWRDWN_MODE(st
->pwr_down_mode
) |
198 AD5504_DAC_PWR(st
->pwr_down_mask
));
200 /* writes to the CTRL register must be followed by a NOOP */
201 ad5504_spi_write(st
, AD5504_ADDR_NOOP
, 0);
203 return ret
? ret
: len
;
206 static IIO_CONST_ATTR(temp0_thresh_rising_value
, "110000");
207 static IIO_CONST_ATTR(temp0_thresh_rising_en
, "1");
209 static struct attribute
*ad5504_ev_attributes
[] = {
210 &iio_const_attr_temp0_thresh_rising_value
.dev_attr
.attr
,
211 &iio_const_attr_temp0_thresh_rising_en
.dev_attr
.attr
,
215 static struct attribute_group ad5504_ev_attribute_group
= {
216 .attrs
= ad5504_ev_attributes
,
219 static irqreturn_t
ad5504_event_handler(int irq
, void *private)
221 iio_push_event(private,
222 IIO_UNMOD_EVENT_CODE(IIO_TEMP
,
231 static const struct iio_info ad5504_info
= {
232 .write_raw
= ad5504_write_raw
,
233 .read_raw
= ad5504_read_raw
,
234 .event_attrs
= &ad5504_ev_attribute_group
,
235 .driver_module
= THIS_MODULE
,
238 static const struct iio_chan_spec_ext_info ad5504_ext_info
[] = {
241 .read
= ad5504_read_dac_powerdown
,
242 .write
= ad5504_write_dac_powerdown
,
243 .shared
= IIO_SEPARATE
,
245 IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE
,
246 &ad5504_powerdown_mode_enum
),
247 IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum
),
251 #define AD5504_CHANNEL(_chan) { \
252 .type = IIO_VOLTAGE, \
255 .channel = (_chan), \
256 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
257 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
258 .address = AD5504_ADDR_DAC(_chan), \
264 .ext_info = ad5504_ext_info, \
267 static const struct iio_chan_spec ad5504_channels
[] = {
274 static int ad5504_probe(struct spi_device
*spi
)
276 struct ad5504_platform_data
*pdata
= spi
->dev
.platform_data
;
277 struct iio_dev
*indio_dev
;
278 struct ad5504_state
*st
;
279 struct regulator
*reg
;
280 int ret
, voltage_uv
= 0;
282 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*st
));
285 reg
= devm_regulator_get(&spi
->dev
, "vcc");
287 ret
= regulator_enable(reg
);
291 ret
= regulator_get_voltage(reg
);
293 goto error_disable_reg
;
298 spi_set_drvdata(spi
, indio_dev
);
299 st
= iio_priv(indio_dev
);
301 st
->vref_mv
= voltage_uv
/ 1000;
303 st
->vref_mv
= pdata
->vref_mv
;
305 dev_warn(&spi
->dev
, "reference voltage unspecified\n");
309 indio_dev
->dev
.parent
= &spi
->dev
;
310 indio_dev
->name
= spi_get_device_id(st
->spi
)->name
;
311 indio_dev
->info
= &ad5504_info
;
312 if (spi_get_device_id(st
->spi
)->driver_data
== ID_AD5501
)
313 indio_dev
->num_channels
= 1;
315 indio_dev
->num_channels
= 4;
316 indio_dev
->channels
= ad5504_channels
;
317 indio_dev
->modes
= INDIO_DIRECT_MODE
;
320 ret
= devm_request_threaded_irq(&spi
->dev
, spi
->irq
,
322 &ad5504_event_handler
,
323 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
324 spi_get_device_id(st
->spi
)->name
,
327 goto error_disable_reg
;
330 ret
= iio_device_register(indio_dev
);
332 goto error_disable_reg
;
338 regulator_disable(reg
);
343 static int ad5504_remove(struct spi_device
*spi
)
345 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
346 struct ad5504_state
*st
= iio_priv(indio_dev
);
348 iio_device_unregister(indio_dev
);
350 if (!IS_ERR(st
->reg
))
351 regulator_disable(st
->reg
);
356 static const struct spi_device_id ad5504_id
[] = {
357 {"ad5504", ID_AD5504
},
358 {"ad5501", ID_AD5501
},
361 MODULE_DEVICE_TABLE(spi
, ad5504_id
);
363 static struct spi_driver ad5504_driver
= {
367 .probe
= ad5504_probe
,
368 .remove
= ad5504_remove
,
369 .id_table
= ad5504_id
,
371 module_spi_driver(ad5504_driver
);
373 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
374 MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
375 MODULE_LICENSE("GPL v2");