All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] TV Anywhere remote
@ 2008-07-14 10:39 Brian Rogers
  0 siblings, 0 replies; only message in thread
From: Brian Rogers @ 2008-07-14 10:39 UTC (permalink / raw)
  To: video4linux-list

[-- Attachment #1: Type: text/plain, Size: 547 bytes --]

This is an update to the older patch by Henry Wong and Mark Schultz to 
make the remote work on the TV@nywhere Plus.

Aside from getting this working on a modern kernel, I also moved the 
special-case probing code for this card outside the probing loop in 
ir_probe to the end of the routine, since it seemed cleaner that way. 
The one possible remaining issue I see is the use of the global variable 
polling_interval, which gets set to a shorter value when this IR chip is 
detected. It should be harmless, but it seems a bit iffy, style-wise.


[-- Attachment #2: tvanywhere-remote.diff --]
[-- Type: text/x-patch, Size: 10402 bytes --]

diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index 8fa91f8..b15583f 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -467,7 +467,8 @@ EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci);
 
 /* ---------------------------------------------------------------------- */
 
-/* MSI TV@nywhere remote */
+/* MSI TV@nywhere MASTER remote */
+
 IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
 	/* Keys 0 to 9 */
 	[ 0x00 ] = KEY_0,
@@ -501,6 +502,96 @@ EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere);
 
 /* ---------------------------------------------------------------------- */
 
+/*
+  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...
+
+  Note: This remote may be of similar or identical design to the
+  Pixelview remote (?).  The raw codes and duplicate button codes
+  appear to be the same.
+
+  Henry Wong <henry@stuffedcow.net>
+  Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
+
+*/
+
+IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = {
+
+/*  ---- Remote Button Layout ----
+
+    POWER   SOURCE  SCAN    MUTE
+    TV/FM   1       2       3
+    |>      4       5       6
+    <|      7       8       9
+    ^^UP    0       +       RECALL
+    vvDN    RECORD  STOP    PLAY
+
+        MINIMIZE          ZOOM
+
+                  CH+
+      VOL-                   VOL+
+                  CH-
+
+        SNAPSHOT           MTS
+
+     <<      FUNC    >>     RESET
+*/
+
+	[ 0x01 ] = KEY_KP1,             /* 1 */
+	[ 0x0B ] = KEY_KP2,             /* 2 */
+	[ 0x1B ] = KEY_KP3,             /* 3 */
+	[ 0x05 ] = KEY_KP4,             /* 4 */
+	[ 0x09 ] = KEY_KP5,             /* 5 */
+	[ 0x15 ] = KEY_KP6,             /* 6 */
+	[ 0x06 ] = KEY_KP7,             /* 7 */
+	[ 0x0A ] = KEY_KP8,             /* 8 */
+	[ 0x12 ] = KEY_KP9,             /* 9 */
+	[ 0x02 ] = KEY_KP0,             /* 0 */
+	[ 0x10 ] = KEY_KPPLUS,          /* + */
+	[ 0x13 ] = KEY_AGAIN,           /* Recall */
+
+	[ 0x1E ] = KEY_POWER,           /* Power */
+	[ 0x07 ] = KEY_TUNER,           /* Source */
+	[ 0x1C ] = KEY_SEARCH,          /* Scan */
+	[ 0x18 ] = KEY_MUTE,            /* Mute */
+
+	[ 0x03 ] = KEY_RADIO,           /* TV/FM */
+	/* The next four keys are duplicates that appear to send the
+	   same IR code as Ch+, Ch-, >>, and << .  The raw code assigned
+	   to them is the actual code + 0x20 - they will never be
+	   detected as such unless some way is discovered to distinguish
+	   these buttons from those that have the same code. */
+	[ 0x3F ] = KEY_RIGHT,           /* |> and Ch+ */
+	[ 0x37 ] = KEY_LEFT,            /* <| and Ch- */
+	[ 0x2C ] = KEY_UP,              /* ^^Up and >> */
+	[ 0x24 ] = KEY_DOWN,            /* vvDn and << */
+
+	[ 0x00 ] = KEY_RECORD,          /* Record */
+	[ 0x08 ] = KEY_STOP,            /* Stop */
+	[ 0x11 ] = KEY_PLAY,            /* Play */
+
+	[ 0x0F ] = KEY_CLOSE,           /* Minimize */
+	[ 0x19 ] = KEY_ZOOM,            /* Zoom */
+	[ 0x1A ] = KEY_SHUFFLE,         /* Snapshot */
+	[ 0x0D ] = KEY_LANGUAGE,        /* MTS */
+
+	[ 0x14 ] = KEY_VOLUMEDOWN,      /* Vol- */
+	[ 0x16 ] = KEY_VOLUMEUP,        /* Vol+ */
+	[ 0x17 ] = KEY_CHANNELDOWN,     /* Ch- */
+	[ 0x1F ] = KEY_CHANNELUP,       /* Ch+ */
+
+	[ 0x04 ] = KEY_REWIND,          /* << */
+	[ 0x0E ] = KEY_MENU,            /* Function */
+	[ 0x0C ] = KEY_FASTFORWARD,     /* >> */
+	[ 0x1D ] = KEY_RESTART,         /* Reset */
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus);
+
+/* ---------------------------------------------------------------------- */
+
 /* Cinergy 1400 DVB-T */
 IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
 	[ 0x01 ] = KEY_POWER,
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 7b65f5e..d22a2ac 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -12,6 +12,10 @@
  *      Markus Rechberger <mrechberger@gmail.com>
  * modified for DViCO Fusion HDTV 5 RT GOLD by
  *      Chaogui Zhang <czhang1974@gmail.com>
+ * modified for MSI TV@nywhere Plus by
+ *      Henry Wong <henry@stuffedcow.net>
+ *      Mark Schultz <n9xmj@yahoo.com>
+ *      Brian Rogers <brian_rogers@comcast.net>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -59,6 +63,8 @@ MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults
 #define dprintk(level, fmt, arg...)	if (debug >= level) \
 	printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
 
+static int polling_interval = 100;     /* Milliseconds */
+
 /* ----------------------------------------------------------------------- */
 
 static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
@@ -308,7 +314,7 @@ static void ir_work(struct work_struct *work)
 	struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
 
 	ir_key_poll(ir);
-	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100));
+	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval));
 }
 
 /* ----------------------------------------------------------------------- */
@@ -387,6 +393,8 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
 		ir->get_key = get_key_knc1;
 		ir_type     = IR_TYPE_OTHER;
 		ir_codes    = ir_codes_empty;
+		if (adap->id == I2C_HW_SAA7134) /* Handled by saa7134-input */
+			polling_interval = 50;  /* mS */
 		break;
 	case 0x6b:
 		name        = "FusionHDTV";
@@ -547,9 +555,39 @@ static int ir_probe(struct i2c_adapter *adap)
 			(1 == rc) ? "yes" : "no");
 		if (1 == rc) {
 			ir_attach(adap, probe[i], 0, 0);
-			break;
+			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... */
+
+		/* Find a device that responds. If none found, oh well. */
+		for (msg.addr = 0x7F; msg.addr > 0; msg.addr--)
+		{
+			if (1 == i2c_transfer(adap, &msg, 1))
+				break;
+		}
+
+		/* 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);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 2618cfa..eb524b3 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5598,6 +5598,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
+	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
 	case SAA7134_BOARD_BEHOLD_607_9FM:
 	case SAA7134_BOARD_BEHOLD_M6:
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index d8af386..cd9c46f 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -335,6 +335,7 @@ static int attach_inform(struct i2c_client *client)
 		case 0x47:
 		case 0x71:
 		case 0x2d:
+		case 0x30:
 		{
 			struct IR_i2c *ir = i2c_get_clientdata(client);
 			d1printk("%s i2c IR detected (%s).\n",
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 76e6501..e5b106a 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -115,6 +115,52 @@ static int build_key(struct saa7134_dev *dev)
 
 /* --------------------- 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;
+
+	/* <dev> is needed to access GPIO. Used by the saa_readl macro. */
+	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");
+		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("get_key_msi_tvanywhere_plus: 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%02X\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)
 {
 	unsigned char b;
@@ -533,6 +579,11 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
 		ir->get_key   = get_key_purpletv;
 		ir->ir_codes  = ir_codes_purpletv;
 		break;
+	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
+		snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus");
+		ir->get_key  = get_key_msi_tvanywhere_plus;
+		ir->ir_codes = ir_codes_msi_tvanywhere_plus;
+		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
 		snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110");
 		ir->get_key   = get_key_hvr1110;
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index b8e8aa9..e70362b 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -147,6 +147,7 @@ extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE];
 
 #endif
 

[-- Attachment #3: Type: text/plain, Size: 164 bytes --]

--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2008-07-14 10:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-14 10:39 [PATCH] TV Anywhere remote Brian Rogers

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.