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*/