spi工作原理参考:http://blog.csdn.net/jklinux/article/details/74287735
在内核里的配置选项:
make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
Device Drivers --->
[*] SPI support --->
<*> Allwinner A31 SPI controller //H5所用的spi控制器驱动
<*> User mode SPI device driver support //是一个spi设备驱动, 用于提供用户调用控制器的接口
spi控制器所用的驱动源码在:drivers/spi/spi-sun6i.c
495 static struct platform_driver sun6i_spi_driver = {
496 .probe = sun6i_spi_probe,
497 .remove = sun6i_spi_remove,
498 .driver = {
499 .name = "sun6i-spi",
500 .of_match_table = sun6i_spi_match,
501 .pm = &sun6i_spi_pm_ops,
502 },
503 };
483 static const struct of_device_id sun6i_spi_match[] = {
484 { .compatible = "allwinner,sun6i-a31-spi", .data = (void *)SUN6I_FIFO_DEPTH },
485 { .compatible = "allwinner,sun8i-h3-spi", .data = (void *)SUN8I_FIFO_DEPTH },
486 {}
487 };
由以上代码可见,在设备树里描述spi控制器相关的设备节点的compatible属性值应为”allwinner,sun6i-a31-spi”或”allwinner,sun8i-h3-spi”.
H5里共有两个spi控制器:
在设备树的文件arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi里,厂家已写好两个spi控制器相关的设备节点:
445 spi0_pins: spi0 {
446 pins = "PC0", "PC1", "PC2", "PC3";
447 function = "spi0";
448 };
449
450 spi1_pins: spi1 {
451 pins = "PA15", "PA16", "PA14", "PA13";
452 function = "spi1";
453 };
...
510 spi0: spi@01c68000 {
511 compatible = "allwinner,sun8i-h3-spi";
512 reg = <0x01c68000 0x1000>;
513 interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
514 clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
515 clock-names = "ahb", "mod";
516 dmas = <&dma 23>, <&dma 23>;
517 dma-names = "rx", "tx";
518 pinctrl-names = "default";
519 pinctrl-0 = <&spi0_pins>;
520 resets = <&ccu RST_BUS_SPI0>;
521 status = "disabled";
522 #address-cells = <1>;
523 #size-cells = <0>;
524 };
525
526 spi1: spi@01c69000 {
527 compatible = "allwinner,sun8i-h3-spi";
528 reg = <0x01c69000 0x1000>;
529 interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
530 clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
531 clock-names = "ahb", "mod";
532 dmas = <&dma 24>, <&dma 24>;
533 dma-names = "rx", "tx";
534 pinctrl-names = "default";
535 pinctrl-0 = <&spi1_pins>;
536 resets = <&ccu RST_BUS_SPI1>;
537 status = "disabled";
538 #address-cells = <1>;
539 #size-cells = <0>;
540 };
在板级主要的设备树文件arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts:
324 &pio {
...
337 spi0_cs_pins: spi0_cs_pins {
338 pins = "PC3", "PA6";
339 function = "gpio_out";
340 };
341 };
414 &spi0 {
415 /* needed to avoid dtc warning */
416 #address-cells = <1>;
417 #size-cells = <0>;
418
419 status = "okay";
420 pinctrl-names = "default";
421 pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
422 cs-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>, <&pio 0 6 GPIO_ACTIVE_HIGH>;
...
在设备树里厂家已经描述了两个spi控制器的设备节点,但在系统里发生只有spi0控制器是驱动好的:
^_^ / # ls /sys/bus/platform/drivers/sun6i-spi/
1c68000.spi/ bind uevent unbind
为了使用扩展口上的spi1接口,需要把spi1控制器驱动好:
参考spi0控制器在设备树里的描述, 在sun50i-h5-nanopi-neo2.dts里增加:
spi1_cs –> PA13
324 &pio {
...
341 spi1_cs_pins: spi1_cs_pins { /* spi1控制器所用的片选线 */
342 pins = "PA13";
343 function = "gpio_out";
344 };
345 };
再增加:
418 &spi1 {
419 #address-cells = <1>;
420 #size-cells = <0>;
421
422 status = "okay"; /* 此属性值为"okay"才会设备使能 */
423 pinctrl-names = "default";
424 pinctrl-0 = <&spi1_pins &spi1_cs_pins>; /* spi1控制器所用到的gpio功能配置 */
425 cs-gpios = <&pio 0 13 GPIO_ACTIVE_HIGH>;
426 };
重编设备树文件,更新并启动系统后:
^_^ / # ls /sys/bus/platform/drivers/sun6i-spi/
1c68000.spi/ 1c69000.spi/ bind uevent unbind