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

📄 omap-tsc2101-ts.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
字号:
/* * linux/sound/oss/omap-audio.c * * Touch Screen driver  for the OMAP processors * * Copyright (C) 2004 Texas Instruments, Inc. * * * This package is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * History: * * 2004-10-28 	Srinath - Ported to 2420 * * 2004-11-16	Srianth	- Changed from polling mode to interrupt mode on 1710 and 1610 * * 2004-11-23	Srinath	- Added support for Power Management *//************************************************************************** * 			INCLUDES * **********************************************************************/#include <linux/errno.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/init.h>#include <linux/wait.h>#include <linux/interrupt.h>#include <linux/suspend.h>#include <linux/device.h>#include <asm/mach-types.h>#include <asm/arch/gpio.h>#include <asm/arch/mux.h>#include <asm/arch/hardware.h>#include <asm/hardware/tsc2101.h>#include <../drivers/ssi/omap-tsc2101.h>/******************************************************************************* * 			MACROS *****************************************************************************/#define OMAP_TSC2101_NAME			"omap_tsc2101_ts"#define OMAP_TSC2101_XRES                       500#define TOUCHSCREEN_DATA_REGISTERS_PAGE		0x0#define TOUCHSCREEN_CONTROL_REGISTERS_PAGE	0x1#define OMAP_TSC2101_READ_MAX			0x4#define TSC2101_GETSTATUS(ret)			(((ret) >> 11) & 0x1)#define TSC2101_MASKVAL				0xFFF#define TSC2101_PRESSUREVAL(x)			((x) << 12)#if CONFIG_ARCH_OMAP16XX#define OMAP_1710_GPIO_NUM 			48#define OMAP_1610_GPIO_NUM			4#elif CONFIG_ARCH_OMAP24XX#define OMAP_24XX_GPIO_NUM 			93#endif/*************************************************************************** * 		FUNCTION PROTOTYPES **************************************************************************/static void omap_tsc2101_ts_tasklet(unsigned long);static int omap_tsc2101_ts_read_buf(void);static int omap_tsc2101_ts_buf_empty(void);static irqreturn_t omap_tsc2101_ts_handler(int irq, void *dev_id,					   struct pt_regs *regs);static int omap_tsc2101_ts_probe(struct device *dev);static int omap_tsc2101_ts_remove(struct device *dev);static int omap_tsc2101_ts_suspend(struct device *dev, u32 state, u32 level);static int omap_tsc2101_ts_resume(struct device *dev, u32 level);static void omap_tsc2101_ts_disable(void);static void omap_tsc2101_ts_enable(void);/**************************************************************************** * 			DATA STRUCTURES ***************************************************************************//* Tasklet Declaration */DECLARE_TASKLET(omap_tsc2101_ts, omap_tsc2101_ts_tasklet, 0);static struct {	struct input_dev inputdevice;	int touched;	int irq;	int xres;} tsc2101_ts;/* Device Information */static struct platform_device omap_tsc2101_ts_device = {	.name = OMAP_TSC2101_NAME,	.id = 0,};/* Driver Information */static struct device_driver omap_tsc2101_ts_driver = {	.name = OMAP_TSC2101_NAME,	.bus = &platform_bus_type,	.probe = omap_tsc2101_ts_probe,	.remove = omap_tsc2101_ts_remove,	.suspend = omap_tsc2101_ts_suspend,	.resume = omap_tsc2101_ts_resume,};/*********************************************************************************** omap_tsc2101_ts_buf_empty(void) : Function to read the TSC status register  *  **********************************************************************************/static int omap_tsc2101_ts_buf_empty(void){	int ret = 0;	/* Read the status register */	ret =	    omap_tsc2101_read(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			      TSC2101_TS_STATUS);	/* Check for avialbality of data in status register */	ret = TSC2101_GETSTATUS(ret);	return !ret;}/********************************************************************************** * omap_tsc2101_ts_read_buf(void) : Function to read the TSC data registers* *********************************************************************************/static int omap_tsc2101_ts_read_buf(void){	u16 values[OMAP_TSC2101_READ_MAX] = { 0, 0, 0, 0 };	s32 t, p = 0;	int i;	/* Read X, Y, Z1 and Z2 */	omap_tsc2101_reads(TOUCHSCREEN_DATA_REGISTERS_PAGE, TSC2101_TS_X,			   values, OMAP_TSC2101_READ_MAX);	for (i = 0; i < OMAP_TSC2101_READ_MAX; i++)		values[i] &= TSC2101_MASKVAL;	input_report_abs(&(tsc2101_ts.inputdevice), ABS_X,			 values[TSC2101_TS_X]);	input_report_abs(&(tsc2101_ts.inputdevice), ABS_Y,			 values[TSC2101_TS_Y]);	/* Calculate Pressure */	if (values[TSC2101_TS_Z1] != 0) {		t = ((tsc2101_ts.xres * values[TSC2101_TS_X]) *		     (values[TSC2101_TS_Z2] - values[TSC2101_TS_Z1]));		p = t / (u32) (TSC2101_PRESSUREVAL(values[TSC2101_TS_Z1]));		if (p < 0)			p = 0;	}	input_report_abs(&(tsc2101_ts.inputdevice), ABS_PRESSURE, p);	input_sync(&(tsc2101_ts.inputdevice));	return 0;}/***********************************************************************************     omap_tsc2101_ts_tasklet(unsigned long nothing) : Tasklet Function ***********************************************************************************/static void omap_tsc2101_ts_tasklet(unsigned long nothing){	if (!omap_tsc2101_ts_buf_empty()) {		/* Pen  down */		if (!tsc2101_ts.touched) {			input_report_key(&(tsc2101_ts.inputdevice),					 BTN_TOUCH, 1);		}		tsc2101_ts.touched = 1;		omap_tsc2101_ts_read_buf();	} else {		/* Pen  up */		if (tsc2101_ts.touched) {			tsc2101_ts.touched = 0;			input_report_key(&(tsc2101_ts.inputdevice),					 BTN_TOUCH, 0);		}	}	return;}/***********************************************************************************    omap_tsc2101_ts_handler(int irq, void *dev_id,*                                     struct pt_regs *regs)  : Interrupt Handler************************************************************************************/static irqreturn_t omap_tsc2101_ts_handler(int irq, void *dev_id,					   struct pt_regs *regs){	/* Schedule Takslet */	tasklet_schedule(&omap_tsc2101_ts);	return IRQ_HANDLED;}/***********************************************************************************	omap_tsc2101_ts_enable(void) : Function to  configure the TSC Codec*********************************************************************************/static void omap_tsc2101_ts_enable(void){	int ret = omap_tsc2101_enable();	if (ret) {		printk(KERN_ERR "FAILED TO INITIALIZE TSC CODEC\n");		return;	}	/* PINTDAV is data available only */	omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			   TSC2101_TS_STATUS, TSC2101_DATA_AVAILABLE);	/* disable buffer mode */	omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			   TSC2101_TS_BUFFER_CTRL, TSC2101_BUFFERMODE_DISABLE);	/* use internal reference, 100 usec power-up delay,	 * power down between conversions, 1.25V internal reference */	omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			   TSC2101_TS_REF_CTRL, TSC2101_REF_POWERUP);	/* enable touch detection, 84usec precharge time, 32 usec sense time */	omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			   TSC2101_TS_CONFIG_CTRL, TSC2101_ENABLE_TOUCHDETECT);	/* 1 msec conversion delays and MCLK selected  */	omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			   TSC2101_TS_PROG_DELAY, TSC2101_PRG_DELAY);	/* 	 * TSC2101-controlled conversions	 * 12-bit samples	 * continuous X,Y,Z1,Z2 scan mode	 * average (mean) 4 samples per coordinate 	 * 1 MHz internal conversion clock	 * 500 usec panel voltage stabilization delay	 * */	omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			   TSC2101_TS_ADC_CTRL, TSC2101_ADC_CONTROL);	return;}/***********************************************************************************       omap_tsc2101_ts_disable(void) : Function to  shutdown  TSC Codec*********************************************************************************/static void omap_tsc2101_ts_disable(void){	tasklet_kill(&omap_tsc2101_ts);	/* stop conversions and power down */	omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,			   TSC2101_TS_ADC_CTRL, TSC2101_ADC_POWERDOWN);	omap_tsc2101_disable();	return;}/***********************************************************************************	 omap_tsc2101_ts_probe(): The TSC driver probe function***********************************************************************************/static int omap_tsc2101_ts_probe(struct device *dev){	memset(&tsc2101_ts, 0, sizeof(tsc2101_ts));	tsc2101_ts.xres = OMAP_TSC2101_XRES;#ifdef  CONFIG_ARCH_OMAP16XX	if (machine_is_omap_h3()) {		tsc2101_ts.irq = OMAP_GPIO_IRQ(OMAP_1710_GPIO_NUM);		/* Configure GPIO for Pen IRQ */		omap_cfg_reg(W19_1610_GPIO48);		if (omap_request_gpio(OMAP_1710_GPIO_NUM) != 0) {			printk(KERN_ERR			       "omap_tsc2101_ts.c: Could not reserve GPIO!\n");			return -EINVAL;		};		omap_set_gpio_direction(OMAP_1710_GPIO_NUM, 1);		omap_set_gpio_edge_ctrl(OMAP_1710_GPIO_NUM,					OMAP_GPIO_FALLING_EDGE);	} else if (machine_is_omap_h2()) {		tsc2101_ts.irq = OMAP_GPIO_IRQ(OMAP_1610_GPIO_NUM);		/* Configure GPIO for Pen IRQ */		omap_cfg_reg(P20_1610_GPIO4);		if (omap_request_gpio(OMAP_1610_GPIO_NUM) != 0) {			printk(KERN_ERR			       "omap_tsc2101_ts.c: Could not reserve GPIO!\n");			return -EINVAL;		};		omap_set_gpio_direction(OMAP_1610_GPIO_NUM, 1);		omap_set_gpio_edge_ctrl(OMAP_1610_GPIO_NUM,					OMAP_GPIO_FALLING_EDGE);	} else {		printk(KERN_ERR "omap_tsc2101_ts.c: Unsupported platform!\n");		return -EINVAL;	}#endif#ifdef CONFIG_ARCH_OMAP24XX	tsc2101_ts.irq = OMAP_GPIO_IRQ_NO(OMAP_24XX_GPIO_NUM);	omap2_cfg_reg(P20_2420_TSC_IRQ);	if (omap_request_gpio(OMAP_24XX_GPIO_NUM) != 0) {		printk(KERN_ERR "omap_tsc2101_ts.c: Could not reserve GPIO!\n");		return -EINVAL;	};	omap_set_gpio_direction(OMAP_24XX_GPIO_NUM, OMAP2420_DIR_INPUT);	omap_set_gpio_edge_ctrl(OMAP_24XX_GPIO_NUM, OMAP_GPIO_FALLING_EDGE);#endif	/* Request irq */	if (request_irq(tsc2101_ts.irq, omap_tsc2101_ts_handler,			SA_INTERRUPT | SA_SAMPLE_RANDOM,			"omap_tsc2101_ts", &tsc2101_ts)) {		printk(KERN_ERR		       "omap_tsc2101_ts.c: Could not allocate pen IRQ!\n");		tsc2101_ts.irq = -1;	}	init_input_dev(&(tsc2101_ts.inputdevice));	tsc2101_ts.inputdevice.name = OMAP_TSC2101_NAME;	tsc2101_ts.inputdevice.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);	tsc2101_ts.inputdevice.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);	tsc2101_ts.inputdevice.absbit[0] =	    BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);	input_register_device(&(tsc2101_ts.inputdevice));	/* Enable the TSC */	omap_tsc2101_ts_enable();	return 0;}/***********************************************************************************        omap_tsc2101_ts_remove(): Function to handle removal operations***********************************************************************************/static int omap_tsc2101_ts_remove(struct device *dev){	omap_tsc2101_ts_disable();	input_unregister_device(&tsc2101_ts.inputdevice);#ifdef CONFIG_ARCH_16XX	free_irq(tsc2101_ts.irq, &tsc2101_ts);	if (machine_is_omap_h2())		omap_free_gpio(OMAP_1610_GPIO_NUM);	else if (machine_is_omap_h3())		omap_free_gpio(OMAP_1710_GPIO_NUM);	else {		printk(KERN_ERR "omap_tsc2101_ts.c: Unsupported platform!\n");		return -EINVAL;	}#endif#ifdef CONFIG_ARCH_OMAP24XX	omap_free_gpio(OMAP_24XX_GPIO_NUM);#endif	return 0;}/*********************************************************************************** 	omap_tsc2101_ts_suspend(): Function to handle suspend operations**********************************************************************************/static int omap_tsc2101_ts_suspend(struct device *dev, u32 state, u32 level){	if (level != 3) {		return 0;	}	omap_tsc2101_ts_disable();	return 0;}/***********************************************************************************	 omap_tsc2101_ts_resume : Function to handle resume operations**********************************************************************************/static int omap_tsc2101_ts_resume(struct device *dev, u32 level){	if (level != 0) {		return 0;	}	omap_tsc2101_ts_enable();	return 0;}/***********************************************************************************	  omap_tsc2101_ts_init(): TSC driver init function**********************************************************************************/static int __init omap_tsc2101_ts_init(void){	int ret;	ret = platform_device_register(&omap_tsc2101_ts_device);	if (ret != 0)		return -ENODEV;	ret = driver_register(&omap_tsc2101_ts_driver);	if (ret == 0)		return 0;	platform_device_unregister(&omap_tsc2101_ts_device);	return -ENODEV;}/***********************************************************************************         omap_tsc2101_ts_exitt(): TSC driver exit function**********************************************************************************/static void __exit omap_tsc2101_ts_exit(void){	driver_unregister(&omap_tsc2101_ts_driver);	platform_device_unregister(&omap_tsc2101_ts_device);}module_init(omap_tsc2101_ts_init);module_exit(omap_tsc2101_ts_exit);MODULE_AUTHOR("Texas Instruments");MODULE_DESCRIPTION("Touch screen Driver for OMAP processors");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -