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