2 * HID driver for Nintendo Wiimote extension devices
3 * Copyright (c) 2011 David Herrmann
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
13 #include <linux/atomic.h>
14 #include <linux/module.h>
15 #include <linux/spinlock.h>
16 #include <linux/workqueue.h>
17 #include "hid-wiimote.h"
20 struct wiimote_data
*wdata
;
21 struct work_struct worker
;
31 WIIEXT_NONE
, /* placeholder */
32 WIIEXT_CLASSIC
, /* Nintendo classic controller */
33 WIIEXT_NUNCHUCK
, /* Nintendo nunchuck controller */
36 /* diable all extensions */
37 static void ext_disable(struct wiimote_ext
*ext
)
41 spin_lock_irqsave(&ext
->wdata
->state
.lock
, flags
);
43 ext
->ext_type
= WIIEXT_NONE
;
44 spin_unlock_irqrestore(&ext
->wdata
->state
.lock
, flags
);
47 static bool motionp_read(struct wiimote_ext
*ext
)
52 static __u8
ext_read(struct wiimote_ext
*ext
)
57 static void ext_enable(struct wiimote_ext
*ext
, bool motionp
, __u8 ext_type
)
61 spin_lock_irqsave(&ext
->wdata
->state
.lock
, flags
);
62 ext
->motionp
= motionp
;
63 ext
->ext_type
= ext_type
;
64 spin_unlock_irqrestore(&ext
->wdata
->state
.lock
, flags
);
67 static void wiiext_worker(struct work_struct
*work
)
69 struct wiimote_ext
*ext
= container_of(work
, struct wiimote_ext
,
75 motionp
= motionp_read(ext
);
76 ext_type
= ext_read(ext
);
77 ext_enable(ext
, motionp
, ext_type
);
80 /* schedule work only once, otherwise mark for reschedule */
81 static void wiiext_schedule(struct wiimote_ext
*ext
)
83 queue_work(system_nrt_wq
, &ext
->worker
);
87 * Reacts on extension port events
88 * Whenever the driver gets an event from the wiimote that an extension has been
89 * plugged or unplugged, this funtion shall be called. It checks what extensions
90 * are connected and initializes and activates them.
91 * This can be called in atomic context. The initialization is done in a
92 * separate worker thread. The state.lock spinlock must be held by the caller.
94 void wiiext_event(struct wiimote_data
*wdata
, bool plugged
)
99 if (wdata
->ext
->plugged
== plugged
)
102 wdata
->ext
->plugged
= plugged
;
104 * We need to call wiiext_schedule(wdata->ext) here, however, the
105 * extension initialization logic is not fully understood and so
106 * automatic initialization is not supported, yet.
111 * Returns true if the current DRM mode should contain extension data and false
112 * if there is no interest in extension data.
113 * All supported extensions send 6 byte extension data so any DRM that contains
114 * extension bytes is fine.
115 * The caller must hold the state.lock spinlock.
117 bool wiiext_active(struct wiimote_data
*wdata
)
122 return wdata
->ext
->motionp
|| wdata
->ext
->ext_type
;
125 /* Initializes the extension driver of a wiimote */
126 int wiiext_init(struct wiimote_data
*wdata
)
128 struct wiimote_ext
*ext
;
131 ext
= kzalloc(sizeof(*ext
), GFP_KERNEL
);
136 INIT_WORK(&ext
->worker
, wiiext_worker
);
138 spin_lock_irqsave(&wdata
->state
.lock
, flags
);
140 spin_unlock_irqrestore(&wdata
->state
.lock
, flags
);
145 /* Deinitializes the extension driver of a wiimote */
146 void wiiext_deinit(struct wiimote_data
*wdata
)
148 struct wiimote_ext
*ext
= wdata
->ext
;
155 * We first unset wdata->ext to avoid further input from the wiimote
156 * core. The worker thread does not access this pointer so it is not
158 * We kill the worker after this so it does not get respawned during
162 spin_lock_irqsave(&wdata
->state
.lock
, flags
);
164 spin_unlock_irqrestore(&wdata
->state
.lock
, flags
);
166 cancel_work_sync(&ext
->worker
);
This page took 0.036792 seconds and 6 git commands to generate.