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