dev->priv = coredev;
        dev->driver_type = RC_DRIVER_IR_RAW;
-       dev->allowed_protos = RC_TYPE_ALL;
+       dev->allowed_protos = RC_BIT_ALL;
        dev->map_name = sms_get_board(board_id)->rc_codes;
        dev->driver_name = MODULE_NAME;
 
 
 {
        char *ir_codes = NULL;
        const char *name = NULL;
-       u64 rc_type = RC_TYPE_UNKNOWN;
+       u64 rc_type = RC_BIT_UNKNOWN;
        struct IR_i2c *ir;
        struct rc_dev *rc = NULL;
        struct i2c_adapter *adap = client->adapter;
        case 0x64:
                name        = "Pixelview";
                ir->get_key = get_key_pixelview;
-               rc_type     = RC_TYPE_OTHER;
+               rc_type     = RC_BIT_OTHER;
                ir_codes    = RC_MAP_EMPTY;
                break;
        case 0x18:
        case 0x1a:
                name        = "Hauppauge";
                ir->get_key = get_key_haup;
-               rc_type     = RC_TYPE_RC5;
+               rc_type     = RC_BIT_RC5;
                ir_codes    = RC_MAP_HAUPPAUGE;
                break;
        case 0x30:
                name        = "KNC One";
                ir->get_key = get_key_knc1;
-               rc_type     = RC_TYPE_OTHER;
+               rc_type     = RC_BIT_OTHER;
                ir_codes    = RC_MAP_EMPTY;
                break;
        case 0x6b:
                name        = "FusionHDTV";
                ir->get_key = get_key_fusionhdtv;
-               rc_type     = RC_TYPE_RC5;
+               rc_type     = RC_BIT_RC5;
                ir_codes    = RC_MAP_FUSIONHDTV_MCE;
                break;
        case 0x40:
                name        = "AVerMedia Cardbus remote";
                ir->get_key = get_key_avermedia_cardbus;
-               rc_type     = RC_TYPE_OTHER;
+               rc_type     = RC_BIT_OTHER;
                ir_codes    = RC_MAP_AVERMEDIA_CARDBUS;
                break;
        case 0x71:
                name        = "Hauppauge/Zilog Z8";
                ir->get_key = get_key_haup_xvr;
-               rc_type     = RC_TYPE_RC5;
+               rc_type     = RC_BIT_RC5;
                ir_codes    = RC_MAP_HAUPPAUGE;
                break;
        }
 
        case CX18_HW_Z8F0811_IR_RX_HAUP:
                init_data->ir_codes = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-               init_data->type = RC_TYPE_RC5;
+               init_data->type = RC_BIT_RC5;
                init_data->name = cx->card_name;
                info.platform_data = init_data;
                break;
 
        case CX23885_BOARD_HAUPPAUGE_HVR1250:
                /* Integrated CX2388[58] IR controller */
                driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_TYPE_ALL;
+               allowed_protos = RC_BIT_ALL;
                /* The grey Hauppauge RC-5 remote */
                rc_map = RC_MAP_HAUPPAUGE;
                break;
        case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL:
                /* Integrated CX23885 IR controller */
                driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_TYPE_NEC;
+               allowed_protos = RC_BIT_NEC;
                /* The grey Terratec remote with orange buttons */
                rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS;
                break;
        case CX23885_BOARD_TEVII_S470:
                /* Integrated CX23885 IR controller */
                driver_type = RC_DRIVER_IR_RAW;
-               allowed_protos = RC_TYPE_ALL;
+               allowed_protos = RC_BIT_ALL;
                /* A guess at the remote */
                rc_map = RC_MAP_TEVII_NEC;
                break;
 
        struct cx88_IR *ir;
        struct rc_dev *dev;
        char *ir_codes = NULL;
-       u64 rc_type = RC_TYPE_OTHER;
+       u64 rc_type = RC_BIT_OTHER;
        int err = -ENOMEM;
        u32 hardware_mask = 0;  /* For devices with a hardware mask, when
                                 * used with a full-code IR table
                break;
        case CX88_BOARD_TWINHAN_VP1027_DVBS:
                ir_codes         = RC_MAP_TWINHAN_VP1027_DVBS;
-               rc_type          = RC_TYPE_NEC;
+               rc_type          = RC_BIT_NEC;
                ir->sampling     = 0xff00; /* address */
                break;
        }
        case CX88_BOARD_LEADTEK_PVR2000:
                addr_list = pvr2000_addr_list;
                core->init_data.name = "cx88 Leadtek PVR 2000 remote";
-               core->init_data.type = RC_TYPE_UNKNOWN;
+               core->init_data.type = RC_BIT_UNKNOWN;
                core->init_data.get_key = get_key_pvr2000;
                core->init_data.ir_codes = RC_MAP_EMPTY;
                break;
                        /* Hauppauge XVR */
                        core->init_data.name = "cx88 Hauppauge XVR remote";
                        core->init_data.ir_codes = RC_MAP_HAUPPAUGE;
-                       core->init_data.type = RC_TYPE_RC5;
+                       core->init_data.type = RC_BIT_RC5;
                        core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
 
                        info.platform_data = &core->init_data;
 
                init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
                init_data->internal_get_key_func =
                                        IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
-               init_data->type = RC_TYPE_OTHER;
+               init_data->type = RC_BIT_OTHER;
                init_data->name = "AVerMedia AVerTV card";
                break;
        case IVTV_HW_I2C_IR_RX_HAUP_EXT:
        case IVTV_HW_I2C_IR_RX_HAUP_INT:
                init_data->ir_codes = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
-               init_data->type = RC_TYPE_RC5;
+               init_data->type = RC_BIT_RC5;
                init_data->name = itv->card_name;
                break;
        case IVTV_HW_Z8F0811_IR_RX_HAUP:
                /* Default to grey remote */
                init_data->ir_codes = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-               init_data->type = RC_TYPE_RC5;
+               init_data->type = RC_BIT_RC5;
                init_data->name = itv->card_name;
                break;
        case IVTV_HW_I2C_IR_RX_ADAPTEC:
                init_data->name = itv->card_name;
                /* FIXME: The protocol and RC_MAP needs to be corrected */
                init_data->ir_codes = RC_MAP_EMPTY;
-               init_data->type = RC_TYPE_UNKNOWN;
+               init_data->type = RC_BIT_UNKNOWN;
                break;
        }
 
 
                dev->init_data.name = "BeholdTV";
                dev->init_data.get_key = get_key_beholdm6xx;
                dev->init_data.ir_codes = RC_MAP_BEHOLD;
-               dev->init_data.type = RC_TYPE_NEC;
+               dev->init_data.type = RC_BIT_NEC;
                info.addr = 0x2d;
                break;
        case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
 
 
        rdev->priv = ati_remote;
        rdev->driver_type = RC_DRIVER_SCANCODE;
-       rdev->allowed_protos = RC_TYPE_OTHER;
+       rdev->allowed_protos = RC_BIT_OTHER;
        rdev->driver_name = "ati_remote";
 
        rdev->open = ati_remote_rc_open;
 
                learning_mode_force = false;
 
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->priv = dev;
        rdev->open = ene_open;
        rdev->close = ene_close;
 
        /* Set up the rc device */
        rdev->priv = fintek;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->open = fintek_open;
        rdev->close = fintek_close;
        rdev->input_name = FINTEK_DESCRIPTION;
 
        if (pdata->allowed_protos)
                rcdev->allowed_protos = pdata->allowed_protos;
        else
-               rcdev->allowed_protos = RC_TYPE_ALL;
+               rcdev->allowed_protos = RC_BIT_ALL;
        rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
 
        gpio_dev->rcdev = rcdev;
 
        usb_to_input_id(ir->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->priv = ir;
        rc->open = iguanair_open;
        rc->close = iguanair_close;
 
  * it is not, so we must acquire it prior to calling send_packet, which
  * requires that the lock is held.
  */
-static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
+static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type)
 {
        int retval;
        struct imon_context *ictx = rc->priv;
        unsigned char ir_proto_packet[] = {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
 
-       if (rc_type && !(rc_type & rc->allowed_protos))
+       if (*rc_type && !(*rc_type & rc->allowed_protos))
                dev_warn(dev, "Looks like you're trying to use an IR protocol "
                         "this device does not support\n");
 
-       switch (rc_type) {
-       case RC_TYPE_RC6:
+       if (*rc_type & RC_BIT_RC6_MCE) {
                dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
                ir_proto_packet[0] = 0x01;
-               break;
-       case RC_TYPE_UNKNOWN:
-       case RC_TYPE_OTHER:
+               *rc_type = RC_BIT_RC6_MCE;
+       } else if (*rc_type & RC_BIT_OTHER) {
                dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
                if (!pad_stabilize)
                        dev_dbg(dev, "PAD stabilize functionality disabled\n");
                /* ir_proto_packet[0] = 0x00; // already the default */
-               rc_type = RC_TYPE_OTHER;
-               break;
-       default:
+               *rc_type = RC_BIT_OTHER;
+       } else {
                dev_warn(dev, "Unsupported IR protocol specified, overriding "
                         "to iMON IR protocol\n");
                if (!pad_stabilize)
                        dev_dbg(dev, "PAD stabilize functionality disabled\n");
                /* ir_proto_packet[0] = 0x00; // already the default */
-               rc_type = RC_TYPE_OTHER;
-               break;
+               *rc_type = RC_BIT_OTHER;
        }
 
        memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
        if (retval)
                goto out;
 
-       ictx->rc_type = rc_type;
+       ictx->rc_type = *rc_type;
        ictx->pad_mouse = false;
 
 out:
                rel_x = buf[2];
                rel_y = buf[3];
 
-               if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
+               if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) {
                        if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
                                dir = stabilize((int)rel_x, (int)rel_y,
                                                timeout, threshold);
                buf[0] = 0x01;
                buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
 
-               if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
+               if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) {
                        dir = stabilize((int)rel_x, (int)rel_y,
                                        timeout, threshold);
                        if (!dir) {
                kc = imon_panel_key_lookup(scancode);
        } else {
                scancode = be32_to_cpu(*((u32 *)buf));
-               if (ictx->rc_type == RC_TYPE_RC6) {
+               if (ictx->rc_type == RC_BIT_RC6_MCE) {
                        ktype = IMON_KEY_IMON;
                        if (buf[0] == 0x80)
                                ktype = IMON_KEY_MCE;
 {
        u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
        u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
-       u64 allowed_protos = RC_TYPE_OTHER;
+       u64 allowed_protos = RC_BIT_OTHER;
 
        switch (ffdc_cfg_byte) {
        /* iMON Knob, no display, iMON IR + vol knob */
        case 0x9e:
                dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
-               allowed_protos = RC_TYPE_RC6;
+               allowed_protos = RC_BIT_RC6_MCE;
                break;
        /* iMON LCD, MCE IR */
        case 0x9f:
                dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
                detected_display_type = IMON_DISPLAY_TYPE_LCD;
-               allowed_protos = RC_TYPE_RC6;
+               allowed_protos = RC_BIT_RC6_MCE;
                break;
        default:
                dev_info(ictx->dev, "Unknown 0xffdc device, "
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
                /* We don't know which one it is, allow user to set the
                 * RC6 one from userspace if OTHER wasn't correct. */
-               allowed_protos |= RC_TYPE_RC6;
+               allowed_protos |= RC_BIT_RC6_MCE;
                break;
        }
 
 
        rdev->priv = ictx;
        rdev->driver_type = RC_DRIVER_SCANCODE;
-       rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */
+       rdev->allowed_protos = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
        rdev->change_protocol = imon_ir_change_protocol;
        rdev->driver_name = MOD_NAME;
 
 
        imon_set_display_type(ictx);
 
-       if (ictx->rc_type == RC_TYPE_RC6)
+       if (ictx->rc_type == RC_BIT_RC6_MCE)
                rdev->map_name = RC_MAP_IMON_MCE;
        else
                rdev->map_name = RC_MAP_IMON_PAD;
 
 {
        struct jvc_dec *data = &dev->raw->jvc;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_JVC))
+       if (!(dev->raw->enabled_protocols & RC_BIT_JVC))
                return 0;
 
        if (!is_timing_event(ev)) {
 }
 
 static struct ir_raw_handler jvc_handler = {
-       .protocols      = RC_TYPE_JVC,
+       .protocols      = RC_BIT_JVC,
        .decode         = ir_jvc_decode,
 };
 
 
        struct lirc_codec *lirc = &dev->raw->lirc;
        int sample;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_LIRC))
+       if (!(dev->raw->enabled_protocols & RC_BIT_LIRC))
                return 0;
 
        if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
 }
 
 static struct ir_raw_handler lirc_handler = {
-       .protocols      = RC_TYPE_LIRC,
+       .protocols      = RC_BIT_LIRC,
        .decode         = ir_lirc_decode,
        .raw_register   = ir_lirc_register,
        .raw_unregister = ir_lirc_unregister,
 
        u32 scancode;
        unsigned long delay;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_MCE_KBD))
+       if (!(dev->raw->enabled_protocols & RC_BIT_MCE_KBD))
                return 0;
 
        if (!is_timing_event(ev)) {
 }
 
 static struct ir_raw_handler mce_kbd_handler = {
-       .protocols      = RC_TYPE_MCE_KBD,
+       .protocols      = RC_BIT_MCE_KBD,
        .decode         = ir_mce_kbd_decode,
        .raw_register   = ir_mce_kbd_register,
        .raw_unregister = ir_mce_kbd_unregister,
 
        u8 address, not_address, command, not_command;
        bool send_32bits = false;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_NEC))
+       if (!(dev->raw->enabled_protocols & RC_BIT_NEC))
                return 0;
 
        if (!is_timing_event(ev)) {
 }
 
 static struct ir_raw_handler nec_handler = {
-       .protocols      = RC_TYPE_NEC,
+       .protocols      = RC_BIT_NEC,
        .decode         = ir_nec_decode,
 };
 
 
        u8 toggle;
        u32 scancode;
 
-        if (!(dev->raw->enabled_protocols & RC_TYPE_RC5))
-                return 0;
+       if (!(dev->raw->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X)))
+               return 0;
 
        if (!is_timing_event(ev)) {
                if (ev.reset)
                if (data->wanted_bits == RC5X_NBITS) {
                        /* RC5X */
                        u8 xdata, command, system;
+                       if (!(dev->raw->enabled_protocols & RC_BIT_RC5X)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        xdata    = (data->bits & 0x0003F) >> 0;
                        command  = (data->bits & 0x00FC0) >> 6;
                        system   = (data->bits & 0x1F000) >> 12;
                } else {
                        /* RC5 */
                        u8 command, system;
+                       if (!(dev->raw->enabled_protocols & RC_BIT_RC5)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        command  = (data->bits & 0x0003F) >> 0;
                        system   = (data->bits & 0x007C0) >> 6;
                        toggle   = (data->bits & 0x00800) ? 1 : 0;
 }
 
 static struct ir_raw_handler rc5_handler = {
-       .protocols      = RC_TYPE_RC5,
+       .protocols      = RC_BIT_RC5 | RC_BIT_RC5X,
        .decode         = ir_rc5_decode,
 };
 
 
        u8 toggle, command, system;
        u32 scancode;
 
-        if (!(dev->raw->enabled_protocols & RC_TYPE_RC5_SZ))
-                return 0;
+       if (!(dev->raw->enabled_protocols & RC_BIT_RC5_SZ))
+               return 0;
 
        if (!is_timing_event(ev)) {
                if (ev.reset)
 }
 
 static struct ir_raw_handler rc5_sz_handler = {
-       .protocols      = RC_TYPE_RC5_SZ,
+       .protocols      = RC_BIT_RC5_SZ,
        .decode         = ir_rc5_sz_decode,
 };
 
 
        u32 scancode;
        u8 toggle;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_RC6))
+       if (!(dev->raw->enabled_protocols &
+             (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 |
+              RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)))
                return 0;
 
        if (!is_timing_event(ev)) {
 }
 
 static struct ir_raw_handler rc6_handler = {
-       .protocols      = RC_TYPE_RC6,
+       .protocols      = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 |
+                         RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 |
+                         RC_BIT_RC6_MCE,
        .decode         = ir_rc6_decode,
 };
 
 
        u32 scancode;
        u8 address, command, not_command;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_SANYO))
+       if (!(dev->raw->enabled_protocols & RC_BIT_SANYO))
                return 0;
 
        if (!is_timing_event(ev)) {
 }
 
 static struct ir_raw_handler sanyo_handler = {
-       .protocols      = RC_TYPE_SANYO,
+       .protocols      = RC_BIT_SANYO,
        .decode         = ir_sanyo_decode,
 };
 
 
        u32 scancode;
        u8 device, subdevice, function;
 
-       if (!(dev->raw->enabled_protocols & RC_TYPE_SONY))
+       if (!(dev->raw->enabled_protocols &
+             (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20)))
                return 0;
 
        if (!is_timing_event(ev)) {
 
                switch (data->count) {
                case 12:
+                       if (!(dev->raw->enabled_protocols & RC_BIT_SONY12)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        device    = bitrev8((data->bits <<  3) & 0xF8);
                        subdevice = 0;
                        function  = bitrev8((data->bits >>  4) & 0xFE);
                        break;
                case 15:
+                       if (!(dev->raw->enabled_protocols & RC_BIT_SONY15)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        device    = bitrev8((data->bits >>  0) & 0xFF);
                        subdevice = 0;
                        function  = bitrev8((data->bits >>  7) & 0xFE);
                        break;
                case 20:
+                       if (!(dev->raw->enabled_protocols & RC_BIT_SONY20)) {
+                               data->state = STATE_INACTIVE;
+                               return 0;
+                       }
                        device    = bitrev8((data->bits >>  5) & 0xF8);
                        subdevice = bitrev8((data->bits >>  0) & 0xFF);
                        function  = bitrev8((data->bits >> 12) & 0xFE);
 }
 
 static struct ir_raw_handler sony_handler = {
-       .protocols      = RC_TYPE_SONY,
+       .protocols      = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20,
        .decode         = ir_sony_decode,
 };
 
 
        /* set up ir-core props */
        rdev->priv = itdev;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->open = ite_open;
        rdev->close = ite_close;
        rdev->s_idle = ite_s_idle;
 
                .scan    = imon_mce,
                .size    = ARRAY_SIZE(imon_mce),
                /* its RC6, but w/a hardware decoder */
-               .rc_type = RC_TYPE_RC6,
+               .rc_type = RC_TYPE_RC6_MCE,
                .name    = RC_MAP_IMON_MCE,
        }
 };
 
        .map = {
                .scan    = rc6_mce,
                .size    = ARRAY_SIZE(rc6_mce),
-               .rc_type = RC_TYPE_RC6,
+               .rc_type = RC_TYPE_RC6_MCE,
                .name    = RC_MAP_RC6_MCE,
        }
 };
 
        rc->dev.parent = dev;
        rc->priv = ir;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->timeout = MS_TO_NS(100);
        if (!ir->flags.no_tx) {
                rc->s_tx_mask = mceusb_set_tx_mask;
 
        /* Set up the rc device */
        rdev->priv = nvt;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->open = nvt_open;
        rdev->close = nvt_close;
        rdev->tx_ir = nvt_tx_ir;
 
        rc->map_name            = RC_MAP_EMPTY;
        rc->priv                = &loopdev;
        rc->driver_type         = RC_DRIVER_IR_RAW;
-       rc->allowed_protos      = RC_TYPE_ALL;
+       rc->allowed_protos      = RC_BIT_ALL;
        rc->timeout             = 100 * 1000 * 1000; /* 100 ms */
        rc->min_timeout         = 1;
        rc->max_timeout         = UINT_MAX;
 
        .devnode        = ir_devnode,
 };
 
+/*
+ * These are the protocol textual descriptions that are
+ * used by the sysfs protocols file. Note that the order
+ * of the entries is relevant.
+ */
 static struct {
        u64     type;
        char    *name;
 } proto_names[] = {
-       { RC_TYPE_UNKNOWN,      "unknown"       },
-       { RC_TYPE_RC5,          "rc-5"          },
-       { RC_TYPE_NEC,          "nec"           },
-       { RC_TYPE_RC6,          "rc-6"          },
-       { RC_TYPE_JVC,          "jvc"           },
-       { RC_TYPE_SONY,         "sony"          },
-       { RC_TYPE_RC5_SZ,       "rc-5-sz"       },
-       { RC_TYPE_SANYO,        "sanyo"         },
-       { RC_TYPE_MCE_KBD,      "mce_kbd"       },
-       { RC_TYPE_LIRC,         "lirc"          },
-       { RC_TYPE_OTHER,        "other"         },
+       { RC_BIT_NONE,          "none"          },
+       { RC_BIT_OTHER,         "other"         },
+       { RC_BIT_UNKNOWN,       "unknown"       },
+       { RC_BIT_RC5 |
+         RC_BIT_RC5X,          "rc-5"          },
+       { RC_BIT_NEC,           "nec"           },
+       { RC_BIT_RC6_0 |
+         RC_BIT_RC6_6A_20 |
+         RC_BIT_RC6_6A_24 |
+         RC_BIT_RC6_6A_32 |
+         RC_BIT_RC6_MCE,       "rc-6"          },
+       { RC_BIT_JVC,           "jvc"           },
+       { RC_BIT_SONY12 |
+         RC_BIT_SONY15 |
+         RC_BIT_SONY20,        "sony"          },
+       { RC_BIT_RC5_SZ,        "rc-5-sz"       },
+       { RC_BIT_SANYO,         "sanyo"         },
+       { RC_BIT_MCE_KBD,       "mce_kbd"       },
+       { RC_BIT_LIRC,          "lirc"          },
 };
 
-#define PROTO_NONE     "none"
-
 /**
  * show_protocols() - shows the current IR protocol(s)
  * @device:    the device descriptor
                        tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
                else if (allowed & proto_names[i].type)
                        tmp += sprintf(tmp, "%s ", proto_names[i].name);
+
+               if (allowed & proto_names[i].type)
+                       allowed &= ~proto_names[i].type;
        }
 
        if (tmp != buf)
                        disable = false;
                }
 
-               if (!enable && !disable && !strncasecmp(tmp, PROTO_NONE, sizeof(PROTO_NONE))) {
-                       tmp += sizeof(PROTO_NONE);
-                       mask = 0;
-                       count++;
-               } else {
-                       for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
-                               if (!strcasecmp(tmp, proto_names[i].name)) {
-                                       tmp += strlen(proto_names[i].name);
-                                       mask = proto_names[i].type;
-                                       break;
-                               }
-                       }
-                       if (i == ARRAY_SIZE(proto_names)) {
-                               IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
-                               ret = -EINVAL;
-                               goto out;
+               for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
+                       if (!strcasecmp(tmp, proto_names[i].name)) {
+                               mask = proto_names[i].type;
+                               break;
                        }
-                       count++;
                }
 
+               if (i == ARRAY_SIZE(proto_names)) {
+                       IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
+                       return -EINVAL;
+               }
+
+               count++;
+
                if (enable)
                        type |= mask;
                else if (disable)
        }
 
        if (dev->change_protocol) {
-               rc = dev->change_protocol(dev, type);
+               rc = dev->change_protocol(dev, &type);
                if (rc < 0) {
                        IR_dprintk(1, "Error setting protocols to 0x%llx\n",
                                   (long long)type);
        }
 
        if (dev->change_protocol) {
-               rc = dev->change_protocol(dev, rc_map->rc_type);
+               u64 rc_type = (1 << rc_map->rc_type);
+               rc = dev->change_protocol(dev, &rc_type);
                if (rc < 0)
                        goto out_raw;
        }
 
        rc->dev.parent = dev;
        rc->priv = rr3;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->timeout = US_TO_NS(2750);
        rc->tx_ir = redrat3_transmit_ir;
        rc->s_tx_carrier = redrat3_set_tx_carrier;
 
        rdev->dev.parent = dev;
        rdev->priv = sz;
        rdev->driver_type = RC_DRIVER_IR_RAW;
-       rdev->allowed_protos = RC_TYPE_ALL;
+       rdev->allowed_protos = RC_BIT_ALL;
        rdev->driver_name = DRIVER_NAME;
        rdev->map_name = RC_MAP_STREAMZAP;
 
 
        usb_to_input_id(tt->udev, &rc->input_id);
        rc->dev.parent = &intf->dev;
        rc->driver_type = RC_DRIVER_IR_RAW;
-       rc->allowed_protos = RC_TYPE_ALL;
+       rc->allowed_protos = RC_BIT_ALL;
        rc->priv = tt;
        rc->driver_name = DRIVER_NAME;
        rc->map_name = RC_MAP_TT_1500;
 
        data->dev->priv = data;
        data->dev->dev.parent = &device->dev;
        data->dev->timeout = MS_TO_NS(100);
-       data->dev->allowed_protos = RC_TYPE_ALL;
+       data->dev->allowed_protos = RC_BIT_ALL;
 
        if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) {
                dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
 
        /* The i2c micro-controller only outputs the cmd part of NEC protocol */
        dev->init_data.rc_dev->scanmask = 0xff;
        dev->init_data.rc_dev->driver_name = "cx231xx";
-       dev->init_data.type = RC_TYPE_NEC;
+       dev->init_data.type = RC_BIT_NEC;
        info.addr = 0x30;
 
        /* Load and bind ir-kbd-i2c */
 
        if (!rc->map_name)
                rc->map_name = RC_MAP_EMPTY;
 
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = af9015_rc_query;
        rc->interval = 500;
 
 
                switch (tmp) {
                case 0: /* NEC */
                default:
-                       rc->allowed_protos = RC_TYPE_NEC;
+                       rc->allowed_protos = RC_BIT_NEC;
                        break;
                case 1: /* RC6 */
-                       rc->allowed_protos = RC_TYPE_RC6;
+                       rc->allowed_protos = RC_BIT_RC6_MCE;
                        break;
                }
 
 
 
 static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
 {
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query          = anysee_rc_query;
        rc->interval       = 250;  /* windows driver uses 500ms */
 
 
 {
        pr_debug("Getting az6007 Remote Control properties\n");
 
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query          = az6007_rc_query;
        rc->interval       = 400;
 
 
 struct dvb_usb_rc {
        const char *map_name;
        u64 allowed_protos;
-       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
        int (*query) (struct dvb_usb_device *d);
        unsigned int interval;
        const enum rc_driver_type driver_type;
 
                return 0;
        }
 
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = it913x_rc_query;
        rc->interval = 250;
 
 
 static int lme2510_get_rc_config(struct dvb_usb_device *d,
        struct dvb_usb_rc *rc)
 {
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        return 0;
 }
 
 
                struct dvb_usb_rc *rc)
 {
        rc->map_name = RC_MAP_EMPTY;
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = rtl2831u_rc_query;
        rc->interval = 400;
 
                struct dvb_usb_rc *rc)
 {
        rc->map_name = RC_MAP_EMPTY;
-       rc->allowed_protos = RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_NEC;
        rc->query = rtl2832u_rc_query;
        rc->interval = 400;
 
 
 extern struct i2c_algorithm dib0700_i2c_algo;
 extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
                        struct dvb_usb_device_description **desc, int *cold);
-extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
+extern int dib0700_change_protocol(struct rc_dev *dev, u64 *rc_type);
 extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
 
 extern int dib0700_device_count;
 
        return ret;
 }
 
-int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
+int dib0700_change_protocol(struct rc_dev *rc, u64 *rc_type)
 {
        struct dvb_usb_device *d = rc->priv;
        struct dib0700_state *st = d->priv;
        st->buf[2] = 0;
 
        /* Set the IR mode */
-       if (rc_type == RC_TYPE_RC5)
+       if (*rc_type & RC_BIT_RC5) {
                new_proto = 1;
-       else if (rc_type == RC_TYPE_NEC)
+               *rc_type = RC_BIT_RC5;
+       } else if (*rc_type & RC_BIT_NEC) {
                new_proto = 0;
-       else if (rc_type == RC_TYPE_RC6) {
+               *rc_type = RC_BIT_NEC;
+       } else if (*rc_type & RC_BIT_RC6_MCE) {
                if (st->fw_version < 0x10200) {
                        ret = -EINVAL;
                        goto out;
                }
-
                new_proto = 2;
+               *rc_type = RC_BIT_RC6_MCE;
        } else {
                ret = -EINVAL;
                goto out;
                goto out;
        }
 
-       d->props.rc.core.protocol = rc_type;
+       d->props.rc.core.protocol = *rc_type;
 
 out:
        mutex_unlock(&d->usb_mutex);
                 purb->actual_length);
 
        switch (d->props.rc.core.protocol) {
-       case RC_TYPE_NEC:
+       case RC_BIT_NEC:
                toggle = 0;
 
                /* NEC protocol sends repeat code as 0 0 0 FF */
 
 
        d->last_event = 0;
        switch (d->props.rc.core.protocol) {
-       case RC_TYPE_NEC:
+       case RC_BIT_NEC:
                /* NEC protocol sends repeat code as 0 0 0 FF */
                if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
                    (key[3] == 0xff))
                        .rc_interval      = DEFAULT_RC_INTERVAL,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_interval      = DEFAULT_RC_INTERVAL,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_interval      = DEFAULT_RC_INTERVAL,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_NEC_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
                        .rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
                        .module_name      = "dib0700",
                        .rc_query         = dib0700_rc_query_old_firmware,
-                       .allowed_protos   = RC_TYPE_RC5 |
-                                           RC_TYPE_RC6 |
-                                           RC_TYPE_NEC,
+                       .allowed_protos   = RC_BIT_RC5 |
+                                           RC_BIT_RC6_MCE |
+                                           RC_BIT_NEC,
                        .change_protocol  = dib0700_change_protocol,
                },
        },
 
        u64 protocol;
        u64 allowed_protos;
        enum rc_driver_type driver_type;
-       int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
        char *module_name;
        int (*rc_query) (struct dvb_usb_device *d);
        int rc_interval;
 
 
        .rc.core = {
                .rc_codes       = RC_MAP_DIB0700_RC5_TABLE,
-               .allowed_protos = RC_TYPE_UNKNOWN,
+               .allowed_protos = RC_BIT_UNKNOWN,
                .rc_query       = pctv452e_rc_query,
                .rc_interval    = 100,
        },
 
        .rc.core = {
                .rc_codes       = RC_MAP_TT_1500,
-               .allowed_protos = RC_TYPE_UNKNOWN,
+               .allowed_protos = RC_BIT_UNKNOWN,
                .rc_query       = pctv452e_rc_query,
                .rc_interval    = 100,
        },
 
                .rc_codes    = RC_MAP_TECHNISAT_USB2,
                .module_name = "technisat-usb2",
                .rc_query    = technisat_usb2_rc_query,
-               .allowed_protos = RC_TYPE_ALL,
+               .allowed_protos = RC_BIT_ALL,
                .driver_type    = RC_DRIVER_IR_RAW,
        }
 };
 
                .rc_interval      = 150, /* Less than IR_KEYPRESS_TIMEOUT */
                .rc_codes         = RC_MAP_TT_1500,
                .rc_query         = tt3650_rc_query,
-               .allowed_protos   = RC_TYPE_UNKNOWN,
+               .allowed_protos   = RC_BIT_UNKNOWN,
        },
 
        .num_adapters = 1,
 
        cancel_delayed_work_sync(&ir->work);
 }
 
-static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
+static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type)
 {
        int rc = 0;
        struct em28xx_IR *ir = rc_dev->priv;
 
        /* Adjust xclk based o IR table for RC5/NEC tables */
 
-       if (rc_type == RC_TYPE_RC5) {
+       if (*rc_type & RC_BIT_RC5) {
                dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE;
                ir->full_code = 1;
-       } else if (rc_type == RC_TYPE_NEC) {
+               *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->full_code = 1;
-       } else if (rc_type != RC_TYPE_UNKNOWN)
+               *rc_type = RC_BIT_NEC;
+       } else if (*rc_type != RC_BIT_UNKNOWN)
                rc = -EINVAL;
 
        em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk,
        struct em28xx_IR *ir;
        struct rc_dev *rc;
        int err = -ENOMEM;
+       u64 rc_type;
 
        if (dev->board.ir_codes == NULL) {
                /* No remote control support */
         * em2874 supports more protocols. For now, let's just announce
         * the two protocols that were already tested
         */
-       rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
        rc->priv = ir;
        rc->change_protocol = em28xx_ir_change_protocol;
        rc->open = em28xx_ir_start;
        rc->close = em28xx_ir_stop;
 
        /* By default, keep protocol field untouched */
-       err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
+       rc_type = RC_BIT_UNKNOWN;
+       err = em28xx_ir_change_protocol(rc, &rc_type);
        if (err)
                goto err_out_free;
 
 
        /* Our default information for ir-kbd-i2c.c to use */
        init_data->ir_codes = RC_MAP_HAUPPAUGE;
        init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-       init_data->type = RC_TYPE_RC5;
+       init_data->type = RC_BIT_RC5;
        init_data->name = "HD-PVR";
        init_data->polling_interval = 405; /* ms, duplicated from Windows */
        hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
 
        case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */
                init_data->ir_codes              = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
-               init_data->type                  = RC_TYPE_RC5;
+               init_data->type                  = RC_BIT_RC5;
                init_data->name                  = hdw->hdw_desc->description;
                init_data->polling_interval      = 100; /* ms From ir-kbd-i2c */
                /* IR Receiver */
        case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */
                init_data->ir_codes              = RC_MAP_HAUPPAUGE;
                init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
-               init_data->type                  = RC_TYPE_RC5;
+               init_data->type                  = RC_BIT_RC5;
                init_data->name                  = hdw->hdw_desc->description;
                /* IR Receiver */
                info.addr          = 0x71;
 
         */
 
        switch (ir->rc_type) {
-       case RC_TYPE_NEC:
+       case RC_BIT_NEC:
                leader = 900;   /* ms */
                pulse  = 700;   /* ms - the actual value would be 562 */
                break;
        default:
-       case RC_TYPE_RC5:
+       case RC_BIT_RC5:
                leader = 900;   /* ms - from the NEC decoding */
                pulse  = 1780;  /* ms - The actual value would be 1776 */
                break;
 
        pulse = ir_clock_mhz * pulse;
        leader = ir_clock_mhz * leader;
-       if (ir->rc_type == RC_TYPE_NEC)
+       if (ir->rc_type == RC_BIT_NEC)
                leader = leader | 0x8000;
 
        dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n",
                __func__,
-               (ir->rc_type == RC_TYPE_NEC) ? "NEC" : "RC-5",
+               (ir->rc_type == RC_BIT_NEC) ? "NEC" : "RC-5",
                ir_clock_mhz, leader, pulse);
 
        /* Remote WAKEUP = enable, normal mode, from IR decoder output */
        cancel_delayed_work_sync(&ir->work);
 }
 
-static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
+static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_type)
 {
        struct tm6000_IR *ir = rc->priv;
 
 
        dprintk(2, "%s\n",__func__);
 
-       if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
+       if ((rc->rc_map.scan) && (*rc_type == RC_BIT_NEC))
                ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);
 
-       ir->rc_type = rc_type;
+       ir->rc_type = *rc_type;
 
        tm6000_ir_config(ir);
        /* TODO */
        struct tm6000_IR *ir;
        struct rc_dev *rc;
        int err = -ENOMEM;
+       u64 rc_type;
 
        if (!enable_ir)
                return -ENODEV;
        ir->rc = rc;
 
        /* input setup */
-       rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+       rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC;
        /* Neded, in order to support NEC remotes with 24 or 32 bits */
        rc->scanmask = 0xffff;
        rc->priv = ir;
        usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
        strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-       tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN);
+       rc_type = RC_BIT_UNKNOWN;
+       tm6000_ir_change_protocol(rc, &rc_type);
 
        rc->input_name = ir->name;
        rc->input_phys = ir->phys;
 
 struct IR_i2c_init_data {
        char                    *ir_codes;
        const char              *name;
-       u64                     type; /* RC_TYPE_RC5, etc */
+       u64                     type; /* RC_BIT_RC5, etc */
        u32                     polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */
 
        /*
 
  * @input_dev: the input child device used to communicate events to userspace
  * @driver_type: specifies if protocol decoding is done in hardware or software
  * @idle: used to keep track of RX state
- * @allowed_protos: bitmask with the supported RC_TYPE_* protocols
+ * @allowed_protos: bitmask with the supported RC_BIT_* protocols
  * @scanmask: some hardware decoders are not capable of providing the full
  *     scancode to the application. As this is a hardware limit, we can't do
  *     anything with it. Yet, as the same keycode table can be used with other
        u32                             max_timeout;
        u32                             rx_resolution;
        u32                             tx_resolution;
-       int                             (*change_protocol)(struct rc_dev *dev, u64 rc_type);
+       int                             (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
        int                             (*open)(struct rc_dev *dev);
        void                            (*close)(struct rc_dev *dev);
        int                             (*s_tx_mask)(struct rc_dev *dev, u32 mask);
 
 
 #include <linux/input.h>
 
-#define RC_TYPE_UNKNOWN        0
-#define RC_TYPE_RC5    (1  << 0)       /* Philips RC5 protocol */
-#define RC_TYPE_NEC    (1  << 1)
-#define RC_TYPE_RC6    (1  << 2)       /* Philips RC6 protocol */
-#define RC_TYPE_JVC    (1  << 3)       /* JVC protocol */
-#define RC_TYPE_SONY   (1  << 4)       /* Sony12/15/20 protocol */
-#define RC_TYPE_RC5_SZ (1  << 5)       /* RC5 variant used by Streamzap */
-#define RC_TYPE_SANYO   (1  << 6)      /* Sanyo protocol */
-#define RC_TYPE_MCE_KBD        (1  << 29)      /* RC6-ish MCE keyboard/mouse */
-#define RC_TYPE_LIRC   (1  << 30)      /* Pass raw IR to lirc userspace */
-#define RC_TYPE_OTHER  (1u << 31)
+enum rc_type {
+       RC_TYPE_UNKNOWN         = 0,    /* Protocol not known */
+       RC_TYPE_OTHER           = 1,    /* Protocol known but proprietary */
+       RC_TYPE_LIRC            = 2,    /* Pass raw IR to lirc userspace */
+       RC_TYPE_RC5             = 3,    /* Philips RC5 protocol */
+       RC_TYPE_RC5X            = 4,    /* Philips RC5x protocol */
+       RC_TYPE_RC5_SZ          = 5,    /* StreamZap variant of RC5 */
+       RC_TYPE_JVC             = 6,    /* JVC protocol */
+       RC_TYPE_SONY12          = 7,    /* Sony 12 bit protocol */
+       RC_TYPE_SONY15          = 8,    /* Sony 15 bit protocol */
+       RC_TYPE_SONY20          = 9,    /* Sony 20 bit protocol */
+       RC_TYPE_NEC             = 10,   /* NEC protocol */
+       RC_TYPE_SANYO           = 11,   /* Sanyo protocol */
+       RC_TYPE_MCE_KBD         = 12,   /* RC6-ish MCE keyboard/mouse */
+       RC_TYPE_RC6_0           = 13,   /* Philips RC6-0-16 protocol */
+       RC_TYPE_RC6_6A_20       = 14,   /* Philips RC6-6A-20 protocol */
+       RC_TYPE_RC6_6A_24       = 15,   /* Philips RC6-6A-24 protocol */
+       RC_TYPE_RC6_6A_32       = 16,   /* Philips RC6-6A-32 protocol */
+       RC_TYPE_RC6_MCE         = 17,   /* MCE (Philips RC6-6A-32 subtype) protocol */
+};
+
+#define RC_BIT_NONE            0
+#define RC_BIT_UNKNOWN         (1 << RC_TYPE_UNKNOWN)
+#define RC_BIT_OTHER           (1 << RC_TYPE_OTHER)
+#define RC_BIT_LIRC            (1 << RC_TYPE_LIRC)
+#define RC_BIT_RC5             (1 << RC_TYPE_RC5)
+#define RC_BIT_RC5X            (1 << RC_TYPE_RC5X)
+#define RC_BIT_RC5_SZ          (1 << RC_TYPE_RC5_SZ)
+#define RC_BIT_JVC             (1 << RC_TYPE_JVC)
+#define RC_BIT_SONY12          (1 << RC_TYPE_SONY12)
+#define RC_BIT_SONY15          (1 << RC_TYPE_SONY15)
+#define RC_BIT_SONY20          (1 << RC_TYPE_SONY20)
+#define RC_BIT_NEC             (1 << RC_TYPE_NEC)
+#define RC_BIT_SANYO           (1 << RC_TYPE_SANYO)
+#define RC_BIT_MCE_KBD         (1 << RC_TYPE_MCE_KBD)
+#define RC_BIT_RC6_0           (1 << RC_TYPE_RC6_0)
+#define RC_BIT_RC6_6A_20       (1 << RC_TYPE_RC6_6A_20)
+#define RC_BIT_RC6_6A_24       (1 << RC_TYPE_RC6_6A_24)
+#define RC_BIT_RC6_6A_32       (1 << RC_TYPE_RC6_6A_32)
+#define RC_BIT_RC6_MCE         (1 << RC_TYPE_RC6_MCE)
 
-#define RC_TYPE_ALL (RC_TYPE_RC5    | RC_TYPE_NEC   | RC_TYPE_RC6     | \
-                    RC_TYPE_JVC    | RC_TYPE_SONY  | RC_TYPE_LIRC    | \
-                    RC_TYPE_RC5_SZ | RC_TYPE_SANYO | RC_TYPE_MCE_KBD | \
-                    RC_TYPE_OTHER)
+#define RC_BIT_ALL     (RC_BIT_UNKNOWN | RC_BIT_OTHER | RC_BIT_LIRC | \
+                        RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \
+                        RC_BIT_JVC | \
+                        RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \
+                        RC_BIT_NEC | RC_BIT_SANYO | RC_BIT_MCE_KBD | \
+                        RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \
+                        RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)
 
 struct rc_map_table {
        u32     scancode;
        unsigned int            size;   /* Max number of entries */
        unsigned int            len;    /* Used number of entries */
        unsigned int            alloc;  /* Size of *scan in bytes */
-       u64                     rc_type;
+       enum rc_type            rc_type;
        const char              *name;
        spinlock_t              lock;
 };