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