Uboot驱动模型之spi-driver(3/3)

概述

本章主要是翻译《spi-howto.txt》,文档路径u-boot/doc/driver-model/spi-howto.txt。

主要是介绍如何porting spi driver到driver model中。

这篇文章以exynos spi driver移植到driver model(DM)为例子一步步介绍如何将一个spi驱动移植到驱动模型中,文章比较长,因为涉及实际的代码例子,例子代码基于U-Boot v2014.10-rc2(commit be9f643)。

在DM之前,SPI驱动将struct spi_slave放到它们自己的私有数据结构中。在DM中,struct spi_slave仍然存在,但是它是以spi bus的per-child data存在。每个child就是spi bus的一个spi slave。意味着可以将struct spi_slave从驱动指定的slave结构中移植到spi bus的私有数据中。

例如如下的struct tegra_spi_slave结构,slave应该是per-child data,而ctrl可以作为SPI的总线私有数据。

struct tegra_spi_slave {
     struct spi_slave slave;
     struct tegra_spi_ctrl *ctrl;
};

0. 需要花多长时间?

您应该能够在2小时内完成此操作,包括测试,但不包括准备补丁。API与以前基本相同,只有细微的变化:

  • 设置速度和模式的方法是分开的
  • cs_info用于获取芯片选择信息

1. 打开驱动模型以及spi flash

在板子配置文件中添加这些宏:

CONFIG_DM_SPI

CONFIG_DM_SPI_FLASH

2. 添加框架

将此代码放在现有驱动程序文件的底部:

struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
            unsigned int max_hz, unsigned int mode)
{
    return NULL;
}

struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
                      int spi_node)
{
    return NULL;
}

static int exynos_spi_ofdata_to_platdata(struct udevice *dev)
{
    return -ENODEV;
}

static int exynos_spi_probe(struct udevice *dev)
{
    return -ENODEV;
}

static int exynos_spi_remove(struct udevice *dev)
{
    return -ENODEV;
}

static int exynos_spi_claim_bus(struct udevice *dev)
{

    return -ENODEV;
}

static int exynos_spi_release_bus(struct udevice *dev)
{

    return -ENODEV;
}

static int exynos_spi_xfer(struct udevice *dev, unsigned int bitlen,
                const void *dout, void *din, unsigned long flags)
{

    return -ENODEV;
}

static int exynos_spi_set_speed(struct udevice *dev, uint speed)
{
    return -ENODEV;
}

static int exynos_spi_set_mode(struct udevice *dev, uint mode)
{
    return -ENODEV;
}

static int exynos_cs_info(struct udevice *bus, uint cs,
              struct spi_cs_info *info)
{
    return -ENODEV;
}

static const struct dm_spi_ops exynos_spi_ops = {
    .claim_bus  = exynos_spi_claim_bus,
    .release_bus    = exynos_spi_release_bus,
    .xfer       = exynos_spi_xfer,
    .set_speed  = exynos_spi_set_speed,
    .set_mode   = exynos_spi_set_mode,
    .cs_info    = exynos_cs_info,
};

static const struct udevice_id exynos_spi_ids[] = {
    { .compatible = "samsung,exynos-spi" },
    { }
};

U_BOOT_DRIVER(exynos_spi) = {
    .name   = "exynos_spi",
    .id = UCLASS_SPI,
    .of_match = exynos_spi_ids,
    .ops    = &exynos_spi_ops,
    .ofdata_to_platdata = exynos_spi_ofdata_to_platdata,
    .probe  = exynos_spi_probe,
    .remove = exynos_spi_remove,
};

3. 修改框架名称

把上面代码中的exynos替换为你的驱动名字

4. 隔开旧代码

用#ifdef把驱动文件中非上述的代码隔开,这就允许编译它,这意味着您可以逐步工作。由于所有方法最初都会返回错误,你不小心把东西留在里面的可能性较小。

此外,尽管基本上对你来说是在重写,但是保留之前的函数在文件相同的地方对review的人来说是由帮助的,特别是对于大型的驱动来说。

5. 添加一些头文件

在你的驱动中添加这些头文件:

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值