Return to cvdv.c CVS log | Up to [DVB] / margi2 |
1.1 cvs 1: /*
2: cvdv.c
3:
1.13 mocm 4: Copyright (C) Christian Wolff
5: Marcus Metzler for convergence integrated media.
1.1 cvs 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 as published by
9: the Free Software Foundation; either version 2 of the License, or
10: (at your option) any later version.
11:
12: This program is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with this program; if not, write to the Free Software
19: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20: */
21:
22: /////////////////////////////////////////////////////////////////////
23: // //
24: // Driver for the Convergence Digital Video decoder card (pci) //
25: // with L64017, L64021, PCM1723, and Bt864/Bt865 chipset //
26: // (c) Christian Wolff 19990209 for convergence integrated media //
27: // //
28: /////////////////////////////////////////////////////////////////////
29:
30: // Convergence CV2300i
31: #define __NO_VERSION__
32:
1.24 ! mocm 33: //#include <linux/module.h>
1.1 cvs 34: #include "cvdv.h"
1.23 mocm 35: #include "ost/osd.h"
1.1 cvs 36: #include "i2c.h"
37:
38: //////////////////////
39: // global variables //
40: //////////////////////
41:
42: // Our major device number
43: unsigned int major_device_number;
44:
45:
46: // my little random function for memory test
1.12 mocm 47: uint16_t rnd_seed;
48: uint16_t rnd(uint16_t range)
1.1 cvs 49: { // returns random 0..(range-1) range<=872
1.12 mocm 50: uint32_t b = 75 * (rnd_seed + 1) - 1;
51: rnd_seed = (uint16_t) (b & 0xFFFF);
1.1 cvs 52: return ((b * range) / 0xFFFF) - ((b / 0xFFFF) * range);
53: }
54: void rnd_omize(void)
55: {
1.12 mocm 56: rnd_seed = (uint16_t) jiffies;
1.1 cvs 57: }
58:
1.5 mocm 59: static char *cimlogo[] = {
60: ".............................................",
61: ".............................................",
62: "......................###....................",
63: ".....................#####...................",
64: ".....................######..................",
65: "..............#......#####...................",
66: "...........#####....######...................",
67: ".........########...######...................",
68: "........########....######...................",
69: ".......#########...######....................",
70: "......########.....######...####.............",
71: ".....#######.......#####...#####.............",
72: ".....######.......######...######............",
73: "....#######.......######....######...........",
74: "....######........######....######...........",
75: "....#####........######......#####...........",
76: "...######........######......#####...........",
77: "...#####.........######......######..........",
78: "...#####.........#####.......######..........",
79: "...#####........######........#####..........",
80: "...#####........######.......######..........",
81: "...#####........#####.........#####..........",
82: "...#####.......######........######..........",
83: "...#####.......######........#####...........",
84: "...######.......####.........#####...........",
85: "....#####........##.........######...........",
86: "....######..................######...........",
87: "....######.................######............",
88: ".....#######..............######.....#####...",
89: ".....########............#######....#######..",
90: "......#########........########.....#######..",
91: ".......#######################......########.",
92: "........#####################.......#######..",
93: "..........#################.........#######..",
94: "............#############............#####...",
95: "...............#.#####.................##....",
96: ".............................................",
97: "............................................."
98: };
1.1 cvs 99:
100: /////////////////////////////////////////////
101: // //
102: // Controlling the L64021 MPEG-2 Decoder //
103: // //
104: /////////////////////////////////////////////
105:
106: int OSDTest(struct cvdv_cards *card)
107: {
1.5 mocm 108: int i, j, col, x0, y0, x1, y1,aspx;
1.12 mocm 109: uint8_t b;
1.5 mocm 110:
1.1 cvs 111:
112: if (!card->OSD.open)
113: return -2;
114:
115: OSDQuery(card, &x0, &y0, &x1, &y1, &aspx);
116: OSDShow(card);
1.5 mocm 117: OSDSetColor(card, 0, 0, 0, 0, 0, 0, 0);
118: OSDSetColor(card, 1, 128, 255, 255, 0, 0, 0);
119: for ( i = 0; i < cimlogo_width; i++){
120: for ( j = 0; j < cimlogo_height; j++){
121: b = cimlogo[j][i];
122: col = (b == '#') ? 1: 0;
123: OSDSetPixel(card, x0+i, y0+j, col);
1.1 cvs 124: }
125: }
126:
127: return 0;
128: }
129:
130:
131: void SetVideoSystem(struct cvdv_cards *card)
132: {
1.21 mocm 133: uint8_t reg;
134:
1.1 cvs 135: // set the hsync and vsync generators in the L64017 according to the video standard
1.21 mocm 136: reg = read_indexed_register(card, IIO_VIDEO_CONTROL1);
137: reg &= ~0x03;
1.1 cvs 138: switch (card->videomode) {
139: case PAL: // 864*625*50Hz = 27MHz, 25fps
140: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x41 | 0x0a);
141: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
142: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
143: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
144: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
145: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
146: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
1.21 mocm 147: reg |= VMS_PAL;
1.1 cvs 148: break;
149: case PALN:
150: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0xa1 | 0x0a);
151: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
152: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
153: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
154: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
155: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
156: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
1.21 mocm 157: reg |= VMS_PAL;
1.1 cvs 158: break;
159:
160: case PALNc:
161: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x81 | 0x0a);
162: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
163: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
164: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x8c);
165: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x28);
166: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xed);
167: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
1.21 mocm 168: reg |= VMS_PAL;
1.1 cvs 169: break;
170:
171: case NTSC: // 858*525*59.94006Hz = 27MHz, 29.97fps
172: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a);
173: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
174: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c);
175: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);
176: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);
177: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);
178: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
1.21 mocm 179: reg |= VMS_NTSC;
1.1 cvs 180: break;
181:
182: case PALM:
183: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a);
184: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
185: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
186: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e);
187: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);
188: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);
189: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
1.21 mocm 190: reg |= VMS_PAL;
1.1 cvs 191: break;
192:
193: case NTSC60: // 857*525*60.010002Hz = 27MHz, 30fps
194: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x21 | 0x0a);
195: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
196: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c);
197: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);
198: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);
199: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);
200: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
1.21 mocm 201: reg |= VMS_NTSC;
1.1 cvs 202: break;
203:
204: case PALM60:
205: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x61 | 0x0a);
206: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
207: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
208: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e);
209: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);
210: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);
211: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
1.21 mocm 212: reg |= VMS_PAL;
1.1 cvs 213: break;
214:
215: case PAL60:
216: break;
217: }
1.21 mocm 218: write_indexed_register(card, IIO_VIDEO_CONTROL1, reg);
1.1 cvs 219: // set the pixel generators according to the video standard
220: L64021Setup(card);
221: }
222:
1.12 mocm 223: int SetVideoAttr(struct cvdv_cards *card, uint16_t vattr)
1.1 cvs 224: {
1.12 mocm 225: uint8_t video_compression_mode;
226: uint8_t tv_system;
227: uint8_t aspect_ratio;
228: uint8_t display_mode;
229: uint8_t line_21_switch_1;
230: uint8_t line_21_switch_2;
231: uint8_t source_picture_resolution;
232: uint8_t source_picture_letterboxed;
233: uint8_t reserved;
234: uint8_t film_camera_mode;
235: uint16_t hsize, vsize;
1.1 cvs 236: if (vattr != card->lastvattr) {
237: video_compression_mode = (vattr >> 14) & 0x03;
238: tv_system = (vattr >> 12) & 0x03;
239: aspect_ratio = (vattr >> 10) & 0x03;
240: display_mode = (vattr >> 8) & 0x03;
241: line_21_switch_1 = (vattr >> 7) & 0x01;
242: line_21_switch_2 = (vattr >> 6) & 0x01;
243: source_picture_resolution = (vattr >> 3) & 0x07;
244: source_picture_letterboxed = (vattr >> 2) & 0x01;
245: reserved = (vattr >> 1) & 0x01;
246: film_camera_mode = (vattr >> 0) & 0x01;
247: card->videomode =
248: ((tv_system == 0) ? NTSC : ((tv_system == 1) ?
249: PAL : PAL));
250: SetVideoSystem(card);
251: hsize =
252: ((source_picture_resolution == 0) ? 720
253: : ((source_picture_resolution == 1) ? 702 : 352));
254: vsize = ((source_picture_resolution == 3)
255: ? ((tv_system == 0) ? 240 : 288)
256: : ((tv_system == 0) ? 480 : 576));
257: if (DecoderOpen
258: (card, hsize, vsize, ((aspect_ratio) ? 3 : 2),
259: ((video_compression_mode) ? 0 : 1),
260: source_picture_letterboxed, tv_system)) {
1.14 mocm 261: MDEBUG(0,
1.1 cvs 262: ": Video Decoder Open failed: On-card memory insufficient for frame stores\n");
263: }
264: card->lastvattr = vattr;
265: } else {
1.14 mocm 266: MDEBUG(0,
1.1 cvs 267: ": Video attribute not set, equal to previous one.\n");
268: }
269: return 0;
270: }
271:
1.12 mocm 272: int SetAudioAttr(struct cvdv_cards *card, uint16_t aattr)
1.1 cvs 273: {
1.12 mocm 274: uint8_t audio_coding_mode;
275: uint8_t multichannel_extension;
276: uint8_t audio_type;
277: uint8_t audio_application_mode;
278: uint8_t quantization_drc;
279: uint8_t fs;
280: uint8_t reserved;
281: uint8_t num_audio_ch;
1.1 cvs 282: if (aattr) {
283: if (aattr != card->lastaattr) {
284: audio_coding_mode = (aattr >> 13) & 0x07;
285: multichannel_extension = (aattr >> 12) & 0x01;
286: audio_type = (aattr >> 10) & 0x03;
287: audio_application_mode = (aattr >> 8) & 0x03;
288: quantization_drc = (aattr >> 6) & 0x03;
289: fs = (aattr >> 4) & 0x03;
290: reserved = (aattr >> 3) & 0x01;
291: num_audio_ch = (aattr >> 0) & 0x07;
292: switch (audio_coding_mode) {
293: case 0: // AC-3
294: card->setup.audioselect = audio_AC3;
295: break;
296: case 2: // MPEG Audio
297: card->setup.audioselect = audio_MPEG;
298: break;
299: case 3: // MPEG Audio with ext.
300: card->setup.audioselect = audio_MPEG_EXT;
301: break;
302: case 4: // Linear Pulse Code Modulation LPCM
303: card->setup.audioselect = audio_LPCM;
304: break;
305: case 6: // DTS
306: card->setup.audioselect = audio_DTS;
307: break;
308: case 7: // SDDS
309: card->setup.audioselect = audio_SDDS;
310: break;
311: }
312: DecoderPrepareAudio(card);
313: AudioInit(card, ((fs) ? 96 : 48),
314: ((audio_application_mode == 2) ? 1 : 0));
315: } else {
1.14 mocm 316: MDEBUG(0,
1.1 cvs 317: ": Audio attribute not set, equal to previous one.\n");
318: }
319: } else {
320: card->setup.audioselect = audio_none;
321: DecoderPrepareAudio(card);
322: }
323: card->lastaattr = aattr;
324: return 0;
325: }
326:
327: int Prepare(struct cvdv_cards *card)
328: {
329: int err, h;
330: struct StreamSetup *setup = &card->setup;
331:
332: if (!card->ChannelBuffersAllocated) {
333:
334: DecoderStreamReset(card);
335: if (setup->streamtype == stream_none) {
336: setup->streamtype = stream_PS;
337: }
338:
339: if (setup->audioselect == audio_none) {
340: setup->audioselect = audio_MPEG;
341: }
342:
343: DecoderPrepareAudio(card);
344: AudioMute(card, 1);
345: DecoderPrepareVideo(card);
346: VideoSetBackground(card, 1, 0, 0, 0); // black
347:
348: switch (setup->streamtype) {
349: default:
350: case stream_none: // unknown stream!
1.14 mocm 351: MDEBUG(0,
1.1 cvs 352: ": Video Decoder Prepare failed: unknown stream type\n");
353: return -ENODEV; // not an MPEG stream!
354: case stream_ES: // Elementary Stream
355: err = DecoderPrepareES(card);
356: break;
357: case stream_PES: // Packetized Elementary Stream
358: err = DecoderPreparePES(card);
359: break;
360: case stream_PS: // MPEG-1 System Stream / MPEG-2 Program Stream
361: err = DecoderPreparePS(card, -1, 0, 0, 0, 0, 0);
362: break;
363: case stream_DVD: // DVD Stream
364: err = DecoderPreparePS(card, 0, 0, 0, 0, 3, 1);
365: break;
366: }
367: if (err) { // insufficient memory
1.14 mocm 368: MDEBUG(0,
1.1 cvs 369: ": Video Decoder Prepare failed: no kernel memory, please reboot if possible\n");
370: CloseCard(card);
371: return -ENODEV;
372: }
373: }
374:
375: // Set up the Video Decoder as we have the stream information
376: if ((!card->FrameBuffersAllocated)
377: && (card->ChannelBuffersAllocated) && (card->stream.sh.valid)) {
378: // Automatic PAL/NTSC-switch according to MPEG-Source
379: h = card->stream.vsize;
380: if (h < 480)
381: h *= 2; // catch quarter sized images
382: printk(KERN_INFO LOGNAME ": Video mode: %s\n",
383: ((h == 480) ? "NTSC" : "PAL"));
384: card->videomode = ((h == 480) ? NTSC : PAL);
385: SetVideoSystem(card);
386: // Open the Video Decoder with the parameters retreived from the stream
387: if (
388: (err =
389: DecoderOpen(card, card->stream.hsize,
390: card->stream.vsize,
391: card->stream.sh.aspectratio,
392: !card->stream.MPEG2, 0,
1.2 rjkm 393: (card->stream.hsize > 480)))) { // TODO: include vbvbuffersize
1.14 mocm 394: MDEBUG(0,
1.1 cvs 395: ": Video Decoder Open failed: %s\n",
396: ((err == 1) ?
397: "Picture size too big (>1440 pixel wide)" :
398: "On-card memory insufficient for frame stores"));
399: CloseCard(card);
400: return -ENODEV; // picture too big or insufficient memory
401: }
1.14 mocm 402: MDEBUG(1, ": Ready to go\n");
1.1 cvs 403: card->startingV = 1; // tell the card to start playing as soon as ES-buffers are sufficiently full
404: card->startingA = 1; // tell the card to start playing as soon as ES-buffers are sufficiently full
405: }
406:
407:
408: return 0;
409: }
410:
1.12 mocm 411: int SetSCRstart(struct cvdv_cards *card, uint32_t SCR_base)
1.1 cvs 412: {
1.12 mocm 413: uint32_t SCR_compare;
414: uint32_t SCR_compareA;
415: uint32_t SCR_compareV;
1.1 cvs 416: if (card->startingV) {
1.14 mocm 417: MDEBUG(0, ": SCR in DVD Pack: 0x%08X\n",
1.1 cvs 418: SCR_base);
419: card->startingV = 0;
420: card->startingA = 0;
421: DecoderMaskByte(card, 0x007, 0xD2, 0xD2); // Set 0x010, halt SCR counter
422: SCR_compare = SCR_base + 000;
423: if (SCR_base < 900)
424: SCR_base = 0;
425: else
426: SCR_base -= 900;
427: //DecoderWriteDWord(card,0x009,SCR_base); // Set SCR counter
428: DecoderWriteByte(card, 0x009, SCR_base & 0xFF); // Set SCR counter
429: DecoderWriteByte(card, 0x00A, (SCR_base >> 8) & 0xFF);
430: DecoderWriteByte(card, 0x00B, (SCR_base >> 16) & 0xFF);
431: DecoderWriteByte(card, 0x00C, (SCR_base >> 24) & 0xFF);
432: DecoderMaskByte(card, 0x011, 0x03, 0x02); // compare, not capture
1.14 mocm 433: MDEBUG(0, ": SCR compare value: 0x%08X\n",
1.1 cvs 434: SCR_compare);
435: //DecoderWriteDWord(card,0x00D,SCR_compare); // Set Compare register
436: DecoderWriteByte(card, 0x00D, SCR_compare & 0xFF); // Set Compare register
437: DecoderWriteByte(card, 0x00E, (SCR_compare >> 8) & 0xFF);
438: DecoderWriteByte(card, 0x00F, (SCR_compare >> 16) & 0xFF);
439: DecoderWriteByte(card, 0x010, (SCR_compare >> 24) & 0xFF);
440: //DecoderWriteDWord(card,0x014,SCR_compare); // Set audio compare reg.
441: DecoderWriteByte(card, 0x014, SCR_compare & 0xFF); // Set audio compare reg.
442: DecoderWriteByte(card, 0x015, (SCR_compare >> 8) & 0xFF);
443: DecoderWriteByte(card, 0x016, (SCR_compare >> 16) & 0xFF);
444: DecoderWriteByte(card, 0x017, (SCR_compare >> 24) & 0xFF);
445: DecoderSetByte(card, 0x013, 0x03); // Video and Audio start on cmp.
446: //DecoderSetVideoPanic(card,0,DecoderGetVideoESSize(card)/4); // video panic at 25 percent
447: VideoSetBackground(card, 1, 0, 0, 0); // black
448: SCR_base = DecoderReadByte(card, 0x009);
449: SCR_base =
1.12 mocm 450: SCR_base | ((uint32_t) DecoderReadByte(card, 0x00A) << 8);
1.1 cvs 451: SCR_base =
1.12 mocm 452: SCR_base | ((uint32_t) DecoderReadByte(card, 0x00B) << 16);
1.1 cvs 453: SCR_base =
1.12 mocm 454: SCR_base | ((uint32_t) DecoderReadByte(card, 0x00C) << 24);
1.1 cvs 455: SCR_compareA = DecoderReadByte(card, 0x014);
456: SCR_compareA =
1.12 mocm 457: SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x015) <<
1.1 cvs 458: 8);
459: SCR_compareA =
1.12 mocm 460: SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x016) <<
1.1 cvs 461: 16);
462: SCR_compareA =
1.12 mocm 463: SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x017) <<
1.1 cvs 464: 24);
465: SCR_compareV = DecoderReadByte(card, 0x00D);
466: SCR_compareV =
1.12 mocm 467: SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00E) <<
1.1 cvs 468: 8);
469: SCR_compareV =
1.12 mocm 470: SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00F) <<
1.1 cvs 471: 16);
472: SCR_compareV =
1.12 mocm 473: SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x010) <<
1.1 cvs 474: 24);
475: if (DecoderReadByte(card, 0x013) & 0x03)
1.14 mocm 476: MDEBUG(1,": SCR 0x%08X, videocmp=0x%08X, audiocmp=0x%08X %02X\n",
1.1 cvs 477: SCR_base, SCR_compareV, SCR_compareA,
478: DecoderReadByte(card, 0x013));
479: DecoderMaskByte(card, 0x007, 0xD2, 0xC2); // Del 0x010, SCR counter run
480: }
481: return 0;
482: }
483:
1.12 mocm 484: int DecoderWriteBlock(struct cvdv_cards *card, uint8_t * data, int size,
1.1 cvs 485: int initial, int setSCR)
486: {
487: //int a,v,as,vs,ap,vp;
488: int res;
1.12 mocm 489: uint32_t SCR_base;
1.1 cvs 490: int co = 0;
1.12 mocm 491: // uint32_t SCR_compare;
1.1 cvs 492: res = 0;
1.6 mocm 493:
494: Prepare(card);
1.1 cvs 495:
496: if (size > 0) {
497:
1.14 mocm 498: if (!card->use_ringA)
1.17 mocm 499: MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE,0);
1.1 cvs 500:
501: if (card->startingDVDV || card->startingDVDA)
502: setSCR = 1;
503:
504: if (initial) {
505: DecoderStreamReset(card);
506: //TODO stop and start channel interface
507: setSCR = 1;
508: }
509:
510: if (setSCR) {
511: SCR_base = ParseSCR(data);
512: SetSCR(card, SCR_base);
513: }
1.6 mocm 514: card->DMAABusy = 0;
1.14 mocm 515: while (((res = MargiPushA(card, size, data)) < size)
1.6 mocm 516: && co < 1000) {
1.1 cvs 517: data+=res;
518: size-=res;
519: co++;
1.14 mocm 520: MDEBUG(2,
521: ": DecoderWriteBlock - buffers only filled with %d instead of %d bytes\n",res, size);
1.10 mocm 522: if (card->DMAABusy){
1.1 cvs 523: interruptible_sleep_on(&card->wqA);
1.10 mocm 524: }
1.1 cvs 525: }
526:
527: if (card->startingDVDV) {
528: card->startingDVDV = 0;
1.6 mocm 529: card->startingV = 1;
1.1 cvs 530: DecoderStartDecode(card);
531: }
532: if (card->startingDVDA) {
533: card->startingDVDA = 0;
1.6 mocm 534: card->startingA = 1;
535: AudioSetPlayMode(card, MAUDIO_PLAY);
1.1 cvs 536: }
537: }
538: return 0;
539: }
540:
541:
542:
543:
544:
545: //////////////////////////////
546: // //
547: // Char Device Procedures //
548: // //
549: //////////////////////////////
1.11 mocm 550: static long margi_write(struct cvdv_cards *card, const char *data,
1.6 mocm 551: unsigned long count, int nonblock)
1.1 cvs 552: {
1.11 mocm 553:
1.1 cvs 554: int res;
1.10 mocm 555: long int out=0;
1.17 mocm 556: int free;
557:
558: free = ring_write_rest(&(card->rbufA));
1.10 mocm 559:
1.1 cvs 560: if (card != NULL) {
1.21 mocm 561: card->nonblock = nonblock;
1.1 cvs 562: if (count > 0) { // Do we have data?
563: if ((res = Prepare(card)))
564: return res;
1.17 mocm 565: if (!card->use_ringA)
566: MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE,
567: 0);
568: if (!nonblock &&
1.21 mocm 569: !wait_event_interruptible(
570: card->wqA,
571: ring_write_rest(&(card->rbufA)) >count )){
572:
1.17 mocm 573: out = MargiPushA(card, count,
574: data);
575: } else {
576: out = MargiPushA(card, count, data);
1.14 mocm 577: }
578: }
579: return out;
580: } else {
581: MDEBUG(0,
582: ": Video Decoder Prepare failed: device with this minor number not found\n");
583: return -ENODEV; // device with this minor number not found
584: }
585: }
586:
1.17 mocm 587:
1.14 mocm 588: static long margi_write_audio(struct cvdv_cards *card, const char *data,
589: unsigned long count, int nonblock)
590: {
591: struct StreamSetup *setup = &card->setup;
1.1 cvs 592:
1.14 mocm 593: int res;
594: long int out=0;
1.17 mocm 595: int free;
596:
597: free = ring_write_rest(&(card->rbufB));
1.1 cvs 598:
1.14 mocm 599: if (card != NULL) {
1.21 mocm 600: card->nonblock = nonblock;
601:
1.14 mocm 602: if (count > 0) { // Do we have data?
603: if ((res = Prepare(card)))
604: return res;
605: if ((setup->streamtype == stream_ES)
1.17 mocm 606: || (setup->streamtype == stream_PES)){
1.14 mocm 607: if (!card->use_ringB)
1.17 mocm 608: MargiSetBuffers(card, NBBUF*
609: CHANNELBUFFERSIZE,1);
610: if (!nonblock &&
1.21 mocm 611: !wait_event_interruptible(
612: card->wqB,
613: ring_write_rest(&(card->rbufB))
614: > count)){
1.17 mocm 615: out = MargiPushB(card, count,
616: data);
617: } else {
1.14 mocm 618: out = MargiPushB(card, count, data);
619: }
1.1 cvs 620: }
621: }
1.10 mocm 622: return out;
1.1 cvs 623: } else {
1.14 mocm 624: MDEBUG(0,
1.1 cvs 625: ": Video Decoder Prepare failed: device with this minor number not found\n");
626: return -ENODEV; // device with this minor number not found
627: }
1.6 mocm 628: }
629:
1.12 mocm 630: void pes_write(uint8_t *buf, int count, void *priv)
631: {
632: struct cvdv_cards *card = (struct cvdv_cards *) priv;
1.14 mocm 633:
634: margi_write(card, buf, count, 0);
1.12 mocm 635: }
636:
1.6 mocm 637:
638: static ssize_t PSwrite(struct file *file, const char *data, size_t count,
639: loff_t * offset)
640: {
641: struct cvdv_cards *card =
642: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
1.17 mocm 643: return margi_write(card, data, count, file->f_flags&O_NONBLOCK);
1.1 cvs 644: }
645:
646: static unsigned int PSpoll(struct file *file, poll_table * table)
647: {
648: struct cvdv_cards *card =
649: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
650: if (card != NULL) {
1.9 mocm 651: poll_wait(file, &card->wqA , table);
1.14 mocm 652: if ( !card->rbufA.buffy || ring_write_rest(&(card->rbufA)) )
653: return (POLLOUT | POLLWRNORM);
654: else {
655: return 0;
656: }
1.1 cvs 657: } else
1.8 mocm 658: return POLLERR;
1.1 cvs 659: }
660:
1.17 mocm 661: static unsigned int poll_audio(struct file *file, poll_table * table)
662: {
663: struct cvdv_cards *card =
664: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
665: if (card != NULL) {
666: poll_wait(file, &card->wqB, table);
667: if ( !card->rbufB.buffy || ring_write_rest(&(card->rbufB)) )
668: return (POLLOUT | POLLWRNORM);
669: else {
670: return 0;
671: }
672: } else
673: return POLLERR;
674: }
675:
1.13 mocm 676: static int
677: OSD_DrawCommand(struct cvdv_cards *card,osd_cmd_t *dc)
678: {
679:
680: switch (dc->cmd) {
681: case OSD_Close:
1.14 mocm 682: MDEBUG(1,": OSD Close\n");
1.13 mocm 683: return OSDClose(card);
684: case OSD_Open: // Open(x0,y0,x1,y1,BitPerPixel(2/4/8),mix(0..15))
685: return OSDOpen(card, dc->x0,
686: dc->y0, dc->x1,
687: dc->y1,
688: dc->color & 0x0F,
689: (dc->color >> 4) &
690: 0x0F);
691: case OSD_Show:
692: return OSDShow(card);
693: case OSD_Hide:
694: return OSDHide(card);
695: case OSD_Clear:
696: return OSDClear(card);
697: case OSD_Fill: // Fill(color)
698: return OSDFill(card, dc->color);
699: case OSD_SetColor: // SetColor(color,R(x0),G(y0),B(x1),opacity(y1))
700: return (OSDSetColor
701: (card, dc->color, dc->x0,
702: dc->y0, dc->x1, 0,
703: (dc->y1 != 255),
704: (dc->y1 == 0)) >= 0);
705: case OSD_SetPalette:// SetPalette(firstcolor{color},lastcolor{x0},data)
706: return OSDSetPalette(card,
707: dc->color,
708: dc->x0, (uint8_t *)
709: dc->data);
710: case OSD_SetTrans: // SetTrans(transparency{color})
711: return OSDSetTrans(card,
712: (dc->color >> 4)
713: & 0x0F);
714: case OSD_SetPixel: // SetPixel(x0,y0,color)
715: return OSDSetPixel(card, dc->x0,
716: dc->y0,
717: dc->color);
718: case OSD_GetPixel: // GetPixel(x0,y0);
719: return OSDGetPixel(card, dc->x0,
720: dc->y0);
721: case OSD_SetRow: // SetRow(x0,y0,x1,(uint8_t*)data)
722: return OSDSetRow(card, dc->x0,
723: dc->y0, dc->x1,
724: (uint8_t *) dc->data);
725: case OSD_SetBlock: // SetBlock(x0,y0,x1,y1,(uint8_t*)data)
726: return OSDSetBlock(card, dc->x0,
727: dc->y0, dc->x1,
728: dc->y1,
729: dc->color,
730: (uint8_t *)
731: dc->data);
732: case OSD_FillRow: // FillRow(x0,y0,x1,color)
733: return OSDFillRow(card, dc->x0,
734: dc->y0, dc->x1,
735: dc->color);
736: case OSD_FillBlock: // FillRow(x0,y0,x1,y1,color)
737: return OSDFillBlock(card, dc->x0,
738: dc->y0, dc->x1,
739: dc->y1,
740: dc->color);
741: case OSD_Line: // Line(x0,y0,x1,y1,color);
742: return OSDLine(card, dc->x0,
743: dc->y0, dc->x1,
744: dc->y1, dc->color);
745: case OSD_Query: // Query(x0,y0,x1,y1,aspect(color:11)
746: return OSDQuery(card, &dc->x0,
747: &dc->y0, &dc->x1,
748: &dc->y1,
749: &dc->color);
750: case OSD_Test:
751: return OSDTest(card);
752: default:
753: return -EINVAL;
754: }
755: }
756:
1.6 mocm 757:
1.1 cvs 758: static int PSioctl(struct inode *inode, struct file *file,
759: unsigned int cmd, unsigned long arg)
760: {
761: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
1.13 mocm 762: osd_cmd_t *dc;
1.1 cvs 763: struct decodercmd *command;
1.12 mocm 764: uint16_t attr;
1.10 mocm 765:
1.1 cvs 766: if (card != NULL) {
767: if (_IOC_TYPE(cmd) == CVDV_IOCTL_MAGIC)
768: switch (_IOC_NR(cmd)) {
769: case IOCTL_DRAW: // Drawing commands
1.13 mocm 770: dc = (osd_cmd_t *) arg;
771: return OSD_DrawCommand(card,dc);
772: break;
1.1 cvs 773: case IOCTL_DECODER:
774: command = (struct decodercmd *) arg;
775: switch (command->cmd) {
1.10 mocm 776:
777: case Decoder_CSS:
1.1 cvs 778: /*
779: return DecoderCSS(card,
780: command->param1,
781: command->data1);
782: */
1.10 mocm 783: break;
784:
1.1 cvs 785: case Decoder_Set_Videosystem:
1.14 mocm 786: MDEBUG(1,": -- Decoder_Set_Videosystem\n");
1.1 cvs 787: card->videomode =
788: (videosystem) command->param1;
789: SetVideoSystem(card);
790: return 0;
1.10 mocm 791: break;
792:
1.1 cvs 793: case Decoder_Set_Streamtype:
1.14 mocm 794: MDEBUG(1,": -- Decoder_Set_Streamtype\n");
1.1 cvs 795: card->setup.streamtype =
796: (stream_type) command->param1;
797: return 0;
1.10 mocm 798: break;
799:
1.1 cvs 800: case Decoder_Set_Audiotype:
1.14 mocm 801: MDEBUG(1,": -- Decoder_Set_Audiotype\n");
1.1 cvs 802: card->setup.audioselect =
803: (audio_type) command->param1;
804: DecoderPrepareAudio(card);
805: return 0;
1.10 mocm 806: break;
807:
1.1 cvs 808: case Decoder_Set_VideoStreamID:
1.14 mocm 809: MDEBUG(1,": -- Decoder_Set_VideoStreamID\n");
1.1 cvs 810: card->setup.videoID =
811: command->param1;
812: DecoderPrepareVideo(card);
813: return 0;
1.10 mocm 814: break;
815:
1.1 cvs 816: case Decoder_Set_AudioStreamID:
1.14 mocm 817: MDEBUG(1,": -- Decoder_Set_AudioStreamID 0x%02X 0x%02X\n",
818: command->param1,command->param2);
1.1 cvs 819: card->setup.audioID =
820: command->param1;
821: card->setup.audioIDext =
822: command->param2;
823: attr = card->lastaattr;
824: DecoderSelectAudioID(card);
825: card->lastaattr = attr;
826: return 0;
1.10 mocm 827: break;
828:
1.1 cvs 829: case Decoder_Still_Put:
830: return DecoderShowStill(card,
831: command->
832: param1,
833: command->
834: param2,
835: command->
836: data1,
837: command->
838: data2);
1.10 mocm 839: break;
840:
1.1 cvs 841: case Decoder_Still_Get:
842: return DecoderGetStill(card,
843: &command->
844: param1,
845: &command->
846: param2,
847: command->
848: data1,
849: command->
850: data2);
1.10 mocm 851: break;
852:
1.1 cvs 853: case Decoder_Pause: // pause{param1} 0=run 1=pause 2=toggle
854: if (command->param1 == 2) {
855: if (card->paused)
856: DecoderUnPause
857: (card);
858: else
859: DecoderPause(card);
860: } else {
861: if (!command->param1)
862: DecoderUnPause
863: (card);
864: else
865: DecoderPause(card);
866: }
867: return 0;
1.10 mocm 868:
869: /* Too buggy
870: case Decoder_FFWD: // pause{param1} =normal 1=ffwd 2=toggle
871: if (command->param1 == 2) {
872: if (card->videoffwd)
873: card->videoffwd = 0;
874: else
1.13 mocm 875: card->videoffwd = 3;
1.10 mocm 876: } else {
877: if (!command->param1)
878: card->videoffwd = 0;
879: else
1.13 mocm 880: card->videoffwd = 3;
1.10 mocm 881: }
882: return 0;
883:
884: case Decoder_Slow: // pause{param1} =normal 1=slow 2=toggle
885: if (command->param1 == 2) {
886: if (card->videoslow)
887: card->videoslow = 0;
888: else
889: card->videoslow = 4;
890: } else {
891: if (!command->param1)
892: card->videoslow = 0;
893: else
894: card->videoslow = 4;
895: }
896: return 0;
897: */
1.1 cvs 898: case Decoder_Highlight: // active{param1}, color information(SL_COLI or AC_COLI){data1[4]}, button position(BTN_POSI){data2[6]}
899: return DecoderHighlight(card,
900: command->
901: param1,
902: command->
903: data1,
904: command->
905: data2);
906: case Decoder_SPU: // stream{param1}, active{param2}
907: return DecoderSPUStream(card,
908: command->
909: param1,
910: command->
911: param2);
912: case Decoder_SPU_Palette: // length{param1}, palette{data1}
913: return DecoderSPUPalette(card,
914: command->
915: param1,
916: command->
917: data1);
918: case Decoder_GetNavi: // data1 will be filled with PCI or DSI pack, and 1024 will be returned
919: return DecoderGetNavi(card,
920: command->
921: data1);
922: case Decoder_SetKaraoke: // Vocal1{param1}, Vocal2{param2}, Melody{param3}
923: return DecoderKaraoke(card,
924: command->
925: param1,
926: command->
927: param2,
928: command->
929: param3);
930: case Decoder_Set_Videoattribute:
1.14 mocm 931: MDEBUG(1,": -- Decoder_Set_Videoattribute\n");
1.1 cvs 932: if (!card->ChannelBuffersAllocated) {
933: DecoderStreamReset(card);
934: MargiFlush(card);
935:
936: card->setup.streamtype =
937: stream_DVD;
938: card->setup.videoID = 0;
939: DecoderPrepareVideo(card);
940: DecoderPreparePS(card, 0,
941: 0, 2, 2,
942: 3, 1);
943: }
944:
945: SetVideoAttr(card,
946: command->param1);
1.6 mocm 947: card->startingDVDV = 1;
948: // tell the card to start playing as soon as ES-buffers are sufficiently full
1.1 cvs 949: return 0;
950: case Decoder_Set_Audioattribute:
1.14 mocm 951: MDEBUG(1,": -- Decoder_Set_Audioattribute\n");
1.1 cvs 952: SetAudioAttr(card,
953: command->param1);
954: card->startingDVDA =
955: ((card->setup.audioselect !=
956: audio_none)
957: && (card->setup.audioselect != audio_disable)); // tell the card to start playing as soon as ES-buffers are sufficiently full
958: return 0;
959: case Decoder_WriteBlock: // DVD-Sector{data1}, sectorsize{param1{2048}}, initialsector{param2{bool}}, set_SCR{param3}
960: return DecoderWriteBlock(card,
961: command->
962: data1,
963: command->
964: param1,
965: command->
966: param2,
967: command->
968: param3);
969: default:
970: return -EINVAL;
971: }
972: default:
973: return -EINVAL;
974: } else
975: return -EINVAL;
976: } else {
1.14 mocm 977: MDEBUG(0,
1.1 cvs 978: ": Video Decoder Prepare failed: device with this minor number not found\n");
979: return -ENODEV; // device with this minor number not found
980: }
981: }
982:
1.6 mocm 983:
1.1 cvs 984: static int PSmmap(struct file *file, struct vm_area_struct *vm)
985: {
986: return -ENODEV;
987: }
988:
1.6 mocm 989:
990:
1.11 mocm 991: static int margi_open(struct cvdv_cards *card, int flags)
1.1 cvs 992: {
1.6 mocm 993: int closed;
1.1 cvs 994: if (card != NULL) {
1.14 mocm 995: MDEBUG(1, ": -- open \n");
1.1 cvs 996: CloseCard(card);
1.5 mocm 997: OSDClose(card);
1.6 mocm 998: #ifdef NOINT
999: card->timer.function = Timerfunction;
1000: card->timer.data=(unsigned long) card;
1001: card->timer.expires=jiffies+1;
1002: add_timer(&card->timer);
1003: #endif
1004:
1005: if (card->open)
1.14 mocm 1006: MDEBUG(0,": PSopen - already open\n");
1.1 cvs 1007: closed = 1;
1.6 mocm 1008: if (card->open)
1009: closed = 0;
1.1 cvs 1010: if (closed) { // first open() for this card?
1.19 mocm 1011: MargiFreeBuffers(card);
1.1 cvs 1012: VideoSetBackground(card, 1, 0, 0, 0); // black
1013: }
1.6 mocm 1014: card->open++;
1.11 mocm 1015: MOD_INC_USE_COUNT;
1.1 cvs 1016: return 0;
1017: } else {
1.14 mocm 1018: MDEBUG(0,
1.1 cvs 1019: ": Video Decoder Prepare failed: device with this minor number not found\n");
1020: return -ENODEV; // device with this minor number not found
1021: }
1.6 mocm 1022:
1.1 cvs 1023: }
1024:
1.6 mocm 1025:
1026: static int PSopen(struct inode *inode, struct file *file)
1.1 cvs 1027: {
1.11 mocm 1028: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV];
1.15 mocm 1029: card->audiostate.AVSyncState=true;
1.17 mocm 1030: return margi_open(card, file->f_flags);
1.6 mocm 1031: }
1032:
1033:
1.11 mocm 1034: static int all_margi_close(struct cvdv_cards *card)
1.6 mocm 1035: {
1.11 mocm 1036:
1.1 cvs 1037: if (card != NULL) {
1.14 mocm 1038: MDEBUG(1, ": -- PSrelease\n");
1.11 mocm 1039: if (card->open <= 0)
1.14 mocm 1040: MDEBUG(1,": PSrelease - not open\n");
1.6 mocm 1041: card->open--;
1.4 mocm 1042:
1.11 mocm 1043: MOD_DEC_USE_COUNT;
1.6 mocm 1044: if (!card->open) {
1.14 mocm 1045: MDEBUG(1,": PSrelease - last close\n");
1.11 mocm 1046: CloseCard(card); // close immediately
1.1 cvs 1047: }
1048: return 0;
1049: } else {
1.14 mocm 1050: MDEBUG(0,": Video Decoder Prepare failed:\n");
1.1 cvs 1051: return -ENODEV; // device with this minor number not found
1052: }
1.6 mocm 1053:
1054: }
1055:
1056: static int PSrelease(struct inode *inode, struct file *file)
1057: {
1058: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
1.11 mocm 1059: return all_margi_close(card);
1.1 cvs 1060: }
1061:
1062: //////////////////////////
1063: // //
1064: // Char Device Hookup //
1065: // //
1066: //////////////////////////
1067:
1068: // Hookups for a write-only device, that accepts MPEG-2 Program Stream
1069: struct file_operations cvdv_fileops = {
1070: write: PSwrite,
1071: poll: PSpoll,
1072: ioctl: PSioctl,
1073: mmap: PSmmap,
1074: open: PSopen,
1075: release: PSrelease,
1076: };
1.6 mocm 1077:
1078:
1079: #ifdef DVB
1080:
1081: static inline int
1082: num2type(struct cvdv_cards *card, int num)
1083: {
1084: if (!card->dvb_devs)
1085: return -2;
1086: if (num>=card->dvb_devs->num)
1087: return -2;
1088: return card->dvb_devs->tab[num];
1089: }
1090:
1091: static int
1092: dvbdev_open(struct dvb_device *dvbdev, int num,
1093: struct inode *inode, struct file *file)
1094: {
1095: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1096: int type=num2type(card, num);
1097: int ret=0;
1098:
1099: if (type<0)
1100: return -EINVAL;
1101:
1102: if (card->users[num] >= card->dvb_devs->max_users[num])
1103: return -EBUSY;
1104:
1105: if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
1106: if (card->writers[num] >= card->dvb_devs->max_writers[num])
1107: return -EBUSY;
1108:
1109: switch (type) {
1110: case DVB_DEVICE_VIDEO_0:
1111: card->video_blank=true;
1.9 mocm 1112: card->audiostate.AVSyncState=true;
1.6 mocm 1113: card->videostate.streamSource=VIDEO_SOURCE_DEMUX;
1.17 mocm 1114: margi_open(card, file->f_flags);
1.7 mocm 1115: break;
1.6 mocm 1116:
1117: case DVB_DEVICE_AUDIO_0:
1.17 mocm 1118: card->audiostate.AVSyncState=true;
1.6 mocm 1119: card->audiostate.streamSource=AUDIO_SOURCE_DEMUX;
1120: break;
1121:
1122: case DVB_DEVICE_DEMUX_0:
1123: if ((file->f_flags&O_ACCMODE)!=O_RDWR)
1124: return -EINVAL;
1125: ret=DmxDevFilterAlloc(&card->dmxdev, file);
1126: break;
1.18 mocm 1127:
1.6 mocm 1128: case DVB_DEVICE_DVR_0:
1.17 mocm 1129: card->audiostate.AVSyncState=true;
1.18 mocm 1130: card->setup.streamtype = stream_PES;
1.17 mocm 1131: margi_open(card, file->f_flags);
1.6 mocm 1132: ret=DmxDevDVROpen(&card->dmxdev, file);
1133: break;
1.9 mocm 1134:
1135: case DVB_DEVICE_OSD_0:
1136: break;
1137: default:
1.6 mocm 1138: return -EINVAL;
1139: }
1140: if (ret<0)
1141: return ret;
1142: if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
1143: card->writers[num]++;
1144: card->users[num]++;
1145: return ret;
1146: }
1147:
1148: static int
1149: dvbdev_close(struct dvb_device *dvbdev, int num,
1150: struct inode *inode, struct file *file)
1151: {
1152: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1153: int type=num2type(card, num);
1154: int ret=0;
1155:
1156: if (type<0)
1157: return -EINVAL;
1158:
1159: switch (type) {
1160: case DVB_DEVICE_VIDEO_0:
1.11 mocm 1161: case DVB_DEVICE_AUDIO_0:
1162: if (card->open)
1163: all_margi_close(card);
1.6 mocm 1164: break;
1165:
1166: case DVB_DEVICE_DEMUX_0:
1167: ret=DmxDevFilterFree(&card->dmxdev, file);
1168: break;
1169:
1170: case DVB_DEVICE_DVR_0:
1171: ret=DmxDevDVRClose(&card->dmxdev, file);
1.12 mocm 1172: if (card->open)
1173: all_margi_close(card);
1.6 mocm 1174: break;
1.9 mocm 1175: case DVB_DEVICE_OSD_0:
1176: break;
1177: default:
1.6 mocm 1178: return -EINVAL;
1179: }
1180: if (ret<0)
1181: return ret;
1182: if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
1183: card->writers[num]--;
1184: card->users[num]--;
1185: return ret;
1186: }
1187:
1.13 mocm 1188:
1.6 mocm 1189: static ssize_t
1190: dvbdev_write(struct dvb_device *dvbdev, int num,
1191: struct file *file,
1192: const char *buf, size_t count, loff_t *ppos)
1193: {
1194: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1195: int type=num2type(card, num);
1196:
1197: switch (type) {
1198: case DVB_DEVICE_VIDEO_0:
1199: if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY)
1200: return -EPERM;
1.11 mocm 1201: return margi_write(card, buf, count,
1.6 mocm 1202: file->f_flags&O_NONBLOCK);
1203:
1204: case DVB_DEVICE_AUDIO_0:
1205: if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
1206: return -EPERM;
1.14 mocm 1207: if ( card->setup.streamtype != stream_PES )
1208: return -EPERM;
1209:
1.17 mocm 1210: return margi_write_audio(card, buf, count,
1211: file->f_flags&O_NONBLOCK);
1.6 mocm 1212:
1213: case DVB_DEVICE_DVR_0:
1214: return DmxDevDVRWrite(&card->dmxdev, file, buf, count, ppos);
1215: default:
1216: return -EOPNOTSUPP;
1217: }
1218: return 0;
1219: }
1220:
1.12 mocm 1221: static ssize_t
1222: dvbdev_read(struct dvb_device *dvbdev, int num,
1223: struct file *file, char *buf, size_t count, loff_t *ppos)
1224: {
1225: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1226: int type=num2type(card, num);
1227:
1228: switch (type) {
1229: case DVB_DEVICE_VIDEO_0:
1230: break;
1231: case DVB_DEVICE_AUDIO_0:
1232: break;
1233: case DVB_DEVICE_DEMUX_0:
1234: return DmxDevRead(&card->dmxdev, file, buf, count, ppos);
1235: case DVB_DEVICE_DVR_0:
1236: return DmxDevDVRRead(&card->dmxdev, file, buf, count, ppos);
1237: case DVB_DEVICE_CA_0:
1238: break;
1239: default:
1240: return -EOPNOTSUPP;
1241: }
1242: return 0;
1243: }
1244:
1245:
1246:
1.6 mocm 1247:
1248: static int
1249: dvbdev_ioctl(struct dvb_device *dvbdev, int num,
1250: struct file *file, unsigned int cmd, unsigned long arg)
1251: {
1252: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1253: void *parg=(void *)arg;
1254: int type=num2type(card, num);
1.17 mocm 1255: uint16_t attr;
1.6 mocm 1256:
1257: switch (type) {
1258: case DVB_DEVICE_VIDEO_0:
1259: if (((file->f_flags&O_ACCMODE)==O_RDONLY) &&
1260: (cmd!=VIDEO_GET_STATUS))
1261: return -EPERM;
1262:
1263: switch (cmd) {
1264:
1265: case VIDEO_STOP:
1266: DecoderPause(card);
1.9 mocm 1267: card->videostate.playState = VIDEO_STOPPED;
1.10 mocm 1268: if (card->videostate.videoBlank)
1269: VideoSetBackground(card, 1, 0, 0, 0);
1.9 mocm 1270:
1.10 mocm 1271:
1.9 mocm 1272: return 0;
1.6 mocm 1273:
1274: case VIDEO_PLAY:
1275:
1276: if (card->videostate.streamSource==
1277: VIDEO_SOURCE_MEMORY) {
1.9 mocm 1278: if (card->videostate.playState==VIDEO_FREEZED){
1279: DecoderUnPause(card);
1280: } else {
1281: DecoderUnPause(card);
1282: }
1.6 mocm 1283: }
1284: break;
1285:
1286: case VIDEO_FREEZE:
1287: DecoderPause(card);
1288: break;
1289:
1290: case VIDEO_CONTINUE:
1291: if (card->videostate.playState==VIDEO_FREEZED) {
1292: DecoderUnPause(card);
1293: }
1294: break;
1295:
1296: case VIDEO_SELECT_SOURCE:
1297: card->videostate.streamSource=(videoStreamSource_t) arg;
1298: break;
1299:
1300: case VIDEO_SET_BLANK:
1301: card->videostate.videoBlank=(boolean) arg;
1302: break;
1303:
1304: case VIDEO_GET_STATUS:
1305: if(copy_to_user(parg, &card->videostate,
1306: sizeof(struct videoStatus)))
1307: return -EFAULT;
1308: break;
1309:
1310: case VIDEO_GET_EVENT:
1311: return -EOPNOTSUPP;
1312:
1313: case VIDEO_SET_DISPLAY_FORMAT:
1314: {
1315: videoDisplayFormat_t format=(videoDisplayFormat_t) arg;
1.12 mocm 1316: uint16_t val=0;
1.6 mocm 1317:
1318: switch(format) {
1319: case VIDEO_PAN_SCAN:
1320: val=VID_PAN_SCAN_PREF;
1321: break;
1322:
1323: case VIDEO_LETTER_BOX:
1324: val=VID_VC_AND_PS_PREF;
1325: break;
1326:
1327: case VIDEO_CENTER_CUT_OUT:
1328: val=VID_CENTRE_CUT_PREF;
1329: break;
1330:
1331: default:
1332: return -EINVAL;
1333: }
1334:
1335: card->videostate.videoFormat=format;
1336: return 0;
1337: }
1338:
1339: case VIDEO_STILLPICTURE:
1340: {
1341: struct videoDisplayStillPicture pic;
1342:
1343: if(copy_from_user(&pic, parg,
1344: sizeof(struct videoDisplayStillPicture)))
1345: return -EFAULT;
1346:
1347: break;
1348: }
1349:
1350: case VIDEO_FAST_FORWARD:
1.10 mocm 1351: if (card->videostate.streamSource !=
1352: VIDEO_SOURCE_MEMORY)
1353: return -EPERM;
1.13 mocm 1354: card->videoffwd = 3;
1.6 mocm 1355: break;
1356:
1357: case VIDEO_SLOWMOTION:
1358: if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY)
1359: return -EPERM;
1.10 mocm 1360: card->videoslow = arg;
1.6 mocm 1361:
1362: break;
1363:
1364: case VIDEO_GET_CAPABILITIES:
1365: {
1.8 mocm 1366: int cap=VIDEO_CAP_MPEG1|
1367: VIDEO_CAP_MPEG2|
1368: VIDEO_CAP_SYS|
1369: VIDEO_CAP_PROG|
1370: VIDEO_CAP_SPU|
1371: VIDEO_CAP_NAVI|
1372: VIDEO_CAP_CSS;
1373:
1.6 mocm 1374:
1375: if (copy_to_user(parg, &cap,
1376: sizeof(cap)))
1377: return -EFAULT;
1378: break;
1379: }
1.18 mocm 1380:
1.14 mocm 1381: case VIDEO_SET_STREAMTYPE:
1382: {
1383: int f = -1;
1384: switch(arg){
1385: case VIDEO_CAP_MPEG1:
1386: case VIDEO_CAP_MPEG2:
1387: f = stream_PES;
1388: break;
1389:
1390: case VIDEO_CAP_SYS:
1391: case VIDEO_CAP_PROG:
1392: f = stream_PS;
1393: break;
1394:
1395: case VIDEO_CAP_SPU:
1396: case VIDEO_CAP_NAVI:
1397: case VIDEO_CAP_CSS:
1398: f = stream_DVD;
1399: }
1400: card->setup.streamtype = f;
1.17 mocm 1401:
1.14 mocm 1402: }
1403: break;
1404:
1.17 mocm 1405: case VIDEO_SET_ID:
1406: card->setup.videoID = arg;
1407: DecoderPrepareVideo(card);
1408: break;
1409:
1410: case VIDEO_SET_SYSTEM:
1411: card->videomode = (videosystem) arg;
1412: SetVideoSystem(card);
1413: break;
1414:
1415: case VIDEO_SET_HIGHLIGHT:
1416: {
1417: uint8_t data1[4];
1418: uint8_t data2[6];
1419: videoHighlight_t vh;
1420:
1421: if(copy_from_user(&vh, parg, sizeof(videoHighlight_t)))
1422: return -EFAULT;
1423:
1424: data1[0] = vh.contrast1;
1425: data1[1] = vh.contrast2;
1426: data1[2] = vh.color1;
1427: data1[3] = vh.color2;
1428: data2[0] = vh.ypos & 0xFF;
1429: data2[1] = (uint8_t) ((vh.ypos >> 1) & 0xFF);
1430: data2[2] = (uint8_t) ((vh.ypos >> 2) & 0xFF);
1431: data2[3] = vh.xpos & 0xFF;
1432: data2[4] = (uint8_t) ((vh.xpos >> 1) & 0xFF);
1433: data2[5] = (uint8_t) ((vh.xpos >> 2) & 0xFF);
1434: return DecoderHighlight(card, vh.active, data1, data2);
1435: break;
1436: }
1437:
1438: case VIDEO_SET_SPU:
1439: {
1440: videoSPU_t spu;
1441:
1442: if(copy_from_user(&spu, parg, sizeof(videoSPU_t)))
1443: return -EFAULT;
1444:
1445: return DecoderSPUStream(card, spu.streamID, spu.active);
1446: break;
1447: }
1448:
1.20 mocm 1449: case VIDEO_SET_SPU_PALETTE:
1.17 mocm 1450: {
1451: videoSPUPalette_t spup;
1452:
1453: if(copy_from_user(&spup, parg, sizeof(videoSPUPalette_t)))
1454: return -EFAULT;
1455:
1456: return DecoderSPUPalette(card, spup.length, spup.palette);
1457: break;
1458: }
1459:
1460: case VIDEO_GET_NAVI:
1461: {
1462: videoNaviPack_t navi;
1463:
1.18 mocm 1464: navi.length = DecoderGetNavi(card, (u8 *)&(navi.data));
1.17 mocm 1465: if(copy_to_user(parg, &navi, sizeof(videoNaviPack_t)))
1466: return -EFAULT;
1467: }
1468: break;
1469:
1470: case VIDEO_SET_ATTRIBUTES:
1471: {
1472: if (!card->ChannelBuffersAllocated) {
1473: DecoderStreamReset(card);
1474: MargiFlush(card);
1475:
1476: card->setup.streamtype = stream_DVD;
1477: card->setup.videoID = 0;
1478: DecoderPrepareVideo(card);
1479: DecoderPreparePS(card, 0, 0, 2, 2, 3, 1);
1480: }
1481:
1482: SetVideoAttr(card, arg);
1483: card->startingDVDV = 1;
1484: }
1485: break;
1486:
1.6 mocm 1487: default:
1488: return -ENOIOCTLCMD;
1489: }
1490: return 0;
1.14 mocm 1491:
1.6 mocm 1492: case DVB_DEVICE_AUDIO_0:
1493: if (((file->f_flags&O_ACCMODE)==O_RDONLY) &&
1494: (cmd!=AUDIO_GET_STATUS))
1495: return -EPERM;
1496:
1497: switch (cmd) {
1498:
1499: case AUDIO_STOP:
1500: if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
1501: break;
1502: AudioStopDecode(card);
1503: card->audiostate.playState=AUDIO_STOPPED;
1504: break;
1505:
1506: case AUDIO_PLAY:
1507: if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
1508: break;
1509: AudioSetPlayMode(card, MAUDIO_PLAY);
1510: card->audiostate.playState=AUDIO_PLAYING;
1511: break;
1512:
1513: case AUDIO_PAUSE:
1514: card->audiostate.playState=AUDIO_PAUSED;
1515: AudioSetPlayMode(card, MAUDIO_PAUSE);
1516: break;
1517:
1518: case AUDIO_CONTINUE:
1519: if (card->audiostate.playState==AUDIO_PAUSED) {
1520: card->audiostate.playState=AUDIO_PLAYING;
1521: AudioSetPlayMode(card, MAUDIO_PLAY);
1522: }
1523: break;
1524:
1525: case AUDIO_SELECT_SOURCE:
1.14 mocm 1526: card->audiostate.streamSource=
1527: (audioStreamSource_t) arg;
1.6 mocm 1528: break;
1529:
1530: case AUDIO_SET_MUTE:
1531: {
1532: AudioMute(card, arg);
1533: card->audiostate.muteState=(boolean) arg;
1534: break;
1535: }
1536:
1537: case AUDIO_SET_AV_SYNC:
1.9 mocm 1538: card->videosync=(boolean) arg;
1.6 mocm 1539: card->audiostate.AVSyncState=(boolean) arg;
1540: break;
1541:
1542: case AUDIO_SET_BYPASS_MODE:
1543: return -EINVAL;
1544:
1545: case AUDIO_CHANNEL_SELECT:
1546: card->audiostate.channelSelect=(audioChannelSelect_t) arg;
1547:
1548: switch(card->audiostate.channelSelect) {
1549: case AUDIO_STEREO:
1550: break;
1551:
1552: case AUDIO_MONO_LEFT:
1553: break;
1554:
1555: case AUDIO_MONO_RIGHT:
1556: break;
1557:
1558: default:
1559: return -EINVAL;
1560: }
1561: return 0;
1562:
1563: case AUDIO_GET_STATUS:
1564: if(copy_to_user(parg, &card->audiostate,
1565: sizeof(struct audioStatus)))
1566: return -EFAULT;
1567: break;
1568:
1569: case AUDIO_GET_CAPABILITIES:
1570: {
1571: int cap=AUDIO_CAP_LPCM|
1572: AUDIO_CAP_MP1|
1.8 mocm 1573: AUDIO_CAP_MP2|
1574: AUDIO_CAP_AC3;
1.6 mocm 1575:
1576: if (copy_to_user(parg, &cap,
1577: sizeof(cap)))
1578: return -EFAULT;
1579: }
1.14 mocm 1580: break;
1581:
1582:
1583: case AUDIO_SET_STREAMTYPE:
1584: {
1585: int f = -1;
1586:
1587: switch(arg){
1588: case AUDIO_CAP_DTS:
1589: case AUDIO_CAP_MP3:
1590: case AUDIO_CAP_AAC:
1591: case AUDIO_CAP_SDDS:
1592: case AUDIO_CAP_OGG:
1593: f = audio_none;
1594: break;
1595:
1596: case AUDIO_CAP_LPCM:
1597: f = audio_LPCM;
1598: break;
1599:
1600: case AUDIO_CAP_MP1:
1601: case AUDIO_CAP_MP2:
1602: f = audio_MPEG;
1603: break;
1604:
1605: case AUDIO_CAP_AC3:
1606: f = audio_AC3;
1607: break;
1608: }
1609:
1610: card->setup.audioselect = (audio_type) f;
1611: DecoderPrepareAudio(card);
1.17 mocm 1612: break;
1.14 mocm 1613: }
1.17 mocm 1614:
1615: case AUDIO_SET_ID:
1616: if (arg < 0 || arg >32) arg = 0;
1617: card->setup.audioID = arg;
1618: arg = 0;
1619: case AUDIO_SET_EXT_ID:
1620: if (arg < 0 || arg >32) arg = 0;
1621: card->setup.audioIDext = arg;
1622:
1623: attr = card->lastaattr;
1624: DecoderSelectAudioID(card);
1625: card->lastaattr = attr;
1626: break;
1627:
1628: case AUDIO_SET_MIXER:
1629: return -EINVAL;
1630:
1631: case AUDIO_SET_ATTRIBUTES:
1632: SetAudioAttr(card,arg);
1633: card->startingDVDA = ((card->setup.audioselect != audio_none)
1634: && (card->setup.audioselect !=
1635: audio_disable));
1636: break;
1637:
1638:
1639: case AUDIO_SET_KARAOKE:
1640: {
1641: break;
1642: }
1.14 mocm 1643:
1644: default:
1.6 mocm 1645: return -ENOIOCTLCMD;
1646: }
1.14 mocm 1647: break;
1.6 mocm 1648:
1649: case DVB_DEVICE_DEMUX_0:
1650: return DmxDevIoctl(&card->dmxdev, file, cmd, arg);
1.13 mocm 1651: break;
1.6 mocm 1652:
1.9 mocm 1653: case DVB_DEVICE_OSD_0:
1654: {
1.13 mocm 1655: switch (cmd) {
1.9 mocm 1656: case OSD_SEND_CMD:
1.13 mocm 1657: {
1658: osd_cmd_t doc;
1659:
1660: if(copy_from_user(&doc, parg,
1661: sizeof(osd_cmd_t)))
1662: return -EFAULT;
1663: return OSD_DrawCommand(card, &doc);
1664: }
1.9 mocm 1665: default:
1666: return -EINVAL;
1.13 mocm 1667: }
1.9 mocm 1668: break;
1669: }
1670: default:
1.6 mocm 1671: return -EOPNOTSUPP;
1672: }
1673: return 0;
1674: }
1675:
1676: static unsigned int
1677: dvbdev_poll(struct dvb_device *dvbdev, int num,
1678: struct file *file, poll_table * wait)
1679: {
1680: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1681: int type=num2type(card, num);
1682:
1683: switch (type) {
1684: case DVB_DEVICE_DEMUX_0:
1685: return DmxDevPoll(&card->dmxdev, file, wait);
1686:
1687: case DVB_DEVICE_VIDEO_0:
1688: return PSpoll(file, wait);
1689:
1690: case DVB_DEVICE_AUDIO_0:
1.17 mocm 1691: return poll_audio(file, wait);
1.6 mocm 1692:
1693: case DVB_DEVICE_CA_0:
1694: break;
1695:
1696: default:
1697: return -EOPNOTSUPP;
1698: }
1699:
1700: return 0;
1701: }
1702:
1703:
1704: static int
1705: dvbdev_device_type(struct dvb_device *dvbdev, unsigned int num)
1706: {
1707: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1708:
1709: return num2type(card, num);
1710: }
1711: #endif
1712:
1713: /******************************************************************************
1714: * driver registration
1715: ******************************************************************************/
1716:
1717:
1718: #ifdef DVB
1719:
1720: #define INFU 32768
1721:
1.9 mocm 1722:
1723:
1.6 mocm 1724: static dvb_devs_t mdvb_devs = {
1.9 mocm 1725: 9,
1.6 mocm 1726: {
1.9 mocm 1727: DVB_DEVICE_VIDEO_0, DVB_DEVICE_AUDIO_0,
1728: -1, -1,
1729: DVB_DEVICE_DEMUX_0, DVB_DEVICE_DVR_0,
1730: -1, -1,
1.13 mocm 1731: DVB_DEVICE_OSD_0,
1.6 mocm 1732: },
1.9 mocm 1733: { INFU, INFU, INFU, INFU, INFU, 1, 1, INFU, 1 },
1734: { 1, 1, 1, 1, INFU, 1, 1, 1, 1}
1.6 mocm 1735: };
1736:
1.12 mocm 1737:
1738: static int
1739: dvb_start_feed(dvb_demux_feed_t *dvbdmxfeed)
1740: {
1741: dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
1742: struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv;
1743:
1744: if (!dvbdmx->dmx.frontend || !card)
1745: return -EINVAL;
1746:
1747: if (dvbdmxfeed->type == DMX_TYPE_TS) {
1748: if ((dvbdmxfeed->ts_type & TS_DECODER)
1749: && (dvbdmxfeed->pes_type<DMX_TS_PES_OTHER)) {
1750: switch (dvbdmx->dmx.frontend->source) {
1751: case DMX_MEMORY_FE:
1752: if (dvbdmxfeed->ts_type & TS_DECODER)
1753: if (dvbdmxfeed->pes_type<2 &&
1754: dvbdmx->pids[0]!=0xffff &&
1755: dvbdmx->pids[1]!=0xffff) {
1756:
1757: setup_ts2pes( &card->tsa,
1758: &card->tsv,
1759: dvbdmx->pids,
1760: dvbdmx->pids+1,
1761: pes_write,
1762: (void *)card);
1763:
1764: dvbdmx->playing=1;
1765: }
1766: break;
1767: default:
1768: return -EINVAL;
1769: break;
1770: }
1771: }
1772: }
1773:
1774: if (dvbdmxfeed->type == DMX_TYPE_SEC) {
1775: int i;
1776:
1777: for (i=0; i<dvbdmx->filternum; i++) {
1778: if (dvbdmx->filter[i].state!=DMX_STATE_READY)
1779: continue;
1780: if (dvbdmx->filter[i].type!=DMX_TYPE_SEC)
1781: continue;
1782: if (dvbdmx->filter[i].filter.parent!=
1783: &dvbdmxfeed->feed.sec)
1784: continue;
1785:
1786: dvbdmxfeed->feed.sec.is_filtering=1;
1787: dvbdmx->filter[i].state=DMX_STATE_GO;
1788: }
1789: }
1790:
1791: return 0;
1792: }
1793:
1794:
1795: static int
1796: dvb_stop_feed(dvb_demux_feed_t *dvbdmxfeed)
1797: {
1798: dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
1799: struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv;
1800: if (!card)
1801: return -EINVAL;
1802:
1803: if (dvbdmxfeed->type == DMX_TYPE_TS) {
1804: if ((dvbdmxfeed->ts_type & TS_DECODER)
1805: && (dvbdmxfeed->pes_type<=1)) {
1806: if (dvbdmx->playing) {
1.14 mocm 1807: free_ipack(&card->tsa);
1808: free_ipack(&card->tsv);
1.12 mocm 1809: DecoderPause(card);
1810: dvbdmx->playing=0;
1811: }
1812: }
1813:
1814: }
1815: if (dvbdmxfeed->type == DMX_TYPE_SEC) {
1816: int i;
1817:
1818: for (i=0; i<dvbdmx->filternum; i++)
1819: if (dvbdmx->filter[i].state==DMX_STATE_GO &&
1820: dvbdmx->filter[i].filter.parent==
1821: &dvbdmxfeed->feed.sec) {
1822: dvbdmx->filter[i].state=DMX_STATE_READY;
1823: }
1824:
1825: }
1826: return 0;
1827: }
1828:
1.22 mocm 1829: static uint16_t get_pid(uint8_t *pid)
1830: {
1831: uint16_t pp = 0;
1832:
1833: pp = (pid[0] & PID_MASK_HI)<<8;
1834: pp |= pid[1];
1835:
1836: return pp;
1837: }
1838:
1.12 mocm 1839:
1840: static int
1841: dvb_write_to_decoder(dvb_demux_feed_t *dvbdmxfeed, uint8_t *buf, size_t count)
1842: {
1843: dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
1844: struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv;
1845: uint16_t pid = 0;
1.18 mocm 1846: int off = 0;
1.12 mocm 1847:
1.14 mocm 1848: ipack *p;
1.12 mocm 1849:
1850: if (!card)
1851: return -EINVAL;
1852:
1853: pid = get_pid(buf+1);
1854:
1855: if (pid == *(card->tsa.pid)) p = &(card->tsa);
1856: else if (pid == *(card->tsv.pid)) p = &(card->tsv);
1857: else return 0;
1858:
1859: if (dvbdmxfeed->pes_type>1)
1860: return -1;
1861: if (!(buf[3]&0x10)) // no payload?
1862: return -1;
1863:
1864: if (count != TS_SIZE) return -1;
1865:
1.18 mocm 1866: if ( buf[3] & ADAPT_FIELD) { // adaptation field?
1867: off = buf[4] + 1;
1868: }
1869:
1870:
1871: if (pid == *(card->tsa.pid)){
1872: MDEBUG(0,"AUDIO count: %d off: %d\n",count,off);
1873: margi_write_audio(card, buf+off+4, TS_SIZE-4-off, 0);
1874: } else {
1875: MDEBUG(0,"VIDEO count: %d off: %d\n",count,off);
1876: margi_write(card, buf+off+4, TS_SIZE-4-off, 0);
1877: }
1878:
1879: // ts_to_pes( p, buf); // don't need count (=188)
1.12 mocm 1880: return 0;
1881: }
1882:
1.6 mocm 1883: int dvb_register(struct cvdv_cards *card)
1884: {
1.12 mocm 1885: int i,ret;
1.6 mocm 1886: struct dvb_device *dvbd=&card->dvb_dev;
1.12 mocm 1887:
1888: dvb_demux_t *dvbdemux = (dvb_demux_t *)&card->demux;
1.6 mocm 1889:
1890: if (card->dvb_registered)
1891: return -1;
1892: card->dvb_registered=1;
1893:
1894: card->audiostate.AVSyncState=0;
1895: card->audiostate.muteState=0;
1896: card->audiostate.playState=AUDIO_STOPPED;
1897: card->audiostate.streamSource=AUDIO_SOURCE_MEMORY;
1898: card->audiostate.channelSelect=AUDIO_STEREO;
1899: card->audiostate.bypassMode=0;
1900:
1901: card->videostate.videoBlank=0;
1902: card->videostate.playState=VIDEO_STOPPED;
1903: card->videostate.streamSource=VIDEO_SOURCE_MEMORY;
1904: card->videostate.videoFormat=VIDEO_FORMAT_4_3;
1905: card->videostate.displayFormat=VIDEO_CENTER_CUT_OUT;
1906:
1907: // init and register demuxes
1.12 mocm 1908: memcpy(card->demux_id, "demux0_0", 9);
1909: card->demux_id[7] = 1+0x30;
1910: dvbdemux->priv = (void *) card;
1911: dvbdemux->filternum = 32;
1912: dvbdemux->feednum = 32;
1913: dvbdemux->start_feed = dvb_start_feed;
1914: dvbdemux->stop_feed = dvb_stop_feed;
1915: dvbdemux->write_to_decoder = dvb_write_to_decoder;
1916:
1917: dvbdemux->dmx.vendor="CIM";
1918: dvbdemux->dmx.model="sw";
1919: dvbdemux->dmx.id=card->demux_id;
1920: dvbdemux->dmx.capabilities=(DMX_TS_FILTERING|
1921: DMX_SECTION_FILTERING|
1922: DMX_MEMORY_BASED_FILTERING);
1923:
1924: DvbDmxInit(&card->demux);
1925:
1926: card->dmxdev.filternum=32;
1927: card->dmxdev.demux=&dvbdemux->dmx;
1928: card->dmxdev.capabilities=0;
1929:
1930: DmxDevInit(&card->dmxdev);
1.6 mocm 1931:
1.12 mocm 1932: card->mem_frontend.id="mem_frontend";
1933: card->mem_frontend.vendor="memory";
1934: card->mem_frontend.model="sw";
1935: card->mem_frontend.source=DMX_MEMORY_FE;
1936: ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx,
1937: &card->mem_frontend);
1938: if (ret<0)
1939: return ret;
1940: ret=dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1941: &card->mem_frontend);
1942: if (ret<0)
1943: return ret;
1.6 mocm 1944:
1945: // init and register dvb device structure
1946: dvbd->priv=(void *) card;
1947: dvbd->open=dvbdev_open;
1948: dvbd->close=dvbdev_close;
1949: dvbd->write=dvbdev_write;
1.12 mocm 1950: dvbd->read=dvbdev_read;
1.6 mocm 1951: dvbd->ioctl=dvbdev_ioctl;
1952: dvbd->poll=dvbdev_poll;
1953: dvbd->device_type=dvbdev_device_type;
1954:
1955: for (i=0; i<DVB_DEVS_MAX; i++)
1956: card->users[i]=card->writers[i]=0;
1957:
1958: card->dvb_devs=0;
1959: card->dvb_devs=&mdvb_devs;
1.12 mocm 1960:
1.6 mocm 1961: return dvb_register_device(dvbd);
1962: }
1963:
1964: void dvb_unregister(struct cvdv_cards *card)
1965: {
1.12 mocm 1966: dvb_demux_t *dvbdemux=&card->demux;
1967:
1968: dvbdemux->dmx.close(&dvbdemux->dmx);
1969: dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &card->mem_frontend);
1970: DmxDevRelease(&card->dmxdev);
1971: DvbDmxRelease(&card->demux);
1.6 mocm 1972: dvb_unregister_device(&card->dvb_dev);
1973: }
1974: #endif