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