card_has_mpeg(dev))
                        saa7134_irq_ts_done(dev,status);
 
-               if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
-                              SAA7134_IRQ_REPORT_GPIO18)) &&
-                   dev->remote)
-                       saa7134_input_irq(dev);
+               if (report & SAA7134_IRQ_REPORT_GPIO16) {
+                       switch (dev->has_remote) {
+                               case SAA7134_REMOTE_GPIO:
+                                       if  (dev->remote->mask_keydown & 0x10000) {
+                                               saa7134_input_irq(dev);
+                                       }
+                                       break;
+
+                               case SAA7134_REMOTE_I2C:
+                                       break;                  /* FIXME: invoke I2C get_key() */
+
+                               default:                        /* GPIO16 not used by IR remote */
+                                       break;
+                       }
+               }
 
+               if (report & SAA7134_IRQ_REPORT_GPIO18) {
+                       switch (dev->has_remote) {
+                               case SAA7134_REMOTE_GPIO:
+                                       if ((dev->remote->mask_keydown & 0x40000) ||
+                                           (dev->remote->mask_keyup & 0x40000)) {
+                                               saa7134_input_irq(dev);
+                                       }
+                                       break;
+
+                               case SAA7134_REMOTE_I2C:
+                                       break;                  /* FIXME: invoke I2C get_key() */
+
+                               default:                        /* GPIO18 not used by IR remote */
+                                       break;
+                       }
+               }
        }
 
        if (10 == loop) {
                        printk(KERN_WARNING "%s/irq: looping -- "
                               "clearing PE (parity error!) enable bit\n",dev->name);
                        saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
-               } else if (report & (SAA7134_IRQ_REPORT_GPIO16 |
-                                    SAA7134_IRQ_REPORT_GPIO18)) {
-                       /* disable gpio IRQs */
+               } else if (report & SAA7134_IRQ_REPORT_GPIO16) {
+                       /* disable gpio16 IRQ */
                        printk(KERN_WARNING "%s/irq: looping -- "
-                              "clearing GPIO enable bits\n",dev->name);
-                       saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |
-                                                 SAA7134_IRQ2_INTE_GPIO18));
+                              "clearing GPIO16 enable bit\n",dev->name);
+                       saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16);
+               } else if (report & SAA7134_IRQ_REPORT_GPIO18) {
+                       /* disable gpio18 IRQs */
+                       printk(KERN_WARNING "%s/irq: looping -- "
+                              "clearing GPIO18 enable bit\n",dev->name);
+                       saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18);
                } else {
                        /* disable all irqs */
                        printk(KERN_WARNING "%s/irq: looping -- "
                SAA7134_IRQ2_INTE_PE      |
                SAA7134_IRQ2_INTE_AR;
 
-       if (dev->has_remote == SAA7134_REMOTE_GPIO)
-               irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18  |
-                             SAA7134_IRQ2_INTE_GPIO18A |
-                             SAA7134_IRQ2_INTE_GPIO16  );
+       if (dev->has_remote == SAA7134_REMOTE_GPIO) {
+               if (dev->remote->mask_keydown & 0x10000)
+                       irq2_mask |= SAA7134_IRQ2_INTE_GPIO16;
+               else if (dev->remote->mask_keydown & 0x40000)
+                       irq2_mask |= SAA7134_IRQ2_INTE_GPIO18;
+               else if (dev->remote->mask_keyup & 0x40000)
+                       irq2_mask |= SAA7134_IRQ2_INTE_GPIO18A;
+       }
 
        saa_writel(SAA7134_IRQ1, 0);
        saa_writel(SAA7134_IRQ2, irq2_mask);
 
        [   12 ] = KEY_KP8,
        [   13 ] = KEY_KP9,
 
-       [   14 ] = KEY_TUNER,        // Air/Cable
+       [   14 ] = KEY_MODE,         // Air/Cable
        [   17 ] = KEY_VIDEO,        // Video
        [   21 ] = KEY_AUDIO,        // Audio
-       [    0 ] = KEY_POWER,        // Pover
+       [    0 ] = KEY_POWER,        // Power
+       [   24 ] = KEY_TUNER,        // AV Source
        [    2 ] = KEY_ZOOM,         // Fullscreen
+       [   26 ] = KEY_LANGUAGE,     // Stereo
        [   27 ] = KEY_MUTE,         // Mute
-       [   20 ] = KEY_VOLUMEUP,
-       [   23 ] = KEY_VOLUMEDOWN,
+       [   20 ] = KEY_VOLUMEUP,     // Volume +
+       [   23 ] = KEY_VOLUMEDOWN,   // Volume -
        [   18 ] = KEY_CHANNELUP,    // Channel +
        [   19 ] = KEY_CHANNELDOWN,  // Channel -
-       [    6 ] = KEY_AGAIN,        // Recal
-       [   16 ] = KEY_KPENTER,      // Enter
-
-       [   26 ] = KEY_F22,          // Stereo
-       [   24 ] = KEY_EDIT,         // AV Source
+       [    6 ] = KEY_AGAIN,        // Recall
+       [   16 ] = KEY_ENTER,      // Enter
 };
 
+
 static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
        [    0 ] = KEY_KP0,
        [    1 ] = KEY_KP1,
        dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
                gpio, ir->mask_keycode, data);
 
-       if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
-           (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-               ir_input_keydown(ir->dev, &ir->ir, data, data);
-       } else {
-               ir_input_nokey(ir->dev, &ir->ir);
+       if (ir->polling) {
+               if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
+                   (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
+                       ir_input_keydown(ir->dev, &ir->ir, data, data);
+               } else {
+                       ir_input_nokey(ir->dev, &ir->ir);
+               }
+       }
+       else {  /* IRQ driven mode - handle key press and release in one go */
+               if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
+                   (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
+                       ir_input_keydown(ir->dev, &ir->ir, data, data);
+                       ir_input_nokey(ir->dev, &ir->ir);
+               }
        }
+
        return 0;
 }