⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2410ps.c

📁 s3c2410平台
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************************************* 								*	Copyright (C) EVOC  Co., LTD. 2007		*								*	File name:	s3c2410ps.c				*	Description:    *	  							*	Revision history					*               2007.11.05      Bing yu liu	start.	*								************************************************************************************************//* Include files--------------------------------------------------------------*/#include <linux/version.h>#include <linux/kernel.h>     /* We're doing kernel work */#include <linux/module.h>     /* Specifically, a module */ #include <linux/interrupt.h>  /* We want interrupts */#include <linux/miscdevice.h> /* for misc_register() and misc_deregister() */#include <linux/fs.h>         /* for struct 'file_operations' */#include <linux/timer.h>     /* for timeout interrupts */#include <linux/param.h>     /* for HZ. HZ = 100 and the timer step is 1/100 */#include <linux/sched.h>     /* for jiffies definition. jiffies is incremented                              * once for each clock tick; thus it's incremented*/#include <linux/mm.h>        /* for verify_area */#include <linux/types.h>#include <linux/slab.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/poll.h>#include <asm/irq.h>         /* For IRQ_MACHSPEC */#include <asm/io.h>#include <asm/uaccess.h>#include <asm/arch/irqs.h>#include <asm/arch/hardware.h>        /* For IRQ_MACHSPEC */static const char* __file__ = __FILE__;#define PS2_MINOR   0#define DEVICE_NAME    "s3c2410ps"#define FSRTC_MINOR   0#define IRQ_PS2    IRQ_EINT10  // GPB4    GPG2   // DATA    CLK    #define PS2_DATA_CLR    (GPBDAT &= ~(1<<4))#define PS2_DATA_SET    (GPBDAT |= (1<<4))#define PS2_REVBUFFER_SIZE        0x8#define PSSTATUS_WAITREV          0    //wait receive#define PSSTATUS_REVING           1    //receive data#define PSSTATUS_REVPARITY        2    //receive parity#define PSSTATUS_REVSTOP          3    //receive stop#define PSSTATUS_SendPDCLK        4    //when request send, Then down clk#define PSSTATUS_SendWTCLK        5    //When request send, Then wait change of clk#define PSSTATUS_SendDATA         6    //Send data#define PSSTATUS_SendPARITY       7    //Send Parity#define PSSTATUS_SendSTOP         8    //Send stop#define PSSTATUS_SendWTACK        9    //Wait ack while send#define PS2_SEND_OK               0    //PS/2 send ok#define PS2_SEND_FAILED           0xff //PS/2 send failed#define GETPS0Data()     (GPBDAT & (0x1<<4))//PS/2 status regstatic char ps0status = PSSTATUS_WAITREV;//, sendps2 = 0;static struct timer_list key_timer;//PS/2 data buffer manage#define PS2_BUFCNT_INC(inc)   do{inc++;inc & = (PS2_REBUFFER_SIZE - 1);}while(0)#define Stop_Time1()       do{del_timer(&key_timer);}while(0)static int DbPs2Major = 0;static int   device_open = 0;static unsigned char PS0revdata;volatile char count = 0,paritysum = 0;#ifdef CONFIG_DEVFS_FS 	static devfs_handle_t devfs_PS2_dir,devfs_PS2raw;#endif//static unsigned char ps2_data_buff[PS2_REVBUFFER_SIZE];static unsigned char ps2_senddata0,//ps2_data_Revcnt0 = 0,ps2_data_Readcnt0 = 0,                     lastps2sendstatus0 = PS2_SEND_OK;                     #define PS2_BUF_SIZE    32                   typedef struct S3C2410fcrps2 {	unsigned long head;	unsigned long tail;	wait_queue_head_t proc_list;	struct fasync_struct *fasync_queue;	unsigned char buf[PS2_BUF_SIZE];} S3C2410fcrps2; wait_queue_head_t proc_list_w;static int new_ps2_state = 0;//static int device_open = 0;static S3C2410fcrps2   * s3c2410fcrps2_device; volatile u8 place = 0;;void set_timer_irq(struct timer_list *timer,int delay);static inline void Release_PS2CLK0(void){				unsigned long flagst;		save_flags(flagst);		cli();		GPGDAT |= (1<<2);		GPGCON &= ~(0x03<<4);		GPGCON |= (0x02<<4);		restore_flags(flagst);		enable_irq(IRQ_PS2);} static inline void PULLDOWN_PS2CLK0(void){		GPGCON &= ~(0x03<<4);		GPGCON |= (0x01<<4);		GPGDAT &= ~(1<<2);		disable_irq(IRQ_PS2);} static inline void PS2_DATA_OUT(void){	GPBCON &= ~(0x03<<8); 	GPBCON |= (0x01<<8);	GPBUP  |= (0x01<<4);} static inline void ReleasePS20Data(void){	GPBCON &= ~(0x03<<8);	GPBUP  &= ~(0x01<<4);}     /*************************************************************************	功能:	参数:				返回值:-1: error			     0: OK		   			**************************************************************************/static unsigned char get_char_from_queue(void) {/* used for getting data from driver buffer*/	unsigned char ch;	ch = s3c2410fcrps2_device->buf[s3c2410fcrps2_device->tail];	s3c2410fcrps2_device->tail = (s3c2410fcrps2_device->tail + 1) & (PS2_BUF_SIZE - 1);	return ch;}/* get_char_from_queue *//*************************************************************************	功能:	参数:				返回值:-1: error			     0: OK		   			**************************************************************************/static void put_in_queue(unsigned char *in, int len) {/*used for putting data into driver buffer*/	unsigned long head = s3c2410fcrps2_device->head;	unsigned long maxhead = (s3c2410fcrps2_device->tail - len) & (PS2_BUF_SIZE - 1);	int i;	if (head != maxhead)		for (i = 0;i < len;i++)		{			s3c2410fcrps2_device->buf[head] = in[i];			head++;			head &= (PS2_BUF_SIZE - 1);		}	else		printk("the s3c2410fcrps2_device->buf is full\n");	s3c2410fcrps2_device->head = head;}/* put_in_queue *//*************************************************************************	功能:	参数:				返回值:-1: error			     0: OK		   			**************************************************************************/static int queue_empty(void) {	return s3c2410fcrps2_device->head == s3c2410fcrps2_device->tail ;}/* queue_empty*/                   /*************************************************************************	功能:delay	参数:				返回值:-1: error			     0: OK		   			**************************************************************************/static void delay(int i) //Delay for 10 CPU Cycles //OK{	for( ;i > 0; i-- )	{		asm("nop");	}}/****************************************************************************XXXXXXXXXXXXXXXX                          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX    ps/2 send & receive       XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX *****************************************************************************//*************************************************************************	功能:EXINT10 interrupt handle	参数:				返回值:lcd status			     		   			**************************************************************************/static void s3c2410_exint_isr_PS2(int irq,void *dev_id,struct pt_regs *reg){	//static unsigned char PS0revdata;	//static char count = 0,paritysum = 0;	unsigned char data, revd;	unsigned long flags;	//printk("input exint10 init!\n");	save_flags(flags);	cli();	switch(ps0status){				    case PSSTATUS_WAITREV:             //ps/2 start receive data    	 //place = 0;	     data = GETPS0Data();	     if(data == 0)	     {	     		PS0revdata = 0;	     		ps0status = PSSTATUS_REVING;	     		count = 0;	     		paritysum = 0;	     }	    break;    case PSSTATUS_REVING:    	//printk("PSSTATUS_REVING\n");    	data = GETPS0Data();    	PS0revdata >>= 1;    	if(data)revd = 1;    	else revd = 0;    	    	PS0revdata |= (revd << 7);    	count++;    	paritysum += revd;    	if(count == 8)    		ps0status = PSSTATUS_REVPARITY;    	break;    	    	    case PSSTATUS_REVPARITY:    	//printk("PSSTATUS_REVPARITY\n");    	data = GETPS0Data();    	if(data) revd = 1;    	else revd = 0;    	paritysum += revd;    	if((paritysum & 0x01) == 1)   //parity ok    	{    		ps0status = PSSTATUS_REVSTOP;    	}    	else    	{    		ps0status = PSSTATUS_WAITREV;    	}    break;             case PSSTATUS_REVSTOP:    	//printk("PSSTATUS_REVSTOP\n");    	data = GETPS0Data();    	if(data) revd = 1;    	else revd = 0;    	if(revd == 1)                      //receive stop ok    	{    		//PS2_data_buff[ps2_data_Revcnt0] = ps0revdata;    		//ps2_bUFCNT_INC(ps2_data_Revcnt0);    		//data = PS2_data_Revcnt0;    		//PS2_BUFCNT_INC(data);    		put_in_queue((unsigned char *)&PS0revdata ,1);    		new_ps2_state = 1;    		    		if (&s3c2410fcrps2_device->fasync_queue)	    	kill_fasync(&s3c2410fcrps2_device->fasync_queue,SIGIO,POLL_IN);	      wake_up_interruptible(&s3c2410fcrps2_device->proc_list);    		//if(data == ps2data_Readcnt0)    		//	PULLDOWN_PS2CLK0();    	}    	ps0status = PSSTATUS_WAITREV;    break;             case PSSTATUS_SendWTCLK:           //send of clk change    	//printk("PSSTATUS_SendWTCLK\n");    	data = (ps2_senddata0 & 0x1);    	if(data == 1)    		 PS2_DATA_SET;       else      	 PS2_DATA_CLR;      Stop_Time1();                   //stop timeout time      count = 1;      paritysum = data;      ps2_senddata0 >>= 1;      ps0status = PSSTATUS_SendDATA;      //count = 0;    break;            case PSSTATUS_SendDATA:            //send data    	//printk("PSSTATUS_SendDATA\n");    	data = (ps2_senddata0 & 0x01);    	if(data == 1)    		 PS2_DATA_SET;       else      	 PS2_DATA_CLR;      paritysum ^= data;      if(count == 7)      {      	ps0status = PSSTATUS_SendPARITY;      }	 	      count++;      ps2_senddata0 >>= 1;    break;            case PSSTATUS_SendPARITY:        //send parity    	//printk("PSSTATUS_SendPARITY\n");    	if(paritysum == 1)    			 PS2_DATA_CLR;       else      	 PS2_DATA_SET;     ps0status = PSSTATUS_SendSTOP; 	     break;        case PSSTATUS_SendSTOP:        //send Stop    	//printk("PSSTATUS_SendTOP\n");    	PS2_DATA_SET;    	ps0status = PSSTATUS_SendWTACK;    break;        case PSSTATUS_SendWTACK:       //wait dev ack    	//printk("PSSTATUS_SendWTACK\n");    	ReleasePS20Data();    	data = GETPS0Data();    	if(data == 0)    	{	    		lastps2sendstatus0 = PS2_SEND_OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -