Dear sirs, The patch adds this touch screen driver to w90p910 ARM platform. It is based on version of 2.6.30-rc3. would you please give me some advice about this patch? arch/arm/mach-w90x900/include/mach/regs-adc.h | 57 +++ drivers/input/touchscreen/Kconfig | 6 drivers/input/touchscreen/Makefile | 1 drivers/input/touchscreen/w90p910_ts.c | 229 ++++++++++++++++ 4 files changed, 293 insertions(+) --- Add this touch screen driver c file for W90P910 platform. It is only one part of patch,the other such as maping, device register will be submitted soon after. Signed-off-by: Wan ZongShun <mcuos.com@xxxxxxxxx> diff -Npur linux-2.6.29/arch/arm/mach-w90x900/include/mach/regs-adc.h linux-2.6.30-rc3/arch/arm/mach-w90x900/include/mach/regs-adc.h --- linux-2.6.29/arch/arm/mach-w90x900/include/mach/regs-adc.h 1970-01-01 08:00:00.000000000 +0800 +++ linux-2.6.30-rc3/arch/arm/mach-w90x900/include/mach/regs-adc.h 2009-04-27 20:53:57.000000000 +0800 @@ -0,0 +1,57 @@ +/* + * arch/arm/mach-w90x900/include/mach/regs-adc.h + * + * Copyright (c) 2008 Nuvoton technology corporation + * All rights reserved. + * + * Wan ZongShun <mcuos.com@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#ifndef __ASM_ARM_REGS_ADC_H +#define __ASM_ARM_REGS_ADC_H + +/* ADC Control Registers */ +#define ADC_BA W90X900_VA_ADC +#define REG_ADC_CON (ADC_BA+0x00) +#define REG_ADC_TSC (ADC_BA+0x04) +#define REG_ADC_DLY (ADC_BA+0x08) +#define REG_ADC_XDATA (ADC_BA+0x0C) +#define REG_ADC_YDATA (ADC_BA+0x10) +#define REG_ADC_LV_CON (ADC_BA+0x14) +#define REG_ADC_LV_STS (ADC_BA+0x18) +#define ADC_INT 0x040000 +#define WT_INT 0x100000 +#define ADC_RESOULTION 1024 + +#define ADC_WRITE(addr, val) __raw_writel(val, addr) +#define ADC_READ(addr) __raw_readl(addr) +#define DEV_NAME "ADC" + +#define TSDEV_SCREEN_X 320 +#define TSDEV_SCREEN_Y 240 + +unsigned int INTERVAL_TIME = 4; +unsigned int pre_x, pre_y, STATE; +unsigned int nRadioWidth1, nRadioWidth2, nRadioHeight1, nRadioHeight2; +int adc_get = 0, adc_block = 1; + +static struct input_dev *w90p910_dev; +static DECLARE_MUTEX(sem); +static DEFINE_SPINLOCK(w90x900_touch_lock); +static struct timer_list ts_timer1; + +struct _pointmap{ + int x; + int y; + int status; +}; + +struct _pointmap point; + +#endif/*__ASM_ARM_REGS_ADC_H*/ diff -Npur linux-2.6.29/drivers/input/touchscreen/Kconfig linux-2.6.30-rc3/drivers/input/touchscreen/Kconfig --- linux-2.6.29/drivers/input/touchscreen/Kconfig 2009-04-27 14:10:36.000000000 +0800 +++ linux-2.6.30-rc3/drivers/input/touchscreen/Kconfig 2009-04-27 19:50:36.000000000 +0800 @@ -466,4 +466,10 @@ config TOUCHSCREEN_TSC2007 To compile this driver as a module, choose M here: the module will be called tsc2007. +config TOUCHSCREEN_W90X900 + tristate "W90P910 touchscreens" + depends on CPU_W90P910 + help + Compile this driver to support W90P910 touchscreen. + endif diff -Npur linux-2.6.29/drivers/input/touchscreen/Makefile linux-2.6.30-rc3/drivers/input/touchscreen/Makefile --- linux-2.6.29/drivers/input/touchscreen/Makefile 2009-04-27 14:10:36.000000000 +0800 +++ linux-2.6.30-rc3/drivers/input/touchscreen/Makefile 2009-04-27 19:50:49.000000000 +0800 @@ -37,3 +37,4 @@ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) + wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o +obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o diff -Npur linux-2.6.29/drivers/input/touchscreen/w90p910_ts.c linux-2.6.30-rc3/drivers/input/touchscreen/w90p910_ts.c --- linux-2.6.29/drivers/input/touchscreen/w90p910_ts.c 1970-01-01 08:00:00.000000000 +0800 +++ linux-2.6.30-rc3/drivers/input/touchscreen/w90p910_ts.c 2009-04-27 20:55:21.000000000 +0800 @@ -0,0 +1,229 @@ +/* + * linux/driver/input/w90x900_ts.c + * + * Copyright (c) 2008 Nuvoton technology corporation + * All rights reserved. + * + * Wan ZongShun <mcuos.com@xxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/input.h> +#include <linux/interrupt.h> + +#include <mach/hardware.h> +#include <mach/regs-clock.h> +#include <mach/regs-adc.h> + +short ADCDataIn(void) +{ + pre_x = ((ADC_READ(REG_ADC_XDATA)*TSDEV_SCREEN_X)/ADC_RESOULTION); + pre_y = ((ADC_READ(REG_ADC_YDATA)*TSDEV_SCREEN_Y)/ADC_RESOULTION); + + input_report_key(w90p910_dev, BTN_TOUCH, 1); + input_report_abs(w90p910_dev, ABS_X, pre_x); + input_report_abs(w90p910_dev, ABS_Y, pre_y); + input_report_abs(w90p910_dev, ABS_PRESSURE, 1000); + input_sync(w90p910_dev); + return 0; +} + +static void wb_sensitivity(unsigned long sensi) +{ + unsigned long flags; + down_interruptible(&sem); + spin_lock_irqsave(&w90x900_touch_lock, flags); + + if ((ADC_READ(REG_ADC_TSC)&0x1) == 0x1) { + + ADC_WRITE(REG_ADC_TSC, 0x0); + ADC_WRITE(REG_ADC_CON, (ADC_READ(REG_ADC_CON)| + 0x00206000)&0xFF7F7FFF); + STATE = 1; + } else{ + input_sync(w90p910_dev); + input_report_key(w90p910_dev, BTN_TOUCH, 0); + input_report_abs(w90p910_dev, ABS_PRESSURE, 0); + ADC_WRITE(REG_ADC_CON, (ADC_READ(REG_ADC_CON)| + 0x0080C000)&0xFFCBFFFF); + STATE = 0; + point.status = 0; + } + up(&sem); + spin_unlock_irqrestore(&w90x900_touch_lock, flags); +} + +static irqreturn_t wb_adc_irq(int irq, void *dev_id) +{ + unsigned long flags; + + down_interruptible(&sem); + spin_lock_irqsave(&w90x900_touch_lock, flags); + adc_get = 1; + + if (((ADC_READ(REG_ADC_CON)&WT_INT)>>20) == 1 && STATE == 0) { + STATE = 1; + ADC_WRITE(REG_ADC_TSC, 0x0); + ADC_WRITE(REG_ADC_CON, (ADC_READ(REG_ADC_CON)| + 0x00206000)&0xFF6F7FFF); + } + + if (((ADC_READ(REG_ADC_CON)&ADC_INT)>>18) == 1 && STATE == 1) { + STATE = 2; + ADC_WRITE(REG_ADC_TSC, 0x100); + ADC_WRITE(REG_ADC_CON, (ADC_READ(REG_ADC_CON)| + 0x00206000)&0xFF7B7FFF); + } + + if (((ADC_READ(REG_ADC_CON)&ADC_INT)>>18) == 1 && STATE == 2) { + ADCDataIn(); + point.status = 1; + ADC_WRITE(REG_ADC_CON, (ADC_READ(REG_ADC_CON)| + 0x0000C000)&0xFF5BFFFF); + + del_timer(&ts_timer1); + ts_timer1.expires = jiffies+INTERVAL_TIME; + ts_timer1.data = 0UL; + add_timer(&ts_timer1); + + } + up(&sem); + spin_unlock_irqrestore(&w90x900_touch_lock, flags); + return IRQ_HANDLED; +} + +static int wb_adc_open(struct input_dev *dev) +{ + + adc_block = 1; + adc_get = 1; + init_timer(&ts_timer1); + ts_timer1.function = wb_sensitivity; + /* reset */ + ADC_WRITE(REG_ADC_CON, 0x00010000); + udelay(1000); + ADC_WRITE(REG_ADC_CON, 0x00000000); + udelay(1000); + /* ADC setting */ + /* set delay and screen type */ + ADC_WRITE(REG_ADC_TSC, ADC_READ(REG_CLKSEL) & 0xFFFFFFF9); + ADC_WRITE(REG_ADC_DLY, 0xF00); + /* waitting for trigger mode */ + ADC_WRITE(REG_ADC_CON, (ADC_READ(REG_ADC_CON)| + 0x0082C008) & 0xFFEBFF09); + STATE = 0; + pre_x = pre_y = 0; + return 0; +} + +static void wb_adc_close(struct input_dev *dev) +{ + free_irq(IRQ_ADC, NULL); +} + +static int __init w90x900ts_probe(struct platform_device *pdev) +{ + int irq, result, err; + unsigned int tmp32; + struct resource *res; + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq for device\n"); + return -ENOENT; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + if (!request_mem_region(res->start, res->end - res->start + 1, + pdev->name)) { + dev_err(&pdev->dev, "Memory region busy\n"); + err = -EBUSY; + goto fail; + } + + /* enable the ADC clock */ + tmp32 = ADC_READ(REG_CLKEN); + tmp32 = tmp32 | 0x10000000; + ADC_WRITE(REG_CLKEN, tmp32); + + w90p910_dev = input_allocate_device(); + + if (!w90p910_dev) { + printk(KERN_ERR "w90p910_dev: not enough memory\n"); + err = -ENOMEM; + goto fail; + } + + w90p910_dev->name = "W90P910 TouchScreen"; + w90p910_dev->phys = "input/event0"; + w90p910_dev->id.bustype = BUS_HOST; + w90p910_dev->id.vendor = 0x0005; + w90p910_dev->id.product = 0x0001; + w90p910_dev->id.version = 0x0100; + + w90p910_dev->open = wb_adc_open; + w90p910_dev->close = wb_adc_close; + + w90p910_dev->evbit[0] = BIT_MASK(EV_KEY)| + BIT_MASK(EV_ABS) | BIT_MASK(EV_SYN); + w90p910_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + + input_set_abs_params(w90p910_dev, ABS_X, 0, 0x400, 0, 0); + input_set_abs_params(w90p910_dev, ABS_Y, 0, 0x400, 0, 0); + input_set_abs_params(w90p910_dev, ABS_PRESSURE, 0, 1000, 0, 0); + + result = request_irq(irq, wb_adc_irq, IRQF_DISABLED, DEV_NAME, NULL); + if (result != 0) + printk(KERN_ERR"register the wb_adc_irq failed!\n"); + + input_register_device(w90p910_dev); + return 0; + +fail: + input_free_device(w90p910_dev); + return err; +} + +static int w90x900ts_remove(struct platform_device *pdev) +{ + + input_unregister_device(w90p910_dev); + return 0; +} + +static struct platform_driver w90x900ts_driver = { + .probe = w90x900ts_probe, + .remove = w90x900ts_remove, + .driver = { + .name = "w90x900-ts", + .owner = THIS_MODULE, + }, +}; + +int __init w90x900ts_init(void) +{ + return platform_driver_register(&w90x900ts_driver); +} + +static void __exit w90x900ts_exit(void) +{ + platform_driver_unregister(&w90x900ts_driver); +} + +module_init(w90x900ts_init); +module_exit(w90x900ts_exit); + +MODULE_AUTHOR("PT50 zswan <mcuos.com@xxxxxxxxx>"); +MODULE_DESCRIPTION("w90p910 touch screen driver!"); +MODULE_LICENSE("GPL"); -- embedded forum http://mcuos.com -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html