📄 demo.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. * * Copyright (C) 2007, 2010 fengGuojin(fgjnew@163.com) */#include <linux/module.h>#include <linux/init.h>#include <linux/input.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/arch-s3c2410/irqs.h>#include <asm/signal.h>#include <asm/hardware.h>#include <asm/uaccess.h>#include <asm/arch/regs-gpio.h>#include <asm/arch/regs-adc.h>#include <asm/dma.h>MODULE_AUTHOR("FGJ");MODULE_DESCRIPTION("s3c2410 ts driver");MODULE_LICENSE("GPL");#define SIMPLE_TIMER_DELAY (HZ/100)//1Second==HZstatic struct timer_list simple_timer;#define S3C2410_ADCTSC_XY_PST_N (0x0<<0)#define S3C2410_ADCTSC_XY_PST_X (0x1<<0)#define S3C2410_ADCTSC_XY_PST_Y (0x2<<0)#define S3C2410_ADCTSC_XY_PST_W (0x3<<0)#define S3C2410_ADCTSC_YM_SEN (0x1<<7)#define S3C2410_ADCTSC_YP_SEN (0x1<<6)#define S3C2410_ADCTSC_XM_SEN (0x1<<4)#define S3C2410_ADCTSC_XP_SEN (0x1<<4)#define S3C2410_ADCTSC_AUTO_PST (0x1<<2)#define S3C2410_ADCCON_ENABLE_START 0x01#define S3C2410_ADCTSC_PULL_UP_DISABLE (0x1<<3)#define S3C2410_ADCDAT0_XPDATA_MASK 0x3FF#define S3C2410_ADCDAT1_YPDATA_MASK 0x3FF#define S3C2410_ADCDAT0_UPDOWN (0x1<<15)#define WAIT4INT(x) (((x)<<8) | \ S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \ S3C2410_ADCTSC_XY_PST_W)struct demo_ts{ struct input_dev tsdev; long xp; long yp; int count;};static struct demo_ts tsdemo_dev;static char *tsdemo_name = "tsdemo";static char *tsdemo_phys = "input0";static void touch_timer_fire(unsigned long data){ del_timer(&simple_timer); tsdemo_dev.xp = 0; tsdemo_dev.yp = 0; tsdemo_dev.count = 0; __raw_writel(0x69, S3C2410_ADCTSC); __raw_writel(0x4c7a, S3C2410_ADCCON); usleep(1); printk("enter touch_timer_fire\n");}static irqreturn_t adcdemo_interrupt(int irq, void *dummy, struct pt_regs *fp){ if(tsdemo_dev.count==0) { tsdemo_dev.count= 1; __raw_writel(__raw_readl(S3C2410_ADCCON)&(~2), S3C2410_ADCCON); tsdemo_dev.yp = __raw_readl(S3C2410_ADCDAT1) & S3C2410_ADCDAT0_XPDATA_MASK; __raw_writel(0x9a, S3C2410_ADCTSC); __raw_writel(0x4c6a, S3C2410_ADCCON); usleep(1); printk("PEN DOWN1: x: %ld, y: %ld\n",tsdemo_dev.xp,tsdemo_dev.yp); } else if(tsdemo_dev.count==1) { tsdemo_dev.count= 2; __raw_writel(__raw_readl(S3C2410_ADCCON)&(~2), S3C2410_ADCCON); tsdemo_dev.xp = __raw_readl(S3C2410_ADCDAT0) & S3C2410_ADCDAT0_XPDATA_MASK; printk("PEN DOWN: x: %ld, y: %ld\n",tsdemo_dev.xp,tsdemo_dev.yp); input_report_abs(&tsdemo_dev.tsdev, ABS_X, tsdemo_dev.xp); input_report_abs(&tsdemo_dev.tsdev, ABS_Y, tsdemo_dev.yp); //input_report_key(&tsdemo_dev.tsdev, BTN_TOUCH, 1); input_report_abs(&tsdemo_dev.tsdev, ABS_PRESSURE, 1); input_report_abs(&tsdemo_dev.tsdev, ABS_PRESSURE, 0); input_sync(&tsdemo_dev.tsdev); mdelay(1); writel(WAIT4INT(0), S3C2410_ADCTSC); } return IRQ_HANDLED;}static irqreturn_t tsdemo_interrupt(int irq, void *dummy, struct pt_regs *fp){ unsigned long data0; unsigned long data1; int updown; data0 = readl(S3C2410_ADCDAT0); data1 = readl(S3C2410_ADCDAT1); updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN)); printk("tsdemo_interrupt data0 = %ld, data1 = %ld updown = %d\n", data0, data1, updown); //点击 if (updown) { init_timer(&simple_timer); simple_timer.function = &touch_timer_fire; simple_timer.expires = jiffies + SIMPLE_TIMER_DELAY; add_timer (&simple_timer); } return IRQ_HANDLED;}void init_ts(void){ __raw_writel(__raw_readl(S3C2410_GPGCON)|(0xff<<24), S3C2410_GPGCON); __raw_writel(30000, S3C2410_ADCDLY); __raw_writel(0,S3C2410_ADCCON); __raw_writel(WAIT4INT(0), S3C2410_ADCTSC);}static int __init tsdemo_init(void){ init_ts(); /* Get irqs */ if (request_irq(IRQ_ADC, adcdemo_interrupt, SA_INTERRUPT, "tsdemo",NULL)) { printk(KERN_ERR "s3c2440_ts.c: Could not allocate ts IRQ_ADC !\n"); return -EIO; } if (request_irq(IRQ_TC, tsdemo_interrupt, SA_INTERRUPT, "tsdemo", NULL)) { disable_irq(IRQ_ADC); free_irq(IRQ_ADC,adcdemo_interrupt); return -EIO; } init_input_dev(&tsdemo_dev.tsdev); tsdemo_dev.tsdev.evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS);// | BIT(EV_REP); tsdemo_dev.tsdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(&tsdemo_dev.tsdev, ABS_X, 0, 0x3FF, 0, 0); input_set_abs_params(&tsdemo_dev.tsdev, ABS_Y, 0, 0x3FF, 0, 0); input_set_abs_params(&tsdemo_dev.tsdev, ABS_PRESSURE, 0, 1, 0, 0); tsdemo_dev.tsdev.private = &tsdemo_dev; tsdemo_dev.tsdev.name = tsdemo_name; tsdemo_dev.tsdev.phys = tsdemo_phys; tsdemo_dev.tsdev.id.bustype = BUS_RS232; tsdemo_dev.tsdev.id.vendor = 0xDEAD; tsdemo_dev.tsdev.id.product = 0xBEEF; tsdemo_dev.tsdev.id.version = 0x0101; input_register_device(&tsdemo_dev.tsdev); printk(KERN_INFO "input: %s\n", tsdemo_name); return 0;}static void __exit tsdemo_exit(void){ free_irq(IRQ_TC,tsdemo_interrupt); input_unregister_device(&tsdemo_dev.tsdev);}module_init(tsdemo_init);module_exit(tsdemo_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -