xref: /linux/drivers/iio/dac/ltc2632.c (revision 53597deca0e38c30e6cd4ba2114fa42d2bcd85bb)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * LTC2632 Digital to analog convertors spi driver
4  *
5  * Copyright 2017 Maxime Roussin-Bélanger
6  * expanded by Silvan Murer <silvan.murer@gmail.com>
7  */
8 
9 #include <linux/device.h>
10 #include <linux/spi/spi.h>
11 #include <linux/module.h>
12 #include <linux/iio/iio.h>
13 #include <linux/property.h>
14 #include <linux/regulator/consumer.h>
15 
16 #include <linux/unaligned.h>
17 
18 #define LTC2632_CMD_WRITE_INPUT_N               0x0
19 #define LTC2632_CMD_UPDATE_DAC_N                0x1
20 #define LTC2632_CMD_WRITE_INPUT_N_UPDATE_ALL    0x2
21 #define LTC2632_CMD_WRITE_INPUT_N_UPDATE_N      0x3
22 #define LTC2632_CMD_POWERDOWN_DAC_N             0x4
23 #define LTC2632_CMD_POWERDOWN_CHIP              0x5
24 #define LTC2632_CMD_INTERNAL_REFER              0x6
25 #define LTC2632_CMD_EXTERNAL_REFER              0x7
26 
27 /**
28  * struct ltc2632_chip_info - chip specific information
29  * @channels:		channel spec for the DAC
30  * @num_channels:	DAC channel count of the chip
31  * @vref_mv:		internal reference voltage
32  */
33 struct ltc2632_chip_info {
34 	const struct iio_chan_spec *channels;
35 	const size_t num_channels;
36 	const int vref_mv;
37 };
38 
39 /**
40  * struct ltc2632_state - driver instance specific data
41  * @spi_dev:			pointer to the spi_device struct
42  * @powerdown_cache_mask:	used to show current channel powerdown state
43  * @vref_mv:			used reference voltage (internal or external)
44  */
45 struct ltc2632_state {
46 	struct spi_device *spi_dev;
47 	unsigned int powerdown_cache_mask;
48 	int vref_mv;
49 };
50 
51 static int ltc2632_spi_write(struct spi_device *spi,
52 			     u8 cmd, u8 addr, u16 val, u8 shift)
53 {
54 	u32 data;
55 	u8 msg[3];
56 
57 	/*
58 	 * The input shift register is 24 bits wide.
59 	 * The next four are the command bits, C3 to C0,
60 	 * followed by the 4-bit DAC address, A3 to A0, and then the
61 	 * 16-, 12-, 10-, 8-bit data-word. The data-word comprises the
62 	 * 16-, 12-, 10-, 8-bit input code followed by 0, 4, 6, or 8
63 	 * don't care bits.
64 	 */
65 	data = (cmd << 20) | (addr << 16) | (val << shift);
66 	put_unaligned_be24(data, &msg[0]);
67 
68 	return spi_write(spi, msg, sizeof(msg));
69 }
70 
71 static int ltc2632_read_raw(struct iio_dev *indio_dev,
72 			    struct iio_chan_spec const *chan,
73 			    int *val,
74 			    int *val2,
75 			    long m)
76 {
77 	const struct ltc2632_state *st = iio_priv(indio_dev);
78 
79 	switch (m) {
80 	case IIO_CHAN_INFO_SCALE:
81 		*val = st->vref_mv;
82 		*val2 = chan->scan_type.realbits;
83 		return IIO_VAL_FRACTIONAL_LOG2;
84 	}
85 	return -EINVAL;
86 }
87 
88 static int ltc2632_write_raw(struct iio_dev *indio_dev,
89 			     struct iio_chan_spec const *chan,
90 			     int val,
91 			     int val2,
92 			     long mask)
93 {
94 	struct ltc2632_state *st = iio_priv(indio_dev);
95 
96 	switch (mask) {
97 	case IIO_CHAN_INFO_RAW:
98 		if (val >= (1 << chan->scan_type.realbits) || val < 0)
99 			return -EINVAL;
100 
101 		return ltc2632_spi_write(st->spi_dev,
102 					 LTC2632_CMD_WRITE_INPUT_N_UPDATE_N,
103 					 chan->address, val,
104 					 chan->scan_type.shift);
105 	default:
106 		return -EINVAL;
107 	}
108 }
109 
110 static ssize_t ltc2632_read_dac_powerdown(struct iio_dev *indio_dev,
111 					  uintptr_t private,
112 					  const struct iio_chan_spec *chan,
113 					  char *buf)
114 {
115 	struct ltc2632_state *st = iio_priv(indio_dev);
116 
117 	return sysfs_emit(buf, "%d\n",
118 			  !!(st->powerdown_cache_mask & (1 << chan->channel)));
119 }
120 
121 static ssize_t ltc2632_write_dac_powerdown(struct iio_dev *indio_dev,
122 					   uintptr_t private,
123 					   const struct iio_chan_spec *chan,
124 					   const char *buf,
125 					   size_t len)
126 {
127 	bool pwr_down;
128 	int ret;
129 	struct ltc2632_state *st = iio_priv(indio_dev);
130 
131 	ret = kstrtobool(buf, &pwr_down);
132 	if (ret)
133 		return ret;
134 
135 	if (pwr_down)
136 		st->powerdown_cache_mask |= (1 << chan->channel);
137 	else
138 		st->powerdown_cache_mask &= ~(1 << chan->channel);
139 
140 	ret = ltc2632_spi_write(st->spi_dev,
141 				LTC2632_CMD_POWERDOWN_DAC_N,
142 				chan->channel, 0, 0);
143 
144 	return ret ? ret : len;
145 }
146 
147 static const struct iio_info ltc2632_info = {
148 	.write_raw	= ltc2632_write_raw,
149 	.read_raw	= ltc2632_read_raw,
150 };
151 
152 static const struct iio_chan_spec_ext_info ltc2632_ext_info[] = {
153 	{
154 		.name = "powerdown",
155 		.read = ltc2632_read_dac_powerdown,
156 		.write = ltc2632_write_dac_powerdown,
157 		.shared = IIO_SEPARATE,
158 	},
159 	{ }
160 };
161 
162 #define LTC2632_CHANNEL(_chan, _bits) { \
163 		.type = IIO_VOLTAGE, \
164 		.indexed = 1, \
165 		.output = 1, \
166 		.channel = (_chan), \
167 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
168 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
169 		.address = (_chan), \
170 		.scan_type = { \
171 			.realbits	= (_bits), \
172 			.shift		= 16 - (_bits), \
173 		}, \
174 		.ext_info = ltc2632_ext_info, \
175 }
176 
177 #define DECLARE_LTC2632_CHANNELS(_name, _bits) \
178 	const struct iio_chan_spec _name ## _channels[] = { \
179 		LTC2632_CHANNEL(0, _bits), \
180 		LTC2632_CHANNEL(1, _bits), \
181 		LTC2632_CHANNEL(2, _bits), \
182 		LTC2632_CHANNEL(3, _bits), \
183 		LTC2632_CHANNEL(4, _bits), \
184 		LTC2632_CHANNEL(5, _bits), \
185 		LTC2632_CHANNEL(6, _bits), \
186 		LTC2632_CHANNEL(7, _bits), \
187 	}
188 
189 static DECLARE_LTC2632_CHANNELS(ltc2632x16, 16);
190 static DECLARE_LTC2632_CHANNELS(ltc2632x12, 12);
191 static DECLARE_LTC2632_CHANNELS(ltc2632x10, 10);
192 static DECLARE_LTC2632_CHANNELS(ltc2632x8, 8);
193 
194 static const struct ltc2632_chip_info ltc2632l12_chip_info = {
195 	.channels	= ltc2632x12_channels,
196 	.num_channels	= 2,
197 	.vref_mv	= 2500,
198 };
199 
200 static const struct ltc2632_chip_info ltc2632l10_chip_info = {
201 	.channels	= ltc2632x10_channels,
202 	.num_channels	= 2,
203 	.vref_mv	= 2500,
204 };
205 
206 static const struct ltc2632_chip_info ltc2632l8_chip_info = {
207 	.channels	= ltc2632x8_channels,
208 	.num_channels	= 2,
209 	.vref_mv	= 2500,
210 };
211 
212 static const struct ltc2632_chip_info ltc2632h12_chip_info = {
213 	.channels	= ltc2632x12_channels,
214 	.num_channels	= 2,
215 	.vref_mv	= 4096,
216 };
217 
218 static const struct ltc2632_chip_info ltc2632h10_chip_info = {
219 	.channels	= ltc2632x10_channels,
220 	.num_channels	= 2,
221 	.vref_mv	= 4096,
222 };
223 
224 static const struct ltc2632_chip_info ltc2632h8_chip_info = {
225 	.channels	= ltc2632x8_channels,
226 	.num_channels	= 2,
227 	.vref_mv	= 4096,
228 };
229 
230 static const struct ltc2632_chip_info ltc2634l12_chip_info = {
231 	.channels	= ltc2632x12_channels,
232 	.num_channels	= 4,
233 	.vref_mv	= 2500,
234 };
235 
236 static const struct ltc2632_chip_info ltc2634l10_chip_info = {
237 	.channels	= ltc2632x10_channels,
238 	.num_channels	= 4,
239 	.vref_mv	= 2500,
240 };
241 
242 static const struct ltc2632_chip_info ltc2634l8_chip_info = {
243 	.channels	= ltc2632x8_channels,
244 	.num_channels	= 4,
245 	.vref_mv	= 2500,
246 };
247 
248 static const struct ltc2632_chip_info ltc2634h12_chip_info = {
249 	.channels	= ltc2632x12_channels,
250 	.num_channels	= 4,
251 	.vref_mv	= 4096,
252 };
253 
254 static const struct ltc2632_chip_info ltc2634h10_chip_info = {
255 	.channels	= ltc2632x10_channels,
256 	.num_channels	= 4,
257 	.vref_mv	= 4096,
258 };
259 
260 static const struct ltc2632_chip_info ltc2634h8_chip_info = {
261 	.channels	= ltc2632x8_channels,
262 	.num_channels	= 4,
263 	.vref_mv	= 4096,
264 };
265 
266 static const struct ltc2632_chip_info ltc2636l12_chip_info = {
267 	.channels	= ltc2632x12_channels,
268 	.num_channels	= 8,
269 	.vref_mv	= 2500,
270 };
271 
272 static const struct ltc2632_chip_info ltc2636l10_chip_info = {
273 	.channels	= ltc2632x10_channels,
274 	.num_channels	= 8,
275 	.vref_mv	= 2500,
276 };
277 
278 static const struct ltc2632_chip_info ltc2636l8_chip_info = {
279 	.channels	= ltc2632x8_channels,
280 	.num_channels	= 8,
281 	.vref_mv	= 2500,
282 };
283 
284 static const struct ltc2632_chip_info ltc2636h12_chip_info = {
285 	.channels	= ltc2632x12_channels,
286 	.num_channels	= 8,
287 	.vref_mv	= 4096,
288 };
289 
290 static const struct ltc2632_chip_info ltc2636h10_chip_info = {
291 	.channels	= ltc2632x10_channels,
292 	.num_channels	= 8,
293 	.vref_mv	= 4096,
294 };
295 
296 static const struct ltc2632_chip_info ltc2636h8_chip_info = {
297 	.channels	= ltc2632x8_channels,
298 	.num_channels	= 8,
299 	.vref_mv	= 4096,
300 };
301 
302 static const struct ltc2632_chip_info ltc2654l16_chip_info = {
303 	.channels	= ltc2632x16_channels,
304 	.num_channels	= 4,
305 	.vref_mv	= 2500,
306 };
307 
308 static const struct ltc2632_chip_info ltc2654h16_chip_info = {
309 	.channels	= ltc2632x16_channels,
310 	.num_channels	= 4,
311 	.vref_mv	= 4096,
312 };
313 
314 static int ltc2632_probe(struct spi_device *spi)
315 {
316 	struct ltc2632_state *st;
317 	struct iio_dev *indio_dev;
318 	struct ltc2632_chip_info *chip_info;
319 	bool has_external_vref;
320 	int ret;
321 
322 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
323 	if (!indio_dev)
324 		return -ENOMEM;
325 
326 	st = iio_priv(indio_dev);
327 
328 	st->spi_dev = spi;
329 
330 	chip_info = (struct ltc2632_chip_info *)
331 			spi_get_device_id(spi)->driver_data;
332 
333 	ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref");
334 	if (ret < 0 && ret != -ENODEV)
335 		return dev_err_probe(&spi->dev, ret,
336 				     "Failed to get vref regulator voltage\n");
337 
338 	has_external_vref = ret != -ENODEV;
339 	st->vref_mv = has_external_vref ? ret / 1000 : chip_info->vref_mv;
340 
341 	if (has_external_vref) {
342 		ret = ltc2632_spi_write(spi, LTC2632_CMD_EXTERNAL_REFER,
343 					0, 0, 0);
344 		if (ret)
345 			return dev_err_probe(&spi->dev, ret,
346 				"Set external reference command failed\n");
347 	} else {
348 		ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER,
349 					0, 0, 0);
350 		if (ret)
351 			return dev_err_probe(&spi->dev, ret,
352 				"Set internal reference command failed\n");
353 	}
354 
355 	indio_dev->name = fwnode_get_name(dev_fwnode(&spi->dev)) ?: spi_get_device_id(spi)->name;
356 	indio_dev->info = &ltc2632_info;
357 	indio_dev->modes = INDIO_DIRECT_MODE;
358 	indio_dev->channels = chip_info->channels;
359 	indio_dev->num_channels = chip_info->num_channels;
360 
361 	return devm_iio_device_register(&spi->dev, indio_dev);
362 }
363 
364 static const struct spi_device_id ltc2632_id[] = {
365 	{ "ltc2632-l12", (kernel_ulong_t)&ltc2632l12_chip_info },
366 	{ "ltc2632-l10", (kernel_ulong_t)&ltc2632l10_chip_info },
367 	{ "ltc2632-l8",  (kernel_ulong_t)&ltc2632l8_chip_info  },
368 	{ "ltc2632-h12", (kernel_ulong_t)&ltc2632h12_chip_info },
369 	{ "ltc2632-h10", (kernel_ulong_t)&ltc2632h10_chip_info },
370 	{ "ltc2632-h8",  (kernel_ulong_t)&ltc2632h8_chip_info  },
371 	{ "ltc2634-l12", (kernel_ulong_t)&ltc2634l12_chip_info },
372 	{ "ltc2634-l10", (kernel_ulong_t)&ltc2634l10_chip_info },
373 	{ "ltc2634-l8",  (kernel_ulong_t)&ltc2634l8_chip_info  },
374 	{ "ltc2634-h12", (kernel_ulong_t)&ltc2634h12_chip_info },
375 	{ "ltc2634-h10", (kernel_ulong_t)&ltc2634h10_chip_info },
376 	{ "ltc2634-h8",  (kernel_ulong_t)&ltc2634h8_chip_info  },
377 	{ "ltc2636-l12", (kernel_ulong_t)&ltc2636l12_chip_info },
378 	{ "ltc2636-l10", (kernel_ulong_t)&ltc2636l10_chip_info },
379 	{ "ltc2636-l8",  (kernel_ulong_t)&ltc2636l8_chip_info  },
380 	{ "ltc2636-h12", (kernel_ulong_t)&ltc2636h12_chip_info },
381 	{ "ltc2636-h10", (kernel_ulong_t)&ltc2636h10_chip_info },
382 	{ "ltc2636-h8",  (kernel_ulong_t)&ltc2636h8_chip_info  },
383 	{ "ltc2654-l16", (kernel_ulong_t)&ltc2654l16_chip_info },
384 	{ "ltc2654-l12", (kernel_ulong_t)&ltc2634l12_chip_info },
385 	{ "ltc2654-h16", (kernel_ulong_t)&ltc2654h16_chip_info },
386 	{ "ltc2654-h12", (kernel_ulong_t)&ltc2634h12_chip_info },
387 	{ }
388 };
389 MODULE_DEVICE_TABLE(spi, ltc2632_id);
390 
391 static const struct of_device_id ltc2632_of_match[] = {
392 	{ .compatible = "lltc,ltc2632-l12", .data = &ltc2632l12_chip_info },
393 	{ .compatible = "lltc,ltc2632-l10", .data = &ltc2632l10_chip_info },
394 	{ .compatible = "lltc,ltc2632-l8",  .data = &ltc2632l8_chip_info  },
395 	{ .compatible = "lltc,ltc2632-h12", .data = &ltc2632h12_chip_info },
396 	{ .compatible = "lltc,ltc2632-h10", .data = &ltc2632h10_chip_info },
397 	{ .compatible = "lltc,ltc2632-h8",  .data = &ltc2632h8_chip_info  },
398 	{ .compatible = "lltc,ltc2634-l12", .data = &ltc2634l12_chip_info },
399 	{ .compatible = "lltc,ltc2634-l10", .data = &ltc2634l10_chip_info },
400 	{ .compatible = "lltc,ltc2634-l8",  .data = &ltc2634l8_chip_info  },
401 	{ .compatible = "lltc,ltc2634-h12", .data = &ltc2634h12_chip_info },
402 	{ .compatible = "lltc,ltc2634-h10", .data = &ltc2634h10_chip_info },
403 	{ .compatible = "lltc,ltc2634-h8",  .data = &ltc2634h8_chip_info  },
404 	{ .compatible = "lltc,ltc2636-l12", .data = &ltc2636l12_chip_info },
405 	{ .compatible = "lltc,ltc2636-l10", .data = &ltc2636l10_chip_info },
406 	{ .compatible = "lltc,ltc2636-l8",  .data = &ltc2636l8_chip_info  },
407 	{ .compatible = "lltc,ltc2636-h12", .data = &ltc2636h12_chip_info },
408 	{ .compatible = "lltc,ltc2636-h10", .data = &ltc2636h10_chip_info },
409 	{ .compatible = "lltc,ltc2636-h8",  .data = &ltc2636h8_chip_info  },
410 	{ .compatible = "lltc,ltc2654-l16", .data = &ltc2654l16_chip_info },
411 	{ .compatible = "lltc,ltc2654-h16", .data = &ltc2654h16_chip_info },
412 	{ }
413 };
414 MODULE_DEVICE_TABLE(of, ltc2632_of_match);
415 
416 static struct spi_driver ltc2632_driver = {
417 	.driver		= {
418 		.name	= "ltc2632",
419 		.of_match_table = ltc2632_of_match,
420 	},
421 	.probe		= ltc2632_probe,
422 	.id_table	= ltc2632_id,
423 };
424 module_spi_driver(ltc2632_driver);
425 
426 MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
427 MODULE_DESCRIPTION("LTC2632 and similar DAC SPI driver");
428 MODULE_LICENSE("GPL v2");
429