Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
adis16201_ring.c
Go to the documentation of this file.
1 #include <linux/export.h>
2 #include <linux/interrupt.h>
3 #include <linux/mutex.h>
4 #include <linux/kernel.h>
5 #include <linux/spi/spi.h>
6 #include <linux/slab.h>
7 
8 #include <linux/iio/iio.h>
9 #include "../ring_sw.h"
11 #include "adis16201.h"
12 
13 
19 static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
20 {
21  struct spi_message msg;
22  struct adis16201_state *st = iio_priv(indio_dev);
23  struct spi_transfer xfers[ADIS16201_OUTPUTS + 1];
24  int ret;
25  int i;
26 
27  mutex_lock(&st->buf_lock);
28 
29  spi_message_init(&msg);
30 
31  memset(xfers, 0, sizeof(xfers));
32  for (i = 0; i <= ADIS16201_OUTPUTS; i++) {
33  xfers[i].bits_per_word = 8;
34  xfers[i].cs_change = 1;
35  xfers[i].len = 2;
36  xfers[i].delay_usecs = 20;
37  if (i < ADIS16201_OUTPUTS) {
38  xfers[i].tx_buf = st->tx + 2 * i;
40  2 * i);
41  st->tx[2 * i + 1] = 0;
42  }
43  if (i >= 1)
44  xfers[i].rx_buf = rx + 2 * (i - 1);
45  spi_message_add_tail(&xfers[i], &msg);
46  }
47 
48  ret = spi_sync(st->us, &msg);
49  if (ret)
50  dev_err(&st->us->dev, "problem when burst reading");
51 
52  mutex_unlock(&st->buf_lock);
53 
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 adis16201_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 adis16201_state *st = iio_priv(indio_dev);
65 
66  int i = 0;
67  s16 *data;
68 
69  data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
70  if (data == NULL) {
71  dev_err(&st->us->dev, "memory alloc failed in ring bh");
72  goto done;
73  }
74 
75  if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)
76  && adis16201_read_ring_data(indio_dev, st->rx) >= 0)
77  for (; i < bitmap_weight(indio_dev->active_scan_mask,
78  indio_dev->masklength); i++)
79  data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
80 
81  /* Guaranteed to be aligned with 8 byte boundary */
82  if (indio_dev->scan_timestamp)
83  *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
84 
85  iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
86 
87  kfree(data);
88 done:
89  iio_trigger_notify_done(indio_dev->trig);
90 
91  return IRQ_HANDLED;
92 }
93 
94 void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
95 {
96  iio_dealloc_pollfunc(indio_dev->pollfunc);
97  iio_sw_rb_free(indio_dev->buffer);
98 }
99 
100 static const struct iio_buffer_setup_ops adis16201_ring_setup_ops = {
101  .preenable = &iio_sw_buffer_preenable,
102  .postenable = &iio_triggered_buffer_postenable,
103  .predisable = &iio_triggered_buffer_predisable,
104 };
105 
106 int adis16201_configure_ring(struct iio_dev *indio_dev)
107 {
108  int ret = 0;
109  struct iio_buffer *ring;
110 
111  ring = iio_sw_rb_allocate(indio_dev);
112  if (!ring) {
113  ret = -ENOMEM;
114  return ret;
115  }
116  indio_dev->buffer = ring;
117  ring->scan_timestamp = true;
118  indio_dev->setup_ops = &adis16201_ring_setup_ops;
119 
121  &adis16201_trigger_handler,
122  IRQF_ONESHOT,
123  indio_dev,
124  "adis16201_consumer%d",
125  indio_dev->id);
126  if (indio_dev->pollfunc == NULL) {
127  ret = -ENOMEM;
128  goto error_iio_sw_rb_free;
129  }
130 
131  indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
132  return 0;
133 error_iio_sw_rb_free:
134  iio_sw_rb_free(indio_dev->buffer);
135  return ret;
136 }