i.MX51 Device Tree GPIO as output

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX51 Device Tree GPIO as output

Jump to solution
22,185 Views
daveebright
Contributor III

Hello,

I am looking for a device tree example to define a GPIO as an output.  The gpio output is software controlled and is not connected to a button or LED (not a gpio-keys or gpio-leds compatible).  The gpio is a power enable/switch for a peripheral to the i.MX51 (when high (1) powered on and when low (0) powered off).  Additionally is there a way during kernel init to export this gpio to sysfs as was done in pre-device tree days?

Thanks,

Dave

Labels (1)
1 Solution
7,811 Views
leoschwab
Contributor III

Here's how I'm doing it on the i.MX6 in the Dora branch.  The approach for the i.MX51 looks to be similar.

In the DTS, there's a group of pinmux entries named pinctrl_hog.  This group is not well documented, but I've been assuming these are set up unconditionally by the kernel (pins that need to be setup, but aren't managed by any particular device/driver).  Add a pinmux and pad control entry to this group along the lines of:

&iomuxc {

        pinctrl-names = "default";

        pinctrl-0 = <&pinctrl_hog>;

        hog {

                pinctrl_hog: hoggrp {

                        fsl,pins = <

                               /*  This is just an example; your own setup *will* vary.  */

                                MX51_PAD_EIM_A27__GPIO2_21   0x5

                        >;

                };

        };

};

This example sets up the mux for pin EIM_A27 as connecting to GPIO2_21.  The "argument" to the MX51_* entry is the pad control.  On the i.MX6, this value is stuffed directly into the IOMUXC_SW_PAD_CTL_* register; consult your reference manual for the proper pad control values.

However, this only sets up the mux and pad control.  It does not set up the GPIO state (input vs. output, current pin level, etc.).  For that, it looks like you have to wait for the kernel to come up.  In order to expose a GPIO to user space, you must first "export" it by writing the pin number you want exported to /sys/class/gpio/export.  This in turn creates a subdirectory named /sys/class/gpio/gpio<nn>, where <nn> is the pin number.  In there are various files that let you configure the GPIO pin the way you need it.  However, everything under /sys is owned and writable only by root, so you (probably) need to make those entries writable by non-privileged applications.

You can do this using an init script, but I've chosen to do it using udev rules, since they run fairly early, are somewhat simpler once you understand the syntax, and will work regardless of what init system you're using.  Here are the rules I created to make a GPIO entry available for applications:

ACTION=="add", SUBSYSTEM=="gpio", DEVPATH=="/devices/*/gpio/gpiochip64", ATTR{subsystem/export}="86"

ACTION=="add", SUBSYSTEM=="gpio", DEVPATH=="/devices/*/gpio/gpio86",     RUN+="/bin/chgrp -R gpio $sys$devpath", RUN+="/bin/chmod -R g+w $sys$devpath"

The first rule performs the export operation, creating the entry /sys/class/gpio/gpio86.  That, in turn, triggers the second rule, which changes the group ownership and permissions of everything under /sys/class/gpio/gpio86 to be writable by members of the group "gpio" (which you will need to create).  You then create a user who is a member of the group "gpio", run your application(s) as that user, and you should be able to dance on the GPIO pin.

Again, this is all for the 3.10.x series kernel in Dora (and probably Daisy as well).  Hope this made some sense...

View solution in original post

6 Replies
7,810 Views
kartiknatarajan
Contributor II

Hi,

     I am exactly at this situation trying to configure my mx6 gpio pins with a 3.10.17 kernel. More importantly the idea is to set direction for each gpio pin in the dts(i) files. While input gpio pins seem adequately documented, I haven't found anything with output pins. Is it true that a gpio can be configured as output only in userspace with sysfs? or there is a way of setting it in the dts file? Please confirm.

0 Kudos
7,812 Views
leoschwab
Contributor III

Here's how I'm doing it on the i.MX6 in the Dora branch.  The approach for the i.MX51 looks to be similar.

In the DTS, there's a group of pinmux entries named pinctrl_hog.  This group is not well documented, but I've been assuming these are set up unconditionally by the kernel (pins that need to be setup, but aren't managed by any particular device/driver).  Add a pinmux and pad control entry to this group along the lines of:

&iomuxc {

        pinctrl-names = "default";

        pinctrl-0 = <&pinctrl_hog>;

        hog {

                pinctrl_hog: hoggrp {

                        fsl,pins = <

                               /*  This is just an example; your own setup *will* vary.  */

                                MX51_PAD_EIM_A27__GPIO2_21   0x5

                        >;

                };

        };

};

This example sets up the mux for pin EIM_A27 as connecting to GPIO2_21.  The "argument" to the MX51_* entry is the pad control.  On the i.MX6, this value is stuffed directly into the IOMUXC_SW_PAD_CTL_* register; consult your reference manual for the proper pad control values.

However, this only sets up the mux and pad control.  It does not set up the GPIO state (input vs. output, current pin level, etc.).  For that, it looks like you have to wait for the kernel to come up.  In order to expose a GPIO to user space, you must first "export" it by writing the pin number you want exported to /sys/class/gpio/export.  This in turn creates a subdirectory named /sys/class/gpio/gpio<nn>, where <nn> is the pin number.  In there are various files that let you configure the GPIO pin the way you need it.  However, everything under /sys is owned and writable only by root, so you (probably) need to make those entries writable by non-privileged applications.

You can do this using an init script, but I've chosen to do it using udev rules, since they run fairly early, are somewhat simpler once you understand the syntax, and will work regardless of what init system you're using.  Here are the rules I created to make a GPIO entry available for applications:

ACTION=="add", SUBSYSTEM=="gpio", DEVPATH=="/devices/*/gpio/gpiochip64", ATTR{subsystem/export}="86"

ACTION=="add", SUBSYSTEM=="gpio", DEVPATH=="/devices/*/gpio/gpio86",     RUN+="/bin/chgrp -R gpio $sys$devpath", RUN+="/bin/chmod -R g+w $sys$devpath"

The first rule performs the export operation, creating the entry /sys/class/gpio/gpio86.  That, in turn, triggers the second rule, which changes the group ownership and permissions of everything under /sys/class/gpio/gpio86 to be writable by members of the group "gpio" (which you will need to create).  You then create a user who is a member of the group "gpio", run your application(s) as that user, and you should be able to dance on the GPIO pin.

Again, this is all for the 3.10.x series kernel in Dora (and probably Daisy as well).  Hope this made some sense...

7,811 Views
daveebright
Contributor III

I already had added my GPIOs to the hoggrp and defined the pad control.  Export and configuration of the gpio via command line in an init script, shell script, or c code were going to be backup plan.  Leo thanks for the specifics on how you went about this.  That is helpful!!!

However I still think it would be better to perform this configuration during kernel init so that you have defined the state of the gpio (it doesn't blip on or off for several seconds until the init completes and an init script performs the desired configuration).  I guess I can at least configure the gpios in u-boot so that their initial state is defined until an init script can run to configure them for general purpose use.

0 Kudos
7,811 Views
leoschwab
Contributor III

Dave Ebright wrote:

However I still think it would be better to perform this configuration during kernel init so that you have defined the state of the gpio (it doesn't blip on or off for several seconds until the init completes and an init script performs the desired configuration).

I agree.  However, this appears to be a common complaint about embedded Linux.  While Googling for possible solutions, I got the impression that the Raspberry-PI crowd has the same complaint -- Linux doesn't init GPIOs until comparatively late, causing them to flap in the breeze for a long time at startup.  Doing the setup in U-Boot appears to be best available solution, assuming the kernel doesn't come along and completely reset everything...

7,811 Views
daveebright
Contributor III

Before device trees configuring a GPIO was easy.  You would just go to the board's init function and make the modifications/patch to configure the GPIO, initialize the value of the GPIO if it was an output, and export the GPIO to sysfs for easy user space access.  The board init was performed early on and thus the GPIOs were configured shortly after MUXing was complete.

Fabio I'll look to see if setting up the GPIO as a GPIO controlled regulator will work for me.

0 Kudos
7,811 Views
fabio_estevam
NXP Employee
NXP Employee

Can't you define this GPIO as a GPIO controlled regulator in your dts file?

0 Kudos