linux-device-driver – max732x.c I2C IO扩展器具有Linux设备树的GPIO密钥无法正常工作

前端之家收集整理的这篇文章主要介绍了linux-device-driver – max732x.c I2C IO扩展器具有Linux设备树的GPIO密钥无法正常工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用飞思卡尔MX6和3.10.31飞思卡尔修改过的内核.我有一个Maxim MAX7325用作IO扩展器,它有一个连接到P0-P2的按钮.来自7325的中断线连接到GPIO_3焊盘(我相信是GPIO1_3 ……)

我在设备树中设置了7325和gpio-keys,如下所示:

max7325_reset: max7325-reset {
  compatible = "gpio-reset";
  reset-gpios = <&gpio5 16 GPIO_ACTIVE_LOW>;
  reset-delay-us = <1>;
  #reset-cells = <0>;
};


gpio-keys {
  compatible = "gpio-keys";

  sw2 {
     gpios = <&max7325 2 GPIO_ACTIVE_LOW>;
     linux,code = <30>;    //a
     gpio-key,wakeup;
  };
};

&i2c1 {
   clock-frequency = <100000>;
   pinctrl-names = "default";
   pinctrl-0 = <&pinctrl_i2c1_2>;
   status = "okay";

   max7325: gpio@68 {
      compatible = "maxim,max7325";
      reg = <0x68>;
      gpio-controller;
      #gpio-cells = <2>;
      resets = <&max7325_reset>;

      gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
      interrupt-parent = <&gpio1>;
      interrupts = <3 2>;
   };
};

似乎发生的情况是调用MAX7325驱动程序的探针时,client-> dev.platform_data为NULL.因此,当稍后调用max732x_irq_setup时,它不会设置chip-> gpio_chip.to_irq指针指向max732x_gpio_to_irq函数(可能是因为它没有正确的信息可以使其工作.)后来,当gpio_keys
尝试配置第一个输入,它在尝试设置中断时失败,并且没有设置其他任何键.

gpio-keys gpio-keys.20: Unable to get irq number for GPIO 242,error -6

我确实使用P0映射到GPIO 240的/ sys接口,所以是的,GPIO 242是我试图设置的sw2 GPIO-KEY.

我想知道,这个驱动程序不适用于设备树吗?我没有看到它试图获得任何设备树属性,但我看到的其他IO扩展器驱动程序也没有,所以我想也许I2C内核正在读取设备树并且应该以某种方式从那里填充platform_data它调用驱动程序的探测函数(?)

我对此很新,所以任何帮助都会受到赞赏. =)我确实在线阅读了一些设备树文档,但我认为这是一个相当具体的东西,我做得不正确,他们没有覆盖……(?)

我在内核中配置了CONFIG_GPIO_MAX732X_IRQ ……我曾经尝试为max7325 I2c1节点设置中断控制器属性,但我不确定是否需要(?)

解决方法

MAX732x器件树支持

您正在使用的驱动程序将无法使用设备树中的数据.我已经为此驱动程序添加了设备树支持并将其发送到内核邮件列表以供审阅,但它们尚未合并.见this thread(共4个补丁):

您可以将这些补丁应用到您的分支或等待它们进入上游内核,然后从那里挑选它们(进入您的分支).

Bindings文档(参见上面的补丁)显示了如何为MAX732x创建设备树声明.在您的情况下,它可能看起来像这样:

&i2c1 {
    expander: max7325@68 {
        compatible = "maxim,max7325";
        reg = <0x68>;
        gpio-controller;
        #gpio-cells = <2>;
        interrupt-controller;
        #interrupt-cells = <2>;
        interrupt-parent = <&gpio1>;
        interrupts = <3 2>;
    };
};

另一种使用此驱动程序的方法(上面没有补丁)是为您的电路板指定电路板文件中的平台数据.我相信它应该是下一个文件之一:

> arch / arm / mach-imx / mach-imx6q.c
> arch / arm / mach-imx / mach-imx6sl.c
> arch / arm / mach-imx / mach-imx6sx.c

您可以在此处找到如何执行此操作的示例:arch / arm / mach-pxa / littleton.c,第394行.

但它可能不是可靠的方式:我试图这样做并且在i2c总线数量方面存在一些问题(虽然这样看起来并不太多).在board文件和dts文件之间分散设备的定义也很糟糕.所以我强烈建议你使用上面的补丁.

问题的答案

What appears to happen is when probe for the MAX7325 driver is called,client->dev.platform_data is NULL.

之所以发生这种情况,是因为驱动程序与来自设备树文件的设备声明绑定,而不是来自板文在这种情况下,驱动程序应使用client-> dev.of_node而不是client-> dev.platform_data.看看我在上面的补丁中是如何完成的.

您可以在此处阅读有关内核文档中绑定/匹配/实例化的更多信息:

> Documentation / i2c / instantiating-devices
> Documentation / devicetree / usage-model.txt

I thought maybe the I2C core is reading the device tree and supposed to fill in the platform_data from there somehow before it calls the driver’s probe function (?)

不会.当绑定发生时,client-> irq会自动填充在I2C内核中(在调用驱动程序的探测功能之前).像gpio_base和irq_base这样的属性 – 如果数据来自设备树,则不需要它们.

I did at one point try setting the interrupt-controller property for the max7325 I2c1 node,but I wasn’t sure that was needed (?)

当MAX7325检测到输入线路发生变化时(更具体地说,配置为输入的漏极开路I / O端口),它会向SoC发出中断.
因此,如果您希望驱动程序为每个输入I / O线生成单独的中断(以便其他驱动程序可以使用它们),则应指定“interrupt-controller”和“#interrupt-cells”属性.但为此你需要应用上面提到的所有补丁.

补丁状态

现在所有提到的补丁都合并到了上游内核(v4.0及更高版本):

> gpio: max732x: Add device tree support
> gpio: max732x: Rewrite IRQ code to use irq_domain API
> gpio: max732x: Fix possible deadlock
> gpio: max732x: Add DT binding documentation

另请注意,在我的补丁之上有一些新补丁.你可以看他们here.

猜你在找的Linux相关文章