1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * BD79703 ROHM Digital to Analog converter
4 *
5 * Copyright (c) 2024, ROHM Semiconductor.
6 */
7
8 #include <linux/bits.h>
9 #include <linux/device.h>
10 #include <linux/module.h>
11 #include <linux/regmap.h>
12 #include <linux/regulator/consumer.h>
13 #include <linux/spi/spi.h>
14 #include <linux/iio/iio.h>
15
16 #define BD79703_MAX_REGISTER 0xf
17 #define BD79703_DAC_BITS 8
18 #define BD79703_REG_OUT_ALL GENMASK(2, 0)
19
20 /*
21 * The BD79703 uses 12-bit SPI commands. First four bits (high bits) define
22 * channel(s) which are operated on, and also the mode. The mode can be to set
23 * a DAC word only, or set DAC word and output. The data-sheet is not very
24 * specific on how a previously set DAC word can be 'taken in to use'. Thus
25 * this driver only uses the 'set DAC and output it' -mode.
26 *
27 * The BD79703 latches last 12-bits when the chip-select is toggled. Thus we
28 * can use 16-bit transfers which should be widely supported. To simplify this
29 * further, we treat the last 8 bits as a value, and first 8 bits as an
30 * address. This allows us to separate channels/mode by address and treat the
31 * 8-bit register value as DAC word. The highest 4 bits of address will be
32 * discarded when the transfer is latched.
33 */
34 static const struct regmap_config bd79703_regmap_config = {
35 .reg_bits = 8,
36 .val_bits = 8,
37 .max_register = BD79703_MAX_REGISTER,
38 .cache_type = REGCACHE_MAPLE,
39 };
40
41 /* Dynamic driver private data */
42 struct bd79703_data {
43 struct regmap *regmap;
44 int vfs;
45 };
46
47 /* Static, IC type specific data for different variants */
48 struct bd7970x_chip_data {
49 const char *name;
50 const struct iio_chan_spec *channels;
51 int num_channels;
52 bool has_vfs;
53 };
54
bd79703_read_raw(struct iio_dev * idev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)55 static int bd79703_read_raw(struct iio_dev *idev,
56 struct iio_chan_spec const *chan, int *val,
57 int *val2, long mask)
58 {
59 struct bd79703_data *data = iio_priv(idev);
60
61 if (mask != IIO_CHAN_INFO_SCALE)
62 return -EINVAL;
63
64 *val = data->vfs / 1000;
65 *val2 = BD79703_DAC_BITS;
66
67 return IIO_VAL_FRACTIONAL_LOG2;
68 }
69
bd79703_write_raw(struct iio_dev * idev,struct iio_chan_spec const * chan,int val,int val2,long mask)70 static int bd79703_write_raw(struct iio_dev *idev,
71 struct iio_chan_spec const *chan, int val,
72 int val2, long mask)
73 {
74 struct bd79703_data *data = iio_priv(idev);
75
76 if (val < 0 || val >= 1 << BD79703_DAC_BITS)
77 return -EINVAL;
78
79 return regmap_write(data->regmap, chan->address, val);
80 };
81
82 static const struct iio_info bd79703_info = {
83 .read_raw = bd79703_read_raw,
84 .write_raw = bd79703_write_raw,
85 };
86
87 #define BD79703_CHAN_ADDR(_chan, _addr) { \
88 .type = IIO_VOLTAGE, \
89 .indexed = 1, \
90 .output = 1, \
91 .channel = (_chan), \
92 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
93 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
94 .address = (_addr), \
95 }
96
97 #define BD79703_CHAN(_chan) BD79703_CHAN_ADDR((_chan), (_chan) + 1)
98
99 static const struct iio_chan_spec bd79700_channels[] = {
100 BD79703_CHAN(0),
101 BD79703_CHAN(1),
102 };
103
104 static const struct iio_chan_spec bd79701_channels[] = {
105 BD79703_CHAN(0),
106 BD79703_CHAN(1),
107 BD79703_CHAN(2),
108 };
109
110 /*
111 * The BD79702 has 4 channels. They aren't mapped to BD79703 channels 0, 1, 2
112 * and 3, but to the channels 0, 1, 4, 5. So the addressing used with SPI
113 * accesses is 1, 2, 5 and 6 for them. Thus, they're not constant offset to
114 * the channel number as with other IC variants.
115 */
116 static const struct iio_chan_spec bd79702_channels[] = {
117 BD79703_CHAN_ADDR(0, 1),
118 BD79703_CHAN_ADDR(1, 2),
119 BD79703_CHAN_ADDR(2, 5),
120 BD79703_CHAN_ADDR(3, 6),
121 };
122
123 static const struct iio_chan_spec bd79703_channels[] = {
124 BD79703_CHAN(0),
125 BD79703_CHAN(1),
126 BD79703_CHAN(2),
127 BD79703_CHAN(3),
128 BD79703_CHAN(4),
129 BD79703_CHAN(5),
130 };
131
132 static const struct bd7970x_chip_data bd79700_chip_data = {
133 .name = "bd79700",
134 .channels = bd79700_channels,
135 .num_channels = ARRAY_SIZE(bd79700_channels),
136 .has_vfs = false,
137 };
138
139 static const struct bd7970x_chip_data bd79701_chip_data = {
140 .name = "bd79701",
141 .channels = bd79701_channels,
142 .num_channels = ARRAY_SIZE(bd79701_channels),
143 .has_vfs = false,
144 };
145
146 static const struct bd7970x_chip_data bd79702_chip_data = {
147 .name = "bd79702",
148 .channels = bd79702_channels,
149 .num_channels = ARRAY_SIZE(bd79702_channels),
150 .has_vfs = true,
151 };
152
153 static const struct bd7970x_chip_data bd79703_chip_data = {
154 .name = "bd79703",
155 .channels = bd79703_channels,
156 .num_channels = ARRAY_SIZE(bd79703_channels),
157 .has_vfs = true,
158 };
159
bd79703_probe(struct spi_device * spi)160 static int bd79703_probe(struct spi_device *spi)
161 {
162 const struct bd7970x_chip_data *cd;
163 struct device *dev = &spi->dev;
164 struct bd79703_data *data;
165 struct iio_dev *idev;
166 int ret;
167
168 cd = spi_get_device_match_data(spi);
169 if (!cd)
170 return -ENODEV;
171
172 idev = devm_iio_device_alloc(dev, sizeof(*data));
173 if (!idev)
174 return -ENOMEM;
175
176 data = iio_priv(idev);
177
178 data->regmap = devm_regmap_init_spi(spi, &bd79703_regmap_config);
179 if (IS_ERR(data->regmap))
180 return dev_err_probe(dev, PTR_ERR(data->regmap),
181 "Failed to initialize Regmap\n");
182
183 /*
184 * BD79703 has a separate VFS pin, whereas the BD79700 and BD79701 use
185 * VCC for their full-scale output voltage.
186 */
187 if (cd->has_vfs) {
188 ret = devm_regulator_get_enable(dev, "vcc");
189 if (ret)
190 return dev_err_probe(dev, ret, "Failed to enable VCC\n");
191
192 ret = devm_regulator_get_enable_read_voltage(dev, "vfs");
193 if (ret < 0)
194 return dev_err_probe(dev, ret, "Failed to get Vfs\n");
195 } else {
196 ret = devm_regulator_get_enable_read_voltage(dev, "vcc");
197 if (ret < 0)
198 return dev_err_probe(dev, ret, "Failed to get VCC\n");
199 }
200 data->vfs = ret;
201
202 idev->channels = cd->channels;
203 idev->num_channels = cd->num_channels;
204 idev->modes = INDIO_DIRECT_MODE;
205 idev->info = &bd79703_info;
206 idev->name = cd->name;
207
208 /* Initialize all to output zero */
209 ret = regmap_write(data->regmap, BD79703_REG_OUT_ALL, 0);
210 if (ret)
211 return ret;
212
213 return devm_iio_device_register(dev, idev);
214 }
215
216 static const struct spi_device_id bd79703_id[] = {
217 { "bd79700", (kernel_ulong_t)&bd79700_chip_data },
218 { "bd79701", (kernel_ulong_t)&bd79701_chip_data },
219 { "bd79702", (kernel_ulong_t)&bd79702_chip_data },
220 { "bd79703", (kernel_ulong_t)&bd79703_chip_data },
221 { }
222 };
223 MODULE_DEVICE_TABLE(spi, bd79703_id);
224
225 static const struct of_device_id bd79703_of_match[] = {
226 { .compatible = "rohm,bd79700", .data = &bd79700_chip_data },
227 { .compatible = "rohm,bd79701", .data = &bd79701_chip_data },
228 { .compatible = "rohm,bd79702", .data = &bd79702_chip_data },
229 { .compatible = "rohm,bd79703", .data = &bd79703_chip_data },
230 { }
231 };
232 MODULE_DEVICE_TABLE(of, bd79703_of_match);
233
234 static struct spi_driver bd79703_driver = {
235 .driver = {
236 .name = "bd79703",
237 .of_match_table = bd79703_of_match,
238 },
239 .probe = bd79703_probe,
240 .id_table = bd79703_id,
241 };
242 module_spi_driver(bd79703_driver);
243
244 MODULE_AUTHOR("Matti Vaittinen <mazziesaccount@gmail.com>");
245 MODULE_DESCRIPTION("ROHM BD79703 DAC driver");
246 MODULE_LICENSE("GPL");
247