linux/drivers/staging/iio/meter/ade7758_ring.c
<<
>>
Prefs
   1/*
   2 * ADE7758 Poly Phase Multifunction Energy Metering IC driver
   3 *
   4 * Copyright 2010-2011 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2.
   7 */
   8#include <linux/export.h>
   9#include <linux/interrupt.h>
  10#include <linux/kernel.h>
  11#include <linux/spi/spi.h>
  12#include <linux/slab.h>
  13#include <asm/unaligned.h>
  14
  15#include <linux/iio/iio.h>
  16#include <linux/iio/kfifo_buf.h>
  17#include <linux/iio/trigger_consumer.h>
  18#include "ade7758.h"
  19
  20/**
  21 * ade7758_spi_read_burst() - read data registers
  22 * @indio_dev: the IIO device
  23 **/
  24static int ade7758_spi_read_burst(struct iio_dev *indio_dev)
  25{
  26        struct ade7758_state *st = iio_priv(indio_dev);
  27        int ret;
  28
  29        ret = spi_sync(st->us, &st->ring_msg);
  30        if (ret)
  31                dev_err(&st->us->dev, "problem when reading WFORM value\n");
  32
  33        return ret;
  34}
  35
  36static int ade7758_write_waveform_type(struct device *dev, unsigned type)
  37{
  38        int ret;
  39        u8 reg;
  40
  41        ret = ade7758_spi_read_reg_8(dev,
  42                        ADE7758_WAVMODE,
  43                        &reg);
  44        if (ret)
  45                goto out;
  46
  47        reg &= ~0x1F;
  48        reg |= type & 0x1F;
  49
  50        ret = ade7758_spi_write_reg_8(dev,
  51                        ADE7758_WAVMODE,
  52                        reg);
  53out:
  54        return ret;
  55}
  56
  57/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  58 * specific to be rolled into the core.
  59 */
  60static irqreturn_t ade7758_trigger_handler(int irq, void *p)
  61{
  62        struct iio_poll_func *pf = p;
  63        struct iio_dev *indio_dev = pf->indio_dev;
  64        struct ade7758_state *st = iio_priv(indio_dev);
  65        s64 dat64[2];
  66        u32 *dat32 = (u32 *)dat64;
  67
  68        if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
  69                if (ade7758_spi_read_burst(indio_dev) >= 0)
  70                        *dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
  71
  72        /* Guaranteed to be aligned with 8 byte boundary */
  73        if (indio_dev->scan_timestamp)
  74                dat64[1] = pf->timestamp;
  75
  76        iio_push_to_buffers(indio_dev, (u8 *)dat64);
  77
  78        iio_trigger_notify_done(indio_dev->trig);
  79
  80        return IRQ_HANDLED;
  81}
  82
  83/**
  84 * ade7758_ring_preenable() setup the parameters of the ring before enabling
  85 *
  86 * The complex nature of the setting of the number of bytes per datum is due
  87 * to this driver currently ensuring that the timestamp is stored at an 8
  88 * byte boundary.
  89 **/
  90static int ade7758_ring_preenable(struct iio_dev *indio_dev)
  91{
  92        struct ade7758_state *st = iio_priv(indio_dev);
  93        unsigned channel;
  94        int ret;
  95
  96        if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
  97                return -EINVAL;
  98
  99        ret = iio_sw_buffer_preenable(indio_dev);
 100        if (ret < 0)
 101                return ret;
 102
 103        channel = find_first_bit(indio_dev->active_scan_mask,
 104                                 indio_dev->masklength);
 105
 106        ade7758_write_waveform_type(&indio_dev->dev,
 107                st->ade7758_ring_channels[channel].address);
 108
 109        return 0;
 110}
 111
 112static const struct iio_buffer_setup_ops ade7758_ring_setup_ops = {
 113        .preenable = &ade7758_ring_preenable,
 114        .postenable = &iio_triggered_buffer_postenable,
 115        .predisable = &iio_triggered_buffer_predisable,
 116        .validate_scan_mask = &iio_validate_scan_mask_onehot,
 117};
 118
 119void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 120{
 121        iio_dealloc_pollfunc(indio_dev->pollfunc);
 122        iio_kfifo_free(indio_dev->buffer);
 123}
 124
 125int ade7758_configure_ring(struct iio_dev *indio_dev)
 126{
 127        struct ade7758_state *st = iio_priv(indio_dev);
 128        int ret = 0;
 129
 130        indio_dev->buffer = iio_kfifo_allocate(indio_dev);
 131        if (!indio_dev->buffer) {
 132                ret = -ENOMEM;
 133                return ret;
 134        }
 135
 136        indio_dev->setup_ops = &ade7758_ring_setup_ops;
 137
 138        indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 139                                                 &ade7758_trigger_handler,
 140                                                 0,
 141                                                 indio_dev,
 142                                                 "ade7759_consumer%d",
 143                                                 indio_dev->id);
 144        if (indio_dev->pollfunc == NULL) {
 145                ret = -ENOMEM;
 146                goto error_iio_kfifo_free;
 147        }
 148
 149        indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
 150
 151        st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
 152        st->tx_buf[1] = 0;
 153        st->tx_buf[2] = 0;
 154        st->tx_buf[3] = 0;
 155        st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM);
 156        st->tx_buf[5] = 0;
 157        st->tx_buf[6] = 0;
 158        st->tx_buf[7] = 0;
 159
 160        /* build spi ring message */
 161        st->ring_xfer[0].tx_buf = &st->tx_buf[0];
 162        st->ring_xfer[0].len = 1;
 163        st->ring_xfer[0].bits_per_word = 8;
 164        st->ring_xfer[0].delay_usecs = 4;
 165        st->ring_xfer[1].rx_buf = &st->rx_buf[1];
 166        st->ring_xfer[1].len = 3;
 167        st->ring_xfer[1].bits_per_word = 8;
 168        st->ring_xfer[1].cs_change = 1;
 169
 170        st->ring_xfer[2].tx_buf = &st->tx_buf[4];
 171        st->ring_xfer[2].len = 1;
 172        st->ring_xfer[2].bits_per_word = 8;
 173        st->ring_xfer[2].delay_usecs = 1;
 174        st->ring_xfer[3].rx_buf = &st->rx_buf[5];
 175        st->ring_xfer[3].len = 3;
 176        st->ring_xfer[3].bits_per_word = 8;
 177
 178        spi_message_init(&st->ring_msg);
 179        spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
 180        spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
 181        spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg);
 182        spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg);
 183
 184        return 0;
 185
 186error_iio_kfifo_free:
 187        iio_kfifo_free(indio_dev->buffer);
 188        return ret;
 189}
 190
 191void ade7758_uninitialize_ring(struct iio_dev *indio_dev)
 192{
 193        iio_buffer_unregister(indio_dev);
 194}
 195