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