1 // SPDX-License-Identifier: GPL-2.0
3 * DAC7612 Dual, 12-Bit Serial input Digital-to-Analog Converter
5 * Copyright 2019 Qtechnology A/S
6 * 2019 Ricardo Ribalda <ricardo@ribalda.com>
8 * Licensed under the GPL-2.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/spi/spi.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/iio/iio.h>
16 #define DAC7612_RESOLUTION 12
17 #define DAC7612_ADDRESS 4
18 #define DAC7612_START 5
21 struct spi_device
*spi
;
22 struct gpio_desc
*loaddacs
;
26 * DMA (thus cache coherency maintenance) requires the
27 * transfer buffers to live in their own cache lines.
29 uint8_t data
[2] ____cacheline_aligned
;
32 static int dac7612_cmd_single(struct dac7612
*priv
, int channel
, u16 val
)
36 priv
->data
[0] = BIT(DAC7612_START
) | (channel
<< DAC7612_ADDRESS
);
37 priv
->data
[0] |= val
>> 8;
38 priv
->data
[1] = val
& 0xff;
40 priv
->cache
[channel
] = val
;
42 ret
= spi_write(priv
->spi
, priv
->data
, sizeof(priv
->data
));
46 gpiod_set_value(priv
->loaddacs
, 1);
47 gpiod_set_value(priv
->loaddacs
, 0);
52 #define dac7612_CHANNEL(chan, name) { \
53 .type = IIO_VOLTAGE, \
57 .datasheet_name = name, \
58 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
59 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
62 static const struct iio_chan_spec dac7612_channels
[] = {
63 dac7612_CHANNEL(0, "OUTA"),
64 dac7612_CHANNEL(1, "OUTB"),
67 static int dac7612_read_raw(struct iio_dev
*iio_dev
,
68 const struct iio_chan_spec
*chan
,
69 int *val
, int *val2
, long mask
)
74 case IIO_CHAN_INFO_RAW
:
75 priv
= iio_priv(iio_dev
);
76 *val
= priv
->cache
[chan
->channel
];
79 case IIO_CHAN_INFO_SCALE
:
88 static int dac7612_write_raw(struct iio_dev
*iio_dev
,
89 const struct iio_chan_spec
*chan
,
90 int val
, int val2
, long mask
)
92 struct dac7612
*priv
= iio_priv(iio_dev
);
95 if (mask
!= IIO_CHAN_INFO_RAW
)
98 if ((val
>= BIT(DAC7612_RESOLUTION
)) || val
< 0 || val2
)
101 if (val
== priv
->cache
[chan
->channel
])
104 mutex_lock(&iio_dev
->mlock
);
105 ret
= dac7612_cmd_single(priv
, chan
->channel
, val
);
106 mutex_unlock(&iio_dev
->mlock
);
111 static const struct iio_info dac7612_info
= {
112 .read_raw
= dac7612_read_raw
,
113 .write_raw
= dac7612_write_raw
,
116 static int dac7612_probe(struct spi_device
*spi
)
118 struct iio_dev
*iio_dev
;
119 struct dac7612
*priv
;
123 iio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*priv
));
127 priv
= iio_priv(iio_dev
);
129 * LOADDACS pin can be controlled by the driver or externally.
130 * When controlled by the driver, the DAC value is updated after
132 * When the driver does not control the PIN, the user or an external
133 * event can change the value of all DACs by pulsing down the LOADDACs
136 priv
->loaddacs
= devm_gpiod_get_optional(&spi
->dev
, "ti,loaddacs",
138 if (IS_ERR(priv
->loaddacs
))
139 return PTR_ERR(priv
->loaddacs
);
141 spi_set_drvdata(spi
, iio_dev
);
142 iio_dev
->dev
.parent
= &spi
->dev
;
143 iio_dev
->info
= &dac7612_info
;
144 iio_dev
->modes
= INDIO_DIRECT_MODE
;
145 iio_dev
->channels
= dac7612_channels
;
146 iio_dev
->num_channels
= ARRAY_SIZE(priv
->cache
);
147 iio_dev
->name
= spi_get_device_id(spi
)->name
;
149 for (i
= 0; i
< ARRAY_SIZE(priv
->cache
); i
++) {
150 ret
= dac7612_cmd_single(priv
, i
, 0);
155 return devm_iio_device_register(&spi
->dev
, iio_dev
);
158 static const struct spi_device_id dac7612_id
[] = {
162 MODULE_DEVICE_TABLE(spi
, dac7612_id
);
164 static const struct of_device_id dac7612_of_match
[] = {
165 { .compatible
= "ti,dac7612" },
166 { .compatible
= "ti,dac7612u" },
167 { .compatible
= "ti,dac7612ub" },
170 MODULE_DEVICE_TABLE(of
, dac7612_of_match
);
172 static struct spi_driver dac7612_driver
= {
174 .name
= "ti-dac7612",
175 .of_match_table
= dac7612_of_match
,
177 .probe
= dac7612_probe
,
178 .id_table
= dac7612_id
,
180 module_spi_driver(dac7612_driver
);
182 MODULE_AUTHOR("Ricardo Ribalda <ricardo@ribalda.com>");
183 MODULE_DESCRIPTION("Texas Instruments DAC7612 DAC driver");
184 MODULE_LICENSE("GPL v2");