1 /* $OpenBSD: bktr_core.c,v 1.26 2007/11/26 09:28:34 martynas 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 #include <sys/stdint.h> /* uintptr_t */ 104 105 #include <dev/rndvar.h> 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%x\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 add_video_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 add_video_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 #else 657 if (bktr->vbi_select.si_selpid) { 658 #endif 659 selwakeup(&bktr->vbi_select); 660 } 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 = (struct proc *)0; 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 int 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 ((int) uio->uio_iov->iov_len < 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(BKTR_SLEEP, BKTRPRI, "captur", 0); 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 int 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(VBI_SLEEP, VBIPRI, "vbi", 0))) { 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 = (int)uio->uio_iov->iov_len; 1070 1071 if (readsize > bktr->vbisize) readsize = bktr->vbisize; 1072 1073 /* Check if we can read this number of bytes without having 1074 * to wrap around the circular buffer */ 1075 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) { 1076 /* We need to wrap around */ 1077 1078 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart; 1079 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio); 1080 status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio); 1081 } else { 1082 /* We do not need to wrap around */ 1083 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio); 1084 } 1085 1086 /* Update the number of bytes left to read */ 1087 bktr->vbisize -= readsize; 1088 1089 /* Update vbistart */ 1090 bktr->vbistart += readsize; 1091 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */ 1092 1093 return( status ); 1094 1095 } 1096 1097 1098 1099 /* 1100 * video ioctls 1101 */ 1102 int 1103 video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr ) 1104 { 1105 volatile u_char c_temp; 1106 unsigned int temp; 1107 unsigned int temp_iform; 1108 unsigned int error; 1109 struct meteor_geomet *geo; 1110 struct meteor_counts *counts; 1111 struct meteor_video *video; 1112 struct bktr_capture_area *cap_area; 1113 vaddr_t buf; 1114 int i; 1115 char char_temp; 1116 1117 switch ( cmd ) { 1118 1119 case BT848SCLIP: /* set clip region */ 1120 bktr->max_clip_node = 0; 1121 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list)); 1122 1123 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) { 1124 if (bktr->clip_list[i].y_min == 0 && 1125 bktr->clip_list[i].y_max == 0) 1126 break; 1127 } 1128 bktr->max_clip_node = i; 1129 1130 /* make sure that the list contains a valid clip secquence */ 1131 /* the clip rectangles should be sorted by x then by y as the 1132 second order sort key */ 1133 1134 /* clip rectangle list is terminated by y_min and y_max set to 0 */ 1135 1136 /* to disable clipping set y_min and y_max to 0 in the first 1137 clip rectangle . The first clip rectangle is clip_list[0]. 1138 */ 1139 1140 if (bktr->max_clip_node == 0 && 1141 (bktr->clip_list[0].y_min != 0 && 1142 bktr->clip_list[0].y_max != 0)) { 1143 return EINVAL; 1144 } 1145 1146 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) { 1147 if (bktr->clip_list[i].y_min == 0 && 1148 bktr->clip_list[i].y_max == 0) { 1149 break; 1150 } 1151 if ( bktr->clip_list[i+1].y_min != 0 && 1152 bktr->clip_list[i+1].y_max != 0 && 1153 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) { 1154 1155 bktr->max_clip_node = 0; 1156 return (EINVAL); 1157 1158 } 1159 1160 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max || 1161 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max || 1162 bktr->clip_list[i].x_min < 0 || 1163 bktr->clip_list[i].x_max < 0 || 1164 bktr->clip_list[i].y_min < 0 || 1165 bktr->clip_list[i].y_max < 0 ) { 1166 bktr->max_clip_node = 0; 1167 return (EINVAL); 1168 } 1169 } 1170 1171 bktr->dma_prog_loaded = FALSE; 1172 1173 break; 1174 1175 case METEORSTATUS: /* get Bt848 status */ 1176 c_temp = INB(bktr, BKTR_DSTATUS); 1177 temp = 0; 1178 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK; 1179 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT; 1180 *(u_short *)arg = temp; 1181 break; 1182 1183 case BT848SFMT: /* set input format */ 1184 temp = *(unsigned int *)arg & BT848_IFORM_FORMAT; 1185 temp_iform = INB(bktr, BKTR_IFORM); 1186 temp_iform &= ~BT848_IFORM_FORMAT; 1187 temp_iform &= ~BT848_IFORM_XTSEL; 1188 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel)); 1189 switch( temp ) { 1190 case BT848_IFORM_F_AUTO: 1191 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1192 METEOR_AUTOMODE; 1193 break; 1194 1195 case BT848_IFORM_F_NTSCM: 1196 case BT848_IFORM_F_NTSCJ: 1197 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1198 METEOR_NTSC; 1199 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay); 1200 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay); 1201 bktr->format_params = temp; 1202 break; 1203 1204 case BT848_IFORM_F_PALBDGHI: 1205 case BT848_IFORM_F_PALN: 1206 case BT848_IFORM_F_SECAM: 1207 case BT848_IFORM_F_RSVD: 1208 case BT848_IFORM_F_PALM: 1209 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1210 METEOR_PAL; 1211 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay); 1212 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay); 1213 bktr->format_params = temp; 1214 break; 1215 1216 } 1217 bktr->dma_prog_loaded = FALSE; 1218 break; 1219 1220 case METEORSFMT: /* set input format */ 1221 temp_iform = INB(bktr, BKTR_IFORM); 1222 temp_iform &= ~BT848_IFORM_FORMAT; 1223 temp_iform &= ~BT848_IFORM_XTSEL; 1224 switch(*(unsigned int *)arg & METEOR_FORM_MASK ) { 1225 case 0: /* default */ 1226 case METEOR_FMT_NTSC: 1227 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1228 METEOR_NTSC; 1229 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM | 1230 format_params[BT848_IFORM_F_NTSCM].iform_xtsel); 1231 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay); 1232 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay); 1233 bktr->format_params = BT848_IFORM_F_NTSCM; 1234 break; 1235 1236 case METEOR_FMT_PAL: 1237 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1238 METEOR_PAL; 1239 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI | 1240 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel); 1241 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay); 1242 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay); 1243 bktr->format_params = BT848_IFORM_F_PALBDGHI; 1244 break; 1245 1246 case METEOR_FMT_AUTOMODE: 1247 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1248 METEOR_AUTOMODE; 1249 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO | 1250 format_params[BT848_IFORM_F_AUTO].iform_xtsel); 1251 break; 1252 1253 default: 1254 return( EINVAL ); 1255 } 1256 bktr->dma_prog_loaded = FALSE; 1257 break; 1258 1259 case METEORGFMT: /* get input format */ 1260 *(u_int *)arg = bktr->flags & METEOR_FORM_MASK; 1261 break; 1262 1263 1264 case BT848GFMT: /* get input format */ 1265 *(u_int *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT; 1266 break; 1267 1268 case METEORSCOUNT: /* (re)set error counts */ 1269 counts = (struct meteor_counts *) arg; 1270 bktr->fifo_errors = counts->fifo_errors; 1271 bktr->dma_errors = counts->dma_errors; 1272 bktr->frames_captured = counts->frames_captured; 1273 bktr->even_fields_captured = counts->even_fields_captured; 1274 bktr->odd_fields_captured = counts->odd_fields_captured; 1275 break; 1276 1277 case METEORGCOUNT: /* get error counts */ 1278 counts = (struct meteor_counts *) arg; 1279 counts->fifo_errors = bktr->fifo_errors; 1280 counts->dma_errors = bktr->dma_errors; 1281 counts->frames_captured = bktr->frames_captured; 1282 counts->even_fields_captured = bktr->even_fields_captured; 1283 counts->odd_fields_captured = bktr->odd_fields_captured; 1284 break; 1285 1286 case METEORGVIDEO: 1287 video = (struct meteor_video *)arg; 1288 video->addr = bktr->video.addr; 1289 video->width = bktr->video.width; 1290 video->banksize = bktr->video.banksize; 1291 video->ramsize = bktr->video.ramsize; 1292 break; 1293 1294 case METEORSVIDEO: 1295 video = (struct meteor_video *)arg; 1296 bktr->video.addr = video->addr; 1297 bktr->video.width = video->width; 1298 bktr->video.banksize = video->banksize; 1299 bktr->video.ramsize = video->ramsize; 1300 break; 1301 1302 case METEORSFPS: 1303 set_fps(bktr, *(u_short *)arg); 1304 break; 1305 1306 case METEORGFPS: 1307 *(u_short *)arg = bktr->fps; 1308 break; 1309 1310 case METEORSHUE: /* set hue */ 1311 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff); 1312 break; 1313 1314 case METEORGHUE: /* get hue */ 1315 *(u_char *)arg = INB(bktr, BKTR_HUE); 1316 break; 1317 1318 case METEORSBRIG: /* set brightness */ 1319 char_temp = ( *(u_char *)arg & 0xff) - 128; 1320 OUTB(bktr, BKTR_BRIGHT, char_temp); 1321 1322 break; 1323 1324 case METEORGBRIG: /* get brightness */ 1325 *(u_char *)arg = INB(bktr, BKTR_BRIGHT) + 128; 1326 break; 1327 1328 case METEORSCSAT: /* set chroma saturation */ 1329 temp = (int)*(u_char *)arg; 1330 1331 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff); 1332 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff); 1333 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) 1334 & ~(BT848_E_CONTROL_SAT_U_MSB 1335 | BT848_E_CONTROL_SAT_V_MSB)); 1336 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) 1337 & ~(BT848_O_CONTROL_SAT_U_MSB | 1338 BT848_O_CONTROL_SAT_V_MSB)); 1339 1340 if ( temp & BIT_SEVEN_HIGH ) { 1341 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) 1342 | (BT848_E_CONTROL_SAT_U_MSB 1343 | BT848_E_CONTROL_SAT_V_MSB)); 1344 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) 1345 | (BT848_O_CONTROL_SAT_U_MSB 1346 | BT848_O_CONTROL_SAT_V_MSB)); 1347 } 1348 break; 1349 1350 case METEORGCSAT: /* get chroma saturation */ 1351 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff; 1352 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB ) 1353 temp |= BIT_SEVEN_HIGH; 1354 *(u_char *)arg = (u_char)temp; 1355 break; 1356 1357 case METEORSCONT: /* set contrast */ 1358 temp = (int)*(u_char *)arg & 0xff; 1359 temp <<= 1; 1360 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff); 1361 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB); 1362 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB); 1363 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | 1364 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB)); 1365 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | 1366 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB)); 1367 break; 1368 1369 case METEORGCONT: /* get contrast */ 1370 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff; 1371 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6; 1372 *(u_char *)arg = (u_char)((temp >> 1) & 0xff); 1373 break; 1374 1375 case BT848SCBUF: /* set Clear-Buffer-on-start flag */ 1376 bktr->clr_on_start = (*(int *)arg != 0); 1377 break; 1378 1379 case BT848GCBUF: /* get Clear-Buffer-on-start flag */ 1380 *(int *)arg = (int) bktr->clr_on_start; 1381 break; 1382 1383 case METEORSSIGNAL: 1384 if(*(int *)arg == 0 || *(int *)arg >= NSIG) { 1385 return( EINVAL ); 1386 break; 1387 } 1388 bktr->signal = *(int *) arg; 1389 bktr->proc = pr; 1390 break; 1391 1392 case METEORGSIGNAL: 1393 *(int *)arg = bktr->signal; 1394 break; 1395 1396 case METEORCAPTUR: 1397 temp = bktr->flags; 1398 switch (*(int *) arg) { 1399 case METEOR_CAP_SINGLE: 1400 1401 if (bktr->bigbuf==0) /* no frame buffer allocated */ 1402 return( ENOMEM ); 1403 /* already capturing */ 1404 if (temp & METEOR_CAP_MASK) 1405 return( EIO ); 1406 1407 1408 1409 start_capture(bktr, METEOR_SINGLE); 1410 1411 /* wait for capture to complete */ 1412 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 1413 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1414 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1415 1416 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1417 BT848_INT_RISCI | 1418 BT848_INT_VSYNC | 1419 BT848_INT_FMTCHG); 1420 1421 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 1422 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz); 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 temp = tv_channel( bktr, (int)*(unsigned int *)arg ); 1736 if ( temp < 0 ) { 1737 temp_mute( bktr, FALSE ); 1738 return( EINVAL ); 1739 } 1740 *(unsigned int *)arg = temp; 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 temp = tv_freq( bktr, (int)*(unsigned int *)arg, TV_FREQUENCY); 1777 temp_mute( bktr, FALSE ); 1778 if ( temp < 0 ) { 1779 temp_mute( bktr, FALSE ); 1780 return( EINVAL ); 1781 } 1782 *(unsigned int *)arg = temp; 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 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY ); 2057 temp_mute( bktr, FALSE ); 2058 #ifdef BKTR_RADIO_DEBUG 2059 if(temp) 2060 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp); 2061 #endif 2062 if ( temp < 0 ) 2063 return( EINVAL ); 2064 *(unsigned long *)arg = temp; 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 (1 << 28) 2365 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29) 2366 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30) 2367 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 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 = 1 << 6 | 1 << 4 | 1 << 2 | 3; 2868 bktr->capcontrol = 3 << 2 | 3; 2869 2870 dma_prog = (u_int *) bktr->dma_prog; 2871 2872 /* Construct Write */ 2873 2874 /* write , sol, eol */ 2875 inst = OP_WRITE | OP_SOL | (cols); 2876 /* write , sol, eol */ 2877 inst3 = OP_WRITE | OP_EOL | (cols); 2878 2879 if (bktr->video.addr) 2880 target_buffer = bktr->video.addr; 2881 else 2882 target_buffer = bktr->dm_mem->dm_segs->ds_addr; 2883 2884 buffer = target_buffer; 2885 2886 /* contruct sync : for video packet format */ 2887 /* sync, mode indicator packed data */ 2888 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1); 2889 *dma_prog++ = htole32(0); /* NULL WORD */ 2890 2891 b = cols; 2892 2893 for (i = 0; i < (rows/interlace); i++) { 2894 *dma_prog++ = htole32(inst); 2895 *dma_prog++ = htole32(target_buffer); 2896 *dma_prog++ = htole32(inst3); 2897 *dma_prog++ = htole32(target_buffer + b); 2898 target_buffer += interlace*(cols * 2); 2899 } 2900 2901 switch (i_flag) { 2902 case 1: 2903 /* sync vre */ 2904 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); 2905 *dma_prog++ = htole32(0); /* NULL WORD */ 2906 *dma_prog++ = htole32(OP_JUMP); 2907 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 2908 return; 2909 2910 case 2: 2911 /* sync vro */ 2912 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); 2913 *dma_prog++ = htole32(0); /* NULL WORD */ 2914 *dma_prog++ = htole32(OP_JUMP); 2915 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 2916 return; 2917 2918 case 3: 2919 /* sync vro */ 2920 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO); 2921 *dma_prog++ = htole32(0); /* NULL WORD */ 2922 *dma_prog++ = htole32(OP_JUMP); 2923 *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr); 2924 break; 2925 } 2926 2927 if (interlace == 2) { 2928 2929 target_buffer = buffer + cols*2; 2930 2931 dma_prog = (u_int * ) bktr->odd_dma_prog; 2932 2933 /* sync vre */ 2934 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1); 2935 *dma_prog++ = htole32(0); /* NULL WORD */ 2936 2937 for (i = 0; i < (rows/interlace) ; i++) { 2938 *dma_prog++ = htole32(inst); 2939 *dma_prog++ = htole32(target_buffer); 2940 *dma_prog++ = htole32(inst3); 2941 *dma_prog++ = htole32(target_buffer + b); 2942 target_buffer += interlace * ( cols*2); 2943 } 2944 } 2945 2946 /* sync vro IRQ bit */ 2947 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE); 2948 *dma_prog++ = htole32(0); /* NULL WORD */ 2949 *dma_prog++ = htole32(OP_JUMP); 2950 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 2951 2952 *dma_prog++ = htole32(OP_JUMP); 2953 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 2954 *dma_prog++ = htole32(0); /* NULL WORD */ 2955 } 2956 2957 2958 /* 2959 * 2960 */ 2961 static void 2962 yuv422_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace) 2963 { 2964 int i; 2965 u_int inst; 2966 u_int target_buffer, t1, buffer; 2967 u_int *dma_prog; 2968 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2969 2970 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 2971 2972 dma_prog = (u_int *) bktr->dma_prog; 2973 2974 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 2975 2976 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 2977 OUTB(bktr, BKTR_OFORM, 0x00); 2978 2979 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */ 2980 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC); 2981 2982 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */ 2983 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC); 2984 2985 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */ 2986 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80); 2987 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */ 2988 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40); 2989 2990 /* disable gamma correction removal */ 2991 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA); 2992 2993 /* Construct Write */ 2994 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 2995 if (bktr->video.addr) 2996 target_buffer = (u_int) bktr->video.addr; 2997 else 2998 target_buffer = bktr->dm_mem->dm_segs->ds_addr; 2999 3000 buffer = target_buffer; 3001 3002 t1 = buffer; 3003 3004 /* contruct sync : for video packet format */ 3005 /* sync, mode indicator packed data*/ 3006 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); 3007 *dma_prog++ = htole32(0); /* NULL WORD */ 3008 3009 for (i = 0; i < (rows/interlace ) ; i++) { 3010 *dma_prog++ = htole32(inst); 3011 *dma_prog++ = htole32(cols/2 | cols/2 << 16); 3012 *dma_prog++ = htole32(target_buffer); 3013 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace); 3014 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + 3015 i*cols/2 * interlace); 3016 target_buffer += interlace*cols; 3017 } 3018 3019 switch (i_flag) { 3020 case 1: 3021 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/ 3022 *dma_prog++ = htole32(0); /* NULL WORD */ 3023 3024 *dma_prog++ = htole32(OP_JUMP); 3025 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 3026 return; 3027 3028 case 2: 3029 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vre*/ 3030 *dma_prog++ = htole32(0); /* NULL WORD */ 3031 3032 *dma_prog++ = htole32(OP_JUMP); 3033 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 3034 return; 3035 3036 case 3: 3037 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO); 3038 *dma_prog++ = htole32(0); /* NULL WORD */ 3039 3040 *dma_prog++ = htole32(OP_JUMP); 3041 *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr); 3042 break; 3043 } 3044 3045 if (interlace == 2) { 3046 3047 dma_prog = (u_int * ) bktr->odd_dma_prog; 3048 3049 target_buffer = (u_int) buffer + cols; 3050 t1 = buffer + cols/2; 3051 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); 3052 *dma_prog++ = htole32(0); /* NULL WORD */ 3053 3054 for (i = 0; i < (rows/interlace ) ; i++) { 3055 *dma_prog++ = htole32(inst); 3056 *dma_prog++ = htole32(cols/2 | cols/2 << 16); 3057 *dma_prog++ = htole32(target_buffer); 3058 *dma_prog++ = htole32(t1 + (cols*rows) + 3059 i*cols/2 * interlace); 3060 *dma_prog++ = htole32(t1 + (cols*rows) + 3061 (cols*rows/2) + i*cols/2 * interlace); 3062 target_buffer += interlace*cols; 3063 } 3064 } 3065 3066 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE); 3067 *dma_prog++ = htole32(0); /* NULL WORD */ 3068 *dma_prog++ = htole32(OP_JUMP); 3069 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 3070 *dma_prog++ = htole32(0); /* NULL WORD */ 3071 } 3072 3073 3074 /* 3075 * 3076 */ 3077 static void 3078 yuv12_prog( bktr_ptr_t bktr, char i_flag, 3079 int cols, int rows, int interlace ){ 3080 3081 int i; 3082 u_int inst; 3083 u_int inst1; 3084 u_int target_buffer, t1, buffer; 3085 u_int *dma_prog; 3086 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3087 3088 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 3089 3090 dma_prog = (u_int *) bktr->dma_prog; 3091 3092 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 3093 3094 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 3095 OUTB(bktr, BKTR_OFORM, 0x0); 3096 3097 /* Construct Write */ 3098 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 3099 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols); 3100 if (bktr->video.addr) 3101 target_buffer = (u_int) bktr->video.addr; 3102 else 3103 target_buffer = bktr->dm_mem->dm_segs->ds_addr; 3104 3105 buffer = target_buffer; 3106 t1 = buffer; 3107 3108 /* sync, mode indicator packed data*/ 3109 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); 3110 *dma_prog++ = htole32(0); /* NULL WORD */ 3111 3112 for (i = 0; i < (rows/interlace )/2 ; i++) { 3113 *dma_prog++ = htole32(inst); 3114 *dma_prog++ = htole32(cols/2 | (cols/2 << 16)); 3115 *dma_prog++ = htole32(target_buffer); 3116 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace); 3117 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + 3118 i*cols/2 * interlace); 3119 target_buffer += interlace*cols; 3120 *dma_prog++ = htole32(inst1); 3121 *dma_prog++ = htole32(cols/2 | (cols/2 << 16)); 3122 *dma_prog++ = htole32(target_buffer); 3123 target_buffer += interlace*cols; 3124 3125 } 3126 3127 switch (i_flag) { 3128 case 1: 3129 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/ 3130 *dma_prog++ = htole32(0); /* NULL WORD */ 3131 3132 *dma_prog++ = htole32(OP_JUMP); 3133 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 3134 return; 3135 3136 case 2: 3137 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vro*/ 3138 *dma_prog++ = htole32(0); /* NULL WORD */ 3139 3140 *dma_prog++ = htole32(OP_JUMP); 3141 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 3142 return; 3143 3144 case 3: 3145 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO); 3146 *dma_prog++ = htole32(0); /* NULL WORD */ 3147 *dma_prog++ = htole32(OP_JUMP); 3148 *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr); 3149 break; 3150 } 3151 3152 if (interlace == 2) { 3153 3154 dma_prog = (u_int *)bktr->odd_dma_prog; 3155 3156 target_buffer = (u_int) buffer + cols; 3157 t1 = buffer + cols/2; 3158 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); 3159 *dma_prog++ = htole32(0); /* NULL WORD */ 3160 3161 for (i = 0; i < ((rows/interlace )/2 ) ; i++) { 3162 *dma_prog++ = htole32(inst); 3163 *dma_prog++ = htole32(cols/2 | (cols/2 << 16)); 3164 *dma_prog++ = htole32(target_buffer); 3165 *dma_prog++ = htole32(t1 + (cols*rows) + 3166 i*cols/2 * interlace); 3167 *dma_prog++ = htole32(t1 + (cols*rows) + 3168 (cols*rows/4) + i*cols/2 * interlace); 3169 target_buffer += interlace*cols; 3170 *dma_prog++ = htole32(inst1); 3171 *dma_prog++ = htole32(cols/2 | (cols/2 << 16)); 3172 *dma_prog++ = htole32(target_buffer); 3173 target_buffer += interlace*cols; 3174 } 3175 } 3176 3177 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE); 3178 *dma_prog++ = htole32(0); /* NULL WORD */ 3179 *dma_prog++ = htole32(OP_JUMP); 3180 *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr); 3181 *dma_prog++ = htole32(0); /* NULL WORD */ 3182 } 3183 3184 3185 /* 3186 * 3187 */ 3188 static void 3189 build_dma_prog( bktr_ptr_t bktr, char i_flag ) 3190 { 3191 int rows, cols, interlace; 3192 int tmp_int; 3193 unsigned int temp; 3194 const struct format_params *fp; 3195 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3196 3197 3198 fp = &format_params[bktr->format_params]; 3199 3200 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 3201 3202 /* disable FIFO & RISC, leave other bits alone */ 3203 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED); 3204 3205 /* set video parameters */ 3206 if (bktr->capture_area_enabled) 3207 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096 3208 / fp->scaled_htotal / bktr->cols) - 4096; 3209 else 3210 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096 3211 / fp->scaled_htotal / bktr->cols) - 4096; 3212 3213 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */ 3214 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff); 3215 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff); 3216 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff); 3217 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff); 3218 3219 /* horizontal active */ 3220 temp = bktr->cols; 3221 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */ 3222 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff); 3223 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff); 3224 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3); 3225 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3); 3226 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3)); 3227 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3)); 3228 3229 /* horizontal delay */ 3230 if (bktr->capture_area_enabled) 3231 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal) 3232 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive); 3233 else 3234 temp = (fp->hdelay * bktr->cols) / fp->hactive; 3235 3236 temp = temp & 0x3fe; 3237 3238 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */ 3239 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff); 3240 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff); 3241 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc); 3242 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc); 3243 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc)); 3244 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc)); 3245 3246 /* vertical scale */ 3247 3248 if (bktr->capture_area_enabled) { 3249 if (bktr->flags & METEOR_ONLY_ODD_FIELDS || 3250 bktr->flags & METEOR_ONLY_EVEN_FIELDS) 3251 tmp_int = 65536 - 3252 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512); 3253 else { 3254 tmp_int = 65536 - 3255 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512); 3256 } 3257 } else { 3258 if (bktr->flags & METEOR_ONLY_ODD_FIELDS || 3259 bktr->flags & METEOR_ONLY_EVEN_FIELDS) 3260 tmp_int = 65536 - 3261 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512); 3262 else { 3263 tmp_int = 65536 - 3264 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512); 3265 } 3266 } 3267 3268 tmp_int &= 0x1fff; 3269 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */ 3270 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff); 3271 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff); 3272 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f); 3273 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f); 3274 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f)); 3275 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f)); 3276 3277 3278 /* vertical active */ 3279 if (bktr->capture_area_enabled) 3280 temp = bktr->capture_area_y_size; 3281 else 3282 temp = fp->vactive; 3283 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */ 3284 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30); 3285 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30)); 3286 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff); 3287 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30); 3288 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30)); 3289 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff); 3290 3291 /* vertical delay */ 3292 if (bktr->capture_area_enabled) 3293 temp = fp->vdelay + (bktr->capture_area_y_offset); 3294 else 3295 temp = fp->vdelay; 3296 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */ 3297 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0); 3298 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0)); 3299 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff); 3300 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0); 3301 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0)); 3302 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff); 3303 3304 /* end of video params */ 3305 3306 if ((bktr->xtal_pll_mode == BT848_USE_PLL) 3307 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) { 3308 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */ 3309 } else { 3310 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */ 3311 } 3312 3313 /* capture control */ 3314 switch (i_flag) { 3315 case 1: 3316 bktr->bktr_cap_ctl = 3317 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN); 3318 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20); 3319 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20); 3320 interlace = 1; 3321 break; 3322 case 2: 3323 bktr->bktr_cap_ctl = 3324 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD); 3325 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20); 3326 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20); 3327 interlace = 1; 3328 break; 3329 default: 3330 bktr->bktr_cap_ctl = 3331 (BT848_CAP_CTL_DITH_FRAME | 3332 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD); 3333 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20); 3334 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20); 3335 interlace = 2; 3336 break; 3337 } 3338 3339 OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr); 3340 3341 rows = bktr->rows; 3342 cols = bktr->cols; 3343 3344 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */ 3345 3346 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */ 3347 /* user, then use the rgb_vbi RISC program. */ 3348 /* Otherwise, use the normal rgb RISC program */ 3349 if (pf_int->public.type == METEOR_PIXTYPE_RGB) { 3350 if ( (bktr->vbiflags & VBI_OPEN) 3351 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI) 3352 ||(bktr->format_params == BT848_IFORM_F_SECAM) 3353 ){ 3354 bktr->bktr_cap_ctl |= 3355 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD; 3356 bktr->vbiflags |= VBI_CAPTURE; 3357 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace); 3358 return; 3359 } else { 3360 rgb_prog(bktr, i_flag, cols, rows, interlace); 3361 return; 3362 } 3363 } 3364 3365 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) { 3366 yuv422_prog(bktr, i_flag, cols, rows, interlace); 3367 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3368 | pixfmt_swap_flags( bktr->pixfmt )); 3369 return; 3370 } 3371 3372 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) { 3373 yuvpack_prog(bktr, i_flag, cols, rows, interlace); 3374 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3375 | pixfmt_swap_flags( bktr->pixfmt )); 3376 return; 3377 } 3378 3379 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) { 3380 yuv12_prog(bktr, i_flag, cols, rows, interlace); 3381 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3382 | pixfmt_swap_flags( bktr->pixfmt )); 3383 return; 3384 } 3385 return; 3386 } 3387 3388 3389 /****************************************************************************** 3390 * video & video capture specific routines: 3391 */ 3392 3393 3394 /* 3395 * 3396 */ 3397 static void 3398 start_capture( bktr_ptr_t bktr, unsigned type ) 3399 { 3400 u_char i_flag; 3401 const struct format_params *fp; 3402 3403 fp = &format_params[bktr->format_params]; 3404 3405 /* If requested, clear out capture buf first */ 3406 if (bktr->clr_on_start && (bktr->video.addr == 0)) { 3407 bzero((caddr_t)bktr->bigbuf, 3408 (size_t)bktr->rows * bktr->cols * bktr->frames * 3409 pixfmt_table[ bktr->pixfmt ].public.Bpp); 3410 } 3411 3412 OUTB(bktr, BKTR_DSTATUS, 0); 3413 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT)); 3414 3415 bktr->flags |= type; 3416 bktr->flags &= ~METEOR_WANT_MASK; 3417 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3418 case METEOR_ONLY_EVEN_FIELDS: 3419 bktr->flags |= METEOR_WANT_EVEN; 3420 i_flag = 1; 3421 break; 3422 case METEOR_ONLY_ODD_FIELDS: 3423 bktr->flags |= METEOR_WANT_ODD; 3424 i_flag = 2; 3425 break; 3426 default: 3427 bktr->flags |= METEOR_WANT_MASK; 3428 i_flag = 3; 3429 break; 3430 } 3431 3432 /* TDEC is only valid for continuous captures */ 3433 if ( type == METEOR_SINGLE ) { 3434 u_short fps_save = bktr->fps; 3435 3436 set_fps(bktr, fp->frame_rate); 3437 bktr->fps = fps_save; 3438 } 3439 else 3440 set_fps(bktr, bktr->fps); 3441 3442 if (bktr->dma_prog_loaded == FALSE) { 3443 build_dma_prog(bktr, i_flag); 3444 bktr->dma_prog_loaded = TRUE; 3445 } 3446 3447 3448 OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr); 3449 } 3450 3451 3452 /* 3453 * 3454 */ 3455 static void 3456 set_fps( bktr_ptr_t bktr, u_short fps ) 3457 { 3458 const struct format_params *fp; 3459 int i_flag; 3460 3461 fp = &format_params[bktr->format_params]; 3462 3463 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3464 case METEOR_ONLY_EVEN_FIELDS: 3465 bktr->flags |= METEOR_WANT_EVEN; 3466 i_flag = 1; 3467 break; 3468 case METEOR_ONLY_ODD_FIELDS: 3469 bktr->flags |= METEOR_WANT_ODD; 3470 i_flag = 1; 3471 break; 3472 default: 3473 bktr->flags |= METEOR_WANT_MASK; 3474 i_flag = 2; 3475 break; 3476 } 3477 3478 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 3479 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 3480 3481 bktr->fps = fps; 3482 OUTB(bktr, BKTR_TDEC, 0); 3483 3484 if (fps < fp->frame_rate) 3485 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f); 3486 else 3487 OUTB(bktr, BKTR_TDEC, 0); 3488 return; 3489 3490 } 3491 3492 3493 3494 3495 3496 /* 3497 * Given a pixfmt index, compute the bt848 swap_flags necessary to 3498 * achieve the specified swapping. 3499 * Note that without bt swapping, 2Bpp and 3Bpp modes are written 3500 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6 3501 * and read R->L). 3502 * Note also that for 3Bpp, we may additionally need to do some creative 3503 * SKIPing to align the FIFO bytelines with the target buffer (see split()). 3504 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR 3505 * as one would expect. 3506 */ 3507 3508 static u_int pixfmt_swap_flags( int pixfmt ) 3509 { 3510 const struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public; 3511 u_int swapf = 0; 3512 int swap_bytes, swap_shorts; 3513 3514 #if BYTE_ORDER == LITTLE_ENDIAN 3515 swap_bytes = pf->swap_bytes; 3516 swap_shorts = pf->swap_shorts; 3517 #else 3518 swap_bytes = !pf->swap_bytes; 3519 swap_shorts = !pf->swap_shorts; 3520 #endif 3521 3522 switch ( pf->Bpp ) { 3523 case 2: 3524 swapf = swap_bytes ? 0 : BSWAP; 3525 break; 3526 3527 case 3: /* no swaps supported for 3bpp - makes no sense w/ bt848 */ 3528 break; 3529 3530 case 4: 3531 swapf = swap_bytes ? 0 : BSWAP; 3532 swapf |= swap_shorts ? 0 : WSWAP; 3533 break; 3534 } 3535 return swapf; 3536 } 3537 3538 3539 3540 /* 3541 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into 3542 * our pixfmt_table indices. 3543 */ 3544 3545 static int oformat_meteor_to_bt( u_int format ) 3546 { 3547 int i; 3548 const struct meteor_pixfmt *pf1, *pf2; 3549 3550 /* Find format in compatibility table */ 3551 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ ) 3552 if ( meteor_pixfmt_table[i].meteor_format == format ) 3553 break; 3554 3555 if ( i >= METEOR_PIXFMT_TABLE_SIZE ) 3556 return -1; 3557 pf1 = &meteor_pixfmt_table[i].public; 3558 3559 /* Match it with an entry in master pixel format table */ 3560 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) { 3561 pf2 = &pixfmt_table[i].public; 3562 3563 if (( pf1->type == pf2->type ) && 3564 ( pf1->Bpp == pf2->Bpp ) && 3565 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) && 3566 ( pf1->swap_bytes == pf2->swap_bytes ) && 3567 ( pf1->swap_shorts == pf2->swap_shorts )) 3568 break; 3569 } 3570 if ( i >= PIXFMT_TABLE_SIZE ) 3571 return -1; 3572 3573 return i; 3574 } 3575 3576 /****************************************************************************** 3577 * i2c primitives: 3578 */ 3579 3580 /* */ 3581 #define I2CBITTIME (0x5) /* 5 * 0.48uS */ 3582 #define I2CBITTIME_878 (0x8) 3583 #define I2C_READ 0x01 3584 #define I2C_COMMAND ((I2CBITTIME << 4) | \ 3585 BT848_DATA_CTL_I2CSCL | \ 3586 BT848_DATA_CTL_I2CSDA) 3587 3588 #define I2C_COMMAND_878 ((I2CBITTIME_878 << 4) | \ 3589 BT848_DATA_CTL_I2CSCL | \ 3590 BT848_DATA_CTL_I2CSDA) 3591 3592 /* 3593 * Program the i2c bus directly 3594 */ 3595 int 3596 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 ) 3597 { 3598 u_int x; 3599 u_int data; 3600 3601 /* clear status bits */ 3602 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE); 3603 3604 /* build the command datum */ 3605 if (bktr->id == BROOKTREE_848 || 3606 bktr->id == BROOKTREE_848A || 3607 bktr->id == BROOKTREE_849A) { 3608 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND; 3609 } else { 3610 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878; 3611 } 3612 if ( byte2 != -1 ) { 3613 data |= ((byte2 & 0xff) << 8); 3614 data |= BT848_DATA_CTL_I2CW3B; 3615 } 3616 3617 /* write the address and data */ 3618 OUTL(bktr, BKTR_I2C_DATA_CTL, data); 3619 3620 /* wait for completion */ 3621 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 3622 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE ) 3623 break; 3624 } 3625 3626 /* check for ACK */ 3627 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) ) 3628 return( -1 ); 3629 3630 /* return OK */ 3631 return( 0 ); 3632 } 3633 3634 3635 /* 3636 * 3637 */ 3638 int 3639 i2cRead( bktr_ptr_t bktr, int addr ) 3640 { 3641 u_int32_t x, stat; 3642 3643 /* clear status bits */ 3644 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE); 3645 3646 /* write the READ address */ 3647 /* The Bt878 and Bt879 differed on the treatment of i2c commands */ 3648 3649 if (bktr->id == BROOKTREE_848 || 3650 bktr->id == BROOKTREE_848A || 3651 bktr->id == BROOKTREE_849A) 3652 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND); 3653 else 3654 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878); 3655 3656 /* wait for completion */ 3657 for (x = 5000; x--; DELAY(1)) /* 5 msec, safety valve */ 3658 if ((stat = INL(bktr, BKTR_INT_STAT)) & BT848_INT_I2CDONE) 3659 break; 3660 3661 /* check for ACK */ 3662 if ((stat & (I2C_BITS)) != (I2C_BITS)) 3663 return (-1); 3664 3665 /* it was a read */ 3666 x = INL(bktr, BKTR_I2C_DATA_CTL); 3667 return ((x >> 8) & 0xff); 3668 } 3669 3670 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */ 3671 /* bt848 automated i2c bus controller cannot handle */ 3672 /* Therefore we need low level control of the i2c bus hardware */ 3673 /* Idea for the following functions are from elsewhere in this driver and */ 3674 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */ 3675 3676 #define BITD 40 3677 static void i2c_start( bktr_ptr_t bktr) { 3678 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */ 3679 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */ 3680 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */ 3681 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */ 3682 } 3683 3684 static void i2c_stop( bktr_ptr_t bktr) { 3685 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */ 3686 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */ 3687 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */ 3688 } 3689 3690 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) { 3691 int x; 3692 int status; 3693 3694 /* write out the byte */ 3695 for ( x = 7; x >= 0; --x ) { 3696 if ( data & (1<<x) ) { 3697 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3698 DELAY( BITD ); /* assert HI data */ 3699 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 3700 DELAY( BITD ); /* strobe clock */ 3701 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3702 DELAY( BITD ); /* release clock */ 3703 } 3704 else { 3705 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 3706 DELAY( BITD ); /* assert LO data */ 3707 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); 3708 DELAY( BITD ); /* strobe clock */ 3709 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 3710 DELAY( BITD ); /* release clock */ 3711 } 3712 } 3713 3714 /* look for an ACK */ 3715 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */ 3716 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */ 3717 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */ 3718 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */ 3719 3720 return( status ); 3721 } 3722 3723 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) { 3724 int x; 3725 int bit; 3726 int byte = 0; 3727 3728 /* read in the byte */ 3729 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3730 DELAY( BITD ); /* float data */ 3731 for ( x = 7; x >= 0; --x ) { 3732 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 3733 DELAY( BITD ); /* strobe clock */ 3734 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */ 3735 if ( bit ) byte |= (1<<x); 3736 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3737 DELAY( BITD ); /* release clock */ 3738 } 3739 /* After reading the byte, send an ACK */ 3740 /* (unless that was the last byte, for which we send a NAK */ 3741 if (last) { /* send NAK - same a writing a 1 */ 3742 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3743 DELAY( BITD ); /* set data bit */ 3744 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 3745 DELAY( BITD ); /* strobe clock */ 3746 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3747 DELAY( BITD ); /* release clock */ 3748 } else { /* send ACK - same as writing a 0 */ 3749 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 3750 DELAY( BITD ); /* set data bit */ 3751 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); 3752 DELAY( BITD ); /* strobe clock */ 3753 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 3754 DELAY( BITD ); /* release clock */ 3755 } 3756 3757 *data=byte; 3758 return 0; 3759 } 3760 #undef BITD 3761 3762 /* Write to the MSP or DPL registers */ 3763 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, 3764 unsigned int data){ 3765 unsigned int msp_w_addr = i2c_addr; 3766 unsigned char addr_l, addr_h, data_h, data_l ; 3767 addr_h = (addr >>8) & 0xff; 3768 addr_l = addr & 0xff; 3769 data_h = (data >>8) & 0xff; 3770 data_l = data & 0xff; 3771 3772 i2c_start(bktr); 3773 i2c_write_byte(bktr, msp_w_addr); 3774 i2c_write_byte(bktr, dev); 3775 i2c_write_byte(bktr, addr_h); 3776 i2c_write_byte(bktr, addr_l); 3777 i2c_write_byte(bktr, data_h); 3778 i2c_write_byte(bktr, data_l); 3779 i2c_stop(bktr); 3780 } 3781 3782 /* Read from the MSP or DPL registers */ 3783 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){ 3784 unsigned int data; 3785 unsigned char addr_l, addr_h, data_1, data_2, dev_r ; 3786 addr_h = (addr >>8) & 0xff; 3787 addr_l = addr & 0xff; 3788 dev_r = dev+1; 3789 3790 i2c_start(bktr); 3791 i2c_write_byte(bktr,i2c_addr); 3792 i2c_write_byte(bktr,dev_r); 3793 i2c_write_byte(bktr,addr_h); 3794 i2c_write_byte(bktr,addr_l); 3795 3796 i2c_start(bktr); 3797 i2c_write_byte(bktr,i2c_addr+1); 3798 i2c_read_byte(bktr,&data_1, 0); 3799 i2c_read_byte(bktr,&data_2, 1); 3800 i2c_stop(bktr); 3801 data = (data_1<<8) | data_2; 3802 return data; 3803 } 3804 3805 /* Reset the MSP or DPL chip */ 3806 /* The user can block the reset (which is handy if you initialise the 3807 * MSP audio in another operating system first (eg in Windows) 3808 */ 3809 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) { 3810 3811 #ifndef BKTR_NO_MSP_RESET 3812 /* put into reset mode */ 3813 i2c_start(bktr); 3814 i2c_write_byte(bktr, i2c_addr); 3815 i2c_write_byte(bktr, 0x00); 3816 i2c_write_byte(bktr, 0x80); 3817 i2c_write_byte(bktr, 0x00); 3818 i2c_stop(bktr); 3819 3820 /* put back to operational mode */ 3821 i2c_start(bktr); 3822 i2c_write_byte(bktr, i2c_addr); 3823 i2c_write_byte(bktr, 0x00); 3824 i2c_write_byte(bktr, 0x00); 3825 i2c_write_byte(bktr, 0x00); 3826 i2c_stop(bktr); 3827 #endif 3828 return; 3829 3830 } 3831 3832 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) { 3833 3834 /* XXX errors ignored */ 3835 i2c_start(bktr); 3836 i2c_write_byte(bktr,bktr->remote_control_addr); 3837 i2c_read_byte(bktr,&(remote->data[0]), 0); 3838 i2c_read_byte(bktr,&(remote->data[1]), 0); 3839 i2c_read_byte(bktr,&(remote->data[2]), 0); 3840 i2c_stop(bktr); 3841 3842 return; 3843 } 3844 3845 #if defined( I2C_SOFTWARE_PROBE ) 3846 3847 /* 3848 * we are keeping this around for any parts that we need to probe 3849 * but that CANNOT be probed via an i2c read. 3850 * this is necessary because the hardware i2c mechanism 3851 * cannot be programmed for 1 byte writes. 3852 * currently there are no known i2c parts that we need to probe 3853 * and that cannot be safely read. 3854 */ 3855 static int i2cProbe( bktr_ptr_t bktr, int addr ); 3856 #define BITD 40 3857 #define EXTRA_START 3858 3859 /* 3860 * probe for an I2C device at addr. 3861 */ 3862 static int 3863 i2cProbe( bktr_ptr_t bktr, int addr ) 3864 { 3865 int x, status; 3866 3867 /* the START */ 3868 #if defined( EXTRA_START ) 3869 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */ 3870 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */ 3871 #endif /* EXTRA_START */ 3872 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */ 3873 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */ 3874 3875 /* write addr */ 3876 for ( x = 7; x >= 0; --x ) { 3877 if ( addr & (1<<x) ) { 3878 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3879 DELAY( BITD ); /* assert HI data */ 3880 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); 3881 DELAY( BITD ); /* strobe clock */ 3882 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); 3883 DELAY( BITD ); /* release clock */ 3884 } 3885 else { 3886 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 3887 DELAY( BITD ); /* assert LO data */ 3888 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); 3889 DELAY( BITD ); /* strobe clock */ 3890 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); 3891 DELAY( BITD ); /* release clock */ 3892 } 3893 } 3894 3895 /* look for an ACK */ 3896 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */ 3897 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */ 3898 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */ 3899 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */ 3900 3901 /* the STOP */ 3902 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */ 3903 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */ 3904 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */ 3905 3906 return( status ); 3907 } 3908 #undef EXTRA_START 3909 #undef BITD 3910 3911 #endif /* I2C_SOFTWARE_PROBE */ 3912