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