LCOV - code coverage report
Current view: top level - dev/pci/bktr - bktr_core.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1691 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 38 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13