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