From 3233bb1968fe4960358e75186cbe0114993716a2 Mon Sep 17 00:00:00 2001 From: Gennady Kupava Date: Wed, 20 Oct 2010 20:26:40 +0200 Subject: [PATCH] s3c2410_ts: jitter less touchscreen for glamo, version 3 Signed-off-by: Martin Jansa --- arch/arm/mach-s3c2410/include/mach/ts.h | 4 ++ arch/arm/mach-s3c2440/mach-gta02.c | 23 ++++++++++- drivers/input/touchscreen/s3c2410_ts.c | 35 ++++++++++++++++- drivers/mfd/glamo-core.c | 63 ++++++++++++++++++++++++++++++- include/linux/mfd/glamo-core.h | 5 ++ 5 files changed, 124 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-s3c2410/include/mach/ts.h b/arch/arm/mach-s3c2410/include/mach/ts.h index dc36170..3112a2c 100644 --- a/arch/arm/mach-s3c2410/include/mach/ts.h +++ b/arch/arm/mach-s3c2410/include/mach/ts.h @@ -14,6 +14,10 @@ struct s3c2410_ts_mach_info { int delay; int presc; int oversampling_shift; +#ifdef CONFIG_MACH_NEO1973_GTA02 + void (*before_adc_hook)(void); + void (*after_adc_hook)(void); +#endif }; extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *); diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index 702b80a..3093ca9 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -111,6 +111,7 @@ #include #include #include +#include #define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) @@ -943,11 +944,29 @@ static struct s3c2410_hcd_info gta02_usb_info __initdata = { }, }; +static int glamo_slowed = 0; + +static void gta02_ts_hook_before_adc () { + if (!glamo_slowed) { + glamo_slowed = 1; + glamo_pixclock_slow(dev_get_drvdata (>a02_glamo_dev.dev)); + } +}; + +static void gta02_ts_hook_after_adc () { + if (glamo_slowed) { + glamo_slowed = 0; + glamo_pixclock_fast(dev_get_drvdata (>a02_glamo_dev.dev)); + } +}; + /* Touchscreen */ static struct s3c2410_ts_mach_info gta02_ts_info = { - .delay = 10000, + .delay = 1000, .presc = 0xff, /* slow as we can go */ - .oversampling_shift = 2, + .oversampling_shift = 0, + .before_adc_hook = gta02_ts_hook_before_adc, + .after_adc_hook = gta02_ts_hook_after_adc, }; /* Buttons */ diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index ed5b437..c4d82c9 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -84,6 +84,10 @@ struct s3c2410ts { int count; int shift; int expectedintr; /* kind of interrupt we are waiting for */ +#ifdef CONFIG_MACH_NEO1973_GTA02 + void (*before_adc_hook)(void); + void (*after_adc_hook)(void); +#endif }; static struct s3c2410ts ts; @@ -92,6 +96,7 @@ static struct s3c2410ts ts; #define WAITFORINT_DOWN (1) #define WAITFORINT_NOTHING (2) + /** * s3c2410_ts_connect - configure gpio for s3c2410 systems * @@ -152,6 +157,9 @@ static void touch_timer_fire(unsigned long data) ts.count = 0; } +#ifdef CONFIG_MACH_NEO1973_GTA02 + ts.before_adc_hook(); +#endif s3c_adc_start(ts.client, 0, 1 << ts.shift); } else { ts.xp = 0; @@ -159,7 +167,7 @@ static void touch_timer_fire(unsigned long data) ts.count = 0; input_report_key(ts.input, BTN_TOUCH, 0); - input_report_abs(ts.input, ABS_PRESSURE, 0); + input_report_abs(ts.input, ABS_PRESSURE, 0); input_sync(ts.input); ts.expectedintr = WAITFORINT_DOWN; @@ -201,7 +209,7 @@ static irqreturn_t stylus_irq(int irq, void *dev_id) ts.expectedintr = WAITFORINT_NOTHING; if (down) - s3c_adc_start(ts.client, 0, 1 << ts.shift); + mod_timer(&touch_timer, jiffies + 2); else dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count); @@ -228,6 +236,11 @@ static void s3c24xx_ts_conversion(struct s3c_adc_client *client, ts.count++; +#ifdef CONFIG_MACH_NEO1973_GTA02 + if (!*left) + ts.after_adc_hook(); +#endif + /* From tests, it seems that it is unlikely to get a pen-up * event during the conversion process which means we can * ignore any pen-up events with less than the requisite @@ -251,7 +264,7 @@ static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select) writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts.io + S3C2410_ADCTSC); } else { - mod_timer(&touch_timer, jiffies+1); + mod_timer(&touch_timer, jiffies + 3); ts.expectedintr = WAITFORINT_UP; writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC); } @@ -333,6 +346,8 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) ts.expectedintr = WAITFORINT_DOWN; writel(WAIT4INT | INT_DOWN, ts.io + S3C2410_ADCTSC); + + input_dev = input_allocate_device(); if (!input_dev) { dev_err(dev, "Unable to allocate the input device !!\n"); @@ -355,6 +370,11 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) ts.shift = info->oversampling_shift; +#ifdef CONFIG_MACH_NEO1973_GTA02 + ts.before_adc_hook = info->before_adc_hook; + ts.after_adc_hook = info->after_adc_hook; +#endif + ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED, "s3c2410_ts_pen", ts.input); if (ret) { @@ -412,6 +432,15 @@ static int s3c2410ts_suspend(struct device *dev) ts.expectedintr = WAITFORINT_NOTHING; writel(TSC_SLEEP, ts.io + S3C2410_ADCTSC); disable_irq(ts.irq_tc); + + del_timer_sync(&touch_timer); + /* TODO - need to fix races better, as timer can fire + between TSC_SLEEP and del_timer_sync() and shedule next adc */ + +#ifdef CONFIG_MACH_NEO1973_GTA02 + ts.after_adc_hook(); +#endif + clk_disable(ts.clock); return 0; diff --git a/drivers/mfd/glamo-core.c b/drivers/mfd/glamo-core.c index fb0c92d..716f236 100644 --- a/drivers/mfd/glamo-core.c +++ b/drivers/mfd/glamo-core.c @@ -104,6 +104,8 @@ static const struct reg_range reg_range[] = { /* { 0x1b00, 0x900, "3D Unit", 0 }, */ }; +struct glamo_core *default_glamo = 0; + static inline void __reg_write(struct glamo_core *glamo, uint16_t reg, uint16_t val) { @@ -160,6 +162,19 @@ static void reg_set_bit_mask(struct glamo_core *glamo, spin_unlock(&glamo->lock); } + + +static void reg_checkandset_bit_mask(struct glamo_core *glamo, + uint16_t reg, uint16_t mask, + uint16_t val, uint16_t check) +{ + spin_lock(&glamo->lock); + if (__reg_read(glamo, reg) & mask == check) + __reg_set_bit_mask(glamo, reg, mask, val); + spin_unlock(&glamo->lock); +} + + static inline void __reg_set_bit(struct glamo_core *glamo, uint16_t reg, uint16_t bit) { @@ -169,6 +184,49 @@ static inline void __reg_set_bit(struct glamo_core *glamo, __reg_write(glamo, reg, tmp); } +void glamo_pixclock_slow (struct glamo_core *glamo) { + + int x,lastx=0; + int timeout=1000000; + int threshold=5; + int fa; + + int evcnt=0; + + //int phase=0; //wait for value changing, then for non-changing + + for (fa=0;faslowed_divider = glamo_reg_read (glamo, 0x36) & 0xFF; + reg_set_bit_mask (glamo, 0x36, 0xFF, 0xFF); + +} + +void glamo_pixclock_fast (struct glamo_core *glamo) { + reg_checkandset_bit_mask (glamo, 0x36, 0xFF, glamo->slowed_divider, 0xFF); +} +EXPORT_SYMBOL_GPL(glamo_pixclock_fast); +EXPORT_SYMBOL_GPL(glamo_pixclock_slow); + static inline void __reg_clear_bit(struct glamo_core *glamo, uint16_t reg, uint16_t bit) { @@ -963,6 +1021,8 @@ static int __devinit glamo_probe(struct platform_device *pdev) for (n = 0; n < __NUM_GLAMO_ENGINES; n++) glamo->engine_state[n] = GLAMO_ENGINE_DISABLED; + default_glamo = glamo; + spin_lock_init(&glamo->lock); glamo->pdev = pdev; @@ -970,6 +1030,7 @@ static int __devinit glamo_probe(struct platform_device *pdev) glamo->irq = platform_get_irq(pdev, 0); glamo->irq_base = irq_base = platform_get_irq(pdev, 1); glamo->pdata = pdev->dev.platform_data; + glamo->slowed_divider = 0xFF; if (glamo->irq < 0) { ret = glamo->irq; @@ -1005,7 +1066,7 @@ static int __devinit glamo_probe(struct platform_device *pdev) goto err_free; } - glamo->base = ioremap(glamo->mem->start, resource_size(glamo->mem)); + glamo->base = ioremap(glamo->mem->start, resource_size(glamo->mem)+0x1100); if (!glamo->base) { dev_err(&pdev->dev, "Failed to ioremap() memory region\n"); goto err_release_mem_region; diff --git a/include/linux/mfd/glamo-core.h b/include/linux/mfd/glamo-core.h index 66cd7a5..6fe29a8 100644 --- a/include/linux/mfd/glamo-core.h +++ b/include/linux/mfd/glamo-core.h @@ -49,11 +49,14 @@ struct glamo_core { enum glamo_engine_state engine_state[__NUM_GLAMO_ENGINES]; spinlock_t lock; uint16_t saved_irq_mask; + int slowed_divider; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dir; #endif }; +extern struct glamo_core *default_glamo; + struct glamo_script { uint16_t reg; uint16_t val; @@ -67,4 +70,6 @@ int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine); void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine); int glamo_engine_reclock(struct glamo_core *glamo, enum glamo_engine engine, int ps); +void glamo_pixclock_slow (struct glamo_core *glamo); +void glamo_pixclock_fast (struct glamo_core *glamo); #endif /* __GLAMO_CORE_H */ -- 1.7.3.2