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