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