SPI 专题(三)-- linux spi driver 框架

 

 

本文基于 linux4.6.69 + ti am335x 分析

 

1、linux 下 spi driver 的代码文件

 

下面两个文件是 TI 平台 spi 控制器驱动 , 主要和SOC的相关的寄存器配置有关,和具体的外设 SPI设备进行物理上的通信。

drivers/spi/spi-omap2-mcspi.c  (master)

drivers/spi/spi-omap2-mcspi-slave.c  (slave)

下面的 spi.c 主要是注册spi bus , 一个SOC的 spi 控制器对应一个 spi bus , 对应一个 spi_master

drivers/spi/spi.c

下面的 spidev.c 属于 protocol drivers, 属于一种通用的spi 驱动,可选的,如果你要使用其他driver,比如 spi-flash , FRAM ,或者bitbang,也是可以的, 如果你在设备树中添加的spi 设备的 compatible=“spidev” 的话,匹配成功之后,就会产生 /dev/spidevX.Y 设备节点,通过这个节点可以和应用层进行交互

drivers/spi/spidev.c

	 spidev_read 
			(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
			
	 spidev_write
			(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)

	 spidev_ioctl
			(struct file *filp, unsigned int cmd, unsigned long arg)

	static struct spi_driver spidev_spi_driver = {
		.driver = {
			.name =		"spidev",
			.of_match_table = of_match_ptr(spidev_dt_ids),
			.acpi_match_table = ACPI_PTR(spidev_acpi_ids),
		},
		.probe =	spidev_probe,
		.remove =	spidev_remove,
	};

 

下面的 spi-gpio.c  spi-bitbang.c 属于 protocol drivers ,是用gpio来模拟spi 的一种驱动,这种情况是当SOC的spi 控制器被占用或者不够使用时,才会用到这个驱动,需要3-4个gpio 。

如果你在设备树中添加的spi 设备的 compatible=“spi-gpio” 的话, 才会使用这个驱动,这个后续再讲解此驱动的实现方式。

drivers/spi/spi-bitbang.c  模拟 控制器驱动

drivers/spi/spi-gpio.c      protocol drivers,类似于spidev.c

比如我们有用到一个 128K 的SPI接口的FRAM,就可以自己写一个driver ,不用上面的spidev bitbang等驱动 ,记住一个 spi_device 对应 一个 spi_driver 就可以了, 为了简单使用,使用了sysfs,

fm25_bin_read(struct file *filp, struct kobject *kobj,
               struct bin_attribute *bin_attr,
               char *buf, loff_t off, size_t count)
{
        spi_read()
}

fm25_bin_write(struct file *filp, struct kobject *kobj,
               struct bin_attribute *bin_attr,
               char *buf, loff_t off, size_t count)
{
        spi_write()
}


static int fm25_probe(struct spi_device *spi)
{
        sysfs_bin_attr_init(&fm25->bin);
        fm25->bin.read = fm25_bin_read;
        fm25->bin.write = fm25_bin_write;
        sysfs_create_bin_file(&spi->dev.kobj, &fm25->bin);
}


static const struct of_device_id fm25_of_match[] = {
		{ .compatible = "cypress,fm25", },
		{ }
	};
	
MODULE_DEVICE_TABLE(of, fm25_of_match);

static struct spi_driver fm25_driver = {
		.driver = {
			.name       = "fm25",
			.of_match_table = fm25_of_match,
		},
		.probe      = fm25_probe,
		.remove     = fm25_remove,
};


   其中 spi_read  spi_write 在 spi.h 中

    驱动层读写 spi 从设备的接口,可以被 spidev 或者 自己写的其他驱动比如FRAM的驱动调用,并不会与应用层交互。
    spi_write(struct spi_device *spi, const void *buf, size_t len)
    spi_read(struct spi_device *spi, void *buf, size_t len)
    
    //spi.c
    int spi_write_then_read
            (struct spi_device *spi,
                const void *txbuf, unsigned n_tx,
                    void *rxbuf, unsigned n_rx) 
                    
                    
    其实这三个接口,都是通过下面的接口实现的
        spi_message_init(&m);
        spi_message_add_tail(&t, &m);
        spidev_sync(spidev, &m);

 

2、spi 框架

下面是使用SOC spi 控制器驱动框架

下面是 用gpio模拟spi ,bit-bang 框架

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值