16
16
* Copyright (C) 2005 Peter Osterlund ([email protected] )
17
17
* Copyright (C) 2005 Michael Hanselmann ([email protected] )
18
18
* Copyright (C) 2006 Nicolas Boichat ([email protected] )
19
+ * Copyright (C) 2016 Marek Wyborski ([email protected] )
19
20
*
20
21
* This program is free software; you can redistribute it and/or modify
21
22
* it under the terms of the GNU General Public License as published by
96
97
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
97
98
#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
98
99
#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
100
+ /* MagicTrackpad2 (2015) */
101
+ #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 0x0265
99
102
100
103
#define BCM5974_DEVICE (prod ) { \
101
104
.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
@@ -161,6 +164,8 @@ static const struct usb_device_id bcm5974_table[] = {
161
164
BCM5974_DEVICE (USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI ),
162
165
BCM5974_DEVICE (USB_DEVICE_ID_APPLE_WELLSPRING9_ISO ),
163
166
BCM5974_DEVICE (USB_DEVICE_ID_APPLE_WELLSPRING9_JIS ),
167
+ /* MagicTrackpad2 */
168
+ BCM5974_DEVICE (USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ),
164
169
/* Terminating entry */
165
170
{}
166
171
};
@@ -190,20 +195,23 @@ enum tp_type {
190
195
TYPE1 , /* plain trackpad */
191
196
TYPE2 , /* button integrated in trackpad */
192
197
TYPE3 , /* additional header fields since June 2013 */
193
- TYPE4 /* additional header field for pressure data */
198
+ TYPE4 , /* additional header field for pressure data */
199
+ TYPE5 /* format for magic trackpad 2 */
194
200
};
195
201
196
202
/* trackpad finger data offsets, le16-aligned */
197
203
#define HEADER_TYPE1 (13 * sizeof(__le16))
198
204
#define HEADER_TYPE2 (15 * sizeof(__le16))
199
205
#define HEADER_TYPE3 (19 * sizeof(__le16))
200
206
#define HEADER_TYPE4 (23 * sizeof(__le16))
207
+ #define HEADER_TYPE5 ( 6 * sizeof(__le16))
201
208
202
209
/* trackpad button data offsets */
203
210
#define BUTTON_TYPE1 0
204
211
#define BUTTON_TYPE2 15
205
212
#define BUTTON_TYPE3 23
206
213
#define BUTTON_TYPE4 31
214
+ #define BUTTON_TYPE5 1
207
215
208
216
/* list of device capability bits */
209
217
#define HAS_INTEGRATED_BUTTON 1
@@ -213,18 +221,21 @@ enum tp_type {
213
221
#define FSIZE_TYPE2 (14 * sizeof(__le16))
214
222
#define FSIZE_TYPE3 (14 * sizeof(__le16))
215
223
#define FSIZE_TYPE4 (15 * sizeof(__le16))
224
+ #define FSIZE_TYPE5 (9)
216
225
217
226
/* offset from header to finger struct */
218
227
#define DELTA_TYPE1 (0 * sizeof(__le16))
219
228
#define DELTA_TYPE2 (0 * sizeof(__le16))
220
229
#define DELTA_TYPE3 (0 * sizeof(__le16))
221
230
#define DELTA_TYPE4 (1 * sizeof(__le16))
231
+ #define DELTA_TYPE5 (0 * sizeof(__le16))
222
232
223
233
/* usb control message mode switch data */
224
234
#define USBMSG_TYPE1 8, 0x300, 0, 0, 0x1, 0x8
225
235
#define USBMSG_TYPE2 8, 0x300, 0, 0, 0x1, 0x8
226
236
#define USBMSG_TYPE3 8, 0x300, 0, 0, 0x1, 0x8
227
237
#define USBMSG_TYPE4 2, 0x302, 2, 1, 0x1, 0x0
238
+ #define USBMSG_TYPE5 2, 0x302, 1, 1, 0x1, 0x0
228
239
229
240
/* Wellspring initialization constants */
230
241
#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1
@@ -247,6 +258,18 @@ struct tp_finger {
247
258
__le16 multi ; /* one finger: varies, more fingers: constant */
248
259
} __attribute__((packed ,aligned (2 )));
249
260
261
+ /* trackpad finger structure for type5 (magic trackpad), le16-aligned */
262
+ struct tp_finger_type5 {
263
+ u8 abs_x ; /* absolute x coodinate */
264
+ u8 abs_x_y ; /* absolute x,y coodinate */
265
+ u8 abs_y [2 ]; /* absolute y coodinate */
266
+ u8 touch_major ; /* touch area, major axis */
267
+ u8 touch_minor ; /* touch area, minor axis */
268
+ u8 size ; /* tool area, size */
269
+ u8 pressure ; /* pressure on forcetouch touchpad */
270
+ u8 orientation_origin ; /* orientation and id */
271
+ } __attribute__((packed ,aligned (2 )));
272
+
250
273
/* trackpad finger data size, empirically at least ten fingers */
251
274
#define MAX_FINGERS 16
252
275
#define MAX_FINGER_ORIENTATION 16384
@@ -497,6 +520,19 @@ static const struct bcm5974_config bcm5974_config_table[] = {
497
520
{ SN_COORD , -203 , 6803 },
498
521
{ SN_ORIENT , - MAX_FINGER_ORIENTATION , MAX_FINGER_ORIENTATION }
499
522
},
523
+ {
524
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ,
525
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ,
526
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ,
527
+ HAS_INTEGRATED_BUTTON ,
528
+ 0 , sizeof (struct bt_data ),
529
+ 0x83 , DATAFORMAT (TYPE5 ),
530
+ { SN_PRESSURE , 0 , 300 },
531
+ { SN_WIDTH , 0 , 2048 },
532
+ { SN_COORD , -3678 , 3934 },
533
+ { SN_COORD , -2479 , 2586 },
534
+ { SN_ORIENT , - MAX_FINGER_ORIENTATION , MAX_FINGER_ORIENTATION }
535
+ },
500
536
{}
501
537
};
502
538
@@ -539,9 +575,13 @@ static void setup_events_to_report(struct input_dev *input_dev,
539
575
/* finger touch area */
540
576
set_abs (input_dev , ABS_MT_TOUCH_MAJOR , & cfg -> w );
541
577
set_abs (input_dev , ABS_MT_TOUCH_MINOR , & cfg -> w );
578
+
542
579
/* finger approach area */
543
- set_abs (input_dev , ABS_MT_WIDTH_MAJOR , & cfg -> w );
544
- set_abs (input_dev , ABS_MT_WIDTH_MINOR , & cfg -> w );
580
+ if (cfg -> tp_type != TYPE5 ) {
581
+ set_abs (input_dev , ABS_MT_WIDTH_MAJOR , & cfg -> w );
582
+ set_abs (input_dev , ABS_MT_WIDTH_MINOR , & cfg -> w );
583
+ }
584
+
545
585
/* finger orientation */
546
586
set_abs (input_dev , ABS_MT_ORIENTATION , & cfg -> o );
547
587
/* finger position */
@@ -596,6 +636,23 @@ static void report_finger_data(struct input_dev *input, int slot,
596
636
input_report_abs (input , ABS_MT_POSITION_Y , pos -> y );
597
637
}
598
638
639
+ static void report_finger_data_type5 (struct input_dev * input , int slot ,
640
+ const struct input_mt_pos * pos ,
641
+ const struct tp_finger_type5 * f )
642
+ {
643
+ input_mt_slot (input , slot );
644
+ input_mt_report_slot_state (input , MT_TOOL_FINGER , true);
645
+
646
+ input_report_abs (input , ABS_MT_TOUCH_MAJOR ,
647
+ raw2int (f -> touch_major ) << 2 );
648
+ input_report_abs (input , ABS_MT_TOUCH_MINOR ,
649
+ raw2int (f -> touch_minor ) << 2 );
650
+ input_report_abs (input , ABS_MT_ORIENTATION ,
651
+ MAX_FINGER_ORIENTATION - ((f -> orientation_origin & 0xf0 ) << 6 ));
652
+ input_report_abs (input , ABS_MT_POSITION_X , pos -> x << 1 );
653
+ input_report_abs (input , ABS_MT_POSITION_Y , pos -> y << 1 );
654
+ }
655
+
599
656
static void report_synaptics_data (struct input_dev * input ,
600
657
const struct bcm5974_config * cfg ,
601
658
const struct tp_finger * f , int raw_n )
@@ -615,11 +672,31 @@ static void report_synaptics_data(struct input_dev *input,
615
672
input_report_abs (input , ABS_TOOL_WIDTH , abs_w );
616
673
}
617
674
675
+ static void report_synaptics_data_type5 (struct input_dev * input ,
676
+ const struct bcm5974_config * cfg ,
677
+ const struct tp_finger_type5 * f , int raw_n )
678
+ {
679
+ int abs_p = 0 , abs_w = 0 ;
680
+
681
+ if (raw_n ) {
682
+ int p = f -> pressure ;
683
+ int w = f -> size ;
684
+ if (p && w ) {
685
+ abs_p = p ;
686
+ abs_w = w ;
687
+ }
688
+ }
689
+
690
+ input_report_abs (input , ABS_PRESSURE , abs_p );
691
+ input_report_abs (input , ABS_TOOL_WIDTH , abs_w );
692
+ }
693
+
618
694
/* report trackpad data as logical trackpad state */
619
695
static int report_tp_state (struct bcm5974 * dev , int size )
620
696
{
621
697
const struct bcm5974_config * c = & dev -> cfg ;
622
698
const struct tp_finger * f ;
699
+ const struct tp_finger_type5 * f_type5 ;
623
700
struct input_dev * input = dev -> input ;
624
701
int raw_n , i , n = 0 ;
625
702
@@ -629,23 +706,47 @@ static int report_tp_state(struct bcm5974 *dev, int size)
629
706
raw_n = (size - c -> tp_header ) / c -> tp_fsize ;
630
707
631
708
for (i = 0 ; i < raw_n ; i ++ ) {
709
+
632
710
f = get_tp_finger (dev , i );
633
- if (raw2int (f -> touch_major ) == 0 )
634
- continue ;
635
- dev -> pos [n ].x = raw2int (f -> abs_x );
636
- dev -> pos [n ].y = c -> y .min + c -> y .max - raw2int (f -> abs_y );
711
+
712
+ if (c -> tp_type != TYPE5 ) {
713
+ if (raw2int (f -> touch_major ) == 0 )
714
+ continue ;
715
+ dev -> pos [n ].x = raw2int (f -> abs_x );
716
+ dev -> pos [n ].y = c -> y .min + c -> y .max - raw2int (f -> abs_y );
717
+ }
718
+ else {
719
+ u16 tmp_x ;
720
+ u32 tmp_y ;
721
+ f_type5 = (const struct tp_finger_type5 * ) f ;
722
+ if (f_type5 -> pressure == 0 )
723
+ continue ;
724
+ tmp_x = le16_to_cpu (* ((__le16 * )f_type5 )) & 0x1fff ;
725
+ dev -> pos [n ].x = (s16 ) (tmp_x << 3 ) >> 3 ;
726
+ tmp_y = (s32 ) le32_to_cpu (* ((__le32 * )f_type5 ));
727
+ dev -> pos [n ].y = - (s32 ) (tmp_y << 6 ) >> 19 ;
728
+ }
637
729
dev -> index [n ++ ] = f ;
638
730
}
639
731
640
732
input_mt_assign_slots (input , dev -> slots , dev -> pos , n , 0 );
641
733
642
- for (i = 0 ; i < n ; i ++ )
643
- report_finger_data (input , dev -> slots [i ],
644
- & dev -> pos [i ], dev -> index [i ]);
734
+ for (i = 0 ; i < n ; i ++ ) {
735
+ if (c -> tp_type != TYPE5 )
736
+ report_finger_data (input , dev -> slots [i ],
737
+ & dev -> pos [i ], dev -> index [i ]);
738
+ else
739
+ report_finger_data_type5 (input , dev -> slots [i ], & dev -> pos [i ],
740
+ (const struct tp_finger_type5 * ) dev -> index [i ]);
741
+ }
645
742
646
743
input_mt_sync_frame (input );
647
744
648
- report_synaptics_data (input , c , get_tp_finger (dev , 0 ), raw_n );
745
+ if (c -> tp_type != TYPE5 )
746
+ report_synaptics_data (input , c , get_tp_finger (dev , 0 ), raw_n );
747
+ else
748
+ report_synaptics_data_type5 (input , c ,
749
+ (const struct tp_finger_type5 * ) get_tp_finger (dev , 0 ), raw_n );
649
750
650
751
/* later types report button events via integrated button only */
651
752
if (c -> caps & HAS_INTEGRATED_BUTTON ) {
0 commit comments