[PATCH] v4l: 783: fixed bad em2820 remote layout values
[deliverable/linux.git] / drivers / media / video / ir-kbd-i2c.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 *
3 * keyboard input driver for i2c IR remote controls
4 *
5 * Copyright (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
6 * modified for PixelView (BT878P+W/FM) by
7 * Michal Kochanowicz <mkochano@pld.org.pl>
8 * Christoph Bartelmus <lirc@bartelmus.de>
9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
10 * Ulrich Mueller <ulrich.mueller42@web.de>
c365864f
MR
11 * modified for em2820 based USB TV tuners by
12 * Markus Rechberger <mrechberger@gmail.com>
1da177e4
LT
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/init.h>
33#include <linux/kernel.h>
34#include <linux/sched.h>
35#include <linux/string.h>
36#include <linux/timer.h>
37#include <linux/delay.h>
38#include <linux/errno.h>
39#include <linux/slab.h>
40#include <linux/i2c.h>
41#include <linux/workqueue.h>
1da177e4 42#include <asm/semaphore.h>
1da177e4
LT
43#include <media/ir-common.h>
44
c365864f 45static IR_KEYTAB_TYPE ir_codes_em2820[IR_KEYTAB_SIZE] = {
da45a2a5
MR
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,
c365864f
MR
74};
75
1da177e4
LT
76/* Mark Phalan <phalanm@o2.ie> */
77static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
2f4710b1
MR
78 [ 0x00 ] = KEY_KP0,
79 [ 0x01 ] = KEY_KP1,
80 [ 0x02 ] = KEY_KP2,
81 [ 0x03 ] = KEY_KP3,
82 [ 0x04 ] = KEY_KP4,
83 [ 0x05 ] = KEY_KP5,
84 [ 0x06 ] = KEY_KP6,
85 [ 0x07 ] = KEY_KP7,
86 [ 0x08 ] = KEY_KP8,
87 [ 0x09 ] = KEY_KP9,
88
89 [ 0x12 ] = KEY_POWER,
90 [ 0x10 ] = KEY_MUTE,
91 [ 0x1f ] = KEY_VOLUMEDOWN,
92 [ 0x1b ] = KEY_VOLUMEUP,
93 [ 0x1a ] = KEY_CHANNELUP,
94 [ 0x1e ] = KEY_CHANNELDOWN,
95 [ 0x0e ] = KEY_PAGEUP,
96 [ 0x1d ] = KEY_PAGEDOWN,
97 [ 0x13 ] = KEY_SOUND,
98
99 [ 0x18 ] = KEY_KPPLUSMINUS, /* CH +/- */
100 [ 0x16 ] = KEY_SUBTITLE, /* CC */
101 [ 0x0d ] = KEY_TEXT, /* TTX */
102 [ 0x0b ] = KEY_TV, /* AIR/CBL */
103 [ 0x11 ] = KEY_PC, /* PC/TV */
104 [ 0x17 ] = KEY_OK, /* CH RTN */
105 [ 0x19 ] = KEY_MODE, /* FUNC */
106 [ 0x0c ] = KEY_SEARCH, /* AUTOSCAN */
1da177e4
LT
107
108 /* Not sure what to do with these ones! */
2f4710b1
MR
109 [ 0x0f ] = KEY_SELECT, /* SOURCE */
110 [ 0x0a ] = KEY_KPPLUS, /* +100 */
111 [ 0x14 ] = KEY_KPEQUAL, /* SYNC */
112 [ 0x1c ] = KEY_MEDIA, /* PC/TV */
1da177e4
LT
113};
114
115static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
2f4710b1 116 [ 0x03 ] = KEY_POWER,
1da177e4 117 [ 0x6f ] = KEY_MUTE,
de9c6342 118 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
1da177e4
LT
119
120 [ 0x11 ] = KEY_KP0,
2f4710b1
MR
121 [ 0x04 ] = KEY_KP1,
122 [ 0x05 ] = KEY_KP2,
123 [ 0x06 ] = KEY_KP3,
124 [ 0x08 ] = KEY_KP4,
125 [ 0x09 ] = KEY_KP5,
126 [ 0x0a ] = KEY_KP6,
127 [ 0x0c ] = KEY_KP7,
128 [ 0x0d ] = KEY_KP8,
129 [ 0x0e ] = KEY_KP9,
de9c6342 130 [ 0x12 ] = KEY_KPDOT, /* 100+ */
1da177e4 131
2f4710b1
MR
132 [ 0x07 ] = KEY_VOLUMEUP,
133 [ 0x0b ] = KEY_VOLUMEDOWN,
1da177e4
LT
134 [ 0x1a ] = KEY_KPPLUS,
135 [ 0x18 ] = KEY_KPMINUS,
136 [ 0x15 ] = KEY_UP,
137 [ 0x1d ] = KEY_DOWN,
2f4710b1 138 [ 0x0f ] = KEY_CHANNELUP,
1da177e4
LT
139 [ 0x13 ] = KEY_CHANNELDOWN,
140 [ 0x48 ] = KEY_ZOOM,
141
de9c6342
MCC
142 [ 0x1b ] = KEY_VIDEO, /* Video source */
143 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
144 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
1da177e4
LT
145
146 [ 0x4b ] = KEY_RECORD,
147 [ 0x46 ] = KEY_PLAY,
de9c6342 148 [ 0x45 ] = KEY_PAUSE, /* Pause */
1da177e4 149 [ 0x44 ] = KEY_STOP,
de9c6342
MCC
150 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
151 [ 0x42 ] = KEY_REWIND, /* Backward ? */
1da177e4
LT
152
153};
154
1da177e4
LT
155struct IR {
156 struct i2c_client c;
b7df3910 157 struct input_dev *input;
1da177e4
LT
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/* ----------------------------------------------------------------------- */
167/* insmod parameters */
168
169static int debug;
170module_param(debug, int, 0644); /* debug level (0,1,2) */
171
172#define DEVNAME "ir-kbd-i2c"
173#define dprintk(level, fmt, arg...) if (debug >= level) \
174 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
175
2f4710b1
MR
176#define IR_PINNACLE_REMOTE 0x01
177#define IR_TERRATEC_REMOTE 0x02
178
1da177e4
LT
179/* ----------------------------------------------------------------------- */
180
181static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
182{
183 unsigned char buf[3];
184 int start, toggle, dev, code;
185
186 /* poll IR chip */
187 if (3 != i2c_master_recv(&ir->c,buf,3))
188 return -EIO;
189
190 /* split rc5 data block ... */
191 start = (buf[0] >> 6) & 3;
192 toggle = (buf[0] >> 5) & 1;
193 dev = buf[0] & 0x1f;
194 code = (buf[1] >> 2) & 0x3f;
195
196 if (3 != start)
197 /* no key pressed */
198 return 0;
199 dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
200 start, toggle, dev, code);
201
202 /* return key */
203 *ir_key = code;
204 *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code;
205 return 1;
206}
207
208static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
209{
210 unsigned char b;
211
212 /* poll IR chip */
213 if (1 != i2c_master_recv(&ir->c,&b,1)) {
214 dprintk(1,"read error\n");
215 return -EIO;
216 }
217 *ir_key = b;
218 *ir_raw = b;
219 return 1;
220}
221
222static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
223{
224 unsigned char b;
225
226 /* poll IR chip */
227 if (1 != i2c_master_recv(&ir->c,&b,1)) {
228 dprintk(1,"read error\n");
229 return -EIO;
230 }
231
232 /* ignore 0xaa */
233 if (b==0xaa)
234 return 0;
235 dprintk(2,"key %02x\n", b);
236
237 *ir_key = b;
238 *ir_raw = b;
239 return 1;
240}
241
242static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
243{
244 unsigned char b;
245
246 /* poll IR chip */
247 if (1 != i2c_master_recv(&ir->c,&b,1)) {
248 dprintk(1,"read error\n");
249 return -EIO;
250 }
251
252 /* it seems that 0xFE indicates that a button is still hold
253 down, while 0xFF indicates that no button is hold
254 down. 0xFE sequences are sometimes interrupted by 0xFF */
255
256 dprintk(2,"key %02x\n", b);
257
258 if (b == 0xFF)
259 return 0;
260
261 if (b == 0xFE)
262 /* keep old data */
263 return 1;
264
265 *ir_key = b;
266 *ir_raw = b;
267 return 1;
268}
269
270static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
271{
272 unsigned char b;
273
274 /* poll IR chip */
275 if (1 != i2c_master_recv(&ir->c,&b,1)) {
276 dprintk(1,"read error\n");
277 return -EIO;
278 }
279
280 /* no button press */
281 if (b==0)
282 return 0;
283
284 /* repeating */
285 if (b & 0x80)
286 return 1;
287
288 *ir_key = b;
289 *ir_raw = b;
290 return 1;
291}
2f4710b1 292
1da177e4
LT
293/* ----------------------------------------------------------------------- */
294
295static void ir_key_poll(struct IR *ir)
296{
297 static u32 ir_key, ir_raw;
298 int rc;
299
300 dprintk(2,"ir_poll_key\n");
301 rc = ir->get_key(ir, &ir_key, &ir_raw);
302 if (rc < 0) {
303 dprintk(2,"error\n");
304 return;
305 }
306
307 if (0 == rc) {
b7df3910 308 ir_input_nokey(ir->input, &ir->ir);
1da177e4 309 } else {
b7df3910 310 ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
1da177e4
LT
311 }
312}
313
314static void ir_timer(unsigned long data)
315{
316 struct IR *ir = (struct IR*)data;
317 schedule_work(&ir->work);
318}
319
320static void ir_work(void *data)
321{
322 struct IR *ir = data;
323 ir_key_poll(ir);
324 mod_timer(&ir->timer, jiffies+HZ/10);
325}
326
327/* ----------------------------------------------------------------------- */
328
329static int ir_attach(struct i2c_adapter *adap, int addr,
330 unsigned short flags, int kind);
331static int ir_detach(struct i2c_client *client);
332static int ir_probe(struct i2c_adapter *adap);
333
334static struct i2c_driver driver = {
335 .name = "ir remote kbd driver",
336 .id = I2C_DRIVERID_EXP3, /* FIXME */
337 .flags = I2C_DF_NOTIFY,
338 .attach_adapter = ir_probe,
339 .detach_client = ir_detach,
340};
341
342static struct i2c_client client_template =
343{
fae91e72 344 .name = "unset",
1da177e4
LT
345 .driver = &driver
346};
347
348static int ir_attach(struct i2c_adapter *adap, int addr,
349 unsigned short flags, int kind)
350{
351 IR_KEYTAB_TYPE *ir_codes = NULL;
352 char *name;
353 int ir_type;
354 struct IR *ir;
b7df3910 355 struct input_dev *input_dev;
1da177e4 356
b7df3910
DT
357 ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
358 input_dev = input_allocate_device();
359 if (!ir || !input_dev) {
360 kfree(ir);
361 input_free_device(input_dev);
1da177e4 362 return -ENOMEM;
b7df3910
DT
363 }
364
1da177e4 365 ir->c = client_template;
b7df3910 366 ir->input = input_dev;
1da177e4
LT
367
368 i2c_set_clientdata(&ir->c, ir);
369 ir->c.adapter = adap;
370 ir->c.addr = addr;
371
372 switch(addr) {
373 case 0x64:
374 name = "Pixelview";
375 ir->get_key = get_key_pixelview;
376 ir_type = IR_TYPE_OTHER;
377 ir_codes = ir_codes_empty;
378 break;
379 case 0x4b:
380 name = "PV951";
381 ir->get_key = get_key_pv951;
382 ir_type = IR_TYPE_OTHER;
383 ir_codes = ir_codes_pv951;
384 break;
385 case 0x18:
386 case 0x1a:
387 name = "Hauppauge";
388 ir->get_key = get_key_haup;
389 ir_type = IR_TYPE_RC5;
390 ir_codes = ir_codes_rc5_tv;
391 break;
392 case 0x30:
2f4710b1
MR
393 switch(kind){
394 case IR_TERRATEC_REMOTE:
395 name = "Terratec IR";
396 ir->get_key = get_key_knc1;
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;
da45a2a5 404 ir_codes = ir_codes_empty;
2f4710b1 405 }
1da177e4 406 break;
2f4710b1 407 case 0x47:
1da177e4 408 case 0x7a:
2f4710b1
MR
409 switch(kind){
410 case IR_PINNACLE_REMOTE:
411 name = "Pinnacle IR Remote";
412 ir->get_key = get_key_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;
da45a2a5 420 ir_codes = ir_codes_purpletv;
2f4710b1 421 }
1da177e4
LT
422 break;
423 default:
424 /* shouldn't happen */
425 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
426 kfree(ir);
427 return -1;
428 }
429
430 /* register i2c device */
431 i2c_attach_client(&ir->c);
432 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
433 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
434 ir->c.adapter->dev.bus_id,
435 ir->c.dev.bus_id);
436
437 /* init + register input device */
b7df3910
DT
438 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
439 input_dev->id.bustype = BUS_I2C;
440 input_dev->name = ir->c.name;
441 input_dev->phys = ir->phys;
442
443 input_register_device(ir->input);
1da177e4
LT
444
445 /* start polling via eventd */
446 INIT_WORK(&ir->work, ir_work, ir);
447 init_timer(&ir->timer);
448 ir->timer.function = ir_timer;
449 ir->timer.data = (unsigned long)ir;
450 schedule_work(&ir->work);
451
452 return 0;
453}
454
455static int ir_detach(struct i2c_client *client)
456{
457 struct IR *ir = i2c_get_clientdata(client);
458
459 /* kill outstanding polls */
460 del_timer(&ir->timer);
461 flush_scheduled_work();
462
463 /* unregister devices */
b7df3910 464 input_unregister_device(ir->input);
1da177e4
LT
465 i2c_detach_client(&ir->c);
466
467 /* free memory */
468 kfree(ir);
469 return 0;
470}
471
472static int ir_probe(struct i2c_adapter *adap)
473{
474
475 /* The external IR receiver is at i2c address 0x34 (0x35 for
476 reads). Future Hauppauge cards will have an internal
477 receiver at 0x30 (0x31 for reads). In theory, both can be
478 fitted, and Hauppauge suggest an external overrides an
479 internal.
480
481 That's why we probe 0x1a (~0x34) first. CB
482 */
483
484 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
485 static const int probe_saa7134[] = { 0x7a, -1 };
2f4710b1 486 static const int probe_em2820[] = { 0x47, 0x30, -1 };
1da177e4 487 const int *probe = NULL;
2f4710b1
MR
488 int attached = 0;
489
490 struct i2c_client c; unsigned char buf; int i,rc;
1da177e4
LT
491
492 switch (adap->id) {
c7a46533 493 case I2C_HW_B_BT848:
1da177e4
LT
494 probe = probe_bttv;
495 break;
1684a984 496 case I2C_HW_SAA7134:
1da177e4
LT
497 probe = probe_saa7134;
498 break;
c365864f
MR
499 case I2C_HW_B_EM2820:
500 probe = probe_em2820;
501 break;
1da177e4
LT
502 }
503 if (NULL == probe)
504 return 0;
505
506 memset(&c,0,sizeof(c));
507 c.adapter = adap;
2f4710b1 508 for (i = 0; -1 != probe[i] && attached != 1; i++) {
1da177e4
LT
509 c.addr = probe[i];
510 rc = i2c_master_recv(&c,&buf,1);
511 dprintk(1,"probe 0x%02x @ %s: %s\n",
512 probe[i], adap->name,
513 (1 == rc) ? "yes" : "no");
2f4710b1
MR
514 switch(adap->id){
515 case I2C_HW_B_BT848:
516 case I2C_HW_SAA7134:
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;
1da177e4
LT
529 }
530 }
531 return 0;
532}
533
534/* ----------------------------------------------------------------------- */
535
536MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
537MODULE_DESCRIPTION("input driver for i2c IR remote controls");
538MODULE_LICENSE("GPL");
539
540static int __init ir_init(void)
541{
542 return i2c_add_driver(&driver);
543}
544
545static void __exit ir_fini(void)
546{
547 i2c_del_driver(&driver);
548}
549
550module_init(ir_init);
551module_exit(ir_fini);
552
553/*
554 * Overrides for Emacs so that we follow Linus's tabbing style.
555 * ---------------------------------------------------------------------------
556 * Local variables:
557 * c-basic-offset: 8
558 * End:
559 */
This page took 0.094219 seconds and 5 git commands to generate.