1 /* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.103.2.4 2000/11/01 09:36:14 roger Exp $ */
2 /* $DragonFly: src/sys/dev/video/bktr/bktr_core.c,v 1.5 2003/08/07 21:17:15 dillon Exp $ */
5 * This is part of the Driver for Video Capture Cards (Frame grabbers)
6 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
8 * Copyright Roger Hardiman and Amancio Hasty.
10 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
11 * Handles all the open, close, ioctl and read userland calls.
12 * Sets the Bt848 registers and generates RISC pograms.
13 * Controls the i2c bus and GPIO interface.
14 * Contains the interface to the kernel.
15 * (eg probe/attach and open/close/ioctl)
20 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
21 Jim Lowe's driver for the Matrox Meteor PCI card . The
22 Philips SAA 7116 and SAA 7196 are very different chipsets than
25 The original copyright notice by Mark and Jim is included mostly
26 to honor their fantastic work in the Matrox Meteor driver!
31 * 1. Redistributions of source code must retain the
32 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
33 * All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed by Amancio Hasty and
47 * 4. The name of the author may not be used to endorse or promote products
48 * derived from this software without specific prior written permission.
50 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
51 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
54 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
55 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
56 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
58 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
59 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 * POSSIBILITY OF SUCH DAMAGE.
67 * 1. Redistributions of source code must retain the
68 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
69 * All rights reserved.
71 * Redistribution and use in source and binary forms, with or without
72 * modification, are permitted provided that the following conditions
74 * 1. Redistributions of source code must retain the above copyright
75 * notice, this list of conditions and the following disclaimer.
76 * 2. Redistributions in binary form must reproduce the above copyright
77 * notice, this list of conditions and the following disclaimer in the
78 * documentation and/or other materials provided with the distribution.
79 * 3. All advertising materials mentioning features or use of this software
80 * must display the following acknowledgement:
81 * This product includes software developed by Mark Tinguely and Jim Lowe
82 * 4. The name of the author may not be used to endorse or promote products
83 * derived from this software without specific prior written permission.
85 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
86 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
89 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
91 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
92 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
93 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
94 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
95 * POSSIBILITY OF SUCH DAMAGE.
98 #include "opt_bktr.h" /* Include any kernel config options */
101 #include "use_bktr.h"
102 #endif /* __FreeBSD__ */
105 (defined(__FreeBSD__) && (NBKTR > 0)) \
106 || (defined(__bsdi__)) \
107 || (defined(__OpenBSD__)) \
108 || (defined(__NetBSD__)) \
112 /*******************/
113 /* *** FreeBSD *** */
114 /*******************/
117 #include <sys/param.h>
118 #include <sys/systm.h>
119 #include <sys/kernel.h>
120 #include <sys/signalvar.h>
121 #include <sys/vnode.h>
124 #include <vm/vm_kern.h>
126 #include <vm/vm_extern.h>
128 #if (__FreeBSD_version >=400000) || (NSMBUS > 0)
129 #include <sys/bus.h> /* used by smbus and newbus */
132 #if (__FreeBSD_version < 500000)
133 #include <machine/clock.h> /* for DELAY */
136 #include <bus/pci/pcivar.h>
138 #if (__FreeBSD_version >=300000)
139 #include <machine/bus_memio.h> /* for bus space */
140 #include <machine/bus.h>
144 #include <machine/ioctl_meteor.h>
145 #include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
146 #include "bktr_reg.h"
147 #include "bktr_tuner.h"
148 #include "bktr_card.h"
149 #include "bktr_audio.h"
151 #include "bktr_core.h"
152 #if defined(BKTR_FREEBSD_MODULE)
153 #include "bktr_mem.h"
156 #if defined(BKTR_USE_FREEBSD_SMBUS)
157 #include "bktr_i2c.h"
158 #include <bus/smbus/smbconf.h>
159 #include <bus/iicbus/iiconf.h>
160 #include "smbus_if.h"
161 #include "iicbus_if.h"
165 bktr_name(bktr_ptr_t bktr)
167 return bktr->bktr_xname;
171 #if (__FreeBSD__ == 2)
172 typedef unsigned int uintptr_t;
174 #endif /* __FreeBSD__ */
181 #endif /* __bsdi__ */
184 /**************************/
185 /* *** OpenBSD/NetBSD *** */
186 /**************************/
187 #if defined(__NetBSD__) || defined(__OpenBSD__)
189 #include <sys/param.h>
190 #include <sys/systm.h>
191 #include <sys/kernel.h>
192 #include <sys/signalvar.h>
193 #include <sys/vnode.h>
196 #include <uvm/uvm_extern.h>
199 #include <vm/vm_kern.h>
201 #include <vm/vm_extern.h>
204 #include <sys/inttypes.h> /* uintptr_t */
205 #include <dev/ic/bt8xx.h>
206 #include <dev/pci/bktr/bktr_reg.h>
207 #include <dev/pci/bktr/bktr_tuner.h>
208 #include <dev/pci/bktr/bktr_card.h>
209 #include <dev/pci/bktr/bktr_audio.h>
210 #include <dev/pci/bktr/bktr_core.h>
211 #include <dev/pci/bktr/bktr_os.h>
213 static int bt848_format = -1;
216 bktr_name(bktr_ptr_t bktr)
218 return (bktr->bktr_dev.dv_xname);
221 #endif /* __NetBSD__ || __OpenBSD__ */
225 typedef u_char bool_t;
228 * memory allocated for DMA programs
230 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
232 /* When to split a dma transfer , the bt848 has timing as well as
233 dma transfer size limitations so that we have to split dma
234 transfers into two dma requests
236 #define DMA_BT848_SPLIT 319*2
239 * Allocate enough memory for:
240 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
242 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
243 * in your kernel configuration file.
246 #ifndef BROOKTREE_ALLOC_PAGES
247 #define BROOKTREE_ALLOC_PAGES 217*4
249 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
251 /* Definitions for VBI capture.
252 * There are 16 VBI lines in a PAL video field (32 in a frame),
253 * and we take 2044 samples from each line (placed in a 2048 byte buffer
255 * VBI lines are held in a circular buffer before being read by a
256 * user program from /dev/vbi.
259 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
260 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
261 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
262 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
263 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
266 /* Defines for fields */
272 * Parameters describing size of transmitted image.
275 static struct format_params format_params[] = {
276 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
277 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
279 /* # define BT848_IFORM_F_NTSCM (0x1) */
280 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
282 /* # define BT848_IFORM_F_NTSCJ (0x2) */
283 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
285 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
286 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
288 /* # define BT848_IFORM_F_PALM (0x4) */
289 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
291 /* # define BT848_IFORM_F_PALN (0x5) */
292 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
294 /* # define BT848_IFORM_F_SECAM (0x6) */
295 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
297 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
298 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
303 * Table of supported Pixel Formats
306 static struct meteor_pixfmt_internal {
307 struct meteor_pixfmt public;
311 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
312 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
314 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
315 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
317 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
319 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
320 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
321 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
322 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
323 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
324 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
325 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
328 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
331 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
334 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
336 u_long meteor_format;
337 struct meteor_pixfmt public;
338 } meteor_pixfmt_table[] = {
340 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
343 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
344 { METEOR_GEO_YUV_422,
345 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
347 { METEOR_GEO_YUV_PACKED,
348 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
351 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
354 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
358 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
359 sizeof(meteor_pixfmt_table[0]) )
362 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
363 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
367 /* sync detect threshold */
369 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
370 BT848_ADC_CRUSH) /* threshold ~125 mV */
372 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
373 BT848_ADC_SYNC_T) /* threshold ~75 mV */
379 /* debug utility for holding previous INT_STAT contents */
381 static u_long status_sum = 0;
384 * defines to make certain bit-fiddles understandable
386 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
387 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
388 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
389 #define FIFO_RISC_DISABLED 0
391 #define ALL_INTS_DISABLED 0
392 #define ALL_INTS_CLEARED 0xffffffff
393 #define CAPTURE_OFF 0
395 #define BIT_SEVEN_HIGH (1<<7)
396 #define BIT_EIGHT_HIGH (1<<8)
398 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
399 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
403 static int oformat_meteor_to_bt( u_long format );
405 static u_int pixfmt_swap_flags( int pixfmt );
408 * bt848 RISC programming routines.
411 static int dump_bt848( bktr_ptr_t bktr );
414 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
415 int rows, int interlace );
416 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
417 int rows, int interlace );
418 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
419 int rows, int interlace );
420 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
421 int rows, int interlace );
422 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
423 int rows, int interlace );
424 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
426 static bool_t getline(bktr_reg_t *, int);
427 static bool_t notclipped(bktr_reg_t * , int , int);
428 static bool_t split(bktr_reg_t *, volatile u_long **, int, u_long, int,
429 volatile u_char ** , int );
431 static void start_capture( bktr_ptr_t bktr, unsigned type );
432 static void set_fps( bktr_ptr_t bktr, u_short fps );
437 * Remote Control Functions
439 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
443 * ioctls common to both video & tuner.
445 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
448 #if !defined(BKTR_USE_FREEBSD_SMBUS)
450 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
452 static void i2c_start( bktr_ptr_t bktr);
453 static void i2c_stop( bktr_ptr_t bktr);
454 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
455 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
461 * the common attach code, used by all OS versions.
464 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
467 int need_to_allocate_memory = 1;
469 /***************************************/
470 /* *** OS Specific memory routines *** */
471 /***************************************/
472 #if defined(__NetBSD__) || defined(__OpenBSD__)
473 /* allocate space for dma program */
474 bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog,
476 bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
479 /* allocate space for the VBI buffer */
480 bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata,
482 bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
485 /* allocate space for pixel buffer */
486 if ( BROOKTREE_ALLOC )
487 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
492 #if defined(__FreeBSD__) || defined(__bsdi__)
494 /* If this is a module, check if there is any currently saved contiguous memory */
495 #if defined(BKTR_FREEBSD_MODULE)
496 if (bktr_has_stored_addresses(unit) == 1) {
497 /* recover the addresses */
498 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
499 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
500 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
501 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
502 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
503 need_to_allocate_memory = 0;
507 if (need_to_allocate_memory == 1) {
508 /* allocate space for dma program */
509 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
510 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
512 /* allocte space for the VBI buffer */
513 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
514 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
516 /* allocate space for pixel buffer */
517 if ( BROOKTREE_ALLOC )
518 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
522 #endif /* FreeBSD or BSDi */
525 /* If this is a module, save the current contiguous memory */
526 #if defined(BKTR_FREEBSD_MODULE)
527 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
528 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
529 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
530 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
531 bktr_store_address(unit, BKTR_MEM_BUF, buf);
536 printf("%s: buffer size %d, addr 0x%x\n",
537 bktr_name(bktr), BROOKTREE_ALLOC, vtophys(buf));
542 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
543 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
545 bktr->alloc_pages = 0;
549 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
550 METEOR_DEV0 | METEOR_RGB16;
551 bktr->dma_prog_loaded = FALSE;
554 bktr->frames = 1; /* one frame */
555 bktr->format = METEOR_GEO_RGB16;
556 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
557 bktr->pixfmt_compat = TRUE;
566 /* using the pci device id and revision id */
567 /* and determine the card type */
568 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
570 switch (PCI_PRODUCT(pci_id)) {
571 case PCI_PRODUCT_BROOKTREE_BT848:
573 bktr->id = BROOKTREE_848A;
575 bktr->id = BROOKTREE_848;
577 case PCI_PRODUCT_BROOKTREE_BT849:
578 bktr->id = BROOKTREE_849A;
580 case PCI_PRODUCT_BROOKTREE_BT878:
581 bktr->id = BROOKTREE_878;
583 case PCI_PRODUCT_BROOKTREE_BT879:
584 bktr->id = BROOKTREE_879;
589 bktr->clr_on_start = FALSE;
591 /* defaults for the tuner section of the card */
592 bktr->tflags = TUNER_INITALIZED;
593 bktr->tuner.frequency = 0;
594 bktr->tuner.channel = 0;
595 bktr->tuner.chnlset = DEFAULT_CHNLSET;
597 bktr->tuner.radio_mode = 0;
598 bktr->audio_mux_select = 0;
599 bktr->audio_mute_state = FALSE;
600 bktr->bt848_card = -1;
601 bktr->bt848_tuner = -1;
602 bktr->reverse_mute = -1;
603 bktr->slow_msp_audio = 0;
604 bktr->msp_use_mono_source = 0;
605 bktr->msp_source_selected = -1;
606 bktr->audio_mux_present = 1;
608 probeCard( bktr, TRUE, unit );
610 /* Initialise any MSP34xx or TDA98xx audio chips */
611 init_audio_devices( bktr );
616 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
617 * The circular buffer holds 'n' fixed size data blocks.
618 * vbisize is the number of bytes in the circular buffer
619 * vbiread is the point we reading data out of the circular buffer
620 * vbiinsert is the point we insert data into the circular buffer
622 static void vbidecode(bktr_ptr_t bktr) {
624 unsigned int *seq_dest;
626 /* Check if there is room in the buffer to insert the data. */
627 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
629 /* Copy the VBI data into the next free slot in the buffer. */
630 /* 'dest' is the point in vbibuffer where we want to insert new data */
631 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
632 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
634 /* Write the VBI sequence number to the end of the vbi data */
635 /* This is used by the AleVT teletext program */
636 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
638 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
639 *seq_dest = bktr->vbi_sequence_number;
641 /* And increase the VBI sequence number */
642 /* This can wrap around */
643 bktr->vbi_sequence_number++;
646 /* Increment the vbiinsert pointer */
647 /* This can wrap around */
648 bktr->vbiinsert += VBI_DATA_SIZE;
649 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
651 /* And increase the amount of vbi data in the buffer */
652 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
658 * the common interrupt handler.
659 * Returns a 0 or 1 depending on whether the interrupt has handled.
660 * In the OS specific section, bktr_intr() is defined which calls this
661 * common interrupt handler.
664 common_bktr_intr( void *arg )
673 bktr = (bktr_ptr_t) arg;
676 * check to see if any interrupts are unmasked on this device. If
677 * none are, then we likely got here by way of being on a PCI shared
678 * interrupt dispatch list.
680 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
681 return 0; /* bail out now, before we do something we
684 if (!(bktr->flags & METEOR_OPEN)) {
685 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
686 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
690 /* record and clear the INTerrupt status bits */
691 bktr_status = INL(bktr, BKTR_INT_STAT);
692 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
694 /* record and clear the device status register */
695 dstatus = INB(bktr, BKTR_DSTATUS);
696 OUTB(bktr, BKTR_DSTATUS, 0x00);
698 #if defined( STATUS_SUM )
699 /* add any new device status or INTerrupt status bits */
700 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
701 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
702 #endif /* STATUS_SUM */
703 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
704 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
708 /* if risc was disabled re-start process again */
709 /* if there was one of the following errors re-start again */
710 if ( !(bktr_status & BT848_INT_RISC_EN) ||
711 ((bktr_status &(/* BT848_INT_FBUS | */
712 /* BT848_INT_FTRGT | */
713 /* BT848_INT_FDSR | */
715 BT848_INT_RIPERR | BT848_INT_PABORT |
716 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
717 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
719 u_short tdec_save = INB(bktr, BKTR_TDEC);
721 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
722 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
724 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
726 /* Reset temporal decimation counter */
727 OUTB(bktr, BKTR_TDEC, 0);
728 OUTB(bktr, BKTR_TDEC, tdec_save);
730 /* Reset to no-fields captured state */
731 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
732 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
733 case METEOR_ONLY_ODD_FIELDS:
734 bktr->flags |= METEOR_WANT_ODD;
736 case METEOR_ONLY_EVEN_FIELDS:
737 bktr->flags |= METEOR_WANT_EVEN;
740 bktr->flags |= METEOR_WANT_MASK;
745 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
746 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
747 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
749 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
754 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
758 /* If this is not a RISC program interrupt, return */
759 if (!(bktr_status & BT848_INT_RISCI))
763 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
764 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
769 * Disable future interrupts if a capture mode is not selected.
770 * This can happen when we are in the process of closing or
771 * changing capture modes, otherwise it shouldn't happen.
773 if (!(bktr->flags & METEOR_CAP_MASK))
774 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
777 /* Determine which field generated this interrupt */
778 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
782 * Process the VBI data if it is being captured. We do this once
783 * both Odd and Even VBI data is captured. Therefore we do this
784 * in the Even field interrupt handler.
786 if ( (bktr->vbiflags & VBI_CAPTURE)
787 &&(bktr->vbiflags & VBI_OPEN)
789 /* Put VBI data into circular buffer */
792 /* If someone is blocked on reading from /dev/vbi, wake them */
793 if (bktr->vbi_read_blocked) {
794 bktr->vbi_read_blocked = FALSE;
798 /* If someone has a select() on /dev/vbi, inform them */
799 if (bktr->vbi_select.si_pid) {
800 selwakeup(&bktr->vbi_select);
808 * Register the completed field
809 * (For dual-field mode, require fields from the same frame)
811 switch ( bktr->flags & METEOR_WANT_MASK ) {
812 case METEOR_WANT_ODD : w_field = ODD_F ; break;
813 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
814 default : w_field = (ODD_F|EVEN_F); break;
816 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
817 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
818 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
819 default : req_field = (ODD_F|EVEN_F);
823 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
824 bktr->flags &= ~METEOR_WANT_EVEN;
825 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
826 ( w_field == ODD_F ))
827 bktr->flags &= ~METEOR_WANT_ODD;
828 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
829 ( w_field == (ODD_F|EVEN_F) ))
830 bktr->flags &= ~METEOR_WANT_ODD;
831 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
832 ( w_field == ODD_F )) {
833 bktr->flags &= ~METEOR_WANT_ODD;
834 bktr->flags |= METEOR_WANT_EVEN;
837 /* We're out of sync. Start over. */
838 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
839 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
840 case METEOR_ONLY_ODD_FIELDS:
841 bktr->flags |= METEOR_WANT_ODD;
843 case METEOR_ONLY_EVEN_FIELDS:
844 bktr->flags |= METEOR_WANT_EVEN;
847 bktr->flags |= METEOR_WANT_MASK;
855 * If we have a complete frame.
857 if (!(bktr->flags & METEOR_WANT_MASK)) {
858 bktr->frames_captured++;
860 * post the completion time.
862 if (bktr->flags & METEOR_WANT_TS) {
865 if ((u_int) bktr->alloc_pages * PAGE_SIZE
866 <= (bktr->frame_size + sizeof(struct timeval))) {
867 ts =(struct timeval *)bktr->bigbuf +
869 /* doesn't work in synch mode except
878 * Wake up the user in single capture mode.
880 if (bktr->flags & METEOR_SINGLE) {
883 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
885 /* disable risc, leave fifo running */
886 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
891 * If the user requested to be notified via signal,
892 * let them know the frame is complete.
895 if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK))
897 bktr->signal&(~METEOR_SIG_MODE_MASK) );
900 * Reset the want flags if in continuous or
901 * synchronous capture mode.
905 * currently we only support 3 capture modes: odd only, even only,
906 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
907 * either even OR odd) could provide 60 (50 for PAL) pictures per
908 * second, but it would require this routine to toggle the desired frame
909 * each time, and one more different DMA program for the Bt848.
910 * As a consequence, this fourth mode is currently unsupported.
913 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
914 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
915 case METEOR_ONLY_ODD_FIELDS:
916 bktr->flags |= METEOR_WANT_ODD;
918 case METEOR_ONLY_EVEN_FIELDS:
919 bktr->flags |= METEOR_WANT_EVEN;
922 bktr->flags |= METEOR_WANT_MASK;
937 extern int bt848_format; /* used to set the default format, PAL or NTSC */
939 video_open( bktr_ptr_t bktr )
941 int frame_rate, video_format=0;
943 if (bktr->flags & METEOR_OPEN) /* device is busy */
946 bktr->flags |= METEOR_OPEN;
952 bktr->clr_on_start = FALSE;
954 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
956 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
958 #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
964 if (bt848_format == 0 )
967 if (bt848_format == 1 )
970 if (video_format == 1 ) {
971 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
972 bktr->format_params = BT848_IFORM_F_NTSCM;
975 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
976 bktr->format_params = BT848_IFORM_F_PALBDGHI;
980 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
982 /* work around for new Hauppauge 878 cards */
983 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
984 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
985 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
987 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
989 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
990 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
991 frame_rate = format_params[bktr->format_params].frame_rate;
993 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
994 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
995 OUTB(bktr, BKTR_TGCTRL, 0);
996 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
997 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
998 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
1001 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1003 bktr->max_clip_node = 0;
1005 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
1007 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
1008 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
1010 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
1011 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
1012 OUTB(bktr, BKTR_E_SCLOOP, 0);
1013 OUTB(bktr, BKTR_O_SCLOOP, 0);
1015 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
1016 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
1018 bktr->fifo_errors = 0;
1019 bktr->dma_errors = 0;
1020 bktr->frames_captured = 0;
1021 bktr->even_fields_captured = 0;
1022 bktr->odd_fields_captured = 0;
1023 bktr->proc = (struct proc *)0;
1024 set_fps(bktr, frame_rate);
1025 bktr->video.addr = 0;
1026 bktr->video.width = 0;
1027 bktr->video.banksize = 0;
1028 bktr->video.ramsize = 0;
1029 bktr->pixfmt_compat = TRUE;
1030 bktr->format = METEOR_GEO_RGB16;
1031 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1033 bktr->capture_area_enabled = FALSE;
1035 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
1036 based motherboards will
1037 operate unreliably */
1042 vbi_open( bktr_ptr_t bktr )
1044 if (bktr->vbiflags & VBI_OPEN) /* device is busy */
1047 bktr->vbiflags |= VBI_OPEN;
1049 /* reset the VBI circular buffer pointers and clear the buffers */
1050 bktr->vbiinsert = 0;
1053 bktr->vbi_sequence_number = 0;
1054 bktr->vbi_read_blocked = FALSE;
1056 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
1057 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
1066 tuner_open( bktr_ptr_t bktr )
1068 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1071 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1074 bktr->tflags |= TUNER_OPEN;
1075 bktr->tuner.frequency = 0;
1076 bktr->tuner.channel = 0;
1077 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1078 bktr->tuner.afc = 0;
1079 bktr->tuner.radio_mode = 0;
1081 /* enable drivers on the GPIO port that control the MUXes */
1082 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1084 /* unmute the audio stream */
1085 set_audio( bktr, AUDIO_UNMUTE );
1087 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1088 init_audio_devices( bktr );
1100 video_close( bktr_ptr_t bktr )
1102 bktr->flags &= ~(METEOR_OPEN |
1107 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1108 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1110 bktr->dma_prog_loaded = FALSE;
1111 OUTB(bktr, BKTR_TDEC, 0);
1112 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1114 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1115 OUTL(bktr, BKTR_SRESET, 0xf);
1116 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1123 * tuner close handle,
1124 * place holder for tuner specific operations on a close.
1127 tuner_close( bktr_ptr_t bktr )
1129 bktr->tflags &= ~TUNER_OPEN;
1131 /* mute the audio by switching the mux */
1132 set_audio( bktr, AUDIO_MUTE );
1134 /* disable drivers on the GPIO port that control the MUXes */
1135 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1141 vbi_close( bktr_ptr_t bktr )
1144 bktr->vbiflags &= ~VBI_OPEN;
1153 video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
1159 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1162 if (bktr->flags & METEOR_CAP_MASK)
1163 return( EIO ); /* already capturing */
1165 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1168 count = bktr->rows * bktr->cols *
1169 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1171 if ((int) uio->uio_iov->iov_len < count)
1174 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1176 /* capture one frame */
1177 start_capture(bktr, METEOR_SINGLE);
1178 /* wait for capture to complete */
1179 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1180 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1181 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1182 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1188 status = tsleep(BKTR_SLEEP, PCATCH, "captur", 0);
1189 if (!status) /* successful capture */
1190 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1192 printf ("%s: read: tsleep error %d\n",
1193 bktr_name(bktr), status);
1195 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1201 * Read VBI data from the vbi circular buffer
1202 * The buffer holds vbi data blocks which are the same size
1203 * vbiinsert is the position we will insert the next item into the buffer
1204 * vbistart is the actual position in the buffer we want to read from
1205 * vbisize is the exact number of bytes in the buffer left to read
1208 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1210 int readsize, readsize2;
1214 while(bktr->vbisize == 0) {
1215 if (ioflag & IO_NDELAY) {
1219 bktr->vbi_read_blocked = TRUE;
1220 if ((status = tsleep(VBI_SLEEP, PCATCH, "vbi", 0))) {
1225 /* Now we have some data to give to the user */
1227 /* We cannot read more bytes than there are in
1228 * the circular buffer
1230 readsize = (int)uio->uio_iov->iov_len;
1232 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1234 /* Check if we can read this number of bytes without having
1235 * to wrap around the circular buffer */
1236 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1237 /* We need to wrap around */
1239 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1240 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
1241 status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1243 /* We do not need to wrap around */
1244 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1247 /* Update the number of bytes left to read */
1248 bktr->vbisize -= readsize;
1250 /* Update vbistart */
1251 bktr->vbistart += readsize;
1252 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1264 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td)
1266 volatile u_char c_temp;
1268 unsigned int temp_iform;
1270 struct meteor_geomet *geo;
1271 struct meteor_counts *counts;
1272 struct meteor_video *video;
1273 struct bktr_capture_area *cap_area;
1280 case BT848SCLIP: /* set clip region */
1281 bktr->max_clip_node = 0;
1282 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1284 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1285 if (bktr->clip_list[i].y_min == 0 &&
1286 bktr->clip_list[i].y_max == 0)
1289 bktr->max_clip_node = i;
1291 /* make sure that the list contains a valid clip secquence */
1292 /* the clip rectangles should be sorted by x then by y as the
1293 second order sort key */
1295 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1297 /* to disable clipping set y_min and y_max to 0 in the first
1298 clip rectangle . The first clip rectangle is clip_list[0].
1303 if (bktr->max_clip_node == 0 &&
1304 (bktr->clip_list[0].y_min != 0 &&
1305 bktr->clip_list[0].y_max != 0)) {
1309 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1310 if (bktr->clip_list[i].y_min == 0 &&
1311 bktr->clip_list[i].y_max == 0) {
1314 if ( bktr->clip_list[i+1].y_min != 0 &&
1315 bktr->clip_list[i+1].y_max != 0 &&
1316 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1318 bktr->max_clip_node = 0;
1323 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1324 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1325 bktr->clip_list[i].x_min < 0 ||
1326 bktr->clip_list[i].x_max < 0 ||
1327 bktr->clip_list[i].y_min < 0 ||
1328 bktr->clip_list[i].y_max < 0 ) {
1329 bktr->max_clip_node = 0;
1334 bktr->dma_prog_loaded = FALSE;
1338 case METEORSTATUS: /* get Bt848 status */
1339 c_temp = INB(bktr, BKTR_DSTATUS);
1341 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1342 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1343 *(u_short *)arg = temp;
1346 case BT848SFMT: /* set input format */
1347 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1348 temp_iform = INB(bktr, BKTR_IFORM);
1349 temp_iform &= ~BT848_IFORM_FORMAT;
1350 temp_iform &= ~BT848_IFORM_XTSEL;
1351 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1353 case BT848_IFORM_F_AUTO:
1354 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1358 case BT848_IFORM_F_NTSCM:
1359 case BT848_IFORM_F_NTSCJ:
1360 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1362 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1363 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1364 bktr->format_params = temp;
1367 case BT848_IFORM_F_PALBDGHI:
1368 case BT848_IFORM_F_PALN:
1369 case BT848_IFORM_F_SECAM:
1370 case BT848_IFORM_F_RSVD:
1371 case BT848_IFORM_F_PALM:
1372 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1374 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1375 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1376 bktr->format_params = temp;
1380 bktr->dma_prog_loaded = FALSE;
1383 case METEORSFMT: /* set input format */
1384 temp_iform = INB(bktr, BKTR_IFORM);
1385 temp_iform &= ~BT848_IFORM_FORMAT;
1386 temp_iform &= ~BT848_IFORM_XTSEL;
1387 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1388 case 0: /* default */
1389 case METEOR_FMT_NTSC:
1390 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1392 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1393 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1394 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1395 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1396 bktr->format_params = BT848_IFORM_F_NTSCM;
1399 case METEOR_FMT_PAL:
1400 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1402 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1403 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1404 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1405 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1406 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1409 case METEOR_FMT_AUTOMODE:
1410 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1412 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1413 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1419 bktr->dma_prog_loaded = FALSE;
1422 case METEORGFMT: /* get input format */
1423 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1427 case BT848GFMT: /* get input format */
1428 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1431 case METEORSCOUNT: /* (re)set error counts */
1432 counts = (struct meteor_counts *) arg;
1433 bktr->fifo_errors = counts->fifo_errors;
1434 bktr->dma_errors = counts->dma_errors;
1435 bktr->frames_captured = counts->frames_captured;
1436 bktr->even_fields_captured = counts->even_fields_captured;
1437 bktr->odd_fields_captured = counts->odd_fields_captured;
1440 case METEORGCOUNT: /* get error counts */
1441 counts = (struct meteor_counts *) arg;
1442 counts->fifo_errors = bktr->fifo_errors;
1443 counts->dma_errors = bktr->dma_errors;
1444 counts->frames_captured = bktr->frames_captured;
1445 counts->even_fields_captured = bktr->even_fields_captured;
1446 counts->odd_fields_captured = bktr->odd_fields_captured;
1450 video = (struct meteor_video *)arg;
1451 video->addr = bktr->video.addr;
1452 video->width = bktr->video.width;
1453 video->banksize = bktr->video.banksize;
1454 video->ramsize = bktr->video.ramsize;
1458 video = (struct meteor_video *)arg;
1459 bktr->video.addr = video->addr;
1460 bktr->video.width = video->width;
1461 bktr->video.banksize = video->banksize;
1462 bktr->video.ramsize = video->ramsize;
1466 set_fps(bktr, *(u_short *)arg);
1470 *(u_short *)arg = bktr->fps;
1473 case METEORSHUE: /* set hue */
1474 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1477 case METEORGHUE: /* get hue */
1478 *(u_char *)arg = INB(bktr, BKTR_HUE);
1481 case METEORSBRIG: /* set brightness */
1482 char_temp = ( *(u_char *)arg & 0xff) - 128;
1483 OUTB(bktr, BKTR_BRIGHT, char_temp);
1487 case METEORGBRIG: /* get brightness */
1488 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1491 case METEORSCSAT: /* set chroma saturation */
1492 temp = (int)*(u_char *)arg;
1494 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1495 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1496 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1497 & ~(BT848_E_CONTROL_SAT_U_MSB
1498 | BT848_E_CONTROL_SAT_V_MSB));
1499 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1500 & ~(BT848_O_CONTROL_SAT_U_MSB |
1501 BT848_O_CONTROL_SAT_V_MSB));
1503 if ( temp & BIT_SEVEN_HIGH ) {
1504 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1505 | (BT848_E_CONTROL_SAT_U_MSB
1506 | BT848_E_CONTROL_SAT_V_MSB));
1507 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1508 | (BT848_O_CONTROL_SAT_U_MSB
1509 | BT848_O_CONTROL_SAT_V_MSB));
1513 case METEORGCSAT: /* get chroma saturation */
1514 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1515 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1516 temp |= BIT_SEVEN_HIGH;
1517 *(u_char *)arg = (u_char)temp;
1520 case METEORSCONT: /* set contrast */
1521 temp = (int)*(u_char *)arg & 0xff;
1523 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1524 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1525 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1526 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1527 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1528 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1529 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1532 case METEORGCONT: /* get contrast */
1533 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1534 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1535 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1538 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1539 bktr->clr_on_start = (*(int *)arg != 0);
1542 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1543 *(int *)arg = (int) bktr->clr_on_start;
1547 if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
1551 KKASSERT(td->td_proc != NULL);
1552 bktr->signal = *(int *) arg;
1553 bktr->proc = td->td_proc;
1557 *(int *)arg = bktr->signal;
1562 switch (*(int *) arg) {
1563 case METEOR_CAP_SINGLE:
1565 if (bktr->bigbuf==0) /* no frame buffer allocated */
1567 /* already capturing */
1568 if (temp & METEOR_CAP_MASK)
1573 start_capture(bktr, METEOR_SINGLE);
1575 /* wait for capture to complete */
1576 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1577 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1578 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1580 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1585 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1586 error = tsleep(BKTR_SLEEP, PCATCH, "captur", hz);
1587 if (error && (error != ERESTART)) {
1588 /* Here if we didn't get complete frame */
1590 printf( "%s: ioctl: tsleep error %d %x\n",
1591 bktr_name(bktr), error,
1592 INL(bktr, BKTR_RISC_COUNT));
1596 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1598 /* disable risc, leave fifo running */
1599 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1602 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1603 /* FIXME: should we set bt848->int_stat ??? */
1606 case METEOR_CAP_CONTINOUS:
1607 if (bktr->bigbuf==0) /* no frame buffer allocated */
1609 /* already capturing */
1610 if (temp & METEOR_CAP_MASK)
1614 start_capture(bktr, METEOR_CONTIN);
1616 /* Clear the interrypt status register */
1617 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1619 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1620 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1621 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1623 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1628 dump_bt848( bt848 );
1632 case METEOR_CAP_STOP_CONT:
1633 if (bktr->flags & METEOR_CONTIN) {
1634 /* turn off capture */
1635 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1636 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1637 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1639 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1646 /* can't change parameters while capturing */
1647 if (bktr->flags & METEOR_CAP_MASK)
1651 geo = (struct meteor_geomet *) arg;
1654 /* Either even or odd, if even & odd, then these a zero */
1655 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1656 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1657 printf( "%s: ioctl: Geometry odd or even only.\n",
1662 /* set/clear even/odd flags */
1663 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1664 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1666 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1667 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1668 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1670 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1672 if (geo->columns <= 0) {
1674 "%s: ioctl: %d: columns must be greater than zero.\n",
1675 bktr_name(bktr), geo->columns);
1678 else if ((geo->columns & 0x3fe) != geo->columns) {
1680 "%s: ioctl: %d: columns too large or not even.\n",
1681 bktr_name(bktr), geo->columns);
1685 if (geo->rows <= 0) {
1687 "%s: ioctl: %d: rows must be greater than zero.\n",
1688 bktr_name(bktr), geo->rows);
1691 else if (((geo->rows & 0x7fe) != geo->rows) ||
1692 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1693 ((geo->rows & 0x3fe) != geo->rows)) ) {
1695 "%s: ioctl: %d: rows too large or not even.\n",
1696 bktr_name(bktr), geo->rows);
1700 if (geo->frames > 32) {
1701 printf("%s: ioctl: too many frames.\n",
1710 bktr->dma_prog_loaded = FALSE;
1711 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1713 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1715 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1716 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1718 /* meteor_mem structure for SYNC Capture */
1719 if (geo->frames > 1) temp += PAGE_SIZE;
1722 if ((int) temp > bktr->alloc_pages
1723 && bktr->video.addr == 0) {
1725 /*****************************/
1726 /* *** OS Dependant code *** */
1727 /*****************************/
1728 #if defined(__NetBSD__) || defined(__OpenBSD__)
1729 bus_dmamap_t dmamap;
1731 buf = get_bktr_mem(bktr, &dmamap,
1734 free_bktr_mem(bktr, bktr->dm_mem,
1736 bktr->dm_mem = dmamap;
1739 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1741 kmem_free(kernel_map, bktr->bigbuf,
1742 (bktr->alloc_pages * PAGE_SIZE));
1746 bktr->alloc_pages = temp;
1749 "%s: ioctl: Allocating %d bytes\n",
1750 bktr_name(bktr), temp*PAGE_SIZE);
1760 bktr->rows = geo->rows;
1761 bktr->cols = geo->columns;
1762 bktr->frames = geo->frames;
1764 /* Pixel format (if in meteor pixfmt compatibility mode) */
1765 if ( bktr->pixfmt_compat ) {
1766 bktr->format = METEOR_GEO_YUV_422;
1767 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1768 case 0: /* default */
1769 case METEOR_GEO_RGB16:
1770 bktr->format = METEOR_GEO_RGB16;
1772 case METEOR_GEO_RGB24:
1773 bktr->format = METEOR_GEO_RGB24;
1775 case METEOR_GEO_YUV_422:
1776 bktr->format = METEOR_GEO_YUV_422;
1777 if (geo->oformat & METEOR_GEO_YUV_12)
1778 bktr->format = METEOR_GEO_YUV_12;
1780 case METEOR_GEO_YUV_PACKED:
1781 bktr->format = METEOR_GEO_YUV_PACKED;
1784 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1787 if (bktr->flags & METEOR_CAP_MASK) {
1789 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1790 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1791 case METEOR_ONLY_ODD_FIELDS:
1792 bktr->flags |= METEOR_WANT_ODD;
1794 case METEOR_ONLY_EVEN_FIELDS:
1795 bktr->flags |= METEOR_WANT_EVEN;
1798 bktr->flags |= METEOR_WANT_MASK;
1802 start_capture(bktr, METEOR_CONTIN);
1803 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1804 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1805 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1806 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1812 /* end of METEORSETGEO */
1814 /* FIXME. The Capture Area currently has the following restrictions:
1816 y_offset may need to be even in interlaced modes
1817 RGB24 - Interlaced mode
1818 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1819 y_size must be greater than or equal to METEORSETGEO height (rows)
1820 RGB24 - Even Only (or Odd Only) mode
1821 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1822 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1823 YUV12 - Interlaced mode
1824 x_size must be greater than or equal to METEORSETGEO width (cols)
1825 y_size must be greater than or equal to METEORSETGEO height (rows)
1826 YUV12 - Even Only (or Odd Only) mode
1827 x_size must be greater than or equal to METEORSETGEO width (cols)
1828 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1831 case BT848_SCAPAREA: /* set capture area of each video frame */
1832 /* can't change parameters while capturing */
1833 if (bktr->flags & METEOR_CAP_MASK)
1836 cap_area = (struct bktr_capture_area *) arg;
1837 bktr->capture_area_x_offset = cap_area->x_offset;
1838 bktr->capture_area_y_offset = cap_area->y_offset;
1839 bktr->capture_area_x_size = cap_area->x_size;
1840 bktr->capture_area_y_size = cap_area->y_size;
1841 bktr->capture_area_enabled = TRUE;
1843 bktr->dma_prog_loaded = FALSE;
1846 case BT848_GCAPAREA: /* get capture area of each video frame */
1847 cap_area = (struct bktr_capture_area *) arg;
1848 if (bktr->capture_area_enabled == FALSE) {
1849 cap_area->x_offset = 0;
1850 cap_area->y_offset = 0;
1851 cap_area->x_size = format_params[
1852 bktr->format_params].scaled_hactive;
1853 cap_area->y_size = format_params[
1854 bktr->format_params].vactive;
1856 cap_area->x_offset = bktr->capture_area_x_offset;
1857 cap_area->y_offset = bktr->capture_area_y_offset;
1858 cap_area->x_size = bktr->capture_area_x_size;
1859 cap_area->y_size = bktr->capture_area_y_size;
1864 return common_ioctl( bktr, cmd, arg );
1874 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td)
1877 unsigned int temp, temp1;
1890 /* Read the last key pressed by the Remote Control */
1891 if (bktr->remote_control == 0) return (EINVAL);
1892 remote_read(bktr, (struct bktr_remote *)arg);
1895 #if defined( TUNER_AFC )
1896 case TVTUNER_SETAFC:
1897 bktr->tuner.afc = (*(int *)arg != 0);
1900 case TVTUNER_GETAFC:
1901 *(int *)arg = bktr->tuner.afc;
1902 /* XXX Perhaps use another bit to indicate AFC success? */
1904 #endif /* TUNER_AFC */
1906 case TVTUNER_SETCHNL:
1907 temp_mute( bktr, TRUE );
1908 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1910 temp_mute( bktr, FALSE );
1913 *(unsigned long *)arg = temp;
1915 /* after every channel change, we must restart the MSP34xx */
1916 /* audio chip to reselect NICAM STEREO or MONO audio */
1917 if ( bktr->card.msp3400c )
1918 msp_autodetect( bktr );
1920 /* after every channel change, we must restart the DPL35xx */
1921 if ( bktr->card.dpl3518a )
1922 dpl_autodetect( bktr );
1924 temp_mute( bktr, FALSE );
1927 case TVTUNER_GETCHNL:
1928 *(unsigned long *)arg = bktr->tuner.channel;
1931 case TVTUNER_SETTYPE:
1932 temp = *(unsigned long *)arg;
1933 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1935 bktr->tuner.chnlset = temp;
1938 case TVTUNER_GETTYPE:
1939 *(unsigned long *)arg = bktr->tuner.chnlset;
1942 case TVTUNER_GETSTATUS:
1943 temp = get_tuner_status( bktr );
1944 *(unsigned long *)arg = temp & 0xff;
1947 case TVTUNER_SETFREQ:
1948 temp_mute( bktr, TRUE );
1949 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1950 temp_mute( bktr, FALSE );
1952 temp_mute( bktr, FALSE );
1955 *(unsigned long *)arg = temp;
1957 /* after every channel change, we must restart the MSP34xx */
1958 /* audio chip to reselect NICAM STEREO or MONO audio */
1959 if ( bktr->card.msp3400c )
1960 msp_autodetect( bktr );
1962 /* after every channel change, we must restart the DPL35xx */
1963 if ( bktr->card.dpl3518a )
1964 dpl_autodetect( bktr );
1966 temp_mute( bktr, FALSE );
1969 case TVTUNER_GETFREQ:
1970 *(unsigned long *)arg = bktr->tuner.frequency;
1973 case TVTUNER_GETCHNLSET:
1974 return tuner_getchnlset((struct bktr_chnlset *)arg);
1976 case BT848_SAUDIO: /* set audio channel */
1977 if ( set_audio( bktr, *(int*)arg ) < 0 )
1981 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1982 case BT848_SHUE: /* set hue */
1983 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1986 case BT848_GHUE: /* get hue */
1987 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1990 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1991 case BT848_SBRIG: /* set brightness */
1992 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1995 case BT848_GBRIG: /* get brightness */
1996 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2000 case BT848_SCSAT: /* set chroma saturation */
2001 tmp_int = *(int*)arg;
2003 temp = INB(bktr, BKTR_E_CONTROL);
2004 temp1 = INB(bktr, BKTR_O_CONTROL);
2005 if ( tmp_int & BIT_EIGHT_HIGH ) {
2006 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2007 BT848_E_CONTROL_SAT_V_MSB);
2008 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2009 BT848_O_CONTROL_SAT_V_MSB);
2012 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2013 BT848_E_CONTROL_SAT_V_MSB);
2014 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2015 BT848_O_CONTROL_SAT_V_MSB);
2018 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2019 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2020 OUTB(bktr, BKTR_E_CONTROL, temp);
2021 OUTB(bktr, BKTR_O_CONTROL, temp1);
2024 case BT848_GCSAT: /* get chroma saturation */
2025 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2026 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2027 tmp_int |= BIT_EIGHT_HIGH;
2028 *(int*)arg = tmp_int;
2032 case BT848_SVSAT: /* set chroma V saturation */
2033 tmp_int = *(int*)arg;
2035 temp = INB(bktr, BKTR_E_CONTROL);
2036 temp1 = INB(bktr, BKTR_O_CONTROL);
2037 if ( tmp_int & BIT_EIGHT_HIGH) {
2038 temp |= BT848_E_CONTROL_SAT_V_MSB;
2039 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2042 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2043 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2046 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2047 OUTB(bktr, BKTR_E_CONTROL, temp);
2048 OUTB(bktr, BKTR_O_CONTROL, temp1);
2051 case BT848_GVSAT: /* get chroma V saturation */
2052 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2053 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2054 tmp_int |= BIT_EIGHT_HIGH;
2055 *(int*)arg = tmp_int;
2059 case BT848_SUSAT: /* set chroma U saturation */
2060 tmp_int = *(int*)arg;
2062 temp = INB(bktr, BKTR_E_CONTROL);
2063 temp1 = INB(bktr, BKTR_O_CONTROL);
2064 if ( tmp_int & BIT_EIGHT_HIGH ) {
2065 temp |= BT848_E_CONTROL_SAT_U_MSB;
2066 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2069 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2070 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2073 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2074 OUTB(bktr, BKTR_E_CONTROL, temp);
2075 OUTB(bktr, BKTR_O_CONTROL, temp1);
2078 case BT848_GUSAT: /* get chroma U saturation */
2079 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2080 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2081 tmp_int |= BIT_EIGHT_HIGH;
2082 *(int*)arg = tmp_int;
2085 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2087 case BT848_SLNOTCH: /* set luma notch */
2088 tmp_int = (*(int *)arg & 0x7) << 5 ;
2089 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2090 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2091 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2092 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2095 case BT848_GLNOTCH: /* get luma notch */
2096 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2101 case BT848_SCONT: /* set contrast */
2102 tmp_int = *(int*)arg;
2104 temp = INB(bktr, BKTR_E_CONTROL);
2105 temp1 = INB(bktr, BKTR_O_CONTROL);
2106 if ( tmp_int & BIT_EIGHT_HIGH ) {
2107 temp |= BT848_E_CONTROL_CON_MSB;
2108 temp1 |= BT848_O_CONTROL_CON_MSB;
2111 temp &= ~BT848_E_CONTROL_CON_MSB;
2112 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2115 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2116 OUTB(bktr, BKTR_E_CONTROL, temp);
2117 OUTB(bktr, BKTR_O_CONTROL, temp1);
2120 case BT848_GCONT: /* get contrast */
2121 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2122 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2123 tmp_int |= BIT_EIGHT_HIGH;
2124 *(int*)arg = tmp_int;
2127 /* FIXME: SCBARS and CCBARS require a valid int * */
2128 /* argument to succeed, but its not used; consider */
2129 /* using the arg to store the on/off state so */
2130 /* there's only one ioctl() needed to turn cbars on/off */
2131 case BT848_SCBARS: /* set colorbar output */
2132 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2135 case BT848_CCBARS: /* clear colorbar output */
2136 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2139 case BT848_GAUDIO: /* get audio channel */
2140 temp = bktr->audio_mux_select;
2141 if ( bktr->audio_mute_state == TRUE )
2146 case BT848_SBTSC: /* set audio channel */
2147 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2151 case BT848_WEEPROM: /* write eeprom */
2152 offset = (((struct eeProm *)arg)->offset);
2153 count = (((struct eeProm *)arg)->count);
2154 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2155 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2159 case BT848_REEPROM: /* read eeprom */
2160 offset = (((struct eeProm *)arg)->offset);
2161 count = (((struct eeProm *)arg)->count);
2162 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2163 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2167 case BT848_SIGNATURE:
2168 offset = (((struct eeProm *)arg)->offset);
2169 count = (((struct eeProm *)arg)->count);
2170 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2171 if ( signCard( bktr, offset, count, buf ) < 0 )
2175 /* Ioctl's for direct gpio access */
2176 #ifdef BKTR_GPIO_ACCESS
2177 case BT848_GPIO_GET_EN:
2178 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2181 case BT848_GPIO_SET_EN:
2182 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2185 case BT848_GPIO_GET_DATA:
2186 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2189 case BT848_GPIO_SET_DATA:
2190 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2192 #endif /* BKTR_GPIO_ACCESS */
2194 /* Ioctl's for running the tuner device in radio mode */
2197 *(unsigned char *)arg = bktr->tuner.radio_mode;
2201 bktr->tuner.radio_mode = *(unsigned char *)arg;
2205 *(unsigned long *)arg = bktr->tuner.frequency;
2209 /* The argument to this ioctl is NOT freq*16. It is
2213 temp=(int)*(unsigned long *)arg;
2215 #ifdef BKTR_RADIO_DEBUG
2216 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2217 (int)*(unsigned long *)arg, temp);
2220 #ifndef BKTR_RADIO_NOFREQCHECK
2221 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2223 if(temp<8750 || temp>10800) {
2224 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2228 temp_mute( bktr, TRUE );
2229 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2230 temp_mute( bktr, FALSE );
2231 #ifdef BKTR_RADIO_DEBUG
2233 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2237 *(unsigned long *)arg = temp;
2240 /* Luigi's I2CWR ioctl */
2242 par = *(u_long *)arg;
2243 write = (par >> 24) & 0xff ;
2244 i2c_addr = (par >> 16) & 0xff ;
2245 i2c_port = (par >> 8) & 0xff ;
2246 data = (par) & 0xff ;
2249 i2cWrite( bktr, i2c_addr, i2c_port, data);
2251 data = i2cRead( bktr, i2c_addr);
2253 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2257 #ifdef BT848_MSP_READ
2258 /* I2C ioctls to allow userland access to the MSP chip */
2259 case BT848_MSP_READ:
2261 struct bktr_msp_control *msp;
2262 msp = (struct bktr_msp_control *) arg;
2263 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2264 msp->function, msp->address);
2268 case BT848_MSP_WRITE:
2270 struct bktr_msp_control *msp;
2271 msp = (struct bktr_msp_control *) arg;
2272 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2273 msp->address, msp->data );
2277 case BT848_MSP_RESET:
2278 msp_dpl_reset(bktr, bktr->msp_addr);
2283 return common_ioctl( bktr, cmd, arg );
2294 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2298 struct meteor_pixfmt *pf_pub;
2302 case METEORSINPUT: /* set input device */
2303 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2304 /* On the original bt848 boards, */
2305 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2306 /* On the Hauppauge bt878 boards, */
2307 /* Tuner is MUX0, RCA is MUX3 */
2308 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2309 /* stick with this system in our Meteor Emulation */
2311 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2313 /* this is the RCA video input */
2314 case 0: /* default */
2315 case METEOR_INPUT_DEV0:
2316 /* METEOR_INPUT_DEV_RCA: */
2317 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2319 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2320 & ~BT848_IFORM_MUXSEL);
2322 /* work around for new Hauppauge 878 cards */
2323 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2324 (bktr->id==BROOKTREE_878 ||
2325 bktr->id==BROOKTREE_879) )
2326 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2328 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2330 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2331 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2332 set_audio( bktr, AUDIO_EXTERN );
2335 /* this is the tuner input */
2336 case METEOR_INPUT_DEV1:
2337 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2339 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2340 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2341 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2342 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2343 set_audio( bktr, AUDIO_TUNER );
2346 /* this is the S-VHS input, but with a composite camera */
2347 case METEOR_INPUT_DEV2:
2348 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2350 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2351 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2352 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2353 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2354 set_audio( bktr, AUDIO_EXTERN );
2357 /* this is the S-VHS input */
2358 case METEOR_INPUT_DEV_SVIDEO:
2359 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2360 | METEOR_DEV_SVIDEO;
2361 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2362 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2363 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2364 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2365 set_audio( bktr, AUDIO_EXTERN );
2368 case METEOR_INPUT_DEV3:
2369 if ((bktr->id == BROOKTREE_848A) ||
2370 (bktr->id == BROOKTREE_849A) ||
2371 (bktr->id == BROOKTREE_878) ||
2372 (bktr->id == BROOKTREE_879) ) {
2373 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2375 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2377 /* work around for new Hauppauge 878 cards */
2378 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2379 (bktr->id==BROOKTREE_878 ||
2380 bktr->id==BROOKTREE_879) )
2381 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2383 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2385 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2386 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2387 set_audio( bktr, AUDIO_EXTERN );
2397 case METEORGINPUT: /* get input device */
2398 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2401 case METEORSACTPIXFMT:
2402 if (( *(int *)arg < 0 ) ||
2403 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2406 bktr->pixfmt = *(int *)arg;
2407 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2408 | pixfmt_swap_flags( bktr->pixfmt ));
2409 bktr->pixfmt_compat = FALSE;
2412 case METEORGACTPIXFMT:
2413 *(int *)arg = bktr->pixfmt;
2416 case METEORGSUPPIXFMT :
2417 pf_pub = (struct meteor_pixfmt *)arg;
2418 pixfmt = pf_pub->index;
2420 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2423 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2424 sizeof( *pf_pub ) );
2426 /* Patch in our format index */
2427 pf_pub->index = pixfmt;
2430 #if defined( STATUS_SUM )
2431 case BT848_GSTATUS: /* reap status */
2433 DECLARE_INTR_MASK(s);
2438 *(u_int*)arg = temp;
2441 #endif /* STATUS_SUM */
2453 /******************************************************************************
2454 * bt848 RISC programming routines:
2463 dump_bt848( bktr_ptr_t bktr )
2466 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2467 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2468 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2469 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2470 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2475 for (i = 0; i < 40; i+=4) {
2476 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2478 r[i], INL(bktr, r[i]),
2479 r[i+1], INL(bktr, r[i+1]),
2480 r[i+2], INL(bktr, r[i+2]),
2481 r[i+3], INL(bktr, r[i+3]]));
2484 printf("%s: INT STAT %x \n", bktr_name(bktr),
2485 INL(bktr, BKTR_INT_STAT));
2486 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2487 INL(bktr, BKTR_INT_MASK));
2488 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2489 INW(bktr, BKTR_GPIO_DMA_CTL));
2497 * build write instruction
2499 #define BKTR_FM1 0x6 /* packed data to follow */
2500 #define BKTR_FM3 0xe /* planar data to follow */
2501 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2502 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2503 #define BKTR_PXV 0x0 /* valid word (never used) */
2504 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2505 #define BKTR_SOL 0x2 /* first dword */
2507 #define OP_WRITE (0x1 << 28)
2508 #define OP_SKIP (0x2 << 28)
2509 #define OP_WRITEC (0x5 << 28)
2510 #define OP_JUMP (0x7 << 28)
2511 #define OP_SYNC (0x8 << 28)
2512 #define OP_WRITE123 (0x9 << 28)
2513 #define OP_WRITES123 (0xb << 28)
2514 #define OP_SOL (1 << 27) /* first instr for scanline */
2515 #define OP_EOL (1 << 26)
2517 #define BKTR_RESYNC (1 << 15)
2518 #define BKTR_GEN_IRQ (1 << 24)
2521 * The RISC status bits can be set/cleared in the RISC programs
2522 * and tested in the Interrupt Handler
2524 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2525 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2526 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2527 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2529 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2530 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2531 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2532 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2534 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2535 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2536 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2537 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2539 bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2541 bktr_clip_t * clip_node;
2542 bktr->clip_start = -1;
2546 bktr->line_length = width;
2549 bktr->current_col = 0;
2551 if (bktr->max_clip_node == 0 ) return TRUE;
2552 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2555 for (i = 0; i < bktr->max_clip_node; i++ ) {
2556 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2557 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2558 bktr->clip_start = i;
2566 bool_t getline(bktr_reg_t *bktr, int x ) {
2568 bktr_clip_t * clip_node ;
2570 if (bktr->line_length == 0 ||
2571 bktr->current_col >= bktr->line_length) return FALSE;
2573 bktr->y = min(bktr->last_y, bktr->line_length);
2574 bktr->y2 = bktr->line_length;
2576 bktr->yclip = bktr->yclip2 = -1;
2577 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2578 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2579 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2580 if (bktr->last_y <= clip_node->y_min) {
2581 bktr->y = min(bktr->last_y, bktr->line_length);
2582 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2583 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2584 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2585 bktr->last_y = bktr->yclip2;
2586 bktr->clip_start = i;
2588 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2589 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2590 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2591 if (bktr->last_y >= clip_node->y_min) {
2592 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2593 bktr->last_y = bktr->yclip2;
2594 bktr->clip_start = j;
2603 if (bktr->current_col <= bktr->line_length) {
2604 bktr->current_col = bktr->line_length;
2610 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2611 u_long operation, int pixel_width,
2612 volatile u_char ** target_buffer, int cols ) {
2615 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2616 u_int skip, start_skip;
2618 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2619 /* to the 1st byte in the mem dword containing our start addr. */
2620 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2623 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2624 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2625 case 2 : start_skip = 4 ; break;
2626 case 1 : start_skip = 8 ; break;
2629 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2630 if ( width == cols) {
2631 flag = OP_SOL | OP_EOL;
2632 } else if (bktr->current_col == 0 ) {
2634 } else if (bktr->current_col == cols) {
2639 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2640 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2645 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2646 if (operation != OP_SKIP )
2647 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2649 *target_buffer += width * pixel_width;
2650 bktr->current_col += width;
2654 if (bktr->current_col == 0 && width == cols) {
2657 } else if (bktr->current_col == 0 ) {
2660 } else if (bktr->current_col >= cols) {
2669 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2670 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2675 *(*dma_prog)++ = operation | flag |
2676 (width * pixel_width / 2 - skip);
2677 if (operation != OP_SKIP )
2678 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2679 *target_buffer += (width * pixel_width / 2) ;
2681 if ( operation == OP_WRITE )
2682 operation = OP_WRITEC;
2683 *(*dma_prog)++ = operation | flag2 |
2684 (width * pixel_width / 2);
2685 *target_buffer += (width * pixel_width / 2) ;
2686 bktr->current_col += width;
2694 * Generate the RISC instructions to capture both VBI and video images
2697 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2700 volatile u_long target_buffer, buffer, target,width;
2701 volatile u_long pitch;
2702 volatile u_long *dma_prog; /* DMA prog is an array of
2703 32 bit RISC instructions */
2704 volatile u_long *loop_point;
2705 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2706 u_int Bpp = pf_int->public.Bpp;
2707 unsigned int vbisamples; /* VBI samples per line */
2708 unsigned int vbilines; /* VBI lines per field */
2709 unsigned int num_dwords; /* DWORDS per line */
2711 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2712 vbilines = format_params[bktr->format_params].vbi_num_lines;
2713 num_dwords = vbisamples/4;
2715 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2716 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2717 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2718 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2721 OUTB(bktr, BKTR_OFORM, 0x00);
2723 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2724 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2725 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2726 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2728 /* disable gamma correction removal */
2729 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2732 OUTB(bktr, BKTR_E_VTC, 0);
2733 OUTB(bktr, BKTR_O_VTC, 0);
2735 OUTB(bktr, BKTR_E_VTC, 1);
2736 OUTB(bktr, BKTR_O_VTC, 1);
2738 bktr->capcontrol = 3 << 2 | 3;
2740 dma_prog = (u_long *) bktr->dma_prog;
2742 /* Construct Write */
2744 if (bktr->video.addr) {
2745 target_buffer = (u_long) bktr->video.addr;
2746 pitch = bktr->video.width;
2749 target_buffer = (u_long) vtophys(bktr->bigbuf);
2753 buffer = target_buffer;
2755 /* Wait for the VRE sync marking the end of the Even and
2756 * the start of the Odd field. Resync here.
2758 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2761 loop_point = dma_prog;
2763 /* store the VBI data */
2764 /* look for sync with packed data */
2765 *dma_prog++ = OP_SYNC | BKTR_FM1;
2767 for(i = 0; i < vbilines; i++) {
2768 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2769 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2770 (i * VBI_LINE_SIZE));
2773 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2774 /* store the Odd field video image */
2775 /* look for sync with packed data */
2776 *dma_prog++ = OP_SYNC | BKTR_FM1;
2777 *dma_prog++ = 0; /* NULL WORD */
2779 for (i = 0; i < (rows/interlace); i++) {
2780 target = target_buffer;
2781 if ( notclipped(bktr, i, width)) {
2782 split(bktr, (volatile u_long **) &dma_prog,
2783 bktr->y2 - bktr->y, OP_WRITE,
2784 Bpp, (volatile u_char **) &target, cols);
2787 while(getline(bktr, i)) {
2788 if (bktr->y != bktr->y2 ) {
2789 split(bktr, (volatile u_long **) &dma_prog,
2790 bktr->y2 - bktr->y, OP_WRITE,
2791 Bpp, (volatile u_char **) &target, cols);
2793 if (bktr->yclip != bktr->yclip2 ) {
2794 split(bktr,(volatile u_long **) &dma_prog,
2795 bktr->yclip2 - bktr->yclip,
2797 Bpp, (volatile u_char **) &target, cols);
2803 target_buffer += interlace * pitch;
2809 /* Grab the Even field */
2810 /* Look for the VRO, end of Odd field, marker */
2811 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2812 *dma_prog++ = 0; /* NULL WORD */
2814 /* store the VBI data */
2815 /* look for sync with packed data */
2816 *dma_prog++ = OP_SYNC | BKTR_FM1;
2818 for(i = 0; i < vbilines; i++) {
2819 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2820 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2821 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2824 /* store the video image */
2825 if (i_flag == 1) /*Even Only*/
2826 target_buffer = buffer;
2827 if (i_flag == 3) /*interlaced*/
2828 target_buffer = buffer+pitch;
2831 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2832 /* look for sync with packed data */
2833 *dma_prog++ = OP_SYNC | BKTR_FM1;
2834 *dma_prog++ = 0; /* NULL WORD */
2836 for (i = 0; i < (rows/interlace); i++) {
2837 target = target_buffer;
2838 if ( notclipped(bktr, i, width)) {
2839 split(bktr, (volatile u_long **) &dma_prog,
2840 bktr->y2 - bktr->y, OP_WRITE,
2841 Bpp, (volatile u_char **) &target, cols);
2843 while(getline(bktr, i)) {
2844 if (bktr->y != bktr->y2 ) {
2845 split(bktr, (volatile u_long **) &dma_prog,
2846 bktr->y2 - bktr->y, OP_WRITE,
2847 Bpp, (volatile u_char **) &target,
2850 if (bktr->yclip != bktr->yclip2 ) {
2851 split(bktr, (volatile u_long **) &dma_prog,
2852 bktr->yclip2 - bktr->yclip, OP_SKIP,
2853 Bpp, (volatile u_char **) &target, cols);
2860 target_buffer += interlace * pitch;
2865 /* Look for end of 'Even Field' */
2866 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2867 *dma_prog++ = 0; /* NULL WORD */
2869 *dma_prog++ = OP_JUMP ;
2870 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2871 *dma_prog++ = 0; /* NULL WORD */
2879 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2882 volatile u_long target_buffer, buffer, target,width;
2883 volatile u_long pitch;
2884 volatile u_long *dma_prog;
2885 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2886 u_int Bpp = pf_int->public.Bpp;
2888 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2889 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2890 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2891 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2893 OUTB(bktr, BKTR_OFORM, 0x00);
2895 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2896 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2897 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2898 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2900 /* disable gamma correction removal */
2901 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2904 OUTB(bktr, BKTR_E_VTC, 0);
2905 OUTB(bktr, BKTR_O_VTC, 0);
2907 OUTB(bktr, BKTR_E_VTC, 1);
2908 OUTB(bktr, BKTR_O_VTC, 1);
2910 bktr->capcontrol = 3 << 2 | 3;
2912 dma_prog = (u_long *) bktr->dma_prog;
2914 /* Construct Write */
2916 if (bktr->video.addr) {
2917 target_buffer = (u_long) bktr->video.addr;
2918 pitch = bktr->video.width;
2921 target_buffer = (u_long) vtophys(bktr->bigbuf);
2925 buffer = target_buffer;
2927 /* contruct sync : for video packet format */
2928 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2930 /* sync, mode indicator packed data */
2931 *dma_prog++ = 0; /* NULL WORD */
2933 for (i = 0; i < (rows/interlace); i++) {
2934 target = target_buffer;
2935 if ( notclipped(bktr, i, width)) {
2936 split(bktr, (volatile u_long **) &dma_prog,
2937 bktr->y2 - bktr->y, OP_WRITE,
2938 Bpp, (volatile u_char **) &target, cols);
2941 while(getline(bktr, i)) {
2942 if (bktr->y != bktr->y2 ) {
2943 split(bktr, (volatile u_long **) &dma_prog,
2944 bktr->y2 - bktr->y, OP_WRITE,
2945 Bpp, (volatile u_char **) &target, cols);
2947 if (bktr->yclip != bktr->yclip2 ) {
2948 split(bktr,(volatile u_long **) &dma_prog,
2949 bktr->yclip2 - bktr->yclip,
2951 Bpp, (volatile u_char **) &target, cols);
2957 target_buffer += interlace * pitch;
2964 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2965 *dma_prog++ = 0; /* NULL WORD */
2967 *dma_prog++ = OP_JUMP;
2968 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2973 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2974 *dma_prog++ = 0; /* NULL WORD */
2976 *dma_prog++ = OP_JUMP;
2977 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2982 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2983 *dma_prog++ = 0; /* NULL WORD */
2984 *dma_prog++ = OP_JUMP; ;
2985 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
2989 if (interlace == 2) {
2991 target_buffer = buffer + pitch;
2993 dma_prog = (u_long *) bktr->odd_dma_prog;
2995 /* sync vre IRQ bit */
2996 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2997 *dma_prog++ = 0; /* NULL WORD */
2999 for (i = 0; i < (rows/interlace); i++) {
3000 target = target_buffer;
3001 if ( notclipped(bktr, i, width)) {
3002 split(bktr, (volatile u_long **) &dma_prog,
3003 bktr->y2 - bktr->y, OP_WRITE,
3004 Bpp, (volatile u_char **) &target, cols);
3006 while(getline(bktr, i)) {
3007 if (bktr->y != bktr->y2 ) {
3008 split(bktr, (volatile u_long **) &dma_prog,
3009 bktr->y2 - bktr->y, OP_WRITE,
3010 Bpp, (volatile u_char **) &target,
3013 if (bktr->yclip != bktr->yclip2 ) {
3014 split(bktr, (volatile u_long **) &dma_prog,
3015 bktr->yclip2 - bktr->yclip, OP_SKIP,
3016 Bpp, (volatile u_char **) &target, cols);
3023 target_buffer += interlace * pitch;
3028 /* sync vre IRQ bit */
3029 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3030 *dma_prog++ = 0; /* NULL WORD */
3031 *dma_prog++ = OP_JUMP ;
3032 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3033 *dma_prog++ = 0; /* NULL WORD */
3041 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3042 int cols, int rows, int interlace )
3045 volatile unsigned int inst;
3046 volatile unsigned int inst3;
3047 volatile u_long target_buffer, buffer;
3048 volatile u_long *dma_prog;
3049 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3052 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3054 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3055 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3057 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3058 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3060 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3061 bktr->capcontrol = 3 << 2 | 3;
3063 dma_prog = (u_long *) bktr->dma_prog;
3065 /* Construct Write */
3067 /* write , sol, eol */
3068 inst = OP_WRITE | OP_SOL | (cols);
3069 /* write , sol, eol */
3070 inst3 = OP_WRITE | OP_EOL | (cols);
3072 if (bktr->video.addr)
3073 target_buffer = (u_long) bktr->video.addr;
3075 target_buffer = (u_long) vtophys(bktr->bigbuf);
3077 buffer = target_buffer;
3079 /* contruct sync : for video packet format */
3080 /* sync, mode indicator packed data */
3081 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3082 *dma_prog++ = 0; /* NULL WORD */
3086 for (i = 0; i < (rows/interlace); i++) {
3088 *dma_prog++ = target_buffer;
3089 *dma_prog++ = inst3;
3090 *dma_prog++ = target_buffer + b;
3091 target_buffer += interlace*(cols * 2);
3097 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
3098 *dma_prog++ = 0; /* NULL WORD */
3100 *dma_prog++ = OP_JUMP;
3101 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3106 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
3107 *dma_prog++ = 0; /* NULL WORD */
3108 *dma_prog++ = OP_JUMP;
3109 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3114 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3115 *dma_prog++ = 0; /* NULL WORD */
3116 *dma_prog++ = OP_JUMP ;
3117 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3121 if (interlace == 2) {
3123 target_buffer = (u_long) buffer + cols*2;
3125 dma_prog = (u_long * ) bktr->odd_dma_prog;
3128 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1;
3129 *dma_prog++ = 0; /* NULL WORD */
3131 for (i = 0; i < (rows/interlace) ; i++) {
3133 *dma_prog++ = target_buffer;
3134 *dma_prog++ = inst3;
3135 *dma_prog++ = target_buffer + b;
3136 target_buffer += interlace * ( cols*2);
3140 /* sync vro IRQ bit */
3141 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3142 *dma_prog++ = 0; /* NULL WORD */
3143 *dma_prog++ = OP_JUMP ;
3144 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3146 *dma_prog++ = OP_JUMP;
3147 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3148 *dma_prog++ = 0; /* NULL WORD */
3156 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3157 int cols, int rows, int interlace ){
3160 volatile unsigned int inst;
3161 volatile u_long target_buffer, t1, buffer;
3162 volatile u_long *dma_prog;
3163 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3165 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3167 dma_prog = (u_long *) bktr->dma_prog;
3169 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3171 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3172 OUTB(bktr, BKTR_OFORM, 0x00);
3174 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3175 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3177 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3178 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3180 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3181 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3182 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ~0x40); /* set chroma comb */
3183 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ~0x40);
3185 /* disable gamma correction removal */
3186 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3188 /* Construct Write */
3189 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3190 if (bktr->video.addr)
3191 target_buffer = (u_long) bktr->video.addr;
3193 target_buffer = (u_long) vtophys(bktr->bigbuf);
3195 buffer = target_buffer;
3199 /* contruct sync : for video packet format */
3200 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3201 *dma_prog++ = 0; /* NULL WORD */
3203 for (i = 0; i < (rows/interlace ) ; i++) {
3205 *dma_prog++ = cols/2 | cols/2 << 16;
3206 *dma_prog++ = target_buffer;
3207 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3208 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3209 target_buffer += interlace*cols;
3214 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3215 *dma_prog++ = 0; /* NULL WORD */
3217 *dma_prog++ = OP_JUMP ;
3218 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3222 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3223 *dma_prog++ = 0; /* NULL WORD */
3225 *dma_prog++ = OP_JUMP;
3226 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3230 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3231 *dma_prog++ = 0; /* NULL WORD */
3233 *dma_prog++ = OP_JUMP ;
3234 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3238 if (interlace == 2) {
3240 dma_prog = (u_long * ) bktr->odd_dma_prog;
3242 target_buffer = (u_long) buffer + cols;
3243 t1 = buffer + cols/2;
3244 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3245 *dma_prog++ = 0; /* NULL WORD */
3247 for (i = 0; i < (rows/interlace ) ; i++) {
3249 *dma_prog++ = cols/2 | cols/2 << 16;
3250 *dma_prog++ = target_buffer;
3251 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3252 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3253 target_buffer += interlace*cols;
3257 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3258 *dma_prog++ = 0; /* NULL WORD */
3259 *dma_prog++ = OP_JUMP ;
3260 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3261 *dma_prog++ = 0; /* NULL WORD */
3269 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3270 int cols, int rows, int interlace ){
3273 volatile unsigned int inst;
3274 volatile unsigned int inst1;
3275 volatile u_long target_buffer, t1, buffer;
3276 volatile u_long *dma_prog;
3277 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3279 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3281 dma_prog = (u_long *) bktr->dma_prog;
3283 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3285 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3286 OUTB(bktr, BKTR_OFORM, 0x0);
3288 /* Construct Write */
3289 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3290 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3291 if (bktr->video.addr)
3292 target_buffer = (u_long) bktr->video.addr;
3294 target_buffer = (u_long) vtophys(bktr->bigbuf);
3296 buffer = target_buffer;
3299 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3300 *dma_prog++ = 0; /* NULL WORD */
3302 for (i = 0; i < (rows/interlace )/2 ; i++) {
3304 *dma_prog++ = cols/2 | (cols/2 << 16);
3305 *dma_prog++ = target_buffer;
3306 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3307 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3308 target_buffer += interlace*cols;
3309 *dma_prog++ = inst1;
3310 *dma_prog++ = cols/2 | (cols/2 << 16);
3311 *dma_prog++ = target_buffer;
3312 target_buffer += interlace*cols;
3318 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3319 *dma_prog++ = 0; /* NULL WORD */
3321 *dma_prog++ = OP_JUMP;
3322 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3326 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3327 *dma_prog++ = 0; /* NULL WORD */
3329 *dma_prog++ = OP_JUMP;
3330 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3334 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3335 *dma_prog++ = 0; /* NULL WORD */
3336 *dma_prog++ = OP_JUMP ;
3337 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3341 if (interlace == 2) {
3343 dma_prog = (u_long * ) bktr->odd_dma_prog;
3345 target_buffer = (u_long) buffer + cols;
3346 t1 = buffer + cols/2;
3347 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3348 *dma_prog++ = 0; /* NULL WORD */
3350 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3352 *dma_prog++ = cols/2 | (cols/2 << 16);
3353 *dma_prog++ = target_buffer;
3354 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3355 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3356 target_buffer += interlace*cols;
3357 *dma_prog++ = inst1;
3358 *dma_prog++ = cols/2 | (cols/2 << 16);
3359 *dma_prog++ = target_buffer;
3360 target_buffer += interlace*cols;
3367 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3368 *dma_prog++ = 0; /* NULL WORD */
3369 *dma_prog++ = OP_JUMP;
3370 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3371 *dma_prog++ = 0; /* NULL WORD */
3380 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3382 int rows, cols, interlace;
3385 struct format_params *fp;
3386 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3389 fp = &format_params[bktr->format_params];
3391 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3393 /* disable FIFO & RISC, leave other bits alone */
3394 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3396 /* set video parameters */
3397 if (bktr->capture_area_enabled)
3398 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3399 / fp->scaled_htotal / bktr->cols) - 4096;
3401 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3402 / fp->scaled_htotal / bktr->cols) - 4096;
3404 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3405 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3406 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3407 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3408 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3410 /* horizontal active */
3412 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3413 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3414 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3415 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3416 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3417 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3418 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3420 /* horizontal delay */
3421 if (bktr->capture_area_enabled)
3422 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3423 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3425 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3427 temp = temp & 0x3fe;
3429 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3430 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3431 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3432 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3433 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3434 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3435 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3437 /* vertical scale */
3439 if (bktr->capture_area_enabled) {
3440 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3441 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3443 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3446 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3449 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3450 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3452 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3455 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3460 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3461 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3462 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3463 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3464 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3465 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3466 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3469 /* vertical active */
3470 if (bktr->capture_area_enabled)
3471 temp = bktr->capture_area_y_size;
3474 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3475 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3476 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3477 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3478 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3479 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3480 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3482 /* vertical delay */
3483 if (bktr->capture_area_enabled)
3484 temp = fp->vdelay + (bktr->capture_area_y_offset);
3487 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3488 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3489 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3490 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3491 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3492 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3493 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3495 /* end of video params */
3497 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3498 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3499 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3501 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3504 /* capture control */
3507 bktr->bktr_cap_ctl =
3508 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3509 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3510 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3514 bktr->bktr_cap_ctl =
3515 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3516 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3517 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3521 bktr->bktr_cap_ctl =
3522 (BT848_CAP_CTL_DITH_FRAME |
3523 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3524 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3525 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3530 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3535 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3537 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3538 /* user, then use the rgb_vbi RISC program. */
3539 /* Otherwise, use the normal rgb RISC program */
3540 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3541 if ( (bktr->vbiflags & VBI_OPEN)
3542 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3543 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3545 bktr->bktr_cap_ctl |=
3546 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3547 bktr->vbiflags |= VBI_CAPTURE;
3548 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3551 rgb_prog(bktr, i_flag, cols, rows, interlace);
3556 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3557 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3558 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3559 | pixfmt_swap_flags( bktr->pixfmt ));
3563 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3564 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3565 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3566 | pixfmt_swap_flags( bktr->pixfmt ));
3570 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3571 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3572 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3573 | pixfmt_swap_flags( bktr->pixfmt ));
3580 /******************************************************************************
3581 * video & video capture specific routines:
3589 start_capture( bktr_ptr_t bktr, unsigned type )
3592 struct format_params *fp;
3594 fp = &format_params[bktr->format_params];
3596 /* If requested, clear out capture buf first */
3597 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3598 bzero((caddr_t)bktr->bigbuf,
3599 (size_t)bktr->rows * bktr->cols * bktr->frames *
3600 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3603 OUTB(bktr, BKTR_DSTATUS, 0);
3604 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3606 bktr->flags |= type;
3607 bktr->flags &= ~METEOR_WANT_MASK;
3608 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3609 case METEOR_ONLY_EVEN_FIELDS:
3610 bktr->flags |= METEOR_WANT_EVEN;
3613 case METEOR_ONLY_ODD_FIELDS:
3614 bktr->flags |= METEOR_WANT_ODD;
3618 bktr->flags |= METEOR_WANT_MASK;
3623 /* TDEC is only valid for continuous captures */
3624 if ( type == METEOR_SINGLE ) {
3625 u_short fps_save = bktr->fps;
3627 set_fps(bktr, fp->frame_rate);
3628 bktr->fps = fps_save;
3631 set_fps(bktr, bktr->fps);
3633 if (bktr->dma_prog_loaded == FALSE) {
3634 build_dma_prog(bktr, i_flag);
3635 bktr->dma_prog_loaded = TRUE;
3639 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3648 set_fps( bktr_ptr_t bktr, u_short fps )
3650 struct format_params *fp;
3653 fp = &format_params[bktr->format_params];
3655 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3656 case METEOR_ONLY_EVEN_FIELDS:
3657 bktr->flags |= METEOR_WANT_EVEN;
3660 case METEOR_ONLY_ODD_FIELDS:
3661 bktr->flags |= METEOR_WANT_ODD;
3665 bktr->flags |= METEOR_WANT_MASK;
3670 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3671 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3674 OUTB(bktr, BKTR_TDEC, 0);
3676 if (fps < fp->frame_rate)
3677 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3679 OUTB(bktr, BKTR_TDEC, 0);
3689 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3690 * achieve the specified swapping.
3691 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3692 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3694 * Note also that for 3Bpp, we may additionally need to do some creative
3695 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3696 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3697 * as one would expect.
3700 static u_int pixfmt_swap_flags( int pixfmt )
3702 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3705 switch ( pf->Bpp ) {
3706 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3709 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3712 case 4 : if ( pf->swap_bytes )
3713 swapf = pf->swap_shorts ? 0 : WSWAP;
3715 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3724 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3725 * our pixfmt_table indices.
3728 static int oformat_meteor_to_bt( u_long format )
3731 struct meteor_pixfmt *pf1, *pf2;
3733 /* Find format in compatibility table */
3734 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3735 if ( meteor_pixfmt_table[i].meteor_format == format )
3738 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3740 pf1 = &meteor_pixfmt_table[i].public;
3742 /* Match it with an entry in master pixel format table */
3743 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3744 pf2 = &pixfmt_table[i].public;
3746 if (( pf1->type == pf2->type ) &&
3747 ( pf1->Bpp == pf2->Bpp ) &&
3748 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3749 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3750 ( pf1->swap_shorts == pf2->swap_shorts ))
3753 if ( i >= PIXFMT_TABLE_SIZE )
3759 /******************************************************************************
3764 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3765 #define I2CBITTIME_878 (1 << 7)
3766 #define I2C_READ 0x01
3767 #define I2C_COMMAND (I2CBITTIME | \
3768 BT848_DATA_CTL_I2CSCL | \
3769 BT848_DATA_CTL_I2CSDA)
3771 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3772 BT848_DATA_CTL_I2CSCL | \
3773 BT848_DATA_CTL_I2CSDA)
3775 /* Select between old i2c code and new iicbus / smbus code */
3776 #if defined(BKTR_USE_FREEBSD_SMBUS)
3779 * The hardware interface is actually SMB commands
3782 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3786 if (bktr->id == BROOKTREE_848 ||
3787 bktr->id == BROOKTREE_848A ||
3788 bktr->id == BROOKTREE_849A)
3791 cmd = I2C_COMMAND_878;
3794 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3795 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3798 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3799 (char)(byte1 & 0xff)))
3808 i2cRead( bktr_ptr_t bktr, int addr )
3813 if (bktr->id == BROOKTREE_848 ||
3814 bktr->id == BROOKTREE_848A ||
3815 bktr->id == BROOKTREE_849A)
3818 cmd = I2C_COMMAND_878;
3820 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3823 return ((int)((unsigned char)result));
3826 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3828 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3829 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3830 /* Therefore we need low level control of the i2c bus hardware */
3832 /* Write to the MSP or DPL registers */
3834 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3836 unsigned char addr_l, addr_h, data_h, data_l ;
3838 addr_h = (addr >>8) & 0xff;
3839 addr_l = addr & 0xff;
3840 data_h = (data >>8) & 0xff;
3841 data_l = data & 0xff;
3843 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3845 iicbus_write_byte(IICBUS(bktr), dev, 0);
3846 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3847 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3848 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3849 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3851 iicbus_stop(IICBUS(bktr));
3856 /* Read from the MSP or DPL registers */
3858 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3861 unsigned char addr_l, addr_h, dev_r;
3863 u_char data_read[2];
3865 addr_h = (addr >>8) & 0xff;
3866 addr_l = addr & 0xff;
3869 /* XXX errors ignored */
3870 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3872 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3873 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3874 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3876 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3877 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3878 iicbus_stop(IICBUS(bktr));
3880 data = (data_read[0]<<8) | data_read[1];
3885 /* Reset the MSP or DPL chip */
3886 /* The user can block the reset (which is handy if you initialise the
3887 * MSP and/or DPL audio in another operating system first (eg in Windows)
3890 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3893 #ifndef BKTR_NO_MSP_RESET
3894 /* put into reset mode */
3895 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3896 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3897 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3898 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3899 iicbus_stop(IICBUS(bktr));
3901 /* put back to operational mode */
3902 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3903 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3904 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3905 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3906 iicbus_stop(IICBUS(bktr));
3911 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3914 /* XXX errors ignored */
3915 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3916 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3917 iicbus_stop(IICBUS(bktr));
3922 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3925 * Program the i2c bus directly
3928 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3933 /* clear status bits */
3934 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3936 /* build the command datum */
3937 if (bktr->id == BROOKTREE_848 ||
3938 bktr->id == BROOKTREE_848A ||
3939 bktr->id == BROOKTREE_849A) {
3940 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3942 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3944 if ( byte2 != -1 ) {
3945 data |= ((byte2 & 0xff) << 8);
3946 data |= BT848_DATA_CTL_I2CW3B;
3949 /* write the address and data */
3950 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3952 /* wait for completion */
3953 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3954 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3959 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3971 i2cRead( bktr_ptr_t bktr, int addr )
3975 /* clear status bits */
3976 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3978 /* write the READ address */
3979 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3981 if (bktr->id == BROOKTREE_848 ||
3982 bktr->id == BROOKTREE_848A ||
3983 bktr->id == BROOKTREE_849A) {
3984 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3986 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3989 /* wait for completion */
3990 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3991 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3996 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4000 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4003 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4004 /* bt848 automated i2c bus controller cannot handle */
4005 /* Therefore we need low level control of the i2c bus hardware */
4006 /* Idea for the following functions are from elsewhere in this driver and */
4007 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4010 static void i2c_start( bktr_ptr_t bktr) {
4011 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4012 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4013 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4014 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4017 static void i2c_stop( bktr_ptr_t bktr) {
4018 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4019 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4020 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4023 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4027 /* write out the byte */
4028 for ( x = 7; x >= 0; --x ) {
4029 if ( data & (1<<x) ) {
4030 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4031 DELAY( BITD ); /* assert HI data */
4032 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4033 DELAY( BITD ); /* strobe clock */
4034 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4035 DELAY( BITD ); /* release clock */
4038 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4039 DELAY( BITD ); /* assert LO data */
4040 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4041 DELAY( BITD ); /* strobe clock */
4042 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4043 DELAY( BITD ); /* release clock */
4047 /* look for an ACK */
4048 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4049 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4050 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4051 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4056 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4061 /* read in the byte */
4062 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4063 DELAY( BITD ); /* float data */
4064 for ( x = 7; x >= 0; --x ) {
4065 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4066 DELAY( BITD ); /* strobe clock */
4067 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4068 if ( bit ) byte |= (1<<x);
4069 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4070 DELAY( BITD ); /* release clock */
4072 /* After reading the byte, send an ACK */
4073 /* (unless that was the last byte, for which we send a NAK */
4074 if (last) { /* send NAK - same a writing a 1 */
4075 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4076 DELAY( BITD ); /* set data bit */
4077 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4078 DELAY( BITD ); /* strobe clock */
4079 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4080 DELAY( BITD ); /* release clock */
4081 } else { /* send ACK - same as writing a 0 */
4082 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4083 DELAY( BITD ); /* set data bit */
4084 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4085 DELAY( BITD ); /* strobe clock */
4086 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4087 DELAY( BITD ); /* release clock */
4095 /* Write to the MSP or DPL registers */
4096 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4098 unsigned int msp_w_addr = i2c_addr;
4099 unsigned char addr_l, addr_h, data_h, data_l ;
4100 addr_h = (addr >>8) & 0xff;
4101 addr_l = addr & 0xff;
4102 data_h = (data >>8) & 0xff;
4103 data_l = data & 0xff;
4106 i2c_write_byte(bktr, msp_w_addr);
4107 i2c_write_byte(bktr, dev);
4108 i2c_write_byte(bktr, addr_h);
4109 i2c_write_byte(bktr, addr_l);
4110 i2c_write_byte(bktr, data_h);
4111 i2c_write_byte(bktr, data_l);
4115 /* Read from the MSP or DPL registers */
4116 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4118 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4119 addr_h = (addr >>8) & 0xff;
4120 addr_l = addr & 0xff;
4124 i2c_write_byte(bktr,i2c_addr);
4125 i2c_write_byte(bktr,dev_r);
4126 i2c_write_byte(bktr,addr_h);
4127 i2c_write_byte(bktr,addr_l);
4130 i2c_write_byte(bktr,i2c_addr+1);
4131 i2c_read_byte(bktr,&data_1, 0);
4132 i2c_read_byte(bktr,&data_2, 1);
4134 data = (data_1<<8) | data_2;
4138 /* Reset the MSP or DPL chip */
4139 /* The user can block the reset (which is handy if you initialise the
4140 * MSP audio in another operating system first (eg in Windows)
4142 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4144 #ifndef BKTR_NO_MSP_RESET
4145 /* put into reset mode */
4147 i2c_write_byte(bktr, i2c_addr);
4148 i2c_write_byte(bktr, 0x00);
4149 i2c_write_byte(bktr, 0x80);
4150 i2c_write_byte(bktr, 0x00);
4153 /* put back to operational mode */
4155 i2c_write_byte(bktr, i2c_addr);
4156 i2c_write_byte(bktr, 0x00);
4157 i2c_write_byte(bktr, 0x00);
4158 i2c_write_byte(bktr, 0x00);
4165 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4167 /* XXX errors ignored */
4169 i2c_write_byte(bktr,bktr->remote_control_addr);
4170 i2c_read_byte(bktr,&(remote->data[0]), 0);
4171 i2c_read_byte(bktr,&(remote->data[1]), 0);
4172 i2c_read_byte(bktr,&(remote->data[2]), 0);
4178 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4181 #if defined( I2C_SOFTWARE_PROBE )
4184 * we are keeping this around for any parts that we need to probe
4185 * but that CANNOT be probed via an i2c read.
4186 * this is necessary because the hardware i2c mechanism
4187 * cannot be programmed for 1 byte writes.
4188 * currently there are no known i2c parts that we need to probe
4189 * and that cannot be safely read.
4191 static int i2cProbe( bktr_ptr_t bktr, int addr );
4196 * probe for an I2C device at addr.
4199 i2cProbe( bktr_ptr_t bktr, int addr )
4204 #if defined( EXTRA_START )
4205 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4206 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4207 #endif /* EXTRA_START */
4208 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4209 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4212 for ( x = 7; x >= 0; --x ) {
4213 if ( addr & (1<<x) ) {
4214 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4215 DELAY( BITD ); /* assert HI data */
4216 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4217 DELAY( BITD ); /* strobe clock */
4218 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4219 DELAY( BITD ); /* release clock */
4222 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4223 DELAY( BITD ); /* assert LO data */
4224 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4225 DELAY( BITD ); /* strobe clock */
4226 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4227 DELAY( BITD ); /* release clock */
4231 /* look for an ACK */
4232 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4233 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4234 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4235 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4238 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4239 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4240 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4247 #endif /* I2C_SOFTWARE_PROBE */
4252 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */