--- v4l-dvb.orig/linux/drivers/media/video/bt8xx/bttv-i2c.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/bt8xx/bttv-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -405,6 +405,27 @@ int __devinit init_bttv_i2c(struct bttv
 	}
 	if (0 == btv->i2c_rc && i2c_scan)
 		do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
+
+	/* Instantiate the IR receiver device, if present */
+	if (0 == btv->i2c_rc) {
+		struct i2c_board_info info;
+		/* The external IR receiver is at i2c address 0x34 (0x35 for
+		   reads).  Future Hauppauge cards will have an internal
+		   receiver at 0x30 (0x31 for reads).  In theory, both can be
+		   fitted, and Hauppauge suggest an external overrides an
+		   internal.
+
+		   That's why we probe 0x1a (~0x34) first. CB
+		*/
+		const unsigned short addr_list[] = {
+			0x1a, 0x18, 0x4b, 0x64, 0x30,
+			I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
+	}
 	return btv->i2c_rc;
 }
 
--- v4l-dvb.orig/linux/drivers/media/video/cx231xx/cx231xx-cards.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx231xx/cx231xx-cards.c	2009-05-12 11:24:19.000000000 +0200
@@ -282,13 +282,16 @@ static void cx231xx_config_tuner(struct
 }
 
 /* ----------------------------------------------------------------------- */
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+void cx231xx_register_i2c_ir(struct cx231xx *dev)
 {
-	if (disable_ir) {
-		ir->get_key = NULL;
+	if (disable_ir)
 		return;
-	}
 
+	/* REVISIT: instantiate IR device */
+}
+
+void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+{
 	/* detect & configure */
 	switch (dev->model) {
 
--- v4l-dvb.orig/linux/drivers/media/video/cx231xx/cx231xx-i2c.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx231xx/cx231xx-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -540,6 +540,9 @@ int cx231xx_i2c_register(struct cx231xx_
 	if (0 == bus->i2c_rc) {
 		if (i2c_scan)
 			cx231xx_do_i2c_scan(dev, &bus->i2c_client);
+
+		/* Instantiate the IR receiver device, if present */
+		cx231xx_register_i2c_ir(dev);
 	} else
 		cx231xx_warn("%s: i2c bus %d register FAILED\n",
 			     dev->name, bus->nr);
--- v4l-dvb.orig/linux/drivers/media/video/cx231xx/cx231xx.h	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx231xx/cx231xx.h	2009-05-12 11:24:19.000000000 +0200
@@ -747,6 +747,7 @@ extern void cx231xx_card_setup(struct cx
 extern struct cx231xx_board cx231xx_boards[];
 extern struct usb_device_id cx231xx_id_table[];
 extern const unsigned int cx231xx_bcount;
+void cx231xx_register_i2c_ir(struct cx231xx *dev);
 void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir);
 int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
 
--- v4l-dvb.orig/linux/drivers/media/video/cx23885/cx23885-i2c.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx23885/cx23885-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -364,6 +364,18 @@ int cx23885_i2c_register(struct cx23885_
 		printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
 			dev->name, bus->nr);
 
+	/* Instantiate the IR receiver device, if present */
+	if (0 == bus->i2c_rc) {
+		struct i2c_board_info info;
+		const unsigned short addr_list[] = {
+			0x6b, I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
+	}
+
 	return bus->i2c_rc;
 }
 
--- v4l-dvb.orig/linux/drivers/media/video/cx88/cx88-i2c.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx88/cx88-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -186,6 +186,19 @@ int cx88_i2c_init(struct cx88_core *core
 			do_i2c_scan(core->name,&core->i2c_client);
 	} else
 		printk("%s: i2c register FAILED\n", core->name);
+
+	/* Instantiate the IR receiver device, if present */
+	if (0 == core->i2c_rc) {
+		struct i2c_board_info info;
+		const unsigned short addr_list[] = {
+			0x18, 0x6b, 0x71,
+			I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
+	}
 	return core->i2c_rc;
 }
 
--- v4l-dvb.orig/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-05-12 11:14:20.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-05-12 11:24:19.000000000 +0200
@@ -1931,13 +1931,23 @@ static int em28xx_hint_board(struct em28
 }
 
 /* ----------------------------------------------------------------------- */
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
+void em28xx_register_i2c_ir(struct em28xx *dev)
 {
-	if (disable_ir) {
-		ir->get_key = NULL;
-		return ;
-	}
+	struct i2c_board_info info;
+	const unsigned short addr_list[] = {
+		 0x30, 0x47, I2C_CLIENT_END
+	};
+
+	if (disable_ir)
+		return;
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+}
 
+void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
+{
 	/* detect & configure */
 	switch (dev->model) {
 	case (EM2800_BOARD_UNKNOWN):
--- v4l-dvb.orig/linux/drivers/media/video/em28xx/em28xx-i2c.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -581,6 +581,9 @@ int em28xx_i2c_register(struct em28xx *d
 	if (i2c_scan)
 		em28xx_do_i2c_scan(dev);
 
+	/* Instantiate the IR receiver device, if present */
+	em28xx_register_i2c_ir(dev);
+
 	return 0;
 }
 
--- v4l-dvb.orig/linux/drivers/media/video/em28xx/em28xx-input.c	2009-05-12 11:14:20.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx-input.c	2009-05-12 11:24:19.000000000 +0200
@@ -86,7 +86,7 @@ int em28xx_get_key_terratec(struct IR_i2
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -115,7 +115,7 @@ int em28xx_get_key_em_haup(struct IR_i2c
 	unsigned char code;
 
 	/* poll IR chip */
-	if (2 != i2c_master_recv(&ir->c, buf, 2))
+	if (2 != i2c_master_recv(ir->c, buf, 2))
 		return -EIO;
 
 	/* Does eliminate repeated parity code */
@@ -153,7 +153,7 @@ int em28xx_get_key_pinnacle_usb_grey(str
 
 	/* poll IR chip */
 
-	if (3 != i2c_master_recv(&ir->c, buf, 3)) {
+	if (3 != i2c_master_recv(ir->c, buf, 3)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
--- v4l-dvb.orig/linux/drivers/media/video/em28xx/em28xx.h	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx.h	2009-05-12 11:24:19.000000000 +0200
@@ -649,6 +649,7 @@ extern void em28xx_card_setup(struct em2
 extern struct em28xx_board em28xx_boards[];
 extern struct usb_device_id em28xx_id_table[];
 extern const unsigned int em28xx_bcount;
+void em28xx_register_i2c_ir(struct em28xx *dev);
 void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir);
 int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
 void em28xx_release_resources(struct em28xx *dev);
--- v4l-dvb.orig/linux/drivers/media/video/ir-kbd-i2c.c	2009-05-12 11:14:20.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -75,7 +75,7 @@ static int get_key_haup_common(struct IR
 	int start, range, toggle, dev, code, ircode;
 
 	/* poll IR chip */
-	if (size != i2c_master_recv(&ir->c,buf,size))
+	if (size != i2c_master_recv(ir->c, buf, size))
 		return -EIO;
 
 	/* split rc5 data block ... */
@@ -138,7 +138,7 @@ static int get_key_pixelview(struct IR_i
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -152,7 +152,7 @@ static int get_key_pv951(struct IR_i2c *
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -172,7 +172,7 @@ static int get_key_fusionhdtv(struct IR_
 	unsigned char buf[4];
 
 	/* poll IR chip */
-	if (4 != i2c_master_recv(&ir->c,buf,4)) {
+	if (4 != i2c_master_recv(ir->c, buf, 4)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -196,7 +196,7 @@ static int get_key_knc1(struct IR_i2c *i
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		dprintk(1,"read error\n");
 		return -EIO;
 	}
@@ -223,12 +223,12 @@ static int get_key_avermedia_cardbus(str
 				     u32 *ir_key, u32 *ir_raw)
 {
 	unsigned char subaddr, key, keygroup;
-	struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+	struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
 				   .buf = &subaddr, .len = 1},
-				 { .addr = ir->c.addr, .flags = I2C_M_RD,
+				 { .addr = ir->c->addr, .flags = I2C_M_RD,
 				  .buf = &key, .len = 1} };
 	subaddr = 0x0d;
-	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
 		dprintk(1, "read error\n");
 		return -EIO;
 	}
@@ -238,7 +238,7 @@ static int get_key_avermedia_cardbus(str
 
 	subaddr = 0x0b;
 	msg[1].buf = &keygroup;
-	if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
 		dprintk(1, "read error\n");
 		return -EIO;
 	}
@@ -295,7 +295,7 @@ static void ir_work(struct work_struct *
 
 	/* MSI TV@nywhere Plus requires more frequent polling
 	   otherwise it will miss some keypresses */
-	if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30)
+	if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30)
 		polling_interval = 50;
 
 	ir_key_poll(ir);
@@ -304,34 +304,15 @@ static void ir_work(struct work_struct *
 
 /* ----------------------------------------------------------------------- */
 
-static int ir_attach(struct i2c_adapter *adap, int addr,
-		      unsigned short flags, int kind);
-static int ir_detach(struct i2c_client *client);
-static int ir_probe(struct i2c_adapter *adap);
-
-static struct i2c_driver driver = {
-	.driver = {
-		.name   = "ir-kbd-i2c",
-	},
-	.id             = I2C_DRIVERID_INFRARED,
-	.attach_adapter = ir_probe,
-	.detach_client  = ir_detach,
-};
-
-static struct i2c_client client_template =
-{
-	.name = "unset",
-	.driver = &driver
-};
-
-static int ir_attach(struct i2c_adapter *adap, int addr,
-		     unsigned short flags, int kind)
+static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	char *name;
 	int ir_type;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
+	struct i2c_adapter *adap = client->adapter;
+	unsigned short addr = client->addr;
 	int err;
 
 	ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
@@ -341,14 +322,9 @@ static int ir_attach(struct i2c_adapter
 		goto err_out_free;
 	}
 
-	ir->c = client_template;
+	ir->c = client;
 	ir->input = input_dev;
-
-	ir->c.adapter = adap;
-	ir->c.addr    = addr;
-	snprintf(ir->c.name, sizeof(ir->c.name), "ir-kbd");
-
-	i2c_set_clientdata(&ir->c, ir);
+	i2c_set_clientdata(client, ir);
 
 	switch(addr) {
 	case 0x64:
@@ -423,24 +399,9 @@ static int ir_attach(struct i2c_adapter
 	snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
 	ir->ir_codes = ir_codes;
 
-	/* register i2c device
-	 * At device register, IR codes may be changed to be
-	 * board dependent.
-	 */
-	err = i2c_attach_client(&ir->c);
-	if (err)
-		goto err_out_free;
-
-	/* If IR not supported or disabled, unregisters driver */
-	if (ir->get_key == NULL) {
-		err = -ENODEV;
-		goto err_out_detach;
-	}
-
-	/* Phys addr can only be set after attaching (for ir->c.dev) */
 	snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
-		 dev_name(&ir->c.adapter->dev),
-		 dev_name(&ir->c.dev));
+		 dev_name(&adap->dev),
+		 dev_name(&client->dev));
 
 	/* init + register input device */
 	ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
@@ -450,7 +411,7 @@ static int ir_attach(struct i2c_adapter
 
 	err = input_register_device(ir->input);
 	if (err)
-		goto err_out_detach;
+		goto err_out_free;
 
 	printk(DEVNAME ": %s detected at %s [%s]\n",
 	       ir->input->name, ir->input->phys, adap->name);
@@ -465,135 +426,42 @@ static int ir_attach(struct i2c_adapter
 
 	return 0;
 
- err_out_detach:
-	i2c_detach_client(&ir->c);
  err_out_free:
 	input_free_device(input_dev);
 	kfree(ir);
 	return err;
 }
 
-static int ir_detach(struct i2c_client *client)
+static int ir_remove(struct i2c_client *client)
 {
 	struct IR_i2c *ir = i2c_get_clientdata(client);
 
 	/* kill outstanding polls */
 	cancel_delayed_work_sync(&ir->work);
 
-	/* unregister devices */
+	/* unregister device */
 	input_unregister_device(ir->input);
-	i2c_detach_client(&ir->c);
 
 	/* free memory */
 	kfree(ir);
 	return 0;
 }
 
-static int ir_probe(struct i2c_adapter *adap)
-{
-
-	/* The external IR receiver is at i2c address 0x34 (0x35 for
-	   reads).  Future Hauppauge cards will have an internal
-	   receiver at 0x30 (0x31 for reads).  In theory, both can be
-	   fitted, and Hauppauge suggest an external overrides an
-	   internal.
-
-	   That's why we probe 0x1a (~0x34) first. CB
-	*/
-
-	static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
-	static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 };
-	static const int probe_em28XX[] = { 0x30, 0x47, -1 };
-	static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
-	static const int probe_cx23885[] = { 0x6b, -1 };
-	const int *probe;
-	struct i2c_msg msg = {
-		.flags = I2C_M_RD,
-		.len = 0,
-		.buf = NULL,
-	};
-	int i, rc;
-
-	switch (adap->id) {
-	case I2C_HW_B_BT848:
-		probe = probe_bttv;
-		break;
-	case I2C_HW_B_CX2341X:
-		probe = probe_bttv;
-		break;
-	case I2C_HW_SAA7134:
-		probe = probe_saa7134;
-		break;
-	case I2C_HW_B_EM28XX:
-		probe = probe_em28XX;
-		break;
-	case I2C_HW_B_CX2388x:
-		probe = probe_cx88;
-		break;
-	case I2C_HW_B_CX23885:
-		probe = probe_cx23885;
-		break;
-	default:
-		return 0;
-	}
-
-	for (i = 0; -1 != probe[i]; i++) {
-		msg.addr = probe[i];
-		rc = i2c_transfer(adap, &msg, 1);
-		dprintk(1,"probe 0x%02x @ %s: %s\n",
-			probe[i], adap->name,
-			(1 == rc) ? "yes" : "no");
-		if (1 == rc) {
-			ir_attach(adap, probe[i], 0, 0);
-			return 0;
-		}
-	}
-
-	/* Special case for MSI TV@nywhere Plus remote */
-	if (adap->id == I2C_HW_SAA7134) {
-		u8 temp;
-
-		/* MSI TV@nywhere Plus controller doesn't seem to
-		   respond to probes unless we read something from
-		   an existing device. Weird... */
-
-		msg.addr = 0x50;
-		rc = i2c_transfer(adap, &msg, 1);
-			dprintk(1, "probe 0x%02x @ %s: %s\n",
-			msg.addr, adap->name,
-			(1 == rc) ? "yes" : "no");
-
-		/* Now do the probe. The controller does not respond
-		   to 0-byte reads, so we use a 1-byte read instead. */
-		msg.addr = 0x30;
-		msg.len = 1;
-		msg.buf = &temp;
-		rc = i2c_transfer(adap, &msg, 1);
-		dprintk(1, "probe 0x%02x @ %s: %s\n",
-			msg.addr, adap->name,
-			(1 == rc) ? "yes" : "no");
-		if (1 == rc)
-			ir_attach(adap, msg.addr, 0, 0);
-	}
-
-	/* Special case for AVerMedia Cardbus remote */
-	if (adap->id == I2C_HW_SAA7134) {
-		unsigned char subaddr, data;
-		struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
-					   .buf = &subaddr, .len = 1},
-					 { .addr = 0x40, .flags = I2C_M_RD,
-					   .buf = &data, .len = 1} };
-		subaddr = 0x0d;
-		rc = i2c_transfer(adap, msg, 2);
-		dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
-			msg[0].addr, subaddr, adap->name,
-			(2 == rc) ? "yes" : "no");
-		if (2 == rc)
-			ir_attach(adap, msg[0].addr, 0, 0);
-	}
+static const struct i2c_device_id ir_kbd_id[] = {
+	/* Generic entry for any IR receiver */
+	{ "ir_video", 0 },
+	/* IR device specific entries could be added here */
+	{ }
+};
 
-	return 0;
-}
+static struct i2c_driver driver = {
+	.driver = {
+		.name   = "ir-kbd-i2c",
+	},
+	.probe          = ir_probe,
+	.remove         = ir_remove,
+	.id_table       = ir_kbd_id,
+};
 
 /* ----------------------------------------------------------------------- */
 
--- v4l-dvb.orig/linux/drivers/media/video/ivtv/ivtv-i2c.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/ivtv/ivtv-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -592,9 +592,11 @@ static struct i2c_client ivtv_i2c_client
 	.name = "ivtv internal",
 };
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter + instantiate IR receiver */
 int init_ivtv_i2c(struct ivtv *itv)
 {
+	int retval;
+
 	IVTV_DEBUG_I2C("i2c init\n");
 
 	/* Sanity checks for the I2C hardware arrays. They must be the
@@ -634,9 +636,32 @@ int init_ivtv_i2c(struct ivtv *itv)
 	ivtv_setsda(itv, 1);
 
 	if (itv->options.newi2c > 0)
-		return i2c_add_adapter(&itv->i2c_adap);
+		retval = i2c_add_adapter(&itv->i2c_adap);
 	else
-		return i2c_bit_add_bus(&itv->i2c_adap);
+		retval = i2c_bit_add_bus(&itv->i2c_adap);
+
+	/* Instantiate the IR receiver device, if present */
+	if (retval == 0) {
+		struct i2c_board_info info;
+		/* The external IR receiver is at i2c address 0x34 (0x35 for
+		   reads).  Future Hauppauge cards will have an internal
+		   receiver at 0x30 (0x31 for reads).  In theory, both can be
+		   fitted, and Hauppauge suggest an external overrides an
+		   internal.
+
+		   That's why we probe 0x1a (~0x34) first. CB
+		*/
+		const unsigned short addr_list[] = {
+			0x1a, 0x18, 0x64, 0x30,
+			I2C_CLIENT_END
+		};
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+		i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
+	}
+
+	return retval;
 }
 
 void exit_ivtv_i2c(struct ivtv *itv)
--- v4l-dvb.orig/linux/drivers/media/video/saa7134/saa7134-i2c.c	2009-05-12 10:19:13.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134-i2c.c	2009-05-12 11:24:19.000000000 +0200
@@ -444,6 +444,9 @@ int saa7134_i2c_register(struct saa7134_
 	saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
 	if (i2c_scan)
 		do_i2c_scan(dev->name,&dev->i2c_client);
+
+	/* Instantiate the IR receiver device, if present */
+	saa7134_probe_i2c_ir(dev);
 	return 0;
 }
 
--- v4l-dvb.orig/linux/drivers/media/video/saa7134/saa7134-input.c	2009-05-12 11:14:20.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134-input.c	2009-05-12 11:24:19.000000000 +0200
@@ -134,10 +134,10 @@ static int get_key_msi_tvanywhere_plus(s
 	int gpio;
 
 	/* <dev> is needed to access GPIO. Used by the saa_readl macro. */
-	struct saa7134_dev *dev = ir->c.adapter->algo_data;
+	struct saa7134_dev *dev = ir->c->adapter->algo_data;
 	if (dev == NULL) {
 		dprintk("get_key_msi_tvanywhere_plus: "
-			"gir->c.adapter->algo_data is NULL!\n");
+			"gir->c->adapter->algo_data is NULL!\n");
 		return -EIO;
 	}
 
@@ -156,7 +156,7 @@ static int get_key_msi_tvanywhere_plus(s
 
 	/* GPIO says there is a button press. Get it. */
 
-	if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -179,7 +179,7 @@ static int get_key_purpletv(struct IR_i2
 	unsigned char b;
 
 	/* poll IR chip */
-	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+	if (1 != i2c_master_recv(ir->c, &b, 1)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -202,7 +202,7 @@ static int get_key_hvr1110(struct IR_i2c
 	unsigned char buf[5], cod4, code3, code4;
 
 	/* poll IR chip */
-	if (5 != i2c_master_recv(&ir->c,buf,5))
+	if (5 != i2c_master_recv(ir->c, buf, 5))
 		return -EIO;
 
 	cod4	= buf[4];
@@ -224,7 +224,7 @@ static int get_key_beholdm6xx(struct IR_
 	unsigned char data[12];
 	u32 gpio;
 
-	struct saa7134_dev *dev = ir->c.adapter->algo_data;
+	struct saa7134_dev *dev = ir->c->adapter->algo_data;
 
 	/* rising SAA7134_GPIO_GPRESCAN reads the status */
 	saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
@@ -235,9 +235,9 @@ static int get_key_beholdm6xx(struct IR_
 	if (0x400000 & ~gpio)
 		return 0; /* No button press */
 
-	ir->c.addr = 0x5a >> 1;
+	ir->c->addr = 0x5a >> 1;
 
-	if (12 != i2c_master_recv(&ir->c, data, 12)) {
+	if (12 != i2c_master_recv(ir->c, data, 12)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -267,7 +267,7 @@ static int get_key_pinnacle(struct IR_i2
 	unsigned int start = 0,parity = 0,code = 0;
 
 	/* poll IR chip */
-	if (4 != i2c_master_recv(&ir->c, b, 4)) {
+	if (4 != i2c_master_recv(ir->c, b, 4)) {
 		i2cdprintk("read error\n");
 		return -EIO;
 	}
@@ -686,14 +686,76 @@ void saa7134_input_fini(struct saa7134_d
 	dev->remote = NULL;
 }
 
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 {
+	struct i2c_board_info info;
+	const unsigned short addr_list[] = {
+		0x7a, 0x47, 0x71, 0x2d,
+		I2C_CLIENT_END
+	};
+
+	const unsigned short addr_list_msi[] = {
+		0x30, I2C_CLIENT_END
+	};
+	struct i2c_msg msg_msi = {
+		.addr = 0x50,
+		.flags = I2C_M_RD,
+		.len = 0,
+		.buf = NULL,
+	};
+
+	unsigned char subaddr, data;
+	struct i2c_msg msg_avermedia[] = { {
+		.addr = 0x40,
+		.flags = 0,
+		.len = 1,
+		.buf = &subaddr,
+	}, {
+		.addr = 0x40,
+		.flags = I2C_M_RD,
+		.len = 1,
+		.buf = &data,
+	} };
+
+	struct i2c_client *client;
+	int rc;
+
 	if (disable_ir) {
-		dprintk("Found supported i2c remote, but IR has been disabled\n");
-		ir->get_key=NULL;
+		dprintk("IR has been disabled, not probing for i2c remote\n");
+		return;
+	}
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+	if (client)
 		return;
+
+	/* MSI TV@nywhere Plus controller doesn't seem to
+	   respond to probes unless we read something from
+	   an existing device. Weird... */
+	rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
+	dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+		msg_msi.addr, dev->i2c_adap.name,
+		(1 == rc) ? "yes" : "no");
+	client = i2c_new_probed_device(&dev->i2c_adap, &info, addr_list_msi);
+	if (client)
+		return;
+
+	/* Special case for AVerMedia Cardbus remote */
+	subaddr = 0x0d;
+	rc = i2c_transfer(&dev->i2c_adap, msg_avermedia, 2);
+	dprintk(KERN_DEBUG "probe 0x%02x/0x%02x @ %s: %s\n",
+		msg_avermedia[0].addr, subaddr, dev->i2c_adap.name,
+		(2 == rc) ? "yes" : "no");
+	if (2 == rc) {
+		info.addr = msg_avermedia[0].addr;
+		i2c_new_device(&dev->i2c_adap, &info);
 	}
+}
 
+void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
+{
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
--- v4l-dvb.orig/linux/drivers/media/video/saa7134/saa7134.h	2009-05-12 10:19:32.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134.h	2009-05-12 11:24:19.000000000 +0200
@@ -804,6 +804,7 @@ void saa7134_irq_oss_done(struct saa7134
 int  saa7134_input_init1(struct saa7134_dev *dev);
 void saa7134_input_fini(struct saa7134_dev *dev);
 void saa7134_input_irq(struct saa7134_dev *dev);
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
 void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
 void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
 void saa7134_ir_stop(struct saa7134_dev *dev);
--- v4l-dvb.orig/linux/include/media/ir-kbd-i2c.h	2009-05-12 11:14:20.000000000 +0200
+++ v4l-dvb/linux/include/media/ir-kbd-i2c.h	2009-05-12 11:24:19.000000000 +0200
@@ -7,7 +7,7 @@ struct IR_i2c;
 
 struct IR_i2c {
 	IR_KEYTAB_TYPE         *ir_codes;
-	struct i2c_client      c;
+	struct i2c_client      *c;
 	struct input_dev       *input;
 	struct ir_input_state  ir;
 
