Puckett

Problems using LVDS pins as GPIOs on the i.MX53 Quick Start Board

Discussion created by Puckett on Oct 5, 2011
Latest reply on Jul 19, 2012 by Jose Nicolas Izquierdo Martinez

We have some prototype boards on order that are using the following LVDS pins as GPIOs:

LVDS0_TX0_N
LVDS0_TX0_P
LVDS0_TX1_N
LVDS0_TX1_P

 

In preparation for the boards' arrival I have been attempting to access these pins as GPIOs via the Linux sysfs GPIO driver.

 

In my mx53_loco.c file I have added these entries to the pad definitions:

MX53_PAD_LVDS0_TX1_P__GPIO7_28
MX53_PAD_LVDS0_TX0_P__GPIO7_30

I have ensured that there are no conflicting entries in the pad definitions by commenting out the existing block of LVDS pad definitions.  There are no entries for LVDS0_TX0_N and LVDS0_TX1_N as they are not muxed.

 

According to the quick start board schematic these lines go to the following pins on the LVDS connector (J9):

LVDS0_TX0_N - 8
LVDS0_TX0_P - 9
LVDS0_TX1_N - 11
LVDS0_TX1_P - 12

 

On the target I do the following in /sys/class/gpio:

  1. Set up access to the GPIO, in this case GPIO-7[29] for LVDS0_TX1_N:
    echo 221 > export
  2. cd gpio221
  3. Change the direction from in to out:
    echo out > direction
  4. Set the value to 1:
    echo 1 > value

 

At this point I check pin 11 of the LVDS connector with a scope and see no change in the signal.  I see the same behavior when I try the other three GPIOs as well.

 

As a test of the sysfs GPIO driver I was successfully able to control the user LED by doing the following in /sys/class/gpio:

  1. echo 199 > export
  2. cd gpio199
  3. echo out > direction (LED goes off)
  4. echo 1 > value (LED comes on)
  5. echo 0 > value (LED goes off)

 

To help debug this problem I added some printk() calls to the mxc_gpio_set() function in arch/arm/plat-mxc/gpio.c:

    //TEST
    printk("%s() - reg = %p, offset = %d, value = %d, GPDIR = 0x%X PSR = 0x%X\n", __func__,
        reg, offset, value, __raw_readl(reg + GPIO_GDIR), __raw_readl(reg + GPIO_PSR));
    //ENDTEST
    spin_lock_irqsave(&port->lock, flags);
    l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset);
    __raw_writel(l, reg);
    spin_unlock_irqrestore(&port->lock, flags);
    //TEST
    printk("%s() - after write: DR = 0x%X, GPDIR = 0x%X PSR = 0x%X\n", __func__,
        __raw_readl(reg), __raw_readl(reg + GPIO_GDIR), __raw_readl(reg + GPIO_PSR));
    //ENDTEST

 

I also added the following to mxc_gpio_get():

    //TEST
    printk("%s() - base = %p, offset = %d, DR = 0x%X, GPDIR = 0x%X PSR = 0x%X\n",
        __func__, port->base, offset, __raw_readl(port->base),
        __raw_readl(port->base + GPIO_GDIR), __raw_readl(port->base + GPIO_PSR));
    //ENDTEST

 

With these in place I get the following output:

root@freescale /sys/class/gpio$ echo 221 > export
root@freescale /sys/class/gpio$ cd gpio221
root@freescale /sys/class/gpio/gpio221$ cat direction
in
root@freescale /sys/class/gpio/gpio221$ echo out > direction
mxc_gpio_set() - reg = f7ee4000, offset = 29, value = 0, GPDIR = 0x3140 PSR = 0xFFC00EAF
mxc_gpio_set() - after write: DR = 0xFFC00FEF, GPDIR = 0x3140 PSR = 0xFFC00EAF
root@freescale /sys/class/gpio/gpio221$ cat value
mxc_gpio_get() - base = f7ee4000, offset = 29, DR = 0xDFC00FEF, GPDIR = 0x20003140 PSR = 0xFFC00EAF
1
root@freescale /sys/class/gpio/gpio221$ echo 1 > value
mxc_gpio_set() - reg = f7ee4000, offset = 29, value = 1, GPDIR = 0x20003140 PSR = 0xFFC00EAF
mxc_gpio_set() - after write: DR = 0xFFC00FEF, GPDIR = 0x20003140 PSR = 0xFFC00EAF
root@freescale /sys/class/gpio/gpio221$ echo 0 > value
mxc_gpio_set() - reg = f7ee4000, offset = 29, value = 0, GPDIR = 0x20003140 PSR = 0xFFC00EAF
mxc_gpio_set() - after write: DR = 0xDFC00FEF, GPDIR = 0x20003140 PSR = 0xFFC00EAF

 

It looks like the data and direction registers are getting set correctly yet I am not able to see the signal change on the scope.

 

On a side note the current implementation in gpio.c will not correctly report the status of an output GPIO using the "cat value" command.  It's set to read the value from the PSR register which only reports the values of input signals.

 

What am I missing here?


Outcomes