gul*_*der 2 linux-device-driver gpio device-tree max732x.c
我正在使用飞思卡尔 MX6 和飞思卡尔 3.10.31 修改内核。我有一个用作 IO 扩展器的 Maxim MAX7325,它的按钮连接到 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;
  };
};
Run Code Online (Sandbox Code Playgroud)
和
&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>;
   };
};
Run Code Online (Sandbox Code Playgroud)
出现的情况是当调用 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
Run Code Online (Sandbox Code Playgroud)
我确实确定使用 P0 映射到 GPIO 240 的 /sys 接口,所以是的,GPIO 242 是我试图设置的 sw2 GPIO-KEY。
我想知道,这个驱动程序不能与设备树一起使用吗?我没有看到它试图获取任何设备树属性,但我查看的其他 IO 扩展器驱动程序也没有,所以我想也许 I2C 核心正在读取设备树并应该以某种方式从那里填充 platform_data 之前它调用驱动程序的探测函数(?)
我在这方面相当新,所以任何帮助将不胜感激。=) 我确实在网上阅读了一些设备树文档,但我认为这是我没有正确做的相当具体的事情,他们没有涵盖......(?)
我确实在内核中配置了 CONFIG_GPIO_MAX732X_IRQ ......我曾经尝试为 max7325 I2c1 节点设置中断控制器属性,但我不确定是否需要(?)
您正在使用的驱动程序无法处理设备树中的数据。我已向该驱动程序添加了设备树支持并将其发送到内核邮件列表以供审核,但它们尚未合并。请参阅此线程(共 4 个补丁):
您可以将这些补丁应用到您的分支,或者等待它们进入上游内核,然后从那里挑选它们(进入您的分支)。
绑定文档(见上面的补丁)展示了如何为 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>;
    };
};
Run Code Online (Sandbox Code Playgroud)
您使用此驱动程序的另一种方法(没有上面的补丁)是在板文件中为您的板指定平台数据。我相信它应该是下一个文件之一:
您可以在此处找到如何操作的示例:arch/arm/mach-pxa/littleton.c,第 394 行。
但这可能不是可靠的方式:我尝试这样做并且在 i2c 总线编号方面遇到了一些问题(尽管那样看起来并不多)。在板文件和 dts 文件之间分散设备的定义看起来也很糟糕。所以我强烈建议你使用上面的补丁。
出现的情况是当调用 MAX7325 驱动程序的探针时,client->dev.platform_data 为 NULL。
发生这种情况是因为驱动程序与设备树文件而非板文件中的设备声明绑定在一起。在这种情况下,驱动程序应该使用client->dev.of_node而不是client->dev.platform_data。看看它是如何在我上面的补丁中完成的。
您可以在此处的内核文档中阅读有关绑定/匹配/实例化如何发生的更多信息:
我想也许 I2C 核心正在读取设备树并应该在调用驱动程序的探测函数之前以某种方式从那里填充 platform_data (?)
不。当绑定发生时,client->irq会自动填充到 I2C 内核中(在调用驱动程序的探测函数之前)。gpio_base和irq_base 之类的属性——如果数据来自设备树,则不需要它们。
我曾尝试为 max7325 I2c1 节点设置中断控制器属性,但我不确定是否需要(?)
当 MAX7325 检测到输入线路(更具体地说,配置为输入的开漏 I/O 端口)发生变化时,它会向您的 SoC 发出中断。因此,如果您希望驱动程序为每个输入 I/O 线生成单独的中断(以便其他驱动程序可以使用它们),您应该指定“interrupt-controller”和“#interrupt-cells”属性。但为此,您需要应用上述所有补丁。
现在所有提到的补丁都合并到上游内核(v4.0 及更高版本)中:
另请注意,在我的补丁之上制作了一些新补丁。你可以在这里观看它们。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           2582 次  |  
        
|   最近记录:  |