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