@@ -2403,6 +2403,230 @@ static const struct wiimod_ops wiimod_guitar = {
2403
2403
.in_ext = wiimod_guitar_in_ext ,
2404
2404
};
2405
2405
2406
+ /*
2407
+ * Turntable
2408
+ * DJ Hero came with a Turntable Controller that was plugged in
2409
+ * as an extension.
2410
+ * We create a separate device for turntables and report all information via this
2411
+ * input device.
2412
+ */
2413
+
2414
+ enum wiimod_turntable_keys {
2415
+ WIIMOD_TURNTABLE_KEY_G_RIGHT ,
2416
+ WIIMOD_TURNTABLE_KEY_R_RIGHT ,
2417
+ WIIMOD_TURNTABLE_KEY_B_RIGHT ,
2418
+ WIIMOD_TURNTABLE_KEY_G_LEFT ,
2419
+ WIIMOD_TURNTABLE_KEY_R_LEFT ,
2420
+ WIIMOD_TURNTABLE_KEY_B_LEFT ,
2421
+ WIIMOD_TURNTABLE_KEY_EUPHORIA ,
2422
+ WIIMOD_TURNTABLE_KEY_PLUS ,
2423
+ WIIMOD_TURNTABLE_KEY_MINUS ,
2424
+ WIIMOD_TURNTABLE_KEY_NUM
2425
+ };
2426
+
2427
+ static const __u16 wiimod_turntable_map [] = {
2428
+ BTN_1 , /* WIIMOD_TURNTABLE_KEY_G_RIGHT */
2429
+ BTN_2 , /* WIIMOD_TURNTABLE_KEY_R_RIGHT */
2430
+ BTN_3 , /* WIIMOD_TURNTABLE_KEY_B_RIGHT */
2431
+ BTN_4 , /* WIIMOD_TURNTABLE_KEY_G_LEFT */
2432
+ BTN_5 , /* WIIMOD_TURNTABLE_KEY_R_LEFT */
2433
+ BTN_6 , /* WIIMOD_TURNTABLE_KEY_B_LEFT */
2434
+ BTN_7 , /* WIIMOD_TURNTABLE_KEY_EUPHORIA */
2435
+ BTN_START , /* WIIMOD_TURNTABLE_KEY_PLUS */
2436
+ BTN_SELECT , /* WIIMOD_TURNTABLE_KEY_MINUS */
2437
+ };
2438
+
2439
+ static void wiimod_turntable_in_ext (struct wiimote_data * wdata , const __u8 * ext )
2440
+ {
2441
+ __u8 be , cs , sx , sy , ed , rtt , rbg , rbr , rbb , ltt , lbg , lbr , lbb , bp , bm ;
2442
+ /*
2443
+ * Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
2444
+ *------+------+-----+-----+-----+-----+------+------+--------+
2445
+ * 0 | RTT<4:3> | SX <5:0> |
2446
+ * 1 | RTT<2:1> | SY <5:0> |
2447
+ *------+------+-----+-----+-----+-----+------+------+--------+
2448
+ * 2 |RTT<0>| ED<4:3> | CS<3:0> | RTT<5> |
2449
+ *------+------+-----+-----+-----+-----+------+------+--------+
2450
+ * 3 | ED<2:0> | LTT<4:0> |
2451
+ *------+------+-----+-----+-----+-----+------+------+--------+
2452
+ * 4 | 0 | 0 | LBR | B- | 0 | B+ | RBR | LTT<5> |
2453
+ *------+------+-----+-----+-----+-----+------+------+--------+
2454
+ * 5 | LBB | 0 | RBG | BE | LBG | RBB | 0 | 0 |
2455
+ *------+------+-----+-----+-----+-----+------+------+--------+
2456
+ * All pressed buttons are 0
2457
+ *
2458
+ * With Motion+ enabled, it will look like this:
2459
+ * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
2460
+ *------+------+-----+-----+-----+-----+------+------+--------+
2461
+ * 1 | RTT<4:3> | SX <5:1> | 0 |
2462
+ * 2 | RTT<2:1> | SY <5:1> | 0 |
2463
+ *------+------+-----+-----+-----+-----+------+------+--------+
2464
+ * 3 |RTT<0>| ED<4:3> | CS<3:0> | RTT<5> |
2465
+ *------+------+-----+-----+-----+-----+------+------+--------+
2466
+ * 4 | ED<2:0> | LTT<4:0> |
2467
+ *------+------+-----+-----+-----+-----+------+------+--------+
2468
+ * 5 | 0 | 0 | LBR | B- | 0 | B+ | RBR | XXXX |
2469
+ *------+------+-----+-----+-----+-----+------+------+--------+
2470
+ * 6 | LBB | 0 | RBG | BE | LBG | RBB | XXXX | XXXX |
2471
+ *------+------+-----+-----+-----+-----+------+------+--------+
2472
+ */
2473
+
2474
+ be = !(ext [5 ] & 0x10 );
2475
+ cs = ((ext [2 ] & 0x1e ));
2476
+ sx = ext [0 ] & 0x3f ;
2477
+ sy = ext [1 ] & 0x3f ;
2478
+ ed = (ext [3 ] & 0xe0 ) >> 5 ;
2479
+ rtt = ((ext [2 ] & 0x01 ) << 5 | (ext [0 ] & 0xc0 ) >> 3 | (ext [1 ] & 0xc0 ) >> 5 | ( ext [2 ] & 0x80 ) >> 7 );
2480
+ ltt = ((ext [4 ] & 0x01 ) << 5 | (ext [3 ] & 0x1f ));
2481
+ rbg = !(ext [5 ] & 0x20 );
2482
+ rbr = !(ext [4 ] & 0x02 );
2483
+ rbb = !(ext [5 ] & 0x04 );
2484
+ lbg = !(ext [5 ] & 0x08 );
2485
+ lbb = !(ext [5 ] & 0x80 );
2486
+ lbr = !(ext [4 ] & 0x20 );
2487
+ bm = !(ext [4 ] & 0x10 );
2488
+ bp = !(ext [4 ] & 0x04 );
2489
+
2490
+ if (wdata -> state .flags & WIIPROTO_FLAG_MP_ACTIVE ) {
2491
+ ltt = (ext [4 ] & 0x01 ) << 5 ;
2492
+ sx &= 0x3e ;
2493
+ sy &= 0x3e ;
2494
+ }
2495
+
2496
+ input_report_abs (wdata -> extension .input , ABS_X , sx );
2497
+ input_report_abs (wdata -> extension .input , ABS_Y , sy );
2498
+ input_report_abs (wdata -> extension .input , ABS_HAT0X , rtt );
2499
+ input_report_abs (wdata -> extension .input , ABS_HAT1X , ltt );
2500
+ input_report_abs (wdata -> extension .input , ABS_HAT2X , cs );
2501
+ input_report_abs (wdata -> extension .input , ABS_HAT3X , ed );
2502
+ input_report_key (wdata -> extension .input ,
2503
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_G_RIGHT ],
2504
+ rbg );
2505
+ input_report_key (wdata -> extension .input ,
2506
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_R_RIGHT ],
2507
+ rbr );
2508
+ input_report_key (wdata -> extension .input ,
2509
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_B_RIGHT ],
2510
+ rbb );
2511
+ input_report_key (wdata -> extension .input ,
2512
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_G_LEFT ],
2513
+ lbg );
2514
+ input_report_key (wdata -> extension .input ,
2515
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_R_LEFT ],
2516
+ lbr );
2517
+ input_report_key (wdata -> extension .input ,
2518
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_B_LEFT ],
2519
+ lbb );
2520
+ input_report_key (wdata -> extension .input ,
2521
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_EUPHORIA ],
2522
+ be );
2523
+ input_report_key (wdata -> extension .input ,
2524
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_PLUS ],
2525
+ bp );
2526
+ input_report_key (wdata -> extension .input ,
2527
+ wiimod_turntable_map [WIIMOD_TURNTABLE_KEY_MINUS ],
2528
+ bm );
2529
+
2530
+ input_sync (wdata -> extension .input );
2531
+ }
2532
+
2533
+ static int wiimod_turntable_open (struct input_dev * dev )
2534
+ {
2535
+ struct wiimote_data * wdata = input_get_drvdata (dev );
2536
+ unsigned long flags ;
2537
+
2538
+ spin_lock_irqsave (& wdata -> state .lock , flags );
2539
+ wdata -> state .flags |= WIIPROTO_FLAG_EXT_USED ;
2540
+ wiiproto_req_drm (wdata , WIIPROTO_REQ_NULL );
2541
+ spin_unlock_irqrestore (& wdata -> state .lock , flags );
2542
+
2543
+ return 0 ;
2544
+ }
2545
+
2546
+ static void wiimod_turntable_close (struct input_dev * dev )
2547
+ {
2548
+ struct wiimote_data * wdata = input_get_drvdata (dev );
2549
+ unsigned long flags ;
2550
+
2551
+ spin_lock_irqsave (& wdata -> state .lock , flags );
2552
+ wdata -> state .flags &= ~WIIPROTO_FLAG_EXT_USED ;
2553
+ wiiproto_req_drm (wdata , WIIPROTO_REQ_NULL );
2554
+ spin_unlock_irqrestore (& wdata -> state .lock , flags );
2555
+ }
2556
+
2557
+ static int wiimod_turntable_probe (const struct wiimod_ops * ops ,
2558
+ struct wiimote_data * wdata )
2559
+ {
2560
+ int ret , i ;
2561
+
2562
+ wdata -> extension .input = input_allocate_device ();
2563
+ if (!wdata -> extension .input )
2564
+ return - ENOMEM ;
2565
+
2566
+ input_set_drvdata (wdata -> extension .input , wdata );
2567
+ wdata -> extension .input -> open = wiimod_turntable_open ;
2568
+ wdata -> extension .input -> close = wiimod_turntable_close ;
2569
+ wdata -> extension .input -> dev .parent = & wdata -> hdev -> dev ;
2570
+ wdata -> extension .input -> id .bustype = wdata -> hdev -> bus ;
2571
+ wdata -> extension .input -> id .vendor = wdata -> hdev -> vendor ;
2572
+ wdata -> extension .input -> id .product = wdata -> hdev -> product ;
2573
+ wdata -> extension .input -> id .version = wdata -> hdev -> version ;
2574
+ wdata -> extension .input -> name = WIIMOTE_NAME " Turntable" ;
2575
+
2576
+ set_bit (EV_KEY , wdata -> extension .input -> evbit );
2577
+ for (i = 0 ; i < WIIMOD_TURNTABLE_KEY_NUM ; ++ i )
2578
+ set_bit (wiimod_turntable_map [i ],
2579
+ wdata -> extension .input -> keybit );
2580
+
2581
+ set_bit (EV_ABS , wdata -> extension .input -> evbit );
2582
+ set_bit (ABS_X , wdata -> extension .input -> absbit );
2583
+ set_bit (ABS_Y , wdata -> extension .input -> absbit );
2584
+ set_bit (ABS_HAT0X , wdata -> extension .input -> absbit );
2585
+ set_bit (ABS_HAT1X , wdata -> extension .input -> absbit );
2586
+ set_bit (ABS_HAT2X , wdata -> extension .input -> absbit );
2587
+ set_bit (ABS_HAT3X , wdata -> extension .input -> absbit );
2588
+ input_set_abs_params (wdata -> extension .input ,
2589
+ ABS_X , 0 , 63 , 1 , 0 );
2590
+ input_set_abs_params (wdata -> extension .input ,
2591
+ ABS_Y , 63 , 0 , 1 , 0 );
2592
+ input_set_abs_params (wdata -> extension .input ,
2593
+ ABS_HAT0X , -8 , 8 , 0 , 0 );
2594
+ input_set_abs_params (wdata -> extension .input ,
2595
+ ABS_HAT1X , -8 , 8 , 0 , 0 );
2596
+ input_set_abs_params (wdata -> extension .input ,
2597
+ ABS_HAT2X , 0 , 31 , 1 , 1 );
2598
+ input_set_abs_params (wdata -> extension .input ,
2599
+ ABS_HAT3X , 0 , 7 , 0 , 0 );
2600
+ ret = input_register_device (wdata -> extension .input );
2601
+ if (ret )
2602
+ goto err_free ;
2603
+
2604
+ return 0 ;
2605
+
2606
+ err_free :
2607
+ input_free_device (wdata -> extension .input );
2608
+ wdata -> extension .input = NULL ;
2609
+ return ret ;
2610
+ }
2611
+
2612
+ static void wiimod_turntable_remove (const struct wiimod_ops * ops ,
2613
+ struct wiimote_data * wdata )
2614
+ {
2615
+ if (!wdata -> extension .input )
2616
+ return ;
2617
+
2618
+ input_unregister_device (wdata -> extension .input );
2619
+ wdata -> extension .input = NULL ;
2620
+ }
2621
+
2622
+ static const struct wiimod_ops wiimod_turntable = {
2623
+ .flags = 0 ,
2624
+ .arg = 0 ,
2625
+ .probe = wiimod_turntable_probe ,
2626
+ .remove = wiimod_turntable_remove ,
2627
+ .in_ext = wiimod_turntable_in_ext ,
2628
+ };
2629
+
2406
2630
/*
2407
2631
* Builtin Motion Plus
2408
2632
* This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which
@@ -2657,4 +2881,5 @@ const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
2657
2881
[WIIMOTE_EXT_PRO_CONTROLLER ] = & wiimod_pro ,
2658
2882
[WIIMOTE_EXT_DRUMS ] = & wiimod_drums ,
2659
2883
[WIIMOTE_EXT_GUITAR ] = & wiimod_guitar ,
2884
+ [WIIMOTE_EXT_TURNTABLE ] = & wiimod_turntable ,
2660
2885
};
0 commit comments