Problem with uboot gpio pin status...

Hi, people.

I configured the u-boot to have SPI, UART and GPIO pins on the expansion header. SPI and UART works fine.
The problem is that all the GPIO are not in the state in which I set on “beagle.h”. After booting I can change the status of all the GPIO using /sys/class… so no problem with this.
The problem is that one of the GPIO (gpio158) is connected to a buzzer and the state of this pin on boot is “1”, then the buzzer start always making noise throughout the boot process (approx. 1 minute). This is not what I want :).
Below, I write the “beagle.h” configuration file:

#define MUX_BEAGLE_C()
MUX_VAL(CP(MCBSP3_DX), (IEN | PTD | DIS | M4)) /GPIO_140/
MUX_VAL(CP(MCBSP3_DR), (IEN | PTD | DIS | M4)) /GPIO_142/
MUX_VAL(CP(MCBSP3_CLKX), (IEN | PTD | DIS | M4)) /GPIO_141/
MUX_VAL(CP(MCBSP3_FSX), (IEN | PTD | DIS | M1)) /UART2_RX/
MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)) /UART2_TX/
MUX_VAL(CP(MMC2_DAT7), (IEN | PTD | EN | M4)) /GPIO_139/
MUX_VAL(CP(UART2_CTS), (IEN | PTD | DIS | M4)) /GPIO_144/
MUX_VAL(CP(MMC2_DAT6), (IEN | PTD | EN | M4)) /GPIO_138/
MUX_VAL(CP(MMC2_DAT5), (IEN | PTD | EN | M4)) /GPIO_137/
MUX_VAL(CP(MMC2_DAT4), (IEN | PTD | EN | M4)) /GPIO_136/
MUX_VAL(CP(UART2_RTS), (IEN | PTD | EN | M4)) /GPIO_145/
MUX_VAL(CP(MCBSP1_DX), (IEN | PTD | EN | M4)) /GPIO_158/</b>
MUX_VAL(CP(MMC2_DAT2), (IEN | PTD | EN | M4)) /GPIO_134/
MUX_VAL(CP(MCBSP1_CLKX), (IEN | PTD | EN | M4)) /GPIO_162/
MUX_VAL(CP(MMC2_DAT1), (IEN | PTU | EN | M4)) /GPIO_133/
MUX_VAL(CP(MCBSP1_FSX), (IEN | PTD | EN | M4)) /GPIO_161/
MUX_VAL(CP(MCBSP1_DR), (IEN | PTD | EN | M4)) /GPIO_159/
MUX_VAL(CP(MCBSP1_CLKR), (IEN | PTD | EN | M4)) /GPIO_156/
MUX_VAL(CP(MCBSP1_FSR), (IEN | PTD | EN | M4)) /GPIO_157/
MUX_VAL(CP(I2C2_SDA), (IEN | PTD | EN | M4)) /GPIO_183/
MUX_VAL(CP(I2C2_SCL), (IEN | PTU | EN | M4)) /GPIO_168/
MUX_VAL(CP(MMC2_DAT3), (IEN | PTD | EN | M1)) /SPI3_CS0/
MUX_VAL(CP(MMC2_DAT0), (IEN | PTU | EN | M1)) /SPI3_SOMI/
MUX_VAL(CP(MMC2_CMD), (IEN | PTU | DIS | M1)) /SPI3_SIMO/
MUX_VAL(CP(MMC2_CLK), (IEN | PTU | DIS | M1)) /SPI3_CLK/

BB-C4
u-boot version: 2011.09
OMAP_CONFIG_MUX = n

Thank’s a lot.

daniel.

change the line to" MUX_VAL(CP(MCBSP1_DX), (IDIS | PTU | DIS | M4)) /GPIO_158/"
and check the response

Thank’s Sudheer D but I’m still have the problem.

I change the line to" MUX_VAL(CP(MCBSP1_DX), (IDIS | PTU | DIS | M4)) /GPIO_158/" and the result is the same.

cat /sys/class/gpio/gpio158/direction : in
cat /sys/class/gpio/gpio158/value : 1

daniel.

Hi

Quoting daicav <daicav@gmail.com>:

cat /sys/class/gpio/gpio158/direction : in
cat /sys/class/gpio/gpio158/value : 1

Telling from this output, I'd say, the kernel did not care about the direction settings in U-Boot. Actually I'm not too sure if it's the right strategy to do the whole pinmux in the secondary stage loader.

Anyway, I think what you have to do is telling the kernel at board init time what you want to do with your GPIO: If I were in your shoes, I'd request the gpio and set it's direction in the board init file of your kernel like in the following "patch":

in arch/arm/mach-omap2/board-omap3beagle.c:
   create a new static function like this:
     /*! \brief Initializes a gpio as output and sets it to 0

         \param gpio Number of the GPIO to be initialized */
     static void __init buzzer_init(unsigned gpio)
     {
       /* Tell the kernel, we want to use the GPIO 158 */
       if (gpio_request(gpio, "myBuzzer") != 0)
       {
         printk(KERN_ALERT "Buzzer: Unable to request GPIO %d", gpio);
       }
       else
       {
         /* Now tell the kernel that GPIO 158 is an output and should
            be set to 0 */
         if (gpio_direction_output(gpio, 0) != 0)
         {
            printk(KERN_ALERT "Buzzer: Unable to set GPIO direction for GPIO %d", gpio);
         }
       }
     }

   in function static void __init omap3_beagle_init(void)
     add a call to above function like this:
       buzzer_init(158);

But maybe theres a better way to achieve the same goal. Honestly the whole init concept seems to me not very standardized (at least for the omap tree) or is at least a little mistery for me :wink:

I hope that helps
Ueli

The above solution solves the problem but after I started the system I don’t have access to gpio158 on /sys/class/gpio. This is because it was never exported to user space. I added some lines to the previous code to achieve export gpio158 and now everything works fine.
Below, I write the modified code:

static void __init buzzer_init(unsigned gpio)
{
/* Tell the kernel, we want to use the GPIO 158 /
if (gpio_request(gpio, “myBuzzer”) != 0)
{
printk(KERN_ALERT “Buzzer: Unable to request GPIO %d”, gpio);
}
else
{
/
Now tell the kernel that GPIO 158 is an output and should
be set to 0 */
if (gpio_direction_output(gpio, 0) != 0)
{
printk(KERN_ALERT “Buzzer: Unable to set GPIO direction for GPIO %d”, gpio);
}
else
{
gpio_export(gpio, 0);
}
}
}

The only thing missing is the direction on /sys/class/gpio/gpio158/direction but no problem for me.

Thank you very much Ueli Niederer.

I read something else!

gpio_export(gpioNumber, 0) means that there’s no “direction” on /sys/class/gpio/gpioNumber/ (you can’t change direction)

and

gpio_export(gpioNumber, 1) means that you can access (and change) the direction of the gpio.

daniel.

Quoting daicav <daicav@gmail.com>:

I read something else!
*gpio_export(gpioNumber, 0)* means that there's no "direction" on
/sys/class/gpio/gpioNumber/ (you can't change direction)
[...]
*gpio_export(gpioNumber, 1)* means that you can access (and change) the
direction of the gpio.

Nothing wrong with your explaination. Except the fact that taku tried to access GPIO from user space using sysfs. And according to gpiolib, if you export a gpio using the /sys/class/gpio/export file, the gpio is exported with following line (ln 625 in gpiolib.c of 2.6.39 kernel):
   status = gpio_export(gpio, true);

So he should be able to manipluate the direction from userspace.

regards
ueli

Quoting Ueli Niederer <beagleboard.org_group@junix.ch>:

Quoting daicav <daicav@gmail.com>:

I read something else!
[...]

Nothing wrong with your explaination. Except the fact that taku tried to [...]

I just realized that, while writing my answer, I falsely attributed your answer to another discussion in this group[1], mea culpa.

Of course your addition and it's correction is totally right.

To summarize the discussion, your final solution including all modifications is now

in arch/arm/mach-omap2/board-omap3beagle.c:
    create a new static function like this:
      /*! \brief Initializes a gpio as output and sets it to 0

          \param gpio Number of the GPIO to be initialized */
      static void __init buzzer_init(unsigned gpio)
      {
        /* Tell the kernel, we want to use the GPIO 158 */
        if (gpio_request(gpio, "myBuzzer") != 0)
        {
          printk(KERN_ALERT "Buzzer: Unable to request GPIO %d", gpio);
        }
        else
        {
          /* Now tell the kernel that GPIO 158 is an output and should
             be set to 0 */
          if (gpio_direction_output(gpio, 0) != 0)
          {
             printk(KERN_ALERT "Buzzer: Unable to set GPIO direction
for GPIO %d", gpio);
          }
          else
          {
            /* Export the gpio to userspace without the possibility of changing
               direction. If this is needed, pass 1 instead of 0 */
            gpio_export(gpio, 0);
          }
        }
      }

    in function static void __init omap3_beagle_init(void)
      add a call to above function like this:
        buzzer_init(158);

Is this correct? In fact, I think in your case it's not optional to be able to change direction settings from userspace, it's even more mandatory to prevent such an action from userspace since you have some hardware outside expecting an output connected to it.

regards
ueli