Annotation of margi2/cvdv.c, revision 1.14
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)
! 496: MargiSetABuffers(card, NBBUF* 128 *
1.4 mocm 497: CHANNELBUFFERSIZE);
1.1 cvs 498:
499: if (card->startingDVDV || card->startingDVDA)
500: setSCR = 1;
501:
502: if (initial) {
503: DecoderStreamReset(card);
504: //TODO stop and start channel interface
505: setSCR = 1;
506: }
507:
508: if (setSCR) {
509: SCR_base = ParseSCR(data);
510: SetSCR(card, SCR_base);
511: }
1.6 mocm 512: card->DMAABusy = 0;
1.14 ! mocm 513: while (((res = MargiPushA(card, size, data)) < size)
1.6 mocm 514: && co < 1000) {
1.1 cvs 515: data+=res;
516: size-=res;
517: co++;
1.14 ! mocm 518: MDEBUG(2,
! 519: ": DecoderWriteBlock - buffers only filled with %d instead of %d bytes\n",res, size);
1.10 mocm 520: if (card->DMAABusy){
1.1 cvs 521: interruptible_sleep_on(&card->wqA);
1.10 mocm 522: }
1.1 cvs 523: }
524:
525: if (card->startingDVDV) {
526: card->startingDVDV = 0;
1.6 mocm 527: card->startingV = 1;
1.1 cvs 528: DecoderStartDecode(card);
529: }
530: if (card->startingDVDA) {
531: card->startingDVDA = 0;
1.6 mocm 532: card->startingA = 1;
533: AudioSetPlayMode(card, MAUDIO_PLAY);
1.1 cvs 534: }
535: }
536: return 0;
537: }
538:
539:
540:
541:
542:
543: //////////////////////////////
544: // //
545: // Char Device Procedures //
546: // //
547: //////////////////////////////
1.11 mocm 548: static long margi_write(struct cvdv_cards *card, const char *data,
1.6 mocm 549: unsigned long count, int nonblock)
1.1 cvs 550: {
551: struct StreamSetup *setup = &card->setup;
1.11 mocm 552:
1.1 cvs 553: int res;
1.10 mocm 554: long int out=0;
1.12 mocm 555: int wc = 0;
1.10 mocm 556:
557: card->nonblock = nonblock;
1.1 cvs 558:
559: if (card != NULL) {
560: if (count > 0) { // Do we have data?
561: if ((res = Prepare(card)))
562: return res;
563:
564: if ((setup->streamtype != stream_ES)
1.14 ! mocm 565: && (setup->streamtype != stream_PES)){
! 566: if (!card->use_ringA)
! 567: MargiSetABuffers(card, NBBUF*
1.1 cvs 568: CHANNELBUFFERSIZE);
1.10 mocm 569:
1.12 mocm 570: while (wc < 100 &&
571: !card->nonblock && out < count){
572: wc++;
1.14 ! mocm 573: out += MargiPushA(card, count, data);
1.13 mocm 574: if (out < count){
1.10 mocm 575: interruptible_sleep_on(&card->wqA);
576: }
577: }
578: if (card->nonblock) {
1.14 ! mocm 579: out = MargiPushA(card, count, data);
1.1 cvs 580: }
1.14 ! mocm 581: }
! 582: }
! 583: return out;
! 584: } else {
! 585: MDEBUG(0,
! 586: ": Video Decoder Prepare failed: device with this minor number not found\n");
! 587: return -ENODEV; // device with this minor number not found
! 588: }
! 589: }
! 590:
! 591: static long margi_write_audio(struct cvdv_cards *card, const char *data,
! 592: unsigned long count, int nonblock)
! 593: {
! 594: struct StreamSetup *setup = &card->setup;
1.1 cvs 595:
1.14 ! mocm 596: int res;
! 597: long int out=0;
! 598: int wc = 0;
1.1 cvs 599:
1.14 ! mocm 600: card->nonblock = nonblock;
1.1 cvs 601:
1.14 ! mocm 602: if (card != NULL) {
! 603: if (count > 0) { // Do we have data?
! 604: if ((res = Prepare(card)))
! 605: return res;
! 606:
! 607: if ((setup->streamtype == stream_ES)
! 608: && (setup->streamtype == stream_PES)){
! 609: if (!card->use_ringB)
! 610: MargiSetBBuffers(card, NBBUF*
! 611: CHANNELBUFFERSIZE);
! 612:
! 613: while (wc < 100 &&
! 614: !card->nonblock && out < count){
! 615: wc++;
! 616: out += MargiPushB(card, count, data);
! 617: if (out < count){
! 618: interruptible_sleep_on(&card->wqB);
! 619: }
! 620: }
! 621: if (card->nonblock) {
! 622: out = MargiPushB(card, count, data);
! 623: }
1.1 cvs 624: }
625: }
1.10 mocm 626: return out;
1.1 cvs 627: } else {
1.14 ! mocm 628: MDEBUG(0,
1.1 cvs 629: ": Video Decoder Prepare failed: device with this minor number not found\n");
630: return -ENODEV; // device with this minor number not found
631: }
1.6 mocm 632: }
633:
1.12 mocm 634: void pes_write(uint8_t *buf, int count, void *priv)
635: {
636: struct cvdv_cards *card = (struct cvdv_cards *) priv;
1.14 ! mocm 637:
! 638: margi_write(card, buf, count, 0);
1.12 mocm 639:
640: }
641:
1.6 mocm 642:
643: static ssize_t PSwrite(struct file *file, const char *data, size_t count,
644: loff_t * offset)
645: {
646: struct cvdv_cards *card =
647: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
1.11 mocm 648: return margi_write(card, data, count, 1);
1.6 mocm 649:
1.1 cvs 650: }
651:
652: static unsigned int PSpoll(struct file *file, poll_table * table)
653: {
654: struct cvdv_cards *card =
655: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
656: if (card != NULL) {
1.9 mocm 657: poll_wait(file, &card->wqA , table);
1.14 ! mocm 658: if ( !card->rbufA.buffy || ring_write_rest(&(card->rbufA)) )
! 659: return (POLLOUT | POLLWRNORM);
! 660: else {
! 661: return 0;
! 662: }
1.1 cvs 663: } else
1.8 mocm 664: return POLLERR;
1.1 cvs 665: }
666:
1.13 mocm 667: static int
668: OSD_DrawCommand(struct cvdv_cards *card,osd_cmd_t *dc)
669: {
670:
671: switch (dc->cmd) {
672: case OSD_Close:
1.14 ! mocm 673: MDEBUG(1,": OSD Close\n");
1.13 mocm 674: return OSDClose(card);
675: case OSD_Open: // Open(x0,y0,x1,y1,BitPerPixel(2/4/8),mix(0..15))
676: return OSDOpen(card, dc->x0,
677: dc->y0, dc->x1,
678: dc->y1,
679: dc->color & 0x0F,
680: (dc->color >> 4) &
681: 0x0F);
682: case OSD_Show:
683: return OSDShow(card);
684: case OSD_Hide:
685: return OSDHide(card);
686: case OSD_Clear:
687: return OSDClear(card);
688: case OSD_Fill: // Fill(color)
689: return OSDFill(card, dc->color);
690: case OSD_SetColor: // SetColor(color,R(x0),G(y0),B(x1),opacity(y1))
691: return (OSDSetColor
692: (card, dc->color, dc->x0,
693: dc->y0, dc->x1, 0,
694: (dc->y1 != 255),
695: (dc->y1 == 0)) >= 0);
696: case OSD_SetPalette:// SetPalette(firstcolor{color},lastcolor{x0},data)
697: return OSDSetPalette(card,
698: dc->color,
699: dc->x0, (uint8_t *)
700: dc->data);
701: case OSD_SetTrans: // SetTrans(transparency{color})
702: return OSDSetTrans(card,
703: (dc->color >> 4)
704: & 0x0F);
705: case OSD_SetPixel: // SetPixel(x0,y0,color)
706: return OSDSetPixel(card, dc->x0,
707: dc->y0,
708: dc->color);
709: case OSD_GetPixel: // GetPixel(x0,y0);
710: return OSDGetPixel(card, dc->x0,
711: dc->y0);
712: case OSD_SetRow: // SetRow(x0,y0,x1,(uint8_t*)data)
713: return OSDSetRow(card, dc->x0,
714: dc->y0, dc->x1,
715: (uint8_t *) dc->data);
716: case OSD_SetBlock: // SetBlock(x0,y0,x1,y1,(uint8_t*)data)
717: return OSDSetBlock(card, dc->x0,
718: dc->y0, dc->x1,
719: dc->y1,
720: dc->color,
721: (uint8_t *)
722: dc->data);
723: case OSD_FillRow: // FillRow(x0,y0,x1,color)
724: return OSDFillRow(card, dc->x0,
725: dc->y0, dc->x1,
726: dc->color);
727: case OSD_FillBlock: // FillRow(x0,y0,x1,y1,color)
728: return OSDFillBlock(card, dc->x0,
729: dc->y0, dc->x1,
730: dc->y1,
731: dc->color);
732: case OSD_Line: // Line(x0,y0,x1,y1,color);
733: return OSDLine(card, dc->x0,
734: dc->y0, dc->x1,
735: dc->y1, dc->color);
736: case OSD_Query: // Query(x0,y0,x1,y1,aspect(color:11)
737: return OSDQuery(card, &dc->x0,
738: &dc->y0, &dc->x1,
739: &dc->y1,
740: &dc->color);
741: case OSD_Test:
742: return OSDTest(card);
743: default:
744: return -EINVAL;
745: }
746: }
747:
1.6 mocm 748:
1.1 cvs 749: static int PSioctl(struct inode *inode, struct file *file,
750: unsigned int cmd, unsigned long arg)
751: {
752: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
1.13 mocm 753: osd_cmd_t *dc;
1.1 cvs 754: struct decodercmd *command;
1.12 mocm 755: uint16_t attr;
1.10 mocm 756:
1.1 cvs 757: if (card != NULL) {
758: if (_IOC_TYPE(cmd) == CVDV_IOCTL_MAGIC)
759: switch (_IOC_NR(cmd)) {
760: case IOCTL_DRAW: // Drawing commands
1.13 mocm 761: dc = (osd_cmd_t *) arg;
762: return OSD_DrawCommand(card,dc);
763: break;
1.1 cvs 764: case IOCTL_DECODER:
765: command = (struct decodercmd *) arg;
766: switch (command->cmd) {
1.10 mocm 767:
768: case Decoder_CSS:
1.1 cvs 769: /*
770: return DecoderCSS(card,
771: command->param1,
772: command->data1);
773: */
1.10 mocm 774: break;
775:
1.1 cvs 776: case Decoder_Set_Videosystem:
1.14 ! mocm 777: MDEBUG(1,": -- Decoder_Set_Videosystem\n");
1.1 cvs 778: card->videomode =
779: (videosystem) command->param1;
780: SetVideoSystem(card);
781: return 0;
1.10 mocm 782: break;
783:
1.1 cvs 784: case Decoder_Set_Streamtype:
1.14 ! mocm 785: MDEBUG(1,": -- Decoder_Set_Streamtype\n");
1.1 cvs 786: card->setup.streamtype =
787: (stream_type) command->param1;
788: return 0;
1.10 mocm 789: break;
790:
1.1 cvs 791: case Decoder_Set_Audiotype:
1.14 ! mocm 792: MDEBUG(1,": -- Decoder_Set_Audiotype\n");
1.1 cvs 793: card->setup.audioselect =
794: (audio_type) command->param1;
795: DecoderPrepareAudio(card);
796: return 0;
1.10 mocm 797: break;
798:
1.1 cvs 799: case Decoder_Set_VideoStreamID:
1.14 ! mocm 800: MDEBUG(1,": -- Decoder_Set_VideoStreamID\n");
1.1 cvs 801: card->setup.videoID =
802: command->param1;
803: DecoderPrepareVideo(card);
804: return 0;
1.10 mocm 805: break;
806:
1.1 cvs 807: case Decoder_Set_AudioStreamID:
1.14 ! mocm 808: MDEBUG(1,": -- Decoder_Set_AudioStreamID 0x%02X 0x%02X\n",
! 809: command->param1,command->param2);
1.1 cvs 810: card->setup.audioID =
811: command->param1;
812: card->setup.audioIDext =
813: command->param2;
814: attr = card->lastaattr;
815: DecoderSelectAudioID(card);
816: card->lastaattr = attr;
817: return 0;
1.10 mocm 818: break;
819:
1.1 cvs 820: case Decoder_Still_Put:
821: return DecoderShowStill(card,
822: command->
823: param1,
824: command->
825: param2,
826: command->
827: data1,
828: command->
829: data2);
1.10 mocm 830: break;
831:
1.1 cvs 832: case Decoder_Still_Get:
833: return DecoderGetStill(card,
834: &command->
835: param1,
836: &command->
837: param2,
838: command->
839: data1,
840: command->
841: data2);
1.10 mocm 842: break;
843:
1.1 cvs 844: case Decoder_Pause: // pause{param1} 0=run 1=pause 2=toggle
845: if (command->param1 == 2) {
846: if (card->paused)
847: DecoderUnPause
848: (card);
849: else
850: DecoderPause(card);
851: } else {
852: if (!command->param1)
853: DecoderUnPause
854: (card);
855: else
856: DecoderPause(card);
857: }
858: return 0;
1.10 mocm 859:
860: /* Too buggy
861: case Decoder_FFWD: // pause{param1} =normal 1=ffwd 2=toggle
862: if (command->param1 == 2) {
863: if (card->videoffwd)
864: card->videoffwd = 0;
865: else
1.13 mocm 866: card->videoffwd = 3;
1.10 mocm 867: } else {
868: if (!command->param1)
869: card->videoffwd = 0;
870: else
1.13 mocm 871: card->videoffwd = 3;
1.10 mocm 872: }
873: return 0;
874:
875: case Decoder_Slow: // pause{param1} =normal 1=slow 2=toggle
876: if (command->param1 == 2) {
877: if (card->videoslow)
878: card->videoslow = 0;
879: else
880: card->videoslow = 4;
881: } else {
882: if (!command->param1)
883: card->videoslow = 0;
884: else
885: card->videoslow = 4;
886: }
887: return 0;
888: */
1.1 cvs 889: case Decoder_Highlight: // active{param1}, color information(SL_COLI or AC_COLI){data1[4]}, button position(BTN_POSI){data2[6]}
890: return DecoderHighlight(card,
891: command->
892: param1,
893: command->
894: data1,
895: command->
896: data2);
897: case Decoder_SPU: // stream{param1}, active{param2}
898: return DecoderSPUStream(card,
899: command->
900: param1,
901: command->
902: param2);
903: case Decoder_SPU_Palette: // length{param1}, palette{data1}
904: return DecoderSPUPalette(card,
905: command->
906: param1,
907: command->
908: data1);
909: case Decoder_GetNavi: // data1 will be filled with PCI or DSI pack, and 1024 will be returned
910: return DecoderGetNavi(card,
911: command->
912: data1);
913: case Decoder_SetKaraoke: // Vocal1{param1}, Vocal2{param2}, Melody{param3}
914: return DecoderKaraoke(card,
915: command->
916: param1,
917: command->
918: param2,
919: command->
920: param3);
921: case Decoder_Set_Videoattribute:
1.14 ! mocm 922: MDEBUG(1,": -- Decoder_Set_Videoattribute\n");
1.1 cvs 923: if (!card->ChannelBuffersAllocated) {
924: DecoderStreamReset(card);
925: MargiFlush(card);
926:
927: card->setup.streamtype =
928: stream_DVD;
929: card->setup.videoID = 0;
930: DecoderPrepareVideo(card);
931: DecoderPreparePS(card, 0,
932: 0, 2, 2,
933: 3, 1);
934: }
935:
936: SetVideoAttr(card,
937: command->param1);
1.6 mocm 938: card->startingDVDV = 1;
939: // tell the card to start playing as soon as ES-buffers are sufficiently full
1.1 cvs 940: return 0;
941: case Decoder_Set_Audioattribute:
1.14 ! mocm 942: MDEBUG(1,": -- Decoder_Set_Audioattribute\n");
1.1 cvs 943: SetAudioAttr(card,
944: command->param1);
945: card->startingDVDA =
946: ((card->setup.audioselect !=
947: audio_none)
948: && (card->setup.audioselect != audio_disable)); // tell the card to start playing as soon as ES-buffers are sufficiently full
949: return 0;
950: case Decoder_WriteBlock: // DVD-Sector{data1}, sectorsize{param1{2048}}, initialsector{param2{bool}}, set_SCR{param3}
951: return DecoderWriteBlock(card,
952: command->
953: data1,
954: command->
955: param1,
956: command->
957: param2,
958: command->
959: param3);
960: default:
961: return -EINVAL;
962: }
963: default:
964: return -EINVAL;
965: } else
966: return -EINVAL;
967: } else {
1.14 ! mocm 968: MDEBUG(0,
1.1 cvs 969: ": Video Decoder Prepare failed: device with this minor number not found\n");
970: return -ENODEV; // device with this minor number not found
971: }
972: }
973:
1.6 mocm 974:
1.1 cvs 975: static int PSmmap(struct file *file, struct vm_area_struct *vm)
976: {
977: return -ENODEV;
978: }
979:
1.6 mocm 980:
981:
1.11 mocm 982: static int margi_open(struct cvdv_cards *card, int flags)
1.1 cvs 983: {
1.6 mocm 984: int closed;
1.1 cvs 985: if (card != NULL) {
1.14 ! mocm 986: MDEBUG(1, ": -- open \n");
1.1 cvs 987: CloseCard(card);
1.5 mocm 988: OSDClose(card);
1.6 mocm 989: #ifdef NOINT
990: card->timer.function = Timerfunction;
991: card->timer.data=(unsigned long) card;
992: card->timer.expires=jiffies+1;
993: add_timer(&card->timer);
994: #endif
995:
996: if (card->open)
1.14 ! mocm 997: MDEBUG(0,": PSopen - already open\n");
1.1 cvs 998: closed = 1;
1.6 mocm 999: if (card->open)
1000: closed = 0;
1.1 cvs 1001: if (closed) { // first open() for this card?
1002: MargiFreeBuffers(card);
1003: VideoSetBackground(card, 1, 0, 0, 0); // black
1004: }
1.6 mocm 1005: card->open++;
1.11 mocm 1006: MOD_INC_USE_COUNT;
1.1 cvs 1007: return 0;
1008: } else {
1.14 ! mocm 1009: MDEBUG(0,
1.1 cvs 1010: ": Video Decoder Prepare failed: device with this minor number not found\n");
1011: return -ENODEV; // device with this minor number not found
1012: }
1.6 mocm 1013:
1.1 cvs 1014: }
1015:
1.6 mocm 1016:
1017: static int PSopen(struct inode *inode, struct file *file)
1.1 cvs 1018: {
1.11 mocm 1019: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV];
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
LinuxTV legacy CVS <linuxtv.org/cvs>