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