xref: /netbsd/sys/dev/pci/bktr/bktr_core.c (revision 647e93ed)
1 /* $SourceForge: bktr_core.c,v 1.6 2003/03/11 23:11:22 thomasklausner Exp $ */
2 
3 /*	$NetBSD: bktr_core.c,v 1.59 2021/12/19 22:03:41 andvar 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 programs.
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.59 2021/12/19 22:03:41 andvar 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 video 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 sequence */
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 interrupt 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 		/* Unfortunately 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 			/* FALLTHROUGH */
2443 		default:
2444 			return(EINVAL);
2445 		}
2446 		break;
2447 
2448 	case METEORGINPUT:	/* get input device */
2449 		*(u_int *)arg = bktr->flags & METEOR_DEV_MASK;
2450 		break;
2451 
2452 	case METEORSACTPIXFMT:
2453 		if ((*(int *)arg < 0) ||
2454 		    (*(int *)arg >= PIXFMT_TABLE_SIZE))
2455 			return(EINVAL);
2456 
2457 		bktr->pixfmt          = *(int *)arg;
2458 		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2459 		     | pixfmt_swap_flags(bktr->pixfmt));
2460 		bktr->pixfmt_compat   = FALSE;
2461 		break;
2462 
2463 	case METEORGACTPIXFMT:
2464 		*(int *)arg = bktr->pixfmt;
2465 		break;
2466 
2467 	case METEORGSUPPIXFMT :
2468 		pf_pub = (struct meteor_pixfmt *)arg;
2469 		pixfmt = pf_pub->index;
2470 
2471 		if ((pixfmt < 0) || (pixfmt >= PIXFMT_TABLE_SIZE))
2472 			return(EINVAL);
2473 
2474 		memcpy(pf_pub, &pixfmt_table[pixfmt].public,
2475 			sizeof(*pf_pub));
2476 
2477 		/*  Patch in our format index  */
2478 		pf_pub->index       = pixfmt;
2479 		break;
2480 
2481 #if defined(STATUS_SUM)
2482 	case BT848_GSTATUS:	/* reap status */
2483 		{
2484                 DECLARE_INTR_MASK(s);
2485 		DISABLE_INTR(s);
2486 		temp = status_sum;
2487 		status_sum = 0;
2488 		ENABLE_INTR(s);
2489 		*(u_int*)arg = temp;
2490 		break;
2491 		}
2492 #endif /* STATUS_SUM */
2493 
2494 	default:
2495 		return(ENOTTY);
2496 	}
2497 
2498 	return(0);
2499 }
2500 
2501 
2502 
2503 
2504 /******************************************************************************
2505  * bt848 RISC programming routines:
2506  */
2507 
2508 
2509 /*
2510  *
2511  */
2512 #ifdef BT848_DEBUG
2513 static int
2514 dump_bt848(bktr_ptr_t bktr)
2515 {
2516 	int	r[60]={
2517 			   4,    8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2518 			0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2519 			0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2520 			0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2521 			0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2522 			0,	 0,    0,    0
2523 		   };
2524 	int	i;
2525 
2526 	for (i = 0; i < 40; i+=4) {
2527 		printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2528 		       bktr_name(bktr),
2529 		       r[i], INL(bktr, r[i]),
2530 		       r[i+1], INL(bktr, r[i+1]),
2531 		       r[i+2], INL(bktr, r[i+2]),
2532 		       r[i+3], INL(bktr, r[i+3]));
2533 	}
2534 
2535 	printf("%s: INT STAT %x \n", bktr_name(bktr),
2536 	       INL(bktr, BKTR_INT_STAT));
2537 	printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2538 	       INL(bktr, BKTR_INT_MASK));
2539 	printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2540 	       INW(bktr, BKTR_GPIO_DMA_CTL));
2541 
2542 	return(0);
2543 }
2544 
2545 #endif
2546 
2547 /*
2548  * build write instruction
2549  */
2550 #define BKTR_FM1      0x6	/* packed data to follow */
2551 #define BKTR_FM3      0xe	/* planar data to follow */
2552 #define BKTR_VRE      0x4	/* Marks the end of the even field */
2553 #define BKTR_VRO      0xC	/* Marks the end of the odd field */
2554 #define BKTR_PXV      0x0	/* valid word (never used) */
2555 #define BKTR_EOL      0x1	/* last dword, 4 bytes */
2556 #define BKTR_SOL      0x2	/* first dword */
2557 
2558 #define OP_WRITE      (0x1 << 28)
2559 #define OP_SKIP       (0x2 << 28)
2560 #define OP_WRITEC     (0x5 << 28)
2561 #define OP_JUMP	      (0x7 << 28)
2562 #define OP_SYNC	      (0x8 << 28)
2563 #define OP_WRITE123   (0x9 << 28)
2564 #define OP_WRITES123  (0xb << 28)
2565 #define OP_SOL	      (1 << 27)		/* first instr for scanline */
2566 #define OP_EOL	      (1 << 26)
2567 
2568 #define BKTR_RESYNC   (1 << 15)
2569 #define BKTR_GEN_IRQ  (1 << 24)
2570 
2571 /*
2572  * The RISC status bits can be set/cleared in the RISC programs
2573  * and tested in the Interrupt Handler
2574  */
2575 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2576 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2577 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2578 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2579 
2580 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2581 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2582 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2583 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2584 
2585 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2586 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2587 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2588 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2589 
2590 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2591     int i;
2592     bktr_clip_t * clip_node;
2593     bktr->clip_start = -1;
2594     bktr->last_y = 0;
2595     bktr->y = 0;
2596     bktr->y2 = width;
2597     bktr->line_length = width;
2598     bktr->yclip = -1;
2599     bktr->yclip2 = -1;
2600     bktr->current_col = 0;
2601 
2602     if (bktr->max_clip_node == 0) return TRUE;
2603     clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2604 
2605 
2606     for (i = 0; i < bktr->max_clip_node; i++) {
2607 	clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2608 	if (x >= clip_node->x_min && x <= clip_node->x_max) {
2609 	    bktr->clip_start = i;
2610 	    return FALSE;
2611 	}
2612     }
2613 
2614     return TRUE;
2615 }
2616 
2617 static bool_t getline(bktr_reg_t *bktr, int x) {
2618     int i, j;
2619     bktr_clip_t * clip_node;
2620 
2621     if (bktr->line_length == 0 ||
2622 	bktr->current_col >= bktr->line_length) return FALSE;
2623 
2624     bktr->y = uimin(bktr->last_y, bktr->line_length);
2625     bktr->y2 = bktr->line_length;
2626 
2627     bktr->yclip = bktr->yclip2 = -1;
2628     for (i = bktr->clip_start; i < bktr->max_clip_node; i++) {
2629 	clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2630 	if (x >= clip_node->x_min && x <= clip_node->x_max) {
2631 	    if (bktr->last_y <= clip_node->y_min) {
2632 		bktr->y =      uimin(bktr->last_y, bktr->line_length);
2633 		bktr->y2 =     uimin(clip_node->y_min, bktr->line_length);
2634 		bktr->yclip =  uimin(clip_node->y_min, bktr->line_length);
2635 		bktr->yclip2 = uimin(clip_node->y_max, bktr->line_length);
2636 		bktr->last_y = bktr->yclip2;
2637 		bktr->clip_start = i;
2638 
2639 		for (j = i+1; j < bktr->max_clip_node; j++) {
2640 		    clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2641 		    if (x >= clip_node->x_min && x <= clip_node->x_max) {
2642 			if (bktr->last_y >= clip_node->y_min) {
2643 			    bktr->yclip2 = uimin(clip_node->y_max, bktr->line_length);
2644 			    bktr->last_y = bktr->yclip2;
2645 			    bktr->clip_start = j;
2646 			}
2647 		    } else break;
2648 		}
2649 		return TRUE;
2650 	    }
2651 	}
2652     }
2653 
2654     if (bktr->current_col <= bktr->line_length) {
2655 	bktr->current_col = bktr->line_length;
2656 	return TRUE;
2657     }
2658     return FALSE;
2659 }
2660 
2661 static bool_t split(bktr_reg_t * bktr, volatile u_int **dma_prog, int width ,
2662 		    u_int operation, int pixel_width,
2663 		    volatile u_char ** target_buffer, int cols) {
2664 
2665  u_int flag, flag2;
2666  const struct meteor_pixfmt *pf = &pixfmt_table[bktr->pixfmt].public;
2667  u_int  skip, start_skip;
2668 
2669   /*  For RGB24, we need to align the component in FIFO Byte Lane 0         */
2670   /*    to the 1st byte in the mem dword containing our start addr.         */
2671   /*    BTW, we know this pixfmt's 1st byte is Blue; thus the start addr    */
2672   /*     must be Blue.                                                      */
2673   start_skip = 0;
2674   if ((pf->type == METEOR_PIXTYPE_RGB) && (pf->Bpp == 3))
2675 	  switch (((uintptr_t) (volatile void *) *target_buffer) % 4) {
2676 	  case 2 : start_skip = 4; break;
2677 	  case 1 : start_skip = 8; break;
2678 	  }
2679 
2680  if ((width * pixel_width) < DMA_BT848_SPLIT) {
2681      if (width == cols) {
2682 	 flag = OP_SOL | OP_EOL;
2683        } else if (bktr->current_col == 0) {
2684 	    flag  = OP_SOL;
2685        } else if (bktr->current_col == cols) {
2686 	    flag = OP_EOL;
2687        } else flag = 0;
2688 
2689      skip = 0;
2690      if ((flag & OP_SOL) && (start_skip > 0)) {
2691 	     *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2692 	     flag &= ~OP_SOL;
2693 	     skip = start_skip;
2694      }
2695 
2696      *(*dma_prog)++ = htole32(operation | flag  |
2697     	(width * pixel_width - skip));
2698      if (operation != OP_SKIP)
2699 	 *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2700 
2701      *target_buffer += width * pixel_width;
2702      bktr->current_col += width;
2703 
2704  } else {
2705 
2706 	if (bktr->current_col == 0 && width == cols) {
2707 	    flag = OP_SOL;
2708 	    flag2 = OP_EOL;
2709         } else if (bktr->current_col == 0) {
2710 	    flag = OP_SOL;
2711 	    flag2 = 0;
2712 	} else if (bktr->current_col >= cols)  {
2713 	    flag =  0;
2714 	    flag2 = OP_EOL;
2715 	} else {
2716 	    flag =  0;
2717 	    flag2 = 0;
2718 	}
2719 
2720 	skip = 0;
2721 	if ((flag & OP_SOL) && (start_skip > 0)) {
2722 		*(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2723 		flag &= ~OP_SOL;
2724 		skip = start_skip;
2725 	}
2726 
2727 	*(*dma_prog)++ = htole32(operation  | flag |
2728 	      (width * pixel_width / 2 - skip));
2729 	if (operation != OP_SKIP)
2730 	      *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2731 	*target_buffer +=  (width * pixel_width / 2);
2732 
2733 	if (operation == OP_WRITE)
2734 		operation = OP_WRITEC;
2735 	*(*dma_prog)++ = htole32(operation | flag2 |
2736 	    (width * pixel_width / 2));
2737 	*target_buffer +=  (width * pixel_width / 2);
2738 	  bktr->current_col += width;
2739 
2740     }
2741  return TRUE;
2742 }
2743 
2744 
2745 /*
2746  * Generate the RISC instructions to capture both VBI and video images
2747  */
2748 static void
2749 rgb_vbi_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2750 {
2751 	int			i;
2752 	volatile u_int		target_buffer, buffer, target,width;
2753 	volatile u_int		pitch;
2754 	volatile u_int		*dma_prog;	/* DMA prog is an array of
2755 						32 bit RISC instructions */
2756 	volatile bus_addr_t	loop_point;
2757         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
2758 	u_int                   Bpp = pf_int->public.Bpp;
2759 	unsigned int            vbisamples;     /* VBI samples per line */
2760 	unsigned int            vbilines;       /* VBI lines per field */
2761 	unsigned int            num_dwords;     /* DWORDS per line */
2762 
2763 	vbisamples = format_params[bktr->format_params].vbi_num_samples;
2764 	vbilines   = format_params[bktr->format_params].vbi_num_lines;
2765 	num_dwords = vbisamples/4;
2766 
2767 	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2768 	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2769 	OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2770 	OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay    */
2771 							    /* no ext frame */
2772 
2773 	OUTB(bktr, BKTR_OFORM, 0x00);
2774 
2775 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2776 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2777 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2778 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2779 
2780 	/* disable gamma correction removal */
2781 	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2782 
2783 	if (cols > 385) {
2784 	    OUTB(bktr, BKTR_E_VTC, 0);
2785 	    OUTB(bktr, BKTR_O_VTC, 0);
2786 	} else {
2787 	    OUTB(bktr, BKTR_E_VTC, 1);
2788 	    OUTB(bktr, BKTR_O_VTC, 1);
2789 	}
2790 	bktr->capcontrol = 3 << 2 |  3;
2791 
2792 	dma_prog = (u_int *) bktr->dma_prog;
2793 
2794 	/* Construct Write */
2795 
2796 	if (bktr->video.addr) {
2797 		target_buffer = (u_int) bktr->video.addr;
2798 		pitch = bktr->video.width;
2799 	}
2800 	else {
2801 		target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
2802 		pitch = cols*Bpp;
2803 	}
2804 
2805 	buffer = target_buffer;
2806 
2807 	/* Wait for the VRE sync marking the end of the Even and
2808 	 * the start of the Odd field. Resync here.
2809 	 */
2810 	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_VRE);
2811 	*dma_prog++ = htole32(0);
2812 
2813 	loop_point = bktr->dm_prog->dm_segs[0].ds_addr;
2814 
2815 	/* store the VBI data */
2816 	/* look for sync with packed data */
2817 	*dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2818 	*dma_prog++ = htole32(0);
2819 	for(i = 0; i < vbilines; i++) {
2820 		*dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2821 		*dma_prog++ = htole32((u_int)
2822 		    bktr->dm_vbidata->dm_segs[0].ds_addr + (i * VBI_LINE_SIZE));
2823 	}
2824 
2825 	if ((i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/) {
2826 		/* store the Odd field video image */
2827 		/* look for sync with packed data */
2828 		*dma_prog++ = htole32(OP_SYNC  | BKTR_FM1);
2829 		*dma_prog++ = htole32(0);  /* NULL WORD */
2830 		width = cols;
2831 		for (i = 0; i < (rows/interlace); i++) {
2832 		    target = target_buffer;
2833 		    if (notclipped(bktr, i, width)) {
2834 			split(bktr, (volatile u_int **) &dma_prog,
2835 			      bktr->y2 - bktr->y, OP_WRITE,
2836 			      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2837 
2838 		    } else {
2839 			while(getline(bktr, i)) {
2840 			    if (bktr->y != bktr->y2) {
2841 				split(bktr, (volatile u_int **) &dma_prog,
2842 				      bktr->y2 - bktr->y, OP_WRITE,
2843 				      Bpp, (volatile u_char **) (uintptr_t)&target, cols);
2844 			    }
2845 			    if (bktr->yclip != bktr->yclip2) {
2846 				split(bktr,(volatile u_int **) &dma_prog,
2847 				      bktr->yclip2 - bktr->yclip,
2848 				      OP_SKIP,
2849 				      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2850 			    }
2851 			}
2852 
2853 		    }
2854 
2855 		    target_buffer += interlace * pitch;
2856 
2857 		}
2858 
2859 	} /* end if */
2860 
2861 	/* Grab the Even field */
2862 	/* Look for the VRO, end of Odd field, marker */
2863 	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2864 	*dma_prog++ = htole32(0);  /* NULL WORD */
2865 
2866 	/* store the VBI data */
2867 	/* look for sync with packed data */
2868 	*dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2869 	*dma_prog++ = htole32(0);
2870 	for(i = 0; i < vbilines; i++) {
2871 		*dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2872 		*dma_prog++ = htole32((u_int)
2873 		    bktr->dm_vbidata->dm_segs[0].ds_addr +
2874 		    ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2875 	}
2876 
2877 	/* store the video image */
2878 	if (i_flag == 1) /*Even Only*/
2879 	        target_buffer = buffer;
2880 	if (i_flag == 3) /*interlaced*/
2881 	        target_buffer = buffer+pitch;
2882 
2883 
2884 	if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2885 		/* look for sync with packed data */
2886 		*dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2887 		*dma_prog++ = htole32(0);  /* NULL WORD */
2888 		width = cols;
2889 		for (i = 0; i < (rows/interlace); i++) {
2890 		    target = target_buffer;
2891 		    if (notclipped(bktr, i, width)) {
2892 			split(bktr, (volatile u_int **) &dma_prog,
2893 			      bktr->y2 - bktr->y, OP_WRITE,
2894 			      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2895 		    } else {
2896 			while(getline(bktr, i)) {
2897 			    if (bktr->y != bktr->y2) {
2898 				split(bktr, (volatile u_int **) &dma_prog,
2899 				      bktr->y2 - bktr->y, OP_WRITE,
2900 				      Bpp, (volatile u_char **)(uintptr_t)&target,
2901 				      cols);
2902 			    }
2903 			    if (bktr->yclip != bktr->yclip2) {
2904 				split(bktr, (volatile u_int **) &dma_prog,
2905 				      bktr->yclip2 - bktr->yclip, OP_SKIP,
2906 				      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2907 			    }
2908 
2909 			}
2910 
2911 		    }
2912 
2913 		    target_buffer += interlace * pitch;
2914 
2915 		}
2916 	}
2917 
2918 	/* Look for end of 'Even Field' */
2919 	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2920 	*dma_prog++ = htole32(0);  /* NULL WORD */
2921 
2922 	*dma_prog++ = htole32(OP_JUMP);
2923 	*dma_prog++ = htole32(loop_point);
2924 	*dma_prog++ = htole32(0);  /* NULL WORD */
2925 
2926 }
2927 
2928 
2929 
2930 
2931 static void
2932 rgb_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2933 {
2934 	int			i;
2935 	volatile u_int		target_buffer, buffer, target,width;
2936 	volatile u_int		pitch;
2937 	volatile  u_int	*dma_prog;
2938         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
2939 	u_int                   Bpp = pf_int->public.Bpp;
2940 
2941 	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2942 	OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2943 	OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2944 	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2945 
2946 	OUTB(bktr, BKTR_OFORM, 0x00);
2947 
2948 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2949 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2950 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2951 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2952 
2953 	/* disable gamma correction removal */
2954 	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2955 
2956 	if (cols > 385) {
2957 	    OUTB(bktr, BKTR_E_VTC, 0);
2958 	    OUTB(bktr, BKTR_O_VTC, 0);
2959 	} else {
2960 	    OUTB(bktr, BKTR_E_VTC, 1);
2961 	    OUTB(bktr, BKTR_O_VTC, 1);
2962 	}
2963 	bktr->capcontrol = 3 << 2 |  3;
2964 
2965 	dma_prog = (u_int *) bktr->dma_prog;
2966 
2967 	/* Construct Write */
2968 
2969 	if (bktr->video.addr) {
2970 		target_buffer = (u_int) bktr->video.addr;
2971 		pitch = bktr->video.width;
2972 	}
2973 	else {
2974 		target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
2975 		pitch = cols*Bpp;
2976 	}
2977 
2978 	buffer = target_buffer;
2979 
2980 	/* construct sync : for video packet format */
2981 	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2982 
2983 	/* sync, mode indicator packed data */
2984 	*dma_prog++ = htole32(0);  /* NULL WORD */
2985 	width = cols;
2986 	for (i = 0; i < (rows/interlace); i++) {
2987 	    target = target_buffer;
2988 	    if (notclipped(bktr, i, width)) {
2989 		split(bktr, (volatile u_int **) &dma_prog,
2990 		      bktr->y2 - bktr->y, OP_WRITE,
2991 		      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2992 
2993 	    } else {
2994 		while(getline(bktr, i)) {
2995 		    if (bktr->y != bktr->y2) {
2996 			split(bktr, (volatile u_int **) &dma_prog,
2997 			      bktr->y2 - bktr->y, OP_WRITE,
2998 			      Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2999 		    }
3000 		    if (bktr->yclip != bktr->yclip2) {
3001 			split(bktr,(volatile u_int **) &dma_prog,
3002 			      bktr->yclip2 - bktr->yclip,
3003 			      OP_SKIP,
3004 			      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
3005 		    }
3006 		}
3007 
3008 	    }
3009 
3010 	    target_buffer += interlace * pitch;
3011 
3012 	}
3013 
3014 	switch (i_flag) {
3015 	case 1:
3016 		/* sync vre */
3017 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
3018 		*dma_prog++ = htole32(0);  /* NULL WORD */
3019 
3020 		*dma_prog++ = htole32(OP_JUMP);
3021 		*dma_prog++ = htole32((u_int)
3022 				bktr->dm_prog->dm_segs[0].ds_addr);
3023 		return;
3024 
3025 	case 2:
3026 		/* sync vro */
3027 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
3028 		*dma_prog++ = htole32(0);  /* NULL WORD */
3029 
3030 		*dma_prog++ = htole32(OP_JUMP);
3031 		*dma_prog++ = htole32((u_int)
3032 				bktr->dm_prog->dm_segs[0].ds_addr);
3033 		return;
3034 
3035 	case 3:
3036 		/* sync vro */
3037 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3038 		*dma_prog++ = htole32(0);  /* NULL WORD */
3039 		*dma_prog++ = htole32(OP_JUMP);
3040 		*dma_prog++ = htole32((u_int)
3041 				bktr->dm_oprog->dm_segs[0].ds_addr);
3042 		break;
3043 	}
3044 
3045 	if (interlace == 2) {
3046 
3047 	        target_buffer = buffer + pitch;
3048 
3049 		dma_prog = (u_int *) bktr->odd_dma_prog;
3050 
3051 		/* sync vre IRQ bit */
3052 		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3053 		*dma_prog++ = htole32(0);  /* NULL WORD */
3054                 width = cols;
3055 		for (i = 0; i < (rows/interlace); i++) {
3056 		    target = target_buffer;
3057 		    if (notclipped(bktr, i, width)) {
3058 			split(bktr, (volatile u_int **) &dma_prog,
3059 			      bktr->y2 - bktr->y, OP_WRITE,
3060 			      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
3061 		    } else {
3062 			while(getline(bktr, i)) {
3063 			    if (bktr->y != bktr->y2) {
3064 				split(bktr, (volatile u_int **) &dma_prog,
3065 				      bktr->y2 - bktr->y, OP_WRITE,
3066 				      Bpp, (volatile u_char **)(uintptr_t)&target,
3067 				      cols);
3068 			    }
3069 			    if (bktr->yclip != bktr->yclip2) {
3070 				split(bktr, (volatile u_int **) &dma_prog,
3071 				      bktr->yclip2 - bktr->yclip, OP_SKIP,
3072 				      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
3073 			    }
3074 
3075 			}
3076 
3077 		    }
3078 
3079 		    target_buffer += interlace * pitch;
3080 
3081 		}
3082 	}
3083 
3084 	/* sync vre IRQ bit */
3085 	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3086 	*dma_prog++ = htole32(0);  /* NULL WORD */
3087 	*dma_prog++ = htole32(OP_JUMP);
3088 	*dma_prog++ = htole32((u_int) bktr->dm_prog->dm_segs[0].ds_addr);
3089 	*dma_prog++ = htole32(0);  /* NULL WORD */
3090 }
3091 
3092 
3093 /*
3094  *
3095  */
3096 static void
3097 yuvpack_prog(bktr_ptr_t bktr, char i_flag,
3098 	      int cols, int rows, int interlace)
3099 {
3100 	int			i;
3101 	volatile unsigned int	inst;
3102 	volatile unsigned int	inst3;
3103 	volatile u_int		target_buffer, buffer;
3104 	volatile  u_int	*dma_prog;
3105         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3106 	int			b;
3107 
3108 	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3109 
3110 	OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3111 	OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3112 
3113 	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3114 	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3115 
3116 	bktr->capcontrol =   1 << 6 | 1 << 4 | 1 << 2 | 3;
3117 	bktr->capcontrol = 3 << 2 |  3;
3118 
3119 	dma_prog = (u_int *) bktr->dma_prog;
3120 
3121 	/* Construct Write */
3122 
3123 	/* write , sol, eol */
3124 	inst = OP_WRITE	 | OP_SOL | (cols);
3125 	/* write , sol, eol */
3126 	inst3 = OP_WRITE | OP_EOL | (cols);
3127 
3128 	if (bktr->video.addr)
3129 		target_buffer = (u_int) bktr->video.addr;
3130 	else
3131 		target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
3132 
3133 	buffer = target_buffer;
3134 
3135 	/* construct sync : for video packet format */
3136 	/* sync, mode indicator packed data */
3137 	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3138 	*dma_prog++ = htole32(0);  /* NULL WORD */
3139 
3140 	b = cols;
3141 
3142 	for (i = 0; i < (rows/interlace); i++) {
3143 		*dma_prog++ = htole32(inst);
3144 		*dma_prog++ = htole32(target_buffer);
3145 		*dma_prog++ = htole32(inst3);
3146 		*dma_prog++ = htole32(target_buffer + b);
3147 		target_buffer += interlace*(cols * 2);
3148 	}
3149 
3150 	switch (i_flag) {
3151 	case 1:
3152 		/* sync vre */
3153 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
3154 		*dma_prog++ = htole32(0);  /* NULL WORD */
3155 
3156 		*dma_prog++ = htole32(OP_JUMP);
3157 		*dma_prog++ = htole32(
3158 				(u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3159 		return;
3160 
3161 	case 2:
3162 		/* sync vro */
3163 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
3164 		*dma_prog++ = htole32(0);  /* NULL WORD */
3165 		*dma_prog++ = htole32(OP_JUMP);
3166 		*dma_prog++ = htole32((u_int)
3167 				bktr->dm_prog->dm_segs[0].ds_addr);
3168 		return;
3169 
3170 	case 3:
3171 		/* sync vro */
3172 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3173 		*dma_prog++ = htole32(0);  /* NULL WORD */
3174 		*dma_prog++ = htole32(OP_JUMP);
3175 		*dma_prog++ = htole32((u_int)
3176 				bktr->dm_oprog->dm_segs[0].ds_addr);
3177 		break;
3178 	}
3179 
3180 	if (interlace == 2) {
3181 
3182 		target_buffer =	 (u_int) buffer + cols*2;
3183 
3184 		dma_prog = (u_int *) bktr->odd_dma_prog;
3185 
3186 		/* sync vre */
3187 		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3188 		*dma_prog++ = htole32(0);  /* NULL WORD */
3189 
3190 		for (i = 0; i < (rows/interlace); i++) {
3191 			*dma_prog++ = htole32(inst);
3192 			*dma_prog++ = htole32(target_buffer);
3193 			*dma_prog++ = htole32(inst3);
3194 			*dma_prog++ = htole32(target_buffer + b);
3195 			target_buffer += interlace * (cols*2);
3196 		}
3197 	}
3198 
3199 	/* sync vro IRQ bit */
3200 	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3201 	*dma_prog++ = htole32(0);  /* NULL WORD */
3202 	*dma_prog++ = htole32(OP_JUMP);
3203 	*dma_prog++ = htole32((u_int) bktr->dm_prog->dm_segs[0].ds_addr);
3204 
3205 	*dma_prog++ = htole32(OP_JUMP);
3206 	*dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3207 	*dma_prog++ = htole32(0);  /* NULL WORD */
3208 }
3209 
3210 
3211 /*
3212  *
3213  */
3214 static void
3215 yuv422_prog(bktr_ptr_t bktr, char i_flag,
3216 	     int cols, int rows, int interlace) {
3217 
3218 	int			i;
3219 	volatile unsigned int	inst;
3220 	volatile u_int		target_buffer, t1, buffer;
3221 	volatile u_int		*dma_prog;
3222         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3223 
3224 	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3225 
3226 	dma_prog = (u_int *) bktr->dma_prog;
3227 
3228 	bktr->capcontrol =   1 << 6 | 1 << 4 |	3;
3229 
3230 	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3231 	OUTB(bktr, BKTR_OFORM, 0x00);
3232 
3233 	OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3234 	OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3235 
3236 	OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC);	/* chroma agc enable */
3237 	OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3238 
3239 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3240 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3241 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3242 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3243 
3244 	/* disable gamma correction removal */
3245 	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3246 
3247 	/* Construct Write */
3248 	inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
3249 	if (bktr->video.addr)
3250 		target_buffer = (u_int) bktr->video.addr;
3251 	else
3252 		target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
3253 
3254 	buffer = target_buffer;
3255 
3256 	t1 = buffer;
3257 
3258 	/* construct sync : for video packet format */
3259 	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3260 	*dma_prog++ = htole32(0);  /* NULL WORD */
3261 
3262 	for (i = 0; i < (rows/interlace); i++) {
3263 		*dma_prog++ = htole32(inst);
3264 		*dma_prog++ = htole32(cols/2 | cols/2 << 16);
3265 		*dma_prog++ = htole32(target_buffer);
3266 		*dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3267 		*dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3268 		target_buffer += interlace*cols;
3269 	}
3270 
3271 	switch (i_flag) {
3272 	case 1:
3273 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
3274 		*dma_prog++ = htole32(0);  /* NULL WORD */
3275 
3276 		*dma_prog++ = htole32(OP_JUMP);
3277 		*dma_prog++ = htole32((u_int)
3278 				bktr->dm_prog->dm_segs[0].ds_addr);
3279 		return;
3280 
3281 	case 2:
3282 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vre*/
3283 		*dma_prog++ = htole32(0);  /* NULL WORD */
3284 
3285 		*dma_prog++ = htole32(OP_JUMP);
3286 		*dma_prog++ = htole32((u_int)
3287 				bktr->dm_prog->dm_segs[0].ds_addr);
3288 		return;
3289 
3290 	case 3:
3291 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3292 		*dma_prog++ = htole32(0);  /* NULL WORD */
3293 
3294 		*dma_prog++ = htole32(OP_JUMP);
3295 		*dma_prog++ = htole32((u_int)
3296 				bktr->dm_oprog->dm_segs[0].ds_addr);
3297 		break;
3298 	}
3299 
3300 	if (interlace == 2) {
3301 
3302 		dma_prog = (u_int *) bktr->odd_dma_prog;
3303 
3304 		target_buffer  = (u_int) buffer + cols;
3305 		t1 = buffer + cols/2;
3306 		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3307 		*dma_prog++ = htole32(0);  /* NULL WORD */
3308 
3309 		for (i = 0; i < (rows/interlace); i++) {
3310 			*dma_prog++ = htole32(inst);
3311 			*dma_prog++ = htole32(cols/2 | cols/2 << 16);
3312 			*dma_prog++ = htole32(target_buffer);
3313 			*dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3314 			*dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3315 			target_buffer += interlace*cols;
3316 		}
3317 	}
3318 
3319 	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3320 	*dma_prog++ = htole32(0);  /* NULL WORD */
3321 	*dma_prog++ = htole32(OP_JUMP);
3322 	*dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3323 	*dma_prog++ = htole32(0);  /* NULL WORD */
3324 }
3325 
3326 
3327 /*
3328  *
3329  */
3330 static void
3331 yuv12_prog(bktr_ptr_t bktr, char i_flag,
3332 	     int cols, int rows, int interlace) {
3333 
3334 	int			i;
3335 	volatile unsigned int	inst;
3336 	volatile unsigned int	inst1;
3337 	volatile u_int		target_buffer, t1, buffer;
3338 	volatile u_int		*dma_prog;
3339         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3340 
3341 	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3342 
3343 	dma_prog = (u_int *) bktr->dma_prog;
3344 
3345 	bktr->capcontrol =   1 << 6 | 1 << 4 |	3;
3346 
3347 	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3348 	OUTB(bktr, BKTR_OFORM, 0x0);
3349 
3350 	/* Construct Write */
3351 	inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
3352 	inst1  = OP_WRITES123  | OP_SOL | OP_EOL |  (cols);
3353 	if (bktr->video.addr)
3354 		target_buffer = (u_int) bktr->video.addr;
3355 	else
3356 		target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
3357 
3358 	buffer = target_buffer;
3359 	t1 = buffer;
3360 
3361 	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3362 	*dma_prog++ = htole32(0);  /* NULL WORD */
3363 
3364 	for (i = 0; i < (rows/interlace)/2; i++) {
3365 		*dma_prog++ = htole32(inst);
3366 		*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3367 		*dma_prog++ = htole32(target_buffer);
3368 		*dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3369 		*dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3370 		target_buffer += interlace*cols;
3371 		*dma_prog++ = htole32(inst1);
3372 		*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3373 		*dma_prog++ = htole32(target_buffer);
3374 		target_buffer += interlace*cols;
3375 
3376 	}
3377 
3378 	switch (i_flag) {
3379 	case 1:
3380 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
3381 		*dma_prog++ = htole32(0);  /* NULL WORD */
3382 
3383 		*dma_prog++ = htole32(OP_JUMP);
3384 		*dma_prog++ = htole32((u_int)
3385 				bktr->dm_prog->dm_segs[0].ds_addr);
3386 		return;
3387 
3388 	case 2:
3389 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vro*/
3390 		*dma_prog++ = htole32(0);  /* NULL WORD */
3391 
3392 		*dma_prog++ = htole32(OP_JUMP);
3393 		*dma_prog++ = htole32((u_int)
3394 				bktr->dm_prog->dm_segs[0].ds_addr);
3395 		return;
3396 
3397 	case 3:
3398 		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3399 		*dma_prog++ = htole32(0);  /* NULL WORD */
3400 		*dma_prog++ = htole32(OP_JUMP);
3401 		*dma_prog++ = htole32((u_int)
3402 				bktr->dm_oprog->dm_segs[0].ds_addr);
3403 		break;
3404 	}
3405 
3406 	if (interlace == 2) {
3407 
3408 		dma_prog = (u_int *) bktr->odd_dma_prog;
3409 
3410 		target_buffer  = (u_int) buffer + cols;
3411 		t1 = buffer + cols/2;
3412 		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3413 		*dma_prog++ = htole32(0);  /* NULL WORD */
3414 
3415 		for (i = 0; i < ((rows/interlace)/2); i++) {
3416 		    *dma_prog++ = htole32(inst);
3417 		    *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3418 		    *dma_prog++ = htole32(target_buffer);
3419 		    *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3420 		    *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3421 		    target_buffer += interlace*cols;
3422 		    *dma_prog++ = htole32(inst1);
3423 		    *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3424 		    *dma_prog++ = htole32(target_buffer);
3425 		    target_buffer += interlace*cols;
3426 
3427 		}
3428 
3429 
3430 	}
3431 
3432 	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3433 	*dma_prog++ = htole32(0);  /* NULL WORD */
3434 	*dma_prog++ = htole32(OP_JUMP);
3435 	*dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3436 	*dma_prog++ = htole32(0);  /* NULL WORD */
3437 }
3438 
3439 
3440 
3441 /*
3442  *
3443  */
3444 static void
3445 build_dma_prog(bktr_ptr_t bktr, char i_flag)
3446 {
3447 	int			rows, cols,  interlace;
3448 	int			tmp_int;
3449 	unsigned int		temp;
3450 	const struct format_params	*fp;
3451         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3452 
3453 
3454 	fp = &format_params[bktr->format_params];
3455 
3456 	OUTL(bktr, BKTR_INT_MASK,  ALL_INTS_DISABLED);
3457 
3458 	/* disable FIFO & RISC, leave other bits alone */
3459 	OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3460 
3461 	/* set video parameters */
3462 	if (bktr->capture_area_enabled)
3463 	  temp = ((quad_t) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3464 		  / fp->scaled_htotal / bktr->cols) -  4096;
3465 	else
3466 	  temp = ((quad_t) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3467 		  / fp->scaled_htotal / bktr->cols) -  4096;
3468 
3469 	/* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3470 	OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3471 	OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3472 	OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3473 	OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3474 
3475 	/* horizontal active */
3476 	temp = bktr->cols;
3477 	/* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3478 	OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3479 	OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3480 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3481 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3482 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3483 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3484 
3485 	/* horizontal delay */
3486 	if (bktr->capture_area_enabled)
3487 	  temp = ((fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3488 		 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3489 	else
3490 	  temp = (fp->hdelay * bktr->cols) / fp->hactive;
3491 
3492 	temp = temp & 0x3fe;
3493 
3494 	/* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3495 	OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3496 	OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3497 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3498 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3499 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3500 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3501 
3502 	/* vertical scale */
3503 
3504 	if (bktr->capture_area_enabled) {
3505 	  if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3506 	      bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3507 	    tmp_int = 65536 -
3508 	    (((bktr->capture_area_y_size  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3509 	  else {
3510 	    tmp_int = 65536 -
3511 	    (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3512 	  }
3513 	} else {
3514 	  if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3515 	      bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3516 	    tmp_int = 65536 -
3517 	    (((fp->vactive  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3518 	  else {
3519 	    tmp_int = 65536  -
3520 	    (((fp->vactive * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3521 	  }
3522 	}
3523 
3524 	tmp_int &= 0x1fff;
3525 	/* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3526 	OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3527 	OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3528 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3529 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3530 	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3531 	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3532 
3533 
3534 	/* vertical active */
3535 	if (bktr->capture_area_enabled)
3536 	  temp = bktr->capture_area_y_size;
3537 	else
3538 	  temp = fp->vactive;
3539 	/* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3540 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3541 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3542 	OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3543 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3544 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3545 	OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3546 
3547 	/* vertical delay */
3548 	if (bktr->capture_area_enabled)
3549 	  temp = fp->vdelay + (bktr->capture_area_y_offset);
3550 	else
3551 	  temp = fp->vdelay;
3552 	/* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3553 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3554 	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3555 	OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3556 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3557 	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3558 	OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3559 
3560 	/* end of video params */
3561 
3562 	if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3563 	   && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3564 		OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3565 	} else {
3566 		OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3567 	}
3568 
3569 	/* capture control */
3570 	switch (i_flag) {
3571 	case 1:
3572 	        bktr->bktr_cap_ctl =
3573 		    (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3574 		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3575 		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3576 		interlace = 1;
3577 		break;
3578 	 case 2:
3579 	        bktr->bktr_cap_ctl =
3580 			(BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3581 		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3582 		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3583 		interlace = 1;
3584 		break;
3585 	 default:
3586 	        bktr->bktr_cap_ctl =
3587 			(BT848_CAP_CTL_DITH_FRAME |
3588 			 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3589 		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3590 		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3591 		interlace = 2;
3592 		break;
3593 	}
3594 
3595 	OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs[0].ds_addr);
3596 
3597 	rows = bktr->rows;
3598 	cols = bktr->cols;
3599 
3600 	bktr->vbiflags &= ~VBI_CAPTURE;	/* default - no vbi capture */
3601 
3602 	/* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3603 	/* user, then use the rgb_vbi RISC program. */
3604 	/* Otherwise, use the normal rgb RISC program */
3605 	if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3606 		if ((bktr->vbiflags & VBI_OPEN)
3607 		   ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3608 		   ||(bktr->format_params == BT848_IFORM_F_SECAM)) {
3609 			bktr->bktr_cap_ctl |=
3610 		                BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3611 			bktr->vbiflags |= VBI_CAPTURE;
3612 			rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3613 			return;
3614 		} else {
3615 			rgb_prog(bktr, i_flag, cols, rows, interlace);
3616 			return;
3617 		}
3618 	}
3619 
3620 	if (pf_int->public.type  == METEOR_PIXTYPE_YUV) {
3621 		yuv422_prog(bktr, i_flag, cols, rows, interlace);
3622 		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3623 		     | pixfmt_swap_flags(bktr->pixfmt));
3624 		return;
3625 	}
3626 
3627 	if (pf_int->public.type  == METEOR_PIXTYPE_YUV_PACKED) {
3628 		yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3629 		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3630 		     | pixfmt_swap_flags(bktr->pixfmt));
3631 		return;
3632 	}
3633 
3634 	if (pf_int->public.type  == METEOR_PIXTYPE_YUV_12) {
3635 		yuv12_prog(bktr, i_flag, cols, rows, interlace);
3636 		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3637 		     | pixfmt_swap_flags(bktr->pixfmt));
3638 		return;
3639 	}
3640 	return;
3641 }
3642 
3643 
3644 /******************************************************************************
3645  * video & video capture specific routines:
3646  */
3647 
3648 
3649 /*
3650  *
3651  */
3652 static void
3653 start_capture(bktr_ptr_t bktr, unsigned type)
3654 {
3655 	u_char			i_flag;
3656 	const struct format_params   *fp;
3657 
3658 	fp = &format_params[bktr->format_params];
3659 
3660 	/*  If requested, clear out capture buf first  */
3661 	if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3662 		memset((void *)bktr->bigbuf, 0,
3663 		      (size_t)bktr->rows * bktr->cols * bktr->frames *
3664 			pixfmt_table[bktr->pixfmt].public.Bpp);
3665 	}
3666 
3667 	OUTB(bktr, BKTR_DSTATUS,  0);
3668 	OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3669 
3670 	bktr->flags |= type;
3671 	bktr->flags &= ~METEOR_WANT_MASK;
3672 	switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3673 	case METEOR_ONLY_EVEN_FIELDS:
3674 		bktr->flags |= METEOR_WANT_EVEN;
3675 		i_flag = 1;
3676 		break;
3677 	case METEOR_ONLY_ODD_FIELDS:
3678 		bktr->flags |= METEOR_WANT_ODD;
3679 		i_flag = 2;
3680 		break;
3681 	default:
3682 		bktr->flags |= METEOR_WANT_MASK;
3683 		i_flag = 3;
3684 		break;
3685 	}
3686 
3687 	/*  TDEC is only valid for continuous captures  */
3688 	if (type == METEOR_SINGLE) {
3689 		u_short	fps_save = bktr->fps;
3690 
3691 		set_fps(bktr, fp->frame_rate);
3692 		bktr->fps = fps_save;
3693 	}
3694 	else
3695 		set_fps(bktr, bktr->fps);
3696 
3697 	if (bktr->dma_prog_loaded == FALSE) {
3698 		build_dma_prog(bktr, i_flag);
3699 		bktr->dma_prog_loaded = TRUE;
3700 	}
3701 
3702 
3703 	OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs[0].ds_addr);
3704 
3705 }
3706 
3707 
3708 /*
3709  *
3710  */
3711 static void
3712 set_fps(bktr_ptr_t bktr, u_short fps)
3713 {
3714 	const struct format_params	*fp;
3715 	int i_flag;
3716 
3717 	fp = &format_params[bktr->format_params];
3718 
3719 	switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3720 	case METEOR_ONLY_EVEN_FIELDS:
3721 		bktr->flags |= METEOR_WANT_EVEN;
3722 		i_flag = 1;
3723 		break;
3724 	case METEOR_ONLY_ODD_FIELDS:
3725 		bktr->flags |= METEOR_WANT_ODD;
3726 		i_flag = 1;
3727 		break;
3728 	default:
3729 		bktr->flags |= METEOR_WANT_MASK;
3730 		i_flag = 2;
3731 		break;
3732 	}
3733 
3734 	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3735 	OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3736 
3737 	bktr->fps = fps;
3738 	OUTB(bktr, BKTR_TDEC, 0);
3739 
3740 	if (fps < fp->frame_rate)
3741 		OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3742 	else
3743 		OUTB(bktr, BKTR_TDEC, 0);
3744 	return;
3745 
3746 }
3747 
3748 
3749 
3750 
3751 
3752 /*
3753  * Given a pixfmt index, compute the bt848 swap_flags necessary to
3754  *   achieve the specified swapping.
3755  * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3756  *   byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3757  *   and read R->L).
3758  * Note also that for 3Bpp, we may additionally need to do some creative
3759  *   SKIPing to align the FIFO bytelines with the target buffer (see split()).
3760  * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3761  *   as one would expect.
3762  */
3763 
3764 static u_int pixfmt_swap_flags(int pixfmt)
3765 {
3766 	const struct meteor_pixfmt *pf = &pixfmt_table[pixfmt].public;
3767 	u_int		      swapf = 0;
3768     	int swap_bytes, swap_shorts;
3769 
3770 #if BYTE_ORDER == LITTLE_ENDIAN
3771     	swap_bytes = pf->swap_bytes;
3772     	swap_shorts = pf->swap_shorts;
3773 #else
3774     	swap_bytes = !pf->swap_bytes;
3775     	swap_shorts = !pf->swap_shorts;
3776 #endif
3777 	switch (pf->Bpp) {
3778 	case 2 : swapf = (swap_bytes ? 0 : BSWAP);
3779 		 break;
3780 
3781 	case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3782 		 break;
3783 
3784 	case 4 :
3785     	    	swapf  = swap_bytes  ? 0 : BSWAP;
3786     	    	swapf |= swap_shorts ? 0 : WSWAP;
3787     	    	break;
3788 	}
3789 	return swapf;
3790 }
3791 
3792 
3793 
3794 /*
3795  * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3796  *   our pixfmt_table indices.
3797  */
3798 
3799 static int oformat_meteor_to_bt(u_int format)
3800 {
3801 	int    i;
3802         const struct meteor_pixfmt *pf1, *pf2;
3803 
3804 	/*  Find format in compatibility table  */
3805 	for (i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++)
3806 		if (meteor_pixfmt_table[i].meteor_format == format)
3807 			break;
3808 
3809 	if (i >= METEOR_PIXFMT_TABLE_SIZE)
3810 		return -1;
3811 	pf1 = &meteor_pixfmt_table[i].public;
3812 
3813 	/*  Match it with an entry in master pixel format table  */
3814 	for (i = 0; i < PIXFMT_TABLE_SIZE; i++) {
3815 		pf2 = &pixfmt_table[i].public;
3816 
3817 		if ((pf1->type        == pf2->type) &&
3818 		    (pf1->Bpp         == pf2->Bpp) &&
3819 		    !memcmp(pf1->masks, pf2->masks, sizeof(pf1->masks)) &&
3820 		    (pf1->swap_bytes  == pf2->swap_bytes) &&
3821 		    (pf1->swap_shorts == pf2->swap_shorts))
3822 			break;
3823 	}
3824 	if (i >= PIXFMT_TABLE_SIZE)
3825 		return -1;
3826 
3827 	return i;
3828 }
3829 
3830 /******************************************************************************
3831  * i2c primitives:
3832  */
3833 
3834 /* */
3835 #define I2CBITTIME		(0x5<<4)	/* 5 * 0.48uS */
3836 #define I2CBITTIME_878              (1 << 7)
3837 #define I2C_READ		0x01
3838 #define I2C_COMMAND		(I2CBITTIME |			\
3839 				 BT848_DATA_CTL_I2CSCL |	\
3840 				 BT848_DATA_CTL_I2CSDA)
3841 
3842 #define I2C_COMMAND_878		(I2CBITTIME_878 |			\
3843 				 BT848_DATA_CTL_I2CSCL |	\
3844 				 BT848_DATA_CTL_I2CSDA)
3845 
3846 /* Select between old i2c code and new iicbus / smbus code */
3847 #if defined(BKTR_USE_FREEBSD_SMBUS)
3848 
3849 /*
3850  * The hardware interface is actually SMB commands
3851  */
3852 int
3853 i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
3854 {
3855 	char cmd;
3856 
3857 	if (bktr->id == BROOKTREE_848  ||
3858 	    bktr->id == BROOKTREE_848A ||
3859 	    bktr->id == BROOKTREE_849A)
3860 		cmd = I2C_COMMAND;
3861 	else
3862 		cmd = I2C_COMMAND_878;
3863 
3864 	if (byte2 != -1) {
3865 		if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3866 			(short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3867 			return (-1);
3868 	} else {
3869 		if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3870 			(char)(byte1 & 0xff)))
3871 			return (-1);
3872 	}
3873 
3874 	/* return OK */
3875 	return(0);
3876 }
3877 
3878 int
3879 i2cRead(bktr_ptr_t bktr, int addr)
3880 {
3881 	char result;
3882 	char cmd;
3883 
3884 	if (bktr->id == BROOKTREE_848  ||
3885 	    bktr->id == BROOKTREE_848A ||
3886 	    bktr->id == BROOKTREE_849A)
3887 		cmd = I2C_COMMAND;
3888 	else
3889 		cmd = I2C_COMMAND_878;
3890 
3891 	if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3892 		return (-1);
3893 
3894 	return ((int)((unsigned char)result));
3895 }
3896 
3897 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3898 
3899 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3900 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3901 /* Therefore we need low level control of the i2c bus hardware */
3902 
3903 /* Write to the MSP or DPL registers */
3904 void
3905 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr,  unsigned char dev, unsigned int addr, unsigned int data)
3906 {
3907 	unsigned char addr_l, addr_h, data_h, data_l;
3908 
3909 	addr_h = (addr >>8) & 0xff;
3910 	addr_l = addr & 0xff;
3911 	data_h = (data >>8) & 0xff;
3912 	data_l = data & 0xff;
3913 
3914 	iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3915 
3916 	iicbus_write_byte(IICBUS(bktr), dev, 0);
3917 	iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3918 	iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3919 	iicbus_write_byte(IICBUS(bktr), data_h, 0);
3920 	iicbus_write_byte(IICBUS(bktr), data_l, 0);
3921 
3922 	iicbus_stop(IICBUS(bktr));
3923 
3924 	return;
3925 }
3926 
3927 /* Read from the MSP or DPL registers */
3928 unsigned int
3929 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3930 {
3931 	unsigned int data;
3932 	unsigned char addr_l, addr_h, dev_r;
3933 	int read;
3934 	u_char data_read[2];
3935 
3936 	addr_h = (addr >>8) & 0xff;
3937 	addr_l = addr & 0xff;
3938 	dev_r = dev+1;
3939 
3940 	/* XXX errors ignored */
3941 	iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3942 
3943 	iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3944 	iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3945 	iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3946 
3947 	iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3948 	iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3949 	iicbus_stop(IICBUS(bktr));
3950 
3951 	data = (data_read[0]<<8) | data_read[1];
3952 
3953 	return (data);
3954 }
3955 
3956 /* Reset the MSP or DPL chip */
3957 /* The user can block the reset (which is handy if you initialise the
3958  * MSP and/or DPL audio in another operating system first (eg in Windows)
3959  */
3960 void
3961 msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr)
3962 {
3963 
3964 #ifndef BKTR_NO_MSP_RESET
3965 	/* put into reset mode */
3966 	iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3967 	iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3968 	iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3969 	iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3970 	iicbus_stop(IICBUS(bktr));
3971 
3972 	/* put back to operational mode */
3973 	iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3974 	iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3975 	iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3976 	iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3977 	iicbus_stop(IICBUS(bktr));
3978 #endif
3979 	return;
3980 }
3981 
3982 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3983 	int read;
3984 
3985 	/* XXX errors ignored */
3986 	iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3987 	iicbus_read(IICBUS(bktr),  remote->data, 3, &read, IIC_LAST_READ, 0);
3988 	iicbus_stop(IICBUS(bktr));
3989 
3990 	return;
3991 }
3992 
3993 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3994 
3995 /*
3996  * Program the i2c bus directly
3997  */
3998 int
3999 i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
4000 {
4001 	u_int		x;
4002 	u_int		data;
4003 
4004 	/* clear status bits */
4005 	OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4006 
4007 	/* build the command datum */
4008 	if (bktr->id == BROOKTREE_848  ||
4009 	    bktr->id == BROOKTREE_848A ||
4010 	    bktr->id == BROOKTREE_849A) {
4011 	  data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
4012 	} else {
4013 	  data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
4014 	}
4015 	if (byte2 != -1) {
4016 		data |= ((byte2 & 0xff) << 8);
4017 		data |= BT848_DATA_CTL_I2CW3B;
4018 	}
4019 
4020 	/* write the address and data */
4021 	OUTL(bktr, BKTR_I2C_DATA_CTL, data);
4022 
4023 	/* wait for completion */
4024 	for (x = 0x7fffffff; x; --x) {	/* safety valve */
4025 		if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
4026 			break;
4027 	}
4028 
4029 	/* check for ACK */
4030 	if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
4031 		return(-1);
4032 
4033 	/* return OK */
4034 	return(0);
4035 }
4036 
4037 
4038 /*
4039  *
4040  */
4041 int
4042 i2cRead(bktr_ptr_t bktr, int addr)
4043 {
4044 	u_int		x;
4045 
4046 	/* clear status bits */
4047 	OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4048 
4049 	/* write the READ address */
4050 	/* The Bt878 and Bt879  differed on the treatment of i2c commands */
4051 
4052 	if (bktr->id == BROOKTREE_848  ||
4053 	    bktr->id == BROOKTREE_848A ||
4054 	    bktr->id == BROOKTREE_849A) {
4055 		OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
4056 	} else {
4057 		OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
4058 	}
4059 
4060 	/* wait for completion */
4061 	for (x = 5000; x--; DELAY(1)) {	/* 5msec, safety valve */
4062 		if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
4063 			break;
4064 	}
4065 
4066 	/* check for ACK */
4067 	if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
4068 		return(-1);
4069 
4070 	/* it was a read */
4071 	return((INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff);
4072 }
4073 
4074 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4075 /* bt848 automated i2c bus controller cannot handle */
4076 /* Therefore we need low level control of the i2c bus hardware */
4077 /* Idea for the following functions are from elsewhere in this driver and */
4078 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4079 
4080 #define BITD    40
4081 static void i2c_start(bktr_ptr_t bktr) {
4082         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release data */
4083         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release clock */
4084         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* lower data */
4085         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock */
4086 }
4087 
4088 static void i2c_stop(bktr_ptr_t bktr) {
4089         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock & data */
4090         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* release clock */
4091         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release data */
4092 }
4093 
4094 static int i2c_write_byte(bktr_ptr_t bktr, unsigned char data) {
4095         int x;
4096         int status;
4097 
4098         /* write out the byte */
4099         for (x = 7; x >= 0; --x) {
4100                 if (data & (1<<x)) {
4101 			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4102                         DELAY(BITD);          /* assert HI data */
4103 			OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4104                         DELAY(BITD);          /* strobe clock */
4105 			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4106                         DELAY(BITD);          /* release clock */
4107                 }
4108                 else {
4109 			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4110                         DELAY(BITD);          /* assert LO data */
4111 			OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4112                         DELAY(BITD);          /* strobe clock */
4113 			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4114                         DELAY(BITD);          /* release clock */
4115                 }
4116         }
4117 
4118         /* look for an ACK */
4119 	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* float data */
4120 	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* strobe clock */
4121         status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;       /* read the ACK bit */
4122         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release clock */
4123 
4124         return(status);
4125 }
4126 
4127 static int i2c_read_byte(bktr_ptr_t bktr, unsigned char *data, int last) {
4128         int x;
4129         int bit;
4130         int byte = 0;
4131 
4132         /* read in the byte */
4133 	OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4134         DELAY(BITD);                          /* float data */
4135         for (x = 7; x >= 0; --x) {
4136 		OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4137                 DELAY(BITD);                  /* strobe clock */
4138                 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1;  /* read the data bit */
4139                 if (bit) byte |= (1<<x);
4140 		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4141                 DELAY(BITD);                  /* release clock */
4142         }
4143         /* After reading the byte, send an ACK */
4144         /* (unless that was the last byte, for which we send a NAK */
4145         if (last) { /* send NAK - same a writing a 1 */
4146 		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4147                 DELAY(BITD);                  /* set data bit */
4148 		OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4149                 DELAY(BITD);                  /* strobe clock */
4150 		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4151                 DELAY(BITD);                  /* release clock */
4152         } else { /* send ACK - same as writing a 0 */
4153 		OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4154                 DELAY(BITD);                  /* set data bit */
4155 		OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4156                 DELAY(BITD);                  /* strobe clock */
4157 		OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4158                 DELAY(BITD);                  /* release clock */
4159         }
4160 
4161         *data=byte;
4162 	return 0;
4163 }
4164 #undef BITD
4165 
4166 /* Write to the MSP or DPL registers */
4167 void msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4168 		    unsigned int data) {
4169 	unsigned int msp_w_addr = i2c_addr;
4170 	unsigned char addr_l, addr_h, data_h, data_l;
4171 	addr_h = (addr >>8) & 0xff;
4172 	addr_l = addr & 0xff;
4173 	data_h = (data >>8) & 0xff;
4174 	data_l = data & 0xff;
4175 
4176 	i2c_start(bktr);
4177 	i2c_write_byte(bktr, msp_w_addr);
4178 	i2c_write_byte(bktr, dev);
4179 	i2c_write_byte(bktr, addr_h);
4180 	i2c_write_byte(bktr, addr_l);
4181 	i2c_write_byte(bktr, data_h);
4182 	i2c_write_byte(bktr, data_l);
4183 	i2c_stop(bktr);
4184 }
4185 
4186 /* Read from the MSP or DPL registers */
4187 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr) {
4188 	unsigned int data;
4189 	unsigned char addr_l, addr_h, data_1, data_2, dev_r;
4190 	addr_h = (addr >>8) & 0xff;
4191 	addr_l = addr & 0xff;
4192 	dev_r = dev+1;
4193 
4194 	i2c_start(bktr);
4195 	i2c_write_byte(bktr,i2c_addr);
4196 	i2c_write_byte(bktr,dev_r);
4197 	i2c_write_byte(bktr,addr_h);
4198 	i2c_write_byte(bktr,addr_l);
4199 
4200 	i2c_start(bktr);
4201 	i2c_write_byte(bktr,i2c_addr+1);
4202 	i2c_read_byte(bktr,&data_1, 0);
4203 	i2c_read_byte(bktr,&data_2, 1);
4204 	i2c_stop(bktr);
4205 	data = (data_1<<8) | data_2;
4206 	return data;
4207 }
4208 
4209 /* Reset the MSP or DPL chip */
4210 /* The user can block the reset (which is handy if you initialise the
4211  * MSP audio in another operating system first (eg in Windows)
4212  */
4213 void msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr) {
4214 
4215 #ifndef BKTR_NO_MSP_RESET
4216 	/* put into reset mode */
4217 	i2c_start(bktr);
4218 	i2c_write_byte(bktr, i2c_addr);
4219 	i2c_write_byte(bktr, 0x00);
4220 	i2c_write_byte(bktr, 0x80);
4221 	i2c_write_byte(bktr, 0x00);
4222 	i2c_stop(bktr);
4223 
4224 	/* put back to operational mode */
4225 	i2c_start(bktr);
4226 	i2c_write_byte(bktr, i2c_addr);
4227 	i2c_write_byte(bktr, 0x00);
4228 	i2c_write_byte(bktr, 0x00);
4229 	i2c_write_byte(bktr, 0x00);
4230 	i2c_stop(bktr);
4231 #endif
4232 	return;
4233 
4234 }
4235 
4236 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4237 
4238 	/* XXX errors ignored */
4239 	i2c_start(bktr);
4240 	i2c_write_byte(bktr,bktr->remote_control_addr);
4241 	i2c_read_byte(bktr,&(remote->data[0]), 0);
4242 	i2c_read_byte(bktr,&(remote->data[1]), 0);
4243 	i2c_read_byte(bktr,&(remote->data[2]), 0);
4244 	i2c_stop(bktr);
4245 
4246 	return;
4247 }
4248 
4249 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4250 
4251 
4252 #if defined(I2C_SOFTWARE_PROBE)
4253 
4254 /*
4255  * we are keeping this around for any parts that we need to probe
4256  * but that CANNOT be probed via an i2c read.
4257  * this is necessary because the hardware i2c mechanism
4258  * cannot be programmed for 1 byte writes.
4259  * currently there are no known i2c parts that we need to probe
4260  * and that cannot be safely read.
4261  */
4262 static int	i2cProbe(bktr_ptr_t bktr, int addr);
4263 #define BITD		40
4264 #define EXTRA_START
4265 
4266 /*
4267  * probe for an I2C device at addr.
4268  */
4269 static int
4270 i2cProbe(bktr_ptr_t bktr, int addr)
4271 {
4272 	int		x, status;
4273 
4274 	/* the START */
4275 #if defined(EXTRA_START)
4276 	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD);	/* release data */
4277 	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD);	/* release clock */
4278 #endif /* EXTRA_START */
4279 	OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD);	/* lower data */
4280 	OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD);	/* lower clock */
4281 
4282 	/* write addr */
4283 	for (x = 7; x >= 0; --x) {
4284 		if (addr & (1<<x)) {
4285 			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4286 			DELAY(BITD);		/* assert HI data */
4287 			OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4288 			DELAY(BITD);		/* strobe clock */
4289 			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4290 			DELAY(BITD);		/* release clock */
4291 		}
4292 		else {
4293 			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4294 			DELAY(BITD);		/* assert LO data */
4295 			OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4296 			DELAY(BITD);		/* strobe clock */
4297 			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4298 			DELAY(BITD);		/* release clock */
4299 		}
4300 	}
4301 
4302 	/* look for an ACK */
4303 	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD);	/* float data */
4304 	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD);	/* strobe clock */
4305 	status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;	/* read the ACK bit */
4306 	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD);	/* release clock */
4307 
4308 	/* the STOP */
4309 	OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD);	/* lower clock & data */
4310 	OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD);	/* release clock */
4311 	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD);	/* release data */
4312 
4313 	return(status);
4314 }
4315 #undef EXTRA_START
4316 #undef BITD
4317 
4318 #endif /* I2C_SOFTWARE_PROBE */
4319