1 /* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.103.2.4 2000/11/01 09:36:14 roger Exp $ */
4 * This is part of the Driver for Video Capture Cards (Frame grabbers)
5 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
7 * Copyright Roger Hardiman and Amancio Hasty.
9 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
10 * Handles all the open, close, ioctl and read userland calls.
11 * Sets the Bt848 registers and generates RISC pograms.
12 * Controls the i2c bus and GPIO interface.
13 * Contains the interface to the kernel.
14 * (eg probe/attach and open/close/ioctl)
19 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
20 Jim Lowe's driver for the Matrox Meteor PCI card . The
21 Philips SAA 7116 and SAA 7196 are very different chipsets than
24 The original copyright notice by Mark and Jim is included mostly
25 to honor their fantastic work in the Matrox Meteor driver!
30 * 1. Redistributions of source code must retain the
31 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
32 * All rights reserved.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * 3. All advertising materials mentioning features or use of this software
43 * must display the following acknowledgement:
44 * This product includes software developed by Amancio Hasty and
46 * 4. The name of the author may not be used to endorse or promote products
47 * derived from this software without specific prior written permission.
49 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
53 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
54 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
55 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
58 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59 * POSSIBILITY OF SUCH DAMAGE.
66 * 1. Redistributions of source code must retain the
67 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
68 * All rights reserved.
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 * 3. All advertising materials mentioning features or use of this software
79 * must display the following acknowledgement:
80 * This product includes software developed by Mark Tinguely and Jim Lowe
81 * 4. The name of the author may not be used to endorse or promote products
82 * derived from this software without specific prior written permission.
84 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
85 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
86 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
88 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
90 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
91 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
92 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
93 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
94 * POSSIBILITY OF SUCH DAMAGE.
97 #include "opt_bktr.h" /* Include any kernel config options */
101 #endif /* __FreeBSD__ */
104 (defined(__FreeBSD__) && (NBKTR > 0)) \
105 || (defined(__bsdi__)) \
106 || (defined(__OpenBSD__)) \
107 || (defined(__NetBSD__)) \
111 /*******************/
112 /* *** FreeBSD *** */
113 /*******************/
116 #include <sys/param.h>
117 #include <sys/systm.h>
118 #include <sys/kernel.h>
119 #include <sys/signalvar.h>
120 #include <sys/vnode.h>
123 #include <vm/vm_kern.h>
125 #include <vm/vm_extern.h>
127 #if (__FreeBSD_version >=400000) || (NSMBUS > 0)
128 #include <sys/bus.h> /* used by smbus and newbus */
131 #if (__FreeBSD_version < 500000)
132 #include <machine/clock.h> /* for DELAY */
135 #include <pci/pcivar.h>
137 #if (__FreeBSD_version >=300000)
138 #include <machine/bus_memio.h> /* for bus space */
139 #include <machine/bus.h>
143 #include <machine/ioctl_meteor.h>
144 #include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
145 #include <dev/bktr/bktr_reg.h>
146 #include <dev/bktr/bktr_tuner.h>
147 #include <dev/bktr/bktr_card.h>
148 #include <dev/bktr/bktr_audio.h>
149 #include <dev/bktr/bktr_os.h>
150 #include <dev/bktr/bktr_core.h>
151 #if defined(BKTR_FREEBSD_MODULE)
152 #include <dev/bktr/bktr_mem.h>
155 #if defined(BKTR_USE_FREEBSD_SMBUS)
156 #include <dev/bktr/bktr_i2c.h>
157 #include <dev/smbus/smbconf.h>
158 #include <dev/iicbus/iiconf.h>
159 #include "smbus_if.h"
160 #include "iicbus_if.h"
164 bktr_name(bktr_ptr_t bktr)
166 return bktr->bktr_xname;
170 #if (__FreeBSD__ == 2)
171 typedef unsigned int uintptr_t;
173 #endif /* __FreeBSD__ */
180 #endif /* __bsdi__ */
183 /**************************/
184 /* *** OpenBSD/NetBSD *** */
185 /**************************/
186 #if defined(__NetBSD__) || defined(__OpenBSD__)
188 #include <sys/param.h>
189 #include <sys/systm.h>
190 #include <sys/kernel.h>
191 #include <sys/signalvar.h>
192 #include <sys/vnode.h>
195 #include <uvm/uvm_extern.h>
198 #include <vm/vm_kern.h>
200 #include <vm/vm_extern.h>
203 #include <sys/inttypes.h> /* uintptr_t */
204 #include <dev/ic/bt8xx.h>
205 #include <dev/pci/bktr/bktr_reg.h>
206 #include <dev/pci/bktr/bktr_tuner.h>
207 #include <dev/pci/bktr/bktr_card.h>
208 #include <dev/pci/bktr/bktr_audio.h>
209 #include <dev/pci/bktr/bktr_core.h>
210 #include <dev/pci/bktr/bktr_os.h>
212 static int bt848_format = -1;
215 bktr_name(bktr_ptr_t bktr)
217 return (bktr->bktr_dev.dv_xname);
220 #endif /* __NetBSD__ || __OpenBSD__ */
224 typedef u_char bool_t;
226 #define BKTRPRI (PZERO+8)|PCATCH
227 #define VBIPRI (PZERO-4)|PCATCH
231 * memory allocated for DMA programs
233 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
235 /* When to split a dma transfer , the bt848 has timing as well as
236 dma transfer size limitations so that we have to split dma
237 transfers into two dma requests
239 #define DMA_BT848_SPLIT 319*2
242 * Allocate enough memory for:
243 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
245 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
246 * in your kernel configuration file.
249 #ifndef BROOKTREE_ALLOC_PAGES
250 #define BROOKTREE_ALLOC_PAGES 217*4
252 #define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
254 /* Definitions for VBI capture.
255 * There are 16 VBI lines in a PAL video field (32 in a frame),
256 * and we take 2044 samples from each line (placed in a 2048 byte buffer
258 * VBI lines are held in a circular buffer before being read by a
259 * user program from /dev/vbi.
262 #define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
263 #define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
264 #define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
265 #define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
266 #define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
269 /* Defines for fields */
275 * Parameters describing size of transmitted image.
278 static struct format_params format_params[] = {
279 /* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
280 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
282 /* # define BT848_IFORM_F_NTSCM (0x1) */
283 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
285 /* # define BT848_IFORM_F_NTSCJ (0x2) */
286 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
288 /* # define BT848_IFORM_F_PALBDGHI (0x3) */
289 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
291 /* # define BT848_IFORM_F_PALM (0x4) */
292 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
294 /* # define BT848_IFORM_F_PALN (0x5) */
295 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
297 /* # define BT848_IFORM_F_SECAM (0x6) */
298 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
300 /* # define BT848_IFORM_F_RSVD (0x7) - ???? */
301 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
306 * Table of supported Pixel Formats
309 static struct meteor_pixfmt_internal {
310 struct meteor_pixfmt public;
314 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
315 { { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
317 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
318 { { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
320 { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
322 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
323 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
324 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
325 { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
326 { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
327 { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
328 { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
331 #define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
334 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
337 /* FIXME: Also add YUV_422 and YUV_PACKED as well */
339 u_long meteor_format;
340 struct meteor_pixfmt public;
341 } meteor_pixfmt_table[] = {
343 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
346 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
347 { METEOR_GEO_YUV_422,
348 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
350 { METEOR_GEO_YUV_PACKED,
351 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
354 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
357 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
361 #define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
362 sizeof(meteor_pixfmt_table[0]) )
365 #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
366 #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
370 /* sync detect threshold */
372 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
373 BT848_ADC_CRUSH) /* threshold ~125 mV */
375 #define SYNC_LEVEL (BT848_ADC_RESERVED | \
376 BT848_ADC_SYNC_T) /* threshold ~75 mV */
382 /* debug utility for holding previous INT_STAT contents */
384 static u_long status_sum = 0;
387 * defines to make certain bit-fiddles understandable
389 #define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
390 #define RISC_ENABLED BT848_DMA_CTL_RISC_EN
391 #define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
392 #define FIFO_RISC_DISABLED 0
394 #define ALL_INTS_DISABLED 0
395 #define ALL_INTS_CLEARED 0xffffffff
396 #define CAPTURE_OFF 0
398 #define BIT_SEVEN_HIGH (1<<7)
399 #define BIT_EIGHT_HIGH (1<<8)
401 #define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
402 #define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
406 static int oformat_meteor_to_bt( u_long format );
408 static u_int pixfmt_swap_flags( int pixfmt );
411 * bt848 RISC programming routines.
414 static int dump_bt848( bktr_ptr_t bktr );
417 static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
418 int rows, int interlace );
419 static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
420 int rows, int interlace );
421 static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
422 int rows, int interlace );
423 static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
424 int rows, int interlace );
425 static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
426 int rows, int interlace );
427 static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
429 static bool_t getline(bktr_reg_t *, int);
430 static bool_t notclipped(bktr_reg_t * , int , int);
431 static bool_t split(bktr_reg_t *, volatile u_long **, int, u_long, int,
432 volatile u_char ** , int );
434 static void start_capture( bktr_ptr_t bktr, unsigned type );
435 static void set_fps( bktr_ptr_t bktr, u_short fps );
440 * Remote Control Functions
442 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
446 * ioctls common to both video & tuner.
448 static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
451 #if !defined(BKTR_USE_FREEBSD_SMBUS)
453 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
455 static void i2c_start( bktr_ptr_t bktr);
456 static void i2c_stop( bktr_ptr_t bktr);
457 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
458 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
464 * the common attach code, used by all OS versions.
467 common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
470 int need_to_allocate_memory = 1;
472 /***************************************/
473 /* *** OS Specific memory routines *** */
474 /***************************************/
475 #if defined(__NetBSD__) || defined(__OpenBSD__)
476 /* allocate space for dma program */
477 bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog,
479 bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
482 /* allocate space for the VBI buffer */
483 bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata,
485 bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
488 /* allocate space for pixel buffer */
489 if ( BROOKTREE_ALLOC )
490 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
495 #if defined(__FreeBSD__) || defined(__bsdi__)
497 /* If this is a module, check if there is any currently saved contiguous memory */
498 #if defined(BKTR_FREEBSD_MODULE)
499 if (bktr_has_stored_addresses(unit) == 1) {
500 /* recover the addresses */
501 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
502 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
503 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
504 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
505 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
506 need_to_allocate_memory = 0;
510 if (need_to_allocate_memory == 1) {
511 /* allocate space for dma program */
512 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
513 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
515 /* allocte space for the VBI buffer */
516 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
517 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
519 /* allocate space for pixel buffer */
520 if ( BROOKTREE_ALLOC )
521 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
525 #endif /* FreeBSD or BSDi */
528 /* If this is a module, save the current contiguous memory */
529 #if defined(BKTR_FREEBSD_MODULE)
530 bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
531 bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
532 bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
533 bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
534 bktr_store_address(unit, BKTR_MEM_BUF, buf);
539 printf("%s: buffer size %d, addr 0x%x\n",
540 bktr_name(bktr), BROOKTREE_ALLOC, vtophys(buf));
545 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
546 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
548 bktr->alloc_pages = 0;
552 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
553 METEOR_DEV0 | METEOR_RGB16;
554 bktr->dma_prog_loaded = FALSE;
557 bktr->frames = 1; /* one frame */
558 bktr->format = METEOR_GEO_RGB16;
559 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
560 bktr->pixfmt_compat = TRUE;
569 /* using the pci device id and revision id */
570 /* and determine the card type */
571 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
573 switch (PCI_PRODUCT(pci_id)) {
574 case PCI_PRODUCT_BROOKTREE_BT848:
576 bktr->id = BROOKTREE_848A;
578 bktr->id = BROOKTREE_848;
580 case PCI_PRODUCT_BROOKTREE_BT849:
581 bktr->id = BROOKTREE_849A;
583 case PCI_PRODUCT_BROOKTREE_BT878:
584 bktr->id = BROOKTREE_878;
586 case PCI_PRODUCT_BROOKTREE_BT879:
587 bktr->id = BROOKTREE_879;
592 bktr->clr_on_start = FALSE;
594 /* defaults for the tuner section of the card */
595 bktr->tflags = TUNER_INITALIZED;
596 bktr->tuner.frequency = 0;
597 bktr->tuner.channel = 0;
598 bktr->tuner.chnlset = DEFAULT_CHNLSET;
600 bktr->tuner.radio_mode = 0;
601 bktr->audio_mux_select = 0;
602 bktr->audio_mute_state = FALSE;
603 bktr->bt848_card = -1;
604 bktr->bt848_tuner = -1;
605 bktr->reverse_mute = -1;
606 bktr->slow_msp_audio = 0;
607 bktr->msp_use_mono_source = 0;
608 bktr->msp_source_selected = -1;
609 bktr->audio_mux_present = 1;
611 probeCard( bktr, TRUE, unit );
613 /* Initialise any MSP34xx or TDA98xx audio chips */
614 init_audio_devices( bktr );
619 /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
620 * The circular buffer holds 'n' fixed size data blocks.
621 * vbisize is the number of bytes in the circular buffer
622 * vbiread is the point we reading data out of the circular buffer
623 * vbiinsert is the point we insert data into the circular buffer
625 static void vbidecode(bktr_ptr_t bktr) {
627 unsigned int *seq_dest;
629 /* Check if there is room in the buffer to insert the data. */
630 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
632 /* Copy the VBI data into the next free slot in the buffer. */
633 /* 'dest' is the point in vbibuffer where we want to insert new data */
634 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
635 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
637 /* Write the VBI sequence number to the end of the vbi data */
638 /* This is used by the AleVT teletext program */
639 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
641 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
642 *seq_dest = bktr->vbi_sequence_number;
644 /* And increase the VBI sequence number */
645 /* This can wrap around */
646 bktr->vbi_sequence_number++;
649 /* Increment the vbiinsert pointer */
650 /* This can wrap around */
651 bktr->vbiinsert += VBI_DATA_SIZE;
652 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
654 /* And increase the amount of vbi data in the buffer */
655 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
661 * the common interrupt handler.
662 * Returns a 0 or 1 depending on whether the interrupt has handled.
663 * In the OS specific section, bktr_intr() is defined which calls this
664 * common interrupt handler.
667 common_bktr_intr( void *arg )
676 bktr = (bktr_ptr_t) arg;
679 * check to see if any interrupts are unmasked on this device. If
680 * none are, then we likely got here by way of being on a PCI shared
681 * interrupt dispatch list.
683 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
684 return 0; /* bail out now, before we do something we
687 if (!(bktr->flags & METEOR_OPEN)) {
688 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
689 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
693 /* record and clear the INTerrupt status bits */
694 bktr_status = INL(bktr, BKTR_INT_STAT);
695 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
697 /* record and clear the device status register */
698 dstatus = INB(bktr, BKTR_DSTATUS);
699 OUTB(bktr, BKTR_DSTATUS, 0x00);
701 #if defined( STATUS_SUM )
702 /* add any new device status or INTerrupt status bits */
703 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
704 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
705 #endif /* STATUS_SUM */
706 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
707 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
711 /* if risc was disabled re-start process again */
712 /* if there was one of the following errors re-start again */
713 if ( !(bktr_status & BT848_INT_RISC_EN) ||
714 ((bktr_status &(/* BT848_INT_FBUS | */
715 /* BT848_INT_FTRGT | */
716 /* BT848_INT_FDSR | */
718 BT848_INT_RIPERR | BT848_INT_PABORT |
719 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
720 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
722 u_short tdec_save = INB(bktr, BKTR_TDEC);
724 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
725 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
727 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
729 /* Reset temporal decimation counter */
730 OUTB(bktr, BKTR_TDEC, 0);
731 OUTB(bktr, BKTR_TDEC, tdec_save);
733 /* Reset to no-fields captured state */
734 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
735 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
736 case METEOR_ONLY_ODD_FIELDS:
737 bktr->flags |= METEOR_WANT_ODD;
739 case METEOR_ONLY_EVEN_FIELDS:
740 bktr->flags |= METEOR_WANT_EVEN;
743 bktr->flags |= METEOR_WANT_MASK;
748 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
749 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
750 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
752 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
757 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
761 /* If this is not a RISC program interrupt, return */
762 if (!(bktr_status & BT848_INT_RISCI))
766 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
767 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
772 * Disable future interrupts if a capture mode is not selected.
773 * This can happen when we are in the process of closing or
774 * changing capture modes, otherwise it shouldn't happen.
776 if (!(bktr->flags & METEOR_CAP_MASK))
777 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
780 /* Determine which field generated this interrupt */
781 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
785 * Process the VBI data if it is being captured. We do this once
786 * both Odd and Even VBI data is captured. Therefore we do this
787 * in the Even field interrupt handler.
789 if ( (bktr->vbiflags & VBI_CAPTURE)
790 &&(bktr->vbiflags & VBI_OPEN)
792 /* Put VBI data into circular buffer */
795 /* If someone is blocked on reading from /dev/vbi, wake them */
796 if (bktr->vbi_read_blocked) {
797 bktr->vbi_read_blocked = FALSE;
801 /* If someone has a select() on /dev/vbi, inform them */
802 if (bktr->vbi_select.si_pid) {
803 selwakeup(&bktr->vbi_select);
811 * Register the completed field
812 * (For dual-field mode, require fields from the same frame)
814 switch ( bktr->flags & METEOR_WANT_MASK ) {
815 case METEOR_WANT_ODD : w_field = ODD_F ; break;
816 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
817 default : w_field = (ODD_F|EVEN_F); break;
819 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
820 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
821 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
822 default : req_field = (ODD_F|EVEN_F);
826 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
827 bktr->flags &= ~METEOR_WANT_EVEN;
828 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
829 ( w_field == ODD_F ))
830 bktr->flags &= ~METEOR_WANT_ODD;
831 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
832 ( w_field == (ODD_F|EVEN_F) ))
833 bktr->flags &= ~METEOR_WANT_ODD;
834 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
835 ( w_field == ODD_F )) {
836 bktr->flags &= ~METEOR_WANT_ODD;
837 bktr->flags |= METEOR_WANT_EVEN;
840 /* We're out of sync. Start over. */
841 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
842 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
843 case METEOR_ONLY_ODD_FIELDS:
844 bktr->flags |= METEOR_WANT_ODD;
846 case METEOR_ONLY_EVEN_FIELDS:
847 bktr->flags |= METEOR_WANT_EVEN;
850 bktr->flags |= METEOR_WANT_MASK;
858 * If we have a complete frame.
860 if (!(bktr->flags & METEOR_WANT_MASK)) {
861 bktr->frames_captured++;
863 * post the completion time.
865 if (bktr->flags & METEOR_WANT_TS) {
868 if ((u_int) bktr->alloc_pages * PAGE_SIZE
869 <= (bktr->frame_size + sizeof(struct timeval))) {
870 ts =(struct timeval *)bktr->bigbuf +
872 /* doesn't work in synch mode except
881 * Wake up the user in single capture mode.
883 if (bktr->flags & METEOR_SINGLE) {
886 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
888 /* disable risc, leave fifo running */
889 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
894 * If the user requested to be notified via signal,
895 * let them know the frame is complete.
898 if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK))
900 bktr->signal&(~METEOR_SIG_MODE_MASK) );
903 * Reset the want flags if in continuous or
904 * synchronous capture mode.
908 * currently we only support 3 capture modes: odd only, even only,
909 * odd+even interlaced (odd field first). A fourth mode (non interlaced,
910 * either even OR odd) could provide 60 (50 for PAL) pictures per
911 * second, but it would require this routine to toggle the desired frame
912 * each time, and one more different DMA program for the Bt848.
913 * As a consequence, this fourth mode is currently unsupported.
916 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
917 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
918 case METEOR_ONLY_ODD_FIELDS:
919 bktr->flags |= METEOR_WANT_ODD;
921 case METEOR_ONLY_EVEN_FIELDS:
922 bktr->flags |= METEOR_WANT_EVEN;
925 bktr->flags |= METEOR_WANT_MASK;
940 extern int bt848_format; /* used to set the default format, PAL or NTSC */
942 video_open( bktr_ptr_t bktr )
944 int frame_rate, video_format=0;
946 if (bktr->flags & METEOR_OPEN) /* device is busy */
949 bktr->flags |= METEOR_OPEN;
955 bktr->clr_on_start = FALSE;
957 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
959 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
961 #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
967 if (bt848_format == 0 )
970 if (bt848_format == 1 )
973 if (video_format == 1 ) {
974 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
975 bktr->format_params = BT848_IFORM_F_NTSCM;
978 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
979 bktr->format_params = BT848_IFORM_F_PALBDGHI;
983 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
985 /* work around for new Hauppauge 878 cards */
986 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
987 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
988 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
990 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
992 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
993 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
994 frame_rate = format_params[bktr->format_params].frame_rate;
996 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
997 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
998 OUTB(bktr, BKTR_TGCTRL, 0);
999 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
1000 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
1001 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
1004 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1006 bktr->max_clip_node = 0;
1008 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
1010 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
1011 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
1013 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
1014 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
1015 OUTB(bktr, BKTR_E_SCLOOP, 0);
1016 OUTB(bktr, BKTR_O_SCLOOP, 0);
1018 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
1019 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
1021 bktr->fifo_errors = 0;
1022 bktr->dma_errors = 0;
1023 bktr->frames_captured = 0;
1024 bktr->even_fields_captured = 0;
1025 bktr->odd_fields_captured = 0;
1026 bktr->proc = (struct proc *)0;
1027 set_fps(bktr, frame_rate);
1028 bktr->video.addr = 0;
1029 bktr->video.width = 0;
1030 bktr->video.banksize = 0;
1031 bktr->video.ramsize = 0;
1032 bktr->pixfmt_compat = TRUE;
1033 bktr->format = METEOR_GEO_RGB16;
1034 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1036 bktr->capture_area_enabled = FALSE;
1038 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
1039 based motherboards will
1040 operate unreliably */
1045 vbi_open( bktr_ptr_t bktr )
1047 if (bktr->vbiflags & VBI_OPEN) /* device is busy */
1050 bktr->vbiflags |= VBI_OPEN;
1052 /* reset the VBI circular buffer pointers and clear the buffers */
1053 bktr->vbiinsert = 0;
1056 bktr->vbi_sequence_number = 0;
1057 bktr->vbi_read_blocked = FALSE;
1059 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
1060 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
1069 tuner_open( bktr_ptr_t bktr )
1071 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1074 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1077 bktr->tflags |= TUNER_OPEN;
1078 bktr->tuner.frequency = 0;
1079 bktr->tuner.channel = 0;
1080 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1081 bktr->tuner.afc = 0;
1082 bktr->tuner.radio_mode = 0;
1084 /* enable drivers on the GPIO port that control the MUXes */
1085 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1087 /* unmute the audio stream */
1088 set_audio( bktr, AUDIO_UNMUTE );
1090 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1091 init_audio_devices( bktr );
1103 video_close( bktr_ptr_t bktr )
1105 bktr->flags &= ~(METEOR_OPEN |
1110 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1111 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1113 bktr->dma_prog_loaded = FALSE;
1114 OUTB(bktr, BKTR_TDEC, 0);
1115 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1117 /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1118 OUTL(bktr, BKTR_SRESET, 0xf);
1119 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1126 * tuner close handle,
1127 * place holder for tuner specific operations on a close.
1130 tuner_close( bktr_ptr_t bktr )
1132 bktr->tflags &= ~TUNER_OPEN;
1134 /* mute the audio by switching the mux */
1135 set_audio( bktr, AUDIO_MUTE );
1137 /* disable drivers on the GPIO port that control the MUXes */
1138 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1144 vbi_close( bktr_ptr_t bktr )
1147 bktr->vbiflags &= ~VBI_OPEN;
1156 video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
1162 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1165 if (bktr->flags & METEOR_CAP_MASK)
1166 return( EIO ); /* already capturing */
1168 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1171 count = bktr->rows * bktr->cols *
1172 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1174 if ((int) uio->uio_iov->iov_len < count)
1177 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1179 /* capture one frame */
1180 start_capture(bktr, METEOR_SINGLE);
1181 /* wait for capture to complete */
1182 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1183 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1184 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1185 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1191 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
1192 if (!status) /* successful capture */
1193 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1195 printf ("%s: read: tsleep error %d\n",
1196 bktr_name(bktr), status);
1198 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1204 * Read VBI data from the vbi circular buffer
1205 * The buffer holds vbi data blocks which are the same size
1206 * vbiinsert is the position we will insert the next item into the buffer
1207 * vbistart is the actual position in the buffer we want to read from
1208 * vbisize is the exact number of bytes in the buffer left to read
1211 vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1213 int readsize, readsize2;
1217 while(bktr->vbisize == 0) {
1218 if (ioflag & IO_NDELAY) {
1222 bktr->vbi_read_blocked = TRUE;
1223 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1228 /* Now we have some data to give to the user */
1230 /* We cannot read more bytes than there are in
1231 * the circular buffer
1233 readsize = (int)uio->uio_iov->iov_len;
1235 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1237 /* Check if we can read this number of bytes without having
1238 * to wrap around the circular buffer */
1239 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1240 /* We need to wrap around */
1242 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1243 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
1244 status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1246 /* We do not need to wrap around */
1247 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1250 /* Update the number of bytes left to read */
1251 bktr->vbisize -= readsize;
1253 /* Update vbistart */
1254 bktr->vbistart += readsize;
1255 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1267 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
1269 volatile u_char c_temp;
1271 unsigned int temp_iform;
1273 struct meteor_geomet *geo;
1274 struct meteor_counts *counts;
1275 struct meteor_video *video;
1276 struct bktr_capture_area *cap_area;
1283 case BT848SCLIP: /* set clip region */
1284 bktr->max_clip_node = 0;
1285 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1287 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1288 if (bktr->clip_list[i].y_min == 0 &&
1289 bktr->clip_list[i].y_max == 0)
1292 bktr->max_clip_node = i;
1294 /* make sure that the list contains a valid clip secquence */
1295 /* the clip rectangles should be sorted by x then by y as the
1296 second order sort key */
1298 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1300 /* to disable clipping set y_min and y_max to 0 in the first
1301 clip rectangle . The first clip rectangle is clip_list[0].
1306 if (bktr->max_clip_node == 0 &&
1307 (bktr->clip_list[0].y_min != 0 &&
1308 bktr->clip_list[0].y_max != 0)) {
1312 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1313 if (bktr->clip_list[i].y_min == 0 &&
1314 bktr->clip_list[i].y_max == 0) {
1317 if ( bktr->clip_list[i+1].y_min != 0 &&
1318 bktr->clip_list[i+1].y_max != 0 &&
1319 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1321 bktr->max_clip_node = 0;
1326 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1327 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1328 bktr->clip_list[i].x_min < 0 ||
1329 bktr->clip_list[i].x_max < 0 ||
1330 bktr->clip_list[i].y_min < 0 ||
1331 bktr->clip_list[i].y_max < 0 ) {
1332 bktr->max_clip_node = 0;
1337 bktr->dma_prog_loaded = FALSE;
1341 case METEORSTATUS: /* get Bt848 status */
1342 c_temp = INB(bktr, BKTR_DSTATUS);
1344 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1345 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1346 *(u_short *)arg = temp;
1349 case BT848SFMT: /* set input format */
1350 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1351 temp_iform = INB(bktr, BKTR_IFORM);
1352 temp_iform &= ~BT848_IFORM_FORMAT;
1353 temp_iform &= ~BT848_IFORM_XTSEL;
1354 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1356 case BT848_IFORM_F_AUTO:
1357 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1361 case BT848_IFORM_F_NTSCM:
1362 case BT848_IFORM_F_NTSCJ:
1363 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1365 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1366 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1367 bktr->format_params = temp;
1370 case BT848_IFORM_F_PALBDGHI:
1371 case BT848_IFORM_F_PALN:
1372 case BT848_IFORM_F_SECAM:
1373 case BT848_IFORM_F_RSVD:
1374 case BT848_IFORM_F_PALM:
1375 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1377 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1378 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1379 bktr->format_params = temp;
1383 bktr->dma_prog_loaded = FALSE;
1386 case METEORSFMT: /* set input format */
1387 temp_iform = INB(bktr, BKTR_IFORM);
1388 temp_iform &= ~BT848_IFORM_FORMAT;
1389 temp_iform &= ~BT848_IFORM_XTSEL;
1390 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1391 case 0: /* default */
1392 case METEOR_FMT_NTSC:
1393 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1395 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1396 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1397 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1398 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1399 bktr->format_params = BT848_IFORM_F_NTSCM;
1402 case METEOR_FMT_PAL:
1403 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1405 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1406 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1407 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1408 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1409 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1412 case METEOR_FMT_AUTOMODE:
1413 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1415 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1416 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1422 bktr->dma_prog_loaded = FALSE;
1425 case METEORGFMT: /* get input format */
1426 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1430 case BT848GFMT: /* get input format */
1431 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1434 case METEORSCOUNT: /* (re)set error counts */
1435 counts = (struct meteor_counts *) arg;
1436 bktr->fifo_errors = counts->fifo_errors;
1437 bktr->dma_errors = counts->dma_errors;
1438 bktr->frames_captured = counts->frames_captured;
1439 bktr->even_fields_captured = counts->even_fields_captured;
1440 bktr->odd_fields_captured = counts->odd_fields_captured;
1443 case METEORGCOUNT: /* get error counts */
1444 counts = (struct meteor_counts *) arg;
1445 counts->fifo_errors = bktr->fifo_errors;
1446 counts->dma_errors = bktr->dma_errors;
1447 counts->frames_captured = bktr->frames_captured;
1448 counts->even_fields_captured = bktr->even_fields_captured;
1449 counts->odd_fields_captured = bktr->odd_fields_captured;
1453 video = (struct meteor_video *)arg;
1454 video->addr = bktr->video.addr;
1455 video->width = bktr->video.width;
1456 video->banksize = bktr->video.banksize;
1457 video->ramsize = bktr->video.ramsize;
1461 video = (struct meteor_video *)arg;
1462 bktr->video.addr = video->addr;
1463 bktr->video.width = video->width;
1464 bktr->video.banksize = video->banksize;
1465 bktr->video.ramsize = video->ramsize;
1469 set_fps(bktr, *(u_short *)arg);
1473 *(u_short *)arg = bktr->fps;
1476 case METEORSHUE: /* set hue */
1477 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1480 case METEORGHUE: /* get hue */
1481 *(u_char *)arg = INB(bktr, BKTR_HUE);
1484 case METEORSBRIG: /* set brightness */
1485 char_temp = ( *(u_char *)arg & 0xff) - 128;
1486 OUTB(bktr, BKTR_BRIGHT, char_temp);
1490 case METEORGBRIG: /* get brightness */
1491 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1494 case METEORSCSAT: /* set chroma saturation */
1495 temp = (int)*(u_char *)arg;
1497 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1498 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1499 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1500 & ~(BT848_E_CONTROL_SAT_U_MSB
1501 | BT848_E_CONTROL_SAT_V_MSB));
1502 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1503 & ~(BT848_O_CONTROL_SAT_U_MSB |
1504 BT848_O_CONTROL_SAT_V_MSB));
1506 if ( temp & BIT_SEVEN_HIGH ) {
1507 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1508 | (BT848_E_CONTROL_SAT_U_MSB
1509 | BT848_E_CONTROL_SAT_V_MSB));
1510 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1511 | (BT848_O_CONTROL_SAT_U_MSB
1512 | BT848_O_CONTROL_SAT_V_MSB));
1516 case METEORGCSAT: /* get chroma saturation */
1517 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1518 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1519 temp |= BIT_SEVEN_HIGH;
1520 *(u_char *)arg = (u_char)temp;
1523 case METEORSCONT: /* set contrast */
1524 temp = (int)*(u_char *)arg & 0xff;
1526 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1527 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1528 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1529 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1530 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1531 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1532 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1535 case METEORGCONT: /* get contrast */
1536 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1537 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1538 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1541 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1542 bktr->clr_on_start = (*(int *)arg != 0);
1545 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1546 *(int *)arg = (int) bktr->clr_on_start;
1550 if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
1554 bktr->signal = *(int *) arg;
1559 *(int *)arg = bktr->signal;
1564 switch (*(int *) arg) {
1565 case METEOR_CAP_SINGLE:
1567 if (bktr->bigbuf==0) /* no frame buffer allocated */
1569 /* already capturing */
1570 if (temp & METEOR_CAP_MASK)
1575 start_capture(bktr, METEOR_SINGLE);
1577 /* wait for capture to complete */
1578 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1579 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1580 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1582 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1587 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1588 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
1589 if (error && (error != ERESTART)) {
1590 /* Here if we didn't get complete frame */
1592 printf( "%s: ioctl: tsleep error %d %x\n",
1593 bktr_name(bktr), error,
1594 INL(bktr, BKTR_RISC_COUNT));
1598 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1600 /* disable risc, leave fifo running */
1601 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1604 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1605 /* FIXME: should we set bt848->int_stat ??? */
1608 case METEOR_CAP_CONTINOUS:
1609 if (bktr->bigbuf==0) /* no frame buffer allocated */
1611 /* already capturing */
1612 if (temp & METEOR_CAP_MASK)
1616 start_capture(bktr, METEOR_CONTIN);
1618 /* Clear the interrypt status register */
1619 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1621 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1622 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1623 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1625 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1630 dump_bt848( bt848 );
1634 case METEOR_CAP_STOP_CONT:
1635 if (bktr->flags & METEOR_CONTIN) {
1636 /* turn off capture */
1637 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1638 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1639 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1641 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1648 /* can't change parameters while capturing */
1649 if (bktr->flags & METEOR_CAP_MASK)
1653 geo = (struct meteor_geomet *) arg;
1656 /* Either even or odd, if even & odd, then these a zero */
1657 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1658 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1659 printf( "%s: ioctl: Geometry odd or even only.\n",
1664 /* set/clear even/odd flags */
1665 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1666 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1668 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1669 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1670 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1672 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1674 if (geo->columns <= 0) {
1676 "%s: ioctl: %d: columns must be greater than zero.\n",
1677 bktr_name(bktr), geo->columns);
1680 else if ((geo->columns & 0x3fe) != geo->columns) {
1682 "%s: ioctl: %d: columns too large or not even.\n",
1683 bktr_name(bktr), geo->columns);
1687 if (geo->rows <= 0) {
1689 "%s: ioctl: %d: rows must be greater than zero.\n",
1690 bktr_name(bktr), geo->rows);
1693 else if (((geo->rows & 0x7fe) != geo->rows) ||
1694 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1695 ((geo->rows & 0x3fe) != geo->rows)) ) {
1697 "%s: ioctl: %d: rows too large or not even.\n",
1698 bktr_name(bktr), geo->rows);
1702 if (geo->frames > 32) {
1703 printf("%s: ioctl: too many frames.\n",
1712 bktr->dma_prog_loaded = FALSE;
1713 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1715 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1717 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1718 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1720 /* meteor_mem structure for SYNC Capture */
1721 if (geo->frames > 1) temp += PAGE_SIZE;
1724 if ((int) temp > bktr->alloc_pages
1725 && bktr->video.addr == 0) {
1727 /*****************************/
1728 /* *** OS Dependant code *** */
1729 /*****************************/
1730 #if defined(__NetBSD__) || defined(__OpenBSD__)
1731 bus_dmamap_t dmamap;
1733 buf = get_bktr_mem(bktr, &dmamap,
1736 free_bktr_mem(bktr, bktr->dm_mem,
1738 bktr->dm_mem = dmamap;
1741 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1743 kmem_free(kernel_map, bktr->bigbuf,
1744 (bktr->alloc_pages * PAGE_SIZE));
1748 bktr->alloc_pages = temp;
1751 "%s: ioctl: Allocating %d bytes\n",
1752 bktr_name(bktr), temp*PAGE_SIZE);
1762 bktr->rows = geo->rows;
1763 bktr->cols = geo->columns;
1764 bktr->frames = geo->frames;
1766 /* Pixel format (if in meteor pixfmt compatibility mode) */
1767 if ( bktr->pixfmt_compat ) {
1768 bktr->format = METEOR_GEO_YUV_422;
1769 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1770 case 0: /* default */
1771 case METEOR_GEO_RGB16:
1772 bktr->format = METEOR_GEO_RGB16;
1774 case METEOR_GEO_RGB24:
1775 bktr->format = METEOR_GEO_RGB24;
1777 case METEOR_GEO_YUV_422:
1778 bktr->format = METEOR_GEO_YUV_422;
1779 if (geo->oformat & METEOR_GEO_YUV_12)
1780 bktr->format = METEOR_GEO_YUV_12;
1782 case METEOR_GEO_YUV_PACKED:
1783 bktr->format = METEOR_GEO_YUV_PACKED;
1786 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1789 if (bktr->flags & METEOR_CAP_MASK) {
1791 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1792 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1793 case METEOR_ONLY_ODD_FIELDS:
1794 bktr->flags |= METEOR_WANT_ODD;
1796 case METEOR_ONLY_EVEN_FIELDS:
1797 bktr->flags |= METEOR_WANT_EVEN;
1800 bktr->flags |= METEOR_WANT_MASK;
1804 start_capture(bktr, METEOR_CONTIN);
1805 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1806 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1807 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1808 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1814 /* end of METEORSETGEO */
1816 /* FIXME. The Capture Area currently has the following restrictions:
1818 y_offset may need to be even in interlaced modes
1819 RGB24 - Interlaced mode
1820 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1821 y_size must be greater than or equal to METEORSETGEO height (rows)
1822 RGB24 - Even Only (or Odd Only) mode
1823 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1824 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1825 YUV12 - Interlaced mode
1826 x_size must be greater than or equal to METEORSETGEO width (cols)
1827 y_size must be greater than or equal to METEORSETGEO height (rows)
1828 YUV12 - Even Only (or Odd Only) mode
1829 x_size must be greater than or equal to METEORSETGEO width (cols)
1830 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1833 case BT848_SCAPAREA: /* set capture area of each video frame */
1834 /* can't change parameters while capturing */
1835 if (bktr->flags & METEOR_CAP_MASK)
1838 cap_area = (struct bktr_capture_area *) arg;
1839 bktr->capture_area_x_offset = cap_area->x_offset;
1840 bktr->capture_area_y_offset = cap_area->y_offset;
1841 bktr->capture_area_x_size = cap_area->x_size;
1842 bktr->capture_area_y_size = cap_area->y_size;
1843 bktr->capture_area_enabled = TRUE;
1845 bktr->dma_prog_loaded = FALSE;
1848 case BT848_GCAPAREA: /* get capture area of each video frame */
1849 cap_area = (struct bktr_capture_area *) arg;
1850 if (bktr->capture_area_enabled == FALSE) {
1851 cap_area->x_offset = 0;
1852 cap_area->y_offset = 0;
1853 cap_area->x_size = format_params[
1854 bktr->format_params].scaled_hactive;
1855 cap_area->y_size = format_params[
1856 bktr->format_params].vactive;
1858 cap_area->x_offset = bktr->capture_area_x_offset;
1859 cap_area->y_offset = bktr->capture_area_y_offset;
1860 cap_area->x_size = bktr->capture_area_x_size;
1861 cap_area->y_size = bktr->capture_area_y_size;
1866 return common_ioctl( bktr, cmd, arg );
1876 tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
1879 unsigned int temp, temp1;
1892 /* Read the last key pressed by the Remote Control */
1893 if (bktr->remote_control == 0) return (EINVAL);
1894 remote_read(bktr, (struct bktr_remote *)arg);
1897 #if defined( TUNER_AFC )
1898 case TVTUNER_SETAFC:
1899 bktr->tuner.afc = (*(int *)arg != 0);
1902 case TVTUNER_GETAFC:
1903 *(int *)arg = bktr->tuner.afc;
1904 /* XXX Perhaps use another bit to indicate AFC success? */
1906 #endif /* TUNER_AFC */
1908 case TVTUNER_SETCHNL:
1909 temp_mute( bktr, TRUE );
1910 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1912 temp_mute( bktr, FALSE );
1915 *(unsigned long *)arg = temp;
1917 /* after every channel change, we must restart the MSP34xx */
1918 /* audio chip to reselect NICAM STEREO or MONO audio */
1919 if ( bktr->card.msp3400c )
1920 msp_autodetect( bktr );
1922 /* after every channel change, we must restart the DPL35xx */
1923 if ( bktr->card.dpl3518a )
1924 dpl_autodetect( bktr );
1926 temp_mute( bktr, FALSE );
1929 case TVTUNER_GETCHNL:
1930 *(unsigned long *)arg = bktr->tuner.channel;
1933 case TVTUNER_SETTYPE:
1934 temp = *(unsigned long *)arg;
1935 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1937 bktr->tuner.chnlset = temp;
1940 case TVTUNER_GETTYPE:
1941 *(unsigned long *)arg = bktr->tuner.chnlset;
1944 case TVTUNER_GETSTATUS:
1945 temp = get_tuner_status( bktr );
1946 *(unsigned long *)arg = temp & 0xff;
1949 case TVTUNER_SETFREQ:
1950 temp_mute( bktr, TRUE );
1951 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1952 temp_mute( bktr, FALSE );
1954 temp_mute( bktr, FALSE );
1957 *(unsigned long *)arg = temp;
1959 /* after every channel change, we must restart the MSP34xx */
1960 /* audio chip to reselect NICAM STEREO or MONO audio */
1961 if ( bktr->card.msp3400c )
1962 msp_autodetect( bktr );
1964 /* after every channel change, we must restart the DPL35xx */
1965 if ( bktr->card.dpl3518a )
1966 dpl_autodetect( bktr );
1968 temp_mute( bktr, FALSE );
1971 case TVTUNER_GETFREQ:
1972 *(unsigned long *)arg = bktr->tuner.frequency;
1975 case TVTUNER_GETCHNLSET:
1976 return tuner_getchnlset((struct bktr_chnlset *)arg);
1978 case BT848_SAUDIO: /* set audio channel */
1979 if ( set_audio( bktr, *(int*)arg ) < 0 )
1983 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1984 case BT848_SHUE: /* set hue */
1985 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1988 case BT848_GHUE: /* get hue */
1989 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1992 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1993 case BT848_SBRIG: /* set brightness */
1994 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1997 case BT848_GBRIG: /* get brightness */
1998 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2002 case BT848_SCSAT: /* set chroma saturation */
2003 tmp_int = *(int*)arg;
2005 temp = INB(bktr, BKTR_E_CONTROL);
2006 temp1 = INB(bktr, BKTR_O_CONTROL);
2007 if ( tmp_int & BIT_EIGHT_HIGH ) {
2008 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2009 BT848_E_CONTROL_SAT_V_MSB);
2010 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2011 BT848_O_CONTROL_SAT_V_MSB);
2014 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2015 BT848_E_CONTROL_SAT_V_MSB);
2016 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2017 BT848_O_CONTROL_SAT_V_MSB);
2020 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2021 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2022 OUTB(bktr, BKTR_E_CONTROL, temp);
2023 OUTB(bktr, BKTR_O_CONTROL, temp1);
2026 case BT848_GCSAT: /* get chroma saturation */
2027 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2028 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2029 tmp_int |= BIT_EIGHT_HIGH;
2030 *(int*)arg = tmp_int;
2034 case BT848_SVSAT: /* set chroma V saturation */
2035 tmp_int = *(int*)arg;
2037 temp = INB(bktr, BKTR_E_CONTROL);
2038 temp1 = INB(bktr, BKTR_O_CONTROL);
2039 if ( tmp_int & BIT_EIGHT_HIGH) {
2040 temp |= BT848_E_CONTROL_SAT_V_MSB;
2041 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2044 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2045 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2048 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2049 OUTB(bktr, BKTR_E_CONTROL, temp);
2050 OUTB(bktr, BKTR_O_CONTROL, temp1);
2053 case BT848_GVSAT: /* get chroma V saturation */
2054 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2055 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
2056 tmp_int |= BIT_EIGHT_HIGH;
2057 *(int*)arg = tmp_int;
2061 case BT848_SUSAT: /* set chroma U saturation */
2062 tmp_int = *(int*)arg;
2064 temp = INB(bktr, BKTR_E_CONTROL);
2065 temp1 = INB(bktr, BKTR_O_CONTROL);
2066 if ( tmp_int & BIT_EIGHT_HIGH ) {
2067 temp |= BT848_E_CONTROL_SAT_U_MSB;
2068 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2071 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2072 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2075 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2076 OUTB(bktr, BKTR_E_CONTROL, temp);
2077 OUTB(bktr, BKTR_O_CONTROL, temp1);
2080 case BT848_GUSAT: /* get chroma U saturation */
2081 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2082 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2083 tmp_int |= BIT_EIGHT_HIGH;
2084 *(int*)arg = tmp_int;
2087 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2089 case BT848_SLNOTCH: /* set luma notch */
2090 tmp_int = (*(int *)arg & 0x7) << 5 ;
2091 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2092 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2093 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2094 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2097 case BT848_GLNOTCH: /* get luma notch */
2098 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2103 case BT848_SCONT: /* set contrast */
2104 tmp_int = *(int*)arg;
2106 temp = INB(bktr, BKTR_E_CONTROL);
2107 temp1 = INB(bktr, BKTR_O_CONTROL);
2108 if ( tmp_int & BIT_EIGHT_HIGH ) {
2109 temp |= BT848_E_CONTROL_CON_MSB;
2110 temp1 |= BT848_O_CONTROL_CON_MSB;
2113 temp &= ~BT848_E_CONTROL_CON_MSB;
2114 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2117 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2118 OUTB(bktr, BKTR_E_CONTROL, temp);
2119 OUTB(bktr, BKTR_O_CONTROL, temp1);
2122 case BT848_GCONT: /* get contrast */
2123 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2124 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2125 tmp_int |= BIT_EIGHT_HIGH;
2126 *(int*)arg = tmp_int;
2129 /* FIXME: SCBARS and CCBARS require a valid int * */
2130 /* argument to succeed, but its not used; consider */
2131 /* using the arg to store the on/off state so */
2132 /* there's only one ioctl() needed to turn cbars on/off */
2133 case BT848_SCBARS: /* set colorbar output */
2134 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2137 case BT848_CCBARS: /* clear colorbar output */
2138 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2141 case BT848_GAUDIO: /* get audio channel */
2142 temp = bktr->audio_mux_select;
2143 if ( bktr->audio_mute_state == TRUE )
2148 case BT848_SBTSC: /* set audio channel */
2149 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2153 case BT848_WEEPROM: /* write eeprom */
2154 offset = (((struct eeProm *)arg)->offset);
2155 count = (((struct eeProm *)arg)->count);
2156 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2157 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2161 case BT848_REEPROM: /* read eeprom */
2162 offset = (((struct eeProm *)arg)->offset);
2163 count = (((struct eeProm *)arg)->count);
2164 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2165 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2169 case BT848_SIGNATURE:
2170 offset = (((struct eeProm *)arg)->offset);
2171 count = (((struct eeProm *)arg)->count);
2172 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2173 if ( signCard( bktr, offset, count, buf ) < 0 )
2177 /* Ioctl's for direct gpio access */
2178 #ifdef BKTR_GPIO_ACCESS
2179 case BT848_GPIO_GET_EN:
2180 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2183 case BT848_GPIO_SET_EN:
2184 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2187 case BT848_GPIO_GET_DATA:
2188 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2191 case BT848_GPIO_SET_DATA:
2192 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2194 #endif /* BKTR_GPIO_ACCESS */
2196 /* Ioctl's for running the tuner device in radio mode */
2199 *(unsigned char *)arg = bktr->tuner.radio_mode;
2203 bktr->tuner.radio_mode = *(unsigned char *)arg;
2207 *(unsigned long *)arg = bktr->tuner.frequency;
2211 /* The argument to this ioctl is NOT freq*16. It is
2215 temp=(int)*(unsigned long *)arg;
2217 #ifdef BKTR_RADIO_DEBUG
2218 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2219 (int)*(unsigned long *)arg, temp);
2222 #ifndef BKTR_RADIO_NOFREQCHECK
2223 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2225 if(temp<8750 || temp>10800) {
2226 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2230 temp_mute( bktr, TRUE );
2231 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2232 temp_mute( bktr, FALSE );
2233 #ifdef BKTR_RADIO_DEBUG
2235 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2239 *(unsigned long *)arg = temp;
2242 /* Luigi's I2CWR ioctl */
2244 par = *(u_long *)arg;
2245 write = (par >> 24) & 0xff ;
2246 i2c_addr = (par >> 16) & 0xff ;
2247 i2c_port = (par >> 8) & 0xff ;
2248 data = (par) & 0xff ;
2251 i2cWrite( bktr, i2c_addr, i2c_port, data);
2253 data = i2cRead( bktr, i2c_addr);
2255 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2259 #ifdef BT848_MSP_READ
2260 /* I2C ioctls to allow userland access to the MSP chip */
2261 case BT848_MSP_READ:
2263 struct bktr_msp_control *msp;
2264 msp = (struct bktr_msp_control *) arg;
2265 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2266 msp->function, msp->address);
2270 case BT848_MSP_WRITE:
2272 struct bktr_msp_control *msp;
2273 msp = (struct bktr_msp_control *) arg;
2274 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2275 msp->address, msp->data );
2279 case BT848_MSP_RESET:
2280 msp_dpl_reset(bktr, bktr->msp_addr);
2285 return common_ioctl( bktr, cmd, arg );
2296 common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2300 struct meteor_pixfmt *pf_pub;
2304 case METEORSINPUT: /* set input device */
2305 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2306 /* On the original bt848 boards, */
2307 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2308 /* On the Hauppauge bt878 boards, */
2309 /* Tuner is MUX0, RCA is MUX3 */
2310 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2311 /* stick with this system in our Meteor Emulation */
2313 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2315 /* this is the RCA video input */
2316 case 0: /* default */
2317 case METEOR_INPUT_DEV0:
2318 /* METEOR_INPUT_DEV_RCA: */
2319 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2321 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2322 & ~BT848_IFORM_MUXSEL);
2324 /* work around for new Hauppauge 878 cards */
2325 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2326 (bktr->id==BROOKTREE_878 ||
2327 bktr->id==BROOKTREE_879) )
2328 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2330 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2332 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2333 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2334 set_audio( bktr, AUDIO_EXTERN );
2337 /* this is the tuner input */
2338 case METEOR_INPUT_DEV1:
2339 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2341 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2342 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2343 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2344 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2345 set_audio( bktr, AUDIO_TUNER );
2348 /* this is the S-VHS input, but with a composite camera */
2349 case METEOR_INPUT_DEV2:
2350 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2352 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2353 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2354 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2355 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2356 set_audio( bktr, AUDIO_EXTERN );
2359 /* this is the S-VHS input */
2360 case METEOR_INPUT_DEV_SVIDEO:
2361 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2362 | METEOR_DEV_SVIDEO;
2363 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2364 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2365 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2366 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2367 set_audio( bktr, AUDIO_EXTERN );
2370 case METEOR_INPUT_DEV3:
2371 if ((bktr->id == BROOKTREE_848A) ||
2372 (bktr->id == BROOKTREE_849A) ||
2373 (bktr->id == BROOKTREE_878) ||
2374 (bktr->id == BROOKTREE_879) ) {
2375 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2377 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2379 /* work around for new Hauppauge 878 cards */
2380 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2381 (bktr->id==BROOKTREE_878 ||
2382 bktr->id==BROOKTREE_879) )
2383 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2385 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2387 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2388 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2389 set_audio( bktr, AUDIO_EXTERN );
2399 case METEORGINPUT: /* get input device */
2400 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2403 case METEORSACTPIXFMT:
2404 if (( *(int *)arg < 0 ) ||
2405 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2408 bktr->pixfmt = *(int *)arg;
2409 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2410 | pixfmt_swap_flags( bktr->pixfmt ));
2411 bktr->pixfmt_compat = FALSE;
2414 case METEORGACTPIXFMT:
2415 *(int *)arg = bktr->pixfmt;
2418 case METEORGSUPPIXFMT :
2419 pf_pub = (struct meteor_pixfmt *)arg;
2420 pixfmt = pf_pub->index;
2422 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2425 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2426 sizeof( *pf_pub ) );
2428 /* Patch in our format index */
2429 pf_pub->index = pixfmt;
2432 #if defined( STATUS_SUM )
2433 case BT848_GSTATUS: /* reap status */
2435 DECLARE_INTR_MASK(s);
2440 *(u_int*)arg = temp;
2443 #endif /* STATUS_SUM */
2455 /******************************************************************************
2456 * bt848 RISC programming routines:
2465 dump_bt848( bktr_ptr_t bktr )
2468 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2469 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2470 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2471 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2472 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2477 for (i = 0; i < 40; i+=4) {
2478 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2480 r[i], INL(bktr, r[i]),
2481 r[i+1], INL(bktr, r[i+1]),
2482 r[i+2], INL(bktr, r[i+2]),
2483 r[i+3], INL(bktr, r[i+3]]));
2486 printf("%s: INT STAT %x \n", bktr_name(bktr),
2487 INL(bktr, BKTR_INT_STAT));
2488 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2489 INL(bktr, BKTR_INT_MASK));
2490 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2491 INW(bktr, BKTR_GPIO_DMA_CTL));
2499 * build write instruction
2501 #define BKTR_FM1 0x6 /* packed data to follow */
2502 #define BKTR_FM3 0xe /* planar data to follow */
2503 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2504 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2505 #define BKTR_PXV 0x0 /* valid word (never used) */
2506 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2507 #define BKTR_SOL 0x2 /* first dword */
2509 #define OP_WRITE (0x1 << 28)
2510 #define OP_SKIP (0x2 << 28)
2511 #define OP_WRITEC (0x5 << 28)
2512 #define OP_JUMP (0x7 << 28)
2513 #define OP_SYNC (0x8 << 28)
2514 #define OP_WRITE123 (0x9 << 28)
2515 #define OP_WRITES123 (0xb << 28)
2516 #define OP_SOL (1 << 27) /* first instr for scanline */
2517 #define OP_EOL (1 << 26)
2519 #define BKTR_RESYNC (1 << 15)
2520 #define BKTR_GEN_IRQ (1 << 24)
2523 * The RISC status bits can be set/cleared in the RISC programs
2524 * and tested in the Interrupt Handler
2526 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2527 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2528 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2529 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2531 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2532 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2533 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2534 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2536 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2537 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2538 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2539 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2541 bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2543 bktr_clip_t * clip_node;
2544 bktr->clip_start = -1;
2548 bktr->line_length = width;
2551 bktr->current_col = 0;
2553 if (bktr->max_clip_node == 0 ) return TRUE;
2554 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2557 for (i = 0; i < bktr->max_clip_node; i++ ) {
2558 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2559 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
2560 bktr->clip_start = i;
2568 bool_t getline(bktr_reg_t *bktr, int x ) {
2570 bktr_clip_t * clip_node ;
2572 if (bktr->line_length == 0 ||
2573 bktr->current_col >= bktr->line_length) return FALSE;
2575 bktr->y = min(bktr->last_y, bktr->line_length);
2576 bktr->y2 = bktr->line_length;
2578 bktr->yclip = bktr->yclip2 = -1;
2579 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
2580 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2581 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2582 if (bktr->last_y <= clip_node->y_min) {
2583 bktr->y = min(bktr->last_y, bktr->line_length);
2584 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2585 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2586 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2587 bktr->last_y = bktr->yclip2;
2588 bktr->clip_start = i;
2590 for (j = i+1; j < bktr->max_clip_node; j++ ) {
2591 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2592 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2593 if (bktr->last_y >= clip_node->y_min) {
2594 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2595 bktr->last_y = bktr->yclip2;
2596 bktr->clip_start = j;
2605 if (bktr->current_col <= bktr->line_length) {
2606 bktr->current_col = bktr->line_length;
2612 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2613 u_long operation, int pixel_width,
2614 volatile u_char ** target_buffer, int cols ) {
2617 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
2618 u_int skip, start_skip;
2620 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2621 /* to the 1st byte in the mem dword containing our start addr. */
2622 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2625 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
2626 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) {
2627 case 2 : start_skip = 4 ; break;
2628 case 1 : start_skip = 8 ; break;
2631 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
2632 if ( width == cols) {
2633 flag = OP_SOL | OP_EOL;
2634 } else if (bktr->current_col == 0 ) {
2636 } else if (bktr->current_col == cols) {
2641 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2642 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2647 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
2648 if (operation != OP_SKIP )
2649 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer;
2651 *target_buffer += width * pixel_width;
2652 bktr->current_col += width;
2656 if (bktr->current_col == 0 && width == cols) {
2659 } else if (bktr->current_col == 0 ) {
2662 } else if (bktr->current_col >= cols) {
2671 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2672 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
2677 *(*dma_prog)++ = operation | flag |
2678 (width * pixel_width / 2 - skip);
2679 if (operation != OP_SKIP )
2680 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ;
2681 *target_buffer += (width * pixel_width / 2) ;
2683 if ( operation == OP_WRITE )
2684 operation = OP_WRITEC;
2685 *(*dma_prog)++ = operation | flag2 |
2686 (width * pixel_width / 2);
2687 *target_buffer += (width * pixel_width / 2) ;
2688 bktr->current_col += width;
2696 * Generate the RISC instructions to capture both VBI and video images
2699 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2702 volatile u_long target_buffer, buffer, target,width;
2703 volatile u_long pitch;
2704 volatile u_long *dma_prog; /* DMA prog is an array of
2705 32 bit RISC instructions */
2706 volatile u_long *loop_point;
2707 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2708 u_int Bpp = pf_int->public.Bpp;
2709 unsigned int vbisamples; /* VBI samples per line */
2710 unsigned int vbilines; /* VBI lines per field */
2711 unsigned int num_dwords; /* DWORDS per line */
2713 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2714 vbilines = format_params[bktr->format_params].vbi_num_lines;
2715 num_dwords = vbisamples/4;
2717 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2718 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2719 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2720 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2723 OUTB(bktr, BKTR_OFORM, 0x00);
2725 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2726 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2727 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2728 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2730 /* disable gamma correction removal */
2731 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2734 OUTB(bktr, BKTR_E_VTC, 0);
2735 OUTB(bktr, BKTR_O_VTC, 0);
2737 OUTB(bktr, BKTR_E_VTC, 1);
2738 OUTB(bktr, BKTR_O_VTC, 1);
2740 bktr->capcontrol = 3 << 2 | 3;
2742 dma_prog = (u_long *) bktr->dma_prog;
2744 /* Construct Write */
2746 if (bktr->video.addr) {
2747 target_buffer = (u_long) bktr->video.addr;
2748 pitch = bktr->video.width;
2751 target_buffer = (u_long) vtophys(bktr->bigbuf);
2755 buffer = target_buffer;
2757 /* Wait for the VRE sync marking the end of the Even and
2758 * the start of the Odd field. Resync here.
2760 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE;
2763 loop_point = dma_prog;
2765 /* store the VBI data */
2766 /* look for sync with packed data */
2767 *dma_prog++ = OP_SYNC | BKTR_FM1;
2769 for(i = 0; i < vbilines; i++) {
2770 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2771 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2772 (i * VBI_LINE_SIZE));
2775 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2776 /* store the Odd field video image */
2777 /* look for sync with packed data */
2778 *dma_prog++ = OP_SYNC | BKTR_FM1;
2779 *dma_prog++ = 0; /* NULL WORD */
2781 for (i = 0; i < (rows/interlace); i++) {
2782 target = target_buffer;
2783 if ( notclipped(bktr, i, width)) {
2784 split(bktr, (volatile u_long **) &dma_prog,
2785 bktr->y2 - bktr->y, OP_WRITE,
2786 Bpp, (volatile u_char **) &target, cols);
2789 while(getline(bktr, i)) {
2790 if (bktr->y != bktr->y2 ) {
2791 split(bktr, (volatile u_long **) &dma_prog,
2792 bktr->y2 - bktr->y, OP_WRITE,
2793 Bpp, (volatile u_char **) &target, cols);
2795 if (bktr->yclip != bktr->yclip2 ) {
2796 split(bktr,(volatile u_long **) &dma_prog,
2797 bktr->yclip2 - bktr->yclip,
2799 Bpp, (volatile u_char **) &target, cols);
2805 target_buffer += interlace * pitch;
2811 /* Grab the Even field */
2812 /* Look for the VRO, end of Odd field, marker */
2813 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2814 *dma_prog++ = 0; /* NULL WORD */
2816 /* store the VBI data */
2817 /* look for sync with packed data */
2818 *dma_prog++ = OP_SYNC | BKTR_FM1;
2820 for(i = 0; i < vbilines; i++) {
2821 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples;
2822 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata +
2823 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2826 /* store the video image */
2827 if (i_flag == 1) /*Even Only*/
2828 target_buffer = buffer;
2829 if (i_flag == 3) /*interlaced*/
2830 target_buffer = buffer+pitch;
2833 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2834 /* look for sync with packed data */
2835 *dma_prog++ = OP_SYNC | BKTR_FM1;
2836 *dma_prog++ = 0; /* NULL WORD */
2838 for (i = 0; i < (rows/interlace); i++) {
2839 target = target_buffer;
2840 if ( notclipped(bktr, i, width)) {
2841 split(bktr, (volatile u_long **) &dma_prog,
2842 bktr->y2 - bktr->y, OP_WRITE,
2843 Bpp, (volatile u_char **) &target, cols);
2845 while(getline(bktr, i)) {
2846 if (bktr->y != bktr->y2 ) {
2847 split(bktr, (volatile u_long **) &dma_prog,
2848 bktr->y2 - bktr->y, OP_WRITE,
2849 Bpp, (volatile u_char **) &target,
2852 if (bktr->yclip != bktr->yclip2 ) {
2853 split(bktr, (volatile u_long **) &dma_prog,
2854 bktr->yclip2 - bktr->yclip, OP_SKIP,
2855 Bpp, (volatile u_char **) &target, cols);
2862 target_buffer += interlace * pitch;
2867 /* Look for end of 'Even Field' */
2868 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
2869 *dma_prog++ = 0; /* NULL WORD */
2871 *dma_prog++ = OP_JUMP ;
2872 *dma_prog++ = (u_long ) vtophys(loop_point) ;
2873 *dma_prog++ = 0; /* NULL WORD */
2881 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2884 volatile u_long target_buffer, buffer, target,width;
2885 volatile u_long pitch;
2886 volatile u_long *dma_prog;
2887 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2888 u_int Bpp = pf_int->public.Bpp;
2890 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2891 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2892 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2893 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2895 OUTB(bktr, BKTR_OFORM, 0x00);
2897 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2898 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2899 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2900 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2902 /* disable gamma correction removal */
2903 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2906 OUTB(bktr, BKTR_E_VTC, 0);
2907 OUTB(bktr, BKTR_O_VTC, 0);
2909 OUTB(bktr, BKTR_E_VTC, 1);
2910 OUTB(bktr, BKTR_O_VTC, 1);
2912 bktr->capcontrol = 3 << 2 | 3;
2914 dma_prog = (u_long *) bktr->dma_prog;
2916 /* Construct Write */
2918 if (bktr->video.addr) {
2919 target_buffer = (u_long) bktr->video.addr;
2920 pitch = bktr->video.width;
2923 target_buffer = (u_long) vtophys(bktr->bigbuf);
2927 buffer = target_buffer;
2929 /* contruct sync : for video packet format */
2930 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2932 /* sync, mode indicator packed data */
2933 *dma_prog++ = 0; /* NULL WORD */
2935 for (i = 0; i < (rows/interlace); i++) {
2936 target = target_buffer;
2937 if ( notclipped(bktr, i, width)) {
2938 split(bktr, (volatile u_long **) &dma_prog,
2939 bktr->y2 - bktr->y, OP_WRITE,
2940 Bpp, (volatile u_char **) &target, cols);
2943 while(getline(bktr, i)) {
2944 if (bktr->y != bktr->y2 ) {
2945 split(bktr, (volatile u_long **) &dma_prog,
2946 bktr->y2 - bktr->y, OP_WRITE,
2947 Bpp, (volatile u_char **) &target, cols);
2949 if (bktr->yclip != bktr->yclip2 ) {
2950 split(bktr,(volatile u_long **) &dma_prog,
2951 bktr->yclip2 - bktr->yclip,
2953 Bpp, (volatile u_char **) &target, cols);
2959 target_buffer += interlace * pitch;
2966 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO;
2967 *dma_prog++ = 0; /* NULL WORD */
2969 *dma_prog++ = OP_JUMP;
2970 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2975 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE;
2976 *dma_prog++ = 0; /* NULL WORD */
2978 *dma_prog++ = OP_JUMP;
2979 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
2984 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO;
2985 *dma_prog++ = 0; /* NULL WORD */
2986 *dma_prog++ = OP_JUMP; ;
2987 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
2991 if (interlace == 2) {
2993 target_buffer = buffer + pitch;
2995 dma_prog = (u_long *) bktr->odd_dma_prog;
2997 /* sync vre IRQ bit */
2998 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1;
2999 *dma_prog++ = 0; /* NULL WORD */
3001 for (i = 0; i < (rows/interlace); i++) {
3002 target = target_buffer;
3003 if ( notclipped(bktr, i, width)) {
3004 split(bktr, (volatile u_long **) &dma_prog,
3005 bktr->y2 - bktr->y, OP_WRITE,
3006 Bpp, (volatile u_char **) &target, cols);
3008 while(getline(bktr, i)) {
3009 if (bktr->y != bktr->y2 ) {
3010 split(bktr, (volatile u_long **) &dma_prog,
3011 bktr->y2 - bktr->y, OP_WRITE,
3012 Bpp, (volatile u_char **) &target,
3015 if (bktr->yclip != bktr->yclip2 ) {
3016 split(bktr, (volatile u_long **) &dma_prog,
3017 bktr->yclip2 - bktr->yclip, OP_SKIP,
3018 Bpp, (volatile u_char **) &target, cols);
3025 target_buffer += interlace * pitch;
3030 /* sync vre IRQ bit */
3031 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE;
3032 *dma_prog++ = 0; /* NULL WORD */
3033 *dma_prog++ = OP_JUMP ;
3034 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3035 *dma_prog++ = 0; /* NULL WORD */
3043 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3044 int cols, int rows, int interlace )
3047 volatile unsigned int inst;
3048 volatile unsigned int inst3;
3049 volatile u_long target_buffer, buffer;
3050 volatile u_long *dma_prog;
3051 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3054 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3056 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3057 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3059 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3060 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3062 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3063 bktr->capcontrol = 3 << 2 | 3;
3065 dma_prog = (u_long *) bktr->dma_prog;
3067 /* Construct Write */
3069 /* write , sol, eol */
3070 inst = OP_WRITE | OP_SOL | (cols);
3071 /* write , sol, eol */
3072 inst3 = OP_WRITE | OP_EOL | (cols);
3074 if (bktr->video.addr)
3075 target_buffer = (u_long) bktr->video.addr;
3077 target_buffer = (u_long) vtophys(bktr->bigbuf);
3079 buffer = target_buffer;
3081 /* contruct sync : for video packet format */
3082 /* sync, mode indicator packed data */
3083 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3084 *dma_prog++ = 0; /* NULL WORD */
3088 for (i = 0; i < (rows/interlace); i++) {
3090 *dma_prog++ = target_buffer;
3091 *dma_prog++ = inst3;
3092 *dma_prog++ = target_buffer + b;
3093 target_buffer += interlace*(cols * 2);
3099 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
3100 *dma_prog++ = 0; /* NULL WORD */
3102 *dma_prog++ = OP_JUMP;
3103 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3108 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
3109 *dma_prog++ = 0; /* NULL WORD */
3110 *dma_prog++ = OP_JUMP;
3111 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3116 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3117 *dma_prog++ = 0; /* NULL WORD */
3118 *dma_prog++ = OP_JUMP ;
3119 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3123 if (interlace == 2) {
3125 target_buffer = (u_long) buffer + cols*2;
3127 dma_prog = (u_long * ) bktr->odd_dma_prog;
3130 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1;
3131 *dma_prog++ = 0; /* NULL WORD */
3133 for (i = 0; i < (rows/interlace) ; i++) {
3135 *dma_prog++ = target_buffer;
3136 *dma_prog++ = inst3;
3137 *dma_prog++ = target_buffer + b;
3138 target_buffer += interlace * ( cols*2);
3142 /* sync vro IRQ bit */
3143 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3144 *dma_prog++ = 0; /* NULL WORD */
3145 *dma_prog++ = OP_JUMP ;
3146 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3148 *dma_prog++ = OP_JUMP;
3149 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3150 *dma_prog++ = 0; /* NULL WORD */
3158 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3159 int cols, int rows, int interlace ){
3162 volatile unsigned int inst;
3163 volatile u_long target_buffer, t1, buffer;
3164 volatile u_long *dma_prog;
3165 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3167 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3169 dma_prog = (u_long *) bktr->dma_prog;
3171 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3173 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3174 OUTB(bktr, BKTR_OFORM, 0x00);
3176 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3177 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3179 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3180 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3182 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3183 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3184 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ~0x40); /* set chroma comb */
3185 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ~0x40);
3187 /* disable gamma correction removal */
3188 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3190 /* Construct Write */
3191 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3192 if (bktr->video.addr)
3193 target_buffer = (u_long) bktr->video.addr;
3195 target_buffer = (u_long) vtophys(bktr->bigbuf);
3197 buffer = target_buffer;
3201 /* contruct sync : for video packet format */
3202 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3203 *dma_prog++ = 0; /* NULL WORD */
3205 for (i = 0; i < (rows/interlace ) ; i++) {
3207 *dma_prog++ = cols/2 | cols/2 << 16;
3208 *dma_prog++ = target_buffer;
3209 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3210 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3211 target_buffer += interlace*cols;
3216 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3217 *dma_prog++ = 0; /* NULL WORD */
3219 *dma_prog++ = OP_JUMP ;
3220 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3224 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3225 *dma_prog++ = 0; /* NULL WORD */
3227 *dma_prog++ = OP_JUMP;
3228 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3232 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3233 *dma_prog++ = 0; /* NULL WORD */
3235 *dma_prog++ = OP_JUMP ;
3236 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3240 if (interlace == 2) {
3242 dma_prog = (u_long * ) bktr->odd_dma_prog;
3244 target_buffer = (u_long) buffer + cols;
3245 t1 = buffer + cols/2;
3246 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3247 *dma_prog++ = 0; /* NULL WORD */
3249 for (i = 0; i < (rows/interlace ) ; i++) {
3251 *dma_prog++ = cols/2 | cols/2 << 16;
3252 *dma_prog++ = target_buffer;
3253 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3254 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3255 target_buffer += interlace*cols;
3259 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3260 *dma_prog++ = 0; /* NULL WORD */
3261 *dma_prog++ = OP_JUMP ;
3262 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3263 *dma_prog++ = 0; /* NULL WORD */
3271 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3272 int cols, int rows, int interlace ){
3275 volatile unsigned int inst;
3276 volatile unsigned int inst1;
3277 volatile u_long target_buffer, t1, buffer;
3278 volatile u_long *dma_prog;
3279 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3281 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3283 dma_prog = (u_long *) bktr->dma_prog;
3285 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3287 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3288 OUTB(bktr, BKTR_OFORM, 0x0);
3290 /* Construct Write */
3291 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3292 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3293 if (bktr->video.addr)
3294 target_buffer = (u_long) bktr->video.addr;
3296 target_buffer = (u_long) vtophys(bktr->bigbuf);
3298 buffer = target_buffer;
3301 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3302 *dma_prog++ = 0; /* NULL WORD */
3304 for (i = 0; i < (rows/interlace )/2 ; i++) {
3306 *dma_prog++ = cols/2 | (cols/2 << 16);
3307 *dma_prog++ = target_buffer;
3308 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3309 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3310 target_buffer += interlace*cols;
3311 *dma_prog++ = inst1;
3312 *dma_prog++ = cols/2 | (cols/2 << 16);
3313 *dma_prog++ = target_buffer;
3314 target_buffer += interlace*cols;
3320 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3321 *dma_prog++ = 0; /* NULL WORD */
3323 *dma_prog++ = OP_JUMP;
3324 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3328 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3329 *dma_prog++ = 0; /* NULL WORD */
3331 *dma_prog++ = OP_JUMP;
3332 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3336 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3337 *dma_prog++ = 0; /* NULL WORD */
3338 *dma_prog++ = OP_JUMP ;
3339 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3343 if (interlace == 2) {
3345 dma_prog = (u_long * ) bktr->odd_dma_prog;
3347 target_buffer = (u_long) buffer + cols;
3348 t1 = buffer + cols/2;
3349 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3350 *dma_prog++ = 0; /* NULL WORD */
3352 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3354 *dma_prog++ = cols/2 | (cols/2 << 16);
3355 *dma_prog++ = target_buffer;
3356 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3357 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3358 target_buffer += interlace*cols;
3359 *dma_prog++ = inst1;
3360 *dma_prog++ = cols/2 | (cols/2 << 16);
3361 *dma_prog++ = target_buffer;
3362 target_buffer += interlace*cols;
3369 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3370 *dma_prog++ = 0; /* NULL WORD */
3371 *dma_prog++ = OP_JUMP;
3372 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3373 *dma_prog++ = 0; /* NULL WORD */
3382 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3384 int rows, cols, interlace;
3387 struct format_params *fp;
3388 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3391 fp = &format_params[bktr->format_params];
3393 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3395 /* disable FIFO & RISC, leave other bits alone */
3396 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3398 /* set video parameters */
3399 if (bktr->capture_area_enabled)
3400 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3401 / fp->scaled_htotal / bktr->cols) - 4096;
3403 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3404 / fp->scaled_htotal / bktr->cols) - 4096;
3406 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3407 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3408 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3409 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3410 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3412 /* horizontal active */
3414 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3415 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3416 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3417 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3418 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3419 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3420 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3422 /* horizontal delay */
3423 if (bktr->capture_area_enabled)
3424 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3425 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3427 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3429 temp = temp & 0x3fe;
3431 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3432 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3433 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3434 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3435 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3436 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3437 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3439 /* vertical scale */
3441 if (bktr->capture_area_enabled) {
3442 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3443 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3445 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3448 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3451 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3452 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3454 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3457 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3462 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3463 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3464 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3465 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3466 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3467 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3468 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3471 /* vertical active */
3472 if (bktr->capture_area_enabled)
3473 temp = bktr->capture_area_y_size;
3476 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3477 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3478 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3479 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3480 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3481 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3482 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3484 /* vertical delay */
3485 if (bktr->capture_area_enabled)
3486 temp = fp->vdelay + (bktr->capture_area_y_offset);
3489 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3490 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3491 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3492 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3493 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3494 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3495 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3497 /* end of video params */
3499 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3500 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3501 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3503 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3506 /* capture control */
3509 bktr->bktr_cap_ctl =
3510 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3511 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3512 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3516 bktr->bktr_cap_ctl =
3517 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3518 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3519 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3523 bktr->bktr_cap_ctl =
3524 (BT848_CAP_CTL_DITH_FRAME |
3525 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3526 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3527 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3532 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3537 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3539 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3540 /* user, then use the rgb_vbi RISC program. */
3541 /* Otherwise, use the normal rgb RISC program */
3542 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3543 if ( (bktr->vbiflags & VBI_OPEN)
3544 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3545 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3547 bktr->bktr_cap_ctl |=
3548 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3549 bktr->vbiflags |= VBI_CAPTURE;
3550 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3553 rgb_prog(bktr, i_flag, cols, rows, interlace);
3558 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3559 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3560 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3561 | pixfmt_swap_flags( bktr->pixfmt ));
3565 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3566 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3567 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3568 | pixfmt_swap_flags( bktr->pixfmt ));
3572 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3573 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3574 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3575 | pixfmt_swap_flags( bktr->pixfmt ));
3582 /******************************************************************************
3583 * video & video capture specific routines:
3591 start_capture( bktr_ptr_t bktr, unsigned type )
3594 struct format_params *fp;
3596 fp = &format_params[bktr->format_params];
3598 /* If requested, clear out capture buf first */
3599 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3600 bzero((caddr_t)bktr->bigbuf,
3601 (size_t)bktr->rows * bktr->cols * bktr->frames *
3602 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3605 OUTB(bktr, BKTR_DSTATUS, 0);
3606 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3608 bktr->flags |= type;
3609 bktr->flags &= ~METEOR_WANT_MASK;
3610 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3611 case METEOR_ONLY_EVEN_FIELDS:
3612 bktr->flags |= METEOR_WANT_EVEN;
3615 case METEOR_ONLY_ODD_FIELDS:
3616 bktr->flags |= METEOR_WANT_ODD;
3620 bktr->flags |= METEOR_WANT_MASK;
3625 /* TDEC is only valid for continuous captures */
3626 if ( type == METEOR_SINGLE ) {
3627 u_short fps_save = bktr->fps;
3629 set_fps(bktr, fp->frame_rate);
3630 bktr->fps = fps_save;
3633 set_fps(bktr, bktr->fps);
3635 if (bktr->dma_prog_loaded == FALSE) {
3636 build_dma_prog(bktr, i_flag);
3637 bktr->dma_prog_loaded = TRUE;
3641 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3650 set_fps( bktr_ptr_t bktr, u_short fps )
3652 struct format_params *fp;
3655 fp = &format_params[bktr->format_params];
3657 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3658 case METEOR_ONLY_EVEN_FIELDS:
3659 bktr->flags |= METEOR_WANT_EVEN;
3662 case METEOR_ONLY_ODD_FIELDS:
3663 bktr->flags |= METEOR_WANT_ODD;
3667 bktr->flags |= METEOR_WANT_MASK;
3672 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3673 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3676 OUTB(bktr, BKTR_TDEC, 0);
3678 if (fps < fp->frame_rate)
3679 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3681 OUTB(bktr, BKTR_TDEC, 0);
3691 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3692 * achieve the specified swapping.
3693 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3694 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3696 * Note also that for 3Bpp, we may additionally need to do some creative
3697 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3698 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3699 * as one would expect.
3702 static u_int pixfmt_swap_flags( int pixfmt )
3704 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3707 switch ( pf->Bpp ) {
3708 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
3711 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3714 case 4 : if ( pf->swap_bytes )
3715 swapf = pf->swap_shorts ? 0 : WSWAP;
3717 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
3726 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3727 * our pixfmt_table indices.
3730 static int oformat_meteor_to_bt( u_long format )
3733 struct meteor_pixfmt *pf1, *pf2;
3735 /* Find format in compatibility table */
3736 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3737 if ( meteor_pixfmt_table[i].meteor_format == format )
3740 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3742 pf1 = &meteor_pixfmt_table[i].public;
3744 /* Match it with an entry in master pixel format table */
3745 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3746 pf2 = &pixfmt_table[i].public;
3748 if (( pf1->type == pf2->type ) &&
3749 ( pf1->Bpp == pf2->Bpp ) &&
3750 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3751 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3752 ( pf1->swap_shorts == pf2->swap_shorts ))
3755 if ( i >= PIXFMT_TABLE_SIZE )
3761 /******************************************************************************
3766 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3767 #define I2CBITTIME_878 (1 << 7)
3768 #define I2C_READ 0x01
3769 #define I2C_COMMAND (I2CBITTIME | \
3770 BT848_DATA_CTL_I2CSCL | \
3771 BT848_DATA_CTL_I2CSDA)
3773 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3774 BT848_DATA_CTL_I2CSCL | \
3775 BT848_DATA_CTL_I2CSDA)
3777 /* Select between old i2c code and new iicbus / smbus code */
3778 #if defined(BKTR_USE_FREEBSD_SMBUS)
3781 * The hardware interface is actually SMB commands
3784 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3788 if (bktr->id == BROOKTREE_848 ||
3789 bktr->id == BROOKTREE_848A ||
3790 bktr->id == BROOKTREE_849A)
3793 cmd = I2C_COMMAND_878;
3796 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3797 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3800 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3801 (char)(byte1 & 0xff)))
3810 i2cRead( bktr_ptr_t bktr, int addr )
3815 if (bktr->id == BROOKTREE_848 ||
3816 bktr->id == BROOKTREE_848A ||
3817 bktr->id == BROOKTREE_849A)
3820 cmd = I2C_COMMAND_878;
3822 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3825 return ((int)((unsigned char)result));
3828 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3830 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3831 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3832 /* Therefore we need low level control of the i2c bus hardware */
3834 /* Write to the MSP or DPL registers */
3836 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3838 unsigned char addr_l, addr_h, data_h, data_l ;
3840 addr_h = (addr >>8) & 0xff;
3841 addr_l = addr & 0xff;
3842 data_h = (data >>8) & 0xff;
3843 data_l = data & 0xff;
3845 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3847 iicbus_write_byte(IICBUS(bktr), dev, 0);
3848 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3849 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3850 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3851 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3853 iicbus_stop(IICBUS(bktr));
3858 /* Read from the MSP or DPL registers */
3860 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3863 unsigned char addr_l, addr_h, dev_r;
3865 u_char data_read[2];
3867 addr_h = (addr >>8) & 0xff;
3868 addr_l = addr & 0xff;
3871 /* XXX errors ignored */
3872 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3874 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3875 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3876 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3878 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3879 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3880 iicbus_stop(IICBUS(bktr));
3882 data = (data_read[0]<<8) | data_read[1];
3887 /* Reset the MSP or DPL chip */
3888 /* The user can block the reset (which is handy if you initialise the
3889 * MSP and/or DPL audio in another operating system first (eg in Windows)
3892 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3895 #ifndef BKTR_NO_MSP_RESET
3896 /* put into reset mode */
3897 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3898 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3899 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3900 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3901 iicbus_stop(IICBUS(bktr));
3903 /* put back to operational mode */
3904 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3905 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3906 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3907 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3908 iicbus_stop(IICBUS(bktr));
3913 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3916 /* XXX errors ignored */
3917 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3918 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3919 iicbus_stop(IICBUS(bktr));
3924 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3927 * Program the i2c bus directly
3930 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3935 /* clear status bits */
3936 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3938 /* build the command datum */
3939 if (bktr->id == BROOKTREE_848 ||
3940 bktr->id == BROOKTREE_848A ||
3941 bktr->id == BROOKTREE_849A) {
3942 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3944 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3946 if ( byte2 != -1 ) {
3947 data |= ((byte2 & 0xff) << 8);
3948 data |= BT848_DATA_CTL_I2CW3B;
3951 /* write the address and data */
3952 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3954 /* wait for completion */
3955 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3956 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3961 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3973 i2cRead( bktr_ptr_t bktr, int addr )
3977 /* clear status bits */
3978 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3980 /* write the READ address */
3981 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3983 if (bktr->id == BROOKTREE_848 ||
3984 bktr->id == BROOKTREE_848A ||
3985 bktr->id == BROOKTREE_849A) {
3986 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3988 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3991 /* wait for completion */
3992 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3993 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3998 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4002 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4005 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4006 /* bt848 automated i2c bus controller cannot handle */
4007 /* Therefore we need low level control of the i2c bus hardware */
4008 /* Idea for the following functions are from elsewhere in this driver and */
4009 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4012 static void i2c_start( bktr_ptr_t bktr) {
4013 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4014 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4015 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4016 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4019 static void i2c_stop( bktr_ptr_t bktr) {
4020 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4021 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4022 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4025 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4029 /* write out the byte */
4030 for ( x = 7; x >= 0; --x ) {
4031 if ( data & (1<<x) ) {
4032 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4033 DELAY( BITD ); /* assert HI data */
4034 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4035 DELAY( BITD ); /* strobe clock */
4036 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4037 DELAY( BITD ); /* release clock */
4040 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4041 DELAY( BITD ); /* assert LO data */
4042 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4043 DELAY( BITD ); /* strobe clock */
4044 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4045 DELAY( BITD ); /* release clock */
4049 /* look for an ACK */
4050 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4051 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4052 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4053 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4058 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4063 /* read in the byte */
4064 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4065 DELAY( BITD ); /* float data */
4066 for ( x = 7; x >= 0; --x ) {
4067 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4068 DELAY( BITD ); /* strobe clock */
4069 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4070 if ( bit ) byte |= (1<<x);
4071 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4072 DELAY( BITD ); /* release clock */
4074 /* After reading the byte, send an ACK */
4075 /* (unless that was the last byte, for which we send a NAK */
4076 if (last) { /* send NAK - same a writing a 1 */
4077 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4078 DELAY( BITD ); /* set data bit */
4079 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4080 DELAY( BITD ); /* strobe clock */
4081 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4082 DELAY( BITD ); /* release clock */
4083 } else { /* send ACK - same as writing a 0 */
4084 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4085 DELAY( BITD ); /* set data bit */
4086 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4087 DELAY( BITD ); /* strobe clock */
4088 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4089 DELAY( BITD ); /* release clock */
4097 /* Write to the MSP or DPL registers */
4098 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4100 unsigned int msp_w_addr = i2c_addr;
4101 unsigned char addr_l, addr_h, data_h, data_l ;
4102 addr_h = (addr >>8) & 0xff;
4103 addr_l = addr & 0xff;
4104 data_h = (data >>8) & 0xff;
4105 data_l = data & 0xff;
4108 i2c_write_byte(bktr, msp_w_addr);
4109 i2c_write_byte(bktr, dev);
4110 i2c_write_byte(bktr, addr_h);
4111 i2c_write_byte(bktr, addr_l);
4112 i2c_write_byte(bktr, data_h);
4113 i2c_write_byte(bktr, data_l);
4117 /* Read from the MSP or DPL registers */
4118 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4120 unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
4121 addr_h = (addr >>8) & 0xff;
4122 addr_l = addr & 0xff;
4126 i2c_write_byte(bktr,i2c_addr);
4127 i2c_write_byte(bktr,dev_r);
4128 i2c_write_byte(bktr,addr_h);
4129 i2c_write_byte(bktr,addr_l);
4132 i2c_write_byte(bktr,i2c_addr+1);
4133 i2c_read_byte(bktr,&data_1, 0);
4134 i2c_read_byte(bktr,&data_2, 1);
4136 data = (data_1<<8) | data_2;
4140 /* Reset the MSP or DPL chip */
4141 /* The user can block the reset (which is handy if you initialise the
4142 * MSP audio in another operating system first (eg in Windows)
4144 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4146 #ifndef BKTR_NO_MSP_RESET
4147 /* put into reset mode */
4149 i2c_write_byte(bktr, i2c_addr);
4150 i2c_write_byte(bktr, 0x00);
4151 i2c_write_byte(bktr, 0x80);
4152 i2c_write_byte(bktr, 0x00);
4155 /* put back to operational mode */
4157 i2c_write_byte(bktr, i2c_addr);
4158 i2c_write_byte(bktr, 0x00);
4159 i2c_write_byte(bktr, 0x00);
4160 i2c_write_byte(bktr, 0x00);
4167 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4169 /* XXX errors ignored */
4171 i2c_write_byte(bktr,bktr->remote_control_addr);
4172 i2c_read_byte(bktr,&(remote->data[0]), 0);
4173 i2c_read_byte(bktr,&(remote->data[1]), 0);
4174 i2c_read_byte(bktr,&(remote->data[2]), 0);
4180 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4183 #if defined( I2C_SOFTWARE_PROBE )
4186 * we are keeping this around for any parts that we need to probe
4187 * but that CANNOT be probed via an i2c read.
4188 * this is necessary because the hardware i2c mechanism
4189 * cannot be programmed for 1 byte writes.
4190 * currently there are no known i2c parts that we need to probe
4191 * and that cannot be safely read.
4193 static int i2cProbe( bktr_ptr_t bktr, int addr );
4198 * probe for an I2C device at addr.
4201 i2cProbe( bktr_ptr_t bktr, int addr )
4206 #if defined( EXTRA_START )
4207 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4208 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4209 #endif /* EXTRA_START */
4210 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4211 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4214 for ( x = 7; x >= 0; --x ) {
4215 if ( addr & (1<<x) ) {
4216 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4217 DELAY( BITD ); /* assert HI data */
4218 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4219 DELAY( BITD ); /* strobe clock */
4220 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4221 DELAY( BITD ); /* release clock */
4224 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4225 DELAY( BITD ); /* assert LO data */
4226 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4227 DELAY( BITD ); /* strobe clock */
4228 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4229 DELAY( BITD ); /* release clock */
4233 /* look for an ACK */
4234 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4235 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4236 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4237 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4240 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4241 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4242 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4249 #endif /* I2C_SOFTWARE_PROBE */
4254 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */