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