else                                    /* Normal NEC */
                        poll_result->scancode = msg[1] << 8 | msg[3];
                break;
+       case RC_BIT_RC6_0:
+               poll_result->scancode = msg[1] << 8 | msg[2];
+               break;
        default:
                poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) |
                                        (msg[3] << 8)  | msg[4];
        cancel_delayed_work_sync(&ir->work);
 }
 
-static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
+static int em2860_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
 {
-       int rc = 0;
        struct em28xx_IR *ir = rc_dev->priv;
        struct em28xx *dev = ir->dev;
-       u8 ir_config = EM2874_IR_RC5;
 
-       /* Adjust xclk based o IR table for RC5/NEC tables */
+       /* Adjust xclk based on IR table for RC5/NEC tables */
+       if (*rc_type & RC_BIT_RC5) {
+               dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
+               ir->full_code = 1;
+               *rc_type = RC_BIT_RC5;
+       } else if (*rc_type & RC_BIT_NEC) {
+               dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE;
+               ir->full_code = 1;
+               *rc_type = RC_BIT_NEC;
+       } else if (*rc_type & RC_BIT_UNKNOWN) {
+               *rc_type = RC_BIT_UNKNOWN;
+       } else {
+               *rc_type = ir->rc_type;
+               return -EINVAL;
+       }
+       ir->get_key = default_polling_getkey;
+       em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
+                             EM28XX_XCLK_IR_RC5_MODE);
+
+       ir->rc_type = *rc_type;
 
+       return 0;
+}
+
+static int em2874_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
+{
+       struct em28xx_IR *ir = rc_dev->priv;
+       struct em28xx *dev = ir->dev;
+       u8 ir_config = EM2874_IR_RC5;
+
+       /* Adjust xclk and set type based on IR table for RC5/NEC/RC6 tables */
        if (*rc_type & RC_BIT_RC5) {
                dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
                ir->full_code = 1;
                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;
+       } else if (*rc_type & RC_BIT_RC6_0) {
+               dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
+               ir_config = EM2874_IR_RC6_MODE_0;
+               ir->full_code = 1;
+               *rc_type = RC_BIT_RC6_0;
+       } else if (*rc_type & RC_BIT_UNKNOWN) {
+               *rc_type = RC_BIT_UNKNOWN;
+       } else {
+               *rc_type = ir->rc_type;
+               return -EINVAL;
+       }
 
-       ir->rc_type = *rc_type;
+       ir->get_key = em2874_polling_getkey;
+       em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
 
        em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
                              EM28XX_XCLK_IR_RC5_MODE);
 
+       ir->rc_type = *rc_type;
+
+       return 0;
+}
+static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
+{
+       struct em28xx_IR *ir = rc_dev->priv;
+       struct em28xx *dev = ir->dev;
+
        /* Setup the proper handler based on the chip */
        switch (dev->chip_id) {
        case CHIP_ID_EM2860:
        case CHIP_ID_EM2883:
-               ir->get_key = default_polling_getkey;
-               break;
+               return em2860_ir_change_protocol(rc_dev, rc_type);
        case CHIP_ID_EM2884:
        case CHIP_ID_EM2874:
        case CHIP_ID_EM28174:
-               ir->get_key = em2874_polling_getkey;
-               em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
-               break;
+               return em2874_ir_change_protocol(rc_dev, rc_type);
        default:
                printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n",
                        dev->chip_id);
-               rc = -EINVAL;
+               return -EINVAL;
        }
-
-       return rc;
 }
 
 static void em28xx_register_i2c_ir(struct em28xx *dev)
        rc->open = em28xx_ir_start;
        rc->close = em28xx_ir_stop;
 
+       switch (dev->chip_id) {
+       case CHIP_ID_EM2860:
+       case CHIP_ID_EM2883:
+               rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
+               break;
+       case CHIP_ID_EM2884:
+       case CHIP_ID_EM2874:
+       case CHIP_ID_EM28174:
+               rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | RC_BIT_RC6_0;
+               break;
+       default:
+               err = -ENODEV;
+               goto err_out_free;
+       }
+
        /* By default, keep protocol field untouched */
        rc_type = RC_BIT_UNKNOWN;
        err = em28xx_ir_change_protocol(rc, &rc_type);
 
        return 0;
 
- err_out_stop:
+err_out_stop:
        dev->ir = NULL;
- err_out_free:
+err_out_free:
        rc_free_device(rc);
        kfree(ir);
        return err;