2 * 1. Redistributions of source code must retain the
3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Amancio Hasty and
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 * 1. Redistributions of source code must retain the
35 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
36 * All rights reserved.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by Mark Tinguely and Jim Lowe
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
56 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
58 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
60 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
61 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
65 #include <sys/cdefs.h>
66 __FBSDID("$FreeBSD$");
69 * This is part of the Driver for Video Capture Cards (Frame grabbers)
70 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
72 * Copyright Roger Hardiman and Amancio Hasty.
74 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
75 * Handles all the open, close, ioctl and read userland calls.
76 * Sets the Bt848 registers and generates RISC pograms.
77 * Controls the i2c bus and GPIO interface.
78 * Contains the interface to the kernel.
79 * (eg probe/attach and open/close/ioctl)
83 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
84 Jim Lowe's driver for the Matrox Meteor PCI card . The
85 Philips SAA 7116 and SAA 7196 are very different chipsets than
88 The original copyright notice by Mark and Jim is included mostly
89 to honor their fantastic work in the Matrox Meteor driver!
92 #include "opt_bktr.h" /* Include any kernel config options */
95 (defined(__FreeBSD__)) \
96 || (defined(__bsdi__)) \
97 || (defined(__OpenBSD__)) \
98 || (defined(__NetBSD__)) \
102 /*******************/
103 /* *** FreeBSD *** */
104 /*******************/
107 #include <sys/param.h>
108 #include <sys/systm.h>
109 #include <sys/kernel.h>
110 #include <sys/fcntl.h>
111 #include <sys/lock.h>
112 #include <sys/malloc.h>
113 #include <sys/mutex.h>
114 #include <sys/proc.h>
115 #include <sys/signalvar.h>
116 #include <sys/selinfo.h>
120 #include <vm/vm_kern.h>
122 #include <vm/vm_extern.h>
124 #include <sys/bus.h> /* used by smbus and newbus */
126 #if (__FreeBSD_version < 500000)
127 #include <machine/clock.h> /* for DELAY */
129 #define PROC_UNLOCK(p)
130 #include <pci/pcivar.h>
132 #include <dev/pci/pcivar.h>
135 #include <machine/bus.h>
138 #include <dev/bktr/ioctl_meteor.h>
139 #include <dev/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
140 #include <dev/bktr/bktr_reg.h>
141 #include <dev/bktr/bktr_tuner.h>
142 #include <dev/bktr/bktr_card.h>
143 #include <dev/bktr/bktr_audio.h>
144 #include <dev/bktr/bktr_os.h>
145 #include <dev/bktr/bktr_core.h>
146 #if defined(BKTR_FREEBSD_MODULE)
147 #include <dev/bktr/bktr_mem.h>
150 #if defined(BKTR_USE_FREEBSD_SMBUS)
151 #include <dev/bktr/bktr_i2c.h>
152 #include <dev/smbus/smbconf.h>
153 #include <dev/iicbus/iiconf.h>
154 #include "smbus_if.h"
155 #include "iicbus_if.h"
159 bktr_name(bktr_ptr_t bktr)
161 return bktr->bktr_xname;
165 #endif /* __FreeBSD__ */
173 #define PROC_UNLOCK(p)
174 #endif /* __bsdi__ */
177 /**************************/
178 /* *** OpenBSD/NetBSD *** */
179 /**************************/
180 #if defined(__NetBSD__) || defined(__OpenBSD__)
182 #include <sys/param.h>
183 #include <sys/systm.h>
184 #include <sys/kernel.h>
185 #include <sys/signalvar.h>
186 #include <sys/vnode.h>
189 #include <uvm/uvm_extern.h>
192 #include <vm/vm_kern.h>
194 #include <vm/vm_extern.h>
197 #include <sys/inttypes.h> /* uintptr_t */
198 #include <dev/ic/bt8xx.h>
199 #include <dev/pci/bktr/bktr_reg.h>
200 #include <dev/pci/bktr/bktr_tuner.h>
201 #include <dev/pci/bktr/bktr_card.h>
202 #include <dev/pci/bktr/bktr_audio.h>
203 #include <dev/pci/bktr/bktr_core.h>
204 #include <dev/pci/bktr/bktr_os.h>
206 static int bt848_format = -1;
209 bktr_name(bktr_ptr_t bktr)
211 return (bktr->bktr_dev.dv_xname);
215 #define PROC_UNLOCK(p)
217 #endif /* __NetBSD__ || __OpenBSD__ */
220 typedef u_char bool_t;
222 #define BKTRPRI (PZERO+8)|PCATCH
223 #define VBIPRI (PZERO-4)|PCATCH
227 * memory allocated for DMA programs
229 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
231 /* When to split a dma transfer , the bt848 has timing as well as
232 dma transfer size limitations so that we have to split dma
233 transfers into two dma requests
235 #define DMA_BT848_SPLIT 319*2
238 * Allocate enough memory for:
239 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
241 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
242 * in your kernel configuration file.
245 #ifndef BROOKTREE_ALLOC_PAGES
246 #define BROOKTREE_ALLOC_PAGES 217*4
248 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
250 /* Definitions for VBI capture.
251 * There are 16 VBI lines in a PAL video field (32 in a frame),
252 * and we take 2044 samples from each line (placed in a 2048 byte buffer
254 * VBI lines are held in a circular buffer before being read by a
255 * user program from /dev/vbi.
258 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
259 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
260 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
261 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
262 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
265 /* Defines for fields */
271 * Parameters describing size of transmitted image.
274 static struct format_params format_params[] = {
275 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
276 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
278 /* # define BT848_IFORM_F_NTSCM (0x1) */
279 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
281 /* # define BT848_IFORM_F_NTSCJ (0x2) */
282 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
284 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
285 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
287 /* # define BT848_IFORM_F_PALM (0x4) */
288 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
290 /* # define BT848_IFORM_F_PALN (0x5) */
291 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
293 /* # define BT848_IFORM_F_SECAM (0x6) */
294 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
296 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
297 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
302 * Table of supported Pixel Formats
305 static struct meteor_pixfmt_internal {
306 struct meteor_pixfmt public;
310 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
311 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
313 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
314 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
316 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
318 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
319 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
320 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
321 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
322 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
323 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
324 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
327 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
330 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
333 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
335 u_long meteor_format;
336 struct meteor_pixfmt public;
337 } meteor_pixfmt_table[] = {
339 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
342 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
343 { METEOR_GEO_YUV_422,
344 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
346 { METEOR_GEO_YUV_PACKED,
347 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
350 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
353 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
357 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
358 sizeof(meteor_pixfmt_table[0]) )
361 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
362 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
366 /* sync detect threshold */
368 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
369 BT848_ADC_CRUSH) /* threshold ~125 mV */
371 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
372 BT848_ADC_SYNC_T) /* threshold ~75 mV */
378 /* debug utility for holding previous INT_STAT contents */
380 static u_long status_sum = 0;
383 * defines to make certain bit-fiddles understandable
385 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
386 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
387 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
388 #define FIFO_RISC_DISABLED 0
390 #define ALL_INTS_DISABLED 0
391 #define ALL_INTS_CLEARED 0xffffffff
392 #define CAPTURE_OFF 0
394 #define BIT_SEVEN_HIGH (1<<7)
395 #define BIT_EIGHT_HIGH (1<<8)
397 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
398 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
402 static int oformat_meteor_to_bt( u_long format );
404 static u_int pixfmt_swap_flags( int pixfmt );
407 * bt848 RISC programming routines.
410 static int dump_bt848( bktr_ptr_t bktr );
413 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
414 int rows, int interlace );
415 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
416 int rows, int interlace );
417 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
418 int rows, int interlace );
419 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
420 int rows, int interlace );
421 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
422 int rows, int interlace );
423 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
425 static bool_t getline(bktr_reg_t *, int);
426 static bool_t notclipped(bktr_reg_t * , int , int);
427 static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
428 volatile u_char ** , int );
430 static void start_capture( bktr_ptr_t bktr, unsigned type );
431 static void set_fps( bktr_ptr_t bktr, u_short fps );
436 * Remote Control Functions
438 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
442 * ioctls common to both video & tuner.
444 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
447 #if !defined(BKTR_USE_FREEBSD_SMBUS)
449 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
451 static void i2c_start( bktr_ptr_t bktr);
452 static void i2c_stop( bktr_ptr_t bktr);
453 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
454 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
460 * the common attach code, used by all OS versions.
463 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
466 int need_to_allocate_memory = 1;
467 #ifdef BKTR_NEW_MSP34XX_DRIVER
471 /***************************************/
472 /* *** OS Specific memory routines *** */
473 /***************************************/
474 #if defined(__NetBSD__) || defined(__OpenBSD__)
475 /* allocate space for dma program */
476 bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog,
478 bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
481 /* allocate space for the VBI buffer */
482 bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata,
484 bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
487 /* allocate space for pixel buffer */
488 if ( BROOKTREE_ALLOC )
489 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
494 #if defined(__FreeBSD__) || defined(__bsdi__)
496 /* If this is a module, check if there is any currently saved contiguous memory */
497 #if defined(BKTR_FREEBSD_MODULE)
498 if (bktr_has_stored_addresses(unit) == 1) {
499 /* recover the addresses */
500 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
501 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
502 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
503 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
504 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
505 need_to_allocate_memory = 0;
509 if (need_to_allocate_memory == 1) {
510 /* allocate space for dma program */
511 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
512 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
514 /* allocte space for the VBI buffer */
515 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
516 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
518 /* allocate space for pixel buffer */
519 if ( BROOKTREE_ALLOC )
520 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
524 #endif /* FreeBSD or BSDi */
527 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
530 /* If this is a module, save the current contiguous memory */
531 #if defined(BKTR_FREEBSD_MODULE)
532 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
533 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
534 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
535 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
536 bktr_store_address(unit, BKTR_MEM_BUF, buf);
541 printf("%s: buffer size %d, addr %p\n",
542 bktr_name(bktr), (int)BROOKTREE_ALLOC,
543 (void *)(uintptr_t)vtophys(buf));
548 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
549 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
551 bktr->alloc_pages = 0;
555 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
556 METEOR_DEV0 | METEOR_RGB16;
557 bktr->dma_prog_loaded = FALSE;
560 bktr->frames = 1; /* one frame */
561 bktr->format = METEOR_GEO_RGB16;
562 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
563 bktr->pixfmt_compat = TRUE;
572 /* using the pci device id and revision id */
573 /* and determine the card type */
574 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
576 switch (PCI_PRODUCT(pci_id)) {
577 case PCI_PRODUCT_BROOKTREE_BT848:
579 bktr->id = BROOKTREE_848A;
581 bktr->id = BROOKTREE_848;
583 case PCI_PRODUCT_BROOKTREE_BT849:
584 bktr->id = BROOKTREE_849A;
586 case PCI_PRODUCT_BROOKTREE_BT878:
587 bktr->id = BROOKTREE_878;
589 case PCI_PRODUCT_BROOKTREE_BT879:
590 bktr->id = BROOKTREE_879;
595 bktr->clr_on_start = FALSE;
597 /* defaults for the tuner section of the card */
598 bktr->tflags = TUNER_INITALIZED;
599 bktr->tuner.frequency = 0;
600 bktr->tuner.channel = 0;
601 bktr->tuner.chnlset = DEFAULT_CHNLSET;
603 bktr->tuner.radio_mode = 0;
604 bktr->audio_mux_select = 0;
605 bktr->audio_mute_state = FALSE;
606 bktr->bt848_card = -1;
607 bktr->bt848_tuner = -1;
608 bktr->reverse_mute = -1;
609 bktr->slow_msp_audio = 0;
610 bktr->msp_use_mono_source = 0;
611 bktr->msp_source_selected = -1;
612 bktr->audio_mux_present = 1;
614 #if defined(__FreeBSD__)
615 #ifdef BKTR_NEW_MSP34XX_DRIVER
616 /* get hint on short programming of the msp34xx, so we know */
617 /* if the decision what thread to start should be overwritten */
618 if ( (err = resource_int_value("bktr", unit, "mspsimple",
619 &(bktr->mspsimple)) ) != 0 )
620 bktr->mspsimple = -1; /* fall back to default */
624 probeCard( bktr, TRUE, unit );
626 /* Initialise any MSP34xx or TDA98xx audio chips */
627 init_audio_devices( bktr );
629 #ifdef BKTR_NEW_MSP34XX_DRIVER
630 /* setup the kenrel thread */
631 err = msp_attach( bktr );
632 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
633 bktr->card.msp3400c = 0;
640 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
641 * The circular buffer holds 'n' fixed size data blocks.
642 * vbisize is the number of bytes in the circular buffer
643 * vbiread is the point we reading data out of the circular buffer
644 * vbiinsert is the point we insert data into the circular buffer
646 static void vbidecode(bktr_ptr_t bktr) {
648 unsigned int *seq_dest;
650 /* Check if there is room in the buffer to insert the data. */
651 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
653 /* Copy the VBI data into the next free slot in the buffer. */
654 /* 'dest' is the point in vbibuffer where we want to insert new data */
655 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
656 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
658 /* Write the VBI sequence number to the end of the vbi data */
659 /* This is used by the AleVT teletext program */
660 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
662 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
663 *seq_dest = bktr->vbi_sequence_number;
665 /* And increase the VBI sequence number */
666 /* This can wrap around */
667 bktr->vbi_sequence_number++;
670 /* Increment the vbiinsert pointer */
671 /* This can wrap around */
672 bktr->vbiinsert += VBI_DATA_SIZE;
673 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
675 /* And increase the amount of vbi data in the buffer */
676 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
682 * the common interrupt handler.
683 * Returns a 0 or 1 depending on whether the interrupt has handled.
684 * In the OS specific section, bktr_intr() is defined which calls this
685 * common interrupt handler.
688 common_bktr_intr( void *arg )
697 bktr = (bktr_ptr_t) arg;
700 * check to see if any interrupts are unmasked on this device. If
701 * none are, then we likely got here by way of being on a PCI shared
702 * interrupt dispatch list.
704 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
705 return 0; /* bail out now, before we do something we
708 if (!(bktr->flags & METEOR_OPEN)) {
709 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
710 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
714 /* record and clear the INTerrupt status bits */
715 bktr_status = INL(bktr, BKTR_INT_STAT);
716 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
718 /* record and clear the device status register */
719 dstatus = INB(bktr, BKTR_DSTATUS);
720 OUTB(bktr, BKTR_DSTATUS, 0x00);
722 #if defined( STATUS_SUM )
723 /* add any new device status or INTerrupt status bits */
724 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
725 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
726 #endif /* STATUS_SUM */
727 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
728 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
732 /* if risc was disabled re-start process again */
733 /* if there was one of the following errors re-start again */
734 if ( !(bktr_status & BT848_INT_RISC_EN) ||
735 ((bktr_status &(/* BT848_INT_FBUS | */
736 /* BT848_INT_FTRGT | */
737 /* BT848_INT_FDSR | */
739 BT848_INT_RIPERR | BT848_INT_PABORT |
740 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
741 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
743 u_short tdec_save = INB(bktr, BKTR_TDEC);
745 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
746 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
748 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
750 /* Reset temporal decimation counter */
751 OUTB(bktr, BKTR_TDEC, 0);
752 OUTB(bktr, BKTR_TDEC, tdec_save);
754 /* Reset to no-fields captured state */
755 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
756 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
757 case METEOR_ONLY_ODD_FIELDS:
758 bktr->flags |= METEOR_WANT_ODD;
760 case METEOR_ONLY_EVEN_FIELDS:
761 bktr->flags |= METEOR_WANT_EVEN;
764 bktr->flags |= METEOR_WANT_MASK;
769 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
770 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
771 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
773 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
778 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
782 /* If this is not a RISC program interrupt, return */
783 if (!(bktr_status & BT848_INT_RISCI))
787 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
788 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
793 * Disable future interrupts if a capture mode is not selected.
794 * This can happen when we are in the process of closing or
795 * changing capture modes, otherwise it shouldn't happen.
797 if (!(bktr->flags & METEOR_CAP_MASK))
798 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
801 /* Determine which field generated this interrupt */
802 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
806 * Process the VBI data if it is being captured. We do this once
807 * both Odd and Even VBI data is captured. Therefore we do this
808 * in the Even field interrupt handler.
811 if ( (bktr->vbiflags & VBI_CAPTURE)
812 &&(bktr->vbiflags & VBI_OPEN)
814 /* Put VBI data into circular buffer */
817 /* If someone is blocked on reading from /dev/vbi, wake them */
818 if (bktr->vbi_read_blocked) {
819 bktr->vbi_read_blocked = FALSE;
823 /* If someone has a select() on /dev/vbi, inform them */
824 if (SEL_WAITING(&bktr->vbi_select)) {
825 selwakeuppri(&bktr->vbi_select, VBIPRI);
833 * Register the completed field
834 * (For dual-field mode, require fields from the same frame)
836 switch ( bktr->flags & METEOR_WANT_MASK ) {
837 case METEOR_WANT_ODD : w_field = ODD_F ; break;
838 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
839 default : w_field = (ODD_F|EVEN_F); break;
841 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
842 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
843 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
844 default : req_field = (ODD_F|EVEN_F);
848 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
849 bktr->flags &= ~METEOR_WANT_EVEN;
850 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
851 ( w_field == ODD_F ))
852 bktr->flags &= ~METEOR_WANT_ODD;
853 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
854 ( w_field == (ODD_F|EVEN_F) ))
855 bktr->flags &= ~METEOR_WANT_ODD;
856 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
857 ( w_field == ODD_F )) {
858 bktr->flags &= ~METEOR_WANT_ODD;
859 bktr->flags |= METEOR_WANT_EVEN;
862 /* We're out of sync. Start over. */
863 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
864 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
865 case METEOR_ONLY_ODD_FIELDS:
866 bktr->flags |= METEOR_WANT_ODD;
868 case METEOR_ONLY_EVEN_FIELDS:
869 bktr->flags |= METEOR_WANT_EVEN;
872 bktr->flags |= METEOR_WANT_MASK;
880 * If we have a complete frame.
882 if (!(bktr->flags & METEOR_WANT_MASK)) {
883 bktr->frames_captured++;
885 * post the completion time.
887 if (bktr->flags & METEOR_WANT_TS) {
890 if ((u_int) bktr->alloc_pages * PAGE_SIZE
891 <= (bktr->frame_size + sizeof(struct timeval))) {
892 ts =(struct timeval *)bktr->bigbuf +
894 /* doesn't work in synch mode except
903 * Wake up the user in single capture mode.
905 if (bktr->flags & METEOR_SINGLE) {
908 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
910 /* disable risc, leave fifo running */
911 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
916 * If the user requested to be notified via signal,
917 * let them know the frame is complete.
920 if (bktr->proc != NULL) {
921 PROC_LOCK(bktr->proc);
922 kern_psignal( bktr->proc, bktr->signal);
923 PROC_UNLOCK(bktr->proc);
927 * Reset the want flags if in continuous or
928 * synchronous capture mode.
932 * currently we only support 3 capture modes: odd only, even only,
933 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
934 * either even OR odd) could provide 60 (50 for PAL) pictures per
935 * second, but it would require this routine to toggle the desired frame
936 * each time, and one more different DMA program for the Bt848.
937 * As a consequence, this fourth mode is currently unsupported.
940 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
941 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
942 case METEOR_ONLY_ODD_FIELDS:
943 bktr->flags |= METEOR_WANT_ODD;
945 case METEOR_ONLY_EVEN_FIELDS:
946 bktr->flags |= METEOR_WANT_EVEN;
949 bktr->flags |= METEOR_WANT_MASK;
964 extern int bt848_format; /* used to set the default format, PAL or NTSC */
966 video_open( bktr_ptr_t bktr )
968 int frame_rate, video_format=0;
970 if (bktr->flags & METEOR_OPEN) /* device is busy */
973 bktr->flags |= METEOR_OPEN;
979 bktr->clr_on_start = FALSE;
981 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
983 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
985 #if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
991 if (bt848_format == 0 )
994 if (bt848_format == 1 )
997 if (video_format == 1 ) {
998 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
999 bktr->format_params = BT848_IFORM_F_NTSCM;
1002 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
1003 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1007 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
1009 /* work around for new Hauppauge 878 cards */
1010 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
1011 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
1012 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
1014 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
1016 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
1017 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
1018 frame_rate = format_params[bktr->format_params].frame_rate;
1020 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
1021 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
1022 OUTB(bktr, BKTR_TGCTRL, 0);
1023 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
1024 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
1025 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
1028 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1030 bktr->max_clip_node = 0;
1032 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
1034 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
1035 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
1037 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
1038 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
1039 OUTB(bktr, BKTR_E_SCLOOP, 0);
1040 OUTB(bktr, BKTR_O_SCLOOP, 0);
1042 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
1043 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
1045 bktr->fifo_errors = 0;
1046 bktr->dma_errors = 0;
1047 bktr->frames_captured = 0;
1048 bktr->even_fields_captured = 0;
1049 bktr->odd_fields_captured = 0;
1051 set_fps(bktr, frame_rate);
1052 bktr->video.addr = 0;
1053 bktr->video.width = 0;
1054 bktr->video.banksize = 0;
1055 bktr->video.ramsize = 0;
1056 bktr->pixfmt_compat = TRUE;
1057 bktr->format = METEOR_GEO_RGB16;
1058 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1060 bktr->capture_area_enabled = FALSE;
1062 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
1063 based motherboards will
1064 operate unreliably */
1069 vbi_open( bktr_ptr_t bktr )
1074 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
1079 bktr->vbiflags |= VBI_OPEN;
1081 /* reset the VBI circular buffer pointers and clear the buffers */
1082 bktr->vbiinsert = 0;
1085 bktr->vbi_sequence_number = 0;
1086 bktr->vbi_read_blocked = FALSE;
1088 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
1089 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
1100 tuner_open( bktr_ptr_t bktr )
1102 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1105 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1108 bktr->tflags |= TUNER_OPEN;
1109 bktr->tuner.frequency = 0;
1110 bktr->tuner.channel = 0;
1111 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1112 bktr->tuner.afc = 0;
1113 bktr->tuner.radio_mode = 0;
1115 /* enable drivers on the GPIO port that control the MUXes */
1116 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1118 /* unmute the audio stream */
1119 set_audio( bktr, AUDIO_UNMUTE );
1121 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1122 init_audio_devices( bktr );
1134 video_close( bktr_ptr_t bktr )
1136 bktr->flags &= ~(METEOR_OPEN |
1141 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1142 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1144 bktr->dma_prog_loaded = FALSE;
1145 OUTB(bktr, BKTR_TDEC, 0);
1146 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1148 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1149 OUTL(bktr, BKTR_SRESET, 0xf);
1150 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1157 * tuner close handle,
1158 * place holder for tuner specific operations on a close.
1161 tuner_close( bktr_ptr_t bktr )
1163 bktr->tflags &= ~TUNER_OPEN;
1165 /* mute the audio by switching the mux */
1166 set_audio( bktr, AUDIO_MUTE );
1168 /* disable drivers on the GPIO port that control the MUXes */
1169 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1175 vbi_close( bktr_ptr_t bktr )
1180 bktr->vbiflags &= ~VBI_OPEN;
1191 video_read(bktr_ptr_t bktr, int unit, struct cdev *dev, struct uio *uio)
1197 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1200 if (bktr->flags & METEOR_CAP_MASK)
1201 return( EIO ); /* already capturing */
1203 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1206 count = bktr->rows * bktr->cols *
1207 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1209 if ((int) uio->uio_iov->iov_len < count)
1212 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1214 /* capture one frame */
1215 start_capture(bktr, METEOR_SINGLE);
1216 /* wait for capture to complete */
1217 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1218 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1219 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1220 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1226 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1227 if (!status) /* successful capture */
1228 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1230 printf ("%s: read: tsleep error %d\n",
1231 bktr_name(bktr), status);
1233 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1239 * Read VBI data from the vbi circular buffer
1240 * The buffer holds vbi data blocks which are the same size
1241 * vbiinsert is the position we will insert the next item into the buffer
1242 * vbistart is the actual position in the buffer we want to read from
1243 * vbisize is the exact number of bytes in the buffer left to read
1246 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1248 int readsize, readsize2, start;
1252 * XXX - vbi_read() should be protected against being re-entered
1253 * while it is unlocked for the uiomove.
1257 while(bktr->vbisize == 0) {
1258 if (ioflag & FNDELAY) {
1259 status = EWOULDBLOCK;
1263 bktr->vbi_read_blocked = TRUE;
1265 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1270 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1276 /* Now we have some data to give to the user */
1278 /* We cannot read more bytes than there are in
1279 * the circular buffer
1281 readsize = (int)uio->uio_iov->iov_len;
1283 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1285 /* Check if we can read this number of bytes without having
1286 * to wrap around the circular buffer */
1287 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1288 /* We need to wrap around */
1290 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1291 start = bktr->vbistart;
1293 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1295 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1298 /* We do not need to wrap around */
1299 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1304 /* Update the number of bytes left to read */
1305 bktr->vbisize -= readsize;
1307 /* Update vbistart */
1308 bktr->vbistart += readsize;
1309 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1324 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1326 volatile u_char c_temp;
1328 unsigned int temp_iform;
1330 struct meteor_geomet *geo;
1331 struct meteor_counts *counts;
1332 struct meteor_video *video;
1333 struct bktr_capture_area *cap_area;
1341 case BT848SCLIP: /* set clip region */
1342 bktr->max_clip_node = 0;
1343 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1345 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1346 if (bktr->clip_list[i].y_min == 0 &&
1347 bktr->clip_list[i].y_max == 0)
1350 bktr->max_clip_node = i;
1352 /* make sure that the list contains a valid clip secquence */
1353 /* the clip rectangles should be sorted by x then by y as the
1354 second order sort key */
1356 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1358 /* to disable clipping set y_min and y_max to 0 in the first
1359 clip rectangle . The first clip rectangle is clip_list[0].
1364 if (bktr->max_clip_node == 0 &&
1365 (bktr->clip_list[0].y_min != 0 &&
1366 bktr->clip_list[0].y_max != 0)) {
1370 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1371 if (bktr->clip_list[i].y_min == 0 &&
1372 bktr->clip_list[i].y_max == 0) {
1375 if ( bktr->clip_list[i+1].y_min != 0 &&
1376 bktr->clip_list[i+1].y_max != 0 &&
1377 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1379 bktr->max_clip_node = 0;
1384 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1385 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1386 bktr->clip_list[i].x_min < 0 ||
1387 bktr->clip_list[i].x_max < 0 ||
1388 bktr->clip_list[i].y_min < 0 ||
1389 bktr->clip_list[i].y_max < 0 ) {
1390 bktr->max_clip_node = 0;
1395 bktr->dma_prog_loaded = FALSE;
1399 case METEORSTATUS: /* get Bt848 status */
1400 c_temp = INB(bktr, BKTR_DSTATUS);
1402 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1403 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1404 *(u_short *)arg = temp;
1407 case BT848SFMT: /* set input format */
1408 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1409 temp_iform = INB(bktr, BKTR_IFORM);
1410 temp_iform &= ~BT848_IFORM_FORMAT;
1411 temp_iform &= ~BT848_IFORM_XTSEL;
1412 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1414 case BT848_IFORM_F_AUTO:
1415 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1419 case BT848_IFORM_F_NTSCM:
1420 case BT848_IFORM_F_NTSCJ:
1421 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1423 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1424 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1425 bktr->format_params = temp;
1428 case BT848_IFORM_F_PALBDGHI:
1429 case BT848_IFORM_F_PALN:
1430 case BT848_IFORM_F_SECAM:
1431 case BT848_IFORM_F_RSVD:
1432 case BT848_IFORM_F_PALM:
1433 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1435 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1436 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1437 bktr->format_params = temp;
1441 bktr->dma_prog_loaded = FALSE;
1444 case METEORSFMT: /* set input format */
1445 temp_iform = INB(bktr, BKTR_IFORM);
1446 temp_iform &= ~BT848_IFORM_FORMAT;
1447 temp_iform &= ~BT848_IFORM_XTSEL;
1448 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1449 case 0: /* default */
1450 case METEOR_FMT_NTSC:
1451 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1453 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1454 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1455 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1456 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1457 bktr->format_params = BT848_IFORM_F_NTSCM;
1460 case METEOR_FMT_PAL:
1461 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1463 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1464 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1465 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1466 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1467 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1470 case METEOR_FMT_AUTOMODE:
1471 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1473 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1474 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1480 bktr->dma_prog_loaded = FALSE;
1483 case METEORGFMT: /* get input format */
1484 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1488 case BT848GFMT: /* get input format */
1489 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1492 case METEORSCOUNT: /* (re)set error counts */
1493 counts = (struct meteor_counts *) arg;
1494 bktr->fifo_errors = counts->fifo_errors;
1495 bktr->dma_errors = counts->dma_errors;
1496 bktr->frames_captured = counts->frames_captured;
1497 bktr->even_fields_captured = counts->even_fields_captured;
1498 bktr->odd_fields_captured = counts->odd_fields_captured;
1501 case METEORGCOUNT: /* get error counts */
1502 counts = (struct meteor_counts *) arg;
1503 counts->fifo_errors = bktr->fifo_errors;
1504 counts->dma_errors = bktr->dma_errors;
1505 counts->frames_captured = bktr->frames_captured;
1506 counts->even_fields_captured = bktr->even_fields_captured;
1507 counts->odd_fields_captured = bktr->odd_fields_captured;
1511 video = (struct meteor_video *)arg;
1512 video->addr = bktr->video.addr;
1513 video->width = bktr->video.width;
1514 video->banksize = bktr->video.banksize;
1515 video->ramsize = bktr->video.ramsize;
1519 video = (struct meteor_video *)arg;
1520 bktr->video.addr = video->addr;
1521 bktr->video.width = video->width;
1522 bktr->video.banksize = video->banksize;
1523 bktr->video.ramsize = video->ramsize;
1527 set_fps(bktr, *(u_short *)arg);
1531 *(u_short *)arg = bktr->fps;
1534 case METEORSHUE: /* set hue */
1535 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1538 case METEORGHUE: /* get hue */
1539 *(u_char *)arg = INB(bktr, BKTR_HUE);
1542 case METEORSBRIG: /* set brightness */
1543 char_temp = ( *(u_char *)arg & 0xff) - 128;
1544 OUTB(bktr, BKTR_BRIGHT, char_temp);
1548 case METEORGBRIG: /* get brightness */
1549 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1552 case METEORSCSAT: /* set chroma saturation */
1553 temp = (int)*(u_char *)arg;
1555 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1556 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1557 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1558 & ~(BT848_E_CONTROL_SAT_U_MSB
1559 | BT848_E_CONTROL_SAT_V_MSB));
1560 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1561 & ~(BT848_O_CONTROL_SAT_U_MSB |
1562 BT848_O_CONTROL_SAT_V_MSB));
1564 if ( temp & BIT_SEVEN_HIGH ) {
1565 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1566 | (BT848_E_CONTROL_SAT_U_MSB
1567 | BT848_E_CONTROL_SAT_V_MSB));
1568 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1569 | (BT848_O_CONTROL_SAT_U_MSB
1570 | BT848_O_CONTROL_SAT_V_MSB));
1574 case METEORGCSAT: /* get chroma saturation */
1575 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1576 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1577 temp |= BIT_SEVEN_HIGH;
1578 *(u_char *)arg = (u_char)temp;
1581 case METEORSCONT: /* set contrast */
1582 temp = (int)*(u_char *)arg & 0xff;
1584 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1585 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1586 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1587 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1588 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1589 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1590 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1593 case METEORGCONT: /* get contrast */
1594 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1595 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1596 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1599 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1600 bktr->clr_on_start = (*(int *)arg != 0);
1603 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1604 *(int *)arg = (int) bktr->clr_on_start;
1609 /* Historically, applications used METEOR_SIG_MODE_MASK
1610 * to reset signal delivery.
1612 if (sig == METEOR_SIG_MODE_MASK)
1614 if (sig < 0 || sig > _SIG_MAXSIG)
1617 bktr->proc = sig ? td->td_proc : NULL;
1621 *(int *)arg = bktr->signal;
1626 switch (*(int *) arg) {
1627 case METEOR_CAP_SINGLE:
1629 if (bktr->bigbuf==0) /* no frame buffer allocated */
1631 /* already capturing */
1632 if (temp & METEOR_CAP_MASK)
1637 start_capture(bktr, METEOR_SINGLE);
1639 /* wait for capture to complete */
1640 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1641 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1642 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1644 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1649 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1650 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1651 if (error && (error != ERESTART)) {
1652 /* Here if we didn't get complete frame */
1654 printf( "%s: ioctl: tsleep error %d %x\n",
1655 bktr_name(bktr), error,
1656 INL(bktr, BKTR_RISC_COUNT));
1660 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1662 /* disable risc, leave fifo running */
1663 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1666 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1667 /* FIXME: should we set bt848->int_stat ??? */
1670 case METEOR_CAP_CONTINOUS:
1671 if (bktr->bigbuf==0) /* no frame buffer allocated */
1673 /* already capturing */
1674 if (temp & METEOR_CAP_MASK)
1678 start_capture(bktr, METEOR_CONTIN);
1680 /* Clear the interrypt status register */
1681 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1683 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1684 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1685 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1687 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1692 dump_bt848( bt848 );
1696 case METEOR_CAP_STOP_CONT:
1697 if (bktr->flags & METEOR_CONTIN) {
1698 /* turn off capture */
1699 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1700 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1701 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1703 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1710 /* can't change parameters while capturing */
1711 if (bktr->flags & METEOR_CAP_MASK)
1715 geo = (struct meteor_geomet *) arg;
1718 /* Either even or odd, if even & odd, then these a zero */
1719 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1720 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1721 printf( "%s: ioctl: Geometry odd or even only.\n",
1726 /* set/clear even/odd flags */
1727 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1728 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1730 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1731 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1732 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1734 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1736 if (geo->columns <= 0) {
1738 "%s: ioctl: %d: columns must be greater than zero.\n",
1739 bktr_name(bktr), geo->columns);
1742 else if ((geo->columns & 0x3fe) != geo->columns) {
1744 "%s: ioctl: %d: columns too large or not even.\n",
1745 bktr_name(bktr), geo->columns);
1749 if (geo->rows <= 0) {
1751 "%s: ioctl: %d: rows must be greater than zero.\n",
1752 bktr_name(bktr), geo->rows);
1755 else if (((geo->rows & 0x7fe) != geo->rows) ||
1756 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1757 ((geo->rows & 0x3fe) != geo->rows)) ) {
1759 "%s: ioctl: %d: rows too large or not even.\n",
1760 bktr_name(bktr), geo->rows);
1764 if (geo->frames > 32) {
1765 printf("%s: ioctl: too many frames.\n",
1774 bktr->dma_prog_loaded = FALSE;
1775 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1777 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1779 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1780 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1782 /* meteor_mem structure for SYNC Capture */
1783 if (geo->frames > 1) temp += PAGE_SIZE;
1786 if ((int) temp > bktr->alloc_pages
1787 && bktr->video.addr == 0) {
1789 /*****************************/
1790 /* *** OS Dependant code *** */
1791 /*****************************/
1792 #if defined(__NetBSD__) || defined(__OpenBSD__)
1793 bus_dmamap_t dmamap;
1795 buf = get_bktr_mem(bktr, &dmamap,
1798 free_bktr_mem(bktr, bktr->dm_mem,
1800 bktr->dm_mem = dmamap;
1803 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1806 (void *)(uintptr_t)bktr->bigbuf,
1807 (bktr->alloc_pages * PAGE_SIZE),
1812 bktr->alloc_pages = temp;
1814 printf("%s: ioctl: Allocating %d bytes\n",
1815 bktr_name(bktr), (int)(temp*PAGE_SIZE));
1825 bktr->rows = geo->rows;
1826 bktr->cols = geo->columns;
1827 bktr->frames = geo->frames;
1829 /* Pixel format (if in meteor pixfmt compatibility mode) */
1830 if ( bktr->pixfmt_compat ) {
1831 bktr->format = METEOR_GEO_YUV_422;
1832 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1833 case 0: /* default */
1834 case METEOR_GEO_RGB16:
1835 bktr->format = METEOR_GEO_RGB16;
1837 case METEOR_GEO_RGB24:
1838 bktr->format = METEOR_GEO_RGB24;
1840 case METEOR_GEO_YUV_422:
1841 bktr->format = METEOR_GEO_YUV_422;
1842 if (geo->oformat & METEOR_GEO_YUV_12)
1843 bktr->format = METEOR_GEO_YUV_12;
1845 case METEOR_GEO_YUV_PACKED:
1846 bktr->format = METEOR_GEO_YUV_PACKED;
1849 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1852 if (bktr->flags & METEOR_CAP_MASK) {
1854 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1855 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1856 case METEOR_ONLY_ODD_FIELDS:
1857 bktr->flags |= METEOR_WANT_ODD;
1859 case METEOR_ONLY_EVEN_FIELDS:
1860 bktr->flags |= METEOR_WANT_EVEN;
1863 bktr->flags |= METEOR_WANT_MASK;
1867 start_capture(bktr, METEOR_CONTIN);
1868 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1869 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1870 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1871 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1877 /* end of METEORSETGEO */
1879 /* FIXME. The Capture Area currently has the following restrictions:
1881 y_offset may need to be even in interlaced modes
1882 RGB24 - Interlaced mode
1883 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1884 y_size must be greater than or equal to METEORSETGEO height (rows)
1885 RGB24 - Even Only (or Odd Only) mode
1886 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1887 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1888 YUV12 - Interlaced mode
1889 x_size must be greater than or equal to METEORSETGEO width (cols)
1890 y_size must be greater than or equal to METEORSETGEO height (rows)
1891 YUV12 - Even Only (or Odd Only) mode
1892 x_size must be greater than or equal to METEORSETGEO width (cols)
1893 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1896 case BT848_SCAPAREA: /* set capture area of each video frame */
1897 /* can't change parameters while capturing */
1898 if (bktr->flags & METEOR_CAP_MASK)
1901 cap_area = (struct bktr_capture_area *) arg;
1902 bktr->capture_area_x_offset = cap_area->x_offset;
1903 bktr->capture_area_y_offset = cap_area->y_offset;
1904 bktr->capture_area_x_size = cap_area->x_size;
1905 bktr->capture_area_y_size = cap_area->y_size;
1906 bktr->capture_area_enabled = TRUE;
1908 bktr->dma_prog_loaded = FALSE;
1911 case BT848_GCAPAREA: /* get capture area of each video frame */
1912 cap_area = (struct bktr_capture_area *) arg;
1913 if (bktr->capture_area_enabled == FALSE) {
1914 cap_area->x_offset = 0;
1915 cap_area->y_offset = 0;
1916 cap_area->x_size = format_params[
1917 bktr->format_params].scaled_hactive;
1918 cap_area->y_size = format_params[
1919 bktr->format_params].vactive;
1921 cap_area->x_offset = bktr->capture_area_x_offset;
1922 cap_area->y_offset = bktr->capture_area_y_offset;
1923 cap_area->x_size = bktr->capture_area_x_size;
1924 cap_area->y_size = bktr->capture_area_y_size;
1929 return common_ioctl( bktr, cmd, arg );
1939 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
1955 /* Read the last key pressed by the Remote Control */
1956 if (bktr->remote_control == 0) return (EINVAL);
1957 remote_read(bktr, (struct bktr_remote *)arg);
1960 #if defined( TUNER_AFC )
1961 case TVTUNER_SETAFC:
1962 bktr->tuner.afc = (*(int *)arg != 0);
1965 case TVTUNER_GETAFC:
1966 *(int *)arg = bktr->tuner.afc;
1967 /* XXX Perhaps use another bit to indicate AFC success? */
1969 #endif /* TUNER_AFC */
1971 case TVTUNER_SETCHNL:
1972 temp_mute( bktr, TRUE );
1973 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1975 temp_mute( bktr, FALSE );
1978 *(unsigned long *)arg = temp;
1980 /* after every channel change, we must restart the MSP34xx */
1981 /* audio chip to reselect NICAM STEREO or MONO audio */
1982 if ( bktr->card.msp3400c )
1983 msp_autodetect( bktr );
1985 /* after every channel change, we must restart the DPL35xx */
1986 if ( bktr->card.dpl3518a )
1987 dpl_autodetect( bktr );
1989 temp_mute( bktr, FALSE );
1992 case TVTUNER_GETCHNL:
1993 *(unsigned long *)arg = bktr->tuner.channel;
1996 case TVTUNER_SETTYPE:
1997 temp = *(unsigned long *)arg;
1998 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
2000 bktr->tuner.chnlset = temp;
2003 case TVTUNER_GETTYPE:
2004 *(unsigned long *)arg = bktr->tuner.chnlset;
2007 case TVTUNER_GETSTATUS:
2008 temp = get_tuner_status( bktr );
2009 *(unsigned long *)arg = temp & 0xff;
2012 case TVTUNER_SETFREQ:
2013 temp_mute( bktr, TRUE );
2014 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
2015 temp_mute( bktr, FALSE );
2017 temp_mute( bktr, FALSE );
2020 *(unsigned long *)arg = temp;
2022 /* after every channel change, we must restart the MSP34xx */
2023 /* audio chip to reselect NICAM STEREO or MONO audio */
2024 if ( bktr->card.msp3400c )
2025 msp_autodetect( bktr );
2027 /* after every channel change, we must restart the DPL35xx */
2028 if ( bktr->card.dpl3518a )
2029 dpl_autodetect( bktr );
2031 temp_mute( bktr, FALSE );
2034 case TVTUNER_GETFREQ:
2035 *(unsigned long *)arg = bktr->tuner.frequency;
2038 case TVTUNER_GETCHNLSET:
2039 return tuner_getchnlset((struct bktr_chnlset *)arg);
2041 case BT848_SAUDIO: /* set audio channel */
2042 if ( set_audio( bktr, *(int*)arg ) < 0 )
2046 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
2047 case BT848_SHUE: /* set hue */
2048 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
2051 case BT848_GHUE: /* get hue */
2052 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
2055 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
2056 case BT848_SBRIG: /* set brightness */
2057 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
2060 case BT848_GBRIG: /* get brightness */
2061 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2065 case BT848_SCSAT: /* set chroma saturation */
2066 tmp_int = *(int*)arg;
2068 temp = INB(bktr, BKTR_E_CONTROL);
2069 temp1 = INB(bktr, BKTR_O_CONTROL);
2070 if ( tmp_int & BIT_EIGHT_HIGH ) {
2071 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2072 BT848_E_CONTROL_SAT_V_MSB);
2073 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2074 BT848_O_CONTROL_SAT_V_MSB);
2077 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2078 BT848_E_CONTROL_SAT_V_MSB);
2079 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2080 BT848_O_CONTROL_SAT_V_MSB);
2083 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2084 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2085 OUTB(bktr, BKTR_E_CONTROL, temp);
2086 OUTB(bktr, BKTR_O_CONTROL, temp1);
2089 case BT848_GCSAT: /* get chroma saturation */
2090 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2091 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2092 tmp_int |= BIT_EIGHT_HIGH;
2093 *(int*)arg = tmp_int;
2097 case BT848_SVSAT: /* set chroma V saturation */
2098 tmp_int = *(int*)arg;
2100 temp = INB(bktr, BKTR_E_CONTROL);
2101 temp1 = INB(bktr, BKTR_O_CONTROL);
2102 if ( tmp_int & BIT_EIGHT_HIGH) {
2103 temp |= BT848_E_CONTROL_SAT_V_MSB;
2104 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2107 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2108 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2111 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2112 OUTB(bktr, BKTR_E_CONTROL, temp);
2113 OUTB(bktr, BKTR_O_CONTROL, temp1);
2116 case BT848_GVSAT: /* get chroma V saturation */
2117 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2118 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2119 tmp_int |= BIT_EIGHT_HIGH;
2120 *(int*)arg = tmp_int;
2124 case BT848_SUSAT: /* set chroma U saturation */
2125 tmp_int = *(int*)arg;
2127 temp = INB(bktr, BKTR_E_CONTROL);
2128 temp1 = INB(bktr, BKTR_O_CONTROL);
2129 if ( tmp_int & BIT_EIGHT_HIGH ) {
2130 temp |= BT848_E_CONTROL_SAT_U_MSB;
2131 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2134 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2135 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2138 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2139 OUTB(bktr, BKTR_E_CONTROL, temp);
2140 OUTB(bktr, BKTR_O_CONTROL, temp1);
2143 case BT848_GUSAT: /* get chroma U saturation */
2144 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2145 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2146 tmp_int |= BIT_EIGHT_HIGH;
2147 *(int*)arg = tmp_int;
2150 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2152 case BT848_SLNOTCH: /* set luma notch */
2153 tmp_int = (*(int *)arg & 0x7) << 5 ;
2154 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2155 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2156 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2157 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2160 case BT848_GLNOTCH: /* get luma notch */
2161 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2166 case BT848_SCONT: /* set contrast */
2167 tmp_int = *(int*)arg;
2169 temp = INB(bktr, BKTR_E_CONTROL);
2170 temp1 = INB(bktr, BKTR_O_CONTROL);
2171 if ( tmp_int & BIT_EIGHT_HIGH ) {
2172 temp |= BT848_E_CONTROL_CON_MSB;
2173 temp1 |= BT848_O_CONTROL_CON_MSB;
2176 temp &= ~BT848_E_CONTROL_CON_MSB;
2177 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2180 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2181 OUTB(bktr, BKTR_E_CONTROL, temp);
2182 OUTB(bktr, BKTR_O_CONTROL, temp1);
2185 case BT848_GCONT: /* get contrast */
2186 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2187 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2188 tmp_int |= BIT_EIGHT_HIGH;
2189 *(int*)arg = tmp_int;
2192 /* FIXME: SCBARS and CCBARS require a valid int * */
2193 /* argument to succeed, but its not used; consider */
2194 /* using the arg to store the on/off state so */
2195 /* there's only one ioctl() needed to turn cbars on/off */
2196 case BT848_SCBARS: /* set colorbar output */
2197 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2200 case BT848_CCBARS: /* clear colorbar output */
2201 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2204 case BT848_GAUDIO: /* get audio channel */
2205 temp = bktr->audio_mux_select;
2206 if ( bktr->audio_mute_state == TRUE )
2211 case BT848_SBTSC: /* set audio channel */
2212 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2216 case BT848_WEEPROM: /* write eeprom */
2217 offset = (((struct eeProm *)arg)->offset);
2218 count = (((struct eeProm *)arg)->count);
2219 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2220 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2224 case BT848_REEPROM: /* read eeprom */
2225 offset = (((struct eeProm *)arg)->offset);
2226 count = (((struct eeProm *)arg)->count);
2227 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2228 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2232 case BT848_SIGNATURE:
2233 offset = (((struct eeProm *)arg)->offset);
2234 count = (((struct eeProm *)arg)->count);
2235 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2236 if ( signCard( bktr, offset, count, buf ) < 0 )
2240 /* Ioctl's for direct gpio access */
2241 #ifdef BKTR_GPIO_ACCESS
2242 case BT848_GPIO_GET_EN:
2243 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2246 case BT848_GPIO_SET_EN:
2247 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2250 case BT848_GPIO_GET_DATA:
2251 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2254 case BT848_GPIO_SET_DATA:
2255 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2257 #endif /* BKTR_GPIO_ACCESS */
2259 /* Ioctl's for running the tuner device in radio mode */
2262 *(unsigned char *)arg = bktr->tuner.radio_mode;
2266 bktr->tuner.radio_mode = *(unsigned char *)arg;
2270 *(unsigned long *)arg = bktr->tuner.frequency;
2274 /* The argument to this ioctl is NOT freq*16. It is
2278 temp=(int)*(unsigned long *)arg;
2280 #ifdef BKTR_RADIO_DEBUG
2281 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2282 (int)*(unsigned long *)arg, temp);
2285 #ifndef BKTR_RADIO_NOFREQCHECK
2286 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2288 if(temp<8750 || temp>10800) {
2289 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2293 temp_mute( bktr, TRUE );
2294 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2295 temp_mute( bktr, FALSE );
2296 #ifdef BKTR_RADIO_DEBUG
2298 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2302 *(unsigned long *)arg = temp;
2305 /* Luigi's I2CWR ioctl */
2307 par = *(u_long *)arg;
2308 write = (par >> 24) & 0xff ;
2309 i2c_addr = (par >> 16) & 0xff ;
2310 i2c_port = (par >> 8) & 0xff ;
2311 data = (par) & 0xff ;
2314 i2cWrite( bktr, i2c_addr, i2c_port, data);
2316 data = i2cRead( bktr, i2c_addr);
2318 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2322 #ifdef BT848_MSP_READ
2323 /* I2C ioctls to allow userland access to the MSP chip */
2324 case BT848_MSP_READ:
2326 struct bktr_msp_control *msp;
2327 msp = (struct bktr_msp_control *) arg;
2328 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2329 msp->function, msp->address);
2333 case BT848_MSP_WRITE:
2335 struct bktr_msp_control *msp;
2336 msp = (struct bktr_msp_control *) arg;
2337 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2338 msp->address, msp->data );
2342 case BT848_MSP_RESET:
2343 msp_dpl_reset(bktr, bktr->msp_addr);
2348 return common_ioctl( bktr, cmd, arg );
2359 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2363 struct meteor_pixfmt *pf_pub;
2367 case METEORSINPUT: /* set input device */
2368 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2369 /* On the original bt848 boards, */
2370 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2371 /* On the Hauppauge bt878 boards, */
2372 /* Tuner is MUX0, RCA is MUX3 */
2373 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2374 /* stick with this system in our Meteor Emulation */
2376 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2378 /* this is the RCA video input */
2379 case 0: /* default */
2380 case METEOR_INPUT_DEV0:
2381 /* METEOR_INPUT_DEV_RCA: */
2382 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2384 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2385 & ~BT848_IFORM_MUXSEL);
2387 /* work around for new Hauppauge 878 cards */
2388 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2389 (bktr->id==BROOKTREE_878 ||
2390 bktr->id==BROOKTREE_879) )
2391 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2393 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2395 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2396 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2397 set_audio( bktr, AUDIO_EXTERN );
2400 /* this is the tuner input */
2401 case METEOR_INPUT_DEV1:
2402 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2404 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2405 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2406 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2407 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2408 set_audio( bktr, AUDIO_TUNER );
2411 /* this is the S-VHS input, but with a composite camera */
2412 case METEOR_INPUT_DEV2:
2413 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2415 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2416 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2417 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2418 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2419 set_audio( bktr, AUDIO_EXTERN );
2422 /* this is the S-VHS input */
2423 case METEOR_INPUT_DEV_SVIDEO:
2424 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2425 | METEOR_DEV_SVIDEO;
2426 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2427 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2428 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2429 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2430 set_audio( bktr, AUDIO_EXTERN );
2433 case METEOR_INPUT_DEV3:
2434 if ((bktr->id == BROOKTREE_848A) ||
2435 (bktr->id == BROOKTREE_849A) ||
2436 (bktr->id == BROOKTREE_878) ||
2437 (bktr->id == BROOKTREE_879) ) {
2438 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2440 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2442 /* work around for new Hauppauge 878 cards */
2443 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2444 (bktr->id==BROOKTREE_878 ||
2445 bktr->id==BROOKTREE_879) )
2446 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2448 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2450 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2451 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2452 set_audio( bktr, AUDIO_EXTERN );
2462 case METEORGINPUT: /* get input device */
2463 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2466 case METEORSACTPIXFMT:
2467 if (( *(int *)arg < 0 ) ||
2468 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2471 bktr->pixfmt = *(int *)arg;
2472 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2473 | pixfmt_swap_flags( bktr->pixfmt ));
2474 bktr->pixfmt_compat = FALSE;
2477 case METEORGACTPIXFMT:
2478 *(int *)arg = bktr->pixfmt;
2481 case METEORGSUPPIXFMT :
2482 pf_pub = (struct meteor_pixfmt *)arg;
2483 pixfmt = pf_pub->index;
2485 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2488 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2489 sizeof( *pf_pub ) );
2491 /* Patch in our format index */
2492 pf_pub->index = pixfmt;
2495 #if defined( STATUS_SUM )
2496 case BT848_GSTATUS: /* reap status */
2498 DECLARE_INTR_MASK(s);
2503 *(u_int*)arg = temp;
2506 #endif /* STATUS_SUM */
2518 /******************************************************************************
2519 * bt848 RISC programming routines:
2528 dump_bt848( bktr_ptr_t bktr )
2531 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2532 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2533 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2534 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2535 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2540 for (i = 0; i < 40; i+=4) {
2541 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2543 r[i], INL(bktr, r[i]),
2544 r[i+1], INL(bktr, r[i+1]),
2545 r[i+2], INL(bktr, r[i+2]),
2546 r[i+3], INL(bktr, r[i+3]]));
2549 printf("%s: INT STAT %x \n", bktr_name(bktr),
2550 INL(bktr, BKTR_INT_STAT));
2551 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2552 INL(bktr, BKTR_INT_MASK));
2553 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2554 INW(bktr, BKTR_GPIO_DMA_CTL));
2562 * build write instruction
2564 #define BKTR_FM1 0x6 /* packed data to follow */
2565 #define BKTR_FM3 0xe /* planar data to follow */
2566 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2567 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2568 #define BKTR_PXV 0x0 /* valid word (never used) */
2569 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2570 #define BKTR_SOL 0x2 /* first dword */
2572 #define OP_WRITE (0x1 << 28)
2573 #define OP_SKIP (0x2 << 28)
2574 #define OP_WRITEC (0x5 << 28)
2575 #define OP_JUMP (0x7 << 28)
2576 #define OP_SYNC (0x8 << 28)
2577 #define OP_WRITE123 (0x9 << 28)
2578 #define OP_WRITES123 (0xb << 28)
2579 #define OP_SOL (1 << 27) /* first instr for scanline */
2580 #define OP_EOL (1 << 26)
2582 #define BKTR_RESYNC (1 << 15)
2583 #define BKTR_GEN_IRQ (1 << 24)
2586 * The RISC status bits can be set/cleared in the RISC programs
2587 * and tested in the Interrupt Handler
2589 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2590 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2591 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2592 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2594 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2595 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2596 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2597 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2599 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2600 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2601 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2602 #define BKTR_TEST_RISC_STATUS_BIT3 (1U << 31)
2604 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2606 bktr_clip_t * clip_node;
2607 bktr->clip_start = -1;
2611 bktr->line_length = width;
2614 bktr->current_col = 0;
2616 if (bktr->max_clip_node == 0 ) return TRUE;
2617 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2620 for (i = 0; i < bktr->max_clip_node; i++ ) {
2621 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2622 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2623 bktr->clip_start = i;
2631 static bool_t getline(bktr_reg_t *bktr, int x ) {
2633 bktr_clip_t * clip_node ;
2635 if (bktr->line_length == 0 ||
2636 bktr->current_col >= bktr->line_length) return FALSE;
2638 bktr->y = min(bktr->last_y, bktr->line_length);
2639 bktr->y2 = bktr->line_length;
2641 bktr->yclip = bktr->yclip2 = -1;
2642 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2643 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2644 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2645 if (bktr->last_y <= clip_node->y_min) {
2646 bktr->y = min(bktr->last_y, bktr->line_length);
2647 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2648 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2649 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2650 bktr->last_y = bktr->yclip2;
2651 bktr->clip_start = i;
2653 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2654 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2655 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2656 if (bktr->last_y >= clip_node->y_min) {
2657 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2658 bktr->last_y = bktr->yclip2;
2659 bktr->clip_start = j;
2668 if (bktr->current_col <= bktr->line_length) {
2669 bktr->current_col = bktr->line_length;
2675 static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width ,
2676 u_long operation, int pixel_width,
2677 volatile u_char ** target_buffer, int cols ) {
2680 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2681 u_int skip, start_skip;
2683 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2684 /* to the 1st byte in the mem dword containing our start addr. */
2685 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2688 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2689 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2690 case 2 : start_skip = 4 ; break;
2691 case 1 : start_skip = 8 ; break;
2694 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2695 if ( width == cols) {
2696 flag = OP_SOL | OP_EOL;
2697 } else if (bktr->current_col == 0 ) {
2699 } else if (bktr->current_col == cols) {
2704 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2705 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2710 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2711 if (operation != OP_SKIP )
2712 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2714 *target_buffer += width * pixel_width;
2715 bktr->current_col += width;
2719 if (bktr->current_col == 0 && width == cols) {
2722 } else if (bktr->current_col == 0 ) {
2725 } else if (bktr->current_col >= cols) {
2734 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2735 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2740 *(*dma_prog)++ = operation | flag |
2741 (width * pixel_width / 2 - skip);
2742 if (operation != OP_SKIP )
2743 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2744 *target_buffer += (width * pixel_width / 2) ;
2746 if ( operation == OP_WRITE )
2747 operation = OP_WRITEC;
2748 *(*dma_prog)++ = operation | flag2 |
2749 (width * pixel_width / 2);
2750 *target_buffer += (width * pixel_width / 2) ;
2751 bktr->current_col += width;
2759 * Generate the RISC instructions to capture both VBI and video images
2762 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2765 volatile uint32_t target_buffer, buffer, target,width;
2766 volatile uint32_t pitch;
2767 volatile uint32_t *dma_prog; /* DMA prog is an array of
2768 32 bit RISC instructions */
2769 volatile uint32_t *loop_point;
2770 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2771 u_int Bpp = pf_int->public.Bpp;
2772 unsigned int vbisamples; /* VBI samples per line */
2773 unsigned int vbilines; /* VBI lines per field */
2774 unsigned int num_dwords; /* DWORDS per line */
2776 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2777 vbilines = format_params[bktr->format_params].vbi_num_lines;
2778 num_dwords = vbisamples/4;
2780 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2781 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2782 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2783 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2786 OUTB(bktr, BKTR_OFORM, 0x00);
2788 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2789 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2790 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2791 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2793 /* disable gamma correction removal */
2794 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2797 OUTB(bktr, BKTR_E_VTC, 0);
2798 OUTB(bktr, BKTR_O_VTC, 0);
2800 OUTB(bktr, BKTR_E_VTC, 1);
2801 OUTB(bktr, BKTR_O_VTC, 1);
2803 bktr->capcontrol = 3 << 2 | 3;
2805 dma_prog = (uint32_t *) bktr->dma_prog;
2807 /* Construct Write */
2809 if (bktr->video.addr) {
2810 target_buffer = (u_long) bktr->video.addr;
2811 pitch = bktr->video.width;
2814 target_buffer = (u_long) vtophys(bktr->bigbuf);
2818 buffer = target_buffer;
2820 /* Wait for the VRE sync marking the end of the Even and
2821 * the start of the Odd field. Resync here.
2823 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2826 loop_point = dma_prog;
2828 /* store the VBI data */
2829 /* look for sync with packed data */
2830 *dma_prog++ = OP_SYNC | BKTR_FM1;
2832 for(i = 0; i < vbilines; i++) {
2833 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2834 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2835 (i * VBI_LINE_SIZE));
2838 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2839 /* store the Odd field video image */
2840 /* look for sync with packed data */
2841 *dma_prog++ = OP_SYNC | BKTR_FM1;
2842 *dma_prog++ = 0; /* NULL WORD */
2844 for (i = 0; i < (rows/interlace); i++) {
2845 target = target_buffer;
2846 if ( notclipped(bktr, i, width)) {
2847 split(bktr, (volatile uint32_t **) &dma_prog,
2848 bktr->y2 - bktr->y, OP_WRITE,
2849 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2852 while(getline(bktr, i)) {
2853 if (bktr->y != bktr->y2 ) {
2854 split(bktr, (volatile uint32_t **) &dma_prog,
2855 bktr->y2 - bktr->y, OP_WRITE,
2856 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2858 if (bktr->yclip != bktr->yclip2 ) {
2859 split(bktr,(volatile uint32_t **) &dma_prog,
2860 bktr->yclip2 - bktr->yclip,
2862 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2868 target_buffer += interlace * pitch;
2874 /* Grab the Even field */
2875 /* Look for the VRO, end of Odd field, marker */
2876 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2877 *dma_prog++ = 0; /* NULL WORD */
2879 /* store the VBI data */
2880 /* look for sync with packed data */
2881 *dma_prog++ = OP_SYNC | BKTR_FM1;
2883 for(i = 0; i < vbilines; i++) {
2884 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2885 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2886 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2889 /* store the video image */
2890 if (i_flag == 1) /*Even Only*/
2891 target_buffer = buffer;
2892 if (i_flag == 3) /*interlaced*/
2893 target_buffer = buffer+pitch;
2896 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2897 /* look for sync with packed data */
2898 *dma_prog++ = OP_SYNC | BKTR_FM1;
2899 *dma_prog++ = 0; /* NULL WORD */
2901 for (i = 0; i < (rows/interlace); i++) {
2902 target = target_buffer;
2903 if ( notclipped(bktr, i, width)) {
2904 split(bktr, (volatile uint32_t **) &dma_prog,
2905 bktr->y2 - bktr->y, OP_WRITE,
2906 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2908 while(getline(bktr, i)) {
2909 if (bktr->y != bktr->y2 ) {
2910 split(bktr, (volatile uint32_t **) &dma_prog,
2911 bktr->y2 - bktr->y, OP_WRITE,
2912 Bpp, (volatile u_char **)(uintptr_t)&target,
2915 if (bktr->yclip != bktr->yclip2 ) {
2916 split(bktr, (volatile uint32_t **) &dma_prog,
2917 bktr->yclip2 - bktr->yclip, OP_SKIP,
2918 Bpp, (volatile u_char **)(uintptr_t) &target, cols);
2925 target_buffer += interlace * pitch;
2930 /* Look for end of 'Even Field' */
2931 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2932 *dma_prog++ = 0; /* NULL WORD */
2934 *dma_prog++ = OP_JUMP ;
2935 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2936 *dma_prog++ = 0; /* NULL WORD */
2944 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2947 volatile uint32_t target_buffer, buffer, target,width;
2948 volatile uint32_t pitch;
2949 volatile uint32_t *dma_prog;
2950 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2951 u_int Bpp = pf_int->public.Bpp;
2953 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2954 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2955 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2956 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2958 OUTB(bktr, BKTR_OFORM, 0x00);
2960 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2961 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2962 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2963 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2965 /* disable gamma correction removal */
2966 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2969 OUTB(bktr, BKTR_E_VTC, 0);
2970 OUTB(bktr, BKTR_O_VTC, 0);
2972 OUTB(bktr, BKTR_E_VTC, 1);
2973 OUTB(bktr, BKTR_O_VTC, 1);
2975 bktr->capcontrol = 3 << 2 | 3;
2977 dma_prog = (uint32_t *) bktr->dma_prog;
2979 /* Construct Write */
2981 if (bktr->video.addr) {
2982 target_buffer = (uint32_t) bktr->video.addr;
2983 pitch = bktr->video.width;
2986 target_buffer = (uint32_t) vtophys(bktr->bigbuf);
2990 buffer = target_buffer;
2992 /* contruct sync : for video packet format */
2993 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2995 /* sync, mode indicator packed data */
2996 *dma_prog++ = 0; /* NULL WORD */
2998 for (i = 0; i < (rows/interlace); i++) {
2999 target = target_buffer;
3000 if ( notclipped(bktr, i, width)) {
3001 split(bktr, (volatile uint32_t **) &dma_prog,
3002 bktr->y2 - bktr->y, OP_WRITE,
3003 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3006 while(getline(bktr, i)) {
3007 if (bktr->y != bktr->y2 ) {
3008 split(bktr, (volatile uint32_t **) &dma_prog,
3009 bktr->y2 - bktr->y, OP_WRITE,
3010 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3012 if (bktr->yclip != bktr->yclip2 ) {
3013 split(bktr,(volatile uint32_t **) &dma_prog,
3014 bktr->yclip2 - bktr->yclip,
3016 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3022 target_buffer += interlace * pitch;
3029 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3030 *dma_prog++ = 0; /* NULL WORD */
3032 *dma_prog++ = OP_JUMP;
3033 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
3038 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3039 *dma_prog++ = 0; /* NULL WORD */
3041 *dma_prog++ = OP_JUMP;
3042 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog);
3047 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3048 *dma_prog++ = 0; /* NULL WORD */
3049 *dma_prog++ = OP_JUMP; ;
3050 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog);
3054 if (interlace == 2) {
3056 target_buffer = buffer + pitch;
3058 dma_prog = (uint32_t *) bktr->odd_dma_prog;
3060 /* sync vre IRQ bit */
3061 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3062 *dma_prog++ = 0; /* NULL WORD */
3064 for (i = 0; i < (rows/interlace); i++) {
3065 target = target_buffer;
3066 if ( notclipped(bktr, i, width)) {
3067 split(bktr, (volatile uint32_t **) &dma_prog,
3068 bktr->y2 - bktr->y, OP_WRITE,
3069 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3071 while(getline(bktr, i)) {
3072 if (bktr->y != bktr->y2 ) {
3073 split(bktr, (volatile uint32_t **) &dma_prog,
3074 bktr->y2 - bktr->y, OP_WRITE,
3075 Bpp, (volatile u_char **)(uintptr_t)&target,
3078 if (bktr->yclip != bktr->yclip2 ) {
3079 split(bktr, (volatile uint32_t **) &dma_prog,
3080 bktr->yclip2 - bktr->yclip, OP_SKIP,
3081 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3088 target_buffer += interlace * pitch;
3093 /* sync vre IRQ bit */
3094 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3095 *dma_prog++ = 0; /* NULL WORD */
3096 *dma_prog++ = OP_JUMP ;
3097 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ;
3098 *dma_prog++ = 0; /* NULL WORD */
3106 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3107 int cols, int rows, int interlace )
3110 volatile unsigned int inst;
3111 volatile unsigned int inst3;
3112 volatile uint32_t target_buffer, buffer;
3113 volatile uint32_t *dma_prog;
3114 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3117 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3119 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3120 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3122 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3123 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3125 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
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));
3713 set_fps( bktr_ptr_t bktr, u_short fps )
3715 struct format_params *fp;
3718 fp = &format_params[bktr->format_params];
3720 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3721 case METEOR_ONLY_EVEN_FIELDS:
3722 bktr->flags |= METEOR_WANT_EVEN;
3725 case METEOR_ONLY_ODD_FIELDS:
3726 bktr->flags |= METEOR_WANT_ODD;
3730 bktr->flags |= METEOR_WANT_MASK;
3735 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3736 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3739 OUTB(bktr, BKTR_TDEC, 0);
3741 if (fps < fp->frame_rate)
3742 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3744 OUTB(bktr, BKTR_TDEC, 0);
3754 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3755 * achieve the specified swapping.
3756 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3757 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3759 * Note also that for 3Bpp, we may additionally need to do some creative
3760 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3761 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3762 * as one would expect.
3765 static u_int pixfmt_swap_flags( int pixfmt )
3767 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3770 switch ( pf->Bpp ) {
3771 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3774 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3777 case 4 : if ( pf->swap_bytes )
3778 swapf = pf->swap_shorts ? 0 : WSWAP;
3780 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3789 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3790 * our pixfmt_table indices.
3793 static int oformat_meteor_to_bt( u_long format )
3796 struct meteor_pixfmt *pf1, *pf2;
3798 /* Find format in compatibility table */
3799 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3800 if ( meteor_pixfmt_table[i].meteor_format == format )
3803 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3805 pf1 = &meteor_pixfmt_table[i].public;
3807 /* Match it with an entry in master pixel format table */
3808 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3809 pf2 = &pixfmt_table[i].public;
3811 if (( pf1->type == pf2->type ) &&
3812 ( pf1->Bpp == pf2->Bpp ) &&
3813 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3814 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3815 ( pf1->swap_shorts == pf2->swap_shorts ))
3818 if ( i >= PIXFMT_TABLE_SIZE )
3824 /******************************************************************************
3829 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3830 #define I2CBITTIME_878 (1 << 7)
3831 #define I2C_READ 0x01
3832 #define I2C_COMMAND (I2CBITTIME | \
3833 BT848_DATA_CTL_I2CSCL | \
3834 BT848_DATA_CTL_I2CSDA)
3836 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3837 BT848_DATA_CTL_I2CSCL | \
3838 BT848_DATA_CTL_I2CSDA)
3840 /* Select between old i2c code and new iicbus / smbus code */
3841 #if defined(BKTR_USE_FREEBSD_SMBUS)
3844 * The hardware interface is actually SMB commands
3847 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3851 if (bktr->id == BROOKTREE_848 ||
3852 bktr->id == BROOKTREE_848A ||
3853 bktr->id == BROOKTREE_849A)
3856 cmd = I2C_COMMAND_878;
3859 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3860 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3863 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3864 (char)(byte1 & 0xff)))
3873 i2cRead( bktr_ptr_t bktr, int addr )
3878 if (bktr->id == BROOKTREE_848 ||
3879 bktr->id == BROOKTREE_848A ||
3880 bktr->id == BROOKTREE_849A)
3883 cmd = I2C_COMMAND_878;
3885 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3888 return ((int)((unsigned char)result));
3891 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbb)
3893 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3894 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3895 /* Therefore we need low level control of the i2c bus hardware */
3897 /* Write to the MSP or DPL registers */
3899 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3901 unsigned char addr_l, addr_h, data_h, data_l ;
3903 addr_h = (addr >>8) & 0xff;
3904 addr_l = addr & 0xff;
3905 data_h = (data >>8) & 0xff;
3906 data_l = data & 0xff;
3908 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3910 iicbus_write_byte(IICBUS(bktr), dev, 0);
3911 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3912 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3913 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3914 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3916 iicbus_stop(IICBUS(bktr));
3921 /* Read from the MSP or DPL registers */
3923 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3926 unsigned char addr_l, addr_h, dev_r;
3928 u_char data_read[2];
3930 addr_h = (addr >>8) & 0xff;
3931 addr_l = addr & 0xff;
3934 /* XXX errors ignored */
3935 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3937 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3938 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3939 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3941 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3942 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3943 iicbus_stop(IICBUS(bktr));
3945 data = (data_read[0]<<8) | data_read[1];
3950 /* Reset the MSP or DPL chip */
3951 /* The user can block the reset (which is handy if you initialise the
3952 * MSP and/or DPL audio in another operating system first (eg in Windows)
3955 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3958 #ifndef BKTR_NO_MSP_RESET
3959 /* put into reset mode */
3960 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3961 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3962 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3963 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3964 iicbus_stop(IICBUS(bktr));
3966 /* put back to operational mode */
3967 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3968 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3969 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3970 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3971 iicbus_stop(IICBUS(bktr));
3976 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3979 /* XXX errors ignored */
3980 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3981 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3982 iicbus_stop(IICBUS(bktr));
3987 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3990 * Program the i2c bus directly
3993 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3998 /* clear status bits */
3999 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4001 /* build the command datum */
4002 if (bktr->id == BROOKTREE_848 ||
4003 bktr->id == BROOKTREE_848A ||
4004 bktr->id == BROOKTREE_849A) {
4005 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
4007 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
4009 if ( byte2 != -1 ) {
4010 data |= ((byte2 & 0xff) << 8);
4011 data |= BT848_DATA_CTL_I2CW3B;
4014 /* write the address and data */
4015 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
4017 /* wait for completion */
4018 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4019 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4024 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4036 i2cRead( bktr_ptr_t bktr, int addr )
4040 /* clear status bits */
4041 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4043 /* write the READ address */
4044 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
4046 if (bktr->id == BROOKTREE_848 ||
4047 bktr->id == BROOKTREE_848A ||
4048 bktr->id == BROOKTREE_849A) {
4049 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
4051 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
4054 /* wait for completion */
4055 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4056 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4061 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4065 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4068 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4069 /* bt848 automated i2c bus controller cannot handle */
4070 /* Therefore we need low level control of the i2c bus hardware */
4071 /* Idea for the following functions are from elsewhere in this driver and */
4072 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4075 static void i2c_start( bktr_ptr_t bktr) {
4076 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4077 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4078 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4079 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4082 static void i2c_stop( bktr_ptr_t bktr) {
4083 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4084 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4085 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4088 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4092 /* write out the byte */
4093 for ( x = 7; x >= 0; --x ) {
4094 if ( data & (1<<x) ) {
4095 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4096 DELAY( BITD ); /* assert HI data */
4097 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4098 DELAY( BITD ); /* strobe clock */
4099 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4100 DELAY( BITD ); /* release clock */
4103 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4104 DELAY( BITD ); /* assert LO data */
4105 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4106 DELAY( BITD ); /* strobe clock */
4107 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4108 DELAY( BITD ); /* release clock */
4112 /* look for an ACK */
4113 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4114 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4115 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4116 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4121 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4126 /* read in the byte */
4127 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4128 DELAY( BITD ); /* float data */
4129 for ( x = 7; x >= 0; --x ) {
4130 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4131 DELAY( BITD ); /* strobe clock */
4132 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4133 if ( bit ) byte |= (1<<x);
4134 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4135 DELAY( BITD ); /* release clock */
4137 /* After reading the byte, send an ACK */
4138 /* (unless that was the last byte, for which we send a NAK */
4139 if (last) { /* send NAK - same a writing a 1 */
4140 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4141 DELAY( BITD ); /* set data bit */
4142 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4143 DELAY( BITD ); /* strobe clock */
4144 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4145 DELAY( BITD ); /* release clock */
4146 } else { /* send ACK - same as writing a 0 */
4147 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4148 DELAY( BITD ); /* set data bit */
4149 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4150 DELAY( BITD ); /* strobe clock */
4151 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4152 DELAY( BITD ); /* release clock */
4160 /* Write to the MSP or DPL registers */
4161 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4163 unsigned int msp_w_addr = i2c_addr;
4164 unsigned char addr_l, addr_h, data_h, data_l ;
4165 addr_h = (addr >>8) & 0xff;
4166 addr_l = addr & 0xff;
4167 data_h = (data >>8) & 0xff;
4168 data_l = data & 0xff;
4171 i2c_write_byte(bktr, msp_w_addr);
4172 i2c_write_byte(bktr, dev);
4173 i2c_write_byte(bktr, addr_h);
4174 i2c_write_byte(bktr, addr_l);
4175 i2c_write_byte(bktr, data_h);
4176 i2c_write_byte(bktr, data_l);
4180 /* Read from the MSP or DPL registers */
4181 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4183 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4184 addr_h = (addr >>8) & 0xff;
4185 addr_l = addr & 0xff;
4189 i2c_write_byte(bktr,i2c_addr);
4190 i2c_write_byte(bktr,dev_r);
4191 i2c_write_byte(bktr,addr_h);
4192 i2c_write_byte(bktr,addr_l);
4195 i2c_write_byte(bktr,i2c_addr+1);
4196 i2c_read_byte(bktr,&data_1, 0);
4197 i2c_read_byte(bktr,&data_2, 1);
4199 data = (data_1<<8) | data_2;
4203 /* Reset the MSP or DPL chip */
4204 /* The user can block the reset (which is handy if you initialise the
4205 * MSP audio in another operating system first (eg in Windows)
4207 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4209 #ifndef BKTR_NO_MSP_RESET
4210 /* put into reset mode */
4212 i2c_write_byte(bktr, i2c_addr);
4213 i2c_write_byte(bktr, 0x00);
4214 i2c_write_byte(bktr, 0x80);
4215 i2c_write_byte(bktr, 0x00);
4218 /* put back to operational mode */
4220 i2c_write_byte(bktr, i2c_addr);
4221 i2c_write_byte(bktr, 0x00);
4222 i2c_write_byte(bktr, 0x00);
4223 i2c_write_byte(bktr, 0x00);
4230 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4232 /* XXX errors ignored */
4234 i2c_write_byte(bktr,bktr->remote_control_addr);
4235 i2c_read_byte(bktr,&(remote->data[0]), 0);
4236 i2c_read_byte(bktr,&(remote->data[1]), 0);
4237 i2c_read_byte(bktr,&(remote->data[2]), 0);
4243 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4246 #if defined( I2C_SOFTWARE_PROBE )
4249 * we are keeping this around for any parts that we need to probe
4250 * but that CANNOT be probed via an i2c read.
4251 * this is necessary because the hardware i2c mechanism
4252 * cannot be programmed for 1 byte writes.
4253 * currently there are no known i2c parts that we need to probe
4254 * and that cannot be safely read.
4256 static int i2cProbe( bktr_ptr_t bktr, int addr );
4261 * probe for an I2C device at addr.
4264 i2cProbe( bktr_ptr_t bktr, int addr )
4269 #if defined( EXTRA_START )
4270 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4271 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4272 #endif /* EXTRA_START */
4273 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4274 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4277 for ( x = 7; x >= 0; --x ) {
4278 if ( addr & (1<<x) ) {
4279 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4280 DELAY( BITD ); /* assert HI data */
4281 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4282 DELAY( BITD ); /* strobe clock */
4283 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4284 DELAY( BITD ); /* release clock */
4287 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4288 DELAY( BITD ); /* assert LO data */
4289 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4290 DELAY( BITD ); /* strobe clock */
4291 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4292 DELAY( BITD ); /* release clock */
4296 /* look for an ACK */
4297 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4298 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4299 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4300 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4303 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4304 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4305 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4312 #endif /* I2C_SOFTWARE_PROBE */
4317 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */