-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Somebody in the thread at some point said:
| On Tue, 21 Oct 2008 03:55:48 +0100 Andy Green <[EMAIL PROTECTED]> babbled:
|
|> -----BEGIN PGP SIGNED MESSAGE-----
|> Hash: SHA1
|>
|> Somebody in the thread at some point said:
|> |> http://svn.openmoko.org/developers/tick/touchtest/touch_test.py
|> |
|> | IIUC this is listening to X events, but this has already been filtered
|> | through a driver that tries to reduce jitter and stuff. What kind of
|> | info does the driver give? Could it support multiple touches
|> | (e.g. pinch, two-finger scroll, ...)?
|>
|> The only extra thing you can squeeze out of it is the area of the
|> contact to the touchscreen, so you can tell between stylus, fingernail,
|> thumb. I also made a patch for this, but I was unable to get the
|> results normalized across the whole touchscreen surface. It could tell
|> very well though in any given area about the contact size.
|
| do you have any raw data on your results? how was the "size" reported
(radius
| from touch point?)
It was reported as additional ABS_PRESSURE of the sample, so X and Y
were left alone. That breaks X somehow so it needs changing to Z or
some other parallel attribute.
But I couldn't find the right formula to normalize the results across
the screen, they varied widely depending on which corner of the screen.
Here's the somewhat bitrotted patch with some noise stuff at the
beginning, if anyone is interested to move it on. It applies over the
other patch mentioned earlier that does median filtering.
- -Andy
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iEYEARECAAYFAkj9eP0ACgkQOjLpvpq7dMpMggCbBsl1WPp9/duMqkdZpAK4NeAX
KTkAn1gnJx0QcfCzxPwx2a2Ka5/RqizE
=ZJJ8
-----END PGP SIGNATURE-----
test-touchscreen-pressure.patch
From: Andy Green <[EMAIL PROTECTED]>
Signed-off-by: Andy Green <[EMAIL PROTECTED]>
---
arch/arm/mach-s3c2440/mach-gta02.c | 20 ++-
defconfig-gta01 | 6 +
defconfig-gta02 | 7 +
drivers/input/touchscreen/s3c2410_ts.c | 217 +++++++++++++++++++++-----------
drivers/input/touchscreen/ts_filter.c | 86 +++++++++++++
include/asm-arm/arch-s3c2410/ts.h | 4 +
include/linux/ts_filter.h | 27 ++++
7 files changed, 283 insertions(+), 84 deletions(-)
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-gta02.c
index 8c5d1cb..b033490 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -902,10 +902,10 @@ static struct s3c2410_udc_mach_info gta02_udc_cfg = {
/* touchscreen configuration */
static struct ts_filter_median_configuration gta02_ts_median_config = {
- .extent = 31,
- .decimation_below = 28,
- .decimation_threshold = 8 * 3,
- .decimation_above = 12,
+ .extent = 31, /* total memory of median filter */
+ .decimation_threshold = 6 * 3, /* delta that decides fast or slow */
+ .decimation_below = 28, /* slow -- accumilate lots of inp before out */
+ .decimation_above = 8, /* fast -- less inp before output so we track */
};
static struct ts_filter_mean_configuration gta02_ts_mean_config = {
@@ -915,14 +915,20 @@ static struct ts_filter_mean_configuration
gta02_ts_mean_config = {
static struct s3c2410_ts_mach_info gta02_ts_cfg = {
.delay = 10000,
- .presc = 0xff, /* slow as we can go */
+ /* fast as we can go to reduce time with ts plates powered */
+ .presc = 50000000 / 2500000, /* 50MHz PCLK / 2.5MHz clock needed */
+ /* only do additional area measurements every third time */
+ .area_test_ratio = 3,
+ .area_minimum = 20,
+ .area_maximum = 75,
+
.filter_sequence = {
[0] = &ts_filter_median_api,
- [1] = &ts_filter_mean_api,
+// [1] = &ts_filter_mean_api,
},
.filter_config = {
[0] = >a02_ts_median_config,
- [1] = >a02_ts_mean_config,
+// [1] = >a02_ts_mean_config,
},
};
diff --git a/defconfig-gta01 b/defconfig-gta01
index 57a7d51..08fce0c 100644
--- a/defconfig-gta01
+++ b/defconfig-gta01
@@ -159,7 +159,7 @@ CONFIG_CPU_LLSERIAL_S3C2440=y
#
# Power management
#
-# CONFIG_S3C2410_PM_DEBUG is not set
+CONFIG_S3C2410_PM_DEBUG=y
# CONFIG_S3C2410_PM_CHECK is not set
CONFIG_S3C_LOWLEVEL_UART_PORT=0
@@ -1696,7 +1696,9 @@ CONFIG_FORCED_INLINING=y
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_USER is not set
CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+CONFIG_DEBUG_S3C_PORT=y
CONFIG_DEBUG_S3C_UART=0
#
diff --git a/defconfig-gta02 b/defconfig-gta02
index 8150615..8ca3f9c 100644
--- a/defconfig-gta02
+++ b/defconfig-gta02
@@ -159,6 +159,7 @@ CONFIG_CPU_LLSERIAL_S3C2440=y
#
# Power management
#
+CONFIG_S3C2410_PM_DEBUG=y
# CONFIG_S3C2410_PM_CHECK is not set
CONFIG_S3C_LOWLEVEL_UART_PORT=2
@@ -1020,7 +1021,7 @@ CONFIG_SPI_S3C24XX_GPIO=y
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
-CONFIG_APM_POWER=y
+# CONFIG_APM_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
CONFIG_BATTERY_BQ27000_HDQ=y
CONFIG_GTA02_HDQ=y
@@ -1695,7 +1696,9 @@ CONFIG_FORCED_INLINING=y
# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_USER is not set
CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+CONFIG_DEBUG_S3C_PORT=y
CONFIG_DEBUG_S3C_UART=2
#
diff --git a/drivers/input/touchscreen/s3c2410_ts.c
b/drivers/input/touchscreen/s3c2410_ts.c
index 3b063bb..77d3f63 100644
--- a/drivers/input/touchscreen/s3c2410_ts.c
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -79,6 +79,18 @@
S3C2410_ADCTSC_AUTO_PST | \
S3C2410_ADCTSC_XY_PST(0))
+#define READZ1 (S3C2410_ADCTSC_XM_SEN | /* X- on */ \
+ S3C2410_ADCTSC_YP_SEN | /* Y+ off -- sample this*/ \
+ S3C2410_ADCTSC_XY_PST(0)) /* Y- off, X+ on */
+
+#define READZ2 (S3C2410_ADCTSC_XM_SEN | /* X- on */ \
+ S3C2410_ADCTSC_XP_SEN | /* X+ off -- z1*/ \
+ S3C2410_ADCTSC_XY_PST(0)) /* Y- off -- z2, Y+ on */
+
+#define NODRIVE (S3C2410_ADCTSC_YP_SEN | /* Y+ off */ \
+ S3C2410_ADCTSC_XP_SEN | /* X+ off */ \
+ S3C2410_ADCTSC_XY_PST(0)) /* Y- off, X- off */
+
#define DEBUG_LVL KERN_DEBUG
MODULE_AUTHOR("Arnaud Patard <[EMAIL PROTECTED]>");
@@ -99,7 +111,11 @@ static char *s3c2410ts_name = "s3c2410 TouchScreen";
struct s3c2410ts {
struct input_dev *dev;
struct ts_filter *tsf[MAX_TS_FILTER_CHAIN];
- int coords[2]; /* just X and Y for us */
+ struct s3c2410_ts_mach_info info;
+ struct ts_filter_4node_area area;
+
+ int coords[4]; /* X, Y, Z1, Z2 */
+ int running;
};
static struct s3c2410ts ts;
@@ -108,7 +124,7 @@ static void __iomem *base_addr;
-static inline void s3c2410_ts_connect(void)
+static void s3c2410_ts_connect(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
@@ -118,53 +134,62 @@ static inline void s3c2410_ts_connect(void)
static void touch_timer_fire(unsigned long data)
{
- unsigned long data0;
- unsigned long data1;
- int updown;
+ int area = 0;
- data0 = readl(base_addr + S3C2410_ADCDAT0);
- data1 = readl(base_addr + S3C2410_ADCDAT1);
+ /* has he lifted the stylus? */
- updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) &&
- (!(data1 & S3C2410_ADCDAT0_UPDOWN));
+ if ((readl(base_addr + S3C2410_ADCDAT0) &
+ readl(base_addr + S3C2410_ADCDAT1)) & S3C2410_ADCDAT0_UPDOWN) {
- if (updown) {
+ /* he's stopped touching */
if (ts.tsf[0])
- (ts.tsf[0]->api->scale)(ts.tsf[0], &ts.coords[0]);
+ (ts.tsf[0]->api->clear)(ts.tsf[0]);
-#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
- {
- struct timeval tv;
+ input_report_key(ts.dev, BTN_TOUCH, 0);
+ input_report_abs(ts.dev, ABS_PRESSURE, 0);
+ input_sync(ts.dev);
- do_gettimeofday(&tv);
- printk(DEBUG_LVL "T:%06d, X:%03ld, Y:%03ld\n",
- (int)tv.tv_usec, ts.coords[0], ts.coords[1]);
- }
-#endif
+ printk(KERN_INFO "up\n");
- input_report_abs(ts.dev, ABS_X, ts.coords[0]);
- input_report_abs(ts.dev, ABS_Y, ts.coords[1]);
+ ts.area.last_area = 0;
+ ts.running = 0;
- input_report_key(ts.dev, BTN_TOUCH, 1);
- input_report_abs(ts.dev, ABS_PRESSURE, 1);
- input_sync(ts.dev);
+ writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
- writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
- base_addr+S3C2410_ADCTSC);
- writel(readl(base_addr+S3C2410_ADCCON) |
- S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
- } else {
+ return;
+ }
- if (ts.tsf[0])
- (ts.tsf[0]->api->clear)(ts.tsf[0]);
+ /* no, we are still "down" */
- input_report_key(ts.dev, BTN_TOUCH, 0);
- input_report_abs(ts.dev, ABS_PRESSURE, 0);
- input_sync(ts.dev);
+ if (ts.tsf[0])
+ area = ts_filter_4node_compute(ts.tsf[0], &ts.area,
+ &ts.coords[0]);
+ printk(KERN_INFO "%d\n", area);
+ input_report_abs(ts.dev, ABS_PRESSURE, area);
- writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
+#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
+ {
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+ printk(DEBUG_LVL "T:%06d, X:%03ld, Y:%03ld\n",
+ (int)tv.tv_usec, ts.coords[0], ts.coords[1]);
}
+#endif
+
+ input_report_key(ts.dev, BTN_TOUCH, 1);
+ input_report_abs(ts.dev, ABS_X, ts.coords[0]);
+ input_report_abs(ts.dev, ABS_Y, ts.coords[1]);
+
+ input_sync(ts.dev);
+
+ /* start another ADC action */
+
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
+ base_addr+S3C2410_ADCTSC);
+ writel(readl(base_addr+S3C2410_ADCCON) |
+ S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
}
static struct timer_list touch_timer =
@@ -172,52 +197,88 @@ static struct timer_list touch_timer =
static irqreturn_t stylus_updown(int irq, void *dev_id)
{
- unsigned long data0;
- unsigned long data1;
- int updown;
-
- data0 = readl(base_addr+S3C2410_ADCDAT0);
- data1 = readl(base_addr+S3C2410_ADCDAT1);
-
- updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) &&
- (!(data1 & S3C2410_ADCDAT0_UPDOWN));
-
- /* TODO we should never get an interrupt with updown set while
- * the timer is running, but maybe we ought to verify that the
- * timer isn't running anyways. */
-
- if (updown)
- touch_timer_fire(0);
+ if (!(((readl(base_addr + S3C2410_ADCDAT0) &
+ readl(base_addr + S3C2410_ADCDAT1)) & S3C2410_ADCDAT0_UPDOWN)) &&
+ !ts.running) {
+ ts.running = 1;
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
+ base_addr+S3C2410_ADCTSC);
+ writel(readl(base_addr+S3C2410_ADCCON) |
+ S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
+ }
return IRQ_HANDLED;
}
static irqreturn_t stylus_action(int irq, void *dev_id)
{
- /* grab the ADC results */
- ts.coords[0] = readl(base_addr + S3C2410_ADCDAT0) &
+
+ switch(ts_filter_4node_area_sequencer(&ts.area, &ts.coords[0])) {
+
+ case TSF4NS_XMXP_GETYP: /* grab the X Y normal ADC results */
+ ts.coords[0] = readl(base_addr + S3C2410_ADCDAT0) &
S3C2410_ADCDAT0_XPDATA_MASK;
- ts.coords[1] = readl(base_addr + S3C2410_ADCDAT1) &
+ ts.coords[1] = readl(base_addr + S3C2410_ADCDAT1) &
S3C2410_ADCDAT1_YPDATA_MASK;
+ /* because we get X and Y in one step, advance sequencer
+ * past the "get the Y step" it will give us next time
+ */
+ ts_filter_4node_area_sequencer(&ts.area, &ts.coords[0]);
+
+ /* if not doing area measurement next, let's go with X Y */
+ if (ts.area.step == TSF4NS_XMXP_GETYP)
+ break;
+
+ /* set up to get the first area reading
+ * We force power across X- and Y+, then read Y-
+ */
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | READZ2,
+ base_addr + S3C2410_ADCTSC);
+ writel((readl(base_addr + S3C2410_ADCCON) & ~(7 << 3)) |
+ S3C2410_ADCCON_ENABLE_START | (4 << 3), /* Y- */
+ base_addr + S3C2410_ADCCON);
+ return IRQ_HANDLED;
+
+ case TSF4NS_XMYP_GETYM:
+ ts.coords[2] = readl(base_addr + S3C2410_ADCDAT0) &
+ S3C2410_ADCDAT0_XPDATA_MASK;
+ /* set up to get the second area reading
+ * We force power across X- and Y+, then read X+
+ */
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | READZ2,
+ base_addr + S3C2410_ADCTSC);
+ writel((readl(base_addr + S3C2410_ADCCON) & ~(7 << 3)) |
+ S3C2410_ADCCON_ENABLE_START | (7 << 3), /* X+ */
+ base_addr + S3C2410_ADCCON);
+ return IRQ_HANDLED;
+
+ case TSF4NS_XMYP_GETXP:
+ default:
+ ts.coords[3] = readl(base_addr + S3C2410_ADCDAT0) &
+ S3C2410_ADCDAT0_XPDATA_MASK;
- if (!ts.tsf[0]) /* filtering is disabled then use raw directly */
- goto real_sample;
+ ts.area.area_coords_stash[0] = ts.coords[2];
+ ts.area.area_coords_stash[1] = ts.coords[3];
- /* send it to the chain of filters */
- if ((ts.tsf[0]->api->process)(ts.tsf[0], &ts.coords[0]))
- goto real_sample;
+ /* kill power across plates */
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | NODRIVE,
+ base_addr + S3C2410_ADCTSC);
+ break;
+ }
- /*
- * no real sample came out of processing yet,
- * get another raw result to feed it
- */
- writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
+ if (ts.tsf[0] && !(ts.tsf[0]->api->process)(ts.tsf[0], &ts.coords[0])) {
+ /*
+ * no real sample came out of processing yet,
+ * get another raw result to feed it
+ */
+ writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
base_addr + S3C2410_ADCTSC);
- writel(readl(base_addr + S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START,
- base_addr + S3C2410_ADCCON);
- return IRQ_HANDLED;
+ writel(readl(base_addr + S3C2410_ADCCON) |
+ S3C2410_ADCCON_ENABLE_START, base_addr + S3C2410_ADCCON);
+
+ return IRQ_HANDLED;
+ }
-real_sample:
mod_timer(&touch_timer, jiffies + 1);
writel(WAIT4INT(1), base_addr + S3C2410_ADCTSC);
@@ -236,13 +297,13 @@ static int __init s3c2410ts_probe(struct platform_device
*pdev)
struct s3c2410_ts_mach_info *info;
struct input_dev *input_dev;
int ret = 0;
+ int used_coord_dimensions = ARRAY_SIZE(ts.coords);
dev_info(&pdev->dev, "Starting\n");
info = (struct s3c2410_ts_mach_info *)pdev->dev.platform_data;
- if (!info)
- {
+ if (!info) {
dev_err(&pdev->dev, "Hm... too bad: no platform data for ts\n");
return -EINVAL;
}
@@ -303,7 +364,10 @@ static int __init s3c2410ts_probe(struct platform_device
*pdev)
ts.dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);
input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);
- input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);
+ if (info->area_maximum) /* if machine data set it up... */
+ input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 100, 0, 0);
+ else
+ used_coord_dimensions = 2; /* no area, just x and y */
ts.dev->private = &ts;
ts.dev->name = s3c2410ts_name;
@@ -312,10 +376,17 @@ static int __init s3c2410ts_probe(struct platform_device
*pdev)
ts.dev->id.product = 0xBEEF;
ts.dev->id.version = S3C2410TSVERSION;
- /* create the filter chain set up for the 2 coordinates we produce */
+ /* copy the info struct wholesale */
+ ts.info = *info;
+
+ ts.area.test_ratio = info->area_test_ratio;
+ ts.area.min_clip = info->area_minimum;
+ ts.area.max_clip = info->area_maximum;
+
+ /* create the filter chain set up for the 3 coordinates we produce */
ret = ts_filter_create_chain(
(struct ts_filter_api **)&info->filter_sequence,
- &info->filter_config, ts.tsf, ARRAY_SIZE(ts.coords));
+ info->filter_config, ts.tsf, used_coord_dimensions);
if (ret)
dev_info(&pdev->dev, "%d filter(s) initialized\n", ret);
else /* this is OK, just means there won't be any filtering */
diff --git a/drivers/input/touchscreen/ts_filter.c
b/drivers/input/touchscreen/ts_filter.c
index f8b2b2f..9817766 100644
--- a/drivers/input/touchscreen/ts_filter.c
+++ b/drivers/input/touchscreen/ts_filter.c
@@ -55,3 +55,89 @@ void ts_filter_destroy_chain(struct ts_filter **list)
}
}
EXPORT_SYMBOL_GPL(ts_filter_destroy_chain);
+
+enum ts_filter_4node_step
+ts_filter_4node_area_sequencer(struct ts_filter_4node_area *area, int * coords)
+{
+ enum ts_filter_4node_step step = area->step;
+
+ switch (step) {
+ case TSF4NS_XMXP_GETYP: /* normal X coord */
+ area->step = TSF4NS_YMYP_GETXP;
+ break;
+ case TSF4NS_YMYP_GETXP: /* normal Y coord */
+ area->step = TSF4NS_XMXP_GETYP; /* default to go back for X */
+ if (!area->max_clip) /* not used */
+ break;
+ if (!area->test_counter--) {
+ area->test_counter = area->test_ratio;
+ area->step = TSF4NS_XMYP_GETYM; /* do z1 / z2 seq */
+ break;
+ }
+ coords[2] = area->area_coords_stash[0];
+ coords[3] = area->area_coords_stash[1];
+ break;
+ case TSF4NS_XMYP_GETYM: /* special z1 coord for area */
+ area->step = TSF4NS_XMYP_GETXP;
+ break;
+ case TSF4NS_XMYP_GETXP: /* special z2 coord for area */
+ default:
+ area->step = TSF4NS_XMXP_GETYP; /* restart after this one */
+ break;
+ }
+
+ return step;
+}
+EXPORT_SYMBOL_GPL(ts_filter_4node_area_sequencer);
+
+int ts_filter_4node_compute(struct ts_filter *tsf,
+ struct ts_filter_4node_area *area, int * coords)
+{
+ int n;
+
+ if (!tsf || !area)
+ return 0;
+
+ /* get filters to scale their results just before use */
+ (tsf->api->scale)(tsf, coords);
+
+ if (!area->max_clip)
+ return 0;
+
+ /* we didn't get fresh area coords this time, use last computed */
+ if (area->test_counter != area->test_ratio)
+ return area->last_area;
+
+ /* avoid divide by zero */
+ if (!coords[2]) {
+ area->last_area = 100;
+
+ return area->last_area;
+ }
+
+ n = coords[0];
+ if (!n)
+ n = 1;
+
+ /* compute area depressed */
+// area->last_area = ((950 * coords[0]) / ((((1024 * coords[3]) /
coords[2]) - 1024)));
+ area->last_area = ((100 * coords[3]) / coords[2]);
+
+ printk(KERN_INFO "coords[0]=%d, coords[2]=%d, coords[3]=%d, area =
%d\n",
+ coords[0], coords[2], coords[3], area->last_area);
+
+ /* clip the area */
+ if (area->last_area < area->min_clip)
+ area->last_area = area->min_clip;
+ if (area->last_area > area->max_clip)
+ area->last_area = area->max_clip;
+
+ /* scale it up to 1 - 100 */
+ area->last_area = 100 - ((100 * (area->last_area - area->min_clip)) /
+ (area->max_clip - area->min_clip));
+ if (area->last_area < 1)
+ area->last_area = 1;
+
+ return area->last_area;
+}
+EXPORT_SYMBOL_GPL(ts_filter_4node_compute);
diff --git a/include/asm-arm/arch-s3c2410/ts.h
b/include/asm-arm/arch-s3c2410/ts.h
index ffd33d2..09633f7 100644
--- a/include/asm-arm/arch-s3c2410/ts.h
+++ b/include/asm-arm/arch-s3c2410/ts.h
@@ -21,6 +21,10 @@
struct s3c2410_ts_mach_info {
int delay;
int presc;
+ int area_test_ratio;
+ int area_minimum;
+ int area_maximum;
+
/* array of pointers to filter APIs we want to use, in order
* ends on first NULL, all NULL is OK
*/
diff --git a/include/linux/ts_filter.h b/include/linux/ts_filter.h
index 7262bba..b4a5831 100644
--- a/include/linux/ts_filter.h
+++ b/include/linux/ts_filter.h
@@ -38,6 +38,25 @@ struct ts_filter {
int coords[MAX_TS_FILTER_COORDS];
};
+enum ts_filter_4node_step {
+ TSF4NS_XMXP_GETYP,
+ TSF4NS_YMYP_GETXP,
+ TSF4NS_XMYP_GETYM,
+ TSF4NS_XMYP_GETXP,
+};
+
+struct ts_filter_4node_area {
+ int test_ratio;
+
+ int test_counter;
+ int min_clip;
+ int max_clip;
+ int area_coords_stash[2];
+
+ enum ts_filter_4node_step step;
+ int last_area;
+};
+
/*
* helper to create a filter chain from array of API pointers and
* array of config ints... leaves pointers to created filters in list
@@ -51,3 +70,11 @@ extern int ts_filter_create_chain(struct ts_filter_api
**api, void **config,
extern void ts_filter_destroy_chain(struct ts_filter **list);
#endif
+
+/* helpers to compute pressure from 4-pin touchscreen */
+
+extern enum ts_filter_4node_step
+ts_filter_4node_area_sequencer(struct ts_filter_4node_area *area, int *
coords);
+
+extern int ts_filter_4node_compute(struct ts_filter *tsf,
+ struct ts_filter_4node_area *area, int * coords);
_______________________________________________
devel mailing list
[email protected]
https://lists.openmoko.org/mailman/listinfo/devel