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 */
101 #include <sys/thread2.h>
104 #include <vm/vm_kern.h>
106 #include <vm/vm_extern.h>
109 #define PROC_UNLOCK(p)
110 #include <bus/pci/pcivar.h>
113 #include <dev/video/meteor/ioctl_meteor.h>
114 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
115 #include <dev/video/bktr/bktr_reg.h>
116 #include <dev/video/bktr/bktr_tuner.h>
117 #include <dev/video/bktr/bktr_card.h>
118 #include <dev/video/bktr/bktr_audio.h>
119 #include <dev/video/bktr/bktr_os.h>
120 #include <dev/video/bktr/bktr_core.h>
121 #if defined(BKTR_FREEBSD_MODULE)
122 #include <dev/video/bktr/bktr_mem.h>
125 #if defined(BKTR_USE_FREEBSD_SMBUS)
126 #include <dev/video/bktr/bktr_i2c.h>
127 #include <bus/smbus/smbconf.h>
128 #include <bus/iicbus/iiconf.h>
129 #include "smbus_if.h"
130 #include "iicbus_if.h"
134 bktr_name(bktr_ptr_t bktr)
136 return bktr->bktr_xname;
139 typedef u_char bool_t;
141 #define BKTRPRI PCATCH
142 #define VBIPRI PCATCH
146 * memory allocated for DMA programs
148 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
150 /* When to split a dma transfer , the bt848 has timing as well as
151 dma transfer size limitations so that we have to split dma
152 transfers into two dma requests
154 #define DMA_BT848_SPLIT 319*2
157 * Allocate enough memory for:
158 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
160 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
161 * in your kernel configuration file.
164 #ifndef BROOKTREE_ALLOC_PAGES
165 #define BROOKTREE_ALLOC_PAGES 217*4
167 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
169 /* Definitions for VBI capture.
170 * There are 16 VBI lines in a PAL video field (32 in a frame),
171 * and we take 2044 samples from each line (placed in a 2048 byte buffer
173 * VBI lines are held in a circular buffer before being read by a
174 * user program from /dev/vbi.
177 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
178 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
179 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
180 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
181 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
184 /* Defines for fields */
190 * Parameters describing size of transmitted image.
193 static struct format_params format_params[] = {
194 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
195 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
197 /* # define BT848_IFORM_F_NTSCM (0x1) */
198 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
200 /* # define BT848_IFORM_F_NTSCJ (0x2) */
201 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
203 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
204 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
206 /* # define BT848_IFORM_F_PALM (0x4) */
207 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
209 /* # define BT848_IFORM_F_PALN (0x5) */
210 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
212 /* # define BT848_IFORM_F_SECAM (0x6) */
213 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
215 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
216 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
221 * Table of supported Pixel Formats
224 static struct meteor_pixfmt_internal {
225 struct meteor_pixfmt public;
229 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
230 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
232 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
233 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
235 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
237 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
238 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
239 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
240 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
241 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
242 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
243 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
246 #define PIXFMT_TABLE_SIZE NELEM(pixfmt_table)
249 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
252 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
254 u_long meteor_format;
255 struct meteor_pixfmt public;
256 } meteor_pixfmt_table[] = {
258 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
261 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
262 { METEOR_GEO_YUV_422,
263 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
265 { METEOR_GEO_YUV_PACKED,
266 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
269 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
272 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
276 #define METEOR_PIXFMT_TABLE_SIZE NELEM(meteor_pixfmt_table)
279 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
280 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
284 /* sync detect threshold */
286 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
287 BT848_ADC_CRUSH) /* threshold ~125 mV */
289 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
290 BT848_ADC_SYNC_T) /* threshold ~75 mV */
296 /* debug utility for holding previous INT_STAT contents */
298 static u_long status_sum = 0;
301 * defines to make certain bit-fiddles understandable
303 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
304 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
305 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
306 #define FIFO_RISC_DISABLED 0
308 #define ALL_INTS_DISABLED 0
309 #define ALL_INTS_CLEARED 0xffffffff
310 #define CAPTURE_OFF 0
312 #define BIT_SEVEN_HIGH (1<<7)
313 #define BIT_EIGHT_HIGH (1<<8)
315 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
316 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
320 static int oformat_meteor_to_bt( u_long format );
322 static u_int pixfmt_swap_flags( int pixfmt );
325 * bt848 RISC programming routines.
328 static int dump_bt848( bktr_ptr_t bktr );
331 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
332 int rows, int interlace );
333 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
334 int rows, int interlace );
335 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
336 int rows, int interlace );
337 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
338 int rows, int interlace );
339 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
340 int rows, int interlace );
341 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
343 static bool_t getline(bktr_reg_t *, int);
344 static bool_t notclipped(bktr_reg_t * , int , int);
345 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
346 volatile u_char ** , int );
348 static void start_capture( bktr_ptr_t bktr, unsigned type );
349 static void set_fps( bktr_ptr_t bktr, u_short fps );
354 * Remote Control Functions
356 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
360 * ioctls common to both video & tuner.
362 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
365 #if !defined(BKTR_USE_FREEBSD_SMBUS)
367 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
369 static void i2c_start( bktr_ptr_t bktr);
370 static void i2c_stop( bktr_ptr_t bktr);
371 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
372 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
378 * the common attach code, used by all OS versions.
381 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
384 int need_to_allocate_memory = 1;
385 #ifdef BKTR_NEW_MSP34XX_DRIVER
389 /* If this is a module, check if there is any currently saved contiguous memory */
390 #if defined(BKTR_FREEBSD_MODULE)
391 if (bktr_has_stored_addresses(unit) == 1) {
392 /* recover the addresses */
393 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
394 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
395 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
396 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
397 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
398 need_to_allocate_memory = 0;
402 if (need_to_allocate_memory == 1) {
403 /* allocate space for dma program */
404 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
405 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
407 /* allocte space for the VBI buffer */
408 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
409 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
411 /* allocate space for pixel buffer */
412 if ( BROOKTREE_ALLOC )
413 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
419 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
422 /* If this is a module, save the current contiguous memory */
423 #if defined(BKTR_FREEBSD_MODULE)
424 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
425 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
426 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
427 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
428 bktr_store_address(unit, BKTR_MEM_BUF, buf);
433 kprintf("%s: buffer size %d, addr %p\n",
434 bktr_name(bktr), BROOKTREE_ALLOC,
435 (void *)(uintptr_t)vtophys(buf));
440 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
441 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
443 bktr->alloc_pages = 0;
447 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
448 METEOR_DEV0 | METEOR_RGB16;
449 bktr->dma_prog_loaded = FALSE;
452 bktr->frames = 1; /* one frame */
453 bktr->format = METEOR_GEO_RGB16;
454 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
455 bktr->pixfmt_compat = TRUE;
464 /* using the pci device id and revision id */
465 /* and determine the card type */
466 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
468 switch (PCI_PRODUCT(pci_id)) {
469 case PCI_PRODUCT_BROOKTREE_BT848:
471 bktr->id = BROOKTREE_848A;
473 bktr->id = BROOKTREE_848;
475 case PCI_PRODUCT_BROOKTREE_BT849:
476 bktr->id = BROOKTREE_849A;
478 case PCI_PRODUCT_BROOKTREE_BT878:
479 bktr->id = BROOKTREE_878;
481 case PCI_PRODUCT_BROOKTREE_BT879:
482 bktr->id = BROOKTREE_879;
487 bktr->clr_on_start = FALSE;
489 /* defaults for the tuner section of the card */
490 bktr->tflags = TUNER_INITALIZED;
491 bktr->tuner.frequency = 0;
492 bktr->tuner.channel = 0;
493 bktr->tuner.chnlset = DEFAULT_CHNLSET;
495 bktr->tuner.radio_mode = 0;
496 bktr->audio_mux_select = 0;
497 bktr->audio_mute_state = FALSE;
498 bktr->bt848_card = -1;
499 bktr->bt848_tuner = -1;
500 bktr->reverse_mute = -1;
501 bktr->slow_msp_audio = 0;
502 bktr->msp_use_mono_source = 0;
503 bktr->msp_source_selected = -1;
504 bktr->audio_mux_present = 1;
506 #ifdef BKTR_NEW_MSP34XX_DRIVER
507 /* get hint on short programming of the msp34xx, so we know */
508 /* if the decision what thread to start should be overwritten */
509 if ( (err = resource_int_value("bktr", unit, "mspsimple",
510 &(bktr->mspsimple)) ) != 0 )
511 bktr->mspsimple = -1; /* fall back to default */
514 probeCard( bktr, TRUE, unit );
516 /* Initialise any MSP34xx or TDA98xx audio chips */
517 init_audio_devices( bktr );
519 #ifdef BKTR_NEW_MSP34XX_DRIVER
520 /* setup the kenrel thread */
521 err = msp_attach( bktr );
522 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
523 bktr->card.msp3400c = 0;
530 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
531 * The circular buffer holds 'n' fixed size data blocks.
532 * vbisize is the number of bytes in the circular buffer
533 * vbiread is the point we reading data out of the circular buffer
534 * vbiinsert is the point we insert data into the circular buffer
536 static void vbidecode(bktr_ptr_t bktr) {
538 unsigned int *seq_dest;
540 /* Check if there is room in the buffer to insert the data. */
541 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
543 /* Copy the VBI data into the next free slot in the buffer. */
544 /* 'dest' is the point in vbibuffer where we want to insert new data */
545 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
546 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
548 /* Write the VBI sequence number to the end of the vbi data */
549 /* This is used by the AleVT teletext program */
550 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
552 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
553 *seq_dest = bktr->vbi_sequence_number;
555 /* And increase the VBI sequence number */
556 /* This can wrap around */
557 bktr->vbi_sequence_number++;
560 /* Increment the vbiinsert pointer */
561 /* This can wrap around */
562 bktr->vbiinsert += VBI_DATA_SIZE;
563 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
565 /* And increase the amount of vbi data in the buffer */
566 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
572 * the common interrupt handler.
573 * Returns a 0 or 1 depending on whether the interrupt has handled.
574 * In the OS specific section, bktr_intr() is defined which calls this
575 * common interrupt handler.
578 common_bktr_intr( void *arg )
587 bktr = (bktr_ptr_t) arg;
590 * check to see if any interrupts are unmasked on this device. If
591 * none are, then we likely got here by way of being on a PCI shared
592 * interrupt dispatch list.
594 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
595 return 0; /* bail out now, before we do something we
598 if (!(bktr->flags & METEOR_OPEN)) {
599 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
600 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
604 /* record and clear the INTerrupt status bits */
605 bktr_status = INL(bktr, BKTR_INT_STAT);
606 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
608 /* record and clear the device status register */
609 dstatus = INB(bktr, BKTR_DSTATUS);
610 OUTB(bktr, BKTR_DSTATUS, 0x00);
612 #if defined( STATUS_SUM )
613 /* add any new device status or INTerrupt status bits */
614 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
615 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
616 #endif /* STATUS_SUM */
617 /* kprintf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
618 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
622 /* if risc was disabled re-start process again */
623 /* if there was one of the following errors re-start again */
624 if ( !(bktr_status & BT848_INT_RISC_EN) ||
625 ((bktr_status &(/* BT848_INT_FBUS | */
626 /* BT848_INT_FTRGT | */
627 /* BT848_INT_FDSR | */
629 BT848_INT_RIPERR | BT848_INT_PABORT |
630 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
631 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
633 u_short tdec_save = INB(bktr, BKTR_TDEC);
635 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
636 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
638 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
640 /* Reset temporal decimation counter */
641 OUTB(bktr, BKTR_TDEC, 0);
642 OUTB(bktr, BKTR_TDEC, tdec_save);
644 /* Reset to no-fields captured state */
645 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
646 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
647 case METEOR_ONLY_ODD_FIELDS:
648 bktr->flags |= METEOR_WANT_ODD;
650 case METEOR_ONLY_EVEN_FIELDS:
651 bktr->flags |= METEOR_WANT_EVEN;
654 bktr->flags |= METEOR_WANT_MASK;
659 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
660 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
661 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
663 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
668 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
672 /* If this is not a RISC program interrupt, return */
673 if (!(bktr_status & BT848_INT_RISCI))
677 kprintf( "%s: intr status %x %x %x\n", bktr_name(bktr),
678 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
683 * Disable future interrupts if a capture mode is not selected.
684 * This can happen when we are in the process of closing or
685 * changing capture modes, otherwise it shouldn't happen.
687 if (!(bktr->flags & METEOR_CAP_MASK))
688 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
691 /* Determine which field generated this interrupt */
692 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
696 * Process the VBI data if it is being captured. We do this once
697 * both Odd and Even VBI data is captured. Therefore we do this
698 * in the Even field interrupt handler.
701 if ( (bktr->vbiflags & VBI_CAPTURE)
702 &&(bktr->vbiflags & VBI_OPEN)
704 /* Put VBI data into circular buffer */
707 /* If someone is blocked on reading from /dev/vbi, wake them */
708 if (bktr->vbi_read_blocked) {
709 bktr->vbi_read_blocked = FALSE;
713 /* Inform anyone who is polling */
714 KNOTE(&bktr->vbi_kq.ki_note, 0);
720 * Register the completed field
721 * (For dual-field mode, require fields from the same frame)
723 switch ( bktr->flags & METEOR_WANT_MASK ) {
724 case METEOR_WANT_ODD : w_field = ODD_F ; break;
725 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
726 default : w_field = (ODD_F|EVEN_F); break;
728 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
729 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
730 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
731 default : req_field = (ODD_F|EVEN_F);
735 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
736 bktr->flags &= ~METEOR_WANT_EVEN;
737 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
738 ( w_field == ODD_F ))
739 bktr->flags &= ~METEOR_WANT_ODD;
740 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
741 ( w_field == (ODD_F|EVEN_F) ))
742 bktr->flags &= ~METEOR_WANT_ODD;
743 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
744 ( w_field == ODD_F )) {
745 bktr->flags &= ~METEOR_WANT_ODD;
746 bktr->flags |= METEOR_WANT_EVEN;
749 /* We're out of sync. Start over. */
750 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
751 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
752 case METEOR_ONLY_ODD_FIELDS:
753 bktr->flags |= METEOR_WANT_ODD;
755 case METEOR_ONLY_EVEN_FIELDS:
756 bktr->flags |= METEOR_WANT_EVEN;
759 bktr->flags |= METEOR_WANT_MASK;
767 * If we have a complete frame.
769 if (!(bktr->flags & METEOR_WANT_MASK)) {
770 bktr->frames_captured++;
772 * post the completion time.
774 if (bktr->flags & METEOR_WANT_TS) {
777 if ((u_int) bktr->alloc_pages * PAGE_SIZE
778 <= (bktr->frame_size + sizeof(struct timeval))) {
779 ts =(struct timeval *)bktr->bigbuf +
781 /* doesn't work in synch mode except
790 * Wake up the user in single capture mode.
792 if (bktr->flags & METEOR_SINGLE) {
795 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
797 /* disable risc, leave fifo running */
798 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
803 * If the user requested to be notified via signal,
804 * let them know the frame is complete.
807 if (bktr->proc != NULL) {
808 PROC_LOCK(bktr->proc);
809 ksignal( bktr->proc, bktr->signal);
810 PROC_UNLOCK(bktr->proc);
814 * Reset the want flags if in continuous or
815 * synchronous capture mode.
819 * currently we only support 3 capture modes: odd only, even only,
820 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
821 * either even OR odd) could provide 60 (50 for PAL) pictures per
822 * second, but it would require this routine to toggle the desired frame
823 * each time, and one more different DMA program for the Bt848.
824 * As a consequence, this fourth mode is currently unsupported.
827 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
828 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
829 case METEOR_ONLY_ODD_FIELDS:
830 bktr->flags |= METEOR_WANT_ODD;
832 case METEOR_ONLY_EVEN_FIELDS:
833 bktr->flags |= METEOR_WANT_EVEN;
836 bktr->flags |= METEOR_WANT_MASK;
851 extern int bt848_format; /* used to set the default format, PAL or NTSC */
853 video_open( bktr_ptr_t bktr )
855 int frame_rate, video_format=0;
857 if (bktr->flags & METEOR_OPEN) /* device is busy */
860 bktr->flags |= METEOR_OPEN;
866 bktr->clr_on_start = FALSE;
868 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
870 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
872 #if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
878 if (bt848_format == 0 )
881 if (bt848_format == 1 )
884 if (video_format == 1 ) {
885 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
886 bktr->format_params = BT848_IFORM_F_NTSCM;
889 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
890 bktr->format_params = BT848_IFORM_F_PALBDGHI;
894 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
896 /* work around for new Hauppauge 878 cards */
897 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
898 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
899 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
901 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
903 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
904 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
905 frame_rate = format_params[bktr->format_params].frame_rate;
907 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
908 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
909 OUTB(bktr, BKTR_TGCTRL, 0);
910 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
911 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
912 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
915 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
917 bktr->max_clip_node = 0;
919 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
921 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
922 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
924 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
925 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
926 OUTB(bktr, BKTR_E_SCLOOP, 0);
927 OUTB(bktr, BKTR_O_SCLOOP, 0);
929 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
930 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
932 bktr->fifo_errors = 0;
933 bktr->dma_errors = 0;
934 bktr->frames_captured = 0;
935 bktr->even_fields_captured = 0;
936 bktr->odd_fields_captured = 0;
938 set_fps(bktr, frame_rate);
939 bktr->video.addr = 0;
940 bktr->video.width = 0;
941 bktr->video.banksize = 0;
942 bktr->video.ramsize = 0;
943 bktr->pixfmt_compat = TRUE;
944 bktr->format = METEOR_GEO_RGB16;
945 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
947 bktr->capture_area_enabled = FALSE;
949 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
950 based motherboards will
951 operate unreliably */
956 vbi_open( bktr_ptr_t bktr )
961 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
966 bktr->vbiflags |= VBI_OPEN;
968 /* reset the VBI circular buffer pointers and clear the buffers */
972 bktr->vbi_sequence_number = 0;
973 bktr->vbi_read_blocked = FALSE;
975 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
976 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
987 tuner_open( bktr_ptr_t bktr )
989 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
992 if ( bktr->tflags & TUNER_OPEN ) /* already open */
995 bktr->tflags |= TUNER_OPEN;
996 bktr->tuner.frequency = 0;
997 bktr->tuner.channel = 0;
998 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1000 bktr->tuner.radio_mode = 0;
1002 /* enable drivers on the GPIO port that control the MUXes */
1003 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1005 /* unmute the audio stream */
1006 set_audio( bktr, AUDIO_UNMUTE );
1008 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1009 init_audio_devices( bktr );
1021 video_close( bktr_ptr_t bktr )
1023 bktr->flags &= ~(METEOR_OPEN |
1028 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1029 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1031 bktr->dma_prog_loaded = FALSE;
1032 OUTB(bktr, BKTR_TDEC, 0);
1033 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1035 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1036 OUTL(bktr, BKTR_SRESET, 0xf);
1037 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1044 * tuner close handle,
1045 * place holder for tuner specific operations on a close.
1048 tuner_close( bktr_ptr_t bktr )
1050 bktr->tflags &= ~TUNER_OPEN;
1052 /* mute the audio by switching the mux */
1053 set_audio( bktr, AUDIO_MUTE );
1055 /* disable drivers on the GPIO port that control the MUXes */
1056 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1062 vbi_close( bktr_ptr_t bktr )
1067 bktr->vbiflags &= ~VBI_OPEN;
1078 video_read(bktr_ptr_t bktr, int unit, cdev_t dev, struct uio *uio)
1084 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1087 if (bktr->flags & METEOR_CAP_MASK)
1088 return( EIO ); /* already capturing */
1090 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1093 count = bktr->rows * bktr->cols *
1094 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1096 if ((int) uio->uio_iov->iov_len < count)
1099 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1101 /* capture one frame */
1102 start_capture(bktr, METEOR_SINGLE);
1103 /* wait for capture to complete */
1104 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1105 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1106 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1107 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1113 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1114 if (!status) /* successful capture */
1115 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1117 kprintf ("%s: read: tsleep error %d\n",
1118 bktr_name(bktr), status);
1120 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1126 * Read VBI data from the vbi circular buffer
1127 * The buffer holds vbi data blocks which are the same size
1128 * vbiinsert is the position we will insert the next item into the buffer
1129 * vbistart is the actual position in the buffer we want to read from
1130 * vbisize is the exact number of bytes in the buffer left to read
1133 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1135 int readsize, readsize2, start;
1139 * XXX - vbi_read() should be protected against being re-entered
1140 * while it is unlocked for the uiomove.
1144 while(bktr->vbisize == 0) {
1145 if (ioflag & IO_NDELAY) {
1146 status = EWOULDBLOCK;
1150 bktr->vbi_read_blocked = TRUE;
1152 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1157 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1163 /* Now we have some data to give to the user */
1165 /* We cannot read more bytes than there are in
1166 * the circular buffer
1168 readsize = (int)uio->uio_iov->iov_len;
1170 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1172 /* Check if we can read this number of bytes without having
1173 * to wrap around the circular buffer */
1174 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1175 /* We need to wrap around */
1177 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1178 start = bktr->vbistart;
1180 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1182 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1185 /* We do not need to wrap around */
1186 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1191 /* Update the number of bytes left to read */
1192 bktr->vbisize -= readsize;
1194 /* Update vbistart */
1195 bktr->vbistart += readsize;
1196 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1211 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1213 volatile u_char c_temp;
1215 unsigned int temp_iform;
1217 struct meteor_geomet *geo;
1218 struct meteor_counts *counts;
1219 struct meteor_video *video;
1220 struct bktr_capture_area *cap_area;
1228 case BT848SCLIP: /* set clip region */
1229 bktr->max_clip_node = 0;
1230 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1232 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1233 if (bktr->clip_list[i].y_min == 0 &&
1234 bktr->clip_list[i].y_max == 0)
1237 bktr->max_clip_node = i;
1239 /* make sure that the list contains a valid clip secquence */
1240 /* the clip rectangles should be sorted by x then by y as the
1241 second order sort key */
1243 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1245 /* to disable clipping set y_min and y_max to 0 in the first
1246 clip rectangle . The first clip rectangle is clip_list[0].
1251 if (bktr->max_clip_node == 0 &&
1252 (bktr->clip_list[0].y_min != 0 &&
1253 bktr->clip_list[0].y_max != 0)) {
1257 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1258 if (bktr->clip_list[i].y_min == 0 &&
1259 bktr->clip_list[i].y_max == 0) {
1262 if ( bktr->clip_list[i+1].y_min != 0 &&
1263 bktr->clip_list[i+1].y_max != 0 &&
1264 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1266 bktr->max_clip_node = 0;
1271 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1272 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1273 bktr->clip_list[i].x_min < 0 ||
1274 bktr->clip_list[i].x_max < 0 ||
1275 bktr->clip_list[i].y_min < 0 ||
1276 bktr->clip_list[i].y_max < 0 ) {
1277 bktr->max_clip_node = 0;
1282 bktr->dma_prog_loaded = FALSE;
1286 case METEORSTATUS: /* get Bt848 status */
1287 c_temp = INB(bktr, BKTR_DSTATUS);
1289 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1290 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1291 *(u_short *)arg = temp;
1294 case BT848SFMT: /* set input format */
1295 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1296 temp_iform = INB(bktr, BKTR_IFORM);
1297 temp_iform &= ~BT848_IFORM_FORMAT;
1298 temp_iform &= ~BT848_IFORM_XTSEL;
1299 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1301 case BT848_IFORM_F_AUTO:
1302 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1306 case BT848_IFORM_F_NTSCM:
1307 case BT848_IFORM_F_NTSCJ:
1308 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1310 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1311 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1312 bktr->format_params = temp;
1315 case BT848_IFORM_F_PALBDGHI:
1316 case BT848_IFORM_F_PALN:
1317 case BT848_IFORM_F_SECAM:
1318 case BT848_IFORM_F_RSVD:
1319 case BT848_IFORM_F_PALM:
1320 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1322 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1323 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1324 bktr->format_params = temp;
1328 bktr->dma_prog_loaded = FALSE;
1331 case METEORSFMT: /* set input format */
1332 temp_iform = INB(bktr, BKTR_IFORM);
1333 temp_iform &= ~BT848_IFORM_FORMAT;
1334 temp_iform &= ~BT848_IFORM_XTSEL;
1335 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1336 case 0: /* default */
1337 case METEOR_FMT_NTSC:
1338 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1340 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1341 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1342 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1343 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1344 bktr->format_params = BT848_IFORM_F_NTSCM;
1347 case METEOR_FMT_PAL:
1348 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1350 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1351 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1352 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1353 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1354 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1357 case METEOR_FMT_AUTOMODE:
1358 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1360 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1361 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1367 bktr->dma_prog_loaded = FALSE;
1370 case METEORGFMT: /* get input format */
1371 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1375 case BT848GFMT: /* get input format */
1376 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1379 case METEORSCOUNT: /* (re)set error counts */
1380 counts = (struct meteor_counts *) arg;
1381 bktr->fifo_errors = counts->fifo_errors;
1382 bktr->dma_errors = counts->dma_errors;
1383 bktr->frames_captured = counts->frames_captured;
1384 bktr->even_fields_captured = counts->even_fields_captured;
1385 bktr->odd_fields_captured = counts->odd_fields_captured;
1388 case METEORGCOUNT: /* get error counts */
1389 counts = (struct meteor_counts *) arg;
1390 counts->fifo_errors = bktr->fifo_errors;
1391 counts->dma_errors = bktr->dma_errors;
1392 counts->frames_captured = bktr->frames_captured;
1393 counts->even_fields_captured = bktr->even_fields_captured;
1394 counts->odd_fields_captured = bktr->odd_fields_captured;
1398 video = (struct meteor_video *)arg;
1399 video->addr = bktr->video.addr;
1400 video->width = bktr->video.width;
1401 video->banksize = bktr->video.banksize;
1402 video->ramsize = bktr->video.ramsize;
1406 video = (struct meteor_video *)arg;
1407 bktr->video.addr = video->addr;
1408 bktr->video.width = video->width;
1409 bktr->video.banksize = video->banksize;
1410 bktr->video.ramsize = video->ramsize;
1414 set_fps(bktr, *(u_short *)arg);
1418 *(u_short *)arg = bktr->fps;
1421 case METEORSHUE: /* set hue */
1422 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1425 case METEORGHUE: /* get hue */
1426 *(u_char *)arg = INB(bktr, BKTR_HUE);
1429 case METEORSBRIG: /* set brightness */
1430 char_temp = ( *(u_char *)arg & 0xff) - 128;
1431 OUTB(bktr, BKTR_BRIGHT, char_temp);
1435 case METEORGBRIG: /* get brightness */
1436 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1439 case METEORSCSAT: /* set chroma saturation */
1440 temp = (int)*(u_char *)arg;
1442 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1443 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1444 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1445 & ~(BT848_E_CONTROL_SAT_U_MSB
1446 | BT848_E_CONTROL_SAT_V_MSB));
1447 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1448 & ~(BT848_O_CONTROL_SAT_U_MSB |
1449 BT848_O_CONTROL_SAT_V_MSB));
1451 if ( temp & BIT_SEVEN_HIGH ) {
1452 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1453 | (BT848_E_CONTROL_SAT_U_MSB
1454 | BT848_E_CONTROL_SAT_V_MSB));
1455 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1456 | (BT848_O_CONTROL_SAT_U_MSB
1457 | BT848_O_CONTROL_SAT_V_MSB));
1461 case METEORGCSAT: /* get chroma saturation */
1462 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1463 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1464 temp |= BIT_SEVEN_HIGH;
1465 *(u_char *)arg = (u_char)temp;
1468 case METEORSCONT: /* set contrast */
1469 temp = (int)*(u_char *)arg & 0xff;
1471 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1472 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1473 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1474 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1475 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1476 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1477 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1480 case METEORGCONT: /* get contrast */
1481 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1482 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1483 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1486 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1487 bktr->clr_on_start = (*(int *)arg != 0);
1490 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1491 *(int *)arg = (int) bktr->clr_on_start;
1496 /* Historically, applications used METEOR_SIG_MODE_MASK
1497 * to reset signal delivery.
1499 if (sig == METEOR_SIG_MODE_MASK)
1501 if (sig < 0 || sig > _SIG_MAXSIG)
1504 bktr->proc = sig ? td->td_proc : NULL;
1508 *(int *)arg = bktr->signal;
1513 switch (*(int *) arg) {
1514 case METEOR_CAP_SINGLE:
1516 if (bktr->bigbuf==0) /* no frame buffer allocated */
1518 /* already capturing */
1519 if (temp & METEOR_CAP_MASK)
1524 start_capture(bktr, METEOR_SINGLE);
1526 /* wait for capture to complete */
1527 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1528 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1529 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1531 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1536 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1537 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1538 if (error && (error != ERESTART)) {
1539 /* Here if we didn't get complete frame */
1541 kprintf( "%s: ioctl: tsleep error %d %x\n",
1542 bktr_name(bktr), error,
1543 INL(bktr, BKTR_RISC_COUNT));
1547 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1549 /* disable risc, leave fifo running */
1550 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1553 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1554 /* FIXME: should we set bt848->int_stat ??? */
1557 case METEOR_CAP_CONTINOUS:
1558 if (bktr->bigbuf==0) /* no frame buffer allocated */
1560 /* already capturing */
1561 if (temp & METEOR_CAP_MASK)
1565 start_capture(bktr, METEOR_CONTIN);
1567 /* Clear the interrypt status register */
1568 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1570 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1571 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1572 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1574 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1583 case METEOR_CAP_STOP_CONT:
1584 if (bktr->flags & METEOR_CONTIN) {
1585 /* turn off capture */
1586 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1587 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1588 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1590 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1597 /* can't change parameters while capturing */
1598 if (bktr->flags & METEOR_CAP_MASK)
1602 geo = (struct meteor_geomet *) arg;
1605 /* Either even or odd, if even & odd, then these a zero */
1606 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1607 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1608 kprintf( "%s: ioctl: Geometry odd or even only.\n",
1613 /* set/clear even/odd flags */
1614 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1615 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1617 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1618 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1619 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1621 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1623 if (geo->columns <= 0) {
1625 "%s: ioctl: %d: columns must be greater than zero.\n",
1626 bktr_name(bktr), geo->columns);
1629 else if ((geo->columns & 0x3fe) != geo->columns) {
1631 "%s: ioctl: %d: columns too large or not even.\n",
1632 bktr_name(bktr), geo->columns);
1636 if (geo->rows <= 0) {
1638 "%s: ioctl: %d: rows must be greater than zero.\n",
1639 bktr_name(bktr), geo->rows);
1642 else if (((geo->rows & 0x7fe) != geo->rows) ||
1643 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1644 ((geo->rows & 0x3fe) != geo->rows)) ) {
1646 "%s: ioctl: %d: rows too large or not even.\n",
1647 bktr_name(bktr), geo->rows);
1651 if (geo->frames > 32) {
1652 kprintf("%s: ioctl: too many frames.\n",
1661 bktr->dma_prog_loaded = FALSE;
1662 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1664 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1666 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1667 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1669 /* meteor_mem structure for SYNC Capture */
1670 if (geo->frames > 1) temp += PAGE_SIZE;
1673 if ((int) temp > bktr->alloc_pages
1674 && bktr->video.addr == 0) {
1676 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1678 kmem_free(&kernel_map, bktr->bigbuf,
1679 (bktr->alloc_pages * PAGE_SIZE));
1682 bktr->alloc_pages = temp;
1685 "%s: ioctl: Allocating %d bytes\n",
1686 bktr_name(bktr), temp*PAGE_SIZE);
1696 bktr->rows = geo->rows;
1697 bktr->cols = geo->columns;
1698 bktr->frames = geo->frames;
1700 /* Pixel format (if in meteor pixfmt compatibility mode) */
1701 if ( bktr->pixfmt_compat ) {
1702 bktr->format = METEOR_GEO_YUV_422;
1703 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1704 case 0: /* default */
1705 case METEOR_GEO_RGB16:
1706 bktr->format = METEOR_GEO_RGB16;
1708 case METEOR_GEO_RGB24:
1709 bktr->format = METEOR_GEO_RGB24;
1711 case METEOR_GEO_YUV_422:
1712 bktr->format = METEOR_GEO_YUV_422;
1713 if (geo->oformat & METEOR_GEO_YUV_12)
1714 bktr->format = METEOR_GEO_YUV_12;
1716 case METEOR_GEO_YUV_PACKED:
1717 bktr->format = METEOR_GEO_YUV_PACKED;
1720 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1723 if (bktr->flags & METEOR_CAP_MASK) {
1725 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1726 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1727 case METEOR_ONLY_ODD_FIELDS:
1728 bktr->flags |= METEOR_WANT_ODD;
1730 case METEOR_ONLY_EVEN_FIELDS:
1731 bktr->flags |= METEOR_WANT_EVEN;
1734 bktr->flags |= METEOR_WANT_MASK;
1738 start_capture(bktr, METEOR_CONTIN);
1739 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1740 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1741 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1742 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1748 /* end of METEORSETGEO */
1750 /* FIXME. The Capture Area currently has the following restrictions:
1752 y_offset may need to be even in interlaced modes
1753 RGB24 - Interlaced mode
1754 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1755 y_size must be greater than or equal to METEORSETGEO height (rows)
1756 RGB24 - Even Only (or Odd Only) mode
1757 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1758 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1759 YUV12 - Interlaced mode
1760 x_size must be greater than or equal to METEORSETGEO width (cols)
1761 y_size must be greater than or equal to METEORSETGEO height (rows)
1762 YUV12 - Even Only (or Odd Only) mode
1763 x_size must be greater than or equal to METEORSETGEO width (cols)
1764 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1767 case BT848_SCAPAREA: /* set capture area of each video frame */
1768 /* can't change parameters while capturing */
1769 if (bktr->flags & METEOR_CAP_MASK)
1772 cap_area = (struct bktr_capture_area *) arg;
1773 bktr->capture_area_x_offset = cap_area->x_offset;
1774 bktr->capture_area_y_offset = cap_area->y_offset;
1775 bktr->capture_area_x_size = cap_area->x_size;
1776 bktr->capture_area_y_size = cap_area->y_size;
1777 bktr->capture_area_enabled = TRUE;
1779 bktr->dma_prog_loaded = FALSE;
1782 case BT848_GCAPAREA: /* get capture area of each video frame */
1783 cap_area = (struct bktr_capture_area *) arg;
1784 if (bktr->capture_area_enabled == FALSE) {
1785 cap_area->x_offset = 0;
1786 cap_area->y_offset = 0;
1787 cap_area->x_size = format_params[
1788 bktr->format_params].scaled_hactive;
1789 cap_area->y_size = format_params[
1790 bktr->format_params].vactive;
1792 cap_area->x_offset = bktr->capture_area_x_offset;
1793 cap_area->y_offset = bktr->capture_area_y_offset;
1794 cap_area->x_size = bktr->capture_area_x_size;
1795 cap_area->y_size = bktr->capture_area_y_size;
1800 return common_ioctl( bktr, cmd, arg );
1810 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1813 unsigned int temp, temp1;
1826 /* Read the last key pressed by the Remote Control */
1827 if (bktr->remote_control == 0) return (EINVAL);
1828 remote_read(bktr, (struct bktr_remote *)arg);
1831 #if defined( TUNER_AFC )
1832 case TVTUNER_SETAFC:
1833 bktr->tuner.afc = (*(int *)arg != 0);
1836 case TVTUNER_GETAFC:
1837 *(int *)arg = bktr->tuner.afc;
1838 /* XXX Perhaps use another bit to indicate AFC success? */
1840 #endif /* TUNER_AFC */
1842 case TVTUNER_SETCHNL:
1843 temp_mute( bktr, TRUE );
1844 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1846 temp_mute( bktr, FALSE );
1849 *(unsigned long *)arg = temp;
1851 /* after every channel change, we must restart the MSP34xx */
1852 /* audio chip to reselect NICAM STEREO or MONO audio */
1853 if ( bktr->card.msp3400c )
1854 msp_autodetect( bktr );
1856 /* after every channel change, we must restart the DPL35xx */
1857 if ( bktr->card.dpl3518a )
1858 dpl_autodetect( bktr );
1860 temp_mute( bktr, FALSE );
1863 case TVTUNER_GETCHNL:
1864 *(unsigned long *)arg = bktr->tuner.channel;
1867 case TVTUNER_SETTYPE:
1868 temp = *(unsigned long *)arg;
1869 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1871 bktr->tuner.chnlset = temp;
1874 case TVTUNER_GETTYPE:
1875 *(unsigned long *)arg = bktr->tuner.chnlset;
1878 case TVTUNER_GETSTATUS:
1879 temp = get_tuner_status( bktr );
1880 *(unsigned long *)arg = temp & 0xff;
1883 case TVTUNER_SETFREQ:
1884 temp_mute( bktr, TRUE );
1885 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1886 temp_mute( bktr, FALSE );
1888 temp_mute( bktr, FALSE );
1891 *(unsigned long *)arg = temp;
1893 /* after every channel change, we must restart the MSP34xx */
1894 /* audio chip to reselect NICAM STEREO or MONO audio */
1895 if ( bktr->card.msp3400c )
1896 msp_autodetect( bktr );
1898 /* after every channel change, we must restart the DPL35xx */
1899 if ( bktr->card.dpl3518a )
1900 dpl_autodetect( bktr );
1902 temp_mute( bktr, FALSE );
1905 case TVTUNER_GETFREQ:
1906 *(unsigned long *)arg = bktr->tuner.frequency;
1909 case TVTUNER_GETCHNLSET:
1910 return tuner_getchnlset((struct bktr_chnlset *)arg);
1912 case BT848_SAUDIO: /* set audio channel */
1913 if ( set_audio( bktr, *(int*)arg ) < 0 )
1917 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1918 case BT848_SHUE: /* set hue */
1919 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1922 case BT848_GHUE: /* get hue */
1923 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1926 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1927 case BT848_SBRIG: /* set brightness */
1928 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1931 case BT848_GBRIG: /* get brightness */
1932 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1936 case BT848_SCSAT: /* set chroma saturation */
1937 tmp_int = *(int*)arg;
1939 temp = INB(bktr, BKTR_E_CONTROL);
1940 temp1 = INB(bktr, BKTR_O_CONTROL);
1941 if ( tmp_int & BIT_EIGHT_HIGH ) {
1942 temp |= (BT848_E_CONTROL_SAT_U_MSB |
1943 BT848_E_CONTROL_SAT_V_MSB);
1944 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1945 BT848_O_CONTROL_SAT_V_MSB);
1948 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1949 BT848_E_CONTROL_SAT_V_MSB);
1950 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1951 BT848_O_CONTROL_SAT_V_MSB);
1954 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1955 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1956 OUTB(bktr, BKTR_E_CONTROL, temp);
1957 OUTB(bktr, BKTR_O_CONTROL, temp1);
1960 case BT848_GCSAT: /* get chroma saturation */
1961 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1962 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1963 tmp_int |= BIT_EIGHT_HIGH;
1964 *(int*)arg = tmp_int;
1968 case BT848_SVSAT: /* set chroma V saturation */
1969 tmp_int = *(int*)arg;
1971 temp = INB(bktr, BKTR_E_CONTROL);
1972 temp1 = INB(bktr, BKTR_O_CONTROL);
1973 if ( tmp_int & BIT_EIGHT_HIGH) {
1974 temp |= BT848_E_CONTROL_SAT_V_MSB;
1975 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1978 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1979 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1982 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1983 OUTB(bktr, BKTR_E_CONTROL, temp);
1984 OUTB(bktr, BKTR_O_CONTROL, temp1);
1987 case BT848_GVSAT: /* get chroma V saturation */
1988 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1989 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1990 tmp_int |= BIT_EIGHT_HIGH;
1991 *(int*)arg = tmp_int;
1995 case BT848_SUSAT: /* set chroma U saturation */
1996 tmp_int = *(int*)arg;
1998 temp = INB(bktr, BKTR_E_CONTROL);
1999 temp1 = INB(bktr, BKTR_O_CONTROL);
2000 if ( tmp_int & BIT_EIGHT_HIGH ) {
2001 temp |= BT848_E_CONTROL_SAT_U_MSB;
2002 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2005 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2006 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2009 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2010 OUTB(bktr, BKTR_E_CONTROL, temp);
2011 OUTB(bktr, BKTR_O_CONTROL, temp1);
2014 case BT848_GUSAT: /* get chroma U saturation */
2015 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2016 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2017 tmp_int |= BIT_EIGHT_HIGH;
2018 *(int*)arg = tmp_int;
2021 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2023 case BT848_SLNOTCH: /* set luma notch */
2024 tmp_int = (*(int *)arg & 0x7) << 5 ;
2025 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2026 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2027 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2028 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2031 case BT848_GLNOTCH: /* get luma notch */
2032 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2037 case BT848_SCONT: /* set contrast */
2038 tmp_int = *(int*)arg;
2040 temp = INB(bktr, BKTR_E_CONTROL);
2041 temp1 = INB(bktr, BKTR_O_CONTROL);
2042 if ( tmp_int & BIT_EIGHT_HIGH ) {
2043 temp |= BT848_E_CONTROL_CON_MSB;
2044 temp1 |= BT848_O_CONTROL_CON_MSB;
2047 temp &= ~BT848_E_CONTROL_CON_MSB;
2048 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2051 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2052 OUTB(bktr, BKTR_E_CONTROL, temp);
2053 OUTB(bktr, BKTR_O_CONTROL, temp1);
2056 case BT848_GCONT: /* get contrast */
2057 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2058 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2059 tmp_int |= BIT_EIGHT_HIGH;
2060 *(int*)arg = tmp_int;
2063 /* FIXME: SCBARS and CCBARS require a valid int * */
2064 /* argument to succeed, but its not used; consider */
2065 /* using the arg to store the on/off state so */
2066 /* there's only one ioctl() needed to turn cbars on/off */
2067 case BT848_SCBARS: /* set colorbar output */
2068 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2071 case BT848_CCBARS: /* clear colorbar output */
2072 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2075 case BT848_GAUDIO: /* get audio channel */
2076 temp = bktr->audio_mux_select;
2077 if ( bktr->audio_mute_state == TRUE )
2082 case BT848_SBTSC: /* set audio channel */
2083 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2087 case BT848_WEEPROM: /* write eeprom */
2088 offset = (((struct eeProm *)arg)->offset);
2089 count = (((struct eeProm *)arg)->count);
2090 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2091 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2095 case BT848_REEPROM: /* read eeprom */
2096 offset = (((struct eeProm *)arg)->offset);
2097 count = (((struct eeProm *)arg)->count);
2098 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2099 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2103 case BT848_SIGNATURE:
2104 offset = (((struct eeProm *)arg)->offset);
2105 count = (((struct eeProm *)arg)->count);
2106 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2107 if ( signCard( bktr, offset, count, buf ) < 0 )
2111 /* Ioctl's for direct gpio access */
2112 #ifdef BKTR_GPIO_ACCESS
2113 case BT848_GPIO_GET_EN:
2114 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2117 case BT848_GPIO_SET_EN:
2118 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2121 case BT848_GPIO_GET_DATA:
2122 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2125 case BT848_GPIO_SET_DATA:
2126 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2128 #endif /* BKTR_GPIO_ACCESS */
2130 /* Ioctl's for running the tuner device in radio mode */
2133 *(unsigned char *)arg = bktr->tuner.radio_mode;
2137 bktr->tuner.radio_mode = *(unsigned char *)arg;
2141 *(unsigned long *)arg = bktr->tuner.frequency;
2145 /* The argument to this ioctl is NOT freq*16. It is
2149 temp=(int)*(unsigned long *)arg;
2151 #ifdef BKTR_RADIO_DEBUG
2152 kprintf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2153 (int)*(unsigned long *)arg, temp);
2156 #ifndef BKTR_RADIO_NOFREQCHECK
2157 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2159 if(temp<8750 || temp>10800) {
2160 kprintf("%s: Radio frequency out of range\n", bktr_name(bktr));
2164 temp_mute( bktr, TRUE );
2165 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2166 temp_mute( bktr, FALSE );
2167 #ifdef BKTR_RADIO_DEBUG
2169 kprintf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2173 *(unsigned long *)arg = temp;
2176 /* Luigi's I2CWR ioctl */
2178 par = *(u_long *)arg;
2179 write = (par >> 24) & 0xff ;
2180 i2c_addr = (par >> 16) & 0xff ;
2181 i2c_port = (par >> 8) & 0xff ;
2182 data = (par) & 0xff ;
2185 i2cWrite( bktr, i2c_addr, i2c_port, data);
2187 data = i2cRead( bktr, i2c_addr);
2189 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2193 #ifdef BT848_MSP_READ
2194 /* I2C ioctls to allow userland access to the MSP chip */
2195 case BT848_MSP_READ:
2197 struct bktr_msp_control *msp;
2198 msp = (struct bktr_msp_control *) arg;
2199 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2200 msp->function, msp->address);
2204 case BT848_MSP_WRITE:
2206 struct bktr_msp_control *msp;
2207 msp = (struct bktr_msp_control *) arg;
2208 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2209 msp->address, msp->data );
2213 case BT848_MSP_RESET:
2214 msp_dpl_reset(bktr, bktr->msp_addr);
2219 return common_ioctl( bktr, cmd, arg );
2230 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2234 struct meteor_pixfmt *pf_pub;
2238 case METEORSINPUT: /* set input device */
2239 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2240 /* On the original bt848 boards, */
2241 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2242 /* On the Hauppauge bt878 boards, */
2243 /* Tuner is MUX0, RCA is MUX3 */
2244 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2245 /* stick with this system in our Meteor Emulation */
2247 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2249 /* this is the RCA video input */
2250 case 0: /* default */
2251 case METEOR_INPUT_DEV0:
2252 /* METEOR_INPUT_DEV_RCA: */
2253 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2255 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2256 & ~BT848_IFORM_MUXSEL);
2258 /* work around for new Hauppauge 878 cards */
2259 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2260 (bktr->id==BROOKTREE_878 ||
2261 bktr->id==BROOKTREE_879) )
2262 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2264 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2266 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2267 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2268 set_audio( bktr, AUDIO_EXTERN );
2271 /* this is the tuner input */
2272 case METEOR_INPUT_DEV1:
2273 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2275 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2276 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2277 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2278 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2279 set_audio( bktr, AUDIO_TUNER );
2282 /* this is the S-VHS input, but with a composite camera */
2283 case METEOR_INPUT_DEV2:
2284 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2286 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2287 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2288 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2289 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2290 set_audio( bktr, AUDIO_EXTERN );
2293 /* this is the S-VHS input */
2294 case METEOR_INPUT_DEV_SVIDEO:
2295 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2296 | METEOR_DEV_SVIDEO;
2297 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2298 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2299 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2300 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2301 set_audio( bktr, AUDIO_EXTERN );
2304 case METEOR_INPUT_DEV3:
2305 if ((bktr->id == BROOKTREE_848A) ||
2306 (bktr->id == BROOKTREE_849A) ||
2307 (bktr->id == BROOKTREE_878) ||
2308 (bktr->id == BROOKTREE_879) ) {
2309 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2311 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2313 /* work around for new Hauppauge 878 cards */
2314 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2315 (bktr->id==BROOKTREE_878 ||
2316 bktr->id==BROOKTREE_879) )
2317 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2319 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2321 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2322 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2323 set_audio( bktr, AUDIO_EXTERN );
2333 case METEORGINPUT: /* get input device */
2334 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2337 case METEORSACTPIXFMT:
2338 if (( *(int *)arg < 0 ) ||
2339 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2342 bktr->pixfmt = *(int *)arg;
2343 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2344 | pixfmt_swap_flags( bktr->pixfmt ));
2345 bktr->pixfmt_compat = FALSE;
2348 case METEORGACTPIXFMT:
2349 *(int *)arg = bktr->pixfmt;
2352 case METEORGSUPPIXFMT :
2353 pf_pub = (struct meteor_pixfmt *)arg;
2354 pixfmt = pf_pub->index;
2356 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2359 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2360 sizeof( *pf_pub ) );
2362 /* Patch in our format index */
2363 pf_pub->index = pixfmt;
2366 #if defined( STATUS_SUM )
2367 case BT848_GSTATUS: /* reap status */
2373 *(u_int*)arg = temp;
2376 #endif /* STATUS_SUM */
2388 /******************************************************************************
2389 * bt848 RISC programming routines:
2398 dump_bt848( bktr_ptr_t bktr )
2401 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2402 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2403 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2404 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2405 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2410 for (i = 0; i < 40; i+=4) {
2411 kprintf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2413 r[i], INL(bktr, r[i]),
2414 r[i+1], INL(bktr, r[i+1]),
2415 r[i+2], INL(bktr, r[i+2]),
2416 r[i+3], INL(bktr, r[i+3]));
2419 kprintf("%s: INT STAT %x \n", bktr_name(bktr),
2420 INL(bktr, BKTR_INT_STAT));
2421 kprintf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2422 INL(bktr, BKTR_INT_MASK));
2423 kprintf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2424 INW(bktr, BKTR_GPIO_DMA_CTL));
2432 * build write instruction
2434 #define BKTR_FM1 0x6 /* packed data to follow */
2435 #define BKTR_FM3 0xe /* planar data to follow */
2436 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2437 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2438 #define BKTR_PXV 0x0 /* valid word (never used) */
2439 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2440 #define BKTR_SOL 0x2 /* first dword */
2442 #define OP_WRITE (0x1 << 28)
2443 #define OP_SKIP (0x2 << 28)
2444 #define OP_WRITEC (0x5 << 28)
2445 #define OP_JUMP (0x7 << 28)
2446 #define OP_SYNC (0x8 << 28)
2447 #define OP_WRITE123 (0x9 << 28)
2448 #define OP_WRITES123 (0xb << 28)
2449 #define OP_SOL (1 << 27) /* first instr for scanline */
2450 #define OP_EOL (1 << 26)
2452 #define BKTR_RESYNC (1 << 15)
2453 #define BKTR_GEN_IRQ (1 << 24)
2456 * The RISC status bits can be set/cleared in the RISC programs
2457 * and tested in the Interrupt Handler
2459 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2460 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2461 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2462 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2464 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2465 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2466 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2467 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2469 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2470 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2471 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2472 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2474 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2476 bktr_clip_t * clip_node;
2477 bktr->clip_start = -1;
2481 bktr->line_length = width;
2484 bktr->current_col = 0;
2486 if (bktr->max_clip_node == 0 ) return TRUE;
2487 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2490 for (i = 0; i < bktr->max_clip_node; i++ ) {
2491 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2492 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2493 bktr->clip_start = i;
2501 static bool_t getline(bktr_reg_t *bktr, int x ) {
2503 bktr_clip_t * clip_node ;
2505 if (bktr->line_length == 0 ||
2506 bktr->current_col >= bktr->line_length) return FALSE;
2508 bktr->y = min(bktr->last_y, bktr->line_length);
2509 bktr->y2 = bktr->line_length;
2511 bktr->yclip = bktr->yclip2 = -1;
2512 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2513 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2514 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2515 if (bktr->last_y <= clip_node->y_min) {
2516 bktr->y = min(bktr->last_y, bktr->line_length);
2517 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2518 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2519 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2520 bktr->last_y = bktr->yclip2;
2521 bktr->clip_start = i;
2523 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2524 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2525 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2526 if (bktr->last_y >= clip_node->y_min) {
2527 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2528 bktr->last_y = bktr->yclip2;
2529 bktr->clip_start = j;
2538 if (bktr->current_col <= bktr->line_length) {
2539 bktr->current_col = bktr->line_length;
2545 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2546 u_long operation, int pixel_width,
2547 volatile u_char ** target_buffer, int cols ) {
2550 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2551 u_int skip, start_skip;
2553 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2554 /* to the 1st byte in the mem dword containing our start addr. */
2555 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2558 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2559 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2560 case 2 : start_skip = 4 ; break;
2561 case 1 : start_skip = 8 ; break;
2564 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2565 if ( width == cols) {
2566 flag = OP_SOL | OP_EOL;
2567 } else if (bktr->current_col == 0 ) {
2569 } else if (bktr->current_col == cols) {
2574 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2575 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2580 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2581 if (operation != OP_SKIP )
2582 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2584 *target_buffer += width * pixel_width;
2585 bktr->current_col += width;
2589 if (bktr->current_col == 0 && width == cols) {
2592 } else if (bktr->current_col == 0 ) {
2595 } else if (bktr->current_col >= cols) {
2604 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2605 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2610 *(*dma_prog)++ = operation | flag |
2611 (width * pixel_width / 2 - skip);
2612 if (operation != OP_SKIP )
2613 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2614 *target_buffer += (width * pixel_width / 2) ;
2616 if ( operation == OP_WRITE )
2617 operation = OP_WRITEC;
2618 *(*dma_prog)++ = operation | flag2 |
2619 (width * pixel_width / 2);
2620 *target_buffer += (width * pixel_width / 2) ;
2621 bktr->current_col += width;
2629 * Generate the RISC instructions to capture both VBI and video images
2632 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2635 volatile uint32_t target_buffer, buffer, target,width;
2636 volatile uint32_t pitch;
2637 volatile uint32_t *dma_prog; /* DMA prog is an array of
2638 32 bit RISC instructions */
2639 volatile uint32_t *loop_point;
2640 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2641 u_int Bpp = pf_int->public.Bpp;
2642 unsigned int vbisamples; /* VBI samples per line */
2643 unsigned int vbilines; /* VBI lines per field */
2644 unsigned int num_dwords; /* DWORDS per line */
2646 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2647 vbilines = format_params[bktr->format_params].vbi_num_lines;
2648 num_dwords = vbisamples/4;
2650 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2651 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2652 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2653 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2656 OUTB(bktr, BKTR_OFORM, 0x00);
2658 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2659 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2660 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2661 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2663 /* disable gamma correction removal */
2664 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2667 OUTB(bktr, BKTR_E_VTC, 0);
2668 OUTB(bktr, BKTR_O_VTC, 0);
2670 OUTB(bktr, BKTR_E_VTC, 1);
2671 OUTB(bktr, BKTR_O_VTC, 1);
2673 bktr->capcontrol = 3 << 2 | 3;
2675 dma_prog = (uint32_t *) bktr->dma_prog;
2677 /* Construct Write */
2679 if (bktr->video.addr) {
2680 target_buffer = (u_long) bktr->video.addr;
2681 pitch = bktr->video.width;
2684 target_buffer = (u_long) vtophys(bktr->bigbuf);
2688 buffer = target_buffer;
2690 /* Wait for the VRE sync marking the end of the Even and
2691 * the start of the Odd field. Resync here.
2693 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2696 loop_point = dma_prog;
2698 /* store the VBI data */
2699 /* look for sync with packed data */
2700 *dma_prog++ = OP_SYNC | BKTR_FM1;
2702 for(i = 0; i < vbilines; i++) {
2703 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2704 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2705 (i * VBI_LINE_SIZE));
2708 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2709 /* store the Odd field video image */
2710 /* look for sync with packed data */
2711 *dma_prog++ = OP_SYNC | BKTR_FM1;
2712 *dma_prog++ = 0; /* NULL WORD */
2714 for (i = 0; i < (rows/interlace); i++) {
2715 target = target_buffer;
2716 if ( notclipped(bktr, i, width)) {
2717 split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2718 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2721 while(getline(bktr, i)) {
2722 if (bktr->y != bktr->y2 ) {
2723 split(bktr, &dma_prog,
2724 bktr->y2 - bktr->y, OP_WRITE,
2725 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2727 if (bktr->yclip != bktr->yclip2 ) {
2728 split(bktr,&dma_prog,
2729 bktr->yclip2 - bktr->yclip,
2731 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2737 target_buffer += interlace * pitch;
2743 /* Grab the Even field */
2744 /* Look for the VRO, end of Odd field, marker */
2745 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2746 *dma_prog++ = 0; /* NULL WORD */
2748 /* store the VBI data */
2749 /* look for sync with packed data */
2750 *dma_prog++ = OP_SYNC | BKTR_FM1;
2752 for(i = 0; i < vbilines; i++) {
2753 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2754 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2755 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2758 /* store the video image */
2759 if (i_flag == 1) /*Even Only*/
2760 target_buffer = buffer;
2761 if (i_flag == 3) /*interlaced*/
2762 target_buffer = buffer+pitch;
2765 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2766 /* look for sync with packed data */
2767 *dma_prog++ = OP_SYNC | BKTR_FM1;
2768 *dma_prog++ = 0; /* NULL WORD */
2770 for (i = 0; i < (rows/interlace); i++) {
2771 target = target_buffer;
2772 if ( notclipped(bktr, i, width)) {
2773 split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2774 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2776 while(getline(bktr, i)) {
2777 if (bktr->y != bktr->y2 ) {
2778 split(bktr, &dma_prog,
2779 bktr->y2 - bktr->y, OP_WRITE,
2780 Bpp, (volatile u_char **)(uintptr_t)&target,
2783 if (bktr->yclip != bktr->yclip2 ) {
2784 split(bktr, &dma_prog,
2785 bktr->yclip2 - bktr->yclip, OP_SKIP,
2786 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2793 target_buffer += interlace * pitch;
2798 /* Look for end of 'Even Field' */
2799 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2800 *dma_prog++ = 0; /* NULL WORD */
2802 *dma_prog++ = OP_JUMP ;
2803 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2804 *dma_prog++ = 0; /* NULL WORD */
2812 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2815 volatile uint32_t target_buffer, buffer, target,width;
2816 volatile uint32_t pitch;
2817 volatile uint32_t *dma_prog;
2818 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2819 u_int Bpp = pf_int->public.Bpp;
2821 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2822 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2823 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2824 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2826 OUTB(bktr, BKTR_OFORM, 0x00);
2828 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2829 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2830 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2831 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2833 /* disable gamma correction removal */
2834 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2837 OUTB(bktr, BKTR_E_VTC, 0);
2838 OUTB(bktr, BKTR_O_VTC, 0);
2840 OUTB(bktr, BKTR_E_VTC, 1);
2841 OUTB(bktr, BKTR_O_VTC, 1);
2843 bktr->capcontrol = 3 << 2 | 3;
2845 dma_prog = (uint32_t *) bktr->dma_prog;
2847 /* Construct Write */
2849 if (bktr->video.addr) {
2850 target_buffer = (uint32_t) bktr->video.addr;
2851 pitch = bktr->video.width;
2854 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2858 buffer = target_buffer;
2860 /* contruct sync : for video packet format */
2861 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2863 /* sync, mode indicator packed data */
2864 *dma_prog++ = 0; /* NULL WORD */
2866 for (i = 0; i < (rows/interlace); i++) {
2867 target = target_buffer;
2868 if ( notclipped(bktr, i, width)) {
2869 split(bktr, &dma_prog,
2870 bktr->y2 - bktr->y, OP_WRITE,
2871 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2874 while(getline(bktr, i)) {
2875 if (bktr->y != bktr->y2 ) {
2876 split(bktr, &dma_prog,
2877 bktr->y2 - bktr->y, OP_WRITE,
2878 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2880 if (bktr->yclip != bktr->yclip2 ) {
2881 split(bktr,&dma_prog,
2882 bktr->yclip2 - bktr->yclip,
2884 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2890 target_buffer += interlace * pitch;
2897 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2898 *dma_prog++ = 0; /* NULL WORD */
2900 *dma_prog++ = OP_JUMP;
2901 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2906 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2907 *dma_prog++ = 0; /* NULL WORD */
2909 *dma_prog++ = OP_JUMP;
2910 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2915 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2916 *dma_prog++ = 0; /* NULL WORD */
2917 *dma_prog++ = OP_JUMP;
2918 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
2922 if (interlace == 2) {
2924 target_buffer = buffer + pitch;
2926 dma_prog = (uint32_t *) bktr->odd_dma_prog;
2928 /* sync vre IRQ bit */
2929 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2930 *dma_prog++ = 0; /* NULL WORD */
2932 for (i = 0; i < (rows/interlace); i++) {
2933 target = target_buffer;
2934 if ( notclipped(bktr, i, width)) {
2935 split(bktr, &dma_prog,
2936 bktr->y2 - bktr->y, OP_WRITE,
2937 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2939 while(getline(bktr, i)) {
2940 if (bktr->y != bktr->y2 ) {
2941 split(bktr, &dma_prog,
2942 bktr->y2 - bktr->y, OP_WRITE,
2943 Bpp, (volatile u_char **)(uintptr_t)&target,
2946 if (bktr->yclip != bktr->yclip2 ) {
2947 split(bktr, &dma_prog,
2948 bktr->yclip2 - bktr->yclip, OP_SKIP,
2949 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2956 target_buffer += interlace * pitch;
2961 /* sync vre IRQ bit */
2962 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2963 *dma_prog++ = 0; /* NULL WORD */
2964 *dma_prog++ = OP_JUMP ;
2965 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
2966 *dma_prog++ = 0; /* NULL WORD */
2974 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2975 int cols, int rows, int interlace )
2978 volatile unsigned int inst;
2979 volatile unsigned int inst3;
2980 volatile uint32_t target_buffer, buffer;
2981 volatile uint32_t *dma_prog;
2982 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2985 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2987 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
2988 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2990 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
2991 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2993 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
2994 bktr->capcontrol = 3 << 2 | 3;
2996 dma_prog = (uint32_t *) bktr->dma_prog;
2998 /* Construct Write */
3000 /* write , sol, eol */
3001 inst = OP_WRITE | OP_SOL | (cols);
3002 /* write , sol, eol */
3003 inst3 = OP_WRITE | OP_EOL | (cols);
3005 if (bktr->video.addr)
3006 target_buffer = (uint32_t) bktr->video.addr;
3008 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3010 buffer = target_buffer;
3012 /* contruct sync : for video packet format */
3013 /* sync, mode indicator packed data */
3014 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3015 *dma_prog++ = 0; /* NULL WORD */
3019 for (i = 0; i < (rows/interlace); i++) {
3021 *dma_prog++ = target_buffer;
3022 *dma_prog++ = inst3;
3023 *dma_prog++ = target_buffer + b;
3024 target_buffer += interlace*(cols * 2);
3030 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3031 *dma_prog++ = 0; /* NULL WORD */
3033 *dma_prog++ = OP_JUMP;
3034 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3039 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3040 *dma_prog++ = 0; /* NULL WORD */
3041 *dma_prog++ = OP_JUMP;
3042 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3047 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3048 *dma_prog++ = 0; /* NULL WORD */
3049 *dma_prog++ = OP_JUMP ;
3050 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3054 if (interlace == 2) {
3056 target_buffer = (uint32_t) buffer + cols*2;
3058 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3061 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3062 *dma_prog++ = 0; /* NULL WORD */
3064 for (i = 0; i < (rows/interlace) ; i++) {
3066 *dma_prog++ = target_buffer;
3067 *dma_prog++ = inst3;
3068 *dma_prog++ = target_buffer + b;
3069 target_buffer += interlace * ( cols*2);
3073 /* sync vro IRQ bit */
3074 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3075 *dma_prog++ = 0; /* NULL WORD */
3076 *dma_prog++ = OP_JUMP ;
3077 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3079 *dma_prog++ = OP_JUMP;
3080 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3081 *dma_prog++ = 0; /* NULL WORD */
3089 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3090 int cols, int rows, int interlace ){
3093 volatile unsigned int inst;
3094 volatile uint32_t target_buffer, t1, buffer;
3095 volatile uint32_t *dma_prog;
3096 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3098 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3100 dma_prog = (uint32_t*) bktr->dma_prog;
3102 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3104 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3105 OUTB(bktr, BKTR_OFORM, 0x00);
3107 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3108 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3110 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3111 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3113 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3114 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3115 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3116 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3118 /* disable gamma correction removal */
3119 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3121 /* Construct Write */
3122 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3123 if (bktr->video.addr)
3124 target_buffer = (uint32_t) bktr->video.addr;
3126 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3128 buffer = target_buffer;
3132 /* contruct sync : for video packet format */
3133 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3134 *dma_prog++ = 0; /* NULL WORD */
3136 for (i = 0; i < (rows/interlace ) ; i++) {
3138 *dma_prog++ = cols/2 | cols/2 << 16;
3139 *dma_prog++ = target_buffer;
3140 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3141 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3142 target_buffer += interlace*cols;
3147 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3148 *dma_prog++ = 0; /* NULL WORD */
3150 *dma_prog++ = OP_JUMP ;
3151 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3155 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3156 *dma_prog++ = 0; /* NULL WORD */
3158 *dma_prog++ = OP_JUMP;
3159 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3163 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3164 *dma_prog++ = 0; /* NULL WORD */
3166 *dma_prog++ = OP_JUMP ;
3167 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3171 if (interlace == 2) {
3173 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3175 target_buffer = (uint32_t) buffer + cols;
3176 t1 = buffer + cols/2;
3177 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3178 *dma_prog++ = 0; /* NULL WORD */
3180 for (i = 0; i < (rows/interlace ) ; i++) {
3182 *dma_prog++ = cols/2 | cols/2 << 16;
3183 *dma_prog++ = target_buffer;
3184 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3185 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3186 target_buffer += interlace*cols;
3190 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3191 *dma_prog++ = 0; /* NULL WORD */
3192 *dma_prog++ = OP_JUMP ;
3193 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3194 *dma_prog++ = 0; /* NULL WORD */
3202 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3203 int cols, int rows, int interlace ){
3206 volatile unsigned int inst;
3207 volatile unsigned int inst1;
3208 volatile uint32_t target_buffer, t1, buffer;
3209 volatile uint32_t *dma_prog;
3210 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3212 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3214 dma_prog = (uint32_t *) bktr->dma_prog;
3216 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3218 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3219 OUTB(bktr, BKTR_OFORM, 0x0);
3221 /* Construct Write */
3222 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3223 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3224 if (bktr->video.addr)
3225 target_buffer = (uint32_t) bktr->video.addr;
3227 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3229 buffer = target_buffer;
3232 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3233 *dma_prog++ = 0; /* NULL WORD */
3235 for (i = 0; i < (rows/interlace )/2 ; i++) {
3237 *dma_prog++ = cols/2 | (cols/2 << 16);
3238 *dma_prog++ = target_buffer;
3239 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3240 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3241 target_buffer += interlace*cols;
3242 *dma_prog++ = inst1;
3243 *dma_prog++ = cols/2 | (cols/2 << 16);
3244 *dma_prog++ = target_buffer;
3245 target_buffer += interlace*cols;
3251 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3252 *dma_prog++ = 0; /* NULL WORD */
3254 *dma_prog++ = OP_JUMP;
3255 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3259 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3260 *dma_prog++ = 0; /* NULL WORD */
3262 *dma_prog++ = OP_JUMP;
3263 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3267 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3268 *dma_prog++ = 0; /* NULL WORD */
3269 *dma_prog++ = OP_JUMP ;
3270 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3274 if (interlace == 2) {
3276 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3278 target_buffer = (uint32_t) buffer + cols;
3279 t1 = buffer + cols/2;
3280 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3281 *dma_prog++ = 0; /* NULL WORD */
3283 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3285 *dma_prog++ = cols/2 | (cols/2 << 16);
3286 *dma_prog++ = target_buffer;
3287 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3288 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3289 target_buffer += interlace*cols;
3290 *dma_prog++ = inst1;
3291 *dma_prog++ = cols/2 | (cols/2 << 16);
3292 *dma_prog++ = target_buffer;
3293 target_buffer += interlace*cols;
3300 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3301 *dma_prog++ = 0; /* NULL WORD */
3302 *dma_prog++ = OP_JUMP;
3303 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3304 *dma_prog++ = 0; /* NULL WORD */
3313 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3315 int rows, cols, interlace;
3318 struct format_params *fp;
3319 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3322 fp = &format_params[bktr->format_params];
3324 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3326 /* disable FIFO & RISC, leave other bits alone */
3327 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3329 /* set video parameters */
3330 if (bktr->capture_area_enabled)
3331 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3332 / fp->scaled_htotal / bktr->cols) - 4096;
3334 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3335 / fp->scaled_htotal / bktr->cols) - 4096;
3337 /* kprintf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3338 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3339 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3340 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3341 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3343 /* horizontal active */
3345 /* kprintf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3346 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3347 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3348 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3349 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3350 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3351 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3353 /* horizontal delay */
3354 if (bktr->capture_area_enabled)
3355 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3356 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3358 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3360 temp = temp & 0x3fe;
3362 /* kprintf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3363 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3364 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3365 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3366 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3367 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3368 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3370 /* vertical scale */
3372 if (bktr->capture_area_enabled) {
3373 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3374 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3376 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3379 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3382 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3383 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3385 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3388 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3393 /* kprintf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3394 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3395 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3396 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3397 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3398 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3399 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3402 /* vertical active */
3403 if (bktr->capture_area_enabled)
3404 temp = bktr->capture_area_y_size;
3407 /* kprintf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3408 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3409 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3410 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3411 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3412 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3413 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3415 /* vertical delay */
3416 if (bktr->capture_area_enabled)
3417 temp = fp->vdelay + (bktr->capture_area_y_offset);
3420 /* kprintf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3421 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3422 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3423 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3424 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3425 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3426 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3428 /* end of video params */
3430 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3431 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3432 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3434 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3437 /* capture control */
3440 bktr->bktr_cap_ctl =
3441 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3442 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3443 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3447 bktr->bktr_cap_ctl =
3448 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3449 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3450 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3454 bktr->bktr_cap_ctl =
3455 (BT848_CAP_CTL_DITH_FRAME |
3456 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3457 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3458 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3463 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3468 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3470 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3471 /* user, then use the rgb_vbi RISC program. */
3472 /* Otherwise, use the normal rgb RISC program */
3473 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3474 if ( (bktr->vbiflags & VBI_OPEN)
3475 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3476 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3478 bktr->bktr_cap_ctl |=
3479 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3480 bktr->vbiflags |= VBI_CAPTURE;
3481 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3484 rgb_prog(bktr, i_flag, cols, rows, interlace);
3489 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3490 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3491 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3492 | pixfmt_swap_flags( bktr->pixfmt ));
3496 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3497 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3498 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3499 | pixfmt_swap_flags( bktr->pixfmt ));
3503 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3504 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3505 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3506 | pixfmt_swap_flags( bktr->pixfmt ));
3513 /******************************************************************************
3514 * video & video capture specific routines:
3522 start_capture( bktr_ptr_t bktr, unsigned type )
3525 struct format_params *fp;
3527 fp = &format_params[bktr->format_params];
3529 /* If requested, clear out capture buf first */
3530 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3531 bzero((caddr_t)bktr->bigbuf,
3532 (size_t)bktr->rows * bktr->cols * bktr->frames *
3533 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3536 OUTB(bktr, BKTR_DSTATUS, 0);
3537 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3539 bktr->flags |= type;
3540 bktr->flags &= ~METEOR_WANT_MASK;
3541 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3542 case METEOR_ONLY_EVEN_FIELDS:
3543 bktr->flags |= METEOR_WANT_EVEN;
3546 case METEOR_ONLY_ODD_FIELDS:
3547 bktr->flags |= METEOR_WANT_ODD;
3551 bktr->flags |= METEOR_WANT_MASK;
3556 /* TDEC is only valid for continuous captures */
3557 if ( type == METEOR_SINGLE ) {
3558 u_short fps_save = bktr->fps;
3560 set_fps(bktr, fp->frame_rate);
3561 bktr->fps = fps_save;
3564 set_fps(bktr, bktr->fps);
3566 if (bktr->dma_prog_loaded == FALSE) {
3567 build_dma_prog(bktr, i_flag);
3568 bktr->dma_prog_loaded = TRUE;
3572 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3581 set_fps( bktr_ptr_t bktr, u_short fps )
3583 struct format_params *fp;
3586 fp = &format_params[bktr->format_params];
3588 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3589 case METEOR_ONLY_EVEN_FIELDS:
3590 bktr->flags |= METEOR_WANT_EVEN;
3593 case METEOR_ONLY_ODD_FIELDS:
3594 bktr->flags |= METEOR_WANT_ODD;
3598 bktr->flags |= METEOR_WANT_MASK;
3603 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3604 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3607 OUTB(bktr, BKTR_TDEC, 0);
3609 if (fps < fp->frame_rate)
3610 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3612 OUTB(bktr, BKTR_TDEC, 0);
3622 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3623 * achieve the specified swapping.
3624 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3625 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3627 * Note also that for 3Bpp, we may additionally need to do some creative
3628 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3629 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3630 * as one would expect.
3633 static u_int pixfmt_swap_flags( int pixfmt )
3635 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3638 switch ( pf->Bpp ) {
3639 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3642 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3645 case 4 : if ( pf->swap_bytes )
3646 swapf = pf->swap_shorts ? 0 : WSWAP;
3648 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3657 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3658 * our pixfmt_table indices.
3661 static int oformat_meteor_to_bt( u_long format )
3664 struct meteor_pixfmt *pf1, *pf2;
3666 /* Find format in compatibility table */
3667 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3668 if ( meteor_pixfmt_table[i].meteor_format == format )
3671 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3673 pf1 = &meteor_pixfmt_table[i].public;
3675 /* Match it with an entry in master pixel format table */
3676 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3677 pf2 = &pixfmt_table[i].public;
3679 if (( pf1->type == pf2->type ) &&
3680 ( pf1->Bpp == pf2->Bpp ) &&
3681 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3682 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3683 ( pf1->swap_shorts == pf2->swap_shorts ))
3686 if ( i >= PIXFMT_TABLE_SIZE )
3692 /******************************************************************************
3697 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3698 #define I2CBITTIME_878 (1 << 7)
3699 #define I2C_READ 0x01
3700 #define I2C_COMMAND (I2CBITTIME | \
3701 BT848_DATA_CTL_I2CSCL | \
3702 BT848_DATA_CTL_I2CSDA)
3704 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3705 BT848_DATA_CTL_I2CSCL | \
3706 BT848_DATA_CTL_I2CSDA)
3708 /* Select between old i2c code and new iicbus / smbus code */
3709 #if defined(BKTR_USE_FREEBSD_SMBUS)
3712 * The hardware interface is actually SMB commands
3715 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3719 if (bktr->id == BROOKTREE_848 ||
3720 bktr->id == BROOKTREE_848A ||
3721 bktr->id == BROOKTREE_849A)
3724 cmd = I2C_COMMAND_878;
3727 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3728 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3731 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3732 (char)(byte1 & 0xff)))
3741 i2cRead( bktr_ptr_t bktr, int addr )
3746 if (bktr->id == BROOKTREE_848 ||
3747 bktr->id == BROOKTREE_848A ||
3748 bktr->id == BROOKTREE_849A)
3751 cmd = I2C_COMMAND_878;
3753 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3756 return ((int)((unsigned char)result));
3759 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3761 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3762 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3763 /* Therefore we need low level control of the i2c bus hardware */
3765 /* Write to the MSP or DPL registers */
3767 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3769 unsigned char addr_l, addr_h, data_h, data_l ;
3771 addr_h = (addr >>8) & 0xff;
3772 addr_l = addr & 0xff;
3773 data_h = (data >>8) & 0xff;
3774 data_l = data & 0xff;
3776 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3778 iicbus_write_byte(IICBUS(bktr), dev, 0);
3779 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3780 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3781 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3782 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3784 iicbus_stop(IICBUS(bktr));
3789 /* Read from the MSP or DPL registers */
3791 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3794 unsigned char addr_l, addr_h, dev_r;
3796 u_char data_read[2];
3798 addr_h = (addr >>8) & 0xff;
3799 addr_l = addr & 0xff;
3802 /* XXX errors ignored */
3803 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3805 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3806 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3807 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3809 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3810 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3811 iicbus_stop(IICBUS(bktr));
3813 data = (data_read[0]<<8) | data_read[1];
3818 /* Reset the MSP or DPL chip */
3819 /* The user can block the reset (which is handy if you initialise the
3820 * MSP and/or DPL audio in another operating system first (eg in Windows)
3823 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3826 #ifndef BKTR_NO_MSP_RESET
3827 /* put into reset mode */
3828 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3829 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3830 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3831 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3832 iicbus_stop(IICBUS(bktr));
3834 /* put back to operational mode */
3835 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3836 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3837 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3838 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3839 iicbus_stop(IICBUS(bktr));
3844 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3847 /* XXX errors ignored */
3848 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3849 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3850 iicbus_stop(IICBUS(bktr));
3855 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3858 * Program the i2c bus directly
3861 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3866 /* clear status bits */
3867 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3869 /* build the command datum */
3870 if (bktr->id == BROOKTREE_848 ||
3871 bktr->id == BROOKTREE_848A ||
3872 bktr->id == BROOKTREE_849A) {
3873 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3875 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3877 if ( byte2 != -1 ) {
3878 data |= ((byte2 & 0xff) << 8);
3879 data |= BT848_DATA_CTL_I2CW3B;
3882 /* write the address and data */
3883 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3885 /* wait for completion */
3886 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3887 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3892 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3904 i2cRead( bktr_ptr_t bktr, int addr )
3908 /* clear status bits */
3909 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3911 /* write the READ address */
3912 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3914 if (bktr->id == BROOKTREE_848 ||
3915 bktr->id == BROOKTREE_848A ||
3916 bktr->id == BROOKTREE_849A) {
3917 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3919 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3922 /* wait for completion */
3923 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3924 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3929 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3933 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3936 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3937 /* bt848 automated i2c bus controller cannot handle */
3938 /* Therefore we need low level control of the i2c bus hardware */
3939 /* Idea for the following functions are from elsewhere in this driver and */
3940 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3943 static void i2c_start( bktr_ptr_t bktr) {
3944 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3945 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3946 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3947 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3950 static void i2c_stop( bktr_ptr_t bktr) {
3951 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3952 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3953 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3956 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3960 /* write out the byte */
3961 for ( x = 7; x >= 0; --x ) {
3962 if ( data & (1<<x) ) {
3963 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3964 DELAY( BITD ); /* assert HI data */
3965 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3966 DELAY( BITD ); /* strobe clock */
3967 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3968 DELAY( BITD ); /* release clock */
3971 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3972 DELAY( BITD ); /* assert LO data */
3973 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3974 DELAY( BITD ); /* strobe clock */
3975 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3976 DELAY( BITD ); /* release clock */
3980 /* look for an ACK */
3981 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3982 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3983 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3984 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3989 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3994 /* read in the byte */
3995 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3996 DELAY( BITD ); /* float data */
3997 for ( x = 7; x >= 0; --x ) {
3998 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3999 DELAY( BITD ); /* strobe clock */
4000 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4001 if ( bit ) byte |= (1<<x);
4002 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4003 DELAY( BITD ); /* release clock */
4005 /* After reading the byte, send an ACK */
4006 /* (unless that was the last byte, for which we send a NAK */
4007 if (last) { /* send NAK - same a writing a 1 */
4008 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4009 DELAY( BITD ); /* set data bit */
4010 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4011 DELAY( BITD ); /* strobe clock */
4012 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4013 DELAY( BITD ); /* release clock */
4014 } else { /* send ACK - same as writing a 0 */
4015 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4016 DELAY( BITD ); /* set data bit */
4017 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4018 DELAY( BITD ); /* strobe clock */
4019 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4020 DELAY( BITD ); /* release clock */
4028 /* Write to the MSP or DPL registers */
4029 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4031 unsigned int msp_w_addr = i2c_addr;
4032 unsigned char addr_l, addr_h, data_h, data_l ;
4033 addr_h = (addr >>8) & 0xff;
4034 addr_l = addr & 0xff;
4035 data_h = (data >>8) & 0xff;
4036 data_l = data & 0xff;
4039 i2c_write_byte(bktr, msp_w_addr);
4040 i2c_write_byte(bktr, dev);
4041 i2c_write_byte(bktr, addr_h);
4042 i2c_write_byte(bktr, addr_l);
4043 i2c_write_byte(bktr, data_h);
4044 i2c_write_byte(bktr, data_l);
4048 /* Read from the MSP or DPL registers */
4049 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4051 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4052 addr_h = (addr >>8) & 0xff;
4053 addr_l = addr & 0xff;
4057 i2c_write_byte(bktr,i2c_addr);
4058 i2c_write_byte(bktr,dev_r);
4059 i2c_write_byte(bktr,addr_h);
4060 i2c_write_byte(bktr,addr_l);
4063 i2c_write_byte(bktr,i2c_addr+1);
4064 i2c_read_byte(bktr,&data_1, 0);
4065 i2c_read_byte(bktr,&data_2, 1);
4067 data = (data_1<<8) | data_2;
4071 /* Reset the MSP or DPL chip */
4072 /* The user can block the reset (which is handy if you initialise the
4073 * MSP audio in another operating system first (eg in Windows)
4075 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4077 #ifndef BKTR_NO_MSP_RESET
4078 /* put into reset mode */
4080 i2c_write_byte(bktr, i2c_addr);
4081 i2c_write_byte(bktr, 0x00);
4082 i2c_write_byte(bktr, 0x80);
4083 i2c_write_byte(bktr, 0x00);
4086 /* put back to operational mode */
4088 i2c_write_byte(bktr, i2c_addr);
4089 i2c_write_byte(bktr, 0x00);
4090 i2c_write_byte(bktr, 0x00);
4091 i2c_write_byte(bktr, 0x00);
4098 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4100 /* XXX errors ignored */
4102 i2c_write_byte(bktr,bktr->remote_control_addr);
4103 i2c_read_byte(bktr,&(remote->data[0]), 0);
4104 i2c_read_byte(bktr,&(remote->data[1]), 0);
4105 i2c_read_byte(bktr,&(remote->data[2]), 0);
4111 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4114 #if defined( I2C_SOFTWARE_PROBE )
4117 * we are keeping this around for any parts that we need to probe
4118 * but that CANNOT be probed via an i2c read.
4119 * this is necessary because the hardware i2c mechanism
4120 * cannot be programmed for 1 byte writes.
4121 * currently there are no known i2c parts that we need to probe
4122 * and that cannot be safely read.
4124 static int i2cProbe( bktr_ptr_t bktr, int addr );
4129 * probe for an I2C device at addr.
4132 i2cProbe( bktr_ptr_t bktr, int addr )
4137 #if defined( EXTRA_START )
4138 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4139 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4140 #endif /* EXTRA_START */
4141 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4142 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4145 for ( x = 7; x >= 0; --x ) {
4146 if ( addr & (1<<x) ) {
4147 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4148 DELAY( BITD ); /* assert HI data */
4149 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4150 DELAY( BITD ); /* strobe clock */
4151 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4152 DELAY( BITD ); /* release clock */
4155 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4156 DELAY( BITD ); /* assert LO data */
4157 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4158 DELAY( BITD ); /* strobe clock */
4159 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4160 DELAY( BITD ); /* release clock */
4164 /* look for an ACK */
4165 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4166 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4167 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4168 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4171 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4172 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4173 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4180 #endif /* I2C_SOFTWARE_PROBE */