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