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