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(client: data->client, DS4424_DAC_ADDR(channel));
78 if (ret < 0)
79 goto fail;
80
81 *val = ret;
82
83fail:
84 mutex_unlock(lock: &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(client: data->client,
96 DS4424_DAC_ADDR(chan->channel), value: val);
97 if (ret < 0)
98 goto fail;
99
100 data->raw[chan->channel] = val;
101
102fail:
103 mutex_unlock(lock: &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, channel: 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, val: 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: &val, channel: 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, val: 0,
185 chan: &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, val: data->save[i],
202 chan: &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(parent: &client->dev, sizeof_priv: 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, data: indio_dev);
231 data->client = client;
232 indio_dev->name = id->name;
233
234 data->vcc_reg = devm_regulator_get(dev: &client->dev, id: "vcc");
235 if (IS_ERR(ptr: data->vcc_reg))
236 return dev_err_probe(dev: &client->dev, err: PTR_ERR(ptr: data->vcc_reg),
237 fmt: "Failed to get vcc-supply regulator.\n");
238
239 mutex_init(&data->lock);
240 ret = regulator_enable(regulator: 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(min: 1000, max: 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(regulator: 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(regulator: 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

source code of linux/drivers/iio/dac/ds4424.c