1 // SPDX-License-Identifier: GPL-2.0-only
4 * 7-bit, Multi-Channel Sink/Source Current DAC Driver
5 * Copyright (C) 2017 Maxim Integrated
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>
19 #define DS4422_MAX_DAC_CHANNELS 2
20 #define DS4424_MAX_DAC_CHANNELS 4
22 #define DS4424_DAC_ADDR(chan) ((chan) + 0xf8)
23 #define DS4424_SOURCE_I 1
24 #define DS4424_SINK_I 0
26 #define DS4424_CHANNEL(chan) { \
27 .type = IIO_CURRENT, \
31 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
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.
42 union ds4424_raw_data
{
50 enum ds4424_device_ids
{
56 struct i2c_client
*client
;
58 uint8_t save
[DS4424_MAX_DAC_CHANNELS
];
59 struct regulator
*vcc_reg
;
60 uint8_t raw
[DS4424_MAX_DAC_CHANNELS
];
63 static const struct iio_chan_spec ds4424_channels
[] = {
70 static int ds4424_get_value(struct iio_dev
*indio_dev
,
71 int *val
, int channel
)
73 struct ds4424_data
*data
= iio_priv(indio_dev
);
76 mutex_lock(&data
->lock
);
77 ret
= i2c_smbus_read_byte_data(data
->client
, DS4424_DAC_ADDR(channel
));
84 mutex_unlock(&data
->lock
);
88 static int ds4424_set_value(struct iio_dev
*indio_dev
,
89 int val
, struct iio_chan_spec
const *chan
)
91 struct ds4424_data
*data
= iio_priv(indio_dev
);
94 mutex_lock(&data
->lock
);
95 ret
= i2c_smbus_write_byte_data(data
->client
,
96 DS4424_DAC_ADDR(chan
->channel
), val
);
100 data
->raw
[chan
->channel
] = val
;
103 mutex_unlock(&data
->lock
);
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
)
111 union ds4424_raw_data raw
;
115 case IIO_CHAN_INFO_RAW
:
116 ret
= ds4424_get_value(indio_dev
, val
, chan
->channel
);
118 pr_err("%s : ds4424_get_value returned %d\n",
124 if (raw
.source_bit
== DS4424_SINK_I
)
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
)
137 union ds4424_raw_data raw
;
143 case IIO_CHAN_INFO_RAW
:
144 if (val
< S8_MIN
|| val
> S8_MAX
)
148 raw
.source_bit
= DS4424_SOURCE_I
;
151 raw
.source_bit
= DS4424_SINK_I
;
155 return ds4424_set_value(indio_dev
, raw
.bits
, chan
);
162 static int ds4424_verify_chip(struct iio_dev
*indio_dev
)
166 ret
= ds4424_get_value(indio_dev
, &val
, 0);
168 dev_err(&indio_dev
->dev
,
169 "%s failed. ret: %d\n", __func__
, ret
);
174 static int __maybe_unused
ds4424_suspend(struct device
*dev
)
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
);
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
]);
192 static int __maybe_unused
ds4424_resume(struct device
*dev
)
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
);
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
]);
209 static SIMPLE_DEV_PM_OPS(ds4424_pm_ops
, ds4424_suspend
, ds4424_resume
);
211 static const struct iio_info ds4424_info
= {
212 .read_raw
= ds4424_read_raw
,
213 .write_raw
= ds4424_write_raw
,
216 static int ds4424_probe(struct i2c_client
*client
,
217 const struct i2c_device_id
*id
)
219 struct ds4424_data
*data
;
220 struct iio_dev
*indio_dev
;
223 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*data
));
225 dev_err(&client
->dev
, "iio dev alloc failed.\n");
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
;
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
);
244 mutex_init(&data
->lock
);
245 ret
= regulator_enable(data
->vcc_reg
);
247 dev_err(&client
->dev
,
248 "Unable to enable the regulator.\n");
252 usleep_range(1000, 1200);
253 ret
= ds4424_verify_chip(indio_dev
);
257 switch (id
->driver_data
) {
259 indio_dev
->num_channels
= DS4422_MAX_DAC_CHANNELS
;
262 indio_dev
->num_channels
= DS4424_MAX_DAC_CHANNELS
;
265 dev_err(&client
->dev
,
266 "ds4424: Invalid chip id.\n");
271 indio_dev
->channels
= ds4424_channels
;
272 indio_dev
->modes
= INDIO_DIRECT_MODE
;
273 indio_dev
->info
= &ds4424_info
;
275 ret
= iio_device_register(indio_dev
);
277 dev_err(&client
->dev
,
278 "iio_device_register failed. ret: %d\n", ret
);
285 regulator_disable(data
->vcc_reg
);
289 static int ds4424_remove(struct i2c_client
*client
)
291 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
292 struct ds4424_data
*data
= iio_priv(indio_dev
);
294 iio_device_unregister(indio_dev
);
295 regulator_disable(data
->vcc_reg
);
300 static const struct i2c_device_id ds4424_id
[] = {
301 { "ds4422", ID_DS4422
},
302 { "ds4424", ID_DS4424
},
306 MODULE_DEVICE_TABLE(i2c
, ds4424_id
);
308 static const struct of_device_id ds4424_of_match
[] = {
309 { .compatible
= "maxim,ds4422" },
310 { .compatible
= "maxim,ds4424" },
314 MODULE_DEVICE_TABLE(of
, ds4424_of_match
);
316 static struct i2c_driver ds4424_driver
= {
319 .of_match_table
= ds4424_of_match
,
320 .pm
= &ds4424_pm_ops
,
322 .probe
= ds4424_probe
,
323 .remove
= ds4424_remove
,
324 .id_table
= ds4424_id
,
326 module_i2c_driver(ds4424_driver
);
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");