0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #define DEBUG
0030 #include <linux/slab.h>
0031 #include <linux/input.h>
0032 #include <linux/module.h>
0033 #include <linux/serio.h>
0034 #include <linux/libps2.h>
0035 #include <linux/delay.h>
0036 #include <asm/olpc.h>
0037
0038 #include "psmouse.h"
0039 #include "hgpk.h"
0040
0041 #define ILLEGAL_XY 999999
0042
0043 static bool tpdebug;
0044 module_param(tpdebug, bool, 0644);
0045 MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
0046
0047 static int recalib_delta = 100;
0048 module_param(recalib_delta, int, 0644);
0049 MODULE_PARM_DESC(recalib_delta,
0050 "packets containing a delta this large will be discarded, and a "
0051 "recalibration may be scheduled.");
0052
0053 static int jumpy_delay = 20;
0054 module_param(jumpy_delay, int, 0644);
0055 MODULE_PARM_DESC(jumpy_delay,
0056 "delay (ms) before recal after jumpiness detected");
0057
0058 static int spew_delay = 1;
0059 module_param(spew_delay, int, 0644);
0060 MODULE_PARM_DESC(spew_delay,
0061 "delay (ms) before recal after packet spew detected");
0062
0063 static int recal_guard_time;
0064 module_param(recal_guard_time, int, 0644);
0065 MODULE_PARM_DESC(recal_guard_time,
0066 "interval (ms) during which recal will be restarted if packet received");
0067
0068 static int post_interrupt_delay = 40;
0069 module_param(post_interrupt_delay, int, 0644);
0070 MODULE_PARM_DESC(post_interrupt_delay,
0071 "delay (ms) before recal after recal interrupt detected");
0072
0073 static bool autorecal = true;
0074 module_param(autorecal, bool, 0644);
0075 MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
0076
0077 static char hgpk_mode_name[16];
0078 module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644);
0079 MODULE_PARM_DESC(hgpk_mode,
0080 "default hgpk mode: mouse, glidesensor or pentablet");
0081
0082 static int hgpk_default_mode = HGPK_MODE_MOUSE;
0083
0084 static const char * const hgpk_mode_names[] = {
0085 [HGPK_MODE_MOUSE] = "Mouse",
0086 [HGPK_MODE_GLIDESENSOR] = "GlideSensor",
0087 [HGPK_MODE_PENTABLET] = "PenTablet",
0088 };
0089
0090 static int hgpk_mode_from_name(const char *buf, int len)
0091 {
0092 int i;
0093
0094 for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) {
0095 const char *name = hgpk_mode_names[i];
0096 if (strlen(name) == len && !strncasecmp(name, buf, len))
0097 return i;
0098 }
0099
0100 return HGPK_MODE_INVALID;
0101 }
0102
0103
0104
0105
0106 static int approx_half(int curr, int prev)
0107 {
0108 int belowhalf, abovehalf;
0109
0110 if (curr < 5 || prev < 5)
0111 return 0;
0112
0113 belowhalf = (prev * 8) / 20;
0114 abovehalf = (prev * 12) / 20;
0115
0116 return belowhalf < curr && curr <= abovehalf;
0117 }
0118
0119
0120
0121
0122
0123
0124 static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
0125 {
0126 struct hgpk_data *priv = psmouse->private;
0127 int avx, avy;
0128 bool do_recal = false;
0129
0130 avx = abs(x);
0131 avy = abs(y);
0132
0133
0134 if (avx > recalib_delta ||
0135 (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) {
0136 psmouse_warn(psmouse, "detected %dpx jump in x\n", x);
0137 priv->xbigj = avx;
0138 } else if (approx_half(avx, priv->xbigj)) {
0139 psmouse_warn(psmouse, "detected secondary %dpx jump in x\n", x);
0140 priv->xbigj = avx;
0141 priv->xsaw_secondary++;
0142 } else {
0143 if (priv->xbigj && priv->xsaw_secondary > 1)
0144 do_recal = true;
0145 priv->xbigj = 0;
0146 priv->xsaw_secondary = 0;
0147 }
0148
0149 if (avy > recalib_delta ||
0150 (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) {
0151 psmouse_warn(psmouse, "detected %dpx jump in y\n", y);
0152 priv->ybigj = avy;
0153 } else if (approx_half(avy, priv->ybigj)) {
0154 psmouse_warn(psmouse, "detected secondary %dpx jump in y\n", y);
0155 priv->ybigj = avy;
0156 priv->ysaw_secondary++;
0157 } else {
0158 if (priv->ybigj && priv->ysaw_secondary > 1)
0159 do_recal = true;
0160 priv->ybigj = 0;
0161 priv->ysaw_secondary = 0;
0162 }
0163
0164 priv->xlast = avx;
0165 priv->ylast = avy;
0166
0167 if (do_recal && jumpy_delay) {
0168 psmouse_warn(psmouse, "scheduling recalibration\n");
0169 psmouse_queue_work(psmouse, &priv->recalib_wq,
0170 msecs_to_jiffies(jumpy_delay));
0171 }
0172
0173 return priv->xbigj || priv->ybigj;
0174 }
0175
0176 static void hgpk_reset_spew_detection(struct hgpk_data *priv)
0177 {
0178 priv->spew_count = 0;
0179 priv->dupe_count = 0;
0180 priv->x_tally = 0;
0181 priv->y_tally = 0;
0182 priv->spew_flag = NO_SPEW;
0183 }
0184
0185 static void hgpk_reset_hack_state(struct psmouse *psmouse)
0186 {
0187 struct hgpk_data *priv = psmouse->private;
0188
0189 priv->abs_x = priv->abs_y = -1;
0190 priv->xlast = priv->ylast = ILLEGAL_XY;
0191 priv->xbigj = priv->ybigj = 0;
0192 priv->xsaw_secondary = priv->ysaw_secondary = 0;
0193 hgpk_reset_spew_detection(priv);
0194 }
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 static void hgpk_spewing_hack(struct psmouse *psmouse,
0212 int l, int r, int x, int y)
0213 {
0214 struct hgpk_data *priv = psmouse->private;
0215
0216
0217
0218 if (l || r)
0219 return;
0220
0221
0222 if (!spew_delay)
0223 return;
0224
0225 if (abs(x) > 3 || abs(y) > 3) {
0226
0227 hgpk_reset_spew_detection(priv);
0228 return;
0229 }
0230
0231
0232
0233 priv->x_tally += x;
0234 priv->y_tally += y;
0235
0236 switch (priv->spew_flag) {
0237 case NO_SPEW:
0238
0239 priv->spew_flag = MAYBE_SPEWING;
0240
0241 fallthrough;
0242
0243 case MAYBE_SPEWING:
0244 priv->spew_count++;
0245
0246 if (priv->spew_count < SPEW_WATCH_COUNT)
0247 break;
0248
0249
0250 priv->spew_flag = SPEW_DETECTED;
0251
0252 fallthrough;
0253
0254 case SPEW_DETECTED:
0255
0256
0257
0258
0259 if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
0260 psmouse_warn(psmouse, "packet spew detected (%d,%d)\n",
0261 priv->x_tally, priv->y_tally);
0262 priv->spew_flag = RECALIBRATING;
0263 psmouse_queue_work(psmouse, &priv->recalib_wq,
0264 msecs_to_jiffies(spew_delay));
0265 }
0266
0267 break;
0268 case RECALIBRATING:
0269
0270
0271 break;
0272 }
0273 }
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306 static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet)
0307 {
0308 struct hgpk_data *priv = psmouse->private;
0309 int pktcnt = psmouse->pktcnt;
0310 bool valid;
0311
0312 switch (priv->mode) {
0313 case HGPK_MODE_MOUSE:
0314 valid = (packet[0] & 0x0C) == 0x08;
0315 break;
0316
0317 case HGPK_MODE_GLIDESENSOR:
0318 valid = pktcnt == 1 ?
0319 packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80);
0320 break;
0321
0322 case HGPK_MODE_PENTABLET:
0323 valid = pktcnt == 1 ?
0324 packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80);
0325 break;
0326
0327 default:
0328 valid = false;
0329 break;
0330 }
0331
0332 if (!valid)
0333 psmouse_dbg(psmouse,
0334 "bad data, mode %d (%d) %*ph\n",
0335 priv->mode, pktcnt, 6, psmouse->packet);
0336
0337 return valid;
0338 }
0339
0340 static void hgpk_process_advanced_packet(struct psmouse *psmouse)
0341 {
0342 struct hgpk_data *priv = psmouse->private;
0343 struct input_dev *idev = psmouse->dev;
0344 unsigned char *packet = psmouse->packet;
0345 int down = !!(packet[2] & 2);
0346 int left = !!(packet[3] & 1);
0347 int right = !!(packet[3] & 2);
0348 int x = packet[1] | ((packet[2] & 0x78) << 4);
0349 int y = packet[4] | ((packet[3] & 0x70) << 3);
0350
0351 if (priv->mode == HGPK_MODE_GLIDESENSOR) {
0352 int pt_down = !!(packet[2] & 1);
0353 int finger_down = !!(packet[2] & 2);
0354 int z = packet[5];
0355
0356 input_report_abs(idev, ABS_PRESSURE, z);
0357 if (tpdebug)
0358 psmouse_dbg(psmouse, "pd=%d fd=%d z=%d",
0359 pt_down, finger_down, z);
0360 } else {
0361
0362
0363
0364
0365 if (tpdebug)
0366 psmouse_dbg(psmouse, "pd=%d ", down);
0367 }
0368
0369 if (tpdebug)
0370 psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
0371 left, right, x, y);
0372
0373 input_report_key(idev, BTN_TOUCH, down);
0374 input_report_key(idev, BTN_LEFT, left);
0375 input_report_key(idev, BTN_RIGHT, right);
0376
0377
0378
0379
0380
0381 if (!down) {
0382 hgpk_reset_hack_state(psmouse);
0383 goto done;
0384 }
0385
0386
0387
0388
0389
0390 if (x == priv->abs_x && y == priv->abs_y) {
0391 if (++priv->dupe_count > SPEW_WATCH_COUNT) {
0392 if (tpdebug)
0393 psmouse_dbg(psmouse, "hard spew detected\n");
0394 priv->spew_flag = RECALIBRATING;
0395 psmouse_queue_work(psmouse, &priv->recalib_wq,
0396 msecs_to_jiffies(spew_delay));
0397 }
0398 goto done;
0399 }
0400
0401
0402 priv->dupe_count = 0;
0403
0404
0405 if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) {
0406 int x_diff = priv->abs_x - x;
0407 int y_diff = priv->abs_y - y;
0408 if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) {
0409 if (tpdebug)
0410 psmouse_dbg(psmouse, "discarding\n");
0411 goto done;
0412 }
0413 hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff);
0414 }
0415
0416 input_report_abs(idev, ABS_X, x);
0417 input_report_abs(idev, ABS_Y, y);
0418 priv->abs_x = x;
0419 priv->abs_y = y;
0420
0421 done:
0422 input_sync(idev);
0423 }
0424
0425 static void hgpk_process_simple_packet(struct psmouse *psmouse)
0426 {
0427 struct input_dev *dev = psmouse->dev;
0428 unsigned char *packet = psmouse->packet;
0429 int left = packet[0] & 1;
0430 int right = (packet[0] >> 1) & 1;
0431 int x = packet[1] - ((packet[0] << 4) & 0x100);
0432 int y = ((packet[0] << 3) & 0x100) - packet[2];
0433
0434 if (packet[0] & 0xc0)
0435 psmouse_dbg(psmouse,
0436 "overflow -- 0x%02x 0x%02x 0x%02x\n",
0437 packet[0], packet[1], packet[2]);
0438
0439 if (hgpk_discard_decay_hack(psmouse, x, y)) {
0440 if (tpdebug)
0441 psmouse_dbg(psmouse, "discarding\n");
0442 return;
0443 }
0444
0445 hgpk_spewing_hack(psmouse, left, right, x, y);
0446
0447 if (tpdebug)
0448 psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
0449 left, right, x, y);
0450
0451 input_report_key(dev, BTN_LEFT, left);
0452 input_report_key(dev, BTN_RIGHT, right);
0453
0454 input_report_rel(dev, REL_X, x);
0455 input_report_rel(dev, REL_Y, y);
0456
0457 input_sync(dev);
0458 }
0459
0460 static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
0461 {
0462 struct hgpk_data *priv = psmouse->private;
0463
0464 if (!hgpk_is_byte_valid(psmouse, psmouse->packet))
0465 return PSMOUSE_BAD_DATA;
0466
0467 if (psmouse->pktcnt >= psmouse->pktsize) {
0468 if (priv->mode == HGPK_MODE_MOUSE)
0469 hgpk_process_simple_packet(psmouse);
0470 else
0471 hgpk_process_advanced_packet(psmouse);
0472 return PSMOUSE_FULL_PACKET;
0473 }
0474
0475 if (priv->recalib_window) {
0476 if (time_before(jiffies, priv->recalib_window)) {
0477
0478
0479
0480
0481 psmouse_dbg(psmouse,
0482 "packet inside calibration window, queueing another recalibration\n");
0483 psmouse_queue_work(psmouse, &priv->recalib_wq,
0484 msecs_to_jiffies(post_interrupt_delay));
0485 }
0486 priv->recalib_window = 0;
0487 }
0488
0489 return PSMOUSE_GOOD_DATA;
0490 }
0491
0492 static int hgpk_select_mode(struct psmouse *psmouse)
0493 {
0494 struct ps2dev *ps2dev = &psmouse->ps2dev;
0495 struct hgpk_data *priv = psmouse->private;
0496 int i;
0497 int cmd;
0498
0499
0500
0501
0502
0503 const int advanced_init[] = {
0504 PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
0505 PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
0506 0xf2, 0xf2, 0xf2,
0507 };
0508
0509 switch (priv->mode) {
0510 case HGPK_MODE_MOUSE:
0511 psmouse->pktsize = 3;
0512 break;
0513
0514 case HGPK_MODE_GLIDESENSOR:
0515 case HGPK_MODE_PENTABLET:
0516 psmouse->pktsize = 6;
0517
0518
0519 for (i = 0; i < ARRAY_SIZE(advanced_init); i++)
0520 if (ps2_command(ps2dev, NULL, advanced_init[i]))
0521 return -EIO;
0522
0523
0524 cmd = priv->mode == HGPK_MODE_GLIDESENSOR ?
0525 PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21;
0526
0527 if (ps2_command(ps2dev, NULL, cmd))
0528 return -EIO;
0529 break;
0530
0531 default:
0532 return -EINVAL;
0533 }
0534
0535 return 0;
0536 }
0537
0538 static void hgpk_setup_input_device(struct input_dev *input,
0539 struct input_dev *old_input,
0540 enum hgpk_mode mode)
0541 {
0542 if (old_input) {
0543 input->name = old_input->name;
0544 input->phys = old_input->phys;
0545 input->id = old_input->id;
0546 input->dev.parent = old_input->dev.parent;
0547 }
0548
0549 memset(input->evbit, 0, sizeof(input->evbit));
0550 memset(input->relbit, 0, sizeof(input->relbit));
0551 memset(input->keybit, 0, sizeof(input->keybit));
0552
0553
0554 __set_bit(EV_KEY, input->evbit);
0555 __set_bit(BTN_LEFT, input->keybit);
0556 __set_bit(BTN_RIGHT, input->keybit);
0557
0558 switch (mode) {
0559 case HGPK_MODE_MOUSE:
0560 __set_bit(EV_REL, input->evbit);
0561 __set_bit(REL_X, input->relbit);
0562 __set_bit(REL_Y, input->relbit);
0563 break;
0564
0565 case HGPK_MODE_GLIDESENSOR:
0566 __set_bit(BTN_TOUCH, input->keybit);
0567 __set_bit(BTN_TOOL_FINGER, input->keybit);
0568
0569 __set_bit(EV_ABS, input->evbit);
0570
0571
0572 input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0);
0573
0574
0575 input_set_abs_params(input, ABS_X, 0, 399, 0, 0);
0576 input_set_abs_params(input, ABS_Y, 0, 290, 0, 0);
0577
0578
0579 input_abs_set_res(input, ABS_X, 8);
0580 input_abs_set_res(input, ABS_Y, 8);
0581 break;
0582
0583 case HGPK_MODE_PENTABLET:
0584 __set_bit(BTN_TOUCH, input->keybit);
0585 __set_bit(BTN_TOOL_FINGER, input->keybit);
0586
0587 __set_bit(EV_ABS, input->evbit);
0588
0589
0590 input_set_abs_params(input, ABS_X, 0, 999, 0, 0);
0591 input_set_abs_params(input, ABS_Y, 5, 239, 0, 0);
0592
0593
0594 input_abs_set_res(input, ABS_X, 6);
0595 input_abs_set_res(input, ABS_Y, 8);
0596 break;
0597
0598 default:
0599 BUG();
0600 }
0601 }
0602
0603 static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate)
0604 {
0605 int err;
0606
0607 psmouse_reset(psmouse);
0608
0609 if (recalibrate) {
0610 struct ps2dev *ps2dev = &psmouse->ps2dev;
0611
0612
0613 if (ps2_command(ps2dev, NULL, 0xf5) ||
0614 ps2_command(ps2dev, NULL, 0xf5) ||
0615 ps2_command(ps2dev, NULL, 0xe6) ||
0616 ps2_command(ps2dev, NULL, 0xf5)) {
0617 return -1;
0618 }
0619
0620
0621 msleep(150);
0622 }
0623
0624 err = hgpk_select_mode(psmouse);
0625 if (err) {
0626 psmouse_err(psmouse, "failed to select mode\n");
0627 return err;
0628 }
0629
0630 hgpk_reset_hack_state(psmouse);
0631
0632 return 0;
0633 }
0634
0635 static int hgpk_force_recalibrate(struct psmouse *psmouse)
0636 {
0637 struct hgpk_data *priv = psmouse->private;
0638 int err;
0639
0640
0641 if (psmouse->model < HGPK_MODEL_C)
0642 return 0;
0643
0644 if (!autorecal) {
0645 psmouse_dbg(psmouse, "recalibration disabled, ignoring\n");
0646 return 0;
0647 }
0648
0649 psmouse_dbg(psmouse, "recalibrating touchpad..\n");
0650
0651
0652 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
0653
0654
0655 err = hgpk_reset_device(psmouse, true);
0656 if (err)
0657 return err;
0658
0659
0660
0661
0662
0663
0664
0665 if (psmouse_activate(psmouse))
0666 return -1;
0667
0668 if (tpdebug)
0669 psmouse_dbg(psmouse, "touchpad reactivated\n");
0670
0671
0672
0673
0674
0675
0676 if (recal_guard_time)
0677 priv->recalib_window = jiffies +
0678 msecs_to_jiffies(recal_guard_time);
0679
0680 return 0;
0681 }
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692 static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
0693 {
0694 struct ps2dev *ps2dev = &psmouse->ps2dev;
0695 int timeo;
0696 int err;
0697
0698
0699 if (psmouse->model < HGPK_MODEL_D)
0700 return 0;
0701
0702 if (enable) {
0703 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
0704
0705
0706
0707
0708
0709
0710
0711
0712 for (timeo = 20; timeo > 0; timeo--) {
0713 if (!ps2_sendbyte(ps2dev, PSMOUSE_CMD_DISABLE, 20))
0714 break;
0715 msleep(25);
0716 }
0717
0718 err = hgpk_reset_device(psmouse, false);
0719 if (err) {
0720 psmouse_err(psmouse, "Failed to reset device!\n");
0721 return err;
0722 }
0723
0724
0725 psmouse_activate(psmouse);
0726 psmouse_dbg(psmouse, "Touchpad powered up.\n");
0727 } else {
0728 psmouse_dbg(psmouse, "Powering off touchpad.\n");
0729
0730 if (ps2_command(ps2dev, NULL, 0xec) ||
0731 ps2_command(ps2dev, NULL, 0xec) ||
0732 ps2_command(ps2dev, NULL, 0xea)) {
0733 return -1;
0734 }
0735
0736 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
0737
0738
0739 ps2_sendbyte(ps2dev, 0xec, 20);
0740 }
0741
0742 return 0;
0743 }
0744
0745 static int hgpk_poll(struct psmouse *psmouse)
0746 {
0747
0748 return -1;
0749 }
0750
0751 static int hgpk_reconnect(struct psmouse *psmouse)
0752 {
0753 struct hgpk_data *priv = psmouse->private;
0754
0755
0756
0757
0758
0759
0760 if (olpc_board_at_least(olpc_board(0xb2)))
0761 if (psmouse->ps2dev.serio->dev.power.power_state.event !=
0762 PM_EVENT_ON)
0763 return 0;
0764
0765 priv->powered = 1;
0766 return hgpk_reset_device(psmouse, false);
0767 }
0768
0769 static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
0770 {
0771 struct hgpk_data *priv = psmouse->private;
0772
0773 return sprintf(buf, "%d\n", priv->powered);
0774 }
0775
0776 static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
0777 const char *buf, size_t count)
0778 {
0779 struct hgpk_data *priv = psmouse->private;
0780 unsigned int value;
0781 int err;
0782
0783 err = kstrtouint(buf, 10, &value);
0784 if (err)
0785 return err;
0786
0787 if (value > 1)
0788 return -EINVAL;
0789
0790 if (value != priv->powered) {
0791
0792
0793
0794
0795 err = hgpk_toggle_powersave(psmouse, value);
0796 if (!err)
0797 priv->powered = value;
0798 }
0799
0800 return err ? err : count;
0801 }
0802
0803 __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
0804 hgpk_show_powered, hgpk_set_powered, false);
0805
0806 static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf)
0807 {
0808 struct hgpk_data *priv = psmouse->private;
0809
0810 return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]);
0811 }
0812
0813 static ssize_t attr_set_mode(struct psmouse *psmouse, void *data,
0814 const char *buf, size_t len)
0815 {
0816 struct hgpk_data *priv = psmouse->private;
0817 enum hgpk_mode old_mode = priv->mode;
0818 enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len);
0819 struct input_dev *old_dev = psmouse->dev;
0820 struct input_dev *new_dev;
0821 int err;
0822
0823 if (new_mode == HGPK_MODE_INVALID)
0824 return -EINVAL;
0825
0826 if (old_mode == new_mode)
0827 return len;
0828
0829 new_dev = input_allocate_device();
0830 if (!new_dev)
0831 return -ENOMEM;
0832
0833 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
0834
0835
0836 priv->mode = new_mode;
0837 err = hgpk_reset_device(psmouse, false);
0838 if (err)
0839 goto err_try_restore;
0840
0841 hgpk_setup_input_device(new_dev, old_dev, new_mode);
0842
0843 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
0844
0845 err = input_register_device(new_dev);
0846 if (err)
0847 goto err_try_restore;
0848
0849 psmouse->dev = new_dev;
0850 input_unregister_device(old_dev);
0851
0852 return len;
0853
0854 err_try_restore:
0855 input_free_device(new_dev);
0856 priv->mode = old_mode;
0857 hgpk_reset_device(psmouse, false);
0858
0859 return err;
0860 }
0861
0862 PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL,
0863 attr_show_mode, attr_set_mode);
0864
0865 static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
0866 void *data, char *buf)
0867 {
0868 return -EINVAL;
0869 }
0870
0871 static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
0872 const char *buf, size_t count)
0873 {
0874 struct hgpk_data *priv = psmouse->private;
0875 unsigned int value;
0876 int err;
0877
0878 err = kstrtouint(buf, 10, &value);
0879 if (err)
0880 return err;
0881
0882 if (value != 1)
0883 return -EINVAL;
0884
0885
0886
0887
0888
0889
0890 psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
0891 return count;
0892 }
0893
0894 __PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
0895 hgpk_trigger_recal_show, hgpk_trigger_recal, false);
0896
0897 static void hgpk_disconnect(struct psmouse *psmouse)
0898 {
0899 struct hgpk_data *priv = psmouse->private;
0900
0901 device_remove_file(&psmouse->ps2dev.serio->dev,
0902 &psmouse_attr_powered.dattr);
0903 device_remove_file(&psmouse->ps2dev.serio->dev,
0904 &psmouse_attr_hgpk_mode.dattr);
0905
0906 if (psmouse->model >= HGPK_MODEL_C)
0907 device_remove_file(&psmouse->ps2dev.serio->dev,
0908 &psmouse_attr_recalibrate.dattr);
0909
0910 psmouse_reset(psmouse);
0911 kfree(priv);
0912 }
0913
0914 static void hgpk_recalib_work(struct work_struct *work)
0915 {
0916 struct delayed_work *w = to_delayed_work(work);
0917 struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
0918 struct psmouse *psmouse = priv->psmouse;
0919
0920 if (hgpk_force_recalibrate(psmouse))
0921 psmouse_err(psmouse, "recalibration failed!\n");
0922 }
0923
0924 static int hgpk_register(struct psmouse *psmouse)
0925 {
0926 struct hgpk_data *priv = psmouse->private;
0927 int err;
0928
0929
0930 psmouse->protocol_handler = hgpk_process_byte;
0931 psmouse->poll = hgpk_poll;
0932 psmouse->disconnect = hgpk_disconnect;
0933 psmouse->reconnect = hgpk_reconnect;
0934
0935
0936 psmouse->resync_time = 0;
0937
0938 psmouse->resetafter = 1024;
0939
0940 hgpk_setup_input_device(psmouse->dev, NULL, priv->mode);
0941
0942 err = device_create_file(&psmouse->ps2dev.serio->dev,
0943 &psmouse_attr_powered.dattr);
0944 if (err) {
0945 psmouse_err(psmouse, "Failed creating 'powered' sysfs node\n");
0946 return err;
0947 }
0948
0949 err = device_create_file(&psmouse->ps2dev.serio->dev,
0950 &psmouse_attr_hgpk_mode.dattr);
0951 if (err) {
0952 psmouse_err(psmouse,
0953 "Failed creating 'hgpk_mode' sysfs node\n");
0954 goto err_remove_powered;
0955 }
0956
0957
0958 if (psmouse->model >= HGPK_MODEL_C) {
0959 err = device_create_file(&psmouse->ps2dev.serio->dev,
0960 &psmouse_attr_recalibrate.dattr);
0961 if (err) {
0962 psmouse_err(psmouse,
0963 "Failed creating 'recalibrate' sysfs node\n");
0964 goto err_remove_mode;
0965 }
0966 }
0967
0968 return 0;
0969
0970 err_remove_mode:
0971 device_remove_file(&psmouse->ps2dev.serio->dev,
0972 &psmouse_attr_hgpk_mode.dattr);
0973 err_remove_powered:
0974 device_remove_file(&psmouse->ps2dev.serio->dev,
0975 &psmouse_attr_powered.dattr);
0976 return err;
0977 }
0978
0979 int hgpk_init(struct psmouse *psmouse)
0980 {
0981 struct hgpk_data *priv;
0982 int err;
0983
0984 priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);
0985 if (!priv) {
0986 err = -ENOMEM;
0987 goto alloc_fail;
0988 }
0989
0990 psmouse->private = priv;
0991
0992 priv->psmouse = psmouse;
0993 priv->powered = true;
0994 priv->mode = hgpk_default_mode;
0995 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
0996
0997 err = hgpk_reset_device(psmouse, false);
0998 if (err)
0999 goto init_fail;
1000
1001 err = hgpk_register(psmouse);
1002 if (err)
1003 goto init_fail;
1004
1005 return 0;
1006
1007 init_fail:
1008 kfree(priv);
1009 alloc_fail:
1010 return err;
1011 }
1012
1013 static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
1014 {
1015 struct ps2dev *ps2dev = &psmouse->ps2dev;
1016 unsigned char param[3];
1017
1018
1019 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1020 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1021 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1022 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
1023 return -EIO;
1024 }
1025
1026 psmouse_dbg(psmouse, "ID: %*ph\n", 3, param);
1027
1028
1029 if (param[0] != 0x67 || param[1] != 0x00)
1030 return -ENODEV;
1031
1032 psmouse_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);
1033
1034 return param[2];
1035 }
1036
1037 int hgpk_detect(struct psmouse *psmouse, bool set_properties)
1038 {
1039 int version;
1040
1041 version = hgpk_get_model(psmouse);
1042 if (version < 0)
1043 return version;
1044
1045 if (set_properties) {
1046 psmouse->vendor = "ALPS";
1047 psmouse->name = "HGPK";
1048 psmouse->model = version;
1049 }
1050
1051 return 0;
1052 }
1053
1054 void hgpk_module_init(void)
1055 {
1056 hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name,
1057 strlen(hgpk_mode_name));
1058 if (hgpk_default_mode == HGPK_MODE_INVALID) {
1059 hgpk_default_mode = HGPK_MODE_MOUSE;
1060 strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE],
1061 sizeof(hgpk_mode_name));
1062 }
1063 }