This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3352: Setting up GPIO in the device tree

Part Number: AM3352

Tool/software: Linux

I am having trouble setting up the GPIO for a custom board that is being developed. We have loosely modeled the board after the AM335x EVM, but we are not utilizing anywhere near as many peripherals. I have been attempting to make use of the GPIO by creating a new node in the dts file, but it doesn't seem to be working the way I would think it should. The GPIO doesn't get setup, and the access to the registers isn't even set up. The CM_PER registers and CM_WKUP registers that correlate to the GPIO seem to go from the correct settings in Uboot to the incorrect ones in Linux.

In the .dts file, which includes the am33xx.dtsi file, an example of the node that I am trying to add includes in the &am33xx_pinmux section:

gpio0_pins: gpio0_pins {
pinctrl-single,pins = <
0x164 ( PIN_INPUT | MUX_MODE7 ) /* (C18) eCAP0_in_PWM0_out.gpio0[7] */
0xd0 ( PIN_INPUT | MUX_MODE7 ) /* (V2) lcd_data12.gpio0[8] */
0xd4 ( PIN_INPUT | MUX_MODE7 ) /* (V3) lcd_data13.gpio0[9] */
0xd8 ( PIN_OUTPUT_PULLUP | MUX_MODE7 ) /* (V4) lcd_data14.gpio0[10] */
0xdc ( PIN_OUTPUT_PULLUP | MUX_MODE7 ) /* (T5) lcd_data15.gpio0[11] */
0x1b0 ( PIN_INPUT | MUX_MODE7 ) /* (A15) xdma_event_intr0.gpio0[19] */
0x1b4 ( PIN_INPUT | MUX_MODE7 ) /* (D14) xdma_event_intr1.gpio0[20] */
0x20 ( PIN_INPUT | MUX_MODE7 ) /* (U10) gpmc_ad8.gpio0[22] */
0x24 ( PIN_INPUT | MUX_MODE7 ) /* (T10) gpmc_ad9.gpio0[23] */
0x28 ( PIN_INPUT | MUX_MODE7 ) /* (T11) gpmc_ad10.gpio0[26] */
0x2c ( PIN_INPUT | MUX_MODE7 ) /* (U12) gpmc_ad11.gpio0[27] */
0x144 ( PIN_INPUT | MUX_MODE7 ) /* (H18) rmii1_refclk.gpio0[29] */
>;
};

and in the section below that:

&gpio0 {
ti,no-reset-on-init;
};

I am really not familiar with the Device Tree Structure, so any help would be appreciated.

Thank you,

Dallas

  • Hi Dallas. If you are defining a new section, you need the 'compatible' field in order to bind it to a driver. For example, if you have a button:

    gpio_keys {

    compatible = "gpio-keys";
    #address-cells = <1>;
    #size-cells = <0>;
    autorepeat;

    key@0 {
    label = "key-up";
    linux,code = <103>;
    gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
    debounce-interval = <8>;
    gpio-key,wakeup;
    };
    }

    The line 'compatible = "gpio-keys;' is probed when the kernel boots, and it will attach those nested GPIOs. Another example would be:

    compatible = "gpio-leds";

    Which attaches the GPIOs to the Linux LED driver. What are your GPIOs intended to do? Then there is one level below, the pinmuxing. Pinmuxing (or pin control as it is called in Linux) is it own 'device'. The section labeled &am33xx_pinmux is where you have to put any pin initialization. If you look in am33xx.dtsi (in the same directory) there is a section called am33xx_pinmux ( which is actually the same section - the & means a reference too ... ) which has its own 'compatible = ...' entry. There is a whole bunch of documentation under 'Documentation/devicetree/bindings' for each type of device tree entries. Its pretty helpful. Hope that helps clears things up.
  • Chris,

    Thank you for the response. I've been out of town, or else I would have responded earlier. Your description is helpful. I actually failed to include the piece of code where I did call out the 'compatible = "gpio-keys";' line.

    I have looked through some of the bindings documentation in the section directory that you have described, but I haven't found any of the documentation to be particularly clear on certain points. For example, what do the various linux,codes mean? In your example it is <103>, but is there a relatively limitless number of code options, or is there a cap?

    A more important question that I have had trouble figuring out also ties back to your question about what the GPIOs are intended to do. The only way I have made the GPIOs work through the Device Tree is to set them as LEDs if they are outputs, or Keys if they are inputs. I haven't been able to just set them up as generic GPIOs. Most of my GPIOs aren't LEDs or Keys. They are either control signals that go to FETs to turn devices on or off, or they are input signals like a power good signal from a PMIC. 

    I have attempted using the compatible = "ti,omap4-gpio"; binding, but this call out doesn't seem to set up the PRCM correctly to allow access to GPIO registers. I can only get access to the registers if I use the other LED and Key bindings.

    Again, thank you for your help, and I look forward to if you have any other suggestions on how to proceed.

  • Hi Dallas,

    The key codes are Linux defined values for specific inputs. So if you want your custom GPIO to send an 'up arrow', then you set that key code to 103. The key codes are all in include/linux/input.h.

    As for using just raw GPIOs, you should only need to set up the pin muxing as I described before, and then your GPIO should be available in user space through sysfs (see here for more details). There always has to be some driver that your GPIO is connected to in order to make it available in user space. SysFs is a simple way to access them without needing any additional drivers. However, if you only plan on accessing the GPIO through another device driver, than you should just define that GPIO as part of that device.