bktr_core.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-4-Clause 3 * 4 * 1. Redistributions of source code must retain the 5 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Amancio Hasty and 19 * Roger Hardiman 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35/*- 36 * 1. Redistributions of source code must retain the 37 * Copyright (c) 1995 Mark Tinguely and Jim Lowe 38 * All rights reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. All advertising materials mentioning features or use of this software 49 * must display the following acknowledgement: 50 * This product includes software developed by Mark Tinguely and Jim Lowe 51 * 4. The name of the author may not be used to endorse or promote products 52 * derived from this software without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 56 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 57 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 60 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 62 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 63 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 64 * POSSIBILITY OF SUCH DAMAGE. 65 */ 66 67#include <sys/cdefs.h> 68__FBSDID("$FreeBSD: stable/11/sys/dev/bktr/bktr_core.c 330897 2018-03-14 03:19:51Z eadler $"); 69 70/* 71 * This is part of the Driver for Video Capture Cards (Frame grabbers) 72 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 73 * chipset. 74 * Copyright Roger Hardiman and Amancio Hasty. 75 * 76 * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber, 77 * Handles all the open, close, ioctl and read userland calls. 78 * Sets the Bt848 registers and generates RISC pograms. 79 * Controls the i2c bus and GPIO interface. 80 * Contains the interface to the kernel. 81 * (eg probe/attach and open/close/ioctl) 82 */ 83 84 /* 85 The Brooktree BT848 Driver driver is based upon Mark Tinguely and 86 Jim Lowe's driver for the Matrox Meteor PCI card . The 87 Philips SAA 7116 and SAA 7196 are very different chipsets than 88 the BT848. 89 90 The original copyright notice by Mark and Jim is included mostly 91 to honor their fantastic work in the Matrox Meteor driver! 92 */ 93 94#include "opt_bktr.h" /* Include any kernel config options */ 95 96#if ( \ 97 (defined(__FreeBSD__)) \ 98 || (defined(__bsdi__)) \ 99 || (defined(__OpenBSD__)) \ 100 || (defined(__NetBSD__)) \ 101 ) 102 103 104/*******************/ 105/* *** FreeBSD *** */ 106/*******************/ 107#ifdef __FreeBSD__ 108 109#include <sys/param.h> 110#include <sys/systm.h> 111#include <sys/kernel.h> 112#include <sys/fcntl.h> 113#include <sys/lock.h> 114#include <sys/malloc.h> 115#include <sys/mutex.h> 116#include <sys/proc.h> 117#include <sys/signalvar.h> 118#include <sys/selinfo.h> 119#include <sys/uio.h> 120 121#include <vm/vm.h> 122#include <vm/vm_kern.h> 123#include <vm/pmap.h> 124#include <vm/vm_extern.h> 125 126#include <sys/bus.h> /* used by smbus and newbus */ 127 128#if (__FreeBSD_version < 500000) 129#include <machine/clock.h> /* for DELAY */ 130#define PROC_LOCK(p) 131#define PROC_UNLOCK(p) 132#include <pci/pcivar.h> 133#else 134#include <dev/pci/pcivar.h> 135#endif 136 137#include <machine/bus.h> 138#include <sys/bus.h> 139 140#include <dev/bktr/ioctl_meteor.h> 141#include <dev/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 142#include <dev/bktr/bktr_reg.h> 143#include <dev/bktr/bktr_tuner.h> 144#include <dev/bktr/bktr_card.h> 145#include <dev/bktr/bktr_audio.h> 146#include <dev/bktr/bktr_os.h> 147#include <dev/bktr/bktr_core.h> 148#if defined(BKTR_FREEBSD_MODULE) 149#include <dev/bktr/bktr_mem.h> 150#endif 151 152#if defined(BKTR_USE_FREEBSD_SMBUS) 153#include <dev/bktr/bktr_i2c.h> 154#include <dev/smbus/smbconf.h> 155#include <dev/iicbus/iiconf.h> 156#include "smbus_if.h" 157#include "iicbus_if.h" 158#endif 159 160const char * 161bktr_name(bktr_ptr_t bktr) 162{ 163 return bktr->bktr_xname; 164} 165 166 167#endif /* __FreeBSD__ */ 168 169 170/****************/ 171/* *** BSDI *** */ 172/****************/ 173#ifdef __bsdi__ 174#define PROC_LOCK(p) 175#define PROC_UNLOCK(p) 176#endif /* __bsdi__ */ 177 178 179/**************************/ 180/* *** OpenBSD/NetBSD *** */ 181/**************************/ 182#if defined(__NetBSD__) || defined(__OpenBSD__) 183 184#include <sys/param.h> 185#include <sys/systm.h> 186#include <sys/kernel.h> 187#include <sys/signalvar.h> 188#include <sys/vnode.h> 189 190#ifdef __NetBSD__ 191#include <uvm/uvm_extern.h> 192#else 193#include <vm/vm.h> 194#include <vm/vm_kern.h> 195#include <vm/pmap.h> 196#include <vm/vm_extern.h> 197#endif 198 199#include <sys/inttypes.h> /* uintptr_t */ 200#include <dev/ic/bt8xx.h> 201#include <dev/pci/bktr/bktr_reg.h> 202#include <dev/pci/bktr/bktr_tuner.h> 203#include <dev/pci/bktr/bktr_card.h> 204#include <dev/pci/bktr/bktr_audio.h> 205#include <dev/pci/bktr/bktr_core.h> 206#include <dev/pci/bktr/bktr_os.h> 207 208static int bt848_format = -1; 209 210const char * 211bktr_name(bktr_ptr_t bktr) 212{ 213 return (bktr->bktr_dev.dv_xname); 214} 215 216#define PROC_LOCK(p) 217#define PROC_UNLOCK(p) 218 219#endif /* __NetBSD__ || __OpenBSD__ */ 220 221 222typedef u_char bool_t; 223 224#define BKTRPRI (PZERO+8)|PCATCH 225#define VBIPRI (PZERO-4)|PCATCH 226 227 228/* 229 * memory allocated for DMA programs 230 */ 231#define DMA_PROG_ALLOC (8 * PAGE_SIZE) 232 233/* When to split a dma transfer , the bt848 has timing as well as 234 dma transfer size limitations so that we have to split dma 235 transfers into two dma requests 236 */ 237#define DMA_BT848_SPLIT 319*2 238 239/* 240 * Allocate enough memory for: 241 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages 242 * 243 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value" 244 * in your kernel configuration file. 245 */ 246 247#ifndef BROOKTREE_ALLOC_PAGES 248#define BROOKTREE_ALLOC_PAGES 217*4 249#endif 250#define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE) 251 252/* Definitions for VBI capture. 253 * There are 16 VBI lines in a PAL video field (32 in a frame), 254 * and we take 2044 samples from each line (placed in a 2048 byte buffer 255 * for alignment). 256 * VBI lines are held in a circular buffer before being read by a 257 * user program from /dev/vbi. 258 */ 259 260#define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */ 261#define VBI_LINE_SIZE 2048 /* Store up to 2048 bytes per line */ 262#define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */ 263#define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2) 264#define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS) 265 266 267/* Defines for fields */ 268#define ODD_F 0x01 269#define EVEN_F 0x02 270 271 272/* 273 * Parameters describing size of transmitted image. 274 */ 275 276static struct format_params format_params[] = { 277/* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */ 278 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO, 279 12, 1600 }, 280/* # define BT848_IFORM_F_NTSCM (0x1) */ 281 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0, 282 12, 1600 }, 283/* # define BT848_IFORM_F_NTSCJ (0x2) */ 284 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0, 285 12, 1600 }, 286/* # define BT848_IFORM_F_PALBDGHI (0x3) */ 287 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1, 288 16, 2044 }, 289/* # define BT848_IFORM_F_PALM (0x4) */ 290 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0, 291 12, 1600 }, 292/* # define BT848_IFORM_F_PALN (0x5) */ 293 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1, 294 16, 2044 }, 295/* # define BT848_IFORM_F_SECAM (0x6) */ 296 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1, 297 16, 2044 }, 298/* # define BT848_IFORM_F_RSVD (0x7) - ???? */ 299 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0, 300 16, 2044 }, 301}; 302 303/* 304 * Table of supported Pixel Formats 305 */ 306 307static struct meteor_pixfmt_internal { 308 struct meteor_pixfmt public; 309 u_int color_fmt; 310} pixfmt_table[] = { 311 312{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 }, 313{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 }, 314 315{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 }, 316{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 }, 317 318{ { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 }, 319 320{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 }, 321{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 }, 322{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 }, 323{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 }, 324{ { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 }, 325{ { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 }, 326{ { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 }, 327 328}; 329#define PIXFMT_TABLE_SIZE nitems(pixfmt_table) 330 331/* 332 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility) 333 */ 334 335/* FIXME: Also add YUV_422 and YUV_PACKED as well */ 336static struct { 337 u_long meteor_format; 338 struct meteor_pixfmt public; 339} meteor_pixfmt_table[] = { 340 { METEOR_GEO_YUV_12, 341 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 } 342 }, 343 344 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */ 345 { METEOR_GEO_YUV_422, 346 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 } 347 }, 348 { METEOR_GEO_YUV_PACKED, 349 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 } 350 }, 351 { METEOR_GEO_RGB16, 352 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 } 353 }, 354 { METEOR_GEO_RGB24, 355 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 } 356 }, 357 358}; 359#define METEOR_PIXFMT_TABLE_SIZE nitems(meteor_pixfmt_table) 360 361 362#define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN) 363#define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN) 364 365 366 367/* sync detect threshold */ 368#if 0 369#define SYNC_LEVEL (BT848_ADC_RESERVED | \ 370 BT848_ADC_CRUSH) /* threshold ~125 mV */ 371#else 372#define SYNC_LEVEL (BT848_ADC_RESERVED | \ 373 BT848_ADC_SYNC_T) /* threshold ~75 mV */ 374#endif 375 376 377 378 379/* debug utility for holding previous INT_STAT contents */ 380#define STATUS_SUM 381static u_long status_sum = 0; 382 383/* 384 * defines to make certain bit-fiddles understandable 385 */ 386#define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN 387#define RISC_ENABLED BT848_DMA_CTL_RISC_EN 388#define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN) 389#define FIFO_RISC_DISABLED 0 390 391#define ALL_INTS_DISABLED 0 392#define ALL_INTS_CLEARED 0xffffffff 393#define CAPTURE_OFF 0 394 395#define BIT_SEVEN_HIGH (1<<7) 396#define BIT_EIGHT_HIGH (1<<8) 397 398#define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE) 399#define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS) 400 401 402 403static int oformat_meteor_to_bt( u_long format ); 404 405static u_int pixfmt_swap_flags( int pixfmt ); 406 407/* 408 * bt848 RISC programming routines. 409 */ 410#ifdef BT848_DUMP 411static int dump_bt848( bktr_ptr_t bktr ); 412#endif 413 414static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols, 415 int rows, int interlace ); 416static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols, 417 int rows, int interlace ); 418static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols, 419 int rows, int interlace ); 420static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, 421 int rows, int interlace ); 422static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, 423 int rows, int interlace ); 424static void build_dma_prog( bktr_ptr_t bktr, char i_flag ); 425 426static bool_t getline(bktr_reg_t *, int); 427static bool_t notclipped(bktr_reg_t * , int , int); 428static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int, 429 volatile u_char ** , int ); 430 431static void start_capture( bktr_ptr_t bktr, unsigned type ); 432static void set_fps( bktr_ptr_t bktr, u_short fps ); 433 434 435 436/* 437 * Remote Control Functions 438 */ 439static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote); 440 441 442/* 443 * ioctls common to both video & tuner. 444 */ 445static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg ); 446 447 448#if !defined(BKTR_USE_FREEBSD_SMBUS) 449/* 450 * i2c primitives for low level control of i2c bus. Added for MSP34xx control 451 */ 452static void i2c_start( bktr_ptr_t bktr); 453static void i2c_stop( bktr_ptr_t bktr); 454static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data); 455static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ); 456#endif 457 458 459 460/* 461 * the common attach code, used by all OS versions. 462 */ 463void 464common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ) 465{ 466 vm_offset_t buf = 0; 467 int need_to_allocate_memory = 1; 468#ifdef BKTR_NEW_MSP34XX_DRIVER 469 int err; 470#endif 471 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, 478 DMA_PROG_ALLOC); 479 bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog, 480 DMA_PROG_ALLOC); 481 482 /* allocate space for the VBI buffer */ 483 bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata, 484 VBI_DATA_SIZE); 485 bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer, 486 VBI_BUFFER_SIZE); 487 488 /* allocate space for pixel buffer */ 489 if ( BROOKTREE_ALLOC ) 490 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC); 491 else 492 buf = 0; 493#endif 494 495#if defined(__FreeBSD__) || defined(__bsdi__) 496 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; 507 } 508#endif 509 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); 514 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); 518 519 /* allocate space for pixel buffer */ 520 if ( BROOKTREE_ALLOC ) 521 buf = get_bktr_mem(unit, BROOKTREE_ALLOC); 522 else 523 buf = 0; 524 } 525#endif /* FreeBSD or BSDi */ 526 527#ifdef USE_VBIMUTEX 528 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF); 529#endif 530 531/* If this is a module, save the current contiguous memory */ 532#if defined(BKTR_FREEBSD_MODULE) 533bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog); 534bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog); 535bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata); 536bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer); 537bktr_store_address(unit, BKTR_MEM_BUF, buf); 538#endif 539 540 541 if ( bootverbose ) { 542 printf("%s: buffer size %d, addr %p\n", 543 bktr_name(bktr), (int)BROOKTREE_ALLOC, 544 (void *)(uintptr_t)vtophys(buf)); 545 } 546 547 if ( buf != 0 ) { 548 bktr->bigbuf = buf; 549 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES; 550 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC); 551 } else { 552 bktr->alloc_pages = 0; 553 } 554 555 556 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE | 557 METEOR_DEV0 | METEOR_RGB16; 558 bktr->dma_prog_loaded = FALSE; 559 bktr->cols = 640; 560 bktr->rows = 480; 561 bktr->frames = 1; /* one frame */ 562 bktr->format = METEOR_GEO_RGB16; 563 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 564 bktr->pixfmt_compat = TRUE; 565 566 567 bktr->vbiinsert = 0; 568 bktr->vbistart = 0; 569 bktr->vbisize = 0; 570 bktr->vbiflags = 0; 571 572 573 /* using the pci device id and revision id */ 574 /* and determine the card type */ 575 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE) 576 { 577 switch (PCI_PRODUCT(pci_id)) { 578 case PCI_PRODUCT_BROOKTREE_BT848: 579 if (rev == 0x12) 580 bktr->id = BROOKTREE_848A; 581 else 582 bktr->id = BROOKTREE_848; 583 break; 584 case PCI_PRODUCT_BROOKTREE_BT849: 585 bktr->id = BROOKTREE_849A; 586 break; 587 case PCI_PRODUCT_BROOKTREE_BT878: 588 bktr->id = BROOKTREE_878; 589 break; 590 case PCI_PRODUCT_BROOKTREE_BT879: 591 bktr->id = BROOKTREE_879; 592 break; 593 } 594 } 595 596 bktr->clr_on_start = FALSE; 597 598 /* defaults for the tuner section of the card */ 599 bktr->tflags = TUNER_INITALIZED; 600 bktr->tuner.frequency = 0; 601 bktr->tuner.channel = 0; 602 bktr->tuner.chnlset = DEFAULT_CHNLSET; 603 bktr->tuner.afc = 0; 604 bktr->tuner.radio_mode = 0; 605 bktr->audio_mux_select = 0; 606 bktr->audio_mute_state = FALSE; 607 bktr->bt848_card = -1; 608 bktr->bt848_tuner = -1; 609 bktr->reverse_mute = -1; 610 bktr->slow_msp_audio = 0; 611 bktr->msp_use_mono_source = 0; 612 bktr->msp_source_selected = -1; 613 bktr->audio_mux_present = 1; 614 615#if defined(__FreeBSD__) 616#ifdef BKTR_NEW_MSP34XX_DRIVER 617 /* get hint on short programming of the msp34xx, so we know */ 618 /* if the decision what thread to start should be overwritten */ 619 if ( (err = resource_int_value("bktr", unit, "mspsimple", 620 &(bktr->mspsimple)) ) != 0 ) 621 bktr->mspsimple = -1; /* fall back to default */ 622#endif 623#endif 624 625 probeCard( bktr, TRUE, unit ); 626 627 /* Initialise any MSP34xx or TDA98xx audio chips */ 628 init_audio_devices( bktr ); 629 630#ifdef BKTR_NEW_MSP34XX_DRIVER 631 /* setup the kernel thread */ 632 err = msp_attach( bktr ); 633 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */ 634 bktr->card.msp3400c = 0; 635#endif 636 637 638} 639 640 641/* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'. 642 * The circular buffer holds 'n' fixed size data blocks. 643 * vbisize is the number of bytes in the circular buffer 644 * vbiread is the point we reading data out of the circular buffer 645 * vbiinsert is the point we insert data into the circular buffer 646 */ 647static void vbidecode(bktr_ptr_t bktr) { 648 unsigned char *dest; 649 unsigned int *seq_dest; 650 651 /* Check if there is room in the buffer to insert the data. */ 652 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return; 653 654 /* Copy the VBI data into the next free slot in the buffer. */ 655 /* 'dest' is the point in vbibuffer where we want to insert new data */ 656 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert; 657 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE); 658 659 /* Write the VBI sequence number to the end of the vbi data */ 660 /* This is used by the AleVT teletext program */ 661 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer 662 + bktr->vbiinsert 663 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number))); 664 *seq_dest = bktr->vbi_sequence_number; 665 666 /* And increase the VBI sequence number */ 667 /* This can wrap around */ 668 bktr->vbi_sequence_number++; 669 670 671 /* Increment the vbiinsert pointer */ 672 /* This can wrap around */ 673 bktr->vbiinsert += VBI_DATA_SIZE; 674 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE); 675 676 /* And increase the amount of vbi data in the buffer */ 677 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE; 678 679} 680 681 682/* 683 * the common interrupt handler. 684 * Returns a 0 or 1 depending on whether the interrupt has handled. 685 * In the OS specific section, bktr_intr() is defined which calls this 686 * common interrupt handler. 687 */ 688int 689common_bktr_intr( void *arg ) 690{ 691 bktr_ptr_t bktr; 692 u_long bktr_status; 693 u_char dstatus; 694 u_long field; 695 u_long w_field; 696 u_long req_field; 697 698 bktr = (bktr_ptr_t) arg; 699 700 /* 701 * check to see if any interrupts are unmasked on this device. If 702 * none are, then we likely got here by way of being on a PCI shared 703 * interrupt dispatch list. 704 */ 705 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED) 706 return 0; /* bail out now, before we do something we 707 shouldn't */ 708 709 if (!(bktr->flags & METEOR_OPEN)) { 710 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 711 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 712 /* return; ?? */ 713 } 714 715 /* record and clear the INTerrupt status bits */ 716 bktr_status = INL(bktr, BKTR_INT_STAT); 717 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */ 718 719 /* record and clear the device status register */ 720 dstatus = INB(bktr, BKTR_DSTATUS); 721 OUTB(bktr, BKTR_DSTATUS, 0x00); 722 723#if defined( STATUS_SUM ) 724 /* add any new device status or INTerrupt status bits */ 725 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1)); 726 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6); 727#endif /* STATUS_SUM */ 728 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr), 729 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) ); 730 */ 731 732 733 /* if risc was disabled re-start process again */ 734 /* if there was one of the following errors re-start again */ 735 if ( !(bktr_status & BT848_INT_RISC_EN) || 736 ((bktr_status &(/* BT848_INT_FBUS | */ 737 /* BT848_INT_FTRGT | */ 738 /* BT848_INT_FDSR | */ 739 BT848_INT_PPERR | 740 BT848_INT_RIPERR | BT848_INT_PABORT | 741 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0) 742 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) { 743 744 u_short tdec_save = INB(bktr, BKTR_TDEC); 745 746 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 747 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 748 749 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 750 751 /* Reset temporal decimation counter */ 752 OUTB(bktr, BKTR_TDEC, 0); 753 OUTB(bktr, BKTR_TDEC, tdec_save); 754 755 /* Reset to no-fields captured state */ 756 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 757 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 758 case METEOR_ONLY_ODD_FIELDS: 759 bktr->flags |= METEOR_WANT_ODD; 760 break; 761 case METEOR_ONLY_EVEN_FIELDS: 762 bktr->flags |= METEOR_WANT_EVEN; 763 break; 764 default: 765 bktr->flags |= METEOR_WANT_MASK; 766 break; 767 } 768 } 769 770 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog)); 771 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 772 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 773 774 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 775 BT848_INT_RISCI | 776 BT848_INT_VSYNC | 777 BT848_INT_FMTCHG); 778 779 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 780 return 1; 781 } 782 783 /* If this is not a RISC program interrupt, return */ 784 if (!(bktr_status & BT848_INT_RISCI)) 785 return 0; 786 787/** 788 printf( "%s: intr status %x %x %x\n", bktr_name(bktr), 789 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) ); 790 */ 791 792 793 /* 794 * Disable future interrupts if a capture mode is not selected. 795 * This can happen when we are in the process of closing or 796 * changing capture modes, otherwise it shouldn't happen. 797 */ 798 if (!(bktr->flags & METEOR_CAP_MASK)) 799 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 800 801 802 /* Determine which field generated this interrupt */ 803 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F; 804 805 806 /* 807 * Process the VBI data if it is being captured. We do this once 808 * both Odd and Even VBI data is captured. Therefore we do this 809 * in the Even field interrupt handler. 810 */ 811 LOCK_VBI(bktr); 812 if ( (bktr->vbiflags & VBI_CAPTURE) 813 &&(bktr->vbiflags & VBI_OPEN) 814 &&(field==EVEN_F)) { 815 /* Put VBI data into circular buffer */ 816 vbidecode(bktr); 817 818 /* If someone is blocked on reading from /dev/vbi, wake them */ 819 if (bktr->vbi_read_blocked) { 820 bktr->vbi_read_blocked = FALSE; 821 wakeup(VBI_SLEEP); 822 } 823 824 /* If someone has a select() on /dev/vbi, inform them */ 825 if (SEL_WAITING(&bktr->vbi_select)) { 826 selwakeuppri(&bktr->vbi_select, VBIPRI); 827 } 828 829 830 } 831 UNLOCK_VBI(bktr); 832 833 /* 834 * Register the completed field 835 * (For dual-field mode, require fields from the same frame) 836 */ 837 switch ( bktr->flags & METEOR_WANT_MASK ) { 838 case METEOR_WANT_ODD : w_field = ODD_F ; break; 839 case METEOR_WANT_EVEN : w_field = EVEN_F ; break; 840 default : w_field = (ODD_F|EVEN_F); break; 841 } 842 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) { 843 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break; 844 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break; 845 default : req_field = (ODD_F|EVEN_F); 846 break; 847 } 848 849 if (( field == EVEN_F ) && ( w_field == EVEN_F )) 850 bktr->flags &= ~METEOR_WANT_EVEN; 851 else if (( field == ODD_F ) && ( req_field == ODD_F ) && 852 ( w_field == ODD_F )) 853 bktr->flags &= ~METEOR_WANT_ODD; 854 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) && 855 ( w_field == (ODD_F|EVEN_F) )) 856 bktr->flags &= ~METEOR_WANT_ODD; 857 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) && 858 ( w_field == ODD_F )) { 859 bktr->flags &= ~METEOR_WANT_ODD; 860 bktr->flags |= METEOR_WANT_EVEN; 861 } 862 else { 863 /* We're out of sync. Start over. */ 864 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 865 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 866 case METEOR_ONLY_ODD_FIELDS: 867 bktr->flags |= METEOR_WANT_ODD; 868 break; 869 case METEOR_ONLY_EVEN_FIELDS: 870 bktr->flags |= METEOR_WANT_EVEN; 871 break; 872 default: 873 bktr->flags |= METEOR_WANT_MASK; 874 break; 875 } 876 } 877 return 1; 878 } 879 880 /* 881 * If we have a complete frame. 882 */ 883 if (!(bktr->flags & METEOR_WANT_MASK)) { 884 bktr->frames_captured++; 885 /* 886 * post the completion time. 887 */ 888 if (bktr->flags & METEOR_WANT_TS) { 889 struct timeval *ts; 890 891 if ((u_int) bktr->alloc_pages * PAGE_SIZE 892 <= (bktr->frame_size + sizeof(struct timeval))) { 893 ts =(struct timeval *)bktr->bigbuf + 894 bktr->frame_size; 895 /* doesn't work in synch mode except 896 * for first frame */ 897 /* XXX */ 898 microtime(ts); 899 } 900 } 901 902 903 /* 904 * Wake up the user in single capture mode. 905 */ 906 if (bktr->flags & METEOR_SINGLE) { 907 908 /* stop dma */ 909 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 910 911 /* disable risc, leave fifo running */ 912 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 913 wakeup(BKTR_SLEEP); 914 } 915 916 /* 917 * If the user requested to be notified via signal, 918 * let them know the frame is complete. 919 */ 920 921 if (bktr->proc != NULL) { 922 PROC_LOCK(bktr->proc); 923 kern_psignal( bktr->proc, bktr->signal); 924 PROC_UNLOCK(bktr->proc); 925 } 926 927 /* 928 * Reset the want flags if in continuous or 929 * synchronous capture mode. 930 */ 931/* 932* XXX NOTE (Luigi): 933* currently we only support 3 capture modes: odd only, even only, 934* odd+even interlaced (odd field first). A fourth mode (non interlaced, 935* either even OR odd) could provide 60 (50 for PAL) pictures per 936* second, but it would require this routine to toggle the desired frame 937* each time, and one more different DMA program for the Bt848. 938* As a consequence, this fourth mode is currently unsupported. 939*/ 940 941 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 942 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 943 case METEOR_ONLY_ODD_FIELDS: 944 bktr->flags |= METEOR_WANT_ODD; 945 break; 946 case METEOR_ONLY_EVEN_FIELDS: 947 bktr->flags |= METEOR_WANT_EVEN; 948 break; 949 default: 950 bktr->flags |= METEOR_WANT_MASK; 951 break; 952 } 953 } 954 } 955 956 return 1; 957} 958 959 960 961 962/* 963 * 964 */ 965extern int bt848_format; /* used to set the default format, PAL or NTSC */ 966int 967video_open( bktr_ptr_t bktr ) 968{ 969 int frame_rate, video_format=0; 970 971 if (bktr->flags & METEOR_OPEN) /* device is busy */ 972 return( EBUSY ); 973 974 bktr->flags |= METEOR_OPEN; 975 976#ifdef BT848_DUMP 977 dump_bt848( bt848 ); 978#endif 979 980 bktr->clr_on_start = FALSE; 981 982 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */ 983 984 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 985 986#if defined(BKTR_SYSTEM_DEFAULT) && BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL 987 video_format = 0; 988#else 989 video_format = 1; 990#endif 991 992 if (bt848_format == 0 ) 993 video_format = 0; 994 995 if (bt848_format == 1 ) 996 video_format = 1; 997 998 if (video_format == 1 ) { 999 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM); 1000 bktr->format_params = BT848_IFORM_F_NTSCM; 1001 1002 } else { 1003 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI); 1004 bktr->format_params = BT848_IFORM_F_PALBDGHI; 1005 1006 } 1007 1008 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel); 1009 1010 /* work around for new Hauppauge 878 cards */ 1011 if ((bktr->card.card_id == CARD_HAUPPAUGE) && 1012 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) ) 1013 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3); 1014 else 1015 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1); 1016 1017 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay); 1018 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay); 1019 frame_rate = format_params[bktr->format_params].frame_rate; 1020 1021 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */ 1022 if (bktr->xtal_pll_mode == BT848_USE_PLL) { 1023 OUTB(bktr, BKTR_TGCTRL, 0); 1024 OUTB(bktr, BKTR_PLL_F_LO, 0xf9); 1025 OUTB(bktr, BKTR_PLL_F_HI, 0xdc); 1026 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e); 1027 } 1028 1029 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0; 1030 1031 bktr->max_clip_node = 0; 1032 1033 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED); 1034 1035 OUTB(bktr, BKTR_E_HSCALE_LO, 170); 1036 OUTB(bktr, BKTR_O_HSCALE_LO, 170); 1037 1038 OUTB(bktr, BKTR_E_DELAY_LO, 0x72); 1039 OUTB(bktr, BKTR_O_DELAY_LO, 0x72); 1040 OUTB(bktr, BKTR_E_SCLOOP, 0); 1041 OUTB(bktr, BKTR_O_SCLOOP, 0); 1042 1043 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0); 1044 OUTB(bktr, BKTR_VBI_PACK_DEL, 0); 1045 1046 bktr->fifo_errors = 0; 1047 bktr->dma_errors = 0; 1048 bktr->frames_captured = 0; 1049 bktr->even_fields_captured = 0; 1050 bktr->odd_fields_captured = 0; 1051 bktr->proc = NULL; 1052 set_fps(bktr, frame_rate); 1053 bktr->video.addr = 0; 1054 bktr->video.width = 0; 1055 bktr->video.banksize = 0; 1056 bktr->video.ramsize = 0; 1057 bktr->pixfmt_compat = TRUE; 1058 bktr->format = METEOR_GEO_RGB16; 1059 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 1060 1061 bktr->capture_area_enabled = FALSE; 1062 1063 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton 1064 based motherboards will 1065 operate unreliably */ 1066 return( 0 ); 1067} 1068 1069int 1070vbi_open( bktr_ptr_t bktr ) 1071{ 1072 1073 LOCK_VBI(bktr); 1074 1075 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */ 1076 UNLOCK_VBI(bktr); 1077 return( EBUSY ); 1078 } 1079 1080 bktr->vbiflags |= VBI_OPEN; 1081 1082 /* reset the VBI circular buffer pointers and clear the buffers */ 1083 bktr->vbiinsert = 0; 1084 bktr->vbistart = 0; 1085 bktr->vbisize = 0; 1086 bktr->vbi_sequence_number = 0; 1087 bktr->vbi_read_blocked = FALSE; 1088 1089 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE); 1090 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE); 1091 1092 UNLOCK_VBI(bktr); 1093 1094 return( 0 ); 1095} 1096 1097/* 1098 * 1099 */ 1100int 1101tuner_open( bktr_ptr_t bktr ) 1102{ 1103 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */ 1104 return( ENXIO ); 1105 1106 if ( bktr->tflags & TUNER_OPEN ) /* already open */ 1107 return( 0 ); 1108 1109 bktr->tflags |= TUNER_OPEN; 1110 bktr->tuner.frequency = 0; 1111 bktr->tuner.channel = 0; 1112 bktr->tuner.chnlset = DEFAULT_CHNLSET; 1113 bktr->tuner.afc = 0; 1114 bktr->tuner.radio_mode = 0; 1115 1116 /* enable drivers on the GPIO port that control the MUXes */ 1117 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits); 1118 1119 /* unmute the audio stream */ 1120 set_audio( bktr, AUDIO_UNMUTE ); 1121 1122 /* Initialise any audio chips, eg MSP34xx or TDA98xx */ 1123 init_audio_devices( bktr ); 1124 1125 return( 0 ); 1126} 1127 1128 1129 1130 1131/* 1132 * 1133 */ 1134int 1135video_close( bktr_ptr_t bktr ) 1136{ 1137 bktr->flags &= ~(METEOR_OPEN | 1138 METEOR_SINGLE | 1139 METEOR_CAP_MASK | 1140 METEOR_WANT_MASK); 1141 1142 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 1143 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 1144 1145 bktr->dma_prog_loaded = FALSE; 1146 OUTB(bktr, BKTR_TDEC, 0); 1147 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1148 1149/** FIXME: is 0xf magic, wouldn't 0x00 work ??? */ 1150 OUTL(bktr, BKTR_SRESET, 0xf); 1151 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 1152 1153 return( 0 ); 1154} 1155 1156 1157/* 1158 * tuner close handle, 1159 * place holder for tuner specific operations on a close. 1160 */ 1161int 1162tuner_close( bktr_ptr_t bktr ) 1163{ 1164 bktr->tflags &= ~TUNER_OPEN; 1165 1166 /* mute the audio by switching the mux */ 1167 set_audio( bktr, AUDIO_MUTE ); 1168 1169 /* disable drivers on the GPIO port that control the MUXes */ 1170 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits); 1171 1172 return( 0 ); 1173} 1174 1175int 1176vbi_close( bktr_ptr_t bktr ) 1177{ 1178 1179 LOCK_VBI(bktr); 1180 1181 bktr->vbiflags &= ~VBI_OPEN; 1182 1183 UNLOCK_VBI(bktr); 1184 1185 return( 0 ); 1186} 1187 1188/* 1189 * 1190 */ 1191int 1192video_read(bktr_ptr_t bktr, int unit, struct cdev *dev, struct uio *uio) 1193{ 1194 int status; 1195 int count; 1196 1197 1198 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */ 1199 return( ENOMEM ); 1200 1201 if (bktr->flags & METEOR_CAP_MASK) 1202 return( EIO ); /* already capturing */ 1203 1204 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 1205 1206 1207 count = bktr->rows * bktr->cols * 1208 pixfmt_table[ bktr->pixfmt ].public.Bpp; 1209 1210 if ((int) uio->uio_iov->iov_len < count) 1211 return( EINVAL ); 1212 1213 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK); 1214 1215 /* capture one frame */ 1216 start_capture(bktr, METEOR_SINGLE); 1217 /* wait for capture to complete */ 1218 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 1219 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1220 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1221 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1222 BT848_INT_RISCI | 1223 BT848_INT_VSYNC | 1224 BT848_INT_FMTCHG); 1225 1226 1227 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0); 1228 if (!status) /* successful capture */ 1229 status = uiomove((caddr_t)bktr->bigbuf, count, uio); 1230 else 1231 printf ("%s: read: tsleep error %d\n", 1232 bktr_name(bktr), status); 1233 1234 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK); 1235 1236 return( status ); 1237} 1238 1239/* 1240 * Read VBI data from the vbi circular buffer 1241 * The buffer holds vbi data blocks which are the same size 1242 * vbiinsert is the position we will insert the next item into the buffer 1243 * vbistart is the actual position in the buffer we want to read from 1244 * vbisize is the exact number of bytes in the buffer left to read 1245 */ 1246int 1247vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag) 1248{ 1249 int readsize, readsize2, start; 1250 int status; 1251 1252 /* 1253 * XXX - vbi_read() should be protected against being re-entered 1254 * while it is unlocked for the uiomove. 1255 */ 1256 LOCK_VBI(bktr); 1257 1258 while(bktr->vbisize == 0) { 1259 if (ioflag & FNDELAY) { 1260 status = EWOULDBLOCK; 1261 goto out; 1262 } 1263 1264 bktr->vbi_read_blocked = TRUE; 1265#ifdef USE_VBIMUTEX 1266 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi", 1267 0))) { 1268 goto out; 1269 } 1270#else 1271 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) { 1272 goto out; 1273 } 1274#endif 1275 } 1276 1277 /* Now we have some data to give to the user */ 1278 1279 /* We cannot read more bytes than there are in 1280 * the circular buffer 1281 */ 1282 readsize = (int)uio->uio_iov->iov_len; 1283 1284 if (readsize > bktr->vbisize) readsize = bktr->vbisize; 1285 1286 /* Check if we can read this number of bytes without having 1287 * to wrap around the circular buffer */ 1288 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) { 1289 /* We need to wrap around */ 1290 1291 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart; 1292 start = bktr->vbistart; 1293 UNLOCK_VBI(bktr); 1294 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio); 1295 if (status == 0) 1296 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio); 1297 } else { 1298 UNLOCK_VBI(bktr); 1299 /* We do not need to wrap around */ 1300 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio); 1301 } 1302 1303 LOCK_VBI(bktr); 1304 1305 /* Update the number of bytes left to read */ 1306 bktr->vbisize -= readsize; 1307 1308 /* Update vbistart */ 1309 bktr->vbistart += readsize; 1310 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */ 1311 1312out: 1313 UNLOCK_VBI(bktr); 1314 1315 return( status ); 1316 1317} 1318 1319 1320 1321/* 1322 * video ioctls 1323 */ 1324int 1325video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td ) 1326{ 1327 volatile u_char c_temp; 1328 unsigned int temp; 1329 unsigned int temp_iform; 1330 unsigned int error; 1331 struct meteor_geomet *geo; 1332 struct meteor_counts *counts; 1333 struct meteor_video *video; 1334 struct bktr_capture_area *cap_area; 1335 vm_offset_t buf; 1336 int i; 1337 int sig; 1338 char char_temp; 1339 1340 switch ( cmd ) { 1341 1342 case BT848SCLIP: /* set clip region */ 1343 bktr->max_clip_node = 0; 1344 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list)); 1345 1346 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) { 1347 if (bktr->clip_list[i].y_min == 0 && 1348 bktr->clip_list[i].y_max == 0) 1349 break; 1350 } 1351 bktr->max_clip_node = i; 1352 1353 /* make sure that the list contains a valid clip secquence */ 1354 /* the clip rectangles should be sorted by x then by y as the 1355 second order sort key */ 1356 1357 /* clip rectangle list is terminated by y_min and y_max set to 0 */ 1358 1359 /* to disable clipping set y_min and y_max to 0 in the first 1360 clip rectangle . The first clip rectangle is clip_list[0]. 1361 */ 1362 1363 1364 1365 if (bktr->max_clip_node == 0 && 1366 (bktr->clip_list[0].y_min != 0 && 1367 bktr->clip_list[0].y_max != 0)) { 1368 return EINVAL; 1369 } 1370 1371 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) { 1372 if (bktr->clip_list[i].y_min == 0 && 1373 bktr->clip_list[i].y_max == 0) { 1374 break; 1375 } 1376 if ( bktr->clip_list[i+1].y_min != 0 && 1377 bktr->clip_list[i+1].y_max != 0 && 1378 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) { 1379 1380 bktr->max_clip_node = 0; 1381 return (EINVAL); 1382 1383 } 1384 1385 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max || 1386 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max || 1387 bktr->clip_list[i].x_min < 0 || 1388 bktr->clip_list[i].x_max < 0 || 1389 bktr->clip_list[i].y_min < 0 || 1390 bktr->clip_list[i].y_max < 0 ) { 1391 bktr->max_clip_node = 0; 1392 return (EINVAL); 1393 } 1394 } 1395 1396 bktr->dma_prog_loaded = FALSE; 1397 1398 break; 1399 1400 case METEORSTATUS: /* get Bt848 status */ 1401 c_temp = INB(bktr, BKTR_DSTATUS); 1402 temp = 0; 1403 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK; 1404 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT; 1405 *(u_short *)arg = temp; 1406 break; 1407 1408 case BT848SFMT: /* set input format */ 1409 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT; 1410 temp_iform = INB(bktr, BKTR_IFORM); 1411 temp_iform &= ~BT848_IFORM_FORMAT; 1412 temp_iform &= ~BT848_IFORM_XTSEL; 1413 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel)); 1414 switch( temp ) { 1415 case BT848_IFORM_F_AUTO: 1416 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1417 METEOR_AUTOMODE; 1418 break; 1419 1420 case BT848_IFORM_F_NTSCM: 1421 case BT848_IFORM_F_NTSCJ: 1422 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1423 METEOR_NTSC; 1424 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay); 1425 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay); 1426 bktr->format_params = temp; 1427 break; 1428 1429 case BT848_IFORM_F_PALBDGHI: 1430 case BT848_IFORM_F_PALN: 1431 case BT848_IFORM_F_SECAM: 1432 case BT848_IFORM_F_RSVD: 1433 case BT848_IFORM_F_PALM: 1434 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1435 METEOR_PAL; 1436 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay); 1437 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay); 1438 bktr->format_params = temp; 1439 break; 1440 1441 } 1442 bktr->dma_prog_loaded = FALSE; 1443 break; 1444 1445 case METEORSFMT: /* set input format */ 1446 temp_iform = INB(bktr, BKTR_IFORM); 1447 temp_iform &= ~BT848_IFORM_FORMAT; 1448 temp_iform &= ~BT848_IFORM_XTSEL; 1449 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) { 1450 case 0: /* default */ 1451 case METEOR_FMT_NTSC: 1452 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1453 METEOR_NTSC; 1454 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM | 1455 format_params[BT848_IFORM_F_NTSCM].iform_xtsel); 1456 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay); 1457 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay); 1458 bktr->format_params = BT848_IFORM_F_NTSCM; 1459 break; 1460 1461 case METEOR_FMT_PAL: 1462 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1463 METEOR_PAL; 1464 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI | 1465 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel); 1466 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay); 1467 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay); 1468 bktr->format_params = BT848_IFORM_F_PALBDGHI; 1469 break; 1470 1471 case METEOR_FMT_AUTOMODE: 1472 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1473 METEOR_AUTOMODE; 1474 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO | 1475 format_params[BT848_IFORM_F_AUTO].iform_xtsel); 1476 break; 1477 1478 default: 1479 return( EINVAL ); 1480 } 1481 bktr->dma_prog_loaded = FALSE; 1482 break; 1483 1484 case METEORGFMT: /* get input format */ 1485 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK; 1486 break; 1487 1488 1489 case BT848GFMT: /* get input format */ 1490 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT; 1491 break; 1492 1493 case METEORSCOUNT: /* (re)set error counts */ 1494 counts = (struct meteor_counts *) arg; 1495 bktr->fifo_errors = counts->fifo_errors; 1496 bktr->dma_errors = counts->dma_errors; 1497 bktr->frames_captured = counts->frames_captured; 1498 bktr->even_fields_captured = counts->even_fields_captured; 1499 bktr->odd_fields_captured = counts->odd_fields_captured; 1500 break; 1501 1502 case METEORGCOUNT: /* get error counts */ 1503 counts = (struct meteor_counts *) arg; 1504 counts->fifo_errors = bktr->fifo_errors; 1505 counts->dma_errors = bktr->dma_errors; 1506 counts->frames_captured = bktr->frames_captured; 1507 counts->even_fields_captured = bktr->even_fields_captured; 1508 counts->odd_fields_captured = bktr->odd_fields_captured; 1509 break; 1510 1511 case METEORGVIDEO: 1512 video = (struct meteor_video *)arg; 1513 video->addr = bktr->video.addr; 1514 video->width = bktr->video.width; 1515 video->banksize = bktr->video.banksize; 1516 video->ramsize = bktr->video.ramsize; 1517 break; 1518 1519 case METEORSVIDEO: 1520 video = (struct meteor_video *)arg; 1521 bktr->video.addr = video->addr; 1522 bktr->video.width = video->width; 1523 bktr->video.banksize = video->banksize; 1524 bktr->video.ramsize = video->ramsize; 1525 break; 1526 1527 case METEORSFPS: 1528 set_fps(bktr, *(u_short *)arg); 1529 break; 1530 1531 case METEORGFPS: 1532 *(u_short *)arg = bktr->fps; 1533 break; 1534 1535 case METEORSHUE: /* set hue */ 1536 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff); 1537 break; 1538 1539 case METEORGHUE: /* get hue */ 1540 *(u_char *)arg = INB(bktr, BKTR_HUE); 1541 break; 1542 1543 case METEORSBRIG: /* set brightness */ 1544 char_temp = ( *(u_char *)arg & 0xff) - 128; 1545 OUTB(bktr, BKTR_BRIGHT, char_temp); 1546 1547 break; 1548 1549 case METEORGBRIG: /* get brightness */ 1550 *(u_char *)arg = INB(bktr, BKTR_BRIGHT); 1551 break; 1552 1553 case METEORSCSAT: /* set chroma saturation */ 1554 temp = (int)*(u_char *)arg; 1555 1556 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff); 1557 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff); 1558 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) 1559 & ~(BT848_E_CONTROL_SAT_U_MSB 1560 | BT848_E_CONTROL_SAT_V_MSB)); 1561 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) 1562 & ~(BT848_O_CONTROL_SAT_U_MSB | 1563 BT848_O_CONTROL_SAT_V_MSB)); 1564 1565 if ( temp & BIT_SEVEN_HIGH ) { 1566 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) 1567 | (BT848_E_CONTROL_SAT_U_MSB 1568 | BT848_E_CONTROL_SAT_V_MSB)); 1569 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) 1570 | (BT848_O_CONTROL_SAT_U_MSB 1571 | BT848_O_CONTROL_SAT_V_MSB)); 1572 } 1573 break; 1574 1575 case METEORGCSAT: /* get chroma saturation */ 1576 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff; 1577 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB ) 1578 temp |= BIT_SEVEN_HIGH; 1579 *(u_char *)arg = (u_char)temp; 1580 break; 1581 1582 case METEORSCONT: /* set contrast */ 1583 temp = (int)*(u_char *)arg & 0xff; 1584 temp <<= 1; 1585 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff); 1586 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB); 1587 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB); 1588 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | 1589 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB)); 1590 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | 1591 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB)); 1592 break; 1593 1594 case METEORGCONT: /* get contrast */ 1595 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff; 1596 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6; 1597 *(u_char *)arg = (u_char)((temp >> 1) & 0xff); 1598 break; 1599 1600 case BT848SCBUF: /* set Clear-Buffer-on-start flag */ 1601 bktr->clr_on_start = (*(int *)arg != 0); 1602 break; 1603 1604 case BT848GCBUF: /* get Clear-Buffer-on-start flag */ 1605 *(int *)arg = (int) bktr->clr_on_start; 1606 break; 1607 1608 case METEORSSIGNAL: 1609 sig = *(int *)arg; 1610 /* Historically, applications used METEOR_SIG_MODE_MASK 1611 * to reset signal delivery. 1612 */ 1613 if (sig == METEOR_SIG_MODE_MASK) 1614 sig = 0; 1615 if (sig < 0 || sig > _SIG_MAXSIG) 1616 return (EINVAL); 1617 bktr->signal = sig; 1618 bktr->proc = sig ? td->td_proc : NULL; 1619 break; 1620 1621 case METEORGSIGNAL: 1622 *(int *)arg = bktr->signal; 1623 break; 1624 1625 case METEORCAPTUR: 1626 temp = bktr->flags; 1627 switch (*(int *) arg) { 1628 case METEOR_CAP_SINGLE: 1629 1630 if (bktr->bigbuf==0) /* no frame buffer allocated */ 1631 return( ENOMEM ); 1632 /* already capturing */ 1633 if (temp & METEOR_CAP_MASK) 1634 return( EIO ); 1635 1636 1637 1638 start_capture(bktr, METEOR_SINGLE); 1639 1640 /* wait for capture to complete */ 1641 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 1642 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1643 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1644 1645 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1646 BT848_INT_RISCI | 1647 BT848_INT_VSYNC | 1648 BT848_INT_FMTCHG); 1649 1650 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 1651 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz); 1652 if (error && (error != ERESTART)) { 1653 /* Here if we didn't get complete frame */ 1654#ifdef DIAGNOSTIC 1655 printf( "%s: ioctl: tsleep error %d %x\n", 1656 bktr_name(bktr), error, 1657 INL(bktr, BKTR_RISC_COUNT)); 1658#endif 1659 1660 /* stop dma */ 1661 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1662 1663 /* disable risc, leave fifo running */ 1664 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1665 } 1666 1667 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK); 1668 /* FIXME: should we set bt848->int_stat ??? */ 1669 break; 1670 1671 case METEOR_CAP_CONTINOUS: 1672 if (bktr->bigbuf==0) /* no frame buffer allocated */ 1673 return( ENOMEM ); 1674 /* already capturing */ 1675 if (temp & METEOR_CAP_MASK) 1676 return( EIO ); 1677 1678 1679 start_capture(bktr, METEOR_CONTIN); 1680 1681 /* Clear the interrypt status register */ 1682 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT)); 1683 1684 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1685 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1686 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 1687 1688 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1689 BT848_INT_RISCI | 1690 BT848_INT_VSYNC | 1691 BT848_INT_FMTCHG); 1692#ifdef BT848_DUMP 1693 dump_bt848( bt848 ); 1694#endif 1695 break; 1696 1697 case METEOR_CAP_STOP_CONT: 1698 if (bktr->flags & METEOR_CONTIN) { 1699 /* turn off capture */ 1700 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 1701 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 1702 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1703 bktr->flags &= 1704 ~(METEOR_CONTIN | METEOR_WANT_MASK); 1705 1706 } 1707 } 1708 break; 1709 1710 case METEORSETGEO: 1711 /* can't change parameters while capturing */ 1712 if (bktr->flags & METEOR_CAP_MASK) 1713 return( EBUSY ); 1714 1715 1716 geo = (struct meteor_geomet *) arg; 1717 1718 error = 0; 1719 /* Either even or odd, if even & odd, then these a zero */ 1720 if ((geo->oformat & METEOR_GEO_ODD_ONLY) && 1721 (geo->oformat & METEOR_GEO_EVEN_ONLY)) { 1722 printf( "%s: ioctl: Geometry odd or even only.\n", 1723 bktr_name(bktr)); 1724 return( EINVAL ); 1725 } 1726 1727 /* set/clear even/odd flags */ 1728 if (geo->oformat & METEOR_GEO_ODD_ONLY) 1729 bktr->flags |= METEOR_ONLY_ODD_FIELDS; 1730 else 1731 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS; 1732 if (geo->oformat & METEOR_GEO_EVEN_ONLY) 1733 bktr->flags |= METEOR_ONLY_EVEN_FIELDS; 1734 else 1735 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS; 1736 1737 if (geo->columns <= 0) { 1738 printf( 1739 "%s: ioctl: %d: columns must be greater than zero.\n", 1740 bktr_name(bktr), geo->columns); 1741 error = EINVAL; 1742 } 1743 else if ((geo->columns & 0x3fe) != geo->columns) { 1744 printf( 1745 "%s: ioctl: %d: columns too large or not even.\n", 1746 bktr_name(bktr), geo->columns); 1747 error = EINVAL; 1748 } 1749 1750 if (geo->rows <= 0) { 1751 printf( 1752 "%s: ioctl: %d: rows must be greater than zero.\n", 1753 bktr_name(bktr), geo->rows); 1754 error = EINVAL; 1755 } 1756 else if (((geo->rows & 0x7fe) != geo->rows) || 1757 ((geo->oformat & METEOR_GEO_FIELD_MASK) && 1758 ((geo->rows & 0x3fe) != geo->rows)) ) { 1759 printf( 1760 "%s: ioctl: %d: rows too large or not even.\n", 1761 bktr_name(bktr), geo->rows); 1762 error = EINVAL; 1763 } 1764 1765 if (geo->frames > 32) { 1766 printf("%s: ioctl: too many frames.\n", 1767 bktr_name(bktr)); 1768 1769 error = EINVAL; 1770 } 1771 1772 if (error) 1773 return( error ); 1774 1775 bktr->dma_prog_loaded = FALSE; 1776 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 1777 1778 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1779 1780 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) { 1781 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2; 1782 1783 /* meteor_mem structure for SYNC Capture */ 1784 if (geo->frames > 1) temp += PAGE_SIZE; 1785 1786 temp = btoc(temp); 1787 if ((int) temp > bktr->alloc_pages 1788 && bktr->video.addr == 0) { 1789 1790/*****************************/ 1791/* *** OS Dependent code *** */ 1792/*****************************/ 1793#if defined(__NetBSD__) || defined(__OpenBSD__) 1794 bus_dmamap_t dmamap; 1795 1796 buf = get_bktr_mem(bktr, &dmamap, 1797 temp * PAGE_SIZE); 1798 if (buf != 0) { 1799 free_bktr_mem(bktr, bktr->dm_mem, 1800 bktr->bigbuf); 1801 bktr->dm_mem = dmamap; 1802 1803#else 1804 buf = get_bktr_mem(unit, temp*PAGE_SIZE); 1805 if (buf != 0) { 1806 contigfree( 1807 (void *)(uintptr_t)bktr->bigbuf, 1808 (bktr->alloc_pages * PAGE_SIZE), 1809 M_DEVBUF); 1810#endif 1811 1812 bktr->bigbuf = buf; 1813 bktr->alloc_pages = temp; 1814 if (bootverbose) 1815 printf("%s: ioctl: Allocating %d bytes\n", 1816 bktr_name(bktr), (int)(temp*PAGE_SIZE)); 1817 } 1818 else 1819 error = ENOMEM; 1820 } 1821 } 1822 1823 if (error) 1824 return error; 1825 1826 bktr->rows = geo->rows; 1827 bktr->cols = geo->columns; 1828 bktr->frames = geo->frames; 1829 1830 /* Pixel format (if in meteor pixfmt compatibility mode) */ 1831 if ( bktr->pixfmt_compat ) { 1832 bktr->format = METEOR_GEO_YUV_422; 1833 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) { 1834 case 0: /* default */ 1835 case METEOR_GEO_RGB16: 1836 bktr->format = METEOR_GEO_RGB16; 1837 break; 1838 case METEOR_GEO_RGB24: 1839 bktr->format = METEOR_GEO_RGB24; 1840 break; 1841 case METEOR_GEO_YUV_422: 1842 bktr->format = METEOR_GEO_YUV_422; 1843 if (geo->oformat & METEOR_GEO_YUV_12) 1844 bktr->format = METEOR_GEO_YUV_12; 1845 break; 1846 case METEOR_GEO_YUV_PACKED: 1847 bktr->format = METEOR_GEO_YUV_PACKED; 1848 break; 1849 } 1850 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 1851 } 1852 1853 if (bktr->flags & METEOR_CAP_MASK) { 1854 1855 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) { 1856 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 1857 case METEOR_ONLY_ODD_FIELDS: 1858 bktr->flags |= METEOR_WANT_ODD; 1859 break; 1860 case METEOR_ONLY_EVEN_FIELDS: 1861 bktr->flags |= METEOR_WANT_EVEN; 1862 break; 1863 default: 1864 bktr->flags |= METEOR_WANT_MASK; 1865 break; 1866 } 1867 1868 start_capture(bktr, METEOR_CONTIN); 1869 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT)); 1870 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1871 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1872 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1873 BT848_INT_VSYNC | 1874 BT848_INT_FMTCHG); 1875 } 1876 } 1877 break; 1878 /* end of METEORSETGEO */ 1879 1880 /* FIXME. The Capture Area currently has the following restrictions: 1881 GENERAL 1882 y_offset may need to be even in interlaced modes 1883 RGB24 - Interlaced mode 1884 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols) 1885 y_size must be greater than or equal to METEORSETGEO height (rows) 1886 RGB24 - Even Only (or Odd Only) mode 1887 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols) 1888 y_size must be greater than or equal to 2*METEORSETGEO height (rows) 1889 YUV12 - Interlaced mode 1890 x_size must be greater than or equal to METEORSETGEO width (cols) 1891 y_size must be greater than or equal to METEORSETGEO height (rows) 1892 YUV12 - Even Only (or Odd Only) mode 1893 x_size must be greater than or equal to METEORSETGEO width (cols) 1894 y_size must be greater than or equal to 2*METEORSETGEO height (rows) 1895 */ 1896 1897 case BT848_SCAPAREA: /* set capture area of each video frame */ 1898 /* can't change parameters while capturing */ 1899 if (bktr->flags & METEOR_CAP_MASK) 1900 return( EBUSY ); 1901 1902 cap_area = (struct bktr_capture_area *) arg; 1903 bktr->capture_area_x_offset = cap_area->x_offset; 1904 bktr->capture_area_y_offset = cap_area->y_offset; 1905 bktr->capture_area_x_size = cap_area->x_size; 1906 bktr->capture_area_y_size = cap_area->y_size; 1907 bktr->capture_area_enabled = TRUE; 1908 1909 bktr->dma_prog_loaded = FALSE; 1910 break; 1911 1912 case BT848_GCAPAREA: /* get capture area of each video frame */ 1913 cap_area = (struct bktr_capture_area *) arg; 1914 if (bktr->capture_area_enabled == FALSE) { 1915 cap_area->x_offset = 0; 1916 cap_area->y_offset = 0; 1917 cap_area->x_size = format_params[ 1918 bktr->format_params].scaled_hactive; 1919 cap_area->y_size = format_params[ 1920 bktr->format_params].vactive; 1921 } else { 1922 cap_area->x_offset = bktr->capture_area_x_offset; 1923 cap_area->y_offset = bktr->capture_area_y_offset; 1924 cap_area->x_size = bktr->capture_area_x_size; 1925 cap_area->y_size = bktr->capture_area_y_size; 1926 } 1927 break; 1928 1929 default: 1930 return common_ioctl( bktr, cmd, arg ); 1931 } 1932 1933 return( 0 ); 1934} 1935 1936/* 1937 * tuner ioctls 1938 */ 1939int 1940tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td ) 1941{ 1942 int tmp_int; 1943 int temp, temp1; 1944 int offset; 1945 int count; 1946 u_char *buf; 1947 u_long par; 1948 u_char write; 1949 int i2c_addr; 1950 int i2c_port; 1951 u_long data; 1952 1953 switch ( cmd ) { 1954 1955 case REMOTE_GETKEY: 1956 /* Read the last key pressed by the Remote Control */ 1957 if (bktr->remote_control == 0) return (EINVAL); 1958 remote_read(bktr, (struct bktr_remote *)arg); 1959 break; 1960 1961#if defined( TUNER_AFC ) 1962 case TVTUNER_SETAFC: 1963 bktr->tuner.afc = (*(int *)arg != 0); 1964 break; 1965 1966 case TVTUNER_GETAFC: 1967 *(int *)arg = bktr->tuner.afc; 1968 /* XXX Perhaps use another bit to indicate AFC success? */ 1969 break; 1970#endif /* TUNER_AFC */ 1971 1972 case TVTUNER_SETCHNL: 1973 temp_mute( bktr, TRUE ); 1974 temp = tv_channel( bktr, (int)*(unsigned long *)arg ); 1975 if ( temp < 0 ) { 1976 temp_mute( bktr, FALSE ); 1977 return( EINVAL ); 1978 } 1979 *(unsigned long *)arg = temp; 1980 1981 /* after every channel change, we must restart the MSP34xx */ 1982 /* audio chip to reselect NICAM STEREO or MONO audio */ 1983 if ( bktr->card.msp3400c ) 1984 msp_autodetect( bktr ); 1985 1986 /* after every channel change, we must restart the DPL35xx */ 1987 if ( bktr->card.dpl3518a ) 1988 dpl_autodetect( bktr ); 1989 1990 temp_mute( bktr, FALSE ); 1991 break; 1992 1993 case TVTUNER_GETCHNL: 1994 *(unsigned long *)arg = bktr->tuner.channel; 1995 break; 1996 1997 case TVTUNER_SETTYPE: 1998 temp = *(unsigned long *)arg; 1999 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) ) 2000 return( EINVAL ); 2001 bktr->tuner.chnlset = temp; 2002 break; 2003 2004 case TVTUNER_GETTYPE: 2005 *(unsigned long *)arg = bktr->tuner.chnlset; 2006 break; 2007 2008 case TVTUNER_GETSTATUS: 2009 temp = get_tuner_status( bktr ); 2010 *(unsigned long *)arg = temp & 0xff; 2011 break; 2012 2013 case TVTUNER_SETFREQ: 2014 temp_mute( bktr, TRUE ); 2015 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY); 2016 temp_mute( bktr, FALSE ); 2017 if ( temp < 0 ) { 2018 temp_mute( bktr, FALSE ); 2019 return( EINVAL ); 2020 } 2021 *(unsigned long *)arg = temp; 2022 2023 /* after every channel change, we must restart the MSP34xx */ 2024 /* audio chip to reselect NICAM STEREO or MONO audio */ 2025 if ( bktr->card.msp3400c ) 2026 msp_autodetect( bktr ); 2027 2028 /* after every channel change, we must restart the DPL35xx */ 2029 if ( bktr->card.dpl3518a ) 2030 dpl_autodetect( bktr ); 2031 2032 temp_mute( bktr, FALSE ); 2033 break; 2034 2035 case TVTUNER_GETFREQ: 2036 *(unsigned long *)arg = bktr->tuner.frequency; 2037 break; 2038 2039 case TVTUNER_GETCHNLSET: 2040 return tuner_getchnlset((struct bktr_chnlset *)arg); 2041 2042 case BT848_SAUDIO: /* set audio channel */ 2043 if ( set_audio( bktr, *(int*)arg ) < 0 ) 2044 return( EIO ); 2045 break; 2046 2047 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */ 2048 case BT848_SHUE: /* set hue */ 2049 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff)); 2050 break; 2051 2052 case BT848_GHUE: /* get hue */ 2053 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff); 2054 break; 2055 2056 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */ 2057 case BT848_SBRIG: /* set brightness */ 2058 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff)); 2059 break; 2060 2061 case BT848_GBRIG: /* get brightness */ 2062 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff); 2063 break; 2064 2065 /* */ 2066 case BT848_SCSAT: /* set chroma saturation */ 2067 tmp_int = *(int*)arg; 2068 2069 temp = INB(bktr, BKTR_E_CONTROL); 2070 temp1 = INB(bktr, BKTR_O_CONTROL); 2071 if ( tmp_int & BIT_EIGHT_HIGH ) { 2072 temp |= (BT848_E_CONTROL_SAT_U_MSB | 2073 BT848_E_CONTROL_SAT_V_MSB); 2074 temp1 |= (BT848_O_CONTROL_SAT_U_MSB | 2075 BT848_O_CONTROL_SAT_V_MSB); 2076 } 2077 else { 2078 temp &= ~(BT848_E_CONTROL_SAT_U_MSB | 2079 BT848_E_CONTROL_SAT_V_MSB); 2080 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB | 2081 BT848_O_CONTROL_SAT_V_MSB); 2082 } 2083 2084 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff)); 2085 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff)); 2086 OUTB(bktr, BKTR_E_CONTROL, temp); 2087 OUTB(bktr, BKTR_O_CONTROL, temp1); 2088 break; 2089 2090 case BT848_GCSAT: /* get chroma saturation */ 2091 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff); 2092 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB ) 2093 tmp_int |= BIT_EIGHT_HIGH; 2094 *(int*)arg = tmp_int; 2095 break; 2096 2097 /* */ 2098 case BT848_SVSAT: /* set chroma V saturation */ 2099 tmp_int = *(int*)arg; 2100 2101 temp = INB(bktr, BKTR_E_CONTROL); 2102 temp1 = INB(bktr, BKTR_O_CONTROL); 2103 if ( tmp_int & BIT_EIGHT_HIGH) { 2104 temp |= BT848_E_CONTROL_SAT_V_MSB; 2105 temp1 |= BT848_O_CONTROL_SAT_V_MSB; 2106 } 2107 else { 2108 temp &= ~BT848_E_CONTROL_SAT_V_MSB; 2109 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB; 2110 } 2111 2112 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff)); 2113 OUTB(bktr, BKTR_E_CONTROL, temp); 2114 OUTB(bktr, BKTR_O_CONTROL, temp1); 2115 break; 2116 2117 case BT848_GVSAT: /* get chroma V saturation */ 2118 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff; 2119 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB ) 2120 tmp_int |= BIT_EIGHT_HIGH; 2121 *(int*)arg = tmp_int; 2122 break; 2123 2124 /* */ 2125 case BT848_SUSAT: /* set chroma U saturation */ 2126 tmp_int = *(int*)arg; 2127 2128 temp = INB(bktr, BKTR_E_CONTROL); 2129 temp1 = INB(bktr, BKTR_O_CONTROL); 2130 if ( tmp_int & BIT_EIGHT_HIGH ) { 2131 temp |= BT848_E_CONTROL_SAT_U_MSB; 2132 temp1 |= BT848_O_CONTROL_SAT_U_MSB; 2133 } 2134 else { 2135 temp &= ~BT848_E_CONTROL_SAT_U_MSB; 2136 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB; 2137 } 2138 2139 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff)); 2140 OUTB(bktr, BKTR_E_CONTROL, temp); 2141 OUTB(bktr, BKTR_O_CONTROL, temp1); 2142 break; 2143 2144 case BT848_GUSAT: /* get chroma U saturation */ 2145 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff; 2146 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB ) 2147 tmp_int |= BIT_EIGHT_HIGH; 2148 *(int*)arg = tmp_int; 2149 break; 2150 2151/* lr 970528 luma notch etc - 3 high bits of e_control/o_control */ 2152 2153 case BT848_SLNOTCH: /* set luma notch */ 2154 tmp_int = (*(int *)arg & 0x7) << 5 ; 2155 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0); 2156 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0); 2157 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int); 2158 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int); 2159 break; 2160 2161 case BT848_GLNOTCH: /* get luma notch */ 2162 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ; 2163 break; 2164 2165 2166 /* */ 2167 case BT848_SCONT: /* set contrast */ 2168 tmp_int = *(int*)arg; 2169 2170 temp = INB(bktr, BKTR_E_CONTROL); 2171 temp1 = INB(bktr, BKTR_O_CONTROL); 2172 if ( tmp_int & BIT_EIGHT_HIGH ) { 2173 temp |= BT848_E_CONTROL_CON_MSB; 2174 temp1 |= BT848_O_CONTROL_CON_MSB; 2175 } 2176 else { 2177 temp &= ~BT848_E_CONTROL_CON_MSB; 2178 temp1 &= ~BT848_O_CONTROL_CON_MSB; 2179 } 2180 2181 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff)); 2182 OUTB(bktr, BKTR_E_CONTROL, temp); 2183 OUTB(bktr, BKTR_O_CONTROL, temp1); 2184 break; 2185 2186 case BT848_GCONT: /* get contrast */ 2187 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff; 2188 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB ) 2189 tmp_int |= BIT_EIGHT_HIGH; 2190 *(int*)arg = tmp_int; 2191 break; 2192 2193 /* FIXME: SCBARS and CCBARS require a valid int * */ 2194 /* argument to succeed, but its not used; consider */ 2195 /* using the arg to store the on/off state so */ 2196 /* there's only one ioctl() needed to turn cbars on/off */ 2197 case BT848_SCBARS: /* set colorbar output */ 2198 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS); 2199 break; 2200 2201 case BT848_CCBARS: /* clear colorbar output */ 2202 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS)); 2203 break; 2204 2205 case BT848_GAUDIO: /* get audio channel */ 2206 temp = bktr->audio_mux_select; 2207 if ( bktr->audio_mute_state == TRUE ) 2208 temp |= AUDIO_MUTE; 2209 *(int*)arg = temp; 2210 break; 2211 2212 case BT848_SBTSC: /* set audio channel */ 2213 if ( set_BTSC( bktr, *(int*)arg ) < 0 ) 2214 return( EIO ); 2215 break; 2216 2217 case BT848_WEEPROM: /* write eeprom */ 2218 offset = (((struct eeProm *)arg)->offset); 2219 count = (((struct eeProm *)arg)->count); 2220 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2221 if ( writeEEProm( bktr, offset, count, buf ) < 0 ) 2222 return( EIO ); 2223 break; 2224 2225 case BT848_REEPROM: /* read eeprom */ 2226 offset = (((struct eeProm *)arg)->offset); 2227 count = (((struct eeProm *)arg)->count); 2228 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2229 if ( readEEProm( bktr, offset, count, buf ) < 0 ) 2230 return( EIO ); 2231 break; 2232 2233 case BT848_SIGNATURE: 2234 offset = (((struct eeProm *)arg)->offset); 2235 count = (((struct eeProm *)arg)->count); 2236 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2237 if ( signCard( bktr, offset, count, buf ) < 0 ) 2238 return( EIO ); 2239 break; 2240 2241 /* Ioctl's for direct gpio access */ 2242#ifdef BKTR_GPIO_ACCESS 2243 case BT848_GPIO_GET_EN: 2244 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN); 2245 break; 2246 2247 case BT848_GPIO_SET_EN: 2248 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg); 2249 break; 2250 2251 case BT848_GPIO_GET_DATA: 2252 *(int*)arg = INL(bktr, BKTR_GPIO_DATA); 2253 break; 2254 2255 case BT848_GPIO_SET_DATA: 2256 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg); 2257 break; 2258#endif /* BKTR_GPIO_ACCESS */ 2259 2260 /* Ioctl's for running the tuner device in radio mode */ 2261 2262 case RADIO_GETMODE: 2263 *(unsigned char *)arg = bktr->tuner.radio_mode; 2264 break; 2265 2266 case RADIO_SETMODE: 2267 bktr->tuner.radio_mode = *(unsigned char *)arg; 2268 break; 2269 2270 case RADIO_GETFREQ: 2271 *(unsigned long *)arg = bktr->tuner.frequency; 2272 break; 2273 2274 case RADIO_SETFREQ: 2275 /* The argument to this ioctl is NOT freq*16. It is 2276 ** freq*100. 2277 */ 2278 2279 temp=(int)*(unsigned long *)arg; 2280 2281#ifdef BKTR_RADIO_DEBUG 2282 printf("%s: arg=%d temp=%d\n", bktr_name(bktr), 2283 (int)*(unsigned long *)arg, temp); 2284#endif 2285 2286#ifndef BKTR_RADIO_NOFREQCHECK 2287 /* According to the spec. sheet the band: 87.5MHz-108MHz */ 2288 /* is supported. */ 2289 if(temp<8750 || temp>10800) { 2290 printf("%s: Radio frequency out of range\n", bktr_name(bktr)); 2291 return(EINVAL); 2292 } 2293#endif 2294 temp_mute( bktr, TRUE ); 2295 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY ); 2296 temp_mute( bktr, FALSE ); 2297#ifdef BKTR_RADIO_DEBUG 2298 if(temp) 2299 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp); 2300#endif 2301 if ( temp < 0 ) 2302 return( EINVAL ); 2303 *(unsigned long *)arg = temp; 2304 break; 2305 2306 /* Luigi's I2CWR ioctl */ 2307 case BT848_I2CWR: 2308 par = *(u_long *)arg; 2309 write = (par >> 24) & 0xff ; 2310 i2c_addr = (par >> 16) & 0xff ; 2311 i2c_port = (par >> 8) & 0xff ; 2312 data = (par) & 0xff ; 2313 2314 if (write) { 2315 i2cWrite( bktr, i2c_addr, i2c_port, data); 2316 } else { 2317 data = i2cRead( bktr, i2c_addr); 2318 } 2319 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff ); 2320 break; 2321 2322 2323#ifdef BT848_MSP_READ 2324 /* I2C ioctls to allow userland access to the MSP chip */ 2325 case BT848_MSP_READ: 2326 { 2327 struct bktr_msp_control *msp; 2328 msp = (struct bktr_msp_control *) arg; 2329 msp->data = msp_dpl_read(bktr, bktr->msp_addr, 2330 msp->function, msp->address); 2331 break; 2332 } 2333 2334 case BT848_MSP_WRITE: 2335 { 2336 struct bktr_msp_control *msp; 2337 msp = (struct bktr_msp_control *) arg; 2338 msp_dpl_write(bktr, bktr->msp_addr, msp->function, 2339 msp->address, msp->data ); 2340 break; 2341 } 2342 2343 case BT848_MSP_RESET: 2344 msp_dpl_reset(bktr, bktr->msp_addr); 2345 break; 2346#endif 2347 2348 default: 2349 return common_ioctl( bktr, cmd, arg ); 2350 } 2351 2352 return( 0 ); 2353} 2354 2355 2356/* 2357 * common ioctls 2358 */ 2359static int 2360common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg ) 2361{ 2362 int pixfmt; 2363 unsigned int temp; 2364 struct meteor_pixfmt *pf_pub; 2365 2366 switch (cmd) { 2367 2368 case METEORSINPUT: /* set input device */ 2369 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/ 2370 /* On the original bt848 boards, */ 2371 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */ 2372 /* On the Hauppauge bt878 boards, */ 2373 /* Tuner is MUX0, RCA is MUX3 */ 2374 /* Unfortunately Meteor driver codes DEV_RCA as DEV_0, so we */ 2375 /* stick with this system in our Meteor Emulation */ 2376 2377 switch(*(unsigned long *)arg & METEOR_DEV_MASK) { 2378 2379 /* this is the RCA video input */ 2380 case 0: /* default */ 2381 case METEOR_INPUT_DEV0: 2382 /* METEOR_INPUT_DEV_RCA: */ 2383 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2384 | METEOR_DEV0; 2385 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) 2386 & ~BT848_IFORM_MUXSEL); 2387 2388 /* work around for new Hauppauge 878 cards */ 2389 if ((bktr->card.card_id == CARD_HAUPPAUGE) && 2390 (bktr->id==BROOKTREE_878 || 2391 bktr->id==BROOKTREE_879) ) 2392 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3); 2393 else 2394 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1); 2395 2396 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2397 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP); 2398 set_audio( bktr, AUDIO_EXTERN ); 2399 break; 2400 2401 /* this is the tuner input */ 2402 case METEOR_INPUT_DEV1: 2403 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2404 | METEOR_DEV1; 2405 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2406 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0); 2407 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2408 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP); 2409 set_audio( bktr, AUDIO_TUNER ); 2410 break; 2411 2412 /* this is the S-VHS input, but with a composite camera */ 2413 case METEOR_INPUT_DEV2: 2414 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2415 | METEOR_DEV2; 2416 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2417 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2); 2418 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2419 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP); 2420 set_audio( bktr, AUDIO_EXTERN ); 2421 break; 2422 2423 /* this is the S-VHS input */ 2424 case METEOR_INPUT_DEV_SVIDEO: 2425 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2426 | METEOR_DEV_SVIDEO; 2427 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2428 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2); 2429 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP); 2430 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP); 2431 set_audio( bktr, AUDIO_EXTERN ); 2432 break; 2433 2434 case METEOR_INPUT_DEV3: 2435 if ((bktr->id == BROOKTREE_848A) || 2436 (bktr->id == BROOKTREE_849A) || 2437 (bktr->id == BROOKTREE_878) || 2438 (bktr->id == BROOKTREE_879) ) { 2439 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2440 | METEOR_DEV3; 2441 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2442 2443 /* work around for new Hauppauge 878 cards */ 2444 if ((bktr->card.card_id == CARD_HAUPPAUGE) && 2445 (bktr->id==BROOKTREE_878 || 2446 bktr->id==BROOKTREE_879) ) 2447 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1); 2448 else 2449 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3); 2450 2451 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2452 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP); 2453 set_audio( bktr, AUDIO_EXTERN ); 2454 2455 break; 2456 } 2457 2458 default: 2459 return( EINVAL ); 2460 } 2461 break; 2462 2463 case METEORGINPUT: /* get input device */ 2464 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK; 2465 break; 2466 2467 case METEORSACTPIXFMT: 2468 if (( *(int *)arg < 0 ) || 2469 ( *(int *)arg >= PIXFMT_TABLE_SIZE )) 2470 return( EINVAL ); 2471 2472 bktr->pixfmt = *(int *)arg; 2473 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 2474 | pixfmt_swap_flags( bktr->pixfmt )); 2475 bktr->pixfmt_compat = FALSE; 2476 break; 2477 2478 case METEORGACTPIXFMT: 2479 *(int *)arg = bktr->pixfmt; 2480 break; 2481 2482 case METEORGSUPPIXFMT : 2483 pf_pub = (struct meteor_pixfmt *)arg; 2484 pixfmt = pf_pub->index; 2485 2486 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE )) 2487 return( EINVAL ); 2488 2489 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public, 2490 sizeof( *pf_pub ) ); 2491 2492 /* Patch in our format index */ 2493 pf_pub->index = pixfmt; 2494 break; 2495 2496#if defined( STATUS_SUM ) 2497 case BT848_GSTATUS: /* reap status */ 2498 { 2499 DECLARE_INTR_MASK(s); 2500 DISABLE_INTR(s); 2501 temp = status_sum; 2502 status_sum = 0; 2503 ENABLE_INTR(s); 2504 *(u_int*)arg = temp; 2505 break; 2506 } 2507#endif /* STATUS_SUM */ 2508 2509 default: 2510 return( ENOTTY ); 2511 } 2512 2513 return( 0 ); 2514} 2515 2516 2517 2518 2519/****************************************************************************** 2520 * bt848 RISC programming routines: 2521 */ 2522 2523 2524/* 2525 * 2526 */ 2527#ifdef BT848_DEBUG 2528static int 2529dump_bt848( bktr_ptr_t bktr ) 2530{ 2531 int r[60]={ 2532 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94, 2533 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4, 2534 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40, 2535 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60, 2536 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4, 2537 0, 0, 0, 0 2538 }; 2539 int i; 2540 2541 for (i = 0; i < 40; i+=4) { 2542 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n", 2543 bktr_name(bktr), 2544 r[i], INL(bktr, r[i]), 2545 r[i+1], INL(bktr, r[i+1]), 2546 r[i+2], INL(bktr, r[i+2]), 2547 r[i+3], INL(bktr, r[i+3]])); 2548 } 2549 2550 printf("%s: INT STAT %x \n", bktr_name(bktr), 2551 INL(bktr, BKTR_INT_STAT)); 2552 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr), 2553 INL(bktr, BKTR_INT_MASK)); 2554 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr), 2555 INW(bktr, BKTR_GPIO_DMA_CTL)); 2556 2557 return( 0 ); 2558} 2559 2560#endif 2561 2562/* 2563 * build write instruction 2564 */ 2565#define BKTR_FM1 0x6 /* packed data to follow */ 2566#define BKTR_FM3 0xe /* planar data to follow */ 2567#define BKTR_VRE 0x4 /* Marks the end of the even field */ 2568#define BKTR_VRO 0xC /* Marks the end of the odd field */ 2569#define BKTR_PXV 0x0 /* valid word (never used) */ 2570#define BKTR_EOL 0x1 /* last dword, 4 bytes */ 2571#define BKTR_SOL 0x2 /* first dword */ 2572 2573#define OP_WRITE (0x1 << 28) 2574#define OP_SKIP (0x2 << 28) 2575#define OP_WRITEC (0x5 << 28) 2576#define OP_JUMP (0x7 << 28) 2577#define OP_SYNC (0x8 << 28) 2578#define OP_WRITE123 (0x9 << 28) 2579#define OP_WRITES123 (0xb << 28) 2580#define OP_SOL (1 << 27) /* first instr for scanline */ 2581#define OP_EOL (1 << 26) 2582 2583#define BKTR_RESYNC (1 << 15) 2584#define BKTR_GEN_IRQ (1 << 24) 2585 2586/* 2587 * The RISC status bits can be set/cleared in the RISC programs 2588 * and tested in the Interrupt Handler 2589 */ 2590#define BKTR_SET_RISC_STATUS_BIT0 (1 << 16) 2591#define BKTR_SET_RISC_STATUS_BIT1 (1 << 17) 2592#define BKTR_SET_RISC_STATUS_BIT2 (1 << 18) 2593#define BKTR_SET_RISC_STATUS_BIT3 (1 << 19) 2594 2595#define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20) 2596#define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21) 2597#define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22) 2598#define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23) 2599 2600#define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28) 2601#define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29) 2602#define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30) 2603#define BKTR_TEST_RISC_STATUS_BIT3 (1U << 31) 2604 2605static bool_t notclipped (bktr_reg_t * bktr, int x, int width) { 2606 int i; 2607 bktr_clip_t * clip_node; 2608 bktr->clip_start = -1; 2609 bktr->last_y = 0; 2610 bktr->y = 0; 2611 bktr->y2 = width; 2612 bktr->line_length = width; 2613 bktr->yclip = -1; 2614 bktr->yclip2 = -1; 2615 bktr->current_col = 0; 2616 2617 if (bktr->max_clip_node == 0 ) return TRUE; 2618 clip_node = (bktr_clip_t *) &bktr->clip_list[0]; 2619 2620 2621 for (i = 0; i < bktr->max_clip_node; i++ ) { 2622 clip_node = (bktr_clip_t *) &bktr->clip_list[i]; 2623 if (x >= clip_node->x_min && x <= clip_node->x_max ) { 2624 bktr->clip_start = i; 2625 return FALSE; 2626 } 2627 } 2628 2629 return TRUE; 2630} 2631 2632static bool_t getline(bktr_reg_t *bktr, int x ) { 2633 int i, j; 2634 bktr_clip_t * clip_node ; 2635 2636 if (bktr->line_length == 0 || 2637 bktr->current_col >= bktr->line_length) return FALSE; 2638 2639 bktr->y = min(bktr->last_y, bktr->line_length); 2640 bktr->y2 = bktr->line_length; 2641 2642 bktr->yclip = bktr->yclip2 = -1; 2643 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) { 2644 clip_node = (bktr_clip_t *) &bktr->clip_list[i]; 2645 if (x >= clip_node->x_min && x <= clip_node->x_max) { 2646 if (bktr->last_y <= clip_node->y_min) { 2647 bktr->y = min(bktr->last_y, bktr->line_length); 2648 bktr->y2 = min(clip_node->y_min, bktr->line_length); 2649 bktr->yclip = min(clip_node->y_min, bktr->line_length); 2650 bktr->yclip2 = min(clip_node->y_max, bktr->line_length); 2651 bktr->last_y = bktr->yclip2; 2652 bktr->clip_start = i; 2653 2654 for (j = i+1; j < bktr->max_clip_node; j++ ) { 2655 clip_node = (bktr_clip_t *) &bktr->clip_list[j]; 2656 if (x >= clip_node->x_min && x <= clip_node->x_max) { 2657 if (bktr->last_y >= clip_node->y_min) { 2658 bktr->yclip2 = min(clip_node->y_max, bktr->line_length); 2659 bktr->last_y = bktr->yclip2; 2660 bktr->clip_start = j; 2661 } 2662 } else break ; 2663 } 2664 return TRUE; 2665 } 2666 } 2667 } 2668 2669 if (bktr->current_col <= bktr->line_length) { 2670 bktr->current_col = bktr->line_length; 2671 return TRUE; 2672 } 2673 return FALSE; 2674} 2675 2676static bool_t split(bktr_reg_t * bktr, volatile uint32_t **dma_prog, int width , 2677 u_long operation, int pixel_width, 2678 volatile u_char ** target_buffer, int cols ) { 2679 2680 u_long flag, flag2; 2681 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public; 2682 u_int skip, start_skip; 2683 2684 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */ 2685 /* to the 1st byte in the mem dword containing our start addr. */ 2686 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */ 2687 /* must be Blue. */ 2688 start_skip = 0; 2689 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 )) 2690 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) { 2691 case 2 : start_skip = 4 ; break; 2692 case 1 : start_skip = 8 ; break; 2693 } 2694 2695 if ((width * pixel_width) < DMA_BT848_SPLIT ) { 2696 if ( width == cols) { 2697 flag = OP_SOL | OP_EOL; 2698 } else if (bktr->current_col == 0 ) { 2699 flag = OP_SOL; 2700 } else if (bktr->current_col == cols) { 2701 flag = OP_EOL; 2702 } else flag = 0; 2703 2704 skip = 0; 2705 if (( flag & OP_SOL ) && ( start_skip > 0 )) { 2706 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip; 2707 flag &= ~OP_SOL; 2708 skip = start_skip; 2709 } 2710 2711 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip); 2712 if (operation != OP_SKIP ) 2713 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer; 2714 2715 *target_buffer += width * pixel_width; 2716 bktr->current_col += width; 2717 2718 } else { 2719 2720 if (bktr->current_col == 0 && width == cols) { 2721 flag = OP_SOL ; 2722 flag2 = OP_EOL; 2723 } else if (bktr->current_col == 0 ) { 2724 flag = OP_SOL; 2725 flag2 = 0; 2726 } else if (bktr->current_col >= cols) { 2727 flag = 0; 2728 flag2 = OP_EOL; 2729 } else { 2730 flag = 0; 2731 flag2 = 0; 2732 } 2733 2734 skip = 0; 2735 if (( flag & OP_SOL ) && ( start_skip > 0 )) { 2736 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip; 2737 flag &= ~OP_SOL; 2738 skip = start_skip; 2739 } 2740 2741 *(*dma_prog)++ = operation | flag | 2742 (width * pixel_width / 2 - skip); 2743 if (operation != OP_SKIP ) 2744 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ; 2745 *target_buffer += (width * pixel_width / 2) ; 2746 2747 if ( operation == OP_WRITE ) 2748 operation = OP_WRITEC; 2749 *(*dma_prog)++ = operation | flag2 | 2750 (width * pixel_width / 2); 2751 *target_buffer += (width * pixel_width / 2) ; 2752 bktr->current_col += width; 2753 2754 } 2755 return TRUE; 2756} 2757 2758 2759/* 2760 * Generate the RISC instructions to capture both VBI and video images 2761 */ 2762static void 2763rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) 2764{ 2765 int i; 2766 volatile uint32_t target_buffer, buffer, target,width; 2767 volatile uint32_t pitch; 2768 volatile uint32_t *dma_prog; /* DMA prog is an array of 2769 32 bit RISC instructions */ 2770 volatile uint32_t *loop_point; 2771 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2772 u_int Bpp = pf_int->public.Bpp; 2773 unsigned int vbisamples; /* VBI samples per line */ 2774 unsigned int vbilines; /* VBI lines per field */ 2775 unsigned int num_dwords; /* DWORDS per line */ 2776 2777 vbisamples = format_params[bktr->format_params].vbi_num_samples; 2778 vbilines = format_params[bktr->format_params].vbi_num_lines; 2779 num_dwords = vbisamples/4; 2780 2781 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 2782 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 2783 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff); 2784 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */ 2785 /* no ext frame */ 2786 2787 OUTB(bktr, BKTR_OFORM, 0x00); 2788 2789 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */ 2790 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40); 2791 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */ 2792 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80); 2793 2794 /* disable gamma correction removal */ 2795 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA); 2796 2797 if (cols > 385 ) { 2798 OUTB(bktr, BKTR_E_VTC, 0); 2799 OUTB(bktr, BKTR_O_VTC, 0); 2800 } else { 2801 OUTB(bktr, BKTR_E_VTC, 1); 2802 OUTB(bktr, BKTR_O_VTC, 1); 2803 } 2804 bktr->capcontrol = 3 << 2 | 3; 2805 2806 dma_prog = (uint32_t *) bktr->dma_prog; 2807 2808 /* Construct Write */ 2809 2810 if (bktr->video.addr) { 2811 target_buffer = (u_long) bktr->video.addr; 2812 pitch = bktr->video.width; 2813 } 2814 else { 2815 target_buffer = (u_long) vtophys(bktr->bigbuf); 2816 pitch = cols*Bpp; 2817 } 2818 2819 buffer = target_buffer; 2820 2821 /* Wait for the VRE sync marking the end of the Even and 2822 * the start of the Odd field. Resync here. 2823 */ 2824 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE; 2825 *dma_prog++ = 0; 2826 2827 loop_point = dma_prog; 2828 2829 /* store the VBI data */ 2830 /* look for sync with packed data */ 2831 *dma_prog++ = OP_SYNC | BKTR_FM1; 2832 *dma_prog++ = 0; 2833 for(i = 0; i < vbilines; i++) { 2834 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples; 2835 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata + 2836 (i * VBI_LINE_SIZE)); 2837 } 2838 2839 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) { 2840 /* store the Odd field video image */ 2841 /* look for sync with packed data */ 2842 *dma_prog++ = OP_SYNC | BKTR_FM1; 2843 *dma_prog++ = 0; /* NULL WORD */ 2844 width = cols; 2845 for (i = 0; i < (rows/interlace); i++) { 2846 target = target_buffer; 2847 if ( notclipped(bktr, i, width)) { 2848 split(bktr, (volatile uint32_t **) &dma_prog, 2849 bktr->y2 - bktr->y, OP_WRITE, 2850 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 2851 2852 } else { 2853 while(getline(bktr, i)) { 2854 if (bktr->y != bktr->y2 ) { 2855 split(bktr, (volatile uint32_t **) &dma_prog, 2856 bktr->y2 - bktr->y, OP_WRITE, 2857 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 2858 } 2859 if (bktr->yclip != bktr->yclip2 ) { 2860 split(bktr,(volatile uint32_t **) &dma_prog, 2861 bktr->yclip2 - bktr->yclip, 2862 OP_SKIP, 2863 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 2864 } 2865 } 2866 2867 } 2868 2869 target_buffer += interlace * pitch; 2870 2871 } 2872 2873 } /* end if */ 2874 2875 /* Grab the Even field */ 2876 /* Look for the VRO, end of Odd field, marker */ 2877 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; 2878 *dma_prog++ = 0; /* NULL WORD */ 2879 2880 /* store the VBI data */ 2881 /* look for sync with packed data */ 2882 *dma_prog++ = OP_SYNC | BKTR_FM1; 2883 *dma_prog++ = 0; 2884 for(i = 0; i < vbilines; i++) { 2885 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples; 2886 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata + 2887 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE)); 2888 } 2889 2890 /* store the video image */ 2891 if (i_flag == 1) /*Even Only*/ 2892 target_buffer = buffer; 2893 if (i_flag == 3) /*interlaced*/ 2894 target_buffer = buffer+pitch; 2895 2896 2897 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) { 2898 /* look for sync with packed data */ 2899 *dma_prog++ = OP_SYNC | BKTR_FM1; 2900 *dma_prog++ = 0; /* NULL WORD */ 2901 width = cols; 2902 for (i = 0; i < (rows/interlace); i++) { 2903 target = target_buffer; 2904 if ( notclipped(bktr, i, width)) { 2905 split(bktr, (volatile uint32_t **) &dma_prog, 2906 bktr->y2 - bktr->y, OP_WRITE, 2907 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 2908 } else { 2909 while(getline(bktr, i)) { 2910 if (bktr->y != bktr->y2 ) { 2911 split(bktr, (volatile uint32_t **) &dma_prog, 2912 bktr->y2 - bktr->y, OP_WRITE, 2913 Bpp, (volatile u_char **)(uintptr_t)&target, 2914 cols); 2915 } 2916 if (bktr->yclip != bktr->yclip2 ) { 2917 split(bktr, (volatile uint32_t **) &dma_prog, 2918 bktr->yclip2 - bktr->yclip, OP_SKIP, 2919 Bpp, (volatile u_char **)(uintptr_t) &target, cols); 2920 } 2921 2922 } 2923 2924 } 2925 2926 target_buffer += interlace * pitch; 2927 2928 } 2929 } 2930 2931 /* Look for end of 'Even Field' */ 2932 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; 2933 *dma_prog++ = 0; /* NULL WORD */ 2934 2935 *dma_prog++ = OP_JUMP ; 2936 *dma_prog++ = (u_long ) vtophys(loop_point) ; 2937 *dma_prog++ = 0; /* NULL WORD */ 2938 2939} 2940 2941 2942 2943 2944static void 2945rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) 2946{ 2947 int i; 2948 volatile uint32_t target_buffer, buffer, target,width; 2949 volatile uint32_t pitch; 2950 volatile uint32_t *dma_prog; 2951 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2952 u_int Bpp = pf_int->public.Bpp; 2953 2954 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 2955 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0); 2956 OUTB(bktr, BKTR_VBI_PACK_DEL, 0); 2957 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 2958 2959 OUTB(bktr, BKTR_OFORM, 0x00); 2960 2961 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */ 2962 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40); 2963 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */ 2964 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80); 2965 2966 /* disable gamma correction removal */ 2967 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA); 2968 2969 if (cols > 385 ) { 2970 OUTB(bktr, BKTR_E_VTC, 0); 2971 OUTB(bktr, BKTR_O_VTC, 0); 2972 } else { 2973 OUTB(bktr, BKTR_E_VTC, 1); 2974 OUTB(bktr, BKTR_O_VTC, 1); 2975 } 2976 bktr->capcontrol = 3 << 2 | 3; 2977 2978 dma_prog = (uint32_t *) bktr->dma_prog; 2979 2980 /* Construct Write */ 2981 2982 if (bktr->video.addr) { 2983 target_buffer = (uint32_t) bktr->video.addr; 2984 pitch = bktr->video.width; 2985 } 2986 else { 2987 target_buffer = (uint32_t) vtophys(bktr->bigbuf); 2988 pitch = cols*Bpp; 2989 } 2990 2991 buffer = target_buffer; 2992 2993 /* contruct sync : for video packet format */ 2994 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; 2995 2996 /* sync, mode indicator packed data */ 2997 *dma_prog++ = 0; /* NULL WORD */ 2998 width = cols; 2999 for (i = 0; i < (rows/interlace); i++) { 3000 target = target_buffer; 3001 if ( notclipped(bktr, i, width)) { 3002 split(bktr, (volatile uint32_t **) &dma_prog, 3003 bktr->y2 - bktr->y, OP_WRITE, 3004 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 3005 3006 } else { 3007 while(getline(bktr, i)) { 3008 if (bktr->y != bktr->y2 ) { 3009 split(bktr, (volatile uint32_t **) &dma_prog, 3010 bktr->y2 - bktr->y, OP_WRITE, 3011 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 3012 } 3013 if (bktr->yclip != bktr->yclip2 ) { 3014 split(bktr,(volatile uint32_t **) &dma_prog, 3015 bktr->yclip2 - bktr->yclip, 3016 OP_SKIP, 3017 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 3018 } 3019 } 3020 3021 } 3022 3023 target_buffer += interlace * pitch; 3024 3025 } 3026 3027 switch (i_flag) { 3028 case 1: 3029 /* sync vre */ 3030 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO; 3031 *dma_prog++ = 0; /* NULL WORD */ 3032 3033 *dma_prog++ = OP_JUMP; 3034 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog); 3035 return; 3036 3037 case 2: 3038 /* sync vro */ 3039 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE; 3040 *dma_prog++ = 0; /* NULL WORD */ 3041 3042 *dma_prog++ = OP_JUMP; 3043 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog); 3044 return; 3045 3046 case 3: 3047 /* sync vro */ 3048 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; 3049 *dma_prog++ = 0; /* NULL WORD */ 3050 *dma_prog++ = OP_JUMP; 3051 *dma_prog = (uint32_t ) vtophys(bktr->odd_dma_prog); 3052 break; 3053 } 3054 3055 if (interlace == 2) { 3056 3057 target_buffer = buffer + pitch; 3058 3059 dma_prog = (uint32_t *) bktr->odd_dma_prog; 3060 3061 /* sync vre IRQ bit */ 3062 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; 3063 *dma_prog++ = 0; /* NULL WORD */ 3064 width = cols; 3065 for (i = 0; i < (rows/interlace); i++) { 3066 target = target_buffer; 3067 if ( notclipped(bktr, i, width)) { 3068 split(bktr, (volatile uint32_t **) &dma_prog, 3069 bktr->y2 - bktr->y, OP_WRITE, 3070 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 3071 } else { 3072 while(getline(bktr, i)) { 3073 if (bktr->y != bktr->y2 ) { 3074 split(bktr, (volatile uint32_t **) &dma_prog, 3075 bktr->y2 - bktr->y, OP_WRITE, 3076 Bpp, (volatile u_char **)(uintptr_t)&target, 3077 cols); 3078 } 3079 if (bktr->yclip != bktr->yclip2 ) { 3080 split(bktr, (volatile uint32_t **) &dma_prog, 3081 bktr->yclip2 - bktr->yclip, OP_SKIP, 3082 Bpp, (volatile u_char **)(uintptr_t)&target, cols); 3083 } 3084 3085 } 3086 3087 } 3088 3089 target_buffer += interlace * pitch; 3090 3091 } 3092 } 3093 3094 /* sync vre IRQ bit */ 3095 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; 3096 *dma_prog++ = 0; /* NULL WORD */ 3097 *dma_prog++ = OP_JUMP ; 3098 *dma_prog++ = (uint32_t ) vtophys(bktr->dma_prog) ; 3099 *dma_prog++ = 0; /* NULL WORD */ 3100} 3101 3102 3103/* 3104 * 3105 */ 3106static void 3107yuvpack_prog( bktr_ptr_t bktr, char i_flag, 3108 int cols, int rows, int interlace ) 3109{ 3110 int i; 3111 volatile unsigned int inst; 3112 volatile unsigned int inst3; 3113 volatile uint32_t target_buffer, buffer; 3114 volatile uint32_t *dma_prog; 3115 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3116 int b; 3117 3118 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 3119 3120 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */ 3121 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC); 3122 3123 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA); 3124 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 3125 3126 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3; 3127 bktr->capcontrol = 3 << 2 | 3; 3128 3129 dma_prog = (uint32_t *) bktr->dma_prog; 3130 3131 /* Construct Write */ 3132 3133 /* write , sol, eol */ 3134 inst = OP_WRITE | OP_SOL | (cols); 3135 /* write , sol, eol */ 3136 inst3 = OP_WRITE | OP_EOL | (cols); 3137 3138 if (bktr->video.addr) 3139 target_buffer = (uint32_t) bktr->video.addr; 3140 else 3141 target_buffer = (uint32_t) vtophys(bktr->bigbuf); 3142 3143 buffer = target_buffer; 3144 3145 /* contruct sync : for video packet format */ 3146 /* sync, mode indicator packed data */ 3147 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; 3148 *dma_prog++ = 0; /* NULL WORD */ 3149 3150 b = cols; 3151 3152 for (i = 0; i < (rows/interlace); i++) { 3153 *dma_prog++ = inst; 3154 *dma_prog++ = target_buffer; 3155 *dma_prog++ = inst3; 3156 *dma_prog++ = target_buffer + b; 3157 target_buffer += interlace*(cols * 2); 3158 } 3159 3160 switch (i_flag) { 3161 case 1: 3162 /* sync vre */ 3163 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE; 3164 *dma_prog++ = 0; /* NULL WORD */ 3165 3166 *dma_prog++ = OP_JUMP; 3167 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3168 return; 3169 3170 case 2: 3171 /* sync vro */ 3172 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO; 3173 *dma_prog++ = 0; /* NULL WORD */ 3174 *dma_prog++ = OP_JUMP; 3175 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3176 return; 3177 3178 case 3: 3179 /* sync vro */ 3180 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; 3181 *dma_prog++ = 0; /* NULL WORD */ 3182 *dma_prog++ = OP_JUMP ; 3183 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog); 3184 break; 3185 } 3186 3187 if (interlace == 2) { 3188 3189 target_buffer = (uint32_t) buffer + cols*2; 3190 3191 dma_prog = (uint32_t *) bktr->odd_dma_prog; 3192 3193 /* sync vre */ 3194 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; 3195 *dma_prog++ = 0; /* NULL WORD */ 3196 3197 for (i = 0; i < (rows/interlace) ; i++) { 3198 *dma_prog++ = inst; 3199 *dma_prog++ = target_buffer; 3200 *dma_prog++ = inst3; 3201 *dma_prog++ = target_buffer + b; 3202 target_buffer += interlace * ( cols*2); 3203 } 3204 } 3205 3206 /* sync vro IRQ bit */ 3207 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; 3208 *dma_prog++ = 0; /* NULL WORD */ 3209 *dma_prog++ = OP_JUMP ; 3210 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3211 3212 *dma_prog++ = OP_JUMP; 3213 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3214 *dma_prog++ = 0; /* NULL WORD */ 3215} 3216 3217 3218/* 3219 * 3220 */ 3221static void 3222yuv422_prog( bktr_ptr_t bktr, char i_flag, 3223 int cols, int rows, int interlace ){ 3224 3225 int i; 3226 volatile unsigned int inst; 3227 volatile uint32_t target_buffer, t1, buffer; 3228 volatile uint32_t *dma_prog; 3229 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3230 3231 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 3232 3233 dma_prog = (uint32_t*) bktr->dma_prog; 3234 3235 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 3236 3237 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 3238 OUTB(bktr, BKTR_OFORM, 0x00); 3239 3240 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */ 3241 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC); 3242 3243 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */ 3244 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC); 3245 3246 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */ 3247 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80); 3248 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */ 3249 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40); 3250 3251 /* disable gamma correction removal */ 3252 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA); 3253 3254 /* Construct Write */ 3255 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 3256 if (bktr->video.addr) 3257 target_buffer = (uint32_t) bktr->video.addr; 3258 else 3259 target_buffer = (uint32_t) vtophys(bktr->bigbuf); 3260 3261 buffer = target_buffer; 3262 3263 t1 = buffer; 3264 3265 /* contruct sync : for video packet format */ 3266 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ 3267 *dma_prog++ = 0; /* NULL WORD */ 3268 3269 for (i = 0; i < (rows/interlace ) ; i++) { 3270 *dma_prog++ = inst; 3271 *dma_prog++ = cols/2 | cols/2 << 16; 3272 *dma_prog++ = target_buffer; 3273 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3274 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace; 3275 target_buffer += interlace*cols; 3276 } 3277 3278 switch (i_flag) { 3279 case 1: 3280 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ 3281 *dma_prog++ = 0; /* NULL WORD */ 3282 3283 *dma_prog++ = OP_JUMP ; 3284 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3285 return; 3286 3287 case 2: 3288 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/ 3289 *dma_prog++ = 0; /* NULL WORD */ 3290 3291 *dma_prog++ = OP_JUMP; 3292 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3293 return; 3294 3295 case 3: 3296 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; 3297 *dma_prog++ = 0; /* NULL WORD */ 3298 3299 *dma_prog++ = OP_JUMP ; 3300 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog); 3301 break; 3302 } 3303 3304 if (interlace == 2) { 3305 3306 dma_prog = (uint32_t *) bktr->odd_dma_prog; 3307 3308 target_buffer = (uint32_t) buffer + cols; 3309 t1 = buffer + cols/2; 3310 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; 3311 *dma_prog++ = 0; /* NULL WORD */ 3312 3313 for (i = 0; i < (rows/interlace ) ; i++) { 3314 *dma_prog++ = inst; 3315 *dma_prog++ = cols/2 | cols/2 << 16; 3316 *dma_prog++ = target_buffer; 3317 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3318 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace; 3319 target_buffer += interlace*cols; 3320 } 3321 } 3322 3323 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; 3324 *dma_prog++ = 0; /* NULL WORD */ 3325 *dma_prog++ = OP_JUMP ; 3326 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog) ; 3327 *dma_prog++ = 0; /* NULL WORD */ 3328} 3329 3330 3331/* 3332 * 3333 */ 3334static void 3335yuv12_prog( bktr_ptr_t bktr, char i_flag, 3336 int cols, int rows, int interlace ){ 3337 3338 int i; 3339 volatile unsigned int inst; 3340 volatile unsigned int inst1; 3341 volatile uint32_t target_buffer, t1, buffer; 3342 volatile uint32_t *dma_prog; 3343 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3344 3345 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 3346 3347 dma_prog = (uint32_t *) bktr->dma_prog; 3348 3349 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 3350 3351 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 3352 OUTB(bktr, BKTR_OFORM, 0x0); 3353 3354 /* Construct Write */ 3355 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 3356 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols); 3357 if (bktr->video.addr) 3358 target_buffer = (uint32_t) bktr->video.addr; 3359 else 3360 target_buffer = (uint32_t) vtophys(bktr->bigbuf); 3361 3362 buffer = target_buffer; 3363 t1 = buffer; 3364 3365 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ 3366 *dma_prog++ = 0; /* NULL WORD */ 3367 3368 for (i = 0; i < (rows/interlace )/2 ; i++) { 3369 *dma_prog++ = inst; 3370 *dma_prog++ = cols/2 | (cols/2 << 16); 3371 *dma_prog++ = target_buffer; 3372 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3373 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace; 3374 target_buffer += interlace*cols; 3375 *dma_prog++ = inst1; 3376 *dma_prog++ = cols/2 | (cols/2 << 16); 3377 *dma_prog++ = target_buffer; 3378 target_buffer += interlace*cols; 3379 3380 } 3381 3382 switch (i_flag) { 3383 case 1: 3384 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ 3385 *dma_prog++ = 0; /* NULL WORD */ 3386 3387 *dma_prog++ = OP_JUMP; 3388 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3389 return; 3390 3391 case 2: 3392 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/ 3393 *dma_prog++ = 0; /* NULL WORD */ 3394 3395 *dma_prog++ = OP_JUMP; 3396 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3397 return; 3398 3399 case 3: 3400 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; 3401 *dma_prog++ = 0; /* NULL WORD */ 3402 *dma_prog++ = OP_JUMP ; 3403 *dma_prog = (uint32_t) vtophys(bktr->odd_dma_prog); 3404 break; 3405 } 3406 3407 if (interlace == 2) { 3408 3409 dma_prog = (uint32_t *) bktr->odd_dma_prog; 3410 3411 target_buffer = (uint32_t) buffer + cols; 3412 t1 = buffer + cols/2; 3413 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; 3414 *dma_prog++ = 0; /* NULL WORD */ 3415 3416 for (i = 0; i < ((rows/interlace )/2 ) ; i++) { 3417 *dma_prog++ = inst; 3418 *dma_prog++ = cols/2 | (cols/2 << 16); 3419 *dma_prog++ = target_buffer; 3420 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3421 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace; 3422 target_buffer += interlace*cols; 3423 *dma_prog++ = inst1; 3424 *dma_prog++ = cols/2 | (cols/2 << 16); 3425 *dma_prog++ = target_buffer; 3426 target_buffer += interlace*cols; 3427 3428 } 3429 3430 3431 } 3432 3433 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; 3434 *dma_prog++ = 0; /* NULL WORD */ 3435 *dma_prog++ = OP_JUMP; 3436 *dma_prog++ = (uint32_t) vtophys(bktr->dma_prog); 3437 *dma_prog++ = 0; /* NULL WORD */ 3438} 3439 3440 3441 3442/* 3443 * 3444 */ 3445static void 3446build_dma_prog( bktr_ptr_t bktr, char i_flag ) 3447{ 3448 int rows, cols, interlace; 3449 int tmp_int; 3450 unsigned int temp; 3451 struct format_params *fp; 3452 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3453 3454 3455 fp = &format_params[bktr->format_params]; 3456 3457 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 3458 3459 /* disable FIFO & RISC, leave other bits alone */ 3460 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED); 3461 3462 /* set video parameters */ 3463 if (bktr->capture_area_enabled) 3464 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096 3465 / fp->scaled_htotal / bktr->cols) - 4096; 3466 else 3467 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096 3468 / fp->scaled_htotal / bktr->cols) - 4096; 3469 3470 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */ 3471 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff); 3472 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff); 3473 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff); 3474 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff); 3475 3476 /* horizontal active */ 3477 temp = bktr->cols; 3478 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */ 3479 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff); 3480 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff); 3481 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3); 3482 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3); 3483 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3)); 3484 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3)); 3485 3486 /* horizontal delay */ 3487 if (bktr->capture_area_enabled) 3488 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal) 3489 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive); 3490 else 3491 temp = (fp->hdelay * bktr->cols) / fp->hactive; 3492 3493 temp = temp & 0x3fe; 3494 3495 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */ 3496 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff); 3497 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff); 3498 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc); 3499 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc); 3500 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc)); 3501 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc)); 3502 3503 /* vertical scale */ 3504 3505 if (bktr->capture_area_enabled) { 3506 if (bktr->flags & METEOR_ONLY_ODD_FIELDS || 3507 bktr->flags & METEOR_ONLY_EVEN_FIELDS) 3508 tmp_int = 65536 - 3509 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512); 3510 else { 3511 tmp_int = 65536 - 3512 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512); 3513 } 3514 } else { 3515 if (bktr->flags & METEOR_ONLY_ODD_FIELDS || 3516 bktr->flags & METEOR_ONLY_EVEN_FIELDS) 3517 tmp_int = 65536 - 3518 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512); 3519 else { 3520 tmp_int = 65536 - 3521 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512); 3522 } 3523 } 3524 3525 tmp_int &= 0x1fff; 3526 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */ 3527 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff); 3528 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff); 3529 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f); 3530 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f); 3531 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f)); 3532 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f)); 3533 3534 3535 /* vertical active */ 3536 if (bktr->capture_area_enabled) 3537 temp = bktr->capture_area_y_size; 3538 else 3539 temp = fp->vactive; 3540 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */ 3541 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30); 3542 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30)); 3543 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff); 3544 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30); 3545 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30)); 3546 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff); 3547 3548 /* vertical delay */ 3549 if (bktr->capture_area_enabled) 3550 temp = fp->vdelay + (bktr->capture_area_y_offset); 3551 else 3552 temp = fp->vdelay; 3553 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */ 3554 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0); 3555 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0)); 3556 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff); 3557 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0); 3558 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0)); 3559 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff); 3560 3561 /* end of video params */ 3562 3563 if ((bktr->xtal_pll_mode == BT848_USE_PLL) 3564 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) { 3565 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */ 3566 } else { 3567 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */ 3568 } 3569 3570 /* capture control */ 3571 switch (i_flag) { 3572 case 1: 3573 bktr->bktr_cap_ctl = 3574 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN); 3575 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20); 3576 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20); 3577 interlace = 1; 3578 break; 3579 case 2: 3580 bktr->bktr_cap_ctl = 3581 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD); 3582 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20); 3583 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20); 3584 interlace = 1; 3585 break; 3586 default: 3587 bktr->bktr_cap_ctl = 3588 (BT848_CAP_CTL_DITH_FRAME | 3589 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD); 3590 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20); 3591 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20); 3592 interlace = 2; 3593 break; 3594 } 3595 3596 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog)); 3597 3598 rows = bktr->rows; 3599 cols = bktr->cols; 3600 3601 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */ 3602 3603 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */ 3604 /* user, then use the rgb_vbi RISC program. */ 3605 /* Otherwise, use the normal rgb RISC program */ 3606 if (pf_int->public.type == METEOR_PIXTYPE_RGB) { 3607 if ( (bktr->vbiflags & VBI_OPEN) 3608 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI) 3609 ||(bktr->format_params == BT848_IFORM_F_SECAM) 3610 ){ 3611 bktr->bktr_cap_ctl |= 3612 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD; 3613 bktr->vbiflags |= VBI_CAPTURE; 3614 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace); 3615 return; 3616 } else { 3617 rgb_prog(bktr, i_flag, cols, rows, interlace); 3618 return; 3619 } 3620 } 3621 3622 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) { 3623 yuv422_prog(bktr, i_flag, cols, rows, interlace); 3624 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3625 | pixfmt_swap_flags( bktr->pixfmt )); 3626 return; 3627 } 3628 3629 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) { 3630 yuvpack_prog(bktr, i_flag, cols, rows, interlace); 3631 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3632 | pixfmt_swap_flags( bktr->pixfmt )); 3633 return; 3634 } 3635 3636 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) { 3637 yuv12_prog(bktr, i_flag, cols, rows, interlace); 3638 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3639 | pixfmt_swap_flags( bktr->pixfmt )); 3640 return; 3641 } 3642 return; 3643} 3644 3645 3646/****************************************************************************** 3647 * video & video capture specific routines: 3648 */ 3649 3650 3651/* 3652 * 3653 */ 3654static void 3655start_capture( bktr_ptr_t bktr, unsigned type ) 3656{ 3657 u_char i_flag; 3658 struct format_params *fp; 3659 3660 fp = &format_params[bktr->format_params]; 3661 3662 /* If requested, clear out capture buf first */ 3663 if (bktr->clr_on_start && (bktr->video.addr == 0)) { 3664 bzero((caddr_t)bktr->bigbuf, 3665 (size_t)bktr->rows * bktr->cols * bktr->frames * 3666 pixfmt_table[ bktr->pixfmt ].public.Bpp); 3667 } 3668 3669 OUTB(bktr, BKTR_DSTATUS, 0); 3670 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT)); 3671 3672 bktr->flags |= type; 3673 bktr->flags &= ~METEOR_WANT_MASK; 3674 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3675 case METEOR_ONLY_EVEN_FIELDS: 3676 bktr->flags |= METEOR_WANT_EVEN; 3677 i_flag = 1; 3678 break; 3679 case METEOR_ONLY_ODD_FIELDS: 3680 bktr->flags |= METEOR_WANT_ODD; 3681 i_flag = 2; 3682 break; 3683 default: 3684 bktr->flags |= METEOR_WANT_MASK; 3685 i_flag = 3; 3686 break; 3687 } 3688 3689 /* TDEC is only valid for continuous captures */ 3690 if ( type == METEOR_SINGLE ) { 3691 u_short fps_save = bktr->fps; 3692 3693 set_fps(bktr, fp->frame_rate); 3694 bktr->fps = fps_save; 3695 } 3696 else 3697 set_fps(bktr, bktr->fps); 3698 3699 if (bktr->dma_prog_loaded == FALSE) { 3700 build_dma_prog(bktr, i_flag); 3701 bktr->dma_prog_loaded = TRUE; 3702 } 3703 3704 3705 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog)); 3706 3707} 3708 3709 3710/* 3711 * 3712 */ 3713static void 3714set_fps( bktr_ptr_t bktr, u_short fps ) 3715{ 3716 struct format_params *fp; 3717 int i_flag; 3718 3719 fp = &format_params[bktr->format_params]; 3720 3721 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3722 case METEOR_ONLY_EVEN_FIELDS: 3723 bktr->flags |= METEOR_WANT_EVEN; 3724 i_flag = 1; 3725 break; 3726 case METEOR_ONLY_ODD_FIELDS: 3727 bktr->flags |= METEOR_WANT_ODD; 3728 i_flag = 1; 3729 break; 3730 default: 3731 bktr->flags |= METEOR_WANT_MASK; 3732 i_flag = 2; 3733 break; 3734 } 3735 3736 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 3737 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 3738 3739 bktr->fps = fps; 3740 OUTB(bktr, BKTR_TDEC, 0); 3741 3742 if (fps < fp->frame_rate) 3743 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f); 3744 else 3745 OUTB(bktr, BKTR_TDEC, 0); 3746 return; 3747 3748} 3749 3750 3751 3752 3753 3754/* 3755 * Given a pixfmt index, compute the bt848 swap_flags necessary to 3756 * achieve the specified swapping. 3757 * Note that without bt swapping, 2Bpp and 3Bpp modes are written 3758 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6 3759 * and read R->L). 3760 * Note also that for 3Bpp, we may additionally need to do some creative 3761 * SKIPing to align the FIFO bytelines with the target buffer (see split()). 3762 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR 3763 * as one would expect. 3764 */ 3765 3766static u_int pixfmt_swap_flags( int pixfmt ) 3767{ 3768 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public; 3769 u_int swapf = 0; 3770 3771 switch ( pf->Bpp ) { 3772 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP ); 3773 break; 3774 3775 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */ 3776 break; 3777 3778 case 4 : if ( pf->swap_bytes ) 3779 swapf = pf->swap_shorts ? 0 : WSWAP; 3780 else 3781 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP); 3782 break; 3783 } 3784 return swapf; 3785} 3786 3787 3788 3789/* 3790 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into 3791 * our pixfmt_table indices. 3792 */ 3793 3794static int oformat_meteor_to_bt( u_long format ) 3795{ 3796 int i; 3797 struct meteor_pixfmt *pf1, *pf2; 3798 3799 /* Find format in compatibility table */ 3800 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ ) 3801 if ( meteor_pixfmt_table[i].meteor_format == format ) 3802 break; 3803 3804 if ( i >= METEOR_PIXFMT_TABLE_SIZE ) 3805 return -1; 3806 pf1 = &meteor_pixfmt_table[i].public; 3807 3808 /* Match it with an entry in master pixel format table */ 3809 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) { 3810 pf2 = &pixfmt_table[i].public; 3811 3812 if (( pf1->type == pf2->type ) && 3813 ( pf1->Bpp == pf2->Bpp ) && 3814 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) && 3815 ( pf1->swap_bytes == pf2->swap_bytes ) && 3816 ( pf1->swap_shorts == pf2->swap_shorts )) 3817 break; 3818 } 3819 if ( i >= PIXFMT_TABLE_SIZE ) 3820 return -1; 3821 3822 return i; 3823} 3824 3825/****************************************************************************** 3826 * i2c primitives: 3827 */ 3828 3829/* */ 3830#define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */ 3831#define I2CBITTIME_878 (1 << 7) 3832#define I2C_READ 0x01 3833#define I2C_COMMAND (I2CBITTIME | \ 3834 BT848_DATA_CTL_I2CSCL | \ 3835 BT848_DATA_CTL_I2CSDA) 3836 3837#define I2C_COMMAND_878 (I2CBITTIME_878 | \ 3838 BT848_DATA_CTL_I2CSCL | \ 3839 BT848_DATA_CTL_I2CSDA) 3840 3841/* Select between old i2c code and new iicbus / smbus code */ 3842#if defined(BKTR_USE_FREEBSD_SMBUS) 3843 3844/* 3845 * The hardware interface is actually SMB commands 3846 */ 3847int 3848i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 ) 3849{ 3850 char cmd; 3851 3852 if (bktr->id == BROOKTREE_848 || 3853 bktr->id == BROOKTREE_848A || 3854 bktr->id == BROOKTREE_849A) 3855 cmd = I2C_COMMAND; 3856 else 3857 cmd = I2C_COMMAND_878; 3858 3859 if (byte2 != -1) { 3860 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd, 3861 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff)))) 3862 return (-1); 3863 } else { 3864 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd, 3865 (char)(byte1 & 0xff))) 3866 return (-1); 3867 } 3868 3869 /* return OK */ 3870 return( 0 ); 3871} 3872 3873int 3874i2cRead( bktr_ptr_t bktr, int addr ) 3875{ 3876 char result; 3877 char cmd; 3878 3879 if (bktr->id == BROOKTREE_848 || 3880 bktr->id == BROOKTREE_848A || 3881 bktr->id == BROOKTREE_849A) 3882 cmd = I2C_COMMAND; 3883 else 3884 cmd = I2C_COMMAND_878; 3885 3886 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result)) 3887 return (-1); 3888 3889 return ((int)((unsigned char)result)); 3890} 3891 3892#define IICBUS(bktr) ((bktr)->i2c_sc.iicbb) 3893 3894/* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */ 3895/* to 5 bytes which the bt848 automated i2c bus controller cannot handle */ 3896/* Therefore we need low level control of the i2c bus hardware */ 3897 3898/* Write to the MSP or DPL registers */ 3899void 3900msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data) 3901{ 3902 unsigned char addr_l, addr_h, data_h, data_l ; 3903 3904 addr_h = (addr >>8) & 0xff; 3905 addr_l = addr & 0xff; 3906 data_h = (data >>8) & 0xff; 3907 data_l = data & 0xff; 3908 3909 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */); 3910 3911 iicbus_write_byte(IICBUS(bktr), dev, 0); 3912 iicbus_write_byte(IICBUS(bktr), addr_h, 0); 3913 iicbus_write_byte(IICBUS(bktr), addr_l, 0); 3914 iicbus_write_byte(IICBUS(bktr), data_h, 0); 3915 iicbus_write_byte(IICBUS(bktr), data_l, 0); 3916 3917 iicbus_stop(IICBUS(bktr)); 3918 3919 return; 3920} 3921 3922/* Read from the MSP or DPL registers */ 3923unsigned int 3924msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr) 3925{ 3926 unsigned int data; 3927 unsigned char addr_l, addr_h, dev_r; 3928 int read; 3929 u_char data_read[2]; 3930 3931 addr_h = (addr >>8) & 0xff; 3932 addr_l = addr & 0xff; 3933 dev_r = dev+1; 3934 3935 /* XXX errors ignored */ 3936 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */); 3937 3938 iicbus_write_byte(IICBUS(bktr), dev_r, 0); 3939 iicbus_write_byte(IICBUS(bktr), addr_h, 0); 3940 iicbus_write_byte(IICBUS(bktr), addr_l, 0); 3941 3942 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */); 3943 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0); 3944 iicbus_stop(IICBUS(bktr)); 3945 3946 data = (data_read[0]<<8) | data_read[1]; 3947 3948 return (data); 3949} 3950 3951/* Reset the MSP or DPL chip */ 3952/* The user can block the reset (which is handy if you initialise the 3953 * MSP and/or DPL audio in another operating system first (eg in Windows) 3954 */ 3955void 3956msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) 3957{ 3958 3959#ifndef BKTR_NO_MSP_RESET 3960 /* put into reset mode */ 3961 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */); 3962 iicbus_write_byte(IICBUS(bktr), 0x00, 0); 3963 iicbus_write_byte(IICBUS(bktr), 0x80, 0); 3964 iicbus_write_byte(IICBUS(bktr), 0x00, 0); 3965 iicbus_stop(IICBUS(bktr)); 3966 3967 /* put back to operational mode */ 3968 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */); 3969 iicbus_write_byte(IICBUS(bktr), 0x00, 0); 3970 iicbus_write_byte(IICBUS(bktr), 0x00, 0); 3971 iicbus_write_byte(IICBUS(bktr), 0x00, 0); 3972 iicbus_stop(IICBUS(bktr)); 3973#endif 3974 return; 3975} 3976 3977static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) { 3978 int read; 3979 3980 /* XXX errors ignored */ 3981 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */); 3982 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0); 3983 iicbus_stop(IICBUS(bktr)); 3984 3985 return; 3986} 3987 3988#else /* defined(BKTR_USE_FREEBSD_SMBUS) */ 3989 3990/* 3991 * Program the i2c bus directly 3992 */ 3993int 3994i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 ) 3995{ 3996 u_long x; 3997 u_long data; 3998 3999 /* clear status bits */ 4000 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE); 4001 4002 /* build the command datum */ 4003 if (bktr->id == BROOKTREE_848 || 4004 bktr->id == BROOKTREE_848A || 4005 bktr->id == BROOKTREE_849A) { 4006 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND; 4007 } else { 4008 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878; 4009 } 4010 if ( byte2 != -1 ) { 4011 data |= ((byte2 & 0xff) << 8); 4012 data |= BT848_DATA_CTL_I2CW3B; 4013 } 4014 4015 /* write the address and data */ 4016 OUTL(bktr, BKTR_I2C_DATA_CTL, data); 4017 4018 /* wait for completion */ 4019 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 4020 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE ) 4021 break; 4022 } 4023 4024 /* check for ACK */ 4025 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) ) 4026 return( -1 ); 4027 4028 /* return OK */ 4029 return( 0 ); 4030} 4031 4032 4033/* 4034 * 4035 */ 4036int 4037i2cRead( bktr_ptr_t bktr, int addr ) 4038{ 4039 u_long x; 4040 4041 /* clear status bits */ 4042 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE); 4043 4044 /* write the READ address */ 4045 /* The Bt878 and Bt879 differed on the treatment of i2c commands */ 4046 4047 if (bktr->id == BROOKTREE_848 || 4048 bktr->id == BROOKTREE_848A || 4049 bktr->id == BROOKTREE_849A) { 4050 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND); 4051 } else { 4052 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878); 4053 } 4054 4055 /* wait for completion */ 4056 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 4057 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE ) 4058 break; 4059 } 4060 4061 /* check for ACK */ 4062 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) ) 4063 return( -1 ); 4064 4065 /* it was a read */ 4066 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff ); 4067} 4068 4069/* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */ 4070/* bt848 automated i2c bus controller cannot handle */ 4071/* Therefore we need low level control of the i2c bus hardware */ 4072/* Idea for the following functions are from elsewhere in this driver and */ 4073/* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */ 4074 4075#define BITD 40 4076static void i2c_start( bktr_ptr_t bktr) { 4077 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */ 4078 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */ 4079 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */ 4080 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */ 4081} 4082 4083static void i2c_stop( bktr_ptr_t bktr) { 4084 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */ 4085 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */ 4086 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */ 4087} 4088 4089static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) { 4090 int x; 4091 int status; 4092 4093 /* write out the byte */ 4094 for ( x = 7; x >= 0; --x ) { 4095 if ( data & (1<<x) ) { 4096 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4097 DELAY( BITD ); /* assert HI data */ 4098 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 4099 DELAY( BITD ); /* strobe clock */ 4100 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4101 DELAY( BITD ); /* release clock */ 4102 } 4103 else { 4104 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 4105 DELAY( BITD ); /* assert LO data */ 4106 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); 4107 DELAY( BITD ); /* strobe clock */ 4108 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 4109 DELAY( BITD ); /* release clock */ 4110 } 4111 } 4112 4113 /* look for an ACK */ 4114 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */ 4115 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */ 4116 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */ 4117 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */ 4118 4119 return( status ); 4120} 4121 4122static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) { 4123 int x; 4124 int bit; 4125 int byte = 0; 4126 4127 /* read in the byte */ 4128 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4129 DELAY( BITD ); /* float data */ 4130 for ( x = 7; x >= 0; --x ) { 4131 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 4132 DELAY( BITD ); /* strobe clock */ 4133 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */ 4134 if ( bit ) byte |= (1<<x); 4135 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4136 DELAY( BITD ); /* release clock */ 4137 } 4138 /* After reading the byte, send an ACK */ 4139 /* (unless that was the last byte, for which we send a NAK */ 4140 if (last) { /* send NAK - same a writing a 1 */ 4141 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4142 DELAY( BITD ); /* set data bit */ 4143 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 4144 DELAY( BITD ); /* strobe clock */ 4145 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4146 DELAY( BITD ); /* release clock */ 4147 } else { /* send ACK - same as writing a 0 */ 4148 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 4149 DELAY( BITD ); /* set data bit */ 4150 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); 4151 DELAY( BITD ); /* strobe clock */ 4152 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 4153 DELAY( BITD ); /* release clock */ 4154 } 4155 4156 *data=byte; 4157 return 0; 4158} 4159#undef BITD 4160 4161/* Write to the MSP or DPL registers */ 4162void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, 4163 unsigned int data){ 4164 unsigned int msp_w_addr = i2c_addr; 4165 unsigned char addr_l, addr_h, data_h, data_l ; 4166 addr_h = (addr >>8) & 0xff; 4167 addr_l = addr & 0xff; 4168 data_h = (data >>8) & 0xff; 4169 data_l = data & 0xff; 4170 4171 i2c_start(bktr); 4172 i2c_write_byte(bktr, msp_w_addr); 4173 i2c_write_byte(bktr, dev); 4174 i2c_write_byte(bktr, addr_h); 4175 i2c_write_byte(bktr, addr_l); 4176 i2c_write_byte(bktr, data_h); 4177 i2c_write_byte(bktr, data_l); 4178 i2c_stop(bktr); 4179} 4180 4181/* Read from the MSP or DPL registers */ 4182unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){ 4183 unsigned int data; 4184 unsigned char addr_l, addr_h, data_1, data_2, dev_r ; 4185 addr_h = (addr >>8) & 0xff; 4186 addr_l = addr & 0xff; 4187 dev_r = dev+1; 4188 4189 i2c_start(bktr); 4190 i2c_write_byte(bktr,i2c_addr); 4191 i2c_write_byte(bktr,dev_r); 4192 i2c_write_byte(bktr,addr_h); 4193 i2c_write_byte(bktr,addr_l); 4194 4195 i2c_start(bktr); 4196 i2c_write_byte(bktr,i2c_addr+1); 4197 i2c_read_byte(bktr,&data_1, 0); 4198 i2c_read_byte(bktr,&data_2, 1); 4199 i2c_stop(bktr); 4200 data = (data_1<<8) | data_2; 4201 return data; 4202} 4203 4204/* Reset the MSP or DPL chip */ 4205/* The user can block the reset (which is handy if you initialise the 4206 * MSP audio in another operating system first (eg in Windows) 4207 */ 4208void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) { 4209 4210#ifndef BKTR_NO_MSP_RESET 4211 /* put into reset mode */ 4212 i2c_start(bktr); 4213 i2c_write_byte(bktr, i2c_addr); 4214 i2c_write_byte(bktr, 0x00); 4215 i2c_write_byte(bktr, 0x80); 4216 i2c_write_byte(bktr, 0x00); 4217 i2c_stop(bktr); 4218 4219 /* put back to operational mode */ 4220 i2c_start(bktr); 4221 i2c_write_byte(bktr, i2c_addr); 4222 i2c_write_byte(bktr, 0x00); 4223 i2c_write_byte(bktr, 0x00); 4224 i2c_write_byte(bktr, 0x00); 4225 i2c_stop(bktr); 4226#endif 4227 return; 4228 4229} 4230 4231static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) { 4232 4233 /* XXX errors ignored */ 4234 i2c_start(bktr); 4235 i2c_write_byte(bktr,bktr->remote_control_addr); 4236 i2c_read_byte(bktr,&(remote->data[0]), 0); 4237 i2c_read_byte(bktr,&(remote->data[1]), 0); 4238 i2c_read_byte(bktr,&(remote->data[2]), 0); 4239 i2c_stop(bktr); 4240 4241 return; 4242} 4243 4244#endif /* defined(BKTR_USE_FREEBSD_SMBUS) */ 4245 4246 4247#if defined( I2C_SOFTWARE_PROBE ) 4248 4249/* 4250 * we are keeping this around for any parts that we need to probe 4251 * but that CANNOT be probed via an i2c read. 4252 * this is necessary because the hardware i2c mechanism 4253 * cannot be programmed for 1 byte writes. 4254 * currently there are no known i2c parts that we need to probe 4255 * and that cannot be safely read. 4256 */ 4257static int i2cProbe( bktr_ptr_t bktr, int addr ); 4258#define BITD 40 4259#define EXTRA_START 4260 4261/* 4262 * probe for an I2C device at addr. 4263 */ 4264static int 4265i2cProbe( bktr_ptr_t bktr, int addr ) 4266{ 4267 int x, status; 4268 4269 /* the START */ 4270#if defined( EXTRA_START ) 4271 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */ 4272 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */ 4273#endif /* EXTRA_START */ 4274 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */ 4275 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */ 4276 4277 /* write addr */ 4278 for ( x = 7; x >= 0; --x ) { 4279 if ( addr & (1<<x) ) { 4280 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4281 DELAY( BITD ); /* assert HI data */ 4282 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 4283 DELAY( BITD ); /* strobe clock */ 4284 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 4285 DELAY( BITD ); /* release clock */ 4286 } 4287 else { 4288 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 4289 DELAY( BITD ); /* assert LO data */ 4290 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); 4291 DELAY( BITD ); /* strobe clock */ 4292 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 4293 DELAY( BITD ); /* release clock */ 4294 } 4295 } 4296 4297 /* look for an ACK */ 4298 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */ 4299 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */ 4300 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */ 4301 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */ 4302 4303 /* the STOP */ 4304 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */ 4305 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */ 4306 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */ 4307 4308 return( status ); 4309} 4310#undef EXTRA_START 4311#undef BITD 4312 4313#endif /* I2C_SOFTWARE_PROBE */ 4314 4315 4316#define ABSENT (-1) 4317 4318#endif /* FreeBSD, BSDI, NetBSD, OpenBSD */ 4319 4320