Annotation of margi2/cvdv.c, revision 1.10
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
44: u16 rnd_seed;
45: u16 rnd(u16 range)
46: { // returns random 0..(range-1) range<=872
47: u32 b = 75 * (rnd_seed + 1) - 1;
48: rnd_seed = (u16) (b & 0xFFFF);
49: return ((b * range) / 0xFFFF) - ((b / 0xFFFF) * range);
50: }
51: void rnd_omize(void)
52: {
53: rnd_seed = (u16) jiffies;
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;
106: u8 b;
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:
219: int SetVideoAttr(struct cvdv_cards *card, u16 vattr)
220: {
221: u8 video_compression_mode;
222: u8 tv_system;
223: u8 aspect_ratio;
224: u8 display_mode;
225: u8 line_21_switch_1;
226: u8 line_21_switch_2;
227: u8 source_picture_resolution;
228: u8 source_picture_letterboxed;
229: u8 reserved;
230: u8 film_camera_mode;
231: u16 hsize, vsize;
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:
268: int SetAudioAttr(struct cvdv_cards *card, u16 aattr)
269: {
270: u8 audio_coding_mode;
271: u8 multichannel_extension;
272: u8 audio_type;
273: u8 audio_application_mode;
274: u8 quantization_drc;
275: u8 fs;
276: u8 reserved;
277: u8 num_audio_ch;
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:
407: int SetSCRstart(struct cvdv_cards *card, u32 SCR_base)
408: {
409: u32 SCR_compare;
410: u32 SCR_compareA;
411: u32 SCR_compareV;
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 =
446: SCR_base | ((u32) DecoderReadByte(card, 0x00A) << 8);
447: SCR_base =
448: SCR_base | ((u32) DecoderReadByte(card, 0x00B) << 16);
449: SCR_base =
450: SCR_base | ((u32) DecoderReadByte(card, 0x00C) << 24);
451: SCR_compareA = DecoderReadByte(card, 0x014);
452: SCR_compareA =
453: SCR_compareA | ((u32) DecoderReadByte(card, 0x015) <<
454: 8);
455: SCR_compareA =
456: SCR_compareA | ((u32) DecoderReadByte(card, 0x016) <<
457: 16);
458: SCR_compareA =
459: SCR_compareA | ((u32) DecoderReadByte(card, 0x017) <<
460: 24);
461: SCR_compareV = DecoderReadByte(card, 0x00D);
462: SCR_compareV =
463: SCR_compareV | ((u32) DecoderReadByte(card, 0x00E) <<
464: 8);
465: SCR_compareV =
466: SCR_compareV | ((u32) DecoderReadByte(card, 0x00F) <<
467: 16);
468: SCR_compareV =
469: SCR_compareV | ((u32) DecoderReadByte(card, 0x010) <<
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:
481: int DecoderWriteBlock(struct cvdv_cards *card, u8 * data, int size,
482: int initial, int setSCR)
483: {
484: //int a,v,as,vs,ap,vp;
485: int res;
486: u32 SCR_base;
487: int co = 0;
488: // u32 SCR_compare;
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.6 mocm 549: static long margi_write(struct video_device *dev, const char *data,
550: unsigned long count, int nonblock)
1.1 cvs 551: {
1.6 mocm 552: struct cvdv_cards *card = (struct cvdv_cards*)dev;
553:
1.1 cvs 554: struct StreamSetup *setup = &card->setup;
555: // int i;
556: // int laststart=-1;
557: // int B3=0, B5=0, C0=0, E0=0, BD=0, BF=0;
558: int res;
1.6 mocm 559: int channel=0;
1.10 ! mocm 560: long int out=0;
! 561:
! 562: card->nonblock = nonblock;
1.1 cvs 563:
564: if (card != NULL) {
565: if (count > 0) { // Do we have data?
566: if ((res = Prepare(card)))
567: return res;
568:
569: if ((setup->streamtype != stream_ES)
570: && (setup->streamtype != stream_PES))
571: channel = 0;
572: // only ES and PES come in separate streams
573: switch (channel) {
574: case 0:
575: if (!card->use_ring)
576: MargiSetBuffers(card, NBBUF*
577: CHANNELBUFFERSIZE);
1.10 ! mocm 578:
! 579: while (!card->nonblock && out < count){
! 580: out += MargiPush(card, count, data);
! 581: if (out < count || card->DMAABusy){
! 582: interruptible_sleep_on(&card->wqA);
! 583: }
! 584: }
! 585: if (card->nonblock) {
! 586: out = MargiPush(card, count, data);
! 587: if (card->DMAABusy){
! 588: interruptible_sleep_on(&card->wqA);
! 589: }
! 590:
1.1 cvs 591: }
592: break;
593:
594:
595: case 1:
596:
597: // todo
598: break;
599: }
600: }
1.10 ! mocm 601: return out;
1.1 cvs 602: } else {
603: printk(KERN_ERR LOGNAME
604: ": Video Decoder Prepare failed: device with this minor number not found\n");
605: return -ENODEV; // device with this minor number not found
606: }
1.6 mocm 607: }
608:
609:
610: static ssize_t PSwrite(struct file *file, const char *data, size_t count,
611: loff_t * offset)
612: {
613: struct cvdv_cards *card =
614: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
615: return margi_write((struct video_device *)card, data, count, 0);
616:
1.1 cvs 617: }
618:
619: static unsigned int PSpoll(struct file *file, poll_table * table)
620: {
621: struct cvdv_cards *card =
622: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
623: if (card != NULL) {
1.9 mocm 624: poll_wait(file, &card->wqA , table);
1.10 ! mocm 625: if ( ring_write_rest(&(card->rbuf)) &&
1.8 mocm 626: card->videostate.playState==VIDEO_PLAYING)
627: return POLLOUT | POLLWRNORM;
628: else return 0;
1.1 cvs 629: } else
1.8 mocm 630: return POLLERR;
1.1 cvs 631: }
632:
1.6 mocm 633:
634: static int margi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
635: {
636: // struct cvdv_cards *card = (struct cvdv_cards*)dev;
637: return 0;
638: }
639:
640:
1.1 cvs 641: static int PSioctl(struct inode *inode, struct file *file,
642: unsigned int cmd, unsigned long arg)
643: {
644: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
645: struct drawcmd *dc;
646: struct decodercmd *command;
647: u16 attr;
1.10 ! mocm 648:
1.1 cvs 649: if (card != NULL) {
650: if (_IOC_TYPE(cmd) == CVDV_IOCTL_MAGIC)
651: switch (_IOC_NR(cmd)) {
652: case IOCTL_DRAW: // Drawing commands
653: dc = (struct drawcmd *) arg;
654: switch (dc->cmd) {
655: case OSD_Close:
656: printk(KERN_DEBUG LOGNAME
657: ": OSD Close\n");
658: return OSDClose(card);
659: case OSD_Open: // Open(x0,y0,x1,y1,BitPerPixel(2/4/8),mix(0..15))
660: return OSDOpen(card, dc->x0,
661: dc->y0, dc->x1,
662: dc->y1,
663: dc->color & 0x0F,
664: (dc->color >> 4) &
665: 0x0F);
666: case OSD_Show:
667: return OSDShow(card);
668: case OSD_Hide:
669: return OSDHide(card);
670: case OSD_Clear:
671: return OSDClear(card);
672: case OSD_Fill: // Fill(color)
673: return OSDFill(card, dc->color);
674: case OSD_SetColor: // SetColor(color,R(x0),G(y0),B(x1),opacity(y1))
675: //printk(KERN_DEBUG LOGNAME ": OSD SetColor(%d,%d,%d,%d,%d)\n",
676: //dc->color,dc->x0,dc->y0,dc->x1,dc->y1);
677: return (OSDSetColor
678: (card, dc->color, dc->x0,
679: dc->y0, dc->x1, 0,
680: (dc->y1 != 255),
681: (dc->y1 == 0)) >= 0);
682: case OSD_SetPalette: // SetPalette(firstcolor{color},lastcolor{x0},data)
683: return OSDSetPalette(card,
684: dc->color,
685: dc->x0, (u8 *)
686: dc->data);
687: case OSD_SetTrans: // SetTrans(transparency{color})
688: return OSDSetTrans(card,
689: (dc->color >> 4)
690: & 0x0F);
691: case OSD_SetPixel: // SetPixel(x0,y0,color)
692: return OSDSetPixel(card, dc->x0,
693: dc->y0,
694: dc->color);
695: case OSD_GetPixel: // GetPixel(x0,y0);
696: return OSDGetPixel(card, dc->x0,
697: dc->y0);
698: case OSD_SetRow: // SetRow(x0,y0,x1,(u8*)data)
699: return OSDSetRow(card, dc->x0,
700: dc->y0, dc->x1,
701: (u8 *) dc->data);
702: case OSD_SetBlock: // SetBlock(x0,y0,x1,y1,(u8*)data)
703: return OSDSetBlock(card, dc->x0,
704: dc->y0, dc->x1,
705: dc->y1,
706: dc->color,
707: (u8 *)
708: dc->data);
709: case OSD_FillRow: // FillRow(x0,y0,x1,color)
710: return OSDFillRow(card, dc->x0,
711: dc->y0, dc->x1,
712: dc->color);
713: case OSD_FillBlock: // FillRow(x0,y0,x1,y1,color)
714: return OSDFillBlock(card, dc->x0,
715: dc->y0, dc->x1,
716: dc->y1,
717: dc->color);
718: case OSD_Line: // Line(x0,y0,x1,y1,color);
719: return OSDLine(card, dc->x0,
720: dc->y0, dc->x1,
721: dc->y1, dc->color);
722: case OSD_Query: // Query(x0,y0,x1,y1,aspect(color:11)
723: return OSDQuery(card, &dc->x0,
724: &dc->y0, &dc->x1,
725: &dc->y1,
726: &dc->color);
727: case OSD_Test:
728: return OSDTest(card);
729: default:
730: return -EINVAL;
731: }
732: case IOCTL_DECODER:
733: command = (struct decodercmd *) arg;
1.10 ! mocm 734: printk(KERN_DEBUG LOGNAME ":IOCTL: _IOC_TYPE:%d IOC_NR:%d cmd:%d\n",
! 735: _IOC_TYPE(cmd),_IOC_NR(cmd),command->cmd);
1.1 cvs 736: switch (command->cmd) {
1.10 ! mocm 737:
! 738: case Decoder_CSS:
1.1 cvs 739: /*
740: return DecoderCSS(card,
741: command->param1,
742: command->data1);
743: */
1.10 ! mocm 744: break;
! 745:
1.1 cvs 746: case Decoder_Set_Videosystem:
747: printk(KERN_DEBUG LOGNAME
748: ": -- Decoder_Set_Videosystem\n");
749: card->videomode =
750: (videosystem) command->param1;
751: SetVideoSystem(card);
752: return 0;
1.10 ! mocm 753: break;
! 754:
1.1 cvs 755: case Decoder_Set_Streamtype:
756: printk(KERN_DEBUG LOGNAME
757: ": -- Decoder_Set_Streamtype\n");
758: card->setup.streamtype =
759: (stream_type) command->param1;
760: return 0;
1.10 ! mocm 761: break;
! 762:
1.1 cvs 763: case Decoder_Set_Audiotype:
764: printk(KERN_DEBUG LOGNAME
765: ": -- Decoder_Set_Audiotype\n");
766: card->setup.audioselect =
767: (audio_type) command->param1;
768: DecoderPrepareAudio(card);
769: return 0;
1.10 ! mocm 770: break;
! 771:
1.1 cvs 772: case Decoder_Set_VideoStreamID:
773: printk(KERN_DEBUG LOGNAME
774: ": -- Decoder_Set_VideoStreamID\n");
775: card->setup.videoID =
776: command->param1;
777: DecoderPrepareVideo(card);
778: return 0;
1.10 ! mocm 779: break;
! 780:
1.1 cvs 781: case Decoder_Set_AudioStreamID:
782: printk(KERN_DEBUG LOGNAME
783: ": -- Decoder_Set_AudioStreamID 0x%02X 0x%02X\n",command->param1,command->param2);
784: card->setup.audioID =
785: command->param1;
786: card->setup.audioIDext =
787: command->param2;
788: attr = card->lastaattr;
789: DecoderSelectAudioID(card);
790: card->lastaattr = attr;
791: return 0;
1.10 ! mocm 792: break;
! 793:
1.1 cvs 794: case Decoder_Still_Put:
795: return DecoderShowStill(card,
796: command->
797: param1,
798: command->
799: param2,
800: command->
801: data1,
802: command->
803: data2);
1.10 ! mocm 804: break;
! 805:
1.1 cvs 806: case Decoder_Still_Get:
807: return DecoderGetStill(card,
808: &command->
809: param1,
810: &command->
811: param2,
812: command->
813: data1,
814: command->
815: data2);
1.10 ! mocm 816: break;
! 817:
1.1 cvs 818: case Decoder_Pause: // pause{param1} 0=run 1=pause 2=toggle
819: if (command->param1 == 2) {
820: if (card->paused)
821: DecoderUnPause
822: (card);
823: else
824: DecoderPause(card);
825: } else {
826: if (!command->param1)
827: DecoderUnPause
828: (card);
829: else
830: DecoderPause(card);
831: }
832: return 0;
1.10 ! mocm 833:
! 834: /* Too buggy
! 835: case Decoder_FFWD: // pause{param1} =normal 1=ffwd 2=toggle
! 836: if (command->param1 == 2) {
! 837: if (card->videoffwd)
! 838: card->videoffwd = 0;
! 839: else
! 840: card->videoffwd = 2;
! 841: } else {
! 842: if (!command->param1)
! 843: card->videoffwd = 0;
! 844: else
! 845: card->videoffwd = 2;
! 846: }
! 847: return 0;
! 848:
! 849: case Decoder_Slow: // pause{param1} =normal 1=slow 2=toggle
! 850: if (command->param1 == 2) {
! 851: if (card->videoslow)
! 852: card->videoslow = 0;
! 853: else
! 854: card->videoslow = 4;
! 855: } else {
! 856: if (!command->param1)
! 857: card->videoslow = 0;
! 858: else
! 859: card->videoslow = 4;
! 860: }
! 861: return 0;
! 862: */
1.1 cvs 863: case Decoder_Highlight: // active{param1}, color information(SL_COLI or AC_COLI){data1[4]}, button position(BTN_POSI){data2[6]}
864: return DecoderHighlight(card,
865: command->
866: param1,
867: command->
868: data1,
869: command->
870: data2);
871: case Decoder_SPU: // stream{param1}, active{param2}
872: return DecoderSPUStream(card,
873: command->
874: param1,
875: command->
876: param2);
877: case Decoder_SPU_Palette: // length{param1}, palette{data1}
878: return DecoderSPUPalette(card,
879: command->
880: param1,
881: command->
882: data1);
883: case Decoder_GetNavi: // data1 will be filled with PCI or DSI pack, and 1024 will be returned
884: return DecoderGetNavi(card,
885: command->
886: data1);
887: case Decoder_SetKaraoke: // Vocal1{param1}, Vocal2{param2}, Melody{param3}
888: return DecoderKaraoke(card,
889: command->
890: param1,
891: command->
892: param2,
893: command->
894: param3);
895: case Decoder_Set_Videoattribute:
896: printk(KERN_DEBUG LOGNAME
897: ": -- Decoder_Set_Videoattribute\n");
898: if (!card->ChannelBuffersAllocated) {
899: DecoderStreamReset(card);
900: MargiFlush(card);
901:
902: card->setup.streamtype =
903: stream_DVD;
904: card->setup.videoID = 0;
905: DecoderPrepareVideo(card);
906: DecoderPreparePS(card, 0,
907: 0, 2, 2,
908: 3, 1);
909: }
910:
911: SetVideoAttr(card,
912: command->param1);
1.6 mocm 913: card->startingDVDV = 1;
914: // tell the card to start playing as soon as ES-buffers are sufficiently full
1.1 cvs 915: return 0;
916: case Decoder_Set_Audioattribute:
917: printk(KERN_DEBUG LOGNAME
918: ": -- Decoder_Set_Audioattribute\n");
919: SetAudioAttr(card,
920: command->param1);
921: card->startingDVDA =
922: ((card->setup.audioselect !=
923: audio_none)
924: && (card->setup.audioselect != audio_disable)); // tell the card to start playing as soon as ES-buffers are sufficiently full
925: return 0;
926: case Decoder_WriteBlock: // DVD-Sector{data1}, sectorsize{param1{2048}}, initialsector{param2{bool}}, set_SCR{param3}
927: return DecoderWriteBlock(card,
928: command->
929: data1,
930: command->
931: param1,
932: command->
933: param2,
934: command->
935: param3);
936: default:
937: return -EINVAL;
938: }
939: default:
940: return -EINVAL;
941: } else
942: return -EINVAL;
943: } else {
944: printk(KERN_ERR LOGNAME
945: ": Video Decoder Prepare failed: device with this minor number not found\n");
946: return -ENODEV; // device with this minor number not found
947: }
948: }
949:
1.6 mocm 950:
1.1 cvs 951: static int PSmmap(struct file *file, struct vm_area_struct *vm)
952: {
953: return -ENODEV;
954: }
955:
1.6 mocm 956:
957:
958: static int margi_open(struct video_device *dev, int flags)
1.1 cvs 959: {
1.6 mocm 960: struct cvdv_cards *card = (struct cvdv_cards*)dev;
961:
962: int closed;
1.1 cvs 963: if (card != NULL) {
1.10 ! mocm 964: printk(KERN_DEBUG LOGNAME ": -- open \n");
1.1 cvs 965: CloseCard(card);
1.5 mocm 966: OSDClose(card);
1.6 mocm 967: #ifdef NOINT
968: card->timer.function = Timerfunction;
969: card->timer.data=(unsigned long) card;
970: card->timer.expires=jiffies+1;
971: add_timer(&card->timer);
972: #endif
973:
974: if (card->open)
1.1 cvs 975: printk(KERN_DEBUG LOGNAME
1.6 mocm 976: ": PSopen - already open\n");
1.1 cvs 977: closed = 1;
1.6 mocm 978: if (card->open)
979: closed = 0;
1.1 cvs 980: if (closed) { // first open() for this card?
981: MargiFreeBuffers(card);
982: VideoSetBackground(card, 1, 0, 0, 0); // black
983: }
1.6 mocm 984: card->open++;
1.1 cvs 985: //MOD_INC_USE_COUNT;
986: return 0;
987: } else {
988: printk(KERN_ERR LOGNAME
989: ": Video Decoder Prepare failed: device with this minor number not found\n");
990: return -ENODEV; // device with this minor number not found
991: }
1.6 mocm 992:
1.1 cvs 993: }
994:
1.6 mocm 995:
996: static int PSopen(struct inode *inode, struct file *file)
1.1 cvs 997: {
998: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
1.10 ! mocm 999: return margi_open((struct video_device *) card,1);
1.6 mocm 1000: }
1001:
1002:
1003: static int all_margi_close(struct video_device *dev)
1004: {
1005: struct cvdv_cards *card = (struct cvdv_cards*)dev;
1006:
1007: int closed;
1.4 mocm 1008: int count;
1009: count = ring_read_rest(&(card->rbuf));
1010: if (count > 0 ) card->DMAABusy = 1;
1.1 cvs 1011: if (card != NULL) {
1012: printk(KERN_DEBUG LOGNAME ": -- PSrelease\n");
1.6 mocm 1013: if (!card->open)
1.1 cvs 1014: printk(KERN_DEBUG LOGNAME
1.6 mocm 1015: ": PSrelease - not open\n");
1016: card->open--;
1.4 mocm 1017:
1.1 cvs 1018: //MOD_DEC_USE_COUNT;
1.6 mocm 1019: if (!card->open) {
1.1 cvs 1020: closed = 1;
1021: if (closed) { // last close() for this card?
1022: printk(KERN_DEBUG LOGNAME
1023: ": PSrelease - last close\n");
1024: // flush remaining data
1025:
1026: card->channelApos = 0;
1027: card->channelBpos = 0;
1028:
1.4 mocm 1029: if ((card->DMAABusy || card->DMABBusy
1030: || count >1000 ) &&
1031: (card->intdecodestatus)) {
1032: // ongoing DMA?
1.1 cvs 1033: printk(KERN_DEBUG LOGNAME
1034: ": Delayed closing: A=%d B=%d\n",
1035: card->DMAABusy,
1036: card->DMABBusy);
1037: card->closing = 1; // then delay closing until DMA finished,
1038: } else { // otherwise
1039: CloseCard(card); // close immediately
1.4 mocm 1040: printk(KERN_DEBUG LOGNAME
1041: ": closing now\n");
1.1 cvs 1042: }
1043: }
1044: }
1045: return 0;
1046: } else {
1047: printk(KERN_ERR LOGNAME
1048: ": Video Decoder Prepare failed: device with this minor number not found\n");
1049: return -ENODEV; // device with this minor number not found
1050: }
1.6 mocm 1051:
1052: }
1053:
1054:
1055: static void margi_close(struct video_device *dev)
1056: {
1057: all_margi_close(dev);
1058: }
1059:
1060: static int PSrelease(struct inode *inode, struct file *file)
1061: {
1062: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
1063: return all_margi_close((struct video_device *)card);
1.1 cvs 1064: }
1065:
1066: //////////////////////////
1067: // //
1068: // Char Device Hookup //
1069: // //
1070: //////////////////////////
1071:
1072: // Hookups for a write-only device, that accepts MPEG-2 Program Stream
1073: struct file_operations cvdv_fileops = {
1074: write: PSwrite,
1075: poll: PSpoll,
1076: ioctl: PSioctl,
1077: mmap: PSmmap,
1078: open: PSopen,
1079: release: PSrelease,
1080: };
1.6 mocm 1081:
1082: static int margi_init_done(struct video_device *dev)
1083: {
1084: printk(KERN_ERR "margi: margi_init_done called\n");
1085: return 0;
1086: }
1087:
1088: static int margi_mmap(struct video_device *dev,
1089: const char *adr, unsigned long size)
1090: {
1091: return 0;
1092: }
1093:
1094: static struct video_device margi_template = {
1095: name: "Margi MPEG2 Decoder",
1.8 mocm 1096: type: (VID_TYPE_MPEG_DECODER|VID_TYPE_OVERLAY),
1.6 mocm 1097: open: margi_open,
1098: close: margi_close,
1099: write: margi_write,
1100: ioctl: margi_ioctl,
1101: mmap: margi_mmap,
1102: initialize: margi_init_done,
1103: };
1104:
1105:
1106:
1107: #ifdef DVB
1108:
1109: static inline int
1110: num2type(struct cvdv_cards *card, int num)
1111: {
1112: if (!card->dvb_devs)
1113: return -2;
1114: if (num>=card->dvb_devs->num)
1115: return -2;
1116: return card->dvb_devs->tab[num];
1117: }
1118:
1119: static int
1120: dvbdev_open(struct dvb_device *dvbdev, int num,
1121: struct inode *inode, struct file *file)
1122: {
1123: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1124: int type=num2type(card, num);
1125: int ret=0;
1126:
1127: if (type<0)
1128: return -EINVAL;
1129:
1130: if (card->users[num] >= card->dvb_devs->max_users[num])
1131: return -EBUSY;
1132:
1133: if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
1134: if (card->writers[num] >= card->dvb_devs->max_writers[num])
1135: return -EBUSY;
1136:
1137: switch (type) {
1138: case DVB_DEVICE_VIDEO_0:
1139: card->video_blank=true;
1.9 mocm 1140: card->audiostate.AVSyncState=true;
1.6 mocm 1141: card->videostate.streamSource=VIDEO_SOURCE_DEMUX;
1.7 mocm 1142: margi_open((struct video_device *) card, 0);
1143: break;
1.6 mocm 1144:
1145: case DVB_DEVICE_AUDIO_0:
1146: card->audiostate.streamSource=AUDIO_SOURCE_DEMUX;
1147: break;
1148:
1149: case DVB_DEVICE_DEMUX_0:
1150: if ((file->f_flags&O_ACCMODE)!=O_RDWR)
1151: return -EINVAL;
1152: ret=DmxDevFilterAlloc(&card->dmxdev, file);
1153: break;
1154: case DVB_DEVICE_DVR_0:
1155: ret=DmxDevDVROpen(&card->dmxdev, file);
1156: break;
1.9 mocm 1157:
1158: case DVB_DEVICE_OSD_0:
1159: break;
1160: default:
1.6 mocm 1161: return -EINVAL;
1162: }
1163: if (ret<0)
1164: return ret;
1165: if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
1166: card->writers[num]++;
1167: card->users[num]++;
1168: return ret;
1169: }
1170:
1171: static int
1172: dvbdev_close(struct dvb_device *dvbdev, int num,
1173: struct inode *inode, struct file *file)
1174: {
1175: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1176: int type=num2type(card, num);
1177: int ret=0;
1178:
1179: if (type<0)
1180: return -EINVAL;
1181:
1182: switch (type) {
1183: case DVB_DEVICE_VIDEO_0:
1184: all_margi_close((struct video_device *)card);
1185: break;
1186:
1187: case DVB_DEVICE_AUDIO_0:
1188: all_margi_close((struct video_device *)card);
1189: break;
1190:
1191: case DVB_DEVICE_DEMUX_0:
1192: ret=DmxDevFilterFree(&card->dmxdev, file);
1193: break;
1194:
1195: case DVB_DEVICE_DVR_0:
1196: ret=DmxDevDVRClose(&card->dmxdev, file);
1197: break;
1.9 mocm 1198: case DVB_DEVICE_OSD_0:
1199: break;
1200: default:
1.6 mocm 1201: return -EINVAL;
1202: }
1203: if (ret<0)
1204: return ret;
1205: if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
1206: card->writers[num]--;
1207: card->users[num]--;
1208: return ret;
1209: }
1210:
1211: static ssize_t
1212: dvbdev_write(struct dvb_device *dvbdev, int num,
1213: struct file *file,
1214: const char *buf, size_t count, loff_t *ppos)
1215: {
1216: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1217: int type=num2type(card, num);
1218:
1219: switch (type) {
1220: case DVB_DEVICE_VIDEO_0:
1221: if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY)
1222: return -EPERM;
1223: return margi_write((struct video_device *)card, buf, count,
1224: file->f_flags&O_NONBLOCK);
1225:
1226: case DVB_DEVICE_AUDIO_0:
1227: if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
1228: return -EPERM;
1229: return count;
1230:
1231: case DVB_DEVICE_DVR_0:
1232: return DmxDevDVRWrite(&card->dmxdev, file, buf, count, ppos);
1233: default:
1234: return -EOPNOTSUPP;
1235: }
1236: return 0;
1237: }
1238:
1239:
1240: static int
1241: dvbdev_ioctl(struct dvb_device *dvbdev, int num,
1242: struct file *file, unsigned int cmd, unsigned long arg)
1243: {
1244: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1245: void *parg=(void *)arg;
1246: int type=num2type(card, num);
1247:
1248: switch (type) {
1249: case DVB_DEVICE_VIDEO_0:
1250: if (((file->f_flags&O_ACCMODE)==O_RDONLY) &&
1251: (cmd!=VIDEO_GET_STATUS))
1252: return -EPERM;
1253:
1254: switch (cmd) {
1255:
1256: case VIDEO_STOP:
1257: DecoderPause(card);
1.9 mocm 1258: card->videostate.playState = VIDEO_STOPPED;
1.10 ! mocm 1259: if (card->videostate.videoBlank)
! 1260: VideoSetBackground(card, 1, 0, 0, 0);
1.9 mocm 1261:
1.10 ! mocm 1262:
1.9 mocm 1263: return 0;
1.6 mocm 1264:
1265: case VIDEO_PLAY:
1266:
1267: if (card->videostate.streamSource==
1268: VIDEO_SOURCE_MEMORY) {
1.9 mocm 1269: if (card->videostate.playState==VIDEO_FREEZED){
1270: DecoderUnPause(card);
1271: } else {
1272: DecoderUnPause(card);
1273: }
1.6 mocm 1274: }
1275: break;
1276:
1277: case VIDEO_FREEZE:
1278: DecoderPause(card);
1279: break;
1280:
1281: case VIDEO_CONTINUE:
1282: if (card->videostate.playState==VIDEO_FREEZED) {
1283: DecoderUnPause(card);
1284: }
1285: break;
1286:
1287: case VIDEO_SELECT_SOURCE:
1288: card->videostate.streamSource=(videoStreamSource_t) arg;
1289: break;
1290:
1291: case VIDEO_SET_BLANK:
1292: card->videostate.videoBlank=(boolean) arg;
1293: break;
1294:
1295: case VIDEO_GET_STATUS:
1296: if(copy_to_user(parg, &card->videostate,
1297: sizeof(struct videoStatus)))
1298: return -EFAULT;
1299: break;
1300:
1301: case VIDEO_GET_EVENT:
1302: return -EOPNOTSUPP;
1303:
1304: case VIDEO_SET_DISPLAY_FORMAT:
1305: {
1306: videoDisplayFormat_t format=(videoDisplayFormat_t) arg;
1307: u16 val=0;
1308:
1309: switch(format) {
1310: case VIDEO_PAN_SCAN:
1311: val=VID_PAN_SCAN_PREF;
1312: break;
1313:
1314: case VIDEO_LETTER_BOX:
1315: val=VID_VC_AND_PS_PREF;
1316: break;
1317:
1318: case VIDEO_CENTER_CUT_OUT:
1319: val=VID_CENTRE_CUT_PREF;
1320: break;
1321:
1322: default:
1323: return -EINVAL;
1324: }
1325:
1326: card->videostate.videoFormat=format;
1327: return 0;
1328: }
1329:
1330: case VIDEO_STILLPICTURE:
1331: {
1332: struct videoDisplayStillPicture pic;
1333:
1334: if(copy_from_user(&pic, parg,
1335: sizeof(struct videoDisplayStillPicture)))
1336: return -EFAULT;
1337:
1338: break;
1339: }
1340:
1341: case VIDEO_FAST_FORWARD:
1.10 ! mocm 1342: if (card->videostate.streamSource !=
! 1343: VIDEO_SOURCE_MEMORY)
! 1344: return -EPERM;
! 1345: card->videoffwd = 2;
1.6 mocm 1346: break;
1347:
1348: case VIDEO_SLOWMOTION:
1349: if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY)
1350: return -EPERM;
1.10 ! mocm 1351: card->videoslow = arg;
1.6 mocm 1352:
1353: break;
1354:
1355: case VIDEO_GET_CAPABILITIES:
1356: {
1.8 mocm 1357: int cap=VIDEO_CAP_MPEG1|
1358: VIDEO_CAP_MPEG2|
1359: VIDEO_CAP_SYS|
1360: VIDEO_CAP_PROG|
1361: VIDEO_CAP_SPU|
1362: VIDEO_CAP_NAVI|
1363: VIDEO_CAP_CSS;
1364:
1.6 mocm 1365:
1366: if (copy_to_user(parg, &cap,
1367: sizeof(cap)))
1368: return -EFAULT;
1369: break;
1370: }
1371: default:
1372: return -ENOIOCTLCMD;
1373: }
1374: return 0;
1375:
1376: case DVB_DEVICE_AUDIO_0:
1377: if (((file->f_flags&O_ACCMODE)==O_RDONLY) &&
1378: (cmd!=AUDIO_GET_STATUS))
1379: return -EPERM;
1380:
1381: switch (cmd) {
1382:
1383: case AUDIO_STOP:
1384: if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
1385: break;
1386: AudioStopDecode(card);
1387: card->audiostate.playState=AUDIO_STOPPED;
1388: break;
1389:
1390: case AUDIO_PLAY:
1391: if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
1392: break;
1393: AudioSetPlayMode(card, MAUDIO_PLAY);
1394: card->audiostate.playState=AUDIO_PLAYING;
1395: break;
1396:
1397: case AUDIO_PAUSE:
1398: card->audiostate.playState=AUDIO_PAUSED;
1399: AudioSetPlayMode(card, MAUDIO_PAUSE);
1400: break;
1401:
1402: case AUDIO_CONTINUE:
1403: if (card->audiostate.playState==AUDIO_PAUSED) {
1404: card->audiostate.playState=AUDIO_PLAYING;
1405: AudioSetPlayMode(card, MAUDIO_PLAY);
1406: }
1407: break;
1408:
1409: case AUDIO_SELECT_SOURCE:
1410: card->audiostate.streamSource=(audioStreamSource_t) arg;
1411: break;
1412:
1413: case AUDIO_SET_MUTE:
1414: {
1415: AudioMute(card, arg);
1416: card->audiostate.muteState=(boolean) arg;
1417: break;
1418: }
1419:
1420: case AUDIO_SET_AV_SYNC:
1.9 mocm 1421: card->videosync=(boolean) arg;
1.6 mocm 1422: card->audiostate.AVSyncState=(boolean) arg;
1423: break;
1424:
1425: case AUDIO_SET_BYPASS_MODE:
1426: return -EINVAL;
1427:
1428: case AUDIO_CHANNEL_SELECT:
1429: card->audiostate.channelSelect=(audioChannelSelect_t) arg;
1430:
1431: switch(card->audiostate.channelSelect) {
1432: case AUDIO_STEREO:
1433: break;
1434:
1435: case AUDIO_MONO_LEFT:
1436: break;
1437:
1438: case AUDIO_MONO_RIGHT:
1439: break;
1440:
1441: default:
1442: return -EINVAL;
1443: }
1444: return 0;
1445:
1446: case AUDIO_GET_STATUS:
1447: if(copy_to_user(parg, &card->audiostate,
1448: sizeof(struct audioStatus)))
1449: return -EFAULT;
1450: break;
1451:
1452: case AUDIO_GET_CAPABILITIES:
1453: {
1454: int cap=AUDIO_CAP_LPCM|
1455: AUDIO_CAP_MP1|
1.8 mocm 1456: AUDIO_CAP_MP2|
1457: AUDIO_CAP_AC3;
1.6 mocm 1458:
1459: if (copy_to_user(parg, &cap,
1460: sizeof(cap)))
1461: return -EFAULT;
1462: break;
1463: }
1464: default:
1465: return -ENOIOCTLCMD;
1466: }
1467: break;
1468:
1469:
1470: case DVB_DEVICE_DEMUX_0:
1471: return DmxDevIoctl(&card->dmxdev, file, cmd, arg);
1472:
1.9 mocm 1473: case DVB_DEVICE_OSD_0:
1474: {
1475: /* switch (cmd) {
1476: case OSD_SEND_CMD:
1477: {
1478: osd_cmd_t doc;
1479:
1480: if(copy_from_user(&doc, parg,
1481: sizeof(osd_cmd_t)))
1482: return -EFAULT;
1483: return OSD_DrawCommand(dvb, &doc);
1484: }
1485: default:
1486: return -EINVAL;
1487: }*/
1488: break;
1489: }
1490: default:
1.6 mocm 1491: return -EOPNOTSUPP;
1492: }
1493: return 0;
1494: }
1495:
1496: static unsigned int
1497: dvbdev_poll(struct dvb_device *dvbdev, int num,
1498: struct file *file, poll_table * wait)
1499: {
1500: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1501: int type=num2type(card, num);
1502:
1503: switch (type) {
1504: case DVB_DEVICE_DEMUX_0:
1505: return DmxDevPoll(&card->dmxdev, file, wait);
1506:
1507: case DVB_DEVICE_VIDEO_0:
1508: return PSpoll(file, wait);
1509:
1510: case DVB_DEVICE_AUDIO_0:
1511: return PSpoll(file, wait);
1512:
1513: case DVB_DEVICE_CA_0:
1514: break;
1515:
1516: default:
1517: return -EOPNOTSUPP;
1518: }
1519:
1520: return 0;
1521: }
1522:
1523:
1524: static int
1525: dvbdev_device_type(struct dvb_device *dvbdev, unsigned int num)
1526: {
1527: struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
1528:
1529: return num2type(card, num);
1530: }
1531: #endif
1532:
1533: /******************************************************************************
1534: * driver registration
1535: ******************************************************************************/
1536:
1537:
1538: void v4l_init(struct cvdv_cards *card)
1539: {
1540:
1541: memcpy( &card->video, &margi_template, sizeof(struct video_device));
1542:
1543: if( 0 > (video_register_device(&card->video, VFL_TYPE_GRABBER))) {
1544: printk(KERN_ERR "margi: can't register videodevice\n");
1545: }
1546: }
1547:
1548: #ifdef DVB
1549:
1550: #define INFU 32768
1551:
1.9 mocm 1552:
1553:
1.6 mocm 1554: static dvb_devs_t mdvb_devs = {
1.9 mocm 1555: 9,
1.6 mocm 1556: {
1.9 mocm 1557: DVB_DEVICE_VIDEO_0, DVB_DEVICE_AUDIO_0,
1558: -1, -1,
1559: DVB_DEVICE_DEMUX_0, DVB_DEVICE_DVR_0,
1560: -1, -1,
1561: -1//DVB_DEVICE_OSD,
1.6 mocm 1562: },
1.9 mocm 1563: { INFU, INFU, INFU, INFU, INFU, 1, 1, INFU, 1 },
1564: { 1, 1, 1, 1, INFU, 1, 1, 1, 1}
1.6 mocm 1565: };
1566:
1567: int dvb_register(struct cvdv_cards *card)
1568: {
1569: int i;
1570: struct dvb_device *dvbd=&card->dvb_dev;
1571:
1572: if (card->dvb_registered)
1573: return -1;
1574: card->dvb_registered=1;
1575:
1576: card->audiostate.AVSyncState=0;
1577: card->audiostate.muteState=0;
1578: card->audiostate.playState=AUDIO_STOPPED;
1579: card->audiostate.streamSource=AUDIO_SOURCE_MEMORY;
1580: card->audiostate.channelSelect=AUDIO_STEREO;
1581: card->audiostate.bypassMode=0;
1582:
1583: card->videostate.videoBlank=0;
1584: card->videostate.playState=VIDEO_STOPPED;
1585: card->videostate.streamSource=VIDEO_SOURCE_MEMORY;
1586: card->videostate.videoFormat=VIDEO_FORMAT_4_3;
1587: card->videostate.displayFormat=VIDEO_CENTER_CUT_OUT;
1588:
1589: // init and register demuxes
1590:
1591:
1592: // init and register dvb device structure
1593: dvbd->priv=(void *) card;
1594: dvbd->open=dvbdev_open;
1595: dvbd->close=dvbdev_close;
1596: dvbd->write=dvbdev_write;
1597: dvbd->ioctl=dvbdev_ioctl;
1598: dvbd->poll=dvbdev_poll;
1599: dvbd->device_type=dvbdev_device_type;
1600:
1601: for (i=0; i<DVB_DEVS_MAX; i++)
1602: card->users[i]=card->writers[i]=0;
1603:
1604: card->dvb_devs=0;
1605: card->dvb_devs=&mdvb_devs;
1606:
1607: return dvb_register_device(dvbd);
1608: }
1609:
1610: void dvb_unregister(struct cvdv_cards *card)
1611: {
1612: dvb_unregister_device(&card->dvb_dev);
1613: }
1614: #endif
LinuxTV legacy CVS <linuxtv.org/cvs>