root/include/linux/spi/offload/types.h
/* 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,
};

/**
 * spi_offload_trigger_periodic - configuration parameters for periodic triggers
 * @frequency_hz: The rate that the trigger should fire in Hz.
 * @offset_ns: A delay in nanoseconds between when this trigger fires
 *             compared to another trigger. This requires specialized hardware
 *             that supports such synchronization with a delay between two or
 *             more triggers. Set to 0 when not needed.
 */
struct spi_offload_trigger_periodic {
        u64 frequency_hz;
        u64 offset_ns;
};

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 */