aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ir-kbd-i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r--drivers/media/video/ir-kbd-i2c.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index a30254bed311..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
@@ -65,7 +69,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
65 int size, int offset) 69 int size, int offset)
66{ 70{
67 unsigned char buf[6]; 71 unsigned char buf[6];
68 int start, range, toggle, dev, code; 72 int start, range, toggle, dev, code, ircode;
69 73
70 /* poll IR chip */ 74 /* poll IR chip */
71 if (size != i2c_master_recv(&ir->c,buf,size)) 75 if (size != i2c_master_recv(&ir->c,buf,size))
@@ -85,6 +89,24 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
85 if (!start) 89 if (!start)
86 /* no key pressed */ 90 /* no key pressed */
87 return 0; 91 return 0;
92 /*
93 * Hauppauge remotes (black/silver) always use
94 * specific device ids. If we do not filter the
95 * device ids then messages destined for devices
96 * such as TVs (id=0) will get through causing
97 * mis-fired events.
98 *
99 * We also filter out invalid key presses which
100 * produce annoying debug log entries.
101 */
102 ircode= (start << 12) | (toggle << 11) | (dev << 6) | code;
103 if ((ircode & 0x1fff)==0x1fff)
104 /* invalid key press */
105 return 0;
106
107 if (dev!=0x1e && dev!=0x1f)
108 /* not a hauppauge remote */
109 return 0;
88 110
89 if (!range) 111 if (!range)
90 code += 64; 112 code += 64;
@@ -94,7 +116,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
94 116
95 /* return key */ 117 /* return key */
96 *ir_key = code; 118 *ir_key = code;
97 *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code; 119 *ir_raw = ircode;
98 return 1; 120 return 1;
99} 121}
100 122
@@ -224,9 +246,15 @@ static void ir_timer(unsigned long data)
224static void ir_work(struct work_struct *work) 246static void ir_work(struct work_struct *work)
225{ 247{
226 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;
227 255
228 ir_key_poll(ir); 256 ir_key_poll(ir);
229 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100)); 257 mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval));
230} 258}
231 259
232/* ----------------------------------------------------------------------- */ 260/* ----------------------------------------------------------------------- */
@@ -465,9 +493,37 @@ static int ir_probe(struct i2c_adapter *adap)
465 (1 == rc) ? "yes" : "no"); 493 (1 == rc) ? "yes" : "no");
466 if (1 == rc) { 494 if (1 == rc) {
467 ir_attach(adap, probe[i], 0, 0); 495 ir_attach(adap, probe[i], 0, 0);
468 break; 496 return 0;
469 } 497 }
470 } 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
471 return 0; 527 return 0;
472} 528}
473 529