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, (volatile uint32_t **) &dma_prog,
2719 bktr->y2 - bktr->y, OP_WRITE,
2720 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2723 while(getline(bktr, i)) {
2724 if (bktr->y != bktr->y2 ) {
2725 split(bktr, (volatile uint32_t **) &dma_prog,
2726 bktr->y2 - bktr->y, OP_WRITE,
2727 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2729 if (bktr->yclip != bktr->yclip2 ) {
2730 split(bktr,(volatile uint32_t **) &dma_prog,
2731 bktr->yclip2 - bktr->yclip,
2733 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2739 target_buffer += interlace * pitch;
2745 /* Grab the Even field */
2746 /* Look for the VRO, end of Odd field, marker */
2747 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2748 *dma_prog++ = 0; /* NULL WORD */
2750 /* store the VBI data */
2751 /* look for sync with packed data */
2752 *dma_prog++ = OP_SYNC | BKTR_FM1;
2754 for(i = 0; i < vbilines; i++) {
2755 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2756 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2757 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2760 /* store the video image */
2761 if (i_flag == 1) /*Even Only*/
2762 target_buffer = buffer;
2763 if (i_flag == 3) /*interlaced*/
2764 target_buffer = buffer+pitch;
2767 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2768 /* look for sync with packed data */
2769 *dma_prog++ = OP_SYNC | BKTR_FM1;
2770 *dma_prog++ = 0; /* NULL WORD */
2772 for (i = 0; i < (rows/interlace); i++) {
2773 target = target_buffer;
2774 if ( notclipped(bktr, i, width)) {
2775 split(bktr, (volatile uint32_t **) &dma_prog,
2776 bktr->y2 - bktr->y, OP_WRITE,
2777 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2779 while(getline(bktr, i)) {
2780 if (bktr->y != bktr->y2 ) {
2781 split(bktr, (volatile uint32_t **) &dma_prog,
2782 bktr->y2 - bktr->y, OP_WRITE,
2783 Bpp, (volatile u_char **)(uintptr_t)&target,
2786 if (bktr->yclip != bktr->yclip2 ) {
2787 split(bktr, (volatile uint32_t **) &dma_prog,
2788 bktr->yclip2 - bktr->yclip, OP_SKIP,
2789 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2796 target_buffer += interlace * pitch;
2801 /* Look for end of 'Even Field' */
2802 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2803 *dma_prog++ = 0; /* NULL WORD */
2805 *dma_prog++ = OP_JUMP ;
2806 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2807 *dma_prog++ = 0; /* NULL WORD */
2815 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2818 volatile uint32_t target_buffer, buffer, target,width;
2819 volatile uint32_t pitch;
2820 volatile uint32_t *dma_prog;
2821 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2822 u_int Bpp = pf_int->public.Bpp;
2824 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2825 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2826 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2827 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2829 OUTB(bktr, BKTR_OFORM, 0x00);
2831 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2832 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2833 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2834 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2836 /* disable gamma correction removal */
2837 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2840 OUTB(bktr, BKTR_E_VTC, 0);
2841 OUTB(bktr, BKTR_O_VTC, 0);
2843 OUTB(bktr, BKTR_E_VTC, 1);
2844 OUTB(bktr, BKTR_O_VTC, 1);
2846 bktr->capcontrol = 3 << 2 | 3;
2848 dma_prog = (uint32_t *) bktr->dma_prog;
2850 /* Construct Write */
2852 if (bktr->video.addr) {
2853 target_buffer = (uint32_t) bktr->video.addr;
2854 pitch = bktr->video.width;
2857 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2861 buffer = target_buffer;
2863 /* contruct sync : for video packet format */
2864 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2866 /* sync, mode indicator packed data */
2867 *dma_prog++ = 0; /* NULL WORD */
2869 for (i = 0; i < (rows/interlace); i++) {
2870 target = target_buffer;
2871 if ( notclipped(bktr, i, width)) {
2872 split(bktr, (volatile uint32_t **) &dma_prog,
2873 bktr->y2 - bktr->y, OP_WRITE,
2874 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2877 while(getline(bktr, i)) {
2878 if (bktr->y != bktr->y2 ) {
2879 split(bktr, (volatile uint32_t **) &dma_prog,
2880 bktr->y2 - bktr->y, OP_WRITE,
2881 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2883 if (bktr->yclip != bktr->yclip2 ) {
2884 split(bktr,(volatile uint32_t **) &dma_prog,
2885 bktr->yclip2 - bktr->yclip,
2887 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2893 target_buffer += interlace * pitch;
2900 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2901 *dma_prog++ = 0; /* NULL WORD */
2903 *dma_prog++ = OP_JUMP;
2904 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2909 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2910 *dma_prog++ = 0; /* NULL WORD */
2912 *dma_prog++ = OP_JUMP;
2913 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2918 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2919 *dma_prog++ = 0; /* NULL WORD */
2920 *dma_prog++ = OP_JUMP;
2921 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
2925 if (interlace == 2) {
2927 target_buffer = buffer + pitch;
2929 dma_prog = (uint32_t *) bktr->odd_dma_prog;
2931 /* sync vre IRQ bit */
2932 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2933 *dma_prog++ = 0; /* NULL WORD */
2935 for (i = 0; i < (rows/interlace); i++) {
2936 target = target_buffer;
2937 if ( notclipped(bktr, i, width)) {
2938 split(bktr, (volatile uint32_t **) &dma_prog,
2939 bktr->y2 - bktr->y, OP_WRITE,
2940 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2942 while(getline(bktr, i)) {
2943 if (bktr->y != bktr->y2 ) {
2944 split(bktr, (volatile uint32_t **) &dma_prog,
2945 bktr->y2 - bktr->y, OP_WRITE,
2946 Bpp, (volatile u_char **)(uintptr_t)&target,
2949 if (bktr->yclip != bktr->yclip2 ) {
2950 split(bktr, (volatile uint32_t **) &dma_prog,
2951 bktr->yclip2 - bktr->yclip, OP_SKIP,
2952 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2959 target_buffer += interlace * pitch;
2964 /* sync vre IRQ bit */
2965 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2966 *dma_prog++ = 0; /* NULL WORD */
2967 *dma_prog++ = OP_JUMP ;
2968 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
2969 *dma_prog++ = 0; /* NULL WORD */
2977 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2978 int cols, int rows, int interlace )
2981 volatile unsigned int inst;
2982 volatile unsigned int inst3;
2983 volatile uint32_t target_buffer, buffer;
2984 volatile uint32_t *dma_prog;
2985 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2988 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2990 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
2991 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2993 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
2994 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2996 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
2997 bktr->capcontrol = 3 << 2 | 3;
2999 dma_prog = (uint32_t *) bktr->dma_prog;
3001 /* Construct Write */
3003 /* write , sol, eol */
3004 inst = OP_WRITE | OP_SOL | (cols);
3005 /* write , sol, eol */
3006 inst3 = OP_WRITE | OP_EOL | (cols);
3008 if (bktr->video.addr)
3009 target_buffer = (uint32_t) bktr->video.addr;
3011 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3013 buffer = target_buffer;
3015 /* contruct sync : for video packet format */
3016 /* sync, mode indicator packed data */
3017 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3018 *dma_prog++ = 0; /* NULL WORD */
3022 for (i = 0; i < (rows/interlace); i++) {
3024 *dma_prog++ = target_buffer;
3025 *dma_prog++ = inst3;
3026 *dma_prog++ = target_buffer + b;
3027 target_buffer += interlace*(cols * 2);
3033 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3034 *dma_prog++ = 0; /* NULL WORD */
3036 *dma_prog++ = OP_JUMP;
3037 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3042 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3043 *dma_prog++ = 0; /* NULL WORD */
3044 *dma_prog++ = OP_JUMP;
3045 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3050 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3051 *dma_prog++ = 0; /* NULL WORD */
3052 *dma_prog++ = OP_JUMP ;
3053 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3057 if (interlace == 2) {
3059 target_buffer = (uint32_t) buffer + cols*2;
3061 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3064 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3065 *dma_prog++ = 0; /* NULL WORD */
3067 for (i = 0; i < (rows/interlace) ; i++) {
3069 *dma_prog++ = target_buffer;
3070 *dma_prog++ = inst3;
3071 *dma_prog++ = target_buffer + b;
3072 target_buffer += interlace * ( cols*2);
3076 /* sync vro IRQ bit */
3077 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3078 *dma_prog++ = 0; /* NULL WORD */
3079 *dma_prog++ = OP_JUMP ;
3080 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3082 *dma_prog++ = OP_JUMP;
3083 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3084 *dma_prog++ = 0; /* NULL WORD */
3092 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3093 int cols, int rows, int interlace ){
3096 volatile unsigned int inst;
3097 volatile uint32_t target_buffer, t1, buffer;
3098 volatile uint32_t *dma_prog;
3099 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3101 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3103 dma_prog = (uint32_t*) bktr->dma_prog;
3105 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3107 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3108 OUTB(bktr, BKTR_OFORM, 0x00);
3110 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3111 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3113 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3114 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3116 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3117 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3118 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3119 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3121 /* disable gamma correction removal */
3122 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3124 /* Construct Write */
3125 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3126 if (bktr->video.addr)
3127 target_buffer = (uint32_t) bktr->video.addr;
3129 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3131 buffer = target_buffer;
3135 /* contruct sync : for video packet format */
3136 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3137 *dma_prog++ = 0; /* NULL WORD */
3139 for (i = 0; i < (rows/interlace ) ; i++) {
3141 *dma_prog++ = cols/2 | cols/2 << 16;
3142 *dma_prog++ = target_buffer;
3143 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3144 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3145 target_buffer += interlace*cols;
3150 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3151 *dma_prog++ = 0; /* NULL WORD */
3153 *dma_prog++ = OP_JUMP ;
3154 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3158 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3159 *dma_prog++ = 0; /* NULL WORD */
3161 *dma_prog++ = OP_JUMP;
3162 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3166 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3167 *dma_prog++ = 0; /* NULL WORD */
3169 *dma_prog++ = OP_JUMP ;
3170 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3174 if (interlace == 2) {
3176 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3178 target_buffer = (uint32_t) buffer + cols;
3179 t1 = buffer + cols/2;
3180 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3181 *dma_prog++ = 0; /* NULL WORD */
3183 for (i = 0; i < (rows/interlace ) ; i++) {
3185 *dma_prog++ = cols/2 | cols/2 << 16;
3186 *dma_prog++ = target_buffer;
3187 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3188 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3189 target_buffer += interlace*cols;
3193 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3194 *dma_prog++ = 0; /* NULL WORD */
3195 *dma_prog++ = OP_JUMP ;
3196 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3197 *dma_prog++ = 0; /* NULL WORD */
3205 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3206 int cols, int rows, int interlace ){
3209 volatile unsigned int inst;
3210 volatile unsigned int inst1;
3211 volatile uint32_t target_buffer, t1, buffer;
3212 volatile uint32_t *dma_prog;
3213 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3215 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3217 dma_prog = (uint32_t *) bktr->dma_prog;
3219 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3221 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3222 OUTB(bktr, BKTR_OFORM, 0x0);
3224 /* Construct Write */
3225 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3226 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3227 if (bktr->video.addr)
3228 target_buffer = (uint32_t) bktr->video.addr;
3230 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3232 buffer = target_buffer;
3235 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3236 *dma_prog++ = 0; /* NULL WORD */
3238 for (i = 0; i < (rows/interlace )/2 ; i++) {
3240 *dma_prog++ = cols/2 | (cols/2 << 16);
3241 *dma_prog++ = target_buffer;
3242 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3243 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3244 target_buffer += interlace*cols;
3245 *dma_prog++ = inst1;
3246 *dma_prog++ = cols/2 | (cols/2 << 16);
3247 *dma_prog++ = target_buffer;
3248 target_buffer += interlace*cols;
3254 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3255 *dma_prog++ = 0; /* NULL WORD */
3257 *dma_prog++ = OP_JUMP;
3258 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3262 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3263 *dma_prog++ = 0; /* NULL WORD */
3265 *dma_prog++ = OP_JUMP;
3266 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3270 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3271 *dma_prog++ = 0; /* NULL WORD */
3272 *dma_prog++ = OP_JUMP ;
3273 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3277 if (interlace == 2) {
3279 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3281 target_buffer = (uint32_t) buffer + cols;
3282 t1 = buffer + cols/2;
3283 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3284 *dma_prog++ = 0; /* NULL WORD */
3286 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3288 *dma_prog++ = cols/2 | (cols/2 << 16);
3289 *dma_prog++ = target_buffer;
3290 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3291 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3292 target_buffer += interlace*cols;
3293 *dma_prog++ = inst1;
3294 *dma_prog++ = cols/2 | (cols/2 << 16);
3295 *dma_prog++ = target_buffer;
3296 target_buffer += interlace*cols;
3303 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3304 *dma_prog++ = 0; /* NULL WORD */
3305 *dma_prog++ = OP_JUMP;
3306 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3307 *dma_prog++ = 0; /* NULL WORD */
3316 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3318 int rows, cols, interlace;
3321 struct format_params *fp;
3322 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3325 fp = &format_params[bktr->format_params];
3327 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3329 /* disable FIFO & RISC, leave other bits alone */
3330 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3332 /* set video parameters */
3333 if (bktr->capture_area_enabled)
3334 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3335 / fp->scaled_htotal / bktr->cols) - 4096;
3337 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3338 / fp->scaled_htotal / bktr->cols) - 4096;
3340 /* kprintf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3341 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3342 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3343 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3344 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3346 /* horizontal active */
3348 /* kprintf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3349 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3350 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3351 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3352 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3353 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3354 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3356 /* horizontal delay */
3357 if (bktr->capture_area_enabled)
3358 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3359 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3361 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3363 temp = temp & 0x3fe;
3365 /* kprintf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3366 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3367 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3368 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3369 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3370 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3371 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3373 /* vertical scale */
3375 if (bktr->capture_area_enabled) {
3376 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3377 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3379 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3382 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3385 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3386 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3388 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3391 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3396 /* kprintf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3397 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3398 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3399 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3400 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3401 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3402 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3405 /* vertical active */
3406 if (bktr->capture_area_enabled)
3407 temp = bktr->capture_area_y_size;
3410 /* kprintf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3411 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3412 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3413 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3414 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3415 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3416 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3418 /* vertical delay */
3419 if (bktr->capture_area_enabled)
3420 temp = fp->vdelay + (bktr->capture_area_y_offset);
3423 /* kprintf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3424 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3425 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3426 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3427 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3428 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3429 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3431 /* end of video params */
3433 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3434 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3435 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3437 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3440 /* capture control */
3443 bktr->bktr_cap_ctl =
3444 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3445 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3446 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3450 bktr->bktr_cap_ctl =
3451 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3452 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3453 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3457 bktr->bktr_cap_ctl =
3458 (BT848_CAP_CTL_DITH_FRAME |
3459 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3460 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3461 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3466 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3471 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3473 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3474 /* user, then use the rgb_vbi RISC program. */
3475 /* Otherwise, use the normal rgb RISC program */
3476 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3477 if ( (bktr->vbiflags & VBI_OPEN)
3478 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3479 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3481 bktr->bktr_cap_ctl |=
3482 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3483 bktr->vbiflags |= VBI_CAPTURE;
3484 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3487 rgb_prog(bktr, i_flag, cols, rows, interlace);
3492 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3493 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3494 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3495 | pixfmt_swap_flags( bktr->pixfmt ));
3499 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3500 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3501 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3502 | pixfmt_swap_flags( bktr->pixfmt ));
3506 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3507 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3508 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3509 | pixfmt_swap_flags( bktr->pixfmt ));
3516 /******************************************************************************
3517 * video & video capture specific routines:
3525 start_capture( bktr_ptr_t bktr, unsigned type )
3528 struct format_params *fp;
3530 fp = &format_params[bktr->format_params];
3532 /* If requested, clear out capture buf first */
3533 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3534 bzero((caddr_t)bktr->bigbuf,
3535 (size_t)bktr->rows * bktr->cols * bktr->frames *
3536 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3539 OUTB(bktr, BKTR_DSTATUS, 0);
3540 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3542 bktr->flags |= type;
3543 bktr->flags &= ~METEOR_WANT_MASK;
3544 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3545 case METEOR_ONLY_EVEN_FIELDS:
3546 bktr->flags |= METEOR_WANT_EVEN;
3549 case METEOR_ONLY_ODD_FIELDS:
3550 bktr->flags |= METEOR_WANT_ODD;
3554 bktr->flags |= METEOR_WANT_MASK;
3559 /* TDEC is only valid for continuous captures */
3560 if ( type == METEOR_SINGLE ) {
3561 u_short fps_save = bktr->fps;
3563 set_fps(bktr, fp->frame_rate);
3564 bktr->fps = fps_save;
3567 set_fps(bktr, bktr->fps);
3569 if (bktr->dma_prog_loaded == FALSE) {
3570 build_dma_prog(bktr, i_flag);
3571 bktr->dma_prog_loaded = TRUE;
3575 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3584 set_fps( bktr_ptr_t bktr, u_short fps )
3586 struct format_params *fp;
3589 fp = &format_params[bktr->format_params];
3591 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3592 case METEOR_ONLY_EVEN_FIELDS:
3593 bktr->flags |= METEOR_WANT_EVEN;
3596 case METEOR_ONLY_ODD_FIELDS:
3597 bktr->flags |= METEOR_WANT_ODD;
3601 bktr->flags |= METEOR_WANT_MASK;
3606 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3607 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3610 OUTB(bktr, BKTR_TDEC, 0);
3612 if (fps < fp->frame_rate)
3613 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3615 OUTB(bktr, BKTR_TDEC, 0);
3625 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3626 * achieve the specified swapping.
3627 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3628 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3630 * Note also that for 3Bpp, we may additionally need to do some creative
3631 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3632 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3633 * as one would expect.
3636 static u_int pixfmt_swap_flags( int pixfmt )
3638 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3641 switch ( pf->Bpp ) {
3642 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3645 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3648 case 4 : if ( pf->swap_bytes )
3649 swapf = pf->swap_shorts ? 0 : WSWAP;
3651 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3660 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3661 * our pixfmt_table indices.
3664 static int oformat_meteor_to_bt( u_long format )
3667 struct meteor_pixfmt *pf1, *pf2;
3669 /* Find format in compatibility table */
3670 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3671 if ( meteor_pixfmt_table[i].meteor_format == format )
3674 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3676 pf1 = &meteor_pixfmt_table[i].public;
3678 /* Match it with an entry in master pixel format table */
3679 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3680 pf2 = &pixfmt_table[i].public;
3682 if (( pf1->type == pf2->type ) &&
3683 ( pf1->Bpp == pf2->Bpp ) &&
3684 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3685 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3686 ( pf1->swap_shorts == pf2->swap_shorts ))
3689 if ( i >= PIXFMT_TABLE_SIZE )
3695 /******************************************************************************
3700 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3701 #define I2CBITTIME_878 (1 << 7)
3702 #define I2C_READ 0x01
3703 #define I2C_COMMAND (I2CBITTIME | \
3704 BT848_DATA_CTL_I2CSCL | \
3705 BT848_DATA_CTL_I2CSDA)
3707 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3708 BT848_DATA_CTL_I2CSCL | \
3709 BT848_DATA_CTL_I2CSDA)
3711 /* Select between old i2c code and new iicbus / smbus code */
3712 #if defined(BKTR_USE_FREEBSD_SMBUS)
3715 * The hardware interface is actually SMB commands
3718 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3722 if (bktr->id == BROOKTREE_848 ||
3723 bktr->id == BROOKTREE_848A ||
3724 bktr->id == BROOKTREE_849A)
3727 cmd = I2C_COMMAND_878;
3730 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3731 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3734 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3735 (char)(byte1 & 0xff)))
3744 i2cRead( bktr_ptr_t bktr, int addr )
3749 if (bktr->id == BROOKTREE_848 ||
3750 bktr->id == BROOKTREE_848A ||
3751 bktr->id == BROOKTREE_849A)
3754 cmd = I2C_COMMAND_878;
3756 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3759 return ((int)((unsigned char)result));
3762 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3764 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3765 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3766 /* Therefore we need low level control of the i2c bus hardware */
3768 /* Write to the MSP or DPL registers */
3770 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3772 unsigned char addr_l, addr_h, data_h, data_l ;
3774 addr_h = (addr >>8) & 0xff;
3775 addr_l = addr & 0xff;
3776 data_h = (data >>8) & 0xff;
3777 data_l = data & 0xff;
3779 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3781 iicbus_write_byte(IICBUS(bktr), dev, 0);
3782 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3783 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3784 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3785 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3787 iicbus_stop(IICBUS(bktr));
3792 /* Read from the MSP or DPL registers */
3794 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3797 unsigned char addr_l, addr_h, dev_r;
3799 u_char data_read[2];
3801 addr_h = (addr >>8) & 0xff;
3802 addr_l = addr & 0xff;
3805 /* XXX errors ignored */
3806 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3808 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3809 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3810 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3812 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3813 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3814 iicbus_stop(IICBUS(bktr));
3816 data = (data_read[0]<<8) | data_read[1];
3821 /* Reset the MSP or DPL chip */
3822 /* The user can block the reset (which is handy if you initialise the
3823 * MSP and/or DPL audio in another operating system first (eg in Windows)
3826 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3829 #ifndef BKTR_NO_MSP_RESET
3830 /* put into reset mode */
3831 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3832 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3833 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3834 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3835 iicbus_stop(IICBUS(bktr));
3837 /* put back to operational mode */
3838 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3839 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3840 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3841 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3842 iicbus_stop(IICBUS(bktr));
3847 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3850 /* XXX errors ignored */
3851 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3852 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3853 iicbus_stop(IICBUS(bktr));
3858 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3861 * Program the i2c bus directly
3864 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3869 /* clear status bits */
3870 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3872 /* build the command datum */
3873 if (bktr->id == BROOKTREE_848 ||
3874 bktr->id == BROOKTREE_848A ||
3875 bktr->id == BROOKTREE_849A) {
3876 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3878 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3880 if ( byte2 != -1 ) {
3881 data |= ((byte2 & 0xff) << 8);
3882 data |= BT848_DATA_CTL_I2CW3B;
3885 /* write the address and data */
3886 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3888 /* wait for completion */
3889 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3890 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3895 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3907 i2cRead( bktr_ptr_t bktr, int addr )
3911 /* clear status bits */
3912 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3914 /* write the READ address */
3915 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3917 if (bktr->id == BROOKTREE_848 ||
3918 bktr->id == BROOKTREE_848A ||
3919 bktr->id == BROOKTREE_849A) {
3920 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3922 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3925 /* wait for completion */
3926 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3927 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3932 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3936 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3939 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3940 /* bt848 automated i2c bus controller cannot handle */
3941 /* Therefore we need low level control of the i2c bus hardware */
3942 /* Idea for the following functions are from elsewhere in this driver and */
3943 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3946 static void i2c_start( bktr_ptr_t bktr) {
3947 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3948 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3949 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3950 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3953 static void i2c_stop( bktr_ptr_t bktr) {
3954 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3955 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3956 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3959 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3963 /* write out the byte */
3964 for ( x = 7; x >= 0; --x ) {
3965 if ( data & (1<<x) ) {
3966 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3967 DELAY( BITD ); /* assert HI data */
3968 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3969 DELAY( BITD ); /* strobe clock */
3970 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3971 DELAY( BITD ); /* release clock */
3974 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3975 DELAY( BITD ); /* assert LO data */
3976 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3977 DELAY( BITD ); /* strobe clock */
3978 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3979 DELAY( BITD ); /* release clock */
3983 /* look for an ACK */
3984 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3985 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3986 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3987 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3992 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3997 /* read in the byte */
3998 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3999 DELAY( BITD ); /* float data */
4000 for ( x = 7; x >= 0; --x ) {
4001 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4002 DELAY( BITD ); /* strobe clock */
4003 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4004 if ( bit ) byte |= (1<<x);
4005 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4006 DELAY( BITD ); /* release clock */
4008 /* After reading the byte, send an ACK */
4009 /* (unless that was the last byte, for which we send a NAK */
4010 if (last) { /* send NAK - same a writing a 1 */
4011 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4012 DELAY( BITD ); /* set data bit */
4013 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4014 DELAY( BITD ); /* strobe clock */
4015 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4016 DELAY( BITD ); /* release clock */
4017 } else { /* send ACK - same as writing a 0 */
4018 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4019 DELAY( BITD ); /* set data bit */
4020 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4021 DELAY( BITD ); /* strobe clock */
4022 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4023 DELAY( BITD ); /* release clock */
4031 /* Write to the MSP or DPL registers */
4032 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4034 unsigned int msp_w_addr = i2c_addr;
4035 unsigned char addr_l, addr_h, data_h, data_l ;
4036 addr_h = (addr >>8) & 0xff;
4037 addr_l = addr & 0xff;
4038 data_h = (data >>8) & 0xff;
4039 data_l = data & 0xff;
4042 i2c_write_byte(bktr, msp_w_addr);
4043 i2c_write_byte(bktr, dev);
4044 i2c_write_byte(bktr, addr_h);
4045 i2c_write_byte(bktr, addr_l);
4046 i2c_write_byte(bktr, data_h);
4047 i2c_write_byte(bktr, data_l);
4051 /* Read from the MSP or DPL registers */
4052 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4054 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4055 addr_h = (addr >>8) & 0xff;
4056 addr_l = addr & 0xff;
4060 i2c_write_byte(bktr,i2c_addr);
4061 i2c_write_byte(bktr,dev_r);
4062 i2c_write_byte(bktr,addr_h);
4063 i2c_write_byte(bktr,addr_l);
4066 i2c_write_byte(bktr,i2c_addr+1);
4067 i2c_read_byte(bktr,&data_1, 0);
4068 i2c_read_byte(bktr,&data_2, 1);
4070 data = (data_1<<8) | data_2;
4074 /* Reset the MSP or DPL chip */
4075 /* The user can block the reset (which is handy if you initialise the
4076 * MSP audio in another operating system first (eg in Windows)
4078 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4080 #ifndef BKTR_NO_MSP_RESET
4081 /* put into reset mode */
4083 i2c_write_byte(bktr, i2c_addr);
4084 i2c_write_byte(bktr, 0x00);
4085 i2c_write_byte(bktr, 0x80);
4086 i2c_write_byte(bktr, 0x00);
4089 /* put back to operational mode */
4091 i2c_write_byte(bktr, i2c_addr);
4092 i2c_write_byte(bktr, 0x00);
4093 i2c_write_byte(bktr, 0x00);
4094 i2c_write_byte(bktr, 0x00);
4101 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4103 /* XXX errors ignored */
4105 i2c_write_byte(bktr,bktr->remote_control_addr);
4106 i2c_read_byte(bktr,&(remote->data[0]), 0);
4107 i2c_read_byte(bktr,&(remote->data[1]), 0);
4108 i2c_read_byte(bktr,&(remote->data[2]), 0);
4114 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4117 #if defined( I2C_SOFTWARE_PROBE )
4120 * we are keeping this around for any parts that we need to probe
4121 * but that CANNOT be probed via an i2c read.
4122 * this is necessary because the hardware i2c mechanism
4123 * cannot be programmed for 1 byte writes.
4124 * currently there are no known i2c parts that we need to probe
4125 * and that cannot be safely read.
4127 static int i2cProbe( bktr_ptr_t bktr, int addr );
4132 * probe for an I2C device at addr.
4135 i2cProbe( bktr_ptr_t bktr, int addr )
4140 #if defined( EXTRA_START )
4141 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4142 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4143 #endif /* EXTRA_START */
4144 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4145 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4148 for ( x = 7; x >= 0; --x ) {
4149 if ( addr & (1<<x) ) {
4150 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4151 DELAY( BITD ); /* assert HI data */
4152 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4153 DELAY( BITD ); /* strobe clock */
4154 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4155 DELAY( BITD ); /* release clock */
4158 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4159 DELAY( BITD ); /* assert LO data */
4160 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4161 DELAY( BITD ); /* strobe clock */
4162 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4163 DELAY( BITD ); /* release clock */
4167 /* look for an ACK */
4168 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4169 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4170 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4171 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4174 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4175 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4176 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4183 #endif /* I2C_SOFTWARE_PROBE */