diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index d4be1fd20a36262d4a523c6b38f1b0a246f89978..accbc32725cf9d9fdd190c0ff5590e83d8d97291 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -539,11 +539,38 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
 		    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) {
@@ -553,13 +580,16 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
 			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 -- "
@@ -640,10 +670,14 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
 		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);
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 7175abbd2f8c58ff32aa7e2c46fe79c57a79135e..82d28cbf289f1a1fe1bb5e22168ee32d8de2e001 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -56,23 +56,23 @@ static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
 	[   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,
@@ -543,12 +543,22 @@ static int build_key(struct saa7134_dev *dev)
 	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;
 }