[BACK]Return to bktr_core.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci / bktr

Annotation of sys/dev/pci/bktr/bktr_core.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: bktr_core.c,v 1.24 2007/07/25 23:11:52 art Exp $      */
        !             2: /* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.114 2000/10/31 13:09:56 roger Exp $ */
        !             3:
        !             4: /*
        !             5:  * This is part of the Driver for Video Capture Cards (Frame grabbers)
        !             6:  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
        !             7:  * chipset.
        !             8:  * Copyright Roger Hardiman and Amancio Hasty.
        !             9:  *
        !            10:  * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
        !            11:  *               Handles all the open, close, ioctl and read userland calls.
        !            12:  *               Sets the Bt848 registers and generates RISC pograms.
        !            13:  *               Controls the i2c bus and GPIO interface.
        !            14:  *               Contains the interface to the kernel.
        !            15:  *               (eg probe/attach and open/close/ioctl)
        !            16:  *
        !            17:  */
        !            18:
        !            19:  /*
        !            20:    The Brooktree BT848 Driver driver is based upon Mark Tinguely and
        !            21:    Jim Lowe's driver for the Matrox Meteor PCI card . The
        !            22:    Philips SAA 7116 and SAA 7196 are very different chipsets than
        !            23:    the BT848.
        !            24:
        !            25:    The original copyright notice by Mark and Jim is included mostly
        !            26:    to honor their fantastic work in the Matrox Meteor driver!
        !            27:
        !            28:  */
        !            29:
        !            30: /*
        !            31:  * 1. Redistributions of source code must retain the
        !            32:  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
        !            33:  * All rights reserved.
        !            34:  *
        !            35:  * Redistribution and use in source and binary forms, with or without
        !            36:  * modification, are permitted provided that the following conditions
        !            37:  * are met:
        !            38:  * 1. Redistributions of source code must retain the above copyright
        !            39:  *    notice, this list of conditions and the following disclaimer.
        !            40:  * 2. Redistributions in binary form must reproduce the above copyright
        !            41:  *    notice, this list of conditions and the following disclaimer in the
        !            42:  *    documentation and/or other materials provided with the distribution.
        !            43:  * 3. All advertising materials mentioning features or use of this software
        !            44:  *    must display the following acknowledgement:
        !            45:  *     This product includes software developed by Amancio Hasty and
        !            46:  *      Roger Hardiman
        !            47:  * 4. The name of the author may not be used to endorse or promote products
        !            48:  *    derived from this software without specific prior written permission.
        !            49:  *
        !            50:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            51:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            52:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            53:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            54:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            55:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            56:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            57:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            58:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            59:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            60:  * POSSIBILITY OF SUCH DAMAGE.
        !            61:  */
        !            62:
        !            63:
        !            64:
        !            65:
        !            66: /*
        !            67:  * 1. Redistributions of source code must retain the
        !            68:  * Copyright (c) 1995 Mark Tinguely and Jim Lowe
        !            69:  * All rights reserved.
        !            70:  *
        !            71:  * Redistribution and use in source and binary forms, with or without
        !            72:  * modification, are permitted provided that the following conditions
        !            73:  * are met:
        !            74:  * 1. Redistributions of source code must retain the above copyright
        !            75:  *    notice, this list of conditions and the following disclaimer.
        !            76:  * 2. Redistributions in binary form must reproduce the above copyright
        !            77:  *    notice, this list of conditions and the following disclaimer in the
        !            78:  *    documentation and/or other materials provided with the distribution.
        !            79:  * 3. All advertising materials mentioning features or use of this software
        !            80:  *    must display the following acknowledgement:
        !            81:  *     This product includes software developed by Mark Tinguely and Jim Lowe
        !            82:  * 4. The name of the author may not be used to endorse or promote products
        !            83:  *    derived from this software without specific prior written permission.
        !            84:  *
        !            85:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            86:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            87:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            88:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            89:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            90:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            91:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            92:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            93:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            94:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            95:  * POSSIBILITY OF SUCH DAMAGE.
        !            96:  */
        !            97:
        !            98: #include <sys/param.h>
        !            99: #include <sys/systm.h>
        !           100: #include <sys/kernel.h>
        !           101: #include <sys/signalvar.h>
        !           102: #include <sys/vnode.h>
        !           103: #include <sys/stdint.h>                /* uintptr_t */
        !           104:
        !           105: #include <dev/rndvar.h>
        !           106: #include <dev/ic/bt8xx.h>
        !           107: #include <dev/pci/bktr/bktr_reg.h>
        !           108: #include <dev/pci/bktr/bktr_tuner.h>
        !           109: #include <dev/pci/bktr/bktr_card.h>
        !           110: #include <dev/pci/bktr/bktr_audio.h>
        !           111: #include <dev/pci/bktr/bktr_core.h>
        !           112: #include <dev/pci/bktr/bktr_os.h>
        !           113:
        !           114: typedef int intrmask_t;
        !           115:
        !           116: static int bt848_format = -1;
        !           117:
        !           118: const char *
        !           119: bktr_name(bktr_ptr_t bktr)
        !           120: {
        !           121:         return (bktr->bktr_dev.dv_xname);
        !           122: }
        !           123:
        !           124:
        !           125: typedef u_char bool_t;
        !           126:
        !           127: #define BKTRPRI (PZERO+8)|PCATCH
        !           128: #define VBIPRI  (PZERO-4)|PCATCH
        !           129:
        !           130:
        !           131: /*
        !           132:  * memory allocated for DMA programs
        !           133:  */
        !           134: #define DMA_PROG_ALLOC         (8 * PAGE_SIZE)
        !           135:
        !           136: /* When to split a dma transfer , the bt848 has timing as well as
        !           137:    dma transfer size limitations so that we have to split dma
        !           138:    transfers into two dma requests
        !           139:    */
        !           140: #define DMA_BT848_SPLIT 319*2
        !           141:
        !           142: /*
        !           143:  * Allocate enough memory for:
        !           144:  *     768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
        !           145:  *
        !           146:  * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
        !           147:  * in your  kernel configuration file.
        !           148:  */
        !           149:
        !           150: #ifndef BROOKTREE_ALLOC_PAGES
        !           151: #define BROOKTREE_ALLOC_PAGES  217*4
        !           152: #endif
        !           153: #define BROOKTREE_ALLOC                (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
        !           154:
        !           155: /* Definitions for VBI capture.
        !           156:  * There are 16 VBI lines in a PAL video field (32 in a frame),
        !           157:  * and we take 2044 samples from each line (placed in a 2048 byte buffer
        !           158:  * for alignment).
        !           159:  * VBI lines are held in a circular buffer before being read by a
        !           160:  * user program from /dev/vbi.
        !           161:  */
        !           162:
        !           163: #define MAX_VBI_LINES        16   /* Maximum for all vidoe formats */
        !           164: #define VBI_LINE_SIZE         2048 /* Store upto 2048 bytes per line */
        !           165: #define VBI_BUFFER_ITEMS      20   /* Number of frames we buffer */
        !           166: #define VBI_DATA_SIZE         (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
        !           167: #define VBI_BUFFER_SIZE       (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
        !           168:
        !           169:
        !           170: /*  Defines for fields  */
        !           171: #define ODD_F  0x01
        !           172: #define EVEN_F 0x02
        !           173:
        !           174:
        !           175: /*
        !           176:  * Parameters describing size of transmitted image.
        !           177:  */
        !           178:
        !           179: static const struct format_params format_params[] = {
        !           180: /* # define BT848_IFORM_F_AUTO             (0x0) - don't matter. */
        !           181:   { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
        !           182:     12,  1600 },
        !           183: /* # define BT848_IFORM_F_NTSCM            (0x1) */
        !           184:   { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
        !           185:     12, 1600 },
        !           186: /* # define BT848_IFORM_F_NTSCJ            (0x2) */
        !           187:   { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
        !           188:     12, 1600 },
        !           189: /* # define BT848_IFORM_F_PALBDGHI         (0x3) */
        !           190:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
        !           191:     16,  2044 },
        !           192: /* # define BT848_IFORM_F_PALM             (0x4) */
        !           193:   { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
        !           194:     12, 1600 },
        !           195: /* # define BT848_IFORM_F_PALN             (0x5) */
        !           196:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
        !           197:     16, 2044 },
        !           198: /* # define BT848_IFORM_F_SECAM            (0x6) */
        !           199:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
        !           200:     16, 2044 },
        !           201: /* # define BT848_IFORM_F_RSVD             (0x7) - ???? */
        !           202:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
        !           203:     16, 2044 },
        !           204: };
        !           205:
        !           206: /*
        !           207:  * Table of supported Pixel Formats
        !           208:  */
        !           209:
        !           210: static const struct meteor_pixfmt_internal {
        !           211:        struct meteor_pixfmt public;
        !           212:        u_int                color_fmt;
        !           213: } pixfmt_table[] = {
        !           214:
        !           215: { { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 0,0 }, 0x33 },
        !           216: { { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 1,0 }, 0x33 },
        !           217:
        !           218: { { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 0,0 }, 0x22 },
        !           219: { { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 1,0 }, 0x22 },
        !           220:
        !           221: { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
        !           222:
        !           223: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
        !           224: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
        !           225: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
        !           226: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
        !           227: { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
        !           228: { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
        !           229: { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
        !           230:
        !           231: };
        !           232: #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
        !           233:
        !           234: /*
        !           235:  * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
        !           236:  */
        !           237:
        !           238: /*  FIXME:  Also add YUV_422 and YUV_PACKED as well  */
        !           239: static const struct {
        !           240:        u_int   meteor_format;
        !           241:        struct meteor_pixfmt public;
        !           242: } meteor_pixfmt_table[] = {
        !           243:     { METEOR_GEO_YUV_12,
        !           244:       { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
        !           245:     },
        !           246:
        !           247:       /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
        !           248:     { METEOR_GEO_YUV_422,
        !           249:       { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
        !           250:     },
        !           251:     { METEOR_GEO_YUV_PACKED,
        !           252:       { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
        !           253:     },
        !           254:     { METEOR_GEO_RGB16,
        !           255:       { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,   0x03e0,   0x001f }, 0, 0 }
        !           256:     },
        !           257:     { METEOR_GEO_RGB24,
        !           258:       { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
        !           259:     },
        !           260:
        !           261: };
        !           262: #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
        !           263:                                   sizeof(meteor_pixfmt_table[0]) )
        !           264:
        !           265:
        !           266: #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
        !           267: #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
        !           268:
        !           269:
        !           270:
        !           271: /* sync detect threshold */
        !           272: #if 0
        !           273: #define SYNC_LEVEL             (BT848_ADC_RESERVED |   \
        !           274:                                 BT848_ADC_CRUSH)       /* threshold ~125 mV */
        !           275: #else
        !           276: #define SYNC_LEVEL             (BT848_ADC_RESERVED |   \
        !           277:                                 BT848_ADC_SYNC_T)      /* threshold ~75 mV */
        !           278: #endif
        !           279:
        !           280:
        !           281:
        !           282:
        !           283: /* debug utility for holding previous INT_STAT contents */
        !           284: #undef STATUS_SUM
        !           285: #if defined( STATUS_SUM )
        !           286: static u_int   status_sum = 0;
        !           287: #endif
        !           288:
        !           289: /*
        !           290:  * defines to make certain bit-fiddles understandable
        !           291:  */
        !           292: #define FIFO_ENABLED           BT848_DMA_CTL_FIFO_EN
        !           293: #define RISC_ENABLED           BT848_DMA_CTL_RISC_EN
        !           294: #define FIFO_RISC_ENABLED      (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
        !           295: #define FIFO_RISC_DISABLED     0
        !           296:
        !           297: #define ALL_INTS_DISABLED      0
        !           298: #define ALL_INTS_CLEARED       0xffffffff
        !           299: #define CAPTURE_OFF            0
        !           300:
        !           301: #define BIT_SEVEN_HIGH         (1<<7)
        !           302: #define BIT_EIGHT_HIGH         (1<<8)
        !           303:
        !           304: #define I2C_BITS               (BT848_INT_RACK | BT848_INT_I2CDONE)
        !           305: #define TDEC_BITS               (BT848_INT_FDSR | BT848_INT_FBUS)
        !           306:
        !           307:
        !           308:
        !           309: static int             oformat_meteor_to_bt( u_int format );
        !           310:
        !           311: static u_int           pixfmt_swap_flags( int pixfmt );
        !           312:
        !           313: /*
        !           314:  * bt848 RISC programming routines.
        !           315:  */
        !           316: #ifdef BT848_DUMP
        !           317: static int     dump_bt848( bktr_ptr_t bktr );
        !           318: #endif
        !           319:
        !           320: static void    yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
        !           321:                              int rows,  int interlace );
        !           322: static void    yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
        !           323:                             int rows, int interlace );
        !           324: static void    yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
        !           325:                             int rows, int interlace );
        !           326: static void    rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
        !           327:                          int rows, int interlace );
        !           328: static void    rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
        !           329:                          int rows, int interlace );
        !           330: static void    build_dma_prog( bktr_ptr_t bktr, char i_flag );
        !           331:
        !           332: static bool_t   getline(bktr_reg_t *, int);
        !           333: static bool_t   notclipped(bktr_reg_t * , int , int);
        !           334: static bool_t   split(bktr_reg_t *, u_int **, int, u_int, int, u_int * , int);
        !           335:
        !           336: static void    start_capture( bktr_ptr_t bktr, unsigned type );
        !           337: static void    set_fps( bktr_ptr_t bktr, u_short fps );
        !           338:
        !           339:
        !           340:
        !           341: /*
        !           342:  * Remote Control Functions
        !           343:  */
        !           344: static void    remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
        !           345:
        !           346:
        !           347: /*
        !           348:  * ioctls common to both video & tuner.
        !           349:  */
        !           350: int    bktr_common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
        !           351:
        !           352:
        !           353: /*
        !           354:  * i2c primitives for low level control of i2c bus. Added for MSP34xx control
        !           355:  */
        !           356: static void     i2c_start( bktr_ptr_t bktr);
        !           357: static void     i2c_stop( bktr_ptr_t bktr);
        !           358: static int      i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
        !           359: static int      i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
        !           360:
        !           361: /*
        !           362:  * the common attach code, used by all OS versions.
        !           363:  */
        !           364: void
        !           365: common_bktr_attach( bktr_ptr_t bktr, int unit, u_int pci_id, u_int rev )
        !           366: {
        !           367:        vaddr_t buf = 0;
        !           368:
        !           369: /***************************************/
        !           370: /* *** OS Specific memory routines *** */
        !           371: /***************************************/
        !           372:         /* allocate space for dma program */
        !           373:         bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog, DMA_PROG_ALLOC);
        !           374:         bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
        !           375:            DMA_PROG_ALLOC);
        !           376:
        !           377:        /* allocate space for the VBI buffer */
        !           378:        bktr->vbidata  = get_bktr_mem(bktr, &bktr->dm_vbidata, VBI_DATA_SIZE);
        !           379:        bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
        !           380:            VBI_BUFFER_SIZE);
        !           381:
        !           382:         /* allocate space for pixel buffer */
        !           383:         if (BROOKTREE_ALLOC)
        !           384:                 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
        !           385:         else
        !           386:                 buf = 0;
        !           387:
        !           388:        if ( bootverbose ) {
        !           389:                printf("%s: buffer size %d, addr 0x%x\n",
        !           390:                        bktr_name(bktr), BROOKTREE_ALLOC,
        !           391:                        bktr->dm_prog->dm_segs->ds_addr);
        !           392:        }
        !           393:
        !           394:        if (buf != 0) {
        !           395:                bktr->bigbuf = buf;
        !           396:                bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
        !           397:                bzero((void *)bktr->bigbuf, BROOKTREE_ALLOC);
        !           398:        } else {
        !           399:                bktr->alloc_pages = 0;
        !           400:        }
        !           401:
        !           402:        bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
        !           403:                      METEOR_DEV0 | METEOR_RGB16;
        !           404:        bktr->dma_prog_loaded = FALSE;
        !           405:        bktr->cols = 640;
        !           406:        bktr->rows = 480;
        !           407:        bktr->frames = 1;               /* one frame */
        !           408:        bktr->format = METEOR_GEO_RGB16;
        !           409:        bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
        !           410:        bktr->pixfmt_compat = TRUE;
        !           411:
        !           412:        bktr->vbiinsert = 0;
        !           413:        bktr->vbistart = 0;
        !           414:        bktr->vbisize = 0;
        !           415:        bktr->vbiflags = 0;
        !           416:
        !           417:        /* using the pci device id and revision id */
        !           418:        /* and determine the card type            */
        !           419:        if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE) {
        !           420:                switch (PCI_PRODUCT(pci_id)) {
        !           421:                case PCI_PRODUCT_BROOKTREE_BT848:
        !           422:                        if (rev == 0x12)
        !           423:                                bktr->id = BROOKTREE_848A;
        !           424:                        else
        !           425:                                bktr->id = BROOKTREE_848;
        !           426:                        break;
        !           427:                case PCI_PRODUCT_BROOKTREE_BT849:
        !           428:                        bktr->id = BROOKTREE_849A;
        !           429:                        break;
        !           430:                case PCI_PRODUCT_BROOKTREE_BT878:
        !           431:                        bktr->id = BROOKTREE_878;
        !           432:                        break;
        !           433:                case PCI_PRODUCT_BROOKTREE_BT879:
        !           434:                        bktr->id = BROOKTREE_879;
        !           435:                        break;
        !           436:                }
        !           437:        }
        !           438:
        !           439:        bktr->clr_on_start = FALSE;
        !           440:
        !           441:        /* defaults for the tuner section of the card */
        !           442:        bktr->tflags = TUNER_INITALIZED;
        !           443:        bktr->tuner.frequency = 0;
        !           444:        bktr->tuner.channel = 0;
        !           445:        bktr->tuner.chnlset = DEFAULT_CHNLSET;
        !           446:        bktr->tuner.afc = 0;
        !           447:        bktr->tuner.radio_mode = 0;
        !           448:        bktr->audio_mux_select = 0;
        !           449:        bktr->audio_mute_state = FALSE;
        !           450:        bktr->bt848_card = -1;
        !           451:        bktr->bt848_tuner = -1;
        !           452:        bktr->reverse_mute = -1;
        !           453:        bktr->slow_msp_audio = 0;
        !           454:        bktr->msp_use_mono_source = 0;
        !           455:         bktr->msp_source_selected = -1;
        !           456:        bktr->audio_mux_present = 1;
        !           457:
        !           458:        probeCard(bktr, TRUE, unit);
        !           459:
        !           460:        /* enable drivers on the GPIO port that control the MUXes */
        !           461:        OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
        !           462:
        !           463:        /* mute the audio stream */
        !           464:        set_audio( bktr, AUDIO_MUTE );
        !           465:
        !           466:        /* Initialise any MSP34xx or TDA98xx audio chips */
        !           467:        init_audio_devices(bktr);
        !           468:
        !           469: }
        !           470:
        !           471:
        !           472: /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
        !           473:  * The circular buffer holds 'n' fixed size data blocks.
        !           474:  * vbisize   is the number of bytes in the circular buffer
        !           475:  * vbiread   is the point we reading data out of the circular buffer
        !           476:  * vbiinsert is the point we insert data into the circular buffer
        !           477:  */
        !           478: static void
        !           479: vbidecode(bktr_ptr_t bktr)
        !           480: {
        !           481:         unsigned char *dest;
        !           482:        unsigned int *seq_dest;
        !           483:
        !           484:        /* Check if there is room in the buffer to insert the data. */
        !           485:        if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
        !           486:
        !           487:        /* Copy the VBI data into the next free slot in the buffer. */
        !           488:        /* 'dest' is the point in vbibuffer where we want to insert new data */
        !           489:         dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
        !           490:         memcpy(dest, (unsigned char *)bktr->vbidata, VBI_DATA_SIZE);
        !           491:
        !           492:        /* Write the VBI sequence number to the end of the vbi data */
        !           493:        /* This is used by the AleVT teletext program */
        !           494:        seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
        !           495:                        + bktr->vbiinsert
        !           496:                        + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
        !           497:        *seq_dest = bktr->vbi_sequence_number;
        !           498:
        !           499:        /* And increase the VBI sequence number */
        !           500:        /* This can wrap around */
        !           501:        bktr->vbi_sequence_number++;
        !           502:
        !           503:        /* Increment the vbiinsert pointer */
        !           504:        /* This can wrap around */
        !           505:        bktr->vbiinsert += VBI_DATA_SIZE;
        !           506:        bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
        !           507:
        !           508:        /* And increase the amount of vbi data in the buffer */
        !           509:        bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
        !           510: }
        !           511:
        !           512:
        !           513: /*
        !           514:  * the common interrupt handler.
        !           515:  * Returns a 0 or 1 depending on whether the interrupt has handled.
        !           516:  * In the OS specific section, bktr_intr() is defined which calls this
        !           517:  * common interrupt handler.
        !           518:  */
        !           519: int
        !           520: common_bktr_intr( void *arg )
        !           521: {
        !           522:        bktr_ptr_t      bktr = (bktr_ptr_t) arg;
        !           523:        u_int   bktr_status;
        !           524:        u_char  dstatus;
        !           525:        u_int   field;
        !           526:        u_int   w_field;
        !           527:        u_int   req_field;
        !           528:
        !           529:        /*
        !           530:         * check to see if any interrupts are unmasked on this device.  If
        !           531:         * none are, then we likely got here by way of being on a PCI shared
        !           532:         * interrupt dispatch list.
        !           533:         */
        !           534:        if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
        !           535:                return 0;       /* bail out now, before we do something we
        !           536:                                   shouldn't */
        !           537:
        !           538:        if (!(bktr->flags & METEOR_OPEN)) {
        !           539:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
        !           540:                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
        !           541:                /* return; ?? */
        !           542:        }
        !           543:
        !           544:        /* record and clear the INTerrupt status bits */
        !           545:        bktr_status = INL(bktr, BKTR_INT_STAT);
        !           546:        OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS);     /* don't touch i2c */
        !           547:
        !           548:        /* record and clear the device status register */
        !           549:        dstatus = INB(bktr, BKTR_DSTATUS);
        !           550:        OUTB(bktr, BKTR_DSTATUS, 0x00);
        !           551:
        !           552: #if defined( STATUS_SUM )
        !           553:        /* add any new device status or INTerrupt status bits */
        !           554:        status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
        !           555:        status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
        !           556: #endif /* STATUS_SUM */
        !           557:        /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
        !           558:                dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
        !           559:        */
        !           560:
        !           561:
        !           562:        /* if risc was disabled re-start process again */
        !           563:        /* if there was one of the following errors re-start again */
        !           564:        if ( !(bktr_status & BT848_INT_RISC_EN) ||
        !           565:             ((bktr_status &(/* BT848_INT_FBUS   | */
        !           566:                             /* BT848_INT_FTRGT  | */
        !           567:                             /* BT848_INT_FDSR   | */
        !           568:                              BT848_INT_PPERR  |
        !           569:                              BT848_INT_RIPERR | BT848_INT_PABORT |
        !           570:                              BT848_INT_OCERR  | BT848_INT_SCERR) ) != 0)
        !           571:                || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
        !           572:
        !           573:                u_short tdec_save = INB(bktr, BKTR_TDEC);
        !           574:
        !           575:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
        !           576:                OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
        !           577:
        !           578:                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
        !           579:
        !           580:                /*  Reset temporal decimation counter  */
        !           581:                OUTB(bktr, BKTR_TDEC, 0);
        !           582:                OUTB(bktr, BKTR_TDEC, tdec_save);
        !           583:
        !           584:                /*  Reset to no-fields captured state  */
        !           585:                if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
        !           586:                        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
        !           587:                        case METEOR_ONLY_ODD_FIELDS:
        !           588:                                bktr->flags |= METEOR_WANT_ODD;
        !           589:                                break;
        !           590:                        case METEOR_ONLY_EVEN_FIELDS:
        !           591:                                bktr->flags |= METEOR_WANT_EVEN;
        !           592:                                break;
        !           593:                        default:
        !           594:                                bktr->flags |= METEOR_WANT_MASK;
        !           595:                                break;
        !           596:                        }
        !           597:                }
        !           598:
        !           599:                OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
        !           600:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
        !           601:                OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
        !           602:
        !           603:                OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
        !           604:                                    BT848_INT_RISCI      |
        !           605:                                    BT848_INT_VSYNC      |
        !           606:                                    BT848_INT_FMTCHG);
        !           607:
        !           608:                OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
        !           609:
        !           610:                add_video_randomness(tdec_save);
        !           611:
        !           612:                return 1;
        !           613:        }
        !           614:
        !           615:        /* If this is not a RISC program interrupt, return */
        !           616:        if (!(bktr_status & BT848_INT_RISCI))
        !           617:                return 0;
        !           618:
        !           619: /**
        !           620:        printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
        !           621:                bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
        !           622:  */
        !           623:
        !           624:        add_video_randomness(INL(bktr, BKTR_RISC_COUNT));
        !           625:
        !           626:        /*
        !           627:         * Disable future interrupts if a capture mode is not selected.
        !           628:         * This can happen when we are in the process of closing or
        !           629:         * changing capture modes, otherwise it shouldn't happen.
        !           630:         */
        !           631:        if (!(bktr->flags & METEOR_CAP_MASK))
        !           632:                OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
        !           633:
        !           634:        /* Determine which field generated this interrupt */
        !           635:        field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
        !           636:
        !           637:        /*
        !           638:         * Process the VBI data if it is being captured. We do this once
        !           639:         * both Odd and Even VBI data is captured. Therefore we do this
        !           640:         * in the Even field interrupt handler.
        !           641:         */
        !           642:        if ((bktr->vbiflags & (VBI_CAPTURE|VBI_OPEN)) ==
        !           643:            (VBI_CAPTURE|VBI_OPEN) && (field == EVEN_F)) {
        !           644:                /* Put VBI data into circular buffer */
        !           645:                vbidecode(bktr);
        !           646:
        !           647:                /* If someone is blocked on reading from /dev/vbi, wake them */
        !           648:                if (bktr->vbi_read_blocked) {
        !           649:                        bktr->vbi_read_blocked = FALSE;
        !           650:                        wakeup(VBI_SLEEP);
        !           651:                }
        !           652:
        !           653:                /* If someone has a select() on /dev/vbi, inform them */
        !           654: #ifndef __OpenBSD__
        !           655:                if (bktr->vbi_select.si_pid) {
        !           656: #else
        !           657:                if (bktr->vbi_select.si_selpid) {
        !           658: #endif
        !           659:                        selwakeup(&bktr->vbi_select);
        !           660:                }
        !           661:        }
        !           662:
        !           663:
        !           664:        /*
        !           665:         *  Register the completed field
        !           666:         *    (For dual-field mode, require fields from the same frame)
        !           667:         */
        !           668:        switch ( bktr->flags & METEOR_WANT_MASK ) {
        !           669:                case METEOR_WANT_ODD  : w_field = ODD_F         ;  break;
        !           670:                case METEOR_WANT_EVEN : w_field = EVEN_F        ;  break;
        !           671:                default               : w_field = (ODD_F|EVEN_F);  break;
        !           672:        }
        !           673:        switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
        !           674:                case METEOR_ONLY_ODD_FIELDS  : req_field = ODD_F  ;  break;
        !           675:                case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ;  break;
        !           676:                default                      : req_field = (ODD_F|EVEN_F);
        !           677:                                               break;
        !           678:        }
        !           679:
        !           680:        if (( field == EVEN_F ) && ( w_field == EVEN_F ))
        !           681:                bktr->flags &= ~METEOR_WANT_EVEN;
        !           682:        else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
        !           683:                 ( w_field == ODD_F ))
        !           684:                bktr->flags &= ~METEOR_WANT_ODD;
        !           685:        else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
        !           686:                 ( w_field == (ODD_F|EVEN_F) ))
        !           687:                bktr->flags &= ~METEOR_WANT_ODD;
        !           688:        else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
        !           689:                 ( w_field == ODD_F )) {
        !           690:                bktr->flags &= ~METEOR_WANT_ODD;
        !           691:                bktr->flags |=  METEOR_WANT_EVEN;
        !           692:        }
        !           693:        else {
        !           694:                /*  We're out of sync.  Start over.  */
        !           695:                if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
        !           696:                        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
        !           697:                        case METEOR_ONLY_ODD_FIELDS:
        !           698:                                bktr->flags |= METEOR_WANT_ODD;
        !           699:                                break;
        !           700:                        case METEOR_ONLY_EVEN_FIELDS:
        !           701:                                bktr->flags |= METEOR_WANT_EVEN;
        !           702:                                break;
        !           703:                        default:
        !           704:                                bktr->flags |= METEOR_WANT_MASK;
        !           705:                                break;
        !           706:                        }
        !           707:                }
        !           708:                return 1;
        !           709:        }
        !           710:
        !           711:        /*
        !           712:         * If we have a complete frame.
        !           713:         */
        !           714:        if (!(bktr->flags & METEOR_WANT_MASK)) {
        !           715:                bktr->frames_captured++;
        !           716:                /*
        !           717:                 * post the completion time.
        !           718:                 */
        !           719:                if (bktr->flags & METEOR_WANT_TS) {
        !           720:                        struct timeval *ts;
        !           721:
        !           722:                        if ((u_int) bktr->alloc_pages * PAGE_SIZE
        !           723:                           <= (bktr->frame_size + sizeof(struct timeval))) {
        !           724:                                ts =(struct timeval *)bktr->bigbuf +
        !           725:                                  bktr->frame_size;
        !           726:                                /* doesn't work in synch mode except
        !           727:                                 *  for first frame */
        !           728:                                /* XXX */
        !           729:                                microtime(ts);
        !           730:                        }
        !           731:                }
        !           732:
        !           733:
        !           734:                /*
        !           735:                 * Wake up the user in single capture mode.
        !           736:                 */
        !           737:                if (bktr->flags & METEOR_SINGLE) {
        !           738:
        !           739:                        /* stop dma */
        !           740:                        OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
        !           741:
        !           742:                        /* disable risc, leave fifo running */
        !           743:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
        !           744:                        wakeup(BKTR_SLEEP);
        !           745:                }
        !           746:
        !           747:                /*
        !           748:                 * If the user requested to be notified via signal,
        !           749:                 * let them know the frame is complete.
        !           750:                 */
        !           751:
        !           752:                if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK))
        !           753:                        psignal( bktr->proc,
        !           754:                                 bktr->signal&(~METEOR_SIG_MODE_MASK) );
        !           755:
        !           756:                /*
        !           757:                 * Reset the want flags if in continuous or
        !           758:                 * synchronous capture mode.
        !           759:                 */
        !           760: /*
        !           761: * XXX NOTE (Luigi):
        !           762: * currently we only support 3 capture modes: odd only, even only,
        !           763: * odd+even interlaced (odd field first). A fourth mode (non interlaced,
        !           764: * either even OR odd) could provide 60 (50 for PAL) pictures per
        !           765: * second, but it would require this routine to toggle the desired frame
        !           766: * each time, and one more different DMA program for the Bt848.
        !           767: * As a consequence, this fourth mode is currently unsupported.
        !           768: */
        !           769:
        !           770:                if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
        !           771:                        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
        !           772:                        case METEOR_ONLY_ODD_FIELDS:
        !           773:                                bktr->flags |= METEOR_WANT_ODD;
        !           774:                                break;
        !           775:                        case METEOR_ONLY_EVEN_FIELDS:
        !           776:                                bktr->flags |= METEOR_WANT_EVEN;
        !           777:                                break;
        !           778:                        default:
        !           779:                                bktr->flags |= METEOR_WANT_MASK;
        !           780:                                break;
        !           781:                        }
        !           782:                }
        !           783:        }
        !           784:
        !           785:        return 1;
        !           786: }
        !           787:
        !           788:
        !           789:
        !           790:
        !           791: /*
        !           792:  *
        !           793:  */
        !           794: extern int bt848_format; /* used to set the default format, PAL or NTSC */
        !           795: int
        !           796: video_open( bktr_ptr_t bktr )
        !           797: {
        !           798:        int frame_rate, video_format=0;
        !           799:
        !           800:        if (bktr->flags & METEOR_OPEN)          /* device is busy */
        !           801:                return( EBUSY );
        !           802:
        !           803:        bktr->flags |= METEOR_OPEN;
        !           804:
        !           805: #ifdef BT848_DUMP
        !           806:        dump_bt848( bt848 );
        !           807: #endif
        !           808:
        !           809:         bktr->clr_on_start = FALSE;
        !           810:
        !           811:        OUTB(bktr, BKTR_DSTATUS, 0x00);                 /* clear device status reg. */
        !           812:
        !           813:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
        !           814:
        !           815: #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
        !           816:        video_format = 0;
        !           817: #else
        !           818:        video_format = 1;
        !           819: #endif
        !           820:
        !           821:        if (bt848_format == 0 )
        !           822:          video_format = 0;
        !           823:
        !           824:        if (bt848_format == 1 )
        !           825:          video_format = 1;
        !           826:
        !           827:        if (video_format == 1 ) {
        !           828:          OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
        !           829:          bktr->format_params = BT848_IFORM_F_NTSCM;
        !           830:
        !           831:        } else {
        !           832:          OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
        !           833:          bktr->format_params = BT848_IFORM_F_PALBDGHI;
        !           834:
        !           835:        }
        !           836:
        !           837:        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) |
        !           838:            format_params[bktr->format_params].iform_xtsel);
        !           839:
        !           840:        /* work around for new Hauppauge 878 cards */
        !           841:        if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
        !           842:            (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
        !           843:                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
        !           844:        else
        !           845:                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
        !           846:
        !           847:        OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
        !           848:        OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
        !           849:        frame_rate    = format_params[bktr->format_params].frame_rate;
        !           850:
        !           851:        /* enable PLL mode using 28MHz crystal for PAL/SECAM users */
        !           852:        if (bktr->xtal_pll_mode == BT848_USE_PLL) {
        !           853:                OUTB(bktr, BKTR_TGCTRL, 0);
        !           854:                OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
        !           855:                OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
        !           856:                OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
        !           857:        }
        !           858:
        !           859:        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
        !           860:
        !           861:        bktr->max_clip_node = 0;
        !           862:
        !           863:        OUTB(bktr, BKTR_COLOR_CTL,
        !           864:            BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
        !           865:
        !           866:        OUTB(bktr, BKTR_E_HSCALE_LO, 170);
        !           867:        OUTB(bktr, BKTR_O_HSCALE_LO, 170);
        !           868:
        !           869:        OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
        !           870:        OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
        !           871:        OUTB(bktr, BKTR_E_SCLOOP, 0);
        !           872:        OUTB(bktr, BKTR_O_SCLOOP, 0);
        !           873:
        !           874:        OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
        !           875:        OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
        !           876:
        !           877:        bktr->fifo_errors = 0;
        !           878:        bktr->dma_errors = 0;
        !           879:        bktr->frames_captured = 0;
        !           880:        bktr->even_fields_captured = 0;
        !           881:        bktr->odd_fields_captured = 0;
        !           882:        bktr->proc = (struct proc *)0;
        !           883:        set_fps(bktr, frame_rate);
        !           884:        bktr->video.addr = 0;
        !           885:        bktr->video.width = 0;
        !           886:        bktr->video.banksize = 0;
        !           887:        bktr->video.ramsize = 0;
        !           888:        bktr->pixfmt_compat = TRUE;
        !           889:        bktr->format = METEOR_GEO_RGB16;
        !           890:        bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
        !           891:
        !           892:        bktr->capture_area_enabled = FALSE;
        !           893:
        !           894:        /* if you take this out triton-based mobos will operate unreliably */
        !           895:        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT);
        !           896:
        !           897:        return( 0 );
        !           898: }
        !           899:
        !           900: int
        !           901: vbi_open( bktr_ptr_t bktr )
        !           902: {
        !           903:        if (bktr->vbiflags & VBI_OPEN)          /* device is busy */
        !           904:                return( EBUSY );
        !           905:
        !           906:        bktr->vbiflags |= VBI_OPEN;
        !           907:
        !           908:        /* reset the VBI circular buffer pointers and clear the buffers */
        !           909:        bktr->vbiinsert = 0;
        !           910:        bktr->vbistart = 0;
        !           911:        bktr->vbisize = 0;
        !           912:        bktr->vbi_sequence_number = 0;
        !           913:        bktr->vbi_read_blocked = FALSE;
        !           914:
        !           915:        bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
        !           916:        bzero((caddr_t) bktr->vbidata,  VBI_DATA_SIZE);
        !           917:
        !           918:        return( 0 );
        !           919: }
        !           920:
        !           921: /*
        !           922:  *
        !           923:  */
        !           924: int
        !           925: tuner_open( bktr_ptr_t bktr )
        !           926: {
        !           927:        if ( !(bktr->tflags & TUNER_INITALIZED) )       /* device not found */
        !           928:                return( ENXIO );
        !           929:
        !           930:        if ( bktr->tflags & TUNER_OPEN )                /* already open */
        !           931:                return( 0 );
        !           932:
        !           933:        bktr->tflags |= TUNER_OPEN;
        !           934:
        !           935:        return( 0 );
        !           936: }
        !           937:
        !           938:
        !           939:
        !           940:
        !           941: /*
        !           942:  *
        !           943:  */
        !           944: int
        !           945: video_close( bktr_ptr_t bktr )
        !           946: {
        !           947:        bktr->flags &= ~(METEOR_OPEN     |
        !           948:                         METEOR_SINGLE   |
        !           949:                         METEOR_CAP_MASK |
        !           950:                         METEOR_WANT_MASK);
        !           951:
        !           952:        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
        !           953:        OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
        !           954:
        !           955:        bktr->dma_prog_loaded = FALSE;
        !           956:        OUTB(bktr, BKTR_TDEC, 0);
        !           957:        OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
        !           958:
        !           959: /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
        !           960:        OUTL(bktr, BKTR_SRESET, 0xf);
        !           961:        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
        !           962:
        !           963:        return( 0 );
        !           964: }
        !           965:
        !           966:
        !           967: /*
        !           968:  * tuner close handle,
        !           969:  *  place holder for tuner specific operations on a close.
        !           970:  */
        !           971: int
        !           972: tuner_close( bktr_ptr_t bktr )
        !           973: {
        !           974:        bktr->tflags &= ~TUNER_OPEN;
        !           975:
        !           976:        return( 0 );
        !           977: }
        !           978:
        !           979: int
        !           980: vbi_close( bktr_ptr_t bktr )
        !           981: {
        !           982:
        !           983:        bktr->vbiflags &= ~VBI_OPEN;
        !           984:
        !           985:        return( 0 );
        !           986: }
        !           987:
        !           988: /*
        !           989:  *
        !           990:  */
        !           991: int
        !           992: video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
        !           993: {
        !           994:         int             status;
        !           995:         int             count;
        !           996:
        !           997:
        !           998:        if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
        !           999:                return( ENOMEM );
        !          1000:
        !          1001:        if (bktr->flags & METEOR_CAP_MASK)
        !          1002:                return( EIO );  /* already capturing */
        !          1003:
        !          1004:         OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
        !          1005:
        !          1006:
        !          1007:        count = bktr->rows * bktr->cols *
        !          1008:                pixfmt_table[ bktr->pixfmt ].public.Bpp;
        !          1009:
        !          1010:        if ((int) uio->uio_iov->iov_len < count)
        !          1011:                return( EINVAL );
        !          1012:
        !          1013:        bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
        !          1014:
        !          1015:        /* capture one frame */
        !          1016:        start_capture(bktr, METEOR_SINGLE);
        !          1017:        /* wait for capture to complete */
        !          1018:        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
        !          1019:        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
        !          1020:        OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
        !          1021:        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
        !          1022:                             BT848_INT_RISCI      |
        !          1023:                             BT848_INT_VSYNC      |
        !          1024:                             BT848_INT_FMTCHG);
        !          1025:
        !          1026:
        !          1027:        status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
        !          1028:        if (!status)            /* successful capture */
        !          1029:                status = uiomove((caddr_t)bktr->bigbuf, count, uio);
        !          1030:        else
        !          1031:                printf ("%s: read: tsleep error %d\n",
        !          1032:                        bktr_name(bktr), status);
        !          1033:
        !          1034:        bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
        !          1035:
        !          1036:        return( status );
        !          1037: }
        !          1038:
        !          1039: /*
        !          1040:  * Read VBI data from the vbi circular buffer
        !          1041:  * The buffer holds vbi data blocks which are the same size
        !          1042:  * vbiinsert is the position we will insert the next item into the buffer
        !          1043:  * vbistart is the actual position in the buffer we want to read from
        !          1044:  * vbisize is the exact number of bytes in the buffer left to read
        !          1045:  */
        !          1046: int
        !          1047: vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
        !          1048: {
        !          1049:        int             readsize, readsize2;
        !          1050:        int             status;
        !          1051:
        !          1052:
        !          1053:        while(bktr->vbisize == 0) {
        !          1054:                if (ioflag & IO_NDELAY) {
        !          1055:                        return EWOULDBLOCK;
        !          1056:                }
        !          1057:
        !          1058:                bktr->vbi_read_blocked = TRUE;
        !          1059:                if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
        !          1060:                        return status;
        !          1061:                }
        !          1062:        }
        !          1063:
        !          1064:        /* Now we have some data to give to the user */
        !          1065:
        !          1066:        /* We cannot read more bytes than there are in
        !          1067:         * the circular buffer
        !          1068:         */
        !          1069:        readsize = (int)uio->uio_iov->iov_len;
        !          1070:
        !          1071:        if (readsize > bktr->vbisize) readsize = bktr->vbisize;
        !          1072:
        !          1073:        /* Check if we can read this number of bytes without having
        !          1074:         * to wrap around the circular buffer */
        !          1075:        if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
        !          1076:                /* We need to wrap around */
        !          1077:
        !          1078:                readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
        !          1079:                status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
        !          1080:                status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
        !          1081:        } else {
        !          1082:                /* We do not need to wrap around */
        !          1083:                status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
        !          1084:        }
        !          1085:
        !          1086:        /* Update the number of bytes left to read */
        !          1087:        bktr->vbisize -= readsize;
        !          1088:
        !          1089:        /* Update vbistart */
        !          1090:        bktr->vbistart += readsize;
        !          1091:        bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
        !          1092:
        !          1093:        return( status );
        !          1094:
        !          1095: }
        !          1096:
        !          1097:
        !          1098:
        !          1099: /*
        !          1100:  * video ioctls
        !          1101:  */
        !          1102: int
        !          1103: video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
        !          1104: {
        !          1105:        volatile u_char         c_temp;
        !          1106:        unsigned int            temp;
        !          1107:        unsigned int            temp_iform;
        !          1108:        unsigned int            error;
        !          1109:        struct meteor_geomet    *geo;
        !          1110:        struct meteor_counts    *counts;
        !          1111:        struct meteor_video     *video;
        !          1112:        struct bktr_capture_area *cap_area;
        !          1113:        vaddr_t                 buf;
        !          1114:        int                     i;
        !          1115:        char                    char_temp;
        !          1116:
        !          1117:        switch ( cmd ) {
        !          1118:
        !          1119:        case BT848SCLIP: /* set clip region */
        !          1120:            bktr->max_clip_node = 0;
        !          1121:            memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
        !          1122:
        !          1123:            for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
        !          1124:                if (bktr->clip_list[i].y_min ==  0 &&
        !          1125:                    bktr->clip_list[i].y_max == 0)
        !          1126:                    break;
        !          1127:            }
        !          1128:            bktr->max_clip_node = i;
        !          1129:
        !          1130:            /* make sure that the list contains a valid clip secquence */
        !          1131:            /* the clip rectangles should be sorted by x then by y as the
        !          1132:                second order sort key */
        !          1133:
        !          1134:            /* clip rectangle list is terminated by y_min and y_max set to 0 */
        !          1135:
        !          1136:            /* to disable clipping set  y_min and y_max to 0 in the first
        !          1137:                clip rectangle . The first clip rectangle is clip_list[0].
        !          1138:              */
        !          1139:
        !          1140:            if (bktr->max_clip_node == 0 &&
        !          1141:                (bktr->clip_list[0].y_min != 0 &&
        !          1142:                 bktr->clip_list[0].y_max != 0)) {
        !          1143:                return EINVAL;
        !          1144:            }
        !          1145:
        !          1146:            for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
        !          1147:                if (bktr->clip_list[i].y_min == 0 &&
        !          1148:                    bktr->clip_list[i].y_max == 0) {
        !          1149:                    break;
        !          1150:                }
        !          1151:                if ( bktr->clip_list[i+1].y_min != 0 &&
        !          1152:                     bktr->clip_list[i+1].y_max != 0 &&
        !          1153:                     bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
        !          1154:
        !          1155:                    bktr->max_clip_node = 0;
        !          1156:                    return (EINVAL);
        !          1157:
        !          1158:                 }
        !          1159:
        !          1160:                if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
        !          1161:                    bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
        !          1162:                    bktr->clip_list[i].x_min < 0 ||
        !          1163:                    bktr->clip_list[i].x_max < 0 ||
        !          1164:                    bktr->clip_list[i].y_min < 0 ||
        !          1165:                    bktr->clip_list[i].y_max < 0 ) {
        !          1166:                    bktr->max_clip_node = 0;
        !          1167:                    return (EINVAL);
        !          1168:                }
        !          1169:            }
        !          1170:
        !          1171:            bktr->dma_prog_loaded = FALSE;
        !          1172:
        !          1173:            break;
        !          1174:
        !          1175:        case METEORSTATUS:      /* get Bt848 status */
        !          1176:                c_temp = INB(bktr, BKTR_DSTATUS);
        !          1177:                temp = 0;
        !          1178:                if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
        !          1179:                if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
        !          1180:                *(u_short *)arg = temp;
        !          1181:                break;
        !          1182:
        !          1183:        case BT848SFMT:         /* set input format */
        !          1184:                temp = *(unsigned int *)arg & BT848_IFORM_FORMAT;
        !          1185:                temp_iform = INB(bktr, BKTR_IFORM);
        !          1186:                temp_iform &= ~BT848_IFORM_FORMAT;
        !          1187:                temp_iform &= ~BT848_IFORM_XTSEL;
        !          1188:                OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
        !          1189:                switch( temp ) {
        !          1190:                case BT848_IFORM_F_AUTO:
        !          1191:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
        !          1192:                        METEOR_AUTOMODE;
        !          1193:                        break;
        !          1194:
        !          1195:                case BT848_IFORM_F_NTSCM:
        !          1196:                case BT848_IFORM_F_NTSCJ:
        !          1197:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
        !          1198:                                METEOR_NTSC;
        !          1199:                        OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
        !          1200:                        OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
        !          1201:                        bktr->format_params = temp;
        !          1202:                        break;
        !          1203:
        !          1204:                case BT848_IFORM_F_PALBDGHI:
        !          1205:                case BT848_IFORM_F_PALN:
        !          1206:                case BT848_IFORM_F_SECAM:
        !          1207:                case BT848_IFORM_F_RSVD:
        !          1208:                case BT848_IFORM_F_PALM:
        !          1209:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
        !          1210:                                METEOR_PAL;
        !          1211:                        OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
        !          1212:                        OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
        !          1213:                        bktr->format_params = temp;
        !          1214:                        break;
        !          1215:
        !          1216:                }
        !          1217:                bktr->dma_prog_loaded = FALSE;
        !          1218:                break;
        !          1219:
        !          1220:        case METEORSFMT:        /* set input format */
        !          1221:                temp_iform = INB(bktr, BKTR_IFORM);
        !          1222:                temp_iform &= ~BT848_IFORM_FORMAT;
        !          1223:                temp_iform &= ~BT848_IFORM_XTSEL;
        !          1224:                switch(*(unsigned int *)arg & METEOR_FORM_MASK ) {
        !          1225:                case 0:         /* default */
        !          1226:                case METEOR_FMT_NTSC:
        !          1227:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
        !          1228:                                METEOR_NTSC;
        !          1229:                        OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
        !          1230:                                         format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
        !          1231:                        OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
        !          1232:                        OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
        !          1233:                        bktr->format_params = BT848_IFORM_F_NTSCM;
        !          1234:                        break;
        !          1235:
        !          1236:                case METEOR_FMT_PAL:
        !          1237:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
        !          1238:                                METEOR_PAL;
        !          1239:                        OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
        !          1240:                                         format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
        !          1241:                        OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
        !          1242:                        OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
        !          1243:                        bktr->format_params = BT848_IFORM_F_PALBDGHI;
        !          1244:                        break;
        !          1245:
        !          1246:                case METEOR_FMT_AUTOMODE:
        !          1247:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
        !          1248:                                METEOR_AUTOMODE;
        !          1249:                        OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
        !          1250:                                         format_params[BT848_IFORM_F_AUTO].iform_xtsel);
        !          1251:                        break;
        !          1252:
        !          1253:                default:
        !          1254:                        return( EINVAL );
        !          1255:                }
        !          1256:                bktr->dma_prog_loaded = FALSE;
        !          1257:                break;
        !          1258:
        !          1259:        case METEORGFMT:        /* get input format */
        !          1260:                *(u_int *)arg = bktr->flags & METEOR_FORM_MASK;
        !          1261:                break;
        !          1262:
        !          1263:
        !          1264:        case BT848GFMT:         /* get input format */
        !          1265:                *(u_int *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
        !          1266:                break;
        !          1267:
        !          1268:        case METEORSCOUNT:      /* (re)set error counts */
        !          1269:                counts = (struct meteor_counts *) arg;
        !          1270:                bktr->fifo_errors = counts->fifo_errors;
        !          1271:                bktr->dma_errors = counts->dma_errors;
        !          1272:                bktr->frames_captured = counts->frames_captured;
        !          1273:                bktr->even_fields_captured = counts->even_fields_captured;
        !          1274:                bktr->odd_fields_captured = counts->odd_fields_captured;
        !          1275:                break;
        !          1276:
        !          1277:        case METEORGCOUNT:      /* get error counts */
        !          1278:                counts = (struct meteor_counts *) arg;
        !          1279:                counts->fifo_errors = bktr->fifo_errors;
        !          1280:                counts->dma_errors = bktr->dma_errors;
        !          1281:                counts->frames_captured = bktr->frames_captured;
        !          1282:                counts->even_fields_captured = bktr->even_fields_captured;
        !          1283:                counts->odd_fields_captured = bktr->odd_fields_captured;
        !          1284:                break;
        !          1285:
        !          1286:        case METEORGVIDEO:
        !          1287:                video = (struct meteor_video *)arg;
        !          1288:                video->addr = bktr->video.addr;
        !          1289:                video->width = bktr->video.width;
        !          1290:                video->banksize = bktr->video.banksize;
        !          1291:                video->ramsize = bktr->video.ramsize;
        !          1292:                break;
        !          1293:
        !          1294:        case METEORSVIDEO:
        !          1295:                video = (struct meteor_video *)arg;
        !          1296:                bktr->video.addr = video->addr;
        !          1297:                bktr->video.width = video->width;
        !          1298:                bktr->video.banksize = video->banksize;
        !          1299:                bktr->video.ramsize = video->ramsize;
        !          1300:                break;
        !          1301:
        !          1302:        case METEORSFPS:
        !          1303:                set_fps(bktr, *(u_short *)arg);
        !          1304:                break;
        !          1305:
        !          1306:        case METEORGFPS:
        !          1307:                *(u_short *)arg = bktr->fps;
        !          1308:                break;
        !          1309:
        !          1310:        case METEORSHUE:        /* set hue */
        !          1311:                OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
        !          1312:                break;
        !          1313:
        !          1314:        case METEORGHUE:        /* get hue */
        !          1315:                *(u_char *)arg = INB(bktr, BKTR_HUE);
        !          1316:                break;
        !          1317:
        !          1318:        case METEORSBRIG:       /* set brightness */
        !          1319:                char_temp =    ( *(u_char *)arg & 0xff) - 128;
        !          1320:                OUTB(bktr, BKTR_BRIGHT, char_temp);
        !          1321:
        !          1322:                break;
        !          1323:
        !          1324:        case METEORGBRIG:       /* get brightness */
        !          1325:                *(u_char *)arg = INB(bktr, BKTR_BRIGHT) + 128;
        !          1326:                break;
        !          1327:
        !          1328:        case METEORSCSAT:       /* set chroma saturation */
        !          1329:                temp = (int)*(u_char *)arg;
        !          1330:
        !          1331:                OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
        !          1332:                OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
        !          1333:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
        !          1334:                                     & ~(BT848_E_CONTROL_SAT_U_MSB
        !          1335:                                         | BT848_E_CONTROL_SAT_V_MSB));
        !          1336:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
        !          1337:                                     & ~(BT848_O_CONTROL_SAT_U_MSB |
        !          1338:                                         BT848_O_CONTROL_SAT_V_MSB));
        !          1339:
        !          1340:                if ( temp & BIT_SEVEN_HIGH ) {
        !          1341:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
        !          1342:                                             | (BT848_E_CONTROL_SAT_U_MSB
        !          1343:                                                | BT848_E_CONTROL_SAT_V_MSB));
        !          1344:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
        !          1345:                                             | (BT848_O_CONTROL_SAT_U_MSB
        !          1346:                                                | BT848_O_CONTROL_SAT_V_MSB));
        !          1347:                }
        !          1348:                break;
        !          1349:
        !          1350:        case METEORGCSAT:       /* get chroma saturation */
        !          1351:                temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
        !          1352:                if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
        !          1353:                        temp |= BIT_SEVEN_HIGH;
        !          1354:                *(u_char *)arg = (u_char)temp;
        !          1355:                break;
        !          1356:
        !          1357:        case METEORSCONT:       /* set contrast */
        !          1358:                temp = (int)*(u_char *)arg & 0xff;
        !          1359:                temp <<= 1;
        !          1360:                OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
        !          1361:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
        !          1362:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
        !          1363:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
        !          1364:                        (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
        !          1365:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
        !          1366:                        (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
        !          1367:                break;
        !          1368:
        !          1369:        case METEORGCONT:       /* get contrast */
        !          1370:                temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
        !          1371:                temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
        !          1372:                *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
        !          1373:                break;
        !          1374:
        !          1375:        case BT848SCBUF:        /* set Clear-Buffer-on-start flag */
        !          1376:                bktr->clr_on_start = (*(int *)arg != 0);
        !          1377:                break;
        !          1378:
        !          1379:        case BT848GCBUF:        /* get Clear-Buffer-on-start flag */
        !          1380:                *(int *)arg = (int) bktr->clr_on_start;
        !          1381:                break;
        !          1382:
        !          1383:        case METEORSSIGNAL:
        !          1384:                if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
        !          1385:                        return( EINVAL );
        !          1386:                        break;
        !          1387:                }
        !          1388:                bktr->signal = *(int *) arg;
        !          1389:                bktr->proc = pr;
        !          1390:                break;
        !          1391:
        !          1392:        case METEORGSIGNAL:
        !          1393:                *(int *)arg = bktr->signal;
        !          1394:                break;
        !          1395:
        !          1396:        case METEORCAPTUR:
        !          1397:                temp = bktr->flags;
        !          1398:                switch (*(int *) arg) {
        !          1399:                case METEOR_CAP_SINGLE:
        !          1400:
        !          1401:                        if (bktr->bigbuf==0)    /* no frame buffer allocated */
        !          1402:                                return( ENOMEM );
        !          1403:                        /* already capturing */
        !          1404:                        if (temp & METEOR_CAP_MASK)
        !          1405:                                return( EIO );
        !          1406:
        !          1407:
        !          1408:
        !          1409:                        start_capture(bktr, METEOR_SINGLE);
        !          1410:
        !          1411:                        /* wait for capture to complete */
        !          1412:                        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
        !          1413:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
        !          1414:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
        !          1415:
        !          1416:                        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
        !          1417:                                            BT848_INT_RISCI      |
        !          1418:                                            BT848_INT_VSYNC      |
        !          1419:                                            BT848_INT_FMTCHG);
        !          1420:
        !          1421:                        OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
        !          1422:                        error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
        !          1423:                        if (error && (error != ERESTART)) {
        !          1424:                                /*  Here if we didn't get complete frame  */
        !          1425: #ifdef DIAGNOSTIC
        !          1426:                                printf( "%s: ioctl: tsleep error %d %x\n",
        !          1427:                                        bktr_name(bktr), error,
        !          1428:                                        INL(bktr, BKTR_RISC_COUNT));
        !          1429: #endif
        !          1430:
        !          1431:                                /* stop dma */
        !          1432:                                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
        !          1433:
        !          1434:                                /* disable risc, leave fifo running */
        !          1435:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
        !          1436:                        }
        !          1437:
        !          1438:                        bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
        !          1439:                        /* FIXME: should we set bt848->int_stat ??? */
        !          1440:                        break;
        !          1441:
        !          1442:                case METEOR_CAP_CONTINOUS:
        !          1443:                        if (bktr->bigbuf == 0)  /* no frame buffer allocated */
        !          1444:                                return (ENOMEM);
        !          1445:                        /* already capturing */
        !          1446:                        if (temp & METEOR_CAP_MASK)
        !          1447:                            return( EIO );
        !          1448:
        !          1449:
        !          1450:                        start_capture(bktr, METEOR_CONTIN);
        !          1451:
        !          1452:                        /* Clear the interrupt status register */
        !          1453:                        OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
        !          1454:
        !          1455:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
        !          1456:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
        !          1457:                        OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
        !          1458:
        !          1459:                        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
        !          1460:                                            BT848_INT_RISCI      |
        !          1461:                                            BT848_INT_VSYNC      |
        !          1462:                                            BT848_INT_FMTCHG);
        !          1463: #ifdef BT848_DUMP
        !          1464:                        dump_bt848( bt848 );
        !          1465: #endif
        !          1466:                        break;
        !          1467:
        !          1468:                case METEOR_CAP_STOP_CONT:
        !          1469:                        if (bktr->flags & METEOR_CONTIN) {
        !          1470:                                /* turn off capture */
        !          1471:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
        !          1472:                                OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
        !          1473:                                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
        !          1474:                                bktr->flags &=
        !          1475:                                        ~(METEOR_CONTIN | METEOR_WANT_MASK);
        !          1476:
        !          1477:                        }
        !          1478:                }
        !          1479:                break;
        !          1480:
        !          1481:        case METEORSETGEO:
        !          1482:                /* can't change parameters while capturing */
        !          1483:                if (bktr->flags & METEOR_CAP_MASK)
        !          1484:                        return( EBUSY );
        !          1485:
        !          1486:
        !          1487:                geo = (struct meteor_geomet *) arg;
        !          1488:
        !          1489:                error = 0;
        !          1490:                /* Either even or odd, if even & odd, then these a zero */
        !          1491:                if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
        !          1492:                        (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
        !          1493:                        printf( "%s: ioctl: Geometry odd or even only.\n",
        !          1494:                                bktr_name(bktr));
        !          1495:                        return( EINVAL );
        !          1496:                }
        !          1497:
        !          1498:                /* set/clear even/odd flags */
        !          1499:                if (geo->oformat & METEOR_GEO_ODD_ONLY)
        !          1500:                        bktr->flags |= METEOR_ONLY_ODD_FIELDS;
        !          1501:                else
        !          1502:                        bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
        !          1503:                if (geo->oformat & METEOR_GEO_EVEN_ONLY)
        !          1504:                        bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
        !          1505:                else
        !          1506:                        bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
        !          1507:
        !          1508:                if (geo->columns <= 0) {
        !          1509:                        printf(
        !          1510:                        "%s: ioctl: %d: columns must be greater than zero.\n",
        !          1511:                                bktr_name(bktr), geo->columns);
        !          1512:                        error = EINVAL;
        !          1513:                }
        !          1514:                else if ((geo->columns & 0x3fe) != geo->columns) {
        !          1515:                        printf(
        !          1516:                        "%s: ioctl: %d: columns too large or not even.\n",
        !          1517:                                bktr_name(bktr), geo->columns);
        !          1518:                        error = EINVAL;
        !          1519:                }
        !          1520:
        !          1521:                if (geo->rows <= 0) {
        !          1522:                        printf(
        !          1523:                        "%s: ioctl: %d: rows must be greater than zero.\n",
        !          1524:                                bktr_name(bktr), geo->rows);
        !          1525:                        error = EINVAL;
        !          1526:                }
        !          1527:                else if (((geo->rows & 0x7fe) != geo->rows) ||
        !          1528:                        ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
        !          1529:                                ((geo->rows & 0x3fe) != geo->rows)) ) {
        !          1530:                        printf(
        !          1531:                        "%s: ioctl: %d: rows too large or not even.\n",
        !          1532:                                bktr_name(bktr), geo->rows);
        !          1533:                        error = EINVAL;
        !          1534:                }
        !          1535:
        !          1536:                if (geo->frames > 32) {
        !          1537:                        printf("%s: ioctl: too many frames.\n",
        !          1538:                               bktr_name(bktr));
        !          1539:
        !          1540:                        error = EINVAL;
        !          1541:                }
        !          1542:
        !          1543:                if (error)
        !          1544:                        return( error );
        !          1545:
        !          1546:                bktr->dma_prog_loaded = FALSE;
        !          1547:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
        !          1548:
        !          1549:                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
        !          1550:
        !          1551:                if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
        !          1552:                        if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
        !          1553:
        !          1554:                        /* meteor_mem structure for SYNC Capture */
        !          1555:                        if (geo->frames > 1) temp += PAGE_SIZE;
        !          1556:
        !          1557:                        temp = btoc(temp);
        !          1558:                        if ((int) temp > bktr->alloc_pages
        !          1559:                            && bktr->video.addr == 0) {
        !          1560:
        !          1561: /*****************************/
        !          1562: /* *** OS Dependant code *** */
        !          1563: /*****************************/
        !          1564:                                 bus_dmamap_t dmamap;
        !          1565:
        !          1566:                                 buf = get_bktr_mem(bktr, &dmamap,
        !          1567:                                                    temp * PAGE_SIZE);
        !          1568:                                 if (buf != 0) {
        !          1569:                                         free_bktr_mem(bktr, bktr->dm_mem,
        !          1570:                                                       bktr->bigbuf);
        !          1571:                                         bktr->dm_mem = dmamap;
        !          1572:                                        bktr->bigbuf = buf;
        !          1573:                                        bktr->alloc_pages = temp;
        !          1574:                                        if (bootverbose)
        !          1575:                                                printf("%s: ioctl: "
        !          1576:                                                    "Allocating %d bytes\n",
        !          1577:                                                    bktr_name(bktr),
        !          1578:                                                    temp * PAGE_SIZE);
        !          1579:                                } else
        !          1580:                                        error = ENOMEM;
        !          1581:                        }
        !          1582:                }
        !          1583:
        !          1584:                if (error)
        !          1585:                        return error;
        !          1586:
        !          1587:                bktr->rows = geo->rows;
        !          1588:                bktr->cols = geo->columns;
        !          1589:                bktr->frames = geo->frames;
        !          1590:
        !          1591:                /*  Pixel format (if in meteor pixfmt compatibility mode)  */
        !          1592:                if ( bktr->pixfmt_compat ) {
        !          1593:                        bktr->format = METEOR_GEO_YUV_422;
        !          1594:                        switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
        !          1595:                        case 0:                 /* default */
        !          1596:                        case METEOR_GEO_RGB16:
        !          1597:                                    bktr->format = METEOR_GEO_RGB16;
        !          1598:                                    break;
        !          1599:                        case METEOR_GEO_RGB24:
        !          1600:                                    bktr->format = METEOR_GEO_RGB24;
        !          1601:                                    break;
        !          1602:                        case METEOR_GEO_YUV_422:
        !          1603:                                    bktr->format = METEOR_GEO_YUV_422;
        !          1604:                                     if (geo->oformat & METEOR_GEO_YUV_12)
        !          1605:                                        bktr->format = METEOR_GEO_YUV_12;
        !          1606:                                    break;
        !          1607:                        case METEOR_GEO_YUV_PACKED:
        !          1608:                                    bktr->format = METEOR_GEO_YUV_PACKED;
        !          1609:                                    break;
        !          1610:                        }
        !          1611:                        bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
        !          1612:                }
        !          1613:
        !          1614:                if (bktr->flags & METEOR_CAP_MASK) {
        !          1615:
        !          1616:                        if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
        !          1617:                                switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
        !          1618:                                case METEOR_ONLY_ODD_FIELDS:
        !          1619:                                        bktr->flags |= METEOR_WANT_ODD;
        !          1620:                                        break;
        !          1621:                                case METEOR_ONLY_EVEN_FIELDS:
        !          1622:                                        bktr->flags |= METEOR_WANT_EVEN;
        !          1623:                                        break;
        !          1624:                                default:
        !          1625:                                        bktr->flags |= METEOR_WANT_MASK;
        !          1626:                                        break;
        !          1627:                                }
        !          1628:
        !          1629:                                start_capture(bktr, METEOR_CONTIN);
        !          1630:                                OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
        !          1631:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
        !          1632:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
        !          1633:                                OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
        !          1634:                                                    BT848_INT_VSYNC      |
        !          1635:                                                    BT848_INT_FMTCHG);
        !          1636:                        }
        !          1637:                }
        !          1638:                break;
        !          1639:        /* end of METEORSETGEO */
        !          1640:
        !          1641:        /* FIXME. The Capture Area currently has the following restrictions:
        !          1642:        GENERAL
        !          1643:         y_offset may need to be even in interlaced modes
        !          1644:        RGB24 - Interlaced mode
        !          1645:         x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
        !          1646:         y_size must be greater than or equal to METEORSETGEO height (rows)
        !          1647:        RGB24 - Even Only (or Odd Only) mode
        !          1648:         x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
        !          1649:         y_size must be greater than or equal to 2*METEORSETGEO height (rows)
        !          1650:        YUV12 - Interlaced mode
        !          1651:         x_size must be greater than or equal to METEORSETGEO width (cols)
        !          1652:         y_size must be greater than or equal to METEORSETGEO height (rows)
        !          1653:        YUV12 - Even Only (or Odd Only) mode
        !          1654:         x_size must be greater than or equal to METEORSETGEO width (cols)
        !          1655:         y_size must be greater than or equal to 2*METEORSETGEO height (rows)
        !          1656:        */
        !          1657:
        !          1658:        case BT848_SCAPAREA: /* set capture area of each video frame */
        !          1659:                /* can't change parameters while capturing */
        !          1660:                if (bktr->flags & METEOR_CAP_MASK)
        !          1661:                        return( EBUSY );
        !          1662:
        !          1663:                cap_area = (struct bktr_capture_area *) arg;
        !          1664:                bktr->capture_area_x_offset = cap_area->x_offset;
        !          1665:                bktr->capture_area_y_offset = cap_area->y_offset;
        !          1666:                bktr->capture_area_x_size   = cap_area->x_size;
        !          1667:                bktr->capture_area_y_size   = cap_area->y_size;
        !          1668:                bktr->capture_area_enabled  = TRUE;
        !          1669:
        !          1670:                bktr->dma_prog_loaded = FALSE;
        !          1671:                break;
        !          1672:
        !          1673:        case BT848_GCAPAREA: /* get capture area of each video frame */
        !          1674:                cap_area = (struct bktr_capture_area *) arg;
        !          1675:                if (bktr->capture_area_enabled == FALSE) {
        !          1676:                        cap_area->x_offset = 0;
        !          1677:                        cap_area->y_offset = 0;
        !          1678:                        cap_area->x_size   = format_params[
        !          1679:                                bktr->format_params].scaled_hactive;
        !          1680:                        cap_area->y_size   = format_params[
        !          1681:                                bktr->format_params].vactive;
        !          1682:                } else {
        !          1683:                        cap_area->x_offset = bktr->capture_area_x_offset;
        !          1684:                        cap_area->y_offset = bktr->capture_area_y_offset;
        !          1685:                        cap_area->x_size   = bktr->capture_area_x_size;
        !          1686:                        cap_area->y_size   = bktr->capture_area_y_size;
        !          1687:                }
        !          1688:                break;
        !          1689:
        !          1690:        default:
        !          1691:                return bktr_common_ioctl( bktr, cmd, arg );
        !          1692:        }
        !          1693:
        !          1694:        return( 0 );
        !          1695: }
        !          1696:
        !          1697: /*
        !          1698:  * tuner ioctls
        !          1699:  */
        !          1700: int
        !          1701: tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
        !          1702: {
        !          1703:        int             tmp_int;
        !          1704:        unsigned int    temp, temp1;
        !          1705:        int             offset;
        !          1706:        int             count;
        !          1707:        u_char          *buf;
        !          1708:        u_int           par;
        !          1709:        u_char          write;
        !          1710:        int             i2c_addr;
        !          1711:        int             i2c_port;
        !          1712:        u_int           data;
        !          1713:
        !          1714:        switch ( cmd ) {
        !          1715:
        !          1716:        case REMOTE_GETKEY:
        !          1717:                /* Read the last key pressed by the Remote Control */
        !          1718:                if (bktr->remote_control == 0) return (EINVAL);
        !          1719:                remote_read(bktr, (struct bktr_remote *)arg);
        !          1720:                break;
        !          1721:
        !          1722: #if defined(TUNER_AFC)
        !          1723:        case TVTUNER_SETAFC:
        !          1724:                bktr->tuner.afc = (*(int *)arg != 0);
        !          1725:                break;
        !          1726:
        !          1727:        case TVTUNER_GETAFC:
        !          1728:                *(int *)arg = bktr->tuner.afc;
        !          1729:                /* XXX Perhaps use another bit to indicate AFC success? */
        !          1730:                break;
        !          1731: #endif /* TUNER_AFC */
        !          1732:
        !          1733:        case TVTUNER_SETCHNL:
        !          1734:                temp_mute( bktr, TRUE );
        !          1735:                temp = tv_channel( bktr, (int)*(unsigned int *)arg );
        !          1736:                if ( temp < 0 ) {
        !          1737:                        temp_mute( bktr, FALSE );
        !          1738:                        return( EINVAL );
        !          1739:                }
        !          1740:                *(unsigned int *)arg = temp;
        !          1741:
        !          1742:                /* after every channel change, we must restart the MSP34xx */
        !          1743:                /* audio chip to reselect NICAM STEREO or MONO audio */
        !          1744:                if ( bktr->card.msp3400c )
        !          1745:                  msp_autodetect( bktr );
        !          1746:
        !          1747:                /* after every channel change, we must restart the DPL35xx */
        !          1748:                if ( bktr->card.dpl3518a )
        !          1749:                  dpl_autodetect( bktr );
        !          1750:
        !          1751:                temp_mute( bktr, FALSE );
        !          1752:                break;
        !          1753:
        !          1754:        case TVTUNER_GETCHNL:
        !          1755:                *(unsigned int *)arg = bktr->tuner.channel;
        !          1756:                break;
        !          1757:
        !          1758:        case TVTUNER_SETTYPE:
        !          1759:                temp = *(unsigned int *)arg;
        !          1760:                if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
        !          1761:                        return( EINVAL );
        !          1762:                bktr->tuner.chnlset = temp;
        !          1763:                break;
        !          1764:
        !          1765:        case TVTUNER_GETTYPE:
        !          1766:                *(unsigned int *)arg = bktr->tuner.chnlset;
        !          1767:                break;
        !          1768:
        !          1769:        case TVTUNER_GETSTATUS:
        !          1770:                temp = get_tuner_status( bktr );
        !          1771:                *(unsigned int *)arg = temp & 0xff;
        !          1772:                break;
        !          1773:
        !          1774:        case TVTUNER_SETFREQ:
        !          1775:                temp_mute( bktr, TRUE );
        !          1776:                temp = tv_freq( bktr, (int)*(unsigned int *)arg, TV_FREQUENCY);
        !          1777:                temp_mute( bktr, FALSE );
        !          1778:                if ( temp < 0 ) {
        !          1779:                        temp_mute( bktr, FALSE );
        !          1780:                        return( EINVAL );
        !          1781:                }
        !          1782:                *(unsigned int *)arg = temp;
        !          1783:
        !          1784:                /* after every channel change, we must restart the MSP34xx */
        !          1785:                /* audio chip to reselect NICAM STEREO or MONO audio */
        !          1786:                if ( bktr->card.msp3400c )
        !          1787:                  msp_autodetect( bktr );
        !          1788:
        !          1789:                /* after every channel change, we must restart the DPL35xx */
        !          1790:                if ( bktr->card.dpl3518a )
        !          1791:                  dpl_autodetect( bktr );
        !          1792:
        !          1793:                temp_mute( bktr, FALSE );
        !          1794:                break;
        !          1795:
        !          1796:        case TVTUNER_GETFREQ:
        !          1797:                *(unsigned int *)arg = bktr->tuner.frequency;
        !          1798:                break;
        !          1799:
        !          1800:        case TVTUNER_GETCHNLSET:
        !          1801:                return tuner_getchnlset((struct bktr_chnlset *)arg);
        !          1802:
        !          1803:        case BT848_SAUDIO:      /* set audio channel */
        !          1804:                if ( set_audio( bktr, *(int *)arg ) < 0 )
        !          1805:                        return( EIO );
        !          1806:                break;
        !          1807:
        !          1808:        /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
        !          1809:        case BT848_SHUE:        /* set hue */
        !          1810:                OUTB(bktr, BKTR_HUE, (u_char)(*(int *)arg & 0xff));
        !          1811:                break;
        !          1812:
        !          1813:        case BT848_GHUE:        /* get hue */
        !          1814:                *(int *)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
        !          1815:                break;
        !          1816:
        !          1817:        /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
        !          1818:        case BT848_SBRIG:       /* set brightness */
        !          1819:                OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
        !          1820:                break;
        !          1821:
        !          1822:        case BT848_GBRIG:       /* get brightness */
        !          1823:                *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
        !          1824:                break;
        !          1825:
        !          1826:        /*  */
        !          1827:        case BT848_SCSAT:       /* set chroma saturation */
        !          1828:                tmp_int = *(int *)arg;
        !          1829:
        !          1830:                temp = INB(bktr, BKTR_E_CONTROL);
        !          1831:                temp1 = INB(bktr, BKTR_O_CONTROL);
        !          1832:                if ( tmp_int & BIT_EIGHT_HIGH ) {
        !          1833:                        temp |= (BT848_E_CONTROL_SAT_U_MSB |
        !          1834:                                 BT848_E_CONTROL_SAT_V_MSB);
        !          1835:                        temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
        !          1836:                                  BT848_O_CONTROL_SAT_V_MSB);
        !          1837:                }
        !          1838:                else {
        !          1839:                        temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
        !          1840:                                  BT848_E_CONTROL_SAT_V_MSB);
        !          1841:                        temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
        !          1842:                                   BT848_O_CONTROL_SAT_V_MSB);
        !          1843:                }
        !          1844:
        !          1845:                OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
        !          1846:                OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
        !          1847:                OUTB(bktr, BKTR_E_CONTROL, temp);
        !          1848:                OUTB(bktr, BKTR_O_CONTROL, temp1);
        !          1849:                break;
        !          1850:
        !          1851:        case BT848_GCSAT:       /* get chroma saturation */
        !          1852:                tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
        !          1853:                if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
        !          1854:                        tmp_int |= BIT_EIGHT_HIGH;
        !          1855:                *(int *)arg = tmp_int;
        !          1856:                break;
        !          1857:
        !          1858:        /*  */
        !          1859:        case BT848_SVSAT:       /* set chroma V saturation */
        !          1860:                tmp_int = *(int *)arg;
        !          1861:
        !          1862:                temp = INB(bktr, BKTR_E_CONTROL);
        !          1863:                temp1 = INB(bktr, BKTR_O_CONTROL);
        !          1864:                if ( tmp_int & BIT_EIGHT_HIGH) {
        !          1865:                        temp |= BT848_E_CONTROL_SAT_V_MSB;
        !          1866:                        temp1 |= BT848_O_CONTROL_SAT_V_MSB;
        !          1867:                }
        !          1868:                else {
        !          1869:                        temp &= ~BT848_E_CONTROL_SAT_V_MSB;
        !          1870:                        temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
        !          1871:                }
        !          1872:
        !          1873:                OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
        !          1874:                OUTB(bktr, BKTR_E_CONTROL, temp);
        !          1875:                OUTB(bktr, BKTR_O_CONTROL, temp1);
        !          1876:                break;
        !          1877:
        !          1878:        case BT848_GVSAT:       /* get chroma V saturation */
        !          1879:                tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
        !          1880:                if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
        !          1881:                        tmp_int |= BIT_EIGHT_HIGH;
        !          1882:                *(int *)arg = tmp_int;
        !          1883:                break;
        !          1884:
        !          1885:        /*  */
        !          1886:        case BT848_SUSAT:       /* set chroma U saturation */
        !          1887:                tmp_int = *(int *)arg;
        !          1888:
        !          1889:                temp = INB(bktr, BKTR_E_CONTROL);
        !          1890:                temp1 = INB(bktr, BKTR_O_CONTROL);
        !          1891:                if ( tmp_int & BIT_EIGHT_HIGH ) {
        !          1892:                        temp |= BT848_E_CONTROL_SAT_U_MSB;
        !          1893:                        temp1 |= BT848_O_CONTROL_SAT_U_MSB;
        !          1894:                }
        !          1895:                else {
        !          1896:                        temp &= ~BT848_E_CONTROL_SAT_U_MSB;
        !          1897:                        temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
        !          1898:                }
        !          1899:
        !          1900:                OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
        !          1901:                OUTB(bktr, BKTR_E_CONTROL, temp);
        !          1902:                OUTB(bktr, BKTR_O_CONTROL, temp1);
        !          1903:                break;
        !          1904:
        !          1905:        case BT848_GUSAT:       /* get chroma U saturation */
        !          1906:                tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
        !          1907:                if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
        !          1908:                        tmp_int |= BIT_EIGHT_HIGH;
        !          1909:                *(int *)arg = tmp_int;
        !          1910:                break;
        !          1911:
        !          1912: /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
        !          1913:
        !          1914:        case BT848_SLNOTCH:     /* set luma notch */
        !          1915:                tmp_int = (*(int *)arg & 0x7) << 5 ;
        !          1916:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
        !          1917:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
        !          1918:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
        !          1919:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
        !          1920:                break;
        !          1921:
        !          1922:        case BT848_GLNOTCH:     /* get luma notch */
        !          1923:                *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
        !          1924:                break;
        !          1925:
        !          1926:
        !          1927:        /*  */
        !          1928:        case BT848_SCONT:       /* set contrast */
        !          1929:                tmp_int = *(int *)arg;
        !          1930:
        !          1931:                temp = INB(bktr, BKTR_E_CONTROL);
        !          1932:                temp1 = INB(bktr, BKTR_O_CONTROL);
        !          1933:                if ( tmp_int & BIT_EIGHT_HIGH ) {
        !          1934:                        temp |= BT848_E_CONTROL_CON_MSB;
        !          1935:                        temp1 |= BT848_O_CONTROL_CON_MSB;
        !          1936:                }
        !          1937:                else {
        !          1938:                        temp &= ~BT848_E_CONTROL_CON_MSB;
        !          1939:                        temp1 &= ~BT848_O_CONTROL_CON_MSB;
        !          1940:                }
        !          1941:
        !          1942:                OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
        !          1943:                OUTB(bktr, BKTR_E_CONTROL, temp);
        !          1944:                OUTB(bktr, BKTR_O_CONTROL, temp1);
        !          1945:                break;
        !          1946:
        !          1947:        case BT848_GCONT:       /* get contrast */
        !          1948:                tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
        !          1949:                if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
        !          1950:                        tmp_int |= BIT_EIGHT_HIGH;
        !          1951:                *(int *)arg = tmp_int;
        !          1952:                break;
        !          1953:
        !          1954:                /*  FIXME:  SCBARS and CCBARS require a valid int *        */
        !          1955:                /*    argument to succeed, but its not used; consider      */
        !          1956:                /*    using the arg to store the on/off state so           */
        !          1957:                /*    there's only one ioctl() needed to turn cbars on/off */
        !          1958:        case BT848_SCBARS:      /* set colorbar output */
        !          1959:                OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
        !          1960:                break;
        !          1961:
        !          1962:        case BT848_CCBARS:      /* clear colorbar output */
        !          1963:                OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
        !          1964:                break;
        !          1965:
        !          1966:        case BT848_GAUDIO:      /* get audio channel */
        !          1967:                temp = bktr->audio_mux_select;
        !          1968:                if ( bktr->audio_mute_state == TRUE )
        !          1969:                        temp |= AUDIO_MUTE;
        !          1970:                *(int *)arg = temp;
        !          1971:                break;
        !          1972:
        !          1973:        case BT848_SBTSC:       /* set audio channel */
        !          1974:                if ( set_BTSC( bktr, *(int *)arg ) < 0 )
        !          1975:                        return( EIO );
        !          1976:                break;
        !          1977:
        !          1978:        case BT848_WEEPROM:     /* write eeprom */
        !          1979:                offset = (((struct eeProm *)arg)->offset);
        !          1980:                count = (((struct eeProm *)arg)->count);
        !          1981:                buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
        !          1982:                if ( writeEEProm( bktr, offset, count, buf ) < 0 )
        !          1983:                        return( EIO );
        !          1984:                break;
        !          1985:
        !          1986:        case BT848_REEPROM:     /* read eeprom */
        !          1987:                offset = (((struct eeProm *)arg)->offset);
        !          1988:                count = (((struct eeProm *)arg)->count);
        !          1989:                buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
        !          1990:                if ( readEEProm( bktr, offset, count, buf ) < 0 )
        !          1991:                        return( EIO );
        !          1992:                break;
        !          1993:
        !          1994:        case BT848_SIGNATURE:
        !          1995:                offset = (((struct eeProm *)arg)->offset);
        !          1996:                count = (((struct eeProm *)arg)->count);
        !          1997:                buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
        !          1998:                if ( signCard( bktr, offset, count, buf ) < 0 )
        !          1999:                        return( EIO );
        !          2000:                break;
        !          2001:
        !          2002:         /* Ioctl's for direct gpio access */
        !          2003: #ifdef BKTR_GPIO_ACCESS
        !          2004:         case BT848_GPIO_GET_EN:
        !          2005:                 *(int *)arg = INL(bktr, BKTR_GPIO_OUT_EN);
        !          2006:                 break;
        !          2007:
        !          2008:         case BT848_GPIO_SET_EN:
        !          2009:                 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int *)arg);
        !          2010:                 break;
        !          2011:
        !          2012:         case BT848_GPIO_GET_DATA:
        !          2013:                 *(int *)arg = INL(bktr, BKTR_GPIO_DATA);
        !          2014:                 break;
        !          2015:
        !          2016:         case BT848_GPIO_SET_DATA:
        !          2017:                 OUTL(bktr, BKTR_GPIO_DATA, *(int *)arg);
        !          2018:                 break;
        !          2019: #endif /* BKTR_GPIO_ACCESS */
        !          2020:
        !          2021:        /* Ioctl's for running the tuner device in radio mode           */
        !          2022:
        !          2023:        case RADIO_GETMODE:
        !          2024:             *(unsigned char *)arg = bktr->tuner.radio_mode;
        !          2025:            break;
        !          2026:
        !          2027:        case RADIO_SETMODE:
        !          2028:             bktr->tuner.radio_mode = *(unsigned char *)arg;
        !          2029:             break;
        !          2030:
        !          2031:        case RADIO_GETFREQ:
        !          2032:             *(unsigned long *)arg = bktr->tuner.frequency;
        !          2033:             break;
        !          2034:
        !          2035:        case RADIO_SETFREQ:
        !          2036:            /* The argument to this ioctl is NOT freq*16. It is
        !          2037:            ** freq*100.
        !          2038:            */
        !          2039:
        !          2040:             temp=(int)*(unsigned long *)arg;
        !          2041:
        !          2042: #ifdef BKTR_RADIO_DEBUG
        !          2043:            printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
        !          2044:                   (int)*(unsigned long *)arg, temp);
        !          2045: #endif
        !          2046:
        !          2047: #ifndef BKTR_RADIO_NOFREQCHECK
        !          2048:            /* According to the spec. sheet the band: 87.5MHz-108MHz    */
        !          2049:            /* is supported.                                            */
        !          2050:            if(temp<8750 || temp>10800) {
        !          2051:              printf("%s: Radio frequency out of range\n", bktr_name(bktr));
        !          2052:              return(EINVAL);
        !          2053:              }
        !          2054: #endif
        !          2055:            temp_mute( bktr, TRUE );
        !          2056:            temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
        !          2057:            temp_mute( bktr, FALSE );
        !          2058: #ifdef BKTR_RADIO_DEBUG
        !          2059:   if(temp)
        !          2060:     printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
        !          2061: #endif
        !          2062:            if ( temp < 0 )
        !          2063:                    return( EINVAL );
        !          2064:            *(unsigned long *)arg = temp;
        !          2065:            break;
        !          2066:
        !          2067:        /* Luigi's I2CWR ioctl */
        !          2068:        case BT848_I2CWR:
        !          2069:                par = *(u_int *)arg;
        !          2070:                write = (par >> 24) & 0xff ;
        !          2071:                i2c_addr = (par >> 16) & 0xff ;
        !          2072:                i2c_port = (par >> 8) & 0xff ;
        !          2073:                data = (par) & 0xff ;
        !          2074:
        !          2075:                if (write) {
        !          2076:                        i2cWrite( bktr, i2c_addr, i2c_port, data);
        !          2077:                } else {
        !          2078:                        data = i2cRead( bktr, i2c_addr);
        !          2079:                }
        !          2080:                *(u_int *)arg = (par & 0xffffff00) | ( data & 0xff );
        !          2081:                break;
        !          2082:
        !          2083:
        !          2084: #ifdef BT848_MSP_READ
        !          2085:        /* I2C ioctls to allow userland access to the MSP chip */
        !          2086:        case BT848_MSP_READ:
        !          2087:                {
        !          2088:                struct bktr_msp_control *msp;
        !          2089:                msp = (struct bktr_msp_control *) arg;
        !          2090:                msp->data = msp_dpl_read(bktr, bktr->msp_addr,
        !          2091:                                         msp->function, msp->address);
        !          2092:                break;
        !          2093:                }
        !          2094:
        !          2095:        case BT848_MSP_WRITE:
        !          2096:                {
        !          2097:                struct bktr_msp_control *msp;
        !          2098:                msp = (struct bktr_msp_control *) arg;
        !          2099:                msp_dpl_write(bktr, bktr->msp_addr, msp->function,
        !          2100:                             msp->address, msp->data );
        !          2101:                break;
        !          2102:                }
        !          2103:
        !          2104:        case BT848_MSP_RESET:
        !          2105:                msp_dpl_reset(bktr, bktr->msp_addr);
        !          2106:                break;
        !          2107: #endif
        !          2108:
        !          2109:        default:
        !          2110:                return bktr_common_ioctl( bktr, cmd, arg );
        !          2111:        }
        !          2112:
        !          2113:        return( 0 );
        !          2114: }
        !          2115:
        !          2116:
        !          2117: /*
        !          2118:  * common ioctls
        !          2119:  */
        !          2120: int
        !          2121: bktr_common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
        !          2122: {
        !          2123:        int                           pixfmt;
        !          2124:        struct meteor_pixfmt          *pf_pub;
        !          2125:
        !          2126: #if defined( STATUS_SUM )
        !          2127:        unsigned int                  temp;
        !          2128: #endif
        !          2129:
        !          2130:        switch (cmd) {
        !          2131:
        !          2132:        case METEORSINPUT:      /* set input device */
        !          2133:                /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
        !          2134:                /* On the original bt848 boards, */
        !          2135:                /*   Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
        !          2136:                /* On the Hauppauge bt878 boards, */
        !          2137:                /*   Tuner is MUX0, RCA is MUX3 */
        !          2138:                /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
        !          2139:                /* stick with this system in our Meteor Emulation */
        !          2140:
        !          2141:                switch(*(unsigned int *)arg & METEOR_DEV_MASK) {
        !          2142:
        !          2143:                /* this is the RCA video input */
        !          2144:                case 0:         /* default */
        !          2145:                case METEOR_INPUT_DEV0:
        !          2146:                  /* METEOR_INPUT_DEV_RCA: */
        !          2147:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
        !          2148:                          | METEOR_DEV0;
        !          2149:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
        !          2150:                                         & ~BT848_IFORM_MUXSEL);
        !          2151:
        !          2152:                        /* work around for new Hauppauge 878 cards */
        !          2153:                        if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
        !          2154:                                (bktr->id==BROOKTREE_878 ||
        !          2155:                                 bktr->id==BROOKTREE_879) )
        !          2156:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
        !          2157:                        else
        !          2158:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
        !          2159:
        !          2160:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
        !          2161:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
        !          2162:                        set_audio( bktr, AUDIO_EXTERN );
        !          2163:                        break;
        !          2164:
        !          2165:                /* this is the tuner input */
        !          2166:                case METEOR_INPUT_DEV1:
        !          2167:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
        !          2168:                                | METEOR_DEV1;
        !          2169:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
        !          2170:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
        !          2171:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
        !          2172:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
        !          2173:                        set_audio( bktr, AUDIO_TUNER );
        !          2174:                        break;
        !          2175:
        !          2176:                /* this is the S-VHS input, but with a composite camera */
        !          2177:                case METEOR_INPUT_DEV2:
        !          2178:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
        !          2179:                                | METEOR_DEV2;
        !          2180:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
        !          2181:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
        !          2182:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
        !          2183:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
        !          2184:                        set_audio( bktr, AUDIO_EXTERN );
        !          2185:                        break;
        !          2186:
        !          2187:                /* this is the S-VHS input */
        !          2188:                case METEOR_INPUT_DEV_SVIDEO:
        !          2189:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
        !          2190:                                | METEOR_DEV_SVIDEO;
        !          2191:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
        !          2192:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
        !          2193:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
        !          2194:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
        !          2195:                        set_audio( bktr, AUDIO_EXTERN );
        !          2196:                        break;
        !          2197:
        !          2198:                case METEOR_INPUT_DEV3:
        !          2199:                  if ((bktr->id == BROOKTREE_848A) ||
        !          2200:                      (bktr->id == BROOKTREE_849A) ||
        !          2201:                      (bktr->id == BROOKTREE_878) ||
        !          2202:                      (bktr->id == BROOKTREE_879) ) {
        !          2203:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
        !          2204:                                | METEOR_DEV3;
        !          2205:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
        !          2206:
        !          2207:                        /* work around for new Hauppauge 878 cards */
        !          2208:                        if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
        !          2209:                                (bktr->id==BROOKTREE_878 ||
        !          2210:                                 bktr->id==BROOKTREE_879) )
        !          2211:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
        !          2212:                        else
        !          2213:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
        !          2214:
        !          2215:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
        !          2216:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
        !          2217:                        set_audio( bktr, AUDIO_EXTERN );
        !          2218:
        !          2219:                        break;
        !          2220:                  }
        !          2221:
        !          2222:                default:
        !          2223:                        return( EINVAL );
        !          2224:                }
        !          2225:                break;
        !          2226:
        !          2227:        case METEORGINPUT:      /* get input device */
        !          2228:                *(u_int *)arg = bktr->flags & METEOR_DEV_MASK;
        !          2229:                break;
        !          2230:
        !          2231:        case METEORSACTPIXFMT:
        !          2232:                if (( *(int *)arg < 0 ) ||
        !          2233:                    ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
        !          2234:                        return( EINVAL );
        !          2235:
        !          2236:                bktr->pixfmt          = *(int *)arg;
        !          2237:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
        !          2238:                     | pixfmt_swap_flags( bktr->pixfmt ));
        !          2239:                bktr->pixfmt_compat   = FALSE;
        !          2240:                break;
        !          2241:
        !          2242:        case METEORGACTPIXFMT:
        !          2243:                *(int *)arg = bktr->pixfmt;
        !          2244:                break;
        !          2245:
        !          2246:        case METEORGSUPPIXFMT :
        !          2247:                pf_pub = (struct meteor_pixfmt *)arg;
        !          2248:                pixfmt = pf_pub->index;
        !          2249:
        !          2250:                if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
        !          2251:                        return( EINVAL );
        !          2252:
        !          2253:                memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
        !          2254:                        sizeof( *pf_pub ) );
        !          2255:
        !          2256:                /*  Patch in our format index  */
        !          2257:                pf_pub->index       = pixfmt;
        !          2258:                break;
        !          2259:
        !          2260: #if defined( STATUS_SUM )
        !          2261:        case BT848_GSTATUS:     /* reap status */
        !          2262:                {
        !          2263:                 DECLARE_INTR_MASK(s);
        !          2264:                DISABLE_INTR(s);
        !          2265:                temp = status_sum;
        !          2266:                status_sum = 0;
        !          2267:                ENABLE_INTR(s);
        !          2268:                *(u_int *)arg = temp;
        !          2269:                break;
        !          2270:                }
        !          2271: #endif /* STATUS_SUM */
        !          2272:
        !          2273:        default:
        !          2274:                return( ENOTTY );
        !          2275:        }
        !          2276:
        !          2277:        return( 0 );
        !          2278: }
        !          2279:
        !          2280:
        !          2281:
        !          2282:
        !          2283: /******************************************************************************
        !          2284:  * bt848 RISC programming routines:
        !          2285:  */
        !          2286:
        !          2287:
        !          2288: /*
        !          2289:  *
        !          2290:  */
        !          2291: #ifdef BT848_DEBUG
        !          2292: static int
        !          2293: dump_bt848( bktr_ptr_t bktr )
        !          2294: {
        !          2295:        int     r[60]={
        !          2296:                           4,    8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
        !          2297:                        0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
        !          2298:                        0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
        !          2299:                        0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
        !          2300:                        0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
        !          2301:                        0,       0,    0,    0
        !          2302:                   };
        !          2303:        int     i;
        !          2304:
        !          2305:        for (i = 0; i < 40; i+=4) {
        !          2306:                printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
        !          2307:                       bktr_name(bktr),
        !          2308:                       r[i], INL(bktr, r[i]),
        !          2309:                       r[i+1], INL(bktr, r[i+1]),
        !          2310:                       r[i+2], INL(bktr, r[i+2]),
        !          2311:                       r[i+3], INL(bktr, r[i+3]));
        !          2312:        }
        !          2313:
        !          2314:        printf("%s: INT STAT %x \n", bktr_name(bktr),
        !          2315:               INL(bktr, BKTR_INT_STAT));
        !          2316:        printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
        !          2317:               INL(bktr, BKTR_INT_MASK));
        !          2318:        printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
        !          2319:               INW(bktr, BKTR_GPIO_DMA_CTL));
        !          2320:
        !          2321:        return( 0 );
        !          2322: }
        !          2323:
        !          2324: #endif
        !          2325:
        !          2326: /*
        !          2327:  * build write instruction
        !          2328:  */
        !          2329: #define BKTR_FM1      0x6      /* packed data to follow */
        !          2330: #define BKTR_FM3      0xe      /* planar data to follow */
        !          2331: #define BKTR_VRE      0x4      /* Marks the end of the even field */
        !          2332: #define BKTR_VRO      0xC      /* Marks the end of the odd field */
        !          2333: #define BKTR_PXV      0x0      /* valid word (never used) */
        !          2334: #define BKTR_EOL      0x1      /* last dword, 4 bytes */
        !          2335: #define BKTR_SOL      0x2      /* first dword */
        !          2336:
        !          2337: #define OP_WRITE      (0x1 << 28)
        !          2338: #define OP_SKIP       (0x2 << 28)
        !          2339: #define OP_WRITEC     (0x5 << 28)
        !          2340: #define OP_JUMP              (0x7 << 28)
        !          2341: #define OP_SYNC              (0x8 << 28)
        !          2342: #define OP_WRITE123   (0x9 << 28)
        !          2343: #define OP_WRITES123  (0xb << 28)
        !          2344: #define OP_SOL       (1 << 27)         /* first instr for scanline */
        !          2345: #define OP_EOL       (1 << 26)
        !          2346:
        !          2347: #define BKTR_RESYNC   (1 << 15)
        !          2348: #define BKTR_GEN_IRQ  (1 << 24)
        !          2349:
        !          2350: /*
        !          2351:  * The RISC status bits can be set/cleared in the RISC programs
        !          2352:  * and tested in the Interrupt Handler
        !          2353:  */
        !          2354: #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
        !          2355: #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
        !          2356: #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
        !          2357: #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
        !          2358:
        !          2359: #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
        !          2360: #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
        !          2361: #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
        !          2362: #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
        !          2363:
        !          2364: #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
        !          2365: #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
        !          2366: #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
        !          2367: #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
        !          2368:
        !          2369: static bool_t
        !          2370: notclipped (bktr_reg_t * bktr, int x, int width) {
        !          2371:     int i;
        !          2372:     bktr_clip_t * clip_node;
        !          2373:     bktr->clip_start = -1;
        !          2374:     bktr->last_y = 0;
        !          2375:     bktr->y = 0;
        !          2376:     bktr->y2 = width;
        !          2377:     bktr->line_length = width;
        !          2378:     bktr->yclip = -1;
        !          2379:     bktr->yclip2 = -1;
        !          2380:     bktr->current_col = 0;
        !          2381:
        !          2382:     if (bktr->max_clip_node == 0 ) return TRUE;
        !          2383:     clip_node = (bktr_clip_t *) &bktr->clip_list[0];
        !          2384:
        !          2385:
        !          2386:     for (i = 0; i < bktr->max_clip_node; i++ ) {
        !          2387:        clip_node = (bktr_clip_t *) &bktr->clip_list[i];
        !          2388:        if (x >= clip_node->x_min && x <= clip_node->x_max  ) {
        !          2389:            bktr->clip_start = i;
        !          2390:            return FALSE;
        !          2391:        }
        !          2392:     }
        !          2393:
        !          2394:     return TRUE;
        !          2395: }
        !          2396:
        !          2397: static bool_t
        !          2398: getline(bktr_reg_t *bktr, int x ) {
        !          2399:     int i, j;
        !          2400:     bktr_clip_t * clip_node ;
        !          2401:
        !          2402:     if (bktr->line_length == 0 ||
        !          2403:        bktr->current_col >= bktr->line_length) return FALSE;
        !          2404:
        !          2405:     bktr->y = min(bktr->last_y, bktr->line_length);
        !          2406:     bktr->y2 = bktr->line_length;
        !          2407:
        !          2408:     bktr->yclip = bktr->yclip2 = -1;
        !          2409:     for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
        !          2410:        clip_node = (bktr_clip_t *) &bktr->clip_list[i];
        !          2411:        if (x >= clip_node->x_min && x <= clip_node->x_max) {
        !          2412:            if (bktr->last_y <= clip_node->y_min) {
        !          2413:                bktr->y =      min(bktr->last_y, bktr->line_length);
        !          2414:                bktr->y2 =     min(clip_node->y_min, bktr->line_length);
        !          2415:                bktr->yclip =  min(clip_node->y_min, bktr->line_length);
        !          2416:                bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
        !          2417:                bktr->last_y = bktr->yclip2;
        !          2418:                bktr->clip_start = i;
        !          2419:
        !          2420:                for (j = i+1; j  < bktr->max_clip_node; j++ ) {
        !          2421:                    clip_node = (bktr_clip_t *) &bktr->clip_list[j];
        !          2422:                    if (x >= clip_node->x_min && x <= clip_node->x_max) {
        !          2423:                        if (bktr->last_y >= clip_node->y_min) {
        !          2424:                            bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
        !          2425:                            bktr->last_y = bktr->yclip2;
        !          2426:                            bktr->clip_start = j;
        !          2427:                        }
        !          2428:                    } else break  ;
        !          2429:                }
        !          2430:                return TRUE;
        !          2431:            }
        !          2432:        }
        !          2433:     }
        !          2434:
        !          2435:     if (bktr->current_col <= bktr->line_length) {
        !          2436:        bktr->current_col = bktr->line_length;
        !          2437:        return TRUE;
        !          2438:     }
        !          2439:     return FALSE;
        !          2440: }
        !          2441:
        !          2442: static bool_t
        !          2443: split(bktr_reg_t *bktr, u_int **dma_prog, int width, u_int operation,
        !          2444:     int pixel_width, u_int *target_buffer, int cols)
        !          2445: {
        !          2446:
        !          2447:  u_int flag, flag2;
        !          2448:  const struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
        !          2449:  u_int  skip, start_skip;
        !          2450:
        !          2451:   /*  For RGB24, we need to align the component in FIFO Byte Lane 0         */
        !          2452:   /*    to the 1st byte in the mem dword containing our start addr.         */
        !          2453:   /*    BTW, we know this pixfmt's 1st byte is Blue; thus the start addr    */
        !          2454:   /*     must be Blue.                                                      */
        !          2455:   start_skip = 0;
        !          2456:   if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
        !          2457:          switch ((*target_buffer) % 4) {
        !          2458:          case 2 : start_skip = 4 ; break;
        !          2459:          case 1 : start_skip = 8 ; break;
        !          2460:          }
        !          2461:
        !          2462:  if ((width * pixel_width) < DMA_BT848_SPLIT ) {
        !          2463:      if (  width == cols) {
        !          2464:         flag = OP_SOL | OP_EOL;
        !          2465:        } else if (bktr->current_col == 0 ) {
        !          2466:            flag  = OP_SOL;
        !          2467:        } else if (bktr->current_col == cols) {
        !          2468:            flag = OP_EOL;
        !          2469:        } else flag = 0;
        !          2470:
        !          2471:      skip = 0;
        !          2472:      if (( flag & OP_SOL ) && ( start_skip > 0 )) {
        !          2473:             *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
        !          2474:             flag &= ~OP_SOL;
        !          2475:             skip = start_skip;
        !          2476:      }
        !          2477:
        !          2478:      *(*dma_prog)++ = htole32(operation | flag  | (width * pixel_width - skip));
        !          2479:      if (operation != OP_SKIP )
        !          2480:         *(*dma_prog)++ = htole32(*target_buffer);
        !          2481:
        !          2482:      *target_buffer += width * pixel_width;
        !          2483:      bktr->current_col += width;
        !          2484:
        !          2485:  } else {
        !          2486:
        !          2487:        if (bktr->current_col == 0 && width == cols) {
        !          2488:            flag = OP_SOL ;
        !          2489:            flag2 = OP_EOL;
        !          2490:         } else if (bktr->current_col == 0 ) {
        !          2491:            flag = OP_SOL;
        !          2492:            flag2 = 0;
        !          2493:        } else if (bktr->current_col >= cols)  {
        !          2494:            flag =  0;
        !          2495:            flag2 = OP_EOL;
        !          2496:        } else {
        !          2497:            flag =  0;
        !          2498:            flag2 = 0;
        !          2499:        }
        !          2500:
        !          2501:        skip = 0;
        !          2502:        if (( flag & OP_SOL ) && ( start_skip > 0 )) {
        !          2503:                *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
        !          2504:                flag &= ~OP_SOL;
        !          2505:                skip = start_skip;
        !          2506:        }
        !          2507:
        !          2508:        *(*dma_prog)++ = htole32(operation | flag |
        !          2509:              (width * pixel_width / 2 - skip));
        !          2510:        if (operation != OP_SKIP )
        !          2511:              *(*dma_prog)++ = htole32(*target_buffer);
        !          2512:        *target_buffer += width * pixel_width / 2;
        !          2513:
        !          2514:        if ( operation == OP_WRITE )
        !          2515:                operation = OP_WRITEC;
        !          2516:        *(*dma_prog)++ = htole32(operation | flag2 |
        !          2517:            (width * pixel_width / 2));
        !          2518:        *target_buffer += width * pixel_width / 2;
        !          2519:        bktr->current_col += width;
        !          2520:
        !          2521:     }
        !          2522:
        !          2523:     return TRUE;
        !          2524: }
        !          2525:
        !          2526:
        !          2527: /*
        !          2528:  * Generate the RISC instructions to capture both VBI and video images
        !          2529:  */
        !          2530: static void
        !          2531: rgb_vbi_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
        !          2532: {
        !          2533:        int             i;
        !          2534:        u_int           target_buffer, buffer, target, width;
        !          2535:        u_int           pitch;
        !          2536:        u_int           *dma_prog;      /* DMA prog is an array of
        !          2537:                                           32 bit RISC instructions */
        !          2538:        u_int           *loop_point;
        !          2539:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
        !          2540:        u_int           Bpp = pf_int->public.Bpp;
        !          2541:        unsigned int    vbisamples;     /* VBI samples per line */
        !          2542:        unsigned int    vbilines;       /* VBI lines per field */
        !          2543:        unsigned int    num_dwords;     /* DWORDS per line */
        !          2544:
        !          2545:        vbisamples = format_params[bktr->format_params].vbi_num_samples;
        !          2546:        vbilines   = format_params[bktr->format_params].vbi_num_lines;
        !          2547:        num_dwords = vbisamples/4;
        !          2548:
        !          2549:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
        !          2550:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
        !          2551:        OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
        !          2552:        OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay    */
        !          2553:                                                            /* no ext frame */
        !          2554:
        !          2555:        OUTB(bktr, BKTR_OFORM, 0x00);
        !          2556:
        !          2557:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
        !          2558:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
        !          2559:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
        !          2560:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
        !          2561:
        !          2562:        /* disable gamma correction removal */
        !          2563:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
        !          2564:
        !          2565:        if (cols > 385 ) {
        !          2566:            OUTB(bktr, BKTR_E_VTC, 0);
        !          2567:            OUTB(bktr, BKTR_O_VTC, 0);
        !          2568:        } else {
        !          2569:            OUTB(bktr, BKTR_E_VTC, 1);
        !          2570:            OUTB(bktr, BKTR_O_VTC, 1);
        !          2571:        }
        !          2572:        bktr->capcontrol = 3 << 2 |  3;
        !          2573:
        !          2574:        dma_prog = (u_int *) bktr->dma_prog;
        !          2575:
        !          2576:        /* Construct Write */
        !          2577:
        !          2578:        if (bktr->video.addr) {
        !          2579:                target_buffer = bktr->video.addr;
        !          2580:                pitch = bktr->video.width;
        !          2581:        }
        !          2582:        else {
        !          2583:                target_buffer = bktr->dm_mem->dm_segs->ds_addr;
        !          2584:                pitch = cols*Bpp;
        !          2585:        }
        !          2586:
        !          2587:        buffer = target_buffer;
        !          2588:
        !          2589:        /* Wait for the VRE sync marking the end of the Even and
        !          2590:         * the start of the Odd field. Resync here.
        !          2591:         */
        !          2592:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC |BKTR_VRE);
        !          2593:        *dma_prog++ = htole32(0);
        !          2594:
        !          2595:        loop_point = dma_prog;
        !          2596:
        !          2597:        /* store the VBI data */
        !          2598:        /* look for sync with packed data */
        !          2599:        *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
        !          2600:        *dma_prog++ = htole32(0);
        !          2601:        for(i = 0; i < vbilines; i++) {
        !          2602:                *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
        !          2603:                *dma_prog++ = htole32(bktr->dm_vbidata->dm_segs->ds_addr +
        !          2604:                                        (i * VBI_LINE_SIZE));
        !          2605:        }
        !          2606:
        !          2607:        if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
        !          2608:                /* store the Odd field video image */
        !          2609:                /* look for sync with packed data */
        !          2610:                *dma_prog++ = htole32(OP_SYNC  | BKTR_FM1);
        !          2611:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2612:                width = cols;
        !          2613:                for (i = 0; i < (rows/interlace); i++) {
        !          2614:                    target = target_buffer;
        !          2615:                    if ( notclipped(bktr, i, width)) {
        !          2616:                        split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
        !          2617:                              Bpp, &target, cols);
        !          2618:
        !          2619:                    } else {
        !          2620:                        while(getline(bktr, i)) {
        !          2621:                            if (bktr->y != bktr->y2 ) {
        !          2622:                                split(bktr, &dma_prog, bktr->y2 - bktr->y,
        !          2623:                                    OP_WRITE, Bpp, &target, cols);
        !          2624:                            }
        !          2625:                            if (bktr->yclip != bktr->yclip2 ) {
        !          2626:                                split(bktr, &dma_prog, bktr->yclip2 -
        !          2627:                                    bktr->yclip, OP_SKIP, Bpp, &target, cols);
        !          2628:                            }
        !          2629:                        }
        !          2630:                    }
        !          2631:
        !          2632:                    target_buffer += interlace * pitch;
        !          2633:                }
        !          2634:
        !          2635:        } /* end if */
        !          2636:
        !          2637:        /* Grab the Even field */
        !          2638:        /* Look for the VRO, end of Odd field, marker */
        !          2639:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
        !          2640:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2641:
        !          2642:        /* store the VBI data */
        !          2643:        /* look for sync with packed data */
        !          2644:        *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
        !          2645:        *dma_prog++ = htole32(0);
        !          2646:        for(i = 0; i < vbilines; i++) {
        !          2647:                *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
        !          2648:                *dma_prog++ = htole32(bktr->dm_vbidata->dm_segs->ds_addr +
        !          2649:                                ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
        !          2650:        }
        !          2651:
        !          2652:        /* store the video image */
        !          2653:        if (i_flag == 1) /*Even Only*/
        !          2654:                target_buffer = buffer;
        !          2655:        if (i_flag == 3) /*interlaced*/
        !          2656:                target_buffer = buffer+pitch;
        !          2657:
        !          2658:
        !          2659:        if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
        !          2660:                /* look for sync with packed data */
        !          2661:                *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
        !          2662:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2663:                width = cols;
        !          2664:                for (i = 0; i < (rows/interlace); i++) {
        !          2665:                    target = target_buffer;
        !          2666:                    if ( notclipped(bktr, i, width)) {
        !          2667:                        split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
        !          2668:                              Bpp, &target,  cols);
        !          2669:                    } else {
        !          2670:                        while(getline(bktr, i)) {
        !          2671:                            if (bktr->y != bktr->y2 ) {
        !          2672:                                split(bktr, &dma_prog, bktr->y2 - bktr->y,
        !          2673:                                    OP_WRITE, Bpp, &target, cols);
        !          2674:                            }
        !          2675:                            if (bktr->yclip != bktr->yclip2 ) {
        !          2676:                                split(bktr, &dma_prog, bktr->yclip2 -
        !          2677:                                    bktr->yclip, OP_SKIP, Bpp, &target, cols);
        !          2678:                            }
        !          2679:                        }
        !          2680:                    }
        !          2681:
        !          2682:                    target_buffer += interlace * pitch;
        !          2683:                }
        !          2684:        }
        !          2685:
        !          2686:        /* Look for end of 'Even Field' */
        !          2687:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
        !          2688:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2689:
        !          2690:        *dma_prog++ = htole32(OP_JUMP);
        !          2691:        *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr +
        !          2692:            ((char *)loop_point - (char *)bktr->dma_prog));
        !          2693:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2694:
        !          2695: }
        !          2696:
        !          2697: static void
        !          2698: rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
        !          2699: {
        !          2700:        int             i;
        !          2701:        u_int           target_buffer, buffer, target,width;
        !          2702:        u_int           pitch;
        !          2703:        u_int           *dma_prog;
        !          2704:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
        !          2705:        u_int                   Bpp = pf_int->public.Bpp;
        !          2706:
        !          2707:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
        !          2708:        OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
        !          2709:        OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
        !          2710:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
        !          2711:
        !          2712:        OUTB(bktr, BKTR_OFORM, 0x00);
        !          2713:
        !          2714:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
        !          2715:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
        !          2716:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
        !          2717:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
        !          2718:
        !          2719:        /* disable gamma correction removal */
        !          2720:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
        !          2721:
        !          2722:        if (cols > 385 ) {
        !          2723:            OUTB(bktr, BKTR_E_VTC, 0);
        !          2724:            OUTB(bktr, BKTR_O_VTC, 0);
        !          2725:        } else {
        !          2726:            OUTB(bktr, BKTR_E_VTC, 1);
        !          2727:            OUTB(bktr, BKTR_O_VTC, 1);
        !          2728:        }
        !          2729:        bktr->capcontrol = 3 << 2 |  3;
        !          2730:
        !          2731:        dma_prog = (u_int *)bktr->dma_prog;
        !          2732:
        !          2733:        /* Construct Write */
        !          2734:
        !          2735:        if (bktr->video.addr) {
        !          2736:                target_buffer = (u_int) bktr->video.addr;
        !          2737:                pitch = bktr->video.width;
        !          2738:        }
        !          2739:        else {
        !          2740:                target_buffer = bktr->dm_mem->dm_segs->ds_addr;
        !          2741:                pitch = cols*Bpp;
        !          2742:        }
        !          2743:
        !          2744:        buffer = target_buffer;
        !          2745:
        !          2746:        /* construct sync : for video packet format */
        !          2747:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
        !          2748:
        !          2749:        /* sync, mode indicator packed data */
        !          2750:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2751:        width = cols;
        !          2752:        for (i = 0; i < (rows/interlace); i++) {
        !          2753:            target = target_buffer;
        !          2754:            if ( notclipped(bktr, i, width)) {
        !          2755:                split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
        !          2756:                    Bpp, &target,  cols);
        !          2757:
        !          2758:            } else {
        !          2759:                while(getline(bktr, i)) {
        !          2760:                    if (bktr->y != bktr->y2 ) {
        !          2761:                        split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
        !          2762:                              Bpp, &target, cols);
        !          2763:                    }
        !          2764:                    if (bktr->yclip != bktr->yclip2 ) {
        !          2765:                        split(bktr, &dma_prog, bktr->yclip2 - bktr->yclip,
        !          2766:                              OP_SKIP, Bpp, &target,  cols);
        !          2767:                    }
        !          2768:                }
        !          2769:            }
        !          2770:
        !          2771:            target_buffer += interlace * pitch;
        !          2772:        }
        !          2773:
        !          2774:        switch (i_flag) {
        !          2775:        case 1:
        !          2776:                /* sync vre */
        !          2777:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
        !          2778:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2779:
        !          2780:                *dma_prog++ = htole32(OP_JUMP);
        !          2781:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          2782:                return;
        !          2783:
        !          2784:        case 2:
        !          2785:                /* sync vro */
        !          2786:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
        !          2787:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2788:
        !          2789:                *dma_prog++ = htole32(OP_JUMP);
        !          2790:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          2791:                return;
        !          2792:
        !          2793:        case 3:
        !          2794:                /* sync vro */
        !          2795:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
        !          2796:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2797:
        !          2798:                *dma_prog++ = htole32(OP_JUMP);
        !          2799:                *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
        !          2800:                break;
        !          2801:        }
        !          2802:
        !          2803:        if (interlace == 2) {
        !          2804:
        !          2805:                target_buffer = buffer + pitch;
        !          2806:
        !          2807:                dma_prog = (u_int *) bktr->odd_dma_prog;
        !          2808:
        !          2809:                /* sync vre IRQ bit */
        !          2810:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
        !          2811:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2812:                 width = cols;
        !          2813:                for (i = 0; i < (rows/interlace); i++) {
        !          2814:                    target = target_buffer;
        !          2815:                    if ( notclipped(bktr, i, width)) {
        !          2816:                        split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
        !          2817:                            Bpp, &target,  cols);
        !          2818:                    } else {
        !          2819:                        while(getline(bktr, i)) {
        !          2820:                            if (bktr->y != bktr->y2 ) {
        !          2821:                                split(bktr, &dma_prog, bktr->y2 - bktr->y,
        !          2822:                                    OP_WRITE, Bpp, &target, cols);
        !          2823:                            }
        !          2824:                            if (bktr->yclip != bktr->yclip2 ) {
        !          2825:                                split(bktr, &dma_prog, bktr->yclip2 -
        !          2826:                                    bktr->yclip, OP_SKIP, Bpp, &target, cols);
        !          2827:                            }
        !          2828:                        }
        !          2829:                    }
        !          2830:
        !          2831:                    target_buffer += interlace * pitch;
        !          2832:                }
        !          2833:        }
        !          2834:
        !          2835:        /* sync vre IRQ bit */
        !          2836:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
        !          2837:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2838:        *dma_prog++ = htole32(OP_JUMP);
        !          2839:        *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          2840:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2841: }
        !          2842:
        !          2843:
        !          2844: /*
        !          2845:  *
        !          2846:  */
        !          2847: static void
        !          2848: yuvpack_prog( bktr_ptr_t bktr, char i_flag,
        !          2849:              int cols, int rows, int interlace )
        !          2850: {
        !          2851:        int                     i;
        !          2852:        volatile unsigned int   inst;
        !          2853:        volatile unsigned int   inst3;
        !          2854:        volatile u_int          target_buffer, buffer;
        !          2855:        volatile u_int          *dma_prog;
        !          2856:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
        !          2857:        int                     b;
        !          2858:
        !          2859:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
        !          2860:
        !          2861:        OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
        !          2862:        OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
        !          2863:
        !          2864:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
        !          2865:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
        !          2866:
        !          2867:        bktr->capcontrol =   1 << 6 | 1 << 4 | 1 << 2 | 3;
        !          2868:        bktr->capcontrol = 3 << 2 |  3;
        !          2869:
        !          2870:        dma_prog = (u_int *) bktr->dma_prog;
        !          2871:
        !          2872:        /* Construct Write */
        !          2873:
        !          2874:        /* write , sol, eol */
        !          2875:        inst = OP_WRITE  | OP_SOL | (cols);
        !          2876:        /* write , sol, eol */
        !          2877:        inst3 = OP_WRITE | OP_EOL | (cols);
        !          2878:
        !          2879:        if (bktr->video.addr)
        !          2880:                target_buffer = bktr->video.addr;
        !          2881:        else
        !          2882:                target_buffer = bktr->dm_mem->dm_segs->ds_addr;
        !          2883:
        !          2884:        buffer = target_buffer;
        !          2885:
        !          2886:        /* contruct sync : for video packet format */
        !          2887:        /* sync, mode indicator packed data */
        !          2888:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
        !          2889:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2890:
        !          2891:        b = cols;
        !          2892:
        !          2893:        for (i = 0; i < (rows/interlace); i++) {
        !          2894:                *dma_prog++ = htole32(inst);
        !          2895:                *dma_prog++ = htole32(target_buffer);
        !          2896:                *dma_prog++ = htole32(inst3);
        !          2897:                *dma_prog++ = htole32(target_buffer + b);
        !          2898:                target_buffer += interlace*(cols * 2);
        !          2899:        }
        !          2900:
        !          2901:        switch (i_flag) {
        !          2902:        case 1:
        !          2903:                /* sync vre */
        !          2904:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
        !          2905:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2906:                *dma_prog++ = htole32(OP_JUMP);
        !          2907:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          2908:                return;
        !          2909:
        !          2910:        case 2:
        !          2911:                /* sync vro */
        !          2912:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
        !          2913:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2914:                *dma_prog++ = htole32(OP_JUMP);
        !          2915:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          2916:                return;
        !          2917:
        !          2918:        case 3:
        !          2919:                /* sync vro */
        !          2920:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
        !          2921:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2922:                *dma_prog++ = htole32(OP_JUMP);
        !          2923:                *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
        !          2924:                break;
        !          2925:        }
        !          2926:
        !          2927:        if (interlace == 2) {
        !          2928:
        !          2929:                target_buffer = buffer + cols*2;
        !          2930:
        !          2931:                dma_prog = (u_int * ) bktr->odd_dma_prog;
        !          2932:
        !          2933:                /* sync vre */
        !          2934:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
        !          2935:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2936:
        !          2937:                for (i = 0; i < (rows/interlace) ; i++) {
        !          2938:                        *dma_prog++ = htole32(inst);
        !          2939:                        *dma_prog++ = htole32(target_buffer);
        !          2940:                        *dma_prog++ = htole32(inst3);
        !          2941:                        *dma_prog++ = htole32(target_buffer + b);
        !          2942:                        target_buffer += interlace * ( cols*2);
        !          2943:                }
        !          2944:        }
        !          2945:
        !          2946:        /* sync vro IRQ bit */
        !          2947:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
        !          2948:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2949:        *dma_prog++ = htole32(OP_JUMP);
        !          2950:        *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          2951:
        !          2952:        *dma_prog++ = htole32(OP_JUMP);
        !          2953:        *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          2954:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          2955: }
        !          2956:
        !          2957:
        !          2958: /*
        !          2959:  *
        !          2960:  */
        !          2961: static void
        !          2962: yuv422_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
        !          2963: {
        !          2964:        int             i;
        !          2965:        u_int           inst;
        !          2966:        u_int           target_buffer, t1, buffer;
        !          2967:        u_int           *dma_prog;
        !          2968:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
        !          2969:
        !          2970:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
        !          2971:
        !          2972:        dma_prog = (u_int *) bktr->dma_prog;
        !          2973:
        !          2974:        bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
        !          2975:
        !          2976:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
        !          2977:        OUTB(bktr, BKTR_OFORM, 0x00);
        !          2978:
        !          2979:        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
        !          2980:        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
        !          2981:
        !          2982:        OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC);      /* chroma agc enable */
        !          2983:        OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
        !          2984:
        !          2985:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
        !          2986:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
        !          2987:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
        !          2988:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
        !          2989:
        !          2990:        /* disable gamma correction removal */
        !          2991:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
        !          2992:
        !          2993:        /* Construct Write */
        !          2994:        inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
        !          2995:        if (bktr->video.addr)
        !          2996:                target_buffer = (u_int) bktr->video.addr;
        !          2997:        else
        !          2998:                target_buffer = bktr->dm_mem->dm_segs->ds_addr;
        !          2999:
        !          3000:        buffer = target_buffer;
        !          3001:
        !          3002:        t1 = buffer;
        !          3003:
        !          3004:        /* contruct sync : for video packet format */
        !          3005:        /*     sync, mode indicator packed data*/
        !          3006:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
        !          3007:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3008:
        !          3009:        for (i = 0; i < (rows/interlace ) ; i++) {
        !          3010:                *dma_prog++ = htole32(inst);
        !          3011:                *dma_prog++ = htole32(cols/2 | cols/2 << 16);
        !          3012:                *dma_prog++ = htole32(target_buffer);
        !          3013:                *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
        !          3014:                *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) +
        !          3015:                    i*cols/2 * interlace);
        !          3016:                target_buffer += interlace*cols;
        !          3017:        }
        !          3018:
        !          3019:        switch (i_flag) {
        !          3020:        case 1:
        !          3021:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
        !          3022:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3023:
        !          3024:                *dma_prog++ = htole32(OP_JUMP);
        !          3025:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          3026:                return;
        !          3027:
        !          3028:        case 2:
        !          3029:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vre*/
        !          3030:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3031:
        !          3032:                *dma_prog++ = htole32(OP_JUMP);
        !          3033:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          3034:                return;
        !          3035:
        !          3036:        case 3:
        !          3037:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
        !          3038:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3039:
        !          3040:                *dma_prog++ = htole32(OP_JUMP);
        !          3041:                *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
        !          3042:                break;
        !          3043:        }
        !          3044:
        !          3045:        if (interlace == 2) {
        !          3046:
        !          3047:                dma_prog = (u_int * ) bktr->odd_dma_prog;
        !          3048:
        !          3049:                target_buffer  = (u_int) buffer + cols;
        !          3050:                t1 = buffer + cols/2;
        !          3051:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
        !          3052:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3053:
        !          3054:                for (i = 0; i < (rows/interlace )  ; i++) {
        !          3055:                        *dma_prog++ = htole32(inst);
        !          3056:                        *dma_prog++ = htole32(cols/2 | cols/2 << 16);
        !          3057:                        *dma_prog++ = htole32(target_buffer);
        !          3058:                        *dma_prog++ = htole32(t1 + (cols*rows) +
        !          3059:                            i*cols/2 * interlace);
        !          3060:                        *dma_prog++ = htole32(t1 + (cols*rows) +
        !          3061:                            (cols*rows/2) + i*cols/2 * interlace);
        !          3062:                        target_buffer += interlace*cols;
        !          3063:                }
        !          3064:        }
        !          3065:
        !          3066:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
        !          3067:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3068:        *dma_prog++ = htole32(OP_JUMP);
        !          3069:        *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          3070:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3071: }
        !          3072:
        !          3073:
        !          3074: /*
        !          3075:  *
        !          3076:  */
        !          3077: static void
        !          3078: yuv12_prog( bktr_ptr_t bktr, char i_flag,
        !          3079:             int cols, int rows, int interlace ){
        !          3080:
        !          3081:        int             i;
        !          3082:        u_int           inst;
        !          3083:        u_int           inst1;
        !          3084:        u_int           target_buffer, t1, buffer;
        !          3085:        u_int           *dma_prog;
        !          3086:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
        !          3087:
        !          3088:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
        !          3089:
        !          3090:        dma_prog = (u_int *) bktr->dma_prog;
        !          3091:
        !          3092:        bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
        !          3093:
        !          3094:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
        !          3095:        OUTB(bktr, BKTR_OFORM, 0x0);
        !          3096:
        !          3097:        /* Construct Write */
        !          3098:        inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
        !          3099:        inst1  = OP_WRITES123  | OP_SOL | OP_EOL |  (cols);
        !          3100:        if (bktr->video.addr)
        !          3101:                target_buffer = (u_int) bktr->video.addr;
        !          3102:        else
        !          3103:                target_buffer = bktr->dm_mem->dm_segs->ds_addr;
        !          3104:
        !          3105:        buffer = target_buffer;
        !          3106:        t1 = buffer;
        !          3107:
        !          3108:        /* sync, mode indicator packed data*/
        !          3109:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
        !          3110:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3111:
        !          3112:        for (i = 0; i < (rows/interlace )/2 ; i++) {
        !          3113:                *dma_prog++ = htole32(inst);
        !          3114:                *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
        !          3115:                *dma_prog++ = htole32(target_buffer);
        !          3116:                *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
        !          3117:                *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) +
        !          3118:                    i*cols/2 * interlace);
        !          3119:                target_buffer += interlace*cols;
        !          3120:                *dma_prog++ = htole32(inst1);
        !          3121:                *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
        !          3122:                *dma_prog++ = htole32(target_buffer);
        !          3123:                target_buffer += interlace*cols;
        !          3124:
        !          3125:        }
        !          3126:
        !          3127:        switch (i_flag) {
        !          3128:        case 1:
        !          3129:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
        !          3130:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3131:
        !          3132:                *dma_prog++ = htole32(OP_JUMP);
        !          3133:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          3134:                return;
        !          3135:
        !          3136:        case 2:
        !          3137:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vro*/
        !          3138:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3139:
        !          3140:                *dma_prog++ = htole32(OP_JUMP);
        !          3141:                *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          3142:                return;
        !          3143:
        !          3144:        case 3:
        !          3145:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
        !          3146:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3147:                *dma_prog++ = htole32(OP_JUMP);
        !          3148:                *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
        !          3149:                break;
        !          3150:        }
        !          3151:
        !          3152:        if (interlace == 2) {
        !          3153:
        !          3154:                dma_prog = (u_int *)bktr->odd_dma_prog;
        !          3155:
        !          3156:                target_buffer  = (u_int) buffer + cols;
        !          3157:                t1 = buffer + cols/2;
        !          3158:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
        !          3159:                *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3160:
        !          3161:                for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
        !          3162:                        *dma_prog++ = htole32(inst);
        !          3163:                        *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
        !          3164:                        *dma_prog++ = htole32(target_buffer);
        !          3165:                        *dma_prog++ = htole32(t1 + (cols*rows) +
        !          3166:                            i*cols/2 * interlace);
        !          3167:                        *dma_prog++ = htole32(t1 + (cols*rows) +
        !          3168:                            (cols*rows/4) + i*cols/2 * interlace);
        !          3169:                        target_buffer += interlace*cols;
        !          3170:                        *dma_prog++ = htole32(inst1);
        !          3171:                        *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
        !          3172:                        *dma_prog++ = htole32(target_buffer);
        !          3173:                        target_buffer += interlace*cols;
        !          3174:                }
        !          3175:        }
        !          3176:
        !          3177:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
        !          3178:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3179:        *dma_prog++ = htole32(OP_JUMP);
        !          3180:        *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
        !          3181:        *dma_prog++ = htole32(0);  /* NULL WORD */
        !          3182: }
        !          3183:
        !          3184:
        !          3185: /*
        !          3186:  *
        !          3187:  */
        !          3188: static void
        !          3189: build_dma_prog( bktr_ptr_t bktr, char i_flag )
        !          3190: {
        !          3191:        int                     rows, cols,  interlace;
        !          3192:        int                     tmp_int;
        !          3193:        unsigned int            temp;
        !          3194:        const struct format_params *fp;
        !          3195:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
        !          3196:
        !          3197:
        !          3198:        fp = &format_params[bktr->format_params];
        !          3199:
        !          3200:        OUTL(bktr, BKTR_INT_MASK,  ALL_INTS_DISABLED);
        !          3201:
        !          3202:        /* disable FIFO & RISC, leave other bits alone */
        !          3203:        OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
        !          3204:
        !          3205:        /* set video parameters */
        !          3206:        if (bktr->capture_area_enabled)
        !          3207:          temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
        !          3208:                  / fp->scaled_htotal / bktr->cols) -  4096;
        !          3209:        else
        !          3210:          temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
        !          3211:                  / fp->scaled_htotal / bktr->cols) -  4096;
        !          3212:
        !          3213:        /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
        !          3214:        OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
        !          3215:        OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
        !          3216:        OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
        !          3217:        OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
        !          3218:
        !          3219:        /* horizontal active */
        !          3220:        temp = bktr->cols;
        !          3221:        /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
        !          3222:        OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
        !          3223:        OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
        !          3224:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
        !          3225:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
        !          3226:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
        !          3227:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
        !          3228:
        !          3229:        /* horizontal delay */
        !          3230:        if (bktr->capture_area_enabled)
        !          3231:          temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
        !          3232:                 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
        !          3233:        else
        !          3234:          temp = (fp->hdelay * bktr->cols) / fp->hactive;
        !          3235:
        !          3236:        temp = temp & 0x3fe;
        !          3237:
        !          3238:        /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
        !          3239:        OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
        !          3240:        OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
        !          3241:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
        !          3242:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
        !          3243:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
        !          3244:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
        !          3245:
        !          3246:        /* vertical scale */
        !          3247:
        !          3248:        if (bktr->capture_area_enabled) {
        !          3249:          if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
        !          3250:              bktr->flags & METEOR_ONLY_EVEN_FIELDS)
        !          3251:            tmp_int = 65536 -
        !          3252:            (((bktr->capture_area_y_size  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
        !          3253:          else {
        !          3254:            tmp_int = 65536 -
        !          3255:            (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
        !          3256:          }
        !          3257:        } else {
        !          3258:          if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
        !          3259:              bktr->flags & METEOR_ONLY_EVEN_FIELDS)
        !          3260:            tmp_int = 65536 -
        !          3261:            (((fp->vactive  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
        !          3262:          else {
        !          3263:            tmp_int = 65536  -
        !          3264:            (((fp->vactive * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
        !          3265:          }
        !          3266:        }
        !          3267:
        !          3268:        tmp_int &= 0x1fff;
        !          3269:        /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
        !          3270:        OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
        !          3271:        OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
        !          3272:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
        !          3273:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
        !          3274:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
        !          3275:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
        !          3276:
        !          3277:
        !          3278:        /* vertical active */
        !          3279:        if (bktr->capture_area_enabled)
        !          3280:          temp = bktr->capture_area_y_size;
        !          3281:        else
        !          3282:          temp = fp->vactive;
        !          3283:        /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
        !          3284:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
        !          3285:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
        !          3286:        OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
        !          3287:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
        !          3288:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
        !          3289:        OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
        !          3290:
        !          3291:        /* vertical delay */
        !          3292:        if (bktr->capture_area_enabled)
        !          3293:          temp = fp->vdelay + (bktr->capture_area_y_offset);
        !          3294:        else
        !          3295:          temp = fp->vdelay;
        !          3296:        /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
        !          3297:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
        !          3298:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
        !          3299:        OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
        !          3300:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
        !          3301:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
        !          3302:        OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
        !          3303:
        !          3304:        /* end of video params */
        !          3305:
        !          3306:        if ((bktr->xtal_pll_mode == BT848_USE_PLL)
        !          3307:           && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
        !          3308:                OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
        !          3309:        } else {
        !          3310:                OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
        !          3311:        }
        !          3312:
        !          3313:        /* capture control */
        !          3314:        switch (i_flag) {
        !          3315:        case 1:
        !          3316:                bktr->bktr_cap_ctl =
        !          3317:                    (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
        !          3318:                OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
        !          3319:                OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
        !          3320:                interlace = 1;
        !          3321:                break;
        !          3322:         case 2:
        !          3323:                bktr->bktr_cap_ctl =
        !          3324:                        (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
        !          3325:                OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
        !          3326:                OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
        !          3327:                interlace = 1;
        !          3328:                break;
        !          3329:         default:
        !          3330:                bktr->bktr_cap_ctl =
        !          3331:                        (BT848_CAP_CTL_DITH_FRAME |
        !          3332:                         BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
        !          3333:                OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
        !          3334:                OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
        !          3335:                interlace = 2;
        !          3336:                break;
        !          3337:        }
        !          3338:
        !          3339:        OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
        !          3340:
        !          3341:        rows = bktr->rows;
        !          3342:        cols = bktr->cols;
        !          3343:
        !          3344:        bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
        !          3345:
        !          3346:        /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
        !          3347:        /* user, then use the rgb_vbi RISC program. */
        !          3348:        /* Otherwise, use the normal rgb RISC program */
        !          3349:        if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
        !          3350:                if ( (bktr->vbiflags & VBI_OPEN)
        !          3351:                   ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
        !          3352:                   ||(bktr->format_params == BT848_IFORM_F_SECAM)
        !          3353:                    ){
        !          3354:                        bktr->bktr_cap_ctl |=
        !          3355:                                BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
        !          3356:                        bktr->vbiflags |= VBI_CAPTURE;
        !          3357:                        rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
        !          3358:                        return;
        !          3359:                } else {
        !          3360:                        rgb_prog(bktr, i_flag, cols, rows, interlace);
        !          3361:                        return;
        !          3362:                }
        !          3363:        }
        !          3364:
        !          3365:        if ( pf_int->public.type  == METEOR_PIXTYPE_YUV ) {
        !          3366:                yuv422_prog(bktr, i_flag, cols, rows, interlace);
        !          3367:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
        !          3368:                     | pixfmt_swap_flags( bktr->pixfmt ));
        !          3369:                return;
        !          3370:        }
        !          3371:
        !          3372:        if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_PACKED ) {
        !          3373:                yuvpack_prog(bktr, i_flag, cols, rows, interlace);
        !          3374:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
        !          3375:                     | pixfmt_swap_flags( bktr->pixfmt ));
        !          3376:                return;
        !          3377:        }
        !          3378:
        !          3379:        if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_12 ) {
        !          3380:                yuv12_prog(bktr, i_flag, cols, rows, interlace);
        !          3381:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
        !          3382:                     | pixfmt_swap_flags( bktr->pixfmt ));
        !          3383:                return;
        !          3384:        }
        !          3385:        return;
        !          3386: }
        !          3387:
        !          3388:
        !          3389: /******************************************************************************
        !          3390:  * video & video capture specific routines:
        !          3391:  */
        !          3392:
        !          3393:
        !          3394: /*
        !          3395:  *
        !          3396:  */
        !          3397: static void
        !          3398: start_capture( bktr_ptr_t bktr, unsigned type )
        !          3399: {
        !          3400:        u_char                  i_flag;
        !          3401:        const struct format_params   *fp;
        !          3402:
        !          3403:        fp = &format_params[bktr->format_params];
        !          3404:
        !          3405:        /*  If requested, clear out capture buf first  */
        !          3406:        if (bktr->clr_on_start && (bktr->video.addr == 0)) {
        !          3407:                bzero((caddr_t)bktr->bigbuf,
        !          3408:                      (size_t)bktr->rows * bktr->cols * bktr->frames *
        !          3409:                        pixfmt_table[ bktr->pixfmt ].public.Bpp);
        !          3410:        }
        !          3411:
        !          3412:        OUTB(bktr, BKTR_DSTATUS,  0);
        !          3413:        OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
        !          3414:
        !          3415:        bktr->flags |= type;
        !          3416:        bktr->flags &= ~METEOR_WANT_MASK;
        !          3417:        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
        !          3418:        case METEOR_ONLY_EVEN_FIELDS:
        !          3419:                bktr->flags |= METEOR_WANT_EVEN;
        !          3420:                i_flag = 1;
        !          3421:                break;
        !          3422:        case METEOR_ONLY_ODD_FIELDS:
        !          3423:                bktr->flags |= METEOR_WANT_ODD;
        !          3424:                i_flag = 2;
        !          3425:                break;
        !          3426:        default:
        !          3427:                bktr->flags |= METEOR_WANT_MASK;
        !          3428:                i_flag = 3;
        !          3429:                break;
        !          3430:        }
        !          3431:
        !          3432:        /*  TDEC is only valid for continuous captures  */
        !          3433:        if ( type == METEOR_SINGLE ) {
        !          3434:                u_short fps_save = bktr->fps;
        !          3435:
        !          3436:                set_fps(bktr, fp->frame_rate);
        !          3437:                bktr->fps = fps_save;
        !          3438:        }
        !          3439:        else
        !          3440:                set_fps(bktr, bktr->fps);
        !          3441:
        !          3442:        if (bktr->dma_prog_loaded == FALSE) {
        !          3443:                build_dma_prog(bktr, i_flag);
        !          3444:                bktr->dma_prog_loaded = TRUE;
        !          3445:        }
        !          3446:
        !          3447:
        !          3448:        OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
        !          3449: }
        !          3450:
        !          3451:
        !          3452: /*
        !          3453:  *
        !          3454:  */
        !          3455: static void
        !          3456: set_fps( bktr_ptr_t bktr, u_short fps )
        !          3457: {
        !          3458:        const struct format_params      *fp;
        !          3459:        int i_flag;
        !          3460:
        !          3461:        fp = &format_params[bktr->format_params];
        !          3462:
        !          3463:        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
        !          3464:        case METEOR_ONLY_EVEN_FIELDS:
        !          3465:                bktr->flags |= METEOR_WANT_EVEN;
        !          3466:                i_flag = 1;
        !          3467:                break;
        !          3468:        case METEOR_ONLY_ODD_FIELDS:
        !          3469:                bktr->flags |= METEOR_WANT_ODD;
        !          3470:                i_flag = 1;
        !          3471:                break;
        !          3472:        default:
        !          3473:                bktr->flags |= METEOR_WANT_MASK;
        !          3474:                i_flag = 2;
        !          3475:                break;
        !          3476:        }
        !          3477:
        !          3478:        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
        !          3479:        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
        !          3480:
        !          3481:        bktr->fps = fps;
        !          3482:        OUTB(bktr, BKTR_TDEC, 0);
        !          3483:
        !          3484:        if (fps < fp->frame_rate)
        !          3485:                OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
        !          3486:        else
        !          3487:                OUTB(bktr, BKTR_TDEC, 0);
        !          3488:        return;
        !          3489:
        !          3490: }
        !          3491:
        !          3492:
        !          3493:
        !          3494:
        !          3495:
        !          3496: /*
        !          3497:  * Given a pixfmt index, compute the bt848 swap_flags necessary to
        !          3498:  *   achieve the specified swapping.
        !          3499:  * Note that without bt swapping, 2Bpp and 3Bpp modes are written
        !          3500:  *   byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
        !          3501:  *   and read R->L).
        !          3502:  * Note also that for 3Bpp, we may additionally need to do some creative
        !          3503:  *   SKIPing to align the FIFO bytelines with the target buffer (see split()).
        !          3504:  * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
        !          3505:  *   as one would expect.
        !          3506:  */
        !          3507:
        !          3508: static u_int pixfmt_swap_flags( int pixfmt )
        !          3509: {
        !          3510:        const struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
        !          3511:        u_int                 swapf = 0;
        !          3512:        int swap_bytes, swap_shorts;
        !          3513:
        !          3514: #if BYTE_ORDER == LITTLE_ENDIAN
        !          3515:        swap_bytes = pf->swap_bytes;
        !          3516:        swap_shorts = pf->swap_shorts;
        !          3517: #else
        !          3518:        swap_bytes = !pf->swap_bytes;
        !          3519:        swap_shorts = !pf->swap_shorts;
        !          3520: #endif
        !          3521:
        !          3522:        switch ( pf->Bpp ) {
        !          3523:        case 2:
        !          3524:                swapf = swap_bytes ? 0 : BSWAP;
        !          3525:                break;
        !          3526:
        !          3527:        case 3: /* no swaps supported for 3bpp - makes no sense w/ bt848 */
        !          3528:                break;
        !          3529:
        !          3530:        case 4:
        !          3531:                swapf = swap_bytes ? 0 : BSWAP;
        !          3532:                swapf |= swap_shorts ? 0 : WSWAP;
        !          3533:                break;
        !          3534:        }
        !          3535:        return swapf;
        !          3536: }
        !          3537:
        !          3538:
        !          3539:
        !          3540: /*
        !          3541:  * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
        !          3542:  *   our pixfmt_table indices.
        !          3543:  */
        !          3544:
        !          3545: static int oformat_meteor_to_bt( u_int format )
        !          3546: {
        !          3547:        int    i;
        !          3548:         const struct meteor_pixfmt *pf1, *pf2;
        !          3549:
        !          3550:        /*  Find format in compatibility table  */
        !          3551:        for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
        !          3552:                if ( meteor_pixfmt_table[i].meteor_format == format )
        !          3553:                        break;
        !          3554:
        !          3555:        if ( i >= METEOR_PIXFMT_TABLE_SIZE )
        !          3556:                return -1;
        !          3557:        pf1 = &meteor_pixfmt_table[i].public;
        !          3558:
        !          3559:        /*  Match it with an entry in master pixel format table  */
        !          3560:        for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
        !          3561:                pf2 = &pixfmt_table[i].public;
        !          3562:
        !          3563:                if (( pf1->type        == pf2->type        ) &&
        !          3564:                    ( pf1->Bpp         == pf2->Bpp         ) &&
        !          3565:                    !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
        !          3566:                    ( pf1->swap_bytes  == pf2->swap_bytes  ) &&
        !          3567:                    ( pf1->swap_shorts == pf2->swap_shorts ))
        !          3568:                        break;
        !          3569:        }
        !          3570:        if ( i >= PIXFMT_TABLE_SIZE )
        !          3571:                return -1;
        !          3572:
        !          3573:        return i;
        !          3574: }
        !          3575:
        !          3576: /******************************************************************************
        !          3577:  * i2c primitives:
        !          3578:  */
        !          3579:
        !          3580: /* */
        !          3581: #define I2CBITTIME             (0x5)   /* 5 * 0.48uS */
        !          3582: #define I2CBITTIME_878         (0x8)
        !          3583: #define I2C_READ               0x01
        !          3584: #define I2C_COMMAND            ((I2CBITTIME << 4) |            \
        !          3585:                                 BT848_DATA_CTL_I2CSCL |        \
        !          3586:                                 BT848_DATA_CTL_I2CSDA)
        !          3587:
        !          3588: #define I2C_COMMAND_878                ((I2CBITTIME_878 << 4) |        \
        !          3589:                                 BT848_DATA_CTL_I2CSCL |        \
        !          3590:                                 BT848_DATA_CTL_I2CSDA)
        !          3591:
        !          3592: /*
        !          3593:  * Program the i2c bus directly
        !          3594:  */
        !          3595: int
        !          3596: i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
        !          3597: {
        !          3598:        u_int           x;
        !          3599:        u_int           data;
        !          3600:
        !          3601:        /* clear status bits */
        !          3602:        OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
        !          3603:
        !          3604:        /* build the command datum */
        !          3605:        if (bktr->id == BROOKTREE_848  ||
        !          3606:            bktr->id == BROOKTREE_848A ||
        !          3607:            bktr->id == BROOKTREE_849A) {
        !          3608:          data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
        !          3609:        } else {
        !          3610:          data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
        !          3611:        }
        !          3612:        if ( byte2 != -1 ) {
        !          3613:                data |= ((byte2 & 0xff) << 8);
        !          3614:                data |= BT848_DATA_CTL_I2CW3B;
        !          3615:        }
        !          3616:
        !          3617:        /* write the address and data */
        !          3618:        OUTL(bktr, BKTR_I2C_DATA_CTL, data);
        !          3619:
        !          3620:        /* wait for completion */
        !          3621:        for ( x = 0x7fffffff; x; --x ) {        /* safety valve */
        !          3622:                if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
        !          3623:                        break;
        !          3624:        }
        !          3625:
        !          3626:        /* check for ACK */
        !          3627:        if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
        !          3628:                return( -1 );
        !          3629:
        !          3630:        /* return OK */
        !          3631:        return( 0 );
        !          3632: }
        !          3633:
        !          3634:
        !          3635: /*
        !          3636:  *
        !          3637:  */
        !          3638: int
        !          3639: i2cRead( bktr_ptr_t bktr, int addr )
        !          3640: {
        !          3641:        u_int32_t x, stat;
        !          3642:
        !          3643:        /* clear status bits */
        !          3644:        OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
        !          3645:
        !          3646:        /* write the READ address */
        !          3647:        /* The Bt878 and Bt879  differed on the treatment of i2c commands */
        !          3648:
        !          3649:        if (bktr->id == BROOKTREE_848  ||
        !          3650:            bktr->id == BROOKTREE_848A ||
        !          3651:            bktr->id == BROOKTREE_849A)
        !          3652:                OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
        !          3653:        else
        !          3654:                OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
        !          3655:
        !          3656:        /* wait for completion */
        !          3657:        for (x = 5000; x--; DELAY(1))   /* 5 msec, safety valve */
        !          3658:                if ((stat = INL(bktr, BKTR_INT_STAT)) & BT848_INT_I2CDONE)
        !          3659:                        break;
        !          3660:
        !          3661:        /* check for ACK */
        !          3662:        if ((stat & (I2C_BITS)) != (I2C_BITS))
        !          3663:                return (-1);
        !          3664:
        !          3665:        /* it was a read */
        !          3666:        x = INL(bktr, BKTR_I2C_DATA_CTL);
        !          3667:        return ((x >> 8) & 0xff);
        !          3668: }
        !          3669:
        !          3670: /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
        !          3671: /* bt848 automated i2c bus controller cannot handle */
        !          3672: /* Therefore we need low level control of the i2c bus hardware */
        !          3673: /* Idea for the following functions are from elsewhere in this driver and */
        !          3674: /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
        !          3675:
        !          3676: #define BITD    40
        !          3677: static void i2c_start( bktr_ptr_t bktr) {
        !          3678:         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
        !          3679:         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
        !          3680:         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
        !          3681:         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
        !          3682: }
        !          3683:
        !          3684: static void i2c_stop( bktr_ptr_t bktr) {
        !          3685:         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
        !          3686:         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
        !          3687:         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
        !          3688: }
        !          3689:
        !          3690: static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
        !          3691:         int x;
        !          3692:         int status;
        !          3693:
        !          3694:         /* write out the byte */
        !          3695:         for ( x = 7; x >= 0; --x ) {
        !          3696:                 if ( data & (1<<x) ) {
        !          3697:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3698:                         DELAY( BITD );          /* assert HI data */
        !          3699:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
        !          3700:                         DELAY( BITD );          /* strobe clock */
        !          3701:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3702:                         DELAY( BITD );          /* release clock */
        !          3703:                 }
        !          3704:                 else {
        !          3705:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
        !          3706:                         DELAY( BITD );          /* assert LO data */
        !          3707:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
        !          3708:                         DELAY( BITD );          /* strobe clock */
        !          3709:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
        !          3710:                         DELAY( BITD );          /* release clock */
        !          3711:                 }
        !          3712:         }
        !          3713:
        !          3714:         /* look for an ACK */
        !          3715:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
        !          3716:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
        !          3717:         status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;       /* read the ACK bit */
        !          3718:         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
        !          3719:
        !          3720:         return( status );
        !          3721: }
        !          3722:
        !          3723: static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
        !          3724:         int x;
        !          3725:         int bit;
        !          3726:         int byte = 0;
        !          3727:
        !          3728:         /* read in the byte */
        !          3729:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3730:         DELAY( BITD );                          /* float data */
        !          3731:         for ( x = 7; x >= 0; --x ) {
        !          3732:                OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
        !          3733:                 DELAY( BITD );                  /* strobe clock */
        !          3734:                 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1;  /* read the data bit */
        !          3735:                 if ( bit ) byte |= (1<<x);
        !          3736:                OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3737:                 DELAY( BITD );                  /* release clock */
        !          3738:         }
        !          3739:         /* After reading the byte, send an ACK */
        !          3740:         /* (unless that was the last byte, for which we send a NAK */
        !          3741:         if (last) { /* send NAK - same a writing a 1 */
        !          3742:                OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3743:                 DELAY( BITD );                  /* set data bit */
        !          3744:                OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
        !          3745:                 DELAY( BITD );                  /* strobe clock */
        !          3746:                OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3747:                 DELAY( BITD );                  /* release clock */
        !          3748:         } else { /* send ACK - same as writing a 0 */
        !          3749:                OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
        !          3750:                 DELAY( BITD );                  /* set data bit */
        !          3751:                OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
        !          3752:                 DELAY( BITD );                  /* strobe clock */
        !          3753:                OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
        !          3754:                 DELAY( BITD );                  /* release clock */
        !          3755:         }
        !          3756:
        !          3757:         *data=byte;
        !          3758:        return 0;
        !          3759: }
        !          3760: #undef BITD
        !          3761:
        !          3762: /* Write to the MSP or DPL registers */
        !          3763: void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
        !          3764:                    unsigned int data){
        !          3765:        unsigned int msp_w_addr = i2c_addr;
        !          3766:        unsigned char addr_l, addr_h, data_h, data_l ;
        !          3767:        addr_h = (addr >>8) & 0xff;
        !          3768:        addr_l = addr & 0xff;
        !          3769:        data_h = (data >>8) & 0xff;
        !          3770:        data_l = data & 0xff;
        !          3771:
        !          3772:        i2c_start(bktr);
        !          3773:        i2c_write_byte(bktr, msp_w_addr);
        !          3774:        i2c_write_byte(bktr, dev);
        !          3775:        i2c_write_byte(bktr, addr_h);
        !          3776:        i2c_write_byte(bktr, addr_l);
        !          3777:        i2c_write_byte(bktr, data_h);
        !          3778:        i2c_write_byte(bktr, data_l);
        !          3779:        i2c_stop(bktr);
        !          3780: }
        !          3781:
        !          3782: /* Read from the MSP or DPL registers */
        !          3783: unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
        !          3784:        unsigned int data;
        !          3785:        unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
        !          3786:        addr_h = (addr >>8) & 0xff;
        !          3787:        addr_l = addr & 0xff;
        !          3788:        dev_r = dev+1;
        !          3789:
        !          3790:        i2c_start(bktr);
        !          3791:        i2c_write_byte(bktr,i2c_addr);
        !          3792:        i2c_write_byte(bktr,dev_r);
        !          3793:        i2c_write_byte(bktr,addr_h);
        !          3794:        i2c_write_byte(bktr,addr_l);
        !          3795:
        !          3796:        i2c_start(bktr);
        !          3797:        i2c_write_byte(bktr,i2c_addr+1);
        !          3798:        i2c_read_byte(bktr,&data_1, 0);
        !          3799:        i2c_read_byte(bktr,&data_2, 1);
        !          3800:        i2c_stop(bktr);
        !          3801:        data = (data_1<<8) | data_2;
        !          3802:        return data;
        !          3803: }
        !          3804:
        !          3805: /* Reset the MSP or DPL chip */
        !          3806: /* The user can block the reset (which is handy if you initialise the
        !          3807:  * MSP audio in another operating system first (eg in Windows)
        !          3808:  */
        !          3809: void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
        !          3810:
        !          3811: #ifndef BKTR_NO_MSP_RESET
        !          3812:        /* put into reset mode */
        !          3813:        i2c_start(bktr);
        !          3814:        i2c_write_byte(bktr, i2c_addr);
        !          3815:        i2c_write_byte(bktr, 0x00);
        !          3816:        i2c_write_byte(bktr, 0x80);
        !          3817:        i2c_write_byte(bktr, 0x00);
        !          3818:        i2c_stop(bktr);
        !          3819:
        !          3820:        /* put back to operational mode */
        !          3821:        i2c_start(bktr);
        !          3822:        i2c_write_byte(bktr, i2c_addr);
        !          3823:        i2c_write_byte(bktr, 0x00);
        !          3824:        i2c_write_byte(bktr, 0x00);
        !          3825:        i2c_write_byte(bktr, 0x00);
        !          3826:        i2c_stop(bktr);
        !          3827: #endif
        !          3828:        return;
        !          3829:
        !          3830: }
        !          3831:
        !          3832: static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
        !          3833:
        !          3834:        /* XXX errors ignored */
        !          3835:        i2c_start(bktr);
        !          3836:        i2c_write_byte(bktr,bktr->remote_control_addr);
        !          3837:        i2c_read_byte(bktr,&(remote->data[0]), 0);
        !          3838:        i2c_read_byte(bktr,&(remote->data[1]), 0);
        !          3839:        i2c_read_byte(bktr,&(remote->data[2]), 0);
        !          3840:        i2c_stop(bktr);
        !          3841:
        !          3842:        return;
        !          3843: }
        !          3844:
        !          3845: #if defined( I2C_SOFTWARE_PROBE )
        !          3846:
        !          3847: /*
        !          3848:  * we are keeping this around for any parts that we need to probe
        !          3849:  * but that CANNOT be probed via an i2c read.
        !          3850:  * this is necessary because the hardware i2c mechanism
        !          3851:  * cannot be programmed for 1 byte writes.
        !          3852:  * currently there are no known i2c parts that we need to probe
        !          3853:  * and that cannot be safely read.
        !          3854:  */
        !          3855: static int     i2cProbe( bktr_ptr_t bktr, int addr );
        !          3856: #define BITD           40
        !          3857: #define EXTRA_START
        !          3858:
        !          3859: /*
        !          3860:  * probe for an I2C device at addr.
        !          3861:  */
        !          3862: static int
        !          3863: i2cProbe( bktr_ptr_t bktr, int addr )
        !          3864: {
        !          3865:        int             x, status;
        !          3866:
        !          3867:        /* the START */
        !          3868: #if defined( EXTRA_START )
        !          3869:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* release data */
        !          3870:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* release clock */
        !          3871: #endif /* EXTRA_START */
        !          3872:        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );        /* lower data */
        !          3873:        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );        /* lower clock */
        !          3874:
        !          3875:        /* write addr */
        !          3876:        for ( x = 7; x >= 0; --x ) {
        !          3877:                if ( addr & (1<<x) ) {
        !          3878:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3879:                        DELAY( BITD );          /* assert HI data */
        !          3880:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
        !          3881:                        DELAY( BITD );          /* strobe clock */
        !          3882:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
        !          3883:                        DELAY( BITD );          /* release clock */
        !          3884:                }
        !          3885:                else {
        !          3886:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
        !          3887:                        DELAY( BITD );          /* assert LO data */
        !          3888:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
        !          3889:                        DELAY( BITD );          /* strobe clock */
        !          3890:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
        !          3891:                        DELAY( BITD );          /* release clock */
        !          3892:                }
        !          3893:        }
        !          3894:
        !          3895:        /* look for an ACK */
        !          3896:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* float data */
        !          3897:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* strobe clock */
        !          3898:        status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;      /* read the ACK bit */
        !          3899:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* release clock */
        !          3900:
        !          3901:        /* the STOP */
        !          3902:        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );        /* lower clock & data */
        !          3903:        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );        /* release clock */
        !          3904:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* release data */
        !          3905:
        !          3906:        return( status );
        !          3907: }
        !          3908: #undef EXTRA_START
        !          3909: #undef BITD
        !          3910:
        !          3911: #endif /* I2C_SOFTWARE_PROBE */

CVSweb