Linux系统SPI驱动总结(一)
3、 CPOL=1,CPHA=0 模式为2
4、CPOL=1,CPHA=1 模式为3
# Makefile for kernel SPI drivers.
#
# config declarations into driver model code
obj-$(CONFIG_SPI_MASTER) += spi.o
obj-$(CONFIG_SPI_SPIDEV) += spidev.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o
obj-$(CONFIG_SPI_IMX) += spi-imx.o
2、对应的Kconfig配置内核
| | --- SPI support | |
| | [ ] Debug support for SPI drivers | |
| | *** SPI Master Controller Drivers *** | |
| | <M> Altera SPI Controller | |
| | {M} Utilities for Bitbanging SPI masters | |
| | <M> Parallel port adapter for AVR Butterfly (DEVELOPMENT) | |
| | <M> GPIO-based bitbanging SPI Master | |
| | <M> Parallel port adapter for LM70 eval board (DEVELOPMENT) | |
| | <M> OpenCores tiny SPI | |
| | <M> PXA2xx SSP SPI master
spi_master代表一个主机控制器,一般不需要自己编写spi控制器驱动,但了解这个结构体还是必要的。
struct device dev; //设备模型使用
* board-specific. usually that simplifies to being SOC-specific.
* example: one SOC has three SPI controllers, numbered 0..2,
* and one board's schematics might show it using SPI-2. software
* would normally use bus_num=2 for that controller.
*/
s16 bus_num; // 总线(或控制器)编号
* might use board-specific GPIOs.
*/
u16 num_chipselect; // 片选数量,决定该控制器下面挂接多少个SPI设备,从设备的片选号不能大于这个数量
* buffers; let protocol drivers know about these requirements.
*/
u16 dma_alignment;
u16 mode_bits; // master支持的设备模式
u32 bits_per_word_mask;
#define SPI_BPW_MASK(bits) BIT((bits) - 1)
#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0U : (BIT(bits) - 1))
#define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1))
u32 min_speed_hz;
u32 max_speed_hz;
u16 flags;
#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 */
#define SPI_MASTER_MUST_RX BIT(3) /* requires rx */
#define SPI_MASTER_MUST_TX BIT(4) /* requires tx */
spinlock_t bus_lock_spinlock;
struct mutex bus_lock_mutex;
bool bus_lock_flag;
*
* IMPORTANT: this may be called when transfers to another
* device are active. DO NOT UPDATE SHARED REGISTERS in ways
* which could break those transfers.
*/
int (*setup)(struct spi_device *spi); // 根据SPI设备更新硬件配置。设置模式、时钟等,这个需要自己具体实现,主要设置SPI控制器和工作方式
*
* + The transfer() method may not sleep; its main role is
* just to add the message to the queue.
* + For now there's no remove-from-queue operation, or
* any other request management
* + To a given spi_device, message queueing is pure fifo
*
* + The master's main job is to process its message queue,
* selecting a chip then transferring data
* + If there are multiple spi_device children, the i/o queue
* arbitration algorithm is unspecified (round robin, fifo,
* priority, reservations, preemption, etc)
*
* + Chipselect stays active during the entire message
* (unless modified by spi_transfer.cs_change != 0).
* + The message transfers use clock and SPI mode parameters
* previously established by setup() for this device
*/
int (*transfer)(struct spi_device *spi,
struct spi_message *mesg);// 添加消息到队列的方法。这个函数不可以睡眠。主要是安排发生的传送并且调用注册的回调函数complete()。这个不同的控制器要具体实现,传输数据最后都要调用这个函数
void (*cleanup)(struct spi_device *spi);// 在spidev_release函数中被调用。
* Used to enable core support for DMA handling, if can_dma()
* exists and returns true then the transfer will be mapped
* prior to transfer_one() being called. The driver should
* not modify or store xfer and dma_tx and dma_rx must be set
* while the device is prepared.
*/
bool (*can_dma)(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *xfer);
* These hooks are for drivers that want to use the generic
* master transfer queueing mechanism. If these are used, the
* transfer() function above must NOT be specified by the driver.
* Over time we expect SPI drivers to be phased over to this API.
*/
bool queued;
struct kthread_worker kworker;
struct task_struct *kworker_task;
struct kthread_work pump_messages;
spinlock_t queue_lock;
struct list_head queue;
struct spi_message *cur_msg;
bool busy;
bool running;
bool rt;
bool auto_runtime_pm;
bool cur_msg_prepared;
bool cur_msg_mapped;
struct completion xfer_completion;
size_t max_dma_len;
int (*transfer_one_message)(struct spi_master *master,
struct spi_message *mesg);
int (*unprepare_transfer_hardware)(struct spi_master *master);
int (*prepare_message)(struct spi_master *master,
struct spi_message *message);
int (*unprepare_message)(struct spi_master *master,
struct spi_message *message);
* These hooks are for drivers that use a generic implementation
* of transfer_one_message() provied by the core.
*/
void (*set_cs)(struct spi_device *spi, bool enable);
int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
struct spi_transfer *transfer);
int *cs_gpios;
struct dma_chan *dma_tx;
struct dma_chan *dma_rx;
void *dummy_rx;
void *dummy_tx;
};
struct device dev;// 设备模型使用
struct spi_master *master;// 设备使用的master结构,挂接在哪个主控制器下
u32 max_speed_hz;// 通信时钟最大频率
u8 chip_select;// 片选号,每个master支持多个spi_device
u8 bits_per_word;// 每个字长的比特数,默认是8
u16 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 /* chipselect active high? */
#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */
#define SPI_3WIRE 0x10 /* SI/SO signals shared */
#define SPI_LOOP 0x20 /* loopback mode */
#define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */
#define SPI_READY 0x80 /* slave pulls low to pause */
#define SPI_TX_DUAL 0x100 /* transmit with 2 wires */
#define SPI_TX_QUAD 0x200 /* transmit with 4 wires */
#define SPI_RX_DUAL 0x400 /* receive with 2 wires */
#define SPI_RX_QUAD 0x800 /* receive with 4 wires */
int irq;// 中断号
void *controller_state;// 控制寄存器状态
void *controller_data;
char modalias[SPI_NAME_SIZE];
int cs_gpio; /* chip select gpio */
* likely need more hooks for more protocol options affecting how
* the controller talks to each chip, like:
* - memory packing (12 bit samples into low bits, others zeroed)
* - priority
* - drop chipselect after each word
* - chipselect delays
* - ...
*/
};
spi_driver代表一个SPI协议驱动,也就是外设驱动。
const struct spi_device_id *id_table; // 支持的spi_device设备表
int (*probe)(struct spi_device *spi);
int (*remove)(struct spi_device *spi);// 解除spi_device和spi_driver的绑定,释放probe申请的资源
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;// 设备模型使用
};
/* it's ok if tx_buf == rx_buf (right?)
* for MicroWire, one buffer must be null
* buffers must work with dma_*map_single() calls, unless
* spi_message.is_dma_mapped reports a pre-existing mapping
*/
const void *tx_buf;
void *rx_buf;
unsigned len;
dma_addr_t rx_dma;
struct sg_table tx_sg;
struct sg_table rx_sg;
unsigned tx_nbits:3;
unsigned rx_nbits:3;
#define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */
#define SPI_NBITS_DUAL 0x02 /* 2bits transfer */
#define SPI_NBITS_QUAD 0x04 /* 4bits transfer */
u8 bits_per_word;
u16 delay_usecs;
u32 speed_hz;
};
Linux系统SPI驱动总结(一)相关推荐
- Linux系统SPI驱动总结
平台:rk3288 系统:Android7.1 kernel4.4.143 linux spi 驱动分为三部分: SPI外设驱动:我们写.oled,spi flash 等 linux spi核心层:d ...
- 转载:Linux kernel SPI驱动解释
From: http://www.cnblogs.com/liugf05/archive/2012/12/03/2800457.html 下面有两个大的模块: 一个是SPI总线驱动的分析 ...
- linux中spi驱动框架
原 linux中spi驱动框架 2016年09月14日 15:57:06 andylauren 阅读数:403 <span class="tags-box artic-tag-box& ...
- linux系统网络驱动简介
网络设备驱动简介 网络设备驱动是linux内核中三大类设备驱动之一,它用来完成高层网络协议的底层数据传输及设备控制. 网络设备与其他两种设备的区别: 网络接口不存在于linux的文件系统中,及/dev ...
- linux系统LCD驱动(三):mtk lcd驱动lcm的加载以及初始化
上一篇博文(linux系统LCD驱动(二):mtk lcd驱动fb_info初始化)https://blog.csdn.net/Ian22l/article/details/105929192 提到m ...
- Linux下spi驱动分析与测试【详细流程】
驱动是基于ARM的pl022的SSP控制器,其支持三种通信格式:SPI.SSI以及Microwrite,llinux5.4内核下,SSP控制器驱动的路径为/drivers/spi/spi-pl022. ...
- Linux下SPI驱动详解
更多嵌入式原创文章,请关注公众号:一口Linux 1. SPI总线 1.1. SPI总线概述 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口. ...
- Linux下SPI驱动详解(干货)
关注.星标公众号,直达精彩内容 本文由嵌入式大牛:蒙工投稿! 1. SPI总线 1.1. SPI总线概述 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外 ...
- linux系统无线驱动在哪下载,在linux上怎么安装无线网卡驱动?
在linux上怎么安装无线网卡驱动? 在linux上安装无线网卡驱动的方法: (1)先确定无线网卡型号,因驱动安装和型号是密切相关的,不同的型号,安装和下载驱动有所不同,但原理是一样的.图例为无线网卡 ...
最新文章
- hive 修改分桶数 分桶表_Hive中的分桶
- 小胖机器人能刷碗吗_小胖机器人好不好?透过真相看本质
- 原相机水印怎么改字_抖音/自媒体做影视二次剪辑,如何下载高清无水印视频?...
- PHP类的静态(static)方法和静态(static)变量使用介绍
- 期货与期权(part5)--期货市场机制
- 对抗思想与强化学习的碰撞-SeqGAN模型原理和代码解析
- java打包----“Artifacts”
- Java url转MultipartFile inputStream转File file转multipartFile
- 求职必备素材:个人简历Word模板
- 三维模型重建(1):关于三维模型重建的一些简介
- 阿里云国际版控制台使用海外云服务器教程详解
- 【CyberSecurityLearning 12】数据链路层 及 交换机工作原理与配置
- 团队用过最好的bug管理软件-delbug管理
- edgexfoundry docker 容器化部署 ubuntu16.4 跑起来 go0.6.0 版
- 了不起的 Webpack HMR 学习指南(含源码分析)
- EditText设置输入的类型,比如说限制只能输入字母和数字
- 青藤 #10115 栈练习1
- 会声会影如何新建html项目,会声会影如何使用即时项目模板
- RocketMQTemplate 注入失败
- 关于如何获得虚拟机还是真机信息