微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440上touchscreen触摸屏驱动

S3C2440上touchscreen触摸屏驱动

时间:11-20 来源:互联网 点击:

if(adc_base == NULL)

{

printk(KERN_ERR "failed to remap register block/n");

ret = -EINVAL;

goto err_noclk;

}

adc_initialize();

ret = request_irq(IRQ_ADC, adc_irq, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DEVICE_NAME, 1);

if(ret)

{

printk(KERN_ERR "IRQ%d error %d/n", IRQ_ADC, ret);

ret = -EINVAL;

goto err_nomap;

}

ret = request_irq(IRQ_TC, tc_irq, IRQF_SAMPLE_RANDOM, DEVICE_NAME, 1);

if(ret)

{

printk(KERN_ERR "IRQ%d error %d/n", IRQ_TC, ret);

ret = -EINVAL;

goto err_noirq;

}

ts_dev = input_allocate_device();

ts_dev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);

ts_dev->keybit[BITS_TO_LONGS(BTN_TOUCH)] = BIT(BTN_TOUCH);

input_set_abs_params(ts_dev, ABS_X, 0, 0x3FF, 0, 0);

input_set_abs_params(ts_dev, ABS_Y, 0, 0x3FF, 0, 0);

input_set_abs_params(ts_dev, ABS_PRESSURE, 0, 1, 0, 0);

ts_dev->name = DEVICE_NAME;

ts_dev->id.bustype = BUS_RS232;

ts_dev->id.vendor = 0xDEAD;

ts_dev->id.product = 0xBEEF;

ts_dev->id.version = 0x0101;

input_register_device(ts_dev);

return 0;

err_noclk:

clk_disable(adc_clk);

clk_put(adc_clk);

err_nomap:

iounmap(adc_base);

err_noirq:

free_irq(IRQ_ADC, 1);

return ret;

}

static void adc_initialize(void)

{

writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF), adc_base + S3C2410_ADCCON);

writel(0xffff, adc_base + S3C2410_ADCDLY);

writel(WAIT4INT(0), adc_base + S3C2410_ADCTSC);

}

static void __exit ts_exit(void)

{

disable_irq(IRQ_ADC);

disable_irq(IRQ_TC);

free_irq(IRQ_ADC, 1);

free_irq(IRQ_TC, 1);

iounmap(adc_base);

if(adc_clk)

{

clk_disable(adc_clk);

clk_put(adc_clk);

adc_clk = NULL;

}

input_unregister_device(ts_dev);

}

module_init(ts_init);

module_exit(ts_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Huang Gang");

MODULE_DESCRIPTION("My2440 Touch Screen Driver");

3、接下来要做的是,在两个中断服务程序中实现触摸屏状态和坐标的转换。先看代码,如下:

view plainprint?

extern struct semaphore ADC_LOCK;

static int OwnADC = 0;

static long xp;

static long yp;

static int count;

#define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | /

S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))

static irqreturn_t tc_irq(int irq, void *dev_id)

{

unsigned long data0;

unsigned long data1;

int updown;

if (down_trylock(&ADC_LOCK) == 0)

{

OwnADC = 1;

data0 = readl(adc_base + S3C2410_ADCDAT0);

data1 = readl(adc_base + S3C2410_ADCDAT1);

updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));

if (updown)

{

touch_timer_fire(0);

}

else

{

OwnADC = 0;

up(&ADC_LOCK);

}

}

return IRQ_HANDLED;

}

static void touch_timer_fire(unsigned long data)

{

unsigned long data0;

unsigned long data1;

int updown;

data0 = readl(adc_base + S3C2410_ADCDAT0);

data1 = readl(adc_base + S3C2410_ADCDAT1);

updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));

if (updown)

{

if (count != 0)

{

long tmp;

tmp = xp;

xp = yp;

yp = tmp;

xp >>= 2;

yp >>= 2;

#ifdef CONFIG_TOUCHSCREEN_MY2440_DEBUG

struct timeval tv;

do_gettimeofday(&tv);

printk(KERN_DEBUG "T: d, X: ld, Y: ld/n", (int)tv.tv_usec, xp, yp);

#endif

input_report_abs(ts_dev, ABS_X, xp);

input_report_abs(ts_dev, ABS_Y, yp);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top