Commit | Line | Data |
---|---|---|
349282d8 MH |
1 | /* |
2 | * Copyright 2010 Analog Devices Inc. | |
3 | * Copyright (C) 2008 Jonathan Cameron | |
4 | * | |
5 | * Licensed under the GPL-2 or later. | |
6 | * | |
7 | * ad7476_ring.c | |
8 | */ | |
9 | ||
10 | #include <linux/interrupt.h> | |
11 | #include <linux/gpio.h> | |
12 | #include <linux/workqueue.h> | |
13 | #include <linux/device.h> | |
14 | #include <linux/kernel.h> | |
15 | #include <linux/slab.h> | |
16 | #include <linux/sysfs.h> | |
17 | #include <linux/list.h> | |
18 | #include <linux/spi/spi.h> | |
19 | ||
20 | #include "../iio.h" | |
21 | #include "../ring_generic.h" | |
22 | #include "../ring_sw.h" | |
23 | #include "../trigger.h" | |
24 | #include "../sysfs.h" | |
25 | ||
26 | #include "ad7476.h" | |
27 | ||
28 | static IIO_SCAN_EL_C(in0, 0, 0, NULL); | |
86f702ab MH |
29 | static IIO_SCAN_EL_TIMESTAMP(1); |
30 | static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); | |
349282d8 MH |
31 | |
32 | static ssize_t ad7476_show_type(struct device *dev, | |
33 | struct device_attribute *attr, | |
34 | char *buf) | |
35 | { | |
36 | struct iio_ring_buffer *ring = dev_get_drvdata(dev); | |
37 | struct iio_dev *indio_dev = ring->indio_dev; | |
38 | struct ad7476_state *st = indio_dev->dev_data; | |
39 | ||
40 | return sprintf(buf, "%c%d/%d>>%d\n", st->chip_info->sign, | |
41 | st->chip_info->bits, st->chip_info->storagebits, | |
42 | st->chip_info->res_shift); | |
43 | } | |
44 | static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7476_show_type, NULL, 0); | |
45 | ||
46 | static struct attribute *ad7476_scan_el_attrs[] = { | |
47 | &iio_scan_el_in0.dev_attr.attr, | |
48 | &iio_const_attr_in0_index.dev_attr.attr, | |
86f702ab MH |
49 | &iio_const_attr_timestamp_index.dev_attr.attr, |
50 | &iio_scan_el_timestamp.dev_attr.attr, | |
51 | &iio_const_attr_timestamp_type.dev_attr.attr, | |
349282d8 MH |
52 | &iio_dev_attr_in_type.dev_attr.attr, |
53 | NULL, | |
54 | }; | |
55 | ||
56 | static struct attribute_group ad7476_scan_el_group = { | |
57 | .name = "scan_elements", | |
58 | .attrs = ad7476_scan_el_attrs, | |
59 | }; | |
60 | ||
61 | int ad7476_scan_from_ring(struct ad7476_state *st) | |
62 | { | |
63 | struct iio_ring_buffer *ring = st->indio_dev->ring; | |
64 | int ret; | |
65 | u8 *ring_data; | |
66 | ||
67 | ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL); | |
68 | if (ring_data == NULL) { | |
69 | ret = -ENOMEM; | |
70 | goto error_ret; | |
71 | } | |
72 | ret = ring->access.read_last(ring, ring_data); | |
73 | if (ret) | |
74 | goto error_free_ring_data; | |
75 | ||
76 | ret = (ring_data[0] << 8) | ring_data[1]; | |
77 | ||
78 | error_free_ring_data: | |
79 | kfree(ring_data); | |
80 | error_ret: | |
81 | return ret; | |
82 | } | |
83 | ||
84 | /** | |
85 | * ad7476_ring_preenable() setup the parameters of the ring before enabling | |
86 | * | |
87 | * The complex nature of the setting of the nuber of bytes per datum is due | |
88 | * to this driver currently ensuring that the timestamp is stored at an 8 | |
89 | * byte boundary. | |
90 | **/ | |
91 | static int ad7476_ring_preenable(struct iio_dev *indio_dev) | |
92 | { | |
93 | struct ad7476_state *st = indio_dev->dev_data; | |
86f702ab | 94 | struct iio_ring_buffer *ring = indio_dev->ring; |
349282d8 | 95 | |
86f702ab MH |
96 | st->d_size = ring->scan_count * st->chip_info->storagebits / 8; |
97 | ||
98 | if (ring->scan_timestamp) { | |
99 | st->d_size += sizeof(s64); | |
100 | ||
101 | if (st->d_size % sizeof(s64)) | |
102 | st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); | |
349282d8 MH |
103 | } |
104 | ||
86f702ab MH |
105 | if (indio_dev->ring->access.set_bytes_per_datum) |
106 | indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, | |
107 | st->d_size); | |
108 | ||
349282d8 MH |
109 | return 0; |
110 | } | |
111 | ||
112 | /** | |
113 | * ad7476_poll_func_th() th of trigger launched polling to ring buffer | |
114 | * | |
25985edc | 115 | * As sampling only occurs on i2c comms occurring, leave timestamping until |
349282d8 MH |
116 | * then. Some triggers will generate their own time stamp. Currently |
117 | * there is no way of notifying them when no one cares. | |
118 | **/ | |
119 | static void ad7476_poll_func_th(struct iio_dev *indio_dev, s64 time) | |
120 | { | |
121 | struct ad7476_state *st = indio_dev->dev_data; | |
122 | ||
123 | schedule_work(&st->poll_work); | |
124 | return; | |
125 | } | |
126 | /** | |
127 | * ad7476_poll_bh_to_ring() bh of trigger launched polling to ring buffer | |
128 | * @work_s: the work struct through which this was scheduled | |
129 | * | |
130 | * Currently there is no option in this driver to disable the saving of | |
131 | * timestamps within the ring. | |
132 | * I think the one copy of this at a time was to avoid problems if the | |
133 | * trigger was set far too high and the reads then locked up the computer. | |
134 | **/ | |
135 | static void ad7476_poll_bh_to_ring(struct work_struct *work_s) | |
136 | { | |
137 | struct ad7476_state *st = container_of(work_s, struct ad7476_state, | |
138 | poll_work); | |
139 | struct iio_dev *indio_dev = st->indio_dev; | |
140 | struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring); | |
141 | s64 time_ns; | |
142 | __u8 *rxbuf; | |
143 | int b_sent; | |
349282d8 MH |
144 | |
145 | /* Ensure only one copy of this function running at a time */ | |
146 | if (atomic_inc_return(&st->protect_ring) > 1) | |
147 | return; | |
148 | ||
86f702ab | 149 | rxbuf = kzalloc(st->d_size, GFP_KERNEL); |
349282d8 MH |
150 | if (rxbuf == NULL) |
151 | return; | |
152 | ||
153 | b_sent = spi_read(st->spi, rxbuf, st->chip_info->storagebits / 8); | |
154 | if (b_sent < 0) | |
155 | goto done; | |
156 | ||
157 | time_ns = iio_get_time_ns(); | |
158 | ||
86f702ab MH |
159 | if (indio_dev->ring->scan_timestamp) |
160 | memcpy(rxbuf + st->d_size - sizeof(s64), | |
161 | &time_ns, sizeof(time_ns)); | |
349282d8 MH |
162 | |
163 | indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns); | |
164 | done: | |
165 | kfree(rxbuf); | |
166 | atomic_dec(&st->protect_ring); | |
167 | } | |
168 | ||
169 | int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) | |
170 | { | |
171 | struct ad7476_state *st = indio_dev->dev_data; | |
172 | int ret = 0; | |
173 | ||
174 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | |
175 | if (!indio_dev->ring) { | |
176 | ret = -ENOMEM; | |
177 | goto error_ret; | |
178 | } | |
179 | /* Effectively select the ring buffer implementation */ | |
180 | iio_ring_sw_register_funcs(&indio_dev->ring->access); | |
181 | ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7476_poll_func_th); | |
182 | if (ret) | |
183 | goto error_deallocate_sw_rb; | |
184 | ||
185 | /* Ring buffer functions - here trigger setup related */ | |
186 | ||
187 | indio_dev->ring->preenable = &ad7476_ring_preenable; | |
188 | indio_dev->ring->postenable = &iio_triggered_ring_postenable; | |
189 | indio_dev->ring->predisable = &iio_triggered_ring_predisable; | |
190 | indio_dev->ring->scan_el_attrs = &ad7476_scan_el_group; | |
86f702ab | 191 | indio_dev->ring->scan_timestamp = true; |
349282d8 MH |
192 | |
193 | INIT_WORK(&st->poll_work, &ad7476_poll_bh_to_ring); | |
194 | ||
195 | /* Flag that polled ring buffering is possible */ | |
196 | indio_dev->modes |= INDIO_RING_TRIGGERED; | |
197 | return 0; | |
198 | error_deallocate_sw_rb: | |
199 | iio_sw_rb_free(indio_dev->ring); | |
200 | error_ret: | |
201 | return ret; | |
202 | } | |
203 | ||
204 | void ad7476_ring_cleanup(struct iio_dev *indio_dev) | |
205 | { | |
206 | /* ensure that the trigger has been detached */ | |
207 | if (indio_dev->trig) { | |
208 | iio_put_trigger(indio_dev->trig); | |
209 | iio_trigger_dettach_poll_func(indio_dev->trig, | |
210 | indio_dev->pollfunc); | |
211 | } | |
212 | kfree(indio_dev->pollfunc); | |
213 | iio_sw_rb_free(indio_dev->ring); | |
214 | } |