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