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