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