QSPI Flash驱动代码分析(spi主设备驱动框架)
SPI主设备驱动的主要功能是:
- 向上提供 struct spi_master 主设备驱动接口和struct spi_controller_mem_ops相关访问操作方法。
- 向下管理SPI控制器。
1. struct spi_master结构体分配
/*linux/spi/spi.h*/
static inline struct spi_controller *spi_alloc_master(struct device *host,
unsigned int size)
参数介绍:
- 第一个参数是SPI控制器对应的device结构;
- 第二个参数是SPI控制器私有结构体的长度;
可以通过宏spi_master_get_devdata(),根据struct spi_master结构体来获取私有结构体。
2.struct spi_controller结构体
即struct spi_master结构
struct spi_controller {
struct device dev;
struct list_head list;
s16 bus_num;
/*SPI总线提供的有效片选信号数量,也可以指有效Flash芯片数量*/
u16 num_chipselect;
u16 dma_alignment;
/*由SPI驱动提供的描述SPI控制器的收发模式*/
u32 mode_bits;
u32 buswidth_override_bits;
u32 bits_per_word_mask;
u32 min_speed_hz;
/*设置为SPI设备的参考时钟频率*/
u32 max_speed_hz;
u16 flags;
bool devm_allocated;
bool slave;
size_t (*max_transfer_size)(struct spi_device *spi);
size_t (*max_message_size)(struct spi_device *spi);
struct mutex io_mutex;
spinlock_t bus_lock_spinlock;
struct mutex bus_lock_mutex;
bool bus_lock_flag;
int (*setup)(struct spi_device *spi);
int (*set_cs_timing)(struct spi_device *spi, struct spi_delay *setup,
struct spi_delay *hold, struct spi_delay *inactive);
int (*transfer)(struct spi_device *spi,
struct spi_message *mesg);
void (*cleanup)(struct spi_device *spi);
bool (*can_dma)(struct spi_controller *ctlr, struct spi_device *spi,
struct spi_transfer *xfer);
bool queued;
struct kthread_worker *kworker;
struct kthread_work pump_messages;
spinlock_t queue_lock;
struct list_head queue;
struct spi_message *cur_msg;
bool idling;
bool busy;
bool running;
bool rt;
bool auto_runtime_pm;
bool cur_msg_prepared;
bool cur_msg_mapped;
bool last_cs_enable;
bool last_cs_mode_high;
bool fallback;
struct completion xfer_completion;
size_t max_dma_len;
int (*prepare_transfer_hardware)(struct spi_controller *ctlr);
int (*transfer_one_message)(struct spi_controller *ctlr,
struct spi_message *mesg);
int (*unprepare_transfer_hardware)(struct spi_controller *ctlr);
int (*prepare_message)(struct spi_controller *ctlr,
struct spi_message *message);
int (*unprepare_message)(struct spi_controller *ctlr,
struct spi_message *message);
int (*slave_abort)(struct spi_controller *ctlr);
void (*set_cs)(struct spi_device *spi, bool enable);
int (*transfer_one)(struct spi_controller *ctlr, struct spi_device *spi,
struct spi_transfer *transfer);
void (*handle_err)(struct spi_controller *ctlr,
struct spi_message *message);
/*由SPI驱动提供的访问SPI内存操作方法*/
const struct spi_controller_mem_ops *mem_ops;
struct spi_delay cs_setup;
struct spi_delay cs_hold;
struct spi_delay cs_inactive;
int *cs_gpios;
struct gpio_desc **cs_gpiods;
bool use_gpio_descriptors;
s8 unused_native_cs;
s8 max_native_cs;
struct spi_statistics statistics;
struct dma_chan *dma_tx;
struct dma_chan *dma_rx;
void *dummy_rx;
void *dummy_tx;
int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
bool ptp_sts_supported;
unsigned long irq_flags;
};
3. struct spi_controller_mem_ops访问SPI内存操作结构体
struct spi_controller_mem_ops {
int (*adjust_op_size)(struct spi_mem *mem, struct spi_mem_op *op);
bool (*supports_op)(struct spi_mem *mem,
const struct spi_mem_op *op);
int (*exec_op)(struct spi_mem *mem,
const struct spi_mem_op *op);
const char *(*get_name)(struct spi_mem *mem);
int (*dirmap_create)(struct spi_mem_dirmap_desc *desc);
void (*dirmap_destroy)(struct spi_mem_dirmap_desc *desc);
ssize_t (*dirmap_read)(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, void *buf);
ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc,
u64 offs, size_t len, const void *buf);
};
其中 supports_op判断访问是否被支持,exec_op是具体实现SPI内存访问操作的接口。
4. 向系统注册SPI master设备
devm_spi_register_master(_dev, _ctlr)
向系统注册SPI主设备,第一个参数是SPI设备的device结构体,第二参数是SPI设备的spi_master结构体。