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