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