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