diff options
Diffstat (limited to 'drivers/media/IR/mceusb.c')
-rw-r--r-- | drivers/media/IR/mceusb.c | 475 |
1 files changed, 316 insertions, 159 deletions
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index bc620e10ef77..9dce684fd231 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c | |||
@@ -46,24 +46,58 @@ | |||
46 | "device driver" | 46 | "device driver" |
47 | #define DRIVER_NAME "mceusb" | 47 | #define DRIVER_NAME "mceusb" |
48 | 48 | ||
49 | #define USB_BUFLEN 32 /* USB reception buffer length */ | 49 | #define USB_BUFLEN 32 /* USB reception buffer length */ |
50 | #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ | 50 | #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ |
51 | #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ | 51 | #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ |
52 | 52 | ||
53 | /* MCE constants */ | 53 | /* MCE constants */ |
54 | #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ | 54 | #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ |
55 | #define MCE_TIME_UNIT 50 /* Approx 50us resolution */ | 55 | #define MCE_TIME_UNIT 50 /* Approx 50us resolution */ |
56 | #define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ | 56 | #define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ |
57 | #define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ | 57 | #define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ |
58 | #define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ | 58 | #define MCE_IRDATA_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ |
59 | #define MCE_CONTROL_HEADER 0x9F /* MCE status header */ | 59 | #define MCE_IRDATA_TRAILER 0x80 /* End of IR data */ |
60 | #define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ | 60 | #define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ |
61 | #define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ | 61 | #define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ |
62 | #define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */ | 62 | #define MCE_DEFAULT_TX_MASK 0x03 /* Vals: TX1=0x01, TX2=0x02, ALL=0x03 */ |
63 | #define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ | 63 | #define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ |
64 | #define MCE_PULSE_MASK 0x7F /* Pulse mask */ | 64 | #define MCE_PULSE_MASK 0x7f /* Pulse mask */ |
65 | #define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */ | 65 | #define MCE_MAX_PULSE_LENGTH 0x7f /* Longest transmittable pulse symbol */ |
66 | #define MCE_PACKET_LENGTH_MASK 0x1F /* Packet length mask */ | 66 | |
67 | #define MCE_HW_CMD_HEADER 0xff /* MCE hardware command header */ | ||
68 | #define MCE_COMMAND_HEADER 0x9f /* MCE command header */ | ||
69 | #define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */ | ||
70 | #define MCE_COMMAND_NULL 0x00 /* These show up various places... */ | ||
71 | /* if buf[i] & MCE_COMMAND_MASK == 0x80 and buf[i] != MCE_COMMAND_HEADER, | ||
72 | * then we're looking at a raw IR data sample */ | ||
73 | #define MCE_COMMAND_IRDATA 0x80 | ||
74 | #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ | ||
75 | |||
76 | /* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */ | ||
77 | #define MCE_CMD_PING 0x03 /* Ping device */ | ||
78 | #define MCE_CMD_UNKNOWN 0x04 /* Unknown */ | ||
79 | #define MCE_CMD_UNKNOWN2 0x05 /* Unknown */ | ||
80 | #define MCE_CMD_S_CARRIER 0x06 /* Set TX carrier frequency */ | ||
81 | #define MCE_CMD_G_CARRIER 0x07 /* Get TX carrier frequency */ | ||
82 | #define MCE_CMD_S_TXMASK 0x08 /* Set TX port bitmask */ | ||
83 | #define MCE_CMD_UNKNOWN3 0x09 /* Unknown */ | ||
84 | #define MCE_CMD_UNKNOWN4 0x0a /* Unknown */ | ||
85 | #define MCE_CMD_G_REVISION 0x0b /* Get hw/sw revision */ | ||
86 | #define MCE_CMD_S_TIMEOUT 0x0c /* Set RX timeout value */ | ||
87 | #define MCE_CMD_G_TIMEOUT 0x0d /* Get RX timeout value */ | ||
88 | #define MCE_CMD_UNKNOWN5 0x0e /* Unknown */ | ||
89 | #define MCE_CMD_UNKNOWN6 0x0f /* Unknown */ | ||
90 | #define MCE_CMD_G_RXPORTSTS 0x11 /* Get RX port status */ | ||
91 | #define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */ | ||
92 | #define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */ | ||
93 | #define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */ | ||
94 | #define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */ | ||
95 | #define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */ | ||
96 | #define MCE_CMD_UNKNOWN7 0x18 /* Unknown */ | ||
97 | #define MCE_CMD_UNKNOWN8 0x19 /* Unknown */ | ||
98 | #define MCE_CMD_UNKNOWN9 0x1b /* Unknown */ | ||
99 | #define MCE_CMD_DEVICE_RESET 0xaa /* Reset the hardware */ | ||
100 | #define MCE_RSP_CMD_INVALID 0xfe /* Invalid command issued */ | ||
67 | 101 | ||
68 | 102 | ||
69 | /* module parameters */ | 103 | /* module parameters */ |
@@ -104,14 +138,64 @@ static int debug; | |||
104 | #define VENDOR_NORTHSTAR 0x04eb | 138 | #define VENDOR_NORTHSTAR 0x04eb |
105 | #define VENDOR_REALTEK 0x0bda | 139 | #define VENDOR_REALTEK 0x0bda |
106 | #define VENDOR_TIVO 0x105a | 140 | #define VENDOR_TIVO 0x105a |
141 | #define VENDOR_CONEXANT 0x0572 | ||
142 | |||
143 | enum mceusb_model_type { | ||
144 | MCE_GEN2 = 0, /* Most boards */ | ||
145 | MCE_GEN1, | ||
146 | MCE_GEN3, | ||
147 | MCE_GEN2_TX_INV, | ||
148 | POLARIS_EVK, | ||
149 | }; | ||
150 | |||
151 | struct mceusb_model { | ||
152 | u32 mce_gen1:1; | ||
153 | u32 mce_gen2:1; | ||
154 | u32 mce_gen3:1; | ||
155 | u32 tx_mask_inverted:1; | ||
156 | u32 is_polaris:1; | ||
157 | |||
158 | const char *rc_map; /* Allow specify a per-board map */ | ||
159 | const char *name; /* per-board name */ | ||
160 | }; | ||
161 | |||
162 | static const struct mceusb_model mceusb_model[] = { | ||
163 | [MCE_GEN1] = { | ||
164 | .mce_gen1 = 1, | ||
165 | .tx_mask_inverted = 1, | ||
166 | }, | ||
167 | [MCE_GEN2] = { | ||
168 | .mce_gen2 = 1, | ||
169 | }, | ||
170 | [MCE_GEN2_TX_INV] = { | ||
171 | .mce_gen2 = 1, | ||
172 | .tx_mask_inverted = 1, | ||
173 | }, | ||
174 | [MCE_GEN3] = { | ||
175 | .mce_gen3 = 1, | ||
176 | .tx_mask_inverted = 1, | ||
177 | }, | ||
178 | [POLARIS_EVK] = { | ||
179 | .is_polaris = 1, | ||
180 | /* | ||
181 | * In fact, the EVK is shipped without | ||
182 | * remotes, but we should have something handy, | ||
183 | * to allow testing it | ||
184 | */ | ||
185 | .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, | ||
186 | .name = "cx231xx MCE IR", | ||
187 | }, | ||
188 | }; | ||
107 | 189 | ||
108 | static struct usb_device_id mceusb_dev_table[] = { | 190 | static struct usb_device_id mceusb_dev_table[] = { |
109 | /* Original Microsoft MCE IR Transceiver (often HP-branded) */ | 191 | /* Original Microsoft MCE IR Transceiver (often HP-branded) */ |
110 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | 192 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d), |
193 | .driver_info = MCE_GEN1 }, | ||
111 | /* Philips Infrared Transceiver - Sahara branded */ | 194 | /* Philips Infrared Transceiver - Sahara branded */ |
112 | { USB_DEVICE(VENDOR_PHILIPS, 0x0608) }, | 195 | { USB_DEVICE(VENDOR_PHILIPS, 0x0608) }, |
113 | /* Philips Infrared Transceiver - HP branded */ | 196 | /* Philips Infrared Transceiver - HP branded */ |
114 | { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, | 197 | { USB_DEVICE(VENDOR_PHILIPS, 0x060c), |
198 | .driver_info = MCE_GEN2_TX_INV }, | ||
115 | /* Philips SRM5100 */ | 199 | /* Philips SRM5100 */ |
116 | { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, | 200 | { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, |
117 | /* Philips Infrared Transceiver - Omaura */ | 201 | /* Philips Infrared Transceiver - Omaura */ |
@@ -127,11 +211,14 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
127 | /* Realtek MCE IR Receiver */ | 211 | /* Realtek MCE IR Receiver */ |
128 | { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, | 212 | { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, |
129 | /* SMK/Toshiba G83C0004D410 */ | 213 | /* SMK/Toshiba G83C0004D410 */ |
130 | { USB_DEVICE(VENDOR_SMK, 0x031d) }, | 214 | { USB_DEVICE(VENDOR_SMK, 0x031d), |
215 | .driver_info = MCE_GEN2_TX_INV }, | ||
131 | /* SMK eHome Infrared Transceiver (Sony VAIO) */ | 216 | /* SMK eHome Infrared Transceiver (Sony VAIO) */ |
132 | { USB_DEVICE(VENDOR_SMK, 0x0322) }, | 217 | { USB_DEVICE(VENDOR_SMK, 0x0322), |
218 | .driver_info = MCE_GEN2_TX_INV }, | ||
133 | /* bundled with Hauppauge PVR-150 */ | 219 | /* bundled with Hauppauge PVR-150 */ |
134 | { USB_DEVICE(VENDOR_SMK, 0x0334) }, | 220 | { USB_DEVICE(VENDOR_SMK, 0x0334), |
221 | .driver_info = MCE_GEN2_TX_INV }, | ||
135 | /* SMK eHome Infrared Transceiver */ | 222 | /* SMK eHome Infrared Transceiver */ |
136 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, | 223 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, |
137 | /* Tatung eHome Infrared Transceiver */ | 224 | /* Tatung eHome Infrared Transceiver */ |
@@ -145,17 +232,23 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
145 | /* Mitsumi */ | 232 | /* Mitsumi */ |
146 | { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, | 233 | { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, |
147 | /* Topseed eHome Infrared Transceiver */ | 234 | /* Topseed eHome Infrared Transceiver */ |
148 | { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, | 235 | { USB_DEVICE(VENDOR_TOPSEED, 0x0001), |
236 | .driver_info = MCE_GEN2_TX_INV }, | ||
149 | /* Topseed HP eHome Infrared Transceiver */ | 237 | /* Topseed HP eHome Infrared Transceiver */ |
150 | { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, | 238 | { USB_DEVICE(VENDOR_TOPSEED, 0x0006), |
239 | .driver_info = MCE_GEN2_TX_INV }, | ||
151 | /* Topseed eHome Infrared Transceiver */ | 240 | /* Topseed eHome Infrared Transceiver */ |
152 | { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, | 241 | { USB_DEVICE(VENDOR_TOPSEED, 0x0007), |
242 | .driver_info = MCE_GEN2_TX_INV }, | ||
153 | /* Topseed eHome Infrared Transceiver */ | 243 | /* Topseed eHome Infrared Transceiver */ |
154 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | 244 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008), |
245 | .driver_info = MCE_GEN3 }, | ||
155 | /* Topseed eHome Infrared Transceiver */ | 246 | /* Topseed eHome Infrared Transceiver */ |
156 | { USB_DEVICE(VENDOR_TOPSEED, 0x000a) }, | 247 | { USB_DEVICE(VENDOR_TOPSEED, 0x000a), |
248 | .driver_info = MCE_GEN2_TX_INV }, | ||
157 | /* Topseed eHome Infrared Transceiver */ | 249 | /* Topseed eHome Infrared Transceiver */ |
158 | { USB_DEVICE(VENDOR_TOPSEED, 0x0011) }, | 250 | { USB_DEVICE(VENDOR_TOPSEED, 0x0011), |
251 | .driver_info = MCE_GEN2_TX_INV }, | ||
159 | /* Ricavision internal Infrared Transceiver */ | 252 | /* Ricavision internal Infrared Transceiver */ |
160 | { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, | 253 | { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, |
161 | /* Itron ione Libra Q-11 */ | 254 | /* Itron ione Libra Q-11 */ |
@@ -185,7 +278,8 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
185 | /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ | 278 | /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ |
186 | { USB_DEVICE(VENDOR_FINTEK, 0x0702) }, | 279 | { USB_DEVICE(VENDOR_FINTEK, 0x0702) }, |
187 | /* Pinnacle Remote Kit */ | 280 | /* Pinnacle Remote Kit */ |
188 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | 281 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225), |
282 | .driver_info = MCE_GEN3 }, | ||
189 | /* Elitegroup Computer Systems IR */ | 283 | /* Elitegroup Computer Systems IR */ |
190 | { USB_DEVICE(VENDOR_ECS, 0x0f38) }, | 284 | { USB_DEVICE(VENDOR_ECS, 0x0f38) }, |
191 | /* Wistron Corp. eHome Infrared Receiver */ | 285 | /* Wistron Corp. eHome Infrared Receiver */ |
@@ -198,37 +292,13 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
198 | { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, | 292 | { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, |
199 | /* TiVo PC IR Receiver */ | 293 | /* TiVo PC IR Receiver */ |
200 | { USB_DEVICE(VENDOR_TIVO, 0x2000) }, | 294 | { USB_DEVICE(VENDOR_TIVO, 0x2000) }, |
295 | /* Conexant SDK */ | ||
296 | { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), | ||
297 | .driver_info = POLARIS_EVK }, | ||
201 | /* Terminating entry */ | 298 | /* Terminating entry */ |
202 | { } | 299 | { } |
203 | }; | 300 | }; |
204 | 301 | ||
205 | static struct usb_device_id gen3_list[] = { | ||
206 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | ||
207 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | ||
208 | {} | ||
209 | }; | ||
210 | |||
211 | static struct usb_device_id microsoft_gen1_list[] = { | ||
212 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | ||
213 | {} | ||
214 | }; | ||
215 | |||
216 | static struct usb_device_id std_tx_mask_list[] = { | ||
217 | { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, | ||
218 | { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, | ||
219 | { USB_DEVICE(VENDOR_SMK, 0x031d) }, | ||
220 | { USB_DEVICE(VENDOR_SMK, 0x0322) }, | ||
221 | { USB_DEVICE(VENDOR_SMK, 0x0334) }, | ||
222 | { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, | ||
223 | { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, | ||
224 | { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, | ||
225 | { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, | ||
226 | { USB_DEVICE(VENDOR_TOPSEED, 0x000a) }, | ||
227 | { USB_DEVICE(VENDOR_TOPSEED, 0x0011) }, | ||
228 | { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, | ||
229 | {} | ||
230 | }; | ||
231 | |||
232 | /* data structure for each usb transceiver */ | 302 | /* data structure for each usb transceiver */ |
233 | struct mceusb_dev { | 303 | struct mceusb_dev { |
234 | /* ir-core bits */ | 304 | /* ir-core bits */ |
@@ -248,8 +318,15 @@ struct mceusb_dev { | |||
248 | /* buffers and dma */ | 318 | /* buffers and dma */ |
249 | unsigned char *buf_in; | 319 | unsigned char *buf_in; |
250 | unsigned int len_in; | 320 | unsigned int len_in; |
251 | u8 cmd; /* MCE command type */ | 321 | |
252 | u8 rem; /* Remaining IR data bytes in packet */ | 322 | enum { |
323 | CMD_HEADER = 0, | ||
324 | SUBCMD, | ||
325 | CMD_DATA, | ||
326 | PARSE_IRDATA, | ||
327 | } parser_state; | ||
328 | u8 cmd, rem; /* Remaining IR data bytes in packet */ | ||
329 | |||
253 | dma_addr_t dma_in; | 330 | dma_addr_t dma_in; |
254 | dma_addr_t dma_out; | 331 | dma_addr_t dma_out; |
255 | 332 | ||
@@ -257,7 +334,6 @@ struct mceusb_dev { | |||
257 | u32 connected:1; | 334 | u32 connected:1; |
258 | u32 tx_mask_inverted:1; | 335 | u32 tx_mask_inverted:1; |
259 | u32 microsoft_gen1:1; | 336 | u32 microsoft_gen1:1; |
260 | u32 reserved:29; | ||
261 | } flags; | 337 | } flags; |
262 | 338 | ||
263 | /* transmit support */ | 339 | /* transmit support */ |
@@ -267,6 +343,7 @@ struct mceusb_dev { | |||
267 | 343 | ||
268 | char name[128]; | 344 | char name[128]; |
269 | char phys[64]; | 345 | char phys[64]; |
346 | enum mceusb_model_type model; | ||
270 | }; | 347 | }; |
271 | 348 | ||
272 | /* | 349 | /* |
@@ -291,43 +368,81 @@ struct mceusb_dev { | |||
291 | * - SET_RX_TIMEOUT sets the receiver timeout | 368 | * - SET_RX_TIMEOUT sets the receiver timeout |
292 | * - SET_RX_SENSOR sets which receiver sensor to use | 369 | * - SET_RX_SENSOR sets which receiver sensor to use |
293 | */ | 370 | */ |
294 | static char DEVICE_RESET[] = {0x00, 0xff, 0xaa}; | 371 | static char DEVICE_RESET[] = {MCE_COMMAND_NULL, MCE_HW_CMD_HEADER, |
295 | static char GET_REVISION[] = {0xff, 0x0b}; | 372 | MCE_CMD_DEVICE_RESET}; |
296 | static char GET_UNKNOWN[] = {0xff, 0x18}; | 373 | static char GET_REVISION[] = {MCE_HW_CMD_HEADER, MCE_CMD_G_REVISION}; |
297 | static char GET_UNKNOWN2[] = {0x9f, 0x05}; | 374 | static char GET_UNKNOWN[] = {MCE_HW_CMD_HEADER, MCE_CMD_UNKNOWN7}; |
298 | static char GET_CARRIER_FREQ[] = {0x9f, 0x07}; | 375 | static char GET_UNKNOWN2[] = {MCE_COMMAND_HEADER, MCE_CMD_UNKNOWN2}; |
299 | static char GET_RX_TIMEOUT[] = {0x9f, 0x0d}; | 376 | static char GET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, MCE_CMD_G_CARRIER}; |
300 | static char GET_TX_BITMASK[] = {0x9f, 0x13}; | 377 | static char GET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TIMEOUT}; |
301 | static char GET_RX_SENSOR[] = {0x9f, 0x15}; | 378 | static char GET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TXMASK}; |
379 | static char GET_RX_SENSOR[] = {MCE_COMMAND_HEADER, MCE_CMD_G_RXSENSOR}; | ||
302 | /* sub in desired values in lower byte or bytes for full command */ | 380 | /* sub in desired values in lower byte or bytes for full command */ |
303 | /* FIXME: make use of these for transmit. | 381 | /* FIXME: make use of these for transmit. |
304 | static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00}; | 382 | static char SET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, |
305 | static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00}; | 383 | MCE_CMD_S_CARRIER, 0x00, 0x00}; |
306 | static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00}; | 384 | static char SET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_S_TXMASK, 0x00}; |
307 | static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00}; | 385 | static char SET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, |
386 | MCE_CMD_S_TIMEOUT, 0x00, 0x00}; | ||
387 | static char SET_RX_SENSOR[] = {MCE_COMMAND_HEADER, | ||
388 | MCE_CMD_S_RXSENSOR, 0x00}; | ||
308 | */ | 389 | */ |
309 | 390 | ||
391 | static int mceusb_cmdsize(u8 cmd, u8 subcmd) | ||
392 | { | ||
393 | int datasize = 0; | ||
394 | |||
395 | switch (cmd) { | ||
396 | case MCE_COMMAND_NULL: | ||
397 | if (subcmd == MCE_HW_CMD_HEADER) | ||
398 | datasize = 1; | ||
399 | break; | ||
400 | case MCE_HW_CMD_HEADER: | ||
401 | switch (subcmd) { | ||
402 | case MCE_CMD_G_REVISION: | ||
403 | datasize = 2; | ||
404 | break; | ||
405 | } | ||
406 | case MCE_COMMAND_HEADER: | ||
407 | switch (subcmd) { | ||
408 | case MCE_CMD_UNKNOWN: | ||
409 | case MCE_CMD_S_CARRIER: | ||
410 | case MCE_CMD_S_TIMEOUT: | ||
411 | case MCE_CMD_G_RXSENSOR: | ||
412 | datasize = 2; | ||
413 | break; | ||
414 | case MCE_CMD_S_TXMASK: | ||
415 | case MCE_CMD_S_RXSENSOR: | ||
416 | datasize = 1; | ||
417 | break; | ||
418 | } | ||
419 | } | ||
420 | return datasize; | ||
421 | } | ||
422 | |||
310 | static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | 423 | static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, |
311 | int len, bool out) | 424 | int offset, int len, bool out) |
312 | { | 425 | { |
313 | char codes[USB_BUFLEN * 3 + 1]; | 426 | char codes[USB_BUFLEN * 3 + 1]; |
314 | char inout[9]; | 427 | char inout[9]; |
315 | int i; | ||
316 | u8 cmd, subcmd, data1, data2; | 428 | u8 cmd, subcmd, data1, data2; |
317 | struct device *dev = ir->dev; | 429 | struct device *dev = ir->dev; |
318 | int idx = 0; | 430 | int i, start, skip = 0; |
431 | |||
432 | if (!debug) | ||
433 | return; | ||
319 | 434 | ||
320 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ | 435 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ |
321 | if (ir->flags.microsoft_gen1 && !out) | 436 | if (ir->flags.microsoft_gen1 && !out) |
322 | idx = 2; | 437 | skip = 2; |
323 | 438 | ||
324 | if (len <= idx) | 439 | if (len <= skip) |
325 | return; | 440 | return; |
326 | 441 | ||
327 | for (i = 0; i < len && i < USB_BUFLEN; i++) | 442 | for (i = 0; i < len && i < USB_BUFLEN; i++) |
328 | snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF); | 443 | snprintf(codes + i * 3, 4, "%02x ", buf[i + offset] & 0xff); |
329 | 444 | ||
330 | dev_info(dev, "%sx data: %s (length=%d)\n", | 445 | dev_info(dev, "%sx data: %s(length=%d)\n", |
331 | (out ? "t" : "r"), codes, len); | 446 | (out ? "t" : "r"), codes, len); |
332 | 447 | ||
333 | if (out) | 448 | if (out) |
@@ -335,91 +450,93 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
335 | else | 450 | else |
336 | strcpy(inout, "Got\0"); | 451 | strcpy(inout, "Got\0"); |
337 | 452 | ||
338 | cmd = buf[idx] & 0xff; | 453 | start = offset + skip; |
339 | subcmd = buf[idx + 1] & 0xff; | 454 | cmd = buf[start] & 0xff; |
340 | data1 = buf[idx + 2] & 0xff; | 455 | subcmd = buf[start + 1] & 0xff; |
341 | data2 = buf[idx + 3] & 0xff; | 456 | data1 = buf[start + 2] & 0xff; |
457 | data2 = buf[start + 3] & 0xff; | ||
342 | 458 | ||
343 | switch (cmd) { | 459 | switch (cmd) { |
344 | case 0x00: | 460 | case MCE_COMMAND_NULL: |
345 | if (subcmd == 0xff && data1 == 0xaa) | 461 | if ((subcmd == MCE_HW_CMD_HEADER) && |
462 | (data1 == MCE_CMD_DEVICE_RESET)) | ||
346 | dev_info(dev, "Device reset requested\n"); | 463 | dev_info(dev, "Device reset requested\n"); |
347 | else | 464 | else |
348 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | 465 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", |
349 | cmd, subcmd); | 466 | cmd, subcmd); |
350 | break; | 467 | break; |
351 | case 0xff: | 468 | case MCE_HW_CMD_HEADER: |
352 | switch (subcmd) { | 469 | switch (subcmd) { |
353 | case 0x0b: | 470 | case MCE_CMD_G_REVISION: |
354 | if (len == 2) | 471 | if (len == 2) |
355 | dev_info(dev, "Get hw/sw rev?\n"); | 472 | dev_info(dev, "Get hw/sw rev?\n"); |
356 | else | 473 | else |
357 | dev_info(dev, "hw/sw rev 0x%02x 0x%02x " | 474 | dev_info(dev, "hw/sw rev 0x%02x 0x%02x " |
358 | "0x%02x 0x%02x\n", data1, data2, | 475 | "0x%02x 0x%02x\n", data1, data2, |
359 | buf[idx + 4], buf[idx + 5]); | 476 | buf[start + 4], buf[start + 5]); |
360 | break; | 477 | break; |
361 | case 0xaa: | 478 | case MCE_CMD_DEVICE_RESET: |
362 | dev_info(dev, "Device reset requested\n"); | 479 | dev_info(dev, "Device reset requested\n"); |
363 | break; | 480 | break; |
364 | case 0xfe: | 481 | case MCE_RSP_CMD_INVALID: |
365 | dev_info(dev, "Previous command not supported\n"); | 482 | dev_info(dev, "Previous command not supported\n"); |
366 | break; | 483 | break; |
367 | case 0x18: | 484 | case MCE_CMD_UNKNOWN7: |
368 | case 0x1b: | 485 | case MCE_CMD_UNKNOWN9: |
369 | default: | 486 | default: |
370 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | 487 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", |
371 | cmd, subcmd); | 488 | cmd, subcmd); |
372 | break; | 489 | break; |
373 | } | 490 | } |
374 | break; | 491 | break; |
375 | case 0x9f: | 492 | case MCE_COMMAND_HEADER: |
376 | switch (subcmd) { | 493 | switch (subcmd) { |
377 | case 0x03: | 494 | case MCE_CMD_PING: |
378 | dev_info(dev, "Ping\n"); | 495 | dev_info(dev, "Ping\n"); |
379 | break; | 496 | break; |
380 | case 0x04: | 497 | case MCE_CMD_UNKNOWN: |
381 | dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", | 498 | dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", |
382 | data1, data2); | 499 | data1, data2); |
383 | break; | 500 | break; |
384 | case 0x06: | 501 | case MCE_CMD_S_CARRIER: |
385 | dev_info(dev, "%s carrier mode and freq of " | 502 | dev_info(dev, "%s carrier mode and freq of " |
386 | "0x%02x 0x%02x\n", inout, data1, data2); | 503 | "0x%02x 0x%02x\n", inout, data1, data2); |
387 | break; | 504 | break; |
388 | case 0x07: | 505 | case MCE_CMD_G_CARRIER: |
389 | dev_info(dev, "Get carrier mode and freq\n"); | 506 | dev_info(dev, "Get carrier mode and freq\n"); |
390 | break; | 507 | break; |
391 | case 0x08: | 508 | case MCE_CMD_S_TXMASK: |
392 | dev_info(dev, "%s transmit blaster mask of 0x%02x\n", | 509 | dev_info(dev, "%s transmit blaster mask of 0x%02x\n", |
393 | inout, data1); | 510 | inout, data1); |
394 | break; | 511 | break; |
395 | case 0x0c: | 512 | case MCE_CMD_S_TIMEOUT: |
396 | /* value is in units of 50us, so x*50/100 or x/2 ms */ | 513 | /* value is in units of 50us, so x*50/100 or x/2 ms */ |
397 | dev_info(dev, "%s receive timeout of %d ms\n", | 514 | dev_info(dev, "%s receive timeout of %d ms\n", |
398 | inout, ((data1 << 8) | data2) / 2); | 515 | inout, ((data1 << 8) | data2) / 2); |
399 | break; | 516 | break; |
400 | case 0x0d: | 517 | case MCE_CMD_G_TIMEOUT: |
401 | dev_info(dev, "Get receive timeout\n"); | 518 | dev_info(dev, "Get receive timeout\n"); |
402 | break; | 519 | break; |
403 | case 0x13: | 520 | case MCE_CMD_G_TXMASK: |
404 | dev_info(dev, "Get transmit blaster mask\n"); | 521 | dev_info(dev, "Get transmit blaster mask\n"); |
405 | break; | 522 | break; |
406 | case 0x14: | 523 | case MCE_CMD_S_RXSENSOR: |
407 | dev_info(dev, "%s %s-range receive sensor in use\n", | 524 | dev_info(dev, "%s %s-range receive sensor in use\n", |
408 | inout, data1 == 0x02 ? "short" : "long"); | 525 | inout, data1 == 0x02 ? "short" : "long"); |
409 | break; | 526 | break; |
410 | case 0x15: | 527 | case MCE_CMD_G_RXSENSOR: |
411 | if (len == 2) | 528 | if (len == 2) |
412 | dev_info(dev, "Get receive sensor\n"); | 529 | dev_info(dev, "Get receive sensor\n"); |
413 | else | 530 | else |
414 | dev_info(dev, "Received pulse count is %d\n", | 531 | dev_info(dev, "Received pulse count is %d\n", |
415 | ((data1 << 8) | data2)); | 532 | ((data1 << 8) | data2)); |
416 | break; | 533 | break; |
417 | case 0xfe: | 534 | case MCE_RSP_CMD_INVALID: |
418 | dev_info(dev, "Error! Hardware is likely wedged...\n"); | 535 | dev_info(dev, "Error! Hardware is likely wedged...\n"); |
419 | break; | 536 | break; |
420 | case 0x05: | 537 | case MCE_CMD_UNKNOWN2: |
421 | case 0x09: | 538 | case MCE_CMD_UNKNOWN3: |
422 | case 0x0f: | 539 | case MCE_CMD_UNKNOWN5: |
423 | default: | 540 | default: |
424 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", | 541 | dev_info(dev, "Unknown command 0x%02x 0x%02x\n", |
425 | cmd, subcmd); | 542 | cmd, subcmd); |
@@ -429,6 +546,12 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
429 | default: | 546 | default: |
430 | break; | 547 | break; |
431 | } | 548 | } |
549 | |||
550 | if (cmd == MCE_IRDATA_TRAILER) | ||
551 | dev_info(dev, "End of raw IR data\n"); | ||
552 | else if ((cmd != MCE_COMMAND_HEADER) && | ||
553 | ((cmd & MCE_COMMAND_MASK) == MCE_COMMAND_IRDATA)) | ||
554 | dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem); | ||
432 | } | 555 | } |
433 | 556 | ||
434 | static void mce_async_callback(struct urb *urb, struct pt_regs *regs) | 557 | static void mce_async_callback(struct urb *urb, struct pt_regs *regs) |
@@ -446,9 +569,7 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs) | |||
446 | dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", | 569 | dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", |
447 | urb->status, len); | 570 | urb->status, len); |
448 | 571 | ||
449 | if (debug) | 572 | mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); |
450 | mceusb_dev_printdata(ir, urb->transfer_buffer, | ||
451 | len, true); | ||
452 | } | 573 | } |
453 | 574 | ||
454 | } | 575 | } |
@@ -536,8 +657,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
536 | return -ENOMEM; | 657 | return -ENOMEM; |
537 | 658 | ||
538 | /* MCE tx init header */ | 659 | /* MCE tx init header */ |
539 | cmdbuf[cmdcount++] = MCE_CONTROL_HEADER; | 660 | cmdbuf[cmdcount++] = MCE_COMMAND_HEADER; |
540 | cmdbuf[cmdcount++] = 0x08; | 661 | cmdbuf[cmdcount++] = MCE_CMD_S_TXMASK; |
541 | cmdbuf[cmdcount++] = ir->tx_mask; | 662 | cmdbuf[cmdcount++] = ir->tx_mask; |
542 | 663 | ||
543 | /* Generate mce packet data */ | 664 | /* Generate mce packet data */ |
@@ -551,7 +672,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
551 | if ((cmdcount < MCE_CMDBUF_SIZE) && | 672 | if ((cmdcount < MCE_CMDBUF_SIZE) && |
552 | (cmdcount - MCE_TX_HEADER_LENGTH) % | 673 | (cmdcount - MCE_TX_HEADER_LENGTH) % |
553 | MCE_CODE_LENGTH == 0) | 674 | MCE_CODE_LENGTH == 0) |
554 | cmdbuf[cmdcount++] = MCE_PACKET_HEADER; | 675 | cmdbuf[cmdcount++] = MCE_IRDATA_HEADER; |
555 | 676 | ||
556 | /* Insert mce packet data */ | 677 | /* Insert mce packet data */ |
557 | if (cmdcount < MCE_CMDBUF_SIZE) | 678 | if (cmdcount < MCE_CMDBUF_SIZE) |
@@ -570,7 +691,8 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
570 | 691 | ||
571 | /* Fix packet length in last header */ | 692 | /* Fix packet length in last header */ |
572 | cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = | 693 | cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = |
573 | 0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1; | 694 | MCE_COMMAND_IRDATA + (cmdcount - MCE_TX_HEADER_LENGTH) % |
695 | MCE_CODE_LENGTH - 1; | ||
574 | 696 | ||
575 | /* Check if we have room for the empty packet at the end */ | 697 | /* Check if we have room for the empty packet at the end */ |
576 | if (cmdcount >= MCE_CMDBUF_SIZE) { | 698 | if (cmdcount >= MCE_CMDBUF_SIZE) { |
@@ -579,7 +701,7 @@ static int mceusb_tx_ir(void *priv, int *txbuf, u32 n) | |||
579 | } | 701 | } |
580 | 702 | ||
581 | /* All mce commands end with an empty packet (0x80) */ | 703 | /* All mce commands end with an empty packet (0x80) */ |
582 | cmdbuf[cmdcount++] = 0x80; | 704 | cmdbuf[cmdcount++] = MCE_IRDATA_TRAILER; |
583 | 705 | ||
584 | /* Transmit the command to the mce device */ | 706 | /* Transmit the command to the mce device */ |
585 | mce_async_out(ir, cmdbuf, cmdcount); | 707 | mce_async_out(ir, cmdbuf, cmdcount); |
@@ -608,7 +730,8 @@ static int mceusb_set_tx_mask(void *priv, u32 mask) | |||
608 | struct mceusb_dev *ir = priv; | 730 | struct mceusb_dev *ir = priv; |
609 | 731 | ||
610 | if (ir->flags.tx_mask_inverted) | 732 | if (ir->flags.tx_mask_inverted) |
611 | ir->tx_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1; | 733 | ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ? |
734 | mask ^ MCE_DEFAULT_TX_MASK : mask) << 1; | ||
612 | else | 735 | else |
613 | ir->tx_mask = mask; | 736 | ir->tx_mask = mask; |
614 | 737 | ||
@@ -621,7 +744,8 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
621 | struct mceusb_dev *ir = priv; | 744 | struct mceusb_dev *ir = priv; |
622 | int clk = 10000000; | 745 | int clk = 10000000; |
623 | int prescaler = 0, divisor = 0; | 746 | int prescaler = 0, divisor = 0; |
624 | unsigned char cmdbuf[4] = { 0x9f, 0x06, 0x00, 0x00 }; | 747 | unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER, |
748 | MCE_CMD_S_CARRIER, 0x00, 0x00 }; | ||
625 | 749 | ||
626 | /* Carrier has changed */ | 750 | /* Carrier has changed */ |
627 | if (ir->carrier != carrier) { | 751 | if (ir->carrier != carrier) { |
@@ -629,7 +753,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
629 | if (carrier == 0) { | 753 | if (carrier == 0) { |
630 | ir->carrier = carrier; | 754 | ir->carrier = carrier; |
631 | cmdbuf[2] = 0x01; | 755 | cmdbuf[2] = 0x01; |
632 | cmdbuf[3] = 0x80; | 756 | cmdbuf[3] = MCE_IRDATA_TRAILER; |
633 | dev_dbg(ir->dev, "%s: disabling carrier " | 757 | dev_dbg(ir->dev, "%s: disabling carrier " |
634 | "modulation\n", __func__); | 758 | "modulation\n", __func__); |
635 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); | 759 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); |
@@ -638,7 +762,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
638 | 762 | ||
639 | for (prescaler = 0; prescaler < 4; ++prescaler) { | 763 | for (prescaler = 0; prescaler < 4; ++prescaler) { |
640 | divisor = (clk >> (2 * prescaler)) / carrier; | 764 | divisor = (clk >> (2 * prescaler)) / carrier; |
641 | if (divisor <= 0xFF) { | 765 | if (divisor <= 0xff) { |
642 | ir->carrier = carrier; | 766 | ir->carrier = carrier; |
643 | cmdbuf[2] = prescaler; | 767 | cmdbuf[2] = prescaler; |
644 | cmdbuf[3] = divisor; | 768 | cmdbuf[3] = divisor; |
@@ -660,47 +784,36 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
660 | 784 | ||
661 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | 785 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) |
662 | { | 786 | { |
663 | struct ir_raw_event rawir = { .pulse = false, .duration = 0 }; | 787 | DEFINE_IR_RAW_EVENT(rawir); |
664 | int i, start_index = 0; | 788 | int i = 0; |
665 | u8 hdr = MCE_CONTROL_HEADER; | ||
666 | 789 | ||
667 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ | 790 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ |
668 | if (ir->flags.microsoft_gen1) | 791 | if (ir->flags.microsoft_gen1) |
669 | start_index = 2; | 792 | i = 2; |
670 | 793 | ||
671 | for (i = start_index; i < buf_len;) { | 794 | for (; i < buf_len; i++) { |
672 | if (ir->rem == 0) { | 795 | switch (ir->parser_state) { |
673 | /* decode mce packets of the form (84),AA,BB,CC,DD */ | 796 | case SUBCMD: |
674 | /* IR data packets can span USB messages - rem */ | 797 | ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]); |
675 | hdr = ir->buf_in[i]; | 798 | mceusb_dev_printdata(ir, ir->buf_in, i - 1, |
676 | ir->rem = (hdr & MCE_PACKET_LENGTH_MASK); | 799 | ir->rem + 2, false); |
677 | ir->cmd = (hdr & ~MCE_PACKET_LENGTH_MASK); | 800 | ir->parser_state = CMD_DATA; |
678 | dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n", | 801 | break; |
679 | ir->rem, ir->cmd); | 802 | case PARSE_IRDATA: |
680 | i++; | ||
681 | } | ||
682 | |||
683 | /* don't process MCE commands */ | ||
684 | if (hdr == MCE_CONTROL_HEADER || hdr == 0xff) { | ||
685 | ir->rem = 0; | ||
686 | return; | ||
687 | } | ||
688 | |||
689 | for (; (ir->rem > 0) && (i < buf_len); i++) { | ||
690 | ir->rem--; | 803 | ir->rem--; |
691 | |||
692 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); | 804 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); |
693 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) | 805 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) |
694 | * MCE_TIME_UNIT * 1000; | 806 | * MCE_TIME_UNIT * 1000; |
695 | 807 | ||
696 | if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { | 808 | if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { |
697 | if (ir->rawir.pulse == rawir.pulse) | 809 | if (ir->rawir.pulse == rawir.pulse) { |
698 | ir->rawir.duration += rawir.duration; | 810 | ir->rawir.duration += rawir.duration; |
699 | else { | 811 | } else { |
700 | ir->rawir.duration = rawir.duration; | 812 | ir->rawir.duration = rawir.duration; |
701 | ir->rawir.pulse = rawir.pulse; | 813 | ir->rawir.pulse = rawir.pulse; |
702 | } | 814 | } |
703 | continue; | 815 | if (ir->rem) |
816 | break; | ||
704 | } | 817 | } |
705 | rawir.duration += ir->rawir.duration; | 818 | rawir.duration += ir->rawir.duration; |
706 | ir->rawir.duration = 0; | 819 | ir->rawir.duration = 0; |
@@ -711,14 +824,40 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
711 | rawir.duration); | 824 | rawir.duration); |
712 | 825 | ||
713 | ir_raw_event_store(ir->idev, &rawir); | 826 | ir_raw_event_store(ir->idev, &rawir); |
827 | break; | ||
828 | case CMD_DATA: | ||
829 | ir->rem--; | ||
830 | break; | ||
831 | case CMD_HEADER: | ||
832 | /* decode mce packets of the form (84),AA,BB,CC,DD */ | ||
833 | /* IR data packets can span USB messages - rem */ | ||
834 | ir->cmd = ir->buf_in[i]; | ||
835 | if ((ir->cmd == MCE_COMMAND_HEADER) || | ||
836 | ((ir->cmd & MCE_COMMAND_MASK) != | ||
837 | MCE_COMMAND_IRDATA)) { | ||
838 | ir->parser_state = SUBCMD; | ||
839 | continue; | ||
840 | } | ||
841 | ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); | ||
842 | mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false); | ||
843 | if (ir->rem) { | ||
844 | ir->parser_state = PARSE_IRDATA; | ||
845 | break; | ||
846 | } | ||
847 | /* | ||
848 | * a package with len=0 (e. g. 0x80) means end of | ||
849 | * data. We could use it to do the call to | ||
850 | * ir_raw_event_handle(). For now, we don't need to | ||
851 | * use it. | ||
852 | */ | ||
853 | break; | ||
714 | } | 854 | } |
715 | 855 | ||
716 | if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f) | 856 | if (ir->parser_state != CMD_HEADER && !ir->rem) |
717 | ir->rem = 0; | 857 | ir->parser_state = CMD_HEADER; |
718 | |||
719 | dev_dbg(ir->dev, "calling ir_raw_event_handle\n"); | ||
720 | ir_raw_event_handle(ir->idev); | ||
721 | } | 858 | } |
859 | dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); | ||
860 | ir_raw_event_handle(ir->idev); | ||
722 | } | 861 | } |
723 | 862 | ||
724 | static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | 863 | static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) |
@@ -737,9 +876,6 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
737 | 876 | ||
738 | buf_len = urb->actual_length; | 877 | buf_len = urb->actual_length; |
739 | 878 | ||
740 | if (debug) | ||
741 | mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false); | ||
742 | |||
743 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { | 879 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { |
744 | ir->send_flags = SEND_FLAG_COMPLETE; | 880 | ir->send_flags = SEND_FLAG_COMPLETE; |
745 | dev_dbg(ir->dev, "setup answer received %d bytes\n", | 881 | dev_dbg(ir->dev, "setup answer received %d bytes\n", |
@@ -760,6 +896,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
760 | 896 | ||
761 | case -EPIPE: | 897 | case -EPIPE: |
762 | default: | 898 | default: |
899 | dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status); | ||
763 | break; | 900 | break; |
764 | } | 901 | } |
765 | 902 | ||
@@ -865,6 +1002,8 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | |||
865 | struct input_dev *idev; | 1002 | struct input_dev *idev; |
866 | struct ir_dev_props *props; | 1003 | struct ir_dev_props *props; |
867 | struct device *dev = ir->dev; | 1004 | struct device *dev = ir->dev; |
1005 | const char *rc_map = RC_MAP_RC6_MCE; | ||
1006 | const char *name = "Media Center Ed. eHome Infrared Remote Transceiver"; | ||
868 | int ret = -ENODEV; | 1007 | int ret = -ENODEV; |
869 | 1008 | ||
870 | idev = input_allocate_device(); | 1009 | idev = input_allocate_device(); |
@@ -880,8 +1019,11 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | |||
880 | goto props_alloc_failed; | 1019 | goto props_alloc_failed; |
881 | } | 1020 | } |
882 | 1021 | ||
883 | snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome " | 1022 | if (mceusb_model[ir->model].name) |
884 | "Infrared Remote Transceiver (%04x:%04x)", | 1023 | name = mceusb_model[ir->model].name; |
1024 | |||
1025 | snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)", | ||
1026 | name, | ||
885 | le16_to_cpu(ir->usbdev->descriptor.idVendor), | 1027 | le16_to_cpu(ir->usbdev->descriptor.idVendor), |
886 | le16_to_cpu(ir->usbdev->descriptor.idProduct)); | 1028 | le16_to_cpu(ir->usbdev->descriptor.idProduct)); |
887 | 1029 | ||
@@ -899,7 +1041,10 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | |||
899 | 1041 | ||
900 | ir->props = props; | 1042 | ir->props = props; |
901 | 1043 | ||
902 | ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME); | 1044 | if (mceusb_model[ir->model].rc_map) |
1045 | rc_map = mceusb_model[ir->model].rc_map; | ||
1046 | |||
1047 | ret = ir_input_register(idev, rc_map, props, DRIVER_NAME); | ||
903 | if (ret < 0) { | 1048 | if (ret < 0) { |
904 | dev_err(dev, "remote input device register failed\n"); | 1049 | dev_err(dev, "remote input device register failed\n"); |
905 | goto irdev_failed; | 1050 | goto irdev_failed; |
@@ -926,17 +1071,26 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
926 | struct mceusb_dev *ir = NULL; | 1071 | struct mceusb_dev *ir = NULL; |
927 | int pipe, maxp, i; | 1072 | int pipe, maxp, i; |
928 | char buf[63], name[128] = ""; | 1073 | char buf[63], name[128] = ""; |
1074 | enum mceusb_model_type model = id->driver_info; | ||
929 | bool is_gen3; | 1075 | bool is_gen3; |
930 | bool is_microsoft_gen1; | 1076 | bool is_microsoft_gen1; |
931 | bool tx_mask_inverted; | 1077 | bool tx_mask_inverted; |
1078 | bool is_polaris; | ||
932 | 1079 | ||
933 | dev_dbg(&intf->dev, ": %s called\n", __func__); | 1080 | dev_dbg(&intf->dev, ": %s called\n", __func__); |
934 | 1081 | ||
935 | idesc = intf->cur_altsetting; | 1082 | idesc = intf->cur_altsetting; |
936 | 1083 | ||
937 | is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0; | 1084 | is_gen3 = mceusb_model[model].mce_gen3; |
938 | is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0; | 1085 | is_microsoft_gen1 = mceusb_model[model].mce_gen1; |
939 | tx_mask_inverted = usb_match_id(intf, std_tx_mask_list) ? 0 : 1; | 1086 | tx_mask_inverted = mceusb_model[model].tx_mask_inverted; |
1087 | is_polaris = mceusb_model[model].is_polaris; | ||
1088 | |||
1089 | if (is_polaris) { | ||
1090 | /* Interface 0 is IR */ | ||
1091 | if (idesc->desc.bInterfaceNumber) | ||
1092 | return -ENODEV; | ||
1093 | } | ||
940 | 1094 | ||
941 | /* step through the endpoints to find first bulk in and out endpoint */ | 1095 | /* step through the endpoints to find first bulk in and out endpoint */ |
942 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { | 1096 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { |
@@ -997,6 +1151,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
997 | ir->len_in = maxp; | 1151 | ir->len_in = maxp; |
998 | ir->flags.microsoft_gen1 = is_microsoft_gen1; | 1152 | ir->flags.microsoft_gen1 = is_microsoft_gen1; |
999 | ir->flags.tx_mask_inverted = tx_mask_inverted; | 1153 | ir->flags.tx_mask_inverted = tx_mask_inverted; |
1154 | ir->model = model; | ||
1155 | |||
1156 | init_ir_raw_event(&ir->rawir); | ||
1000 | 1157 | ||
1001 | /* Saving usb interface data for use by the transmitter routine */ | 1158 | /* Saving usb interface data for use by the transmitter routine */ |
1002 | ir->usb_ep_in = ep_in; | 1159 | ir->usb_ep_in = ep_in; |