3 * 7-bit, Multi-Channel Sink/Source Current DAC Driver
4 * Copyright (C) 2017 Maxim Integrated
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.
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>
22 #define DS4422_MAX_DAC_CHANNELS 2
23 #define DS4424_MAX_DAC_CHANNELS 4
25 #define DS4424_DAC_ADDR(chan) ((chan) + 0xf8)
26 #define DS4424_SOURCE_I 1
27 #define DS4424_SINK_I 0
29 #define DS4424_CHANNEL(chan) { \
30 .type = IIO_CURRENT, \
34 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
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.
45 union ds4424_raw_data
{
53 enum ds4424_device_ids
{
59 struct i2c_client
*client
;
61 uint8_t save
[DS4424_MAX_DAC_CHANNELS
];
62 struct regulator
*vcc_reg
;
63 uint8_t raw
[DS4424_MAX_DAC_CHANNELS
];
66 static const struct iio_chan_spec ds4424_channels
[] = {
73 static int ds4424_get_value(struct iio_dev
*indio_dev
,
74 int *val
, int channel
)
76 struct ds4424_data
*data
= iio_priv(indio_dev
);
79 mutex_lock(&data
->lock
);
80 ret
= i2c_smbus_read_byte_data(data
->client
, DS4424_DAC_ADDR(channel
));
87 mutex_unlock(&data
->lock
);
91 static int ds4424_set_value(struct iio_dev
*indio_dev
,
92 int val
, struct iio_chan_spec
const *chan
)
94 struct ds4424_data
*data
= iio_priv(indio_dev
);
97 mutex_lock(&data
->lock
);
98 ret
= i2c_smbus_write_byte_data(data
->client
,
99 DS4424_DAC_ADDR(chan
->channel
), val
);
103 data
->raw
[chan
->channel
] = val
;
106 mutex_unlock(&data
->lock
);
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
)
114 union ds4424_raw_data raw
;
118 case IIO_CHAN_INFO_RAW
:
119 ret
= ds4424_get_value(indio_dev
, val
, chan
->channel
);
121 pr_err("%s : ds4424_get_value returned %d\n",
127 if (raw
.source_bit
== DS4424_SINK_I
)
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
)
140 union ds4424_raw_data raw
;
146 case IIO_CHAN_INFO_RAW
:
147 if (val
< S8_MIN
|| val
> S8_MAX
)
151 raw
.source_bit
= DS4424_SOURCE_I
;
154 raw
.source_bit
= DS4424_SINK_I
;
158 return ds4424_set_value(indio_dev
, raw
.bits
, chan
);
165 static int ds4424_verify_chip(struct iio_dev
*indio_dev
)
169 ret
= ds4424_get_value(indio_dev
, &val
, DS4424_DAC_ADDR(0));
171 dev_err(&indio_dev
->dev
,
172 "%s failed. ret: %d\n", __func__
, ret
);
177 static int __maybe_unused
ds4424_suspend(struct device
*dev
)
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
);
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
]);
195 static int __maybe_unused
ds4424_resume(struct device
*dev
)
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
);
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
]);
212 static SIMPLE_DEV_PM_OPS(ds4424_pm_ops
, ds4424_suspend
, ds4424_resume
);
214 static const struct iio_info ds4424_info
= {
215 .read_raw
= ds4424_read_raw
,
216 .write_raw
= ds4424_write_raw
,
219 static int ds4424_probe(struct i2c_client
*client
,
220 const struct i2c_device_id
*id
)
222 struct ds4424_data
*data
;
223 struct iio_dev
*indio_dev
;
226 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*data
));
228 dev_err(&client
->dev
, "iio dev alloc failed.\n");
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
;
239 if (!client
->dev
.of_node
) {
240 dev_err(&client
->dev
,
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
);
253 mutex_init(&data
->lock
);
254 ret
= regulator_enable(data
->vcc_reg
);
256 dev_err(&client
->dev
,
257 "Unable to enable the regulator.\n");
261 usleep_range(1000, 1200);
262 ret
= ds4424_verify_chip(indio_dev
);
266 switch (id
->driver_data
) {
268 indio_dev
->num_channels
= DS4422_MAX_DAC_CHANNELS
;
271 indio_dev
->num_channels
= DS4424_MAX_DAC_CHANNELS
;
274 dev_err(&client
->dev
,
275 "ds4424: Invalid chip id.\n");
280 indio_dev
->channels
= ds4424_channels
;
281 indio_dev
->modes
= INDIO_DIRECT_MODE
;
282 indio_dev
->info
= &ds4424_info
;
284 ret
= iio_device_register(indio_dev
);
286 dev_err(&client
->dev
,
287 "iio_device_register failed. ret: %d\n", ret
);
294 regulator_disable(data
->vcc_reg
);
298 static int ds4424_remove(struct i2c_client
*client
)
300 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
301 struct ds4424_data
*data
= iio_priv(indio_dev
);
303 iio_device_unregister(indio_dev
);
304 regulator_disable(data
->vcc_reg
);
309 static const struct i2c_device_id ds4424_id
[] = {
310 { "ds4422", ID_DS4422
},
311 { "ds4424", ID_DS4424
},
315 MODULE_DEVICE_TABLE(i2c
, ds4424_id
);
317 static const struct of_device_id ds4424_of_match
[] = {
318 { .compatible
= "maxim,ds4422" },
319 { .compatible
= "maxim,ds4424" },
323 MODULE_DEVICE_TABLE(of
, ds4424_of_match
);
325 static struct i2c_driver ds4424_driver
= {
328 .of_match_table
= ds4424_of_match
,
329 .pm
= &ds4424_pm_ops
,
331 .probe
= ds4424_probe
,
332 .remove
= ds4424_remove
,
333 .id_table
= ds4424_id
,
335 module_i2c_driver(ds4424_driver
);
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");