2 * AD5446 SPI DAC driver
4 * Copyright 2010 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/interrupt.h>
10 #include <linux/workqueue.h>
11 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15 #include <linux/list.h>
16 #include <linux/spi/spi.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/err.h>
19 #include <linux/module.h>
27 static void ad5446_store_sample(struct ad5446_state
*st
, unsigned val
)
29 st
->data
.d16
= cpu_to_be16(AD5446_LOAD
| val
);
32 static void ad5542_store_sample(struct ad5446_state
*st
, unsigned val
)
34 st
->data
.d16
= cpu_to_be16(val
);
37 static void ad5620_store_sample(struct ad5446_state
*st
, unsigned val
)
39 st
->data
.d16
= cpu_to_be16(AD5620_LOAD
| val
);
42 static void ad5660_store_sample(struct ad5446_state
*st
, unsigned val
)
45 st
->data
.d24
[0] = (val
>> 16) & 0xFF;
46 st
->data
.d24
[1] = (val
>> 8) & 0xFF;
47 st
->data
.d24
[2] = val
& 0xFF;
50 static void ad5620_store_pwr_down(struct ad5446_state
*st
, unsigned mode
)
52 st
->data
.d16
= cpu_to_be16(mode
<< 14);
55 static void ad5660_store_pwr_down(struct ad5446_state
*st
, unsigned mode
)
57 unsigned val
= mode
<< 16;
59 st
->data
.d24
[0] = (val
>> 16) & 0xFF;
60 st
->data
.d24
[1] = (val
>> 8) & 0xFF;
61 st
->data
.d24
[2] = val
& 0xFF;
64 static ssize_t
ad5446_write_powerdown_mode(struct device
*dev
,
65 struct device_attribute
*attr
,
66 const char *buf
, size_t len
)
68 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
69 struct ad5446_state
*st
= iio_priv(indio_dev
);
71 if (sysfs_streq(buf
, "1kohm_to_gnd"))
72 st
->pwr_down_mode
= MODE_PWRDWN_1k
;
73 else if (sysfs_streq(buf
, "100kohm_to_gnd"))
74 st
->pwr_down_mode
= MODE_PWRDWN_100k
;
75 else if (sysfs_streq(buf
, "three_state"))
76 st
->pwr_down_mode
= MODE_PWRDWN_TRISTATE
;
83 static ssize_t
ad5446_read_powerdown_mode(struct device
*dev
,
84 struct device_attribute
*attr
, char *buf
)
86 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
87 struct ad5446_state
*st
= iio_priv(indio_dev
);
89 char mode
[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"};
91 return sprintf(buf
, "%s\n", mode
[st
->pwr_down_mode
]);
94 static ssize_t
ad5446_read_dac_powerdown(struct device
*dev
,
95 struct device_attribute
*attr
,
98 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
99 struct ad5446_state
*st
= iio_priv(indio_dev
);
101 return sprintf(buf
, "%d\n", st
->pwr_down
);
104 static ssize_t
ad5446_write_dac_powerdown(struct device
*dev
,
105 struct device_attribute
*attr
,
106 const char *buf
, size_t len
)
108 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
109 struct ad5446_state
*st
= iio_priv(indio_dev
);
110 unsigned long readin
;
113 ret
= strict_strtol(buf
, 10, &readin
);
120 mutex_lock(&indio_dev
->mlock
);
121 st
->pwr_down
= readin
;
124 st
->chip_info
->store_pwr_down(st
, st
->pwr_down_mode
);
126 st
->chip_info
->store_sample(st
, st
->cached_val
);
128 ret
= spi_sync(st
->spi
, &st
->msg
);
129 mutex_unlock(&indio_dev
->mlock
);
131 return ret
? ret
: len
;
134 static IIO_DEVICE_ATTR(out_voltage_powerdown_mode
, S_IRUGO
| S_IWUSR
,
135 ad5446_read_powerdown_mode
,
136 ad5446_write_powerdown_mode
, 0);
138 static IIO_CONST_ATTR(out_voltage_powerdown_mode_available
,
139 "1kohm_to_gnd 100kohm_to_gnd three_state");
141 static IIO_DEVICE_ATTR(out_voltage0_powerdown
, S_IRUGO
| S_IWUSR
,
142 ad5446_read_dac_powerdown
,
143 ad5446_write_dac_powerdown
, 0);
145 static struct attribute
*ad5446_attributes
[] = {
146 &iio_dev_attr_out_voltage0_powerdown
.dev_attr
.attr
,
147 &iio_dev_attr_out_voltage_powerdown_mode
.dev_attr
.attr
,
148 &iio_const_attr_out_voltage_powerdown_mode_available
.dev_attr
.attr
,
152 static umode_t
ad5446_attr_is_visible(struct kobject
*kobj
,
153 struct attribute
*attr
, int n
)
155 struct device
*dev
= container_of(kobj
, struct device
, kobj
);
156 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
157 struct ad5446_state
*st
= iio_priv(indio_dev
);
159 umode_t mode
= attr
->mode
;
161 if (!st
->chip_info
->store_pwr_down
&&
162 (attr
== &iio_dev_attr_out_voltage0_powerdown
.dev_attr
.attr
||
163 attr
== &iio_dev_attr_out_voltage_powerdown_mode
.
166 &iio_const_attr_out_voltage_powerdown_mode_available
.
173 static const struct attribute_group ad5446_attribute_group
= {
174 .attrs
= ad5446_attributes
,
175 .is_visible
= ad5446_attr_is_visible
,
178 #define AD5446_CHANNEL(bits, storage, shift) { \
179 .type = IIO_VOLTAGE, \
183 .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \
184 .scan_type = IIO_ST('u', (bits), (storage), (shift)) \
187 static const struct ad5446_chip_info ad5446_chip_info_tbl
[] = {
189 .channel
= AD5446_CHANNEL(12, 16, 2),
190 .store_sample
= ad5446_store_sample
,
193 .channel
= AD5446_CHANNEL(14, 16, 0),
194 .store_sample
= ad5446_store_sample
,
197 .channel
= AD5446_CHANNEL(16, 16, 0),
198 .store_sample
= ad5542_store_sample
,
201 .channel
= AD5446_CHANNEL(16, 16, 0),
202 .store_sample
= ad5542_store_sample
,
205 .channel
= AD5446_CHANNEL(16, 16, 0),
206 .store_sample
= ad5542_store_sample
,
209 .channel
= AD5446_CHANNEL(12, 16, 4),
210 .store_sample
= ad5542_store_sample
,
213 .channel
= AD5446_CHANNEL(14, 16, 0),
214 .store_sample
= ad5542_store_sample
,
217 .channel
= AD5446_CHANNEL(8, 16, 6),
218 .store_sample
= ad5542_store_sample
,
219 .store_pwr_down
= ad5620_store_pwr_down
,
222 .channel
= AD5446_CHANNEL(10, 16, 4),
223 .store_sample
= ad5542_store_sample
,
224 .store_pwr_down
= ad5620_store_pwr_down
,
227 .channel
= AD5446_CHANNEL(12, 16, 2),
228 .store_sample
= ad5542_store_sample
,
229 .store_pwr_down
= ad5620_store_pwr_down
,
232 .channel
= AD5446_CHANNEL(12, 16, 2),
234 .store_sample
= ad5620_store_sample
,
235 .store_pwr_down
= ad5620_store_pwr_down
,
238 .channel
= AD5446_CHANNEL(12, 16, 2),
240 .store_sample
= ad5620_store_sample
,
241 .store_pwr_down
= ad5620_store_pwr_down
,
244 .channel
= AD5446_CHANNEL(14, 16, 0),
246 .store_sample
= ad5620_store_sample
,
247 .store_pwr_down
= ad5620_store_pwr_down
,
250 .channel
= AD5446_CHANNEL(14, 16, 0),
252 .store_sample
= ad5620_store_sample
,
253 .store_pwr_down
= ad5620_store_pwr_down
,
256 .channel
= AD5446_CHANNEL(16, 16, 0),
258 .store_sample
= ad5660_store_sample
,
259 .store_pwr_down
= ad5660_store_pwr_down
,
262 .channel
= AD5446_CHANNEL(16, 16, 0),
264 .store_sample
= ad5660_store_sample
,
265 .store_pwr_down
= ad5660_store_pwr_down
,
269 static int ad5446_read_raw(struct iio_dev
*indio_dev
,
270 struct iio_chan_spec
const *chan
,
275 struct ad5446_state
*st
= iio_priv(indio_dev
);
276 unsigned long scale_uv
;
279 case IIO_CHAN_INFO_SCALE
:
280 scale_uv
= (st
->vref_mv
* 1000) >> chan
->scan_type
.realbits
;
281 *val
= scale_uv
/ 1000;
282 *val2
= (scale_uv
% 1000) * 1000;
283 return IIO_VAL_INT_PLUS_MICRO
;
289 static int ad5446_write_raw(struct iio_dev
*indio_dev
,
290 struct iio_chan_spec
const *chan
,
295 struct ad5446_state
*st
= iio_priv(indio_dev
);
300 if (val
>= (1 << chan
->scan_type
.realbits
) || val
< 0)
303 val
<<= chan
->scan_type
.shift
;
304 mutex_lock(&indio_dev
->mlock
);
305 st
->cached_val
= val
;
306 st
->chip_info
->store_sample(st
, val
);
307 ret
= spi_sync(st
->spi
, &st
->msg
);
308 mutex_unlock(&indio_dev
->mlock
);
317 static const struct iio_info ad5446_info
= {
318 .read_raw
= ad5446_read_raw
,
319 .write_raw
= ad5446_write_raw
,
320 .attrs
= &ad5446_attribute_group
,
321 .driver_module
= THIS_MODULE
,
324 static int __devinit
ad5446_probe(struct spi_device
*spi
)
326 struct ad5446_state
*st
;
327 struct iio_dev
*indio_dev
;
328 struct regulator
*reg
;
329 int ret
, voltage_uv
= 0;
331 reg
= regulator_get(&spi
->dev
, "vcc");
333 ret
= regulator_enable(reg
);
337 voltage_uv
= regulator_get_voltage(reg
);
340 indio_dev
= iio_allocate_device(sizeof(*st
));
341 if (indio_dev
== NULL
) {
343 goto error_disable_reg
;
345 st
= iio_priv(indio_dev
);
347 &ad5446_chip_info_tbl
[spi_get_device_id(spi
)->driver_data
];
349 spi_set_drvdata(spi
, indio_dev
);
353 /* Estabilish that the iio_dev is a child of the spi device */
354 indio_dev
->dev
.parent
= &spi
->dev
;
355 indio_dev
->name
= spi_get_device_id(spi
)->name
;
356 indio_dev
->info
= &ad5446_info
;
357 indio_dev
->modes
= INDIO_DIRECT_MODE
;
358 indio_dev
->channels
= &st
->chip_info
->channel
;
359 indio_dev
->num_channels
= 1;
361 /* Setup default message */
363 st
->xfer
.tx_buf
= &st
->data
;
364 st
->xfer
.len
= st
->chip_info
->channel
.scan_type
.storagebits
/ 8;
366 spi_message_init(&st
->msg
);
367 spi_message_add_tail(&st
->xfer
, &st
->msg
);
369 switch (spi_get_device_id(spi
)->driver_data
) {
376 st
->vref_mv
= st
->chip_info
->int_vref_mv
;
380 st
->vref_mv
= voltage_uv
/ 1000;
383 "reference voltage unspecified\n");
386 ret
= iio_device_register(indio_dev
);
388 goto error_free_device
;
393 iio_free_device(indio_dev
);
396 regulator_disable(reg
);
404 static int ad5446_remove(struct spi_device
*spi
)
406 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
407 struct ad5446_state
*st
= iio_priv(indio_dev
);
409 iio_device_unregister(indio_dev
);
410 if (!IS_ERR(st
->reg
)) {
411 regulator_disable(st
->reg
);
412 regulator_put(st
->reg
);
414 iio_free_device(indio_dev
);
419 static const struct spi_device_id ad5446_id
[] = {
420 {"ad5444", ID_AD5444
},
421 {"ad5446", ID_AD5446
},
422 {"ad5512a", ID_AD5512A
},
423 {"ad5541a", ID_AD5541A
},
424 {"ad5542a", ID_AD5542A
},
425 {"ad5543", ID_AD5543
},
426 {"ad5553", ID_AD5553
},
427 {"ad5601", ID_AD5601
},
428 {"ad5611", ID_AD5611
},
429 {"ad5621", ID_AD5621
},
430 {"ad5620-2500", ID_AD5620_2500
}, /* AD5620/40/60: */
431 {"ad5620-1250", ID_AD5620_1250
}, /* part numbers may look differently */
432 {"ad5640-2500", ID_AD5640_2500
},
433 {"ad5640-1250", ID_AD5640_1250
},
434 {"ad5660-2500", ID_AD5660_2500
},
435 {"ad5660-1250", ID_AD5660_1250
},
438 MODULE_DEVICE_TABLE(spi
, ad5446_id
);
440 static struct spi_driver ad5446_driver
= {
443 .owner
= THIS_MODULE
,
445 .probe
= ad5446_probe
,
446 .remove
= __devexit_p(ad5446_remove
),
447 .id_table
= ad5446_id
,
449 module_spi_driver(ad5446_driver
);
451 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
452 MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");
453 MODULE_LICENSE("GPL v2");