Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ad7606_ring.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2012 Analog Devices Inc.
3  *
4  * Licensed under the GPL-2.
5  *
6  */
7 
8 #include <linux/interrupt.h>
9 #include <linux/gpio.h>
10 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13 
14 #include <linux/iio/iio.h>
15 #include <linux/iio/buffer.h>
18 
19 #include "ad7606.h"
20 
25 static irqreturn_t ad7606_trigger_handler_th_bh(int irq, void *p)
26 {
27  struct iio_poll_func *pf = p;
28  struct ad7606_state *st = iio_priv(pf->indio_dev);
29 
30  gpio_set_value(st->pdata->gpio_convst, 1);
31 
32  return IRQ_HANDLED;
33 }
34 
44 static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
45 {
46  struct ad7606_state *st = container_of(work_s, struct ad7606_state,
47  poll_work);
48  struct iio_dev *indio_dev = iio_priv_to_dev(st);
49  s64 time_ns;
50  __u8 *buf;
51  int ret;
52 
53  buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
54  if (buf == NULL)
55  return;
56 
57  if (gpio_is_valid(st->pdata->gpio_frstdata)) {
58  ret = st->bops->read_block(st->dev, 1, buf);
59  if (ret)
60  goto done;
61  if (!gpio_get_value(st->pdata->gpio_frstdata)) {
62  /* This should never happen. However
63  * some signal glitch caused by bad PCB desgin or
64  * electrostatic discharge, could cause an extra read
65  * or clock. This allows recovery.
66  */
67  ad7606_reset(st);
68  goto done;
69  }
70  ret = st->bops->read_block(st->dev,
71  st->chip_info->num_channels - 1, buf + 2);
72  if (ret)
73  goto done;
74  } else {
75  ret = st->bops->read_block(st->dev,
76  st->chip_info->num_channels, buf);
77  if (ret)
78  goto done;
79  }
80 
81  time_ns = iio_get_time_ns();
82 
83  if (indio_dev->scan_timestamp)
84  *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
85 
86  iio_push_to_buffer(indio_dev->buffer, buf);
87 done:
88  gpio_set_value(st->pdata->gpio_convst, 0);
89  iio_trigger_notify_done(indio_dev->trig);
90  kfree(buf);
91 }
92 
94 {
95  struct ad7606_state *st = iio_priv(indio_dev);
96 
97  INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
98 
99  return iio_triggered_buffer_setup(indio_dev,
100  &ad7606_trigger_handler_th_bh, &ad7606_trigger_handler_th_bh,
101  NULL);
102 }
103 
104 void ad7606_ring_cleanup(struct iio_dev *indio_dev)
105 {
106  iio_triggered_buffer_cleanup(indio_dev);
107 }