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