bktr_core.c revision 1.37
1/*	$OpenBSD: bktr_core.c,v 1.37 2016/02/15 19:21:46 stefan 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 pograms.
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/rndvar.h>
107#include <dev/ic/bt8xx.h>
108#include <dev/pci/bktr/bktr_reg.h>
109#include <dev/pci/bktr/bktr_tuner.h>
110#include <dev/pci/bktr/bktr_card.h>
111#include <dev/pci/bktr/bktr_audio.h>
112#include <dev/pci/bktr/bktr_core.h>
113#include <dev/pci/bktr/bktr_os.h>
114
115typedef int intrmask_t;
116
117static int bt848_format = -1;
118
119const char *
120bktr_name(bktr_ptr_t bktr)
121{
122        return (bktr->bktr_dev.dv_xname);
123}
124
125
126typedef u_char bool_t;
127
128#define BKTRPRI (PZERO+8)|PCATCH
129#define VBIPRI  (PZERO-4)|PCATCH
130
131
132/*
133 * memory allocated for DMA programs
134 */
135#define DMA_PROG_ALLOC		(8 * PAGE_SIZE)
136
137/* When to split a dma transfer , the bt848 has timing as well as
138   dma transfer size limitations so that we have to split dma
139   transfers into two dma requests
140   */
141#define DMA_BT848_SPLIT 319*2
142
143/*
144 * Allocate enough memory for:
145 *	768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
146 *
147 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
148 * in your  kernel configuration file.
149 */
150
151#ifndef BROOKTREE_ALLOC_PAGES
152#define BROOKTREE_ALLOC_PAGES	217*4
153#endif
154#define BROOKTREE_ALLOC		(BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
155
156/* Definitions for VBI capture.
157 * There are 16 VBI lines in a PAL video field (32 in a frame),
158 * and we take 2044 samples from each line (placed in a 2048 byte buffer
159 * for alignment).
160 * VBI lines are held in a circular buffer before being read by a
161 * user program from /dev/vbi.
162 */
163
164#define MAX_VBI_LINES	      16   /* Maximum for all vidoe formats */
165#define VBI_LINE_SIZE         2048 /* Store upto 2048 bytes per line */
166#define VBI_BUFFER_ITEMS      20   /* Number of frames we buffer */
167#define VBI_DATA_SIZE         (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
168#define VBI_BUFFER_SIZE       (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
169
170
171/*  Defines for fields  */
172#define ODD_F  0x01
173#define EVEN_F 0x02
174
175
176/*
177 * Parameters describing size of transmitted image.
178 */
179
180static const struct format_params format_params[] = {
181/* # define BT848_IFORM_F_AUTO             (0x0) - don't matter. */
182  { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
183    12,  1600 },
184/* # define BT848_IFORM_F_NTSCM            (0x1) */
185  { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
186    12, 1600 },
187/* # define BT848_IFORM_F_NTSCJ            (0x2) */
188  { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
189    12, 1600 },
190/* # define BT848_IFORM_F_PALBDGHI         (0x3) */
191  { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
192    16,  2044 },
193/* # define BT848_IFORM_F_PALM             (0x4) */
194  { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
195    12, 1600 },
196/* # define BT848_IFORM_F_PALN             (0x5) */
197  { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
198    16, 2044 },
199/* # define BT848_IFORM_F_SECAM            (0x6) */
200  { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
201    16, 2044 },
202/* # define BT848_IFORM_F_RSVD             (0x7) - ???? */
203  { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
204    16, 2044 },
205};
206
207/*
208 * Table of supported Pixel Formats
209 */
210
211static const struct meteor_pixfmt_internal {
212	struct meteor_pixfmt public;
213	u_int                color_fmt;
214} pixfmt_table[] = {
215
216{ { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 0,0 }, 0x33 },
217{ { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 1,0 }, 0x33 },
218
219{ { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 0,0 }, 0x22 },
220{ { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 1,0 }, 0x22 },
221
222{ { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
223
224{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
225{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
226{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
227{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
228{ { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
229{ { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
230{ { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
231
232};
233#define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
234
235/*
236 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
237 */
238
239/*  FIXME:  Also add YUV_422 and YUV_PACKED as well  */
240static const struct {
241	u_int	meteor_format;
242	struct meteor_pixfmt public;
243} meteor_pixfmt_table[] = {
244    { METEOR_GEO_YUV_12,
245      { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
246    },
247
248      /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
249    { METEOR_GEO_YUV_422,
250      { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
251    },
252    { METEOR_GEO_YUV_PACKED,
253      { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
254    },
255    { METEOR_GEO_RGB16,
256      { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,   0x03e0,   0x001f }, 0, 0 }
257    },
258    { METEOR_GEO_RGB24,
259      { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
260    },
261
262};
263#define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
264				   sizeof(meteor_pixfmt_table[0]) )
265
266
267#define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
268#define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
269
270
271
272/* sync detect threshold */
273#if 0
274#define SYNC_LEVEL		(BT848_ADC_RESERVED |	\
275				 BT848_ADC_CRUSH)	/* threshold ~125 mV */
276#else
277#define SYNC_LEVEL		(BT848_ADC_RESERVED |	\
278				 BT848_ADC_SYNC_T)	/* threshold ~75 mV */
279#endif
280
281
282
283
284/* debug utility for holding previous INT_STAT contents */
285#undef STATUS_SUM
286#if defined( STATUS_SUM )
287static u_int	status_sum = 0;
288#endif
289
290/*
291 * defines to make certain bit-fiddles understandable
292 */
293#define FIFO_ENABLED		BT848_DMA_CTL_FIFO_EN
294#define RISC_ENABLED		BT848_DMA_CTL_RISC_EN
295#define FIFO_RISC_ENABLED	(BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
296#define FIFO_RISC_DISABLED	0
297
298#define ALL_INTS_DISABLED	0
299#define ALL_INTS_CLEARED	0xffffffff
300#define CAPTURE_OFF		0
301
302#define BIT_SEVEN_HIGH		(1<<7)
303#define BIT_EIGHT_HIGH		(1<<8)
304
305#define I2C_BITS		(BT848_INT_RACK | BT848_INT_I2CDONE)
306#define TDEC_BITS               (BT848_INT_FDSR | BT848_INT_FBUS)
307
308
309
310static int		oformat_meteor_to_bt( u_int format );
311
312static u_int		pixfmt_swap_flags( int pixfmt );
313
314/*
315 * bt848 RISC programming routines.
316 */
317#ifdef BT848_DUMP
318static int	dump_bt848( bktr_ptr_t bktr );
319#endif
320
321static void	yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
322			      int rows,  int interlace );
323static void	yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
324			     int rows, int interlace );
325static void	yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
326			     int rows, int interlace );
327static void	rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
328			  int rows, int interlace );
329static void	rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
330			  int rows, int interlace );
331static void	build_dma_prog( bktr_ptr_t bktr, char i_flag );
332
333static bool_t   getline(bktr_reg_t *, int);
334static bool_t   notclipped(bktr_reg_t * , int , int);
335static bool_t   split(bktr_reg_t *, u_int **, int, u_int, int, u_int * , int);
336
337static void	start_capture( bktr_ptr_t bktr, unsigned type );
338static void	set_fps( bktr_ptr_t bktr, u_short fps );
339
340
341
342/*
343 * Remote Control Functions
344 */
345static void	remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
346
347
348/*
349 * ioctls common to both video & tuner.
350 */
351int	bktr_common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
352
353
354/*
355 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
356 */
357static void     i2c_start( bktr_ptr_t bktr);
358static void     i2c_stop( bktr_ptr_t bktr);
359static int      i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
360static int      i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
361
362/*
363 * the common attach code, used by all OS versions.
364 */
365void
366common_bktr_attach( bktr_ptr_t bktr, int unit, u_int pci_id, u_int rev )
367{
368	vaddr_t	buf = 0;
369
370/***************************************/
371/* *** OS Specific memory routines *** */
372/***************************************/
373        /* allocate space for dma program */
374        bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog, DMA_PROG_ALLOC);
375        bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
376	    DMA_PROG_ALLOC);
377
378	/* allocate space for the VBI buffer */
379	bktr->vbidata  = get_bktr_mem(bktr, &bktr->dm_vbidata, VBI_DATA_SIZE);
380	bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
381	    VBI_BUFFER_SIZE);
382
383        /* allocate space for pixel buffer */
384        if (BROOKTREE_ALLOC)
385                buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
386        else
387                buf = 0;
388
389	if ( bootverbose ) {
390		printf("%s: buffer size %d, addr 0x%lx\n",
391			bktr_name(bktr), BROOKTREE_ALLOC,
392			bktr->dm_prog->dm_segs->ds_addr);
393	}
394
395	if (buf != 0) {
396		bktr->bigbuf = buf;
397		bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
398		bzero((void *)bktr->bigbuf, BROOKTREE_ALLOC);
399	} else {
400		bktr->alloc_pages = 0;
401	}
402
403	bktr->flags = METEOR_INITIALIZED | METEOR_AUTOMODE |
404		      METEOR_DEV0 | METEOR_RGB16;
405	bktr->dma_prog_loaded = FALSE;
406	bktr->cols = 640;
407	bktr->rows = 480;
408	bktr->frames = 1;		/* one frame */
409	bktr->format = METEOR_GEO_RGB16;
410	bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
411	bktr->pixfmt_compat = TRUE;
412
413	bktr->vbiinsert = 0;
414	bktr->vbistart = 0;
415	bktr->vbisize = 0;
416	bktr->vbiflags = 0;
417
418	/* using the pci device id and revision id */
419	/* and determine the card type            */
420	if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE) {
421		switch (PCI_PRODUCT(pci_id)) {
422		case PCI_PRODUCT_BROOKTREE_BT848:
423			if (rev == 0x12)
424				bktr->id = BROOKTREE_848A;
425			else
426				bktr->id = BROOKTREE_848;
427			break;
428		case PCI_PRODUCT_BROOKTREE_BT849:
429			bktr->id = BROOKTREE_849A;
430			break;
431		case PCI_PRODUCT_BROOKTREE_BT878:
432			bktr->id = BROOKTREE_878;
433			break;
434		case PCI_PRODUCT_BROOKTREE_BT879:
435			bktr->id = BROOKTREE_879;
436			break;
437		}
438	}
439
440	bktr->clr_on_start = FALSE;
441
442	/* defaults for the tuner section of the card */
443	bktr->tflags = TUNER_INITIALIZED;
444	bktr->tuner.frequency = 0;
445	bktr->tuner.channel = 0;
446	bktr->tuner.chnlset = DEFAULT_CHNLSET;
447	bktr->tuner.afc = 0;
448	bktr->tuner.radio_mode = 0;
449	bktr->audio_mux_select = 0;
450	bktr->audio_mute_state = FALSE;
451	bktr->bt848_card = -1;
452	bktr->bt848_tuner = -1;
453	bktr->reverse_mute = -1;
454	bktr->slow_msp_audio = 0;
455	bktr->msp_use_mono_source = 0;
456        bktr->msp_source_selected = -1;
457	bktr->audio_mux_present = 1;
458
459	probeCard(bktr, TRUE, unit);
460
461	/* enable drivers on the GPIO port that control the MUXes */
462	OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
463
464	/* mute the audio stream */
465	set_audio( bktr, AUDIO_MUTE );
466
467	/* Initialise any MSP34xx or TDA98xx audio chips */
468	init_audio_devices(bktr);
469
470}
471
472
473/* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
474 * The circular buffer holds 'n' fixed size data blocks.
475 * vbisize   is the number of bytes in the circular buffer
476 * vbiread   is the point we reading data out of the circular buffer
477 * vbiinsert is the point we insert data into the circular buffer
478 */
479static void
480vbidecode(bktr_ptr_t bktr)
481{
482        unsigned char *dest;
483	unsigned int *seq_dest;
484
485	/* Check if there is room in the buffer to insert the data. */
486	if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
487
488	/* Copy the VBI data into the next free slot in the buffer. */
489	/* 'dest' is the point in vbibuffer where we want to insert new data */
490        dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
491        memcpy(dest, (unsigned char *)bktr->vbidata, VBI_DATA_SIZE);
492
493	/* Write the VBI sequence number to the end of the vbi data */
494	/* This is used by the AleVT teletext program */
495	seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
496			+ bktr->vbiinsert
497			+ (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
498	*seq_dest = bktr->vbi_sequence_number;
499
500	/* And increase the VBI sequence number */
501	/* This can wrap around */
502	bktr->vbi_sequence_number++;
503
504	/* Increment the vbiinsert pointer */
505	/* This can wrap around */
506	bktr->vbiinsert += VBI_DATA_SIZE;
507	bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
508
509	/* And increase the amount of vbi data in the buffer */
510	bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
511}
512
513
514/*
515 * the common interrupt handler.
516 * Returns a 0 or 1 depending on whether the interrupt has handled.
517 * In the OS specific section, bktr_intr() is defined which calls this
518 * common interrupt handler.
519 */
520int
521common_bktr_intr( void *arg )
522{
523	bktr_ptr_t	bktr = (bktr_ptr_t) arg;
524	u_int	bktr_status;
525	u_char	dstatus;
526	u_int	field;
527	u_int	w_field;
528	u_int	req_field;
529
530	/*
531	 * check to see if any interrupts are unmasked on this device.  If
532	 * none are, then we likely got here by way of being on a PCI shared
533	 * interrupt dispatch list.
534	 */
535	if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
536		return 0;	/* bail out now, before we do something we
537				   shouldn't */
538
539	if (!(bktr->flags & METEOR_OPEN)) {
540		OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
541		OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
542		/* return; ?? */
543	}
544
545	/* record and clear the INTerrupt status bits */
546	bktr_status = INL(bktr, BKTR_INT_STAT);
547	OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS);	/* don't touch i2c */
548
549	/* record and clear the device status register */
550	dstatus = INB(bktr, BKTR_DSTATUS);
551	OUTB(bktr, BKTR_DSTATUS, 0x00);
552
553#if defined( STATUS_SUM )
554	/* add any new device status or INTerrupt status bits */
555	status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
556	status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
557#endif /* STATUS_SUM */
558	/* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
559		dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
560	*/
561
562
563	/* if risc was disabled re-start process again */
564	/* if there was one of the following errors re-start again */
565	if ( !(bktr_status & BT848_INT_RISC_EN) ||
566	     ((bktr_status &(/* BT848_INT_FBUS   | */
567			     /* BT848_INT_FTRGT  | */
568			     /* BT848_INT_FDSR   | */
569			      BT848_INT_PPERR  |
570			      BT848_INT_RIPERR | BT848_INT_PABORT |
571			      BT848_INT_OCERR  | BT848_INT_SCERR) ) != 0)
572		|| ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
573
574		u_short	tdec_save = INB(bktr, BKTR_TDEC);
575
576		OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
577		OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
578
579		OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
580
581		/*  Reset temporal decimation counter  */
582		OUTB(bktr, BKTR_TDEC, 0);
583		OUTB(bktr, BKTR_TDEC, tdec_save);
584
585		/*  Reset to no-fields captured state  */
586		if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
587			switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
588			case METEOR_ONLY_ODD_FIELDS:
589				bktr->flags |= METEOR_WANT_ODD;
590				break;
591			case METEOR_ONLY_EVEN_FIELDS:
592				bktr->flags |= METEOR_WANT_EVEN;
593				break;
594			default:
595				bktr->flags |= METEOR_WANT_MASK;
596				break;
597			}
598		}
599
600		OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
601		OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
602		OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
603
604		OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
605				    BT848_INT_RISCI      |
606				    BT848_INT_VSYNC      |
607				    BT848_INT_FMTCHG);
608
609		OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
610
611		add_video_randomness(tdec_save);
612
613		return 1;
614	}
615
616	/* If this is not a RISC program interrupt, return */
617	if (!(bktr_status & BT848_INT_RISCI))
618		return 0;
619
620/**
621	printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
622		bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
623 */
624
625	add_video_randomness(INL(bktr, BKTR_RISC_COUNT));
626
627	/*
628	 * Disable future interrupts if a capture mode is not selected.
629	 * This can happen when we are in the process of closing or
630	 * changing capture modes, otherwise it shouldn't happen.
631	 */
632	if (!(bktr->flags & METEOR_CAP_MASK))
633		OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
634
635	/* Determine which field generated this interrupt */
636	field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
637
638	/*
639	 * Process the VBI data if it is being captured. We do this once
640	 * both Odd and Even VBI data is captured. Therefore we do this
641	 * in the Even field interrupt handler.
642	 */
643	if ((bktr->vbiflags & (VBI_CAPTURE|VBI_OPEN)) ==
644	    (VBI_CAPTURE|VBI_OPEN) && (field == EVEN_F)) {
645		/* Put VBI data into circular buffer */
646		vbidecode(bktr);
647
648		/* If someone is blocked on reading from /dev/vbi, wake them */
649		if (bktr->vbi_read_blocked) {
650			bktr->vbi_read_blocked = FALSE;
651			wakeup(VBI_SLEEP);
652		}
653
654		/* If someone has a select() on /dev/vbi, inform them */
655#ifndef __OpenBSD__
656		if (bktr->vbi_select.si_pid) {
657			selwakeup(&bktr->vbi_select);
658		}
659#else
660		selwakeup(&bktr->vbi_select);
661#endif
662	}
663
664
665	/*
666	 *  Register the completed field
667	 *    (For dual-field mode, require fields from the same frame)
668	 */
669	switch ( bktr->flags & METEOR_WANT_MASK ) {
670		case METEOR_WANT_ODD  : w_field = ODD_F         ;  break;
671		case METEOR_WANT_EVEN : w_field = EVEN_F        ;  break;
672		default               : w_field = (ODD_F|EVEN_F);  break;
673	}
674	switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
675		case METEOR_ONLY_ODD_FIELDS  : req_field = ODD_F  ;  break;
676		case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ;  break;
677		default                      : req_field = (ODD_F|EVEN_F);
678			                       break;
679	}
680
681	if (( field == EVEN_F ) && ( w_field == EVEN_F ))
682		bktr->flags &= ~METEOR_WANT_EVEN;
683	else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
684		 ( w_field == ODD_F ))
685		bktr->flags &= ~METEOR_WANT_ODD;
686	else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
687		 ( w_field == (ODD_F|EVEN_F) ))
688		bktr->flags &= ~METEOR_WANT_ODD;
689	else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
690		 ( w_field == ODD_F )) {
691		bktr->flags &= ~METEOR_WANT_ODD;
692		bktr->flags |=  METEOR_WANT_EVEN;
693	}
694	else {
695		/*  We're out of sync.  Start over.  */
696		if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
697			switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
698			case METEOR_ONLY_ODD_FIELDS:
699				bktr->flags |= METEOR_WANT_ODD;
700				break;
701			case METEOR_ONLY_EVEN_FIELDS:
702				bktr->flags |= METEOR_WANT_EVEN;
703				break;
704			default:
705				bktr->flags |= METEOR_WANT_MASK;
706				break;
707			}
708		}
709		return 1;
710	}
711
712	/*
713	 * If we have a complete frame.
714	 */
715	if (!(bktr->flags & METEOR_WANT_MASK)) {
716		bktr->frames_captured++;
717		/*
718		 * post the completion time.
719		 */
720		if (bktr->flags & METEOR_WANT_TS) {
721			struct timeval *ts;
722
723			if ((u_int) bktr->alloc_pages * PAGE_SIZE
724			   <= (bktr->frame_size + sizeof(struct timeval))) {
725				ts =(struct timeval *)bktr->bigbuf +
726				  bktr->frame_size;
727				/* doesn't work in synch mode except
728				 *  for first frame */
729				/* XXX */
730				microtime(ts);
731			}
732		}
733
734
735		/*
736		 * Wake up the user in single capture mode.
737		 */
738		if (bktr->flags & METEOR_SINGLE) {
739
740			/* stop dma */
741			OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
742
743			/* disable risc, leave fifo running */
744			OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
745			wakeup(BKTR_SLEEP);
746		}
747
748		/*
749		 * If the user requested to be notified via signal,
750		 * let them know the frame is complete.
751		 */
752
753		if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK))
754			psignal( bktr->proc,
755				 bktr->signal&(~METEOR_SIG_MODE_MASK) );
756
757		/*
758		 * Reset the want flags if in continuous or
759		 * synchronous capture mode.
760		 */
761/*
762* XXX NOTE (Luigi):
763* currently we only support 3 capture modes: odd only, even only,
764* odd+even interlaced (odd field first). A fourth mode (non interlaced,
765* either even OR odd) could provide 60 (50 for PAL) pictures per
766* second, but it would require this routine to toggle the desired frame
767* each time, and one more different DMA program for the Bt848.
768* As a consequence, this fourth mode is currently unsupported.
769*/
770
771		if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
772			switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
773			case METEOR_ONLY_ODD_FIELDS:
774				bktr->flags |= METEOR_WANT_ODD;
775				break;
776			case METEOR_ONLY_EVEN_FIELDS:
777				bktr->flags |= METEOR_WANT_EVEN;
778				break;
779			default:
780				bktr->flags |= METEOR_WANT_MASK;
781				break;
782			}
783		}
784	}
785
786	return 1;
787}
788
789
790
791
792/*
793 *
794 */
795extern int bt848_format; /* used to set the default format, PAL or NTSC */
796int
797video_open( bktr_ptr_t bktr )
798{
799	int frame_rate, video_format=0;
800
801	if (bktr->flags & METEOR_OPEN)		/* device is busy */
802		return( EBUSY );
803
804	bktr->flags |= METEOR_OPEN;
805
806#ifdef BT848_DUMP
807	dump_bt848( bt848 );
808#endif
809
810        bktr->clr_on_start = FALSE;
811
812	OUTB(bktr, BKTR_DSTATUS, 0x00);			/* clear device status reg. */
813
814	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
815
816#if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
817	video_format = 0;
818#else
819	video_format = 1;
820#endif
821
822	if (bt848_format == 0 )
823	  video_format = 0;
824
825	if (bt848_format == 1 )
826	  video_format = 1;
827
828	if (video_format == 1 ) {
829	  OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
830	  bktr->format_params = BT848_IFORM_F_NTSCM;
831
832	} else {
833	  OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
834	  bktr->format_params = BT848_IFORM_F_PALBDGHI;
835
836	}
837
838	OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) |
839	    format_params[bktr->format_params].iform_xtsel);
840
841	/* work around for new Hauppauge 878 cards */
842	if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
843	    (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
844		OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
845	else
846		OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
847
848	OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
849	OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
850	frame_rate    = format_params[bktr->format_params].frame_rate;
851
852	/* enable PLL mode using 28MHz crystal for PAL/SECAM users */
853	if (bktr->xtal_pll_mode == BT848_USE_PLL) {
854		OUTB(bktr, BKTR_TGCTRL, 0);
855		OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
856		OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
857		OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
858	}
859
860	bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
861
862	bktr->max_clip_node = 0;
863
864	OUTB(bktr, BKTR_COLOR_CTL,
865	    BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
866
867	OUTB(bktr, BKTR_E_HSCALE_LO, 170);
868	OUTB(bktr, BKTR_O_HSCALE_LO, 170);
869
870	OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
871	OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
872	OUTB(bktr, BKTR_E_SCLOOP, 0);
873	OUTB(bktr, BKTR_O_SCLOOP, 0);
874
875	OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
876	OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
877
878	bktr->fifo_errors = 0;
879	bktr->dma_errors = 0;
880	bktr->frames_captured = 0;
881	bktr->even_fields_captured = 0;
882	bktr->odd_fields_captured = 0;
883	bktr->proc = (struct proc *)0;
884	set_fps(bktr, frame_rate);
885	bktr->video.addr = 0;
886	bktr->video.width = 0;
887	bktr->video.banksize = 0;
888	bktr->video.ramsize = 0;
889	bktr->pixfmt_compat = TRUE;
890	bktr->format = METEOR_GEO_RGB16;
891	bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
892
893	bktr->capture_area_enabled = FALSE;
894
895	/* if you take this out triton-based mobos will operate unreliably */
896	OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT);
897
898	return( 0 );
899}
900
901int
902vbi_open( bktr_ptr_t bktr )
903{
904	if (bktr->vbiflags & VBI_OPEN)		/* device is busy */
905		return( EBUSY );
906
907	bktr->vbiflags |= VBI_OPEN;
908
909	/* reset the VBI circular buffer pointers and clear the buffers */
910	bktr->vbiinsert = 0;
911	bktr->vbistart = 0;
912	bktr->vbisize = 0;
913	bktr->vbi_sequence_number = 0;
914	bktr->vbi_read_blocked = FALSE;
915
916	bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
917	bzero((caddr_t) bktr->vbidata,  VBI_DATA_SIZE);
918
919	return( 0 );
920}
921
922/*
923 *
924 */
925int
926tuner_open( bktr_ptr_t bktr )
927{
928	if ( !(bktr->tflags & TUNER_INITIALIZED) )	/* device not found */
929		return( ENXIO );
930
931	if ( bktr->tflags & TUNER_OPEN )		/* already open */
932		return( 0 );
933
934	bktr->tflags |= TUNER_OPEN;
935
936	return( 0 );
937}
938
939
940
941
942/*
943 *
944 */
945int
946video_close( bktr_ptr_t bktr )
947{
948	bktr->flags &= ~(METEOR_OPEN     |
949			 METEOR_SINGLE   |
950			 METEOR_CAP_MASK |
951			 METEOR_WANT_MASK);
952
953	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
954	OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
955
956	bktr->dma_prog_loaded = FALSE;
957	OUTB(bktr, BKTR_TDEC, 0);
958	OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
959
960/** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
961	OUTL(bktr, BKTR_SRESET, 0xf);
962	OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
963
964	return( 0 );
965}
966
967
968/*
969 * tuner close handle,
970 *  place holder for tuner specific operations on a close.
971 */
972int
973tuner_close( bktr_ptr_t bktr )
974{
975	bktr->tflags &= ~TUNER_OPEN;
976
977	return( 0 );
978}
979
980int
981vbi_close( bktr_ptr_t bktr )
982{
983
984	bktr->vbiflags &= ~VBI_OPEN;
985
986	return( 0 );
987}
988
989/*
990 *
991 */
992int
993video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
994{
995        int             status;
996        size_t          count;
997
998
999	if (bktr->bigbuf == 0)	/* no frame buffer allocated (ioctl failed) */
1000		return( ENOMEM );
1001
1002	if (bktr->flags & METEOR_CAP_MASK)
1003		return( EIO );	/* already capturing */
1004
1005        OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1006
1007
1008	count = bktr->rows * bktr->cols *
1009		pixfmt_table[ bktr->pixfmt ].public.Bpp;
1010
1011	if (uio->uio_resid < count)
1012		return( EINVAL );
1013
1014	bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1015
1016	/* capture one frame */
1017	start_capture(bktr, METEOR_SINGLE);
1018	/* wait for capture to complete */
1019	OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1020	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1021	OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1022	OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1023                            BT848_INT_RISCI      |
1024                            BT848_INT_VSYNC      |
1025                            BT848_INT_FMTCHG);
1026
1027
1028	status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1029	if (!status)		/* successful capture */
1030		status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1031	else
1032		printf ("%s: read: tsleep error %d\n",
1033			bktr_name(bktr), status);
1034
1035	bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1036
1037	return( status );
1038}
1039
1040/*
1041 * Read VBI data from the vbi circular buffer
1042 * The buffer holds vbi data blocks which are the same size
1043 * vbiinsert is the position we will insert the next item into the buffer
1044 * vbistart is the actual position in the buffer we want to read from
1045 * vbisize is the exact number of bytes in the buffer left to read
1046 */
1047int
1048vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1049{
1050	size_t          readsize, readsize2;
1051	int             status;
1052
1053
1054	while(bktr->vbisize == 0) {
1055		if (ioflag & IO_NDELAY) {
1056			return EWOULDBLOCK;
1057		}
1058
1059		bktr->vbi_read_blocked = TRUE;
1060		if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1061			return status;
1062		}
1063	}
1064
1065	/* Now we have some data to give to the user */
1066
1067	/* We cannot read more bytes than there are in
1068	 * the circular buffer
1069	 */
1070	readsize = ulmin(uio->uio_resid, bktr->vbisize);
1071
1072	/* Check if we can read this number of bytes without having
1073	 * to wrap around the circular buffer */
1074	if (readsize >= VBI_BUFFER_SIZE - bktr->vbistart) {
1075		/* We need to wrap around */
1076
1077		readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1078		status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
1079		if (status == 0)
1080			status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1081	} else {
1082		/* We do not need to wrap around */
1083		status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1084	}
1085
1086	/* Update the number of bytes left to read */
1087	bktr->vbisize -= readsize;
1088
1089	/* Update vbistart */
1090	bktr->vbistart += readsize;
1091	bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1092
1093	return( status );
1094
1095}
1096
1097
1098
1099/*
1100 * video ioctls
1101 */
1102int
1103video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
1104{
1105	volatile u_char		c_temp;
1106	unsigned int		temp;
1107	unsigned int		temp_iform;
1108	unsigned int		error;
1109	struct meteor_geomet	*geo;
1110	struct meteor_counts	*counts;
1111	struct meteor_video	*video;
1112	struct bktr_capture_area *cap_area;
1113	vaddr_t			buf;
1114	int                     i;
1115	char                    char_temp;
1116
1117	switch ( cmd ) {
1118
1119	case BT848SCLIP: /* set clip region */
1120	    bktr->max_clip_node = 0;
1121	    memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1122
1123	    for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1124		if (bktr->clip_list[i].y_min ==  0 &&
1125		    bktr->clip_list[i].y_max == 0)
1126		    break;
1127	    }
1128	    bktr->max_clip_node = i;
1129
1130	    /* make sure that the list contains a valid clip secquence */
1131	    /* the clip rectangles should be sorted by x then by y as the
1132               second order sort key */
1133
1134	    /* clip rectangle list is terminated by y_min and y_max set to 0 */
1135
1136	    /* to disable clipping set  y_min and y_max to 0 in the first
1137               clip rectangle . The first clip rectangle is clip_list[0].
1138             */
1139
1140	    if (bktr->max_clip_node == 0 &&
1141		(bktr->clip_list[0].y_min != 0 &&
1142		 bktr->clip_list[0].y_max != 0)) {
1143		return EINVAL;
1144	    }
1145
1146	    for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1147		if (bktr->clip_list[i].y_min == 0 &&
1148		    bktr->clip_list[i].y_max == 0) {
1149		    break;
1150		}
1151		if ( bktr->clip_list[i+1].y_min != 0 &&
1152		     bktr->clip_list[i+1].y_max != 0 &&
1153		     bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1154
1155		    bktr->max_clip_node = 0;
1156		    return (EINVAL);
1157
1158		 }
1159
1160		if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1161		    bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1162		    bktr->clip_list[i].x_min < 0 ||
1163		    bktr->clip_list[i].x_max < 0 ||
1164		    bktr->clip_list[i].y_min < 0 ||
1165		    bktr->clip_list[i].y_max < 0 ) {
1166		    bktr->max_clip_node = 0;
1167		    return (EINVAL);
1168		}
1169	    }
1170
1171	    bktr->dma_prog_loaded = FALSE;
1172
1173	    break;
1174
1175	case METEORSTATUS:	/* get Bt848 status */
1176		c_temp = INB(bktr, BKTR_DSTATUS);
1177		temp = 0;
1178		if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1179		if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1180		*(u_short *)arg = temp;
1181		break;
1182
1183	case BT848SFMT:		/* set input format */
1184		temp = *(unsigned int *)arg & BT848_IFORM_FORMAT;
1185		temp_iform = INB(bktr, BKTR_IFORM);
1186		temp_iform &= ~BT848_IFORM_FORMAT;
1187		temp_iform &= ~BT848_IFORM_XTSEL;
1188		OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1189		switch( temp ) {
1190		case BT848_IFORM_F_AUTO:
1191			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1192			METEOR_AUTOMODE;
1193			break;
1194
1195		case BT848_IFORM_F_NTSCM:
1196		case BT848_IFORM_F_NTSCJ:
1197			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1198				METEOR_NTSC;
1199			OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1200			OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1201			bktr->format_params = temp;
1202			break;
1203
1204		case BT848_IFORM_F_PALBDGHI:
1205		case BT848_IFORM_F_PALN:
1206		case BT848_IFORM_F_SECAM:
1207		case BT848_IFORM_F_RSVD:
1208		case BT848_IFORM_F_PALM:
1209			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1210				METEOR_PAL;
1211			OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1212			OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1213			bktr->format_params = temp;
1214			break;
1215
1216		}
1217		bktr->dma_prog_loaded = FALSE;
1218		break;
1219
1220	case METEORSFMT:	/* set input format */
1221		temp_iform = INB(bktr, BKTR_IFORM);
1222		temp_iform &= ~BT848_IFORM_FORMAT;
1223		temp_iform &= ~BT848_IFORM_XTSEL;
1224		switch(*(unsigned int *)arg & METEOR_FORM_MASK ) {
1225		case 0:		/* default */
1226		case METEOR_FMT_NTSC:
1227			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1228				METEOR_NTSC;
1229			OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1230		                         format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1231			OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1232			OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1233			bktr->format_params = BT848_IFORM_F_NTSCM;
1234			break;
1235
1236		case METEOR_FMT_PAL:
1237			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1238				METEOR_PAL;
1239			OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1240		                         format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1241			OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1242			OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1243			bktr->format_params = BT848_IFORM_F_PALBDGHI;
1244			break;
1245
1246		case METEOR_FMT_AUTOMODE:
1247			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1248				METEOR_AUTOMODE;
1249			OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1250		                         format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1251			break;
1252
1253		default:
1254			return( EINVAL );
1255		}
1256		bktr->dma_prog_loaded = FALSE;
1257		break;
1258
1259	case METEORGFMT:	/* get input format */
1260		*(u_int *)arg = bktr->flags & METEOR_FORM_MASK;
1261		break;
1262
1263
1264	case BT848GFMT:		/* get input format */
1265	        *(u_int *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1266		break;
1267
1268	case METEORSCOUNT:	/* (re)set error counts */
1269		counts = (struct meteor_counts *) arg;
1270		bktr->fifo_errors = counts->fifo_errors;
1271		bktr->dma_errors = counts->dma_errors;
1272		bktr->frames_captured = counts->frames_captured;
1273		bktr->even_fields_captured = counts->even_fields_captured;
1274		bktr->odd_fields_captured = counts->odd_fields_captured;
1275		break;
1276
1277	case METEORGCOUNT:	/* get error counts */
1278		counts = (struct meteor_counts *) arg;
1279		counts->fifo_errors = bktr->fifo_errors;
1280		counts->dma_errors = bktr->dma_errors;
1281		counts->frames_captured = bktr->frames_captured;
1282		counts->even_fields_captured = bktr->even_fields_captured;
1283		counts->odd_fields_captured = bktr->odd_fields_captured;
1284		break;
1285
1286	case METEORGVIDEO:
1287		video = (struct meteor_video *)arg;
1288		video->addr = bktr->video.addr;
1289		video->width = bktr->video.width;
1290		video->banksize = bktr->video.banksize;
1291		video->ramsize = bktr->video.ramsize;
1292		break;
1293
1294	case METEORSVIDEO:
1295		video = (struct meteor_video *)arg;
1296		bktr->video.addr = video->addr;
1297		bktr->video.width = video->width;
1298		bktr->video.banksize = video->banksize;
1299		bktr->video.ramsize = video->ramsize;
1300		break;
1301
1302	case METEORSFPS:
1303		set_fps(bktr, *(u_short *)arg);
1304		break;
1305
1306	case METEORGFPS:
1307		*(u_short *)arg = bktr->fps;
1308		break;
1309
1310	case METEORSHUE:	/* set hue */
1311		OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1312		break;
1313
1314	case METEORGHUE:	/* get hue */
1315		*(u_char *)arg = INB(bktr, BKTR_HUE);
1316		break;
1317
1318	case METEORSBRIG:	/* set brightness */
1319	        char_temp =    ( *(u_char *)arg & 0xff) - 128;
1320		OUTB(bktr, BKTR_BRIGHT, char_temp);
1321
1322		break;
1323
1324	case METEORGBRIG:	/* get brightness */
1325		*(u_char *)arg = INB(bktr, BKTR_BRIGHT) + 128;
1326		break;
1327
1328	case METEORSCSAT:	/* set chroma saturation */
1329		temp = (int)*(u_char *)arg;
1330
1331		OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1332		OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1333		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1334		                     & ~(BT848_E_CONTROL_SAT_U_MSB
1335					 | BT848_E_CONTROL_SAT_V_MSB));
1336		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1337		                     & ~(BT848_O_CONTROL_SAT_U_MSB |
1338					 BT848_O_CONTROL_SAT_V_MSB));
1339
1340		if ( temp & BIT_SEVEN_HIGH ) {
1341		        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1342			                     | (BT848_E_CONTROL_SAT_U_MSB
1343						| BT848_E_CONTROL_SAT_V_MSB));
1344			OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1345			                     | (BT848_O_CONTROL_SAT_U_MSB
1346						| BT848_O_CONTROL_SAT_V_MSB));
1347		}
1348		break;
1349
1350	case METEORGCSAT:	/* get chroma saturation */
1351		temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1352		if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1353			temp |= BIT_SEVEN_HIGH;
1354		*(u_char *)arg = (u_char)temp;
1355		break;
1356
1357	case METEORSCONT:	/* set contrast */
1358		temp = (int)*(u_char *)arg & 0xff;
1359		temp <<= 1;
1360		OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1361		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1362		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1363		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1364			(((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1365		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1366			(((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1367		break;
1368
1369	case METEORGCONT:	/* get contrast */
1370		temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1371		temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1372		*(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1373		break;
1374
1375	case BT848SCBUF:	/* set Clear-Buffer-on-start flag */
1376		bktr->clr_on_start = (*(int *)arg != 0);
1377		break;
1378
1379	case BT848GCBUF:	/* get Clear-Buffer-on-start flag */
1380		*(int *)arg = (int) bktr->clr_on_start;
1381		break;
1382
1383	case METEORSSIGNAL:
1384		if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
1385			return( EINVAL );
1386			break;
1387		}
1388		bktr->signal = *(int *) arg;
1389		bktr->proc = pr;
1390		break;
1391
1392	case METEORGSIGNAL:
1393		*(int *)arg = bktr->signal;
1394		break;
1395
1396	case METEORCAPTUR:
1397		temp = bktr->flags;
1398		switch (*(int *) arg) {
1399		case METEOR_CAP_SINGLE:
1400
1401			if (bktr->bigbuf==0)	/* no frame buffer allocated */
1402				return( ENOMEM );
1403			/* already capturing */
1404			if (temp & METEOR_CAP_MASK)
1405				return( EIO );
1406
1407
1408
1409			start_capture(bktr, METEOR_SINGLE);
1410
1411			/* wait for capture to complete */
1412			OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1413			OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1414			OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1415
1416			OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1417					    BT848_INT_RISCI      |
1418					    BT848_INT_VSYNC      |
1419					    BT848_INT_FMTCHG);
1420
1421			OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1422			error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
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 */
1700int
1701tuner_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 */
2120int
2121bktr_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		/* Unfortunatly 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
2292static int
2293dump_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
2369static bool_t
2370notclipped (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
2397static bool_t
2398getline(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
2442static bool_t
2443split(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 */
2530static void
2531rgb_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
2697static void
2698rgb_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 */
2847static void
2848yuvpack_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 =   1 << 6 | 1 << 4 | 1 << 2 | 3;
2868	bktr->capcontrol = 3 << 2 |  3;
2869
2870	dma_prog = (u_int *) bktr->dma_prog;
2871
2872	/* Construct Write */
2873
2874	/* write , sol, eol */
2875	inst = OP_WRITE	 | OP_SOL | (cols);
2876	/* write , sol, eol */
2877	inst3 = OP_WRITE | OP_EOL | (cols);
2878
2879	if (bktr->video.addr)
2880		target_buffer = bktr->video.addr;
2881	else
2882		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
2883
2884	buffer = target_buffer;
2885
2886	/* contruct sync : for video packet format */
2887	/* sync, mode indicator packed data */
2888	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2889	*dma_prog++ = htole32(0);  /* NULL WORD */
2890
2891	b = cols;
2892
2893	for (i = 0; i < (rows/interlace); i++) {
2894		*dma_prog++ = htole32(inst);
2895		*dma_prog++ = htole32(target_buffer);
2896		*dma_prog++ = htole32(inst3);
2897		*dma_prog++ = htole32(target_buffer + b);
2898		target_buffer += interlace*(cols * 2);
2899	}
2900
2901	switch (i_flag) {
2902	case 1:
2903		/* sync vre */
2904		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
2905		*dma_prog++ = htole32(0);  /* NULL WORD */
2906		*dma_prog++ = htole32(OP_JUMP);
2907		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2908		return;
2909
2910	case 2:
2911		/* sync vro */
2912		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
2913		*dma_prog++ = htole32(0);  /* NULL WORD */
2914		*dma_prog++ = htole32(OP_JUMP);
2915		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2916		return;
2917
2918	case 3:
2919		/* sync vro */
2920		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2921		*dma_prog++ = htole32(0);  /* NULL WORD */
2922		*dma_prog++ = htole32(OP_JUMP);
2923		*dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
2924		break;
2925	}
2926
2927	if (interlace == 2) {
2928
2929		target_buffer =	buffer + cols*2;
2930
2931		dma_prog = (u_int * ) bktr->odd_dma_prog;
2932
2933		/* sync vre */
2934		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2935		*dma_prog++ = htole32(0);  /* NULL WORD */
2936
2937		for (i = 0; i < (rows/interlace) ; i++) {
2938			*dma_prog++ = htole32(inst);
2939			*dma_prog++ = htole32(target_buffer);
2940			*dma_prog++ = htole32(inst3);
2941			*dma_prog++ = htole32(target_buffer + b);
2942			target_buffer += interlace * ( cols*2);
2943		}
2944	}
2945
2946	/* sync vro IRQ bit */
2947	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2948	*dma_prog++ = htole32(0);  /* NULL WORD */
2949	*dma_prog++ = htole32(OP_JUMP);
2950	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2951
2952	*dma_prog++ = htole32(OP_JUMP);
2953	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2954	*dma_prog++ = htole32(0);  /* NULL WORD */
2955}
2956
2957
2958/*
2959 *
2960 */
2961static void
2962yuv422_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2963{
2964	int		i;
2965	u_int		inst;
2966	u_int		target_buffer, t1, buffer;
2967	u_int		*dma_prog;
2968        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2969
2970	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2971
2972	dma_prog = (u_int *) bktr->dma_prog;
2973
2974	bktr->capcontrol =   1 << 6 | 1 << 4 |	3;
2975
2976	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2977	OUTB(bktr, BKTR_OFORM, 0x00);
2978
2979	OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
2980	OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
2981
2982	OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC);	/* chroma agc enable */
2983	OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2984
2985	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2986	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2987	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2988	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2989
2990	/* disable gamma correction removal */
2991	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2992
2993	/* Construct Write */
2994	inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
2995	if (bktr->video.addr)
2996		target_buffer = (u_int) bktr->video.addr;
2997	else
2998		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
2999
3000	buffer = target_buffer;
3001
3002	t1 = buffer;
3003
3004	/* contruct sync : for video packet format */
3005	/*     sync, mode indicator packed data*/
3006	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3007	*dma_prog++ = htole32(0);  /* NULL WORD */
3008
3009	for (i = 0; i < (rows/interlace ) ; i++) {
3010		*dma_prog++ = htole32(inst);
3011		*dma_prog++ = htole32(cols/2 | cols/2 << 16);
3012		*dma_prog++ = htole32(target_buffer);
3013		*dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3014		*dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) +
3015		    i*cols/2 * interlace);
3016		target_buffer += interlace*cols;
3017	}
3018
3019	switch (i_flag) {
3020	case 1:
3021		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
3022		*dma_prog++ = htole32(0);  /* NULL WORD */
3023
3024		*dma_prog++ = htole32(OP_JUMP);
3025		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3026		return;
3027
3028	case 2:
3029		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vre*/
3030		*dma_prog++ = htole32(0);  /* NULL WORD */
3031
3032		*dma_prog++ = htole32(OP_JUMP);
3033		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3034		return;
3035
3036	case 3:
3037		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3038		*dma_prog++ = htole32(0);  /* NULL WORD */
3039
3040		*dma_prog++ = htole32(OP_JUMP);
3041		*dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
3042		break;
3043	}
3044
3045	if (interlace == 2) {
3046
3047		dma_prog = (u_int * ) bktr->odd_dma_prog;
3048
3049		target_buffer  = (u_int) buffer + cols;
3050		t1 = buffer + cols/2;
3051		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3052		*dma_prog++ = htole32(0);  /* NULL WORD */
3053
3054		for (i = 0; i < (rows/interlace )  ; i++) {
3055			*dma_prog++ = htole32(inst);
3056			*dma_prog++ = htole32(cols/2 | cols/2 << 16);
3057			*dma_prog++ = htole32(target_buffer);
3058			*dma_prog++ = htole32(t1 + (cols*rows) +
3059			    i*cols/2 * interlace);
3060			*dma_prog++ = htole32(t1 + (cols*rows) +
3061			    (cols*rows/2) + i*cols/2 * interlace);
3062			target_buffer += interlace*cols;
3063		}
3064	}
3065
3066	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3067	*dma_prog++ = htole32(0);  /* NULL WORD */
3068	*dma_prog++ = htole32(OP_JUMP);
3069	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3070	*dma_prog++ = htole32(0);  /* NULL WORD */
3071}
3072
3073
3074/*
3075 *
3076 */
3077static void
3078yuv12_prog( bktr_ptr_t bktr, char i_flag,
3079	     int cols, int rows, int interlace ){
3080
3081	int		i;
3082	u_int		inst;
3083	u_int		inst1;
3084	u_int		target_buffer, t1, buffer;
3085	u_int		*dma_prog;
3086        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3087
3088	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3089
3090	dma_prog = (u_int *) bktr->dma_prog;
3091
3092	bktr->capcontrol =   1 << 6 | 1 << 4 |	3;
3093
3094	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3095	OUTB(bktr, BKTR_OFORM, 0x0);
3096
3097	/* Construct Write */
3098	inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
3099	inst1  = OP_WRITES123  | OP_SOL | OP_EOL |  (cols);
3100	if (bktr->video.addr)
3101		target_buffer = (u_int) bktr->video.addr;
3102	else
3103		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
3104
3105	buffer = target_buffer;
3106	t1 = buffer;
3107
3108	/* sync, mode indicator packed data*/
3109	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3110	*dma_prog++ = htole32(0);  /* NULL WORD */
3111
3112	for (i = 0; i < (rows/interlace )/2 ; i++) {
3113		*dma_prog++ = htole32(inst);
3114		*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3115		*dma_prog++ = htole32(target_buffer);
3116		*dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3117		*dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) +
3118		    i*cols/2 * interlace);
3119		target_buffer += interlace*cols;
3120		*dma_prog++ = htole32(inst1);
3121		*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3122		*dma_prog++ = htole32(target_buffer);
3123		target_buffer += interlace*cols;
3124
3125	}
3126
3127	switch (i_flag) {
3128	case 1:
3129		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
3130		*dma_prog++ = htole32(0);  /* NULL WORD */
3131
3132		*dma_prog++ = htole32(OP_JUMP);
3133		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3134		return;
3135
3136	case 2:
3137		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vro*/
3138		*dma_prog++ = htole32(0);  /* NULL WORD */
3139
3140		*dma_prog++ = htole32(OP_JUMP);
3141		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3142		return;
3143
3144	case 3:
3145		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3146		*dma_prog++ = htole32(0);  /* NULL WORD */
3147		*dma_prog++ = htole32(OP_JUMP);
3148		*dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
3149		break;
3150	}
3151
3152	if (interlace == 2) {
3153
3154		dma_prog = (u_int *)bktr->odd_dma_prog;
3155
3156		target_buffer  = (u_int) buffer + cols;
3157		t1 = buffer + cols/2;
3158		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3159		*dma_prog++ = htole32(0);  /* NULL WORD */
3160
3161		for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3162			*dma_prog++ = htole32(inst);
3163			*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3164			*dma_prog++ = htole32(target_buffer);
3165			*dma_prog++ = htole32(t1 + (cols*rows) +
3166			    i*cols/2 * interlace);
3167			*dma_prog++ = htole32(t1 + (cols*rows) +
3168			    (cols*rows/4) + i*cols/2 * interlace);
3169			target_buffer += interlace*cols;
3170			*dma_prog++ = htole32(inst1);
3171			*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3172			*dma_prog++ = htole32(target_buffer);
3173			target_buffer += interlace*cols;
3174		}
3175	}
3176
3177	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3178	*dma_prog++ = htole32(0);  /* NULL WORD */
3179	*dma_prog++ = htole32(OP_JUMP);
3180	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3181	*dma_prog++ = htole32(0);  /* NULL WORD */
3182}
3183
3184
3185/*
3186 *
3187 */
3188static void
3189build_dma_prog( bktr_ptr_t bktr, char i_flag )
3190{
3191	int			rows, cols,  interlace;
3192	int			tmp_int;
3193	unsigned int		temp;
3194	const struct format_params *fp;
3195        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3196
3197
3198	fp = &format_params[bktr->format_params];
3199
3200	OUTL(bktr, BKTR_INT_MASK,  ALL_INTS_DISABLED);
3201
3202	/* disable FIFO & RISC, leave other bits alone */
3203	OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3204
3205	/* set video parameters */
3206	if (bktr->capture_area_enabled)
3207	  temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3208		  / fp->scaled_htotal / bktr->cols) -  4096;
3209	else
3210	  temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3211		  / fp->scaled_htotal / bktr->cols) -  4096;
3212
3213	/* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3214	OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3215	OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3216	OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3217	OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3218
3219	/* horizontal active */
3220	temp = bktr->cols;
3221	/* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3222	OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3223	OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3224	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3225	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3226	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3227	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3228
3229	/* horizontal delay */
3230	if (bktr->capture_area_enabled)
3231	  temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3232		 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3233	else
3234	  temp = (fp->hdelay * bktr->cols) / fp->hactive;
3235
3236	temp = temp & 0x3fe;
3237
3238	/* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3239	OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3240	OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3241	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3242	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3243	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3244	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3245
3246	/* vertical scale */
3247
3248	if (bktr->capture_area_enabled) {
3249	  if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3250	      bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3251	    tmp_int = 65536 -
3252	    (((bktr->capture_area_y_size  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3253	  else {
3254	    tmp_int = 65536 -
3255	    (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3256	  }
3257	} else {
3258	  if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3259	      bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3260	    tmp_int = 65536 -
3261	    (((fp->vactive  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3262	  else {
3263	    tmp_int = 65536  -
3264	    (((fp->vactive * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3265	  }
3266	}
3267
3268	tmp_int &= 0x1fff;
3269	/* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3270	OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3271	OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3272	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3273	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3274	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3275	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3276
3277
3278	/* vertical active */
3279	if (bktr->capture_area_enabled)
3280	  temp = bktr->capture_area_y_size;
3281	else
3282	  temp = fp->vactive;
3283	/* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3284	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3285	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3286	OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3287	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3288	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3289	OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3290
3291	/* vertical delay */
3292	if (bktr->capture_area_enabled)
3293	  temp = fp->vdelay + (bktr->capture_area_y_offset);
3294	else
3295	  temp = fp->vdelay;
3296	/* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3297	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3298	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3299	OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3300	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3301	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3302	OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3303
3304	/* end of video params */
3305
3306	if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3307	   && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3308		OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3309	} else {
3310		OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3311	}
3312
3313	/* capture control */
3314	switch (i_flag) {
3315	case 1:
3316	        bktr->bktr_cap_ctl =
3317		    (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3318		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3319		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3320		interlace = 1;
3321		break;
3322	 case 2:
3323	        bktr->bktr_cap_ctl =
3324			(BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3325		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3326		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3327		interlace = 1;
3328		break;
3329	 default:
3330	        bktr->bktr_cap_ctl =
3331			(BT848_CAP_CTL_DITH_FRAME |
3332			 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3333		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3334		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3335		interlace = 2;
3336		break;
3337	}
3338
3339	OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
3340
3341	rows = bktr->rows;
3342	cols = bktr->cols;
3343
3344	bktr->vbiflags &= ~VBI_CAPTURE;	/* default - no vbi capture */
3345
3346	/* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3347	/* user, then use the rgb_vbi RISC program. */
3348	/* Otherwise, use the normal rgb RISC program */
3349	if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3350		if ( (bktr->vbiflags & VBI_OPEN)
3351		   ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3352		   ||(bktr->format_params == BT848_IFORM_F_SECAM)
3353                   ){
3354			bktr->bktr_cap_ctl |=
3355		                BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3356			bktr->vbiflags |= VBI_CAPTURE;
3357			rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3358			return;
3359		} else {
3360			rgb_prog(bktr, i_flag, cols, rows, interlace);
3361			return;
3362		}
3363	}
3364
3365	if ( pf_int->public.type  == METEOR_PIXTYPE_YUV ) {
3366		yuv422_prog(bktr, i_flag, cols, rows, interlace);
3367		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3368		     | pixfmt_swap_flags( bktr->pixfmt ));
3369		return;
3370	}
3371
3372	if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_PACKED ) {
3373		yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3374		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3375		     | pixfmt_swap_flags( bktr->pixfmt ));
3376		return;
3377	}
3378
3379	if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_12 ) {
3380		yuv12_prog(bktr, i_flag, cols, rows, interlace);
3381		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3382		     | pixfmt_swap_flags( bktr->pixfmt ));
3383		return;
3384	}
3385	return;
3386}
3387
3388
3389/******************************************************************************
3390 * video & video capture specific routines:
3391 */
3392
3393
3394/*
3395 *
3396 */
3397static void
3398start_capture( bktr_ptr_t bktr, unsigned type )
3399{
3400	u_char			i_flag;
3401	const struct format_params   *fp;
3402
3403	fp = &format_params[bktr->format_params];
3404
3405	/*  If requested, clear out capture buf first  */
3406	if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3407		bzero((caddr_t)bktr->bigbuf,
3408		      (size_t)bktr->rows * bktr->cols * bktr->frames *
3409			pixfmt_table[ bktr->pixfmt ].public.Bpp);
3410	}
3411
3412	OUTB(bktr, BKTR_DSTATUS,  0);
3413	OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3414
3415	bktr->flags |= type;
3416	bktr->flags &= ~METEOR_WANT_MASK;
3417	switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3418	case METEOR_ONLY_EVEN_FIELDS:
3419		bktr->flags |= METEOR_WANT_EVEN;
3420		i_flag = 1;
3421		break;
3422	case METEOR_ONLY_ODD_FIELDS:
3423		bktr->flags |= METEOR_WANT_ODD;
3424		i_flag = 2;
3425		break;
3426	default:
3427		bktr->flags |= METEOR_WANT_MASK;
3428		i_flag = 3;
3429		break;
3430	}
3431
3432	/*  TDEC is only valid for continuous captures  */
3433	if ( type == METEOR_SINGLE ) {
3434		u_short	fps_save = bktr->fps;
3435
3436		set_fps(bktr, fp->frame_rate);
3437		bktr->fps = fps_save;
3438	}
3439	else
3440		set_fps(bktr, bktr->fps);
3441
3442	if (bktr->dma_prog_loaded == FALSE) {
3443		build_dma_prog(bktr, i_flag);
3444		bktr->dma_prog_loaded = TRUE;
3445	}
3446
3447
3448	OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
3449}
3450
3451
3452/*
3453 *
3454 */
3455static void
3456set_fps( bktr_ptr_t bktr, u_short fps )
3457{
3458	const struct format_params	*fp;
3459	int i_flag;
3460
3461	fp = &format_params[bktr->format_params];
3462
3463	switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3464	case METEOR_ONLY_EVEN_FIELDS:
3465		bktr->flags |= METEOR_WANT_EVEN;
3466		i_flag = 1;
3467		break;
3468	case METEOR_ONLY_ODD_FIELDS:
3469		bktr->flags |= METEOR_WANT_ODD;
3470		i_flag = 1;
3471		break;
3472	default:
3473		bktr->flags |= METEOR_WANT_MASK;
3474		i_flag = 2;
3475		break;
3476	}
3477
3478	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3479	OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3480
3481	bktr->fps = fps;
3482	OUTB(bktr, BKTR_TDEC, 0);
3483
3484	if (fps < fp->frame_rate)
3485		OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3486	else
3487		OUTB(bktr, BKTR_TDEC, 0);
3488	return;
3489
3490}
3491
3492
3493
3494
3495
3496/*
3497 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3498 *   achieve the specified swapping.
3499 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3500 *   byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3501 *   and read R->L).
3502 * Note also that for 3Bpp, we may additionally need to do some creative
3503 *   SKIPing to align the FIFO bytelines with the target buffer (see split()).
3504 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3505 *   as one would expect.
3506 */
3507
3508static u_int 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
3545static int oformat_meteor_to_bt( u_int format )
3546{
3547	int    i;
3548        const struct meteor_pixfmt *pf1, *pf2;
3549
3550	/*  Find format in compatibility table  */
3551	for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3552		if ( meteor_pixfmt_table[i].meteor_format == format )
3553			break;
3554
3555	if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3556		return -1;
3557	pf1 = &meteor_pixfmt_table[i].public;
3558
3559	/*  Match it with an entry in master pixel format table  */
3560	for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3561		pf2 = &pixfmt_table[i].public;
3562
3563		if (( pf1->type        == pf2->type        ) &&
3564		    ( pf1->Bpp         == pf2->Bpp         ) &&
3565		    !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3566		    ( pf1->swap_bytes  == pf2->swap_bytes  ) &&
3567		    ( pf1->swap_shorts == pf2->swap_shorts ))
3568			break;
3569	}
3570	if ( i >= PIXFMT_TABLE_SIZE )
3571		return -1;
3572
3573	return i;
3574}
3575
3576/******************************************************************************
3577 * i2c primitives:
3578 */
3579
3580/* */
3581#define I2CBITTIME		(0x5)	/* 5 * 0.48uS */
3582#define I2CBITTIME_878		(0x8)
3583#define I2C_READ		0x01
3584#define I2C_COMMAND		((I2CBITTIME << 4) |		\
3585				 BT848_DATA_CTL_I2CSCL |	\
3586				 BT848_DATA_CTL_I2CSDA)
3587
3588#define I2C_COMMAND_878		((I2CBITTIME_878 << 4) |	\
3589				 BT848_DATA_CTL_I2CSCL |	\
3590				 BT848_DATA_CTL_I2CSDA)
3591
3592/*
3593 * Program the i2c bus directly
3594 */
3595int
3596i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3597{
3598	u_int		x;
3599	u_int		data;
3600
3601	/* clear status bits */
3602	OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3603
3604	/* build the command datum */
3605	if (bktr->id == BROOKTREE_848  ||
3606	    bktr->id == BROOKTREE_848A ||
3607	    bktr->id == BROOKTREE_849A) {
3608	  data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3609	} else {
3610	  data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3611	}
3612	if ( byte2 != -1 ) {
3613		data |= ((byte2 & 0xff) << 8);
3614		data |= BT848_DATA_CTL_I2CW3B;
3615	}
3616
3617	/* write the address and data */
3618	OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3619
3620	/* wait for completion */
3621	for ( x = 0x7fffffff; x; --x ) {	/* safety valve */
3622		if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3623			break;
3624	}
3625
3626	/* check for ACK */
3627	if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3628		return( -1 );
3629
3630	/* return OK */
3631	return( 0 );
3632}
3633
3634
3635/*
3636 *
3637 */
3638int
3639i2cRead( bktr_ptr_t bktr, int addr )
3640{
3641	u_int32_t x, stat;
3642
3643	/* clear status bits */
3644	OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3645
3646	/* write the READ address */
3647	/* The Bt878 and Bt879  differed on the treatment of i2c commands */
3648
3649	if (bktr->id == BROOKTREE_848  ||
3650	    bktr->id == BROOKTREE_848A ||
3651	    bktr->id == BROOKTREE_849A)
3652		OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3653	else
3654		OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3655
3656	/* wait for completion */
3657	for (x = 5000; x--; DELAY(1))	/* 5 msec, safety valve */
3658		if ((stat = INL(bktr, BKTR_INT_STAT)) & BT848_INT_I2CDONE)
3659			break;
3660
3661	/* check for ACK */
3662	if ((stat & (I2C_BITS)) != (I2C_BITS))
3663		return (-1);
3664
3665	/* it was a read */
3666	x = INL(bktr, BKTR_I2C_DATA_CTL);
3667	return ((x >> 8) & 0xff);
3668}
3669
3670/* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3671/* bt848 automated i2c bus controller cannot handle */
3672/* Therefore we need low level control of the i2c bus hardware */
3673/* Idea for the following functions are from elsewhere in this driver and */
3674/* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3675
3676#define BITD    40
3677static void i2c_start( bktr_ptr_t bktr) {
3678        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3679        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3680        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3681        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3682}
3683
3684static void i2c_stop( bktr_ptr_t bktr) {
3685        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3686        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3687        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3688}
3689
3690static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3691        int x;
3692        int status;
3693
3694        /* write out the byte */
3695        for ( x = 7; x >= 0; --x ) {
3696                if ( data & (1<<x) ) {
3697			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3698                        DELAY( BITD );          /* assert HI data */
3699			OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3700                        DELAY( BITD );          /* strobe clock */
3701			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3702                        DELAY( BITD );          /* release clock */
3703                }
3704                else {
3705			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3706                        DELAY( BITD );          /* assert LO data */
3707			OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3708                        DELAY( BITD );          /* strobe clock */
3709			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3710                        DELAY( BITD );          /* release clock */
3711                }
3712        }
3713
3714        /* look for an ACK */
3715	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3716	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3717        status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;       /* read the ACK bit */
3718        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3719
3720        return( status );
3721}
3722
3723static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3724        int x;
3725        int bit;
3726        int byte = 0;
3727
3728        /* read in the byte */
3729	OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3730        DELAY( BITD );                          /* float data */
3731        for ( x = 7; x >= 0; --x ) {
3732		OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3733                DELAY( BITD );                  /* strobe clock */
3734                bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1;  /* read the data bit */
3735                if ( bit ) byte |= (1<<x);
3736		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3737                DELAY( BITD );                  /* release clock */
3738        }
3739        /* After reading the byte, send an ACK */
3740        /* (unless that was the last byte, for which we send a NAK */
3741        if (last) { /* send NAK - same a writing a 1 */
3742		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3743                DELAY( BITD );                  /* set data bit */
3744		OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3745                DELAY( BITD );                  /* strobe clock */
3746		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3747                DELAY( BITD );                  /* release clock */
3748        } else { /* send ACK - same as writing a 0 */
3749		OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3750                DELAY( BITD );                  /* set data bit */
3751		OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3752                DELAY( BITD );                  /* strobe clock */
3753		OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3754                DELAY( BITD );                  /* release clock */
3755        }
3756
3757        *data=byte;
3758	return 0;
3759}
3760#undef BITD
3761
3762/* Write to the MSP or DPL registers */
3763void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
3764		    unsigned int data){
3765	unsigned int msp_w_addr = i2c_addr;
3766	unsigned char addr_l, addr_h, data_h, data_l ;
3767	addr_h = (addr >>8) & 0xff;
3768	addr_l = addr & 0xff;
3769	data_h = (data >>8) & 0xff;
3770	data_l = data & 0xff;
3771
3772	i2c_start(bktr);
3773	i2c_write_byte(bktr, msp_w_addr);
3774	i2c_write_byte(bktr, dev);
3775	i2c_write_byte(bktr, addr_h);
3776	i2c_write_byte(bktr, addr_l);
3777	i2c_write_byte(bktr, data_h);
3778	i2c_write_byte(bktr, data_l);
3779	i2c_stop(bktr);
3780}
3781
3782/* Read from the MSP or DPL registers */
3783unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
3784	unsigned int data;
3785	unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
3786	addr_h = (addr >>8) & 0xff;
3787	addr_l = addr & 0xff;
3788	dev_r = dev+1;
3789
3790	i2c_start(bktr);
3791	i2c_write_byte(bktr,i2c_addr);
3792	i2c_write_byte(bktr,dev_r);
3793	i2c_write_byte(bktr,addr_h);
3794	i2c_write_byte(bktr,addr_l);
3795
3796	i2c_start(bktr);
3797	i2c_write_byte(bktr,i2c_addr+1);
3798	i2c_read_byte(bktr,&data_1, 0);
3799	i2c_read_byte(bktr,&data_2, 1);
3800	i2c_stop(bktr);
3801	data = (data_1<<8) | data_2;
3802	return data;
3803}
3804
3805/* Reset the MSP or DPL chip */
3806/* The user can block the reset (which is handy if you initialise the
3807 * MSP audio in another operating system first (eg in Windows)
3808 */
3809void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
3810
3811#ifndef BKTR_NO_MSP_RESET
3812	/* put into reset mode */
3813	i2c_start(bktr);
3814	i2c_write_byte(bktr, i2c_addr);
3815	i2c_write_byte(bktr, 0x00);
3816	i2c_write_byte(bktr, 0x80);
3817	i2c_write_byte(bktr, 0x00);
3818	i2c_stop(bktr);
3819
3820	/* put back to operational mode */
3821	i2c_start(bktr);
3822	i2c_write_byte(bktr, i2c_addr);
3823	i2c_write_byte(bktr, 0x00);
3824	i2c_write_byte(bktr, 0x00);
3825	i2c_write_byte(bktr, 0x00);
3826	i2c_stop(bktr);
3827#endif
3828	return;
3829
3830}
3831
3832static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3833
3834	/* XXX errors ignored */
3835	i2c_start(bktr);
3836	i2c_write_byte(bktr,bktr->remote_control_addr);
3837	i2c_read_byte(bktr,&(remote->data[0]), 0);
3838	i2c_read_byte(bktr,&(remote->data[1]), 0);
3839	i2c_read_byte(bktr,&(remote->data[2]), 0);
3840	i2c_stop(bktr);
3841
3842	return;
3843}
3844
3845#if defined( I2C_SOFTWARE_PROBE )
3846
3847/*
3848 * we are keeping this around for any parts that we need to probe
3849 * but that CANNOT be probed via an i2c read.
3850 * this is necessary because the hardware i2c mechanism
3851 * cannot be programmed for 1 byte writes.
3852 * currently there are no known i2c parts that we need to probe
3853 * and that cannot be safely read.
3854 */
3855static int	i2cProbe( bktr_ptr_t bktr, int addr );
3856#define BITD		40
3857#define EXTRA_START
3858
3859/*
3860 * probe for an I2C device at addr.
3861 */
3862static int
3863i2cProbe( bktr_ptr_t bktr, int addr )
3864{
3865	int		x, status;
3866
3867	/* the START */
3868#if defined( EXTRA_START )
3869	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );	/* release data */
3870	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );	/* release clock */
3871#endif /* EXTRA_START */
3872	OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );	/* lower data */
3873	OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );	/* lower clock */
3874
3875	/* write addr */
3876	for ( x = 7; x >= 0; --x ) {
3877		if ( addr & (1<<x) ) {
3878			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3879			DELAY( BITD );		/* assert HI data */
3880			OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3881			DELAY( BITD );		/* strobe clock */
3882			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3883			DELAY( BITD );		/* release clock */
3884		}
3885		else {
3886			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3887			DELAY( BITD );		/* assert LO data */
3888			OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3889			DELAY( BITD );		/* strobe clock */
3890			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3891			DELAY( BITD );		/* release clock */
3892		}
3893	}
3894
3895	/* look for an ACK */
3896	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );	/* float data */
3897	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );	/* strobe clock */
3898	status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;	/* read the ACK bit */
3899	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );	/* release clock */
3900
3901	/* the STOP */
3902	OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );	/* lower clock & data */
3903	OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );	/* release clock */
3904	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );	/* release data */
3905
3906	return( status );
3907}
3908#undef EXTRA_START
3909#undef BITD
3910
3911#endif /* I2C_SOFTWARE_PROBE */
3912