史上最详细的触摸屏驱动分析

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*触摸屏驱动程序及分析*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

/* For ts.dev.id.version */

#define S3C2410TSVERSION 0x0101

#define WAIT4INT(x) (((x)<<8) | \

S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \

S3C2410_ADCTSC_XY_PST(3))

#define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \

S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))

static char *s3c2410ts_name = "s3c2410 TouchScreen";

static struct input_dev *dev;

static long xp;

static long yp;

static int count;

extern struct semaphore ADC_LOCK;

static int OwnADC = 0;

static void __iomem *base_addr;

/*把GPG12~15 设置为保留模式*/

static inline void s3c2410_ts_connect(void)

{

s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);

s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);

s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);

s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);

}

/*求坐标的平均值,报告坐标,当还是按下状态时,再次调用ADC转换,如果抬起则让触摸屏设置为等待中断模式*/

static void touch_timer_fire(unsigned long data)

{

unsigned long data0;

unsigned long data1;

int updown;

/*用于读取ADCDA T数据*/

data0 = ioread32(base_addr+S3C2410_ADCDA T0);

data1 = ioread32(base_addr+S3C2410_ADCDA T1);

/*判断是按下还是送开*/

updown = (!(data0 & S3C2410_ADCDA T0_UPDOWN)) && (!(data1 & S3C2410_ADCDA T0_UPDOWN));

/*如果按下*/

if (updown) {

if (count != 0) {/*转换四次后进行事件汇报*/

long tmp;

tmp = xp;

xp = yp;

yp = tmp;

/* 求平均值*/

xp >>= 2;

yp >>= 2;

/* 报告x、y的绝对坐标值*/

input_report_abs(dev, ABS_X, xp);

input_report_abs(dev, ABS_Y, yp);

/* 报告按键事件,键值为1(代表触摸屏对应的按键被按下) */

input_report_key(dev, BTN_TOUCH, 1);

/* 报告触摸屏的状态,1表明触摸屏被按下*/

input_report_abs(dev, ABS_PRESSURE, 1);

/* 同步*/

input_sync(dev);

}

xp = 0;

yp = 0;

count = 0;

/*自动X/Y轴坐标转换模式的设置,自动地进行X轴和Y轴的转换操作,随后产生相应的INT_ADC中断通知转换完毕*/

iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);

/*如果还没有启动ADC或者ADC转换四次完毕后则启动ADC*/

iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);

} else {

count = 0;

/* 如果触摸笔是弹起状态,则提出报告,并让触摸屏处于等待触摸的阶段*/

/* 报告按键事件,键值为0(代表触摸屏对应的按键被释放) */

input_report_key(dev, BTN_TOUCH, 0);

/* 报告触摸屏的状态,0表明触摸屏未被按下*/

input_report_abs(dev, ABS_PRESSURE, 0);

/*同步*/

input_sync(dev);

/* 设置触摸屏为等待中断模式,等待触摸笔按下*/

iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);

if (OwnADC) {

OwnADC = 0;

up(&ADC_LOCK);

}

}

}

static struct timer_list touch_timer =

TIMER_INITIALIZER(touch_timer_fire, 0, 0);

/*当触摸按下时,产生INT_TC中断,会进入到stylus_updown中断处理函数

当有中断产生时,会使OwnADC=1,然后读取数据,并判断是抬起还是按下,按下则调用touch_timer_fire()函数,

抬起则释放锁,并使OwnADC=0

*/

相关文档
最新文档