The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/bktr/bktr_core.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: b286d425fbfe9a8424c0ee745ff39279


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.