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

📄 hi_touchscreen.c

📁 嵌入式linux系统下hi3510平台的osd开发源码
💻 C
字号:
/*  * extdrv/peripheral/touchscreenpad/touchscreenpad_iptv.c * * Copyright (c) 2006 Hisilicon Co., Ltd.  * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA * *  * History:  *      10-April-2006 create this file *		27-06-2006 modified by y36721 */#include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/string.h>#include <linux/poll.h>#include <linux/interrupt.h>#include <linux/timer.h>#include <linux/miscdevice.h>#include <asm/hardware.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <asm/io.h>#include "hi_gpio.h"#include "hi_touchScreen.h"static int open_cnt = 0;unsigned short  u16XPosition;unsigned short  u16YPosition;int 		   begain=0,end=0,difference = 0;unsigned int ts_rx_buf[BUFSIZE];int ts_rx_head=-1;int ts_rx_tail=-1;int ready=0;int watch_dog=0;static struct   	timer_list delay_timer;	static struct   	timer_list cycle_timer;	#define DELAY(x) time_delay_us(x)static unsigned short gpio_send_command(unsigned char);static inline void time_delay_us(unsigned int );static unsigned short touchscreen_ready(void);static unsigned short touchscreen_readx(void);static  DECLARE_WAIT_QUEUE_HEAD(touchscreen_wait);/*  *	initialize gpio configure */static void gpio_init(void){    	/* set gpio_0 dir: in 5,6, 2 ;out 1,3,4*/      gpio_dirsetbit(SPICLK_G , SPICLK_B ,DIRECTION_OUTPUT);    	      gpio_dirsetbit(SPICSN_G , SPICSN_B ,DIRECTION_OUTPUT);      	      gpio_dirsetbit(SPIDI_G , SPIDI_B ,DIRECTION_OUTPUT);        gpio_dirsetbit(SPIIRQ_G , SPIIRQ_B ,DIRECTION_INPUT);            gpio_dirsetbit(SPIBUSY_G , SPIBUSY_B ,DIRECTION_INPUT);              gpio_dirsetbit(SPIDO_G , SPIDO_B ,DIRECTION_INPUT);     	      /* disable gpio_0_5 interrupt */       gpio_interruptdisable (SPIIRQ_G ,SPIIRQ_B);      	/* set gpio_0 interrupt mode */    	gpio_interruptset(                      		SPIIRQ_G,                       		SPIIRQ_B,                       		SENSE_SINGLE,                       		SENSE_EDGE,                       		EVENT_FALLING_EDGE                        );    	/* clear the int_flags of gpio_0_7 */    	gpio_interruptclear(SPIIRQ_G, SPIIRQ_B);      gpio_interruptenable(SPIIRQ_G, SPIIRQ_B);   	    	     	        /*enable CS*/      gpio_writebit(SPICLK_G,SPICLK_B,0);        gpio_writebit(SPIDI_G,SPIDI_B,0);            gpio_writebit(SPICSN_G,SPICSN_B,0);    }static inline void time_delay_us(unsigned int d200nsec){	int i,j;		for(i=0;i<d200nsec ;i++)	{     for(j=0;j<10;j++)     {     }	}}static unsigned short gpio_send_command(unsigned char command){	 unsigned short tmp;	 static char map[8];	 int i; 	 static unsigned short map_r[16];	 	 	 for(i=0;i<8;i++)	 {	 	 tmp = command;	 	 tmp = (tmp >> (7-i)) & 0x01;	 	 map[i] = tmp;	 }	 	 /*CLK low*/	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[0]); 	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);     gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[1]); 	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);     gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[2]); 	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);     gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[3]); 	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);           gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[4]);	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);           gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[5]); 	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);            gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[6]); 	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);                      gpio_writebit(SPICLK_G,SPICLK_B,0);	     /*send data*/     gpio_writebit(SPIDI_G,SPIDI_B,map[7]); 	     /*delay min 100ns*/      DELAY(1);        	 	 /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);	          /*delay min 10ns*/     DELAY(1);        	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);       /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);                 /*delay min 10ns*/     DELAY(1);        	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);         /*CLK high*/     gpio_writebit(SPICLK_G,SPICLK_B,1);     map_r[0]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                        gpio_writebit(SPICLK_G,SPICLK_B,1);     map_r[1]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);             gpio_writebit(SPICLK_G,SPICLK_B,1);      map_r[2]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                  gpio_writebit(SPICLK_G,SPICLK_B,1);     map_r[3]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                            gpio_writebit(SPICLK_G,SPICLK_B,1);     map_r[4]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                  gpio_writebit(SPICLK_G,SPICLK_B,1);       map_r[5]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                 gpio_writebit(SPICLK_G,SPICLK_B,1);      map_r[6]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                gpio_writebit(SPICLK_G,SPICLK_B,1);      map_r[7]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                  gpio_writebit(SPICLK_G,SPICLK_B,1);     map_r[8]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                  gpio_writebit(SPICLK_G,SPICLK_B,1);     map_r[9]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);               gpio_writebit(SPICLK_G,SPICLK_B,1);      map_r[10]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));      DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);                         gpio_writebit(SPICLK_G,SPICLK_B,1);      map_r[11]=*((volatile unsigned char *)IO_ADDRESS(SPIDO));     DELAY(1); 	 	 /*CLK low*/     gpio_writebit(SPICLK_G,SPICLK_B,0);     /*delay min 100ns*/      DELAY(1);               tmp = 0;	 for(i=0;i<12;i++)	 {	 	 tmp = tmp | (map_r[i]<<(11-i));		 }      return(tmp);  }static unsigned short touchscreen_readx(void){ 	/* Make sure write buffer is free. */  	unsigned char command;  	   	unsigned short data=0;  	/* Write out the control data. */  	command = 0xD0;    data = gpio_send_command(command);       	return(data);}static unsigned short touchscreen_ready(void){  	/* Make sure write buffer is free. */  	unsigned char command;  	   	unsigned short data = 0;  	/* Write out the control data. */  	command = 0x90;    data = gpio_send_command(command);   	return(data);}/* *	interrupt handle and start time_list *      Do not to modify the input parameter! */static irqreturn_t hi_touchscreen_irq(int irq, void *dev_id, struct pt_regs *reg){    	int handled = 0;    	unsigned char tmp;    	    	begain = jiffies;        tmp=*((volatile unsigned char *)IO_ADDRESS(SPIIRQ_RIS));     	  	      tmp = tmp & (1<<SPIIRQ_B);      if(tmp)      {	      gpio_interruptdisable (SPIIRQ_G ,SPIIRQ_B);  		    	delay_timer.expires = jiffies + margin;	    	add_timer (&delay_timer);      }    	handled = 1;    	return IRQ_RETVAL(handled);}static int get_position(unsigned long data){	  		u16XPosition = touchscreen_readx();  	u16YPosition = touchscreen_ready();		ts_rx_buf[ts_rx_head]=u16XPosition;				ts_rx_head++;		ts_rx_buf[ts_rx_head]=u16YPosition;		ts_rx_head++;		if(ts_rx_head>=BUFSIZE)		{			ts_rx_head = 0;		}		cycle_timer.expires = jiffies + 2*margin;		add_timer(&cycle_timer);		ready = 1;		wake_up_interruptible(&touchscreen_wait);  			return 0;	}	static int read_position(void){		unsigned int up;   			  gpio_readbit(SPIIRQ_G,SPIIRQ_B,&up); 	  if(!up)	  {		  u16XPosition = touchscreen_readx();	    u16YPosition = touchscreen_ready();			ts_rx_buf[ts_rx_head]=u16XPosition;			ts_rx_head++;			ts_rx_buf[ts_rx_head]=u16YPosition;			ts_rx_head++;			if(ts_rx_head>=BUFSIZE)			{				ts_rx_head = 0 ;			}			ready = 1;			wake_up_interruptible(&touchscreen_wait);   			  cycle_timer.expires = jiffies + 2*margin;			add_timer(&cycle_timer);	  }	  else	  {      gpio_interruptclear(SPIIRQ_G, SPIIRQ_B);      gpio_interruptenable(SPIIRQ_G, SPIIRQ_B); 	  		  }	  return 0;}		static int hi_touchscreen_open(struct inode *inode ,struct file *file){	 int ret;	 	 if(!open_cnt)	 	{    	gpio_init();    	      ret = request_irq(Irq_0, &hi_touchscreen_irq, 0, TOUCHSCREEN_DEVICE_NAME, NULL);     	if(ret<0)    	{    		    		printk(TOUCHSCREEN_DEVICE_NAME " can't request irq(%d)\n",Irq_0);    		return ret;    	}     	  	    	ts_rx_head = 0;    	ts_rx_tail = 0;    	ready = 0;    	watch_dog = 0;    	    }    open_cnt++;    return 0;}static int hi_touchscreen_close(struct inode *inode ,struct file *file){	open_cnt--;	return 0;}/* *	read touchscreen_value buf.  */static int hi_touchscreen_read(struct file * file, char * buffer, size_t count, loff_t *ppos) {     	int *user_buf = (int *)buffer;retry:    	if (ready)    	{        	copy_to_user(user_buf, (int *)(&ts_rx_buf[ts_rx_tail]), sizeof(int));        	if(++ts_rx_tail>=BUFSIZE)        		 ts_rx_tail =0;        		        	count = sizeof(char);        	if(ts_rx_tail == ts_rx_head)        		ready = 0;        	return count;        	    	}    	else    	{        	if((file->f_flags & O_NONBLOCK) == O_NONBLOCK)        		return -EAGAIN;        	interruptible_sleep_on(&touchscreen_wait);        	goto retry;    	}}		 static struct file_operations hi_touchscreen_fops ={     	owner:    THIS_MODULE,     	open :    hi_touchscreen_open,    	release:  hi_touchscreen_close,    	read:     hi_touchscreen_read,}; static struct miscdevice hi_touchscreen_miscdev ={	.minor		= MISC_DYNAMIC_MINOR,	.name		= TOUCHSCREEN_DEVICE_NAME,	.fops		= &hi_touchscreen_fops,};   static int __init hi_touchscreen_init(void){ 	  int ret;    ret = misc_register(&hi_touchscreen_miscdev);    if (ret < 0)     {        	printk(TOUCHSCREEN_DEVICE_NAME "can't register!\n");        	return ret;     }            gpio_remap();    gpio_init();           	init_waitqueue_head(&touchscreen_wait);  	init_timer(&delay_timer);  	init_timer(&cycle_timer);  	delay_timer.function = (void *)get_position;  	cycle_timer.function = (void *)read_position;  	  	printk("Hi35**  Touchscreen Device Driver v1.0\n");  	  	  	return 0;} static void __exit hi_touchscreen_exit(void) {           del_timer(&delay_timer);      del_timer(&cycle_timer);	    	free_irq(Irq_0,NULL);	    misc_deregister(&hi_touchscreen_miscdev);	    gpio_unmap();}module_init(hi_touchscreen_init);module_exit(hi_touchscreen_exit);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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