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