frank529 发表于 2012-03-28 10:24

请教linux的SPI驱动问题

内核版本2.6.30。编进内核的SPI驱动,通过看代码我明白了,大致过程是这样:
1、先创建一个spi_board_info结构描述spi设备信息,调用spi_register_board_info将这个结构添加到board_list中。
2、然后调用spi_register_master注册SPI控制器驱动,此时会调用scan_boardinfo扫描board_list,根据spi_board_info调用spi_new_device生成spi_device结构,用spi_add_device添加设备。
3、调用spi_register_driver注册spi_driver,通过与device匹配驱动设备。

下面是问题:
1、上述做法需要在注册spi控制器驱动即spi master前,先要定义好spi_board_info结构并注册。但是如果我要编写一个驱动模块,我应该怎样注册spi_device?
2、spi控制器是通过片选信号来区分多个spi设备的,这个片选信号是像I2C地址一样由设备定义好的吗?如何知道某个设备该用怎样的片选信号?

meijianjun 发表于 2012-03-28 11:11

1、上述做法需要在注册spi控制器驱动即spi master前,先要定义好spi_board_info结构并注册。但是如果我要编写一个驱动模块,我应该怎样注册spi_device?
>象 spi_master 一样注册你的设备.
2、spi控制器是通过片选信号来区分多个spi设备的,这个片选信号是像I2C地址一样由设备定义好的吗?如何知道某个设备该用怎样的片选信号?
>和i2c 不同,i2c 是通过地址选择从设备。 spi 的cs 是对被选设备而言。 一般是 H /L 表示enable/disable 从设备 。

linuxfellow 发表于 2012-03-28 11:34

回复 1# frank529
急用先学,最近刚好看了这一部分:
1、上述做法需要在注册spi控制器驱动即spi master前,先要定义好spi_board_info结构并注册。但是如果我要编写一个驱动模块,我应该怎样注册spi_device?
spi_device就是就是通过    spi_register_board_info 来注册的。
通过spi_board_info结构,给定设备的下面信息:
设备名
波特率
设备挂在哪个spi总线上,如powerpc 5000有SPI A, B, C ,D
片选信号

#define SPI_AK4104      \
659{                     \
660      .modalias       = "ak4104-codec",       \设备名
661      .max_speed_hz   = 10000,                \波特率
662      .bus_num      = 0,                  \SPI A, B, C ,D
663      .chip_select    = 0,                  \片选(0~7)
664      .controller_data = (void *) GPIO_SPDIF_CS,\平台数据
665}
#define SPI_DAC7512   \
679{       \
680      .modalias       = "dac7512",            \设备名
681      .max_speed_hz   = 1000000,            \波特率
682      .bus_num      = 0,         \ SPI A, B, C ,D
683      .chip_select    = 2,            \片选(0~7)
684      .controller_data = (void *) GPIO_MCLK_DAC_CS,   \
685}

static struct spi_board_info connector_spi_devices[] __initdata = {
         SPI_AK4104,
         SPI_DAC7512,
};
调用下面函数,就把上面两个设备登记到/sys/bus/spi下了

    spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));
2、spi控制器是通过片选信号来区分多个spi设备的,这个片选信号是像I2C地址一样由设备定义好的吗?如何知道某个设备该用怎样的片选信号?
硬件连线决定的。
上面的例子,spi bus A上挂了上面两个设备:AK4104/DAC7512
SPI接口有下列信号线:
SCK_A: 时钟,同两个设备的时钟信号接在一起
SIN_A:data in;同两个设备的data out信号接在一起
SOUT_A data out; 同两个设备的data in信号接在一起
PCS0_A:bus A chip select 0, 接AK4104的片选
PCS2_A::bus A chip select 2,接DAC7512的片选

如果先选中chip select 0, 下面的操作就会作用于设备AK4104
如果先选中chip select 2, 下面的操作就会作用于设备DAC7512




   

frank529 发表于 2012-03-28 13:22

本帖最后由 frank529 于 2012-03-28 13:25 编辑

linuxfellow 发表于 2012-03-28 11:34 static/image/common/back.gif
回复 1# frank529
急用先学,最近刚好看了这一部分:
1、上述做法需要在注册spi控制器驱动即spi master前 ...

谢谢楼上两位的回复。

用spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));注册SPI设备,只是将spi_board_info 结构挂在board_list上,真正创建spi device结构的是scan_boardinfo函数。而scan_boardinfo只在spi_register_master函数中调用。如果要在模块中注册spi_device,此时master已经注册过了,scan_boardinfo函数不会被调用,那spi_device结构从哪里来呢?

片选的话,如果我CPU上只有NCS0、NCS1、NCS2和NCS3四根线,那是不是只能挂4个SPI设备?

asuka2001 发表于 2012-03-28 13:42

回复 4# frank529

scan_boardinfo函数还不是依靠spi_new_device(), spi_alloc_device(), spi_add_device()来向设备字系统注册,你直接依靠这些函数自己注册个spi_device不就得了。。。

片选如果你想挂超过4个SPI设备,那自己做译码片选就是。。。外面加2个3-8译码器解决问题。。。

   

frank529 发表于 2012-03-28 14:06

本帖最后由 frank529 于 2012-03-28 14:10 编辑

asuka2001 发表于 2012-03-28 13:42 static/image/common/back.gif
回复 4# frank529

scan_boardinfo函数还不是依靠spi_new_device(), spi_alloc_device(), spi_add_devic ...

spi_alloc_device的参数是master,之前不知道怎么在模块中获取master,现在知道了,用spi_busnum_to_master

asuka2001 发表于 2012-03-28 14:11

回复 6# frank529

spi_busnum_to_master()

g__gle 发表于 2012-03-28 20:14

我记得某个版本里是不能单独添加SPI device的,当时总结SPI与I2C子系统不同时还提出过,注册适配器时要把适配器上存在的设备都带起来,SPI实例化设备时只有这一个时机,I2C却可以在任何时候注册。

我以前做这个的时候还像把某部分代码改了才能在其它时候添加SPI设备。那是半年前的事了,可能当时没发现有其它方法。

frank529 发表于 2012-03-30 14:09

擦,搞了半天,只有添加spi设备的函数,没有删除spi设备的函数,看来spi子系统设计时就没有考虑模块加载的情况,得自己写个函数了。

bjq1016 发表于 2014-11-17 20:28

回复 6# frank529


    spi_alloc_device的参数是master,之前不知道怎么在模块中获取master,现在知道了,用spi_busnum_to_master

spi_busnum_to_master是啥作用?我还是不明白
页: [1]
查看完整版本: 请教linux的SPI驱动问题