Merge branch 'vendor/BYACC'
[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, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2719                               Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2720         
2721                     } else {
2722                         while(getline(bktr, i)) {
2723                             if (bktr->y != bktr->y2 ) {
2724                                 split(bktr, &dma_prog,
2725                                       bktr->y2 - bktr->y, OP_WRITE,
2726                                       Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2727                             }
2728                             if (bktr->yclip != bktr->yclip2 ) {
2729                                 split(bktr,&dma_prog,
2730                                       bktr->yclip2 - bktr->yclip,
2731                                       OP_SKIP,
2732                                       Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2733                             }
2734                         }
2735                         
2736                     }
2737         
2738                     target_buffer += interlace * pitch;
2739         
2740                 }
2741
2742         } /* end if */
2743
2744         /* Grab the Even field */
2745         /* Look for the VRO, end of Odd field, marker */
2746         *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2747         *dma_prog++ = 0;  /* NULL WORD */
2748
2749         /* store the VBI data */
2750         /* look for sync with packed data */
2751         *dma_prog++ = OP_SYNC | BKTR_FM1;
2752         *dma_prog++ = 0;
2753         for(i = 0; i < vbilines; i++) {
2754                 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2755                 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2756                                 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2757         }
2758
2759         /* store the video image */
2760         if (i_flag == 1) /*Even Only*/
2761                 target_buffer = buffer;
2762         if (i_flag == 3) /*interlaced*/
2763                 target_buffer = buffer+pitch;
2764
2765
2766         if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2767                 /* look for sync with packed data */
2768                 *dma_prog++ = OP_SYNC | BKTR_FM1;
2769                 *dma_prog++ = 0;  /* NULL WORD */
2770                 width = cols;
2771                 for (i = 0; i < (rows/interlace); i++) {
2772                     target = target_buffer;
2773                     if ( notclipped(bktr, i, width)) {
2774                         split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2775                               Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2776                     } else {
2777                         while(getline(bktr, i)) {
2778                             if (bktr->y != bktr->y2 ) {
2779                                 split(bktr, &dma_prog,
2780                                       bktr->y2 - bktr->y, OP_WRITE,
2781                                       Bpp, (volatile u_char **)(uintptr_t)&target,
2782                                       cols);
2783                             }   
2784                             if (bktr->yclip != bktr->yclip2 ) {
2785                                 split(bktr, &dma_prog,
2786                                       bktr->yclip2 - bktr->yclip, OP_SKIP,
2787                                       Bpp, (volatile u_char **)(uintptr_t) &target,  cols);
2788                             }   
2789
2790                         }       
2791
2792                     }
2793
2794                     target_buffer += interlace * pitch;
2795
2796                 }
2797         }
2798
2799         /* Look for end of 'Even Field' */
2800         *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2801         *dma_prog++ = 0;  /* NULL WORD */
2802
2803         *dma_prog++ = OP_JUMP ;
2804         *dma_prog++ = (u_long ) vtophys(loop_point) ;
2805         *dma_prog++ = 0;  /* NULL WORD */
2806
2807 }
2808
2809
2810
2811
2812 static void
2813 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2814 {
2815         int                     i;
2816         volatile uint32_t               target_buffer, buffer, target,width;
2817         volatile uint32_t       pitch;
2818         volatile  uint32_t      *dma_prog;
2819         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2820         u_int                   Bpp = pf_int->public.Bpp;
2821
2822         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2823         OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2824         OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2825         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2826
2827         OUTB(bktr, BKTR_OFORM, 0x00);
2828
2829         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2830         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2831         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2832         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2833
2834         /* disable gamma correction removal */
2835         OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2836
2837         if (cols > 385 ) {
2838             OUTB(bktr, BKTR_E_VTC, 0);
2839             OUTB(bktr, BKTR_O_VTC, 0);
2840         } else {
2841             OUTB(bktr, BKTR_E_VTC, 1);
2842             OUTB(bktr, BKTR_O_VTC, 1);
2843         }
2844         bktr->capcontrol = 3 << 2 |  3;
2845
2846         dma_prog = (uint32_t *) bktr->dma_prog;
2847
2848         /* Construct Write */
2849
2850         if (bktr->video.addr) {
2851                 target_buffer = (uint32_t) bktr->video.addr;
2852                 pitch = bktr->video.width;
2853         }
2854         else {
2855                 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2856                 pitch = cols*Bpp;
2857         }
2858
2859         buffer = target_buffer;
2860
2861         /* contruct sync : for video packet format */
2862         *dma_prog++ = OP_SYNC  | BKTR_RESYNC | BKTR_FM1;
2863
2864         /* sync, mode indicator packed data */
2865         *dma_prog++ = 0;  /* NULL WORD */
2866         width = cols;
2867         for (i = 0; i < (rows/interlace); i++) {
2868             target = target_buffer;
2869             if ( notclipped(bktr, i, width)) {
2870                 split(bktr, &dma_prog,
2871                       bktr->y2 - bktr->y, OP_WRITE,
2872                       Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2873
2874             } else {
2875                 while(getline(bktr, i)) {
2876                     if (bktr->y != bktr->y2 ) {
2877                         split(bktr, &dma_prog,
2878                               bktr->y2 - bktr->y, OP_WRITE,
2879                               Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2880                     }
2881                     if (bktr->yclip != bktr->yclip2 ) {
2882                         split(bktr,&dma_prog,
2883                               bktr->yclip2 - bktr->yclip,
2884                               OP_SKIP,
2885                               Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2886                     }
2887                 }
2888
2889             }
2890
2891             target_buffer += interlace * pitch;
2892
2893         }
2894
2895         switch (i_flag) {
2896         case 1:
2897                 /* sync vre */
2898                 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2899                 *dma_prog++ = 0;  /* NULL WORD */
2900
2901                 *dma_prog++ = OP_JUMP;
2902                 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2903                 return;
2904
2905         case 2:
2906                 /* sync vro */
2907                 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2908                 *dma_prog++ = 0;  /* NULL WORD */
2909
2910                 *dma_prog++ = OP_JUMP;
2911                 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2912                 return;
2913
2914         case 3:
2915                 /* sync vro */
2916                 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2917                 *dma_prog++ = 0;  /* NULL WORD */
2918                 *dma_prog++ = OP_JUMP;
2919                 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
2920                 break;
2921         }
2922
2923         if (interlace == 2) {
2924
2925                 target_buffer = buffer + pitch; 
2926
2927                 dma_prog = (uint32_t *) bktr->odd_dma_prog;
2928
2929                 /* sync vre IRQ bit */
2930                 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2931                 *dma_prog++ = 0;  /* NULL WORD */
2932                 width = cols;
2933                 for (i = 0; i < (rows/interlace); i++) {
2934                     target = target_buffer;
2935                     if ( notclipped(bktr, i, width)) {
2936                         split(bktr, &dma_prog,
2937                               bktr->y2 - bktr->y, OP_WRITE,
2938                               Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2939                     } else {
2940                         while(getline(bktr, i)) {
2941                             if (bktr->y != bktr->y2 ) {
2942                                 split(bktr, &dma_prog,
2943                                       bktr->y2 - bktr->y, OP_WRITE,
2944                                       Bpp, (volatile u_char **)(uintptr_t)&target,
2945                                       cols);
2946                             }   
2947                             if (bktr->yclip != bktr->yclip2 ) {
2948                                 split(bktr, &dma_prog,
2949                                       bktr->yclip2 - bktr->yclip, OP_SKIP,
2950                                       Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
2951                             }   
2952
2953                         }       
2954
2955                     }
2956
2957                     target_buffer += interlace * pitch;
2958
2959                 }
2960         }
2961
2962         /* sync vre IRQ bit */
2963         *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2964         *dma_prog++ = 0;  /* NULL WORD */
2965         *dma_prog++ = OP_JUMP ;
2966         *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
2967         *dma_prog++ = 0;  /* NULL WORD */
2968 }
2969
2970
2971 /*
2972  * 
2973  */
2974 static void
2975 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2976               int cols, int rows, int interlace )
2977 {
2978         int                     i;
2979         volatile unsigned int   inst;
2980         volatile unsigned int   inst3;
2981         volatile uint32_t       target_buffer, buffer;
2982         volatile  uint32_t      *dma_prog;
2983         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2984         int                     b;
2985
2986         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2987
2988         OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
2989         OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2990
2991         OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
2992         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2993
2994         bktr->capcontrol =   1 << 6 | 1 << 4 | 1 << 2 | 3;
2995         bktr->capcontrol = 3 << 2 |  3;
2996
2997         dma_prog = (uint32_t *) bktr->dma_prog;
2998
2999         /* Construct Write */
3000     
3001         /* write , sol, eol */
3002         inst = OP_WRITE  | OP_SOL | (cols);
3003         /* write , sol, eol */
3004         inst3 = OP_WRITE | OP_EOL | (cols);
3005
3006         if (bktr->video.addr)
3007                 target_buffer = (uint32_t) bktr->video.addr;
3008         else
3009                 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3010
3011         buffer = target_buffer;
3012
3013         /* contruct sync : for video packet format */
3014         /* sync, mode indicator packed data */
3015         *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3016         *dma_prog++ = 0;  /* NULL WORD */
3017
3018         b = cols;
3019
3020         for (i = 0; i < (rows/interlace); i++) {
3021                 *dma_prog++ = inst;
3022                 *dma_prog++ = target_buffer;
3023                 *dma_prog++ = inst3;
3024                 *dma_prog++ = target_buffer + b; 
3025                 target_buffer += interlace*(cols * 2);
3026         }
3027
3028         switch (i_flag) {
3029         case 1:
3030                 /* sync vre */
3031                 *dma_prog++ = OP_SYNC  | BKTR_GEN_IRQ | BKTR_VRE;
3032                 *dma_prog++ = 0;  /* NULL WORD */
3033
3034                 *dma_prog++ = OP_JUMP;
3035                 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3036                 return;
3037
3038         case 2:
3039                 /* sync vro */
3040                 *dma_prog++ = OP_SYNC  | BKTR_GEN_IRQ | BKTR_VRO;
3041                 *dma_prog++ = 0;  /* NULL WORD */
3042                 *dma_prog++ = OP_JUMP;
3043                 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3044                 return;
3045
3046         case 3:
3047                 /* sync vro */
3048                 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3049                 *dma_prog++ = 0;  /* NULL WORD */
3050                 *dma_prog++ = OP_JUMP  ;
3051                 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3052                 break;
3053         }
3054
3055         if (interlace == 2) {
3056
3057                 target_buffer =  (uint32_t) buffer + cols*2;
3058
3059                 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3060
3061                 /* sync vre */
3062                 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3063                 *dma_prog++ = 0;  /* NULL WORD */
3064
3065                 for (i = 0; i < (rows/interlace) ; i++) {
3066                         *dma_prog++ = inst;
3067                         *dma_prog++ = target_buffer;
3068                         *dma_prog++ = inst3;
3069                         *dma_prog++ = target_buffer + b;
3070                         target_buffer += interlace * ( cols*2);
3071                 }
3072         }
3073
3074         /* sync vro IRQ bit */
3075         *dma_prog++ = OP_SYNC   |  BKTR_GEN_IRQ  | BKTR_RESYNC |  BKTR_VRE;
3076         *dma_prog++ = 0;  /* NULL WORD */
3077         *dma_prog++ = OP_JUMP ;
3078         *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3079
3080         *dma_prog++ = OP_JUMP;
3081         *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3082         *dma_prog++ = 0;  /* NULL WORD */
3083 }
3084
3085
3086 /*
3087  * 
3088  */
3089 static void
3090 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3091              int cols, int rows, int interlace ){
3092
3093         int                     i;
3094         volatile unsigned int   inst;
3095         volatile uint32_t       target_buffer, t1, buffer;
3096         volatile uint32_t       *dma_prog;
3097         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3098
3099         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3100
3101         dma_prog = (uint32_t*) bktr->dma_prog;
3102
3103         bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
3104
3105         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3106         OUTB(bktr, BKTR_OFORM, 0x00);
3107
3108         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3109         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3110
3111         OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC);      /* chroma agc enable */
3112         OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3113
3114         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3115         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3116         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3117         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3118
3119         /* disable gamma correction removal */
3120         OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3121
3122         /* Construct Write */
3123         inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols); 
3124         if (bktr->video.addr)
3125                 target_buffer = (uint32_t) bktr->video.addr;
3126         else
3127                 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3128     
3129         buffer = target_buffer;
3130
3131         t1 = buffer;
3132
3133         /* contruct sync : for video packet format */
3134         *dma_prog++ = OP_SYNC  | 1 << 15 |      BKTR_FM3; /*sync, mode indicator packed data*/
3135         *dma_prog++ = 0;  /* NULL WORD */
3136
3137         for (i = 0; i < (rows/interlace ) ; i++) {
3138                 *dma_prog++ = inst;
3139                 *dma_prog++ = cols/2 | cols/2 << 16;
3140                 *dma_prog++ = target_buffer;
3141                 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3142                 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3143                 target_buffer += interlace*cols;
3144         }
3145
3146         switch (i_flag) {
3147         case 1:
3148                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRE;  /*sync vre*/
3149                 *dma_prog++ = 0;  /* NULL WORD */
3150
3151                 *dma_prog++ = OP_JUMP ;
3152                 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3153                 return;
3154
3155         case 2:
3156                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRO;  /*sync vre*/
3157                 *dma_prog++ = 0;  /* NULL WORD */
3158
3159                 *dma_prog++ = OP_JUMP;
3160                 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3161                 return;
3162
3163         case 3:
3164                 *dma_prog++ = OP_SYNC   | 1 << 24 |  1 << 15 |   BKTR_VRO; 
3165                 *dma_prog++ = 0;  /* NULL WORD */
3166
3167                 *dma_prog++ = OP_JUMP  ;
3168                 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3169                 break;
3170         }
3171
3172         if (interlace == 2) {
3173
3174                 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3175
3176                 target_buffer  = (uint32_t) buffer + cols;
3177                 t1 = buffer + cols/2;
3178                 *dma_prog++ = OP_SYNC   |   1 << 15 | BKTR_FM3; 
3179                 *dma_prog++ = 0;  /* NULL WORD */
3180
3181                 for (i = 0; i < (rows/interlace )  ; i++) {
3182                         *dma_prog++ = inst;
3183                         *dma_prog++ = cols/2 | cols/2 << 16;
3184                         *dma_prog++ = target_buffer;
3185                         *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3186                         *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3187                         target_buffer += interlace*cols;
3188                 }
3189         }
3190     
3191         *dma_prog++ = OP_SYNC  | 1 << 24 | 1 << 15 |   BKTR_VRE; 
3192         *dma_prog++ = 0;  /* NULL WORD */
3193         *dma_prog++ = OP_JUMP ;
3194         *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3195         *dma_prog++ = 0;  /* NULL WORD */
3196 }
3197
3198
3199 /*
3200  * 
3201  */
3202 static void
3203 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3204              int cols, int rows, int interlace ){
3205
3206         int                     i;
3207         volatile unsigned int   inst;
3208         volatile unsigned int   inst1;
3209         volatile uint32_t       target_buffer, t1, buffer;
3210         volatile uint32_t       *dma_prog;
3211         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3212
3213         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3214
3215         dma_prog = (uint32_t *) bktr->dma_prog;
3216
3217         bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
3218
3219         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3220         OUTB(bktr, BKTR_OFORM, 0x0);
3221  
3222         /* Construct Write */
3223         inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols); 
3224         inst1  = OP_WRITES123  | OP_SOL | OP_EOL |  (cols); 
3225         if (bktr->video.addr)
3226                 target_buffer = (uint32_t) bktr->video.addr;
3227         else
3228                 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3229      
3230         buffer = target_buffer;
3231         t1 = buffer;
3232  
3233         *dma_prog++ = OP_SYNC  | 1 << 15 |      BKTR_FM3; /*sync, mode indicator packed data*/
3234         *dma_prog++ = 0;  /* NULL WORD */
3235                
3236         for (i = 0; i < (rows/interlace )/2 ; i++) {
3237                 *dma_prog++ = inst;
3238                 *dma_prog++ = cols/2 | (cols/2 << 16);
3239                 *dma_prog++ = target_buffer;
3240                 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3241                 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3242                 target_buffer += interlace*cols;
3243                 *dma_prog++ = inst1;
3244                 *dma_prog++ = cols/2 | (cols/2 << 16);
3245                 *dma_prog++ = target_buffer;
3246                 target_buffer += interlace*cols;
3247  
3248         }
3249  
3250         switch (i_flag) {
3251         case 1:
3252                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRE;  /*sync vre*/
3253                 *dma_prog++ = 0;  /* NULL WORD */
3254
3255                 *dma_prog++ = OP_JUMP;
3256                 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3257                 return;
3258
3259         case 2:
3260                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRO;  /*sync vro*/
3261                 *dma_prog++ = 0;  /* NULL WORD */
3262
3263                 *dma_prog++ = OP_JUMP;
3264                 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3265                 return;
3266  
3267         case 3:
3268                 *dma_prog++ = OP_SYNC |  1 << 24 | 1 << 15 | BKTR_VRO;
3269                 *dma_prog++ = 0;  /* NULL WORD */
3270                 *dma_prog++ = OP_JUMP ;
3271                 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3272                 break;
3273         }
3274
3275         if (interlace == 2) {
3276
3277                 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3278
3279                 target_buffer  = (uint32_t) buffer + cols;
3280                 t1 = buffer + cols/2;
3281                 *dma_prog++ = OP_SYNC   | 1 << 15 | BKTR_FM3; 
3282                 *dma_prog++ = 0;  /* NULL WORD */
3283
3284                 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3285                     *dma_prog++ = inst;
3286                     *dma_prog++ = cols/2 | (cols/2 << 16);
3287                     *dma_prog++ = target_buffer;
3288                     *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3289                     *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3290                     target_buffer += interlace*cols;
3291                     *dma_prog++ = inst1;
3292                     *dma_prog++ = cols/2 | (cols/2 << 16);
3293                     *dma_prog++ = target_buffer;
3294                     target_buffer += interlace*cols;
3295
3296                 }       
3297
3298         
3299         }
3300     
3301         *dma_prog++ = OP_SYNC |  1 << 24 | 1 << 15 | BKTR_VRE;
3302         *dma_prog++ = 0;  /* NULL WORD */
3303         *dma_prog++ = OP_JUMP;
3304         *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3305         *dma_prog++ = 0;  /* NULL WORD */
3306 }
3307   
3308
3309
3310 /*
3311  * 
3312  */
3313 static void
3314 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3315 {
3316         int                     rows, cols,  interlace;
3317         int                     tmp_int;
3318         unsigned int            temp;   
3319         struct format_params    *fp;
3320         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3321         
3322
3323         fp = &format_params[bktr->format_params];
3324
3325         OUTL(bktr, BKTR_INT_MASK,  ALL_INTS_DISABLED);
3326
3327         /* disable FIFO & RISC, leave other bits alone */
3328         OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3329
3330         /* set video parameters */
3331         if (bktr->capture_area_enabled)
3332           temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3333                   / fp->scaled_htotal / bktr->cols) -  4096;
3334         else
3335           temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3336                   / fp->scaled_htotal / bktr->cols) -  4096;
3337
3338         /* kprintf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3339         OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3340         OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3341         OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3342         OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3343  
3344         /* horizontal active */
3345         temp = bktr->cols;
3346         /* kprintf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3347         OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3348         OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3349         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3350         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3351         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3352         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3353  
3354         /* horizontal delay */
3355         if (bktr->capture_area_enabled)
3356           temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3357                  * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3358         else
3359           temp = (fp->hdelay * bktr->cols) / fp->hactive;
3360
3361         temp = temp & 0x3fe;
3362
3363         /* kprintf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3364         OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3365         OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3366         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3367         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3368         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3369         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3370
3371         /* vertical scale */
3372
3373         if (bktr->capture_area_enabled) {
3374           if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3375               bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3376             tmp_int = 65536 -
3377             (((bktr->capture_area_y_size  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3378           else {
3379             tmp_int = 65536 -
3380             (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3381           }
3382         } else {
3383           if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3384               bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3385             tmp_int = 65536 -
3386             (((fp->vactive  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3387           else {
3388             tmp_int = 65536  -
3389             (((fp->vactive * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3390           }
3391         }
3392
3393         tmp_int &= 0x1fff;
3394         /* kprintf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3395         OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3396         OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3397         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3398         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3399         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3400         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3401
3402
3403         /* vertical active */
3404         if (bktr->capture_area_enabled)
3405           temp = bktr->capture_area_y_size;
3406         else
3407           temp = fp->vactive;
3408         /* kprintf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3409         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3410         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3411         OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3412         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3413         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3414         OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3415  
3416         /* vertical delay */
3417         if (bktr->capture_area_enabled)
3418           temp = fp->vdelay + (bktr->capture_area_y_offset);
3419         else
3420           temp = fp->vdelay;
3421         /* kprintf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3422         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3423         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3424         OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3425         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3426         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3427         OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3428
3429         /* end of video params */
3430
3431         if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3432            && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3433                 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3434         } else {
3435                 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3436         }
3437
3438         /* capture control */
3439         switch (i_flag) {
3440         case 1:
3441                 bktr->bktr_cap_ctl = 
3442                     (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3443                 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3444                 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3445                 interlace = 1;
3446                 break;
3447          case 2:
3448                 bktr->bktr_cap_ctl =
3449                         (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3450                 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3451                 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3452                 interlace = 1;
3453                 break;
3454          default:
3455                 bktr->bktr_cap_ctl = 
3456                         (BT848_CAP_CTL_DITH_FRAME |
3457                          BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3458                 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3459                 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3460                 interlace = 2;
3461                 break;
3462         }
3463
3464         OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3465
3466         rows = bktr->rows;
3467         cols = bktr->cols;
3468
3469         bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3470
3471         /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3472         /* user, then use the rgb_vbi RISC program. */
3473         /* Otherwise, use the normal rgb RISC program */
3474         if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3475                 if ( (bktr->vbiflags & VBI_OPEN)
3476                    ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3477                    ||(bktr->format_params == BT848_IFORM_F_SECAM)
3478                    ){
3479                         bktr->bktr_cap_ctl |=
3480                                 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3481                         bktr->vbiflags |= VBI_CAPTURE;
3482                         rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3483                         return;
3484                 } else {
3485                         rgb_prog(bktr, i_flag, cols, rows, interlace);
3486                         return;
3487                 }
3488         }
3489
3490         if ( pf_int->public.type  == METEOR_PIXTYPE_YUV ) {
3491                 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3492                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3493                      | pixfmt_swap_flags( bktr->pixfmt ));
3494                 return;
3495         }
3496
3497         if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_PACKED ) {
3498                 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3499                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3500                      | pixfmt_swap_flags( bktr->pixfmt ));
3501                 return;
3502         }
3503
3504         if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_12 ) {
3505                 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3506                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3507                      | pixfmt_swap_flags( bktr->pixfmt ));
3508                 return;
3509         }
3510         return;
3511 }
3512
3513
3514 /******************************************************************************
3515  * video & video capture specific routines:
3516  */
3517
3518
3519 /*
3520  * 
3521  */
3522 static void
3523 start_capture( bktr_ptr_t bktr, unsigned type )
3524 {
3525         u_char                  i_flag;
3526         struct format_params   *fp;
3527
3528         fp = &format_params[bktr->format_params];
3529
3530         /*  If requested, clear out capture buf first  */
3531         if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3532                 bzero((caddr_t)bktr->bigbuf, 
3533                       (size_t)bktr->rows * bktr->cols * bktr->frames *
3534                         pixfmt_table[ bktr->pixfmt ].public.Bpp);
3535         }
3536
3537         OUTB(bktr, BKTR_DSTATUS,  0);
3538         OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3539
3540         bktr->flags |= type;
3541         bktr->flags &= ~METEOR_WANT_MASK;
3542         switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3543         case METEOR_ONLY_EVEN_FIELDS:
3544                 bktr->flags |= METEOR_WANT_EVEN;
3545                 i_flag = 1;
3546                 break;
3547         case METEOR_ONLY_ODD_FIELDS:
3548                 bktr->flags |= METEOR_WANT_ODD;
3549                 i_flag = 2;
3550                 break;
3551         default:
3552                 bktr->flags |= METEOR_WANT_MASK;
3553                 i_flag = 3;
3554                 break;
3555         }
3556
3557         /*  TDEC is only valid for continuous captures  */
3558         if ( type == METEOR_SINGLE ) {
3559                 u_short fps_save = bktr->fps;
3560
3561                 set_fps(bktr, fp->frame_rate);
3562                 bktr->fps = fps_save;
3563         }
3564         else
3565                 set_fps(bktr, bktr->fps);
3566
3567         if (bktr->dma_prog_loaded == FALSE) {
3568                 build_dma_prog(bktr, i_flag);
3569                 bktr->dma_prog_loaded = TRUE;
3570         }
3571         
3572
3573         OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3574
3575 }
3576
3577
3578 /*
3579  * 
3580  */
3581 static void
3582 set_fps( bktr_ptr_t bktr, u_short fps )
3583 {
3584         struct format_params    *fp;
3585         int i_flag;
3586
3587         fp = &format_params[bktr->format_params];
3588
3589         switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3590         case METEOR_ONLY_EVEN_FIELDS:
3591                 bktr->flags |= METEOR_WANT_EVEN;
3592                 i_flag = 1;
3593                 break;
3594         case METEOR_ONLY_ODD_FIELDS:
3595                 bktr->flags |= METEOR_WANT_ODD;
3596                 i_flag = 1;
3597                 break;
3598         default:
3599                 bktr->flags |= METEOR_WANT_MASK;
3600                 i_flag = 2;
3601                 break;
3602         }
3603
3604         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3605         OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3606
3607         bktr->fps = fps;
3608         OUTB(bktr, BKTR_TDEC, 0);
3609
3610         if (fps < fp->frame_rate)
3611                 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3612         else
3613                 OUTB(bktr, BKTR_TDEC, 0);
3614         return;
3615
3616 }
3617
3618
3619
3620
3621
3622 /* 
3623  * Given a pixfmt index, compute the bt848 swap_flags necessary to 
3624  *   achieve the specified swapping.
3625  * Note that without bt swapping, 2Bpp and 3Bpp modes are written 
3626  *   byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6 
3627  *   and read R->L).  
3628  * Note also that for 3Bpp, we may additionally need to do some creative 
3629  *   SKIPing to align the FIFO bytelines with the target buffer (see split()).
3630  * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3631  *   as one would expect.
3632  */
3633
3634 static u_int pixfmt_swap_flags( int pixfmt )
3635 {
3636         struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3637         u_int                 swapf = 0;
3638
3639         switch ( pf->Bpp ) {
3640         case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3641                  break;
3642
3643         case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3644                  break;
3645                  
3646         case 4 : if ( pf->swap_bytes )
3647                         swapf = pf->swap_shorts ? 0 : WSWAP;
3648                  else
3649                         swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3650                  break;
3651         }
3652         return swapf;
3653 }
3654
3655
3656
3657 /* 
3658  * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3659  *   our pixfmt_table indices.
3660  */
3661
3662 static int oformat_meteor_to_bt( u_long format )
3663 {
3664         int    i;
3665         struct meteor_pixfmt *pf1, *pf2;
3666
3667         /*  Find format in compatibility table  */
3668         for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3669                 if ( meteor_pixfmt_table[i].meteor_format == format )
3670                         break;
3671
3672         if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3673                 return -1;
3674         pf1 = &meteor_pixfmt_table[i].public;
3675
3676         /*  Match it with an entry in master pixel format table  */
3677         for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3678                 pf2 = &pixfmt_table[i].public;
3679
3680                 if (( pf1->type        == pf2->type        ) &&
3681                     ( pf1->Bpp         == pf2->Bpp         ) &&
3682                     !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3683                     ( pf1->swap_bytes  == pf2->swap_bytes  ) &&
3684                     ( pf1->swap_shorts == pf2->swap_shorts )) 
3685                         break;
3686         }
3687         if ( i >= PIXFMT_TABLE_SIZE )
3688                 return -1;
3689
3690         return i;
3691 }
3692
3693 /******************************************************************************
3694  * i2c primitives:
3695  */
3696
3697 /* */
3698 #define I2CBITTIME              (0x5<<4)        /* 5 * 0.48uS */
3699 #define I2CBITTIME_878              (1 << 7)
3700 #define I2C_READ                0x01
3701 #define I2C_COMMAND             (I2CBITTIME |                   \
3702                                  BT848_DATA_CTL_I2CSCL |        \
3703                                  BT848_DATA_CTL_I2CSDA)
3704
3705 #define I2C_COMMAND_878         (I2CBITTIME_878 |                       \
3706                                  BT848_DATA_CTL_I2CSCL |        \
3707                                  BT848_DATA_CTL_I2CSDA)
3708
3709 /* Select between old i2c code and new iicbus / smbus code */
3710 #if defined(BKTR_USE_FREEBSD_SMBUS)
3711
3712 /*
3713  * The hardware interface is actually SMB commands
3714  */
3715 int
3716 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3717 {
3718         char cmd;
3719
3720         if (bktr->id == BROOKTREE_848  ||
3721             bktr->id == BROOKTREE_848A ||
3722             bktr->id == BROOKTREE_849A)
3723                 cmd = I2C_COMMAND;
3724         else
3725                 cmd = I2C_COMMAND_878;
3726
3727         if (byte2 != -1) {
3728                 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3729                         (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3730                         return (-1);
3731         } else {
3732                 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3733                         (char)(byte1 & 0xff)))
3734                         return (-1);
3735         }
3736
3737         /* return OK */
3738         return( 0 );
3739 }
3740
3741 int
3742 i2cRead( bktr_ptr_t bktr, int addr )
3743 {
3744         char result;
3745         char cmd;
3746
3747         if (bktr->id == BROOKTREE_848  ||
3748             bktr->id == BROOKTREE_848A ||
3749             bktr->id == BROOKTREE_849A)
3750                 cmd = I2C_COMMAND;
3751         else
3752                 cmd = I2C_COMMAND_878;
3753
3754         if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3755                 return (-1);
3756
3757         return ((int)((unsigned char)result));
3758 }
3759
3760 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3761
3762 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3763 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3764 /* Therefore we need low level control of the i2c bus hardware */
3765
3766 /* Write to the MSP or DPL registers */
3767 void
3768 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr,  unsigned char dev, unsigned int addr, unsigned int data)
3769 {
3770         unsigned char addr_l, addr_h, data_h, data_l ;
3771
3772         addr_h = (addr >>8) & 0xff;
3773         addr_l = addr & 0xff;
3774         data_h = (data >>8) & 0xff;
3775         data_l = data & 0xff;
3776
3777         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3778
3779         iicbus_write_byte(IICBUS(bktr), dev, 0);
3780         iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3781         iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3782         iicbus_write_byte(IICBUS(bktr), data_h, 0);
3783         iicbus_write_byte(IICBUS(bktr), data_l, 0);
3784
3785         iicbus_stop(IICBUS(bktr));
3786
3787         return;
3788 }
3789
3790 /* Read from the MSP or DPL registers */
3791 unsigned int
3792 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3793 {
3794         unsigned int data;
3795         unsigned char addr_l, addr_h, dev_r;
3796         int read;
3797         u_char data_read[2];
3798
3799         addr_h = (addr >>8) & 0xff;
3800         addr_l = addr & 0xff;
3801         dev_r = dev+1;
3802
3803         /* XXX errors ignored */
3804         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3805
3806         iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3807         iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3808         iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3809
3810         iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3811         iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3812         iicbus_stop(IICBUS(bktr));
3813
3814         data = (data_read[0]<<8) | data_read[1];
3815
3816         return (data);
3817 }
3818
3819 /* Reset the MSP or DPL chip */
3820 /* The user can block the reset (which is handy if you initialise the
3821  * MSP and/or DPL audio in another operating system first (eg in Windows)
3822  */
3823 void
3824 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3825 {
3826
3827 #ifndef BKTR_NO_MSP_RESET
3828         /* put into reset mode */
3829         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3830         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3831         iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3832         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3833         iicbus_stop(IICBUS(bktr));
3834
3835         /* put back to operational mode */
3836         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3837         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3838         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3839         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3840         iicbus_stop(IICBUS(bktr));
3841 #endif
3842         return;
3843 }
3844
3845 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3846         int read;
3847
3848         /* XXX errors ignored */
3849         iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3850         iicbus_read(IICBUS(bktr),  remote->data, 3, &read, IIC_LAST_READ, 0);
3851         iicbus_stop(IICBUS(bktr));
3852
3853         return;
3854 }
3855
3856 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3857
3858 /*
3859  * Program the i2c bus directly
3860  */
3861 int
3862 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3863 {
3864         u_long          x;
3865         u_long          data;
3866
3867         /* clear status bits */
3868         OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3869
3870         /* build the command datum */
3871         if (bktr->id == BROOKTREE_848  ||
3872             bktr->id == BROOKTREE_848A ||
3873             bktr->id == BROOKTREE_849A) {
3874           data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3875         } else {
3876           data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3877         }
3878         if ( byte2 != -1 ) {
3879                 data |= ((byte2 & 0xff) << 8);
3880                 data |= BT848_DATA_CTL_I2CW3B;
3881         }
3882
3883         /* write the address and data */
3884         OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3885
3886         /* wait for completion */
3887         for ( x = 0x7fffffff; x; --x ) {        /* safety valve */
3888                 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3889                         break;
3890         }
3891
3892         /* check for ACK */
3893         if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3894                 return( -1 );
3895
3896         /* return OK */
3897         return( 0 );
3898 }
3899
3900
3901 /*
3902  * 
3903  */
3904 int
3905 i2cRead( bktr_ptr_t bktr, int addr )
3906 {
3907         u_long          x;
3908
3909         /* clear status bits */
3910         OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3911
3912         /* write the READ address */
3913         /* The Bt878 and Bt879  differed on the treatment of i2c commands */
3914            
3915         if (bktr->id == BROOKTREE_848  ||
3916             bktr->id == BROOKTREE_848A ||
3917             bktr->id == BROOKTREE_849A) {
3918                 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3919         } else {
3920                 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3921         }
3922
3923         /* wait for completion */
3924         for ( x = 0x7fffffff; x; --x ) {        /* safety valve */
3925                 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3926                         break;
3927         }
3928
3929         /* check for ACK */
3930         if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3931                 return( -1 );
3932
3933         /* it was a read */
3934         return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3935 }
3936
3937 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3938 /* bt848 automated i2c bus controller cannot handle */
3939 /* Therefore we need low level control of the i2c bus hardware */
3940 /* Idea for the following functions are from elsewhere in this driver and */
3941 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3942
3943 #define BITD    40
3944 static void i2c_start( bktr_ptr_t bktr) {
3945         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3946         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3947         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3948         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3949 }
3950
3951 static void i2c_stop( bktr_ptr_t bktr) {
3952         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3953         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3954         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3955 }
3956
3957 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3958         int x;
3959         int status;
3960
3961         /* write out the byte */
3962         for ( x = 7; x >= 0; --x ) {
3963                 if ( data & (1<<x) ) {
3964                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3965                         DELAY( BITD );          /* assert HI data */
3966                         OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3967                         DELAY( BITD );          /* strobe clock */
3968                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3969                         DELAY( BITD );          /* release clock */
3970                 }
3971                 else {
3972                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3973                         DELAY( BITD );          /* assert LO data */
3974                         OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3975                         DELAY( BITD );          /* strobe clock */
3976                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3977                         DELAY( BITD );          /* release clock */
3978                 }
3979         }
3980
3981         /* look for an ACK */
3982         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3983         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3984         status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;       /* read the ACK bit */
3985         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3986
3987         return( status );
3988 }
3989
3990 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3991         int x;
3992         int bit;
3993         int byte = 0;
3994
3995         /* read in the byte */
3996         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3997         DELAY( BITD );                          /* float data */
3998         for ( x = 7; x >= 0; --x ) {
3999                 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4000                 DELAY( BITD );                  /* strobe clock */
4001                 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1;  /* read the data bit */
4002                 if ( bit ) byte |= (1<<x);
4003                 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4004                 DELAY( BITD );                  /* release clock */
4005         }
4006         /* After reading the byte, send an ACK */
4007         /* (unless that was the last byte, for which we send a NAK */
4008         if (last) { /* send NAK - same a writing a 1 */
4009                 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4010                 DELAY( BITD );                  /* set data bit */
4011                 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4012                 DELAY( BITD );                  /* strobe clock */
4013                 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4014                 DELAY( BITD );                  /* release clock */
4015         } else { /* send ACK - same as writing a 0 */
4016                 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4017                 DELAY( BITD );                  /* set data bit */
4018                 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4019                 DELAY( BITD );                  /* strobe clock */
4020                 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4021                 DELAY( BITD );                  /* release clock */
4022         }
4023
4024         *data=byte;
4025         return 0;
4026 }
4027 #undef BITD
4028
4029 /* Write to the MSP or DPL registers */
4030 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4031                     unsigned int data){
4032         unsigned int msp_w_addr = i2c_addr;
4033         unsigned char addr_l, addr_h, data_h, data_l ;
4034         addr_h = (addr >>8) & 0xff;
4035         addr_l = addr & 0xff;
4036         data_h = (data >>8) & 0xff;
4037         data_l = data & 0xff;
4038
4039         i2c_start(bktr);
4040         i2c_write_byte(bktr, msp_w_addr);
4041         i2c_write_byte(bktr, dev);
4042         i2c_write_byte(bktr, addr_h);
4043         i2c_write_byte(bktr, addr_l);
4044         i2c_write_byte(bktr, data_h);
4045         i2c_write_byte(bktr, data_l);
4046         i2c_stop(bktr);
4047 }
4048
4049 /* Read from the MSP or DPL registers */
4050 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4051         unsigned int data;
4052         unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4053         addr_h = (addr >>8) & 0xff;
4054         addr_l = addr & 0xff;
4055         dev_r = dev+1;
4056
4057         i2c_start(bktr);
4058         i2c_write_byte(bktr,i2c_addr);
4059         i2c_write_byte(bktr,dev_r);
4060         i2c_write_byte(bktr,addr_h);
4061         i2c_write_byte(bktr,addr_l);
4062
4063         i2c_start(bktr);
4064         i2c_write_byte(bktr,i2c_addr+1);
4065         i2c_read_byte(bktr,&data_1, 0);
4066         i2c_read_byte(bktr,&data_2, 1);
4067         i2c_stop(bktr);
4068         data = (data_1<<8) | data_2;
4069         return data;
4070 }
4071
4072 /* Reset the MSP or DPL chip */
4073 /* The user can block the reset (which is handy if you initialise the
4074  * MSP audio in another operating system first (eg in Windows)
4075  */
4076 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4077
4078 #ifndef BKTR_NO_MSP_RESET
4079         /* put into reset mode */
4080         i2c_start(bktr);
4081         i2c_write_byte(bktr, i2c_addr);
4082         i2c_write_byte(bktr, 0x00);
4083         i2c_write_byte(bktr, 0x80);
4084         i2c_write_byte(bktr, 0x00);
4085         i2c_stop(bktr);
4086
4087         /* put back to operational mode */
4088         i2c_start(bktr);
4089         i2c_write_byte(bktr, i2c_addr);
4090         i2c_write_byte(bktr, 0x00);
4091         i2c_write_byte(bktr, 0x00);
4092         i2c_write_byte(bktr, 0x00);
4093         i2c_stop(bktr);
4094 #endif
4095         return;
4096
4097 }
4098
4099 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4100
4101         /* XXX errors ignored */
4102         i2c_start(bktr);
4103         i2c_write_byte(bktr,bktr->remote_control_addr);
4104         i2c_read_byte(bktr,&(remote->data[0]), 0);
4105         i2c_read_byte(bktr,&(remote->data[1]), 0);
4106         i2c_read_byte(bktr,&(remote->data[2]), 0);
4107         i2c_stop(bktr);
4108
4109         return;
4110 }
4111
4112 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4113
4114
4115 #if defined( I2C_SOFTWARE_PROBE )
4116
4117 /*
4118  * we are keeping this around for any parts that we need to probe
4119  * but that CANNOT be probed via an i2c read.
4120  * this is necessary because the hardware i2c mechanism
4121  * cannot be programmed for 1 byte writes.
4122  * currently there are no known i2c parts that we need to probe
4123  * and that cannot be safely read.
4124  */
4125 static int      i2cProbe( bktr_ptr_t bktr, int addr );
4126 #define BITD            40
4127 #define EXTRA_START
4128
4129 /*
4130  * probe for an I2C device at addr.
4131  */
4132 static int
4133 i2cProbe( bktr_ptr_t bktr, int addr )
4134 {
4135         int             x, status;
4136
4137         /* the START */
4138 #if defined( EXTRA_START )
4139         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* release data */
4140         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* release clock */
4141 #endif /* EXTRA_START */
4142         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );        /* lower data */
4143         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );        /* lower clock */
4144
4145         /* write addr */
4146         for ( x = 7; x >= 0; --x ) {
4147                 if ( addr & (1<<x) ) {
4148                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4149                         DELAY( BITD );          /* assert HI data */
4150                         OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4151                         DELAY( BITD );          /* strobe clock */
4152                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4153                         DELAY( BITD );          /* release clock */
4154                 }
4155                 else {
4156                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4157                         DELAY( BITD );          /* assert LO data */
4158                         OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4159                         DELAY( BITD );          /* strobe clock */
4160                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4161                         DELAY( BITD );          /* release clock */
4162                 }
4163         }
4164
4165         /* look for an ACK */
4166         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* float data */
4167         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* strobe clock */
4168         status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;      /* read the ACK bit */
4169         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* release clock */
4170
4171         /* the STOP */
4172         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );        /* lower clock & data */
4173         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );        /* release clock */
4174         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* release data */
4175
4176         return( status );
4177 }
4178 #undef EXTRA_START
4179 #undef BITD
4180
4181 #endif /* I2C_SOFTWARE_PROBE */
4182
4183
4184 #define ABSENT          (-1)