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