Rename functions to avoid conflicts with libc.
[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.138 2005/01/09 17:42:03 cognet Exp
65  * $DragonFly: src/sys/dev/video/bktr/bktr_core.c,v 1.17 2006/09/03 18:29:16 dillon 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 #include <sys/thread2.h>
118
119 #include <dev/video/meteor/ioctl_meteor.h>
120 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
121 #include <dev/video/bktr/bktr_reg.h>
122 #include <dev/video/bktr/bktr_tuner.h>
123 #include <dev/video/bktr/bktr_card.h>
124 #include <dev/video/bktr/bktr_audio.h>
125 #include <dev/video/bktr/bktr_os.h>
126 #include <dev/video/bktr/bktr_core.h>
127 #if defined(BKTR_FREEBSD_MODULE)
128 #include <dev/video/bktr/bktr_mem.h>
129 #endif
130
131 #if defined(BKTR_USE_FREEBSD_SMBUS)
132 #include <dev/video/bktr/bktr_i2c.h>
133 #include <bus/smbus/smbconf.h>
134 #include <bus/iicbus/iiconf.h>
135 #include "smbus_if.h"
136 #include "iicbus_if.h"
137 #endif
138
139 const char *
140 bktr_name(bktr_ptr_t bktr)
141 {
142   return bktr->bktr_xname;
143 }
144
145 typedef u_char bool_t;
146
147 #define BKTRPRI PCATCH
148 #define VBIPRI  PCATCH
149
150
151 /*
152  * memory allocated for DMA programs
153  */
154 #define DMA_PROG_ALLOC          (8 * PAGE_SIZE)
155
156 /* When to split a dma transfer , the bt848 has timing as well as
157    dma transfer size limitations so that we have to split dma
158    transfers into two dma requests 
159    */
160 #define DMA_BT848_SPLIT 319*2
161
162 /* 
163  * Allocate enough memory for:
164  *      768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
165  *
166  * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
167  * in your  kernel configuration file.
168  */
169
170 #ifndef BROOKTREE_ALLOC_PAGES
171 #define BROOKTREE_ALLOC_PAGES   217*4
172 #endif
173 #define BROOKTREE_ALLOC         (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
174
175 /* Definitions for VBI capture.
176  * There are 16 VBI lines in a PAL video field (32 in a frame),
177  * and we take 2044 samples from each line (placed in a 2048 byte buffer
178  * for alignment).
179  * VBI lines are held in a circular buffer before being read by a
180  * user program from /dev/vbi.
181  */
182
183 #define MAX_VBI_LINES         16   /* Maximum for all vidoe formats */
184 #define VBI_LINE_SIZE         2048 /* Store upto 2048 bytes per line */
185 #define VBI_BUFFER_ITEMS      20   /* Number of frames we buffer */
186 #define VBI_DATA_SIZE         (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
187 #define VBI_BUFFER_SIZE       (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
188
189
190 /*  Defines for fields  */
191 #define ODD_F  0x01
192 #define EVEN_F 0x02
193
194
195 /*
196  * Parameters describing size of transmitted image.
197  */
198
199 static struct format_params format_params[] = {
200 /* # define BT848_IFORM_F_AUTO             (0x0) - don't matter. */
201   { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
202     12,  1600 },
203 /* # define BT848_IFORM_F_NTSCM            (0x1) */
204   { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
205     12, 1600 },
206 /* # define BT848_IFORM_F_NTSCJ            (0x2) */
207   { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
208     12, 1600 },
209 /* # define BT848_IFORM_F_PALBDGHI         (0x3) */
210   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
211     16,  2044 },
212 /* # define BT848_IFORM_F_PALM             (0x4) */
213   { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
214     12, 1600 },
215 /* # define BT848_IFORM_F_PALN             (0x5) */
216   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
217     16, 2044 },
218 /* # define BT848_IFORM_F_SECAM            (0x6) */
219   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
220     16, 2044 },
221 /* # define BT848_IFORM_F_RSVD             (0x7) - ???? */
222   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
223     16, 2044 },
224 };
225
226 /*
227  * Table of supported Pixel Formats 
228  */
229
230 static struct meteor_pixfmt_internal {
231         struct meteor_pixfmt public;
232         u_int                color_fmt;
233 } pixfmt_table[] = {
234
235 { { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 0,0 }, 0x33 },
236 { { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 1,0 }, 0x33 },
237
238 { { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 0,0 }, 0x22 },
239 { { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 1,0 }, 0x22 },
240
241 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
242
243 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
244 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
245 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
246 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
247 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
248 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
249 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
250
251 };
252 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
253
254 /*
255  * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
256  */
257
258 /*  FIXME:  Also add YUV_422 and YUV_PACKED as well  */
259 static struct {
260         u_long               meteor_format;
261         struct meteor_pixfmt public;
262 } meteor_pixfmt_table[] = {
263     { METEOR_GEO_YUV_12,
264       { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
265     },
266
267       /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
268     { METEOR_GEO_YUV_422,
269       { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
270     },
271     { METEOR_GEO_YUV_PACKED,
272       { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
273     },
274     { METEOR_GEO_RGB16,
275       { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,   0x03e0,   0x001f }, 0, 0 }
276     },
277     { METEOR_GEO_RGB24,
278       { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
279     },
280
281 };
282 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
283                                    sizeof(meteor_pixfmt_table[0]) )
284
285
286 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
287 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
288
289
290
291 /* sync detect threshold */
292 #if 0
293 #define SYNC_LEVEL              (BT848_ADC_RESERVED |   \
294                                  BT848_ADC_CRUSH)       /* threshold ~125 mV */
295 #else
296 #define SYNC_LEVEL              (BT848_ADC_RESERVED |   \
297                                  BT848_ADC_SYNC_T)      /* threshold ~75 mV */
298 #endif
299
300
301
302
303 /* debug utility for holding previous INT_STAT contents */
304 #define STATUS_SUM
305 static u_long   status_sum = 0;
306
307 /*
308  * defines to make certain bit-fiddles understandable
309  */
310 #define FIFO_ENABLED            BT848_DMA_CTL_FIFO_EN
311 #define RISC_ENABLED            BT848_DMA_CTL_RISC_EN
312 #define FIFO_RISC_ENABLED       (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
313 #define FIFO_RISC_DISABLED      0
314
315 #define ALL_INTS_DISABLED       0
316 #define ALL_INTS_CLEARED        0xffffffff
317 #define CAPTURE_OFF             0
318
319 #define BIT_SEVEN_HIGH          (1<<7)
320 #define BIT_EIGHT_HIGH          (1<<8)
321
322 #define I2C_BITS                (BT848_INT_RACK | BT848_INT_I2CDONE)
323 #define TDEC_BITS               (BT848_INT_FDSR | BT848_INT_FBUS)
324
325
326
327 static int              oformat_meteor_to_bt( u_long format );
328
329 static u_int            pixfmt_swap_flags( int pixfmt );
330
331 /*
332  * bt848 RISC programming routines.
333  */
334 #ifdef BT848_DUMP
335 static int      dump_bt848( bktr_ptr_t bktr );
336 #endif
337
338 static void     yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
339                               int rows,  int interlace );
340 static void     yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
341                              int rows, int interlace );
342 static void     yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
343                              int rows, int interlace );
344 static void     rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
345                           int rows, int interlace );
346 static void     rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
347                           int rows, int interlace );
348 static void     build_dma_prog( bktr_ptr_t bktr, char i_flag );
349
350 static bool_t   getline(bktr_reg_t *, int);
351 static bool_t   notclipped(bktr_reg_t * , int , int);     
352 static bool_t   split(bktr_reg_t *, volatile uint32_t **, int, u_long, int, 
353                       volatile u_char ** , int  );
354
355 static void     start_capture( bktr_ptr_t bktr, unsigned type );
356 static void     set_fps( bktr_ptr_t bktr, u_short fps );
357
358
359
360 /*
361  * Remote Control Functions
362  */
363 static void     remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
364
365
366 /*
367  * ioctls common to both video & tuner.
368  */
369 static int      common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
370
371
372 #if !defined(BKTR_USE_FREEBSD_SMBUS)
373 /*
374  * i2c primitives for low level control of i2c bus. Added for MSP34xx control
375  */
376 static void     i2c_start( bktr_ptr_t bktr);
377 static void     i2c_stop( bktr_ptr_t bktr);
378 static int      i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
379 static int      i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
380 #endif
381
382
383
384 /*
385  * the common attach code, used by all OS versions.
386  */
387 void 
388 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
389 {
390         vm_offset_t     buf = 0;
391         int             need_to_allocate_memory = 1;
392 #ifdef BKTR_NEW_MSP34XX_DRIVER
393         int             err;
394 #endif
395
396 /* If this is a module, check if there is any currently saved contiguous memory */
397 #if defined(BKTR_FREEBSD_MODULE)
398         if (bktr_has_stored_addresses(unit) == 1) {
399                 /* recover the addresses */
400                 bktr->dma_prog     = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
401                 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
402                 bktr->vbidata      = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
403                 bktr->vbibuffer    = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
404                 buf                = bktr_retrieve_address(unit, BKTR_MEM_BUF);
405                 need_to_allocate_memory = 0;
406         }
407 #endif
408
409         if (need_to_allocate_memory == 1) {
410                 /* allocate space for dma program */
411                 bktr->dma_prog     = get_bktr_mem(unit, DMA_PROG_ALLOC);
412                 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
413
414                 /* allocte space for the VBI buffer */
415                 bktr->vbidata  = get_bktr_mem(unit, VBI_DATA_SIZE);
416                 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
417
418                 /* allocate space for pixel buffer */
419                 if ( BROOKTREE_ALLOC )
420                         buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
421                 else
422                         buf = 0;
423         }
424
425 #ifdef USE_VBIMUTEX
426         mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
427 #endif
428
429 /* If this is a module, save the current contiguous memory */
430 #if defined(BKTR_FREEBSD_MODULE)
431 bktr_store_address(unit, BKTR_MEM_DMA_PROG,     bktr->dma_prog);
432 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
433 bktr_store_address(unit, BKTR_MEM_VBIDATA,      bktr->vbidata);
434 bktr_store_address(unit, BKTR_MEM_VBIBUFFER,    bktr->vbibuffer);
435 bktr_store_address(unit, BKTR_MEM_BUF,          buf);
436 #endif
437
438
439         if ( bootverbose ) {
440                 printf("%s: buffer size %d, addr %p\n",
441                         bktr_name(bktr), BROOKTREE_ALLOC,
442                         (void *)(uintptr_t)vtophys(buf));
443         }
444
445         if ( buf != 0 ) {
446                 bktr->bigbuf = buf;
447                 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
448                 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
449         } else {
450                 bktr->alloc_pages = 0;
451         }
452                 
453
454         bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
455                       METEOR_DEV0 | METEOR_RGB16;
456         bktr->dma_prog_loaded = FALSE;
457         bktr->cols = 640;
458         bktr->rows = 480;
459         bktr->frames = 1;               /* one frame */
460         bktr->format = METEOR_GEO_RGB16;
461         bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
462         bktr->pixfmt_compat = TRUE;
463
464
465         bktr->vbiinsert = 0;
466         bktr->vbistart = 0;
467         bktr->vbisize = 0;
468         bktr->vbiflags = 0;
469
470  
471         /* using the pci device id and revision id */
472         /* and determine the card type            */
473         if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
474         {
475                 switch (PCI_PRODUCT(pci_id)) {
476                 case PCI_PRODUCT_BROOKTREE_BT848:
477                         if (rev == 0x12)
478                                 bktr->id = BROOKTREE_848A;
479                         else
480                                 bktr->id = BROOKTREE_848;
481                         break;
482                 case PCI_PRODUCT_BROOKTREE_BT849:
483                         bktr->id = BROOKTREE_849A;
484                         break;
485                 case PCI_PRODUCT_BROOKTREE_BT878:
486                         bktr->id = BROOKTREE_878;
487                         break;
488                 case PCI_PRODUCT_BROOKTREE_BT879:
489                         bktr->id = BROOKTREE_879;
490                         break;
491                 }
492         };
493
494         bktr->clr_on_start = FALSE;
495
496         /* defaults for the tuner section of the card */
497         bktr->tflags = TUNER_INITALIZED;
498         bktr->tuner.frequency = 0;
499         bktr->tuner.channel = 0;
500         bktr->tuner.chnlset = DEFAULT_CHNLSET;
501         bktr->tuner.afc = 0;
502         bktr->tuner.radio_mode = 0;
503         bktr->audio_mux_select = 0;
504         bktr->audio_mute_state = FALSE;
505         bktr->bt848_card = -1;
506         bktr->bt848_tuner = -1;
507         bktr->reverse_mute = -1;
508         bktr->slow_msp_audio = 0;
509         bktr->msp_use_mono_source = 0;
510         bktr->msp_source_selected = -1;
511         bktr->audio_mux_present = 1;
512
513 #ifdef BKTR_NEW_MSP34XX_DRIVER
514         /* get hint on short programming of the msp34xx, so we know */
515         /* if the decision what thread to start should be overwritten */
516         if ( (err = resource_int_value("bktr", unit, "mspsimple",
517                         &(bktr->mspsimple)) ) != 0 )
518                 bktr->mspsimple = -1;   /* fall back to default */
519 #endif
520
521         probeCard( bktr, TRUE, unit );
522
523         /* Initialise any MSP34xx or TDA98xx audio chips */
524         init_audio_devices( bktr );
525
526 #ifdef BKTR_NEW_MSP34XX_DRIVER
527         /* setup the kenrel thread */
528         err = msp_attach( bktr );
529         if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
530                 bktr->card.msp3400c = 0;
531 #endif
532
533
534 }
535
536
537 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
538  * The circular buffer holds 'n' fixed size data blocks. 
539  * vbisize   is the number of bytes in the circular buffer 
540  * vbiread   is the point we reading data out of the circular buffer 
541  * vbiinsert is the point we insert data into the circular buffer 
542  */
543 static void vbidecode(bktr_ptr_t bktr) {
544         unsigned char *dest;
545         unsigned int *seq_dest;
546
547         /* Check if there is room in the buffer to insert the data. */
548         if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
549
550         /* Copy the VBI data into the next free slot in the buffer. */
551         /* 'dest' is the point in vbibuffer where we want to insert new data */
552         dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
553         memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
554
555         /* Write the VBI sequence number to the end of the vbi data */
556         /* This is used by the AleVT teletext program */
557         seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
558                         + bktr->vbiinsert
559                         + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
560         *seq_dest = bktr->vbi_sequence_number;
561
562         /* And increase the VBI sequence number */
563         /* This can wrap around */
564         bktr->vbi_sequence_number++;
565
566
567         /* Increment the vbiinsert pointer */
568         /* This can wrap around */
569         bktr->vbiinsert += VBI_DATA_SIZE;
570         bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
571
572         /* And increase the amount of vbi data in the buffer */
573         bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
574
575 }
576
577
578 /*
579  * the common interrupt handler.
580  * Returns a 0 or 1 depending on whether the interrupt has handled.
581  * In the OS specific section, bktr_intr() is defined which calls this
582  * common interrupt handler.
583  */
584 int 
585 common_bktr_intr( void *arg )
586
587         bktr_ptr_t              bktr;
588         u_long                  bktr_status;
589         u_char                  dstatus;
590         u_long                  field;
591         u_long                  w_field;
592         u_long                  req_field;
593
594         bktr = (bktr_ptr_t) arg;
595
596         /*
597          * check to see if any interrupts are unmasked on this device.  If
598          * none are, then we likely got here by way of being on a PCI shared
599          * interrupt dispatch list.
600          */
601         if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
602                 return 0;       /* bail out now, before we do something we
603                                    shouldn't */
604
605         if (!(bktr->flags & METEOR_OPEN)) {
606                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
607                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
608                 /* return; ?? */
609         }
610
611         /* record and clear the INTerrupt status bits */
612         bktr_status = INL(bktr, BKTR_INT_STAT);
613         OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS);     /* don't touch i2c */
614
615         /* record and clear the device status register */
616         dstatus = INB(bktr, BKTR_DSTATUS);
617         OUTB(bktr, BKTR_DSTATUS, 0x00);
618
619 #if defined( STATUS_SUM )
620         /* add any new device status or INTerrupt status bits */
621         status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
622         status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
623 #endif /* STATUS_SUM */
624         /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
625                 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
626         */
627
628
629         /* if risc was disabled re-start process again */
630         /* if there was one of the following errors re-start again */
631         if ( !(bktr_status & BT848_INT_RISC_EN) ||
632              ((bktr_status &(/* BT848_INT_FBUS   | */
633                              /* BT848_INT_FTRGT  | */
634                              /* BT848_INT_FDSR   | */
635                               BT848_INT_PPERR  |
636                               BT848_INT_RIPERR | BT848_INT_PABORT |
637                               BT848_INT_OCERR  | BT848_INT_SCERR) ) != 0) 
638                 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) { 
639
640                 u_short tdec_save = INB(bktr, BKTR_TDEC);
641
642                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
643                 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
644
645                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
646
647                 /*  Reset temporal decimation counter  */
648                 OUTB(bktr, BKTR_TDEC, 0);
649                 OUTB(bktr, BKTR_TDEC, tdec_save);
650                 
651                 /*  Reset to no-fields captured state  */
652                 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
653                         switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
654                         case METEOR_ONLY_ODD_FIELDS:
655                                 bktr->flags |= METEOR_WANT_ODD;
656                                 break;
657                         case METEOR_ONLY_EVEN_FIELDS:
658                                 bktr->flags |= METEOR_WANT_EVEN;
659                                 break;
660                         default:
661                                 bktr->flags |= METEOR_WANT_MASK;
662                                 break;
663                         }
664                 }
665
666                 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
667                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
668                 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
669
670                 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
671                                     BT848_INT_RISCI      |
672                                     BT848_INT_VSYNC      |
673                                     BT848_INT_FMTCHG);
674
675                 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
676                 return 1;
677         }
678
679         /* If this is not a RISC program interrupt, return */
680         if (!(bktr_status & BT848_INT_RISCI))
681                 return 0;
682
683 /**
684         printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
685                 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
686  */
687
688
689         /*
690          * Disable future interrupts if a capture mode is not selected.
691          * This can happen when we are in the process of closing or 
692          * changing capture modes, otherwise it shouldn't happen.
693          */
694         if (!(bktr->flags & METEOR_CAP_MASK))
695                 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
696
697
698         /* Determine which field generated this interrupt */
699         field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
700
701
702         /*
703          * Process the VBI data if it is being captured. We do this once
704          * both Odd and Even VBI data is captured. Therefore we do this
705          * in the Even field interrupt handler.
706          */
707         LOCK_VBI(bktr);
708         if (  (bktr->vbiflags & VBI_CAPTURE)
709             &&(bktr->vbiflags & VBI_OPEN)
710             &&(field==EVEN_F)) {
711                 /* Put VBI data into circular buffer */
712                 vbidecode(bktr);
713
714                 /* If someone is blocked on reading from /dev/vbi, wake them */
715                 if (bktr->vbi_read_blocked) {
716                         bktr->vbi_read_blocked = FALSE;
717                         wakeup(VBI_SLEEP);
718                 }
719
720                 /* If someone has a select() on /dev/vbi, inform them */
721                 if (bktr->vbi_select.si_pid) {
722                         selwakeup(&bktr->vbi_select);
723                 }
724
725
726         }
727         UNLOCK_VBI(bktr);
728
729         /*
730          *  Register the completed field
731          *    (For dual-field mode, require fields from the same frame)
732          */
733         switch ( bktr->flags & METEOR_WANT_MASK ) {
734                 case METEOR_WANT_ODD  : w_field = ODD_F         ;  break;
735                 case METEOR_WANT_EVEN : w_field = EVEN_F        ;  break;
736                 default               : w_field = (ODD_F|EVEN_F);  break;
737         }
738         switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
739                 case METEOR_ONLY_ODD_FIELDS  : req_field = ODD_F  ;  break;
740                 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ;  break;
741                 default                      : req_field = (ODD_F|EVEN_F);  
742                                                break;
743         }
744
745         if (( field == EVEN_F ) && ( w_field == EVEN_F ))
746                 bktr->flags &= ~METEOR_WANT_EVEN;
747         else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
748                  ( w_field == ODD_F ))
749                 bktr->flags &= ~METEOR_WANT_ODD;
750         else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
751                  ( w_field == (ODD_F|EVEN_F) ))
752                 bktr->flags &= ~METEOR_WANT_ODD;
753         else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
754                  ( w_field == ODD_F )) {
755                 bktr->flags &= ~METEOR_WANT_ODD;
756                 bktr->flags |=  METEOR_WANT_EVEN;
757         }
758         else {
759                 /*  We're out of sync.  Start over.  */
760                 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
761                         switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
762                         case METEOR_ONLY_ODD_FIELDS:
763                                 bktr->flags |= METEOR_WANT_ODD;
764                                 break;
765                         case METEOR_ONLY_EVEN_FIELDS:
766                                 bktr->flags |= METEOR_WANT_EVEN;
767                                 break;
768                         default:
769                                 bktr->flags |= METEOR_WANT_MASK;
770                                 break;
771                         }
772                 }
773                 return 1;
774         }
775
776         /*
777          * If we have a complete frame.
778          */
779         if (!(bktr->flags & METEOR_WANT_MASK)) {
780                 bktr->frames_captured++;
781                 /*
782                  * post the completion time. 
783                  */
784                 if (bktr->flags & METEOR_WANT_TS) {
785                         struct timeval *ts;
786                         
787                         if ((u_int) bktr->alloc_pages * PAGE_SIZE
788                            <= (bktr->frame_size + sizeof(struct timeval))) {
789                                 ts =(struct timeval *)bktr->bigbuf +
790                                   bktr->frame_size;
791                                 /* doesn't work in synch mode except
792                                  *  for first frame */
793                                 /* XXX */
794                                 microtime(ts);
795                         }
796                 }
797         
798
799                 /*
800                  * Wake up the user in single capture mode.
801                  */
802                 if (bktr->flags & METEOR_SINGLE) {
803
804                         /* stop dma */
805                         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
806
807                         /* disable risc, leave fifo running */
808                         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
809                         wakeup(BKTR_SLEEP);
810                 }
811
812                 /*
813                  * If the user requested to be notified via signal,
814                  * let them know the frame is complete.
815                  */
816
817                 if (bktr->proc != NULL) {
818                         PROC_LOCK(bktr->proc);
819                         ksignal( bktr->proc, bktr->signal);
820                         PROC_UNLOCK(bktr->proc);
821                 }
822
823                 /*
824                  * Reset the want flags if in continuous or
825                  * synchronous capture mode.
826                  */
827 /*
828 * XXX NOTE (Luigi):
829 * currently we only support 3 capture modes: odd only, even only,
830 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
831 * either even OR odd) could provide 60 (50 for PAL) pictures per
832 * second, but it would require this routine to toggle the desired frame
833 * each time, and one more different DMA program for the Bt848.
834 * As a consequence, this fourth mode is currently unsupported.
835 */
836
837                 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
838                         switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
839                         case METEOR_ONLY_ODD_FIELDS:
840                                 bktr->flags |= METEOR_WANT_ODD;
841                                 break;
842                         case METEOR_ONLY_EVEN_FIELDS:
843                                 bktr->flags |= METEOR_WANT_EVEN;
844                                 break;
845                         default:
846                                 bktr->flags |= METEOR_WANT_MASK;
847                                 break;
848                         }
849                 }
850         }
851
852         return 1;
853 }
854
855
856
857
858 /*
859  * 
860  */
861 extern int bt848_format; /* used to set the default format, PAL or NTSC */
862 int
863 video_open( bktr_ptr_t bktr )
864 {
865         int frame_rate, video_format=0;
866
867         if (bktr->flags & METEOR_OPEN)          /* device is busy */
868                 return( EBUSY );
869
870         bktr->flags |= METEOR_OPEN;
871
872 #ifdef BT848_DUMP
873         dump_bt848( bt848 );
874 #endif
875
876         bktr->clr_on_start = FALSE;
877
878         OUTB(bktr, BKTR_DSTATUS, 0x00);                 /* clear device status reg. */
879
880         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
881
882 #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
883         video_format = 0;
884 #else
885         video_format = 1;
886 #endif
887
888         if (bt848_format == 0 ) 
889           video_format = 0;
890
891         if (bt848_format == 1 ) 
892           video_format = 1;
893
894         if (video_format == 1 ) {
895           OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
896           bktr->format_params = BT848_IFORM_F_NTSCM;
897
898         } else {
899           OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
900           bktr->format_params = BT848_IFORM_F_PALBDGHI;
901
902         }
903
904         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
905
906         /* work around for new Hauppauge 878 cards */
907         if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
908             (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
909                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
910         else
911                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
912
913         OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
914         OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
915         frame_rate    = format_params[bktr->format_params].frame_rate;
916
917         /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
918         if (bktr->xtal_pll_mode == BT848_USE_PLL) {
919                 OUTB(bktr, BKTR_TGCTRL, 0);
920                 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
921                 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
922                 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
923         }
924
925         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
926
927         bktr->max_clip_node = 0;
928
929         OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
930
931         OUTB(bktr, BKTR_E_HSCALE_LO, 170);
932         OUTB(bktr, BKTR_O_HSCALE_LO, 170);
933
934         OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
935         OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
936         OUTB(bktr, BKTR_E_SCLOOP, 0);
937         OUTB(bktr, BKTR_O_SCLOOP, 0);
938
939         OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
940         OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
941
942         bktr->fifo_errors = 0;
943         bktr->dma_errors = 0;
944         bktr->frames_captured = 0;
945         bktr->even_fields_captured = 0;
946         bktr->odd_fields_captured = 0;
947         bktr->proc = NULL;
948         set_fps(bktr, frame_rate);
949         bktr->video.addr = 0;
950         bktr->video.width = 0;
951         bktr->video.banksize = 0;
952         bktr->video.ramsize = 0;
953         bktr->pixfmt_compat = TRUE;
954         bktr->format = METEOR_GEO_RGB16;
955         bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
956
957         bktr->capture_area_enabled = FALSE;
958
959         OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT);        /* if you take this out triton
960                                                    based motherboards will 
961                                                    operate unreliably */
962         return( 0 );
963 }
964
965 int
966 vbi_open( bktr_ptr_t bktr )
967 {
968
969         LOCK_VBI(bktr);
970
971         if (bktr->vbiflags & VBI_OPEN) {        /* device is busy */
972                 UNLOCK_VBI(bktr);
973                 return( EBUSY );
974         }
975
976         bktr->vbiflags |= VBI_OPEN;
977
978         /* reset the VBI circular buffer pointers and clear the buffers */
979         bktr->vbiinsert = 0;
980         bktr->vbistart = 0;
981         bktr->vbisize = 0;
982         bktr->vbi_sequence_number = 0;
983         bktr->vbi_read_blocked = FALSE;
984
985         bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
986         bzero((caddr_t) bktr->vbidata,  VBI_DATA_SIZE);
987
988         UNLOCK_VBI(bktr);
989
990         return( 0 );
991 }
992
993 /*
994  * 
995  */
996 int
997 tuner_open( bktr_ptr_t bktr )
998 {
999         if ( !(bktr->tflags & TUNER_INITALIZED) )       /* device not found */
1000                 return( ENXIO );        
1001
1002         if ( bktr->tflags & TUNER_OPEN )                /* already open */
1003                 return( 0 );
1004
1005         bktr->tflags |= TUNER_OPEN;
1006         bktr->tuner.frequency = 0;
1007         bktr->tuner.channel = 0;
1008         bktr->tuner.chnlset = DEFAULT_CHNLSET;
1009         bktr->tuner.afc = 0;
1010         bktr->tuner.radio_mode = 0;
1011
1012         /* enable drivers on the GPIO port that control the MUXes */
1013         OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1014
1015         /* unmute the audio stream */
1016         set_audio( bktr, AUDIO_UNMUTE );
1017
1018         /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1019         init_audio_devices( bktr );
1020         
1021         return( 0 );
1022 }
1023
1024
1025
1026
1027 /*
1028  * 
1029  */
1030 int
1031 video_close( bktr_ptr_t bktr )
1032 {
1033         bktr->flags &= ~(METEOR_OPEN     |
1034                          METEOR_SINGLE   |
1035                          METEOR_CAP_MASK |
1036                          METEOR_WANT_MASK);
1037
1038         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1039         OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1040
1041         bktr->dma_prog_loaded = FALSE;
1042         OUTB(bktr, BKTR_TDEC, 0);
1043         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1044
1045 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1046         OUTL(bktr, BKTR_SRESET, 0xf);
1047         OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1048
1049         return( 0 );
1050 }
1051
1052
1053 /*
1054  * tuner close handle,
1055  *  place holder for tuner specific operations on a close.
1056  */
1057 int
1058 tuner_close( bktr_ptr_t bktr )
1059 {
1060         bktr->tflags &= ~TUNER_OPEN;
1061
1062         /* mute the audio by switching the mux */
1063         set_audio( bktr, AUDIO_MUTE );
1064
1065         /* disable drivers on the GPIO port that control the MUXes */
1066         OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1067
1068         return( 0 );
1069 }
1070
1071 int
1072 vbi_close( bktr_ptr_t bktr )
1073 {
1074
1075         LOCK_VBI(bktr);
1076
1077         bktr->vbiflags &= ~VBI_OPEN;
1078
1079         UNLOCK_VBI(bktr);
1080
1081         return( 0 );
1082 }
1083
1084 /*
1085  *
1086  */
1087 int
1088 video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
1089 {
1090         int             status;
1091         int             count;
1092
1093
1094         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
1095                 return( ENOMEM );
1096
1097         if (bktr->flags & METEOR_CAP_MASK)
1098                 return( EIO );  /* already capturing */
1099
1100         OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1101
1102
1103         count = bktr->rows * bktr->cols * 
1104                 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1105
1106         if ((int) uio->uio_iov->iov_len < count)
1107                 return( EINVAL );
1108
1109         bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1110
1111         /* capture one frame */
1112         start_capture(bktr, METEOR_SINGLE);
1113         /* wait for capture to complete */
1114         OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1115         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1116         OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1117         OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1118                             BT848_INT_RISCI      |
1119                             BT848_INT_VSYNC      |
1120                             BT848_INT_FMTCHG);
1121
1122
1123         status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1124         if (!status)            /* successful capture */
1125                 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1126         else
1127                 printf ("%s: read: tsleep error %d\n",
1128                         bktr_name(bktr), status);
1129
1130         bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1131
1132         return( status );
1133 }
1134
1135 /*
1136  * Read VBI data from the vbi circular buffer
1137  * The buffer holds vbi data blocks which are the same size
1138  * vbiinsert is the position we will insert the next item into the buffer
1139  * vbistart is the actual position in the buffer we want to read from
1140  * vbisize is the exact number of bytes in the buffer left to read 
1141  */
1142 int
1143 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1144 {
1145         int             readsize, readsize2, start;
1146         int             status;
1147
1148         /*
1149          * XXX - vbi_read() should be protected against being re-entered
1150          * while it is unlocked for the uiomove.
1151          */
1152         LOCK_VBI(bktr);
1153
1154         while(bktr->vbisize == 0) {
1155                 if (ioflag & IO_NDELAY) {
1156                         status = EWOULDBLOCK;
1157                         goto out;
1158                 }
1159
1160                 bktr->vbi_read_blocked = TRUE;
1161 #ifdef USE_VBIMUTEX
1162                 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1163                     0))) {
1164                         goto out;
1165                 }
1166 #else
1167                 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1168                         goto out;
1169                 }
1170 #endif
1171         }
1172
1173         /* Now we have some data to give to the user */
1174                         
1175         /* We cannot read more bytes than there are in
1176          * the circular buffer
1177          */
1178         readsize = (int)uio->uio_iov->iov_len;
1179
1180         if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1181
1182         /* Check if we can read this number of bytes without having
1183          * to wrap around the circular buffer */
1184         if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1185                 /* We need to wrap around */
1186
1187                 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1188                 start =  bktr->vbistart;
1189                 UNLOCK_VBI(bktr);
1190                 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1191                 if (status == 0)
1192                         status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1193         } else {
1194                 UNLOCK_VBI(bktr);
1195                 /* We do not need to wrap around */
1196                 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1197         }
1198
1199         LOCK_VBI(bktr);
1200
1201         /* Update the number of bytes left to read */
1202         bktr->vbisize -= readsize;
1203
1204         /* Update vbistart */
1205         bktr->vbistart += readsize;
1206         bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1207
1208 out:
1209         UNLOCK_VBI(bktr);
1210
1211         return( status );
1212
1213 }
1214
1215
1216
1217 /*
1218  * video ioctls
1219  */
1220 int
1221 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1222 {
1223         volatile u_char         c_temp;
1224         unsigned int            temp;
1225         unsigned int            temp_iform;
1226         unsigned int            error;
1227         struct meteor_geomet    *geo;
1228         struct meteor_counts    *counts;
1229         struct meteor_video     *video;
1230         struct bktr_capture_area *cap_area;
1231         vm_offset_t             buf;
1232         int                     i;
1233         int                     sig;
1234         char                    char_temp;
1235
1236         switch ( cmd ) {
1237
1238         case BT848SCLIP: /* set clip region */
1239             bktr->max_clip_node = 0;
1240             memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1241
1242             for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1243                 if (bktr->clip_list[i].y_min ==  0 &&
1244                     bktr->clip_list[i].y_max == 0)
1245                     break;
1246             }
1247             bktr->max_clip_node = i;
1248
1249             /* make sure that the list contains a valid clip secquence */
1250             /* the clip rectangles should be sorted by x then by y as the
1251                second order sort key */
1252
1253             /* clip rectangle list is terminated by y_min and y_max set to 0 */
1254
1255             /* to disable clipping set  y_min and y_max to 0 in the first
1256                clip rectangle . The first clip rectangle is clip_list[0].
1257              */
1258
1259              
1260                 
1261             if (bktr->max_clip_node == 0 && 
1262                 (bktr->clip_list[0].y_min != 0 && 
1263                  bktr->clip_list[0].y_max != 0)) {
1264                 return EINVAL;
1265             }
1266
1267             for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1268                 if (bktr->clip_list[i].y_min == 0 &&
1269                     bktr->clip_list[i].y_max == 0) {
1270                     break;
1271                 }
1272                 if ( bktr->clip_list[i+1].y_min != 0 &&
1273                      bktr->clip_list[i+1].y_max != 0 &&
1274                      bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1275
1276                     bktr->max_clip_node = 0;
1277                     return (EINVAL);
1278
1279                  }
1280
1281                 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1282                     bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1283                     bktr->clip_list[i].x_min < 0 ||
1284                     bktr->clip_list[i].x_max < 0 || 
1285                     bktr->clip_list[i].y_min < 0 ||
1286                     bktr->clip_list[i].y_max < 0 ) {
1287                     bktr->max_clip_node = 0;
1288                     return (EINVAL);
1289                 }
1290             }
1291
1292             bktr->dma_prog_loaded = FALSE;
1293
1294             break;
1295
1296         case METEORSTATUS:      /* get Bt848 status */
1297                 c_temp = INB(bktr, BKTR_DSTATUS);
1298                 temp = 0;
1299                 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1300                 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1301                 *(u_short *)arg = temp;
1302                 break;
1303
1304         case BT848SFMT:         /* set input format */
1305                 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1306                 temp_iform = INB(bktr, BKTR_IFORM);
1307                 temp_iform &= ~BT848_IFORM_FORMAT;
1308                 temp_iform &= ~BT848_IFORM_XTSEL;
1309                 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1310                 switch( temp ) {
1311                 case BT848_IFORM_F_AUTO:
1312                         bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1313                         METEOR_AUTOMODE;
1314                         break;
1315
1316                 case BT848_IFORM_F_NTSCM:
1317                 case BT848_IFORM_F_NTSCJ:
1318                         bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1319                                 METEOR_NTSC;
1320                         OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1321                         OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1322                         bktr->format_params = temp;
1323                         break;
1324
1325                 case BT848_IFORM_F_PALBDGHI:
1326                 case BT848_IFORM_F_PALN:
1327                 case BT848_IFORM_F_SECAM:
1328                 case BT848_IFORM_F_RSVD:
1329                 case BT848_IFORM_F_PALM:
1330                         bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1331                                 METEOR_PAL;
1332                         OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1333                         OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1334                         bktr->format_params = temp;
1335                         break;
1336
1337                 }
1338                 bktr->dma_prog_loaded = FALSE;          
1339                 break;
1340
1341         case METEORSFMT:        /* set input format */
1342                 temp_iform = INB(bktr, BKTR_IFORM);
1343                 temp_iform &= ~BT848_IFORM_FORMAT;
1344                 temp_iform &= ~BT848_IFORM_XTSEL;
1345                 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1346                 case 0:         /* default */
1347                 case METEOR_FMT_NTSC:
1348                         bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1349                                 METEOR_NTSC;
1350                         OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM | 
1351                                          format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1352                         OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1353                         OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1354                         bktr->format_params = BT848_IFORM_F_NTSCM;
1355                         break;
1356
1357                 case METEOR_FMT_PAL:
1358                         bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1359                                 METEOR_PAL;
1360                         OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1361                                          format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1362                         OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1363                         OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1364                         bktr->format_params = BT848_IFORM_F_PALBDGHI;
1365                         break;
1366
1367                 case METEOR_FMT_AUTOMODE:
1368                         bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1369                                 METEOR_AUTOMODE;
1370                         OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1371                                          format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1372                         break;
1373
1374                 default:
1375                         return( EINVAL );
1376                 }
1377                 bktr->dma_prog_loaded = FALSE;          
1378                 break;
1379
1380         case METEORGFMT:        /* get input format */
1381                 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1382                 break;
1383
1384
1385         case BT848GFMT:         /* get input format */
1386                 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1387                 break;
1388  
1389         case METEORSCOUNT:      /* (re)set error counts */
1390                 counts = (struct meteor_counts *) arg;
1391                 bktr->fifo_errors = counts->fifo_errors;
1392                 bktr->dma_errors = counts->dma_errors;
1393                 bktr->frames_captured = counts->frames_captured;
1394                 bktr->even_fields_captured = counts->even_fields_captured;
1395                 bktr->odd_fields_captured = counts->odd_fields_captured;
1396                 break;
1397
1398         case METEORGCOUNT:      /* get error counts */
1399                 counts = (struct meteor_counts *) arg;
1400                 counts->fifo_errors = bktr->fifo_errors;
1401                 counts->dma_errors = bktr->dma_errors;
1402                 counts->frames_captured = bktr->frames_captured;
1403                 counts->even_fields_captured = bktr->even_fields_captured;
1404                 counts->odd_fields_captured = bktr->odd_fields_captured;
1405                 break;
1406
1407         case METEORGVIDEO:
1408                 video = (struct meteor_video *)arg;
1409                 video->addr = bktr->video.addr;
1410                 video->width = bktr->video.width;
1411                 video->banksize = bktr->video.banksize;
1412                 video->ramsize = bktr->video.ramsize;
1413                 break;
1414
1415         case METEORSVIDEO:
1416                 video = (struct meteor_video *)arg;
1417                 bktr->video.addr = video->addr;
1418                 bktr->video.width = video->width;
1419                 bktr->video.banksize = video->banksize;
1420                 bktr->video.ramsize = video->ramsize;
1421                 break;
1422
1423         case METEORSFPS:
1424                 set_fps(bktr, *(u_short *)arg);
1425                 break;
1426
1427         case METEORGFPS:
1428                 *(u_short *)arg = bktr->fps;
1429                 break;
1430
1431         case METEORSHUE:        /* set hue */
1432                 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1433                 break;
1434
1435         case METEORGHUE:        /* get hue */
1436                 *(u_char *)arg = INB(bktr, BKTR_HUE);
1437                 break;
1438
1439         case METEORSBRIG:       /* set brightness */
1440                 char_temp =    ( *(u_char *)arg & 0xff) - 128;
1441                 OUTB(bktr, BKTR_BRIGHT, char_temp);
1442                 
1443                 break;
1444
1445         case METEORGBRIG:       /* get brightness */
1446                 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1447                 break;
1448
1449         case METEORSCSAT:       /* set chroma saturation */
1450                 temp = (int)*(u_char *)arg;
1451
1452                 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1453                 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1454                 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1455                                      & ~(BT848_E_CONTROL_SAT_U_MSB
1456                                          | BT848_E_CONTROL_SAT_V_MSB));
1457                 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1458                                      & ~(BT848_O_CONTROL_SAT_U_MSB |
1459                                          BT848_O_CONTROL_SAT_V_MSB));
1460
1461                 if ( temp & BIT_SEVEN_HIGH ) {
1462                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1463                                              | (BT848_E_CONTROL_SAT_U_MSB
1464                                                 | BT848_E_CONTROL_SAT_V_MSB));
1465                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1466                                              | (BT848_O_CONTROL_SAT_U_MSB
1467                                                 | BT848_O_CONTROL_SAT_V_MSB));
1468                 }
1469                 break;
1470
1471         case METEORGCSAT:       /* get chroma saturation */
1472                 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1473                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1474                         temp |= BIT_SEVEN_HIGH;
1475                 *(u_char *)arg = (u_char)temp;
1476                 break;
1477
1478         case METEORSCONT:       /* set contrast */
1479                 temp = (int)*(u_char *)arg & 0xff;
1480                 temp <<= 1;
1481                 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1482                 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1483                 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1484                 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1485                         (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1486                 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1487                         (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1488                 break;
1489
1490         case METEORGCONT:       /* get contrast */
1491                 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1492                 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1493                 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1494                 break;
1495
1496         case BT848SCBUF:        /* set Clear-Buffer-on-start flag */
1497                 bktr->clr_on_start = (*(int *)arg != 0);
1498                 break;
1499
1500         case BT848GCBUF:        /* get Clear-Buffer-on-start flag */
1501                 *(int *)arg = (int) bktr->clr_on_start;
1502                 break;
1503
1504         case METEORSSIGNAL:
1505                 sig = *(int *)arg;
1506                 /* Historically, applications used METEOR_SIG_MODE_MASK
1507                  * to reset signal delivery.
1508                  */
1509                 if (sig == METEOR_SIG_MODE_MASK)
1510                         sig = 0;
1511                 if (sig < 0 || sig > _SIG_MAXSIG)
1512                         return (EINVAL);
1513                 bktr->signal = sig;
1514                 bktr->proc = sig ? td->td_proc : NULL;
1515                 break;
1516
1517         case METEORGSIGNAL:
1518                 *(int *)arg = bktr->signal;
1519                 break;
1520
1521         case METEORCAPTUR:
1522                 temp = bktr->flags;
1523                 switch (*(int *) arg) {
1524                 case METEOR_CAP_SINGLE:
1525
1526                         if (bktr->bigbuf==0)    /* no frame buffer allocated */
1527                                 return( ENOMEM );
1528                         /* already capturing */
1529                         if (temp & METEOR_CAP_MASK)
1530                                 return( EIO );
1531
1532
1533
1534                         start_capture(bktr, METEOR_SINGLE);
1535
1536                         /* wait for capture to complete */
1537                         OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1538                         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1539                         OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1540
1541                         OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1542                                             BT848_INT_RISCI      |
1543                                             BT848_INT_VSYNC      |
1544                                             BT848_INT_FMTCHG);
1545
1546                         OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1547                         error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1548                         if (error && (error != ERESTART)) {
1549                                 /*  Here if we didn't get complete frame  */
1550 #ifdef DIAGNOSTIC
1551                                 printf( "%s: ioctl: tsleep error %d %x\n",
1552                                         bktr_name(bktr), error,
1553                                         INL(bktr, BKTR_RISC_COUNT));
1554 #endif
1555
1556                                 /* stop dma */
1557                                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1558
1559                                 /* disable risc, leave fifo running */
1560                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1561                         }
1562
1563                         bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1564                         /* FIXME: should we set bt848->int_stat ??? */
1565                         break;
1566
1567                 case METEOR_CAP_CONTINOUS:
1568                         if (bktr->bigbuf==0)    /* no frame buffer allocated */
1569                                 return( ENOMEM );
1570                         /* already capturing */
1571                         if (temp & METEOR_CAP_MASK)
1572                             return( EIO );
1573
1574
1575                         start_capture(bktr, METEOR_CONTIN);
1576
1577                         /* Clear the interrypt status register */
1578                         OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1579
1580                         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1581                         OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1582                         OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1583
1584                         OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1585                                             BT848_INT_RISCI      |
1586                                             BT848_INT_VSYNC      |
1587                                             BT848_INT_FMTCHG);
1588 #ifdef BT848_DUMP
1589                         dump_bt848( bt848 );
1590 #endif
1591                         break;
1592                 
1593                 case METEOR_CAP_STOP_CONT:
1594                         if (bktr->flags & METEOR_CONTIN) {
1595                                 /* turn off capture */
1596                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1597                                 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1598                                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1599                                 bktr->flags &=
1600                                         ~(METEOR_CONTIN | METEOR_WANT_MASK);
1601
1602                         }
1603                 }
1604                 break;
1605
1606         case METEORSETGEO:
1607                 /* can't change parameters while capturing */
1608                 if (bktr->flags & METEOR_CAP_MASK)
1609                         return( EBUSY );
1610
1611
1612                 geo = (struct meteor_geomet *) arg;
1613
1614                 error = 0;
1615                 /* Either even or odd, if even & odd, then these a zero */
1616                 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1617                         (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1618                         printf( "%s: ioctl: Geometry odd or even only.\n",
1619                                 bktr_name(bktr));
1620                         return( EINVAL );
1621                 }
1622
1623                 /* set/clear even/odd flags */
1624                 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1625                         bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1626                 else
1627                         bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1628                 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1629                         bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1630                 else
1631                         bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1632
1633                 if (geo->columns <= 0) {
1634                         printf(
1635                         "%s: ioctl: %d: columns must be greater than zero.\n",
1636                                 bktr_name(bktr), geo->columns);
1637                         error = EINVAL;
1638                 }
1639                 else if ((geo->columns & 0x3fe) != geo->columns) {
1640                         printf(
1641                         "%s: ioctl: %d: columns too large or not even.\n",
1642                                 bktr_name(bktr), geo->columns);
1643                         error = EINVAL;
1644                 }
1645
1646                 if (geo->rows <= 0) {
1647                         printf(
1648                         "%s: ioctl: %d: rows must be greater than zero.\n",
1649                                 bktr_name(bktr), geo->rows);
1650                         error = EINVAL;
1651                 }
1652                 else if (((geo->rows & 0x7fe) != geo->rows) ||
1653                         ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1654                                 ((geo->rows & 0x3fe) != geo->rows)) ) {
1655                         printf(
1656                         "%s: ioctl: %d: rows too large or not even.\n",
1657                                 bktr_name(bktr), geo->rows);
1658                         error = EINVAL;
1659                 }
1660
1661                 if (geo->frames > 32) {
1662                         printf("%s: ioctl: too many frames.\n",
1663                                bktr_name(bktr));
1664
1665                         error = EINVAL;
1666                 }
1667
1668                 if (error)
1669                         return( error );
1670
1671                 bktr->dma_prog_loaded = FALSE;
1672                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1673
1674                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1675
1676                 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1677                         if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1678
1679                         /* meteor_mem structure for SYNC Capture */
1680                         if (geo->frames > 1) temp += PAGE_SIZE;
1681
1682                         temp = btoc(temp);
1683                         if ((int) temp > bktr->alloc_pages
1684                             && bktr->video.addr == 0) {
1685
1686                                 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1687                                 if (buf != 0) {
1688                                         kmem_free(kernel_map, bktr->bigbuf,
1689                                           (bktr->alloc_pages * PAGE_SIZE));
1690
1691                                         bktr->bigbuf = buf;
1692                                         bktr->alloc_pages = temp;
1693                                         if (bootverbose)
1694                                                 printf(
1695                                 "%s: ioctl: Allocating %d bytes\n",
1696                                                         bktr_name(bktr), temp*PAGE_SIZE);
1697                                 }
1698                                 else
1699                                         error = ENOMEM;
1700                         }
1701                 }
1702
1703                 if (error)
1704                         return error;
1705
1706                 bktr->rows = geo->rows;
1707                 bktr->cols = geo->columns;
1708                 bktr->frames = geo->frames;
1709
1710                 /*  Pixel format (if in meteor pixfmt compatibility mode)  */
1711                 if ( bktr->pixfmt_compat ) {
1712                         bktr->format = METEOR_GEO_YUV_422;
1713                         switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1714                         case 0:                 /* default */
1715                         case METEOR_GEO_RGB16:
1716                                     bktr->format = METEOR_GEO_RGB16;
1717                                     break;
1718                         case METEOR_GEO_RGB24:
1719                                     bktr->format = METEOR_GEO_RGB24;
1720                                     break;
1721                         case METEOR_GEO_YUV_422:
1722                                     bktr->format = METEOR_GEO_YUV_422;
1723                                     if (geo->oformat & METEOR_GEO_YUV_12) 
1724                                         bktr->format = METEOR_GEO_YUV_12;
1725                                     break;
1726                         case METEOR_GEO_YUV_PACKED:
1727                                     bktr->format = METEOR_GEO_YUV_PACKED;
1728                                     break;
1729                         }
1730                         bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1731                 }
1732
1733                 if (bktr->flags & METEOR_CAP_MASK) {
1734
1735                         if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1736                                 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1737                                 case METEOR_ONLY_ODD_FIELDS:
1738                                         bktr->flags |= METEOR_WANT_ODD;
1739                                         break;
1740                                 case METEOR_ONLY_EVEN_FIELDS:
1741                                         bktr->flags |= METEOR_WANT_EVEN;
1742                                         break;
1743                                 default:
1744                                         bktr->flags |= METEOR_WANT_MASK;
1745                                         break;
1746                                 }
1747
1748                                 start_capture(bktr, METEOR_CONTIN);
1749                                 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1750                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1751                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1752                                 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1753                                                     BT848_INT_VSYNC      |
1754                                                     BT848_INT_FMTCHG);
1755                         }
1756                 }
1757                 break;
1758         /* end of METEORSETGEO */
1759
1760         /* FIXME. The Capture Area currently has the following restrictions:
1761         GENERAL
1762          y_offset may need to be even in interlaced modes
1763         RGB24 - Interlaced mode
1764          x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1765          y_size must be greater than or equal to METEORSETGEO height (rows)
1766         RGB24 - Even Only (or Odd Only) mode
1767          x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1768          y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1769         YUV12 - Interlaced mode
1770          x_size must be greater than or equal to METEORSETGEO width (cols)
1771          y_size must be greater than or equal to METEORSETGEO height (rows)
1772         YUV12 - Even Only (or Odd Only) mode
1773          x_size must be greater than or equal to METEORSETGEO width (cols)
1774          y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1775         */
1776
1777         case BT848_SCAPAREA: /* set capture area of each video frame */
1778                 /* can't change parameters while capturing */
1779                 if (bktr->flags & METEOR_CAP_MASK)
1780                         return( EBUSY );
1781
1782                 cap_area = (struct bktr_capture_area *) arg;
1783                 bktr->capture_area_x_offset = cap_area->x_offset;
1784                 bktr->capture_area_y_offset = cap_area->y_offset;
1785                 bktr->capture_area_x_size   = cap_area->x_size;
1786                 bktr->capture_area_y_size   = cap_area->y_size;
1787                 bktr->capture_area_enabled  = TRUE;
1788  
1789                 bktr->dma_prog_loaded = FALSE;
1790                 break;
1791    
1792         case BT848_GCAPAREA: /* get capture area of each video frame */
1793                 cap_area = (struct bktr_capture_area *) arg;
1794                 if (bktr->capture_area_enabled == FALSE) {
1795                         cap_area->x_offset = 0;
1796                         cap_area->y_offset = 0;
1797                         cap_area->x_size   = format_params[
1798                                 bktr->format_params].scaled_hactive;
1799                         cap_area->y_size   = format_params[
1800                                 bktr->format_params].vactive;
1801                 } else {
1802                         cap_area->x_offset = bktr->capture_area_x_offset;
1803                         cap_area->y_offset = bktr->capture_area_y_offset;
1804                         cap_area->x_size   = bktr->capture_area_x_size;
1805                         cap_area->y_size   = bktr->capture_area_y_size;
1806                 }
1807                 break;
1808
1809         default:
1810                 return common_ioctl( bktr, cmd, arg );
1811         }
1812
1813         return( 0 );
1814 }
1815
1816 /*
1817  * tuner ioctls
1818  */
1819 int
1820 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1821 {
1822         int             tmp_int;
1823         unsigned int    temp, temp1;
1824         int             offset;
1825         int             count;
1826         u_char          *buf;
1827         u_long          par;
1828         u_char          write;
1829         int             i2c_addr;
1830         int             i2c_port;
1831         u_long          data;
1832
1833         switch ( cmd ) {
1834
1835         case REMOTE_GETKEY:
1836                 /* Read the last key pressed by the Remote Control */
1837                 if (bktr->remote_control == 0) return (EINVAL);
1838                 remote_read(bktr, (struct bktr_remote *)arg);
1839                 break;
1840
1841 #if defined( TUNER_AFC )
1842         case TVTUNER_SETAFC:
1843                 bktr->tuner.afc = (*(int *)arg != 0);
1844                 break;
1845
1846         case TVTUNER_GETAFC:
1847                 *(int *)arg = bktr->tuner.afc;
1848                 /* XXX Perhaps use another bit to indicate AFC success? */
1849                 break;
1850 #endif /* TUNER_AFC */
1851
1852         case TVTUNER_SETCHNL:
1853                 temp_mute( bktr, TRUE );
1854                 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1855                 if ( temp < 0 ) {
1856                         temp_mute( bktr, FALSE );
1857                         return( EINVAL );
1858                 }
1859                 *(unsigned long *)arg = temp;
1860
1861                 /* after every channel change, we must restart the MSP34xx */
1862                 /* audio chip to reselect NICAM STEREO or MONO audio */
1863                 if ( bktr->card.msp3400c )
1864                   msp_autodetect( bktr );
1865
1866                 /* after every channel change, we must restart the DPL35xx */
1867                 if ( bktr->card.dpl3518a )
1868                   dpl_autodetect( bktr );
1869
1870                 temp_mute( bktr, FALSE );
1871                 break;
1872
1873         case TVTUNER_GETCHNL:
1874                 *(unsigned long *)arg = bktr->tuner.channel;
1875                 break;
1876
1877         case TVTUNER_SETTYPE:
1878                 temp = *(unsigned long *)arg;
1879                 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1880                         return( EINVAL );
1881                 bktr->tuner.chnlset = temp;
1882                 break;
1883
1884         case TVTUNER_GETTYPE:
1885                 *(unsigned long *)arg = bktr->tuner.chnlset;
1886                 break;
1887
1888         case TVTUNER_GETSTATUS:
1889                 temp = get_tuner_status( bktr );
1890                 *(unsigned long *)arg = temp & 0xff;
1891                 break;
1892
1893         case TVTUNER_SETFREQ:
1894                 temp_mute( bktr, TRUE );
1895                 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1896                 temp_mute( bktr, FALSE );
1897                 if ( temp < 0 ) {
1898                         temp_mute( bktr, FALSE );
1899                         return( EINVAL );
1900                 }
1901                 *(unsigned long *)arg = temp;
1902
1903                 /* after every channel change, we must restart the MSP34xx */
1904                 /* audio chip to reselect NICAM STEREO or MONO audio */
1905                 if ( bktr->card.msp3400c )
1906                   msp_autodetect( bktr );
1907
1908                 /* after every channel change, we must restart the DPL35xx */
1909                 if ( bktr->card.dpl3518a )
1910                   dpl_autodetect( bktr );
1911
1912                 temp_mute( bktr, FALSE );
1913                 break;
1914
1915         case TVTUNER_GETFREQ:
1916                 *(unsigned long *)arg = bktr->tuner.frequency;
1917                 break;
1918
1919         case TVTUNER_GETCHNLSET:
1920                 return tuner_getchnlset((struct bktr_chnlset *)arg);
1921
1922         case BT848_SAUDIO:      /* set audio channel */
1923                 if ( set_audio( bktr, *(int*)arg ) < 0 )
1924                         return( EIO );
1925                 break;
1926
1927         /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1928         case BT848_SHUE:        /* set hue */
1929                 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1930                 break;
1931
1932         case BT848_GHUE:        /* get hue */
1933                 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1934                 break;
1935
1936         /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1937         case BT848_SBRIG:       /* set brightness */
1938                 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1939                 break;
1940
1941         case BT848_GBRIG:       /* get brightness */
1942                 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1943                 break;
1944
1945         /*  */
1946         case BT848_SCSAT:       /* set chroma saturation */
1947                 tmp_int = *(int*)arg;
1948
1949                 temp = INB(bktr, BKTR_E_CONTROL);
1950                 temp1 = INB(bktr, BKTR_O_CONTROL);
1951                 if ( tmp_int & BIT_EIGHT_HIGH ) {
1952                         temp |= (BT848_E_CONTROL_SAT_U_MSB |
1953                                  BT848_E_CONTROL_SAT_V_MSB);
1954                         temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1955                                   BT848_O_CONTROL_SAT_V_MSB);
1956                 }
1957                 else {
1958                         temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1959                                   BT848_E_CONTROL_SAT_V_MSB);
1960                         temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1961                                    BT848_O_CONTROL_SAT_V_MSB);
1962                 }
1963
1964                 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1965                 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1966                 OUTB(bktr, BKTR_E_CONTROL, temp);
1967                 OUTB(bktr, BKTR_O_CONTROL, temp1);
1968                 break;
1969
1970         case BT848_GCSAT:       /* get chroma saturation */
1971                 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1972                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1973                         tmp_int |= BIT_EIGHT_HIGH;
1974                 *(int*)arg = tmp_int;
1975                 break;
1976
1977         /*  */
1978         case BT848_SVSAT:       /* set chroma V saturation */
1979                 tmp_int = *(int*)arg;
1980
1981                 temp = INB(bktr, BKTR_E_CONTROL);
1982                 temp1 = INB(bktr, BKTR_O_CONTROL);
1983                 if ( tmp_int & BIT_EIGHT_HIGH) {
1984                         temp |= BT848_E_CONTROL_SAT_V_MSB;
1985                         temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1986                 }
1987                 else {
1988                         temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1989                         temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1990                 }
1991
1992                 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1993                 OUTB(bktr, BKTR_E_CONTROL, temp);
1994                 OUTB(bktr, BKTR_O_CONTROL, temp1);
1995                 break;
1996
1997         case BT848_GVSAT:       /* get chroma V saturation */
1998                 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1999                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2000                         tmp_int |= BIT_EIGHT_HIGH;
2001                 *(int*)arg = tmp_int;
2002                 break;
2003
2004         /*  */
2005         case BT848_SUSAT:       /* set chroma U saturation */
2006                 tmp_int = *(int*)arg;
2007
2008                 temp = INB(bktr, BKTR_E_CONTROL);
2009                 temp1 = INB(bktr, BKTR_O_CONTROL);
2010                 if ( tmp_int & BIT_EIGHT_HIGH ) {
2011                         temp |= BT848_E_CONTROL_SAT_U_MSB;
2012                         temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2013                 }
2014                 else {
2015                         temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2016                         temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2017                 }
2018
2019                 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2020                 OUTB(bktr, BKTR_E_CONTROL, temp);
2021                 OUTB(bktr, BKTR_O_CONTROL, temp1);
2022                 break;
2023
2024         case BT848_GUSAT:       /* get chroma U saturation */
2025                 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2026                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2027                         tmp_int |= BIT_EIGHT_HIGH;
2028                 *(int*)arg = tmp_int;
2029                 break;
2030
2031 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2032
2033         case BT848_SLNOTCH:     /* set luma notch */
2034                 tmp_int = (*(int *)arg & 0x7) << 5 ;
2035                 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2036                 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2037                 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2038                 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2039                 break;
2040
2041         case BT848_GLNOTCH:     /* get luma notch */
2042                 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2043                 break;
2044
2045
2046         /*  */
2047         case BT848_SCONT:       /* set contrast */
2048                 tmp_int = *(int*)arg;
2049
2050                 temp = INB(bktr, BKTR_E_CONTROL);
2051                 temp1 = INB(bktr, BKTR_O_CONTROL);
2052                 if ( tmp_int & BIT_EIGHT_HIGH ) {
2053                         temp |= BT848_E_CONTROL_CON_MSB;
2054                         temp1 |= BT848_O_CONTROL_CON_MSB;
2055                 }
2056                 else {
2057                         temp &= ~BT848_E_CONTROL_CON_MSB;
2058                         temp1 &= ~BT848_O_CONTROL_CON_MSB;
2059                 }
2060
2061                 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2062                 OUTB(bktr, BKTR_E_CONTROL, temp);
2063                 OUTB(bktr, BKTR_O_CONTROL, temp1);
2064                 break;
2065
2066         case BT848_GCONT:       /* get contrast */
2067                 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2068                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2069                         tmp_int |= BIT_EIGHT_HIGH;
2070                 *(int*)arg = tmp_int;
2071                 break;
2072
2073                 /*  FIXME:  SCBARS and CCBARS require a valid int *        */
2074                 /*    argument to succeed, but its not used; consider      */
2075                 /*    using the arg to store the on/off state so           */
2076                 /*    there's only one ioctl() needed to turn cbars on/off */
2077         case BT848_SCBARS:      /* set colorbar output */
2078                 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2079                 break;
2080
2081         case BT848_CCBARS:      /* clear colorbar output */
2082                 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2083                 break;
2084
2085         case BT848_GAUDIO:      /* get audio channel */
2086                 temp = bktr->audio_mux_select;
2087                 if ( bktr->audio_mute_state == TRUE )
2088                         temp |= AUDIO_MUTE;
2089                 *(int*)arg = temp;
2090                 break;
2091
2092         case BT848_SBTSC:       /* set audio channel */
2093                 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2094                         return( EIO );
2095                 break;
2096
2097         case BT848_WEEPROM:     /* write eeprom */
2098                 offset = (((struct eeProm *)arg)->offset);
2099                 count = (((struct eeProm *)arg)->count);
2100                 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2101                 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2102                         return( EIO );
2103                 break;
2104
2105         case BT848_REEPROM:     /* read eeprom */
2106                 offset = (((struct eeProm *)arg)->offset);
2107                 count = (((struct eeProm *)arg)->count);
2108                 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2109                 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2110                         return( EIO );
2111                 break;
2112
2113         case BT848_SIGNATURE:
2114                 offset = (((struct eeProm *)arg)->offset);
2115                 count = (((struct eeProm *)arg)->count);
2116                 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2117                 if ( signCard( bktr, offset, count, buf ) < 0 )
2118                         return( EIO );
2119                 break;
2120
2121         /* Ioctl's for direct gpio access */
2122 #ifdef BKTR_GPIO_ACCESS
2123         case BT848_GPIO_GET_EN:
2124                 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2125                 break;
2126
2127         case BT848_GPIO_SET_EN:
2128                 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2129                 break;
2130
2131         case BT848_GPIO_GET_DATA:
2132                 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2133                 break;
2134
2135         case BT848_GPIO_SET_DATA:
2136                 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2137                 break;
2138 #endif /* BKTR_GPIO_ACCESS */
2139
2140         /* Ioctl's for running the tuner device in radio mode           */
2141
2142         case RADIO_GETMODE:
2143             *(unsigned char *)arg = bktr->tuner.radio_mode;
2144             break;
2145
2146         case RADIO_SETMODE:
2147             bktr->tuner.radio_mode = *(unsigned char *)arg;
2148             break;
2149
2150         case RADIO_GETFREQ:
2151             *(unsigned long *)arg = bktr->tuner.frequency;
2152             break;
2153
2154         case RADIO_SETFREQ:
2155             /* The argument to this ioctl is NOT freq*16. It is
2156             ** freq*100.
2157             */
2158
2159             temp=(int)*(unsigned long *)arg;
2160
2161 #ifdef BKTR_RADIO_DEBUG
2162             printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2163                    (int)*(unsigned long *)arg, temp);
2164 #endif
2165
2166 #ifndef BKTR_RADIO_NOFREQCHECK
2167             /* According to the spec. sheet the band: 87.5MHz-108MHz    */
2168             /* is supported.                                            */
2169             if(temp<8750 || temp>10800) {
2170               printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2171               return(EINVAL);
2172               }
2173 #endif
2174             temp_mute( bktr, TRUE );
2175             temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2176             temp_mute( bktr, FALSE );
2177 #ifdef BKTR_RADIO_DEBUG
2178   if(temp)
2179     printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2180 #endif
2181             if ( temp < 0 )
2182                     return( EINVAL );
2183             *(unsigned long *)arg = temp;
2184             break;
2185
2186         /* Luigi's I2CWR ioctl */ 
2187         case BT848_I2CWR:
2188                 par = *(u_long *)arg;
2189                 write = (par >> 24) & 0xff ;
2190                 i2c_addr = (par >> 16) & 0xff ;
2191                 i2c_port = (par >> 8) & 0xff ;
2192                 data = (par) & 0xff ;
2193  
2194                 if (write) { 
2195                         i2cWrite( bktr, i2c_addr, i2c_port, data);
2196                 } else {
2197                         data = i2cRead( bktr, i2c_addr);
2198                 }
2199                 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2200                 break;
2201
2202
2203 #ifdef BT848_MSP_READ
2204         /* I2C ioctls to allow userland access to the MSP chip */
2205         case BT848_MSP_READ:
2206                 {
2207                 struct bktr_msp_control *msp;
2208                 msp = (struct bktr_msp_control *) arg;
2209                 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2210                                          msp->function, msp->address);
2211                 break;
2212                 }
2213
2214         case BT848_MSP_WRITE:
2215                 {
2216                 struct bktr_msp_control *msp;
2217                 msp = (struct bktr_msp_control *) arg;
2218                 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2219                              msp->address, msp->data );
2220                 break;
2221                 }
2222
2223         case BT848_MSP_RESET:
2224                 msp_dpl_reset(bktr, bktr->msp_addr);
2225                 break;
2226 #endif
2227
2228         default:
2229                 return common_ioctl( bktr, cmd, arg );
2230         }
2231
2232         return( 0 );
2233 }
2234
2235
2236 /*
2237  * common ioctls
2238  */
2239 static int
2240 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2241 {
2242         int                           pixfmt;
2243         unsigned int                  temp;
2244         struct meteor_pixfmt          *pf_pub;
2245
2246         switch (cmd) {
2247
2248         case METEORSINPUT:      /* set input device */
2249                 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2250                 /* On the original bt848 boards, */
2251                 /*   Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2252                 /* On the Hauppauge bt878 boards, */
2253                 /*   Tuner is MUX0, RCA is MUX3 */
2254                 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2255                 /* stick with this system in our Meteor Emulation */
2256
2257                 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2258
2259                 /* this is the RCA video input */
2260                 case 0:         /* default */
2261                 case METEOR_INPUT_DEV0:
2262                   /* METEOR_INPUT_DEV_RCA: */
2263                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2264                           | METEOR_DEV0;
2265                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2266                                          & ~BT848_IFORM_MUXSEL);
2267
2268                         /* work around for new Hauppauge 878 cards */
2269                         if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2270                                 (bktr->id==BROOKTREE_878 ||
2271                                  bktr->id==BROOKTREE_879) )
2272                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2273                         else
2274                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2275
2276                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2277                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2278                         set_audio( bktr, AUDIO_EXTERN );
2279                         break;
2280
2281                 /* this is the tuner input */
2282                 case METEOR_INPUT_DEV1:
2283                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2284                                 | METEOR_DEV1;
2285                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2286                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2287                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2288                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2289                         set_audio( bktr, AUDIO_TUNER );
2290                         break;
2291
2292                 /* this is the S-VHS input, but with a composite camera */
2293                 case METEOR_INPUT_DEV2:
2294                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2295                                 | METEOR_DEV2;
2296                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2297                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2298                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2299                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2300                         set_audio( bktr, AUDIO_EXTERN );
2301                         break;
2302
2303                 /* this is the S-VHS input */
2304                 case METEOR_INPUT_DEV_SVIDEO:
2305                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2306                                 | METEOR_DEV_SVIDEO;
2307                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2308                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2309                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2310                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2311                         set_audio( bktr, AUDIO_EXTERN );
2312                         break;
2313
2314                 case METEOR_INPUT_DEV3:
2315                   if ((bktr->id == BROOKTREE_848A) ||
2316                       (bktr->id == BROOKTREE_849A) ||
2317                       (bktr->id == BROOKTREE_878) ||
2318                       (bktr->id == BROOKTREE_879) ) {
2319                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2320                                 | METEOR_DEV3;
2321                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2322
2323                         /* work around for new Hauppauge 878 cards */
2324                         if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2325                                 (bktr->id==BROOKTREE_878 ||
2326                                  bktr->id==BROOKTREE_879) )
2327                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2328                         else
2329                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2330
2331                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2332                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2333                         set_audio( bktr, AUDIO_EXTERN );
2334
2335                         break;
2336                   }     
2337
2338                 default:
2339                         return( EINVAL );
2340                 }
2341                 break;
2342
2343         case METEORGINPUT:      /* get input device */
2344                 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2345                 break;
2346
2347         case METEORSACTPIXFMT:
2348                 if (( *(int *)arg < 0 ) ||
2349                     ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2350                         return( EINVAL );
2351
2352                 bktr->pixfmt          = *(int *)arg;
2353                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2354                      | pixfmt_swap_flags( bktr->pixfmt ));
2355                 bktr->pixfmt_compat   = FALSE;
2356                 break;
2357         
2358         case METEORGACTPIXFMT:
2359                 *(int *)arg = bktr->pixfmt;
2360                 break;
2361
2362         case METEORGSUPPIXFMT :
2363                 pf_pub = (struct meteor_pixfmt *)arg;
2364                 pixfmt = pf_pub->index;
2365
2366                 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2367                         return( EINVAL );
2368
2369                 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public, 
2370                         sizeof( *pf_pub ) );
2371
2372                 /*  Patch in our format index  */
2373                 pf_pub->index       = pixfmt;
2374                 break;
2375
2376 #if defined( STATUS_SUM )
2377         case BT848_GSTATUS:     /* reap status */
2378                 {
2379                 crit_enter();
2380                 temp = status_sum;
2381                 status_sum = 0;
2382                 crit_exit();
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 uint32_t **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 uint32_t       target_buffer, buffer, target,width;
2646         volatile uint32_t       pitch;
2647         volatile uint32_t       *dma_prog;      /* DMA prog is an array of 
2648                                                 32 bit RISC instructions */
2649         volatile uint32_t       *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 = (uint32_t *) 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 uint32_t **) &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 uint32_t **) &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 uint32_t **) &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 uint32_t **) &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 uint32_t **) &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 uint32_t **) &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 uint32_t               target_buffer, buffer, target,width;
2828         volatile uint32_t       pitch;
2829         volatile  uint32_t      *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 = (uint32_t *) bktr->dma_prog;
2858
2859         /* Construct Write */
2860
2861         if (bktr->video.addr) {
2862                 target_buffer = (uint32_t) bktr->video.addr;
2863                 pitch = bktr->video.width;
2864         }
2865         else {
2866                 target_buffer = (uint32_t) 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 uint32_t **) &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 uint32_t **) &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 uint32_t **) &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++ = (uint32_t ) 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++ = (uint32_t ) 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 = (uint32_t ) vtophys(bktr->odd_dma_prog);
2931                 break;
2932         }
2933
2934         if (interlace == 2) {
2935
2936                 target_buffer = buffer + pitch; 
2937
2938                 dma_prog = (uint32_t *) 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 uint32_t **) &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 uint32_t **) &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 uint32_t **) &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++ = (uint32_t ) 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 uint32_t       target_buffer, buffer;
2993         volatile  uint32_t      *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 = (uint32_t *) 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 = (uint32_t) bktr->video.addr;
3019         else
3020                 target_buffer = (uint32_t) 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++ = (uint32_t) 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++ = (uint32_t) 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 = (uint32_t) vtophys(bktr->odd_dma_prog);
3063                 break;
3064         }
3065
3066         if (interlace == 2) {
3067
3068                 target_buffer =  (uint32_t) buffer + cols*2;
3069
3070                 dma_prog = (uint32_t *) 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++ = (uint32_t) vtophys(bktr->dma_prog);
3090
3091         *dma_prog++ = OP_JUMP;
3092         *dma_prog++ = (uint32_t) 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 uint32_t       target_buffer, t1, buffer;
3107         volatile uint32_t       *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 = (uint32_t*) 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 = (uint32_t) bktr->video.addr;
3137         else
3138                 target_buffer = (uint32_t) 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++ = (uint32_t) 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++ = (uint32_t) 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 = (uint32_t) vtophys(bktr->odd_dma_prog);
3180                 break;
3181         }
3182
3183         if (interlace == 2) {
3184
3185                 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3186
3187                 target_buffer  = (uint32_t) 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++ = (uint32_t) 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 uint32_t       target_buffer, t1, buffer;
3221         volatile uint32_t       *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 = (uint32_t *) 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 = (uint32_t) bktr->video.addr;
3238         else
3239                 target_buffer = (uint32_t) 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++ = (uint32_t) 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++ = (uint32_t) 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 = (uint32_t) vtophys(bktr->odd_dma_prog);
3283                 break;
3284         }
3285
3286         if (interlace == 2) {
3287
3288                 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3289
3290                 target_buffer  = (uint32_t) 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++ = (uint32_t) 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.iicbb)
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);
3819         iicbus_write_byte(IICBUS(bktr), addr_l, 0);