Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
425 giacomo 1
/*
2
    dpc7146.c - v4l2 driver for the dpc7146 demonstration board
3
 
4
    Copyright (C) 2000-2003 Michael Hunold <michael@mihu.de>
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 as published by
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
*/
20
 
21
#define DEBUG_VARIABLE debug
22
 
23
#include <media/saa7146_vv.h>
24
#include <linux/video_decoder.h>        /* for saa7111a */
25
 
26
#define I2C_SAA7111A            0x24
27
 
28
/* All unused bytes are reserverd. */
29
#define SAA711X_CHIP_VERSION            0x00
30
#define SAA711X_ANALOG_INPUT_CONTROL_1  0x02
31
#define SAA711X_ANALOG_INPUT_CONTROL_2  0x03
32
#define SAA711X_ANALOG_INPUT_CONTROL_3  0x04
33
#define SAA711X_ANALOG_INPUT_CONTROL_4  0x05
34
#define SAA711X_HORIZONTAL_SYNC_START   0x06
35
#define SAA711X_HORIZONTAL_SYNC_STOP    0x07
36
#define SAA711X_SYNC_CONTROL            0x08
37
#define SAA711X_LUMINANCE_CONTROL       0x09
38
#define SAA711X_LUMINANCE_BRIGHTNESS    0x0A
39
#define SAA711X_LUMINANCE_CONTRAST      0x0B
40
#define SAA711X_CHROMA_SATURATION       0x0C
41
#define SAA711X_CHROMA_HUE_CONTROL      0x0D
42
#define SAA711X_CHROMA_CONTROL          0x0E
43
#define SAA711X_FORMAT_DELAY_CONTROL    0x10
44
#define SAA711X_OUTPUT_CONTROL_1        0x11
45
#define SAA711X_OUTPUT_CONTROL_2        0x12
46
#define SAA711X_OUTPUT_CONTROL_3        0x13
47
#define SAA711X_V_GATE_1_START          0x15
48
#define SAA711X_V_GATE_1_STOP           0x16
49
#define SAA711X_V_GATE_1_MSB            0x17
50
#define SAA711X_TEXT_SLICER_STATUS      0x1A
51
#define SAA711X_DECODED_BYTES_OF_TS_1   0x1B
52
#define SAA711X_DECODED_BYTES_OF_TS_2   0x1C
53
#define SAA711X_STATUS_BYTE             0x1F
54
 
55
#define DPC_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0) 
56
 
57
static int debug = 0;
58
MODULE_PARM(debug,"i");
59
MODULE_PARM_DESC(debug, "debug verbosity");
60
 
61
/* global variables */
62
int dpc_num = 0;
63
 
64
#define DPC_INPUTS      2
65
static struct v4l2_input dpc_inputs[DPC_INPUTS] = {
66
        { 0, "Port A",  V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
67
        { 1, "Port B",  V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
68
};
69
 
70
#define DPC_AUDIOS      0
71
 
72
static struct saa7146_extension_ioctls ioctls[] = {
73
        { VIDIOC_G_INPUT,       SAA7146_EXCLUSIVE },
74
        { VIDIOC_S_INPUT,       SAA7146_EXCLUSIVE },
75
        { VIDIOC_ENUMINPUT,     SAA7146_EXCLUSIVE },
76
        { VIDIOC_S_STD,         SAA7146_AFTER },
77
        { 0,                    0 }
78
};
79
 
80
struct dpc
81
{
82
        struct video_device     video_dev;
83
        struct video_device     vbi_dev;
84
 
85
        struct i2c_adapter      i2c_adapter;   
86
        struct i2c_client       *saa7111a;
87
 
88
        int cur_input;  /* current input */
89
};
90
 
91
/* fixme: add vbi stuff here */
92
static int dpc_probe(struct saa7146_dev* dev)
93
{
94
        struct dpc* dpc = 0;   
95
        int i = 0;
96
 
97
        dpc = (struct dpc*)kmalloc(sizeof(struct dpc), GFP_KERNEL);
98
        if( NULL == dpc ) {
99
                printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n");
100
                return -ENOMEM;
101
        }
102
        memset(dpc, 0x0, sizeof(struct dpc));  
103
 
104
        saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
105
        if(i2c_add_adapter(&dpc->i2c_adapter) < 0) {
106
                DEB_S(("cannot register i2c-device. skipping.\n"));
107
                kfree(dpc);
108
                return -EFAULT;
109
        }
110
 
111
        /* loop through all i2c-devices on the bus and look who is there */
112
        for(i = 0; i < I2C_CLIENT_MAX; i++) {
113
                if( NULL == dpc->i2c_adapter.clients[i] ) {
114
                        continue;
115
                }
116
                if( I2C_SAA7111A == dpc->i2c_adapter.clients[i]->addr )
117
                        dpc->saa7111a = dpc->i2c_adapter.clients[i];
118
        }
119
 
120
        /* check if all devices are present */
121
        if( 0 == dpc->saa7111a ) {
122
                DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n"));   
123
                kfree(dpc);
124
                return -ENODEV;
125
        }
126
 
127
        /* all devices are present, probe was successful */    
128
        DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); 
129
 
130
        /* we store the pointer in our private data field */
131
        (struct dpc*)dev->ext_priv = dpc;
132
 
133
        return 0;
134
}
135
 
136
/* bring hardware to a sane state. this has to be done, just in case someone
137
   wants to capture from this device before it has been properly initialized.
138
   the capture engine would badly fail, because no valid signal arrives on the
139
   saa7146, thus leading to timeouts and stuff. */
140
static int dpc_init_done(struct saa7146_dev* dev)
141
{
142
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
143
 
144
        DEB_D(("dpc_v4l2.o: dpc_init_done called.\n"));
145
 
146
        /* initialize the helper ics to useful values */
147
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11);
148
 
149
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0);
150
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30);
151
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00);
152
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00);
153
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde);
154
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad);
155
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8);
156
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00);
157
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80);
158
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47);
159
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40);
160
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00);
161
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03);
162
 
163
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0);
164
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c);
165
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1);
166
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30);
167
 
168
        i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81);
169
 
170
        return 0;
171
}
172
 
173
static struct saa7146_ext_vv vv_data;
174
 
175
/* this function only gets called when the probing was successful */
176
static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
177
{
178
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
179
 
180
        DEB_D(("dpc_v4l2.o: dpc_attach called.\n"));
181
 
182
        /* checking for i2c-devices can be omitted here, because we
183
           already did this in "dpc_vl42_probe" */
184
 
185
        saa7146_vv_init(dev,&vv_data);
186
        if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) {
187
                ERR(("cannot register capture v4l2 device. skipping.\n"));
188
                return -1;
189
        }
190
 
191
        /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
192
        if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
193
                if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) {
194
                        ERR(("cannot register vbi v4l2 device. skipping.\n"));
195
                }
196
        }
197
 
198
        i2c_use_client(dpc->saa7111a);
199
 
200
        printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num);
201
        dpc_num++;
202
 
203
        /* the rest */
204
        dpc->cur_input = 0;
205
        dpc_init_done(dev);
206
 
207
        return 0;
208
}
209
 
210
static int dpc_detach(struct saa7146_dev* dev)
211
{
212
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
213
 
214
        DEB_EE(("dev:%p\n",dev));
215
 
216
        i2c_release_client(dpc->saa7111a);
217
 
218
        saa7146_unregister_device(&dpc->video_dev,dev);
219
        if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
220
                saa7146_unregister_device(&dpc->vbi_dev,dev);
221
        }
222
        saa7146_vv_release(dev);
223
 
224
        dpc_num--;
225
 
226
        i2c_del_adapter(&dpc->i2c_adapter);
227
        kfree(dpc);
228
        return 0;
229
}
230
 
231
#ifdef axa
232
int dpc_vbi_bypass(struct saa7146_dev* dev)
233
{
234
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
235
 
236
        int i = 1;
237
 
238
        /* switch bypass in saa7111a */
239
        if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) {
240
                printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n");
241
                return -1;
242
        }                      
243
 
244
        return 0;
245
}
246
#endif
247
 
248
static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
249
{
250
        struct saa7146_dev *dev = fh->dev;
251
        struct dpc* dpc = (struct dpc*)dev->ext_priv;
252
/*
253
        struct saa7146_vv *vv = dev->vv_data;
254
*/
255
        switch(cmd)
256
        {
257
        case VIDIOC_ENUMINPUT:
258
        {
259
                struct v4l2_input *i = arg;
260
                DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
261
 
262
                if( i->index < 0 || i->index >= DPC_INPUTS) {
263
                        return -EINVAL;
264
                }
265
 
266
                memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input));
267
 
268
                DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index));
269
                return 0;
270
        }
271
        case VIDIOC_G_INPUT:
272
        {
273
                int *input = (int *)arg;
274
                *input = dpc->cur_input;
275
 
276
                DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input));
277
                return 0;
278
        }
279
        case VIDIOC_S_INPUT:
280
        {
281
                int     input = *(int *)arg;
282
 
283
                if (input < 0 || input >= DPC_INPUTS) {
284
                        return -EINVAL;
285
                }
286
 
287
                dpc->cur_input = input;
288
 
289
                /* fixme: switch input here, switch audio, too! */
290
//              saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
291
                printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n");
292
 
293
                return 0;
294
        }
295
        default:
296
/*
297
                DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n"));
298
*/
299
                return -ENOIOCTLCMD;
300
        }
301
        return 0;
302
}
303
 
304
static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
305
{
306
        return 0;
307
}
308
 
309
static struct saa7146_standard standard[] = {
310
        {
311
                .name   = "PAL",        .id     = V4L2_STD_PAL,
312
                .v_offset       = 0x17, .v_field        = 288,  .v_calc         = 576,
313
                .h_offset       = 0x14, .h_pixels       = 680,  .h_calc         = 680+1,
314
                .v_max_out      = 576,  .h_max_out      = 768,
315
        }, {
316
                .name   = "NTSC",       .id     = V4L2_STD_NTSC,
317
                .v_offset       = 0x16, .v_field        = 240,  .v_calc         = 480,
318
                .h_offset       = 0x06, .h_pixels       = 708,  .h_calc         = 708+1,
319
                .v_max_out      = 480,  .h_max_out      = 640,
320
        }, {
321
                .name   = "SECAM",      .id     = V4L2_STD_SECAM,
322
                .v_offset       = 0x14, .v_field        = 288,  .v_calc         = 576,
323
                .h_offset       = 0x14, .h_pixels       = 720,  .h_calc         = 720+1,
324
                .v_max_out      = 576,  .h_max_out      = 768,
325
        }
326
};             
327
 
328
static struct saa7146_extension extension;
329
 
330
static struct saa7146_pci_extension_data dpc = {
331
        .ext_priv = "Multimedia eXtension Board",
332
        .ext = &extension,
333
};
334
 
335
static struct pci_device_id pci_tbl[] = {
336
        {
337
                .vendor    = PCI_VENDOR_ID_PHILIPS,
338
                .device    = PCI_DEVICE_ID_PHILIPS_SAA7146,
339
                .subvendor = 0x0000,
340
                .subdevice = 0x0000,
341
                .driver_data = (unsigned long)&dpc,
342
        }, {
343
                .vendor = 0,
344
        }
345
};
346
 
347
MODULE_DEVICE_TABLE(pci, pci_tbl);
348
 
349
static struct saa7146_ext_vv vv_data = {
350
        .inputs         = DPC_INPUTS,
351
        .capabilities   = V4L2_CAP_VBI_CAPTURE,
352
        .stds           = &standard[0],
353
        .num_stds       = sizeof(standard)/sizeof(struct saa7146_standard),
354
        .std_callback   = &std_callback,
355
        .ioctls         = &ioctls[0],
356
        .ioctl          = dpc_ioctl,
357
};
358
 
359
static struct saa7146_extension extension = {
360
        .name           = "dpc7146 demonstration board",
361
        .flags          = SAA7146_USE_I2C_IRQ,
362
 
363
        .pci_tbl        = &pci_tbl[0],
364
        .module         = THIS_MODULE,
365
 
366
        .probe          = dpc_probe,
367
        .attach         = dpc_attach,
368
        .detach         = dpc_detach,
369
 
370
        .irq_mask       = 0,
371
        .irq_func       = NULL,
372
};     
373
 
374
int __init dpc_init_module(void)
375
{
376
        if( 0 != saa7146_register_extension(&extension)) {
377
                DEB_S(("failed to register extension.\n"));
378
                return -ENODEV;
379
        }
380
 
381
        return 0;
382
}
383
 
384
void __exit dpc_cleanup_module(void)
385
{
386
        saa7146_unregister_extension(&extension);
387
}
388
 
389
module_init(dpc_init_module);
390
module_exit(dpc_cleanup_module);
391
 
392
MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'");
393
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
394
MODULE_LICENSE("GPL");