Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ade7758_ring.c
Go to the documentation of this file.
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 "../ring_sw.h"
18 #include "ade7758.h"
19 
24 static 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 
36 static 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,
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,
52  reg);
53 out:
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  */
60 static 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_buffer(indio_dev->buffer, (u8 *)dat64);
77 
78  iio_trigger_notify_done(indio_dev->trig);
79 
80  return IRQ_HANDLED;
81 }
82 
90 static 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 
112 static 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 
119 void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
120 {
121  iio_dealloc_pollfunc(indio_dev->pollfunc);
122  iio_sw_rb_free(indio_dev->buffer);
123 }
124 
125 int 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_sw_rb_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 
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_sw_rb_free;
147  }
148 
149  indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
150 
152  st->tx_buf[1] = 0;
153  st->tx_buf[2] = 0;
154  st->tx_buf[3] = 0;
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 
186 error_iio_sw_rb_free:
187  iio_sw_rb_free(indio_dev->buffer);
188  return ret;
189 }
190 
191 void ade7758_uninitialize_ring(struct iio_dev *indio_dev)
192 {
193  iio_buffer_unregister(indio_dev);
194 }