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