www.pudn.com > leddrv_irq.rar > leddrv.c


/***************************************************************
* Beijing Hyesco CO,LTD 
* File Name: leddrv.c
* Description: Light leds(PC14&PC15) on h9200 board
* with timer and irq example
* Revised:2005/12/30
* Author: flyerwing(weian@hyesco.com)
***************************************************************/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

static int at91_led_open (struct inode *,struct file *);
static int at91_led_close(struct inode *,struct file *);
static int at91_led_ioctl(struct inode *,struct file *,int,unsigned long);
static unsigned int major =249;

static struct file_operations led_fops=
{     
      open:    (void(*))at91_led_open,
      release: (void(*))at91_led_close,
      ioctl:   (void(*))at91_led_ioctl,
};

devfs_handle_t led_handle_t; 
char drvname[]="led";
            
#define CMD_TC_PERIOD  0 
#define CMD_LED_ON     1
#define CMD_LED_OFF    2
#define CMD_INT_ON     3
#define CMD_INT_OFF    4

s32 i=0;
AT91PS_SYS sys= (AT91PS_SYS)AT91C_VA_BASE_SYS;
AT91PS_TC  tc =(AT91PS_TC)AT91C_VA_BASE_TC1;

static void tc1_init(void)
{
      volatile s32 status;
      
      sys->PMC_PCER=0x1<TC_CCR=AT91C_TC_CLKDIS;
    
     
      status=tc->TC_SR;
      tc->TC_CMR=AT91C_TC_TIMER_DIV5_CLOCK|AT91C_TC_CPCTRG;
      tc->TC_CCR=AT91C_TC_CLKEN;
      tc->TC_IER=AT91C_TC_CPCS;
      
      sys->AIC_ICCR=0x1<TC_RC=0;
      tc->TC_CCR=AT91C_TC_SWTRG;
}

static void tc1_irq_handler(int irq,void *dev_id,struct pt_regs *regs)
{
       volatile s32 status;
       status=tc->TC_SR;
 
       printk("Ok,interrupt occur %d times\n",i++);
       sys->AIC_ICCR=0x1<PIOC_SODR=(unsigned int)(1<<14)|(unsigned int)(1<<15);
       udelay(8000);
}
static int at91_led_open(struct inode *inode,struct file *filp)
{
       sys->PIOC_PER=(unsigned int)(1<<14)|(unsigned int)(1<<15);
       sys->PIOC_OER=(unsigned int)(1<<14)|(unsigned int)(1<<15);
       
       /* request irq */
       if(request_irq(AT91C_ID_TC1,tc1_irq_handler,SA_INTERRUPT,"tc1",NULL)<0)
          printk("timer1 interrupt request failed!\n");
       tc1_init();
       sys->PIOC_CODR=(unsigned int)(1<<14)|(unsigned int)(1<<15);
       return 0;
}
static int at91_led_close(struct inode *inode,struct file *filp)
{      
       disable_irq(AT91C_ID_TC1);
       /*free irq */
       free_irq(AT91C_ID_TC1,NULL);
       return 0;
}
static int __init led_init_module(void)
{
 
     led_handle_t=devfs_register(NULL,drvname,DEVFS_FL_DEFAULT,major,0,S_IFCHR|S_IRUSR|
                                  S_IRGRP|S_IWGRP,&led_fops,NULL);
     printk("Led Register OK!\n");
     return 0;

}
static void __exit led_cleanup(void)
{
      devfs_unregister(led_handle_t);
      printk("Led Unregister OK!\n");

}
static int at91_led_ioctl(struct inode * s_node,struct file * s_file,int cmd,unsigned long arg)
{      
       u32 iodata=0;
       switch(cmd)
       {
        case CMD_TC_PERIOD:
             if(copy_from_user((char *)&iodata,(char*)arg,sizeof(arg)))
                return -EFAULT;
             tc->TC_RC=(unsigned int)iodata;
             break;
        case CMD_LED_ON:
             sys->PIOC_SODR=(unsigned int)(1<<14)|(unsigned int)(1<<15);    
             break;
        case CMD_LED_OFF:
             sys->PIOC_CODR=(unsigned int)(1<<14)|(unsigned int)(1<<15);
             break;
        case CMD_INT_ON:
             enable_irq(AT91C_ID_TC1);
             break;
        case CMD_INT_OFF:
             disable_irq(AT91C_ID_TC1);
             break;
        default:
             break;
       }
      return 0;
}

module_init(led_init_module);
module_exit(led_cleanup);

MODULE_AUTHOR("flyerwing");
MODULE_DESCRIPTION("H9200 LED Driver");
MODULE_LICENSE("GPL");

/*end of leddrv.c*/