
From: Gerd Knorr <kraxel@bytesex.org>

This patch updates the ir-kbd-gpio and ir-kbd-i2c drivers.  Nothing major,
just some keytable fixes and support for more hardware.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/media/video/ir-kbd-gpio.c |   82 ++++++++++----------
 25-akpm/drivers/media/video/ir-kbd-i2c.c  |  122 ++++++++++++++++++++++++++----
 2 files changed, 147 insertions(+), 57 deletions(-)

diff -puN drivers/media/video/ir-kbd-gpio.c~v4l-ir-input-driver-update drivers/media/video/ir-kbd-gpio.c
--- 25/drivers/media/video/ir-kbd-gpio.c~v4l-ir-input-driver-update	2004-06-19 13:58:33.626705840 -0700
+++ 25-akpm/drivers/media/video/ir-kbd-gpio.c	2004-06-19 13:58:33.633704776 -0700
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (c) 2003 Gerd Knorr
  * Copyright (c) 2003 Pavel Machek
@@ -32,47 +33,45 @@
 /* ---------------------------------------------------------------------- */
 
 static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
-	[ 17 ] = KEY_KP0, 
-	[ 20 ] = KEY_KP1, 
-	[ 12 ] = KEY_KP2, 
-	[ 28 ] = KEY_KP3, 
-	[ 18 ] = KEY_KP4, 
-	[ 10 ] = KEY_KP5, 
-	[ 26 ] = KEY_KP6, 
-	[ 22 ] = KEY_KP7, 
-	[ 14 ] = KEY_KP8, 
-	[ 30 ] = KEY_KP9, 
+	[ 34 ] = KEY_KP0,
+	[ 40 ] = KEY_KP1,
+	[ 24 ] = KEY_KP2,
+	[ 56 ] = KEY_KP3,
+	[ 36 ] = KEY_KP4,
+	[ 20 ] = KEY_KP5,
+	[ 52 ] = KEY_KP6,
+	[ 44 ] = KEY_KP7,
+	[ 28 ] = KEY_KP8,
+	[ 60 ] = KEY_KP9,
 
-	[ 24 ] = KEY_EJECTCD,     // Unmarked on my controller
+	[ 48 ] = KEY_EJECTCD,     // Unmarked on my controller
 	[  0 ] = KEY_POWER, 
-	[  9 ] = BTN_LEFT,        // DISPLAY/L
-	[ 25 ] = BTN_RIGHT,       // LOOP/R
-	[  5 ] = KEY_MUTE, 
-	[ 19 ] = KEY_RECORD, 
-	[ 11 ] = KEY_PAUSE, 
-	[ 27 ] = KEY_STOP, 
-	[ 15 ] = KEY_VOLUMEDOWN, 
-	[ 31 ] = KEY_VOLUMEUP, 
-
-	[ 16 ] = KEY_TUNER,       // TV/FM
-	[  8 ] = KEY_CD, 
-	[  4 ] = KEY_VIDEO, 
-	[  2 ] = KEY_AUDIO, 
-	[  6 ] = KEY_ZOOM,        // full screen
-	[  1 ] = KEY_INFO,        // preview 
-	[ 21 ] = KEY_SEARCH,      // autoscan
-	[ 13 ] = KEY_STOP,        // freeze 
-	[ 29 ] = KEY_RECORD,      // capture 
-	[  3 ] = KEY_PLAY,        // unmarked
-	[ 23 ] = KEY_RED,         // unmarked
-	[  7 ] = KEY_GREEN,       // unmarked
-
-#if 0
-	[ 16 ] = KEY_YELLOW,      // unmarked
-	[  8 ] = KEY_CHANNELDOWN, 
-	[ 24 ] = KEY_CHANNELUP, 
-	[  0 ] = KEY_BLUE,        // unmarked
-#endif
+	[ 18 ] = BTN_LEFT,        // DISPLAY/L
+	[ 50 ] = BTN_RIGHT,       // LOOP/R
+	[ 10 ] = KEY_MUTE,
+	[ 38 ] = KEY_RECORD,
+	[ 22 ] = KEY_PAUSE,
+	[ 54 ] = KEY_STOP,
+	[ 30 ] = KEY_VOLUMEDOWN,
+	[ 62 ] = KEY_VOLUMEUP,
+
+	[ 32 ] = KEY_TUNER,       // TV/FM
+	[ 16 ] = KEY_CD,
+	[  8 ] = KEY_VIDEO,
+	[  4 ] = KEY_AUDIO,
+	[ 12 ] = KEY_ZOOM,        // full screen
+	[  2 ] = KEY_INFO,        // preview
+	[ 42 ] = KEY_SEARCH,      // autoscan
+	[ 26 ] = KEY_STOP,        // freeze
+	[ 58 ] = KEY_RECORD,      // capture
+	[  6 ] = KEY_PLAY,        // unmarked
+	[ 46 ] = KEY_RED,         // unmarked
+	[ 14 ] = KEY_GREEN,       // unmarked
+
+	[ 33 ] = KEY_YELLOW,      // unmarked
+	[ 17 ] = KEY_CHANNELDOWN,
+	[ 49 ] = KEY_CHANNELUP,
+	[  1 ] = KEY_BLUE,        // unmarked
 };
 
 static IR_KEYTAB_TYPE winfast_codes[IR_KEYTAB_SIZE] = {
@@ -280,8 +279,9 @@ static int ir_probe(struct device *dev)
 	case BTTV_AVPHONE98:
 	case BTTV_AVERMEDIA98:
 		ir_codes         = ir_codes_avermedia;
-		ir->mask_keycode = 0xf80000;
+		ir->mask_keycode = 0xf88000;
 		ir->mask_keydown = 0x010000;
+		ir->polling      = 50; // ms
 		break;
 
 	case BTTV_PXELVWPLTVPAK:
@@ -300,7 +300,7 @@ static int ir_probe(struct device *dev)
 
 	case BTTV_WINFAST2000:
 		ir_codes         = winfast_codes;
-		ir->mask_keycode = 0x8f8;
+		ir->mask_keycode = 0x1f8;
 		break;
 	case BTTV_MAGICTVIEW061:
 	case BTTV_MAGICTVIEW063:
diff -puN drivers/media/video/ir-kbd-i2c.c~v4l-ir-input-driver-update drivers/media/video/ir-kbd-i2c.c
--- 25/drivers/media/video/ir-kbd-i2c.c~v4l-ir-input-driver-update	2004-06-19 13:58:33.628705536 -0700
+++ 25-akpm/drivers/media/video/ir-kbd-i2c.c	2004-06-19 13:58:33.634704624 -0700
@@ -77,6 +77,56 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_
 	[ 15 ] = KEY_SELECT, 		// SOURCE
 	[ 10 ] = KEY_KPPLUS,		// +100
 	[ 20 ] = KEY_KPEQUAL,		// SYNC
+	[ 28 ] = KEY_MEDIA,             // PC/TV
+};
+
+static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
+	[ 0x3  ] = KEY_POWER,
+	[ 0x6f ] = KEY_MUTE,
+	[ 0x10 ] = KEY_BACKSPACE,	// Recall
+
+	[ 0x11 ] = KEY_KP0,
+	[ 0x4  ] = KEY_KP1,
+	[ 0x5  ] = KEY_KP2,
+	[ 0x6  ] = KEY_KP3,
+	[ 0x8  ] = KEY_KP4,
+	[ 0x9  ] = KEY_KP5,
+	[ 0xa  ] = KEY_KP6,
+	[ 0xc  ] = KEY_KP7,
+	[ 0xd  ] = KEY_KP8,
+	[ 0xe  ] = KEY_KP9,
+	[ 0x12 ] = KEY_KPDOT,		// 100+
+
+	[ 0x7  ] = KEY_VOLUMEUP,
+	[ 0xb  ] = KEY_VOLUMEDOWN,
+	[ 0x1a ] = KEY_KPPLUS,
+	[ 0x18 ] = KEY_KPMINUS,
+	[ 0x15 ] = KEY_UP,
+	[ 0x1d ] = KEY_DOWN,
+	[ 0xf  ] = KEY_CHANNELUP,
+	[ 0x13 ] = KEY_CHANNELDOWN,
+	[ 0x48 ] = KEY_ZOOM,
+
+	[ 0x1b ] = KEY_VIDEO,		// Video source
+#if 0
+	[ 0x1f ] = KEY_S,       	// Snapshot
+#endif
+	[ 0x49 ] = KEY_LANGUAGE,	// MTS Select
+	[ 0x19 ] = KEY_SEARCH,		// Auto Scan
+
+	[ 0x4b ] = KEY_RECORD,
+	[ 0x46 ] = KEY_PLAY,
+	[ 0x45 ] = KEY_PAUSE,   	// Pause
+	[ 0x44 ] = KEY_STOP,
+#if 0
+	[ 0x43 ] = KEY_T,    		// Time Shift
+	[ 0x47 ] = KEY_Y,    		// Time Shift OFF
+	[ 0x4a ] = KEY_O,    		// TOP
+	[ 0x17 ] = KEY_F,    		// SURF CH
+#endif
+	[ 0x40 ] = KEY_FORWARD,   	// Forward ?
+	[ 0x42 ] = KEY_REWIND,   	// Backward ?
+
 };
 
 struct IR;
@@ -202,11 +252,33 @@ static int get_key_knc1(struct IR *ir, u
 	return 1;
 }
 
+static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
+{
+        unsigned char b;
+
+	/* poll IR chip */
+	if (1 != i2c_master_recv(&ir->c,&b,1)) {
+		dprintk(1,"read error\n");
+		return -EIO;
+	}
+
+	/* no button press */
+	if (b==0)
+		return 0;
+
+	/* repeating */
+	if (b & 0x80)
+		return 1;
+
+	*ir_key = b;
+	*ir_raw = b;
+	return 1;
+}
 /* ----------------------------------------------------------------------- */
 
 static void ir_key_poll(struct IR *ir)
 {
-	u32 ir_key, ir_raw;
+	static u32 ir_key, ir_raw;
 	int rc;
 
 	dprintk(2,"ir_poll_key\n");
@@ -300,6 +372,12 @@ static int ir_attach(struct i2c_adapter 
 		ir_type     = IR_TYPE_OTHER;
 		ir_codes    = ir_codes_empty;
 		break;
+	case 0x7a:
+		name        = "Purple TV";
+		ir->get_key = get_key_purpletv;
+		ir_type     = IR_TYPE_OTHER;
+		ir_codes    = ir_codes_purpletv;
+		break;
 	default:
 		/* shouldn't happen */
 		printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
@@ -320,7 +398,8 @@ static int ir_attach(struct i2c_adapter 
 	ir->input.name       = ir->c.name;
 	ir->input.phys       = ir->phys;
 	input_register_device(&ir->input);
-	printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
+	printk(DEVNAME ": %s detected at %s [%s]\n",
+	       ir->input.name,ir->input.phys,adap->name);
 	       
 	/* start polling via eventd */
 	INIT_WORK(&ir->work, ir_work, ir);
@@ -361,22 +440,33 @@ static int ir_probe(struct i2c_adapter *
 	   That's why we probe 0x1a (~0x34) first. CB 
 	*/
 	
-	static const int probe[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
+	static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
+	static const int probe_saa7134[] = { 0x7a, -1};
+	const int *probe = NULL;
 	struct i2c_client c; char buf; int i,rc;
 
-	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) {
-		memset(&c,0,sizeof(c));
-		c.adapter = adap;
-		for (i = 0; -1 != probe[i]; i++) {
-			c.addr = probe[i];
-			rc = i2c_master_recv(&c,&buf,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);
-				break;
-			}
+	switch (adap->id) {
+	case I2C_ALGO_BIT | I2C_HW_B_BT848:
+		probe = probe_bttv;
+		break;
+	case I2C_ALGO_SAA7134:
+		probe = probe_saa7134;
+		break;
+	}
+	if (NULL == probe)
+		return 0;
+
+	memset(&c,0,sizeof(c));
+	c.adapter = adap;
+	for (i = 0; -1 != probe[i]; i++) {
+		c.addr = probe[i];
+		rc = i2c_master_recv(&c,&buf,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);
+			break;
 		}
 	}
 	return 0;
_
