2 * 1. Redistributions of source code must retain the
3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Amancio Hasty and
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 * 1. Redistributions of source code must retain the
35 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
36 * All rights reserved.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by Mark Tinguely and Jim Lowe
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
56 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
58 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
60 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
61 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
65 #include <sys/cdefs.h>
66 __FBSDID("$FreeBSD$");
69 * This is part of the Driver for Video Capture Cards (Frame grabbers)
70 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
72 * Copyright Roger Hardiman and Amancio Hasty.
74 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
75 * Handles all the open, close, ioctl and read userland calls.
76 * Sets the Bt848 registers and generates RISC pograms.
77 * Controls the i2c bus and GPIO interface.
78 * Contains the interface to the kernel.
79 * (eg probe/attach and open/close/ioctl)
83 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
84 Jim Lowe's driver for the Matrox Meteor PCI card . The
85 Philips SAA 7116 and SAA 7196 are very different chipsets than
88 The original copyright notice by Mark and Jim is included mostly
89 to honor their fantastic work in the Matrox Meteor driver!
92 #include "opt_bktr.h" /* Include any kernel config options */
95 (defined(__FreeBSD__)) \
96 || (defined(__bsdi__)) \
97 || (defined(__OpenBSD__)) \
98 || (defined(__NetBSD__)) \
102 /*******************/
103 /* *** FreeBSD *** */
104 /*******************/
107 #include <sys/param.h>
108 #include <sys/systm.h>
109 #include <sys/kernel.h>
110 #include <sys/fcntl.h>
111 #include <sys/lock.h>
112 #include <sys/mutex.h>
113 #include <sys/proc.h>
114 #include <sys/signalvar.h>
115 #include <sys/selinfo.h>
119 #include <vm/vm_kern.h>
121 #include <vm/vm_extern.h>
123 #include <sys/bus.h> /* used by smbus and newbus */
125 #if (__FreeBSD_version < 500000)
126 #include <machine/clock.h> /* for DELAY */
128 #define PROC_UNLOCK(p)
129 #include <pci/pcivar.h>
131 #include <dev/pci/pcivar.h>
134 #include <machine/bus.h>
137 #include <dev/bktr/ioctl_meteor.h>
138 #include <dev/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
139 #include <dev/bktr/bktr_reg.h>
140 #include <dev/bktr/bktr_tuner.h>
141 #include <dev/bktr/bktr_card.h>
142 #include <dev/bktr/bktr_audio.h>
143 #include <dev/bktr/bktr_os.h>
144 #include <dev/bktr/bktr_core.h>
145 #if defined(BKTR_FREEBSD_MODULE)
146 #include <dev/bktr/bktr_mem.h>
149 #if defined(BKTR_USE_FREEBSD_SMBUS)
150 #include <dev/bktr/bktr_i2c.h>
151 #include <dev/smbus/smbconf.h>
152 #include <dev/iicbus/iiconf.h>
153 #include "smbus_if.h"
154 #include "iicbus_if.h"
158 bktr_name(bktr_ptr_t bktr)
160 return bktr->bktr_xname;
164 #endif /* __FreeBSD__ */
172 #define PROC_UNLOCK(p)
173 #endif /* __bsdi__ */
176 /**************************/
177 /* *** OpenBSD/NetBSD *** */
178 /**************************/
179 #if defined(__NetBSD__) || defined(__OpenBSD__)
181 #include <sys/param.h>
182 #include <sys/systm.h>
183 #include <sys/kernel.h>
184 #include <sys/signalvar.h>
185 #include <sys/vnode.h>
188 #include <uvm/uvm_extern.h>
191 #include <vm/vm_kern.h>
193 #include <vm/vm_extern.h>
196 #include <sys/inttypes.h> /* uintptr_t */
197 #include <dev/ic/bt8xx.h>
198 #include <dev/pci/bktr/bktr_reg.h>
199 #include <dev/pci/bktr/bktr_tuner.h>
200 #include <dev/pci/bktr/bktr_card.h>
201 #include <dev/pci/bktr/bktr_audio.h>
202 #include <dev/pci/bktr/bktr_core.h>
203 #include <dev/pci/bktr/bktr_os.h>
205 static int bt848_format = -1;
208 bktr_name(bktr_ptr_t bktr)
210 return (bktr->bktr_dev.dv_xname);
214 #define PROC_UNLOCK(p)
216 #endif /* __NetBSD__ || __OpenBSD__ */
219 typedef u_char bool_t;
221 #define BKTRPRI (PZERO+8)|PCATCH
222 #define VBIPRI (PZERO-4)|PCATCH
226 * memory allocated for DMA programs
228 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
230 /* When to split a dma transfer , the bt848 has timing as well as
231 dma transfer size limitations so that we have to split dma
232 transfers into two dma requests
234 #define DMA_BT848_SPLIT 319*2
237 * Allocate enough memory for:
238 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
240 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
241 * in your kernel configuration file.
244 #ifndef BROOKTREE_ALLOC_PAGES
245 #define BROOKTREE_ALLOC_PAGES 217*4
247 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
249 /* Definitions for VBI capture.
250 * There are 16 VBI lines in a PAL video field (32 in a frame),
251 * and we take 2044 samples from each line (placed in a 2048 byte buffer
253 * VBI lines are held in a circular buffer before being read by a
254 * user program from /dev/vbi.
257 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
258 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
259 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
260 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
261 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
264 /* Defines for fields */
270 * Parameters describing size of transmitted image.
273 static struct format_params format_params[] = {
274 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
275 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
277 /* # define BT848_IFORM_F_NTSCM (0x1) */
278 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
280 /* # define BT848_IFORM_F_NTSCJ (0x2) */
281 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
283 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
284 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
286 /* # define BT848_IFORM_F_PALM (0x4) */
287 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
289 /* # define BT848_IFORM_F_PALN (0x5) */
290 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
292 /* # define BT848_IFORM_F_SECAM (0x6) */
293 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
295 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
296 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
301 * Table of supported Pixel Formats
304 static struct meteor_pixfmt_internal {
305 struct meteor_pixfmt public;
309 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
310 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
312 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
313 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
315 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
317 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
318 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
319 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
320 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
321 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
322 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
323 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
326 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
329 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
332 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
334 u_long meteor_format;
335 struct meteor_pixfmt public;
336 } meteor_pixfmt_table[] = {
338 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
341 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
342 { METEOR_GEO_YUV_422,
343 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
345 { METEOR_GEO_YUV_PACKED,
346 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
349 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
352 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
356 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
357 sizeof(meteor_pixfmt_table[0]) )
360 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
361 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
365 /* sync detect threshold */
367 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
368 BT848_ADC_CRUSH) /* threshold ~125 mV */
370 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
371 BT848_ADC_SYNC_T) /* threshold ~75 mV */
377 /* debug utility for holding previous INT_STAT contents */
379 static u_long status_sum = 0;
382 * defines to make certain bit-fiddles understandable
384 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
385 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
386 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
387 #define FIFO_RISC_DISABLED 0
389 #define ALL_INTS_DISABLED 0
390 #define ALL_INTS_CLEARED 0xffffffff
391 #define CAPTURE_OFF 0
393 #define BIT_SEVEN_HIGH (1<<7)
394 #define BIT_EIGHT_HIGH (1<<8)
396 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
397 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
401 static int oformat_meteor_to_bt( u_long format );
403 static u_int pixfmt_swap_flags( int pixfmt );
406 * bt848 RISC programming routines.
409 static int dump_bt848( bktr_ptr_t bktr );
412 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
413 int rows, int interlace );
414 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
415 int rows, int interlace );
416 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
417 int rows, int interlace );
418 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
419 int rows, int interlace );
420 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
421 int rows, int interlace );
422 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
424 static bool_t getline(bktr_reg_t *, int);
425 static bool_t notclipped(bktr_reg_t * , int , int);
426 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
427 volatile u_char ** , int );
429 static void start_capture( bktr_ptr_t bktr, unsigned type );
430 static void set_fps( bktr_ptr_t bktr, u_short fps );
435 * Remote Control Functions
437 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
441 * ioctls common to both video & tuner.
443 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
446 #if !defined(BKTR_USE_FREEBSD_SMBUS)
448 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
450 static void i2c_start( bktr_ptr_t bktr);
451 static void i2c_stop( bktr_ptr_t bktr);
452 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
453 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
459 * the common attach code, used by all OS versions.
462 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
465 int need_to_allocate_memory = 1;
466 #ifdef BKTR_NEW_MSP34XX_DRIVER
470 /***************************************/
471 /* *** OS Specific memory routines *** */
472 /***************************************/
473 #if defined(__NetBSD__) || defined(__OpenBSD__)
474 /* allocate space for dma program */
475 bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog,
477 bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
480 /* allocate space for the VBI buffer */
481 bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata,
483 bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
486 /* allocate space for pixel buffer */
487 if ( BROOKTREE_ALLOC )
488 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
493 #if defined(__FreeBSD__) || defined(__bsdi__)
495 /* If this is a module, check if there is any currently saved contiguous memory */
496 #if defined(BKTR_FREEBSD_MODULE)
497 if (bktr_has_stored_addresses(unit) == 1) {
498 /* recover the addresses */
499 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
500 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
501 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
502 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
503 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
504 need_to_allocate_memory = 0;
508 if (need_to_allocate_memory == 1) {
509 /* allocate space for dma program */
510 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
511 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
513 /* allocte space for the VBI buffer */
514 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
515 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
517 /* allocate space for pixel buffer */
518 if ( BROOKTREE_ALLOC )
519 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
523 #endif /* FreeBSD or BSDi */
526 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
529 /* If this is a module, save the current contiguous memory */
530 #if defined(BKTR_FREEBSD_MODULE)
531 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
532 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
533 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
534 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
535 bktr_store_address(unit, BKTR_MEM_BUF, buf);
540 printf("%s: buffer size %d, addr %p\n",
541 bktr_name(bktr), BROOKTREE_ALLOC,
542 (void *)(uintptr_t)vtophys(buf));
547 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
548 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
550 bktr->alloc_pages = 0;
554 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
555 METEOR_DEV0 | METEOR_RGB16;
556 bktr->dma_prog_loaded = FALSE;
559 bktr->frames = 1; /* one frame */
560 bktr->format = METEOR_GEO_RGB16;
561 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
562 bktr->pixfmt_compat = TRUE;
571 /* using the pci device id and revision id */
572 /* and determine the card type */
573 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
575 switch (PCI_PRODUCT(pci_id)) {
576 case PCI_PRODUCT_BROOKTREE_BT848:
578 bktr->id = BROOKTREE_848A;
580 bktr->id = BROOKTREE_848;
582 case PCI_PRODUCT_BROOKTREE_BT849:
583 bktr->id = BROOKTREE_849A;
585 case PCI_PRODUCT_BROOKTREE_BT878:
586 bktr->id = BROOKTREE_878;
588 case PCI_PRODUCT_BROOKTREE_BT879:
589 bktr->id = BROOKTREE_879;
594 bktr->clr_on_start = FALSE;
596 /* defaults for the tuner section of the card */
597 bktr->tflags = TUNER_INITALIZED;
598 bktr->tuner.frequency = 0;
599 bktr->tuner.channel = 0;
600 bktr->tuner.chnlset = DEFAULT_CHNLSET;
602 bktr->tuner.radio_mode = 0;
603 bktr->audio_mux_select = 0;
604 bktr->audio_mute_state = FALSE;
605 bktr->bt848_card = -1;
606 bktr->bt848_tuner = -1;
607 bktr->reverse_mute = -1;
608 bktr->slow_msp_audio = 0;
609 bktr->msp_use_mono_source = 0;
610 bktr->msp_source_selected = -1;
611 bktr->audio_mux_present = 1;
613 #if defined(__FreeBSD__)
614 #ifdef BKTR_NEW_MSP34XX_DRIVER
615 /* get hint on short programming of the msp34xx, so we know */
616 /* if the decision what thread to start should be overwritten */
617 if ( (err = resource_int_value("bktr", unit, "mspsimple",
618 &(bktr->mspsimple)) ) != 0 )
619 bktr->mspsimple = -1; /* fall back to default */
623 probeCard( bktr, TRUE, unit );
625 /* Initialise any MSP34xx or TDA98xx audio chips */
626 init_audio_devices( bktr );
628 #ifdef BKTR_NEW_MSP34XX_DRIVER
629 /* setup the kenrel thread */
630 err = msp_attach( bktr );
631 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
632 bktr->card.msp3400c = 0;
639 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
640 * The circular buffer holds 'n' fixed size data blocks.
641 * vbisize is the number of bytes in the circular buffer
642 * vbiread is the point we reading data out of the circular buffer
643 * vbiinsert is the point we insert data into the circular buffer
645 static void vbidecode(bktr_ptr_t bktr) {
647 unsigned int *seq_dest;
649 /* Check if there is room in the buffer to insert the data. */
650 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
652 /* Copy the VBI data into the next free slot in the buffer. */
653 /* 'dest' is the point in vbibuffer where we want to insert new data */
654 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
655 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
657 /* Write the VBI sequence number to the end of the vbi data */
658 /* This is used by the AleVT teletext program */
659 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
661 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
662 *seq_dest = bktr->vbi_sequence_number;
664 /* And increase the VBI sequence number */
665 /* This can wrap around */
666 bktr->vbi_sequence_number++;
669 /* Increment the vbiinsert pointer */
670 /* This can wrap around */
671 bktr->vbiinsert += VBI_DATA_SIZE;
672 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
674 /* And increase the amount of vbi data in the buffer */
675 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
681 * the common interrupt handler.
682 * Returns a 0 or 1 depending on whether the interrupt has handled.
683 * In the OS specific section, bktr_intr() is defined which calls this
684 * common interrupt handler.
687 common_bktr_intr( void *arg )
696 bktr = (bktr_ptr_t) arg;
699 * check to see if any interrupts are unmasked on this device. If
700 * none are, then we likely got here by way of being on a PCI shared
701 * interrupt dispatch list.
703 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
704 return 0; /* bail out now, before we do something we
707 if (!(bktr->flags & METEOR_OPEN)) {
708 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
709 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
713 /* record and clear the INTerrupt status bits */
714 bktr_status = INL(bktr, BKTR_INT_STAT);
715 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
717 /* record and clear the device status register */
718 dstatus = INB(bktr, BKTR_DSTATUS);
719 OUTB(bktr, BKTR_DSTATUS, 0x00);
721 #if defined( STATUS_SUM )
722 /* add any new device status or INTerrupt status bits */
723 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
724 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
725 #endif /* STATUS_SUM */
726 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
727 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
731 /* if risc was disabled re-start process again */
732 /* if there was one of the following errors re-start again */
733 if ( !(bktr_status & BT848_INT_RISC_EN) ||
734 ((bktr_status &(/* BT848_INT_FBUS | */
735 /* BT848_INT_FTRGT | */
736 /* BT848_INT_FDSR | */
738 BT848_INT_RIPERR | BT848_INT_PABORT |
739 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
740 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
742 u_short tdec_save = INB(bktr, BKTR_TDEC);
744 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
745 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
747 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
749 /* Reset temporal decimation counter */
750 OUTB(bktr, BKTR_TDEC, 0);
751 OUTB(bktr, BKTR_TDEC, tdec_save);
753 /* Reset to no-fields captured state */
754 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
755 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
756 case METEOR_ONLY_ODD_FIELDS:
757 bktr->flags |= METEOR_WANT_ODD;
759 case METEOR_ONLY_EVEN_FIELDS:
760 bktr->flags |= METEOR_WANT_EVEN;
763 bktr->flags |= METEOR_WANT_MASK;
768 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
769 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
770 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
772 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
777 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
781 /* If this is not a RISC program interrupt, return */
782 if (!(bktr_status & BT848_INT_RISCI))
786 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
787 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
792 * Disable future interrupts if a capture mode is not selected.
793 * This can happen when we are in the process of closing or
794 * changing capture modes, otherwise it shouldn't happen.
796 if (!(bktr->flags & METEOR_CAP_MASK))
797 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
800 /* Determine which field generated this interrupt */
801 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
805 * Process the VBI data if it is being captured. We do this once
806 * both Odd and Even VBI data is captured. Therefore we do this
807 * in the Even field interrupt handler.
810 if ( (bktr->vbiflags & VBI_CAPTURE)
811 &&(bktr->vbiflags & VBI_OPEN)
813 /* Put VBI data into circular buffer */
816 /* If someone is blocked on reading from /dev/vbi, wake them */
817 if (bktr->vbi_read_blocked) {
818 bktr->vbi_read_blocked = FALSE;
822 /* If someone has a select() on /dev/vbi, inform them */
823 if (SEL_WAITING(&bktr->vbi_select)) {
824 selwakeuppri(&bktr->vbi_select, VBIPRI);
832 * Register the completed field
833 * (For dual-field mode, require fields from the same frame)
835 switch ( bktr->flags & METEOR_WANT_MASK ) {
836 case METEOR_WANT_ODD : w_field = ODD_F ; break;
837 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
838 default : w_field = (ODD_F|EVEN_F); break;
840 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
841 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
842 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
843 default : req_field = (ODD_F|EVEN_F);
847 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
848 bktr->flags &= ~METEOR_WANT_EVEN;
849 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
850 ( w_field == ODD_F ))
851 bktr->flags &= ~METEOR_WANT_ODD;
852 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
853 ( w_field == (ODD_F|EVEN_F) ))
854 bktr->flags &= ~METEOR_WANT_ODD;
855 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
856 ( w_field == ODD_F )) {
857 bktr->flags &= ~METEOR_WANT_ODD;
858 bktr->flags |= METEOR_WANT_EVEN;
861 /* We're out of sync. Start over. */
862 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
863 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
864 case METEOR_ONLY_ODD_FIELDS:
865 bktr->flags |= METEOR_WANT_ODD;
867 case METEOR_ONLY_EVEN_FIELDS:
868 bktr->flags |= METEOR_WANT_EVEN;
871 bktr->flags |= METEOR_WANT_MASK;
879 * If we have a complete frame.
881 if (!(bktr->flags & METEOR_WANT_MASK)) {
882 bktr->frames_captured++;
884 * post the completion time.
886 if (bktr->flags & METEOR_WANT_TS) {
889 if ((u_int) bktr->alloc_pages * PAGE_SIZE
890 <= (bktr->frame_size + sizeof(struct timeval))) {
891 ts =(struct timeval *)bktr->bigbuf +
893 /* doesn't work in synch mode except
902 * Wake up the user in single capture mode.
904 if (bktr->flags & METEOR_SINGLE) {
907 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
909 /* disable risc, leave fifo running */
910 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
915 * If the user requested to be notified via signal,
916 * let them know the frame is complete.
919 if (bktr->proc != NULL) {
920 PROC_LOCK(bktr->proc);
921 psignal( bktr->proc, bktr->signal);
922 PROC_UNLOCK(bktr->proc);
926 * Reset the want flags if in continuous or
927 * synchronous capture mode.
931 * currently we only support 3 capture modes: odd only, even only,
932 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
933 * either even OR odd) could provide 60 (50 for PAL) pictures per
934 * second, but it would require this routine to toggle the desired frame
935 * each time, and one more different DMA program for the Bt848.
936 * As a consequence, this fourth mode is currently unsupported.
939 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
940 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
941 case METEOR_ONLY_ODD_FIELDS:
942 bktr->flags |= METEOR_WANT_ODD;
944 case METEOR_ONLY_EVEN_FIELDS:
945 bktr->flags |= METEOR_WANT_EVEN;
948 bktr->flags |= METEOR_WANT_MASK;
963 extern int bt848_format; /* used to set the default format, PAL or NTSC */
965 video_open( bktr_ptr_t bktr )
967 int frame_rate, video_format=0;
969 if (bktr->flags & METEOR_OPEN) /* device is busy */
972 bktr->flags |= METEOR_OPEN;
978 bktr->clr_on_start = FALSE;
980 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
982 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
984 #if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
990 if (bt848_format == 0 )
993 if (bt848_format == 1 )
996 if (video_format == 1 ) {
997 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
998 bktr->format_params = BT848_IFORM_F_NTSCM;
1001 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
1002 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1006 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
1008 /* work around for new Hauppauge 878 cards */
1009 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
1010 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
1011 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
1013 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
1015 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
1016 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
1017 frame_rate = format_params[bktr->format_params].frame_rate;
1019 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
1020 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
1021 OUTB(bktr, BKTR_TGCTRL, 0);
1022 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
1023 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
1024 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
1027 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1029 bktr->max_clip_node = 0;
1031 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
1033 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
1034 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
1036 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
1037 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
1038 OUTB(bktr, BKTR_E_SCLOOP, 0);
1039 OUTB(bktr, BKTR_O_SCLOOP, 0);
1041 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
1042 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
1044 bktr->fifo_errors = 0;
1045 bktr->dma_errors = 0;
1046 bktr->frames_captured = 0;
1047 bktr->even_fields_captured = 0;
1048 bktr->odd_fields_captured = 0;
1050 set_fps(bktr, frame_rate);
1051 bktr->video.addr = 0;
1052 bktr->video.width = 0;
1053 bktr->video.banksize = 0;
1054 bktr->video.ramsize = 0;
1055 bktr->pixfmt_compat = TRUE;
1056 bktr->format = METEOR_GEO_RGB16;
1057 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1059 bktr->capture_area_enabled = FALSE;
1061 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
1062 based motherboards will
1063 operate unreliably */
1068 vbi_open( bktr_ptr_t bktr )
1073 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
1078 bktr->vbiflags |= VBI_OPEN;
1080 /* reset the VBI circular buffer pointers and clear the buffers */
1081 bktr->vbiinsert = 0;
1084 bktr->vbi_sequence_number = 0;
1085 bktr->vbi_read_blocked = FALSE;
1087 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
1088 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
1099 tuner_open( bktr_ptr_t bktr )
1101 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1104 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1107 bktr->tflags |= TUNER_OPEN;
1108 bktr->tuner.frequency = 0;
1109 bktr->tuner.channel = 0;
1110 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1111 bktr->tuner.afc = 0;
1112 bktr->tuner.radio_mode = 0;
1114 /* enable drivers on the GPIO port that control the MUXes */
1115 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1117 /* unmute the audio stream */
1118 set_audio( bktr, AUDIO_UNMUTE );
1120 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1121 init_audio_devices( bktr );
1133 video_close( bktr_ptr_t bktr )
1135 bktr->flags &= ~(METEOR_OPEN |
1140 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1141 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1143 bktr->dma_prog_loaded = FALSE;
1144 OUTB(bktr, BKTR_TDEC, 0);
1145 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1147 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1148 OUTL(bktr, BKTR_SRESET, 0xf);
1149 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1156 * tuner close handle,
1157 * place holder for tuner specific operations on a close.
1160 tuner_close( bktr_ptr_t bktr )
1162 bktr->tflags &= ~TUNER_OPEN;
1164 /* mute the audio by switching the mux */
1165 set_audio( bktr, AUDIO_MUTE );
1167 /* disable drivers on the GPIO port that control the MUXes */
1168 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1174 vbi_close( bktr_ptr_t bktr )
1179 bktr->vbiflags &= ~VBI_OPEN;
1190 video_read(bktr_ptr_t bktr, int unit, struct cdev *dev, struct uio *uio)
1196 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1199 if (bktr->flags & METEOR_CAP_MASK)
1200 return( EIO ); /* already capturing */
1202 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1205 count = bktr->rows * bktr->cols *
1206 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1208 if ((int) uio->uio_iov->iov_len < count)
1211 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1213 /* capture one frame */
1214 start_capture(bktr, METEOR_SINGLE);
1215 /* wait for capture to complete */
1216 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1217 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1218 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1219 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1225 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1226 if (!status) /* successful capture */
1227 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1229 printf ("%s: read: tsleep error %d\n",
1230 bktr_name(bktr), status);
1232 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1238 * Read VBI data from the vbi circular buffer
1239 * The buffer holds vbi data blocks which are the same size
1240 * vbiinsert is the position we will insert the next item into the buffer
1241 * vbistart is the actual position in the buffer we want to read from
1242 * vbisize is the exact number of bytes in the buffer left to read
1245 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1247 int readsize, readsize2, start;
1251 * XXX - vbi_read() should be protected against being re-entered
1252 * while it is unlocked for the uiomove.
1256 while(bktr->vbisize == 0) {
1257 if (ioflag & FNDELAY) {
1258 status = EWOULDBLOCK;
1262 bktr->vbi_read_blocked = TRUE;
1264 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1269 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1275 /* Now we have some data to give to the user */
1277 /* We cannot read more bytes than there are in
1278 * the circular buffer
1280 readsize = (int)uio->uio_iov->iov_len;
1282 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1284 /* Check if we can read this number of bytes without having
1285 * to wrap around the circular buffer */
1286 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1287 /* We need to wrap around */
1289 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1290 start = bktr->vbistart;
1292 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1294 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1297 /* We do not need to wrap around */
1298 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1303 /* Update the number of bytes left to read */
1304 bktr->vbisize -= readsize;
1306 /* Update vbistart */
1307 bktr->vbistart += readsize;
1308 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1323 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1325 volatile u_char c_temp;
1327 unsigned int temp_iform;
1329 struct meteor_geomet *geo;
1330 struct meteor_counts *counts;
1331 struct meteor_video *video;
1332 struct bktr_capture_area *cap_area;
1340 case BT848SCLIP: /* set clip region */
1341 bktr->max_clip_node = 0;
1342 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1344 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1345 if (bktr->clip_list[i].y_min == 0 &&
1346 bktr->clip_list[i].y_max == 0)
1349 bktr->max_clip_node = i;
1351 /* make sure that the list contains a valid clip secquence */
1352 /* the clip rectangles should be sorted by x then by y as the
1353 second order sort key */
1355 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1357 /* to disable clipping set y_min and y_max to 0 in the first
1358 clip rectangle . The first clip rectangle is clip_list[0].
1363 if (bktr->max_clip_node == 0 &&
1364 (bktr->clip_list[0].y_min != 0 &&
1365 bktr->clip_list[0].y_max != 0)) {
1369 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1370 if (bktr->clip_list[i].y_min == 0 &&
1371 bktr->clip_list[i].y_max == 0) {
1374 if ( bktr->clip_list[i+1].y_min != 0 &&
1375 bktr->clip_list[i+1].y_max != 0 &&
1376 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1378 bktr->max_clip_node = 0;
1383 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1384 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1385 bktr->clip_list[i].x_min < 0 ||
1386 bktr->clip_list[i].x_max < 0 ||
1387 bktr->clip_list[i].y_min < 0 ||
1388 bktr->clip_list[i].y_max < 0 ) {
1389 bktr->max_clip_node = 0;
1394 bktr->dma_prog_loaded = FALSE;
1398 case METEORSTATUS: /* get Bt848 status */
1399 c_temp = INB(bktr, BKTR_DSTATUS);
1401 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1402 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1403 *(u_short *)arg = temp;
1406 case BT848SFMT: /* set input format */
1407 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1408 temp_iform = INB(bktr, BKTR_IFORM);
1409 temp_iform &= ~BT848_IFORM_FORMAT;
1410 temp_iform &= ~BT848_IFORM_XTSEL;
1411 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1413 case BT848_IFORM_F_AUTO:
1414 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1418 case BT848_IFORM_F_NTSCM:
1419 case BT848_IFORM_F_NTSCJ:
1420 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1422 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1423 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1424 bktr->format_params = temp;
1427 case BT848_IFORM_F_PALBDGHI:
1428 case BT848_IFORM_F_PALN:
1429 case BT848_IFORM_F_SECAM:
1430 case BT848_IFORM_F_RSVD:
1431 case BT848_IFORM_F_PALM:
1432 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1434 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1435 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1436 bktr->format_params = temp;
1440 bktr->dma_prog_loaded = FALSE;
1443 case METEORSFMT: /* set input format */
1444 temp_iform = INB(bktr, BKTR_IFORM);
1445 temp_iform &= ~BT848_IFORM_FORMAT;
1446 temp_iform &= ~BT848_IFORM_XTSEL;
1447 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1448 case 0: /* default */
1449 case METEOR_FMT_NTSC:
1450 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1452 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1453 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1454 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1455 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1456 bktr->format_params = BT848_IFORM_F_NTSCM;
1459 case METEOR_FMT_PAL:
1460 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1462 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1463 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1464 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1465 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1466 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1469 case METEOR_FMT_AUTOMODE:
1470 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1472 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1473 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1479 bktr->dma_prog_loaded = FALSE;
1482 case METEORGFMT: /* get input format */
1483 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1487 case BT848GFMT: /* get input format */
1488 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1491 case METEORSCOUNT: /* (re)set error counts */
1492 counts = (struct meteor_counts *) arg;
1493 bktr->fifo_errors = counts->fifo_errors;
1494 bktr->dma_errors = counts->dma_errors;
1495 bktr->frames_captured = counts->frames_captured;
1496 bktr->even_fields_captured = counts->even_fields_captured;
1497 bktr->odd_fields_captured = counts->odd_fields_captured;
1500 case METEORGCOUNT: /* get error counts */
1501 counts = (struct meteor_counts *) arg;
1502 counts->fifo_errors = bktr->fifo_errors;
1503 counts->dma_errors = bktr->dma_errors;
1504 counts->frames_captured = bktr->frames_captured;
1505 counts->even_fields_captured = bktr->even_fields_captured;
1506 counts->odd_fields_captured = bktr->odd_fields_captured;
1510 video = (struct meteor_video *)arg;
1511 video->addr = bktr->video.addr;
1512 video->width = bktr->video.width;
1513 video->banksize = bktr->video.banksize;
1514 video->ramsize = bktr->video.ramsize;
1518 video = (struct meteor_video *)arg;
1519 bktr->video.addr = video->addr;
1520 bktr->video.width = video->width;
1521 bktr->video.banksize = video->banksize;
1522 bktr->video.ramsize = video->ramsize;
1526 set_fps(bktr, *(u_short *)arg);
1530 *(u_short *)arg = bktr->fps;
1533 case METEORSHUE: /* set hue */
1534 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1537 case METEORGHUE: /* get hue */
1538 *(u_char *)arg = INB(bktr, BKTR_HUE);
1541 case METEORSBRIG: /* set brightness */
1542 char_temp = ( *(u_char *)arg & 0xff) - 128;
1543 OUTB(bktr, BKTR_BRIGHT, char_temp);
1547 case METEORGBRIG: /* get brightness */
1548 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1551 case METEORSCSAT: /* set chroma saturation */
1552 temp = (int)*(u_char *)arg;
1554 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1555 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1556 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1557 & ~(BT848_E_CONTROL_SAT_U_MSB
1558 | BT848_E_CONTROL_SAT_V_MSB));
1559 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1560 & ~(BT848_O_CONTROL_SAT_U_MSB |
1561 BT848_O_CONTROL_SAT_V_MSB));
1563 if ( temp & BIT_SEVEN_HIGH ) {
1564 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1565 | (BT848_E_CONTROL_SAT_U_MSB
1566 | BT848_E_CONTROL_SAT_V_MSB));
1567 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1568 | (BT848_O_CONTROL_SAT_U_MSB
1569 | BT848_O_CONTROL_SAT_V_MSB));
1573 case METEORGCSAT: /* get chroma saturation */
1574 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1575 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1576 temp |= BIT_SEVEN_HIGH;
1577 *(u_char *)arg = (u_char)temp;
1580 case METEORSCONT: /* set contrast */
1581 temp = (int)*(u_char *)arg & 0xff;
1583 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1584 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1585 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1586 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1587 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1588 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1589 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1592 case METEORGCONT: /* get contrast */
1593 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1594 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1595 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1598 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1599 bktr->clr_on_start = (*(int *)arg != 0);
1602 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1603 *(int *)arg = (int) bktr->clr_on_start;
1608 /* Historically, applications used METEOR_SIG_MODE_MASK
1609 * to reset signal delivery.
1611 if (sig == METEOR_SIG_MODE_MASK)
1613 if (sig < 0 || sig > _SIG_MAXSIG)
1616 bktr->proc = sig ? td->td_proc : NULL;
1620 *(int *)arg = bktr->signal;
1625 switch (*(int *) arg) {
1626 case METEOR_CAP_SINGLE:
1628 if (bktr->bigbuf==0) /* no frame buffer allocated */
1630 /* already capturing */
1631 if (temp & METEOR_CAP_MASK)
1636 start_capture(bktr, METEOR_SINGLE);
1638 /* wait for capture to complete */
1639 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1640 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1641 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1643 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1648 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1649 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1650 if (error && (error != ERESTART)) {
1651 /* Here if we didn't get complete frame */
1653 printf( "%s: ioctl: tsleep error %d %x\n",
1654 bktr_name(bktr), error,
1655 INL(bktr, BKTR_RISC_COUNT));
1659 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1661 /* disable risc, leave fifo running */
1662 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1665 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1666 /* FIXME: should we set bt848->int_stat ??? */
1669 case METEOR_CAP_CONTINOUS:
1670 if (bktr->bigbuf==0) /* no frame buffer allocated */
1672 /* already capturing */
1673 if (temp & METEOR_CAP_MASK)
1677 start_capture(bktr, METEOR_CONTIN);
1679 /* Clear the interrypt status register */
1680 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1682 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1683 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1684 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1686 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1691 dump_bt848( bt848 );
1695 case METEOR_CAP_STOP_CONT:
1696 if (bktr->flags & METEOR_CONTIN) {
1697 /* turn off capture */
1698 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1699 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1700 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1702 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1709 /* can't change parameters while capturing */
1710 if (bktr->flags & METEOR_CAP_MASK)
1714 geo = (struct meteor_geomet *) arg;
1717 /* Either even or odd, if even & odd, then these a zero */
1718 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1719 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1720 printf( "%s: ioctl: Geometry odd or even only.\n",
1725 /* set/clear even/odd flags */
1726 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1727 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1729 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1730 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1731 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1733 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1735 if (geo->columns <= 0) {
1737 "%s: ioctl: %d: columns must be greater than zero.\n",
1738 bktr_name(bktr), geo->columns);
1741 else if ((geo->columns & 0x3fe) != geo->columns) {
1743 "%s: ioctl: %d: columns too large or not even.\n",
1744 bktr_name(bktr), geo->columns);
1748 if (geo->rows <= 0) {
1750 "%s: ioctl: %d: rows must be greater than zero.\n",
1751 bktr_name(bktr), geo->rows);
1754 else if (((geo->rows & 0x7fe) != geo->rows) ||
1755 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1756 ((geo->rows & 0x3fe) != geo->rows)) ) {
1758 "%s: ioctl: %d: rows too large or not even.\n",
1759 bktr_name(bktr), geo->rows);
1763 if (geo->frames > 32) {
1764 printf("%s: ioctl: too many frames.\n",
1773 bktr->dma_prog_loaded = FALSE;
1774 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1776 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1778 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1779 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1781 /* meteor_mem structure for SYNC Capture */
1782 if (geo->frames > 1) temp += PAGE_SIZE;
1785 if ((int) temp > bktr->alloc_pages
1786 && bktr->video.addr == 0) {
1788 /*****************************/
1789 /* *** OS Dependant code *** */
1790 /*****************************/
1791 #if defined(__NetBSD__) || defined(__OpenBSD__)
1792 bus_dmamap_t dmamap;
1794 buf = get_bktr_mem(bktr, &dmamap,
1797 free_bktr_mem(bktr, bktr->dm_mem,
1799 bktr->dm_mem = dmamap;
1802 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1804 kmem_free(kernel_map, bktr->bigbuf,
1805 (bktr->alloc_pages * PAGE_SIZE));
1809 bktr->alloc_pages = temp;
1812 "%s: ioctl: Allocating %d bytes\n",
1813 bktr_name(bktr), temp*PAGE_SIZE);
1823 bktr->rows = geo->rows;
1824 bktr->cols = geo->columns;
1825 bktr->frames = geo->frames;
1827 /* Pixel format (if in meteor pixfmt compatibility mode) */
1828 if ( bktr->pixfmt_compat ) {
1829 bktr->format = METEOR_GEO_YUV_422;
1830 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1831 case 0: /* default */
1832 case METEOR_GEO_RGB16:
1833 bktr->format = METEOR_GEO_RGB16;
1835 case METEOR_GEO_RGB24:
1836 bktr->format = METEOR_GEO_RGB24;
1838 case METEOR_GEO_YUV_422:
1839 bktr->format = METEOR_GEO_YUV_422;
1840 if (geo->oformat & METEOR_GEO_YUV_12)
1841 bktr->format = METEOR_GEO_YUV_12;
1843 case METEOR_GEO_YUV_PACKED:
1844 bktr->format = METEOR_GEO_YUV_PACKED;
1847 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1850 if (bktr->flags & METEOR_CAP_MASK) {
1852 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1853 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1854 case METEOR_ONLY_ODD_FIELDS:
1855 bktr->flags |= METEOR_WANT_ODD;
1857 case METEOR_ONLY_EVEN_FIELDS:
1858 bktr->flags |= METEOR_WANT_EVEN;
1861 bktr->flags |= METEOR_WANT_MASK;
1865 start_capture(bktr, METEOR_CONTIN);
1866 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1867 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1868 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1869 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1875 /* end of METEORSETGEO */
1877 /* FIXME. The Capture Area currently has the following restrictions:
1879 y_offset may need to be even in interlaced modes
1880 RGB24 - Interlaced mode
1881 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1882 y_size must be greater than or equal to METEORSETGEO height (rows)
1883 RGB24 - Even Only (or Odd Only) mode
1884 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1885 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1886 YUV12 - Interlaced mode
1887 x_size must be greater than or equal to METEORSETGEO width (cols)
1888 y_size must be greater than or equal to METEORSETGEO height (rows)
1889 YUV12 - Even Only (or Odd Only) mode
1890 x_size must be greater than or equal to METEORSETGEO width (cols)
1891 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1894 case BT848_SCAPAREA: /* set capture area of each video frame */
1895 /* can't change parameters while capturing */
1896 if (bktr->flags & METEOR_CAP_MASK)
1899 cap_area = (struct bktr_capture_area *) arg;
1900 bktr->capture_area_x_offset = cap_area->x_offset;
1901 bktr->capture_area_y_offset = cap_area->y_offset;
1902 bktr->capture_area_x_size = cap_area->x_size;
1903 bktr->capture_area_y_size = cap_area->y_size;
1904 bktr->capture_area_enabled = TRUE;
1906 bktr->dma_prog_loaded = FALSE;
1909 case BT848_GCAPAREA: /* get capture area of each video frame */
1910 cap_area = (struct bktr_capture_area *) arg;
1911 if (bktr->capture_area_enabled == FALSE) {
1912 cap_area->x_offset = 0;
1913 cap_area->y_offset = 0;
1914 cap_area->x_size = format_params[
1915 bktr->format_params].scaled_hactive;
1916 cap_area->y_size = format_params[
1917 bktr->format_params].vactive;
1919 cap_area->x_offset = bktr->capture_area_x_offset;
1920 cap_area->y_offset = bktr->capture_area_y_offset;
1921 cap_area->x_size = bktr->capture_area_x_size;
1922 cap_area->y_size = bktr->capture_area_y_size;
1927 return common_ioctl( bktr, cmd, arg );
1937 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1940 unsigned int temp, temp1;
1953 /* Read the last key pressed by the Remote Control */
1954 if (bktr->remote_control == 0) return (EINVAL);
1955 remote_read(bktr, (struct bktr_remote *)arg);
1958 #if defined( TUNER_AFC )
1959 case TVTUNER_SETAFC:
1960 bktr->tuner.afc = (*(int *)arg != 0);
1963 case TVTUNER_GETAFC:
1964 *(int *)arg = bktr->tuner.afc;
1965 /* XXX Perhaps use another bit to indicate AFC success? */
1967 #endif /* TUNER_AFC */
1969 case TVTUNER_SETCHNL:
1970 temp_mute( bktr, TRUE );
1971 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1973 temp_mute( bktr, FALSE );
1976 *(unsigned long *)arg = temp;
1978 /* after every channel change, we must restart the MSP34xx */
1979 /* audio chip to reselect NICAM STEREO or MONO audio */
1980 if ( bktr->card.msp3400c )
1981 msp_autodetect( bktr );
1983 /* after every channel change, we must restart the DPL35xx */
1984 if ( bktr->card.dpl3518a )
1985 dpl_autodetect( bktr );
1987 temp_mute( bktr, FALSE );
1990 case TVTUNER_GETCHNL:
1991 *(unsigned long *)arg = bktr->tuner.channel;
1994 case TVTUNER_SETTYPE:
1995 temp = *(unsigned long *)arg;
1996 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1998 bktr->tuner.chnlset = temp;
2001 case TVTUNER_GETTYPE:
2002 *(unsigned long *)arg = bktr->tuner.chnlset;
2005 case TVTUNER_GETSTATUS:
2006 temp = get_tuner_status( bktr );
2007 *(unsigned long *)arg = temp & 0xff;
2010 case TVTUNER_SETFREQ:
2011 temp_mute( bktr, TRUE );
2012 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
2013 temp_mute( bktr, FALSE );
2015 temp_mute( bktr, FALSE );
2018 *(unsigned long *)arg = temp;
2020 /* after every channel change, we must restart the MSP34xx */
2021 /* audio chip to reselect NICAM STEREO or MONO audio */
2022 if ( bktr->card.msp3400c )
2023 msp_autodetect( bktr );
2025 /* after every channel change, we must restart the DPL35xx */
2026 if ( bktr->card.dpl3518a )
2027 dpl_autodetect( bktr );
2029 temp_mute( bktr, FALSE );
2032 case TVTUNER_GETFREQ:
2033 *(unsigned long *)arg = bktr->tuner.frequency;
2036 case TVTUNER_GETCHNLSET:
2037 return tuner_getchnlset((struct bktr_chnlset *)arg);
2039 case BT848_SAUDIO: /* set audio channel */
2040 if ( set_audio( bktr, *(int*)arg ) < 0 )
2044 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
2045 case BT848_SHUE: /* set hue */
2046 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
2049 case BT848_GHUE: /* get hue */
2050 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
2053 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
2054 case BT848_SBRIG: /* set brightness */
2055 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
2058 case BT848_GBRIG: /* get brightness */
2059 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2063 case BT848_SCSAT: /* set chroma saturation */
2064 tmp_int = *(int*)arg;
2066 temp = INB(bktr, BKTR_E_CONTROL);
2067 temp1 = INB(bktr, BKTR_O_CONTROL);
2068 if ( tmp_int & BIT_EIGHT_HIGH ) {
2069 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2070 BT848_E_CONTROL_SAT_V_MSB);
2071 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2072 BT848_O_CONTROL_SAT_V_MSB);
2075 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2076 BT848_E_CONTROL_SAT_V_MSB);
2077 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2078 BT848_O_CONTROL_SAT_V_MSB);
2081 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2082 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2083 OUTB(bktr, BKTR_E_CONTROL, temp);
2084 OUTB(bktr, BKTR_O_CONTROL, temp1);
2087 case BT848_GCSAT: /* get chroma saturation */
2088 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2089 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2090 tmp_int |= BIT_EIGHT_HIGH;
2091 *(int*)arg = tmp_int;
2095 case BT848_SVSAT: /* set chroma V saturation */
2096 tmp_int = *(int*)arg;
2098 temp = INB(bktr, BKTR_E_CONTROL);
2099 temp1 = INB(bktr, BKTR_O_CONTROL);
2100 if ( tmp_int & BIT_EIGHT_HIGH) {
2101 temp |= BT848_E_CONTROL_SAT_V_MSB;
2102 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2105 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2106 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2109 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2110 OUTB(bktr, BKTR_E_CONTROL, temp);
2111 OUTB(bktr, BKTR_O_CONTROL, temp1);
2114 case BT848_GVSAT: /* get chroma V saturation */
2115 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2116 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2117 tmp_int |= BIT_EIGHT_HIGH;
2118 *(int*)arg = tmp_int;
2122 case BT848_SUSAT: /* set chroma U saturation */
2123 tmp_int = *(int*)arg;
2125 temp = INB(bktr, BKTR_E_CONTROL);
2126 temp1 = INB(bktr, BKTR_O_CONTROL);
2127 if ( tmp_int & BIT_EIGHT_HIGH ) {
2128 temp |= BT848_E_CONTROL_SAT_U_MSB;
2129 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2132 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2133 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2136 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2137 OUTB(bktr, BKTR_E_CONTROL, temp);
2138 OUTB(bktr, BKTR_O_CONTROL, temp1);
2141 case BT848_GUSAT: /* get chroma U saturation */
2142 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2143 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2144 tmp_int |= BIT_EIGHT_HIGH;
2145 *(int*)arg = tmp_int;
2148 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2150 case BT848_SLNOTCH: /* set luma notch */
2151 tmp_int = (*(int *)arg & 0x7) << 5 ;
2152 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2153 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2154 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2155 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2158 case BT848_GLNOTCH: /* get luma notch */
2159 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2164 case BT848_SCONT: /* set contrast */
2165 tmp_int = *(int*)arg;
2167 temp = INB(bktr, BKTR_E_CONTROL);
2168 temp1 = INB(bktr, BKTR_O_CONTROL);
2169 if ( tmp_int & BIT_EIGHT_HIGH ) {
2170 temp |= BT848_E_CONTROL_CON_MSB;
2171 temp1 |= BT848_O_CONTROL_CON_MSB;
2174 temp &= ~BT848_E_CONTROL_CON_MSB;
2175 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2178 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2179 OUTB(bktr, BKTR_E_CONTROL, temp);
2180 OUTB(bktr, BKTR_O_CONTROL, temp1);
2183 case BT848_GCONT: /* get contrast */
2184 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2185 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2186 tmp_int |= BIT_EIGHT_HIGH;
2187 *(int*)arg = tmp_int;
2190 /* FIXME: SCBARS and CCBARS require a valid int * */
2191 /* argument to succeed, but its not used; consider */
2192 /* using the arg to store the on/off state so */
2193 /* there's only one ioctl() needed to turn cbars on/off */
2194 case BT848_SCBARS: /* set colorbar output */
2195 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2198 case BT848_CCBARS: /* clear colorbar output */
2199 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2202 case BT848_GAUDIO: /* get audio channel */
2203 temp = bktr->audio_mux_select;
2204 if ( bktr->audio_mute_state == TRUE )
2209 case BT848_SBTSC: /* set audio channel */
2210 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2214 case BT848_WEEPROM: /* write eeprom */
2215 offset = (((struct eeProm *)arg)->offset);
2216 count = (((struct eeProm *)arg)->count);
2217 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2218 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2222 case BT848_REEPROM: /* read eeprom */
2223 offset = (((struct eeProm *)arg)->offset);
2224 count = (((struct eeProm *)arg)->count);
2225 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2226 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2230 case BT848_SIGNATURE:
2231 offset = (((struct eeProm *)arg)->offset);
2232 count = (((struct eeProm *)arg)->count);
2233 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2234 if ( signCard( bktr, offset, count, buf ) < 0 )
2238 /* Ioctl's for direct gpio access */
2239 #ifdef BKTR_GPIO_ACCESS
2240 case BT848_GPIO_GET_EN:
2241 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2244 case BT848_GPIO_SET_EN:
2245 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2248 case BT848_GPIO_GET_DATA:
2249 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2252 case BT848_GPIO_SET_DATA:
2253 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2255 #endif /* BKTR_GPIO_ACCESS */
2257 /* Ioctl's for running the tuner device in radio mode */
2260 *(unsigned char *)arg = bktr->tuner.radio_mode;
2264 bktr->tuner.radio_mode = *(unsigned char *)arg;
2268 *(unsigned long *)arg = bktr->tuner.frequency;
2272 /* The argument to this ioctl is NOT freq*16. It is
2276 temp=(int)*(unsigned long *)arg;
2278 #ifdef BKTR_RADIO_DEBUG
2279 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2280 (int)*(unsigned long *)arg, temp);
2283 #ifndef BKTR_RADIO_NOFREQCHECK
2284 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2286 if(temp<8750 || temp>10800) {
2287 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2291 temp_mute( bktr, TRUE );
2292 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2293 temp_mute( bktr, FALSE );
2294 #ifdef BKTR_RADIO_DEBUG
2296 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2300 *(unsigned long *)arg = temp;
2303 /* Luigi's I2CWR ioctl */
2305 par = *(u_long *)arg;
2306 write = (par >> 24) & 0xff ;
2307 i2c_addr = (par >> 16) & 0xff ;
2308 i2c_port = (par >> 8) & 0xff ;
2309 data = (par) & 0xff ;
2312 i2cWrite( bktr, i2c_addr, i2c_port, data);
2314 data = i2cRead( bktr, i2c_addr);
2316 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2320 #ifdef BT848_MSP_READ
2321 /* I2C ioctls to allow userland access to the MSP chip */
2322 case BT848_MSP_READ:
2324 struct bktr_msp_control *msp;
2325 msp = (struct bktr_msp_control *) arg;
2326 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2327 msp->function, msp->address);
2331 case BT848_MSP_WRITE:
2333 struct bktr_msp_control *msp;
2334 msp = (struct bktr_msp_control *) arg;
2335 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2336 msp->address, msp->data );
2340 case BT848_MSP_RESET:
2341 msp_dpl_reset(bktr, bktr->msp_addr);
2346 return common_ioctl( bktr, cmd, arg );
2357 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2361 struct meteor_pixfmt *pf_pub;
2365 case METEORSINPUT: /* set input device */
2366 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2367 /* On the original bt848 boards, */
2368 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2369 /* On the Hauppauge bt878 boards, */
2370 /* Tuner is MUX0, RCA is MUX3 */
2371 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2372 /* stick with this system in our Meteor Emulation */
2374 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2376 /* this is the RCA video input */
2377 case 0: /* default */
2378 case METEOR_INPUT_DEV0:
2379 /* METEOR_INPUT_DEV_RCA: */
2380 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2382 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2383 & ~BT848_IFORM_MUXSEL);
2385 /* work around for new Hauppauge 878 cards */
2386 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2387 (bktr->id==BROOKTREE_878 ||
2388 bktr->id==BROOKTREE_879) )
2389 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2391 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2393 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2394 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2395 set_audio( bktr, AUDIO_EXTERN );
2398 /* this is the tuner input */
2399 case METEOR_INPUT_DEV1:
2400 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2402 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2403 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2404 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2405 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2406 set_audio( bktr, AUDIO_TUNER );
2409 /* this is the S-VHS input, but with a composite camera */
2410 case METEOR_INPUT_DEV2:
2411 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2413 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2414 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2415 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2416 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2417 set_audio( bktr, AUDIO_EXTERN );
2420 /* this is the S-VHS input */
2421 case METEOR_INPUT_DEV_SVIDEO:
2422 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2423 | METEOR_DEV_SVIDEO;
2424 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2425 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2426 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2427 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2428 set_audio( bktr, AUDIO_EXTERN );
2431 case METEOR_INPUT_DEV3:
2432 if ((bktr->id == BROOKTREE_848A) ||
2433 (bktr->id == BROOKTREE_849A) ||
2434 (bktr->id == BROOKTREE_878) ||
2435 (bktr->id == BROOKTREE_879) ) {
2436 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2438 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2440 /* work around for new Hauppauge 878 cards */
2441 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2442 (bktr->id==BROOKTREE_878 ||
2443 bktr->id==BROOKTREE_879) )
2444 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2446 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2448 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2449 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2450 set_audio( bktr, AUDIO_EXTERN );
2460 case METEORGINPUT: /* get input device */
2461 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2464 case METEORSACTPIXFMT:
2465 if (( *(int *)arg < 0 ) ||
2466 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2469 bktr->pixfmt = *(int *)arg;
2470 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2471 | pixfmt_swap_flags( bktr->pixfmt ));
2472 bktr->pixfmt_compat = FALSE;
2475 case METEORGACTPIXFMT:
2476 *(int *)arg = bktr->pixfmt;
2479 case METEORGSUPPIXFMT :
2480 pf_pub = (struct meteor_pixfmt *)arg;
2481 pixfmt = pf_pub->index;
2483 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2486 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2487 sizeof( *pf_pub ) );
2489 /* Patch in our format index */
2490 pf_pub->index = pixfmt;
2493 #if defined( STATUS_SUM )
2494 case BT848_GSTATUS: /* reap status */
2496 DECLARE_INTR_MASK(s);
2501 *(u_int*)arg = temp;
2504 #endif /* STATUS_SUM */
2516 /******************************************************************************
2517 * bt848 RISC programming routines:
2526 dump_bt848( bktr_ptr_t bktr )
2529 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2530 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2531 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2532 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2533 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2538 for (i = 0; i < 40; i+=4) {
2539 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2541 r[i], INL(bktr, r[i]),
2542 r[i+1], INL(bktr, r[i+1]),
2543 r[i+2], INL(bktr, r[i+2]),
2544 r[i+3], INL(bktr, r[i+3]]));
2547 printf("%s: INT STAT %x \n", bktr_name(bktr),
2548 INL(bktr, BKTR_INT_STAT));
2549 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2550 INL(bktr, BKTR_INT_MASK));
2551 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2552 INW(bktr, BKTR_GPIO_DMA_CTL));
2560 * build write instruction
2562 #define BKTR_FM1 0x6 /* packed data to follow */
2563 #define BKTR_FM3 0xe /* planar data to follow */
2564 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2565 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2566 #define BKTR_PXV 0x0 /* valid word (never used) */
2567 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2568 #define BKTR_SOL 0x2 /* first dword */
2570 #define OP_WRITE (0x1 << 28)
2571 #define OP_SKIP (0x2 << 28)
2572 #define OP_WRITEC (0x5 << 28)
2573 #define OP_JUMP (0x7 << 28)
2574 #define OP_SYNC (0x8 << 28)
2575 #define OP_WRITE123 (0x9 << 28)
2576 #define OP_WRITES123 (0xb << 28)
2577 #define OP_SOL (1 << 27) /* first instr for scanline */
2578 #define OP_EOL (1 << 26)
2580 #define BKTR_RESYNC (1 << 15)
2581 #define BKTR_GEN_IRQ (1 << 24)
2584 * The RISC status bits can be set/cleared in the RISC programs
2585 * and tested in the Interrupt Handler
2587 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2588 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2589 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2590 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2592 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2593 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2594 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2595 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2597 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2598 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2599 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2600 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2602 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2604 bktr_clip_t * clip_node;
2605 bktr->clip_start = -1;
2609 bktr->line_length = width;
2612 bktr->current_col = 0;
2614 if (bktr->max_clip_node == 0 ) return TRUE;
2615 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2618 for (i = 0; i < bktr->max_clip_node; i++ ) {
2619 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2620 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2621 bktr->clip_start = i;
2629 static bool_t getline(bktr_reg_t *bktr, int x ) {
2631 bktr_clip_t * clip_node ;
2633 if (bktr->line_length == 0 ||
2634 bktr->current_col >= bktr->line_length) return FALSE;
2636 bktr->y = min(bktr->last_y, bktr->line_length);
2637 bktr->y2 = bktr->line_length;
2639 bktr->yclip = bktr->yclip2 = -1;
2640 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2641 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2642 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2643 if (bktr->last_y <= clip_node->y_min) {
2644 bktr->y = min(bktr->last_y, bktr->line_length);
2645 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2646 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2647 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2648 bktr->last_y = bktr->yclip2;
2649 bktr->clip_start = i;
2651 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2652 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2653 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2654 if (bktr->last_y >= clip_node->y_min) {
2655 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2656 bktr->last_y = bktr->yclip2;
2657 bktr->clip_start = j;
2666 if (bktr->current_col <= bktr->line_length) {
2667 bktr->current_col = bktr->line_length;
2673 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2674 u_long operation, int pixel_width,
2675 volatile u_char ** target_buffer, int cols ) {
2678 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2679 u_int skip, start_skip;
2681 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2682 /* to the 1st byte in the mem dword containing our start addr. */
2683 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2686 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2687 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2688 case 2 : start_skip = 4 ; break;
2689 case 1 : start_skip = 8 ; break;
2692 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2693 if ( width == cols) {
2694 flag = OP_SOL | OP_EOL;
2695 } else if (bktr->current_col == 0 ) {
2697 } else if (bktr->current_col == cols) {
2702 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2703 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2708 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2709 if (operation != OP_SKIP )
2710 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2712 *target_buffer += width * pixel_width;
2713 bktr->current_col += width;
2717 if (bktr->current_col == 0 && width == cols) {
2720 } else if (bktr->current_col == 0 ) {
2723 } else if (bktr->current_col >= cols) {
2732 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2733 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2738 *(*dma_prog)++ = operation | flag |
2739 (width * pixel_width / 2 - skip);
2740 if (operation != OP_SKIP )
2741 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2742 *target_buffer += (width * pixel_width / 2) ;
2744 if ( operation == OP_WRITE )
2745 operation = OP_WRITEC;
2746 *(*dma_prog)++ = operation | flag2 |
2747 (width * pixel_width / 2);
2748 *target_buffer += (width * pixel_width / 2) ;
2749 bktr->current_col += width;
2757 * Generate the RISC instructions to capture both VBI and video images
2760 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2763 volatile uint32_t target_buffer, buffer, target,width;
2764 volatile uint32_t pitch;
2765 volatile uint32_t *dma_prog; /* DMA prog is an array of
2766 32 bit RISC instructions */
2767 volatile uint32_t *loop_point;
2768 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2769 u_int Bpp = pf_int->public.Bpp;
2770 unsigned int vbisamples; /* VBI samples per line */
2771 unsigned int vbilines; /* VBI lines per field */
2772 unsigned int num_dwords; /* DWORDS per line */
2774 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2775 vbilines = format_params[bktr->format_params].vbi_num_lines;
2776 num_dwords = vbisamples/4;
2778 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2779 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2780 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2781 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2784 OUTB(bktr, BKTR_OFORM, 0x00);
2786 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2787 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2788 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2789 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2791 /* disable gamma correction removal */
2792 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2795 OUTB(bktr, BKTR_E_VTC, 0);
2796 OUTB(bktr, BKTR_O_VTC, 0);
2798 OUTB(bktr, BKTR_E_VTC, 1);
2799 OUTB(bktr, BKTR_O_VTC, 1);
2801 bktr->capcontrol = 3 << 2 | 3;
2803 dma_prog = (uint32_t *) bktr->dma_prog;
2805 /* Construct Write */
2807 if (bktr->video.addr) {
2808 target_buffer = (u_long) bktr->video.addr;
2809 pitch = bktr->video.width;
2812 target_buffer = (u_long) vtophys(bktr->bigbuf);
2816 buffer = target_buffer;
2818 /* Wait for the VRE sync marking the end of the Even and
2819 * the start of the Odd field. Resync here.
2821 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2824 loop_point = dma_prog;
2826 /* store the VBI data */
2827 /* look for sync with packed data */
2828 *dma_prog++ = OP_SYNC | BKTR_FM1;
2830 for(i = 0; i < vbilines; i++) {
2831 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2832 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2833 (i * VBI_LINE_SIZE));
2836 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2837 /* store the Odd field video image */
2838 /* look for sync with packed data */
2839 *dma_prog++ = OP_SYNC | BKTR_FM1;
2840 *dma_prog++ = 0; /* NULL WORD */
2842 for (i = 0; i < (rows/interlace); i++) {
2843 target = target_buffer;
2844 if ( notclipped(bktr, i, width)) {
2845 split(bktr, (volatile uint32_t **) &dma_prog,
2846 bktr->y2 - bktr->y, OP_WRITE,
2847 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2850 while(getline(bktr, i)) {
2851 if (bktr->y != bktr->y2 ) {
2852 split(bktr, (volatile uint32_t **) &dma_prog,
2853 bktr->y2 - bktr->y, OP_WRITE,
2854 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2856 if (bktr->yclip != bktr->yclip2 ) {
2857 split(bktr,(volatile uint32_t **) &dma_prog,
2858 bktr->yclip2 - bktr->yclip,
2860 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2866 target_buffer += interlace * pitch;
2872 /* Grab the Even field */
2873 /* Look for the VRO, end of Odd field, marker */
2874 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2875 *dma_prog++ = 0; /* NULL WORD */
2877 /* store the VBI data */
2878 /* look for sync with packed data */
2879 *dma_prog++ = OP_SYNC | BKTR_FM1;
2881 for(i = 0; i < vbilines; i++) {
2882 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2883 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2884 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2887 /* store the video image */
2888 if (i_flag == 1) /*Even Only*/
2889 target_buffer = buffer;
2890 if (i_flag == 3) /*interlaced*/
2891 target_buffer = buffer+pitch;
2894 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2895 /* look for sync with packed data */
2896 *dma_prog++ = OP_SYNC | BKTR_FM1;
2897 *dma_prog++ = 0; /* NULL WORD */
2899 for (i = 0; i < (rows/interlace); i++) {
2900 target = target_buffer;
2901 if ( notclipped(bktr, i, width)) {
2902 split(bktr, (volatile uint32_t **) &dma_prog,
2903 bktr->y2 - bktr->y, OP_WRITE,
2904 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2906 while(getline(bktr, i)) {
2907 if (bktr->y != bktr->y2 ) {
2908 split(bktr, (volatile uint32_t **) &dma_prog,
2909 bktr->y2 - bktr->y, OP_WRITE,
2910 Bpp, (volatile u_char **)(uintptr_t)&target,
2913 if (bktr->yclip != bktr->yclip2 ) {
2914 split(bktr, (volatile uint32_t **) &dma_prog,
2915 bktr->yclip2 - bktr->yclip, OP_SKIP,
2916 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2923 target_buffer += interlace * pitch;
2928 /* Look for end of 'Even Field' */
2929 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2930 *dma_prog++ = 0; /* NULL WORD */
2932 *dma_prog++ = OP_JUMP ;
2933 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2934 *dma_prog++ = 0; /* NULL WORD */
2942 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2945 volatile uint32_t target_buffer, buffer, target,width;
2946 volatile uint32_t pitch;
2947 volatile uint32_t *dma_prog;
2948 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2949 u_int Bpp = pf_int->public.Bpp;
2951 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2952 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2953 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2954 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2956 OUTB(bktr, BKTR_OFORM, 0x00);
2958 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2959 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2960 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2961 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2963 /* disable gamma correction removal */
2964 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2967 OUTB(bktr, BKTR_E_VTC, 0);
2968 OUTB(bktr, BKTR_O_VTC, 0);
2970 OUTB(bktr, BKTR_E_VTC, 1);
2971 OUTB(bktr, BKTR_O_VTC, 1);
2973 bktr->capcontrol = 3 << 2 | 3;
2975 dma_prog = (uint32_t *) bktr->dma_prog;
2977 /* Construct Write */
2979 if (bktr->video.addr) {
2980 target_buffer = (uint32_t) bktr->video.addr;
2981 pitch = bktr->video.width;
2984 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2988 buffer = target_buffer;
2990 /* contruct sync : for video packet format */
2991 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2993 /* sync, mode indicator packed data */
2994 *dma_prog++ = 0; /* NULL WORD */
2996 for (i = 0; i < (rows/interlace); i++) {
2997 target = target_buffer;
2998 if ( notclipped(bktr, i, width)) {
2999 split(bktr, (volatile uint32_t **) &dma_prog,
3000 bktr->y2 - bktr->y, OP_WRITE,
3001 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3004 while(getline(bktr, i)) {
3005 if (bktr->y != bktr->y2 ) {
3006 split(bktr, (volatile uint32_t **) &dma_prog,
3007 bktr->y2 - bktr->y, OP_WRITE,
3008 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3010 if (bktr->yclip != bktr->yclip2 ) {
3011 split(bktr,(volatile uint32_t **) &dma_prog,
3012 bktr->yclip2 - bktr->yclip,
3014 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3020 target_buffer += interlace * pitch;
3027 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3028 *dma_prog++ = 0; /* NULL WORD */
3030 *dma_prog++ = OP_JUMP;
3031 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
3036 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3037 *dma_prog++ = 0; /* NULL WORD */
3039 *dma_prog++ = OP_JUMP;
3040 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
3045 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3046 *dma_prog++ = 0; /* NULL WORD */
3047 *dma_prog++ = OP_JUMP; ;
3048 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
3052 if (interlace == 2) {
3054 target_buffer = buffer + pitch;
3056 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3058 /* sync vre IRQ bit */
3059 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3060 *dma_prog++ = 0; /* NULL WORD */
3062 for (i = 0; i < (rows/interlace); i++) {
3063 target = target_buffer;
3064 if ( notclipped(bktr, i, width)) {
3065 split(bktr, (volatile uint32_t **) &dma_prog,
3066 bktr->y2 - bktr->y, OP_WRITE,
3067 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3069 while(getline(bktr, i)) {
3070 if (bktr->y != bktr->y2 ) {
3071 split(bktr, (volatile uint32_t **) &dma_prog,
3072 bktr->y2 - bktr->y, OP_WRITE,
3073 Bpp, (volatile u_char **)(uintptr_t)&target,
3076 if (bktr->yclip != bktr->yclip2 ) {
3077 split(bktr, (volatile uint32_t **) &dma_prog,
3078 bktr->yclip2 - bktr->yclip, OP_SKIP,
3079 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3086 target_buffer += interlace * pitch;
3091 /* sync vre IRQ bit */
3092 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3093 *dma_prog++ = 0; /* NULL WORD */
3094 *dma_prog++ = OP_JUMP ;
3095 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
3096 *dma_prog++ = 0; /* NULL WORD */
3104 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3105 int cols, int rows, int interlace )
3108 volatile unsigned int inst;
3109 volatile unsigned int inst3;
3110 volatile uint32_t target_buffer, buffer;
3111 volatile uint32_t *dma_prog;
3112 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3115 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3117 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3118 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3120 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3121 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3123 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3124 bktr->capcontrol = 3 << 2 | 3;
3126 dma_prog = (uint32_t *) bktr->dma_prog;
3128 /* Construct Write */
3130 /* write , sol, eol */
3131 inst = OP_WRITE | OP_SOL | (cols);
3132 /* write , sol, eol */
3133 inst3 = OP_WRITE | OP_EOL | (cols);
3135 if (bktr->video.addr)
3136 target_buffer = (uint32_t) bktr->video.addr;
3138 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3140 buffer = target_buffer;
3142 /* contruct sync : for video packet format */
3143 /* sync, mode indicator packed data */
3144 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3145 *dma_prog++ = 0; /* NULL WORD */
3149 for (i = 0; i < (rows/interlace); i++) {
3151 *dma_prog++ = target_buffer;
3152 *dma_prog++ = inst3;
3153 *dma_prog++ = target_buffer + b;
3154 target_buffer += interlace*(cols * 2);
3160 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3161 *dma_prog++ = 0; /* NULL WORD */
3163 *dma_prog++ = OP_JUMP;
3164 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3169 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3170 *dma_prog++ = 0; /* NULL WORD */
3171 *dma_prog++ = OP_JUMP;
3172 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3177 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3178 *dma_prog++ = 0; /* NULL WORD */
3179 *dma_prog++ = OP_JUMP ;
3180 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3184 if (interlace == 2) {
3186 target_buffer = (uint32_t) buffer + cols*2;
3188 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3191 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3192 *dma_prog++ = 0; /* NULL WORD */
3194 for (i = 0; i < (rows/interlace) ; i++) {
3196 *dma_prog++ = target_buffer;
3197 *dma_prog++ = inst3;
3198 *dma_prog++ = target_buffer + b;
3199 target_buffer += interlace * ( cols*2);
3203 /* sync vro IRQ bit */
3204 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3205 *dma_prog++ = 0; /* NULL WORD */
3206 *dma_prog++ = OP_JUMP ;
3207 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3209 *dma_prog++ = OP_JUMP;
3210 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3211 *dma_prog++ = 0; /* NULL WORD */
3219 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3220 int cols, int rows, int interlace ){
3223 volatile unsigned int inst;
3224 volatile uint32_t target_buffer, t1, buffer;
3225 volatile uint32_t *dma_prog;
3226 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3228 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3230 dma_prog = (uint32_t*) bktr->dma_prog;
3232 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3234 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3235 OUTB(bktr, BKTR_OFORM, 0x00);
3237 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3238 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3240 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3241 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3243 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3244 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3245 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3246 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3248 /* disable gamma correction removal */
3249 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3251 /* Construct Write */
3252 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3253 if (bktr->video.addr)
3254 target_buffer = (uint32_t) bktr->video.addr;
3256 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3258 buffer = target_buffer;
3262 /* contruct sync : for video packet format */
3263 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3264 *dma_prog++ = 0; /* NULL WORD */
3266 for (i = 0; i < (rows/interlace ) ; i++) {
3268 *dma_prog++ = cols/2 | cols/2 << 16;
3269 *dma_prog++ = target_buffer;
3270 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3271 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3272 target_buffer += interlace*cols;
3277 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3278 *dma_prog++ = 0; /* NULL WORD */
3280 *dma_prog++ = OP_JUMP ;
3281 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3285 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3286 *dma_prog++ = 0; /* NULL WORD */
3288 *dma_prog++ = OP_JUMP;
3289 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3293 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3294 *dma_prog++ = 0; /* NULL WORD */
3296 *dma_prog++ = OP_JUMP ;
3297 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3301 if (interlace == 2) {
3303 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3305 target_buffer = (uint32_t) buffer + cols;
3306 t1 = buffer + cols/2;
3307 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3308 *dma_prog++ = 0; /* NULL WORD */
3310 for (i = 0; i < (rows/interlace ) ; i++) {
3312 *dma_prog++ = cols/2 | cols/2 << 16;
3313 *dma_prog++ = target_buffer;
3314 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3315 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3316 target_buffer += interlace*cols;
3320 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3321 *dma_prog++ = 0; /* NULL WORD */
3322 *dma_prog++ = OP_JUMP ;
3323 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3324 *dma_prog++ = 0; /* NULL WORD */
3332 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3333 int cols, int rows, int interlace ){
3336 volatile unsigned int inst;
3337 volatile unsigned int inst1;
3338 volatile uint32_t target_buffer, t1, buffer;
3339 volatile uint32_t *dma_prog;
3340 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3342 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3344 dma_prog = (uint32_t *) bktr->dma_prog;
3346 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3348 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3349 OUTB(bktr, BKTR_OFORM, 0x0);
3351 /* Construct Write */
3352 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3353 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3354 if (bktr->video.addr)
3355 target_buffer = (uint32_t) bktr->video.addr;
3357 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3359 buffer = target_buffer;
3362 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3363 *dma_prog++ = 0; /* NULL WORD */
3365 for (i = 0; i < (rows/interlace )/2 ; i++) {
3367 *dma_prog++ = cols/2 | (cols/2 << 16);
3368 *dma_prog++ = target_buffer;
3369 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3370 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3371 target_buffer += interlace*cols;
3372 *dma_prog++ = inst1;
3373 *dma_prog++ = cols/2 | (cols/2 << 16);
3374 *dma_prog++ = target_buffer;
3375 target_buffer += interlace*cols;
3381 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3382 *dma_prog++ = 0; /* NULL WORD */
3384 *dma_prog++ = OP_JUMP;
3385 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3389 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3390 *dma_prog++ = 0; /* NULL WORD */
3392 *dma_prog++ = OP_JUMP;
3393 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3397 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3398 *dma_prog++ = 0; /* NULL WORD */
3399 *dma_prog++ = OP_JUMP ;
3400 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3404 if (interlace == 2) {
3406 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3408 target_buffer = (uint32_t) buffer + cols;
3409 t1 = buffer + cols/2;
3410 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3411 *dma_prog++ = 0; /* NULL WORD */
3413 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3415 *dma_prog++ = cols/2 | (cols/2 << 16);
3416 *dma_prog++ = target_buffer;
3417 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3418 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3419 target_buffer += interlace*cols;
3420 *dma_prog++ = inst1;
3421 *dma_prog++ = cols/2 | (cols/2 << 16);
3422 *dma_prog++ = target_buffer;
3423 target_buffer += interlace*cols;
3430 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3431 *dma_prog++ = 0; /* NULL WORD */
3432 *dma_prog++ = OP_JUMP;
3433 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3434 *dma_prog++ = 0; /* NULL WORD */
3443 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3445 int rows, cols, interlace;
3448 struct format_params *fp;
3449 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3452 fp = &format_params[bktr->format_params];
3454 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3456 /* disable FIFO & RISC, leave other bits alone */
3457 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3459 /* set video parameters */
3460 if (bktr->capture_area_enabled)
3461 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3462 / fp->scaled_htotal / bktr->cols) - 4096;
3464 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3465 / fp->scaled_htotal / bktr->cols) - 4096;
3467 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3468 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3469 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3470 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3471 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3473 /* horizontal active */
3475 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3476 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3477 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3478 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3479 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3480 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3481 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3483 /* horizontal delay */
3484 if (bktr->capture_area_enabled)
3485 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3486 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3488 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3490 temp = temp & 0x3fe;
3492 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3493 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3494 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3495 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3496 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3497 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3498 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3500 /* vertical scale */
3502 if (bktr->capture_area_enabled) {
3503 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3504 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3506 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3509 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3512 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3513 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3515 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3518 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3523 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3524 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3525 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3526 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3527 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3528 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3529 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3532 /* vertical active */
3533 if (bktr->capture_area_enabled)
3534 temp = bktr->capture_area_y_size;
3537 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3538 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3539 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3540 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3541 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3542 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3543 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3545 /* vertical delay */
3546 if (bktr->capture_area_enabled)
3547 temp = fp->vdelay + (bktr->capture_area_y_offset);
3550 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3551 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3552 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3553 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3554 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3555 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3556 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3558 /* end of video params */
3560 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3561 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3562 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3564 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3567 /* capture control */
3570 bktr->bktr_cap_ctl =
3571 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3572 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3573 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3577 bktr->bktr_cap_ctl =
3578 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3579 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3580 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3584 bktr->bktr_cap_ctl =
3585 (BT848_CAP_CTL_DITH_FRAME |
3586 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3587 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3588 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3593 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3598 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3600 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3601 /* user, then use the rgb_vbi RISC program. */
3602 /* Otherwise, use the normal rgb RISC program */
3603 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3604 if ( (bktr->vbiflags & VBI_OPEN)
3605 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3606 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3608 bktr->bktr_cap_ctl |=
3609 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3610 bktr->vbiflags |= VBI_CAPTURE;
3611 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3614 rgb_prog(bktr, i_flag, cols, rows, interlace);
3619 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3620 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3621 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3622 | pixfmt_swap_flags( bktr->pixfmt ));
3626 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3627 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3628 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3629 | pixfmt_swap_flags( bktr->pixfmt ));
3633 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3634 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3635 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3636 | pixfmt_swap_flags( bktr->pixfmt ));
3643 /******************************************************************************
3644 * video & video capture specific routines:
3652 start_capture( bktr_ptr_t bktr, unsigned type )
3655 struct format_params *fp;
3657 fp = &format_params[bktr->format_params];
3659 /* If requested, clear out capture buf first */
3660 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3661 bzero((caddr_t)bktr->bigbuf,
3662 (size_t)bktr->rows * bktr->cols * bktr->frames *
3663 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3666 OUTB(bktr, BKTR_DSTATUS, 0);
3667 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3669 bktr->flags |= type;
3670 bktr->flags &= ~METEOR_WANT_MASK;
3671 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3672 case METEOR_ONLY_EVEN_FIELDS:
3673 bktr->flags |= METEOR_WANT_EVEN;
3676 case METEOR_ONLY_ODD_FIELDS:
3677 bktr->flags |= METEOR_WANT_ODD;
3681 bktr->flags |= METEOR_WANT_MASK;
3686 /* TDEC is only valid for continuous captures */
3687 if ( type == METEOR_SINGLE ) {
3688 u_short fps_save = bktr->fps;
3690 set_fps(bktr, fp->frame_rate);
3691 bktr->fps = fps_save;
3694 set_fps(bktr, bktr->fps);
3696 if (bktr->dma_prog_loaded == FALSE) {
3697 build_dma_prog(bktr, i_flag);
3698 bktr->dma_prog_loaded = TRUE;
3702 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3711 set_fps( bktr_ptr_t bktr, u_short fps )
3713 struct format_params *fp;
3716 fp = &format_params[bktr->format_params];
3718 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3719 case METEOR_ONLY_EVEN_FIELDS:
3720 bktr->flags |= METEOR_WANT_EVEN;
3723 case METEOR_ONLY_ODD_FIELDS:
3724 bktr->flags |= METEOR_WANT_ODD;
3728 bktr->flags |= METEOR_WANT_MASK;
3733 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3734 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3737 OUTB(bktr, BKTR_TDEC, 0);
3739 if (fps < fp->frame_rate)
3740 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3742 OUTB(bktr, BKTR_TDEC, 0);
3752 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3753 * achieve the specified swapping.
3754 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3755 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3757 * Note also that for 3Bpp, we may additionally need to do some creative
3758 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3759 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3760 * as one would expect.
3763 static u_int pixfmt_swap_flags( int pixfmt )
3765 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3768 switch ( pf->Bpp ) {
3769 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3772 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3775 case 4 : if ( pf->swap_bytes )
3776 swapf = pf->swap_shorts ? 0 : WSWAP;
3778 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3787 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3788 * our pixfmt_table indices.
3791 static int oformat_meteor_to_bt( u_long format )
3794 struct meteor_pixfmt *pf1, *pf2;
3796 /* Find format in compatibility table */
3797 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3798 if ( meteor_pixfmt_table[i].meteor_format == format )
3801 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3803 pf1 = &meteor_pixfmt_table[i].public;
3805 /* Match it with an entry in master pixel format table */
3806 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3807 pf2 = &pixfmt_table[i].public;
3809 if (( pf1->type == pf2->type ) &&
3810 ( pf1->Bpp == pf2->Bpp ) &&
3811 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3812 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3813 ( pf1->swap_shorts == pf2->swap_shorts ))
3816 if ( i >= PIXFMT_TABLE_SIZE )
3822 /******************************************************************************
3827 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3828 #define I2CBITTIME_878 (1 << 7)
3829 #define I2C_READ 0x01
3830 #define I2C_COMMAND (I2CBITTIME | \
3831 BT848_DATA_CTL_I2CSCL | \
3832 BT848_DATA_CTL_I2CSDA)
3834 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3835 BT848_DATA_CTL_I2CSCL | \
3836 BT848_DATA_CTL_I2CSDA)
3838 /* Select between old i2c code and new iicbus / smbus code */
3839 #if defined(BKTR_USE_FREEBSD_SMBUS)
3842 * The hardware interface is actually SMB commands
3845 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3849 if (bktr->id == BROOKTREE_848 ||
3850 bktr->id == BROOKTREE_848A ||
3851 bktr->id == BROOKTREE_849A)
3854 cmd = I2C_COMMAND_878;
3857 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3858 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3861 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3862 (char)(byte1 & 0xff)))
3871 i2cRead( bktr_ptr_t bktr, int addr )
3876 if (bktr->id == BROOKTREE_848 ||
3877 bktr->id == BROOKTREE_848A ||
3878 bktr->id == BROOKTREE_849A)
3881 cmd = I2C_COMMAND_878;
3883 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3886 return ((int)((unsigned char)result));
3889 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3891 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3892 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3893 /* Therefore we need low level control of the i2c bus hardware */
3895 /* Write to the MSP or DPL registers */
3897 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3899 unsigned char addr_l, addr_h, data_h, data_l ;
3901 addr_h = (addr >>8) & 0xff;
3902 addr_l = addr & 0xff;
3903 data_h = (data >>8) & 0xff;
3904 data_l = data & 0xff;
3906 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3908 iicbus_write_byte(IICBUS(bktr), dev, 0);
3909 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3910 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3911 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3912 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3914 iicbus_stop(IICBUS(bktr));
3919 /* Read from the MSP or DPL registers */
3921 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3924 unsigned char addr_l, addr_h, dev_r;
3926 u_char data_read[2];
3928 addr_h = (addr >>8) & 0xff;
3929 addr_l = addr & 0xff;
3932 /* XXX errors ignored */
3933 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3935 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3936 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3937 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3939 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3940 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3941 iicbus_stop(IICBUS(bktr));
3943 data = (data_read[0]<<8) | data_read[1];
3948 /* Reset the MSP or DPL chip */
3949 /* The user can block the reset (which is handy if you initialise the
3950 * MSP and/or DPL audio in another operating system first (eg in Windows)
3953 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3956 #ifndef BKTR_NO_MSP_RESET
3957 /* put into reset mode */
3958 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3959 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3960 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3961 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3962 iicbus_stop(IICBUS(bktr));
3964 /* put back to operational mode */
3965 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3966 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3967 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3968 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3969 iicbus_stop(IICBUS(bktr));
3974 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3977 /* XXX errors ignored */
3978 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3979 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3980 iicbus_stop(IICBUS(bktr));
3985 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3988 * Program the i2c bus directly
3991 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3996 /* clear status bits */
3997 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3999 /* build the command datum */
4000 if (bktr->id == BROOKTREE_848 ||
4001 bktr->id == BROOKTREE_848A ||
4002 bktr->id == BROOKTREE_849A) {
4003 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
4005 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
4007 if ( byte2 != -1 ) {
4008 data |= ((byte2 & 0xff) << 8);
4009 data |= BT848_DATA_CTL_I2CW3B;
4012 /* write the address and data */
4013 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
4015 /* wait for completion */
4016 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4017 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4022 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4034 i2cRead( bktr_ptr_t bktr, int addr )
4038 /* clear status bits */
4039 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4041 /* write the READ address */
4042 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
4044 if (bktr->id == BROOKTREE_848 ||
4045 bktr->id == BROOKTREE_848A ||
4046 bktr->id == BROOKTREE_849A) {
4047 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
4049 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
4052 /* wait for completion */
4053 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4054 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4059 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4063 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4066 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4067 /* bt848 automated i2c bus controller cannot handle */
4068 /* Therefore we need low level control of the i2c bus hardware */
4069 /* Idea for the following functions are from elsewhere in this driver and */
4070 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4073 static void i2c_start( bktr_ptr_t bktr) {
4074 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4075 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4076 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4077 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4080 static void i2c_stop( bktr_ptr_t bktr) {
4081 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4082 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4083 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4086 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4090 /* write out the byte */
4091 for ( x = 7; x >= 0; --x ) {
4092 if ( data & (1<<x) ) {
4093 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4094 DELAY( BITD ); /* assert HI data */
4095 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4096 DELAY( BITD ); /* strobe clock */
4097 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4098 DELAY( BITD ); /* release clock */
4101 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4102 DELAY( BITD ); /* assert LO data */
4103 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4104 DELAY( BITD ); /* strobe clock */
4105 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4106 DELAY( BITD ); /* release clock */
4110 /* look for an ACK */
4111 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4112 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4113 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4114 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4119 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4124 /* read in the byte */
4125 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4126 DELAY( BITD ); /* float data */
4127 for ( x = 7; x >= 0; --x ) {
4128 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4129 DELAY( BITD ); /* strobe clock */
4130 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4131 if ( bit ) byte |= (1<<x);
4132 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4133 DELAY( BITD ); /* release clock */
4135 /* After reading the byte, send an ACK */
4136 /* (unless that was the last byte, for which we send a NAK */
4137 if (last) { /* send NAK - same a writing a 1 */
4138 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4139 DELAY( BITD ); /* set data bit */
4140 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4141 DELAY( BITD ); /* strobe clock */
4142 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4143 DELAY( BITD ); /* release clock */
4144 } else { /* send ACK - same as writing a 0 */
4145 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4146 DELAY( BITD ); /* set data bit */
4147 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4148 DELAY( BITD ); /* strobe clock */
4149 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4150 DELAY( BITD ); /* release clock */
4158 /* Write to the MSP or DPL registers */
4159 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4161 unsigned int msp_w_addr = i2c_addr;
4162 unsigned char addr_l, addr_h, data_h, data_l ;
4163 addr_h = (addr >>8) & 0xff;
4164 addr_l = addr & 0xff;
4165 data_h = (data >>8) & 0xff;
4166 data_l = data & 0xff;
4169 i2c_write_byte(bktr, msp_w_addr);
4170 i2c_write_byte(bktr, dev);
4171 i2c_write_byte(bktr, addr_h);
4172 i2c_write_byte(bktr, addr_l);
4173 i2c_write_byte(bktr, data_h);
4174 i2c_write_byte(bktr, data_l);
4178 /* Read from the MSP or DPL registers */
4179 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4181 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4182 addr_h = (addr >>8) & 0xff;
4183 addr_l = addr & 0xff;
4187 i2c_write_byte(bktr,i2c_addr);
4188 i2c_write_byte(bktr,dev_r);
4189 i2c_write_byte(bktr,addr_h);
4190 i2c_write_byte(bktr,addr_l);
4193 i2c_write_byte(bktr,i2c_addr+1);
4194 i2c_read_byte(bktr,&data_1, 0);
4195 i2c_read_byte(bktr,&data_2, 1);
4197 data = (data_1<<8) | data_2;
4201 /* Reset the MSP or DPL chip */
4202 /* The user can block the reset (which is handy if you initialise the
4203 * MSP audio in another operating system first (eg in Windows)
4205 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4207 #ifndef BKTR_NO_MSP_RESET
4208 /* put into reset mode */
4210 i2c_write_byte(bktr, i2c_addr);
4211 i2c_write_byte(bktr, 0x00);
4212 i2c_write_byte(bktr, 0x80);
4213 i2c_write_byte(bktr, 0x00);
4216 /* put back to operational mode */
4218 i2c_write_byte(bktr, i2c_addr);
4219 i2c_write_byte(bktr, 0x00);
4220 i2c_write_byte(bktr, 0x00);
4221 i2c_write_byte(bktr, 0x00);
4228 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4230 /* XXX errors ignored */
4232 i2c_write_byte(bktr,bktr->remote_control_addr);
4233 i2c_read_byte(bktr,&(remote->data[0]), 0);
4234 i2c_read_byte(bktr,&(remote->data[1]), 0);
4235 i2c_read_byte(bktr,&(remote->data[2]), 0);
4241 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4244 #if defined( I2C_SOFTWARE_PROBE )
4247 * we are keeping this around for any parts that we need to probe
4248 * but that CANNOT be probed via an i2c read.
4249 * this is necessary because the hardware i2c mechanism
4250 * cannot be programmed for 1 byte writes.
4251 * currently there are no known i2c parts that we need to probe
4252 * and that cannot be safely read.
4254 static int i2cProbe( bktr_ptr_t bktr, int addr );
4259 * probe for an I2C device at addr.
4262 i2cProbe( bktr_ptr_t bktr, int addr )
4267 #if defined( EXTRA_START )
4268 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4269 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4270 #endif /* EXTRA_START */
4271 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4272 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4275 for ( x = 7; x >= 0; --x ) {
4276 if ( addr & (1<<x) ) {
4277 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4278 DELAY( BITD ); /* assert HI data */
4279 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4280 DELAY( BITD ); /* strobe clock */
4281 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4282 DELAY( BITD ); /* release clock */
4285 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4286 DELAY( BITD ); /* assert LO data */
4287 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4288 DELAY( BITD ); /* strobe clock */
4289 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4290 DELAY( BITD ); /* release clock */
4294 /* look for an ACK */
4295 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4296 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4297 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4298 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4301 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4302 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4303 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4310 #endif /* I2C_SOFTWARE_PROBE */
4315 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */