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

📄 linux下的触摸屏驱动源码.txt

📁 linux下的触摸屏驱动源码适合用在4线制触摸屏
💻 TXT
字号:
*
***************************************
* linux/driver/touch/touchscreen.c
* touchscreen driver for my S3C44b0X board
* copyright by kom118@163.com
***************************************
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/wait.h>  /*等待队列*/
#include <linux/queue.h> /*任务队列*/
#include <asm/uaccess.h>
#include <asm/arch-S3C44B0X/s3c44b0x.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch-S3C44B0X/irqs.h>
#define  TOUCH_MAJOR    10
#define  TOUCH_DEVNAME   "touchscreen_kmf"
#define  TS_IRQ   S3C44B0X_INTERRUPT_EINT3
//#define  MAX_TS_BUF   16  //校准用
/*第一次轮询时间*/
static int   FirstPollDelay=2; 
static int   PollDelay = 10; 
static int   touch_initialized;  
static int   touch_users = 0;  /* number of connected users; only one is allowed */
static int    touch_event=0; /* is there an event pending? */
/*该值校正用*/
static int   xres = 640;
static int   yres = 240;
// A/D 通道选择命令字和工作寄存器
#define CHX  0x90  //通道Y+的选择控制字 //0x94
#define CHY  0xD0 //通道X+的选择控制字 //0xD4
#define TP_DCLK(a)         outw((inw(S3C44B0X_PDATF) &(~(1<<8)) ) | ((a&1)<<8),S3C44B0X_PDATF)   //----GPF8  
#define TP_CS(a)       outw((inw(S3C44B0X_PDATF) &(~(1<<7)) ) | ((a&1)<<7),S3C44B0X_PDATF)   //-----GPF7
#define TP_DIN(a)           outw((inw(S3C44B0X_PDATF) &(~(1<<6)) ) | ((a&1)<<6),S3C44B0X_PDATF)   //------GPF6

//读ADS7843的IO控制口
//#define TP_BUSY 
#define TP_DOUT        ((inw(S3C44B0X_PDATF)>>5) & 0x1)        //-------GPF5
#define TP_IRQ  ((inb(S3C44B0X_PDATG)>>3) & 0x1)        //TP_IRQ--------ExINT3(GPG3)

/*打算在中断中使用定时器队列,定义定时器链表*/
static struct timer_list  touch_timer;  /* be used for polling */
//struct wait_queue *wq = NULL; /* global variable */ 
DECLARE_WAIT_QUEUE_HEAD(touch_wait); /*等同于 struct wait_queue *touch_wait= NULL*/

static  struct TS_RET
{
   unsigned short pressure;//!< zero -> not pressed, all other values indicate that the touch is pressed
  unsigned short x; //The x position
   unsigned short y;//The y position
 
}touchstat={0,0,0}; 

static void ads7843_Start( void )
{
     TP_DCLK(0);
 TP_CS(1);
 TP_DIN(1);
     TP_DCLK(1);
     TP_CS(0);         //芯片允许
}
static void ads7843_Write ( unsigned char  cmd )
{
 unsigned char  buf, i, j ;
       TP_DCLK(0);
 for( i = 0; i < 8; i++ )
 {
  buf = (cmd >> (7-i)) & 0x1 ; //MSB在前,LSB在后
  TP_DIN(buf);   //时钟上升沿锁存DIN
  
  for( j = 0; j < 25; j++ ); //200ns
  TP_DCLK(1);    //开始发送命令字
  
  for( j = 0; j < 25; j++ ); //200ns
  TP_DCLK(0);   //时钟脉冲,一共8个
 }
}
static unsigned short  ads7843_Read ( void )
{
 unsigned short buf = 0 ;
 unsigned char i, j ;
 
 for( i = 0; i < 12; i++ )
 {
  buf = buf << 1 ;
  
  TP_DCLK(1);
  for( j = 0; j < 25; j++ );  //200ns
  TP_DCLK(0);   
  for( j = 0; j < 5; j++ ); //时钟下降沿读取,一共12个,MSB在前,LSB在后
  if ( TP_DOUT )  buf = buf + 1 ;
  for( j = 0; j < 20; j++ );  //200ns
 }
/* 
 for( i = 0; i < 4; i++ )
 {
  TP_DCLK(1);
  for( j = 0; j < 25; j++ );  //200ns
  TP_DCLK(0);   
  for( j = 0; j < 25; j++ ); //4个没用时钟
 } 
*/
 return( buf ) ;
}

static  void  ads7843_port_init(void)
{
       /*配置与ADS7843 相连的I/O端口 output : PF5,PG3;      input:PF6,PF7,PF8   ; ads7843  busy  线没用*/
 unsigned int val32;
 unsigned short  val16;
      /*配置F  端口*/
 /*-------------------------*/
 /* configuration of PCONF  */
 /*-------------------------*/
 val32=inl(S3C44B0X_PCONF);
 outl((val32&&0xFFC003FF)|0xFFC923FF, S3C44B0X_PCONF);  /* config GPF5 input  ; GPF6  GPF7  GPE8 output */
 
 /*-------------------------*/
 /* configuration of PUPF */
 /*-------------------------*/
 val16 =inb(S3C44B0X_PUPF);
 outw((val16&0xFFDF), S3C44B0X_PUPF); /* config GPF5 activate pull up   GPF5 上拉电阻使能*/
}
static void ads7843_get_XY(void)
{
 unsigned short j ;
 
 ads7843_Start() ;
 for( j = 0; j < 5; j++ );  //40ns
 //while ( TP_BUSY ) ;  //如果BUSY,等待直到转换完毕,这个可以不用
 
 ads7843_Write( CHX ) ;
 
 for( j = 0; j < 25; j++ );  //200ns
       touchstat.x= ads7843_Read() ;
 
 ads7843_Write( CHY ) ;
 
 for( j = 0; j < 25; j++ );  //200ns
 touchstat.y = ads7843_Read() ;
 
}
void touch_poll_task (unsigned long irq)   /*中断程序下半部*/
{    
      /*配置PCNOG 将GPG3设为输入模式,供轮询*/
 outw(inw(S3C44B0X_PCONG)&0xFF3F, S3C44B0X_PCONG); 
   
 /*读入GPG3脚(触摸屏当前)状态*/
 touchstat.pressure=TP_IRQ;
  
      /*获取X , Y 坐标*/
       ads7843_get_XY();
   
 
   
       /*触摸屏仍然被按下, 继续轮询*/
       if(touchstat.pressure==1)
       {
         init_timer(&touch_timer);
  touch_timer.function = touch_poll_task;
  touch_timer.data = irq;
  touch_timer.expires = PollDelay;
  add_timer(&touch_timer);
       }
 else 
 {
       /*-------------------------*/
  /* enable irq                 */
  /*-------------------------*/
  touchstat.pressure=0;   
  touch_event=1;
  outw( inw(S3C44B0X_PCONG)|0xC0, S3C44B0X_PCONG); /*重新配置PCNOG 将GPG3设为中断模式*/
       enable_irq(irq);
  return;
 }
 
      wake_up_interruptible(&touch_wait);   /* wake any reading process */ 
} 
static void touch_interrupt(int irq, void *dev_id, struct pt_regs *regs)  /*中断程序上半部*/
{
 /*-------------------------*/
 /* disable irq                 */
 /*-------------------------*/
 disable_irq(irq);
 
 touchstat.pressure=1;  /*表示按下状态*/
 
 /*-------------------------*/
 /* setup kernel timer                 */
 /*-------------------------*/
 init_timer(&touch_timer);
 touch_timer.function = touch_poll_task;
 touch_timer.data = irq;
 touch_timer.expires = FirstPollDelay;
 add_timer(&touch_timer);
 
        /*--------------------------*/
 /* return from interrupt               */
 /*--------------------------*/
 return;
}
static ssize_t touchscreen_read(struct file *file, char *buffer,
     size_t count, loff_t *pos)
{    
      int count=2;
      unsigned short   XYret[2];
   
      while (!touch_event) 
 { 
         interruptible_sleep_on( &touch_wait); 
 } 
   
   XYret[0]=touchstat.x;
   XYret[1]=touchstat.y;
 if(copy_to_user(buffer, XYret, count))
  return -EFAULT;
 
  touch_event = 0;
        return count; 
   
}
static unsigned int touchscreen_poll(struct file *file, poll_table *wait)
{
 poll_wait(file, &touch_wait, wait);
 if(touch_event)
  return (POLLIN | POLLRDNORM);  /* readable */
 return 0;
}
static int touchscreen_open(struct inode *inode, struct file *file) 
{
 if(!touch_users) /* only one user is allowed!! */
  touch_users++;
 else
  return -EBUSY;
 enable_irq(TS_IRQ);
 return 0;
}

static int touchscreen_close(struct inode * inode, struct file * file) 
{
       touch_users--;
 if(!touch_users) /* must be also true since we allow only one user */
  disable_irq(TS_IRQ);
 return 0;
}
struct file_operations  ts_fops = {
 read: touchscreen_read,  
 poll: touchscreen_poll,   //查询设备
 open: touchscreen_open,
 release: touchscreen_close, //释放设备
};

int s3c44b0x_ts_init(void)
{     
 int result;
 unsigned int val32;
       unsigned short val16;
   
 printk("s3c44b0x_touch: initializing...\n");
 touch_initialized = 0;
 
 TP_CS(1);/*ads7843芯片禁止*/
 
 ads7843_port_init();
 
       /*-------------------------------*/
 /* configure interrupt              */
 /*-------------------------------*/
 val32=inl(S3C44B0X_INTMOD);
 outl((val32&0xFBFFFFF), S3C44B0X_INTMOD);           /* normal IRQ */
 
 val32=inl(S3C44B0X_EXTINT);
 outl((val32&0xFFFF8FFF)|0x2000, S3C44B0X_EXTINT);   /*falling edge  下降沿触发*/
 
 val16 =inw(S3C44B0X_PCONG);
 outw(val16 | 0xC0, S3C44B0X_PCONG);       /* use Port G pin 3 as ext int 3 */
 
     ads7843_Start();            //   ADS7843 芯片允许
 
 if((result = register_chrdev(TOUCH_MAJOR,TOUCH_DEVNAME ,&ts_fops))<0)
 {
  printk("touch_rw. unable to get major %d for led write\n", TOUCH_MAJOR);
  return result;
 }
 
   if(request_irq(TS_IRQ, touch_interrupt, 0, "44b0_touchscreen",NULL))
 {
  printk("s3c44b0: unable to get IRQ\n");
  return -EBUSY;
 }
 
  touch_initialized ++;
 
 return 0;
}

int  s3c44b0x_ts_exit(void)
{
 int result;
 
 if (touch_initialized >= 1)
 {
  if((result = unregister_chrdev(TOUCH_MAJOR,TOUCH_DEVNAME ))<0)
  printk("TOUCH DEV. unable to release major %d for read  \n",TOUCH_MAJOR);
  return result;
 }
 
 free_irq(TS_IRQ, NULL);
 
 printk(KERN_INFO "touchscreen uninstalled\n");
 
 touch_initialized --;
 return 0;
}

⌨️ 快捷键说明

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