SPI串行外围设备驱动移植
仇洁婷,陈儒军
SPI 串行外围设备接口是一种高速的,全双工,同步的通信总线,它只需用四根线:时钟线 SCK 、片选线 NPSC 、数据输入线 MOSI 和数据输出线 MISO ,不仅节约了芯片管脚,而且也节省 PCB 的布局空间。
在 Linux-2.6.21 内核中,有两组 SPI 代码: SPI Support ,Atmel SPI Controler 和 SPI Driver(legacy) for at91rm9200 processor 。前者是内核增加的 SPI 新代码,后者是为了兼容以前版本,而作为保留选项。本文采用 SPI Driver(legacy) for at91rm9200 processor 中的代码。该代码主要由 linux-2.6.21/drivers/char/ 目录下的 at91_spi.c 和 at91_spidev.c 实现。
( 1 ) at91_spi.c 文件
at91_spi.c 文件实现了 spi 设备驱动的加载和卸载,并向 at91_spidev.c 文件导出 3 个函数: spi_access_bus() 函数用于使能 SPI 总线,完成 SPI 传输前的准备工作; spi_transfer() 函数实现 SPI 传输; spi_release_bus() 函数释放 SPI 总线。
EXPORT_SYMBOL(spi_access_bus);
EXPORT_SYMBOL(spi_release_bus);
EXPORT_SYMBOL(spi_transfer);
SPI 驱动的加载由 at91spi_init() 实现。它调用 platform_driver_register (&at91spi_driver) 注册 spi 驱动,进而转向 at91spi_probe() 函数。 at91spi_probe() 函数获取了 SPI 使用的内存、时钟源,调用 ioremap 完成内存的物理地址到虚拟空间的映射,设置 SPI 的传输速率和 SPI0~SPI3 的传输模式,最后注册 SPI 的中断号。
SPI 驱动的卸载由 at91spi_exit() 实现,包括:禁止 SPI 总线传输、释放 SPI 的内存资源和中断号等。
( 2 ) at91_spidev.c 文件
at91_spidev.c 文件实现了 SPI 设备号的注册和释放,以及 SPI 设备文件接口函数。文件接口 spidev_fops 代码如下:
static struct file_operations spidev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = spidev_rd_wr,
.write = (int (*) (struct file *file, const char *buf, size_t count, loff_t *offset))spidev_rd_wr,
.ioctl = spidev_ioctl,
.open = spidev_open,
.release = spidev_close,
};
其中 read() 和 write() 都是采用 spidev_rd_wr() 函数实现。 spidev_rd_wr() 函数通过调用 at91_spi.c 文件的三个导出函数来实现 SPI 的传输:
spi_access_bus(spi_device);
spi_transfer(list);
spi_release_bus(spi_device);
为了 AT91RM9200 和 CS5376A 的 SPI 接口能够通信,需要在 Linux2.6 内核的 SPI 驱动程序上修改 3 个地方。
转载本文请联系原作者获取授权,同时请注明本文来自陈儒军科学网博客。 链接地址: https://blog.sciencenet.cn/blog-39626-332586.html
上一篇:
UART串口驱动程序移植 下一篇:
USB驱动移植