Commit | Line | Data |
---|---|---|
0a1231df JC |
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> | |
5a0e3ad6 | 12 | #include <linux/slab.h> |
0a1231df | 13 | #include <linux/kernel.h> |
0a1231df | 14 | #include <linux/i2c.h> |
82020b0e | 15 | #include <linux/bitops.h> |
0a1231df JC |
16 | |
17 | #include "../iio.h" | |
18 | #include "../ring_generic.h" | |
19 | #include "../ring_sw.h" | |
20 | #include "../trigger.h" | |
0a1231df JC |
21 | |
22 | #include "max1363.h" | |
23 | ||
82020b0e | 24 | int max1363_single_channel_from_ring(long mask, struct max1363_state *st) |
0a1231df | 25 | { |
3dba81ba | 26 | struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; |
82020b0e JC |
27 | int count = 0, ret; |
28 | u8 *ring_data; | |
29 | if (!(st->current_mode->modemask & mask)) { | |
30 | ret = -EBUSY; | |
31 | goto error_ret; | |
32 | } | |
0a1231df | 33 | |
5565a450 JC |
34 | ring_data = kmalloc(ring->access->get_bytes_per_datum(ring), |
35 | GFP_KERNEL); | |
0a1231df JC |
36 | if (ring_data == NULL) { |
37 | ret = -ENOMEM; | |
38 | goto error_ret; | |
39 | } | |
5565a450 | 40 | ret = ring->access->read_last(ring, ring_data); |
0a1231df JC |
41 | if (ret) |
42 | goto error_free_ring_data; | |
82020b0e JC |
43 | /* Need a count of channels prior to this one */ |
44 | mask >>= 1; | |
45 | while (mask) { | |
81b77f94 | 46 | if (mask & st->current_mode->modemask) |
82020b0e JC |
47 | count++; |
48 | mask >>= 1; | |
49 | } | |
3bf877c1 | 50 | if (st->chip_info->bits != 8) |
81b77f94 | 51 | ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8) |
3bf877c1 JC |
52 | + (int)(ring_data[count*2 + 1]); |
53 | else | |
81b77f94 | 54 | ret = ring_data[count]; |
0a1231df JC |
55 | |
56 | error_free_ring_data: | |
57 | kfree(ring_data); | |
58 | error_ret: | |
59 | return ret; | |
60 | } | |
61 | ||
58f0a255 | 62 | |
0a1231df | 63 | /** |
c40ab874 | 64 | * max1363_ring_preenable() - setup the parameters of the ring before enabling |
0a1231df JC |
65 | * |
66 | * The complex nature of the setting of the nuber of bytes per datum is due | |
67 | * to this driver currently ensuring that the timestamp is stored at an 8 | |
68 | * byte boundary. | |
69 | **/ | |
70 | static int max1363_ring_preenable(struct iio_dev *indio_dev) | |
71 | { | |
3dba81ba | 72 | struct max1363_state *st = iio_priv(indio_dev); |
bf32963c | 73 | struct iio_ring_buffer *ring = indio_dev->ring; |
9cc55989 | 74 | size_t d_size = 0; |
82020b0e JC |
75 | unsigned long numvals; |
76 | ||
77 | /* | |
78 | * Need to figure out the current mode based upon the requested | |
79 | * scan mask in iio_dev | |
80 | */ | |
bf32963c | 81 | st->current_mode = max1363_match_mode(ring->scan_mask, |
82020b0e JC |
82 | st->chip_info); |
83 | if (!st->current_mode) | |
84 | return -EINVAL; | |
85 | ||
86 | max1363_set_scan_mode(st); | |
0a1231df | 87 | |
82020b0e | 88 | numvals = hweight_long(st->current_mode->modemask); |
5565a450 | 89 | if (ring->access->set_bytes_per_datum) { |
9cc55989 JC |
90 | if (ring->scan_timestamp) |
91 | d_size += sizeof(s64); | |
3bf877c1 | 92 | if (st->chip_info->bits != 8) |
9cc55989 | 93 | d_size += numvals*2; |
3bf877c1 | 94 | else |
9cc55989 JC |
95 | d_size += numvals; |
96 | if (ring->scan_timestamp && (d_size % 8)) | |
0a1231df | 97 | d_size += 8 - (d_size % 8); |
5565a450 | 98 | ring->access->set_bytes_per_datum(ring, d_size); |
0a1231df JC |
99 | } |
100 | ||
101 | return 0; | |
102 | } | |
103 | ||
6da288a3 | 104 | static irqreturn_t max1363_trigger_handler(int irq, void *p) |
0a1231df | 105 | { |
6da288a3 | 106 | struct iio_poll_func *pf = p; |
e65bc6ac | 107 | struct iio_dev *indio_dev = pf->indio_dev; |
3dba81ba | 108 | struct max1363_state *st = iio_priv(indio_dev); |
0a1231df JC |
109 | s64 time_ns; |
110 | __u8 *rxbuf; | |
111 | int b_sent; | |
112 | size_t d_size; | |
82020b0e | 113 | unsigned long numvals = hweight_long(st->current_mode->modemask); |
0a1231df JC |
114 | |
115 | /* Ensure the timestamp is 8 byte aligned */ | |
3bf877c1 JC |
116 | if (st->chip_info->bits != 8) |
117 | d_size = numvals*2 + sizeof(s64); | |
118 | else | |
119 | d_size = numvals + sizeof(s64); | |
0a1231df JC |
120 | if (d_size % sizeof(s64)) |
121 | d_size += sizeof(s64) - (d_size % sizeof(s64)); | |
122 | ||
0a1231df JC |
123 | /* Monitor mode prevents reading. Whilst not currently implemented |
124 | * might as well have this test in here in the meantime as it does | |
125 | * no harm. | |
126 | */ | |
82020b0e | 127 | if (numvals == 0) |
6da288a3 | 128 | return IRQ_HANDLED; |
0a1231df JC |
129 | |
130 | rxbuf = kmalloc(d_size, GFP_KERNEL); | |
131 | if (rxbuf == NULL) | |
6da288a3 | 132 | return -ENOMEM; |
3bf877c1 JC |
133 | if (st->chip_info->bits != 8) |
134 | b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); | |
135 | else | |
136 | b_sent = i2c_master_recv(st->client, rxbuf, numvals); | |
0a1231df JC |
137 | if (b_sent < 0) |
138 | goto done; | |
139 | ||
140 | time_ns = iio_get_time_ns(); | |
141 | ||
142 | memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); | |
143 | ||
5565a450 | 144 | indio_dev->ring->access->store_to(indio_dev->ring, rxbuf, time_ns); |
0a1231df | 145 | done: |
6da288a3 | 146 | iio_trigger_notify_done(indio_dev->trig); |
0a1231df | 147 | kfree(rxbuf); |
6da288a3 JC |
148 | |
149 | return IRQ_HANDLED; | |
0a1231df JC |
150 | } |
151 | ||
5565a450 JC |
152 | static const struct iio_ring_setup_ops max1363_ring_setup_ops = { |
153 | .postenable = &iio_triggered_ring_postenable, | |
154 | .preenable = &max1363_ring_preenable, | |
155 | .predisable = &iio_triggered_ring_predisable, | |
156 | }; | |
0a1231df JC |
157 | |
158 | int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) | |
159 | { | |
3dba81ba | 160 | struct max1363_state *st = iio_priv(indio_dev); |
0a1231df JC |
161 | int ret = 0; |
162 | ||
163 | indio_dev->ring = iio_sw_rb_allocate(indio_dev); | |
164 | if (!indio_dev->ring) { | |
165 | ret = -ENOMEM; | |
166 | goto error_ret; | |
167 | } | |
0ed731d2 JC |
168 | indio_dev->pollfunc = iio_alloc_pollfunc(NULL, |
169 | &max1363_trigger_handler, | |
170 | IRQF_ONESHOT, | |
171 | indio_dev, | |
172 | "%s_consumer%d", | |
173 | st->client->name, | |
174 | indio_dev->id); | |
6da288a3 JC |
175 | if (indio_dev->pollfunc == NULL) { |
176 | ret = -ENOMEM; | |
0a1231df | 177 | goto error_deallocate_sw_rb; |
6da288a3 | 178 | } |
5565a450 JC |
179 | /* Effectively select the ring buffer implementation */ |
180 | indio_dev->ring->access = &ring_sw_access_funcs; | |
0a1231df | 181 | /* Ring buffer functions - here trigger setup related */ |
5565a450 | 182 | indio_dev->ring->setup_ops = &max1363_ring_setup_ops; |
0a1231df JC |
183 | |
184 | /* Flag that polled ring buffering is possible */ | |
185 | indio_dev->modes |= INDIO_RING_TRIGGERED; | |
6da288a3 | 186 | |
0a1231df | 187 | return 0; |
0ed731d2 | 188 | |
0a1231df JC |
189 | error_deallocate_sw_rb: |
190 | iio_sw_rb_free(indio_dev->ring); | |
191 | error_ret: | |
192 | return ret; | |
193 | } | |
194 | ||
195 | void max1363_ring_cleanup(struct iio_dev *indio_dev) | |
196 | { | |
197 | /* ensure that the trigger has been detached */ | |
0ed731d2 | 198 | iio_dealloc_pollfunc(indio_dev->pollfunc); |
0a1231df JC |
199 | iio_sw_rb_free(indio_dev->ring); |
200 | } |