1 // SPDX-License-Identifier: GPL-2.0-only
3 * AD5504, AD5501 High Voltage Digital to Analog Converter
5 * Copyright 2011 Analog Devices Inc.
8 #include <linux/interrupt.h>
10 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #include <linux/spi/spi.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/module.h>
17 #include <linux/bitops.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 AD5504_RES_MASK GENMASK(11, 0)
25 #define AD5504_CMD_READ BIT(15)
26 #define AD5504_CMD_WRITE 0
27 #define AD5504_ADDR(addr) ((addr) << 12)
30 #define AD5504_ADDR_NOOP 0
31 #define AD5504_ADDR_DAC(x) ((x) + 1)
32 #define AD5504_ADDR_ALL_DAC 5
33 #define AD5504_ADDR_CTRL 7
35 /* Control Register */
36 #define AD5504_DAC_PWR(ch) ((ch) << 2)
37 #define AD5504_DAC_PWRDWN_MODE(mode) ((mode) << 6)
38 #define AD5504_DAC_PWRDN_20K 0
39 #define AD5504_DAC_PWRDN_3STATE 1
42 * struct ad5446_state - driver instance specific data
44 * @reg: supply regulator
45 * @vref_mv: actual reference voltage used
46 * @pwr_down_mask: power down mask
47 * @pwr_down_mode: current power down mode
48 * @data: transfer buffer
51 struct spi_device
*spi
;
52 struct regulator
*reg
;
53 unsigned short vref_mv
;
54 unsigned pwr_down_mask
;
55 unsigned pwr_down_mode
;
57 __be16 data
[2] ____cacheline_aligned
;
61 * ad5504_supported_device_ids:
63 enum ad5504_supported_device_ids
{
68 static int ad5504_spi_write(struct ad5504_state
*st
, u8 addr
, u16 val
)
70 st
->data
[0] = cpu_to_be16(AD5504_CMD_WRITE
| AD5504_ADDR(addr
) |
71 (val
& AD5504_RES_MASK
));
73 return spi_write(st
->spi
, &st
->data
[0], 2);
76 static int ad5504_spi_read(struct ad5504_state
*st
, u8 addr
)
79 struct spi_transfer t
= {
80 .tx_buf
= &st
->data
[0],
81 .rx_buf
= &st
->data
[1],
85 st
->data
[0] = cpu_to_be16(AD5504_CMD_READ
| AD5504_ADDR(addr
));
86 ret
= spi_sync_transfer(st
->spi
, &t
, 1);
90 return be16_to_cpu(st
->data
[1]) & AD5504_RES_MASK
;
93 static int ad5504_read_raw(struct iio_dev
*indio_dev
,
94 struct iio_chan_spec
const *chan
,
99 struct ad5504_state
*st
= iio_priv(indio_dev
);
103 case IIO_CHAN_INFO_RAW
:
104 ret
= ad5504_spi_read(st
, chan
->address
);
111 case IIO_CHAN_INFO_SCALE
:
113 *val2
= chan
->scan_type
.realbits
;
114 return IIO_VAL_FRACTIONAL_LOG2
;
119 static int ad5504_write_raw(struct iio_dev
*indio_dev
,
120 struct iio_chan_spec
const *chan
,
125 struct ad5504_state
*st
= iio_priv(indio_dev
);
128 case IIO_CHAN_INFO_RAW
:
129 if (val
>= (1 << chan
->scan_type
.realbits
) || val
< 0)
132 return ad5504_spi_write(st
, chan
->address
, val
);
138 static const char * const ad5504_powerdown_modes
[] = {
143 static int ad5504_get_powerdown_mode(struct iio_dev
*indio_dev
,
144 const struct iio_chan_spec
*chan
)
146 struct ad5504_state
*st
= iio_priv(indio_dev
);
148 return st
->pwr_down_mode
;
151 static int ad5504_set_powerdown_mode(struct iio_dev
*indio_dev
,
152 const struct iio_chan_spec
*chan
, unsigned int mode
)
154 struct ad5504_state
*st
= iio_priv(indio_dev
);
156 st
->pwr_down_mode
= mode
;
161 static const struct iio_enum ad5504_powerdown_mode_enum
= {
162 .items
= ad5504_powerdown_modes
,
163 .num_items
= ARRAY_SIZE(ad5504_powerdown_modes
),
164 .get
= ad5504_get_powerdown_mode
,
165 .set
= ad5504_set_powerdown_mode
,
168 static ssize_t
ad5504_read_dac_powerdown(struct iio_dev
*indio_dev
,
169 uintptr_t private, const struct iio_chan_spec
*chan
, char *buf
)
171 struct ad5504_state
*st
= iio_priv(indio_dev
);
173 return sprintf(buf
, "%d\n",
174 !(st
->pwr_down_mask
& (1 << chan
->channel
)));
177 static ssize_t
ad5504_write_dac_powerdown(struct iio_dev
*indio_dev
,
178 uintptr_t private, const struct iio_chan_spec
*chan
, const char *buf
,
183 struct ad5504_state
*st
= iio_priv(indio_dev
);
185 ret
= strtobool(buf
, &pwr_down
);
190 st
->pwr_down_mask
|= (1 << chan
->channel
);
192 st
->pwr_down_mask
&= ~(1 << chan
->channel
);
194 ret
= ad5504_spi_write(st
, AD5504_ADDR_CTRL
,
195 AD5504_DAC_PWRDWN_MODE(st
->pwr_down_mode
) |
196 AD5504_DAC_PWR(st
->pwr_down_mask
));
198 /* writes to the CTRL register must be followed by a NOOP */
199 ad5504_spi_write(st
, AD5504_ADDR_NOOP
, 0);
201 return ret
? ret
: len
;
204 static IIO_CONST_ATTR(temp0_thresh_rising_value
, "110000");
205 static IIO_CONST_ATTR(temp0_thresh_rising_en
, "1");
207 static struct attribute
*ad5504_ev_attributes
[] = {
208 &iio_const_attr_temp0_thresh_rising_value
.dev_attr
.attr
,
209 &iio_const_attr_temp0_thresh_rising_en
.dev_attr
.attr
,
213 static const struct attribute_group ad5504_ev_attribute_group
= {
214 .attrs
= ad5504_ev_attributes
,
217 static irqreturn_t
ad5504_event_handler(int irq
, void *private)
219 iio_push_event(private,
220 IIO_UNMOD_EVENT_CODE(IIO_TEMP
,
224 iio_get_time_ns(private));
229 static const struct iio_info ad5504_info
= {
230 .write_raw
= ad5504_write_raw
,
231 .read_raw
= ad5504_read_raw
,
232 .event_attrs
= &ad5504_ev_attribute_group
,
235 static const struct iio_chan_spec_ext_info ad5504_ext_info
[] = {
238 .read
= ad5504_read_dac_powerdown
,
239 .write
= ad5504_write_dac_powerdown
,
240 .shared
= IIO_SEPARATE
,
242 IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE
,
243 &ad5504_powerdown_mode_enum
),
244 IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum
),
248 #define AD5504_CHANNEL(_chan) { \
249 .type = IIO_VOLTAGE, \
252 .channel = (_chan), \
253 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
254 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
255 .address = AD5504_ADDR_DAC(_chan), \
261 .ext_info = ad5504_ext_info, \
264 static const struct iio_chan_spec ad5504_channels
[] = {
271 static int ad5504_probe(struct spi_device
*spi
)
273 struct ad5504_platform_data
*pdata
= spi
->dev
.platform_data
;
274 struct iio_dev
*indio_dev
;
275 struct ad5504_state
*st
;
276 struct regulator
*reg
;
277 int ret
, voltage_uv
= 0;
279 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*st
));
282 reg
= devm_regulator_get(&spi
->dev
, "vcc");
284 ret
= regulator_enable(reg
);
288 ret
= regulator_get_voltage(reg
);
290 goto error_disable_reg
;
295 spi_set_drvdata(spi
, indio_dev
);
296 st
= iio_priv(indio_dev
);
298 st
->vref_mv
= voltage_uv
/ 1000;
300 st
->vref_mv
= pdata
->vref_mv
;
302 dev_warn(&spi
->dev
, "reference voltage unspecified\n");
306 indio_dev
->name
= spi_get_device_id(st
->spi
)->name
;
307 indio_dev
->info
= &ad5504_info
;
308 if (spi_get_device_id(st
->spi
)->driver_data
== ID_AD5501
)
309 indio_dev
->num_channels
= 1;
311 indio_dev
->num_channels
= 4;
312 indio_dev
->channels
= ad5504_channels
;
313 indio_dev
->modes
= INDIO_DIRECT_MODE
;
316 ret
= devm_request_threaded_irq(&spi
->dev
, spi
->irq
,
318 &ad5504_event_handler
,
319 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
320 spi_get_device_id(st
->spi
)->name
,
323 goto error_disable_reg
;
326 ret
= iio_device_register(indio_dev
);
328 goto error_disable_reg
;
334 regulator_disable(reg
);
339 static int ad5504_remove(struct spi_device
*spi
)
341 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
342 struct ad5504_state
*st
= iio_priv(indio_dev
);
344 iio_device_unregister(indio_dev
);
346 if (!IS_ERR(st
->reg
))
347 regulator_disable(st
->reg
);
352 static const struct spi_device_id ad5504_id
[] = {
353 {"ad5504", ID_AD5504
},
354 {"ad5501", ID_AD5501
},
357 MODULE_DEVICE_TABLE(spi
, ad5504_id
);
359 static struct spi_driver ad5504_driver
= {
363 .probe
= ad5504_probe
,
364 .remove
= ad5504_remove
,
365 .id_table
= ad5504_id
,
367 module_spi_driver(ad5504_driver
);
369 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
370 MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
371 MODULE_LICENSE("GPL v2");