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

Hi all

my kernel is 2.6.22.18 the kernel and i cannot go to latest kernel

my driver is:

-----------------------------------------------------------------------------------------------------

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h> /* get_user and put_user */
#include <asm/arch/gpio.h>
//#include <asm/gpio.h>

#include <asm/arch/omap34xx.h>
#include <asm/arch/hardware.h>

#include <asm/arch/mux.h>
//#include <asm/arch/irda.h>
#include <asm/arch/board.h>
#include <asm/arch/common.h>
#include <asm/arch/keypad.h>
#include <asm/arch/dma.h>
#include <asm/arch/gpmc.h>
#include <asm/arch/twl4030-rtc.h>
#include <asm/arch/mcspi.h>
#include <asm/arch/prcm.h>
//#include <unistd.h>
//#include <unistd.h>
/* #define DEBUG */

#include "../agm_gpio.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Doron Sandroy(AGMtonson)");

#define GPIO_DIR_INPUT              1
#define GPIO_DIR_OUTPUT             0


#define OMAP_MPUIO_INPUT_LATCH  0x00
#define OMAP_MPUIO_OUTPUT  0x04
#define OMAP_MPUIO_IO_CNTL  0x08
#define OMAP_MPUIO_KBR_LATCH  0x10
#define OMAP_MPUIO_KBC   0x14
#define OMAP_MPUIO_GPIO_EVENT_MODE 0x18
#define OMAP_MPUIO_GPIO_INT_EDGE 0x1c
#define OMAP_MPUIO_KBD_INT  0x20
#define OMAP_MPUIO_GPIO_INT  0x24
#define OMAP_MPUIO_KBD_MASKIT  0x28
#define OMAP_MPUIO_GPIO_MASKIT  0x2c
#define OMAP_MPUIO_GPIO_DEBOUNCING 0x30
#define OMAP_MPUIO_LATCH  0x34
struct semaphore sw_sem;
#define CONTROL_PADCONF_ETK_D2  (void __iomem *)0x480025E0

#define MUX1_1_GPIO113 113
#define MUX1_1_GPIO114 114
#define MUX1_1_GPIO115 115
#define GPIO52 52
#define GPIO55 55
//U4_242X_GPIO51,
//V3_242X_GPIO52,

void clean_reg(int reg,int bit)
{
 int u=0;
 u=__raw_readl(IO_ADDRESS(CONTROL_PADCONF_ETK_D2));
 u= u & (~(0x7<<16));            //clean bit 16,17,18
 u = u | (0x04<<16);             // set mode 4
 u = u | ( 0x100 << 16 );        //input enable
 __raw_writel(u,IO_ADDRESS(CONTROL_PADCONF_ETK_D2));


}


static int device_open(struct inode *inode, struct file *file)
{
#ifdef DEBUG
  printk(KERN_INFO "device_open(%p)\n", file);
#endif

  return 0;
}

static int device_release(struct inode *inode, struct file *file)
{
#ifdef DEBUG
  printk(KERN_INFO "device_release(%p,%p)\n", inode, file);
#endif

  return 0;
}

static int device_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
  int ret_val = 0;
  int ret = 0;
  struct pin_value *temp_pin, pv;

  //if (down_interruptible (&sw_sem)) return -ERESTARTSYS;

  switch(ioctl_num)
  {
    case IOCTL_CONFIG_PIN_VALUE:

 temp_pin = (struct pin_value*)ioctl_param;

 //if (omap_cfg_reg(temp_pin->pin))
 if (omap_request_gpio(temp_pin->pin))
 {
  omap_free_gpio(temp_pin->pin);
 }
 else{
       printk(KERN_INFO "gpio not config(%lu )\n", temp_pin->pin);
  ret_val = -1;
  goto ioctl_out;
     }
 break;
    case IOCTL_FREE_PIN_VALUE:

  temp_pin = (struct pin_value*)ioctl_param;

  omap_free_gpio(temp_pin->pin);
  printk(KERN_INFO "gpio not free(%lu)\n", temp_pin->pin);
  ret_val = -1;
 break;
    case IOCTL_SET_PIN_VALUE:
  temp_pin = (struct pin_value*)ioctl_param;
  //printk(KERN_INFO "try to set gpio pin(%lu ) return %d \n", temp_pin->pin,ret);
  omap_request_gpio((int)temp_pin->pin);
  omap_set_gpio_direction((int)temp_pin->pin, 0); //input=1//output=0
  if ((int)temp_pin->value)
   omap_set_gpio_dataout((int)temp_pin->pin,1);
  else
   omap_set_gpio_dataout((int)temp_pin->pin,0);

  printk(KERN_INFO "gpio set(%lu ) to val %d\n", temp_pin->pin,temp_pin->value);
  //ret = omap_get_gpio_datain((int)temp_pin->pin);
  //printk(KERN_INFO "gpio get (%lu ) to val %d\n", temp_pin->pin,ret);
  omap_free_gpio((int)temp_pin->pin);
  ret_val = -1;

  break;
    case IOCTL_GET_PIN_VALUE:
    temp_pin = (struct pin_value*)ioctl_param;
    pv.pin = temp_pin->pin;
  /*
  omap_get_gpio_datain(int gpio)
  Description: This function is responsible for reading pin values.
  Parameter: int gpio - GPIO PIN (Pin 0-63)
  */
  //omap_free_gpio((int)temp_pin->pin);
  if (omap_request_gpio(temp_pin->pin)==0)
  {
   omap_set_gpio_direction(temp_pin->pin, 1); //input=1//output=0
   pv.value = omap_get_gpio_datain(temp_pin->pin);
   printk(KERN_INFO "gpio get val (%lu ) to val %d\n", temp_pin->pin,pv.value);
   if (copy_to_user(temp_pin, &pv, sizeof(struct pin_value)) != 0)
    {
    ret_val = -1;
    goto ioctl_out;
    }
    omap_free_gpio((int)temp_pin->pin);
     //ret_val = pv.value;
    //copy_to_user(temp_pin, &pv, sizeof(struct pin_value));
  }
  else{
    printk(KERN_INFO "gpio not free(%lu )\n", temp_pin->pin);
   ret_val = -1;
   goto ioctl_out;
   }
      break;
    case IOCTL_SET_PIN_INPUT:
      temp_pin = (struct pin_value*)ioctl_param;
 /*
 Description: This function is responsible for setting the gpio pin direction
       (input or output).

 Parameter: int gpio - GPIO PIN (Pin 0-63)
     int is_input - pin direction (0 = output, 1 = input)

 */
 if (omap_request_gpio(temp_pin->pin)==0)
        omap_set_gpio_direction(temp_pin->pin, temp_pin->value); //input=1//output=0
 else{
   printk(KERN_INFO "gpio not free(%lu )\n", temp_pin->pin);
  ret_val = -1;
  goto ioctl_out;
  }
     break;

  }

ioctl_out:
  //up(&sw_sem);
  return ret_val;
}


struct file_operations our_file_ops = {
  .ioctl = device_ioctl,
  .open = device_open,
  .release = device_release,
  .owner = THIS_MODULE,
};

int init_module()
{
  int ret_val;

  ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &our_file_ops);

  if (ret_val < 0)
  {
    printk(KERN_ALERT "device %s failed(%d)\n", DEVICE_NAME, ret_val);
    return ret_val;
  }

   sema_init(&sw_sem, 1);
   printk(KERN_INFO "mknod /dev/%s c %d 0\n", DEVICE_NAME, MAJOR_NUM);
/*
 omap_cfg_reg(MUX1_1_GPIO113);
 omap_cfg_reg(MUX1_2_GPIO114);
 omap_cfg_reg(MUX1_3_GPIO115);

 ret = omap_request_gpio(MUX1_1_GPIO113);
 if (ret < 0)
  printk(KERN_ERR "SELECT_MUX1_1: can't reserve GPIO:%d !\n", MUX1_1_GPIO113);
 ret = omap_request_gpio(MUX1_2_GPIO114);
 if (ret < 0)
  printk(KERN_ERR "SELECT_MUX1_2: can't reserve GPIO:%d !\n", MUX1_2_GPIO114);
 ret = omap_request_gpio(MUX1_3_GPIO115);
 if (ret < 0)
  printk(KERN_ERR "SELECT_MUX1_3: can't reserve GPIO:%d !\n", MUX1_3_GPIO115);

*/

  return 0;
}

void cleanup_module()
{
  unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
}

 

 

------------------------------------------------------------------------------------------------------

I try to togal GPIO

on the first time I get:

------------------------------------------------------------------------------------------------------

[root@OMAP3EVM /home]# ./setpin /dev/agm_gpio 153 1 0

<3>omap-gpio: GPIO 153 is already reserved!

omap-gpio: GPIO 153 is already reserved!

[<c00303a8>] [<c00303a8>] (dump_stack+0x0/0x14) (dump_stack+0x0/0x14) from [<c0057a74>] from [<c0057a74>] (omap_request_gpio+0x5c/0x88)

(omap_request_gpio+0x5c/0x88)

[<c0057a18>] [<c0057a18>] (omap_request_gpio+0x0/0x88) (omap_request_gpio+0x0/0x88) from [<bf0000f8>] from [<bf0000f8>] (device_ioctl+0xa8/0x1cc [agm_gpio])

(device_ioctl+0xa8/0x1cc [agm_gpio])

 r5:00011008 r5:00011008 r4:00011008 r4:00011008

 

[<bf000050>] [<bf000050>] (device_ioctl+0x0/0x1cc [agm_gpio]) (device_ioctl+0x0/0x1cc [agm_gpio]) from [<c00b3ea8>] from [<c00b3ea8>] (do_ioctl+0x68/0x78)

(do_ioctl+0x68/0x78)

 r5:00011008 r5:00011008 r4:4004fa00 r4:4004fa00

 

[<c00b3e40>] [<c00b3e40>] (do_ioctl+0x0/0x78) (do_ioctl+0x0/0x78) from [<c00b4114>] from [<c00b4114>] (vfs_ioctl+0x25c/0x274)

(vfs_ioctl+0x25c/0x274)

 r5:00011008 r5:00011008 r4:c05d55a0 r4:c05d55a0

 

[<c00b3eb8>] [<c00b3eb8>] (vfs_ioctl+0x0/0x274) (vfs_ioctl+0x0/0x274) from [<c00b416c>] from [<c00b416c>] (sys_ioctl+0x40/0x64)

(sys_ioctl+0x40/0x64)

 r7:c05d55a0 r7:c05d55a0 r6:4004fa00 r6:4004fa00 r5:00011008 r5:00011008 r4:00000003 r4:00000003

 

[<c00b412c>] [<c00b412c>] (sys_ioctl+0x0/0x64) (sys_ioctl+0x0/0x64) from [<c002be80>] from [<c002be80>] (ret_fast_syscall+0x0/0x2c)

(ret_fast_syscall+0x0/0x2c)

 r7:00000036 r7:00000036 r6:00000000 r6:00000000 r5:00000000 r5:00000000 r4:40023e08 r4:40023e08

 

<6>gpio set(153 ) to val 1

gpio set(153 ) to val 1

<6>gpio get val (153 ) to val 0

gpio get val (153 ) to val 0

 

 pin is free 0x99 ==> 0

------------------------------------------------------------------------------------------------------------------------------------------

on the second time I get : good display but the GPIO not set to "1"

-----------------------------------------------------------------------------------------------------------

[root@OMAP3EVM /home]# ./setpin /dev/agm_gpio 153 1 0

<6>gpio set(153 ) to val 1

gpio set(153 ) to val 1

<6>gpio get val (153 ) to val 0

gpio get val (153 ) to val 0

 

 pin is free 0x99 ==> 0

----------------------------------------------------------------------------------------------------------

 

The problem is i set or reset the GPIO on the output no change.

Regard .

Doron Sandroy

Software Team Leader

AGM tonson L.T.D

Cell : +972-52-6070406

Tel :+972-72-2500230

Fax :+972-72-2500231

 

  • Hi All

    i find the way to work with the GPIO i preper list :

    1.add to \include\asm\arch\mux.h
     to : enum omap34xx_index
     add all GPIO nedded
    2.add to  \arch\arm\mach-omap2\mux.c
     to :struct pin_config __initdata_or_module omap34xx_pins[]
     add all GPIO needed :
     this is example the gpio 112,113,114,115 is input only
     /*agm gpio out */
     MUX_CFG_34XX("MUX1_1_GPIO113",                0x136,  4,      0,      0,
    0,
                                   0,      0,      0,      0,      0,      0)
     MUX_CFG_34XX("MUX1_2_GPIO114",                0x138,  4,      0,      0,
    0,
                                   0,      0,      0,      0,      0,      0)
     MUX_CFG_34XX("MUX1_3_GPIO115",                0x13a,  4,      0,      0,
    0,
                                   0,      0,      0,      0,      0,      0)
     MUX_CFG_34XX("GPIO96"         ,               0x110,  4,      0,      0,
    0,
                                   0,      0,      0,      0,      0,      0)

     the offset add is from the pdf OMAP35x Applications Processor page 932 get
    the Physical
     Address the last 3 numbers is the offset :if the Physical Address is
    :0x4800 2134 the offset
     is 134
     3.add to devices.c new function :example

     static void omap_init_agm_gpio(void)
     {
           omap_cfg_reg(MUX1_1_GPIO113);
           omap_cfg_reg(MUX1_2_GPIO114);
           omap_cfg_reg(MUX1_3_GPIO115);
           omap_cfg_reg(GPIO96);
    }

    then add the function to :static int __init omap_init_devices(void)

    4. build driver from gpio doc

     

     Regard .
     Doron Sandroy
     Software Team Leader
     AGM tonson L.T.D
     Cell : +972-52-6070406
     Tel :+972-72-2500230
     Fax :+972-72-2500231