hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/iio/imu/adis_buffer.c
....@@ -1,10 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Common library for ADIS16XXX devices
34 *
45 * Copyright 2012 Analog Devices Inc.
56 * Author: Lars-Peter Clausen <lars@metafoo.de>
6
- *
7
- * Licensed under the GPL-2 or later.
87 */
98
109 #include <linux/export.h>
....@@ -20,8 +19,51 @@
2019 #include <linux/iio/triggered_buffer.h>
2120 #include <linux/iio/imu/adis.h>
2221
22
+static int adis_update_scan_mode_burst(struct iio_dev *indio_dev,
23
+ const unsigned long *scan_mask)
24
+{
25
+ struct adis *adis = iio_device_get_drvdata(indio_dev);
26
+ unsigned int burst_length, burst_max_length;
27
+ u8 *tx;
28
+
29
+ burst_length = adis->data->burst_len + adis->burst_extra_len;
30
+
31
+ if (adis->data->burst_max_len)
32
+ burst_max_length = adis->data->burst_max_len;
33
+ else
34
+ burst_max_length = burst_length;
35
+
36
+ adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL);
37
+ if (!adis->xfer)
38
+ return -ENOMEM;
39
+
40
+ adis->buffer = kzalloc(burst_max_length + sizeof(u16), GFP_KERNEL);
41
+ if (!adis->buffer) {
42
+ kfree(adis->xfer);
43
+ adis->xfer = NULL;
44
+ return -ENOMEM;
45
+ }
46
+
47
+ tx = adis->buffer + burst_max_length;
48
+ tx[0] = ADIS_READ_REG(adis->data->burst_reg_cmd);
49
+ tx[1] = 0;
50
+
51
+ adis->xfer[0].tx_buf = tx;
52
+ adis->xfer[0].bits_per_word = 8;
53
+ adis->xfer[0].len = 2;
54
+ adis->xfer[1].rx_buf = adis->buffer;
55
+ adis->xfer[1].bits_per_word = 8;
56
+ adis->xfer[1].len = burst_length;
57
+
58
+ spi_message_init(&adis->msg);
59
+ spi_message_add_tail(&adis->xfer[0], &adis->msg);
60
+ spi_message_add_tail(&adis->xfer[1], &adis->msg);
61
+
62
+ return 0;
63
+}
64
+
2365 int adis_update_scan_mode(struct iio_dev *indio_dev,
24
- const unsigned long *scan_mask)
66
+ const unsigned long *scan_mask)
2567 {
2668 struct adis *adis = iio_device_get_drvdata(indio_dev);
2769 const struct iio_chan_spec *chan;
....@@ -31,6 +73,9 @@
3173
3274 kfree(adis->xfer);
3375 kfree(adis->buffer);
76
+
77
+ if (adis->data->burst_len)
78
+ return adis_update_scan_mode_burst(indio_dev, scan_mask);
3479
3580 scan_count = indio_dev->scan_bytes / 2;
3681
....@@ -55,7 +100,8 @@
55100 if (j != scan_count)
56101 adis->xfer[j].cs_change = 1;
57102 adis->xfer[j].len = 2;
58
- adis->xfer[j].delay_usecs = adis->data->read_delay;
103
+ adis->xfer[j].delay.value = adis->data->read_delay;
104
+ adis->xfer[j].delay.unit = SPI_DELAY_UNIT_USECS;
59105 if (j < scan_count)
60106 adis->xfer[j].tx_buf = &tx[j];
61107 if (j >= 1)
....@@ -74,7 +120,7 @@
74120
75121 return 0;
76122 }
77
-EXPORT_SYMBOL_GPL(adis_update_scan_mode);
123
+EXPORT_SYMBOL_NS_GPL(adis_update_scan_mode, IIO_ADISLIB);
78124
79125 static irqreturn_t adis_trigger_handler(int irq, void *p)
80126 {
....@@ -84,7 +130,7 @@
84130 int ret;
85131
86132 if (adis->data->has_paging) {
87
- mutex_lock(&adis->txrx_lock);
133
+ mutex_lock(&adis->state_lock);
88134 if (adis->current_page != 0) {
89135 adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
90136 adis->tx[1] = 0;
....@@ -99,21 +145,30 @@
99145
100146 if (adis->data->has_paging) {
101147 adis->current_page = 0;
102
- mutex_unlock(&adis->txrx_lock);
148
+ mutex_unlock(&adis->state_lock);
103149 }
104150
105151 iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
106
- pf->timestamp);
152
+ pf->timestamp);
107153
108154 iio_trigger_notify_done(indio_dev->trig);
109155
110156 return IRQ_HANDLED;
111157 }
112158
159
+static void adis_buffer_cleanup(void *arg)
160
+{
161
+ struct adis *adis = arg;
162
+
163
+ kfree(adis->buffer);
164
+ kfree(adis->xfer);
165
+}
166
+
113167 /**
114
- * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device
115
- * @adis: The adis device.
116
- * @indio_dev: The IIO device.
168
+ * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for
169
+ * the managed adis device
170
+ * @adis: The adis device
171
+ * @indio_dev: The IIO device
117172 * @trigger_handler: Optional trigger handler, may be NULL.
118173 *
119174 * Returns 0 on success, a negative error code otherwise.
....@@ -122,50 +177,30 @@
122177 * 'trigger_handler' is NULL the default trigger handler will be used. The
123178 * default trigger handler will simply read the registers assigned to the
124179 * currently active channels.
125
- *
126
- * adis_cleanup_buffer_and_trigger() should be called to free the resources
127
- * allocated by this function.
128180 */
129
-int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
130
- irqreturn_t (*trigger_handler)(int, void *))
181
+int
182
+devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
183
+ irq_handler_t trigger_handler)
131184 {
132185 int ret;
133186
134187 if (!trigger_handler)
135188 trigger_handler = adis_trigger_handler;
136189
137
- ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
138
- trigger_handler, NULL);
190
+ ret = devm_iio_triggered_buffer_setup(&adis->spi->dev, indio_dev,
191
+ &iio_pollfunc_store_time,
192
+ trigger_handler, NULL);
139193 if (ret)
140194 return ret;
141195
142196 if (adis->spi->irq) {
143
- ret = adis_probe_trigger(adis, indio_dev);
197
+ ret = devm_adis_probe_trigger(adis, indio_dev);
144198 if (ret)
145
- goto error_buffer_cleanup;
199
+ return ret;
146200 }
147
- return 0;
148201
149
-error_buffer_cleanup:
150
- iio_triggered_buffer_cleanup(indio_dev);
151
- return ret;
202
+ return devm_add_action_or_reset(&adis->spi->dev, adis_buffer_cleanup,
203
+ adis);
152204 }
153
-EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
205
+EXPORT_SYMBOL_NS_GPL(devm_adis_setup_buffer_and_trigger, IIO_ADISLIB);
154206
155
-/**
156
- * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources
157
- * @adis: The adis device.
158
- * @indio_dev: The IIO device.
159
- *
160
- * Frees resources allocated by adis_setup_buffer_and_trigger()
161
- */
162
-void adis_cleanup_buffer_and_trigger(struct adis *adis,
163
- struct iio_dev *indio_dev)
164
-{
165
- if (adis->spi->irq)
166
- adis_remove_trigger(adis);
167
- kfree(adis->buffer);
168
- kfree(adis->xfer);
169
- iio_triggered_buffer_cleanup(indio_dev);
170
-}
171
-EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger);