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.12 2004/04/12 00:50:40 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 */
100 #if defined(__DragonFly__) || defined(__FreeBSD__)
101 #include "use_bktr.h"
102 #endif /* __FreeBSD__ */
105 (defined(__DragonFly__) || (defined(__FreeBSD__)) && (NBKTR > 0)) \
106 || (defined(__bsdi__)) \
107 || (defined(__OpenBSD__)) \
108 || (defined(__NetBSD__)) \
112 /*******************/
113 /* *** FreeBSD *** */
114 /*******************/
115 #if defined(__DragonFly__) || defined(__FreeBSD__)
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 defined(__DragonFly__) || (__FreeBSD_version >=400000) || (NSMBUS > 0)
129 #include <sys/bus.h> /* used by smbus and newbus */
132 #if defined(__DragonFly__) || (__FreeBSD_version < 500000)
133 #include <machine/clock.h> /* for DELAY */
136 #include <bus/pci/pcivar.h>
138 #if defined(__DragonFly__) || (__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 defined(__FreeBSD__) && (__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/stdint.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(__DragonFly__) || 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 %p\n",
537 bktr_name(bktr), BROOKTREE_ALLOC,
538 (void *)(uintptr_t)vtophys(buf));
543 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
544 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
546 bktr->alloc_pages = 0;
550 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
551 METEOR_DEV0 | METEOR_RGB16;
552 bktr->dma_prog_loaded = FALSE;
555 bktr->frames = 1; /* one frame */
556 bktr->format = METEOR_GEO_RGB16;
557 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
558 bktr->pixfmt_compat = TRUE;
567 /* using the pci device id and revision id */
568 /* and determine the card type */
569 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
571 switch (PCI_PRODUCT(pci_id)) {
572 case PCI_PRODUCT_BROOKTREE_BT848:
574 bktr->id = BROOKTREE_848A;
576 bktr->id = BROOKTREE_848;
578 case PCI_PRODUCT_BROOKTREE_BT849:
579 bktr->id = BROOKTREE_849A;
581 case PCI_PRODUCT_BROOKTREE_BT878:
582 bktr->id = BROOKTREE_878;
584 case PCI_PRODUCT_BROOKTREE_BT879:
585 bktr->id = BROOKTREE_879;
590 bktr->clr_on_start = FALSE;
592 /* defaults for the tuner section of the card */
593 bktr->tflags = TUNER_INITALIZED;
594 bktr->tuner.frequency = 0;
595 bktr->tuner.channel = 0;
596 bktr->tuner.chnlset = DEFAULT_CHNLSET;
598 bktr->tuner.radio_mode = 0;
599 bktr->audio_mux_select = 0;
600 bktr->audio_mute_state = FALSE;
601 bktr->bt848_card = -1;
602 bktr->bt848_tuner = -1;
603 bktr->reverse_mute = -1;
604 bktr->slow_msp_audio = 0;
605 bktr->msp_use_mono_source = 0;
606 bktr->msp_source_selected = -1;
607 bktr->audio_mux_present = 1;
609 probeCard( bktr, TRUE, unit );
611 /* Initialise any MSP34xx or TDA98xx audio chips */
612 init_audio_devices( bktr );
617 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
618 * The circular buffer holds 'n' fixed size data blocks.
619 * vbisize is the number of bytes in the circular buffer
620 * vbiread is the point we reading data out of the circular buffer
621 * vbiinsert is the point we insert data into the circular buffer
623 static void vbidecode(bktr_ptr_t bktr) {
625 unsigned int *seq_dest;
627 /* Check if there is room in the buffer to insert the data. */
628 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
630 /* Copy the VBI data into the next free slot in the buffer. */
631 /* 'dest' is the point in vbibuffer where we want to insert new data */
632 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
633 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
635 /* Write the VBI sequence number to the end of the vbi data */
636 /* This is used by the AleVT teletext program */
637 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
639 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
640 *seq_dest = bktr->vbi_sequence_number;
642 /* And increase the VBI sequence number */
643 /* This can wrap around */
644 bktr->vbi_sequence_number++;
647 /* Increment the vbiinsert pointer */
648 /* This can wrap around */
649 bktr->vbiinsert += VBI_DATA_SIZE;
650 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
652 /* And increase the amount of vbi data in the buffer */
653 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
659 * the common interrupt handler.
660 * Returns a 0 or 1 depending on whether the interrupt has handled.
661 * In the OS specific section, bktr_intr() is defined which calls this
662 * common interrupt handler.
665 common_bktr_intr( void *arg )
674 bktr = (bktr_ptr_t) arg;
677 * check to see if any interrupts are unmasked on this device. If
678 * none are, then we likely got here by way of being on a PCI shared
679 * interrupt dispatch list.
681 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
682 return 0; /* bail out now, before we do something we
685 if (!(bktr->flags & METEOR_OPEN)) {
686 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
687 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
691 /* record and clear the INTerrupt status bits */
692 bktr_status = INL(bktr, BKTR_INT_STAT);
693 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
695 /* record and clear the device status register */
696 dstatus = INB(bktr, BKTR_DSTATUS);
697 OUTB(bktr, BKTR_DSTATUS, 0x00);
699 #if defined( STATUS_SUM )
700 /* add any new device status or INTerrupt status bits */
701 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
702 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
703 #endif /* STATUS_SUM */
704 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
705 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
709 /* if risc was disabled re-start process again */
710 /* if there was one of the following errors re-start again */
711 if ( !(bktr_status & BT848_INT_RISC_EN) ||
712 ((bktr_status &(/* BT848_INT_FBUS | */
713 /* BT848_INT_FTRGT | */
714 /* BT848_INT_FDSR | */
716 BT848_INT_RIPERR | BT848_INT_PABORT |
717 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
718 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
720 u_short tdec_save = INB(bktr, BKTR_TDEC);
722 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
723 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
725 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
727 /* Reset temporal decimation counter */
728 OUTB(bktr, BKTR_TDEC, 0);
729 OUTB(bktr, BKTR_TDEC, tdec_save);
731 /* Reset to no-fields captured state */
732 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
733 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
734 case METEOR_ONLY_ODD_FIELDS:
735 bktr->flags |= METEOR_WANT_ODD;
737 case METEOR_ONLY_EVEN_FIELDS:
738 bktr->flags |= METEOR_WANT_EVEN;
741 bktr->flags |= METEOR_WANT_MASK;
746 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
747 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
748 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
750 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
755 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
759 /* If this is not a RISC program interrupt, return */
760 if (!(bktr_status & BT848_INT_RISCI))
764 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
765 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
770 * Disable future interrupts if a capture mode is not selected.
771 * This can happen when we are in the process of closing or
772 * changing capture modes, otherwise it shouldn't happen.
774 if (!(bktr->flags & METEOR_CAP_MASK))
775 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
778 /* Determine which field generated this interrupt */
779 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
783 * Process the VBI data if it is being captured. We do this once
784 * both Odd and Even VBI data is captured. Therefore we do this
785 * in the Even field interrupt handler.
787 if ( (bktr->vbiflags & VBI_CAPTURE)
788 &&(bktr->vbiflags & VBI_OPEN)
790 /* Put VBI data into circular buffer */
793 /* If someone is blocked on reading from /dev/vbi, wake them */
794 if (bktr->vbi_read_blocked) {
795 bktr->vbi_read_blocked = FALSE;
799 /* If someone has a select() on /dev/vbi, inform them */
800 if (bktr->vbi_select.si_pid) {
801 selwakeup(&bktr->vbi_select);
809 * Register the completed field
810 * (For dual-field mode, require fields from the same frame)
812 switch ( bktr->flags & METEOR_WANT_MASK ) {
813 case METEOR_WANT_ODD : w_field = ODD_F ; break;
814 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
815 default : w_field = (ODD_F|EVEN_F); break;
817 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
818 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
819 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
820 default : req_field = (ODD_F|EVEN_F);
824 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
825 bktr->flags &= ~METEOR_WANT_EVEN;
826 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
827 ( w_field == ODD_F ))
828 bktr->flags &= ~METEOR_WANT_ODD;
829 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
830 ( w_field == (ODD_F|EVEN_F) ))
831 bktr->flags &= ~METEOR_WANT_ODD;
832 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
833 ( w_field == ODD_F )) {
834 bktr->flags &= ~METEOR_WANT_ODD;
835 bktr->flags |= METEOR_WANT_EVEN;
838 /* We're out of sync. Start over. */
839 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
840 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
841 case METEOR_ONLY_ODD_FIELDS:
842 bktr->flags |= METEOR_WANT_ODD;
844 case METEOR_ONLY_EVEN_FIELDS:
845 bktr->flags |= METEOR_WANT_EVEN;
848 bktr->flags |= METEOR_WANT_MASK;
856 * If we have a complete frame.
858 if (!(bktr->flags & METEOR_WANT_MASK)) {
859 bktr->frames_captured++;
861 * post the completion time.
863 if (bktr->flags & METEOR_WANT_TS) {
866 if ((u_int) bktr->alloc_pages * PAGE_SIZE
867 <= (bktr->frame_size + sizeof(struct timeval))) {
868 ts =(struct timeval *)bktr->bigbuf +
870 /* doesn't work in synch mode except
879 * Wake up the user in single capture mode.
881 if (bktr->flags & METEOR_SINGLE) {
884 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
886 /* disable risc, leave fifo running */
887 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
892 * If the user requested to be notified via signal,
893 * let them know the frame is complete.
896 if (bktr->proc && (bktr->signal & ~METEOR_SIG_MODE_MASK)) {
898 bktr->signal & ~METEOR_SIG_MODE_MASK );
902 * Reset the want flags if in continuous or
903 * synchronous capture mode.
907 * currently we only support 3 capture modes: odd only, even only,
908 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
909 * either even OR odd) could provide 60 (50 for PAL) pictures per
910 * second, but it would require this routine to toggle the desired frame
911 * each time, and one more different DMA program for the Bt848.
912 * As a consequence, this fourth mode is currently unsupported.
915 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
916 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
917 case METEOR_ONLY_ODD_FIELDS:
918 bktr->flags |= METEOR_WANT_ODD;
920 case METEOR_ONLY_EVEN_FIELDS:
921 bktr->flags |= METEOR_WANT_EVEN;
924 bktr->flags |= METEOR_WANT_MASK;
939 extern int bt848_format; /* used to set the default format, PAL or NTSC */
941 video_open( bktr_ptr_t bktr )
943 int frame_rate, video_format=0;
945 if (bktr->flags & METEOR_OPEN) /* device is busy */
948 bktr->flags |= METEOR_OPEN;
954 bktr->clr_on_start = FALSE;
956 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
958 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
960 #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
966 if (bt848_format == 0 )
969 if (bt848_format == 1 )
972 if (video_format == 1 ) {
973 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
974 bktr->format_params = BT848_IFORM_F_NTSCM;
977 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
978 bktr->format_params = BT848_IFORM_F_PALBDGHI;
982 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
984 /* work around for new Hauppauge 878 cards */
985 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
986 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
987 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
989 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
991 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
992 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
993 frame_rate = format_params[bktr->format_params].frame_rate;
995 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
996 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
997 OUTB(bktr, BKTR_TGCTRL, 0);
998 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
999 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
1000 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
1003 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1005 bktr->max_clip_node = 0;
1007 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
1009 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
1010 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
1012 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
1013 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
1014 OUTB(bktr, BKTR_E_SCLOOP, 0);
1015 OUTB(bktr, BKTR_O_SCLOOP, 0);
1017 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
1018 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
1020 bktr->fifo_errors = 0;
1021 bktr->dma_errors = 0;
1022 bktr->frames_captured = 0;
1023 bktr->even_fields_captured = 0;
1024 bktr->odd_fields_captured = 0;
1025 bktr->proc = (struct proc *)0;
1026 set_fps(bktr, frame_rate);
1027 bktr->video.addr = 0;
1028 bktr->video.width = 0;
1029 bktr->video.banksize = 0;
1030 bktr->video.ramsize = 0;
1031 bktr->pixfmt_compat = TRUE;
1032 bktr->format = METEOR_GEO_RGB16;
1033 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1035 bktr->capture_area_enabled = FALSE;
1037 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
1038 based motherboards will
1039 operate unreliably */
1044 vbi_open( bktr_ptr_t bktr )
1046 if (bktr->vbiflags & VBI_OPEN) /* device is busy */
1049 bktr->vbiflags |= VBI_OPEN;
1051 /* reset the VBI circular buffer pointers and clear the buffers */
1052 bktr->vbiinsert = 0;
1055 bktr->vbi_sequence_number = 0;
1056 bktr->vbi_read_blocked = FALSE;
1058 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
1059 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
1068 tuner_open( bktr_ptr_t bktr )
1070 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1073 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1076 bktr->tflags |= TUNER_OPEN;
1077 bktr->tuner.frequency = 0;
1078 bktr->tuner.channel = 0;
1079 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1080 bktr->tuner.afc = 0;
1081 bktr->tuner.radio_mode = 0;
1083 /* enable drivers on the GPIO port that control the MUXes */
1084 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1086 /* unmute the audio stream */
1087 set_audio( bktr, AUDIO_UNMUTE );
1089 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1090 init_audio_devices( bktr );
1102 video_close( bktr_ptr_t bktr )
1104 bktr->flags &= ~(METEOR_OPEN |
1109 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1110 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1112 bktr->dma_prog_loaded = FALSE;
1113 OUTB(bktr, BKTR_TDEC, 0);
1114 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1116 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1117 OUTL(bktr, BKTR_SRESET, 0xf);
1118 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1125 * tuner close handle,
1126 * place holder for tuner specific operations on a close.
1129 tuner_close( bktr_ptr_t bktr )
1131 bktr->tflags &= ~TUNER_OPEN;
1133 /* mute the audio by switching the mux */
1134 set_audio( bktr, AUDIO_MUTE );
1136 /* disable drivers on the GPIO port that control the MUXes */
1137 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1143 vbi_close( bktr_ptr_t bktr )
1146 bktr->vbiflags &= ~VBI_OPEN;
1155 video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
1161 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1164 if (bktr->flags & METEOR_CAP_MASK)
1165 return( EIO ); /* already capturing */
1167 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1170 count = bktr->rows * bktr->cols *
1171 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1173 if ((int) uio->uio_iov->iov_len < count)
1176 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1178 /* capture one frame */
1179 start_capture(bktr, METEOR_SINGLE);
1180 /* wait for capture to complete */
1181 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1182 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1183 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1184 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1190 status = tsleep(BKTR_SLEEP, PCATCH, "captur", 0);
1191 if (!status) /* successful capture */
1192 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1194 printf ("%s: read: tsleep error %d\n",
1195 bktr_name(bktr), status);
1197 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1203 * Read VBI data from the vbi circular buffer
1204 * The buffer holds vbi data blocks which are the same size
1205 * vbiinsert is the position we will insert the next item into the buffer
1206 * vbistart is the actual position in the buffer we want to read from
1207 * vbisize is the exact number of bytes in the buffer left to read
1210 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1212 int readsize, readsize2, start;
1216 while(bktr->vbisize == 0) {
1217 if (ioflag & IO_NDELAY) {
1221 bktr->vbi_read_blocked = TRUE;
1222 if ((status = tsleep(VBI_SLEEP, PCATCH, "vbi", 0))) {
1227 /* Now we have some data to give to the user */
1229 /* We cannot read more bytes than there are in
1230 * the circular buffer
1232 readsize = (int)uio->uio_iov->iov_len;
1234 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1236 /* Check if we can read this number of bytes without having
1237 * to wrap around the circular buffer */
1238 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1239 /* We need to wrap around */
1241 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1242 start = bktr->vbistart;
1243 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1245 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1247 /* We do not need to wrap around */
1248 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1251 /* Update the number of bytes left to read */
1252 bktr->vbisize -= readsize;
1254 /* Update vbistart */
1255 bktr->vbistart += readsize;
1256 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1268 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td)
1270 volatile u_char c_temp;
1272 unsigned int temp_iform;
1274 struct meteor_geomet *geo;
1275 struct meteor_counts *counts;
1276 struct meteor_video *video;
1277 struct bktr_capture_area *cap_area;
1285 case BT848SCLIP: /* set clip region */
1286 bktr->max_clip_node = 0;
1287 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1289 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1290 if (bktr->clip_list[i].y_min == 0 &&
1291 bktr->clip_list[i].y_max == 0)
1294 bktr->max_clip_node = i;
1296 /* make sure that the list contains a valid clip secquence */
1297 /* the clip rectangles should be sorted by x then by y as the
1298 second order sort key */
1300 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1302 /* to disable clipping set y_min and y_max to 0 in the first
1303 clip rectangle . The first clip rectangle is clip_list[0].
1308 if (bktr->max_clip_node == 0 &&
1309 (bktr->clip_list[0].y_min != 0 &&
1310 bktr->clip_list[0].y_max != 0)) {
1314 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1315 if (bktr->clip_list[i].y_min == 0 &&
1316 bktr->clip_list[i].y_max == 0) {
1319 if ( bktr->clip_list[i+1].y_min != 0 &&
1320 bktr->clip_list[i+1].y_max != 0 &&
1321 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1323 bktr->max_clip_node = 0;
1328 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1329 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1330 bktr->clip_list[i].x_min < 0 ||
1331 bktr->clip_list[i].x_max < 0 ||
1332 bktr->clip_list[i].y_min < 0 ||
1333 bktr->clip_list[i].y_max < 0 ) {
1334 bktr->max_clip_node = 0;
1339 bktr->dma_prog_loaded = FALSE;
1343 case METEORSTATUS: /* get Bt848 status */
1344 c_temp = INB(bktr, BKTR_DSTATUS);
1346 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1347 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1348 *(u_short *)arg = temp;
1351 case BT848SFMT: /* set input format */
1352 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1353 temp_iform = INB(bktr, BKTR_IFORM);
1354 temp_iform &= ~BT848_IFORM_FORMAT;
1355 temp_iform &= ~BT848_IFORM_XTSEL;
1356 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1358 case BT848_IFORM_F_AUTO:
1359 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1363 case BT848_IFORM_F_NTSCM:
1364 case BT848_IFORM_F_NTSCJ:
1365 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1367 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1368 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1369 bktr->format_params = temp;
1372 case BT848_IFORM_F_PALBDGHI:
1373 case BT848_IFORM_F_PALN:
1374 case BT848_IFORM_F_SECAM:
1375 case BT848_IFORM_F_RSVD:
1376 case BT848_IFORM_F_PALM:
1377 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1379 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1380 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1381 bktr->format_params = temp;
1385 bktr->dma_prog_loaded = FALSE;
1388 case METEORSFMT: /* set input format */
1389 temp_iform = INB(bktr, BKTR_IFORM);
1390 temp_iform &= ~BT848_IFORM_FORMAT;
1391 temp_iform &= ~BT848_IFORM_XTSEL;
1392 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1393 case 0: /* default */
1394 case METEOR_FMT_NTSC:
1395 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1397 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1398 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1399 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1400 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1401 bktr->format_params = BT848_IFORM_F_NTSCM;
1404 case METEOR_FMT_PAL:
1405 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1407 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1408 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1409 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1410 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1411 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1414 case METEOR_FMT_AUTOMODE:
1415 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1417 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1418 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1424 bktr->dma_prog_loaded = FALSE;
1427 case METEORGFMT: /* get input format */
1428 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1432 case BT848GFMT: /* get input format */
1433 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1436 case METEORSCOUNT: /* (re)set error counts */
1437 counts = (struct meteor_counts *) arg;
1438 bktr->fifo_errors = counts->fifo_errors;
1439 bktr->dma_errors = counts->dma_errors;
1440 bktr->frames_captured = counts->frames_captured;
1441 bktr->even_fields_captured = counts->even_fields_captured;
1442 bktr->odd_fields_captured = counts->odd_fields_captured;
1445 case METEORGCOUNT: /* get error counts */
1446 counts = (struct meteor_counts *) arg;
1447 counts->fifo_errors = bktr->fifo_errors;
1448 counts->dma_errors = bktr->dma_errors;
1449 counts->frames_captured = bktr->frames_captured;
1450 counts->even_fields_captured = bktr->even_fields_captured;
1451 counts->odd_fields_captured = bktr->odd_fields_captured;
1455 video = (struct meteor_video *)arg;
1456 video->addr = bktr->video.addr;
1457 video->width = bktr->video.width;
1458 video->banksize = bktr->video.banksize;
1459 video->ramsize = bktr->video.ramsize;
1463 video = (struct meteor_video *)arg;
1464 bktr->video.addr = video->addr;
1465 bktr->video.width = video->width;
1466 bktr->video.banksize = video->banksize;
1467 bktr->video.ramsize = video->ramsize;
1471 set_fps(bktr, *(u_short *)arg);
1475 *(u_short *)arg = bktr->fps;
1478 case METEORSHUE: /* set hue */
1479 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1482 case METEORGHUE: /* get hue */
1483 *(u_char *)arg = INB(bktr, BKTR_HUE);
1486 case METEORSBRIG: /* set brightness */
1487 char_temp = ( *(u_char *)arg & 0xff) - 128;
1488 OUTB(bktr, BKTR_BRIGHT, char_temp);
1492 case METEORGBRIG: /* get brightness */
1493 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1496 case METEORSCSAT: /* set chroma saturation */
1497 temp = (int)*(u_char *)arg;
1499 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1500 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1501 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1502 & ~(BT848_E_CONTROL_SAT_U_MSB
1503 | BT848_E_CONTROL_SAT_V_MSB));
1504 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1505 & ~(BT848_O_CONTROL_SAT_U_MSB |
1506 BT848_O_CONTROL_SAT_V_MSB));
1508 if ( temp & BIT_SEVEN_HIGH ) {
1509 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1510 | (BT848_E_CONTROL_SAT_U_MSB
1511 | BT848_E_CONTROL_SAT_V_MSB));
1512 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1513 | (BT848_O_CONTROL_SAT_U_MSB
1514 | BT848_O_CONTROL_SAT_V_MSB));
1518 case METEORGCSAT: /* get chroma saturation */
1519 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1520 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1521 temp |= BIT_SEVEN_HIGH;
1522 *(u_char *)arg = (u_char)temp;
1525 case METEORSCONT: /* set contrast */
1526 temp = (int)*(u_char *)arg & 0xff;
1528 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1529 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1530 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1531 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1532 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1533 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1534 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1537 case METEORGCONT: /* get contrast */
1538 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1539 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1540 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1543 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1544 bktr->clr_on_start = (*(int *)arg != 0);
1547 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1548 *(int *)arg = (int) bktr->clr_on_start;
1554 * Historically, applications used METEOR_SIG_MODE_MASK
1555 * to reset signal delivery.
1557 if (sig == METEOR_SIG_MODE_MASK)
1559 if (sig < 0 || sig > _SIG_MAXSIG)
1561 KKASSERT(td->td_proc != NULL);
1563 bktr->proc = td->td_proc;
1567 *(int *)arg = bktr->signal;
1572 switch (*(int *) arg) {
1573 case METEOR_CAP_SINGLE:
1575 if (bktr->bigbuf==0) /* no frame buffer allocated */
1577 /* already capturing */
1578 if (temp & METEOR_CAP_MASK)
1583 start_capture(bktr, METEOR_SINGLE);
1585 /* wait for capture to complete */
1586 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1587 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1588 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1590 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1595 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1596 error = tsleep(BKTR_SLEEP, PCATCH, "captur", hz);
1597 if (error && (error != ERESTART)) {
1598 /* Here if we didn't get complete frame */
1600 printf( "%s: ioctl: tsleep error %d %x\n",
1601 bktr_name(bktr), error,
1602 INL(bktr, BKTR_RISC_COUNT));
1606 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1608 /* disable risc, leave fifo running */
1609 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1612 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1613 /* FIXME: should we set bt848->int_stat ??? */
1616 case METEOR_CAP_CONTINOUS:
1617 if (bktr->bigbuf==0) /* no frame buffer allocated */
1619 /* already capturing */
1620 if (temp & METEOR_CAP_MASK)
1624 start_capture(bktr, METEOR_CONTIN);
1626 /* Clear the interrypt status register */
1627 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1629 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1630 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1631 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1633 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1638 dump_bt848( bt848 );
1642 case METEOR_CAP_STOP_CONT:
1643 if (bktr->flags & METEOR_CONTIN) {
1644 /* turn off capture */
1645 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1646 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1647 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1649 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1656 /* can't change parameters while capturing */
1657 if (bktr->flags & METEOR_CAP_MASK)
1661 geo = (struct meteor_geomet *) arg;
1664 /* Either even or odd, if even & odd, then these a zero */
1665 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1666 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1667 printf( "%s: ioctl: Geometry odd or even only.\n",
1672 /* set/clear even/odd flags */
1673 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1674 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1676 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1677 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1678 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1680 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1682 if (geo->columns <= 0) {
1684 "%s: ioctl: %d: columns must be greater than zero.\n",
1685 bktr_name(bktr), geo->columns);
1688 else if ((geo->columns & 0x3fe) != geo->columns) {
1690 "%s: ioctl: %d: columns too large or not even.\n",
1691 bktr_name(bktr), geo->columns);
1695 if (geo->rows <= 0) {
1697 "%s: ioctl: %d: rows must be greater than zero.\n",
1698 bktr_name(bktr), geo->rows);
1701 else if (((geo->rows & 0x7fe) != geo->rows) ||
1702 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1703 ((geo->rows & 0x3fe) != geo->rows)) ) {
1705 "%s: ioctl: %d: rows too large or not even.\n",
1706 bktr_name(bktr), geo->rows);
1710 if (geo->frames > 32) {
1711 printf("%s: ioctl: too many frames.\n",
1720 bktr->dma_prog_loaded = FALSE;
1721 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1723 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1725 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1726 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1728 /* meteor_mem structure for SYNC Capture */
1729 if (geo->frames > 1) temp += PAGE_SIZE;
1732 if ((int) temp > bktr->alloc_pages
1733 && bktr->video.addr == 0) {
1735 /*****************************/
1736 /* *** OS Dependant code *** */
1737 /*****************************/
1738 #if defined(__NetBSD__) || defined(__OpenBSD__)
1739 bus_dmamap_t dmamap;
1741 buf = get_bktr_mem(bktr, &dmamap,
1744 free_bktr_mem(bktr, bktr->dm_mem,
1746 bktr->dm_mem = dmamap;
1749 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1751 kmem_free(kernel_map, bktr->bigbuf,
1752 (bktr->alloc_pages * PAGE_SIZE));
1756 bktr->alloc_pages = temp;
1759 "%s: ioctl: Allocating %d bytes\n",
1760 bktr_name(bktr), temp*PAGE_SIZE);
1770 bktr->rows = geo->rows;
1771 bktr->cols = geo->columns;
1772 bktr->frames = geo->frames;
1774 /* Pixel format (if in meteor pixfmt compatibility mode) */
1775 if ( bktr->pixfmt_compat ) {
1776 bktr->format = METEOR_GEO_YUV_422;
1777 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1778 case 0: /* default */
1779 case METEOR_GEO_RGB16:
1780 bktr->format = METEOR_GEO_RGB16;
1782 case METEOR_GEO_RGB24:
1783 bktr->format = METEOR_GEO_RGB24;
1785 case METEOR_GEO_YUV_422:
1786 bktr->format = METEOR_GEO_YUV_422;
1787 if (geo->oformat & METEOR_GEO_YUV_12)
1788 bktr->format = METEOR_GEO_YUV_12;
1790 case METEOR_GEO_YUV_PACKED:
1791 bktr->format = METEOR_GEO_YUV_PACKED;
1794 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1797 if (bktr->flags & METEOR_CAP_MASK) {
1799 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1800 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1801 case METEOR_ONLY_ODD_FIELDS:
1802 bktr->flags |= METEOR_WANT_ODD;
1804 case METEOR_ONLY_EVEN_FIELDS:
1805 bktr->flags |= METEOR_WANT_EVEN;
1808 bktr->flags |= METEOR_WANT_MASK;
1812 start_capture(bktr, METEOR_CONTIN);
1813 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1814 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1815 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1816 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1822 /* end of METEORSETGEO */
1824 /* FIXME. The Capture Area currently has the following restrictions:
1826 y_offset may need to be even in interlaced modes
1827 RGB24 - Interlaced mode
1828 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1829 y_size must be greater than or equal to METEORSETGEO height (rows)
1830 RGB24 - Even Only (or Odd Only) mode
1831 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1832 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1833 YUV12 - Interlaced mode
1834 x_size must be greater than or equal to METEORSETGEO width (cols)
1835 y_size must be greater than or equal to METEORSETGEO height (rows)
1836 YUV12 - Even Only (or Odd Only) mode
1837 x_size must be greater than or equal to METEORSETGEO width (cols)
1838 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1841 case BT848_SCAPAREA: /* set capture area of each video frame */
1842 /* can't change parameters while capturing */
1843 if (bktr->flags & METEOR_CAP_MASK)
1846 cap_area = (struct bktr_capture_area *) arg;
1847 bktr->capture_area_x_offset = cap_area->x_offset;
1848 bktr->capture_area_y_offset = cap_area->y_offset;
1849 bktr->capture_area_x_size = cap_area->x_size;
1850 bktr->capture_area_y_size = cap_area->y_size;
1851 bktr->capture_area_enabled = TRUE;
1853 bktr->dma_prog_loaded = FALSE;
1856 case BT848_GCAPAREA: /* get capture area of each video frame */
1857 cap_area = (struct bktr_capture_area *) arg;
1858 if (bktr->capture_area_enabled == FALSE) {
1859 cap_area->x_offset = 0;
1860 cap_area->y_offset = 0;
1861 cap_area->x_size = format_params[
1862 bktr->format_params].scaled_hactive;
1863 cap_area->y_size = format_params[
1864 bktr->format_params].vactive;
1866 cap_area->x_offset = bktr->capture_area_x_offset;
1867 cap_area->y_offset = bktr->capture_area_y_offset;
1868 cap_area->x_size = bktr->capture_area_x_size;
1869 cap_area->y_size = bktr->capture_area_y_size;
1874 return common_ioctl( bktr, cmd, arg );
1884 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td)
1887 unsigned int temp, temp1;
1900 /* Read the last key pressed by the Remote Control */
1901 if (bktr->remote_control == 0) return (EINVAL);
1902 remote_read(bktr, (struct bktr_remote *)arg);
1905 #if defined( TUNER_AFC )
1906 case TVTUNER_SETAFC:
1907 bktr->tuner.afc = (*(int *)arg != 0);
1910 case TVTUNER_GETAFC:
1911 *(int *)arg = bktr->tuner.afc;
1912 /* XXX Perhaps use another bit to indicate AFC success? */
1914 #endif /* TUNER_AFC */
1916 case TVTUNER_SETCHNL:
1917 temp_mute( bktr, TRUE );
1918 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1920 temp_mute( bktr, FALSE );
1923 *(unsigned long *)arg = temp;
1925 /* after every channel change, we must restart the MSP34xx */
1926 /* audio chip to reselect NICAM STEREO or MONO audio */
1927 if ( bktr->card.msp3400c )
1928 msp_autodetect( bktr );
1930 /* after every channel change, we must restart the DPL35xx */
1931 if ( bktr->card.dpl3518a )
1932 dpl_autodetect( bktr );
1934 temp_mute( bktr, FALSE );
1937 case TVTUNER_GETCHNL:
1938 *(unsigned long *)arg = bktr->tuner.channel;
1941 case TVTUNER_SETTYPE:
1942 temp = *(unsigned long *)arg;
1943 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1945 bktr->tuner.chnlset = temp;
1948 case TVTUNER_GETTYPE:
1949 *(unsigned long *)arg = bktr->tuner.chnlset;
1952 case TVTUNER_GETSTATUS:
1953 temp = get_tuner_status( bktr );
1954 *(unsigned long *)arg = temp & 0xff;
1957 case TVTUNER_SETFREQ:
1958 temp_mute( bktr, TRUE );
1959 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1960 temp_mute( bktr, FALSE );
1962 temp_mute( bktr, FALSE );
1965 *(unsigned long *)arg = temp;
1967 /* after every channel change, we must restart the MSP34xx */
1968 /* audio chip to reselect NICAM STEREO or MONO audio */
1969 if ( bktr->card.msp3400c )
1970 msp_autodetect( bktr );
1972 /* after every channel change, we must restart the DPL35xx */
1973 if ( bktr->card.dpl3518a )
1974 dpl_autodetect( bktr );
1976 temp_mute( bktr, FALSE );
1979 case TVTUNER_GETFREQ:
1980 *(unsigned long *)arg = bktr->tuner.frequency;
1983 case TVTUNER_GETCHNLSET:
1984 return tuner_getchnlset((struct bktr_chnlset *)arg);
1986 case BT848_SAUDIO: /* set audio channel */
1987 if ( set_audio( bktr, *(int*)arg ) < 0 )
1991 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1992 case BT848_SHUE: /* set hue */
1993 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1996 case BT848_GHUE: /* get hue */
1997 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
2000 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
2001 case BT848_SBRIG: /* set brightness */
2002 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
2005 case BT848_GBRIG: /* get brightness */
2006 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2010 case BT848_SCSAT: /* set chroma saturation */
2011 tmp_int = *(int*)arg;
2013 temp = INB(bktr, BKTR_E_CONTROL);
2014 temp1 = INB(bktr, BKTR_O_CONTROL);
2015 if ( tmp_int & BIT_EIGHT_HIGH ) {
2016 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2017 BT848_E_CONTROL_SAT_V_MSB);
2018 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2019 BT848_O_CONTROL_SAT_V_MSB);
2022 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2023 BT848_E_CONTROL_SAT_V_MSB);
2024 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2025 BT848_O_CONTROL_SAT_V_MSB);
2028 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2029 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2030 OUTB(bktr, BKTR_E_CONTROL, temp);
2031 OUTB(bktr, BKTR_O_CONTROL, temp1);
2034 case BT848_GCSAT: /* get chroma saturation */
2035 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2036 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2037 tmp_int |= BIT_EIGHT_HIGH;
2038 *(int*)arg = tmp_int;
2042 case BT848_SVSAT: /* set chroma V saturation */
2043 tmp_int = *(int*)arg;
2045 temp = INB(bktr, BKTR_E_CONTROL);
2046 temp1 = INB(bktr, BKTR_O_CONTROL);
2047 if ( tmp_int & BIT_EIGHT_HIGH) {
2048 temp |= BT848_E_CONTROL_SAT_V_MSB;
2049 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2052 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2053 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2056 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2057 OUTB(bktr, BKTR_E_CONTROL, temp);
2058 OUTB(bktr, BKTR_O_CONTROL, temp1);
2061 case BT848_GVSAT: /* get chroma V saturation */
2062 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2063 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2064 tmp_int |= BIT_EIGHT_HIGH;
2065 *(int*)arg = tmp_int;
2069 case BT848_SUSAT: /* set chroma U saturation */
2070 tmp_int = *(int*)arg;
2072 temp = INB(bktr, BKTR_E_CONTROL);
2073 temp1 = INB(bktr, BKTR_O_CONTROL);
2074 if ( tmp_int & BIT_EIGHT_HIGH ) {
2075 temp |= BT848_E_CONTROL_SAT_U_MSB;
2076 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2079 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2080 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2083 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2084 OUTB(bktr, BKTR_E_CONTROL, temp);
2085 OUTB(bktr, BKTR_O_CONTROL, temp1);
2088 case BT848_GUSAT: /* get chroma U saturation */
2089 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2090 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2091 tmp_int |= BIT_EIGHT_HIGH;
2092 *(int*)arg = tmp_int;
2095 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2097 case BT848_SLNOTCH: /* set luma notch */
2098 tmp_int = (*(int *)arg & 0x7) << 5 ;
2099 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2100 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2101 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2102 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2105 case BT848_GLNOTCH: /* get luma notch */
2106 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2111 case BT848_SCONT: /* set contrast */
2112 tmp_int = *(int*)arg;
2114 temp = INB(bktr, BKTR_E_CONTROL);
2115 temp1 = INB(bktr, BKTR_O_CONTROL);
2116 if ( tmp_int & BIT_EIGHT_HIGH ) {
2117 temp |= BT848_E_CONTROL_CON_MSB;
2118 temp1 |= BT848_O_CONTROL_CON_MSB;
2121 temp &= ~BT848_E_CONTROL_CON_MSB;
2122 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2125 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2126 OUTB(bktr, BKTR_E_CONTROL, temp);
2127 OUTB(bktr, BKTR_O_CONTROL, temp1);
2130 case BT848_GCONT: /* get contrast */
2131 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2132 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2133 tmp_int |= BIT_EIGHT_HIGH;
2134 *(int*)arg = tmp_int;
2137 /* FIXME: SCBARS and CCBARS require a valid int * */
2138 /* argument to succeed, but its not used; consider */
2139 /* using the arg to store the on/off state so */
2140 /* there's only one ioctl() needed to turn cbars on/off */
2141 case BT848_SCBARS: /* set colorbar output */
2142 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2145 case BT848_CCBARS: /* clear colorbar output */
2146 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2149 case BT848_GAUDIO: /* get audio channel */
2150 temp = bktr->audio_mux_select;
2151 if ( bktr->audio_mute_state == TRUE )
2156 case BT848_SBTSC: /* set audio channel */
2157 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2161 case BT848_WEEPROM: /* write eeprom */
2162 offset = (((struct eeProm *)arg)->offset);
2163 count = (((struct eeProm *)arg)->count);
2164 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2165 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2169 case BT848_REEPROM: /* read eeprom */
2170 offset = (((struct eeProm *)arg)->offset);
2171 count = (((struct eeProm *)arg)->count);
2172 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2173 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2177 case BT848_SIGNATURE:
2178 offset = (((struct eeProm *)arg)->offset);
2179 count = (((struct eeProm *)arg)->count);
2180 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2181 if ( signCard( bktr, offset, count, buf ) < 0 )
2185 /* Ioctl's for direct gpio access */
2186 #ifdef BKTR_GPIO_ACCESS
2187 case BT848_GPIO_GET_EN:
2188 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2191 case BT848_GPIO_SET_EN:
2192 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2195 case BT848_GPIO_GET_DATA:
2196 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2199 case BT848_GPIO_SET_DATA:
2200 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2202 #endif /* BKTR_GPIO_ACCESS */
2204 /* Ioctl's for running the tuner device in radio mode */
2207 *(unsigned char *)arg = bktr->tuner.radio_mode;
2211 bktr->tuner.radio_mode = *(unsigned char *)arg;
2215 *(unsigned long *)arg = bktr->tuner.frequency;
2219 /* The argument to this ioctl is NOT freq*16. It is
2223 temp=(int)*(unsigned long *)arg;
2225 #ifdef BKTR_RADIO_DEBUG
2226 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2227 (int)*(unsigned long *)arg, temp);
2230 #ifndef BKTR_RADIO_NOFREQCHECK
2231 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2233 if(temp<8750 || temp>10800) {
2234 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2238 temp_mute( bktr, TRUE );
2239 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2240 temp_mute( bktr, FALSE );
2241 #ifdef BKTR_RADIO_DEBUG
2243 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2247 *(unsigned long *)arg = temp;
2250 /* Luigi's I2CWR ioctl */
2252 par = *(u_long *)arg;
2253 write = (par >> 24) & 0xff ;
2254 i2c_addr = (par >> 16) & 0xff ;
2255 i2c_port = (par >> 8) & 0xff ;
2256 data = (par) & 0xff ;
2259 i2cWrite( bktr, i2c_addr, i2c_port, data);
2261 data = i2cRead( bktr, i2c_addr);
2263 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2267 #ifdef BT848_MSP_READ
2268 /* I2C ioctls to allow userland access to the MSP chip */
2269 case BT848_MSP_READ:
2271 struct bktr_msp_control *msp;
2272 msp = (struct bktr_msp_control *) arg;
2273 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2274 msp->function, msp->address);
2278 case BT848_MSP_WRITE:
2280 struct bktr_msp_control *msp;
2281 msp = (struct bktr_msp_control *) arg;
2282 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2283 msp->address, msp->data );
2287 case BT848_MSP_RESET:
2288 msp_dpl_reset(bktr, bktr->msp_addr);
2293 return common_ioctl( bktr, cmd, arg );
2304 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2308 struct meteor_pixfmt *pf_pub;
2312 case METEORSINPUT: /* set input device */
2313 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2314 /* On the original bt848 boards, */
2315 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2316 /* On the Hauppauge bt878 boards, */
2317 /* Tuner is MUX0, RCA is MUX3 */
2318 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2319 /* stick with this system in our Meteor Emulation */
2321 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2323 /* this is the RCA video input */
2324 case 0: /* default */
2325 case METEOR_INPUT_DEV0:
2326 /* METEOR_INPUT_DEV_RCA: */
2327 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2329 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2330 & ~BT848_IFORM_MUXSEL);
2332 /* work around for new Hauppauge 878 cards */
2333 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2334 (bktr->id==BROOKTREE_878 ||
2335 bktr->id==BROOKTREE_879) )
2336 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2338 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2340 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2341 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2342 set_audio( bktr, AUDIO_EXTERN );
2345 /* this is the tuner input */
2346 case METEOR_INPUT_DEV1:
2347 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2349 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2350 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2351 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2352 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2353 set_audio( bktr, AUDIO_TUNER );
2356 /* this is the S-VHS input, but with a composite camera */
2357 case METEOR_INPUT_DEV2:
2358 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2360 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2361 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2362 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2363 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2364 set_audio( bktr, AUDIO_EXTERN );
2367 /* this is the S-VHS input */
2368 case METEOR_INPUT_DEV_SVIDEO:
2369 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2370 | METEOR_DEV_SVIDEO;
2371 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2372 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2373 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2374 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2375 set_audio( bktr, AUDIO_EXTERN );
2378 case METEOR_INPUT_DEV3:
2379 if ((bktr->id == BROOKTREE_848A) ||
2380 (bktr->id == BROOKTREE_849A) ||
2381 (bktr->id == BROOKTREE_878) ||
2382 (bktr->id == BROOKTREE_879) ) {
2383 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2385 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2387 /* work around for new Hauppauge 878 cards */
2388 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2389 (bktr->id==BROOKTREE_878 ||
2390 bktr->id==BROOKTREE_879) )
2391 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2393 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2395 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2396 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2397 set_audio( bktr, AUDIO_EXTERN );
2407 case METEORGINPUT: /* get input device */
2408 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2411 case METEORSACTPIXFMT:
2412 if (( *(int *)arg < 0 ) ||
2413 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2416 bktr->pixfmt = *(int *)arg;
2417 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2418 | pixfmt_swap_flags( bktr->pixfmt ));
2419 bktr->pixfmt_compat = FALSE;
2422 case METEORGACTPIXFMT:
2423 *(int *)arg = bktr->pixfmt;
2426 case METEORGSUPPIXFMT :
2427 pf_pub = (struct meteor_pixfmt *)arg;
2428 pixfmt = pf_pub->index;
2430 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2433 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2434 sizeof( *pf_pub ) );
2436 /* Patch in our format index */
2437 pf_pub->index = pixfmt;
2440 #if defined( STATUS_SUM )
2441 case BT848_GSTATUS: /* reap status */
2443 DECLARE_INTR_MASK(s);
2448 *(u_int*)arg = temp;
2451 #endif /* STATUS_SUM */
2463 /******************************************************************************
2464 * bt848 RISC programming routines:
2473 dump_bt848( bktr_ptr_t bktr )
2476 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2477 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2478 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2479 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2480 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2485 for (i = 0; i < 40; i+=4) {
2486 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2488 r[i], INL(bktr, r[i]),
2489 r[i+1], INL(bktr, r[i+1]),
2490 r[i+2], INL(bktr, r[i+2]),
2491 r[i+3], INL(bktr, r[i+3]]));
2494 printf("%s: INT STAT %x \n", bktr_name(bktr),
2495 INL(bktr, BKTR_INT_STAT));
2496 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2497 INL(bktr, BKTR_INT_MASK));
2498 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2499 INW(bktr, BKTR_GPIO_DMA_CTL));
2507 * build write instruction
2509 #define BKTR_FM1 0x6 /* packed data to follow */
2510 #define BKTR_FM3 0xe /* planar data to follow */
2511 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2512 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2513 #define BKTR_PXV 0x0 /* valid word (never used) */
2514 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2515 #define BKTR_SOL 0x2 /* first dword */
2517 #define OP_WRITE (0x1 << 28)
2518 #define OP_SKIP (0x2 << 28)
2519 #define OP_WRITEC (0x5 << 28)
2520 #define OP_JUMP (0x7 << 28)
2521 #define OP_SYNC (0x8 << 28)
2522 #define OP_WRITE123 (0x9 << 28)
2523 #define OP_WRITES123 (0xb << 28)
2524 #define OP_SOL (1 << 27) /* first instr for scanline */
2525 #define OP_EOL (1 << 26)
2527 #define BKTR_RESYNC (1 << 15)
2528 #define BKTR_GEN_IRQ (1 << 24)
2531 * The RISC status bits can be set/cleared in the RISC programs
2532 * and tested in the Interrupt Handler
2534 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2535 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2536 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2537 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2539 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2540 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2541 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2542 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2544 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2545 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2546 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2547 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2549 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2551 bktr_clip_t * clip_node;
2552 bktr->clip_start = -1;
2556 bktr->line_length = width;
2559 bktr->current_col = 0;
2561 if (bktr->max_clip_node == 0 ) return TRUE;
2562 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2565 for (i = 0; i < bktr->max_clip_node; i++ ) {
2566 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2567 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2568 bktr->clip_start = i;
2576 static bool_t getline(bktr_reg_t *bktr, int x ) {
2578 bktr_clip_t * clip_node ;
2580 if (bktr->line_length == 0 ||
2581 bktr->current_col >= bktr->line_length) return FALSE;
2583 bktr->y = min(bktr->last_y, bktr->line_length);
2584 bktr->y2 = bktr->line_length;
2586 bktr->yclip = bktr->yclip2 = -1;
2587 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2588 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2589 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2590 if (bktr->last_y <= clip_node->y_min) {
2591 bktr->y = min(bktr->last_y, bktr->line_length);
2592 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2593 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2594 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2595 bktr->last_y = bktr->yclip2;
2596 bktr->clip_start = i;
2598 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2599 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2600 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2601 if (bktr->last_y >= clip_node->y_min) {
2602 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2603 bktr->last_y = bktr->yclip2;
2604 bktr->clip_start = j;
2613 if (bktr->current_col <= bktr->line_length) {
2614 bktr->current_col = bktr->line_length;
2620 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2621 u_long operation, int pixel_width,
2622 volatile u_char ** target_buffer, int cols ) {
2625 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2626 u_int skip, start_skip;
2628 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2629 /* to the 1st byte in the mem dword containing our start addr. */
2630 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2633 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2634 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2635 case 2 : start_skip = 4 ; break;
2636 case 1 : start_skip = 8 ; break;
2639 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2640 if ( width == cols) {
2641 flag = OP_SOL | OP_EOL;
2642 } else if (bktr->current_col == 0 ) {
2644 } else if (bktr->current_col == cols) {
2649 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2650 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2655 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2656 if (operation != OP_SKIP )
2657 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2659 *target_buffer += width * pixel_width;
2660 bktr->current_col += width;
2664 if (bktr->current_col == 0 && width == cols) {
2667 } else if (bktr->current_col == 0 ) {
2670 } else if (bktr->current_col >= cols) {
2679 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2680 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2685 *(*dma_prog)++ = operation | flag |
2686 (width * pixel_width / 2 - skip);
2687 if (operation != OP_SKIP )
2688 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2689 *target_buffer += (width * pixel_width / 2) ;
2691 if ( operation == OP_WRITE )
2692 operation = OP_WRITEC;
2693 *(*dma_prog)++ = operation | flag2 |
2694 (width * pixel_width / 2);
2695 *target_buffer += (width * pixel_width / 2) ;
2696 bktr->current_col += width;
2704 * Generate the RISC instructions to capture both VBI and video images
2707 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2710 volatile u_long target_buffer, buffer, target,width;
2711 volatile u_long pitch;
2712 volatile u_long *dma_prog; /* DMA prog is an array of
2713 32 bit RISC instructions */
2714 volatile u_long *loop_point;
2715 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2716 u_int Bpp = pf_int->public.Bpp;
2717 unsigned int vbisamples; /* VBI samples per line */
2718 unsigned int vbilines; /* VBI lines per field */
2719 unsigned int num_dwords; /* DWORDS per line */
2721 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2722 vbilines = format_params[bktr->format_params].vbi_num_lines;
2723 num_dwords = vbisamples/4;
2725 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2726 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2727 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2728 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2731 OUTB(bktr, BKTR_OFORM, 0x00);
2733 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2734 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2735 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2736 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2738 /* disable gamma correction removal */
2739 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2742 OUTB(bktr, BKTR_E_VTC, 0);
2743 OUTB(bktr, BKTR_O_VTC, 0);
2745 OUTB(bktr, BKTR_E_VTC, 1);
2746 OUTB(bktr, BKTR_O_VTC, 1);
2748 bktr->capcontrol = 3 << 2 | 3;
2750 dma_prog = (u_long *) bktr->dma_prog;
2752 /* Construct Write */
2754 if (bktr->video.addr) {
2755 target_buffer = (u_long) bktr->video.addr;
2756 pitch = bktr->video.width;
2759 target_buffer = (u_long) vtophys(bktr->bigbuf);
2763 buffer = target_buffer;
2765 /* Wait for the VRE sync marking the end of the Even and
2766 * the start of the Odd field. Resync here.
2768 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_VRE;
2771 loop_point = dma_prog;
2773 /* store the VBI data */
2774 /* look for sync with packed data */
2775 *dma_prog++ = OP_SYNC | BKTR_FM1;
2777 for(i = 0; i < vbilines; i++) {
2778 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2779 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2780 (i * VBI_LINE_SIZE));
2783 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2784 /* store the Odd field video image */
2785 /* look for sync with packed data */
2786 *dma_prog++ = OP_SYNC | BKTR_FM1;
2787 *dma_prog++ = 0; /* NULL WORD */
2789 for (i = 0; i < (rows/interlace); i++) {
2790 target = target_buffer;
2791 if ( notclipped(bktr, i, width)) {
2792 split(bktr, (volatile u_long **) &dma_prog,
2793 bktr->y2 - bktr->y, OP_WRITE,
2794 Bpp, (volatile u_char **) &target, cols);
2797 while(getline(bktr, i)) {
2798 if (bktr->y != bktr->y2 ) {
2799 split(bktr, (volatile u_long **) &dma_prog,
2800 bktr->y2 - bktr->y, OP_WRITE,
2801 Bpp, (volatile u_char **) &target, cols);
2803 if (bktr->yclip != bktr->yclip2 ) {
2804 split(bktr,(volatile u_long **) &dma_prog,
2805 bktr->yclip2 - bktr->yclip,
2807 Bpp, (volatile u_char **) &target, cols);
2813 target_buffer += interlace * pitch;
2819 /* Grab the Even field */
2820 /* Look for the VRO, end of Odd field, marker */
2821 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2822 *dma_prog++ = 0; /* NULL WORD */
2824 /* store the VBI data */
2825 /* look for sync with packed data */
2826 *dma_prog++ = OP_SYNC | BKTR_FM1;
2828 for(i = 0; i < vbilines; i++) {
2829 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2830 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2831 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2834 /* store the video image */
2835 if (i_flag == 1) /*Even Only*/
2836 target_buffer = buffer;
2837 if (i_flag == 3) /*interlaced*/
2838 target_buffer = buffer+pitch;
2841 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2842 /* look for sync with packed data */
2843 *dma_prog++ = OP_SYNC | BKTR_FM1;
2844 *dma_prog++ = 0; /* NULL WORD */
2846 for (i = 0; i < (rows/interlace); i++) {
2847 target = target_buffer;
2848 if ( notclipped(bktr, i, width)) {
2849 split(bktr, (volatile u_long **) &dma_prog,
2850 bktr->y2 - bktr->y, OP_WRITE,
2851 Bpp, (volatile u_char **) &target, cols);
2853 while(getline(bktr, i)) {
2854 if (bktr->y != bktr->y2 ) {
2855 split(bktr, (volatile u_long **) &dma_prog,
2856 bktr->y2 - bktr->y, OP_WRITE,
2857 Bpp, (volatile u_char **) &target,
2860 if (bktr->yclip != bktr->yclip2 ) {
2861 split(bktr, (volatile u_long **) &dma_prog,
2862 bktr->yclip2 - bktr->yclip, OP_SKIP,
2863 Bpp, (volatile u_char **) &target, cols);
2870 target_buffer += interlace * pitch;
2875 /* Look for end of 'Even Field' */
2876 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2877 *dma_prog++ = 0; /* NULL WORD */
2879 *dma_prog++ = OP_JUMP ;
2880 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2881 *dma_prog++ = 0; /* NULL WORD */
2889 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2892 volatile u_long target_buffer, buffer, target,width;
2893 volatile u_long pitch;
2894 volatile u_long *dma_prog;
2895 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2896 u_int Bpp = pf_int->public.Bpp;
2898 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2899 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2900 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2901 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2903 OUTB(bktr, BKTR_OFORM, 0x00);
2905 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2906 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2907 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2908 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2910 /* disable gamma correction removal */
2911 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2914 OUTB(bktr, BKTR_E_VTC, 0);
2915 OUTB(bktr, BKTR_O_VTC, 0);
2917 OUTB(bktr, BKTR_E_VTC, 1);
2918 OUTB(bktr, BKTR_O_VTC, 1);
2920 bktr->capcontrol = 3 << 2 | 3;
2922 dma_prog = (u_long *) bktr->dma_prog;
2924 /* Construct Write */
2926 if (bktr->video.addr) {
2927 target_buffer = (u_long) bktr->video.addr;
2928 pitch = bktr->video.width;
2931 target_buffer = (u_long) vtophys(bktr->bigbuf);
2935 buffer = target_buffer;
2937 /* contruct sync : for video packet format */
2938 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2940 /* sync, mode indicator packed data */
2941 *dma_prog++ = 0; /* NULL WORD */
2943 for (i = 0; i < (rows/interlace); i++) {
2944 target = target_buffer;
2945 if ( notclipped(bktr, i, width)) {
2946 split(bktr, (volatile u_long **) &dma_prog,
2947 bktr->y2 - bktr->y, OP_WRITE,
2948 Bpp, (volatile u_char **) &target, cols);
2951 while(getline(bktr, i)) {
2952 if (bktr->y != bktr->y2 ) {
2953 split(bktr, (volatile u_long **) &dma_prog,
2954 bktr->y2 - bktr->y, OP_WRITE,
2955 Bpp, (volatile u_char **) &target, cols);
2957 if (bktr->yclip != bktr->yclip2 ) {
2958 split(bktr,(volatile u_long **) &dma_prog,
2959 bktr->yclip2 - bktr->yclip,
2961 Bpp, (volatile u_char **) &target, cols);
2967 target_buffer += interlace * pitch;
2974 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2975 *dma_prog++ = 0; /* NULL WORD */
2977 *dma_prog++ = OP_JUMP;
2978 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2983 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2984 *dma_prog++ = 0; /* NULL WORD */
2986 *dma_prog++ = OP_JUMP;
2987 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2992 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2993 *dma_prog++ = 0; /* NULL WORD */
2994 *dma_prog++ = OP_JUMP; ;
2995 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
2999 if (interlace == 2) {
3001 target_buffer = buffer + pitch;
3003 dma_prog = (u_long *) bktr->odd_dma_prog;
3005 /* sync vre IRQ bit */
3006 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3007 *dma_prog++ = 0; /* NULL WORD */
3009 for (i = 0; i < (rows/interlace); i++) {
3010 target = target_buffer;
3011 if ( notclipped(bktr, i, width)) {
3012 split(bktr, (volatile u_long **) &dma_prog,
3013 bktr->y2 - bktr->y, OP_WRITE,
3014 Bpp, (volatile u_char **) &target, cols);
3016 while(getline(bktr, i)) {
3017 if (bktr->y != bktr->y2 ) {
3018 split(bktr, (volatile u_long **) &dma_prog,
3019 bktr->y2 - bktr->y, OP_WRITE,
3020 Bpp, (volatile u_char **) &target,
3023 if (bktr->yclip != bktr->yclip2 ) {
3024 split(bktr, (volatile u_long **) &dma_prog,
3025 bktr->yclip2 - bktr->yclip, OP_SKIP,
3026 Bpp, (volatile u_char **) &target, cols);
3033 target_buffer += interlace * pitch;
3038 /* sync vre IRQ bit */
3039 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3040 *dma_prog++ = 0; /* NULL WORD */
3041 *dma_prog++ = OP_JUMP ;
3042 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3043 *dma_prog++ = 0; /* NULL WORD */
3051 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3052 int cols, int rows, int interlace )
3055 volatile unsigned int inst;
3056 volatile unsigned int inst3;
3057 volatile u_long target_buffer, buffer;
3058 volatile u_long *dma_prog;
3059 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3062 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3064 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3065 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3067 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3068 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3070 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3071 bktr->capcontrol = 3 << 2 | 3;
3073 dma_prog = (u_long *) bktr->dma_prog;
3075 /* Construct Write */
3077 /* write , sol, eol */
3078 inst = OP_WRITE | OP_SOL | (cols);
3079 /* write , sol, eol */
3080 inst3 = OP_WRITE | OP_EOL | (cols);
3082 if (bktr->video.addr)
3083 target_buffer = (u_long) bktr->video.addr;
3085 target_buffer = (u_long) vtophys(bktr->bigbuf);
3087 buffer = target_buffer;
3089 /* contruct sync : for video packet format */
3090 /* sync, mode indicator packed data */
3091 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3092 *dma_prog++ = 0; /* NULL WORD */
3096 for (i = 0; i < (rows/interlace); i++) {
3098 *dma_prog++ = target_buffer;
3099 *dma_prog++ = inst3;
3100 *dma_prog++ = target_buffer + b;
3101 target_buffer += interlace*(cols * 2);
3107 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
3108 *dma_prog++ = 0; /* NULL WORD */
3110 *dma_prog++ = OP_JUMP;
3111 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3116 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
3117 *dma_prog++ = 0; /* NULL WORD */
3118 *dma_prog++ = OP_JUMP;
3119 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3124 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | 1 << 15 | BKTR_VRO;
3125 *dma_prog++ = 0; /* NULL WORD */
3126 *dma_prog++ = OP_JUMP ;
3127 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3131 if (interlace == 2) {
3133 target_buffer = (u_long) buffer + cols*2;
3135 dma_prog = (u_long * ) bktr->odd_dma_prog;
3138 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3139 *dma_prog++ = 0; /* NULL WORD */
3141 for (i = 0; i < (rows/interlace) ; i++) {
3143 *dma_prog++ = target_buffer;
3144 *dma_prog++ = inst3;
3145 *dma_prog++ = target_buffer + b;
3146 target_buffer += interlace * ( cols*2);
3150 /* sync vro IRQ bit */
3151 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3152 *dma_prog++ = 0; /* NULL WORD */
3153 *dma_prog++ = OP_JUMP ;
3154 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3156 *dma_prog++ = OP_JUMP;
3157 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3158 *dma_prog++ = 0; /* NULL WORD */
3166 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3167 int cols, int rows, int interlace ){
3170 volatile unsigned int inst;
3171 volatile u_long target_buffer, t1, buffer;
3172 volatile u_long *dma_prog;
3173 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3175 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3177 dma_prog = (u_long *) bktr->dma_prog;
3179 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3181 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3182 OUTB(bktr, BKTR_OFORM, 0x00);
3184 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3185 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3187 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3188 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3190 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3191 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3192 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3193 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3195 /* disable gamma correction removal */
3196 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3198 /* Construct Write */
3199 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3200 if (bktr->video.addr)
3201 target_buffer = (u_long) bktr->video.addr;
3203 target_buffer = (u_long) vtophys(bktr->bigbuf);
3205 buffer = target_buffer;
3209 /* contruct sync : for video packet format */
3210 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3; /*sync, mode indicator packed data*/
3211 *dma_prog++ = 0; /* NULL WORD */
3213 for (i = 0; i < (rows/interlace ) ; i++) {
3215 *dma_prog++ = cols/2 | cols/2 << 16;
3216 *dma_prog++ = target_buffer;
3217 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3218 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3219 target_buffer += interlace*cols;
3224 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE; /*sync vre*/
3225 *dma_prog++ = 0; /* NULL WORD */
3227 *dma_prog++ = OP_JUMP ;
3228 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3232 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO; /*sync vre*/
3233 *dma_prog++ = 0; /* NULL WORD */
3235 *dma_prog++ = OP_JUMP;
3236 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3240 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3241 *dma_prog++ = 0; /* NULL WORD */
3243 *dma_prog++ = OP_JUMP ;
3244 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3248 if (interlace == 2) {
3250 dma_prog = (u_long * ) bktr->odd_dma_prog;
3252 target_buffer = (u_long) buffer + cols;
3253 t1 = buffer + cols/2;
3254 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3;
3255 *dma_prog++ = 0; /* NULL WORD */
3257 for (i = 0; i < (rows/interlace ) ; i++) {
3259 *dma_prog++ = cols/2 | cols/2 << 16;
3260 *dma_prog++ = target_buffer;
3261 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3262 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3263 target_buffer += interlace*cols;
3267 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3268 *dma_prog++ = 0; /* NULL WORD */
3269 *dma_prog++ = OP_JUMP ;
3270 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3271 *dma_prog++ = 0; /* NULL WORD */
3279 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3280 int cols, int rows, int interlace ){
3283 volatile unsigned int inst;
3284 volatile unsigned int inst1;
3285 volatile u_long target_buffer, t1, buffer;
3286 volatile u_long *dma_prog;
3287 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3289 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3291 dma_prog = (u_long *) bktr->dma_prog;
3293 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3295 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3296 OUTB(bktr, BKTR_OFORM, 0x0);
3298 /* Construct Write */
3299 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3300 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3301 if (bktr->video.addr)
3302 target_buffer = (u_long) bktr->video.addr;
3304 target_buffer = (u_long) vtophys(bktr->bigbuf);
3306 buffer = target_buffer;
3309 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3; /*sync, mode indicator packed data*/
3310 *dma_prog++ = 0; /* NULL WORD */
3312 for (i = 0; i < (rows/interlace )/2 ; i++) {
3314 *dma_prog++ = cols/2 | (cols/2 << 16);
3315 *dma_prog++ = target_buffer;
3316 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3317 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3318 target_buffer += interlace*cols;
3319 *dma_prog++ = inst1;
3320 *dma_prog++ = cols/2 | (cols/2 << 16);
3321 *dma_prog++ = target_buffer;
3322 target_buffer += interlace*cols;
3328 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE; /*sync vre*/
3329 *dma_prog++ = 0; /* NULL WORD */
3331 *dma_prog++ = OP_JUMP;
3332 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3336 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO; /*sync vro*/
3337 *dma_prog++ = 0; /* NULL WORD */
3339 *dma_prog++ = OP_JUMP;
3340 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3344 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
3345 *dma_prog++ = 0; /* NULL WORD */
3346 *dma_prog++ = OP_JUMP ;
3347 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3351 if (interlace == 2) {
3353 dma_prog = (u_long * ) bktr->odd_dma_prog;
3355 target_buffer = (u_long) buffer + cols;
3356 t1 = buffer + cols/2;
3357 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM3;
3358 *dma_prog++ = 0; /* NULL WORD */
3360 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3362 *dma_prog++ = cols/2 | (cols/2 << 16);
3363 *dma_prog++ = target_buffer;
3364 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3365 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3366 target_buffer += interlace*cols;
3367 *dma_prog++ = inst1;
3368 *dma_prog++ = cols/2 | (cols/2 << 16);
3369 *dma_prog++ = target_buffer;
3370 target_buffer += interlace*cols;
3377 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3378 *dma_prog++ = 0; /* NULL WORD */
3379 *dma_prog++ = OP_JUMP;
3380 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3381 *dma_prog++ = 0; /* NULL WORD */
3390 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3392 int rows, cols, interlace;
3395 struct format_params *fp;
3396 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3399 fp = &format_params[bktr->format_params];
3401 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3403 /* disable FIFO & RISC, leave other bits alone */
3404 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3406 /* set video parameters */
3407 if (bktr->capture_area_enabled)
3408 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3409 / fp->scaled_htotal / bktr->cols) - 4096;
3411 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3412 / fp->scaled_htotal / bktr->cols) - 4096;
3414 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3415 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3416 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3417 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3418 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3420 /* horizontal active */
3422 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3423 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3424 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3425 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3426 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3427 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3428 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3430 /* horizontal delay */
3431 if (bktr->capture_area_enabled)
3432 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3433 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3435 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3437 temp = temp & 0x3fe;
3439 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3440 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3441 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3442 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3443 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3444 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3445 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3447 /* vertical scale */
3449 if (bktr->capture_area_enabled) {
3450 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3451 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3453 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3456 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3459 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3460 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3462 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3465 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3470 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3471 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3472 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3473 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3474 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3475 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3476 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3479 /* vertical active */
3480 if (bktr->capture_area_enabled)
3481 temp = bktr->capture_area_y_size;
3484 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3485 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3486 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3487 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3488 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3489 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3490 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3492 /* vertical delay */
3493 if (bktr->capture_area_enabled)
3494 temp = fp->vdelay + (bktr->capture_area_y_offset);
3497 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3498 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3499 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3500 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3501 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3502 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3503 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3505 /* end of video params */
3507 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3508 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3509 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3511 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3514 /* capture control */
3517 bktr->bktr_cap_ctl =
3518 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3519 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3520 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3524 bktr->bktr_cap_ctl =
3525 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3526 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3527 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3531 bktr->bktr_cap_ctl =
3532 (BT848_CAP_CTL_DITH_FRAME |
3533 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3534 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3535 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3540 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3545 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3547 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3548 /* user, then use the rgb_vbi RISC program. */
3549 /* Otherwise, use the normal rgb RISC program */
3550 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3551 if ( (bktr->vbiflags & VBI_OPEN)
3552 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3553 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3555 bktr->bktr_cap_ctl |=
3556 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3557 bktr->vbiflags |= VBI_CAPTURE;
3558 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3561 rgb_prog(bktr, i_flag, cols, rows, interlace);
3566 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3567 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3568 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3569 | pixfmt_swap_flags( bktr->pixfmt ));
3573 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3574 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3575 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3576 | pixfmt_swap_flags( bktr->pixfmt ));
3580 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3581 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3582 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3583 | pixfmt_swap_flags( bktr->pixfmt ));
3590 /******************************************************************************
3591 * video & video capture specific routines:
3599 start_capture( bktr_ptr_t bktr, unsigned type )
3602 struct format_params *fp;
3604 fp = &format_params[bktr->format_params];
3606 /* If requested, clear out capture buf first */
3607 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3608 bzero((caddr_t)bktr->bigbuf,
3609 (size_t)bktr->rows * bktr->cols * bktr->frames *
3610 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3613 OUTB(bktr, BKTR_DSTATUS, 0);
3614 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3616 bktr->flags |= type;
3617 bktr->flags &= ~METEOR_WANT_MASK;
3618 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3619 case METEOR_ONLY_EVEN_FIELDS:
3620 bktr->flags |= METEOR_WANT_EVEN;
3623 case METEOR_ONLY_ODD_FIELDS:
3624 bktr->flags |= METEOR_WANT_ODD;
3628 bktr->flags |= METEOR_WANT_MASK;
3633 /* TDEC is only valid for continuous captures */
3634 if ( type == METEOR_SINGLE ) {
3635 u_short fps_save = bktr->fps;
3637 set_fps(bktr, fp->frame_rate);
3638 bktr->fps = fps_save;
3641 set_fps(bktr, bktr->fps);
3643 if (bktr->dma_prog_loaded == FALSE) {
3644 build_dma_prog(bktr, i_flag);
3645 bktr->dma_prog_loaded = TRUE;
3649 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3658 set_fps( bktr_ptr_t bktr, u_short fps )
3660 struct format_params *fp;
3663 fp = &format_params[bktr->format_params];
3665 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3666 case METEOR_ONLY_EVEN_FIELDS:
3667 bktr->flags |= METEOR_WANT_EVEN;
3670 case METEOR_ONLY_ODD_FIELDS:
3671 bktr->flags |= METEOR_WANT_ODD;
3675 bktr->flags |= METEOR_WANT_MASK;
3680 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3681 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3684 OUTB(bktr, BKTR_TDEC, 0);
3686 if (fps < fp->frame_rate)
3687 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3689 OUTB(bktr, BKTR_TDEC, 0);
3699 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3700 * achieve the specified swapping.
3701 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3702 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3704 * Note also that for 3Bpp, we may additionally need to do some creative
3705 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3706 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3707 * as one would expect.
3710 static u_int pixfmt_swap_flags( int pixfmt )
3712 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3715 switch ( pf->Bpp ) {
3716 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3719 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3722 case 4 : if ( pf->swap_bytes )
3723 swapf = pf->swap_shorts ? 0 : WSWAP;
3725 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3734 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3735 * our pixfmt_table indices.
3738 static int oformat_meteor_to_bt( u_long format )
3741 struct meteor_pixfmt *pf1, *pf2;
3743 /* Find format in compatibility table */
3744 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3745 if ( meteor_pixfmt_table[i].meteor_format == format )
3748 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3750 pf1 = &meteor_pixfmt_table[i].public;
3752 /* Match it with an entry in master pixel format table */
3753 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3754 pf2 = &pixfmt_table[i].public;
3756 if (( pf1->type == pf2->type ) &&
3757 ( pf1->Bpp == pf2->Bpp ) &&
3758 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3759 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3760 ( pf1->swap_shorts == pf2->swap_shorts ))
3763 if ( i >= PIXFMT_TABLE_SIZE )
3769 /******************************************************************************
3774 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3775 #define I2CBITTIME_878 (1 << 7)
3776 #define I2C_READ 0x01
3777 #define I2C_COMMAND (I2CBITTIME | \
3778 BT848_DATA_CTL_I2CSCL | \
3779 BT848_DATA_CTL_I2CSDA)
3781 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3782 BT848_DATA_CTL_I2CSCL | \
3783 BT848_DATA_CTL_I2CSDA)
3785 /* Select between old i2c code and new iicbus / smbus code */
3786 #if defined(BKTR_USE_FREEBSD_SMBUS)
3789 * The hardware interface is actually SMB commands
3792 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3796 if (bktr->id == BROOKTREE_848 ||
3797 bktr->id == BROOKTREE_848A ||
3798 bktr->id == BROOKTREE_849A)
3801 cmd = I2C_COMMAND_878;
3804 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3805 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3808 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3809 (char)(byte1 & 0xff)))
3818 i2cRead( bktr_ptr_t bktr, int addr )
3823 if (bktr->id == BROOKTREE_848 ||
3824 bktr->id == BROOKTREE_848A ||
3825 bktr->id == BROOKTREE_849A)
3828 cmd = I2C_COMMAND_878;
3830 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3833 return ((int)((unsigned char)result));
3836 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3838 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3839 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3840 /* Therefore we need low level control of the i2c bus hardware */
3842 /* Write to the MSP or DPL registers */
3844 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3846 unsigned char addr_l, addr_h, data_h, data_l ;
3848 addr_h = (addr >>8) & 0xff;
3849 addr_l = addr & 0xff;
3850 data_h = (data >>8) & 0xff;
3851 data_l = data & 0xff;
3853 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3855 iicbus_write_byte(IICBUS(bktr), dev, 0);
3856 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3857 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3858 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3859 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3861 iicbus_stop(IICBUS(bktr));
3866 /* Read from the MSP or DPL registers */
3868 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3871 unsigned char addr_l, addr_h, dev_r;
3873 u_char data_read[2];
3875 addr_h = (addr >>8) & 0xff;
3876 addr_l = addr & 0xff;
3879 /* XXX errors ignored */
3880 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3882 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3883 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3884 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3886 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3887 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3888 iicbus_stop(IICBUS(bktr));
3890 data = (data_read[0]<<8) | data_read[1];
3895 /* Reset the MSP or DPL chip */
3896 /* The user can block the reset (which is handy if you initialise the
3897 * MSP and/or DPL audio in another operating system first (eg in Windows)
3900 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3903 #ifndef BKTR_NO_MSP_RESET
3904 /* put into reset mode */
3905 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3906 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3907 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3908 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3909 iicbus_stop(IICBUS(bktr));
3911 /* put back to operational mode */
3912 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3913 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3914 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3915 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3916 iicbus_stop(IICBUS(bktr));
3921 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3924 /* XXX errors ignored */
3925 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3926 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3927 iicbus_stop(IICBUS(bktr));
3932 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3935 * Program the i2c bus directly
3938 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3943 /* clear status bits */
3944 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3946 /* build the command datum */
3947 if (bktr->id == BROOKTREE_848 ||
3948 bktr->id == BROOKTREE_848A ||
3949 bktr->id == BROOKTREE_849A) {
3950 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3952 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3954 if ( byte2 != -1 ) {
3955 data |= ((byte2 & 0xff) << 8);
3956 data |= BT848_DATA_CTL_I2CW3B;
3959 /* write the address and data */
3960 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3962 /* wait for completion */
3963 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3964 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3969 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3981 i2cRead( bktr_ptr_t bktr, int addr )
3985 /* clear status bits */
3986 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3988 /* write the READ address */
3989 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3991 if (bktr->id == BROOKTREE_848 ||
3992 bktr->id == BROOKTREE_848A ||
3993 bktr->id == BROOKTREE_849A) {
3994 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3996 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3999 /* wait for completion */
4000 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4001 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4006 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4010 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4013 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4014 /* bt848 automated i2c bus controller cannot handle */
4015 /* Therefore we need low level control of the i2c bus hardware */
4016 /* Idea for the following functions are from elsewhere in this driver and */
4017 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4020 static void i2c_start( bktr_ptr_t bktr) {
4021 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4022 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4023 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4024 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4027 static void i2c_stop( bktr_ptr_t bktr) {
4028 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4029 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4030 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4033 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4037 /* write out the byte */
4038 for ( x = 7; x >= 0; --x ) {
4039 if ( data & (1<<x) ) {
4040 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4041 DELAY( BITD ); /* assert HI data */
4042 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4043 DELAY( BITD ); /* strobe clock */
4044 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4045 DELAY( BITD ); /* release clock */
4048 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4049 DELAY( BITD ); /* assert LO data */
4050 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4051 DELAY( BITD ); /* strobe clock */
4052 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4053 DELAY( BITD ); /* release clock */
4057 /* look for an ACK */
4058 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4059 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4060 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4061 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4066 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4071 /* read in the byte */
4072 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4073 DELAY( BITD ); /* float data */
4074 for ( x = 7; x >= 0; --x ) {
4075 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4076 DELAY( BITD ); /* strobe clock */
4077 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4078 if ( bit ) byte |= (1<<x);
4079 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4080 DELAY( BITD ); /* release clock */
4082 /* After reading the byte, send an ACK */
4083 /* (unless that was the last byte, for which we send a NAK */
4084 if (last) { /* send NAK - same a writing a 1 */
4085 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4086 DELAY( BITD ); /* set data bit */
4087 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4088 DELAY( BITD ); /* strobe clock */
4089 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4090 DELAY( BITD ); /* release clock */
4091 } else { /* send ACK - same as writing a 0 */
4092 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4093 DELAY( BITD ); /* set data bit */
4094 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4095 DELAY( BITD ); /* strobe clock */
4096 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4097 DELAY( BITD ); /* release clock */
4105 /* Write to the MSP or DPL registers */
4106 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4108 unsigned int msp_w_addr = i2c_addr;
4109 unsigned char addr_l, addr_h, data_h, data_l ;
4110 addr_h = (addr >>8) & 0xff;
4111 addr_l = addr & 0xff;
4112 data_h = (data >>8) & 0xff;
4113 data_l = data & 0xff;
4116 i2c_write_byte(bktr, msp_w_addr);
4117 i2c_write_byte(bktr, dev);
4118 i2c_write_byte(bktr, addr_h);
4119 i2c_write_byte(bktr, addr_l);
4120 i2c_write_byte(bktr, data_h);
4121 i2c_write_byte(bktr, data_l);
4125 /* Read from the MSP or DPL registers */
4126 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4128 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4129 addr_h = (addr >>8) & 0xff;
4130 addr_l = addr & 0xff;
4134 i2c_write_byte(bktr,i2c_addr);
4135 i2c_write_byte(bktr,dev_r);
4136 i2c_write_byte(bktr,addr_h);
4137 i2c_write_byte(bktr,addr_l);
4140 i2c_write_byte(bktr,i2c_addr+1);
4141 i2c_read_byte(bktr,&data_1, 0);
4142 i2c_read_byte(bktr,&data_2, 1);
4144 data = (data_1<<8) | data_2;
4148 /* Reset the MSP or DPL chip */
4149 /* The user can block the reset (which is handy if you initialise the
4150 * MSP audio in another operating system first (eg in Windows)
4152 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4154 #ifndef BKTR_NO_MSP_RESET
4155 /* put into reset mode */
4157 i2c_write_byte(bktr, i2c_addr);
4158 i2c_write_byte(bktr, 0x00);
4159 i2c_write_byte(bktr, 0x80);
4160 i2c_write_byte(bktr, 0x00);
4163 /* put back to operational mode */
4165 i2c_write_byte(bktr, i2c_addr);
4166 i2c_write_byte(bktr, 0x00);
4167 i2c_write_byte(bktr, 0x00);
4168 i2c_write_byte(bktr, 0x00);
4175 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4177 /* XXX errors ignored */
4179 i2c_write_byte(bktr,bktr->remote_control_addr);
4180 i2c_read_byte(bktr,&(remote->data[0]), 0);
4181 i2c_read_byte(bktr,&(remote->data[1]), 0);
4182 i2c_read_byte(bktr,&(remote->data[2]), 0);
4188 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4191 #if defined( I2C_SOFTWARE_PROBE )
4194 * we are keeping this around for any parts that we need to probe
4195 * but that CANNOT be probed via an i2c read.
4196 * this is necessary because the hardware i2c mechanism
4197 * cannot be programmed for 1 byte writes.
4198 * currently there are no known i2c parts that we need to probe
4199 * and that cannot be safely read.
4201 static int i2cProbe( bktr_ptr_t bktr, int addr );
4206 * probe for an I2C device at addr.
4209 i2cProbe( bktr_ptr_t bktr, int addr )
4214 #if defined( EXTRA_START )
4215 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4216 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4217 #endif /* EXTRA_START */
4218 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4219 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4222 for ( x = 7; x >= 0; --x ) {
4223 if ( addr & (1<<x) ) {
4224 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4225 DELAY( BITD ); /* assert HI data */
4226 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4227 DELAY( BITD ); /* strobe clock */
4228 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4229 DELAY( BITD ); /* release clock */
4232 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4233 DELAY( BITD ); /* assert LO data */
4234 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4235 DELAY( BITD ); /* strobe clock */
4236 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4237 DELAY( BITD ); /* release clock */
4241 /* look for an ACK */
4242 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4243 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4244 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4245 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4248 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4249 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4250 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4257 #endif /* I2C_SOFTWARE_PROBE */
4262 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */