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