linux/drivers/iio/adc/ad_sigma_delta.c
<<
>>
Prefs
   1/*
   2 * Support code for Analog Devices Sigma-Delta ADCs
   3 *
   4 * Copyright 2012 Analog Devices Inc.
   5 *  Author: Lars-Peter Clausen <lars@metafoo.de>
   6 *
   7 * Licensed under the GPL-2.
   8 */
   9
  10#include <linux/interrupt.h>
  11#include <linux/device.h>
  12#include <linux/kernel.h>
  13#include <linux/slab.h>
  14#include <linux/spi/spi.h>
  15#include <linux/err.h>
  16#include <linux/module.h>
  17
  18#include <linux/iio/iio.h>
  19#include <linux/iio/sysfs.h>
  20#include <linux/iio/buffer.h>
  21#include <linux/iio/trigger.h>
  22#include <linux/iio/trigger_consumer.h>
  23#include <linux/iio/triggered_buffer.h>
  24#include <linux/iio/adc/ad_sigma_delta.h>
  25
  26#include <asm/unaligned.h>
  27
  28
  29#define AD_SD_COMM_CHAN_MASK    0x3
  30
  31#define AD_SD_REG_COMM          0x00
  32#define AD_SD_REG_DATA          0x03
  33
  34/**
  35 * ad_sd_set_comm() - Set communications register
  36 *
  37 * @sigma_delta: The sigma delta device
  38 * @comm: New value for the communications register
  39 */
  40void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm)
  41{
  42        /* Some variants use the lower two bits of the communications register
  43         * to select the channel */
  44        sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK;
  45}
  46EXPORT_SYMBOL_GPL(ad_sd_set_comm);
  47
  48/**
  49 * ad_sd_write_reg() - Write a register
  50 *
  51 * @sigma_delta: The sigma delta device
  52 * @reg: Address of the register
  53 * @size: Size of the register (0-3)
  54 * @val: Value to write to the register
  55 *
  56 * Returns 0 on success, an error code otherwise.
  57 **/
  58int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
  59        unsigned int size, unsigned int val)
  60{
  61        uint8_t *data = sigma_delta->data;
  62        struct spi_transfer t = {
  63                .tx_buf         = data,
  64                .len            = size + 1,
  65                .cs_change      = sigma_delta->bus_locked,
  66        };
  67        struct spi_message m;
  68        int ret;
  69
  70        data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm;
  71
  72        switch (size) {
  73        case 3:
  74                data[1] = val >> 16;
  75                data[2] = val >> 8;
  76                data[3] = val;
  77                break;
  78        case 2:
  79                put_unaligned_be16(val, &data[1]);
  80                break;
  81        case 1:
  82                data[1] = val;
  83                break;
  84        case 0:
  85                break;
  86        default:
  87                return -EINVAL;
  88        }
  89
  90        spi_message_init(&m);
  91        spi_message_add_tail(&t, &m);
  92
  93        if (sigma_delta->bus_locked)
  94                ret = spi_sync_locked(sigma_delta->spi, &m);
  95        else
  96                ret = spi_sync(sigma_delta->spi, &m);
  97
  98        return ret;
  99}
 100EXPORT_SYMBOL_GPL(ad_sd_write_reg);
 101
 102static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta,
 103        unsigned int reg, unsigned int size, uint8_t *val)
 104{
 105        uint8_t *data = sigma_delta->data;
 106        int ret;
 107        struct spi_transfer t[] = {
 108                {
 109                        .tx_buf = data,
 110                        .len = 1,
 111                }, {
 112                        .rx_buf = val,
 113                        .len = size,
 114                        .cs_change = sigma_delta->bus_locked,
 115                },
 116        };
 117        struct spi_message m;
 118
 119        spi_message_init(&m);
 120
 121        if (sigma_delta->info->has_registers) {
 122                data[0] = reg << sigma_delta->info->addr_shift;
 123                data[0] |= sigma_delta->info->read_mask;
 124                spi_message_add_tail(&t[0], &m);
 125        }
 126        spi_message_add_tail(&t[1], &m);
 127
 128        if (sigma_delta->bus_locked)
 129                ret = spi_sync_locked(sigma_delta->spi, &m);
 130        else
 131                ret = spi_sync(sigma_delta->spi, &m);
 132
 133        return ret;
 134}
 135
 136/**
 137 * ad_sd_read_reg() - Read a register
 138 *
 139 * @sigma_delta: The sigma delta device
 140 * @reg: Address of the register
 141 * @size: Size of the register (1-4)
 142 * @val: Read value
 143 *
 144 * Returns 0 on success, an error code otherwise.
 145 **/
 146int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta,
 147        unsigned int reg, unsigned int size, unsigned int *val)
 148{
 149        int ret;
 150
 151        ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data);
 152        if (ret < 0)
 153                goto out;
 154
 155        switch (size) {
 156        case 4:
 157                *val = get_unaligned_be32(sigma_delta->data);
 158                break;
 159        case 3:
 160                *val = (sigma_delta->data[0] << 16) |
 161                        (sigma_delta->data[1] << 8) |
 162                        sigma_delta->data[2];
 163                break;
 164        case 2:
 165                *val = get_unaligned_be16(sigma_delta->data);
 166                break;
 167        case 1:
 168                *val = sigma_delta->data[0];
 169                break;
 170        default:
 171                ret = -EINVAL;
 172                break;
 173        }
 174
 175out:
 176        return ret;
 177}
 178EXPORT_SYMBOL_GPL(ad_sd_read_reg);
 179
 180static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
 181        unsigned int mode, unsigned int channel)
 182{
 183        int ret;
 184
 185        ret = ad_sigma_delta_set_channel(sigma_delta, channel);
 186        if (ret)
 187                return ret;
 188
 189        spi_bus_lock(sigma_delta->spi->master);
 190        sigma_delta->bus_locked = true;
 191        reinit_completion(&sigma_delta->completion);
 192
 193        ret = ad_sigma_delta_set_mode(sigma_delta, mode);
 194        if (ret < 0)
 195                goto out;
 196
 197        sigma_delta->irq_dis = false;
 198        enable_irq(sigma_delta->spi->irq);
 199        ret = wait_for_completion_timeout(&sigma_delta->completion, 2*HZ);
 200        if (ret == 0) {
 201                sigma_delta->irq_dis = true;
 202                disable_irq_nosync(sigma_delta->spi->irq);
 203                ret = -EIO;
 204        } else {
 205                ret = 0;
 206        }
 207out:
 208        sigma_delta->bus_locked = false;
 209        spi_bus_unlock(sigma_delta->spi->master);
 210        ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
 211
 212        return ret;
 213}
 214
 215/**
 216 * ad_sd_calibrate_all() - Performs channel calibration
 217 * @sigma_delta: The sigma delta device
 218 * @cb: Array of channels and calibration type to perform
 219 * @n: Number of items in cb
 220 *
 221 * Returns 0 on success, an error code otherwise.
 222 **/
 223int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
 224        const struct ad_sd_calib_data *cb, unsigned int n)
 225{
 226        unsigned int i;
 227        int ret;
 228
 229        for (i = 0; i < n; i++) {
 230                ret = ad_sd_calibrate(sigma_delta, cb[i].mode, cb[i].channel);
 231                if (ret)
 232                        return ret;
 233        }
 234
 235        return 0;
 236}
 237EXPORT_SYMBOL_GPL(ad_sd_calibrate_all);
 238
 239/**
 240 * ad_sigma_delta_single_conversion() - Performs a single data conversion
 241 * @indio_dev: The IIO device
 242 * @chan: The conversion is done for this channel
 243 * @val: Pointer to the location where to store the read value
 244 *
 245 * Returns: 0 on success, an error value otherwise.
 246 */
 247int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
 248        const struct iio_chan_spec *chan, int *val)
 249{
 250        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 251        unsigned int sample, raw_sample;
 252        int ret = 0;
 253
 254        if (iio_buffer_enabled(indio_dev))
 255                return -EBUSY;
 256
 257        mutex_lock(&indio_dev->mlock);
 258        ad_sigma_delta_set_channel(sigma_delta, chan->address);
 259
 260        spi_bus_lock(sigma_delta->spi->master);
 261        sigma_delta->bus_locked = true;
 262        reinit_completion(&sigma_delta->completion);
 263
 264        ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE);
 265
 266        sigma_delta->irq_dis = false;
 267        enable_irq(sigma_delta->spi->irq);
 268        ret = wait_for_completion_interruptible_timeout(
 269                        &sigma_delta->completion, HZ);
 270
 271        sigma_delta->bus_locked = false;
 272        spi_bus_unlock(sigma_delta->spi->master);
 273
 274        if (ret == 0)
 275                ret = -EIO;
 276        if (ret < 0)
 277                goto out;
 278
 279        ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA,
 280                DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8),
 281                &raw_sample);
 282
 283out:
 284        if (!sigma_delta->irq_dis) {
 285                disable_irq_nosync(sigma_delta->spi->irq);
 286                sigma_delta->irq_dis = true;
 287        }
 288
 289        ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
 290        mutex_unlock(&indio_dev->mlock);
 291
 292        if (ret)
 293                return ret;
 294
 295        sample = raw_sample >> chan->scan_type.shift;
 296        sample &= (1 << chan->scan_type.realbits) - 1;
 297        *val = sample;
 298
 299        ret = ad_sigma_delta_postprocess_sample(sigma_delta, raw_sample);
 300        if (ret)
 301                return ret;
 302
 303        return IIO_VAL_INT;
 304}
 305EXPORT_SYMBOL_GPL(ad_sigma_delta_single_conversion);
 306
 307static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
 308{
 309        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 310        unsigned int channel;
 311        int ret;
 312
 313        ret = iio_triggered_buffer_postenable(indio_dev);
 314        if (ret < 0)
 315                return ret;
 316
 317        channel = find_first_bit(indio_dev->active_scan_mask,
 318                                 indio_dev->masklength);
 319        ret = ad_sigma_delta_set_channel(sigma_delta,
 320                indio_dev->channels[channel].address);
 321        if (ret)
 322                goto err_predisable;
 323
 324        spi_bus_lock(sigma_delta->spi->master);
 325        sigma_delta->bus_locked = true;
 326        ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS);
 327        if (ret)
 328                goto err_unlock;
 329
 330        sigma_delta->irq_dis = false;
 331        enable_irq(sigma_delta->spi->irq);
 332
 333        return 0;
 334
 335err_unlock:
 336        spi_bus_unlock(sigma_delta->spi->master);
 337err_predisable:
 338
 339        return ret;
 340}
 341
 342static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
 343{
 344        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 345
 346        reinit_completion(&sigma_delta->completion);
 347        wait_for_completion_timeout(&sigma_delta->completion, HZ);
 348
 349        if (!sigma_delta->irq_dis) {
 350                disable_irq_nosync(sigma_delta->spi->irq);
 351                sigma_delta->irq_dis = true;
 352        }
 353
 354        ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
 355
 356        sigma_delta->bus_locked = false;
 357        return spi_bus_unlock(sigma_delta->spi->master);
 358}
 359
 360static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
 361{
 362        struct iio_poll_func *pf = p;
 363        struct iio_dev *indio_dev = pf->indio_dev;
 364        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 365        unsigned int reg_size;
 366        uint8_t data[16];
 367        int ret;
 368
 369        memset(data, 0x00, 16);
 370
 371        reg_size = indio_dev->channels[0].scan_type.realbits +
 372                        indio_dev->channels[0].scan_type.shift;
 373        reg_size = DIV_ROUND_UP(reg_size, 8);
 374
 375        switch (reg_size) {
 376        case 4:
 377        case 2:
 378        case 1:
 379                ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
 380                        reg_size, &data[0]);
 381                break;
 382        case 3:
 383                /* We store 24 bit samples in a 32 bit word. Keep the upper
 384                 * byte set to zero. */
 385                ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
 386                        reg_size, &data[1]);
 387                break;
 388        }
 389
 390        iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
 391
 392        iio_trigger_notify_done(indio_dev->trig);
 393        sigma_delta->irq_dis = false;
 394        enable_irq(sigma_delta->spi->irq);
 395
 396        return IRQ_HANDLED;
 397}
 398
 399static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
 400        .postenable = &ad_sd_buffer_postenable,
 401        .predisable = &iio_triggered_buffer_predisable,
 402        .postdisable = &ad_sd_buffer_postdisable,
 403        .validate_scan_mask = &iio_validate_scan_mask_onehot,
 404};
 405
 406static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
 407{
 408        struct ad_sigma_delta *sigma_delta = private;
 409
 410        complete(&sigma_delta->completion);
 411        disable_irq_nosync(irq);
 412        sigma_delta->irq_dis = true;
 413        iio_trigger_poll(sigma_delta->trig);
 414
 415        return IRQ_HANDLED;
 416}
 417
 418/**
 419 * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices
 420 * @indio_dev: The IIO device
 421 * @trig: The new trigger
 422 *
 423 * Returns: 0 if the 'trig' matches the trigger registered by the ad_sigma_delta
 424 * device, -EINVAL otherwise.
 425 */
 426int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig)
 427{
 428        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 429
 430        if (sigma_delta->trig != trig)
 431                return -EINVAL;
 432
 433        return 0;
 434}
 435EXPORT_SYMBOL_GPL(ad_sd_validate_trigger);
 436
 437static const struct iio_trigger_ops ad_sd_trigger_ops = {
 438        .owner = THIS_MODULE,
 439};
 440
 441static int ad_sd_probe_trigger(struct iio_dev *indio_dev)
 442{
 443        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 444        int ret;
 445
 446        sigma_delta->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
 447                                                indio_dev->id);
 448        if (sigma_delta->trig == NULL) {
 449                ret = -ENOMEM;
 450                goto error_ret;
 451        }
 452        sigma_delta->trig->ops = &ad_sd_trigger_ops;
 453        init_completion(&sigma_delta->completion);
 454
 455        ret = request_irq(sigma_delta->spi->irq,
 456                          ad_sd_data_rdy_trig_poll,
 457                          IRQF_TRIGGER_LOW,
 458                          indio_dev->name,
 459                          sigma_delta);
 460        if (ret)
 461                goto error_free_trig;
 462
 463        if (!sigma_delta->irq_dis) {
 464                sigma_delta->irq_dis = true;
 465                disable_irq_nosync(sigma_delta->spi->irq);
 466        }
 467        sigma_delta->trig->dev.parent = &sigma_delta->spi->dev;
 468        iio_trigger_set_drvdata(sigma_delta->trig, sigma_delta);
 469
 470        ret = iio_trigger_register(sigma_delta->trig);
 471        if (ret)
 472                goto error_free_irq;
 473
 474        /* select default trigger */
 475        indio_dev->trig = iio_trigger_get(sigma_delta->trig);
 476
 477        return 0;
 478
 479error_free_irq:
 480        free_irq(sigma_delta->spi->irq, sigma_delta);
 481error_free_trig:
 482        iio_trigger_free(sigma_delta->trig);
 483error_ret:
 484        return ret;
 485}
 486
 487static void ad_sd_remove_trigger(struct iio_dev *indio_dev)
 488{
 489        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 490
 491        iio_trigger_unregister(sigma_delta->trig);
 492        free_irq(sigma_delta->spi->irq, sigma_delta);
 493        iio_trigger_free(sigma_delta->trig);
 494}
 495
 496/**
 497 * ad_sd_setup_buffer_and_trigger() -
 498 * @indio_dev: The IIO device
 499 */
 500int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev)
 501{
 502        int ret;
 503
 504        ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
 505                        &ad_sd_trigger_handler, &ad_sd_buffer_setup_ops);
 506        if (ret)
 507                return ret;
 508
 509        ret = ad_sd_probe_trigger(indio_dev);
 510        if (ret) {
 511                iio_triggered_buffer_cleanup(indio_dev);
 512                return ret;
 513        }
 514
 515        return 0;
 516}
 517EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger);
 518
 519/**
 520 * ad_sd_cleanup_buffer_and_trigger() -
 521 * @indio_dev: The IIO device
 522 */
 523void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev)
 524{
 525        ad_sd_remove_trigger(indio_dev);
 526        iio_triggered_buffer_cleanup(indio_dev);
 527}
 528EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger);
 529
 530/**
 531 * ad_sd_init() - Initializes a ad_sigma_delta struct
 532 * @sigma_delta: The ad_sigma_delta device
 533 * @indio_dev: The IIO device which the Sigma Delta device is used for
 534 * @spi: The SPI device for the ad_sigma_delta device
 535 * @info: Device specific callbacks and options
 536 *
 537 * This function needs to be called before any other operations are performed on
 538 * the ad_sigma_delta struct.
 539 */
 540int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
 541        struct spi_device *spi, const struct ad_sigma_delta_info *info)
 542{
 543        sigma_delta->spi = spi;
 544        sigma_delta->info = info;
 545        iio_device_set_drvdata(indio_dev, sigma_delta);
 546
 547        return 0;
 548}
 549EXPORT_SYMBOL_GPL(ad_sd_init);
 550
 551MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 552MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs");
 553MODULE_LICENSE("GPL v2");
 554