blob: 061dda10721b011305fb4bdd932ddf6b81c4153b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
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>
Markus Rechbergerc3658642005-11-08 21:37:21 -080011 * modified for em2820 based USB TV tuners by
12 * Markus Rechberger <mrechberger@gmail.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 *
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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/semaphore.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <media/ir-common.h>
44
Markus Rechbergerc3658642005-11-08 21:37:21 -080045static IR_KEYTAB_TYPE ir_codes_em2820[IR_KEYTAB_SIZE] = {
46 [ 0 ] = KEY_CHANNEL,
47 [ 1 ] = KEY_SELECT,
48 [ 2 ] = KEY_MUTE,
49 [ 3 ] = KEY_POWER,
50 [ 4 ] = KEY_KP1,
51 [ 5 ] = KEY_KP2,
52 [ 6 ] = KEY_KP3,
53 [ 7 ] = KEY_CHANNELUP,
54 [ 8 ] = KEY_KP4,
55 [ 9 ] = KEY_KP5,
56 [ 10 ] = KEY_KP6,
57
58 [ 11 ] = KEY_CHANNELDOWN,
59 [ 12 ] = KEY_KP7,
60 [ 13 ] = KEY_KP8,
61 [ 14 ] = KEY_KP9,
62 [ 15 ] = KEY_VOLUMEUP,
63 [ 16 ] = KEY_KP0,
64 [ 17 ] = KEY_MENU,
65 [ 18 ] = KEY_PRINT,
66
67 [ 19 ] = KEY_VOLUMEDOWN,
68 [ 21 ] = KEY_PAUSE,
69 [ 23 ] = KEY_RECORD,
70 [ 24 ] = KEY_REWIND,
71 [ 25 ] = KEY_PLAY,
72 [ 27 ] = KEY_BACKSPACE,
73 [ 29 ] = KEY_STOP,
74 [ 31 ] = KEY_ZOOM,
75};
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077/* Mark Phalan <phalanm@o2.ie> */
78static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
79 [ 0 ] = KEY_KP0,
80 [ 1 ] = KEY_KP1,
81 [ 2 ] = KEY_KP2,
82 [ 3 ] = KEY_KP3,
83 [ 4 ] = KEY_KP4,
84 [ 5 ] = KEY_KP5,
85 [ 6 ] = KEY_KP6,
86 [ 7 ] = KEY_KP7,
87 [ 8 ] = KEY_KP8,
88 [ 9 ] = KEY_KP9,
89
90 [ 18 ] = KEY_POWER,
91 [ 16 ] = KEY_MUTE,
92 [ 31 ] = KEY_VOLUMEDOWN,
93 [ 27 ] = KEY_VOLUMEUP,
94 [ 26 ] = KEY_CHANNELUP,
95 [ 30 ] = KEY_CHANNELDOWN,
96 [ 14 ] = KEY_PAGEUP,
97 [ 29 ] = KEY_PAGEDOWN,
98 [ 19 ] = KEY_SOUND,
99
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700100 [ 24 ] = KEY_KPPLUSMINUS, /* CH +/- */
101 [ 22 ] = KEY_SUBTITLE, /* CC */
102 [ 13 ] = KEY_TEXT, /* TTX */
103 [ 11 ] = KEY_TV, /* AIR/CBL */
104 [ 17 ] = KEY_PC, /* PC/TV */
105 [ 23 ] = KEY_OK, /* CH RTN */
106 [ 25 ] = KEY_MODE, /* FUNC */
107 [ 12 ] = KEY_SEARCH, /* AUTOSCAN */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
109 /* Not sure what to do with these ones! */
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700110 [ 15 ] = KEY_SELECT, /* SOURCE */
111 [ 10 ] = KEY_KPPLUS, /* +100 */
112 [ 20 ] = KEY_KPEQUAL, /* SYNC */
113 [ 28 ] = KEY_MEDIA, /* PC/TV */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114};
115
116static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
117 [ 0x3 ] = KEY_POWER,
118 [ 0x6f ] = KEY_MUTE,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700119 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
121 [ 0x11 ] = KEY_KP0,
122 [ 0x4 ] = KEY_KP1,
123 [ 0x5 ] = KEY_KP2,
124 [ 0x6 ] = KEY_KP3,
125 [ 0x8 ] = KEY_KP4,
126 [ 0x9 ] = KEY_KP5,
127 [ 0xa ] = KEY_KP6,
128 [ 0xc ] = KEY_KP7,
129 [ 0xd ] = KEY_KP8,
130 [ 0xe ] = KEY_KP9,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700131 [ 0x12 ] = KEY_KPDOT, /* 100+ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133 [ 0x7 ] = KEY_VOLUMEUP,
134 [ 0xb ] = KEY_VOLUMEDOWN,
135 [ 0x1a ] = KEY_KPPLUS,
136 [ 0x18 ] = KEY_KPMINUS,
137 [ 0x15 ] = KEY_UP,
138 [ 0x1d ] = KEY_DOWN,
139 [ 0xf ] = KEY_CHANNELUP,
140 [ 0x13 ] = KEY_CHANNELDOWN,
141 [ 0x48 ] = KEY_ZOOM,
142
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700143 [ 0x1b ] = KEY_VIDEO, /* Video source */
144 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
145 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
147 [ 0x4b ] = KEY_RECORD,
148 [ 0x46 ] = KEY_PLAY,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700149 [ 0x45 ] = KEY_PAUSE, /* Pause */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 [ 0x44 ] = KEY_STOP,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700151 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
152 [ 0x42 ] = KEY_REWIND, /* Backward ? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153
154};
155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156struct IR {
157 struct i2c_client c;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500158 struct input_dev *input;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 struct ir_input_state ir;
160
161 struct work_struct work;
162 struct timer_list timer;
163 char phys[32];
164 int (*get_key)(struct IR*, u32*, u32*);
165};
166
167/* ----------------------------------------------------------------------- */
168/* insmod parameters */
169
170static int debug;
171module_param(debug, int, 0644); /* debug level (0,1,2) */
172
173#define DEVNAME "ir-kbd-i2c"
174#define dprintk(level, fmt, arg...) if (debug >= level) \
175 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
176
177/* ----------------------------------------------------------------------- */
178
179static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
180{
181 unsigned char buf[3];
182 int start, toggle, dev, code;
183
184 /* poll IR chip */
185 if (3 != i2c_master_recv(&ir->c,buf,3))
186 return -EIO;
187
188 /* split rc5 data block ... */
189 start = (buf[0] >> 6) & 3;
190 toggle = (buf[0] >> 5) & 1;
191 dev = buf[0] & 0x1f;
192 code = (buf[1] >> 2) & 0x3f;
193
194 if (3 != start)
195 /* no key pressed */
196 return 0;
197 dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
198 start, toggle, dev, code);
199
200 /* return key */
201 *ir_key = code;
202 *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code;
203 return 1;
204}
205
206static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
207{
208 unsigned char b;
209
210 /* poll IR chip */
211 if (1 != i2c_master_recv(&ir->c,&b,1)) {
212 dprintk(1,"read error\n");
213 return -EIO;
214 }
215 *ir_key = b;
216 *ir_raw = b;
217 return 1;
218}
219
220static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
221{
222 unsigned char b;
223
224 /* poll IR chip */
225 if (1 != i2c_master_recv(&ir->c,&b,1)) {
226 dprintk(1,"read error\n");
227 return -EIO;
228 }
229
230 /* ignore 0xaa */
231 if (b==0xaa)
232 return 0;
233 dprintk(2,"key %02x\n", b);
234
235 *ir_key = b;
236 *ir_raw = b;
237 return 1;
238}
239
240static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
241{
242 unsigned char b;
243
244 /* poll IR chip */
245 if (1 != i2c_master_recv(&ir->c,&b,1)) {
246 dprintk(1,"read error\n");
247 return -EIO;
248 }
249
250 /* it seems that 0xFE indicates that a button is still hold
251 down, while 0xFF indicates that no button is hold
252 down. 0xFE sequences are sometimes interrupted by 0xFF */
253
254 dprintk(2,"key %02x\n", b);
255
256 if (b == 0xFF)
257 return 0;
258
259 if (b == 0xFE)
260 /* keep old data */
261 return 1;
262
263 *ir_key = b;
264 *ir_raw = b;
265 return 1;
266}
267
268static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
269{
270 unsigned char b;
271
272 /* poll IR chip */
273 if (1 != i2c_master_recv(&ir->c,&b,1)) {
274 dprintk(1,"read error\n");
275 return -EIO;
276 }
277
278 /* no button press */
279 if (b==0)
280 return 0;
281
282 /* repeating */
283 if (b & 0x80)
284 return 1;
285
286 *ir_key = b;
287 *ir_raw = b;
288 return 1;
289}
290/* ----------------------------------------------------------------------- */
291
292static void ir_key_poll(struct IR *ir)
293{
294 static u32 ir_key, ir_raw;
295 int rc;
296
297 dprintk(2,"ir_poll_key\n");
298 rc = ir->get_key(ir, &ir_key, &ir_raw);
299 if (rc < 0) {
300 dprintk(2,"error\n");
301 return;
302 }
303
304 if (0 == rc) {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500305 ir_input_nokey(ir->input, &ir->ir);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 } else {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500307 ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 }
309}
310
311static void ir_timer(unsigned long data)
312{
313 struct IR *ir = (struct IR*)data;
314 schedule_work(&ir->work);
315}
316
317static void ir_work(void *data)
318{
319 struct IR *ir = data;
320 ir_key_poll(ir);
321 mod_timer(&ir->timer, jiffies+HZ/10);
322}
323
324/* ----------------------------------------------------------------------- */
325
326static int ir_attach(struct i2c_adapter *adap, int addr,
327 unsigned short flags, int kind);
328static int ir_detach(struct i2c_client *client);
329static int ir_probe(struct i2c_adapter *adap);
330
331static struct i2c_driver driver = {
332 .name = "ir remote kbd driver",
333 .id = I2C_DRIVERID_EXP3, /* FIXME */
334 .flags = I2C_DF_NOTIFY,
335 .attach_adapter = ir_probe,
336 .detach_client = ir_detach,
337};
338
339static struct i2c_client client_template =
340{
Jean Delvarefae91e72005-08-15 19:57:04 +0200341 .name = "unset",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 .driver = &driver
343};
344
345static int ir_attach(struct i2c_adapter *adap, int addr,
346 unsigned short flags, int kind)
347{
348 IR_KEYTAB_TYPE *ir_codes = NULL;
349 char *name;
350 int ir_type;
351 struct IR *ir;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500352 struct input_dev *input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500354 ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
355 input_dev = input_allocate_device();
356 if (!ir || !input_dev) {
357 kfree(ir);
358 input_free_device(input_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 return -ENOMEM;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500360 }
361
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 ir->c = client_template;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500363 ir->input = input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364
365 i2c_set_clientdata(&ir->c, ir);
366 ir->c.adapter = adap;
367 ir->c.addr = addr;
368
369 switch(addr) {
370 case 0x64:
371 name = "Pixelview";
372 ir->get_key = get_key_pixelview;
373 ir_type = IR_TYPE_OTHER;
374 ir_codes = ir_codes_empty;
375 break;
376 case 0x4b:
377 name = "PV951";
378 ir->get_key = get_key_pv951;
379 ir_type = IR_TYPE_OTHER;
380 ir_codes = ir_codes_pv951;
381 break;
382 case 0x18:
383 case 0x1a:
384 name = "Hauppauge";
385 ir->get_key = get_key_haup;
386 ir_type = IR_TYPE_RC5;
387 ir_codes = ir_codes_rc5_tv;
388 break;
Markus Rechbergerc3658642005-11-08 21:37:21 -0800389 case 0x60:
390 name = "em2820";
391 ir->get_key = get_key_knc1;
392 ir->c.addr = addr>>1;
393 ir_type = IR_TYPE_OTHER;
394 ir_codes = ir_codes_em2820;
395 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 case 0x30:
397 name = "KNC One";
398 ir->get_key = get_key_knc1;
399 ir_type = IR_TYPE_OTHER;
400 ir_codes = ir_codes_empty;
401 break;
402 case 0x7a:
403 name = "Purple TV";
404 ir->get_key = get_key_purpletv;
405 ir_type = IR_TYPE_OTHER;
406 ir_codes = ir_codes_purpletv;
407 break;
408 default:
409 /* shouldn't happen */
410 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
411 kfree(ir);
412 return -1;
413 }
414
415 /* register i2c device */
416 i2c_attach_client(&ir->c);
417 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
418 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
419 ir->c.adapter->dev.bus_id,
420 ir->c.dev.bus_id);
421
422 /* init + register input device */
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500423 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
424 input_dev->id.bustype = BUS_I2C;
425 input_dev->name = ir->c.name;
426 input_dev->phys = ir->phys;
427
428 input_register_device(ir->input);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430 /* start polling via eventd */
431 INIT_WORK(&ir->work, ir_work, ir);
432 init_timer(&ir->timer);
433 ir->timer.function = ir_timer;
434 ir->timer.data = (unsigned long)ir;
435 schedule_work(&ir->work);
436
437 return 0;
438}
439
440static int ir_detach(struct i2c_client *client)
441{
442 struct IR *ir = i2c_get_clientdata(client);
443
444 /* kill outstanding polls */
445 del_timer(&ir->timer);
446 flush_scheduled_work();
447
448 /* unregister devices */
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500449 input_unregister_device(ir->input);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 i2c_detach_client(&ir->c);
451
452 /* free memory */
453 kfree(ir);
454 return 0;
455}
456
457static int ir_probe(struct i2c_adapter *adap)
458{
459
460 /* The external IR receiver is at i2c address 0x34 (0x35 for
461 reads). Future Hauppauge cards will have an internal
462 receiver at 0x30 (0x31 for reads). In theory, both can be
463 fitted, and Hauppauge suggest an external overrides an
464 internal.
465
466 That's why we probe 0x1a (~0x34) first. CB
467 */
468
469 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
470 static const int probe_saa7134[] = { 0x7a, -1 };
Markus Rechbergerc3658642005-11-08 21:37:21 -0800471 static const int probe_em2820[] = { 0x60, -1 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 const int *probe = NULL;
473 struct i2c_client c; char buf; int i,rc;
474
475 switch (adap->id) {
Jean Delvarec7a46532005-08-11 23:41:56 +0200476 case I2C_HW_B_BT848:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 probe = probe_bttv;
478 break;
Jean Delvare1684a9842005-08-11 23:51:10 +0200479 case I2C_HW_SAA7134:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 probe = probe_saa7134;
481 break;
Markus Rechbergerc3658642005-11-08 21:37:21 -0800482 case I2C_HW_B_EM2820:
483 probe = probe_em2820;
484 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 }
486 if (NULL == probe)
487 return 0;
488
489 memset(&c,0,sizeof(c));
490 c.adapter = adap;
491 for (i = 0; -1 != probe[i]; i++) {
492 c.addr = probe[i];
493 rc = i2c_master_recv(&c,&buf,1);
494 dprintk(1,"probe 0x%02x @ %s: %s\n",
495 probe[i], adap->name,
496 (1 == rc) ? "yes" : "no");
497 if (1 == rc) {
498 ir_attach(adap,probe[i],0,0);
499 break;
500 }
501 }
502 return 0;
503}
504
505/* ----------------------------------------------------------------------- */
506
507MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
508MODULE_DESCRIPTION("input driver for i2c IR remote controls");
509MODULE_LICENSE("GPL");
510
511static int __init ir_init(void)
512{
513 return i2c_add_driver(&driver);
514}
515
516static void __exit ir_fini(void)
517{
518 i2c_del_driver(&driver);
519}
520
521module_init(ir_init);
522module_exit(ir_fini);
523
524/*
525 * Overrides for Emacs so that we follow Linus's tabbing style.
526 * ---------------------------------------------------------------------------
527 * Local variables:
528 * c-basic-offset: 8
529 * End:
530 */