From: "Nuno Sá" <noname.nuno@gmail.com>
To: "David Lechner" <dlechner@baylibre.com>,
"Mark Brown" <broonie@kernel.org>,
"Jonathan Cameron" <jic23@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Nuno Sá" <nuno.sa@analog.com>
Cc: "Uwe Kleine-König" <ukleinek@kernel.org>,
"Michael Hennerich" <Michael.Hennerich@analog.com>,
"Lars-Peter Clausen" <lars@metafoo.de>,
"David Jander" <david@protonic.nl>,
"Martin Sperl" <kernel@martin.sperl.org>,
linux-spi@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org,
linux-pwm@vger.kernel.org, "Axel Haslam" <ahaslam@baylibre.com>
Subject: Re: [PATCH v6 17/17] iio: dac: ad5791: Add offload support
Date: Tue, 17 Dec 2024 13:18:16 +0100 [thread overview]
Message-ID: <c54da9aa3edb841b1e3d5f2fbfd0b29e89da1184.camel@gmail.com> (raw)
In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-17-88ee574d5d03@baylibre.com>
On Wed, 2024-12-11 at 14:54 -0600, David Lechner wrote:
> From: Axel Haslam <ahaslam@baylibre.com>
>
> Add SPI offload support to stream TX buffers using DMA.
> This allows loading samples to the DAC with a rate of 1 MSPS.
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
Reviewed-by: Nuno Sa <nuno.sa@analog.com>
>
> v6 changes: new patch in v6
> ---
> drivers/iio/dac/Kconfig | 3 +
> drivers/iio/dac/ad5791.c | 150
> +++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 153 insertions(+)
>
> diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
> index
> 4cde34e8c8e3356aa41bcd2cba38d67d5c6f8049..f6c5cb632acbdc2432f60b163452bb0c5f89
> fa72 100644
> --- a/drivers/iio/dac/Kconfig
> +++ b/drivers/iio/dac/Kconfig
> @@ -296,6 +296,9 @@ config AD5770R
> config AD5791
> tristate "Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC SPI
> driver"
> depends on SPI
> + select SPI_OFFLOAD
> + select IIO_BUFFER
> + select IIO_BUFFER_DMAENGINE
> help
> Say yes here to build support for Analog Devices AD5760, AD5780,
> AD5781, AD5790, AD5791 High Resolution Voltage Output Digital to
> diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c
> index
> 24462cb020e19e8e2c6faa13109ac047cf423c37..a2953a9a4e5d5bc17c9c4a8281be4b41b1af
> 5de8 100644
> --- a/drivers/iio/dac/ad5791.c
> +++ b/drivers/iio/dac/ad5791.c
> @@ -15,9 +15,12 @@
> #include <linux/module.h>
> #include <linux/regulator/consumer.h>
> #include <linux/slab.h>
> +#include <linux/spi/offload/consumer.h>
> #include <linux/spi/spi.h>
> #include <linux/sysfs.h>
> +#include <linux/units.h>
>
> +#include <linux/iio/buffer-dmaengine.h>
> #include <linux/iio/dac/ad5791.h>
> #include <linux/iio/iio.h>
> #include <linux/iio/sysfs.h>
> @@ -64,11 +67,13 @@
> * struct ad5791_chip_info - chip specific information
> * @name: name of the dac chip
> * @channel: channel specification
> + * @channel_offload: channel specification for offload
> * @get_lin_comp: function pointer to the device specific function
> */
> struct ad5791_chip_info {
> const char *name;
> const struct iio_chan_spec channel;
> + const struct iio_chan_spec channel_offload;
> int (*get_lin_comp)(unsigned int span);
> };
>
> @@ -81,6 +86,11 @@ struct ad5791_chip_info {
> * @gpio_clear: clear gpio
> * @gpio_ldac: load dac gpio
> * @chip_info: chip model specific constants
> + * @offload_msg: spi message used for offload
> + * @offload_xfer: spi transfer used for offload
> + * @offload: offload device
> + * @offload_trigger: offload trigger
> + * @offload_trigger_hz: offload sample rate
> * @vref_mv: actual reference voltage used
> * @vref_neg_mv: voltage of the negative supply
> * @ctrl: control register cache
> @@ -96,6 +106,11 @@ struct ad5791_state {
> struct gpio_desc *gpio_clear;
> struct gpio_desc *gpio_ldac;
> const struct ad5791_chip_info *chip_info;
> + struct spi_message offload_msg;
> + struct spi_transfer offload_xfer;
> + struct spi_offload *offload;
> + struct spi_offload_trigger *offload_trigger;
> + unsigned int offload_trigger_hz;
> unsigned short vref_mv;
> unsigned int vref_neg_mv;
> unsigned ctrl;
> @@ -232,6 +247,25 @@ static int ad5780_get_lin_comp(unsigned int span)
> return AD5780_LINCOMP_10_20;
> }
>
> +static int ad5791_set_sample_freq(struct ad5791_state *st, int val)
> +{
> + struct spi_offload_trigger_config config = {
> + .type = SPI_OFFLOAD_TRIGGER_PERIODIC,
> + .periodic = {
> + .frequency_hz = val,
> + },
> + };
> + int ret;
> +
> + ret = spi_offload_trigger_validate(st->offload_trigger, &config);
> + if (ret)
> + return ret;
> +
> + st->offload_trigger_hz = config.periodic.frequency_hz;
> +
> + return 0;
> +}
> +
> static int ad5791_read_raw(struct iio_dev *indio_dev,
> struct iio_chan_spec const *chan,
> int *val,
> @@ -259,6 +293,9 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
> do_div(val64, st->vref_mv);
> *val = -val64;
> return IIO_VAL_INT;
> + case IIO_CHAN_INFO_SAMP_FREQ:
> + *val = st->offload_trigger_hz;
> + return IIO_VAL_INT;
> default:
> return -EINVAL;
> }
> @@ -299,6 +336,24 @@ static const struct ad5791_chip_info _name##_chip_info =
> { \
> }, \
> .ext_info = ad5791_ext_info, \
> }, \
> + .channel_offload = { \
> + .type = IIO_VOLTAGE, \
> + .output = 1, \
> + .indexed = 1, \
> + .address = AD5791_ADDR_DAC0, \
> + .channel = 0, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)
> | \
> + BIT(IIO_CHAN_INFO_OFFSET), \
> + .info_mask_shared_by_all =
> BIT(IIO_CHAN_INFO_SAMP_FREQ),\
> + .scan_type = { \
> + .sign = 'u', \
> + .realbits = (bits), \
> + .storagebits = 32, \
> + .shift = (_shift), \
> + }, \
> + .ext_info = ad5791_ext_info, \
> + }, \
> }
>
> AD5791_DEFINE_CHIP_INFO(ad5760, 16, 4, ad5780_get_lin_comp);
> @@ -322,16 +377,95 @@ static int ad5791_write_raw(struct iio_dev *indio_dev,
>
> return ad5791_spi_write(st, chan->address, val);
>
> + case IIO_CHAN_INFO_SAMP_FREQ:
> + if (val < 0 || val2 < 0)
> + return -EINVAL;
> + return ad5791_set_sample_freq(st, val);
> default:
> return -EINVAL;
> }
> }
>
> +static int ad5791_buffer_preenable(struct iio_dev *indio_dev)
> +{
> + struct ad5791_state *st = iio_priv(indio_dev);
> + struct spi_offload_trigger_config config = {
> + .type = SPI_OFFLOAD_TRIGGER_PERIODIC,
> + .periodic = {
> + .frequency_hz = st->offload_trigger_hz,
> + },
> + };
> +
> + if (st->pwr_down)
> + return -EINVAL;
> +
> + return spi_offload_trigger_enable(st->offload, st->offload_trigger,
> + &config);
> +}
> +
> +static int ad5791_buffer_postdisable(struct iio_dev *indio_dev)
> +{
> + struct ad5791_state *st = iio_priv(indio_dev);
> +
> + spi_offload_trigger_disable(st->offload, st->offload_trigger);
> +
> + return 0;
> +}
> +
> +static const struct iio_buffer_setup_ops ad5791_buffer_setup_ops = {
> + .preenable = &ad5791_buffer_preenable,
> + .postdisable = &ad5791_buffer_postdisable,
> +};
> +
> +static int ad5791_offload_setup(struct iio_dev *indio_dev)
> +{
> + struct ad5791_state *st = iio_priv(indio_dev);
> + struct spi_device *spi = st->spi;
> + struct dma_chan *tx_dma;
> + int ret;
> +
> + st->offload_trigger = devm_spi_offload_trigger_get(&spi->dev,
> + st->offload, SPI_OFFLOAD_TRIGGER_PERIODIC);
> + if (IS_ERR(st->offload_trigger))
> + return dev_err_probe(&spi->dev, PTR_ERR(st->offload_trigger),
> + "failed to get offload trigger\n");
> +
> + ret = ad5791_set_sample_freq(st, 1 * MEGA);
> + if (ret)
> + return dev_err_probe(&spi->dev, ret,
> + "failed to init sample rate\n");
> +
> + tx_dma = devm_spi_offload_tx_stream_request_dma_chan(&spi->dev,
> + st->offload);
> + if (IS_ERR(tx_dma))
> + return dev_err_probe(&spi->dev, PTR_ERR(tx_dma),
> + "failed to get offload TX DMA\n");
> +
> + ret = devm_iio_dmaengine_buffer_setup_with_handle(&spi->dev,
> + indio_dev, tx_dma, IIO_BUFFER_DIRECTION_OUT);
> + if (ret)
> + return ret;
> +
> + st->offload_xfer.len = 4;
> + st->offload_xfer.bits_per_word = 24;
> + st->offload_xfer.offload_flags = SPI_OFFLOAD_XFER_TX_STREAM;
> +
> + spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer,
> 1);
> + st->offload_msg.offload = st->offload;
> +
> + return devm_spi_optimize_message(&spi->dev, st->spi, &st-
> >offload_msg);
> +}
> +
> static const struct iio_info ad5791_info = {
> .read_raw = &ad5791_read_raw,
> .write_raw = &ad5791_write_raw,
> };
>
> +static const struct spi_offload_config ad5791_offload_config = {
> + .capability_flags = SPI_OFFLOAD_CAP_TRIGGER |
> + SPI_OFFLOAD_CAP_TX_STREAM_DMA,
> +};
> +
> static int ad5791_probe(struct spi_device *spi)
> {
> const struct ad5791_platform_data *pdata = dev_get_platdata(&spi-
> >dev);
> @@ -416,6 +550,21 @@ static int ad5791_probe(struct spi_device *spi)
> indio_dev->channels = &st->chip_info->channel;
> indio_dev->num_channels = 1;
> indio_dev->name = st->chip_info->name;
> +
> + st->offload = devm_spi_offload_get(&spi->dev, spi,
> &ad5791_offload_config);
> + ret = PTR_ERR_OR_ZERO(st->offload);
> + if (ret && ret != -ENODEV)
> + return dev_err_probe(&spi->dev, ret, "failed to get
> offload\n");
> +
> + if (ret != -ENODEV) {
> + indio_dev->channels = &st->chip_info->channel_offload;
> + indio_dev->setup_ops = &ad5791_buffer_setup_ops;
> + ret = ad5791_offload_setup(indio_dev);
> + if (ret)
> + return dev_err_probe(&spi->dev, ret,
> + "fail to setup offload\n");
> + }
> +
> return devm_iio_device_register(&spi->dev, indio_dev);
> }
>
> @@ -452,3 +601,4 @@ module_spi_driver(ad5791_driver);
> MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
> MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
> MODULE_LICENSE("GPL v2");
> +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER");
>
prev parent reply other threads:[~2024-12-17 12:13 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-11 20:54 [PATCH v6 00/17] spi: axi-spi-engine: add offload support David Lechner
2024-12-11 20:54 ` [PATCH v6 01/17] spi: add basic support for SPI offloading David Lechner
2024-12-17 11:21 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 02/17] spi: offload: add support for hardware triggers David Lechner
2024-12-17 11:30 ` Nuno Sá
2024-12-17 15:35 ` David Lechner
2024-12-11 20:54 ` [PATCH v6 03/17] dt-bindings: trigger-source: add generic PWM trigger source David Lechner
2024-12-14 14:25 ` Jonathan Cameron
2024-12-17 14:32 ` Rob Herring (Arm)
2024-12-11 20:54 ` [PATCH v6 04/17] spi: offload-trigger: add PWM trigger driver David Lechner
2024-12-17 11:36 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 05/17] spi: add offload TX/RX streaming APIs David Lechner
2024-12-14 14:28 ` Jonathan Cameron
2024-12-17 11:43 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 06/17] spi: dt-bindings: axi-spi-engine: add SPI offload properties David Lechner
2024-12-14 14:30 ` Jonathan Cameron
2024-12-17 14:33 ` Rob Herring (Arm)
2024-12-11 20:54 ` [PATCH v6 07/17] spi: axi-spi-engine: implement offload support David Lechner
2024-12-17 11:48 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 08/17] iio: buffer-dmaengine: split requesting DMA channel from allocating buffer David Lechner
2024-12-14 14:37 ` Jonathan Cameron
2024-12-17 11:50 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 09/17] iio: buffer-dmaengine: add devm_iio_dmaengine_buffer_setup_with_handle() David Lechner
2024-12-14 14:39 ` Jonathan Cameron
2024-12-17 11:51 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 10/17] iio: adc: ad7944: don't use storagebits for sizing David Lechner
2024-12-14 16:56 ` Jonathan Cameron
2024-12-17 11:52 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 11/17] iio: adc: ad7944: add support for SPI offload David Lechner
2024-12-17 12:02 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 12/17] doc: iio: ad7944: describe offload support David Lechner
2024-12-11 20:54 ` [PATCH v6 13/17] dt-bindings: iio: adc: adi,ad4695: add SPI offload properties David Lechner
2024-12-14 16:59 ` Jonathan Cameron
2024-12-17 14:36 ` Rob Herring (Arm)
2024-12-11 20:54 ` [PATCH v6 14/17] iio: adc: ad4695: Add support for SPI offload David Lechner
2024-12-17 12:15 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 15/17] doc: iio: ad4695: add SPI offload support David Lechner
2024-12-11 20:54 ` [PATCH v6 16/17] iio: dac: ad5791: sort include directives David Lechner
2024-12-17 12:15 ` Nuno Sá
2024-12-11 20:54 ` [PATCH v6 17/17] iio: dac: ad5791: Add offload support David Lechner
2024-12-14 17:12 ` Jonathan Cameron
2024-12-17 12:18 ` Nuno Sá [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c54da9aa3edb841b1e3d5f2fbfd0b29e89da1184.camel@gmail.com \
--to=noname.nuno@gmail.com \
--cc=Michael.Hennerich@analog.com \
--cc=ahaslam@baylibre.com \
--cc=broonie@kernel.org \
--cc=conor+dt@kernel.org \
--cc=david@protonic.nl \
--cc=devicetree@vger.kernel.org \
--cc=dlechner@baylibre.com \
--cc=jic23@kernel.org \
--cc=kernel@martin.sperl.org \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=nuno.sa@analog.com \
--cc=robh@kernel.org \
--cc=ukleinek@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.