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>
96 #include <sys/kernel.h>
99 #include <sys/signalvar.h>
100 #include <sys/vnode.h>
101 #include <sys/bus.h> /* used by smbus and newbus */
102 #include <sys/thread2.h>
105 #include <vm/vm_kern.h>
107 #include <vm/vm_extern.h>
110 #define PROC_UNLOCK(p)
111 #include <bus/pci/pcivar.h>
114 #include <dev/video/meteor/ioctl_meteor.h>
115 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
116 #include <dev/video/bktr/bktr_reg.h>
117 #include <dev/video/bktr/bktr_tuner.h>
118 #include <dev/video/bktr/bktr_card.h>
119 #include <dev/video/bktr/bktr_audio.h>
120 #include <dev/video/bktr/bktr_os.h>
121 #include <dev/video/bktr/bktr_core.h>
122 #if defined(KLD_MODULE)
123 #include <dev/video/bktr/bktr_mem.h>
127 bktr_name(bktr_ptr_t bktr)
129 return bktr->bktr_xname;
132 typedef u_char bool_t;
134 #define BKTRPRI PCATCH
135 #define VBIPRI PCATCH
139 * memory allocated for DMA programs
141 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
143 /* When to split a dma transfer , the bt848 has timing as well as
144 dma transfer size limitations so that we have to split dma
145 transfers into two dma requests
147 #define DMA_BT848_SPLIT 319*2
150 * Allocate enough memory for:
151 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
153 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
154 * in your kernel configuration file.
157 #ifndef BROOKTREE_ALLOC_PAGES
158 #define BROOKTREE_ALLOC_PAGES 217*4
160 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
162 /* Definitions for VBI capture.
163 * There are 16 VBI lines in a PAL video field (32 in a frame),
164 * and we take 2044 samples from each line (placed in a 2048 byte buffer
166 * VBI lines are held in a circular buffer before being read by a
167 * user program from /dev/vbi.
170 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
171 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
172 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
173 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
174 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
177 /* Defines for fields */
183 * Parameters describing size of transmitted image.
186 static struct format_params format_params[] = {
187 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
188 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
190 /* # define BT848_IFORM_F_NTSCM (0x1) */
191 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
193 /* # define BT848_IFORM_F_NTSCJ (0x2) */
194 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
196 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
197 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
199 /* # define BT848_IFORM_F_PALM (0x4) */
200 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
202 /* # define BT848_IFORM_F_PALN (0x5) */
203 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
205 /* # define BT848_IFORM_F_SECAM (0x6) */
206 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
208 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
209 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
214 * Table of supported Pixel Formats
217 static struct meteor_pixfmt_internal {
218 struct meteor_pixfmt public;
222 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
223 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
225 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
226 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
228 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
230 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
231 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
232 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
233 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
234 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
235 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
236 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
239 #define PIXFMT_TABLE_SIZE NELEM(pixfmt_table)
242 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
245 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
247 u_long meteor_format;
248 struct meteor_pixfmt public;
249 } meteor_pixfmt_table[] = {
251 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
254 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
255 { METEOR_GEO_YUV_422,
256 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
258 { METEOR_GEO_YUV_PACKED,
259 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
262 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
265 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
269 #define METEOR_PIXFMT_TABLE_SIZE NELEM(meteor_pixfmt_table)
272 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
273 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
277 /* sync detect threshold */
279 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
280 BT848_ADC_CRUSH) /* threshold ~125 mV */
282 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
283 BT848_ADC_SYNC_T) /* threshold ~75 mV */
289 /* debug utility for holding previous INT_STAT contents */
291 static u_long status_sum = 0;
294 * defines to make certain bit-fiddles understandable
296 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
297 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
298 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
299 #define FIFO_RISC_DISABLED 0
301 #define ALL_INTS_DISABLED 0
302 #define ALL_INTS_CLEARED 0xffffffff
303 #define CAPTURE_OFF 0
305 #define BIT_SEVEN_HIGH (1<<7)
306 #define BIT_EIGHT_HIGH (1<<8)
308 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
309 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
313 static int oformat_meteor_to_bt( u_long format );
315 static u_int pixfmt_swap_flags( int pixfmt );
318 * bt848 RISC programming routines.
321 static int dump_bt848( bktr_ptr_t bktr );
324 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
325 int rows, int interlace );
326 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
327 int rows, int interlace );
328 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
329 int rows, int interlace );
330 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
331 int rows, int interlace );
332 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
333 int rows, int interlace );
334 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
336 static bool_t getline(bktr_reg_t *, int);
337 static bool_t notclipped(bktr_reg_t * , int , int);
338 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
339 volatile u_char ** , int );
341 static void start_capture( bktr_ptr_t bktr, unsigned type );
342 static void set_fps( bktr_ptr_t bktr, u_short fps );
347 * Remote Control Functions
349 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
353 * ioctls common to both video & tuner.
355 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
359 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
361 static void i2c_start( bktr_ptr_t bktr);
362 static void i2c_stop( bktr_ptr_t bktr);
363 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
364 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
369 * the common attach code, used by all OS versions.
372 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
375 int need_to_allocate_memory = 1;
376 #ifdef BKTR_NEW_MSP34XX_DRIVER
380 /* If this is a module, check if there is any currently saved contiguous memory */
381 #if defined(KLD_MODULE)
382 if (bktr_has_stored_addresses(unit) == 1) {
383 /* recover the addresses */
384 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
385 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
386 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
387 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
388 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
389 need_to_allocate_memory = 0;
393 if (need_to_allocate_memory == 1) {
394 /* allocate space for dma program */
395 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
396 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
398 /* allocte space for the VBI buffer */
399 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
400 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
402 /* allocate space for pixel buffer */
403 if ( BROOKTREE_ALLOC )
404 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
410 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
413 /* If this is a module, save the current contiguous memory */
414 #if defined(KLD_MODULE)
415 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
416 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
417 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
418 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
419 bktr_store_address(unit, BKTR_MEM_BUF, buf);
424 kprintf("%s: buffer size %d, addr %p\n",
425 bktr_name(bktr), BROOKTREE_ALLOC,
426 (void *)(uintptr_t)vtophys(buf));
431 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
432 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
434 bktr->alloc_pages = 0;
438 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
439 METEOR_DEV0 | METEOR_RGB16;
440 bktr->dma_prog_loaded = FALSE;
443 bktr->frames = 1; /* one frame */
444 bktr->format = METEOR_GEO_RGB16;
445 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
446 bktr->pixfmt_compat = TRUE;
455 /* using the pci device id and revision id */
456 /* and determine the card type */
457 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
459 switch (PCI_PRODUCT(pci_id)) {
460 case PCI_PRODUCT_BROOKTREE_BT848:
462 bktr->id = BROOKTREE_848A;
464 bktr->id = BROOKTREE_848;
466 case PCI_PRODUCT_BROOKTREE_BT849:
467 bktr->id = BROOKTREE_849A;
469 case PCI_PRODUCT_BROOKTREE_BT878:
470 bktr->id = BROOKTREE_878;
472 case PCI_PRODUCT_BROOKTREE_BT879:
473 bktr->id = BROOKTREE_879;
478 bktr->clr_on_start = FALSE;
480 /* defaults for the tuner section of the card */
481 bktr->tflags = TUNER_INITALIZED;
482 bktr->tuner.frequency = 0;
483 bktr->tuner.channel = 0;
484 bktr->tuner.chnlset = DEFAULT_CHNLSET;
486 bktr->tuner.radio_mode = 0;
487 bktr->audio_mux_select = 0;
488 bktr->audio_mute_state = FALSE;
489 bktr->bt848_card = -1;
490 bktr->bt848_tuner = -1;
491 bktr->reverse_mute = -1;
492 bktr->slow_msp_audio = 0;
493 bktr->msp_use_mono_source = 0;
494 bktr->msp_source_selected = -1;
495 bktr->audio_mux_present = 1;
497 #ifdef BKTR_NEW_MSP34XX_DRIVER
498 /* get hint on short programming of the msp34xx, so we know */
499 /* if the decision what thread to start should be overwritten */
500 if ( (err = resource_int_value("bktr", unit, "mspsimple",
501 &(bktr->mspsimple)) ) != 0 )
502 bktr->mspsimple = -1; /* fall back to default */
505 probeCard( bktr, TRUE, unit );
507 /* Initialise any MSP34xx or TDA98xx audio chips */
508 init_audio_devices( bktr );
510 #ifdef BKTR_NEW_MSP34XX_DRIVER
511 /* setup the kenrel thread */
512 err = msp_attach( bktr );
513 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
514 bktr->card.msp3400c = 0;
521 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
522 * The circular buffer holds 'n' fixed size data blocks.
523 * vbisize is the number of bytes in the circular buffer
524 * vbiread is the point we reading data out of the circular buffer
525 * vbiinsert is the point we insert data into the circular buffer
527 static void vbidecode(bktr_ptr_t bktr) {
529 unsigned int *seq_dest;
531 /* Check if there is room in the buffer to insert the data. */
532 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
534 /* Copy the VBI data into the next free slot in the buffer. */
535 /* 'dest' is the point in vbibuffer where we want to insert new data */
536 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
537 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
539 /* Write the VBI sequence number to the end of the vbi data */
540 /* This is used by the AleVT teletext program */
541 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
543 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
544 *seq_dest = bktr->vbi_sequence_number;
546 /* And increase the VBI sequence number */
547 /* This can wrap around */
548 bktr->vbi_sequence_number++;
551 /* Increment the vbiinsert pointer */
552 /* This can wrap around */
553 bktr->vbiinsert += VBI_DATA_SIZE;
554 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
556 /* And increase the amount of vbi data in the buffer */
557 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
563 * the common interrupt handler.
564 * Returns a 0 or 1 depending on whether the interrupt has handled.
565 * In the OS specific section, bktr_intr() is defined which calls this
566 * common interrupt handler.
569 common_bktr_intr( void *arg )
578 bktr = (bktr_ptr_t) arg;
581 * check to see if any interrupts are unmasked on this device. If
582 * none are, then we likely got here by way of being on a PCI shared
583 * interrupt dispatch list.
585 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
586 return 0; /* bail out now, before we do something we
589 if (!(bktr->flags & METEOR_OPEN)) {
590 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
591 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
595 /* record and clear the INTerrupt status bits */
596 bktr_status = INL(bktr, BKTR_INT_STAT);
597 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
599 /* record and clear the device status register */
600 dstatus = INB(bktr, BKTR_DSTATUS);
601 OUTB(bktr, BKTR_DSTATUS, 0x00);
603 #if defined( STATUS_SUM )
604 /* add any new device status or INTerrupt status bits */
605 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
606 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
607 #endif /* STATUS_SUM */
608 /* kprintf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
609 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
613 /* if risc was disabled re-start process again */
614 /* if there was one of the following errors re-start again */
615 if ( !(bktr_status & BT848_INT_RISC_EN) ||
616 ((bktr_status &(/* BT848_INT_FBUS | */
617 /* BT848_INT_FTRGT | */
618 /* BT848_INT_FDSR | */
620 BT848_INT_RIPERR | BT848_INT_PABORT |
621 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
622 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
624 u_short tdec_save = INB(bktr, BKTR_TDEC);
626 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
627 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
629 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
631 /* Reset temporal decimation counter */
632 OUTB(bktr, BKTR_TDEC, 0);
633 OUTB(bktr, BKTR_TDEC, tdec_save);
635 /* Reset to no-fields captured state */
636 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
637 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
638 case METEOR_ONLY_ODD_FIELDS:
639 bktr->flags |= METEOR_WANT_ODD;
641 case METEOR_ONLY_EVEN_FIELDS:
642 bktr->flags |= METEOR_WANT_EVEN;
645 bktr->flags |= METEOR_WANT_MASK;
650 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
651 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
652 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
654 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
659 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
663 /* If this is not a RISC program interrupt, return */
664 if (!(bktr_status & BT848_INT_RISCI))
668 kprintf( "%s: intr status %x %x %x\n", bktr_name(bktr),
669 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
674 * Disable future interrupts if a capture mode is not selected.
675 * This can happen when we are in the process of closing or
676 * changing capture modes, otherwise it shouldn't happen.
678 if (!(bktr->flags & METEOR_CAP_MASK))
679 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
682 /* Determine which field generated this interrupt */
683 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
687 * Process the VBI data if it is being captured. We do this once
688 * both Odd and Even VBI data is captured. Therefore we do this
689 * in the Even field interrupt handler.
692 if ( (bktr->vbiflags & VBI_CAPTURE)
693 &&(bktr->vbiflags & VBI_OPEN)
695 /* Put VBI data into circular buffer */
698 /* If someone is blocked on reading from /dev/vbi, wake them */
699 if (bktr->vbi_read_blocked) {
700 bktr->vbi_read_blocked = FALSE;
704 /* Inform anyone who is polling */
705 KNOTE(&bktr->vbi_kq.ki_note, 0);
711 * Register the completed field
712 * (For dual-field mode, require fields from the same frame)
714 switch ( bktr->flags & METEOR_WANT_MASK ) {
715 case METEOR_WANT_ODD : w_field = ODD_F ; break;
716 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
717 default : w_field = (ODD_F|EVEN_F); break;
719 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
720 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
721 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
722 default : req_field = (ODD_F|EVEN_F);
726 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
727 bktr->flags &= ~METEOR_WANT_EVEN;
728 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
729 ( w_field == ODD_F ))
730 bktr->flags &= ~METEOR_WANT_ODD;
731 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
732 ( w_field == (ODD_F|EVEN_F) ))
733 bktr->flags &= ~METEOR_WANT_ODD;
734 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
735 ( w_field == ODD_F )) {
736 bktr->flags &= ~METEOR_WANT_ODD;
737 bktr->flags |= METEOR_WANT_EVEN;
740 /* We're out of sync. Start over. */
741 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
742 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
743 case METEOR_ONLY_ODD_FIELDS:
744 bktr->flags |= METEOR_WANT_ODD;
746 case METEOR_ONLY_EVEN_FIELDS:
747 bktr->flags |= METEOR_WANT_EVEN;
750 bktr->flags |= METEOR_WANT_MASK;
758 * If we have a complete frame.
760 if (!(bktr->flags & METEOR_WANT_MASK)) {
761 bktr->frames_captured++;
763 * post the completion time.
765 if (bktr->flags & METEOR_WANT_TS) {
768 if ((u_int) bktr->alloc_pages * PAGE_SIZE
769 <= (bktr->frame_size + sizeof(struct timeval))) {
770 ts =(struct timeval *)bktr->bigbuf +
772 /* doesn't work in synch mode except
781 * Wake up the user in single capture mode.
783 if (bktr->flags & METEOR_SINGLE) {
786 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
788 /* disable risc, leave fifo running */
789 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
794 * If the user requested to be notified via signal,
795 * let them know the frame is complete.
798 if (bktr->proc != NULL) {
799 PROC_LOCK(bktr->proc);
800 ksignal( bktr->proc, bktr->signal);
801 PROC_UNLOCK(bktr->proc);
805 * Reset the want flags if in continuous or
806 * synchronous capture mode.
810 * currently we only support 3 capture modes: odd only, even only,
811 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
812 * either even OR odd) could provide 60 (50 for PAL) pictures per
813 * second, but it would require this routine to toggle the desired frame
814 * each time, and one more different DMA program for the Bt848.
815 * As a consequence, this fourth mode is currently unsupported.
818 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
819 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
820 case METEOR_ONLY_ODD_FIELDS:
821 bktr->flags |= METEOR_WANT_ODD;
823 case METEOR_ONLY_EVEN_FIELDS:
824 bktr->flags |= METEOR_WANT_EVEN;
827 bktr->flags |= METEOR_WANT_MASK;
842 extern int bt848_format; /* used to set the default format, PAL or NTSC */
844 video_open( bktr_ptr_t bktr )
846 int frame_rate, video_format=0;
848 if (bktr->flags & METEOR_OPEN) /* device is busy */
851 bktr->flags |= METEOR_OPEN;
857 bktr->clr_on_start = FALSE;
859 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
861 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
863 #if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
869 if (bt848_format == 0 )
872 if (bt848_format == 1 )
875 if (video_format == 1 ) {
876 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
877 bktr->format_params = BT848_IFORM_F_NTSCM;
880 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
881 bktr->format_params = BT848_IFORM_F_PALBDGHI;
885 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
887 /* work around for new Hauppauge 878 cards */
888 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
889 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
890 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
892 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
894 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
895 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
896 frame_rate = format_params[bktr->format_params].frame_rate;
898 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
899 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
900 OUTB(bktr, BKTR_TGCTRL, 0);
901 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
902 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
903 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
906 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
908 bktr->max_clip_node = 0;
910 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
912 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
913 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
915 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
916 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
917 OUTB(bktr, BKTR_E_SCLOOP, 0);
918 OUTB(bktr, BKTR_O_SCLOOP, 0);
920 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
921 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
923 bktr->fifo_errors = 0;
924 bktr->dma_errors = 0;
925 bktr->frames_captured = 0;
926 bktr->even_fields_captured = 0;
927 bktr->odd_fields_captured = 0;
929 set_fps(bktr, frame_rate);
930 bktr->video.addr = 0;
931 bktr->video.width = 0;
932 bktr->video.banksize = 0;
933 bktr->video.ramsize = 0;
934 bktr->pixfmt_compat = TRUE;
935 bktr->format = METEOR_GEO_RGB16;
936 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
938 bktr->capture_area_enabled = FALSE;
940 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
941 based motherboards will
942 operate unreliably */
947 vbi_open( bktr_ptr_t bktr )
952 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
957 bktr->vbiflags |= VBI_OPEN;
959 /* reset the VBI circular buffer pointers and clear the buffers */
963 bktr->vbi_sequence_number = 0;
964 bktr->vbi_read_blocked = FALSE;
966 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
967 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
978 tuner_open( bktr_ptr_t bktr )
980 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
983 if ( bktr->tflags & TUNER_OPEN ) /* already open */
986 bktr->tflags |= TUNER_OPEN;
987 bktr->tuner.frequency = 0;
988 bktr->tuner.channel = 0;
989 bktr->tuner.chnlset = DEFAULT_CHNLSET;
991 bktr->tuner.radio_mode = 0;
993 /* enable drivers on the GPIO port that control the MUXes */
994 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
996 /* unmute the audio stream */
997 set_audio( bktr, AUDIO_UNMUTE );
999 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1000 init_audio_devices( bktr );
1012 video_close( bktr_ptr_t bktr )
1014 bktr->flags &= ~(METEOR_OPEN |
1019 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1020 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1022 bktr->dma_prog_loaded = FALSE;
1023 OUTB(bktr, BKTR_TDEC, 0);
1024 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1026 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1027 OUTL(bktr, BKTR_SRESET, 0xf);
1028 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1035 * tuner close handle,
1036 * place holder for tuner specific operations on a close.
1039 tuner_close( bktr_ptr_t bktr )
1041 bktr->tflags &= ~TUNER_OPEN;
1043 /* mute the audio by switching the mux */
1044 set_audio( bktr, AUDIO_MUTE );
1046 /* disable drivers on the GPIO port that control the MUXes */
1047 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1053 vbi_close( bktr_ptr_t bktr )
1058 bktr->vbiflags &= ~VBI_OPEN;
1069 video_read(bktr_ptr_t bktr, int unit, cdev_t dev, struct uio *uio)
1075 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1078 if (bktr->flags & METEOR_CAP_MASK)
1079 return( EIO ); /* already capturing */
1081 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1084 count = bktr->rows * bktr->cols *
1085 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1087 if ((int) uio->uio_iov->iov_len < count)
1090 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1092 /* capture one frame */
1093 start_capture(bktr, METEOR_SINGLE);
1094 /* wait for capture to complete */
1095 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1096 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1097 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1098 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1104 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1105 if (!status) /* successful capture */
1106 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1108 kprintf ("%s: read: tsleep error %d\n",
1109 bktr_name(bktr), status);
1111 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1117 * Read VBI data from the vbi circular buffer
1118 * The buffer holds vbi data blocks which are the same size
1119 * vbiinsert is the position we will insert the next item into the buffer
1120 * vbistart is the actual position in the buffer we want to read from
1121 * vbisize is the exact number of bytes in the buffer left to read
1124 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1126 int readsize, readsize2, start;
1130 * XXX - vbi_read() should be protected against being re-entered
1131 * while it is unlocked for the uiomove.
1135 while(bktr->vbisize == 0) {
1136 if (ioflag & IO_NDELAY) {
1137 status = EWOULDBLOCK;
1141 bktr->vbi_read_blocked = TRUE;
1143 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1148 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1154 /* Now we have some data to give to the user */
1156 /* We cannot read more bytes than there are in
1157 * the circular buffer
1159 readsize = (int)uio->uio_iov->iov_len;
1161 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1163 /* Check if we can read this number of bytes without having
1164 * to wrap around the circular buffer */
1165 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1166 /* We need to wrap around */
1168 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1169 start = bktr->vbistart;
1171 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1173 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1176 /* We do not need to wrap around */
1177 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1182 /* Update the number of bytes left to read */
1183 bktr->vbisize -= readsize;
1185 /* Update vbistart */
1186 bktr->vbistart += readsize;
1187 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1202 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1204 volatile u_char c_temp;
1206 unsigned int temp_iform;
1208 struct meteor_geomet *geo;
1209 struct meteor_counts *counts;
1210 struct meteor_video *video;
1211 struct bktr_capture_area *cap_area;
1219 case BT848SCLIP: /* set clip region */
1220 bktr->max_clip_node = 0;
1221 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1223 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1224 if (bktr->clip_list[i].y_min == 0 &&
1225 bktr->clip_list[i].y_max == 0)
1228 bktr->max_clip_node = i;
1230 /* make sure that the list contains a valid clip secquence */
1231 /* the clip rectangles should be sorted by x then by y as the
1232 second order sort key */
1234 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1236 /* to disable clipping set y_min and y_max to 0 in the first
1237 clip rectangle . The first clip rectangle is clip_list[0].
1242 if (bktr->max_clip_node == 0 &&
1243 (bktr->clip_list[0].y_min != 0 &&
1244 bktr->clip_list[0].y_max != 0)) {
1248 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1249 if (bktr->clip_list[i].y_min == 0 &&
1250 bktr->clip_list[i].y_max == 0) {
1253 if ( bktr->clip_list[i+1].y_min != 0 &&
1254 bktr->clip_list[i+1].y_max != 0 &&
1255 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1257 bktr->max_clip_node = 0;
1262 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1263 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1264 bktr->clip_list[i].x_min < 0 ||
1265 bktr->clip_list[i].x_max < 0 ||
1266 bktr->clip_list[i].y_min < 0 ||
1267 bktr->clip_list[i].y_max < 0 ) {
1268 bktr->max_clip_node = 0;
1273 bktr->dma_prog_loaded = FALSE;
1277 case METEORSTATUS: /* get Bt848 status */
1278 c_temp = INB(bktr, BKTR_DSTATUS);
1280 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1281 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1282 *(u_short *)arg = temp;
1285 case BT848SFMT: /* set input format */
1286 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1287 temp_iform = INB(bktr, BKTR_IFORM);
1288 temp_iform &= ~BT848_IFORM_FORMAT;
1289 temp_iform &= ~BT848_IFORM_XTSEL;
1290 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1292 case BT848_IFORM_F_AUTO:
1293 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1297 case BT848_IFORM_F_NTSCM:
1298 case BT848_IFORM_F_NTSCJ:
1299 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1301 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1302 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1303 bktr->format_params = temp;
1306 case BT848_IFORM_F_PALBDGHI:
1307 case BT848_IFORM_F_PALN:
1308 case BT848_IFORM_F_SECAM:
1309 case BT848_IFORM_F_RSVD:
1310 case BT848_IFORM_F_PALM:
1311 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1313 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1314 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1315 bktr->format_params = temp;
1319 bktr->dma_prog_loaded = FALSE;
1322 case METEORSFMT: /* set input format */
1323 temp_iform = INB(bktr, BKTR_IFORM);
1324 temp_iform &= ~BT848_IFORM_FORMAT;
1325 temp_iform &= ~BT848_IFORM_XTSEL;
1326 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1327 case 0: /* default */
1328 case METEOR_FMT_NTSC:
1329 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1331 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1332 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1333 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1334 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1335 bktr->format_params = BT848_IFORM_F_NTSCM;
1338 case METEOR_FMT_PAL:
1339 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1341 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1342 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1343 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1344 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1345 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1348 case METEOR_FMT_AUTOMODE:
1349 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1351 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1352 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1358 bktr->dma_prog_loaded = FALSE;
1361 case METEORGFMT: /* get input format */
1362 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1366 case BT848GFMT: /* get input format */
1367 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1370 case METEORSCOUNT: /* (re)set error counts */
1371 counts = (struct meteor_counts *) arg;
1372 bktr->fifo_errors = counts->fifo_errors;
1373 bktr->dma_errors = counts->dma_errors;
1374 bktr->frames_captured = counts->frames_captured;
1375 bktr->even_fields_captured = counts->even_fields_captured;
1376 bktr->odd_fields_captured = counts->odd_fields_captured;
1379 case METEORGCOUNT: /* get error counts */
1380 counts = (struct meteor_counts *) arg;
1381 counts->fifo_errors = bktr->fifo_errors;
1382 counts->dma_errors = bktr->dma_errors;
1383 counts->frames_captured = bktr->frames_captured;
1384 counts->even_fields_captured = bktr->even_fields_captured;
1385 counts->odd_fields_captured = bktr->odd_fields_captured;
1389 video = (struct meteor_video *)arg;
1390 video->addr = bktr->video.addr;
1391 video->width = bktr->video.width;
1392 video->banksize = bktr->video.banksize;
1393 video->ramsize = bktr->video.ramsize;
1397 video = (struct meteor_video *)arg;
1398 bktr->video.addr = video->addr;
1399 bktr->video.width = video->width;
1400 bktr->video.banksize = video->banksize;
1401 bktr->video.ramsize = video->ramsize;
1405 set_fps(bktr, *(u_short *)arg);
1409 *(u_short *)arg = bktr->fps;
1412 case METEORSHUE: /* set hue */
1413 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1416 case METEORGHUE: /* get hue */
1417 *(u_char *)arg = INB(bktr, BKTR_HUE);
1420 case METEORSBRIG: /* set brightness */
1421 char_temp = ( *(u_char *)arg & 0xff) - 128;
1422 OUTB(bktr, BKTR_BRIGHT, char_temp);
1426 case METEORGBRIG: /* get brightness */
1427 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1430 case METEORSCSAT: /* set chroma saturation */
1431 temp = (int)*(u_char *)arg;
1433 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1434 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1435 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1436 & ~(BT848_E_CONTROL_SAT_U_MSB
1437 | BT848_E_CONTROL_SAT_V_MSB));
1438 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1439 & ~(BT848_O_CONTROL_SAT_U_MSB |
1440 BT848_O_CONTROL_SAT_V_MSB));
1442 if ( temp & BIT_SEVEN_HIGH ) {
1443 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1444 | (BT848_E_CONTROL_SAT_U_MSB
1445 | BT848_E_CONTROL_SAT_V_MSB));
1446 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1447 | (BT848_O_CONTROL_SAT_U_MSB
1448 | BT848_O_CONTROL_SAT_V_MSB));
1452 case METEORGCSAT: /* get chroma saturation */
1453 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1454 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1455 temp |= BIT_SEVEN_HIGH;
1456 *(u_char *)arg = (u_char)temp;
1459 case METEORSCONT: /* set contrast */
1460 temp = (int)*(u_char *)arg & 0xff;
1462 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1463 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1464 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1465 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1466 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1467 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1468 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1471 case METEORGCONT: /* get contrast */
1472 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1473 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1474 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1477 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1478 bktr->clr_on_start = (*(int *)arg != 0);
1481 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1482 *(int *)arg = (int) bktr->clr_on_start;
1487 /* Historically, applications used METEOR_SIG_MODE_MASK
1488 * to reset signal delivery.
1490 if (sig == METEOR_SIG_MODE_MASK)
1492 if (sig < 0 || sig > _SIG_MAXSIG)
1495 bktr->proc = sig ? td->td_proc : NULL;
1499 *(int *)arg = bktr->signal;
1504 switch (*(int *) arg) {
1505 case METEOR_CAP_SINGLE:
1507 if (bktr->bigbuf==0) /* no frame buffer allocated */
1509 /* already capturing */
1510 if (temp & METEOR_CAP_MASK)
1515 start_capture(bktr, METEOR_SINGLE);
1517 /* wait for capture to complete */
1518 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1519 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1520 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1522 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1527 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1528 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1529 if (error && (error != ERESTART)) {
1530 /* Here if we didn't get complete frame */
1532 kprintf( "%s: ioctl: tsleep error %d %x\n",
1533 bktr_name(bktr), error,
1534 INL(bktr, BKTR_RISC_COUNT));
1538 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1540 /* disable risc, leave fifo running */
1541 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1544 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1545 /* FIXME: should we set bt848->int_stat ??? */
1548 case METEOR_CAP_CONTINOUS:
1549 if (bktr->bigbuf==0) /* no frame buffer allocated */
1551 /* already capturing */
1552 if (temp & METEOR_CAP_MASK)
1556 start_capture(bktr, METEOR_CONTIN);
1558 /* Clear the interrypt status register */
1559 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1561 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1562 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1563 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1565 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1574 case METEOR_CAP_STOP_CONT:
1575 if (bktr->flags & METEOR_CONTIN) {
1576 /* turn off capture */
1577 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1578 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1579 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1581 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1588 /* can't change parameters while capturing */
1589 if (bktr->flags & METEOR_CAP_MASK)
1593 geo = (struct meteor_geomet *) arg;
1596 /* Either even or odd, if even & odd, then these a zero */
1597 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1598 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1599 kprintf( "%s: ioctl: Geometry odd or even only.\n",
1604 /* set/clear even/odd flags */
1605 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1606 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1608 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1609 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1610 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1612 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1614 if (geo->columns <= 0) {
1616 "%s: ioctl: %d: columns must be greater than zero.\n",
1617 bktr_name(bktr), geo->columns);
1620 else if ((geo->columns & 0x3fe) != geo->columns) {
1622 "%s: ioctl: %d: columns too large or not even.\n",
1623 bktr_name(bktr), geo->columns);
1627 if (geo->rows <= 0) {
1629 "%s: ioctl: %d: rows must be greater than zero.\n",
1630 bktr_name(bktr), geo->rows);
1633 else if (((geo->rows & 0x7fe) != geo->rows) ||
1634 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1635 ((geo->rows & 0x3fe) != geo->rows)) ) {
1637 "%s: ioctl: %d: rows too large or not even.\n",
1638 bktr_name(bktr), geo->rows);
1642 if (geo->frames > 32) {
1643 kprintf("%s: ioctl: too many frames.\n",
1652 bktr->dma_prog_loaded = FALSE;
1653 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1655 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1657 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1658 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1660 /* meteor_mem structure for SYNC Capture */
1661 if (geo->frames > 1) temp += PAGE_SIZE;
1664 if ((int) temp > bktr->alloc_pages
1665 && bktr->video.addr == 0) {
1667 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1669 kmem_free(&kernel_map, bktr->bigbuf,
1670 (bktr->alloc_pages * PAGE_SIZE));
1673 bktr->alloc_pages = temp;
1676 "%s: ioctl: Allocating %d bytes\n",
1677 bktr_name(bktr), temp*PAGE_SIZE);
1687 bktr->rows = geo->rows;
1688 bktr->cols = geo->columns;
1689 bktr->frames = geo->frames;
1691 /* Pixel format (if in meteor pixfmt compatibility mode) */
1692 if ( bktr->pixfmt_compat ) {
1693 bktr->format = METEOR_GEO_YUV_422;
1694 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1695 case 0: /* default */
1696 case METEOR_GEO_RGB16:
1697 bktr->format = METEOR_GEO_RGB16;
1699 case METEOR_GEO_RGB24:
1700 bktr->format = METEOR_GEO_RGB24;
1702 case METEOR_GEO_YUV_422:
1703 bktr->format = METEOR_GEO_YUV_422;
1704 if (geo->oformat & METEOR_GEO_YUV_12)
1705 bktr->format = METEOR_GEO_YUV_12;
1707 case METEOR_GEO_YUV_PACKED:
1708 bktr->format = METEOR_GEO_YUV_PACKED;
1711 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1714 if (bktr->flags & METEOR_CAP_MASK) {
1716 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1717 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1718 case METEOR_ONLY_ODD_FIELDS:
1719 bktr->flags |= METEOR_WANT_ODD;
1721 case METEOR_ONLY_EVEN_FIELDS:
1722 bktr->flags |= METEOR_WANT_EVEN;
1725 bktr->flags |= METEOR_WANT_MASK;
1729 start_capture(bktr, METEOR_CONTIN);
1730 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1731 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1732 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1733 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1739 /* end of METEORSETGEO */
1741 /* FIXME. The Capture Area currently has the following restrictions:
1743 y_offset may need to be even in interlaced modes
1744 RGB24 - Interlaced mode
1745 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1746 y_size must be greater than or equal to METEORSETGEO height (rows)
1747 RGB24 - Even Only (or Odd Only) mode
1748 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1749 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1750 YUV12 - Interlaced mode
1751 x_size must be greater than or equal to METEORSETGEO width (cols)
1752 y_size must be greater than or equal to METEORSETGEO height (rows)
1753 YUV12 - Even Only (or Odd Only) mode
1754 x_size must be greater than or equal to METEORSETGEO width (cols)
1755 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1758 case BT848_SCAPAREA: /* set capture area of each video frame */
1759 /* can't change parameters while capturing */
1760 if (bktr->flags & METEOR_CAP_MASK)
1763 cap_area = (struct bktr_capture_area *) arg;
1764 bktr->capture_area_x_offset = cap_area->x_offset;
1765 bktr->capture_area_y_offset = cap_area->y_offset;
1766 bktr->capture_area_x_size = cap_area->x_size;
1767 bktr->capture_area_y_size = cap_area->y_size;
1768 bktr->capture_area_enabled = TRUE;
1770 bktr->dma_prog_loaded = FALSE;
1773 case BT848_GCAPAREA: /* get capture area of each video frame */
1774 cap_area = (struct bktr_capture_area *) arg;
1775 if (bktr->capture_area_enabled == FALSE) {
1776 cap_area->x_offset = 0;
1777 cap_area->y_offset = 0;
1778 cap_area->x_size = format_params[
1779 bktr->format_params].scaled_hactive;
1780 cap_area->y_size = format_params[
1781 bktr->format_params].vactive;
1783 cap_area->x_offset = bktr->capture_area_x_offset;
1784 cap_area->y_offset = bktr->capture_area_y_offset;
1785 cap_area->x_size = bktr->capture_area_x_size;
1786 cap_area->y_size = bktr->capture_area_y_size;
1791 return common_ioctl( bktr, cmd, arg );
1801 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1817 /* Read the last key pressed by the Remote Control */
1818 if (bktr->remote_control == 0) return (EINVAL);
1819 remote_read(bktr, (struct bktr_remote *)arg);
1822 #if defined( TUNER_AFC )
1823 case TVTUNER_SETAFC:
1824 bktr->tuner.afc = (*(int *)arg != 0);
1827 case TVTUNER_GETAFC:
1828 *(int *)arg = bktr->tuner.afc;
1829 /* XXX Perhaps use another bit to indicate AFC success? */
1831 #endif /* TUNER_AFC */
1833 case TVTUNER_SETCHNL:
1834 temp_mute( bktr, TRUE );
1835 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1837 temp_mute( bktr, FALSE );
1840 *(unsigned long *)arg = temp;
1842 /* after every channel change, we must restart the MSP34xx */
1843 /* audio chip to reselect NICAM STEREO or MONO audio */
1844 if ( bktr->card.msp3400c )
1845 msp_autodetect( bktr );
1847 /* after every channel change, we must restart the DPL35xx */
1848 if ( bktr->card.dpl3518a )
1849 dpl_autodetect( bktr );
1851 temp_mute( bktr, FALSE );
1854 case TVTUNER_GETCHNL:
1855 *(unsigned long *)arg = bktr->tuner.channel;
1858 case TVTUNER_SETTYPE:
1859 temp = *(unsigned long *)arg;
1860 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1862 bktr->tuner.chnlset = temp;
1865 case TVTUNER_GETTYPE:
1866 *(unsigned long *)arg = bktr->tuner.chnlset;
1869 case TVTUNER_GETSTATUS:
1870 temp = get_tuner_status( bktr );
1871 *(unsigned long *)arg = temp & 0xff;
1874 case TVTUNER_SETFREQ:
1875 temp_mute( bktr, TRUE );
1876 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1877 temp_mute( bktr, FALSE );
1879 temp_mute( bktr, FALSE );
1882 *(unsigned long *)arg = temp;
1884 /* after every channel change, we must restart the MSP34xx */
1885 /* audio chip to reselect NICAM STEREO or MONO audio */
1886 if ( bktr->card.msp3400c )
1887 msp_autodetect( bktr );
1889 /* after every channel change, we must restart the DPL35xx */
1890 if ( bktr->card.dpl3518a )
1891 dpl_autodetect( bktr );
1893 temp_mute( bktr, FALSE );
1896 case TVTUNER_GETFREQ:
1897 *(unsigned long *)arg = bktr->tuner.frequency;
1900 case TVTUNER_GETCHNLSET:
1901 return tuner_getchnlset((struct bktr_chnlset *)arg);
1903 case BT848_SAUDIO: /* set audio channel */
1904 if ( set_audio( bktr, *(int*)arg ) < 0 )
1908 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1909 case BT848_SHUE: /* set hue */
1910 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1913 case BT848_GHUE: /* get hue */
1914 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1917 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1918 case BT848_SBRIG: /* set brightness */
1919 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1922 case BT848_GBRIG: /* get brightness */
1923 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1927 case BT848_SCSAT: /* set chroma saturation */
1928 tmp_int = *(int*)arg;
1930 temp = INB(bktr, BKTR_E_CONTROL);
1931 temp1 = INB(bktr, BKTR_O_CONTROL);
1932 if ( tmp_int & BIT_EIGHT_HIGH ) {
1933 temp |= (BT848_E_CONTROL_SAT_U_MSB |
1934 BT848_E_CONTROL_SAT_V_MSB);
1935 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1936 BT848_O_CONTROL_SAT_V_MSB);
1939 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1940 BT848_E_CONTROL_SAT_V_MSB);
1941 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1942 BT848_O_CONTROL_SAT_V_MSB);
1945 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1946 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1947 OUTB(bktr, BKTR_E_CONTROL, temp);
1948 OUTB(bktr, BKTR_O_CONTROL, temp1);
1951 case BT848_GCSAT: /* get chroma saturation */
1952 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1953 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1954 tmp_int |= BIT_EIGHT_HIGH;
1955 *(int*)arg = tmp_int;
1959 case BT848_SVSAT: /* set chroma V saturation */
1960 tmp_int = *(int*)arg;
1962 temp = INB(bktr, BKTR_E_CONTROL);
1963 temp1 = INB(bktr, BKTR_O_CONTROL);
1964 if ( tmp_int & BIT_EIGHT_HIGH) {
1965 temp |= BT848_E_CONTROL_SAT_V_MSB;
1966 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1969 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1970 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1973 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1974 OUTB(bktr, BKTR_E_CONTROL, temp);
1975 OUTB(bktr, BKTR_O_CONTROL, temp1);
1978 case BT848_GVSAT: /* get chroma V saturation */
1979 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1980 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1981 tmp_int |= BIT_EIGHT_HIGH;
1982 *(int*)arg = tmp_int;
1986 case BT848_SUSAT: /* set chroma U saturation */
1987 tmp_int = *(int*)arg;
1989 temp = INB(bktr, BKTR_E_CONTROL);
1990 temp1 = INB(bktr, BKTR_O_CONTROL);
1991 if ( tmp_int & BIT_EIGHT_HIGH ) {
1992 temp |= BT848_E_CONTROL_SAT_U_MSB;
1993 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
1996 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
1997 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2000 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2001 OUTB(bktr, BKTR_E_CONTROL, temp);
2002 OUTB(bktr, BKTR_O_CONTROL, temp1);
2005 case BT848_GUSAT: /* get chroma U saturation */
2006 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2007 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2008 tmp_int |= BIT_EIGHT_HIGH;
2009 *(int*)arg = tmp_int;
2012 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2014 case BT848_SLNOTCH: /* set luma notch */
2015 tmp_int = (*(int *)arg & 0x7) << 5 ;
2016 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2017 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2018 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2019 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2022 case BT848_GLNOTCH: /* get luma notch */
2023 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2028 case BT848_SCONT: /* set contrast */
2029 tmp_int = *(int*)arg;
2031 temp = INB(bktr, BKTR_E_CONTROL);
2032 temp1 = INB(bktr, BKTR_O_CONTROL);
2033 if ( tmp_int & BIT_EIGHT_HIGH ) {
2034 temp |= BT848_E_CONTROL_CON_MSB;
2035 temp1 |= BT848_O_CONTROL_CON_MSB;
2038 temp &= ~BT848_E_CONTROL_CON_MSB;
2039 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2042 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2043 OUTB(bktr, BKTR_E_CONTROL, temp);
2044 OUTB(bktr, BKTR_O_CONTROL, temp1);
2047 case BT848_GCONT: /* get contrast */
2048 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2049 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2050 tmp_int |= BIT_EIGHT_HIGH;
2051 *(int*)arg = tmp_int;
2054 /* FIXME: SCBARS and CCBARS require a valid int * */
2055 /* argument to succeed, but its not used; consider */
2056 /* using the arg to store the on/off state so */
2057 /* there's only one ioctl() needed to turn cbars on/off */
2058 case BT848_SCBARS: /* set colorbar output */
2059 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2062 case BT848_CCBARS: /* clear colorbar output */
2063 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2066 case BT848_GAUDIO: /* get audio channel */
2067 temp = bktr->audio_mux_select;
2068 if ( bktr->audio_mute_state == TRUE )
2073 case BT848_SBTSC: /* set audio channel */
2074 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2078 case BT848_WEEPROM: /* write eeprom */
2079 offset = (((struct eeProm *)arg)->offset);
2080 count = (((struct eeProm *)arg)->count);
2081 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2082 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2086 case BT848_REEPROM: /* read eeprom */
2087 offset = (((struct eeProm *)arg)->offset);
2088 count = (((struct eeProm *)arg)->count);
2089 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2090 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2094 case BT848_SIGNATURE:
2095 offset = (((struct eeProm *)arg)->offset);
2096 count = (((struct eeProm *)arg)->count);
2097 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2098 if ( signCard( bktr, offset, count, buf ) < 0 )
2102 /* Ioctl's for direct gpio access */
2103 #ifdef BKTR_GPIO_ACCESS
2104 case BT848_GPIO_GET_EN:
2105 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2108 case BT848_GPIO_SET_EN:
2109 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2112 case BT848_GPIO_GET_DATA:
2113 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2116 case BT848_GPIO_SET_DATA:
2117 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2119 #endif /* BKTR_GPIO_ACCESS */
2121 /* Ioctl's for running the tuner device in radio mode */
2124 *(unsigned char *)arg = bktr->tuner.radio_mode;
2128 bktr->tuner.radio_mode = *(unsigned char *)arg;
2132 *(unsigned long *)arg = bktr->tuner.frequency;
2136 /* The argument to this ioctl is NOT freq*16. It is
2140 temp=(int)*(unsigned long *)arg;
2142 #ifdef BKTR_RADIO_DEBUG
2143 kprintf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2144 (int)*(unsigned long *)arg, temp);
2147 #ifndef BKTR_RADIO_NOFREQCHECK
2148 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2150 if(temp<8750 || temp>10800) {
2151 kprintf("%s: Radio frequency out of range\n", bktr_name(bktr));
2155 temp_mute( bktr, TRUE );
2156 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2157 temp_mute( bktr, FALSE );
2158 #ifdef BKTR_RADIO_DEBUG
2160 kprintf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2164 *(unsigned long *)arg = temp;
2167 /* Luigi's I2CWR ioctl */
2169 par = *(u_long *)arg;
2170 write = (par >> 24) & 0xff ;
2171 i2c_addr = (par >> 16) & 0xff ;
2172 i2c_port = (par >> 8) & 0xff ;
2173 data = (par) & 0xff ;
2176 i2cWrite( bktr, i2c_addr, i2c_port, data);
2178 data = i2cRead( bktr, i2c_addr);
2180 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2184 #ifdef BT848_MSP_READ
2185 /* I2C ioctls to allow userland access to the MSP chip */
2186 case BT848_MSP_READ:
2188 struct bktr_msp_control *msp;
2189 msp = (struct bktr_msp_control *) arg;
2190 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2191 msp->function, msp->address);
2195 case BT848_MSP_WRITE:
2197 struct bktr_msp_control *msp;
2198 msp = (struct bktr_msp_control *) arg;
2199 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2200 msp->address, msp->data );
2204 case BT848_MSP_RESET:
2205 msp_dpl_reset(bktr, bktr->msp_addr);
2210 return common_ioctl( bktr, cmd, arg );
2221 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2225 struct meteor_pixfmt *pf_pub;
2229 case METEORSINPUT: /* set input device */
2230 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2231 /* On the original bt848 boards, */
2232 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2233 /* On the Hauppauge bt878 boards, */
2234 /* Tuner is MUX0, RCA is MUX3 */
2235 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2236 /* stick with this system in our Meteor Emulation */
2238 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2240 /* this is the RCA video input */
2241 case 0: /* default */
2242 case METEOR_INPUT_DEV0:
2243 /* METEOR_INPUT_DEV_RCA: */
2244 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2246 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2247 & ~BT848_IFORM_MUXSEL);
2249 /* work around for new Hauppauge 878 cards */
2250 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2251 (bktr->id==BROOKTREE_878 ||
2252 bktr->id==BROOKTREE_879) )
2253 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2255 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2257 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2258 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2259 set_audio( bktr, AUDIO_EXTERN );
2262 /* this is the tuner input */
2263 case METEOR_INPUT_DEV1:
2264 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2266 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2267 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2268 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2269 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2270 set_audio( bktr, AUDIO_TUNER );
2273 /* this is the S-VHS input, but with a composite camera */
2274 case METEOR_INPUT_DEV2:
2275 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2277 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2278 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2279 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2280 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2281 set_audio( bktr, AUDIO_EXTERN );
2284 /* this is the S-VHS input */
2285 case METEOR_INPUT_DEV_SVIDEO:
2286 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2287 | METEOR_DEV_SVIDEO;
2288 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2289 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2290 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2291 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2292 set_audio( bktr, AUDIO_EXTERN );
2295 case METEOR_INPUT_DEV3:
2296 if ((bktr->id == BROOKTREE_848A) ||
2297 (bktr->id == BROOKTREE_849A) ||
2298 (bktr->id == BROOKTREE_878) ||
2299 (bktr->id == BROOKTREE_879) ) {
2300 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2302 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2304 /* work around for new Hauppauge 878 cards */
2305 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2306 (bktr->id==BROOKTREE_878 ||
2307 bktr->id==BROOKTREE_879) )
2308 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2310 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2312 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2313 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2314 set_audio( bktr, AUDIO_EXTERN );
2324 case METEORGINPUT: /* get input device */
2325 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2328 case METEORSACTPIXFMT:
2329 if (( *(int *)arg < 0 ) ||
2330 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2333 bktr->pixfmt = *(int *)arg;
2334 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2335 | pixfmt_swap_flags( bktr->pixfmt ));
2336 bktr->pixfmt_compat = FALSE;
2339 case METEORGACTPIXFMT:
2340 *(int *)arg = bktr->pixfmt;
2343 case METEORGSUPPIXFMT :
2344 pf_pub = (struct meteor_pixfmt *)arg;
2345 pixfmt = pf_pub->index;
2347 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2350 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2351 sizeof( *pf_pub ) );
2353 /* Patch in our format index */
2354 pf_pub->index = pixfmt;
2357 #if defined( STATUS_SUM )
2358 case BT848_GSTATUS: /* reap status */
2364 *(u_int*)arg = temp;
2367 #endif /* STATUS_SUM */
2379 /******************************************************************************
2380 * bt848 RISC programming routines:
2389 dump_bt848( bktr_ptr_t bktr )
2392 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2393 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2394 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2395 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2396 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2401 for (i = 0; i < 40; i+=4) {
2402 kprintf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2404 r[i], INL(bktr, r[i]),
2405 r[i+1], INL(bktr, r[i+1]),
2406 r[i+2], INL(bktr, r[i+2]),
2407 r[i+3], INL(bktr, r[i+3]));
2410 kprintf("%s: INT STAT %x \n", bktr_name(bktr),
2411 INL(bktr, BKTR_INT_STAT));
2412 kprintf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2413 INL(bktr, BKTR_INT_MASK));
2414 kprintf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2415 INW(bktr, BKTR_GPIO_DMA_CTL));
2423 * build write instruction
2425 #define BKTR_FM1 0x6 /* packed data to follow */
2426 #define BKTR_FM3 0xe /* planar data to follow */
2427 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2428 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2429 #define BKTR_PXV 0x0 /* valid word (never used) */
2430 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2431 #define BKTR_SOL 0x2 /* first dword */
2433 #define OP_WRITE (0x1 << 28)
2434 #define OP_SKIP (0x2 << 28)
2435 #define OP_WRITEC (0x5 << 28)
2436 #define OP_JUMP (0x7 << 28)
2437 #define OP_SYNC (0x8 << 28)
2438 #define OP_WRITE123 (0x9 << 28)
2439 #define OP_WRITES123 (0xb << 28)
2440 #define OP_SOL (1 << 27) /* first instr for scanline */
2441 #define OP_EOL (1 << 26)
2443 #define BKTR_RESYNC (1 << 15)
2444 #define BKTR_GEN_IRQ (1 << 24)
2447 * The RISC status bits can be set/cleared in the RISC programs
2448 * and tested in the Interrupt Handler
2450 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2451 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2452 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2453 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2455 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2456 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2457 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2458 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2460 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2461 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2462 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2463 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2465 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2467 bktr_clip_t * clip_node;
2468 bktr->clip_start = -1;
2472 bktr->line_length = width;
2475 bktr->current_col = 0;
2477 if (bktr->max_clip_node == 0 ) return TRUE;
2478 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2481 for (i = 0; i < bktr->max_clip_node; i++ ) {
2482 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2483 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2484 bktr->clip_start = i;
2492 static bool_t getline(bktr_reg_t *bktr, int x ) {
2494 bktr_clip_t * clip_node ;
2496 if (bktr->line_length == 0 ||
2497 bktr->current_col >= bktr->line_length) return FALSE;
2499 bktr->y = min(bktr->last_y, bktr->line_length);
2500 bktr->y2 = bktr->line_length;
2502 bktr->yclip = bktr->yclip2 = -1;
2503 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2504 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2505 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2506 if (bktr->last_y <= clip_node->y_min) {
2507 bktr->y = min(bktr->last_y, bktr->line_length);
2508 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2509 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2510 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2511 bktr->last_y = bktr->yclip2;
2512 bktr->clip_start = i;
2514 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2515 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2516 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2517 if (bktr->last_y >= clip_node->y_min) {
2518 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2519 bktr->last_y = bktr->yclip2;
2520 bktr->clip_start = j;
2529 if (bktr->current_col <= bktr->line_length) {
2530 bktr->current_col = bktr->line_length;
2536 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2537 u_long operation, int pixel_width,
2538 volatile u_char ** target_buffer, int cols ) {
2541 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2542 u_int skip, start_skip;
2544 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2545 /* to the 1st byte in the mem dword containing our start addr. */
2546 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2549 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2550 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2551 case 2 : start_skip = 4 ; break;
2552 case 1 : start_skip = 8 ; break;
2555 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2556 if ( width == cols) {
2557 flag = OP_SOL | OP_EOL;
2558 } else if (bktr->current_col == 0 ) {
2560 } else if (bktr->current_col == cols) {
2565 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2566 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2571 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2572 if (operation != OP_SKIP )
2573 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2575 *target_buffer += width * pixel_width;
2576 bktr->current_col += width;
2580 if (bktr->current_col == 0 && width == cols) {
2583 } else if (bktr->current_col == 0 ) {
2586 } else if (bktr->current_col >= cols) {
2595 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2596 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2601 *(*dma_prog)++ = operation | flag |
2602 (width * pixel_width / 2 - skip);
2603 if (operation != OP_SKIP )
2604 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2605 *target_buffer += (width * pixel_width / 2) ;
2607 if ( operation == OP_WRITE )
2608 operation = OP_WRITEC;
2609 *(*dma_prog)++ = operation | flag2 |
2610 (width * pixel_width / 2);
2611 *target_buffer += (width * pixel_width / 2) ;
2612 bktr->current_col += width;
2620 * Generate the RISC instructions to capture both VBI and video images
2623 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2626 volatile uint32_t target_buffer, buffer, target,width;
2627 volatile uint32_t pitch;
2628 volatile uint32_t *dma_prog; /* DMA prog is an array of
2629 32 bit RISC instructions */
2630 volatile uint32_t *loop_point;
2631 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2632 u_int Bpp = pf_int->public.Bpp;
2633 unsigned int vbisamples; /* VBI samples per line */
2634 unsigned int vbilines; /* VBI lines per field */
2635 unsigned int num_dwords; /* DWORDS per line */
2637 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2638 vbilines = format_params[bktr->format_params].vbi_num_lines;
2639 num_dwords = vbisamples/4;
2641 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2642 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2643 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2644 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2647 OUTB(bktr, BKTR_OFORM, 0x00);
2649 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2650 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2651 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2652 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2654 /* disable gamma correction removal */
2655 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2658 OUTB(bktr, BKTR_E_VTC, 0);
2659 OUTB(bktr, BKTR_O_VTC, 0);
2661 OUTB(bktr, BKTR_E_VTC, 1);
2662 OUTB(bktr, BKTR_O_VTC, 1);
2664 bktr->capcontrol = 3 << 2 | 3;
2666 dma_prog = (uint32_t *) bktr->dma_prog;
2668 /* Construct Write */
2670 if (bktr->video.addr) {
2671 target_buffer = (u_long) bktr->video.addr;
2672 pitch = bktr->video.width;
2675 target_buffer = (u_long) vtophys(bktr->bigbuf);
2679 buffer = target_buffer;
2681 /* Wait for the VRE sync marking the end of the Even and
2682 * the start of the Odd field. Resync here.
2684 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2687 loop_point = dma_prog;
2689 /* store the VBI data */
2690 /* look for sync with packed data */
2691 *dma_prog++ = OP_SYNC | BKTR_FM1;
2693 for(i = 0; i < vbilines; i++) {
2694 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2695 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2696 (i * VBI_LINE_SIZE));
2699 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2700 /* store the Odd field video image */
2701 /* look for sync with packed data */
2702 *dma_prog++ = OP_SYNC | BKTR_FM1;
2703 *dma_prog++ = 0; /* NULL WORD */
2705 for (i = 0; i < (rows/interlace); i++) {
2706 target = target_buffer;
2707 if ( notclipped(bktr, i, width)) {
2708 split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2709 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2712 while(getline(bktr, i)) {
2713 if (bktr->y != bktr->y2 ) {
2714 split(bktr, &dma_prog,
2715 bktr->y2 - bktr->y, OP_WRITE,
2716 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2718 if (bktr->yclip != bktr->yclip2 ) {
2719 split(bktr,&dma_prog,
2720 bktr->yclip2 - bktr->yclip,
2722 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2728 target_buffer += interlace * pitch;
2734 /* Grab the Even field */
2735 /* Look for the VRO, end of Odd field, marker */
2736 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2737 *dma_prog++ = 0; /* NULL WORD */
2739 /* store the VBI data */
2740 /* look for sync with packed data */
2741 *dma_prog++ = OP_SYNC | BKTR_FM1;
2743 for(i = 0; i < vbilines; i++) {
2744 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2745 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2746 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2749 /* store the video image */
2750 if (i_flag == 1) /*Even Only*/
2751 target_buffer = buffer;
2752 if (i_flag == 3) /*interlaced*/
2753 target_buffer = buffer+pitch;
2756 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2757 /* look for sync with packed data */
2758 *dma_prog++ = OP_SYNC | BKTR_FM1;
2759 *dma_prog++ = 0; /* NULL WORD */
2761 for (i = 0; i < (rows/interlace); i++) {
2762 target = target_buffer;
2763 if ( notclipped(bktr, i, width)) {
2764 split(bktr, &dma_prog, bktr->y2 - bktr->y, OP_WRITE,
2765 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2767 while(getline(bktr, i)) {
2768 if (bktr->y != bktr->y2 ) {
2769 split(bktr, &dma_prog,
2770 bktr->y2 - bktr->y, OP_WRITE,
2771 Bpp, (volatile u_char **)(uintptr_t)&target,
2774 if (bktr->yclip != bktr->yclip2 ) {
2775 split(bktr, &dma_prog,
2776 bktr->yclip2 - bktr->yclip, OP_SKIP,
2777 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2784 target_buffer += interlace * pitch;
2789 /* Look for end of 'Even Field' */
2790 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2791 *dma_prog++ = 0; /* NULL WORD */
2793 *dma_prog++ = OP_JUMP ;
2794 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2795 *dma_prog++ = 0; /* NULL WORD */
2803 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2806 volatile uint32_t target_buffer, buffer, target,width;
2807 volatile uint32_t pitch;
2808 volatile uint32_t *dma_prog;
2809 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2810 u_int Bpp = pf_int->public.Bpp;
2812 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2813 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2814 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2815 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2817 OUTB(bktr, BKTR_OFORM, 0x00);
2819 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2820 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2821 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2822 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2824 /* disable gamma correction removal */
2825 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2828 OUTB(bktr, BKTR_E_VTC, 0);
2829 OUTB(bktr, BKTR_O_VTC, 0);
2831 OUTB(bktr, BKTR_E_VTC, 1);
2832 OUTB(bktr, BKTR_O_VTC, 1);
2834 bktr->capcontrol = 3 << 2 | 3;
2836 dma_prog = (uint32_t *) bktr->dma_prog;
2838 /* Construct Write */
2840 if (bktr->video.addr) {
2841 target_buffer = (uint32_t) bktr->video.addr;
2842 pitch = bktr->video.width;
2845 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2849 buffer = target_buffer;
2851 /* contruct sync : for video packet format */
2852 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2854 /* sync, mode indicator packed data */
2855 *dma_prog++ = 0; /* NULL WORD */
2857 for (i = 0; i < (rows/interlace); i++) {
2858 target = target_buffer;
2859 if ( notclipped(bktr, i, width)) {
2860 split(bktr, &dma_prog,
2861 bktr->y2 - bktr->y, OP_WRITE,
2862 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2865 while(getline(bktr, i)) {
2866 if (bktr->y != bktr->y2 ) {
2867 split(bktr, &dma_prog,
2868 bktr->y2 - bktr->y, OP_WRITE,
2869 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2871 if (bktr->yclip != bktr->yclip2 ) {
2872 split(bktr,&dma_prog,
2873 bktr->yclip2 - bktr->yclip,
2875 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2881 target_buffer += interlace * pitch;
2888 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2889 *dma_prog++ = 0; /* NULL WORD */
2891 *dma_prog++ = OP_JUMP;
2892 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
2897 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
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_RESYNC | BKTR_VRO;
2907 *dma_prog++ = 0; /* NULL WORD */
2908 *dma_prog++ = OP_JUMP;
2909 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
2913 if (interlace == 2) {
2915 target_buffer = buffer + pitch;
2917 dma_prog = (uint32_t *) bktr->odd_dma_prog;
2919 /* sync vre IRQ bit */
2920 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2921 *dma_prog++ = 0; /* NULL WORD */
2923 for (i = 0; i < (rows/interlace); i++) {
2924 target = target_buffer;
2925 if ( notclipped(bktr, i, width)) {
2926 split(bktr, &dma_prog,
2927 bktr->y2 - bktr->y, OP_WRITE,
2928 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2930 while(getline(bktr, i)) {
2931 if (bktr->y != bktr->y2 ) {
2932 split(bktr, &dma_prog,
2933 bktr->y2 - bktr->y, OP_WRITE,
2934 Bpp, (volatile u_char **)(uintptr_t)&target,
2937 if (bktr->yclip != bktr->yclip2 ) {
2938 split(bktr, &dma_prog,
2939 bktr->yclip2 - bktr->yclip, OP_SKIP,
2940 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2947 target_buffer += interlace * pitch;
2952 /* sync vre IRQ bit */
2953 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2954 *dma_prog++ = 0; /* NULL WORD */
2955 *dma_prog++ = OP_JUMP ;
2956 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
2957 *dma_prog++ = 0; /* NULL WORD */
2965 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2966 int cols, int rows, int interlace )
2969 volatile unsigned int inst;
2970 volatile unsigned int inst3;
2971 volatile uint32_t target_buffer, buffer;
2972 volatile uint32_t *dma_prog;
2973 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2976 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2978 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
2979 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2981 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
2982 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2984 bktr->capcontrol = 3 << 2 | 3;
2986 dma_prog = (uint32_t *) bktr->dma_prog;
2988 /* Construct Write */
2990 /* write , sol, eol */
2991 inst = OP_WRITE | OP_SOL | (cols);
2992 /* write , sol, eol */
2993 inst3 = OP_WRITE | OP_EOL | (cols);
2995 if (bktr->video.addr)
2996 target_buffer = (uint32_t) bktr->video.addr;
2998 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3000 buffer = target_buffer;
3002 /* contruct sync : for video packet format */
3003 /* sync, mode indicator packed data */
3004 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3005 *dma_prog++ = 0; /* NULL WORD */
3009 for (i = 0; i < (rows/interlace); i++) {
3011 *dma_prog++ = target_buffer;
3012 *dma_prog++ = inst3;
3013 *dma_prog++ = target_buffer + b;
3014 target_buffer += interlace*(cols * 2);
3020 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3021 *dma_prog++ = 0; /* NULL WORD */
3023 *dma_prog++ = OP_JUMP;
3024 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3029 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3030 *dma_prog++ = 0; /* NULL WORD */
3031 *dma_prog++ = OP_JUMP;
3032 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3037 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3038 *dma_prog++ = 0; /* NULL WORD */
3039 *dma_prog++ = OP_JUMP ;
3040 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3044 if (interlace == 2) {
3046 target_buffer = (uint32_t) buffer + cols*2;
3048 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3051 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3052 *dma_prog++ = 0; /* NULL WORD */
3054 for (i = 0; i < (rows/interlace) ; i++) {
3056 *dma_prog++ = target_buffer;
3057 *dma_prog++ = inst3;
3058 *dma_prog++ = target_buffer + b;
3059 target_buffer += interlace * ( cols*2);
3063 /* sync vro IRQ bit */
3064 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3065 *dma_prog++ = 0; /* NULL WORD */
3066 *dma_prog++ = OP_JUMP ;
3067 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3069 *dma_prog++ = OP_JUMP;
3070 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3071 *dma_prog++ = 0; /* NULL WORD */
3079 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3080 int cols, int rows, int interlace ){
3083 volatile unsigned int inst;
3084 volatile uint32_t target_buffer, t1, buffer;
3085 volatile uint32_t *dma_prog;
3086 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3088 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3090 dma_prog = (uint32_t*) bktr->dma_prog;
3092 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3094 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3095 OUTB(bktr, BKTR_OFORM, 0x00);
3097 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3098 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3100 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3101 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3103 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3104 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3105 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3106 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3108 /* disable gamma correction removal */
3109 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3111 /* Construct Write */
3112 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3113 if (bktr->video.addr)
3114 target_buffer = (uint32_t) bktr->video.addr;
3116 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3118 buffer = target_buffer;
3122 /* contruct sync : for video packet format */
3123 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3124 *dma_prog++ = 0; /* NULL WORD */
3126 for (i = 0; i < (rows/interlace ) ; i++) {
3128 *dma_prog++ = cols/2 | cols/2 << 16;
3129 *dma_prog++ = target_buffer;
3130 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3131 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3132 target_buffer += interlace*cols;
3137 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3138 *dma_prog++ = 0; /* NULL WORD */
3140 *dma_prog++ = OP_JUMP ;
3141 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3145 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3146 *dma_prog++ = 0; /* NULL WORD */
3148 *dma_prog++ = OP_JUMP;
3149 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3153 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3154 *dma_prog++ = 0; /* NULL WORD */
3156 *dma_prog++ = OP_JUMP ;
3157 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3161 if (interlace == 2) {
3163 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3165 target_buffer = (uint32_t) buffer + cols;
3166 t1 = buffer + cols/2;
3167 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3168 *dma_prog++ = 0; /* NULL WORD */
3170 for (i = 0; i < (rows/interlace ) ; i++) {
3172 *dma_prog++ = cols/2 | cols/2 << 16;
3173 *dma_prog++ = target_buffer;
3174 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3175 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3176 target_buffer += interlace*cols;
3180 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3181 *dma_prog++ = 0; /* NULL WORD */
3182 *dma_prog++ = OP_JUMP ;
3183 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3184 *dma_prog++ = 0; /* NULL WORD */
3192 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3193 int cols, int rows, int interlace ){
3196 volatile unsigned int inst;
3197 volatile unsigned int inst1;
3198 volatile uint32_t target_buffer, t1, buffer;
3199 volatile uint32_t *dma_prog;
3200 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3202 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3204 dma_prog = (uint32_t *) bktr->dma_prog;
3206 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3208 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3209 OUTB(bktr, BKTR_OFORM, 0x0);
3211 /* Construct Write */
3212 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3213 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3214 if (bktr->video.addr)
3215 target_buffer = (uint32_t) bktr->video.addr;
3217 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3219 buffer = target_buffer;
3222 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3223 *dma_prog++ = 0; /* NULL WORD */
3225 for (i = 0; i < (rows/interlace )/2 ; i++) {
3227 *dma_prog++ = cols/2 | (cols/2 << 16);
3228 *dma_prog++ = target_buffer;
3229 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3230 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3231 target_buffer += interlace*cols;
3232 *dma_prog++ = inst1;
3233 *dma_prog++ = cols/2 | (cols/2 << 16);
3234 *dma_prog++ = target_buffer;
3235 target_buffer += interlace*cols;
3241 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3242 *dma_prog++ = 0; /* NULL WORD */
3244 *dma_prog++ = OP_JUMP;
3245 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3249 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3250 *dma_prog++ = 0; /* NULL WORD */
3252 *dma_prog++ = OP_JUMP;
3253 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3257 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3258 *dma_prog++ = 0; /* NULL WORD */
3259 *dma_prog++ = OP_JUMP ;
3260 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3264 if (interlace == 2) {
3266 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3268 target_buffer = (uint32_t) buffer + cols;
3269 t1 = buffer + cols/2;
3270 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3271 *dma_prog++ = 0; /* NULL WORD */
3273 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3275 *dma_prog++ = cols/2 | (cols/2 << 16);
3276 *dma_prog++ = target_buffer;
3277 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3278 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3279 target_buffer += interlace*cols;
3280 *dma_prog++ = inst1;
3281 *dma_prog++ = cols/2 | (cols/2 << 16);
3282 *dma_prog++ = target_buffer;
3283 target_buffer += interlace*cols;
3290 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3291 *dma_prog++ = 0; /* NULL WORD */
3292 *dma_prog++ = OP_JUMP;
3293 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3294 *dma_prog++ = 0; /* NULL WORD */
3303 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3305 int rows, cols, interlace;
3308 struct format_params *fp;
3309 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3312 fp = &format_params[bktr->format_params];
3314 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3316 /* disable FIFO & RISC, leave other bits alone */
3317 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3319 /* set video parameters */
3320 if (bktr->capture_area_enabled)
3321 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3322 / fp->scaled_htotal / bktr->cols) - 4096;
3324 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3325 / fp->scaled_htotal / bktr->cols) - 4096;
3327 /* kprintf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3328 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3329 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3330 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3331 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3333 /* horizontal active */
3335 /* kprintf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3336 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3337 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3338 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3339 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3340 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3341 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3343 /* horizontal delay */
3344 if (bktr->capture_area_enabled)
3345 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3346 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3348 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3350 temp = temp & 0x3fe;
3352 /* kprintf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3353 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3354 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3355 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3356 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3357 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3358 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3360 /* vertical scale */
3362 if (bktr->capture_area_enabled) {
3363 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3364 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3366 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3369 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3372 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3373 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3375 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3378 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3383 /* kprintf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3384 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3385 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3386 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3387 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3388 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3389 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3392 /* vertical active */
3393 if (bktr->capture_area_enabled)
3394 temp = bktr->capture_area_y_size;
3397 /* kprintf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3398 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3399 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3400 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3401 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3402 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3403 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3405 /* vertical delay */
3406 if (bktr->capture_area_enabled)
3407 temp = fp->vdelay + (bktr->capture_area_y_offset);
3410 /* kprintf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3411 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3412 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3413 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3414 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3415 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3416 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3418 /* end of video params */
3420 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3421 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3422 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3424 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3427 /* capture control */
3430 bktr->bktr_cap_ctl =
3431 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3432 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3433 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3437 bktr->bktr_cap_ctl =
3438 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3439 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3440 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3444 bktr->bktr_cap_ctl =
3445 (BT848_CAP_CTL_DITH_FRAME |
3446 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3447 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3448 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3453 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3458 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3460 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3461 /* user, then use the rgb_vbi RISC program. */
3462 /* Otherwise, use the normal rgb RISC program */
3463 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3464 if ( (bktr->vbiflags & VBI_OPEN)
3465 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3466 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3468 bktr->bktr_cap_ctl |=
3469 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3470 bktr->vbiflags |= VBI_CAPTURE;
3471 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3474 rgb_prog(bktr, i_flag, cols, rows, interlace);
3479 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3480 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3481 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3482 | pixfmt_swap_flags( bktr->pixfmt ));
3486 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3487 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3488 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3489 | pixfmt_swap_flags( bktr->pixfmt ));
3493 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3494 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3495 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3496 | pixfmt_swap_flags( bktr->pixfmt ));
3503 /******************************************************************************
3504 * video & video capture specific routines:
3512 start_capture( bktr_ptr_t bktr, unsigned type )
3515 struct format_params *fp;
3517 fp = &format_params[bktr->format_params];
3519 /* If requested, clear out capture buf first */
3520 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3521 bzero((caddr_t)bktr->bigbuf,
3522 (size_t)bktr->rows * bktr->cols * bktr->frames *
3523 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3526 OUTB(bktr, BKTR_DSTATUS, 0);
3527 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3529 bktr->flags |= type;
3530 bktr->flags &= ~METEOR_WANT_MASK;
3531 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3532 case METEOR_ONLY_EVEN_FIELDS:
3533 bktr->flags |= METEOR_WANT_EVEN;
3536 case METEOR_ONLY_ODD_FIELDS:
3537 bktr->flags |= METEOR_WANT_ODD;
3541 bktr->flags |= METEOR_WANT_MASK;
3546 /* TDEC is only valid for continuous captures */
3547 if ( type == METEOR_SINGLE ) {
3548 u_short fps_save = bktr->fps;
3550 set_fps(bktr, fp->frame_rate);
3551 bktr->fps = fps_save;
3554 set_fps(bktr, bktr->fps);
3556 if (bktr->dma_prog_loaded == FALSE) {
3557 build_dma_prog(bktr, i_flag);
3558 bktr->dma_prog_loaded = TRUE;
3562 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3571 set_fps( bktr_ptr_t bktr, u_short fps )
3573 struct format_params *fp;
3576 fp = &format_params[bktr->format_params];
3578 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3579 case METEOR_ONLY_EVEN_FIELDS:
3580 bktr->flags |= METEOR_WANT_EVEN;
3583 case METEOR_ONLY_ODD_FIELDS:
3584 bktr->flags |= METEOR_WANT_ODD;
3588 bktr->flags |= METEOR_WANT_MASK;
3593 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3594 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3597 OUTB(bktr, BKTR_TDEC, 0);
3599 if (fps < fp->frame_rate)
3600 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3602 OUTB(bktr, BKTR_TDEC, 0);
3612 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3613 * achieve the specified swapping.
3614 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3615 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3617 * Note also that for 3Bpp, we may additionally need to do some creative
3618 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3619 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3620 * as one would expect.
3623 static u_int pixfmt_swap_flags( int pixfmt )
3625 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3628 switch ( pf->Bpp ) {
3629 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3632 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3635 case 4 : if ( pf->swap_bytes )
3636 swapf = pf->swap_shorts ? 0 : WSWAP;
3638 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3647 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3648 * our pixfmt_table indices.
3651 static int oformat_meteor_to_bt( u_long format )
3654 struct meteor_pixfmt *pf1, *pf2;
3656 /* Find format in compatibility table */
3657 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3658 if ( meteor_pixfmt_table[i].meteor_format == format )
3661 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3663 pf1 = &meteor_pixfmt_table[i].public;
3665 /* Match it with an entry in master pixel format table */
3666 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3667 pf2 = &pixfmt_table[i].public;
3669 if (( pf1->type == pf2->type ) &&
3670 ( pf1->Bpp == pf2->Bpp ) &&
3671 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3672 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3673 ( pf1->swap_shorts == pf2->swap_shorts ))
3676 if ( i >= PIXFMT_TABLE_SIZE )
3682 /******************************************************************************
3687 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3688 #define I2CBITTIME_878 (1 << 7)
3689 #define I2C_READ 0x01
3690 #define I2C_COMMAND (I2CBITTIME | \
3691 BT848_DATA_CTL_I2CSCL | \
3692 BT848_DATA_CTL_I2CSDA)
3694 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3695 BT848_DATA_CTL_I2CSCL | \
3696 BT848_DATA_CTL_I2CSDA)
3699 * Program the i2c bus directly
3702 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3707 /* clear status bits */
3708 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3710 /* build the command datum */
3711 if (bktr->id == BROOKTREE_848 ||
3712 bktr->id == BROOKTREE_848A ||
3713 bktr->id == BROOKTREE_849A) {
3714 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3716 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3718 if ( byte2 != -1 ) {
3719 data |= ((byte2 & 0xff) << 8);
3720 data |= BT848_DATA_CTL_I2CW3B;
3723 /* write the address and data */
3724 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3726 /* wait for completion */
3727 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3728 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3733 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3745 i2cRead( bktr_ptr_t bktr, int addr )
3749 /* clear status bits */
3750 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3752 /* write the READ address */
3753 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3755 if (bktr->id == BROOKTREE_848 ||
3756 bktr->id == BROOKTREE_848A ||
3757 bktr->id == BROOKTREE_849A) {
3758 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3760 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3763 /* wait for completion */
3764 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3765 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3770 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3774 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3777 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3778 /* bt848 automated i2c bus controller cannot handle */
3779 /* Therefore we need low level control of the i2c bus hardware */
3780 /* Idea for the following functions are from elsewhere in this driver and */
3781 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3784 static void i2c_start( bktr_ptr_t bktr) {
3785 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3786 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3787 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3788 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3791 static void i2c_stop( bktr_ptr_t bktr) {
3792 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3793 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3794 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3797 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3801 /* write out the byte */
3802 for ( x = 7; x >= 0; --x ) {
3803 if ( data & (1<<x) ) {
3804 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3805 DELAY( BITD ); /* assert HI data */
3806 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3807 DELAY( BITD ); /* strobe clock */
3808 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3809 DELAY( BITD ); /* release clock */
3812 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3813 DELAY( BITD ); /* assert LO data */
3814 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3815 DELAY( BITD ); /* strobe clock */
3816 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3817 DELAY( BITD ); /* release clock */
3821 /* look for an ACK */
3822 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3823 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3824 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3825 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3830 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3835 /* read in the byte */
3836 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3837 DELAY( BITD ); /* float data */
3838 for ( x = 7; x >= 0; --x ) {
3839 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3840 DELAY( BITD ); /* strobe clock */
3841 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
3842 if ( bit ) byte |= (1<<x);
3843 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3844 DELAY( BITD ); /* release clock */
3846 /* After reading the byte, send an ACK */
3847 /* (unless that was the last byte, for which we send a NAK */
3848 if (last) { /* send NAK - same a writing a 1 */
3849 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3850 DELAY( BITD ); /* set data bit */
3851 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3852 DELAY( BITD ); /* strobe clock */
3853 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3854 DELAY( BITD ); /* release clock */
3855 } else { /* send ACK - same as writing a 0 */
3856 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3857 DELAY( BITD ); /* set data bit */
3858 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3859 DELAY( BITD ); /* strobe clock */
3860 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3861 DELAY( BITD ); /* release clock */
3869 /* Write to the MSP or DPL registers */
3870 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
3872 unsigned int msp_w_addr = i2c_addr;
3873 unsigned char addr_l, addr_h, data_h, data_l ;
3874 addr_h = (addr >>8) & 0xff;
3875 addr_l = addr & 0xff;
3876 data_h = (data >>8) & 0xff;
3877 data_l = data & 0xff;
3880 i2c_write_byte(bktr, msp_w_addr);
3881 i2c_write_byte(bktr, dev);
3882 i2c_write_byte(bktr, addr_h);
3883 i2c_write_byte(bktr, addr_l);
3884 i2c_write_byte(bktr, data_h);
3885 i2c_write_byte(bktr, data_l);
3889 /* Read from the MSP or DPL registers */
3890 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
3892 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
3893 addr_h = (addr >>8) & 0xff;
3894 addr_l = addr & 0xff;
3898 i2c_write_byte(bktr,i2c_addr);
3899 i2c_write_byte(bktr,dev_r);
3900 i2c_write_byte(bktr,addr_h);
3901 i2c_write_byte(bktr,addr_l);
3904 i2c_write_byte(bktr,i2c_addr+1);
3905 i2c_read_byte(bktr,&data_1, 0);
3906 i2c_read_byte(bktr,&data_2, 1);
3908 data = (data_1<<8) | data_2;
3912 /* Reset the MSP or DPL chip */
3913 /* The user can block the reset (which is handy if you initialise the
3914 * MSP audio in another operating system first (eg in Windows)
3916 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
3918 #ifndef BKTR_NO_MSP_RESET
3919 /* put into reset mode */
3921 i2c_write_byte(bktr, i2c_addr);
3922 i2c_write_byte(bktr, 0x00);
3923 i2c_write_byte(bktr, 0x80);
3924 i2c_write_byte(bktr, 0x00);
3927 /* put back to operational mode */
3929 i2c_write_byte(bktr, i2c_addr);
3930 i2c_write_byte(bktr, 0x00);
3931 i2c_write_byte(bktr, 0x00);
3932 i2c_write_byte(bktr, 0x00);
3939 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3941 /* XXX errors ignored */
3943 i2c_write_byte(bktr,bktr->remote_control_addr);
3944 i2c_read_byte(bktr,&(remote->data[0]), 0);
3945 i2c_read_byte(bktr,&(remote->data[1]), 0);
3946 i2c_read_byte(bktr,&(remote->data[2]), 0);
3953 #if defined( I2C_SOFTWARE_PROBE )
3956 * we are keeping this around for any parts that we need to probe
3957 * but that CANNOT be probed via an i2c read.
3958 * this is necessary because the hardware i2c mechanism
3959 * cannot be programmed for 1 byte writes.
3960 * currently there are no known i2c parts that we need to probe
3961 * and that cannot be safely read.
3963 static int i2cProbe( bktr_ptr_t bktr, int addr );
3968 * probe for an I2C device at addr.
3971 i2cProbe( bktr_ptr_t bktr, int addr )
3976 #if defined( EXTRA_START )
3977 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3978 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3979 #endif /* EXTRA_START */
3980 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3981 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3984 for ( x = 7; x >= 0; --x ) {
3985 if ( addr & (1<<x) ) {
3986 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3987 DELAY( BITD ); /* assert HI data */
3988 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3989 DELAY( BITD ); /* strobe clock */
3990 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3991 DELAY( BITD ); /* release clock */
3994 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3995 DELAY( BITD ); /* assert LO data */
3996 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3997 DELAY( BITD ); /* strobe clock */
3998 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3999 DELAY( BITD ); /* release clock */
4003 /* look for an ACK */
4004 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4005 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4006 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4007 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4010 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4011 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4012 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4019 #endif /* I2C_SOFTWARE_PROBE */