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.133 2003/12/08 07:59:18 obrien Exp $
65 * $DragonFly: src/sys/dev/video/bktr/bktr_core.c,v 1.13 2004/05/15 17:54:12 joerg Exp $
69 * This is part of the Driver for Video Capture Cards (Frame grabbers)
70 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
72 * Copyright Roger Hardiman and Amancio Hasty.
74 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
75 * Handles all the open, close, ioctl and read userland calls.
76 * Sets the Bt848 registers and generates RISC pograms.
77 * Controls the i2c bus and GPIO interface.
78 * Contains the interface to the kernel.
79 * (eg probe/attach and open/close/ioctl)
83 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
84 Jim Lowe's driver for the Matrox Meteor PCI card . The
85 Philips SAA 7116 and SAA 7196 are very different chipsets than
88 The original copyright notice by Mark and Jim is included mostly
89 to honor their fantastic work in the Matrox Meteor driver!
92 #include "opt_bktr.h" /* Include any kernel config options */
94 #include <sys/param.h>
95 #include <sys/systm.h>
96 #include <sys/kernel.h>
99 #include <sys/signalvar.h>
100 #include <sys/vnode.h>
103 #include <vm/vm_kern.h>
105 #include <vm/vm_extern.h>
107 #include <sys/bus.h> /* used by smbus and newbus */
110 #define PROC_UNLOCK(p)
111 #include <bus/pci/pcivar.h>
112 #include <bus/pci/pcidevs.h>
114 #include <machine/bus_memio.h> /* for bus space */
115 #include <machine/bus.h>
118 #include <dev/video/meteor/ioctl_meteor.h>
119 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
120 #include <dev/video/bktr/bktr_reg.h>
121 #include <dev/video/bktr/bktr_tuner.h>
122 #include <dev/video/bktr/bktr_card.h>
123 #include <dev/video/bktr/bktr_audio.h>
124 #include <dev/video/bktr/bktr_os.h>
125 #include <dev/video/bktr/bktr_core.h>
126 #if defined(BKTR_FREEBSD_MODULE)
127 #include <dev/video/bktr/bktr_mem.h>
130 #if defined(BKTR_USE_FREEBSD_SMBUS)
131 #include <dev/video/bktr/bktr_i2c.h>
132 #include <bus/smbus/smbconf.h>
133 #include <bus/iicbus/iiconf.h>
134 #include "smbus_if.h"
135 #include "iicbus_if.h"
139 bktr_name(bktr_ptr_t bktr)
141 return bktr->bktr_xname;
144 typedef u_char bool_t;
146 #define BKTRPRI PCATCH
147 #define VBIPRI PCATCH
151 * memory allocated for DMA programs
153 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
155 /* When to split a dma transfer , the bt848 has timing as well as
156 dma transfer size limitations so that we have to split dma
157 transfers into two dma requests
159 #define DMA_BT848_SPLIT 319*2
162 * Allocate enough memory for:
163 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
165 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
166 * in your kernel configuration file.
169 #ifndef BROOKTREE_ALLOC_PAGES
170 #define BROOKTREE_ALLOC_PAGES 217*4
172 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
174 /* Definitions for VBI capture.
175 * There are 16 VBI lines in a PAL video field (32 in a frame),
176 * and we take 2044 samples from each line (placed in a 2048 byte buffer
178 * VBI lines are held in a circular buffer before being read by a
179 * user program from /dev/vbi.
182 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
183 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
184 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
185 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
186 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
189 /* Defines for fields */
195 * Parameters describing size of transmitted image.
198 static struct format_params format_params[] = {
199 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
200 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
202 /* # define BT848_IFORM_F_NTSCM (0x1) */
203 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
205 /* # define BT848_IFORM_F_NTSCJ (0x2) */
206 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
208 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
209 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
211 /* # define BT848_IFORM_F_PALM (0x4) */
212 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
214 /* # define BT848_IFORM_F_PALN (0x5) */
215 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
217 /* # define BT848_IFORM_F_SECAM (0x6) */
218 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
220 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
221 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
226 * Table of supported Pixel Formats
229 static struct meteor_pixfmt_internal {
230 struct meteor_pixfmt public;
234 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
235 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
237 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
238 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
240 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
242 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
243 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
244 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
245 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
246 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
247 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
248 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
251 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
254 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
257 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
259 u_long meteor_format;
260 struct meteor_pixfmt public;
261 } meteor_pixfmt_table[] = {
263 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
266 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
267 { METEOR_GEO_YUV_422,
268 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
270 { METEOR_GEO_YUV_PACKED,
271 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
274 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
277 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
281 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
282 sizeof(meteor_pixfmt_table[0]) )
285 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
286 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
290 /* sync detect threshold */
292 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
293 BT848_ADC_CRUSH) /* threshold ~125 mV */
295 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
296 BT848_ADC_SYNC_T) /* threshold ~75 mV */
302 /* debug utility for holding previous INT_STAT contents */
304 static u_long status_sum = 0;
307 * defines to make certain bit-fiddles understandable
309 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
310 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
311 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
312 #define FIFO_RISC_DISABLED 0
314 #define ALL_INTS_DISABLED 0
315 #define ALL_INTS_CLEARED 0xffffffff
316 #define CAPTURE_OFF 0
318 #define BIT_SEVEN_HIGH (1<<7)
319 #define BIT_EIGHT_HIGH (1<<8)
321 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
322 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
326 static int oformat_meteor_to_bt( u_long format );
328 static u_int pixfmt_swap_flags( int pixfmt );
331 * bt848 RISC programming routines.
334 static int dump_bt848( bktr_ptr_t bktr );
337 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
338 int rows, int interlace );
339 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
340 int rows, int interlace );
341 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
342 int rows, int interlace );
343 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
344 int rows, int interlace );
345 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
346 int rows, int interlace );
347 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
349 static bool_t getline(bktr_reg_t *, int);
350 static bool_t notclipped(bktr_reg_t * , int , int);
351 static bool_t split(bktr_reg_t *, volatile u_long **, int, u_long, int,
352 volatile u_char ** , int );
354 static void start_capture( bktr_ptr_t bktr, unsigned type );
355 static void set_fps( bktr_ptr_t bktr, u_short fps );
360 * Remote Control Functions
362 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
366 * ioctls common to both video & tuner.
368 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
371 #if !defined(BKTR_USE_FREEBSD_SMBUS)
373 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
375 static void i2c_start( bktr_ptr_t bktr);
376 static void i2c_stop( bktr_ptr_t bktr);
377 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
378 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
384 * the common attach code, used by all OS versions.
387 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
390 int need_to_allocate_memory = 1;
391 #ifdef BKTR_NEW_MSP34XX_DRIVER
395 /* If this is a module, check if there is any currently saved contiguous memory */
396 #if defined(BKTR_FREEBSD_MODULE)
397 if (bktr_has_stored_addresses(unit) == 1) {
398 /* recover the addresses */
399 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
400 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
401 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
402 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
403 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
404 need_to_allocate_memory = 0;
408 if (need_to_allocate_memory == 1) {
409 /* allocate space for dma program */
410 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
411 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
413 /* allocte space for the VBI buffer */
414 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
415 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
417 /* allocate space for pixel buffer */
418 if ( BROOKTREE_ALLOC )
419 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
425 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
428 /* If this is a module, save the current contiguous memory */
429 #if defined(BKTR_FREEBSD_MODULE)
430 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
431 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
432 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
433 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
434 bktr_store_address(unit, BKTR_MEM_BUF, buf);
439 printf("%s: buffer size %d, addr %p\n",
440 bktr_name(bktr), BROOKTREE_ALLOC,
441 (void *)(uintptr_t)vtophys(buf));
446 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
447 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
449 bktr->alloc_pages = 0;
453 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
454 METEOR_DEV0 | METEOR_RGB16;
455 bktr->dma_prog_loaded = FALSE;
458 bktr->frames = 1; /* one frame */
459 bktr->format = METEOR_GEO_RGB16;
460 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
461 bktr->pixfmt_compat = TRUE;
470 /* using the pci device id and revision id */
471 /* and determine the card type */
472 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
474 switch (PCI_PRODUCT(pci_id)) {
475 case PCI_PRODUCT_BROOKTREE_BT848:
477 bktr->id = BROOKTREE_848A;
479 bktr->id = BROOKTREE_848;
481 case PCI_PRODUCT_BROOKTREE_BT849:
482 bktr->id = BROOKTREE_849A;
484 case PCI_PRODUCT_BROOKTREE_BT878:
485 bktr->id = BROOKTREE_878;
487 case PCI_PRODUCT_BROOKTREE_BT879:
488 bktr->id = BROOKTREE_879;
493 bktr->clr_on_start = FALSE;
495 /* defaults for the tuner section of the card */
496 bktr->tflags = TUNER_INITALIZED;
497 bktr->tuner.frequency = 0;
498 bktr->tuner.channel = 0;
499 bktr->tuner.chnlset = DEFAULT_CHNLSET;
501 bktr->tuner.radio_mode = 0;
502 bktr->audio_mux_select = 0;
503 bktr->audio_mute_state = FALSE;
504 bktr->bt848_card = -1;
505 bktr->bt848_tuner = -1;
506 bktr->reverse_mute = -1;
507 bktr->slow_msp_audio = 0;
508 bktr->msp_use_mono_source = 0;
509 bktr->msp_source_selected = -1;
510 bktr->audio_mux_present = 1;
512 #ifdef BKTR_NEW_MSP34XX_DRIVER
513 /* get hint on short programming of the msp34xx, so we know */
514 /* if the decision what thread to start should be overwritten */
515 if ( (err = resource_int_value("bktr", unit, "mspsimple",
516 &(bktr->mspsimple)) ) != 0 )
517 bktr->mspsimple = -1; /* fall back to default */
520 probeCard( bktr, TRUE, unit );
522 /* Initialise any MSP34xx or TDA98xx audio chips */
523 init_audio_devices( bktr );
525 #ifdef BKTR_NEW_MSP34XX_DRIVER
526 /* setup the kenrel thread */
527 err = msp_attach( bktr );
528 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
529 bktr->card.msp3400c = 0;
536 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
537 * The circular buffer holds 'n' fixed size data blocks.
538 * vbisize is the number of bytes in the circular buffer
539 * vbiread is the point we reading data out of the circular buffer
540 * vbiinsert is the point we insert data into the circular buffer
542 static void vbidecode(bktr_ptr_t bktr) {
544 unsigned int *seq_dest;
546 /* Check if there is room in the buffer to insert the data. */
547 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
549 /* Copy the VBI data into the next free slot in the buffer. */
550 /* 'dest' is the point in vbibuffer where we want to insert new data */
551 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
552 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
554 /* Write the VBI sequence number to the end of the vbi data */
555 /* This is used by the AleVT teletext program */
556 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
558 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
559 *seq_dest = bktr->vbi_sequence_number;
561 /* And increase the VBI sequence number */
562 /* This can wrap around */
563 bktr->vbi_sequence_number++;
566 /* Increment the vbiinsert pointer */
567 /* This can wrap around */
568 bktr->vbiinsert += VBI_DATA_SIZE;
569 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
571 /* And increase the amount of vbi data in the buffer */
572 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
578 * the common interrupt handler.
579 * Returns a 0 or 1 depending on whether the interrupt has handled.
580 * In the OS specific section, bktr_intr() is defined which calls this
581 * common interrupt handler.
584 common_bktr_intr( void *arg )
593 bktr = (bktr_ptr_t) arg;
596 * check to see if any interrupts are unmasked on this device. If
597 * none are, then we likely got here by way of being on a PCI shared
598 * interrupt dispatch list.
600 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
601 return 0; /* bail out now, before we do something we
604 if (!(bktr->flags & METEOR_OPEN)) {
605 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
606 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
610 /* record and clear the INTerrupt status bits */
611 bktr_status = INL(bktr, BKTR_INT_STAT);
612 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
614 /* record and clear the device status register */
615 dstatus = INB(bktr, BKTR_DSTATUS);
616 OUTB(bktr, BKTR_DSTATUS, 0x00);
618 #if defined( STATUS_SUM )
619 /* add any new device status or INTerrupt status bits */
620 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
621 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
622 #endif /* STATUS_SUM */
623 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
624 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
628 /* if risc was disabled re-start process again */
629 /* if there was one of the following errors re-start again */
630 if ( !(bktr_status & BT848_INT_RISC_EN) ||
631 ((bktr_status &(/* BT848_INT_FBUS | */
632 /* BT848_INT_FTRGT | */
633 /* BT848_INT_FDSR | */
635 BT848_INT_RIPERR | BT848_INT_PABORT |
636 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
637 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
639 u_short tdec_save = INB(bktr, BKTR_TDEC);
641 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
642 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
644 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
646 /* Reset temporal decimation counter */
647 OUTB(bktr, BKTR_TDEC, 0);
648 OUTB(bktr, BKTR_TDEC, tdec_save);
650 /* Reset to no-fields captured state */
651 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
652 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
653 case METEOR_ONLY_ODD_FIELDS:
654 bktr->flags |= METEOR_WANT_ODD;
656 case METEOR_ONLY_EVEN_FIELDS:
657 bktr->flags |= METEOR_WANT_EVEN;
660 bktr->flags |= METEOR_WANT_MASK;
665 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
666 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
667 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
669 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
674 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
678 /* If this is not a RISC program interrupt, return */
679 if (!(bktr_status & BT848_INT_RISCI))
683 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
684 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
689 * Disable future interrupts if a capture mode is not selected.
690 * This can happen when we are in the process of closing or
691 * changing capture modes, otherwise it shouldn't happen.
693 if (!(bktr->flags & METEOR_CAP_MASK))
694 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
697 /* Determine which field generated this interrupt */
698 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
702 * Process the VBI data if it is being captured. We do this once
703 * both Odd and Even VBI data is captured. Therefore we do this
704 * in the Even field interrupt handler.
707 if ( (bktr->vbiflags & VBI_CAPTURE)
708 &&(bktr->vbiflags & VBI_OPEN)
710 /* Put VBI data into circular buffer */
713 /* If someone is blocked on reading from /dev/vbi, wake them */
714 if (bktr->vbi_read_blocked) {
715 bktr->vbi_read_blocked = FALSE;
719 /* If someone has a select() on /dev/vbi, inform them */
720 if (bktr->vbi_select.si_pid) {
721 selwakeup(&bktr->vbi_select);
729 * Register the completed field
730 * (For dual-field mode, require fields from the same frame)
732 switch ( bktr->flags & METEOR_WANT_MASK ) {
733 case METEOR_WANT_ODD : w_field = ODD_F ; break;
734 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
735 default : w_field = (ODD_F|EVEN_F); break;
737 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
738 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
739 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
740 default : req_field = (ODD_F|EVEN_F);
744 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
745 bktr->flags &= ~METEOR_WANT_EVEN;
746 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
747 ( w_field == ODD_F ))
748 bktr->flags &= ~METEOR_WANT_ODD;
749 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
750 ( w_field == (ODD_F|EVEN_F) ))
751 bktr->flags &= ~METEOR_WANT_ODD;
752 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
753 ( w_field == ODD_F )) {
754 bktr->flags &= ~METEOR_WANT_ODD;
755 bktr->flags |= METEOR_WANT_EVEN;
758 /* We're out of sync. Start over. */
759 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
760 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
761 case METEOR_ONLY_ODD_FIELDS:
762 bktr->flags |= METEOR_WANT_ODD;
764 case METEOR_ONLY_EVEN_FIELDS:
765 bktr->flags |= METEOR_WANT_EVEN;
768 bktr->flags |= METEOR_WANT_MASK;
776 * If we have a complete frame.
778 if (!(bktr->flags & METEOR_WANT_MASK)) {
779 bktr->frames_captured++;
781 * post the completion time.
783 if (bktr->flags & METEOR_WANT_TS) {
786 if ((u_int) bktr->alloc_pages * PAGE_SIZE
787 <= (bktr->frame_size + sizeof(struct timeval))) {
788 ts =(struct timeval *)bktr->bigbuf +
790 /* doesn't work in synch mode except
799 * Wake up the user in single capture mode.
801 if (bktr->flags & METEOR_SINGLE) {
804 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
806 /* disable risc, leave fifo running */
807 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
812 * If the user requested to be notified via signal,
813 * let them know the frame is complete.
816 if (bktr->proc != NULL) {
817 PROC_LOCK(bktr->proc);
818 psignal( bktr->proc, bktr->signal);
819 PROC_UNLOCK(bktr->proc);
823 * Reset the want flags if in continuous or
824 * synchronous capture mode.
828 * currently we only support 3 capture modes: odd only, even only,
829 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
830 * either even OR odd) could provide 60 (50 for PAL) pictures per
831 * second, but it would require this routine to toggle the desired frame
832 * each time, and one more different DMA program for the Bt848.
833 * As a consequence, this fourth mode is currently unsupported.
836 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
837 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
838 case METEOR_ONLY_ODD_FIELDS:
839 bktr->flags |= METEOR_WANT_ODD;
841 case METEOR_ONLY_EVEN_FIELDS:
842 bktr->flags |= METEOR_WANT_EVEN;
845 bktr->flags |= METEOR_WANT_MASK;
860 extern int bt848_format; /* used to set the default format, PAL or NTSC */
862 video_open( bktr_ptr_t bktr )
864 int frame_rate, video_format=0;
866 if (bktr->flags & METEOR_OPEN) /* device is busy */
869 bktr->flags |= METEOR_OPEN;
875 bktr->clr_on_start = FALSE;
877 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
879 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
881 #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
887 if (bt848_format == 0 )
890 if (bt848_format == 1 )
893 if (video_format == 1 ) {
894 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
895 bktr->format_params = BT848_IFORM_F_NTSCM;
898 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
899 bktr->format_params = BT848_IFORM_F_PALBDGHI;
903 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
905 /* work around for new Hauppauge 878 cards */
906 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
907 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
908 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
910 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
912 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
913 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
914 frame_rate = format_params[bktr->format_params].frame_rate;
916 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
917 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
918 OUTB(bktr, BKTR_TGCTRL, 0);
919 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
920 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
921 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
924 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
926 bktr->max_clip_node = 0;
928 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
930 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
931 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
933 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
934 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
935 OUTB(bktr, BKTR_E_SCLOOP, 0);
936 OUTB(bktr, BKTR_O_SCLOOP, 0);
938 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
939 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
941 bktr->fifo_errors = 0;
942 bktr->dma_errors = 0;
943 bktr->frames_captured = 0;
944 bktr->even_fields_captured = 0;
945 bktr->odd_fields_captured = 0;
947 set_fps(bktr, frame_rate);
948 bktr->video.addr = 0;
949 bktr->video.width = 0;
950 bktr->video.banksize = 0;
951 bktr->video.ramsize = 0;
952 bktr->pixfmt_compat = TRUE;
953 bktr->format = METEOR_GEO_RGB16;
954 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
956 bktr->capture_area_enabled = FALSE;
958 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
959 based motherboards will
960 operate unreliably */
965 vbi_open( bktr_ptr_t bktr )
970 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
975 bktr->vbiflags |= VBI_OPEN;
977 /* reset the VBI circular buffer pointers and clear the buffers */
981 bktr->vbi_sequence_number = 0;
982 bktr->vbi_read_blocked = FALSE;
984 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
985 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
996 tuner_open( bktr_ptr_t bktr )
998 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1001 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1004 bktr->tflags |= TUNER_OPEN;
1005 bktr->tuner.frequency = 0;
1006 bktr->tuner.channel = 0;
1007 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1008 bktr->tuner.afc = 0;
1009 bktr->tuner.radio_mode = 0;
1011 /* enable drivers on the GPIO port that control the MUXes */
1012 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1014 /* unmute the audio stream */
1015 set_audio( bktr, AUDIO_UNMUTE );
1017 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1018 init_audio_devices( bktr );
1030 video_close( bktr_ptr_t bktr )
1032 bktr->flags &= ~(METEOR_OPEN |
1037 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1038 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1040 bktr->dma_prog_loaded = FALSE;
1041 OUTB(bktr, BKTR_TDEC, 0);
1042 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1044 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1045 OUTL(bktr, BKTR_SRESET, 0xf);
1046 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1053 * tuner close handle,
1054 * place holder for tuner specific operations on a close.
1057 tuner_close( bktr_ptr_t bktr )
1059 bktr->tflags &= ~TUNER_OPEN;
1061 /* mute the audio by switching the mux */
1062 set_audio( bktr, AUDIO_MUTE );
1064 /* disable drivers on the GPIO port that control the MUXes */
1065 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1071 vbi_close( bktr_ptr_t bktr )
1076 bktr->vbiflags &= ~VBI_OPEN;
1087 video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
1093 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1096 if (bktr->flags & METEOR_CAP_MASK)
1097 return( EIO ); /* already capturing */
1099 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1102 count = bktr->rows * bktr->cols *
1103 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1105 if ((int) uio->uio_iov->iov_len < count)
1108 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1110 /* capture one frame */
1111 start_capture(bktr, METEOR_SINGLE);
1112 /* wait for capture to complete */
1113 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1114 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1115 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1116 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1122 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1123 if (!status) /* successful capture */
1124 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1126 printf ("%s: read: tsleep error %d\n",
1127 bktr_name(bktr), status);
1129 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1135 * Read VBI data from the vbi circular buffer
1136 * The buffer holds vbi data blocks which are the same size
1137 * vbiinsert is the position we will insert the next item into the buffer
1138 * vbistart is the actual position in the buffer we want to read from
1139 * vbisize is the exact number of bytes in the buffer left to read
1142 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1144 int readsize, readsize2, start;
1148 * XXX - vbi_read() should be protected against being re-entered
1149 * while it is unlocked for the uiomove.
1153 while(bktr->vbisize == 0) {
1154 if (ioflag & IO_NDELAY) {
1155 status = EWOULDBLOCK;
1159 bktr->vbi_read_blocked = TRUE;
1161 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1166 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1172 /* Now we have some data to give to the user */
1174 /* We cannot read more bytes than there are in
1175 * the circular buffer
1177 readsize = (int)uio->uio_iov->iov_len;
1179 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1181 /* Check if we can read this number of bytes without having
1182 * to wrap around the circular buffer */
1183 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1184 /* We need to wrap around */
1186 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1187 start = bktr->vbistart;
1189 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1191 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1194 /* We do not need to wrap around */
1195 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1200 /* Update the number of bytes left to read */
1201 bktr->vbisize -= readsize;
1203 /* Update vbistart */
1204 bktr->vbistart += readsize;
1205 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1220 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1222 volatile u_char c_temp;
1224 unsigned int temp_iform;
1226 struct meteor_geomet *geo;
1227 struct meteor_counts *counts;
1228 struct meteor_video *video;
1229 struct bktr_capture_area *cap_area;
1237 case BT848SCLIP: /* set clip region */
1238 bktr->max_clip_node = 0;
1239 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1241 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1242 if (bktr->clip_list[i].y_min == 0 &&
1243 bktr->clip_list[i].y_max == 0)
1246 bktr->max_clip_node = i;
1248 /* make sure that the list contains a valid clip secquence */
1249 /* the clip rectangles should be sorted by x then by y as the
1250 second order sort key */
1252 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1254 /* to disable clipping set y_min and y_max to 0 in the first
1255 clip rectangle . The first clip rectangle is clip_list[0].
1260 if (bktr->max_clip_node == 0 &&
1261 (bktr->clip_list[0].y_min != 0 &&
1262 bktr->clip_list[0].y_max != 0)) {
1266 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1267 if (bktr->clip_list[i].y_min == 0 &&
1268 bktr->clip_list[i].y_max == 0) {
1271 if ( bktr->clip_list[i+1].y_min != 0 &&
1272 bktr->clip_list[i+1].y_max != 0 &&
1273 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1275 bktr->max_clip_node = 0;
1280 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1281 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1282 bktr->clip_list[i].x_min < 0 ||
1283 bktr->clip_list[i].x_max < 0 ||
1284 bktr->clip_list[i].y_min < 0 ||
1285 bktr->clip_list[i].y_max < 0 ) {
1286 bktr->max_clip_node = 0;
1291 bktr->dma_prog_loaded = FALSE;
1295 case METEORSTATUS: /* get Bt848 status */
1296 c_temp = INB(bktr, BKTR_DSTATUS);
1298 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1299 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1300 *(u_short *)arg = temp;
1303 case BT848SFMT: /* set input format */
1304 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1305 temp_iform = INB(bktr, BKTR_IFORM);
1306 temp_iform &= ~BT848_IFORM_FORMAT;
1307 temp_iform &= ~BT848_IFORM_XTSEL;
1308 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1310 case BT848_IFORM_F_AUTO:
1311 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1315 case BT848_IFORM_F_NTSCM:
1316 case BT848_IFORM_F_NTSCJ:
1317 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1319 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1320 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1321 bktr->format_params = temp;
1324 case BT848_IFORM_F_PALBDGHI:
1325 case BT848_IFORM_F_PALN:
1326 case BT848_IFORM_F_SECAM:
1327 case BT848_IFORM_F_RSVD:
1328 case BT848_IFORM_F_PALM:
1329 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1331 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1332 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1333 bktr->format_params = temp;
1337 bktr->dma_prog_loaded = FALSE;
1340 case METEORSFMT: /* set input format */
1341 temp_iform = INB(bktr, BKTR_IFORM);
1342 temp_iform &= ~BT848_IFORM_FORMAT;
1343 temp_iform &= ~BT848_IFORM_XTSEL;
1344 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1345 case 0: /* default */
1346 case METEOR_FMT_NTSC:
1347 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1349 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1350 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1351 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1352 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1353 bktr->format_params = BT848_IFORM_F_NTSCM;
1356 case METEOR_FMT_PAL:
1357 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1359 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1360 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1361 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1362 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1363 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1366 case METEOR_FMT_AUTOMODE:
1367 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1369 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1370 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1376 bktr->dma_prog_loaded = FALSE;
1379 case METEORGFMT: /* get input format */
1380 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1384 case BT848GFMT: /* get input format */
1385 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1388 case METEORSCOUNT: /* (re)set error counts */
1389 counts = (struct meteor_counts *) arg;
1390 bktr->fifo_errors = counts->fifo_errors;
1391 bktr->dma_errors = counts->dma_errors;
1392 bktr->frames_captured = counts->frames_captured;
1393 bktr->even_fields_captured = counts->even_fields_captured;
1394 bktr->odd_fields_captured = counts->odd_fields_captured;
1397 case METEORGCOUNT: /* get error counts */
1398 counts = (struct meteor_counts *) arg;
1399 counts->fifo_errors = bktr->fifo_errors;
1400 counts->dma_errors = bktr->dma_errors;
1401 counts->frames_captured = bktr->frames_captured;
1402 counts->even_fields_captured = bktr->even_fields_captured;
1403 counts->odd_fields_captured = bktr->odd_fields_captured;
1407 video = (struct meteor_video *)arg;
1408 video->addr = bktr->video.addr;
1409 video->width = bktr->video.width;
1410 video->banksize = bktr->video.banksize;
1411 video->ramsize = bktr->video.ramsize;
1415 video = (struct meteor_video *)arg;
1416 bktr->video.addr = video->addr;
1417 bktr->video.width = video->width;
1418 bktr->video.banksize = video->banksize;
1419 bktr->video.ramsize = video->ramsize;
1423 set_fps(bktr, *(u_short *)arg);
1427 *(u_short *)arg = bktr->fps;
1430 case METEORSHUE: /* set hue */
1431 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1434 case METEORGHUE: /* get hue */
1435 *(u_char *)arg = INB(bktr, BKTR_HUE);
1438 case METEORSBRIG: /* set brightness */
1439 char_temp = ( *(u_char *)arg & 0xff) - 128;
1440 OUTB(bktr, BKTR_BRIGHT, char_temp);
1444 case METEORGBRIG: /* get brightness */
1445 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1448 case METEORSCSAT: /* set chroma saturation */
1449 temp = (int)*(u_char *)arg;
1451 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1452 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1453 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1454 & ~(BT848_E_CONTROL_SAT_U_MSB
1455 | BT848_E_CONTROL_SAT_V_MSB));
1456 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1457 & ~(BT848_O_CONTROL_SAT_U_MSB |
1458 BT848_O_CONTROL_SAT_V_MSB));
1460 if ( temp & BIT_SEVEN_HIGH ) {
1461 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1462 | (BT848_E_CONTROL_SAT_U_MSB
1463 | BT848_E_CONTROL_SAT_V_MSB));
1464 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1465 | (BT848_O_CONTROL_SAT_U_MSB
1466 | BT848_O_CONTROL_SAT_V_MSB));
1470 case METEORGCSAT: /* get chroma saturation */
1471 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1472 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1473 temp |= BIT_SEVEN_HIGH;
1474 *(u_char *)arg = (u_char)temp;
1477 case METEORSCONT: /* set contrast */
1478 temp = (int)*(u_char *)arg & 0xff;
1480 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1481 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1482 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1483 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1484 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1485 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1486 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1489 case METEORGCONT: /* get contrast */
1490 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1491 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1492 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1495 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1496 bktr->clr_on_start = (*(int *)arg != 0);
1499 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1500 *(int *)arg = (int) bktr->clr_on_start;
1505 /* Historically, applications used METEOR_SIG_MODE_MASK
1506 * to reset signal delivery.
1508 if (sig == METEOR_SIG_MODE_MASK)
1510 if (sig < 0 || sig > _SIG_MAXSIG)
1513 bktr->proc = sig ? td->td_proc : NULL;
1517 *(int *)arg = bktr->signal;
1522 switch (*(int *) arg) {
1523 case METEOR_CAP_SINGLE:
1525 if (bktr->bigbuf==0) /* no frame buffer allocated */
1527 /* already capturing */
1528 if (temp & METEOR_CAP_MASK)
1533 start_capture(bktr, METEOR_SINGLE);
1535 /* wait for capture to complete */
1536 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1537 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1538 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1540 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1545 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1546 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1547 if (error && (error != ERESTART)) {
1548 /* Here if we didn't get complete frame */
1550 printf( "%s: ioctl: tsleep error %d %x\n",
1551 bktr_name(bktr), error,
1552 INL(bktr, BKTR_RISC_COUNT));
1556 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1558 /* disable risc, leave fifo running */
1559 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1562 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1563 /* FIXME: should we set bt848->int_stat ??? */
1566 case METEOR_CAP_CONTINOUS:
1567 if (bktr->bigbuf==0) /* no frame buffer allocated */
1569 /* already capturing */
1570 if (temp & METEOR_CAP_MASK)
1574 start_capture(bktr, METEOR_CONTIN);
1576 /* Clear the interrypt status register */
1577 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1579 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1580 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1581 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1583 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1588 dump_bt848( bt848 );
1592 case METEOR_CAP_STOP_CONT:
1593 if (bktr->flags & METEOR_CONTIN) {
1594 /* turn off capture */
1595 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1596 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1597 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1599 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1606 /* can't change parameters while capturing */
1607 if (bktr->flags & METEOR_CAP_MASK)
1611 geo = (struct meteor_geomet *) arg;
1614 /* Either even or odd, if even & odd, then these a zero */
1615 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1616 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1617 printf( "%s: ioctl: Geometry odd or even only.\n",
1622 /* set/clear even/odd flags */
1623 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1624 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1626 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1627 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1628 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1630 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1632 if (geo->columns <= 0) {
1634 "%s: ioctl: %d: columns must be greater than zero.\n",
1635 bktr_name(bktr), geo->columns);
1638 else if ((geo->columns & 0x3fe) != geo->columns) {
1640 "%s: ioctl: %d: columns too large or not even.\n",
1641 bktr_name(bktr), geo->columns);
1645 if (geo->rows <= 0) {
1647 "%s: ioctl: %d: rows must be greater than zero.\n",
1648 bktr_name(bktr), geo->rows);
1651 else if (((geo->rows & 0x7fe) != geo->rows) ||
1652 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1653 ((geo->rows & 0x3fe) != geo->rows)) ) {
1655 "%s: ioctl: %d: rows too large or not even.\n",
1656 bktr_name(bktr), geo->rows);
1660 if (geo->frames > 32) {
1661 printf("%s: ioctl: too many frames.\n",
1670 bktr->dma_prog_loaded = FALSE;
1671 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1673 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1675 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1676 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1678 /* meteor_mem structure for SYNC Capture */
1679 if (geo->frames > 1) temp += PAGE_SIZE;
1682 if ((int) temp > bktr->alloc_pages
1683 && bktr->video.addr == 0) {
1685 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1687 kmem_free(kernel_map, bktr->bigbuf,
1688 (bktr->alloc_pages * PAGE_SIZE));
1691 bktr->alloc_pages = temp;
1694 "%s: ioctl: Allocating %d bytes\n",
1695 bktr_name(bktr), temp*PAGE_SIZE);
1705 bktr->rows = geo->rows;
1706 bktr->cols = geo->columns;
1707 bktr->frames = geo->frames;
1709 /* Pixel format (if in meteor pixfmt compatibility mode) */
1710 if ( bktr->pixfmt_compat ) {
1711 bktr->format = METEOR_GEO_YUV_422;
1712 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1713 case 0: /* default */
1714 case METEOR_GEO_RGB16:
1715 bktr->format = METEOR_GEO_RGB16;
1717 case METEOR_GEO_RGB24:
1718 bktr->format = METEOR_GEO_RGB24;
1720 case METEOR_GEO_YUV_422:
1721 bktr->format = METEOR_GEO_YUV_422;
1722 if (geo->oformat & METEOR_GEO_YUV_12)
1723 bktr->format = METEOR_GEO_YUV_12;
1725 case METEOR_GEO_YUV_PACKED:
1726 bktr->format = METEOR_GEO_YUV_PACKED;
1729 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1732 if (bktr->flags & METEOR_CAP_MASK) {
1734 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1735 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1736 case METEOR_ONLY_ODD_FIELDS:
1737 bktr->flags |= METEOR_WANT_ODD;
1739 case METEOR_ONLY_EVEN_FIELDS:
1740 bktr->flags |= METEOR_WANT_EVEN;
1743 bktr->flags |= METEOR_WANT_MASK;
1747 start_capture(bktr, METEOR_CONTIN);
1748 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1749 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1750 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1751 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1757 /* end of METEORSETGEO */
1759 /* FIXME. The Capture Area currently has the following restrictions:
1761 y_offset may need to be even in interlaced modes
1762 RGB24 - Interlaced mode
1763 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1764 y_size must be greater than or equal to METEORSETGEO height (rows)
1765 RGB24 - Even Only (or Odd Only) mode
1766 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1767 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1768 YUV12 - Interlaced mode
1769 x_size must be greater than or equal to METEORSETGEO width (cols)
1770 y_size must be greater than or equal to METEORSETGEO height (rows)
1771 YUV12 - Even Only (or Odd Only) mode
1772 x_size must be greater than or equal to METEORSETGEO width (cols)
1773 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1776 case BT848_SCAPAREA: /* set capture area of each video frame */
1777 /* can't change parameters while capturing */
1778 if (bktr->flags & METEOR_CAP_MASK)
1781 cap_area = (struct bktr_capture_area *) arg;
1782 bktr->capture_area_x_offset = cap_area->x_offset;
1783 bktr->capture_area_y_offset = cap_area->y_offset;
1784 bktr->capture_area_x_size = cap_area->x_size;
1785 bktr->capture_area_y_size = cap_area->y_size;
1786 bktr->capture_area_enabled = TRUE;
1788 bktr->dma_prog_loaded = FALSE;
1791 case BT848_GCAPAREA: /* get capture area of each video frame */
1792 cap_area = (struct bktr_capture_area *) arg;
1793 if (bktr->capture_area_enabled == FALSE) {
1794 cap_area->x_offset = 0;
1795 cap_area->y_offset = 0;
1796 cap_area->x_size = format_params[
1797 bktr->format_params].scaled_hactive;
1798 cap_area->y_size = format_params[
1799 bktr->format_params].vactive;
1801 cap_area->x_offset = bktr->capture_area_x_offset;
1802 cap_area->y_offset = bktr->capture_area_y_offset;
1803 cap_area->x_size = bktr->capture_area_x_size;
1804 cap_area->y_size = bktr->capture_area_y_size;
1809 return common_ioctl( bktr, cmd, arg );
1819 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1822 unsigned int temp, temp1;
1835 /* Read the last key pressed by the Remote Control */
1836 if (bktr->remote_control == 0) return (EINVAL);
1837 remote_read(bktr, (struct bktr_remote *)arg);
1840 #if defined( TUNER_AFC )
1841 case TVTUNER_SETAFC:
1842 bktr->tuner.afc = (*(int *)arg != 0);
1845 case TVTUNER_GETAFC:
1846 *(int *)arg = bktr->tuner.afc;
1847 /* XXX Perhaps use another bit to indicate AFC success? */
1849 #endif /* TUNER_AFC */
1851 case TVTUNER_SETCHNL:
1852 temp_mute( bktr, TRUE );
1853 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1855 temp_mute( bktr, FALSE );
1858 *(unsigned long *)arg = temp;
1860 /* after every channel change, we must restart the MSP34xx */
1861 /* audio chip to reselect NICAM STEREO or MONO audio */
1862 if ( bktr->card.msp3400c )
1863 msp_autodetect( bktr );
1865 /* after every channel change, we must restart the DPL35xx */
1866 if ( bktr->card.dpl3518a )
1867 dpl_autodetect( bktr );
1869 temp_mute( bktr, FALSE );
1872 case TVTUNER_GETCHNL:
1873 *(unsigned long *)arg = bktr->tuner.channel;
1876 case TVTUNER_SETTYPE:
1877 temp = *(unsigned long *)arg;
1878 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1880 bktr->tuner.chnlset = temp;
1883 case TVTUNER_GETTYPE:
1884 *(unsigned long *)arg = bktr->tuner.chnlset;
1887 case TVTUNER_GETSTATUS:
1888 temp = get_tuner_status( bktr );
1889 *(unsigned long *)arg = temp & 0xff;
1892 case TVTUNER_SETFREQ:
1893 temp_mute( bktr, TRUE );
1894 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1895 temp_mute( bktr, FALSE );
1897 temp_mute( bktr, FALSE );
1900 *(unsigned long *)arg = temp;
1902 /* after every channel change, we must restart the MSP34xx */
1903 /* audio chip to reselect NICAM STEREO or MONO audio */
1904 if ( bktr->card.msp3400c )
1905 msp_autodetect( bktr );
1907 /* after every channel change, we must restart the DPL35xx */
1908 if ( bktr->card.dpl3518a )
1909 dpl_autodetect( bktr );
1911 temp_mute( bktr, FALSE );
1914 case TVTUNER_GETFREQ:
1915 *(unsigned long *)arg = bktr->tuner.frequency;
1918 case TVTUNER_GETCHNLSET:
1919 return tuner_getchnlset((struct bktr_chnlset *)arg);
1921 case BT848_SAUDIO: /* set audio channel */
1922 if ( set_audio( bktr, *(int*)arg ) < 0 )
1926 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1927 case BT848_SHUE: /* set hue */
1928 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1931 case BT848_GHUE: /* get hue */
1932 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1935 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1936 case BT848_SBRIG: /* set brightness */
1937 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1940 case BT848_GBRIG: /* get brightness */
1941 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1945 case BT848_SCSAT: /* set chroma saturation */
1946 tmp_int = *(int*)arg;
1948 temp = INB(bktr, BKTR_E_CONTROL);
1949 temp1 = INB(bktr, BKTR_O_CONTROL);
1950 if ( tmp_int & BIT_EIGHT_HIGH ) {
1951 temp |= (BT848_E_CONTROL_SAT_U_MSB |
1952 BT848_E_CONTROL_SAT_V_MSB);
1953 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1954 BT848_O_CONTROL_SAT_V_MSB);
1957 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1958 BT848_E_CONTROL_SAT_V_MSB);
1959 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1960 BT848_O_CONTROL_SAT_V_MSB);
1963 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1964 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1965 OUTB(bktr, BKTR_E_CONTROL, temp);
1966 OUTB(bktr, BKTR_O_CONTROL, temp1);
1969 case BT848_GCSAT: /* get chroma saturation */
1970 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1971 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1972 tmp_int |= BIT_EIGHT_HIGH;
1973 *(int*)arg = tmp_int;
1977 case BT848_SVSAT: /* set chroma V saturation */
1978 tmp_int = *(int*)arg;
1980 temp = INB(bktr, BKTR_E_CONTROL);
1981 temp1 = INB(bktr, BKTR_O_CONTROL);
1982 if ( tmp_int & BIT_EIGHT_HIGH) {
1983 temp |= BT848_E_CONTROL_SAT_V_MSB;
1984 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1987 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1988 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1991 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1992 OUTB(bktr, BKTR_E_CONTROL, temp);
1993 OUTB(bktr, BKTR_O_CONTROL, temp1);
1996 case BT848_GVSAT: /* get chroma V saturation */
1997 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1998 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1999 tmp_int |= BIT_EIGHT_HIGH;
2000 *(int*)arg = tmp_int;
2004 case BT848_SUSAT: /* set chroma U saturation */
2005 tmp_int = *(int*)arg;
2007 temp = INB(bktr, BKTR_E_CONTROL);
2008 temp1 = INB(bktr, BKTR_O_CONTROL);
2009 if ( tmp_int & BIT_EIGHT_HIGH ) {
2010 temp |= BT848_E_CONTROL_SAT_U_MSB;
2011 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2014 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2015 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2018 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2019 OUTB(bktr, BKTR_E_CONTROL, temp);
2020 OUTB(bktr, BKTR_O_CONTROL, temp1);
2023 case BT848_GUSAT: /* get chroma U saturation */
2024 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2025 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2026 tmp_int |= BIT_EIGHT_HIGH;
2027 *(int*)arg = tmp_int;
2030 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2032 case BT848_SLNOTCH: /* set luma notch */
2033 tmp_int = (*(int *)arg & 0x7) << 5 ;
2034 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2035 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2036 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2037 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2040 case BT848_GLNOTCH: /* get luma notch */
2041 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2046 case BT848_SCONT: /* set contrast */
2047 tmp_int = *(int*)arg;
2049 temp = INB(bktr, BKTR_E_CONTROL);
2050 temp1 = INB(bktr, BKTR_O_CONTROL);
2051 if ( tmp_int & BIT_EIGHT_HIGH ) {
2052 temp |= BT848_E_CONTROL_CON_MSB;
2053 temp1 |= BT848_O_CONTROL_CON_MSB;
2056 temp &= ~BT848_E_CONTROL_CON_MSB;
2057 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2060 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2061 OUTB(bktr, BKTR_E_CONTROL, temp);
2062 OUTB(bktr, BKTR_O_CONTROL, temp1);
2065 case BT848_GCONT: /* get contrast */
2066 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2067 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2068 tmp_int |= BIT_EIGHT_HIGH;
2069 *(int*)arg = tmp_int;
2072 /* FIXME: SCBARS and CCBARS require a valid int * */
2073 /* argument to succeed, but its not used; consider */
2074 /* using the arg to store the on/off state so */
2075 /* there's only one ioctl() needed to turn cbars on/off */
2076 case BT848_SCBARS: /* set colorbar output */
2077 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2080 case BT848_CCBARS: /* clear colorbar output */
2081 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2084 case BT848_GAUDIO: /* get audio channel */
2085 temp = bktr->audio_mux_select;
2086 if ( bktr->audio_mute_state == TRUE )
2091 case BT848_SBTSC: /* set audio channel */
2092 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2096 case BT848_WEEPROM: /* write eeprom */
2097 offset = (((struct eeProm *)arg)->offset);
2098 count = (((struct eeProm *)arg)->count);
2099 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2100 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2104 case BT848_REEPROM: /* read eeprom */
2105 offset = (((struct eeProm *)arg)->offset);
2106 count = (((struct eeProm *)arg)->count);
2107 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2108 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2112 case BT848_SIGNATURE:
2113 offset = (((struct eeProm *)arg)->offset);
2114 count = (((struct eeProm *)arg)->count);
2115 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2116 if ( signCard( bktr, offset, count, buf ) < 0 )
2120 /* Ioctl's for direct gpio access */
2121 #ifdef BKTR_GPIO_ACCESS
2122 case BT848_GPIO_GET_EN:
2123 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2126 case BT848_GPIO_SET_EN:
2127 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2130 case BT848_GPIO_GET_DATA:
2131 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2134 case BT848_GPIO_SET_DATA:
2135 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2137 #endif /* BKTR_GPIO_ACCESS */
2139 /* Ioctl's for running the tuner device in radio mode */
2142 *(unsigned char *)arg = bktr->tuner.radio_mode;
2146 bktr->tuner.radio_mode = *(unsigned char *)arg;
2150 *(unsigned long *)arg = bktr->tuner.frequency;
2154 /* The argument to this ioctl is NOT freq*16. It is
2158 temp=(int)*(unsigned long *)arg;
2160 #ifdef BKTR_RADIO_DEBUG
2161 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2162 (int)*(unsigned long *)arg, temp);
2165 #ifndef BKTR_RADIO_NOFREQCHECK
2166 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2168 if(temp<8750 || temp>10800) {
2169 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2173 temp_mute( bktr, TRUE );
2174 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2175 temp_mute( bktr, FALSE );
2176 #ifdef BKTR_RADIO_DEBUG
2178 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2182 *(unsigned long *)arg = temp;
2185 /* Luigi's I2CWR ioctl */
2187 par = *(u_long *)arg;
2188 write = (par >> 24) & 0xff ;
2189 i2c_addr = (par >> 16) & 0xff ;
2190 i2c_port = (par >> 8) & 0xff ;
2191 data = (par) & 0xff ;
2194 i2cWrite( bktr, i2c_addr, i2c_port, data);
2196 data = i2cRead( bktr, i2c_addr);
2198 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2202 #ifdef BT848_MSP_READ
2203 /* I2C ioctls to allow userland access to the MSP chip */
2204 case BT848_MSP_READ:
2206 struct bktr_msp_control *msp;
2207 msp = (struct bktr_msp_control *) arg;
2208 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2209 msp->function, msp->address);
2213 case BT848_MSP_WRITE:
2215 struct bktr_msp_control *msp;
2216 msp = (struct bktr_msp_control *) arg;
2217 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2218 msp->address, msp->data );
2222 case BT848_MSP_RESET:
2223 msp_dpl_reset(bktr, bktr->msp_addr);
2228 return common_ioctl( bktr, cmd, arg );
2239 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2243 struct meteor_pixfmt *pf_pub;
2247 case METEORSINPUT: /* set input device */
2248 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2249 /* On the original bt848 boards, */
2250 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2251 /* On the Hauppauge bt878 boards, */
2252 /* Tuner is MUX0, RCA is MUX3 */
2253 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2254 /* stick with this system in our Meteor Emulation */
2256 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2258 /* this is the RCA video input */
2259 case 0: /* default */
2260 case METEOR_INPUT_DEV0:
2261 /* METEOR_INPUT_DEV_RCA: */
2262 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2264 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2265 & ~BT848_IFORM_MUXSEL);
2267 /* work around for new Hauppauge 878 cards */
2268 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2269 (bktr->id==BROOKTREE_878 ||
2270 bktr->id==BROOKTREE_879) )
2271 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2273 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2275 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2276 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2277 set_audio( bktr, AUDIO_EXTERN );
2280 /* this is the tuner input */
2281 case METEOR_INPUT_DEV1:
2282 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2284 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2285 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2286 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2287 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2288 set_audio( bktr, AUDIO_TUNER );
2291 /* this is the S-VHS input, but with a composite camera */
2292 case METEOR_INPUT_DEV2:
2293 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2295 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2296 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2297 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2298 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2299 set_audio( bktr, AUDIO_EXTERN );
2302 /* this is the S-VHS input */
2303 case METEOR_INPUT_DEV_SVIDEO:
2304 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2305 | METEOR_DEV_SVIDEO;
2306 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2307 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2308 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2309 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2310 set_audio( bktr, AUDIO_EXTERN );
2313 case METEOR_INPUT_DEV3:
2314 if ((bktr->id == BROOKTREE_848A) ||
2315 (bktr->id == BROOKTREE_849A) ||
2316 (bktr->id == BROOKTREE_878) ||
2317 (bktr->id == BROOKTREE_879) ) {
2318 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2320 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2322 /* work around for new Hauppauge 878 cards */
2323 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2324 (bktr->id==BROOKTREE_878 ||
2325 bktr->id==BROOKTREE_879) )
2326 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2328 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2330 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2331 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2332 set_audio( bktr, AUDIO_EXTERN );
2342 case METEORGINPUT: /* get input device */
2343 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2346 case METEORSACTPIXFMT:
2347 if (( *(int *)arg < 0 ) ||
2348 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2351 bktr->pixfmt = *(int *)arg;
2352 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2353 | pixfmt_swap_flags( bktr->pixfmt ));
2354 bktr->pixfmt_compat = FALSE;
2357 case METEORGACTPIXFMT:
2358 *(int *)arg = bktr->pixfmt;
2361 case METEORGSUPPIXFMT :
2362 pf_pub = (struct meteor_pixfmt *)arg;
2363 pixfmt = pf_pub->index;
2365 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2368 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2369 sizeof( *pf_pub ) );
2371 /* Patch in our format index */
2372 pf_pub->index = pixfmt;
2375 #if defined( STATUS_SUM )
2376 case BT848_GSTATUS: /* reap status */
2378 DECLARE_INTR_MASK(s);
2383 *(u_int*)arg = temp;
2386 #endif /* STATUS_SUM */
2398 /******************************************************************************
2399 * bt848 RISC programming routines:
2408 dump_bt848( bktr_ptr_t bktr )
2411 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2412 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2413 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2414 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2415 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2420 for (i = 0; i < 40; i+=4) {
2421 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2423 r[i], INL(bktr, r[i]),
2424 r[i+1], INL(bktr, r[i+1]),
2425 r[i+2], INL(bktr, r[i+2]),
2426 r[i+3], INL(bktr, r[i+3]]));
2429 printf("%s: INT STAT %x \n", bktr_name(bktr),
2430 INL(bktr, BKTR_INT_STAT));
2431 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2432 INL(bktr, BKTR_INT_MASK));
2433 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2434 INW(bktr, BKTR_GPIO_DMA_CTL));
2442 * build write instruction
2444 #define BKTR_FM1 0x6 /* packed data to follow */
2445 #define BKTR_FM3 0xe /* planar data to follow */
2446 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2447 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2448 #define BKTR_PXV 0x0 /* valid word (never used) */
2449 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2450 #define BKTR_SOL 0x2 /* first dword */
2452 #define OP_WRITE (0x1 << 28)
2453 #define OP_SKIP (0x2 << 28)
2454 #define OP_WRITEC (0x5 << 28)
2455 #define OP_JUMP (0x7 << 28)
2456 #define OP_SYNC (0x8 << 28)
2457 #define OP_WRITE123 (0x9 << 28)
2458 #define OP_WRITES123 (0xb << 28)
2459 #define OP_SOL (1 << 27) /* first instr for scanline */
2460 #define OP_EOL (1 << 26)
2462 #define BKTR_RESYNC (1 << 15)
2463 #define BKTR_GEN_IRQ (1 << 24)
2466 * The RISC status bits can be set/cleared in the RISC programs
2467 * and tested in the Interrupt Handler
2469 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2470 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2471 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2472 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2474 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2475 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2476 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2477 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2479 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2480 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2481 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2482 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2484 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2486 bktr_clip_t * clip_node;
2487 bktr->clip_start = -1;
2491 bktr->line_length = width;
2494 bktr->current_col = 0;
2496 if (bktr->max_clip_node == 0 ) return TRUE;
2497 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2500 for (i = 0; i < bktr->max_clip_node; i++ ) {
2501 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2502 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2503 bktr->clip_start = i;
2511 static bool_t getline(bktr_reg_t *bktr, int x ) {
2513 bktr_clip_t * clip_node ;
2515 if (bktr->line_length == 0 ||
2516 bktr->current_col >= bktr->line_length) return FALSE;
2518 bktr->y = min(bktr->last_y, bktr->line_length);
2519 bktr->y2 = bktr->line_length;
2521 bktr->yclip = bktr->yclip2 = -1;
2522 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2523 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2524 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2525 if (bktr->last_y <= clip_node->y_min) {
2526 bktr->y = min(bktr->last_y, bktr->line_length);
2527 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2528 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2529 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2530 bktr->last_y = bktr->yclip2;
2531 bktr->clip_start = i;
2533 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2534 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2535 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2536 if (bktr->last_y >= clip_node->y_min) {
2537 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2538 bktr->last_y = bktr->yclip2;
2539 bktr->clip_start = j;
2548 if (bktr->current_col <= bktr->line_length) {
2549 bktr->current_col = bktr->line_length;
2555 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2556 u_long operation, int pixel_width,
2557 volatile u_char ** target_buffer, int cols ) {
2560 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2561 u_int skip, start_skip;
2563 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2564 /* to the 1st byte in the mem dword containing our start addr. */
2565 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2568 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2569 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2570 case 2 : start_skip = 4 ; break;
2571 case 1 : start_skip = 8 ; break;
2574 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2575 if ( width == cols) {
2576 flag = OP_SOL | OP_EOL;
2577 } else if (bktr->current_col == 0 ) {
2579 } else if (bktr->current_col == cols) {
2584 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2585 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2590 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2591 if (operation != OP_SKIP )
2592 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2594 *target_buffer += width * pixel_width;
2595 bktr->current_col += width;
2599 if (bktr->current_col == 0 && width == cols) {
2602 } else if (bktr->current_col == 0 ) {
2605 } else if (bktr->current_col >= cols) {
2614 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2615 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2620 *(*dma_prog)++ = operation | flag |
2621 (width * pixel_width / 2 - skip);
2622 if (operation != OP_SKIP )
2623 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2624 *target_buffer += (width * pixel_width / 2) ;
2626 if ( operation == OP_WRITE )
2627 operation = OP_WRITEC;
2628 *(*dma_prog)++ = operation | flag2 |
2629 (width * pixel_width / 2);
2630 *target_buffer += (width * pixel_width / 2) ;
2631 bktr->current_col += width;
2639 * Generate the RISC instructions to capture both VBI and video images
2642 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2645 volatile u_long target_buffer, buffer, target,width;
2646 volatile u_long pitch;
2647 volatile u_long *dma_prog; /* DMA prog is an array of
2648 32 bit RISC instructions */
2649 volatile u_long *loop_point;
2650 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2651 u_int Bpp = pf_int->public.Bpp;
2652 unsigned int vbisamples; /* VBI samples per line */
2653 unsigned int vbilines; /* VBI lines per field */
2654 unsigned int num_dwords; /* DWORDS per line */
2656 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2657 vbilines = format_params[bktr->format_params].vbi_num_lines;
2658 num_dwords = vbisamples/4;
2660 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2661 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2662 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2663 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2666 OUTB(bktr, BKTR_OFORM, 0x00);
2668 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2669 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2670 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2671 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2673 /* disable gamma correction removal */
2674 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2677 OUTB(bktr, BKTR_E_VTC, 0);
2678 OUTB(bktr, BKTR_O_VTC, 0);
2680 OUTB(bktr, BKTR_E_VTC, 1);
2681 OUTB(bktr, BKTR_O_VTC, 1);
2683 bktr->capcontrol = 3 << 2 | 3;
2685 dma_prog = (u_long *) bktr->dma_prog;
2687 /* Construct Write */
2689 if (bktr->video.addr) {
2690 target_buffer = (u_long) bktr->video.addr;
2691 pitch = bktr->video.width;
2694 target_buffer = (u_long) vtophys(bktr->bigbuf);
2698 buffer = target_buffer;
2700 /* Wait for the VRE sync marking the end of the Even and
2701 * the start of the Odd field. Resync here.
2703 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2706 loop_point = dma_prog;
2708 /* store the VBI data */
2709 /* look for sync with packed data */
2710 *dma_prog++ = OP_SYNC | BKTR_FM1;
2712 for(i = 0; i < vbilines; i++) {
2713 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2714 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2715 (i * VBI_LINE_SIZE));
2718 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2719 /* store the Odd field video image */
2720 /* look for sync with packed data */
2721 *dma_prog++ = OP_SYNC | BKTR_FM1;
2722 *dma_prog++ = 0; /* NULL WORD */
2724 for (i = 0; i < (rows/interlace); i++) {
2725 target = target_buffer;
2726 if ( notclipped(bktr, i, width)) {
2727 split(bktr, (volatile u_long **) &dma_prog,
2728 bktr->y2 - bktr->y, OP_WRITE,
2729 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2732 while(getline(bktr, i)) {
2733 if (bktr->y != bktr->y2 ) {
2734 split(bktr, (volatile u_long **) &dma_prog,
2735 bktr->y2 - bktr->y, OP_WRITE,
2736 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2738 if (bktr->yclip != bktr->yclip2 ) {
2739 split(bktr,(volatile u_long **) &dma_prog,
2740 bktr->yclip2 - bktr->yclip,
2742 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2748 target_buffer += interlace * pitch;
2754 /* Grab the Even field */
2755 /* Look for the VRO, end of Odd field, marker */
2756 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2757 *dma_prog++ = 0; /* NULL WORD */
2759 /* store the VBI data */
2760 /* look for sync with packed data */
2761 *dma_prog++ = OP_SYNC | BKTR_FM1;
2763 for(i = 0; i < vbilines; i++) {
2764 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2765 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2766 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2769 /* store the video image */
2770 if (i_flag == 1) /*Even Only*/
2771 target_buffer = buffer;
2772 if (i_flag == 3) /*interlaced*/
2773 target_buffer = buffer+pitch;
2776 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2777 /* look for sync with packed data */
2778 *dma_prog++ = OP_SYNC | BKTR_FM1;
2779 *dma_prog++ = 0; /* NULL WORD */
2781 for (i = 0; i < (rows/interlace); i++) {
2782 target = target_buffer;
2783 if ( notclipped(bktr, i, width)) {
2784 split(bktr, (volatile u_long **) &dma_prog,
2785 bktr->y2 - bktr->y, OP_WRITE,
2786 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2788 while(getline(bktr, i)) {
2789 if (bktr->y != bktr->y2 ) {
2790 split(bktr, (volatile u_long **) &dma_prog,
2791 bktr->y2 - bktr->y, OP_WRITE,
2792 Bpp, (volatile u_char **)(uintptr_t)&target,
2795 if (bktr->yclip != bktr->yclip2 ) {
2796 split(bktr, (volatile u_long **) &dma_prog,
2797 bktr->yclip2 - bktr->yclip, OP_SKIP,
2798 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2805 target_buffer += interlace * pitch;
2810 /* Look for end of 'Even Field' */
2811 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2812 *dma_prog++ = 0; /* NULL WORD */
2814 *dma_prog++ = OP_JUMP ;
2815 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2816 *dma_prog++ = 0; /* NULL WORD */
2824 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2827 volatile u_long target_buffer, buffer, target,width;
2828 volatile u_long pitch;
2829 volatile u_long *dma_prog;
2830 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2831 u_int Bpp = pf_int->public.Bpp;
2833 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2834 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2835 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2836 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2838 OUTB(bktr, BKTR_OFORM, 0x00);
2840 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2841 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2842 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2843 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2845 /* disable gamma correction removal */
2846 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2849 OUTB(bktr, BKTR_E_VTC, 0);
2850 OUTB(bktr, BKTR_O_VTC, 0);
2852 OUTB(bktr, BKTR_E_VTC, 1);
2853 OUTB(bktr, BKTR_O_VTC, 1);
2855 bktr->capcontrol = 3 << 2 | 3;
2857 dma_prog = (u_long *) bktr->dma_prog;
2859 /* Construct Write */
2861 if (bktr->video.addr) {
2862 target_buffer = (u_long) bktr->video.addr;
2863 pitch = bktr->video.width;
2866 target_buffer = (u_long) vtophys(bktr->bigbuf);
2870 buffer = target_buffer;
2872 /* contruct sync : for video packet format */
2873 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2875 /* sync, mode indicator packed data */
2876 *dma_prog++ = 0; /* NULL WORD */
2878 for (i = 0; i < (rows/interlace); i++) {
2879 target = target_buffer;
2880 if ( notclipped(bktr, i, width)) {
2881 split(bktr, (volatile u_long **) &dma_prog,
2882 bktr->y2 - bktr->y, OP_WRITE,
2883 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2886 while(getline(bktr, i)) {
2887 if (bktr->y != bktr->y2 ) {
2888 split(bktr, (volatile u_long **) &dma_prog,
2889 bktr->y2 - bktr->y, OP_WRITE,
2890 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2892 if (bktr->yclip != bktr->yclip2 ) {
2893 split(bktr,(volatile u_long **) &dma_prog,
2894 bktr->yclip2 - bktr->yclip,
2896 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2902 target_buffer += interlace * pitch;
2909 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2910 *dma_prog++ = 0; /* NULL WORD */
2912 *dma_prog++ = OP_JUMP;
2913 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2918 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2919 *dma_prog++ = 0; /* NULL WORD */
2921 *dma_prog++ = OP_JUMP;
2922 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2927 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2928 *dma_prog++ = 0; /* NULL WORD */
2929 *dma_prog++ = OP_JUMP; ;
2930 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
2934 if (interlace == 2) {
2936 target_buffer = buffer + pitch;
2938 dma_prog = (u_long *) bktr->odd_dma_prog;
2940 /* sync vre IRQ bit */
2941 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2942 *dma_prog++ = 0; /* NULL WORD */
2944 for (i = 0; i < (rows/interlace); i++) {
2945 target = target_buffer;
2946 if ( notclipped(bktr, i, width)) {
2947 split(bktr, (volatile u_long **) &dma_prog,
2948 bktr->y2 - bktr->y, OP_WRITE,
2949 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2951 while(getline(bktr, i)) {
2952 if (bktr->y != bktr->y2 ) {
2953 split(bktr, (volatile u_long **) &dma_prog,
2954 bktr->y2 - bktr->y, OP_WRITE,
2955 Bpp, (volatile u_char **)(uintptr_t)&target,
2958 if (bktr->yclip != bktr->yclip2 ) {
2959 split(bktr, (volatile u_long **) &dma_prog,
2960 bktr->yclip2 - bktr->yclip, OP_SKIP,
2961 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2968 target_buffer += interlace * pitch;
2973 /* sync vre IRQ bit */
2974 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2975 *dma_prog++ = 0; /* NULL WORD */
2976 *dma_prog++ = OP_JUMP ;
2977 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
2978 *dma_prog++ = 0; /* NULL WORD */
2986 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
2987 int cols, int rows, int interlace )
2990 volatile unsigned int inst;
2991 volatile unsigned int inst3;
2992 volatile u_long target_buffer, buffer;
2993 volatile u_long *dma_prog;
2994 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2997 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2999 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3000 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3002 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3003 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3005 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3006 bktr->capcontrol = 3 << 2 | 3;
3008 dma_prog = (u_long *) bktr->dma_prog;
3010 /* Construct Write */
3012 /* write , sol, eol */
3013 inst = OP_WRITE | OP_SOL | (cols);
3014 /* write , sol, eol */
3015 inst3 = OP_WRITE | OP_EOL | (cols);
3017 if (bktr->video.addr)
3018 target_buffer = (u_long) bktr->video.addr;
3020 target_buffer = (u_long) vtophys(bktr->bigbuf);
3022 buffer = target_buffer;
3024 /* contruct sync : for video packet format */
3025 /* sync, mode indicator packed data */
3026 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3027 *dma_prog++ = 0; /* NULL WORD */
3031 for (i = 0; i < (rows/interlace); i++) {
3033 *dma_prog++ = target_buffer;
3034 *dma_prog++ = inst3;
3035 *dma_prog++ = target_buffer + b;
3036 target_buffer += interlace*(cols * 2);
3042 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3043 *dma_prog++ = 0; /* NULL WORD */
3045 *dma_prog++ = OP_JUMP;
3046 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3051 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3052 *dma_prog++ = 0; /* NULL WORD */
3053 *dma_prog++ = OP_JUMP;
3054 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3059 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3060 *dma_prog++ = 0; /* NULL WORD */
3061 *dma_prog++ = OP_JUMP ;
3062 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3066 if (interlace == 2) {
3068 target_buffer = (u_long) buffer + cols*2;
3070 dma_prog = (u_long * ) bktr->odd_dma_prog;
3073 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3074 *dma_prog++ = 0; /* NULL WORD */
3076 for (i = 0; i < (rows/interlace) ; i++) {
3078 *dma_prog++ = target_buffer;
3079 *dma_prog++ = inst3;
3080 *dma_prog++ = target_buffer + b;
3081 target_buffer += interlace * ( cols*2);
3085 /* sync vro IRQ bit */
3086 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3087 *dma_prog++ = 0; /* NULL WORD */
3088 *dma_prog++ = OP_JUMP ;
3089 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3091 *dma_prog++ = OP_JUMP;
3092 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3093 *dma_prog++ = 0; /* NULL WORD */
3101 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3102 int cols, int rows, int interlace ){
3105 volatile unsigned int inst;
3106 volatile u_long target_buffer, t1, buffer;
3107 volatile u_long *dma_prog;
3108 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3110 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3112 dma_prog = (u_long *) bktr->dma_prog;
3114 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3116 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3117 OUTB(bktr, BKTR_OFORM, 0x00);
3119 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3120 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3122 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3123 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3125 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3126 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3127 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3128 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3130 /* disable gamma correction removal */
3131 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3133 /* Construct Write */
3134 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3135 if (bktr->video.addr)
3136 target_buffer = (u_long) bktr->video.addr;
3138 target_buffer = (u_long) vtophys(bktr->bigbuf);
3140 buffer = target_buffer;
3144 /* contruct sync : for video packet format */
3145 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3146 *dma_prog++ = 0; /* NULL WORD */
3148 for (i = 0; i < (rows/interlace ) ; i++) {
3150 *dma_prog++ = cols/2 | cols/2 << 16;
3151 *dma_prog++ = target_buffer;
3152 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3153 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3154 target_buffer += interlace*cols;
3159 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3160 *dma_prog++ = 0; /* NULL WORD */
3162 *dma_prog++ = OP_JUMP ;
3163 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3167 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3168 *dma_prog++ = 0; /* NULL WORD */
3170 *dma_prog++ = OP_JUMP;
3171 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3175 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3176 *dma_prog++ = 0; /* NULL WORD */
3178 *dma_prog++ = OP_JUMP ;
3179 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3183 if (interlace == 2) {
3185 dma_prog = (u_long * ) bktr->odd_dma_prog;
3187 target_buffer = (u_long) buffer + cols;
3188 t1 = buffer + cols/2;
3189 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3190 *dma_prog++ = 0; /* NULL WORD */
3192 for (i = 0; i < (rows/interlace ) ; i++) {
3194 *dma_prog++ = cols/2 | cols/2 << 16;
3195 *dma_prog++ = target_buffer;
3196 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3197 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3198 target_buffer += interlace*cols;
3202 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3203 *dma_prog++ = 0; /* NULL WORD */
3204 *dma_prog++ = OP_JUMP ;
3205 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3206 *dma_prog++ = 0; /* NULL WORD */
3214 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3215 int cols, int rows, int interlace ){
3218 volatile unsigned int inst;
3219 volatile unsigned int inst1;
3220 volatile u_long target_buffer, t1, buffer;
3221 volatile u_long *dma_prog;
3222 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3224 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3226 dma_prog = (u_long *) bktr->dma_prog;
3228 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3230 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3231 OUTB(bktr, BKTR_OFORM, 0x0);
3233 /* Construct Write */
3234 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3235 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3236 if (bktr->video.addr)
3237 target_buffer = (u_long) bktr->video.addr;
3239 target_buffer = (u_long) vtophys(bktr->bigbuf);
3241 buffer = target_buffer;
3244 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3245 *dma_prog++ = 0; /* NULL WORD */
3247 for (i = 0; i < (rows/interlace )/2 ; i++) {
3249 *dma_prog++ = cols/2 | (cols/2 << 16);
3250 *dma_prog++ = target_buffer;
3251 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3252 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3253 target_buffer += interlace*cols;
3254 *dma_prog++ = inst1;
3255 *dma_prog++ = cols/2 | (cols/2 << 16);
3256 *dma_prog++ = target_buffer;
3257 target_buffer += interlace*cols;
3263 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3264 *dma_prog++ = 0; /* NULL WORD */
3266 *dma_prog++ = OP_JUMP;
3267 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3271 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3272 *dma_prog++ = 0; /* NULL WORD */
3274 *dma_prog++ = OP_JUMP;
3275 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3279 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3280 *dma_prog++ = 0; /* NULL WORD */
3281 *dma_prog++ = OP_JUMP ;
3282 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3286 if (interlace == 2) {
3288 dma_prog = (u_long * ) bktr->odd_dma_prog;
3290 target_buffer = (u_long) buffer + cols;
3291 t1 = buffer + cols/2;
3292 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3293 *dma_prog++ = 0; /* NULL WORD */
3295 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3297 *dma_prog++ = cols/2 | (cols/2 << 16);
3298 *dma_prog++ = target_buffer;
3299 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3300 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3301 target_buffer += interlace*cols;
3302 *dma_prog++ = inst1;
3303 *dma_prog++ = cols/2 | (cols/2 << 16);
3304 *dma_prog++ = target_buffer;
3305 target_buffer += interlace*cols;
3312 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3313 *dma_prog++ = 0; /* NULL WORD */
3314 *dma_prog++ = OP_JUMP;
3315 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3316 *dma_prog++ = 0; /* NULL WORD */
3325 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3327 int rows, cols, interlace;
3330 struct format_params *fp;
3331 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3334 fp = &format_params[bktr->format_params];
3336 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3338 /* disable FIFO & RISC, leave other bits alone */
3339 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3341 /* set video parameters */
3342 if (bktr->capture_area_enabled)
3343 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3344 / fp->scaled_htotal / bktr->cols) - 4096;
3346 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3347 / fp->scaled_htotal / bktr->cols) - 4096;
3349 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3350 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3351 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3352 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3353 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3355 /* horizontal active */
3357 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3358 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3359 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3360 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3361 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3362 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3363 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3365 /* horizontal delay */
3366 if (bktr->capture_area_enabled)
3367 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3368 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3370 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3372 temp = temp & 0x3fe;
3374 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3375 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3376 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3377 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3378 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3379 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3380 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3382 /* vertical scale */
3384 if (bktr->capture_area_enabled) {
3385 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3386 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3388 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3391 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3394 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3395 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3397 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3400 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3405 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3406 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3407 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3408 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3409 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3410 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3411 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3414 /* vertical active */
3415 if (bktr->capture_area_enabled)
3416 temp = bktr->capture_area_y_size;
3419 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3420 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3421 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3422 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3423 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3424 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3425 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3427 /* vertical delay */
3428 if (bktr->capture_area_enabled)
3429 temp = fp->vdelay + (bktr->capture_area_y_offset);
3432 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3433 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3434 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3435 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3436 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3437 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3438 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3440 /* end of video params */
3442 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3443 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3444 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3446 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3449 /* capture control */
3452 bktr->bktr_cap_ctl =
3453 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3454 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3455 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3459 bktr->bktr_cap_ctl =
3460 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3461 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3462 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3466 bktr->bktr_cap_ctl =
3467 (BT848_CAP_CTL_DITH_FRAME |
3468 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3469 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3470 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3475 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3480 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3482 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3483 /* user, then use the rgb_vbi RISC program. */
3484 /* Otherwise, use the normal rgb RISC program */
3485 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3486 if ( (bktr->vbiflags & VBI_OPEN)
3487 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3488 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3490 bktr->bktr_cap_ctl |=
3491 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3492 bktr->vbiflags |= VBI_CAPTURE;
3493 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3496 rgb_prog(bktr, i_flag, cols, rows, interlace);
3501 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3502 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3503 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3504 | pixfmt_swap_flags( bktr->pixfmt ));
3508 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3509 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3510 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3511 | pixfmt_swap_flags( bktr->pixfmt ));
3515 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3516 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3517 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3518 | pixfmt_swap_flags( bktr->pixfmt ));
3525 /******************************************************************************
3526 * video & video capture specific routines:
3534 start_capture( bktr_ptr_t bktr, unsigned type )
3537 struct format_params *fp;
3539 fp = &format_params[bktr->format_params];
3541 /* If requested, clear out capture buf first */
3542 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3543 bzero((caddr_t)bktr->bigbuf,
3544 (size_t)bktr->rows * bktr->cols * bktr->frames *
3545 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3548 OUTB(bktr, BKTR_DSTATUS, 0);
3549 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3551 bktr->flags |= type;
3552 bktr->flags &= ~METEOR_WANT_MASK;
3553 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3554 case METEOR_ONLY_EVEN_FIELDS:
3555 bktr->flags |= METEOR_WANT_EVEN;
3558 case METEOR_ONLY_ODD_FIELDS:
3559 bktr->flags |= METEOR_WANT_ODD;
3563 bktr->flags |= METEOR_WANT_MASK;
3568 /* TDEC is only valid for continuous captures */
3569 if ( type == METEOR_SINGLE ) {
3570 u_short fps_save = bktr->fps;
3572 set_fps(bktr, fp->frame_rate);
3573 bktr->fps = fps_save;
3576 set_fps(bktr, bktr->fps);
3578 if (bktr->dma_prog_loaded == FALSE) {
3579 build_dma_prog(bktr, i_flag);
3580 bktr->dma_prog_loaded = TRUE;
3584 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3593 set_fps( bktr_ptr_t bktr, u_short fps )
3595 struct format_params *fp;
3598 fp = &format_params[bktr->format_params];
3600 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3601 case METEOR_ONLY_EVEN_FIELDS:
3602 bktr->flags |= METEOR_WANT_EVEN;
3605 case METEOR_ONLY_ODD_FIELDS:
3606 bktr->flags |= METEOR_WANT_ODD;
3610 bktr->flags |= METEOR_WANT_MASK;
3615 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3616 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3619 OUTB(bktr, BKTR_TDEC, 0);
3621 if (fps < fp->frame_rate)
3622 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3624 OUTB(bktr, BKTR_TDEC, 0);
3634 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3635 * achieve the specified swapping.
3636 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3637 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3639 * Note also that for 3Bpp, we may additionally need to do some creative
3640 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3641 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3642 * as one would expect.
3645 static u_int pixfmt_swap_flags( int pixfmt )
3647 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3650 switch ( pf->Bpp ) {
3651 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3654 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3657 case 4 : if ( pf->swap_bytes )
3658 swapf = pf->swap_shorts ? 0 : WSWAP;
3660 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3669 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3670 * our pixfmt_table indices.
3673 static int oformat_meteor_to_bt( u_long format )
3676 struct meteor_pixfmt *pf1, *pf2;
3678 /* Find format in compatibility table */
3679 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3680 if ( meteor_pixfmt_table[i].meteor_format == format )
3683 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3685 pf1 = &meteor_pixfmt_table[i].public;
3687 /* Match it with an entry in master pixel format table */
3688 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3689 pf2 = &pixfmt_table[i].public;
3691 if (( pf1->type == pf2->type ) &&
3692 ( pf1->Bpp == pf2->Bpp ) &&
3693 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3694 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3695 ( pf1->swap_shorts == pf2->swap_shorts ))
3698 if ( i >= PIXFMT_TABLE_SIZE )
3704 /******************************************************************************
3709 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3710 #define I2CBITTIME_878 (1 << 7)
3711 #define I2C_READ 0x01
3712 #define I2C_COMMAND (I2CBITTIME | \
3713 BT848_DATA_CTL_I2CSCL | \
3714 BT848_DATA_CTL_I2CSDA)
3716 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3717 BT848_DATA_CTL_I2CSCL | \
3718 BT848_DATA_CTL_I2CSDA)
3720 /* Select between old i2c code and new iicbus / smbus code */
3721 #if defined(BKTR_USE_FREEBSD_SMBUS)
3724 * The hardware interface is actually SMB commands
3727 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3731 if (bktr->id == BROOKTREE_848 ||
3732 bktr->id == BROOKTREE_848A ||
3733 bktr->id == BROOKTREE_849A)
3736 cmd = I2C_COMMAND_878;
3739 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3740 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3743 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3744 (char)(byte1 & 0xff)))
3753 i2cRead( bktr_ptr_t bktr, int addr )
3758 if (bktr->id == BROOKTREE_848 ||
3759 bktr->id == BROOKTREE_848A ||
3760 bktr->id == BROOKTREE_849A)
3763 cmd = I2C_COMMAND_878;
3765 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3768 return ((int)((unsigned char)result));
3771 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3773 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3774 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3775 /* Therefore we need low level control of the i2c bus hardware */
3777 /* Write to the MSP or DPL registers */
3779 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3781 unsigned char addr_l, addr_h, data_h, data_l ;
3783 addr_h = (addr >>8) & 0xff;
3784 addr_l = addr & 0xff;
3785 data_h = (data >>8) & 0xff;
3786 data_l = data & 0xff;
3788 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3790 iicbus_write_byte(IICBUS(bktr), dev, 0);
3791 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3792 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3793 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3794 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3796 iicbus_stop(IICBUS(bktr));
3801 /* Read from the MSP or DPL registers */
3803 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3806 unsigned char addr_l, addr_h, dev_r;
3808 u_char data_read[2];
3810 addr_h = (addr >>8) & 0xff;
3811 addr_l = addr & 0xff;
3814 /* XXX errors ignored */
3815 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3817 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3818 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3819 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3821 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3822 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3823 iicbus_stop(IICBUS(bktr));
3825 data = (data_read[0]<<8) | data_read[1];
3830 /* Reset the MSP or DPL chip */
3831 /* The user can block the reset (which is handy if you initialise the
3832 * MSP and/or DPL audio in another operating system first (eg in Windows)
3835 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3838 #ifndef BKTR_NO_MSP_RESET
3839 /* put into reset mode */
3840 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3841 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3842 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3843 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3844 iicbus_stop(IICBUS(bktr));
3846 /* put back to operational mode */
3847 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3848 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3849 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3850 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3851 iicbus_stop(IICBUS(bktr));
3856 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3859 /* XXX errors ignored */
3860 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3861 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3862 iicbus_stop(IICBUS(bktr));
3867 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3870 * Program the i2c bus directly
3873 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3878 /* clear status bits */
3879 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3881 /* build the command datum */
3882 if (bktr->id == BROOKTREE_848 ||
3883 bktr->id == BROOKTREE_848A ||
3884 bktr->id == BROOKTREE_849A) {
3885 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3887 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3889 if ( byte2 != -1 ) {
3890 data |= ((byte2 & 0xff) << 8);
3891 data |= BT848_DATA_CTL_I2CW3B;
3894 /* write the address and data */
3895 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3897 /* wait for completion */
3898 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3899 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3904 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3916 i2cRead( bktr_ptr_t bktr, int addr )
3920 /* clear status bits */
3921 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3923 /* write the READ address */
3924 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3926 if (bktr->id == BROOKTREE_848 ||
3927 bktr->id == BROOKTREE_848A ||
3928 bktr->id == BROOKTREE_849A) {
3929 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3931 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3934 /* wait for completion */
3935 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3936 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3941 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3945 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
3948 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3949 /* bt848 automated i2c bus controller cannot handle */
3950 /* Therefore we need low level control of the i2c bus hardware */
3951 /* Idea for the following functions are from elsewhere in this driver and */
3952 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3955 static void i2c_start( bktr_ptr_t bktr) {
3956 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3957 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3958 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3959 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3962 static void i2c_stop( bktr_ptr_t bktr) {
3963 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3964 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3965 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3968 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3972 /* write out the byte */
3973 for ( x = 7; x >= 0; --x ) {
3974 if ( data & (1<<x) ) {
3975 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3976 DELAY( BITD ); /* assert HI data */
3977 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3978 DELAY( BITD ); /* strobe clock */
3979 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3980 DELAY( BITD ); /* release clock */
3983 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3984 DELAY( BITD ); /* assert LO data */
3985 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3986 DELAY( BITD ); /* strobe clock */
3987 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3988 DELAY( BITD ); /* release clock */
3992 /* look for an ACK */
3993 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3994 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3995 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3996 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4001 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4006 /* read in the byte */
4007 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4008 DELAY( BITD ); /* float data */
4009 for ( x = 7; x >= 0; --x ) {
4010 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4011 DELAY( BITD ); /* strobe clock */
4012 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4013 if ( bit ) byte |= (1<<x);
4014 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4015 DELAY( BITD ); /* release clock */
4017 /* After reading the byte, send an ACK */
4018 /* (unless that was the last byte, for which we send a NAK */
4019 if (last) { /* send NAK - same a writing a 1 */
4020 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4021 DELAY( BITD ); /* set data bit */
4022 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4023 DELAY( BITD ); /* strobe clock */
4024 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4025 DELAY( BITD ); /* release clock */
4026 } else { /* send ACK - same as writing a 0 */
4027 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4028 DELAY( BITD ); /* set data bit */
4029 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4030 DELAY( BITD ); /* strobe clock */
4031 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4032 DELAY( BITD ); /* release clock */
4040 /* Write to the MSP or DPL registers */
4041 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4043 unsigned int msp_w_addr = i2c_addr;
4044 unsigned char addr_l, addr_h, data_h, data_l ;
4045 addr_h = (addr >>8) & 0xff;
4046 addr_l = addr & 0xff;
4047 data_h = (data >>8) & 0xff;
4048 data_l = data & 0xff;
4051 i2c_write_byte(bktr, msp_w_addr);
4052 i2c_write_byte(bktr, dev);
4053 i2c_write_byte(bktr, addr_h);
4054 i2c_write_byte(bktr, addr_l);
4055 i2c_write_byte(bktr, data_h);
4056 i2c_write_byte(bktr, data_l);
4060 /* Read from the MSP or DPL registers */
4061 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4063 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4064 addr_h = (addr >>8) & 0xff;
4065 addr_l = addr & 0xff;
4069 i2c_write_byte(bktr,i2c_addr);
4070 i2c_write_byte(bktr,dev_r);
4071 i2c_write_byte(bktr,addr_h);
4072 i2c_write_byte(bktr,addr_l);
4075 i2c_write_byte(bktr,i2c_addr+1);
4076 i2c_read_byte(bktr,&data_1, 0);
4077 i2c_read_byte(bktr,&data_2, 1);
4079 data = (data_1<<8) | data_2;
4083 /* Reset the MSP or DPL chip */
4084 /* The user can block the reset (which is handy if you initialise the
4085 * MSP audio in another operating system first (eg in Windows)
4087 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4089 #ifndef BKTR_NO_MSP_RESET
4090 /* put into reset mode */
4092 i2c_write_byte(bktr, i2c_addr);
4093 i2c_write_byte(bktr, 0x00);
4094 i2c_write_byte(bktr, 0x80);
4095 i2c_write_byte(bktr, 0x00);
4098 /* put back to operational mode */
4100 i2c_write_byte(bktr, i2c_addr);
4101 i2c_write_byte(bktr, 0x00);
4102 i2c_write_byte(bktr, 0x00);
4103 i2c_write_byte(bktr, 0x00);
4110 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4112 /* XXX errors ignored */
4114 i2c_write_byte(bktr,bktr->remote_control_addr);
4115 i2c_read_byte(bktr,&(remote->data[0]), 0);
4116 i2c_read_byte(bktr,&(remote->data[1]), 0);
4117 i2c_read_byte(bktr,&(remote->data[2]), 0);
4123 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4126 #if defined( I2C_SOFTWARE_PROBE )
4129 * we are keeping this around for any parts that we need to probe
4130 * but that CANNOT be probed via an i2c read.
4131 * this is necessary because the hardware i2c mechanism
4132 * cannot be programmed for 1 byte writes.
4133 * currently there are no known i2c parts that we need to probe
4134 * and that cannot be safely read.
4136 static int i2cProbe( bktr_ptr_t bktr, int addr );
4141 * probe for an I2C device at addr.
4144 i2cProbe( bktr_ptr_t bktr, int addr )
4149 #if defined( EXTRA_START )
4150 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4151 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4152 #endif /* EXTRA_START */
4153 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4154 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4157 for ( x = 7; x >= 0; --x ) {
4158 if ( addr & (1<<x) ) {
4159 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4160 DELAY( BITD ); /* assert HI data */
4161 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4162 DELAY( BITD ); /* strobe clock */
4163 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4164 DELAY( BITD ); /* release clock */
4167 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4168 DELAY( BITD ); /* assert LO data */
4169 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4170 DELAY( BITD ); /* strobe clock */
4171 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4172 DELAY( BITD ); /* release clock */
4176 /* look for an ACK */
4177 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4178 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4179 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4180 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4183 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4184 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4185 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4192 #endif /* I2C_SOFTWARE_PROBE */