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