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 )
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 = 3 << 2 | 3;
2995 dma_prog = (uint32_t *) bktr->dma_prog;
2997 /* Construct Write */
2999 /* write , sol, eol */
3000 inst = OP_WRITE | OP_SOL | (cols);
3001 /* write , sol, eol */
3002 inst3 = OP_WRITE | OP_EOL | (cols);
3004 if (bktr->video.addr)
3005 target_buffer = (uint32_t) bktr->video.addr;
3007 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3009 buffer = target_buffer;
3011 /* contruct sync : for video packet format */
3012 /* sync, mode indicator packed data */
3013 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3014 *dma_prog++ = 0; /* NULL WORD */
3018 for (i = 0; i < (rows/interlace); i++) {
3020 *dma_prog++ = target_buffer;
3021 *dma_prog++ = inst3;
3022 *dma_prog++ = target_buffer + b;
3023 target_buffer += interlace*(cols * 2);
3029 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3030 *dma_prog++ = 0; /* NULL WORD */
3032 *dma_prog++ = OP_JUMP;
3033 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3038 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3039 *dma_prog++ = 0; /* NULL WORD */
3040 *dma_prog++ = OP_JUMP;
3041 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3046 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3047 *dma_prog++ = 0; /* NULL WORD */
3048 *dma_prog++ = OP_JUMP ;
3049 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3053 if (interlace == 2) {
3055 target_buffer = (uint32_t) buffer + cols*2;
3057 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3060 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3061 *dma_prog++ = 0; /* NULL WORD */
3063 for (i = 0; i < (rows/interlace) ; i++) {
3065 *dma_prog++ = target_buffer;
3066 *dma_prog++ = inst3;
3067 *dma_prog++ = target_buffer + b;
3068 target_buffer += interlace * ( cols*2);
3072 /* sync vro IRQ bit */
3073 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3074 *dma_prog++ = 0; /* NULL WORD */
3075 *dma_prog++ = OP_JUMP ;
3076 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3078 *dma_prog++ = OP_JUMP;
3079 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3080 *dma_prog++ = 0; /* NULL WORD */
3088 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3089 int cols, int rows, int interlace ){
3092 volatile unsigned int inst;
3093 volatile uint32_t target_buffer, t1, buffer;
3094 volatile uint32_t *dma_prog;
3095 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3097 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3099 dma_prog = (uint32_t*) bktr->dma_prog;
3101 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3103 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3104 OUTB(bktr, BKTR_OFORM, 0x00);
3106 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3107 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3109 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3110 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3112 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3113 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3114 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3115 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3117 /* disable gamma correction removal */
3118 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3120 /* Construct Write */
3121 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3122 if (bktr->video.addr)
3123 target_buffer = (uint32_t) bktr->video.addr;
3125 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3127 buffer = target_buffer;
3131 /* contruct sync : for video packet format */
3132 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3133 *dma_prog++ = 0; /* NULL WORD */
3135 for (i = 0; i < (rows/interlace ) ; i++) {
3137 *dma_prog++ = cols/2 | cols/2 << 16;
3138 *dma_prog++ = target_buffer;
3139 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3140 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3141 target_buffer += interlace*cols;
3146 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3147 *dma_prog++ = 0; /* NULL WORD */
3149 *dma_prog++ = OP_JUMP ;
3150 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3154 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3155 *dma_prog++ = 0; /* NULL WORD */
3157 *dma_prog++ = OP_JUMP;
3158 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3162 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3163 *dma_prog++ = 0; /* NULL WORD */
3165 *dma_prog++ = OP_JUMP ;
3166 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3170 if (interlace == 2) {
3172 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3174 target_buffer = (uint32_t) buffer + cols;
3175 t1 = buffer + cols/2;
3176 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3177 *dma_prog++ = 0; /* NULL WORD */
3179 for (i = 0; i < (rows/interlace ) ; i++) {
3181 *dma_prog++ = cols/2 | cols/2 << 16;
3182 *dma_prog++ = target_buffer;
3183 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3184 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3185 target_buffer += interlace*cols;
3189 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3190 *dma_prog++ = 0; /* NULL WORD */
3191 *dma_prog++ = OP_JUMP ;
3192 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3193 *dma_prog++ = 0; /* NULL WORD */
3201 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3202 int cols, int rows, int interlace ){
3205 volatile unsigned int inst;
3206 volatile unsigned int inst1;
3207 volatile uint32_t target_buffer, t1, buffer;
3208 volatile uint32_t *dma_prog;
3209 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3211 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3213 dma_prog = (uint32_t *) bktr->dma_prog;
3215 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3217 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3218 OUTB(bktr, BKTR_OFORM, 0x0);
3220 /* Construct Write */
3221 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3222 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3223 if (bktr->video.addr)
3224 target_buffer = (uint32_t) bktr->video.addr;
3226 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3228 buffer = target_buffer;
3231 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3232 *dma_prog++ = 0; /* NULL WORD */
3234 for (i = 0; i < (rows/interlace )/2 ; i++) {
3236 *dma_prog++ = cols/2 | (cols/2 << 16);
3237 *dma_prog++ = target_buffer;
3238 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3239 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3240 target_buffer += interlace*cols;
3241 *dma_prog++ = inst1;
3242 *dma_prog++ = cols/2 | (cols/2 << 16);
3243 *dma_prog++ = target_buffer;
3244 target_buffer += interlace*cols;
3250 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3251 *dma_prog++ = 0; /* NULL WORD */
3253 *dma_prog++ = OP_JUMP;
3254 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3258 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3259 *dma_prog++ = 0; /* NULL WORD */
3261 *dma_prog++ = OP_JUMP;
3262 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3266 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3267 *dma_prog++ = 0; /* NULL WORD */
3268 *dma_prog++ = OP_JUMP ;
3269 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3273 if (interlace == 2) {
3275 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3277 target_buffer = (uint32_t) buffer + cols;
3278 t1 = buffer + cols/2;
3279 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3280 *dma_prog++ = 0; /* NULL WORD */
3282 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3284 *dma_prog++ = cols/2 | (cols/2 << 16);
3285 *dma_prog++ = target_buffer;
3286 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3287 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3288 target_buffer += interlace*cols;
3289 *dma_prog++ = inst1;
3290 *dma_prog++ = cols/2 | (cols/2 << 16);
3291 *dma_prog++ = target_buffer;
3292 target_buffer += interlace*cols;
3299 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3300 *dma_prog++ = 0; /* NULL WORD */
3301 *dma_prog++ = OP_JUMP;
3302 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3303 *dma_prog++ = 0; /* NULL WORD */
3312 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3314 int rows, cols, interlace;
3317 struct format_params *fp;
3318 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3321 fp = &format_params[bktr->format_params];
3323 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3325 /* disable FIFO & RISC, leave other bits alone */
3326 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3328 /* set video parameters */
3329 if (bktr->capture_area_enabled)
3330 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3331 / fp->scaled_htotal / bktr->cols) - 4096;
3333 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3334 / fp->scaled_htotal / bktr->cols) - 4096;
3336 /* kprintf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3337 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3338 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3339 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3340 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3342 /* horizontal active */
3344 /* kprintf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3345 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3346 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3347 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3348 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3349 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3350 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3352 /* horizontal delay */
3353 if (bktr->capture_area_enabled)
3354 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3355 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3357 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3359 temp = temp & 0x3fe;
3361 /* kprintf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3362 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3363 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3364 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3365 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3366 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3367 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3369 /* vertical scale */
3371 if (bktr->capture_area_enabled) {
3372 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3373 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3375 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3378 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3381 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3382 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3384 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3387 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3392 /* kprintf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3393 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3394 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3395 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3396 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3397 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3398 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3401 /* vertical active */
3402 if (bktr->capture_area_enabled)
3403 temp = bktr->capture_area_y_size;
3406 /* kprintf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3407 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3408 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3409 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3410 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3411 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3412 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3414 /* vertical delay */
3415 if (bktr->capture_area_enabled)
3416 temp = fp->vdelay + (bktr->capture_area_y_offset);
3419 /* kprintf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3420 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3421 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3422 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3423 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3424 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3425 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3427 /* end of video params */
3429 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3430 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3431 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3433 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3436 /* capture control */
3439 bktr->bktr_cap_ctl =
3440 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3441 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3442 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3446 bktr->bktr_cap_ctl =
3447 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3448 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3449 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3453 bktr->bktr_cap_ctl =
3454 (BT848_CAP_CTL_DITH_FRAME |
3455 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3456 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3457 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3462 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3467 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3469 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3470 /* user, then use the rgb_vbi RISC program. */
3471 /* Otherwise, use the normal rgb RISC program */
3472 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3473 if ( (bktr->vbiflags & VBI_OPEN)
3474 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3475 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3477 bktr->bktr_cap_ctl |=
3478 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3479 bktr->vbiflags |= VBI_CAPTURE;
3480 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3483 rgb_prog(bktr, i_flag, cols, rows, interlace);
3488 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3489 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3490 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3491 | pixfmt_swap_flags( bktr->pixfmt ));
3495 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3496 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3497 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3498 | pixfmt_swap_flags( bktr->pixfmt ));
3502 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3503 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3504 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3505 | pixfmt_swap_flags( bktr->pixfmt ));
3512 /******************************************************************************
3513 * video & video capture specific routines:
3521 start_capture( bktr_ptr_t bktr, unsigned type )
3524 struct format_params *fp;
3526 fp = &format_params[bktr->format_params];
3528 /* If requested, clear out capture buf first */
3529 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3530 bzero((caddr_t)bktr->bigbuf,
3531 (size_t)bktr->rows * bktr->cols * bktr->frames *
3532 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3535 OUTB(bktr, BKTR_DSTATUS, 0);
3536 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3538 bktr->flags |= type;
3539 bktr->flags &= ~METEOR_WANT_MASK;
3540 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3541 case METEOR_ONLY_EVEN_FIELDS:
3542 bktr->flags |= METEOR_WANT_EVEN;
3545 case METEOR_ONLY_ODD_FIELDS:
3546 bktr->flags |= METEOR_WANT_ODD;
3550 bktr->flags |= METEOR_WANT_MASK;
3555 /* TDEC is only valid for continuous captures */
3556 if ( type == METEOR_SINGLE ) {
3557 u_short fps_save = bktr->fps;
3559 set_fps(bktr, fp->frame_rate);
3560 bktr->fps = fps_save;
3563 set_fps(bktr, bktr->fps);
3565 if (bktr->dma_prog_loaded == FALSE) {
3566 build_dma_prog(bktr, i_flag);
3567 bktr->dma_prog_loaded = TRUE;
3571 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3580 set_fps( bktr_ptr_t bktr, u_short fps )
3582 struct format_params *fp;
3585 fp = &format_params[bktr->format_params];
3587 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3588 case METEOR_ONLY_EVEN_FIELDS:
3589 bktr->flags |= METEOR_WANT_EVEN;
3592 case METEOR_ONLY_ODD_FIELDS:
3593 bktr->flags |= METEOR_WANT_ODD;
3597 bktr->flags |= METEOR_WANT_MASK;
3602 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3603 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3606 OUTB(bktr, BKTR_TDEC, 0);
3608 if (fps < fp->frame_rate)
3609 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3611 OUTB(bktr, BKTR_TDEC, 0);
3621 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3622 * achieve the specified swapping.
3623 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3624 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3626 * Note also that for 3Bpp, we may additionally need to do some creative
3627 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3628 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3629 * as one would expect.
3632 static u_int pixfmt_swap_flags( int pixfmt )
3634 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3637 switch ( pf->Bpp ) {
3638 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3641 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3644 case 4 : if ( pf->swap_bytes )
3645 swapf = pf->swap_shorts ? 0 : WSWAP;
3647 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3656 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3657 * our pixfmt_table indices.
3660 static int oformat_meteor_to_bt( u_long format )
3663 struct meteor_pixfmt *pf1, *pf2;
3665 /* Find format in compatibility table */
3666 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3667 if ( meteor_pixfmt_table[i].meteor_format == format )
3670 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3672 pf1 = &meteor_pixfmt_table[i].public;
3674 /* Match it with an entry in master pixel format table */
3675 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3676 pf2 = &pixfmt_table[i].public;
3678 if (( pf1->type == pf2->type ) &&
3679 ( pf1->Bpp == pf2->Bpp ) &&
3680 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3681 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3682 ( pf1->swap_shorts == pf2->swap_shorts ))
3685 if ( i >= PIXFMT_TABLE_SIZE )
3691 /******************************************************************************
3696 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3697 #define I2CBITTIME_878 (1 << 7)
3698 #define I2C_READ 0x01
3699 #define I2C_COMMAND (I2CBITTIME | \
3700 BT848_DATA_CTL_I2CSCL | \
3701 BT848_DATA_CTL_I2CSDA)
3703 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3704 BT848_DATA_CTL_I2CSCL | \
3705 BT848_DATA_CTL_I2CSDA)
3707 /* Select between old i2c code and new iicbus / smbus code */
3708 #if defined(BKTR_USE_FREEBSD_SMBUS)
3711 * The hardware interface is actually SMB commands
3714 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3718 if (bktr->id == BROOKTREE_848 ||
3719 bktr->id == BROOKTREE_848A ||
3720 bktr->id == BROOKTREE_849A)
3723 cmd = I2C_COMMAND_878;
3726 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3727 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3730 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3731 (char)(byte1 & 0xff)))
3740 i2cRead( bktr_ptr_t bktr, int addr )
3745 if (bktr->id == BROOKTREE_848 ||
3746 bktr->id == BROOKTREE_848A ||
3747 bktr->id == BROOKTREE_849A)
3750 cmd = I2C_COMMAND_878;
3752 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3755 return ((int)((unsigned char)result));
3758 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3760 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3761 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3762 /* Therefore we need low level control of the i2c bus hardware */
3764 /* Write to the MSP or DPL registers */
3766 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3768 unsigned char addr_l, addr_h, data_h, data_l ;
3770 addr_h = (addr >>8) & 0xff;
3771 addr_l = addr & 0xff;
3772 data_h = (data >>8) & 0xff;
3773 data_l = data & 0xff;
3775 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3777 iicbus_write_byte(IICBUS(bktr), dev, 0);
3778 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3779 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3780 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3781 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3783 iicbus_stop(IICBUS(bktr));
3788 /* Read from the MSP or DPL registers */
3790 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3793 unsigned char addr_l, addr_h, dev_r;
3795 u_char data_read[2];
3797 addr_h = (addr >>8) & 0xff;
3798 addr_l = addr & 0xff;
3801 /* XXX errors ignored */
3802 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3804 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3805 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3806 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3808 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3809 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3810 iicbus_stop(IICBUS(bktr));
3812 data = (data_read[0]<<8) | data_read[1];
3817 /* Reset the MSP or DPL chip */
3818 /* The user can block the reset (which is handy if you initialise the
3819 * MSP and/or DPL audio in another operating system first (eg in Windows)
3822 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3825 #ifndef BKTR_NO_MSP_RESET
3826 /* put into reset mode */
3827 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3828 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3829 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3830 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3831 iicbus_stop(IICBUS(bktr));
3833 /* put back to operational mode */
3834 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3835 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3836 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3837 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3838 iicbus_stop(IICBUS(bktr));
3843 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3846 /* XXX errors ignored */
3847 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3848 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3849 iicbus_stop(IICBUS(bktr));
3854 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3857 * Program the i2c bus directly
3860 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3865 /* clear status bits */
3866 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3868 /* build the command datum */
3869 if (bktr->id == BROOKTREE_848 ||
3870 bktr->id == BROOKTREE_848A ||
3871 bktr->id == BROOKTREE_849A) {
3872 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3874 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3876 if ( byte2 != -1 ) {
3877 data |= ((byte2 & 0xff) << 8);
3878 data |= BT848_DATA_CTL_I2CW3B;
3881 /* write the address and data */
3882 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3884 /* wait for completion */
3885 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3886 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3891 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3903 i2cRead( bktr_ptr_t bktr, int addr )
3907 /* clear status bits */
3908 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3910 /* write the READ address */
3911 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3913 if (bktr->id == BROOKTREE_848 ||
3914 bktr->id == BROOKTREE_848A ||
3915 bktr->id == BROOKTREE_849A) {
3916 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3918 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3921 /* wait for completion */
3922 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3923 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3928 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3932 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3935 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3936 /* bt848 automated i2c bus controller cannot handle */
3937 /* Therefore we need low level control of the i2c bus hardware */
3938 /* Idea for the following functions are from elsewhere in this driver and */
3939 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3942 static void i2c_start( bktr_ptr_t bktr) {
3943 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3944 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3945 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3946 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3949 static void i2c_stop( bktr_ptr_t bktr) {
3950 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3951 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3952 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3955 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3959 /* write out the byte */
3960 for ( x = 7; x >= 0; --x ) {
3961 if ( data & (1<<x) ) {
3962 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3963 DELAY( BITD ); /* assert HI data */
3964 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3965 DELAY( BITD ); /* strobe clock */
3966 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3967 DELAY( BITD ); /* release clock */
3970 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3971 DELAY( BITD ); /* assert LO data */
3972 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3973 DELAY( BITD ); /* strobe clock */
3974 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3975 DELAY( BITD ); /* release clock */
3979 /* look for an ACK */
3980 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3981 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3982 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3983 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3988 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3993 /* read in the byte */
3994 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3995 DELAY( BITD ); /* float data */
3996 for ( x = 7; x >= 0; --x ) {
3997 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3998 DELAY( BITD ); /* strobe clock */
3999 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4000 if ( bit ) byte |= (1<<x);
4001 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4002 DELAY( BITD ); /* release clock */
4004 /* After reading the byte, send an ACK */
4005 /* (unless that was the last byte, for which we send a NAK */
4006 if (last) { /* send NAK - same a writing a 1 */
4007 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4008 DELAY( BITD ); /* set data bit */
4009 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4010 DELAY( BITD ); /* strobe clock */
4011 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4012 DELAY( BITD ); /* release clock */
4013 } else { /* send ACK - same as writing a 0 */
4014 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4015 DELAY( BITD ); /* set data bit */
4016 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4017 DELAY( BITD ); /* strobe clock */
4018 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4019 DELAY( BITD ); /* release clock */
4027 /* Write to the MSP or DPL registers */
4028 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4030 unsigned int msp_w_addr = i2c_addr;
4031 unsigned char addr_l, addr_h, data_h, data_l ;
4032 addr_h = (addr >>8) & 0xff;
4033 addr_l = addr & 0xff;
4034 data_h = (data >>8) & 0xff;
4035 data_l = data & 0xff;
4038 i2c_write_byte(bktr, msp_w_addr);
4039 i2c_write_byte(bktr, dev);
4040 i2c_write_byte(bktr, addr_h);
4041 i2c_write_byte(bktr, addr_l);
4042 i2c_write_byte(bktr, data_h);
4043 i2c_write_byte(bktr, data_l);
4047 /* Read from the MSP or DPL registers */
4048 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4050 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4051 addr_h = (addr >>8) & 0xff;
4052 addr_l = addr & 0xff;
4056 i2c_write_byte(bktr,i2c_addr);
4057 i2c_write_byte(bktr,dev_r);
4058 i2c_write_byte(bktr,addr_h);
4059 i2c_write_byte(bktr,addr_l);
4062 i2c_write_byte(bktr,i2c_addr+1);
4063 i2c_read_byte(bktr,&data_1, 0);
4064 i2c_read_byte(bktr,&data_2, 1);
4066 data = (data_1<<8) | data_2;
4070 /* Reset the MSP or DPL chip */
4071 /* The user can block the reset (which is handy if you initialise the
4072 * MSP audio in another operating system first (eg in Windows)
4074 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4076 #ifndef BKTR_NO_MSP_RESET
4077 /* put into reset mode */
4079 i2c_write_byte(bktr, i2c_addr);
4080 i2c_write_byte(bktr, 0x00);
4081 i2c_write_byte(bktr, 0x80);
4082 i2c_write_byte(bktr, 0x00);
4085 /* put back to operational mode */
4087 i2c_write_byte(bktr, i2c_addr);
4088 i2c_write_byte(bktr, 0x00);
4089 i2c_write_byte(bktr, 0x00);
4090 i2c_write_byte(bktr, 0x00);
4097 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4099 /* XXX errors ignored */
4101 i2c_write_byte(bktr,bktr->remote_control_addr);
4102 i2c_read_byte(bktr,&(remote->data[0]), 0);
4103 i2c_read_byte(bktr,&(remote->data[1]), 0);
4104 i2c_read_byte(bktr,&(remote->data[2]), 0);
4110 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4113 #if defined( I2C_SOFTWARE_PROBE )
4116 * we are keeping this around for any parts that we need to probe
4117 * but that CANNOT be probed via an i2c read.
4118 * this is necessary because the hardware i2c mechanism
4119 * cannot be programmed for 1 byte writes.
4120 * currently there are no known i2c parts that we need to probe
4121 * and that cannot be safely read.
4123 static int i2cProbe( bktr_ptr_t bktr, int addr );
4128 * probe for an I2C device at addr.
4131 i2cProbe( bktr_ptr_t bktr, int addr )
4136 #if defined( EXTRA_START )
4137 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4138 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4139 #endif /* EXTRA_START */
4140 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4141 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4144 for ( x = 7; x >= 0; --x ) {
4145 if ( addr & (1<<x) ) {
4146 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4147 DELAY( BITD ); /* assert HI data */
4148 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4149 DELAY( BITD ); /* strobe clock */
4150 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4151 DELAY( BITD ); /* release clock */
4154 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4155 DELAY( BITD ); /* assert LO data */
4156 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4157 DELAY( BITD ); /* strobe clock */
4158 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4159 DELAY( BITD ); /* release clock */
4163 /* look for an ACK */
4164 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4165 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4166 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4167 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4170 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4171 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4172 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4179 #endif /* I2C_SOFTWARE_PROBE */