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 too 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        iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);
  73
  74        iio_trigger_notify_done(indio_dev->trig);
  75
  76        return IRQ_HANDLED;
  77}
  78
  79/**
  80 * ade7758_ring_preenable() setup the parameters of the ring before enabling
  81 *
  82 * The complex nature of the setting of the number of bytes per datum is due
  83 * to this driver currently ensuring that the timestamp is stored at an 8
  84 * byte boundary.
  85 **/
  86static int ade7758_ring_preenable(struct iio_dev *indio_dev)
  87{
  88        unsigned channel;
  89
  90        if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
  91                return -EINVAL;
  92
  93        channel = find_first_bit(indio_dev->active_scan_mask,
  94                                 indio_dev->masklength);
  95
  96        ade7758_write_waveform_type(&indio_dev->dev,
  97                indio_dev->channels[channel].address);
  98
  99        return 0;
 100}
 101
 102static const struct iio_buffer_setup_ops ade7758_ring_setup_ops = {
 103        .preenable = &ade7758_ring_preenable,
 104        .postenable = &iio_triggered_buffer_postenable,
 105        .predisable = &iio_triggered_buffer_predisable,
 106        .validate_scan_mask = &iio_validate_scan_mask_onehot,
 107};
 108
 109void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 110{
 111        iio_dealloc_pollfunc(indio_dev->pollfunc);
 112        iio_kfifo_free(indio_dev->buffer);
 113}
 114
 115int ade7758_configure_ring(struct iio_dev *indio_dev)
 116{
 117        struct ade7758_state *st = iio_priv(indio_dev);
 118        struct iio_buffer *buffer;
 119        int ret = 0;
 120
 121        buffer = iio_kfifo_allocate();
 122        if (!buffer)
 123                return -ENOMEM;
 124
 125        iio_device_attach_buffer(indio_dev, buffer);
 126
 127        indio_dev->setup_ops = &ade7758_ring_setup_ops;
 128
 129        indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 130                                                 &ade7758_trigger_handler,
 131                                                 0,
 132                                                 indio_dev,
 133                                                 "ade7759_consumer%d",
 134                                                 indio_dev->id);
 135        if (!indio_dev->pollfunc) {
 136                ret = -ENOMEM;
 137                goto error_iio_kfifo_free;
 138        }
 139
 140        indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
 141
 142        st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
 143        st->tx_buf[1] = 0;
 144        st->tx_buf[2] = 0;
 145        st->tx_buf[3] = 0;
 146        st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM);
 147        st->tx_buf[5] = 0;
 148        st->tx_buf[6] = 0;
 149        st->tx_buf[7] = 0;
 150
 151        /* build spi ring message */
 152        st->ring_xfer[0].tx_buf = &st->tx_buf[0];
 153        st->ring_xfer[0].len = 1;
 154        st->ring_xfer[0].bits_per_word = 8;
 155        st->ring_xfer[0].delay_usecs = 4;
 156        st->ring_xfer[1].rx_buf = &st->rx_buf[1];
 157        st->ring_xfer[1].len = 3;
 158        st->ring_xfer[1].bits_per_word = 8;
 159        st->ring_xfer[1].cs_change = 1;
 160
 161        st->ring_xfer[2].tx_buf = &st->tx_buf[4];
 162        st->ring_xfer[2].len = 1;
 163        st->ring_xfer[2].bits_per_word = 8;
 164        st->ring_xfer[2].delay_usecs = 1;
 165        st->ring_xfer[3].rx_buf = &st->rx_buf[5];
 166        st->ring_xfer[3].len = 3;
 167        st->ring_xfer[3].bits_per_word = 8;
 168
 169        spi_message_init(&st->ring_msg);
 170        spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
 171        spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
 172        spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg);
 173        spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg);
 174
 175        return 0;
 176
 177error_iio_kfifo_free:
 178        iio_kfifo_free(indio_dev->buffer);
 179        return ret;
 180}
 181