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

📄 demo.c

📁 《linux驱动程序设计从入门到精通》一书中所有的程序代码含驱动和相应的应用程序
💻 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 + -