public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Brian Rogers <brian_rogers@comcast.net>
To: video4linux-list@redhat.com
Cc: Henry Wong <henry@stuffedcow.net>, Mark Schultz <n9xmj@yahoo.com>,
	Mauro Carvalho Chehab <mchehab@infradead.org>
Subject: [PATCH] Add support for MSI TV@nywhere Plus remote
Date: Mon, 08 Sep 2008 03:19:11 -0700	[thread overview]
Message-ID: <48C4FC1F.40509@comcast.net> (raw)

I've been carrying this patch, originally by Henry Wong, for a while. 
Here's the latest version, based off the linux master branch. I think 
it's ready for inclusion.

Rather than going on a probing spree, as in the previous version, I just 
probe a single address that's known to respond (0x50) as the workaround 
for the controller quirk. Also, the polling interval is no longer 
handled globally.

---

Add support for the MSI TV@nywhere Plus remote

The IR controller has a couple quirks. It won't respond until some other
device on the bus is probed. To work around that, probe 0x50 first.
Then, since it won't respond to a zero-byte read, probe with a one-byte 
read.

Signed-off-by: Brian Rogers <brian_rogers@comcast.net>

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 a30254b..ee9dd8e 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
@@ -224,9 +228,15 @@ static void ir_timer(unsigned long data)
 static void ir_work(struct work_struct *work)
 {
     struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
+    int polling_interval = 100;
+
+    /* MSI TV@nywhere Plus requires more frequent polling
+       otherwise it will miss some keypresses */
+    if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30)
+        polling_interval = 50;
 
     ir_key_poll(ir);
-    mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100));
+    mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval));
 }
 
 /* 
----------------------------------------------------------------------- */
@@ -465,9 +475,37 @@ 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... */
+
+        msg.addr = 0x50;
+        rc = i2c_transfer(adap, &msg, 1);
+        dprintk(1,"probe 0x%02x @ %s: %s\n",
+            msg.addr, adap->name,
+            (1 == rc) ? "yes" : "no");
+
+        /* 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 98364d1..e8f4589 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5745,6 +5745,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 5f713e6..926e898 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -337,6 +337,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 ad08d13..aeb85d7 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 != i2c_master_recv(&ir->c, &b, 1)) {
+        i2cdprintk("read error\n");
+        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;
@@ -612,6 +658,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
 

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

             reply	other threads:[~2008-09-08 10:19 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-08 10:19 Brian Rogers [this message]
     [not found] ` <20080911103801.52629349@mchehab.chehab.org>
2008-09-11 21:14   ` [PATCH] Add support for MSI TV@nywhere Plus remote Brian Rogers
2008-09-14  2:35   ` hermann pitton
2008-09-15  4:26     ` Mauro Carvalho Chehab
2008-09-15 21:53       ` hermann pitton
2008-10-13 11:33       ` Brian Rogers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48C4FC1F.40509@comcast.net \
    --to=brian_rogers@comcast.net \
    --cc=henry@stuffedcow.net \
    --cc=mchehab@infradead.org \
    --cc=n9xmj@yahoo.com \
    --cc=video4linux-list@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox