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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
3
 *
4
 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5
 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6
 *
7
 * Modifications for LML33/DC10plus unified driver
8
 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9
 *
10
 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11
 *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
12
 *
13
 * This code was modify/ported from the saa7111 driver written
14
 * by Dave Perks.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
29
 */
30
 
31
#include <linux/module.h>
32
#include <linux/init.h>
33
#include <linux/delay.h>
34
#include <linux/errno.h>
35
#include <linux/fs.h>
36
#include <linux/kernel.h>
37
#include <linux/major.h>
38
#include <linux/slab.h>
39
#include <linux/mm.h>
40
#include <linux/signal.h>
41
#include <linux/types.h>
42
#include <linux/i2c.h>
43
#include <asm/io.h>
44
#include <asm/pgtable.h>
45
#include <asm/page.h>
46
#include <asm/uaccess.h>
47
 
48
#include <linux/videodev.h>
49
#include <linux/video_decoder.h>
50
 
51
 
52
MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
53
MODULE_AUTHOR("Mike Bernson & Dave Perks");
54
MODULE_LICENSE("GPL");
55
 
56
 
57
#define I2C_NAME(s) (s)->name
58
 
59
 
60
static int debug = 0;
61
module_param(debug, int, 0);
62
MODULE_PARM_DESC(debug, "Debug level (0-1)");
63
 
64
#define dprintk(num, format, args...) \
65
        do { \
66
                if (debug >= num) \
67
                        printk(format, ##args); \
68
        } while (0)
69
 
70
/* ----------------------------------------------------------------------- */
71
 
72
struct bt819 {
73
        unsigned char reg[32];
74
 
75
        int initialized;
76
        int norm;
77
        int input;
78
        int enable;
79
        int bright;
80
        int contrast;
81
        int hue;
82
        int sat;
83
};
84
 
85
struct timing {
86
        int hactive;
87
        int hdelay;
88
        int vactive;
89
        int vdelay;
90
        int hscale;
91
        int vscale;
92
};
93
 
94
/* for values, see the bt819 datasheet */
95
static struct timing timing_data[] = {
96
        {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
97
        {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
98
};
99
 
100
#define   I2C_BT819        0x8a
101
 
102
/* ----------------------------------------------------------------------- */
103
 
104
static inline int
105
bt819_write (struct i2c_client *client,
106
             u8                 reg,
107
             u8                 value)
108
{
109
        struct bt819 *decoder = i2c_get_clientdata(client);
110
 
111
        decoder->reg[reg] = value;
112
        return i2c_smbus_write_byte_data(client, reg, value);
113
}
114
 
115
static inline int
116
bt819_setbit (struct i2c_client *client,
117
              u8                 reg,
118
              u8                 bit,
119
              u8                 value)
120
{
121
        struct bt819 *decoder = i2c_get_clientdata(client);
122
 
123
        return bt819_write(client, reg,
124
                           (decoder->
125
                            reg[reg] & ~(1 << bit)) |
126
                            (value ? (1 << bit) : 0));
127
}
128
 
129
static int
130
bt819_write_block (struct i2c_client *client,
131
                   const u8          *data,
132
                   unsigned int       len)
133
{
134
        int ret = -1;
135
        u8 reg;
136
 
137
        /* the bt819 has an autoincrement function, use it if
138
         * the adapter understands raw I2C */
139
        if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
140
                /* do raw I2C, not smbus compatible */
141
                struct bt819 *decoder = i2c_get_clientdata(client);
142
                u8 block_data[32];
143
                int block_len;
144
 
145
                while (len >= 2) {
146
                        block_len = 0;
147
                        block_data[block_len++] = reg = data[0];
148
                        do {
149
                                block_data[block_len++] =
150
                                    decoder->reg[reg++] = data[1];
151
                                len -= 2;
152
                                data += 2;
153
                        } while (len >= 2 && data[0] == reg &&
154
                                 block_len < 32);
155
                        if ((ret = i2c_master_send(client, block_data,
156
                                                   block_len)) < 0)
157
                                break;
158
                }
159
        } else {
160
                /* do some slow I2C emulation kind of thing */
161
                while (len >= 2) {
162
                        reg = *data++;
163
                        if ((ret = bt819_write(client, reg, *data++)) < 0)
164
                                break;
165
                        len -= 2;
166
                }
167
        }
168
 
169
        return ret;
170
}
171
 
172
static inline int
173
bt819_read (struct i2c_client *client,
174
            u8                 reg)
175
{
176
        return i2c_smbus_read_byte_data(client, reg);
177
}
178
 
179
static int
180
bt819_init (struct i2c_client *client)
181
{
182
        struct bt819 *decoder = i2c_get_clientdata(client);
183
 
184
        static unsigned char init[] = {
185
                //0x1f, 0x00,     /* Reset */
186
                0x01, 0x59,     /* 0x01 input format */
187
                0x02, 0x00,     /* 0x02 temporal decimation */
188
                0x03, 0x12,     /* 0x03 Cropping msb */
189
                0x04, 0x16,     /* 0x04 Vertical Delay, lsb */
190
                0x05, 0xe0,     /* 0x05 Vertical Active lsb */
191
                0x06, 0x80,     /* 0x06 Horizontal Delay lsb */
192
                0x07, 0xd0,     /* 0x07 Horizontal Active lsb */
193
                0x08, 0x00,     /* 0x08 Horizontal Scaling msb */
194
                0x09, 0xf8,     /* 0x09 Horizontal Scaling lsb */
195
                0x0a, 0x00,     /* 0x0a Brightness control */
196
                0x0b, 0x30,     /* 0x0b Miscellaneous control */
197
                0x0c, 0xd8,     /* 0x0c Luma Gain lsb */
198
                0x0d, 0xfe,     /* 0x0d Chroma Gain (U) lsb */
199
                0x0e, 0xb4,     /* 0x0e Chroma Gain (V) msb */
200
                0x0f, 0x00,     /* 0x0f Hue control */
201
                0x12, 0x04,     /* 0x12 Output Format */
202
                0x13, 0x20,     /* 0x13 Vertial Scaling msb 0x00
203
                                           chroma comb OFF, line drop scaling, interlace scaling
204
                                           BUG? Why does turning the chroma comb on fuck up color?
205
                                           Bug in the bt819 stepping on my board?
206
                                        */
207
                0x14, 0x00,     /* 0x14 Vertial Scaling lsb */
208
                0x16, 0x07,     /* 0x16 Video Timing Polarity
209
                                           ACTIVE=active low
210
                                           FIELD: high=odd,
211
                                           vreset=active high,
212
                                           hreset=active high */
213
                0x18, 0x68,     /* 0x18 AGC Delay */
214
                0x19, 0x5d,     /* 0x19 Burst Gate Delay */
215
                0x1a, 0x80,     /* 0x1a ADC Interface */
216
        };
217
 
218
        struct timing *timing = &timing_data[decoder->norm];
219
 
220
        init[0x03 * 2 - 1] =
221
            (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
222
                                                       vactive >> 8) &
223
                                                      0x03) << 4) |
224
            (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
225
                                                      hactive >> 8) &
226
                                                     0x03);
227
        init[0x04 * 2 - 1] = timing->vdelay & 0xff;
228
        init[0x05 * 2 - 1] = timing->vactive & 0xff;
229
        init[0x06 * 2 - 1] = timing->hdelay & 0xff;
230
        init[0x07 * 2 - 1] = timing->hactive & 0xff;
231
        init[0x08 * 2 - 1] = timing->hscale >> 8;
232
        init[0x09 * 2 - 1] = timing->hscale & 0xff;
233
        /* 0x15 in array is address 0x19 */
234
        init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93;    /* Chroma burst delay */
235
        /* reset */
236
        bt819_write(client, 0x1f, 0x00);
237
        mdelay(1);
238
 
239
        /* init */
240
        return bt819_write_block(client, init, sizeof(init));
241
 
242
}
243
 
244
/* ----------------------------------------------------------------------- */
245
 
246
static int
247
bt819_command (struct i2c_client *client,
248
               unsigned int       cmd,
249
               void              *arg)
250
{
251
        int temp;
252
 
253
        struct bt819 *decoder = i2c_get_clientdata(client);
254
 
255
        if (!decoder->initialized) {    // First call to bt819_init could be
256
                bt819_init(client);     // without #FRST = 0
257
                decoder->initialized = 1;
258
        }
259
 
260
        switch (cmd) {
261
 
262
        case 0:
263
                /* This is just for testing!!! */
264
                bt819_init(client);
265
                break;
266
 
267
        case DECODER_GET_CAPABILITIES:
268
        {
269
                struct video_decoder_capability *cap = arg;
270
 
271
                cap->flags = VIDEO_DECODER_PAL |
272
                             VIDEO_DECODER_NTSC |
273
                             VIDEO_DECODER_AUTO |
274
                             VIDEO_DECODER_CCIR;
275
                cap->inputs = 8;
276
                cap->outputs = 1;
277
        }
278
                break;
279
 
280
        case DECODER_GET_STATUS:
281
        {
282
                int *iarg = arg;
283
                int status;
284
                int res;
285
 
286
                status = bt819_read(client, 0x00);
287
                res = 0;
288
                if ((status & 0x80)) {
289
                        res |= DECODER_STATUS_GOOD;
290
                }
291
                switch (decoder->norm) {
292
                case VIDEO_MODE_NTSC:
293
                        res |= DECODER_STATUS_NTSC;
294
                        break;
295
                case VIDEO_MODE_PAL:
296
                        res |= DECODER_STATUS_PAL;
297
                        break;
298
                default:
299
                case VIDEO_MODE_AUTO:
300
                        if ((status & 0x10)) {
301
                                res |= DECODER_STATUS_PAL;
302
                        } else {
303
                                res |= DECODER_STATUS_NTSC;
304
                        }
305
                        break;
306
                }
307
                res |= DECODER_STATUS_COLOR;
308
                *iarg = res;
309
 
310
                dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
311
                        *iarg);
312
        }
313
                break;
314
 
315
        case DECODER_SET_NORM:
316
        {
317
                int *iarg = arg;
318
                struct timing *timing = NULL;
319
 
320
                dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
321
                        *iarg);
322
 
323
                switch (*iarg) {
324
                case VIDEO_MODE_NTSC:
325
                        bt819_setbit(client, 0x01, 0, 1);
326
                        bt819_setbit(client, 0x01, 1, 0);
327
                        bt819_setbit(client, 0x01, 5, 0);
328
                        bt819_write(client, 0x18, 0x68);
329
                        bt819_write(client, 0x19, 0x5d);
330
                        //bt819_setbit(client, 0x1a,  5, 1);
331
                        timing = &timing_data[VIDEO_MODE_NTSC];
332
                        break;
333
                case VIDEO_MODE_PAL:
334
                        bt819_setbit(client, 0x01, 0, 1);
335
                        bt819_setbit(client, 0x01, 1, 1);
336
                        bt819_setbit(client, 0x01, 5, 1);
337
                        bt819_write(client, 0x18, 0x7f);
338
                        bt819_write(client, 0x19, 0x72);
339
                        //bt819_setbit(client, 0x1a,  5, 0);
340
                        timing = &timing_data[VIDEO_MODE_PAL];
341
                        break;
342
                case VIDEO_MODE_AUTO:
343
                        bt819_setbit(client, 0x01, 0, 0);
344
                        bt819_setbit(client, 0x01, 1, 0);
345
                        break;
346
                default:
347
                        dprintk(1,
348
                                KERN_ERR
349
                                "%s: unsupported norm %d\n",
350
                                I2C_NAME(client), *iarg);
351
                        return -EINVAL;
352
                }
353
 
354
                if (timing) {
355
                        bt819_write(client, 0x03,
356
                                    (((timing->vdelay >> 8) & 0x03) << 6) |
357
                                    (((timing->vactive >> 8) & 0x03) << 4) |
358
                                    (((timing->hdelay >> 8) & 0x03) << 2) |
359
                                     ((timing->hactive >> 8) & 0x03) );
360
                        bt819_write(client, 0x04, timing->vdelay & 0xff);
361
                        bt819_write(client, 0x05, timing->vactive & 0xff);
362
                        bt819_write(client, 0x06, timing->hdelay & 0xff);
363
                        bt819_write(client, 0x07, timing->hactive & 0xff);
364
                        bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
365
                        bt819_write(client, 0x09, timing->hscale & 0xff);
366
                }
367
 
368
                decoder->norm = *iarg;
369
        }
370
                break;
371
 
372
        case DECODER_SET_INPUT:
373
        {
374
                int *iarg = arg;
375
 
376
                dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
377
                        *iarg);
378
 
379
                if (*iarg < 0 || *iarg > 7) {
380
                        return -EINVAL;
381
                }
382
 
383
                if (decoder->input != *iarg) {
384
                        decoder->input = *iarg;
385
                        /* select mode */
386
                        if (decoder->input == 0) {
387
                                bt819_setbit(client, 0x0b, 6, 0);
388
                                bt819_setbit(client, 0x1a, 1, 1);
389
                        } else {
390
                                bt819_setbit(client, 0x0b, 6, 1);
391
                                bt819_setbit(client, 0x1a, 1, 0);
392
                        }
393
                }
394
        }
395
                break;
396
 
397
        case DECODER_SET_OUTPUT:
398
        {
399
                int *iarg = arg;
400
 
401
                dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
402
                        *iarg);
403
 
404
                /* not much choice of outputs */
405
                if (*iarg != 0) {
406
                        return -EINVAL;
407
                }
408
        }
409
                break;
410
 
411
        case DECODER_ENABLE_OUTPUT:
412
        {
413
                int *iarg = arg;
414
                int enable = (*iarg != 0);
415
 
416
                dprintk(1, KERN_INFO "%s: enable output %x\n",
417
                        I2C_NAME(client), *iarg);
418
 
419
                if (decoder->enable != enable) {
420
                        decoder->enable = enable;
421
 
422
                        if (decoder->enable) {
423
                                bt819_setbit(client, 0x16, 7, 0);
424
                        } else {
425
                                bt819_setbit(client, 0x16, 7, 1);
426
                        }
427
                }
428
        }
429
                break;
430
 
431
        case DECODER_SET_PICTURE:
432
        {
433
                struct video_picture *pic = arg;
434
 
435
                dprintk(1,
436
                        KERN_INFO
437
                        "%s: set picture brightness %d contrast %d colour %d\n",
438
                        I2C_NAME(client), pic->brightness, pic->contrast,
439
                        pic->colour);
440
 
441
 
442
                if (decoder->bright != pic->brightness) {
443
                        /* We want -128 to 127 we get 0-65535 */
444
                        decoder->bright = pic->brightness;
445
                        bt819_write(client, 0x0a,
446
                                    (decoder->bright >> 8) - 128);
447
                }
448
 
449
                if (decoder->contrast != pic->contrast) {
450
                        /* We want 0 to 511 we get 0-65535 */
451
                        decoder->contrast = pic->contrast;
452
                        bt819_write(client, 0x0c,
453
                                    (decoder->contrast >> 7) & 0xff);
454
                        bt819_setbit(client, 0x0b, 2,
455
                                     ((decoder->contrast >> 15) & 0x01));
456
                }
457
 
458
                if (decoder->sat != pic->colour) {
459
                        /* We want 0 to 511 we get 0-65535 */
460
                        decoder->sat = pic->colour;
461
                        bt819_write(client, 0x0d,
462
                                    (decoder->sat >> 7) & 0xff);
463
                        bt819_setbit(client, 0x0b, 1,
464
                                     ((decoder->sat >> 15) & 0x01));
465
 
466
                        temp = (decoder->sat * 201) / 237;
467
                        bt819_write(client, 0x0e, (temp >> 7) & 0xff);
468
                        bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
469
                }
470
 
471
                if (decoder->hue != pic->hue) {
472
                        /* We want -128 to 127 we get 0-65535 */
473
                        decoder->hue = pic->hue;
474
                        bt819_write(client, 0x0f,
475
                                    128 - (decoder->hue >> 8));
476
                }
477
        }
478
                break;
479
 
480
        default:
481
                return -EINVAL;
482
        }
483
 
484
        return 0;
485
}
486
 
487
/* ----------------------------------------------------------------------- */
488
 
489
/*
490
 * Generic i2c probe
491
 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
492
 */
493
static unsigned short normal_i2c[] = {
494
        I2C_BT819 >> 1,
495
        I2C_CLIENT_END,
496
};
497
 
498
static unsigned short ignore = I2C_CLIENT_END;
499
 
500
static struct i2c_client_address_data addr_data = {
501
        .normal_i2c             = normal_i2c,
502
        .probe                  = &ignore,
503
        .ignore                 = &ignore,
504
};
505
 
506
static struct i2c_driver i2c_driver_bt819;
507
 
508
static int
509
bt819_detect_client (struct i2c_adapter *adapter,
510
                     int                 address,
511
                     int                 kind)
512
{
513
        int i, id;
514
        struct bt819 *decoder;
515
        struct i2c_client *client;
516
 
517
        dprintk(1,
518
                KERN_INFO
519
                "saa7111.c: detecting bt819 client on address 0x%x\n",
520
                address << 1);
521
 
522
        /* Check if the adapter supports the needed features */
523
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
524
                return 0;
525
 
526
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
527
        if (client == 0)
528
                return -ENOMEM;
529
        client->addr = address;
530
        client->adapter = adapter;
531
        client->driver = &i2c_driver_bt819;
532
 
533
        decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
534
        if (decoder == NULL) {
535
                kfree(client);
536
                return -ENOMEM;
537
        }
538
        decoder->norm = VIDEO_MODE_NTSC;
539
        decoder->input = 0;
540
        decoder->enable = 1;
541
        decoder->bright = 32768;
542
        decoder->contrast = 32768;
543
        decoder->hue = 32768;
544
        decoder->sat = 32768;
545
        decoder->initialized = 0;
546
        i2c_set_clientdata(client, decoder);
547
 
548
        id = bt819_read(client, 0x17);
549
        switch (id & 0xf0) {
550
        case 0x70:
551
                strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
552
                break;
553
        case 0x60:
554
                strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
555
                break;
556
        case 0x20:
557
                strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
558
                break;
559
        default:
560
                dprintk(1,
561
                        KERN_ERR
562
                        "bt819: unknown chip version 0x%x (ver 0x%x)\n",
563
                        id & 0xf0, id & 0x0f);
564
                kfree(decoder);
565
                kfree(client);
566
                return 0;
567
        }
568
 
569
        i = i2c_attach_client(client);
570
        if (i) {
571
                kfree(client);
572
                kfree(decoder);
573
                return i;
574
        }
575
 
576
        i = bt819_init(client);
577
        if (i < 0) {
578
                dprintk(1, KERN_ERR "%s_attach: init status %d\n",
579
                        I2C_NAME(client), i);
580
        } else {
581
                dprintk(1,
582
                        KERN_INFO
583
                        "%s_attach: chip version 0x%x at address 0x%x\n",
584
                        I2C_NAME(client), id & 0x0f,
585
                        client->addr << 1);
586
        }
587
 
588
        return 0;
589
}
590
 
591
static int
592
bt819_attach_adapter (struct i2c_adapter *adapter)
593
{
594
        return i2c_probe(adapter, &addr_data, &bt819_detect_client);
595
}
596
 
597
static int
598
bt819_detach_client (struct i2c_client *client)
599
{
600
        struct bt819 *decoder = i2c_get_clientdata(client);
601
        int err;
602
 
603
        err = i2c_detach_client(client);
604
        if (err) {
605
                return err;
606
        }
607
 
608
        kfree(decoder);
609
        kfree(client);
610
 
611
        return 0;
612
}
613
 
614
/* ----------------------------------------------------------------------- */
615
 
616
static struct i2c_driver i2c_driver_bt819 = {
617
        .driver = {
618
                .name = "bt819",
619
        },
620
 
621
        .id = I2C_DRIVERID_BT819,
622
 
623
        .attach_adapter = bt819_attach_adapter,
624
        .detach_client = bt819_detach_client,
625
        .command = bt819_command,
626
};
627
 
628
static int __init
629
bt819_init_module (void)
630
{
631
        return i2c_add_driver(&i2c_driver_bt819);
632
}
633
 
634
static void __exit
635
bt819_exit (void)
636
{
637
        i2c_del_driver(&i2c_driver_bt819);
638
}
639
 
640
module_init(bt819_init_module);
641
module_exit(bt819_exit);

powered by: WebSVN 2.1.0

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