GPIO를초기화를 하였다면 GPIO를 제어하는 합수에 대해서 알아 보도록 하겠습니다.

 

1) gpio_set_value(unsigned gpio, int value)

   

    gpio를 High 또는 Low로 설정하는 함수이다. 아래는 gpio_set_value 함수의 흐름이다.
 
    - arch/arm/mach-s3c6400/include/mach/gpio.h

       

           #define gpio_set_value  __gpio_set_value

 

    - include/asm-generic/gpio.h

  

           extern void __gpio_set_value(unsigned gpio, int value);

 

    - drivers/gpio/gpiolib.c
 
           void __gpio_set_value(unsigned gpio, int value)
 
저번 소스에 이어 gpio_set_value 를 IOCTL 함수에 추가하도록 하겠습니다.
 

Write함수에서 제어해도 상관은 없지만 좀더 유연성을 가지기 위해서 IOCTL 함수를 사용하기로 합니다.

 

 

1. gpio.h

 

  #ifndef _DEV_GPIO_H_
  #define _DEV_GPIO_H_

 

  /* 모듈관련 -------------------------------------------------------------------*/
  #define GPIO_MAJOR_DEF 203
  #define GPIO_DEV_NAME "S3C6410 GPIO Ver 1.0"


  /* ioctl 함수의 command -------------------------------------------------------*/
  #define   GPIO_IOCTL_MAGIC   'd'

 

  #define   IOCTL_GPIO_ON            _IO ( GPIO_IOCTL_MAGIC, 1 )
  #define   IOCTL_GPIO_OFF          _IO ( GPIO_IOCTL_MAGIC, 2 )

 

  #endif // _DEV_GPIO_H_

 

 

2. gpio.c

 

  #ifndef __KERNEL__
  #define __KERNEL__
  #endif
 
  #ifndef MODULE
  #define MODULE
  #endif
 
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/version.h>
  #include <linux/init.h>
  #include <linux/fs.h>
  #include <linux/sched.h>
  #include <linux/interrupt.h>
  #include <linux/wait.h>
  #include <linux/ioport.h>
  #include <linux/slab.h>
  #include <linux/poll.h>
  #include <linux/proc_fs.h>
  #include <linux/irq.h>
  #include <linux/io.h>
  #include <linux/delay.h>
 
  #include <asm/system.h>    
  #include <asm/uaccess.h>
  #include <asm/irq.h>
  #include <asm/ioctl.h>
  #include <asm/unistd.h>
  #include <asm/io.h>
  #include <asm/delay.h>
 
  #include <mach/gpio.h>
  #include <mach/map.h>
  #include <mach/regs-mem.h>
 
  #include <plat/clock.h>
  #include <plat/gpio-cfg.h>
  #include <plat/regs-gpio.h>
  #include <plat/regs-timer.h>
 
 
  #include  "dev-gpio.h"
 
  static int major  = GPIO_MAJOR_DEF;
 
 
  //------------------------------------------------------------------------------
  /** @brief   하드웨어 초기화
      @remark  인터럽트 설정은 반드시 초기화 순서를 지켜야 함
  *///----------------------------------------------------------------------------
  static void hw_gpio_init( void )
  {
        /// 출력설정 GPN5
        s3c_gpio_cfgpin (S3C64XX_GPN(5), S3C64XX_GPN_OUTPUT(5));
        s3c_gpio_setpull(S3C64XX_GPN(5), S3C_GPIO_PULL_NONE);
  }
 
  //------------------------------------------------------------------------------
  /** @brief   ioctl 함수
        @remark 
  *///----------------------------------------------------------------------------
  static int s3c6410_gpio_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg )
  {
       switch (cmd)
      {
       case IOCTL_GPIO_ON  : gpio_set_value( S3C64XX_GPN(5), 1 ); return 0;
       case IOCTL_GPIO_OFF : gpio_set_value( S3C64XX_GPN(5), 0 ); return 0;
      }        
      return -EINVAL;
}
 
  //------------------------------------------------------------------------------
  /** @brief   어플리케이션에서 디바이스를  open 하였을때 호출되는 함수
        @remark 
  *///----------------------------------------------------------------------------
  static int s3c6410_gpio_open( struct inode *inode, struct file *filp )
  {
        return 0;
  }

  //------------------------------------------------------------------------------
  /** @brief   어플리케이션에서 디바이스를  close를 하였을때 호출되는 함수
        @remark 
  *///----------------------------------------------------------------------------
  static int s3c6410_gpio_release( struct inode *inode, struct file *filp)
  {
       return 0;
  }
   //------------------------------------------------------------------------------
   /** @brief   드라이버에 사용되는 접근 함수에 대한 함수 포인터 구조체를 정의 한다.
                       이 구조체는 fs.h에 정의 되어 있다.
        @remark
   *///----------------------------------------------------------------------------
   static struct file_operations s3c6410_gpio_fops =
   {
        .open  = s3c6410_gpio_open,
        .release = s3c6410_gpio_release,
     // .poll  = s3c6410_gpio_poll,
        .ioctl  = s3c6410_gpio_ioctl,
   };
 
   //------------------------------------------------------------------------------
   /** @brief  Module Init
        @return  0 : Success
                      -1: Fail
   *///----------------------------------------------------------------------------       
   static __init int s3c6410_gpio_init( void )
   {
        /// 장치를 등록한다. ============================================
        major &= 0xff;
        if( !register_chrdev( major, GPIO_DEV_NAME, &s3c6410_gpio_fops ) )
        {
             printk("\nRgister device %s Ok (major=%d)\n", GPIO_DEV_NAME, major );
             printk( "Last Modify %s\n\n", __DATE__);
        }
        else
        {
             printk("\nUnable to get major %d for %s \n", major, GPIO_DEV_NAME );
             return -EBUSY;
        }
 
        hw_gpio_init();
 
        return 0;
   }
 
   //------------------------------------------------------------------------------
   /** @brief  Module Exit
   *///----------------------------------------------------------------------------       
   static __exit void s3c6410_gpio_free( void )
   {
        /// 장치등록을 해지한다.
        unregister_chrdev( major, GPIO_DEV_NAME );
        printk("\nUnregister %s Ok\n\n", GPIO_DEV_NAME );
   }
 
   module_init(s3c6410_gpio_init);
   module_exit(s3c6410_gpio_free);
 
   MODULE_AUTHOR("falinux.com");
   MODULE_LICENSE("GPL");