Linux-libre 5.4.39-gnu
[librecmc/linux-libre.git] / drivers / iio / dac / ds4424.c
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  */
42 union ds4424_raw_data {
43         struct {
44                 u8 dx:7;
45                 u8 source_bit:1;
46         };
47         u8 bits;
48 };
49
50 enum ds4424_device_ids {
51         ID_DS4422,
52         ID_DS4424,
53 };
54
55 struct 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
63 static 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
70 static 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
83 fail:
84         mutex_unlock(&data->lock);
85         return ret;
86 }
87
88 static 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
102 fail:
103         mutex_unlock(&data->lock);
104         return ret;
105 }
106
107 static 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
133 static 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
162 static 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
174 static int __maybe_unused 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
192 static int __maybe_unused 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
209 static SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);
210
211 static const struct iio_info ds4424_info = {
212         .read_raw = ds4424_read_raw,
213         .write_raw = ds4424_write_raw,
214 };
215
216 static int ds4424_probe(struct i2c_client *client,
217                         const struct i2c_device_id *id)
218 {
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         indio_dev->dev.of_node = client->dev.of_node;
234         indio_dev->dev.parent = &client->dev;
235
236         data->vcc_reg = devm_regulator_get(&client->dev, "vcc");
237         if (IS_ERR(data->vcc_reg)) {
238                 dev_err(&client->dev,
239                         "Failed to get vcc-supply regulator. err: %ld\n",
240                                 PTR_ERR(data->vcc_reg));
241                 return PTR_ERR(data->vcc_reg);
242         }
243
244         mutex_init(&data->lock);
245         ret = regulator_enable(data->vcc_reg);
246         if (ret < 0) {
247                 dev_err(&client->dev,
248                                 "Unable to enable the regulator.\n");
249                 return ret;
250         }
251
252         usleep_range(1000, 1200);
253         ret = ds4424_verify_chip(indio_dev);
254         if (ret < 0)
255                 goto fail;
256
257         switch (id->driver_data) {
258         case ID_DS4422:
259                 indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
260                 break;
261         case ID_DS4424:
262                 indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
263                 break;
264         default:
265                 dev_err(&client->dev,
266                                 "ds4424: Invalid chip id.\n");
267                 ret = -ENXIO;
268                 goto fail;
269         }
270
271         indio_dev->channels = ds4424_channels;
272         indio_dev->modes = INDIO_DIRECT_MODE;
273         indio_dev->info = &ds4424_info;
274
275         ret = iio_device_register(indio_dev);
276         if (ret < 0) {
277                 dev_err(&client->dev,
278                                 "iio_device_register failed. ret: %d\n", ret);
279                 goto fail;
280         }
281
282         return ret;
283
284 fail:
285         regulator_disable(data->vcc_reg);
286         return ret;
287 }
288
289 static int ds4424_remove(struct i2c_client *client)
290 {
291         struct iio_dev *indio_dev = i2c_get_clientdata(client);
292         struct ds4424_data *data = iio_priv(indio_dev);
293
294         iio_device_unregister(indio_dev);
295         regulator_disable(data->vcc_reg);
296
297         return 0;
298 }
299
300 static const struct i2c_device_id ds4424_id[] = {
301         { "ds4422", ID_DS4422 },
302         { "ds4424", ID_DS4424 },
303         { }
304 };
305
306 MODULE_DEVICE_TABLE(i2c, ds4424_id);
307
308 static const struct of_device_id ds4424_of_match[] = {
309         { .compatible = "maxim,ds4422" },
310         { .compatible = "maxim,ds4424" },
311         { },
312 };
313
314 MODULE_DEVICE_TABLE(of, ds4424_of_match);
315
316 static struct i2c_driver ds4424_driver = {
317         .driver = {
318                 .name   = "ds4424",
319                 .of_match_table = ds4424_of_match,
320                 .pm     = &ds4424_pm_ops,
321         },
322         .probe          = ds4424_probe,
323         .remove         = ds4424_remove,
324         .id_table       = ds4424_id,
325 };
326 module_i2c_driver(ds4424_driver);
327
328 MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
329 MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
330 MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
331 MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
332 MODULE_LICENSE("GPL v2");