xref: /linux/drivers/iio/dac/ti-dac7612.c (revision 6fdcba32711044c35c0e1b094cbd8f3f0b4472c9)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * DAC7612 Dual, 12-Bit Serial input Digital-to-Analog Converter
4  *
5  * Copyright 2019 Qtechnology A/S
6  * 2019 Ricardo Ribalda <ricardo@ribalda.com>
7  *
8  * Licensed under the GPL-2.
9  */
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>
15 
16 #define DAC7612_RESOLUTION 12
17 #define DAC7612_ADDRESS 4
18 #define DAC7612_START 5
19 
20 struct dac7612 {
21 	struct spi_device *spi;
22 	struct gpio_desc *loaddacs;
23 	uint16_t cache[2];
24 
25 	/*
26 	 * DMA (thus cache coherency maintenance) requires the
27 	 * transfer buffers to live in their own cache lines.
28 	 */
29 	uint8_t data[2] ____cacheline_aligned;
30 };
31 
32 static int dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val)
33 {
34 	int ret;
35 
36 	priv->data[0] = BIT(DAC7612_START) | (channel << DAC7612_ADDRESS);
37 	priv->data[0] |= val >> 8;
38 	priv->data[1] = val & 0xff;
39 
40 	priv->cache[channel] = val;
41 
42 	ret = spi_write(priv->spi, priv->data, sizeof(priv->data));
43 	if (ret)
44 		return ret;
45 
46 	gpiod_set_value(priv->loaddacs, 1);
47 	gpiod_set_value(priv->loaddacs, 0);
48 
49 	return 0;
50 }
51 
52 #define dac7612_CHANNEL(chan, name) {				\
53 	.type = IIO_VOLTAGE,					\
54 	.channel = (chan),					\
55 	.indexed = 1,						\
56 	.output = 1,						\
57 	.datasheet_name = name,					\
58 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
59 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
60 }
61 
62 static const struct iio_chan_spec dac7612_channels[] = {
63 	dac7612_CHANNEL(0, "OUTA"),
64 	dac7612_CHANNEL(1, "OUTB"),
65 };
66 
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)
70 {
71 	struct dac7612 *priv;
72 
73 	switch (mask) {
74 	case IIO_CHAN_INFO_RAW:
75 		priv = iio_priv(iio_dev);
76 		*val = priv->cache[chan->channel];
77 		return IIO_VAL_INT;
78 
79 	case IIO_CHAN_INFO_SCALE:
80 		*val = 1;
81 		return IIO_VAL_INT;
82 
83 	default:
84 		return -EINVAL;
85 	}
86 }
87 
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)
91 {
92 	struct dac7612 *priv = iio_priv(iio_dev);
93 	int ret;
94 
95 	if (mask != IIO_CHAN_INFO_RAW)
96 		return -EINVAL;
97 
98 	if ((val >= BIT(DAC7612_RESOLUTION)) || val < 0 || val2)
99 		return -EINVAL;
100 
101 	if (val == priv->cache[chan->channel])
102 		return 0;
103 
104 	mutex_lock(&iio_dev->mlock);
105 	ret = dac7612_cmd_single(priv, chan->channel, val);
106 	mutex_unlock(&iio_dev->mlock);
107 
108 	return ret;
109 }
110 
111 static const struct iio_info dac7612_info = {
112 	.read_raw = dac7612_read_raw,
113 	.write_raw = dac7612_write_raw,
114 };
115 
116 static int dac7612_probe(struct spi_device *spi)
117 {
118 	struct iio_dev *iio_dev;
119 	struct dac7612 *priv;
120 	int i;
121 	int ret;
122 
123 	iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
124 	if (!iio_dev)
125 		return -ENOMEM;
126 
127 	priv = iio_priv(iio_dev);
128 	/*
129 	 * LOADDACS pin can be controlled by the driver or externally.
130 	 * When controlled by the driver, the DAC value is updated after
131 	 * every write.
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
134 	 * pin.
135 	 */
136 	priv->loaddacs = devm_gpiod_get_optional(&spi->dev, "ti,loaddacs",
137 						 GPIOD_OUT_LOW);
138 	if (IS_ERR(priv->loaddacs))
139 		return PTR_ERR(priv->loaddacs);
140 	priv->spi = spi;
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;
148 
149 	for (i = 0; i < ARRAY_SIZE(priv->cache); i++) {
150 		ret = dac7612_cmd_single(priv, i, 0);
151 		if (ret)
152 			return ret;
153 	}
154 
155 	return devm_iio_device_register(&spi->dev, iio_dev);
156 }
157 
158 static const struct spi_device_id dac7612_id[] = {
159 	{"ti-dac7612"},
160 	{}
161 };
162 MODULE_DEVICE_TABLE(spi, dac7612_id);
163 
164 static const struct of_device_id dac7612_of_match[] = {
165 	{ .compatible = "ti,dac7612" },
166 	{ .compatible = "ti,dac7612u" },
167 	{ .compatible = "ti,dac7612ub" },
168 	{ },
169 };
170 MODULE_DEVICE_TABLE(of, dac7612_of_match);
171 
172 static struct spi_driver dac7612_driver = {
173 	.driver = {
174 		   .name = "ti-dac7612",
175 		   .of_match_table = dac7612_of_match,
176 		   },
177 	.probe = dac7612_probe,
178 	.id_table = dac7612_id,
179 };
180 module_spi_driver(dac7612_driver);
181 
182 MODULE_AUTHOR("Ricardo Ribalda <ricardo@ribalda.com>");
183 MODULE_DESCRIPTION("Texas Instruments DAC7612 DAC driver");
184 MODULE_LICENSE("GPL v2");
185