max732x.c I2C IO Expander + ключи GPIO с деревом устройств Linux не работают

Я работаю с Freescale MX6 и модифицированным ядром Freescale 3.10.31. У меня есть Maxim MAX7325, используемый в качестве расширителя ввода-вывода, кнопки которого подключены к P0-P2. Линия прерывания от 7325 подключена к контактной площадке GPIO_3 (я считаю, что это GPIO1_3 ...)

Я настроил ключи 7325 и gpio в дереве устройств следующим образом:

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

С помощью интерфейса / sys я определил, что P0 сопоставляется с GPIO 240, так что да, GPIO 242 - это ключ GPIO sw2, который я пытался настроить.

Мне интересно, а этот драйвер не работает с деревом устройств? Я не вижу, чтобы он пытался получить какие-либо свойства дерева устройств, но другие драйверы расширителей ввода-вывода, на которые я смотрел, тоже не смотрели, поэтому я подумал, что, возможно, ядро ​​I2C читает дерево устройств и должно как-то раньше заполнять оттуда platform_data он вызывает функцию зонда драйвера (?)

Я новичок в этом, поэтому любая помощь будет принята с благодарностью. =) Я прочитал несколько онлайн-документов по дереву устройств, но я думаю, что это что-то довольно конкретное, что я делаю неправильно, и они не охватывают ... (?)

У меня есть CONFIG_GPIO_MAX732X_IRQ, настроенный в ядре ... и я однажды попытался установить свойство контроллера прерывания для узла max7325 I2c1, но я не был уверен, что это было необходимо (?)


person gulchrider    schedule 31.10.2014    source источник


Ответы (1)


Поддержка дерева устройств MAX732x

Используемый вами драйвер не будет работать с данными из дерева устройств. Я добавил в этот драйвер поддержку дерева устройств и отправил его в списки рассылки ядра для проверки, но они еще не объединены. См. эту ветку (всего 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>;
    };
};

Другой способ использовать этот драйвер (без вышеуказанных патчей) - указать данные платформы в файле платы для вашей платы. Я считаю, что это должен быть один из следующих файлов:

  • арка / рука / mach-imx / mach-imx6q.c
  • арка / рука / mach-imx / mach-imx6sl.c
  • арка / рука / mach-imx / mach-imx6sx.c

Вы можете найти пример, как это сделать, здесь: arch / arm / mach-pxa / littleton.c, строка 394.

Но это может быть ненадежный способ: я пытался это сделать, и у меня возникли проблемы с номерами шин i2c (хотя в этом смысле не выглядело слишком много). Также неплохо выглядит разбросать определения устройств между файлом платы и файлом dts. Поэтому я настоятельно рекомендую вам использовать патчи, указанные выше.

Ответы на вопросы

Похоже, что когда вызывается зонд для драйвера MAX7325, client-> dev.platform_data имеет значение NULL.

Это происходит потому, что драйвер был привязан к объявлению устройства из файла дерева устройств, а не из файла платы. В этом случае драйвер должен использовать client-> dev.of_node вместо client-> dev.platform_data. Посмотрите, как это сделано в моем патче выше.

Вы можете прочитать больше о том, как происходит привязка / сопоставление / создание экземпляра, в документации ядра здесь:

  • Документация / i2c / создание экземпляров устройств
  • Документация / devicetree / usage-model.txt

Я подумал, что, возможно, ядро ​​I2C читает дерево устройств и должно каким-то образом заполнить оттуда platform_data до того, как вызовет функцию проверки драйвера (?)

Нет. Когда происходит привязка, client-> irq автоматически заполняется в ядре I2C (до вызова функции проверки драйвера). Такие свойства, как gpio_base и irq_base - они вам не нужны, если данные пришли из дерева устройств.

Однажды я попытался установить свойство контроллера прерывания для узла max7325 I2c1, но я не был уверен, что это необходимо (?)

MAX7325 выдает прерывание для вашей SoC, когда он обнаруживает изменения на входных линиях (точнее, на портах ввода-вывода с открытым стоком, настроенных как входы). Поэтому, если вы хотите, чтобы ваш драйвер генерировал отдельные прерывания для каждой строки ввода / вывода (чтобы другие драйверы могли их использовать), вы должны указать свойства «interrupt-controller» и «# interrupt-cells». Но для этого нужно применить все патчи, упомянутые выше.

Статус патчей

Теперь все упомянутые патчи были объединены в исходное ядро ​​(v4.0 и новее):

  1. gpio: max732x: добавление поддержки дерева устройств
  2. gpio: max732x: переписать код IRQ, чтобы использовать irq_domain API
  3. gpio: max732x: / а>
  4. gpio: max732x: Добавить привязку D для gpio: max732x

Также обратите внимание, что поверх моих исправлений было сделано несколько новых исправлений. Вы можете посмотреть их здесь < / а>.

person Sam Protsenko    schedule 14.01.2015
comment
@chrisdew Я добавил раздел статуса патчей в конце своего ответа, отвечая на ваши вопросы. - person Sam Protsenko; 26.10.2016