summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2008-10-08 23:18:49 +0200
committerHenrik Rydberg <rydberg@euromail.se>2008-10-08 23:18:49 +0200
commit4e9ef6f50ac1df020d572924dd57304655fb535d (patch)
treed69870cdd4d6a318b2ea2f7c2f5a81bac4b53100
parente018e95b0785ba2ee0e219cd0b59ca58eeeeb9f3 (diff)
bcm5974 (0.51) unstable; urgency=low
* Fine-tuned signal-to-noise ratio, smoother mouse motion. * Interrupt code got minor simplifications. * GFP_ATOMIC completetly removed. -- Henrik Rydberg <rydberg@euromail.se> Mon, 07 Jul 2008 18:09:39 +0200
-rw-r--r--CHANGES62
-rw-r--r--bcm5974.c114
-rw-r--r--dkms.conf2
3 files changed, 114 insertions, 64 deletions
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..cd46743
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,62 @@
107JUL2008 version 0.51
2----------------------
3
4Fine-tuned signal-to-noise ratio, smoother mouse motion.
5Interrupt code got minor simplifications.
6GFP_ATOMIC completetly removed.
7
806JUL2008 version 0.5
9----------------------
10
11Working palm detection, changes for kernel.org, dkms introduced.
12
1301JUL2008 version 0.42
14----------------------
15
16First button click registered, pre/post-reset added.
17
1829JUN2008 version 0.41
19----------------------
20
21The reset_resume kernel function added.
22
2329JUN2008 version 0.4
24----------------------
25
26Both finger pressure and width reported.
27
2827JUN2008 version 0.31
29----------------------
30
31Administrative changes for kernel.org.
32
3327JUN2008 version 0.3
34----------------------
35
36Explicit device structure, use all packages.
37
3827JUN2008 version 0.23
39----------------------
40
41Finger release not reported properly.
42
4326JUN2008 version 0.22
44----------------------
45
46ABS coordinates more stable with synaptics.
47
4825JUN2008 version 0.21
49----------------------
50
51Fixed the relative coordinate scaling.
52
5325JUN2008 version 0.2
54----------------------
55
56Misinterpreted pressure input, noise reduction.
57
5824JUN2008 version 0.1
59----------------------
60
61First version.
62
diff --git a/bcm5974.c b/bcm5974.c
index a7f070f..bc00a38 100644
--- a/bcm5974.c
+++ b/bcm5974.c
@@ -127,6 +127,7 @@ struct tp_data {
127/* device-specific parameters */ 127/* device-specific parameters */
128struct atp_params { 128struct atp_params {
129 int dim; /* logical dimension */ 129 int dim; /* logical dimension */
130 int fuzz; /* logical noise value */
130 int devmin; /* device minimum reading */ 131 int devmin; /* device minimum reading */
131 int devmax; /* device maximum reading */ 132 int devmax; /* device maximum reading */
132}; 133};
@@ -144,15 +145,6 @@ struct atp_config {
144 struct atp_params y; /* vertical limits */ 145 struct atp_params y; /* vertical limits */
145}; 146};
146 147
147/* logical trackpad state */
148struct tp_state {
149 int pressure; /* finger pressure value */
150 int width; /* finger width value */
151 int abs_x; /* absolute x coordinate */
152 int abs_y; /* absolute y coordinate */
153 int fingers; /* number of fingers on trackpad */
154};
155
156/* logical device structure */ 148/* logical device structure */
157struct atp { 149struct atp {
158 char phys[64]; 150 char phys[64];
@@ -163,11 +155,8 @@ struct atp {
163 int suspended; /* >0: suspended, else open */ 155 int suspended; /* >0: suspended, else open */
164 struct urb *bt_urb; /* button usb request block */ 156 struct urb *bt_urb; /* button usb request block */
165 struct bt_data *bt_data; /* button transferred data */ 157 struct bt_data *bt_data; /* button transferred data */
166 unsigned bt_prev_state; /* logical button previous state */
167 unsigned bt_state; /* logical button state */
168 struct urb *tp_urb; /* trackpad usb request block */ 158 struct urb *tp_urb; /* trackpad usb request block */
169 struct tp_data *tp_data; /* trackpad transferred data */ 159 struct tp_data *tp_data; /* trackpad transferred data */
170 struct tp_state tp_state; /* logical trackpad state */
171 unsigned tp_valid; /* trackpad sensors valid */ 160 unsigned tp_valid; /* trackpad sensors valid */
172}; 161};
173 162
@@ -176,7 +165,11 @@ struct atp {
176#define DIM_WIDTH 16 /* maximum finger width */ 165#define DIM_WIDTH 16 /* maximum finger width */
177#define DIM_X 1280 /* maximum trackpad x value */ 166#define DIM_X 1280 /* maximum trackpad x value */
178#define DIM_Y 800 /* maximum trackpad y value */ 167#define DIM_Y 800 /* maximum trackpad y value */
179#define SNRATIO 50 /* signal to noise ratio */ 168
169/* logical signal quality */
170#define SN_PRESSURE 40 /* pressure signal-to-noise ratio */
171#define SN_WIDTH 100 /* width signal-to-noise ratio */
172#define SN_COORD 250 /* coordinate signal-to-noise ratio */
180 173
181/* device constants */ 174/* device constants */
182static const struct atp_config atp_config_table[] = { 175static const struct atp_config atp_config_table[] = {
@@ -186,10 +179,10 @@ static const struct atp_config atp_config_table[] = {
186 ATP_WELLSPRING_JIS, 179 ATP_WELLSPRING_JIS,
187 0x84, sizeof(struct bt_data), 180 0x84, sizeof(struct bt_data),
188 0x81, sizeof(struct tp_data), 181 0x81, sizeof(struct tp_data),
189 { DIM_PRESSURE, 0, 256 }, 182 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
190 { DIM_WIDTH, 0, 2048 }, 183 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
191 { DIM_X, -4824, 5342 }, 184 { DIM_X, DIM_X / SN_COORD, -4824, 5342 },
192 { DIM_Y, -172, 5820 } 185 { DIM_Y, DIM_Y / SN_COORD, -172, 5820 }
193 }, 186 },
194 { 187 {
195 ATP_WELLSPRING2_ANSI, 188 ATP_WELLSPRING2_ANSI,
@@ -197,10 +190,10 @@ static const struct atp_config atp_config_table[] = {
197 ATP_WELLSPRING2_JIS, 190 ATP_WELLSPRING2_JIS,
198 0x84, sizeof(struct bt_data), 191 0x84, sizeof(struct bt_data),
199 0x81, sizeof(struct tp_data), 192 0x81, sizeof(struct tp_data),
200 { DIM_PRESSURE, 0, 256 }, 193 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
201 { DIM_WIDTH, 0, 2048 }, 194 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
202 { DIM_X, -4824, 5342 }, 195 { DIM_X, DIM_X / SN_COORD, -4824, 5342 },
203 { DIM_Y, -172, 5820 } 196 { DIM_Y, DIM_Y / SN_COORD, -172, 5820 }
204 }, 197 },
205 {} 198 {}
206}; 199};
@@ -236,45 +229,52 @@ static inline int int2bound(const struct atp_params *p, int x)
236 return s < 0 ? 0 : s >= p->dim ? p->dim - 1 : s; 229 return s < 0 ? 0 : s >= p->dim ? p->dim - 1 : s;
237} 230}
238 231
239/* convert button data to logical button state */ 232/* report button data as logical button state */
240static int compute_bt_state(struct atp *dev, int size) 233static int report_bt_state(struct atp *dev, int size)
241{ 234{
242 if (size != sizeof(struct bt_data)) 235 if (size != sizeof(struct bt_data))
243 return -EIO; 236 return -EIO;
244 237
245 dev->bt_prev_state = dev->bt_state; 238 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
246 dev->bt_state = dev->bt_data->button;
247 239
248 return 0; 240 return 0;
249} 241}
250 242
251/* convert trackpad data to logical trackpad state */ 243/* report trackpad data as logical trackpad state */
252static int compute_tp_state(struct atp *dev, int size) 244static int report_tp_state(struct atp *dev, int size)
253{ 245{
254 const struct atp_config *c = &dev->cfg; 246 const struct atp_config *c = &dev->cfg;
255 const struct tp_finger *f = dev->tp_data->finger; 247 const struct tp_finger *f = dev->tp_data->finger;
256 const int fingers = (size - 26) / 28; 248 const int fingers = (size - 26) / 28;
257 struct tp_state *s = &dev->tp_state; 249 int p, w, x, y, n;
258 250
259 if (size < 26 || (size - 26) % 28 != 0) 251 if (size < 26 || (size - 26) % 28 != 0)
260 return -EIO; 252 return -EIO;
261 253
262 if (!fingers) { 254 if (!fingers) {
263 s->pressure = 0; 255 input_report_abs(dev->input, ABS_PRESSURE, 0);
264 s->fingers = 0; 256 input_report_key(dev->input, BTN_TOOL_FINGER, false);
257 input_report_key(dev->input, BTN_TOOL_DOUBLETAP, false);
258 input_report_key(dev->input, BTN_TOOL_TRIPLETAP, false);
265 return 0; 259 return 0;
266 } 260 }
267 261
268 dprintk(9, "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d f: %d\n", 262 p = raw2int(f->force_major);
269 raw2int(f->force_major), raw2int(f->size_major), 263 w = raw2int(f->size_major);
270 raw2int(f->abs_x), raw2int(f->abs_y), fingers); 264 x = raw2int(f->abs_x);
271 265 y = raw2int(f->abs_y);
272 s->pressure = int2bound(&c->p, raw2int(f->force_major)); 266 n = p > 0 ? fingers : 0;
273 s->width = int2bound(&c->w, raw2int(f->size_major)); 267
274 s->abs_x = int2bound(&c->x, raw2int(f->abs_x) - c->x.devmin); 268 dprintk(9, "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
275 s->abs_y = int2bound(&c->y, c->y.devmax - raw2int(f->abs_y)); 269 p, w, x, y, n);
276 s->fingers = s->pressure > 0 ? fingers : 0; 270
277 271 input_report_abs(dev->input, ABS_PRESSURE, int2bound(&c->p, p));
272 input_report_abs(dev->input, ABS_TOOL_WIDTH, int2bound(&c->w, w));
273 input_report_abs(dev->input, ABS_X, int2bound(&c->x, x - c->x.devmin));
274 input_report_abs(dev->input, ABS_Y, int2bound(&c->y, c->y.devmax - y));
275 input_report_key(dev->input, BTN_TOOL_FINGER, n == 1);
276 input_report_key(dev->input, BTN_TOOL_DOUBLETAP, n == 2);
277 input_report_key(dev->input, BTN_TOOL_TRIPLETAP, n > 2);
278 return 0; 278 return 0;
279} 279}
280 280
@@ -376,20 +376,16 @@ static void irq_button(struct urb *urb)
376 goto exit; 376 goto exit;
377 } 377 }
378 378
379 if (compute_bt_state(dev, dev->bt_urb->actual_length)) { 379 if (report_bt_state(dev, dev->bt_urb->actual_length)) {
380 dprintk(1, "bcm5974: bad button package, length: %d)\n", 380 dprintk(1, "bcm5974: bad button package, length: %d)\n",
381 dev->bt_urb->actual_length); 381 dev->bt_urb->actual_length);
382 goto exit; 382 goto exit;
383 } 383 }
384 384
385 /* only report button state changes */ 385 input_sync(dev->input);
386 if (dev->bt_state != dev->bt_prev_state) {
387 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
388 input_sync(dev->input);
389 }
390 386
391exit: 387exit:
392 error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC); 388 error = usb_submit_urb(dev->bt_urb, GFP_KERNEL);
393 if (error) 389 if (error)
394 err("bcm5974: button urb failed: %d", error); 390 err("bcm5974: button urb failed: %d", error);
395} 391}
@@ -397,7 +393,6 @@ exit:
397static void irq_trackpad(struct urb *urb) 393static void irq_trackpad(struct urb *urb)
398{ 394{
399 struct atp *dev = urb->context; 395 struct atp *dev = urb->context;
400 struct tp_state *state = &dev->tp_state;
401 int error; 396 int error;
402 397
403 switch (urb->status) { 398 switch (urb->status) {
@@ -420,23 +415,16 @@ static void irq_trackpad(struct urb *urb)
420 goto exit; 415 goto exit;
421 } 416 }
422 417
423 if (compute_tp_state(dev, dev->tp_urb->actual_length)) { 418 if (report_tp_state(dev, dev->tp_urb->actual_length)) {
424 dprintk(1, "bcm5974: bad trackpad package, length: %d)\n", 419 dprintk(1, "bcm5974: bad trackpad package, length: %d)\n",
425 dev->tp_urb->actual_length); 420 dev->tp_urb->actual_length);
426 goto exit; 421 goto exit;
427 } 422 }
428 423
429 input_report_abs(dev->input, ABS_PRESSURE, state->pressure);
430 input_report_abs(dev->input, ABS_TOOL_WIDTH, state->width);
431 input_report_abs(dev->input, ABS_X, state->abs_x);
432 input_report_abs(dev->input, ABS_Y, state->abs_y);
433 input_report_key(dev->input, BTN_TOOL_FINGER, state->fingers == 1);
434 input_report_key(dev->input, BTN_TOOL_DOUBLETAP, state->fingers == 2);
435 input_report_key(dev->input, BTN_TOOL_TRIPLETAP, state->fingers > 2);
436 input_sync(dev->input); 424 input_sync(dev->input);
437 425
438exit: 426exit:
439 error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC); 427 error = usb_submit_urb(dev->tp_urb, GFP_KERNEL);
440 if (error) 428 if (error)
441 err("bcm5974: trackpad urb failed: %d", error); 429 err("bcm5974: trackpad urb failed: %d", error);
442} 430}
@@ -446,9 +434,9 @@ static int atp_open(struct input_dev *input)
446 struct atp *dev = input_get_drvdata(input); 434 struct atp *dev = input_get_drvdata(input);
447 435
448 if (!dev->open) { 436 if (!dev->open) {
449 if (usb_submit_urb(dev->bt_urb, GFP_ATOMIC)) 437 if (usb_submit_urb(dev->bt_urb, GFP_KERNEL))
450 goto error; 438 goto error;
451 if (usb_submit_urb(dev->tp_urb, GFP_ATOMIC)) 439 if (usb_submit_urb(dev->tp_urb, GFP_KERNEL))
452 goto err_free_bt_urb; 440 goto err_free_bt_urb;
453 } 441 }
454 442
@@ -557,13 +545,13 @@ static int atp_probe(struct usb_interface *iface,
557 545
558 set_bit(EV_ABS, input_dev->evbit); 546 set_bit(EV_ABS, input_dev->evbit);
559 input_set_abs_params(input_dev, ABS_PRESSURE, 547 input_set_abs_params(input_dev, ABS_PRESSURE,
560 0, cfg->p.dim, cfg->p.dim / SNRATIO, 0); 548 0, cfg->p.dim, cfg->p.fuzz, 0);
561 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 549 input_set_abs_params(input_dev, ABS_TOOL_WIDTH,
562 0, cfg->w.dim, cfg->w.dim / SNRATIO, 0); 550 0, cfg->w.dim, cfg->w.fuzz, 0);
563 input_set_abs_params(input_dev, ABS_X, 551 input_set_abs_params(input_dev, ABS_X,
564 0, cfg->x.dim, cfg->x.dim / SNRATIO, 0); 552 0, cfg->x.dim, cfg->x.fuzz, 0);
565 input_set_abs_params(input_dev, ABS_Y, 553 input_set_abs_params(input_dev, ABS_Y,
566 0, cfg->y.dim, cfg->y.dim / SNRATIO, 0); 554 0, cfg->y.dim, cfg->y.fuzz, 0);
567 555
568 set_bit(EV_KEY, input_dev->evbit); 556 set_bit(EV_KEY, input_dev->evbit);
569 set_bit(BTN_TOOL_FINGER, input_dev->keybit); 557 set_bit(BTN_TOOL_FINGER, input_dev->keybit);
diff --git a/dkms.conf b/dkms.conf
index 89d112e..615cc69 100644
--- a/dkms.conf
+++ b/dkms.conf
@@ -1,5 +1,5 @@
1PACKAGE_NAME="bcm5974" 1PACKAGE_NAME="bcm5974"
2PACKAGE_VERSION="0.5" 2PACKAGE_VERSION="0.51"
3MAKE[0]="make -C ${kernel_source_dir} 3MAKE[0]="make -C ${kernel_source_dir}
4 SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules" 4 SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
5BUILT_MODULE_NAME[0]="bcm5974" 5BUILT_MODULE_NAME[0]="bcm5974"