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