📄 s3c2410ts.c
字号:
/* * s3c2410-ts.c * * touchScreen driver for SAMSUNG S3C2410 * * Author: Janghoon Lyu <nandy@mizi.com> * Date : $Date: 2002/06/04 07:11:00 $ * * $Revision: 1.1.2.6 $ * * Based on pt036001b-ts.c * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. * * History: * * 2002-05-27: Janghoon Lyu <nandy@mizi.com> * - Add HOOK_FOR_DRAG * - PM 内靛啊 甸绢啊 乐变 窍瘤父 抛胶飘 登瘤 臼疽澜. * */#include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/device.h>#include <linux/miscdevice.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <linux/interrupt.h>#include <linux/delay.h>#include <linux/devfs_fs_kernel.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/arch/regs-gpio.h>//#include <asm/arch/regs-adc.h>//#include "regs-adc.h"//#include "portts/S3C2440.h"//#include "portts/bitfield.h"//#include "portts/hardware.h"//#define SUBSRCPND (0x4A000018)//#define INTSUBMSK (0x4A00001C)//#define INTMSK (0x4A000008)//#define ADCTSC (0x58000004)//--------------------------------------follow add by fla#define WAIT4INT(x) (((x)<<8) | \ S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \ S3C2410_ADCTSC_XY_PST(3)) /* ADCTSC Register Bits */#define S3C2410_ADCTSC_YM_SEN (1<<7)#define S3C2410_ADCTSC_YP_SEN (1<<6)#define S3C2410_ADCTSC_XM_SEN (1<<5)#define S3C2410_ADCTSC_XP_SEN (1<<4)#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)#define S3C2410_ADCTSC_AUTO_PST (1<<2)#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)/* ADCCON Register Bits */#define S3C2410_ADCCON_ECFLG (1<<15)#define S3C2410_ADCCON_PRSCEN (1<<14)#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)#define S3C2410_ADCCON_MUXMASK (0x7<<3)#define S3C2410_ADCCON_STDBM (1<<2)#define S3C2410_ADCCON_READ_START (1<<1)#define S3C2410_ADCCON_ENABLE_START (1<<0)#define S3C2410_ADCCON_STARTMASK (0x3<<0)#ifdef S3C2410_ADCCON#undef S3C2410_ADCCON#endif#ifdef S3C2410_ADCTSC#undef S3C2410_ADCTSC#endif#ifdef S3C2410_ADCDLY#undef S3C2410_ADCDLY#endif#ifdef S3C2410_ADCDAT0#undef S3C2410_ADCDAT0#endif#ifdef S3C2410_ADCDAT1#undef S3C2410_ADCDAT1#endif#ifdef S3C2410_PA_ADC#undef S3C2410_PA_ADC#endif#define S3C2410_PA_ADC (0x58000000) static void __iomem *base_addr;#define S3C2410_ADCCON (base_addr+(0x00))#define S3C2410_ADCTSC (base_addr+(0x04))#define S3C2410_ADCDLY (base_addr+(0x08))#define S3C2410_ADCDAT0 (base_addr+(0x0c))#define S3C2410_ADCDAT1 (base_addr+(0x10))//-------------------------------------------------------------------fla#ifdef CONFIG_PM#include <linux/pm.h>#endif/* debug macros */#define DEBUG#undef DEBUG#ifdef DEBUG#define DPRINTK( x... ) printk("%s: ", __FUNCTION__, ##x)#else#define DPRINTK( x... )#endiftypedef struct { unsigned short pressure; unsigned short x; unsigned short y; unsigned short pad;} TS_RET;typedef struct { int xscale; int xtrans; int yscale; int ytrans; int xyswap;} TS_CAL;#define PEN_UP 0 #define PEN_DOWN 1#define PEN_FLEETING 2#define MAX_TS_BUF 16 /* how many do we want to buffer */#undef USE_ASYNC #define DEVICE_NAME "s3c2410-ts"#define TSRAW_MINOR 1typedef struct { unsigned int penStatus; /* PEN_UP, PEN_DOWN, PEN_SAMPLE */ TS_RET buf[MAX_TS_BUF]; /* protect against overrun */ unsigned int head, tail; /* head and tail for queued events */ wait_queue_head_t wq; spinlock_t lock;#ifdef USE_ASYNC struct fasync_struct *aq;#endif#ifdef CONFIG_PM struct pm_dev *pm_dev;#endif} TS_DEV;static TS_DEV tsdev;#define BUF_HEAD (tsdev.buf[tsdev.head])#define BUF_TAIL (tsdev.buf[tsdev.tail])#define INCBUF(x,mod) ((++(x)) & ((mod) - 1))static int tsMajor = 0;static void (*tsEvent)(void);#define HOOK_FOR_DRAG#ifdef HOOK_FOR_DRAG#define TS_TIMER_DELAY (HZ/100) /* 10 ms */static struct timer_list ts_timer;#endif/*#define wait_down_int() __raw_writel(DOWN_INT | XP_PULL_UP_EN | \ XP_AIN | XM_HIZ | YP_AIN | YM_GND | \ XP_PST(WAIT_INT_MODE), S3C2410_ADCTSC)#define wait_up_int() __raw_writel(UP_INT | XP_PULL_UP_EN | XP_AIN | XM_HIZ | \ YP_AIN | YM_GND | XP_PST(WAIT_INT_MODE), S3C2410_ADCTSC)#define mode_x_axis() __raw_writel(XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ | \ XP_PULL_UP_DIS | XP_PST(X_AXIS_MODE), S3C2410_ADCTSC)#define mode_x_axis_n() __raw_writel(XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ | \ XP_PULL_UP_DIS | XP_PST(NOP_MODE), S3C2410_ADCTSC)#define mode_y_axis() __raw_writel(XP_AIN | XM_HIZ | YP_EXTVLT | YM_GND | \ XP_PULL_UP_DIS | XP_PST(Y_AXIS_MODE), S3C2410_ADCTSC)#define start_adc_x() do {__raw_writel(PRESCALE_EN | PRSCVL(49) | \ ADC_INPUT(ADC_IN7) | ADC_START_BY_RD_EN | \ ADC_NORMAL_MODE, S3C2410_ADCCON); \ __raw_readl(S3C2410_ADCDAT0); } while(0)#define start_adc_y() do {__raw_writel(PRESCALE_EN | PRSCVL(49) | \ ADC_INPUT(ADC_IN5) | ADC_START_BY_RD_EN | \ ADC_NORMAL_MODE, S3C2410_ADCCON); \ __raw_readl(S3C2410_ADCDAT1); } while(0)#define disable_ts_adc() __raw_writel(__raw_readl(S3C2410_ADCCON)&~ADCCON_READ_START, S3C2410_ADCCON)*///-------------------------fla pick-up regs val from 2.4.18&2440#define wait_down_int() __raw_writel(0x000000d3,S3C2410_ADCTSC)#define wait_up_int() __raw_writel(0x000001d3, S3C2410_ADCTSC)#define mode_x_axis() __raw_writel(0x00000069, S3C2410_ADCTSC)#define mode_x_axis_n() __raw_writel(XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ | \ XP_PULL_UP_DIS | XP_PST(NOP_MODE), S3C2410_ADCTSC)#define mode_y_axis() __raw_writel(0x0000009a, S3C2410_ADCTSC)#define start_adc_x() do {__raw_writel(0x00007ffa, S3C2410_ADCCON); \ __raw_readl(S3C2410_ADCDAT0); } while(0)#define start_adc_y() do {__raw_writel(0x00007ffa, S3C2410_ADCCON); \ __raw_readl(S3C2410_ADCDAT1); } while(0)#define disable_ts_adc() __raw_writel(__raw_readl(S3C2410_ADCCON)&0xfffffffd, S3C2410_ADCCON)//---------------------------flastatic int adc_state = 0;static int x, y; /* touch screen coorinates */#define RT_BT_EMU_TM ((HZ>>1)+(HZ>>2)) //0.75Sstatic u16 ts_r_x[5];static u16 ts_r_y[5];static u16 ts_r_idx;static u16 ts_r_beg;static u32 dn_start;static void tsEvent_raw(void){ if (tsdev.penStatus == PEN_DOWN) { u16 i, j;#ifdef HOOK_FOR_DRAG ts_timer.expires = jiffies + TS_TIMER_DELAY; add_timer(&ts_timer);#endif ts_r_x[ts_r_idx] = x; ts_r_y[ts_r_idx] = y; ts_r_idx++; if(ts_r_idx>=5) ts_r_idx = 0; if(ts_r_beg) { ts_r_beg--; if(ts_r_beg) return; dn_start = jiffies; } for(i=4; i; i--) for(j=i; j; j--) { u16 swap_xy; if(ts_r_x[j-1]>ts_r_x[i]) { swap_xy = ts_r_x[j-1]; ts_r_x[j-1] = ts_r_x[i]; ts_r_x[i] = swap_xy; } if(ts_r_y[j-1]>ts_r_y[i]) { swap_xy = ts_r_y[j-1]; ts_r_y[j-1] = ts_r_y[i]; ts_r_y[i] = swap_xy; } } BUF_HEAD.x = x = ts_r_x[3]; BUF_HEAD.y = y = ts_r_y[3]; BUF_HEAD.pressure = ((jiffies - dn_start) >= RT_BT_EMU_TM) ? 2 : PEN_DOWN; } else {#ifdef HOOK_FOR_DRAG del_timer(&ts_timer);#endif if(ts_r_beg) return; BUF_HEAD.x = x;//0; BUF_HEAD.y = y;//0; BUF_HEAD.pressure = PEN_UP; } tsdev.head = INCBUF(tsdev.head, MAX_TS_BUF); wake_up_interruptible(&(tsdev.wq));#ifdef USE_ASYNC if (tsdev.aq) kill_fasync(&(tsdev.aq), SIGIO, POLL_IN);#endif#ifdef CONFIG_PM pm_access(tsdev.pm_dev);#endif}static int tsRead(TS_RET * ts_ret){ spin_lock_irq(&(tsdev.lock)); ts_ret->x = BUF_TAIL.x; ts_ret->y = BUF_TAIL.y; ts_ret->pressure = BUF_TAIL.pressure;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -