]>
Commit | Line | Data |
---|---|---|
7c31b984 MH |
1 | /* |
2 | * AD7298 SPI ADC driver | |
3 | * | |
4 | * Copyright 2011 Analog Devices Inc. | |
5 | * | |
6 | * Licensed under the GPL-2. | |
7 | */ | |
8 | ||
9 | #include <linux/interrupt.h> | |
7c31b984 MH |
10 | #include <linux/kernel.h> |
11 | #include <linux/slab.h> | |
7c31b984 MH |
12 | #include <linux/spi/spi.h> |
13 | ||
14 | #include "../iio.h" | |
3811cd62 | 15 | #include "../buffer_generic.h" |
7c31b984 | 16 | #include "../ring_sw.h" |
3f72395e | 17 | #include "../trigger_consumer.h" |
7c31b984 MH |
18 | |
19 | #include "ad7298.h" | |
20 | ||
84f79ecb | 21 | int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch) |
7c31b984 | 22 | { |
84f79ecb | 23 | struct iio_buffer *ring = indio_dev->buffer; |
7c31b984 MH |
24 | int ret; |
25 | u16 *ring_data; | |
26 | ||
32b5eeca | 27 | if (!(test_bit(ch, ring->scan_mask))) { |
7c31b984 MH |
28 | ret = -EBUSY; |
29 | goto error_ret; | |
30 | } | |
31 | ||
5565a450 | 32 | ring_data = kmalloc(ring->access->get_bytes_per_datum(ring), |
01a99e18 | 33 | GFP_KERNEL); |
7c31b984 MH |
34 | if (ring_data == NULL) { |
35 | ret = -ENOMEM; | |
36 | goto error_ret; | |
37 | } | |
5565a450 | 38 | ret = ring->access->read_last(ring, (u8 *) ring_data); |
7c31b984 MH |
39 | if (ret) |
40 | goto error_free_ring_data; | |
41 | ||
42 | ret = be16_to_cpu(ring_data[ch]); | |
43 | ||
44 | error_free_ring_data: | |
45 | kfree(ring_data); | |
46 | error_ret: | |
47 | return ret; | |
48 | } | |
49 | ||
50 | /** | |
51 | * ad7298_ring_preenable() setup the parameters of the ring before enabling | |
52 | * | |
53 | * The complex nature of the setting of the number of bytes per datum is due | |
54 | * to this driver currently ensuring that the timestamp is stored at an 8 | |
55 | * byte boundary. | |
56 | **/ | |
57 | static int ad7298_ring_preenable(struct iio_dev *indio_dev) | |
58 | { | |
cc4a48e4 | 59 | struct ad7298_state *st = iio_priv(indio_dev); |
14555b14 | 60 | struct iio_buffer *ring = indio_dev->buffer; |
7c31b984 MH |
61 | size_t d_size; |
62 | int i, m; | |
63 | unsigned short command; | |
64 | ||
65 | d_size = ring->scan_count * (AD7298_STORAGE_BITS / 8); | |
66 | ||
67 | if (ring->scan_timestamp) { | |
68 | d_size += sizeof(s64); | |
69 | ||
70 | if (d_size % sizeof(s64)) | |
71 | d_size += sizeof(s64) - (d_size % sizeof(s64)); | |
72 | } | |
73 | ||
5565a450 JC |
74 | if (ring->access->set_bytes_per_datum) |
75 | ring->access->set_bytes_per_datum(ring, d_size); | |
7c31b984 MH |
76 | |
77 | st->d_size = d_size; | |
78 | ||
79 | command = AD7298_WRITE | st->ext_ref; | |
80 | ||
81 | for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) | |
32b5eeca | 82 | if (test_bit(i, ring->scan_mask)) |
7c31b984 MH |
83 | command |= m; |
84 | ||
85 | st->tx_buf[0] = cpu_to_be16(command); | |
86 | ||
87 | /* build spi ring message */ | |
88 | st->ring_xfer[0].tx_buf = &st->tx_buf[0]; | |
89 | st->ring_xfer[0].len = 2; | |
90 | st->ring_xfer[0].cs_change = 1; | |
91 | st->ring_xfer[1].tx_buf = &st->tx_buf[1]; | |
92 | st->ring_xfer[1].len = 2; | |
93 | st->ring_xfer[1].cs_change = 1; | |
94 | ||
95 | spi_message_init(&st->ring_msg); | |
96 | spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); | |
97 | spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); | |
98 | ||
99 | for (i = 0; i < ring->scan_count; i++) { | |
100 | st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; | |
101 | st->ring_xfer[i + 2].len = 2; | |
102 | st->ring_xfer[i + 2].cs_change = 1; | |
103 | spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); | |
104 | } | |
105 | /* make sure last transfer cs_change is not set */ | |
106 | st->ring_xfer[i + 1].cs_change = 0; | |
107 | ||
108 | return 0; | |
109 | } | |
110 | ||
111 | /** | |
70d4fd3f | 112 | * ad7298_trigger_handler() bh of trigger launched polling to ring buffer |
7c31b984 MH |
113 | * |
114 | * Currently there is no option in this driver to disable the saving of | |
115 | * timestamps within the ring. | |
7c31b984 | 116 | **/ |
70d4fd3f | 117 | static irqreturn_t ad7298_trigger_handler(int irq, void *p) |
7c31b984 | 118 | { |
70d4fd3f | 119 | struct iio_poll_func *pf = p; |
e65bc6ac | 120 | struct iio_dev *indio_dev = pf->indio_dev; |
cc4a48e4 | 121 | struct ad7298_state *st = iio_priv(indio_dev); |
14555b14 | 122 | struct iio_buffer *ring = indio_dev->buffer; |
7c31b984 MH |
123 | s64 time_ns; |
124 | __u16 buf[16]; | |
125 | int b_sent, i; | |
126 | ||
7c31b984 MH |
127 | b_sent = spi_sync(st->spi, &st->ring_msg); |
128 | if (b_sent) | |
70d4fd3f | 129 | return b_sent; |
7c31b984 MH |
130 | |
131 | if (ring->scan_timestamp) { | |
132 | time_ns = iio_get_time_ns(); | |
133 | memcpy((u8 *)buf + st->d_size - sizeof(s64), | |
134 | &time_ns, sizeof(time_ns)); | |
135 | } | |
136 | ||
137 | for (i = 0; i < ring->scan_count; i++) | |
138 | buf[i] = be16_to_cpu(st->rx_buf[i]); | |
139 | ||
14555b14 | 140 | indio_dev->buffer->access->store_to(ring, (u8 *)buf, time_ns); |
01a99e18 | 141 | iio_trigger_notify_done(indio_dev->trig); |
70d4fd3f JC |
142 | |
143 | return IRQ_HANDLED; | |
7c31b984 MH |
144 | } |
145 | ||
14555b14 | 146 | static const struct iio_buffer_setup_ops ad7298_ring_setup_ops = { |
5565a450 | 147 | .preenable = &ad7298_ring_preenable, |
3b99fb76 JC |
148 | .postenable = &iio_triggered_buffer_postenable, |
149 | .predisable = &iio_triggered_buffer_predisable, | |
5565a450 JC |
150 | }; |
151 | ||
7c31b984 MH |
152 | int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) |
153 | { | |
7c31b984 MH |
154 | int ret; |
155 | ||
14555b14 JC |
156 | indio_dev->buffer = iio_sw_rb_allocate(indio_dev); |
157 | if (!indio_dev->buffer) { | |
7c31b984 MH |
158 | ret = -ENOMEM; |
159 | goto error_ret; | |
160 | } | |
161 | /* Effectively select the ring buffer implementation */ | |
14555b14 | 162 | indio_dev->buffer->access = &ring_sw_access_funcs; |
7c31b984 | 163 | |
0ed731d2 JC |
164 | indio_dev->pollfunc = iio_alloc_pollfunc(NULL, |
165 | &ad7298_trigger_handler, | |
166 | IRQF_ONESHOT, | |
167 | indio_dev, | |
168 | "ad7298_consumer%d", | |
169 | indio_dev->id); | |
170 | ||
70d4fd3f JC |
171 | if (indio_dev->pollfunc == NULL) { |
172 | ret = -ENOMEM; | |
173 | goto error_deallocate_sw_rb; | |
174 | } | |
0ed731d2 | 175 | |
7c31b984 | 176 | /* Ring buffer functions - here trigger setup related */ |
14555b14 JC |
177 | indio_dev->buffer->setup_ops = &ad7298_ring_setup_ops; |
178 | indio_dev->buffer->scan_timestamp = true; | |
7c31b984 | 179 | |
7c31b984 | 180 | /* Flag that polled ring buffering is possible */ |
ec3afa40 | 181 | indio_dev->modes |= INDIO_BUFFER_TRIGGERED; |
7c31b984 | 182 | return 0; |
0ed731d2 | 183 | |
7c31b984 | 184 | error_deallocate_sw_rb: |
14555b14 | 185 | iio_sw_rb_free(indio_dev->buffer); |
7c31b984 MH |
186 | error_ret: |
187 | return ret; | |
188 | } | |
189 | ||
190 | void ad7298_ring_cleanup(struct iio_dev *indio_dev) | |
191 | { | |
0ed731d2 | 192 | iio_dealloc_pollfunc(indio_dev->pollfunc); |
14555b14 | 193 | iio_sw_rb_free(indio_dev->buffer); |
7c31b984 | 194 | } |