.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Support code for Analog Devices Sigma-Delta ADCs |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2012 Analog Devices Inc. |
---|
5 | 6 | * Author: Lars-Peter Clausen <lars@metafoo.de> |
---|
6 | | - * |
---|
7 | | - * Licensed under the GPL-2. |
---|
8 | 7 | */ |
---|
9 | 8 | |
---|
10 | 9 | #include <linux/interrupt.h> |
---|
.. | .. |
---|
58 | 57 | int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, |
---|
59 | 58 | unsigned int size, unsigned int val) |
---|
60 | 59 | { |
---|
61 | | - uint8_t *data = sigma_delta->data; |
---|
| 60 | + uint8_t *data = sigma_delta->tx_buf; |
---|
62 | 61 | struct spi_transfer t = { |
---|
63 | 62 | .tx_buf = data, |
---|
64 | 63 | .len = size + 1, |
---|
.. | .. |
---|
71 | 70 | |
---|
72 | 71 | switch (size) { |
---|
73 | 72 | case 3: |
---|
74 | | - data[1] = val >> 16; |
---|
75 | | - data[2] = val >> 8; |
---|
76 | | - data[3] = val; |
---|
| 73 | + put_unaligned_be24(val, &data[1]); |
---|
77 | 74 | break; |
---|
78 | 75 | case 2: |
---|
79 | 76 | put_unaligned_be16(val, &data[1]); |
---|
.. | .. |
---|
102 | 99 | static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta, |
---|
103 | 100 | unsigned int reg, unsigned int size, uint8_t *val) |
---|
104 | 101 | { |
---|
105 | | - uint8_t *data = sigma_delta->data; |
---|
| 102 | + uint8_t *data = sigma_delta->tx_buf; |
---|
106 | 103 | int ret; |
---|
107 | 104 | struct spi_transfer t[] = { |
---|
108 | 105 | { |
---|
.. | .. |
---|
149 | 146 | { |
---|
150 | 147 | int ret; |
---|
151 | 148 | |
---|
152 | | - ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data); |
---|
| 149 | + ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->rx_buf); |
---|
153 | 150 | if (ret < 0) |
---|
154 | 151 | goto out; |
---|
155 | 152 | |
---|
156 | 153 | switch (size) { |
---|
157 | 154 | case 4: |
---|
158 | | - *val = get_unaligned_be32(sigma_delta->data); |
---|
| 155 | + *val = get_unaligned_be32(sigma_delta->rx_buf); |
---|
159 | 156 | break; |
---|
160 | 157 | case 3: |
---|
161 | | - *val = (sigma_delta->data[0] << 16) | |
---|
162 | | - (sigma_delta->data[1] << 8) | |
---|
163 | | - sigma_delta->data[2]; |
---|
| 158 | + *val = get_unaligned_be24(sigma_delta->rx_buf); |
---|
164 | 159 | break; |
---|
165 | 160 | case 2: |
---|
166 | | - *val = get_unaligned_be16(sigma_delta->data); |
---|
| 161 | + *val = get_unaligned_be16(sigma_delta->rx_buf); |
---|
167 | 162 | break; |
---|
168 | 163 | case 1: |
---|
169 | | - *val = sigma_delta->data[0]; |
---|
| 164 | + *val = sigma_delta->rx_buf[0]; |
---|
170 | 165 | break; |
---|
171 | 166 | default: |
---|
172 | 167 | ret = -EINVAL; |
---|
.. | .. |
---|
206 | 201 | } |
---|
207 | 202 | EXPORT_SYMBOL_GPL(ad_sd_reset); |
---|
208 | 203 | |
---|
209 | | -static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, |
---|
| 204 | +int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, |
---|
210 | 205 | unsigned int mode, unsigned int channel) |
---|
211 | 206 | { |
---|
212 | 207 | int ret; |
---|
.. | .. |
---|
243 | 238 | |
---|
244 | 239 | return ret; |
---|
245 | 240 | } |
---|
| 241 | +EXPORT_SYMBOL_GPL(ad_sd_calibrate); |
---|
246 | 242 | |
---|
247 | 243 | /** |
---|
248 | 244 | * ad_sd_calibrate_all() - Performs channel calibration |
---|
.. | .. |
---|
281 | 277 | { |
---|
282 | 278 | struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); |
---|
283 | 279 | unsigned int sample, raw_sample; |
---|
| 280 | + unsigned int data_reg; |
---|
284 | 281 | int ret = 0; |
---|
285 | 282 | |
---|
286 | | - if (iio_buffer_enabled(indio_dev)) |
---|
287 | | - return -EBUSY; |
---|
| 283 | + ret = iio_device_claim_direct_mode(indio_dev); |
---|
| 284 | + if (ret) |
---|
| 285 | + return ret; |
---|
288 | 286 | |
---|
289 | | - mutex_lock(&indio_dev->mlock); |
---|
290 | 287 | ad_sigma_delta_set_channel(sigma_delta, chan->address); |
---|
291 | 288 | |
---|
292 | 289 | spi_bus_lock(sigma_delta->spi->master); |
---|
.. | .. |
---|
306 | 303 | if (ret < 0) |
---|
307 | 304 | goto out; |
---|
308 | 305 | |
---|
309 | | - ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA, |
---|
| 306 | + if (sigma_delta->info->data_reg != 0) |
---|
| 307 | + data_reg = sigma_delta->info->data_reg; |
---|
| 308 | + else |
---|
| 309 | + data_reg = AD_SD_REG_DATA; |
---|
| 310 | + |
---|
| 311 | + ret = ad_sd_read_reg(sigma_delta, data_reg, |
---|
310 | 312 | DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8), |
---|
311 | 313 | &raw_sample); |
---|
312 | 314 | |
---|
.. | .. |
---|
320 | 322 | ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); |
---|
321 | 323 | sigma_delta->bus_locked = false; |
---|
322 | 324 | spi_bus_unlock(sigma_delta->spi->master); |
---|
323 | | - mutex_unlock(&indio_dev->mlock); |
---|
| 325 | + iio_device_release_direct_mode(indio_dev); |
---|
324 | 326 | |
---|
325 | 327 | if (ret) |
---|
326 | 328 | return ret; |
---|
.. | .. |
---|
343 | 345 | unsigned int channel; |
---|
344 | 346 | int ret; |
---|
345 | 347 | |
---|
346 | | - ret = iio_triggered_buffer_postenable(indio_dev); |
---|
347 | | - if (ret < 0) |
---|
348 | | - return ret; |
---|
349 | | - |
---|
350 | 348 | channel = find_first_bit(indio_dev->active_scan_mask, |
---|
351 | 349 | indio_dev->masklength); |
---|
352 | 350 | ret = ad_sigma_delta_set_channel(sigma_delta, |
---|
353 | 351 | indio_dev->channels[channel].address); |
---|
354 | 352 | if (ret) |
---|
355 | | - goto err_predisable; |
---|
| 353 | + return ret; |
---|
356 | 354 | |
---|
357 | 355 | spi_bus_lock(sigma_delta->spi->master); |
---|
358 | 356 | sigma_delta->bus_locked = true; |
---|
.. | .. |
---|
369 | 367 | |
---|
370 | 368 | err_unlock: |
---|
371 | 369 | spi_bus_unlock(sigma_delta->spi->master); |
---|
372 | | -err_predisable: |
---|
373 | 370 | |
---|
374 | 371 | return ret; |
---|
375 | 372 | } |
---|
.. | .. |
---|
398 | 395 | struct iio_poll_func *pf = p; |
---|
399 | 396 | struct iio_dev *indio_dev = pf->indio_dev; |
---|
400 | 397 | struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); |
---|
| 398 | + uint8_t *data = sigma_delta->rx_buf; |
---|
401 | 399 | unsigned int reg_size; |
---|
402 | | - uint8_t data[16]; |
---|
403 | | - int ret; |
---|
404 | | - |
---|
405 | | - memset(data, 0x00, 16); |
---|
| 400 | + unsigned int data_reg; |
---|
406 | 401 | |
---|
407 | 402 | reg_size = indio_dev->channels[0].scan_type.realbits + |
---|
408 | 403 | indio_dev->channels[0].scan_type.shift; |
---|
409 | 404 | reg_size = DIV_ROUND_UP(reg_size, 8); |
---|
410 | 405 | |
---|
| 406 | + if (sigma_delta->info->data_reg != 0) |
---|
| 407 | + data_reg = sigma_delta->info->data_reg; |
---|
| 408 | + else |
---|
| 409 | + data_reg = AD_SD_REG_DATA; |
---|
| 410 | + |
---|
411 | 411 | switch (reg_size) { |
---|
412 | 412 | case 4: |
---|
413 | 413 | case 2: |
---|
414 | 414 | case 1: |
---|
415 | | - ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, |
---|
416 | | - reg_size, &data[0]); |
---|
| 415 | + ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, &data[0]); |
---|
417 | 416 | break; |
---|
418 | 417 | case 3: |
---|
419 | 418 | /* We store 24 bit samples in a 32 bit word. Keep the upper |
---|
420 | 419 | * byte set to zero. */ |
---|
421 | | - ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, |
---|
422 | | - reg_size, &data[1]); |
---|
| 420 | + ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, &data[1]); |
---|
423 | 421 | break; |
---|
424 | 422 | } |
---|
425 | 423 | |
---|
.. | .. |
---|
434 | 432 | |
---|
435 | 433 | static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = { |
---|
436 | 434 | .postenable = &ad_sd_buffer_postenable, |
---|
437 | | - .predisable = &iio_triggered_buffer_predisable, |
---|
438 | 435 | .postdisable = &ad_sd_buffer_postdisable, |
---|
439 | 436 | .validate_scan_mask = &iio_validate_scan_mask_onehot, |
---|
440 | 437 | }; |
---|
.. | .. |
---|
489 | 486 | |
---|
490 | 487 | ret = request_irq(sigma_delta->spi->irq, |
---|
491 | 488 | ad_sd_data_rdy_trig_poll, |
---|
492 | | - IRQF_TRIGGER_LOW, |
---|
| 489 | + sigma_delta->info->irq_flags, |
---|
493 | 490 | indio_dev->name, |
---|
494 | 491 | sigma_delta); |
---|
495 | 492 | if (ret) |
---|