diff mbox

[2/6] ir-kbd-i2c: Switch to the new-style device binding model

Message ID 20090417223105.28b8957e@hyperion.delvare (mailing list archive)
State RFC
Headers show

Commit Message

Jean Delvare April 17, 2009, 8:31 p.m. UTC
Let card drivers probe for IR receiver devices and instantiate them if
found. Ultimately it would be better if we could stop probing
completely, but I suspect this won't be possible for all card types.

There's certainly room for cleanups. For example, some drivers are
sharing I2C adapter IDs, so they also had to share the list of I2C
addresses being probed for an IR receiver. Now that each driver
explicitly says which addresses should be probed, maybe some addresses
can be dropped from some drivers.

Also, the special cases in saa7134-i2c should probably be handled on a
per-board basis. This would be more efficient and less risky than always
probing extra addresses on all boards. I'll give it a try later.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Cc: Andy Walls <awalls@radix.net>
Cc: Mike Isely <isely@pobox.com>
---
 linux/drivers/media/video/bt8xx/bttv-i2c.c           |   21 +
 linux/drivers/media/video/cx231xx/cx231xx-cards.c    |   11 
 linux/drivers/media/video/cx231xx/cx231xx-i2c.c      |    3 
 linux/drivers/media/video/cx231xx/cx231xx.h          |    1 
 linux/drivers/media/video/cx23885/cx23885-i2c.c      |   12 +
 linux/drivers/media/video/cx88/cx88-i2c.c            |   13 +
 linux/drivers/media/video/em28xx/em28xx-cards.c      |   20 +
 linux/drivers/media/video/em28xx/em28xx-i2c.c        |    3 
 linux/drivers/media/video/em28xx/em28xx-input.c      |    6 
 linux/drivers/media/video/em28xx/em28xx.h            |    1 
 linux/drivers/media/video/ir-kbd-i2c.c               |  200 +++---------------
 linux/drivers/media/video/ivtv/ivtv-i2c.c            |   31 ++
 linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c |   24 ++
 linux/drivers/media/video/saa7134/saa7134-i2c.c      |    3 
 linux/drivers/media/video/saa7134/saa7134-input.c    |   86 ++++++-
 linux/drivers/media/video/saa7134/saa7134.h          |    1 
 linux/include/media/ir-kbd-i2c.h                     |    2 
 17 files changed, 244 insertions(+), 194 deletions(-)

Comments

Mike Isely April 17, 2009, 11:35 p.m. UTC | #1
I thought we were going to leave the pvrusb2 driver out of this since 
I've already got a change ready that also includes additional logic to 
take into account the properties of the hardware device (i.e. only 
activate ir-kbd-i2c when we know it has a chance of working).

  -Mike


On Fri, 17 Apr 2009, Jean Delvare wrote:

> Let card drivers probe for IR receiver devices and instantiate them if
> found. Ultimately it would be better if we could stop probing
> completely, but I suspect this won't be possible for all card types.
> 
> There's certainly room for cleanups. For example, some drivers are
> sharing I2C adapter IDs, so they also had to share the list of I2C
> addresses being probed for an IR receiver. Now that each driver
> explicitly says which addresses should be probed, maybe some addresses
> can be dropped from some drivers.
> 
> Also, the special cases in saa7134-i2c should probably be handled on a
> per-board basis. This would be more efficient and less risky than always
> probing extra addresses on all boards. I'll give it a try later.
> 
> Signed-off-by: Jean Delvare <khali@linux-fr.org>
> Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
> Cc: Hans Verkuil <hverkuil@xs4all.nl>
> Cc: Andy Walls <awalls@radix.net>
> Cc: Mike Isely <isely@pobox.com>
> ---
>  linux/drivers/media/video/bt8xx/bttv-i2c.c           |   21 +
>  linux/drivers/media/video/cx231xx/cx231xx-cards.c    |   11 
>  linux/drivers/media/video/cx231xx/cx231xx-i2c.c      |    3 
>  linux/drivers/media/video/cx231xx/cx231xx.h          |    1 
>  linux/drivers/media/video/cx23885/cx23885-i2c.c      |   12 +
>  linux/drivers/media/video/cx88/cx88-i2c.c            |   13 +
>  linux/drivers/media/video/em28xx/em28xx-cards.c      |   20 +
>  linux/drivers/media/video/em28xx/em28xx-i2c.c        |    3 
>  linux/drivers/media/video/em28xx/em28xx-input.c      |    6 
>  linux/drivers/media/video/em28xx/em28xx.h            |    1 
>  linux/drivers/media/video/ir-kbd-i2c.c               |  200 +++---------------
>  linux/drivers/media/video/ivtv/ivtv-i2c.c            |   31 ++
>  linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c |   24 ++
>  linux/drivers/media/video/saa7134/saa7134-i2c.c      |    3 
>  linux/drivers/media/video/saa7134/saa7134-input.c    |   86 ++++++-
>  linux/drivers/media/video/saa7134/saa7134.h          |    1 
>  linux/include/media/ir-kbd-i2c.h                     |    2 
>  17 files changed, 244 insertions(+), 194 deletions(-)

   [...]
Jean Delvare April 18, 2009, 9:25 a.m. UTC | #2
Hi Mike,

On Fri, 17 Apr 2009 18:35:55 -0500 (CDT), Mike Isely wrote:
> I thought we were going to leave the pvrusb2 driver out of this since 
> I've already got a change ready that also includes additional logic to 
> take into account the properties of the hardware device (i.e. only 
> activate ir-kbd-i2c when we know it has a chance of working).

Hmm, I thought that our latest discussions had (at least partly)
obsoleted your patches. Remember that we want to always instantiate
ir_video I2C devices even when ir-kbd-i2c can't driver them, otherwise
lirc won't be able to bind to the devices in question as soon as the
legacy binding model is gone. So the conditionals in your second patch
(which is all that makes it differ from mine) are no longer desirable.

I'll work on lirc patches today or tomorrow, so that lirc doesn't break
when my patches hit mainline.

Your first patch is still interesting but it is independent from my own
patches, so it can be merged before or after, it doesn't matter.
Jean Delvare April 18, 2009, 1:16 p.m. UTC | #3
Hi again Mike,

On Sat, 18 Apr 2009 11:25:19 +0200, Jean Delvare wrote:
> On Fri, 17 Apr 2009 18:35:55 -0500 (CDT), Mike Isely wrote:
> > I thought we were going to leave the pvrusb2 driver out of this since 
> > I've already got a change ready that also includes additional logic to 
> > take into account the properties of the hardware device (i.e. only 
> > activate ir-kbd-i2c when we know it has a chance of working).
> 
> Hmm, I thought that our latest discussions had (at least partly)
> obsoleted your patches. Remember that we want to always instantiate
> ir_video I2C devices even when ir-kbd-i2c can't driver them, otherwise
> lirc won't be able to bind to the devices in question as soon as the
> legacy binding model is gone. So the conditionals in your second patch
> (which is all that makes it differ from mine) are no longer desirable.
> 
> I'll work on lirc patches today or tomorrow, so that lirc doesn't break
> when my patches hit mainline.

Speaking of this: do you know all the I2C addresses that can host IR
devices on pvrusb2 cards? I understand that the only address supported
by ir-kbd-i2c is 0x18, but I also need to know the addresses supported
by lirc_i2c and possibly lirc_zilog, if you happen to know this.

Thanks,
Mike Isely April 18, 2009, 1:53 p.m. UTC | #4
On Sat, 18 Apr 2009, Jean Delvare wrote:

> Hi again Mike,
> 
> On Sat, 18 Apr 2009 11:25:19 +0200, Jean Delvare wrote:
> > On Fri, 17 Apr 2009 18:35:55 -0500 (CDT), Mike Isely wrote:
> > > I thought we were going to leave the pvrusb2 driver out of this since 
> > > I've already got a change ready that also includes additional logic to 
> > > take into account the properties of the hardware device (i.e. only 
> > > activate ir-kbd-i2c when we know it has a chance of working).
> > 
> > Hmm, I thought that our latest discussions had (at least partly)
> > obsoleted your patches. Remember that we want to always instantiate
> > ir_video I2C devices even when ir-kbd-i2c can't driver them, otherwise
> > lirc won't be able to bind to the devices in question as soon as the
> > legacy binding model is gone. So the conditionals in your second patch
> > (which is all that makes it differ from mine) are no longer desirable.

Jean:

The differences between my patch(es) and yours are:

1. My patch only attempts to bind the driver if the hardware actually 
supports it.

2. My patch selects the right I2C address for the case(s) where it makes 
sense to bind.

3. My patch provides a module option to completely disable binding.

You are probably thinking about (3) but you forgot that I had also taken 
care of (1).  Difference (1) is why I don't want your patch.  If your 
patch gets merged I will have to partially redo my patch to make (1) 
work again.

When I had issued my pull request to Mauro (which he didn't pull), there 
were actually 2 patches.  The first one dealt with (1) and the second 
dealt with (2) and (3), while taking advantage of (1).  Had Mauro pulled 
those patches at that time then you could have made further changes on 
top without losing (1).  But since he didn't, it's best just to leave 
the pvrusb2 driver alone and I'll make the needed additional change(s) 
there after your stuff is merged.


> > 
> > I'll work on lirc patches today or tomorrow, so that lirc doesn't break
> > when my patches hit mainline.
> 
> Speaking of this: do you know all the I2C addresses that can host IR
> devices on pvrusb2 cards? I understand that the only address supported
> by ir-kbd-i2c is 0x18, but I also need to know the addresses supported
> by lirc_i2c and possibly lirc_zilog, if you happen to know this.

Right now I only care about 0x18 (for 29xxx and early 24xxx devices).  
I noticed the thread where Andy got IR reception to work with ir-kbd-i2c 
using 0x71 (lirc_zilog type) and I suspect that same set of ir-kbd-i2c 
changes will probably work with the pvrusb2 driver for MCE 24xxx and 
HVR-1900/HVR-1950 devices.  But I figured once Andy's stuff gets into 
ir-kbd-i2c I'd simply test for this and if it worked I would make the 
appropriate adjustments in the pvrusb2 driver to enable ir-kbd-i2c 
binding in those cases as well (an easy change).  However even with that 
change, there are other pvrusb2-driven devices that cannot support 
ir-kbd-i2c.

  -Mike
Jean Delvare April 23, 2009, 9 a.m. UTC | #5
Hi Mike,

Sorry for the late answer.

On Sat, 18 Apr 2009 08:53:35 -0500 (CDT), Mike Isely wrote:
> On Sat, 18 Apr 2009, Jean Delvare wrote:
> > On Sat, 18 Apr 2009 11:25:19 +0200, Jean Delvare wrote:
> > > Hmm, I thought that our latest discussions had (at least partly)
> > > obsoleted your patches. Remember that we want to always instantiate
> > > ir_video I2C devices even when ir-kbd-i2c can't driver them, otherwise
> > > lirc won't be able to bind to the devices in question as soon as the
> > > legacy binding model is gone. So the conditionals in your second patch
> > > (which is all that makes it differ from mine) are no longer desirable.
> 
> Jean:
> 
> The differences between my patch(es) and yours are:
> 
> 1. My patch only attempts to bind the driver if the hardware actually 
> supports it.

That's not clear to me. I seem to understand that your patch
instantiates the ir_video device if and only if the ir-kbd-i2c driver
supports it. This is not what we want to do. We want to create the
ir_video device if an IR receiver exists, even if ir-kbd-i2c doesn't
support it. The reason is that ir-kbd-i2c could be extended to support
the IR receiver in question in the future, and that alternative drivers
(lirc_i2c comes to mind) could also be used.

I also don't understand why you use i2c_new_probed_device() rather than
i2c_new_device() if you already know for sure that the IR receiver
device is present?

> 2. My patch selects the right I2C address for the case(s) where it makes 
> sense to bind.

This is a good thing, although your implementation isn't exactly what I
would expect. The address list should depend on the value of
hdw->ir_scheme_active. At the moment you support only 2 schemes and
they happen to use the same I2C address, but I presume this will change
in the future.

> 3. My patch provides a module option to completely disable binding.

I agree this can be useful, as discussed earlier, although I still
object to the name you chose (disable_autoload_ir_kbd). This module
option is only remotely related to the i2c binding model change.

> You are probably thinking about (3) but you forgot that I had also taken 
> care of (1).  Difference (1) is why I don't want your patch.  If your 
> patch gets merged I will have to partially redo my patch to make (1) 
> work again.

This is correct. But if your second patch is merged before my own
changes, then IR support will be broken for all pvrusb2 users, unless
they temporarily load the driver with disable_autoload_ir_kbd=1. But
they will have to remove the parameter as soon as my own patches are
merged. This approach doesn't strike me as the best user experience.

If my patches are merged first and yours go second (which I admit means
you'll have to adjust your patches a bit) then everything will keep
working for the user. This is the reason why I was proposing this order.

> When I had issued my pull request to Mauro (which he didn't pull), there 
> were actually 2 patches.  The first one dealt with (1) and the second 
> dealt with (2) and (3), while taking advantage of (1).  Had Mauro pulled 
> those patches at that time then you could have made further changes on 
> top without losing (1).  But since he didn't, it's best just to leave 
> the pvrusb2 driver alone and I'll make the needed additional change(s) 
> there after your stuff is merged.

I can't "leave the pvrusb2 driver alone", unless you consider it
acceptable that your users lose IR support between my patches and
yours. When ir-kbd-i2c is converted to the new-style i2c binding, all
bridge drivers must be updated too.

> > > I'll work on lirc patches today or tomorrow, so that lirc doesn't break
> > > when my patches hit mainline.
> > 
> > Speaking of this: do you know all the I2C addresses that can host IR
> > devices on pvrusb2 cards? I understand that the only address supported
> > by ir-kbd-i2c is 0x18, but I also need to know the addresses supported
> > by lirc_i2c and possibly lirc_zilog, if you happen to know this.
> 
> Right now I only care about 0x18 (for 29xxx and early 24xxx devices).

I've seen this, but this isn't my question. If lirc_i2c supports other
IR devices that are present on pvrusb2 devices, we must declare them as
well so that we don't break lirc_i2c. So, once again: do you know all
the I2C addresses where pvrusb2 cards can have IR devices?

> I noticed the thread where Andy got IR reception to work with ir-kbd-i2c 
> using 0x71 (lirc_zilog type) and I suspect that same set of ir-kbd-i2c 
> changes will probably work with the pvrusb2 driver for MCE 24xxx and 
> HVR-1900/HVR-1950 devices.  But I figured once Andy's stuff gets into 
> ir-kbd-i2c I'd simply test for this and if it worked I would make the 
> appropriate adjustments in the pvrusb2 driver to enable ir-kbd-i2c 
> binding in those cases as well (an easy change).  However even with that 
> change, there are other pvrusb2-driven devices that cannot support 
> ir-kbd-i2c.

I'm worried that this means doing several changes first and only then
converting ir-kbd-i2c to the new i2c binding model. Similar to Mauro
who was suggesting that we should merge lirc in the kernel first and
only the convert to the new i2c model. There is really no good reason to
delay the i2c binding model change, and I would like to remind everyone
that my point here was to take care of that quickly because it is
delaying other i2c changes.

I am willing to collaborate with you v4l-dvb people, but if your answer
is "we'll do many unrelated changes first and then we'll look at your
patches", this isn't acceptable. I would hate to push the changes to
Linus' tree directly without going through the v4l-dvb tree, as I know
this means more work for you, but if you do not give me any other
choice, it might happen.
Mike Isely April 24, 2009, 2:44 a.m. UTC | #6
Hi Jean,

I had actually written out a longer, detailed, point-by-point reply 
earlier today, but before I could finish it I got interrupted with a 
crisis.  And then another.  And that's kind of how my day went.  Now I'm 
finally back to this, but I have another e-mail debacle to immediately 
deal with (thank you pobox.com, not!) so I'm tossing that unfinished 
lengthy reply.  I think I can sum this whole thing up very simply.  
Here's what I think should be happening:

1a. Your existing IR changeset, minus the pvrusb2 changes, should be 
merged.

1b. In parallel with (1a) I modify my pvrusb2 changeset to use the right 
module name and I adjust the driver option name to match.

2. My pvrusb2 changeset, with changes from (1b) is merged.

3. Andy's proposed change for ir_kbd_i2c to support additional IR 
devices is investigated and probably merged.

4. I test the changed ir_kbd_i2c against additional pvrusb2 devices 
known not to work previously with ir_kbd_i2c.  If they work, then I will 
create a pvrusb2 patch to load ir_video in those cases as well as the 
cases already set up (which still won't cover all possible 
pvrusb2-driven devices).

I think this satisfies the remaining issues, except that from between 
steps 1 and 2 ir_kbd_i2c won't work with the pvrusb2 driver.  But you 
know, I'm OK with that.  I expect (2) to happen within a few days after 
(1) so the impact should be minimal.  It certainly won't escape into the 
kernel tree that way.  In addition, my impression from the community of 
pvrusb2 users is that the preferred IR strategy is lirc anyway, and it's 
a foregone conclusion that they are all going to be, uh, impacted once 
your compatibility parts are gone from i2c.  From where I'm sitting the 
"gap" from (1) to (2) is trivial compared to that impending mess - 
realize I'm not complaining since after all (a) it really falls to the 
lirc developers to fix that, (b) you do need to get your changes in, and 
(c) there's little I can do for lirc there except to keep it working as 
long as possible with the pvrusb2 driver.  I'm just pointing out that 
I'm OK with the step 1 -> 2 gap for the pvrusb2 driver because it's 
small and will be nothing compared to what's about to happen with lirc.

If you still don't like any of that, well, then I give up.  In that 
case, then merge your changes with the pvrusb2 changes included.  I 
won't ack them, but I'll just deal with it later.  Because while your 
changes might keep ir_kbd_i2c going, they will also immediately break 
the more-useful and apparently more-used lirc (by always binding 
ir_kbd_i2c even in cases in the pvrusb2 driver where it's known that it 
can't even work but lirc would have) which as far as I'm concerned is 
far worse than the step 1 - 2 gap above.  But it's just another gap and 
I'll push another pvrusb2 changeset on top to clean it up.  So just do 
whatever you think is best right now, if you disagree with the sequence 
above.

Now I will go off and deal with the steamer that pobox.com has just 
handed me :-(

  -Mike
diff mbox

Patch

--- v4l-dvb.orig/linux/drivers/media/video/bt8xx/bttv-i2c.c	2009-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/bt8xx/bttv-i2c.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx231xx/cx231xx-cards.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx231xx/cx231xx-i2c.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx231xx/cx231xx.h	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx23885/cx23885-i2c.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/cx88/cx88-i2c.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx-cards.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx-i2c.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx-input.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/em28xx/em28xx.h	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/ivtv/ivtv-i2c.c	2009-04-17 14:37:54.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/pvrusb2/pvrusb2-i2c-core.c	2009-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c	2009-04-17 14:37:54.000000000 +0200
@@ -637,6 +637,27 @@  static void do_i2c_scan(struct pvr2_hdw
 	printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
 }
 
+static void pvr2_i2c_register_ir(struct i2c_adapter *i2c_adap)
+{
+	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(i2c_adap, &info, addr_list);
+}
+
 void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
 {
 	unsigned int idx;
@@ -684,6 +705,9 @@  void pvr2_i2c_core_init(struct pvr2_hdw
 		}
 	}
 	if (i2c_scan) do_i2c_scan(hdw);
+
+	/* Instantiate the IR receiver device, if present */
+	pvr2_i2c_register_ir(&hdw->i2c_adap);
 }
 
 void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
--- v4l-dvb.orig/linux/drivers/media/video/saa7134/saa7134-i2c.c	2009-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134-i2c.c	2009-04-17 14:37:54.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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134-input.c	2009-04-17 14:37:54.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;
 	}
@@ -683,14 +683,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-04-17 14:36:51.000000000 +0200
+++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134.h	2009-04-17 14:37:54.000000000 +0200
@@ -792,6 +792,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-04-17 14:36:50.000000000 +0200
+++ v4l-dvb/linux/include/media/ir-kbd-i2c.h	2009-04-17 14:37:54.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;