【问题标题】:How to use a GPIO driver to control pins from a different device's driver?如何使用 GPIO 驱动程序控制来自不同设备驱动程序的引脚?
【发布时间】:2020-08-12 13:52:22
【问题描述】:

我正在尝试使用 linux 设备驱动程序。我正在尝试为我的笔记本电脑 Lenovo Miix 510 构建 OV2680 驱动程序。在该平台上,传感器位于 INT3472 PMIC 后面,访问驱动程序需要控制 INT3472 的 GPIO 引脚。 INT3472 有a driver 和相应的MFD Driver,它不能开箱即用,但我已经改变它可以工作(我的笔记本电脑的 ACPI 表没有为 INT3472 定义 I2cSerialBus2,所以我只需要添加一个ic2_device_id 表并使用echo INT3472 0x48 | sudo tee /sys/bus/i2c/devices/i2c-7/new_device 创建一个i2c 设备——这将创建一个gpiochip1 并在GPIO 驱动程序中定义了10 个GPIO 通道,因此它似乎可以工作。

我可以使用 libgpiod 提供的工具在终端中设置和获取这些引脚的值。例如sudo gpioset gpiochip1 1 1 设置车道 1 高。

我的问题是; 我的相机驱动程序中控制 INT3472 提供的 10 个 GPIO 引脚的正确方法是什么?例如,我需要能够将引脚拉低/拉高以触发相机的软件待机。我想显而易见的答案是“使用 libgpiod”,但如果是这种情况,我如何识别 /dev 中正确的“gpiochipN”文件以打开,因为我的笔记本电脑中有两个 INT3470 和主 gpiochip0。

【问题讨论】:

  • 这个问题被误导了。你搞砸了 providerconsumer 的东西。第一部分关于 PMIC 是 消费者,而您问题的第二部分是讨论如何访问它 提供的 PMIC GPIO。它们是完全不同的 GPIO 芯片!
  • @0andriy 抱歉;我很困惑。我认为我在第一个 sn-p 中连接的 PMIC 与将由您链接的驱动程序驱动的 TPS68470 相同,并且您建议我应该使用该芯片的驱动程序提供的 API 而不是哈克方法。我有没有得到错误的印象?
  • 您将gpiod_get_index() 放入elixir.bootlin.com/linux/latest/source/drivers/mfd/… tps68470_probe()。这就是如何做到这一点。在某些(罕见或损坏的)情况下,当前的方法可能是合理的。
  • @0andriy 感谢您的耐心等待,非常感谢;阅读往往只能让我到目前为止!所以再试一次;鉴于 DSDT 中定义的 GPIO 实际上是由该设备消耗的,我通过打开这些实际上所做的是打开 tps68470 本身,而不是 ov2680?这确实很有意义,因为当我这样做时出现的另一个 i2c 设备位于 0x48,这是 tps68470 的第一个可能地址。所以我需要更改tps68470_probe() 函数来获取这些GPIO,并在调用函数时(即我认为在启动时)打开它们
  • 这听起来不错,但我不熟悉该设备。如果您能获得类似的原理图以了解此相机 PMIC 是如何连接到 SoC 的,那就太好了。 PMIC 的数据表也可能有很大帮助。

标签: linux linux-kernel linux-device-driver gpio


【解决方案1】:

我想我遇到了正确的方法here。简而言之,您可以在相机驱动程序中将 GPIO 引脚映射到设备(作为.probe 函数的一部分):

    static struct gpiod_lookup_table ov2680_gpios = {
        .dev_id = "i2c-OVTI2680:00",
        .table = {
            GPIO_LOOKUP_IDX("tps68470-gpio", 7, "s_enable", 0, GPIO_ACTIVE_HIGH),
            GPIO_LOOKUP_IDX("tps68470-gpio", 8, "s_idle", 0, GPIO_ACTIVE_HIGH),
            GPIO_LOOKUP_IDX("tps68470-gpio", 9, "s_resetn", 0, GPIO_ACTIVE_HIGH),
            { },
        },
    };

    gpiod_add_lookup_table(&ov2680_gpios);

.dev_id 成员与设备名称匹配。 GPIO_LOOKUP_IDX 是一个宏,它获取 GPIO 芯片的标签(tps68470-gpio)、芯片中引脚的索引(由 PMIC 的 GPIO 驱动程序here 给出,加上函数名称、函数中的索引和一些标志。一旦建立查找表,它就可以注册到gpiod_add_lookup_table()。完成后,您可以使用gpiod_get... 获取引脚:

/* ov2680 is a struct ov2680_device containing, amongst other things... */
struct ov2680_device {
    gpio_desc            *s_enable;
    struct i2c_device    *client;
}; 

ov2680->s_idle = gpiod_get_index(&ov2680->client->dev, "s_idle", 0, GPIOD_OUT_HIGH);

认为这是对的;但我会暂时搁置这个问题,以防有更好的答案出现。

【讨论】:

  • 是的,这是创建 board 文件 来提升 ACPI 表的劣势的一种方法。我不能说这是理想的,但我也不能说这是丑陋的。
  • @0andriy 谢谢,它似乎正在工作。我还修改了 MFD 驱动程序的.probe() 以按照您的建议打开它消耗的引脚,并且在将 I2CSerialBusV2 条目修补到 PMIC 的 DSDT 条目后,它现在可以在启动时自动探测,这很好。非常感谢您的帮助;在你回答的后面,我还设法让 PMIC 的调节器和时钟驱动程序也能正常工作,这样相机驱动程序就可以消耗这些资源,这感觉是一个很大的进步。
猜你喜欢
  • 2019-03-17
  • 1970-01-01
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多