From 08f87f769b595151be1afeff53e144f543faa614 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 06 Dec 2023 09:51:13 +0000 Subject: [PATCH] add dts config --- kernel/drivers/iio/imu/adis_buffer.c | 113 +++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 74 insertions(+), 39 deletions(-) diff --git a/kernel/drivers/iio/imu/adis_buffer.c b/kernel/drivers/iio/imu/adis_buffer.c index bde6846..175af15 100644 --- a/kernel/drivers/iio/imu/adis_buffer.c +++ b/kernel/drivers/iio/imu/adis_buffer.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Common library for ADIS16XXX devices * * Copyright 2012 Analog Devices Inc. * Author: Lars-Peter Clausen <lars@metafoo.de> - * - * Licensed under the GPL-2 or later. */ #include <linux/export.h> @@ -20,6 +19,49 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/imu/adis.h> +static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct adis *adis = iio_device_get_drvdata(indio_dev); + unsigned int burst_length, burst_max_length; + u8 *tx; + + burst_length = adis->data->burst_len + adis->burst_extra_len; + + if (adis->data->burst_max_len) + burst_max_length = adis->data->burst_max_len; + else + burst_max_length = burst_length; + + adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); + if (!adis->xfer) + return -ENOMEM; + + adis->buffer = kzalloc(burst_max_length + sizeof(u16), GFP_KERNEL); + if (!adis->buffer) { + kfree(adis->xfer); + adis->xfer = NULL; + return -ENOMEM; + } + + tx = adis->buffer + burst_max_length; + tx[0] = ADIS_READ_REG(adis->data->burst_reg_cmd); + tx[1] = 0; + + adis->xfer[0].tx_buf = tx; + adis->xfer[0].bits_per_word = 8; + adis->xfer[0].len = 2; + adis->xfer[1].rx_buf = adis->buffer; + adis->xfer[1].bits_per_word = 8; + adis->xfer[1].len = burst_length; + + spi_message_init(&adis->msg); + spi_message_add_tail(&adis->xfer[0], &adis->msg); + spi_message_add_tail(&adis->xfer[1], &adis->msg); + + return 0; +} + int adis_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { @@ -31,6 +73,9 @@ kfree(adis->xfer); kfree(adis->buffer); + + if (adis->data->burst_len) + return adis_update_scan_mode_burst(indio_dev, scan_mask); scan_count = indio_dev->scan_bytes / 2; @@ -55,7 +100,8 @@ if (j != scan_count) adis->xfer[j].cs_change = 1; adis->xfer[j].len = 2; - adis->xfer[j].delay_usecs = adis->data->read_delay; + adis->xfer[j].delay.value = adis->data->read_delay; + adis->xfer[j].delay.unit = SPI_DELAY_UNIT_USECS; if (j < scan_count) adis->xfer[j].tx_buf = &tx[j]; if (j >= 1) @@ -84,7 +130,7 @@ int ret; if (adis->data->has_paging) { - mutex_lock(&adis->txrx_lock); + mutex_lock(&adis->state_lock); if (adis->current_page != 0) { adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID); adis->tx[1] = 0; @@ -99,7 +145,7 @@ if (adis->data->has_paging) { adis->current_page = 0; - mutex_unlock(&adis->txrx_lock); + mutex_unlock(&adis->state_lock); } iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer, @@ -110,10 +156,19 @@ return IRQ_HANDLED; } +static void adis_buffer_cleanup(void *arg) +{ + struct adis *adis = arg; + + kfree(adis->buffer); + kfree(adis->xfer); +} + /** - * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device - * @adis: The adis device. - * @indio_dev: The IIO device. + * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for + * the managed adis device + * @adis: The adis device + * @indio_dev: The IIO device * @trigger_handler: Optional trigger handler, may be NULL. * * Returns 0 on success, a negative error code otherwise. @@ -122,50 +177,30 @@ * 'trigger_handler' is NULL the default trigger handler will be used. The * default trigger handler will simply read the registers assigned to the * currently active channels. - * - * adis_cleanup_buffer_and_trigger() should be called to free the resources - * allocated by this function. */ -int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, - irqreturn_t (*trigger_handler)(int, void *)) +int +devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, + irq_handler_t trigger_handler) { int ret; if (!trigger_handler) trigger_handler = adis_trigger_handler; - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - trigger_handler, NULL); + ret = devm_iio_triggered_buffer_setup(&adis->spi->dev, indio_dev, + &iio_pollfunc_store_time, + trigger_handler, NULL); if (ret) return ret; if (adis->spi->irq) { - ret = adis_probe_trigger(adis, indio_dev); + ret = devm_adis_probe_trigger(adis, indio_dev); if (ret) - goto error_buffer_cleanup; + return ret; } - return 0; -error_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); - return ret; + return devm_add_action_or_reset(&adis->spi->dev, adis_buffer_cleanup, + adis); } -EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); +EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger); -/** - * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources - * @adis: The adis device. - * @indio_dev: The IIO device. - * - * Frees resources allocated by adis_setup_buffer_and_trigger() - */ -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - if (adis->spi->irq) - adis_remove_trigger(adis); - kfree(adis->buffer); - kfree(adis->xfer); - iio_triggered_buffer_cleanup(indio_dev); -} -EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); -- Gitblit v1.6.2