[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