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