2 * SPDX-License-Identifier: BSD-4-Clause
4 * 1. Redistributions of source code must retain the
5 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Amancio Hasty and
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
36 * 1. Redistributions of source code must retain the
37 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
38 * All rights reserved.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by Mark Tinguely and Jim Lowe
51 * 4. The name of the author may not be used to endorse or promote products
52 * derived from this software without specific prior written permission.
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
56 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
62 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
63 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
67 #include <sys/cdefs.h>
68 __FBSDID("$FreeBSD$");
71 * This is part of the Driver for Video Capture Cards (Frame grabbers)
72 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
74 * Copyright Roger Hardiman and Amancio Hasty.
76 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
77 * Handles all the open, close, ioctl and read userland calls.
78 * Sets the Bt848 registers and generates RISC pograms.
79 * Controls the i2c bus and GPIO interface.
80 * Contains the interface to the kernel.
81 * (eg probe/attach and open/close/ioctl)
85 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
86 Jim Lowe's driver for the Matrox Meteor PCI card . The
87 Philips SAA 7116 and SAA 7196 are very different chipsets than
90 The original copyright notice by Mark and Jim is included mostly
91 to honor their fantastic work in the Matrox Meteor driver!
94 #include "opt_bktr.h" /* Include any kernel config options */
97 (defined(__FreeBSD__)) \
98 || (defined(__bsdi__)) \
99 || (defined(__OpenBSD__)) \
100 || (defined(__NetBSD__)) \
104 /*******************/
105 /* *** FreeBSD *** */
106 /*******************/
109 #include <sys/param.h>
110 #include <sys/systm.h>
111 #include <sys/kernel.h>
112 #include <sys/fcntl.h>
113 #include <sys/lock.h>
114 #include <sys/malloc.h>
115 #include <sys/mutex.h>
116 #include <sys/proc.h>
117 #include <sys/signalvar.h>
118 #include <sys/selinfo.h>
122 #include <vm/vm_kern.h>
124 #include <vm/vm_extern.h>
126 #include <sys/bus.h> /* used by smbus and newbus */
128 #if (__FreeBSD_version < 500000)
129 #include <machine/clock.h> /* for DELAY */
131 #define PROC_UNLOCK(p)
132 #include <pci/pcivar.h>
134 #include <dev/pci/pcivar.h>
137 #include <machine/bus.h>
140 #include <dev/bktr/ioctl_meteor.h>
141 #include <dev/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
142 #include <dev/bktr/bktr_reg.h>
143 #include <dev/bktr/bktr_tuner.h>
144 #include <dev/bktr/bktr_card.h>
145 #include <dev/bktr/bktr_audio.h>
146 #include <dev/bktr/bktr_os.h>
147 #include <dev/bktr/bktr_core.h>
148 #if defined(BKTR_FREEBSD_MODULE)
149 #include <dev/bktr/bktr_mem.h>
152 #if defined(BKTR_USE_FREEBSD_SMBUS)
153 #include <dev/bktr/bktr_i2c.h>
154 #include <dev/smbus/smbconf.h>
155 #include <dev/iicbus/iiconf.h>
156 #include "smbus_if.h"
157 #include "iicbus_if.h"
161 bktr_name(bktr_ptr_t bktr)
163 return bktr->bktr_xname;
167 #endif /* __FreeBSD__ */
175 #define PROC_UNLOCK(p)
176 #endif /* __bsdi__ */
179 /**************************/
180 /* *** OpenBSD/NetBSD *** */
181 /**************************/
182 #if defined(__NetBSD__) || defined(__OpenBSD__)
184 #include <sys/param.h>
185 #include <sys/systm.h>
186 #include <sys/kernel.h>
187 #include <sys/signalvar.h>
188 #include <sys/vnode.h>
191 #include <uvm/uvm_extern.h>
194 #include <vm/vm_kern.h>
196 #include <vm/vm_extern.h>
199 #include <sys/inttypes.h> /* uintptr_t */
200 #include <dev/ic/bt8xx.h>
201 #include <dev/pci/bktr/bktr_reg.h>
202 #include <dev/pci/bktr/bktr_tuner.h>
203 #include <dev/pci/bktr/bktr_card.h>
204 #include <dev/pci/bktr/bktr_audio.h>
205 #include <dev/pci/bktr/bktr_core.h>
206 #include <dev/pci/bktr/bktr_os.h>
208 static int bt848_format = -1;
211 bktr_name(bktr_ptr_t bktr)
213 return (bktr->bktr_dev.dv_xname);
217 #define PROC_UNLOCK(p)
219 #endif /* __NetBSD__ || __OpenBSD__ */
222 typedef u_char bool_t;
224 #define BKTRPRI (PZERO+8)|PCATCH
225 #define VBIPRI (PZERO-4)|PCATCH
229 * memory allocated for DMA programs
231 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
233 /* When to split a dma transfer , the bt848 has timing as well as
234 dma transfer size limitations so that we have to split dma
235 transfers into two dma requests
237 #define DMA_BT848_SPLIT 319*2
240 * Allocate enough memory for:
241 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
243 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
244 * in your kernel configuration file.
247 #ifndef BROOKTREE_ALLOC_PAGES
248 #define BROOKTREE_ALLOC_PAGES 217*4
250 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
252 /* Definitions for VBI capture.
253 * There are 16 VBI lines in a PAL video field (32 in a frame),
254 * and we take 2044 samples from each line (placed in a 2048 byte buffer
256 * VBI lines are held in a circular buffer before being read by a
257 * user program from /dev/vbi.
260 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
261 #define VBI_LINE_SIZE 2048 /* Store up to 2048 bytes per line */
262 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
263 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
264 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
267 /* Defines for fields */
273 * Parameters describing size of transmitted image.
276 static struct format_params format_params[] = {
277 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
278 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
280 /* # define BT848_IFORM_F_NTSCM (0x1) */
281 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
283 /* # define BT848_IFORM_F_NTSCJ (0x2) */
284 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
286 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
287 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
289 /* # define BT848_IFORM_F_PALM (0x4) */
290 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
292 /* # define BT848_IFORM_F_PALN (0x5) */
293 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
295 /* # define BT848_IFORM_F_SECAM (0x6) */
296 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
298 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
299 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
304 * Table of supported Pixel Formats
307 static struct meteor_pixfmt_internal {
308 struct meteor_pixfmt public;
312 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
313 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
315 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
316 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
318 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
320 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
321 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
322 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
323 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
324 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
325 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
326 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
329 #define PIXFMT_TABLE_SIZE nitems(pixfmt_table)
332 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
335 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
337 u_long meteor_format;
338 struct meteor_pixfmt public;
339 } meteor_pixfmt_table[] = {
341 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
344 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
345 { METEOR_GEO_YUV_422,
346 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
348 { METEOR_GEO_YUV_PACKED,
349 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
352 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
355 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
359 #define METEOR_PIXFMT_TABLE_SIZE nitems(meteor_pixfmt_table)
362 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
363 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
367 /* sync detect threshold */
369 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
370 BT848_ADC_CRUSH) /* threshold ~125 mV */
372 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
373 BT848_ADC_SYNC_T) /* threshold ~75 mV */
379 /* debug utility for holding previous INT_STAT contents */
381 static u_long status_sum = 0;
384 * defines to make certain bit-fiddles understandable
386 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
387 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
388 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
389 #define FIFO_RISC_DISABLED 0
391 #define ALL_INTS_DISABLED 0
392 #define ALL_INTS_CLEARED 0xffffffff
393 #define CAPTURE_OFF 0
395 #define BIT_SEVEN_HIGH (1<<7)
396 #define BIT_EIGHT_HIGH (1<<8)
398 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
399 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
403 static int oformat_meteor_to_bt( u_long format );
405 static u_int pixfmt_swap_flags( int pixfmt );
408 * bt848 RISC programming routines.
411 static int dump_bt848( bktr_ptr_t bktr );
414 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
415 int rows, int interlace );
416 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
417 int rows, int interlace );
418 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
419 int rows, int interlace );
420 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
421 int rows, int interlace );
422 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
423 int rows, int interlace );
424 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
426 static bool_t getline(bktr_reg_t *, int);
427 static bool_t notclipped(bktr_reg_t * , int , int);
428 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
429 volatile u_char ** , int );
431 static void start_capture( bktr_ptr_t bktr, unsigned type );
432 static void set_fps( bktr_ptr_t bktr, u_short fps );
437 * Remote Control Functions
439 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
443 * ioctls common to both video & tuner.
445 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
448 #if !defined(BKTR_USE_FREEBSD_SMBUS)
450 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
452 static void i2c_start( bktr_ptr_t bktr);
453 static void i2c_stop( bktr_ptr_t bktr);
454 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
455 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
461 * the common attach code, used by all OS versions.
464 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
467 int need_to_allocate_memory = 1;
468 #ifdef BKTR_NEW_MSP34XX_DRIVER
472 /***************************************/
473 /* *** OS Specific memory routines *** */
474 /***************************************/
475 #if defined(__NetBSD__) || defined(__OpenBSD__)
476 /* allocate space for dma program */
477 bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog,
479 bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
482 /* allocate space for the VBI buffer */
483 bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata,
485 bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
488 /* allocate space for pixel buffer */
489 if ( BROOKTREE_ALLOC )
490 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
495 #if defined(__FreeBSD__) || defined(__bsdi__)
497 /* If this is a module, check if there is any currently saved contiguous memory */
498 #if defined(BKTR_FREEBSD_MODULE)
499 if (bktr_has_stored_addresses(unit) == 1) {
500 /* recover the addresses */
501 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
502 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
503 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
504 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
505 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
506 need_to_allocate_memory = 0;
510 if (need_to_allocate_memory == 1) {
511 /* allocate space for dma program */
512 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
513 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
515 /* allocte space for the VBI buffer */
516 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
517 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
519 /* allocate space for pixel buffer */
520 if ( BROOKTREE_ALLOC )
521 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
525 #endif /* FreeBSD or BSDi */
528 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
531 /* If this is a module, save the current contiguous memory */
532 #if defined(BKTR_FREEBSD_MODULE)
533 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
534 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
535 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
536 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
537 bktr_store_address(unit, BKTR_MEM_BUF, buf);
542 printf("%s: buffer size %d, addr %p\n",
543 bktr_name(bktr), (int)BROOKTREE_ALLOC,
544 (void *)(uintptr_t)vtophys(buf));
549 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
550 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
552 bktr->alloc_pages = 0;
556 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
557 METEOR_DEV0 | METEOR_RGB16;
558 bktr->dma_prog_loaded = FALSE;
561 bktr->frames = 1; /* one frame */
562 bktr->format = METEOR_GEO_RGB16;
563 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
564 bktr->pixfmt_compat = TRUE;
573 /* using the pci device id and revision id */
574 /* and determine the card type */
575 if (BKTR_PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
577 switch (BKTR_PCI_PRODUCT(pci_id)) {
578 case PCI_PRODUCT_BROOKTREE_BT848:
580 bktr->id = BROOKTREE_848A;
582 bktr->id = BROOKTREE_848;
584 case PCI_PRODUCT_BROOKTREE_BT849:
585 bktr->id = BROOKTREE_849A;
587 case PCI_PRODUCT_BROOKTREE_BT878:
588 bktr->id = BROOKTREE_878;
590 case PCI_PRODUCT_BROOKTREE_BT879:
591 bktr->id = BROOKTREE_879;
596 bktr->clr_on_start = FALSE;
598 /* defaults for the tuner section of the card */
599 bktr->tflags = TUNER_INITALIZED;
600 bktr->tuner.frequency = 0;
601 bktr->tuner.channel = 0;
602 bktr->tuner.chnlset = DEFAULT_CHNLSET;
604 bktr->tuner.radio_mode = 0;
605 bktr->audio_mux_select = 0;
606 bktr->audio_mute_state = FALSE;
607 bktr->bt848_card = -1;
608 bktr->bt848_tuner = -1;
609 bktr->reverse_mute = -1;
610 bktr->slow_msp_audio = 0;
611 bktr->msp_use_mono_source = 0;
612 bktr->msp_source_selected = -1;
613 bktr->audio_mux_present = 1;
615 #if defined(__FreeBSD__)
616 #ifdef BKTR_NEW_MSP34XX_DRIVER
617 /* get hint on short programming of the msp34xx, so we know */
618 /* if the decision what thread to start should be overwritten */
619 if ( (err = resource_int_value("bktr", unit, "mspsimple",
620 &(bktr->mspsimple)) ) != 0 )
621 bktr->mspsimple = -1; /* fall back to default */
625 probeCard( bktr, TRUE, unit );
627 /* Initialise any MSP34xx or TDA98xx audio chips */
628 init_audio_devices( bktr );
630 #ifdef BKTR_NEW_MSP34XX_DRIVER
631 /* setup the kernel thread */
632 err = msp_attach( bktr );
633 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
634 bktr->card.msp3400c = 0;
641 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
642 * The circular buffer holds 'n' fixed size data blocks.
643 * vbisize is the number of bytes in the circular buffer
644 * vbiread is the point we reading data out of the circular buffer
645 * vbiinsert is the point we insert data into the circular buffer
647 static void vbidecode(bktr_ptr_t bktr) {
649 unsigned int *seq_dest;
651 /* Check if there is room in the buffer to insert the data. */
652 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
654 /* Copy the VBI data into the next free slot in the buffer. */
655 /* 'dest' is the point in vbibuffer where we want to insert new data */
656 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
657 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
659 /* Write the VBI sequence number to the end of the vbi data */
660 /* This is used by the AleVT teletext program */
661 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
663 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
664 *seq_dest = bktr->vbi_sequence_number;
666 /* And increase the VBI sequence number */
667 /* This can wrap around */
668 bktr->vbi_sequence_number++;
671 /* Increment the vbiinsert pointer */
672 /* This can wrap around */
673 bktr->vbiinsert += VBI_DATA_SIZE;
674 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
676 /* And increase the amount of vbi data in the buffer */
677 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
683 * the common interrupt handler.
684 * Returns a 0 or 1 depending on whether the interrupt has handled.
685 * In the OS specific section, bktr_intr() is defined which calls this
686 * common interrupt handler.
689 common_bktr_intr( void *arg )
698 bktr = (bktr_ptr_t) arg;
701 * check to see if any interrupts are unmasked on this device. If
702 * none are, then we likely got here by way of being on a PCI shared
703 * interrupt dispatch list.
705 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
706 return 0; /* bail out now, before we do something we
709 if (!(bktr->flags & METEOR_OPEN)) {
710 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
711 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
715 /* record and clear the INTerrupt status bits */
716 bktr_status = INL(bktr, BKTR_INT_STAT);
717 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
719 /* record and clear the device status register */
720 dstatus = INB(bktr, BKTR_DSTATUS);
721 OUTB(bktr, BKTR_DSTATUS, 0x00);
723 #if defined( STATUS_SUM )
724 /* add any new device status or INTerrupt status bits */
725 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
726 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
727 #endif /* STATUS_SUM */
728 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
729 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
733 /* if risc was disabled re-start process again */
734 /* if there was one of the following errors re-start again */
735 if ( !(bktr_status & BT848_INT_RISC_EN) ||
736 ((bktr_status &(/* BT848_INT_FBUS | */
737 /* BT848_INT_FTRGT | */
738 /* BT848_INT_FDSR | */
740 BT848_INT_RIPERR | BT848_INT_PABORT |
741 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
742 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
744 u_short tdec_save = INB(bktr, BKTR_TDEC);
746 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
747 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
749 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
751 /* Reset temporal decimation counter */
752 OUTB(bktr, BKTR_TDEC, 0);
753 OUTB(bktr, BKTR_TDEC, tdec_save);
755 /* Reset to no-fields captured state */
756 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
757 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
758 case METEOR_ONLY_ODD_FIELDS:
759 bktr->flags |= METEOR_WANT_ODD;
761 case METEOR_ONLY_EVEN_FIELDS:
762 bktr->flags |= METEOR_WANT_EVEN;
765 bktr->flags |= METEOR_WANT_MASK;
770 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
771 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
772 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
774 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
779 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
783 /* If this is not a RISC program interrupt, return */
784 if (!(bktr_status & BT848_INT_RISCI))
788 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
789 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
794 * Disable future interrupts if a capture mode is not selected.
795 * This can happen when we are in the process of closing or
796 * changing capture modes, otherwise it shouldn't happen.
798 if (!(bktr->flags & METEOR_CAP_MASK))
799 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
802 /* Determine which field generated this interrupt */
803 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
807 * Process the VBI data if it is being captured. We do this once
808 * both Odd and Even VBI data is captured. Therefore we do this
809 * in the Even field interrupt handler.
812 if ( (bktr->vbiflags & VBI_CAPTURE)
813 &&(bktr->vbiflags & VBI_OPEN)
815 /* Put VBI data into circular buffer */
818 /* If someone is blocked on reading from /dev/vbi, wake them */
819 if (bktr->vbi_read_blocked) {
820 bktr->vbi_read_blocked = FALSE;
824 /* If someone has a select() on /dev/vbi, inform them */
825 if (SEL_WAITING(&bktr->vbi_select)) {
826 selwakeuppri(&bktr->vbi_select, VBIPRI);
834 * Register the completed field
835 * (For dual-field mode, require fields from the same frame)
837 switch ( bktr->flags & METEOR_WANT_MASK ) {
838 case METEOR_WANT_ODD : w_field = ODD_F ; break;
839 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
840 default : w_field = (ODD_F|EVEN_F); break;
842 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
843 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
844 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
845 default : req_field = (ODD_F|EVEN_F);
849 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
850 bktr->flags &= ~METEOR_WANT_EVEN;
851 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
852 ( w_field == ODD_F ))
853 bktr->flags &= ~METEOR_WANT_ODD;
854 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
855 ( w_field == (ODD_F|EVEN_F) ))
856 bktr->flags &= ~METEOR_WANT_ODD;
857 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
858 ( w_field == ODD_F )) {
859 bktr->flags &= ~METEOR_WANT_ODD;
860 bktr->flags |= METEOR_WANT_EVEN;
863 /* We're out of sync. Start over. */
864 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
865 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
866 case METEOR_ONLY_ODD_FIELDS:
867 bktr->flags |= METEOR_WANT_ODD;
869 case METEOR_ONLY_EVEN_FIELDS:
870 bktr->flags |= METEOR_WANT_EVEN;
873 bktr->flags |= METEOR_WANT_MASK;
881 * If we have a complete frame.
883 if (!(bktr->flags & METEOR_WANT_MASK)) {
884 bktr->frames_captured++;
886 * post the completion time.
888 if (bktr->flags & METEOR_WANT_TS) {
891 if ((u_int) bktr->alloc_pages * PAGE_SIZE
892 <= (bktr->frame_size + sizeof(struct timeval))) {
893 ts =(struct timeval *)bktr->bigbuf +
895 /* doesn't work in synch mode except
904 * Wake up the user in single capture mode.
906 if (bktr->flags & METEOR_SINGLE) {
909 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
911 /* disable risc, leave fifo running */
912 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
917 * If the user requested to be notified via signal,
918 * let them know the frame is complete.
921 if (bktr->proc != NULL) {
922 PROC_LOCK(bktr->proc);
923 kern_psignal( bktr->proc, bktr->signal);
924 PROC_UNLOCK(bktr->proc);
928 * Reset the want flags if in continuous or
929 * synchronous capture mode.
933 * currently we only support 3 capture modes: odd only, even only,
934 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
935 * either even OR odd) could provide 60 (50 for PAL) pictures per
936 * second, but it would require this routine to toggle the desired frame
937 * each time, and one more different DMA program for the Bt848.
938 * As a consequence, this fourth mode is currently unsupported.
941 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
942 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
943 case METEOR_ONLY_ODD_FIELDS:
944 bktr->flags |= METEOR_WANT_ODD;
946 case METEOR_ONLY_EVEN_FIELDS:
947 bktr->flags |= METEOR_WANT_EVEN;
950 bktr->flags |= METEOR_WANT_MASK;
965 extern int bt848_format; /* used to set the default format, PAL or NTSC */
967 video_open( bktr_ptr_t bktr )
969 int frame_rate, video_format=0;
971 if (bktr->flags & METEOR_OPEN) /* device is busy */
974 bktr->flags |= METEOR_OPEN;
980 bktr->clr_on_start = FALSE;
982 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
984 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
986 #if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
992 if (bt848_format == 0 )
995 if (bt848_format == 1 )
998 if (video_format == 1 ) {
999 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
1000 bktr->format_params = BT848_IFORM_F_NTSCM;
1003 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
1004 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1008 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
1010 /* work around for new Hauppauge 878 cards */
1011 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
1012 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
1013 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
1015 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
1017 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
1018 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
1019 frame_rate = format_params[bktr->format_params].frame_rate;
1021 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
1022 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
1023 OUTB(bktr, BKTR_TGCTRL, 0);
1024 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
1025 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
1026 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
1029 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1031 bktr->max_clip_node = 0;
1033 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
1035 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
1036 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
1038 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
1039 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
1040 OUTB(bktr, BKTR_E_SCLOOP, 0);
1041 OUTB(bktr, BKTR_O_SCLOOP, 0);
1043 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
1044 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
1046 bktr->fifo_errors = 0;
1047 bktr->dma_errors = 0;
1048 bktr->frames_captured = 0;
1049 bktr->even_fields_captured = 0;
1050 bktr->odd_fields_captured = 0;
1052 set_fps(bktr, frame_rate);
1053 bktr->video.addr = 0;
1054 bktr->video.width = 0;
1055 bktr->video.banksize = 0;
1056 bktr->video.ramsize = 0;
1057 bktr->pixfmt_compat = TRUE;
1058 bktr->format = METEOR_GEO_RGB16;
1059 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1061 bktr->capture_area_enabled = FALSE;
1063 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
1064 based motherboards will
1065 operate unreliably */
1070 vbi_open( bktr_ptr_t bktr )
1075 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
1080 bktr->vbiflags |= VBI_OPEN;
1082 /* reset the VBI circular buffer pointers and clear the buffers */
1083 bktr->vbiinsert = 0;
1086 bktr->vbi_sequence_number = 0;
1087 bktr->vbi_read_blocked = FALSE;
1089 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
1090 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
1101 tuner_open( bktr_ptr_t bktr )
1103 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1106 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1109 bktr->tflags |= TUNER_OPEN;
1110 bktr->tuner.frequency = 0;
1111 bktr->tuner.channel = 0;
1112 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1113 bktr->tuner.afc = 0;
1114 bktr->tuner.radio_mode = 0;
1116 /* enable drivers on the GPIO port that control the MUXes */
1117 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1119 /* unmute the audio stream */
1120 set_audio( bktr, AUDIO_UNMUTE );
1122 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1123 init_audio_devices( bktr );
1135 video_close( bktr_ptr_t bktr )
1137 bktr->flags &= ~(METEOR_OPEN |
1142 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1143 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1145 bktr->dma_prog_loaded = FALSE;
1146 OUTB(bktr, BKTR_TDEC, 0);
1147 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1149 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1150 OUTL(bktr, BKTR_SRESET, 0xf);
1151 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1158 * tuner close handle,
1159 * place holder for tuner specific operations on a close.
1162 tuner_close( bktr_ptr_t bktr )
1164 bktr->tflags &= ~TUNER_OPEN;
1166 /* mute the audio by switching the mux */
1167 set_audio( bktr, AUDIO_MUTE );
1169 /* disable drivers on the GPIO port that control the MUXes */
1170 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1176 vbi_close( bktr_ptr_t bktr )
1181 bktr->vbiflags &= ~VBI_OPEN;
1192 video_read(bktr_ptr_t bktr, int unit, struct cdev *dev, struct uio *uio)
1198 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1201 if (bktr->flags & METEOR_CAP_MASK)
1202 return( EIO ); /* already capturing */
1204 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1207 count = bktr->rows * bktr->cols *
1208 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1210 if ((int) uio->uio_iov->iov_len < count)
1213 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1215 /* capture one frame */
1216 start_capture(bktr, METEOR_SINGLE);
1217 /* wait for capture to complete */
1218 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1219 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1220 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1221 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1227 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1228 if (!status) /* successful capture */
1229 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1231 printf ("%s: read: tsleep error %d\n",
1232 bktr_name(bktr), status);
1234 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1240 * Read VBI data from the vbi circular buffer
1241 * The buffer holds vbi data blocks which are the same size
1242 * vbiinsert is the position we will insert the next item into the buffer
1243 * vbistart is the actual position in the buffer we want to read from
1244 * vbisize is the exact number of bytes in the buffer left to read
1247 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1249 int readsize, readsize2, start;
1253 * XXX - vbi_read() should be protected against being re-entered
1254 * while it is unlocked for the uiomove.
1258 while(bktr->vbisize == 0) {
1259 if (ioflag & FNDELAY) {
1260 status = EWOULDBLOCK;
1264 bktr->vbi_read_blocked = TRUE;
1266 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1271 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1277 /* Now we have some data to give to the user */
1279 /* We cannot read more bytes than there are in
1280 * the circular buffer
1282 readsize = (int)uio->uio_iov->iov_len;
1284 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1286 /* Check if we can read this number of bytes without having
1287 * to wrap around the circular buffer */
1288 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1289 /* We need to wrap around */
1291 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1292 start = bktr->vbistart;
1294 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1296 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1299 /* We do not need to wrap around */
1300 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1305 /* Update the number of bytes left to read */
1306 bktr->vbisize -= readsize;
1308 /* Update vbistart */
1309 bktr->vbistart += readsize;
1310 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1325 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1327 volatile u_char c_temp;
1329 unsigned int temp_iform;
1331 struct meteor_geomet *geo;
1332 struct meteor_counts *counts;
1333 struct meteor_video *video;
1334 struct bktr_capture_area *cap_area;
1342 case BT848SCLIP: /* set clip region */
1343 bktr->max_clip_node = 0;
1344 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1346 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1347 if (bktr->clip_list[i].y_min == 0 &&
1348 bktr->clip_list[i].y_max == 0)
1351 bktr->max_clip_node = i;
1353 /* make sure that the list contains a valid clip secquence */
1354 /* the clip rectangles should be sorted by x then by y as the
1355 second order sort key */
1357 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1359 /* to disable clipping set y_min and y_max to 0 in the first
1360 clip rectangle . The first clip rectangle is clip_list[0].
1365 if (bktr->max_clip_node == 0 &&
1366 (bktr->clip_list[0].y_min != 0 &&
1367 bktr->clip_list[0].y_max != 0)) {
1371 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1372 if (bktr->clip_list[i].y_min == 0 &&
1373 bktr->clip_list[i].y_max == 0) {
1376 if ( bktr->clip_list[i+1].y_min != 0 &&
1377 bktr->clip_list[i+1].y_max != 0 &&
1378 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1380 bktr->max_clip_node = 0;
1385 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1386 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1387 bktr->clip_list[i].x_min < 0 ||
1388 bktr->clip_list[i].x_max < 0 ||
1389 bktr->clip_list[i].y_min < 0 ||
1390 bktr->clip_list[i].y_max < 0 ) {
1391 bktr->max_clip_node = 0;
1396 bktr->dma_prog_loaded = FALSE;
1400 case METEORSTATUS: /* get Bt848 status */
1401 c_temp = INB(bktr, BKTR_DSTATUS);
1403 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1404 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1405 *(u_short *)arg = temp;
1408 case BT848SFMT: /* set input format */
1409 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1410 temp_iform = INB(bktr, BKTR_IFORM);
1411 temp_iform &= ~BT848_IFORM_FORMAT;
1412 temp_iform &= ~BT848_IFORM_XTSEL;
1413 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1415 case BT848_IFORM_F_AUTO:
1416 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1420 case BT848_IFORM_F_NTSCM:
1421 case BT848_IFORM_F_NTSCJ:
1422 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1424 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1425 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1426 bktr->format_params = temp;
1429 case BT848_IFORM_F_PALBDGHI:
1430 case BT848_IFORM_F_PALN:
1431 case BT848_IFORM_F_SECAM:
1432 case BT848_IFORM_F_RSVD:
1433 case BT848_IFORM_F_PALM:
1434 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1436 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1437 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1438 bktr->format_params = temp;
1442 bktr->dma_prog_loaded = FALSE;
1445 case METEORSFMT: /* set input format */
1446 temp_iform = INB(bktr, BKTR_IFORM);
1447 temp_iform &= ~BT848_IFORM_FORMAT;
1448 temp_iform &= ~BT848_IFORM_XTSEL;
1449 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1450 case 0: /* default */
1451 case METEOR_FMT_NTSC:
1452 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1454 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1455 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1456 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1457 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1458 bktr->format_params = BT848_IFORM_F_NTSCM;
1461 case METEOR_FMT_PAL:
1462 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1464 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1465 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1466 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1467 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1468 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1471 case METEOR_FMT_AUTOMODE:
1472 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1474 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1475 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1481 bktr->dma_prog_loaded = FALSE;
1484 case METEORGFMT: /* get input format */
1485 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1489 case BT848GFMT: /* get input format */
1490 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1493 case METEORSCOUNT: /* (re)set error counts */
1494 counts = (struct meteor_counts *) arg;
1495 bktr->fifo_errors = counts->fifo_errors;
1496 bktr->dma_errors = counts->dma_errors;
1497 bktr->frames_captured = counts->frames_captured;
1498 bktr->even_fields_captured = counts->even_fields_captured;
1499 bktr->odd_fields_captured = counts->odd_fields_captured;
1502 case METEORGCOUNT: /* get error counts */
1503 counts = (struct meteor_counts *) arg;
1504 counts->fifo_errors = bktr->fifo_errors;
1505 counts->dma_errors = bktr->dma_errors;
1506 counts->frames_captured = bktr->frames_captured;
1507 counts->even_fields_captured = bktr->even_fields_captured;
1508 counts->odd_fields_captured = bktr->odd_fields_captured;
1512 video = (struct meteor_video *)arg;
1513 video->addr = bktr->video.addr;
1514 video->width = bktr->video.width;
1515 video->banksize = bktr->video.banksize;
1516 video->ramsize = bktr->video.ramsize;
1520 video = (struct meteor_video *)arg;
1521 bktr->video.addr = video->addr;
1522 bktr->video.width = video->width;
1523 bktr->video.banksize = video->banksize;
1524 bktr->video.ramsize = video->ramsize;
1528 set_fps(bktr, *(u_short *)arg);
1532 *(u_short *)arg = bktr->fps;
1535 case METEORSHUE: /* set hue */
1536 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1539 case METEORGHUE: /* get hue */
1540 *(u_char *)arg = INB(bktr, BKTR_HUE);
1543 case METEORSBRIG: /* set brightness */
1544 char_temp = ( *(u_char *)arg & 0xff) - 128;
1545 OUTB(bktr, BKTR_BRIGHT, char_temp);
1549 case METEORGBRIG: /* get brightness */
1550 *(u_char *)arg = INB(bktr, BKTR_BRIGHT) + 128;
1553 case METEORSCSAT: /* set chroma saturation */
1554 temp = (int)*(u_char *)arg;
1556 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1557 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1558 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1559 & ~(BT848_E_CONTROL_SAT_U_MSB
1560 | BT848_E_CONTROL_SAT_V_MSB));
1561 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1562 & ~(BT848_O_CONTROL_SAT_U_MSB |
1563 BT848_O_CONTROL_SAT_V_MSB));
1565 if ( temp & BIT_SEVEN_HIGH ) {
1566 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1567 | (BT848_E_CONTROL_SAT_U_MSB
1568 | BT848_E_CONTROL_SAT_V_MSB));
1569 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1570 | (BT848_O_CONTROL_SAT_U_MSB
1571 | BT848_O_CONTROL_SAT_V_MSB));
1575 case METEORGCSAT: /* get chroma saturation */
1576 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1577 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1578 temp |= BIT_SEVEN_HIGH;
1579 *(u_char *)arg = (u_char)temp;
1582 case METEORSCONT: /* set contrast */
1583 temp = (int)*(u_char *)arg & 0xff;
1585 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1586 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1587 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1588 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1589 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1590 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1591 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1594 case METEORGCONT: /* get contrast */
1595 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1596 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1597 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1600 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1601 bktr->clr_on_start = (*(int *)arg != 0);
1604 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1605 *(int *)arg = (int) bktr->clr_on_start;
1610 /* Historically, applications used METEOR_SIG_MODE_MASK
1611 * to reset signal delivery.
1613 if (sig == METEOR_SIG_MODE_MASK)
1615 if (sig < 0 || sig > _SIG_MAXSIG)
1618 bktr->proc = sig ? td->td_proc : NULL;
1622 *(int *)arg = bktr->signal;
1627 switch (*(int *) arg) {
1628 case METEOR_CAP_SINGLE:
1630 if (bktr->bigbuf==0) /* no frame buffer allocated */
1632 /* already capturing */
1633 if (temp & METEOR_CAP_MASK)
1638 start_capture(bktr, METEOR_SINGLE);
1640 /* wait for capture to complete */
1641 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1642 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1643 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1645 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1650 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1651 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1652 if (error && (error != ERESTART)) {
1653 /* Here if we didn't get complete frame */
1655 printf( "%s: ioctl: tsleep error %d %x\n",
1656 bktr_name(bktr), error,
1657 INL(bktr, BKTR_RISC_COUNT));
1661 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1663 /* disable risc, leave fifo running */
1664 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1667 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1668 /* FIXME: should we set bt848->int_stat ??? */
1671 case METEOR_CAP_CONTINOUS:
1672 if (bktr->bigbuf==0) /* no frame buffer allocated */
1674 /* already capturing */
1675 if (temp & METEOR_CAP_MASK)
1679 start_capture(bktr, METEOR_CONTIN);
1681 /* Clear the interrypt status register */
1682 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1684 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1685 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1686 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1688 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1697 case METEOR_CAP_STOP_CONT:
1698 if (bktr->flags & METEOR_CONTIN) {
1699 /* turn off capture */
1700 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1701 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1702 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1704 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1711 /* can't change parameters while capturing */
1712 if (bktr->flags & METEOR_CAP_MASK)
1716 geo = (struct meteor_geomet *) arg;
1719 /* Either even or odd, if even & odd, then these a zero */
1720 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1721 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1722 printf( "%s: ioctl: Geometry odd or even only.\n",
1727 /* set/clear even/odd flags */
1728 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1729 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1731 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1732 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1733 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1735 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1737 if (geo->columns <= 0) {
1739 "%s: ioctl: %d: columns must be greater than zero.\n",
1740 bktr_name(bktr), geo->columns);
1743 else if ((geo->columns & 0x3fe) != geo->columns) {
1745 "%s: ioctl: %d: columns too large or not even.\n",
1746 bktr_name(bktr), geo->columns);
1750 if (geo->rows <= 0) {
1752 "%s: ioctl: %d: rows must be greater than zero.\n",
1753 bktr_name(bktr), geo->rows);
1756 else if (((geo->rows & 0x7fe) != geo->rows) ||
1757 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1758 ((geo->rows & 0x3fe) != geo->rows)) ) {
1760 "%s: ioctl: %d: rows too large or not even.\n",
1761 bktr_name(bktr), geo->rows);
1765 if (geo->frames > 32) {
1766 printf("%s: ioctl: too many frames.\n",
1775 bktr->dma_prog_loaded = FALSE;
1776 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1778 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1780 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1781 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1783 /* meteor_mem structure for SYNC Capture */
1784 if (geo->frames > 1) temp += PAGE_SIZE;
1787 if ((int) temp > bktr->alloc_pages
1788 && bktr->video.addr == 0) {
1790 /*****************************/
1791 /* *** OS Dependent code *** */
1792 /*****************************/
1793 #if defined(__NetBSD__) || defined(__OpenBSD__)
1794 bus_dmamap_t dmamap;
1796 buf = get_bktr_mem(bktr, &dmamap,
1799 free_bktr_mem(bktr, bktr->dm_mem,
1801 bktr->dm_mem = dmamap;
1804 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1807 (void *)(uintptr_t)bktr->bigbuf,
1808 (bktr->alloc_pages * PAGE_SIZE),
1813 bktr->alloc_pages = temp;
1815 printf("%s: ioctl: Allocating %d bytes\n",
1816 bktr_name(bktr), (int)(temp*PAGE_SIZE));
1826 bktr->rows = geo->rows;
1827 bktr->cols = geo->columns;
1828 bktr->frames = geo->frames;
1830 /* Pixel format (if in meteor pixfmt compatibility mode) */
1831 if ( bktr->pixfmt_compat ) {
1832 bktr->format = METEOR_GEO_YUV_422;
1833 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1834 case 0: /* default */
1835 case METEOR_GEO_RGB16:
1836 bktr->format = METEOR_GEO_RGB16;
1838 case METEOR_GEO_RGB24:
1839 bktr->format = METEOR_GEO_RGB24;
1841 case METEOR_GEO_YUV_422:
1842 bktr->format = METEOR_GEO_YUV_422;
1843 if (geo->oformat & METEOR_GEO_YUV_12)
1844 bktr->format = METEOR_GEO_YUV_12;
1846 case METEOR_GEO_YUV_PACKED:
1847 bktr->format = METEOR_GEO_YUV_PACKED;
1850 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1853 if (bktr->flags & METEOR_CAP_MASK) {
1855 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1856 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1857 case METEOR_ONLY_ODD_FIELDS:
1858 bktr->flags |= METEOR_WANT_ODD;
1860 case METEOR_ONLY_EVEN_FIELDS:
1861 bktr->flags |= METEOR_WANT_EVEN;
1864 bktr->flags |= METEOR_WANT_MASK;
1868 start_capture(bktr, METEOR_CONTIN);
1869 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1870 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1871 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1872 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1878 /* end of METEORSETGEO */
1880 /* FIXME. The Capture Area currently has the following restrictions:
1882 y_offset may need to be even in interlaced modes
1883 RGB24 - Interlaced mode
1884 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1885 y_size must be greater than or equal to METEORSETGEO height (rows)
1886 RGB24 - Even Only (or Odd Only) mode
1887 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1888 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1889 YUV12 - Interlaced mode
1890 x_size must be greater than or equal to METEORSETGEO width (cols)
1891 y_size must be greater than or equal to METEORSETGEO height (rows)
1892 YUV12 - Even Only (or Odd Only) mode
1893 x_size must be greater than or equal to METEORSETGEO width (cols)
1894 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1897 case BT848_SCAPAREA: /* set capture area of each video frame */
1898 /* can't change parameters while capturing */
1899 if (bktr->flags & METEOR_CAP_MASK)
1902 cap_area = (struct bktr_capture_area *) arg;
1903 bktr->capture_area_x_offset = cap_area->x_offset;
1904 bktr->capture_area_y_offset = cap_area->y_offset;
1905 bktr->capture_area_x_size = cap_area->x_size;
1906 bktr->capture_area_y_size = cap_area->y_size;
1907 bktr->capture_area_enabled = TRUE;
1909 bktr->dma_prog_loaded = FALSE;
1912 case BT848_GCAPAREA: /* get capture area of each video frame */
1913 cap_area = (struct bktr_capture_area *) arg;
1914 if (bktr->capture_area_enabled == FALSE) {
1915 cap_area->x_offset = 0;
1916 cap_area->y_offset = 0;
1917 cap_area->x_size = format_params[
1918 bktr->format_params].scaled_hactive;
1919 cap_area->y_size = format_params[
1920 bktr->format_params].vactive;
1922 cap_area->x_offset = bktr->capture_area_x_offset;
1923 cap_area->y_offset = bktr->capture_area_y_offset;
1924 cap_area->x_size = bktr->capture_area_x_size;
1925 cap_area->y_size = bktr->capture_area_y_size;
1930 return common_ioctl( bktr, cmd, arg );
1940 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1956 /* Read the last key pressed by the Remote Control */
1957 if (bktr->remote_control == 0) return (EINVAL);
1958 remote_read(bktr, (struct bktr_remote *)arg);
1961 #if defined( TUNER_AFC )
1962 case TVTUNER_SETAFC:
1963 bktr->tuner.afc = (*(int *)arg != 0);
1966 case TVTUNER_GETAFC:
1967 *(int *)arg = bktr->tuner.afc;
1968 /* XXX Perhaps use another bit to indicate AFC success? */
1970 #endif /* TUNER_AFC */
1972 case TVTUNER_SETCHNL:
1973 temp_mute( bktr, TRUE );
1974 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1976 temp_mute( bktr, FALSE );
1979 *(unsigned long *)arg = temp;
1981 /* after every channel change, we must restart the MSP34xx */
1982 /* audio chip to reselect NICAM STEREO or MONO audio */
1983 if ( bktr->card.msp3400c )
1984 msp_autodetect( bktr );
1986 /* after every channel change, we must restart the DPL35xx */
1987 if ( bktr->card.dpl3518a )
1988 dpl_autodetect( bktr );
1990 temp_mute( bktr, FALSE );
1993 case TVTUNER_GETCHNL:
1994 *(unsigned long *)arg = bktr->tuner.channel;
1997 case TVTUNER_SETTYPE:
1998 temp = *(unsigned long *)arg;
1999 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
2001 bktr->tuner.chnlset = temp;
2004 case TVTUNER_GETTYPE:
2005 *(unsigned long *)arg = bktr->tuner.chnlset;
2008 case TVTUNER_GETSTATUS:
2009 temp = get_tuner_status( bktr );
2010 *(unsigned long *)arg = temp & 0xff;
2013 case TVTUNER_SETFREQ:
2014 temp_mute( bktr, TRUE );
2015 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
2016 temp_mute( bktr, FALSE );
2018 temp_mute( bktr, FALSE );
2021 *(unsigned long *)arg = temp;
2023 /* after every channel change, we must restart the MSP34xx */
2024 /* audio chip to reselect NICAM STEREO or MONO audio */
2025 if ( bktr->card.msp3400c )
2026 msp_autodetect( bktr );
2028 /* after every channel change, we must restart the DPL35xx */
2029 if ( bktr->card.dpl3518a )
2030 dpl_autodetect( bktr );
2032 temp_mute( bktr, FALSE );
2035 case TVTUNER_GETFREQ:
2036 *(unsigned long *)arg = bktr->tuner.frequency;
2039 case TVTUNER_GETCHNLSET:
2040 return tuner_getchnlset((struct bktr_chnlset *)arg);
2042 case BT848_SAUDIO: /* set audio channel */
2043 if ( set_audio( bktr, *(int*)arg ) < 0 )
2047 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
2048 case BT848_SHUE: /* set hue */
2049 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
2052 case BT848_GHUE: /* get hue */
2053 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
2056 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
2057 case BT848_SBRIG: /* set brightness */
2058 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
2061 case BT848_GBRIG: /* get brightness */
2062 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2066 case BT848_SCSAT: /* set chroma saturation */
2067 tmp_int = *(int*)arg;
2069 temp = INB(bktr, BKTR_E_CONTROL);
2070 temp1 = INB(bktr, BKTR_O_CONTROL);
2071 if ( tmp_int & BIT_EIGHT_HIGH ) {
2072 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2073 BT848_E_CONTROL_SAT_V_MSB);
2074 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2075 BT848_O_CONTROL_SAT_V_MSB);
2078 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2079 BT848_E_CONTROL_SAT_V_MSB);
2080 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2081 BT848_O_CONTROL_SAT_V_MSB);
2084 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2085 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2086 OUTB(bktr, BKTR_E_CONTROL, temp);
2087 OUTB(bktr, BKTR_O_CONTROL, temp1);
2090 case BT848_GCSAT: /* get chroma saturation */
2091 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2092 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2093 tmp_int |= BIT_EIGHT_HIGH;
2094 *(int*)arg = tmp_int;
2098 case BT848_SVSAT: /* set chroma V saturation */
2099 tmp_int = *(int*)arg;
2101 temp = INB(bktr, BKTR_E_CONTROL);
2102 temp1 = INB(bktr, BKTR_O_CONTROL);
2103 if ( tmp_int & BIT_EIGHT_HIGH) {
2104 temp |= BT848_E_CONTROL_SAT_V_MSB;
2105 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2108 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2109 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2112 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2113 OUTB(bktr, BKTR_E_CONTROL, temp);
2114 OUTB(bktr, BKTR_O_CONTROL, temp1);
2117 case BT848_GVSAT: /* get chroma V saturation */
2118 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2119 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2120 tmp_int |= BIT_EIGHT_HIGH;
2121 *(int*)arg = tmp_int;
2125 case BT848_SUSAT: /* set chroma U saturation */
2126 tmp_int = *(int*)arg;
2128 temp = INB(bktr, BKTR_E_CONTROL);
2129 temp1 = INB(bktr, BKTR_O_CONTROL);
2130 if ( tmp_int & BIT_EIGHT_HIGH ) {
2131 temp |= BT848_E_CONTROL_SAT_U_MSB;
2132 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2135 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2136 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2139 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2140 OUTB(bktr, BKTR_E_CONTROL, temp);
2141 OUTB(bktr, BKTR_O_CONTROL, temp1);
2144 case BT848_GUSAT: /* get chroma U saturation */
2145 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2146 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2147 tmp_int |= BIT_EIGHT_HIGH;
2148 *(int*)arg = tmp_int;
2151 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2153 case BT848_SLNOTCH: /* set luma notch */
2154 tmp_int = (*(int *)arg & 0x7) << 5 ;
2155 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2156 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2157 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2158 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2161 case BT848_GLNOTCH: /* get luma notch */
2162 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2167 case BT848_SCONT: /* set contrast */
2168 tmp_int = *(int*)arg;
2170 temp = INB(bktr, BKTR_E_CONTROL);
2171 temp1 = INB(bktr, BKTR_O_CONTROL);
2172 if ( tmp_int & BIT_EIGHT_HIGH ) {
2173 temp |= BT848_E_CONTROL_CON_MSB;
2174 temp1 |= BT848_O_CONTROL_CON_MSB;
2177 temp &= ~BT848_E_CONTROL_CON_MSB;
2178 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2181 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2182 OUTB(bktr, BKTR_E_CONTROL, temp);
2183 OUTB(bktr, BKTR_O_CONTROL, temp1);
2186 case BT848_GCONT: /* get contrast */
2187 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2188 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2189 tmp_int |= BIT_EIGHT_HIGH;
2190 *(int*)arg = tmp_int;
2193 /* FIXME: SCBARS and CCBARS require a valid int * */
2194 /* argument to succeed, but its not used; consider */
2195 /* using the arg to store the on/off state so */
2196 /* there's only one ioctl() needed to turn cbars on/off */
2197 case BT848_SCBARS: /* set colorbar output */
2198 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2201 case BT848_CCBARS: /* clear colorbar output */
2202 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2205 case BT848_GAUDIO: /* get audio channel */
2206 temp = bktr->audio_mux_select;
2207 if ( bktr->audio_mute_state == TRUE )
2212 case BT848_SBTSC: /* set audio channel */
2213 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2217 case BT848_WEEPROM: /* write eeprom */
2218 offset = (((struct eeProm *)arg)->offset);
2219 count = (((struct eeProm *)arg)->count);
2220 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2221 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2225 case BT848_REEPROM: /* read eeprom */
2226 offset = (((struct eeProm *)arg)->offset);
2227 count = (((struct eeProm *)arg)->count);
2228 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2229 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2233 case BT848_SIGNATURE:
2234 offset = (((struct eeProm *)arg)->offset);
2235 count = (((struct eeProm *)arg)->count);
2236 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2237 if ( signCard( bktr, offset, count, buf ) < 0 )
2241 /* Ioctl's for direct gpio access */
2242 #ifdef BKTR_GPIO_ACCESS
2243 case BT848_GPIO_GET_EN:
2244 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2247 case BT848_GPIO_SET_EN:
2248 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2251 case BT848_GPIO_GET_DATA:
2252 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2255 case BT848_GPIO_SET_DATA:
2256 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2258 #endif /* BKTR_GPIO_ACCESS */
2260 /* Ioctl's for running the tuner device in radio mode */
2263 *(unsigned char *)arg = bktr->tuner.radio_mode;
2267 bktr->tuner.radio_mode = *(unsigned char *)arg;
2271 *(unsigned long *)arg = bktr->tuner.frequency;
2275 /* The argument to this ioctl is NOT freq*16. It is
2279 temp=(int)*(unsigned long *)arg;
2281 #ifdef BKTR_RADIO_DEBUG
2282 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2283 (int)*(unsigned long *)arg, temp);
2286 #ifndef BKTR_RADIO_NOFREQCHECK
2287 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2289 if(temp<8750 || temp>10800) {
2290 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2294 temp_mute( bktr, TRUE );
2295 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2296 temp_mute( bktr, FALSE );
2297 #ifdef BKTR_RADIO_DEBUG
2299 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2303 *(unsigned long *)arg = temp;
2306 /* Luigi's I2CWR ioctl */
2308 par = *(u_long *)arg;
2309 write = (par >> 24) & 0xff ;
2310 i2c_addr = (par >> 16) & 0xff ;
2311 i2c_port = (par >> 8) & 0xff ;
2312 data = (par) & 0xff ;
2315 i2cWrite( bktr, i2c_addr, i2c_port, data);
2317 data = i2cRead( bktr, i2c_addr);
2319 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2323 #ifdef BT848_MSP_READ
2324 /* I2C ioctls to allow userland access to the MSP chip */
2325 case BT848_MSP_READ:
2327 struct bktr_msp_control *msp;
2328 msp = (struct bktr_msp_control *) arg;
2329 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2330 msp->function, msp->address);
2334 case BT848_MSP_WRITE:
2336 struct bktr_msp_control *msp;
2337 msp = (struct bktr_msp_control *) arg;
2338 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2339 msp->address, msp->data );
2343 case BT848_MSP_RESET:
2344 msp_dpl_reset(bktr, bktr->msp_addr);
2349 return common_ioctl( bktr, cmd, arg );
2360 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2364 struct meteor_pixfmt *pf_pub;
2368 case METEORSINPUT: /* set input device */
2369 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2370 /* On the original bt848 boards, */
2371 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2372 /* On the Hauppauge bt878 boards, */
2373 /* Tuner is MUX0, RCA is MUX3 */
2374 /* Unfortunately Meteor driver codes DEV_RCA as DEV_0, so we */
2375 /* stick with this system in our Meteor Emulation */
2377 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2379 /* this is the RCA video input */
2380 case 0: /* default */
2381 case METEOR_INPUT_DEV0:
2382 /* METEOR_INPUT_DEV_RCA: */
2383 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2385 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2386 & ~BT848_IFORM_MUXSEL);
2388 /* work around for new Hauppauge 878 cards */
2389 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2390 (bktr->id==BROOKTREE_878 ||
2391 bktr->id==BROOKTREE_879) )
2392 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2394 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2396 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2397 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2398 set_audio( bktr, AUDIO_EXTERN );
2401 /* this is the tuner input */
2402 case METEOR_INPUT_DEV1:
2403 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2405 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2406 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2407 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2408 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2409 set_audio( bktr, AUDIO_TUNER );
2412 /* this is the S-VHS input, but with a composite camera */
2413 case METEOR_INPUT_DEV2:
2414 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2416 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2417 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2418 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2419 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2420 set_audio( bktr, AUDIO_EXTERN );
2423 /* this is the S-VHS input */
2424 case METEOR_INPUT_DEV_SVIDEO:
2425 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2426 | METEOR_DEV_SVIDEO;
2427 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2428 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2429 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2430 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2431 set_audio( bktr, AUDIO_EXTERN );
2434 case METEOR_INPUT_DEV3:
2435 if ((bktr->id == BROOKTREE_848A) ||
2436 (bktr->id == BROOKTREE_849A) ||
2437 (bktr->id == BROOKTREE_878) ||
2438 (bktr->id == BROOKTREE_879) ) {
2439 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2441 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2443 /* work around for new Hauppauge 878 cards */
2444 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2445 (bktr->id==BROOKTREE_878 ||
2446 bktr->id==BROOKTREE_879) )
2447 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2449 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2451 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2452 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2453 set_audio( bktr, AUDIO_EXTERN );
2463 case METEORGINPUT: /* get input device */
2464 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2467 case METEORSACTPIXFMT:
2468 if (( *(int *)arg < 0 ) ||
2469 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2472 bktr->pixfmt = *(int *)arg;
2473 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2474 | pixfmt_swap_flags( bktr->pixfmt ));
2475 bktr->pixfmt_compat = FALSE;
2478 case METEORGACTPIXFMT:
2479 *(int *)arg = bktr->pixfmt;
2482 case METEORGSUPPIXFMT :
2483 pf_pub = (struct meteor_pixfmt *)arg;
2484 pixfmt = pf_pub->index;
2486 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2489 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2490 sizeof( *pf_pub ) );
2492 /* Patch in our format index */
2493 pf_pub->index = pixfmt;
2496 #if defined( STATUS_SUM )
2497 case BT848_GSTATUS: /* reap status */
2499 DECLARE_INTR_MASK(s);
2504 *(u_int*)arg = temp;
2507 #endif /* STATUS_SUM */
2519 /******************************************************************************
2520 * bt848 RISC programming routines:
2527 #if defined(BT848_DEBUG) || defined(BT848_DUMP)
2529 dump_bt848( bktr_ptr_t bktr )
2532 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2533 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2534 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2535 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2536 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2541 for (i = 0; i < 40; i+=4) {
2542 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2544 r[i], INL(bktr, r[i]),
2545 r[i+1], INL(bktr, r[i+1]),
2546 r[i+2], INL(bktr, r[i+2]),
2547 r[i+3], INL(bktr, r[i+3]));
2550 printf("%s: INT STAT %x \n", bktr_name(bktr),
2551 INL(bktr, BKTR_INT_STAT));
2552 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2553 INL(bktr, BKTR_INT_MASK));
2554 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2555 INW(bktr, BKTR_GPIO_DMA_CTL));
2563 * build write instruction
2565 #define BKTR_FM1 0x6 /* packed data to follow */
2566 #define BKTR_FM3 0xe /* planar data to follow */
2567 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2568 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2569 #define BKTR_PXV 0x0 /* valid word (never used) */
2570 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2571 #define BKTR_SOL 0x2 /* first dword */
2573 #define OP_WRITE (0x1 << 28)
2574 #define OP_SKIP (0x2 << 28)
2575 #define OP_WRITEC (0x5 << 28)
2576 #define OP_JUMP (0x7 << 28)
2577 #define OP_SYNC (0x8 << 28)
2578 #define OP_WRITE123 (0x9 << 28)
2579 #define OP_WRITES123 (0xb << 28)
2580 #define OP_SOL (1 << 27) /* first instr for scanline */
2581 #define OP_EOL (1 << 26)
2583 #define BKTR_RESYNC (1 << 15)
2584 #define BKTR_GEN_IRQ (1 << 24)
2587 * The RISC status bits can be set/cleared in the RISC programs
2588 * and tested in the Interrupt Handler
2590 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2591 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2592 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2593 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2595 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2596 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2597 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2598 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2600 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2601 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2602 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2603 #define BKTR_TEST_RISC_STATUS_BIT3 (1U << 31)
2605 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2607 bktr_clip_t * clip_node;
2608 bktr->clip_start = -1;
2612 bktr->line_length = width;
2615 bktr->current_col = 0;
2617 if (bktr->max_clip_node == 0 ) return TRUE;
2618 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2621 for (i = 0; i < bktr->max_clip_node; i++ ) {
2622 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2623 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2624 bktr->clip_start = i;
2632 static bool_t getline(bktr_reg_t *bktr, int x ) {
2634 bktr_clip_t * clip_node ;
2636 if (bktr->line_length == 0 ||
2637 bktr->current_col >= bktr->line_length) return FALSE;
2639 bktr->y = min(bktr->last_y, bktr->line_length);
2640 bktr->y2 = bktr->line_length;
2642 bktr->yclip = bktr->yclip2 = -1;
2643 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2644 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2645 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2646 if (bktr->last_y <= clip_node->y_min) {
2647 bktr->y = min(bktr->last_y, bktr->line_length);
2648 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2649 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2650 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2651 bktr->last_y = bktr->yclip2;
2652 bktr->clip_start = i;
2654 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2655 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2656 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2657 if (bktr->last_y >= clip_node->y_min) {
2658 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2659 bktr->last_y = bktr->yclip2;
2660 bktr->clip_start = j;
2669 if (bktr->current_col <= bktr->line_length) {
2670 bktr->current_col = bktr->line_length;
2676 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2677 u_long operation, int pixel_width,
2678 volatile u_char ** target_buffer, int cols ) {
2681 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2682 u_int skip, start_skip;
2684 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2685 /* to the 1st byte in the mem dword containing our start addr. */
2686 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2689 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2690 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2691 case 2 : start_skip = 4 ; break;
2692 case 1 : start_skip = 8 ; break;
2695 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2696 if ( width == cols) {
2697 flag = OP_SOL | OP_EOL;
2698 } else if (bktr->current_col == 0 ) {
2700 } else if (bktr->current_col == cols) {
2705 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2706 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2711 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2712 if (operation != OP_SKIP )
2713 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2715 *target_buffer += width * pixel_width;
2716 bktr->current_col += width;
2720 if (bktr->current_col == 0 && width == cols) {
2723 } else if (bktr->current_col == 0 ) {
2726 } else if (bktr->current_col >= cols) {
2735 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2736 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2741 *(*dma_prog)++ = operation | flag |
2742 (width * pixel_width / 2 - skip);
2743 if (operation != OP_SKIP )
2744 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2745 *target_buffer += (width * pixel_width / 2) ;
2747 if ( operation == OP_WRITE )
2748 operation = OP_WRITEC;
2749 *(*dma_prog)++ = operation | flag2 |
2750 (width * pixel_width / 2);
2751 *target_buffer += (width * pixel_width / 2) ;
2752 bktr->current_col += width;
2760 * Generate the RISC instructions to capture both VBI and video images
2763 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2766 volatile uint32_t target_buffer, buffer, target,width;
2767 volatile uint32_t pitch;
2768 volatile uint32_t *dma_prog; /* DMA prog is an array of
2769 32 bit RISC instructions */
2770 volatile uint32_t *loop_point;
2771 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2772 u_int Bpp = pf_int->public.Bpp;
2773 unsigned int vbisamples; /* VBI samples per line */
2774 unsigned int vbilines; /* VBI lines per field */
2775 unsigned int num_dwords; /* DWORDS per line */
2777 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2778 vbilines = format_params[bktr->format_params].vbi_num_lines;
2779 num_dwords = vbisamples/4;
2781 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2782 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2783 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2784 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2787 OUTB(bktr, BKTR_OFORM, 0x00);
2789 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2790 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2791 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2792 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2794 /* disable gamma correction removal */
2795 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2798 OUTB(bktr, BKTR_E_VTC, 0);
2799 OUTB(bktr, BKTR_O_VTC, 0);
2801 OUTB(bktr, BKTR_E_VTC, 1);
2802 OUTB(bktr, BKTR_O_VTC, 1);
2804 bktr->capcontrol = 3 << 2 | 3;
2806 dma_prog = (uint32_t *) bktr->dma_prog;
2808 /* Construct Write */
2810 if (bktr->video.addr) {
2811 target_buffer = (u_long) bktr->video.addr;
2812 pitch = bktr->video.width;
2815 target_buffer = (u_long) vtophys(bktr->bigbuf);
2819 buffer = target_buffer;
2821 /* Wait for the VRE sync marking the end of the Even and
2822 * the start of the Odd field. Resync here.
2824 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2827 loop_point = dma_prog;
2829 /* store the VBI data */
2830 /* look for sync with packed data */
2831 *dma_prog++ = OP_SYNC | BKTR_FM1;
2833 for(i = 0; i < vbilines; i++) {
2834 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2835 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2836 (i * VBI_LINE_SIZE));
2839 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2840 /* store the Odd field video image */
2841 /* look for sync with packed data */
2842 *dma_prog++ = OP_SYNC | BKTR_FM1;
2843 *dma_prog++ = 0; /* NULL WORD */
2845 for (i = 0; i < (rows/interlace); i++) {
2846 target = target_buffer;
2847 if ( notclipped(bktr, i, width)) {
2848 split(bktr, (volatile uint32_t **) &dma_prog,
2849 bktr->y2 - bktr->y, OP_WRITE,
2850 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2853 while(getline(bktr, i)) {
2854 if (bktr->y != bktr->y2 ) {
2855 split(bktr, (volatile uint32_t **) &dma_prog,
2856 bktr->y2 - bktr->y, OP_WRITE,
2857 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2859 if (bktr->yclip != bktr->yclip2 ) {
2860 split(bktr,(volatile uint32_t **) &dma_prog,
2861 bktr->yclip2 - bktr->yclip,
2863 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2869 target_buffer += interlace * pitch;
2875 /* Grab the Even field */
2876 /* Look for the VRO, end of Odd field, marker */
2877 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2878 *dma_prog++ = 0; /* NULL WORD */
2880 /* store the VBI data */
2881 /* look for sync with packed data */
2882 *dma_prog++ = OP_SYNC | BKTR_FM1;
2884 for(i = 0; i < vbilines; i++) {
2885 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2886 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2887 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2890 /* store the video image */
2891 if (i_flag == 1) /*Even Only*/
2892 target_buffer = buffer;
2893 if (i_flag == 3) /*interlaced*/
2894 target_buffer = buffer+pitch;
2897 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2898 /* look for sync with packed data */
2899 *dma_prog++ = OP_SYNC | BKTR_FM1;
2900 *dma_prog++ = 0; /* NULL WORD */
2902 for (i = 0; i < (rows/interlace); i++) {
2903 target = target_buffer;
2904 if ( notclipped(bktr, i, width)) {
2905 split(bktr, (volatile uint32_t **) &dma_prog,
2906 bktr->y2 - bktr->y, OP_WRITE,
2907 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2909 while(getline(bktr, i)) {
2910 if (bktr->y != bktr->y2 ) {
2911 split(bktr, (volatile uint32_t **) &dma_prog,
2912 bktr->y2 - bktr->y, OP_WRITE,
2913 Bpp, (volatile u_char **)(uintptr_t)&target,
2916 if (bktr->yclip != bktr->yclip2 ) {
2917 split(bktr, (volatile uint32_t **) &dma_prog,
2918 bktr->yclip2 - bktr->yclip, OP_SKIP,
2919 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2926 target_buffer += interlace * pitch;
2931 /* Look for end of 'Even Field' */
2932 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2933 *dma_prog++ = 0; /* NULL WORD */
2935 *dma_prog++ = OP_JUMP ;
2936 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2937 *dma_prog++ = 0; /* NULL WORD */
2945 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2948 volatile uint32_t target_buffer, buffer, target,width;
2949 volatile uint32_t pitch;
2950 volatile uint32_t *dma_prog;
2951 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2952 u_int Bpp = pf_int->public.Bpp;
2954 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2955 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2956 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2957 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2959 OUTB(bktr, BKTR_OFORM, 0x00);
2961 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2962 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2963 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2964 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2966 /* disable gamma correction removal */
2967 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2970 OUTB(bktr, BKTR_E_VTC, 0);
2971 OUTB(bktr, BKTR_O_VTC, 0);
2973 OUTB(bktr, BKTR_E_VTC, 1);
2974 OUTB(bktr, BKTR_O_VTC, 1);
2976 bktr->capcontrol = 3 << 2 | 3;
2978 dma_prog = (uint32_t *) bktr->dma_prog;
2980 /* Construct Write */
2982 if (bktr->video.addr) {
2983 target_buffer = (uint32_t) bktr->video.addr;
2984 pitch = bktr->video.width;
2987 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2991 buffer = target_buffer;
2993 /* contruct sync : for video packet format */
2994 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2996 /* sync, mode indicator packed data */
2997 *dma_prog++ = 0; /* NULL WORD */
2999 for (i = 0; i < (rows/interlace); i++) {
3000 target = target_buffer;
3001 if ( notclipped(bktr, i, width)) {
3002 split(bktr, (volatile uint32_t **) &dma_prog,
3003 bktr->y2 - bktr->y, OP_WRITE,
3004 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3007 while(getline(bktr, i)) {
3008 if (bktr->y != bktr->y2 ) {
3009 split(bktr, (volatile uint32_t **) &dma_prog,
3010 bktr->y2 - bktr->y, OP_WRITE,
3011 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3013 if (bktr->yclip != bktr->yclip2 ) {
3014 split(bktr,(volatile uint32_t **) &dma_prog,
3015 bktr->yclip2 - bktr->yclip,
3017 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3023 target_buffer += interlace * pitch;
3030 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3031 *dma_prog++ = 0; /* NULL WORD */
3033 *dma_prog++ = OP_JUMP;
3034 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
3039 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3040 *dma_prog++ = 0; /* NULL WORD */
3042 *dma_prog++ = OP_JUMP;
3043 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
3048 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3049 *dma_prog++ = 0; /* NULL WORD */
3050 *dma_prog++ = OP_JUMP;
3051 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
3055 if (interlace == 2) {
3057 target_buffer = buffer + pitch;
3059 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3061 /* sync vre IRQ bit */
3062 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3063 *dma_prog++ = 0; /* NULL WORD */
3065 for (i = 0; i < (rows/interlace); i++) {
3066 target = target_buffer;
3067 if ( notclipped(bktr, i, width)) {
3068 split(bktr, (volatile uint32_t **) &dma_prog,
3069 bktr->y2 - bktr->y, OP_WRITE,
3070 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3072 while(getline(bktr, i)) {
3073 if (bktr->y != bktr->y2 ) {
3074 split(bktr, (volatile uint32_t **) &dma_prog,
3075 bktr->y2 - bktr->y, OP_WRITE,
3076 Bpp, (volatile u_char **)(uintptr_t)&target,
3079 if (bktr->yclip != bktr->yclip2 ) {
3080 split(bktr, (volatile uint32_t **) &dma_prog,
3081 bktr->yclip2 - bktr->yclip, OP_SKIP,
3082 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3089 target_buffer += interlace * pitch;
3094 /* sync vre IRQ bit */
3095 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3096 *dma_prog++ = 0; /* NULL WORD */
3097 *dma_prog++ = OP_JUMP ;
3098 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
3099 *dma_prog++ = 0; /* NULL WORD */
3107 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3108 int cols, int rows, int interlace )
3111 volatile unsigned int inst;
3112 volatile unsigned int inst3;
3113 volatile uint32_t target_buffer, buffer;
3114 volatile uint32_t *dma_prog;
3115 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3118 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3120 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3121 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3123 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3124 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3126 bktr->capcontrol = 3 << 2 | 3;
3128 dma_prog = (uint32_t *) bktr->dma_prog;
3130 /* Construct Write */
3132 /* write , sol, eol */
3133 inst = OP_WRITE | OP_SOL | (cols);
3134 /* write , sol, eol */
3135 inst3 = OP_WRITE | OP_EOL | (cols);
3137 if (bktr->video.addr)
3138 target_buffer = (uint32_t) bktr->video.addr;
3140 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3142 buffer = target_buffer;
3144 /* contruct sync : for video packet format */
3145 /* sync, mode indicator packed data */
3146 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3147 *dma_prog++ = 0; /* NULL WORD */
3151 for (i = 0; i < (rows/interlace); i++) {
3153 *dma_prog++ = target_buffer;
3154 *dma_prog++ = inst3;
3155 *dma_prog++ = target_buffer + b;
3156 target_buffer += interlace*(cols * 2);
3162 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3163 *dma_prog++ = 0; /* NULL WORD */
3165 *dma_prog++ = OP_JUMP;
3166 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3171 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3172 *dma_prog++ = 0; /* NULL WORD */
3173 *dma_prog++ = OP_JUMP;
3174 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3179 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3180 *dma_prog++ = 0; /* NULL WORD */
3181 *dma_prog++ = OP_JUMP ;
3182 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3186 if (interlace == 2) {
3188 target_buffer = (uint32_t) buffer + cols*2;
3190 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3193 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3194 *dma_prog++ = 0; /* NULL WORD */
3196 for (i = 0; i < (rows/interlace) ; i++) {
3198 *dma_prog++ = target_buffer;
3199 *dma_prog++ = inst3;
3200 *dma_prog++ = target_buffer + b;
3201 target_buffer += interlace * ( cols*2);
3205 /* sync vro IRQ bit */
3206 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3207 *dma_prog++ = 0; /* NULL WORD */
3208 *dma_prog++ = OP_JUMP ;
3209 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3211 *dma_prog++ = OP_JUMP;
3212 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3213 *dma_prog++ = 0; /* NULL WORD */
3221 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3222 int cols, int rows, int interlace ){
3225 volatile unsigned int inst;
3226 volatile uint32_t target_buffer, t1, buffer;
3227 volatile uint32_t *dma_prog;
3228 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3230 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3232 dma_prog = (uint32_t*) bktr->dma_prog;
3234 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3236 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3237 OUTB(bktr, BKTR_OFORM, 0x00);
3239 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3240 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3242 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3243 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3245 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3246 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3247 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3248 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3250 /* disable gamma correction removal */
3251 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3253 /* Construct Write */
3254 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3255 if (bktr->video.addr)
3256 target_buffer = (uint32_t) bktr->video.addr;
3258 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3260 buffer = target_buffer;
3264 /* contruct sync : for video packet format */
3265 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3266 *dma_prog++ = 0; /* NULL WORD */
3268 for (i = 0; i < (rows/interlace ) ; i++) {
3270 *dma_prog++ = cols/2 | cols/2 << 16;
3271 *dma_prog++ = target_buffer;
3272 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3273 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3274 target_buffer += interlace*cols;
3279 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3280 *dma_prog++ = 0; /* NULL WORD */
3282 *dma_prog++ = OP_JUMP ;
3283 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3287 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3288 *dma_prog++ = 0; /* NULL WORD */
3290 *dma_prog++ = OP_JUMP;
3291 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3295 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3296 *dma_prog++ = 0; /* NULL WORD */
3298 *dma_prog++ = OP_JUMP ;
3299 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3303 if (interlace == 2) {
3305 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3307 target_buffer = (uint32_t) buffer + cols;
3308 t1 = buffer + cols/2;
3309 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3310 *dma_prog++ = 0; /* NULL WORD */
3312 for (i = 0; i < (rows/interlace ) ; i++) {
3314 *dma_prog++ = cols/2 | cols/2 << 16;
3315 *dma_prog++ = target_buffer;
3316 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3317 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3318 target_buffer += interlace*cols;
3322 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3323 *dma_prog++ = 0; /* NULL WORD */
3324 *dma_prog++ = OP_JUMP ;
3325 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ;
3326 *dma_prog++ = 0; /* NULL WORD */
3334 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3335 int cols, int rows, int interlace ){
3338 volatile unsigned int inst;
3339 volatile unsigned int inst1;
3340 volatile uint32_t target_buffer, t1, buffer;
3341 volatile uint32_t *dma_prog;
3342 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3344 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3346 dma_prog = (uint32_t *) bktr->dma_prog;
3348 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3350 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3351 OUTB(bktr, BKTR_OFORM, 0x0);
3353 /* Construct Write */
3354 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3355 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3356 if (bktr->video.addr)
3357 target_buffer = (uint32_t) bktr->video.addr;
3359 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
3361 buffer = target_buffer;
3364 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3365 *dma_prog++ = 0; /* NULL WORD */
3367 for (i = 0; i < (rows/interlace )/2 ; i++) {
3369 *dma_prog++ = cols/2 | (cols/2 << 16);
3370 *dma_prog++ = target_buffer;
3371 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3372 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3373 target_buffer += interlace*cols;
3374 *dma_prog++ = inst1;
3375 *dma_prog++ = cols/2 | (cols/2 << 16);
3376 *dma_prog++ = target_buffer;
3377 target_buffer += interlace*cols;
3383 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3384 *dma_prog++ = 0; /* NULL WORD */
3386 *dma_prog++ = OP_JUMP;
3387 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3391 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3392 *dma_prog++ = 0; /* NULL WORD */
3394 *dma_prog++ = OP_JUMP;
3395 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3399 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3400 *dma_prog++ = 0; /* NULL WORD */
3401 *dma_prog++ = OP_JUMP ;
3402 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog);
3406 if (interlace == 2) {
3408 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3410 target_buffer = (uint32_t) buffer + cols;
3411 t1 = buffer + cols/2;
3412 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3413 *dma_prog++ = 0; /* NULL WORD */
3415 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3417 *dma_prog++ = cols/2 | (cols/2 << 16);
3418 *dma_prog++ = target_buffer;
3419 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3420 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3421 target_buffer += interlace*cols;
3422 *dma_prog++ = inst1;
3423 *dma_prog++ = cols/2 | (cols/2 << 16);
3424 *dma_prog++ = target_buffer;
3425 target_buffer += interlace*cols;
3432 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3433 *dma_prog++ = 0; /* NULL WORD */
3434 *dma_prog++ = OP_JUMP;
3435 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog);
3436 *dma_prog++ = 0; /* NULL WORD */
3445 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3447 int rows, cols, interlace;
3450 struct format_params *fp;
3451 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3454 fp = &format_params[bktr->format_params];
3456 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3458 /* disable FIFO & RISC, leave other bits alone */
3459 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3461 /* set video parameters */
3462 if (bktr->capture_area_enabled)
3463 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3464 / fp->scaled_htotal / bktr->cols) - 4096;
3466 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3467 / fp->scaled_htotal / bktr->cols) - 4096;
3469 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3470 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3471 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3472 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3473 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3475 /* horizontal active */
3477 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3478 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3479 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3480 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3481 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3482 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3483 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3485 /* horizontal delay */
3486 if (bktr->capture_area_enabled)
3487 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3488 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3490 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3492 temp = temp & 0x3fe;
3494 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3495 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3496 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3497 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3498 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3499 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3500 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3502 /* vertical scale */
3504 if (bktr->capture_area_enabled) {
3505 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3506 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3508 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3511 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3514 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3515 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3517 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3520 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3525 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3526 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3527 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3528 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3529 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3530 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3531 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3534 /* vertical active */
3535 if (bktr->capture_area_enabled)
3536 temp = bktr->capture_area_y_size;
3539 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3540 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3541 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3542 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3543 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3544 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3545 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3547 /* vertical delay */
3548 if (bktr->capture_area_enabled)
3549 temp = fp->vdelay + (bktr->capture_area_y_offset);
3552 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3553 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3554 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3555 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3556 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3557 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3558 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3560 /* end of video params */
3562 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3563 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3564 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3566 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3569 /* capture control */
3572 bktr->bktr_cap_ctl =
3573 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3574 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3575 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3579 bktr->bktr_cap_ctl =
3580 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3581 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3582 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3586 bktr->bktr_cap_ctl =
3587 (BT848_CAP_CTL_DITH_FRAME |
3588 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3589 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3590 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3595 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3600 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3602 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3603 /* user, then use the rgb_vbi RISC program. */
3604 /* Otherwise, use the normal rgb RISC program */
3605 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3606 if ( (bktr->vbiflags & VBI_OPEN)
3607 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3608 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3610 bktr->bktr_cap_ctl |=
3611 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3612 bktr->vbiflags |= VBI_CAPTURE;
3613 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3616 rgb_prog(bktr, i_flag, cols, rows, interlace);
3621 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3622 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3623 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3624 | pixfmt_swap_flags( bktr->pixfmt ));
3628 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3629 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3630 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3631 | pixfmt_swap_flags( bktr->pixfmt ));
3635 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3636 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3637 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3638 | pixfmt_swap_flags( bktr->pixfmt ));
3645 /******************************************************************************
3646 * video & video capture specific routines:
3654 start_capture( bktr_ptr_t bktr, unsigned type )
3657 struct format_params *fp;
3659 fp = &format_params[bktr->format_params];
3661 /* If requested, clear out capture buf first */
3662 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3663 bzero((caddr_t)bktr->bigbuf,
3664 (size_t)bktr->rows * bktr->cols * bktr->frames *
3665 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3668 OUTB(bktr, BKTR_DSTATUS, 0);
3669 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3671 bktr->flags |= type;
3672 bktr->flags &= ~METEOR_WANT_MASK;
3673 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3674 case METEOR_ONLY_EVEN_FIELDS:
3675 bktr->flags |= METEOR_WANT_EVEN;
3678 case METEOR_ONLY_ODD_FIELDS:
3679 bktr->flags |= METEOR_WANT_ODD;
3683 bktr->flags |= METEOR_WANT_MASK;
3688 /* TDEC is only valid for continuous captures */
3689 if ( type == METEOR_SINGLE ) {
3690 u_short fps_save = bktr->fps;
3692 set_fps(bktr, fp->frame_rate);
3693 bktr->fps = fps_save;
3696 set_fps(bktr, bktr->fps);
3698 if (bktr->dma_prog_loaded == FALSE) {
3699 build_dma_prog(bktr, i_flag);
3700 bktr->dma_prog_loaded = TRUE;
3704 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3710 * Set the temporal decimation register to get the desired frame rate.
3711 * We use the 'skip frame' modus always and always start dropping on an
3715 set_fps( bktr_ptr_t bktr, u_short fps )
3717 struct format_params *fp;
3719 fp = &format_params[bktr->format_params];
3721 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3722 case METEOR_ONLY_EVEN_FIELDS:
3723 bktr->flags |= METEOR_WANT_EVEN;
3725 case METEOR_ONLY_ODD_FIELDS:
3726 bktr->flags |= METEOR_WANT_ODD;
3729 bktr->flags |= METEOR_WANT_MASK;
3733 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3734 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3737 OUTB(bktr, BKTR_TDEC, 0);
3739 if (fps < fp->frame_rate)
3740 OUTB(bktr, BKTR_TDEC, (fp->frame_rate - fps) & 0x3f);
3742 OUTB(bktr, BKTR_TDEC, 0);
3752 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3753 * achieve the specified swapping.
3754 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3755 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3757 * Note also that for 3Bpp, we may additionally need to do some creative
3758 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3759 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3760 * as one would expect.
3763 static u_int pixfmt_swap_flags( int pixfmt )
3765 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3768 switch ( pf->Bpp ) {
3769 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3772 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3775 case 4 : if ( pf->swap_bytes )
3776 swapf = pf->swap_shorts ? 0 : WSWAP;
3778 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3787 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3788 * our pixfmt_table indices.
3791 static int oformat_meteor_to_bt( u_long format )
3794 struct meteor_pixfmt *pf1, *pf2;
3796 /* Find format in compatibility table */
3797 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3798 if ( meteor_pixfmt_table[i].meteor_format == format )
3801 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3803 pf1 = &meteor_pixfmt_table[i].public;
3805 /* Match it with an entry in master pixel format table */
3806 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3807 pf2 = &pixfmt_table[i].public;
3809 if (( pf1->type == pf2->type ) &&
3810 ( pf1->Bpp == pf2->Bpp ) &&
3811 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3812 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3813 ( pf1->swap_shorts == pf2->swap_shorts ))
3816 if ( i >= PIXFMT_TABLE_SIZE )
3822 /******************************************************************************
3827 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3828 #define I2CBITTIME_878 (1 << 7)
3829 #define I2C_READ 0x01
3830 #define I2C_COMMAND (I2CBITTIME | \
3831 BT848_DATA_CTL_I2CSCL | \
3832 BT848_DATA_CTL_I2CSDA)
3834 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3835 BT848_DATA_CTL_I2CSCL | \
3836 BT848_DATA_CTL_I2CSDA)
3838 /* Select between old i2c code and new iicbus / smbus code */
3839 #if defined(BKTR_USE_FREEBSD_SMBUS)
3842 * The hardware interface is actually SMB commands
3845 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3849 if (bktr->id == BROOKTREE_848 ||
3850 bktr->id == BROOKTREE_848A ||
3851 bktr->id == BROOKTREE_849A)
3854 cmd = I2C_COMMAND_878;
3857 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3858 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3861 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3862 (char)(byte1 & 0xff)))
3871 i2cRead( bktr_ptr_t bktr, int addr )
3876 if (bktr->id == BROOKTREE_848 ||
3877 bktr->id == BROOKTREE_848A ||
3878 bktr->id == BROOKTREE_849A)
3881 cmd = I2C_COMMAND_878;
3883 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3886 return ((int)((unsigned char)result));
3889 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3891 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3892 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3893 /* Therefore we need low level control of the i2c bus hardware */
3895 /* Write to the MSP or DPL registers */
3897 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3899 unsigned char addr_l, addr_h, data_h, data_l ;
3901 addr_h = (addr >>8) & 0xff;
3902 addr_l = addr & 0xff;
3903 data_h = (data >>8) & 0xff;
3904 data_l = data & 0xff;
3906 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3908 iicbus_write_byte(IICBUS(bktr), dev, 0);
3909 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3910 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3911 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3912 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3914 iicbus_stop(IICBUS(bktr));
3919 /* Read from the MSP or DPL registers */
3921 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3924 unsigned char addr_l, addr_h, dev_r;
3926 u_char data_read[2];
3928 addr_h = (addr >>8) & 0xff;
3929 addr_l = addr & 0xff;
3932 /* XXX errors ignored */
3933 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3935 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3936 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3937 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3939 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3940 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3941 iicbus_stop(IICBUS(bktr));
3943 data = (data_read[0]<<8) | data_read[1];
3948 /* Reset the MSP or DPL chip */
3949 /* The user can block the reset (which is handy if you initialise the
3950 * MSP and/or DPL audio in another operating system first (eg in Windows)
3953 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3956 #ifndef BKTR_NO_MSP_RESET
3957 /* put into reset mode */
3958 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3959 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3960 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3961 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3962 iicbus_stop(IICBUS(bktr));
3964 /* put back to operational mode */
3965 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3966 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3967 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3968 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3969 iicbus_stop(IICBUS(bktr));
3974 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3977 /* XXX errors ignored */
3978 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3979 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3980 iicbus_stop(IICBUS(bktr));
3985 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3988 * Program the i2c bus directly
3991 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3996 /* clear status bits */
3997 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3999 /* build the command datum */
4000 if (bktr->id == BROOKTREE_848 ||
4001 bktr->id == BROOKTREE_848A ||
4002 bktr->id == BROOKTREE_849A) {
4003 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
4005 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
4007 if ( byte2 != -1 ) {
4008 data |= ((byte2 & 0xff) << 8);
4009 data |= BT848_DATA_CTL_I2CW3B;
4012 /* write the address and data */
4013 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
4015 /* wait for completion */
4016 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4017 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4022 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4034 i2cRead( bktr_ptr_t bktr, int addr )
4038 /* clear status bits */
4039 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4041 /* write the READ address */
4042 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
4044 if (bktr->id == BROOKTREE_848 ||
4045 bktr->id == BROOKTREE_848A ||
4046 bktr->id == BROOKTREE_849A) {
4047 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
4049 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
4052 /* wait for completion */
4053 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4054 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4059 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4063 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4066 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4067 /* bt848 automated i2c bus controller cannot handle */
4068 /* Therefore we need low level control of the i2c bus hardware */
4069 /* Idea for the following functions are from elsewhere in this driver and */
4070 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4073 static void i2c_start( bktr_ptr_t bktr) {
4074 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4075 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4076 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4077 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4080 static void i2c_stop( bktr_ptr_t bktr) {
4081 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4082 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4083 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4086 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4090 /* write out the byte */
4091 for ( x = 7; x >= 0; --x ) {
4092 if ( data & (1<<x) ) {
4093 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4094 DELAY( BITD ); /* assert HI data */
4095 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4096 DELAY( BITD ); /* strobe clock */
4097 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4098 DELAY( BITD ); /* release clock */
4101 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4102 DELAY( BITD ); /* assert LO data */
4103 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4104 DELAY( BITD ); /* strobe clock */
4105 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4106 DELAY( BITD ); /* release clock */
4110 /* look for an ACK */
4111 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4112 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4113 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4114 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4119 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4124 /* read in the byte */
4125 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4126 DELAY( BITD ); /* float data */
4127 for ( x = 7; x >= 0; --x ) {
4128 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4129 DELAY( BITD ); /* strobe clock */
4130 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4131 if ( bit ) byte |= (1<<x);
4132 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4133 DELAY( BITD ); /* release clock */
4135 /* After reading the byte, send an ACK */
4136 /* (unless that was the last byte, for which we send a NAK */
4137 if (last) { /* send NAK - same a writing a 1 */
4138 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4139 DELAY( BITD ); /* set data bit */
4140 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4141 DELAY( BITD ); /* strobe clock */
4142 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4143 DELAY( BITD ); /* release clock */
4144 } else { /* send ACK - same as writing a 0 */
4145 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4146 DELAY( BITD ); /* set data bit */
4147 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4148 DELAY( BITD ); /* strobe clock */
4149 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4150 DELAY( BITD ); /* release clock */
4158 /* Write to the MSP or DPL registers */
4159 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4161 unsigned int msp_w_addr = i2c_addr;
4162 unsigned char addr_l, addr_h, data_h, data_l ;
4163 addr_h = (addr >>8) & 0xff;
4164 addr_l = addr & 0xff;
4165 data_h = (data >>8) & 0xff;
4166 data_l = data & 0xff;
4169 i2c_write_byte(bktr, msp_w_addr);
4170 i2c_write_byte(bktr, dev);
4171 i2c_write_byte(bktr, addr_h);
4172 i2c_write_byte(bktr, addr_l);
4173 i2c_write_byte(bktr, data_h);
4174 i2c_write_byte(bktr, data_l);
4178 /* Read from the MSP or DPL registers */
4179 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4181 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4182 addr_h = (addr >>8) & 0xff;
4183 addr_l = addr & 0xff;
4187 i2c_write_byte(bktr,i2c_addr);
4188 i2c_write_byte(bktr,dev_r);
4189 i2c_write_byte(bktr,addr_h);
4190 i2c_write_byte(bktr,addr_l);
4193 i2c_write_byte(bktr,i2c_addr+1);
4194 i2c_read_byte(bktr,&data_1, 0);
4195 i2c_read_byte(bktr,&data_2, 1);
4197 data = (data_1<<8) | data_2;
4201 /* Reset the MSP or DPL chip */
4202 /* The user can block the reset (which is handy if you initialise the
4203 * MSP audio in another operating system first (eg in Windows)
4205 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4207 #ifndef BKTR_NO_MSP_RESET
4208 /* put into reset mode */
4210 i2c_write_byte(bktr, i2c_addr);
4211 i2c_write_byte(bktr, 0x00);
4212 i2c_write_byte(bktr, 0x80);
4213 i2c_write_byte(bktr, 0x00);
4216 /* put back to operational mode */
4218 i2c_write_byte(bktr, i2c_addr);
4219 i2c_write_byte(bktr, 0x00);
4220 i2c_write_byte(bktr, 0x00);
4221 i2c_write_byte(bktr, 0x00);
4228 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4230 /* XXX errors ignored */
4232 i2c_write_byte(bktr,bktr->remote_control_addr);
4233 i2c_read_byte(bktr,&(remote->data[0]), 0);
4234 i2c_read_byte(bktr,&(remote->data[1]), 0);
4235 i2c_read_byte(bktr,&(remote->data[2]), 0);
4241 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4244 #if defined( I2C_SOFTWARE_PROBE )
4247 * we are keeping this around for any parts that we need to probe
4248 * but that CANNOT be probed via an i2c read.
4249 * this is necessary because the hardware i2c mechanism
4250 * cannot be programmed for 1 byte writes.
4251 * currently there are no known i2c parts that we need to probe
4252 * and that cannot be safely read.
4254 static int i2cProbe( bktr_ptr_t bktr, int addr );
4259 * probe for an I2C device at addr.
4262 i2cProbe( bktr_ptr_t bktr, int addr )
4267 #if defined( EXTRA_START )
4268 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4269 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4270 #endif /* EXTRA_START */
4271 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4272 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4275 for ( x = 7; x >= 0; --x ) {
4276 if ( addr & (1<<x) ) {
4277 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4278 DELAY( BITD ); /* assert HI data */
4279 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4280 DELAY( BITD ); /* strobe clock */
4281 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4282 DELAY( BITD ); /* release clock */
4285 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4286 DELAY( BITD ); /* assert LO data */
4287 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4288 DELAY( BITD ); /* strobe clock */
4289 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4290 DELAY( BITD ); /* release clock */
4294 /* look for an ACK */
4295 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4296 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4297 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4298 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4301 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4302 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4303 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4310 #endif /* I2C_SOFTWARE_PROBE */
4315 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */