xref: /openbmc/linux/drivers/iio/dac/ti-dac5571.c (revision b9b77222)
1 /*
2  * ti-dac5571.c - Texas Instruments 8/10/12-bit 1/4-channel DAC driver
3  *
4  * Copyright (C) 2018 Prevas A/S
5  *
6  * http://www.ti.com/lit/ds/symlink/dac5571.pdf
7  * http://www.ti.com/lit/ds/symlink/dac6571.pdf
8  * http://www.ti.com/lit/ds/symlink/dac7571.pdf
9  * http://www.ti.com/lit/ds/symlink/dac5574.pdf
10  * http://www.ti.com/lit/ds/symlink/dac6574.pdf
11  * http://www.ti.com/lit/ds/symlink/dac7574.pdf
12  * http://www.ti.com/lit/ds/symlink/dac5573.pdf
13  * http://www.ti.com/lit/ds/symlink/dac6573.pdf
14  * http://www.ti.com/lit/ds/symlink/dac7573.pdf
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License (version 2) as
18  * published by the Free Software Foundation.
19  */
20 
21 #include <linux/iio/iio.h>
22 #include <linux/i2c.h>
23 #include <linux/module.h>
24 #include <linux/of_device.h>
25 #include <linux/of.h>
26 #include <linux/regulator/consumer.h>
27 
28 enum chip_id {
29 	single_8bit, single_10bit, single_12bit,
30 	quad_8bit, quad_10bit, quad_12bit
31 };
32 
33 struct dac5571_spec {
34 	u8 num_channels;
35 	u8 resolution;
36 };
37 
38 static const struct dac5571_spec dac5571_spec[] = {
39 	[single_8bit]  = {.num_channels = 1, .resolution =  8},
40 	[single_10bit] = {.num_channels = 1, .resolution = 10},
41 	[single_12bit] = {.num_channels = 1, .resolution = 12},
42 	[quad_8bit]    = {.num_channels = 4, .resolution =  8},
43 	[quad_10bit]   = {.num_channels = 4, .resolution = 10},
44 	[quad_12bit]   = {.num_channels = 4, .resolution = 12},
45 };
46 
47 struct dac5571_data {
48 	struct i2c_client *client;
49 	int id;
50 	struct mutex lock;
51 	struct regulator *vref;
52 	u16 val[4];
53 	bool powerdown;
54 	u8 powerdown_mode;
55 	struct dac5571_spec const *spec;
56 	int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val);
57 	int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn);
58 	u8 buf[3] ____cacheline_aligned;
59 };
60 
61 #define DAC5571_POWERDOWN(mode)		((mode) + 1)
62 #define DAC5571_POWERDOWN_FLAG		BIT(0)
63 #define DAC5571_CHANNEL_SELECT		1
64 #define DAC5571_LOADMODE_DIRECT		BIT(4)
65 #define DAC5571_SINGLE_PWRDWN_BITS	4
66 #define DAC5571_QUAD_PWRDWN_BITS	6
67 
68 static int dac5571_cmd_single(struct dac5571_data *data, int channel, u16 val)
69 {
70 	unsigned int shift;
71 
72 	shift = 12 - data->spec->resolution;
73 	data->buf[1] = val << shift;
74 	data->buf[0] = val >> (8 - shift);
75 
76 	if (i2c_master_send(data->client, data->buf, 2) != 2)
77 		return -EIO;
78 
79 	return 0;
80 }
81 
82 static int dac5571_cmd_quad(struct dac5571_data *data, int channel, u16 val)
83 {
84 	unsigned int shift;
85 
86 	shift = 16 - data->spec->resolution;
87 	data->buf[2] = val << shift;
88 	data->buf[1] = (val >> (8 - shift));
89 	data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
90 		       DAC5571_LOADMODE_DIRECT;
91 
92 	if (i2c_master_send(data->client, data->buf, 3) != 3)
93 		return -EIO;
94 
95 	return 0;
96 }
97 
98 static int dac5571_pwrdwn_single(struct dac5571_data *data, int channel, u8 pwrdwn)
99 {
100 	unsigned int shift;
101 
102 	shift = 12 - data->spec->resolution;
103 	data->buf[1] = 0;
104 	data->buf[0] = pwrdwn << DAC5571_SINGLE_PWRDWN_BITS;
105 
106 	if (i2c_master_send(data->client, data->buf, 2) != 2)
107 		return -EIO;
108 
109 	return 0;
110 }
111 
112 static int dac5571_pwrdwn_quad(struct dac5571_data *data, int channel, u8 pwrdwn)
113 {
114 	unsigned int shift;
115 
116 	shift = 16 - data->spec->resolution;
117 	data->buf[2] = 0;
118 	data->buf[1] = pwrdwn << DAC5571_QUAD_PWRDWN_BITS;
119 	data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
120 		       DAC5571_LOADMODE_DIRECT | DAC5571_POWERDOWN_FLAG;
121 
122 	if (i2c_master_send(data->client, data->buf, 3) != 3)
123 		return -EIO;
124 
125 	return 0;
126 }
127 
128 static const char *const dac5571_powerdown_modes[] = {
129 	"1kohm_to_gnd", "100kohm_to_gnd", "three_state",
130 };
131 
132 static int dac5571_get_powerdown_mode(struct iio_dev *indio_dev,
133 				      const struct iio_chan_spec *chan)
134 {
135 	struct dac5571_data *data = iio_priv(indio_dev);
136 
137 	return data->powerdown_mode;
138 }
139 
140 static int dac5571_set_powerdown_mode(struct iio_dev *indio_dev,
141 				      const struct iio_chan_spec *chan,
142 				      unsigned int mode)
143 {
144 	struct dac5571_data *data = iio_priv(indio_dev);
145 	int ret = 0;
146 
147 	if (data->powerdown_mode == mode)
148 		return 0;
149 
150 	mutex_lock(&data->lock);
151 	if (data->powerdown) {
152 		ret = data->dac5571_pwrdwn(data, chan->channel,
153 					   DAC5571_POWERDOWN(mode));
154 		if (ret)
155 			goto out;
156 	}
157 	data->powerdown_mode = mode;
158 
159  out:
160 	mutex_unlock(&data->lock);
161 
162 	return ret;
163 }
164 
165 static const struct iio_enum dac5571_powerdown_mode = {
166 	.items = dac5571_powerdown_modes,
167 	.num_items = ARRAY_SIZE(dac5571_powerdown_modes),
168 	.get = dac5571_get_powerdown_mode,
169 	.set = dac5571_set_powerdown_mode,
170 };
171 
172 static ssize_t dac5571_read_powerdown(struct iio_dev *indio_dev,
173 				      uintptr_t private,
174 				      const struct iio_chan_spec *chan,
175 				      char *buf)
176 {
177 	struct dac5571_data *data = iio_priv(indio_dev);
178 
179 	return sprintf(buf, "%d\n", data->powerdown);
180 }
181 
182 static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev,
183 				       uintptr_t private,
184 				       const struct iio_chan_spec *chan,
185 				       const char *buf, size_t len)
186 {
187 	struct dac5571_data *data = iio_priv(indio_dev);
188 	bool powerdown;
189 	int ret;
190 
191 	ret = strtobool(buf, &powerdown);
192 	if (ret)
193 		return ret;
194 
195 	if (data->powerdown == powerdown)
196 		return len;
197 
198 	mutex_lock(&data->lock);
199 	if (powerdown)
200 		ret = data->dac5571_pwrdwn(data, chan->channel,
201 			    DAC5571_POWERDOWN(data->powerdown_mode));
202 	else
203 		ret = data->dac5571_cmd(data, chan->channel, data->val[0]);
204 	if (ret)
205 		goto out;
206 
207 	data->powerdown = powerdown;
208 
209  out:
210 	mutex_unlock(&data->lock);
211 
212 	return ret ? ret : len;
213 }
214 
215 
216 static const struct iio_chan_spec_ext_info dac5571_ext_info[] = {
217 	{
218 		.name	   = "powerdown",
219 		.read	   = dac5571_read_powerdown,
220 		.write	   = dac5571_write_powerdown,
221 		.shared	   = IIO_SHARED_BY_TYPE,
222 	},
223 	IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &dac5571_powerdown_mode),
224 	IIO_ENUM_AVAILABLE("powerdown_mode", &dac5571_powerdown_mode),
225 	{},
226 };
227 
228 #define dac5571_CHANNEL(chan, name) {				\
229 	.type = IIO_VOLTAGE,					\
230 	.channel = (chan),					\
231 	.address = (chan),					\
232 	.indexed = true,					\
233 	.output = true,						\
234 	.datasheet_name = name,					\
235 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
236 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
237 	.ext_info = dac5571_ext_info,				\
238 }
239 
240 static const struct iio_chan_spec dac5571_channels[] = {
241 	dac5571_CHANNEL(0, "A"),
242 	dac5571_CHANNEL(1, "B"),
243 	dac5571_CHANNEL(2, "C"),
244 	dac5571_CHANNEL(3, "D"),
245 };
246 
247 static int dac5571_read_raw(struct iio_dev *indio_dev,
248 			    struct iio_chan_spec const *chan,
249 			    int *val, int *val2, long mask)
250 {
251 	struct dac5571_data *data = iio_priv(indio_dev);
252 	int ret;
253 
254 	switch (mask) {
255 	case IIO_CHAN_INFO_RAW:
256 		*val = data->val[chan->channel];
257 		return IIO_VAL_INT;
258 
259 	case IIO_CHAN_INFO_SCALE:
260 		ret = regulator_get_voltage(data->vref);
261 		if (ret < 0)
262 			return ret;
263 
264 		*val = ret / 1000;
265 		*val2 = data->spec->resolution;
266 		return IIO_VAL_FRACTIONAL_LOG2;
267 
268 	default:
269 		return -EINVAL;
270 	}
271 }
272 
273 static int dac5571_write_raw(struct iio_dev *indio_dev,
274 			     struct iio_chan_spec const *chan,
275 			     int val, int val2, long mask)
276 {
277 	struct dac5571_data *data = iio_priv(indio_dev);
278 	int ret;
279 
280 	switch (mask) {
281 	case IIO_CHAN_INFO_RAW:
282 		if (data->val[chan->channel] == val)
283 			return 0;
284 
285 		if (val >= (1 << data->spec->resolution) || val < 0)
286 			return -EINVAL;
287 
288 		if (data->powerdown)
289 			return -EBUSY;
290 
291 		mutex_lock(&data->lock);
292 		ret = data->dac5571_cmd(data, chan->channel, val);
293 		if (ret == 0)
294 			data->val[chan->channel] = val;
295 		mutex_unlock(&data->lock);
296 		return ret;
297 
298 	default:
299 		return -EINVAL;
300 	}
301 }
302 
303 static int dac5571_write_raw_get_fmt(struct iio_dev *indio_dev,
304 				     struct iio_chan_spec const *chan,
305 				     long mask)
306 {
307 	return IIO_VAL_INT;
308 }
309 
310 static const struct iio_info dac5571_info = {
311 	.read_raw = dac5571_read_raw,
312 	.write_raw = dac5571_write_raw,
313 	.write_raw_get_fmt = dac5571_write_raw_get_fmt,
314 };
315 
316 static int dac5571_probe(struct i2c_client *client,
317 			 const struct i2c_device_id *id)
318 {
319 	struct device *dev = &client->dev;
320 	const struct dac5571_spec *spec;
321 	struct dac5571_data *data;
322 	struct iio_dev *indio_dev;
323 	int ret, i;
324 
325 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
326 	if (!indio_dev)
327 		return -ENOMEM;
328 
329 	data = iio_priv(indio_dev);
330 	i2c_set_clientdata(client, indio_dev);
331 	data->client = client;
332 
333 	indio_dev->dev.parent = dev;
334 	indio_dev->dev.of_node = client->dev.of_node;
335 	indio_dev->info = &dac5571_info;
336 	indio_dev->name = id->name;
337 	indio_dev->modes = INDIO_DIRECT_MODE;
338 	indio_dev->channels = dac5571_channels;
339 
340 	spec = &dac5571_spec[id->driver_data];
341 	indio_dev->num_channels = spec->num_channels;
342 	data->spec = spec;
343 
344 	data->vref = devm_regulator_get(dev, "vref");
345 	if (IS_ERR(data->vref))
346 		return PTR_ERR(data->vref);
347 
348 	ret = regulator_enable(data->vref);
349 	if (ret < 0)
350 		return ret;
351 
352 	mutex_init(&data->lock);
353 
354 	switch (spec->num_channels) {
355 	case 1:
356 		data->dac5571_cmd = dac5571_cmd_single;
357 		data->dac5571_pwrdwn = dac5571_pwrdwn_single;
358 		break;
359 	case 4:
360 		data->dac5571_cmd = dac5571_cmd_quad;
361 		data->dac5571_pwrdwn = dac5571_pwrdwn_quad;
362 		break;
363 	default:
364 		goto err;
365 	}
366 
367 	for (i = 0; i < spec->num_channels; i++) {
368 		ret = data->dac5571_cmd(data, i, 0);
369 		if (ret) {
370 			dev_err(dev, "failed to initialize channel %d to 0\n", i);
371 			goto err;
372 		}
373 	}
374 
375 	ret = iio_device_register(indio_dev);
376 	if (ret)
377 		goto err;
378 
379 	return 0;
380 
381  err:
382 	regulator_disable(data->vref);
383 	return ret;
384 }
385 
386 static int dac5571_remove(struct i2c_client *i2c)
387 {
388 	struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
389 	struct dac5571_data *data = iio_priv(indio_dev);
390 
391 	iio_device_unregister(indio_dev);
392 	regulator_disable(data->vref);
393 
394 	return 0;
395 }
396 
397 #ifdef CONFIG_OF
398 static const struct of_device_id dac5571_of_id[] = {
399 	{.compatible = "ti,dac5571"},
400 	{.compatible = "ti,dac6571"},
401 	{.compatible = "ti,dac7571"},
402 	{.compatible = "ti,dac5574"},
403 	{.compatible = "ti,dac6574"},
404 	{.compatible = "ti,dac7574"},
405 	{.compatible = "ti,dac5573"},
406 	{.compatible = "ti,dac6573"},
407 	{.compatible = "ti,dac7573"},
408 	{}
409 };
410 MODULE_DEVICE_TABLE(of, dac5571_of_id);
411 #endif
412 
413 static const struct i2c_device_id dac5571_id[] = {
414 	{"dac5571", single_8bit},
415 	{"dac6571", single_10bit},
416 	{"dac7571", single_12bit},
417 	{"dac5574", quad_8bit},
418 	{"dac6574", quad_10bit},
419 	{"dac7574", quad_12bit},
420 	{"dac5573", quad_8bit},
421 	{"dac6573", quad_10bit},
422 	{"dac7573", quad_12bit},
423 	{}
424 };
425 MODULE_DEVICE_TABLE(i2c, dac5571_id);
426 
427 static struct i2c_driver dac5571_driver = {
428 	.driver = {
429 		   .name = "ti-dac5571",
430 	},
431 	.probe	  = dac5571_probe,
432 	.remove   = dac5571_remove,
433 	.id_table = dac5571_id,
434 };
435 module_i2c_driver(dac5571_driver);
436 
437 MODULE_AUTHOR("Sean Nyekjaer <sean.nyekjaer@prevas.dk>");
438 MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 1/4-channel DAC driver");
439 MODULE_LICENSE("GPL v2");
440