blob: af6780a4fe7dbd13a1c24e8853477ab1c402f980 [file] [log] [blame]
Michael Hennerichb9618c02011-02-22 21:46:18 +01001/*
2 * Copyright 2011 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2.
5 *
6 */
7
8#include <linux/interrupt.h>
9#include <linux/gpio.h>
Michael Hennerichb9618c02011-02-22 21:46:18 +010010#include <linux/device.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
Michael Hennerichb9618c02011-02-22 21:46:18 +010013
14#include "../iio.h"
Jonathan Cameronaf5046a2011-10-26 17:41:32 +010015#include "../buffer.h"
Michael Hennerichb9618c02011-02-22 21:46:18 +010016#include "../ring_sw.h"
Jonathan Cameron3f723952011-08-24 17:28:39 +010017#include "../trigger_consumer.h"
Michael Hennerichb9618c02011-02-22 21:46:18 +010018
19#include "ad7606.h"
20
Michael Hennerich44039a62011-05-18 14:42:28 +010021int ad7606_scan_from_ring(struct iio_dev *indio_dev, unsigned ch)
Michael Hennerichb9618c02011-02-22 21:46:18 +010022{
Jonathan Cameron14555b12011-09-21 11:15:57 +010023 struct iio_buffer *ring = indio_dev->buffer;
Michael Hennerichb9618c02011-02-22 21:46:18 +010024 int ret;
25 u16 *ring_data;
26
Jonathan Cameron5565a452011-05-18 14:42:24 +010027 ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
Michael Henneriche61181d2011-05-18 14:42:01 +010028 GFP_KERNEL);
Michael Hennerichb9618c02011-02-22 21:46:18 +010029 if (ring_data == NULL) {
30 ret = -ENOMEM;
31 goto error_ret;
32 }
Jonathan Cameron5565a452011-05-18 14:42:24 +010033 ret = ring->access->read_last(ring, (u8 *) ring_data);
Michael Hennerichb9618c02011-02-22 21:46:18 +010034 if (ret)
35 goto error_free_ring_data;
36
37 ret = ring_data[ch];
38
39error_free_ring_data:
40 kfree(ring_data);
41error_ret:
42 return ret;
43}
44
45/**
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010046 * ad7606_trigger_handler_th() th/bh of trigger launched polling to ring buffer
Michael Hennerichb9618c02011-02-22 21:46:18 +010047 *
48 **/
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010049static irqreturn_t ad7606_trigger_handler_th_bh(int irq, void *p)
Michael Hennerichb9618c02011-02-22 21:46:18 +010050{
Jonathan Cameron13cfac22011-05-18 14:41:38 +010051 struct iio_poll_func *pf = p;
Jonathan Camerone65bc6a2011-08-24 17:28:36 +010052 struct ad7606_state *st = iio_priv(pf->indio_dev);
Michael Hennerich1caf7cb2011-05-18 14:42:00 +010053
Michael Hennerichb9618c02011-02-22 21:46:18 +010054 gpio_set_value(st->pdata->gpio_convst, 1);
55
Jonathan Cameron13cfac22011-05-18 14:41:38 +010056 return IRQ_HANDLED;
Michael Hennerichb9618c02011-02-22 21:46:18 +010057}
Jonathan Cameron13cfac22011-05-18 14:41:38 +010058
Michael Hennerichb9618c02011-02-22 21:46:18 +010059/**
60 * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer
61 * @work_s: the work struct through which this was scheduled
62 *
63 * Currently there is no option in this driver to disable the saving of
64 * timestamps within the ring.
65 * I think the one copy of this at a time was to avoid problems if the
66 * trigger was set far too high and the reads then locked up the computer.
67 **/
68static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
69{
70 struct ad7606_state *st = container_of(work_s, struct ad7606_state,
71 poll_work);
Michael Henneriche61181d2011-05-18 14:42:01 +010072 struct iio_dev *indio_dev = iio_priv_to_dev(st);
Jonathan Cameron14555b12011-09-21 11:15:57 +010073 struct iio_buffer *ring = indio_dev->buffer;
Michael Hennerichb9618c02011-02-22 21:46:18 +010074 s64 time_ns;
75 __u8 *buf;
76 int ret;
77
Jonathan Cameron4f5495d2011-09-30 10:05:41 +010078 buf = kzalloc(ring->access->get_bytes_per_datum(ring),
79 GFP_KERNEL);
Michael Hennerichb9618c02011-02-22 21:46:18 +010080 if (buf == NULL)
81 return;
82
Jonathan Cameron68b41ae2011-09-30 10:05:40 +010083 if (gpio_is_valid(st->pdata->gpio_frstdata)) {
Michael Hennerichb9618c02011-02-22 21:46:18 +010084 ret = st->bops->read_block(st->dev, 1, buf);
85 if (ret)
86 goto done;
87 if (!gpio_get_value(st->pdata->gpio_frstdata)) {
88 /* This should never happen. However
89 * some signal glitch caused by bad PCB desgin or
90 * electrostatic discharge, could cause an extra read
91 * or clock. This allows recovery.
92 */
93 ad7606_reset(st);
94 goto done;
95 }
96 ret = st->bops->read_block(st->dev,
97 st->chip_info->num_channels - 1, buf + 2);
98 if (ret)
99 goto done;
100 } else {
101 ret = st->bops->read_block(st->dev,
102 st->chip_info->num_channels, buf);
103 if (ret)
104 goto done;
105 }
106
107 time_ns = iio_get_time_ns();
Michael Hennerichdcfb0862011-02-24 22:19:49 +0100108
109 if (ring->scan_timestamp)
Jonathan Cameron4f5495d2011-09-30 10:05:41 +0100110 *((s64 *)(buf + ring->access->get_bytes_per_datum(ring) -
111 sizeof(s64))) = time_ns;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100112
Jonathan Cameron14555b12011-09-21 11:15:57 +0100113 ring->access->store_to(indio_dev->buffer, buf, time_ns);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100114done:
115 gpio_set_value(st->pdata->gpio_convst, 0);
Michael Hennerich1caf7cb2011-05-18 14:42:00 +0100116 iio_trigger_notify_done(indio_dev->trig);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100117 kfree(buf);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100118}
119
Jonathan Cameron14555b12011-09-21 11:15:57 +0100120static const struct iio_buffer_setup_ops ad7606_ring_setup_ops = {
Jonathan Cameron4f5495d2011-09-30 10:05:41 +0100121 .preenable = &iio_sw_buffer_preenable,
Jonathan Cameron3b99fb72011-09-21 11:15:53 +0100122 .postenable = &iio_triggered_buffer_postenable,
123 .predisable = &iio_triggered_buffer_predisable,
Jonathan Cameron5565a452011-05-18 14:42:24 +0100124};
125
Michael Hennerichb9618c02011-02-22 21:46:18 +0100126int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
127{
Michael Hennerich44039a62011-05-18 14:42:28 +0100128 struct ad7606_state *st = iio_priv(indio_dev);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100129 int ret;
130
Jonathan Cameron14555b12011-09-21 11:15:57 +0100131 indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
132 if (!indio_dev->buffer) {
Michael Hennerichb9618c02011-02-22 21:46:18 +0100133 ret = -ENOMEM;
134 goto error_ret;
135 }
136
137 /* Effectively select the ring buffer implementation */
Jonathan Cameron14555b12011-09-21 11:15:57 +0100138 indio_dev->buffer->access = &ring_sw_access_funcs;
Jonathan Cameron4f5495d2011-09-30 10:05:41 +0100139 indio_dev->buffer->bpe =
140 st->chip_info->channels[0].scan_type.storagebits / 8;
Jonathan Cameron0ed731d2011-05-18 14:42:39 +0100141 indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh,
142 &ad7606_trigger_handler_th_bh,
143 0,
144 indio_dev,
145 "%s_consumer%d",
146 indio_dev->name,
147 indio_dev->id);
Jonathan Cameron13cfac22011-05-18 14:41:38 +0100148 if (indio_dev->pollfunc == NULL) {
149 ret = -ENOMEM;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100150 goto error_deallocate_sw_rb;
Jonathan Cameron13cfac22011-05-18 14:41:38 +0100151 }
Michael Hennerich1caf7cb2011-05-18 14:42:00 +0100152
Michael Hennerichb9618c02011-02-22 21:46:18 +0100153 /* Ring buffer functions - here trigger setup related */
154
Jonathan Cameron14555b12011-09-21 11:15:57 +0100155 indio_dev->buffer->setup_ops = &ad7606_ring_setup_ops;
156 indio_dev->buffer->scan_timestamp = true ;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100157
158 INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
159
160 /* Flag that polled ring buffering is possible */
Jonathan Cameronec3afa42011-09-21 11:15:54 +0100161 indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
Michael Hennerichb9618c02011-02-22 21:46:18 +0100162 return 0;
Jonathan Cameron0ed731d2011-05-18 14:42:39 +0100163
Michael Hennerichb9618c02011-02-22 21:46:18 +0100164error_deallocate_sw_rb:
Jonathan Cameron14555b12011-09-21 11:15:57 +0100165 iio_sw_rb_free(indio_dev->buffer);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100166error_ret:
167 return ret;
168}
169
170void ad7606_ring_cleanup(struct iio_dev *indio_dev)
171{
Jonathan Cameron0ed731d2011-05-18 14:42:39 +0100172 iio_dealloc_pollfunc(indio_dev->pollfunc);
Jonathan Cameron14555b12011-09-21 11:15:57 +0100173 iio_sw_rb_free(indio_dev->buffer);
Michael Hennerichb9618c02011-02-22 21:46:18 +0100174}