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.
64 * $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.140 2005/12/04 10:06:03 ru Exp $
68 * This is part of the Driver for Video Capture Cards (Frame grabbers)
69 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
71 * Copyright Roger Hardiman and Amancio Hasty.
73 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
74 * Handles all the open, close, ioctl and read userland calls.
75 * Sets the Bt848 registers and generates RISC pograms.
76 * Controls the i2c bus and GPIO interface.
77 * Contains the interface to the kernel.
78 * (eg probe/attach and open/close/ioctl)
82 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
83 Jim Lowe's driver for the Matrox Meteor PCI card . The
84 Philips SAA 7116 and SAA 7196 are very different chipsets than
87 The original copyright notice by Mark and Jim is included mostly
88 to honor their fantastic work in the Matrox Meteor driver!
91 #include "opt_bktr.h" /* Include any kernel config options */
93 #include <sys/param.h>
94 #include <sys/systm.h>
95 #include <sys/kernel.h>
98 #include <sys/signalvar.h>
99 #include <sys/vnode.h>
100 #include <sys/bus.h> /* used by smbus and newbus */
102 #include <sys/thread2.h>
105 #include <vm/vm_kern.h>
107 #include <vm/vm_extern.h>
110 #define PROC_UNLOCK(p)
111 #include <bus/pci/pcivar.h>
112 #include <bus/pci/pcidevs.h>
114 #include <dev/video/meteor/ioctl_meteor.h>
115 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
116 #include <dev/video/bktr/bktr_reg.h>
117 #include <dev/video/bktr/bktr_tuner.h>
118 #include <dev/video/bktr/bktr_card.h>
119 #include <dev/video/bktr/bktr_audio.h>
120 #include <dev/video/bktr/bktr_os.h>
121 #include <dev/video/bktr/bktr_core.h>
122 #if defined(BKTR_FREEBSD_MODULE)
123 #include <dev/video/bktr/bktr_mem.h>
126 #if defined(BKTR_USE_FREEBSD_SMBUS)
127 #include <dev/video/bktr/bktr_i2c.h>
128 #include <bus/smbus/smbconf.h>
129 #include <bus/iicbus/iiconf.h>
130 #include "smbus_if.h"
131 #include "iicbus_if.h"
135 bktr_name(bktr_ptr_t bktr)
137 return bktr->bktr_xname;
140 typedef u_char bool_t;
142 #define BKTRPRI PCATCH
143 #define VBIPRI PCATCH
147 * memory allocated for DMA programs
149 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
151 /* When to split a dma transfer , the bt848 has timing as well as
152 dma transfer size limitations so that we have to split dma
153 transfers into two dma requests
155 #define DMA_BT848_SPLIT 319*2
158 * Allocate enough memory for:
159 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
161 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
162 * in your kernel configuration file.
165 #ifndef BROOKTREE_ALLOC_PAGES
166 #define BROOKTREE_ALLOC_PAGES 217*4
168 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
170 /* Definitions for VBI capture.
171 * There are 16 VBI lines in a PAL video field (32 in a frame),
172 * and we take 2044 samples from each line (placed in a 2048 byte buffer
174 * VBI lines are held in a circular buffer before being read by a
175 * user program from /dev/vbi.
178 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
179 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
180 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
181 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
182 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
185 /* Defines for fields */
191 * Parameters describing size of transmitted image.
194 static struct format_params format_params[] = {
195 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
196 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
198 /* # define BT848_IFORM_F_NTSCM (0x1) */
199 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
201 /* # define BT848_IFORM_F_NTSCJ (0x2) */
202 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
204 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
205 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
207 /* # define BT848_IFORM_F_PALM (0x4) */
208 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
210 /* # define BT848_IFORM_F_PALN (0x5) */
211 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
213 /* # define BT848_IFORM_F_SECAM (0x6) */
214 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
216 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
217 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
222 * Table of supported Pixel Formats
225 static struct meteor_pixfmt_internal {
226 struct meteor_pixfmt public;
230 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
231 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
233 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
234 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
236 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
238 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
239 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
240 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
241 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
242 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
243 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
244 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
247 #define PIXFMT_TABLE_SIZE NELEM(pixfmt_table)
250 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
253 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
255 u_long meteor_format;
256 struct meteor_pixfmt public;
257 } meteor_pixfmt_table[] = {
259 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
262 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
263 { METEOR_GEO_YUV_422,
264 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
266 { METEOR_GEO_YUV_PACKED,
267 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
270 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
273 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
277 #define METEOR_PIXFMT_TABLE_SIZE NELEM(meteor_pixfmt_table)
280 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
281 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
285 /* sync detect threshold */
287 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
288 BT848_ADC_CRUSH) /* threshold ~125 mV */
290 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
291 BT848_ADC_SYNC_T) /* threshold ~75 mV */
297 /* debug utility for holding previous INT_STAT contents */
299 static u_long status_sum = 0;
302 * defines to make certain bit-fiddles understandable
304 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
305 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
306 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
307 #define FIFO_RISC_DISABLED 0
309 #define ALL_INTS_DISABLED 0
310 #define ALL_INTS_CLEARED 0xffffffff
311 #define CAPTURE_OFF 0
313 #define BIT_SEVEN_HIGH (1<<7)
314 #define BIT_EIGHT_HIGH (1<<8)
316 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
317 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
321 static int oformat_meteor_to_bt( u_long format );
323 static u_int pixfmt_swap_flags( int pixfmt );
326 * bt848 RISC programming routines.
329 static int dump_bt848( bktr_ptr_t bktr );
332 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
333 int rows, int interlace );
334 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
335 int rows, int interlace );
336 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
337 int rows, int interlace );
338 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
339 int rows, int interlace );
340 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
341 int rows, int interlace );
342 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
344 static bool_t getline(bktr_reg_t *, int);
345 static bool_t notclipped(bktr_reg_t * , int , int);
346 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
347 volatile u_char ** , int );
349 static void start_capture( bktr_ptr_t bktr, unsigned type );
350 static void set_fps( bktr_ptr_t bktr, u_short fps );
355 * Remote Control Functions
357 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
361 * ioctls common to both video & tuner.
363 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
366 #if !defined(BKTR_USE_FREEBSD_SMBUS)
368 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
370 static void i2c_start( bktr_ptr_t bktr);
371 static void i2c_stop( bktr_ptr_t bktr);
372 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
373 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
379 * the common attach code, used by all OS versions.
382 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
385 int need_to_allocate_memory = 1;
386 #ifdef BKTR_NEW_MSP34XX_DRIVER
390 /* If this is a module, check if there is any currently saved contiguous memory */
391 #if defined(BKTR_FREEBSD_MODULE)
392 if (bktr_has_stored_addresses(unit) == 1) {
393 /* recover the addresses */
394 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
395 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
396 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
397 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
398 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
399 need_to_allocate_memory = 0;
403 if (need_to_allocate_memory == 1) {
404 /* allocate space for dma program */
405 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
406 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
408 /* allocte space for the VBI buffer */
409 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
410 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
412 /* allocate space for pixel buffer */
413 if ( BROOKTREE_ALLOC )
414 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
420 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
423 /* If this is a module, save the current contiguous memory */
424 #if defined(BKTR_FREEBSD_MODULE)
425 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
426 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
427 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
428 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
429 bktr_store_address(unit, BKTR_MEM_BUF, buf);
434 kprintf("%s: buffer size %d, addr %p\n",
435 bktr_name(bktr), BROOKTREE_ALLOC,
436 (void *)(uintptr_t)vtophys(buf));
441 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
442 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
444 bktr->alloc_pages = 0;
448 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
449 METEOR_DEV0 | METEOR_RGB16;
450 bktr->dma_prog_loaded = FALSE;
453 bktr->frames = 1; /* one frame */
454 bktr->format = METEOR_GEO_RGB16;
455 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
456 bktr->pixfmt_compat = TRUE;
465 /* using the pci device id and revision id */
466 /* and determine the card type */
467 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
469 switch (PCI_PRODUCT(pci_id)) {
470 case PCI_PRODUCT_BROOKTREE_BT848:
472 bktr->id = BROOKTREE_848A;
474 bktr->id = BROOKTREE_848;
476 case PCI_PRODUCT_BROOKTREE_BT849:
477 bktr->id = BROOKTREE_849A;
479 case PCI_PRODUCT_BROOKTREE_BT878:
480 bktr->id = BROOKTREE_878;
482 case PCI_PRODUCT_BROOKTREE_BT879:
483 bktr->id = BROOKTREE_879;
488 bktr->clr_on_start = FALSE;
490 /* defaults for the tuner section of the card */
491 bktr->tflags = TUNER_INITALIZED;
492 bktr->tuner.frequency = 0;
493 bktr->tuner.channel = 0;
494 bktr->tuner.chnlset = DEFAULT_CHNLSET;
496 bktr->tuner.radio_mode = 0;
497 bktr->audio_mux_select = 0;
498 bktr->audio_mute_state = FALSE;
499 bktr->bt848_card = -1;
500 bktr->bt848_tuner = -1;
501 bktr->reverse_mute = -1;
502 bktr->slow_msp_audio = 0;
503 bktr->msp_use_mono_source = 0;
504 bktr->msp_source_selected = -1;
505 bktr->audio_mux_present = 1;
507 #ifdef BKTR_NEW_MSP34XX_DRIVER
508 /* get hint on short programming of the msp34xx, so we know */
509 /* if the decision what thread to start should be overwritten */
510 if ( (err = resource_int_value("bktr", unit, "mspsimple",
511 &(bktr->mspsimple)) ) != 0 )
512 bktr->mspsimple = -1; /* fall back to default */
515 probeCard( bktr, TRUE, unit );
517 /* Initialise any MSP34xx or TDA98xx audio chips */
518 init_audio_devices( bktr );
520 #ifdef BKTR_NEW_MSP34XX_DRIVER
521 /* setup the kenrel thread */
522 err = msp_attach( bktr );
523 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
524 bktr->card.msp3400c = 0;
531 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
532 * The circular buffer holds 'n' fixed size data blocks.
533 * vbisize is the number of bytes in the circular buffer
534 * vbiread is the point we reading data out of the circular buffer
535 * vbiinsert is the point we insert data into the circular buffer
537 static void vbidecode(bktr_ptr_t bktr) {
539 unsigned int *seq_dest;
541 /* Check if there is room in the buffer to insert the data. */
542 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
544 /* Copy the VBI data into the next free slot in the buffer. */
545 /* 'dest' is the point in vbibuffer where we want to insert new data */
546 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
547 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
549 /* Write the VBI sequence number to the end of the vbi data */
550 /* This is used by the AleVT teletext program */
551 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
553 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
554 *seq_dest = bktr->vbi_sequence_number;
556 /* And increase the VBI sequence number */
557 /* This can wrap around */
558 bktr->vbi_sequence_number++;
561 /* Increment the vbiinsert pointer */
562 /* This can wrap around */
563 bktr->vbiinsert += VBI_DATA_SIZE;
564 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
566 /* And increase the amount of vbi data in the buffer */
567 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
573 * the common interrupt handler.
574 * Returns a 0 or 1 depending on whether the interrupt has handled.
575 * In the OS specific section, bktr_intr() is defined which calls this
576 * common interrupt handler.
579 common_bktr_intr( void *arg )
588 bktr = (bktr_ptr_t) arg;
591 * check to see if any interrupts are unmasked on this device. If
592 * none are, then we likely got here by way of being on a PCI shared
593 * interrupt dispatch list.
595 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
596 return 0; /* bail out now, before we do something we
599 if (!(bktr->flags & METEOR_OPEN)) {
600 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
601 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
605 /* record and clear the INTerrupt status bits */
606 bktr_status = INL(bktr, BKTR_INT_STAT);
607 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
609 /* record and clear the device status register */
610 dstatus = INB(bktr, BKTR_DSTATUS);
611 OUTB(bktr, BKTR_DSTATUS, 0x00);
613 #if defined( STATUS_SUM )
614 /* add any new device status or INTerrupt status bits */
615 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
616 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
617 #endif /* STATUS_SUM */
618 /* kprintf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
619 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
623 /* if risc was disabled re-start process again */
624 /* if there was one of the following errors re-start again */
625 if ( !(bktr_status & BT848_INT_RISC_EN) ||
626 ((bktr_status &(/* BT848_INT_FBUS | */
627 /* BT848_INT_FTRGT | */
628 /* BT848_INT_FDSR | */
630 BT848_INT_RIPERR | BT848_INT_PABORT |
631 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
632 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
634 u_short tdec_save = INB(bktr, BKTR_TDEC);
636 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
637 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
639 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
641 /* Reset temporal decimation counter */
642 OUTB(bktr, BKTR_TDEC, 0);
643 OUTB(bktr, BKTR_TDEC, tdec_save);
645 /* Reset to no-fields captured state */
646 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
647 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
648 case METEOR_ONLY_ODD_FIELDS:
649 bktr->flags |= METEOR_WANT_ODD;
651 case METEOR_ONLY_EVEN_FIELDS:
652 bktr->flags |= METEOR_WANT_EVEN;
655 bktr->flags |= METEOR_WANT_MASK;
660 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
661 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
662 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
664 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
669 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
673 /* If this is not a RISC program interrupt, return */
674 if (!(bktr_status & BT848_INT_RISCI))
678 kprintf( "%s: intr status %x %x %x\n", bktr_name(bktr),
679 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
684 * Disable future interrupts if a capture mode is not selected.
685 * This can happen when we are in the process of closing or
686 * changing capture modes, otherwise it shouldn't happen.
688 if (!(bktr->flags & METEOR_CAP_MASK))
689 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
692 /* Determine which field generated this interrupt */
693 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
697 * Process the VBI data if it is being captured. We do this once
698 * both Odd and Even VBI data is captured. Therefore we do this
699 * in the Even field interrupt handler.
702 if ( (bktr->vbiflags & VBI_CAPTURE)
703 &&(bktr->vbiflags & VBI_OPEN)
705 /* Put VBI data into circular buffer */
708 /* If someone is blocked on reading from /dev/vbi, wake them */
709 if (bktr->vbi_read_blocked) {
710 bktr->vbi_read_blocked = FALSE;
714 /* Inform anyone who is polling */
715 KNOTE(&bktr->vbi_kq.ki_note, 0);
721 * Register the completed field
722 * (For dual-field mode, require fields from the same frame)
724 switch ( bktr->flags & METEOR_WANT_MASK ) {
725 case METEOR_WANT_ODD : w_field = ODD_F ; break;
726 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
727 default : w_field = (ODD_F|EVEN_F); break;
729 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
730 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
731 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
732 default : req_field = (ODD_F|EVEN_F);
736 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
737 bktr->flags &= ~METEOR_WANT_EVEN;
738 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
739 ( w_field == ODD_F ))
740 bktr->flags &= ~METEOR_WANT_ODD;
741 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
742 ( w_field == (ODD_F|EVEN_F) ))
743 bktr->flags &= ~METEOR_WANT_ODD;
744 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
745 ( w_field == ODD_F )) {
746 bktr->flags &= ~METEOR_WANT_ODD;
747 bktr->flags |= METEOR_WANT_EVEN;
750 /* We're out of sync. Start over. */
751 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
752 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
753 case METEOR_ONLY_ODD_FIELDS:
754 bktr->flags |= METEOR_WANT_ODD;
756 case METEOR_ONLY_EVEN_FIELDS:
757 bktr->flags |= METEOR_WANT_EVEN;
760 bktr->flags |= METEOR_WANT_MASK;
768 * If we have a complete frame.
770 if (!(bktr->flags & METEOR_WANT_MASK)) {
771 bktr->frames_captured++;
773 * post the completion time.
775 if (bktr->flags & METEOR_WANT_TS) {
778 if ((u_int) bktr->alloc_pages * PAGE_SIZE
779 <= (bktr->frame_size + sizeof(struct timeval))) {
780 ts =(struct timeval *)bktr->bigbuf +
782 /* doesn't work in synch mode except
791 * Wake up the user in single capture mode.
793 if (bktr->flags & METEOR_SINGLE) {
796 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
798 /* disable risc, leave fifo running */
799 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
804 * If the user requested to be notified via signal,
805 * let them know the frame is complete.
808 if (bktr->proc != NULL) {
809 PROC_LOCK(bktr->proc);
810 ksignal( bktr->proc, bktr->signal);
811 PROC_UNLOCK(bktr->proc);
815 * Reset the want flags if in continuous or
816 * synchronous capture mode.
820 * currently we only support 3 capture modes: odd only, even only,
821 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
822 * either even OR odd) could provide 60 (50 for PAL) pictures per
823 * second, but it would require this routine to toggle the desired frame
824 * each time, and one more different DMA program for the Bt848.
825 * As a consequence, this fourth mode is currently unsupported.
828 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
829 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
830 case METEOR_ONLY_ODD_FIELDS:
831 bktr->flags |= METEOR_WANT_ODD;
833 case METEOR_ONLY_EVEN_FIELDS:
834 bktr->flags |= METEOR_WANT_EVEN;
837 bktr->flags |= METEOR_WANT_MASK;
852 extern int bt848_format; /* used to set the default format, PAL or NTSC */
854 video_open( bktr_ptr_t bktr )
856 int frame_rate, video_format=0;
858 if (bktr->flags & METEOR_OPEN) /* device is busy */
861 bktr->flags |= METEOR_OPEN;
867 bktr->clr_on_start = FALSE;
869 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
871 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
873 #if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
879 if (bt848_format == 0 )
882 if (bt848_format == 1 )
885 if (video_format == 1 ) {
886 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
887 bktr->format_params = BT848_IFORM_F_NTSCM;
890 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
891 bktr->format_params = BT848_IFORM_F_PALBDGHI;
895 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
897 /* work around for new Hauppauge 878 cards */
898 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
899 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
900 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
902 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
904 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
905 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
906 frame_rate = format_params[bktr->format_params].frame_rate;
908 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
909 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
910 OUTB(bktr, BKTR_TGCTRL, 0);
911 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
912 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
913 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
916 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
918 bktr->max_clip_node = 0;
920 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
922 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
923 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
925 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
926 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
927 OUTB(bktr, BKTR_E_SCLOOP, 0);
928 OUTB(bktr, BKTR_O_SCLOOP, 0);
930 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
931 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
933 bktr->fifo_errors = 0;
934 bktr->dma_errors = 0;
935 bktr->frames_captured = 0;
936 bktr->even_fields_captured = 0;
937 bktr->odd_fields_captured = 0;
939 set_fps(bktr, frame_rate);
940 bktr->video.addr = 0;
941 bktr->video.width = 0;
942 bktr->video.banksize = 0;
943 bktr->video.ramsize = 0;
944 bktr->pixfmt_compat = TRUE;
945 bktr->format = METEOR_GEO_RGB16;
946 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
948 bktr->capture_area_enabled = FALSE;
950 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
951 based motherboards will
952 operate unreliably */
957 vbi_open( bktr_ptr_t bktr )
962 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
967 bktr->vbiflags |= VBI_OPEN;
969 /* reset the VBI circular buffer pointers and clear the buffers */
973 bktr->vbi_sequence_number = 0;
974 bktr->vbi_read_blocked = FALSE;
976 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
977 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
988 tuner_open( bktr_ptr_t bktr )
990 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
993 if ( bktr->tflags & TUNER_OPEN ) /* already open */
996 bktr->tflags |= TUNER_OPEN;
997 bktr->tuner.frequency = 0;
998 bktr->tuner.channel = 0;
999 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1000 bktr->tuner.afc = 0;
1001 bktr->tuner.radio_mode = 0;
1003 /* enable drivers on the GPIO port that control the MUXes */
1004 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1006 /* unmute the audio stream */
1007 set_audio( bktr, AUDIO_UNMUTE );
1009 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1010 init_audio_devices( bktr );
1022 video_close( bktr_ptr_t bktr )
1024 bktr->flags &= ~(METEOR_OPEN |
1029 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1030 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1032 bktr->dma_prog_loaded = FALSE;
1033 OUTB(bktr, BKTR_TDEC, 0);
1034 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1036 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1037 OUTL(bktr, BKTR_SRESET, 0xf);
1038 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1045 * tuner close handle,
1046 * place holder for tuner specific operations on a close.
1049 tuner_close( bktr_ptr_t bktr )
1051 bktr->tflags &= ~TUNER_OPEN;
1053 /* mute the audio by switching the mux */
1054 set_audio( bktr, AUDIO_MUTE );
1056 /* disable drivers on the GPIO port that control the MUXes */
1057 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1063 vbi_close( bktr_ptr_t bktr )
1068 bktr->vbiflags &= ~VBI_OPEN;
1079 video_read(bktr_ptr_t bktr, int unit, cdev_t dev, struct uio *uio)
1085 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1088 if (bktr->flags & METEOR_CAP_MASK)
1089 return( EIO ); /* already capturing */
1091 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1094 count = bktr->rows * bktr->cols *
1095 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1097 if ((int) uio->uio_iov->iov_len < count)
1100 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1102 /* capture one frame */
1103 start_capture(bktr, METEOR_SINGLE);
1104 /* wait for capture to complete */
1105 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1106 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1107 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1108 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1114 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1115 if (!status) /* successful capture */
1116 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1118 kprintf ("%s: read: tsleep error %d\n",
1119 bktr_name(bktr), status);
1121 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1127 * Read VBI data from the vbi circular buffer
1128 * The buffer holds vbi data blocks which are the same size
1129 * vbiinsert is the position we will insert the next item into the buffer
1130 * vbistart is the actual position in the buffer we want to read from
1131 * vbisize is the exact number of bytes in the buffer left to read
1134 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1136 int readsize, readsize2, start;
1140 * XXX - vbi_read() should be protected against being re-entered
1141 * while it is unlocked for the uiomove.
1145 while(bktr->vbisize == 0) {
1146 if (ioflag & IO_NDELAY) {
1147 status = EWOULDBLOCK;
1151 bktr->vbi_read_blocked = TRUE;
1153 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1158 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1164 /* Now we have some data to give to the user */
1166 /* We cannot read more bytes than there are in
1167 * the circular buffer
1169 readsize = (int)uio->uio_iov->iov_len;
1171 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1173 /* Check if we can read this number of bytes without having
1174 * to wrap around the circular buffer */
1175 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1176 /* We need to wrap around */
1178 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1179 start = bktr->vbistart;
1181 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1183 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1186 /* We do not need to wrap around */
1187 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1192 /* Update the number of bytes left to read */
1193 bktr->vbisize -= readsize;
1195 /* Update vbistart */
1196 bktr->vbistart += readsize;
1197 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1212 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1214 volatile u_char c_temp;
1216 unsigned int temp_iform;
1218 struct meteor_geomet *geo;
1219 struct meteor_counts *counts;
1220 struct meteor_video *video;
1221 struct bktr_capture_area *cap_area;
1229 case BT848SCLIP: /* set clip region */
1230 bktr->max_clip_node = 0;
1231 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1233 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1234 if (bktr->clip_list[i].y_min == 0 &&
1235 bktr->clip_list[i].y_max == 0)
1238 bktr->max_clip_node = i;
1240 /* make sure that the list contains a valid clip secquence */
1241 /* the clip rectangles should be sorted by x then by y as the
1242 second order sort key */
1244 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1246 /* to disable clipping set y_min and y_max to 0 in the first
1247 clip rectangle . The first clip rectangle is clip_list[0].
1252 if (bktr->max_clip_node == 0 &&
1253 (bktr->clip_list[0].y_min != 0 &&
1254 bktr->clip_list[0].y_max != 0)) {
1258 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1259 if (bktr->clip_list[i].y_min == 0 &&
1260 bktr->clip_list[i].y_max == 0) {
1263 if ( bktr->clip_list[i+1].y_min != 0 &&
1264 bktr->clip_list[i+1].y_max != 0 &&
1265 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1267 bktr->max_clip_node = 0;
1272 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1273 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1274 bktr->clip_list[i].x_min < 0 ||
1275 bktr->clip_list[i].x_max < 0 ||
1276 bktr->clip_list[i].y_min < 0 ||
1277 bktr->clip_list[i].y_max < 0 ) {
1278 bktr->max_clip_node = 0;
1283 bktr->dma_prog_loaded = FALSE;
1287 case METEORSTATUS: /* get Bt848 status */
1288 c_temp = INB(bktr, BKTR_DSTATUS);
1290 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1291 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1292 *(u_short *)arg = temp;
1295 case BT848SFMT: /* set input format */
1296 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1297 temp_iform = INB(bktr, BKTR_IFORM);
1298 temp_iform &= ~BT848_IFORM_FORMAT;
1299 temp_iform &= ~BT848_IFORM_XTSEL;
1300 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1302 case BT848_IFORM_F_AUTO:
1303 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1307 case BT848_IFORM_F_NTSCM:
1308 case BT848_IFORM_F_NTSCJ:
1309 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1311 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1312 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1313 bktr->format_params = temp;
1316 case BT848_IFORM_F_PALBDGHI:
1317 case BT848_IFORM_F_PALN:
1318 case BT848_IFORM_F_SECAM:
1319 case BT848_IFORM_F_RSVD:
1320 case BT848_IFORM_F_PALM:
1321 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1323 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1324 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1325 bktr->format_params = temp;
1329 bktr->dma_prog_loaded = FALSE;
1332 case METEORSFMT: /* set input format */
1333 temp_iform = INB(bktr, BKTR_IFORM);
1334 temp_iform &= ~BT848_IFORM_FORMAT;
1335 temp_iform &= ~BT848_IFORM_XTSEL;
1336 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1337 case 0: /* default */
1338 case METEOR_FMT_NTSC:
1339 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1341 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1342 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1343 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1344 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1345 bktr->format_params = BT848_IFORM_F_NTSCM;
1348 case METEOR_FMT_PAL:
1349 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1351 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1352 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1353 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1354 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1355 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1358 case METEOR_FMT_AUTOMODE:
1359 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1361 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1362 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1368 bktr->dma_prog_loaded = FALSE;
1371 case METEORGFMT: /* get input format */
1372 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1376 case BT848GFMT: /* get input format */
1377 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1380 case METEORSCOUNT: /* (re)set error counts */
1381 counts = (struct meteor_counts *) arg;
1382 bktr->fifo_errors = counts->fifo_errors;
1383 bktr->dma_errors = counts->dma_errors;
1384 bktr->frames_captured = counts->frames_captured;
1385 bktr->even_fields_captured = counts->even_fields_captured;
1386 bktr->odd_fields_captured = counts->odd_fields_captured;
1389 case METEORGCOUNT: /* get error counts */
1390 counts = (struct meteor_counts *) arg;
1391 counts->fifo_errors = bktr->fifo_errors;
1392 counts->dma_errors = bktr->dma_errors;
1393 counts->frames_captured = bktr->frames_captured;
1394 counts->even_fields_captured = bktr->even_fields_captured;
1395 counts->odd_fields_captured = bktr->odd_fields_captured;
1399 video = (struct meteor_video *)arg;
1400 video->addr = bktr->video.addr;
1401 video->width = bktr->video.width;
1402 video->banksize = bktr->video.banksize;
1403 video->ramsize = bktr->video.ramsize;
1407 video = (struct meteor_video *)arg;
1408 bktr->video.addr = video->addr;
1409 bktr->video.width = video->width;
1410 bktr->video.banksize = video->banksize;
1411 bktr->video.ramsize = video->ramsize;
1415 set_fps(bktr, *(u_short *)arg);
1419 *(u_short *)arg = bktr->fps;
1422 case METEORSHUE: /* set hue */
1423 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1426 case METEORGHUE: /* get hue */
1427 *(u_char *)arg = INB(bktr, BKTR_HUE);
1430 case METEORSBRIG: /* set brightness */
1431 char_temp = ( *(u_char *)arg & 0xff) - 128;
1432 OUTB(bktr, BKTR_BRIGHT, char_temp);
1436 case METEORGBRIG: /* get brightness */
1437 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1440 case METEORSCSAT: /* set chroma saturation */
1441 temp = (int)*(u_char *)arg;
1443 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1444 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1445 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1446 & ~(BT848_E_CONTROL_SAT_U_MSB
1447 | BT848_E_CONTROL_SAT_V_MSB));
1448 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1449 & ~(BT848_O_CONTROL_SAT_U_MSB |
1450 BT848_O_CONTROL_SAT_V_MSB));
1452 if ( temp & BIT_SEVEN_HIGH ) {
1453 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1454 | (BT848_E_CONTROL_SAT_U_MSB
1455 | BT848_E_CONTROL_SAT_V_MSB));
1456 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1457 | (BT848_O_CONTROL_SAT_U_MSB
1458 | BT848_O_CONTROL_SAT_V_MSB));
1462 case METEORGCSAT: /* get chroma saturation */
1463 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1464 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1465 temp |= BIT_SEVEN_HIGH;
1466 *(u_char *)arg = (u_char)temp;
1469 case METEORSCONT: /* set contrast */
1470 temp = (int)*(u_char *)arg & 0xff;
1472 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1473 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1474 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1475 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1476 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1477 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1478 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1481 case METEORGCONT: /* get contrast */
1482 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1483 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1484 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1487 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1488 bktr->clr_on_start = (*(int *)arg != 0);
1491 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1492 *(int *)arg = (int) bktr->clr_on_start;
1497 /* Historically, applications used METEOR_SIG_MODE_MASK
1498 * to reset signal delivery.
1500 if (sig == METEOR_SIG_MODE_MASK)
1502 if (sig < 0 || sig > _SIG_MAXSIG)
1505 bktr->proc = sig ? td->td_proc : NULL;
1509 *(int *)arg = bktr->signal;
1514 switch (*(int *) arg) {
1515 case METEOR_CAP_SINGLE:
1517 if (bktr->bigbuf==0) /* no frame buffer allocated */
1519 /* already capturing */
1520 if (temp & METEOR_CAP_MASK)
1525 start_capture(bktr, METEOR_SINGLE);
1527 /* wait for capture to complete */
1528 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1529 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1530 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1532 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1537 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1538 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1539 if (error && (error != ERESTART)) {
1540 /* Here if we didn't get complete frame */
1542 kprintf( "%s: ioctl: tsleep error %d %x\n",
1543 bktr_name(bktr), error,
1544 INL(bktr, BKTR_RISC_COUNT));
1548 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1550 /* disable risc, leave fifo running */
1551 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1554 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1555 /* FIXME: should we set bt848->int_stat ??? */
1558 case METEOR_CAP_CONTINOUS:
1559 if (bktr->bigbuf==0) /* no frame buffer allocated */
1561 /* already capturing */
1562 if (temp & METEOR_CAP_MASK)
1566 start_capture(bktr, METEOR_CONTIN);
1568 /* Clear the interrypt status register */
1569 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1571 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1572 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1573 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1575 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1584 case METEOR_CAP_STOP_CONT:
1585 if (bktr->flags & METEOR_CONTIN) {
1586 /* turn off capture */
1587 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1588 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1589 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1591 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1598 /* can't change parameters while capturing */
1599 if (bktr->flags & METEOR_CAP_MASK)
1603 geo = (struct meteor_geomet *) arg;
1606 /* Either even or odd, if even & odd, then these a zero */
1607 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1608 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1609 kprintf( "%s: ioctl: Geometry odd or even only.\n",
1614 /* set/clear even/odd flags */
1615 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1616 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1618 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1619 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1620 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1622 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1624 if (geo->columns <= 0) {
1626 "%s: ioctl: %d: columns must be greater than zero.\n",
1627 bktr_name(bktr), geo->columns);
1630 else if ((geo->columns & 0x3fe) != geo->columns) {
1632 "%s: ioctl: %d: columns too large or not even.\n",
1633 bktr_name(bktr), geo->columns);
1637 if (geo->rows <= 0) {
1639 "%s: ioctl: %d: rows must be greater than zero.\n",
1640 bktr_name(bktr), geo->rows);
1643 else if (((geo->rows & 0x7fe) != geo->rows) ||
1644 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1645 ((geo->rows & 0x3fe) != geo->rows)) ) {
1647 "%s: ioctl: %d: rows too large or not even.\n",
1648 bktr_name(bktr), geo->rows);
1652 if (geo->frames > 32) {
1653 kprintf("%s: ioctl: too many frames.\n",
1662 bktr->dma_prog_loaded = FALSE;
1663 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1665 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1667 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1668 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1670 /* meteor_mem structure for SYNC Capture */
1671 if (geo->frames > 1) temp += PAGE_SIZE;
1674 if ((int) temp > bktr->alloc_pages
1675 && bktr->video.addr == 0) {
1677 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1679 kmem_free(&kernel_map, bktr->bigbuf,
1680 (bktr->alloc_pages * PAGE_SIZE));
1683 bktr->alloc_pages = temp;
1686 "%s: ioctl: Allocating %d bytes\n",
1687 bktr_name(bktr), temp*PAGE_SIZE);
1697 bktr->rows = geo->rows;
1698 bktr->cols = geo->columns;
1699 bktr->frames = geo->frames;
1701 /* Pixel format (if in meteor pixfmt compatibility mode) */
1702 if ( bktr->pixfmt_compat ) {
1703 bktr->format = METEOR_GEO_YUV_422;
1704 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1705 case 0: /* default */
1706 case METEOR_GEO_RGB16:
1707 bktr->format = METEOR_GEO_RGB16;
1709 case METEOR_GEO_RGB24:
1710 bktr->format = METEOR_GEO_RGB24;
1712 case METEOR_GEO_YUV_422:
1713 bktr->format = METEOR_GEO_YUV_422;
1714 if (geo->oformat & METEOR_GEO_YUV_12)
1715 bktr->format = METEOR_GEO_YUV_12;
1717 case METEOR_GEO_YUV_PACKED:
1718 bktr->format = METEOR_GEO_YUV_PACKED;
1721 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1724 if (bktr->flags & METEOR_CAP_MASK) {
1726 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1727 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1728 case METEOR_ONLY_ODD_FIELDS:
1729 bktr->flags |= METEOR_WANT_ODD;
1731 case METEOR_ONLY_EVEN_FIELDS:
1732 bktr->flags |= METEOR_WANT_EVEN;
1735 bktr->flags |= METEOR_WANT_MASK;
1739 start_capture(bktr, METEOR_CONTIN);
1740 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1741 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1742 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1743 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1749 /* end of METEORSETGEO */
1751 /* FIXME. The Capture Area currently has the following restrictions:
1753 y_offset may need to be even in interlaced modes
1754 RGB24 - Interlaced mode
1755 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1756 y_size must be greater than or equal to METEORSETGEO height (rows)
1757 RGB24 - Even Only (or Odd Only) mode
1758 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1759 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1760 YUV12 - Interlaced mode
1761 x_size must be greater than or equal to METEORSETGEO width (cols)
1762 y_size must be greater than or equal to METEORSETGEO height (rows)
1763 YUV12 - Even Only (or Odd Only) mode
1764 x_size must be greater than or equal to METEORSETGEO width (cols)
1765 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1768 case BT848_SCAPAREA: /* set capture area of each video frame */
1769 /* can't change parameters while capturing */
1770 if (bktr->flags & METEOR_CAP_MASK)
1773 cap_area = (struct bktr_capture_area *) arg;
1774 bktr->capture_area_x_offset = cap_area->x_offset;
1775 bktr->capture_area_y_offset = cap_area->y_offset;
1776 bktr->capture_area_x_size = cap_area->x_size;
1777 bktr->capture_area_y_size = cap_area->y_size;
1778 bktr->capture_area_enabled = TRUE;
1780 bktr->dma_prog_loaded = FALSE;
1783 case BT848_GCAPAREA: /* get capture area of each video frame */
1784 cap_area = (struct bktr_capture_area *) arg;
1785 if (bktr->capture_area_enabled == FALSE) {
1786 cap_area->x_offset = 0;
1787 cap_area->y_offset = 0;
1788 cap_area->x_size = format_params[
1789 bktr->format_params].scaled_hactive;
1790 cap_area->y_size = format_params[
1791 bktr->format_params].vactive;
1793 cap_area->x_offset = bktr->capture_area_x_offset;
1794 cap_area->y_offset = bktr->capture_area_y_offset;
1795 cap_area->x_size = bktr->capture_area_x_size;
1796 cap_area->y_size = bktr->capture_area_y_size;
1801 return common_ioctl( bktr, cmd, arg );
1811 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1814 unsigned int temp, temp1;
1827 /* Read the last key pressed by the Remote Control */
1828 if (bktr->remote_control == 0) return (EINVAL);
1829 remote_read(bktr, (struct bktr_remote *)arg);
1832 #if defined( TUNER_AFC )
1833 case TVTUNER_SETAFC:
1834 bktr->tuner.afc = (*(int *)arg != 0);
1837 case TVTUNER_GETAFC:
1838 *(int *)arg = bktr->tuner.afc;
1839 /* XXX Perhaps use another bit to indicate AFC success? */
1841 #endif /* TUNER_AFC */
1843 case TVTUNER_SETCHNL:
1844 temp_mute( bktr, TRUE );
1845 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1847 temp_mute( bktr, FALSE );
1850 *(unsigned long *)arg = temp;
1852 /* after every channel change, we must restart the MSP34xx */
1853 /* audio chip to reselect NICAM STEREO or MONO audio */
1854 if ( bktr->card.msp3400c )
1855 msp_autodetect( bktr );
1857 /* after every channel change, we must restart the DPL35xx */
1858 if ( bktr->card.dpl3518a )
1859 dpl_autodetect( bktr );
1861 temp_mute( bktr, FALSE );
1864 case TVTUNER_GETCHNL:
1865 *(unsigned long *)arg = bktr->tuner.channel;
1868 case TVTUNER_SETTYPE:
1869 temp = *(unsigned long *)arg;
1870 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1872 bktr->tuner.chnlset = temp;
1875 case TVTUNER_GETTYPE:
1876 *(unsigned long *)arg = bktr->tuner.chnlset;
1879 case TVTUNER_GETSTATUS:
1880 temp = get_tuner_status( bktr );
1881 *(unsigned long *)arg = temp & 0xff;
1884 case TVTUNER_SETFREQ:
1885 temp_mute( bktr, TRUE );
1886 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1887 temp_mute( bktr, FALSE );
1889 temp_mute( bktr, FALSE );
1892 *(unsigned long *)arg = temp;
1894 /* after every channel change, we must restart the MSP34xx */
1895 /* audio chip to reselect NICAM STEREO or MONO audio */
1896 if ( bktr->card.msp3400c )
1897 msp_autodetect( bktr );
1899 /* after every channel change, we must restart the DPL35xx */
1900 if ( bktr->card.dpl3518a )
1901 dpl_autodetect( bktr );
1903 temp_mute( bktr, FALSE );
1906 case TVTUNER_GETFREQ:
1907 *(unsigned long *)arg = bktr->tuner.frequency;
1910 case TVTUNER_GETCHNLSET:
1911 return tuner_getchnlset((struct bktr_chnlset *)arg);
1913 case BT848_SAUDIO: /* set audio channel */
1914 if ( set_audio( bktr, *(int*)arg ) < 0 )
1918 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1919 case BT848_SHUE: /* set hue */
1920 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1923 case BT848_GHUE: /* get hue */
1924 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1927 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1928 case BT848_SBRIG: /* set brightness */
1929 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1932 case BT848_GBRIG: /* get brightness */
1933 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1937 case BT848_SCSAT: /* set chroma saturation */
1938 tmp_int = *(int*)arg;
1940 temp = INB(bktr, BKTR_E_CONTROL);
1941 temp1 = INB(bktr, BKTR_O_CONTROL);
1942 if ( tmp_int & BIT_EIGHT_HIGH ) {
1943 temp |= (BT848_E_CONTROL_SAT_U_MSB |
1944 BT848_E_CONTROL_SAT_V_MSB);
1945 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1946 BT848_O_CONTROL_SAT_V_MSB);
1949 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1950 BT848_E_CONTROL_SAT_V_MSB);
1951 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1952 BT848_O_CONTROL_SAT_V_MSB);
1955 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1956 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1957 OUTB(bktr, BKTR_E_CONTROL, temp);
1958 OUTB(bktr, BKTR_O_CONTROL, temp1);
1961 case BT848_GCSAT: /* get chroma saturation */
1962 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1963 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1964 tmp_int |= BIT_EIGHT_HIGH;
1965 *(int*)arg = tmp_int;
1969 case BT848_SVSAT: /* set chroma V saturation */
1970 tmp_int = *(int*)arg;
1972 temp = INB(bktr, BKTR_E_CONTROL);
1973 temp1 = INB(bktr, BKTR_O_CONTROL);
1974 if ( tmp_int & BIT_EIGHT_HIGH) {
1975 temp |= BT848_E_CONTROL_SAT_V_MSB;
1976 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1979 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1980 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1983 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1984 OUTB(bktr, BKTR_E_CONTROL, temp);
1985 OUTB(bktr, BKTR_O_CONTROL, temp1);
1988 case BT848_GVSAT: /* get chroma V saturation */
1989 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1990 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1991 tmp_int |= BIT_EIGHT_HIGH;
1992 *(int*)arg = tmp_int;
1996 case BT848_SUSAT: /* set chroma U saturation */
1997 tmp_int = *(int*)arg;
1999 temp = INB(bktr, BKTR_E_CONTROL);
2000 temp1 = INB(bktr, BKTR_O_CONTROL);
2001 if ( tmp_int & BIT_EIGHT_HIGH ) {
2002 temp |= BT848_E_CONTROL_SAT_U_MSB;
2003 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2006 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2007 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2010 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2011 OUTB(bktr, BKTR_E_CONTROL, temp);
2012 OUTB(bktr, BKTR_O_CONTROL, temp1);
2015 case BT848_GUSAT: /* get chroma U saturation */
2016 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2017 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2018 tmp_int |= BIT_EIGHT_HIGH;
2019 *(int*)arg = tmp_int;
2022 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2024 case BT848_SLNOTCH: /* set luma notch */
2025 tmp_int = (*(int *)arg & 0x7) << 5 ;
2026 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2027 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2028 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2029 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2032 case BT848_GLNOTCH: /* get luma notch */
2033 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2038 case BT848_SCONT: /* set contrast */
2039 tmp_int = *(int*)arg;
2041 temp = INB(bktr, BKTR_E_CONTROL);
2042 temp1 = INB(bktr, BKTR_O_CONTROL);
2043 if ( tmp_int & BIT_EIGHT_HIGH ) {
2044 temp |= BT848_E_CONTROL_CON_MSB;
2045 temp1 |= BT848_O_CONTROL_CON_MSB;
2048 temp &= ~BT848_E_CONTROL_CON_MSB;
2049 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2052 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2053 OUTB(bktr, BKTR_E_CONTROL, temp);
2054 OUTB(bktr, BKTR_O_CONTROL, temp1);
2057 case BT848_GCONT: /* get contrast */
2058 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2059 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2060 tmp_int |= BIT_EIGHT_HIGH;
2061 *(int*)arg = tmp_int;
2064 /* FIXME: SCBARS and CCBARS require a valid int * */
2065 /* argument to succeed, but its not used; consider */
2066 /* using the arg to store the on/off state so */
2067 /* there's only one ioctl() needed to turn cbars on/off */
2068 case BT848_SCBARS: /* set colorbar output */
2069 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2072 case BT848_CCBARS: /* clear colorbar output */
2073 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2076 case BT848_GAUDIO: /* get audio channel */
2077 temp = bktr->audio_mux_select;
2078 if ( bktr->audio_mute_state == TRUE )
2083 case BT848_SBTSC: /* set audio channel */
2084 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2088 case BT848_WEEPROM: /* write eeprom */
2089 offset = (((struct eeProm *)arg)->offset);
2090 count = (((struct eeProm *)arg)->count);
2091 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2092 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2096 case BT848_REEPROM: /* read eeprom */
2097 offset = (((struct eeProm *)arg)->offset);
2098 count = (((struct eeProm *)arg)->count);
2099 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2100 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2104 case BT848_SIGNATURE:
2105 offset = (((struct eeProm *)arg)->offset);
2106 count = (((struct eeProm *)arg)->count);
2107 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2108 if ( signCard( bktr, offset, count, buf ) < 0 )
2112 /* Ioctl's for direct gpio access */
2113 #ifdef BKTR_GPIO_ACCESS
2114 case BT848_GPIO_GET_EN:
2115 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2118 case BT848_GPIO_SET_EN:
2119 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2122 case BT848_GPIO_GET_DATA:
2123 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2126 case BT848_GPIO_SET_DATA:
2127 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2129 #endif /* BKTR_GPIO_ACCESS */
2131 /* Ioctl's for running the tuner device in radio mode */
2134 *(unsigned char *)arg = bktr->tuner.radio_mode;
2138 bktr->tuner.radio_mode = *(unsigned char *)arg;
2142 *(unsigned long *)arg = bktr->tuner.frequency;
2146 /* The argument to this ioctl is NOT freq*16. It is
2150 temp=(int)*(unsigned long *)arg;
2152 #ifdef BKTR_RADIO_DEBUG
2153 kprintf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2154 (int)*(unsigned long *)arg, temp);
2157 #ifndef BKTR_RADIO_NOFREQCHECK
2158 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2160 if(temp<8750 || temp>10800) {
2161 kprintf("%s: Radio frequency out of range\n", bktr_name(bktr));
2165 temp_mute( bktr, TRUE );
2166 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2167 temp_mute( bktr, FALSE );
2168 #ifdef BKTR_RADIO_DEBUG
2170 kprintf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2174 *(unsigned long *)arg = temp;
2177 /* Luigi's I2CWR ioctl */
2179 par = *(u_long *)arg;
2180 write = (par >> 24) & 0xff ;
2181 i2c_addr = (par >> 16) & 0xff ;
2182 i2c_port = (par >> 8) & 0xff ;
2183 data = (par) & 0xff ;
2186 i2cWrite( bktr, i2c_addr, i2c_port, data);
2188 data = i2cRead( bktr, i2c_addr);
2190 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2194 #ifdef BT848_MSP_READ
2195 /* I2C ioctls to allow userland access to the MSP chip */
2196 case BT848_MSP_READ:
2198 struct bktr_msp_control *msp;
2199 msp = (struct bktr_msp_control *) arg;
2200 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2201 msp->function, msp->address);
2205 case BT848_MSP_WRITE:
2207 struct bktr_msp_control *msp;
2208 msp = (struct bktr_msp_control *) arg;
2209 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2210 msp->address, msp->data );
2214 case BT848_MSP_RESET:
2215 msp_dpl_reset(bktr, bktr->msp_addr);
2220 return common_ioctl( bktr, cmd, arg );
2231 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2235 struct meteor_pixfmt *pf_pub;
2239 case METEORSINPUT: /* set input device */
2240 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2241 /* On the original bt848 boards, */
2242 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2243 /* On the Hauppauge bt878 boards, */
2244 /* Tuner is MUX0, RCA is MUX3 */
2245 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2246 /* stick with this system in our Meteor Emulation */
2248 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2250 /* this is the RCA video input */
2251 case 0: /* default */
2252 case METEOR_INPUT_DEV0:
2253 /* METEOR_INPUT_DEV_RCA: */
2254 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2256 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2257 & ~BT848_IFORM_MUXSEL);
2259 /* work around for new Hauppauge 878 cards */
2260 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2261 (bktr->id==BROOKTREE_878 ||
2262 bktr->id==BROOKTREE_879) )
2263 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2265 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2267 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2268 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2269 set_audio( bktr, AUDIO_EXTERN );
2272 /* this is the tuner input */
2273 case METEOR_INPUT_DEV1:
2274 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2276 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2277 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2278 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2279 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2280 set_audio( bktr, AUDIO_TUNER );
2283 /* this is the S-VHS input, but with a composite camera */
2284 case METEOR_INPUT_DEV2:
2285 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2287 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2288 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2289 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2290 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2291 set_audio( bktr, AUDIO_EXTERN );
2294 /* this is the S-VHS input */
2295 case METEOR_INPUT_DEV_SVIDEO:
2296 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2297 | METEOR_DEV_SVIDEO;
2298 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2299 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2300 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2301 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2302 set_audio( bktr, AUDIO_EXTERN );
2305 case METEOR_INPUT_DEV3:
2306 if ((bktr->id == BROOKTREE_848A) ||
2307 (bktr->id == BROOKTREE_849A) ||
2308 (bktr->id == BROOKTREE_878) ||
2309 (bktr->id == BROOKTREE_879) ) {
2310 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2312 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2314 /* work around for new Hauppauge 878 cards */
2315 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2316 (bktr->id==BROOKTREE_878 ||
2317 bktr->id==BROOKTREE_879) )
2318 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2320 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2322 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2323 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2324 set_audio( bktr, AUDIO_EXTERN );
2334 case METEORGINPUT: /* get input device */
2335 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2338 case METEORSACTPIXFMT:
2339 if (( *(int *)arg < 0 ) ||
2340 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2343 bktr->pixfmt = *(int *)arg;
2344 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2345 | pixfmt_swap_flags( bktr->pixfmt ));
2346 bktr->pixfmt_compat = FALSE;
2349 case METEORGACTPIXFMT:
2350 *(int *)arg = bktr->pixfmt;
2353 case METEORGSUPPIXFMT :
2354 pf_pub = (struct meteor_pixfmt *)arg;
2355 pixfmt = pf_pub->index;
2357 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2360 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2361 sizeof( *pf_pub ) );
2363 /* Patch in our format index */
2364 pf_pub->index = pixfmt;
2367 #if defined( STATUS_SUM )
2368 case BT848_GSTATUS: /* reap status */
2374 *(u_int*)arg = temp;
2377 #endif /* STATUS_SUM */
2389 /******************************************************************************
2390 * bt848 RISC programming routines:
2399 dump_bt848( bktr_ptr_t bktr )
2402 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2403 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2404 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2405 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2406 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2411 for (i = 0; i < 40; i+=4) {
2412 kprintf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2414 r[i], INL(bktr, r[i]),
2415 r[i+1], INL(bktr, r[i+1]),
2416 r[i+2], INL(bktr, r[i+2]),
2417 r[i+3], INL(bktr, r[i+3]));
2420 kprintf("%s: INT STAT %x \n", bktr_name(bktr),
2421 INL(bktr, BKTR_INT_STAT));
2422 kprintf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2423 INL(bktr, BKTR_INT_MASK));
2424 kprintf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2425 INW(bktr, BKTR_GPIO_DMA_CTL));
2433 * build write instruction
2435 #define BKTR_FM1 0x6 /* packed data to follow */
2436 #define BKTR_FM3 0xe /* planar data to follow */
2437 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2438 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2439 #define BKTR_PXV 0x0 /* valid word (never used) */
2440 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2441 #define BKTR_SOL 0x2 /* first dword */
2443 #define OP_WRITE (0x1 << 28)
2444 #define OP_SKIP (0x2 << 28)
2445 #define OP_WRITEC (0x5 << 28)
2446 #define OP_JUMP (0x7 << 28)
2447 #define OP_SYNC (0x8 << 28)
2448 #define OP_WRITE123 (0x9 << 28)
2449 #define OP_WRITES123 (0xb << 28)
2450 #define OP_SOL (1 << 27) /* first instr for scanline */
2451 #define OP_EOL (1 << 26)
2453 #define BKTR_RESYNC (1 << 15)
2454 #define BKTR_GEN_IRQ (1 << 24)
2457 * The RISC status bits can be set/cleared in the RISC programs
2458 * and tested in the Interrupt Handler
2460 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2461 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2462 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2463 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2465 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2466 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2467 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2468 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2470 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2471 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2472 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2473 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2475 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2477 bktr_clip_t * clip_node;
2478 bktr->clip_start = -1;
2482 bktr->line_length = width;
2485 bktr->current_col = 0;
2487 if (bktr->max_clip_node == 0 ) return TRUE;
2488 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2491 for (i = 0; i < bktr->max_clip_node; i++ ) {
2492 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2493 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2494 bktr->clip_start = i;
2502 static bool_t getline(bktr_reg_t *bktr, int x ) {
2504 bktr_clip_t * clip_node ;
2506 if (bktr->line_length == 0 ||
2507 bktr->current_col >= bktr->line_length) return FALSE;
2509 bktr->y = min(bktr->last_y, bktr->line_length);
2510 bktr->y2 = bktr->line_length;
2512 bktr->yclip = bktr->yclip2 = -1;
2513 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2514 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2515 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2516 if (bktr->last_y <= clip_node->y_min) {
2517 bktr->y = min(bktr->last_y, bktr->line_length);
2518 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2519 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2520 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2521 bktr->last_y = bktr->yclip2;
2522 bktr->clip_start = i;
2524 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2525 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2526 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2527 if (bktr->last_y >= clip_node->y_min) {
2528 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2529 bktr->last_y = bktr->yclip2;
2530 bktr->clip_start = j;
2539 if (bktr->current_col <= bktr->line_length) {
2540 bktr->current_col = bktr->line_length;
2546 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2547 u_long operation, int pixel_width,
2548 volatile u_char ** target_buffer, int cols ) {
2551 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2552 u_int skip, start_skip;
2554 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2555 /* to the 1st byte in the mem dword containing our start addr. */
2556 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2559 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2560 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2561 case 2 : start_skip = 4 ; break;
2562 case 1 : start_skip = 8 ; break;
2565 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2566 if ( width == cols) {
2567 flag = OP_SOL | OP_EOL;
2568 } else if (bktr->current_col == 0 ) {
2570 } else if (bktr->current_col == cols) {
2575 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2576 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2581 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2582 if (operation != OP_SKIP )
2583 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2585 *target_buffer += width * pixel_width;
2586 bktr->current_col += width;
2590 if (bktr->current_col == 0 && width == cols) {
2593 } else if (bktr->current_col == 0 ) {
2596 } else if (bktr->current_col >= cols) {
2605 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2606 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2611 *(*dma_prog)++ = operation | flag |
2612 (width * pixel_width / 2 - skip);
2613 if (operation != OP_SKIP )
2614 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2615 *target_buffer += (width * pixel_width / 2) ;
2617 if ( operation == OP_WRITE )
2618 operation = OP_WRITEC;
2619 *(*dma_prog)++ = operation | flag2 |
2620 (width * pixel_width / 2);
2621 *target_buffer += (width * pixel_width / 2) ;
2622 bktr->current_col += width;
2630 * Generate the RISC instructions to capture both VBI and video images
2633 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2636 volatile uint32_t target_buffer, buffer, target,width;
2637 volatile uint32_t pitch;
2638 volatile uint32_t *dma_prog; /* DMA prog is an array of
2639 32 bit RISC instructions */
2640 volatile uint32_t *loop_point;
2641 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2642 u_int Bpp = pf_int->public.Bpp;
2643 unsigned int vbisamples; /* VBI samples per line */
2644 unsigned int vbilines; /* VBI lines per field */
2645 unsigned int num_dwords; /* DWORDS per line */
2647 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2648 vbilines = format_params[bktr->format_params].vbi_num_lines;
2649 num_dwords = vbisamples/4;
2651 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2652 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2653 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2654 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2657 OUTB(bktr, BKTR_OFORM, 0x00);
2659 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2660 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2661 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2662 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2664 /* disable gamma correction removal */
2665 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2668 OUTB(bktr, BKTR_E_VTC, 0);
2669 OUTB(bktr, BKTR_O_VTC, 0);
2671 OUTB(bktr, BKTR_E_VTC, 1);
2672 OUTB(bktr, BKTR_O_VTC, 1);
2674 bktr->capcontrol = 3 << 2 | 3;
2676 dma_prog = (uint32_t *) bktr->dma_prog;
2678 /* Construct Write */
2680 if (bktr->video.addr) {
2681 target_buffer = (u_long) bktr->video.addr;
2682 pitch = bktr->video.width;
2685 target_buffer = (u_long) vtophys(bktr->bigbuf);
2689 buffer = target_buffer;
2691 /* Wait for the VRE sync marking the end of the Even and
2692 * the start of the Odd field. Resync here.
2694 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2697 loop_point = dma_prog;
2699 /* store the VBI data */
2700 /* look for sync with packed data */
2701 *dma_prog++ = OP_SYNC | BKTR_FM1;
2703 for(i = 0; i < vbilines; i++) {
2704 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2705 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2706 (i * VBI_LINE_SIZE));
2709 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2710 /* store the Odd field video image */
2711 /* look for sync with packed data */
2712 *dma_prog++ = OP_SYNC | BKTR_FM1;
2713 *dma_prog++ = 0; /* NULL WORD */
2715 for (i = 0; i < (rows/interlace); i++) {
2716 target = target_buffer;
2717 if ( notclipped(bktr, i, width)) {
2718 split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2719 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2722 while(getline(bktr, i)) {
2723 if (bktr->y != bktr->y2 ) {
2724 split(bktr, &dma_prog,
2725 bktr->y2 - bktr->y, OP_WRITE,
2726 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2728 if (bktr->yclip != bktr->yclip2 ) {
2729 split(bktr,&dma_prog,
2730 bktr->yclip2 - bktr->yclip,
2732 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2738 target_buffer += interlace * pitch;
2744 /* Grab the Even field */
2745 /* Look for the VRO, end of Odd field, marker */
2746 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2747 *dma_prog++ = 0; /* NULL WORD */
2749 /* store the VBI data */
2750 /* look for sync with packed data */
2751 *dma_prog++ = OP_SYNC | BKTR_FM1;
2753 for(i = 0; i < vbilines; i++) {
2754 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2755 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2756 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2759 /* store the video image */
2760 if (i_flag == 1) /*Even Only*/
2761 target_buffer = buffer;
2762 if (i_flag == 3) /*interlaced*/
2763 target_buffer = buffer+pitch;
2766 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2767 /* look for sync with packed data */
2768 *dma_prog++ = OP_SYNC | BKTR_FM1;
2769 *dma_prog++ = 0; /* NULL WORD */
2771 for (i = 0; i < (rows/interlace); i++) {
2772 target = target_buffer;
2773 if ( notclipped(bktr, i, width)) {
2774 split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2775 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2777 while(getline(bktr, i)) {
2778 if (bktr->y != bktr->y2 ) {
2779 split(bktr, &dma_prog,
2780 bktr->y2 - bktr->y, OP_WRITE,
2781 Bpp, (volatile u_char **)(uintptr_t)&target,
2784 if (bktr->yclip != bktr->yclip2 ) {
2785 split(bktr, &dma_prog,
2786 bktr->yclip2 - bktr->yclip, OP_SKIP,
2787 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2794 target_buffer += interlace * pitch;
2799 /* Look for end of 'Even Field' */
2800 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2801 *dma_prog++ = 0; /* NULL WORD */
2803 *dma_prog++ = OP_JUMP ;
2804 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2805 *dma_prog++ = 0; /* NULL WORD */
2813 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2816 volatile uint32_t target_buffer, buffer, target,width;
2817 volatile uint32_t pitch;
2818 volatile uint32_t *dma_prog;
2819 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2820 u_int Bpp = pf_int->public.Bpp;
2822 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2823 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2824 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2825 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2827 OUTB(bktr, BKTR_OFORM, 0x00);
2829 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2830 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2831 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2832 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2834 /* disable gamma correction removal */
2835 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2838 OUTB(bktr, BKTR_E_VTC, 0);
2839 OUTB(bktr, BKTR_O_VTC, 0);
2841 OUTB(bktr, BKTR_E_VTC, 1);
2842 OUTB(bktr, BKTR_O_VTC, 1);
2844 bktr->capcontrol = 3 << 2 | 3;
2846 dma_prog = (uint32_t *) bktr->dma_prog;
2848 /* Construct Write */
2850 if (bktr->video.addr) {
2851 target_buffer = (uint32_t) bktr->video.addr;
2852 pitch = bktr->video.width;
2855 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2859 buffer = target_buffer;
2861 /* contruct sync : for video packet format */
2862 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2864 /* sync, mode indicator packed data */
2865 *dma_prog++ = 0; /* NULL WORD */
2867 for (i = 0; i < (rows/interlace); i++) {
2868 target = target_buffer;
2869 if ( notclipped(bktr, i, width)) {
2870 split(bktr, &dma_prog,
2871 bktr->y2 - bktr->y, OP_WRITE,
2872 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2875 while(getline(bktr, i)) {
2876 if (bktr->y != bktr->y2 ) {
2877 split(bktr, &dma_prog,
2878 bktr->y2 - bktr->y, OP_WRITE,
2879 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2881 if (bktr->yclip != bktr->yclip2 ) {
2882 split(bktr,&dma_prog,
2883 bktr->yclip2 - bktr->yclip,
2885 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2891 target_buffer += interlace * pitch;
2898 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2899 *dma_prog++ = 0; /* NULL WORD */
2901 *dma_prog++ = OP_JUMP;
2902 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2907 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2908 *dma_prog++ = 0; /* NULL WORD */
2910 *dma_prog++ = OP_JUMP;
2911 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2916 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2917 *dma_prog++ = 0; /* NULL WORD */
2918 *dma_prog++ = OP_JUMP;
2919 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
2923 if (interlace == 2) {
2925 target_buffer = buffer + pitch;
2927 dma_prog = (uint32_t *) bktr->odd_dma_prog;
2929 /* sync vre IRQ bit */
2930 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2931 *dma_prog++ = 0; /* NULL WORD */
2933 for (i = 0; i < (rows/interlace); i++) {
2934 target = target_buffer;
2935 if ( notclipped(bktr, i, width)) {
2936 split(bktr, &dma_prog,
2937 bktr->y2 - bktr->y, OP_WRITE,
2938 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2940 while(getline(bktr, i)) {
2941 if (bktr->y != bktr->y2 ) {
2942 split(bktr, &dma_prog,
2943 bktr->y2 - bktr->y, OP_WRITE,
2944 Bpp, (volatile u_char **)(uintptr_t)&target,
2947 if (bktr->yclip != bktr->yclip2 ) {
2948 split(bktr, &dma_prog,
2949 bktr->yclip2 - bktr->yclip, OP_SKIP,
2950 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2957 target_buffer += interlace * pitch;
2962 /* sync vre IRQ bit */
2963 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2964 *dma_prog++ = 0; /* NULL WORD */
2965 *dma_prog++ = OP_JUMP ;
2966 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
2967 *dma_prog++ = 0; /* NULL WORD */
2975 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2976 int cols, int rows, int interlace )
2979 volatile unsigned int inst;
2980 volatile unsigned int inst3;
2981 volatile uint32_t target_buffer, buffer;
2982 volatile uint32_t *dma_prog;
2983 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2986 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2988 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
2989 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2991 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
2992 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2994 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
2995 bktr->capcontrol = 3 << 2 | 3;
2997 dma_prog = (uint32_t *) bktr->dma_prog;
2999 /* Construct Write */
3001 /* write , sol, eol */
3002 inst = OP_WRITE | OP_SOL | (cols);
3003 /* write , sol, eol */
3004 inst3 = OP_WRITE | OP_EOL | (cols);
3006 if (bktr->video.addr)
3007 target_buffer = (uint32_t) bktr->video.addr;
3009 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3011 buffer = target_buffer;
3013 /* contruct sync : for video packet format */
3014 /* sync, mode indicator packed data */
3015 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3016 *dma_prog++ = 0; /* NULL WORD */
3020 for (i = 0; i < (rows/interlace); i++) {
3022 *dma_prog++ = target_buffer;
3023 *dma_prog++ = inst3;
3024 *dma_prog++ = target_buffer + b;
3025 target_buffer += interlace*(cols * 2);
3031 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3032 *dma_prog++ = 0; /* NULL WORD */
3034 *dma_prog++ = OP_JUMP;
3035 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3040 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3041 *dma_prog++ = 0; /* NULL WORD */
3042 *dma_prog++ = OP_JUMP;
3043 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3048 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3049 *dma_prog++ = 0; /* NULL WORD */
3050 *dma_prog++ = OP_JUMP ;
3051 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3055 if (interlace == 2) {
3057 target_buffer = (uint32_t) buffer + cols*2;
3059 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3062 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3063 *dma_prog++ = 0; /* NULL WORD */
3065 for (i = 0; i < (rows/interlace) ; i++) {
3067 *dma_prog++ = target_buffer;
3068 *dma_prog++ = inst3;
3069 *dma_prog++ = target_buffer + b;
3070 target_buffer += interlace * ( cols*2);
3074 /* sync vro IRQ bit */
3075 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3076 *dma_prog++ = 0; /* NULL WORD */
3077 *dma_prog++ = OP_JUMP ;
3078 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3080 *dma_prog++ = OP_JUMP;
3081 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3082 *dma_prog++ = 0; /* NULL WORD */
3090 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3091 int cols, int rows, int interlace ){
3094 volatile unsigned int inst;
3095 volatile uint32_t target_buffer, t1, buffer;
3096 volatile uint32_t *dma_prog;
3097 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3099 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3101 dma_prog = (uint32_t*) bktr->dma_prog;
3103 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3105 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3106 OUTB(bktr, BKTR_OFORM, 0x00);
3108 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3109 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3111 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3112 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3114 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3115 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3116 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3117 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3119 /* disable gamma correction removal */
3120 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3122 /* Construct Write */
3123 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3124 if (bktr->video.addr)
3125 target_buffer = (uint32_t) bktr->video.addr;
3127 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3129 buffer = target_buffer;
3133 /* contruct sync : for video packet format */
3134 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3135 *dma_prog++ = 0; /* NULL WORD */
3137 for (i = 0; i < (rows/interlace ) ; i++) {
3139 *dma_prog++ = cols/2 | cols/2 << 16;
3140 *dma_prog++ = target_buffer;
3141 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3142 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3143 target_buffer += interlace*cols;
3148 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3149 *dma_prog++ = 0; /* NULL WORD */
3151 *dma_prog++ = OP_JUMP ;
3152 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3156 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3157 *dma_prog++ = 0; /* NULL WORD */
3159 *dma_prog++ = OP_JUMP;
3160 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3164 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3165 *dma_prog++ = 0; /* NULL WORD */
3167 *dma_prog++ = OP_JUMP ;
3168 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3172 if (interlace == 2) {
3174 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3176 target_buffer = (uint32_t) buffer + cols;
3177 t1 = buffer + cols/2;
3178 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3179 *dma_prog++ = 0; /* NULL WORD */
3181 for (i = 0; i < (rows/interlace ) ; i++) {
3183 *dma_prog++ = cols/2 | cols/2 << 16;
3184 *dma_prog++ = target_buffer;
3185 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3186 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3187 target_buffer += interlace*cols;
3191 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3192 *dma_prog++ = 0; /* NULL WORD */
3193 *dma_prog++ = OP_JUMP ;
3194 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3195 *dma_prog++ = 0; /* NULL WORD */
3203 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3204 int cols, int rows, int interlace ){
3207 volatile unsigned int inst;
3208 volatile unsigned int inst1;
3209 volatile uint32_t target_buffer, t1, buffer;
3210 volatile uint32_t *dma_prog;
3211 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3213 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3215 dma_prog = (uint32_t *) bktr->dma_prog;
3217 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3219 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3220 OUTB(bktr, BKTR_OFORM, 0x0);
3222 /* Construct Write */
3223 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3224 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3225 if (bktr->video.addr)
3226 target_buffer = (uint32_t) bktr->video.addr;
3228 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3230 buffer = target_buffer;
3233 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3234 *dma_prog++ = 0; /* NULL WORD */
3236 for (i = 0; i < (rows/interlace )/2 ; i++) {
3238 *dma_prog++ = cols/2 | (cols/2 << 16);
3239 *dma_prog++ = target_buffer;
3240 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3241 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3242 target_buffer += interlace*cols;
3243 *dma_prog++ = inst1;
3244 *dma_prog++ = cols/2 | (cols/2 << 16);
3245 *dma_prog++ = target_buffer;
3246 target_buffer += interlace*cols;
3252 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3253 *dma_prog++ = 0; /* NULL WORD */
3255 *dma_prog++ = OP_JUMP;
3256 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3260 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3261 *dma_prog++ = 0; /* NULL WORD */
3263 *dma_prog++ = OP_JUMP;
3264 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3268 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3269 *dma_prog++ = 0; /* NULL WORD */
3270 *dma_prog++ = OP_JUMP ;
3271 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3275 if (interlace == 2) {
3277 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3279 target_buffer = (uint32_t) buffer + cols;
3280 t1 = buffer + cols/2;
3281 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3282 *dma_prog++ = 0; /* NULL WORD */
3284 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3286 *dma_prog++ = cols/2 | (cols/2 << 16);
3287 *dma_prog++ = target_buffer;
3288 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3289 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3290 target_buffer += interlace*cols;
3291 *dma_prog++ = inst1;
3292 *dma_prog++ = cols/2 | (cols/2 << 16);
3293 *dma_prog++ = target_buffer;
3294 target_buffer += interlace*cols;
3301 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3302 *dma_prog++ = 0; /* NULL WORD */
3303 *dma_prog++ = OP_JUMP;
3304 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3305 *dma_prog++ = 0; /* NULL WORD */
3314 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3316 int rows, cols, interlace;
3319 struct format_params *fp;
3320 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3323 fp = &format_params[bktr->format_params];
3325 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3327 /* disable FIFO & RISC, leave other bits alone */
3328 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3330 /* set video parameters */
3331 if (bktr->capture_area_enabled)
3332 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3333 / fp->scaled_htotal / bktr->cols) - 4096;
3335 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3336 / fp->scaled_htotal / bktr->cols) - 4096;
3338 /* kprintf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3339 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3340 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3341 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3342 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3344 /* horizontal active */
3346 /* kprintf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3347 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3348 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3349 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3350 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3351 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3352 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3354 /* horizontal delay */
3355 if (bktr->capture_area_enabled)
3356 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3357 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3359 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3361 temp = temp & 0x3fe;
3363 /* kprintf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3364 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3365 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3366 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3367 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3368 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3369 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3371 /* vertical scale */
3373 if (bktr->capture_area_enabled) {
3374 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3375 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3377 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3380 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3383 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3384 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3386 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3389 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3394 /* kprintf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3395 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3396 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3397 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3398 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3399 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3400 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3403 /* vertical active */
3404 if (bktr->capture_area_enabled)
3405 temp = bktr->capture_area_y_size;
3408 /* kprintf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3409 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3410 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3411 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3412 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3413 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3414 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3416 /* vertical delay */
3417 if (bktr->capture_area_enabled)
3418 temp = fp->vdelay + (bktr->capture_area_y_offset);
3421 /* kprintf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3422 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3423 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3424 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3425 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3426 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3427 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3429 /* end of video params */
3431 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3432 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3433 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3435 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3438 /* capture control */
3441 bktr->bktr_cap_ctl =
3442 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3443 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3444 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3448 bktr->bktr_cap_ctl =
3449 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3450 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3451 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3455 bktr->bktr_cap_ctl =
3456 (BT848_CAP_CTL_DITH_FRAME |
3457 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3458 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3459 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3464 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3469 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3471 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3472 /* user, then use the rgb_vbi RISC program. */
3473 /* Otherwise, use the normal rgb RISC program */
3474 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3475 if ( (bktr->vbiflags & VBI_OPEN)
3476 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3477 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3479 bktr->bktr_cap_ctl |=
3480 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3481 bktr->vbiflags |= VBI_CAPTURE;
3482 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3485 rgb_prog(bktr, i_flag, cols, rows, interlace);
3490 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3491 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3492 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3493 | pixfmt_swap_flags( bktr->pixfmt ));
3497 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3498 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3499 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3500 | pixfmt_swap_flags( bktr->pixfmt ));
3504 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3505 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3506 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3507 | pixfmt_swap_flags( bktr->pixfmt ));
3514 /******************************************************************************
3515 * video & video capture specific routines:
3523 start_capture( bktr_ptr_t bktr, unsigned type )
3526 struct format_params *fp;
3528 fp = &format_params[bktr->format_params];
3530 /* If requested, clear out capture buf first */
3531 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3532 bzero((caddr_t)bktr->bigbuf,
3533 (size_t)bktr->rows * bktr->cols * bktr->frames *
3534 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3537 OUTB(bktr, BKTR_DSTATUS, 0);
3538 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3540 bktr->flags |= type;
3541 bktr->flags &= ~METEOR_WANT_MASK;
3542 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3543 case METEOR_ONLY_EVEN_FIELDS:
3544 bktr->flags |= METEOR_WANT_EVEN;
3547 case METEOR_ONLY_ODD_FIELDS:
3548 bktr->flags |= METEOR_WANT_ODD;
3552 bktr->flags |= METEOR_WANT_MASK;
3557 /* TDEC is only valid for continuous captures */
3558 if ( type == METEOR_SINGLE ) {
3559 u_short fps_save = bktr->fps;
3561 set_fps(bktr, fp->frame_rate);
3562 bktr->fps = fps_save;
3565 set_fps(bktr, bktr->fps);
3567 if (bktr->dma_prog_loaded == FALSE) {
3568 build_dma_prog(bktr, i_flag);
3569 bktr->dma_prog_loaded = TRUE;
3573 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3582 set_fps( bktr_ptr_t bktr, u_short fps )
3584 struct format_params *fp;
3587 fp = &format_params[bktr->format_params];
3589 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3590 case METEOR_ONLY_EVEN_FIELDS:
3591 bktr->flags |= METEOR_WANT_EVEN;
3594 case METEOR_ONLY_ODD_FIELDS:
3595 bktr->flags |= METEOR_WANT_ODD;
3599 bktr->flags |= METEOR_WANT_MASK;
3604 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3605 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3608 OUTB(bktr, BKTR_TDEC, 0);
3610 if (fps < fp->frame_rate)
3611 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3613 OUTB(bktr, BKTR_TDEC, 0);
3623 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3624 * achieve the specified swapping.
3625 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3626 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3628 * Note also that for 3Bpp, we may additionally need to do some creative
3629 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3630 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3631 * as one would expect.
3634 static u_int pixfmt_swap_flags( int pixfmt )
3636 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3639 switch ( pf->Bpp ) {
3640 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3643 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3646 case 4 : if ( pf->swap_bytes )
3647 swapf = pf->swap_shorts ? 0 : WSWAP;
3649 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3658 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3659 * our pixfmt_table indices.
3662 static int oformat_meteor_to_bt( u_long format )
3665 struct meteor_pixfmt *pf1, *pf2;
3667 /* Find format in compatibility table */
3668 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3669 if ( meteor_pixfmt_table[i].meteor_format == format )
3672 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3674 pf1 = &meteor_pixfmt_table[i].public;
3676 /* Match it with an entry in master pixel format table */
3677 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3678 pf2 = &pixfmt_table[i].public;
3680 if (( pf1->type == pf2->type ) &&
3681 ( pf1->Bpp == pf2->Bpp ) &&
3682 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3683 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3684 ( pf1->swap_shorts == pf2->swap_shorts ))
3687 if ( i >= PIXFMT_TABLE_SIZE )
3693 /******************************************************************************
3698 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3699 #define I2CBITTIME_878 (1 << 7)
3700 #define I2C_READ 0x01
3701 #define I2C_COMMAND (I2CBITTIME | \
3702 BT848_DATA_CTL_I2CSCL | \
3703 BT848_DATA_CTL_I2CSDA)
3705 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3706 BT848_DATA_CTL_I2CSCL | \
3707 BT848_DATA_CTL_I2CSDA)
3709 /* Select between old i2c code and new iicbus / smbus code */
3710 #if defined(BKTR_USE_FREEBSD_SMBUS)
3713 * The hardware interface is actually SMB commands
3716 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3720 if (bktr->id == BROOKTREE_848 ||
3721 bktr->id == BROOKTREE_848A ||
3722 bktr->id == BROOKTREE_849A)
3725 cmd = I2C_COMMAND_878;
3728 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3729 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3732 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3733 (char)(byte1 & 0xff)))
3742 i2cRead( bktr_ptr_t bktr, int addr )
3747 if (bktr->id == BROOKTREE_848 ||
3748 bktr->id == BROOKTREE_848A ||
3749 bktr->id == BROOKTREE_849A)
3752 cmd = I2C_COMMAND_878;
3754 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3757 return ((int)((unsigned char)result));
3760 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3762 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3763 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3764 /* Therefore we need low level control of the i2c bus hardware */
3766 /* Write to the MSP or DPL registers */
3768 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3770 unsigned char addr_l, addr_h, data_h, data_l ;
3772 addr_h = (addr >>8) & 0xff;
3773 addr_l = addr & 0xff;
3774 data_h = (data >>8) & 0xff;
3775 data_l = data & 0xff;
3777 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3779 iicbus_write_byte(IICBUS(bktr), dev, 0);
3780 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3781 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3782 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3783 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3785 iicbus_stop(IICBUS(bktr));
3790 /* Read from the MSP or DPL registers */
3792 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3795 unsigned char addr_l, addr_h, dev_r;
3797 u_char data_read[2];
3799 addr_h = (addr >>8) & 0xff;
3800 addr_l = addr & 0xff;
3803 /* XXX errors ignored */
3804 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3806 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3807 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3808 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3810 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3811 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3812 iicbus_stop(IICBUS(bktr));
3814 data = (data_read[0]<<8) | data_read[1];
3819 /* Reset the MSP or DPL chip */
3820 /* The user can block the reset (which is handy if you initialise the
3821 * MSP and/or DPL audio in another operating system first (eg in Windows)
3824 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3827 #ifndef BKTR_NO_MSP_RESET
3828 /* put into reset mode */
3829 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3830 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3831 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3832 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3833 iicbus_stop(IICBUS(bktr));
3835 /* put back to operational mode */
3836 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3837 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3838 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3839 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3840 iicbus_stop(IICBUS(bktr));
3845 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3848 /* XXX errors ignored */
3849 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3850 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3851 iicbus_stop(IICBUS(bktr));
3856 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3859 * Program the i2c bus directly
3862 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3867 /* clear status bits */
3868 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3870 /* build the command datum */
3871 if (bktr->id == BROOKTREE_848 ||
3872 bktr->id == BROOKTREE_848A ||
3873 bktr->id == BROOKTREE_849A) {
3874 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3876 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3878 if ( byte2 != -1 ) {
3879 data |= ((byte2 & 0xff) << 8);
3880 data |= BT848_DATA_CTL_I2CW3B;
3883 /* write the address and data */
3884 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3886 /* wait for completion */
3887 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3888 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3893 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3905 i2cRead( bktr_ptr_t bktr, int addr )
3909 /* clear status bits */
3910 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3912 /* write the READ address */
3913 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3915 if (bktr->id == BROOKTREE_848 ||
3916 bktr->id == BROOKTREE_848A ||
3917 bktr->id == BROOKTREE_849A) {
3918 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3920 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3923 /* wait for completion */
3924 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3925 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3930 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3934 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3937 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3938 /* bt848 automated i2c bus controller cannot handle */
3939 /* Therefore we need low level control of the i2c bus hardware */
3940 /* Idea for the following functions are from elsewhere in this driver and */
3941 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3944 static void i2c_start( bktr_ptr_t bktr) {
3945 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3946 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3947 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3948 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3951 static void i2c_stop( bktr_ptr_t bktr) {
3952 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3953 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3954 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3957 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3961 /* write out the byte */
3962 for ( x = 7; x >= 0; --x ) {
3963 if ( data & (1<<x) ) {
3964 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3965 DELAY( BITD ); /* assert HI data */
3966 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3967 DELAY( BITD ); /* strobe clock */
3968 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3969 DELAY( BITD ); /* release clock */
3972 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3973 DELAY( BITD ); /* assert LO data */
3974 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3975 DELAY( BITD ); /* strobe clock */
3976 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3977 DELAY( BITD ); /* release clock */
3981 /* look for an ACK */
3982 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3983 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3984 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3985 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3990 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3995 /* read in the byte */
3996 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3997 DELAY( BITD ); /* float data */
3998 for ( x = 7; x >= 0; --x ) {
3999 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4000 DELAY( BITD ); /* strobe clock */
4001 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4002 if ( bit ) byte |= (1<<x);
4003 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4004 DELAY( BITD ); /* release clock */
4006 /* After reading the byte, send an ACK */
4007 /* (unless that was the last byte, for which we send a NAK */
4008 if (last) { /* send NAK - same a writing a 1 */
4009 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4010 DELAY( BITD ); /* set data bit */
4011 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4012 DELAY( BITD ); /* strobe clock */
4013 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4014 DELAY( BITD ); /* release clock */
4015 } else { /* send ACK - same as writing a 0 */
4016 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4017 DELAY( BITD ); /* set data bit */
4018 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4019 DELAY( BITD ); /* strobe clock */
4020 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4021 DELAY( BITD ); /* release clock */
4029 /* Write to the MSP or DPL registers */
4030 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4032 unsigned int msp_w_addr = i2c_addr;
4033 unsigned char addr_l, addr_h, data_h, data_l ;
4034 addr_h = (addr >>8) & 0xff;
4035 addr_l = addr & 0xff;
4036 data_h = (data >>8) & 0xff;
4037 data_l = data & 0xff;
4040 i2c_write_byte(bktr, msp_w_addr);
4041 i2c_write_byte(bktr, dev);
4042 i2c_write_byte(bktr, addr_h);
4043 i2c_write_byte(bktr, addr_l);
4044 i2c_write_byte(bktr, data_h);
4045 i2c_write_byte(bktr, data_l);
4049 /* Read from the MSP or DPL registers */
4050 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4052 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4053 addr_h = (addr >>8) & 0xff;
4054 addr_l = addr & 0xff;
4058 i2c_write_byte(bktr,i2c_addr);
4059 i2c_write_byte(bktr,dev_r);
4060 i2c_write_byte(bktr,addr_h);
4061 i2c_write_byte(bktr,addr_l);
4064 i2c_write_byte(bktr,i2c_addr+1);
4065 i2c_read_byte(bktr,&data_1, 0);
4066 i2c_read_byte(bktr,&data_2, 1);
4068 data = (data_1<<8) | data_2;
4072 /* Reset the MSP or DPL chip */
4073 /* The user can block the reset (which is handy if you initialise the
4074 * MSP audio in another operating system first (eg in Windows)
4076 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4078 #ifndef BKTR_NO_MSP_RESET
4079 /* put into reset mode */
4081 i2c_write_byte(bktr, i2c_addr);
4082 i2c_write_byte(bktr, 0x00);
4083 i2c_write_byte(bktr, 0x80);
4084 i2c_write_byte(bktr, 0x00);
4087 /* put back to operational mode */
4089 i2c_write_byte(bktr, i2c_addr);
4090 i2c_write_byte(bktr, 0x00);
4091 i2c_write_byte(bktr, 0x00);
4092 i2c_write_byte(bktr, 0x00);
4099 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4101 /* XXX errors ignored */
4103 i2c_write_byte(bktr,bktr->remote_control_addr);
4104 i2c_read_byte(bktr,&(remote->data[0]), 0);
4105 i2c_read_byte(bktr,&(remote->data[1]), 0);
4106 i2c_read_byte(bktr,&(remote->data[2]), 0);
4112 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4115 #if defined( I2C_SOFTWARE_PROBE )
4118 * we are keeping this around for any parts that we need to probe
4119 * but that CANNOT be probed via an i2c read.
4120 * this is necessary because the hardware i2c mechanism
4121 * cannot be programmed for 1 byte writes.
4122 * currently there are no known i2c parts that we need to probe
4123 * and that cannot be safely read.
4125 static int i2cProbe( bktr_ptr_t bktr, int addr );
4130 * probe for an I2C device at addr.
4133 i2cProbe( bktr_ptr_t bktr, int addr )
4138 #if defined( EXTRA_START )
4139 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4140 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4141 #endif /* EXTRA_START */
4142 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4143 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4146 for ( x = 7; x >= 0; --x ) {
4147 if ( addr & (1<<x) ) {
4148 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4149 DELAY( BITD ); /* assert HI data */
4150 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4151 DELAY( BITD ); /* strobe clock */
4152 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4153 DELAY( BITD ); /* release clock */
4156 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4157 DELAY( BITD ); /* assert LO data */
4158 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4159 DELAY( BITD ); /* strobe clock */
4160 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4161 DELAY( BITD ); /* release clock */
4165 /* look for an ACK */
4166 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4167 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4168 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4169 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4172 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4173 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4174 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4181 #endif /* I2C_SOFTWARE_PROBE */