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