HID: wiimote: add MP quirks
Devices which have built-in motion plus ports don't need MP detection logic. The new WIIMOD_BUILTIN_MP modules sets the WIIPROTO_FLAG_BUILTIN_MP flag which disables polling for MP. Some other devices erroneously report that they support motion-plus. For these devices and all devices without extension ports, we load WIIMOD_NO_MP which sets WIIPROTO_FLAG_NO_MP. This effectively disables all MP detection logic. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
Родитель
45ec9fff86
Коммит
9f329741a6
|
@ -555,6 +555,7 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
|
||||||
WIIMOD_NULL,
|
WIIMOD_NULL,
|
||||||
},
|
},
|
||||||
[WIIMOTE_DEV_UNKNOWN] = (const __u8[]){
|
[WIIMOTE_DEV_UNKNOWN] = (const __u8[]){
|
||||||
|
WIIMOD_NO_MP,
|
||||||
WIIMOD_NULL,
|
WIIMOD_NULL,
|
||||||
},
|
},
|
||||||
[WIIMOTE_DEV_GENERIC] = (const __u8[]){
|
[WIIMOTE_DEV_GENERIC] = (const __u8[]){
|
||||||
|
@ -591,11 +592,13 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
|
||||||
WIIMOD_LED4,
|
WIIMOD_LED4,
|
||||||
WIIMOD_ACCEL,
|
WIIMOD_ACCEL,
|
||||||
WIIMOD_IR,
|
WIIMOD_IR,
|
||||||
|
WIIMOD_BUILTIN_MP,
|
||||||
WIIMOD_NULL,
|
WIIMOD_NULL,
|
||||||
},
|
},
|
||||||
[WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) {
|
[WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) {
|
||||||
WIIMOD_BATTERY,
|
WIIMOD_BATTERY,
|
||||||
WIIMOD_LED1,
|
WIIMOD_LED1,
|
||||||
|
WIIMOD_NO_MP,
|
||||||
WIIMOD_NULL,
|
WIIMOD_NULL,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -867,8 +870,13 @@ static void wiimote_init_detect(struct wiimote_data *wdata)
|
||||||
out_release:
|
out_release:
|
||||||
wiimote_cmd_release(wdata);
|
wiimote_cmd_release(wdata);
|
||||||
wiimote_init_set_type(wdata, exttype);
|
wiimote_init_set_type(wdata, exttype);
|
||||||
|
|
||||||
/* schedule MP timer */
|
/* schedule MP timer */
|
||||||
|
spin_lock_irq(&wdata->state.lock);
|
||||||
|
if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) &&
|
||||||
|
!(wdata->state.flags & WIIPROTO_FLAG_NO_MP))
|
||||||
mod_timer(&wdata->timer, jiffies + HZ * 4);
|
mod_timer(&wdata->timer, jiffies + HZ * 4);
|
||||||
|
spin_unlock_irq(&wdata->state.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1037,7 +1045,8 @@ out_release:
|
||||||
wiimote_cmd_release(wdata);
|
wiimote_cmd_release(wdata);
|
||||||
|
|
||||||
/* only poll for MP if requested and if state didn't change */
|
/* only poll for MP if requested and if state didn't change */
|
||||||
if (ret && poll_mp)
|
if (ret && poll_mp && !(flags & WIIPROTO_FLAG_BUILTIN_MP) &&
|
||||||
|
!(flags & WIIPROTO_FLAG_NO_MP))
|
||||||
wiimote_init_poll_mp(wdata);
|
wiimote_init_poll_mp(wdata);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1082,8 +1091,12 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata)
|
||||||
|
|
||||||
/* init extension and MP (deactivates current extension or MP) */
|
/* init extension and MP (deactivates current extension or MP) */
|
||||||
wiimote_cmd_init_ext(wdata);
|
wiimote_cmd_init_ext(wdata);
|
||||||
|
if (flags & WIIPROTO_FLAG_NO_MP) {
|
||||||
|
mp = false;
|
||||||
|
} else {
|
||||||
wiimote_cmd_init_mp(wdata);
|
wiimote_cmd_init_mp(wdata);
|
||||||
mp = wiimote_cmd_read_mp(wdata, mpdata);
|
mp = wiimote_cmd_read_mp(wdata, mpdata);
|
||||||
|
}
|
||||||
exttype = wiimote_cmd_read_ext(wdata, extdata);
|
exttype = wiimote_cmd_read_ext(wdata, extdata);
|
||||||
|
|
||||||
wiimote_cmd_release(wdata);
|
wiimote_cmd_release(wdata);
|
||||||
|
@ -1133,6 +1146,8 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata)
|
||||||
del_timer_sync(&wdata->timer);
|
del_timer_sync(&wdata->timer);
|
||||||
} else {
|
} else {
|
||||||
/* reschedule MP hotplug timer */
|
/* reschedule MP hotplug timer */
|
||||||
|
if (!(flags & WIIPROTO_FLAG_BUILTIN_MP) &&
|
||||||
|
!(flags & WIIPROTO_FLAG_NO_MP))
|
||||||
mod_timer(&wdata->timer, jiffies + HZ * 4);
|
mod_timer(&wdata->timer, jiffies + HZ * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1539,6 +1539,78 @@ static const struct wiimod_ops wiimod_bboard = {
|
||||||
.in_ext = wiimod_bboard_in_ext,
|
.in_ext = wiimod_bboard_in_ext,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builtin Motion Plus
|
||||||
|
* This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which
|
||||||
|
* disables polling for Motion-Plus. This should be set only for devices which
|
||||||
|
* don't allow MP hotplugging.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int wiimod_builtin_mp_probe(const struct wiimod_ops *ops,
|
||||||
|
struct wiimote_data *wdata)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||||
|
wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP;
|
||||||
|
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wiimod_builtin_mp_remove(const struct wiimod_ops *ops,
|
||||||
|
struct wiimote_data *wdata)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||||
|
wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP;
|
||||||
|
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wiimod_ops wiimod_builtin_mp = {
|
||||||
|
.flags = 0,
|
||||||
|
.arg = 0,
|
||||||
|
.probe = wiimod_builtin_mp_probe,
|
||||||
|
.remove = wiimod_builtin_mp_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No Motion Plus
|
||||||
|
* This module simply sets the WIIPROTO_FLAG_NO_MP protocol flag which
|
||||||
|
* disables motion-plus. This is needed for devices that advertise this but we
|
||||||
|
* don't know how to use it (or whether it is actually present).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int wiimod_no_mp_probe(const struct wiimod_ops *ops,
|
||||||
|
struct wiimote_data *wdata)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||||
|
wdata->state.flags |= WIIPROTO_FLAG_NO_MP;
|
||||||
|
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wiimod_no_mp_remove(const struct wiimod_ops *ops,
|
||||||
|
struct wiimote_data *wdata)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||||
|
wdata->state.flags |= WIIPROTO_FLAG_NO_MP;
|
||||||
|
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wiimod_ops wiimod_no_mp = {
|
||||||
|
.flags = 0,
|
||||||
|
.arg = 0,
|
||||||
|
.probe = wiimod_no_mp_probe,
|
||||||
|
.remove = wiimod_no_mp_remove,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Motion Plus
|
* Motion Plus
|
||||||
* The Motion Plus extension provides rotation sensors (gyro) as a small
|
* The Motion Plus extension provides rotation sensors (gyro) as a small
|
||||||
|
@ -1706,6 +1778,8 @@ const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = {
|
||||||
[WIIMOD_LED4] = &wiimod_leds[3],
|
[WIIMOD_LED4] = &wiimod_leds[3],
|
||||||
[WIIMOD_ACCEL] = &wiimod_accel,
|
[WIIMOD_ACCEL] = &wiimod_accel,
|
||||||
[WIIMOD_IR] = &wiimod_ir,
|
[WIIMOD_IR] = &wiimod_ir,
|
||||||
|
[WIIMOD_BUILTIN_MP] = &wiimod_builtin_mp,
|
||||||
|
[WIIMOD_NO_MP] = &wiimod_no_mp,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
|
const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
#define WIIPROTO_FLAG_MP_ACTIVE 0x2000
|
#define WIIPROTO_FLAG_MP_ACTIVE 0x2000
|
||||||
#define WIIPROTO_FLAG_EXITING 0x4000
|
#define WIIPROTO_FLAG_EXITING 0x4000
|
||||||
#define WIIPROTO_FLAG_DRM_LOCKED 0x8000
|
#define WIIPROTO_FLAG_DRM_LOCKED 0x8000
|
||||||
|
#define WIIPROTO_FLAG_BUILTIN_MP 0x010000
|
||||||
|
#define WIIPROTO_FLAG_NO_MP 0x020000
|
||||||
|
|
||||||
#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
|
#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
|
||||||
WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
|
WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
|
||||||
|
@ -165,6 +167,8 @@ enum wiimod_module {
|
||||||
WIIMOD_LED4,
|
WIIMOD_LED4,
|
||||||
WIIMOD_ACCEL,
|
WIIMOD_ACCEL,
|
||||||
WIIMOD_IR,
|
WIIMOD_IR,
|
||||||
|
WIIMOD_BUILTIN_MP,
|
||||||
|
WIIMOD_NO_MP,
|
||||||
WIIMOD_NUM,
|
WIIMOD_NUM,
|
||||||
WIIMOD_NULL = WIIMOD_NUM,
|
WIIMOD_NULL = WIIMOD_NUM,
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче