~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to drivers/input/mouse/elantech.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#include <linux/slab.h>
17
17
#include <linux/module.h>
18
18
#include <linux/input.h>
 
19
#include <linux/input/mt.h>
19
20
#include <linux/serio.h>
20
21
#include <linux/libps2.h>
21
22
#include "psmouse.h"
81
82
{
82
83
        struct elantech_data *etd = psmouse->private;
83
84
        unsigned char param[3];
 
85
        unsigned char command;
84
86
        int rc = 0;
85
87
 
86
88
        if (reg < 0x10 || reg > 0x26)
89
91
        if (reg > 0x11 && reg < 0x20)
90
92
                return -1;
91
93
 
 
94
        command = (etd->hw_version == 3) ? ETP_REGISTER_RW : ETP_REGISTER_READ;
 
95
 
92
96
        switch (etd->hw_version) {
93
97
        case 1:
94
 
                if (psmouse_sliced_command(psmouse, ETP_REGISTER_READ) ||
 
98
                if (psmouse_sliced_command(psmouse, command) ||
95
99
                    psmouse_sliced_command(psmouse, reg) ||
96
100
                    ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) {
97
101
                        rc = -1;
99
103
                break;
100
104
 
101
105
        case 2:
 
106
        case 3:
102
107
                if (elantech_ps2_command(psmouse,  NULL, ETP_PS2_CUSTOM_COMMAND) ||
103
 
                    elantech_ps2_command(psmouse,  NULL, ETP_REGISTER_READ) ||
 
108
                    elantech_ps2_command(psmouse,  NULL, command) ||
104
109
                    elantech_ps2_command(psmouse,  NULL, ETP_PS2_CUSTOM_COMMAND) ||
105
110
                    elantech_ps2_command(psmouse,  NULL, reg) ||
106
111
                    elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) {
124
129
                                unsigned char val)
125
130
{
126
131
        struct elantech_data *etd = psmouse->private;
 
132
        unsigned char command;
127
133
        int rc = 0;
128
134
 
129
135
        if (reg < 0x10 || reg > 0x26)
132
138
        if (reg > 0x11 && reg < 0x20)
133
139
                return -1;
134
140
 
 
141
        command = (etd->hw_version == 3) ? ETP_REGISTER_RW : ETP_REGISTER_WRITE;
 
142
 
135
143
        switch (etd->hw_version) {
136
144
        case 1:
137
 
                if (psmouse_sliced_command(psmouse, ETP_REGISTER_WRITE) ||
 
145
                if (psmouse_sliced_command(psmouse, command) ||
138
146
                    psmouse_sliced_command(psmouse, reg) ||
139
147
                    psmouse_sliced_command(psmouse, val) ||
140
148
                    ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) {
143
151
                break;
144
152
 
145
153
        case 2:
 
154
        case 3:
146
155
                if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
147
 
                    elantech_ps2_command(psmouse, NULL, ETP_REGISTER_WRITE) ||
 
156
                    elantech_ps2_command(psmouse, NULL, command) ||
148
157
                    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
149
158
                    elantech_ps2_command(psmouse, NULL, reg) ||
150
159
                    elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) ||
222
231
                input_report_abs(dev, ABS_X,
223
232
                        ((packet[1] & 0x0c) << 6) | packet[2]);
224
233
                input_report_abs(dev, ABS_Y,
225
 
                        ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
 
234
                        etd->y_max - (((packet[1] & 0x03) << 8) | packet[3]));
226
235
        }
227
236
 
228
237
        input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
242
251
        input_sync(dev);
243
252
}
244
253
 
 
254
static void elantech_set_slot(struct input_dev *dev, int slot, bool active,
 
255
                              unsigned int x, unsigned int y)
 
256
{
 
257
        input_mt_slot(dev, slot);
 
258
        input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
 
259
        if (active) {
 
260
                input_report_abs(dev, ABS_MT_POSITION_X, x);
 
261
                input_report_abs(dev, ABS_MT_POSITION_Y, y);
 
262
        }
 
263
}
 
264
 
 
265
/* x1 < x2 and y1 < y2 when two fingers, x = y = 0 when not pressed */
 
266
static void elantech_report_semi_mt_data(struct input_dev *dev,
 
267
                                         unsigned int num_fingers,
 
268
                                         unsigned int x1, unsigned int y1,
 
269
                                         unsigned int x2, unsigned int y2)
 
270
{
 
271
        elantech_set_slot(dev, 0, num_fingers != 0, x1, y1);
 
272
        elantech_set_slot(dev, 1, num_fingers == 2, x2, y2);
 
273
}
 
274
 
245
275
/*
246
276
 * Interpret complete data packets and report absolute mode input events for
247
277
 * hardware version 2. (6 byte packets)
248
278
 */
249
279
static void elantech_report_absolute_v2(struct psmouse *psmouse)
250
280
{
 
281
        struct elantech_data *etd = psmouse->private;
251
282
        struct input_dev *dev = psmouse->dev;
252
283
        unsigned char *packet = psmouse->packet;
253
 
        int fingers, x1, y1, x2, y2;
 
284
        unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0, width = 0, pres = 0;
254
285
 
255
286
        /* byte 0: n1  n0   .   .   .   .   R   L */
256
287
        fingers = (packet[0] & 0xc0) >> 6;
270
301
                 * byte 1:  .   .   .   .   .  x10 x9  x8
271
302
                 * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
272
303
                 */
273
 
                input_report_abs(dev, ABS_X,
274
 
                        ((packet[1] & 0x07) << 8) | packet[2]);
 
304
                x1 = ((packet[1] & 0x07) << 8) | packet[2];
275
305
                /*
276
306
                 * byte 4:  .   .   .   .   .   .  y9  y8
277
307
                 * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
278
308
                 */
279
 
                input_report_abs(dev, ABS_Y,
280
 
                        ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]));
 
309
                y1 = etd->y_max - (((packet[4] & 0x03) << 8) | packet[5]);
 
310
 
 
311
                input_report_abs(dev, ABS_X, x1);
 
312
                input_report_abs(dev, ABS_Y, y1);
 
313
 
 
314
                pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
 
315
                width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
281
316
                break;
282
317
 
283
318
        case 2:
289
324
                 */
290
325
                x1 = ((packet[0] & 0x10) << 4) | packet[1];
291
326
                /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
292
 
                y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
 
327
                y1 = etd->y_max_2ft - (((packet[0] & 0x20) << 3) | packet[2]);
293
328
                /*
294
329
                 * byte 3:  .   .  by8 bx8  .   .   .   .
295
330
                 * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
296
331
                 */
297
332
                x2 = ((packet[3] & 0x10) << 4) | packet[4];
298
333
                /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
299
 
                y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
 
334
                y2 = etd->y_max_2ft - (((packet[3] & 0x20) << 3) | packet[5]);
300
335
                /*
301
336
                 * For compatibility with the X Synaptics driver scale up
302
337
                 * one coordinate and report as ordinary mouse movent
303
338
                 */
304
339
                input_report_abs(dev, ABS_X, x1 << 2);
305
340
                input_report_abs(dev, ABS_Y, y1 << 2);
306
 
                /*
307
 
                 * For compatibility with the proprietary X Elantech driver
308
 
                 * report both coordinates as hat coordinates
309
 
                 */
310
 
                input_report_abs(dev, ABS_HAT0X, x1);
311
 
                input_report_abs(dev, ABS_HAT0Y, y1);
312
 
                input_report_abs(dev, ABS_HAT1X, x2);
313
 
                input_report_abs(dev, ABS_HAT1Y, y2);
 
341
 
 
342
                /* Unknown so just report sensible values */
 
343
                pres = 127;
 
344
                width = 7;
314
345
                break;
315
346
        }
316
347
 
 
348
        elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
317
349
        input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
318
350
        input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
319
351
        input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
320
352
        input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
321
353
        input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
322
354
        input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
323
 
 
324
 
        input_sync(dev);
 
355
        if (etd->reports_pressure) {
 
356
                input_report_abs(dev, ABS_PRESSURE, pres);
 
357
                input_report_abs(dev, ABS_TOOL_WIDTH, width);
 
358
        }
 
359
 
 
360
        input_sync(dev);
 
361
}
 
362
 
 
363
static int elantech_v3_is_noise(unsigned int x, unsigned int y)
 
364
{
 
365
        return x == 0xfff && y == 0xfff;
 
366
}
 
367
 
 
368
/*
 
369
 * Interpret complete data packets and report absolute mode input events for
 
370
 * hardware version 3. (6 byte packets)
 
371
 */
 
372
static void elantech_report_absolute_v3(struct psmouse *psmouse)
 
373
{
 
374
        struct elantech_data *etd = psmouse->private;
 
375
        struct input_dev *dev = psmouse->dev;
 
376
        unsigned char *packet1 = psmouse->packet;
 
377
        unsigned char *packet2 = NULL;
 
378
        unsigned int fingers, width = 0, pres = 0;
 
379
        unsigned int x1, y1, x2 = 0, y2 = 0;
 
380
 
 
381
        /* byte 0: n1  n0   .   .   .   .   R   L */
 
382
        fingers = (packet1[0] & 0xc0) >> 6;
 
383
 
 
384
        /*
 
385
         * Need to receive two packets for 2-touch events. If this
 
386
         * is the first packet, store it away and wait for the second.
 
387
         * We don't support parity in v3, so use that storage.
 
388
         */
 
389
        if (fingers == 2 && (packet1[0] & 0x0c) == 0x04 &&
 
390
            (packet1[3] & 0xcf) == 0x2) {
 
391
                memcpy(etd->parity, packet1, psmouse->pktsize);
 
392
                return;
 
393
        }
 
394
 
 
395
        /*
 
396
         * If this the second packet of a two-fingered touch event we
 
397
         * need to process the previous packet stashed away in
 
398
         * etd->parity
 
399
         */
 
400
        if (fingers == 2) {
 
401
                packet1 = etd->parity;
 
402
                packet2 = psmouse->packet;
 
403
        }
 
404
 
 
405
        x1 = ((packet1[1] & 0x0f) << 8) | packet1[2];
 
406
        y1 = ((packet1[4] & 0x0f) << 8) | packet1[5];
 
407
        if (elantech_v3_is_noise(x1, y1))
 
408
                return;
 
409
        y1 = etd->y_max - y1;
 
410
 
 
411
        if (packet2) {
 
412
                x2 = ((packet2[1] & 0x0f) << 8) | packet2[2];
 
413
                y2 = etd->y_max - (((packet2[4] & 0x0f) << 8) | packet2[5]);
 
414
        }
 
415
 
 
416
        pres = (packet1[1] & 0xf0) | ((packet1[4] & 0xf0) >> 4);
 
417
        width = ((packet1[0] & 0x30) >> 2) | ((packet1[3] & 0x30) >> 4);
 
418
 
 
419
        elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
 
420
 
 
421
        input_report_key(dev, BTN_TOUCH, fingers != 0);
 
422
        input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
 
423
        input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
 
424
        input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
 
425
        input_report_abs(dev, ABS_PRESSURE, pres);
 
426
        input_report_abs(dev, ABS_TOOL_WIDTH, width);
 
427
 
 
428
        if (fingers != 0) {
 
429
                input_report_abs(dev, ABS_X, x1);
 
430
                input_report_abs(dev, ABS_Y, y1);
 
431
        }
 
432
 
 
433
        input_report_key(dev, BTN_LEFT, packet1[0] & 0x01);
 
434
        input_report_key(dev, BTN_RIGHT, packet1[0] & 0x02);
 
435
 
 
436
        input_sync(dev);
 
437
        return;
325
438
}
326
439
 
327
440
static int elantech_check_parity_v1(struct psmouse *psmouse)
373
486
                /* We don't know how to check parity in protocol v2 */
374
487
                elantech_report_absolute_v2(psmouse);
375
488
                break;
 
489
        case 3:
 
490
                /* We don't know how to check parity in protocol v3 */
 
491
                elantech_report_absolute_v3(psmouse);
 
492
                break;
376
493
        }
377
494
 
378
495
        return PSMOUSE_FULL_PACKET;
407
524
                    elantech_write_reg(psmouse, 0x11, etd->reg_11) ||
408
525
                    elantech_write_reg(psmouse, 0x21, etd->reg_21)) {
409
526
                        rc = -1;
410
 
                        break;
411
527
                }
 
528
                break;
 
529
        case 3:
 
530
                etd->reg_10 = 0x0b;
 
531
                if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
 
532
                        rc = -1;
 
533
                break;
412
534
        }
413
535
 
414
536
        if (rc == 0) {
445
567
/*
446
568
 * Set the appropriate event bits for the input subsystem
447
569
 */
448
 
static void elantech_set_input_params(struct psmouse *psmouse)
 
570
static int elantech_set_input_params(struct psmouse *psmouse)
449
571
{
450
572
        struct input_dev *dev = psmouse->dev;
451
573
        struct elantech_data *etd = psmouse->private;
 
574
        unsigned char param[3];
452
575
 
453
576
        __set_bit(EV_KEY, dev->evbit);
454
577
        __set_bit(EV_ABS, dev->evbit);
464
587
 
465
588
        switch (etd->hw_version) {
466
589
        case 1:
 
590
                etd->x_max = ETP_XMAX_V1;
 
591
                etd->y_max = ETP_YMAX_V1;
 
592
 
467
593
                /* Rocker button */
468
594
                if (etd->fw_version < 0x020000 &&
469
595
                    (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
470
596
                        __set_bit(BTN_FORWARD, dev->keybit);
471
597
                        __set_bit(BTN_BACK, dev->keybit);
472
598
                }
473
 
                input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, ETP_XMAX_V1, 0, 0);
474
 
                input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, ETP_YMAX_V1, 0, 0);
 
599
                input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, etd->x_max, 0, 0);
 
600
                input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, etd->y_max, 0, 0);
475
601
                break;
476
602
 
477
603
        case 2:
478
604
                __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
479
 
                input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
480
 
                input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
481
 
                input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
482
 
                input_set_abs_params(dev, ABS_HAT0Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
483
 
                input_set_abs_params(dev, ABS_HAT1X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
484
 
                input_set_abs_params(dev, ABS_HAT1Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
 
605
                /* fall through */
 
606
        case 3:
 
607
                if (etd->hw_version == 3) {
 
608
                        if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param))
 
609
                                return -1;
 
610
 
 
611
                        etd->x_max = (param[0] & 0x0f) << 8 | param[1];
 
612
                        etd->y_max = (param[0] & 0xf0) << 4 | param[2];
 
613
                        etd->y_max_2ft = etd->y_max;
 
614
                        elantech_debug("x_max = %d, y_max = %d\n",
 
615
                                       etd->x_max, etd->y_max);
 
616
                } else {
 
617
                        etd->x_max = ETP_XMAX_V2;
 
618
                        etd->y_max = ETP_YMAX_V2;
 
619
                        etd->y_max_2ft = ETP_2FT_YMAX;
 
620
                }
 
621
 
 
622
                input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, etd->x_max, 0, 0);
 
623
                input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, etd->y_max, 0, 0);
 
624
                if (etd->reports_pressure) {
 
625
                        input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
 
626
                                             ETP_PMAX_V2, 0, 0);
 
627
                        input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
 
628
                                             ETP_WMAX_V2, 0, 0);
 
629
                }
 
630
                __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
 
631
                input_mt_init_slots(dev, 2);
 
632
                input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, etd->x_max, 0, 0);
 
633
                input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, etd->y_max, 0, 0);
485
634
                break;
486
635
        }
 
636
 
 
637
        return 0;
487
638
}
488
639
 
489
640
struct elantech_attr_data {
625
776
         * Report this in case there are Elantech models that use a different
626
777
         * set of magic numbers
627
778
         */
628
 
        if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) {
 
779
        if (param[0] != 0x3c || param[1] != 0x03 ||
 
780
            (param[2] != 0xc8 && param[2] != 0x00)) {
629
781
                pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n",
630
782
                         param[0], param[1], param[2]);
631
783
                return -1;
715
867
 
716
868
        etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
717
869
 
718
 
        /*
719
 
         * Assume every version greater than this is new EeePC style
720
 
         * hardware with 6 byte packets
721
 
         */
722
 
        if (etd->fw_version >= 0x020030) {
 
870
        if (etd->fw_version < 0x020030) {
 
871
                etd->hw_version = 1;
 
872
                etd->paritycheck = 1;
 
873
        } else if (etd->fw_version <= 0x150600) {
723
874
                etd->hw_version = 2;
724
875
                /* For now show extra debug information */
725
876
                etd->debug = 1;
726
 
                /* Don't know how to do parity checking for version 2 */
727
 
                etd->paritycheck = 0;
 
877
 
 
878
                if (etd->fw_version >= 0x020800)
 
879
                        etd->reports_pressure = true;
 
880
        } else if ((etd->fw_version & 0x0f0000) == 0x050000) {
 
881
                etd->hw_version = 3;
 
882
                etd->debug = 1;
 
883
                etd->reports_pressure = true;
728
884
        } else {
729
 
                etd->hw_version = 1;
730
 
                etd->paritycheck = 1;
 
885
                pr_debug("unrecognized firmware version 0x%06x\n",
 
886
                         etd->fw_version);
 
887
                goto init_fail;
731
888
        }
732
889
 
733
890
        pr_info("assuming hardware version %d, firmware version %d.%d.%d\n",
756
913
                goto init_fail;
757
914
        }
758
915
 
759
 
        elantech_set_input_params(psmouse);
 
916
        error = elantech_set_input_params(psmouse);
 
917
        if (error) {
 
918
                pr_err("failed to set input parameters\n");
 
919
                goto init_fail;
 
920
        }
760
921
 
761
922
        error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
762
923
                                   &elantech_attr_group);
768
929
        psmouse->protocol_handler = elantech_process_byte;
769
930
        psmouse->disconnect = elantech_disconnect;
770
931
        psmouse->reconnect = elantech_reconnect;
771
 
        psmouse->pktsize = etd->hw_version == 2 ? 6 : 4;
 
932
        psmouse->pktsize = etd->hw_version == 1 ? 4 : 6;
772
933
 
773
934
        return 0;
774
935