diff options
Diffstat (limited to 'include/linux/spi/offload')
-rw-r--r-- | include/linux/spi/offload/consumer.h | 39 | ||||
-rw-r--r-- | include/linux/spi/offload/provider.h | 47 | ||||
-rw-r--r-- | include/linux/spi/offload/types.h | 100 |
3 files changed, 186 insertions, 0 deletions
diff --git a/include/linux/spi/offload/consumer.h b/include/linux/spi/offload/consumer.h new file mode 100644 index 000000000000..cd7d5daa21e6 --- /dev/null +++ b/include/linux/spi/offload/consumer.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +#ifndef __LINUX_SPI_OFFLOAD_CONSUMER_H +#define __LINUX_SPI_OFFLOAD_CONSUMER_H + +#include <linux/module.h> +#include <linux/spi/offload/types.h> +#include <linux/types.h> + +MODULE_IMPORT_NS("SPI_OFFLOAD"); + +struct device; +struct spi_device; + +struct spi_offload *devm_spi_offload_get(struct device *dev, struct spi_device *spi, + const struct spi_offload_config *config); + +struct spi_offload_trigger +*devm_spi_offload_trigger_get(struct device *dev, + struct spi_offload *offload, + enum spi_offload_trigger_type type); +int spi_offload_trigger_validate(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); +int spi_offload_trigger_enable(struct spi_offload *offload, + struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); +void spi_offload_trigger_disable(struct spi_offload *offload, + struct spi_offload_trigger *trigger); + +struct dma_chan *devm_spi_offload_tx_stream_request_dma_chan(struct device *dev, + struct spi_offload *offload); +struct dma_chan *devm_spi_offload_rx_stream_request_dma_chan(struct device *dev, + struct spi_offload *offload); + +#endif /* __LINUX_SPI_OFFLOAD_CONSUMER_H */ diff --git a/include/linux/spi/offload/provider.h b/include/linux/spi/offload/provider.h new file mode 100644 index 000000000000..76c7cf651092 --- /dev/null +++ b/include/linux/spi/offload/provider.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +#ifndef __LINUX_SPI_OFFLOAD_PROVIDER_H +#define __LINUX_SPI_OFFLOAD_PROVIDER_H + +#include <linux/module.h> +#include <linux/spi/offload/types.h> +#include <linux/types.h> + +MODULE_IMPORT_NS("SPI_OFFLOAD"); + +struct device; +struct spi_offload_trigger; + +struct spi_offload *devm_spi_offload_alloc(struct device *dev, size_t priv_size); + +struct spi_offload_trigger_ops { + bool (*match)(struct spi_offload_trigger *trigger, + enum spi_offload_trigger_type type, u64 *args, u32 nargs); + int (*request)(struct spi_offload_trigger *trigger, + enum spi_offload_trigger_type type, u64 *args, u32 nargs); + void (*release)(struct spi_offload_trigger *trigger); + int (*validate)(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); + int (*enable)(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); + void (*disable)(struct spi_offload_trigger *trigger); +}; + +struct spi_offload_trigger_info { + /** @fwnode: Provider fwnode, used to match to consumer. */ + struct fwnode_handle *fwnode; + /** @ops: Provider-specific callbacks. */ + const struct spi_offload_trigger_ops *ops; + /** Provider-specific state to be used in callbacks. */ + void *priv; +}; + +int devm_spi_offload_trigger_register(struct device *dev, + struct spi_offload_trigger_info *info); +void *spi_offload_trigger_get_priv(struct spi_offload_trigger *trigger); + +#endif /* __LINUX_SPI_OFFLOAD_PROVIDER_H */ diff --git a/include/linux/spi/offload/types.h b/include/linux/spi/offload/types.h new file mode 100644 index 000000000000..6f7892347871 --- /dev/null +++ b/include/linux/spi/offload/types.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +#ifndef __LINUX_SPI_OFFLOAD_TYPES_H +#define __LINUX_SPI_OFFLOAD_TYPES_H + +#include <linux/bits.h> +#include <linux/types.h> + +struct device; + +/* This is write xfer but TX uses external data stream rather than tx_buf. */ +#define SPI_OFFLOAD_XFER_TX_STREAM BIT(0) +/* This is read xfer but RX uses external data stream rather than rx_buf. */ +#define SPI_OFFLOAD_XFER_RX_STREAM BIT(1) + +/* Offload can be triggered by external hardware event. */ +#define SPI_OFFLOAD_CAP_TRIGGER BIT(0) +/* Offload can record and then play back TX data when triggered. */ +#define SPI_OFFLOAD_CAP_TX_STATIC_DATA BIT(1) +/* Offload can get TX data from an external stream source. */ +#define SPI_OFFLOAD_CAP_TX_STREAM_DMA BIT(2) +/* Offload can send RX data to an external stream sink. */ +#define SPI_OFFLOAD_CAP_RX_STREAM_DMA BIT(3) + +/** + * struct spi_offload_config - offload configuration + * + * This is used to request an offload with specific configuration. + */ +struct spi_offload_config { + /** @capability_flags: required capabilities. See %SPI_OFFLOAD_CAP_* */ + u32 capability_flags; +}; + +/** + * struct spi_offload - offload instance + */ +struct spi_offload { + /** @provider_dev: for get/put reference counting */ + struct device *provider_dev; + /** @priv: provider driver private data */ + void *priv; + /** @ops: callbacks for offload support */ + const struct spi_offload_ops *ops; + /** @xfer_flags: %SPI_OFFLOAD_XFER_* flags supported by provider */ + u32 xfer_flags; +}; + +enum spi_offload_trigger_type { + /* Indication from SPI peripheral that data is read to read. */ + SPI_OFFLOAD_TRIGGER_DATA_READY, + /* Trigger comes from a periodic source such as a clock. */ + SPI_OFFLOAD_TRIGGER_PERIODIC, +}; + +struct spi_offload_trigger_periodic { + u64 frequency_hz; +}; + +struct spi_offload_trigger_config { + /** @type: type discriminator for union */ + enum spi_offload_trigger_type type; + union { + struct spi_offload_trigger_periodic periodic; + }; +}; + +/** + * struct spi_offload_ops - callbacks implemented by offload providers + */ +struct spi_offload_ops { + /** + * @trigger_enable: Optional callback to enable the trigger for the + * given offload instance. + */ + int (*trigger_enable)(struct spi_offload *offload); + /** + * @trigger_disable: Optional callback to disable the trigger for the + * given offload instance. + */ + void (*trigger_disable)(struct spi_offload *offload); + /** + * @tx_stream_request_dma_chan: Optional callback for controllers that + * have an offload where the TX data stream is connected directly to a + * DMA channel. + */ + struct dma_chan *(*tx_stream_request_dma_chan)(struct spi_offload *offload); + /** + * @rx_stream_request_dma_chan: Optional callback for controllers that + * have an offload where the RX data stream is connected directly to a + * DMA channel. + */ + struct dma_chan *(*rx_stream_request_dma_chan)(struct spi_offload *offload); +}; + +#endif /* __LINUX_SPI_OFFLOAD_TYPES_H */ |