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 | ||
06458e27 JC |
14 | #include <linux/iio/iio.h> |
15 | #include <linux/iio/buffer.h> | |
7c31b984 | 16 | #include "../ring_sw.h" |
06458e27 | 17 | #include <linux/iio/trigger_consumer.h> |
7c31b984 MH |
18 | |
19 | #include "ad7298.h" | |
20 | ||
7c31b984 MH |
21 | /** |
22 | * ad7298_ring_preenable() setup the parameters of the ring before enabling | |
23 | * | |
24 | * The complex nature of the setting of the number of bytes per datum is due | |
25 | * to this driver currently ensuring that the timestamp is stored at an 8 | |
26 | * byte boundary. | |
27 | **/ | |
28 | static int ad7298_ring_preenable(struct iio_dev *indio_dev) | |
29 | { | |
cc4a48e4 | 30 | struct ad7298_state *st = iio_priv(indio_dev); |
7c31b984 MH |
31 | int i, m; |
32 | unsigned short command; | |
8f03aabc | 33 | int scan_count, ret; |
7c31b984 | 34 | |
8f03aabc JC |
35 | ret = iio_sw_buffer_preenable(indio_dev); |
36 | if (ret < 0) | |
37 | return ret; | |
7c31b984 | 38 | |
8f03aabc JC |
39 | /* Now compute overall size */ |
40 | scan_count = bitmap_weight(indio_dev->active_scan_mask, | |
41 | indio_dev->masklength); | |
7c31b984 MH |
42 | |
43 | command = AD7298_WRITE | st->ext_ref; | |
44 | ||
45 | for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) | |
550268ca | 46 | if (test_bit(i, indio_dev->active_scan_mask)) |
7c31b984 MH |
47 | command |= m; |
48 | ||
49 | st->tx_buf[0] = cpu_to_be16(command); | |
50 | ||
51 | /* build spi ring message */ | |
52 | st->ring_xfer[0].tx_buf = &st->tx_buf[0]; | |
53 | st->ring_xfer[0].len = 2; | |
54 | st->ring_xfer[0].cs_change = 1; | |
55 | st->ring_xfer[1].tx_buf = &st->tx_buf[1]; | |
56 | st->ring_xfer[1].len = 2; | |
57 | st->ring_xfer[1].cs_change = 1; | |
58 | ||
59 | spi_message_init(&st->ring_msg); | |
60 | spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); | |
61 | spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); | |
62 | ||
550268ca | 63 | for (i = 0; i < scan_count; i++) { |
7c31b984 MH |
64 | st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; |
65 | st->ring_xfer[i + 2].len = 2; | |
66 | st->ring_xfer[i + 2].cs_change = 1; | |
67 | spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); | |
68 | } | |
69 | /* make sure last transfer cs_change is not set */ | |
70 | st->ring_xfer[i + 1].cs_change = 0; | |
71 | ||
72 | return 0; | |
73 | } | |
74 | ||
75 | /** | |
70d4fd3f | 76 | * ad7298_trigger_handler() bh of trigger launched polling to ring buffer |
7c31b984 MH |
77 | * |
78 | * Currently there is no option in this driver to disable the saving of | |
79 | * timestamps within the ring. | |
7c31b984 | 80 | **/ |
70d4fd3f | 81 | static irqreturn_t ad7298_trigger_handler(int irq, void *p) |
7c31b984 | 82 | { |
70d4fd3f | 83 | struct iio_poll_func *pf = p; |
e65bc6ac | 84 | struct iio_dev *indio_dev = pf->indio_dev; |
cc4a48e4 | 85 | struct ad7298_state *st = iio_priv(indio_dev); |
14555b14 | 86 | struct iio_buffer *ring = indio_dev->buffer; |
7c31b984 MH |
87 | s64 time_ns; |
88 | __u16 buf[16]; | |
89 | int b_sent, i; | |
90 | ||
7c31b984 MH |
91 | b_sent = spi_sync(st->spi, &st->ring_msg); |
92 | if (b_sent) | |
70d4fd3f | 93 | return b_sent; |
7c31b984 | 94 | |
fd6487f8 | 95 | if (indio_dev->scan_timestamp) { |
7c31b984 | 96 | time_ns = iio_get_time_ns(); |
8f03aabc | 97 | memcpy((u8 *)buf + indio_dev->scan_bytes - sizeof(s64), |
7c31b984 MH |
98 | &time_ns, sizeof(time_ns)); |
99 | } | |
100 | ||
550268ca JC |
101 | for (i = 0; i < bitmap_weight(indio_dev->active_scan_mask, |
102 | indio_dev->masklength); i++) | |
7c31b984 MH |
103 | buf[i] = be16_to_cpu(st->rx_buf[i]); |
104 | ||
14555b14 | 105 | indio_dev->buffer->access->store_to(ring, (u8 *)buf, time_ns); |
01a99e18 | 106 | iio_trigger_notify_done(indio_dev->trig); |
70d4fd3f JC |
107 | |
108 | return IRQ_HANDLED; | |
7c31b984 MH |
109 | } |
110 | ||
14555b14 | 111 | static const struct iio_buffer_setup_ops ad7298_ring_setup_ops = { |
5565a450 | 112 | .preenable = &ad7298_ring_preenable, |
3b99fb76 JC |
113 | .postenable = &iio_triggered_buffer_postenable, |
114 | .predisable = &iio_triggered_buffer_predisable, | |
5565a450 JC |
115 | }; |
116 | ||
7c31b984 MH |
117 | int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) |
118 | { | |
7c31b984 MH |
119 | int ret; |
120 | ||
14555b14 JC |
121 | indio_dev->buffer = iio_sw_rb_allocate(indio_dev); |
122 | if (!indio_dev->buffer) { | |
7c31b984 MH |
123 | ret = -ENOMEM; |
124 | goto error_ret; | |
125 | } | |
0ed731d2 JC |
126 | indio_dev->pollfunc = iio_alloc_pollfunc(NULL, |
127 | &ad7298_trigger_handler, | |
128 | IRQF_ONESHOT, | |
129 | indio_dev, | |
130 | "ad7298_consumer%d", | |
131 | indio_dev->id); | |
132 | ||
70d4fd3f JC |
133 | if (indio_dev->pollfunc == NULL) { |
134 | ret = -ENOMEM; | |
135 | goto error_deallocate_sw_rb; | |
136 | } | |
0ed731d2 | 137 | |
7c31b984 | 138 | /* Ring buffer functions - here trigger setup related */ |
1612244f | 139 | indio_dev->setup_ops = &ad7298_ring_setup_ops; |
14555b14 | 140 | indio_dev->buffer->scan_timestamp = true; |
7c31b984 | 141 | |
7c31b984 | 142 | /* Flag that polled ring buffering is possible */ |
ec3afa40 | 143 | indio_dev->modes |= INDIO_BUFFER_TRIGGERED; |
7c31b984 | 144 | return 0; |
0ed731d2 | 145 | |
7c31b984 | 146 | error_deallocate_sw_rb: |
14555b14 | 147 | iio_sw_rb_free(indio_dev->buffer); |
7c31b984 MH |
148 | error_ret: |
149 | return ret; | |
150 | } | |
151 | ||
152 | void ad7298_ring_cleanup(struct iio_dev *indio_dev) | |
153 | { | |
0ed731d2 | 154 | iio_dealloc_pollfunc(indio_dev->pollfunc); |
14555b14 | 155 | iio_sw_rb_free(indio_dev->buffer); |
7c31b984 | 156 | } |