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