linux驱动基础系列--linux spi驱动框架分析(续)
前言
这篇文章是对linux驱动基础系列--linux spi驱动框架分析的补充,主要是添加了最新的linux内核里设备树相关内容。
spi设备树相关信息
如之前的文章里所述,控制器的device和spi device都是通过platform_add_device
和spi_register_board_info
注册到内核的驱动模式中的。而最新的方式是通过设备树来实现的。以arm为例,设备树文件一般存放在arch/arm/boot/dts下,不同的平台对应不同的文件,以xilinx zynq平台为例,最顶层的文件为zynq-zturn.dts,它包含了zynq-7000.dtsi。在zynq-7000.dtsi中,有两个节点用于对该soc的spi控制器的描述:
spi0: spi@e0006000 {
compatible = "xlnx,zynq-spi-r1p6";
reg = <0xe0006000 0x1000>;
status = "disabled";
interrupt-parent = <&intc>;
interrupts = <0 26 4>;
clocks = <&clkc 25>, <&clkc 34>;
clock-names = "ref_clk", "pclk";
#address-cells = <1>;
#size-cells = <0>;
};
spi1: spi@e0007000 {
compatible = "xlnx,zynq-spi-r1p6";
reg = <0xe0007000 0x1000>;
status = "disabled";
interrupt-parent = <&intc>;
interrupts = <0 49 4>;
clocks = <&clkc 26>, <&clkc 35>;
clock-names = "ref_clk", "pclk";
#address-cells = <1>;
#size-cells = <0>;
};
当我们项目中用到spi1控制器时,我们只需要在zynq-7000.dtsi中添加节点:
&spi1 {
status = "okay";
num-cs = <4>;
xxx@0 {
compatible = "yyy";
reg = <0x0>;
spi-max-frequency = <50000000>;
spi-cpol;
spi-cpha;
spi-cs-high;
};
};
然后在aliases节点中添加alias,如
aliases {
ethernet0 = &gem0;
serial0 = &uart1;
serial1 = &uart0;
spi1 = &spi1;
};
上面的status = "okay"用于使能该控制器,num-cs = <4>;用于指定最多支持4个片选,xxx可以修改为自己期望的名字,compatible字段的yyy需要替换成spi驱动对应的字串,spi-max-frequency用于设置支持的最大频率,reg用于设置该spi设备对应的片选,这个和硬件有关,spi-cpol和spi-cpha字段用于设置时钟极性和时钟相位,更加详细的意思参考Documentation/devicetree/bindings/spi/spi-bus.txt。spi-bus.txt里所描述的属性的解析位于drivers/spi/spi.c中,在控制器驱动调用spi_register_master
注册的时候处理。下面以为什么需要在aliases中添加spi1=&spi1为例子说明下解析的过程。
在spi_register_master
中,如果检测到master->bus_num < 0
(spi_alloc_master
分配的时候就设置为-1了)且存在设备节点,那么就用of_alias_get_id
从alias节点中提取该spi节点对应的编号作为总线号,也就是说,上面的添加会导致该控制器对应的spi总线号为1了,如果不加,那么内核通过atomic_dec_return(&dyn_bus_id)
自动分配一个。
if ((master->bus_num < 0) && master->dev.of_node)
master->bus_num = of_alias_get_id(master->dev.of_node, "spi");
/* convention: dynamically assigned bus IDs count down from the max */
if (master->bus_num < 0) {
/* FIXME switch to an IDR based scheme, something like
* I2C now uses, so we can't run out of "dynamic" IDs
*/
master->bus_num = atomic_dec_return(&dyn_bus_id);
dynamic = 1;
}
最后再讲下spi-cs-high属性,在spi-bus.txt中描述如下:
- spi-cs-high - (optional) Empty property indicating device requires
chip select active high
如果设置了该属性,那么在每次需要读写spi前,控制器的回调set_cs
参数enable为true,读写spi完成后,控制器的回调set_cs
参数enable为false,否则反之。
完!
2016年10月
linux驱动基础系列--linux spi驱动框架分析(续)的更多相关文章
- linux驱动基础系列--linux spi驱动框架分析
前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...
- linux驱动基础系列--Linux mmc sd sdio驱动分析
前言 主要是想对Linux mmc子系统(包含mmc sd sdio)驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.块设备驱动.设备模型等也不进行详细说明原 ...
- linux驱动基础系列--Linux I2c驱动分析
前言 主要是想对Linux I2c驱动框架有一个整体的把控,因此会忽略协议上的某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型.sysfs等也不进行详细说明原理,涉及到i2c协议部分也只 ...
- linux驱动基础系列--Linux下Spi接口Wifi驱动分析
前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...
- linux驱动基础系列--Linux 串口、usb转串口驱动分析
前言 主要是想对Linux 串口.usb转串口驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如字符设备驱动.平台驱动等也不进行详细说明原理.如果有任何错误地方,请指出, ...
- linux驱动基础系列--linux rtc子系统
前言 linux驱动子系统太多了,连时钟也搞了个子系统,这导致一般的时钟芯片的驱动也会涉及到至少2个子系统,一个是时钟芯片接口子系统(比如I2c接口的时钟芯片),一个是内核给所有时钟芯片提供的rtc子 ...
- Linux驱动修炼之道-SPI驱动框架源码分析(上)【转】
转自:http://blog.csdn.net/lanmanck/article/details/6895318 SPI驱动架构,以前用过,不过没这个详细,跟各位一起分享: 来自:http://blo ...
- Linux基础系列—Linux体系结构和Linux内核结构
/** ****************************************************************************** * @author 暴走的小 ...
- Linux入门基础(一):Linux基本操作
命令行BASH基本操作 Shell 用户不能直接操作内核,所以用户操作通过shell传递给内核 shell分为两种 : GUI 图形界面 (linux一般是GNOME) CLI 命令行界面 (linu ...
随机推荐
- 阿里云SLB上http强制跳转到https问题处理
背景: 最近一客户有一个需求,需要将外网所有http访问请求强制跳转到https,公网出口使用阿里云SLB,证书放在SLB上,SLB后端实例为ECS(webserver)web服务使用nginx, 网 ...
- octomap建立
1.安装ros的octomap ---已完成 2.阅读相关论文,了解其机理,并编写程序实现. 参考网页:https://www.cnblogs.com/gaoxiang12/p/5041142.ht ...
- Python 异步编程笔记:asyncio
个人笔记,不保证正确. 虽然说看到很多人不看好 asyncio,但是这个东西还是必须学的.. 基于协程的异步,在很多语言中都有,学会了 Python 的,就一通百通. 一.生成器 generator ...
- NO5——素数筛选
#include <stdio.h> int main() { ]={}; ;i<=;i++) a[i]=; ;i<=;i++) if(a[i]) ;j+=i) a[j]=; ...
- 用OneNote写博客的方法
1.进入OneNote要发布博客的分区然后点击菜单栏中的文件 2.点击发送至博客 3.这时候会启动word程序弹出下面的对话框(如果你从未设置过)点击立即注册 ...
- Jboss提示:Server already running on localhost
最近在做项目中,经常遇到JBoss报如下提示:Server already running on localhost.这时Jboss显示已启动,但页面显示不出来.提示中给出了两种解决办法,运行新的服务 ...
- Redis--各个数据类型最大存储量
原文地址:https://redis.io/topics/data-types Strings类型:一个String类型的value最大可以存储512M Lists类型:list的元素个数最多为2^3 ...
- ArcGis下的叠加分析
1矢量与矢量叠加的话就用ToolBox里有Overlay: 2如果是矢量和栅格叠加的话用Spatial analysis模块中的 zonal statistics: 3还有就是栅格与栅格的叠加S ...
- dp类模板
1.n串最长公共子序列 #include<cstdio> #include<cstring> #include<algorithm> using namespace ...
- 机器学习:最近邻规则KNN算法
这个算法就比较简单易懂了 就是把每个向量的特征值抽象成坐标,寻找最近的k个点,来进行划分 代码如下 #include <iostream> #include <cstdio> ...