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