linux驅動基礎系列--linux spi驅動框架分析(續)


前言

  這篇文章是對linux驅動基礎系列--linux spi驅動框架分析的補充,主要是添加了最新的linux內核里設備樹相關內容。

spi設備樹相關信息

  如之前的文章里所述,控制器的device和spi device都是通過platform_add_devicespi_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 < 0spi_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月


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM