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.3 2003/06/23 17:55:30 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 thread *td)
1270 volatile u_char c_temp;
1272 unsigned int temp_iform;
1274 struct meteor_geomet *geo;
1275 struct meteor_counts *counts;
1276 struct meteor_video *video;
1277 struct bktr_capture_area *cap_area;
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 KKASSERT(td->td_proc != NULL);
1556 bktr->signal = *(int *) arg;
1557 bktr->proc = td->td_proc;
1561 *(int *)arg = bktr->signal;
1566 switch (*(int *) arg) {
1567 case METEOR_CAP_SINGLE:
1569 if (bktr->bigbuf==0) /* no frame buffer allocated */
1571 /* already capturing */
1572 if (temp & METEOR_CAP_MASK)
1577 start_capture(bktr, METEOR_SINGLE);
1579 /* wait for capture to complete */
1580 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1581 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1582 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1584 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1589 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1590 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1591 if (error && (error != ERESTART)) {
1592 /* Here if we didn't get complete frame */
1594 printf( "%s: ioctl: tsleep error %d %x\n",
1595 bktr_name(bktr), error,
1596 INL(bktr, BKTR_RISC_COUNT));
1600 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1602 /* disable risc, leave fifo running */
1603 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1606 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1607 /* FIXME: should we set bt848->int_stat ??? */
1610 case METEOR_CAP_CONTINOUS:
1611 if (bktr->bigbuf==0) /* no frame buffer allocated */
1613 /* already capturing */
1614 if (temp & METEOR_CAP_MASK)
1618 start_capture(bktr, METEOR_CONTIN);
1620 /* Clear the interrypt status register */
1621 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1623 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1624 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1625 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1627 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1632 dump_bt848( bt848 );
1636 case METEOR_CAP_STOP_CONT:
1637 if (bktr->flags & METEOR_CONTIN) {
1638 /* turn off capture */
1639 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1640 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1641 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1643 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1650 /* can't change parameters while capturing */
1651 if (bktr->flags & METEOR_CAP_MASK)
1655 geo = (struct meteor_geomet *) arg;
1658 /* Either even or odd, if even & odd, then these a zero */
1659 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1660 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1661 printf( "%s: ioctl: Geometry odd or even only.\n",
1666 /* set/clear even/odd flags */
1667 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1668 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1670 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1671 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1672 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1674 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1676 if (geo->columns <= 0) {
1678 "%s: ioctl: %d: columns must be greater than zero.\n",
1679 bktr_name(bktr), geo->columns);
1682 else if ((geo->columns & 0x3fe) != geo->columns) {
1684 "%s: ioctl: %d: columns too large or not even.\n",
1685 bktr_name(bktr), geo->columns);
1689 if (geo->rows <= 0) {
1691 "%s: ioctl: %d: rows must be greater than zero.\n",
1692 bktr_name(bktr), geo->rows);
1695 else if (((geo->rows & 0x7fe) != geo->rows) ||
1696 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1697 ((geo->rows & 0x3fe) != geo->rows)) ) {
1699 "%s: ioctl: %d: rows too large or not even.\n",
1700 bktr_name(bktr), geo->rows);
1704 if (geo->frames > 32) {
1705 printf("%s: ioctl: too many frames.\n",
1714 bktr->dma_prog_loaded = FALSE;
1715 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1717 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1719 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1720 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1722 /* meteor_mem structure for SYNC Capture */
1723 if (geo->frames > 1) temp += PAGE_SIZE;
1726 if ((int) temp > bktr->alloc_pages
1727 && bktr->video.addr == 0) {
1729 /*****************************/
1730 /* *** OS Dependant code *** */
1731 /*****************************/
1732 #if defined(__NetBSD__) || defined(__OpenBSD__)
1733 bus_dmamap_t dmamap;
1735 buf = get_bktr_mem(bktr, &dmamap,
1738 free_bktr_mem(bktr, bktr->dm_mem,
1740 bktr->dm_mem = dmamap;
1743 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1745 kmem_free(kernel_map, bktr->bigbuf,
1746 (bktr->alloc_pages * PAGE_SIZE));
1750 bktr->alloc_pages = temp;
1753 "%s: ioctl: Allocating %d bytes\n",
1754 bktr_name(bktr), temp*PAGE_SIZE);
1764 bktr->rows = geo->rows;
1765 bktr->cols = geo->columns;
1766 bktr->frames = geo->frames;
1768 /* Pixel format (if in meteor pixfmt compatibility mode) */
1769 if ( bktr->pixfmt_compat ) {
1770 bktr->format = METEOR_GEO_YUV_422;
1771 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1772 case 0: /* default */
1773 case METEOR_GEO_RGB16:
1774 bktr->format = METEOR_GEO_RGB16;
1776 case METEOR_GEO_RGB24:
1777 bktr->format = METEOR_GEO_RGB24;
1779 case METEOR_GEO_YUV_422:
1780 bktr->format = METEOR_GEO_YUV_422;
1781 if (geo->oformat & METEOR_GEO_YUV_12)
1782 bktr->format = METEOR_GEO_YUV_12;
1784 case METEOR_GEO_YUV_PACKED:
1785 bktr->format = METEOR_GEO_YUV_PACKED;
1788 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1791 if (bktr->flags & METEOR_CAP_MASK) {
1793 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1794 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1795 case METEOR_ONLY_ODD_FIELDS:
1796 bktr->flags |= METEOR_WANT_ODD;
1798 case METEOR_ONLY_EVEN_FIELDS:
1799 bktr->flags |= METEOR_WANT_EVEN;
1802 bktr->flags |= METEOR_WANT_MASK;
1806 start_capture(bktr, METEOR_CONTIN);
1807 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1808 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1809 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1810 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1816 /* end of METEORSETGEO */
1818 /* FIXME. The Capture Area currently has the following restrictions:
1820 y_offset may need to be even in interlaced modes
1821 RGB24 - Interlaced mode
1822 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1823 y_size must be greater than or equal to METEORSETGEO height (rows)
1824 RGB24 - Even Only (or Odd Only) mode
1825 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1826 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1827 YUV12 - Interlaced mode
1828 x_size must be greater than or equal to METEORSETGEO width (cols)
1829 y_size must be greater than or equal to METEORSETGEO height (rows)
1830 YUV12 - Even Only (or Odd Only) mode
1831 x_size must be greater than or equal to METEORSETGEO width (cols)
1832 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1835 case BT848_SCAPAREA: /* set capture area of each video frame */
1836 /* can't change parameters while capturing */
1837 if (bktr->flags & METEOR_CAP_MASK)
1840 cap_area = (struct bktr_capture_area *) arg;
1841 bktr->capture_area_x_offset = cap_area->x_offset;
1842 bktr->capture_area_y_offset = cap_area->y_offset;
1843 bktr->capture_area_x_size = cap_area->x_size;
1844 bktr->capture_area_y_size = cap_area->y_size;
1845 bktr->capture_area_enabled = TRUE;
1847 bktr->dma_prog_loaded = FALSE;
1850 case BT848_GCAPAREA: /* get capture area of each video frame */
1851 cap_area = (struct bktr_capture_area *) arg;
1852 if (bktr->capture_area_enabled == FALSE) {
1853 cap_area->x_offset = 0;
1854 cap_area->y_offset = 0;
1855 cap_area->x_size = format_params[
1856 bktr->format_params].scaled_hactive;
1857 cap_area->y_size = format_params[
1858 bktr->format_params].vactive;
1860 cap_area->x_offset = bktr->capture_area_x_offset;
1861 cap_area->y_offset = bktr->capture_area_y_offset;
1862 cap_area->x_size = bktr->capture_area_x_size;
1863 cap_area->y_size = bktr->capture_area_y_size;
1868 return common_ioctl( bktr, cmd, arg );
1878 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread *td)
1881 unsigned int temp, temp1;
1894 /* Read the last key pressed by the Remote Control */
1895 if (bktr->remote_control == 0) return (EINVAL);
1896 remote_read(bktr, (struct bktr_remote *)arg);
1899 #if defined( TUNER_AFC )
1900 case TVTUNER_SETAFC:
1901 bktr->tuner.afc = (*(int *)arg != 0);
1904 case TVTUNER_GETAFC:
1905 *(int *)arg = bktr->tuner.afc;
1906 /* XXX Perhaps use another bit to indicate AFC success? */
1908 #endif /* TUNER_AFC */
1910 case TVTUNER_SETCHNL:
1911 temp_mute( bktr, TRUE );
1912 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1914 temp_mute( bktr, FALSE );
1917 *(unsigned long *)arg = temp;
1919 /* after every channel change, we must restart the MSP34xx */
1920 /* audio chip to reselect NICAM STEREO or MONO audio */
1921 if ( bktr->card.msp3400c )
1922 msp_autodetect( bktr );
1924 /* after every channel change, we must restart the DPL35xx */
1925 if ( bktr->card.dpl3518a )
1926 dpl_autodetect( bktr );
1928 temp_mute( bktr, FALSE );
1931 case TVTUNER_GETCHNL:
1932 *(unsigned long *)arg = bktr->tuner.channel;
1935 case TVTUNER_SETTYPE:
1936 temp = *(unsigned long *)arg;
1937 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1939 bktr->tuner.chnlset = temp;
1942 case TVTUNER_GETTYPE:
1943 *(unsigned long *)arg = bktr->tuner.chnlset;
1946 case TVTUNER_GETSTATUS:
1947 temp = get_tuner_status( bktr );
1948 *(unsigned long *)arg = temp & 0xff;
1951 case TVTUNER_SETFREQ:
1952 temp_mute( bktr, TRUE );
1953 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1954 temp_mute( bktr, FALSE );
1956 temp_mute( bktr, FALSE );
1959 *(unsigned long *)arg = temp;
1961 /* after every channel change, we must restart the MSP34xx */
1962 /* audio chip to reselect NICAM STEREO or MONO audio */
1963 if ( bktr->card.msp3400c )
1964 msp_autodetect( bktr );
1966 /* after every channel change, we must restart the DPL35xx */
1967 if ( bktr->card.dpl3518a )
1968 dpl_autodetect( bktr );
1970 temp_mute( bktr, FALSE );
1973 case TVTUNER_GETFREQ:
1974 *(unsigned long *)arg = bktr->tuner.frequency;
1977 case TVTUNER_GETCHNLSET:
1978 return tuner_getchnlset((struct bktr_chnlset *)arg);
1980 case BT848_SAUDIO: /* set audio channel */
1981 if ( set_audio( bktr, *(int*)arg ) < 0 )
1985 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1986 case BT848_SHUE: /* set hue */
1987 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1990 case BT848_GHUE: /* get hue */
1991 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1994 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1995 case BT848_SBRIG: /* set brightness */
1996 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1999 case BT848_GBRIG: /* get brightness */
2000 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2004 case BT848_SCSAT: /* set chroma saturation */
2005 tmp_int = *(int*)arg;
2007 temp = INB(bktr, BKTR_E_CONTROL);
2008 temp1 = INB(bktr, BKTR_O_CONTROL);
2009 if ( tmp_int & BIT_EIGHT_HIGH ) {
2010 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2011 BT848_E_CONTROL_SAT_V_MSB);
2012 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2013 BT848_O_CONTROL_SAT_V_MSB);
2016 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2017 BT848_E_CONTROL_SAT_V_MSB);
2018 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2019 BT848_O_CONTROL_SAT_V_MSB);
2022 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2023 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2024 OUTB(bktr, BKTR_E_CONTROL, temp);
2025 OUTB(bktr, BKTR_O_CONTROL, temp1);
2028 case BT848_GCSAT: /* get chroma saturation */
2029 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2030 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2031 tmp_int |= BIT_EIGHT_HIGH;
2032 *(int*)arg = tmp_int;
2036 case BT848_SVSAT: /* set chroma V saturation */
2037 tmp_int = *(int*)arg;
2039 temp = INB(bktr, BKTR_E_CONTROL);
2040 temp1 = INB(bktr, BKTR_O_CONTROL);
2041 if ( tmp_int & BIT_EIGHT_HIGH) {
2042 temp |= BT848_E_CONTROL_SAT_V_MSB;
2043 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2046 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2047 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2050 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2051 OUTB(bktr, BKTR_E_CONTROL, temp);
2052 OUTB(bktr, BKTR_O_CONTROL, temp1);
2055 case BT848_GVSAT: /* get chroma V saturation */
2056 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2057 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2058 tmp_int |= BIT_EIGHT_HIGH;
2059 *(int*)arg = tmp_int;
2063 case BT848_SUSAT: /* set chroma U saturation */
2064 tmp_int = *(int*)arg;
2066 temp = INB(bktr, BKTR_E_CONTROL);
2067 temp1 = INB(bktr, BKTR_O_CONTROL);
2068 if ( tmp_int & BIT_EIGHT_HIGH ) {
2069 temp |= BT848_E_CONTROL_SAT_U_MSB;
2070 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2073 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2074 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2077 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2078 OUTB(bktr, BKTR_E_CONTROL, temp);
2079 OUTB(bktr, BKTR_O_CONTROL, temp1);
2082 case BT848_GUSAT: /* get chroma U saturation */
2083 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2084 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2085 tmp_int |= BIT_EIGHT_HIGH;
2086 *(int*)arg = tmp_int;
2089 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2091 case BT848_SLNOTCH: /* set luma notch */
2092 tmp_int = (*(int *)arg & 0x7) << 5 ;
2093 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2094 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2095 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2096 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2099 case BT848_GLNOTCH: /* get luma notch */
2100 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2105 case BT848_SCONT: /* set contrast */
2106 tmp_int = *(int*)arg;
2108 temp = INB(bktr, BKTR_E_CONTROL);
2109 temp1 = INB(bktr, BKTR_O_CONTROL);
2110 if ( tmp_int & BIT_EIGHT_HIGH ) {
2111 temp |= BT848_E_CONTROL_CON_MSB;
2112 temp1 |= BT848_O_CONTROL_CON_MSB;
2115 temp &= ~BT848_E_CONTROL_CON_MSB;
2116 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2119 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2120 OUTB(bktr, BKTR_E_CONTROL, temp);
2121 OUTB(bktr, BKTR_O_CONTROL, temp1);
2124 case BT848_GCONT: /* get contrast */
2125 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2126 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2127 tmp_int |= BIT_EIGHT_HIGH;
2128 *(int*)arg = tmp_int;
2131 /* FIXME: SCBARS and CCBARS require a valid int * */
2132 /* argument to succeed, but its not used; consider */
2133 /* using the arg to store the on/off state so */
2134 /* there's only one ioctl() needed to turn cbars on/off */
2135 case BT848_SCBARS: /* set colorbar output */
2136 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2139 case BT848_CCBARS: /* clear colorbar output */
2140 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2143 case BT848_GAUDIO: /* get audio channel */
2144 temp = bktr->audio_mux_select;
2145 if ( bktr->audio_mute_state == TRUE )
2150 case BT848_SBTSC: /* set audio channel */
2151 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2155 case BT848_WEEPROM: /* write eeprom */
2156 offset = (((struct eeProm *)arg)->offset);
2157 count = (((struct eeProm *)arg)->count);
2158 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2159 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2163 case BT848_REEPROM: /* read eeprom */
2164 offset = (((struct eeProm *)arg)->offset);
2165 count = (((struct eeProm *)arg)->count);
2166 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2167 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2171 case BT848_SIGNATURE:
2172 offset = (((struct eeProm *)arg)->offset);
2173 count = (((struct eeProm *)arg)->count);
2174 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2175 if ( signCard( bktr, offset, count, buf ) < 0 )
2179 /* Ioctl's for direct gpio access */
2180 #ifdef BKTR_GPIO_ACCESS
2181 case BT848_GPIO_GET_EN:
2182 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2185 case BT848_GPIO_SET_EN:
2186 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2189 case BT848_GPIO_GET_DATA:
2190 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2193 case BT848_GPIO_SET_DATA:
2194 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2196 #endif /* BKTR_GPIO_ACCESS */
2198 /* Ioctl's for running the tuner device in radio mode */
2201 *(unsigned char *)arg = bktr->tuner.radio_mode;
2205 bktr->tuner.radio_mode = *(unsigned char *)arg;
2209 *(unsigned long *)arg = bktr->tuner.frequency;
2213 /* The argument to this ioctl is NOT freq*16. It is
2217 temp=(int)*(unsigned long *)arg;
2219 #ifdef BKTR_RADIO_DEBUG
2220 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2221 (int)*(unsigned long *)arg, temp);
2224 #ifndef BKTR_RADIO_NOFREQCHECK
2225 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2227 if(temp<8750 || temp>10800) {
2228 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2232 temp_mute( bktr, TRUE );
2233 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2234 temp_mute( bktr, FALSE );
2235 #ifdef BKTR_RADIO_DEBUG
2237 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2241 *(unsigned long *)arg = temp;
2244 /* Luigi's I2CWR ioctl */
2246 par = *(u_long *)arg;
2247 write = (par >> 24) & 0xff ;
2248 i2c_addr = (par >> 16) & 0xff ;
2249 i2c_port = (par >> 8) & 0xff ;
2250 data = (par) & 0xff ;
2253 i2cWrite( bktr, i2c_addr, i2c_port, data);
2255 data = i2cRead( bktr, i2c_addr);
2257 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2261 #ifdef BT848_MSP_READ
2262 /* I2C ioctls to allow userland access to the MSP chip */
2263 case BT848_MSP_READ:
2265 struct bktr_msp_control *msp;
2266 msp = (struct bktr_msp_control *) arg;
2267 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2268 msp->function, msp->address);
2272 case BT848_MSP_WRITE:
2274 struct bktr_msp_control *msp;
2275 msp = (struct bktr_msp_control *) arg;
2276 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2277 msp->address, msp->data );
2281 case BT848_MSP_RESET:
2282 msp_dpl_reset(bktr, bktr->msp_addr);
2287 return common_ioctl( bktr, cmd, arg );
2298 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2302 struct meteor_pixfmt *pf_pub;
2306 case METEORSINPUT: /* set input device */
2307 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2308 /* On the original bt848 boards, */
2309 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2310 /* On the Hauppauge bt878 boards, */
2311 /* Tuner is MUX0, RCA is MUX3 */
2312 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2313 /* stick with this system in our Meteor Emulation */
2315 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2317 /* this is the RCA video input */
2318 case 0: /* default */
2319 case METEOR_INPUT_DEV0:
2320 /* METEOR_INPUT_DEV_RCA: */
2321 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2323 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2324 & ~BT848_IFORM_MUXSEL);
2326 /* work around for new Hauppauge 878 cards */
2327 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2328 (bktr->id==BROOKTREE_878 ||
2329 bktr->id==BROOKTREE_879) )
2330 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2332 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2334 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2335 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2336 set_audio( bktr, AUDIO_EXTERN );
2339 /* this is the tuner input */
2340 case METEOR_INPUT_DEV1:
2341 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2343 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2344 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2345 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2346 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2347 set_audio( bktr, AUDIO_TUNER );
2350 /* this is the S-VHS input, but with a composite camera */
2351 case METEOR_INPUT_DEV2:
2352 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2354 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2355 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2356 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2357 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2358 set_audio( bktr, AUDIO_EXTERN );
2361 /* this is the S-VHS input */
2362 case METEOR_INPUT_DEV_SVIDEO:
2363 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2364 | METEOR_DEV_SVIDEO;
2365 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2366 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2367 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2368 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2369 set_audio( bktr, AUDIO_EXTERN );
2372 case METEOR_INPUT_DEV3:
2373 if ((bktr->id == BROOKTREE_848A) ||
2374 (bktr->id == BROOKTREE_849A) ||
2375 (bktr->id == BROOKTREE_878) ||
2376 (bktr->id == BROOKTREE_879) ) {
2377 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2379 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2381 /* work around for new Hauppauge 878 cards */
2382 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2383 (bktr->id==BROOKTREE_878 ||
2384 bktr->id==BROOKTREE_879) )
2385 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2387 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2389 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2390 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2391 set_audio( bktr, AUDIO_EXTERN );
2401 case METEORGINPUT: /* get input device */
2402 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2405 case METEORSACTPIXFMT:
2406 if (( *(int *)arg < 0 ) ||
2407 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2410 bktr->pixfmt = *(int *)arg;
2411 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2412 | pixfmt_swap_flags( bktr->pixfmt ));
2413 bktr->pixfmt_compat = FALSE;
2416 case METEORGACTPIXFMT:
2417 *(int *)arg = bktr->pixfmt;
2420 case METEORGSUPPIXFMT :
2421 pf_pub = (struct meteor_pixfmt *)arg;
2422 pixfmt = pf_pub->index;
2424 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2427 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2428 sizeof( *pf_pub ) );
2430 /* Patch in our format index */
2431 pf_pub->index = pixfmt;
2434 #if defined( STATUS_SUM )
2435 case BT848_GSTATUS: /* reap status */
2437 DECLARE_INTR_MASK(s);
2442 *(u_int*)arg = temp;
2445 #endif /* STATUS_SUM */
2457 /******************************************************************************
2458 * bt848 RISC programming routines:
2467 dump_bt848( bktr_ptr_t bktr )
2470 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2471 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2472 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2473 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2474 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2479 for (i = 0; i < 40; i+=4) {
2480 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2482 r[i], INL(bktr, r[i]),
2483 r[i+1], INL(bktr, r[i+1]),
2484 r[i+2], INL(bktr, r[i+2]),
2485 r[i+3], INL(bktr, r[i+3]]));
2488 printf("%s: INT STAT %x \n", bktr_name(bktr),
2489 INL(bktr, BKTR_INT_STAT));
2490 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2491 INL(bktr, BKTR_INT_MASK));
2492 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2493 INW(bktr, BKTR_GPIO_DMA_CTL));
2501 * build write instruction
2503 #define BKTR_FM1 0x6 /* packed data to follow */
2504 #define BKTR_FM3 0xe /* planar data to follow */
2505 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2506 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2507 #define BKTR_PXV 0x0 /* valid word (never used) */
2508 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2509 #define BKTR_SOL 0x2 /* first dword */
2511 #define OP_WRITE (0x1 << 28)
2512 #define OP_SKIP (0x2 << 28)
2513 #define OP_WRITEC (0x5 << 28)
2514 #define OP_JUMP (0x7 << 28)
2515 #define OP_SYNC (0x8 << 28)
2516 #define OP_WRITE123 (0x9 << 28)
2517 #define OP_WRITES123 (0xb << 28)
2518 #define OP_SOL (1 << 27) /* first instr for scanline */
2519 #define OP_EOL (1 << 26)
2521 #define BKTR_RESYNC (1 << 15)
2522 #define BKTR_GEN_IRQ (1 << 24)
2525 * The RISC status bits can be set/cleared in the RISC programs
2526 * and tested in the Interrupt Handler
2528 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2529 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2530 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2531 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2533 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2534 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2535 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2536 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2538 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2539 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2540 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2541 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2543 bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2545 bktr_clip_t * clip_node;
2546 bktr->clip_start = -1;
2550 bktr->line_length = width;
2553 bktr->current_col = 0;
2555 if (bktr->max_clip_node == 0 ) return TRUE;
2556 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2559 for (i = 0; i < bktr->max_clip_node; i++ ) {
2560 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2561 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2562 bktr->clip_start = i;
2570 bool_t getline(bktr_reg_t *bktr, int x ) {
2572 bktr_clip_t * clip_node ;
2574 if (bktr->line_length == 0 ||
2575 bktr->current_col >= bktr->line_length) return FALSE;
2577 bktr->y = min(bktr->last_y, bktr->line_length);
2578 bktr->y2 = bktr->line_length;
2580 bktr->yclip = bktr->yclip2 = -1;
2581 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2582 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2583 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2584 if (bktr->last_y <= clip_node->y_min) {
2585 bktr->y = min(bktr->last_y, bktr->line_length);
2586 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2587 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2588 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2589 bktr->last_y = bktr->yclip2;
2590 bktr->clip_start = i;
2592 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2593 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2594 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2595 if (bktr->last_y >= clip_node->y_min) {
2596 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2597 bktr->last_y = bktr->yclip2;
2598 bktr->clip_start = j;
2607 if (bktr->current_col <= bktr->line_length) {
2608 bktr->current_col = bktr->line_length;
2614 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2615 u_long operation, int pixel_width,
2616 volatile u_char ** target_buffer, int cols ) {
2619 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2620 u_int skip, start_skip;
2622 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2623 /* to the 1st byte in the mem dword containing our start addr. */
2624 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2627 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2628 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2629 case 2 : start_skip = 4 ; break;
2630 case 1 : start_skip = 8 ; break;
2633 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2634 if ( width == cols) {
2635 flag = OP_SOL | OP_EOL;
2636 } else if (bktr->current_col == 0 ) {
2638 } else if (bktr->current_col == cols) {
2643 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2644 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2649 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2650 if (operation != OP_SKIP )
2651 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2653 *target_buffer += width * pixel_width;
2654 bktr->current_col += width;
2658 if (bktr->current_col == 0 && width == cols) {
2661 } else if (bktr->current_col == 0 ) {
2664 } else if (bktr->current_col >= cols) {
2673 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2674 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2679 *(*dma_prog)++ = operation | flag |
2680 (width * pixel_width / 2 - skip);
2681 if (operation != OP_SKIP )
2682 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2683 *target_buffer += (width * pixel_width / 2) ;
2685 if ( operation == OP_WRITE )
2686 operation = OP_WRITEC;
2687 *(*dma_prog)++ = operation | flag2 |
2688 (width * pixel_width / 2);
2689 *target_buffer += (width * pixel_width / 2) ;
2690 bktr->current_col += width;
2698 * Generate the RISC instructions to capture both VBI and video images
2701 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2704 volatile u_long target_buffer, buffer, target,width;
2705 volatile u_long pitch;
2706 volatile u_long *dma_prog; /* DMA prog is an array of
2707 32 bit RISC instructions */
2708 volatile u_long *loop_point;
2709 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2710 u_int Bpp = pf_int->public.Bpp;
2711 unsigned int vbisamples; /* VBI samples per line */
2712 unsigned int vbilines; /* VBI lines per field */
2713 unsigned int num_dwords; /* DWORDS per line */
2715 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2716 vbilines = format_params[bktr->format_params].vbi_num_lines;
2717 num_dwords = vbisamples/4;
2719 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2720 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2721 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2722 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2725 OUTB(bktr, BKTR_OFORM, 0x00);
2727 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2728 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2729 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2730 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2732 /* disable gamma correction removal */
2733 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2736 OUTB(bktr, BKTR_E_VTC, 0);
2737 OUTB(bktr, BKTR_O_VTC, 0);
2739 OUTB(bktr, BKTR_E_VTC, 1);
2740 OUTB(bktr, BKTR_O_VTC, 1);
2742 bktr->capcontrol = 3 << 2 | 3;
2744 dma_prog = (u_long *) bktr->dma_prog;
2746 /* Construct Write */
2748 if (bktr->video.addr) {
2749 target_buffer = (u_long) bktr->video.addr;
2750 pitch = bktr->video.width;
2753 target_buffer = (u_long) vtophys(bktr->bigbuf);
2757 buffer = target_buffer;
2759 /* Wait for the VRE sync marking the end of the Even and
2760 * the start of the Odd field. Resync here.
2762 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2765 loop_point = dma_prog;
2767 /* store the VBI data */
2768 /* look for sync with packed data */
2769 *dma_prog++ = OP_SYNC | BKTR_FM1;
2771 for(i = 0; i < vbilines; i++) {
2772 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2773 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2774 (i * VBI_LINE_SIZE));
2777 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2778 /* store the Odd field video image */
2779 /* look for sync with packed data */
2780 *dma_prog++ = OP_SYNC | BKTR_FM1;
2781 *dma_prog++ = 0; /* NULL WORD */
2783 for (i = 0; i < (rows/interlace); i++) {
2784 target = target_buffer;
2785 if ( notclipped(bktr, i, width)) {
2786 split(bktr, (volatile u_long **) &dma_prog,
2787 bktr->y2 - bktr->y, OP_WRITE,
2788 Bpp, (volatile u_char **) &target, cols);
2791 while(getline(bktr, i)) {
2792 if (bktr->y != bktr->y2 ) {
2793 split(bktr, (volatile u_long **) &dma_prog,
2794 bktr->y2 - bktr->y, OP_WRITE,
2795 Bpp, (volatile u_char **) &target, cols);
2797 if (bktr->yclip != bktr->yclip2 ) {
2798 split(bktr,(volatile u_long **) &dma_prog,
2799 bktr->yclip2 - bktr->yclip,
2801 Bpp, (volatile u_char **) &target, cols);
2807 target_buffer += interlace * pitch;
2813 /* Grab the Even field */
2814 /* Look for the VRO, end of Odd field, marker */
2815 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2816 *dma_prog++ = 0; /* NULL WORD */
2818 /* store the VBI data */
2819 /* look for sync with packed data */
2820 *dma_prog++ = OP_SYNC | BKTR_FM1;
2822 for(i = 0; i < vbilines; i++) {
2823 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2824 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2825 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2828 /* store the video image */
2829 if (i_flag == 1) /*Even Only*/
2830 target_buffer = buffer;
2831 if (i_flag == 3) /*interlaced*/
2832 target_buffer = buffer+pitch;
2835 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2836 /* look for sync with packed data */
2837 *dma_prog++ = OP_SYNC | BKTR_FM1;
2838 *dma_prog++ = 0; /* NULL WORD */
2840 for (i = 0; i < (rows/interlace); i++) {
2841 target = target_buffer;
2842 if ( notclipped(bktr, i, width)) {
2843 split(bktr, (volatile u_long **) &dma_prog,
2844 bktr->y2 - bktr->y, OP_WRITE,
2845 Bpp, (volatile u_char **) &target, cols);
2847 while(getline(bktr, i)) {
2848 if (bktr->y != bktr->y2 ) {
2849 split(bktr, (volatile u_long **) &dma_prog,
2850 bktr->y2 - bktr->y, OP_WRITE,
2851 Bpp, (volatile u_char **) &target,
2854 if (bktr->yclip != bktr->yclip2 ) {
2855 split(bktr, (volatile u_long **) &dma_prog,
2856 bktr->yclip2 - bktr->yclip, OP_SKIP,
2857 Bpp, (volatile u_char **) &target, cols);
2864 target_buffer += interlace * pitch;
2869 /* Look for end of 'Even Field' */
2870 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2871 *dma_prog++ = 0; /* NULL WORD */
2873 *dma_prog++ = OP_JUMP ;
2874 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2875 *dma_prog++ = 0; /* NULL WORD */
2883 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2886 volatile u_long target_buffer, buffer, target,width;
2887 volatile u_long pitch;
2888 volatile u_long *dma_prog;
2889 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2890 u_int Bpp = pf_int->public.Bpp;
2892 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2893 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2894 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2895 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2897 OUTB(bktr, BKTR_OFORM, 0x00);
2899 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2900 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2901 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2902 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2904 /* disable gamma correction removal */
2905 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2908 OUTB(bktr, BKTR_E_VTC, 0);
2909 OUTB(bktr, BKTR_O_VTC, 0);
2911 OUTB(bktr, BKTR_E_VTC, 1);
2912 OUTB(bktr, BKTR_O_VTC, 1);
2914 bktr->capcontrol = 3 << 2 | 3;
2916 dma_prog = (u_long *) bktr->dma_prog;
2918 /* Construct Write */
2920 if (bktr->video.addr) {
2921 target_buffer = (u_long) bktr->video.addr;
2922 pitch = bktr->video.width;
2925 target_buffer = (u_long) vtophys(bktr->bigbuf);
2929 buffer = target_buffer;
2931 /* contruct sync : for video packet format */
2932 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2934 /* sync, mode indicator packed data */
2935 *dma_prog++ = 0; /* NULL WORD */
2937 for (i = 0; i < (rows/interlace); i++) {
2938 target = target_buffer;
2939 if ( notclipped(bktr, i, width)) {
2940 split(bktr, (volatile u_long **) &dma_prog,
2941 bktr->y2 - bktr->y, OP_WRITE,
2942 Bpp, (volatile u_char **) &target, cols);
2945 while(getline(bktr, i)) {
2946 if (bktr->y != bktr->y2 ) {
2947 split(bktr, (volatile u_long **) &dma_prog,
2948 bktr->y2 - bktr->y, OP_WRITE,
2949 Bpp, (volatile u_char **) &target, cols);
2951 if (bktr->yclip != bktr->yclip2 ) {
2952 split(bktr,(volatile u_long **) &dma_prog,
2953 bktr->yclip2 - bktr->yclip,
2955 Bpp, (volatile u_char **) &target, cols);
2961 target_buffer += interlace * pitch;
2968 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2969 *dma_prog++ = 0; /* NULL WORD */
2971 *dma_prog++ = OP_JUMP;
2972 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2977 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2978 *dma_prog++ = 0; /* NULL WORD */
2980 *dma_prog++ = OP_JUMP;
2981 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2986 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2987 *dma_prog++ = 0; /* NULL WORD */
2988 *dma_prog++ = OP_JUMP; ;
2989 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
2993 if (interlace == 2) {
2995 target_buffer = buffer + pitch;
2997 dma_prog = (u_long *) bktr->odd_dma_prog;
2999 /* sync vre IRQ bit */
3000 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
3001 *dma_prog++ = 0; /* NULL WORD */
3003 for (i = 0; i < (rows/interlace); i++) {
3004 target = target_buffer;
3005 if ( notclipped(bktr, i, width)) {
3006 split(bktr, (volatile u_long **) &dma_prog,
3007 bktr->y2 - bktr->y, OP_WRITE,
3008 Bpp, (volatile u_char **) &target, cols);
3010 while(getline(bktr, i)) {
3011 if (bktr->y != bktr->y2 ) {
3012 split(bktr, (volatile u_long **) &dma_prog,
3013 bktr->y2 - bktr->y, OP_WRITE,
3014 Bpp, (volatile u_char **) &target,
3017 if (bktr->yclip != bktr->yclip2 ) {
3018 split(bktr, (volatile u_long **) &dma_prog,
3019 bktr->yclip2 - bktr->yclip, OP_SKIP,
3020 Bpp, (volatile u_char **) &target, cols);
3027 target_buffer += interlace * pitch;
3032 /* sync vre IRQ bit */
3033 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3034 *dma_prog++ = 0; /* NULL WORD */
3035 *dma_prog++ = OP_JUMP ;
3036 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3037 *dma_prog++ = 0; /* NULL WORD */
3045 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3046 int cols, int rows, int interlace )
3049 volatile unsigned int inst;
3050 volatile unsigned int inst3;
3051 volatile u_long target_buffer, buffer;
3052 volatile u_long *dma_prog;
3053 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3056 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3058 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3059 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3061 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3062 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3064 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3065 bktr->capcontrol = 3 << 2 | 3;
3067 dma_prog = (u_long *) bktr->dma_prog;
3069 /* Construct Write */
3071 /* write , sol, eol */
3072 inst = OP_WRITE | OP_SOL | (cols);
3073 /* write , sol, eol */
3074 inst3 = OP_WRITE | OP_EOL | (cols);
3076 if (bktr->video.addr)
3077 target_buffer = (u_long) bktr->video.addr;
3079 target_buffer = (u_long) vtophys(bktr->bigbuf);
3081 buffer = target_buffer;
3083 /* contruct sync : for video packet format */
3084 /* sync, mode indicator packed data */
3085 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3086 *dma_prog++ = 0; /* NULL WORD */
3090 for (i = 0; i < (rows/interlace); i++) {
3092 *dma_prog++ = target_buffer;
3093 *dma_prog++ = inst3;
3094 *dma_prog++ = target_buffer + b;
3095 target_buffer += interlace*(cols * 2);
3101 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
3102 *dma_prog++ = 0; /* NULL WORD */
3104 *dma_prog++ = OP_JUMP;
3105 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3110 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
3111 *dma_prog++ = 0; /* NULL WORD */
3112 *dma_prog++ = OP_JUMP;
3113 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3118 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3119 *dma_prog++ = 0; /* NULL WORD */
3120 *dma_prog++ = OP_JUMP ;
3121 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3125 if (interlace == 2) {
3127 target_buffer = (u_long) buffer + cols*2;
3129 dma_prog = (u_long * ) bktr->odd_dma_prog;
3132 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1;
3133 *dma_prog++ = 0; /* NULL WORD */
3135 for (i = 0; i < (rows/interlace) ; i++) {
3137 *dma_prog++ = target_buffer;
3138 *dma_prog++ = inst3;
3139 *dma_prog++ = target_buffer + b;
3140 target_buffer += interlace * ( cols*2);
3144 /* sync vro IRQ bit */
3145 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3146 *dma_prog++ = 0; /* NULL WORD */
3147 *dma_prog++ = OP_JUMP ;
3148 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3150 *dma_prog++ = OP_JUMP;
3151 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3152 *dma_prog++ = 0; /* NULL WORD */
3160 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3161 int cols, int rows, int interlace ){
3164 volatile unsigned int inst;
3165 volatile u_long target_buffer, t1, buffer;
3166 volatile u_long *dma_prog;
3167 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3169 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3171 dma_prog = (u_long *) bktr->dma_prog;
3173 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3175 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3176 OUTB(bktr, BKTR_OFORM, 0x00);
3178 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3179 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3181 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3182 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3184 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3185 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3186 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ~0x40); /* set chroma comb */
3187 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ~0x40);
3189 /* disable gamma correction removal */
3190 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3192 /* Construct Write */
3193 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3194 if (bktr->video.addr)
3195 target_buffer = (u_long) bktr->video.addr;
3197 target_buffer = (u_long) vtophys(bktr->bigbuf);
3199 buffer = target_buffer;
3203 /* contruct sync : for video packet format */
3204 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3205 *dma_prog++ = 0; /* NULL WORD */
3207 for (i = 0; i < (rows/interlace ) ; i++) {
3209 *dma_prog++ = cols/2 | cols/2 << 16;
3210 *dma_prog++ = target_buffer;
3211 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3212 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3213 target_buffer += interlace*cols;
3218 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3219 *dma_prog++ = 0; /* NULL WORD */
3221 *dma_prog++ = OP_JUMP ;
3222 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3226 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3227 *dma_prog++ = 0; /* NULL WORD */
3229 *dma_prog++ = OP_JUMP;
3230 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3234 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3235 *dma_prog++ = 0; /* NULL WORD */
3237 *dma_prog++ = OP_JUMP ;
3238 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3242 if (interlace == 2) {
3244 dma_prog = (u_long * ) bktr->odd_dma_prog;
3246 target_buffer = (u_long) buffer + cols;
3247 t1 = buffer + cols/2;
3248 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3249 *dma_prog++ = 0; /* NULL WORD */
3251 for (i = 0; i < (rows/interlace ) ; i++) {
3253 *dma_prog++ = cols/2 | cols/2 << 16;
3254 *dma_prog++ = target_buffer;
3255 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3256 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3257 target_buffer += interlace*cols;
3261 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3262 *dma_prog++ = 0; /* NULL WORD */
3263 *dma_prog++ = OP_JUMP ;
3264 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3265 *dma_prog++ = 0; /* NULL WORD */
3273 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3274 int cols, int rows, int interlace ){
3277 volatile unsigned int inst;
3278 volatile unsigned int inst1;
3279 volatile u_long target_buffer, t1, buffer;
3280 volatile u_long *dma_prog;
3281 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3283 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3285 dma_prog = (u_long *) bktr->dma_prog;
3287 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3289 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3290 OUTB(bktr, BKTR_OFORM, 0x0);
3292 /* Construct Write */
3293 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3294 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3295 if (bktr->video.addr)
3296 target_buffer = (u_long) bktr->video.addr;
3298 target_buffer = (u_long) vtophys(bktr->bigbuf);
3300 buffer = target_buffer;
3303 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3304 *dma_prog++ = 0; /* NULL WORD */
3306 for (i = 0; i < (rows/interlace )/2 ; i++) {
3308 *dma_prog++ = cols/2 | (cols/2 << 16);
3309 *dma_prog++ = target_buffer;
3310 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3311 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3312 target_buffer += interlace*cols;
3313 *dma_prog++ = inst1;
3314 *dma_prog++ = cols/2 | (cols/2 << 16);
3315 *dma_prog++ = target_buffer;
3316 target_buffer += interlace*cols;
3322 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3323 *dma_prog++ = 0; /* NULL WORD */
3325 *dma_prog++ = OP_JUMP;
3326 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3330 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3331 *dma_prog++ = 0; /* NULL WORD */
3333 *dma_prog++ = OP_JUMP;
3334 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3338 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3339 *dma_prog++ = 0; /* NULL WORD */
3340 *dma_prog++ = OP_JUMP ;
3341 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3345 if (interlace == 2) {
3347 dma_prog = (u_long * ) bktr->odd_dma_prog;
3349 target_buffer = (u_long) buffer + cols;
3350 t1 = buffer + cols/2;
3351 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3352 *dma_prog++ = 0; /* NULL WORD */
3354 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3356 *dma_prog++ = cols/2 | (cols/2 << 16);
3357 *dma_prog++ = target_buffer;
3358 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3359 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3360 target_buffer += interlace*cols;
3361 *dma_prog++ = inst1;
3362 *dma_prog++ = cols/2 | (cols/2 << 16);
3363 *dma_prog++ = target_buffer;
3364 target_buffer += interlace*cols;
3371 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3372 *dma_prog++ = 0; /* NULL WORD */
3373 *dma_prog++ = OP_JUMP;
3374 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3375 *dma_prog++ = 0; /* NULL WORD */
3384 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3386 int rows, cols, interlace;
3389 struct format_params *fp;
3390 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3393 fp = &format_params[bktr->format_params];
3395 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3397 /* disable FIFO & RISC, leave other bits alone */
3398 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3400 /* set video parameters */
3401 if (bktr->capture_area_enabled)
3402 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3403 / fp->scaled_htotal / bktr->cols) - 4096;
3405 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3406 / fp->scaled_htotal / bktr->cols) - 4096;
3408 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3409 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3410 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3411 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3412 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3414 /* horizontal active */
3416 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3417 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3418 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3419 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3420 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3421 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3422 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3424 /* horizontal delay */
3425 if (bktr->capture_area_enabled)
3426 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3427 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3429 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3431 temp = temp & 0x3fe;
3433 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3434 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3435 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3436 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3437 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3438 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3439 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3441 /* vertical scale */
3443 if (bktr->capture_area_enabled) {
3444 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3445 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3447 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3450 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3453 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3454 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3456 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3459 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3464 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3465 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3466 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3467 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3468 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3469 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3470 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3473 /* vertical active */
3474 if (bktr->capture_area_enabled)
3475 temp = bktr->capture_area_y_size;
3478 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3479 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3480 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3481 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3482 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3483 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3484 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3486 /* vertical delay */
3487 if (bktr->capture_area_enabled)
3488 temp = fp->vdelay + (bktr->capture_area_y_offset);
3491 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3492 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3493 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3494 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3495 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3496 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3497 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3499 /* end of video params */
3501 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3502 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3503 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3505 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3508 /* capture control */
3511 bktr->bktr_cap_ctl =
3512 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3513 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3514 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3518 bktr->bktr_cap_ctl =
3519 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3520 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3521 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3525 bktr->bktr_cap_ctl =
3526 (BT848_CAP_CTL_DITH_FRAME |
3527 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3528 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3529 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3534 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3539 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3541 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3542 /* user, then use the rgb_vbi RISC program. */
3543 /* Otherwise, use the normal rgb RISC program */
3544 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3545 if ( (bktr->vbiflags & VBI_OPEN)
3546 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3547 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3549 bktr->bktr_cap_ctl |=
3550 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3551 bktr->vbiflags |= VBI_CAPTURE;
3552 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3555 rgb_prog(bktr, i_flag, cols, rows, interlace);
3560 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3561 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3562 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3563 | pixfmt_swap_flags( bktr->pixfmt ));
3567 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3568 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3569 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3570 | pixfmt_swap_flags( bktr->pixfmt ));
3574 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3575 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3576 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3577 | pixfmt_swap_flags( bktr->pixfmt ));
3584 /******************************************************************************
3585 * video & video capture specific routines:
3593 start_capture( bktr_ptr_t bktr, unsigned type )
3596 struct format_params *fp;
3598 fp = &format_params[bktr->format_params];
3600 /* If requested, clear out capture buf first */
3601 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3602 bzero((caddr_t)bktr->bigbuf,
3603 (size_t)bktr->rows * bktr->cols * bktr->frames *
3604 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3607 OUTB(bktr, BKTR_DSTATUS, 0);
3608 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3610 bktr->flags |= type;
3611 bktr->flags &= ~METEOR_WANT_MASK;
3612 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3613 case METEOR_ONLY_EVEN_FIELDS:
3614 bktr->flags |= METEOR_WANT_EVEN;
3617 case METEOR_ONLY_ODD_FIELDS:
3618 bktr->flags |= METEOR_WANT_ODD;
3622 bktr->flags |= METEOR_WANT_MASK;
3627 /* TDEC is only valid for continuous captures */
3628 if ( type == METEOR_SINGLE ) {
3629 u_short fps_save = bktr->fps;
3631 set_fps(bktr, fp->frame_rate);
3632 bktr->fps = fps_save;
3635 set_fps(bktr, bktr->fps);
3637 if (bktr->dma_prog_loaded == FALSE) {
3638 build_dma_prog(bktr, i_flag);
3639 bktr->dma_prog_loaded = TRUE;
3643 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3652 set_fps( bktr_ptr_t bktr, u_short fps )
3654 struct format_params *fp;
3657 fp = &format_params[bktr->format_params];
3659 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3660 case METEOR_ONLY_EVEN_FIELDS:
3661 bktr->flags |= METEOR_WANT_EVEN;
3664 case METEOR_ONLY_ODD_FIELDS:
3665 bktr->flags |= METEOR_WANT_ODD;
3669 bktr->flags |= METEOR_WANT_MASK;
3674 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3675 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3678 OUTB(bktr, BKTR_TDEC, 0);
3680 if (fps < fp->frame_rate)
3681 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3683 OUTB(bktr, BKTR_TDEC, 0);
3693 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3694 * achieve the specified swapping.
3695 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3696 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3698 * Note also that for 3Bpp, we may additionally need to do some creative
3699 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3700 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3701 * as one would expect.
3704 static u_int pixfmt_swap_flags( int pixfmt )
3706 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3709 switch ( pf->Bpp ) {
3710 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3713 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3716 case 4 : if ( pf->swap_bytes )
3717 swapf = pf->swap_shorts ? 0 : WSWAP;
3719 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3728 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3729 * our pixfmt_table indices.
3732 static int oformat_meteor_to_bt( u_long format )
3735 struct meteor_pixfmt *pf1, *pf2;
3737 /* Find format in compatibility table */
3738 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3739 if ( meteor_pixfmt_table[i].meteor_format == format )
3742 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3744 pf1 = &meteor_pixfmt_table[i].public;
3746 /* Match it with an entry in master pixel format table */
3747 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3748 pf2 = &pixfmt_table[i].public;
3750 if (( pf1->type == pf2->type ) &&
3751 ( pf1->Bpp == pf2->Bpp ) &&
3752 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3753 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3754 ( pf1->swap_shorts == pf2->swap_shorts ))
3757 if ( i >= PIXFMT_TABLE_SIZE )
3763 /******************************************************************************
3768 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3769 #define I2CBITTIME_878 (1 << 7)
3770 #define I2C_READ 0x01
3771 #define I2C_COMMAND (I2CBITTIME | \
3772 BT848_DATA_CTL_I2CSCL | \
3773 BT848_DATA_CTL_I2CSDA)
3775 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3776 BT848_DATA_CTL_I2CSCL | \
3777 BT848_DATA_CTL_I2CSDA)
3779 /* Select between old i2c code and new iicbus / smbus code */
3780 #if defined(BKTR_USE_FREEBSD_SMBUS)
3783 * The hardware interface is actually SMB commands
3786 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3790 if (bktr->id == BROOKTREE_848 ||
3791 bktr->id == BROOKTREE_848A ||
3792 bktr->id == BROOKTREE_849A)
3795 cmd = I2C_COMMAND_878;
3798 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3799 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3802 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3803 (char)(byte1 & 0xff)))
3812 i2cRead( bktr_ptr_t bktr, int addr )
3817 if (bktr->id == BROOKTREE_848 ||
3818 bktr->id == BROOKTREE_848A ||
3819 bktr->id == BROOKTREE_849A)
3822 cmd = I2C_COMMAND_878;
3824 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3827 return ((int)((unsigned char)result));
3830 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3832 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3833 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3834 /* Therefore we need low level control of the i2c bus hardware */
3836 /* Write to the MSP or DPL registers */
3838 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3840 unsigned char addr_l, addr_h, data_h, data_l ;
3842 addr_h = (addr >>8) & 0xff;
3843 addr_l = addr & 0xff;
3844 data_h = (data >>8) & 0xff;
3845 data_l = data & 0xff;
3847 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3849 iicbus_write_byte(IICBUS(bktr), dev, 0);
3850 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3851 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3852 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3853 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3855 iicbus_stop(IICBUS(bktr));
3860 /* Read from the MSP or DPL registers */
3862 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3865 unsigned char addr_l, addr_h, dev_r;
3867 u_char data_read[2];
3869 addr_h = (addr >>8) & 0xff;
3870 addr_l = addr & 0xff;
3873 /* XXX errors ignored */
3874 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3876 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3877 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3878 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3880 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3881 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3882 iicbus_stop(IICBUS(bktr));
3884 data = (data_read[0]<<8) | data_read[1];
3889 /* Reset the MSP or DPL chip */
3890 /* The user can block the reset (which is handy if you initialise the
3891 * MSP and/or DPL audio in another operating system first (eg in Windows)
3894 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3897 #ifndef BKTR_NO_MSP_RESET
3898 /* put into reset mode */
3899 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3900 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3901 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3902 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3903 iicbus_stop(IICBUS(bktr));
3905 /* put back to operational mode */
3906 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3907 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3908 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3909 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3910 iicbus_stop(IICBUS(bktr));
3915 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3918 /* XXX errors ignored */
3919 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3920 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3921 iicbus_stop(IICBUS(bktr));
3926 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3929 * Program the i2c bus directly
3932 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3937 /* clear status bits */
3938 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3940 /* build the command datum */
3941 if (bktr->id == BROOKTREE_848 ||
3942 bktr->id == BROOKTREE_848A ||
3943 bktr->id == BROOKTREE_849A) {
3944 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3946 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3948 if ( byte2 != -1 ) {
3949 data |= ((byte2 & 0xff) << 8);
3950 data |= BT848_DATA_CTL_I2CW3B;
3953 /* write the address and data */
3954 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3956 /* wait for completion */
3957 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3958 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3963 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3975 i2cRead( bktr_ptr_t bktr, int addr )
3979 /* clear status bits */
3980 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3982 /* write the READ address */
3983 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3985 if (bktr->id == BROOKTREE_848 ||
3986 bktr->id == BROOKTREE_848A ||
3987 bktr->id == BROOKTREE_849A) {
3988 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3990 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3993 /* wait for completion */
3994 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3995 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4000 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4004 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4007 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4008 /* bt848 automated i2c bus controller cannot handle */
4009 /* Therefore we need low level control of the i2c bus hardware */
4010 /* Idea for the following functions are from elsewhere in this driver and */
4011 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4014 static void i2c_start( bktr_ptr_t bktr) {
4015 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4016 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4017 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4018 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4021 static void i2c_stop( bktr_ptr_t bktr) {
4022 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4023 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4024 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4027 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4031 /* write out the byte */
4032 for ( x = 7; x >= 0; --x ) {
4033 if ( data & (1<<x) ) {
4034 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4035 DELAY( BITD ); /* assert HI data */
4036 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4037 DELAY( BITD ); /* strobe clock */
4038 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4039 DELAY( BITD ); /* release clock */
4042 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4043 DELAY( BITD ); /* assert LO data */
4044 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4045 DELAY( BITD ); /* strobe clock */
4046 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4047 DELAY( BITD ); /* release clock */
4051 /* look for an ACK */
4052 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4053 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4054 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4055 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4060 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4065 /* read in the byte */
4066 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4067 DELAY( BITD ); /* float data */
4068 for ( x = 7; x >= 0; --x ) {
4069 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4070 DELAY( BITD ); /* strobe clock */
4071 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4072 if ( bit ) byte |= (1<<x);
4073 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4074 DELAY( BITD ); /* release clock */
4076 /* After reading the byte, send an ACK */
4077 /* (unless that was the last byte, for which we send a NAK */
4078 if (last) { /* send NAK - same a writing a 1 */
4079 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4080 DELAY( BITD ); /* set data bit */
4081 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4082 DELAY( BITD ); /* strobe clock */
4083 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4084 DELAY( BITD ); /* release clock */
4085 } else { /* send ACK - same as writing a 0 */
4086 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4087 DELAY( BITD ); /* set data bit */
4088 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4089 DELAY( BITD ); /* strobe clock */
4090 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4091 DELAY( BITD ); /* release clock */
4099 /* Write to the MSP or DPL registers */
4100 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4102 unsigned int msp_w_addr = i2c_addr;
4103 unsigned char addr_l, addr_h, data_h, data_l ;
4104 addr_h = (addr >>8) & 0xff;
4105 addr_l = addr & 0xff;
4106 data_h = (data >>8) & 0xff;
4107 data_l = data & 0xff;
4110 i2c_write_byte(bktr, msp_w_addr);
4111 i2c_write_byte(bktr, dev);
4112 i2c_write_byte(bktr, addr_h);
4113 i2c_write_byte(bktr, addr_l);
4114 i2c_write_byte(bktr, data_h);
4115 i2c_write_byte(bktr, data_l);
4119 /* Read from the MSP or DPL registers */
4120 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4122 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4123 addr_h = (addr >>8) & 0xff;
4124 addr_l = addr & 0xff;
4128 i2c_write_byte(bktr,i2c_addr);
4129 i2c_write_byte(bktr,dev_r);
4130 i2c_write_byte(bktr,addr_h);
4131 i2c_write_byte(bktr,addr_l);
4134 i2c_write_byte(bktr,i2c_addr+1);
4135 i2c_read_byte(bktr,&data_1, 0);
4136 i2c_read_byte(bktr,&data_2, 1);
4138 data = (data_1<<8) | data_2;
4142 /* Reset the MSP or DPL chip */
4143 /* The user can block the reset (which is handy if you initialise the
4144 * MSP audio in another operating system first (eg in Windows)
4146 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4148 #ifndef BKTR_NO_MSP_RESET
4149 /* put into reset mode */
4151 i2c_write_byte(bktr, i2c_addr);
4152 i2c_write_byte(bktr, 0x00);
4153 i2c_write_byte(bktr, 0x80);
4154 i2c_write_byte(bktr, 0x00);
4157 /* put back to operational mode */
4159 i2c_write_byte(bktr, i2c_addr);
4160 i2c_write_byte(bktr, 0x00);
4161 i2c_write_byte(bktr, 0x00);
4162 i2c_write_byte(bktr, 0x00);
4169 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4171 /* XXX errors ignored */
4173 i2c_write_byte(bktr,bktr->remote_control_addr);
4174 i2c_read_byte(bktr,&(remote->data[0]), 0);
4175 i2c_read_byte(bktr,&(remote->data[1]), 0);
4176 i2c_read_byte(bktr,&(remote->data[2]), 0);
4182 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4185 #if defined( I2C_SOFTWARE_PROBE )
4188 * we are keeping this around for any parts that we need to probe
4189 * but that CANNOT be probed via an i2c read.
4190 * this is necessary because the hardware i2c mechanism
4191 * cannot be programmed for 1 byte writes.
4192 * currently there are no known i2c parts that we need to probe
4193 * and that cannot be safely read.
4195 static int i2cProbe( bktr_ptr_t bktr, int addr );
4200 * probe for an I2C device at addr.
4203 i2cProbe( bktr_ptr_t bktr, int addr )
4208 #if defined( EXTRA_START )
4209 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4210 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4211 #endif /* EXTRA_START */
4212 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4213 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4216 for ( x = 7; x >= 0; --x ) {
4217 if ( addr & (1<<x) ) {
4218 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4219 DELAY( BITD ); /* assert HI data */
4220 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4221 DELAY( BITD ); /* strobe clock */
4222 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4223 DELAY( BITD ); /* release clock */
4226 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4227 DELAY( BITD ); /* assert LO data */
4228 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4229 DELAY( BITD ); /* strobe clock */
4230 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4231 DELAY( BITD ); /* release clock */
4235 /* look for an ACK */
4236 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4237 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4238 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4239 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4242 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4243 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4244 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4251 #endif /* I2C_SOFTWARE_PROBE */
4256 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */