2 * 1. Redistributions of source code must retain the
3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Amancio Hasty and
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 * 1. Redistributions of source code must retain the
35 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
36 * All rights reserved.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by Mark Tinguely and Jim Lowe
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
56 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
58 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
60 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
61 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
64 * $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.140 2005/12/04 10:06:03 ru Exp $
68 * This is part of the Driver for Video Capture Cards (Frame grabbers)
69 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
71 * Copyright Roger Hardiman and Amancio Hasty.
73 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
74 * Handles all the open, close, ioctl and read userland calls.
75 * Sets the Bt848 registers and generates RISC pograms.
76 * Controls the i2c bus and GPIO interface.
77 * Contains the interface to the kernel.
78 * (eg probe/attach and open/close/ioctl)
82 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
83 Jim Lowe's driver for the Matrox Meteor PCI card . The
84 Philips SAA 7116 and SAA 7196 are very different chipsets than
87 The original copyright notice by Mark and Jim is included mostly
88 to honor their fantastic work in the Matrox Meteor driver!
91 #include "opt_bktr.h" /* Include any kernel config options */
93 #include <sys/param.h>
94 #include <sys/systm.h>
95 #include <sys/kernel.h>
98 #include <sys/signalvar.h>
99 #include <sys/vnode.h>
100 #include <sys/bus.h> /* used by smbus and newbus */
102 #include <sys/thread2.h>
105 #include <vm/vm_kern.h>
107 #include <vm/vm_extern.h>
110 #define PROC_UNLOCK(p)
111 #include <bus/pci/pcivar.h>
112 #include <bus/pci/pcidevs.h>
114 #include <dev/video/meteor/ioctl_meteor.h>
115 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
116 #include <dev/video/bktr/bktr_reg.h>
117 #include <dev/video/bktr/bktr_tuner.h>
118 #include <dev/video/bktr/bktr_card.h>
119 #include <dev/video/bktr/bktr_audio.h>
120 #include <dev/video/bktr/bktr_os.h>
121 #include <dev/video/bktr/bktr_core.h>
122 #if defined(BKTR_FREEBSD_MODULE)
123 #include <dev/video/bktr/bktr_mem.h>
126 #if defined(BKTR_USE_FREEBSD_SMBUS)
127 #include <dev/video/bktr/bktr_i2c.h>
128 #include <bus/smbus/smbconf.h>
129 #include <bus/iicbus/iiconf.h>
130 #include "smbus_if.h"
131 #include "iicbus_if.h"
135 bktr_name(bktr_ptr_t bktr)
137 return bktr->bktr_xname;
140 typedef u_char bool_t;
142 #define BKTRPRI PCATCH
143 #define VBIPRI PCATCH
147 * memory allocated for DMA programs
149 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
151 /* When to split a dma transfer , the bt848 has timing as well as
152 dma transfer size limitations so that we have to split dma
153 transfers into two dma requests
155 #define DMA_BT848_SPLIT 319*2
158 * Allocate enough memory for:
159 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
161 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
162 * in your kernel configuration file.
165 #ifndef BROOKTREE_ALLOC_PAGES
166 #define BROOKTREE_ALLOC_PAGES 217*4
168 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
170 /* Definitions for VBI capture.
171 * There are 16 VBI lines in a PAL video field (32 in a frame),
172 * and we take 2044 samples from each line (placed in a 2048 byte buffer
174 * VBI lines are held in a circular buffer before being read by a
175 * user program from /dev/vbi.
178 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
179 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
180 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
181 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
182 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
185 /* Defines for fields */
191 * Parameters describing size of transmitted image.
194 static struct format_params format_params[] = {
195 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
196 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
198 /* # define BT848_IFORM_F_NTSCM (0x1) */
199 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
201 /* # define BT848_IFORM_F_NTSCJ (0x2) */
202 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
204 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
205 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
207 /* # define BT848_IFORM_F_PALM (0x4) */
208 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
210 /* # define BT848_IFORM_F_PALN (0x5) */
211 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
213 /* # define BT848_IFORM_F_SECAM (0x6) */
214 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
216 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
217 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
222 * Table of supported Pixel Formats
225 static struct meteor_pixfmt_internal {
226 struct meteor_pixfmt public;
230 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
231 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
233 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
234 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
236 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
238 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
239 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
240 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
241 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
242 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
243 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
244 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
247 #define PIXFMT_TABLE_SIZE NELEM(pixfmt_table)
250 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
253 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
255 u_long meteor_format;
256 struct meteor_pixfmt public;
257 } meteor_pixfmt_table[] = {
259 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
262 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
263 { METEOR_GEO_YUV_422,
264 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
266 { METEOR_GEO_YUV_PACKED,
267 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
270 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
273 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
277 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
278 sizeof(meteor_pixfmt_table[0]) )
281 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
282 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
286 /* sync detect threshold */
288 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
289 BT848_ADC_CRUSH) /* threshold ~125 mV */
291 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
292 BT848_ADC_SYNC_T) /* threshold ~75 mV */
298 /* debug utility for holding previous INT_STAT contents */
300 static u_long status_sum = 0;
303 * defines to make certain bit-fiddles understandable
305 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
306 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
307 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
308 #define FIFO_RISC_DISABLED 0
310 #define ALL_INTS_DISABLED 0
311 #define ALL_INTS_CLEARED 0xffffffff
312 #define CAPTURE_OFF 0
314 #define BIT_SEVEN_HIGH (1<<7)
315 #define BIT_EIGHT_HIGH (1<<8)
317 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
318 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
322 static int oformat_meteor_to_bt( u_long format );
324 static u_int pixfmt_swap_flags( int pixfmt );
327 * bt848 RISC programming routines.
330 static int dump_bt848( bktr_ptr_t bktr );
333 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
334 int rows, int interlace );
335 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
336 int rows, int interlace );
337 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
338 int rows, int interlace );
339 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
340 int rows, int interlace );
341 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
342 int rows, int interlace );
343 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
345 static bool_t getline(bktr_reg_t *, int);
346 static bool_t notclipped(bktr_reg_t * , int , int);
347 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
348 volatile u_char ** , int );
350 static void start_capture( bktr_ptr_t bktr, unsigned type );
351 static void set_fps( bktr_ptr_t bktr, u_short fps );
356 * Remote Control Functions
358 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
362 * ioctls common to both video & tuner.
364 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
367 #if !defined(BKTR_USE_FREEBSD_SMBUS)
369 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
371 static void i2c_start( bktr_ptr_t bktr);
372 static void i2c_stop( bktr_ptr_t bktr);
373 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
374 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
380 * the common attach code, used by all OS versions.
383 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
386 int need_to_allocate_memory = 1;
387 #ifdef BKTR_NEW_MSP34XX_DRIVER
391 /* If this is a module, check if there is any currently saved contiguous memory */
392 #if defined(BKTR_FREEBSD_MODULE)
393 if (bktr_has_stored_addresses(unit) == 1) {
394 /* recover the addresses */
395 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
396 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
397 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
398 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
399 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
400 need_to_allocate_memory = 0;
404 if (need_to_allocate_memory == 1) {
405 /* allocate space for dma program */
406 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
407 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
409 /* allocte space for the VBI buffer */
410 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
411 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
413 /* allocate space for pixel buffer */
414 if ( BROOKTREE_ALLOC )
415 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
421 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
424 /* If this is a module, save the current contiguous memory */
425 #if defined(BKTR_FREEBSD_MODULE)
426 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
427 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
428 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
429 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
430 bktr_store_address(unit, BKTR_MEM_BUF, buf);
435 kprintf("%s: buffer size %d, addr %p\n",
436 bktr_name(bktr), BROOKTREE_ALLOC,
437 (void *)(uintptr_t)vtophys(buf));
442 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
443 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
445 bktr->alloc_pages = 0;
449 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
450 METEOR_DEV0 | METEOR_RGB16;
451 bktr->dma_prog_loaded = FALSE;
454 bktr->frames = 1; /* one frame */
455 bktr->format = METEOR_GEO_RGB16;
456 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
457 bktr->pixfmt_compat = TRUE;
466 /* using the pci device id and revision id */
467 /* and determine the card type */
468 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
470 switch (PCI_PRODUCT(pci_id)) {
471 case PCI_PRODUCT_BROOKTREE_BT848:
473 bktr->id = BROOKTREE_848A;
475 bktr->id = BROOKTREE_848;
477 case PCI_PRODUCT_BROOKTREE_BT849:
478 bktr->id = BROOKTREE_849A;
480 case PCI_PRODUCT_BROOKTREE_BT878:
481 bktr->id = BROOKTREE_878;
483 case PCI_PRODUCT_BROOKTREE_BT879:
484 bktr->id = BROOKTREE_879;
489 bktr->clr_on_start = FALSE;
491 /* defaults for the tuner section of the card */
492 bktr->tflags = TUNER_INITALIZED;
493 bktr->tuner.frequency = 0;
494 bktr->tuner.channel = 0;
495 bktr->tuner.chnlset = DEFAULT_CHNLSET;
497 bktr->tuner.radio_mode = 0;
498 bktr->audio_mux_select = 0;
499 bktr->audio_mute_state = FALSE;
500 bktr->bt848_card = -1;
501 bktr->bt848_tuner = -1;
502 bktr->reverse_mute = -1;
503 bktr->slow_msp_audio = 0;
504 bktr->msp_use_mono_source = 0;
505 bktr->msp_source_selected = -1;
506 bktr->audio_mux_present = 1;
508 #ifdef BKTR_NEW_MSP34XX_DRIVER
509 /* get hint on short programming of the msp34xx, so we know */
510 /* if the decision what thread to start should be overwritten */
511 if ( (err = resource_int_value("bktr", unit, "mspsimple",
512 &(bktr->mspsimple)) ) != 0 )
513 bktr->mspsimple = -1; /* fall back to default */
516 probeCard( bktr, TRUE, unit );
518 /* Initialise any MSP34xx or TDA98xx audio chips */
519 init_audio_devices( bktr );
521 #ifdef BKTR_NEW_MSP34XX_DRIVER
522 /* setup the kenrel thread */
523 err = msp_attach( bktr );
524 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
525 bktr->card.msp3400c = 0;
532 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
533 * The circular buffer holds 'n' fixed size data blocks.
534 * vbisize is the number of bytes in the circular buffer
535 * vbiread is the point we reading data out of the circular buffer
536 * vbiinsert is the point we insert data into the circular buffer
538 static void vbidecode(bktr_ptr_t bktr) {
540 unsigned int *seq_dest;
542 /* Check if there is room in the buffer to insert the data. */
543 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
545 /* Copy the VBI data into the next free slot in the buffer. */
546 /* 'dest' is the point in vbibuffer where we want to insert new data */
547 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
548 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
550 /* Write the VBI sequence number to the end of the vbi data */
551 /* This is used by the AleVT teletext program */
552 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
554 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
555 *seq_dest = bktr->vbi_sequence_number;
557 /* And increase the VBI sequence number */
558 /* This can wrap around */
559 bktr->vbi_sequence_number++;
562 /* Increment the vbiinsert pointer */
563 /* This can wrap around */
564 bktr->vbiinsert += VBI_DATA_SIZE;
565 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
567 /* And increase the amount of vbi data in the buffer */
568 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
574 * the common interrupt handler.
575 * Returns a 0 or 1 depending on whether the interrupt has handled.
576 * In the OS specific section, bktr_intr() is defined which calls this
577 * common interrupt handler.
580 common_bktr_intr( void *arg )
589 bktr = (bktr_ptr_t) arg;
592 * check to see if any interrupts are unmasked on this device. If
593 * none are, then we likely got here by way of being on a PCI shared
594 * interrupt dispatch list.
596 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
597 return 0; /* bail out now, before we do something we
600 if (!(bktr->flags & METEOR_OPEN)) {
601 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
602 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
606 /* record and clear the INTerrupt status bits */
607 bktr_status = INL(bktr, BKTR_INT_STAT);
608 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
610 /* record and clear the device status register */
611 dstatus = INB(bktr, BKTR_DSTATUS);
612 OUTB(bktr, BKTR_DSTATUS, 0x00);
614 #if defined( STATUS_SUM )
615 /* add any new device status or INTerrupt status bits */
616 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
617 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
618 #endif /* STATUS_SUM */
619 /* kprintf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
620 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
624 /* if risc was disabled re-start process again */
625 /* if there was one of the following errors re-start again */
626 if ( !(bktr_status & BT848_INT_RISC_EN) ||
627 ((bktr_status &(/* BT848_INT_FBUS | */
628 /* BT848_INT_FTRGT | */
629 /* BT848_INT_FDSR | */
631 BT848_INT_RIPERR | BT848_INT_PABORT |
632 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
633 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
635 u_short tdec_save = INB(bktr, BKTR_TDEC);
637 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
638 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
640 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
642 /* Reset temporal decimation counter */
643 OUTB(bktr, BKTR_TDEC, 0);
644 OUTB(bktr, BKTR_TDEC, tdec_save);
646 /* Reset to no-fields captured state */
647 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
648 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
649 case METEOR_ONLY_ODD_FIELDS:
650 bktr->flags |= METEOR_WANT_ODD;
652 case METEOR_ONLY_EVEN_FIELDS:
653 bktr->flags |= METEOR_WANT_EVEN;
656 bktr->flags |= METEOR_WANT_MASK;
661 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
662 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
663 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
665 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
670 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
674 /* If this is not a RISC program interrupt, return */
675 if (!(bktr_status & BT848_INT_RISCI))
679 kprintf( "%s: intr status %x %x %x\n", bktr_name(bktr),
680 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
685 * Disable future interrupts if a capture mode is not selected.
686 * This can happen when we are in the process of closing or
687 * changing capture modes, otherwise it shouldn't happen.
689 if (!(bktr->flags & METEOR_CAP_MASK))
690 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
693 /* Determine which field generated this interrupt */
694 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
698 * Process the VBI data if it is being captured. We do this once
699 * both Odd and Even VBI data is captured. Therefore we do this
700 * in the Even field interrupt handler.
703 if ( (bktr->vbiflags & VBI_CAPTURE)
704 &&(bktr->vbiflags & VBI_OPEN)
706 /* Put VBI data into circular buffer */
709 /* If someone is blocked on reading from /dev/vbi, wake them */
710 if (bktr->vbi_read_blocked) {
711 bktr->vbi_read_blocked = FALSE;
715 /* Inform anyone who is polling */
716 KNOTE(&bktr->vbi_kq.ki_note, 0);
722 * Register the completed field
723 * (For dual-field mode, require fields from the same frame)
725 switch ( bktr->flags & METEOR_WANT_MASK ) {
726 case METEOR_WANT_ODD : w_field = ODD_F ; break;
727 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
728 default : w_field = (ODD_F|EVEN_F); break;
730 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
731 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
732 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
733 default : req_field = (ODD_F|EVEN_F);
737 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
738 bktr->flags &= ~METEOR_WANT_EVEN;
739 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
740 ( w_field == ODD_F ))
741 bktr->flags &= ~METEOR_WANT_ODD;
742 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
743 ( w_field == (ODD_F|EVEN_F) ))
744 bktr->flags &= ~METEOR_WANT_ODD;
745 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
746 ( w_field == ODD_F )) {
747 bktr->flags &= ~METEOR_WANT_ODD;
748 bktr->flags |= METEOR_WANT_EVEN;
751 /* We're out of sync. Start over. */
752 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
753 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
754 case METEOR_ONLY_ODD_FIELDS:
755 bktr->flags |= METEOR_WANT_ODD;
757 case METEOR_ONLY_EVEN_FIELDS:
758 bktr->flags |= METEOR_WANT_EVEN;
761 bktr->flags |= METEOR_WANT_MASK;
769 * If we have a complete frame.
771 if (!(bktr->flags & METEOR_WANT_MASK)) {
772 bktr->frames_captured++;
774 * post the completion time.
776 if (bktr->flags & METEOR_WANT_TS) {
779 if ((u_int) bktr->alloc_pages * PAGE_SIZE
780 <= (bktr->frame_size + sizeof(struct timeval))) {
781 ts =(struct timeval *)bktr->bigbuf +
783 /* doesn't work in synch mode except
792 * Wake up the user in single capture mode.
794 if (bktr->flags & METEOR_SINGLE) {
797 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
799 /* disable risc, leave fifo running */
800 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
805 * If the user requested to be notified via signal,
806 * let them know the frame is complete.
809 if (bktr->proc != NULL) {
810 PROC_LOCK(bktr->proc);
811 ksignal( bktr->proc, bktr->signal);
812 PROC_UNLOCK(bktr->proc);
816 * Reset the want flags if in continuous or
817 * synchronous capture mode.
821 * currently we only support 3 capture modes: odd only, even only,
822 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
823 * either even OR odd) could provide 60 (50 for PAL) pictures per
824 * second, but it would require this routine to toggle the desired frame
825 * each time, and one more different DMA program for the Bt848.
826 * As a consequence, this fourth mode is currently unsupported.
829 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
830 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
831 case METEOR_ONLY_ODD_FIELDS:
832 bktr->flags |= METEOR_WANT_ODD;
834 case METEOR_ONLY_EVEN_FIELDS:
835 bktr->flags |= METEOR_WANT_EVEN;
838 bktr->flags |= METEOR_WANT_MASK;
853 extern int bt848_format; /* used to set the default format, PAL or NTSC */
855 video_open( bktr_ptr_t bktr )
857 int frame_rate, video_format=0;
859 if (bktr->flags & METEOR_OPEN) /* device is busy */
862 bktr->flags |= METEOR_OPEN;
868 bktr->clr_on_start = FALSE;
870 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
872 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
874 #if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
880 if (bt848_format == 0 )
883 if (bt848_format == 1 )
886 if (video_format == 1 ) {
887 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
888 bktr->format_params = BT848_IFORM_F_NTSCM;
891 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
892 bktr->format_params = BT848_IFORM_F_PALBDGHI;
896 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
898 /* work around for new Hauppauge 878 cards */
899 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
900 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
901 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
903 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
905 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
906 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
907 frame_rate = format_params[bktr->format_params].frame_rate;
909 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
910 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
911 OUTB(bktr, BKTR_TGCTRL, 0);
912 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
913 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
914 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
917 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
919 bktr->max_clip_node = 0;
921 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
923 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
924 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
926 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
927 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
928 OUTB(bktr, BKTR_E_SCLOOP, 0);
929 OUTB(bktr, BKTR_O_SCLOOP, 0);
931 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
932 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
934 bktr->fifo_errors = 0;
935 bktr->dma_errors = 0;
936 bktr->frames_captured = 0;
937 bktr->even_fields_captured = 0;
938 bktr->odd_fields_captured = 0;
940 set_fps(bktr, frame_rate);
941 bktr->video.addr = 0;
942 bktr->video.width = 0;
943 bktr->video.banksize = 0;
944 bktr->video.ramsize = 0;
945 bktr->pixfmt_compat = TRUE;
946 bktr->format = METEOR_GEO_RGB16;
947 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
949 bktr->capture_area_enabled = FALSE;
951 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
952 based motherboards will
953 operate unreliably */
958 vbi_open( bktr_ptr_t bktr )
963 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
968 bktr->vbiflags |= VBI_OPEN;
970 /* reset the VBI circular buffer pointers and clear the buffers */
974 bktr->vbi_sequence_number = 0;
975 bktr->vbi_read_blocked = FALSE;
977 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
978 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
989 tuner_open( bktr_ptr_t bktr )
991 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
994 if ( bktr->tflags & TUNER_OPEN ) /* already open */
997 bktr->tflags |= TUNER_OPEN;
998 bktr->tuner.frequency = 0;
999 bktr->tuner.channel = 0;
1000 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1001 bktr->tuner.afc = 0;
1002 bktr->tuner.radio_mode = 0;
1004 /* enable drivers on the GPIO port that control the MUXes */
1005 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1007 /* unmute the audio stream */
1008 set_audio( bktr, AUDIO_UNMUTE );
1010 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1011 init_audio_devices( bktr );
1023 video_close( bktr_ptr_t bktr )
1025 bktr->flags &= ~(METEOR_OPEN |
1030 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1031 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1033 bktr->dma_prog_loaded = FALSE;
1034 OUTB(bktr, BKTR_TDEC, 0);
1035 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1037 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1038 OUTL(bktr, BKTR_SRESET, 0xf);
1039 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1046 * tuner close handle,
1047 * place holder for tuner specific operations on a close.
1050 tuner_close( bktr_ptr_t bktr )
1052 bktr->tflags &= ~TUNER_OPEN;
1054 /* mute the audio by switching the mux */
1055 set_audio( bktr, AUDIO_MUTE );
1057 /* disable drivers on the GPIO port that control the MUXes */
1058 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1064 vbi_close( bktr_ptr_t bktr )
1069 bktr->vbiflags &= ~VBI_OPEN;
1080 video_read(bktr_ptr_t bktr, int unit, cdev_t dev, struct uio *uio)
1086 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1089 if (bktr->flags & METEOR_CAP_MASK)
1090 return( EIO ); /* already capturing */
1092 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1095 count = bktr->rows * bktr->cols *
1096 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1098 if ((int) uio->uio_iov->iov_len < count)
1101 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1103 /* capture one frame */
1104 start_capture(bktr, METEOR_SINGLE);
1105 /* wait for capture to complete */
1106 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1107 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1108 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1109 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1115 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1116 if (!status) /* successful capture */
1117 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1119 kprintf ("%s: read: tsleep error %d\n",
1120 bktr_name(bktr), status);
1122 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1128 * Read VBI data from the vbi circular buffer
1129 * The buffer holds vbi data blocks which are the same size
1130 * vbiinsert is the position we will insert the next item into the buffer
1131 * vbistart is the actual position in the buffer we want to read from
1132 * vbisize is the exact number of bytes in the buffer left to read
1135 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1137 int readsize, readsize2, start;
1141 * XXX - vbi_read() should be protected against being re-entered
1142 * while it is unlocked for the uiomove.
1146 while(bktr->vbisize == 0) {
1147 if (ioflag & IO_NDELAY) {
1148 status = EWOULDBLOCK;
1152 bktr->vbi_read_blocked = TRUE;
1154 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1159 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1165 /* Now we have some data to give to the user */
1167 /* We cannot read more bytes than there are in
1168 * the circular buffer
1170 readsize = (int)uio->uio_iov->iov_len;
1172 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1174 /* Check if we can read this number of bytes without having
1175 * to wrap around the circular buffer */
1176 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1177 /* We need to wrap around */
1179 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1180 start = bktr->vbistart;
1182 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1184 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1187 /* We do not need to wrap around */
1188 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1193 /* Update the number of bytes left to read */
1194 bktr->vbisize -= readsize;
1196 /* Update vbistart */
1197 bktr->vbistart += readsize;
1198 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1213 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1215 volatile u_char c_temp;
1217 unsigned int temp_iform;
1219 struct meteor_geomet *geo;
1220 struct meteor_counts *counts;
1221 struct meteor_video *video;
1222 struct bktr_capture_area *cap_area;
1230 case BT848SCLIP: /* set clip region */
1231 bktr->max_clip_node = 0;
1232 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1234 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1235 if (bktr->clip_list[i].y_min == 0 &&
1236 bktr->clip_list[i].y_max == 0)
1239 bktr->max_clip_node = i;
1241 /* make sure that the list contains a valid clip secquence */
1242 /* the clip rectangles should be sorted by x then by y as the
1243 second order sort key */
1245 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1247 /* to disable clipping set y_min and y_max to 0 in the first
1248 clip rectangle . The first clip rectangle is clip_list[0].
1253 if (bktr->max_clip_node == 0 &&
1254 (bktr->clip_list[0].y_min != 0 &&
1255 bktr->clip_list[0].y_max != 0)) {
1259 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1260 if (bktr->clip_list[i].y_min == 0 &&
1261 bktr->clip_list[i].y_max == 0) {
1264 if ( bktr->clip_list[i+1].y_min != 0 &&
1265 bktr->clip_list[i+1].y_max != 0 &&
1266 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1268 bktr->max_clip_node = 0;
1273 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1274 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1275 bktr->clip_list[i].x_min < 0 ||
1276 bktr->clip_list[i].x_max < 0 ||
1277 bktr->clip_list[i].y_min < 0 ||
1278 bktr->clip_list[i].y_max < 0 ) {
1279 bktr->max_clip_node = 0;
1284 bktr->dma_prog_loaded = FALSE;
1288 case METEORSTATUS: /* get Bt848 status */
1289 c_temp = INB(bktr, BKTR_DSTATUS);
1291 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1292 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1293 *(u_short *)arg = temp;
1296 case BT848SFMT: /* set input format */
1297 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1298 temp_iform = INB(bktr, BKTR_IFORM);
1299 temp_iform &= ~BT848_IFORM_FORMAT;
1300 temp_iform &= ~BT848_IFORM_XTSEL;
1301 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1303 case BT848_IFORM_F_AUTO:
1304 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1308 case BT848_IFORM_F_NTSCM:
1309 case BT848_IFORM_F_NTSCJ:
1310 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1312 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1313 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1314 bktr->format_params = temp;
1317 case BT848_IFORM_F_PALBDGHI:
1318 case BT848_IFORM_F_PALN:
1319 case BT848_IFORM_F_SECAM:
1320 case BT848_IFORM_F_RSVD:
1321 case BT848_IFORM_F_PALM:
1322 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1324 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1325 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1326 bktr->format_params = temp;
1330 bktr->dma_prog_loaded = FALSE;
1333 case METEORSFMT: /* set input format */
1334 temp_iform = INB(bktr, BKTR_IFORM);
1335 temp_iform &= ~BT848_IFORM_FORMAT;
1336 temp_iform &= ~BT848_IFORM_XTSEL;
1337 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1338 case 0: /* default */
1339 case METEOR_FMT_NTSC:
1340 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1342 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1343 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1344 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1345 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1346 bktr->format_params = BT848_IFORM_F_NTSCM;
1349 case METEOR_FMT_PAL:
1350 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1352 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1353 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1354 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1355 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1356 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1359 case METEOR_FMT_AUTOMODE:
1360 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1362 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1363 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1369 bktr->dma_prog_loaded = FALSE;
1372 case METEORGFMT: /* get input format */
1373 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1377 case BT848GFMT: /* get input format */
1378 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1381 case METEORSCOUNT: /* (re)set error counts */
1382 counts = (struct meteor_counts *) arg;
1383 bktr->fifo_errors = counts->fifo_errors;
1384 bktr->dma_errors = counts->dma_errors;
1385 bktr->frames_captured = counts->frames_captured;
1386 bktr->even_fields_captured = counts->even_fields_captured;
1387 bktr->odd_fields_captured = counts->odd_fields_captured;
1390 case METEORGCOUNT: /* get error counts */
1391 counts = (struct meteor_counts *) arg;
1392 counts->fifo_errors = bktr->fifo_errors;
1393 counts->dma_errors = bktr->dma_errors;
1394 counts->frames_captured = bktr->frames_captured;
1395 counts->even_fields_captured = bktr->even_fields_captured;
1396 counts->odd_fields_captured = bktr->odd_fields_captured;
1400 video = (struct meteor_video *)arg;
1401 video->addr = bktr->video.addr;
1402 video->width = bktr->video.width;
1403 video->banksize = bktr->video.banksize;
1404 video->ramsize = bktr->video.ramsize;
1408 video = (struct meteor_video *)arg;
1409 bktr->video.addr = video->addr;
1410 bktr->video.width = video->width;
1411 bktr->video.banksize = video->banksize;
1412 bktr->video.ramsize = video->ramsize;
1416 set_fps(bktr, *(u_short *)arg);
1420 *(u_short *)arg = bktr->fps;
1423 case METEORSHUE: /* set hue */
1424 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1427 case METEORGHUE: /* get hue */
1428 *(u_char *)arg = INB(bktr, BKTR_HUE);
1431 case METEORSBRIG: /* set brightness */
1432 char_temp = ( *(u_char *)arg & 0xff) - 128;
1433 OUTB(bktr, BKTR_BRIGHT, char_temp);
1437 case METEORGBRIG: /* get brightness */
1438 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1441 case METEORSCSAT: /* set chroma saturation */
1442 temp = (int)*(u_char *)arg;
1444 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1445 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1446 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1447 & ~(BT848_E_CONTROL_SAT_U_MSB
1448 | BT848_E_CONTROL_SAT_V_MSB));
1449 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1450 & ~(BT848_O_CONTROL_SAT_U_MSB |
1451 BT848_O_CONTROL_SAT_V_MSB));
1453 if ( temp & BIT_SEVEN_HIGH ) {
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));
1463 case METEORGCSAT: /* get chroma saturation */
1464 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1465 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1466 temp |= BIT_SEVEN_HIGH;
1467 *(u_char *)arg = (u_char)temp;
1470 case METEORSCONT: /* set contrast */
1471 temp = (int)*(u_char *)arg & 0xff;
1473 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1474 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1475 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1476 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1477 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1478 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1479 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1482 case METEORGCONT: /* get contrast */
1483 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1484 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1485 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1488 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1489 bktr->clr_on_start = (*(int *)arg != 0);
1492 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1493 *(int *)arg = (int) bktr->clr_on_start;
1498 /* Historically, applications used METEOR_SIG_MODE_MASK
1499 * to reset signal delivery.
1501 if (sig == METEOR_SIG_MODE_MASK)
1503 if (sig < 0 || sig > _SIG_MAXSIG)
1506 bktr->proc = sig ? td->td_proc : NULL;
1510 *(int *)arg = bktr->signal;
1515 switch (*(int *) arg) {
1516 case METEOR_CAP_SINGLE:
1518 if (bktr->bigbuf==0) /* no frame buffer allocated */
1520 /* already capturing */
1521 if (temp & METEOR_CAP_MASK)
1526 start_capture(bktr, METEOR_SINGLE);
1528 /* wait for capture to complete */
1529 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1530 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1531 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1533 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1538 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1539 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1540 if (error && (error != ERESTART)) {
1541 /* Here if we didn't get complete frame */
1543 kprintf( "%s: ioctl: tsleep error %d %x\n",
1544 bktr_name(bktr), error,
1545 INL(bktr, BKTR_RISC_COUNT));
1549 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1551 /* disable risc, leave fifo running */
1552 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1555 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1556 /* FIXME: should we set bt848->int_stat ??? */
1559 case METEOR_CAP_CONTINOUS:
1560 if (bktr->bigbuf==0) /* no frame buffer allocated */
1562 /* already capturing */
1563 if (temp & METEOR_CAP_MASK)
1567 start_capture(bktr, METEOR_CONTIN);
1569 /* Clear the interrypt status register */
1570 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1572 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1573 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1574 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1576 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1581 dump_bt848( bt848 );
1585 case METEOR_CAP_STOP_CONT:
1586 if (bktr->flags & METEOR_CONTIN) {
1587 /* turn off capture */
1588 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1589 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1590 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1592 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1599 /* can't change parameters while capturing */
1600 if (bktr->flags & METEOR_CAP_MASK)
1604 geo = (struct meteor_geomet *) arg;
1607 /* Either even or odd, if even & odd, then these a zero */
1608 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1609 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1610 kprintf( "%s: ioctl: Geometry odd or even only.\n",
1615 /* set/clear even/odd flags */
1616 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1617 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1619 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1620 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1621 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1623 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1625 if (geo->columns <= 0) {
1627 "%s: ioctl: %d: columns must be greater than zero.\n",
1628 bktr_name(bktr), geo->columns);
1631 else if ((geo->columns & 0x3fe) != geo->columns) {
1633 "%s: ioctl: %d: columns too large or not even.\n",
1634 bktr_name(bktr), geo->columns);
1638 if (geo->rows <= 0) {
1640 "%s: ioctl: %d: rows must be greater than zero.\n",
1641 bktr_name(bktr), geo->rows);
1644 else if (((geo->rows & 0x7fe) != geo->rows) ||
1645 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1646 ((geo->rows & 0x3fe) != geo->rows)) ) {
1648 "%s: ioctl: %d: rows too large or not even.\n",
1649 bktr_name(bktr), geo->rows);
1653 if (geo->frames > 32) {
1654 kprintf("%s: ioctl: too many frames.\n",
1663 bktr->dma_prog_loaded = FALSE;
1664 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1666 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1668 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1669 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1671 /* meteor_mem structure for SYNC Capture */
1672 if (geo->frames > 1) temp += PAGE_SIZE;
1675 if ((int) temp > bktr->alloc_pages
1676 && bktr->video.addr == 0) {
1678 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1680 kmem_free(&kernel_map, bktr->bigbuf,
1681 (bktr->alloc_pages * PAGE_SIZE));
1684 bktr->alloc_pages = temp;
1687 "%s: ioctl: Allocating %d bytes\n",
1688 bktr_name(bktr), temp*PAGE_SIZE);
1698 bktr->rows = geo->rows;
1699 bktr->cols = geo->columns;
1700 bktr->frames = geo->frames;
1702 /* Pixel format (if in meteor pixfmt compatibility mode) */
1703 if ( bktr->pixfmt_compat ) {
1704 bktr->format = METEOR_GEO_YUV_422;
1705 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1706 case 0: /* default */
1707 case METEOR_GEO_RGB16:
1708 bktr->format = METEOR_GEO_RGB16;
1710 case METEOR_GEO_RGB24:
1711 bktr->format = METEOR_GEO_RGB24;
1713 case METEOR_GEO_YUV_422:
1714 bktr->format = METEOR_GEO_YUV_422;
1715 if (geo->oformat & METEOR_GEO_YUV_12)
1716 bktr->format = METEOR_GEO_YUV_12;
1718 case METEOR_GEO_YUV_PACKED:
1719 bktr->format = METEOR_GEO_YUV_PACKED;
1722 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1725 if (bktr->flags & METEOR_CAP_MASK) {
1727 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1728 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1729 case METEOR_ONLY_ODD_FIELDS:
1730 bktr->flags |= METEOR_WANT_ODD;
1732 case METEOR_ONLY_EVEN_FIELDS:
1733 bktr->flags |= METEOR_WANT_EVEN;
1736 bktr->flags |= METEOR_WANT_MASK;
1740 start_capture(bktr, METEOR_CONTIN);
1741 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1742 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1743 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1744 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1750 /* end of METEORSETGEO */
1752 /* FIXME. The Capture Area currently has the following restrictions:
1754 y_offset may need to be even in interlaced modes
1755 RGB24 - Interlaced mode
1756 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1757 y_size must be greater than or equal to METEORSETGEO height (rows)
1758 RGB24 - Even Only (or Odd Only) mode
1759 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1760 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1761 YUV12 - Interlaced mode
1762 x_size must be greater than or equal to METEORSETGEO width (cols)
1763 y_size must be greater than or equal to METEORSETGEO height (rows)
1764 YUV12 - Even Only (or Odd Only) mode
1765 x_size must be greater than or equal to METEORSETGEO width (cols)
1766 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1769 case BT848_SCAPAREA: /* set capture area of each video frame */
1770 /* can't change parameters while capturing */
1771 if (bktr->flags & METEOR_CAP_MASK)
1774 cap_area = (struct bktr_capture_area *) arg;
1775 bktr->capture_area_x_offset = cap_area->x_offset;
1776 bktr->capture_area_y_offset = cap_area->y_offset;
1777 bktr->capture_area_x_size = cap_area->x_size;
1778 bktr->capture_area_y_size = cap_area->y_size;
1779 bktr->capture_area_enabled = TRUE;
1781 bktr->dma_prog_loaded = FALSE;
1784 case BT848_GCAPAREA: /* get capture area of each video frame */
1785 cap_area = (struct bktr_capture_area *) arg;
1786 if (bktr->capture_area_enabled == FALSE) {
1787 cap_area->x_offset = 0;
1788 cap_area->y_offset = 0;
1789 cap_area->x_size = format_params[
1790 bktr->format_params].scaled_hactive;
1791 cap_area->y_size = format_params[
1792 bktr->format_params].vactive;
1794 cap_area->x_offset = bktr->capture_area_x_offset;
1795 cap_area->y_offset = bktr->capture_area_y_offset;
1796 cap_area->x_size = bktr->capture_area_x_size;
1797 cap_area->y_size = bktr->capture_area_y_size;
1802 return common_ioctl( bktr, cmd, arg );
1812 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1815 unsigned int temp, temp1;
1828 /* Read the last key pressed by the Remote Control */
1829 if (bktr->remote_control == 0) return (EINVAL);
1830 remote_read(bktr, (struct bktr_remote *)arg);
1833 #if defined( TUNER_AFC )
1834 case TVTUNER_SETAFC:
1835 bktr->tuner.afc = (*(int *)arg != 0);
1838 case TVTUNER_GETAFC:
1839 *(int *)arg = bktr->tuner.afc;
1840 /* XXX Perhaps use another bit to indicate AFC success? */
1842 #endif /* TUNER_AFC */
1844 case TVTUNER_SETCHNL:
1845 temp_mute( bktr, TRUE );
1846 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1848 temp_mute( bktr, FALSE );
1851 *(unsigned long *)arg = temp;
1853 /* after every channel change, we must restart the MSP34xx */
1854 /* audio chip to reselect NICAM STEREO or MONO audio */
1855 if ( bktr->card.msp3400c )
1856 msp_autodetect( bktr );
1858 /* after every channel change, we must restart the DPL35xx */
1859 if ( bktr->card.dpl3518a )
1860 dpl_autodetect( bktr );
1862 temp_mute( bktr, FALSE );
1865 case TVTUNER_GETCHNL:
1866 *(unsigned long *)arg = bktr->tuner.channel;
1869 case TVTUNER_SETTYPE:
1870 temp = *(unsigned long *)arg;
1871 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1873 bktr->tuner.chnlset = temp;
1876 case TVTUNER_GETTYPE:
1877 *(unsigned long *)arg = bktr->tuner.chnlset;
1880 case TVTUNER_GETSTATUS:
1881 temp = get_tuner_status( bktr );
1882 *(unsigned long *)arg = temp & 0xff;
1885 case TVTUNER_SETFREQ:
1886 temp_mute( bktr, TRUE );
1887 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1888 temp_mute( bktr, FALSE );
1890 temp_mute( bktr, FALSE );
1893 *(unsigned long *)arg = temp;
1895 /* after every channel change, we must restart the MSP34xx */
1896 /* audio chip to reselect NICAM STEREO or MONO audio */
1897 if ( bktr->card.msp3400c )
1898 msp_autodetect( bktr );
1900 /* after every channel change, we must restart the DPL35xx */
1901 if ( bktr->card.dpl3518a )
1902 dpl_autodetect( bktr );
1904 temp_mute( bktr, FALSE );
1907 case TVTUNER_GETFREQ:
1908 *(unsigned long *)arg = bktr->tuner.frequency;
1911 case TVTUNER_GETCHNLSET:
1912 return tuner_getchnlset((struct bktr_chnlset *)arg);
1914 case BT848_SAUDIO: /* set audio channel */
1915 if ( set_audio( bktr, *(int*)arg ) < 0 )
1919 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1920 case BT848_SHUE: /* set hue */
1921 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1924 case BT848_GHUE: /* get hue */
1925 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1928 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1929 case BT848_SBRIG: /* set brightness */
1930 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1933 case BT848_GBRIG: /* get brightness */
1934 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1938 case BT848_SCSAT: /* set chroma saturation */
1939 tmp_int = *(int*)arg;
1941 temp = INB(bktr, BKTR_E_CONTROL);
1942 temp1 = INB(bktr, BKTR_O_CONTROL);
1943 if ( tmp_int & BIT_EIGHT_HIGH ) {
1944 temp |= (BT848_E_CONTROL_SAT_U_MSB |
1945 BT848_E_CONTROL_SAT_V_MSB);
1946 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1947 BT848_O_CONTROL_SAT_V_MSB);
1950 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1951 BT848_E_CONTROL_SAT_V_MSB);
1952 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1953 BT848_O_CONTROL_SAT_V_MSB);
1956 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1957 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1958 OUTB(bktr, BKTR_E_CONTROL, temp);
1959 OUTB(bktr, BKTR_O_CONTROL, temp1);
1962 case BT848_GCSAT: /* get chroma saturation */
1963 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1964 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1965 tmp_int |= BIT_EIGHT_HIGH;
1966 *(int*)arg = tmp_int;
1970 case BT848_SVSAT: /* set chroma V saturation */
1971 tmp_int = *(int*)arg;
1973 temp = INB(bktr, BKTR_E_CONTROL);
1974 temp1 = INB(bktr, BKTR_O_CONTROL);
1975 if ( tmp_int & BIT_EIGHT_HIGH) {
1976 temp |= BT848_E_CONTROL_SAT_V_MSB;
1977 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1980 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1981 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1984 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1985 OUTB(bktr, BKTR_E_CONTROL, temp);
1986 OUTB(bktr, BKTR_O_CONTROL, temp1);
1989 case BT848_GVSAT: /* get chroma V saturation */
1990 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1991 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1992 tmp_int |= BIT_EIGHT_HIGH;
1993 *(int*)arg = tmp_int;
1997 case BT848_SUSAT: /* set chroma U saturation */
1998 tmp_int = *(int*)arg;
2000 temp = INB(bktr, BKTR_E_CONTROL);
2001 temp1 = INB(bktr, BKTR_O_CONTROL);
2002 if ( tmp_int & BIT_EIGHT_HIGH ) {
2003 temp |= BT848_E_CONTROL_SAT_U_MSB;
2004 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2007 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2008 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2011 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2012 OUTB(bktr, BKTR_E_CONTROL, temp);
2013 OUTB(bktr, BKTR_O_CONTROL, temp1);
2016 case BT848_GUSAT: /* get chroma U saturation */
2017 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2018 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2019 tmp_int |= BIT_EIGHT_HIGH;
2020 *(int*)arg = tmp_int;
2023 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2025 case BT848_SLNOTCH: /* set luma notch */
2026 tmp_int = (*(int *)arg & 0x7) << 5 ;
2027 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2028 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2029 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2030 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2033 case BT848_GLNOTCH: /* get luma notch */
2034 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2039 case BT848_SCONT: /* set contrast */
2040 tmp_int = *(int*)arg;
2042 temp = INB(bktr, BKTR_E_CONTROL);
2043 temp1 = INB(bktr, BKTR_O_CONTROL);
2044 if ( tmp_int & BIT_EIGHT_HIGH ) {
2045 temp |= BT848_E_CONTROL_CON_MSB;
2046 temp1 |= BT848_O_CONTROL_CON_MSB;
2049 temp &= ~BT848_E_CONTROL_CON_MSB;
2050 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2053 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2054 OUTB(bktr, BKTR_E_CONTROL, temp);
2055 OUTB(bktr, BKTR_O_CONTROL, temp1);
2058 case BT848_GCONT: /* get contrast */
2059 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2060 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2061 tmp_int |= BIT_EIGHT_HIGH;
2062 *(int*)arg = tmp_int;
2065 /* FIXME: SCBARS and CCBARS require a valid int * */
2066 /* argument to succeed, but its not used; consider */
2067 /* using the arg to store the on/off state so */
2068 /* there's only one ioctl() needed to turn cbars on/off */
2069 case BT848_SCBARS: /* set colorbar output */
2070 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2073 case BT848_CCBARS: /* clear colorbar output */
2074 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2077 case BT848_GAUDIO: /* get audio channel */
2078 temp = bktr->audio_mux_select;
2079 if ( bktr->audio_mute_state == TRUE )
2084 case BT848_SBTSC: /* set audio channel */
2085 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2089 case BT848_WEEPROM: /* write eeprom */
2090 offset = (((struct eeProm *)arg)->offset);
2091 count = (((struct eeProm *)arg)->count);
2092 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2093 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2097 case BT848_REEPROM: /* read eeprom */
2098 offset = (((struct eeProm *)arg)->offset);
2099 count = (((struct eeProm *)arg)->count);
2100 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2101 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2105 case BT848_SIGNATURE:
2106 offset = (((struct eeProm *)arg)->offset);
2107 count = (((struct eeProm *)arg)->count);
2108 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2109 if ( signCard( bktr, offset, count, buf ) < 0 )
2113 /* Ioctl's for direct gpio access */
2114 #ifdef BKTR_GPIO_ACCESS
2115 case BT848_GPIO_GET_EN:
2116 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2119 case BT848_GPIO_SET_EN:
2120 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2123 case BT848_GPIO_GET_DATA:
2124 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2127 case BT848_GPIO_SET_DATA:
2128 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2130 #endif /* BKTR_GPIO_ACCESS */
2132 /* Ioctl's for running the tuner device in radio mode */
2135 *(unsigned char *)arg = bktr->tuner.radio_mode;
2139 bktr->tuner.radio_mode = *(unsigned char *)arg;
2143 *(unsigned long *)arg = bktr->tuner.frequency;
2147 /* The argument to this ioctl is NOT freq*16. It is
2151 temp=(int)*(unsigned long *)arg;
2153 #ifdef BKTR_RADIO_DEBUG
2154 kprintf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2155 (int)*(unsigned long *)arg, temp);
2158 #ifndef BKTR_RADIO_NOFREQCHECK
2159 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2161 if(temp<8750 || temp>10800) {
2162 kprintf("%s: Radio frequency out of range\n", bktr_name(bktr));
2166 temp_mute( bktr, TRUE );
2167 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2168 temp_mute( bktr, FALSE );
2169 #ifdef BKTR_RADIO_DEBUG
2171 kprintf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2175 *(unsigned long *)arg = temp;
2178 /* Luigi's I2CWR ioctl */
2180 par = *(u_long *)arg;
2181 write = (par >> 24) & 0xff ;
2182 i2c_addr = (par >> 16) & 0xff ;
2183 i2c_port = (par >> 8) & 0xff ;
2184 data = (par) & 0xff ;
2187 i2cWrite( bktr, i2c_addr, i2c_port, data);
2189 data = i2cRead( bktr, i2c_addr);
2191 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2195 #ifdef BT848_MSP_READ
2196 /* I2C ioctls to allow userland access to the MSP chip */
2197 case BT848_MSP_READ:
2199 struct bktr_msp_control *msp;
2200 msp = (struct bktr_msp_control *) arg;
2201 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2202 msp->function, msp->address);
2206 case BT848_MSP_WRITE:
2208 struct bktr_msp_control *msp;
2209 msp = (struct bktr_msp_control *) arg;
2210 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2211 msp->address, msp->data );
2215 case BT848_MSP_RESET:
2216 msp_dpl_reset(bktr, bktr->msp_addr);
2221 return common_ioctl( bktr, cmd, arg );
2232 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2236 struct meteor_pixfmt *pf_pub;
2240 case METEORSINPUT: /* set input device */
2241 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2242 /* On the original bt848 boards, */
2243 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2244 /* On the Hauppauge bt878 boards, */
2245 /* Tuner is MUX0, RCA is MUX3 */
2246 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2247 /* stick with this system in our Meteor Emulation */
2249 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2251 /* this is the RCA video input */
2252 case 0: /* default */
2253 case METEOR_INPUT_DEV0:
2254 /* METEOR_INPUT_DEV_RCA: */
2255 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2257 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2258 & ~BT848_IFORM_MUXSEL);
2260 /* work around for new Hauppauge 878 cards */
2261 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2262 (bktr->id==BROOKTREE_878 ||
2263 bktr->id==BROOKTREE_879) )
2264 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2266 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2268 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2269 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2270 set_audio( bktr, AUDIO_EXTERN );
2273 /* this is the tuner input */
2274 case METEOR_INPUT_DEV1:
2275 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2277 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2278 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2279 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2280 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2281 set_audio( bktr, AUDIO_TUNER );
2284 /* this is the S-VHS input, but with a composite camera */
2285 case METEOR_INPUT_DEV2:
2286 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2288 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2289 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2290 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2291 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2292 set_audio( bktr, AUDIO_EXTERN );
2295 /* this is the S-VHS input */
2296 case METEOR_INPUT_DEV_SVIDEO:
2297 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2298 | METEOR_DEV_SVIDEO;
2299 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2300 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2301 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2302 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2303 set_audio( bktr, AUDIO_EXTERN );
2306 case METEOR_INPUT_DEV3:
2307 if ((bktr->id == BROOKTREE_848A) ||
2308 (bktr->id == BROOKTREE_849A) ||
2309 (bktr->id == BROOKTREE_878) ||
2310 (bktr->id == BROOKTREE_879) ) {
2311 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2313 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2315 /* work around for new Hauppauge 878 cards */
2316 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2317 (bktr->id==BROOKTREE_878 ||
2318 bktr->id==BROOKTREE_879) )
2319 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2321 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2323 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2324 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2325 set_audio( bktr, AUDIO_EXTERN );
2335 case METEORGINPUT: /* get input device */
2336 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2339 case METEORSACTPIXFMT:
2340 if (( *(int *)arg < 0 ) ||
2341 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2344 bktr->pixfmt = *(int *)arg;
2345 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2346 | pixfmt_swap_flags( bktr->pixfmt ));
2347 bktr->pixfmt_compat = FALSE;
2350 case METEORGACTPIXFMT:
2351 *(int *)arg = bktr->pixfmt;
2354 case METEORGSUPPIXFMT :
2355 pf_pub = (struct meteor_pixfmt *)arg;
2356 pixfmt = pf_pub->index;
2358 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2361 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2362 sizeof( *pf_pub ) );
2364 /* Patch in our format index */
2365 pf_pub->index = pixfmt;
2368 #if defined( STATUS_SUM )
2369 case BT848_GSTATUS: /* reap status */
2375 *(u_int*)arg = temp;
2378 #endif /* STATUS_SUM */
2390 /******************************************************************************
2391 * bt848 RISC programming routines:
2400 dump_bt848( bktr_ptr_t bktr )
2403 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2404 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2405 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2406 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2407 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2412 for (i = 0; i < 40; i+=4) {
2413 kprintf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2415 r[i], INL(bktr, r[i]),
2416 r[i+1], INL(bktr, r[i+1]),
2417 r[i+2], INL(bktr, r[i+2]),
2418 r[i+3], INL(bktr, r[i+3]]));
2421 kprintf("%s: INT STAT %x \n", bktr_name(bktr),
2422 INL(bktr, BKTR_INT_STAT));
2423 kprintf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2424 INL(bktr, BKTR_INT_MASK));
2425 kprintf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2426 INW(bktr, BKTR_GPIO_DMA_CTL));
2434 * build write instruction
2436 #define BKTR_FM1 0x6 /* packed data to follow */
2437 #define BKTR_FM3 0xe /* planar data to follow */
2438 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2439 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2440 #define BKTR_PXV 0x0 /* valid word (never used) */
2441 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2442 #define BKTR_SOL 0x2 /* first dword */
2444 #define OP_WRITE (0x1 << 28)
2445 #define OP_SKIP (0x2 << 28)
2446 #define OP_WRITEC (0x5 << 28)
2447 #define OP_JUMP (0x7 << 28)
2448 #define OP_SYNC (0x8 << 28)
2449 #define OP_WRITE123 (0x9 << 28)
2450 #define OP_WRITES123 (0xb << 28)
2451 #define OP_SOL (1 << 27) /* first instr for scanline */
2452 #define OP_EOL (1 << 26)
2454 #define BKTR_RESYNC (1 << 15)
2455 #define BKTR_GEN_IRQ (1 << 24)
2458 * The RISC status bits can be set/cleared in the RISC programs
2459 * and tested in the Interrupt Handler
2461 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2462 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2463 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2464 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2466 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2467 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2468 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2469 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2471 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2472 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2473 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2474 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2476 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2478 bktr_clip_t * clip_node;
2479 bktr->clip_start = -1;
2483 bktr->line_length = width;
2486 bktr->current_col = 0;
2488 if (bktr->max_clip_node == 0 ) return TRUE;
2489 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2492 for (i = 0; i < bktr->max_clip_node; i++ ) {
2493 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2494 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2495 bktr->clip_start = i;
2503 static bool_t getline(bktr_reg_t *bktr, int x ) {
2505 bktr_clip_t * clip_node ;
2507 if (bktr->line_length == 0 ||
2508 bktr->current_col >= bktr->line_length) return FALSE;
2510 bktr->y = min(bktr->last_y, bktr->line_length);
2511 bktr->y2 = bktr->line_length;
2513 bktr->yclip = bktr->yclip2 = -1;
2514 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2515 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2516 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2517 if (bktr->last_y <= clip_node->y_min) {
2518 bktr->y = min(bktr->last_y, bktr->line_length);
2519 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2520 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2521 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2522 bktr->last_y = bktr->yclip2;
2523 bktr->clip_start = i;
2525 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2526 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2527 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2528 if (bktr->last_y >= clip_node->y_min) {
2529 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2530 bktr->last_y = bktr->yclip2;
2531 bktr->clip_start = j;
2540 if (bktr->current_col <= bktr->line_length) {
2541 bktr->current_col = bktr->line_length;
2547 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2548 u_long operation, int pixel_width,
2549 volatile u_char ** target_buffer, int cols ) {
2552 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2553 u_int skip, start_skip;
2555 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2556 /* to the 1st byte in the mem dword containing our start addr. */
2557 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2560 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2561 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2562 case 2 : start_skip = 4 ; break;
2563 case 1 : start_skip = 8 ; break;
2566 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2567 if ( width == cols) {
2568 flag = OP_SOL | OP_EOL;
2569 } else if (bktr->current_col == 0 ) {
2571 } else if (bktr->current_col == cols) {
2576 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2577 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2582 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2583 if (operation != OP_SKIP )
2584 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2586 *target_buffer += width * pixel_width;
2587 bktr->current_col += width;
2591 if (bktr->current_col == 0 && width == cols) {
2594 } else if (bktr->current_col == 0 ) {
2597 } else if (bktr->current_col >= cols) {
2606 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2607 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2612 *(*dma_prog)++ = operation | flag |
2613 (width * pixel_width / 2 - skip);
2614 if (operation != OP_SKIP )
2615 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2616 *target_buffer += (width * pixel_width / 2) ;
2618 if ( operation == OP_WRITE )
2619 operation = OP_WRITEC;
2620 *(*dma_prog)++ = operation | flag2 |
2621 (width * pixel_width / 2);
2622 *target_buffer += (width * pixel_width / 2) ;
2623 bktr->current_col += width;
2631 * Generate the RISC instructions to capture both VBI and video images
2634 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2637 volatile uint32_t target_buffer, buffer, target,width;
2638 volatile uint32_t pitch;
2639 volatile uint32_t *dma_prog; /* DMA prog is an array of
2640 32 bit RISC instructions */
2641 volatile uint32_t *loop_point;
2642 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2643 u_int Bpp = pf_int->public.Bpp;
2644 unsigned int vbisamples; /* VBI samples per line */
2645 unsigned int vbilines; /* VBI lines per field */
2646 unsigned int num_dwords; /* DWORDS per line */
2648 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2649 vbilines = format_params[bktr->format_params].vbi_num_lines;
2650 num_dwords = vbisamples/4;
2652 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2653 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2654 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2655 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2658 OUTB(bktr, BKTR_OFORM, 0x00);
2660 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2661 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2662 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2663 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2665 /* disable gamma correction removal */
2666 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2669 OUTB(bktr, BKTR_E_VTC, 0);
2670 OUTB(bktr, BKTR_O_VTC, 0);
2672 OUTB(bktr, BKTR_E_VTC, 1);
2673 OUTB(bktr, BKTR_O_VTC, 1);
2675 bktr->capcontrol = 3 << 2 | 3;
2677 dma_prog = (uint32_t *) bktr->dma_prog;
2679 /* Construct Write */
2681 if (bktr->video.addr) {
2682 target_buffer = (u_long) bktr->video.addr;
2683 pitch = bktr->video.width;
2686 target_buffer = (u_long) vtophys(bktr->bigbuf);
2690 buffer = target_buffer;
2692 /* Wait for the VRE sync marking the end of the Even and
2693 * the start of the Odd field. Resync here.
2695 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2698 loop_point = dma_prog;
2700 /* store the VBI data */
2701 /* look for sync with packed data */
2702 *dma_prog++ = OP_SYNC | BKTR_FM1;
2704 for(i = 0; i < vbilines; i++) {
2705 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2706 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2707 (i * VBI_LINE_SIZE));
2710 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2711 /* store the Odd field video image */
2712 /* look for sync with packed data */
2713 *dma_prog++ = OP_SYNC | BKTR_FM1;
2714 *dma_prog++ = 0; /* NULL WORD */
2716 for (i = 0; i < (rows/interlace); i++) {
2717 target = target_buffer;
2718 if ( notclipped(bktr, i, width)) {
2719 split(bktr, (volatile uint32_t **) &dma_prog,
2720 bktr->y2 - bktr->y, OP_WRITE,
2721 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2724 while(getline(bktr, i)) {
2725 if (bktr->y != bktr->y2 ) {
2726 split(bktr, (volatile uint32_t **) &dma_prog,
2727 bktr->y2 - bktr->y, OP_WRITE,
2728 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2730 if (bktr->yclip != bktr->yclip2 ) {
2731 split(bktr,(volatile uint32_t **) &dma_prog,
2732 bktr->yclip2 - bktr->yclip,
2734 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2740 target_buffer += interlace * pitch;
2746 /* Grab the Even field */
2747 /* Look for the VRO, end of Odd field, marker */
2748 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2749 *dma_prog++ = 0; /* NULL WORD */
2751 /* store the VBI data */
2752 /* look for sync with packed data */
2753 *dma_prog++ = OP_SYNC | BKTR_FM1;
2755 for(i = 0; i < vbilines; i++) {
2756 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2757 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2758 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2761 /* store the video image */
2762 if (i_flag == 1) /*Even Only*/
2763 target_buffer = buffer;
2764 if (i_flag == 3) /*interlaced*/
2765 target_buffer = buffer+pitch;
2768 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2769 /* look for sync with packed data */
2770 *dma_prog++ = OP_SYNC | BKTR_FM1;
2771 *dma_prog++ = 0; /* NULL WORD */
2773 for (i = 0; i < (rows/interlace); i++) {
2774 target = target_buffer;
2775 if ( notclipped(bktr, i, width)) {
2776 split(bktr, (volatile uint32_t **) &dma_prog,
2777 bktr->y2 - bktr->y, OP_WRITE,
2778 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2780 while(getline(bktr, i)) {
2781 if (bktr->y != bktr->y2 ) {
2782 split(bktr, (volatile uint32_t **) &dma_prog,
2783 bktr->y2 - bktr->y, OP_WRITE,
2784 Bpp, (volatile u_char **)(uintptr_t)&target,
2787 if (bktr->yclip != bktr->yclip2 ) {
2788 split(bktr, (volatile uint32_t **) &dma_prog,
2789 bktr->yclip2 - bktr->yclip, OP_SKIP,
2790 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2797 target_buffer += interlace * pitch;
2802 /* Look for end of 'Even Field' */
2803 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2804 *dma_prog++ = 0; /* NULL WORD */
2806 *dma_prog++ = OP_JUMP ;
2807 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2808 *dma_prog++ = 0; /* NULL WORD */
2816 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2819 volatile uint32_t target_buffer, buffer, target,width;
2820 volatile uint32_t pitch;
2821 volatile uint32_t *dma_prog;
2822 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2823 u_int Bpp = pf_int->public.Bpp;
2825 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2826 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2827 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2828 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2830 OUTB(bktr, BKTR_OFORM, 0x00);
2832 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2833 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2834 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2835 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2837 /* disable gamma correction removal */
2838 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2841 OUTB(bktr, BKTR_E_VTC, 0);
2842 OUTB(bktr, BKTR_O_VTC, 0);
2844 OUTB(bktr, BKTR_E_VTC, 1);
2845 OUTB(bktr, BKTR_O_VTC, 1);
2847 bktr->capcontrol = 3 << 2 | 3;
2849 dma_prog = (uint32_t *) bktr->dma_prog;
2851 /* Construct Write */
2853 if (bktr->video.addr) {
2854 target_buffer = (uint32_t) bktr->video.addr;
2855 pitch = bktr->video.width;
2858 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2862 buffer = target_buffer;
2864 /* contruct sync : for video packet format */
2865 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2867 /* sync, mode indicator packed data */
2868 *dma_prog++ = 0; /* NULL WORD */
2870 for (i = 0; i < (rows/interlace); i++) {
2871 target = target_buffer;
2872 if ( notclipped(bktr, i, width)) {
2873 split(bktr, (volatile uint32_t **) &dma_prog,
2874 bktr->y2 - bktr->y, OP_WRITE,
2875 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2878 while(getline(bktr, i)) {
2879 if (bktr->y != bktr->y2 ) {
2880 split(bktr, (volatile uint32_t **) &dma_prog,
2881 bktr->y2 - bktr->y, OP_WRITE,
2882 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2884 if (bktr->yclip != bktr->yclip2 ) {
2885 split(bktr,(volatile uint32_t **) &dma_prog,
2886 bktr->yclip2 - bktr->yclip,
2888 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2894 target_buffer += interlace * pitch;
2901 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2902 *dma_prog++ = 0; /* NULL WORD */
2904 *dma_prog++ = OP_JUMP;
2905 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2910 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2911 *dma_prog++ = 0; /* NULL WORD */
2913 *dma_prog++ = OP_JUMP;
2914 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2919 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2920 *dma_prog++ = 0; /* NULL WORD */
2921 *dma_prog++ = OP_JUMP;
2922 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
2926 if (interlace == 2) {
2928 target_buffer = buffer + pitch;
2930 dma_prog = (uint32_t *) bktr->odd_dma_prog;
2932 /* sync vre IRQ bit */
2933 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2934 *dma_prog++ = 0; /* NULL WORD */
2936 for (i = 0; i < (rows/interlace); i++) {
2937 target = target_buffer;
2938 if ( notclipped(bktr, i, width)) {
2939 split(bktr, (volatile uint32_t **) &dma_prog,
2940 bktr->y2 - bktr->y, OP_WRITE,
2941 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2943 while(getline(bktr, i)) {
2944 if (bktr->y != bktr->y2 ) {
2945 split(bktr, (volatile uint32_t **) &dma_prog,
2946 bktr->y2 - bktr->y, OP_WRITE,
2947 Bpp, (volatile u_char **)(uintptr_t)&target,
2950 if (bktr->yclip != bktr->yclip2 ) {
2951 split(bktr, (volatile uint32_t **) &dma_prog,
2952 bktr->yclip2 - bktr->yclip, OP_SKIP,
2953 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2960 target_buffer += interlace * pitch;
2965 /* sync vre IRQ bit */
2966 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2967 *dma_prog++ = 0; /* NULL WORD */
2968 *dma_prog++ = OP_JUMP ;
2969 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
2970 *dma_prog++ = 0; /* NULL WORD */
2978 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2979 int cols, int rows, int interlace )
2982 volatile unsigned int inst;
2983 volatile unsigned int inst3;
2984 volatile uint32_t target_buffer, buffer;
2985 volatile uint32_t *dma_prog;
2986 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2989 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2991 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
2992 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2994 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
2995 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2997 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
2998 bktr->capcontrol = 3 << 2 | 3;
3000 dma_prog = (uint32_t *) bktr->dma_prog;
3002 /* Construct Write */
3004 /* write , sol, eol */
3005 inst = OP_WRITE | OP_SOL | (cols);
3006 /* write , sol, eol */
3007 inst3 = OP_WRITE | OP_EOL | (cols);
3009 if (bktr->video.addr)
3010 target_buffer = (uint32_t) bktr->video.addr;
3012 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3014 buffer = target_buffer;
3016 /* contruct sync : for video packet format */
3017 /* sync, mode indicator packed data */
3018 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3019 *dma_prog++ = 0; /* NULL WORD */
3023 for (i = 0; i < (rows/interlace); i++) {
3025 *dma_prog++ = target_buffer;
3026 *dma_prog++ = inst3;
3027 *dma_prog++ = target_buffer + b;
3028 target_buffer += interlace*(cols * 2);
3034 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3035 *dma_prog++ = 0; /* NULL WORD */
3037 *dma_prog++ = OP_JUMP;
3038 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3043 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3044 *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_RESYNC | BKTR_VRO;
3052 *dma_prog++ = 0; /* NULL WORD */
3053 *dma_prog++ = OP_JUMP ;
3054 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3058 if (interlace == 2) {
3060 target_buffer = (uint32_t) buffer + cols*2;
3062 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3065 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3066 *dma_prog++ = 0; /* NULL WORD */
3068 for (i = 0; i < (rows/interlace) ; i++) {
3070 *dma_prog++ = target_buffer;
3071 *dma_prog++ = inst3;
3072 *dma_prog++ = target_buffer + b;
3073 target_buffer += interlace * ( cols*2);
3077 /* sync vro IRQ bit */
3078 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3079 *dma_prog++ = 0; /* NULL WORD */
3080 *dma_prog++ = OP_JUMP ;
3081 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3083 *dma_prog++ = OP_JUMP;
3084 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3085 *dma_prog++ = 0; /* NULL WORD */
3093 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3094 int cols, int rows, int interlace ){
3097 volatile unsigned int inst;
3098 volatile uint32_t target_buffer, t1, buffer;
3099 volatile uint32_t *dma_prog;
3100 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3102 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3104 dma_prog = (uint32_t*) bktr->dma_prog;
3106 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3108 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3109 OUTB(bktr, BKTR_OFORM, 0x00);
3111 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3112 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3114 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3115 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3117 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3118 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3119 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3120 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3122 /* disable gamma correction removal */
3123 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3125 /* Construct Write */
3126 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3127 if (bktr->video.addr)
3128 target_buffer = (uint32_t) bktr->video.addr;
3130 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3132 buffer = target_buffer;
3136 /* contruct sync : for video packet format */
3137 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3138 *dma_prog++ = 0; /* NULL WORD */
3140 for (i = 0; i < (rows/interlace ) ; i++) {
3142 *dma_prog++ = cols/2 | cols/2 << 16;
3143 *dma_prog++ = target_buffer;
3144 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3145 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3146 target_buffer += interlace*cols;
3151 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3152 *dma_prog++ = 0; /* NULL WORD */
3154 *dma_prog++ = OP_JUMP ;
3155 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3159 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*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 | 1 << 15 | BKTR_VRO;
3168 *dma_prog++ = 0; /* NULL WORD */
3170 *dma_prog++ = OP_JUMP ;
3171 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3175 if (interlace == 2) {
3177 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3179 target_buffer = (uint32_t) buffer + cols;
3180 t1 = buffer + cols/2;
3181 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3182 *dma_prog++ = 0; /* NULL WORD */
3184 for (i = 0; i < (rows/interlace ) ; i++) {
3186 *dma_prog++ = cols/2 | cols/2 << 16;
3187 *dma_prog++ = target_buffer;
3188 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3189 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3190 target_buffer += interlace*cols;
3194 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3195 *dma_prog++ = 0; /* NULL WORD */
3196 *dma_prog++ = OP_JUMP ;
3197 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3198 *dma_prog++ = 0; /* NULL WORD */
3206 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3207 int cols, int rows, int interlace ){
3210 volatile unsigned int inst;
3211 volatile unsigned int inst1;
3212 volatile uint32_t target_buffer, t1, buffer;
3213 volatile uint32_t *dma_prog;
3214 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3216 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3218 dma_prog = (uint32_t *) bktr->dma_prog;
3220 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3222 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3223 OUTB(bktr, BKTR_OFORM, 0x0);
3225 /* Construct Write */
3226 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3227 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3228 if (bktr->video.addr)
3229 target_buffer = (uint32_t) bktr->video.addr;
3231 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3233 buffer = target_buffer;
3236 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3237 *dma_prog++ = 0; /* NULL WORD */
3239 for (i = 0; i < (rows/interlace )/2 ; i++) {
3241 *dma_prog++ = cols/2 | (cols/2 << 16);
3242 *dma_prog++ = target_buffer;
3243 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3244 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3245 target_buffer += interlace*cols;
3246 *dma_prog++ = inst1;
3247 *dma_prog++ = cols/2 | (cols/2 << 16);
3248 *dma_prog++ = target_buffer;
3249 target_buffer += interlace*cols;
3255 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3256 *dma_prog++ = 0; /* NULL WORD */
3258 *dma_prog++ = OP_JUMP;
3259 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3263 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
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 | 1 << 15 | BKTR_VRO;
3272 *dma_prog++ = 0; /* NULL WORD */
3273 *dma_prog++ = OP_JUMP ;
3274 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3278 if (interlace == 2) {
3280 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3282 target_buffer = (uint32_t) buffer + cols;
3283 t1 = buffer + cols/2;
3284 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3285 *dma_prog++ = 0; /* NULL WORD */
3287 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3289 *dma_prog++ = cols/2 | (cols/2 << 16);
3290 *dma_prog++ = target_buffer;
3291 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3292 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3293 target_buffer += interlace*cols;
3294 *dma_prog++ = inst1;
3295 *dma_prog++ = cols/2 | (cols/2 << 16);
3296 *dma_prog++ = target_buffer;
3297 target_buffer += interlace*cols;
3304 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3305 *dma_prog++ = 0; /* NULL WORD */
3306 *dma_prog++ = OP_JUMP;
3307 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3308 *dma_prog++ = 0; /* NULL WORD */
3317 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3319 int rows, cols, interlace;
3322 struct format_params *fp;
3323 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3326 fp = &format_params[bktr->format_params];
3328 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3330 /* disable FIFO & RISC, leave other bits alone */
3331 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3333 /* set video parameters */
3334 if (bktr->capture_area_enabled)
3335 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3336 / fp->scaled_htotal / bktr->cols) - 4096;
3338 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3339 / fp->scaled_htotal / bktr->cols) - 4096;
3341 /* kprintf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3342 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3343 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3344 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3345 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3347 /* horizontal active */
3349 /* kprintf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3350 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3351 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3352 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3353 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3354 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3355 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3357 /* horizontal delay */
3358 if (bktr->capture_area_enabled)
3359 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3360 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3362 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3364 temp = temp & 0x3fe;
3366 /* kprintf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3367 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3368 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3369 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3370 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3371 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3372 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3374 /* vertical scale */
3376 if (bktr->capture_area_enabled) {
3377 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3378 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3380 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3383 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3386 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3387 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3389 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3392 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3397 /* kprintf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3398 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3399 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3400 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3401 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3402 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3403 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3406 /* vertical active */
3407 if (bktr->capture_area_enabled)
3408 temp = bktr->capture_area_y_size;
3411 /* kprintf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3412 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3413 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3414 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3415 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3416 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3417 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3419 /* vertical delay */
3420 if (bktr->capture_area_enabled)
3421 temp = fp->vdelay + (bktr->capture_area_y_offset);
3424 /* kprintf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3425 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3426 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3427 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3428 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3429 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3430 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3432 /* end of video params */
3434 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3435 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3436 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3438 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3441 /* capture control */
3444 bktr->bktr_cap_ctl =
3445 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3446 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3447 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3451 bktr->bktr_cap_ctl =
3452 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3453 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3454 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3458 bktr->bktr_cap_ctl =
3459 (BT848_CAP_CTL_DITH_FRAME |
3460 BT848_CAP_CTL_EVEN | 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);
3467 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3472 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3474 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3475 /* user, then use the rgb_vbi RISC program. */
3476 /* Otherwise, use the normal rgb RISC program */
3477 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3478 if ( (bktr->vbiflags & VBI_OPEN)
3479 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3480 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3482 bktr->bktr_cap_ctl |=
3483 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3484 bktr->vbiflags |= VBI_CAPTURE;
3485 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3488 rgb_prog(bktr, i_flag, cols, rows, interlace);
3493 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3494 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3495 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3496 | pixfmt_swap_flags( bktr->pixfmt ));
3500 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3501 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3502 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3503 | pixfmt_swap_flags( bktr->pixfmt ));
3507 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3508 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3509 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3510 | pixfmt_swap_flags( bktr->pixfmt ));
3517 /******************************************************************************
3518 * video & video capture specific routines:
3526 start_capture( bktr_ptr_t bktr, unsigned type )
3529 struct format_params *fp;
3531 fp = &format_params[bktr->format_params];
3533 /* If requested, clear out capture buf first */
3534 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3535 bzero((caddr_t)bktr->bigbuf,
3536 (size_t)bktr->rows * bktr->cols * bktr->frames *
3537 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3540 OUTB(bktr, BKTR_DSTATUS, 0);
3541 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3543 bktr->flags |= type;
3544 bktr->flags &= ~METEOR_WANT_MASK;
3545 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3546 case METEOR_ONLY_EVEN_FIELDS:
3547 bktr->flags |= METEOR_WANT_EVEN;
3550 case METEOR_ONLY_ODD_FIELDS:
3551 bktr->flags |= METEOR_WANT_ODD;
3555 bktr->flags |= METEOR_WANT_MASK;
3560 /* TDEC is only valid for continuous captures */
3561 if ( type == METEOR_SINGLE ) {
3562 u_short fps_save = bktr->fps;
3564 set_fps(bktr, fp->frame_rate);
3565 bktr->fps = fps_save;
3568 set_fps(bktr, bktr->fps);
3570 if (bktr->dma_prog_loaded == FALSE) {
3571 build_dma_prog(bktr, i_flag);
3572 bktr->dma_prog_loaded = TRUE;
3576 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3585 set_fps( bktr_ptr_t bktr, u_short fps )
3587 struct format_params *fp;
3590 fp = &format_params[bktr->format_params];
3592 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3593 case METEOR_ONLY_EVEN_FIELDS:
3594 bktr->flags |= METEOR_WANT_EVEN;
3597 case METEOR_ONLY_ODD_FIELDS:
3598 bktr->flags |= METEOR_WANT_ODD;
3602 bktr->flags |= METEOR_WANT_MASK;
3607 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3608 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3611 OUTB(bktr, BKTR_TDEC, 0);
3613 if (fps < fp->frame_rate)
3614 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3616 OUTB(bktr, BKTR_TDEC, 0);
3626 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3627 * achieve the specified swapping.
3628 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3629 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3631 * Note also that for 3Bpp, we may additionally need to do some creative
3632 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3633 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3634 * as one would expect.
3637 static u_int pixfmt_swap_flags( int pixfmt )
3639 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3642 switch ( pf->Bpp ) {
3643 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3646 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3649 case 4 : if ( pf->swap_bytes )
3650 swapf = pf->swap_shorts ? 0 : WSWAP;
3652 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3661 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3662 * our pixfmt_table indices.
3665 static int oformat_meteor_to_bt( u_long format )
3668 struct meteor_pixfmt *pf1, *pf2;
3670 /* Find format in compatibility table */
3671 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3672 if ( meteor_pixfmt_table[i].meteor_format == format )
3675 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3677 pf1 = &meteor_pixfmt_table[i].public;
3679 /* Match it with an entry in master pixel format table */
3680 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3681 pf2 = &pixfmt_table[i].public;
3683 if (( pf1->type == pf2->type ) &&
3684 ( pf1->Bpp == pf2->Bpp ) &&
3685 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3686 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3687 ( pf1->swap_shorts == pf2->swap_shorts ))
3690 if ( i >= PIXFMT_TABLE_SIZE )
3696 /******************************************************************************
3701 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3702 #define I2CBITTIME_878 (1 << 7)
3703 #define I2C_READ 0x01
3704 #define I2C_COMMAND (I2CBITTIME | \
3705 BT848_DATA_CTL_I2CSCL | \
3706 BT848_DATA_CTL_I2CSDA)
3708 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3709 BT848_DATA_CTL_I2CSCL | \
3710 BT848_DATA_CTL_I2CSDA)
3712 /* Select between old i2c code and new iicbus / smbus code */
3713 #if defined(BKTR_USE_FREEBSD_SMBUS)
3716 * The hardware interface is actually SMB commands
3719 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3723 if (bktr->id == BROOKTREE_848 ||
3724 bktr->id == BROOKTREE_848A ||
3725 bktr->id == BROOKTREE_849A)
3728 cmd = I2C_COMMAND_878;
3731 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3732 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3735 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3736 (char)(byte1 & 0xff)))
3745 i2cRead( bktr_ptr_t bktr, int addr )
3750 if (bktr->id == BROOKTREE_848 ||
3751 bktr->id == BROOKTREE_848A ||
3752 bktr->id == BROOKTREE_849A)
3755 cmd = I2C_COMMAND_878;
3757 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3760 return ((int)((unsigned char)result));
3763 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3765 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3766 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3767 /* Therefore we need low level control of the i2c bus hardware */
3769 /* Write to the MSP or DPL registers */
3771 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3773 unsigned char addr_l, addr_h, data_h, data_l ;
3775 addr_h = (addr >>8) & 0xff;
3776 addr_l = addr & 0xff;
3777 data_h = (data >>8) & 0xff;
3778 data_l = data & 0xff;
3780 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3782 iicbus_write_byte(IICBUS(bktr), dev, 0);
3783 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3784 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3785 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3786 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3788 iicbus_stop(IICBUS(bktr));
3793 /* Read from the MSP or DPL registers */
3795 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3798 unsigned char addr_l, addr_h, dev_r;
3800 u_char data_read[2];
3802 addr_h = (addr >>8) & 0xff;
3803 addr_l = addr & 0xff;
3806 /* XXX errors ignored */
3807 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3809 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3810 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3811 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3813 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3814 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3815 iicbus_stop(IICBUS(bktr));
3817 data = (data_read[0]<<8) | data_read[1];
3822 /* Reset the MSP or DPL chip */
3823 /* The user can block the reset (which is handy if you initialise the
3824 * MSP and/or DPL audio in another operating system first (eg in Windows)
3827 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3830 #ifndef BKTR_NO_MSP_RESET
3831 /* put into reset mode */
3832 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3833 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3834 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3835 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3836 iicbus_stop(IICBUS(bktr));
3838 /* put back to operational mode */
3839 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3840 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3841 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3842 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3843 iicbus_stop(IICBUS(bktr));
3848 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3851 /* XXX errors ignored */
3852 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3853 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3854 iicbus_stop(IICBUS(bktr));
3859 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3862 * Program the i2c bus directly
3865 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3870 /* clear status bits */
3871 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3873 /* build the command datum */
3874 if (bktr->id == BROOKTREE_848 ||
3875 bktr->id == BROOKTREE_848A ||
3876 bktr->id == BROOKTREE_849A) {
3877 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3879 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3881 if ( byte2 != -1 ) {
3882 data |= ((byte2 & 0xff) << 8);
3883 data |= BT848_DATA_CTL_I2CW3B;
3886 /* write the address and data */
3887 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3889 /* wait for completion */
3890 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3891 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3896 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3908 i2cRead( bktr_ptr_t bktr, int addr )
3912 /* clear status bits */
3913 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3915 /* write the READ address */
3916 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3918 if (bktr->id == BROOKTREE_848 ||
3919 bktr->id == BROOKTREE_848A ||
3920 bktr->id == BROOKTREE_849A) {
3921 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3923 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3926 /* wait for completion */
3927 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3928 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3933 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3937 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3940 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3941 /* bt848 automated i2c bus controller cannot handle */
3942 /* Therefore we need low level control of the i2c bus hardware */
3943 /* Idea for the following functions are from elsewhere in this driver and */
3944 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3947 static void i2c_start( bktr_ptr_t bktr) {
3948 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3949 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3950 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3951 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3954 static void i2c_stop( bktr_ptr_t bktr) {
3955 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3956 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3957 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3960 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3964 /* write out the byte */
3965 for ( x = 7; x >= 0; --x ) {
3966 if ( data & (1<<x) ) {
3967 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3968 DELAY( BITD ); /* assert HI data */
3969 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3970 DELAY( BITD ); /* strobe clock */
3971 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3972 DELAY( BITD ); /* release clock */
3975 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3976 DELAY( BITD ); /* assert LO data */
3977 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3978 DELAY( BITD ); /* strobe clock */
3979 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3980 DELAY( BITD ); /* release clock */
3984 /* look for an ACK */
3985 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3986 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3987 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3988 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3993 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3998 /* read in the byte */
3999 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4000 DELAY( BITD ); /* float data */
4001 for ( x = 7; x >= 0; --x ) {
4002 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4003 DELAY( BITD ); /* strobe clock */
4004 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4005 if ( bit ) byte |= (1<<x);
4006 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4007 DELAY( BITD ); /* release clock */
4009 /* After reading the byte, send an ACK */
4010 /* (unless that was the last byte, for which we send a NAK */
4011 if (last) { /* send NAK - same a writing a 1 */
4012 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4013 DELAY( BITD ); /* set data bit */
4014 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4015 DELAY( BITD ); /* strobe clock */
4016 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4017 DELAY( BITD ); /* release clock */
4018 } else { /* send ACK - same as writing a 0 */
4019 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4020 DELAY( BITD ); /* set data bit */
4021 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4022 DELAY( BITD ); /* strobe clock */
4023 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4024 DELAY( BITD ); /* release clock */
4032 /* Write to the MSP or DPL registers */
4033 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4035 unsigned int msp_w_addr = i2c_addr;
4036 unsigned char addr_l, addr_h, data_h, data_l ;
4037 addr_h = (addr >>8) & 0xff;
4038 addr_l = addr & 0xff;
4039 data_h = (data >>8) & 0xff;
4040 data_l = data & 0xff;
4043 i2c_write_byte(bktr, msp_w_addr);
4044 i2c_write_byte(bktr, dev);
4045 i2c_write_byte(bktr, addr_h);
4046 i2c_write_byte(bktr, addr_l);
4047 i2c_write_byte(bktr, data_h);
4048 i2c_write_byte(bktr, data_l);
4052 /* Read from the MSP or DPL registers */
4053 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4055 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4056 addr_h = (addr >>8) & 0xff;
4057 addr_l = addr & 0xff;
4061 i2c_write_byte(bktr,i2c_addr);
4062 i2c_write_byte(bktr,dev_r);
4063 i2c_write_byte(bktr,addr_h);
4064 i2c_write_byte(bktr,addr_l);
4067 i2c_write_byte(bktr,i2c_addr+1);
4068 i2c_read_byte(bktr,&data_1, 0);
4069 i2c_read_byte(bktr,&data_2, 1);
4071 data = (data_1<<8) | data_2;
4075 /* Reset the MSP or DPL chip */
4076 /* The user can block the reset (which is handy if you initialise the
4077 * MSP audio in another operating system first (eg in Windows)
4079 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4081 #ifndef BKTR_NO_MSP_RESET
4082 /* put into reset mode */
4084 i2c_write_byte(bktr, i2c_addr);
4085 i2c_write_byte(bktr, 0x00);
4086 i2c_write_byte(bktr, 0x80);
4087 i2c_write_byte(bktr, 0x00);
4090 /* put back to operational mode */
4092 i2c_write_byte(bktr, i2c_addr);
4093 i2c_write_byte(bktr, 0x00);
4094 i2c_write_byte(bktr, 0x00);
4095 i2c_write_byte(bktr, 0x00);
4102 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4104 /* XXX errors ignored */
4106 i2c_write_byte(bktr,bktr->remote_control_addr);
4107 i2c_read_byte(bktr,&(remote->data[0]), 0);
4108 i2c_read_byte(bktr,&(remote->data[1]), 0);
4109 i2c_read_byte(bktr,&(remote->data[2]), 0);
4115 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4118 #if defined( I2C_SOFTWARE_PROBE )
4121 * we are keeping this around for any parts that we need to probe
4122 * but that CANNOT be probed via an i2c read.
4123 * this is necessary because the hardware i2c mechanism
4124 * cannot be programmed for 1 byte writes.
4125 * currently there are no known i2c parts that we need to probe
4126 * and that cannot be safely read.
4128 static int i2cProbe( bktr_ptr_t bktr, int addr );
4133 * probe for an I2C device at addr.
4136 i2cProbe( bktr_ptr_t bktr, int addr )
4141 #if defined( EXTRA_START )
4142 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4143 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4144 #endif /* EXTRA_START */
4145 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4146 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4149 for ( x = 7; x >= 0; --x ) {
4150 if ( addr & (1<<x) ) {
4151 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4152 DELAY( BITD ); /* assert HI data */
4153 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4154 DELAY( BITD ); /* strobe clock */
4155 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4156 DELAY( BITD ); /* release clock */
4159 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4160 DELAY( BITD ); /* assert LO data */
4161 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4162 DELAY( BITD ); /* strobe clock */
4163 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4164 DELAY( BITD ); /* release clock */
4168 /* look for an ACK */
4169 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4170 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4171 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4172 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4175 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4176 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4177 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4184 #endif /* I2C_SOFTWARE_PROBE */