proc->thread stage 2: MAJOR revamping of system calls, ucred, jail API,
[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.3 2003/06/23 17:55:30 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 thread *td)
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                 KKASSERT(td->td_proc != NULL);
1556                 bktr->signal = *(int *) arg;
1557                 bktr->proc = td->td_proc;
1558                 break;
1559
1560         case METEORGSIGNAL:
1561                 *(int *)arg = bktr->signal;
1562                 break;
1563
1564         case METEORCAPTUR:
1565                 temp = bktr->flags;
1566                 switch (*(int *) arg) {
1567                 case METEOR_CAP_SINGLE:
1568
1569                         if (bktr->bigbuf==0)    /* no frame buffer allocated */
1570                                 return( ENOMEM );
1571                         /* already capturing */
1572                         if (temp & METEOR_CAP_MASK)
1573                                 return( EIO );
1574
1575
1576
1577                         start_capture(bktr, METEOR_SINGLE);
1578
1579                         /* wait for capture to complete */
1580                         OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1581                         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1582                         OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1583
1584                         OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1585                                             BT848_INT_RISCI      |
1586                                             BT848_INT_VSYNC      |
1587                                             BT848_INT_FMTCHG);
1588
1589                         OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1590                         error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1591                         if (error && (error != ERESTART)) {
1592                                 /*  Here if we didn't get complete frame  */
1593 #ifdef DIAGNOSTIC
1594                                 printf( "%s: ioctl: tsleep error %d %x\n",
1595                                         bktr_name(bktr), error,
1596                                         INL(bktr, BKTR_RISC_COUNT));
1597 #endif
1598
1599                                 /* stop dma */
1600                                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1601
1602                                 /* disable risc, leave fifo running */
1603                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1604                         }
1605
1606                         bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1607                         /* FIXME: should we set bt848->int_stat ??? */
1608                         break;
1609
1610                 case METEOR_CAP_CONTINOUS:
1611                         if (bktr->bigbuf==0)    /* no frame buffer allocated */
1612                                 return( ENOMEM );
1613                         /* already capturing */
1614                         if (temp & METEOR_CAP_MASK)
1615                             return( EIO );
1616
1617
1618                         start_capture(bktr, METEOR_CONTIN);
1619
1620                         /* Clear the interrypt status register */
1621                         OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1622
1623                         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1624                         OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1625                         OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1626
1627                         OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1628                                             BT848_INT_RISCI      |
1629                                             BT848_INT_VSYNC      |
1630                                             BT848_INT_FMTCHG);
1631 #ifdef BT848_DUMP
1632                         dump_bt848( bt848 );
1633 #endif
1634                         break;
1635                 
1636                 case METEOR_CAP_STOP_CONT:
1637                         if (bktr->flags & METEOR_CONTIN) {
1638                                 /* turn off capture */
1639                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1640                                 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1641                                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1642                                 bktr->flags &=
1643                                         ~(METEOR_CONTIN | METEOR_WANT_MASK);
1644
1645                         }
1646                 }
1647                 break;
1648
1649         case METEORSETGEO:
1650                 /* can't change parameters while capturing */
1651                 if (bktr->flags & METEOR_CAP_MASK)
1652                         return( EBUSY );
1653
1654
1655                 geo = (struct meteor_geomet *) arg;
1656
1657                 error = 0;
1658                 /* Either even or odd, if even & odd, then these a zero */
1659                 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1660                         (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1661                         printf( "%s: ioctl: Geometry odd or even only.\n",
1662                                 bktr_name(bktr));
1663                         return( EINVAL );
1664                 }
1665
1666                 /* set/clear even/odd flags */
1667                 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1668                         bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1669                 else
1670                         bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1671                 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1672                         bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1673                 else
1674                         bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1675
1676                 if (geo->columns <= 0) {
1677                         printf(
1678                         "%s: ioctl: %d: columns must be greater than zero.\n",
1679                                 bktr_name(bktr), geo->columns);
1680                         error = EINVAL;
1681                 }
1682                 else if ((geo->columns & 0x3fe) != geo->columns) {
1683                         printf(
1684                         "%s: ioctl: %d: columns too large or not even.\n",
1685                                 bktr_name(bktr), geo->columns);
1686                         error = EINVAL;
1687                 }
1688
1689                 if (geo->rows <= 0) {
1690                         printf(
1691                         "%s: ioctl: %d: rows must be greater than zero.\n",
1692                                 bktr_name(bktr), geo->rows);
1693                         error = EINVAL;
1694                 }
1695                 else if (((geo->rows & 0x7fe) != geo->rows) ||
1696                         ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1697                                 ((geo->rows & 0x3fe) != geo->rows)) ) {
1698                         printf(
1699                         "%s: ioctl: %d: rows too large or not even.\n",
1700                                 bktr_name(bktr), geo->rows);
1701                         error = EINVAL;
1702                 }
1703
1704                 if (geo->frames > 32) {
1705                         printf("%s: ioctl: too many frames.\n",
1706                                bktr_name(bktr));
1707
1708                         error = EINVAL;
1709                 }
1710
1711                 if (error)
1712                         return( error );
1713
1714                 bktr->dma_prog_loaded = FALSE;
1715                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1716
1717                 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1718
1719                 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1720                         if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1721
1722                         /* meteor_mem structure for SYNC Capture */
1723                         if (geo->frames > 1) temp += PAGE_SIZE;
1724
1725                         temp = btoc(temp);
1726                         if ((int) temp > bktr->alloc_pages
1727                             && bktr->video.addr == 0) {
1728
1729 /*****************************/
1730 /* *** OS Dependant code *** */
1731 /*****************************/
1732 #if defined(__NetBSD__) || defined(__OpenBSD__)
1733                                 bus_dmamap_t dmamap;
1734
1735                                 buf = get_bktr_mem(bktr, &dmamap,
1736                                                    temp * PAGE_SIZE);
1737                                 if (buf != 0) {
1738                                         free_bktr_mem(bktr, bktr->dm_mem,
1739                                                       bktr->bigbuf);
1740                                         bktr->dm_mem = dmamap;
1741
1742 #else
1743                                 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1744                                 if (buf != 0) {
1745                                         kmem_free(kernel_map, bktr->bigbuf,
1746                                           (bktr->alloc_pages * PAGE_SIZE));
1747 #endif                                          
1748
1749                                         bktr->bigbuf = buf;
1750                                         bktr->alloc_pages = temp;
1751                                         if (bootverbose)
1752                                                 printf(
1753                                 "%s: ioctl: Allocating %d bytes\n",
1754                                                         bktr_name(bktr), temp*PAGE_SIZE);
1755                                 }
1756                                 else
1757                                         error = ENOMEM;
1758                         }
1759                 }
1760
1761                 if (error)
1762                         return error;
1763
1764                 bktr->rows = geo->rows;
1765                 bktr->cols = geo->columns;
1766                 bktr->frames = geo->frames;
1767
1768                 /*  Pixel format (if in meteor pixfmt compatibility mode)  */
1769                 if ( bktr->pixfmt_compat ) {
1770                         bktr->format = METEOR_GEO_YUV_422;
1771                         switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1772                         case 0:                 /* default */
1773                         case METEOR_GEO_RGB16:
1774                                     bktr->format = METEOR_GEO_RGB16;
1775                                     break;
1776                         case METEOR_GEO_RGB24:
1777                                     bktr->format = METEOR_GEO_RGB24;
1778                                     break;
1779                         case METEOR_GEO_YUV_422:
1780                                     bktr->format = METEOR_GEO_YUV_422;
1781                                     if (geo->oformat & METEOR_GEO_YUV_12) 
1782                                         bktr->format = METEOR_GEO_YUV_12;
1783                                     break;
1784                         case METEOR_GEO_YUV_PACKED:
1785                                     bktr->format = METEOR_GEO_YUV_PACKED;
1786                                     break;
1787                         }
1788                         bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1789                 }
1790
1791                 if (bktr->flags & METEOR_CAP_MASK) {
1792
1793                         if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1794                                 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1795                                 case METEOR_ONLY_ODD_FIELDS:
1796                                         bktr->flags |= METEOR_WANT_ODD;
1797                                         break;
1798                                 case METEOR_ONLY_EVEN_FIELDS:
1799                                         bktr->flags |= METEOR_WANT_EVEN;
1800                                         break;
1801                                 default:
1802                                         bktr->flags |= METEOR_WANT_MASK;
1803                                         break;
1804                                 }
1805
1806                                 start_capture(bktr, METEOR_CONTIN);
1807                                 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1808                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1809                                 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1810                                 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1811                                                     BT848_INT_VSYNC      |
1812                                                     BT848_INT_FMTCHG);
1813                         }
1814                 }
1815                 break;
1816         /* end of METEORSETGEO */
1817
1818         /* FIXME. The Capture Area currently has the following restrictions:
1819         GENERAL
1820          y_offset may need to be even in interlaced modes
1821         RGB24 - Interlaced mode
1822          x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1823          y_size must be greater than or equal to METEORSETGEO height (rows)
1824         RGB24 - Even Only (or Odd Only) mode
1825          x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1826          y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1827         YUV12 - Interlaced mode
1828          x_size must be greater than or equal to METEORSETGEO width (cols)
1829          y_size must be greater than or equal to METEORSETGEO height (rows)
1830         YUV12 - Even Only (or Odd Only) mode
1831          x_size must be greater than or equal to METEORSETGEO width (cols)
1832          y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1833         */
1834
1835         case BT848_SCAPAREA: /* set capture area of each video frame */
1836                 /* can't change parameters while capturing */
1837                 if (bktr->flags & METEOR_CAP_MASK)
1838                         return( EBUSY );
1839
1840                 cap_area = (struct bktr_capture_area *) arg;
1841                 bktr->capture_area_x_offset = cap_area->x_offset;
1842                 bktr->capture_area_y_offset = cap_area->y_offset;
1843                 bktr->capture_area_x_size   = cap_area->x_size;
1844                 bktr->capture_area_y_size   = cap_area->y_size;
1845                 bktr->capture_area_enabled  = TRUE;
1846  
1847                 bktr->dma_prog_loaded = FALSE;
1848                 break;
1849    
1850         case BT848_GCAPAREA: /* get capture area of each video frame */
1851                 cap_area = (struct bktr_capture_area *) arg;
1852                 if (bktr->capture_area_enabled == FALSE) {
1853                         cap_area->x_offset = 0;
1854                         cap_area->y_offset = 0;
1855                         cap_area->x_size   = format_params[
1856                                 bktr->format_params].scaled_hactive;
1857                         cap_area->y_size   = format_params[
1858                                 bktr->format_params].vactive;
1859                 } else {
1860                         cap_area->x_offset = bktr->capture_area_x_offset;
1861                         cap_area->y_offset = bktr->capture_area_y_offset;
1862                         cap_area->x_size   = bktr->capture_area_x_size;
1863                         cap_area->y_size   = bktr->capture_area_y_size;
1864                 }
1865                 break;
1866
1867         default:
1868                 return common_ioctl( bktr, cmd, arg );
1869         }
1870
1871         return( 0 );
1872 }
1873
1874 /*
1875  * tuner ioctls
1876  */
1877 int
1878 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td)
1879 {
1880         int             tmp_int;
1881         unsigned int    temp, temp1;
1882         int             offset;
1883         int             count;
1884         u_char          *buf;
1885         u_long          par;
1886         u_char          write;
1887         int             i2c_addr;
1888         int             i2c_port;
1889         u_long          data;
1890
1891         switch ( cmd ) {
1892
1893         case REMOTE_GETKEY:
1894                 /* Read the last key pressed by the Remote Control */
1895                 if (bktr->remote_control == 0) return (EINVAL);
1896                 remote_read(bktr, (struct bktr_remote *)arg);
1897                 break;
1898
1899 #if defined( TUNER_AFC )
1900         case TVTUNER_SETAFC:
1901                 bktr->tuner.afc = (*(int *)arg != 0);
1902                 break;
1903
1904         case TVTUNER_GETAFC:
1905                 *(int *)arg = bktr->tuner.afc;
1906                 /* XXX Perhaps use another bit to indicate AFC success? */
1907                 break;
1908 #endif /* TUNER_AFC */
1909
1910         case TVTUNER_SETCHNL:
1911                 temp_mute( bktr, TRUE );
1912                 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1913                 if ( temp < 0 ) {
1914                         temp_mute( bktr, FALSE );
1915                         return( EINVAL );
1916                 }
1917                 *(unsigned long *)arg = temp;
1918
1919                 /* after every channel change, we must restart the MSP34xx */
1920                 /* audio chip to reselect NICAM STEREO or MONO audio */
1921                 if ( bktr->card.msp3400c )
1922                   msp_autodetect( bktr );
1923
1924                 /* after every channel change, we must restart the DPL35xx */
1925                 if ( bktr->card.dpl3518a )
1926                   dpl_autodetect( bktr );
1927
1928                 temp_mute( bktr, FALSE );
1929                 break;
1930
1931         case TVTUNER_GETCHNL:
1932                 *(unsigned long *)arg = bktr->tuner.channel;
1933                 break;
1934
1935         case TVTUNER_SETTYPE:
1936                 temp = *(unsigned long *)arg;
1937                 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1938                         return( EINVAL );
1939                 bktr->tuner.chnlset = temp;
1940                 break;
1941
1942         case TVTUNER_GETTYPE:
1943                 *(unsigned long *)arg = bktr->tuner.chnlset;
1944                 break;
1945
1946         case TVTUNER_GETSTATUS:
1947                 temp = get_tuner_status( bktr );
1948                 *(unsigned long *)arg = temp & 0xff;
1949                 break;
1950
1951         case TVTUNER_SETFREQ:
1952                 temp_mute( bktr, TRUE );
1953                 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1954                 temp_mute( bktr, FALSE );
1955                 if ( temp < 0 ) {
1956                         temp_mute( bktr, FALSE );
1957                         return( EINVAL );
1958                 }
1959                 *(unsigned long *)arg = temp;
1960
1961                 /* after every channel change, we must restart the MSP34xx */
1962                 /* audio chip to reselect NICAM STEREO or MONO audio */
1963                 if ( bktr->card.msp3400c )
1964                   msp_autodetect( bktr );
1965
1966                 /* after every channel change, we must restart the DPL35xx */
1967                 if ( bktr->card.dpl3518a )
1968                   dpl_autodetect( bktr );
1969
1970                 temp_mute( bktr, FALSE );
1971                 break;
1972
1973         case TVTUNER_GETFREQ:
1974                 *(unsigned long *)arg = bktr->tuner.frequency;
1975                 break;
1976
1977         case TVTUNER_GETCHNLSET:
1978                 return tuner_getchnlset((struct bktr_chnlset *)arg);
1979
1980         case BT848_SAUDIO:      /* set audio channel */
1981                 if ( set_audio( bktr, *(int*)arg ) < 0 )
1982                         return( EIO );
1983                 break;
1984
1985         /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1986         case BT848_SHUE:        /* set hue */
1987                 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1988                 break;
1989
1990         case BT848_GHUE:        /* get hue */
1991                 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1992                 break;
1993
1994         /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1995         case BT848_SBRIG:       /* set brightness */
1996                 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1997                 break;
1998
1999         case BT848_GBRIG:       /* get brightness */
2000                 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2001                 break;
2002
2003         /*  */
2004         case BT848_SCSAT:       /* set chroma saturation */
2005                 tmp_int = *(int*)arg;
2006
2007                 temp = INB(bktr, BKTR_E_CONTROL);
2008                 temp1 = INB(bktr, BKTR_O_CONTROL);
2009                 if ( tmp_int & BIT_EIGHT_HIGH ) {
2010                         temp |= (BT848_E_CONTROL_SAT_U_MSB |
2011                                  BT848_E_CONTROL_SAT_V_MSB);
2012                         temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2013                                   BT848_O_CONTROL_SAT_V_MSB);
2014                 }
2015                 else {
2016                         temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2017                                   BT848_E_CONTROL_SAT_V_MSB);
2018                         temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2019                                    BT848_O_CONTROL_SAT_V_MSB);
2020                 }
2021
2022                 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2023                 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2024                 OUTB(bktr, BKTR_E_CONTROL, temp);
2025                 OUTB(bktr, BKTR_O_CONTROL, temp1);
2026                 break;
2027
2028         case BT848_GCSAT:       /* get chroma saturation */
2029                 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2030                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2031                         tmp_int |= BIT_EIGHT_HIGH;
2032                 *(int*)arg = tmp_int;
2033                 break;
2034
2035         /*  */
2036         case BT848_SVSAT:       /* set chroma V saturation */
2037                 tmp_int = *(int*)arg;
2038
2039                 temp = INB(bktr, BKTR_E_CONTROL);
2040                 temp1 = INB(bktr, BKTR_O_CONTROL);
2041                 if ( tmp_int & BIT_EIGHT_HIGH) {
2042                         temp |= BT848_E_CONTROL_SAT_V_MSB;
2043                         temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2044                 }
2045                 else {
2046                         temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2047                         temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2048                 }
2049
2050                 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2051                 OUTB(bktr, BKTR_E_CONTROL, temp);
2052                 OUTB(bktr, BKTR_O_CONTROL, temp1);
2053                 break;
2054
2055         case BT848_GVSAT:       /* get chroma V saturation */
2056                 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2057                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2058                         tmp_int |= BIT_EIGHT_HIGH;
2059                 *(int*)arg = tmp_int;
2060                 break;
2061
2062         /*  */
2063         case BT848_SUSAT:       /* set chroma U saturation */
2064                 tmp_int = *(int*)arg;
2065
2066                 temp = INB(bktr, BKTR_E_CONTROL);
2067                 temp1 = INB(bktr, BKTR_O_CONTROL);
2068                 if ( tmp_int & BIT_EIGHT_HIGH ) {
2069                         temp |= BT848_E_CONTROL_SAT_U_MSB;
2070                         temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2071                 }
2072                 else {
2073                         temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2074                         temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2075                 }
2076
2077                 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2078                 OUTB(bktr, BKTR_E_CONTROL, temp);
2079                 OUTB(bktr, BKTR_O_CONTROL, temp1);
2080                 break;
2081
2082         case BT848_GUSAT:       /* get chroma U saturation */
2083                 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2084                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2085                         tmp_int |= BIT_EIGHT_HIGH;
2086                 *(int*)arg = tmp_int;
2087                 break;
2088
2089 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2090
2091         case BT848_SLNOTCH:     /* set luma notch */
2092                 tmp_int = (*(int *)arg & 0x7) << 5 ;
2093                 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2094                 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2095                 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2096                 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2097                 break;
2098
2099         case BT848_GLNOTCH:     /* get luma notch */
2100                 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2101                 break;
2102
2103
2104         /*  */
2105         case BT848_SCONT:       /* set contrast */
2106                 tmp_int = *(int*)arg;
2107
2108                 temp = INB(bktr, BKTR_E_CONTROL);
2109                 temp1 = INB(bktr, BKTR_O_CONTROL);
2110                 if ( tmp_int & BIT_EIGHT_HIGH ) {
2111                         temp |= BT848_E_CONTROL_CON_MSB;
2112                         temp1 |= BT848_O_CONTROL_CON_MSB;
2113                 }
2114                 else {
2115                         temp &= ~BT848_E_CONTROL_CON_MSB;
2116                         temp1 &= ~BT848_O_CONTROL_CON_MSB;
2117                 }
2118
2119                 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2120                 OUTB(bktr, BKTR_E_CONTROL, temp);
2121                 OUTB(bktr, BKTR_O_CONTROL, temp1);
2122                 break;
2123
2124         case BT848_GCONT:       /* get contrast */
2125                 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2126                 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2127                         tmp_int |= BIT_EIGHT_HIGH;
2128                 *(int*)arg = tmp_int;
2129                 break;
2130
2131                 /*  FIXME:  SCBARS and CCBARS require a valid int *        */
2132                 /*    argument to succeed, but its not used; consider      */
2133                 /*    using the arg to store the on/off state so           */
2134                 /*    there's only one ioctl() needed to turn cbars on/off */
2135         case BT848_SCBARS:      /* set colorbar output */
2136                 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2137                 break;
2138
2139         case BT848_CCBARS:      /* clear colorbar output */
2140                 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2141                 break;
2142
2143         case BT848_GAUDIO:      /* get audio channel */
2144                 temp = bktr->audio_mux_select;
2145                 if ( bktr->audio_mute_state == TRUE )
2146                         temp |= AUDIO_MUTE;
2147                 *(int*)arg = temp;
2148                 break;
2149
2150         case BT848_SBTSC:       /* set audio channel */
2151                 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2152                         return( EIO );
2153                 break;
2154
2155         case BT848_WEEPROM:     /* write eeprom */
2156                 offset = (((struct eeProm *)arg)->offset);
2157                 count = (((struct eeProm *)arg)->count);
2158                 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2159                 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2160                         return( EIO );
2161                 break;
2162
2163         case BT848_REEPROM:     /* read eeprom */
2164                 offset = (((struct eeProm *)arg)->offset);
2165                 count = (((struct eeProm *)arg)->count);
2166                 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2167                 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2168                         return( EIO );
2169                 break;
2170
2171         case BT848_SIGNATURE:
2172                 offset = (((struct eeProm *)arg)->offset);
2173                 count = (((struct eeProm *)arg)->count);
2174                 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2175                 if ( signCard( bktr, offset, count, buf ) < 0 )
2176                         return( EIO );
2177                 break;
2178
2179         /* Ioctl's for direct gpio access */
2180 #ifdef BKTR_GPIO_ACCESS
2181         case BT848_GPIO_GET_EN:
2182                 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2183                 break;
2184
2185         case BT848_GPIO_SET_EN:
2186                 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2187                 break;
2188
2189         case BT848_GPIO_GET_DATA:
2190                 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2191                 break;
2192
2193         case BT848_GPIO_SET_DATA:
2194                 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2195                 break;
2196 #endif /* BKTR_GPIO_ACCESS */
2197
2198         /* Ioctl's for running the tuner device in radio mode           */
2199
2200         case RADIO_GETMODE:
2201             *(unsigned char *)arg = bktr->tuner.radio_mode;
2202             break;
2203
2204         case RADIO_SETMODE:
2205             bktr->tuner.radio_mode = *(unsigned char *)arg;
2206             break;
2207
2208         case RADIO_GETFREQ:
2209             *(unsigned long *)arg = bktr->tuner.frequency;
2210             break;
2211
2212         case RADIO_SETFREQ:
2213             /* The argument to this ioctl is NOT freq*16. It is
2214             ** freq*100.
2215             */
2216
2217             temp=(int)*(unsigned long *)arg;
2218
2219 #ifdef BKTR_RADIO_DEBUG
2220             printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2221                    (int)*(unsigned long *)arg, temp);
2222 #endif
2223
2224 #ifndef BKTR_RADIO_NOFREQCHECK
2225             /* According to the spec. sheet the band: 87.5MHz-108MHz    */
2226             /* is supported.                                            */
2227             if(temp<8750 || temp>10800) {
2228               printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2229               return(EINVAL);
2230               }
2231 #endif
2232             temp_mute( bktr, TRUE );
2233             temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2234             temp_mute( bktr, FALSE );
2235 #ifdef BKTR_RADIO_DEBUG
2236   if(temp)
2237     printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2238 #endif
2239             if ( temp < 0 )
2240                     return( EINVAL );
2241             *(unsigned long *)arg = temp;
2242             break;
2243
2244         /* Luigi's I2CWR ioctl */ 
2245         case BT848_I2CWR:
2246                 par = *(u_long *)arg;
2247                 write = (par >> 24) & 0xff ;
2248                 i2c_addr = (par >> 16) & 0xff ;
2249                 i2c_port = (par >> 8) & 0xff ;
2250                 data = (par) & 0xff ;
2251  
2252                 if (write) { 
2253                         i2cWrite( bktr, i2c_addr, i2c_port, data);
2254                 } else {
2255                         data = i2cRead( bktr, i2c_addr);
2256                 }
2257                 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2258                 break;
2259
2260
2261 #ifdef BT848_MSP_READ
2262         /* I2C ioctls to allow userland access to the MSP chip */
2263         case BT848_MSP_READ:
2264                 {
2265                 struct bktr_msp_control *msp;
2266                 msp = (struct bktr_msp_control *) arg;
2267                 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2268                                          msp->function, msp->address);
2269                 break;
2270                 }
2271
2272         case BT848_MSP_WRITE:
2273                 {
2274                 struct bktr_msp_control *msp;
2275                 msp = (struct bktr_msp_control *) arg;
2276                 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2277                              msp->address, msp->data );
2278                 break;
2279                 }
2280
2281         case BT848_MSP_RESET:
2282                 msp_dpl_reset(bktr, bktr->msp_addr);
2283                 break;
2284 #endif
2285
2286         default:
2287                 return common_ioctl( bktr, cmd, arg );
2288         }
2289
2290         return( 0 );
2291 }
2292
2293
2294 /*
2295  * common ioctls
2296  */
2297 int
2298 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2299 {
2300         int                           pixfmt;
2301         unsigned int                  temp;
2302         struct meteor_pixfmt          *pf_pub;
2303
2304         switch (cmd) {
2305
2306         case METEORSINPUT:      /* set input device */
2307                 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2308                 /* On the original bt848 boards, */
2309                 /*   Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2310                 /* On the Hauppauge bt878 boards, */
2311                 /*   Tuner is MUX0, RCA is MUX3 */
2312                 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2313                 /* stick with this system in our Meteor Emulation */
2314
2315                 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2316
2317                 /* this is the RCA video input */
2318                 case 0:         /* default */
2319                 case METEOR_INPUT_DEV0:
2320                   /* METEOR_INPUT_DEV_RCA: */
2321                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2322                           | METEOR_DEV0;
2323                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2324                                          & ~BT848_IFORM_MUXSEL);
2325
2326                         /* work around for new Hauppauge 878 cards */
2327                         if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2328                                 (bktr->id==BROOKTREE_878 ||
2329                                  bktr->id==BROOKTREE_879) )
2330                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2331                         else
2332                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2333
2334                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2335                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2336                         set_audio( bktr, AUDIO_EXTERN );
2337                         break;
2338
2339                 /* this is the tuner input */
2340                 case METEOR_INPUT_DEV1:
2341                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2342                                 | METEOR_DEV1;
2343                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2344                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2345                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2346                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2347                         set_audio( bktr, AUDIO_TUNER );
2348                         break;
2349
2350                 /* this is the S-VHS input, but with a composite camera */
2351                 case METEOR_INPUT_DEV2:
2352                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2353                                 | METEOR_DEV2;
2354                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2355                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2356                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2357                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2358                         set_audio( bktr, AUDIO_EXTERN );
2359                         break;
2360
2361                 /* this is the S-VHS input */
2362                 case METEOR_INPUT_DEV_SVIDEO:
2363                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2364                                 | METEOR_DEV_SVIDEO;
2365                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2366                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2367                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2368                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2369                         set_audio( bktr, AUDIO_EXTERN );
2370                         break;
2371
2372                 case METEOR_INPUT_DEV3:
2373                   if ((bktr->id == BROOKTREE_848A) ||
2374                       (bktr->id == BROOKTREE_849A) ||
2375                       (bktr->id == BROOKTREE_878) ||
2376                       (bktr->id == BROOKTREE_879) ) {
2377                         bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2378                                 | METEOR_DEV3;
2379                         OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2380
2381                         /* work around for new Hauppauge 878 cards */
2382                         if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2383                                 (bktr->id==BROOKTREE_878 ||
2384                                  bktr->id==BROOKTREE_879) )
2385                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2386                         else
2387                                 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2388
2389                         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2390                         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2391                         set_audio( bktr, AUDIO_EXTERN );
2392
2393                         break;
2394                   }     
2395
2396                 default:
2397                         return( EINVAL );
2398                 }
2399                 break;
2400
2401         case METEORGINPUT:      /* get input device */
2402                 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2403                 break;
2404
2405         case METEORSACTPIXFMT:
2406                 if (( *(int *)arg < 0 ) ||
2407                     ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2408                         return( EINVAL );
2409
2410                 bktr->pixfmt          = *(int *)arg;
2411                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2412                      | pixfmt_swap_flags( bktr->pixfmt ));
2413                 bktr->pixfmt_compat   = FALSE;
2414                 break;
2415         
2416         case METEORGACTPIXFMT:
2417                 *(int *)arg = bktr->pixfmt;
2418                 break;
2419
2420         case METEORGSUPPIXFMT :
2421                 pf_pub = (struct meteor_pixfmt *)arg;
2422                 pixfmt = pf_pub->index;
2423
2424                 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2425                         return( EINVAL );
2426
2427                 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public, 
2428                         sizeof( *pf_pub ) );
2429
2430                 /*  Patch in our format index  */
2431                 pf_pub->index       = pixfmt;
2432                 break;
2433
2434 #if defined( STATUS_SUM )
2435         case BT848_GSTATUS:     /* reap status */
2436                 {
2437                 DECLARE_INTR_MASK(s);
2438                 DISABLE_INTR(s);
2439                 temp = status_sum;
2440                 status_sum = 0;
2441                 ENABLE_INTR(s);
2442                 *(u_int*)arg = temp;
2443                 break;
2444                 }
2445 #endif /* STATUS_SUM */
2446
2447         default:
2448                 return( ENOTTY );
2449         }
2450
2451         return( 0 );
2452 }
2453
2454
2455
2456
2457 /******************************************************************************
2458  * bt848 RISC programming routines:
2459  */
2460
2461
2462 /*
2463  * 
2464  */
2465 #ifdef BT848_DEBUG 
2466 static int
2467 dump_bt848( bktr_ptr_t bktr )
2468 {
2469         int     r[60]={
2470                            4,    8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94, 
2471                         0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2472                         0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2473                         0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2474                         0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2475                         0,       0,    0,    0
2476                    };
2477         int     i;
2478
2479         for (i = 0; i < 40; i+=4) {
2480                 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2481                        bktr_name(bktr), 
2482                        r[i], INL(bktr, r[i]),
2483                        r[i+1], INL(bktr, r[i+1]),
2484                        r[i+2], INL(bktr, r[i+2]),
2485                        r[i+3], INL(bktr, r[i+3]]));
2486         }
2487
2488         printf("%s: INT STAT %x \n", bktr_name(bktr),
2489                INL(bktr, BKTR_INT_STAT)); 
2490         printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2491                INL(bktr, BKTR_INT_MASK));
2492         printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2493                INW(bktr, BKTR_GPIO_DMA_CTL));
2494
2495         return( 0 );
2496 }
2497
2498 #endif
2499
2500 /*
2501  * build write instruction
2502  */
2503 #define BKTR_FM1      0x6       /* packed data to follow */
2504 #define BKTR_FM3      0xe       /* planar data to follow */
2505 #define BKTR_VRE      0x4       /* Marks the end of the even field */
2506 #define BKTR_VRO      0xC       /* Marks the end of the odd field */
2507 #define BKTR_PXV      0x0       /* valid word (never used) */
2508 #define BKTR_EOL      0x1       /* last dword, 4 bytes */
2509 #define BKTR_SOL      0x2       /* first dword */
2510
2511 #define OP_WRITE      (0x1 << 28)
2512 #define OP_SKIP       (0x2 << 28)
2513 #define OP_WRITEC     (0x5 << 28)
2514 #define OP_JUMP       (0x7 << 28)
2515 #define OP_SYNC       (0x8 << 28)
2516 #define OP_WRITE123   (0x9 << 28)
2517 #define OP_WRITES123  (0xb << 28)
2518 #define OP_SOL        (1 << 27)         /* first instr for scanline */
2519 #define OP_EOL        (1 << 26)
2520
2521 #define BKTR_RESYNC   (1 << 15)
2522 #define BKTR_GEN_IRQ  (1 << 24)
2523
2524 /*
2525  * The RISC status bits can be set/cleared in the RISC programs
2526  * and tested in the Interrupt Handler
2527  */
2528 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2529 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2530 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2531 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2532
2533 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2534 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2535 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2536 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2537
2538 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2539 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2540 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2541 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2542
2543 bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2544     int i;
2545     bktr_clip_t * clip_node;
2546     bktr->clip_start = -1;
2547     bktr->last_y = 0;
2548     bktr->y = 0;
2549     bktr->y2 = width;
2550     bktr->line_length = width;
2551     bktr->yclip = -1;
2552     bktr->yclip2 = -1;
2553     bktr->current_col = 0;
2554     
2555     if (bktr->max_clip_node == 0 ) return TRUE;
2556     clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2557
2558
2559     for (i = 0; i < bktr->max_clip_node; i++ ) {
2560         clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2561         if (x >= clip_node->x_min && x <= clip_node->x_max  ) {
2562             bktr->clip_start = i;
2563             return FALSE;
2564         }
2565     }   
2566     
2567     return TRUE;
2568 }       
2569
2570 bool_t getline(bktr_reg_t *bktr, int x ) {
2571     int i, j;
2572     bktr_clip_t * clip_node ;
2573     
2574     if (bktr->line_length == 0 || 
2575         bktr->current_col >= bktr->line_length) return FALSE;
2576
2577     bktr->y = min(bktr->last_y, bktr->line_length);
2578     bktr->y2 = bktr->line_length;
2579
2580     bktr->yclip = bktr->yclip2 = -1;
2581     for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2582         clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2583         if (x >= clip_node->x_min && x <= clip_node->x_max) {
2584             if (bktr->last_y <= clip_node->y_min) {
2585                 bktr->y =      min(bktr->last_y, bktr->line_length);
2586                 bktr->y2 =     min(clip_node->y_min, bktr->line_length);
2587                 bktr->yclip =  min(clip_node->y_min, bktr->line_length);
2588                 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2589                 bktr->last_y = bktr->yclip2;
2590                 bktr->clip_start = i;
2591                 
2592                 for (j = i+1; j  < bktr->max_clip_node; j++ ) {
2593                     clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2594                     if (x >= clip_node->x_min && x <= clip_node->x_max) {
2595                         if (bktr->last_y >= clip_node->y_min) {
2596                             bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2597                             bktr->last_y = bktr->yclip2;
2598                             bktr->clip_start = j;
2599                         }       
2600                     } else break  ;
2601                 }       
2602                 return TRUE;
2603             }   
2604         }
2605     }
2606
2607     if (bktr->current_col <= bktr->line_length) {
2608         bktr->current_col = bktr->line_length;
2609         return TRUE;
2610     }
2611     return FALSE;
2612 }
2613     
2614 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2615                     u_long operation, int pixel_width,
2616                     volatile u_char ** target_buffer, int cols ) {
2617
2618  u_long flag, flag2;
2619  struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2620  u_int  skip, start_skip;
2621
2622   /*  For RGB24, we need to align the component in FIFO Byte Lane 0         */
2623   /*    to the 1st byte in the mem dword containing our start addr.         */
2624   /*    BTW, we know this pixfmt's 1st byte is Blue; thus the start addr    */
2625   /*     must be Blue.                                                      */
2626   start_skip = 0;
2627   if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2628           switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2629           case 2 : start_skip = 4 ; break;
2630           case 1 : start_skip = 8 ; break;
2631           }
2632
2633  if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2634      if (  width == cols) {
2635          flag = OP_SOL | OP_EOL;
2636        } else if (bktr->current_col == 0 ) {
2637             flag  = OP_SOL;
2638        } else if (bktr->current_col == cols) {
2639             flag = OP_EOL;
2640        } else flag = 0; 
2641
2642      skip = 0;
2643      if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2644              *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2645              flag &= ~OP_SOL;
2646              skip = start_skip;
2647      }
2648
2649      *(*dma_prog)++ = operation | flag  | (width * pixel_width - skip);
2650      if (operation != OP_SKIP ) 
2651          *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2652
2653      *target_buffer += width * pixel_width;
2654      bktr->current_col += width;
2655
2656  } else {
2657
2658         if (bktr->current_col == 0 && width == cols) {
2659             flag = OP_SOL ;
2660             flag2 = OP_EOL;
2661         } else if (bktr->current_col == 0 ) {
2662             flag = OP_SOL;
2663             flag2 = 0;
2664         } else if (bktr->current_col >= cols)  {
2665             flag =  0;
2666             flag2 = OP_EOL;
2667         } else {
2668             flag =  0;
2669             flag2 = 0;
2670         }
2671
2672         skip = 0;
2673         if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2674                 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2675                 flag &= ~OP_SOL;
2676                 skip = start_skip;
2677         }
2678
2679         *(*dma_prog)++ = operation  | flag |
2680               (width * pixel_width / 2 - skip);
2681         if (operation != OP_SKIP ) 
2682               *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2683         *target_buffer +=  (width * pixel_width / 2) ;
2684
2685         if ( operation == OP_WRITE )
2686                 operation = OP_WRITEC;
2687         *(*dma_prog)++ = operation | flag2 |
2688             (width * pixel_width / 2);
2689         *target_buffer +=  (width * pixel_width / 2) ;
2690           bktr->current_col += width;
2691
2692     }
2693  return TRUE;
2694 }
2695
2696
2697 /*
2698  * Generate the RISC instructions to capture both VBI and video images
2699  */
2700 static void
2701 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2702 {
2703         int                     i;
2704         volatile u_long         target_buffer, buffer, target,width;
2705         volatile u_long         pitch;
2706         volatile u_long         *dma_prog;      /* DMA prog is an array of 
2707                                                 32 bit RISC instructions */
2708         volatile u_long         *loop_point;
2709         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2710         u_int                   Bpp = pf_int->public.Bpp;
2711         unsigned int            vbisamples;     /* VBI samples per line */
2712         unsigned int            vbilines;       /* VBI lines per field */
2713         unsigned int            num_dwords;     /* DWORDS per line */
2714
2715         vbisamples = format_params[bktr->format_params].vbi_num_samples;
2716         vbilines   = format_params[bktr->format_params].vbi_num_lines;
2717         num_dwords = vbisamples/4;
2718
2719         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2720         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2721         OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2722         OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay    */
2723                                                             /* no ext frame */
2724
2725         OUTB(bktr, BKTR_OFORM, 0x00);
2726
2727         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2728         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2729         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2730         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2731
2732         /* disable gamma correction removal */
2733         OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2734
2735         if (cols > 385 ) {
2736             OUTB(bktr, BKTR_E_VTC, 0);
2737             OUTB(bktr, BKTR_O_VTC, 0);
2738         } else {
2739             OUTB(bktr, BKTR_E_VTC, 1);
2740             OUTB(bktr, BKTR_O_VTC, 1);
2741         }
2742         bktr->capcontrol = 3 << 2 |  3;
2743
2744         dma_prog = (u_long *) bktr->dma_prog;
2745
2746         /* Construct Write */
2747
2748         if (bktr->video.addr) {
2749                 target_buffer = (u_long) bktr->video.addr;
2750                 pitch = bktr->video.width;
2751         }
2752         else {
2753                 target_buffer = (u_long) vtophys(bktr->bigbuf);
2754                 pitch = cols*Bpp;
2755         }
2756
2757         buffer = target_buffer;
2758
2759         /* Wait for the VRE sync marking the end of the Even and
2760          * the start of the Odd field. Resync here.
2761          */
2762         *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2763         *dma_prog++ = 0;
2764
2765         loop_point = dma_prog;
2766
2767         /* store the VBI data */
2768         /* look for sync with packed data */
2769         *dma_prog++ = OP_SYNC | BKTR_FM1;
2770         *dma_prog++ = 0;
2771         for(i = 0; i < vbilines; i++) {
2772                 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2773                 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2774                                         (i * VBI_LINE_SIZE));
2775         }
2776
2777         if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) { 
2778                 /* store the Odd field video image */
2779                 /* look for sync with packed data */
2780                 *dma_prog++ = OP_SYNC  | BKTR_FM1;
2781                 *dma_prog++ = 0;  /* NULL WORD */
2782                 width = cols;
2783                 for (i = 0; i < (rows/interlace); i++) {
2784                     target = target_buffer;
2785                     if ( notclipped(bktr, i, width)) {
2786                         split(bktr, (volatile u_long **) &dma_prog,
2787                               bktr->y2 - bktr->y, OP_WRITE,
2788                               Bpp, (volatile u_char **) &target,  cols);
2789         
2790                     } else {
2791                         while(getline(bktr, i)) {
2792                             if (bktr->y != bktr->y2 ) {
2793                                 split(bktr, (volatile u_long **) &dma_prog,
2794                                       bktr->y2 - bktr->y, OP_WRITE,
2795                                       Bpp, (volatile u_char **) &target, cols);
2796                             }
2797                             if (bktr->yclip != bktr->yclip2 ) {
2798                                 split(bktr,(volatile u_long **) &dma_prog,
2799                                       bktr->yclip2 - bktr->yclip,
2800                                       OP_SKIP,
2801                                       Bpp, (volatile u_char **) &target,  cols);
2802                             }
2803                         }
2804                         
2805                     }
2806         
2807                     target_buffer += interlace * pitch;
2808         
2809                 }
2810
2811         } /* end if */
2812
2813         /* Grab the Even field */
2814         /* Look for the VRO, end of Odd field, marker */
2815         *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2816         *dma_prog++ = 0;  /* NULL WORD */
2817
2818         /* store the VBI data */
2819         /* look for sync with packed data */
2820         *dma_prog++ = OP_SYNC | BKTR_FM1;
2821         *dma_prog++ = 0;
2822         for(i = 0; i < vbilines; i++) {
2823                 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2824                 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2825                                 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2826         }
2827
2828         /* store the video image */
2829         if (i_flag == 1) /*Even Only*/
2830                 target_buffer = buffer;
2831         if (i_flag == 3) /*interlaced*/
2832                 target_buffer = buffer+pitch;
2833
2834
2835         if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2836                 /* look for sync with packed data */
2837                 *dma_prog++ = OP_SYNC | BKTR_FM1;
2838                 *dma_prog++ = 0;  /* NULL WORD */
2839                 width = cols;
2840                 for (i = 0; i < (rows/interlace); i++) {
2841                     target = target_buffer;
2842                     if ( notclipped(bktr, i, width)) {
2843                         split(bktr, (volatile u_long **) &dma_prog,
2844                               bktr->y2 - bktr->y, OP_WRITE,
2845                               Bpp, (volatile u_char **) &target,  cols);
2846                     } else {
2847                         while(getline(bktr, i)) {
2848                             if (bktr->y != bktr->y2 ) {
2849                                 split(bktr, (volatile u_long **) &dma_prog,
2850                                       bktr->y2 - bktr->y, OP_WRITE,
2851                                       Bpp, (volatile u_char **) &target,
2852                                       cols);
2853                             }   
2854                             if (bktr->yclip != bktr->yclip2 ) {
2855                                 split(bktr, (volatile u_long **) &dma_prog,
2856                                       bktr->yclip2 - bktr->yclip, OP_SKIP,
2857                                       Bpp, (volatile u_char **)  &target,  cols);
2858                             }   
2859
2860                         }       
2861
2862                     }
2863
2864                     target_buffer += interlace * pitch;
2865
2866                 }
2867         }
2868
2869         /* Look for end of 'Even Field' */
2870         *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2871         *dma_prog++ = 0;  /* NULL WORD */
2872
2873         *dma_prog++ = OP_JUMP ;
2874         *dma_prog++ = (u_long ) vtophys(loop_point) ;
2875         *dma_prog++ = 0;  /* NULL WORD */
2876
2877 }
2878
2879
2880
2881
2882 static void
2883 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2884 {
2885         int                     i;
2886         volatile u_long         target_buffer, buffer, target,width;
2887         volatile u_long         pitch;
2888         volatile  u_long        *dma_prog;
2889         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2890         u_int                   Bpp = pf_int->public.Bpp;
2891
2892         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2893         OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2894         OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2895         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2896
2897         OUTB(bktr, BKTR_OFORM, 0x00);
2898
2899         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2900         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2901         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2902         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2903
2904         /* disable gamma correction removal */
2905         OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2906
2907         if (cols > 385 ) {
2908             OUTB(bktr, BKTR_E_VTC, 0);
2909             OUTB(bktr, BKTR_O_VTC, 0);
2910         } else {
2911             OUTB(bktr, BKTR_E_VTC, 1);
2912             OUTB(bktr, BKTR_O_VTC, 1);
2913         }
2914         bktr->capcontrol = 3 << 2 |  3;
2915
2916         dma_prog = (u_long *) bktr->dma_prog;
2917
2918         /* Construct Write */
2919
2920         if (bktr->video.addr) {
2921                 target_buffer = (u_long) bktr->video.addr;
2922                 pitch = bktr->video.width;
2923         }
2924         else {
2925                 target_buffer = (u_long) vtophys(bktr->bigbuf);
2926                 pitch = cols*Bpp;
2927         }
2928
2929         buffer = target_buffer;
2930
2931         /* contruct sync : for video packet format */
2932         *dma_prog++ = OP_SYNC  | BKTR_RESYNC | BKTR_FM1;
2933
2934         /* sync, mode indicator packed data */
2935         *dma_prog++ = 0;  /* NULL WORD */
2936         width = cols;
2937         for (i = 0; i < (rows/interlace); i++) {
2938             target = target_buffer;
2939             if ( notclipped(bktr, i, width)) {
2940                 split(bktr, (volatile u_long **) &dma_prog,
2941                       bktr->y2 - bktr->y, OP_WRITE,
2942                       Bpp, (volatile u_char **) &target,  cols);
2943
2944             } else {
2945                 while(getline(bktr, i)) {
2946                     if (bktr->y != bktr->y2 ) {
2947                         split(bktr, (volatile u_long **) &dma_prog,
2948                               bktr->y2 - bktr->y, OP_WRITE,
2949                               Bpp, (volatile u_char **) &target, cols);
2950                     }
2951                     if (bktr->yclip != bktr->yclip2 ) {
2952                         split(bktr,(volatile u_long **) &dma_prog,
2953                               bktr->yclip2 - bktr->yclip,
2954                               OP_SKIP,
2955                               Bpp, (volatile u_char **) &target,  cols);
2956                     }
2957                 }
2958
2959             }
2960
2961             target_buffer += interlace * pitch;
2962
2963         }
2964
2965         switch (i_flag) {
2966         case 1:
2967                 /* sync vre */
2968                 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2969                 *dma_prog++ = 0;  /* NULL WORD */
2970
2971                 *dma_prog++ = OP_JUMP;
2972                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2973                 return;
2974
2975         case 2:
2976                 /* sync vro */
2977                 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2978                 *dma_prog++ = 0;  /* NULL WORD */
2979
2980                 *dma_prog++ = OP_JUMP;
2981                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2982                 return;
2983
2984         case 3:
2985                 /* sync vro */
2986                 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2987                 *dma_prog++ = 0;  /* NULL WORD */
2988                 *dma_prog++ = OP_JUMP; ;
2989                 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
2990                 break;
2991         }
2992
2993         if (interlace == 2) {
2994
2995                 target_buffer = buffer + pitch; 
2996
2997                 dma_prog = (u_long *) bktr->odd_dma_prog;
2998
2999                 /* sync vre IRQ bit */
3000                 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3001                 *dma_prog++ = 0;  /* NULL WORD */
3002                 width = cols;
3003                 for (i = 0; i < (rows/interlace); i++) {
3004                     target = target_buffer;
3005                     if ( notclipped(bktr, i, width)) {
3006                         split(bktr, (volatile u_long **) &dma_prog,
3007                               bktr->y2 - bktr->y, OP_WRITE,
3008                               Bpp, (volatile u_char **) &target,  cols);
3009                     } else {
3010                         while(getline(bktr, i)) {
3011                             if (bktr->y != bktr->y2 ) {
3012                                 split(bktr, (volatile u_long **) &dma_prog,
3013                                       bktr->y2 - bktr->y, OP_WRITE,
3014                                       Bpp, (volatile u_char **) &target,
3015                                       cols);
3016                             }   
3017                             if (bktr->yclip != bktr->yclip2 ) {
3018                                 split(bktr, (volatile u_long **) &dma_prog,
3019                                       bktr->yclip2 - bktr->yclip, OP_SKIP,
3020                                       Bpp, (volatile u_char **)  &target,  cols);
3021                             }   
3022
3023                         }       
3024
3025                     }
3026
3027                     target_buffer += interlace * pitch;
3028
3029                 }
3030         }
3031
3032         /* sync vre IRQ bit */
3033         *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3034         *dma_prog++ = 0;  /* NULL WORD */
3035         *dma_prog++ = OP_JUMP ;
3036         *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3037         *dma_prog++ = 0;  /* NULL WORD */
3038 }
3039
3040
3041 /*
3042  * 
3043  */
3044 static void
3045 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3046               int cols, int rows, int interlace )
3047 {
3048         int                     i;
3049         volatile unsigned int   inst;
3050         volatile unsigned int   inst3;
3051         volatile u_long         target_buffer, buffer;
3052         volatile  u_long        *dma_prog;
3053         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3054         int                     b;
3055
3056         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3057
3058         OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3059         OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3060
3061         OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3062         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3063
3064         bktr->capcontrol =   1 << 6 | 1 << 4 | 1 << 2 | 3;
3065         bktr->capcontrol = 3 << 2 |  3;
3066
3067         dma_prog = (u_long *) bktr->dma_prog;
3068
3069         /* Construct Write */
3070     
3071         /* write , sol, eol */
3072         inst = OP_WRITE  | OP_SOL | (cols);
3073         /* write , sol, eol */
3074         inst3 = OP_WRITE | OP_EOL | (cols);
3075
3076         if (bktr->video.addr)
3077                 target_buffer = (u_long) bktr->video.addr;
3078         else
3079                 target_buffer = (u_long) vtophys(bktr->bigbuf);
3080
3081         buffer = target_buffer;
3082
3083         /* contruct sync : for video packet format */
3084         /* sync, mode indicator packed data */
3085         *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3086         *dma_prog++ = 0;  /* NULL WORD */
3087
3088         b = cols;
3089
3090         for (i = 0; i < (rows/interlace); i++) {
3091                 *dma_prog++ = inst;
3092                 *dma_prog++ = target_buffer;
3093                 *dma_prog++ = inst3;
3094                 *dma_prog++ = target_buffer + b; 
3095                 target_buffer += interlace*(cols * 2);
3096         }
3097
3098         switch (i_flag) {
3099         case 1:
3100                 /* sync vre */
3101                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRE;
3102                 *dma_prog++ = 0;  /* NULL WORD */
3103
3104                 *dma_prog++ = OP_JUMP;
3105                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3106                 return;
3107
3108         case 2:
3109                 /* sync vro */
3110                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRO;
3111                 *dma_prog++ = 0;  /* NULL WORD */
3112                 *dma_prog++ = OP_JUMP;
3113                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3114                 return;
3115
3116         case 3:
3117                 /* sync vro */
3118                 *dma_prog++ = OP_SYNC    | 1 << 24 | 1 << 15 | BKTR_VRO;
3119                 *dma_prog++ = 0;  /* NULL WORD */
3120                 *dma_prog++ = OP_JUMP  ;
3121                 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3122                 break;
3123         }
3124
3125         if (interlace == 2) {
3126
3127                 target_buffer =  (u_long) buffer + cols*2;
3128
3129                 dma_prog = (u_long * ) bktr->odd_dma_prog;
3130
3131                 /* sync vre */
3132                 *dma_prog++ = OP_SYNC | 1 << 24 |  1 << 15 | BKTR_FM1;
3133                 *dma_prog++ = 0;  /* NULL WORD */
3134
3135                 for (i = 0; i < (rows/interlace) ; i++) {
3136                         *dma_prog++ = inst;
3137                         *dma_prog++ = target_buffer;
3138                         *dma_prog++ = inst3;
3139                         *dma_prog++ = target_buffer + b;
3140                         target_buffer += interlace * ( cols*2);
3141                 }
3142         }
3143
3144         /* sync vro IRQ bit */
3145         *dma_prog++ = OP_SYNC   |  1 << 24  | 1 << 15 |  BKTR_VRE;
3146         *dma_prog++ = 0;  /* NULL WORD */
3147         *dma_prog++ = OP_JUMP ;
3148         *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3149
3150         *dma_prog++ = OP_JUMP;
3151         *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3152         *dma_prog++ = 0;  /* NULL WORD */
3153 }
3154
3155
3156 /*
3157  * 
3158  */
3159 static void
3160 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3161              int cols, int rows, int interlace ){
3162
3163         int                     i;
3164         volatile unsigned int   inst;
3165         volatile u_long         target_buffer, t1, buffer;
3166         volatile u_long         *dma_prog;
3167         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3168
3169         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3170
3171         dma_prog = (u_long *) bktr->dma_prog;
3172
3173         bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
3174
3175         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3176         OUTB(bktr, BKTR_OFORM, 0x00);
3177
3178         OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3179         OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3180
3181         OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC);      /* chroma agc enable */
3182         OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3183
3184         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3185         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3186         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ~0x40); /* set chroma comb */
3187         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ~0x40);
3188
3189         /* disable gamma correction removal */
3190         OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3191
3192         /* Construct Write */
3193         inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols); 
3194         if (bktr->video.addr)
3195                 target_buffer = (u_long) bktr->video.addr;
3196         else
3197                 target_buffer = (u_long) vtophys(bktr->bigbuf);
3198     
3199         buffer = target_buffer;
3200
3201         t1 = buffer;
3202
3203         /* contruct sync : for video packet format */
3204         *dma_prog++ = OP_SYNC  | 1 << 15 |      BKTR_FM3; /*sync, mode indicator packed data*/
3205         *dma_prog++ = 0;  /* NULL WORD */
3206
3207         for (i = 0; i < (rows/interlace ) ; i++) {
3208                 *dma_prog++ = inst;
3209                 *dma_prog++ = cols/2 | cols/2 << 16;
3210                 *dma_prog++ = target_buffer;
3211                 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3212                 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3213                 target_buffer += interlace*cols;
3214         }
3215
3216         switch (i_flag) {
3217         case 1:
3218                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRE;  /*sync vre*/
3219                 *dma_prog++ = 0;  /* NULL WORD */
3220
3221                 *dma_prog++ = OP_JUMP ;
3222                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3223                 return;
3224
3225         case 2:
3226                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRO;  /*sync vre*/
3227                 *dma_prog++ = 0;  /* NULL WORD */
3228
3229                 *dma_prog++ = OP_JUMP;
3230                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3231                 return;
3232
3233         case 3:
3234                 *dma_prog++ = OP_SYNC   | 1 << 24 |  1 << 15 |   BKTR_VRO; 
3235                 *dma_prog++ = 0;  /* NULL WORD */
3236
3237                 *dma_prog++ = OP_JUMP  ;
3238                 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3239                 break;
3240         }
3241
3242         if (interlace == 2) {
3243
3244                 dma_prog = (u_long * ) bktr->odd_dma_prog;
3245
3246                 target_buffer  = (u_long) buffer + cols;
3247                 t1 = buffer + cols/2;
3248                 *dma_prog++ = OP_SYNC   |   1 << 15 | BKTR_FM3; 
3249                 *dma_prog++ = 0;  /* NULL WORD */
3250
3251                 for (i = 0; i < (rows/interlace )  ; i++) {
3252                         *dma_prog++ = inst;
3253                         *dma_prog++ = cols/2 | cols/2 << 16;
3254                         *dma_prog++ = target_buffer;
3255                         *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3256                         *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3257                         target_buffer += interlace*cols;
3258                 }
3259         }
3260     
3261         *dma_prog++ = OP_SYNC  | 1 << 24 | 1 << 15 |   BKTR_VRE; 
3262         *dma_prog++ = 0;  /* NULL WORD */
3263         *dma_prog++ = OP_JUMP ;
3264         *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3265         *dma_prog++ = 0;  /* NULL WORD */
3266 }
3267
3268
3269 /*
3270  * 
3271  */
3272 static void
3273 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3274              int cols, int rows, int interlace ){
3275
3276         int                     i;
3277         volatile unsigned int   inst;
3278         volatile unsigned int   inst1;
3279         volatile u_long         target_buffer, t1, buffer;
3280         volatile u_long         *dma_prog;
3281         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3282
3283         OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3284
3285         dma_prog = (u_long *) bktr->dma_prog;
3286
3287         bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
3288
3289         OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3290         OUTB(bktr, BKTR_OFORM, 0x0);
3291  
3292         /* Construct Write */
3293         inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols); 
3294         inst1  = OP_WRITES123  | OP_SOL | OP_EOL |  (cols); 
3295         if (bktr->video.addr)
3296                 target_buffer = (u_long) bktr->video.addr;
3297         else
3298                 target_buffer = (u_long) vtophys(bktr->bigbuf);
3299      
3300         buffer = target_buffer;
3301         t1 = buffer;
3302  
3303         *dma_prog++ = OP_SYNC  | 1 << 15 |      BKTR_FM3; /*sync, mode indicator packed data*/
3304         *dma_prog++ = 0;  /* NULL WORD */
3305                
3306         for (i = 0; i < (rows/interlace )/2 ; i++) {
3307                 *dma_prog++ = inst;
3308                 *dma_prog++ = cols/2 | (cols/2 << 16);
3309                 *dma_prog++ = target_buffer;
3310                 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3311                 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3312                 target_buffer += interlace*cols;
3313                 *dma_prog++ = inst1;
3314                 *dma_prog++ = cols/2 | (cols/2 << 16);
3315                 *dma_prog++ = target_buffer;
3316                 target_buffer += interlace*cols;
3317  
3318         }
3319  
3320         switch (i_flag) {
3321         case 1:
3322                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRE;  /*sync vre*/
3323                 *dma_prog++ = 0;  /* NULL WORD */
3324
3325                 *dma_prog++ = OP_JUMP;
3326                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3327                 return;
3328
3329         case 2:
3330                 *dma_prog++ = OP_SYNC  | 1 << 24 | BKTR_VRO;  /*sync vro*/
3331                 *dma_prog++ = 0;  /* NULL WORD */
3332
3333                 *dma_prog++ = OP_JUMP;
3334                 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3335                 return;
3336  
3337         case 3:
3338                 *dma_prog++ = OP_SYNC |  1 << 24 | 1 << 15 | BKTR_VRO;
3339                 *dma_prog++ = 0;  /* NULL WORD */
3340                 *dma_prog++ = OP_JUMP ;
3341                 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3342                 break;
3343         }
3344
3345         if (interlace == 2) {
3346
3347                 dma_prog = (u_long * ) bktr->odd_dma_prog;
3348
3349                 target_buffer  = (u_long) buffer + cols;
3350                 t1 = buffer + cols/2;
3351                 *dma_prog++ = OP_SYNC   | 1 << 15 | BKTR_FM3; 
3352                 *dma_prog++ = 0;  /* NULL WORD */
3353
3354                 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3355                     *dma_prog++ = inst;
3356                     *dma_prog++ = cols/2 | (cols/2 << 16);
3357                     *dma_prog++ = target_buffer;
3358                     *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3359                     *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3360                     target_buffer += interlace*cols;
3361                     *dma_prog++ = inst1;
3362                     *dma_prog++ = cols/2 | (cols/2 << 16);
3363                     *dma_prog++ = target_buffer;
3364                     target_buffer += interlace*cols;
3365
3366                 }       
3367
3368         
3369         }
3370     
3371         *dma_prog++ = OP_SYNC |  1 << 24 | 1 << 15 | BKTR_VRE;
3372         *dma_prog++ = 0;  /* NULL WORD */
3373         *dma_prog++ = OP_JUMP;
3374         *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3375         *dma_prog++ = 0;  /* NULL WORD */
3376 }
3377   
3378
3379
3380 /*
3381  * 
3382  */
3383 static void
3384 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3385 {
3386         int                     rows, cols,  interlace;
3387         int                     tmp_int;
3388         unsigned int            temp;   
3389         struct format_params    *fp;
3390         struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3391         
3392
3393         fp = &format_params[bktr->format_params];
3394
3395         OUTL(bktr, BKTR_INT_MASK,  ALL_INTS_DISABLED);
3396
3397         /* disable FIFO & RISC, leave other bits alone */
3398         OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3399
3400         /* set video parameters */
3401         if (bktr->capture_area_enabled)
3402           temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3403                   / fp->scaled_htotal / bktr->cols) -  4096;
3404         else
3405           temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3406                   / fp->scaled_htotal / bktr->cols) -  4096;
3407
3408         /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3409         OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3410         OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3411         OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3412         OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3413  
3414         /* horizontal active */
3415         temp = bktr->cols;
3416         /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3417         OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3418         OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3419         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3420         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3421         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3422         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3423  
3424         /* horizontal delay */
3425         if (bktr->capture_area_enabled)
3426           temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3427                  * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3428         else
3429           temp = (fp->hdelay * bktr->cols) / fp->hactive;
3430
3431         temp = temp & 0x3fe;
3432
3433         /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3434         OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3435         OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3436         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3437         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3438         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3439         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3440
3441         /* vertical scale */
3442
3443         if (bktr->capture_area_enabled) {
3444           if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3445               bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3446             tmp_int = 65536 -
3447             (((bktr->capture_area_y_size  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3448           else {
3449             tmp_int = 65536 -
3450             (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3451           }
3452         } else {
3453           if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
3454               bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3455             tmp_int = 65536 -
3456             (((fp->vactive  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3457           else {
3458             tmp_int = 65536  -
3459             (((fp->vactive * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
3460           }
3461         }
3462
3463         tmp_int &= 0x1fff;
3464         /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3465         OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3466         OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3467         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3468         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3469         OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3470         OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3471
3472
3473         /* vertical active */
3474         if (bktr->capture_area_enabled)
3475           temp = bktr->capture_area_y_size;
3476         else
3477           temp = fp->vactive;
3478         /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3479         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3480         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3481         OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3482         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3483         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3484         OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3485  
3486         /* vertical delay */
3487         if (bktr->capture_area_enabled)
3488           temp = fp->vdelay + (bktr->capture_area_y_offset);
3489         else
3490           temp = fp->vdelay;
3491         /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3492         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3493         OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3494         OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3495         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3496         OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3497         OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3498
3499         /* end of video params */
3500
3501         if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3502            && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3503                 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3504         } else {
3505                 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3506         }
3507
3508         /* capture control */
3509         switch (i_flag) {
3510         case 1:
3511                 bktr->bktr_cap_ctl = 
3512                     (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3513                 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3514                 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3515                 interlace = 1;
3516                 break;
3517          case 2:
3518                 bktr->bktr_cap_ctl =
3519                         (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3520                 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3521                 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3522                 interlace = 1;
3523                 break;
3524          default:
3525                 bktr->bktr_cap_ctl = 
3526                         (BT848_CAP_CTL_DITH_FRAME |
3527                          BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3528                 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3529                 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3530                 interlace = 2;
3531                 break;
3532         }
3533
3534         OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3535
3536         rows = bktr->rows;
3537         cols = bktr->cols;
3538
3539         bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3540
3541         /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3542         /* user, then use the rgb_vbi RISC program. */
3543         /* Otherwise, use the normal rgb RISC program */
3544         if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3545                 if ( (bktr->vbiflags & VBI_OPEN)
3546                    ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3547                    ||(bktr->format_params == BT848_IFORM_F_SECAM)
3548                    ){
3549                         bktr->bktr_cap_ctl |=
3550                                 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3551                         bktr->vbiflags |= VBI_CAPTURE;
3552                         rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3553                         return;
3554                 } else {
3555                         rgb_prog(bktr, i_flag, cols, rows, interlace);
3556                         return;
3557                 }
3558         }
3559
3560         if ( pf_int->public.type  == METEOR_PIXTYPE_YUV ) {
3561                 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3562                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3563                      | pixfmt_swap_flags( bktr->pixfmt ));
3564                 return;
3565         }
3566
3567         if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_PACKED ) {
3568                 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3569                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3570                      | pixfmt_swap_flags( bktr->pixfmt ));
3571                 return;
3572         }
3573
3574         if ( pf_int->public.type  == METEOR_PIXTYPE_YUV_12 ) {
3575                 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3576                 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3577                      | pixfmt_swap_flags( bktr->pixfmt ));
3578                 return;
3579         }
3580         return;
3581 }
3582
3583
3584 /******************************************************************************
3585  * video & video capture specific routines:
3586  */
3587
3588
3589 /*
3590  * 
3591  */
3592 static void
3593 start_capture( bktr_ptr_t bktr, unsigned type )
3594 {
3595         u_char                  i_flag;
3596         struct format_params   *fp;
3597
3598         fp = &format_params[bktr->format_params];
3599
3600         /*  If requested, clear out capture buf first  */
3601         if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3602                 bzero((caddr_t)bktr->bigbuf, 
3603                       (size_t)bktr->rows * bktr->cols * bktr->frames *
3604                         pixfmt_table[ bktr->pixfmt ].public.Bpp);
3605         }
3606
3607         OUTB(bktr, BKTR_DSTATUS,  0);
3608         OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3609
3610         bktr->flags |= type;
3611         bktr->flags &= ~METEOR_WANT_MASK;
3612         switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3613         case METEOR_ONLY_EVEN_FIELDS:
3614                 bktr->flags |= METEOR_WANT_EVEN;
3615                 i_flag = 1;
3616                 break;
3617         case METEOR_ONLY_ODD_FIELDS:
3618                 bktr->flags |= METEOR_WANT_ODD;
3619                 i_flag = 2;
3620                 break;
3621         default:
3622                 bktr->flags |= METEOR_WANT_MASK;
3623                 i_flag = 3;
3624                 break;
3625         }
3626
3627         /*  TDEC is only valid for continuous captures  */
3628         if ( type == METEOR_SINGLE ) {
3629                 u_short fps_save = bktr->fps;
3630
3631                 set_fps(bktr, fp->frame_rate);
3632                 bktr->fps = fps_save;
3633         }
3634         else
3635                 set_fps(bktr, bktr->fps);
3636
3637         if (bktr->dma_prog_loaded == FALSE) {
3638                 build_dma_prog(bktr, i_flag);
3639                 bktr->dma_prog_loaded = TRUE;
3640         }
3641         
3642
3643         OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3644
3645 }
3646
3647
3648 /*
3649  * 
3650  */
3651 static void
3652 set_fps( bktr_ptr_t bktr, u_short fps )
3653 {
3654         struct format_params    *fp;
3655         int i_flag;
3656
3657         fp = &format_params[bktr->format_params];
3658
3659         switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3660         case METEOR_ONLY_EVEN_FIELDS:
3661                 bktr->flags |= METEOR_WANT_EVEN;
3662                 i_flag = 1;
3663                 break;
3664         case METEOR_ONLY_ODD_FIELDS:
3665                 bktr->flags |= METEOR_WANT_ODD;
3666                 i_flag = 1;
3667                 break;
3668         default:
3669                 bktr->flags |= METEOR_WANT_MASK;
3670                 i_flag = 2;
3671                 break;
3672         }
3673
3674         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3675         OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3676
3677         bktr->fps = fps;
3678         OUTB(bktr, BKTR_TDEC, 0);
3679
3680         if (fps < fp->frame_rate)
3681                 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3682         else
3683                 OUTB(bktr, BKTR_TDEC, 0);
3684         return;
3685
3686 }
3687
3688
3689
3690
3691
3692 /* 
3693  * Given a pixfmt index, compute the bt848 swap_flags necessary to 
3694  *   achieve the specified swapping.
3695  * Note that without bt swapping, 2Bpp and 3Bpp modes are written 
3696  *   byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6 
3697  *   and read R->L).  
3698  * Note also that for 3Bpp, we may additionally need to do some creative 
3699  *   SKIPing to align the FIFO bytelines with the target buffer (see split()).
3700  * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3701  *   as one would expect.
3702  */
3703
3704 static u_int pixfmt_swap_flags( int pixfmt )
3705 {
3706         struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3707         u_int                 swapf = 0;
3708
3709         switch ( pf->Bpp ) {
3710         case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3711                  break;
3712
3713         case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3714                  break;
3715                  
3716         case 4 : if ( pf->swap_bytes )
3717                         swapf = pf->swap_shorts ? 0 : WSWAP;
3718                  else
3719                         swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3720                  break;
3721         }
3722         return swapf;
3723 }
3724
3725
3726
3727 /* 
3728  * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3729  *   our pixfmt_table indices.
3730  */
3731
3732 static int oformat_meteor_to_bt( u_long format )
3733 {
3734         int    i;
3735         struct meteor_pixfmt *pf1, *pf2;
3736
3737         /*  Find format in compatibility table  */
3738         for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3739                 if ( meteor_pixfmt_table[i].meteor_format == format )
3740                         break;
3741
3742         if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3743                 return -1;
3744         pf1 = &meteor_pixfmt_table[i].public;
3745
3746         /*  Match it with an entry in master pixel format table  */
3747         for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3748                 pf2 = &pixfmt_table[i].public;
3749
3750                 if (( pf1->type        == pf2->type        ) &&
3751                     ( pf1->Bpp         == pf2->Bpp         ) &&
3752                     !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3753                     ( pf1->swap_bytes  == pf2->swap_bytes  ) &&
3754                     ( pf1->swap_shorts == pf2->swap_shorts )) 
3755                         break;
3756         }
3757         if ( i >= PIXFMT_TABLE_SIZE )
3758                 return -1;
3759
3760         return i;
3761 }
3762
3763 /******************************************************************************
3764  * i2c primitives:
3765  */
3766
3767 /* */
3768 #define I2CBITTIME              (0x5<<4)        /* 5 * 0.48uS */
3769 #define I2CBITTIME_878              (1 << 7)
3770 #define I2C_READ                0x01
3771 #define I2C_COMMAND             (I2CBITTIME |                   \
3772                                  BT848_DATA_CTL_I2CSCL |        \
3773                                  BT848_DATA_CTL_I2CSDA)
3774
3775 #define I2C_COMMAND_878         (I2CBITTIME_878 |                       \
3776                                  BT848_DATA_CTL_I2CSCL |        \
3777                                  BT848_DATA_CTL_I2CSDA)
3778
3779 /* Select between old i2c code and new iicbus / smbus code */
3780 #if defined(BKTR_USE_FREEBSD_SMBUS)
3781
3782 /*
3783  * The hardware interface is actually SMB commands
3784  */
3785 int
3786 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3787 {
3788         char cmd;
3789
3790         if (bktr->id == BROOKTREE_848  ||
3791             bktr->id == BROOKTREE_848A ||
3792             bktr->id == BROOKTREE_849A)
3793                 cmd = I2C_COMMAND;
3794         else
3795                 cmd = I2C_COMMAND_878;
3796
3797         if (byte2 != -1) {
3798                 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3799                         (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3800                         return (-1);
3801         } else {
3802                 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3803                         (char)(byte1 & 0xff)))
3804                         return (-1);
3805         }
3806
3807         /* return OK */
3808         return( 0 );
3809 }
3810
3811 int
3812 i2cRead( bktr_ptr_t bktr, int addr )
3813 {
3814         char result;
3815         char cmd;
3816
3817         if (bktr->id == BROOKTREE_848  ||
3818             bktr->id == BROOKTREE_848A ||
3819             bktr->id == BROOKTREE_849A)
3820                 cmd = I2C_COMMAND;
3821         else
3822                 cmd = I2C_COMMAND_878;
3823
3824         if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3825                 return (-1);
3826
3827         return ((int)((unsigned char)result));
3828 }
3829
3830 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3831
3832 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3833 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3834 /* Therefore we need low level control of the i2c bus hardware */
3835
3836 /* Write to the MSP or DPL registers */
3837 void
3838 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr,  unsigned char dev, unsigned int addr, unsigned int data)
3839 {
3840         unsigned char addr_l, addr_h, data_h, data_l ;
3841
3842         addr_h = (addr >>8) & 0xff;
3843         addr_l = addr & 0xff;
3844         data_h = (data >>8) & 0xff;
3845         data_l = data & 0xff;
3846
3847         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3848
3849         iicbus_write_byte(IICBUS(bktr), dev, 0);
3850         iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3851         iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3852         iicbus_write_byte(IICBUS(bktr), data_h, 0);
3853         iicbus_write_byte(IICBUS(bktr), data_l, 0);
3854
3855         iicbus_stop(IICBUS(bktr));
3856
3857         return;
3858 }
3859
3860 /* Read from the MSP or DPL registers */
3861 unsigned int
3862 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3863 {
3864         unsigned int data;
3865         unsigned char addr_l, addr_h, dev_r;
3866         int read;
3867         u_char data_read[2];
3868
3869         addr_h = (addr >>8) & 0xff;
3870         addr_l = addr & 0xff;
3871         dev_r = dev+1;
3872
3873         /* XXX errors ignored */
3874         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3875
3876         iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3877         iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3878         iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3879
3880         iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3881         iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3882         iicbus_stop(IICBUS(bktr));
3883
3884         data = (data_read[0]<<8) | data_read[1];
3885
3886         return (data);
3887 }
3888
3889 /* Reset the MSP or DPL chip */
3890 /* The user can block the reset (which is handy if you initialise the
3891  * MSP and/or DPL audio in another operating system first (eg in Windows)
3892  */
3893 void
3894 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3895 {
3896
3897 #ifndef BKTR_NO_MSP_RESET
3898         /* put into reset mode */
3899         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3900         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3901         iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3902         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3903         iicbus_stop(IICBUS(bktr));
3904
3905         /* put back to operational mode */
3906         iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3907         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3908         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3909         iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3910         iicbus_stop(IICBUS(bktr));
3911 #endif
3912         return;
3913 }
3914
3915 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3916         int read;
3917
3918         /* XXX errors ignored */
3919         iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3920         iicbus_read(IICBUS(bktr),  remote->data, 3, &read, IIC_LAST_READ, 0);
3921         iicbus_stop(IICBUS(bktr));
3922
3923         return;
3924 }
3925
3926 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3927
3928 /*
3929  * Program the i2c bus directly
3930  */
3931 int
3932 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3933 {
3934         u_long          x;
3935         u_long          data;
3936
3937         /* clear status bits */
3938         OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3939
3940         /* build the command datum */
3941         if (bktr->id == BROOKTREE_848  ||
3942             bktr->id == BROOKTREE_848A ||
3943             bktr->id == BROOKTREE_849A) {
3944           data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3945         } else {
3946           data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3947         }
3948         if ( byte2 != -1 ) {
3949                 data |= ((byte2 & 0xff) << 8);
3950                 data |= BT848_DATA_CTL_I2CW3B;
3951         }
3952
3953         /* write the address and data */
3954         OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3955
3956         /* wait for completion */
3957         for ( x = 0x7fffffff; x; --x ) {        /* safety valve */
3958                 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3959                         break;
3960         }
3961
3962         /* check for ACK */
3963         if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3964                 return( -1 );
3965
3966         /* return OK */
3967         return( 0 );
3968 }
3969
3970
3971 /*
3972  * 
3973  */
3974 int
3975 i2cRead( bktr_ptr_t bktr, int addr )
3976 {
3977         u_long          x;
3978
3979         /* clear status bits */
3980         OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3981
3982         /* write the READ address */
3983         /* The Bt878 and Bt879  differed on the treatment of i2c commands */
3984            
3985         if (bktr->id == BROOKTREE_848  ||
3986             bktr->id == BROOKTREE_848A ||
3987             bktr->id == BROOKTREE_849A) {
3988                 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3989         } else {
3990                 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3991         }
3992
3993         /* wait for completion */
3994         for ( x = 0x7fffffff; x; --x ) {        /* safety valve */
3995                 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3996                         break;
3997         }
3998
3999         /* check for ACK */
4000         if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4001                 return( -1 );
4002
4003         /* it was a read */
4004         return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4005 }
4006
4007 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4008 /* bt848 automated i2c bus controller cannot handle */
4009 /* Therefore we need low level control of the i2c bus hardware */
4010 /* Idea for the following functions are from elsewhere in this driver and */
4011 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4012
4013 #define BITD    40
4014 static void i2c_start( bktr_ptr_t bktr) {
4015         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4016         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4017         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4018         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4019 }
4020
4021 static void i2c_stop( bktr_ptr_t bktr) {
4022         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4023         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4024         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4025 }
4026
4027 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4028         int x;
4029         int status;
4030
4031         /* write out the byte */
4032         for ( x = 7; x >= 0; --x ) {
4033                 if ( data & (1<<x) ) {
4034                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4035                         DELAY( BITD );          /* assert HI data */
4036                         OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4037                         DELAY( BITD );          /* strobe clock */
4038                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4039                         DELAY( BITD );          /* release clock */
4040                 }
4041                 else {
4042                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4043                         DELAY( BITD );          /* assert LO data */
4044                         OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4045                         DELAY( BITD );          /* strobe clock */
4046                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4047                         DELAY( BITD );          /* release clock */
4048                 }
4049         }
4050
4051         /* look for an ACK */
4052         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4053         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4054         status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;       /* read the ACK bit */
4055         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4056
4057         return( status );
4058 }
4059
4060 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4061         int x;
4062         int bit;
4063         int byte = 0;
4064
4065         /* read in the byte */
4066         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4067         DELAY( BITD );                          /* float data */
4068         for ( x = 7; x >= 0; --x ) {
4069                 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4070                 DELAY( BITD );                  /* strobe clock */
4071                 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1;  /* read the data bit */
4072                 if ( bit ) byte |= (1<<x);
4073                 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4074                 DELAY( BITD );                  /* release clock */
4075         }
4076         /* After reading the byte, send an ACK */
4077         /* (unless that was the last byte, for which we send a NAK */
4078         if (last) { /* send NAK - same a writing a 1 */
4079                 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4080                 DELAY( BITD );                  /* set data bit */
4081                 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4082                 DELAY( BITD );                  /* strobe clock */
4083                 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4084                 DELAY( BITD );                  /* release clock */
4085         } else { /* send ACK - same as writing a 0 */
4086                 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4087                 DELAY( BITD );                  /* set data bit */
4088                 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4089                 DELAY( BITD );                  /* strobe clock */
4090                 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4091                 DELAY( BITD );                  /* release clock */
4092         }
4093
4094         *data=byte;
4095         return 0;
4096 }
4097 #undef BITD
4098
4099 /* Write to the MSP or DPL registers */
4100 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4101                     unsigned int data){
4102         unsigned int msp_w_addr = i2c_addr;
4103         unsigned char addr_l, addr_h, data_h, data_l ;
4104         addr_h = (addr >>8) & 0xff;
4105         addr_l = addr & 0xff;
4106         data_h = (data >>8) & 0xff;
4107         data_l = data & 0xff;
4108
4109         i2c_start(bktr);
4110         i2c_write_byte(bktr, msp_w_addr);
4111         i2c_write_byte(bktr, dev);
4112         i2c_write_byte(bktr, addr_h);
4113         i2c_write_byte(bktr, addr_l);
4114         i2c_write_byte(bktr, data_h);
4115         i2c_write_byte(bktr, data_l);
4116         i2c_stop(bktr);
4117 }
4118
4119 /* Read from the MSP or DPL registers */
4120 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4121         unsigned int data;
4122         unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4123         addr_h = (addr >>8) & 0xff;
4124         addr_l = addr & 0xff;
4125         dev_r = dev+1;
4126
4127         i2c_start(bktr);
4128         i2c_write_byte(bktr,i2c_addr);
4129         i2c_write_byte(bktr,dev_r);
4130         i2c_write_byte(bktr,addr_h);
4131         i2c_write_byte(bktr,addr_l);
4132
4133         i2c_start(bktr);
4134         i2c_write_byte(bktr,i2c_addr+1);
4135         i2c_read_byte(bktr,&data_1, 0);
4136         i2c_read_byte(bktr,&data_2, 1);
4137         i2c_stop(bktr);
4138         data = (data_1<<8) | data_2;
4139         return data;
4140 }
4141
4142 /* Reset the MSP or DPL chip */
4143 /* The user can block the reset (which is handy if you initialise the
4144  * MSP audio in another operating system first (eg in Windows)
4145  */
4146 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4147
4148 #ifndef BKTR_NO_MSP_RESET
4149         /* put into reset mode */
4150         i2c_start(bktr);
4151         i2c_write_byte(bktr, i2c_addr);
4152         i2c_write_byte(bktr, 0x00);
4153         i2c_write_byte(bktr, 0x80);
4154         i2c_write_byte(bktr, 0x00);
4155         i2c_stop(bktr);
4156
4157         /* put back to operational mode */
4158         i2c_start(bktr);
4159         i2c_write_byte(bktr, i2c_addr);
4160         i2c_write_byte(bktr, 0x00);
4161         i2c_write_byte(bktr, 0x00);
4162         i2c_write_byte(bktr, 0x00);
4163         i2c_stop(bktr);
4164 #endif
4165         return;
4166
4167 }
4168
4169 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4170
4171         /* XXX errors ignored */
4172         i2c_start(bktr);
4173         i2c_write_byte(bktr,bktr->remote_control_addr);
4174         i2c_read_byte(bktr,&(remote->data[0]), 0);
4175         i2c_read_byte(bktr,&(remote->data[1]), 0);
4176         i2c_read_byte(bktr,&(remote->data[2]), 0);
4177         i2c_stop(bktr);
4178
4179         return;
4180 }
4181
4182 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4183
4184
4185 #if defined( I2C_SOFTWARE_PROBE )
4186
4187 /*
4188  * we are keeping this around for any parts that we need to probe
4189  * but that CANNOT be probed via an i2c read.
4190  * this is necessary because the hardware i2c mechanism
4191  * cannot be programmed for 1 byte writes.
4192  * currently there are no known i2c parts that we need to probe
4193  * and that cannot be safely read.
4194  */
4195 static int      i2cProbe( bktr_ptr_t bktr, int addr );
4196 #define BITD            40
4197 #define EXTRA_START
4198
4199 /*
4200  * probe for an I2C device at addr.
4201  */
4202 static int
4203 i2cProbe( bktr_ptr_t bktr, int addr )
4204 {
4205         int             x, status;
4206
4207         /* the START */
4208 #if defined( EXTRA_START )
4209         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* release data */
4210         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* release clock */
4211 #endif /* EXTRA_START */
4212         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );        /* lower data */
4213         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );        /* lower clock */
4214
4215         /* write addr */
4216         for ( x = 7; x >= 0; --x ) {
4217                 if ( addr & (1<<x) ) {
4218                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4219                         DELAY( BITD );          /* assert HI data */
4220                         OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4221                         DELAY( BITD );          /* strobe clock */
4222                         OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4223                         DELAY( BITD );          /* release clock */
4224                 }
4225                 else {
4226                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4227                         DELAY( BITD );          /* assert LO data */
4228                         OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4229                         DELAY( BITD );          /* strobe clock */
4230                         OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4231                         DELAY( BITD );          /* release clock */
4232                 }
4233         }
4234
4235         /* look for an ACK */
4236         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* float data */
4237         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* strobe clock */
4238         status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;      /* read the ACK bit */
4239         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD );        /* release clock */
4240
4241         /* the STOP */
4242         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD );        /* lower clock & data */
4243         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD );        /* release clock */
4244         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD );        /* release data */
4245
4246         return( status );
4247 }
4248 #undef EXTRA_START
4249 #undef BITD
4250
4251 #endif /* I2C_SOFTWARE_PROBE */
4252
4253
4254 #define ABSENT          (-1)
4255
4256 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */
4257