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