blob: 9703d3d351f94309b651b49a53fa9ab2cdee1e6b [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>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/sched.h>
33#include <linux/string.h>
34#include <linux/timer.h>
35#include <linux/delay.h>
36#include <linux/errno.h>
37#include <linux/slab.h>
38#include <linux/i2c.h>
39#include <linux/workqueue.h>
40
41#include <asm/semaphore.h>
42
43#include <media/ir-common.h>
44
45/* Mark Phalan <phalanm@o2.ie> */
46static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
47 [ 0 ] = KEY_KP0,
48 [ 1 ] = KEY_KP1,
49 [ 2 ] = KEY_KP2,
50 [ 3 ] = KEY_KP3,
51 [ 4 ] = KEY_KP4,
52 [ 5 ] = KEY_KP5,
53 [ 6 ] = KEY_KP6,
54 [ 7 ] = KEY_KP7,
55 [ 8 ] = KEY_KP8,
56 [ 9 ] = KEY_KP9,
57
58 [ 18 ] = KEY_POWER,
59 [ 16 ] = KEY_MUTE,
60 [ 31 ] = KEY_VOLUMEDOWN,
61 [ 27 ] = KEY_VOLUMEUP,
62 [ 26 ] = KEY_CHANNELUP,
63 [ 30 ] = KEY_CHANNELDOWN,
64 [ 14 ] = KEY_PAGEUP,
65 [ 29 ] = KEY_PAGEDOWN,
66 [ 19 ] = KEY_SOUND,
67
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -070068 [ 24 ] = KEY_KPPLUSMINUS, /* CH +/- */
69 [ 22 ] = KEY_SUBTITLE, /* CC */
70 [ 13 ] = KEY_TEXT, /* TTX */
71 [ 11 ] = KEY_TV, /* AIR/CBL */
72 [ 17 ] = KEY_PC, /* PC/TV */
73 [ 23 ] = KEY_OK, /* CH RTN */
74 [ 25 ] = KEY_MODE, /* FUNC */
75 [ 12 ] = KEY_SEARCH, /* AUTOSCAN */
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
77 /* Not sure what to do with these ones! */
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -070078 [ 15 ] = KEY_SELECT, /* SOURCE */
79 [ 10 ] = KEY_KPPLUS, /* +100 */
80 [ 20 ] = KEY_KPEQUAL, /* SYNC */
81 [ 28 ] = KEY_MEDIA, /* PC/TV */
Linus Torvalds1da177e2005-04-16 15:20:36 -070082};
83
84static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
85 [ 0x3 ] = KEY_POWER,
86 [ 0x6f ] = KEY_MUTE,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -070087 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89 [ 0x11 ] = KEY_KP0,
90 [ 0x4 ] = KEY_KP1,
91 [ 0x5 ] = KEY_KP2,
92 [ 0x6 ] = KEY_KP3,
93 [ 0x8 ] = KEY_KP4,
94 [ 0x9 ] = KEY_KP5,
95 [ 0xa ] = KEY_KP6,
96 [ 0xc ] = KEY_KP7,
97 [ 0xd ] = KEY_KP8,
98 [ 0xe ] = KEY_KP9,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -070099 [ 0x12 ] = KEY_KPDOT, /* 100+ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
101 [ 0x7 ] = KEY_VOLUMEUP,
102 [ 0xb ] = KEY_VOLUMEDOWN,
103 [ 0x1a ] = KEY_KPPLUS,
104 [ 0x18 ] = KEY_KPMINUS,
105 [ 0x15 ] = KEY_UP,
106 [ 0x1d ] = KEY_DOWN,
107 [ 0xf ] = KEY_CHANNELUP,
108 [ 0x13 ] = KEY_CHANNELDOWN,
109 [ 0x48 ] = KEY_ZOOM,
110
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700111 [ 0x1b ] = KEY_VIDEO, /* Video source */
112 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
113 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
115 [ 0x4b ] = KEY_RECORD,
116 [ 0x46 ] = KEY_PLAY,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700117 [ 0x45 ] = KEY_PAUSE, /* Pause */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 [ 0x44 ] = KEY_STOP,
Mauro Carvalho Chehabde9c6342005-07-12 13:58:41 -0700119 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
120 [ 0x42 ] = KEY_REWIND, /* Backward ? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
122};
123
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124struct IR {
125 struct i2c_client c;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500126 struct input_dev *input;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 struct ir_input_state ir;
128
129 struct work_struct work;
130 struct timer_list timer;
131 char phys[32];
132 int (*get_key)(struct IR*, u32*, u32*);
133};
134
135/* ----------------------------------------------------------------------- */
136/* insmod parameters */
137
138static int debug;
139module_param(debug, int, 0644); /* debug level (0,1,2) */
140
141#define DEVNAME "ir-kbd-i2c"
142#define dprintk(level, fmt, arg...) if (debug >= level) \
143 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
144
145/* ----------------------------------------------------------------------- */
146
147static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
148{
149 unsigned char buf[3];
150 int start, toggle, dev, code;
151
152 /* poll IR chip */
153 if (3 != i2c_master_recv(&ir->c,buf,3))
154 return -EIO;
155
156 /* split rc5 data block ... */
157 start = (buf[0] >> 6) & 3;
158 toggle = (buf[0] >> 5) & 1;
159 dev = buf[0] & 0x1f;
160 code = (buf[1] >> 2) & 0x3f;
161
162 if (3 != start)
163 /* no key pressed */
164 return 0;
165 dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
166 start, toggle, dev, code);
167
168 /* return key */
169 *ir_key = code;
170 *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code;
171 return 1;
172}
173
174static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
175{
176 unsigned char b;
177
178 /* poll IR chip */
179 if (1 != i2c_master_recv(&ir->c,&b,1)) {
180 dprintk(1,"read error\n");
181 return -EIO;
182 }
183 *ir_key = b;
184 *ir_raw = b;
185 return 1;
186}
187
188static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
189{
190 unsigned char b;
191
192 /* poll IR chip */
193 if (1 != i2c_master_recv(&ir->c,&b,1)) {
194 dprintk(1,"read error\n");
195 return -EIO;
196 }
197
198 /* ignore 0xaa */
199 if (b==0xaa)
200 return 0;
201 dprintk(2,"key %02x\n", b);
202
203 *ir_key = b;
204 *ir_raw = b;
205 return 1;
206}
207
208static int get_key_knc1(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
218 /* it seems that 0xFE indicates that a button is still hold
219 down, while 0xFF indicates that no button is hold
220 down. 0xFE sequences are sometimes interrupted by 0xFF */
221
222 dprintk(2,"key %02x\n", b);
223
224 if (b == 0xFF)
225 return 0;
226
227 if (b == 0xFE)
228 /* keep old data */
229 return 1;
230
231 *ir_key = b;
232 *ir_raw = b;
233 return 1;
234}
235
236static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
237{
238 unsigned char b;
239
240 /* poll IR chip */
241 if (1 != i2c_master_recv(&ir->c,&b,1)) {
242 dprintk(1,"read error\n");
243 return -EIO;
244 }
245
246 /* no button press */
247 if (b==0)
248 return 0;
249
250 /* repeating */
251 if (b & 0x80)
252 return 1;
253
254 *ir_key = b;
255 *ir_raw = b;
256 return 1;
257}
258/* ----------------------------------------------------------------------- */
259
260static void ir_key_poll(struct IR *ir)
261{
262 static u32 ir_key, ir_raw;
263 int rc;
264
265 dprintk(2,"ir_poll_key\n");
266 rc = ir->get_key(ir, &ir_key, &ir_raw);
267 if (rc < 0) {
268 dprintk(2,"error\n");
269 return;
270 }
271
272 if (0 == rc) {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500273 ir_input_nokey(ir->input, &ir->ir);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 } else {
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500275 ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 }
277}
278
279static void ir_timer(unsigned long data)
280{
281 struct IR *ir = (struct IR*)data;
282 schedule_work(&ir->work);
283}
284
285static void ir_work(void *data)
286{
287 struct IR *ir = data;
288 ir_key_poll(ir);
289 mod_timer(&ir->timer, jiffies+HZ/10);
290}
291
292/* ----------------------------------------------------------------------- */
293
294static int ir_attach(struct i2c_adapter *adap, int addr,
295 unsigned short flags, int kind);
296static int ir_detach(struct i2c_client *client);
297static int ir_probe(struct i2c_adapter *adap);
298
299static struct i2c_driver driver = {
300 .name = "ir remote kbd driver",
301 .id = I2C_DRIVERID_EXP3, /* FIXME */
302 .flags = I2C_DF_NOTIFY,
303 .attach_adapter = ir_probe,
304 .detach_client = ir_detach,
305};
306
307static struct i2c_client client_template =
308{
Jean Delvarefae91e72005-08-15 19:57:04 +0200309 .name = "unset",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 .driver = &driver
311};
312
313static int ir_attach(struct i2c_adapter *adap, int addr,
314 unsigned short flags, int kind)
315{
316 IR_KEYTAB_TYPE *ir_codes = NULL;
317 char *name;
318 int ir_type;
319 struct IR *ir;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500320 struct input_dev *input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500322 ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
323 input_dev = input_allocate_device();
324 if (!ir || !input_dev) {
325 kfree(ir);
326 input_free_device(input_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 return -ENOMEM;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500328 }
329
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 ir->c = client_template;
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500331 ir->input = input_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
333 i2c_set_clientdata(&ir->c, ir);
334 ir->c.adapter = adap;
335 ir->c.addr = addr;
336
337 switch(addr) {
338 case 0x64:
339 name = "Pixelview";
340 ir->get_key = get_key_pixelview;
341 ir_type = IR_TYPE_OTHER;
342 ir_codes = ir_codes_empty;
343 break;
344 case 0x4b:
345 name = "PV951";
346 ir->get_key = get_key_pv951;
347 ir_type = IR_TYPE_OTHER;
348 ir_codes = ir_codes_pv951;
349 break;
350 case 0x18:
351 case 0x1a:
352 name = "Hauppauge";
353 ir->get_key = get_key_haup;
354 ir_type = IR_TYPE_RC5;
355 ir_codes = ir_codes_rc5_tv;
356 break;
357 case 0x30:
358 name = "KNC One";
359 ir->get_key = get_key_knc1;
360 ir_type = IR_TYPE_OTHER;
361 ir_codes = ir_codes_empty;
362 break;
363 case 0x7a:
364 name = "Purple TV";
365 ir->get_key = get_key_purpletv;
366 ir_type = IR_TYPE_OTHER;
367 ir_codes = ir_codes_purpletv;
368 break;
369 default:
370 /* shouldn't happen */
371 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
372 kfree(ir);
373 return -1;
374 }
375
376 /* register i2c device */
377 i2c_attach_client(&ir->c);
378 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
379 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
380 ir->c.adapter->dev.bus_id,
381 ir->c.dev.bus_id);
382
383 /* init + register input device */
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500384 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
385 input_dev->id.bustype = BUS_I2C;
386 input_dev->name = ir->c.name;
387 input_dev->phys = ir->phys;
388
389 input_register_device(ir->input);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
391 /* start polling via eventd */
392 INIT_WORK(&ir->work, ir_work, ir);
393 init_timer(&ir->timer);
394 ir->timer.function = ir_timer;
395 ir->timer.data = (unsigned long)ir;
396 schedule_work(&ir->work);
397
398 return 0;
399}
400
401static int ir_detach(struct i2c_client *client)
402{
403 struct IR *ir = i2c_get_clientdata(client);
404
405 /* kill outstanding polls */
406 del_timer(&ir->timer);
407 flush_scheduled_work();
408
409 /* unregister devices */
Dmitry Torokhovb7df3912005-09-15 02:01:53 -0500410 input_unregister_device(ir->input);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 i2c_detach_client(&ir->c);
412
413 /* free memory */
414 kfree(ir);
415 return 0;
416}
417
418static int ir_probe(struct i2c_adapter *adap)
419{
420
421 /* The external IR receiver is at i2c address 0x34 (0x35 for
422 reads). Future Hauppauge cards will have an internal
423 receiver at 0x30 (0x31 for reads). In theory, both can be
424 fitted, and Hauppauge suggest an external overrides an
425 internal.
426
427 That's why we probe 0x1a (~0x34) first. CB
428 */
429
430 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
431 static const int probe_saa7134[] = { 0x7a, -1 };
432 const int *probe = NULL;
433 struct i2c_client c; char buf; int i,rc;
434
435 switch (adap->id) {
Jean Delvarec7a46532005-08-11 23:41:56 +0200436 case I2C_HW_B_BT848:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 probe = probe_bttv;
438 break;
Jean Delvare1684a9842005-08-11 23:51:10 +0200439 case I2C_HW_SAA7134:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 probe = probe_saa7134;
441 break;
442 }
443 if (NULL == probe)
444 return 0;
445
446 memset(&c,0,sizeof(c));
447 c.adapter = adap;
448 for (i = 0; -1 != probe[i]; i++) {
449 c.addr = probe[i];
450 rc = i2c_master_recv(&c,&buf,1);
451 dprintk(1,"probe 0x%02x @ %s: %s\n",
452 probe[i], adap->name,
453 (1 == rc) ? "yes" : "no");
454 if (1 == rc) {
455 ir_attach(adap,probe[i],0,0);
456 break;
457 }
458 }
459 return 0;
460}
461
462/* ----------------------------------------------------------------------- */
463
464MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
465MODULE_DESCRIPTION("input driver for i2c IR remote controls");
466MODULE_LICENSE("GPL");
467
468static int __init ir_init(void)
469{
470 return i2c_add_driver(&driver);
471}
472
473static void __exit ir_fini(void)
474{
475 i2c_del_driver(&driver);
476}
477
478module_init(ir_init);
479module_exit(ir_fini);
480
481/*
482 * Overrides for Emacs so that we follow Linus's tabbing style.
483 * ---------------------------------------------------------------------------
484 * Local variables:
485 * c-basic-offset: 8
486 * End:
487 */