aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ir-kbd-i2c.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>2005-11-09 00:37:32 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:18 -0500
commitd5e5265315770bda46c50ecaa64e2b9790f2064c (patch)
tree5c92fa1125dee3f766bd06f18840ce78bf0cd861 /drivers/media/video/ir-kbd-i2c.c
parentda45a2a5b96afd7188c058a55eb2917d6524c0cf (diff)
[PATCH] v4l: 784: several improvement on i2c ir handling for em2820
- Several Improvement on I2C IR handling for em2820: - moved Pinnacle IR table (ir_codes_em2820) to em2820-input.c - IR struct renamed and moved to a header file. - New file to handle em2820-specific IR. - Some cleanups. - attach now detects I2C IR and calls em2820-specific IR code - IR compat code moved to compat.h - New header with struct IR_i2c there, to allow it to be used by board-specific input handlers. - Some improvements at em28xx board detection: - Board detection message improved to show interface and class. - Now it doesn't touch audio interfaces. Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r--drivers/media/video/ir-kbd-i2c.c238
1 files changed, 84 insertions, 154 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index aec710f4effc..8cc3f8ab2f3a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -41,101 +41,71 @@
41#include <linux/workqueue.h> 41#include <linux/workqueue.h>
42#include <asm/semaphore.h> 42#include <asm/semaphore.h>
43#include <media/ir-common.h> 43#include <media/ir-common.h>
44 44#include <media/ir-kbd-i2c.h>
45static IR_KEYTAB_TYPE ir_codes_em2820[IR_KEYTAB_SIZE] = {
46 [ 0x01 ] = KEY_CHANNEL,
47 [ 0x02 ] = KEY_SELECT,
48 [ 0x03 ] = KEY_MUTE,
49 [ 0x04 ] = KEY_POWER,
50 [ 0x05 ] = KEY_KP1,
51 [ 0x06 ] = KEY_KP2,
52 [ 0x07 ] = KEY_KP3,
53 [ 0x08 ] = KEY_CHANNELUP,
54 [ 0x09 ] = KEY_KP4,
55 [ 0x0a ] = KEY_KP5,
56 [ 0x0b ] = KEY_KP6,
57 [ 0x0c ] = KEY_CHANNELDOWN,
58 [ 0x0d ] = KEY_KP7,
59 [ 0x0e ] = KEY_KP8,
60 [ 0x0f ] = KEY_KP9,
61 [ 0x10 ] = KEY_VOLUMEUP,
62 [ 0x11 ] = KEY_KP0,
63 [ 0x12 ] = KEY_MENU,
64 [ 0x13 ] = KEY_PRINT,
65 [ 0x14 ] = KEY_VOLUMEDOWN,
66 [ 0x16 ] = KEY_PAUSE,
67 [ 0x18 ] = KEY_RECORD,
68 [ 0x19 ] = KEY_REWIND,
69 [ 0x1a ] = KEY_PLAY,
70 [ 0x1b ] = KEY_FORWARD,
71 [ 0x1c ] = KEY_BACKSPACE,
72 [ 0x1e ] = KEY_STOP,
73 [ 0x40 ] = KEY_ZOOM,
74};
75 45
76/* Mark Phalan <phalanm@o2.ie> */ 46/* Mark Phalan <phalanm@o2.ie> */
77static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { 47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
78 [ 0x00 ] = KEY_KP0, 48 [ 0 ] = KEY_KP0,
79 [ 0x01 ] = KEY_KP1, 49 [ 1 ] = KEY_KP1,
80 [ 0x02 ] = KEY_KP2, 50 [ 2 ] = KEY_KP2,
81 [ 0x03 ] = KEY_KP3, 51 [ 3 ] = KEY_KP3,
82 [ 0x04 ] = KEY_KP4, 52 [ 4 ] = KEY_KP4,
83 [ 0x05 ] = KEY_KP5, 53 [ 5 ] = KEY_KP5,
84 [ 0x06 ] = KEY_KP6, 54 [ 6 ] = KEY_KP6,
85 [ 0x07 ] = KEY_KP7, 55 [ 7 ] = KEY_KP7,
86 [ 0x08 ] = KEY_KP8, 56 [ 8 ] = KEY_KP8,
87 [ 0x09 ] = KEY_KP9, 57 [ 9 ] = KEY_KP9,
88 58
89 [ 0x12 ] = KEY_POWER, 59 [ 18 ] = KEY_POWER,
90 [ 0x10 ] = KEY_MUTE, 60 [ 16 ] = KEY_MUTE,
91 [ 0x1f ] = KEY_VOLUMEDOWN, 61 [ 31 ] = KEY_VOLUMEDOWN,
92 [ 0x1b ] = KEY_VOLUMEUP, 62 [ 27 ] = KEY_VOLUMEUP,
93 [ 0x1a ] = KEY_CHANNELUP, 63 [ 26 ] = KEY_CHANNELUP,
94 [ 0x1e ] = KEY_CHANNELDOWN, 64 [ 30 ] = KEY_CHANNELDOWN,
95 [ 0x0e ] = KEY_PAGEUP, 65 [ 14 ] = KEY_PAGEUP,
96 [ 0x1d ] = KEY_PAGEDOWN, 66 [ 29 ] = KEY_PAGEDOWN,
97 [ 0x13 ] = KEY_SOUND, 67 [ 19 ] = KEY_SOUND,
98 68
99 [ 0x18 ] = KEY_KPPLUSMINUS, /* CH +/- */ 69 [ 24 ] = KEY_KPPLUSMINUS, /* CH +/- */
100 [ 0x16 ] = KEY_SUBTITLE, /* CC */ 70 [ 22 ] = KEY_SUBTITLE, /* CC */
101 [ 0x0d ] = KEY_TEXT, /* TTX */ 71 [ 13 ] = KEY_TEXT, /* TTX */
102 [ 0x0b ] = KEY_TV, /* AIR/CBL */ 72 [ 11 ] = KEY_TV, /* AIR/CBL */
103 [ 0x11 ] = KEY_PC, /* PC/TV */ 73 [ 17 ] = KEY_PC, /* PC/TV */
104 [ 0x17 ] = KEY_OK, /* CH RTN */ 74 [ 23 ] = KEY_OK, /* CH RTN */
105 [ 0x19 ] = KEY_MODE, /* FUNC */ 75 [ 25 ] = KEY_MODE, /* FUNC */
106 [ 0x0c ] = KEY_SEARCH, /* AUTOSCAN */ 76 [ 12 ] = KEY_SEARCH, /* AUTOSCAN */
107 77
108 /* Not sure what to do with these ones! */ 78 /* Not sure what to do with these ones! */
109 [ 0x0f ] = KEY_SELECT, /* SOURCE */ 79 [ 15 ] = KEY_SELECT, /* SOURCE */
110 [ 0x0a ] = KEY_KPPLUS, /* +100 */ 80 [ 10 ] = KEY_KPPLUS, /* +100 */
111 [ 0x14 ] = KEY_KPEQUAL, /* SYNC */ 81 [ 20 ] = KEY_KPEQUAL, /* SYNC */
112 [ 0x1c ] = KEY_MEDIA, /* PC/TV */ 82 [ 28 ] = KEY_MEDIA, /* PC/TV */
113}; 83};
114 84
115static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { 85static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
116 [ 0x03 ] = KEY_POWER, 86 [ 0x3 ] = KEY_POWER,
117 [ 0x6f ] = KEY_MUTE, 87 [ 0x6f ] = KEY_MUTE,
118 [ 0x10 ] = KEY_BACKSPACE, /* Recall */ 88 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
119 89
120 [ 0x11 ] = KEY_KP0, 90 [ 0x11 ] = KEY_KP0,
121 [ 0x04 ] = KEY_KP1, 91 [ 0x4 ] = KEY_KP1,
122 [ 0x05 ] = KEY_KP2, 92 [ 0x5 ] = KEY_KP2,
123 [ 0x06 ] = KEY_KP3, 93 [ 0x6 ] = KEY_KP3,
124 [ 0x08 ] = KEY_KP4, 94 [ 0x8 ] = KEY_KP4,
125 [ 0x09 ] = KEY_KP5, 95 [ 0x9 ] = KEY_KP5,
126 [ 0x0a ] = KEY_KP6, 96 [ 0xa ] = KEY_KP6,
127 [ 0x0c ] = KEY_KP7, 97 [ 0xc ] = KEY_KP7,
128 [ 0x0d ] = KEY_KP8, 98 [ 0xd ] = KEY_KP8,
129 [ 0x0e ] = KEY_KP9, 99 [ 0xe ] = KEY_KP9,
130 [ 0x12 ] = KEY_KPDOT, /* 100+ */ 100 [ 0x12 ] = KEY_KPDOT, /* 100+ */
131 101
132 [ 0x07 ] = KEY_VOLUMEUP, 102 [ 0x7 ] = KEY_VOLUMEUP,
133 [ 0x0b ] = KEY_VOLUMEDOWN, 103 [ 0xb ] = KEY_VOLUMEDOWN,
134 [ 0x1a ] = KEY_KPPLUS, 104 [ 0x1a ] = KEY_KPPLUS,
135 [ 0x18 ] = KEY_KPMINUS, 105 [ 0x18 ] = KEY_KPMINUS,
136 [ 0x15 ] = KEY_UP, 106 [ 0x15 ] = KEY_UP,
137 [ 0x1d ] = KEY_DOWN, 107 [ 0x1d ] = KEY_DOWN,
138 [ 0x0f ] = KEY_CHANNELUP, 108 [ 0xf ] = KEY_CHANNELUP,
139 [ 0x13 ] = KEY_CHANNELDOWN, 109 [ 0x13 ] = KEY_CHANNELDOWN,
140 [ 0x48 ] = KEY_ZOOM, 110 [ 0x48 ] = KEY_ZOOM,
141 111
@@ -152,17 +122,6 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
152 122
153}; 123};
154 124
155struct IR {
156 struct i2c_client c;
157 struct input_dev *input;
158 struct ir_input_state ir;
159
160 struct work_struct work;
161 struct timer_list timer;
162 char phys[32];
163 int (*get_key)(struct IR*, u32*, u32*);
164};
165
166/* ----------------------------------------------------------------------- */ 125/* ----------------------------------------------------------------------- */
167/* insmod parameters */ 126/* insmod parameters */
168 127
@@ -173,12 +132,9 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
173#define dprintk(level, fmt, arg...) if (debug >= level) \ 132#define dprintk(level, fmt, arg...) if (debug >= level) \
174 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) 133 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
175 134
176#define IR_PINNACLE_REMOTE 0x01
177#define IR_TERRATEC_REMOTE 0x02
178
179/* ----------------------------------------------------------------------- */ 135/* ----------------------------------------------------------------------- */
180 136
181static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) 137static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
182{ 138{
183 unsigned char buf[3]; 139 unsigned char buf[3];
184 int start, toggle, dev, code; 140 int start, toggle, dev, code;
@@ -205,7 +161,7 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
205 return 1; 161 return 1;
206} 162}
207 163
208static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) 164static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
209{ 165{
210 unsigned char b; 166 unsigned char b;
211 167
@@ -219,7 +175,7 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
219 return 1; 175 return 1;
220} 176}
221 177
222static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) 178static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
223{ 179{
224 unsigned char b; 180 unsigned char b;
225 181
@@ -239,7 +195,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
239 return 1; 195 return 1;
240} 196}
241 197
242static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) 198static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
243{ 199{
244 unsigned char b; 200 unsigned char b;
245 201
@@ -267,7 +223,7 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
267 return 1; 223 return 1;
268} 224}
269 225
270static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw) 226static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
271{ 227{
272 unsigned char b; 228 unsigned char b;
273 229
@@ -289,10 +245,9 @@ static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
289 *ir_raw = b; 245 *ir_raw = b;
290 return 1; 246 return 1;
291} 247}
292
293/* ----------------------------------------------------------------------- */ 248/* ----------------------------------------------------------------------- */
294 249
295static void ir_key_poll(struct IR *ir) 250static void ir_key_poll(struct IR_i2c *ir)
296{ 251{
297 static u32 ir_key, ir_raw; 252 static u32 ir_key, ir_raw;
298 int rc; 253 int rc;
@@ -313,13 +268,13 @@ static void ir_key_poll(struct IR *ir)
313 268
314static void ir_timer(unsigned long data) 269static void ir_timer(unsigned long data)
315{ 270{
316 struct IR *ir = (struct IR*)data; 271 struct IR_i2c *ir = (struct IR_i2c*)data;
317 schedule_work(&ir->work); 272 schedule_work(&ir->work);
318} 273}
319 274
320static void ir_work(void *data) 275static void ir_work(void *data)
321{ 276{
322 struct IR *ir = data; 277 struct IR_i2c *ir = data;
323 ir_key_poll(ir); 278 ir_key_poll(ir);
324 mod_timer(&ir->timer, jiffies+HZ/10); 279 mod_timer(&ir->timer, jiffies+HZ/10);
325} 280}
@@ -351,10 +306,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
351 IR_KEYTAB_TYPE *ir_codes = NULL; 306 IR_KEYTAB_TYPE *ir_codes = NULL;
352 char *name; 307 char *name;
353 int ir_type; 308 int ir_type;
354 struct IR *ir; 309 struct IR_i2c *ir;
355 struct input_dev *input_dev; 310 struct input_dev *input_dev;
356 311
357 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 312 ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
358 input_dev = input_allocate_device(); 313 input_dev = input_allocate_device();
359 if (!ir || !input_dev) { 314 if (!ir || !input_dev) {
360 kfree(ir); 315 kfree(ir);
@@ -390,36 +345,18 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
390 ir_codes = ir_codes_rc5_tv; 345 ir_codes = ir_codes_rc5_tv;
391 break; 346 break;
392 case 0x30: 347 case 0x30:
393 switch(kind){ 348 name = "KNC One";
394 case IR_TERRATEC_REMOTE: 349 ir->get_key = get_key_knc1;
395 name = "Terratec IR"; 350 ir_type = IR_TYPE_OTHER;
396 ir->get_key = get_key_knc1; 351 ir_codes = ir_codes_empty;
397 ir_type = IR_TYPE_OTHER;
398 ir_codes = ir_codes_em2820;
399 break;
400 default:
401 name = "KNC One";
402 ir->get_key = get_key_knc1;
403 ir_type = IR_TYPE_OTHER;
404 ir_codes = ir_codes_empty;
405 }
406 break; 352 break;
407 case 0x47:
408 case 0x7a: 353 case 0x7a:
409 switch(kind){ 354 name = "Purple TV";
410 case IR_PINNACLE_REMOTE: 355 ir->get_key = get_key_purpletv;
411 name = "Pinnacle IR Remote"; 356 ir_type = IR_TYPE_OTHER;
412 ir->get_key = get_key_purpletv; 357 ir_codes = ir_codes_purpletv;
413 ir_type = IR_TYPE_OTHER;
414 ir_codes = ir_codes_em2820;
415 break;
416 default:
417 name = "Purple TV";
418 ir->get_key = get_key_purpletv;
419 ir_type = IR_TYPE_OTHER;
420 ir_codes = ir_codes_purpletv;
421 }
422 break; 358 break;
359
423 default: 360 default:
424 /* shouldn't happen */ 361 /* shouldn't happen */
425 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr); 362 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
@@ -427,12 +364,18 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
427 return -1; 364 return -1;
428 } 365 }
429 366
430 /* register i2c device */ 367 /* Sets name and its physical addr */
431 i2c_attach_client(&ir->c);
432 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); 368 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
433 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 369 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
434 ir->c.adapter->dev.bus_id, 370 ir->c.adapter->dev.bus_id,
435 ir->c.dev.bus_id); 371 ir->c.dev.bus_id);
372 ir->ir_codes=ir_codes;
373
374 /* register i2c device
375 * At device register, IR codes may be changed to be
376 * board dependent.
377 */
378 i2c_attach_client(&ir->c);
436 379
437 /* init + register input device */ 380 /* init + register input device */
438 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); 381 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
@@ -440,6 +383,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
440 input_dev->name = ir->c.name; 383 input_dev->name = ir->c.name;
441 input_dev->phys = ir->phys; 384 input_dev->phys = ir->phys;
442 385
386 /* register event device */
443 input_register_device(ir->input); 387 input_register_device(ir->input);
444 388
445 /* start polling via eventd */ 389 /* start polling via eventd */
@@ -454,7 +398,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
454 398
455static int ir_detach(struct i2c_client *client) 399static int ir_detach(struct i2c_client *client)
456{ 400{
457 struct IR *ir = i2c_get_clientdata(client); 401 struct IR_i2c *ir = i2c_get_clientdata(client);
458 402
459 /* kill outstanding polls */ 403 /* kill outstanding polls */
460 del_timer(&ir->timer); 404 del_timer(&ir->timer);
@@ -483,11 +427,9 @@ static int ir_probe(struct i2c_adapter *adap)
483 427
484 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; 428 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
485 static const int probe_saa7134[] = { 0x7a, -1 }; 429 static const int probe_saa7134[] = { 0x7a, -1 };
486 static const int probe_em2820[] = { 0x47, 0x30, -1 }; 430 static const int probe_em2820[] = { 0x30, 0x47, -1 };
487 const int *probe = NULL; 431 const int *probe = NULL;
488 int attached = 0; 432 struct i2c_client c; char buf; int i,rc;
489
490 struct i2c_client c; unsigned char buf; int i,rc;
491 433
492 switch (adap->id) { 434 switch (adap->id) {
493 case I2C_HW_B_BT848: 435 case I2C_HW_B_BT848:
@@ -505,27 +447,15 @@ static int ir_probe(struct i2c_adapter *adap)
505 447
506 memset(&c,0,sizeof(c)); 448 memset(&c,0,sizeof(c));
507 c.adapter = adap; 449 c.adapter = adap;
508 for (i = 0; -1 != probe[i] && attached != 1; i++) { 450 for (i = 0; -1 != probe[i]; i++) {
509 c.addr = probe[i]; 451 c.addr = probe[i];
510 rc = i2c_master_recv(&c,&buf,1); 452 rc = i2c_master_recv(&c,&buf,0);
511 dprintk(1,"probe 0x%02x @ %s: %s\n", 453 dprintk(1,"probe 0x%02x @ %s: %s\n",
512 probe[i], adap->name, 454 probe[i], adap->name,
513 (1 == rc) ? "yes" : "no"); 455 (0 == rc) ? "yes" : "no");
514 switch(adap->id){ 456 if (0 == rc) {
515 case I2C_HW_B_BT848: 457 ir_attach(adap,probe[i],0,0);
516 case I2C_HW_SAA7134: 458 break;
517 if (1 == rc) {
518 ir_attach(adap,probe[i],0,0);
519 attached=1;
520 break;
521 }
522 case I2C_HW_B_EM2820:
523 /* windows logs are needed for fixing the pinnacle device */
524 if (1 == rc && 0xff == buf){
525 ir_attach(adap,probe[i],0,IR_TERRATEC_REMOTE);
526 attached=1;
527 }
528 break;
529 } 459 }
530 } 460 }
531 return 0; 461 return 0;