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