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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [media/] [video/] [saa7191.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  saa7191 - Philips SAA7191 video decoder driver
3
 *
4
 *  Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License version 2 as
8
 *  published by the Free Software Foundation.
9
 */
10
 
11
#include <linux/module.h>
12
#include <linux/init.h>
13
#include <linux/delay.h>
14
#include <linux/errno.h>
15
#include <linux/fs.h>
16
#include <linux/kernel.h>
17
#include <linux/major.h>
18
#include <linux/slab.h>
19
#include <linux/mm.h>
20
#include <linux/sched.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 VINO_ADAPTER    (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
29
 
30
struct saa7191 {
31
        struct i2c_client *client;
32
        unsigned char reg[25];
33
        unsigned char norm;
34
        unsigned char input;
35
        unsigned char bright;
36
        unsigned char contrast;
37
        unsigned char hue;
38
        unsigned char sat;
39
};
40
 
41
static struct i2c_driver i2c_driver_saa7191;
42
 
43
static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
44
{
45
        static const unsigned char initseq[] = {
46
                0,
47
                0x50,   /* SAA7191_REG_IDEL */
48
                0x30,   /* SAA7191_REG_HSYB */
49
                0x00,   /* SAA7191_REG_HSYS */
50
                0xe8,   /* SAA7191_REG_HCLB */
51
                0xb6,   /* SAA7191_REG_HCLS */
52
                0xf4,   /* SAA7191_REG_HPHI */
53
                0x01,   /* SAA7191_REG_LUMA */
54
                0x00,   /* SAA7191_REG_HUEC */
55
                0xf8,   /* SAA7191_REG_CKTQ */
56
                0xf8,   /* SAA7191_REG_CKTS */
57
                0x90,   /* SAA7191_REG_PLSE */
58
                0x90,   /* SAA7191_REG_SESE */
59
                0x00,   /* SAA7191_REG_GAIN */
60
                0x8c,   /* SAA7191_REG_STDC */
61
                0x78,   /* SAA7191_REG_IOCK */
62
                0x99,   /* SAA7191_REG_CTL3 */
63
                0x00,   /* SAA7191_REG_CTL4 */
64
                0x2c,   /* SAA7191_REG_CHCV */
65
                0x00,   /* unused */
66
                0x00,   /* unused */
67
                0x34,   /* SAA7191_REG_HS6B */
68
                0x0a,   /* SAA7191_REG_HS6S */
69
                0xf4,   /* SAA7191_REG_HC6B */
70
                0xce,   /* SAA7191_REG_HC6S */
71
                0xf4,   /* SAA7191_REG_HP6I */
72
        };
73
        int err = 0;
74
        struct saa7191 *decoder;
75
        struct i2c_client *client;
76
 
77
        client = kmalloc(sizeof(*client), GFP_KERNEL);
78
        if (!client)
79
                return -ENOMEM;
80
        decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
81
        if (!decoder) {
82
                err = -ENOMEM;
83
                goto out_free_client;
84
        }
85
        client->data = decoder;
86
        client->adapter = adap;
87
        client->addr = addr;
88
        client->driver = &i2c_driver_saa7191;
89
        strcpy(client->name, "saa7191 client");
90
        decoder->client = client;
91
 
92
        err = i2c_attach_client(client);
93
        if (err)
94
                goto out_free_decoder;
95
 
96
        decoder->norm = VIDEO_DECODER_PAL | VIDEO_MODE_NTSC |
97
                        VIDEO_DECODER_AUTO;
98
        decoder->input = 0;
99
        /* Registers are 8bit wide and we are storing shifted values */
100
        decoder->bright = 128;
101
        decoder->contrast = 128;
102
        decoder->hue = 128;
103
        decoder->sat = 128;
104
 
105
        memcpy(decoder->reg, initseq, sizeof(initseq));
106
        err = i2c_master_send(client, initseq, sizeof(initseq));
107
        if (err)
108
                printk(KERN_INFO "saa7191 initialization failed (%d)\n", err);
109
 
110
        MOD_INC_USE_COUNT;
111
        return 0;
112
 
113
out_free_decoder:
114
        kfree(decoder);
115
out_free_client:
116
        kfree(client);
117
        return err;
118
}
119
 
120
static int saa7191_probe(struct i2c_adapter *adap)
121
{
122
        /* Always connected to VINO */
123
        if (adap->id == VINO_ADAPTER)
124
                return saa7191_attach(adap, SAA7191_ADDR, 0);
125
        /* Feel free to add probe here :-) */
126
        return -ENODEV;
127
}
128
 
129
static int saa7191_detach(struct i2c_client *client)
130
{
131
        struct saa7191 *decoder = client->data;
132
 
133
        i2c_detach_client(client);
134
        kfree(decoder);
135
        kfree(client);
136
        MOD_DEC_USE_COUNT;
137
        return 0;
138
}
139
 
140
static unsigned char saa7191_read(struct i2c_client *client,
141
                                  unsigned char command)
142
{
143
        return ((struct saa7191 *)client->data)->reg[command];
144
}
145
 
146
static int saa7191_write(struct i2c_client *client, unsigned char command,
147
                         unsigned char value)
148
{
149
        ((struct saa7191 *)client->data)->reg[command] = value;
150
        return i2c_smbus_write_byte_data(client, command, value);
151
}
152
 
153
static int vino_set_input(struct i2c_client *client, int val)
154
{
155
        unsigned char luma = saa7191_read(client, SAA7191_REG_LUMA);
156
        unsigned char iock = saa7191_read(client, SAA7191_REG_IOCK);
157
 
158
        switch (val) {
159
        case 0: /* Set Composite input */
160
                iock &= ~0x03;
161
                /* Chrominance trap active */
162
                luma |= ~SAA7191_LUMA_BYPS;
163
                break;
164
        case 1: /* Set S-Video input */
165
                iock |= 2;
166
                /* Chrominance trap bypassed */
167
                luma |= SAA7191_LUMA_BYPS;
168
                break;
169
        default:
170
                return -EINVAL;
171
        }
172
        saa7191_write(client, SAA7191_REG_LUMA, luma);
173
        saa7191_write(client, SAA7191_REG_IOCK, iock);
174
 
175
        return 0;
176
}
177
 
178
static int saa7191_command(struct i2c_client *client, unsigned int cmd,
179
                           void *arg)
180
{
181
        struct saa7191 *decoder = client->data;
182
 
183
        switch (cmd) {
184
 
185
        case DECODER_GET_CAPABILITIES: {
186
                struct video_decoder_capability *cap = arg;
187
 
188
                cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
189
                              VIDEO_DECODER_AUTO;
190
                cap->inputs = (client->adapter->id == VINO_ADAPTER) ? 2 : 1;
191
                cap->outputs = 1;
192
                break;
193
        }
194
        case DECODER_GET_STATUS: {
195
                int *iarg = arg;
196
                int status;
197
                int res = 0;
198
 
199
                status = i2c_smbus_read_byte_data(client, SAA7191_REG_STATUS);
200
                if ((status & SAA7191_STATUS_HLCK) == 0)
201
                        res |= DECODER_STATUS_GOOD;
202
                switch (decoder->norm) {
203
                case VIDEO_MODE_NTSC:
204
                        res |= DECODER_STATUS_NTSC;
205
                        break;
206
                case VIDEO_MODE_PAL:
207
                        res |= DECODER_STATUS_PAL;
208
                        break;
209
                case VIDEO_MODE_AUTO:
210
                default:
211
                        if (status & SAA7191_STATUS_FIDT)
212
                                res |= DECODER_STATUS_NTSC;
213
                        else
214
                                res |= DECODER_STATUS_PAL;
215
                        if (status & SAA7191_STATUS_CODE)
216
                                res |= DECODER_STATUS_COLOR;
217
                        break;
218
                }
219
                *iarg = res;
220
                break;
221
        }
222
        case DECODER_SET_NORM: {
223
                int *iarg = arg;
224
 
225
                switch (*iarg) {
226
                case VIDEO_MODE_NTSC:
227
                        break;
228
                case VIDEO_MODE_PAL:
229
                        break;
230
                default:
231
                        return -EINVAL;
232
                }
233
                decoder->norm = *iarg;
234
                break;
235
        }
236
        case DECODER_SET_INPUT: {
237
                int *iarg = arg;
238
 
239
                switch (client->adapter->id) {
240
                case VINO_ADAPTER:
241
                        return vino_set_input(client, *iarg);
242
                default:
243
                        if (*iarg != 0)
244
                                return -EINVAL;
245
                }
246
                break;
247
        }
248
        case DECODER_SET_OUTPUT: {
249
                int *iarg = arg;
250
 
251
                /* not much choice of outputs */
252
                if (*iarg != 0)
253
                        return -EINVAL;
254
                break;
255
        }
256
        case DECODER_ENABLE_OUTPUT: {
257
                /* Always enabled */
258
                break;
259
        }
260
        case DECODER_SET_PICTURE: {
261
                struct video_picture *pic = arg;
262
                unsigned val;
263
#if 0
264
                /* TODO */
265
                val = pic->brightness >> 8;
266
                if (decoder->bright != val) {
267
                        decoder->bright = val;
268
                        i2c_smbus_write_byte_data(client, XXX, val);
269
                }
270
                val = pic->contrast >> 8;
271
                if (decoder->contrast != val) {
272
                        decoder->contrast = val;
273
                        i2c_smbus_write_byte_data(client, XXX, val);
274
                }
275
                val = pic->colour >> 8;
276
                if (decoder->sat != val) {
277
                        decoder->sat = val;
278
                        i2c_smbus_write_byte_data(client, XXX, val);
279
                }
280
#endif
281
                val = (pic->hue >> 8) - 0x80;
282
                if (decoder->hue != val) {
283
                        decoder->hue = val;
284
                        i2c_smbus_write_byte_data(client, SAA7191_REG_HUEC,
285
                                                  val);
286
                }
287
                break;
288
        }
289
        default:
290
                return -EINVAL;
291
        }
292
 
293
        return 0;
294
}
295
 
296
static struct i2c_driver i2c_driver_saa7191 = {
297
        .name           = "saa7191",
298
        .id             = I2C_DRIVERID_SAA7191,
299
        .flags          = I2C_DF_NOTIFY,
300
        .attach_adapter = saa7191_probe,
301
        .detach_client  = saa7191_detach,
302
        .command        = saa7191_command
303
};
304
 
305
static int saa7191_init(void)
306
{
307
        return i2c_add_driver(&i2c_driver_saa7191);
308
}
309
 
310
static void saa7191_exit(void)
311
{
312
        i2c_del_driver(&i2c_driver_saa7191);
313
}
314
 
315
module_init(saa7191_init);
316
module_exit(saa7191_exit);
317
 
318
MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
319
MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
320
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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