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