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