linux/drivers/iio/imu/adis16400_buffer.c
<<
>>
Prefs
   1#include <linux/interrupt.h>
   2#include <linux/mutex.h>
   3#include <linux/kernel.h>
   4#include <linux/spi/spi.h>
   5#include <linux/slab.h>
   6#include <linux/bitops.h>
   7#include <linux/export.h>
   8
   9#include <linux/iio/iio.h>
  10#include <linux/iio/buffer.h>
  11#include <linux/iio/triggered_buffer.h>
  12#include <linux/iio/trigger_consumer.h>
  13
  14#include "adis16400.h"
  15
  16int adis16400_update_scan_mode(struct iio_dev *indio_dev,
  17        const unsigned long *scan_mask)
  18{
  19        struct adis16400_state *st = iio_priv(indio_dev);
  20        struct adis *adis = &st->adis;
  21        uint16_t *tx, *rx;
  22
  23        if (st->variant->flags & ADIS16400_NO_BURST)
  24                return adis_update_scan_mode(indio_dev, scan_mask);
  25
  26        kfree(adis->xfer);
  27        kfree(adis->buffer);
  28
  29        adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL);
  30        if (!adis->xfer)
  31                return -ENOMEM;
  32
  33        adis->buffer = kzalloc(indio_dev->scan_bytes + sizeof(u16),
  34                GFP_KERNEL);
  35        if (!adis->buffer)
  36                return -ENOMEM;
  37
  38        rx = adis->buffer;
  39        tx = adis->buffer + indio_dev->scan_bytes;
  40
  41        tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
  42        tx[1] = 0;
  43
  44        adis->xfer[0].tx_buf = tx;
  45        adis->xfer[0].bits_per_word = 8;
  46        adis->xfer[0].len = 2;
  47        adis->xfer[1].tx_buf = tx;
  48        adis->xfer[1].bits_per_word = 8;
  49        adis->xfer[1].len = indio_dev->scan_bytes;
  50
  51        spi_message_init(&adis->msg);
  52        spi_message_add_tail(&adis->xfer[0], &adis->msg);
  53        spi_message_add_tail(&adis->xfer[1], &adis->msg);
  54
  55        return 0;
  56}
  57
  58irqreturn_t adis16400_trigger_handler(int irq, void *p)
  59{
  60        struct iio_poll_func *pf = p;
  61        struct iio_dev *indio_dev = pf->indio_dev;
  62        struct adis16400_state *st = iio_priv(indio_dev);
  63        struct adis *adis = &st->adis;
  64        u32 old_speed_hz = st->adis.spi->max_speed_hz;
  65        int ret;
  66
  67        if (!adis->buffer)
  68                return -ENOMEM;
  69
  70        if (!(st->variant->flags & ADIS16400_NO_BURST) &&
  71                st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) {
  72                st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST;
  73                spi_setup(st->adis.spi);
  74        }
  75
  76        ret = spi_sync(adis->spi, &adis->msg);
  77        if (ret)
  78                dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret);
  79
  80        if (!(st->variant->flags & ADIS16400_NO_BURST)) {
  81                st->adis.spi->max_speed_hz = old_speed_hz;
  82                spi_setup(st->adis.spi);
  83        }
  84
  85        /* Guaranteed to be aligned with 8 byte boundary */
  86        if (indio_dev->scan_timestamp) {
  87                void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
  88                *(s64 *)b = pf->timestamp;
  89        }
  90
  91        iio_push_to_buffers(indio_dev, adis->buffer);
  92
  93        iio_trigger_notify_done(indio_dev->trig);
  94
  95        return IRQ_HANDLED;
  96}
  97