2 * ti-dac082s085.c - Texas Instruments 8/10/12-bit 2/4-channel DAC driver
4 * Copyright (C) 2017 KUNBUS GmbH
6 * http://www.ti.com/lit/ds/symlink/dac082s085.pdf
7 * http://www.ti.com/lit/ds/symlink/dac102s085.pdf
8 * http://www.ti.com/lit/ds/symlink/dac122s085.pdf
9 * http://www.ti.com/lit/ds/symlink/dac084s085.pdf
10 * http://www.ti.com/lit/ds/symlink/dac104s085.pdf
11 * http://www.ti.com/lit/ds/symlink/dac124s085.pdf
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License (version 2) as
15 * published by the Free Software Foundation.
18 #include <linux/iio/iio.h>
19 #include <linux/module.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/spi/spi.h>
23 enum { dual_8bit
, dual_10bit
, dual_12bit
, quad_8bit
, quad_10bit
, quad_12bit
};
30 static const struct ti_dac_spec ti_dac_spec
[] = {
31 [dual_8bit
] = { .num_channels
= 2, .resolution
= 8 },
32 [dual_10bit
] = { .num_channels
= 2, .resolution
= 10 },
33 [dual_12bit
] = { .num_channels
= 2, .resolution
= 12 },
34 [quad_8bit
] = { .num_channels
= 4, .resolution
= 8 },
35 [quad_10bit
] = { .num_channels
= 4, .resolution
= 10 },
36 [quad_12bit
] = { .num_channels
= 4, .resolution
= 12 },
40 * struct ti_dac_chip - TI DAC chip
41 * @lock: protects write sequences
42 * @vref: regulator generating Vref
43 * @mesg: SPI message to perform a write
44 * @xfer: SPI transfer used by @mesg
45 * @val: cached value of each output
46 * @powerdown: whether the chip is powered down
47 * @powerdown_mode: selected by the user
48 * @resolution: resolution of the chip
49 * @buf: buffer for @xfer
53 struct regulator
*vref
;
54 struct spi_message mesg
;
55 struct spi_transfer xfer
;
60 u8 buf
[2] ____cacheline_aligned
;
63 #define WRITE_NOT_UPDATE(chan) (0x00 | (chan) << 6)
64 #define WRITE_AND_UPDATE(chan) (0x10 | (chan) << 6)
65 #define WRITE_ALL_UPDATE 0x20
66 #define POWERDOWN(mode) (0x30 | ((mode) + 1) << 6)
68 static int ti_dac_cmd(struct ti_dac_chip
*ti_dac
, u8 cmd
, u16 val
)
70 u8 shift
= 12 - ti_dac
->resolution
;
72 ti_dac
->buf
[0] = cmd
| (val
>> (8 - shift
));
73 ti_dac
->buf
[1] = (val
<< shift
) & 0xff;
74 return spi_sync(ti_dac
->mesg
.spi
, &ti_dac
->mesg
);
77 static const char * const ti_dac_powerdown_modes
[] = {
78 "2.5kohm_to_gnd", "100kohm_to_gnd", "three_state",
81 static int ti_dac_get_powerdown_mode(struct iio_dev
*indio_dev
,
82 const struct iio_chan_spec
*chan
)
84 struct ti_dac_chip
*ti_dac
= iio_priv(indio_dev
);
86 return ti_dac
->powerdown_mode
;
89 static int ti_dac_set_powerdown_mode(struct iio_dev
*indio_dev
,
90 const struct iio_chan_spec
*chan
,
93 struct ti_dac_chip
*ti_dac
= iio_priv(indio_dev
);
96 if (ti_dac
->powerdown_mode
== mode
)
99 mutex_lock(&ti_dac
->lock
);
100 if (ti_dac
->powerdown
) {
101 ret
= ti_dac_cmd(ti_dac
, POWERDOWN(mode
), 0);
105 ti_dac
->powerdown_mode
= mode
;
108 mutex_unlock(&ti_dac
->lock
);
112 static const struct iio_enum ti_dac_powerdown_mode
= {
113 .items
= ti_dac_powerdown_modes
,
114 .num_items
= ARRAY_SIZE(ti_dac_powerdown_modes
),
115 .get
= ti_dac_get_powerdown_mode
,
116 .set
= ti_dac_set_powerdown_mode
,
119 static ssize_t
ti_dac_read_powerdown(struct iio_dev
*indio_dev
,
121 const struct iio_chan_spec
*chan
,
124 struct ti_dac_chip
*ti_dac
= iio_priv(indio_dev
);
126 return sprintf(buf
, "%d\n", ti_dac
->powerdown
);
129 static ssize_t
ti_dac_write_powerdown(struct iio_dev
*indio_dev
,
131 const struct iio_chan_spec
*chan
,
132 const char *buf
, size_t len
)
134 struct ti_dac_chip
*ti_dac
= iio_priv(indio_dev
);
138 ret
= strtobool(buf
, &powerdown
);
142 if (ti_dac
->powerdown
== powerdown
)
145 mutex_lock(&ti_dac
->lock
);
147 ret
= ti_dac_cmd(ti_dac
, POWERDOWN(ti_dac
->powerdown_mode
), 0);
149 ret
= ti_dac_cmd(ti_dac
, WRITE_AND_UPDATE(0), ti_dac
->val
[0]);
151 ti_dac
->powerdown
= powerdown
;
152 mutex_unlock(&ti_dac
->lock
);
154 return ret
? ret
: len
;
157 static const struct iio_chan_spec_ext_info ti_dac_ext_info
[] = {
160 .read
= ti_dac_read_powerdown
,
161 .write
= ti_dac_write_powerdown
,
162 .shared
= IIO_SHARED_BY_TYPE
,
164 IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE
, &ti_dac_powerdown_mode
),
165 IIO_ENUM_AVAILABLE("powerdown_mode", &ti_dac_powerdown_mode
),
169 #define TI_DAC_CHANNEL(chan) { \
170 .type = IIO_VOLTAGE, \
175 .datasheet_name = (const char[]){ 'A' + (chan), 0 }, \
176 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
177 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
178 .ext_info = ti_dac_ext_info, \
181 static const struct iio_chan_spec ti_dac_channels
[] = {
188 static int ti_dac_read_raw(struct iio_dev
*indio_dev
,
189 struct iio_chan_spec
const *chan
,
190 int *val
, int *val2
, long mask
)
192 struct ti_dac_chip
*ti_dac
= iio_priv(indio_dev
);
196 case IIO_CHAN_INFO_RAW
:
197 *val
= ti_dac
->val
[chan
->channel
];
201 case IIO_CHAN_INFO_SCALE
:
202 ret
= regulator_get_voltage(ti_dac
->vref
);
207 *val2
= ti_dac
->resolution
;
208 ret
= IIO_VAL_FRACTIONAL_LOG2
;
218 static int ti_dac_write_raw(struct iio_dev
*indio_dev
,
219 struct iio_chan_spec
const *chan
,
220 int val
, int val2
, long mask
)
222 struct ti_dac_chip
*ti_dac
= iio_priv(indio_dev
);
226 case IIO_CHAN_INFO_RAW
:
227 if (ti_dac
->val
[chan
->channel
] == val
)
230 if (val
>= (1 << ti_dac
->resolution
) || val
< 0)
233 if (ti_dac
->powerdown
)
236 mutex_lock(&ti_dac
->lock
);
237 ret
= ti_dac_cmd(ti_dac
, WRITE_AND_UPDATE(chan
->channel
), val
);
239 ti_dac
->val
[chan
->channel
] = val
;
240 mutex_unlock(&ti_dac
->lock
);
250 static int ti_dac_write_raw_get_fmt(struct iio_dev
*indio_dev
,
251 struct iio_chan_spec
const *chan
, long mask
)
256 static const struct iio_info ti_dac_info
= {
257 .read_raw
= ti_dac_read_raw
,
258 .write_raw
= ti_dac_write_raw
,
259 .write_raw_get_fmt
= ti_dac_write_raw_get_fmt
,
262 static int ti_dac_probe(struct spi_device
*spi
)
264 struct device
*dev
= &spi
->dev
;
265 const struct ti_dac_spec
*spec
;
266 struct ti_dac_chip
*ti_dac
;
267 struct iio_dev
*indio_dev
;
270 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*ti_dac
));
274 indio_dev
->dev
.parent
= dev
;
275 indio_dev
->info
= &ti_dac_info
;
276 indio_dev
->name
= spi
->modalias
;
277 indio_dev
->modes
= INDIO_DIRECT_MODE
;
278 indio_dev
->channels
= ti_dac_channels
;
279 spi_set_drvdata(spi
, indio_dev
);
281 ti_dac
= iio_priv(indio_dev
);
282 ti_dac
->xfer
.tx_buf
= &ti_dac
->buf
;
283 ti_dac
->xfer
.len
= sizeof(ti_dac
->buf
);
284 spi_message_init_with_transfers(&ti_dac
->mesg
, &ti_dac
->xfer
, 1);
285 ti_dac
->mesg
.spi
= spi
;
287 spec
= &ti_dac_spec
[spi_get_device_id(spi
)->driver_data
];
288 indio_dev
->num_channels
= spec
->num_channels
;
289 ti_dac
->resolution
= spec
->resolution
;
291 ti_dac
->vref
= devm_regulator_get(dev
, "vref");
292 if (IS_ERR(ti_dac
->vref
))
293 return PTR_ERR(ti_dac
->vref
);
295 ret
= regulator_enable(ti_dac
->vref
);
299 mutex_init(&ti_dac
->lock
);
301 ret
= ti_dac_cmd(ti_dac
, WRITE_ALL_UPDATE
, 0);
303 dev_err(dev
, "failed to initialize outputs to 0\n");
307 ret
= iio_device_register(indio_dev
);
314 mutex_destroy(&ti_dac
->lock
);
315 regulator_disable(ti_dac
->vref
);
319 static int ti_dac_remove(struct spi_device
*spi
)
321 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
322 struct ti_dac_chip
*ti_dac
= iio_priv(indio_dev
);
324 iio_device_unregister(indio_dev
);
325 mutex_destroy(&ti_dac
->lock
);
326 regulator_disable(ti_dac
->vref
);
332 static const struct of_device_id ti_dac_of_id
[] = {
333 { .compatible
= "ti,dac082s085" },
334 { .compatible
= "ti,dac102s085" },
335 { .compatible
= "ti,dac122s085" },
336 { .compatible
= "ti,dac084s085" },
337 { .compatible
= "ti,dac104s085" },
338 { .compatible
= "ti,dac124s085" },
341 MODULE_DEVICE_TABLE(of
, ti_dac_of_id
);
344 static const struct spi_device_id ti_dac_spi_id
[] = {
345 { "dac082s085", dual_8bit
},
346 { "dac102s085", dual_10bit
},
347 { "dac122s085", dual_12bit
},
348 { "dac084s085", quad_8bit
},
349 { "dac104s085", quad_10bit
},
350 { "dac124s085", quad_12bit
},
353 MODULE_DEVICE_TABLE(spi
, ti_dac_spi_id
);
355 static struct spi_driver ti_dac_driver
= {
357 .name
= "ti-dac082s085",
358 .of_match_table
= of_match_ptr(ti_dac_of_id
),
360 .probe
= ti_dac_probe
,
361 .remove
= ti_dac_remove
,
362 .id_table
= ti_dac_spi_id
,
364 module_spi_driver(ti_dac_driver
);
366 MODULE_AUTHOR("Lukas Wunner <lukas@wunner.de>");
367 MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 2/4-channel DAC driver");
368 MODULE_LICENSE("GPL v2");