[pvrusb2] IR Blaster Support?

Mike Isely isely at isely.net
Fri Oct 24 22:32:43 CDT 2008


On Fri, 24 Oct 2008, Dan Bodoh wrote:

> On Fri, Oct 24, 2008 at 12:20 PM, Mike Isely <isely at isely.net> wrote:
> > There's nothing the pvrusb2 driver does to help or hinder IR blaster
> > support.  However it should work provided you have the right LIRC driver
> > in use.  All the pvrusb2 driver does is act as a communication conduit
> > to the IR blaster hardware within the device, but it's up to another
> > driver (i.e. LIRC) to make use of it.
> 
> One thing the pvrusb2 does have is that "fake" i2c channel which I
> don't understand.
> Should I be setting mode_ir (or ir_mode???) = 0 to get rid of the fake
> i2c channel?  I've actually tried both ways without success.


The pvrusb2 driver normally has little to actually do with IR handling.  
What happens is that the IR receiver merely exists at a specific I2C 
address on the I2C bus within the device.

Some explanation (probably a lot more than you want, but what the 
heck)...

The I2C bus is a serial bus that exists inside the device.  Chips on 
that bus reside at specific 7 bit I2C addresses.  An I2C controller 
connected to that bus can exchange data with any chip on that bus.  TV 
receiver devices typically have a single I2C bus, upon which various 
chips are connected.  The host operates the I2C controller, and the 
receiver's driver operates all the chips by performing I2C transfers 
appropriate to each chip via that controller.

In the case of PVR-USB2 type devices, obviously the I2C bus can't 
physically extend all the way to the host since there's a USB cable in 
the way.  Instead the device's FX2 microcontroller implements the I2C 
controller function, and the transfers it performs are driven by 
requests from the host over the USB cable.  What the pvrusb2 driver does 
in this environment is to implement a logical abstraction of an I2C 
controller, visible in the normal expected way within the Linux kernel, 
but implemented in terms of those USB commands to the FX2 
microcontroller.  Effectively this makes the device's local I2C bus 
transparently accessible to any I2C-aware driver within the Linux 
kernel.

The IR receiver in most PVR-USB2 type devices just simply exists as a 
chip on that I2C bus.  The pvrusb2 driver normally doesn't do anything 
specific to make that IR receiver work.  Rather, you just need to load 
an I2C-aware IR driver in the Linux kernel that knows how to detect and 
talk to that IR receiver chip.  The pvrusb2 driver's part in this setup 
is merely as the communications conduit for that driver - by responding 
to I2C transfer requests from that driver, passing the commands over the 
USB cable to the FX2, and pulling back whatever I2C data is read in 
response.

That's the canonical case: the pvrusb2 driver does nothing to 
specifically help or hurt IR handling.

Now, that's a bit of a white lie.  See, it used to be that way, years 
ago.  But now - as the hardware has changed, there are actually a couple 
of things the pvrusb2 driver does to help with IR handling a bit, and I 
think that's the confusion is happening.

On the original 29xxx series devices, the pvrusb2 driver didn't have to 
do anything to support IR.  We're just talking "conduit" in that case.

But on the first set of 24xxx series devices, Hauppauge changed out the 
IR implementation.  They removed I2C based IR receiver chip and replaced 
it with a bunch of logic in an FPGA which did NOT reside on the I2C bus.  
The only way to reach that IR receiver was via specific, tailored, 
non-I2C commands to the FX2 microcontroller.  This presented a problem, 
because the wire protocol for talking to the FX2 was internal to the 
pvrusb2 driver, and I did not want to invent a new API to allow an 
external driver to access the IR receiver.  That of course is silly so I 
would have instead had to have gotten into the business of doing the IR 
myself, implementing either a /dev/input style of driver or something 
gluing into whatever LIRC did.  Neither was very appealing.  I wanted to 
keep it simple.

So for 24xxx devices I did something different.  Remember that the 
pvrusb2 driver implements a logical abstraction for the I2C controller, 
since after all the "real" controller was at the other end of a USB 
cable.  This permitted a lot of flexibility in how to actually handle 
I2C requests from other I2C-aware drivers in the kernel.  So I added a 
new feature to the driver, a look-up table.  Every time the pvrusb2 
driver got an I2C request from the kernel, it would look up the target 
I2C address in this table.  If it found nothing, it passed it through to 
the hardware.  However it could find a function specifying custom 
behavior for that target address.  One such custom behavior is an 
emulated IR receiver.  I had discovered that the "real" IR receiver's 
communications protocol over I2C on the 29xxx device was almost trivial.  
So I created a software emulation of that chip in the pvrusb2 driver and 
tied it into the pvrusb2 driver's I2C controller at the I2C address that 
corresponded to the I2C address of the original IR receiver in the 29xxx 
device.  The emulation was then simply implemented in terms of the FX2 
commands required to operate the IR on the 24xxx device.  This had the 
outward effect of making IR on the 24xxx device look *identical* to the 
older 29xxx device, thus making it trivial for people to use this IR 
receiver (i.e. just treat it as a 29xxx device).  The pvrusb2 driver 
enabled this emulation during initialization of the hardware when it 
recognized that it was talking to a 24xxx device.  It was all wonderful, 
no special action or other setup required.  So far so good.

Then Hauppauge made another change.  They respun the 24xxx series - 
keeping the model number the same but swapping out the IR again.  You 
can recognize these devices because they all have a built-in IR blaster.  
Unfortunately by keeping the model number the same this made it 
difficult for the pvrusb2 driver to recognize this difference.  The new 
IR blaster also included its own IR receiver, all residing at a 
different I2C address (0x71) than the old 29xxx receiver.  The net 
effect of this is that you end up seeing 2 IR receivers: The pvrusb2 
driver spots a 24xxx device so it enables (the now useless) emulation 
for IR at I2C address 0x18, but the new (and different receiver) is also 
visible at 0x71.  The "fake" one in this case is useless - the emulation 
will just issue FX2 commands that don't work.  But it caused confusion 
because users will be led astray by that fake receiver.  There's e-mail 
in the archive of numerous people being fooled by this.

This issue is what first triggered the ir_mode parameter.  If you set 
that to zero, then the behavior is overridden: the I2C controller's 
lookup table is modified to simply blackhole accesses to address 0x18.  
With transfers to that address dropped, LIRC will no longer detect any 
chip there and the receiver disappears.  This gets rid of the emulation 
(and is also useful if you have multiple devices and want to disable IR 
on all but one).  This option does not affect 0x71 so the new IR 
receiver continues to work.

However I still wasn't completely happy with that and starting with the 
20080831 snapshot (which should also appear starting in 2.6.28), I 
implemented one more ability in the driver.  Now if you are using a 
device which might be subject to enabling of the emulated IR receiver, 
the driver will first probe I2C address 0x71.  If it finds something 
there, it will automatically disable the emulated IR receiver.  This 
returns complete sanity to the IR situation.  Note that this ONLY is the 
case for 20080831 snapshots or later, or for kernel 2.6.28 or later 
(before those points if you want to disable the fake receiver you still 
have to use ir_mode to do it).

The takeaway from all of this is that right now ir_mode only has an 
effect if you are dealing with IR receivers at 0x18, not 0x71.  And if 
you are running a recent enough driver then ir_mode is pretty much 
pointless anyway, as far as disabling the fake IR receiver is concerned.

So in your case, if your device has at internal IR blaster, then you can 
use ir_mode=0 to get rid of the fake IR receiver - if it is still there 
because the driver you are using is old enough.  If you said you did 
this and there was no effect, that might be because you're already 
really dealing with the receiver at 0x71 which ir_mode doesn't at this 
moment affect.  If that is the case, then your problem likely is in how 
LIRC is being set up (probably not a recent enough version of LIRC or 
you have the wrong driver selected).

Clear as mud?  Still awake?

I should probably write this whole thing up into the pvrusb2 
documentation somewhere...

  -Mike


-- 

Mike Isely
isely @ pobox (dot) com
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8


More information about the pvrusb2 mailing list