blob: c86ae92b51db7ad8d3dd3f138520833c8b585273 [file] [log] [blame]
David Herrmannfb51b442011-07-05 13:45:08 +02001/*
2 * HID driver for Nintendo Wiimote devices
3 * Copyright (c) 2011 David Herrmann
4 */
5
6/*
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)
10 * any later version.
11 */
12
David Herrmann4d36e972011-07-05 13:45:12 +020013#include <linux/atomic.h>
David Herrmann672bc4e2011-07-05 13:45:11 +020014#include <linux/device.h>
David Herrmann02fb72a2011-07-05 13:45:09 +020015#include <linux/hid.h>
David Herrmann672bc4e2011-07-05 13:45:11 +020016#include <linux/input.h>
David Herrmannfb51b442011-07-05 13:45:08 +020017#include <linux/module.h>
David Herrmann23c063c2011-07-05 13:45:14 +020018#include <linux/spinlock.h>
David Herrmann02fb72a2011-07-05 13:45:09 +020019#include "hid-ids.h"
David Herrmannfb51b442011-07-05 13:45:08 +020020
21#define WIIMOTE_VERSION "0.1"
22#define WIIMOTE_NAME "Nintendo Wii Remote"
David Herrmann23c063c2011-07-05 13:45:14 +020023#define WIIMOTE_BUFSIZE 32
24
25struct wiimote_buf {
26 __u8 data[HID_MAX_BUFFER_SIZE];
27 size_t size;
28};
David Herrmannfb51b442011-07-05 13:45:08 +020029
David Herrmanne894d0e2011-07-05 13:45:10 +020030struct wiimote_data {
David Herrmann4d36e972011-07-05 13:45:12 +020031 atomic_t ready;
David Herrmanne894d0e2011-07-05 13:45:10 +020032 struct hid_device *hdev;
David Herrmann672bc4e2011-07-05 13:45:11 +020033 struct input_dev *input;
David Herrmann23c063c2011-07-05 13:45:14 +020034
35 spinlock_t qlock;
36 __u8 head;
37 __u8 tail;
38 struct wiimote_buf outq[WIIMOTE_BUFSIZE];
39 struct work_struct worker;
David Herrmanne894d0e2011-07-05 13:45:10 +020040};
41
David Herrmann0c218f142011-07-05 13:45:13 +020042static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
43 size_t count)
44{
45 __u8 *buf;
46 ssize_t ret;
47
48 if (!hdev->hid_output_raw_report)
49 return -ENODEV;
50
51 buf = kmemdup(buffer, count, GFP_KERNEL);
52 if (!buf)
53 return -ENOMEM;
54
55 ret = hdev->hid_output_raw_report(hdev, buf, count, HID_OUTPUT_REPORT);
56
57 kfree(buf);
58 return ret;
59}
60
David Herrmann23c063c2011-07-05 13:45:14 +020061static void wiimote_worker(struct work_struct *work)
62{
63 struct wiimote_data *wdata = container_of(work, struct wiimote_data,
64 worker);
65 unsigned long flags;
66
67 spin_lock_irqsave(&wdata->qlock, flags);
68
69 while (wdata->head != wdata->tail) {
70 spin_unlock_irqrestore(&wdata->qlock, flags);
71 wiimote_hid_send(wdata->hdev, wdata->outq[wdata->tail].data,
72 wdata->outq[wdata->tail].size);
73 spin_lock_irqsave(&wdata->qlock, flags);
74
75 wdata->tail = (wdata->tail + 1) % WIIMOTE_BUFSIZE;
76 }
77
78 spin_unlock_irqrestore(&wdata->qlock, flags);
79}
80
81static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer,
82 size_t count)
83{
84 unsigned long flags;
85 __u8 newhead;
86
87 if (count > HID_MAX_BUFFER_SIZE) {
88 hid_warn(wdata->hdev, "Sending too large output report\n");
89 return;
90 }
91
92 /*
93 * Copy new request into our output queue and check whether the
94 * queue is full. If it is full, discard this request.
95 * If it is empty we need to start a new worker that will
96 * send out the buffer to the hid device.
97 * If the queue is not empty, then there must be a worker
98 * that is currently sending out our buffer and this worker
99 * will reschedule itself until the queue is empty.
100 */
101
102 spin_lock_irqsave(&wdata->qlock, flags);
103
104 memcpy(wdata->outq[wdata->head].data, buffer, count);
105 wdata->outq[wdata->head].size = count;
106 newhead = (wdata->head + 1) % WIIMOTE_BUFSIZE;
107
108 if (wdata->head == wdata->tail) {
109 wdata->head = newhead;
110 schedule_work(&wdata->worker);
111 } else if (newhead != wdata->tail) {
112 wdata->head = newhead;
113 } else {
114 hid_warn(wdata->hdev, "Output queue is full");
115 }
116
117 spin_unlock_irqrestore(&wdata->qlock, flags);
118}
119
David Herrmann672bc4e2011-07-05 13:45:11 +0200120static int wiimote_input_event(struct input_dev *dev, unsigned int type,
121 unsigned int code, int value)
122{
David Herrmann4d36e972011-07-05 13:45:12 +0200123 struct wiimote_data *wdata = input_get_drvdata(dev);
124
125 if (!atomic_read(&wdata->ready))
126 return -EBUSY;
127 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
128 smp_rmb();
129
David Herrmann672bc4e2011-07-05 13:45:11 +0200130 return 0;
131}
132
David Herrmanna4d19192011-07-05 13:45:15 +0200133struct wiiproto_handler {
134 __u8 id;
135 size_t size;
136 void (*func)(struct wiimote_data *wdata, const __u8 *payload);
137};
138
139static struct wiiproto_handler handlers[] = {
140 { .id = 0 }
141};
142
David Herrmann02fb72a2011-07-05 13:45:09 +0200143static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
144 u8 *raw_data, int size)
145{
David Herrmann4d36e972011-07-05 13:45:12 +0200146 struct wiimote_data *wdata = hid_get_drvdata(hdev);
David Herrmanna4d19192011-07-05 13:45:15 +0200147 struct wiiproto_handler *h;
148 int i;
David Herrmann4d36e972011-07-05 13:45:12 +0200149
150 if (!atomic_read(&wdata->ready))
151 return -EBUSY;
152 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
153 smp_rmb();
154
David Herrmann02fb72a2011-07-05 13:45:09 +0200155 if (size < 1)
156 return -EINVAL;
157
David Herrmanna4d19192011-07-05 13:45:15 +0200158 for (i = 0; handlers[i].id; ++i) {
159 h = &handlers[i];
160 if (h->id == raw_data[0] && h->size < size)
161 h->func(wdata, &raw_data[1]);
162 }
163
David Herrmann02fb72a2011-07-05 13:45:09 +0200164 return 0;
165}
166
David Herrmanne894d0e2011-07-05 13:45:10 +0200167static struct wiimote_data *wiimote_create(struct hid_device *hdev)
168{
169 struct wiimote_data *wdata;
170
171 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
172 if (!wdata)
173 return NULL;
174
David Herrmann672bc4e2011-07-05 13:45:11 +0200175 wdata->input = input_allocate_device();
176 if (!wdata->input) {
177 kfree(wdata);
178 return NULL;
179 }
180
David Herrmanne894d0e2011-07-05 13:45:10 +0200181 wdata->hdev = hdev;
182 hid_set_drvdata(hdev, wdata);
183
David Herrmann672bc4e2011-07-05 13:45:11 +0200184 input_set_drvdata(wdata->input, wdata);
185 wdata->input->event = wiimote_input_event;
186 wdata->input->dev.parent = &wdata->hdev->dev;
187 wdata->input->id.bustype = wdata->hdev->bus;
188 wdata->input->id.vendor = wdata->hdev->vendor;
189 wdata->input->id.product = wdata->hdev->product;
190 wdata->input->id.version = wdata->hdev->version;
191 wdata->input->name = WIIMOTE_NAME;
192
David Herrmann23c063c2011-07-05 13:45:14 +0200193 spin_lock_init(&wdata->qlock);
194 INIT_WORK(&wdata->worker, wiimote_worker);
195
David Herrmanne894d0e2011-07-05 13:45:10 +0200196 return wdata;
197}
198
199static void wiimote_destroy(struct wiimote_data *wdata)
200{
201 kfree(wdata);
202}
203
David Herrmann02fb72a2011-07-05 13:45:09 +0200204static int wiimote_hid_probe(struct hid_device *hdev,
205 const struct hid_device_id *id)
206{
David Herrmanne894d0e2011-07-05 13:45:10 +0200207 struct wiimote_data *wdata;
David Herrmann02fb72a2011-07-05 13:45:09 +0200208 int ret;
209
David Herrmanne894d0e2011-07-05 13:45:10 +0200210 wdata = wiimote_create(hdev);
211 if (!wdata) {
212 hid_err(hdev, "Can't alloc device\n");
213 return -ENOMEM;
214 }
215
David Herrmann02fb72a2011-07-05 13:45:09 +0200216 ret = hid_parse(hdev);
217 if (ret) {
218 hid_err(hdev, "HID parse failed\n");
David Herrmanne894d0e2011-07-05 13:45:10 +0200219 goto err;
David Herrmann02fb72a2011-07-05 13:45:09 +0200220 }
221
222 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
223 if (ret) {
224 hid_err(hdev, "HW start failed\n");
David Herrmanne894d0e2011-07-05 13:45:10 +0200225 goto err;
David Herrmann02fb72a2011-07-05 13:45:09 +0200226 }
227
David Herrmann672bc4e2011-07-05 13:45:11 +0200228 ret = input_register_device(wdata->input);
229 if (ret) {
230 hid_err(hdev, "Cannot register input device\n");
231 goto err_stop;
232 }
233
David Herrmann4d36e972011-07-05 13:45:12 +0200234 /* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */
235 smp_wmb();
236 atomic_set(&wdata->ready, 1);
David Herrmann02fb72a2011-07-05 13:45:09 +0200237 hid_info(hdev, "New device registered\n");
238 return 0;
David Herrmanne894d0e2011-07-05 13:45:10 +0200239
David Herrmann672bc4e2011-07-05 13:45:11 +0200240err_stop:
241 hid_hw_stop(hdev);
David Herrmanne894d0e2011-07-05 13:45:10 +0200242err:
David Herrmann672bc4e2011-07-05 13:45:11 +0200243 input_free_device(wdata->input);
David Herrmanne894d0e2011-07-05 13:45:10 +0200244 wiimote_destroy(wdata);
245 return ret;
David Herrmann02fb72a2011-07-05 13:45:09 +0200246}
247
248static void wiimote_hid_remove(struct hid_device *hdev)
249{
David Herrmanne894d0e2011-07-05 13:45:10 +0200250 struct wiimote_data *wdata = hid_get_drvdata(hdev);
251
David Herrmann02fb72a2011-07-05 13:45:09 +0200252 hid_info(hdev, "Device removed\n");
David Herrmann23c063c2011-07-05 13:45:14 +0200253
David Herrmann02fb72a2011-07-05 13:45:09 +0200254 hid_hw_stop(hdev);
David Herrmann672bc4e2011-07-05 13:45:11 +0200255 input_unregister_device(wdata->input);
David Herrmann23c063c2011-07-05 13:45:14 +0200256
257 cancel_work_sync(&wdata->worker);
David Herrmanne894d0e2011-07-05 13:45:10 +0200258 wiimote_destroy(wdata);
David Herrmann02fb72a2011-07-05 13:45:09 +0200259}
260
261static const struct hid_device_id wiimote_hid_devices[] = {
262 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
263 USB_DEVICE_ID_NINTENDO_WIIMOTE) },
264 { }
265};
266MODULE_DEVICE_TABLE(hid, wiimote_hid_devices);
267
268static struct hid_driver wiimote_hid_driver = {
269 .name = "wiimote",
270 .id_table = wiimote_hid_devices,
271 .probe = wiimote_hid_probe,
272 .remove = wiimote_hid_remove,
273 .raw_event = wiimote_hid_event,
274};
275
David Herrmannfb51b442011-07-05 13:45:08 +0200276static int __init wiimote_init(void)
277{
David Herrmann02fb72a2011-07-05 13:45:09 +0200278 int ret;
279
280 ret = hid_register_driver(&wiimote_hid_driver);
281 if (ret)
282 pr_err("Can't register wiimote hid driver\n");
283
284 return ret;
David Herrmannfb51b442011-07-05 13:45:08 +0200285}
286
287static void __exit wiimote_exit(void)
288{
David Herrmann02fb72a2011-07-05 13:45:09 +0200289 hid_unregister_driver(&wiimote_hid_driver);
David Herrmannfb51b442011-07-05 13:45:08 +0200290}
291
292module_init(wiimote_init);
293module_exit(wiimote_exit);
294MODULE_LICENSE("GPL");
295MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
296MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver");
297MODULE_VERSION(WIIMOTE_VERSION);