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

Subversion Repositories test_project

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  saa7191.c - Philips SAA7191 video decoder driver
3
 *
4
 *  Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5
 *  Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License version 2 as
9
 *  published by the Free Software Foundation.
10
 */
11
 
12
#include <linux/delay.h>
13
#include <linux/errno.h>
14
#include <linux/fs.h>
15
#include <linux/init.h>
16
#include <linux/kernel.h>
17
#include <linux/major.h>
18
#include <linux/module.h>
19
#include <linux/mm.h>
20
#include <linux/slab.h>
21
 
22
#include <linux/videodev.h>
23
#include <linux/video_decoder.h>
24
#include <linux/i2c.h>
25
 
26
#include "saa7191.h"
27
 
28
#define SAA7191_MODULE_VERSION  "0.0.5"
29
 
30
MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
31
MODULE_VERSION(SAA7191_MODULE_VERSION);
32
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
33
MODULE_LICENSE("GPL");
34
 
35
// #define SAA7191_DEBUG
36
 
37
#ifdef SAA7191_DEBUG
38
#define dprintk(x...) printk("SAA7191: " x);
39
#else
40
#define dprintk(x...)
41
#endif
42
 
43
#define SAA7191_SYNC_COUNT      30
44
#define SAA7191_SYNC_DELAY      100     /* milliseconds */
45
 
46
struct saa7191 {
47
        struct i2c_client *client;
48
 
49
        /* the register values are stored here as the actual
50
         * I2C-registers are write-only */
51
        u8 reg[25];
52
 
53
        int input;
54
        int norm;
55
};
56
 
57
static struct i2c_driver i2c_driver_saa7191;
58
 
59
static const u8 initseq[] = {
60
        0,       /* Subaddress */
61
 
62
        0x50,   /* (0x50) SAA7191_REG_IDEL */
63
 
64
        /* 50 Hz signal timing */
65
        0x30,   /* (0x30) SAA7191_REG_HSYB */
66
        0x00,   /* (0x00) SAA7191_REG_HSYS */
67
        0xe8,   /* (0xe8) SAA7191_REG_HCLB */
68
        0xb6,   /* (0xb6) SAA7191_REG_HCLS */
69
        0xf4,   /* (0xf4) SAA7191_REG_HPHI */
70
 
71
        /* control */
72
        SAA7191_LUMA_APER_1,    /* (0x01) SAA7191_REG_LUMA - CVBS mode */
73
        0x00,   /* (0x00) SAA7191_REG_HUEC */
74
        0xf8,   /* (0xf8) SAA7191_REG_CKTQ */
75
        0xf8,   /* (0xf8) SAA7191_REG_CKTS */
76
        0x90,   /* (0x90) SAA7191_REG_PLSE */
77
        0x90,   /* (0x90) SAA7191_REG_SESE */
78
        0x00,   /* (0x00) SAA7191_REG_GAIN */
79
        SAA7191_STDC_NFEN | SAA7191_STDC_HRMV,  /* (0x0c) SAA7191_REG_STDC
80
                                                 * - not SECAM,
81
                                                 * slow time constant */
82
        SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
83
        | SAA7191_IOCK_OEDY,    /* (0x78) SAA7191_REG_IOCK
84
                                 * - chroma from CVBS, GPSW1 & 2 off */
85
        SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
86
        | SAA7191_CTL3_YDEL0,   /* (0x99) SAA7191_REG_CTL3
87
                                 * - automatic field detection */
88
        0x00,   /* (0x00) SAA7191_REG_CTL4 */
89
        0x2c,   /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
90
        0x00,   /* unused */
91
        0x00,   /* unused */
92
 
93
        /* 60 Hz signal timing */
94
        0x34,   /* (0x34) SAA7191_REG_HS6B */
95
        0x0a,   /* (0x0a) SAA7191_REG_HS6S */
96
        0xf4,   /* (0xf4) SAA7191_REG_HC6B */
97
        0xce,   /* (0xce) SAA7191_REG_HC6S */
98
        0xf4,   /* (0xf4) SAA7191_REG_HP6I */
99
};
100
 
101
/* SAA7191 register handling */
102
 
103
static u8 saa7191_read_reg(struct i2c_client *client,
104
                           u8 reg)
105
{
106
        return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
107
}
108
 
109
static int saa7191_read_status(struct i2c_client *client,
110
                               u8 *value)
111
{
112
        int ret;
113
 
114
        ret = i2c_master_recv(client, value, 1);
115
        if (ret < 0) {
116
                printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
117
                return ret;
118
        }
119
 
120
        return 0;
121
}
122
 
123
 
124
static int saa7191_write_reg(struct i2c_client *client, u8 reg,
125
                             u8 value)
126
{
127
        ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
128
        return i2c_smbus_write_byte_data(client, reg, value);
129
}
130
 
131
/* the first byte of data must be the first subaddress number (register) */
132
static int saa7191_write_block(struct i2c_client *client,
133
                               u8 length, const u8 *data)
134
{
135
        int i;
136
        int ret;
137
 
138
        struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
139
        for (i = 0; i < (length - 1); i++) {
140
                decoder->reg[data[0] + i] = data[i + 1];
141
        }
142
 
143
        ret = i2c_master_send(client, data, length);
144
        if (ret < 0) {
145
                printk(KERN_ERR "SAA7191: saa7191_write_block(): "
146
                       "write failed\n");
147
                return ret;
148
        }
149
 
150
        return 0;
151
}
152
 
153
/* Helper functions */
154
 
155
static int saa7191_set_input(struct i2c_client *client, int input)
156
{
157
        struct saa7191 *decoder = i2c_get_clientdata(client);
158
        u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
159
        u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
160
        int err;
161
 
162
        switch (input) {
163
        case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
164
                iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
165
                          | SAA7191_IOCK_GPSW2);
166
                /* Chrominance trap active */
167
                luma &= ~SAA7191_LUMA_BYPS;
168
                break;
169
        case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
170
                iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
171
                /* Chrominance trap bypassed */
172
                luma |= SAA7191_LUMA_BYPS;
173
                break;
174
        default:
175
                return -EINVAL;
176
        }
177
 
178
        err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
179
        if (err)
180
                return -EIO;
181
        err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
182
        if (err)
183
                return -EIO;
184
 
185
        decoder->input = input;
186
 
187
        return 0;
188
}
189
 
190
static int saa7191_set_norm(struct i2c_client *client, int norm)
191
{
192
        struct saa7191 *decoder = i2c_get_clientdata(client);
193
        u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
194
        u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
195
        u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
196
        int err;
197
 
198
        switch(norm) {
199
        case SAA7191_NORM_PAL:
200
                stdc &= ~SAA7191_STDC_SECS;
201
                ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
202
                chcv = SAA7191_CHCV_PAL;
203
                break;
204
        case SAA7191_NORM_NTSC:
205
                stdc &= ~SAA7191_STDC_SECS;
206
                ctl3 &= ~SAA7191_CTL3_AUFD;
207
                ctl3 |= SAA7191_CTL3_FSEL;
208
                chcv = SAA7191_CHCV_NTSC;
209
                break;
210
        case SAA7191_NORM_SECAM:
211
                stdc |= SAA7191_STDC_SECS;
212
                ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
213
                chcv = SAA7191_CHCV_PAL;
214
                break;
215
        default:
216
                return -EINVAL;
217
        }
218
 
219
        err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
220
        if (err)
221
                return -EIO;
222
        err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
223
        if (err)
224
                return -EIO;
225
        err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
226
        if (err)
227
                return -EIO;
228
 
229
        decoder->norm = norm;
230
 
231
        dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
232
                stdc, chcv);
233
        dprintk("norm: %d\n", norm);
234
 
235
        return 0;
236
}
237
 
238
static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
239
{
240
        int i = 0;
241
 
242
        dprintk("Checking for signal...\n");
243
 
244
        for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
245
                if (saa7191_read_status(client, status))
246
                        return -EIO;
247
 
248
                if (((*status) & SAA7191_STATUS_HLCK) == 0) {
249
                        dprintk("Signal found\n");
250
                        return 0;
251
                }
252
 
253
                msleep(SAA7191_SYNC_DELAY);
254
        }
255
 
256
        dprintk("No signal\n");
257
 
258
        return -EBUSY;
259
}
260
 
261
static int saa7191_autodetect_norm_extended(struct i2c_client *client)
262
{
263
        u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
264
        u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
265
        u8 status;
266
        int err = 0;
267
 
268
        dprintk("SAA7191 extended signal auto-detection...\n");
269
 
270
        stdc &= ~SAA7191_STDC_SECS;
271
        ctl3 &= ~(SAA7191_CTL3_FSEL);
272
 
273
        err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
274
        if (err) {
275
                err = -EIO;
276
                goto out;
277
        }
278
        err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
279
        if (err) {
280
                err = -EIO;
281
                goto out;
282
        }
283
 
284
        ctl3 |= SAA7191_CTL3_AUFD;
285
        err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
286
        if (err) {
287
                err = -EIO;
288
                goto out;
289
        }
290
 
291
        msleep(SAA7191_SYNC_DELAY);
292
 
293
        err = saa7191_wait_for_signal(client, &status);
294
        if (err)
295
                goto out;
296
 
297
        if (status & SAA7191_STATUS_FIDT) {
298
                /* 60Hz signal -> NTSC */
299
                dprintk("60Hz signal: NTSC\n");
300
                return saa7191_set_norm(client, SAA7191_NORM_NTSC);
301
        }
302
 
303
        /* 50Hz signal */
304
        dprintk("50Hz signal: Trying PAL...\n");
305
 
306
        /* try PAL first */
307
        err = saa7191_set_norm(client, SAA7191_NORM_PAL);
308
        if (err)
309
                goto out;
310
 
311
        msleep(SAA7191_SYNC_DELAY);
312
 
313
        err = saa7191_wait_for_signal(client, &status);
314
        if (err)
315
                goto out;
316
 
317
        /* not 50Hz ? */
318
        if (status & SAA7191_STATUS_FIDT) {
319
                dprintk("No 50Hz signal\n");
320
                err = -EAGAIN;
321
                goto out;
322
        }
323
 
324
        if (status & SAA7191_STATUS_CODE) {
325
                dprintk("PAL\n");
326
                return 0;
327
        }
328
 
329
        dprintk("No color detected with PAL - Trying SECAM...\n");
330
 
331
        /* no color detected ? -> try SECAM */
332
        err = saa7191_set_norm(client,
333
                               SAA7191_NORM_SECAM);
334
        if (err)
335
                goto out;
336
 
337
        msleep(SAA7191_SYNC_DELAY);
338
 
339
        err = saa7191_wait_for_signal(client, &status);
340
        if (err)
341
                goto out;
342
 
343
        /* not 50Hz ? */
344
        if (status & SAA7191_STATUS_FIDT) {
345
                dprintk("No 50Hz signal\n");
346
                err = -EAGAIN;
347
                goto out;
348
        }
349
 
350
        if (status & SAA7191_STATUS_CODE) {
351
                /* Color detected -> SECAM */
352
                dprintk("SECAM\n");
353
                return 0;
354
        }
355
 
356
        dprintk("No color detected with SECAM - Going back to PAL.\n");
357
 
358
        /* still no color detected ?
359
         * -> set norm back to PAL */
360
        err = saa7191_set_norm(client,
361
                               SAA7191_NORM_PAL);
362
        if (err)
363
                goto out;
364
 
365
out:
366
        ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
367
        if (ctl3 & SAA7191_CTL3_AUFD) {
368
                ctl3 &= ~(SAA7191_CTL3_AUFD);
369
                err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
370
                if (err) {
371
                        err = -EIO;
372
                }
373
        }
374
 
375
        return err;
376
}
377
 
378
static int saa7191_autodetect_norm(struct i2c_client *client)
379
{
380
        u8 status;
381
 
382
        dprintk("SAA7191 signal auto-detection...\n");
383
 
384
        dprintk("Reading status...\n");
385
 
386
        if (saa7191_read_status(client, &status))
387
                return -EIO;
388
 
389
        dprintk("Checking for signal...\n");
390
 
391
        /* no signal ? */
392
        if (status & SAA7191_STATUS_HLCK) {
393
                dprintk("No signal\n");
394
                return -EBUSY;
395
        }
396
 
397
        dprintk("Signal found\n");
398
 
399
        if (status & SAA7191_STATUS_FIDT) {
400
                /* 60hz signal -> NTSC */
401
                dprintk("NTSC\n");
402
                return saa7191_set_norm(client, SAA7191_NORM_NTSC);
403
        } else {
404
                /* 50hz signal -> PAL */
405
                dprintk("PAL\n");
406
                return saa7191_set_norm(client, SAA7191_NORM_PAL);
407
        }
408
}
409
 
410
static int saa7191_get_control(struct i2c_client *client,
411
                               struct saa7191_control *ctrl)
412
{
413
        u8 reg;
414
        int ret = 0;
415
 
416
        switch (ctrl->type) {
417
        case SAA7191_CONTROL_BANDPASS:
418
        case SAA7191_CONTROL_BANDPASS_WEIGHT:
419
        case SAA7191_CONTROL_CORING:
420
                reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
421
                switch (ctrl->type) {
422
                case SAA7191_CONTROL_BANDPASS:
423
                        ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
424
                                >> SAA7191_LUMA_BPSS_SHIFT;
425
                        break;
426
                case SAA7191_CONTROL_BANDPASS_WEIGHT:
427
                        ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
428
                                >> SAA7191_LUMA_APER_SHIFT;
429
                        break;
430
                case SAA7191_CONTROL_CORING:
431
                        ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
432
                                >> SAA7191_LUMA_CORI_SHIFT;
433
                        break;
434
                }
435
                break;
436
        case SAA7191_CONTROL_FORCE_COLOUR:
437
        case SAA7191_CONTROL_CHROMA_GAIN:
438
                reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
439
                if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
440
                        ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
441
                else
442
                        ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
443
                                >> SAA7191_GAIN_LFIS_SHIFT;
444
                break;
445
        case SAA7191_CONTROL_HUE:
446
                reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
447
                if (reg < 0x80)
448
                        reg += 0x80;
449
                else
450
                        reg -= 0x80;
451
                ctrl->value = (s32)reg;
452
                break;
453
        case SAA7191_CONTROL_VTRC:
454
                reg = saa7191_read_reg(client, SAA7191_REG_STDC);
455
                ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
456
                break;
457
        case SAA7191_CONTROL_LUMA_DELAY:
458
                reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
459
                ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
460
                        >> SAA7191_CTL3_YDEL_SHIFT;
461
                if (ctrl->value >= 4)
462
                        ctrl->value -= 8;
463
                break;
464
        case SAA7191_CONTROL_VNR:
465
                reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
466
                ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
467
                        >> SAA7191_CTL4_VNOI_SHIFT;
468
                break;
469
        default:
470
                ret = -EINVAL;
471
        }
472
 
473
        return ret;
474
}
475
 
476
static int saa7191_set_control(struct i2c_client *client,
477
                               struct saa7191_control *ctrl)
478
{
479
        u8 reg;
480
        int ret = 0;
481
 
482
        switch (ctrl->type) {
483
        case SAA7191_CONTROL_BANDPASS:
484
        case SAA7191_CONTROL_BANDPASS_WEIGHT:
485
        case SAA7191_CONTROL_CORING:
486
                reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
487
                switch (ctrl->type) {
488
                case SAA7191_CONTROL_BANDPASS:
489
                        reg &= ~SAA7191_LUMA_BPSS_MASK;
490
                        reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
491
                                & SAA7191_LUMA_BPSS_MASK;
492
                        break;
493
                case SAA7191_CONTROL_BANDPASS_WEIGHT:
494
                        reg &= ~SAA7191_LUMA_APER_MASK;
495
                        reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
496
                                & SAA7191_LUMA_APER_MASK;
497
                        break;
498
                case SAA7191_CONTROL_CORING:
499
                        reg &= ~SAA7191_LUMA_CORI_MASK;
500
                        reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
501
                                & SAA7191_LUMA_CORI_MASK;
502
                        break;
503
                }
504
                ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
505
                break;
506
        case SAA7191_CONTROL_FORCE_COLOUR:
507
        case SAA7191_CONTROL_CHROMA_GAIN:
508
                reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
509
                if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
510
                        if (ctrl->value)
511
                                reg |= SAA7191_GAIN_COLO;
512
                        else
513
                                reg &= ~SAA7191_GAIN_COLO;
514
                } else {
515
                        reg &= ~SAA7191_GAIN_LFIS_MASK;
516
                        reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
517
                                & SAA7191_GAIN_LFIS_MASK;
518
                }
519
                ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
520
                break;
521
        case SAA7191_CONTROL_HUE:
522
                reg = ctrl->value & 0xff;
523
                if (reg < 0x80)
524
                        reg += 0x80;
525
                else
526
                        reg -= 0x80;
527
                ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
528
                break;
529
        case SAA7191_CONTROL_VTRC:
530
                reg = saa7191_read_reg(client, SAA7191_REG_STDC);
531
                if (ctrl->value)
532
                        reg |= SAA7191_STDC_VTRC;
533
                else
534
                        reg &= ~SAA7191_STDC_VTRC;
535
                ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
536
                break;
537
        case SAA7191_CONTROL_LUMA_DELAY: {
538
                s32 value = ctrl->value;
539
                if (value < 0)
540
                        value += 8;
541
                reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
542
                reg &= ~SAA7191_CTL3_YDEL_MASK;
543
                reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
544
                        & SAA7191_CTL3_YDEL_MASK;
545
                ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
546
                break;
547
        }
548
        case SAA7191_CONTROL_VNR:
549
                reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
550
                reg &= ~SAA7191_CTL4_VNOI_MASK;
551
                reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
552
                        & SAA7191_CTL4_VNOI_MASK;
553
                ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
554
                break;
555
        default:
556
                ret = -EINVAL;
557
        }
558
 
559
        return ret;
560
}
561
 
562
/* I2C-interface */
563
 
564
static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
565
{
566
        int err = 0;
567
        struct saa7191 *decoder;
568
        struct i2c_client *client;
569
 
570
        printk(KERN_INFO "Philips SAA7191 driver version %s\n",
571
               SAA7191_MODULE_VERSION);
572
 
573
        client = kzalloc(sizeof(*client), GFP_KERNEL);
574
        if (!client)
575
                return -ENOMEM;
576
        decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
577
        if (!decoder) {
578
                err = -ENOMEM;
579
                goto out_free_client;
580
        }
581
 
582
        client->addr = addr;
583
        client->adapter = adap;
584
        client->driver = &i2c_driver_saa7191;
585
        client->flags = 0;
586
        strcpy(client->name, "saa7191 client");
587
        i2c_set_clientdata(client, decoder);
588
 
589
        decoder->client = client;
590
 
591
        err = i2c_attach_client(client);
592
        if (err)
593
                goto out_free_decoder;
594
 
595
        err = saa7191_write_block(client, sizeof(initseq), initseq);
596
        if (err) {
597
                printk(KERN_ERR "SAA7191 initialization failed\n");
598
                goto out_detach_client;
599
        }
600
 
601
        printk(KERN_INFO "SAA7191 initialized\n");
602
 
603
        decoder->input = SAA7191_INPUT_COMPOSITE;
604
        decoder->norm = SAA7191_NORM_PAL;
605
 
606
        err = saa7191_autodetect_norm(client);
607
        if (err && (err != -EBUSY)) {
608
                printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
609
        }
610
 
611
        return 0;
612
 
613
out_detach_client:
614
        i2c_detach_client(client);
615
out_free_decoder:
616
        kfree(decoder);
617
out_free_client:
618
        kfree(client);
619
        return err;
620
}
621
 
622
static int saa7191_probe(struct i2c_adapter *adap)
623
{
624
        /* Always connected to VINO */
625
        if (adap->id == I2C_HW_SGI_VINO)
626
                return saa7191_attach(adap, SAA7191_ADDR, 0);
627
        /* Feel free to add probe here :-) */
628
        return -ENODEV;
629
}
630
 
631
static int saa7191_detach(struct i2c_client *client)
632
{
633
        struct saa7191 *decoder = i2c_get_clientdata(client);
634
 
635
        i2c_detach_client(client);
636
        kfree(decoder);
637
        kfree(client);
638
        return 0;
639
}
640
 
641
static int saa7191_command(struct i2c_client *client, unsigned int cmd,
642
                           void *arg)
643
{
644
        struct saa7191 *decoder = i2c_get_clientdata(client);
645
 
646
        switch (cmd) {
647
        case DECODER_GET_CAPABILITIES: {
648
                struct video_decoder_capability *cap = arg;
649
 
650
                cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
651
                              VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
652
                cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
653
                cap->outputs = 1;
654
                break;
655
        }
656
        case DECODER_GET_STATUS: {
657
                int *iarg = arg;
658
                u8 status;
659
                int res = 0;
660
 
661
                if (saa7191_read_status(client, &status)) {
662
                        return -EIO;
663
                }
664
                if ((status & SAA7191_STATUS_HLCK) == 0)
665
                        res |= DECODER_STATUS_GOOD;
666
                if (status & SAA7191_STATUS_CODE)
667
                        res |= DECODER_STATUS_COLOR;
668
                switch (decoder->norm) {
669
                case SAA7191_NORM_NTSC:
670
                        res |= DECODER_STATUS_NTSC;
671
                        break;
672
                case SAA7191_NORM_PAL:
673
                        res |= DECODER_STATUS_PAL;
674
                        break;
675
                case SAA7191_NORM_SECAM:
676
                        res |= DECODER_STATUS_SECAM;
677
                        break;
678
                case SAA7191_NORM_AUTO:
679
                default:
680
                        if (status & SAA7191_STATUS_FIDT)
681
                                res |= DECODER_STATUS_NTSC;
682
                        else
683
                                res |= DECODER_STATUS_PAL;
684
                        break;
685
                }
686
                *iarg = res;
687
                break;
688
        }
689
        case DECODER_SET_NORM: {
690
                int *iarg = arg;
691
 
692
                switch (*iarg) {
693
                case VIDEO_MODE_AUTO:
694
                        return saa7191_autodetect_norm(client);
695
                case VIDEO_MODE_PAL:
696
                        return saa7191_set_norm(client, SAA7191_NORM_PAL);
697
                case VIDEO_MODE_NTSC:
698
                        return saa7191_set_norm(client, SAA7191_NORM_NTSC);
699
                case VIDEO_MODE_SECAM:
700
                        return saa7191_set_norm(client, SAA7191_NORM_SECAM);
701
                default:
702
                        return -EINVAL;
703
                }
704
                break;
705
        }
706
        case DECODER_SET_INPUT: {
707
                int *iarg = arg;
708
 
709
                switch (client->adapter->id) {
710
                case I2C_HW_SGI_VINO:
711
                        return saa7191_set_input(client, *iarg);
712
                default:
713
                        if (*iarg != 0)
714
                                return -EINVAL;
715
                }
716
                break;
717
        }
718
        case DECODER_SET_OUTPUT: {
719
                int *iarg = arg;
720
 
721
                /* not much choice of outputs */
722
                if (*iarg != 0)
723
                        return -EINVAL;
724
                break;
725
        }
726
        case DECODER_ENABLE_OUTPUT: {
727
                /* Always enabled */
728
                break;
729
        }
730
        case DECODER_SET_PICTURE: {
731
                struct video_picture *pic = arg;
732
                unsigned val;
733
                int err;
734
 
735
                val = (pic->hue >> 8) - 0x80;
736
 
737
                err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
738
                if (err)
739
                        return -EIO;
740
 
741
                break;
742
        }
743
        case DECODER_SAA7191_GET_STATUS: {
744
                struct saa7191_status *status = arg;
745
                u8 status_reg;
746
 
747
                if (saa7191_read_status(client, &status_reg))
748
                        return -EIO;
749
 
750
                status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
751
                        ? 1 : 0;
752
                status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
753
                        ? 1 : 0;
754
                status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
755
 
756
                status->input = decoder->input;
757
                status->norm = decoder->norm;
758
 
759
                break;
760
        }
761
        case DECODER_SAA7191_SET_NORM: {
762
                int *norm = arg;
763
 
764
                switch (*norm) {
765
                case SAA7191_NORM_AUTO:
766
                        return saa7191_autodetect_norm(client);
767
                case SAA7191_NORM_AUTO_EXT:
768
                        return saa7191_autodetect_norm_extended(client);
769
                default:
770
                        return saa7191_set_norm(client, *norm);
771
                }
772
        }
773
        case DECODER_SAA7191_GET_CONTROL: {
774
                return saa7191_get_control(client, arg);
775
        }
776
        case DECODER_SAA7191_SET_CONTROL: {
777
                return saa7191_set_control(client, arg);
778
        }
779
        default:
780
                return -EINVAL;
781
        }
782
 
783
        return 0;
784
}
785
 
786
static struct i2c_driver i2c_driver_saa7191 = {
787
        .driver = {
788
                .name   = "saa7191",
789
        },
790
        .id             = I2C_DRIVERID_SAA7191,
791
        .attach_adapter = saa7191_probe,
792
        .detach_client  = saa7191_detach,
793
        .command        = saa7191_command
794
};
795
 
796
static int saa7191_init(void)
797
{
798
        return i2c_add_driver(&i2c_driver_saa7191);
799
}
800
 
801
static void saa7191_exit(void)
802
{
803
        i2c_del_driver(&i2c_driver_saa7191);
804
}
805
 
806
module_init(saa7191_init);
807
module_exit(saa7191_exit);

powered by: WebSVN 2.1.0

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