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