2 * AD7887 SPI ADC driver
4 * Copyright 2010-2011 Analog Devices Inc.
6 * Licensed under the GPL-2.
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/sysfs.h>
13 #include <linux/spi/spi.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/err.h>
16 #include <linux/module.h>
20 #include "../ring_generic.h"
25 static int ad7887_scan_direct(struct ad7887_state
*st
, unsigned ch
)
27 int ret
= spi_sync(st
->spi
, &st
->msg
[ch
]);
31 return (st
->data
[(ch
* 2)] << 8) | st
->data
[(ch
* 2) + 1];
34 static int ad7887_read_raw(struct iio_dev
*dev_info
,
35 struct iio_chan_spec
const *chan
,
41 struct ad7887_state
*st
= iio_priv(dev_info
);
42 unsigned int scale_uv
;
46 mutex_lock(&dev_info
->mlock
);
47 if (iio_ring_enabled(dev_info
))
48 ret
= ad7887_scan_from_ring(st
, 1 << chan
->address
);
50 ret
= ad7887_scan_direct(st
, chan
->address
);
51 mutex_unlock(&dev_info
->mlock
);
55 *val
= (ret
>> st
->chip_info
->channel
[0].scan_type
.shift
) &
56 RES_MASK(st
->chip_info
->channel
[0].scan_type
.realbits
);
58 case (1 << IIO_CHAN_INFO_SCALE_SHARED
):
59 scale_uv
= (st
->int_vref_mv
* 1000)
60 >> st
->chip_info
->channel
[0].scan_type
.realbits
;
62 *val2
= (scale_uv
%1000)*1000;
63 return IIO_VAL_INT_PLUS_MICRO
;
69 static const struct ad7887_chip_info ad7887_chip_info_tbl
[] = {
71 * More devices added in future
74 .channel
[0] = IIO_CHAN(IIO_IN
, 0, 1, 0, NULL
, 1, 0,
75 (1 << IIO_CHAN_INFO_SCALE_SHARED
),
76 1, 1, IIO_ST('u', 12, 16, 0), 0),
78 .channel
[1] = IIO_CHAN(IIO_IN
, 0, 1, 0, NULL
, 0, 0,
79 (1 << IIO_CHAN_INFO_SCALE_SHARED
),
80 0, 0, IIO_ST('u', 12, 16, 0), 0),
82 .channel
[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
87 static const struct iio_info ad7887_info
= {
88 .read_raw
= &ad7887_read_raw
,
89 .driver_module
= THIS_MODULE
,
92 static int __devinit
ad7887_probe(struct spi_device
*spi
)
94 struct ad7887_platform_data
*pdata
= spi
->dev
.platform_data
;
95 struct ad7887_state
*st
;
96 int ret
, voltage_uv
= 0, regdone
= 0;
97 struct iio_dev
*indio_dev
= iio_allocate_device(sizeof(*st
));
99 if (indio_dev
== NULL
)
102 st
= iio_priv(indio_dev
);
104 st
->reg
= regulator_get(&spi
->dev
, "vcc");
105 if (!IS_ERR(st
->reg
)) {
106 ret
= regulator_enable(st
->reg
);
110 voltage_uv
= regulator_get_voltage(st
->reg
);
114 &ad7887_chip_info_tbl
[spi_get_device_id(spi
)->driver_data
];
116 spi_set_drvdata(spi
, indio_dev
);
119 /* Estabilish that the iio_dev is a child of the spi device */
120 indio_dev
->dev
.parent
= &spi
->dev
;
121 indio_dev
->name
= spi_get_device_id(spi
)->name
;
122 indio_dev
->info
= &ad7887_info
;
123 indio_dev
->modes
= INDIO_DIRECT_MODE
;
125 /* Setup default message */
127 st
->tx_cmd_buf
[0] = AD7887_CH_AIN0
| AD7887_PM_MODE4
|
128 ((pdata
&& pdata
->use_onchip_ref
) ?
131 st
->xfer
[0].rx_buf
= &st
->data
[0];
132 st
->xfer
[0].tx_buf
= &st
->tx_cmd_buf
[0];
135 spi_message_init(&st
->msg
[AD7887_CH0
]);
136 spi_message_add_tail(&st
->xfer
[0], &st
->msg
[AD7887_CH0
]);
138 if (pdata
&& pdata
->en_dual
) {
139 st
->tx_cmd_buf
[0] |= AD7887_DUAL
| AD7887_REF_DIS
;
141 st
->tx_cmd_buf
[2] = AD7887_CH_AIN1
| AD7887_DUAL
|
142 AD7887_REF_DIS
| AD7887_PM_MODE4
;
143 st
->tx_cmd_buf
[4] = AD7887_CH_AIN0
| AD7887_DUAL
|
144 AD7887_REF_DIS
| AD7887_PM_MODE4
;
145 st
->tx_cmd_buf
[6] = AD7887_CH_AIN1
| AD7887_DUAL
|
146 AD7887_REF_DIS
| AD7887_PM_MODE4
;
148 st
->xfer
[1].rx_buf
= &st
->data
[0];
149 st
->xfer
[1].tx_buf
= &st
->tx_cmd_buf
[2];
152 st
->xfer
[2].rx_buf
= &st
->data
[2];
153 st
->xfer
[2].tx_buf
= &st
->tx_cmd_buf
[4];
156 spi_message_init(&st
->msg
[AD7887_CH0_CH1
]);
157 spi_message_add_tail(&st
->xfer
[1], &st
->msg
[AD7887_CH0_CH1
]);
158 spi_message_add_tail(&st
->xfer
[2], &st
->msg
[AD7887_CH0_CH1
]);
160 st
->xfer
[3].rx_buf
= &st
->data
[0];
161 st
->xfer
[3].tx_buf
= &st
->tx_cmd_buf
[6];
164 spi_message_init(&st
->msg
[AD7887_CH1
]);
165 spi_message_add_tail(&st
->xfer
[3], &st
->msg
[AD7887_CH1
]);
167 if (pdata
&& pdata
->vref_mv
)
168 st
->int_vref_mv
= pdata
->vref_mv
;
170 st
->int_vref_mv
= voltage_uv
/ 1000;
172 dev_warn(&spi
->dev
, "reference voltage unspecified\n");
174 indio_dev
->channels
= st
->chip_info
->channel
;
175 indio_dev
->num_channels
= 3;
177 if (pdata
&& pdata
->vref_mv
)
178 st
->int_vref_mv
= pdata
->vref_mv
;
179 else if (pdata
&& pdata
->use_onchip_ref
)
180 st
->int_vref_mv
= st
->chip_info
->int_vref_mv
;
182 dev_warn(&spi
->dev
, "reference voltage unspecified\n");
184 indio_dev
->channels
= &st
->chip_info
->channel
[1];
185 indio_dev
->num_channels
= 2;
188 ret
= ad7887_register_ring_funcs_and_init(indio_dev
);
190 goto error_disable_reg
;
192 ret
= iio_device_register(indio_dev
);
194 goto error_disable_reg
;
197 ret
= iio_ring_buffer_register_ex(indio_dev
, 0,
199 indio_dev
->num_channels
);
201 goto error_cleanup_ring
;
205 ad7887_ring_cleanup(indio_dev
);
207 if (!IS_ERR(st
->reg
))
208 regulator_disable(st
->reg
);
210 if (!IS_ERR(st
->reg
))
211 regulator_put(st
->reg
);
213 iio_device_unregister(indio_dev
);
215 iio_free_device(indio_dev
);
220 static int ad7887_remove(struct spi_device
*spi
)
222 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
223 struct ad7887_state
*st
= iio_priv(indio_dev
);
225 iio_ring_buffer_unregister(indio_dev
);
226 ad7887_ring_cleanup(indio_dev
);
227 if (!IS_ERR(st
->reg
)) {
228 regulator_disable(st
->reg
);
229 regulator_put(st
->reg
);
231 iio_device_unregister(indio_dev
);
236 static const struct spi_device_id ad7887_id
[] = {
237 {"ad7887", ID_AD7887
},
241 static struct spi_driver ad7887_driver
= {
244 .bus
= &spi_bus_type
,
245 .owner
= THIS_MODULE
,
247 .probe
= ad7887_probe
,
248 .remove
= __devexit_p(ad7887_remove
),
249 .id_table
= ad7887_id
,
252 static int __init
ad7887_init(void)
254 return spi_register_driver(&ad7887_driver
);
256 module_init(ad7887_init
);
258 static void __exit
ad7887_exit(void)
260 spi_unregister_driver(&ad7887_driver
);
262 module_exit(ad7887_exit
);
264 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
265 MODULE_DESCRIPTION("Analog Devices AD7887 ADC");
266 MODULE_LICENSE("GPL v2");
267 MODULE_ALIAS("spi:ad7887");