Linux system SPI driver summary (2)

5. Data structure spi_message

spi_message represents a spi message, which consists of multiple spi_transfer segments. spi_message is used to atomically execute a sequence of array transfer requests represented by spi_transfer. This transmission queue is atomic, which means that no other messages occupy the bus until this message is complete. Message execution is always in FIFO order. The code that submits spi_message to the bottom layer is responsible for managing its memory space. Memory that is not shown initialized needs to be initialized with 0.

struct spi_message {
        struct list_head        transfers;
        struct spi_device       *spi;// 传输的目的设备
        unsigned                is_dma_mapped:1;// 如果为真,此次调用提供dma和cpu虚拟地址
        /* REVISIT:  we might want a flag affecting the behavior of the
         * last transfer ... allowing things like "read 16 bit length L"
         * immediately followed by "read L bytes".  Basically imposing
         * a specific message scheduling algorithm.
         *
         * Some controller drivers (message-at-a-time queue processing)
         * could provide that as their default scheduling algorithm.  But
         * others (with multi-message pipelines) could need a flag to
         * tell them about such special cases.
         */
        /* completion is reported through a callback */
        void (*complete)(void *context);// the callback function after the asynchronous call is completed
        void *context;// the parameters of the callback function
        unsigned frame_length;
        unsigned actual_length;// The actual transmission data length
        int status;// The sending result of the message is successfully set to 0, otherwise it is a negative error code
        /* for optional use by whatever driver currently owns the
         * spi_message . .. between calls to spi_async and then later
         * complete(), that's the spi_master controller driver.
         */
        struct list_head queue;
        void                    *state;

};

6. Data structure spi_board_info

The board-level information of spi_device is described by the spi_board_info structure, which records the host control serial number, chip select signal, data bit rate, SPI transmission mode, etc. used by the SPI peripheral. After the kernel after ARM Linux3.x is changed to the device tree, it is no longer necessary to encode the board-level information of the SPI in arch/arm/mach-xxx, and it tends to fill in the child nodes under the SPI controller node.

struct spi_board_info {
        /* the device name and module name are coupled, like platform_bus;
         * "modalias" is normally the driver name.
         *
         * platform_data goes to spi_device.dev.platform_data,
         * controller_data goes to spi_device.controller_data,
         * irq is copied too
         */
        char            modalias[SPI_NAME_SIZE];
        const void      *platform_data;
        void            *controller_data;
        int             irq;
        /* slower signaling on noisy or low voltage boards */
        u32             max_speed_hz;

        /* bus_num is board specific and matches the bus_num of some
         * spi_master that will probably be registered later.
         *
         * chip_select reflects how this chip is wired to that master;
         * it's less than num_chipselect.
         */
        u16             bus_num;
        u16             chip_select;

        /* mode becomes spi_device.mode, and is essential for chips
         * where the default of SPI_CS_HIGH = 0 is wrong.
         */
        u16             mode;

        /* ... may need additional spi_device chip config data here.
         * avoid stuff protocol drivers can set; but include stuff
         * needed to behave without being bound to a driver:
         *  - quirks like clock rate mattering when not selected
         */

};

7. Data structure spi_bitbang

spi_bitbang is a specific data structure responsible for information transmission.

struct spi_bitbang {
spinlock_t lock;
u8 busy;//忙标志
u8 use_dma;
u8 flags; /* extra spi->mode support */
struct spi_master *master;
/* setup_transfer() changes clock and/or wordsize to match settings
* for this transfer; zeroes restore defaults from spi_device.
*/
int (*setup_transfer)(struct spi_device *spi,
struct spi_transfer *t);// 对数据传输进行设置

void (*chipselect)(struct spi_device *spi, int is_on);// 控制片选
#define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */
#define BITBANG_CS_INACTIVE 0

/* txrx_bufs() may handle dma mapping for transfers that don't
* already have one (transfer.{tx,rx}_dma is zero), or use PIO
*/
int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);//实际的数据传输函数

/* txrx_word[SPI_MODE_*]() just looks like a shift register */
u32 (*txrx_word[4])(struct spi_device *spi,
unsigned nsecs,
u32 word, u8 bits);

};

5. SPI-driven software architecture

In the software architecture driven by the kernel SPI, reasonable layering and abstraction are carried out, as shown in the following figure:


1. SPI controller driver

The SPI controller does not need to care about the specific functions of the device. It is only responsible for sending the data prepared by the upper-layer protocol driver to the SPI device according to the timing requirements of the SPI bus, and returning the data received from the device to the upper-layer protocol driver. Therefore, the kernel Separate the driver of the SPI controller. The SPI controller driver is responsible for controlling specific controller hardware, such as DMA and interrupt operations, because multiple upper-layer protocol drivers may request data transfer operations through the controller, so the SPI controller driver is also responsible for these requests. Queue management, to ensure the principle of first-in, first-out.

2. SPI general interface encapsulation layer

In order to simplify the writing of the SPI driver and reduce the coupling between the protocol driver and the controller driver, the Linux kernel encapsulates some general operations of the controller driver and the protocol driver into a standard interface, plus some general logic processing. operation, which constitutes the SPI general interface encapsulation layer. The advantage is that for the controller driver, it only needs to implement the standard interface callback API and register it with the common interface layer, without directly interacting with the protocol layer driver. For the protocol layer driver, the registration of the device and the driver can be completed only through the API provided by the general interface layer, and the data transmission is completed through the API of the general interface layer, without paying attention to the implementation details of the SPI controller driver.

3. SPI protocol driver

The controller driver does not know and pay attention to the specific function of the device. The specific function of the SPI device is completed by the SPI protocol driver. The SPI protocol driver understands the function of the device and the protocol format of the communication data. Downward, the protocol driver exchanges data with the controller through the general interface layer. Upward, the protocol driver usually interacts with other subsystems of the kernel according to the specific functions of the device, for example, with the MTD layer to implement the SPI interface storage device as A file system that interacts with the TTY subsystem to implement an SPI device as a TTY device, interacts with the network subsystem to implement an SPI device as a network device, and so on. If it is a proprietary SPI device, it can also implement its own proprietary protocol driver according to the protocol requirements of the device.

4. SPI generic device driver

Sometimes, considering the variability of the devices connected to the SPI controller, the corresponding protocol driver is not equipped in the kernel. For this case, the kernel prepares a generic SPI device driver, which provides the user space Provides a control interface for controlling SPI control, and the specific protocol control and data transmission work is completed by the user space according to the specific device. In this way, only synchronous mode can be used to communicate with the SPI device. Simple SPI device with less data.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325882750&siteId=291194637