diff options
| -rw-r--r-- | drivers/hid/hid-wiimote-core.c | 25 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote-modules.c | 74 | ||||
| -rw-r--r-- | drivers/hid/hid-wiimote.h | 4 |
3 files changed, 98 insertions, 5 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index fa58045cf7e0..3e696562c944 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
| @@ -555,6 +555,7 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = { | |||
| 555 | WIIMOD_NULL, | 555 | WIIMOD_NULL, |
| 556 | }, | 556 | }, |
| 557 | [WIIMOTE_DEV_UNKNOWN] = (const __u8[]){ | 557 | [WIIMOTE_DEV_UNKNOWN] = (const __u8[]){ |
| 558 | WIIMOD_NO_MP, | ||
| 558 | WIIMOD_NULL, | 559 | WIIMOD_NULL, |
| 559 | }, | 560 | }, |
| 560 | [WIIMOTE_DEV_GENERIC] = (const __u8[]){ | 561 | [WIIMOTE_DEV_GENERIC] = (const __u8[]){ |
| @@ -591,11 +592,13 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = { | |||
| 591 | WIIMOD_LED4, | 592 | WIIMOD_LED4, |
| 592 | WIIMOD_ACCEL, | 593 | WIIMOD_ACCEL, |
| 593 | WIIMOD_IR, | 594 | WIIMOD_IR, |
| 595 | WIIMOD_BUILTIN_MP, | ||
| 594 | WIIMOD_NULL, | 596 | WIIMOD_NULL, |
| 595 | }, | 597 | }, |
| 596 | [WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) { | 598 | [WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) { |
| 597 | WIIMOD_BATTERY, | 599 | WIIMOD_BATTERY, |
| 598 | WIIMOD_LED1, | 600 | WIIMOD_LED1, |
| 601 | WIIMOD_NO_MP, | ||
| 599 | WIIMOD_NULL, | 602 | WIIMOD_NULL, |
| 600 | }, | 603 | }, |
| 601 | }; | 604 | }; |
| @@ -867,8 +870,13 @@ static void wiimote_init_detect(struct wiimote_data *wdata) | |||
| 867 | out_release: | 870 | out_release: |
| 868 | wiimote_cmd_release(wdata); | 871 | wiimote_cmd_release(wdata); |
| 869 | wiimote_init_set_type(wdata, exttype); | 872 | wiimote_init_set_type(wdata, exttype); |
| 873 | |||
| 870 | /* schedule MP timer */ | 874 | /* schedule MP timer */ |
| 871 | mod_timer(&wdata->timer, jiffies + HZ * 4); | 875 | spin_lock_irq(&wdata->state.lock); |
| 876 | if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) && | ||
| 877 | !(wdata->state.flags & WIIPROTO_FLAG_NO_MP)) | ||
| 878 | mod_timer(&wdata->timer, jiffies + HZ * 4); | ||
| 879 | spin_unlock_irq(&wdata->state.lock); | ||
| 872 | } | 880 | } |
| 873 | 881 | ||
| 874 | /* | 882 | /* |
| @@ -1037,7 +1045,8 @@ out_release: | |||
| 1037 | wiimote_cmd_release(wdata); | 1045 | wiimote_cmd_release(wdata); |
| 1038 | 1046 | ||
| 1039 | /* only poll for MP if requested and if state didn't change */ | 1047 | /* only poll for MP if requested and if state didn't change */ |
| 1040 | if (ret && poll_mp) | 1048 | if (ret && poll_mp && !(flags & WIIPROTO_FLAG_BUILTIN_MP) && |
| 1049 | !(flags & WIIPROTO_FLAG_NO_MP)) | ||
| 1041 | wiimote_init_poll_mp(wdata); | 1050 | wiimote_init_poll_mp(wdata); |
| 1042 | 1051 | ||
| 1043 | return ret; | 1052 | return ret; |
| @@ -1082,8 +1091,12 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata) | |||
| 1082 | 1091 | ||
| 1083 | /* init extension and MP (deactivates current extension or MP) */ | 1092 | /* init extension and MP (deactivates current extension or MP) */ |
| 1084 | wiimote_cmd_init_ext(wdata); | 1093 | wiimote_cmd_init_ext(wdata); |
| 1085 | wiimote_cmd_init_mp(wdata); | 1094 | if (flags & WIIPROTO_FLAG_NO_MP) { |
| 1086 | mp = wiimote_cmd_read_mp(wdata, mpdata); | 1095 | mp = false; |
| 1096 | } else { | ||
| 1097 | wiimote_cmd_init_mp(wdata); | ||
| 1098 | mp = wiimote_cmd_read_mp(wdata, mpdata); | ||
| 1099 | } | ||
| 1087 | exttype = wiimote_cmd_read_ext(wdata, extdata); | 1100 | exttype = wiimote_cmd_read_ext(wdata, extdata); |
| 1088 | 1101 | ||
| 1089 | wiimote_cmd_release(wdata); | 1102 | wiimote_cmd_release(wdata); |
| @@ -1133,7 +1146,9 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata) | |||
| 1133 | del_timer_sync(&wdata->timer); | 1146 | del_timer_sync(&wdata->timer); |
| 1134 | } else { | 1147 | } else { |
| 1135 | /* reschedule MP hotplug timer */ | 1148 | /* reschedule MP hotplug timer */ |
| 1136 | mod_timer(&wdata->timer, jiffies + HZ * 4); | 1149 | if (!(flags & WIIPROTO_FLAG_BUILTIN_MP) && |
| 1150 | !(flags & WIIPROTO_FLAG_NO_MP)) | ||
| 1151 | mod_timer(&wdata->timer, jiffies + HZ * 4); | ||
| 1137 | } | 1152 | } |
| 1138 | 1153 | ||
| 1139 | spin_lock_irq(&wdata->state.lock); | 1154 | spin_lock_irq(&wdata->state.lock); |
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 19b8b1c4acb4..e2afe065991d 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c | |||
| @@ -1540,6 +1540,78 @@ static const struct wiimod_ops wiimod_bboard = { | |||
| 1540 | }; | 1540 | }; |
| 1541 | 1541 | ||
| 1542 | /* | 1542 | /* |
| 1543 | * Builtin Motion Plus | ||
| 1544 | * This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which | ||
| 1545 | * disables polling for Motion-Plus. This should be set only for devices which | ||
| 1546 | * don't allow MP hotplugging. | ||
| 1547 | */ | ||
| 1548 | |||
| 1549 | static int wiimod_builtin_mp_probe(const struct wiimod_ops *ops, | ||
| 1550 | struct wiimote_data *wdata) | ||
| 1551 | { | ||
| 1552 | unsigned long flags; | ||
| 1553 | |||
| 1554 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1555 | wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP; | ||
| 1556 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1557 | |||
| 1558 | return 0; | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | static void wiimod_builtin_mp_remove(const struct wiimod_ops *ops, | ||
| 1562 | struct wiimote_data *wdata) | ||
| 1563 | { | ||
| 1564 | unsigned long flags; | ||
| 1565 | |||
| 1566 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1567 | wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP; | ||
| 1568 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | static const struct wiimod_ops wiimod_builtin_mp = { | ||
| 1572 | .flags = 0, | ||
| 1573 | .arg = 0, | ||
| 1574 | .probe = wiimod_builtin_mp_probe, | ||
| 1575 | .remove = wiimod_builtin_mp_remove, | ||
| 1576 | }; | ||
| 1577 | |||
| 1578 | /* | ||
| 1579 | * No Motion Plus | ||
| 1580 | * This module simply sets the WIIPROTO_FLAG_NO_MP protocol flag which | ||
| 1581 | * disables motion-plus. This is needed for devices that advertise this but we | ||
| 1582 | * don't know how to use it (or whether it is actually present). | ||
| 1583 | */ | ||
| 1584 | |||
| 1585 | static int wiimod_no_mp_probe(const struct wiimod_ops *ops, | ||
| 1586 | struct wiimote_data *wdata) | ||
| 1587 | { | ||
| 1588 | unsigned long flags; | ||
| 1589 | |||
| 1590 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1591 | wdata->state.flags |= WIIPROTO_FLAG_NO_MP; | ||
| 1592 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1593 | |||
| 1594 | return 0; | ||
| 1595 | } | ||
| 1596 | |||
| 1597 | static void wiimod_no_mp_remove(const struct wiimod_ops *ops, | ||
| 1598 | struct wiimote_data *wdata) | ||
| 1599 | { | ||
| 1600 | unsigned long flags; | ||
| 1601 | |||
| 1602 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
| 1603 | wdata->state.flags |= WIIPROTO_FLAG_NO_MP; | ||
| 1604 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
| 1605 | } | ||
| 1606 | |||
| 1607 | static const struct wiimod_ops wiimod_no_mp = { | ||
| 1608 | .flags = 0, | ||
| 1609 | .arg = 0, | ||
| 1610 | .probe = wiimod_no_mp_probe, | ||
| 1611 | .remove = wiimod_no_mp_remove, | ||
| 1612 | }; | ||
| 1613 | |||
| 1614 | /* | ||
| 1543 | * Motion Plus | 1615 | * Motion Plus |
| 1544 | * The Motion Plus extension provides rotation sensors (gyro) as a small | 1616 | * The Motion Plus extension provides rotation sensors (gyro) as a small |
| 1545 | * extension device for Wii Remotes. Many devices have them built-in so | 1617 | * extension device for Wii Remotes. Many devices have them built-in so |
| @@ -1706,6 +1778,8 @@ const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { | |||
| 1706 | [WIIMOD_LED4] = &wiimod_leds[3], | 1778 | [WIIMOD_LED4] = &wiimod_leds[3], |
| 1707 | [WIIMOD_ACCEL] = &wiimod_accel, | 1779 | [WIIMOD_ACCEL] = &wiimod_accel, |
| 1708 | [WIIMOD_IR] = &wiimod_ir, | 1780 | [WIIMOD_IR] = &wiimod_ir, |
| 1781 | [WIIMOD_BUILTIN_MP] = &wiimod_builtin_mp, | ||
| 1782 | [WIIMOD_NO_MP] = &wiimod_no_mp, | ||
| 1709 | }; | 1783 | }; |
| 1710 | 1784 | ||
| 1711 | const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = { | 1785 | const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = { |
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index d406a398e54c..5cf8bcb81095 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
| @@ -44,6 +44,8 @@ | |||
| 44 | #define WIIPROTO_FLAG_MP_ACTIVE 0x2000 | 44 | #define WIIPROTO_FLAG_MP_ACTIVE 0x2000 |
| 45 | #define WIIPROTO_FLAG_EXITING 0x4000 | 45 | #define WIIPROTO_FLAG_EXITING 0x4000 |
| 46 | #define WIIPROTO_FLAG_DRM_LOCKED 0x8000 | 46 | #define WIIPROTO_FLAG_DRM_LOCKED 0x8000 |
| 47 | #define WIIPROTO_FLAG_BUILTIN_MP 0x010000 | ||
| 48 | #define WIIPROTO_FLAG_NO_MP 0x020000 | ||
| 47 | 49 | ||
| 48 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ | 50 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ |
| 49 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) | 51 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) |
| @@ -165,6 +167,8 @@ enum wiimod_module { | |||
| 165 | WIIMOD_LED4, | 167 | WIIMOD_LED4, |
| 166 | WIIMOD_ACCEL, | 168 | WIIMOD_ACCEL, |
| 167 | WIIMOD_IR, | 169 | WIIMOD_IR, |
| 170 | WIIMOD_BUILTIN_MP, | ||
| 171 | WIIMOD_NO_MP, | ||
| 168 | WIIMOD_NUM, | 172 | WIIMOD_NUM, |
| 169 | WIIMOD_NULL = WIIMOD_NUM, | 173 | WIIMOD_NULL = WIIMOD_NUM, |
| 170 | }; | 174 | }; |
