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        INIT_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        INIT_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        INIT_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        /* Guaranteed to be aligned with 8 byte boundary */
 372        if (indio_dev->scan_timestamp)
 373                ((s64 *)data)[1] = pf->timestamp;
 374
 375        reg_size = indio_dev->channels[0].scan_type.realbits +
 376                        indio_dev->channels[0].scan_type.shift;
 377        reg_size = DIV_ROUND_UP(reg_size, 8);
 378
 379        switch (reg_size) {
 380        case 4:
 381        case 2:
 382        case 1:
 383                ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
 384                        reg_size, &data[0]);
 385                break;
 386        case 3:
 387                /* We store 24 bit samples in a 32 bit word. Keep the upper
 388                 * byte set to zero. */
 389                ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
 390                        reg_size, &data[1]);
 391                break;
 392        }
 393
 394        iio_push_to_buffers(indio_dev, (uint8_t *)data);
 395
 396        iio_trigger_notify_done(indio_dev->trig);
 397        sigma_delta->irq_dis = false;
 398        enable_irq(sigma_delta->spi->irq);
 399
 400        return IRQ_HANDLED;
 401}
 402
 403static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
 404        .preenable = &iio_sw_buffer_preenable,
 405        .postenable = &ad_sd_buffer_postenable,
 406        .predisable = &iio_triggered_buffer_predisable,
 407        .postdisable = &ad_sd_buffer_postdisable,
 408        .validate_scan_mask = &iio_validate_scan_mask_onehot,
 409};
 410
 411static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
 412{
 413        struct ad_sigma_delta *sigma_delta = private;
 414
 415        complete(&sigma_delta->completion);
 416        disable_irq_nosync(irq);
 417        sigma_delta->irq_dis = true;
 418        iio_trigger_poll(sigma_delta->trig, iio_get_time_ns());
 419
 420        return IRQ_HANDLED;
 421}
 422
 423/**
 424 * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices
 425 * @indio_dev: The IIO device
 426 * @trig: The new trigger
 427 *
 428 * Returns: 0 if the 'trig' matches the trigger registered by the ad_sigma_delta
 429 * device, -EINVAL otherwise.
 430 */
 431int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig)
 432{
 433        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 434
 435        if (sigma_delta->trig != trig)
 436                return -EINVAL;
 437
 438        return 0;
 439}
 440EXPORT_SYMBOL_GPL(ad_sd_validate_trigger);
 441
 442static const struct iio_trigger_ops ad_sd_trigger_ops = {
 443        .owner = THIS_MODULE,
 444};
 445
 446static int ad_sd_probe_trigger(struct iio_dev *indio_dev)
 447{
 448        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 449        int ret;
 450
 451        sigma_delta->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
 452                                                indio_dev->id);
 453        if (sigma_delta->trig == NULL) {
 454                ret = -ENOMEM;
 455                goto error_ret;
 456        }
 457        sigma_delta->trig->ops = &ad_sd_trigger_ops;
 458        init_completion(&sigma_delta->completion);
 459
 460        ret = request_irq(sigma_delta->spi->irq,
 461                          ad_sd_data_rdy_trig_poll,
 462                          IRQF_TRIGGER_LOW,
 463                          indio_dev->name,
 464                          sigma_delta);
 465        if (ret)
 466                goto error_free_trig;
 467
 468        if (!sigma_delta->irq_dis) {
 469                sigma_delta->irq_dis = true;
 470                disable_irq_nosync(sigma_delta->spi->irq);
 471        }
 472        sigma_delta->trig->dev.parent = &sigma_delta->spi->dev;
 473        iio_trigger_set_drvdata(sigma_delta->trig, sigma_delta);
 474
 475        ret = iio_trigger_register(sigma_delta->trig);
 476        if (ret)
 477                goto error_free_irq;
 478
 479        /* select default trigger */
 480        indio_dev->trig = sigma_delta->trig;
 481
 482        return 0;
 483
 484error_free_irq:
 485        free_irq(sigma_delta->spi->irq, sigma_delta);
 486error_free_trig:
 487        iio_trigger_free(sigma_delta->trig);
 488error_ret:
 489        return ret;
 490}
 491
 492static void ad_sd_remove_trigger(struct iio_dev *indio_dev)
 493{
 494        struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
 495
 496        iio_trigger_unregister(sigma_delta->trig);
 497        free_irq(sigma_delta->spi->irq, sigma_delta);
 498        iio_trigger_free(sigma_delta->trig);
 499}
 500
 501/**
 502 * ad_sd_setup_buffer_and_trigger() -
 503 * @indio_dev: The IIO device
 504 */
 505int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev)
 506{
 507        int ret;
 508
 509        ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
 510                        &ad_sd_trigger_handler, &ad_sd_buffer_setup_ops);
 511        if (ret)
 512                return ret;
 513
 514        ret = ad_sd_probe_trigger(indio_dev);
 515        if (ret) {
 516                iio_triggered_buffer_cleanup(indio_dev);
 517                return ret;
 518        }
 519
 520        return 0;
 521}
 522EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger);
 523
 524/**
 525 * ad_sd_cleanup_buffer_and_trigger() -
 526 * @indio_dev: The IIO device
 527 */
 528void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev)
 529{
 530        ad_sd_remove_trigger(indio_dev);
 531        iio_triggered_buffer_cleanup(indio_dev);
 532}
 533EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger);
 534
 535/**
 536 * ad_sd_init() - Initializes a ad_sigma_delta struct
 537 * @sigma_delta: The ad_sigma_delta device
 538 * @indio_dev: The IIO device which the Sigma Delta device is used for
 539 * @spi: The SPI device for the ad_sigma_delta device
 540 * @info: Device specific callbacks and options
 541 *
 542 * This function needs to be called before any other operations are performed on
 543 * the ad_sigma_delta struct.
 544 */
 545int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
 546        struct spi_device *spi, const struct ad_sigma_delta_info *info)
 547{
 548        sigma_delta->spi = spi;
 549        sigma_delta->info = info;
 550        iio_device_set_drvdata(indio_dev, sigma_delta);
 551
 552        return 0;
 553}
 554EXPORT_SYMBOL_GPL(ad_sd_init);
 555
 556MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 557MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs");
 558MODULE_LICENSE("GPL v2");
 559