Annotation of margi2/cvdv.c, revision 1.1.1.1
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:
56:
57: /////////////////////////////////////////////
58: // //
59: // Controlling the L64021 MPEG-2 Decoder //
60: // //
61: /////////////////////////////////////////////
62:
63: int OSDTest(struct cvdv_cards *card)
64: {
65: int i, j, x, y, col, xpos, ypos, x0, y0, x1, y1, aspx, aspy, width,
66: height;
67: u8 row[130];
68:
69: if (!card->OSD.open)
70: return -2;
71:
72: //VideoSetBackground(card,2,83,90,249); // Red
73: //VideoSetBackground(card,2,155,53,53); // Green
74: //VideoSetBackground(card,2,35,212,114); // Blue
75: //VideoSetBackground(card,2,4,128,128); // Black
76:
77: OSDQuery(card, &x0, &y0, &x1, &y1, &aspx);
78: aspy = 11;
79: width = 130;
80: height = width * aspy / aspx;
81: xpos = ((x1 - x0 + 1) - width) / 2;
82: ypos = ((y1 - y0 + 1) - height) / 2;
83:
84: OSDShow(card);
85:
86: OSDSetColor(card, 0, 0, 0, 0, 1, 0, 1); // transparent background
87: for (i = 0; i < 2; i++) {
88: for (j = 0; j < 8; j++) {
89: col = 1 + i * 8 + j;
90: OSDSetColor(card, col, (j & 2) ? 192 : 0,
91: (j & 4) ? 192 : 0, (j & 1) ? 192 : 0,
92: 1, i, 0);
93: }
94: }
95:
96: // for (x=1; x<=16; x++) {
97: // OSDFill(card,x);
98: // }
99: // OSDClear(card);
100:
101: for (i = 0; i < 2; i++) {
102: for (j = 0; j < 8; j++) {
103: col = 1 + i * 8 + j;
104: for (x = 0; x < 16; x++)
105: row[1 + x + j * 16] = col;
106: }
107: for (y = 0; y < (height - 2) / 2; y++) {
108: OSDSetRow(card, xpos,
109: ypos + 1 + y + i * ((height - 2) / 2),
110: xpos + width - 1, row);
111: }
112: }
113:
114: OSDFillRow(card, xpos, ypos, xpos + width - 1, 8);
115: OSDFillRow(card, xpos, ypos + height - 1, xpos + width - 1, 8);
116: for (y = ypos; y < ypos + height; y++) {
117: OSDSetPixel(card, xpos, y, 8);
118: OSDSetPixel(card, xpos + width - 1, y, 8);
119: }
120: for (x = 0; x < 130; x++) {
121: OSDSetPixel(card, x + xpos, x * aspy / aspx + ypos, 8);
122: OSDSetPixel(card, width - x + xpos, x * aspy / aspx + ypos,
123: 8);
124: OSDSetPixel(card, x + xpos,
125: (x >> 3) + ypos + ((height / 2) - 8), 8);
126: }
127: OSDLine(card, x0, y0, x1, y0, 8);
128: OSDLine(card, x1, y0, x1, y1, 8);
129: OSDLine(card, x1, y1, x0, y1, 8);
130: OSDLine(card, x0, y1, x0, y0, 8);
131: OSDLine(card, x0, y0, x1, y1, 8);
132: OSDLine(card, x0, y1, x1, y0, 8);
133:
134: // OSDShow(card);
135:
136: return 0;
137: }
138:
139:
140: void SetVideoSystem(struct cvdv_cards *card)
141: {
142: // set the hsync and vsync generators in the L64017 according to the video standard
143: switch (card->videomode) {
144: case PAL: // 864*625*50Hz = 27MHz, 25fps
145: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x41 | 0x0a);
146: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
147: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
148: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
149: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
150: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
151: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
152: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);
153: break;
154: case PALN:
155: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0xa1 | 0x0a);
156: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
157: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
158: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
159: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
160: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
161: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
162: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);
163: break;
164:
165: case PALNc:
166: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x81 | 0x0a);
167: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
168: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
169: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x8c);
170: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x28);
171: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xed);
172: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
173: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);
174:
175: break;
176:
177: case NTSC: // 858*525*59.94006Hz = 27MHz, 29.97fps
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, 0x1c);
181: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);
182: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);
183: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);
184: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
185: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_NTSC);
186:
187: break;
188:
189: case PALM:
190: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a);
191: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
192: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
193: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e);
194: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);
195: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);
196: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
197: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);
198:
199: break;
200:
201: case NTSC60: // 857*525*60.010002Hz = 27MHz, 30fps
202: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x21 | 0x0a);
203: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
204: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c);
205: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);
206: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);
207: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);
208: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
209: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_NTSC);
210: break;
211:
212: case PALM60:
213: I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x61 | 0x0a);
214: I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
215: I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
216: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e);
217: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);
218: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);
219: I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
220: write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);
221:
222: break;
223:
224: case PAL60:
225: break;
226: }
227: // set the pixel generators according to the video standard
228: L64021Setup(card);
229: }
230:
231: int SetVideoAttr(struct cvdv_cards *card, u16 vattr)
232: {
233: u8 video_compression_mode;
234: u8 tv_system;
235: u8 aspect_ratio;
236: u8 display_mode;
237: u8 line_21_switch_1;
238: u8 line_21_switch_2;
239: u8 source_picture_resolution;
240: u8 source_picture_letterboxed;
241: u8 reserved;
242: u8 film_camera_mode;
243: u16 hsize, vsize;
244: if (vattr != card->lastvattr) {
245: video_compression_mode = (vattr >> 14) & 0x03;
246: tv_system = (vattr >> 12) & 0x03;
247: aspect_ratio = (vattr >> 10) & 0x03;
248: display_mode = (vattr >> 8) & 0x03;
249: line_21_switch_1 = (vattr >> 7) & 0x01;
250: line_21_switch_2 = (vattr >> 6) & 0x01;
251: source_picture_resolution = (vattr >> 3) & 0x07;
252: source_picture_letterboxed = (vattr >> 2) & 0x01;
253: reserved = (vattr >> 1) & 0x01;
254: film_camera_mode = (vattr >> 0) & 0x01;
255: card->videomode =
256: ((tv_system == 0) ? NTSC : ((tv_system == 1) ?
257: PAL : PAL));
258: SetVideoSystem(card);
259: hsize =
260: ((source_picture_resolution == 0) ? 720
261: : ((source_picture_resolution == 1) ? 702 : 352));
262: vsize = ((source_picture_resolution == 3)
263: ? ((tv_system == 0) ? 240 : 288)
264: : ((tv_system == 0) ? 480 : 576));
265: if (DecoderOpen
266: (card, hsize, vsize, ((aspect_ratio) ? 3 : 2),
267: ((video_compression_mode) ? 0 : 1),
268: source_picture_letterboxed, tv_system)) {
269: printk(KERN_ERR LOGNAME
270: ": Video Decoder Open failed: On-card memory insufficient for frame stores\n");
271: }
272: card->lastvattr = vattr;
273: } else {
274: printk(KERN_ERR LOGNAME
275: ": Video attribute not set, equal to previous one.\n");
276: }
277: return 0;
278: }
279:
280: int SetAudioAttr(struct cvdv_cards *card, u16 aattr)
281: {
282: u8 audio_coding_mode;
283: u8 multichannel_extension;
284: u8 audio_type;
285: u8 audio_application_mode;
286: u8 quantization_drc;
287: u8 fs;
288: u8 reserved;
289: u8 num_audio_ch;
290: if (aattr) {
291: if (aattr != card->lastaattr) {
292: audio_coding_mode = (aattr >> 13) & 0x07;
293: multichannel_extension = (aattr >> 12) & 0x01;
294: audio_type = (aattr >> 10) & 0x03;
295: audio_application_mode = (aattr >> 8) & 0x03;
296: quantization_drc = (aattr >> 6) & 0x03;
297: fs = (aattr >> 4) & 0x03;
298: reserved = (aattr >> 3) & 0x01;
299: num_audio_ch = (aattr >> 0) & 0x07;
300: switch (audio_coding_mode) {
301: case 0: // AC-3
302: card->setup.audioselect = audio_AC3;
303: break;
304: case 2: // MPEG Audio
305: card->setup.audioselect = audio_MPEG;
306: break;
307: case 3: // MPEG Audio with ext.
308: card->setup.audioselect = audio_MPEG_EXT;
309: break;
310: case 4: // Linear Pulse Code Modulation LPCM
311: card->setup.audioselect = audio_LPCM;
312: break;
313: case 6: // DTS
314: card->setup.audioselect = audio_DTS;
315: break;
316: case 7: // SDDS
317: card->setup.audioselect = audio_SDDS;
318: break;
319: }
320: DecoderPrepareAudio(card);
321: AudioInit(card, ((fs) ? 96 : 48),
322: ((audio_application_mode == 2) ? 1 : 0));
323: } else {
324: printk(KERN_ERR LOGNAME
325: ": Audio attribute not set, equal to previous one.\n");
326: }
327: } else {
328: card->setup.audioselect = audio_none;
329: DecoderPrepareAudio(card);
330: }
331: card->lastaattr = aattr;
332: return 0;
333: }
334:
335: int Prepare(struct cvdv_cards *card)
336: {
337: int err, h;
338: struct StreamSetup *setup = &card->setup;
339:
340: if (!card->ChannelBuffersAllocated) {
341:
342: DecoderStreamReset(card);
343: if (setup->streamtype == stream_none) {
344: setup->streamtype = stream_PS;
345: }
346:
347: if (setup->audioselect == audio_none) {
348: setup->audioselect = audio_MPEG;
349: }
350:
351: DecoderPrepareAudio(card);
352: AudioMute(card, 1);
353: DecoderPrepareVideo(card);
354: VideoSetBackground(card, 1, 0, 0, 0); // black
355:
356: switch (setup->streamtype) {
357: default:
358: case stream_none: // unknown stream!
359: printk(KERN_ERR LOGNAME
360: ": Video Decoder Prepare failed: unknown stream type\n");
361: return -ENODEV; // not an MPEG stream!
362: case stream_ES: // Elementary Stream
363: err = DecoderPrepareES(card);
364: break;
365: case stream_PES: // Packetized Elementary Stream
366: err = DecoderPreparePES(card);
367: break;
368: case stream_PS: // MPEG-1 System Stream / MPEG-2 Program Stream
369: err = DecoderPreparePS(card, -1, 0, 0, 0, 0, 0);
370: break;
371: case stream_DVD: // DVD Stream
372: err = DecoderPreparePS(card, 0, 0, 0, 0, 3, 1);
373: break;
374: }
375: if (err) { // insufficient memory
376: printk(KERN_ERR LOGNAME
377: ": Video Decoder Prepare failed: no kernel memory, please reboot if possible\n");
378: CloseCard(card);
379: return -ENODEV;
380: }
381: }
382:
383: // Set up the Video Decoder as we have the stream information
384: if ((!card->FrameBuffersAllocated)
385: && (card->ChannelBuffersAllocated) && (card->stream.sh.valid)) {
386: //printk(KERN_DEBUG LOGNAME ": Setup Decoder %d\n",channel);
387: // Automatic PAL/NTSC-switch according to MPEG-Source
388: h = card->stream.vsize;
389: if (h < 480)
390: h *= 2; // catch quarter sized images
391: printk(KERN_INFO LOGNAME ": Video mode: %s\n",
392: ((h == 480) ? "NTSC" : "PAL"));
393: card->videomode = ((h == 480) ? NTSC : PAL);
394: SetVideoSystem(card);
395: // Open the Video Decoder with the parameters retreived from the stream
396: if (
397: (err =
398: DecoderOpen(card, card->stream.hsize,
399: card->stream.vsize,
400: card->stream.sh.aspectratio,
401: !card->stream.MPEG2, 0,
402: (card->videomode == PAL)))) { // TODO: include vbvbuffersize
403: printk(KERN_ERR LOGNAME
404: ": Video Decoder Open failed: %s\n",
405: ((err == 1) ?
406: "Picture size too big (>1440 pixel wide)" :
407: "On-card memory insufficient for frame stores"));
408: CloseCard(card);
409: return -ENODEV; // picture too big or insufficient memory
410: }
411: card->startingV = 1; // tell the card to start playing as soon as ES-buffers are sufficiently full
412: card->startingA = 1; // tell the card to start playing as soon as ES-buffers are sufficiently full
413: }
414:
415:
416: return 0;
417: }
418:
419: int SetSCRstart(struct cvdv_cards *card, u32 SCR_base)
420: {
421: u32 SCR_compare;
422: u32 SCR_compareA;
423: u32 SCR_compareV;
424: if (card->startingV) {
425: printk(KERN_ERR LOGNAME ": SCR in DVD Pack: 0x%08X\n",
426: SCR_base);
427: card->startingV = 0;
428: card->startingA = 0;
429: DecoderMaskByte(card, 0x007, 0xD2, 0xD2); // Set 0x010, halt SCR counter
430: SCR_compare = SCR_base + 000;
431: if (SCR_base < 900)
432: SCR_base = 0;
433: else
434: SCR_base -= 900;
435: //DecoderWriteDWord(card,0x009,SCR_base); // Set SCR counter
436: DecoderWriteByte(card, 0x009, SCR_base & 0xFF); // Set SCR counter
437: DecoderWriteByte(card, 0x00A, (SCR_base >> 8) & 0xFF);
438: DecoderWriteByte(card, 0x00B, (SCR_base >> 16) & 0xFF);
439: DecoderWriteByte(card, 0x00C, (SCR_base >> 24) & 0xFF);
440: DecoderMaskByte(card, 0x011, 0x03, 0x02); // compare, not capture
441: printk(KERN_ERR LOGNAME ": SCR compare value: 0x%08X\n",
442: SCR_compare);
443: //DecoderWriteDWord(card,0x00D,SCR_compare); // Set Compare register
444: DecoderWriteByte(card, 0x00D, SCR_compare & 0xFF); // Set Compare register
445: DecoderWriteByte(card, 0x00E, (SCR_compare >> 8) & 0xFF);
446: DecoderWriteByte(card, 0x00F, (SCR_compare >> 16) & 0xFF);
447: DecoderWriteByte(card, 0x010, (SCR_compare >> 24) & 0xFF);
448: //DecoderWriteDWord(card,0x014,SCR_compare); // Set audio compare reg.
449: DecoderWriteByte(card, 0x014, SCR_compare & 0xFF); // Set audio compare reg.
450: DecoderWriteByte(card, 0x015, (SCR_compare >> 8) & 0xFF);
451: DecoderWriteByte(card, 0x016, (SCR_compare >> 16) & 0xFF);
452: DecoderWriteByte(card, 0x017, (SCR_compare >> 24) & 0xFF);
453: DecoderSetByte(card, 0x013, 0x03); // Video and Audio start on cmp.
454: //DecoderSetVideoPanic(card,0,DecoderGetVideoESSize(card)/4); // video panic at 25 percent
455: VideoSetBackground(card, 1, 0, 0, 0); // black
456: SCR_base = DecoderReadByte(card, 0x009);
457: SCR_base =
458: SCR_base | ((u32) DecoderReadByte(card, 0x00A) << 8);
459: SCR_base =
460: SCR_base | ((u32) DecoderReadByte(card, 0x00B) << 16);
461: SCR_base =
462: SCR_base | ((u32) DecoderReadByte(card, 0x00C) << 24);
463: SCR_compareA = DecoderReadByte(card, 0x014);
464: SCR_compareA =
465: SCR_compareA | ((u32) DecoderReadByte(card, 0x015) <<
466: 8);
467: SCR_compareA =
468: SCR_compareA | ((u32) DecoderReadByte(card, 0x016) <<
469: 16);
470: SCR_compareA =
471: SCR_compareA | ((u32) DecoderReadByte(card, 0x017) <<
472: 24);
473: SCR_compareV = DecoderReadByte(card, 0x00D);
474: SCR_compareV =
475: SCR_compareV | ((u32) DecoderReadByte(card, 0x00E) <<
476: 8);
477: SCR_compareV =
478: SCR_compareV | ((u32) DecoderReadByte(card, 0x00F) <<
479: 16);
480: SCR_compareV =
481: SCR_compareV | ((u32) DecoderReadByte(card, 0x010) <<
482: 24);
483: if (DecoderReadByte(card, 0x013) & 0x03)
484: printk(KERN_DEBUG LOGNAME
485: ": SCR 0x%08X, videocmp=0x%08X, audiocmp=0x%08X %02X\n",
486: SCR_base, SCR_compareV, SCR_compareA,
487: DecoderReadByte(card, 0x013));
488: DecoderMaskByte(card, 0x007, 0xD2, 0xC2); // Del 0x010, SCR counter run
489: }
490: return 0;
491: }
492:
493: int DecoderWriteBlock(struct cvdv_cards *card, u8 * data, int size,
494: int initial, int setSCR)
495: {
496: //int a,v,as,vs,ap,vp;
497: int res;
498: u32 SCR_base;
499: int co = 0;
500: // u32 SCR_compare;
501: res = 0;
502: //Prepare(card);
503:
504: if (size > 0) {
505:
506: if (!card->use_ring)
507: MargiSetBuffers(card, 16*65536);
508:
509: if (card->startingDVDV || card->startingDVDA)
510: setSCR = 1;
511:
512: if (initial) {
513: DecoderStreamReset(card);
514: DecoderSetupReset(card);
515: //TODO stop and start channel interface
516: setSCR = 1;
517: }
518:
519: if (setSCR) {
520: SCR_base = ParseSCR(data);
521: SetSCR(card, SCR_base);
522: }
523:
524: while (((res = MargiPush(card, size, data)) < size)
525: && co < 100) {
526: data+=res;
527: size-=res;
528: co++;
529: // printk(KERN_DEBUG LOGNAME
530: // ": DecoderWriteBlock - buffers only filled with %d instead of %d bytes\n",
531: // res, size);
532: if (card->DMAABusy)
533: interruptible_sleep_on(&card->wqA);
534: }
535:
536: if (card->startingDVDV) {
537: card->startingDVDV = 0;
538: DecoderStartDecode(card);
539: }
540: if (card->startingDVDA) {
541: card->startingDVDA = 0;
542: AudioSetPlayMode(card, AUDIO_PLAY);
543: }
544:
545:
546: }
547: return 0;
548: }
549:
550:
551:
552:
553:
554: //////////////////////////////
555: // //
556: // Char Device Procedures //
557: // //
558: //////////////////////////////
559:
560: static ssize_t PSwrite(struct file *file, const char *data, size_t count,
561: loff_t * offset)
562: {
563: struct cvdv_cards *card =
564: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
565: int channel = MINOR(file->f_dentry->d_inode->i_rdev) / MAXDEV; // minor number div. 16
566: struct StreamSetup *setup = &card->setup;
567: // int i;
568: // int laststart=-1;
569: // int B3=0, B5=0, C0=0, E0=0, BD=0, BF=0;
570: int res;
571:
572: if (card != NULL) {
573: if (count > 0) { // Do we have data?
574: if ((res = Prepare(card)))
575: return res;
576:
577: if ((setup->streamtype != stream_ES)
578: && (setup->streamtype != stream_PES))
579: channel = 0;
580: // only ES and PES come in separate streams
581: switch (channel) {
582: case 0:
583: if (!card->use_ring)
584: MargiSetBuffers(card, NBBUF*
585: CHANNELBUFFERSIZE);
586: if (!(count = MargiPush(card, count, data))){
587: if (card->DMAABusy)
588: interruptible_sleep_on(
589: &card->wqA);
590: }
591: break;
592:
593:
594: case 1:
595:
596: // todo
597: break;
598: }
599: }
600: return count;
601: } else {
602: printk(KERN_ERR LOGNAME
603: ": Video Decoder Prepare failed: device with this minor number not found\n");
604: return -ENODEV; // device with this minor number not found
605: }
606: }
607:
608: static unsigned int PSpoll(struct file *file, poll_table * table)
609: {
610: struct cvdv_cards *card =
611: minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV]; // minor number modulo 16
612: // int channel=MINOR(file->f_dentry->d_inode->i_rdev) / MAXDEV; // minor number div. 16
613: if (card != NULL) {
614:
615: return POLLOUT | POLLWRNORM; // always writeable, HAS TO BE CHANGED!!!!
616:
617: } else
618: return POLLERR; // device with this minor number not found
619: }
620:
621: static int PSioctl(struct inode *inode, struct file *file,
622: unsigned int cmd, unsigned long arg)
623: {
624: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
625: // int channel=MINOR(inode->i_rdev) / MAXDEV; // minor number div. 16
626: struct drawcmd *dc;
627: struct decodercmd *command;
628: u16 attr;
629: if (card != NULL) {
630: if (_IOC_TYPE(cmd) == CVDV_IOCTL_MAGIC)
631: switch (_IOC_NR(cmd)) {
632: case IOCTL_DRAW: // Drawing commands
633: dc = (struct drawcmd *) arg;
634: switch (dc->cmd) {
635: case OSD_Close:
636: printk(KERN_DEBUG LOGNAME
637: ": OSD Close\n");
638: return OSDClose(card);
639: case OSD_Open: // Open(x0,y0,x1,y1,BitPerPixel(2/4/8),mix(0..15))
640: return OSDOpen(card, dc->x0,
641: dc->y0, dc->x1,
642: dc->y1,
643: dc->color & 0x0F,
644: (dc->color >> 4) &
645: 0x0F);
646: case OSD_Show:
647: return OSDShow(card);
648: case OSD_Hide:
649: return OSDHide(card);
650: case OSD_Clear:
651: return OSDClear(card);
652: case OSD_Fill: // Fill(color)
653: return OSDFill(card, dc->color);
654: case OSD_SetColor: // SetColor(color,R(x0),G(y0),B(x1),opacity(y1))
655: //printk(KERN_DEBUG LOGNAME ": OSD SetColor(%d,%d,%d,%d,%d)\n",
656: //dc->color,dc->x0,dc->y0,dc->x1,dc->y1);
657: return (OSDSetColor
658: (card, dc->color, dc->x0,
659: dc->y0, dc->x1, 0,
660: (dc->y1 != 255),
661: (dc->y1 == 0)) >= 0);
662: case OSD_SetPalette: // SetPalette(firstcolor{color},lastcolor{x0},data)
663: return OSDSetPalette(card,
664: dc->color,
665: dc->x0, (u8 *)
666: dc->data);
667: case OSD_SetTrans: // SetTrans(transparency{color})
668: return OSDSetTrans(card,
669: (dc->color >> 4)
670: & 0x0F);
671: case OSD_SetPixel: // SetPixel(x0,y0,color)
672: return OSDSetPixel(card, dc->x0,
673: dc->y0,
674: dc->color);
675: case OSD_GetPixel: // GetPixel(x0,y0);
676: return OSDGetPixel(card, dc->x0,
677: dc->y0);
678: case OSD_SetRow: // SetRow(x0,y0,x1,(u8*)data)
679: return OSDSetRow(card, dc->x0,
680: dc->y0, dc->x1,
681: (u8 *) dc->data);
682: case OSD_SetBlock: // SetBlock(x0,y0,x1,y1,(u8*)data)
683: return OSDSetBlock(card, dc->x0,
684: dc->y0, dc->x1,
685: dc->y1,
686: dc->color,
687: (u8 *)
688: dc->data);
689: case OSD_FillRow: // FillRow(x0,y0,x1,color)
690: return OSDFillRow(card, dc->x0,
691: dc->y0, dc->x1,
692: dc->color);
693: case OSD_FillBlock: // FillRow(x0,y0,x1,y1,color)
694: return OSDFillBlock(card, dc->x0,
695: dc->y0, dc->x1,
696: dc->y1,
697: dc->color);
698: case OSD_Line: // Line(x0,y0,x1,y1,color);
699: return OSDLine(card, dc->x0,
700: dc->y0, dc->x1,
701: dc->y1, dc->color);
702: case OSD_Query: // Query(x0,y0,x1,y1,aspect(color:11)
703: return OSDQuery(card, &dc->x0,
704: &dc->y0, &dc->x1,
705: &dc->y1,
706: &dc->color);
707: case OSD_Test:
708: return OSDTest(card);
709: default:
710: return -EINVAL;
711: }
712: case IOCTL_DECODER:
713: command = (struct decodercmd *) arg;
714: switch (command->cmd) {
715: /*
716: case Decoder_CSS:
717: return DecoderCSS(card,
718: command->param1,
719: command->data1);
720: */
721: case Decoder_Set_Videosystem:
722: printk(KERN_DEBUG LOGNAME
723: ": -- Decoder_Set_Videosystem\n");
724: card->videomode =
725: (videosystem) command->param1;
726: SetVideoSystem(card);
727: return 0;
728: case Decoder_Set_Streamtype:
729: printk(KERN_DEBUG LOGNAME
730: ": -- Decoder_Set_Streamtype\n");
731: card->setup.streamtype =
732: (stream_type) command->param1;
733: return 0;
734: case Decoder_Set_Audiotype:
735: printk(KERN_DEBUG LOGNAME
736: ": -- Decoder_Set_Audiotype\n");
737: card->setup.audioselect =
738: (audio_type) command->param1;
739: DecoderPrepareAudio(card);
740: return 0;
741: case Decoder_Set_VideoStreamID:
742: printk(KERN_DEBUG LOGNAME
743: ": -- Decoder_Set_VideoStreamID\n");
744: card->setup.videoID =
745: command->param1;
746: DecoderPrepareVideo(card);
747: return 0;
748: case Decoder_Set_AudioStreamID:
749: printk(KERN_DEBUG LOGNAME
750: ": -- Decoder_Set_AudioStreamID 0x%02X 0x%02X\n",command->param1,command->param2);
751: card->setup.audioID =
752: command->param1;
753: card->setup.audioIDext =
754: command->param2;
755: attr = card->lastaattr;
756: DecoderSelectAudioID(card);
757: card->lastaattr = attr;
758: return 0;
759: case Decoder_Still_Put:
760: return DecoderShowStill(card,
761: command->
762: param1,
763: command->
764: param2,
765: command->
766: data1,
767: command->
768: data2);
769: case Decoder_Still_Get:
770: return DecoderGetStill(card,
771: &command->
772: param1,
773: &command->
774: param2,
775: command->
776: data1,
777: command->
778: data2);
779: case Decoder_Pause: // pause{param1} 0=run 1=pause 2=toggle
780: if (command->param1 == 2) {
781: if (card->paused)
782: DecoderUnPause
783: (card);
784: else
785: DecoderPause(card);
786: } else {
787: if (!command->param1)
788: DecoderUnPause
789: (card);
790: else
791: DecoderPause(card);
792: }
793: return 0;
794: case Decoder_Highlight: // active{param1}, color information(SL_COLI or AC_COLI){data1[4]}, button position(BTN_POSI){data2[6]}
795: return DecoderHighlight(card,
796: command->
797: param1,
798: command->
799: data1,
800: command->
801: data2);
802: case Decoder_SPU: // stream{param1}, active{param2}
803: return DecoderSPUStream(card,
804: command->
805: param1,
806: command->
807: param2);
808: case Decoder_SPU_Palette: // length{param1}, palette{data1}
809: return DecoderSPUPalette(card,
810: command->
811: param1,
812: command->
813: data1);
814: case Decoder_GetNavi: // data1 will be filled with PCI or DSI pack, and 1024 will be returned
815: return DecoderGetNavi(card,
816: command->
817: data1);
818: case Decoder_SetKaraoke: // Vocal1{param1}, Vocal2{param2}, Melody{param3}
819: return DecoderKaraoke(card,
820: command->
821: param1,
822: command->
823: param2,
824: command->
825: param3);
826: case Decoder_Set_Videoattribute:
827: printk(KERN_DEBUG LOGNAME
828: ": -- Decoder_Set_Videoattribute\n");
829: if (!card->ChannelBuffersAllocated) {
830: DecoderStreamReset(card);
831: MargiFlush(card);
832:
833: card->setup.streamtype =
834: stream_DVD;
835: card->setup.videoID = 0;
836: DecoderPrepareVideo(card);
837: //VideoSetBackground(card,1,0,0,0); // black
838: //DecoderPreparePS(card, -1, 1,2,2,3,1);
839: DecoderPreparePS(card, 0,
840: 0, 2, 2,
841: 3, 1);
842: }
843:
844: SetVideoAttr(card,
845: command->param1);
846: card->startingDVDV = 1; // tell the card to start playing as soon as ES-buffers are sufficiently full
847: return 0;
848: case Decoder_Set_Audioattribute:
849: printk(KERN_DEBUG LOGNAME
850: ": -- Decoder_Set_Audioattribute\n");
851: SetAudioAttr(card,
852: command->param1);
853: card->startingDVDA =
854: ((card->setup.audioselect !=
855: audio_none)
856: && (card->setup.audioselect != audio_disable)); // tell the card to start playing as soon as ES-buffers are sufficiently full
857: return 0;
858: case Decoder_WriteBlock: // DVD-Sector{data1}, sectorsize{param1{2048}}, initialsector{param2{bool}}, set_SCR{param3}
859: return DecoderWriteBlock(card,
860: command->
861: data1,
862: command->
863: param1,
864: command->
865: param2,
866: command->
867: param3);
868: default:
869: return -EINVAL;
870: }
871: default:
872: return -EINVAL;
873: } else
874: return -EINVAL;
875: } else {
876: printk(KERN_ERR LOGNAME
877: ": Video Decoder Prepare failed: device with this minor number not found\n");
878: return -ENODEV; // device with this minor number not found
879: }
880: }
881:
882: static int PSmmap(struct file *file, struct vm_area_struct *vm)
883: {
884: return -ENODEV;
885: }
886:
887: static int PSopen(struct inode *inode, struct file *file)
888: {
889: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
890: int channel = MINOR(inode->i_rdev) / MAXDEV; // minor number div. 16
891: int i, closed;
892: if (card != NULL) {
893: printk(KERN_DEBUG LOGNAME ": -- PSopen %d\n",channel);
894: CloseCard(card);
895: DecoderStreamReset(card);
896: DecoderSetupReset(card);
897: if (card->open[channel])
898: printk(KERN_DEBUG LOGNAME
899: ": PSopen - already open: channel %d\n",
900: channel);
901: closed = 1;
902: for (i = 0; i < MINORNUM; i++)
903: if (card->open[i])
904: closed = 0;
905: if (closed) { // first open() for this card?
906: MargiFreeBuffers(card);
907: VideoSetBackground(card, 1, 0, 0, 0); // black
908: }
909: card->open[channel]++;
910: //MOD_INC_USE_COUNT;
911: return 0;
912: } else {
913: printk(KERN_ERR LOGNAME
914: ": Video Decoder Prepare failed: device with this minor number not found\n");
915: return -ENODEV; // device with this minor number not found
916: }
917: }
918:
919: static int PSrelease(struct inode *inode, struct file *file)
920: {
921: struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV]; // minor number modulo 16
922: int channel = MINOR(inode->i_rdev) / MAXDEV; // minor number div. 16
923: int i, closed;
924:
925: if (card != NULL) {
926: printk(KERN_DEBUG LOGNAME ": -- PSrelease\n");
927: if (!card->open[channel])
928: printk(KERN_DEBUG LOGNAME
929: ": PSrelease - not open: channel %d\n",
930: channel);
931: card->open[channel]--;
932: //MOD_DEC_USE_COUNT;
933: if (!card->open[channel]) {
934: closed = 1;
935: for (i = 0; i < MINORNUM; i++)
936: if (card->open[i])
937: closed = 0;
938: if (closed) { // last close() for this card?
939: printk(KERN_DEBUG LOGNAME
940: ": PSrelease - last close\n");
941: // flush remaining data
942: MargiFlush(card);
943:
944: card->channelApos = 0;
945: card->channelBpos = 0;
946:
947: if ((card->DMAABusy || card->DMABBusy) && (card->intdecodestatus)) { // ongoing DMA?
948: printk(KERN_DEBUG LOGNAME
949: ": Delayed closing: A=%d B=%d\n",
950: card->DMAABusy,
951: card->DMABBusy);
952: card->closing = 1; // then delay closing until DMA finished,
953: } else { // otherwise
954: CloseCard(card); // close immediately
955: }
956: }
957: }
958: return 0;
959: } else {
960: printk(KERN_ERR LOGNAME
961: ": Video Decoder Prepare failed: device with this minor number not found\n");
962: return -ENODEV; // device with this minor number not found
963: }
964: }
965:
966: //////////////////////////
967: // //
968: // Char Device Hookup //
969: // //
970: //////////////////////////
971:
972: // Hookups for a write-only device, that accepts MPEG-2 Program Stream
973: struct file_operations cvdv_fileops = {
974: write: PSwrite,
975: poll: PSpoll,
976: ioctl: PSioctl,
977: mmap: PSmmap,
978: open: PSopen,
979: release: PSrelease,
980: };
LinuxTV legacy CVS <linuxtv.org/cvs>