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