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