aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-wiimote-core.c25
-rw-r--r--drivers/hid/hid-wiimote-modules.c74
-rw-r--r--drivers/hid/hid-wiimote.h4
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)
867out_release: 870out_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
1549static 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
1561static 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
1571static 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
1585static 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
1597static 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
1607static 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
1711const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = { 1785const 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};