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.

GPIO Driver Problem

I must be missing something really obvious getting the GIO driver to work. I am using the DM355 EVM and I'm just trying to toggle GIO54. Here's the code, the output is listed below, don't get bogged down on naming i started with GIO32 and changed to GIO54:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/fs.h>

#include <asm/arch/gio.h>

#define PINMUX0 __REG(0x01c40000)
#define DIR1 __REG(DAVINCI_GPIO_BASE + 0x38)//__REG(0x01c67038)
#define BINTEN __REG(0x01c67008)
#define OUT_DATA01 __REG(0x01c6703C)
#define SET_DATA01 __REG(0x01c67040)
#define CLR_DATA01 __REG(0x01c67044)

static int __init GIO32_init(void)
{
    // GIO54 is to be tested
    u32 gpio = 54;
    
    printk(KERN_INFO "GIO%d: %d\n", gpio, __gpio_get(gpio) );
    
    printk(KERN_INFO "GIO%d Address: 0x%08lX\n",gpio, DAVINCI_GPIO_BASE + 0x38 );
    
    printk(KERN_INFO "PINMUX0 : 0x%08lX\n",PINMUX0);
    printk(KERN_INFO "DIR1    : 0x%08lX\n",DIR1);      
    printk(KERN_INFO "OUT_DATA    : 0x%08lX\n",OUT_DATA01);
     printk(KERN_INFO "SET_DATA    : 0x%08lX\n",SET_DATA01);
    

    /* Configure GPIO as an OUTPUT */
    gpio_set_direction(gpio, GIO_DIR_OUTPUT);

    /* Disable interrupts */
    gpio_interrupt_disable(gpio, TRIGGER_RISING_EDGE);
    gpio_interrupt_disable(gpio, TRIGGER_FALLING_EDGE);
    
    /*set pin to zero*/
   if( gpio_clear(gpio) < 0 )
    { //failed to set the output
        return -1;
    }
    
    printk(KERN_INFO "\nPINMUX0 : 0x%08lX\n",PINMUX0);
    printk(KERN_INFO "DIR1    : 0x%08lX\n",DIR1);      
    printk(KERN_INFO "OUT_DATA    : 0x%08lX\n",OUT_DATA01);
    printk(KERN_INFO "SET_DATA    : 0x%08lX\n",SET_DATA01);
     
    printk(KERN_INFO "GIO%d: %d\n", gpio, __gpio_get(gpio) );
    printk(KERN_INFO "GIO32 Module Loaded\n");
    
    return 0;
}

static void __exit GIO32_exit(void)
{
    // GIO54 is to be tested
    u32 gpio = 54;
    printk(KERN_INFO "GIO%d: %d\n", gpio, __gpio_get(gpio) );
    printk(KERN_INFO "GIO32 Module exit\n");
}

/* init and exit functions */
module_init(GIO32_init);
module_exit(GIO32_exit);

MODULE_LICENSE("GPL");

I start by probing pin 1(GIO54) on header DC7 it reads 3.3V.  I then load the module, the output is listed below.

Console Output:
root@10.10.40.32:/opt/dvsdk# insmod GPIO32.ko
GIO54: 0
GIO54 Address: 0x01C67038
PINMUX0 : 0x00007F55
DIR1    : 0xDEBFFFDE
OUT_DATA    : 0x20400000
SET_DATA    : 0x20400000

PINMUX0 : 0x00007F55
DIR0    : 0xDEBFFFDE
OUT_DATA    : 0x20000000
SET_DATA    : 0x20000000
GIO54: 0
GIO32 Module Loaded
root@10.10.40.32:/opt/dvsdk# rmmod GPIO32
GIO54: 0
GIO32 Module exit

I probe the pin again and it still reads 3.3V. What gives? I currently have no other loadable modules running on the board so there should be no interaction there. I did try using:
  DIR1 &= 0xFFBFFFFF;    //for setting to output
  OUT_DATA01 &= 0xFFBFFFFF;    //set the pin low
  SET_DATA01&= 0xFFBFFFFF;    //set the pin low

But the pin never budges from 3.3V. What I can gather, from the board schematics, there is nothing pulling that pin high. Please, what am I missing?

Thanks for any direction you can give, it will be most appreciated.

  • Nathan,

    Had the same problem. Look in http://focus.ti.com/lit/ug/sprufb3/sprufb3.pdf page 122 for description about PINMUX registers. The one that controls the GPIO 54 is PINMUX2. To select that pin as a GIO you need to set bit [3:2] to 2. I.E. 0x8.

    In the set_nand function it gets set to enable all of the EMIF signals, 0x4. Hence however much you try and set the GIO, nothing happens.

    Nicked some code from the setup_nand function in board-dm355-evm.c which you'll find in ti-davinci/arch/arm/mach-davinci in a standard install.  For my app I needed to drive GIO60 as well so from the code snip below, I've written 0x9, to set both GIO54 and GIO60 as outputs then you can set em up as you wish.

    hope this helps, your understanding. Sorry about the magic numbers.

            void __iomem *pinmux2 = (void __iomem *) IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x8);

            /* Configure the pin multiplexing to enable all of the EMIF signals except GIO54 and 60 for controlling the camera  */
            __raw_writel(0x00000009, pinmux2);

           /* Initially I set both to zero, think I can do away with the set_value calls if I just change the value parameter in the direction_output calls. */

           gpio_direction_output(GPIO(54),0);
            gpio_direction_output(GPIO(60),0);

            gpio_set_value(GPIO(54),0);
            gpio_set_value(GPIO(60),1);
            printk("TILLER_GPIO_code_executed\n");

    RIchard

  • Thanks for the update, i knew it had to be something like that, but I just couldn't find it.

    I will give it a whirl when I get my box back up and running properly, and let you know the results.

     

    Thanks again

  • Hi,

    I'm developing GPIO driver. After compiling my device driver successfully, insmod gpio-drv.ko.

    I got the following error. "Undefined symbol : gpio_set_direction".

    Below is my Makefile.

    INCLUDEDIR := /home/sylee/project/HD_IP_CAMERA/ti-davinci/include
    DFLAGS := -D__KERNEL__ -I$(INCLUDEDIR) -Wall -O2
    CROSS_COMPILE := arm_v5t_le-
    CC=$(CROSS_COMPILE)gcc
    obj-m := gpio-drv.o
    all: gpio-driver gpio-app
    gpio-driver:
            make -C /home/sylee/project/HD_IP_CAMERA/ti-davinci M=`pwd` modules
    gpio-app:
            $(CC) $(CFLAGS) gpio-app.c -o gpio-app
    clean:
            rm -f *.ko gpio-app

    Can you tell me what's wrong with my Makefile?

    How to resolve "Unknown symbol : gpio_set_direction"

  • Where did you get the linux kernel you are working with?  After quickly browsing tru the kernel source code we provide with the DVSDK 1.30.00.41 (our latest), I could not find any implementation of gpio_set_direction; I could not even find a header file that defines this function.  The error message suggests that even though the binary built correctly the symbol (or implementation) for gpio_set_direction could not be found. 

    I believe that the gpio functions you should be using are located under 'ti-davinci/arch/arm/mach-davinci/gpio.c ', though I have not tried these myself.

  • The DVSDK version I am using is 1.30.00.23, and this version still has the gpio_set_direction functions in gpio.c. Newer versions probably have different function calls, but I wouldn't know as I'm just getting something quickly pushed out for proof of concept with this old software that was already setup and ready to roll for me.

    Richard thanks again for the pinmux response that was the part that I was missing. Now I can toggle the GIO's with ease. For some reason, I was thinking that the pinmuxs were being set in gpio_set_direction(), but apparently they were not, so I never thought to set them separately. Need to read a little more carefully next time. Thanks again for the shove in the right direction

     

  • Hi Andeddo,

    I am working on Dm365 of kernel version 2.6.18. I have to toggle LED1(GPIO57) & LED2()GPIO58) of Dm365 leopard board.

    I am struggling as direction is not getting set . I am using Driver written by ti ,got it by googling GPIO and PINMUX Driver for TMS320DM6446 and TMS320DM355 (SPRAB39 ).

    Can you please give me your working driver for reference? As I am struggling a lot and not able to meet dead lines.

     

     

    Thanks in advance.

     

    Regards,

    Ramjee Y.