Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
The problem is that no IR device gets registered during the process and
as a result, no input device is created. However, lsmod | grep tells
that IR modules are loaded:
Interesting question! My TV card's IR remote doesn't work either. Until now, I never bothered to fix it as I don't really need it. You have just given me a task to occupy my time over the weekend.
I checked my /proc/modules and I have the ir_common but not the ir_kbd_i2c.
I'll get to work on it.
I had sent the same message to the lirc list. Jonathon Ison replied me telling that there's a patch here which has not been applied to kernel yet. The patch was badly broken on the list due to line wraps, but thankfully he had a working copy of it which can be found below:
Code:
diff -uprN /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/common/ir-keymaps.c ./linux/drivers/media/common/ir-keymaps.c
--- /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/common/ir-keymaps.c 2006-11-28 20:23:19.432845499 -0600
+++ ./linux/drivers/media/common/ir-keymaps.c 2006-12-14 13:05:48.773675341 -0600
@@ -424,7 +424,8 @@ EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t
/* ---------------------------------------------------------------------- */
-/* 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,
@@ -458,6 +459,99 @@ EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywher
/* ---------------------------------------------------------------------- */
+
+/*
+ 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 at stuffedcow.net>
+ Some changes to formatting and keycodes by Mark Schultz <n9xmj at 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 -uprN /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c ./linux/drivers/media/video/ir-kbd-i2c.c
--- /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/ir-kbd-i2c.c 2006-12-08 12:41:58.633768048 -0600
+++ ./linux/drivers/media/video/ir-kbd-i2c.c 2006-12-14 13:04:18.323675341 -0600
@@ -10,6 +10,9 @@
* Ulrich Mueller <ulrich.mueller42@web.de>
* modified for em2820 based USB TV tuners by
* Markus Rechberger <mrechberger@gmail.com>
+ * modified for MSI TV at nywhere Plus by
+ * Henry Wong <henry at stuffedcow.net>
+ * Mark Schultz <n9xmj at yahoo.com>
*
* 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
@@ -60,6 +63,8 @@ MODULE_PARM_DESC(hauppauge, "Specify Hau
#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(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
@@ -273,7 +278,7 @@ static void ir_work(void *data)
{
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);
}
/* ----------------------------------------------------------------------- */
@@ -360,6 +365,8 @@ static int ir_attach(struct i2c_adapter
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 0x7a:
case 0x47:
@@ -458,7 +465,7 @@ static int ir_probe(struct i2c_adapter *
*/
static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
- static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 };
+ static const int probe_saa7134[] = { 0x7a, 0x47, 0x71,0x30, -1 };
static const int probe_em28XX[] = { 0x30, 0x47, -1 };
const int *probe = NULL;
struct i2c_client c;
@@ -486,7 +493,41 @@ static int ir_probe(struct i2c_adapter *
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 = 0x7F; 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");
diff -uprN /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134-cards.c ./linux/drivers/media/video/saa7134/saa7134-cards.c
--- /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134-cards.c 2006-12-08 12:41:58.653768049 -0600
+++ ./linux/drivers/media/video/saa7134/saa7134-cards.c 2006-12-14 12:55:51.403675340 -0600
@@ -2564,7 +2564,7 @@ struct saa7134_board saa7134_boards[] =
.gpio = 0x0200000,
},
},
- [SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = {
+ [SAA7134_BOARD_MSI_TVANYWHERE_PLUS] = {
.name = "MSI TV@Anywhere plus",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_TDA8290,
@@ -3686,7 +3686,13 @@ struct pci_device_id saa7134_pci_tbl[] =
.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,
+ .subvendor = 0x1462,
+ .subdevice = 0x8624, /* Alternate devid, same board? */
+ .driver_data = SAA7134_BOARD_MSI_TVANYWHERE_PLUS,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -4059,6 +4065,7 @@ int saa7134_board_init1(struct saa7134_d
case SAA7134_BOARD_PINNACLE_PCTV_110i:
case SAA7134_BOARD_PINNACLE_PCTV_310i:
case SAA7134_BOARD_UPMOST_PURPLE_TV:
+ case SAA7134_BOARD_MSI_TVANYWHERE_PLUS:
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
dev->has_remote = SAA7134_REMOTE_I2C;
break;
diff -uprN /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134-i2c.c ./linux/drivers/media/video/saa7134/saa7134-i2c.c
--- /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134-i2c.c 2006-12-08 12:41:58.653768049 -0600
+++ ./linux/drivers/media/video/saa7134/saa7134-i2c.c 2006-12-14 12:55:51.403675340 -0600
@@ -352,6 +352,7 @@ static int attach_inform(struct i2c_clie
case 0x7a:
case 0x47:
case 0x71:
+ case 0x30:
{
struct IR_i2c *ir = i2c_get_clientdata(client);
d1printk("%s i2c IR detected (%s).\n",
diff -uprN /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134-input.c ./linux/drivers/media/video/saa7134/saa7134-input.c
--- /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134-input.c 2006-12-08 12:41:58.663768049 -0600
+++ ./linux/drivers/media/video/saa7134/saa7134-input.c 2006-12-14 12:55:51.423675340 -0600
@@ -90,6 +90,53 @@ static int build_key(struct saa7134_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;
@@ -399,6 +446,11 @@ void saa7134_set_i2c_ir(struct saa7134_d
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 = 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 -uprN /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134.h ./linux/drivers/media/video/saa7134/saa7134.h
--- /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/drivers/media/video/saa7134/saa7134.h 2006-11-28 20:23:20.652845506 -0600
+++ ./linux/drivers/media/video/saa7134/saa7134.h 2006-12-14 12:55:51.423675340 -0600
@@ -217,7 +217,7 @@ struct saa7134_format {
#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
diff -uprN /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/include/media/ir-common.h ./linux/include/media/ir-common.h
--- /home/portage/distfiles/hg-src/v4l-dvb-hg/v4l-dvb/linux/include/media/ir-common.h 2006-11-28 20:23:20.982845500 -0600
+++ ./linux/include/media/ir-common.h 2006-12-14 12:55:51.443675341 -0600
@@ -92,6 +92,7 @@ extern IR_KEYTAB_TYPE ir_codes_hauppauge
extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE];
#endif
After applying the patch and re-building the modules, I can see the IR remote in /proc/bus/input/devices. However, irw doesn't capture any keys even when lircd is started with right parameters.
The patch was still creating problems when applied to a recent kernel so I made some changes by hand and created a diff file in the end for other people. Here is it (if LQ has support for attachments, at least I can't find it easily).
The diff file can be applied to the most recent stable kernels (e.g. 2.6.19.1). It is _supposed_ to solve the problem. However, I can't confirm it yet as I'm currently rebuilding my kernel.
I'll provide more feedback soon.
EDIT: Same story. Device gets recognized but irw doesn't get any input when keys are pressed on the remote.
Last edited by kamran_pro; 12-15-2006 at 01:47 PM.
Device gets recognized but irw doesn't get any input when keys are pressed on the remote.
kamran_pro, thanks for finding that patch! I was noticing the same thing on my MSI TV@nywhere Plus card; that no IR was being detected. I took your 2.6.19 patch and applied it to the newest stock debian kernel (as a cutom build) with some minor fix ups for the difference in files. I was then able to get the IR working perfectly with MythTV after messing around with my lirc config files. I would recommend the inputlirc daemon instead as it's pretty much automatic, so it only requires per app config. If I press the Function key for example it returns KEY_MENU (or the value defined by the saa7134 driver). I will attach the patch as text for anyone who is interested and might be using debian.
Code:
diff -urN linux-source-2.6.18.orig/drivers/media/common/ir-keymaps.c linux-source-2.6.18/drivers/media/common/ir-keymaps.c
--- linux-source-2.6.18.orig/drivers/media/common/ir-keymaps.c 2007-01-20 08:56:41.000000000 -0800
+++ linux-source-2.6.18/drivers/media/common/ir-keymaps.c 2007-01-20 08:57:52.000000000 -0800
@@ -392,7 +392,8 @@
/* ---------------------------------------------------------------------- */
-/* 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,
@@ -426,6 +427,99 @@
/* ---------------------------------------------------------------------- */
+
+/*
+ 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 at stuffedcow.net>
+ Some changes to formatting and keycodes by Mark Schultz <n9xmj at 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 -urN linux-source-2.6.18.orig/drivers/media/video/ir-kbd-i2c.c linux-source-2.6.18/drivers/media/video/ir-kbd-i2c.c
--- linux-source-2.6.18.orig/drivers/media/video/ir-kbd-i2c.c 2007-01-20 08:56:39.000000000 -0800
+++ linux-source-2.6.18/drivers/media/video/ir-kbd-i2c.c 2007-01-20 08:57:52.000000000 -0800
@@ -10,6 +10,9 @@
* Ulrich Mueller <ulrich.mueller42@web.de>
* modified for em2820 based USB TV tuners by
* Markus Rechberger <mrechberger@gmail.com>
+ * modified for MSI TV at nywhere Plus by
+ * Henry Wong <henry at stuffedcow.net>
+ * Mark Schultz <n9xmj at yahoo.com>
*
* 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 +62,8 @@
#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(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
@@ -263,7 +268,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);
}
/* ----------------------------------------------------------------------- */
@@ -343,6 +348,8 @@
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 0x7a:
case 0x47:
@@ -430,7 +437,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, 0x71,0x30, -1 };
static const int probe_em28XX[] = { 0x30, 0x47, -1 };
const int *probe = NULL;
struct i2c_client c;
@@ -458,7 +465,41 @@
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 = 0x7F; 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");
diff -urN linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134-cards.c linux-source-2.6.18/drivers/media/video/saa7134/saa7134-cards.c
--- linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134-cards.c 2007-01-20 08:56:41.000000000 -0800
+++ linux-source-2.6.18/drivers/media/video/saa7134/saa7134-cards.c 2007-01-20 08:57:52.000000000 -0800
@@ -2560,7 +2560,7 @@
.gpio = 0x0200000,
},
},
- [SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = {
+ [SAA7134_BOARD_MSI_TVANYWHERE_PLUS] = {
.name = "MSI TV@Anywhere plus",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_TDA8290,
@@ -3360,7 +3360,13 @@
.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,
+ .subvendor = 0x1462,
+ .subdevice = 0x8624, /* Alternate devid, same board? */
+ .driver_data = SAA7134_BOARD_MSI_TVANYWHERE_PLUS,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3601,6 +3607,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:
diff -urN linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134.h linux-source-2.6.18/drivers/media/video/saa7134/saa7134.h
--- linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134.h 2007-01-20 08:56:41.000000000 -0800
+++ linux-source-2.6.18/drivers/media/video/saa7134/saa7134.h 2007-01-20 08:57:52.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
diff -urN linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134-i2c.c linux-source-2.6.18/drivers/media/video/saa7134/saa7134-i2c.c
--- linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134-i2c.c 2007-01-20 08:56:41.000000000 -0800
+++ linux-source-2.6.18/drivers/media/video/saa7134/saa7134-i2c.c 2007-01-20 08:57:52.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",
diff -urN linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134-input.c linux-source-2.6.18/drivers/media/video/saa7134/saa7134-input.c
--- linux-source-2.6.18.orig/drivers/media/video/saa7134/saa7134-input.c 2007-01-20 08:56:41.000000000 -0800
+++ linux-source-2.6.18/drivers/media/video/saa7134/saa7134-input.c 2007-01-20 08:57:52.000000000 -0800
@@ -89,6 +89,53 @@
/* --------------------- 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;
@@ -333,6 +380,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 = ir_codes_msi_tvanywhere_plus;
+ break;
default:
dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
break;
diff -urN linux-source-2.6.18.orig/include/media/ir-common.h linux-source-2.6.18/include/media/ir-common.h
--- linux-source-2.6.18.orig/include/media/ir-common.h 2007-01-20 08:55:54.000000000 -0800
+++ linux-source-2.6.18/include/media/ir-common.h 2007-01-20 08:57:52.000000000 -0800
@@ -90,6 +90,7 @@
extern IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE];
#endif
The patch was still creating problems when applied to a recent kernel so I made some changes by hand and created a diff file in the end for other people. Here is it (if LQ has support for attachments, at least I can't find it easily).
The diff file can be applied to the most recent stable kernels (e.g. 2.6.19.1). It is _supposed_ to solve the problem. However, I can't confirm it yet as I'm currently rebuilding my kernel.
I'll provide more feedback soon.
EDIT: Same story. Device gets recognized but irw doesn't get any input when keys are pressed on the remote.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.