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