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.138 2005/01/09 17:42:03 cognet Exp
65 * $DragonFly: src/sys/dev/video/bktr/bktr_core.c,v 1.18 2006/09/10 01:26:37 dillon Exp $
69 * This is part of the Driver for Video Capture Cards (Frame grabbers)
70 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
72 * Copyright Roger Hardiman and Amancio Hasty.
74 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
75 * Handles all the open, close, ioctl and read userland calls.
76 * Sets the Bt848 registers and generates RISC pograms.
77 * Controls the i2c bus and GPIO interface.
78 * Contains the interface to the kernel.
79 * (eg probe/attach and open/close/ioctl)
83 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
84 Jim Lowe's driver for the Matrox Meteor PCI card . The
85 Philips SAA 7116 and SAA 7196 are very different chipsets than
88 The original copyright notice by Mark and Jim is included mostly
89 to honor their fantastic work in the Matrox Meteor driver!
92 #include "opt_bktr.h" /* Include any kernel config options */
94 #include <sys/param.h>
95 #include <sys/systm.h>
96 #include <sys/kernel.h>
99 #include <sys/signalvar.h>
100 #include <sys/vnode.h>
103 #include <vm/vm_kern.h>
105 #include <vm/vm_extern.h>
107 #include <sys/bus.h> /* used by smbus and newbus */
110 #define PROC_UNLOCK(p)
111 #include <bus/pci/pcivar.h>
112 #include <bus/pci/pcidevs.h>
114 #include <machine/bus_memio.h> /* for bus space */
115 #include <machine/bus.h>
117 #include <sys/thread2.h>
119 #include <dev/video/meteor/ioctl_meteor.h>
120 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
121 #include <dev/video/bktr/bktr_reg.h>
122 #include <dev/video/bktr/bktr_tuner.h>
123 #include <dev/video/bktr/bktr_card.h>
124 #include <dev/video/bktr/bktr_audio.h>
125 #include <dev/video/bktr/bktr_os.h>
126 #include <dev/video/bktr/bktr_core.h>
127 #if defined(BKTR_FREEBSD_MODULE)
128 #include <dev/video/bktr/bktr_mem.h>
131 #if defined(BKTR_USE_FREEBSD_SMBUS)
132 #include <dev/video/bktr/bktr_i2c.h>
133 #include <bus/smbus/smbconf.h>
134 #include <bus/iicbus/iiconf.h>
135 #include "smbus_if.h"
136 #include "iicbus_if.h"
140 bktr_name(bktr_ptr_t bktr)
142 return bktr->bktr_xname;
145 typedef u_char bool_t;
147 #define BKTRPRI PCATCH
148 #define VBIPRI PCATCH
152 * memory allocated for DMA programs
154 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
156 /* When to split a dma transfer , the bt848 has timing as well as
157 dma transfer size limitations so that we have to split dma
158 transfers into two dma requests
160 #define DMA_BT848_SPLIT 319*2
163 * Allocate enough memory for:
164 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
166 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
167 * in your kernel configuration file.
170 #ifndef BROOKTREE_ALLOC_PAGES
171 #define BROOKTREE_ALLOC_PAGES 217*4
173 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
175 /* Definitions for VBI capture.
176 * There are 16 VBI lines in a PAL video field (32 in a frame),
177 * and we take 2044 samples from each line (placed in a 2048 byte buffer
179 * VBI lines are held in a circular buffer before being read by a
180 * user program from /dev/vbi.
183 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
184 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
185 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
186 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
187 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
190 /* Defines for fields */
196 * Parameters describing size of transmitted image.
199 static struct format_params format_params[] = {
200 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
201 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
203 /* # define BT848_IFORM_F_NTSCM (0x1) */
204 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
206 /* # define BT848_IFORM_F_NTSCJ (0x2) */
207 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
209 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
210 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
212 /* # define BT848_IFORM_F_PALM (0x4) */
213 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
215 /* # define BT848_IFORM_F_PALN (0x5) */
216 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
218 /* # define BT848_IFORM_F_SECAM (0x6) */
219 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
221 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
222 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
227 * Table of supported Pixel Formats
230 static struct meteor_pixfmt_internal {
231 struct meteor_pixfmt public;
235 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
236 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
238 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
239 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
241 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
243 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
244 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
245 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
246 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
247 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
248 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
249 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
252 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
255 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
258 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
260 u_long meteor_format;
261 struct meteor_pixfmt public;
262 } meteor_pixfmt_table[] = {
264 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
267 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
268 { METEOR_GEO_YUV_422,
269 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
271 { METEOR_GEO_YUV_PACKED,
272 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
275 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
278 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
282 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
283 sizeof(meteor_pixfmt_table[0]) )
286 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
287 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
291 /* sync detect threshold */
293 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
294 BT848_ADC_CRUSH) /* threshold ~125 mV */
296 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
297 BT848_ADC_SYNC_T) /* threshold ~75 mV */
303 /* debug utility for holding previous INT_STAT contents */
305 static u_long status_sum = 0;
308 * defines to make certain bit-fiddles understandable
310 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
311 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
312 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
313 #define FIFO_RISC_DISABLED 0
315 #define ALL_INTS_DISABLED 0
316 #define ALL_INTS_CLEARED 0xffffffff
317 #define CAPTURE_OFF 0
319 #define BIT_SEVEN_HIGH (1<<7)
320 #define BIT_EIGHT_HIGH (1<<8)
322 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
323 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
327 static int oformat_meteor_to_bt( u_long format );
329 static u_int pixfmt_swap_flags( int pixfmt );
332 * bt848 RISC programming routines.
335 static int dump_bt848( bktr_ptr_t bktr );
338 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
339 int rows, int interlace );
340 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
341 int rows, int interlace );
342 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
343 int rows, int interlace );
344 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
345 int rows, int interlace );
346 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
347 int rows, int interlace );
348 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
350 static bool_t getline(bktr_reg_t *, int);
351 static bool_t notclipped(bktr_reg_t * , int , int);
352 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
353 volatile u_char ** , int );
355 static void start_capture( bktr_ptr_t bktr, unsigned type );
356 static void set_fps( bktr_ptr_t bktr, u_short fps );
361 * Remote Control Functions
363 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
367 * ioctls common to both video & tuner.
369 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
372 #if !defined(BKTR_USE_FREEBSD_SMBUS)
374 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
376 static void i2c_start( bktr_ptr_t bktr);
377 static void i2c_stop( bktr_ptr_t bktr);
378 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
379 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
385 * the common attach code, used by all OS versions.
388 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
391 int need_to_allocate_memory = 1;
392 #ifdef BKTR_NEW_MSP34XX_DRIVER
396 /* If this is a module, check if there is any currently saved contiguous memory */
397 #if defined(BKTR_FREEBSD_MODULE)
398 if (bktr_has_stored_addresses(unit) == 1) {
399 /* recover the addresses */
400 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
401 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
402 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
403 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
404 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
405 need_to_allocate_memory = 0;
409 if (need_to_allocate_memory == 1) {
410 /* allocate space for dma program */
411 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
412 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
414 /* allocte space for the VBI buffer */
415 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
416 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
418 /* allocate space for pixel buffer */
419 if ( BROOKTREE_ALLOC )
420 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
426 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
429 /* If this is a module, save the current contiguous memory */
430 #if defined(BKTR_FREEBSD_MODULE)
431 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
432 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
433 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
434 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
435 bktr_store_address(unit, BKTR_MEM_BUF, buf);
440 printf("%s: buffer size %d, addr %p\n",
441 bktr_name(bktr), BROOKTREE_ALLOC,
442 (void *)(uintptr_t)vtophys(buf));
447 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
448 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
450 bktr->alloc_pages = 0;
454 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
455 METEOR_DEV0 | METEOR_RGB16;
456 bktr->dma_prog_loaded = FALSE;
459 bktr->frames = 1; /* one frame */
460 bktr->format = METEOR_GEO_RGB16;
461 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
462 bktr->pixfmt_compat = TRUE;
471 /* using the pci device id and revision id */
472 /* and determine the card type */
473 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
475 switch (PCI_PRODUCT(pci_id)) {
476 case PCI_PRODUCT_BROOKTREE_BT848:
478 bktr->id = BROOKTREE_848A;
480 bktr->id = BROOKTREE_848;
482 case PCI_PRODUCT_BROOKTREE_BT849:
483 bktr->id = BROOKTREE_849A;
485 case PCI_PRODUCT_BROOKTREE_BT878:
486 bktr->id = BROOKTREE_878;
488 case PCI_PRODUCT_BROOKTREE_BT879:
489 bktr->id = BROOKTREE_879;
494 bktr->clr_on_start = FALSE;
496 /* defaults for the tuner section of the card */
497 bktr->tflags = TUNER_INITALIZED;
498 bktr->tuner.frequency = 0;
499 bktr->tuner.channel = 0;
500 bktr->tuner.chnlset = DEFAULT_CHNLSET;
502 bktr->tuner.radio_mode = 0;
503 bktr->audio_mux_select = 0;
504 bktr->audio_mute_state = FALSE;
505 bktr->bt848_card = -1;
506 bktr->bt848_tuner = -1;
507 bktr->reverse_mute = -1;
508 bktr->slow_msp_audio = 0;
509 bktr->msp_use_mono_source = 0;
510 bktr->msp_source_selected = -1;
511 bktr->audio_mux_present = 1;
513 #ifdef BKTR_NEW_MSP34XX_DRIVER
514 /* get hint on short programming of the msp34xx, so we know */
515 /* if the decision what thread to start should be overwritten */
516 if ( (err = resource_int_value("bktr", unit, "mspsimple",
517 &(bktr->mspsimple)) ) != 0 )
518 bktr->mspsimple = -1; /* fall back to default */
521 probeCard( bktr, TRUE, unit );
523 /* Initialise any MSP34xx or TDA98xx audio chips */
524 init_audio_devices( bktr );
526 #ifdef BKTR_NEW_MSP34XX_DRIVER
527 /* setup the kenrel thread */
528 err = msp_attach( bktr );
529 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
530 bktr->card.msp3400c = 0;
537 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
538 * The circular buffer holds 'n' fixed size data blocks.
539 * vbisize is the number of bytes in the circular buffer
540 * vbiread is the point we reading data out of the circular buffer
541 * vbiinsert is the point we insert data into the circular buffer
543 static void vbidecode(bktr_ptr_t bktr) {
545 unsigned int *seq_dest;
547 /* Check if there is room in the buffer to insert the data. */
548 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
550 /* Copy the VBI data into the next free slot in the buffer. */
551 /* 'dest' is the point in vbibuffer where we want to insert new data */
552 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
553 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
555 /* Write the VBI sequence number to the end of the vbi data */
556 /* This is used by the AleVT teletext program */
557 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
559 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
560 *seq_dest = bktr->vbi_sequence_number;
562 /* And increase the VBI sequence number */
563 /* This can wrap around */
564 bktr->vbi_sequence_number++;
567 /* Increment the vbiinsert pointer */
568 /* This can wrap around */
569 bktr->vbiinsert += VBI_DATA_SIZE;
570 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
572 /* And increase the amount of vbi data in the buffer */
573 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
579 * the common interrupt handler.
580 * Returns a 0 or 1 depending on whether the interrupt has handled.
581 * In the OS specific section, bktr_intr() is defined which calls this
582 * common interrupt handler.
585 common_bktr_intr( void *arg )
594 bktr = (bktr_ptr_t) arg;
597 * check to see if any interrupts are unmasked on this device. If
598 * none are, then we likely got here by way of being on a PCI shared
599 * interrupt dispatch list.
601 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
602 return 0; /* bail out now, before we do something we
605 if (!(bktr->flags & METEOR_OPEN)) {
606 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
607 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
611 /* record and clear the INTerrupt status bits */
612 bktr_status = INL(bktr, BKTR_INT_STAT);
613 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
615 /* record and clear the device status register */
616 dstatus = INB(bktr, BKTR_DSTATUS);
617 OUTB(bktr, BKTR_DSTATUS, 0x00);
619 #if defined( STATUS_SUM )
620 /* add any new device status or INTerrupt status bits */
621 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
622 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
623 #endif /* STATUS_SUM */
624 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
625 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
629 /* if risc was disabled re-start process again */
630 /* if there was one of the following errors re-start again */
631 if ( !(bktr_status & BT848_INT_RISC_EN) ||
632 ((bktr_status &(/* BT848_INT_FBUS | */
633 /* BT848_INT_FTRGT | */
634 /* BT848_INT_FDSR | */
636 BT848_INT_RIPERR | BT848_INT_PABORT |
637 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
638 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
640 u_short tdec_save = INB(bktr, BKTR_TDEC);
642 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
643 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
645 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
647 /* Reset temporal decimation counter */
648 OUTB(bktr, BKTR_TDEC, 0);
649 OUTB(bktr, BKTR_TDEC, tdec_save);
651 /* Reset to no-fields captured state */
652 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
653 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
654 case METEOR_ONLY_ODD_FIELDS:
655 bktr->flags |= METEOR_WANT_ODD;
657 case METEOR_ONLY_EVEN_FIELDS:
658 bktr->flags |= METEOR_WANT_EVEN;
661 bktr->flags |= METEOR_WANT_MASK;
666 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
667 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
668 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
670 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
675 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
679 /* If this is not a RISC program interrupt, return */
680 if (!(bktr_status & BT848_INT_RISCI))
684 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
685 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
690 * Disable future interrupts if a capture mode is not selected.
691 * This can happen when we are in the process of closing or
692 * changing capture modes, otherwise it shouldn't happen.
694 if (!(bktr->flags & METEOR_CAP_MASK))
695 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
698 /* Determine which field generated this interrupt */
699 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
703 * Process the VBI data if it is being captured. We do this once
704 * both Odd and Even VBI data is captured. Therefore we do this
705 * in the Even field interrupt handler.
708 if ( (bktr->vbiflags & VBI_CAPTURE)
709 &&(bktr->vbiflags & VBI_OPEN)
711 /* Put VBI data into circular buffer */
714 /* If someone is blocked on reading from /dev/vbi, wake them */
715 if (bktr->vbi_read_blocked) {
716 bktr->vbi_read_blocked = FALSE;
720 /* If someone has a select() on /dev/vbi, inform them */
721 if (bktr->vbi_select.si_pid) {
722 selwakeup(&bktr->vbi_select);
730 * Register the completed field
731 * (For dual-field mode, require fields from the same frame)
733 switch ( bktr->flags & METEOR_WANT_MASK ) {
734 case METEOR_WANT_ODD : w_field = ODD_F ; break;
735 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
736 default : w_field = (ODD_F|EVEN_F); break;
738 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
739 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
740 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
741 default : req_field = (ODD_F|EVEN_F);
745 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
746 bktr->flags &= ~METEOR_WANT_EVEN;
747 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
748 ( w_field == ODD_F ))
749 bktr->flags &= ~METEOR_WANT_ODD;
750 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
751 ( w_field == (ODD_F|EVEN_F) ))
752 bktr->flags &= ~METEOR_WANT_ODD;
753 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
754 ( w_field == ODD_F )) {
755 bktr->flags &= ~METEOR_WANT_ODD;
756 bktr->flags |= METEOR_WANT_EVEN;
759 /* We're out of sync. Start over. */
760 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
761 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
762 case METEOR_ONLY_ODD_FIELDS:
763 bktr->flags |= METEOR_WANT_ODD;
765 case METEOR_ONLY_EVEN_FIELDS:
766 bktr->flags |= METEOR_WANT_EVEN;
769 bktr->flags |= METEOR_WANT_MASK;
777 * If we have a complete frame.
779 if (!(bktr->flags & METEOR_WANT_MASK)) {
780 bktr->frames_captured++;
782 * post the completion time.
784 if (bktr->flags & METEOR_WANT_TS) {
787 if ((u_int) bktr->alloc_pages * PAGE_SIZE
788 <= (bktr->frame_size + sizeof(struct timeval))) {
789 ts =(struct timeval *)bktr->bigbuf +
791 /* doesn't work in synch mode except
800 * Wake up the user in single capture mode.
802 if (bktr->flags & METEOR_SINGLE) {
805 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
807 /* disable risc, leave fifo running */
808 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
813 * If the user requested to be notified via signal,
814 * let them know the frame is complete.
817 if (bktr->proc != NULL) {
818 PROC_LOCK(bktr->proc);
819 ksignal( bktr->proc, bktr->signal);
820 PROC_UNLOCK(bktr->proc);
824 * Reset the want flags if in continuous or
825 * synchronous capture mode.
829 * currently we only support 3 capture modes: odd only, even only,
830 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
831 * either even OR odd) could provide 60 (50 for PAL) pictures per
832 * second, but it would require this routine to toggle the desired frame
833 * each time, and one more different DMA program for the Bt848.
834 * As a consequence, this fourth mode is currently unsupported.
837 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
838 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
839 case METEOR_ONLY_ODD_FIELDS:
840 bktr->flags |= METEOR_WANT_ODD;
842 case METEOR_ONLY_EVEN_FIELDS:
843 bktr->flags |= METEOR_WANT_EVEN;
846 bktr->flags |= METEOR_WANT_MASK;
861 extern int bt848_format; /* used to set the default format, PAL or NTSC */
863 video_open( bktr_ptr_t bktr )
865 int frame_rate, video_format=0;
867 if (bktr->flags & METEOR_OPEN) /* device is busy */
870 bktr->flags |= METEOR_OPEN;
876 bktr->clr_on_start = FALSE;
878 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
880 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
882 #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
888 if (bt848_format == 0 )
891 if (bt848_format == 1 )
894 if (video_format == 1 ) {
895 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
896 bktr->format_params = BT848_IFORM_F_NTSCM;
899 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
900 bktr->format_params = BT848_IFORM_F_PALBDGHI;
904 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
906 /* work around for new Hauppauge 878 cards */
907 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
908 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
909 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
911 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
913 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
914 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
915 frame_rate = format_params[bktr->format_params].frame_rate;
917 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
918 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
919 OUTB(bktr, BKTR_TGCTRL, 0);
920 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
921 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
922 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
925 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
927 bktr->max_clip_node = 0;
929 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
931 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
932 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
934 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
935 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
936 OUTB(bktr, BKTR_E_SCLOOP, 0);
937 OUTB(bktr, BKTR_O_SCLOOP, 0);
939 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
940 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
942 bktr->fifo_errors = 0;
943 bktr->dma_errors = 0;
944 bktr->frames_captured = 0;
945 bktr->even_fields_captured = 0;
946 bktr->odd_fields_captured = 0;
948 set_fps(bktr, frame_rate);
949 bktr->video.addr = 0;
950 bktr->video.width = 0;
951 bktr->video.banksize = 0;
952 bktr->video.ramsize = 0;
953 bktr->pixfmt_compat = TRUE;
954 bktr->format = METEOR_GEO_RGB16;
955 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
957 bktr->capture_area_enabled = FALSE;
959 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
960 based motherboards will
961 operate unreliably */
966 vbi_open( bktr_ptr_t bktr )
971 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
976 bktr->vbiflags |= VBI_OPEN;
978 /* reset the VBI circular buffer pointers and clear the buffers */
982 bktr->vbi_sequence_number = 0;
983 bktr->vbi_read_blocked = FALSE;
985 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
986 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
997 tuner_open( bktr_ptr_t bktr )
999 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1002 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1005 bktr->tflags |= TUNER_OPEN;
1006 bktr->tuner.frequency = 0;
1007 bktr->tuner.channel = 0;
1008 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1009 bktr->tuner.afc = 0;
1010 bktr->tuner.radio_mode = 0;
1012 /* enable drivers on the GPIO port that control the MUXes */
1013 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1015 /* unmute the audio stream */
1016 set_audio( bktr, AUDIO_UNMUTE );
1018 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1019 init_audio_devices( bktr );
1031 video_close( bktr_ptr_t bktr )
1033 bktr->flags &= ~(METEOR_OPEN |
1038 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1039 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1041 bktr->dma_prog_loaded = FALSE;
1042 OUTB(bktr, BKTR_TDEC, 0);
1043 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1045 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1046 OUTL(bktr, BKTR_SRESET, 0xf);
1047 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1054 * tuner close handle,
1055 * place holder for tuner specific operations on a close.
1058 tuner_close( bktr_ptr_t bktr )
1060 bktr->tflags &= ~TUNER_OPEN;
1062 /* mute the audio by switching the mux */
1063 set_audio( bktr, AUDIO_MUTE );
1065 /* disable drivers on the GPIO port that control the MUXes */
1066 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1072 vbi_close( bktr_ptr_t bktr )
1077 bktr->vbiflags &= ~VBI_OPEN;
1088 video_read(bktr_ptr_t bktr, int unit, cdev_t dev, struct uio *uio)
1094 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1097 if (bktr->flags & METEOR_CAP_MASK)
1098 return( EIO ); /* already capturing */
1100 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1103 count = bktr->rows * bktr->cols *
1104 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1106 if ((int) uio->uio_iov->iov_len < count)
1109 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1111 /* capture one frame */
1112 start_capture(bktr, METEOR_SINGLE);
1113 /* wait for capture to complete */
1114 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1115 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1116 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1117 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1123 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1124 if (!status) /* successful capture */
1125 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1127 printf ("%s: read: tsleep error %d\n",
1128 bktr_name(bktr), status);
1130 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1136 * Read VBI data from the vbi circular buffer
1137 * The buffer holds vbi data blocks which are the same size
1138 * vbiinsert is the position we will insert the next item into the buffer
1139 * vbistart is the actual position in the buffer we want to read from
1140 * vbisize is the exact number of bytes in the buffer left to read
1143 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1145 int readsize, readsize2, start;
1149 * XXX - vbi_read() should be protected against being re-entered
1150 * while it is unlocked for the uiomove.
1154 while(bktr->vbisize == 0) {
1155 if (ioflag & IO_NDELAY) {
1156 status = EWOULDBLOCK;
1160 bktr->vbi_read_blocked = TRUE;
1162 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1167 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1173 /* Now we have some data to give to the user */
1175 /* We cannot read more bytes than there are in
1176 * the circular buffer
1178 readsize = (int)uio->uio_iov->iov_len;
1180 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1182 /* Check if we can read this number of bytes without having
1183 * to wrap around the circular buffer */
1184 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1185 /* We need to wrap around */
1187 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1188 start = bktr->vbistart;
1190 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1192 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1195 /* We do not need to wrap around */
1196 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1201 /* Update the number of bytes left to read */
1202 bktr->vbisize -= readsize;
1204 /* Update vbistart */
1205 bktr->vbistart += readsize;
1206 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1221 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1223 volatile u_char c_temp;
1225 unsigned int temp_iform;
1227 struct meteor_geomet *geo;
1228 struct meteor_counts *counts;
1229 struct meteor_video *video;
1230 struct bktr_capture_area *cap_area;
1238 case BT848SCLIP: /* set clip region */
1239 bktr->max_clip_node = 0;
1240 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1242 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1243 if (bktr->clip_list[i].y_min == 0 &&
1244 bktr->clip_list[i].y_max == 0)
1247 bktr->max_clip_node = i;
1249 /* make sure that the list contains a valid clip secquence */
1250 /* the clip rectangles should be sorted by x then by y as the
1251 second order sort key */
1253 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1255 /* to disable clipping set y_min and y_max to 0 in the first
1256 clip rectangle . The first clip rectangle is clip_list[0].
1261 if (bktr->max_clip_node == 0 &&
1262 (bktr->clip_list[0].y_min != 0 &&
1263 bktr->clip_list[0].y_max != 0)) {
1267 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1268 if (bktr->clip_list[i].y_min == 0 &&
1269 bktr->clip_list[i].y_max == 0) {
1272 if ( bktr->clip_list[i+1].y_min != 0 &&
1273 bktr->clip_list[i+1].y_max != 0 &&
1274 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1276 bktr->max_clip_node = 0;
1281 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1282 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1283 bktr->clip_list[i].x_min < 0 ||
1284 bktr->clip_list[i].x_max < 0 ||
1285 bktr->clip_list[i].y_min < 0 ||
1286 bktr->clip_list[i].y_max < 0 ) {
1287 bktr->max_clip_node = 0;
1292 bktr->dma_prog_loaded = FALSE;
1296 case METEORSTATUS: /* get Bt848 status */
1297 c_temp = INB(bktr, BKTR_DSTATUS);
1299 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1300 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1301 *(u_short *)arg = temp;
1304 case BT848SFMT: /* set input format */
1305 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1306 temp_iform = INB(bktr, BKTR_IFORM);
1307 temp_iform &= ~BT848_IFORM_FORMAT;
1308 temp_iform &= ~BT848_IFORM_XTSEL;
1309 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1311 case BT848_IFORM_F_AUTO:
1312 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1316 case BT848_IFORM_F_NTSCM:
1317 case BT848_IFORM_F_NTSCJ:
1318 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1320 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1321 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1322 bktr->format_params = temp;
1325 case BT848_IFORM_F_PALBDGHI:
1326 case BT848_IFORM_F_PALN:
1327 case BT848_IFORM_F_SECAM:
1328 case BT848_IFORM_F_RSVD:
1329 case BT848_IFORM_F_PALM:
1330 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1332 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1333 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1334 bktr->format_params = temp;
1338 bktr->dma_prog_loaded = FALSE;
1341 case METEORSFMT: /* set input format */
1342 temp_iform = INB(bktr, BKTR_IFORM);
1343 temp_iform &= ~BT848_IFORM_FORMAT;
1344 temp_iform &= ~BT848_IFORM_XTSEL;
1345 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1346 case 0: /* default */
1347 case METEOR_FMT_NTSC:
1348 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1350 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1351 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1352 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1353 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1354 bktr->format_params = BT848_IFORM_F_NTSCM;
1357 case METEOR_FMT_PAL:
1358 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1360 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1361 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1362 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1363 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1364 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1367 case METEOR_FMT_AUTOMODE:
1368 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1370 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1371 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1377 bktr->dma_prog_loaded = FALSE;
1380 case METEORGFMT: /* get input format */
1381 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1385 case BT848GFMT: /* get input format */
1386 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1389 case METEORSCOUNT: /* (re)set error counts */
1390 counts = (struct meteor_counts *) arg;
1391 bktr->fifo_errors = counts->fifo_errors;
1392 bktr->dma_errors = counts->dma_errors;
1393 bktr->frames_captured = counts->frames_captured;
1394 bktr->even_fields_captured = counts->even_fields_captured;
1395 bktr->odd_fields_captured = counts->odd_fields_captured;
1398 case METEORGCOUNT: /* get error counts */
1399 counts = (struct meteor_counts *) arg;
1400 counts->fifo_errors = bktr->fifo_errors;
1401 counts->dma_errors = bktr->dma_errors;
1402 counts->frames_captured = bktr->frames_captured;
1403 counts->even_fields_captured = bktr->even_fields_captured;
1404 counts->odd_fields_captured = bktr->odd_fields_captured;
1408 video = (struct meteor_video *)arg;
1409 video->addr = bktr->video.addr;
1410 video->width = bktr->video.width;
1411 video->banksize = bktr->video.banksize;
1412 video->ramsize = bktr->video.ramsize;
1416 video = (struct meteor_video *)arg;
1417 bktr->video.addr = video->addr;
1418 bktr->video.width = video->width;
1419 bktr->video.banksize = video->banksize;
1420 bktr->video.ramsize = video->ramsize;
1424 set_fps(bktr, *(u_short *)arg);
1428 *(u_short *)arg = bktr->fps;
1431 case METEORSHUE: /* set hue */
1432 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1435 case METEORGHUE: /* get hue */
1436 *(u_char *)arg = INB(bktr, BKTR_HUE);
1439 case METEORSBRIG: /* set brightness */
1440 char_temp = ( *(u_char *)arg & 0xff) - 128;
1441 OUTB(bktr, BKTR_BRIGHT, char_temp);
1445 case METEORGBRIG: /* get brightness */
1446 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1449 case METEORSCSAT: /* set chroma saturation */
1450 temp = (int)*(u_char *)arg;
1452 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1453 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1454 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1455 & ~(BT848_E_CONTROL_SAT_U_MSB
1456 | BT848_E_CONTROL_SAT_V_MSB));
1457 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1458 & ~(BT848_O_CONTROL_SAT_U_MSB |
1459 BT848_O_CONTROL_SAT_V_MSB));
1461 if ( temp & BIT_SEVEN_HIGH ) {
1462 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1463 | (BT848_E_CONTROL_SAT_U_MSB
1464 | BT848_E_CONTROL_SAT_V_MSB));
1465 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1466 | (BT848_O_CONTROL_SAT_U_MSB
1467 | BT848_O_CONTROL_SAT_V_MSB));
1471 case METEORGCSAT: /* get chroma saturation */
1472 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1473 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1474 temp |= BIT_SEVEN_HIGH;
1475 *(u_char *)arg = (u_char)temp;
1478 case METEORSCONT: /* set contrast */
1479 temp = (int)*(u_char *)arg & 0xff;
1481 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1482 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1483 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1484 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1485 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1486 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1487 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1490 case METEORGCONT: /* get contrast */
1491 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1492 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1493 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1496 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1497 bktr->clr_on_start = (*(int *)arg != 0);
1500 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1501 *(int *)arg = (int) bktr->clr_on_start;
1506 /* Historically, applications used METEOR_SIG_MODE_MASK
1507 * to reset signal delivery.
1509 if (sig == METEOR_SIG_MODE_MASK)
1511 if (sig < 0 || sig > _SIG_MAXSIG)
1514 bktr->proc = sig ? td->td_proc : NULL;
1518 *(int *)arg = bktr->signal;
1523 switch (*(int *) arg) {
1524 case METEOR_CAP_SINGLE:
1526 if (bktr->bigbuf==0) /* no frame buffer allocated */
1528 /* already capturing */
1529 if (temp & METEOR_CAP_MASK)
1534 start_capture(bktr, METEOR_SINGLE);
1536 /* wait for capture to complete */
1537 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1538 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1539 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1541 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1546 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1547 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1548 if (error && (error != ERESTART)) {
1549 /* Here if we didn't get complete frame */
1551 printf( "%s: ioctl: tsleep error %d %x\n",
1552 bktr_name(bktr), error,
1553 INL(bktr, BKTR_RISC_COUNT));
1557 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1559 /* disable risc, leave fifo running */
1560 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1563 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1564 /* FIXME: should we set bt848->int_stat ??? */
1567 case METEOR_CAP_CONTINOUS:
1568 if (bktr->bigbuf==0) /* no frame buffer allocated */
1570 /* already capturing */
1571 if (temp & METEOR_CAP_MASK)
1575 start_capture(bktr, METEOR_CONTIN);
1577 /* Clear the interrypt status register */
1578 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1580 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1581 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1582 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1584 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1589 dump_bt848( bt848 );
1593 case METEOR_CAP_STOP_CONT:
1594 if (bktr->flags & METEOR_CONTIN) {
1595 /* turn off capture */
1596 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1597 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1598 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1600 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1607 /* can't change parameters while capturing */
1608 if (bktr->flags & METEOR_CAP_MASK)
1612 geo = (struct meteor_geomet *) arg;
1615 /* Either even or odd, if even & odd, then these a zero */
1616 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1617 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1618 printf( "%s: ioctl: Geometry odd or even only.\n",
1623 /* set/clear even/odd flags */
1624 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1625 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1627 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1628 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1629 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1631 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1633 if (geo->columns <= 0) {
1635 "%s: ioctl: %d: columns must be greater than zero.\n",
1636 bktr_name(bktr), geo->columns);
1639 else if ((geo->columns & 0x3fe) != geo->columns) {
1641 "%s: ioctl: %d: columns too large or not even.\n",
1642 bktr_name(bktr), geo->columns);
1646 if (geo->rows <= 0) {
1648 "%s: ioctl: %d: rows must be greater than zero.\n",
1649 bktr_name(bktr), geo->rows);
1652 else if (((geo->rows & 0x7fe) != geo->rows) ||
1653 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1654 ((geo->rows & 0x3fe) != geo->rows)) ) {
1656 "%s: ioctl: %d: rows too large or not even.\n",
1657 bktr_name(bktr), geo->rows);
1661 if (geo->frames > 32) {
1662 printf("%s: ioctl: too many frames.\n",
1671 bktr->dma_prog_loaded = FALSE;
1672 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1674 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1676 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1677 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1679 /* meteor_mem structure for SYNC Capture */
1680 if (geo->frames > 1) temp += PAGE_SIZE;
1683 if ((int) temp > bktr->alloc_pages
1684 && bktr->video.addr == 0) {
1686 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1688 kmem_free(kernel_map, bktr->bigbuf,
1689 (bktr->alloc_pages * PAGE_SIZE));
1692 bktr->alloc_pages = temp;
1695 "%s: ioctl: Allocating %d bytes\n",
1696 bktr_name(bktr), temp*PAGE_SIZE);
1706 bktr->rows = geo->rows;
1707 bktr->cols = geo->columns;
1708 bktr->frames = geo->frames;
1710 /* Pixel format (if in meteor pixfmt compatibility mode) */
1711 if ( bktr->pixfmt_compat ) {
1712 bktr->format = METEOR_GEO_YUV_422;
1713 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1714 case 0: /* default */
1715 case METEOR_GEO_RGB16:
1716 bktr->format = METEOR_GEO_RGB16;
1718 case METEOR_GEO_RGB24:
1719 bktr->format = METEOR_GEO_RGB24;
1721 case METEOR_GEO_YUV_422:
1722 bktr->format = METEOR_GEO_YUV_422;
1723 if (geo->oformat & METEOR_GEO_YUV_12)
1724 bktr->format = METEOR_GEO_YUV_12;
1726 case METEOR_GEO_YUV_PACKED:
1727 bktr->format = METEOR_GEO_YUV_PACKED;
1730 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1733 if (bktr->flags & METEOR_CAP_MASK) {
1735 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1736 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1737 case METEOR_ONLY_ODD_FIELDS:
1738 bktr->flags |= METEOR_WANT_ODD;
1740 case METEOR_ONLY_EVEN_FIELDS:
1741 bktr->flags |= METEOR_WANT_EVEN;
1744 bktr->flags |= METEOR_WANT_MASK;
1748 start_capture(bktr, METEOR_CONTIN);
1749 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1750 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1751 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1752 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1758 /* end of METEORSETGEO */
1760 /* FIXME. The Capture Area currently has the following restrictions:
1762 y_offset may need to be even in interlaced modes
1763 RGB24 - Interlaced mode
1764 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1765 y_size must be greater than or equal to METEORSETGEO height (rows)
1766 RGB24 - Even Only (or Odd Only) mode
1767 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1768 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1769 YUV12 - Interlaced mode
1770 x_size must be greater than or equal to METEORSETGEO width (cols)
1771 y_size must be greater than or equal to METEORSETGEO height (rows)
1772 YUV12 - Even Only (or Odd Only) mode
1773 x_size must be greater than or equal to METEORSETGEO width (cols)
1774 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1777 case BT848_SCAPAREA: /* set capture area of each video frame */
1778 /* can't change parameters while capturing */
1779 if (bktr->flags & METEOR_CAP_MASK)
1782 cap_area = (struct bktr_capture_area *) arg;
1783 bktr->capture_area_x_offset = cap_area->x_offset;
1784 bktr->capture_area_y_offset = cap_area->y_offset;
1785 bktr->capture_area_x_size = cap_area->x_size;
1786 bktr->capture_area_y_size = cap_area->y_size;
1787 bktr->capture_area_enabled = TRUE;
1789 bktr->dma_prog_loaded = FALSE;
1792 case BT848_GCAPAREA: /* get capture area of each video frame */
1793 cap_area = (struct bktr_capture_area *) arg;
1794 if (bktr->capture_area_enabled == FALSE) {
1795 cap_area->x_offset = 0;
1796 cap_area->y_offset = 0;
1797 cap_area->x_size = format_params[
1798 bktr->format_params].scaled_hactive;
1799 cap_area->y_size = format_params[
1800 bktr->format_params].vactive;
1802 cap_area->x_offset = bktr->capture_area_x_offset;
1803 cap_area->y_offset = bktr->capture_area_y_offset;
1804 cap_area->x_size = bktr->capture_area_x_size;
1805 cap_area->y_size = bktr->capture_area_y_size;
1810 return common_ioctl( bktr, cmd, arg );
1820 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1823 unsigned int temp, temp1;
1836 /* Read the last key pressed by the Remote Control */
1837 if (bktr->remote_control == 0) return (EINVAL);
1838 remote_read(bktr, (struct bktr_remote *)arg);
1841 #if defined( TUNER_AFC )
1842 case TVTUNER_SETAFC:
1843 bktr->tuner.afc = (*(int *)arg != 0);
1846 case TVTUNER_GETAFC:
1847 *(int *)arg = bktr->tuner.afc;
1848 /* XXX Perhaps use another bit to indicate AFC success? */
1850 #endif /* TUNER_AFC */
1852 case TVTUNER_SETCHNL:
1853 temp_mute( bktr, TRUE );
1854 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1856 temp_mute( bktr, FALSE );
1859 *(unsigned long *)arg = temp;
1861 /* after every channel change, we must restart the MSP34xx */
1862 /* audio chip to reselect NICAM STEREO or MONO audio */
1863 if ( bktr->card.msp3400c )
1864 msp_autodetect( bktr );
1866 /* after every channel change, we must restart the DPL35xx */
1867 if ( bktr->card.dpl3518a )
1868 dpl_autodetect( bktr );
1870 temp_mute( bktr, FALSE );
1873 case TVTUNER_GETCHNL:
1874 *(unsigned long *)arg = bktr->tuner.channel;
1877 case TVTUNER_SETTYPE:
1878 temp = *(unsigned long *)arg;
1879 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1881 bktr->tuner.chnlset = temp;
1884 case TVTUNER_GETTYPE:
1885 *(unsigned long *)arg = bktr->tuner.chnlset;
1888 case TVTUNER_GETSTATUS:
1889 temp = get_tuner_status( bktr );
1890 *(unsigned long *)arg = temp & 0xff;
1893 case TVTUNER_SETFREQ:
1894 temp_mute( bktr, TRUE );
1895 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1896 temp_mute( bktr, FALSE );
1898 temp_mute( bktr, FALSE );
1901 *(unsigned long *)arg = temp;
1903 /* after every channel change, we must restart the MSP34xx */
1904 /* audio chip to reselect NICAM STEREO or MONO audio */
1905 if ( bktr->card.msp3400c )
1906 msp_autodetect( bktr );
1908 /* after every channel change, we must restart the DPL35xx */
1909 if ( bktr->card.dpl3518a )
1910 dpl_autodetect( bktr );
1912 temp_mute( bktr, FALSE );
1915 case TVTUNER_GETFREQ:
1916 *(unsigned long *)arg = bktr->tuner.frequency;
1919 case TVTUNER_GETCHNLSET:
1920 return tuner_getchnlset((struct bktr_chnlset *)arg);
1922 case BT848_SAUDIO: /* set audio channel */
1923 if ( set_audio( bktr, *(int*)arg ) < 0 )
1927 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1928 case BT848_SHUE: /* set hue */
1929 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1932 case BT848_GHUE: /* get hue */
1933 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1936 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1937 case BT848_SBRIG: /* set brightness */
1938 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1941 case BT848_GBRIG: /* get brightness */
1942 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1946 case BT848_SCSAT: /* set chroma saturation */
1947 tmp_int = *(int*)arg;
1949 temp = INB(bktr, BKTR_E_CONTROL);
1950 temp1 = INB(bktr, BKTR_O_CONTROL);
1951 if ( tmp_int & BIT_EIGHT_HIGH ) {
1952 temp |= (BT848_E_CONTROL_SAT_U_MSB |
1953 BT848_E_CONTROL_SAT_V_MSB);
1954 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1955 BT848_O_CONTROL_SAT_V_MSB);
1958 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1959 BT848_E_CONTROL_SAT_V_MSB);
1960 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1961 BT848_O_CONTROL_SAT_V_MSB);
1964 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1965 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1966 OUTB(bktr, BKTR_E_CONTROL, temp);
1967 OUTB(bktr, BKTR_O_CONTROL, temp1);
1970 case BT848_GCSAT: /* get chroma saturation */
1971 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1972 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1973 tmp_int |= BIT_EIGHT_HIGH;
1974 *(int*)arg = tmp_int;
1978 case BT848_SVSAT: /* set chroma V saturation */
1979 tmp_int = *(int*)arg;
1981 temp = INB(bktr, BKTR_E_CONTROL);
1982 temp1 = INB(bktr, BKTR_O_CONTROL);
1983 if ( tmp_int & BIT_EIGHT_HIGH) {
1984 temp |= BT848_E_CONTROL_SAT_V_MSB;
1985 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1988 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1989 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1992 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1993 OUTB(bktr, BKTR_E_CONTROL, temp);
1994 OUTB(bktr, BKTR_O_CONTROL, temp1);
1997 case BT848_GVSAT: /* get chroma V saturation */
1998 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1999 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2000 tmp_int |= BIT_EIGHT_HIGH;
2001 *(int*)arg = tmp_int;
2005 case BT848_SUSAT: /* set chroma U saturation */
2006 tmp_int = *(int*)arg;
2008 temp = INB(bktr, BKTR_E_CONTROL);
2009 temp1 = INB(bktr, BKTR_O_CONTROL);
2010 if ( tmp_int & BIT_EIGHT_HIGH ) {
2011 temp |= BT848_E_CONTROL_SAT_U_MSB;
2012 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2015 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2016 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2019 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2020 OUTB(bktr, BKTR_E_CONTROL, temp);
2021 OUTB(bktr, BKTR_O_CONTROL, temp1);
2024 case BT848_GUSAT: /* get chroma U saturation */
2025 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2026 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2027 tmp_int |= BIT_EIGHT_HIGH;
2028 *(int*)arg = tmp_int;
2031 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2033 case BT848_SLNOTCH: /* set luma notch */
2034 tmp_int = (*(int *)arg & 0x7) << 5 ;
2035 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2036 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2037 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2038 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2041 case BT848_GLNOTCH: /* get luma notch */
2042 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2047 case BT848_SCONT: /* set contrast */
2048 tmp_int = *(int*)arg;
2050 temp = INB(bktr, BKTR_E_CONTROL);
2051 temp1 = INB(bktr, BKTR_O_CONTROL);
2052 if ( tmp_int & BIT_EIGHT_HIGH ) {
2053 temp |= BT848_E_CONTROL_CON_MSB;
2054 temp1 |= BT848_O_CONTROL_CON_MSB;
2057 temp &= ~BT848_E_CONTROL_CON_MSB;
2058 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2061 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2062 OUTB(bktr, BKTR_E_CONTROL, temp);
2063 OUTB(bktr, BKTR_O_CONTROL, temp1);
2066 case BT848_GCONT: /* get contrast */
2067 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2068 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2069 tmp_int |= BIT_EIGHT_HIGH;
2070 *(int*)arg = tmp_int;
2073 /* FIXME: SCBARS and CCBARS require a valid int * */
2074 /* argument to succeed, but its not used; consider */
2075 /* using the arg to store the on/off state so */
2076 /* there's only one ioctl() needed to turn cbars on/off */
2077 case BT848_SCBARS: /* set colorbar output */
2078 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2081 case BT848_CCBARS: /* clear colorbar output */
2082 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2085 case BT848_GAUDIO: /* get audio channel */
2086 temp = bktr->audio_mux_select;
2087 if ( bktr->audio_mute_state == TRUE )
2092 case BT848_SBTSC: /* set audio channel */
2093 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2097 case BT848_WEEPROM: /* write eeprom */
2098 offset = (((struct eeProm *)arg)->offset);
2099 count = (((struct eeProm *)arg)->count);
2100 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2101 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2105 case BT848_REEPROM: /* read eeprom */
2106 offset = (((struct eeProm *)arg)->offset);
2107 count = (((struct eeProm *)arg)->count);
2108 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2109 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2113 case BT848_SIGNATURE:
2114 offset = (((struct eeProm *)arg)->offset);
2115 count = (((struct eeProm *)arg)->count);
2116 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2117 if ( signCard( bktr, offset, count, buf ) < 0 )
2121 /* Ioctl's for direct gpio access */
2122 #ifdef BKTR_GPIO_ACCESS
2123 case BT848_GPIO_GET_EN:
2124 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2127 case BT848_GPIO_SET_EN:
2128 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2131 case BT848_GPIO_GET_DATA:
2132 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2135 case BT848_GPIO_SET_DATA:
2136 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2138 #endif /* BKTR_GPIO_ACCESS */
2140 /* Ioctl's for running the tuner device in radio mode */
2143 *(unsigned char *)arg = bktr->tuner.radio_mode;
2147 bktr->tuner.radio_mode = *(unsigned char *)arg;
2151 *(unsigned long *)arg = bktr->tuner.frequency;
2155 /* The argument to this ioctl is NOT freq*16. It is
2159 temp=(int)*(unsigned long *)arg;
2161 #ifdef BKTR_RADIO_DEBUG
2162 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2163 (int)*(unsigned long *)arg, temp);
2166 #ifndef BKTR_RADIO_NOFREQCHECK
2167 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2169 if(temp<8750 || temp>10800) {
2170 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2174 temp_mute( bktr, TRUE );
2175 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2176 temp_mute( bktr, FALSE );
2177 #ifdef BKTR_RADIO_DEBUG
2179 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2183 *(unsigned long *)arg = temp;
2186 /* Luigi's I2CWR ioctl */
2188 par = *(u_long *)arg;
2189 write = (par >> 24) & 0xff ;
2190 i2c_addr = (par >> 16) & 0xff ;
2191 i2c_port = (par >> 8) & 0xff ;
2192 data = (par) & 0xff ;
2195 i2cWrite( bktr, i2c_addr, i2c_port, data);
2197 data = i2cRead( bktr, i2c_addr);
2199 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2203 #ifdef BT848_MSP_READ
2204 /* I2C ioctls to allow userland access to the MSP chip */
2205 case BT848_MSP_READ:
2207 struct bktr_msp_control *msp;
2208 msp = (struct bktr_msp_control *) arg;
2209 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2210 msp->function, msp->address);
2214 case BT848_MSP_WRITE:
2216 struct bktr_msp_control *msp;
2217 msp = (struct bktr_msp_control *) arg;
2218 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2219 msp->address, msp->data );
2223 case BT848_MSP_RESET:
2224 msp_dpl_reset(bktr, bktr->msp_addr);
2229 return common_ioctl( bktr, cmd, arg );
2240 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2244 struct meteor_pixfmt *pf_pub;
2248 case METEORSINPUT: /* set input device */
2249 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2250 /* On the original bt848 boards, */
2251 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2252 /* On the Hauppauge bt878 boards, */
2253 /* Tuner is MUX0, RCA is MUX3 */
2254 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2255 /* stick with this system in our Meteor Emulation */
2257 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2259 /* this is the RCA video input */
2260 case 0: /* default */
2261 case METEOR_INPUT_DEV0:
2262 /* METEOR_INPUT_DEV_RCA: */
2263 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2265 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2266 & ~BT848_IFORM_MUXSEL);
2268 /* work around for new Hauppauge 878 cards */
2269 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2270 (bktr->id==BROOKTREE_878 ||
2271 bktr->id==BROOKTREE_879) )
2272 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2274 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2276 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2277 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2278 set_audio( bktr, AUDIO_EXTERN );
2281 /* this is the tuner input */
2282 case METEOR_INPUT_DEV1:
2283 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2285 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2286 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2287 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2288 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2289 set_audio( bktr, AUDIO_TUNER );
2292 /* this is the S-VHS input, but with a composite camera */
2293 case METEOR_INPUT_DEV2:
2294 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2296 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2297 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2298 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2299 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2300 set_audio( bktr, AUDIO_EXTERN );
2303 /* this is the S-VHS input */
2304 case METEOR_INPUT_DEV_SVIDEO:
2305 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2306 | METEOR_DEV_SVIDEO;
2307 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2308 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2309 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2310 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2311 set_audio( bktr, AUDIO_EXTERN );
2314 case METEOR_INPUT_DEV3:
2315 if ((bktr->id == BROOKTREE_848A) ||
2316 (bktr->id == BROOKTREE_849A) ||
2317 (bktr->id == BROOKTREE_878) ||
2318 (bktr->id == BROOKTREE_879) ) {
2319 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2321 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2323 /* work around for new Hauppauge 878 cards */
2324 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2325 (bktr->id==BROOKTREE_878 ||
2326 bktr->id==BROOKTREE_879) )
2327 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2329 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2331 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2332 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2333 set_audio( bktr, AUDIO_EXTERN );
2343 case METEORGINPUT: /* get input device */
2344 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2347 case METEORSACTPIXFMT:
2348 if (( *(int *)arg < 0 ) ||
2349 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2352 bktr->pixfmt = *(int *)arg;
2353 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2354 | pixfmt_swap_flags( bktr->pixfmt ));
2355 bktr->pixfmt_compat = FALSE;
2358 case METEORGACTPIXFMT:
2359 *(int *)arg = bktr->pixfmt;
2362 case METEORGSUPPIXFMT :
2363 pf_pub = (struct meteor_pixfmt *)arg;
2364 pixfmt = pf_pub->index;
2366 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2369 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2370 sizeof( *pf_pub ) );
2372 /* Patch in our format index */
2373 pf_pub->index = pixfmt;
2376 #if defined( STATUS_SUM )
2377 case BT848_GSTATUS: /* reap status */
2383 *(u_int*)arg = temp;
2386 #endif /* STATUS_SUM */
2398 /******************************************************************************
2399 * bt848 RISC programming routines:
2408 dump_bt848( bktr_ptr_t bktr )
2411 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2412 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2413 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2414 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2415 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2420 for (i = 0; i < 40; i+=4) {
2421 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2423 r[i], INL(bktr, r[i]),
2424 r[i+1], INL(bktr, r[i+1]),
2425 r[i+2], INL(bktr, r[i+2]),
2426 r[i+3], INL(bktr, r[i+3]]));
2429 printf("%s: INT STAT %x \n", bktr_name(bktr),
2430 INL(bktr, BKTR_INT_STAT));
2431 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2432 INL(bktr, BKTR_INT_MASK));
2433 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2434 INW(bktr, BKTR_GPIO_DMA_CTL));
2442 * build write instruction
2444 #define BKTR_FM1 0x6 /* packed data to follow */
2445 #define BKTR_FM3 0xe /* planar data to follow */
2446 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2447 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2448 #define BKTR_PXV 0x0 /* valid word (never used) */
2449 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2450 #define BKTR_SOL 0x2 /* first dword */
2452 #define OP_WRITE (0x1 << 28)
2453 #define OP_SKIP (0x2 << 28)
2454 #define OP_WRITEC (0x5 << 28)
2455 #define OP_JUMP (0x7 << 28)
2456 #define OP_SYNC (0x8 << 28)
2457 #define OP_WRITE123 (0x9 << 28)
2458 #define OP_WRITES123 (0xb << 28)
2459 #define OP_SOL (1 << 27) /* first instr for scanline */
2460 #define OP_EOL (1 << 26)
2462 #define BKTR_RESYNC (1 << 15)
2463 #define BKTR_GEN_IRQ (1 << 24)
2466 * The RISC status bits can be set/cleared in the RISC programs
2467 * and tested in the Interrupt Handler
2469 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2470 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2471 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2472 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2474 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2475 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2476 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2477 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2479 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2480 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2481 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2482 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2484 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2486 bktr_clip_t * clip_node;
2487 bktr->clip_start = -1;
2491 bktr->line_length = width;
2494 bktr->current_col = 0;
2496 if (bktr->max_clip_node == 0 ) return TRUE;
2497 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2500 for (i = 0; i < bktr->max_clip_node; i++ ) {
2501 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2502 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2503 bktr->clip_start = i;
2511 static bool_t getline(bktr_reg_t *bktr, int x ) {
2513 bktr_clip_t * clip_node ;
2515 if (bktr->line_length == 0 ||
2516 bktr->current_col >= bktr->line_length) return FALSE;
2518 bktr->y = min(bktr->last_y, bktr->line_length);
2519 bktr->y2 = bktr->line_length;
2521 bktr->yclip = bktr->yclip2 = -1;
2522 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2523 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2524 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2525 if (bktr->last_y <= clip_node->y_min) {
2526 bktr->y = min(bktr->last_y, bktr->line_length);
2527 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2528 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2529 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2530 bktr->last_y = bktr->yclip2;
2531 bktr->clip_start = i;
2533 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2534 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2535 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2536 if (bktr->last_y >= clip_node->y_min) {
2537 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2538 bktr->last_y = bktr->yclip2;
2539 bktr->clip_start = j;
2548 if (bktr->current_col <= bktr->line_length) {
2549 bktr->current_col = bktr->line_length;
2555 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2556 u_long operation, int pixel_width,
2557 volatile u_char ** target_buffer, int cols ) {
2560 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2561 u_int skip, start_skip;
2563 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2564 /* to the 1st byte in the mem dword containing our start addr. */
2565 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2568 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2569 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2570 case 2 : start_skip = 4 ; break;
2571 case 1 : start_skip = 8 ; break;
2574 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2575 if ( width == cols) {
2576 flag = OP_SOL | OP_EOL;
2577 } else if (bktr->current_col == 0 ) {
2579 } else if (bktr->current_col == cols) {
2584 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2585 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2590 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2591 if (operation != OP_SKIP )
2592 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2594 *target_buffer += width * pixel_width;
2595 bktr->current_col += width;
2599 if (bktr->current_col == 0 && width == cols) {
2602 } else if (bktr->current_col == 0 ) {
2605 } else if (bktr->current_col >= cols) {
2614 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2615 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2620 *(*dma_prog)++ = operation | flag |
2621 (width * pixel_width / 2 - skip);
2622 if (operation != OP_SKIP )
2623 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2624 *target_buffer += (width * pixel_width / 2) ;
2626 if ( operation == OP_WRITE )
2627 operation = OP_WRITEC;
2628 *(*dma_prog)++ = operation | flag2 |
2629 (width * pixel_width / 2);
2630 *target_buffer += (width * pixel_width / 2) ;
2631 bktr->current_col += width;
2639 * Generate the RISC instructions to capture both VBI and video images
2642 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2645 volatile uint32_t target_buffer, buffer, target,width;
2646 volatile uint32_t pitch;
2647 volatile uint32_t *dma_prog; /* DMA prog is an array of
2648 32 bit RISC instructions */
2649 volatile uint32_t *loop_point;
2650 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2651 u_int Bpp = pf_int->public.Bpp;
2652 unsigned int vbisamples; /* VBI samples per line */
2653 unsigned int vbilines; /* VBI lines per field */
2654 unsigned int num_dwords; /* DWORDS per line */
2656 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2657 vbilines = format_params[bktr->format_params].vbi_num_lines;
2658 num_dwords = vbisamples/4;
2660 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2661 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2662 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2663 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2666 OUTB(bktr, BKTR_OFORM, 0x00);
2668 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2669 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2670 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2671 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2673 /* disable gamma correction removal */
2674 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2677 OUTB(bktr, BKTR_E_VTC, 0);
2678 OUTB(bktr, BKTR_O_VTC, 0);
2680 OUTB(bktr, BKTR_E_VTC, 1);
2681 OUTB(bktr, BKTR_O_VTC, 1);
2683 bktr->capcontrol = 3 << 2 | 3;
2685 dma_prog = (uint32_t *) bktr->dma_prog;
2687 /* Construct Write */
2689 if (bktr->video.addr) {
2690 target_buffer = (u_long) bktr->video.addr;
2691 pitch = bktr->video.width;
2694 target_buffer = (u_long) vtophys(bktr->bigbuf);
2698 buffer = target_buffer;
2700 /* Wait for the VRE sync marking the end of the Even and
2701 * the start of the Odd field. Resync here.
2703 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2706 loop_point = dma_prog;
2708 /* store the VBI data */
2709 /* look for sync with packed data */
2710 *dma_prog++ = OP_SYNC | BKTR_FM1;
2712 for(i = 0; i < vbilines; i++) {
2713 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2714 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2715 (i * VBI_LINE_SIZE));
2718 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2719 /* store the Odd field video image */
2720 /* look for sync with packed data */
2721 *dma_prog++ = OP_SYNC | BKTR_FM1;
2722 *dma_prog++ = 0; /* NULL WORD */
2724 for (i = 0; i < (rows/interlace); i++) {
2725 target = target_buffer;
2726 if ( notclipped(bktr, i, width)) {
2727 split(bktr, (volatile uint32_t **) &dma_prog,
2728 bktr->y2 - bktr->y, OP_WRITE,
2729 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2732 while(getline(bktr, i)) {
2733 if (bktr->y != bktr->y2 ) {
2734 split(bktr, (volatile uint32_t **) &dma_prog,
2735 bktr->y2 - bktr->y, OP_WRITE,
2736 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2738 if (bktr->yclip != bktr->yclip2 ) {
2739 split(bktr,(volatile uint32_t **) &dma_prog,
2740 bktr->yclip2 - bktr->yclip,
2742 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2748 target_buffer += interlace * pitch;
2754 /* Grab the Even field */
2755 /* Look for the VRO, end of Odd field, marker */
2756 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2757 *dma_prog++ = 0; /* NULL WORD */
2759 /* store the VBI data */
2760 /* look for sync with packed data */
2761 *dma_prog++ = OP_SYNC | BKTR_FM1;
2763 for(i = 0; i < vbilines; i++) {
2764 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2765 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2766 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2769 /* store the video image */
2770 if (i_flag == 1) /*Even Only*/
2771 target_buffer = buffer;
2772 if (i_flag == 3) /*interlaced*/
2773 target_buffer = buffer+pitch;
2776 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2777 /* look for sync with packed data */
2778 *dma_prog++ = OP_SYNC | BKTR_FM1;
2779 *dma_prog++ = 0; /* NULL WORD */
2781 for (i = 0; i < (rows/interlace); i++) {
2782 target = target_buffer;
2783 if ( notclipped(bktr, i, width)) {
2784 split(bktr, (volatile uint32_t **) &dma_prog,
2785 bktr->y2 - bktr->y, OP_WRITE,
2786 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2788 while(getline(bktr, i)) {
2789 if (bktr->y != bktr->y2 ) {
2790 split(bktr, (volatile uint32_t **) &dma_prog,
2791 bktr->y2 - bktr->y, OP_WRITE,
2792 Bpp, (volatile u_char **)(uintptr_t)&target,
2795 if (bktr->yclip != bktr->yclip2 ) {
2796 split(bktr, (volatile uint32_t **) &dma_prog,
2797 bktr->yclip2 - bktr->yclip, OP_SKIP,
2798 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2805 target_buffer += interlace * pitch;
2810 /* Look for end of 'Even Field' */
2811 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2812 *dma_prog++ = 0; /* NULL WORD */
2814 *dma_prog++ = OP_JUMP ;
2815 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2816 *dma_prog++ = 0; /* NULL WORD */
2824 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2827 volatile uint32_t target_buffer, buffer, target,width;
2828 volatile uint32_t pitch;
2829 volatile uint32_t *dma_prog;
2830 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2831 u_int Bpp = pf_int->public.Bpp;
2833 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2834 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2835 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2836 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2838 OUTB(bktr, BKTR_OFORM, 0x00);
2840 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2841 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2842 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2843 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2845 /* disable gamma correction removal */
2846 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2849 OUTB(bktr, BKTR_E_VTC, 0);
2850 OUTB(bktr, BKTR_O_VTC, 0);
2852 OUTB(bktr, BKTR_E_VTC, 1);
2853 OUTB(bktr, BKTR_O_VTC, 1);
2855 bktr->capcontrol = 3 << 2 | 3;
2857 dma_prog = (uint32_t *) bktr->dma_prog;
2859 /* Construct Write */
2861 if (bktr->video.addr) {
2862 target_buffer = (uint32_t) bktr->video.addr;
2863 pitch = bktr->video.width;
2866 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2870 buffer = target_buffer;
2872 /* contruct sync : for video packet format */
2873 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2875 /* sync, mode indicator packed data */
2876 *dma_prog++ = 0; /* NULL WORD */
2878 for (i = 0; i < (rows/interlace); i++) {
2879 target = target_buffer;
2880 if ( notclipped(bktr, i, width)) {
2881 split(bktr, (volatile uint32_t **) &dma_prog,
2882 bktr->y2 - bktr->y, OP_WRITE,
2883 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2886 while(getline(bktr, i)) {
2887 if (bktr->y != bktr->y2 ) {
2888 split(bktr, (volatile uint32_t **) &dma_prog,
2889 bktr->y2 - bktr->y, OP_WRITE,
2890 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2892 if (bktr->yclip != bktr->yclip2 ) {
2893 split(bktr,(volatile uint32_t **) &dma_prog,
2894 bktr->yclip2 - bktr->yclip,
2896 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2902 target_buffer += interlace * pitch;
2909 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
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_VRE;
2919 *dma_prog++ = 0; /* NULL WORD */
2921 *dma_prog++ = OP_JUMP;
2922 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2927 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2928 *dma_prog++ = 0; /* NULL WORD */
2929 *dma_prog++ = OP_JUMP;
2930 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
2934 if (interlace == 2) {
2936 target_buffer = buffer + pitch;
2938 dma_prog = (uint32_t *) bktr->odd_dma_prog;
2940 /* sync vre IRQ bit */
2941 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2942 *dma_prog++ = 0; /* NULL WORD */
2944 for (i = 0; i < (rows/interlace); i++) {
2945 target = target_buffer;
2946 if ( notclipped(bktr, i, width)) {
2947 split(bktr, (volatile uint32_t **) &dma_prog,
2948 bktr->y2 - bktr->y, OP_WRITE,
2949 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2951 while(getline(bktr, i)) {
2952 if (bktr->y != bktr->y2 ) {
2953 split(bktr, (volatile uint32_t **) &dma_prog,
2954 bktr->y2 - bktr->y, OP_WRITE,
2955 Bpp, (volatile u_char **)(uintptr_t)&target,
2958 if (bktr->yclip != bktr->yclip2 ) {
2959 split(bktr, (volatile uint32_t **) &dma_prog,
2960 bktr->yclip2 - bktr->yclip, OP_SKIP,
2961 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2968 target_buffer += interlace * pitch;
2973 /* sync vre IRQ bit */
2974 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2975 *dma_prog++ = 0; /* NULL WORD */
2976 *dma_prog++ = OP_JUMP ;
2977 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
2978 *dma_prog++ = 0; /* NULL WORD */
2986 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2987 int cols, int rows, int interlace )
2990 volatile unsigned int inst;
2991 volatile unsigned int inst3;
2992 volatile uint32_t target_buffer, buffer;
2993 volatile uint32_t *dma_prog;
2994 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2997 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2999 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3000 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3002 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3003 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3005 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3006 bktr->capcontrol = 3 << 2 | 3;
3008 dma_prog = (uint32_t *) bktr->dma_prog;
3010 /* Construct Write */
3012 /* write , sol, eol */
3013 inst = OP_WRITE | OP_SOL | (cols);
3014 /* write , sol, eol */
3015 inst3 = OP_WRITE | OP_EOL | (cols);
3017 if (bktr->video.addr)
3018 target_buffer = (uint32_t) bktr->video.addr;
3020 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3022 buffer = target_buffer;
3024 /* contruct sync : for video packet format */
3025 /* sync, mode indicator packed data */
3026 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3027 *dma_prog++ = 0; /* NULL WORD */
3031 for (i = 0; i < (rows/interlace); i++) {
3033 *dma_prog++ = target_buffer;
3034 *dma_prog++ = inst3;
3035 *dma_prog++ = target_buffer + b;
3036 target_buffer += interlace*(cols * 2);
3042 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3043 *dma_prog++ = 0; /* NULL WORD */
3045 *dma_prog++ = OP_JUMP;
3046 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3051 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3052 *dma_prog++ = 0; /* NULL WORD */
3053 *dma_prog++ = OP_JUMP;
3054 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3059 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3060 *dma_prog++ = 0; /* NULL WORD */
3061 *dma_prog++ = OP_JUMP ;
3062 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3066 if (interlace == 2) {
3068 target_buffer = (uint32_t) buffer + cols*2;
3070 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3073 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3074 *dma_prog++ = 0; /* NULL WORD */
3076 for (i = 0; i < (rows/interlace) ; i++) {
3078 *dma_prog++ = target_buffer;
3079 *dma_prog++ = inst3;
3080 *dma_prog++ = target_buffer + b;
3081 target_buffer += interlace * ( cols*2);
3085 /* sync vro IRQ bit */
3086 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3087 *dma_prog++ = 0; /* NULL WORD */
3088 *dma_prog++ = OP_JUMP ;
3089 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3091 *dma_prog++ = OP_JUMP;
3092 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3093 *dma_prog++ = 0; /* NULL WORD */
3101 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3102 int cols, int rows, int interlace ){
3105 volatile unsigned int inst;
3106 volatile uint32_t target_buffer, t1, buffer;
3107 volatile uint32_t *dma_prog;
3108 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3110 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3112 dma_prog = (uint32_t*) bktr->dma_prog;
3114 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3116 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3117 OUTB(bktr, BKTR_OFORM, 0x00);
3119 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3120 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3122 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3123 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3125 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3126 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3127 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3128 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3130 /* disable gamma correction removal */
3131 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3133 /* Construct Write */
3134 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3135 if (bktr->video.addr)
3136 target_buffer = (uint32_t) bktr->video.addr;
3138 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3140 buffer = target_buffer;
3144 /* contruct sync : for video packet format */
3145 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3146 *dma_prog++ = 0; /* NULL WORD */
3148 for (i = 0; i < (rows/interlace ) ; i++) {
3150 *dma_prog++ = cols/2 | cols/2 << 16;
3151 *dma_prog++ = target_buffer;
3152 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3153 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3154 target_buffer += interlace*cols;
3159 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3160 *dma_prog++ = 0; /* NULL WORD */
3162 *dma_prog++ = OP_JUMP ;
3163 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3167 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3168 *dma_prog++ = 0; /* NULL WORD */
3170 *dma_prog++ = OP_JUMP;
3171 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3175 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3176 *dma_prog++ = 0; /* NULL WORD */
3178 *dma_prog++ = OP_JUMP ;
3179 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3183 if (interlace == 2) {
3185 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3187 target_buffer = (uint32_t) buffer + cols;
3188 t1 = buffer + cols/2;
3189 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3190 *dma_prog++ = 0; /* NULL WORD */
3192 for (i = 0; i < (rows/interlace ) ; i++) {
3194 *dma_prog++ = cols/2 | cols/2 << 16;
3195 *dma_prog++ = target_buffer;
3196 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3197 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3198 target_buffer += interlace*cols;
3202 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3203 *dma_prog++ = 0; /* NULL WORD */
3204 *dma_prog++ = OP_JUMP ;
3205 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3206 *dma_prog++ = 0; /* NULL WORD */
3214 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3215 int cols, int rows, int interlace ){
3218 volatile unsigned int inst;
3219 volatile unsigned int inst1;
3220 volatile uint32_t target_buffer, t1, buffer;
3221 volatile uint32_t *dma_prog;
3222 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3224 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3226 dma_prog = (uint32_t *) bktr->dma_prog;
3228 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3230 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3231 OUTB(bktr, BKTR_OFORM, 0x0);
3233 /* Construct Write */
3234 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3235 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3236 if (bktr->video.addr)
3237 target_buffer = (uint32_t) bktr->video.addr;
3239 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3241 buffer = target_buffer;
3244 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3245 *dma_prog++ = 0; /* NULL WORD */
3247 for (i = 0; i < (rows/interlace )/2 ; i++) {
3249 *dma_prog++ = cols/2 | (cols/2 << 16);
3250 *dma_prog++ = target_buffer;
3251 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3252 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3253 target_buffer += interlace*cols;
3254 *dma_prog++ = inst1;
3255 *dma_prog++ = cols/2 | (cols/2 << 16);
3256 *dma_prog++ = target_buffer;
3257 target_buffer += interlace*cols;
3263 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3264 *dma_prog++ = 0; /* NULL WORD */
3266 *dma_prog++ = OP_JUMP;
3267 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3271 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3272 *dma_prog++ = 0; /* NULL WORD */
3274 *dma_prog++ = OP_JUMP;
3275 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3279 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3280 *dma_prog++ = 0; /* NULL WORD */
3281 *dma_prog++ = OP_JUMP ;
3282 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3286 if (interlace == 2) {
3288 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3290 target_buffer = (uint32_t) buffer + cols;
3291 t1 = buffer + cols/2;
3292 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3293 *dma_prog++ = 0; /* NULL WORD */
3295 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3297 *dma_prog++ = cols/2 | (cols/2 << 16);
3298 *dma_prog++ = target_buffer;
3299 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3300 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3301 target_buffer += interlace*cols;
3302 *dma_prog++ = inst1;
3303 *dma_prog++ = cols/2 | (cols/2 << 16);
3304 *dma_prog++ = target_buffer;
3305 target_buffer += interlace*cols;
3312 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3313 *dma_prog++ = 0; /* NULL WORD */
3314 *dma_prog++ = OP_JUMP;
3315 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3316 *dma_prog++ = 0; /* NULL WORD */
3325 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3327 int rows, cols, interlace;
3330 struct format_params *fp;
3331 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3334 fp = &format_params[bktr->format_params];
3336 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3338 /* disable FIFO & RISC, leave other bits alone */
3339 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3341 /* set video parameters */
3342 if (bktr->capture_area_enabled)
3343 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3344 / fp->scaled_htotal / bktr->cols) - 4096;
3346 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3347 / fp->scaled_htotal / bktr->cols) - 4096;
3349 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3350 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3351 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3352 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3353 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3355 /* horizontal active */
3357 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3358 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3359 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3360 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3361 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3362 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3363 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3365 /* horizontal delay */
3366 if (bktr->capture_area_enabled)
3367 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3368 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3370 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3372 temp = temp & 0x3fe;
3374 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3375 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3376 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3377 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3378 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3379 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3380 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3382 /* vertical scale */
3384 if (bktr->capture_area_enabled) {
3385 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3386 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3388 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3391 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3394 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3395 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3397 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3400 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3405 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3406 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3407 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3408 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3409 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3410 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3411 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3414 /* vertical active */
3415 if (bktr->capture_area_enabled)
3416 temp = bktr->capture_area_y_size;
3419 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3420 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3421 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3422 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3423 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3424 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3425 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3427 /* vertical delay */
3428 if (bktr->capture_area_enabled)
3429 temp = fp->vdelay + (bktr->capture_area_y_offset);
3432 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3433 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3434 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3435 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3436 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3437 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3438 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3440 /* end of video params */
3442 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3443 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3444 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3446 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3449 /* capture control */
3452 bktr->bktr_cap_ctl =
3453 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3454 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3455 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3459 bktr->bktr_cap_ctl =
3460 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3461 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3462 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3466 bktr->bktr_cap_ctl =
3467 (BT848_CAP_CTL_DITH_FRAME |
3468 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3469 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3470 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3475 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3480 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3482 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3483 /* user, then use the rgb_vbi RISC program. */
3484 /* Otherwise, use the normal rgb RISC program */
3485 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3486 if ( (bktr->vbiflags & VBI_OPEN)
3487 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3488 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3490 bktr->bktr_cap_ctl |=
3491 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3492 bktr->vbiflags |= VBI_CAPTURE;
3493 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3496 rgb_prog(bktr, i_flag, cols, rows, interlace);
3501 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3502 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3503 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3504 | pixfmt_swap_flags( bktr->pixfmt ));
3508 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3509 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3510 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3511 | pixfmt_swap_flags( bktr->pixfmt ));
3515 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3516 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3517 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3518 | pixfmt_swap_flags( bktr->pixfmt ));
3525 /******************************************************************************
3526 * video & video capture specific routines:
3534 start_capture( bktr_ptr_t bktr, unsigned type )
3537 struct format_params *fp;
3539 fp = &format_params[bktr->format_params];
3541 /* If requested, clear out capture buf first */
3542 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3543 bzero((caddr_t)bktr->bigbuf,
3544 (size_t)bktr->rows * bktr->cols * bktr->frames *
3545 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3548 OUTB(bktr, BKTR_DSTATUS, 0);
3549 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3551 bktr->flags |= type;
3552 bktr->flags &= ~METEOR_WANT_MASK;
3553 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3554 case METEOR_ONLY_EVEN_FIELDS:
3555 bktr->flags |= METEOR_WANT_EVEN;
3558 case METEOR_ONLY_ODD_FIELDS:
3559 bktr->flags |= METEOR_WANT_ODD;
3563 bktr->flags |= METEOR_WANT_MASK;
3568 /* TDEC is only valid for continuous captures */
3569 if ( type == METEOR_SINGLE ) {
3570 u_short fps_save = bktr->fps;
3572 set_fps(bktr, fp->frame_rate);
3573 bktr->fps = fps_save;
3576 set_fps(bktr, bktr->fps);
3578 if (bktr->dma_prog_loaded == FALSE) {
3579 build_dma_prog(bktr, i_flag);
3580 bktr->dma_prog_loaded = TRUE;
3584 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3593 set_fps( bktr_ptr_t bktr, u_short fps )
3595 struct format_params *fp;
3598 fp = &format_params[bktr->format_params];
3600 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3601 case METEOR_ONLY_EVEN_FIELDS:
3602 bktr->flags |= METEOR_WANT_EVEN;
3605 case METEOR_ONLY_ODD_FIELDS:
3606 bktr->flags |= METEOR_WANT_ODD;
3610 bktr->flags |= METEOR_WANT_MASK;
3615 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3616 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3619 OUTB(bktr, BKTR_TDEC, 0);
3621 if (fps < fp->frame_rate)
3622 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3624 OUTB(bktr, BKTR_TDEC, 0);
3634 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3635 * achieve the specified swapping.
3636 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3637 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3639 * Note also that for 3Bpp, we may additionally need to do some creative
3640 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3641 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3642 * as one would expect.
3645 static u_int pixfmt_swap_flags( int pixfmt )
3647 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3650 switch ( pf->Bpp ) {
3651 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3654 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3657 case 4 : if ( pf->swap_bytes )
3658 swapf = pf->swap_shorts ? 0 : WSWAP;
3660 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3669 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3670 * our pixfmt_table indices.
3673 static int oformat_meteor_to_bt( u_long format )
3676 struct meteor_pixfmt *pf1, *pf2;
3678 /* Find format in compatibility table */
3679 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3680 if ( meteor_pixfmt_table[i].meteor_format == format )
3683 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3685 pf1 = &meteor_pixfmt_table[i].public;
3687 /* Match it with an entry in master pixel format table */
3688 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3689 pf2 = &pixfmt_table[i].public;
3691 if (( pf1->type == pf2->type ) &&
3692 ( pf1->Bpp == pf2->Bpp ) &&
3693 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3694 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3695 ( pf1->swap_shorts == pf2->swap_shorts ))
3698 if ( i >= PIXFMT_TABLE_SIZE )
3704 /******************************************************************************
3709 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3710 #define I2CBITTIME_878 (1 << 7)
3711 #define I2C_READ 0x01
3712 #define I2C_COMMAND (I2CBITTIME | \
3713 BT848_DATA_CTL_I2CSCL | \
3714 BT848_DATA_CTL_I2CSDA)
3716 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3717 BT848_DATA_CTL_I2CSCL | \
3718 BT848_DATA_CTL_I2CSDA)
3720 /* Select between old i2c code and new iicbus / smbus code */
3721 #if defined(BKTR_USE_FREEBSD_SMBUS)
3724 * The hardware interface is actually SMB commands
3727 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3731 if (bktr->id == BROOKTREE_848 ||
3732 bktr->id == BROOKTREE_848A ||
3733 bktr->id == BROOKTREE_849A)
3736 cmd = I2C_COMMAND_878;
3739 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3740 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3743 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3744 (char)(byte1 & 0xff)))
3753 i2cRead( bktr_ptr_t bktr, int addr )
3758 if (bktr->id == BROOKTREE_848 ||
3759 bktr->id == BROOKTREE_848A ||
3760 bktr->id == BROOKTREE_849A)
3763 cmd = I2C_COMMAND_878;
3765 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3768 return ((int)((unsigned char)result));
3771 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3773 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3774 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3775 /* Therefore we need low level control of the i2c bus hardware */
3777 /* Write to the MSP or DPL registers */
3779 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3781 unsigned char addr_l, addr_h, data_h, data_l ;
3783 addr_h = (addr >>8) & 0xff;
3784 addr_l = addr & 0xff;
3785 data_h = (data >>8) & 0xff;
3786 data_l = data & 0xff;
3788 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3790 iicbus_write_byte(IICBUS(bktr), dev, 0);
3791 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3792 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3793 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3794 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3796 iicbus_stop(IICBUS(bktr));
3801 /* Read from the MSP or DPL registers */
3803 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3806 unsigned char addr_l, addr_h, dev_r;
3808 u_char data_read[2];
3810 addr_h = (addr >>8) & 0xff;
3811 addr_l = addr & 0xff;
3814 /* XXX errors ignored */
3815 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3817 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3818 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3819 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3821 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3822 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3823 iicbus_stop(IICBUS(bktr));
3825 data = (data_read[0]<<8) | data_read[1];
3830 /* Reset the MSP or DPL chip */
3831 /* The user can block the reset (which is handy if you initialise the
3832 * MSP and/or DPL audio in another operating system first (eg in Windows)
3835 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3838 #ifndef BKTR_NO_MSP_RESET
3839 /* put into reset mode */
3840 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3841 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3842 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3843 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3844 iicbus_stop(IICBUS(bktr));
3846 /* put back to operational mode */
3847 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3848 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3849 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3850 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3851 iicbus_stop(IICBUS(bktr));
3856 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3859 /* XXX errors ignored */
3860 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3861 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3862 iicbus_stop(IICBUS(bktr));
3867 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3870 * Program the i2c bus directly
3873 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3878 /* clear status bits */
3879 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3881 /* build the command datum */
3882 if (bktr->id == BROOKTREE_848 ||
3883 bktr->id == BROOKTREE_848A ||
3884 bktr->id == BROOKTREE_849A) {
3885 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3887 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3889 if ( byte2 != -1 ) {
3890 data |= ((byte2 & 0xff) << 8);
3891 data |= BT848_DATA_CTL_I2CW3B;
3894 /* write the address and data */
3895 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3897 /* wait for completion */
3898 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3899 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3904 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3916 i2cRead( bktr_ptr_t bktr, int addr )
3920 /* clear status bits */
3921 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3923 /* write the READ address */
3924 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3926 if (bktr->id == BROOKTREE_848 ||
3927 bktr->id == BROOKTREE_848A ||
3928 bktr->id == BROOKTREE_849A) {
3929 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3931 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3934 /* wait for completion */
3935 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3936 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3941 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3945 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3948 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3949 /* bt848 automated i2c bus controller cannot handle */
3950 /* Therefore we need low level control of the i2c bus hardware */
3951 /* Idea for the following functions are from elsewhere in this driver and */
3952 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3955 static void i2c_start( bktr_ptr_t bktr) {
3956 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3957 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3958 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3959 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3962 static void i2c_stop( bktr_ptr_t bktr) {
3963 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3964 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3965 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3968 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3972 /* write out the byte */
3973 for ( x = 7; x >= 0; --x ) {
3974 if ( data & (1<<x) ) {
3975 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3976 DELAY( BITD ); /* assert HI data */
3977 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3978 DELAY( BITD ); /* strobe clock */
3979 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3980 DELAY( BITD ); /* release clock */
3983 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3984 DELAY( BITD ); /* assert LO data */
3985 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3986 DELAY( BITD ); /* strobe clock */
3987 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3988 DELAY( BITD ); /* release clock */
3992 /* look for an ACK */
3993 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3994 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3995 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3996 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4001 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4006 /* read in the byte */
4007 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4008 DELAY( BITD ); /* float data */
4009 for ( x = 7; x >= 0; --x ) {
4010 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4011 DELAY( BITD ); /* strobe clock */
4012 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4013 if ( bit ) byte |= (1<<x);
4014 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4015 DELAY( BITD ); /* release clock */
4017 /* After reading the byte, send an ACK */
4018 /* (unless that was the last byte, for which we send a NAK */
4019 if (last) { /* send NAK - same a writing a 1 */
4020 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4021 DELAY( BITD ); /* set data bit */
4022 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4023 DELAY( BITD ); /* strobe clock */
4024 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4025 DELAY( BITD ); /* release clock */
4026 } else { /* send ACK - same as writing a 0 */
4027 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4028 DELAY( BITD ); /* set data bit */
4029 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4030 DELAY( BITD ); /* strobe clock */
4031 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4032 DELAY( BITD ); /* release clock */
4040 /* Write to the MSP or DPL registers */
4041 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4043 unsigned int msp_w_addr = i2c_addr;
4044 unsigned char addr_l, addr_h, data_h, data_l ;
4045 addr_h = (addr >>8) & 0xff;
4046 addr_l = addr & 0xff;
4047 data_h = (data >>8) & 0xff;
4048 data_l = data & 0xff;
4051 i2c_write_byte(bktr, msp_w_addr);
4052 i2c_write_byte(bktr, dev);
4053 i2c_write_byte(bktr, addr_h);
4054 i2c_write_byte(bktr, addr_l);
4055 i2c_write_byte(bktr, data_h);
4056 i2c_write_byte(bktr, data_l);
4060 /* Read from the MSP or DPL registers */
4061 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4063 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4064 addr_h = (addr >>8) & 0xff;
4065 addr_l = addr & 0xff;
4069 i2c_write_byte(bktr,i2c_addr);
4070 i2c_write_byte(bktr,dev_r);
4071 i2c_write_byte(bktr,addr_h);
4072 i2c_write_byte(bktr,addr_l);
4075 i2c_write_byte(bktr,i2c_addr+1);
4076 i2c_read_byte(bktr,&data_1, 0);
4077 i2c_read_byte(bktr,&data_2, 1);
4079 data = (data_1<<8) | data_2;
4083 /* Reset the MSP or DPL chip */
4084 /* The user can block the reset (which is handy if you initialise the
4085 * MSP audio in another operating system first (eg in Windows)
4087 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4089 #ifndef BKTR_NO_MSP_RESET
4090 /* put into reset mode */
4092 i2c_write_byte(bktr, i2c_addr);
4093 i2c_write_byte(bktr, 0x00);
4094 i2c_write_byte(bktr, 0x80);
4095 i2c_write_byte(bktr, 0x00);
4098 /* put back to operational mode */
4100 i2c_write_byte(bktr, i2c_addr);
4101 i2c_write_byte(bktr, 0x00);
4102 i2c_write_byte(bktr, 0x00);
4103 i2c_write_byte(bktr, 0x00);
4110 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4112 /* XXX errors ignored */
4114 i2c_write_byte(bktr,bktr->remote_control_addr);
4115 i2c_read_byte(bktr,&(remote->data[0]), 0);
4116 i2c_read_byte(bktr,&(remote->data[1]), 0);
4117 i2c_read_byte(bktr,&(remote->data[2]), 0);
4123 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4126 #if defined( I2C_SOFTWARE_PROBE )
4129 * we are keeping this around for any parts that we need to probe
4130 * but that CANNOT be probed via an i2c read.
4131 * this is necessary because the hardware i2c mechanism
4132 * cannot be programmed for 1 byte writes.
4133 * currently there are no known i2c parts that we need to probe
4134 * and that cannot be safely read.
4136 static int i2cProbe( bktr_ptr_t bktr, int addr );
4141 * probe for an I2C device at addr.
4144 i2cProbe( bktr_ptr_t bktr, int addr )
4149 #if defined( EXTRA_START )
4150 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4151 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4152 #endif /* EXTRA_START */
4153 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4154 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4157 for ( x = 7; x >= 0; --x ) {
4158 if ( addr & (1<<x) ) {
4159 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4160 DELAY( BITD ); /* assert HI data */
4161 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4162 DELAY( BITD ); /* strobe clock */
4163 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4164 DELAY( BITD ); /* release clock */
4167 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4168 DELAY( BITD ); /* assert LO data */
4169 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4170 DELAY( BITD ); /* strobe clock */
4171 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4172 DELAY( BITD ); /* release clock */
4176 /* look for an ACK */
4177 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4178 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4179 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4180 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4183 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4184 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4185 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4192 #endif /* I2C_SOFTWARE_PROBE */