aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBrian Rogers <brian_rogers@comcast.net>2008-10-13 07:37:06 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-13 07:57:34 -0400
commitba340b40a5f65261731583f67d7ec8cafbf5cfaa (patch)
treeb62243ecb18ccf1d38b60e5919e8ab7eeaa7d6f4 /drivers
parentfa405d7094489828014315a34f0c21fba30be38c (diff)
V4L/DVB (9168): Add support for 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> [mchehab.redhat.com: Fix merge conflicts and remove an unused var] Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/common/ir-keymaps.c92
-rw-r--r--drivers/media/video/ir-kbd-i2c.c42
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c52
5 files changed, 185 insertions, 3 deletions
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index b7ed88c59b54..4952aeb5dd80 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -517,7 +517,8 @@ EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci);
517 517
518/* ---------------------------------------------------------------------- */ 518/* ---------------------------------------------------------------------- */
519 519
520/* MSI TV@nywhere remote */ 520/* MSI TV@nywhere MASTER remote */
521
521IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { 522IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
522 /* Keys 0 to 9 */ 523 /* Keys 0 to 9 */
523 [ 0x00 ] = KEY_0, 524 [ 0x00 ] = KEY_0,
@@ -551,6 +552,95 @@ EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere);
551 552
552/* ---------------------------------------------------------------------- */ 553/* ---------------------------------------------------------------------- */
553 554
555/*
556 Keycodes for remote on the MSI TV@nywhere Plus. The controller IC on the card
557 is marked "KS003". The controller is I2C at address 0x30, but does not seem
558 to respond to probes until a read is performed from a valid device.
559 I don't know why...
560
561 Note: This remote may be of similar or identical design to the
562 Pixelview remote (?). The raw codes and duplicate button codes
563 appear to be the same.
564
565 Henry Wong <henry@stuffedcow.net>
566 Some changes to formatting and keycodes by Mark Schultz <n9xmj@yahoo.com>
567
568*/
569
570IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = {
571
572/* ---- Remote Button Layout ----
573
574 POWER SOURCE SCAN MUTE
575 TV/FM 1 2 3
576 |> 4 5 6
577 <| 7 8 9
578 ^^UP 0 + RECALL
579 vvDN RECORD STOP PLAY
580
581 MINIMIZE ZOOM
582
583 CH+
584 VOL- VOL+
585 CH-
586
587 SNAPSHOT MTS
588
589 << FUNC >> RESET
590*/
591
592 [0x01] = KEY_KP1, /* 1 */
593 [0x0b] = KEY_KP2, /* 2 */
594 [0x1b] = KEY_KP3, /* 3 */
595 [0x05] = KEY_KP4, /* 4 */
596 [0x09] = KEY_KP5, /* 5 */
597 [0x15] = KEY_KP6, /* 6 */
598 [0x06] = KEY_KP7, /* 7 */
599 [0x0a] = KEY_KP8, /* 8 */
600 [0x12] = KEY_KP9, /* 9 */
601 [0x02] = KEY_KP0, /* 0 */
602 [0x10] = KEY_KPPLUS, /* + */
603 [0x13] = KEY_AGAIN, /* Recall */
604
605 [0x1e] = KEY_POWER, /* Power */
606 [0x07] = KEY_TUNER, /* Source */
607 [0x1c] = KEY_SEARCH, /* Scan */
608 [0x18] = KEY_MUTE, /* Mute */
609
610 [0x03] = KEY_RADIO, /* TV/FM */
611 /* The next four keys are duplicates that appear to send the
612 same IR code as Ch+, Ch-, >>, and << . The raw code assigned
613 to them is the actual code + 0x20 - they will never be
614 detected as such unless some way is discovered to distinguish
615 these buttons from those that have the same code. */
616 [0x3f] = KEY_RIGHT, /* |> and Ch+ */
617 [0x37] = KEY_LEFT, /* <| and Ch- */
618 [0x2c] = KEY_UP, /* ^^Up and >> */
619 [0x24] = KEY_DOWN, /* vvDn and << */
620
621 [0x00] = KEY_RECORD, /* Record */
622 [0x08] = KEY_STOP, /* Stop */
623 [0x11] = KEY_PLAY, /* Play */
624
625 [0x0f] = KEY_CLOSE, /* Minimize */
626 [0x19] = KEY_ZOOM, /* Zoom */
627 [0x1a] = KEY_SHUFFLE, /* Snapshot */
628 [0x0d] = KEY_LANGUAGE, /* MTS */
629
630 [0x14] = KEY_VOLUMEDOWN, /* Vol- */
631 [0x16] = KEY_VOLUMEUP, /* Vol+ */
632 [0x17] = KEY_CHANNELDOWN, /* Ch- */
633 [0x1f] = KEY_CHANNELUP, /* Ch+ */
634
635 [0x04] = KEY_REWIND, /* << */
636 [0x0e] = KEY_MENU, /* Function */
637 [0x0c] = KEY_FASTFORWARD, /* >> */
638 [0x1d] = KEY_RESTART, /* Reset */
639};
640EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus);
641
642/* ---------------------------------------------------------------------- */
643
554/* Cinergy 1400 DVB-T */ 644/* Cinergy 1400 DVB-T */
555IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { 645IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
556 [ 0x01 ] = KEY_POWER, 646 [ 0x01 ] = KEY_POWER,
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 703195a5ad4e..efe849981ab7 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -12,6 +12,10 @@
12 * Markus Rechberger <mrechberger@gmail.com> 12 * Markus Rechberger <mrechberger@gmail.com>
13 * modified for DViCO Fusion HDTV 5 RT GOLD by 13 * modified for DViCO Fusion HDTV 5 RT GOLD by
14 * Chaogui Zhang <czhang1974@gmail.com> 14 * Chaogui Zhang <czhang1974@gmail.com>
15 * modified for MSI TV@nywhere Plus by
16 * Henry Wong <henry@stuffedcow.net>
17 * Mark Schultz <n9xmj@yahoo.com>
18 * Brian Rogers <brian_rogers@comcast.net>
15 * 19 *
16 * This program is free software; you can redistribute it and/or modify 20 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 21 * it under the terms of the GNU General Public License as published by
@@ -242,9 +246,15 @@ static void ir_timer(unsigned long data)
242static void ir_work(struct work_struct *work) 246static void ir_work(struct work_struct *work)
243{ 247{
244 struct IR_i2c *ir = container_of(work, struct IR_i2c, work); 248 struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
249 int polling_interval = 100;
250
251 /* MSI TV@nywhere Plus requires more frequent polling
252 otherwise it will miss some keypresses */
253 if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30)
254 polling_interval = 50;
245 255
246 ir_key_poll(ir); 256 ir_key_poll(ir);
247 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100)); 257 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval));
248} 258}
249 259
250/* ----------------------------------------------------------------------- */ 260/* ----------------------------------------------------------------------- */
@@ -483,9 +493,37 @@ static int ir_probe(struct i2c_adapter *adap)
483 (1 == rc) ? "yes" : "no"); 493 (1 == rc) ? "yes" : "no");
484 if (1 == rc) { 494 if (1 == rc) {
485 ir_attach(adap, probe[i], 0, 0); 495 ir_attach(adap, probe[i], 0, 0);
486 break; 496 return 0;
487 } 497 }
488 } 498 }
499
500 /* Special case for MSI TV@nywhere Plus remote */
501 if (adap->id == I2C_HW_SAA7134) {
502 u8 temp;
503
504 /* MSI TV@nywhere Plus controller doesn't seem to
505 respond to probes unless we read something from
506 an existing device. Weird... */
507
508 msg.addr = 0x50;
509 rc = i2c_transfer(adap, &msg, 1);
510 dprintk(1, "probe 0x%02x @ %s: %s\n",
511 msg.addr, adap->name,
512 (1 == rc) ? "yes" : "no");
513
514 /* Now do the probe. The controller does not respond
515 to 0-byte reads, so we use a 1-byte read instead. */
516 msg.addr = 0x30;
517 msg.len = 1;
518 msg.buf = &temp;
519 rc = i2c_transfer(adap, &msg, 1);
520 dprintk(1, "probe 0x%02x @ %s: %s\n",
521 msg.addr, adap->name,
522 (1 == rc) ? "yes" : "no");
523 if (1 == rc)
524 ir_attach(adap, msg.addr, 0, 0);
525 }
526
489 return 0; 527 return 0;
490} 528}
491 529
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index c9392c4e92fd..ddc5402c5fb0 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5969,6 +5969,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
5969 case SAA7134_BOARD_PINNACLE_PCTV_110i: 5969 case SAA7134_BOARD_PINNACLE_PCTV_110i:
5970 case SAA7134_BOARD_PINNACLE_PCTV_310i: 5970 case SAA7134_BOARD_PINNACLE_PCTV_310i:
5971 case SAA7134_BOARD_UPMOST_PURPLE_TV: 5971 case SAA7134_BOARD_UPMOST_PURPLE_TV:
5972 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
5972 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 5973 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
5973 case SAA7134_BOARD_BEHOLD_607_9FM: 5974 case SAA7134_BOARD_BEHOLD_607_9FM:
5974 case SAA7134_BOARD_BEHOLD_M6: 5975 case SAA7134_BOARD_BEHOLD_M6:
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index b02965c52476..20c1b33caf7b 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)
337 case 0x47: 337 case 0x47:
338 case 0x71: 338 case 0x71:
339 case 0x2d: 339 case 0x2d:
340 case 0x30:
340 { 341 {
341 struct IR_i2c *ir = i2c_get_clientdata(client); 342 struct IR_i2c *ir = i2c_get_clientdata(client);
342 d1printk("%s i2c IR detected (%s).\n", 343 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 72a1c67a8c39..c53fd5f9f6b5 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -118,6 +118,53 @@ static int build_key(struct saa7134_dev *dev)
118 118
119/* --------------------- Chip specific I2C key builders ----------------- */ 119/* --------------------- Chip specific I2C key builders ----------------- */
120 120
121static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
122 u32 *ir_raw)
123{
124 unsigned char b;
125 int gpio;
126
127 /* <dev> is needed to access GPIO. Used by the saa_readl macro. */
128 struct saa7134_dev *dev = ir->c.adapter->algo_data;
129 if (dev == NULL) {
130 dprintk("get_key_msi_tvanywhere_plus: "
131 "gir->c.adapter->algo_data is NULL!\n");
132 return -EIO;
133 }
134
135 /* rising SAA7134_GPIO_GPRESCAN reads the status */
136
137 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
138 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
139
140 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
141
142 /* GPIO&0x40 is pulsed low when a button is pressed. Don't do
143 I2C receive if gpio&0x40 is not low. */
144
145 if (gpio & 0x40)
146 return 0; /* No button press */
147
148 /* GPIO says there is a button press. Get it. */
149
150 if (1 != i2c_master_recv(&ir->c, &b, 1)) {
151 i2cdprintk("read error\n");
152 return -EIO;
153 }
154
155 /* No button press */
156
157 if (b == 0xff)
158 return 0;
159
160 /* Button pressed */
161
162 dprintk("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b);
163 *ir_key = b;
164 *ir_raw = b;
165 return 1;
166}
167
121static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 168static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
122{ 169{
123 unsigned char b; 170 unsigned char b;
@@ -641,6 +688,11 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
641 ir->get_key = get_key_purpletv; 688 ir->get_key = get_key_purpletv;
642 ir->ir_codes = ir_codes_purpletv; 689 ir->ir_codes = ir_codes_purpletv;
643 break; 690 break;
691 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
692 snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus");
693 ir->get_key = get_key_msi_tvanywhere_plus;
694 ir->ir_codes = ir_codes_msi_tvanywhere_plus;
695 break;
644 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 696 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
645 snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); 697 snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110");
646 ir->get_key = get_key_hvr1110; 698 ir->get_key = get_key_hvr1110;