I first learned about the main structure of the SPI driver when I learned the Linux bus driver with cainiao.

Source: Internet
Author: User


Now that we know the protocol, we can start to look at the SPI driver code in Linux kenerl. There are many struct in the code, so let's take a look at the main struct first, in this way, we can better understand the driver. Mainly include/Linux/SPI. h

 

The first is the communication interface between the SPI host and the slave, that is, the SPI bus,

extern struct bus_type spi_bus_type; 

Bus_type is defined in Linux/device. h.

 

Struct bus_type {const char * Name; // bus name struct bus_attribute * bus_attrs; struct device_attribute * dev_attrs; struct driver_attribute * drv_attrs; // matching between the device and driver on the bus, if the match succeeds, a non-0 value int (* match) (struct device * Dev, struct device_driver * DRV) is returned. INT (* uevent) (struct device * Dev, struct kobj_uevent_env * env) is returned ); // when a new device or driver is added to the bus, call the probe function in the driver to match int (* probe) (struct device * Dev); int (* remove) (struct device * Dev); void (* shutdown) (struct device * Dev); int (* suspend) (struct device * Dev, pm_message_t State); int (* resume) (struct device * Dev); const struct dev_pm_ops * PM; struct subsys_private * P ;};

 

SPI Device

 

Struct spi_device {struct device dev; struct spi_master * master; // SPI controller u32 max_speed_hz; // maximum clock frequency u8 chip_select; // The u8 mode is selected for each piece; // SPI mode # define spi_cpha 0x01/* Clock Phase */# define spi_cpol 0x02/* Clock polarity */# define spi_mode_0 (0 | 0) /* (original Microwire) */# define spi_mode_1 (0 | spi_cpha) # define spi_mode_2 (spi_cpol | 0) # define spi_mode_3 (spi_cpol | spi_cpha) # define spi_cs_high 0x04/* Ch Ipselect active high? */# Define spi_lsb_first 0x08/* per-word bits-on-wire */# define spi_3wire 0x10/* Si/so signals shared */# define spi_loop 0 x 20/* loopback mode */# define spi_no_cs 0x40/* 1 DEV/bus, no chipselect */# define spi_ready 0x80/* slave pulls low to pause */u8 bits_per_word; // One-time transmitted BITs, which can be 8, 16, 32, the default value is 8 int IRQ; void * controller_state; void * controller_data; char modalias [spi_name_size]; // alias, used for device and driver matching };

 

 

SPI driver

 

Struct spi_driver {const struct spi_device_id * id_table; int (* probe) (struct spi_device * SPI); // bind the driver and SPI device int (* remove) (struct spi_device * SPI ); void (* shutdown) (struct spi_device * SPI); int (* suspend) (struct spi_device * SPI, pm_message_t mesg); int (* resume) (struct spi_device * SPI ); struct device_driver driver ;};

 

SPI master controller

 

Struct spi_master {struct device dev; // device interface of the driver struct list_head list; // The S16 bus_num head of the SPI controller; // bus number/* chipselects will be integral to custom controllers; some others * might use board-specific gpios. */2010num_chipselect; // SPI device chip number: 2010dma_alignment; // DMA mode/* spi_device.mode flags understood by this controller driver */2010mode_bits; /* Other constraints relevant to this driver */servicflags; # define spi_master_half_duplex bit (0)/* can't do full duplex */# define spi_master_no_rx bit (1) /* can't do Buffer read */# define spi_master_no_tx bit (2) /* can't do Buffer write * // * Lock and mutex for SPI bus locking */spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; bool bus_lock_flag; int (* setup) (struct spi_device * SPI); // update the SPI device mode and the SPI device's sampling clock int (* Transfer) (struct spi_device * SPI, // Add a message to the transmission queue struct spi_message * mesg of the Controller; void (* cleanup) (struct spi_device * SPI );};

 

SPI Transmission

 

Struct spi_transfer {/* it's OK if tx_buf = rx_buf (right ?) * For Microwire, one buffer must be null * buffers must work with DMA _ * map_single () CILS, unless * spi_message.is_dma_mapped reports a pre-existing mapping */const void * tx_buf; // The Void * rx_buf of the data to be written; // The unsigned Len of the data to be read; // The dma_addr_t tx_dma of the Data Length; // The dma_addr_t rx_dma address of tx_buf; // The DMA address of rx_buf unsigned cs_change: 1; u8 bits_per_word; // number of bytes transmitted. If this parameter is not selected, the default value of the domain name is "maid, change the pre-selected signal u32 speed_hz; // transmission rate. If this parameter is not selected, use the default struct list_head transfer_list; // transmission linked list to transmit spi_message };

 

SPI message

 

Struct spi_message {struct list_head transfers; // struct spi_device * SPI; // The SPI device added to the transport queue unsigned is_dma_mapped: 1; // DMA transmission control bit/* completion is reported through a callback */void (* Complete) (void * context); // void * context after transmission is completed; // The parameter unsigned actual_length of the complete function; // The total length of all successfully transmitted fields int status; // if the transfer is successful, 0 is returned, otherwise, an error is returned./* for optional use by whatever driver currently owns the * spi_message... between callto spi_async and then later * Complete (), that's the spi_master controller driver. */struct list_head queue; void * State ;};

 

SPI bitbang

 

struct spi_bitbang {       struct workqueue_struct *workqueue;       struct work_struct   work;       spinlock_t              lock;       struct list_head       queue;       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);};

The most common structure in the SPI controller is spi_bitbang.

 

SPI borad info

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.  */ u8  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  */};

The Controller reads the parameters in borad info.

 

SPI gpio_platform_data

 

struct spi_gpio_platform_data {       unsigned  sck;       unsigned  mosi;       unsigned  miso;       u16         num_chipselect;};

Because I used gpio simulation, I recorded the pin number passed in from platform.

 

OK. The structure used by SPI is basically described. Next we will introduce the main functions.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.