diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2008-10-08 23:18:49 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2008-10-08 23:18:49 +0200 |
| commit | 4e9ef6f50ac1df020d572924dd57304655fb535d (patch) | |
| tree | d69870cdd4d6a318b2ea2f7c2f5a81bac4b53100 | |
| parent | e018e95b0785ba2ee0e219cd0b59ca58eeeeb9f3 (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-- | CHANGES | 62 | ||||
| -rw-r--r-- | bcm5974.c | 114 | ||||
| -rw-r--r-- | dkms.conf | 2 |
3 files changed, 114 insertions, 64 deletions
| @@ -0,0 +1,62 @@ | |||
| 1 | 07JUL2008 version 0.51 | ||
| 2 | ---------------------- | ||
| 3 | |||
| 4 | Fine-tuned signal-to-noise ratio, smoother mouse motion. | ||
| 5 | Interrupt code got minor simplifications. | ||
| 6 | GFP_ATOMIC completetly removed. | ||
| 7 | |||
| 8 | 06JUL2008 version 0.5 | ||
| 9 | ---------------------- | ||
| 10 | |||
| 11 | Working palm detection, changes for kernel.org, dkms introduced. | ||
| 12 | |||
| 13 | 01JUL2008 version 0.42 | ||
| 14 | ---------------------- | ||
| 15 | |||
| 16 | First button click registered, pre/post-reset added. | ||
| 17 | |||
| 18 | 29JUN2008 version 0.41 | ||
| 19 | ---------------------- | ||
| 20 | |||
| 21 | The reset_resume kernel function added. | ||
| 22 | |||
| 23 | 29JUN2008 version 0.4 | ||
| 24 | ---------------------- | ||
| 25 | |||
| 26 | Both finger pressure and width reported. | ||
| 27 | |||
| 28 | 27JUN2008 version 0.31 | ||
| 29 | ---------------------- | ||
| 30 | |||
| 31 | Administrative changes for kernel.org. | ||
| 32 | |||
| 33 | 27JUN2008 version 0.3 | ||
| 34 | ---------------------- | ||
| 35 | |||
| 36 | Explicit device structure, use all packages. | ||
| 37 | |||
| 38 | 27JUN2008 version 0.23 | ||
| 39 | ---------------------- | ||
| 40 | |||
| 41 | Finger release not reported properly. | ||
| 42 | |||
| 43 | 26JUN2008 version 0.22 | ||
| 44 | ---------------------- | ||
| 45 | |||
| 46 | ABS coordinates more stable with synaptics. | ||
| 47 | |||
| 48 | 25JUN2008 version 0.21 | ||
| 49 | ---------------------- | ||
| 50 | |||
| 51 | Fixed the relative coordinate scaling. | ||
| 52 | |||
| 53 | 25JUN2008 version 0.2 | ||
| 54 | ---------------------- | ||
| 55 | |||
| 56 | Misinterpreted pressure input, noise reduction. | ||
| 57 | |||
| 58 | 24JUN2008 version 0.1 | ||
| 59 | ---------------------- | ||
| 60 | |||
| 61 | First version. | ||
| 62 | |||
| @@ -127,6 +127,7 @@ struct tp_data { | |||
| 127 | /* device-specific parameters */ | 127 | /* device-specific parameters */ |
| 128 | struct atp_params { | 128 | struct 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 */ | ||
| 148 | struct 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 */ |
| 157 | struct atp { | 149 | struct 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 */ |
| 182 | static const struct atp_config atp_config_table[] = { | 175 | static 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 */ |
| 240 | static int compute_bt_state(struct atp *dev, int size) | 233 | static 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 */ |
| 252 | static int compute_tp_state(struct atp *dev, int size) | 244 | static 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 | ||
| 391 | exit: | 387 | exit: |
| 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: | |||
| 397 | static void irq_trackpad(struct urb *urb) | 393 | static 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 | ||
| 438 | exit: | 426 | exit: |
| 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); |
| @@ -1,5 +1,5 @@ | |||
| 1 | PACKAGE_NAME="bcm5974" | 1 | PACKAGE_NAME="bcm5974" |
| 2 | PACKAGE_VERSION="0.5" | 2 | PACKAGE_VERSION="0.51" |
| 3 | MAKE[0]="make -C ${kernel_source_dir} | 3 | MAKE[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" |
| 5 | BUILT_MODULE_NAME[0]="bcm5974" | 5 | BUILT_MODULE_NAME[0]="bcm5974" |
