GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / iio / dac / ds4424.c
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, 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         data->vcc_reg = devm_regulator_get(&client->dev, "vcc");
240         if (IS_ERR(data->vcc_reg)) {
241                 dev_err(&client->dev,
242                         "Failed to get vcc-supply regulator. err: %ld\n",
243                                 PTR_ERR(data->vcc_reg));
244                 return PTR_ERR(data->vcc_reg);
245         }
246
247         mutex_init(&data->lock);
248         ret = regulator_enable(data->vcc_reg);
249         if (ret < 0) {
250                 dev_err(&client->dev,
251                                 "Unable to enable the regulator.\n");
252                 return ret;
253         }
254
255         usleep_range(1000, 1200);
256         ret = ds4424_verify_chip(indio_dev);
257         if (ret < 0)
258                 goto fail;
259
260         switch (id->driver_data) {
261         case ID_DS4422:
262                 indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
263                 break;
264         case ID_DS4424:
265                 indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
266                 break;
267         default:
268                 dev_err(&client->dev,
269                                 "ds4424: Invalid chip id.\n");
270                 ret = -ENXIO;
271                 goto fail;
272         }
273
274         indio_dev->channels = ds4424_channels;
275         indio_dev->modes = INDIO_DIRECT_MODE;
276         indio_dev->info = &ds4424_info;
277
278         ret = iio_device_register(indio_dev);
279         if (ret < 0) {
280                 dev_err(&client->dev,
281                                 "iio_device_register failed. ret: %d\n", ret);
282                 goto fail;
283         }
284
285         return ret;
286
287 fail:
288         regulator_disable(data->vcc_reg);
289         return ret;
290 }
291
292 static int ds4424_remove(struct i2c_client *client)
293 {
294         struct iio_dev *indio_dev = i2c_get_clientdata(client);
295         struct ds4424_data *data = iio_priv(indio_dev);
296
297         iio_device_unregister(indio_dev);
298         regulator_disable(data->vcc_reg);
299
300         return 0;
301 }
302
303 static const struct i2c_device_id ds4424_id[] = {
304         { "ds4422", ID_DS4422 },
305         { "ds4424", ID_DS4424 },
306         { }
307 };
308
309 MODULE_DEVICE_TABLE(i2c, ds4424_id);
310
311 static const struct of_device_id ds4424_of_match[] = {
312         { .compatible = "maxim,ds4422" },
313         { .compatible = "maxim,ds4424" },
314         { },
315 };
316
317 MODULE_DEVICE_TABLE(of, ds4424_of_match);
318
319 static struct i2c_driver ds4424_driver = {
320         .driver = {
321                 .name   = "ds4424",
322                 .of_match_table = ds4424_of_match,
323                 .pm     = &ds4424_pm_ops,
324         },
325         .probe          = ds4424_probe,
326         .remove         = ds4424_remove,
327         .id_table       = ds4424_id,
328 };
329 module_i2c_driver(ds4424_driver);
330
331 MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
332 MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
333 MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
334 MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
335 MODULE_LICENSE("GPL v2");