SPI总线驱动、设备驱动

zynq SPI控制器理解记录

如下:spi一般都由一下两个不通的模式组合成四个模式:
自动/手到发送数据:
自动:当TxFIFO有数据就进行发送;无数据则停止发送。
手动:通过使能发送位进行数据的发送。
自动/手动控制CS使能信号:
自动:当TXFIFO有数据的时候就自动使能,Txfifo数据传输完成之后就不使能
手动:通过使能位来软件控制片选信号的使能

在这里插入图片描述

在这里插入图片描述

SPI总线

在这里插入图片描述

一个SOC有多个spi控制器,这些控制器都是连接在SPI总线上,linux采用SPI总线来管理这些设备。

其中driver/spi/spi.c中实现了对spi总线的注册,同时为上层设备提供了统一的接口,以下是spi.c中初始化代码

static int __init spi_init(void)
{
	int	status;

	buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
	if (!buf) {
		status = -ENOMEM;
		goto err0;
	}

	status = bus_register(&spi_bus_type);
	if (status < 0)
		goto err1;

	status = class_register(&spi_master_class);
	if (status < 0)
		goto err2;
	return 0;

err2:
	bus_unregister(&spi_bus_type);
err1:
	kfree(buf);
	buf = NULL;
err0:
	return status;
}

/* board_info is normally registered in arch_initcall(),
 * but even essential drivers wait till later
 *
 * REVISIT only boardinfo really needs static linking. the rest (device and
 * driver registration) _could_ be dynamically linked (modular) ... costs
 * include needing to have boardinfo data structures be much more public.
 */
postcore_initcall(spi_init);

其中postcore_initcall(*)是一个宏,内核起来的时候会执行宏里面定义的函数。
status = bus_register(&spi_bus_type);实现对SPI总线的注册

SPI Master控制器驱动

SPI Master控制器是SOC内部的控制器,一般一个SOC有多个控制器,使用同一个控制器驱动,对应的代码在drivers/spi/spi-xxx.c。每一个文件对应着不通的spi控制器驱动,本文以spi-candance.c为例

/**
 * cdns_spi_probe - Probe method for the SPI driver
 * @pdev:	Pointer to the platform_device structure
 *
 * This function initializes the driver data structures and the hardware.
 *
 * Return:	0 on success and error value on error
 */
static int cdns_spi_probe(struct platform_device *pdev)
{
	int ret = 0, irq;
	struct spi_master *master;
	struct cdns_spi *xspi;
	struct resource *res;
	u32 num_cs;

	//pr_info("cdns_spi_probe....\r\n");
	//pr_info("sizeof(*xspi)=%d\n", sizeof(*xspi));

	master = spi_alloc_master(&pdev->dev, sizeof(*xspi));
	if (master == NULL)
		return -ENOMEM;

	xspi = spi_master_get_devdata(master);
	master->dev.of_node = pdev->dev.of_node;
	platform_set_drvdata(pdev, master);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	//pr_info("addr:0x%x\n", res->start);
	xspi->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(xspi->regs)) {
		ret = PTR_ERR(xspi->reg
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值