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