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

📄 ucb1400_ts_tinyx.c~

📁 基于pxa270的touch screen的源码
💻 C~
📖 第 1 页 / 共 2 页
字号:
/*
 *  linux/drivers/misc/ucb1400_tinyx_ts.c
 *
 *  Copyright (C) 2005 Ray.Xian, All Rights Reserved. 
 *  My E-mail : mingrayxian@163.com
 *
 * 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.
 *
 * This Kernel has already provided ucb1x00 driver, but On my XSBase270
 * eva board, the device not running , so I write the driver by myself. 
 *
 */


#define EXPORT_SYMTAB


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/string.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/completion.h>

#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/semaphore.h>
#include <asm/io.h>
#include <asm/mach-types.h>

#include <linux/ac97_codec.h>


#include "ucb1400_ts.h"
#include <linux/timer.h>
#include <asm-arm/arch-pxa/xsbase270.h>

#include <asm-arm/arch-pxa/pxa-regs.h>//bruce

struct timer_list bl_timer;
int bright_time=62;

extern u16 pxa_ac97_read(struct ac97_codec *, u8);
extern void pxa_ac97_write(struct ac97_codec *, u8, u16);
extern struct ac97_codec pxa_ac97_codec;



static wait_queue_head_t ts_wait ;
static int ts_occur;
static int head, tail;
static TS_EVENT cur_data, samples[2], buf[BUFSIZE];
static struct TCH_QUEUE tch_queue;//add by bruce
static int tch_queueSumX=0;//add by bruce
static int tch_queueSumY=0;//add by bruce
static int sumM=0;//add by bruce

static struct fasync_struct * fasync;
static char if_pressure = 1;
static int copy_right = 0;
static unsigned long in_timehandle = 0;
//static struct completion kthread_completion;


DECLARE_WAIT_QUEUE_HEAD( kthread_queue);

void ucb1400_IRQ_handle( void);

/*
static void printf_ucb1400( void )
{
  printk(KERN_EMERG"%s::%s\n", __FILE__, __FUNCTION__);
  printk(KERN_EMERG"ID IS                        0x%08x\n", pxa_ac97_read(&pxa_ac97_codec, 0x7c));
  printk(KERN_EMERG"Positive INT Enable register is   0x%08x\n", pxa_ac97_read(&pxa_ac97_codec, 0x5e));
  printk(KERN_EMERG"Negative INT Enable register is  0x%08x\n", pxa_ac97_read(&pxa_ac97_codec, 0x60));
  printk(KERN_EMERG"INT Clear Status register is      0x%08x\n", pxa_ac97_read(&pxa_ac97_codec, 0x62));
  printk(KERN_EMERG"Touch Screen Control register is 0x%08x\n", pxa_ac97_read(&pxa_ac97_codec, 0x64));
  printk(KERN_EMERG"ADC Control register is         0x%08x\n", pxa_ac97_read(&pxa_ac97_codec, 0x66));
  printk(KERN_EMERG"ADC Data register is           0x%08x\n", pxa_ac97_read(&pxa_ac97_codec, 0x68));
}
*/

static void print_par(void)
{
   printk(KERN_EMERG" Kernel ==> cal_ok = %d\n",cal_ok);
   printk(KERN_EMERG" Kernel ==> raw_max_x = %d\n",raw_max_x);
   printk(KERN_EMERG" Kernel ==> raw_max_y = %d\n",raw_max_y);
   printk(KERN_EMERG" Kernel ==> res_x = %d\n",res_x);
   printk(KERN_EMERG" Kernel ==> res_y = %d\n",res_y);
   printk(KERN_EMERG" Kernel ==> raw_min_x = %d\n",raw_min_x);
   printk(KERN_EMERG" Kernel ==> raw_min_y = %d\n",raw_min_y);
   printk(KERN_EMERG" Kernel ==> xyswap = %d\n",xyswap);
   printk(KERN_EMERG" Kernel ==> x_rev = %d\n",x_rev);
   printk(KERN_EMERG" Kernel ==> y_rev = %d\n",y_rev);
}

static void ts_clear(void)
{
   int i;

   for (i=0; i < BUFSIZE; i++)
   {
       buf[i].pressure=(short)NULL;
       buf[i].x=(int)NULL;
       buf[i].y=(int)NULL;
       buf[i].millisecs=(int)NULL;
   }

   head = 0;
   tail = 0;
}

/*bruce*/
static inline void i2c_init()
{
  ICR = 0;
  CKEN |= CKEN14_I2C;
  set_GPIO_mode(GPIO117_SCL);
  set_GPIO_mode(GPIO118_SDA);
  ISAR = 0;
  ICR = (ICR_IUE | ICR_SCLE);
}

static inline void i2c_write_byte(int addr,char data)
{
  int i;
  
  IDBR = 0xa0;
  ICR |= (ICR_IUE | ICR_SCLE | ICR_START | ICR_TB);
  ICR &= ~(ICR_STOP | ICR_ALDIE);
  
  i = 0xffff;
  while(((ISR & ISR_ITE) != ISR_ITE) && i) i--;
  ISR |= ISR_ITE;
  
  IDBR = addr;
  ICR &= ~(ICR_START | ICR_STOP);
  ICR |= (ICR_ALDIE |ICR_TB);
    
  i = 0xffff;
  while(((ISR & 0x4f) != ISR_ITE) && i) i--;  
  ISR |= ISR_ITE;
  
  IDBR = data;
  ICR &= ~(ICR_START);
  ICR |= (ICR_IUE | ICR_SCLE | ICR_STOP | ICR_TB);
  
  i = 0xffff;
  while(((ISR & ISR_ITE) != ISR_ITE) && i) i--;
  ISR |= ISR_ITE;

  ICR &= ~ICR_STOP;
  mdelay(10);
  
}


static inline void i2c_write_long(int addr,long data)
{ 
  char tmp;
  tmp = (char)(data & 0x000000ff);
  //printk(KERN_EMERG "w0_7: %x\n",tmp);
  i2c_write_byte(addr*4,tmp);
  tmp = (char)((data & 0x0000ff00)>>8);
  //printk(KERN_EMERG "w8_15: %x\n",tmp);
  i2c_write_byte(addr*4+1,tmp);
  tmp = (char)((data & 0x00ff0000)>>16);
  //printk(KERN_EMERG "w16_23: %x\n",tmp);
  i2c_write_byte(addr*4+2,tmp);
  tmp = (char)((data & 0xff000000)>>24);
  //printk(KERN_EMERG "w24_31: %x\n",tmp);
  i2c_write_byte(addr*4+3,tmp);
}

static inline char i2c_read_byte(int addr)
{
  char data;
  int i;
  
  IDBR = 0xa0;
  ICR |= (ICR_IUE | ICR_SCLE | ICR_START | ICR_TB);

  i = 0xffff;
  while(((ISR & 0x4f) != (ISR_UB | ISR_ITE)) && i) i--;
  ISR |= ISR_ITE;

  IDBR = addr;
  ICR &= ~(ICR_START | ICR_STOP);
  ICR |= ICR_ALDIE | ICR_TB;
  
  i = 0xffff;
  while(((ISR & 0x4f) != (ISR_UB | ISR_ITE)) && i) i--;
  ISR |= ISR_ITE;

  IDBR = 0xa1;
  ICR |= ICR_START |ICR_TB;

  i = 0xffff;
  while(((ISR & 0x4f) != (ISR_UB | ISR_ITE | ISR_RWM)) && i) i--;
  ISR |= ISR_ITE;

  ICR &= ~ICR_START;
  ICR |= (ICR_ALDIE | ICR_TB | ICR_ACKNAK | ICR_STOP);

  i = 0xffff;
  while(((ISR & 0x8e) != (ISR_IRF | ISR_ACKNAK)) && i) i--;
  ISR |= ISR_IRF;

  data = (char)IDBR;
  ICR &= ~(ICR_SCLE | ICR_IUE);
  return data;
  
}

static inline long i2c_read_long(int addr)
{
  long tmp = 0x00000000;
  long data = 0x00000000;
  tmp = (long)i2c_read_byte(addr*4);
  //printk(KERN_EMERG "data0_7: %x\n",tmp);
  data |= tmp;
  tmp = (long)i2c_read_byte(addr*4+1);
  //printk(KERN_EMERG "data8_15: %x\n",tmp);
  data |= (tmp<<8);
  tmp = (long)i2c_read_byte(addr*4+2);
  //printk(KERN_EMERG "data16_23: %x\n",tmp);
  data |= (tmp<<16);
  tmp = (long)i2c_read_byte(addr*4+3);
  //printk(KERN_EMERG "data24_31: %x\n",tmp);
  data |= (tmp<<24);
  return data;  
}


//static int ucb1400_ts_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)//mask by bruce
static int ucb1400_ts_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, long arg)
{
   int i;
   switch (cmd)
   {
      case 3:
	 raw_max_x = arg;
	 break;
      case 4:
	 raw_max_y = arg;
	 break;
      case 5:
	 res_x = arg;
	 break;
      case 6:
	 res_y = arg;
	 break;
      case 10:
	 raw_min_x = arg;
	 break;
      case 11:
	 raw_min_y = arg;
	 break;
      case 12:
/* New attribute for portrait modes */
	 xyswap = arg;
/* Allen Add */
      case 13:	       /* 0 = Enable calibration ; 1 = Calibration OK */
	 cal_ok = arg;
      case 14:	       /* Clear all buffer data */
	 ts_clear();
	 break;
      case 15:	       /* X axis reversed setting */
	 x_rev = arg;
	 break;
      case 16:	       /* Y axis reversed setting */
	 y_rev = arg;
	 break;
      case 17:	       /* Clear all buffer data */
	 print_par();
	 break;
      case 19:
	 xConDif=0;//add by bruce
	 x2xScaDif=0;//add by bruce
	 y2xScaDif=0;//add by bruce
	 yConDif=0;//add by bruce
	 y2yScaDif=0;//add by bruce
	 x2yScaDif=0;//add by bruce
	 mulNum=1;//add by bruce
	 break;
      case 20:          //add by bruce for calibrate
         xConDif=arg;
	 //printk(KERN_EMERG "xConDif_s: %d\n",xConDif);
         break;
      case 21:
         x2xScaDif=arg;
	 //printk(KERN_EMERG "x2xScaDif_s: %d\n",x2xScaDif);
         break;
      case 22:
         y2xScaDif=arg;
	 //printk(KERN_EMERG "y2xScaDif_s: %d\n",y2xScaDif);
         break;
      case 23:
         yConDif=arg;
	 //printk(KERN_EMERG "yConDif_s: %d\n",yConDif);
         break;
      case 24:
         y2yScaDif=arg;
	 //printk(KERN_EMERG "y2yScaDif_s: %d\n",y2yScaDif);
         break;
      case 25:
         x2yScaDif=arg;
	 //printk(KERN_EMERG "x2yScaDif_s: %d\n",x2yScaDif);
         break;
      case 26:
	 //bruce 
	 mulNum=arg;
	 //printk(KERN_EMERG "mulNum_s: %d\n",mulNum);
         break;
      case 27: 
	 i2c_init();
	 i2c_write_long(0,xConDif);
	 i2c_write_long(1,x2xScaDif);
	 i2c_write_long(2,y2xScaDif);
	 i2c_write_long(3,yConDif);
	 i2c_write_long(4,y2yScaDif);
	 i2c_write_long(5,x2yScaDif);
	 i2c_write_long(6,mulNum);
	 
	 if(xConDif != i2c_read_long(0)){
	   goto error;
	 }
	 //printk(KERN_EMERG "xConDif_e: %d\n",tmp);
	 if(x2xScaDif != i2c_read_long(1)){
	   goto error;
	 }
	 //printk(KERN_EMERG "x2xScaDif_e: %d\n",tmp);
	 if(y2xScaDif != i2c_read_long(2)){
	   goto error;
	 }
	 //printk(KERN_EMERG "y2xScaDif_e: %d\n",tmp);
	 if(yConDif != i2c_read_long(3)){
	   goto error;
	 }
	 //printk(KERN_EMERG "yConDif_e: %d\n",tmp);
	 if(y2yScaDif != i2c_read_long(4)){
	   goto error;
	 }
	 //printk(KERN_EMERG "y2yScaDif_e: %d\n",tmp);
	 if(x2yScaDif != i2c_read_long(5)){
	   goto error;
	 }
	 //printk(KERN_EMERG "x2yScaDif_e: %d\n",tmp);
	 if(mulNum != i2c_read_long(6)){
	   goto error;
	 }
	 //printk(KERN_EMERG "mulNum_e: %d\n",tmp);
	 break;
/* Allen */
   }
   return 0;

 error: 
   for(i=0;i<6;i++){ 
     i2c_write_long(i,0);
   }
   i2c_write_long(6,1);
   return 1;
}


static void ucb1400_enable_irq(void )
{
  pxa_ac97_write(&pxa_ac97_codec, 0x64, PXP | MXP | PYG | MYG  );
  pxa_ac97_write(&pxa_ac97_codec, 0x60, 0x2000);
}


static void restore_interrupt(void)
{
 pxa_ac97_write(&pxa_ac97_codec, 0x62, 0x2000);
 pxa_ac97_write(&pxa_ac97_codec, 0x64, PXP | MXP | PYG | MYG | TM_INTERRUPT);
 pxa_ac97_write(&pxa_ac97_codec, 0x60, 0x2000);
}



static void timer_handle(void )
{ unsigned short ts_ctr;
  in_timehandle--; 

  ts_ctr = pxa_ac97_read( &pxa_ac97_codec, 0x64 );

  if ((ts_ctr & MX) || (ts_ctr & PX))
  {
     
    cur_data.pressure = 0;
    if_pressure = 0;

  }

  else
  {
    cur_data.pressure = 1;
  }

  ts_occur = 1;
  if(fasync)
      kill_fasync(&fasync, SIGIO, POLL_IN);  
  wake_up_interruptible(&ts_wait);
}


/* Kernel thread */
/*
static int ucb1400_thread(void  * data)
{
  struct task_struct *tsk = current;
  DECLARE_WAITQUEUE(kwait, tsk);


  daemonize();
  reparent_to_init();
  tsk->tty = NULL;
  tsk->policy = SCHED_FIFO; 
  tsk->rt_priority = 1;
  strcpy(tsk->comm, "kUCB1400_TS");

  printk(KERN_EMERG"oh,  my thread\n");

  add_wait_queue(&kthread_queue, &kwait );
  set_task_state(tsk, TASK_INTERRUPTIBLE);

  complete(&kthread_completion);

  for(;;)
   {
    
    schedule( );


  //   timer_handle( );
     printk(KERN_EMERG"OH, My kernel thread\n");
   
     set_task_state(tsk, TASK_INTERRUPTIBLE );
  
   }

}
*/

static void new_data(void)
{
   static TS_EVENT last_data = { 0, 0, 0, 0 };
   static TS_EVENT temp_data[2];
   int diff0;
  
   if (cur_data.pressure)
   {
		diff0 = abs(samples[0].x - samples[1].x);
		if (diff0 > XLIMIT) return;
		temp_data[0].x = (samples[0].x + samples[1].x) / 2;

		diff0 = abs(samples[0].y - samples[1].y);
		if (diff0 > YLIMIT) return;
		temp_data[0].y = (samples[0].y + samples[1].y) / 2;

	  if(!last_data.x && !last_data.y)
      {
	  last_data = temp_data[0];
	  temp_data[1] = temp_data[0];
          copy_right = 0;

	  return;
      }

      cur_data.x = last_data.x;
      cur_data.y = last_data.y;
      last_data = temp_data[1];
      temp_data[1] = temp_data[0];

   }
   else
   {
/* Reset jitter detection on pen release */
      last_data.x = 0;
      last_data.y = 0;
   }

   cur_data.millisecs = jiffies;

   if (head != tail)
   {
      int last = head--;
      if (last < 0)
	 last = BUFSIZE - 1;  

⌨️ 快捷键说明

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