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