1 /*
2  * iio/dac/max5821.c
3  * Copyright (C) 2014 Philippe Reynes
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/i2c.h>
13#include <linux/iio/iio.h>
14#include <linux/regulator/consumer.h>
15
16#define MAX5821_MAX_DAC_CHANNELS		2
17
18/* command bytes */
19#define MAX5821_LOAD_DAC_A_IN_REG_B		0x00
20#define MAX5821_LOAD_DAC_B_IN_REG_A		0x10
21#define MAX5821_EXTENDED_COMMAND_MODE		0xf0
22#define MAX5821_READ_DAC_A_COMMAND		0xf1
23#define MAX5821_READ_DAC_B_COMMAND		0xf2
24
25#define MAX5821_EXTENDED_POWER_UP		0x00
26#define MAX5821_EXTENDED_POWER_DOWN_MODE0	0x01
27#define MAX5821_EXTENDED_POWER_DOWN_MODE1	0x02
28#define MAX5821_EXTENDED_POWER_DOWN_MODE2	0x03
29#define MAX5821_EXTENDED_DAC_A			0x04
30#define MAX5821_EXTENDED_DAC_B			0x08
31
32enum max5821_device_ids {
33	ID_MAX5821,
34};
35
36struct max5821_data {
37	struct i2c_client	*client;
38	struct regulator	*vref_reg;
39	unsigned short		vref_mv;
40	bool			powerdown[MAX5821_MAX_DAC_CHANNELS];
41	u8			powerdown_mode[MAX5821_MAX_DAC_CHANNELS];
42	struct mutex		lock;
43};
44
45static const char * const max5821_powerdown_modes[] = {
46	"three_state",
47	"1kohm_to_gnd",
48	"100kohm_to_gnd",
49};
50
51enum {
52	MAX5821_THREE_STATE,
53	MAX5821_1KOHM_TO_GND,
54	MAX5821_100KOHM_TO_GND
55};
56
57static int max5821_get_powerdown_mode(struct iio_dev *indio_dev,
58				      const struct iio_chan_spec *chan)
59{
60	struct max5821_data *st = iio_priv(indio_dev);
61
62	return st->powerdown_mode[chan->channel];
63}
64
65static int max5821_set_powerdown_mode(struct iio_dev *indio_dev,
66				      const struct iio_chan_spec *chan,
67				      unsigned int mode)
68{
69	struct max5821_data *st = iio_priv(indio_dev);
70
71	st->powerdown_mode[chan->channel] = mode;
72
73	return 0;
74}
75
76static const struct iio_enum max5821_powerdown_mode_enum = {
77	.items = max5821_powerdown_modes,
78	.num_items = ARRAY_SIZE(max5821_powerdown_modes),
79	.get = max5821_get_powerdown_mode,
80	.set = max5821_set_powerdown_mode,
81};
82
83static ssize_t max5821_read_dac_powerdown(struct iio_dev *indio_dev,
84					  uintptr_t private,
85					  const struct iio_chan_spec *chan,
86					  char *buf)
87{
88	struct max5821_data *st = iio_priv(indio_dev);
89
90	return sprintf(buf, "%d\n", st->powerdown[chan->channel]);
91}
92
93static int max5821_sync_powerdown_mode(struct max5821_data *data,
94				       const struct iio_chan_spec *chan)
95{
96	u8 outbuf[2];
97
98	outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE;
99
100	if (chan->channel == 0)
101		outbuf[1] = MAX5821_EXTENDED_DAC_A;
102	else
103		outbuf[1] = MAX5821_EXTENDED_DAC_B;
104
105	if (data->powerdown[chan->channel])
106		outbuf[1] |= data->powerdown_mode[chan->channel] + 1;
107	else
108		outbuf[1] |= MAX5821_EXTENDED_POWER_UP;
109
110	return i2c_master_send(data->client, outbuf, 2);
111}
112
113static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev,
114					   uintptr_t private,
115					   const struct iio_chan_spec *chan,
116					   const char *buf, size_t len)
117{
118	struct max5821_data *data = iio_priv(indio_dev);
119	bool powerdown;
120	int ret;
121
122	ret = strtobool(buf, &powerdown);
123	if (ret)
124		return ret;
125
126	data->powerdown[chan->channel] = powerdown;
127
128	ret = max5821_sync_powerdown_mode(data, chan);
129	if (ret < 0)
130		return ret;
131
132	return len;
133}
134
135static const struct iio_chan_spec_ext_info max5821_ext_info[] = {
136	{
137		.name = "powerdown",
138		.read = max5821_read_dac_powerdown,
139		.write = max5821_write_dac_powerdown,
140		.shared = IIO_SEPARATE,
141	},
142	IIO_ENUM("powerdown_mode", IIO_SEPARATE, &max5821_powerdown_mode_enum),
143	IIO_ENUM_AVAILABLE("powerdown_mode", &max5821_powerdown_mode_enum),
144	{ },
145};
146
147#define MAX5821_CHANNEL(chan) {					\
148	.type = IIO_VOLTAGE,					\
149	.indexed = 1,						\
150	.output = 1,						\
151	.channel = (chan),					\
152	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
153	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE),	\
154	.ext_info = max5821_ext_info,				\
155}
156
157static const struct iio_chan_spec max5821_channels[] = {
158	MAX5821_CHANNEL(0),
159	MAX5821_CHANNEL(1)
160};
161
162static const u8 max5821_read_dac_command[] = {
163	MAX5821_READ_DAC_A_COMMAND,
164	MAX5821_READ_DAC_B_COMMAND
165};
166
167static const u8 max5821_load_dac_command[] = {
168	MAX5821_LOAD_DAC_A_IN_REG_B,
169	MAX5821_LOAD_DAC_B_IN_REG_A
170};
171
172static int max5821_get_value(struct iio_dev *indio_dev,
173			     int *val, int channel)
174{
175	struct max5821_data *data = iio_priv(indio_dev);
176	struct i2c_client *client = data->client;
177	u8 outbuf[1];
178	u8 inbuf[2];
179	int ret;
180
181	if ((channel != 0) && (channel != 1))
182		return -EINVAL;
183
184	outbuf[0] = max5821_read_dac_command[channel];
185
186	mutex_lock(&data->lock);
187
188	ret = i2c_master_send(client, outbuf, 1);
189	if (ret < 0) {
190		mutex_unlock(&data->lock);
191		return ret;
192	} else if (ret != 1) {
193		mutex_unlock(&data->lock);
194		return -EIO;
195	}
196
197	ret = i2c_master_recv(client, inbuf, 2);
198	if (ret < 0) {
199		mutex_unlock(&data->lock);
200		return ret;
201	} else if (ret != 2) {
202		mutex_unlock(&data->lock);
203		return -EIO;
204	}
205
206	mutex_unlock(&data->lock);
207
208	*val = ((inbuf[0] & 0x0f) << 6) | (inbuf[1] >> 2);
209
210	return IIO_VAL_INT;
211}
212
213static int max5821_set_value(struct iio_dev *indio_dev,
214			     int val, int channel)
215{
216	struct max5821_data *data = iio_priv(indio_dev);
217	struct i2c_client *client = data->client;
218	u8 outbuf[2];
219	int ret;
220
221	if ((val < 0) || (val > 1023))
222		return -EINVAL;
223
224	if ((channel != 0) && (channel != 1))
225		return -EINVAL;
226
227	outbuf[0] = max5821_load_dac_command[channel];
228	outbuf[0] |= val >> 6;
229	outbuf[1] = (val & 0x3f) << 2;
230
231	ret = i2c_master_send(client, outbuf, 2);
232	if (ret < 0)
233		return ret;
234	else if (ret != 2)
235		return -EIO;
236	else
237		return 0;
238}
239
240static int max5821_read_raw(struct iio_dev *indio_dev,
241			   struct iio_chan_spec const *chan,
242			   int *val, int *val2, long mask)
243{
244	struct max5821_data *data = iio_priv(indio_dev);
245
246	switch (mask) {
247	case IIO_CHAN_INFO_RAW:
248		return max5821_get_value(indio_dev, val, chan->channel);
249	case IIO_CHAN_INFO_SCALE:
250		*val = data->vref_mv;
251		*val2 = 10;
252		return IIO_VAL_FRACTIONAL_LOG2;
253	default:
254		return -EINVAL;
255	}
256}
257
258static int max5821_write_raw(struct iio_dev *indio_dev,
259			     struct iio_chan_spec const *chan,
260			     int val, int val2, long mask)
261{
262	if (val2 != 0)
263		return -EINVAL;
264
265	switch (mask) {
266	case IIO_CHAN_INFO_RAW:
267		return max5821_set_value(indio_dev, val, chan->channel);
268	default:
269		return -EINVAL;
270	}
271}
272
273#ifdef CONFIG_PM_SLEEP
274static int max5821_suspend(struct device *dev)
275{
276	u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE,
277			 MAX5821_EXTENDED_DAC_A |
278			 MAX5821_EXTENDED_DAC_B |
279			 MAX5821_EXTENDED_POWER_DOWN_MODE2 };
280
281	return i2c_master_send(to_i2c_client(dev), outbuf, 2);
282}
283
284static int max5821_resume(struct device *dev)
285{
286	u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE,
287			 MAX5821_EXTENDED_DAC_A |
288			 MAX5821_EXTENDED_DAC_B |
289			 MAX5821_EXTENDED_POWER_UP };
290
291	return i2c_master_send(to_i2c_client(dev), outbuf, 2);
292}
293
294static SIMPLE_DEV_PM_OPS(max5821_pm_ops, max5821_suspend, max5821_resume);
295#define MAX5821_PM_OPS (&max5821_pm_ops)
296#else
297#define MAX5821_PM_OPS NULL
298#endif /* CONFIG_PM_SLEEP */
299
300static const struct iio_info max5821_info = {
301	.read_raw = max5821_read_raw,
302	.write_raw = max5821_write_raw,
303	.driver_module = THIS_MODULE,
304};
305
306static int max5821_probe(struct i2c_client *client,
307			const struct i2c_device_id *id)
308{
309	struct max5821_data *data;
310	struct iio_dev *indio_dev;
311	u32 tmp;
312	int ret;
313
314	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
315	if (!indio_dev)
316		return -ENOMEM;
317	data = iio_priv(indio_dev);
318	i2c_set_clientdata(client, indio_dev);
319	data->client = client;
320	mutex_init(&data->lock);
321
322	/* max5821 start in powerdown mode 100Kohm to ground */
323	for (tmp = 0; tmp < MAX5821_MAX_DAC_CHANNELS; tmp++) {
324		data->powerdown[tmp] = true;
325		data->powerdown_mode[tmp] = MAX5821_100KOHM_TO_GND;
326	}
327
328	data->vref_reg = devm_regulator_get(&client->dev, "vref");
329	if (IS_ERR(data->vref_reg)) {
330		ret = PTR_ERR(data->vref_reg);
331		dev_err(&client->dev,
332			"Failed to get vref regulator: %d\n", ret);
333		goto error_free_reg;
334	}
335
336	ret = regulator_enable(data->vref_reg);
337	if (ret) {
338		dev_err(&client->dev,
339			"Failed to enable vref regulator: %d\n", ret);
340		goto error_free_reg;
341	}
342
343	ret = regulator_get_voltage(data->vref_reg);
344	if (ret < 0) {
345		dev_err(&client->dev,
346			"Failed to get voltage on regulator: %d\n", ret);
347		goto error_disable_reg;
348	}
349
350	data->vref_mv = ret / 1000;
351
352	indio_dev->name = id->name;
353	indio_dev->dev.parent = &client->dev;
354	indio_dev->num_channels = ARRAY_SIZE(max5821_channels);
355	indio_dev->channels = max5821_channels;
356	indio_dev->modes = INDIO_DIRECT_MODE;
357	indio_dev->info = &max5821_info;
358
359	return iio_device_register(indio_dev);
360
361error_disable_reg:
362	regulator_disable(data->vref_reg);
363
364error_free_reg:
365
366	return ret;
367}
368
369static int max5821_remove(struct i2c_client *client)
370{
371	struct iio_dev *indio_dev = i2c_get_clientdata(client);
372	struct max5821_data *data = iio_priv(indio_dev);
373
374	iio_device_unregister(indio_dev);
375	regulator_disable(data->vref_reg);
376
377	return 0;
378}
379
380static const struct i2c_device_id max5821_id[] = {
381	{ "max5821", ID_MAX5821 },
382	{ }
383};
384MODULE_DEVICE_TABLE(i2c, max5821_id);
385
386static const struct of_device_id max5821_of_match[] = {
387	{ .compatible = "maxim,max5821" },
388	{ }
389};
390
391static struct i2c_driver max5821_driver = {
392	.driver = {
393		.name	= "max5821",
394		.pm     = MAX5821_PM_OPS,
395		.owner	= THIS_MODULE,
396	},
397	.probe		= max5821_probe,
398	.remove		= max5821_remove,
399	.id_table	= max5821_id,
400};
401module_i2c_driver(max5821_driver);
402
403MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>");
404MODULE_DESCRIPTION("MAX5821 DAC");
405MODULE_LICENSE("GPL v2");
406