Annotation of margi2/cvdv.c, revision 1.10

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

LinuxTV legacy CVS <linuxtv.org/cvs>