1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Maxim Integrated
4 * 7-bit, Multi-Channel Sink/Source Current DAC Driver
5 * Copyright (C) 2017 Maxim Integrated
6 */
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/i2c.h>
11#include <linux/regulator/consumer.h>
12#include <linux/err.h>
13#include <linux/delay.h>
14#include <linux/iio/iio.h>
15#include <linux/iio/driver.h>
16#include <linux/iio/machine.h>
17#include <linux/iio/consumer.h>
18
19#define DS4422_MAX_DAC_CHANNELS		2
20#define DS4424_MAX_DAC_CHANNELS		4
21
22#define DS4424_DAC_ADDR(chan)   ((chan) + 0xf8)
23#define DS4424_SOURCE_I		1
24#define DS4424_SINK_I		0
25
26#define DS4424_CHANNEL(chan) { \
27	.type = IIO_CURRENT, \
28	.indexed = 1, \
29	.output = 1, \
30	.channel = chan, \
31	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
32}
33
34/*
35 * DS4424 DAC control register 8 bits
36 * [7]		0: to sink; 1: to source
37 * [6:0]	steps to sink/source
38 * bit[7] looks like a sign bit, but the value of the register is
39 * not a two's complement code considering the bit[6:0] is a absolute
40 * distance from the zero point.
41 */
42union ds4424_raw_data {
43	struct {
44		u8 dx:7;
45		u8 source_bit:1;
46	};
47	u8 bits;
48};
49
50enum ds4424_device_ids {
51	ID_DS4422,
52	ID_DS4424,
53};
54
55struct ds4424_data {
56	struct i2c_client *client;
57	struct mutex lock;
58	uint8_t save[DS4424_MAX_DAC_CHANNELS];
59	struct regulator *vcc_reg;
60	uint8_t raw[DS4424_MAX_DAC_CHANNELS];
61};
62
63static const struct iio_chan_spec ds4424_channels[] = {
64	DS4424_CHANNEL(0),
65	DS4424_CHANNEL(1),
66	DS4424_CHANNEL(2),
67	DS4424_CHANNEL(3),
68};
69
70static int ds4424_get_value(struct iio_dev *indio_dev,
71			     int *val, int channel)
72{
73	struct ds4424_data *data = iio_priv(indio_dev);
74	int ret;
75
76	mutex_lock(&data->lock);
77	ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel));
78	if (ret < 0)
79		goto fail;
80
81	*val = ret;
82
83fail:
84	mutex_unlock(&data->lock);
85	return ret;
86}
87
88static int ds4424_set_value(struct iio_dev *indio_dev,
89			     int val, struct iio_chan_spec const *chan)
90{
91	struct ds4424_data *data = iio_priv(indio_dev);
92	int ret;
93
94	mutex_lock(&data->lock);
95	ret = i2c_smbus_write_byte_data(data->client,
96			DS4424_DAC_ADDR(chan->channel), val);
97	if (ret < 0)
98		goto fail;
99
100	data->raw[chan->channel] = val;
101
102fail:
103	mutex_unlock(&data->lock);
104	return ret;
105}
106
107static int ds4424_read_raw(struct iio_dev *indio_dev,
108			   struct iio_chan_spec const *chan,
109			   int *val, int *val2, long mask)
110{
111	union ds4424_raw_data raw;
112	int ret;
113
114	switch (mask) {
115	case IIO_CHAN_INFO_RAW:
116		ret = ds4424_get_value(indio_dev, val, chan->channel);
117		if (ret < 0) {
118			pr_err("%s : ds4424_get_value returned %d\n",
119							__func__, ret);
120			return ret;
121		}
122		raw.bits = *val;
123		*val = raw.dx;
124		if (raw.source_bit == DS4424_SINK_I)
125			*val = -*val;
126		return IIO_VAL_INT;
127
128	default:
129		return -EINVAL;
130	}
131}
132
133static int ds4424_write_raw(struct iio_dev *indio_dev,
134			     struct iio_chan_spec const *chan,
135			     int val, int val2, long mask)
136{
137	union ds4424_raw_data raw;
138
139	if (val2 != 0)
140		return -EINVAL;
141
142	switch (mask) {
143	case IIO_CHAN_INFO_RAW:
144		if (val < S8_MIN || val > S8_MAX)
145			return -EINVAL;
146
147		if (val > 0) {
148			raw.source_bit = DS4424_SOURCE_I;
149			raw.dx = val;
150		} else {
151			raw.source_bit = DS4424_SINK_I;
152			raw.dx = -val;
153		}
154
155		return ds4424_set_value(indio_dev, raw.bits, chan);
156
157	default:
158		return -EINVAL;
159	}
160}
161
162static int ds4424_verify_chip(struct iio_dev *indio_dev)
163{
164	int ret, val;
165
166	ret = ds4424_get_value(indio_dev, &val, 0);
167	if (ret < 0)
168		dev_err(&indio_dev->dev,
169				"%s failed. ret: %d\n", __func__, ret);
170
171	return ret;
172}
173
174static int ds4424_suspend(struct device *dev)
175{
176	struct i2c_client *client = to_i2c_client(dev);
177	struct iio_dev *indio_dev = i2c_get_clientdata(client);
178	struct ds4424_data *data = iio_priv(indio_dev);
179	int ret = 0;
180	int i;
181
182	for (i = 0; i < indio_dev->num_channels; i++) {
183		data->save[i] = data->raw[i];
184		ret = ds4424_set_value(indio_dev, 0,
185				&indio_dev->channels[i]);
186		if (ret < 0)
187			return ret;
188	}
189	return ret;
190}
191
192static int ds4424_resume(struct device *dev)
193{
194	struct i2c_client *client = to_i2c_client(dev);
195	struct iio_dev *indio_dev = i2c_get_clientdata(client);
196	struct ds4424_data *data = iio_priv(indio_dev);
197	int ret = 0;
198	int i;
199
200	for (i = 0; i < indio_dev->num_channels; i++) {
201		ret = ds4424_set_value(indio_dev, data->save[i],
202				&indio_dev->channels[i]);
203		if (ret < 0)
204			return ret;
205	}
206	return ret;
207}
208
209static DEFINE_SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);
210
211static const struct iio_info ds4424_info = {
212	.read_raw = ds4424_read_raw,
213	.write_raw = ds4424_write_raw,
214};
215
216static int ds4424_probe(struct i2c_client *client)
217{
218	const struct i2c_device_id *id = i2c_client_get_device_id(client);
219	struct ds4424_data *data;
220	struct iio_dev *indio_dev;
221	int ret;
222
223	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
224	if (!indio_dev) {
225		dev_err(&client->dev, "iio dev alloc failed.\n");
226		return -ENOMEM;
227	}
228
229	data = iio_priv(indio_dev);
230	i2c_set_clientdata(client, indio_dev);
231	data->client = client;
232	indio_dev->name = id->name;
233
234	data->vcc_reg = devm_regulator_get(&client->dev, "vcc");
235	if (IS_ERR(data->vcc_reg))
236		return dev_err_probe(&client->dev, PTR_ERR(data->vcc_reg),
237				     "Failed to get vcc-supply regulator.\n");
238
239	mutex_init(&data->lock);
240	ret = regulator_enable(data->vcc_reg);
241	if (ret < 0) {
242		dev_err(&client->dev,
243				"Unable to enable the regulator.\n");
244		return ret;
245	}
246
247	usleep_range(1000, 1200);
248	ret = ds4424_verify_chip(indio_dev);
249	if (ret < 0)
250		goto fail;
251
252	switch (id->driver_data) {
253	case ID_DS4422:
254		indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
255		break;
256	case ID_DS4424:
257		indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
258		break;
259	default:
260		dev_err(&client->dev,
261				"ds4424: Invalid chip id.\n");
262		ret = -ENXIO;
263		goto fail;
264	}
265
266	indio_dev->channels = ds4424_channels;
267	indio_dev->modes = INDIO_DIRECT_MODE;
268	indio_dev->info = &ds4424_info;
269
270	ret = iio_device_register(indio_dev);
271	if (ret < 0) {
272		dev_err(&client->dev,
273				"iio_device_register failed. ret: %d\n", ret);
274		goto fail;
275	}
276
277	return ret;
278
279fail:
280	regulator_disable(data->vcc_reg);
281	return ret;
282}
283
284static void ds4424_remove(struct i2c_client *client)
285{
286	struct iio_dev *indio_dev = i2c_get_clientdata(client);
287	struct ds4424_data *data = iio_priv(indio_dev);
288
289	iio_device_unregister(indio_dev);
290	regulator_disable(data->vcc_reg);
291}
292
293static const struct i2c_device_id ds4424_id[] = {
294	{ "ds4422", ID_DS4422 },
295	{ "ds4424", ID_DS4424 },
296	{ }
297};
298
299MODULE_DEVICE_TABLE(i2c, ds4424_id);
300
301static const struct of_device_id ds4424_of_match[] = {
302	{ .compatible = "maxim,ds4422" },
303	{ .compatible = "maxim,ds4424" },
304	{ },
305};
306
307MODULE_DEVICE_TABLE(of, ds4424_of_match);
308
309static struct i2c_driver ds4424_driver = {
310	.driver = {
311		.name	= "ds4424",
312		.of_match_table = ds4424_of_match,
313		.pm     = pm_sleep_ptr(&ds4424_pm_ops),
314	},
315	.probe		= ds4424_probe,
316	.remove		= ds4424_remove,
317	.id_table	= ds4424_id,
318};
319module_i2c_driver(ds4424_driver);
320
321MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
322MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
323MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
324MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
325MODULE_LICENSE("GPL v2");
326