diff options
author | Jonathan Cameron <jic23@cam.ac.uk> | 2009-08-18 13:06:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 15:02:25 -0400 |
commit | 0a1231dfea57516fb6cf107afdfb625a11a1cc5e (patch) | |
tree | 408b9906efb7a667e429c4f571a58d611393c8cb /drivers | |
parent | 14cd9a73d97e3c1063fa1b2b02ef32ac8a914e11 (diff) |
Staging: IIO: max1363 add software ring buffer support using ring_sw
Changes since V2:
* Moved to new registration methodology.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/iio/adc/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/iio/adc/max1363.h | 14 | ||||
-rw-r--r-- | drivers/staging/iio/adc/max1363_ring.c | 241 |
3 files changed, 255 insertions, 1 deletions
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 2a37feed4add..0c2b6f39e8c8 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile | |||
@@ -3,5 +3,6 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | max1363-y := max1363_core.o | 5 | max1363-y := max1363_core.o |
6 | max1363-$(CONFIG_IIO_RING_BUFFER) += max1363_ring.o | ||
6 | 7 | ||
7 | obj-$(CONFIG_MAX1363) += max1363.o | 8 | obj-$(CONFIG_MAX1363) += max1363.o |
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h index a9d5c21a6c3c..8aca81f14d0b 100644 --- a/drivers/staging/iio/adc/max1363.h +++ b/drivers/staging/iio/adc/max1363.h | |||
@@ -228,6 +228,18 @@ struct max1363_state { | |||
228 | struct iio_trigger *trig; | 228 | struct iio_trigger *trig; |
229 | struct regulator *reg; | 229 | struct regulator *reg; |
230 | }; | 230 | }; |
231 | #ifdef CONFIG_IIO_RING_BUFFER | ||
232 | |||
233 | ssize_t max1363_scan_from_ring(struct device *dev, | ||
234 | struct device_attribute *attr, | ||
235 | char *buf); | ||
236 | int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev); | ||
237 | void max1363_ring_cleanup(struct iio_dev *indio_dev); | ||
238 | |||
239 | int max1363_initialize_ring(struct iio_ring_buffer *ring); | ||
240 | void max1363_uninitialize_ring(struct iio_ring_buffer *ring); | ||
241 | |||
242 | #else /* CONFIG_IIO_RING_BUFFER */ | ||
231 | 243 | ||
232 | static inline void max1363_uninitialize_ring(struct iio_ring_buffer *ring) | 244 | static inline void max1363_uninitialize_ring(struct iio_ring_buffer *ring) |
233 | { | 245 | { |
@@ -253,5 +265,5 @@ max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) | |||
253 | }; | 265 | }; |
254 | 266 | ||
255 | static inline void max1363_ring_cleanup(struct iio_dev *indio_dev) {}; | 267 | static inline void max1363_ring_cleanup(struct iio_dev *indio_dev) {}; |
256 | 268 | #endif /* CONFIG_IIO_RING_BUFFER */ | |
257 | #endif /* _MAX1363_H_ */ | 269 | #endif /* _MAX1363_H_ */ |
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c new file mode 100644 index 000000000000..a953eac6fd62 --- /dev/null +++ b/drivers/staging/iio/adc/max1363_ring.c | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Jonathan Cameron | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * max1363_ring.c | ||
9 | */ | ||
10 | |||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/workqueue.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/sysfs.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/i2c.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 "max1363.h" | ||
27 | |||
28 | ssize_t max1363_scan_from_ring(struct device *dev, | ||
29 | struct device_attribute *attr, | ||
30 | char *buf) | ||
31 | { | ||
32 | struct iio_dev *dev_info = dev_get_drvdata(dev); | ||
33 | struct max1363_state *info = dev_info->dev_data; | ||
34 | int i, ret, len = 0; | ||
35 | char *ring_data; | ||
36 | |||
37 | ring_data = kmalloc(info->current_mode->numvals*2, GFP_KERNEL); | ||
38 | if (ring_data == NULL) { | ||
39 | ret = -ENOMEM; | ||
40 | goto error_ret; | ||
41 | } | ||
42 | ret = dev_info->ring->access.read_last(dev_info->ring, ring_data); | ||
43 | if (ret) | ||
44 | goto error_free_ring_data; | ||
45 | len += sprintf(buf+len, "ring "); | ||
46 | for (i = 0; i < info->current_mode->numvals; i++) | ||
47 | len += sprintf(buf + len, "%d ", | ||
48 | ((int)(ring_data[i*2 + 0] & 0x0F) << 8) | ||
49 | + ((int)(ring_data[i*2 + 1]))); | ||
50 | len += sprintf(buf + len, "\n"); | ||
51 | kfree(ring_data); | ||
52 | |||
53 | return len; | ||
54 | |||
55 | error_free_ring_data: | ||
56 | kfree(ring_data); | ||
57 | error_ret: | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * max1363_ring_preenable() setup the parameters of the ring before enabling | ||
63 | * | ||
64 | * The complex nature of the setting of the nuber of bytes per datum is due | ||
65 | * to this driver currently ensuring that the timestamp is stored at an 8 | ||
66 | * byte boundary. | ||
67 | **/ | ||
68 | static int max1363_ring_preenable(struct iio_dev *indio_dev) | ||
69 | { | ||
70 | struct max1363_state *st = indio_dev->dev_data; | ||
71 | size_t d_size; | ||
72 | |||
73 | if (indio_dev->ring->access.set_bpd) { | ||
74 | d_size = st->current_mode->numvals*2 + sizeof(s64); | ||
75 | if (d_size % 8) | ||
76 | d_size += 8 - (d_size % 8); | ||
77 | indio_dev->ring->access.set_bpd(indio_dev->ring, d_size); | ||
78 | } | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * max1363_ring_postenable() typical ring post enable | ||
85 | * | ||
86 | * Only not moved into the core for the hardware ring buffer cases | ||
87 | * that are more sophisticated. | ||
88 | **/ | ||
89 | static int max1363_ring_postenable(struct iio_dev *indio_dev) | ||
90 | { | ||
91 | if (indio_dev->trig == NULL) | ||
92 | return 0; | ||
93 | return iio_trigger_attach_poll_func(indio_dev->trig, | ||
94 | indio_dev->pollfunc); | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * max1363_ring_predisable() runs just prior to ring buffer being disabled | ||
99 | * | ||
100 | * Typical predisable function which ensures that no trigger events can | ||
101 | * occur before we disable the ring buffer (and hence would have no idea | ||
102 | * what to do with them) | ||
103 | **/ | ||
104 | static int max1363_ring_predisable(struct iio_dev *indio_dev) | ||
105 | { | ||
106 | if (indio_dev->trig) | ||
107 | return iio_trigger_dettach_poll_func(indio_dev->trig, | ||
108 | indio_dev->pollfunc); | ||
109 | else | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * max1363_poll_func_th() th of trigger launched polling to ring buffer | ||
115 | * | ||
116 | * As sampling only occurs on i2c comms occuring, leave timestamping until | ||
117 | * then. Some triggers will generate their own time stamp. Currently | ||
118 | * there is no way of notifying them when no one cares. | ||
119 | **/ | ||
120 | void max1363_poll_func_th(struct iio_dev *indio_dev) | ||
121 | { | ||
122 | struct max1363_state *st = indio_dev->dev_data; | ||
123 | |||
124 | schedule_work(&st->poll_work); | ||
125 | |||
126 | return; | ||
127 | } | ||
128 | /** | ||
129 | * max1363_poll_bh_to_ring() bh of trigger launched polling to ring buffer | ||
130 | * @work_s: the work struct through which this was scheduled | ||
131 | * | ||
132 | * Currently there is no option in this driver to disable the saving of | ||
133 | * timestamps within the ring. | ||
134 | * I think the one copy of this at a time was to avoid problems if the | ||
135 | * trigger was set far too high and the reads then locked up the computer. | ||
136 | **/ | ||
137 | static void max1363_poll_bh_to_ring(struct work_struct *work_s) | ||
138 | { | ||
139 | struct max1363_state *st = container_of(work_s, struct max1363_state, | ||
140 | poll_work); | ||
141 | struct iio_dev *indio_dev = st->indio_dev; | ||
142 | struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring); | ||
143 | s64 time_ns; | ||
144 | __u8 *rxbuf; | ||
145 | int b_sent; | ||
146 | size_t d_size; | ||
147 | |||
148 | /* Ensure the timestamp is 8 byte aligned */ | ||
149 | d_size = st->current_mode->numvals*2 + sizeof(s64); | ||
150 | if (d_size % sizeof(s64)) | ||
151 | d_size += sizeof(s64) - (d_size % sizeof(s64)); | ||
152 | |||
153 | /* Ensure only one copy of this function running at a time */ | ||
154 | if (atomic_inc_return(&st->protect_ring) > 1) | ||
155 | return; | ||
156 | |||
157 | /* Monitor mode prevents reading. Whilst not currently implemented | ||
158 | * might as well have this test in here in the meantime as it does | ||
159 | * no harm. | ||
160 | */ | ||
161 | if (st->current_mode->numvals == 0) | ||
162 | return; | ||
163 | |||
164 | rxbuf = kmalloc(d_size, GFP_KERNEL); | ||
165 | if (rxbuf == NULL) | ||
166 | return; | ||
167 | |||
168 | b_sent = i2c_master_recv(st->client, | ||
169 | rxbuf, | ||
170 | st->current_mode->numvals*2); | ||
171 | if (b_sent < 0) | ||
172 | goto done; | ||
173 | |||
174 | time_ns = iio_get_time_ns(); | ||
175 | |||
176 | memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); | ||
177 | |||
178 | indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns); | ||
179 | done: | ||
180 | kfree(rxbuf); | ||
181 | atomic_dec(&st->protect_ring); | ||
182 | } | ||
183 | |||
184 | |||
185 | int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) | ||
186 | { | ||
187 | struct max1363_state *st = indio_dev->dev_data; | ||
188 | int ret = 0; | ||
189 | |||
190 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | ||
191 | if (!indio_dev->ring) { | ||
192 | ret = -ENOMEM; | ||
193 | goto error_ret; | ||
194 | } | ||
195 | /* Effectively select the ring buffer implementation */ | ||
196 | iio_ring_sw_register_funcs(&st->indio_dev->ring->access); | ||
197 | indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); | ||
198 | if (indio_dev->pollfunc == NULL) { | ||
199 | ret = -ENOMEM; | ||
200 | goto error_deallocate_sw_rb; | ||
201 | } | ||
202 | /* Configure the polling function called on trigger interrupts */ | ||
203 | indio_dev->pollfunc->poll_func_main = &max1363_poll_func_th; | ||
204 | indio_dev->pollfunc->private_data = indio_dev; | ||
205 | |||
206 | /* Ring buffer functions - here trigger setup related */ | ||
207 | indio_dev->ring->postenable = &max1363_ring_postenable; | ||
208 | indio_dev->ring->preenable = &max1363_ring_preenable; | ||
209 | indio_dev->ring->predisable = &max1363_ring_predisable; | ||
210 | INIT_WORK(&st->poll_work, &max1363_poll_bh_to_ring); | ||
211 | |||
212 | /* Flag that polled ring buffering is possible */ | ||
213 | indio_dev->modes |= INDIO_RING_TRIGGERED; | ||
214 | return 0; | ||
215 | error_deallocate_sw_rb: | ||
216 | iio_sw_rb_free(indio_dev->ring); | ||
217 | error_ret: | ||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | void max1363_ring_cleanup(struct iio_dev *indio_dev) | ||
222 | { | ||
223 | /* ensure that the trigger has been detached */ | ||
224 | if (indio_dev->trig) { | ||
225 | iio_put_trigger(indio_dev->trig); | ||
226 | iio_trigger_dettach_poll_func(indio_dev->trig, | ||
227 | indio_dev->pollfunc); | ||
228 | } | ||
229 | kfree(indio_dev->pollfunc); | ||
230 | iio_sw_rb_free(indio_dev->ring); | ||
231 | } | ||
232 | |||
233 | void max1363_uninitialize_ring(struct iio_ring_buffer *ring) | ||
234 | { | ||
235 | iio_ring_buffer_unregister(ring); | ||
236 | }; | ||
237 | |||
238 | int max1363_initialize_ring(struct iio_ring_buffer *ring) | ||
239 | { | ||
240 | return iio_ring_buffer_register(ring); | ||
241 | }; | ||