struct em28xx_ir_poll_result {
        unsigned int toggle_bit:1;
        unsigned int read_count:7;
-       u8 rc_address;
-       u8 rc_data[4]; /* 1 byte on em2860/2880, 4 on em2874 */
+
+       u32 scancode;
 };
 
 struct em28xx_IR {
        struct delayed_work work;
        unsigned int full_code:1;
        unsigned int last_readcount;
+       u64 rc_type;
 
        int  (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
 };
        /* Infrared read count (Reg 0x45[6:0] */
        poll_result->read_count = (msg[0] & 0x7f);
 
-       /* Remote Control Address (Reg 0x46) */
-       poll_result->rc_address = msg[1];
-
-       /* Remote Control Data (Reg 0x47) */
-       poll_result->rc_data[0] = msg[2];
+       /* Remote Control Address/Data (Regs 0x46/0x47) */
+       poll_result->scancode = msg[1] << 8 | msg[2];
 
        return 0;
 }
        /* Infrared read count (Reg 0x51[6:0] */
        poll_result->read_count = (msg[0] & 0x7f);
 
-       /* Remote Control Address (Reg 0x52) */
-       poll_result->rc_address = msg[1];
-
-       /* Remote Control Data (Reg 0x53-55) */
-       poll_result->rc_data[0] = msg[2];
-       poll_result->rc_data[1] = msg[3];
-       poll_result->rc_data[2] = msg[4];
+       /*
+        * Remote Control Address (Reg 0x52)
+        * Remote Control Data (Reg 0x53-0x55)
+        */
+       switch (ir->rc_type) {
+       case RC_BIT_RC5:
+               poll_result->scancode = msg[1] << 8 | msg[2];
+               break;
+       case RC_BIT_NEC:
+               if ((msg[3] ^ msg[4]) != 0xff)          /* 32 bits NEC */
+                       poll_result->scancode = (msg[1] << 24) |
+                                               (msg[2] << 16) |
+                                               (msg[3] << 8)  |
+                                                msg[4];
+               else if ((msg[1] ^ msg[2]) != 0xff)     /* 24 bits NEC */
+                       poll_result->scancode = (msg[1] << 16) |
+                                               (msg[2] << 8)  |
+                                                msg[3];
+               else                                    /* Normal NEC */
+                       poll_result->scancode = msg[1] << 8 | msg[3];
+               break;
+       default:
+               poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) |
+                                       (msg[3] << 8)  | msg[4];
+               break;
+       }
 
        return 0;
 }
        }
 
        if (unlikely(poll_result.read_count != ir->last_readcount)) {
-               dprintk("%s: toggle: %d, count: %d, key 0x%02x%02x\n", __func__,
+               dprintk("%s: toggle: %d, count: %d, key 0x%04x\n", __func__,
                        poll_result.toggle_bit, poll_result.read_count,
-                       poll_result.rc_address, poll_result.rc_data[0]);
+                       poll_result.scancode);
                if (ir->full_code)
                        rc_keydown(ir->rc,
-                                  poll_result.rc_address << 8 |
-                                  poll_result.rc_data[0],
+                                  poll_result.scancode,
                                   poll_result.toggle_bit);
                else
                        rc_keydown(ir->rc,
-                                  poll_result.rc_data[0],
+                                  poll_result.scancode & 0xff,
                                   poll_result.toggle_bit);
 
                if (ir->dev->chip_id == CHIP_ID_EM2874 ||
                *rc_type = RC_BIT_RC5;
        } else if (*rc_type & RC_BIT_NEC) {
                dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
-               ir_config = EM2874_IR_NEC;
+               ir_config = EM2874_IR_NEC | EM2874_IR_NEC_NO_PARITY;
                ir->full_code = 1;
                *rc_type = RC_BIT_NEC;
        } else if (*rc_type != RC_BIT_UNKNOWN)
                rc = -EINVAL;
 
+       ir->rc_type = *rc_type;
+
        em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
                              EM28XX_XCLK_IR_RC5_MODE);