1/*
2 * Copyright 2010-2011 Analog Devices Inc.
3 * Copyright (C) 2008 Jonathan Cameron
4 *
5 * Licensed under the GPL-2.
6 *
7 * ad7887_ring.c
8 */
9
10#include <linux/interrupt.h>
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/spi/spi.h>
14
15#include "../iio.h"
16#include "../buffer.h"
17#include "../ring_sw.h"
18#include "../trigger_consumer.h"
19
20#include "ad7887.h"
21
22/**
23 * ad7887_ring_preenable() setup the parameters of the ring before enabling
24 *
25 * The complex nature of the setting of the nuber of bytes per datum is due
26 * to this driver currently ensuring that the timestamp is stored at an 8
27 * byte boundary.
28 **/
29static int ad7887_ring_preenable(struct iio_dev *indio_dev)
30{
31	struct ad7887_state *st = iio_priv(indio_dev);
32	struct iio_buffer *ring = indio_dev->buffer;
33
34	st->d_size = bitmap_weight(indio_dev->active_scan_mask,
35				   indio_dev->masklength) *
36		st->chip_info->channel[0].scan_type.storagebits / 8;
37
38	if (ring->scan_timestamp) {
39		st->d_size += sizeof(s64);
40
41		if (st->d_size % sizeof(s64))
42			st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
43	}
44
45	if (indio_dev->buffer->access->set_bytes_per_datum)
46		indio_dev->buffer->access->
47			set_bytes_per_datum(indio_dev->buffer, st->d_size);
48
49	/* We know this is a single long so can 'cheat' */
50	switch (*indio_dev->active_scan_mask) {
51	case (1 << 0):
52		st->ring_msg = &st->msg[AD7887_CH0];
53		break;
54	case (1 << 1):
55		st->ring_msg = &st->msg[AD7887_CH1];
56		/* Dummy read: push CH1 setting down to hardware */
57		spi_sync(st->spi, st->ring_msg);
58		break;
59	case ((1 << 1) | (1 << 0)):
60		st->ring_msg = &st->msg[AD7887_CH0_CH1];
61		break;
62	}
63
64	return 0;
65}
66
67static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
68{
69	struct ad7887_state *st = iio_priv(indio_dev);
70
71	/* dummy read: restore default CH0 settin */
72	return spi_sync(st->spi, &st->msg[AD7887_CH0]);
73}
74
75/**
76 * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
77 *
78 * Currently there is no option in this driver to disable the saving of
79 * timestamps within the ring.
80 **/
81static irqreturn_t ad7887_trigger_handler(int irq, void *p)
82{
83	struct iio_poll_func *pf = p;
84	struct iio_dev *indio_dev = pf->indio_dev;
85	struct ad7887_state *st = iio_priv(indio_dev);
86	struct iio_buffer *ring = indio_dev->buffer;
87	s64 time_ns;
88	__u8 *buf;
89	int b_sent;
90
91	unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask,
92					   indio_dev->masklength) *
93		st->chip_info->channel[0].scan_type.storagebits / 8;
94
95	buf = kzalloc(st->d_size, GFP_KERNEL);
96	if (buf == NULL)
97		return -ENOMEM;
98
99	b_sent = spi_sync(st->spi, st->ring_msg);
100	if (b_sent)
101		goto done;
102
103	time_ns = iio_get_time_ns();
104
105	memcpy(buf, st->data, bytes);
106	if (ring->scan_timestamp)
107		memcpy(buf + st->d_size - sizeof(s64),
108		       &time_ns, sizeof(time_ns));
109
110	indio_dev->buffer->access->store_to(indio_dev->buffer, buf, time_ns);
111done:
112	kfree(buf);
113	iio_trigger_notify_done(indio_dev->trig);
114
115	return IRQ_HANDLED;
116}
117
118static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
119	.preenable = &ad7887_ring_preenable,
120	.postenable = &iio_triggered_buffer_postenable,
121	.predisable = &iio_triggered_buffer_predisable,
122	.postdisable = &ad7887_ring_postdisable,
123};
124
125int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
126{
127	int ret;
128
129	indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
130	if (!indio_dev->buffer) {
131		ret = -ENOMEM;
132		goto error_ret;
133	}
134	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
135						 &ad7887_trigger_handler,
136						 IRQF_ONESHOT,
137						 indio_dev,
138						 "ad7887_consumer%d",
139						 indio_dev->id);
140	if (indio_dev->pollfunc == NULL) {
141		ret = -ENOMEM;
142		goto error_deallocate_sw_rb;
143	}
144	/* Ring buffer functions - here trigger setup related */
145	indio_dev->setup_ops = &ad7887_ring_setup_ops;
146
147	/* Flag that polled ring buffering is possible */
148	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
149	return 0;
150
151error_deallocate_sw_rb:
152	iio_sw_rb_free(indio_dev->buffer);
153error_ret:
154	return ret;
155}
156
157void ad7887_ring_cleanup(struct iio_dev *indio_dev)
158{
159	iio_dealloc_pollfunc(indio_dev->pollfunc);
160	iio_sw_rb_free(indio_dev->buffer);
161}
162