aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/mceusb.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-10-22 00:35:44 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-22 18:05:37 -0400
commit39dc5c3adf65bf86115aeccd740993256e6a22d4 (patch)
treef8f523805bb658cb84b55d9e2d925685628bc04e /drivers/media/IR/mceusb.c
parent4c8fa38198e58e9ccf5fca1d76792540eac047da (diff)
[media] mceusb: improve ir data buffer parser
Switch to a state machine that properly handles all incoming urb data packets, and reads much cleaner and corrects some minor parsing errors that were hindering decode on cx231xx/Polaris integrated IR. Also tested with four different mceusb variants, and works perfectly with all of them (at least for the rc6a mce remotes). Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Jarod Wilson <jarod@redhat.com>
Diffstat (limited to 'drivers/media/IR/mceusb.c')
-rw-r--r--drivers/media/IR/mceusb.c151
1 files changed, 103 insertions, 48 deletions
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
index a726f63ecfea..c890cd521b20 100644
--- a/drivers/media/IR/mceusb.c
+++ b/drivers/media/IR/mceusb.c
@@ -56,14 +56,16 @@
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_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */
59#define MCE_CONTROL_HEADER 0x9F /* MCE status header */ 59#define MCE_CONTROL_HEADER 0x9f /* MCE status header */
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 /* Val opts: 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#define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */
67#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
68#define MCE_COMMAND_IRDATA 0x80 /* buf & MCE_COMMAND_MASK == 0x80 -> IR data */
67 69
68 70
69/* module parameters */ 71/* module parameters */
@@ -256,8 +258,15 @@ struct mceusb_dev {
256 /* buffers and dma */ 258 /* buffers and dma */
257 unsigned char *buf_in; 259 unsigned char *buf_in;
258 unsigned int len_in; 260 unsigned int len_in;
259 u8 cmd; /* MCE command type */ 261
260 u8 rem; /* Remaining IR data bytes in packet */ 262 enum {
263 CMD_HEADER = 0,
264 SUBCMD,
265 CMD_DATA,
266 PARSE_IRDATA,
267 } parser_state;
268 u8 cmd, rem; /* Remaining IR data bytes in packet */
269
261 dma_addr_t dma_in; 270 dma_addr_t dma_in;
262 dma_addr_t dma_out; 271 dma_addr_t dma_out;
263 272
@@ -302,19 +311,51 @@ struct mceusb_dev {
302static char DEVICE_RESET[] = {0x00, 0xff, 0xaa}; 311static char DEVICE_RESET[] = {0x00, 0xff, 0xaa};
303static char GET_REVISION[] = {0xff, 0x0b}; 312static char GET_REVISION[] = {0xff, 0x0b};
304static char GET_UNKNOWN[] = {0xff, 0x18}; 313static char GET_UNKNOWN[] = {0xff, 0x18};
305static char GET_UNKNOWN2[] = {0x9f, 0x05}; 314static char GET_UNKNOWN2[] = {MCE_CONTROL_HEADER, 0x05};
306static char GET_CARRIER_FREQ[] = {0x9f, 0x07}; 315static char GET_CARRIER_FREQ[] = {MCE_CONTROL_HEADER, 0x07};
307static char GET_RX_TIMEOUT[] = {0x9f, 0x0d}; 316static char GET_RX_TIMEOUT[] = {MCE_CONTROL_HEADER, 0x0d};
308static char GET_TX_BITMASK[] = {0x9f, 0x13}; 317static char GET_TX_BITMASK[] = {MCE_CONTROL_HEADER, 0x13};
309static char GET_RX_SENSOR[] = {0x9f, 0x15}; 318static char GET_RX_SENSOR[] = {MCE_CONTROL_HEADER, 0x15};
310/* sub in desired values in lower byte or bytes for full command */ 319/* sub in desired values in lower byte or bytes for full command */
311/* FIXME: make use of these for transmit. 320/* FIXME: make use of these for transmit.
312static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00}; 321static char SET_CARRIER_FREQ[] = {MCE_CONTROL_HEADER, 0x06, 0x00, 0x00};
313static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00}; 322static char SET_TX_BITMASK[] = {MCE_CONTROL_HEADER, 0x08, 0x00};
314static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00}; 323static char SET_RX_TIMEOUT[] = {MCE_CONTROL_HEADER, 0x0c, 0x00, 0x00};
315static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00}; 324static char SET_RX_SENSOR[] = {MCE_CONTROL_HEADER, 0x14, 0x00};
316*/ 325*/
317 326
327static int mceusb_cmdsize(u8 cmd, u8 subcmd)
328{
329 int datasize = 0;
330
331 switch (cmd) {
332 case 0x00:
333 if (subcmd == 0xff)
334 datasize = 1;
335 break;
336 case 0xff:
337 switch (subcmd) {
338 case 0x0b:
339 datasize = 2;
340 break;
341 }
342 case MCE_CONTROL_HEADER:
343 switch (subcmd) {
344 case 0x04:
345 case 0x06:
346 case 0x0c:
347 case 0x15:
348 datasize = 2;
349 break;
350 case 0x08:
351 case 0x14:
352 datasize = 1;
353 break;
354 }
355 }
356 return datasize;
357}
358
318static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, 359static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
319 int len, bool out) 360 int len, bool out)
320{ 361{
@@ -380,7 +421,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
380 break; 421 break;
381 } 422 }
382 break; 423 break;
383 case 0x9f: 424 case MCE_CONTROL_HEADER:
384 switch (subcmd) { 425 switch (subcmd) {
385 case 0x03: 426 case 0x03:
386 dev_info(dev, "Ping\n"); 427 dev_info(dev, "Ping\n");
@@ -629,7 +670,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
629 struct mceusb_dev *ir = priv; 670 struct mceusb_dev *ir = priv;
630 int clk = 10000000; 671 int clk = 10000000;
631 int prescaler = 0, divisor = 0; 672 int prescaler = 0, divisor = 0;
632 unsigned char cmdbuf[4] = { 0x9f, 0x06, 0x00, 0x00 }; 673 unsigned char cmdbuf[4] = { MCE_CONTROL_HEADER, 0x06, 0x00, 0x00 };
633 674
634 /* Carrier has changed */ 675 /* Carrier has changed */
635 if (ir->carrier != carrier) { 676 if (ir->carrier != carrier) {
@@ -669,46 +710,33 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
669static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) 710static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
670{ 711{
671 DEFINE_IR_RAW_EVENT(rawir); 712 DEFINE_IR_RAW_EVENT(rawir);
672 int i, start_index = 0; 713 int i = 0;
673 u8 hdr = MCE_CONTROL_HEADER;
674 714
675 /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ 715 /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
676 if (ir->flags.microsoft_gen1) 716 if (ir->flags.microsoft_gen1)
677 start_index = 2; 717 i = 2;
678
679 for (i = start_index; i < buf_len;) {
680 if (ir->rem == 0) {
681 /* decode mce packets of the form (84),AA,BB,CC,DD */
682 /* IR data packets can span USB messages - rem */
683 hdr = ir->buf_in[i];
684 ir->rem = (hdr & MCE_PACKET_LENGTH_MASK);
685 ir->cmd = (hdr & ~MCE_PACKET_LENGTH_MASK);
686 dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n",
687 ir->rem, ir->cmd);
688 i++;
689 }
690 718
691 /* don't process MCE commands */ 719 for (; i < buf_len; i++) {
692 if (hdr == MCE_CONTROL_HEADER || hdr == 0xff) { 720 switch (ir->parser_state) {
693 ir->rem = 0; 721 case SUBCMD:
694 return; 722 ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
695 } 723 ir->parser_state = CMD_DATA;
696 724 break;
697 for (; (ir->rem > 0) && (i < buf_len); i++) { 725 case PARSE_IRDATA:
698 ir->rem--; 726 ir->rem--;
699
700 rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); 727 rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
701 rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) 728 rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
702 * MCE_TIME_UNIT * 1000; 729 * MCE_TIME_UNIT * 1000;
703 730
704 if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { 731 if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
705 if (ir->rawir.pulse == rawir.pulse) 732 if (ir->rawir.pulse == rawir.pulse) {
706 ir->rawir.duration += rawir.duration; 733 ir->rawir.duration += rawir.duration;
707 else { 734 } else {
708 ir->rawir.duration = rawir.duration; 735 ir->rawir.duration = rawir.duration;
709 ir->rawir.pulse = rawir.pulse; 736 ir->rawir.pulse = rawir.pulse;
710 } 737 }
711 continue; 738 if (ir->rem)
739 break;
712 } 740 }
713 rawir.duration += ir->rawir.duration; 741 rawir.duration += ir->rawir.duration;
714 ir->rawir.duration = 0; 742 ir->rawir.duration = 0;
@@ -719,14 +747,40 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
719 rawir.duration); 747 rawir.duration);
720 748
721 ir_raw_event_store(ir->idev, &rawir); 749 ir_raw_event_store(ir->idev, &rawir);
750 break;
751 case CMD_DATA:
752 ir->rem--;
753 break;
754 case CMD_HEADER:
755 /* decode mce packets of the form (84),AA,BB,CC,DD */
756 /* IR data packets can span USB messages - rem */
757 ir->cmd = ir->buf_in[i];
758 if ((ir->cmd == MCE_CONTROL_HEADER) ||
759 ((ir->cmd & MCE_COMMAND_MASK) != MCE_COMMAND_IRDATA)) {
760 ir->parser_state = SUBCMD;
761 continue;
762 }
763 ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
764 dev_dbg(ir->dev, "Processing RX data: len = %d\n",
765 ir->rem);
766 if (ir->rem) {
767 ir->parser_state = PARSE_IRDATA;
768 break;
769 }
770 /*
771 * a package with len=0 (e. g. 0x80) means end of
772 * data. We could use it to do the call to
773 * ir_raw_event_handle(). For now, we don't need to
774 * use it.
775 */
776 break;
722 } 777 }
723 778
724 if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f) 779 if (ir->parser_state != CMD_HEADER && !ir->rem)
725 ir->rem = 0; 780 ir->parser_state = CMD_HEADER;
726
727 dev_dbg(ir->dev, "calling ir_raw_event_handle\n");
728 ir_raw_event_handle(ir->idev);
729 } 781 }
782 dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
783 ir_raw_event_handle(ir->idev);
730} 784}
731 785
732static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) 786static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
@@ -768,6 +822,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
768 822
769 case -EPIPE: 823 case -EPIPE:
770 default: 824 default:
825 dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
771 break; 826 break;
772 } 827 }
773 828