KWorld Global TV Terminator

From MythTV Official Wiki
Jump to: navigation, search

Warning.png Warning: This page has been locked and archived on September 28, 2010. The official documentation for this card can be found at KWorld_Studio_TV_Terminator. This page remains as there is significant information herein not included in the official documentation. Please migrate any such information to the proper location.

General

(Version: VS-LTV7131RF) This (very inexpensive) card has been successfully set up on FC6 and FC8. Also has an FM tuner and an IR receiver and remote. The MSI TV@nywhere Plus PCI is nearly identical to the KWorld Global TV Terminator. I have also found that the KWorld TV Studio Terminator is also compatible with these directions.

Card information:

# lspci -v
06:02.0 Multimedia controller: Philips Semiconductors SAA7133/SAA7135 Video Broadcast Decoder (rev d1)
        Subsystem: Philips Semiconductors Unknown device 0000
        Flags: bus master, medium devsel, latency 32, IRQ 18
        Memory at 50004800 (32-bit, non-prefetchable) [size=2K]
        Capabilities: [40] Power Management version 2

-Or (KWorld TV Studio Terminator):
# lspci -v
00:08.0 Multimedia controller: Philips Semiconductors SAA7133/SAA7135 Video Broadcast Decoder (rev d0)
        Flags: bus master, medium devsel, latency 64, IRQ 24
        Memory at fbfff800 (32-bit, non-prefetchable) [size=2K]
        Capabilities: [40] Power Management version 2
        Kernel modules: saa7134

Audio capture device information:

# arecord -l
card 1: SAA7134 [SAA7134], device 0: SAA7134 PCM [SAA7134 PCM]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

Assuming your soundcard is card 0 add the following to /etc/modprobe.conf (or /etc/modprobe.d/saa7134). This code block will auto install the saa7134 modules as sound card 1, (allowing the video to fall where it may usually /dev/video0). This means that to access the audio input stream you would select /dev/dsp1 as your audio input:

options saa7134 card=65 tuner=54
alias snd-card-1 saa7134-alsa
options snd-card-1 index=1
install saa7134 /sbin/modprobe --ignore-install saa7134; \
        /sbin/modprobe saa7134-alsa
remove saa7134-alsa { /usr/sbin/alsactl store SAA7134 >/dev/null 2>&1 || : ; }; \
        /sbin/modprobe -r --ignore-remove saa7134-alsa
# ---------
# Use the above if you don't need DVB or the below if you do need DVB
# NOTE: DO NOT USE BOTH THE ABOVE AND BELOW PICK ONE! YOU HAVE BEEN WARNED!
# ---------
# Changes made 2008/10/22 by meaje based on mythtv.org/wiki/index.php/KWorld_Global_TV_Terminator
# - modifications to autoinstall the dvb modules as well -> meaje
options saa7134 card=65 tuner=54 i2c_scan=1
alias snd-card-1 saa7134-alsa
options snd-card-1 index=1
install saa7134 /sbin/modprobe --ignore-install saa7134; \
        /sbin/modprobe saa7134-alsa
remove saa7134 /sbin/modprobe -r saa7134-alsa; \
        /sbin/modprobe -r --ignore-remove saa7134
install saa7134-alsa /sbin/modprobe --ignore-install saa7134-alsa; \
        { /usr/sbin/alsactl restore SAA7134 >/dev/null 2>&1 || : ; }; \
        /sbin/modprobe saa7134-dvb
remove saa7134-alsa { /usr/sbin/alsactl store SAA7134 >/dev/null 2>&1 || : ; }; \
        /sbin/modprobe -r saa7134-dvb; \
        /sbin/modprobe -r --ignore-remove saa7134-alsa

Use v4lctl to display/set the card attributes: Note this may not work for users who are using v4l2-ctl as the output has changed. If you find yourself using v4l2-ctl try using the '--all' switch to see the output but be warned that things are not formatted the same. - meaje 2008-10-22

[root@sandbox ~]# v4lctl list
attribute  | type   | current | default | comment
-----------+--------+---------+---------+-------------------------------------
norm       | choice | NTSC    | PAL     | PAL PAL-BG PAL-I PAL-DK NTSC SECAM PAL-M PAL-Nc PAL-60
input      | choice | Televis | Televis | Television Composite1 S-Video
audio mode | choice | mono    | mono    | mono stereo lang1 lang2
bright     | int    |     127 |     128 | range is 0 => 255
contrast   | int    |      67 |      68 | range is 0 => 127
color      | int    |      63 |      64 | range is 0 => 127
hue        | int    |       0 |       0 | range is -128 => 127
volume     | int    |      12 |       0 | range is -15 => 15
mute       | bool   | off     | off     |
Mirror     | bool   | off     | off     |
Invert     | bool   | off     | off     |
y offset o | int    |       0 |       0 | range is 0 => 128
y offset e | int    |       0 |       0 | range is 0 => 128
automute   | bool   | on      | on      |

-- v4l2-ctl (New Format Output) --
# v4l2-ctl -all
Driver Info:
        Driver name   : saa7134
        Card type     : V-Stream Studio TV Terminator
        Bus info      : PCI:0000:00:08.0
        Driver version: 526
        Capabilities  : 0x05010015
                Video Capture
                Video Overlay
                VBI Capture
                Tuner
                Read/Write
                Streaming
Format Video Capture:
        Width/Height  : 720/576
        Pixel Format  : BGR3
        Field         : Interlaced
        Bytes per Line: 2160
        Size Image    : 1244160
        Colorspace    : Unknown (00000000)
Format Video Overlay:
        Left/Top    : 0/0
        Width/Height: 0/0
        Field       : Any
        Chroma Key  : 0x00000000
        Global Alpha: 0x00
        Clip Count  : 0
        Clip Bitmap : No
Format VBI Capture:
        Sampling Rate   : 27000000 Hz
        Offset          : 256 samples (9.48148e-06 secs after leading edge)
        Samples per Line: 2048
        Sample Format   : GREY
        Start 1st Field : 7
        Count 1st Field : 16
        Start 2nd Field : 319
        Count 2nd Field : 16
Framebuffer Format:
        Capability    : Clipping List
        Flags         : 
        Width         : 0
        Height        : 0
        Pixel Format  : 
        Bytes per Line: 0
        Size image    : 0
        Colorspace    : Unknown (00000000)
Crop Capability Video Capture:
        Bounds      : Left 0, Top 46, Width 720, Height 578
        Default     : Left 0, Top 48, Width 720, Height 576
        Pixel Aspect: 54/59
Crop: Left 0, Top 48, Width 720, Height 576
Video input : 0 (Television)
Audio input : 0 (audio)
Frequency: 0 (0.000000 MHz)
Video Standard = 0x000000ff
        PAL-B/B1/G/H/I/D/D1/K
Tuner:
        Capabilities         : 62.5 kHz multi-standard stereo lang1 lang2 
        Frequency range      : 0.0 MHz - 268435455.9 MHz
        Signal strength      : 0%
        Current audio mode   : mono
        Available subchannels: mono 

If you setup saa7134-alsa as card 1 you will refer to it as /dev/dsp1 in mythtv-setup when setting up the capture card.

+-------------+-------------+----------+--------------+----------------+
| videodevice | audiodevice | cardtype | defaultinput | audioratelimit |
+-------------+-------------+----------+--------------+----------------+
| /dev/video0 | /dev/dsp1   | V4L      | Television   |          32000 |
+-------------+-------------+----------+--------------+----------------+

Remote

The remote has 36 buttons of which 32 send unique codes. The remote is not fully supported in the kernel but the knowledge exists on how to get it working by patching the kernel. It is apparently a combined GPIO/i2c remote and a patch has been posted to the v4l mailing list and modified a few times for similar remotes (see Henry Wong patch). There are changes needed in the ir-kbd-i2c and saa7134 modules. Here is a full description on how I got the remote working with Fedora 7 and the 2.6.22 kernel: Terminator Remote Kernel Patch Fedora HOWTO

Here are alternative versions of Henry Wong's patch: Ubuntu Feisty Ubuntu Hardy (kernel 2.6.24) Debian Etch

Problems

Video but no sound? You may need to turn the volume up on the capture. Assuming /dev/dsp1 again run the following command:

[root@sandbox ~]# alsamixer -c 1

Not working in MythTV? Try it with mplayer. If this works (you may need to modify device, chanlist, adevice, or norm) then you have MythTV misconfigured somehow.

mplayer tv://"insert channel" -tv driver=v4l2:device=/dev/video0:chanlist=us-cable:alsa:\
adevice=hw.1,0:amode=1:audiorate=32000:forceaudio:volume=100:immediatemode=0:norm=NTSC

HOWTO with Mythdora

This is a How To for setting this card up in MythDora(specifically 4.0). Much of this was taken from the wiki already and this is just here to make it easier to decipher which commands should be used and also to show that it works when hardware shopping. It was written on 08/03/07.

Video

Uses the saa7134 driver, which will automatically be loaded by Mythdora, but you need to pass the parameters card=65 tuner=54 when the module is loaded. To do this automatically, create a file called saa7134 in /etc/modprobe.d/ with the following contents:

options saa7134 card=65 tuner=54

Now every time the module is loaded, it will be passed these parameters.

You should now see your card show up in the Mythtv setup of capture cards.

I am not certain that this is correct, but I used it as a V4L capture card and it worked.

Audio

Unlike Knoppmyth Mythdora uses the saa7134-alsa module. However it usually starts with the volume turned all the way down. Use the fix below to adjust the sound of the card:

This is assuming the audio of the card is /dev/dsp1 (if not change the 1 at the end to the card number) again run the following command:

[root@sandbox ~]# alsamixer -c 1

Finally to get sound working you may need to go into Utilities/Setup> Setup> General and on the 3rd page you will see info on how your sound is output from Mythtv. Make sure it is using the right soundcard and you may also have to change the Passthrough to the Alsa option.

HOWTO with KnoppMyth

This is a mini HOWTO for getting the video, audio, and remote of the KWorld Global TV Terminator working with KnoppMyth (specifially, version 5E50). The information may be useful to other distributions. It was created on Feb 20, 2007.

Video

Uses the saa7134 driver, which will automatically be loaded by KnoppMyth, but you need to pass the parameters card=65 tuner=54 when the module is loaded. To do this automatically, create a file called saa7134 in /etc/modprobe.d/ with the following contents:

options saa7134 card=65 tuner=54

Now everytime the module is loaded, it will be passed these parameters.

That's it for video. You should now see your card show up in the KnoppMyth setup of capture cards.

Audio

A lot of the documentation I found said to use the saa7134-alsa module for sound; this module is not loaded by KnoppMyth by default, and I found that when I loaded it, it caused a kernel panic.

However, there is another module that provides sound for the saa7134 and that is saa7134-oss. This module worked great for me.

Loading this module should create /dev/dsp1 (or a higher number if another device is already using /dev/dsp1). You need to tell KnoppMyth to use this audio device in the capture card setup.

By default, the sound may be muted, the volume may be too low, and automute may be on (not sure what effect automute has). In order to ensure these settings allow sound to come through, you need to use the video4linux 2 control utility (v4l2-ctl) to change them:

# v4l2-ctl --set-ctrl=mute=0
# v4l2-ctl --set-ctrl=volume=10
# v4l2-ctl --set-ctrl=automute=0

This should be it to get audio working, but you'll probably want these steps to be taken every time the computer boots. To do this, I placed the following lines in /etc/init.d/rc.local (after the line ". /lib/lsb/init-functions"):

modprobe saa7134-oss
v4l2-ctl --set-ctrl=mute=0
v4l2-ctl --set-ctrl=volume=10
v4l2-ctl --set-ctrl=automute=0

and then added rc.local to the system startup by issuing the command:

# update-rc.d rc.local defaults

Remote

The remote is the most difficult piece to get to work. It requires patching the kernel.

In order to do this, you need to download the kernel source, which can be found at ftp://knoppmyth.net/R5/linux-source-2.6.18-chw-13_2.6.18-chw-13-10.00.Custom_all.deb

Install it with:

# dpkg -i linux-source-2.6.18-chw-13_2.6.18-chw-13-10.00.Custom_all.deb

This will create a .tar.bz2 file containing the source in /usr/src/ . Untar this file.

Now you'll need to apply some patches.

The heavy lifting is done by a patch by Henry Wong. I've modified it so that it applies cleanly to the kernel source we are working with. I've broken it into 5 parts:


Script.png KWorld_Global_TV_Terminator remote_control_part1.patch

--- linux/drivers/media/video/saa7134/saa7134-input.c.orig	2006-11-03 17:33:58.000000000 -0800
+++ linux/drivers/media/video/saa7134/saa7134-input.c	2007-02-11 02:19:51.000000000 -0800
@@ -46,6 +46,69 @@
 #define i2cdprintk(fmt, arg...)    if (ir_debug) \
 	printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
 
+ /* 
+   Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
+   is marked "KS003". The controller is I2C at address 0x30, but does not seem to respond
+   to probes until a read is performed from a valid device. (I don't know why.)
+   Henry Wong <henry@xxxxxxxxxxxxxx>
+ */
+ static IR_KEYTAB_TYPE msi_tvanywhere_plus_codes[IR_KEYTAB_SIZE] = {
+ 
+ /*
+     POWER   SOURCE  SCAN    MUTE    
+     TV/FM   1       2       3
+     CH+     4       5       6
+     CH-     7       8       9
+     >>(12)  0       +(16)   RECALL(19)
+     <<(4)   RECORD  STOP    PLAY
+ 
+         MINIMIZE(15)   ZOOM(25)
+ 	
+                   CH+
+            VOL-         VOL+
+                   CH-
+ 		  
+         SNAPSHOT(26)     MTS(13)
+ 	
+     <<(4)  FUNCTION  >>(12) RESET(29)
+ */
+ 	[    2 ] = KEY_KP0,
+ 	[    1 ] = KEY_KP1,
+ 	[   11 ] = KEY_KP2,
+ 	[   27 ] = KEY_KP3,
+ 	[    5 ] = KEY_KP4,
+ 	[    9 ] = KEY_KP5,
+ 	[   21 ] = KEY_KP6,
+ 	[    6 ] = KEY_KP7,
+ 	[   10 ] = KEY_KP8,
+ 	[   18 ] = KEY_KP9,
+ 
+ 	[    0 ] = KEY_RECORD,
+ 	[    3 ] = KEY_RADIO,          /* FM Radio */
+ 	[    4 ] = KEY_BACK,
+ 	[    7 ] = KEY_TUNER,          /* Source */
+ 	[    8 ] = KEY_STOP,
+ 	[   12 ] = KEY_FORWARD,
+ 	[   13 ] = KEY_LANGUAGE,       /* MTS */
+ 	[   14 ] = KEY_MENU,           /* Function */
+ 	[   15 ] = KEY_CLOSE,          /* Minimize */
+ 	[   16 ] = KEY_KPPLUS,         /* + */
+  	[   17 ] = KEY_PLAY,
+ 	[   19 ] = KEY_AGAIN,          /* Recall */
+ 	[   20 ] = KEY_VOLUMEDOWN,
+ 	[   22 ] = KEY_VOLUMEUP,
+ 	[   23 ] = KEY_CHANNELDOWN,
+ 	[   24 ] = KEY_MUTE,
+ 	[   25 ] = KEY_ZOOM,
+ 	[   26 ] = KEY_SHUFFLE,        /* Snapshot */
+ 	[   28 ] = KEY_SEARCH,	       /* Scan */
+ 	[   29 ] = KEY_RESTART,        /* Reset */
+  	[   30 ] = KEY_POWER,
+ 	[   31 ] = KEY_CHANNELUP
+ };
+ 
+ 
+
 /* -------------------- GPIO generic keycode builder -------------------- */
 
 static int build_key(struct saa7134_dev *dev)
@@ -88,6 +151,48 @@
 }
 
 /* --------------------- Chip specific I2C key builders ----------------- */
+static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char b;
+	int rc;
+	int gpio;
+
+	/* We need this to access GPIO. Used by the saa_readl macro. */
+	struct saa7134_dev *dev = ir->c.adapter->algo_data;
+	if (dev == NULL) {
+		dprintk ("ir->c.adapter->algo_data is NULL!\n");
+		return -EIO;
+	}
+	
+	/* rising SAA7134_GPIO_GPRESCAN reads the status */
+	saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
+	saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
+
+	gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
+
+	/* GPIO&0x40 is pulsed low when a button is pressed. Don't do
+	   I2C receive if gpio&0x40 is not low. */
+	if (gpio & 0x40) 
+		return 0;	/* No button press */
+
+
+	/* GPIO says there is a button press. Get it. */
+	if (1 != (rc=i2c_master_recv(&ir->c,&b,1))) {
+		dprintk("read error %d\n", rc);
+		return -EIO;
+	}
+
+	/* No button press */
+	if (b == 0xFF)
+		return 0;
+	
+	/* Button pressed */
+	dprintk ("get_key_msi_tvanywhere_plus key=0x%x\n", b);
+
+	*ir_key = b;
+	*ir_raw = b;
+	return 1;
+}
 
 static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
@@ -333,6 +438,11 @@
 		ir->get_key   = get_key_purpletv;
 		ir->ir_codes  = ir_codes_purpletv;
 		break;
+	case SAA7134_BOARD_MSI_TVANYWHERE_PLUS:
+		snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus");
+		ir->get_key   = get_key_msi_tvanywhere_plus;
+		ir->ir_codes  = msi_tvanywhere_plus_codes;
+		break;
 	default:
 		dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
 		break;


Script.png KWorld_Global_TV_Terminator remote_control_part2.patch

--- linux/drivers/media/video/ir-kbd-i2c.c.orig	2006-11-03 17:33:58.000000000 -0800
+++ linux/drivers/media/video/ir-kbd-i2c.c	2007-02-11 02:06:08.000000000 -0800
@@ -59,6 +59,8 @@
 #define dprintk(level, fmt, arg...)	if (debug >= level) \
 	printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
 
+static int polling_interval = 100; /* ms */
+
 /* ----------------------------------------------------------------------- */
 
 static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
@@ -263,7 +265,7 @@
 {
 	struct IR_i2c *ir = data;
 	ir_key_poll(ir);
-	mod_timer(&ir->timer, jiffies+HZ/10);
+	mod_timer(&ir->timer, jiffies + polling_interval*HZ/1000);
 }
 
 /* ----------------------------------------------------------------------- */
@@ -339,6 +341,9 @@
 		}
 		break;
 	case 0x30:
+		if (adap->id == I2C_HW_SAA7134) /* Handled by saa7134-input */
+			polling_interval = 50; /* ms */
+
 		name        = "KNC One";
 		ir->get_key = get_key_knc1;
 		ir_type     = IR_TYPE_OTHER;
@@ -430,7 +435,7 @@
 	*/
 
 	static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
-	static const int probe_saa7134[] = { 0x7a, 0x47, -1 };
+	static const int probe_saa7134[] = { 0x7a, 0x47, 0x30, -1 };
 	static const int probe_em28XX[] = { 0x30, 0x47, -1 };
 	const int *probe = NULL;
 	struct i2c_client c;
@@ -458,7 +463,36 @@
 	c.adapter = adap;
 	for (i = 0; -1 != probe[i]; i++) {
 		c.addr = probe[i];
-		rc = i2c_master_recv(&c,&buf,0);
+		
+		/* Special case for MSI TV@nywhere Plus remote */
+		if (c.adapter->id == I2C_HW_SAA7134 && probe[i] == 0x30)
+		{
+			struct i2c_client c2;
+
+			memset (&c2, 0, sizeof(c2));
+			c2.adapter = c.adapter;
+
+			/* MSI TV@nywhere Plus' controller doesn't seem to
+			respond to probes unless we read something from an
+			existing device. Weird... */
+						
+			/* Find a device that responds. If none found, oh well. */
+			for (c2.addr=127; c2.addr >= 0; c2.addr--)
+			{
+				if (0 == i2c_master_recv(&c2,&buf,0))
+					break;
+			}
+
+			/* Now do the probe. The controller does not respond
+			   to 0-byte reads, so we use a 1-byte read instead. */
+			rc = i2c_master_recv(&c,&buf,1);
+			rc--;
+		}
+		else
+		{
+			rc = i2c_master_recv(&c,&buf,0);
+		}
+		
 		dprintk(1,"probe 0x%02x @ %s: %s\n",
 			probe[i], adap->name,
 			(0 == rc) ? "yes" : "no");


Script.png KWorld_Global_TV_Terminator remote_control_part3.patch

--- linux/drivers/media/video/saa7134/saa7134-cards.c.orig	2006-11-03 17:33:58.000000000 -0800
+++ linux/drivers/media/video/saa7134/saa7134-cards.c	2007-02-11 02:06:09.000000000 -0800
@@ -2560,8 +2560,8 @@
 			.gpio   = 0x0200000,
 		},
 	},
-	[SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = {
-		.name           = "MSI TV@Anywhere plus",
+	[SAA7134_BOARD_MSI_TVANYWHERE_PLUS] = {
+		.name           = "MSI TV@nywhere Plus",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_TDA8290,
 		.radio_type     = UNSET,
@@ -3360,7 +3360,7 @@
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x1462,
 		.subdevice    = 0x6231,
-		.driver_data  = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
+		.driver_data  = SAA7134_BOARD_MSI_TVANYWHERE_PLUS,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3601,6 +3601,7 @@
 	/* i2c remotes */
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
+	case SAA7134_BOARD_MSI_TVANYWHERE_PLUS:
 		dev->has_remote = SAA7134_REMOTE_I2C;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_A169_B:


Script.png KWorld_Global_TV_Terminator remote_control_part4.patch

--- linux/drivers/media/video/saa7134/saa7134-i2c.c.orig	2006-11-03 17:33:58.000000000 -0800
+++ linux/drivers/media/video/saa7134/saa7134-i2c.c	2007-02-11 02:06:09.000000000 -0800
@@ -341,6 +341,7 @@
 	switch (client->addr) {
 		case 0x7a:
 		case 0x47:
+		case 0x30:
 		{
 			struct IR_i2c *ir = i2c_get_clientdata(client);
 			d1printk("%s i2c IR detected (%s).\n",


Script.png KWorld_Global_TV_Terminator remote_control_part5.patch

--- linux/drivers/media/video/saa7134/saa7134.h.orig	2006-11-03 17:33:58.000000000 -0800
+++ linux/drivers/media/video/saa7134/saa7134.h	2007-02-11 02:06:09.000000000 -0800
@@ -209,7 +209,7 @@
 #define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS     79
 #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
 #define SAA7134_BOARD_PHILIPS_TIGER  81
-#define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS  82
+#define SAA7134_BOARD_MSI_TVANYWHERE_PLUS  82
 #define SAA7134_BOARD_CINERGY250PCI 83
 #define SAA7134_BOARD_FLYDVB_TRIO 84
 #define SAA7134_BOARD_AVERMEDIA_777 85

You can apply these by cd'ing to the /usr/src/linux-source-2.6.18-chw-13 directory and running:

# patch -p1 < remote_control_part1.patch
# patch -p1 < remote_control_part2.patch
# patch -p1 < remote_control_part3.patch
# patch -p1 < remote_control_part4.patch
# patch -p1 < remote_control_part5.patch

This patch is successful in getting events delivered from the remote control. However, they always had the same keycode on my system and were thus useless.

In order to fix this, I wrote a patch which is a total hack. It results in a remote control that mostly works. Some buttons don't work and keypresses don't always register, but it's usable. You can find the patch here:


Script.png KWorld_Global_TV_Terminator rc_hack.patch

--- linux/drivers/media/common/ir-functions.c.orig	2007-02-14 02:25:44.000000000 -0800
+++ linux/drivers/media/common/ir-functions.c	2007-02-20 20:33:31.000000000 -0800
@@ -44,13 +44,119 @@
 
 static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
 {
-	if (KEY_RESERVED == ir->keycode) {
-		printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n",
-		       dev->name,ir->ir_key,ir->ir_raw,ir->keypressed);
+	printk(KERN_INFO "%s: keycode=0x%02x key=0x%02x raw=0x%02x down=%d\n",
+	       dev->name, ir->keycode, ir->ir_key, ir->ir_raw, ir->keypressed);
+	/* ignore events from saa7134 IR (V-Stream Studio TV) */
+	if (ir->keycode == 0xa7) {
 		return;
 	}
-	dprintk(1,"%s: key event code=%d down=%d\n",
-		dev->name,ir->keycode,ir->keypressed);
+	/* translate events from i2c IR (KNC One) */
+	switch (ir->ir_key) {
+		case 0:
+			ir->keycode = KEY_RECORD;
+			break;		
+		case 1:
+			ir->keycode = KEY_KP1;
+			break;		
+		case 2:
+			ir->keycode = KEY_KP0;
+			break;		
+		case 3:
+			ir->keycode = KEY_RADIO;
+			break;		
+		case 4:
+			ir->keycode = KEY_BACK;
+			break;		
+		case 5:
+			ir->keycode = KEY_KP4;
+			break;		
+		case 6:
+			ir->keycode = KEY_KP7;
+			break;		
+		case 7:
+			ir->keycode = KEY_TUNER;
+			break;		
+		case 8:
+			ir->keycode = KEY_STOP;
+			break;		
+		case 9:
+			ir->keycode = KEY_KP5;
+			break;		
+		case 10:
+			ir->keycode = KEY_KP8;
+			break;		
+		case 11:
+			ir->keycode = KEY_KP2;
+			break;		
+		case 12:
+			ir->keycode = KEY_FORWARD;
+			break;		
+		case 13:
+			ir->keycode = KEY_LANGUAGE;
+			break;		
+		case 14:
+			ir->keycode = KEY_MENU;
+			break;		
+		case 15:
+			ir->keycode = KEY_CLOSE;
+			break;		
+		case 16:
+			ir->keycode = KEY_KPPLUS;
+			break;		
+		case 17:
+			ir->keycode = KEY_PLAY;
+			break;		
+		case 18:
+			ir->keycode = KEY_KP9;
+			break;		
+		case 19:
+			ir->keycode = KEY_AGAIN;
+			break;		
+		case 20:
+			ir->keycode = KEY_VOLUMEDOWN;
+			break;
+		case 21:
+			ir->keycode = KEY_KP6;
+			break;		
+		case 22:
+			ir->keycode = KEY_VOLUMEUP;
+			break;		
+		case 23:
+			ir->keycode = KEY_CHANNELDOWN;
+			break;		
+		case 24:
+			ir->keycode = KEY_MUTE;
+			break;		
+		case 25:
+			ir->keycode = KEY_ZOOM;
+			break;		
+		case 26:
+			ir->keycode = KEY_SHUFFLE;
+			break;		
+		case 27:
+			ir->keycode = KEY_KP3;
+			break;		
+		case 28:
+			ir->keycode = KEY_SEARCH;
+			break;		
+		case 29:
+			ir->keycode = KEY_RESTART;
+			break;		
+		case 30:
+			ir->keycode = KEY_POWER;
+			break;
+		case 31:
+			ir->keycode = KEY_CHANNELUP;
+			break;
+		default:
+			/* keycode that noone should expect from this remote */
+			ir->keycode = KEY_PROPS;
+			break;
+	}
+	/* make sure that input layer does not discard event */
+	set_bit(EV_KEY, dev->evbit);
+	set_bit(ir->keycode, dev->keybit);
+	/* send event to input event core */
 	input_report_key(dev,ir->keycode,ir->keypressed);
 	input_sync(dev);
 }

Note that this patch hacks part of the infrared subsystem, so you may want to be especially wary of using it if you have other infrared devices.

Apply this patch the same way you did the other patches:

# patch -p1 < rc_hack.patch

Now you'll need to recompile the kernel modules, but before you do this, you should backup your current modules (located in /lib/modules/2.6.18-chw-13). One way to do this is to move this directory to 2.6.18-chw-13.old . That way, restoring the modules is simply a matter of renaming it back.

Now go into /usr/src/linux-source-2.6.18-chw-13 and type "make menuconfig".

Scoll down and select "load an alternate configuration file".

Specify the file "/boot/config-2.6.18-chw-13".

Save and exit.

Compile the modules and install them in /lib/modules/2.6.18-chw-13 by typing "make modules && make modules_install".

Now run "depmod" to generate symbol information in the /lib/modules/2.6.18-chw-13 directory.

Go ahead and reboot. The modules important to the remote control should be automatically loaded by KnoppMyth.

If everything goes well you should be able to open a terminal, press the 1 key on your remote and see a 1 appear in the terminal (make sure that num lock is on).

You'll now have the following keys working and generating the following X keycodes:

power 222
scan 229
mute 160
recall 133
stop 232
play 179
<< 234
function 158
>> 233
vol+ 176
vol- 174
minimize 175
1 87
2 88
3 89
4 83
5 84
6 85
7 79
8 80
9 81
0 90
+ 86

In order for mythtv to make sense of these keys, you'll want to use xmodmap to map the keycodes to well-known keysyms. To do this, you need to create a file called /home/mythtv/.Xmodmap and you need to run "xmodmap /home/mythtv/.Xmodmap" every time X starts.

My .Xmodmap looks like this:

! power
keycode 222 = F1
! scan
keycode 229 = F2
! mute
keycode 160 = F3
! recall
keycode 133 = F4
! stop
keycode 232 = F5
! play
keycode 179 = F6
! <<
keycode 234 = F7
! function
keycode 158 = F8
! >>
keycode 233 = F9
! vol+
keycode 176 = F10
! vol-
keycode 174 = F11
! min
!keycode 175 = F12
keycode 175 = Return

! keypad
keycode 81 = 9
keycode 80 = 8
keycode 79 = 7
keycode 85 = 6
keycode 84 = 5
keycode 83 = 4
keycode 89 = 3
keycode 88 = 2
keycode 87 = 1
keycode 90 = 0
! plus
keycode 86 = equal

To get xmodmap to run every time X starts, I added the following line to /home/mythtv/.fluxbox/apps after the line "[startup] {xset -dpms s off}":

[startup] {xmodmap ~/.Xmodmap}

Now restart X to get the new mappings to load (ctrl-alt-backspace should do the trick).

mythtv should recognize the keys as if you pressed the corresponding key on the keyboard (Utilities/Setup->Edit Keys is where you bind keys to functions in mythtv BTW).

Resources