gpio-keys 不能与 I/O 扩展器驱动程序 gpio-pca953x (TCA6416A) 结合使用

问题描述

我想借助 DT 覆盖在我的 RaspBerry Pi3 B+ Linux 中集成/加载 gpio-pca953x 驱动程序。该驱动程序是适用于各种芯片(即 TCA6416)的通用 I²C 控制 I/O 扩展器 gpio 驱动程序。我设法创建了一个启用驱动程序的 dts 覆盖。

/dts-v1/;
/plugin/;
/ {
        compatible = "brcm,bcm2835","brcm,bcm2708",bcm2709";

        fragment@0 {
                target = <&i2c1>;
                __overlay__ {
                        status = "okay";
                };
        };

        fragment@1 {
                target = <&i2c1>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        tca6416: tca6416@20 {
                                compatible = "ti,tca6416";
                                reg = <0x20>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-parent = <&gpio>;
                                interrupts = <18 0x02>; //IRQ_TYPE_EDGE_FALLING
                        };
                };
        };
};

一个新的 gpiochip /sys/class/gpio/gpiochip488 并且中断似乎也有效。

我认为下一个简单的步骤是在 gpio-keys 模块的帮助下创建一个虚拟输入设备。但似乎我错了。

我创建了另一个这样的 DT 覆盖:

    fragment@1 {
            target-path = "/soc";
            __overlay__ {
                    gpio: gpio-button {
                            compatible = "gpio-keys";
                            autorepeat;
                            button@14 {
                                    label = "TestKey";
                                    linux,code = <14>;
                                    gpios = <&tca6416 0 1>;
                            };
                    };
            };
    };

但是这次这个叠加层永远无法加载。我得到的错误始终是在实时设备树符号表中找不到符号 tca6416。我在这里做错了什么?是否有任何工作示例?我还尝试将上面 gpios 中的 tca6416 替换为 gpio488 或任何其他可能的名称。两个都不行。

解决方法

问题似乎出在某种意义上的 DTS 覆盖机制本身。 tca6416 永远不会导出为实时树中的符号。我的解决方案是使用叠加层,而是在主要 DTS 文件之一(如 bcm2710-rpi-3-b-plus.dts)中包含一个 DTS 文件。

这个包含文件包含:

&i2c1 {
      tca6416_20: tca6416@20 {
              compatible = "ti,tca6416";
              #gpio-cells = <2>;
              reg = <0x20>;
              gpio-controller;
              interrupt-parent = <&gpio>;
              interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
              reset-gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
      };
};

这按预期工作,gpio-keys 也是如此。