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