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