[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

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