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.2 2003/06/17 04:28:23 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 */
102 #endif /* __FreeBSD__ */
105 (defined(__FreeBSD__) && (NBKTR > 0)) \
106 || (defined(__bsdi__)) \
107 || (defined(__OpenBSD__)) \
108 || (defined(__NetBSD__)) \
112 /*******************/
113 /* *** FreeBSD *** */
114 /*******************/
117 #include <sys/param.h>
118 #include <sys/systm.h>
119 #include <sys/kernel.h>
120 #include <sys/signalvar.h>
121 #include <sys/vnode.h>
124 #include <vm/vm_kern.h>
126 #include <vm/vm_extern.h>
128 #if (__FreeBSD_version >=400000) || (NSMBUS > 0)
129 #include <sys/bus.h> /* used by smbus and newbus */
132 #if (__FreeBSD_version < 500000)
133 #include <machine/clock.h> /* for DELAY */
136 #include <pci/pcivar.h>
138 #if (__FreeBSD_version >=300000)
139 #include <machine/bus_memio.h> /* for bus space */
140 #include <machine/bus.h>
144 #include <machine/ioctl_meteor.h>
145 #include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
146 #include <dev/bktr/bktr_reg.h>
147 #include <dev/bktr/bktr_tuner.h>
148 #include <dev/bktr/bktr_card.h>
149 #include <dev/bktr/bktr_audio.h>
150 #include <dev/bktr/bktr_os.h>
151 #include <dev/bktr/bktr_core.h>
152 #if defined(BKTR_FREEBSD_MODULE)
153 #include <dev/bktr/bktr_mem.h>
156 #if defined(BKTR_USE_FREEBSD_SMBUS)
157 #include <dev/bktr/bktr_i2c.h>
158 #include <dev/smbus/smbconf.h>
159 #include <dev/iicbus/iiconf.h>
160 #include "smbus_if.h"
161 #include "iicbus_if.h"
165 bktr_name(bktr_ptr_t bktr)
167 return bktr->bktr_xname;
171 #if (__FreeBSD__ == 2)
172 typedef unsigned int uintptr_t;
174 #endif /* __FreeBSD__ */
181 #endif /* __bsdi__ */
184 /**************************/
185 /* *** OpenBSD/NetBSD *** */
186 /**************************/
187 #if defined(__NetBSD__) || defined(__OpenBSD__)
189 #include <sys/param.h>
190 #include <sys/systm.h>
191 #include <sys/kernel.h>
192 #include <sys/signalvar.h>
193 #include <sys/vnode.h>
196 #include <uvm/uvm_extern.h>
199 #include <vm/vm_kern.h>
201 #include <vm/vm_extern.h>
204 #include <sys/inttypes.h> /* uintptr_t */
205 #include <dev/ic/bt8xx.h>
206 #include <dev/pci/bktr/bktr_reg.h>
207 #include <dev/pci/bktr/bktr_tuner.h>
208 #include <dev/pci/bktr/bktr_card.h>
209 #include <dev/pci/bktr/bktr_audio.h>
210 #include <dev/pci/bktr/bktr_core.h>
211 #include <dev/pci/bktr/bktr_os.h>
213 static int bt848_format = -1;
216 bktr_name(bktr_ptr_t bktr)
218 return (bktr->bktr_dev.dv_xname);
221 #endif /* __NetBSD__ || __OpenBSD__ */
225 typedef u_char bool_t;
227 #define BKTRPRI (PZERO+8)|PCATCH
228 #define VBIPRI (PZERO-4)|PCATCH
232 * memory allocated for DMA programs
234 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
236 /* When to split a dma transfer , the bt848 has timing as well as
237 dma transfer size limitations so that we have to split dma
238 transfers into two dma requests
240 #define DMA_BT848_SPLIT 319*2
243 * Allocate enough memory for:
244 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
246 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
247 * in your kernel configuration file.
250 #ifndef BROOKTREE_ALLOC_PAGES
251 #define BROOKTREE_ALLOC_PAGES 217*4
253 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
255 /* Definitions for VBI capture.
256 * There are 16 VBI lines in a PAL video field (32 in a frame),
257 * and we take 2044 samples from each line (placed in a 2048 byte buffer
259 * VBI lines are held in a circular buffer before being read by a
260 * user program from /dev/vbi.
263 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
264 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
265 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
266 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
267 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
270 /* Defines for fields */
276 * Parameters describing size of transmitted image.
279 static struct format_params format_params[] = {
280 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
281 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
283 /* # define BT848_IFORM_F_NTSCM (0x1) */
284 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
286 /* # define BT848_IFORM_F_NTSCJ (0x2) */
287 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
289 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
290 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
292 /* # define BT848_IFORM_F_PALM (0x4) */
293 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
295 /* # define BT848_IFORM_F_PALN (0x5) */
296 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
298 /* # define BT848_IFORM_F_SECAM (0x6) */
299 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
301 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
302 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
307 * Table of supported Pixel Formats
310 static struct meteor_pixfmt_internal {
311 struct meteor_pixfmt public;
315 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
316 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
318 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
319 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
321 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
323 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
324 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
325 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
326 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
327 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
328 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
329 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
332 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
335 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
338 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
340 u_long meteor_format;
341 struct meteor_pixfmt public;
342 } meteor_pixfmt_table[] = {
344 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
347 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
348 { METEOR_GEO_YUV_422,
349 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
351 { METEOR_GEO_YUV_PACKED,
352 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
355 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
358 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
362 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
363 sizeof(meteor_pixfmt_table[0]) )
366 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
367 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
371 /* sync detect threshold */
373 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
374 BT848_ADC_CRUSH) /* threshold ~125 mV */
376 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
377 BT848_ADC_SYNC_T) /* threshold ~75 mV */
383 /* debug utility for holding previous INT_STAT contents */
385 static u_long status_sum = 0;
388 * defines to make certain bit-fiddles understandable
390 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
391 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
392 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
393 #define FIFO_RISC_DISABLED 0
395 #define ALL_INTS_DISABLED 0
396 #define ALL_INTS_CLEARED 0xffffffff
397 #define CAPTURE_OFF 0
399 #define BIT_SEVEN_HIGH (1<<7)
400 #define BIT_EIGHT_HIGH (1<<8)
402 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
403 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
407 static int oformat_meteor_to_bt( u_long format );
409 static u_int pixfmt_swap_flags( int pixfmt );
412 * bt848 RISC programming routines.
415 static int dump_bt848( bktr_ptr_t bktr );
418 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
419 int rows, int interlace );
420 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
421 int rows, int interlace );
422 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
423 int rows, int interlace );
424 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
425 int rows, int interlace );
426 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
427 int rows, int interlace );
428 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
430 static bool_t getline(bktr_reg_t *, int);
431 static bool_t notclipped(bktr_reg_t * , int , int);
432 static bool_t split(bktr_reg_t *, volatile u_long **, int, u_long, int,
433 volatile u_char ** , int );
435 static void start_capture( bktr_ptr_t bktr, unsigned type );
436 static void set_fps( bktr_ptr_t bktr, u_short fps );
441 * Remote Control Functions
443 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
447 * ioctls common to both video & tuner.
449 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
452 #if !defined(BKTR_USE_FREEBSD_SMBUS)
454 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
456 static void i2c_start( bktr_ptr_t bktr);
457 static void i2c_stop( bktr_ptr_t bktr);
458 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
459 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
465 * the common attach code, used by all OS versions.
468 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
471 int need_to_allocate_memory = 1;
473 /***************************************/
474 /* *** OS Specific memory routines *** */
475 /***************************************/
476 #if defined(__NetBSD__) || defined(__OpenBSD__)
477 /* allocate space for dma program */
478 bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog,
480 bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
483 /* allocate space for the VBI buffer */
484 bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata,
486 bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
489 /* allocate space for pixel buffer */
490 if ( BROOKTREE_ALLOC )
491 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
496 #if defined(__FreeBSD__) || defined(__bsdi__)
498 /* If this is a module, check if there is any currently saved contiguous memory */
499 #if defined(BKTR_FREEBSD_MODULE)
500 if (bktr_has_stored_addresses(unit) == 1) {
501 /* recover the addresses */
502 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
503 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
504 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
505 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
506 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
507 need_to_allocate_memory = 0;
511 if (need_to_allocate_memory == 1) {
512 /* allocate space for dma program */
513 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
514 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
516 /* allocte space for the VBI buffer */
517 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
518 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
520 /* allocate space for pixel buffer */
521 if ( BROOKTREE_ALLOC )
522 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
526 #endif /* FreeBSD or BSDi */
529 /* If this is a module, save the current contiguous memory */
530 #if defined(BKTR_FREEBSD_MODULE)
531 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
532 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
533 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
534 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
535 bktr_store_address(unit, BKTR_MEM_BUF, buf);
540 printf("%s: buffer size %d, addr 0x%x\n",
541 bktr_name(bktr), BROOKTREE_ALLOC, vtophys(buf));
546 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
547 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
549 bktr->alloc_pages = 0;
553 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
554 METEOR_DEV0 | METEOR_RGB16;
555 bktr->dma_prog_loaded = FALSE;
558 bktr->frames = 1; /* one frame */
559 bktr->format = METEOR_GEO_RGB16;
560 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
561 bktr->pixfmt_compat = TRUE;
570 /* using the pci device id and revision id */
571 /* and determine the card type */
572 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
574 switch (PCI_PRODUCT(pci_id)) {
575 case PCI_PRODUCT_BROOKTREE_BT848:
577 bktr->id = BROOKTREE_848A;
579 bktr->id = BROOKTREE_848;
581 case PCI_PRODUCT_BROOKTREE_BT849:
582 bktr->id = BROOKTREE_849A;
584 case PCI_PRODUCT_BROOKTREE_BT878:
585 bktr->id = BROOKTREE_878;
587 case PCI_PRODUCT_BROOKTREE_BT879:
588 bktr->id = BROOKTREE_879;
593 bktr->clr_on_start = FALSE;
595 /* defaults for the tuner section of the card */
596 bktr->tflags = TUNER_INITALIZED;
597 bktr->tuner.frequency = 0;
598 bktr->tuner.channel = 0;
599 bktr->tuner.chnlset = DEFAULT_CHNLSET;
601 bktr->tuner.radio_mode = 0;
602 bktr->audio_mux_select = 0;
603 bktr->audio_mute_state = FALSE;
604 bktr->bt848_card = -1;
605 bktr->bt848_tuner = -1;
606 bktr->reverse_mute = -1;
607 bktr->slow_msp_audio = 0;
608 bktr->msp_use_mono_source = 0;
609 bktr->msp_source_selected = -1;
610 bktr->audio_mux_present = 1;
612 probeCard( bktr, TRUE, unit );
614 /* Initialise any MSP34xx or TDA98xx audio chips */
615 init_audio_devices( bktr );
620 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
621 * The circular buffer holds 'n' fixed size data blocks.
622 * vbisize is the number of bytes in the circular buffer
623 * vbiread is the point we reading data out of the circular buffer
624 * vbiinsert is the point we insert data into the circular buffer
626 static void vbidecode(bktr_ptr_t bktr) {
628 unsigned int *seq_dest;
630 /* Check if there is room in the buffer to insert the data. */
631 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
633 /* Copy the VBI data into the next free slot in the buffer. */
634 /* 'dest' is the point in vbibuffer where we want to insert new data */
635 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
636 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
638 /* Write the VBI sequence number to the end of the vbi data */
639 /* This is used by the AleVT teletext program */
640 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
642 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
643 *seq_dest = bktr->vbi_sequence_number;
645 /* And increase the VBI sequence number */
646 /* This can wrap around */
647 bktr->vbi_sequence_number++;
650 /* Increment the vbiinsert pointer */
651 /* This can wrap around */
652 bktr->vbiinsert += VBI_DATA_SIZE;
653 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
655 /* And increase the amount of vbi data in the buffer */
656 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
662 * the common interrupt handler.
663 * Returns a 0 or 1 depending on whether the interrupt has handled.
664 * In the OS specific section, bktr_intr() is defined which calls this
665 * common interrupt handler.
668 common_bktr_intr( void *arg )
677 bktr = (bktr_ptr_t) arg;
680 * check to see if any interrupts are unmasked on this device. If
681 * none are, then we likely got here by way of being on a PCI shared
682 * interrupt dispatch list.
684 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
685 return 0; /* bail out now, before we do something we
688 if (!(bktr->flags & METEOR_OPEN)) {
689 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
690 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
694 /* record and clear the INTerrupt status bits */
695 bktr_status = INL(bktr, BKTR_INT_STAT);
696 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
698 /* record and clear the device status register */
699 dstatus = INB(bktr, BKTR_DSTATUS);
700 OUTB(bktr, BKTR_DSTATUS, 0x00);
702 #if defined( STATUS_SUM )
703 /* add any new device status or INTerrupt status bits */
704 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
705 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
706 #endif /* STATUS_SUM */
707 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
708 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
712 /* if risc was disabled re-start process again */
713 /* if there was one of the following errors re-start again */
714 if ( !(bktr_status & BT848_INT_RISC_EN) ||
715 ((bktr_status &(/* BT848_INT_FBUS | */
716 /* BT848_INT_FTRGT | */
717 /* BT848_INT_FDSR | */
719 BT848_INT_RIPERR | BT848_INT_PABORT |
720 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
721 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
723 u_short tdec_save = INB(bktr, BKTR_TDEC);
725 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
726 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
728 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
730 /* Reset temporal decimation counter */
731 OUTB(bktr, BKTR_TDEC, 0);
732 OUTB(bktr, BKTR_TDEC, tdec_save);
734 /* Reset to no-fields captured state */
735 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
736 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
737 case METEOR_ONLY_ODD_FIELDS:
738 bktr->flags |= METEOR_WANT_ODD;
740 case METEOR_ONLY_EVEN_FIELDS:
741 bktr->flags |= METEOR_WANT_EVEN;
744 bktr->flags |= METEOR_WANT_MASK;
749 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
750 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
751 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
753 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
758 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
762 /* If this is not a RISC program interrupt, return */
763 if (!(bktr_status & BT848_INT_RISCI))
767 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
768 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
773 * Disable future interrupts if a capture mode is not selected.
774 * This can happen when we are in the process of closing or
775 * changing capture modes, otherwise it shouldn't happen.
777 if (!(bktr->flags & METEOR_CAP_MASK))
778 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
781 /* Determine which field generated this interrupt */
782 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
786 * Process the VBI data if it is being captured. We do this once
787 * both Odd and Even VBI data is captured. Therefore we do this
788 * in the Even field interrupt handler.
790 if ( (bktr->vbiflags & VBI_CAPTURE)
791 &&(bktr->vbiflags & VBI_OPEN)
793 /* Put VBI data into circular buffer */
796 /* If someone is blocked on reading from /dev/vbi, wake them */
797 if (bktr->vbi_read_blocked) {
798 bktr->vbi_read_blocked = FALSE;
802 /* If someone has a select() on /dev/vbi, inform them */
803 if (bktr->vbi_select.si_pid) {
804 selwakeup(&bktr->vbi_select);
812 * Register the completed field
813 * (For dual-field mode, require fields from the same frame)
815 switch ( bktr->flags & METEOR_WANT_MASK ) {
816 case METEOR_WANT_ODD : w_field = ODD_F ; break;
817 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
818 default : w_field = (ODD_F|EVEN_F); break;
820 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
821 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
822 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
823 default : req_field = (ODD_F|EVEN_F);
827 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
828 bktr->flags &= ~METEOR_WANT_EVEN;
829 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
830 ( w_field == ODD_F ))
831 bktr->flags &= ~METEOR_WANT_ODD;
832 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
833 ( w_field == (ODD_F|EVEN_F) ))
834 bktr->flags &= ~METEOR_WANT_ODD;
835 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
836 ( w_field == ODD_F )) {
837 bktr->flags &= ~METEOR_WANT_ODD;
838 bktr->flags |= METEOR_WANT_EVEN;
841 /* We're out of sync. Start over. */
842 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
843 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
844 case METEOR_ONLY_ODD_FIELDS:
845 bktr->flags |= METEOR_WANT_ODD;
847 case METEOR_ONLY_EVEN_FIELDS:
848 bktr->flags |= METEOR_WANT_EVEN;
851 bktr->flags |= METEOR_WANT_MASK;
859 * If we have a complete frame.
861 if (!(bktr->flags & METEOR_WANT_MASK)) {
862 bktr->frames_captured++;
864 * post the completion time.
866 if (bktr->flags & METEOR_WANT_TS) {
869 if ((u_int) bktr->alloc_pages * PAGE_SIZE
870 <= (bktr->frame_size + sizeof(struct timeval))) {
871 ts =(struct timeval *)bktr->bigbuf +
873 /* doesn't work in synch mode except
882 * Wake up the user in single capture mode.
884 if (bktr->flags & METEOR_SINGLE) {
887 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
889 /* disable risc, leave fifo running */
890 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
895 * If the user requested to be notified via signal,
896 * let them know the frame is complete.
899 if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK))
901 bktr->signal&(~METEOR_SIG_MODE_MASK) );
904 * Reset the want flags if in continuous or
905 * synchronous capture mode.
909 * currently we only support 3 capture modes: odd only, even only,
910 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
911 * either even OR odd) could provide 60 (50 for PAL) pictures per
912 * second, but it would require this routine to toggle the desired frame
913 * each time, and one more different DMA program for the Bt848.
914 * As a consequence, this fourth mode is currently unsupported.
917 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
918 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
919 case METEOR_ONLY_ODD_FIELDS:
920 bktr->flags |= METEOR_WANT_ODD;
922 case METEOR_ONLY_EVEN_FIELDS:
923 bktr->flags |= METEOR_WANT_EVEN;
926 bktr->flags |= METEOR_WANT_MASK;
941 extern int bt848_format; /* used to set the default format, PAL or NTSC */
943 video_open( bktr_ptr_t bktr )
945 int frame_rate, video_format=0;
947 if (bktr->flags & METEOR_OPEN) /* device is busy */
950 bktr->flags |= METEOR_OPEN;
956 bktr->clr_on_start = FALSE;
958 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
960 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
962 #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
968 if (bt848_format == 0 )
971 if (bt848_format == 1 )
974 if (video_format == 1 ) {
975 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
976 bktr->format_params = BT848_IFORM_F_NTSCM;
979 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
980 bktr->format_params = BT848_IFORM_F_PALBDGHI;
984 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
986 /* work around for new Hauppauge 878 cards */
987 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
988 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
989 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
991 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
993 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
994 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
995 frame_rate = format_params[bktr->format_params].frame_rate;
997 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
998 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
999 OUTB(bktr, BKTR_TGCTRL, 0);
1000 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
1001 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
1002 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
1005 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1007 bktr->max_clip_node = 0;
1009 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
1011 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
1012 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
1014 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
1015 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
1016 OUTB(bktr, BKTR_E_SCLOOP, 0);
1017 OUTB(bktr, BKTR_O_SCLOOP, 0);
1019 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
1020 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
1022 bktr->fifo_errors = 0;
1023 bktr->dma_errors = 0;
1024 bktr->frames_captured = 0;
1025 bktr->even_fields_captured = 0;
1026 bktr->odd_fields_captured = 0;
1027 bktr->proc = (struct proc *)0;
1028 set_fps(bktr, frame_rate);
1029 bktr->video.addr = 0;
1030 bktr->video.width = 0;
1031 bktr->video.banksize = 0;
1032 bktr->video.ramsize = 0;
1033 bktr->pixfmt_compat = TRUE;
1034 bktr->format = METEOR_GEO_RGB16;
1035 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1037 bktr->capture_area_enabled = FALSE;
1039 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
1040 based motherboards will
1041 operate unreliably */
1046 vbi_open( bktr_ptr_t bktr )
1048 if (bktr->vbiflags & VBI_OPEN) /* device is busy */
1051 bktr->vbiflags |= VBI_OPEN;
1053 /* reset the VBI circular buffer pointers and clear the buffers */
1054 bktr->vbiinsert = 0;
1057 bktr->vbi_sequence_number = 0;
1058 bktr->vbi_read_blocked = FALSE;
1060 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
1061 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
1070 tuner_open( bktr_ptr_t bktr )
1072 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1075 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1078 bktr->tflags |= TUNER_OPEN;
1079 bktr->tuner.frequency = 0;
1080 bktr->tuner.channel = 0;
1081 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1082 bktr->tuner.afc = 0;
1083 bktr->tuner.radio_mode = 0;
1085 /* enable drivers on the GPIO port that control the MUXes */
1086 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1088 /* unmute the audio stream */
1089 set_audio( bktr, AUDIO_UNMUTE );
1091 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1092 init_audio_devices( bktr );
1104 video_close( bktr_ptr_t bktr )
1106 bktr->flags &= ~(METEOR_OPEN |
1111 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1112 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1114 bktr->dma_prog_loaded = FALSE;
1115 OUTB(bktr, BKTR_TDEC, 0);
1116 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1118 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1119 OUTL(bktr, BKTR_SRESET, 0xf);
1120 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1127 * tuner close handle,
1128 * place holder for tuner specific operations on a close.
1131 tuner_close( bktr_ptr_t bktr )
1133 bktr->tflags &= ~TUNER_OPEN;
1135 /* mute the audio by switching the mux */
1136 set_audio( bktr, AUDIO_MUTE );
1138 /* disable drivers on the GPIO port that control the MUXes */
1139 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1145 vbi_close( bktr_ptr_t bktr )
1148 bktr->vbiflags &= ~VBI_OPEN;
1157 video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
1163 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1166 if (bktr->flags & METEOR_CAP_MASK)
1167 return( EIO ); /* already capturing */
1169 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1172 count = bktr->rows * bktr->cols *
1173 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1175 if ((int) uio->uio_iov->iov_len < count)
1178 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1180 /* capture one frame */
1181 start_capture(bktr, METEOR_SINGLE);
1182 /* wait for capture to complete */
1183 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1184 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1185 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1186 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1192 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1193 if (!status) /* successful capture */
1194 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1196 printf ("%s: read: tsleep error %d\n",
1197 bktr_name(bktr), status);
1199 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1205 * Read VBI data from the vbi circular buffer
1206 * The buffer holds vbi data blocks which are the same size
1207 * vbiinsert is the position we will insert the next item into the buffer
1208 * vbistart is the actual position in the buffer we want to read from
1209 * vbisize is the exact number of bytes in the buffer left to read
1212 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1214 int readsize, readsize2;
1218 while(bktr->vbisize == 0) {
1219 if (ioflag & IO_NDELAY) {
1223 bktr->vbi_read_blocked = TRUE;
1224 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1229 /* Now we have some data to give to the user */
1231 /* We cannot read more bytes than there are in
1232 * the circular buffer
1234 readsize = (int)uio->uio_iov->iov_len;
1236 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1238 /* Check if we can read this number of bytes without having
1239 * to wrap around the circular buffer */
1240 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1241 /* We need to wrap around */
1243 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1244 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, 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 proc* pr )
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;
1284 case BT848SCLIP: /* set clip region */
1285 bktr->max_clip_node = 0;
1286 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1288 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1289 if (bktr->clip_list[i].y_min == 0 &&
1290 bktr->clip_list[i].y_max == 0)
1293 bktr->max_clip_node = i;
1295 /* make sure that the list contains a valid clip secquence */
1296 /* the clip rectangles should be sorted by x then by y as the
1297 second order sort key */
1299 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1301 /* to disable clipping set y_min and y_max to 0 in the first
1302 clip rectangle . The first clip rectangle is clip_list[0].
1307 if (bktr->max_clip_node == 0 &&
1308 (bktr->clip_list[0].y_min != 0 &&
1309 bktr->clip_list[0].y_max != 0)) {
1313 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1314 if (bktr->clip_list[i].y_min == 0 &&
1315 bktr->clip_list[i].y_max == 0) {
1318 if ( bktr->clip_list[i+1].y_min != 0 &&
1319 bktr->clip_list[i+1].y_max != 0 &&
1320 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1322 bktr->max_clip_node = 0;
1327 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1328 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1329 bktr->clip_list[i].x_min < 0 ||
1330 bktr->clip_list[i].x_max < 0 ||
1331 bktr->clip_list[i].y_min < 0 ||
1332 bktr->clip_list[i].y_max < 0 ) {
1333 bktr->max_clip_node = 0;
1338 bktr->dma_prog_loaded = FALSE;
1342 case METEORSTATUS: /* get Bt848 status */
1343 c_temp = INB(bktr, BKTR_DSTATUS);
1345 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1346 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1347 *(u_short *)arg = temp;
1350 case BT848SFMT: /* set input format */
1351 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1352 temp_iform = INB(bktr, BKTR_IFORM);
1353 temp_iform &= ~BT848_IFORM_FORMAT;
1354 temp_iform &= ~BT848_IFORM_XTSEL;
1355 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1357 case BT848_IFORM_F_AUTO:
1358 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1362 case BT848_IFORM_F_NTSCM:
1363 case BT848_IFORM_F_NTSCJ:
1364 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1366 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1367 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1368 bktr->format_params = temp;
1371 case BT848_IFORM_F_PALBDGHI:
1372 case BT848_IFORM_F_PALN:
1373 case BT848_IFORM_F_SECAM:
1374 case BT848_IFORM_F_RSVD:
1375 case BT848_IFORM_F_PALM:
1376 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1378 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1379 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1380 bktr->format_params = temp;
1384 bktr->dma_prog_loaded = FALSE;
1387 case METEORSFMT: /* set input format */
1388 temp_iform = INB(bktr, BKTR_IFORM);
1389 temp_iform &= ~BT848_IFORM_FORMAT;
1390 temp_iform &= ~BT848_IFORM_XTSEL;
1391 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1392 case 0: /* default */
1393 case METEOR_FMT_NTSC:
1394 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1396 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1397 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1398 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1399 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1400 bktr->format_params = BT848_IFORM_F_NTSCM;
1403 case METEOR_FMT_PAL:
1404 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1406 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1407 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1408 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1409 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1410 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1413 case METEOR_FMT_AUTOMODE:
1414 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1416 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1417 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1423 bktr->dma_prog_loaded = FALSE;
1426 case METEORGFMT: /* get input format */
1427 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1431 case BT848GFMT: /* get input format */
1432 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1435 case METEORSCOUNT: /* (re)set error counts */
1436 counts = (struct meteor_counts *) arg;
1437 bktr->fifo_errors = counts->fifo_errors;
1438 bktr->dma_errors = counts->dma_errors;
1439 bktr->frames_captured = counts->frames_captured;
1440 bktr->even_fields_captured = counts->even_fields_captured;
1441 bktr->odd_fields_captured = counts->odd_fields_captured;
1444 case METEORGCOUNT: /* get error counts */
1445 counts = (struct meteor_counts *) arg;
1446 counts->fifo_errors = bktr->fifo_errors;
1447 counts->dma_errors = bktr->dma_errors;
1448 counts->frames_captured = bktr->frames_captured;
1449 counts->even_fields_captured = bktr->even_fields_captured;
1450 counts->odd_fields_captured = bktr->odd_fields_captured;
1454 video = (struct meteor_video *)arg;
1455 video->addr = bktr->video.addr;
1456 video->width = bktr->video.width;
1457 video->banksize = bktr->video.banksize;
1458 video->ramsize = bktr->video.ramsize;
1462 video = (struct meteor_video *)arg;
1463 bktr->video.addr = video->addr;
1464 bktr->video.width = video->width;
1465 bktr->video.banksize = video->banksize;
1466 bktr->video.ramsize = video->ramsize;
1470 set_fps(bktr, *(u_short *)arg);
1474 *(u_short *)arg = bktr->fps;
1477 case METEORSHUE: /* set hue */
1478 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1481 case METEORGHUE: /* get hue */
1482 *(u_char *)arg = INB(bktr, BKTR_HUE);
1485 case METEORSBRIG: /* set brightness */
1486 char_temp = ( *(u_char *)arg & 0xff) - 128;
1487 OUTB(bktr, BKTR_BRIGHT, char_temp);
1491 case METEORGBRIG: /* get brightness */
1492 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1495 case METEORSCSAT: /* set chroma saturation */
1496 temp = (int)*(u_char *)arg;
1498 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1499 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1500 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1501 & ~(BT848_E_CONTROL_SAT_U_MSB
1502 | BT848_E_CONTROL_SAT_V_MSB));
1503 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1504 & ~(BT848_O_CONTROL_SAT_U_MSB |
1505 BT848_O_CONTROL_SAT_V_MSB));
1507 if ( temp & BIT_SEVEN_HIGH ) {
1508 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1509 | (BT848_E_CONTROL_SAT_U_MSB
1510 | BT848_E_CONTROL_SAT_V_MSB));
1511 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1512 | (BT848_O_CONTROL_SAT_U_MSB
1513 | BT848_O_CONTROL_SAT_V_MSB));
1517 case METEORGCSAT: /* get chroma saturation */
1518 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1519 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1520 temp |= BIT_SEVEN_HIGH;
1521 *(u_char *)arg = (u_char)temp;
1524 case METEORSCONT: /* set contrast */
1525 temp = (int)*(u_char *)arg & 0xff;
1527 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1528 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1529 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1530 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1531 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1532 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1533 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1536 case METEORGCONT: /* get contrast */
1537 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1538 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1539 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1542 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1543 bktr->clr_on_start = (*(int *)arg != 0);
1546 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1547 *(int *)arg = (int) bktr->clr_on_start;
1551 if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
1555 bktr->signal = *(int *) arg;
1560 *(int *)arg = bktr->signal;
1565 switch (*(int *) arg) {
1566 case METEOR_CAP_SINGLE:
1568 if (bktr->bigbuf==0) /* no frame buffer allocated */
1570 /* already capturing */
1571 if (temp & METEOR_CAP_MASK)
1576 start_capture(bktr, METEOR_SINGLE);
1578 /* wait for capture to complete */
1579 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1580 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1581 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1583 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1588 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1589 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1590 if (error && (error != ERESTART)) {
1591 /* Here if we didn't get complete frame */
1593 printf( "%s: ioctl: tsleep error %d %x\n",
1594 bktr_name(bktr), error,
1595 INL(bktr, BKTR_RISC_COUNT));
1599 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1601 /* disable risc, leave fifo running */
1602 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1605 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1606 /* FIXME: should we set bt848->int_stat ??? */
1609 case METEOR_CAP_CONTINOUS:
1610 if (bktr->bigbuf==0) /* no frame buffer allocated */
1612 /* already capturing */
1613 if (temp & METEOR_CAP_MASK)
1617 start_capture(bktr, METEOR_CONTIN);
1619 /* Clear the interrypt status register */
1620 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1622 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1623 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1624 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1626 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1631 dump_bt848( bt848 );
1635 case METEOR_CAP_STOP_CONT:
1636 if (bktr->flags & METEOR_CONTIN) {
1637 /* turn off capture */
1638 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1639 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1640 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1642 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1649 /* can't change parameters while capturing */
1650 if (bktr->flags & METEOR_CAP_MASK)
1654 geo = (struct meteor_geomet *) arg;
1657 /* Either even or odd, if even & odd, then these a zero */
1658 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1659 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1660 printf( "%s: ioctl: Geometry odd or even only.\n",
1665 /* set/clear even/odd flags */
1666 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1667 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1669 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1670 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1671 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1673 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1675 if (geo->columns <= 0) {
1677 "%s: ioctl: %d: columns must be greater than zero.\n",
1678 bktr_name(bktr), geo->columns);
1681 else if ((geo->columns & 0x3fe) != geo->columns) {
1683 "%s: ioctl: %d: columns too large or not even.\n",
1684 bktr_name(bktr), geo->columns);
1688 if (geo->rows <= 0) {
1690 "%s: ioctl: %d: rows must be greater than zero.\n",
1691 bktr_name(bktr), geo->rows);
1694 else if (((geo->rows & 0x7fe) != geo->rows) ||
1695 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1696 ((geo->rows & 0x3fe) != geo->rows)) ) {
1698 "%s: ioctl: %d: rows too large or not even.\n",
1699 bktr_name(bktr), geo->rows);
1703 if (geo->frames > 32) {
1704 printf("%s: ioctl: too many frames.\n",
1713 bktr->dma_prog_loaded = FALSE;
1714 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1716 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1718 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1719 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1721 /* meteor_mem structure for SYNC Capture */
1722 if (geo->frames > 1) temp += PAGE_SIZE;
1725 if ((int) temp > bktr->alloc_pages
1726 && bktr->video.addr == 0) {
1728 /*****************************/
1729 /* *** OS Dependant code *** */
1730 /*****************************/
1731 #if defined(__NetBSD__) || defined(__OpenBSD__)
1732 bus_dmamap_t dmamap;
1734 buf = get_bktr_mem(bktr, &dmamap,
1737 free_bktr_mem(bktr, bktr->dm_mem,
1739 bktr->dm_mem = dmamap;
1742 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1744 kmem_free(kernel_map, bktr->bigbuf,
1745 (bktr->alloc_pages * PAGE_SIZE));
1749 bktr->alloc_pages = temp;
1752 "%s: ioctl: Allocating %d bytes\n",
1753 bktr_name(bktr), temp*PAGE_SIZE);
1763 bktr->rows = geo->rows;
1764 bktr->cols = geo->columns;
1765 bktr->frames = geo->frames;
1767 /* Pixel format (if in meteor pixfmt compatibility mode) */
1768 if ( bktr->pixfmt_compat ) {
1769 bktr->format = METEOR_GEO_YUV_422;
1770 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1771 case 0: /* default */
1772 case METEOR_GEO_RGB16:
1773 bktr->format = METEOR_GEO_RGB16;
1775 case METEOR_GEO_RGB24:
1776 bktr->format = METEOR_GEO_RGB24;
1778 case METEOR_GEO_YUV_422:
1779 bktr->format = METEOR_GEO_YUV_422;
1780 if (geo->oformat & METEOR_GEO_YUV_12)
1781 bktr->format = METEOR_GEO_YUV_12;
1783 case METEOR_GEO_YUV_PACKED:
1784 bktr->format = METEOR_GEO_YUV_PACKED;
1787 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1790 if (bktr->flags & METEOR_CAP_MASK) {
1792 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1793 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1794 case METEOR_ONLY_ODD_FIELDS:
1795 bktr->flags |= METEOR_WANT_ODD;
1797 case METEOR_ONLY_EVEN_FIELDS:
1798 bktr->flags |= METEOR_WANT_EVEN;
1801 bktr->flags |= METEOR_WANT_MASK;
1805 start_capture(bktr, METEOR_CONTIN);
1806 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1807 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1808 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1809 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1815 /* end of METEORSETGEO */
1817 /* FIXME. The Capture Area currently has the following restrictions:
1819 y_offset may need to be even in interlaced modes
1820 RGB24 - Interlaced mode
1821 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1822 y_size must be greater than or equal to METEORSETGEO height (rows)
1823 RGB24 - Even Only (or Odd Only) mode
1824 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1825 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1826 YUV12 - Interlaced mode
1827 x_size must be greater than or equal to METEORSETGEO width (cols)
1828 y_size must be greater than or equal to METEORSETGEO height (rows)
1829 YUV12 - Even Only (or Odd Only) mode
1830 x_size must be greater than or equal to METEORSETGEO width (cols)
1831 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1834 case BT848_SCAPAREA: /* set capture area of each video frame */
1835 /* can't change parameters while capturing */
1836 if (bktr->flags & METEOR_CAP_MASK)
1839 cap_area = (struct bktr_capture_area *) arg;
1840 bktr->capture_area_x_offset = cap_area->x_offset;
1841 bktr->capture_area_y_offset = cap_area->y_offset;
1842 bktr->capture_area_x_size = cap_area->x_size;
1843 bktr->capture_area_y_size = cap_area->y_size;
1844 bktr->capture_area_enabled = TRUE;
1846 bktr->dma_prog_loaded = FALSE;
1849 case BT848_GCAPAREA: /* get capture area of each video frame */
1850 cap_area = (struct bktr_capture_area *) arg;
1851 if (bktr->capture_area_enabled == FALSE) {
1852 cap_area->x_offset = 0;
1853 cap_area->y_offset = 0;
1854 cap_area->x_size = format_params[
1855 bktr->format_params].scaled_hactive;
1856 cap_area->y_size = format_params[
1857 bktr->format_params].vactive;
1859 cap_area->x_offset = bktr->capture_area_x_offset;
1860 cap_area->y_offset = bktr->capture_area_y_offset;
1861 cap_area->x_size = bktr->capture_area_x_size;
1862 cap_area->y_size = bktr->capture_area_y_size;
1867 return common_ioctl( bktr, cmd, arg );
1877 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
1880 unsigned int temp, temp1;
1893 /* Read the last key pressed by the Remote Control */
1894 if (bktr->remote_control == 0) return (EINVAL);
1895 remote_read(bktr, (struct bktr_remote *)arg);
1898 #if defined( TUNER_AFC )
1899 case TVTUNER_SETAFC:
1900 bktr->tuner.afc = (*(int *)arg != 0);
1903 case TVTUNER_GETAFC:
1904 *(int *)arg = bktr->tuner.afc;
1905 /* XXX Perhaps use another bit to indicate AFC success? */
1907 #endif /* TUNER_AFC */
1909 case TVTUNER_SETCHNL:
1910 temp_mute( bktr, TRUE );
1911 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1913 temp_mute( bktr, FALSE );
1916 *(unsigned long *)arg = temp;
1918 /* after every channel change, we must restart the MSP34xx */
1919 /* audio chip to reselect NICAM STEREO or MONO audio */
1920 if ( bktr->card.msp3400c )
1921 msp_autodetect( bktr );
1923 /* after every channel change, we must restart the DPL35xx */
1924 if ( bktr->card.dpl3518a )
1925 dpl_autodetect( bktr );
1927 temp_mute( bktr, FALSE );
1930 case TVTUNER_GETCHNL:
1931 *(unsigned long *)arg = bktr->tuner.channel;
1934 case TVTUNER_SETTYPE:
1935 temp = *(unsigned long *)arg;
1936 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1938 bktr->tuner.chnlset = temp;
1941 case TVTUNER_GETTYPE:
1942 *(unsigned long *)arg = bktr->tuner.chnlset;
1945 case TVTUNER_GETSTATUS:
1946 temp = get_tuner_status( bktr );
1947 *(unsigned long *)arg = temp & 0xff;
1950 case TVTUNER_SETFREQ:
1951 temp_mute( bktr, TRUE );
1952 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1953 temp_mute( bktr, FALSE );
1955 temp_mute( bktr, FALSE );
1958 *(unsigned long *)arg = temp;
1960 /* after every channel change, we must restart the MSP34xx */
1961 /* audio chip to reselect NICAM STEREO or MONO audio */
1962 if ( bktr->card.msp3400c )
1963 msp_autodetect( bktr );
1965 /* after every channel change, we must restart the DPL35xx */
1966 if ( bktr->card.dpl3518a )
1967 dpl_autodetect( bktr );
1969 temp_mute( bktr, FALSE );
1972 case TVTUNER_GETFREQ:
1973 *(unsigned long *)arg = bktr->tuner.frequency;
1976 case TVTUNER_GETCHNLSET:
1977 return tuner_getchnlset((struct bktr_chnlset *)arg);
1979 case BT848_SAUDIO: /* set audio channel */
1980 if ( set_audio( bktr, *(int*)arg ) < 0 )
1984 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1985 case BT848_SHUE: /* set hue */
1986 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1989 case BT848_GHUE: /* get hue */
1990 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1993 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1994 case BT848_SBRIG: /* set brightness */
1995 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1998 case BT848_GBRIG: /* get brightness */
1999 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2003 case BT848_SCSAT: /* set chroma saturation */
2004 tmp_int = *(int*)arg;
2006 temp = INB(bktr, BKTR_E_CONTROL);
2007 temp1 = INB(bktr, BKTR_O_CONTROL);
2008 if ( tmp_int & BIT_EIGHT_HIGH ) {
2009 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2010 BT848_E_CONTROL_SAT_V_MSB);
2011 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2012 BT848_O_CONTROL_SAT_V_MSB);
2015 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2016 BT848_E_CONTROL_SAT_V_MSB);
2017 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2018 BT848_O_CONTROL_SAT_V_MSB);
2021 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2022 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2023 OUTB(bktr, BKTR_E_CONTROL, temp);
2024 OUTB(bktr, BKTR_O_CONTROL, temp1);
2027 case BT848_GCSAT: /* get chroma saturation */
2028 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2029 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2030 tmp_int |= BIT_EIGHT_HIGH;
2031 *(int*)arg = tmp_int;
2035 case BT848_SVSAT: /* set chroma V saturation */
2036 tmp_int = *(int*)arg;
2038 temp = INB(bktr, BKTR_E_CONTROL);
2039 temp1 = INB(bktr, BKTR_O_CONTROL);
2040 if ( tmp_int & BIT_EIGHT_HIGH) {
2041 temp |= BT848_E_CONTROL_SAT_V_MSB;
2042 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2045 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2046 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2049 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2050 OUTB(bktr, BKTR_E_CONTROL, temp);
2051 OUTB(bktr, BKTR_O_CONTROL, temp1);
2054 case BT848_GVSAT: /* get chroma V saturation */
2055 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2056 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2057 tmp_int |= BIT_EIGHT_HIGH;
2058 *(int*)arg = tmp_int;
2062 case BT848_SUSAT: /* set chroma U saturation */
2063 tmp_int = *(int*)arg;
2065 temp = INB(bktr, BKTR_E_CONTROL);
2066 temp1 = INB(bktr, BKTR_O_CONTROL);
2067 if ( tmp_int & BIT_EIGHT_HIGH ) {
2068 temp |= BT848_E_CONTROL_SAT_U_MSB;
2069 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2072 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2073 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2076 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2077 OUTB(bktr, BKTR_E_CONTROL, temp);
2078 OUTB(bktr, BKTR_O_CONTROL, temp1);
2081 case BT848_GUSAT: /* get chroma U saturation */
2082 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2083 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2084 tmp_int |= BIT_EIGHT_HIGH;
2085 *(int*)arg = tmp_int;
2088 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2090 case BT848_SLNOTCH: /* set luma notch */
2091 tmp_int = (*(int *)arg & 0x7) << 5 ;
2092 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2093 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2094 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2095 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2098 case BT848_GLNOTCH: /* get luma notch */
2099 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2104 case BT848_SCONT: /* set contrast */
2105 tmp_int = *(int*)arg;
2107 temp = INB(bktr, BKTR_E_CONTROL);
2108 temp1 = INB(bktr, BKTR_O_CONTROL);
2109 if ( tmp_int & BIT_EIGHT_HIGH ) {
2110 temp |= BT848_E_CONTROL_CON_MSB;
2111 temp1 |= BT848_O_CONTROL_CON_MSB;
2114 temp &= ~BT848_E_CONTROL_CON_MSB;
2115 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2118 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2119 OUTB(bktr, BKTR_E_CONTROL, temp);
2120 OUTB(bktr, BKTR_O_CONTROL, temp1);
2123 case BT848_GCONT: /* get contrast */
2124 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2125 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2126 tmp_int |= BIT_EIGHT_HIGH;
2127 *(int*)arg = tmp_int;
2130 /* FIXME: SCBARS and CCBARS require a valid int * */
2131 /* argument to succeed, but its not used; consider */
2132 /* using the arg to store the on/off state so */
2133 /* there's only one ioctl() needed to turn cbars on/off */
2134 case BT848_SCBARS: /* set colorbar output */
2135 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2138 case BT848_CCBARS: /* clear colorbar output */
2139 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2142 case BT848_GAUDIO: /* get audio channel */
2143 temp = bktr->audio_mux_select;
2144 if ( bktr->audio_mute_state == TRUE )
2149 case BT848_SBTSC: /* set audio channel */
2150 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2154 case BT848_WEEPROM: /* write eeprom */
2155 offset = (((struct eeProm *)arg)->offset);
2156 count = (((struct eeProm *)arg)->count);
2157 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2158 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2162 case BT848_REEPROM: /* read eeprom */
2163 offset = (((struct eeProm *)arg)->offset);
2164 count = (((struct eeProm *)arg)->count);
2165 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2166 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2170 case BT848_SIGNATURE:
2171 offset = (((struct eeProm *)arg)->offset);
2172 count = (((struct eeProm *)arg)->count);
2173 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2174 if ( signCard( bktr, offset, count, buf ) < 0 )
2178 /* Ioctl's for direct gpio access */
2179 #ifdef BKTR_GPIO_ACCESS
2180 case BT848_GPIO_GET_EN:
2181 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2184 case BT848_GPIO_SET_EN:
2185 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2188 case BT848_GPIO_GET_DATA:
2189 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2192 case BT848_GPIO_SET_DATA:
2193 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2195 #endif /* BKTR_GPIO_ACCESS */
2197 /* Ioctl's for running the tuner device in radio mode */
2200 *(unsigned char *)arg = bktr->tuner.radio_mode;
2204 bktr->tuner.radio_mode = *(unsigned char *)arg;
2208 *(unsigned long *)arg = bktr->tuner.frequency;
2212 /* The argument to this ioctl is NOT freq*16. It is
2216 temp=(int)*(unsigned long *)arg;
2218 #ifdef BKTR_RADIO_DEBUG
2219 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2220 (int)*(unsigned long *)arg, temp);
2223 #ifndef BKTR_RADIO_NOFREQCHECK
2224 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2226 if(temp<8750 || temp>10800) {
2227 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2231 temp_mute( bktr, TRUE );
2232 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2233 temp_mute( bktr, FALSE );
2234 #ifdef BKTR_RADIO_DEBUG
2236 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2240 *(unsigned long *)arg = temp;
2243 /* Luigi's I2CWR ioctl */
2245 par = *(u_long *)arg;
2246 write = (par >> 24) & 0xff ;
2247 i2c_addr = (par >> 16) & 0xff ;
2248 i2c_port = (par >> 8) & 0xff ;
2249 data = (par) & 0xff ;
2252 i2cWrite( bktr, i2c_addr, i2c_port, data);
2254 data = i2cRead( bktr, i2c_addr);
2256 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2260 #ifdef BT848_MSP_READ
2261 /* I2C ioctls to allow userland access to the MSP chip */
2262 case BT848_MSP_READ:
2264 struct bktr_msp_control *msp;
2265 msp = (struct bktr_msp_control *) arg;
2266 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2267 msp->function, msp->address);
2271 case BT848_MSP_WRITE:
2273 struct bktr_msp_control *msp;
2274 msp = (struct bktr_msp_control *) arg;
2275 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2276 msp->address, msp->data );
2280 case BT848_MSP_RESET:
2281 msp_dpl_reset(bktr, bktr->msp_addr);
2286 return common_ioctl( bktr, cmd, arg );
2297 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2301 struct meteor_pixfmt *pf_pub;
2305 case METEORSINPUT: /* set input device */
2306 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2307 /* On the original bt848 boards, */
2308 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2309 /* On the Hauppauge bt878 boards, */
2310 /* Tuner is MUX0, RCA is MUX3 */
2311 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2312 /* stick with this system in our Meteor Emulation */
2314 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2316 /* this is the RCA video input */
2317 case 0: /* default */
2318 case METEOR_INPUT_DEV0:
2319 /* METEOR_INPUT_DEV_RCA: */
2320 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2322 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2323 & ~BT848_IFORM_MUXSEL);
2325 /* work around for new Hauppauge 878 cards */
2326 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2327 (bktr->id==BROOKTREE_878 ||
2328 bktr->id==BROOKTREE_879) )
2329 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2331 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2333 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2334 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2335 set_audio( bktr, AUDIO_EXTERN );
2338 /* this is the tuner input */
2339 case METEOR_INPUT_DEV1:
2340 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2342 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2343 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2344 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2345 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2346 set_audio( bktr, AUDIO_TUNER );
2349 /* this is the S-VHS input, but with a composite camera */
2350 case METEOR_INPUT_DEV2:
2351 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2353 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2354 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2355 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2356 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2357 set_audio( bktr, AUDIO_EXTERN );
2360 /* this is the S-VHS input */
2361 case METEOR_INPUT_DEV_SVIDEO:
2362 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2363 | METEOR_DEV_SVIDEO;
2364 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2365 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2366 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2367 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2368 set_audio( bktr, AUDIO_EXTERN );
2371 case METEOR_INPUT_DEV3:
2372 if ((bktr->id == BROOKTREE_848A) ||
2373 (bktr->id == BROOKTREE_849A) ||
2374 (bktr->id == BROOKTREE_878) ||
2375 (bktr->id == BROOKTREE_879) ) {
2376 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2378 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2380 /* work around for new Hauppauge 878 cards */
2381 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2382 (bktr->id==BROOKTREE_878 ||
2383 bktr->id==BROOKTREE_879) )
2384 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2386 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2388 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2389 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2390 set_audio( bktr, AUDIO_EXTERN );
2400 case METEORGINPUT: /* get input device */
2401 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2404 case METEORSACTPIXFMT:
2405 if (( *(int *)arg < 0 ) ||
2406 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2409 bktr->pixfmt = *(int *)arg;
2410 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2411 | pixfmt_swap_flags( bktr->pixfmt ));
2412 bktr->pixfmt_compat = FALSE;
2415 case METEORGACTPIXFMT:
2416 *(int *)arg = bktr->pixfmt;
2419 case METEORGSUPPIXFMT :
2420 pf_pub = (struct meteor_pixfmt *)arg;
2421 pixfmt = pf_pub->index;
2423 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2426 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2427 sizeof( *pf_pub ) );
2429 /* Patch in our format index */
2430 pf_pub->index = pixfmt;
2433 #if defined( STATUS_SUM )
2434 case BT848_GSTATUS: /* reap status */
2436 DECLARE_INTR_MASK(s);
2441 *(u_int*)arg = temp;
2444 #endif /* STATUS_SUM */
2456 /******************************************************************************
2457 * bt848 RISC programming routines:
2466 dump_bt848( bktr_ptr_t bktr )
2469 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2470 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2471 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2472 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2473 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2478 for (i = 0; i < 40; i+=4) {
2479 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2481 r[i], INL(bktr, r[i]),
2482 r[i+1], INL(bktr, r[i+1]),
2483 r[i+2], INL(bktr, r[i+2]),
2484 r[i+3], INL(bktr, r[i+3]]));
2487 printf("%s: INT STAT %x \n", bktr_name(bktr),
2488 INL(bktr, BKTR_INT_STAT));
2489 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2490 INL(bktr, BKTR_INT_MASK));
2491 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2492 INW(bktr, BKTR_GPIO_DMA_CTL));
2500 * build write instruction
2502 #define BKTR_FM1 0x6 /* packed data to follow */
2503 #define BKTR_FM3 0xe /* planar data to follow */
2504 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2505 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2506 #define BKTR_PXV 0x0 /* valid word (never used) */
2507 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2508 #define BKTR_SOL 0x2 /* first dword */
2510 #define OP_WRITE (0x1 << 28)
2511 #define OP_SKIP (0x2 << 28)
2512 #define OP_WRITEC (0x5 << 28)
2513 #define OP_JUMP (0x7 << 28)
2514 #define OP_SYNC (0x8 << 28)
2515 #define OP_WRITE123 (0x9 << 28)
2516 #define OP_WRITES123 (0xb << 28)
2517 #define OP_SOL (1 << 27) /* first instr for scanline */
2518 #define OP_EOL (1 << 26)
2520 #define BKTR_RESYNC (1 << 15)
2521 #define BKTR_GEN_IRQ (1 << 24)
2524 * The RISC status bits can be set/cleared in the RISC programs
2525 * and tested in the Interrupt Handler
2527 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2528 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2529 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2530 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2532 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2533 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2534 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2535 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2537 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2538 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2539 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2540 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2542 bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2544 bktr_clip_t * clip_node;
2545 bktr->clip_start = -1;
2549 bktr->line_length = width;
2552 bktr->current_col = 0;
2554 if (bktr->max_clip_node == 0 ) return TRUE;
2555 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2558 for (i = 0; i < bktr->max_clip_node; i++ ) {
2559 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2560 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2561 bktr->clip_start = i;
2569 bool_t getline(bktr_reg_t *bktr, int x ) {
2571 bktr_clip_t * clip_node ;
2573 if (bktr->line_length == 0 ||
2574 bktr->current_col >= bktr->line_length) return FALSE;
2576 bktr->y = min(bktr->last_y, bktr->line_length);
2577 bktr->y2 = bktr->line_length;
2579 bktr->yclip = bktr->yclip2 = -1;
2580 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2581 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2582 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2583 if (bktr->last_y <= clip_node->y_min) {
2584 bktr->y = min(bktr->last_y, bktr->line_length);
2585 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2586 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2587 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2588 bktr->last_y = bktr->yclip2;
2589 bktr->clip_start = i;
2591 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2592 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2593 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2594 if (bktr->last_y >= clip_node->y_min) {
2595 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2596 bktr->last_y = bktr->yclip2;
2597 bktr->clip_start = j;
2606 if (bktr->current_col <= bktr->line_length) {
2607 bktr->current_col = bktr->line_length;
2613 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2614 u_long operation, int pixel_width,
2615 volatile u_char ** target_buffer, int cols ) {
2618 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2619 u_int skip, start_skip;
2621 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2622 /* to the 1st byte in the mem dword containing our start addr. */
2623 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2626 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2627 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2628 case 2 : start_skip = 4 ; break;
2629 case 1 : start_skip = 8 ; break;
2632 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2633 if ( width == cols) {
2634 flag = OP_SOL | OP_EOL;
2635 } else if (bktr->current_col == 0 ) {
2637 } else if (bktr->current_col == cols) {
2642 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2643 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2648 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2649 if (operation != OP_SKIP )
2650 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2652 *target_buffer += width * pixel_width;
2653 bktr->current_col += width;
2657 if (bktr->current_col == 0 && width == cols) {
2660 } else if (bktr->current_col == 0 ) {
2663 } else if (bktr->current_col >= cols) {
2672 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2673 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2678 *(*dma_prog)++ = operation | flag |
2679 (width * pixel_width / 2 - skip);
2680 if (operation != OP_SKIP )
2681 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2682 *target_buffer += (width * pixel_width / 2) ;
2684 if ( operation == OP_WRITE )
2685 operation = OP_WRITEC;
2686 *(*dma_prog)++ = operation | flag2 |
2687 (width * pixel_width / 2);
2688 *target_buffer += (width * pixel_width / 2) ;
2689 bktr->current_col += width;
2697 * Generate the RISC instructions to capture both VBI and video images
2700 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2703 volatile u_long target_buffer, buffer, target,width;
2704 volatile u_long pitch;
2705 volatile u_long *dma_prog; /* DMA prog is an array of
2706 32 bit RISC instructions */
2707 volatile u_long *loop_point;
2708 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2709 u_int Bpp = pf_int->public.Bpp;
2710 unsigned int vbisamples; /* VBI samples per line */
2711 unsigned int vbilines; /* VBI lines per field */
2712 unsigned int num_dwords; /* DWORDS per line */
2714 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2715 vbilines = format_params[bktr->format_params].vbi_num_lines;
2716 num_dwords = vbisamples/4;
2718 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2719 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2720 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2721 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2724 OUTB(bktr, BKTR_OFORM, 0x00);
2726 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2727 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2728 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2729 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2731 /* disable gamma correction removal */
2732 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2735 OUTB(bktr, BKTR_E_VTC, 0);
2736 OUTB(bktr, BKTR_O_VTC, 0);
2738 OUTB(bktr, BKTR_E_VTC, 1);
2739 OUTB(bktr, BKTR_O_VTC, 1);
2741 bktr->capcontrol = 3 << 2 | 3;
2743 dma_prog = (u_long *) bktr->dma_prog;
2745 /* Construct Write */
2747 if (bktr->video.addr) {
2748 target_buffer = (u_long) bktr->video.addr;
2749 pitch = bktr->video.width;
2752 target_buffer = (u_long) vtophys(bktr->bigbuf);
2756 buffer = target_buffer;
2758 /* Wait for the VRE sync marking the end of the Even and
2759 * the start of the Odd field. Resync here.
2761 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2764 loop_point = dma_prog;
2766 /* store the VBI data */
2767 /* look for sync with packed data */
2768 *dma_prog++ = OP_SYNC | BKTR_FM1;
2770 for(i = 0; i < vbilines; i++) {
2771 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2772 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2773 (i * VBI_LINE_SIZE));
2776 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2777 /* store the Odd field video image */
2778 /* look for sync with packed data */
2779 *dma_prog++ = OP_SYNC | BKTR_FM1;
2780 *dma_prog++ = 0; /* NULL WORD */
2782 for (i = 0; i < (rows/interlace); i++) {
2783 target = target_buffer;
2784 if ( notclipped(bktr, i, width)) {
2785 split(bktr, (volatile u_long **) &dma_prog,
2786 bktr->y2 - bktr->y, OP_WRITE,
2787 Bpp, (volatile u_char **) &target, cols);
2790 while(getline(bktr, i)) {
2791 if (bktr->y != bktr->y2 ) {
2792 split(bktr, (volatile u_long **) &dma_prog,
2793 bktr->y2 - bktr->y, OP_WRITE,
2794 Bpp, (volatile u_char **) &target, cols);
2796 if (bktr->yclip != bktr->yclip2 ) {
2797 split(bktr,(volatile u_long **) &dma_prog,
2798 bktr->yclip2 - bktr->yclip,
2800 Bpp, (volatile u_char **) &target, cols);
2806 target_buffer += interlace * pitch;
2812 /* Grab the Even field */
2813 /* Look for the VRO, end of Odd field, marker */
2814 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2815 *dma_prog++ = 0; /* NULL WORD */
2817 /* store the VBI data */
2818 /* look for sync with packed data */
2819 *dma_prog++ = OP_SYNC | BKTR_FM1;
2821 for(i = 0; i < vbilines; i++) {
2822 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2823 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2824 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2827 /* store the video image */
2828 if (i_flag == 1) /*Even Only*/
2829 target_buffer = buffer;
2830 if (i_flag == 3) /*interlaced*/
2831 target_buffer = buffer+pitch;
2834 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2835 /* look for sync with packed data */
2836 *dma_prog++ = OP_SYNC | BKTR_FM1;
2837 *dma_prog++ = 0; /* NULL WORD */
2839 for (i = 0; i < (rows/interlace); i++) {
2840 target = target_buffer;
2841 if ( notclipped(bktr, i, width)) {
2842 split(bktr, (volatile u_long **) &dma_prog,
2843 bktr->y2 - bktr->y, OP_WRITE,
2844 Bpp, (volatile u_char **) &target, cols);
2846 while(getline(bktr, i)) {
2847 if (bktr->y != bktr->y2 ) {
2848 split(bktr, (volatile u_long **) &dma_prog,
2849 bktr->y2 - bktr->y, OP_WRITE,
2850 Bpp, (volatile u_char **) &target,
2853 if (bktr->yclip != bktr->yclip2 ) {
2854 split(bktr, (volatile u_long **) &dma_prog,
2855 bktr->yclip2 - bktr->yclip, OP_SKIP,
2856 Bpp, (volatile u_char **) &target, cols);
2863 target_buffer += interlace * pitch;
2868 /* Look for end of 'Even Field' */
2869 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2870 *dma_prog++ = 0; /* NULL WORD */
2872 *dma_prog++ = OP_JUMP ;
2873 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2874 *dma_prog++ = 0; /* NULL WORD */
2882 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2885 volatile u_long target_buffer, buffer, target,width;
2886 volatile u_long pitch;
2887 volatile u_long *dma_prog;
2888 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2889 u_int Bpp = pf_int->public.Bpp;
2891 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2892 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2893 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2894 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2896 OUTB(bktr, BKTR_OFORM, 0x00);
2898 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2899 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2900 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2901 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2903 /* disable gamma correction removal */
2904 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2907 OUTB(bktr, BKTR_E_VTC, 0);
2908 OUTB(bktr, BKTR_O_VTC, 0);
2910 OUTB(bktr, BKTR_E_VTC, 1);
2911 OUTB(bktr, BKTR_O_VTC, 1);
2913 bktr->capcontrol = 3 << 2 | 3;
2915 dma_prog = (u_long *) bktr->dma_prog;
2917 /* Construct Write */
2919 if (bktr->video.addr) {
2920 target_buffer = (u_long) bktr->video.addr;
2921 pitch = bktr->video.width;
2924 target_buffer = (u_long) vtophys(bktr->bigbuf);
2928 buffer = target_buffer;
2930 /* contruct sync : for video packet format */
2931 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2933 /* sync, mode indicator packed data */
2934 *dma_prog++ = 0; /* NULL WORD */
2936 for (i = 0; i < (rows/interlace); i++) {
2937 target = target_buffer;
2938 if ( notclipped(bktr, i, width)) {
2939 split(bktr, (volatile u_long **) &dma_prog,
2940 bktr->y2 - bktr->y, OP_WRITE,
2941 Bpp, (volatile u_char **) &target, cols);
2944 while(getline(bktr, i)) {
2945 if (bktr->y != bktr->y2 ) {
2946 split(bktr, (volatile u_long **) &dma_prog,
2947 bktr->y2 - bktr->y, OP_WRITE,
2948 Bpp, (volatile u_char **) &target, cols);
2950 if (bktr->yclip != bktr->yclip2 ) {
2951 split(bktr,(volatile u_long **) &dma_prog,
2952 bktr->yclip2 - bktr->yclip,
2954 Bpp, (volatile u_char **) &target, cols);
2960 target_buffer += interlace * pitch;
2967 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2968 *dma_prog++ = 0; /* NULL WORD */
2970 *dma_prog++ = OP_JUMP;
2971 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2976 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2977 *dma_prog++ = 0; /* NULL WORD */
2979 *dma_prog++ = OP_JUMP;
2980 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2985 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2986 *dma_prog++ = 0; /* NULL WORD */
2987 *dma_prog++ = OP_JUMP; ;
2988 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
2992 if (interlace == 2) {
2994 target_buffer = buffer + pitch;
2996 dma_prog = (u_long *) bktr->odd_dma_prog;
2998 /* sync vre IRQ bit */
2999 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3000 *dma_prog++ = 0; /* NULL WORD */
3002 for (i = 0; i < (rows/interlace); i++) {
3003 target = target_buffer;
3004 if ( notclipped(bktr, i, width)) {
3005 split(bktr, (volatile u_long **) &dma_prog,
3006 bktr->y2 - bktr->y, OP_WRITE,
3007 Bpp, (volatile u_char **) &target, cols);
3009 while(getline(bktr, i)) {
3010 if (bktr->y != bktr->y2 ) {
3011 split(bktr, (volatile u_long **) &dma_prog,
3012 bktr->y2 - bktr->y, OP_WRITE,
3013 Bpp, (volatile u_char **) &target,
3016 if (bktr->yclip != bktr->yclip2 ) {
3017 split(bktr, (volatile u_long **) &dma_prog,
3018 bktr->yclip2 - bktr->yclip, OP_SKIP,
3019 Bpp, (volatile u_char **) &target, cols);
3026 target_buffer += interlace * pitch;
3031 /* sync vre IRQ bit */
3032 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3033 *dma_prog++ = 0; /* NULL WORD */
3034 *dma_prog++ = OP_JUMP ;
3035 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3036 *dma_prog++ = 0; /* NULL WORD */
3044 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3045 int cols, int rows, int interlace )
3048 volatile unsigned int inst;
3049 volatile unsigned int inst3;
3050 volatile u_long target_buffer, buffer;
3051 volatile u_long *dma_prog;
3052 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3055 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3057 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3058 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3060 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3061 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3063 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3064 bktr->capcontrol = 3 << 2 | 3;
3066 dma_prog = (u_long *) bktr->dma_prog;
3068 /* Construct Write */
3070 /* write , sol, eol */
3071 inst = OP_WRITE | OP_SOL | (cols);
3072 /* write , sol, eol */
3073 inst3 = OP_WRITE | OP_EOL | (cols);
3075 if (bktr->video.addr)
3076 target_buffer = (u_long) bktr->video.addr;
3078 target_buffer = (u_long) vtophys(bktr->bigbuf);
3080 buffer = target_buffer;
3082 /* contruct sync : for video packet format */
3083 /* sync, mode indicator packed data */
3084 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3085 *dma_prog++ = 0; /* NULL WORD */
3089 for (i = 0; i < (rows/interlace); i++) {
3091 *dma_prog++ = target_buffer;
3092 *dma_prog++ = inst3;
3093 *dma_prog++ = target_buffer + b;
3094 target_buffer += interlace*(cols * 2);
3100 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
3101 *dma_prog++ = 0; /* NULL WORD */
3103 *dma_prog++ = OP_JUMP;
3104 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3109 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
3110 *dma_prog++ = 0; /* NULL WORD */
3111 *dma_prog++ = OP_JUMP;
3112 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3117 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3118 *dma_prog++ = 0; /* NULL WORD */
3119 *dma_prog++ = OP_JUMP ;
3120 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3124 if (interlace == 2) {
3126 target_buffer = (u_long) buffer + cols*2;
3128 dma_prog = (u_long * ) bktr->odd_dma_prog;
3131 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1;
3132 *dma_prog++ = 0; /* NULL WORD */
3134 for (i = 0; i < (rows/interlace) ; i++) {
3136 *dma_prog++ = target_buffer;
3137 *dma_prog++ = inst3;
3138 *dma_prog++ = target_buffer + b;
3139 target_buffer += interlace * ( cols*2);
3143 /* sync vro IRQ bit */
3144 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3145 *dma_prog++ = 0; /* NULL WORD */
3146 *dma_prog++ = OP_JUMP ;
3147 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3149 *dma_prog++ = OP_JUMP;
3150 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3151 *dma_prog++ = 0; /* NULL WORD */
3159 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3160 int cols, int rows, int interlace ){
3163 volatile unsigned int inst;
3164 volatile u_long target_buffer, t1, buffer;
3165 volatile u_long *dma_prog;
3166 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3168 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3170 dma_prog = (u_long *) bktr->dma_prog;
3172 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3174 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3175 OUTB(bktr, BKTR_OFORM, 0x00);
3177 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3178 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3180 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3181 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3183 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3184 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3185 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ~0x40); /* set chroma comb */
3186 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ~0x40);
3188 /* disable gamma correction removal */
3189 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3191 /* Construct Write */
3192 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3193 if (bktr->video.addr)
3194 target_buffer = (u_long) bktr->video.addr;
3196 target_buffer = (u_long) vtophys(bktr->bigbuf);
3198 buffer = target_buffer;
3202 /* contruct sync : for video packet format */
3203 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3204 *dma_prog++ = 0; /* NULL WORD */
3206 for (i = 0; i < (rows/interlace ) ; i++) {
3208 *dma_prog++ = cols/2 | cols/2 << 16;
3209 *dma_prog++ = target_buffer;
3210 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3211 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3212 target_buffer += interlace*cols;
3217 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3218 *dma_prog++ = 0; /* NULL WORD */
3220 *dma_prog++ = OP_JUMP ;
3221 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3225 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3226 *dma_prog++ = 0; /* NULL WORD */
3228 *dma_prog++ = OP_JUMP;
3229 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3233 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3234 *dma_prog++ = 0; /* NULL WORD */
3236 *dma_prog++ = OP_JUMP ;
3237 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3241 if (interlace == 2) {
3243 dma_prog = (u_long * ) bktr->odd_dma_prog;
3245 target_buffer = (u_long) buffer + cols;
3246 t1 = buffer + cols/2;
3247 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3248 *dma_prog++ = 0; /* NULL WORD */
3250 for (i = 0; i < (rows/interlace ) ; i++) {
3252 *dma_prog++ = cols/2 | cols/2 << 16;
3253 *dma_prog++ = target_buffer;
3254 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3255 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3256 target_buffer += interlace*cols;
3260 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3261 *dma_prog++ = 0; /* NULL WORD */
3262 *dma_prog++ = OP_JUMP ;
3263 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3264 *dma_prog++ = 0; /* NULL WORD */
3272 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3273 int cols, int rows, int interlace ){
3276 volatile unsigned int inst;
3277 volatile unsigned int inst1;
3278 volatile u_long target_buffer, t1, buffer;
3279 volatile u_long *dma_prog;
3280 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3282 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3284 dma_prog = (u_long *) bktr->dma_prog;
3286 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3288 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3289 OUTB(bktr, BKTR_OFORM, 0x0);
3291 /* Construct Write */
3292 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3293 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3294 if (bktr->video.addr)
3295 target_buffer = (u_long) bktr->video.addr;
3297 target_buffer = (u_long) vtophys(bktr->bigbuf);
3299 buffer = target_buffer;
3302 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3303 *dma_prog++ = 0; /* NULL WORD */
3305 for (i = 0; i < (rows/interlace )/2 ; i++) {
3307 *dma_prog++ = cols/2 | (cols/2 << 16);
3308 *dma_prog++ = target_buffer;
3309 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3310 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3311 target_buffer += interlace*cols;
3312 *dma_prog++ = inst1;
3313 *dma_prog++ = cols/2 | (cols/2 << 16);
3314 *dma_prog++ = target_buffer;
3315 target_buffer += interlace*cols;
3321 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3322 *dma_prog++ = 0; /* NULL WORD */
3324 *dma_prog++ = OP_JUMP;
3325 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3329 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3330 *dma_prog++ = 0; /* NULL WORD */
3332 *dma_prog++ = OP_JUMP;
3333 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3337 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3338 *dma_prog++ = 0; /* NULL WORD */
3339 *dma_prog++ = OP_JUMP ;
3340 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3344 if (interlace == 2) {
3346 dma_prog = (u_long * ) bktr->odd_dma_prog;
3348 target_buffer = (u_long) buffer + cols;
3349 t1 = buffer + cols/2;
3350 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3351 *dma_prog++ = 0; /* NULL WORD */
3353 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3355 *dma_prog++ = cols/2 | (cols/2 << 16);
3356 *dma_prog++ = target_buffer;
3357 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3358 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3359 target_buffer += interlace*cols;
3360 *dma_prog++ = inst1;
3361 *dma_prog++ = cols/2 | (cols/2 << 16);
3362 *dma_prog++ = target_buffer;
3363 target_buffer += interlace*cols;
3370 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3371 *dma_prog++ = 0; /* NULL WORD */
3372 *dma_prog++ = OP_JUMP;
3373 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3374 *dma_prog++ = 0; /* NULL WORD */
3383 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3385 int rows, cols, interlace;
3388 struct format_params *fp;
3389 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3392 fp = &format_params[bktr->format_params];
3394 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3396 /* disable FIFO & RISC, leave other bits alone */
3397 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3399 /* set video parameters */
3400 if (bktr->capture_area_enabled)
3401 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3402 / fp->scaled_htotal / bktr->cols) - 4096;
3404 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3405 / fp->scaled_htotal / bktr->cols) - 4096;
3407 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3408 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3409 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3410 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3411 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3413 /* horizontal active */
3415 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3416 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3417 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3418 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3419 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3420 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3421 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3423 /* horizontal delay */
3424 if (bktr->capture_area_enabled)
3425 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3426 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3428 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3430 temp = temp & 0x3fe;
3432 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3433 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3434 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3435 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3436 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3437 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3438 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3440 /* vertical scale */
3442 if (bktr->capture_area_enabled) {
3443 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3444 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3446 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3449 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3452 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3453 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3455 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3458 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3463 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3464 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3465 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3466 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3467 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3468 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3469 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3472 /* vertical active */
3473 if (bktr->capture_area_enabled)
3474 temp = bktr->capture_area_y_size;
3477 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3478 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3479 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3480 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3481 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3482 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3483 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3485 /* vertical delay */
3486 if (bktr->capture_area_enabled)
3487 temp = fp->vdelay + (bktr->capture_area_y_offset);
3490 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3491 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3492 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3493 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3494 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3495 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3496 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3498 /* end of video params */
3500 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3501 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3502 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3504 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3507 /* capture control */
3510 bktr->bktr_cap_ctl =
3511 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3512 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3513 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3517 bktr->bktr_cap_ctl =
3518 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
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 |
3526 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3527 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3528 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3533 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3538 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3540 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3541 /* user, then use the rgb_vbi RISC program. */
3542 /* Otherwise, use the normal rgb RISC program */
3543 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3544 if ( (bktr->vbiflags & VBI_OPEN)
3545 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3546 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3548 bktr->bktr_cap_ctl |=
3549 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3550 bktr->vbiflags |= VBI_CAPTURE;
3551 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3554 rgb_prog(bktr, i_flag, cols, rows, interlace);
3559 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3560 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3561 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3562 | pixfmt_swap_flags( bktr->pixfmt ));
3566 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3567 yuvpack_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_12 ) {
3574 yuv12_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 ));
3583 /******************************************************************************
3584 * video & video capture specific routines:
3592 start_capture( bktr_ptr_t bktr, unsigned type )
3595 struct format_params *fp;
3597 fp = &format_params[bktr->format_params];
3599 /* If requested, clear out capture buf first */
3600 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3601 bzero((caddr_t)bktr->bigbuf,
3602 (size_t)bktr->rows * bktr->cols * bktr->frames *
3603 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3606 OUTB(bktr, BKTR_DSTATUS, 0);
3607 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3609 bktr->flags |= type;
3610 bktr->flags &= ~METEOR_WANT_MASK;
3611 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3612 case METEOR_ONLY_EVEN_FIELDS:
3613 bktr->flags |= METEOR_WANT_EVEN;
3616 case METEOR_ONLY_ODD_FIELDS:
3617 bktr->flags |= METEOR_WANT_ODD;
3621 bktr->flags |= METEOR_WANT_MASK;
3626 /* TDEC is only valid for continuous captures */
3627 if ( type == METEOR_SINGLE ) {
3628 u_short fps_save = bktr->fps;
3630 set_fps(bktr, fp->frame_rate);
3631 bktr->fps = fps_save;
3634 set_fps(bktr, bktr->fps);
3636 if (bktr->dma_prog_loaded == FALSE) {
3637 build_dma_prog(bktr, i_flag);
3638 bktr->dma_prog_loaded = TRUE;
3642 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3651 set_fps( bktr_ptr_t bktr, u_short fps )
3653 struct format_params *fp;
3656 fp = &format_params[bktr->format_params];
3658 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3659 case METEOR_ONLY_EVEN_FIELDS:
3660 bktr->flags |= METEOR_WANT_EVEN;
3663 case METEOR_ONLY_ODD_FIELDS:
3664 bktr->flags |= METEOR_WANT_ODD;
3668 bktr->flags |= METEOR_WANT_MASK;
3673 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3674 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3677 OUTB(bktr, BKTR_TDEC, 0);
3679 if (fps < fp->frame_rate)
3680 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3682 OUTB(bktr, BKTR_TDEC, 0);
3692 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3693 * achieve the specified swapping.
3694 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3695 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3697 * Note also that for 3Bpp, we may additionally need to do some creative
3698 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3699 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3700 * as one would expect.
3703 static u_int pixfmt_swap_flags( int pixfmt )
3705 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3708 switch ( pf->Bpp ) {
3709 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3712 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3715 case 4 : if ( pf->swap_bytes )
3716 swapf = pf->swap_shorts ? 0 : WSWAP;
3718 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3727 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3728 * our pixfmt_table indices.
3731 static int oformat_meteor_to_bt( u_long format )
3734 struct meteor_pixfmt *pf1, *pf2;
3736 /* Find format in compatibility table */
3737 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3738 if ( meteor_pixfmt_table[i].meteor_format == format )
3741 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3743 pf1 = &meteor_pixfmt_table[i].public;
3745 /* Match it with an entry in master pixel format table */
3746 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3747 pf2 = &pixfmt_table[i].public;
3749 if (( pf1->type == pf2->type ) &&
3750 ( pf1->Bpp == pf2->Bpp ) &&
3751 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3752 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3753 ( pf1->swap_shorts == pf2->swap_shorts ))
3756 if ( i >= PIXFMT_TABLE_SIZE )
3762 /******************************************************************************
3767 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3768 #define I2CBITTIME_878 (1 << 7)
3769 #define I2C_READ 0x01
3770 #define I2C_COMMAND (I2CBITTIME | \
3771 BT848_DATA_CTL_I2CSCL | \
3772 BT848_DATA_CTL_I2CSDA)
3774 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3775 BT848_DATA_CTL_I2CSCL | \
3776 BT848_DATA_CTL_I2CSDA)
3778 /* Select between old i2c code and new iicbus / smbus code */
3779 #if defined(BKTR_USE_FREEBSD_SMBUS)
3782 * The hardware interface is actually SMB commands
3785 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3789 if (bktr->id == BROOKTREE_848 ||
3790 bktr->id == BROOKTREE_848A ||
3791 bktr->id == BROOKTREE_849A)
3794 cmd = I2C_COMMAND_878;
3797 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3798 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3801 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3802 (char)(byte1 & 0xff)))
3811 i2cRead( bktr_ptr_t bktr, int addr )
3816 if (bktr->id == BROOKTREE_848 ||
3817 bktr->id == BROOKTREE_848A ||
3818 bktr->id == BROOKTREE_849A)
3821 cmd = I2C_COMMAND_878;
3823 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3826 return ((int)((unsigned char)result));
3829 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3831 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3832 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3833 /* Therefore we need low level control of the i2c bus hardware */
3835 /* Write to the MSP or DPL registers */
3837 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3839 unsigned char addr_l, addr_h, data_h, data_l ;
3841 addr_h = (addr >>8) & 0xff;
3842 addr_l = addr & 0xff;
3843 data_h = (data >>8) & 0xff;
3844 data_l = data & 0xff;
3846 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3848 iicbus_write_byte(IICBUS(bktr), dev, 0);
3849 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3850 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3851 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3852 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3854 iicbus_stop(IICBUS(bktr));
3859 /* Read from the MSP or DPL registers */
3861 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3864 unsigned char addr_l, addr_h, dev_r;
3866 u_char data_read[2];
3868 addr_h = (addr >>8) & 0xff;
3869 addr_l = addr & 0xff;
3872 /* XXX errors ignored */
3873 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3875 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3876 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3877 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3879 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3880 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3881 iicbus_stop(IICBUS(bktr));
3883 data = (data_read[0]<<8) | data_read[1];
3888 /* Reset the MSP or DPL chip */
3889 /* The user can block the reset (which is handy if you initialise the
3890 * MSP and/or DPL audio in another operating system first (eg in Windows)
3893 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3896 #ifndef BKTR_NO_MSP_RESET
3897 /* put into reset mode */
3898 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3899 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3900 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3901 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3902 iicbus_stop(IICBUS(bktr));
3904 /* put back to operational 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), 0x00, 0);
3908 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3909 iicbus_stop(IICBUS(bktr));
3914 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3917 /* XXX errors ignored */
3918 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3919 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3920 iicbus_stop(IICBUS(bktr));
3925 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3928 * Program the i2c bus directly
3931 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3936 /* clear status bits */
3937 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3939 /* build the command datum */
3940 if (bktr->id == BROOKTREE_848 ||
3941 bktr->id == BROOKTREE_848A ||
3942 bktr->id == BROOKTREE_849A) {
3943 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3945 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3947 if ( byte2 != -1 ) {
3948 data |= ((byte2 & 0xff) << 8);
3949 data |= BT848_DATA_CTL_I2CW3B;
3952 /* write the address and data */
3953 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3955 /* wait for completion */
3956 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3957 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3962 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3974 i2cRead( bktr_ptr_t bktr, int addr )
3978 /* clear status bits */
3979 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3981 /* write the READ address */
3982 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3984 if (bktr->id == BROOKTREE_848 ||
3985 bktr->id == BROOKTREE_848A ||
3986 bktr->id == BROOKTREE_849A) {
3987 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3989 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3992 /* wait for completion */
3993 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3994 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3999 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4003 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4006 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4007 /* bt848 automated i2c bus controller cannot handle */
4008 /* Therefore we need low level control of the i2c bus hardware */
4009 /* Idea for the following functions are from elsewhere in this driver and */
4010 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4013 static void i2c_start( bktr_ptr_t bktr) {
4014 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4015 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4016 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4017 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4020 static void i2c_stop( bktr_ptr_t bktr) {
4021 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4022 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4023 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4026 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4030 /* write out the byte */
4031 for ( x = 7; x >= 0; --x ) {
4032 if ( data & (1<<x) ) {
4033 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4034 DELAY( BITD ); /* assert HI data */
4035 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4036 DELAY( BITD ); /* strobe clock */
4037 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4038 DELAY( BITD ); /* release clock */
4041 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4042 DELAY( BITD ); /* assert LO data */
4043 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4044 DELAY( BITD ); /* strobe clock */
4045 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4046 DELAY( BITD ); /* release clock */
4050 /* look for an ACK */
4051 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4052 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4053 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4054 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4059 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4064 /* read in the byte */
4065 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4066 DELAY( BITD ); /* float data */
4067 for ( x = 7; x >= 0; --x ) {
4068 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4069 DELAY( BITD ); /* strobe clock */
4070 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4071 if ( bit ) byte |= (1<<x);
4072 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4073 DELAY( BITD ); /* release clock */
4075 /* After reading the byte, send an ACK */
4076 /* (unless that was the last byte, for which we send a NAK */
4077 if (last) { /* send NAK - same a writing a 1 */
4078 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4079 DELAY( BITD ); /* set data bit */
4080 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4081 DELAY( BITD ); /* strobe clock */
4082 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4083 DELAY( BITD ); /* release clock */
4084 } else { /* send ACK - same as writing a 0 */
4085 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4086 DELAY( BITD ); /* set data bit */
4087 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4088 DELAY( BITD ); /* strobe clock */
4089 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4090 DELAY( BITD ); /* release clock */
4098 /* Write to the MSP or DPL registers */
4099 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4101 unsigned int msp_w_addr = i2c_addr;
4102 unsigned char addr_l, addr_h, data_h, data_l ;
4103 addr_h = (addr >>8) & 0xff;
4104 addr_l = addr & 0xff;
4105 data_h = (data >>8) & 0xff;
4106 data_l = data & 0xff;
4109 i2c_write_byte(bktr, msp_w_addr);
4110 i2c_write_byte(bktr, dev);
4111 i2c_write_byte(bktr, addr_h);
4112 i2c_write_byte(bktr, addr_l);
4113 i2c_write_byte(bktr, data_h);
4114 i2c_write_byte(bktr, data_l);
4118 /* Read from the MSP or DPL registers */
4119 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4121 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4122 addr_h = (addr >>8) & 0xff;
4123 addr_l = addr & 0xff;
4127 i2c_write_byte(bktr,i2c_addr);
4128 i2c_write_byte(bktr,dev_r);
4129 i2c_write_byte(bktr,addr_h);
4130 i2c_write_byte(bktr,addr_l);
4133 i2c_write_byte(bktr,i2c_addr+1);
4134 i2c_read_byte(bktr,&data_1, 0);
4135 i2c_read_byte(bktr,&data_2, 1);
4137 data = (data_1<<8) | data_2;
4141 /* Reset the MSP or DPL chip */
4142 /* The user can block the reset (which is handy if you initialise the
4143 * MSP audio in another operating system first (eg in Windows)
4145 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4147 #ifndef BKTR_NO_MSP_RESET
4148 /* put into reset mode */
4150 i2c_write_byte(bktr, i2c_addr);
4151 i2c_write_byte(bktr, 0x00);
4152 i2c_write_byte(bktr, 0x80);
4153 i2c_write_byte(bktr, 0x00);
4156 /* put back to operational mode */
4158 i2c_write_byte(bktr, i2c_addr);
4159 i2c_write_byte(bktr, 0x00);
4160 i2c_write_byte(bktr, 0x00);
4161 i2c_write_byte(bktr, 0x00);
4168 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4170 /* XXX errors ignored */
4172 i2c_write_byte(bktr,bktr->remote_control_addr);
4173 i2c_read_byte(bktr,&(remote->data[0]), 0);
4174 i2c_read_byte(bktr,&(remote->data[1]), 0);
4175 i2c_read_byte(bktr,&(remote->data[2]), 0);
4181 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4184 #if defined( I2C_SOFTWARE_PROBE )
4187 * we are keeping this around for any parts that we need to probe
4188 * but that CANNOT be probed via an i2c read.
4189 * this is necessary because the hardware i2c mechanism
4190 * cannot be programmed for 1 byte writes.
4191 * currently there are no known i2c parts that we need to probe
4192 * and that cannot be safely read.
4194 static int i2cProbe( bktr_ptr_t bktr, int addr );
4199 * probe for an I2C device at addr.
4202 i2cProbe( bktr_ptr_t bktr, int addr )
4207 #if defined( EXTRA_START )
4208 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4209 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4210 #endif /* EXTRA_START */
4211 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4212 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4215 for ( x = 7; x >= 0; --x ) {
4216 if ( addr & (1<<x) ) {
4217 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4218 DELAY( BITD ); /* assert HI data */
4219 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4220 DELAY( BITD ); /* strobe clock */
4221 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4222 DELAY( BITD ); /* release clock */
4225 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4226 DELAY( BITD ); /* assert LO data */
4227 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4228 DELAY( BITD ); /* strobe clock */
4229 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4230 DELAY( BITD ); /* release clock */
4234 /* look for an ACK */
4235 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4236 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4237 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4238 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4241 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4242 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4243 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4250 #endif /* I2C_SOFTWARE_PROBE */
4255 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */