| .. | .. |
|---|
| 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 | 283 | if (iio_buffer_enabled(indio_dev)) |
|---|
| .. | .. |
|---|
| 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 | |
|---|
| .. | .. |
|---|
| 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) |
|---|