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