diff options
-rw-r--r-- | drivers/staging/iio/adc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/staging/iio/adc/ad7780.c | 186 |
2 files changed, 71 insertions, 116 deletions
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 845fb6c70ca3..d0eb27be381c 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig | |||
@@ -99,6 +99,7 @@ config AD7780 | |||
99 | tristate "Analog Devices AD7780 AD7781 ADC driver" | 99 | tristate "Analog Devices AD7780 AD7781 ADC driver" |
100 | depends on SPI | 100 | depends on SPI |
101 | depends on GPIOLIB | 101 | depends on GPIOLIB |
102 | select AD_SIGMA_DELTA | ||
102 | help | 103 | help |
103 | Say yes here to build support for Analog Devices | 104 | Say yes here to build support for Analog Devices |
104 | AD7780 and AD7781 SPI analog to digital converters (ADC). | 105 | AD7780 and AD7781 SPI analog to digital converters (ADC). |
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 19ee49c95de4..853f8b16b4ef 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/iio/iio.h> | 21 | #include <linux/iio/iio.h> |
22 | #include <linux/iio/sysfs.h> | 22 | #include <linux/iio/sysfs.h> |
23 | #include <linux/iio/adc/ad_sigma_delta.h> | ||
23 | 24 | ||
24 | #include "ad7780.h" | 25 | #include "ad7780.h" |
25 | 26 | ||
@@ -37,20 +38,13 @@ struct ad7780_chip_info { | |||
37 | }; | 38 | }; |
38 | 39 | ||
39 | struct ad7780_state { | 40 | struct ad7780_state { |
40 | struct spi_device *spi; | ||
41 | const struct ad7780_chip_info *chip_info; | 41 | const struct ad7780_chip_info *chip_info; |
42 | struct regulator *reg; | 42 | struct regulator *reg; |
43 | struct ad7780_platform_data *pdata; | 43 | int powerdown_gpio; |
44 | wait_queue_head_t wq_data_avail; | 44 | unsigned int gain; |
45 | bool done; | ||
46 | u16 int_vref_mv; | 45 | u16 int_vref_mv; |
47 | struct spi_transfer xfer; | 46 | |
48 | struct spi_message msg; | 47 | struct ad_sigma_delta sd; |
49 | /* | ||
50 | * DMA (thus cache coherency maintenance) requires the | ||
51 | * transfer buffers to live in their own cache lines. | ||
52 | */ | ||
53 | unsigned int data ____cacheline_aligned; | ||
54 | }; | 48 | }; |
55 | 49 | ||
56 | enum ad7780_supported_device_ids { | 50 | enum ad7780_supported_device_ids { |
@@ -58,28 +52,30 @@ enum ad7780_supported_device_ids { | |||
58 | ID_AD7781, | 52 | ID_AD7781, |
59 | }; | 53 | }; |
60 | 54 | ||
61 | static int ad7780_read(struct ad7780_state *st, int *val) | 55 | static struct ad7780_state *ad_sigma_delta_to_ad7780(struct ad_sigma_delta *sd) |
62 | { | 56 | { |
63 | int ret; | 57 | return container_of(sd, struct ad7780_state, sd); |
64 | 58 | } | |
65 | spi_bus_lock(st->spi->master); | ||
66 | |||
67 | enable_irq(st->spi->irq); | ||
68 | st->done = false; | ||
69 | gpio_set_value(st->pdata->gpio_pdrst, 1); | ||
70 | 59 | ||
71 | ret = wait_event_interruptible(st->wq_data_avail, st->done); | 60 | static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta, |
72 | disable_irq_nosync(st->spi->irq); | 61 | enum ad_sigma_delta_mode mode) |
73 | if (ret) | 62 | { |
74 | goto out; | 63 | struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); |
64 | unsigned val; | ||
65 | |||
66 | switch (mode) { | ||
67 | case AD_SD_MODE_SINGLE: | ||
68 | case AD_SD_MODE_CONTINUOUS: | ||
69 | val = 1; | ||
70 | break; | ||
71 | default: | ||
72 | val = 0; | ||
73 | break; | ||
74 | } | ||
75 | 75 | ||
76 | ret = spi_sync_locked(st->spi, &st->msg); | 76 | gpio_set_value(st->powerdown_gpio, val); |
77 | *val = be32_to_cpu(st->data); | ||
78 | out: | ||
79 | gpio_set_value(st->pdata->gpio_pdrst, 0); | ||
80 | spi_bus_unlock(st->spi->master); | ||
81 | 77 | ||
82 | return ret; | 78 | return 0; |
83 | } | 79 | } |
84 | 80 | ||
85 | static int ad7780_read_raw(struct iio_dev *indio_dev, | 81 | static int ad7780_read_raw(struct iio_dev *indio_dev, |
@@ -89,89 +85,57 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, | |||
89 | long m) | 85 | long m) |
90 | { | 86 | { |
91 | struct ad7780_state *st = iio_priv(indio_dev); | 87 | struct ad7780_state *st = iio_priv(indio_dev); |
92 | struct iio_chan_spec channel = st->chip_info->channel; | ||
93 | int ret, smpl = 0; | ||
94 | unsigned long scale_uv; | 88 | unsigned long scale_uv; |
95 | 89 | ||
96 | switch (m) { | 90 | switch (m) { |
97 | case IIO_CHAN_INFO_RAW: | 91 | case IIO_CHAN_INFO_RAW: |
98 | mutex_lock(&indio_dev->mlock); | 92 | return ad_sigma_delta_single_conversion(indio_dev, chan, val); |
99 | ret = ad7780_read(st, &smpl); | ||
100 | mutex_unlock(&indio_dev->mlock); | ||
101 | |||
102 | if (ret < 0) | ||
103 | return ret; | ||
104 | |||
105 | if ((smpl & AD7780_ERR) || | ||
106 | !((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1))) | ||
107 | return -EIO; | ||
108 | |||
109 | *val = (smpl >> channel.scan_type.shift) & | ||
110 | ((1 << (channel.scan_type.realbits)) - 1); | ||
111 | *val -= (1 << (channel.scan_type.realbits - 1)); | ||
112 | |||
113 | if (!(smpl & AD7780_GAIN)) | ||
114 | *val *= 128; | ||
115 | |||
116 | return IIO_VAL_INT; | ||
117 | case IIO_CHAN_INFO_SCALE: | 93 | case IIO_CHAN_INFO_SCALE: |
118 | scale_uv = (st->int_vref_mv * 100000) | 94 | scale_uv = (st->int_vref_mv * 100000 * st->gain) |
119 | >> (channel.scan_type.realbits - 1); | 95 | >> (chan->scan_type.realbits - 1); |
120 | *val = scale_uv / 100000; | 96 | *val = scale_uv / 100000; |
121 | *val2 = (scale_uv % 100000) * 10; | 97 | *val2 = (scale_uv % 100000) * 10; |
122 | return IIO_VAL_INT_PLUS_MICRO; | 98 | return IIO_VAL_INT_PLUS_MICRO; |
99 | case IIO_CHAN_INFO_OFFSET: | ||
100 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
101 | return IIO_VAL_INT; | ||
123 | } | 102 | } |
103 | |||
124 | return -EINVAL; | 104 | return -EINVAL; |
125 | } | 105 | } |
126 | 106 | ||
107 | static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta, | ||
108 | unsigned int raw_sample) | ||
109 | { | ||
110 | struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); | ||
111 | |||
112 | if ((raw_sample & AD7780_ERR) || | ||
113 | !((raw_sample & AD7780_PAT0) && !(raw_sample & AD7780_PAT1))) | ||
114 | return -EIO; | ||
115 | |||
116 | if (raw_sample & AD7780_GAIN) | ||
117 | st->gain = 1; | ||
118 | else | ||
119 | st->gain = 128; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static const struct ad_sigma_delta_info ad7780_sigma_delta_info = { | ||
125 | .set_mode = ad7780_set_mode, | ||
126 | .postprocess_sample = ad7780_postprocess_sample, | ||
127 | .has_registers = false, | ||
128 | }; | ||
129 | |||
127 | static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | 130 | static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { |
128 | [ID_AD7780] = { | 131 | [ID_AD7780] = { |
129 | .channel = { | 132 | .channel = AD_SD_CHANNEL(1, 0, 0, 24, 32, 8), |
130 | .type = IIO_VOLTAGE, | ||
131 | .indexed = 1, | ||
132 | .channel = 0, | ||
133 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | ||
134 | IIO_CHAN_INFO_SCALE_SHARED_BIT | | ||
135 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
136 | .scan_type = { | ||
137 | .sign = 'u', | ||
138 | .realbits = 24, | ||
139 | .storagebits = 32, | ||
140 | .shift = 8, | ||
141 | }, | ||
142 | }, | ||
143 | }, | 133 | }, |
144 | [ID_AD7781] = { | 134 | [ID_AD7781] = { |
145 | .channel = { | 135 | .channel = AD_SD_CHANNEL(1, 0, 0, 20, 32, 12), |
146 | .type = IIO_VOLTAGE, | ||
147 | .indexed = 1, | ||
148 | .channel = 0, | ||
149 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | ||
150 | IIO_CHAN_INFO_SCALE_SHARED_BIT | | ||
151 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
152 | .scan_type = { | ||
153 | .sign = 'u', | ||
154 | .realbits = 20, | ||
155 | .storagebits = 32, | ||
156 | .shift = 12, | ||
157 | }, | ||
158 | }, | ||
159 | }, | 136 | }, |
160 | }; | 137 | }; |
161 | 138 | ||
162 | /** | ||
163 | * Interrupt handler | ||
164 | */ | ||
165 | static irqreturn_t ad7780_interrupt(int irq, void *dev_id) | ||
166 | { | ||
167 | struct ad7780_state *st = dev_id; | ||
168 | |||
169 | st->done = true; | ||
170 | wake_up_interruptible(&st->wq_data_avail); | ||
171 | |||
172 | return IRQ_HANDLED; | ||
173 | }; | ||
174 | |||
175 | static const struct iio_info ad7780_info = { | 139 | static const struct iio_info ad7780_info = { |
176 | .read_raw = &ad7780_read_raw, | 140 | .read_raw = &ad7780_read_raw, |
177 | .driver_module = THIS_MODULE, | 141 | .driver_module = THIS_MODULE, |
@@ -194,6 +158,9 @@ static int __devinit ad7780_probe(struct spi_device *spi) | |||
194 | return -ENOMEM; | 158 | return -ENOMEM; |
195 | 159 | ||
196 | st = iio_priv(indio_dev); | 160 | st = iio_priv(indio_dev); |
161 | st->gain = 1; | ||
162 | |||
163 | ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info); | ||
197 | 164 | ||
198 | st->reg = regulator_get(&spi->dev, "vcc"); | 165 | st->reg = regulator_get(&spi->dev, "vcc"); |
199 | if (!IS_ERR(st->reg)) { | 166 | if (!IS_ERR(st->reg)) { |
@@ -207,7 +174,7 @@ static int __devinit ad7780_probe(struct spi_device *spi) | |||
207 | st->chip_info = | 174 | st->chip_info = |
208 | &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; | 175 | &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; |
209 | 176 | ||
210 | st->pdata = pdata; | 177 | st->powerdown_gpio = pdata->gpio_pdrst; |
211 | 178 | ||
212 | if (pdata && pdata->vref_mv) | 179 | if (pdata && pdata->vref_mv) |
213 | st->int_vref_mv = pdata->vref_mv; | 180 | st->int_vref_mv = pdata->vref_mv; |
@@ -217,7 +184,6 @@ static int __devinit ad7780_probe(struct spi_device *spi) | |||
217 | dev_warn(&spi->dev, "reference voltage unspecified\n"); | 184 | dev_warn(&spi->dev, "reference voltage unspecified\n"); |
218 | 185 | ||
219 | spi_set_drvdata(spi, indio_dev); | 186 | spi_set_drvdata(spi, indio_dev); |
220 | st->spi = spi; | ||
221 | 187 | ||
222 | indio_dev->dev.parent = &spi->dev; | 188 | indio_dev->dev.parent = &spi->dev; |
223 | indio_dev->name = spi_get_device_id(spi)->name; | 189 | indio_dev->name = spi_get_device_id(spi)->name; |
@@ -226,40 +192,27 @@ static int __devinit ad7780_probe(struct spi_device *spi) | |||
226 | indio_dev->num_channels = 1; | 192 | indio_dev->num_channels = 1; |
227 | indio_dev->info = &ad7780_info; | 193 | indio_dev->info = &ad7780_info; |
228 | 194 | ||
229 | init_waitqueue_head(&st->wq_data_avail); | 195 | ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, |
230 | |||
231 | /* Setup default message */ | ||
232 | |||
233 | st->xfer.rx_buf = &st->data; | ||
234 | st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8; | ||
235 | |||
236 | spi_message_init(&st->msg); | ||
237 | spi_message_add_tail(&st->xfer, &st->msg); | ||
238 | |||
239 | ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, | ||
240 | "AD7780 /PDRST"); | 196 | "AD7780 /PDRST"); |
241 | if (ret) { | 197 | if (ret) { |
242 | dev_err(&spi->dev, "failed to request GPIO PDRST\n"); | 198 | dev_err(&spi->dev, "failed to request GPIO PDRST\n"); |
243 | goto error_disable_reg; | 199 | goto error_disable_reg; |
244 | } | 200 | } |
245 | 201 | ||
246 | ret = request_irq(spi->irq, ad7780_interrupt, | 202 | ret = ad_sd_setup_buffer_and_trigger(indio_dev); |
247 | IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st); | ||
248 | if (ret) | 203 | if (ret) |
249 | goto error_free_gpio; | 204 | goto error_free_gpio; |
250 | 205 | ||
251 | disable_irq(spi->irq); | ||
252 | |||
253 | ret = iio_device_register(indio_dev); | 206 | ret = iio_device_register(indio_dev); |
254 | if (ret) | 207 | if (ret) |
255 | goto error_free_irq; | 208 | goto error_cleanup_buffer_and_trigger; |
256 | 209 | ||
257 | return 0; | 210 | return 0; |
258 | 211 | ||
259 | error_free_irq: | 212 | error_cleanup_buffer_and_trigger: |
260 | free_irq(spi->irq, st); | 213 | ad_sd_cleanup_buffer_and_trigger(indio_dev); |
261 | error_free_gpio: | 214 | error_free_gpio: |
262 | gpio_free(st->pdata->gpio_pdrst); | 215 | gpio_free(pdata->gpio_pdrst); |
263 | error_disable_reg: | 216 | error_disable_reg: |
264 | if (!IS_ERR(st->reg)) | 217 | if (!IS_ERR(st->reg)) |
265 | regulator_disable(st->reg); | 218 | regulator_disable(st->reg); |
@@ -278,8 +231,9 @@ static int ad7780_remove(struct spi_device *spi) | |||
278 | struct ad7780_state *st = iio_priv(indio_dev); | 231 | struct ad7780_state *st = iio_priv(indio_dev); |
279 | 232 | ||
280 | iio_device_unregister(indio_dev); | 233 | iio_device_unregister(indio_dev); |
281 | free_irq(spi->irq, st); | 234 | ad_sd_cleanup_buffer_and_trigger(indio_dev); |
282 | gpio_free(st->pdata->gpio_pdrst); | 235 | |
236 | gpio_free(st->powerdown_gpio); | ||
283 | if (!IS_ERR(st->reg)) { | 237 | if (!IS_ERR(st->reg)) { |
284 | regulator_disable(st->reg); | 238 | regulator_disable(st->reg); |
285 | regulator_put(st->reg); | 239 | regulator_put(st->reg); |