bktr_core.c revision 1.31
1/*	$OpenBSD: bktr_core.c,v 1.31 2013/10/04 07:27:36 brad Exp $	*/
2/* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.114 2000/10/31 13:09:56 roger Exp $ */
3
4/*
5 * This is part of the Driver for Video Capture Cards (Frame grabbers)
6 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
7 * chipset.
8 * Copyright Roger Hardiman and Amancio Hasty.
9 *
10 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
11 *               Handles all the open, close, ioctl and read userland calls.
12 *               Sets the Bt848 registers and generates RISC pograms.
13 *               Controls the i2c bus and GPIO interface.
14 *               Contains the interface to the kernel.
15 *               (eg probe/attach and open/close/ioctl)
16 *
17 */
18
19 /*
20   The Brooktree BT848 Driver driver is based upon Mark Tinguely and
21   Jim Lowe's driver for the Matrox Meteor PCI card . The
22   Philips SAA 7116 and SAA 7196 are very different chipsets than
23   the BT848.
24
25   The original copyright notice by Mark and Jim is included mostly
26   to honor their fantastic work in the Matrox Meteor driver!
27
28 */
29
30/*
31 * 1. Redistributions of source code must retain the
32 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 *    notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 *    notice, this list of conditions and the following disclaimer in the
42 *    documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 *    must display the following acknowledgement:
45 *	This product includes software developed by Amancio Hasty and
46 *      Roger Hardiman
47 * 4. The name of the author may not be used to endorse or promote products
48 *    derived from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
51 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53 * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
54 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
56 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
58 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
59 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 * POSSIBILITY OF SUCH DAMAGE.
61 */
62
63
64
65
66/*
67 * 1. Redistributions of source code must retain the
68 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
69 * All rights reserved.
70 *
71 * Redistribution and use in source and binary forms, with or without
72 * modification, are permitted provided that the following conditions
73 * are met:
74 * 1. Redistributions of source code must retain the above copyright
75 *    notice, this list of conditions and the following disclaimer.
76 * 2. Redistributions in binary form must reproduce the above copyright
77 *    notice, this list of conditions and the following disclaimer in the
78 *    documentation and/or other materials provided with the distribution.
79 * 3. All advertising materials mentioning features or use of this software
80 *    must display the following acknowledgement:
81 *	This product includes software developed by Mark Tinguely and Jim Lowe
82 * 4. The name of the author may not be used to endorse or promote products
83 *    derived from this software without specific prior written permission.
84 *
85 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
86 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88 * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
89 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
91 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
92 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
93 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
94 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
95 * POSSIBILITY OF SUCH DAMAGE.
96 */
97
98#include <sys/param.h>
99#include <sys/systm.h>
100#include <sys/kernel.h>
101#include <sys/signalvar.h>
102#include <sys/vnode.h>
103#include <sys/stdint.h>		/* uintptr_t */
104
105#include <dev/rndvar.h>
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%x\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		add_video_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	add_video_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 = (struct proc *)0;
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        int             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 ((int) uio->uio_iov->iov_len < 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(BKTR_SLEEP, BKTRPRI, "captur", 0);
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	int             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(VBI_SLEEP, VBIPRI, "vbi", 0))) {
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 = (int)uio->uio_iov->iov_len;
1070
1071	if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1072
1073	/* Check if we can read this number of bytes without having
1074	 * to wrap around the circular buffer */
1075	if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1076		/* We need to wrap around */
1077
1078		readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1079		status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
1080		if (status == 0)
1081			status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1082	} else {
1083		/* We do not need to wrap around */
1084		status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1085	}
1086
1087	/* Update the number of bytes left to read */
1088	bktr->vbisize -= readsize;
1089
1090	/* Update vbistart */
1091	bktr->vbistart += readsize;
1092	bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1093
1094	return( status );
1095
1096}
1097
1098
1099
1100/*
1101 * video ioctls
1102 */
1103int
1104video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
1105{
1106	volatile u_char		c_temp;
1107	unsigned int		temp;
1108	unsigned int		temp_iform;
1109	unsigned int		error;
1110	struct meteor_geomet	*geo;
1111	struct meteor_counts	*counts;
1112	struct meteor_video	*video;
1113	struct bktr_capture_area *cap_area;
1114	vaddr_t			buf;
1115	int                     i;
1116	char                    char_temp;
1117
1118	switch ( cmd ) {
1119
1120	case BT848SCLIP: /* set clip region */
1121	    bktr->max_clip_node = 0;
1122	    memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1123
1124	    for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1125		if (bktr->clip_list[i].y_min ==  0 &&
1126		    bktr->clip_list[i].y_max == 0)
1127		    break;
1128	    }
1129	    bktr->max_clip_node = i;
1130
1131	    /* make sure that the list contains a valid clip secquence */
1132	    /* the clip rectangles should be sorted by x then by y as the
1133               second order sort key */
1134
1135	    /* clip rectangle list is terminated by y_min and y_max set to 0 */
1136
1137	    /* to disable clipping set  y_min and y_max to 0 in the first
1138               clip rectangle . The first clip rectangle is clip_list[0].
1139             */
1140
1141	    if (bktr->max_clip_node == 0 &&
1142		(bktr->clip_list[0].y_min != 0 &&
1143		 bktr->clip_list[0].y_max != 0)) {
1144		return EINVAL;
1145	    }
1146
1147	    for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1148		if (bktr->clip_list[i].y_min == 0 &&
1149		    bktr->clip_list[i].y_max == 0) {
1150		    break;
1151		}
1152		if ( bktr->clip_list[i+1].y_min != 0 &&
1153		     bktr->clip_list[i+1].y_max != 0 &&
1154		     bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1155
1156		    bktr->max_clip_node = 0;
1157		    return (EINVAL);
1158
1159		 }
1160
1161		if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1162		    bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1163		    bktr->clip_list[i].x_min < 0 ||
1164		    bktr->clip_list[i].x_max < 0 ||
1165		    bktr->clip_list[i].y_min < 0 ||
1166		    bktr->clip_list[i].y_max < 0 ) {
1167		    bktr->max_clip_node = 0;
1168		    return (EINVAL);
1169		}
1170	    }
1171
1172	    bktr->dma_prog_loaded = FALSE;
1173
1174	    break;
1175
1176	case METEORSTATUS:	/* get Bt848 status */
1177		c_temp = INB(bktr, BKTR_DSTATUS);
1178		temp = 0;
1179		if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1180		if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1181		*(u_short *)arg = temp;
1182		break;
1183
1184	case BT848SFMT:		/* set input format */
1185		temp = *(unsigned int *)arg & BT848_IFORM_FORMAT;
1186		temp_iform = INB(bktr, BKTR_IFORM);
1187		temp_iform &= ~BT848_IFORM_FORMAT;
1188		temp_iform &= ~BT848_IFORM_XTSEL;
1189		OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1190		switch( temp ) {
1191		case BT848_IFORM_F_AUTO:
1192			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1193			METEOR_AUTOMODE;
1194			break;
1195
1196		case BT848_IFORM_F_NTSCM:
1197		case BT848_IFORM_F_NTSCJ:
1198			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1199				METEOR_NTSC;
1200			OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1201			OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1202			bktr->format_params = temp;
1203			break;
1204
1205		case BT848_IFORM_F_PALBDGHI:
1206		case BT848_IFORM_F_PALN:
1207		case BT848_IFORM_F_SECAM:
1208		case BT848_IFORM_F_RSVD:
1209		case BT848_IFORM_F_PALM:
1210			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1211				METEOR_PAL;
1212			OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1213			OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1214			bktr->format_params = temp;
1215			break;
1216
1217		}
1218		bktr->dma_prog_loaded = FALSE;
1219		break;
1220
1221	case METEORSFMT:	/* set input format */
1222		temp_iform = INB(bktr, BKTR_IFORM);
1223		temp_iform &= ~BT848_IFORM_FORMAT;
1224		temp_iform &= ~BT848_IFORM_XTSEL;
1225		switch(*(unsigned int *)arg & METEOR_FORM_MASK ) {
1226		case 0:		/* default */
1227		case METEOR_FMT_NTSC:
1228			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1229				METEOR_NTSC;
1230			OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1231		                         format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1232			OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1233			OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1234			bktr->format_params = BT848_IFORM_F_NTSCM;
1235			break;
1236
1237		case METEOR_FMT_PAL:
1238			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1239				METEOR_PAL;
1240			OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1241		                         format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1242			OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1243			OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1244			bktr->format_params = BT848_IFORM_F_PALBDGHI;
1245			break;
1246
1247		case METEOR_FMT_AUTOMODE:
1248			bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1249				METEOR_AUTOMODE;
1250			OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1251		                         format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1252			break;
1253
1254		default:
1255			return( EINVAL );
1256		}
1257		bktr->dma_prog_loaded = FALSE;
1258		break;
1259
1260	case METEORGFMT:	/* get input format */
1261		*(u_int *)arg = bktr->flags & METEOR_FORM_MASK;
1262		break;
1263
1264
1265	case BT848GFMT:		/* get input format */
1266	        *(u_int *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1267		break;
1268
1269	case METEORSCOUNT:	/* (re)set error counts */
1270		counts = (struct meteor_counts *) arg;
1271		bktr->fifo_errors = counts->fifo_errors;
1272		bktr->dma_errors = counts->dma_errors;
1273		bktr->frames_captured = counts->frames_captured;
1274		bktr->even_fields_captured = counts->even_fields_captured;
1275		bktr->odd_fields_captured = counts->odd_fields_captured;
1276		break;
1277
1278	case METEORGCOUNT:	/* get error counts */
1279		counts = (struct meteor_counts *) arg;
1280		counts->fifo_errors = bktr->fifo_errors;
1281		counts->dma_errors = bktr->dma_errors;
1282		counts->frames_captured = bktr->frames_captured;
1283		counts->even_fields_captured = bktr->even_fields_captured;
1284		counts->odd_fields_captured = bktr->odd_fields_captured;
1285		break;
1286
1287	case METEORGVIDEO:
1288		video = (struct meteor_video *)arg;
1289		video->addr = bktr->video.addr;
1290		video->width = bktr->video.width;
1291		video->banksize = bktr->video.banksize;
1292		video->ramsize = bktr->video.ramsize;
1293		break;
1294
1295	case METEORSVIDEO:
1296		video = (struct meteor_video *)arg;
1297		bktr->video.addr = video->addr;
1298		bktr->video.width = video->width;
1299		bktr->video.banksize = video->banksize;
1300		bktr->video.ramsize = video->ramsize;
1301		break;
1302
1303	case METEORSFPS:
1304		set_fps(bktr, *(u_short *)arg);
1305		break;
1306
1307	case METEORGFPS:
1308		*(u_short *)arg = bktr->fps;
1309		break;
1310
1311	case METEORSHUE:	/* set hue */
1312		OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1313		break;
1314
1315	case METEORGHUE:	/* get hue */
1316		*(u_char *)arg = INB(bktr, BKTR_HUE);
1317		break;
1318
1319	case METEORSBRIG:	/* set brightness */
1320	        char_temp =    ( *(u_char *)arg & 0xff) - 128;
1321		OUTB(bktr, BKTR_BRIGHT, char_temp);
1322
1323		break;
1324
1325	case METEORGBRIG:	/* get brightness */
1326		*(u_char *)arg = INB(bktr, BKTR_BRIGHT) + 128;
1327		break;
1328
1329	case METEORSCSAT:	/* set chroma saturation */
1330		temp = (int)*(u_char *)arg;
1331
1332		OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1333		OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1334		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1335		                     & ~(BT848_E_CONTROL_SAT_U_MSB
1336					 | BT848_E_CONTROL_SAT_V_MSB));
1337		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1338		                     & ~(BT848_O_CONTROL_SAT_U_MSB |
1339					 BT848_O_CONTROL_SAT_V_MSB));
1340
1341		if ( temp & BIT_SEVEN_HIGH ) {
1342		        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1343			                     | (BT848_E_CONTROL_SAT_U_MSB
1344						| BT848_E_CONTROL_SAT_V_MSB));
1345			OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1346			                     | (BT848_O_CONTROL_SAT_U_MSB
1347						| BT848_O_CONTROL_SAT_V_MSB));
1348		}
1349		break;
1350
1351	case METEORGCSAT:	/* get chroma saturation */
1352		temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1353		if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1354			temp |= BIT_SEVEN_HIGH;
1355		*(u_char *)arg = (u_char)temp;
1356		break;
1357
1358	case METEORSCONT:	/* set contrast */
1359		temp = (int)*(u_char *)arg & 0xff;
1360		temp <<= 1;
1361		OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1362		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1363		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1364		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1365			(((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1366		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1367			(((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1368		break;
1369
1370	case METEORGCONT:	/* get contrast */
1371		temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1372		temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1373		*(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1374		break;
1375
1376	case BT848SCBUF:	/* set Clear-Buffer-on-start flag */
1377		bktr->clr_on_start = (*(int *)arg != 0);
1378		break;
1379
1380	case BT848GCBUF:	/* get Clear-Buffer-on-start flag */
1381		*(int *)arg = (int) bktr->clr_on_start;
1382		break;
1383
1384	case METEORSSIGNAL:
1385		if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
1386			return( EINVAL );
1387			break;
1388		}
1389		bktr->signal = *(int *) arg;
1390		bktr->proc = pr;
1391		break;
1392
1393	case METEORGSIGNAL:
1394		*(int *)arg = bktr->signal;
1395		break;
1396
1397	case METEORCAPTUR:
1398		temp = bktr->flags;
1399		switch (*(int *) arg) {
1400		case METEOR_CAP_SINGLE:
1401
1402			if (bktr->bigbuf==0)	/* no frame buffer allocated */
1403				return( ENOMEM );
1404			/* already capturing */
1405			if (temp & METEOR_CAP_MASK)
1406				return( EIO );
1407
1408
1409
1410			start_capture(bktr, METEOR_SINGLE);
1411
1412			/* wait for capture to complete */
1413			OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1414			OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1415			OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1416
1417			OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1418					    BT848_INT_RISCI      |
1419					    BT848_INT_VSYNC      |
1420					    BT848_INT_FMTCHG);
1421
1422			OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1423			error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1424			if (error && (error != ERESTART)) {
1425				/*  Here if we didn't get complete frame  */
1426#ifdef DIAGNOSTIC
1427				printf( "%s: ioctl: tsleep error %d %x\n",
1428					bktr_name(bktr), error,
1429					INL(bktr, BKTR_RISC_COUNT));
1430#endif
1431
1432				/* stop dma */
1433				OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1434
1435				/* disable risc, leave fifo running */
1436				OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1437			}
1438
1439			bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1440			/* FIXME: should we set bt848->int_stat ??? */
1441			break;
1442
1443		case METEOR_CAP_CONTINOUS:
1444			if (bktr->bigbuf == 0)	/* no frame buffer allocated */
1445				return (ENOMEM);
1446			/* already capturing */
1447			if (temp & METEOR_CAP_MASK)
1448			    return( EIO );
1449
1450
1451			start_capture(bktr, METEOR_CONTIN);
1452
1453			/* Clear the interrupt status register */
1454			OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1455
1456			OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1457			OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1458			OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1459
1460			OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1461					    BT848_INT_RISCI      |
1462			                    BT848_INT_VSYNC      |
1463					    BT848_INT_FMTCHG);
1464#ifdef BT848_DUMP
1465			dump_bt848( bt848 );
1466#endif
1467			break;
1468
1469		case METEOR_CAP_STOP_CONT:
1470			if (bktr->flags & METEOR_CONTIN) {
1471				/* turn off capture */
1472				OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1473				OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1474				OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1475				bktr->flags &=
1476					~(METEOR_CONTIN | METEOR_WANT_MASK);
1477
1478			}
1479		}
1480		break;
1481
1482	case METEORSETGEO:
1483		/* can't change parameters while capturing */
1484		if (bktr->flags & METEOR_CAP_MASK)
1485			return( EBUSY );
1486
1487
1488		geo = (struct meteor_geomet *) arg;
1489
1490		error = 0;
1491		/* Either even or odd, if even & odd, then these a zero */
1492		if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1493			(geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1494			printf( "%s: ioctl: Geometry odd or even only.\n",
1495				bktr_name(bktr));
1496			return( EINVAL );
1497		}
1498
1499		/* set/clear even/odd flags */
1500		if (geo->oformat & METEOR_GEO_ODD_ONLY)
1501			bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1502		else
1503			bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1504		if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1505			bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1506		else
1507			bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1508
1509		if (geo->columns <= 0) {
1510			printf(
1511			"%s: ioctl: %d: columns must be greater than zero.\n",
1512				bktr_name(bktr), geo->columns);
1513			error = EINVAL;
1514		}
1515		else if ((geo->columns & 0x3fe) != geo->columns) {
1516			printf(
1517			"%s: ioctl: %d: columns too large or not even.\n",
1518				bktr_name(bktr), geo->columns);
1519			error = EINVAL;
1520		}
1521
1522		if (geo->rows <= 0) {
1523			printf(
1524			"%s: ioctl: %d: rows must be greater than zero.\n",
1525				bktr_name(bktr), geo->rows);
1526			error = EINVAL;
1527		}
1528		else if (((geo->rows & 0x7fe) != geo->rows) ||
1529			((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1530				((geo->rows & 0x3fe) != geo->rows)) ) {
1531			printf(
1532			"%s: ioctl: %d: rows too large or not even.\n",
1533				bktr_name(bktr), geo->rows);
1534			error = EINVAL;
1535		}
1536
1537		if (geo->frames > 32) {
1538			printf("%s: ioctl: too many frames.\n",
1539			       bktr_name(bktr));
1540
1541			error = EINVAL;
1542		}
1543
1544		if (error)
1545			return( error );
1546
1547		bktr->dma_prog_loaded = FALSE;
1548		OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1549
1550		OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1551
1552		if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1553			if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1554
1555			/* meteor_mem structure for SYNC Capture */
1556			if (geo->frames > 1) temp += PAGE_SIZE;
1557
1558			temp = atop(round_page(temp));
1559			if ((int) temp > bktr->alloc_pages
1560			    && bktr->video.addr == 0) {
1561
1562/*****************************/
1563/* *** OS Dependant code *** */
1564/*****************************/
1565                                bus_dmamap_t dmamap;
1566
1567                                buf = get_bktr_mem(bktr, &dmamap,
1568                                                   temp * PAGE_SIZE);
1569                                if (buf != 0) {
1570                                        free_bktr_mem(bktr, bktr->dm_mem,
1571                                                      bktr->bigbuf);
1572                                        bktr->dm_mem = dmamap;
1573					bktr->bigbuf = buf;
1574					bktr->alloc_pages = temp;
1575					if (bootverbose)
1576						printf("%s: ioctl: "
1577						    "Allocating %d bytes\n",
1578						    bktr_name(bktr),
1579						    temp * PAGE_SIZE);
1580				} else
1581					error = ENOMEM;
1582			}
1583		}
1584
1585		if (error)
1586			return error;
1587
1588		bktr->rows = geo->rows;
1589		bktr->cols = geo->columns;
1590		bktr->frames = geo->frames;
1591
1592		/*  Pixel format (if in meteor pixfmt compatibility mode)  */
1593		if ( bktr->pixfmt_compat ) {
1594			bktr->format = METEOR_GEO_YUV_422;
1595			switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1596			case 0:			/* default */
1597			case METEOR_GEO_RGB16:
1598				    bktr->format = METEOR_GEO_RGB16;
1599				    break;
1600			case METEOR_GEO_RGB24:
1601				    bktr->format = METEOR_GEO_RGB24;
1602				    break;
1603			case METEOR_GEO_YUV_422:
1604				    bktr->format = METEOR_GEO_YUV_422;
1605                                    if (geo->oformat & METEOR_GEO_YUV_12)
1606					bktr->format = METEOR_GEO_YUV_12;
1607				    break;
1608			case METEOR_GEO_YUV_PACKED:
1609				    bktr->format = METEOR_GEO_YUV_PACKED;
1610				    break;
1611			}
1612			bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1613		}
1614
1615		if (bktr->flags & METEOR_CAP_MASK) {
1616
1617			if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1618				switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1619				case METEOR_ONLY_ODD_FIELDS:
1620					bktr->flags |= METEOR_WANT_ODD;
1621					break;
1622				case METEOR_ONLY_EVEN_FIELDS:
1623					bktr->flags |= METEOR_WANT_EVEN;
1624					break;
1625				default:
1626					bktr->flags |= METEOR_WANT_MASK;
1627					break;
1628				}
1629
1630				start_capture(bktr, METEOR_CONTIN);
1631				OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1632				OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1633				OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1634				OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1635						    BT848_INT_VSYNC      |
1636						    BT848_INT_FMTCHG);
1637			}
1638		}
1639		break;
1640	/* end of METEORSETGEO */
1641
1642	/* FIXME. The Capture Area currently has the following restrictions:
1643	GENERAL
1644	 y_offset may need to be even in interlaced modes
1645	RGB24 - Interlaced mode
1646	 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1647	 y_size must be greater than or equal to METEORSETGEO height (rows)
1648	RGB24 - Even Only (or Odd Only) mode
1649	 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1650	 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1651	YUV12 - Interlaced mode
1652	 x_size must be greater than or equal to METEORSETGEO width (cols)
1653	 y_size must be greater than or equal to METEORSETGEO height (rows)
1654	YUV12 - Even Only (or Odd Only) mode
1655	 x_size must be greater than or equal to METEORSETGEO width (cols)
1656	 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1657	*/
1658
1659	case BT848_SCAPAREA: /* set capture area of each video frame */
1660		/* can't change parameters while capturing */
1661		if (bktr->flags & METEOR_CAP_MASK)
1662			return( EBUSY );
1663
1664		cap_area = (struct bktr_capture_area *) arg;
1665		bktr->capture_area_x_offset = cap_area->x_offset;
1666		bktr->capture_area_y_offset = cap_area->y_offset;
1667		bktr->capture_area_x_size   = cap_area->x_size;
1668		bktr->capture_area_y_size   = cap_area->y_size;
1669		bktr->capture_area_enabled  = TRUE;
1670
1671		bktr->dma_prog_loaded = FALSE;
1672		break;
1673
1674	case BT848_GCAPAREA: /* get capture area of each video frame */
1675		cap_area = (struct bktr_capture_area *) arg;
1676		if (bktr->capture_area_enabled == FALSE) {
1677			cap_area->x_offset = 0;
1678			cap_area->y_offset = 0;
1679			cap_area->x_size   = format_params[
1680				bktr->format_params].scaled_hactive;
1681			cap_area->y_size   = format_params[
1682				bktr->format_params].vactive;
1683		} else {
1684			cap_area->x_offset = bktr->capture_area_x_offset;
1685			cap_area->y_offset = bktr->capture_area_y_offset;
1686			cap_area->x_size   = bktr->capture_area_x_size;
1687			cap_area->y_size   = bktr->capture_area_y_size;
1688		}
1689		break;
1690
1691	default:
1692		return bktr_common_ioctl( bktr, cmd, arg );
1693	}
1694
1695	return( 0 );
1696}
1697
1698/*
1699 * tuner ioctls
1700 */
1701int
1702tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
1703{
1704	int		tmp_int;
1705	unsigned int	temp, temp1;
1706	int		offset;
1707	int		count;
1708	u_char		*buf;
1709	u_int		par;
1710	u_char		write;
1711	int		i2c_addr;
1712	int		i2c_port;
1713	u_int		data;
1714
1715	switch ( cmd ) {
1716
1717	case REMOTE_GETKEY:
1718		/* Read the last key pressed by the Remote Control */
1719		if (bktr->remote_control == 0) return (EINVAL);
1720		remote_read(bktr, (struct bktr_remote *)arg);
1721		break;
1722
1723#if defined(TUNER_AFC)
1724	case TVTUNER_SETAFC:
1725		bktr->tuner.afc = (*(int *)arg != 0);
1726		break;
1727
1728	case TVTUNER_GETAFC:
1729		*(int *)arg = bktr->tuner.afc;
1730		/* XXX Perhaps use another bit to indicate AFC success? */
1731		break;
1732#endif /* TUNER_AFC */
1733
1734	case TVTUNER_SETCHNL:
1735		temp_mute( bktr, TRUE );
1736		tmp_int = tv_channel( bktr, (int)*(unsigned int *)arg );
1737		if ( tmp_int < 0 ) {
1738			temp_mute( bktr, FALSE );
1739			return( EINVAL );
1740		}
1741		*(unsigned int *)arg = tmp_int;
1742
1743		/* after every channel change, we must restart the MSP34xx */
1744		/* audio chip to reselect NICAM STEREO or MONO audio */
1745		if ( bktr->card.msp3400c )
1746		  msp_autodetect( bktr );
1747
1748		/* after every channel change, we must restart the DPL35xx */
1749		if ( bktr->card.dpl3518a )
1750		  dpl_autodetect( bktr );
1751
1752		temp_mute( bktr, FALSE );
1753		break;
1754
1755	case TVTUNER_GETCHNL:
1756		*(unsigned int *)arg = bktr->tuner.channel;
1757		break;
1758
1759	case TVTUNER_SETTYPE:
1760		temp = *(unsigned int *)arg;
1761		if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1762			return( EINVAL );
1763		bktr->tuner.chnlset = temp;
1764		break;
1765
1766	case TVTUNER_GETTYPE:
1767		*(unsigned int *)arg = bktr->tuner.chnlset;
1768		break;
1769
1770	case TVTUNER_GETSTATUS:
1771		temp = get_tuner_status( bktr );
1772		*(unsigned int *)arg = temp & 0xff;
1773		break;
1774
1775	case TVTUNER_SETFREQ:
1776		temp_mute( bktr, TRUE );
1777		tmp_int = tv_freq( bktr, (int)*(unsigned int *)arg, TV_FREQUENCY);
1778		temp_mute( bktr, FALSE );
1779		if ( tmp_int < 0 ) {
1780			temp_mute( bktr, FALSE );
1781			return( EINVAL );
1782		}
1783		*(unsigned int *)arg = tmp_int;
1784
1785		/* after every channel change, we must restart the MSP34xx */
1786		/* audio chip to reselect NICAM STEREO or MONO audio */
1787		if ( bktr->card.msp3400c )
1788		  msp_autodetect( bktr );
1789
1790		/* after every channel change, we must restart the DPL35xx */
1791		if ( bktr->card.dpl3518a )
1792		  dpl_autodetect( bktr );
1793
1794		temp_mute( bktr, FALSE );
1795		break;
1796
1797	case TVTUNER_GETFREQ:
1798		*(unsigned int *)arg = bktr->tuner.frequency;
1799		break;
1800
1801	case TVTUNER_GETCHNLSET:
1802		return tuner_getchnlset((struct bktr_chnlset *)arg);
1803
1804	case BT848_SAUDIO:	/* set audio channel */
1805		if ( set_audio( bktr, *(int *)arg ) < 0 )
1806			return( EIO );
1807		break;
1808
1809	/* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1810	case BT848_SHUE:	/* set hue */
1811		OUTB(bktr, BKTR_HUE, (u_char)(*(int *)arg & 0xff));
1812		break;
1813
1814	case BT848_GHUE:	/* get hue */
1815		*(int *)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1816		break;
1817
1818	/* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1819	case BT848_SBRIG:	/* set brightness */
1820		OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1821		break;
1822
1823	case BT848_GBRIG:	/* get brightness */
1824		*(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1825		break;
1826
1827	/*  */
1828	case BT848_SCSAT:	/* set chroma saturation */
1829		tmp_int = *(int *)arg;
1830
1831		temp = INB(bktr, BKTR_E_CONTROL);
1832		temp1 = INB(bktr, BKTR_O_CONTROL);
1833		if ( tmp_int & BIT_EIGHT_HIGH ) {
1834			temp |= (BT848_E_CONTROL_SAT_U_MSB |
1835				 BT848_E_CONTROL_SAT_V_MSB);
1836			temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1837				  BT848_O_CONTROL_SAT_V_MSB);
1838		}
1839		else {
1840			temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1841				  BT848_E_CONTROL_SAT_V_MSB);
1842			temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1843				   BT848_O_CONTROL_SAT_V_MSB);
1844		}
1845
1846		OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1847		OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1848		OUTB(bktr, BKTR_E_CONTROL, temp);
1849		OUTB(bktr, BKTR_O_CONTROL, temp1);
1850		break;
1851
1852	case BT848_GCSAT:	/* get chroma saturation */
1853		tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1854		if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1855			tmp_int |= BIT_EIGHT_HIGH;
1856		*(int *)arg = tmp_int;
1857		break;
1858
1859	/*  */
1860	case BT848_SVSAT:	/* set chroma V saturation */
1861		tmp_int = *(int *)arg;
1862
1863		temp = INB(bktr, BKTR_E_CONTROL);
1864		temp1 = INB(bktr, BKTR_O_CONTROL);
1865		if ( tmp_int & BIT_EIGHT_HIGH) {
1866			temp |= BT848_E_CONTROL_SAT_V_MSB;
1867			temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1868		}
1869		else {
1870			temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1871			temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1872		}
1873
1874		OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1875		OUTB(bktr, BKTR_E_CONTROL, temp);
1876		OUTB(bktr, BKTR_O_CONTROL, temp1);
1877		break;
1878
1879	case BT848_GVSAT:	/* get chroma V saturation */
1880		tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1881		if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1882			tmp_int |= BIT_EIGHT_HIGH;
1883		*(int *)arg = tmp_int;
1884		break;
1885
1886	/*  */
1887	case BT848_SUSAT:	/* set chroma U saturation */
1888		tmp_int = *(int *)arg;
1889
1890		temp = INB(bktr, BKTR_E_CONTROL);
1891		temp1 = INB(bktr, BKTR_O_CONTROL);
1892		if ( tmp_int & BIT_EIGHT_HIGH ) {
1893			temp |= BT848_E_CONTROL_SAT_U_MSB;
1894			temp1 |= BT848_O_CONTROL_SAT_U_MSB;
1895		}
1896		else {
1897			temp &= ~BT848_E_CONTROL_SAT_U_MSB;
1898			temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
1899		}
1900
1901		OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1902		OUTB(bktr, BKTR_E_CONTROL, temp);
1903		OUTB(bktr, BKTR_O_CONTROL, temp1);
1904		break;
1905
1906	case BT848_GUSAT:	/* get chroma U saturation */
1907		tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
1908		if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
1909			tmp_int |= BIT_EIGHT_HIGH;
1910		*(int *)arg = tmp_int;
1911		break;
1912
1913/* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
1914
1915	case BT848_SLNOTCH:	/* set luma notch */
1916		tmp_int = (*(int *)arg & 0x7) << 5 ;
1917		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
1918		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
1919		OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
1920		OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
1921		break;
1922
1923	case BT848_GLNOTCH:	/* get luma notch */
1924		*(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
1925		break;
1926
1927
1928	/*  */
1929	case BT848_SCONT:	/* set contrast */
1930		tmp_int = *(int *)arg;
1931
1932		temp = INB(bktr, BKTR_E_CONTROL);
1933		temp1 = INB(bktr, BKTR_O_CONTROL);
1934		if ( tmp_int & BIT_EIGHT_HIGH ) {
1935			temp |= BT848_E_CONTROL_CON_MSB;
1936			temp1 |= BT848_O_CONTROL_CON_MSB;
1937		}
1938		else {
1939			temp &= ~BT848_E_CONTROL_CON_MSB;
1940			temp1 &= ~BT848_O_CONTROL_CON_MSB;
1941		}
1942
1943		OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
1944		OUTB(bktr, BKTR_E_CONTROL, temp);
1945		OUTB(bktr, BKTR_O_CONTROL, temp1);
1946		break;
1947
1948	case BT848_GCONT:	/* get contrast */
1949		tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1950		if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
1951			tmp_int |= BIT_EIGHT_HIGH;
1952		*(int *)arg = tmp_int;
1953		break;
1954
1955		/*  FIXME:  SCBARS and CCBARS require a valid int *        */
1956		/*    argument to succeed, but its not used; consider      */
1957		/*    using the arg to store the on/off state so           */
1958		/*    there's only one ioctl() needed to turn cbars on/off */
1959	case BT848_SCBARS:	/* set colorbar output */
1960		OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
1961		break;
1962
1963	case BT848_CCBARS:	/* clear colorbar output */
1964		OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
1965		break;
1966
1967	case BT848_GAUDIO:	/* get audio channel */
1968		temp = bktr->audio_mux_select;
1969		if ( bktr->audio_mute_state == TRUE )
1970			temp |= AUDIO_MUTE;
1971		*(int *)arg = temp;
1972		break;
1973
1974	case BT848_SBTSC:	/* set audio channel */
1975		if ( set_BTSC( bktr, *(int *)arg ) < 0 )
1976			return( EIO );
1977		break;
1978
1979	case BT848_WEEPROM:	/* write eeprom */
1980		offset = (((struct eeProm *)arg)->offset);
1981		count = (((struct eeProm *)arg)->count);
1982		buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
1983		if ( writeEEProm( bktr, offset, count, buf ) < 0 )
1984			return( EIO );
1985		break;
1986
1987	case BT848_REEPROM:	/* read eeprom */
1988		offset = (((struct eeProm *)arg)->offset);
1989		count = (((struct eeProm *)arg)->count);
1990		buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
1991		if ( readEEProm( bktr, offset, count, buf ) < 0 )
1992			return( EIO );
1993		break;
1994
1995	case BT848_SIGNATURE:
1996		offset = (((struct eeProm *)arg)->offset);
1997		count = (((struct eeProm *)arg)->count);
1998		buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
1999		if ( signCard( bktr, offset, count, buf ) < 0 )
2000			return( EIO );
2001		break;
2002
2003        /* Ioctl's for direct gpio access */
2004#ifdef BKTR_GPIO_ACCESS
2005        case BT848_GPIO_GET_EN:
2006                *(int *)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2007                break;
2008
2009        case BT848_GPIO_SET_EN:
2010                OUTL(bktr, BKTR_GPIO_OUT_EN, *(int *)arg);
2011                break;
2012
2013        case BT848_GPIO_GET_DATA:
2014                *(int *)arg = INL(bktr, BKTR_GPIO_DATA);
2015                break;
2016
2017        case BT848_GPIO_SET_DATA:
2018                OUTL(bktr, BKTR_GPIO_DATA, *(int *)arg);
2019                break;
2020#endif /* BKTR_GPIO_ACCESS */
2021
2022	/* Ioctl's for running the tuner device in radio mode		*/
2023
2024	case RADIO_GETMODE:
2025            *(unsigned char *)arg = bktr->tuner.radio_mode;
2026	    break;
2027
2028	case RADIO_SETMODE:
2029            bktr->tuner.radio_mode = *(unsigned char *)arg;
2030            break;
2031
2032	case RADIO_GETFREQ:
2033            *(unsigned long *)arg = bktr->tuner.frequency;
2034            break;
2035
2036	case RADIO_SETFREQ:
2037	    /* The argument to this ioctl is NOT freq*16. It is
2038	    ** freq*100.
2039	    */
2040
2041            temp=(int)*(unsigned long *)arg;
2042
2043#ifdef BKTR_RADIO_DEBUG
2044	    printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2045		   (int)*(unsigned long *)arg, temp);
2046#endif
2047
2048#ifndef BKTR_RADIO_NOFREQCHECK
2049	    /* According to the spec. sheet the band: 87.5MHz-108MHz	*/
2050	    /* is supported.						*/
2051	    if(temp<8750 || temp>10800) {
2052	      printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2053	      return(EINVAL);
2054	      }
2055#endif
2056	    temp_mute( bktr, TRUE );
2057	    tmp_int = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2058	    temp_mute( bktr, FALSE );
2059#ifdef BKTR_RADIO_DEBUG
2060  if(tmp_int)
2061    printf("%s: tv_freq returned: %d\n", bktr_name(bktr), tmp_int);
2062#endif
2063	    if ( tmp_int < 0 )
2064		    return( EINVAL );
2065	    *(unsigned long *)arg = tmp_int;
2066	    break;
2067
2068	/* Luigi's I2CWR ioctl */
2069	case BT848_I2CWR:
2070		par = *(u_int *)arg;
2071		write = (par >> 24) & 0xff ;
2072		i2c_addr = (par >> 16) & 0xff ;
2073		i2c_port = (par >> 8) & 0xff ;
2074		data = (par) & 0xff ;
2075
2076		if (write) {
2077			i2cWrite( bktr, i2c_addr, i2c_port, data);
2078		} else {
2079			data = i2cRead( bktr, i2c_addr);
2080		}
2081		*(u_int *)arg = (par & 0xffffff00) | ( data & 0xff );
2082		break;
2083
2084
2085#ifdef BT848_MSP_READ
2086	/* I2C ioctls to allow userland access to the MSP chip */
2087	case BT848_MSP_READ:
2088		{
2089		struct bktr_msp_control *msp;
2090		msp = (struct bktr_msp_control *) arg;
2091		msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2092		                         msp->function, msp->address);
2093		break;
2094		}
2095
2096	case BT848_MSP_WRITE:
2097		{
2098		struct bktr_msp_control *msp;
2099		msp = (struct bktr_msp_control *) arg;
2100		msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2101		             msp->address, msp->data );
2102		break;
2103		}
2104
2105	case BT848_MSP_RESET:
2106		msp_dpl_reset(bktr, bktr->msp_addr);
2107		break;
2108#endif
2109
2110	default:
2111		return bktr_common_ioctl( bktr, cmd, arg );
2112	}
2113
2114	return( 0 );
2115}
2116
2117
2118/*
2119 * common ioctls
2120 */
2121int
2122bktr_common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2123{
2124	int                           pixfmt;
2125	struct meteor_pixfmt          *pf_pub;
2126
2127#if defined( STATUS_SUM )
2128	unsigned int                  temp;
2129#endif
2130
2131	switch (cmd) {
2132
2133	case METEORSINPUT:	/* set input device */
2134		/*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2135		/* On the original bt848 boards, */
2136		/*   Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2137		/* On the Hauppauge bt878 boards, */
2138		/*   Tuner is MUX0, RCA is MUX3 */
2139		/* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2140		/* stick with this system in our Meteor Emulation */
2141
2142		switch(*(unsigned int *)arg & METEOR_DEV_MASK) {
2143
2144		/* this is the RCA video input */
2145		case 0:		/* default */
2146		case METEOR_INPUT_DEV0:
2147		  /* METEOR_INPUT_DEV_RCA: */
2148		        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2149			  | METEOR_DEV0;
2150			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2151			                 & ~BT848_IFORM_MUXSEL);
2152
2153			/* work around for new Hauppauge 878 cards */
2154			if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2155				(bktr->id==BROOKTREE_878 ||
2156				 bktr->id==BROOKTREE_879) )
2157				OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2158			else
2159				OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2160
2161			OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2162			OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2163			set_audio( bktr, AUDIO_EXTERN );
2164			break;
2165
2166		/* this is the tuner input */
2167		case METEOR_INPUT_DEV1:
2168			bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2169				| METEOR_DEV1;
2170			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2171			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2172			OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2173			OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2174			set_audio( bktr, AUDIO_TUNER );
2175			break;
2176
2177		/* this is the S-VHS input, but with a composite camera */
2178		case METEOR_INPUT_DEV2:
2179			bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2180				| METEOR_DEV2;
2181			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2182			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2183			OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2184			OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2185			set_audio( bktr, AUDIO_EXTERN );
2186			break;
2187
2188		/* this is the S-VHS input */
2189		case METEOR_INPUT_DEV_SVIDEO:
2190			bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2191				| METEOR_DEV_SVIDEO;
2192			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2193			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2194			OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2195			OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2196			set_audio( bktr, AUDIO_EXTERN );
2197			break;
2198
2199		case METEOR_INPUT_DEV3:
2200		  if ((bktr->id == BROOKTREE_848A) ||
2201		      (bktr->id == BROOKTREE_849A) ||
2202		      (bktr->id == BROOKTREE_878) ||
2203		      (bktr->id == BROOKTREE_879) ) {
2204			bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2205				| METEOR_DEV3;
2206			OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2207
2208			/* work around for new Hauppauge 878 cards */
2209			if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2210				(bktr->id==BROOKTREE_878 ||
2211				 bktr->id==BROOKTREE_879) )
2212				OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2213			else
2214				OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2215
2216			OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2217			OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2218			set_audio( bktr, AUDIO_EXTERN );
2219
2220			break;
2221		  }
2222
2223		default:
2224			return( EINVAL );
2225		}
2226		break;
2227
2228	case METEORGINPUT:	/* get input device */
2229		*(u_int *)arg = bktr->flags & METEOR_DEV_MASK;
2230		break;
2231
2232	case METEORSACTPIXFMT:
2233		if (( *(int *)arg < 0 ) ||
2234		    ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2235			return( EINVAL );
2236
2237		bktr->pixfmt          = *(int *)arg;
2238		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2239		     | pixfmt_swap_flags( bktr->pixfmt ));
2240		bktr->pixfmt_compat   = FALSE;
2241		break;
2242
2243	case METEORGACTPIXFMT:
2244		*(int *)arg = bktr->pixfmt;
2245		break;
2246
2247	case METEORGSUPPIXFMT :
2248		pf_pub = (struct meteor_pixfmt *)arg;
2249		pixfmt = pf_pub->index;
2250
2251		if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2252			return( EINVAL );
2253
2254		memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2255			sizeof( *pf_pub ) );
2256
2257		/*  Patch in our format index  */
2258		pf_pub->index       = pixfmt;
2259		break;
2260
2261#if defined( STATUS_SUM )
2262	case BT848_GSTATUS:	/* reap status */
2263		{
2264                DECLARE_INTR_MASK(s);
2265		DISABLE_INTR(s);
2266		temp = status_sum;
2267		status_sum = 0;
2268		ENABLE_INTR(s);
2269		*(u_int *)arg = temp;
2270		break;
2271		}
2272#endif /* STATUS_SUM */
2273
2274	default:
2275		return( ENOTTY );
2276	}
2277
2278	return( 0 );
2279}
2280
2281
2282
2283
2284/******************************************************************************
2285 * bt848 RISC programming routines:
2286 */
2287
2288
2289/*
2290 *
2291 */
2292#ifdef BT848_DEBUG
2293static int
2294dump_bt848( bktr_ptr_t bktr )
2295{
2296	int	r[60]={
2297			   4,    8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2298			0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2299			0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2300			0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2301			0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2302			0,	 0,    0,    0
2303		   };
2304	int	i;
2305
2306	for (i = 0; i < 40; i+=4) {
2307		printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2308		       bktr_name(bktr),
2309		       r[i], INL(bktr, r[i]),
2310		       r[i+1], INL(bktr, r[i+1]),
2311		       r[i+2], INL(bktr, r[i+2]),
2312		       r[i+3], INL(bktr, r[i+3]));
2313	}
2314
2315	printf("%s: INT STAT %x \n", bktr_name(bktr),
2316	       INL(bktr, BKTR_INT_STAT));
2317	printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2318	       INL(bktr, BKTR_INT_MASK));
2319	printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2320	       INW(bktr, BKTR_GPIO_DMA_CTL));
2321
2322	return( 0 );
2323}
2324
2325#endif
2326
2327/*
2328 * build write instruction
2329 */
2330#define BKTR_FM1      0x6	/* packed data to follow */
2331#define BKTR_FM3      0xe	/* planar data to follow */
2332#define BKTR_VRE      0x4	/* Marks the end of the even field */
2333#define BKTR_VRO      0xC	/* Marks the end of the odd field */
2334#define BKTR_PXV      0x0	/* valid word (never used) */
2335#define BKTR_EOL      0x1	/* last dword, 4 bytes */
2336#define BKTR_SOL      0x2	/* first dword */
2337
2338#define OP_WRITE      (0x1 << 28)
2339#define OP_SKIP       (0x2 << 28)
2340#define OP_WRITEC     (0x5 << 28)
2341#define OP_JUMP	      (0x7 << 28)
2342#define OP_SYNC	      (0x8 << 28)
2343#define OP_WRITE123   (0x9 << 28)
2344#define OP_WRITES123  (0xb << 28)
2345#define OP_SOL	      (1 << 27)		/* first instr for scanline */
2346#define OP_EOL	      (1 << 26)
2347
2348#define BKTR_RESYNC   (1 << 15)
2349#define BKTR_GEN_IRQ  (1 << 24)
2350
2351/*
2352 * The RISC status bits can be set/cleared in the RISC programs
2353 * and tested in the Interrupt Handler
2354 */
2355#define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2356#define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2357#define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2358#define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2359
2360#define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2361#define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2362#define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2363#define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2364
2365#define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2366#define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2367#define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2368#define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2369
2370static bool_t
2371notclipped (bktr_reg_t * bktr, int x, int width) {
2372    int i;
2373    bktr_clip_t * clip_node;
2374    bktr->clip_start = -1;
2375    bktr->last_y = 0;
2376    bktr->y = 0;
2377    bktr->y2 = width;
2378    bktr->line_length = width;
2379    bktr->yclip = -1;
2380    bktr->yclip2 = -1;
2381    bktr->current_col = 0;
2382
2383    if (bktr->max_clip_node == 0 ) return TRUE;
2384    clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2385
2386
2387    for (i = 0; i < bktr->max_clip_node; i++ ) {
2388	clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2389	if (x >= clip_node->x_min && x <= clip_node->x_max  ) {
2390	    bktr->clip_start = i;
2391	    return FALSE;
2392	}
2393    }
2394
2395    return TRUE;
2396}
2397
2398static bool_t
2399getline(bktr_reg_t *bktr, int x ) {
2400    int i, j;
2401    bktr_clip_t * clip_node ;
2402
2403    if (bktr->line_length == 0 ||
2404	bktr->current_col >= bktr->line_length) return FALSE;
2405
2406    bktr->y = min(bktr->last_y, bktr->line_length);
2407    bktr->y2 = bktr->line_length;
2408
2409    bktr->yclip = bktr->yclip2 = -1;
2410    for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2411	clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2412	if (x >= clip_node->x_min && x <= clip_node->x_max) {
2413	    if (bktr->last_y <= clip_node->y_min) {
2414		bktr->y =      min(bktr->last_y, bktr->line_length);
2415		bktr->y2 =     min(clip_node->y_min, bktr->line_length);
2416		bktr->yclip =  min(clip_node->y_min, bktr->line_length);
2417		bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2418		bktr->last_y = bktr->yclip2;
2419		bktr->clip_start = i;
2420
2421		for (j = i+1; j  < bktr->max_clip_node; j++ ) {
2422		    clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2423		    if (x >= clip_node->x_min && x <= clip_node->x_max) {
2424			if (bktr->last_y >= clip_node->y_min) {
2425			    bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2426			    bktr->last_y = bktr->yclip2;
2427			    bktr->clip_start = j;
2428			}
2429		    } else break  ;
2430		}
2431		return TRUE;
2432	    }
2433	}
2434    }
2435
2436    if (bktr->current_col <= bktr->line_length) {
2437	bktr->current_col = bktr->line_length;
2438	return TRUE;
2439    }
2440    return FALSE;
2441}
2442
2443static bool_t
2444split(bktr_reg_t *bktr, u_int **dma_prog, int width, u_int operation,
2445    int pixel_width, u_int *target_buffer, int cols)
2446{
2447
2448 u_int flag, flag2;
2449 const struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2450 u_int  skip, start_skip;
2451
2452  /*  For RGB24, we need to align the component in FIFO Byte Lane 0         */
2453  /*    to the 1st byte in the mem dword containing our start addr.         */
2454  /*    BTW, we know this pixfmt's 1st byte is Blue; thus the start addr    */
2455  /*     must be Blue.                                                      */
2456  start_skip = 0;
2457  if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2458	  switch ((*target_buffer) % 4) {
2459	  case 2 : start_skip = 4 ; break;
2460	  case 1 : start_skip = 8 ; break;
2461	  }
2462
2463 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2464     if (  width == cols) {
2465	 flag = OP_SOL | OP_EOL;
2466       } else if (bktr->current_col == 0 ) {
2467	    flag  = OP_SOL;
2468       } else if (bktr->current_col == cols) {
2469	    flag = OP_EOL;
2470       } else flag = 0;
2471
2472     skip = 0;
2473     if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2474	     *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2475	     flag &= ~OP_SOL;
2476	     skip = start_skip;
2477     }
2478
2479     *(*dma_prog)++ = htole32(operation | flag  | (width * pixel_width - skip));
2480     if (operation != OP_SKIP )
2481	 *(*dma_prog)++ = htole32(*target_buffer);
2482
2483     *target_buffer += width * pixel_width;
2484     bktr->current_col += width;
2485
2486 } else {
2487
2488	if (bktr->current_col == 0 && width == cols) {
2489	    flag = OP_SOL ;
2490	    flag2 = OP_EOL;
2491        } else if (bktr->current_col == 0 ) {
2492	    flag = OP_SOL;
2493	    flag2 = 0;
2494	} else if (bktr->current_col >= cols)  {
2495	    flag =  0;
2496	    flag2 = OP_EOL;
2497	} else {
2498	    flag =  0;
2499	    flag2 = 0;
2500	}
2501
2502	skip = 0;
2503	if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2504		*(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2505		flag &= ~OP_SOL;
2506		skip = start_skip;
2507	}
2508
2509	*(*dma_prog)++ = htole32(operation | flag |
2510	      (width * pixel_width / 2 - skip));
2511	if (operation != OP_SKIP )
2512	      *(*dma_prog)++ = htole32(*target_buffer);
2513	*target_buffer += width * pixel_width / 2;
2514
2515	if ( operation == OP_WRITE )
2516		operation = OP_WRITEC;
2517	*(*dma_prog)++ = htole32(operation | flag2 |
2518	    (width * pixel_width / 2));
2519	*target_buffer += width * pixel_width / 2;
2520	bktr->current_col += width;
2521
2522    }
2523
2524    return TRUE;
2525}
2526
2527
2528/*
2529 * Generate the RISC instructions to capture both VBI and video images
2530 */
2531static void
2532rgb_vbi_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2533{
2534	int		i;
2535	u_int		target_buffer, buffer, target, width;
2536	u_int		pitch;
2537	u_int		*dma_prog;	/* DMA prog is an array of
2538					   32 bit RISC instructions */
2539	u_int		*loop_point;
2540        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2541	u_int		Bpp = pf_int->public.Bpp;
2542	unsigned int	vbisamples;     /* VBI samples per line */
2543	unsigned int	vbilines;       /* VBI lines per field */
2544	unsigned int	num_dwords;     /* DWORDS per line */
2545
2546	vbisamples = format_params[bktr->format_params].vbi_num_samples;
2547	vbilines   = format_params[bktr->format_params].vbi_num_lines;
2548	num_dwords = vbisamples/4;
2549
2550	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2551	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2552	OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2553	OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay    */
2554							    /* no ext frame */
2555
2556	OUTB(bktr, BKTR_OFORM, 0x00);
2557
2558	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2559	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2560	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2561	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2562
2563	/* disable gamma correction removal */
2564	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2565
2566	if (cols > 385 ) {
2567	    OUTB(bktr, BKTR_E_VTC, 0);
2568	    OUTB(bktr, BKTR_O_VTC, 0);
2569	} else {
2570	    OUTB(bktr, BKTR_E_VTC, 1);
2571	    OUTB(bktr, BKTR_O_VTC, 1);
2572	}
2573	bktr->capcontrol = 3 << 2 |  3;
2574
2575	dma_prog = (u_int *) bktr->dma_prog;
2576
2577	/* Construct Write */
2578
2579	if (bktr->video.addr) {
2580		target_buffer = bktr->video.addr;
2581		pitch = bktr->video.width;
2582	}
2583	else {
2584		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
2585		pitch = cols*Bpp;
2586	}
2587
2588	buffer = target_buffer;
2589
2590	/* Wait for the VRE sync marking the end of the Even and
2591	 * the start of the Odd field. Resync here.
2592	 */
2593	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC |BKTR_VRE);
2594	*dma_prog++ = htole32(0);
2595
2596	loop_point = dma_prog;
2597
2598	/* store the VBI data */
2599	/* look for sync with packed data */
2600	*dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2601	*dma_prog++ = htole32(0);
2602	for(i = 0; i < vbilines; i++) {
2603		*dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2604		*dma_prog++ = htole32(bktr->dm_vbidata->dm_segs->ds_addr +
2605					(i * VBI_LINE_SIZE));
2606	}
2607
2608	if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2609		/* store the Odd field video image */
2610		/* look for sync with packed data */
2611		*dma_prog++ = htole32(OP_SYNC  | BKTR_FM1);
2612		*dma_prog++ = htole32(0);  /* NULL WORD */
2613		width = cols;
2614		for (i = 0; i < (rows/interlace); i++) {
2615		    target = target_buffer;
2616		    if ( notclipped(bktr, i, width)) {
2617			split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2618			      Bpp, &target, cols);
2619
2620		    } else {
2621			while(getline(bktr, i)) {
2622			    if (bktr->y != bktr->y2 ) {
2623				split(bktr, &dma_prog, bktr->y2 - bktr->y,
2624				    OP_WRITE, Bpp, &target, cols);
2625			    }
2626			    if (bktr->yclip != bktr->yclip2 ) {
2627				split(bktr, &dma_prog, bktr->yclip2 -
2628				    bktr->yclip, OP_SKIP, Bpp, &target, cols);
2629			    }
2630			}
2631		    }
2632
2633		    target_buffer += interlace * pitch;
2634		}
2635
2636	} /* end if */
2637
2638	/* Grab the Even field */
2639	/* Look for the VRO, end of Odd field, marker */
2640	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2641	*dma_prog++ = htole32(0);  /* NULL WORD */
2642
2643	/* store the VBI data */
2644	/* look for sync with packed data */
2645	*dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2646	*dma_prog++ = htole32(0);
2647	for(i = 0; i < vbilines; i++) {
2648		*dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2649		*dma_prog++ = htole32(bktr->dm_vbidata->dm_segs->ds_addr +
2650				((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2651	}
2652
2653	/* store the video image */
2654	if (i_flag == 1) /*Even Only*/
2655	        target_buffer = buffer;
2656	if (i_flag == 3) /*interlaced*/
2657	        target_buffer = buffer+pitch;
2658
2659
2660	if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2661		/* look for sync with packed data */
2662		*dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2663		*dma_prog++ = htole32(0);  /* NULL WORD */
2664		width = cols;
2665		for (i = 0; i < (rows/interlace); i++) {
2666		    target = target_buffer;
2667		    if ( notclipped(bktr, i, width)) {
2668			split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2669			      Bpp, &target,  cols);
2670		    } else {
2671			while(getline(bktr, i)) {
2672			    if (bktr->y != bktr->y2 ) {
2673				split(bktr, &dma_prog, bktr->y2 - bktr->y,
2674				    OP_WRITE, Bpp, &target, cols);
2675			    }
2676			    if (bktr->yclip != bktr->yclip2 ) {
2677				split(bktr, &dma_prog, bktr->yclip2 -
2678				    bktr->yclip, OP_SKIP, Bpp, &target, cols);
2679			    }
2680			}
2681		    }
2682
2683		    target_buffer += interlace * pitch;
2684		}
2685	}
2686
2687	/* Look for end of 'Even Field' */
2688	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2689	*dma_prog++ = htole32(0);  /* NULL WORD */
2690
2691	*dma_prog++ = htole32(OP_JUMP);
2692	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr +
2693	    ((char *)loop_point - (char *)bktr->dma_prog));
2694	*dma_prog++ = htole32(0);  /* NULL WORD */
2695
2696}
2697
2698static void
2699rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2700{
2701	int		i;
2702	u_int		target_buffer, buffer, target,width;
2703	u_int		pitch;
2704	u_int		*dma_prog;
2705        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2706	u_int                   Bpp = pf_int->public.Bpp;
2707
2708	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2709	OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2710	OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2711	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2712
2713	OUTB(bktr, BKTR_OFORM, 0x00);
2714
2715	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2716	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2717	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2718	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2719
2720	/* disable gamma correction removal */
2721	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2722
2723	if (cols > 385 ) {
2724	    OUTB(bktr, BKTR_E_VTC, 0);
2725	    OUTB(bktr, BKTR_O_VTC, 0);
2726	} else {
2727	    OUTB(bktr, BKTR_E_VTC, 1);
2728	    OUTB(bktr, BKTR_O_VTC, 1);
2729	}
2730	bktr->capcontrol = 3 << 2 |  3;
2731
2732	dma_prog = (u_int *)bktr->dma_prog;
2733
2734	/* Construct Write */
2735
2736	if (bktr->video.addr) {
2737		target_buffer = (u_int) bktr->video.addr;
2738		pitch = bktr->video.width;
2739	}
2740	else {
2741		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
2742		pitch = cols*Bpp;
2743	}
2744
2745	buffer = target_buffer;
2746
2747	/* construct sync : for video packet format */
2748	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2749
2750	/* sync, mode indicator packed data */
2751	*dma_prog++ = htole32(0);  /* NULL WORD */
2752	width = cols;
2753	for (i = 0; i < (rows/interlace); i++) {
2754	    target = target_buffer;
2755	    if ( notclipped(bktr, i, width)) {
2756		split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2757		    Bpp, &target,  cols);
2758
2759	    } else {
2760		while(getline(bktr, i)) {
2761		    if (bktr->y != bktr->y2 ) {
2762			split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2763			      Bpp, &target, cols);
2764		    }
2765		    if (bktr->yclip != bktr->yclip2 ) {
2766			split(bktr, &dma_prog, bktr->yclip2 - bktr->yclip,
2767			      OP_SKIP, Bpp, &target,  cols);
2768		    }
2769		}
2770	    }
2771
2772	    target_buffer += interlace * pitch;
2773	}
2774
2775	switch (i_flag) {
2776	case 1:
2777		/* sync vre */
2778		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
2779		*dma_prog++ = htole32(0);  /* NULL WORD */
2780
2781		*dma_prog++ = htole32(OP_JUMP);
2782		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2783		return;
2784
2785	case 2:
2786		/* sync vro */
2787		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
2788		*dma_prog++ = htole32(0);  /* NULL WORD */
2789
2790		*dma_prog++ = htole32(OP_JUMP);
2791		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2792		return;
2793
2794	case 3:
2795		/* sync vro */
2796		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2797		*dma_prog++ = htole32(0);  /* NULL WORD */
2798
2799		*dma_prog++ = htole32(OP_JUMP);
2800		*dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
2801		break;
2802	}
2803
2804	if (interlace == 2) {
2805
2806	        target_buffer = buffer + pitch;
2807
2808		dma_prog = (u_int *) bktr->odd_dma_prog;
2809
2810		/* sync vre IRQ bit */
2811		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2812		*dma_prog++ = htole32(0);  /* NULL WORD */
2813                width = cols;
2814		for (i = 0; i < (rows/interlace); i++) {
2815		    target = target_buffer;
2816		    if ( notclipped(bktr, i, width)) {
2817			split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2818			    Bpp, &target,  cols);
2819		    } else {
2820			while(getline(bktr, i)) {
2821			    if (bktr->y != bktr->y2 ) {
2822				split(bktr, &dma_prog, bktr->y2 - bktr->y,
2823				    OP_WRITE, Bpp, &target, cols);
2824			    }
2825			    if (bktr->yclip != bktr->yclip2 ) {
2826				split(bktr, &dma_prog, bktr->yclip2 -
2827				    bktr->yclip, OP_SKIP, Bpp, &target, cols);
2828			    }
2829			}
2830		    }
2831
2832		    target_buffer += interlace * pitch;
2833		}
2834	}
2835
2836	/* sync vre IRQ bit */
2837	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2838	*dma_prog++ = htole32(0);  /* NULL WORD */
2839	*dma_prog++ = htole32(OP_JUMP);
2840	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2841	*dma_prog++ = htole32(0);  /* NULL WORD */
2842}
2843
2844
2845/*
2846 *
2847 */
2848static void
2849yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2850	      int cols, int rows, int interlace )
2851{
2852	int			i;
2853	volatile unsigned int	inst;
2854	volatile unsigned int	inst3;
2855	volatile u_int		target_buffer, buffer;
2856	volatile u_int		*dma_prog;
2857        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2858	int			b;
2859
2860	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2861
2862	OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
2863	OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2864
2865	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
2866	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2867
2868	bktr->capcontrol =   1 << 6 | 1 << 4 | 1 << 2 | 3;
2869	bktr->capcontrol = 3 << 2 |  3;
2870
2871	dma_prog = (u_int *) bktr->dma_prog;
2872
2873	/* Construct Write */
2874
2875	/* write , sol, eol */
2876	inst = OP_WRITE	 | OP_SOL | (cols);
2877	/* write , sol, eol */
2878	inst3 = OP_WRITE | OP_EOL | (cols);
2879
2880	if (bktr->video.addr)
2881		target_buffer = bktr->video.addr;
2882	else
2883		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
2884
2885	buffer = target_buffer;
2886
2887	/* contruct sync : for video packet format */
2888	/* sync, mode indicator packed data */
2889	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2890	*dma_prog++ = htole32(0);  /* NULL WORD */
2891
2892	b = cols;
2893
2894	for (i = 0; i < (rows/interlace); i++) {
2895		*dma_prog++ = htole32(inst);
2896		*dma_prog++ = htole32(target_buffer);
2897		*dma_prog++ = htole32(inst3);
2898		*dma_prog++ = htole32(target_buffer + b);
2899		target_buffer += interlace*(cols * 2);
2900	}
2901
2902	switch (i_flag) {
2903	case 1:
2904		/* sync vre */
2905		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
2906		*dma_prog++ = htole32(0);  /* NULL WORD */
2907		*dma_prog++ = htole32(OP_JUMP);
2908		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2909		return;
2910
2911	case 2:
2912		/* sync vro */
2913		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
2914		*dma_prog++ = htole32(0);  /* NULL WORD */
2915		*dma_prog++ = htole32(OP_JUMP);
2916		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2917		return;
2918
2919	case 3:
2920		/* sync vro */
2921		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2922		*dma_prog++ = htole32(0);  /* NULL WORD */
2923		*dma_prog++ = htole32(OP_JUMP);
2924		*dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
2925		break;
2926	}
2927
2928	if (interlace == 2) {
2929
2930		target_buffer =	buffer + cols*2;
2931
2932		dma_prog = (u_int * ) bktr->odd_dma_prog;
2933
2934		/* sync vre */
2935		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2936		*dma_prog++ = htole32(0);  /* NULL WORD */
2937
2938		for (i = 0; i < (rows/interlace) ; i++) {
2939			*dma_prog++ = htole32(inst);
2940			*dma_prog++ = htole32(target_buffer);
2941			*dma_prog++ = htole32(inst3);
2942			*dma_prog++ = htole32(target_buffer + b);
2943			target_buffer += interlace * ( cols*2);
2944		}
2945	}
2946
2947	/* sync vro IRQ bit */
2948	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2949	*dma_prog++ = htole32(0);  /* NULL WORD */
2950	*dma_prog++ = htole32(OP_JUMP);
2951	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2952
2953	*dma_prog++ = htole32(OP_JUMP);
2954	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2955	*dma_prog++ = htole32(0);  /* NULL WORD */
2956}
2957
2958
2959/*
2960 *
2961 */
2962static void
2963yuv422_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2964{
2965	int		i;
2966	u_int		inst;
2967	u_int		target_buffer, t1, buffer;
2968	u_int		*dma_prog;
2969        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2970
2971	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2972
2973	dma_prog = (u_int *) bktr->dma_prog;
2974
2975	bktr->capcontrol =   1 << 6 | 1 << 4 |	3;
2976
2977	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2978	OUTB(bktr, BKTR_OFORM, 0x00);
2979
2980	OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
2981	OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
2982
2983	OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC);	/* chroma agc enable */
2984	OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2985
2986	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2987	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2988	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2989	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2990
2991	/* disable gamma correction removal */
2992	OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2993
2994	/* Construct Write */
2995	inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
2996	if (bktr->video.addr)
2997		target_buffer = (u_int) bktr->video.addr;
2998	else
2999		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
3000
3001	buffer = target_buffer;
3002
3003	t1 = buffer;
3004
3005	/* contruct sync : for video packet format */
3006	/*     sync, mode indicator packed data*/
3007	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3008	*dma_prog++ = htole32(0);  /* NULL WORD */
3009
3010	for (i = 0; i < (rows/interlace ) ; i++) {
3011		*dma_prog++ = htole32(inst);
3012		*dma_prog++ = htole32(cols/2 | cols/2 << 16);
3013		*dma_prog++ = htole32(target_buffer);
3014		*dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3015		*dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) +
3016		    i*cols/2 * interlace);
3017		target_buffer += interlace*cols;
3018	}
3019
3020	switch (i_flag) {
3021	case 1:
3022		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
3023		*dma_prog++ = htole32(0);  /* NULL WORD */
3024
3025		*dma_prog++ = htole32(OP_JUMP);
3026		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3027		return;
3028
3029	case 2:
3030		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vre*/
3031		*dma_prog++ = htole32(0);  /* NULL WORD */
3032
3033		*dma_prog++ = htole32(OP_JUMP);
3034		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3035		return;
3036
3037	case 3:
3038		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3039		*dma_prog++ = htole32(0);  /* NULL WORD */
3040
3041		*dma_prog++ = htole32(OP_JUMP);
3042		*dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
3043		break;
3044	}
3045
3046	if (interlace == 2) {
3047
3048		dma_prog = (u_int * ) bktr->odd_dma_prog;
3049
3050		target_buffer  = (u_int) buffer + cols;
3051		t1 = buffer + cols/2;
3052		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3053		*dma_prog++ = htole32(0);  /* NULL WORD */
3054
3055		for (i = 0; i < (rows/interlace )  ; i++) {
3056			*dma_prog++ = htole32(inst);
3057			*dma_prog++ = htole32(cols/2 | cols/2 << 16);
3058			*dma_prog++ = htole32(target_buffer);
3059			*dma_prog++ = htole32(t1 + (cols*rows) +
3060			    i*cols/2 * interlace);
3061			*dma_prog++ = htole32(t1 + (cols*rows) +
3062			    (cols*rows/2) + i*cols/2 * interlace);
3063			target_buffer += interlace*cols;
3064		}
3065	}
3066
3067	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3068	*dma_prog++ = htole32(0);  /* NULL WORD */
3069	*dma_prog++ = htole32(OP_JUMP);
3070	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3071	*dma_prog++ = htole32(0);  /* NULL WORD */
3072}
3073
3074
3075/*
3076 *
3077 */
3078static void
3079yuv12_prog( bktr_ptr_t bktr, char i_flag,
3080	     int cols, int rows, int interlace ){
3081
3082	int		i;
3083	u_int		inst;
3084	u_int		inst1;
3085	u_int		target_buffer, t1, buffer;
3086	u_int		*dma_prog;
3087        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3088
3089	OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3090
3091	dma_prog = (u_int *) bktr->dma_prog;
3092
3093	bktr->capcontrol =   1 << 6 | 1 << 4 |	3;
3094
3095	OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3096	OUTB(bktr, BKTR_OFORM, 0x0);
3097
3098	/* Construct Write */
3099	inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
3100	inst1  = OP_WRITES123  | OP_SOL | OP_EOL |  (cols);
3101	if (bktr->video.addr)
3102		target_buffer = (u_int) bktr->video.addr;
3103	else
3104		target_buffer = bktr->dm_mem->dm_segs->ds_addr;
3105
3106	buffer = target_buffer;
3107	t1 = buffer;
3108
3109	/* sync, mode indicator packed data*/
3110	*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3111	*dma_prog++ = htole32(0);  /* NULL WORD */
3112
3113	for (i = 0; i < (rows/interlace )/2 ; i++) {
3114		*dma_prog++ = htole32(inst);
3115		*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3116		*dma_prog++ = htole32(target_buffer);
3117		*dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3118		*dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) +
3119		    i*cols/2 * interlace);
3120		target_buffer += interlace*cols;
3121		*dma_prog++ = htole32(inst1);
3122		*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3123		*dma_prog++ = htole32(target_buffer);
3124		target_buffer += interlace*cols;
3125
3126	}
3127
3128	switch (i_flag) {
3129	case 1:
3130		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
3131		*dma_prog++ = htole32(0);  /* NULL WORD */
3132
3133		*dma_prog++ = htole32(OP_JUMP);
3134		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3135		return;
3136
3137	case 2:
3138		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vro*/
3139		*dma_prog++ = htole32(0);  /* NULL WORD */
3140
3141		*dma_prog++ = htole32(OP_JUMP);
3142		*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3143		return;
3144
3145	case 3:
3146		*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3147		*dma_prog++ = htole32(0);  /* NULL WORD */
3148		*dma_prog++ = htole32(OP_JUMP);
3149		*dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
3150		break;
3151	}
3152
3153	if (interlace == 2) {
3154
3155		dma_prog = (u_int *)bktr->odd_dma_prog;
3156
3157		target_buffer  = (u_int) buffer + cols;
3158		t1 = buffer + cols/2;
3159		*dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3160		*dma_prog++ = htole32(0);  /* NULL WORD */
3161
3162		for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3163			*dma_prog++ = htole32(inst);
3164			*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3165			*dma_prog++ = htole32(target_buffer);
3166			*dma_prog++ = htole32(t1 + (cols*rows) +
3167			    i*cols/2 * interlace);
3168			*dma_prog++ = htole32(t1 + (cols*rows) +
3169			    (cols*rows/4) + i*cols/2 * interlace);
3170			target_buffer += interlace*cols;
3171			*dma_prog++ = htole32(inst1);
3172			*dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3173			*dma_prog++ = htole32(target_buffer);
3174			target_buffer += interlace*cols;
3175		}
3176	}
3177
3178	*dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3179	*dma_prog++ = htole32(0);  /* NULL WORD */
3180	*dma_prog++ = htole32(OP_JUMP);
3181	*dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3182	*dma_prog++ = htole32(0);  /* NULL WORD */
3183}
3184
3185
3186/*
3187 *
3188 */
3189static void
3190build_dma_prog( bktr_ptr_t bktr, char i_flag )
3191{
3192	int			rows, cols,  interlace;
3193	int			tmp_int;
3194	unsigned int		temp;
3195	const struct format_params *fp;
3196        const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3197
3198
3199	fp = &format_params[bktr->format_params];
3200
3201	OUTL(bktr, BKTR_INT_MASK,  ALL_INTS_DISABLED);
3202
3203	/* disable FIFO & RISC, leave other bits alone */
3204	OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3205
3206	/* set video parameters */
3207	if (bktr->capture_area_enabled)
3208	  temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3209		  / fp->scaled_htotal / bktr->cols) -  4096;
3210	else
3211	  temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3212		  / fp->scaled_htotal / bktr->cols) -  4096;
3213
3214	/* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3215	OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3216	OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3217	OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3218	OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3219
3220	/* horizontal active */
3221	temp = bktr->cols;
3222	/* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3223	OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3224	OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3225	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3226	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3227	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3228	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3229
3230	/* horizontal delay */
3231	if (bktr->capture_area_enabled)
3232	  temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3233		 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3234	else
3235	  temp = (fp->hdelay * bktr->cols) / fp->hactive;
3236
3237	temp = temp & 0x3fe;
3238
3239	/* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3240	OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3241	OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3242	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3243	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3244	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3245	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3246
3247	/* vertical scale */
3248
3249	if (bktr->capture_area_enabled) {
3250	  if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3251	      bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3252	    tmp_int = 65536 -
3253	    (((bktr->capture_area_y_size  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3254	  else {
3255	    tmp_int = 65536 -
3256	    (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3257	  }
3258	} else {
3259	  if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3260	      bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3261	    tmp_int = 65536 -
3262	    (((fp->vactive  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3263	  else {
3264	    tmp_int = 65536  -
3265	    (((fp->vactive * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3266	  }
3267	}
3268
3269	tmp_int &= 0x1fff;
3270	/* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3271	OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3272	OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3273	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3274	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3275	OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3276	OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3277
3278
3279	/* vertical active */
3280	if (bktr->capture_area_enabled)
3281	  temp = bktr->capture_area_y_size;
3282	else
3283	  temp = fp->vactive;
3284	/* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3285	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3286	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3287	OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3288	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3289	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3290	OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3291
3292	/* vertical delay */
3293	if (bktr->capture_area_enabled)
3294	  temp = fp->vdelay + (bktr->capture_area_y_offset);
3295	else
3296	  temp = fp->vdelay;
3297	/* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3298	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3299	OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3300	OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3301	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3302	OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3303	OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3304
3305	/* end of video params */
3306
3307	if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3308	   && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3309		OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3310	} else {
3311		OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3312	}
3313
3314	/* capture control */
3315	switch (i_flag) {
3316	case 1:
3317	        bktr->bktr_cap_ctl =
3318		    (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3319		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3320		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3321		interlace = 1;
3322		break;
3323	 case 2:
3324	        bktr->bktr_cap_ctl =
3325			(BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3326		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3327		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3328		interlace = 1;
3329		break;
3330	 default:
3331	        bktr->bktr_cap_ctl =
3332			(BT848_CAP_CTL_DITH_FRAME |
3333			 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3334		OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3335		OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3336		interlace = 2;
3337		break;
3338	}
3339
3340	OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
3341
3342	rows = bktr->rows;
3343	cols = bktr->cols;
3344
3345	bktr->vbiflags &= ~VBI_CAPTURE;	/* default - no vbi capture */
3346
3347	/* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3348	/* user, then use the rgb_vbi RISC program. */
3349	/* Otherwise, use the normal rgb RISC program */
3350	if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3351		if ( (bktr->vbiflags & VBI_OPEN)
3352		   ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3353		   ||(bktr->format_params == BT848_IFORM_F_SECAM)
3354                   ){
3355			bktr->bktr_cap_ctl |=
3356		                BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3357			bktr->vbiflags |= VBI_CAPTURE;
3358			rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3359			return;
3360		} else {
3361			rgb_prog(bktr, i_flag, cols, rows, interlace);
3362			return;
3363		}
3364	}
3365
3366	if ( pf_int->public.type  == METEOR_PIXTYPE_YUV ) {
3367		yuv422_prog(bktr, i_flag, cols, rows, interlace);
3368		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3369		     | pixfmt_swap_flags( bktr->pixfmt ));
3370		return;
3371	}
3372
3373	if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_PACKED ) {
3374		yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3375		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3376		     | pixfmt_swap_flags( bktr->pixfmt ));
3377		return;
3378	}
3379
3380	if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_12 ) {
3381		yuv12_prog(bktr, i_flag, cols, rows, interlace);
3382		OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3383		     | pixfmt_swap_flags( bktr->pixfmt ));
3384		return;
3385	}
3386	return;
3387}
3388
3389
3390/******************************************************************************
3391 * video & video capture specific routines:
3392 */
3393
3394
3395/*
3396 *
3397 */
3398static void
3399start_capture( bktr_ptr_t bktr, unsigned type )
3400{
3401	u_char			i_flag;
3402	const struct format_params   *fp;
3403
3404	fp = &format_params[bktr->format_params];
3405
3406	/*  If requested, clear out capture buf first  */
3407	if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3408		bzero((caddr_t)bktr->bigbuf,
3409		      (size_t)bktr->rows * bktr->cols * bktr->frames *
3410			pixfmt_table[ bktr->pixfmt ].public.Bpp);
3411	}
3412
3413	OUTB(bktr, BKTR_DSTATUS,  0);
3414	OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3415
3416	bktr->flags |= type;
3417	bktr->flags &= ~METEOR_WANT_MASK;
3418	switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3419	case METEOR_ONLY_EVEN_FIELDS:
3420		bktr->flags |= METEOR_WANT_EVEN;
3421		i_flag = 1;
3422		break;
3423	case METEOR_ONLY_ODD_FIELDS:
3424		bktr->flags |= METEOR_WANT_ODD;
3425		i_flag = 2;
3426		break;
3427	default:
3428		bktr->flags |= METEOR_WANT_MASK;
3429		i_flag = 3;
3430		break;
3431	}
3432
3433	/*  TDEC is only valid for continuous captures  */
3434	if ( type == METEOR_SINGLE ) {
3435		u_short	fps_save = bktr->fps;
3436
3437		set_fps(bktr, fp->frame_rate);
3438		bktr->fps = fps_save;
3439	}
3440	else
3441		set_fps(bktr, bktr->fps);
3442
3443	if (bktr->dma_prog_loaded == FALSE) {
3444		build_dma_prog(bktr, i_flag);
3445		bktr->dma_prog_loaded = TRUE;
3446	}
3447
3448
3449	OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
3450}
3451
3452
3453/*
3454 *
3455 */
3456static void
3457set_fps( bktr_ptr_t bktr, u_short fps )
3458{
3459	const struct format_params	*fp;
3460	int i_flag;
3461
3462	fp = &format_params[bktr->format_params];
3463
3464	switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3465	case METEOR_ONLY_EVEN_FIELDS:
3466		bktr->flags |= METEOR_WANT_EVEN;
3467		i_flag = 1;
3468		break;
3469	case METEOR_ONLY_ODD_FIELDS:
3470		bktr->flags |= METEOR_WANT_ODD;
3471		i_flag = 1;
3472		break;
3473	default:
3474		bktr->flags |= METEOR_WANT_MASK;
3475		i_flag = 2;
3476		break;
3477	}
3478
3479	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3480	OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3481
3482	bktr->fps = fps;
3483	OUTB(bktr, BKTR_TDEC, 0);
3484
3485	if (fps < fp->frame_rate)
3486		OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3487	else
3488		OUTB(bktr, BKTR_TDEC, 0);
3489	return;
3490
3491}
3492
3493
3494
3495
3496
3497/*
3498 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3499 *   achieve the specified swapping.
3500 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3501 *   byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3502 *   and read R->L).
3503 * Note also that for 3Bpp, we may additionally need to do some creative
3504 *   SKIPing to align the FIFO bytelines with the target buffer (see split()).
3505 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3506 *   as one would expect.
3507 */
3508
3509static u_int pixfmt_swap_flags( int pixfmt )
3510{
3511	const struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3512	u_int		      swapf = 0;
3513	int swap_bytes, swap_shorts;
3514
3515#if BYTE_ORDER == LITTLE_ENDIAN
3516	swap_bytes = pf->swap_bytes;
3517	swap_shorts = pf->swap_shorts;
3518#else
3519	swap_bytes = !pf->swap_bytes;
3520	swap_shorts = !pf->swap_shorts;
3521#endif
3522
3523	switch ( pf->Bpp ) {
3524	case 2:
3525		swapf = swap_bytes ? 0 : BSWAP;
3526		break;
3527
3528	case 3: /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3529		break;
3530
3531	case 4:
3532		swapf = swap_bytes ? 0 : BSWAP;
3533		swapf |= swap_shorts ? 0 : WSWAP;
3534		break;
3535	}
3536	return swapf;
3537}
3538
3539
3540
3541/*
3542 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3543 *   our pixfmt_table indices.
3544 */
3545
3546static int oformat_meteor_to_bt( u_int format )
3547{
3548	int    i;
3549        const struct meteor_pixfmt *pf1, *pf2;
3550
3551	/*  Find format in compatibility table  */
3552	for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3553		if ( meteor_pixfmt_table[i].meteor_format == format )
3554			break;
3555
3556	if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3557		return -1;
3558	pf1 = &meteor_pixfmt_table[i].public;
3559
3560	/*  Match it with an entry in master pixel format table  */
3561	for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3562		pf2 = &pixfmt_table[i].public;
3563
3564		if (( pf1->type        == pf2->type        ) &&
3565		    ( pf1->Bpp         == pf2->Bpp         ) &&
3566		    !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3567		    ( pf1->swap_bytes  == pf2->swap_bytes  ) &&
3568		    ( pf1->swap_shorts == pf2->swap_shorts ))
3569			break;
3570	}
3571	if ( i >= PIXFMT_TABLE_SIZE )
3572		return -1;
3573
3574	return i;
3575}
3576
3577/******************************************************************************
3578 * i2c primitives:
3579 */
3580
3581/* */
3582#define I2CBITTIME		(0x5)	/* 5 * 0.48uS */
3583#define I2CBITTIME_878		(0x8)
3584#define I2C_READ		0x01
3585#define I2C_COMMAND		((I2CBITTIME << 4) |		\
3586				 BT848_DATA_CTL_I2CSCL |	\
3587				 BT848_DATA_CTL_I2CSDA)
3588
3589#define I2C_COMMAND_878		((I2CBITTIME_878 << 4) |	\
3590				 BT848_DATA_CTL_I2CSCL |	\
3591				 BT848_DATA_CTL_I2CSDA)
3592
3593/*
3594 * Program the i2c bus directly
3595 */
3596int
3597i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3598{
3599	u_int		x;
3600	u_int		data;
3601
3602	/* clear status bits */
3603	OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3604
3605	/* build the command datum */
3606	if (bktr->id == BROOKTREE_848  ||
3607	    bktr->id == BROOKTREE_848A ||
3608	    bktr->id == BROOKTREE_849A) {
3609	  data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3610	} else {
3611	  data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3612	}
3613	if ( byte2 != -1 ) {
3614		data |= ((byte2 & 0xff) << 8);
3615		data |= BT848_DATA_CTL_I2CW3B;
3616	}
3617
3618	/* write the address and data */
3619	OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3620
3621	/* wait for completion */
3622	for ( x = 0x7fffffff; x; --x ) {	/* safety valve */
3623		if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3624			break;
3625	}
3626
3627	/* check for ACK */
3628	if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3629		return( -1 );
3630
3631	/* return OK */
3632	return( 0 );
3633}
3634
3635
3636/*
3637 *
3638 */
3639int
3640i2cRead( bktr_ptr_t bktr, int addr )
3641{
3642	u_int32_t x, stat;
3643
3644	/* clear status bits */
3645	OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3646
3647	/* write the READ address */
3648	/* The Bt878 and Bt879  differed on the treatment of i2c commands */
3649
3650	if (bktr->id == BROOKTREE_848  ||
3651	    bktr->id == BROOKTREE_848A ||
3652	    bktr->id == BROOKTREE_849A)
3653		OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3654	else
3655		OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3656
3657	/* wait for completion */
3658	for (x = 5000; x--; DELAY(1))	/* 5 msec, safety valve */
3659		if ((stat = INL(bktr, BKTR_INT_STAT)) & BT848_INT_I2CDONE)
3660			break;
3661
3662	/* check for ACK */
3663	if ((stat & (I2C_BITS)) != (I2C_BITS))
3664		return (-1);
3665
3666	/* it was a read */
3667	x = INL(bktr, BKTR_I2C_DATA_CTL);
3668	return ((x >> 8) & 0xff);
3669}
3670
3671/* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3672/* bt848 automated i2c bus controller cannot handle */
3673/* Therefore we need low level control of the i2c bus hardware */
3674/* Idea for the following functions are from elsewhere in this driver and */
3675/* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3676
3677#define BITD    40
3678static void i2c_start( bktr_ptr_t bktr) {
3679        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3680        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3681        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3682        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3683}
3684
3685static void i2c_stop( bktr_ptr_t bktr) {
3686        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3687        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3688        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3689}
3690
3691static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3692        int x;
3693        int status;
3694
3695        /* write out the byte */
3696        for ( x = 7; x >= 0; --x ) {
3697                if ( data & (1<<x) ) {
3698			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3699                        DELAY( BITD );          /* assert HI data */
3700			OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3701                        DELAY( BITD );          /* strobe clock */
3702			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3703                        DELAY( BITD );          /* release clock */
3704                }
3705                else {
3706			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3707                        DELAY( BITD );          /* assert LO data */
3708			OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3709                        DELAY( BITD );          /* strobe clock */
3710			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3711                        DELAY( BITD );          /* release clock */
3712                }
3713        }
3714
3715        /* look for an ACK */
3716	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3717	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3718        status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;       /* read the ACK bit */
3719        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3720
3721        return( status );
3722}
3723
3724static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3725        int x;
3726        int bit;
3727        int byte = 0;
3728
3729        /* read in the byte */
3730	OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3731        DELAY( BITD );                          /* float data */
3732        for ( x = 7; x >= 0; --x ) {
3733		OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3734                DELAY( BITD );                  /* strobe clock */
3735                bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1;  /* read the data bit */
3736                if ( bit ) byte |= (1<<x);
3737		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3738                DELAY( BITD );                  /* release clock */
3739        }
3740        /* After reading the byte, send an ACK */
3741        /* (unless that was the last byte, for which we send a NAK */
3742        if (last) { /* send NAK - same a writing a 1 */
3743		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3744                DELAY( BITD );                  /* set data bit */
3745		OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3746                DELAY( BITD );                  /* strobe clock */
3747		OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3748                DELAY( BITD );                  /* release clock */
3749        } else { /* send ACK - same as writing a 0 */
3750		OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3751                DELAY( BITD );                  /* set data bit */
3752		OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3753                DELAY( BITD );                  /* strobe clock */
3754		OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3755                DELAY( BITD );                  /* release clock */
3756        }
3757
3758        *data=byte;
3759	return 0;
3760}
3761#undef BITD
3762
3763/* Write to the MSP or DPL registers */
3764void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
3765		    unsigned int data){
3766	unsigned int msp_w_addr = i2c_addr;
3767	unsigned char addr_l, addr_h, data_h, data_l ;
3768	addr_h = (addr >>8) & 0xff;
3769	addr_l = addr & 0xff;
3770	data_h = (data >>8) & 0xff;
3771	data_l = data & 0xff;
3772
3773	i2c_start(bktr);
3774	i2c_write_byte(bktr, msp_w_addr);
3775	i2c_write_byte(bktr, dev);
3776	i2c_write_byte(bktr, addr_h);
3777	i2c_write_byte(bktr, addr_l);
3778	i2c_write_byte(bktr, data_h);
3779	i2c_write_byte(bktr, data_l);
3780	i2c_stop(bktr);
3781}
3782
3783/* Read from the MSP or DPL registers */
3784unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
3785	unsigned int data;
3786	unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
3787	addr_h = (addr >>8) & 0xff;
3788	addr_l = addr & 0xff;
3789	dev_r = dev+1;
3790
3791	i2c_start(bktr);
3792	i2c_write_byte(bktr,i2c_addr);
3793	i2c_write_byte(bktr,dev_r);
3794	i2c_write_byte(bktr,addr_h);
3795	i2c_write_byte(bktr,addr_l);
3796
3797	i2c_start(bktr);
3798	i2c_write_byte(bktr,i2c_addr+1);
3799	i2c_read_byte(bktr,&data_1, 0);
3800	i2c_read_byte(bktr,&data_2, 1);
3801	i2c_stop(bktr);
3802	data = (data_1<<8) | data_2;
3803	return data;
3804}
3805
3806/* Reset the MSP or DPL chip */
3807/* The user can block the reset (which is handy if you initialise the
3808 * MSP audio in another operating system first (eg in Windows)
3809 */
3810void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
3811
3812#ifndef BKTR_NO_MSP_RESET
3813	/* put into reset mode */
3814	i2c_start(bktr);
3815	i2c_write_byte(bktr, i2c_addr);
3816	i2c_write_byte(bktr, 0x00);
3817	i2c_write_byte(bktr, 0x80);
3818	i2c_write_byte(bktr, 0x00);
3819	i2c_stop(bktr);
3820
3821	/* put back to operational mode */
3822	i2c_start(bktr);
3823	i2c_write_byte(bktr, i2c_addr);
3824	i2c_write_byte(bktr, 0x00);
3825	i2c_write_byte(bktr, 0x00);
3826	i2c_write_byte(bktr, 0x00);
3827	i2c_stop(bktr);
3828#endif
3829	return;
3830
3831}
3832
3833static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3834
3835	/* XXX errors ignored */
3836	i2c_start(bktr);
3837	i2c_write_byte(bktr,bktr->remote_control_addr);
3838	i2c_read_byte(bktr,&(remote->data[0]), 0);
3839	i2c_read_byte(bktr,&(remote->data[1]), 0);
3840	i2c_read_byte(bktr,&(remote->data[2]), 0);
3841	i2c_stop(bktr);
3842
3843	return;
3844}
3845
3846#if defined( I2C_SOFTWARE_PROBE )
3847
3848/*
3849 * we are keeping this around for any parts that we need to probe
3850 * but that CANNOT be probed via an i2c read.
3851 * this is necessary because the hardware i2c mechanism
3852 * cannot be programmed for 1 byte writes.
3853 * currently there are no known i2c parts that we need to probe
3854 * and that cannot be safely read.
3855 */
3856static int	i2cProbe( bktr_ptr_t bktr, int addr );
3857#define BITD		40
3858#define EXTRA_START
3859
3860/*
3861 * probe for an I2C device at addr.
3862 */
3863static int
3864i2cProbe( bktr_ptr_t bktr, int addr )
3865{
3866	int		x, status;
3867
3868	/* the START */
3869#if defined( EXTRA_START )
3870	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );	/* release data */
3871	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );	/* release clock */
3872#endif /* EXTRA_START */
3873	OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );	/* lower data */
3874	OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );	/* lower clock */
3875
3876	/* write addr */
3877	for ( x = 7; x >= 0; --x ) {
3878		if ( addr & (1<<x) ) {
3879			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3880			DELAY( BITD );		/* assert HI data */
3881			OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3882			DELAY( BITD );		/* strobe clock */
3883			OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3884			DELAY( BITD );		/* release clock */
3885		}
3886		else {
3887			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3888			DELAY( BITD );		/* assert LO data */
3889			OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3890			DELAY( BITD );		/* strobe clock */
3891			OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3892			DELAY( BITD );		/* release clock */
3893		}
3894	}
3895
3896	/* look for an ACK */
3897	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );	/* float data */
3898	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );	/* strobe clock */
3899	status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;	/* read the ACK bit */
3900	OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );	/* release clock */
3901
3902	/* the STOP */
3903	OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );	/* lower clock & data */
3904	OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );	/* release clock */
3905	OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );	/* release data */
3906
3907	return( status );
3908}
3909#undef EXTRA_START
3910#undef BITD
3911
3912#endif /* I2C_SOFTWARE_PROBE */
3913