ltc2632.c (f243d0f0bd16c281ba5cce19eae86b433257fc2a) ltc2632.c (9f15a4a0adc910a7bd535b755185f89c3e25b37e)
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/regulator/consumer.h>
14
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/regulator/consumer.h>
14
15#define LTC2632_DAC_CHANNELS 2
16
17#define LTC2632_ADDR_DAC0 0x0
18#define LTC2632_ADDR_DAC1 0x1
19
20#define LTC2632_CMD_WRITE_INPUT_N 0x0
21#define LTC2632_CMD_UPDATE_DAC_N 0x1
22#define LTC2632_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2
23#define LTC2632_CMD_WRITE_INPUT_N_UPDATE_N 0x3
24#define LTC2632_CMD_POWERDOWN_DAC_N 0x4
25#define LTC2632_CMD_POWERDOWN_CHIP 0x5
26#define LTC2632_CMD_INTERNAL_REFER 0x6
27#define LTC2632_CMD_EXTERNAL_REFER 0x7
28
29/**
30 * struct ltc2632_chip_info - chip specific information
31 * @channels: channel spec for the DAC
32 * @vref_mv: internal reference voltage
33 */
34struct ltc2632_chip_info {
35 const struct iio_chan_spec *channels;
15#define LTC2632_ADDR_DAC0 0x0
16#define LTC2632_ADDR_DAC1 0x1
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 * @vref_mv: internal reference voltage
31 */
32struct ltc2632_chip_info {
33 const struct iio_chan_spec *channels;
34 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)

--- 8 unchanged lines hidden (view full) ---

52
53enum ltc2632_supported_device_ids {
54 ID_LTC2632L12,
55 ID_LTC2632L10,
56 ID_LTC2632L8,
57 ID_LTC2632H12,
58 ID_LTC2632H10,
59 ID_LTC2632H8,
35 const int vref_mv;
36};
37
38/**
39 * struct ltc2632_state - driver instance specific data
40 * @spi_dev: pointer to the spi_device struct
41 * @powerdown_cache_mask used to show current channel powerdown state
42 * @vref_mv used reference voltage (internal or external)

--- 8 unchanged lines hidden (view full) ---

51
52enum ltc2632_supported_device_ids {
53 ID_LTC2632L12,
54 ID_LTC2632L10,
55 ID_LTC2632L8,
56 ID_LTC2632H12,
57 ID_LTC2632H10,
58 ID_LTC2632H8,
59 ID_LTC2636L12,
60 ID_LTC2636L10,
61 ID_LTC2636L8,
62 ID_LTC2636H12,
63 ID_LTC2636H10,
64 ID_LTC2636H8,
60};
61
62static int ltc2632_spi_write(struct spi_device *spi,
63 u8 cmd, u8 addr, u16 val, u8 shift)
64{
65 u32 data;
66 u8 msg[3];
67

--- 117 unchanged lines hidden (view full) ---

185 }, \
186 .ext_info = ltc2632_ext_info, \
187}
188
189#define DECLARE_LTC2632_CHANNELS(_name, _bits) \
190 const struct iio_chan_spec _name ## _channels[] = { \
191 LTC2632_CHANNEL(0, _bits), \
192 LTC2632_CHANNEL(1, _bits), \
65};
66
67static int ltc2632_spi_write(struct spi_device *spi,
68 u8 cmd, u8 addr, u16 val, u8 shift)
69{
70 u32 data;
71 u8 msg[3];
72

--- 117 unchanged lines hidden (view full) ---

190 }, \
191 .ext_info = ltc2632_ext_info, \
192}
193
194#define DECLARE_LTC2632_CHANNELS(_name, _bits) \
195 const struct iio_chan_spec _name ## _channels[] = { \
196 LTC2632_CHANNEL(0, _bits), \
197 LTC2632_CHANNEL(1, _bits), \
198 LTC2632_CHANNEL(2, _bits), \
199 LTC2632_CHANNEL(3, _bits), \
200 LTC2632_CHANNEL(4, _bits), \
201 LTC2632_CHANNEL(5, _bits), \
202 LTC2632_CHANNEL(6, _bits), \
203 LTC2632_CHANNEL(7, _bits), \
193 }
194
195static DECLARE_LTC2632_CHANNELS(ltc2632x12, 12);
196static DECLARE_LTC2632_CHANNELS(ltc2632x10, 10);
197static DECLARE_LTC2632_CHANNELS(ltc2632x8, 8);
198
199static const struct ltc2632_chip_info ltc2632_chip_info_tbl[] = {
200 [ID_LTC2632L12] = {
201 .channels = ltc2632x12_channels,
204 }
205
206static DECLARE_LTC2632_CHANNELS(ltc2632x12, 12);
207static DECLARE_LTC2632_CHANNELS(ltc2632x10, 10);
208static DECLARE_LTC2632_CHANNELS(ltc2632x8, 8);
209
210static const struct ltc2632_chip_info ltc2632_chip_info_tbl[] = {
211 [ID_LTC2632L12] = {
212 .channels = ltc2632x12_channels,
213 .num_channels = 2,
202 .vref_mv = 2500,
203 },
204 [ID_LTC2632L10] = {
205 .channels = ltc2632x10_channels,
214 .vref_mv = 2500,
215 },
216 [ID_LTC2632L10] = {
217 .channels = ltc2632x10_channels,
218 .num_channels = 2,
206 .vref_mv = 2500,
207 },
208 [ID_LTC2632L8] = {
209 .channels = ltc2632x8_channels,
219 .vref_mv = 2500,
220 },
221 [ID_LTC2632L8] = {
222 .channels = ltc2632x8_channels,
223 .num_channels = 2,
210 .vref_mv = 2500,
211 },
212 [ID_LTC2632H12] = {
213 .channels = ltc2632x12_channels,
224 .vref_mv = 2500,
225 },
226 [ID_LTC2632H12] = {
227 .channels = ltc2632x12_channels,
228 .num_channels = 2,
214 .vref_mv = 4096,
215 },
216 [ID_LTC2632H10] = {
217 .channels = ltc2632x10_channels,
229 .vref_mv = 4096,
230 },
231 [ID_LTC2632H10] = {
232 .channels = ltc2632x10_channels,
233 .num_channels = 2,
218 .vref_mv = 4096,
219 },
220 [ID_LTC2632H8] = {
221 .channels = ltc2632x8_channels,
234 .vref_mv = 4096,
235 },
236 [ID_LTC2632H8] = {
237 .channels = ltc2632x8_channels,
238 .num_channels = 2,
222 .vref_mv = 4096,
223 },
239 .vref_mv = 4096,
240 },
241 [ID_LTC2636L12] = {
242 .channels = ltc2632x12_channels,
243 .num_channels = 8,
244 .vref_mv = 2500,
245 },
246 [ID_LTC2636L10] = {
247 .channels = ltc2632x10_channels,
248 .num_channels = 8,
249 .vref_mv = 2500,
250 },
251 [ID_LTC2636L8] = {
252 .channels = ltc2632x8_channels,
253 .num_channels = 8,
254 .vref_mv = 2500,
255 },
256 [ID_LTC2636H12] = {
257 .channels = ltc2632x12_channels,
258 .num_channels = 8,
259 .vref_mv = 4096,
260 },
261 [ID_LTC2636H10] = {
262 .channels = ltc2632x10_channels,
263 .num_channels = 8,
264 .vref_mv = 4096,
265 },
266 [ID_LTC2636H8] = {
267 .channels = ltc2632x8_channels,
268 .num_channels = 8,
269 .vref_mv = 4096,
270 },
224};
225
226static int ltc2632_probe(struct spi_device *spi)
227{
228 struct ltc2632_state *st;
229 struct iio_dev *indio_dev;
230 struct ltc2632_chip_info *chip_info;
231 int ret;

--- 50 unchanged lines hidden (view full) ---

282 }
283
284 indio_dev->dev.parent = &spi->dev;
285 indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name
286 : spi_get_device_id(spi)->name;
287 indio_dev->info = &ltc2632_info;
288 indio_dev->modes = INDIO_DIRECT_MODE;
289 indio_dev->channels = chip_info->channels;
271};
272
273static int ltc2632_probe(struct spi_device *spi)
274{
275 struct ltc2632_state *st;
276 struct iio_dev *indio_dev;
277 struct ltc2632_chip_info *chip_info;
278 int ret;

--- 50 unchanged lines hidden (view full) ---

329 }
330
331 indio_dev->dev.parent = &spi->dev;
332 indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name
333 : spi_get_device_id(spi)->name;
334 indio_dev->info = &ltc2632_info;
335 indio_dev->modes = INDIO_DIRECT_MODE;
336 indio_dev->channels = chip_info->channels;
290 indio_dev->num_channels = LTC2632_DAC_CHANNELS;
337 indio_dev->num_channels = chip_info->num_channels;
291
292 return iio_device_register(indio_dev);
293}
294
295static int ltc2632_remove(struct spi_device *spi)
296{
297 struct iio_dev *indio_dev = spi_get_drvdata(spi);
298 struct ltc2632_state *st = iio_priv(indio_dev);

--- 8 unchanged lines hidden (view full) ---

307
308static const struct spi_device_id ltc2632_id[] = {
309 { "ltc2632-l12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L12] },
310 { "ltc2632-l10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L10] },
311 { "ltc2632-l8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L8] },
312 { "ltc2632-h12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H12] },
313 { "ltc2632-h10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H10] },
314 { "ltc2632-h8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H8] },
338
339 return iio_device_register(indio_dev);
340}
341
342static int ltc2632_remove(struct spi_device *spi)
343{
344 struct iio_dev *indio_dev = spi_get_drvdata(spi);
345 struct ltc2632_state *st = iio_priv(indio_dev);

--- 8 unchanged lines hidden (view full) ---

354
355static const struct spi_device_id ltc2632_id[] = {
356 { "ltc2632-l12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L12] },
357 { "ltc2632-l10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L10] },
358 { "ltc2632-l8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L8] },
359 { "ltc2632-h12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H12] },
360 { "ltc2632-h10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H10] },
361 { "ltc2632-h8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H8] },
362 { "ltc2636-l12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636L12] },
363 { "ltc2636-l10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636L10] },
364 { "ltc2636-l8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636L8] },
365 { "ltc2636-h12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636H12] },
366 { "ltc2636-h10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636H10] },
367 { "ltc2636-h8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636H8] },
315 {}
316};
317MODULE_DEVICE_TABLE(spi, ltc2632_id);
318
319static const struct of_device_id ltc2632_of_match[] = {
320 {
321 .compatible = "lltc,ltc2632-l12",
322 .data = &ltc2632_chip_info_tbl[ID_LTC2632L12]

--- 7 unchanged lines hidden (view full) ---

330 .compatible = "lltc,ltc2632-h12",
331 .data = &ltc2632_chip_info_tbl[ID_LTC2632H12]
332 }, {
333 .compatible = "lltc,ltc2632-h10",
334 .data = &ltc2632_chip_info_tbl[ID_LTC2632H10]
335 }, {
336 .compatible = "lltc,ltc2632-h8",
337 .data = &ltc2632_chip_info_tbl[ID_LTC2632H8]
368 {}
369};
370MODULE_DEVICE_TABLE(spi, ltc2632_id);
371
372static const struct of_device_id ltc2632_of_match[] = {
373 {
374 .compatible = "lltc,ltc2632-l12",
375 .data = &ltc2632_chip_info_tbl[ID_LTC2632L12]

--- 7 unchanged lines hidden (view full) ---

383 .compatible = "lltc,ltc2632-h12",
384 .data = &ltc2632_chip_info_tbl[ID_LTC2632H12]
385 }, {
386 .compatible = "lltc,ltc2632-h10",
387 .data = &ltc2632_chip_info_tbl[ID_LTC2632H10]
388 }, {
389 .compatible = "lltc,ltc2632-h8",
390 .data = &ltc2632_chip_info_tbl[ID_LTC2632H8]
391 }, {
392 .compatible = "lltc,ltc2636-l12",
393 .data = &ltc2632_chip_info_tbl[ID_LTC2636L12]
394 }, {
395 .compatible = "lltc,ltc2636-l10",
396 .data = &ltc2632_chip_info_tbl[ID_LTC2636L10]
397 }, {
398 .compatible = "lltc,ltc2636-l8",
399 .data = &ltc2632_chip_info_tbl[ID_LTC2636L8]
400 }, {
401 .compatible = "lltc,ltc2636-h12",
402 .data = &ltc2632_chip_info_tbl[ID_LTC2636H12]
403 }, {
404 .compatible = "lltc,ltc2636-h10",
405 .data = &ltc2632_chip_info_tbl[ID_LTC2636H10]
406 }, {
407 .compatible = "lltc,ltc2636-h8",
408 .data = &ltc2632_chip_info_tbl[ID_LTC2636H8]
338 },
339 {}
340};
341MODULE_DEVICE_TABLE(of, ltc2632_of_match);
342
343static struct spi_driver ltc2632_driver = {
344 .driver = {
345 .name = "ltc2632",
346 .of_match_table = of_match_ptr(ltc2632_of_match),
347 },
348 .probe = ltc2632_probe,
349 .remove = ltc2632_remove,
350 .id_table = ltc2632_id,
351};
352module_spi_driver(ltc2632_driver);
353
354MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
355MODULE_DESCRIPTION("LTC2632 DAC SPI driver");
356MODULE_LICENSE("GPL v2");
409 },
410 {}
411};
412MODULE_DEVICE_TABLE(of, ltc2632_of_match);
413
414static struct spi_driver ltc2632_driver = {
415 .driver = {
416 .name = "ltc2632",
417 .of_match_table = of_match_ptr(ltc2632_of_match),
418 },
419 .probe = ltc2632_probe,
420 .remove = ltc2632_remove,
421 .id_table = ltc2632_id,
422};
423module_spi_driver(ltc2632_driver);
424
425MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
426MODULE_DESCRIPTION("LTC2632 DAC SPI driver");
427MODULE_LICENSE("GPL v2");