10:00 ~ 12:00 编辑时间: 2012-4-21 11:52
omap2_mcspi 是以平台驱动注册的,因为他是cpu 用来初始化spi总线的
spi 总线上只能有一个主控器,例如我们要用spi1.0 发送数据,omap2_mcspi1已经实现了数据的发送,我们所做的就是怎么将数据交给omap2_mcspi1,让它发出去。 omap2_mcspi1应该叫作总线控制器驱动。这个驱动没有为用户层提供接口的。
这样我们很显然会想到,我修改一下这个驱动,给用户层写个接 口,不就可以解决了。。。
但是linux spi驱动并不是这么设计的,在drivers/spi/ 下有一个spi.c文件,实际上这个是linux的spi驱动核心,不过叫它spi总线驱动更好点,
int spi_async(struct spi_device *spi, struct spi_message *message)
{
struct spi_master *master = spi->master;
/* Half-duplex links include original MicroWire, and ones with
* only one data pin like SPI_3WIRE (switches direction) or where
* either MOSI or MISO is missing. They can also be caused by
* software limitations.
*/
if ((master->flags & SPI_MASTER_HALF_DUPLEX)
|| (spi->mode & SPI_3WIRE)) {
struct spi_transfer *xfer;
unsigned flags = master->flags;
list_for_each_entry(xfer, &message->transfers, transfer_list) {
if (xfer->rx_buf && xfer->tx_buf)
return -EINVAL;
if ((flags & SPI_MASTER_NO_TX) && xfer->tx_buf)
return -EINVAL;
if ((flags & SPI_MASTER_NO_RX) && xfer->rx_buf)
return -EINVAL;
}
}
message->spi = spi;
message->status = -EINPROGRESS;
return master->transfer(spi, message);
}
EXPORT_SYMBOL_GPL(spi_async);
这 个函数很简单,所做的就是,把 spi_device 和 message 告诉 spi_async,然后spi_async通过spi->master->transfer发送出去。
这个master就是omam2_mcspi1,这个transfer函数是TI写的,和硬件有关系了。
当然我们最关心的是 spi_device是谁?
回到前边的一个问题,”修改一下这个驱动,给用户层写个接口,不就可以解决了。。。“ 如果我们在omap2_mcspi1加上用户层接口函数,直接控制寄存器也是可以实现数据的传输的。
当然这样做很多的工作了。。。。
linux 已经把这个工作分开了,那就是 总线 驱动 设备模型,对应一下,总线——spi.c 驱动——omap2_mcspi1(/其他用户驱动) 设备---
static struct platform_device omap2_mcspi1 = {
.name = "omap2_mcspi",
.id = 1,
.num_resources = ARRAY_SIZE(omap2_mcspi1_resources),
.resource = omap2_mcspi1_resources,
.dev = {
.platform_data = &omap2_mcspi1_config,
},
};
12:00 ~ 14:00 编辑时间: 2012-4-21 13:12
有了这样的划分,驱动写起来的工作会少很 多,omap2_mcspi1 可以注册成spi_master 用来完成底层的数据收发,而我们要用这个omap_mcspi1,就需要重新在注册一个spi_device ,按照总线的思想,这个spi_device回在probe函数执行的时候关联到他的总线及spi_master。