diff -urN linux-source-2.6.24.orig/drivers/media/common/ir-keymaps.c linux-source-2.6.24/drivers/media/common/ir-keymaps.c --- linux-source-2.6.24.orig/drivers/media/common/ir-keymaps.c 2008-02-11 06:51:11.000000000 +0100 +++ linux-source-2.6.24/drivers/media/common/ir-keymaps.c 2008-09-15 18:32:37.000000000 +0200 @@ -422,7 +422,7 @@ /* ---------------------------------------------------------------------- */ -/* 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, @@ -456,6 +456,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 + Some changes to formatting and keycodes by Mark Schultz + +*/ + +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.24.orig/drivers/media/video/ir-kbd-i2c.c linux-source-2.6.24/drivers/media/video/ir-kbd-i2c.c --- linux-source-2.6.24.orig/drivers/media/video/ir-kbd-i2c.c 2008-02-11 06:51:11.000000000 +0100 +++ linux-source-2.6.24/drivers/media/video/ir-kbd-i2c.c 2008-09-15 19:17:49.000000000 +0200 @@ -12,6 +12,9 @@ * Markus Rechberger * modified for DViCO Fusion HDTV 5 RT GOLD by * Chaogui Zhang + * modified for MSI TV at nywhere Plus by + * Henry Wong + * Mark Schultz * * 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 @@ #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, @@ -309,7 +314,7 @@ 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 + polling_interval*HZ/1000); } /* ----------------------------------------------------------------------- */ @@ -388,6 +393,9 @@ 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"; @@ -504,7 +512,7 @@ */ 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 }; static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; static const int probe_cx23885[] = { 0x6b, -1 }; @@ -540,7 +548,38 @@ 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.24.orig/drivers/media/video/saa7134/saa7134-cards.c linux-source-2.6.24/drivers/media/video/saa7134/saa7134-cards.c --- linux-source-2.6.24.orig/drivers/media/video/saa7134/saa7134-cards.c 2008-02-11 06:51:11.000000000 +0100 +++ linux-source-2.6.24/drivers/media/video/saa7134/saa7134-cards.c 2008-09-15 19:28:43.000000000 +0200 @@ -2608,7 +2608,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, @@ -4034,7 +4034,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, @@ -4466,6 +4472,7 @@ case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_UPMOST_PURPLE_TV: case SAA7134_BOARD_HAUPPAUGE_HVR1110: + 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.24.orig/drivers/media/video/saa7134/saa7134.h linux-source-2.6.24/drivers/media/video/saa7134/saa7134.h --- linux-source-2.6.24.orig/drivers/media/video/saa7134/saa7134.h 2008-02-11 06:51:11.000000000 +0100 +++ linux-source-2.6.24/drivers/media/video/saa7134/saa7134.h 2008-09-15 19:30:43.000000000 +0200 @@ -204,7 +204,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.24.orig/drivers/media/video/saa7134/saa7134-input.c linux-source-2.6.24/drivers/media/video/saa7134/saa7134-input.c --- linux-source-2.6.24.orig/drivers/media/video/saa7134/saa7134-input.c 2008-02-11 06:51:11.000000000 +0100 +++ linux-source-2.6.24/drivers/media/video/saa7134/saa7134-input.c 2008-09-15 19:36:57.000000000 +0200 @@ -110,6 +110,52 @@ /* --------------------- 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; + + /* 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; @@ -457,6 +503,11 @@ ir->get_key = get_key_hvr1110; ir->ir_codes = ir_codes_hauppauge_new; 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.24.orig/drivers/media/video/saa7134/saa7134-i2c.c linux-source-2.6.24/drivers/media/video/saa7134/saa7134-i2c.c --- linux-source-2.6.24.orig/drivers/media/video/saa7134/saa7134-i2c.c 2008-02-11 06:51:11.000000000 +0100 +++ linux-source-2.6.24/drivers/media/video/saa7134/saa7134-i2c.c 2008-09-15 19:33:32.000000000 +0200 @@ -335,6 +335,7 @@ case 0x7a: case 0x47: case 0x71: + case 0x30: { struct IR_i2c *ir = i2c_get_clientdata(client); d1printk("%s i2c IR detected (%s).\n", diff -urN linux-source-2.6.24.orig/include/media/ir-common.h linux-source-2.6.24/include/media/ir-common.h --- linux-source-2.6.24.orig/include/media/ir-common.h 2008-02-11 06:51:11.000000000 +0100 +++ linux-source-2.6.24/include/media/ir-common.h 2008-09-18 19:28:58.000000000 +0200 @@ -134,6 +134,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]; 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_budget_ci_old[IR_KEYTAB_SIZE];