3 * Copyright (C) 2014 Philippe Reynes
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/i2c.h>
13 #include <linux/iio/iio.h>
14 #include <linux/regulator/consumer.h>
16 #define MAX5821_MAX_DAC_CHANNELS 2
19 #define MAX5821_LOAD_DAC_A_IN_REG_B 0x00
20 #define MAX5821_LOAD_DAC_B_IN_REG_A 0x10
21 #define MAX5821_EXTENDED_COMMAND_MODE 0xf0
22 #define MAX5821_READ_DAC_A_COMMAND 0xf1
23 #define MAX5821_READ_DAC_B_COMMAND 0xf2
25 #define MAX5821_EXTENDED_POWER_UP 0x00
26 #define MAX5821_EXTENDED_POWER_DOWN_MODE0 0x01
27 #define MAX5821_EXTENDED_POWER_DOWN_MODE1 0x02
28 #define MAX5821_EXTENDED_POWER_DOWN_MODE2 0x03
29 #define MAX5821_EXTENDED_DAC_A 0x04
30 #define MAX5821_EXTENDED_DAC_B 0x08
32 enum max5821_device_ids
{
37 struct i2c_client
*client
;
38 struct regulator
*vref_reg
;
39 unsigned short vref_mv
;
40 bool powerdown
[MAX5821_MAX_DAC_CHANNELS
];
41 u8 powerdown_mode
[MAX5821_MAX_DAC_CHANNELS
];
45 static const char * const max5821_powerdown_modes
[] = {
54 MAX5821_100KOHM_TO_GND
57 static int max5821_get_powerdown_mode(struct iio_dev
*indio_dev
,
58 const struct iio_chan_spec
*chan
)
60 struct max5821_data
*st
= iio_priv(indio_dev
);
62 return st
->powerdown_mode
[chan
->channel
];
65 static int max5821_set_powerdown_mode(struct iio_dev
*indio_dev
,
66 const struct iio_chan_spec
*chan
,
69 struct max5821_data
*st
= iio_priv(indio_dev
);
71 st
->powerdown_mode
[chan
->channel
] = mode
;
76 static const struct iio_enum max5821_powerdown_mode_enum
= {
77 .items
= max5821_powerdown_modes
,
78 .num_items
= ARRAY_SIZE(max5821_powerdown_modes
),
79 .get
= max5821_get_powerdown_mode
,
80 .set
= max5821_set_powerdown_mode
,
83 static ssize_t
max5821_read_dac_powerdown(struct iio_dev
*indio_dev
,
85 const struct iio_chan_spec
*chan
,
88 struct max5821_data
*st
= iio_priv(indio_dev
);
90 return sprintf(buf
, "%d\n", st
->powerdown
[chan
->channel
]);
93 static int max5821_sync_powerdown_mode(struct max5821_data
*data
,
94 const struct iio_chan_spec
*chan
)
98 outbuf
[0] = MAX5821_EXTENDED_COMMAND_MODE
;
100 if (chan
->channel
== 0)
101 outbuf
[1] = MAX5821_EXTENDED_DAC_A
;
103 outbuf
[1] = MAX5821_EXTENDED_DAC_B
;
105 if (data
->powerdown
[chan
->channel
])
106 outbuf
[1] |= data
->powerdown_mode
[chan
->channel
] + 1;
108 outbuf
[1] |= MAX5821_EXTENDED_POWER_UP
;
110 return i2c_master_send(data
->client
, outbuf
, 2);
113 static ssize_t
max5821_write_dac_powerdown(struct iio_dev
*indio_dev
,
115 const struct iio_chan_spec
*chan
,
116 const char *buf
, size_t len
)
118 struct max5821_data
*data
= iio_priv(indio_dev
);
122 ret
= strtobool(buf
, &powerdown
);
126 data
->powerdown
[chan
->channel
] = powerdown
;
128 ret
= max5821_sync_powerdown_mode(data
, chan
);
135 static const struct iio_chan_spec_ext_info max5821_ext_info
[] = {
138 .read
= max5821_read_dac_powerdown
,
139 .write
= max5821_write_dac_powerdown
,
140 .shared
= IIO_SEPARATE
,
142 IIO_ENUM("powerdown_mode", IIO_SEPARATE
, &max5821_powerdown_mode_enum
),
143 IIO_ENUM_AVAILABLE("powerdown_mode", &max5821_powerdown_mode_enum
),
147 #define MAX5821_CHANNEL(chan) { \
148 .type = IIO_VOLTAGE, \
152 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
153 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \
154 .ext_info = max5821_ext_info, \
157 static const struct iio_chan_spec max5821_channels
[] = {
162 static const u8 max5821_read_dac_command
[] = {
163 MAX5821_READ_DAC_A_COMMAND
,
164 MAX5821_READ_DAC_B_COMMAND
167 static const u8 max5821_load_dac_command
[] = {
168 MAX5821_LOAD_DAC_A_IN_REG_B
,
169 MAX5821_LOAD_DAC_B_IN_REG_A
172 static int max5821_get_value(struct iio_dev
*indio_dev
,
173 int *val
, int channel
)
175 struct max5821_data
*data
= iio_priv(indio_dev
);
176 struct i2c_client
*client
= data
->client
;
181 if ((channel
!= 0) && (channel
!= 1))
184 outbuf
[0] = max5821_read_dac_command
[channel
];
186 mutex_lock(&data
->lock
);
188 ret
= i2c_master_send(client
, outbuf
, 1);
190 mutex_unlock(&data
->lock
);
192 } else if (ret
!= 1) {
193 mutex_unlock(&data
->lock
);
197 ret
= i2c_master_recv(client
, inbuf
, 2);
199 mutex_unlock(&data
->lock
);
201 } else if (ret
!= 2) {
202 mutex_unlock(&data
->lock
);
206 mutex_unlock(&data
->lock
);
208 *val
= ((inbuf
[0] & 0x0f) << 6) | (inbuf
[1] >> 2);
213 static int max5821_set_value(struct iio_dev
*indio_dev
,
214 int val
, int channel
)
216 struct max5821_data
*data
= iio_priv(indio_dev
);
217 struct i2c_client
*client
= data
->client
;
221 if ((val
< 0) || (val
> 1023))
224 if ((channel
!= 0) && (channel
!= 1))
227 outbuf
[0] = max5821_load_dac_command
[channel
];
228 outbuf
[0] |= val
>> 6;
229 outbuf
[1] = (val
& 0x3f) << 2;
231 ret
= i2c_master_send(client
, outbuf
, 2);
240 static int max5821_read_raw(struct iio_dev
*indio_dev
,
241 struct iio_chan_spec
const *chan
,
242 int *val
, int *val2
, long mask
)
244 struct max5821_data
*data
= iio_priv(indio_dev
);
247 case IIO_CHAN_INFO_RAW
:
248 return max5821_get_value(indio_dev
, val
, chan
->channel
);
249 case IIO_CHAN_INFO_SCALE
:
250 *val
= data
->vref_mv
;
252 return IIO_VAL_FRACTIONAL_LOG2
;
258 static int max5821_write_raw(struct iio_dev
*indio_dev
,
259 struct iio_chan_spec
const *chan
,
260 int val
, int val2
, long mask
)
266 case IIO_CHAN_INFO_RAW
:
267 return max5821_set_value(indio_dev
, val
, chan
->channel
);
273 #ifdef CONFIG_PM_SLEEP
274 static int max5821_suspend(struct device
*dev
)
276 u8 outbuf
[2] = { MAX5821_EXTENDED_COMMAND_MODE
,
277 MAX5821_EXTENDED_DAC_A
|
278 MAX5821_EXTENDED_DAC_B
|
279 MAX5821_EXTENDED_POWER_DOWN_MODE2
};
281 return i2c_master_send(to_i2c_client(dev
), outbuf
, 2);
284 static int max5821_resume(struct device
*dev
)
286 u8 outbuf
[2] = { MAX5821_EXTENDED_COMMAND_MODE
,
287 MAX5821_EXTENDED_DAC_A
|
288 MAX5821_EXTENDED_DAC_B
|
289 MAX5821_EXTENDED_POWER_UP
};
291 return i2c_master_send(to_i2c_client(dev
), outbuf
, 2);
294 static SIMPLE_DEV_PM_OPS(max5821_pm_ops
, max5821_suspend
, max5821_resume
);
295 #define MAX5821_PM_OPS (&max5821_pm_ops)
297 #define MAX5821_PM_OPS NULL
298 #endif /* CONFIG_PM_SLEEP */
300 static const struct iio_info max5821_info
= {
301 .read_raw
= max5821_read_raw
,
302 .write_raw
= max5821_write_raw
,
303 .driver_module
= THIS_MODULE
,
306 static int max5821_probe(struct i2c_client
*client
,
307 const struct i2c_device_id
*id
)
309 struct max5821_data
*data
;
310 struct iio_dev
*indio_dev
;
314 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*data
));
317 data
= iio_priv(indio_dev
);
318 i2c_set_clientdata(client
, indio_dev
);
319 data
->client
= client
;
320 mutex_init(&data
->lock
);
322 /* max5821 start in powerdown mode 100Kohm to ground */
323 for (tmp
= 0; tmp
< MAX5821_MAX_DAC_CHANNELS
; tmp
++) {
324 data
->powerdown
[tmp
] = true;
325 data
->powerdown_mode
[tmp
] = MAX5821_100KOHM_TO_GND
;
328 data
->vref_reg
= devm_regulator_get(&client
->dev
, "vref");
329 if (IS_ERR(data
->vref_reg
)) {
330 ret
= PTR_ERR(data
->vref_reg
);
331 dev_err(&client
->dev
,
332 "Failed to get vref regulator: %d\n", ret
);
336 ret
= regulator_enable(data
->vref_reg
);
338 dev_err(&client
->dev
,
339 "Failed to enable vref regulator: %d\n", ret
);
343 ret
= regulator_get_voltage(data
->vref_reg
);
345 dev_err(&client
->dev
,
346 "Failed to get voltage on regulator: %d\n", ret
);
347 goto error_disable_reg
;
350 data
->vref_mv
= ret
/ 1000;
352 indio_dev
->name
= id
->name
;
353 indio_dev
->dev
.parent
= &client
->dev
;
354 indio_dev
->num_channels
= ARRAY_SIZE(max5821_channels
);
355 indio_dev
->channels
= max5821_channels
;
356 indio_dev
->modes
= INDIO_DIRECT_MODE
;
357 indio_dev
->info
= &max5821_info
;
359 return iio_device_register(indio_dev
);
362 regulator_disable(data
->vref_reg
);
369 static int max5821_remove(struct i2c_client
*client
)
371 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
372 struct max5821_data
*data
= iio_priv(indio_dev
);
374 iio_device_unregister(indio_dev
);
375 regulator_disable(data
->vref_reg
);
380 static const struct i2c_device_id max5821_id
[] = {
381 { "max5821", ID_MAX5821
},
384 MODULE_DEVICE_TABLE(i2c
, max5821_id
);
386 static const struct of_device_id max5821_of_match
[] = {
387 { .compatible
= "maxim,max5821" },
390 MODULE_DEVICE_TABLE(of
, max5821_of_match
);
392 static struct i2c_driver max5821_driver
= {
395 .of_match_table
= max5821_of_match
,
396 .pm
= MAX5821_PM_OPS
,
398 .probe
= max5821_probe
,
399 .remove
= max5821_remove
,
400 .id_table
= max5821_id
,
402 module_i2c_driver(max5821_driver
);
404 MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>");
405 MODULE_DESCRIPTION("MAX5821 DAC");
406 MODULE_LICENSE("GPL v2");