OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [ir-kbd-i2c.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
 * modified for em2820 based USB TV tuners by
12
 *      Markus Rechberger <mrechberger@gmail.com>
13
 * modified for DViCO Fusion HDTV 5 RT GOLD by
14
 *      Chaogui Zhang <czhang1974@gmail.com>
15
 *
16
 *  This program is free software; you can redistribute it and/or modify
17
 *  it under the terms of the GNU General Public License as published by
18
 *  the Free Software Foundation; either version 2 of the License, or
19
 *  (at your option) any later version.
20
 *
21
 *  This program is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  You should have received a copy of the GNU General Public License
27
 *  along with this program; if not, write to the Free Software
28
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29
 *
30
 */
31
 
32
#include <linux/module.h>
33
#include <linux/init.h>
34
#include <linux/kernel.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/i2c-id.h>
42
#include <linux/workqueue.h>
43
#include <asm/semaphore.h>
44
 
45
#include <media/ir-common.h>
46
#include <media/ir-kbd-i2c.h>
47
 
48
/* ----------------------------------------------------------------------- */
49
/* insmod parameters                                                       */
50
 
51
static int debug;
52
module_param(debug, int, 0644);    /* debug level (0,1,2) */
53
 
54
static int hauppauge = 0;
55
module_param(hauppauge, int, 0644);    /* Choose Hauppauge remote */
56
MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)");
57
 
58
 
59
#define DEVNAME "ir-kbd-i2c"
60
#define dprintk(level, fmt, arg...)     if (debug >= level) \
61
        printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
62
 
63
/* ----------------------------------------------------------------------- */
64
 
65
static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
66
                               int size, int offset)
67
{
68
        unsigned char buf[6];
69
        int start, range, toggle, dev, code;
70
 
71
        /* poll IR chip */
72
        if (size != i2c_master_recv(&ir->c,buf,size))
73
                return -EIO;
74
 
75
        /* split rc5 data block ... */
76
        start  = (buf[offset] >> 7) &    1;
77
        range  = (buf[offset] >> 6) &    1;
78
        toggle = (buf[offset] >> 5) &    1;
79
        dev    =  buf[offset]       & 0x1f;
80
        code   = (buf[offset+1] >> 2) & 0x3f;
81
 
82
        /* rc5 has two start bits
83
         * the first bit must be one
84
         * the second bit defines the command range (1 = 0-63, 0 = 64 - 127)
85
         */
86
        if (!start)
87
                /* no key pressed */
88
                return 0;
89
 
90
        if (!range)
91
                code += 64;
92
 
93
        dprintk(1,"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
94
                start, range, toggle, dev, code);
95
 
96
        /* return key */
97
        *ir_key = code;
98
        *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code;
99
        return 1;
100
}
101
 
102
static inline int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
103
{
104
        return get_key_haup_common (ir, ir_key, ir_raw, 3, 0);
105
}
106
 
107
static inline int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
108
{
109
        return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
110
}
111
 
112
static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
113
{
114
        unsigned char b;
115
 
116
        /* poll IR chip */
117
        if (1 != i2c_master_recv(&ir->c,&b,1)) {
118
                dprintk(1,"read error\n");
119
                return -EIO;
120
        }
121
        *ir_key = b;
122
        *ir_raw = b;
123
        return 1;
124
}
125
 
126
static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
127
{
128
        unsigned char b;
129
 
130
        /* poll IR chip */
131
        if (1 != i2c_master_recv(&ir->c,&b,1)) {
132
                dprintk(1,"read error\n");
133
                return -EIO;
134
        }
135
 
136
        /* ignore 0xaa */
137
        if (b==0xaa)
138
                return 0;
139
        dprintk(2,"key %02x\n", b);
140
 
141
        *ir_key = b;
142
        *ir_raw = b;
143
        return 1;
144
}
145
 
146
static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
147
{
148
        unsigned char buf[4];
149
 
150
        /* poll IR chip */
151
        if (4 != i2c_master_recv(&ir->c,buf,4)) {
152
                dprintk(1,"read error\n");
153
                return -EIO;
154
        }
155
 
156
        if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0)
157
                dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __FUNCTION__,
158
                        buf[0], buf[1], buf[2], buf[3]);
159
 
160
        /* no key pressed or signal from other ir remote */
161
        if(buf[0] != 0x1 ||  buf[1] != 0xfe)
162
                return 0;
163
 
164
        *ir_key = buf[2];
165
        *ir_raw = (buf[2] << 8) | buf[3];
166
 
167
        return 1;
168
}
169
 
170
static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
171
{
172
        unsigned char b;
173
 
174
        /* poll IR chip */
175
        if (1 != i2c_master_recv(&ir->c,&b,1)) {
176
                dprintk(1,"read error\n");
177
                return -EIO;
178
        }
179
 
180
        /* it seems that 0xFE indicates that a button is still hold
181
           down, while 0xff indicates that no button is hold
182
           down. 0xfe sequences are sometimes interrupted by 0xFF */
183
 
184
        dprintk(2,"key %02x\n", b);
185
 
186
        if (b == 0xff)
187
                return 0;
188
 
189
        if (b == 0xfe)
190
                /* keep old data */
191
                return 1;
192
 
193
        *ir_key = b;
194
        *ir_raw = b;
195
        return 1;
196
}
197
 
198
/* Common (grey or coloured) pinnacle PCTV remote handling
199
 *
200
 */
201
static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
202
                            int parity_offset, int marker, int code_modulo)
203
{
204
        unsigned char b[4];
205
        unsigned int start = 0,parity = 0,code = 0;
206
 
207
        /* poll IR chip */
208
        if (4 != i2c_master_recv(&ir->c,b,4)) {
209
                dprintk(2,"read error\n");
210
                return -EIO;
211
        }
212
 
213
        for (start = 0; start < ARRAY_SIZE(b); start++) {
214
                if (b[start] == marker) {
215
                        code=b[(start+parity_offset+1)%4];
216
                        parity=b[(start+parity_offset)%4];
217
                }
218
        }
219
 
220
        /* Empty Request */
221
        if (parity==0)
222
                return 0;
223
 
224
        /* Repeating... */
225
        if (ir->old == parity)
226
                return 0;
227
 
228
        ir->old = parity;
229
 
230
        /* drop special codes when a key is held down a long time for the grey controller
231
           In this case, the second bit of the code is asserted */
232
        if (marker == 0xfe && (code & 0x40))
233
                return 0;
234
 
235
        code %= code_modulo;
236
 
237
        *ir_raw = code;
238
        *ir_key = code;
239
 
240
        dprintk(1,"Pinnacle PCTV key %02x\n", code);
241
 
242
        return 1;
243
}
244
 
245
/* The grey pinnacle PCTV remote
246
 *
247
 *  There are one issue with this remote:
248
 *   - I2c packet does not change when the same key is pressed quickly. The workaround
249
 *     is to hold down each key for about half a second, so that another code is generated
250
 *     in the i2c packet, and the function can distinguish key presses.
251
 *
252
 * Sylvain Pasche <sylvain.pasche@gmail.com>
253
 */
254
int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
255
{
256
 
257
        return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff);
258
}
259
 
260
EXPORT_SYMBOL_GPL(get_key_pinnacle_grey);
261
 
262
 
263
/* The new pinnacle PCTV remote (with the colored buttons)
264
 *
265
 * Ricardo Cerqueira <v4l@cerqueira.org>
266
 */
267
int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
268
{
269
        /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE
270
         *
271
         * this is the only value that results in 42 unique
272
         * codes < 128
273
         */
274
 
275
        return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88);
276
}
277
 
278
EXPORT_SYMBOL_GPL(get_key_pinnacle_color);
279
 
280
/* ----------------------------------------------------------------------- */
281
 
282
static void ir_key_poll(struct IR_i2c *ir)
283
{
284
        static u32 ir_key, ir_raw;
285
        int rc;
286
 
287
        dprintk(2,"ir_poll_key\n");
288
        rc = ir->get_key(ir, &ir_key, &ir_raw);
289
        if (rc < 0) {
290
                dprintk(2,"error\n");
291
                return;
292
        }
293
 
294
        if (0 == rc) {
295
                ir_input_nokey(ir->input, &ir->ir);
296
        } else {
297
                ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
298
        }
299
}
300
 
301
static void ir_timer(unsigned long data)
302
{
303
        struct IR_i2c *ir = (struct IR_i2c*)data;
304
        schedule_work(&ir->work);
305
}
306
 
307
static void ir_work(struct work_struct *work)
308
{
309
        struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
310
 
311
        ir_key_poll(ir);
312
        mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100));
313
}
314
 
315
/* ----------------------------------------------------------------------- */
316
 
317
static int ir_attach(struct i2c_adapter *adap, int addr,
318
                      unsigned short flags, int kind);
319
static int ir_detach(struct i2c_client *client);
320
static int ir_probe(struct i2c_adapter *adap);
321
 
322
static struct i2c_driver driver = {
323
        .driver = {
324
                .name   = "ir-kbd-i2c",
325
        },
326
        .id             = I2C_DRIVERID_INFRARED,
327
        .attach_adapter = ir_probe,
328
        .detach_client  = ir_detach,
329
};
330
 
331
static struct i2c_client client_template =
332
{
333
        .name = "unset",
334
        .driver = &driver
335
};
336
 
337
static int ir_attach(struct i2c_adapter *adap, int addr,
338
                     unsigned short flags, int kind)
339
{
340
        IR_KEYTAB_TYPE *ir_codes = NULL;
341
        char *name;
342
        int ir_type;
343
        struct IR_i2c *ir;
344
        struct input_dev *input_dev;
345
        int err;
346
 
347
        ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
348
        input_dev = input_allocate_device();
349
        if (!ir || !input_dev) {
350
                err = -ENOMEM;
351
                goto err_out_free;
352
        }
353
 
354
        ir->c = client_template;
355
        ir->input = input_dev;
356
 
357
        ir->c.adapter = adap;
358
        ir->c.addr    = addr;
359
 
360
        i2c_set_clientdata(&ir->c, ir);
361
 
362
        switch(addr) {
363
        case 0x64:
364
                name        = "Pixelview";
365
                ir->get_key = get_key_pixelview;
366
                ir_type     = IR_TYPE_OTHER;
367
                ir_codes    = ir_codes_empty;
368
                break;
369
        case 0x4b:
370
                name        = "PV951";
371
                ir->get_key = get_key_pv951;
372
                ir_type     = IR_TYPE_OTHER;
373
                ir_codes    = ir_codes_pv951;
374
                break;
375
        case 0x18:
376
        case 0x1a:
377
                name        = "Hauppauge";
378
                ir->get_key = get_key_haup;
379
                ir_type     = IR_TYPE_RC5;
380
                if (hauppauge == 1) {
381
                        ir_codes    = ir_codes_hauppauge_new;
382
                } else {
383
                        ir_codes    = ir_codes_rc5_tv;
384
                }
385
                break;
386
        case 0x30:
387
                name        = "KNC One";
388
                ir->get_key = get_key_knc1;
389
                ir_type     = IR_TYPE_OTHER;
390
                ir_codes    = ir_codes_empty;
391
                break;
392
        case 0x6b:
393
                name        = "FusionHDTV";
394
                ir->get_key = get_key_fusionhdtv;
395
                ir_type     = IR_TYPE_RC5;
396
                ir_codes    = ir_codes_fusionhdtv_mce;
397
                break;
398
        case 0x7a:
399
        case 0x47:
400
        case 0x71:
401
                if (adap->id == I2C_HW_B_CX2388x) {
402
                        /* Handled by cx88-input */
403
                        name        = "CX2388x remote";
404
                        ir_type     = IR_TYPE_RC5;
405
                        ir->get_key = get_key_haup_xvr;
406
                        if (hauppauge == 1) {
407
                                ir_codes    = ir_codes_hauppauge_new;
408
                        } else {
409
                                ir_codes    = ir_codes_rc5_tv;
410
                        }
411
                } else {
412
                        /* Handled by saa7134-input */
413
                        name        = "SAA713x remote";
414
                        ir_type     = IR_TYPE_OTHER;
415
                }
416
                break;
417
        default:
418
                /* shouldn't happen */
419
                printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
420
                err = -ENODEV;
421
                goto err_out_free;
422
        }
423
 
424
        /* Sets name */
425
        snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
426
        ir->ir_codes = ir_codes;
427
 
428
        /* register i2c device
429
         * At device register, IR codes may be changed to be
430
         * board dependent.
431
         */
432
        err = i2c_attach_client(&ir->c);
433
        if (err)
434
                goto err_out_free;
435
 
436
        /* If IR not supported or disabled, unregisters driver */
437
        if (ir->get_key == NULL) {
438
                err = -ENODEV;
439
                goto err_out_detach;
440
        }
441
 
442
        /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
443
        snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
444
                 ir->c.adapter->dev.bus_id,
445
                 ir->c.dev.bus_id);
446
 
447
        /* init + register input device */
448
        ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
449
        input_dev->id.bustype = BUS_I2C;
450
        input_dev->name       = ir->c.name;
451
        input_dev->phys       = ir->phys;
452
 
453
        err = input_register_device(ir->input);
454
        if (err)
455
                goto err_out_detach;
456
 
457
        printk(DEVNAME ": %s detected at %s [%s]\n",
458
               ir->input->name, ir->input->phys, adap->name);
459
 
460
        /* start polling via eventd */
461
        INIT_WORK(&ir->work, ir_work);
462
        init_timer(&ir->timer);
463
        ir->timer.function = ir_timer;
464
        ir->timer.data     = (unsigned long)ir;
465
        schedule_work(&ir->work);
466
 
467
        return 0;
468
 
469
 err_out_detach:
470
        i2c_detach_client(&ir->c);
471
 err_out_free:
472
        input_free_device(input_dev);
473
        kfree(ir);
474
        return err;
475
}
476
 
477
static int ir_detach(struct i2c_client *client)
478
{
479
        struct IR_i2c *ir = i2c_get_clientdata(client);
480
 
481
        /* kill outstanding polls */
482
        del_timer_sync(&ir->timer);
483
        flush_scheduled_work();
484
 
485
        /* unregister devices */
486
        input_unregister_device(ir->input);
487
        i2c_detach_client(&ir->c);
488
 
489
        /* free memory */
490
        kfree(ir);
491
        return 0;
492
}
493
 
494
static int ir_probe(struct i2c_adapter *adap)
495
{
496
 
497
        /* The external IR receiver is at i2c address 0x34 (0x35 for
498
           reads).  Future Hauppauge cards will have an internal
499
           receiver at 0x30 (0x31 for reads).  In theory, both can be
500
           fitted, and Hauppauge suggest an external overrides an
501
           internal.
502
 
503
           That's why we probe 0x1a (~0x34) first. CB
504
        */
505
 
506
        static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
507
        static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 };
508
        static const int probe_em28XX[] = { 0x30, 0x47, -1 };
509
        static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
510
        static const int probe_cx23885[] = { 0x6b, -1 };
511
        const int *probe = NULL;
512
        struct i2c_client c;
513
        unsigned char buf;
514
        int i,rc;
515
 
516
        switch (adap->id) {
517
        case I2C_HW_B_BT848:
518
                probe = probe_bttv;
519
                break;
520
        case I2C_HW_B_CX2341X:
521
                probe = probe_bttv;
522
                break;
523
        case I2C_HW_SAA7134:
524
                probe = probe_saa7134;
525
                break;
526
        case I2C_HW_B_EM28XX:
527
                probe = probe_em28XX;
528
                break;
529
        case I2C_HW_B_CX2388x:
530
                probe = probe_cx88;
531
                break;
532
        case I2C_HW_B_CX23885:
533
                probe = probe_cx23885;
534
                break;
535
        }
536
        if (NULL == probe)
537
                return 0;
538
 
539
        memset(&c,0,sizeof(c));
540
        c.adapter = adap;
541
        for (i = 0; -1 != probe[i]; i++) {
542
                c.addr = probe[i];
543
                rc = i2c_master_recv(&c,&buf,0);
544
                dprintk(1,"probe 0x%02x @ %s: %s\n",
545
                        probe[i], adap->name,
546
                        (0 == rc) ? "yes" : "no");
547
                if (0 == rc) {
548
                        ir_attach(adap,probe[i],0,0);
549
                        break;
550
                }
551
        }
552
        return 0;
553
}
554
 
555
/* ----------------------------------------------------------------------- */
556
 
557
MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
558
MODULE_DESCRIPTION("input driver for i2c IR remote controls");
559
MODULE_LICENSE("GPL");
560
 
561
static int __init ir_init(void)
562
{
563
        return i2c_add_driver(&driver);
564
}
565
 
566
static void __exit ir_fini(void)
567
{
568
        i2c_del_driver(&driver);
569
}
570
 
571
module_init(ir_init);
572
module_exit(ir_fini);
573
 
574
/*
575
 * Overrides for Emacs so that we follow Linus's tabbing style.
576
 * ---------------------------------------------------------------------------
577
 * Local variables:
578
 * c-basic-offset: 8
579
 * End:
580
 */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.