diff options
-rw-r--r-- | drivers/media/IR/Kconfig | 12 | ||||
-rw-r--r-- | drivers/media/IR/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/IR/mceusb.c | 1085 |
3 files changed, 1098 insertions, 0 deletions
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index d22a8ec523fc..07fca4c5165a 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig | |||
@@ -68,3 +68,15 @@ config IR_IMON | |||
68 | 68 | ||
69 | To compile this driver as a module, choose M here: the | 69 | To compile this driver as a module, choose M here: the |
70 | module will be called imon. | 70 | module will be called imon. |
71 | |||
72 | config IR_MCEUSB | ||
73 | tristate "Windows Media Center Ed. eHome Infrared Transceiver" | ||
74 | depends on USB_ARCH_HAS_HCD | ||
75 | depends on IR_CORE | ||
76 | select USB | ||
77 | ---help--- | ||
78 | Say Y here if you want to use a Windows Media Center Edition | ||
79 | eHome Infrared Transceiver. | ||
80 | |||
81 | To compile this driver as a module, choose M here: the | ||
82 | module will be called mceusb. | ||
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile index b998fcced2e4..b43fe36d88b2 100644 --- a/drivers/media/IR/Makefile +++ b/drivers/media/IR/Makefile | |||
@@ -13,3 +13,4 @@ obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o | |||
13 | 13 | ||
14 | # stand-alone IR receivers/transmitters | 14 | # stand-alone IR receivers/transmitters |
15 | obj-$(CONFIG_IR_IMON) += imon.o | 15 | obj-$(CONFIG_IR_IMON) += imon.o |
16 | obj-$(CONFIG_IR_MCEUSB) += mceusb.o | ||
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c new file mode 100644 index 000000000000..fe150911a1c4 --- /dev/null +++ b/drivers/media/IR/mceusb.c | |||
@@ -0,0 +1,1085 @@ | |||
1 | /* | ||
2 | * Driver for USB Windows Media Center Ed. eHome Infrared Transceivers | ||
3 | * | ||
4 | * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com> | ||
5 | * | ||
6 | * Based on the original lirc_mceusb and lirc_mceusb2 drivers, by Dan | ||
7 | * Conti, Martin Blatter and Daniel Melander, the latter of which was | ||
8 | * in turn also based on the lirc_atiusb driver by Paul Miller. The | ||
9 | * two mce drivers were merged into one by Jarod Wilson, with transmit | ||
10 | * support for the 1st-gen device added primarily by Patrick Calhoun, | ||
11 | * with a bit of tweaks by Jarod. Debugging improvements and proper | ||
12 | * support for what appears to be 3rd-gen hardware added by Jarod. | ||
13 | * Initial port from lirc driver to ir-core drivery by Jarod, based | ||
14 | * partially on a port to an earlier proposed IR infrastructure by | ||
15 | * Jon Smirl, which included enhancements and simplifications to the | ||
16 | * incoming IR buffer parsing routines. | ||
17 | * | ||
18 | * TODO: | ||
19 | * - add rc-core transmit support, once available | ||
20 | * - enable support for forthcoming ir-lirc-codec interface | ||
21 | * | ||
22 | * | ||
23 | * This program is free software; you can redistribute it and/or modify | ||
24 | * it under the terms of the GNU General Public License as published by | ||
25 | * the Free Software Foundation; either version 2 of the License, or | ||
26 | * (at your option) any later version. | ||
27 | * | ||
28 | * This program is distributed in the hope that it will be useful, | ||
29 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
30 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
31 | * GNU General Public License for more details. | ||
32 | * | ||
33 | * You should have received a copy of the GNU General Public License | ||
34 | * along with this program; if not, write to the Free Software | ||
35 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | #include <linux/device.h> | ||
40 | #include <linux/module.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/usb.h> | ||
43 | #include <linux/input.h> | ||
44 | #include <media/ir-core.h> | ||
45 | #include <media/ir-common.h> | ||
46 | |||
47 | #define DRIVER_VERSION "1.91" | ||
48 | #define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" | ||
49 | #define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \ | ||
50 | "device driver" | ||
51 | #define DRIVER_NAME "mceusb" | ||
52 | |||
53 | #define USB_BUFLEN 32 /* USB reception buffer length */ | ||
54 | #define IRBUF_SIZE 256 /* IR work buffer length */ | ||
55 | |||
56 | /* MCE constants */ | ||
57 | #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ | ||
58 | #define MCE_TIME_UNIT 50 /* Approx 50us resolution */ | ||
59 | #define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ | ||
60 | #define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ | ||
61 | #define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ | ||
62 | #define MCE_CONTROL_HEADER 0x9F /* MCE status header */ | ||
63 | #define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ | ||
64 | #define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ | ||
65 | #define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */ | ||
66 | #define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ | ||
67 | #define MCE_PULSE_MASK 0x7F /* Pulse mask */ | ||
68 | #define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */ | ||
69 | #define MCE_PACKET_LENGTH_MASK 0xF /* Packet length mask */ | ||
70 | |||
71 | |||
72 | /* module parameters */ | ||
73 | #ifdef CONFIG_USB_DEBUG | ||
74 | static int debug = 1; | ||
75 | #else | ||
76 | static int debug; | ||
77 | #endif | ||
78 | |||
79 | /* general constants */ | ||
80 | #define SEND_FLAG_IN_PROGRESS 1 | ||
81 | #define SEND_FLAG_COMPLETE 2 | ||
82 | #define RECV_FLAG_IN_PROGRESS 3 | ||
83 | #define RECV_FLAG_COMPLETE 4 | ||
84 | |||
85 | #define MCEUSB_RX 1 | ||
86 | #define MCEUSB_TX 2 | ||
87 | |||
88 | #define VENDOR_PHILIPS 0x0471 | ||
89 | #define VENDOR_SMK 0x0609 | ||
90 | #define VENDOR_TATUNG 0x1460 | ||
91 | #define VENDOR_GATEWAY 0x107b | ||
92 | #define VENDOR_SHUTTLE 0x1308 | ||
93 | #define VENDOR_SHUTTLE2 0x051c | ||
94 | #define VENDOR_MITSUMI 0x03ee | ||
95 | #define VENDOR_TOPSEED 0x1784 | ||
96 | #define VENDOR_RICAVISION 0x179d | ||
97 | #define VENDOR_ITRON 0x195d | ||
98 | #define VENDOR_FIC 0x1509 | ||
99 | #define VENDOR_LG 0x043e | ||
100 | #define VENDOR_MICROSOFT 0x045e | ||
101 | #define VENDOR_FORMOSA 0x147a | ||
102 | #define VENDOR_FINTEK 0x1934 | ||
103 | #define VENDOR_PINNACLE 0x2304 | ||
104 | #define VENDOR_ECS 0x1019 | ||
105 | #define VENDOR_WISTRON 0x0fb8 | ||
106 | #define VENDOR_COMPRO 0x185b | ||
107 | #define VENDOR_NORTHSTAR 0x04eb | ||
108 | #define VENDOR_REALTEK 0x0bda | ||
109 | #define VENDOR_TIVO 0x105a | ||
110 | |||
111 | static struct usb_device_id mceusb_dev_table[] = { | ||
112 | /* Original Microsoft MCE IR Transceiver (often HP-branded) */ | ||
113 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | ||
114 | /* Philips Infrared Transceiver - Sahara branded */ | ||
115 | { USB_DEVICE(VENDOR_PHILIPS, 0x0608) }, | ||
116 | /* Philips Infrared Transceiver - HP branded */ | ||
117 | { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, | ||
118 | /* Philips SRM5100 */ | ||
119 | { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, | ||
120 | /* Philips Infrared Transceiver - Omaura */ | ||
121 | { USB_DEVICE(VENDOR_PHILIPS, 0x060f) }, | ||
122 | /* Philips Infrared Transceiver - Spinel plus */ | ||
123 | { USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, | ||
124 | /* Philips eHome Infrared Transceiver */ | ||
125 | { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, | ||
126 | /* Realtek MCE IR Receiver */ | ||
127 | { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, | ||
128 | /* SMK/Toshiba G83C0004D410 */ | ||
129 | { USB_DEVICE(VENDOR_SMK, 0x031d) }, | ||
130 | /* SMK eHome Infrared Transceiver (Sony VAIO) */ | ||
131 | { USB_DEVICE(VENDOR_SMK, 0x0322) }, | ||
132 | /* bundled with Hauppauge PVR-150 */ | ||
133 | { USB_DEVICE(VENDOR_SMK, 0x0334) }, | ||
134 | /* SMK eHome Infrared Transceiver */ | ||
135 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, | ||
136 | /* Tatung eHome Infrared Transceiver */ | ||
137 | { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, | ||
138 | /* Shuttle eHome Infrared Transceiver */ | ||
139 | { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) }, | ||
140 | /* Shuttle eHome Infrared Transceiver */ | ||
141 | { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) }, | ||
142 | /* Gateway eHome Infrared Transceiver */ | ||
143 | { USB_DEVICE(VENDOR_GATEWAY, 0x3009) }, | ||
144 | /* Mitsumi */ | ||
145 | { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, | ||
146 | /* Topseed eHome Infrared Transceiver */ | ||
147 | { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, | ||
148 | /* Topseed HP eHome Infrared Transceiver */ | ||
149 | { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, | ||
150 | /* Topseed eHome Infrared Transceiver */ | ||
151 | { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, | ||
152 | /* Topseed eHome Infrared Transceiver */ | ||
153 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | ||
154 | /* Topseed eHome Infrared Transceiver */ | ||
155 | { USB_DEVICE(VENDOR_TOPSEED, 0x000a) }, | ||
156 | /* Topseed eHome Infrared Transceiver */ | ||
157 | { USB_DEVICE(VENDOR_TOPSEED, 0x0011) }, | ||
158 | /* Ricavision internal Infrared Transceiver */ | ||
159 | { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, | ||
160 | /* Itron ione Libra Q-11 */ | ||
161 | { USB_DEVICE(VENDOR_ITRON, 0x7002) }, | ||
162 | /* FIC eHome Infrared Transceiver */ | ||
163 | { USB_DEVICE(VENDOR_FIC, 0x9242) }, | ||
164 | /* LG eHome Infrared Transceiver */ | ||
165 | { USB_DEVICE(VENDOR_LG, 0x9803) }, | ||
166 | /* Microsoft MCE Infrared Transceiver */ | ||
167 | { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) }, | ||
168 | /* Formosa eHome Infrared Transceiver */ | ||
169 | { USB_DEVICE(VENDOR_FORMOSA, 0xe015) }, | ||
170 | /* Formosa21 / eHome Infrared Receiver */ | ||
171 | { USB_DEVICE(VENDOR_FORMOSA, 0xe016) }, | ||
172 | /* Formosa aim / Trust MCE Infrared Receiver */ | ||
173 | { USB_DEVICE(VENDOR_FORMOSA, 0xe017) }, | ||
174 | /* Formosa Industrial Computing / Beanbag Emulation Device */ | ||
175 | { USB_DEVICE(VENDOR_FORMOSA, 0xe018) }, | ||
176 | /* Formosa21 / eHome Infrared Receiver */ | ||
177 | { USB_DEVICE(VENDOR_FORMOSA, 0xe03a) }, | ||
178 | /* Formosa Industrial Computing AIM IR605/A */ | ||
179 | { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, | ||
180 | /* Formosa Industrial Computing */ | ||
181 | { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, | ||
182 | /* Fintek eHome Infrared Transceiver */ | ||
183 | { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, | ||
184 | /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ | ||
185 | { USB_DEVICE(VENDOR_FINTEK, 0x0702) }, | ||
186 | /* Pinnacle Remote Kit */ | ||
187 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | ||
188 | /* Elitegroup Computer Systems IR */ | ||
189 | { USB_DEVICE(VENDOR_ECS, 0x0f38) }, | ||
190 | /* Wistron Corp. eHome Infrared Receiver */ | ||
191 | { USB_DEVICE(VENDOR_WISTRON, 0x0002) }, | ||
192 | /* Compro K100 */ | ||
193 | { USB_DEVICE(VENDOR_COMPRO, 0x3020) }, | ||
194 | /* Compro K100 v2 */ | ||
195 | { USB_DEVICE(VENDOR_COMPRO, 0x3082) }, | ||
196 | /* Northstar Systems, Inc. eHome Infrared Transceiver */ | ||
197 | { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, | ||
198 | /* TiVo PC IR Receiver */ | ||
199 | { USB_DEVICE(VENDOR_TIVO, 0x2000) }, | ||
200 | /* Terminating entry */ | ||
201 | { } | ||
202 | }; | ||
203 | |||
204 | static struct usb_device_id gen3_list[] = { | ||
205 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | ||
206 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | ||
207 | {} | ||
208 | }; | ||
209 | |||
210 | static struct usb_device_id pinnacle_list[] = { | ||
211 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | ||
212 | {} | ||
213 | }; | ||
214 | |||
215 | static struct usb_device_id microsoft_gen1_list[] = { | ||
216 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | ||
217 | {} | ||
218 | }; | ||
219 | |||
220 | /* data structure for each usb transceiver */ | ||
221 | struct mceusb_dev { | ||
222 | /* ir-core bits */ | ||
223 | struct ir_input_dev *irdev; | ||
224 | struct ir_dev_props *props; | ||
225 | struct ir_input_state *state; | ||
226 | struct ir_raw_event rawir; | ||
227 | |||
228 | /* core device bits */ | ||
229 | struct device *dev; | ||
230 | struct input_dev *idev; | ||
231 | |||
232 | /* usb */ | ||
233 | struct usb_device *usbdev; | ||
234 | struct urb *urb_in; | ||
235 | struct usb_endpoint_descriptor *usb_ep_in; | ||
236 | struct usb_endpoint_descriptor *usb_ep_out; | ||
237 | |||
238 | /* buffers and dma */ | ||
239 | unsigned char *buf_in; | ||
240 | unsigned int len_in; | ||
241 | u8 cmd; /* MCE command type */ | ||
242 | u8 rem; /* Remaining IR data bytes in packet */ | ||
243 | dma_addr_t dma_in; | ||
244 | dma_addr_t dma_out; | ||
245 | |||
246 | struct { | ||
247 | u32 connected:1; | ||
248 | u32 def_xmit_mask_set:1; | ||
249 | u32 microsoft_gen1:1; | ||
250 | u32 gen3:1; | ||
251 | u32 reserved:28; | ||
252 | } flags; | ||
253 | |||
254 | /* handle sending (init strings) */ | ||
255 | int send_flags; | ||
256 | int carrier; | ||
257 | |||
258 | char name[128]; | ||
259 | char phys[64]; | ||
260 | |||
261 | unsigned char def_xmit_mask; | ||
262 | unsigned char cur_xmit_mask; | ||
263 | }; | ||
264 | |||
265 | /* | ||
266 | * MCE Device Command Strings | ||
267 | * Device command responses vary from device to device... | ||
268 | * - DEVICE_RESET resets the hardware to its default state | ||
269 | * - GET_REVISION fetches the hardware/software revision, common | ||
270 | * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42 | ||
271 | * - GET_CARRIER_FREQ gets the carrier mode and frequency of the | ||
272 | * device, with replies in the form of 9f 06 MM FF, where MM is 0-3, | ||
273 | * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is | ||
274 | * ((clk / frequency) - 1) | ||
275 | * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us, | ||
276 | * response in the form of 9f 0c msb lsb | ||
277 | * - GET_TX_BITMASK fetches the transmitter bitmask, replies in | ||
278 | * the form of 9f 08 bm, where bm is the bitmask | ||
279 | * - GET_RX_SENSOR fetches the RX sensor setting -- long-range | ||
280 | * general use one or short-range learning one, in the form of | ||
281 | * 9f 14 ss, where ss is either 01 for long-range or 02 for short | ||
282 | * - SET_CARRIER_FREQ sets a new carrier mode and frequency | ||
283 | * - SET_TX_BITMASK sets the transmitter bitmask | ||
284 | * - SET_RX_TIMEOUT sets the receiver timeout | ||
285 | * - SET_RX_SENSOR sets which receiver sensor to use | ||
286 | */ | ||
287 | static char DEVICE_RESET[] = {0x00, 0xff, 0xaa}; | ||
288 | static char GET_REVISION[] = {0xff, 0x0b}; | ||
289 | static char GET_UNKNOWN[] = {0xff, 0x18}; | ||
290 | static char GET_CARRIER_FREQ[] = {0x9f, 0x07}; | ||
291 | static char GET_RX_TIMEOUT[] = {0x9f, 0x0d}; | ||
292 | static char GET_TX_BITMASK[] = {0x9f, 0x13}; | ||
293 | static char GET_RX_SENSOR[] = {0x9f, 0x15}; | ||
294 | /* sub in desired values in lower byte or bytes for full command */ | ||
295 | /* FIXME: make use of these for transmit. | ||
296 | static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00}; | ||
297 | static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00}; | ||
298 | static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00}; | ||
299 | static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00}; | ||
300 | */ | ||
301 | |||
302 | static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | ||
303 | int len, bool out) | ||
304 | { | ||
305 | char codes[USB_BUFLEN * 3 + 1]; | ||
306 | char inout[9]; | ||
307 | int i; | ||
308 | u8 cmd, subcmd, data1, data2; | ||
309 | struct device *dev = ir->dev; | ||
310 | |||
311 | if (len <= 0) | ||
312 | return; | ||
313 | |||
314 | if (ir->flags.microsoft_gen1 && len <= 2) | ||
315 | return; | ||
316 | |||
317 | for (i = 0; i < len && i < USB_BUFLEN; i++) | ||
318 | snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF); | ||
319 | |||
320 | dev_info(dev, "%sx data: %s (length=%d)\n", | ||
321 | (out ? "t" : "r"), codes, len); | ||
322 | |||
323 | if (out) | ||
324 | strcpy(inout, "Request\0"); | ||
325 | else | ||
326 | strcpy(inout, "Got\0"); | ||
327 | |||
328 | cmd = buf[0] & 0xff; | ||
329 | subcmd = buf[1] & 0xff; | ||
330 | data1 = buf[2] & 0xff; | ||
331 | data2 = buf[3] & 0xff; | ||
332 | |||
333 | switch (cmd) { | ||
334 | case 0x00: | ||
335 | if (subcmd == 0xff && data1 == 0xaa) | ||
336 | dev_info(dev, "Device reset requested\n"); | ||
337 | else | ||
338 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | ||
339 | cmd, subcmd); | ||
340 | break; | ||
341 | case 0xff: | ||
342 | switch (subcmd) { | ||
343 | case 0x0b: | ||
344 | if (len == 2) | ||
345 | dev_info(dev, "Get hw/sw rev?\n"); | ||
346 | else | ||
347 | dev_info(dev, "hw/sw rev 0x%02x 0x%02x " | ||
348 | "0x%02x 0x%02x\n", data1, data2, | ||
349 | buf[4], buf[5]); | ||
350 | break; | ||
351 | case 0xaa: | ||
352 | dev_info(dev, "Device reset requested\n"); | ||
353 | break; | ||
354 | case 0xfe: | ||
355 | dev_info(dev, "Previous command not supported\n"); | ||
356 | break; | ||
357 | case 0x18: | ||
358 | case 0x1b: | ||
359 | default: | ||
360 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | ||
361 | cmd, subcmd); | ||
362 | break; | ||
363 | } | ||
364 | break; | ||
365 | case 0x9f: | ||
366 | switch (subcmd) { | ||
367 | case 0x03: | ||
368 | dev_info(dev, "Ping\n"); | ||
369 | break; | ||
370 | case 0x04: | ||
371 | dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", | ||
372 | data1, data2); | ||
373 | break; | ||
374 | case 0x06: | ||
375 | dev_info(dev, "%s carrier mode and freq of " | ||
376 | "0x%02x 0x%02x\n", inout, data1, data2); | ||
377 | break; | ||
378 | case 0x07: | ||
379 | dev_info(dev, "Get carrier mode and freq\n"); | ||
380 | break; | ||
381 | case 0x08: | ||
382 | dev_info(dev, "%s transmit blaster mask of 0x%02x\n", | ||
383 | inout, data1); | ||
384 | break; | ||
385 | case 0x0c: | ||
386 | /* value is in units of 50us, so x*50/100 or x/2 ms */ | ||
387 | dev_info(dev, "%s receive timeout of %d ms\n", | ||
388 | inout, ((data1 << 8) | data2) / 2); | ||
389 | break; | ||
390 | case 0x0d: | ||
391 | dev_info(dev, "Get receive timeout\n"); | ||
392 | break; | ||
393 | case 0x13: | ||
394 | dev_info(dev, "Get transmit blaster mask\n"); | ||
395 | break; | ||
396 | case 0x14: | ||
397 | dev_info(dev, "%s %s-range receive sensor in use\n", | ||
398 | inout, data1 == 0x02 ? "short" : "long"); | ||
399 | break; | ||
400 | case 0x15: | ||
401 | if (len == 2) | ||
402 | dev_info(dev, "Get receive sensor\n"); | ||
403 | else | ||
404 | dev_info(dev, "Received pulse count is %d\n", | ||
405 | ((data1 << 8) | data2)); | ||
406 | break; | ||
407 | case 0xfe: | ||
408 | dev_info(dev, "Error! Hardware is likely wedged...\n"); | ||
409 | break; | ||
410 | case 0x05: | ||
411 | case 0x09: | ||
412 | case 0x0f: | ||
413 | default: | ||
414 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | ||
415 | cmd, subcmd); | ||
416 | break; | ||
417 | } | ||
418 | break; | ||
419 | default: | ||
420 | break; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | static void usb_async_callback(struct urb *urb, struct pt_regs *regs) | ||
425 | { | ||
426 | struct mceusb_dev *ir; | ||
427 | int len; | ||
428 | |||
429 | if (!urb) | ||
430 | return; | ||
431 | |||
432 | ir = urb->context; | ||
433 | if (ir) { | ||
434 | len = urb->actual_length; | ||
435 | |||
436 | dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", | ||
437 | urb->status, len); | ||
438 | |||
439 | if (debug) | ||
440 | mceusb_dev_printdata(ir, urb->transfer_buffer, | ||
441 | len, true); | ||
442 | } | ||
443 | |||
444 | } | ||
445 | |||
446 | /* request incoming or send outgoing usb packet - used to initialize remote */ | ||
447 | static void mce_request_packet(struct mceusb_dev *ir, | ||
448 | struct usb_endpoint_descriptor *ep, | ||
449 | unsigned char *data, int size, int urb_type) | ||
450 | { | ||
451 | int res; | ||
452 | struct urb *async_urb; | ||
453 | struct device *dev = ir->dev; | ||
454 | unsigned char *async_buf; | ||
455 | |||
456 | if (urb_type == MCEUSB_TX) { | ||
457 | async_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
458 | if (unlikely(!async_urb)) { | ||
459 | dev_err(dev, "Error, couldn't allocate urb!\n"); | ||
460 | return; | ||
461 | } | ||
462 | |||
463 | async_buf = kzalloc(size, GFP_KERNEL); | ||
464 | if (!async_buf) { | ||
465 | dev_err(dev, "Error, couldn't allocate buf!\n"); | ||
466 | usb_free_urb(async_urb); | ||
467 | return; | ||
468 | } | ||
469 | |||
470 | /* outbound data */ | ||
471 | usb_fill_int_urb(async_urb, ir->usbdev, | ||
472 | usb_sndintpipe(ir->usbdev, ep->bEndpointAddress), | ||
473 | async_buf, size, (usb_complete_t) usb_async_callback, | ||
474 | ir, ep->bInterval); | ||
475 | memcpy(async_buf, data, size); | ||
476 | |||
477 | } else if (urb_type == MCEUSB_RX) { | ||
478 | /* standard request */ | ||
479 | async_urb = ir->urb_in; | ||
480 | ir->send_flags = RECV_FLAG_IN_PROGRESS; | ||
481 | |||
482 | } else { | ||
483 | dev_err(dev, "Error! Unknown urb type %d\n", urb_type); | ||
484 | return; | ||
485 | } | ||
486 | |||
487 | dev_dbg(dev, "receive request called (size=%#x)\n", size); | ||
488 | |||
489 | async_urb->transfer_buffer_length = size; | ||
490 | async_urb->dev = ir->usbdev; | ||
491 | |||
492 | res = usb_submit_urb(async_urb, GFP_ATOMIC); | ||
493 | if (res) { | ||
494 | dev_dbg(dev, "receive request FAILED! (res=%d)\n", res); | ||
495 | return; | ||
496 | } | ||
497 | dev_dbg(dev, "receive request complete (res=%d)\n", res); | ||
498 | } | ||
499 | |||
500 | static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) | ||
501 | { | ||
502 | mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX); | ||
503 | } | ||
504 | |||
505 | static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) | ||
506 | { | ||
507 | mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX); | ||
508 | } | ||
509 | |||
510 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | ||
511 | { | ||
512 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | ||
513 | int i, start_index = 0; | ||
514 | |||
515 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ | ||
516 | if (ir->flags.microsoft_gen1) | ||
517 | start_index = 2; | ||
518 | |||
519 | for (i = start_index; i < buf_len;) { | ||
520 | if (ir->rem == 0) { | ||
521 | /* decode mce packets of the form (84),AA,BB,CC,DD */ | ||
522 | /* IR data packets can span USB messages - rem */ | ||
523 | ir->rem = (ir->buf_in[i] & MCE_PACKET_LENGTH_MASK); | ||
524 | ir->cmd = (ir->buf_in[i] & ~MCE_PACKET_LENGTH_MASK); | ||
525 | dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n", | ||
526 | ir->rem, ir->cmd); | ||
527 | i++; | ||
528 | } | ||
529 | |||
530 | /* Only cmd 0x8<bytes> is IR data, don't process MCE commands */ | ||
531 | if (ir->cmd != 0x80) { | ||
532 | ir->rem = 0; | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | for (; (ir->rem > 0) && (i < buf_len); i++) { | ||
537 | ir->rem--; | ||
538 | |||
539 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); | ||
540 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) | ||
541 | * MCE_TIME_UNIT * 1000; | ||
542 | |||
543 | if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { | ||
544 | if (ir->rawir.pulse == rawir.pulse) | ||
545 | ir->rawir.duration += rawir.duration; | ||
546 | else { | ||
547 | ir->rawir.duration = rawir.duration; | ||
548 | ir->rawir.pulse = rawir.pulse; | ||
549 | } | ||
550 | continue; | ||
551 | } | ||
552 | rawir.duration += ir->rawir.duration; | ||
553 | ir->rawir.duration = 0; | ||
554 | ir->rawir.pulse = rawir.pulse; | ||
555 | |||
556 | dev_dbg(ir->dev, "Storing %s with duration %d\n", | ||
557 | rawir.pulse ? "pulse" : "space", | ||
558 | rawir.duration); | ||
559 | |||
560 | ir_raw_event_store(ir->idev, &rawir); | ||
561 | } | ||
562 | |||
563 | if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f) | ||
564 | ir->rem = 0; | ||
565 | |||
566 | dev_dbg(ir->dev, "calling ir_raw_event_handle\n"); | ||
567 | ir_raw_event_handle(ir->idev); | ||
568 | } | ||
569 | } | ||
570 | |||
571 | static void mceusb_set_default_xmit_mask(struct urb *urb) | ||
572 | { | ||
573 | struct mceusb_dev *ir = urb->context; | ||
574 | char *buffer = urb->transfer_buffer; | ||
575 | u8 cmd, subcmd, def_xmit_mask; | ||
576 | |||
577 | cmd = buffer[0] & 0xff; | ||
578 | subcmd = buffer[1] & 0xff; | ||
579 | |||
580 | if (cmd == 0x9f && subcmd == 0x08) { | ||
581 | def_xmit_mask = buffer[2] & 0xff; | ||
582 | dev_dbg(ir->dev, "%s: setting xmit mask to 0x%02x\n", | ||
583 | __func__, def_xmit_mask); | ||
584 | ir->def_xmit_mask = def_xmit_mask; | ||
585 | ir->flags.def_xmit_mask_set = 1; | ||
586 | } | ||
587 | } | ||
588 | |||
589 | static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | ||
590 | { | ||
591 | struct mceusb_dev *ir; | ||
592 | int buf_len; | ||
593 | |||
594 | if (!urb) | ||
595 | return; | ||
596 | |||
597 | ir = urb->context; | ||
598 | if (!ir) { | ||
599 | usb_unlink_urb(urb); | ||
600 | return; | ||
601 | } | ||
602 | |||
603 | buf_len = urb->actual_length; | ||
604 | |||
605 | if (!ir->flags.def_xmit_mask_set) | ||
606 | mceusb_set_default_xmit_mask(urb); | ||
607 | |||
608 | if (debug) | ||
609 | mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false); | ||
610 | |||
611 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { | ||
612 | ir->send_flags = SEND_FLAG_COMPLETE; | ||
613 | dev_dbg(&ir->irdev->dev, "setup answer received %d bytes\n", | ||
614 | buf_len); | ||
615 | } | ||
616 | |||
617 | switch (urb->status) { | ||
618 | /* success */ | ||
619 | case 0: | ||
620 | mceusb_process_ir_data(ir, buf_len); | ||
621 | break; | ||
622 | |||
623 | case -ECONNRESET: | ||
624 | case -ENOENT: | ||
625 | case -ESHUTDOWN: | ||
626 | usb_unlink_urb(urb); | ||
627 | return; | ||
628 | |||
629 | case -EPIPE: | ||
630 | default: | ||
631 | break; | ||
632 | } | ||
633 | |||
634 | usb_submit_urb(urb, GFP_ATOMIC); | ||
635 | } | ||
636 | |||
637 | static void mceusb_gen1_init(struct mceusb_dev *ir) | ||
638 | { | ||
639 | int i, ret; | ||
640 | char junk[64], data[8]; | ||
641 | int partial = 0; | ||
642 | struct device *dev = ir->dev; | ||
643 | |||
644 | /* | ||
645 | * Clear off the first few messages. These look like calibration | ||
646 | * or test data, I can't really tell. This also flushes in case | ||
647 | * we have random ir data queued up. | ||
648 | */ | ||
649 | for (i = 0; i < 40; i++) | ||
650 | usb_bulk_msg(ir->usbdev, | ||
651 | usb_rcvbulkpipe(ir->usbdev, | ||
652 | ir->usb_ep_in->bEndpointAddress), | ||
653 | junk, 64, &partial, HZ * 10); | ||
654 | |||
655 | memset(data, 0, 8); | ||
656 | |||
657 | /* Get Status */ | ||
658 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), | ||
659 | USB_REQ_GET_STATUS, USB_DIR_IN, | ||
660 | 0, 0, data, 2, HZ * 3); | ||
661 | |||
662 | /* ret = usb_get_status( ir->usbdev, 0, 0, data ); */ | ||
663 | dev_dbg(dev, "%s - ret = %d status = 0x%x 0x%x\n", __func__, | ||
664 | ret, data[0], data[1]); | ||
665 | |||
666 | /* | ||
667 | * This is a strange one. They issue a set address to the device | ||
668 | * on the receive control pipe and expect a certain value pair back | ||
669 | */ | ||
670 | memset(data, 0, 8); | ||
671 | |||
672 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), | ||
673 | USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, | ||
674 | data, 2, HZ * 3); | ||
675 | dev_dbg(dev, "%s - ret = %d\n", __func__, ret); | ||
676 | dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n", | ||
677 | __func__, data[0], data[1]); | ||
678 | |||
679 | /* set feature: bit rate 38400 bps */ | ||
680 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | ||
681 | USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, | ||
682 | 0xc04e, 0x0000, NULL, 0, HZ * 3); | ||
683 | |||
684 | dev_dbg(dev, "%s - ret = %d\n", __func__, ret); | ||
685 | |||
686 | /* bRequest 4: set char length to 8 bits */ | ||
687 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | ||
688 | 4, USB_TYPE_VENDOR, | ||
689 | 0x0808, 0x0000, NULL, 0, HZ * 3); | ||
690 | dev_dbg(dev, "%s - retB = %d\n", __func__, ret); | ||
691 | |||
692 | /* bRequest 2: set handshaking to use DTR/DSR */ | ||
693 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | ||
694 | 2, USB_TYPE_VENDOR, | ||
695 | 0x0000, 0x0100, NULL, 0, HZ * 3); | ||
696 | dev_dbg(dev, "%s - retC = %d\n", __func__, ret); | ||
697 | }; | ||
698 | |||
699 | static void mceusb_gen2_init(struct mceusb_dev *ir) | ||
700 | { | ||
701 | int maxp = ir->len_in; | ||
702 | |||
703 | mce_sync_in(ir, NULL, maxp); | ||
704 | mce_sync_in(ir, NULL, maxp); | ||
705 | |||
706 | /* device reset */ | ||
707 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); | ||
708 | mce_sync_in(ir, NULL, maxp); | ||
709 | |||
710 | /* get hw/sw revision? */ | ||
711 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); | ||
712 | mce_sync_in(ir, NULL, maxp); | ||
713 | |||
714 | /* unknown what this actually returns... */ | ||
715 | mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); | ||
716 | mce_sync_in(ir, NULL, maxp); | ||
717 | } | ||
718 | |||
719 | static void mceusb_gen3_init(struct mceusb_dev *ir) | ||
720 | { | ||
721 | int maxp = ir->len_in; | ||
722 | |||
723 | mce_sync_in(ir, NULL, maxp); | ||
724 | |||
725 | /* device reset */ | ||
726 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); | ||
727 | mce_sync_in(ir, NULL, maxp); | ||
728 | |||
729 | /* get the carrier and frequency */ | ||
730 | mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); | ||
731 | mce_sync_in(ir, NULL, maxp); | ||
732 | |||
733 | /* get the transmitter bitmask */ | ||
734 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); | ||
735 | mce_sync_in(ir, NULL, maxp); | ||
736 | |||
737 | /* get receiver timeout value */ | ||
738 | mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); | ||
739 | mce_sync_in(ir, NULL, maxp); | ||
740 | |||
741 | /* get receiver sensor setting */ | ||
742 | mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); | ||
743 | mce_sync_in(ir, NULL, maxp); | ||
744 | } | ||
745 | |||
746 | static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | ||
747 | { | ||
748 | struct input_dev *idev; | ||
749 | struct ir_dev_props *props; | ||
750 | struct ir_input_dev *irdev; | ||
751 | struct ir_input_state *state; | ||
752 | struct device *dev = ir->dev; | ||
753 | int ret = -ENODEV; | ||
754 | |||
755 | idev = input_allocate_device(); | ||
756 | if (!idev) { | ||
757 | dev_err(dev, "remote input dev allocation failed\n"); | ||
758 | goto idev_alloc_failed; | ||
759 | } | ||
760 | |||
761 | ret = -ENOMEM; | ||
762 | props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL); | ||
763 | if (!props) { | ||
764 | dev_err(dev, "remote ir dev props allocation failed\n"); | ||
765 | goto props_alloc_failed; | ||
766 | } | ||
767 | |||
768 | irdev = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL); | ||
769 | if (!irdev) { | ||
770 | dev_err(dev, "remote ir input dev allocation failed\n"); | ||
771 | goto ir_dev_alloc_failed; | ||
772 | } | ||
773 | |||
774 | state = kzalloc(sizeof(struct ir_input_state), GFP_KERNEL); | ||
775 | if (!state) { | ||
776 | dev_err(dev, "remote ir state allocation failed\n"); | ||
777 | goto ir_state_alloc_failed; | ||
778 | } | ||
779 | |||
780 | snprintf(ir->name, sizeof(ir->name), "Media Center Edition eHome " | ||
781 | "Infrared Remote Transceiver (%04x:%04x)", | ||
782 | le16_to_cpu(ir->usbdev->descriptor.idVendor), | ||
783 | le16_to_cpu(ir->usbdev->descriptor.idProduct)); | ||
784 | |||
785 | ret = ir_input_init(idev, state, IR_TYPE_RC6); | ||
786 | if (ret < 0) | ||
787 | goto irdev_failed; | ||
788 | |||
789 | idev->name = ir->name; | ||
790 | |||
791 | usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys)); | ||
792 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | ||
793 | idev->phys = ir->phys; | ||
794 | |||
795 | /* FIXME: no EV_REP (yet), we may need our own auto-repeat handling */ | ||
796 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | ||
797 | |||
798 | idev->keybit[BIT_WORD(BTN_MOUSE)] = | ||
799 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); | ||
800 | idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) | | ||
801 | BIT_MASK(REL_WHEEL); | ||
802 | |||
803 | props->priv = ir; | ||
804 | props->driver_type = RC_DRIVER_IR_RAW; | ||
805 | props->allowed_protos = IR_TYPE_ALL; | ||
806 | |||
807 | ir->props = props; | ||
808 | ir->irdev = irdev; | ||
809 | ir->state = state; | ||
810 | |||
811 | input_set_drvdata(idev, irdev); | ||
812 | |||
813 | ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME); | ||
814 | if (ret < 0) { | ||
815 | dev_err(dev, "remote input device register failed\n"); | ||
816 | goto irdev_failed; | ||
817 | } | ||
818 | |||
819 | return idev; | ||
820 | |||
821 | irdev_failed: | ||
822 | kfree(state); | ||
823 | ir_state_alloc_failed: | ||
824 | kfree(irdev); | ||
825 | ir_dev_alloc_failed: | ||
826 | kfree(props); | ||
827 | props_alloc_failed: | ||
828 | input_free_device(idev); | ||
829 | idev_alloc_failed: | ||
830 | return NULL; | ||
831 | } | ||
832 | |||
833 | static int __devinit mceusb_dev_probe(struct usb_interface *intf, | ||
834 | const struct usb_device_id *id) | ||
835 | { | ||
836 | struct usb_device *dev = interface_to_usbdev(intf); | ||
837 | struct usb_host_interface *idesc; | ||
838 | struct usb_endpoint_descriptor *ep = NULL; | ||
839 | struct usb_endpoint_descriptor *ep_in = NULL; | ||
840 | struct usb_endpoint_descriptor *ep_out = NULL; | ||
841 | struct usb_host_config *config; | ||
842 | struct mceusb_dev *ir = NULL; | ||
843 | int pipe, maxp; | ||
844 | int i, ret; | ||
845 | char buf[63], name[128] = ""; | ||
846 | bool is_gen3; | ||
847 | bool is_microsoft_gen1; | ||
848 | bool is_pinnacle; | ||
849 | |||
850 | dev_dbg(&intf->dev, ": %s called\n", __func__); | ||
851 | |||
852 | usb_reset_device(dev); | ||
853 | |||
854 | config = dev->actconfig; | ||
855 | idesc = intf->cur_altsetting; | ||
856 | |||
857 | is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0; | ||
858 | is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0; | ||
859 | is_pinnacle = usb_match_id(intf, pinnacle_list) ? 1 : 0; | ||
860 | |||
861 | /* step through the endpoints to find first bulk in and out endpoint */ | ||
862 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { | ||
863 | ep = &idesc->endpoint[i].desc; | ||
864 | |||
865 | if ((ep_in == NULL) | ||
866 | && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
867 | == USB_DIR_IN) | ||
868 | && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
869 | == USB_ENDPOINT_XFER_BULK) | ||
870 | || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
871 | == USB_ENDPOINT_XFER_INT))) { | ||
872 | |||
873 | dev_dbg(&intf->dev, ": acceptable inbound endpoint " | ||
874 | "found\n"); | ||
875 | ep_in = ep; | ||
876 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; | ||
877 | if (!is_pinnacle) | ||
878 | /* | ||
879 | * Ideally, we'd use what the device offers up, | ||
880 | * but that leads to non-functioning first and | ||
881 | * second-gen devices, and many devices have an | ||
882 | * invalid bInterval of 0. Pinnacle devices | ||
883 | * don't work witha bInterval of 1 though. | ||
884 | */ | ||
885 | ep_in->bInterval = 1; | ||
886 | } | ||
887 | |||
888 | if ((ep_out == NULL) | ||
889 | && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
890 | == USB_DIR_OUT) | ||
891 | && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
892 | == USB_ENDPOINT_XFER_BULK) | ||
893 | || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
894 | == USB_ENDPOINT_XFER_INT))) { | ||
895 | |||
896 | dev_dbg(&intf->dev, ": acceptable outbound endpoint " | ||
897 | "found\n"); | ||
898 | ep_out = ep; | ||
899 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; | ||
900 | if (!is_pinnacle) | ||
901 | /* | ||
902 | * Ideally, we'd use what the device offers up, | ||
903 | * but that leads to non-functioning first and | ||
904 | * second-gen devices, and many devices have an | ||
905 | * invalid bInterval of 0. Pinnacle devices | ||
906 | * don't work witha bInterval of 1 though. | ||
907 | */ | ||
908 | ep_out->bInterval = 1; | ||
909 | } | ||
910 | } | ||
911 | if (ep_in == NULL) { | ||
912 | dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n"); | ||
913 | return -ENODEV; | ||
914 | } | ||
915 | |||
916 | pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); | ||
917 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | ||
918 | |||
919 | ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); | ||
920 | if (!ir) | ||
921 | goto mem_alloc_fail; | ||
922 | |||
923 | ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in); | ||
924 | if (!ir->buf_in) | ||
925 | goto buf_in_alloc_fail; | ||
926 | |||
927 | ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); | ||
928 | if (!ir->urb_in) | ||
929 | goto urb_in_alloc_fail; | ||
930 | |||
931 | ir->usbdev = dev; | ||
932 | ir->dev = &intf->dev; | ||
933 | ir->len_in = maxp; | ||
934 | ir->flags.gen3 = is_gen3; | ||
935 | ir->flags.microsoft_gen1 = is_microsoft_gen1; | ||
936 | |||
937 | /* Saving usb interface data for use by the transmitter routine */ | ||
938 | ir->usb_ep_in = ep_in; | ||
939 | ir->usb_ep_out = ep_out; | ||
940 | |||
941 | if (dev->descriptor.iManufacturer | ||
942 | && usb_string(dev, dev->descriptor.iManufacturer, | ||
943 | buf, sizeof(buf)) > 0) | ||
944 | strlcpy(name, buf, sizeof(name)); | ||
945 | if (dev->descriptor.iProduct | ||
946 | && usb_string(dev, dev->descriptor.iProduct, | ||
947 | buf, sizeof(buf)) > 0) | ||
948 | snprintf(name + strlen(name), sizeof(name) - strlen(name), | ||
949 | " %s", buf); | ||
950 | |||
951 | ir->idev = mceusb_init_input_dev(ir); | ||
952 | if (!ir->idev) | ||
953 | goto input_dev_fail; | ||
954 | |||
955 | /* inbound data */ | ||
956 | usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, | ||
957 | maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); | ||
958 | ir->urb_in->transfer_dma = ir->dma_in; | ||
959 | ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
960 | |||
961 | if (is_pinnacle) { | ||
962 | /* | ||
963 | * I have no idea why but this reset seems to be crucial to | ||
964 | * getting the device to do outbound IO correctly - without | ||
965 | * this the device seems to hang, ignoring all input - although | ||
966 | * IR signals are correctly sent from the device, no input is | ||
967 | * interpreted by the device and the host never does the | ||
968 | * completion routine | ||
969 | */ | ||
970 | ret = usb_reset_configuration(dev); | ||
971 | dev_info(&intf->dev, "usb reset config ret %x\n", ret); | ||
972 | } | ||
973 | |||
974 | /* initialize device */ | ||
975 | if (ir->flags.gen3) | ||
976 | mceusb_gen3_init(ir); | ||
977 | |||
978 | else if (ir->flags.microsoft_gen1) | ||
979 | mceusb_gen1_init(ir); | ||
980 | |||
981 | else | ||
982 | mceusb_gen2_init(ir); | ||
983 | |||
984 | mce_sync_in(ir, NULL, maxp); | ||
985 | |||
986 | /* We've already done this on gen3 devices */ | ||
987 | if (!ir->flags.def_xmit_mask_set) { | ||
988 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); | ||
989 | mce_sync_in(ir, NULL, maxp); | ||
990 | } | ||
991 | |||
992 | usb_set_intfdata(intf, ir); | ||
993 | |||
994 | dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name, | ||
995 | dev->bus->busnum, dev->devnum); | ||
996 | |||
997 | return 0; | ||
998 | |||
999 | /* Error-handling path */ | ||
1000 | input_dev_fail: | ||
1001 | usb_free_urb(ir->urb_in); | ||
1002 | urb_in_alloc_fail: | ||
1003 | usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in); | ||
1004 | buf_in_alloc_fail: | ||
1005 | kfree(ir); | ||
1006 | mem_alloc_fail: | ||
1007 | dev_err(&intf->dev, "%s: device setup failed!\n", __func__); | ||
1008 | |||
1009 | return -ENOMEM; | ||
1010 | } | ||
1011 | |||
1012 | |||
1013 | static void __devexit mceusb_dev_disconnect(struct usb_interface *intf) | ||
1014 | { | ||
1015 | struct usb_device *dev = interface_to_usbdev(intf); | ||
1016 | struct mceusb_dev *ir = usb_get_intfdata(intf); | ||
1017 | |||
1018 | usb_set_intfdata(intf, NULL); | ||
1019 | |||
1020 | if (!ir) | ||
1021 | return; | ||
1022 | |||
1023 | ir->usbdev = NULL; | ||
1024 | input_unregister_device(ir->idev); | ||
1025 | usb_kill_urb(ir->urb_in); | ||
1026 | usb_free_urb(ir->urb_in); | ||
1027 | usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); | ||
1028 | |||
1029 | kfree(ir); | ||
1030 | } | ||
1031 | |||
1032 | static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message) | ||
1033 | { | ||
1034 | struct mceusb_dev *ir = usb_get_intfdata(intf); | ||
1035 | dev_info(ir->dev, "suspend\n"); | ||
1036 | usb_kill_urb(ir->urb_in); | ||
1037 | return 0; | ||
1038 | } | ||
1039 | |||
1040 | static int mceusb_dev_resume(struct usb_interface *intf) | ||
1041 | { | ||
1042 | struct mceusb_dev *ir = usb_get_intfdata(intf); | ||
1043 | dev_info(ir->dev, "resume\n"); | ||
1044 | if (usb_submit_urb(ir->urb_in, GFP_ATOMIC)) | ||
1045 | return -EIO; | ||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | static struct usb_driver mceusb_dev_driver = { | ||
1050 | .name = DRIVER_NAME, | ||
1051 | .probe = mceusb_dev_probe, | ||
1052 | .disconnect = mceusb_dev_disconnect, | ||
1053 | .suspend = mceusb_dev_suspend, | ||
1054 | .resume = mceusb_dev_resume, | ||
1055 | .reset_resume = mceusb_dev_resume, | ||
1056 | .id_table = mceusb_dev_table | ||
1057 | }; | ||
1058 | |||
1059 | static int __init mceusb_dev_init(void) | ||
1060 | { | ||
1061 | int ret; | ||
1062 | |||
1063 | ret = usb_register(&mceusb_dev_driver); | ||
1064 | if (ret < 0) | ||
1065 | printk(KERN_ERR DRIVER_NAME | ||
1066 | ": usb register failed, result = %d\n", ret); | ||
1067 | |||
1068 | return ret; | ||
1069 | } | ||
1070 | |||
1071 | static void __exit mceusb_dev_exit(void) | ||
1072 | { | ||
1073 | usb_deregister(&mceusb_dev_driver); | ||
1074 | } | ||
1075 | |||
1076 | module_init(mceusb_dev_init); | ||
1077 | module_exit(mceusb_dev_exit); | ||
1078 | |||
1079 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1080 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
1081 | MODULE_LICENSE("GPL"); | ||
1082 | MODULE_DEVICE_TABLE(usb, mceusb_dev_table); | ||
1083 | |||
1084 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
1085 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||