1、概览
spi子系统中分为spi控制器驱动和spi设备驱动。前面已经讲述了spi控制器驱动。下面讲述一下spi设备驱动。所谓的spi设备驱动,就是挂在spi总线上形形色色的芯片驱动。它可能是一个Flash芯片,一个声音编解码芯片,也可能是一个网卡芯片。这些芯片如果要正常工作,那就必须为之编写对应的驱动,这个驱动就是spi设备驱动。下面将讲解如何实现一个spi设备驱动。
2、向内核注册spi设备
如果希望一个spi设备可以在linux系统下很好的工作,除了写驱动,还要向内核申明和注册这个spi设备。目前有两种方法向内核注册一个spi设备。在稍微老点版本的内核(2.6.xx)中通过向内核注册struct spi_board_info
对象,来申明一个spi设备。在比较新的内核中(3.xx)使用device tree的方式向内核申明并注册一个spi设备的。无论使用哪种方式,其实最终的目的就是为了建立一个struct spi_deivce
对象,并注册到spi子系统中。下面就结合代码来看看是如何注册一个spi设备到内核中的。
2.1)spi_board_info的方式
这种方式新版本的内核中已经很少用了,随着device tree的普及,这种方式也不建议使用了。不过目前版本的内核中仍然支持。struct spi_board_info
的注册通常在平台的板级代码中。先来看看struct spi_board_info
这个结构体的结构:
783 struct spi_board_info {
784 /* the device name and module name are coupled, like platform_bus;
785 * "modalias" is normally the driver name.
786 *
787 * platform_data goes to spi_device.dev.platform_data,
788 * controller_data goes to spi_device.controller_data,
789 * irq is copied too
790 */
791 char modalias[SPI_NAME_SIZE];
792 const void *platform_data;
793 void *controller_data;
794 int irq;
795
796 /* slower signaling on noisy or low voltage boards */
797 u32 max_speed_hz;
798
799
800 /* bus_num is board specific and matches the bus_num of some
801 * spi_master that will probably be registered later.
802 *
803 * chip_select reflects how this chip is wired to that master;
804 * it's less than num_chipselect.
805 */
806 u16 bus_num;
807 u16 chip_select;
808
809 /* mode becomes spi_device.mode, and is essential for chips
810 * where the default of SPI_CS_HIGH = 0 is wrong.
811 */
812 u8 mode;
813
814 /* ... may need additional spi_device chip config data here.
815 * avoid stuff protocol drivers can set; but include stuff
816 * needed to behave without being bound to a driver:
817 * - quirks like clock rate mattering when not selected
818 */
819 };
下面就结合imx51的一个板级代码讲解struct spi_board_info
各个字段的含义,以及如何在板级代码中注册struct spi_board_info
。在代码kernel/arch/arm/mach-imx51-3ds.c的121行左右:
121 static struct spi_board_info mx51_3ds_spi_nor_device[] = {
122 {
123 .modalias = "m25p80",
124 .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
125 .bus_num = 1,
126 .chip_select = 1,
127 .mode = SPI_MODE_0,
128 .platform_data = NULL,},
129 };
一个struct spi_board_info
对象对应一个spi设备。上面代码中:
.modalias = "m25p80",
spi设备名字,设备驱动探测时会用到该项;.max_speed_hz = 25000000,
记录了这个spi设备支持的最大速度;.bus_num = 1,
记录了该spi设备是连接在哪个spi总线上的,所在总线的编号;.chip_select = 1,
该spi设备的片选编号;.mode = SPI_MODE_0,
和这个spi设备支持spi总线的工作模式。
配置好这些参数以后,通过下面代码将这个struct spi_board_info
对象注册到内核中,确切说是到spi子系统中去:
146 spi_register_board_info(mx51_3ds_spi_nor_device,
147 ARRAY_SIZE(mx51_3ds_spi_nor_device));
spi_register_board_info()
这个函数调用做了两件事: