aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware-utils/src/zynos.h
blob: aa25deb4749cb3bf0b4a4ea81ec9c1e5b7d5f11f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
 *  $Id$
 *
 *  Copyright (C) 2007-2008 OpenWrt.org
 *  Copyright (C) 2007-2008 Gabor Juhos <juhosg at openwrt.org>
 *
 *  This code was based on the information of the ZyXEL's firmware
 *  image format written by Kolja Waschk, can be found at:
 *  http://www.ixo.de/info/zyxel_uclinux
 *
 *  This program 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.
 *
 */

#ifndef _ZYNOS_H
#define _ZYNOS_H

#define BOOTBASE_NAME_LEN	32
#define BOOTBASE_MAC_LEN	6
#define BOOTBASE_FEAT_LEN	22

#define BOOTEXT_DEF_SIZE	0x18000

struct zyn_bootbase_info {
	char		vendor[BOOTBASE_NAME_LEN]; /* Vendor name */
	char		model[BOOTBASE_NAME_LEN]; /* Model name */
	uint32_t	bootext_addr;	/* absolute address of the Boot Extension */
	uint16_t	res0;		/* reserved/unknown */
	uint8_t		sys_type;	/* system type */
	uint8_t		res1;		/* reserved/unknown */
	uint16_t	model_id;	/* model id */
	uint8_t		feat_other[BOOTBASE_FEAT_LEN]; /* other feature bits */
	uint8_t		feat_main;	/* main feature bits */
	uint8_t		res2;		/* reserved/unknown */
	uint8_t		mac[BOOTBASE_MAC_LEN]; /* mac address */
	uint8_t		country;	/* default country code */
	uint8_t		dbgflag;	/* debug flag */
} __attribute__((packed));

#define ROMBIN_SIG_LEN	3
#define ROMBIN_VER_LEN	15

struct zyn_rombin_hdr {
	uint32_t	addr;		/* load address of the object */
	uint16_t	res0;		/* unknown/unused */
	char		sig[ROMBIN_SIG_LEN];	/* magic, must be "SIG" */
	uint8_t		type;		/* type of the object */
	uint32_t	osize;		/* size of the uncompressed data */
	uint32_t	csize;		/* size of the compressed data */
	uint8_t		flags;		/* various flags */
	uint8_t		res1;		/* unknown/unused */
	uint16_t	ocsum;		/* csum of the uncompressed data */
	uint16_t	ccsum;		/* csum of the compressed data */
	char		ver[ROMBIN_VER_LEN];
	uint32_t	mmap_addr;	/* address of the Memory Map Table*/
	uint32_t	res2;		/* unknown/unused*/
	uint8_t		res3;		/* unknown/unused*/
} __attribute__((packed));

#define ROMBIN_SIGNATURE	"SIG"

/* Rombin flag bits */
#define ROMBIN_FLAG_01		0x01
#define ROMBIN_FLAG_02		0x02
#define ROMBIN_FLAG_04		0x04
#define ROMBIN_FLAG_08		0x08
#define ROMBIN_FLAG_10		0x10
#define ROMBIN_FLAG_CCSUM	0x20	/* compressed checksum is valid */
#define ROMBIN_FLAG_OCSUM	0x40	/* original checksum is valid */
#define ROMBIN_FLAG_COMPRESSED	0x80	/* the binary is compressed */

/* Object types */
#define OBJECT_TYPE_ROMIMG	0x01
#define OBJECT_TYPE_ROMBOOT	0x02
#define OBJECT_TYPE_BOOTEXT	0x03
#define OBJECT_TYPE_ROMBIN	0x04
#define OBJECT_TYPE_ROMDIR	0x05
#define OBJECT_TYPE_6		0x06
#define OBJECT_TYPE_ROMMAP	0x07
#define OBJECT_TYPE_RAM		0x80
#define OBJECT_TYPE_RAMCODE	0x81
#define OBJECT_TYPE_RAMBOOT	0x82

/*
 * Memory Map Table header
 */
struct zyn_mmt_hdr {
	uint16_t	count;
	uint32_t	user_start;
	uint32_t	user_end;
	uint16_t	csum;
	uint8_t		res[12];
} __attribute__((packed));

#define OBJECT_NAME_LEN		8

struct zyn_mmt_item {
	uint8_t		type;	/* type of the object */
	uint8_t		name[OBJECT_NAME_LEN]; /* name of the object */
	uint8_t		res0;	/* unused/unknown */
	uint32_t	addr;
	uint32_t	size;	/* size of the object */
	uint8_t		res1[3]; /* unused/unknown */
	uint8_t		type2;
} __attribute__((packed));

/*
 * Vendor IDs
 */
#define ZYNOS_VENDOR_ID_ZYXEL	0
#define ZYNOS_VENDOR_ID_NETGEAR	1
#define ZYNOS_VENDOR_ID_DLINK	2
#define ZYNOS_VENDOR_ID_03	3
#define ZYNOS_VENDOR_ID_LUCENT	4
#define ZYNOS_VENDOR_ID_O2	10

/*
 * Model IDs (in big-endian format)
 */
#define MID(x)	(((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8)

/*
 * Infineon/ADMtek ADM5120 based models
 */
#define ZYNOS_MODEL_ES_2024A		MID(  221)
#define ZYNOS_MODEL_ES_2024PWR		MID( 4097)
#define ZYNOS_MODEL_ES_2108		MID(61952)
#define ZYNOS_MODEL_ES_2108_F		MID(44801)
#define ZYNOS_MODEL_ES_2108_G		MID(62208)
#define ZYNOS_MODEL_ES_2108_LC		MID(64512)
#define ZYNOS_MODEL_ES_2108PWR		MID(62464)
#define ZYNOS_MODEL_HS_100		MID(61855)
#define ZYNOS_MODEL_HS_100W		ZYNOS_MODEL_HS_100
#define ZYNOS_MODEL_P_334		MID(62879)
#define ZYNOS_MODEL_P_334U		MID(56735)
#define ZYNOS_MODEL_P_334W		MID(62367)
#define ZYNOS_MODEL_P_334WH		MID(57344)
#define ZYNOS_MODEL_P_334WHD		MID(57600)
#define ZYNOS_MODEL_P_334WT		MID(61343)
#define ZYNOS_MODEL_P_335		MID(60831)
#define ZYNOS_MODEL_P_335PLUS		MID( 9472)
#define ZYNOS_MODEL_P_335U		MID(56479)
#define ZYNOS_MODEL_P_335WT		ZYNOS_MODEL_P_335

/*
 * Texas Instruments AR7 based models
 */
#define ZYNOS_MODEL_P_2602H_61C		MID( 3229)
#define ZYNOS_MODEL_P_2602H_63C		MID( 3485)
#define ZYNOS_MODEL_P_2602H_D1A		/* n.a. */
#define ZYNOS_MODEL_P_2602H_D3A		/* n.a. */
#define ZYNOS_MODEL_P_2602HW_61C	/* n.a. */
#define ZYNOS_MODEL_P_2602HW_63		/* n.a. */
#define ZYNOS_MODEL_P_2602HW_63C	ZYNOS_MODEL_P_2602H_63C
#define ZYNOS_MODEL_P_2602HW_D1A	MID( 6301)
#define ZYNOS_MODEL_P_2602HW_D3A	/* n.a. */
#define ZYNOS_MODEL_P_2602HWL_61	MID( 1181)
#define ZYNOS_MODEL_P_2602HWL_61C	ZYNOS_MODEL_P_2602H_61C
#define ZYNOS_MODEL_P_2602HWL_63C	ZYNOS_MODEL_P_2602H_63C
#define ZYNOS_MODEL_P_2602HWL_D1A	ZYNOS_MODEL_P_2602HW_D1A
#define ZYNOS_MODEL_P_2602HWL_D3A	MID( 7581)
#define ZYNOS_MODEL_P_2602HWN_D7A	MID(30464)
#define ZYNOS_MODEL_P_2602HWNLI_D7A	MID( 6813)

#define ZYNOS_MODEL_P_2602R_61		MID( 2205)
#define ZYNOS_MODEL_P_2602R_63		MID( 3997)
#define ZYNOS_MODEL_P_2602R_D1A		/* n.a. */
#define ZYNOS_MODEL_P_2602R_D3A		/* n.a. */
#define ZYNOS_MODEL_P_2602RL_D1A	MID( 6045)
#define ZYNOS_MODEL_P_2602RL_D3A	MID( 7069)

#define ZYNOS_MODEL_P_660H_61		MID(19346)
#define ZYNOS_MODEL_P_660H_63		MID(22162)
#define ZYNOS_MODEL_P_660H_67		/* n.a. */
#define ZYNOS_MODEL_P_660H_D1		MID( 7066)
#define ZYNOS_MODEL_P_660H_D3		MID(13210)

#define ZYNOS_MODEL_P_660HW_61		ZYNOS_MODEL_P_660H_61
#define ZYNOS_MODEL_P_660HW_63		ZYNOS_MODEL_P_660H_63
#define ZYNOS_MODEL_P_660HW_67		ZYNOS_MODEL_P_660HW_63
#define ZYNOS_MODEL_P_660HW_D1		MID( 9114)
#define ZYNOS_MODEL_P_660HW_D3		MID(12698)

#define ZYNOS_MODEL_P_660R_61		MID(20882)
#define ZYNOS_MODEL_P_660R_61C		MID( 1178)
#define ZYNOS_MODEL_P_660R_63		MID(21138)
#define ZYNOS_MODEL_P_660R_63C		MID(  922)
#define ZYNOS_MODEL_P_660R_67		ZYNOS_MODEL_P_660R_63
#define ZYNOS_MODEL_P_660R_67C		/* n.a. */
#define ZYNOS_MODEL_P_660R_D1		MID( 7322)
#define ZYNOS_MODEL_P_660R_D3		MID(10138)

#define ZYNOS_MODEL_P_661H_61		MID(19346)
#define ZYNOS_MODEL_P_661H_63		MID( 1946)
#define ZYNOS_MODEL_P_661H_D1		MID(10650)
#define ZYNOS_MODEL_P_661H_D3		MID(12442)

#define ZYNOS_MODEL_P_661HW_61		ZYNOS_MODEL_P_661H_61
#define ZYNOS_MODEL_P_661HW_63		ZYNOS_MODEL_P_661H_63
#define ZYNOS_MODEL_P_661HW_D1		MID(10906)
#define ZYNOS_MODEL_P_661HW_D3		MID(14746)

#define ZYNOS_MODEL_P_662H_61		MID(22418)
#define ZYNOS_MODEL_P_662H_63		/* n.a. */
#define ZYNOS_MODEL_P_662H_67		/* n.a. */
#define ZYNOS_MODEL_P_662H_D1		/* n.a. */
#define ZYNOS_MODEL_P_662H_D3		/* n.a. */

#define ZYNOS_MODEL_P_662HW_61		/* n.a. */
#define ZYNOS_MODEL_P_662HW_63		MID(22674)
#define ZYNOS_MODEL_P_662HW_67		/* n.a. */
#define ZYNOS_MODEL_P_662HW_D1		MID(10394)
#define ZYNOS_MODEL_P_662HW_D3		MID(12954)

/* OEM boards */
#define ZYNOS_MODEL_O2SURF		ZYNOS_MODEL_P_2602HWN_D7A

/* Atheros AR2318 based boards */
#define ZYNOS_MODEL_NBG_318S		MID(59392)

#endif /* _ZYNOS_H */
+ ts.tail_raw_fifo = 0; + ts.raw_running_avg.x = 0; + ts.raw_running_avg.y = 0; + ts.flag_previous_exceeded_threshold = 0; +} + + static inline void s3c2410_ts_connect(void) { s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON); @@ -110,47 +147,52 @@ static void touch_timer_fire(unsigned long data) unsigned long data1; int updown; - data0 = readl(base_addr+S3C2410_ADCDAT0); - data1 = readl(base_addr+S3C2410_ADCDAT1); + data0 = readl(base_addr + S3C2410_ADCDAT0); + data1 = readl(base_addr + S3C2410_ADCDAT1); - updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN)); + updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && + (!(data1 & S3C2410_ADCDAT0_UPDOWN)); - if (updown) { - if (ts.count != 0) { - ts.xp >>= ts.shift; - ts.yp >>= ts.shift; + if (updown) { + if (ts.count != 0) { + ts.xp >>= ts.shift; + ts.yp >>= ts.shift; #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.xp, ts.yp); - } + { + struct timeval tv; + + do_gettimeofday(&tv); + printk(DEBUG_LVL "T:%06d, X:%03ld, Y:%03ld\n", + (int)tv.tv_usec, ts.xp, ts.yp); + } #endif - input_report_abs(ts.dev, ABS_X, ts.xp); - input_report_abs(ts.dev, ABS_Y, ts.yp); + input_report_abs(ts.dev, ABS_X, ts.xp); + input_report_abs(ts.dev, ABS_Y, ts.yp); - input_report_key(ts.dev, BTN_TOUCH, 1); - input_report_abs(ts.dev, ABS_PRESSURE, 1); - input_sync(ts.dev); - } + input_report_key(ts.dev, BTN_TOUCH, 1); + input_report_abs(ts.dev, ABS_PRESSURE, 1); + input_sync(ts.dev); + } - ts.xp = 0; - ts.yp = 0; - ts.count = 0; + ts.xp = 0; + ts.yp = 0; + ts.count = 0; - 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 { - ts.count = 0; + 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 { + ts.count = 0; - input_report_key(ts.dev, BTN_TOUCH, 0); - input_report_abs(ts.dev, ABS_PRESSURE, 0); - input_sync(ts.dev); + input_report_key(ts.dev, BTN_TOUCH, 0); + input_report_abs(ts.dev, ABS_PRESSURE, 0); + input_sync(ts.dev); - writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); - } + writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); + } } static struct timer_list touch_timer = @@ -165,7 +207,8 @@ static irqreturn_t stylus_updown(int irq, void *dev_id) data0 = readl(base_addr+S3C2410_ADCDAT0); data1 = readl(base_addr+S3C2410_ADCDAT1); - updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN)); + 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 @@ -180,24 +223,94 @@ static irqreturn_t stylus_updown(int irq, void *dev_id) static irqreturn_t stylus_action(int irq, void *dev_id) { - unsigned long data0; - unsigned long data1; - - data0 = readl(base_addr+S3C2410_ADCDAT0); - data1 = readl(base_addr+S3C2410_ADCDAT1); + unsigned long x; + unsigned long y; + int length = (ts.head_raw_fifo - ts.tail_raw_fifo) & (ts.extent - 1); + int scaled_avg_x = ts.raw_running_avg.x / length; + int scaled_avg_y = ts.raw_running_avg.y / length; + + x = readl(base_addr + S3C2410_ADCDAT0) & S3C2410_ADCDAT0_XPDATA_MASK; + y = readl(base_addr + S3C2410_ADCDAT1) & S3C2410_ADCDAT1_YPDATA_MASK; + + /* we appear to accept every sample into both the running average FIFO + * and the summing average. BUT, if the last sample crossed a + * machine-set threshold, each time we do a beauty contest + * on the new sample comparing if it is closer to the running + * average and the previous sample. If it is closer to the previous + * suspicious sample, we assume the change is real and accept both + * if the new sample has returned to being closer to the average than + * the previous sample, we take the previous sample as an excursion + * and overwrite it in both the running average and summing average. + */ + + if (ts.flag_previous_exceeded_threshold) + /* new one closer to "nonconformist" previous, or average? + * Pythagoras? Who? Don't need it because large excursion + * will be accounted for correctly this way + */ + if ((abs(x - scaled_avg_x) + abs(y - scaled_avg_y)) < + (abs(x - ts.raw_sample_fifo[(ts.head_raw_fifo - 1) & + (ts.extent - 1)].x) + + abs(y - ts.raw_sample_fifo[(ts.head_raw_fifo - 1) & + (ts.extent - 1)].y))) { + /* it's closer to average, reject previous as a one- + * shot excursion, by overwriting it + */ + ts.xp += x - ts.raw_sample_fifo[(ts.head_raw_fifo - 1) & + (ts.extent - 1)].x; + ts.yp += y - ts.raw_sample_fifo[(ts.head_raw_fifo - 1) & + (ts.extent - 1)].y; + ts.raw_sample_fifo[(ts.head_raw_fifo - 1) & + (ts.extent - 1)].x = x; + ts.raw_sample_fifo[(ts.head_raw_fifo - 1) & + (ts.extent - 1)].y = y; + /* no new sample: replaced previous, so we are done */ + goto completed; + } + /* else it was closer to nonconformist previous: it's likely + * a genuine consistent move then. + * Keep previous and add new guy. + */ + + if ((x >= scaled_avg_x - ts.reject_threshold_vs_avg) && + (x <= scaled_avg_x + ts.reject_threshold_vs_avg) && + (y >= scaled_avg_y - ts.reject_threshold_vs_avg) && + (y <= scaled_avg_y + ts.reject_threshold_vs_avg)) + ts.flag_previous_exceeded_threshold = 0; + else + ts.flag_previous_exceeded_threshold = 1; - ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK; - ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK; + /* accepted */ + ts.xp += x; + ts.yp += y; ts.count++; - if (ts.count < (1<<ts.shift)) { - 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 { - mod_timer(&touch_timer, jiffies+1); + /* remove oldest sample from avg when we have full pipeline */ + if (((ts.head_raw_fifo + 1) & (ts.extent - 1)) == ts.tail_raw_fifo) { + ts.raw_running_avg.x -= ts.raw_sample_fifo[ts.tail_raw_fifo].x; + ts.raw_running_avg.y -= ts.raw_sample_fifo[ts.tail_raw_fifo].y; + ts.tail_raw_fifo = (ts.tail_raw_fifo + 1) & (ts.extent - 1); + } + /* always add current sample to fifo and average */ + ts.raw_sample_fifo[ts.head_raw_fifo].x = x; + ts.raw_sample_fifo[ts.head_raw_fifo].y = y; + ts.raw_running_avg.x += x; + ts.raw_running_avg.y += y; + ts.head_raw_fifo = (ts.head_raw_fifo + 1) & (ts.extent - 1); + +completed: + if (ts.count >= (1 << ts.shift)) { + mod_timer(&touch_timer, jiffies + 1); writel(WAIT4INT(1), base_addr+S3C2410_ADCTSC); + goto bail; } + 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); + +bail: return IRQ_HANDLED; } @@ -213,11 +326,11 @@ static int __init s3c2410ts_probe(struct platform_device *pdev) struct s3c2410_ts_mach_info *info; struct input_dev *input_dev; - info = ( struct s3c2410_ts_mach_info *)pdev->dev.platform_data; + info = (struct s3c2410_ts_mach_info *)pdev->dev.platform_data; if (!info) { - printk(KERN_ERR "Hm... too bad : no platform data for ts\n"); + dev_err(&pdev->dev, "Hm... too bad: no platform data for ts\n"); return -EINVAL; } @@ -227,7 +340,7 @@ static int __init s3c2410ts_probe(struct platform_device *pdev) adc_clock = clk_get(NULL, "adc"); if (!adc_clock) { - printk(KERN_ERR "failed to get adc clock source\n"); + dev_err(&pdev->dev, "failed to get adc clock source\n"); return -ENOENT; } clk_enable(adc_clock); @@ -238,7 +351,7 @@ static int __init s3c2410ts_probe(struct platform_device *pdev) base_addr = ioremap(S3C2410_PA_ADC,0x20); if (base_addr == NULL) { - printk(KERN_ERR "Failed to remap register block\n"); + dev_err(&pdev->dev, "Failed to remap register block\n"); return -ENOMEM; } @@ -247,25 +360,26 @@ static int __init s3c2410ts_probe(struct platform_device *pdev) if (!strcmp(pdev->name, "s3c2410-ts")) s3c2410_ts_connect(); - if ((info->presc&0xff) > 0) - writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\ - base_addr+S3C2410_ADCCON); + if ((info->presc & 0xff) > 0) + writel(S3C2410_ADCCON_PRSCEN | + S3C2410_ADCCON_PRSCVL(info->presc&0xFF), + base_addr + S3C2410_ADCCON); else - writel(0,base_addr+S3C2410_ADCCON); + writel(0, base_addr+S3C2410_ADCCON); /* Initialise registers */ - if ((info->delay&0xffff) > 0) - writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY); + if ((info->delay & 0xffff) > 0) + writel(info->delay & 0xffff, base_addr + S3C2410_ADCDLY); - writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); + writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC); /* Initialise input stuff */ memset(&ts, 0, sizeof(struct s3c2410ts)); input_dev = input_allocate_device(); if (!input_dev) { - printk(KERN_ERR "Unable to allocate the input device !!\n"); + dev_err(&pdev->dev, "Unable to allocate the input device\n"); return -ENOMEM; } @@ -284,23 +398,30 @@ static int __init s3c2410ts_probe(struct platform_device *pdev) ts.dev->id.version = S3C2410TSVERSION; ts.shift = info->oversampling_shift; + ts.extent = 1 << info->oversampling_shift; + ts.reject_threshold_vs_avg = info->reject_threshold_vs_avg; + ts.excursion_filter_len = 1 << info->excursion_filter_len_bits; + + ts.raw_sample_fifo = kmalloc(sizeof(struct s3c2410ts_sample) * + ts.excursion_filter_len, GFP_KERNEL); + clear_raw_fifo(); /* Get irqs */ if (request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM, - "s3c2410_action", ts.dev)) { - printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_ADC !\n"); + "s3c2410_action", ts.dev)) { + dev_err(&pdev->dev, "Could not allocate ts IRQ_ADC !\n"); iounmap(base_addr); return -EIO; } if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM, "s3c2410_action", ts.dev)) { - printk(KERN_ERR "s3c2410_ts.c: Could not allocate ts IRQ_TC !\n"); + dev_err(&pdev->dev, "Could not allocate ts IRQ_TC !\n"); free_irq(IRQ_ADC, ts.dev); iounmap(base_addr); return -EIO; } - printk(KERN_INFO "%s successfully loaded\n", s3c2410ts_name); + dev_info(&pdev->dev, "successfully loaded\n"); /* All went ok, so register to the input system */ rc = input_register_device(ts.dev); @@ -328,6 +449,8 @@ static int s3c2410ts_remove(struct platform_device *pdev) adc_clock = NULL; } + kfree(ts.raw_sample_fifo); + input_unregister_device(ts.dev); iounmap(base_addr); @@ -357,17 +480,20 @@ static int s3c2410ts_resume(struct platform_device *pdev) clk_enable(adc_clock); mdelay(1); + clear_raw_fifo(); + enable_irq(IRQ_ADC); enable_irq(IRQ_TC); if ((info->presc&0xff) > 0) - writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\ - base_addr+S3C2410_ADCCON); + writel(S3C2410_ADCCON_PRSCEN | + S3C2410_ADCCON_PRSCVL(info->presc&0xFF), + base_addr+S3C2410_ADCCON); else writel(0,base_addr+S3C2410_ADCCON); /* Initialise registers */ - if ((info->delay&0xffff) > 0) + if ((info->delay & 0xffff) > 0) writel(info->delay & 0xffff, base_addr+S3C2410_ADCDLY); writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC); diff --git a/include/asm-arm/arch-s3c2410/ts.h b/include/asm-arm/arch-s3c2410/ts.h index 593632a..44c1e4b 100644 --- a/include/asm-arm/arch-s3c2410/ts.h +++ b/include/asm-arm/arch-s3c2410/ts.h @@ -17,9 +17,11 @@ #define __ASM_ARM_TS_H struct s3c2410_ts_mach_info { - int delay; - int presc; - int oversampling_shift; + int delay; + int presc; + int oversampling_shift; + int excursion_filter_len_bits; + int reject_threshold_vs_avg; }; void set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info); -- 1.5.6.3