WIIMOD_NULL,
},
[WIIMOTE_DEV_UNKNOWN] = (const __u8[]){
+ WIIMOD_NO_MP,
WIIMOD_NULL,
},
[WIIMOTE_DEV_GENERIC] = (const __u8[]){
WIIMOD_LED4,
WIIMOD_ACCEL,
WIIMOD_IR,
+ WIIMOD_BUILTIN_MP,
WIIMOD_NULL,
},
[WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) {
WIIMOD_BATTERY,
WIIMOD_LED1,
+ WIIMOD_NO_MP,
WIIMOD_NULL,
},
};
out_release:
wiimote_cmd_release(wdata);
wiimote_init_set_type(wdata, exttype);
+
/* schedule MP timer */
- mod_timer(&wdata->timer, jiffies + HZ * 4);
+ 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);
+ spin_unlock_irq(&wdata->state.lock);
}
/*
wiimote_cmd_release(wdata);
/* 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);
return ret;
/* init extension and MP (deactivates current extension or MP) */
wiimote_cmd_init_ext(wdata);
- wiimote_cmd_init_mp(wdata);
- mp = wiimote_cmd_read_mp(wdata, mpdata);
+ if (flags & WIIPROTO_FLAG_NO_MP) {
+ mp = false;
+ } else {
+ wiimote_cmd_init_mp(wdata);
+ mp = wiimote_cmd_read_mp(wdata, mpdata);
+ }
exttype = wiimote_cmd_read_ext(wdata, extdata);
wiimote_cmd_release(wdata);
del_timer_sync(&wdata->timer);
} else {
/* reschedule MP hotplug timer */
- mod_timer(&wdata->timer, jiffies + HZ * 4);
+ if (!(flags & WIIPROTO_FLAG_BUILTIN_MP) &&
+ !(flags & WIIPROTO_FLAG_NO_MP))
+ mod_timer(&wdata->timer, jiffies + HZ * 4);
}
spin_lock_irq(&wdata->state.lock);
};
/*
+ * 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
* The Motion Plus extension provides rotation sensors (gyro) as a small
* extension device for Wii Remotes. Many devices have them built-in so
[WIIMOD_LED4] = &wiimod_leds[3],
[WIIMOD_ACCEL] = &wiimod_accel,
[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] = {