1/* BT848 1.24 Driver for Brooktree's Bt848 based cards. 2 The Brooktree BT848 Driver driver is based upon Mark Tinguely and 3 Jim Lowe's driver for the Matrox Meteor PCI card . The 4 Philips SAA 7116 and SAA 7196 are very different chipsets than 5 the BT848. For starters, the BT848 is a one chipset solution and 6 it incorporates a RISC engine to control the DMA transfers -- 7 that is it the actual dma process is control by a program which 8 resides in the hosts memory also the register definitions between 9 the Philips chipsets and the Bt848 are very different. 10 11 The original copyright notice by Mark and Jim is included mostly 12 to honor their fantastic work in the Matrox Meteor driver! 13 14 Enjoy, 15 Amancio 16 17 */ 18 19/* 20 * 1. Redistributions of source code must retain the 21 * Copyright (c) 1997 Amancio Hasty 22 * All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. All advertising materials mentioning features or use of this software 33 * must display the following acknowledgement: 34 * This product includes software developed by Amancio Hasty 35 * 4. The name of the author may not be used to endorse or promote products 36 * derived from this software without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 39 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 40 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 41 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 44 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 47 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 48 * POSSIBILITY OF SUCH DAMAGE. 49 */ 50 51 52 53 54/* 55 * 1. Redistributions of source code must retain the 56 * Copyright (c) 1995 Mark Tinguely and Jim Lowe 57 * All rights reserved. 58 * 59 * Redistribution and use in source and binary forms, with or without 60 * modification, are permitted provided that the following conditions 61 * are met: 62 * 1. Redistributions of source code must retain the above copyright 63 * notice, this list of conditions and the following disclaimer. 64 * 2. Redistributions in binary form must reproduce the above copyright 65 * notice, this list of conditions and the following disclaimer in the 66 * documentation and/or other materials provided with the distribution. 67 * 3. All advertising materials mentioning features or use of this software 68 * must display the following acknowledgement: 69 * This product includes software developed by Mark Tinguely and Jim Lowe 70 * 4. The name of the author may not be used to endorse or promote products 71 * derived from this software without specific prior written permission. 72 * 73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 74 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 75 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 76 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 77 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 79 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 81 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 82 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 83 * POSSIBILITY OF SUCH DAMAGE. 84 */ 85 86/* Change History: 871.0 1/24/97 First Alpha release 88 891.1 2/20/97 Added video ioctl so we can do PCI To PCI 90 data transfers. This is for capturing data 91 directly to a vga frame buffer which has 92 a linear frame buffer. Minor code clean-up. 93 941.3 2/23/97 Fixed system lock-up reported by 95 Randall Hopper <rhh@ct.picker.com>. This 96 problem seems somehow to be exhibited only 97 in his system. I changed the setting of 98 INT_MASK for CAP_CONTINUOUS to be exactly 99 the same as CAP_SINGLE apparently setting 100 bit 23 cleared the system lock up. 101 version 1.1 of the driver has been reported 102 to work with STB's WinTv, Hauppage's Wincast/Tv 103 and last but not least with the Intel Smart 104 Video Recorder. 105 1061.4 3/9/97 fsmp@freefall.org 107 Merged code to support tuners on STB and WinCast 108 cards. 109 Modifications to the contrast and chroma ioctls. 110 Textual cleanup. 111 1121.5 3/15/97 fsmp@freefall.org 113 new bt848 specific versions of hue/bright/ 114 contrast/satu/satv. 115 Amancio's patch to fix "screen freeze" problem. 116 1171.6 3/19/97 fsmp@freefall.org 118 new table-driven frequency lookup. 119 removed disable_intr()/enable_intr() calls from i2c. 120 misc. cleanup. 121 1221.7 3/19/97 fsmp@freefall.org 123 added audio support submitted by: 124 Michael Petry <petry@netwolf.NetMasters.com> 125 1261.8 3/20/97 fsmp@freefall.org 127 extended audio support. 128 card auto-detection. 129 major cleanup, order of routines, declarations, etc. 130 1311.9 3/22/97 fsmp@freefall.org 132 merged in Amancio's minor unit for tuner control 133 mods. 134 misc. cleanup, especially in the _intr routine. 135 made AUDIO_SUPPORT mainline code. 136 1371.10 3/23/97 fsmp@freefall.org 138 added polled hardware i2c routines, 139 removed all existing software i2c routines. 140 created software i2cProbe() routine. 141 Randall Hopper's fixes of BT848_GHUE & BT848_GBRIG. 142 eeprom support. 143 1441.11 3/24/97 fsmp@freefall.org 145 Louis Mamakos's new bt848 struct. 146 1471.12 3/25/97 fsmp@freefall.org 148 japanese freq table from Naohiro Shichijo. 149 new table structs for tuner lookups. 150 major scrub for "magic numbers". 151 1521.13 3/28/97 fsmp@freefall.org 153 1st PAL support. 154 MAGIC_[1-4] demarcates magic #s needing PAL work. 155 AFC code submitted by Richard Tobin 156 <richard@cogsci.ed.ac.uk>. 157 1581.14 3/29/97 richard@cogsci.ed.ac.uk 159 PAL support: magic numbers moved into 160 format_params structure. 161 Revised AFC interface. 162 fixed DMA_PROG_ALLOC size misdefinition. 163 1641.15 4/18/97 John-Mark Gurney <gurney_j@resnet.uoregon.edu> 165 Added [SR]RGBMASKs ioctl for byte swapping. 166 1671.16 4/20/97 Randall Hopper <rhh@ct.picker.com> 168 Generalized RGBMASK ioctls for general pixel 169 format setting [SG]ACTPIXFMT, and added query API 170 to return driver-supported pix fmts GSUPPIXFMT. 171 1721.17 4/21/97 hasty@rah.star-gate.com 173 Clipping support added. 174 1751.18 4/23/97 Clean up after failed CAP_SINGLEs where bt 176 interrupt isn't delivered, and fixed fixing 177 CAP_SINGLEs that for ODD_ONLY fields. 1781.19 9/8/97 improved yuv support , cleaned up weurope 179 channel table, incorporated cleanup work from 180 Luigi, fixed pci interface bug due to a 181 change in the pci interface which disables 182 interrupts from a PCI device by default, 183 Added Luigi's, ioctl's BT848_SLNOTCH, 184 BT848_GLNOTCH (set luma notch and get luma not) 1851.20 10/5/97 Keith Sklower <sklower@CS.Berkeley.EDU> submitted 186 a patch to fix compilation of the BSDI's PCI 187 interface. 188 Hideyuki Suzuki <hideyuki@sat.t.u-tokyo.ac.jp> 189 Submitted a patch for Japanese cable channels 190 Joao Carlos Mendes Luis jonny@gta.ufrj.br 191 Submitted general ioctl to set video broadcast 192 formats (PAL, NTSC, etc..) previously we depended 193 on the Bt848 auto video detect feature. 1941.21 10/24/97 Randall Hopper <rhh@ct.picker.com> 195 Fix temporal decimation, disable it when 196 doing CAP_SINGLEs, and in dual-field capture, don't 197 capture fields for different frames 1981.22 11/08/97 Randall Hopper <rhh@ct.picker.com> 199 Fixes for packed 24bpp - FIFO alignment 2001.23 11/17/97 Amancio <hasty@star-gate.com> 201 Added yuv support mpeg encoding 2021.24 12/27/97 Jonathan Hanna <pangolin@rogers.wave.ca> 203 Patch to support Philips FR1236MK2 tuner
|
204
|
2041.25 02/02/98 Takeshi Ohashi 205 <ohashi@atohasi.mickey.ai.kyutech.ac.jp> submitted 206 code to support bktr_read . 207 Flemming Jacobsen <fj@schizo.dk.tfs.com> 208 submitted code to support radio available with in 209 some bt848 based cards;additionally, wrote code to 210 correctly recognized his bt848 card. 211 Roger Hardiman <roger@cs.strath.ac.uk> submitted 212 various fixes to smooth out the microcode and made 213 all modes consistent. |
214*/ 215 216#define DDB(x) x 217#define DEB(x) 218 219#ifdef __FreeBSD__ 220#include "bktr.h"
|
212#include "opt_devfs.h"
|
221#include "pci.h" 222#endif /* __FreeBSD__ */ 223 224#if !defined(__FreeBSD__) || (NBKTR > 0 && NPCI > 0) 225 226#include <sys/param.h> 227#include <sys/systm.h> 228#include <sys/conf.h> 229#include <sys/uio.h> 230#include <sys/kernel.h> 231#include <sys/signalvar.h> 232#include <sys/mman.h> 233 234#include <vm/vm.h> 235#include <vm/vm_kern.h> 236#include <vm/pmap.h> 237#include <vm/vm_extern.h> 238 239#ifdef __FreeBSD__ 240#ifdef DEVFS 241#include <sys/devfsext.h> 242#endif /* DEVFS */ 243#include <machine/clock.h> 244#include <pci/pcivar.h> 245#include <pci/pcireg.h> 246 247#include <machine/ioctl_meteor.h> 248#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 249#include <pci/brktree_reg.h> 250 251typedef int ioctl_cmd_t; 252#endif /* __FreeBSD__ */ 253 254#ifdef __bsdi__ 255#include <sys/device.h> 256#include <i386/isa/isa.h> 257#include <i386/isa/isavar.h> 258#include <i386/isa/icu.h> 259#include <i386/pci/pci.h> 260#include <i386/isa/dma.h> 261#include <i386/eisa/eisa.h> 262#include "ioctl_meteor.h" 263#include "ioctl_bt848.h" 264#include "bt848_reg.h" 265 266typedef u_long ioctl_cmd_t; 267 268#define pci_conf_read(a, r) pci_inl(a, r) 269#define pci_conf_write(a, r, v) pci_outl(a, r, v) 270#include <sys/reboot.h> 271#define bootverbose (autoprint & (AC_VERBOSE|AC_DEBUG)) 272#endif /* __bsdi__ */ 273 274typedef u_char bool_t; 275 276#define BKTRPRI (PZERO+8)|PCATCH 277 278static void bktr_intr __P((void *arg)); 279 280 281/* 282 * memory allocated for DMA programs 283 */ 284#define DMA_PROG_ALLOC (8 * PAGE_SIZE) 285 286/* When to split a dma transfer , the bt848 has timing as well as 287 dma transfer size limitations so that we have to split dma 288 transfers into two dma requests 289 */ 290#define DMA_BT848_SPLIT 319*2 291 292/* 293 * Allocate enough memory for: 294 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages 295 * 296 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value" 297 * in your kernel configuration file. 298 */ 299 300#ifndef BROOKTREE_ALLOC_PAGES 301#define BROOKTREE_ALLOC_PAGES 217*4 302#endif 303#define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE) 304 305/* Defines for fields */ 306#define ODD_F 0x01 307#define EVEN_F 0x02 308 309#ifdef __FreeBSD__ 310 311static bktr_reg_t brooktree[ NBKTR ]; 312#define BROOKTRE_NUM(mtr) ((bktr - &brooktree[0])/sizeof(bktr_reg_t)) 313 314#define UNIT(x) ((x) & 0x0f) 315#define MINOR(x) ((x >> 4) & 0x0f) 316#define ATTACH_ARGS pcici_t tag, int unit 317 318static char* bktr_probe( pcici_t tag, pcidi_t type ); 319static void bktr_attach( ATTACH_ARGS ); 320 321static u_long bktr_count; 322 323static struct pci_device bktr_device = { 324 "bktr", 325 bktr_probe, 326 bktr_attach, 327 &bktr_count 328}; 329 330DATA_SET (pcidevice_set, bktr_device); 331 332static d_open_t bktr_open; 333static d_close_t bktr_close; 334static d_read_t bktr_read; 335static d_write_t bktr_write; 336static d_ioctl_t bktr_ioctl; 337static d_mmap_t bktr_mmap; 338 339#define CDEV_MAJOR 79 340static struct cdevsw bktr_cdevsw = 341{ 342 bktr_open, bktr_close, bktr_read, bktr_write, 343 bktr_ioctl, nostop, nullreset, nodevtotty, 344 seltrue, bktr_mmap, NULL, "bktr", 345 NULL, -1 346}; 347#endif /* __FreeBSD__ */ 348 349#ifdef __bsdi__ 350#define UNIT dv_unit 351#define MINOR dv_subunit 352#define ATTACH_ARGS \ 353 struct device * const parent, struct device * const self, void * const aux 354 355#define PCI_COMMAND_STATUS_REG PCI_COMMAND 356 357static void bktr_attach( ATTACH_ARGS ); 358#define NBKTR bktrcd.cd_ndevs 359#define brooktree *((bktr_ptr_t *)bktrcd.cd_devs) 360 361static int bktr_spl; 362static int bktr_intr_returning_1(void *arg) { bktr_intr(arg); return (1);} 363#define disable_intr() { bktr_spl = splhigh(); } 364#define enable_intr() { splx(bktr_spl); } 365 366static int 367bktr_pci_match(pci_devaddr_t *pa) 368{ 369 unsigned id; 370 371 id = pci_inl(pa, PCI_VENDOR_ID); 372 if (id != BROOKTREE_848_ID) { 373 aprint_debug("bktr_pci_match got %x\n", id); 374 return 0; 375 } 376 return 1; 377} 378 379pci_devres_t bktr_res; /* XXX only remembers last one, helps debug */ 380 381static int 382bktr_probe(struct device *parent, struct cfdata *cf, void *aux) 383{ 384 pci_devaddr_t *pa; 385 pci_devres_t res; 386 struct isa_attach_args *ia = aux; 387 388 if (ia->ia_bustype != BUS_PCI) 389 return (0); 390 391 if ((pa = pci_scan(bktr_pci_match)) == NULL) 392 return (0); 393 394 pci_getres(pa, &bktr_res, 1, ia); 395 if (ia->ia_maddr == 0) { 396 printf("bktr%d: no mem attached\n", cf->cf_unit); 397 return (0); 398 } 399 ia->ia_aux = pa; 400 return 1; 401} 402 403 404struct cfdriver bktrcd = 405{ 0, "bktr", bktr_probe, bktr_attach, DV_DULL, sizeof(bktr_reg_t) }; 406 407int bktr_open __P((dev_t, int, int, struct proc *)); 408int bktr_close __P((dev_t, int, int, struct proc *)); 409int bktr_read __P((dev_t, struct uio *, int)); 410int bktr_write __P((dev_t, struct uio *, int)); 411int bktr_ioctl __P((dev_t, ioctl_cmd_t, caddr_t, int, struct proc *)); 412int bktr_mmap __P((dev_t, int, int)); 413 414struct devsw bktrsw = { 415 &bktrcd, 416 bktr_open, bktr_close, bktr_read, bktr_write, bktr_ioctl, 417 seltrue, bktr_mmap, NULL, nodump, NULL, 0, nostop 418}; 419#endif /* __bsdi__ */ 420 421/* 422 * This is for start-up convenience only, NOT mandatory. 423 */ 424#if !defined( DEFAULT_CHNLSET ) 425#define DEFAULT_CHNLSET CHNLSET_WEUROPE 426#endif 427 428/* 429 * Parameters describing size of transmitted image. 430 */ 431 432static struct format_params format_params[] = { 433/* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
|
426 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, 0 },
|
434 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, 0 }, |
435/* # define BT848_IFORM_F_NTSCM (0x1) */
|
428 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0 },
|
436 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0 }, |
437/* # define BT848_IFORM_F_NTSCJ (0x2) */ 438 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0 }, 439/* # define BT848_IFORM_F_PALBDGHI (0x3) */ 440 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1 }, 441/* # define BT848_IFORM_F_PALM (0x4) */ 442 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0 }, 443/*{ 625, 32, 576, 910, 186, 922, 640, 780, 25, 0x68, 0x5d, BT848_IFORM_X_XT0 }, */ 444/* # define BT848_IFORM_F_PALN (0x5) */ 445 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1 }, 446/* # define BT848_IFORM_F_SECAM (0x6) */ 447 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x00, BT848_IFORM_X_XT1 }, 448/* # define BT848_IFORM_F_RSVD (0x7) - ???? */ 449 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0 }, 450}; 451 452/* 453 * Table of supported Pixel Formats 454 */ 455 456static struct meteor_pixfmt_internal { 457 struct meteor_pixfmt public; 458 u_int color_fmt; 459} pixfmt_table[] = { 460 461{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 }, 462{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 }, 463 464{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 }, 465{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 }, 466 467{ { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 }, 468 469{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 }, 470{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 }, 471{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 }, 472{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 }, 473{ { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 }, 474{ { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 }, 475{ { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 }, 476 477}; 478#define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) ) 479 480/* 481 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility) 482 */ 483 484/* FIXME: Also add YUV_422 and YUV_PACKED as well */ 485static struct { 486 u_long meteor_format; 487 struct meteor_pixfmt public; 488} meteor_pixfmt_table[] = {
|
489 { METEOR_GEO_YUV_12, 490 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 } 491 }, |
492 493 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */ 494 { METEOR_GEO_YUV_422, 495 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 } 496 }, 497 { METEOR_GEO_YUV_PACKED, 498 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 } 499 }, 500 { METEOR_GEO_RGB16, 501 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 } 502 }, 503 { METEOR_GEO_RGB24, 504 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 } 505 }, 506 507}; 508#define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \ 509 sizeof(meteor_pixfmt_table[0]) ) 510 511 512#define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN) 513#define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN) 514 515 516/* experimental code for Automatic Frequency Control */ 517#define TUNER_AFC 518#define TEST_TUNER_AFC_NOT 519 520#if defined( TUNER_AFC ) 521#define AFC_DELAY 10000 /* 10 millisend delay */ 522#define AFC_BITS 0x07 523#define AFC_FREQ_MINUS_125 0x00 524#define AFC_FREQ_MINUS_62 0x01 525#define AFC_FREQ_CENTERED 0x02 526#define AFC_FREQ_PLUS_62 0x03 527#define AFC_FREQ_PLUS_125 0x04 528#define AFC_MAX_STEP (5 * FREQFACTOR) /* no more than 5 MHz */ 529#endif /* TUNER_AFC */ 530 531/* 532 * i2c things: 533 */ 534 535/* PLL on a Temic NTSC tuner: 4032FY5 */ 536#define TEMIC_NTSC_WADDR 0xc0 537#define TEMIC_NTSC_RADDR 0xc1 538 539/* PLL on a Temic PAL I tuner: 4062FY5 */ 540#define TEMIC_PALI_WADDR 0xc2 541#define TEMIC_PALI_RADDR 0xc3 542 543/* PLL on a Philips tuner */ 544#define PHILIPS_NTSC_WADDR 0xc6 545#define PHILIPS_NTSC_RADDR 0xc7 546 547/* PLL on a the Philips FR1236MK2 tuner */ 548#define PHILIPS_FR1236_NTSC_WADDR 0xc2 549#define PHILIPS_FR1236_NTSC_RADDR 0xc3 550 551/* guaranteed address for any TSA5522/3 (PLL on all(?) tuners) */ 552#define TSA552x_WADDR 0xc2 553#define TSA552x_RADDR 0xc3 554
|
555#define PHILIPS_PAL_WADDR 0xc2 556#define PHILIPS_PAL_RADDR 0xc3 557 558 |
559#define TSA552x_CB_MSB (0x80) 560#define TSA552x_CB_CP (1<<6) 561#define TSA552x_CB_T2 (1<<5) 562#define TSA552x_CB_T1 (1<<4) 563#define TSA552x_CB_T0 (1<<3) 564#define TSA552x_CB_RSA (1<<2) 565#define TSA552x_CB_RSB (1<<1) 566#define TSA552x_CB_OS (1<<0)
|
567#define TSA552x_RADIO (TSA552x_CB_MSB | \ 568 TSA552x_CB_T0) |
569
|
570/* Add RADIO_OFFSET to the "frequency" to indicate that we want to tune */ 571/* the radio (if present) not the TV tuner. */ 572/* 20000 is equivalent to 20000MHz/16 = 1.25GHz - this area is unused. */ 573#define RADIO_OFFSET 20000 |
574
|
575 |
576/* address of BTSC/SAP decoder chip */ 577#define TDA9850_WADDR 0xb6 578#define TDA9850_RADDR 0xb7 579 580/* address of MSP3400C chip */ 581#define MSP3400C_WADDR 0x80 582#define MSP3400C_RADDR 0x81 583 584 585/* EEProm (128 * 8) on an STB card */ 586#define X24C01_WADDR 0xae 587#define X24C01_RADDR 0xaf 588 589 590/* EEProm (256 * 8) on a Hauppauge card */ 591#define PFC8582_WADDR 0xa0 592#define PFC8582_RADDR 0xa1 593 594 595/* registers in the BTSC/dbx chip */ 596#define CON1ADDR 0x04 597#define CON2ADDR 0x05 598#define CON3ADDR 0x06 599#define CON4ADDR 0x07 600 601 602/* raise the charge pump voltage for fast tuning */ 603#define TSA552x_FCONTROL (TSA552x_CB_MSB | \ 604 TSA552x_CB_CP | \ 605 TSA552x_CB_T0 | \ 606 TSA552x_CB_RSA | \ 607 TSA552x_CB_RSB) 608 609/* lower the charge pump voltage for better residual oscillator FM */ 610#define TSA552x_SCONTROL (TSA552x_CB_MSB | \ 611 TSA552x_CB_T0 | \ 612 TSA552x_CB_RSA | \ 613 TSA552x_CB_RSB) 614 615/* sync detect threshold */ 616#if 0 617#define SYNC_LEVEL (BT848_ADC_RESERVED | \ 618 BT848_ADC_CRUSH) /* threshold ~125 mV */ 619#else 620#define SYNC_LEVEL (BT848_ADC_RESERVED | \ 621 BT848_ADC_SYNC_T) /* threshold ~75 mV */ 622#endif 623 624 625/* the GPIO bits that control the audio MUXes */ 626#define GPIO_AUDIOMUX_BITS 0x0f 627 628 629/* debug utility for holding previous INT_STAT contents */ 630#define STATUS_SUM 631static u_long status_sum = 0; 632 633/* 634 * defines to make certain bit-fiddles understandable 635 */ 636#define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN 637#define RISC_ENABLED BT848_DMA_CTL_RISC_EN 638#define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN) 639#define FIFO_RISC_DISABLED 0 640 641#define ALL_INTS_DISABLED 0 642#define ALL_INTS_CLEARED 0xffffffff 643#define CAPTURE_OFF 0 644 645#define BIT_SEVEN_HIGH (1<<7) 646#define BIT_EIGHT_HIGH (1<<8) 647 648#define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE) 649#define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS) 650 651 652/* 653 * misc. support routines. 654 */ 655static const struct CARDTYPE cards[]; 656static const struct TUNER tuners[]; 657static int signCard( bktr_ptr_t bktr, int offset, 658 int count, u_char* sig ); 659static void probeCard( bktr_ptr_t bktr, int verbose ); 660 661static vm_offset_t get_bktr_mem( int unit, unsigned size ); 662 663static int oformat_meteor_to_bt( u_long format ); 664 665static u_int pixfmt_swap_flags( int pixfmt ); 666 667/* 668 * bt848 RISC programming routines. 669 */ 670#ifdef BT848_DUMP 671static int dump_bt848( bt848_ptr_t bt848 ); 672#endif 673 674static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols, 675 int rows, int interlace ); 676static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols, 677 int rows, int interlace );
|
678static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols, 679 int rows, int interlace ); |
680static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, 681 int rows, int interlace ); 682static void build_dma_prog( bktr_ptr_t bktr, char i_flag ); 683 684static bool_t getline(bktr_reg_t *, int); 685static bool_t notclipped(bktr_reg_t * , int , int); 686static bool_t split(bktr_reg_t *, volatile u_long **, int, u_long, int, 687 volatile u_char ** , int ); 688 689/* 690 * video & video capture specific routines. 691 */ 692static int video_open( bktr_ptr_t bktr ); 693static int video_close( bktr_ptr_t bktr ); 694static int video_ioctl( bktr_ptr_t bktr, int unit, 695 int cmd, caddr_t arg, struct proc* pr ); 696 697static void start_capture( bktr_ptr_t bktr, unsigned type ); 698static void set_fps( bktr_ptr_t bktr, u_short fps ); 699 700 701/* 702 * tuner specific functions. 703 */ 704static int tuner_open( bktr_ptr_t bktr ); 705static int tuner_close( bktr_ptr_t bktr ); 706static int tuner_ioctl( bktr_ptr_t bktr, int unit, 707 int cmd, caddr_t arg, struct proc* pr ); 708 709static int tv_channel( bktr_ptr_t bktr, int channel ); 710static int tv_freq( bktr_ptr_t bktr, int frequency ); 711#if defined( TUNER_AFC ) 712static int do_afc( bktr_ptr_t bktr, int addr, int frequency ); 713#endif /* TUNER_AFC */ 714 715 716/* 717 * audio specific functions. 718 */ 719static int set_audio( bktr_ptr_t bktr, int mode ); 720static void temp_mute( bktr_ptr_t bktr, int flag ); 721static int set_BTSC( bktr_ptr_t bktr, int control ); 722 723 724/* 725 * ioctls common to both video & tuner. 726 */ 727static int common_ioctl( bktr_ptr_t bktr, bt848_ptr_t bt848, 728 int cmd, caddr_t arg ); 729 730 731/* 732 * i2c primitives 733 */ 734static int i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 ); 735static int i2cRead( bktr_ptr_t bktr, int addr ); 736static int writeEEProm( bktr_ptr_t bktr, int offset, int count, 737 u_char* data ); 738static int readEEProm( bktr_ptr_t bktr, int offset, int count, 739 u_char* data ); 740 741 742#ifdef __FreeBSD__ 743/* 744 * the boot time probe routine. 745 */ 746static char* 747bktr_probe( pcici_t tag, pcidi_t type ) 748{ 749 switch (type) { 750 case BROOKTREE_848_ID: 751 return("BrookTree 848"); 752 }; 753 754 return ((char *)0); 755} 756#endif /* __FreeBSD__ */ 757 758 759 760 761/* 762 * the attach routine. 763 */ 764static void 765bktr_attach( ATTACH_ARGS ) 766{ 767 bktr_ptr_t bktr; 768 bt848_ptr_t bt848; 769#ifdef BROOKTREE_IRQ 770 u_long old_irq, new_irq; 771#endif 772 vm_offset_t buf; 773 u_long latency; 774 u_long fun; 775 776 777#ifdef __FreeBSD__ 778 bktr = &brooktree[unit]; 779 780 if (unit >= NBKTR) { 781 printf("brooktree%d: attach: only %d units configured.\n", 782 unit, NBKTR); 783 printf("brooktree%d: attach: invalid unit number.\n", unit); 784 return; 785 } 786 787 bktr->tag = tag; 788 pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base, 789 &bktr->phys_base ); 790 791 792#ifdef BROOKTREE_IRQ /* from the configuration file */ 793 old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); 794 pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ); 795 new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); 796 printf("bktr%d: attach: irq changed from %d to %d\n", 797 unit, (old_irq & 0xff), (new_irq & 0xff)); 798#endif 799 /* setup the interrupt handling routine */ 800 pci_map_int(tag, bktr_intr, (void*) bktr, &net_imask); 801#endif /* __FreeBSD__ */ 802 803#ifdef __bsdi__ 804 struct isa_attach_args * const ia = (struct isa_attach_args *)aux; 805 pci_devaddr_t *tag = (pci_devaddr_t *) ia->ia_aux; 806 int unit = bktr->bktr_dev.dv_unit; 807 808 bktr = (bktr_reg_t *) self; 809 bktr->base = (bt848_ptr_t) bktr_res.pci_vaddr; 810 isa_establish(&bktr->bktr_id, &bktr->bktr_dev); 811 bktr->bktr_ih.ih_fun = bktr_intr_returning_1; 812 bktr->bktr_ih.ih_arg = (void *)bktr; 813 intr_establish(ia->ia_irq, &bktr->bktr_ih, DV_DULL); 814#endif /* __bsdi__ */ 815 816/* 817 * PCI latency timer. 32 is a good value for 4 bus mastering slots, if 818 * you have more than four, then 16 would probably be a better value. 819 */ 820#ifndef BROOKTREE_DEF_LATENCY_VALUE 821#define BROOKTREE_DEF_LATENCY_VALUE 10 822#endif 823 latency = pci_conf_read(tag, PCI_LATENCY_TIMER); 824 latency = (latency >> 8) & 0xff; 825 if ( bootverbose ) { 826 if (latency) 827 printf("brooktree%d: PCI bus latency is", unit); 828 else 829 printf("brooktree%d: PCI bus latency was 0 changing to", 830 unit); 831 } 832 if ( !latency ) { 833 latency = BROOKTREE_DEF_LATENCY_VALUE; 834 pci_conf_write(tag, PCI_LATENCY_TIMER, latency<<8); 835 } 836 if ( bootverbose ) { 837 printf(" %d.\n", (int) latency); 838 } 839 840 841 /* allocate space for dma program */ 842 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC); 843 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC); 844 845 /* allocate space for pixel buffer */ 846 if ( BROOKTREE_ALLOC ) 847 buf = get_bktr_mem(unit, BROOKTREE_ALLOC); 848 else 849 buf = 0; 850 851 if ( bootverbose ) { 852 printf("bktr%d: buffer size %d, addr 0x%x\n", 853 unit, BROOKTREE_ALLOC, vtophys(buf)); 854 } 855 856 bktr->bigbuf = buf; 857 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES; 858 if ( buf != 0 ) { 859 bzero((caddr_t) buf, BROOKTREE_ALLOC); 860 buf = vtophys(buf); 861 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE | 862 METEOR_DEV0 | METEOR_RGB16; 863 bktr->dma_prog_loaded = FALSE; 864 bktr->cols = 640; 865 bktr->rows = 480; 866 bktr->frames = 1; /* one frame */ 867 bktr->format = METEOR_GEO_RGB16; 868 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 869 bktr->pixfmt_compat = TRUE; 870 bt848 = bktr->base; 871 bt848->int_mask = ALL_INTS_DISABLED; 872 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; 873 } 874 875 /* defaults for the tuner section of the card */ 876 bktr->tflags = TUNER_INITALIZED; 877 bktr->tuner.frequency = 0; 878 bktr->tuner.channel = 0; 879 bktr->tuner.chnlset = DEFAULT_CHNLSET; 880 bktr->audio_mux_select = 0; 881 bktr->audio_mute_state = FALSE; 882 883 probeCard( bktr, TRUE ); 884 885#ifdef DEVFS
|
862 bktr->devfs_bktr_token = devfs_add_devswf(&bktr_cdevsw, unit,
863 DV_CHR, 0, 0, 0444, "bktr%d", unit);
864 bktr->devfs_tuner_token = devfs_add_devswf(&bktr_cdevsw, unit+16,
865 DV_CHR, 0, 0, 0444, "tuner%d", unit);
|
886 bktr->devfs_token = devfs_add_devswf(&bktr_cdevsw, unit, 887 DV_CHR, 0, 0, 0644, "brooktree"); |
888#endif /* DEVFS */
|
889#if __FreeBSD__ > 2 |
890 fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); 891 pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 4);
|
892#endif |
893 894} 895 896 897/* 898 * interrupt handling routine complete bktr_read() if using interrupts. 899 */ 900static void 901bktr_intr( void *arg ) 902{ 903 bktr_ptr_t bktr; 904 bt848_ptr_t bt848; 905 u_long bktr_status; 906 u_char dstatus; 907 u_long field; 908 u_long w_field; 909 u_long req_field; 910 911 bktr = (bktr_ptr_t) arg; 912 bt848 = bktr->base; 913 914 /* 915 * check to see if any interrupts are unmasked on this device. If 916 * none are, then we likely got here by way of being on a PCI shared 917 * interrupt dispatch list. 918 */ 919 if (bt848->int_mask == ALL_INTS_DISABLED) 920 return; /* bail out now, before we do something we 921 shouldn't */ 922 923 if (!(bktr->flags & METEOR_OPEN)) { 924 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; 925 bt848->int_mask = ALL_INTS_DISABLED; 926 /* return; ?? */ 927 } 928 929 /* record and clear the INTerrupt status bits */ 930 bktr_status = bt848->int_stat; 931 bt848->int_stat = bktr_status & ~I2C_BITS; /* don't touch i2c */ 932 933 /* record and clear the device status register */ 934 dstatus = bt848->dstatus; 935 bt848->dstatus = 0x00; 936 937#if defined( STATUS_SUM ) 938 /* add any new device status or INTerrupt status bits */ 939 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1)); 940 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6); 941#endif /* STATUS_SUM */ 942 /* printf( " STATUS %x %x %x \n", 943 dstatus, bktr_status, bt848->risc_count ); 944 */ 945 /* if risc was disabled re-start process again */ 946 if ( !(bktr_status & BT848_INT_RISC_EN) ||
|
923 ((bktr_status & (BT848_INT_FTRGT |
|
947 ((bktr_status &(BT848_INT_FBUS | 948 BT848_INT_FTRGT | 949 BT848_INT_FDSR | |
950 BT848_INT_PPERR | 951 BT848_INT_RIPERR | 952 BT848_INT_PABORT | 953 BT848_INT_OCERR |
|
928 BT848_INT_SCERR)) != 0) ||
|
954 BT848_INT_SCERR) ) != 0) || |
955 ((bt848->tdec == 0) && (bktr_status & TDEC_BITS)) ) { 956 957 u_short tdec_save = bt848->tdec; 958 959 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; 960 961 bt848->int_mask = ALL_INTS_DISABLED; 962 963 /* Reset temporal decimation ctr */ 964 bt848->tdec = 0; 965 bt848->tdec = tdec_save; 966 967 /* Reset to no-fields captured state */ 968 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 969 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 970 case METEOR_ONLY_ODD_FIELDS: 971 bktr->flags |= METEOR_WANT_ODD; 972 break; 973 case METEOR_ONLY_EVEN_FIELDS: 974 bktr->flags |= METEOR_WANT_EVEN; 975 break; 976 default: 977 bktr->flags |= METEOR_WANT_MASK; 978 break; 979 } 980 } 981 982 bt848->risc_strt_add = vtophys(bktr->dma_prog); 983 bt848->gpio_dma_ctl = FIFO_ENABLED; 984 bt848->gpio_dma_ctl = bktr->capcontrol; 985 986 bt848->int_mask = BT848_INT_MYSTERYBIT | 987 BT848_INT_RISCI | 988 BT848_INT_VSYNC | 989 BT848_INT_FMTCHG; 990 991 bt848->cap_ctl = bktr->bktr_cap_ctl; 992 993 return; 994 } 995 996 if (!(bktr_status & BT848_INT_RISCI)) 997 return; 998/** 999 printf( "intr status %x %x %x\n", 1000 bktr_status, dstatus, bt848->risc_count ); 1001 */ 1002 1003 /* 1004 * Disable future interrupts if a capture mode is not selected. 1005 * This can happen when we are in the process of closing or 1006 * changing capture modes, otherwise it shouldn't happen. 1007 */ 1008 if (!(bktr->flags & METEOR_CAP_MASK)) 1009 bt848->cap_ctl = CAPTURE_OFF; 1010 1011 /* 1012 * Register the completed field 1013 * (For dual-field mode, require fields from the same frame) 1014 */ 1015 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F; 1016 switch ( bktr->flags & METEOR_WANT_MASK ) { 1017 case METEOR_WANT_ODD : w_field = ODD_F ; break; 1018 case METEOR_WANT_EVEN : w_field = EVEN_F ; break; 1019 default : w_field = (ODD_F|EVEN_F); break; 1020 } 1021 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) { 1022 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break; 1023 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break; 1024 default : req_field = (ODD_F|EVEN_F); 1025 break; 1026 } 1027 1028 if (( field == EVEN_F ) && ( w_field == EVEN_F )) 1029 bktr->flags &= ~METEOR_WANT_EVEN; 1030 else if (( field == ODD_F ) && ( req_field == ODD_F ) && 1031 ( w_field == ODD_F )) 1032 bktr->flags &= ~METEOR_WANT_ODD; 1033 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) && 1034 ( w_field == (ODD_F|EVEN_F) )) 1035 bktr->flags &= ~METEOR_WANT_ODD; 1036 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) && 1037 ( w_field == ODD_F )) { 1038 bktr->flags &= ~METEOR_WANT_ODD; 1039 bktr->flags |= METEOR_WANT_EVEN; 1040 } 1041 else { 1042 /* We're out of sync. Start over. */ 1043 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 1044 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 1045 case METEOR_ONLY_ODD_FIELDS: 1046 bktr->flags |= METEOR_WANT_ODD; 1047 break; 1048 case METEOR_ONLY_EVEN_FIELDS: 1049 bktr->flags |= METEOR_WANT_EVEN; 1050 break; 1051 default: 1052 bktr->flags |= METEOR_WANT_MASK; 1053 break; 1054 } 1055 } 1056 return; 1057 } 1058 1059 /* 1060 * If we have a complete frame. 1061 */ 1062 if (!(bktr->flags & METEOR_WANT_MASK)) { 1063 bktr->frames_captured++; 1064 /* 1065 * post the completion time. 1066 */ 1067 if (bktr->flags & METEOR_WANT_TS) { 1068 struct timeval *ts; 1069 1070 if ((u_int) bktr->alloc_pages * PAGE_SIZE 1071 <= (bktr->frame_size + sizeof(struct timeval))) { 1072 ts =(struct timeval *)bktr->bigbuf + 1073 bktr->frame_size; 1074 /* doesn't work in synch mode except 1075 * for first frame */ 1076 /* XXX */ 1077 microtime(ts); 1078 } 1079 } 1080 1081 /* 1082 * Wake up the user in single capture mode. 1083 */ 1084 if (bktr->flags & METEOR_SINGLE) { 1085 1086 /* stop dma */ 1087 bt848->int_mask = ALL_INTS_DISABLED; 1088 1089 /* disable risc, leave fifo running */ 1090 bt848->gpio_dma_ctl = FIFO_ENABLED; 1091 wakeup((caddr_t)bktr); 1092 } 1093 1094 /* 1095 * If the user requested to be notified via signal, 1096 * let them know the frame is complete. 1097 */
|
1098 |
1099 if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK)) 1100 psignal( bktr->proc, 1101 bktr->signal&(~METEOR_SIG_MODE_MASK) ); 1102 1103 /* 1104 * Reset the want flags if in continuous or 1105 * synchronous capture mode. 1106 */ 1107/* 1108* XXX NOTE (Luigi): 1109* currently we only support 3 capture modes: odd only, even only, 1110* odd+even interlaced (odd field first). A fourth mode (non interlaced, 1111* either even OR odd) could provide 60 (50 for PAL) pictures per 1112* second, but it would require this routine to toggle the desired frame 1113* each time, and one more different DMA program for the Bt848. 1114* As a consequence, this fourth mode is currently unsupported. 1115*/ 1116 1117 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 1118 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 1119 case METEOR_ONLY_ODD_FIELDS: 1120 bktr->flags |= METEOR_WANT_ODD; 1121 break; 1122 case METEOR_ONLY_EVEN_FIELDS: 1123 bktr->flags |= METEOR_WANT_EVEN; 1124 break; 1125 default: 1126 bktr->flags |= METEOR_WANT_MASK; 1127 break; 1128 } 1129 } 1130 } 1131 1132 return; 1133} 1134 1135 1136/*--------------------------------------------------------- 1137** 1138** BrookTree 848 character device driver routines 1139** 1140**--------------------------------------------------------- 1141*/ 1142 1143 1144#define VIDEO_DEV 0x00 1145#define TUNER_DEV 0x01 1146 1147/* 1148 * 1149 */ 1150int 1151bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) 1152{ 1153 bktr_ptr_t bktr; 1154 int unit; 1155 1156 unit = UNIT( minor(dev) ); 1157 if (unit >= NBKTR) /* unit out of range */ 1158 return( ENXIO ); 1159 1160 bktr = &(brooktree[ unit ]); 1161 1162 if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */ 1163 return( ENXIO ); 1164 1165 switch ( MINOR( minor(dev) ) ) { 1166 case VIDEO_DEV: 1167 return( video_open( bktr ) ); 1168 1169 case TUNER_DEV: 1170 return( tuner_open( bktr ) ); 1171 } 1172 1173 return( ENXIO ); 1174} 1175 1176 1177/* 1178 * 1179 */ 1180static int 1181video_open( bktr_ptr_t bktr ) 1182{ 1183 bt848_ptr_t bt848; 1184 1185 if (bktr->flags & METEOR_OPEN) /* device is busy */ 1186 return( EBUSY ); 1187 1188 bktr->flags |= METEOR_OPEN; 1189 1190 bt848 = bktr->base; 1191 1192#ifdef BT848_DUMP 1193 dump_bt848( bt848 ); 1194#endif 1195 1196 bt848->dstatus = 0x00; /* clear device status reg. */ 1197 1198 bt848->adc = SYNC_LEVEL; 1199 1200 bt848->iform = BT848_IFORM_M_MUX1 | 1201 BT848_IFORM_X_XT0 | 1202 BT848_IFORM_F_NTSCM; 1203 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0; 1204 bktr->format_params = BT848_IFORM_F_NTSCM; 1205 1206 bktr->max_clip_node = 0; 1207 1208 bt848->color_ctl_gamma = 0; 1209 bt848->color_ctl_rgb_ded = 1; 1210 bt848->color_ctl_color_bars = 0; 1211 bt848->color_ctl_ext_frmrate = 0; 1212 bt848->color_ctl_swap = 0; 1213 1214 bt848->e_hscale_lo = 170; 1215 bt848->o_hscale_lo = 170; 1216 1217 bt848->e_delay_lo = 0x72; 1218 bt848->o_delay_lo = 0x72; 1219 bt848->e_scloop = 0; 1220 bt848->o_scloop = 0; 1221 1222 bt848->vbi_pack_size = 0; 1223 bt848->vbi_pack_del = 0; 1224 1225 bktr->fifo_errors = 0; 1226 bktr->dma_errors = 0; 1227 bktr->frames_captured = 0; 1228 bktr->even_fields_captured = 0; 1229 bktr->odd_fields_captured = 0; 1230 bktr->proc = (struct proc *)0; 1231 set_fps(bktr, 30); 1232 bktr->video.addr = 0; 1233 bktr->video.width = 0; 1234 bktr->video.banksize = 0; 1235 bktr->video.ramsize = 0; 1236 bktr->pixfmt_compat = TRUE; 1237 bktr->format = METEOR_GEO_RGB16; 1238 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 1239 1240 1241 bt848->int_mask = BT848_INT_MYSTERYBIT; /* what does this bit do ??? */ 1242 1243 return( 0 ); 1244} 1245 1246 1247/* 1248 * 1249 */ 1250static int 1251tuner_open( bktr_ptr_t bktr ) 1252{ 1253 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */ 1254 return( ENXIO ); 1255 1256 if ( bktr->tflags & TUNER_OPEN ) /* already open */ 1257 return( 0 ); 1258 1259 bktr->tflags |= TUNER_OPEN; 1260 1261 /* enable drivers on the GPIO port that control the MUXes */ 1262 bktr->base->gpio_out_en = GPIO_AUDIOMUX_BITS; 1263 1264 /* unmute the audio stream */ 1265 set_audio( bktr, AUDIO_UNMUTE ); 1266 1267 /* enable stereo if appropriate */ 1268 if ( bktr->card.dbx ) 1269 set_BTSC( bktr, 0 ); 1270 1271 return( 0 ); 1272} 1273 1274 1275/* 1276 * 1277 */ 1278int 1279bktr_close( dev_t dev, int flags, int fmt, struct proc *p ) 1280{ 1281 bktr_ptr_t bktr; 1282 int unit; 1283 1284 unit = UNIT( minor(dev) ); 1285 if (unit >= NBKTR) /* unit out of range */ 1286 return( ENXIO ); 1287 1288 bktr = &(brooktree[ unit ]); 1289 1290 switch ( MINOR( minor(dev) ) ) { 1291 case VIDEO_DEV: 1292 return( video_close( bktr ) ); 1293 1294 case TUNER_DEV: 1295 return( tuner_close( bktr ) ); 1296 } 1297 1298 return( ENXIO ); 1299} 1300 1301 1302/* 1303 * 1304 */ 1305static int 1306video_close( bktr_ptr_t bktr ) 1307{ 1308 bt848_ptr_t bt848; 1309 1310 bktr->flags &= ~(METEOR_OPEN | 1311 METEOR_SINGLE | 1312 METEOR_CAP_MASK | 1313 METEOR_WANT_MASK); 1314 1315 bt848 = bktr->base; 1316 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; 1317 bt848->cap_ctl = CAPTURE_OFF; 1318 1319 bktr->dma_prog_loaded = FALSE; 1320 bt848->tdec = 0; 1321 bt848->int_mask = ALL_INTS_DISABLED; 1322 1323/** FIXME: is 0xf magic, wouldn't 0x00 work ??? */ 1324 bt848->sreset = 0xf; 1325 bt848->int_stat = ALL_INTS_CLEARED; 1326 1327 return( 0 ); 1328} 1329 1330 1331/* 1332 * tuner close handle, 1333 * place holder for tuner specific operations on a close. 1334 */ 1335static int 1336tuner_close( bktr_ptr_t bktr ) 1337{ 1338 bktr->tflags &= ~TUNER_OPEN; 1339 1340 /* mute the audio by switching the mux */ 1341 set_audio( bktr, AUDIO_MUTE ); 1342 1343 /* disable drivers on the GPIO port that control the MUXes */ 1344 bktr->base->gpio_out_en = 0; 1345 1346 return( 0 ); 1347} 1348 1349 1350/* 1351 * 1352 */ 1353int 1354bktr_read( dev_t dev, struct uio *uio, int ioflag ) 1355{ 1356 bktr_ptr_t bktr; 1357 bt848_ptr_t bt848; 1358 int unit; 1359 int status; 1360 int count; 1361 1362 if (MINOR(minor(dev)) > 0) 1363 return( ENXIO ); 1364 1365 unit = UNIT(minor(dev)); 1366 if (unit >= NBKTR) /* unit out of range */ 1367 return( ENXIO ); 1368
|
1342 printf("btkr driver : use ioctl interface . read function not implemented \n");
1343 return( ENXIO );
1344
|
1369 bktr = &(brooktree[unit]);
|
1370 bt848 = bktr->base; 1371 |
1372 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */ 1373 return( ENOMEM ); 1374 1375 if (bktr->flags & METEOR_CAP_MASK) 1376 return( EIO ); /* already capturing */ 1377
|
1378 bt848->cap_ctl = bktr->bktr_cap_ctl; 1379 1380 |
1381 count = bktr->rows * bktr->cols * 1382 pixfmt_table[ bktr->pixfmt ].public.Bpp; 1383 1384 if ((int) uio->uio_iov->iov_len < count) 1385 return( EINVAL ); 1386 1387 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK); 1388
|
1360 /* Start capture */
1361 bt848 = bktr->base;
|
1389 /* capture one frame */ 1390 start_capture(bktr, METEOR_SINGLE); 1391 /* wait for capture to complete */ 1392 bt848->int_stat = ALL_INTS_CLEARED; |
1393 bt848->gpio_dma_ctl = FIFO_ENABLED;
|
1363 bt848->gpio_dma_ctl = FIFO_RISC_ENABLED;
|
1394 bt848->gpio_dma_ctl = bktr->capcontrol; 1395 bt848->int_mask = BT848_INT_MYSTERYBIT | 1396 BT848_INT_RISCI | 1397 BT848_INT_VSYNC | 1398 BT848_INT_FMTCHG; |
1399
|
1400 |
1401 status = tsleep((caddr_t)bktr, BKTRPRI, "captur", 0); 1402 if (!status) /* successful capture */ 1403 status = uiomove((caddr_t)bktr->bigbuf, count, uio); 1404 else 1405 printf ("bktr%d: read: tsleep error %d\n", unit, status); 1406 1407 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK); 1408 1409 return( status ); 1410} 1411 1412 1413/* 1414 * 1415 */ 1416int 1417bktr_write( dev_t dev, struct uio *uio, int ioflag ) 1418{ 1419 return( EINVAL ); /* XXX or ENXIO ? */ 1420} 1421 1422 1423/* 1424 * 1425 */ 1426int 1427bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct proc* pr ) 1428{ 1429 bktr_ptr_t bktr; 1430 int unit; 1431 1432 unit = UNIT(minor(dev)); 1433 if (unit >= NBKTR) /* unit out of range */ 1434 return( ENXIO ); 1435 1436 bktr = &(brooktree[ unit ]); 1437 1438 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */ 1439 return( ENOMEM ); 1440 1441 switch ( MINOR( minor(dev) ) ) { 1442 case VIDEO_DEV: 1443 return( video_ioctl( bktr, unit, cmd, arg, pr ) ); 1444 1445 case TUNER_DEV: 1446 return( tuner_ioctl( bktr, unit, cmd, arg, pr ) ); 1447 } 1448 1449 return( ENXIO ); 1450} 1451
|
1452 |
1453/* 1454 * video ioctls 1455 */ 1456static int 1457video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr ) 1458{ 1459 int tmp_int; 1460 bt848_ptr_t bt848; 1461 volatile u_char c_temp; 1462 unsigned int temp; 1463 unsigned int error; 1464 struct meteor_geomet *geo; 1465 struct meteor_counts *cnt; 1466 struct meteor_video *video; 1467 vm_offset_t buf; 1468 struct format_params *fp; 1469 int i; 1470 u_long par; 1471 u_char write; 1472 int i2c_addr; 1473 int i2c_port; 1474 u_long data; 1475 1476 bt848 = bktr->base; 1477 1478 switch ( cmd ) { 1479 1480 case BT848SCLIP: /* set clip region */ 1481 bktr->max_clip_node = 0; 1482 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list)); 1483 1484 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) { 1485 if (bktr->clip_list[i].y_min == 0 && 1486 bktr->clip_list[i].y_max == 0) 1487 break; 1488 } 1489 bktr->max_clip_node = i; 1490 1491 /* make sure that the list contains a valid clip secquence */ 1492 /* the clip rectangles should be sorted by x then by y as the 1493 second order sort key */ 1494 1495 /* clip rectangle list is terminated by y_min and y_max set to 0 */ 1496 1497 /* to disable clipping set y_min and y_max to 0 in the first 1498 clip rectangle . The first clip rectangle is clip_list[0]. 1499 */ 1500 1501 1502 1503 if (bktr->max_clip_node == 0 && 1504 (bktr->clip_list[0].y_min != 0 && 1505 bktr->clip_list[0].y_max != 0)) { 1506 return EINVAL; 1507 } 1508 1509 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) { 1510 if (bktr->clip_list[i].y_min == 0 && 1511 bktr->clip_list[i].y_max == 0) { 1512 break; 1513 } 1514 if ( bktr->clip_list[i+1].y_min != 0 && 1515 bktr->clip_list[i+1].y_max != 0 && 1516 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) { 1517 1518 bktr->max_clip_node = 0; 1519 return (EINVAL); 1520 1521 } 1522 1523 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max || 1524 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max || 1525 bktr->clip_list[i].x_min < 0 || 1526 bktr->clip_list[i].x_max < 0 || 1527 bktr->clip_list[i].y_min < 0 || 1528 bktr->clip_list[i].y_max < 0 ) { 1529 bktr->max_clip_node = 0; 1530 return (EINVAL); 1531 } 1532 } 1533 1534 bktr->dma_prog_loaded = FALSE; 1535 1536 break; 1537 1538 case METEORSTATUS: /* get Bt848 status */ 1539 c_temp = bt848->dstatus; 1540 temp = 0; 1541 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK; 1542 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT; 1543 *(u_short *)arg = temp; 1544 break; 1545 1546 case BT848SFMT: /* set input format */ 1547 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT; 1548 bt848->iform &= ~BT848_IFORM_FORMAT; 1549 bt848->iform |= (temp | format_params[temp].iform_xtsel); 1550 switch( temp ) { 1551 case BT848_IFORM_F_AUTO: 1552 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1553 METEOR_AUTOMODE; 1554 break; 1555 1556 case BT848_IFORM_F_NTSCM: 1557 case BT848_IFORM_F_NTSCJ: 1558 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1559 METEOR_NTSC; 1560 bt848->adelay = format_params[temp].adelay; 1561 bt848->bdelay = format_params[temp].bdelay; 1562 bktr->format_params = temp; 1563 break; 1564 1565 case BT848_IFORM_F_PALBDGHI: 1566 case BT848_IFORM_F_PALN: 1567 case BT848_IFORM_F_SECAM: 1568 case BT848_IFORM_F_RSVD: 1569 case BT848_IFORM_F_PALM: 1570 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1571 METEOR_PAL; 1572 bt848->adelay = format_params[temp].adelay; 1573 bt848->bdelay = format_params[temp].bdelay; 1574 bktr->format_params = temp; 1575 break; 1576 1577 }
|
1578 bktr->dma_prog_loaded = FALSE; |
1579 break; 1580 1581 case METEORSFMT: /* set input format */ 1582 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) { 1583 case 0: /* default */ 1584 case METEOR_FMT_NTSC: 1585 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1586 METEOR_NTSC; 1587 bt848->iform &= ~BT848_IFORM_FORMAT;
|
1550 bt848->iform |= BT848_IFORM_F_NTSCM;
|
1588 bt848->iform |= BT848_IFORM_F_NTSCM | 1589 format_params[BT848_IFORM_F_NTSCM].iform_xtsel; |
1590 bt848->adelay = 0x68; 1591 bt848->bdelay = 0x5d; 1592 bktr->format_params = BT848_IFORM_F_NTSCM; 1593 break; 1594 1595 case METEOR_FMT_PAL: 1596 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1597 METEOR_PAL; 1598 bt848->iform &= ~BT848_IFORM_FORMAT;
|
1560 bt848->iform |= BT848_IFORM_F_PALBDGHI;
|
1599 bt848->iform |= BT848_IFORM_F_PALBDGHI | 1600 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel; |
1601 bt848->adelay = 0x7f; 1602 bt848->bdelay = 0x72; 1603 bktr->format_params = BT848_IFORM_F_PALBDGHI; 1604 break; 1605 1606 case METEOR_FMT_AUTOMODE: 1607 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1608 METEOR_AUTOMODE; 1609 bt848->iform &= ~BT848_IFORM_FORMAT; 1610 break; 1611 1612 default: 1613 return( EINVAL ); 1614 }
|
1615 bktr->dma_prog_loaded = FALSE; |
1616 break; 1617 1618 case METEORGFMT: /* get input format */ 1619 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK; 1620 break; 1621 1622 1623 case BT848GFMT: /* get input format */ 1624 *(u_long *)arg = bt848->iform & BT848_IFORM_FORMAT; 1625 break; 1626 1627 case METEORSCOUNT: /* (re)set error counts */ 1628 cnt = (struct meteor_counts *) arg; 1629 bktr->fifo_errors = cnt->fifo_errors; 1630 bktr->dma_errors = cnt->dma_errors; 1631 bktr->frames_captured = cnt->frames_captured; 1632 bktr->even_fields_captured = cnt->even_fields_captured; 1633 bktr->odd_fields_captured = cnt->odd_fields_captured; 1634 break; 1635 1636 case METEORGCOUNT: /* get error counts */ 1637 cnt = (struct meteor_counts *) arg; 1638 cnt->fifo_errors = bktr->fifo_errors; 1639 cnt->dma_errors = bktr->dma_errors; 1640 cnt->frames_captured = bktr->frames_captured; 1641 cnt->even_fields_captured = bktr->even_fields_captured; 1642 cnt->odd_fields_captured = bktr->odd_fields_captured; 1643 break; 1644 1645 case METEORGVIDEO: 1646 video = (struct meteor_video *)arg; 1647 video->addr = bktr->video.addr; 1648 video->width = bktr->video.width; 1649 video->banksize = bktr->video.banksize; 1650 video->ramsize = bktr->video.ramsize; 1651 break; 1652 1653 case METEORSVIDEO: 1654 video = (struct meteor_video *)arg; 1655 bktr->video.addr = video->addr; 1656 bktr->video.width = video->width; 1657 bktr->video.banksize = video->banksize; 1658 bktr->video.ramsize = video->ramsize; 1659 break; 1660 1661 case METEORSFPS: 1662 set_fps(bktr, *(u_short *)arg); 1663 break; 1664 1665 case METEORGFPS: 1666 *(u_short *)arg = bktr->fps; 1667 break; 1668 1669 case METEORSHUE: /* set hue */ 1670 bt848->hue = (*(u_char *) arg) & 0xff; 1671 break; 1672 1673 case METEORGHUE: /* get hue */ 1674 *(u_char *)arg = bt848->hue; 1675 break; 1676 1677 case METEORSBRIG: /* set brightness */ 1678 bt848->bright = *(u_char *)arg & 0xff; 1679 break; 1680 1681 case METEORGBRIG: /* get brightness */ 1682 *(u_char *)arg = bt848->bright; 1683 break; 1684 1685 case METEORSCSAT: /* set chroma saturation */ 1686 temp = (int)*(u_char *)arg; 1687 1688 bt848->sat_u_lo = bt848->sat_v_lo = (temp << 1) & 0xff; 1689 1690 bt848->e_control &= ~(BT848_E_CONTROL_SAT_U_MSB | 1691 BT848_E_CONTROL_SAT_V_MSB); 1692 bt848->o_control &= ~(BT848_O_CONTROL_SAT_U_MSB | 1693 BT848_O_CONTROL_SAT_V_MSB); 1694 1695 if ( temp & BIT_SEVEN_HIGH ) { 1696 bt848->e_control |= (BT848_E_CONTROL_SAT_U_MSB | 1697 BT848_E_CONTROL_SAT_V_MSB); 1698 bt848->o_control |= (BT848_O_CONTROL_SAT_U_MSB | 1699 BT848_O_CONTROL_SAT_V_MSB); 1700 } 1701 break; 1702 1703 case METEORGCSAT: /* get chroma saturation */ 1704 temp = (bt848->sat_v_lo >> 1) & 0xff; 1705 if ( bt848->e_control & BT848_E_CONTROL_SAT_V_MSB ) 1706 temp |= BIT_SEVEN_HIGH; 1707 *(u_char *)arg = (u_char)temp; 1708 break; 1709 1710 case METEORSCONT: /* set contrast */ 1711 temp = (int)*(u_char *)arg & 0xff; 1712 temp <<= 1; 1713 bt848->contrast_lo = temp & 0xff; 1714 bt848->e_control &= ~BT848_E_CONTROL_CON_MSB; 1715 bt848->o_control &= ~BT848_O_CONTROL_CON_MSB; 1716 bt848->e_control |= 1717 ((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB; 1718 bt848->o_control |= 1719 ((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB; 1720 break; 1721 1722 case METEORGCONT: /* get contrast */ 1723 temp = (int)bt848->contrast_lo & 0xff; 1724 temp |= ((int)bt848->o_control & 0x04) << 6; 1725 *(u_char *)arg = (u_char)((temp >> 1) & 0xff); 1726 break; 1727 1728 case METEORSSIGNAL: 1729 if(*(int *)arg == 0 || *(int *)arg >= NSIG) { 1730 return( EINVAL ); 1731 break; 1732 } 1733 bktr->signal = *(int *) arg; 1734 bktr->proc = pr; 1735 break; 1736 1737 case METEORGSIGNAL: 1738 *(int *)arg = bktr->signal; 1739 break; 1740 1741 case METEORCAPTUR: 1742 temp = bktr->flags; 1743 switch (*(int *) arg) { 1744 case METEOR_CAP_SINGLE: 1745 1746 if (bktr->bigbuf==0) /* no frame buffer allocated */ 1747 return( ENOMEM ); 1748 /* already capturing */ 1749 if (temp & METEOR_CAP_MASK) 1750 return( EIO ); 1751 1752 1753 1754 start_capture(bktr, METEOR_SINGLE); 1755 1756 /* wait for capture to complete */ 1757 bt848->int_stat = ALL_INTS_CLEARED; 1758 bt848->gpio_dma_ctl = FIFO_ENABLED; 1759 bt848->gpio_dma_ctl = bktr->capcontrol; 1760 1761 bt848->int_mask = BT848_INT_MYSTERYBIT | 1762 BT848_INT_RISCI | 1763 BT848_INT_VSYNC | 1764 BT848_INT_FMTCHG; 1765 1766 bt848->cap_ctl = bktr->bktr_cap_ctl; 1767 error = tsleep((caddr_t)bktr, BKTRPRI, "captur", hz); 1768 if (error && (error != ERESTART)) { 1769 /* Here if we didn't get complete frame */ 1770#ifdef DIAGNOSTIC 1771 printf( "bktr%d: ioctl: tsleep error %d %x\n", 1772 unit, error, bt848->risc_count); 1773#endif 1774 1775 /* stop dma */ 1776 bt848->int_mask = ALL_INTS_DISABLED; 1777 1778 /* disable risc, leave fifo running */ 1779 bt848->gpio_dma_ctl = FIFO_ENABLED; 1780 } 1781 1782 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK); 1783 /* FIXME: should we set bt848->int_stat ??? */ 1784 break; 1785 1786 case METEOR_CAP_CONTINOUS: 1787 if (bktr->bigbuf==0) /* no frame buffer allocated */ 1788 return( ENOMEM ); 1789 /* already capturing */ 1790 if (temp & METEOR_CAP_MASK) 1791 return( EIO ); 1792 1793 1794 start_capture(bktr, METEOR_CONTIN); 1795 bt848->int_stat = bt848->int_stat; 1796 1797 bt848->gpio_dma_ctl = FIFO_ENABLED; 1798 bt848->gpio_dma_ctl = bktr->capcontrol; 1799 bt848->cap_ctl = bktr->bktr_cap_ctl; 1800 1801 bt848->int_mask = BT848_INT_MYSTERYBIT | 1802 BT848_INT_RISCI | 1803 BT848_INT_VSYNC | 1804 BT848_INT_FMTCHG; 1805#ifdef BT848_DUMP 1806 dump_bt848( bt848 ); 1807#endif 1808 break; 1809 1810 case METEOR_CAP_STOP_CONT: 1811 if (bktr->flags & METEOR_CONTIN) { 1812 /* turn off capture */ 1813 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; 1814 bt848->cap_ctl = CAPTURE_OFF; 1815 bt848->int_mask = ALL_INTS_DISABLED; 1816 bktr->flags &= 1817 ~(METEOR_CONTIN | METEOR_WANT_MASK); 1818 1819 } 1820 } 1821 break; 1822 1823 case METEORSETGEO: 1824 /* can't change parameters while capturing */ 1825 if (bktr->flags & METEOR_CAP_MASK) 1826 return( EBUSY ); 1827 1828 1829 geo = (struct meteor_geomet *) arg;
|
1789 fp = &format_params[bktr->format_params];
|
1830 1831 error = 0; 1832 /* Either even or odd, if even & odd, then these a zero */ 1833 if ((geo->oformat & METEOR_GEO_ODD_ONLY) && 1834 (geo->oformat & METEOR_GEO_EVEN_ONLY)) { 1835 printf( "bktr%d: ioctl: Geometry odd or even only.\n", 1836 unit); 1837 return( EINVAL ); 1838 } 1839 1840 /* set/clear even/odd flags */ 1841 if (geo->oformat & METEOR_GEO_ODD_ONLY) 1842 bktr->flags |= METEOR_ONLY_ODD_FIELDS; 1843 else 1844 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS; 1845 if (geo->oformat & METEOR_GEO_EVEN_ONLY) 1846 bktr->flags |= METEOR_ONLY_EVEN_FIELDS; 1847 else 1848 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS; 1849 1850 if ((geo->columns & 0x3fe) != geo->columns) { 1851 printf( 1852 "bktr%d: ioctl: %d: columns too large or not even.\n", 1853 unit, geo->columns); 1854 error = EINVAL; 1855 } 1856 if (((geo->rows & 0x7fe) != geo->rows) || 1857 ((geo->oformat & METEOR_GEO_FIELD_MASK) && 1858 ((geo->rows & 0x3fe) != geo->rows)) ) { 1859 printf( 1860 "bktr%d: ioctl: %d: rows too large or not even.\n", 1861 unit, geo->rows); 1862 error = EINVAL; 1863 } 1864 if (geo->frames > 32) { 1865 printf("bktr%d: ioctl: too many frames.\n", unit); 1866 1867 error = EINVAL; 1868 } 1869 1870 if (error) 1871 return( error ); 1872 1873 bktr->dma_prog_loaded = FALSE; 1874 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; 1875 1876 bt848->int_mask = ALL_INTS_DISABLED; 1877 1878 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) { 1879 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2; 1880 1881 /* meteor_mem structure for SYNC Capture */ 1882 if (geo->frames > 1) temp += PAGE_SIZE; 1883 1884 temp = btoc(temp); 1885 if ((int) temp > bktr->alloc_pages 1886 && bktr->video.addr == 0) { 1887 buf = get_bktr_mem(unit, temp*PAGE_SIZE); 1888 if (buf != 0) { 1889 kmem_free(kernel_map, bktr->bigbuf, 1890 (bktr->alloc_pages * PAGE_SIZE)); 1891 bktr->bigbuf = buf; 1892 bktr->alloc_pages = temp; 1893 if (bootverbose) 1894 printf( 1895 "bktr%d: ioctl: Allocating %d bytes\n", 1896 unit, temp*PAGE_SIZE); 1897 } 1898 else 1899 error = ENOMEM; 1900 } 1901 } 1902 1903 if (error) 1904 return error; 1905 1906 bktr->rows = geo->rows; 1907 bktr->cols = geo->columns; 1908 bktr->frames = geo->frames; 1909
|
1870 temp = ((quad_t ) fp->htotal* (quad_t) fp->horizontal * 4096
1871 / fp->vertical / bktr->cols) - 4096;
1872 bt848->e_hscale_lo = temp & 0xff;
1873 bt848->o_hscale_lo = temp & 0xff;
1874 bt848->e_hscale_hi = (temp >> 8) & 0xff;
1875 bt848->o_hscale_hi = (temp >> 8) & 0xff;
1876
1877 /* horizontal active */
1878 temp = bktr->cols;
1879 bt848->e_hactive_lo = temp & 0xff;
1880 bt848->o_hactive_lo = temp & 0xff;
1881 bt848->e_crop &= ~0x3;
1882 bt848->o_crop &= ~0x3;
1883 bt848->e_crop |= (temp >> 8) & 0x3;
1884 bt848->o_crop |= (temp >> 8) & 0x3;
1885
1886 /* horizontal delay */
1887 temp = (fp->hdelay * bktr->cols) / fp->hactive;
1888 temp = temp + 2; /* why?? - rmt */
1889 temp = temp & 0x3fe;
1890 bt848->e_delay_lo = temp & 0xff;
1891 bt848->o_delay_lo = temp & 0xff;
1892 bt848->e_crop &= ~0xc;
1893 bt848->o_crop &= ~0xc;
1894 bt848->e_crop |= (temp >> 6) & 0xc;
1895 bt848->o_crop |= (temp >> 6) & 0xc;
1896
1897 /* vertical scale */
1898 if (geo->oformat & METEOR_GEO_ODD_ONLY ||
1899 geo->oformat & METEOR_GEO_EVEN_ONLY)
1900 tmp_int = 65536 -
1901 ((fp->vactive * 256 / bktr->rows) - 512);
1902 else {
1903 tmp_int = 65536 -
1904 (((fp->vactive * 512) / bktr->rows) - 512);
1905 }
1906
1907 tmp_int &= 0x1fff;
1908
1909 bt848->e_vscale_lo = tmp_int & 0xff;
1910 bt848->o_vscale_lo = tmp_int & 0xff;
1911 bt848->e_vscale_hi &= ~0x1f;
1912 bt848->o_vscale_hi &= ~0x1f;
1913 bt848->e_vscale_hi |= (tmp_int >> 8) & 0x1f;
1914 bt848->o_vscale_hi |= (tmp_int >> 8) & 0x1f;
1915
1916 /* vertical active */
1917 bt848->e_crop &= ~0x30;
1918 bt848->e_crop |= (fp->vactive >> 4) & 0x30;
1919 bt848->e_vactive_lo = fp->vactive & 0xff;
1920 bt848->o_crop &= ~0x30;
1921 bt848->o_crop |= (fp->vactive >> 4) & 0x30;
1922 bt848->o_vactive_lo = fp->vactive & 0xff;
1923
1924 /* vertical delay */
1925 bt848->e_vdelay_lo = fp->vdelay;
1926 bt848->o_vdelay_lo = fp->vdelay;
1927
|
1910 /* Pixel format (if in meteor pixfmt compatibility mode) */ 1911 if ( bktr->pixfmt_compat ) { 1912 bktr->format = METEOR_GEO_YUV_422; 1913 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) { 1914 case 0: /* default */ 1915 case METEOR_GEO_RGB16: 1916 bktr->format = METEOR_GEO_RGB16; 1917 break; 1918 case METEOR_GEO_RGB24: 1919 bktr->format = METEOR_GEO_RGB24; 1920 break; 1921 case METEOR_GEO_YUV_422: 1922 bktr->format = METEOR_GEO_YUV_422; 1923 if (geo->oformat & METEOR_GEO_YUV_12) 1924 bktr->format = METEOR_GEO_YUV_12; 1925 break; 1926 case METEOR_GEO_YUV_PACKED: 1927 bktr->format = METEOR_GEO_YUV_PACKED; 1928 break; 1929 } 1930 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 1931 } 1932 1933 if (bktr->flags & METEOR_CAP_MASK) { 1934 1935 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) { 1936 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 1937 case METEOR_ONLY_ODD_FIELDS: 1938 bktr->flags |= METEOR_WANT_ODD; 1939 break; 1940 case METEOR_ONLY_EVEN_FIELDS: 1941 bktr->flags |= METEOR_WANT_EVEN; 1942 break; 1943 default: 1944 bktr->flags |= METEOR_WANT_MASK; 1945 break; 1946 } 1947 1948 start_capture(bktr, METEOR_CONTIN); 1949 bt848->int_stat = bt848->int_stat; 1950 bt848->gpio_dma_ctl = FIFO_ENABLED; 1951 bt848->gpio_dma_ctl = bktr->capcontrol; 1952 bt848->int_mask = BT848_INT_MYSTERYBIT | 1953 BT848_INT_VSYNC | 1954 BT848_INT_FMTCHG; 1955 } 1956 } 1957 break; 1958 /* end of METEORSETGEO */ 1959 1960 case BT848_I2CWR: 1961 par = *(u_long *)arg; 1962 write = (par >> 24) & 0xff ; 1963 i2c_addr = (par >> 16) & 0xff ; 1964 i2c_port = (par >> 8) & 0xff ; 1965 data = (par) & 0xff ; 1966 1967 if (write) { 1968 i2cWrite( bktr, i2c_addr, i2c_port, data); 1969 } else { 1970 data = i2cRead( bktr, i2c_addr); 1971 } 1972 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff ); 1973 break; 1974 1975 default: 1976 return common_ioctl( bktr, bt848, cmd, arg ); 1977 } 1978 1979 return( 0 ); 1980} 1981 1982/* 1983 * tuner ioctls 1984 */ 1985static int 1986tuner_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr ) 1987{ 1988 bt848_ptr_t bt848; 1989 int tmp_int; 1990 unsigned int temp, temp1; 1991 int offset; 1992 int count; 1993 u_char *buf; 1994 1995 bt848 = bktr->base; 1996 1997 switch ( cmd ) { 1998 1999#if defined( TUNER_AFC ) 2000 case TVTUNER_SETAFC: 2001 bktr->tuner.afc = (*(int *)arg != 0); 2002 break; 2003 2004 case TVTUNER_GETAFC: 2005 *(int *)arg = bktr->tuner.afc; 2006 /* XXX Perhaps use another bit to indicate AFC success? */ 2007 break; 2008#endif /* TUNER_AFC */ 2009 2010 case TVTUNER_SETCHNL: 2011 temp_mute( bktr, TRUE ); 2012 temp = tv_channel( bktr, (int)*(unsigned long *)arg ); 2013 temp_mute( bktr, FALSE ); 2014 if ( temp < 0 ) 2015 return( EINVAL ); 2016 *(unsigned long *)arg = temp; 2017 break; 2018 2019 case TVTUNER_GETCHNL: 2020 *(unsigned long *)arg = bktr->tuner.channel; 2021 break; 2022 2023 case TVTUNER_SETTYPE: 2024 temp = *(unsigned long *)arg; 2025 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) ) 2026 return( EINVAL ); 2027 bktr->tuner.chnlset = temp; 2028 break; 2029 2030 case TVTUNER_GETTYPE: 2031 *(unsigned long *)arg = bktr->tuner.chnlset; 2032 break; 2033 2034 case TVTUNER_GETSTATUS: 2035 temp = i2cRead( bktr, TSA552x_RADDR ); 2036 *(unsigned long *)arg = temp & 0xff; 2037 break; 2038 2039 case TVTUNER_SETFREQ: 2040 temp_mute( bktr, TRUE ); 2041 temp = tv_freq( bktr, (int)*(unsigned long *)arg ); 2042 temp_mute( bktr, FALSE ); 2043 if ( temp < 0 ) 2044 return( EINVAL ); 2045 *(unsigned long *)arg = temp; 2046 break; 2047 2048 case TVTUNER_GETFREQ: 2049 *(unsigned long *)arg = bktr->tuner.frequency; 2050 break; 2051 2052 case BT848_SAUDIO: /* set audio channel */ 2053 if ( set_audio( bktr, *(int*)arg ) < 0 ) 2054 return( EIO ); 2055 break; 2056 2057 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */ 2058 case BT848_SHUE: /* set hue */ 2059 bt848->hue = (u_char)(*(int*)arg & 0xff); 2060 break; 2061 2062 case BT848_GHUE: /* get hue */ 2063 *(int*)arg = (signed char)(bt848->hue & 0xff); 2064 break; 2065 2066 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */ 2067 case BT848_SBRIG: /* set brightness */ 2068 bt848->bright = (u_char)(*(int *)arg & 0xff); 2069 break; 2070 2071 case BT848_GBRIG: /* get brightness */ 2072 *(int *)arg = (signed char)(bt848->bright & 0xff); 2073 break; 2074 2075 /* */ 2076 case BT848_SCSAT: /* set chroma saturation */ 2077 tmp_int = *(int*)arg; 2078 2079 temp = bt848->e_control; 2080 temp1 = bt848->o_control; 2081 if ( tmp_int & BIT_EIGHT_HIGH ) { 2082 temp |= (BT848_E_CONTROL_SAT_U_MSB | 2083 BT848_E_CONTROL_SAT_V_MSB); 2084 temp1 |= (BT848_O_CONTROL_SAT_U_MSB | 2085 BT848_O_CONTROL_SAT_V_MSB); 2086 } 2087 else { 2088 temp &= ~(BT848_E_CONTROL_SAT_U_MSB | 2089 BT848_E_CONTROL_SAT_V_MSB); 2090 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB | 2091 BT848_O_CONTROL_SAT_V_MSB); 2092 } 2093 2094 bt848->sat_u_lo = (u_char)(tmp_int & 0xff); 2095 bt848->sat_v_lo = (u_char)(tmp_int & 0xff); 2096 bt848->e_control = temp; 2097 bt848->o_control = temp1; 2098 break; 2099 2100 case BT848_GCSAT: /* get chroma saturation */ 2101 tmp_int = (int)(bt848->sat_v_lo & 0xff); 2102 if ( bt848->e_control & BT848_E_CONTROL_SAT_V_MSB ) 2103 tmp_int |= BIT_EIGHT_HIGH; 2104 *(int*)arg = tmp_int; 2105 break; 2106 2107 /* */ 2108 case BT848_SVSAT: /* set chroma V saturation */ 2109 tmp_int = *(int*)arg; 2110 2111 temp = bt848->e_control; 2112 temp1 = bt848->o_control; 2113 if ( tmp_int & BIT_EIGHT_HIGH) { 2114 temp |= BT848_E_CONTROL_SAT_V_MSB; 2115 temp1 |= BT848_O_CONTROL_SAT_V_MSB; 2116 } 2117 else { 2118 temp &= ~BT848_E_CONTROL_SAT_V_MSB; 2119 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB; 2120 } 2121 2122 bt848->sat_v_lo = (u_char)(tmp_int & 0xff); 2123 bt848->e_control = temp; 2124 bt848->o_control = temp1; 2125 break; 2126 2127 case BT848_GVSAT: /* get chroma V saturation */ 2128 tmp_int = (int)bt848->sat_v_lo & 0xff; 2129 if ( bt848->e_control & BT848_E_CONTROL_SAT_V_MSB ) 2130 tmp_int |= BIT_EIGHT_HIGH; 2131 *(int*)arg = tmp_int; 2132 break; 2133 2134 /* */ 2135 case BT848_SUSAT: /* set chroma U saturation */ 2136 tmp_int = *(int*)arg; 2137 2138 temp = bt848->e_control; 2139 temp1 = bt848->o_control; 2140 if ( tmp_int & BIT_EIGHT_HIGH ) { 2141 temp |= BT848_E_CONTROL_SAT_U_MSB; 2142 temp1 |= BT848_O_CONTROL_SAT_U_MSB; 2143 } 2144 else { 2145 temp &= ~BT848_E_CONTROL_SAT_U_MSB; 2146 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB; 2147 } 2148 2149 bt848->sat_u_lo = (u_char)(tmp_int & 0xff); 2150 bt848->e_control = temp; 2151 bt848->o_control = temp1; 2152 break; 2153 2154 case BT848_GUSAT: /* get chroma U saturation */ 2155 tmp_int = (int)bt848->sat_u_lo & 0xff; 2156 if ( bt848->e_control & BT848_E_CONTROL_SAT_U_MSB ) 2157 tmp_int |= BIT_EIGHT_HIGH; 2158 *(int*)arg = tmp_int; 2159 break; 2160 2161/* lr 970528 luma notch etc - 3 high bits of e_control/o_control */ 2162 2163 case BT848_SLNOTCH: /* set luma notch */ 2164 tmp_int = (*(int *)arg & 0x7) << 5 ; 2165 bt848->e_control &= ~0xe0 ; 2166 bt848->o_control &= ~0xe0 ; 2167 bt848->e_control |= tmp_int ; 2168 bt848->o_control |= tmp_int ; 2169 break; 2170 2171 case BT848_GLNOTCH: /* get luma notch */ 2172 *(int *)arg = (int) ( (bt848->e_control & 0xe0) >> 5) ; 2173 break; 2174 2175 2176 /* */ 2177 case BT848_SCONT: /* set contrast */ 2178 tmp_int = *(int*)arg; 2179 2180 temp = bt848->e_control; 2181 temp1 = bt848->o_control; 2182 if ( tmp_int & BIT_EIGHT_HIGH ) { 2183 temp |= BT848_E_CONTROL_CON_MSB; 2184 temp1 |= BT848_O_CONTROL_CON_MSB; 2185 } 2186 else { 2187 temp &= ~BT848_E_CONTROL_CON_MSB; 2188 temp1 &= ~BT848_O_CONTROL_CON_MSB; 2189 } 2190 2191 bt848->contrast_lo = (u_char)(tmp_int & 0xff); 2192 bt848->e_control = temp; 2193 bt848->o_control = temp1; 2194 break; 2195 2196 case BT848_GCONT: /* get contrast */ 2197 tmp_int = (int)bt848->contrast_lo & 0xff; 2198 if ( bt848->e_control & BT848_E_CONTROL_CON_MSB ) 2199 tmp_int |= BIT_EIGHT_HIGH; 2200 *(int*)arg = tmp_int; 2201 break; 2202 2203 /* FIXME: SCBARS and CCBARS require a valid int * */ 2204 /* argument to succeed, but its not used; consider */ 2205 /* using the arg to store the on/off state so */ 2206 /* there's only one ioctl() needed to turn cbars on/off */ 2207 case BT848_SCBARS: /* set colorbar output */ 2208 bt848->color_ctl_color_bars = 1; 2209 break; 2210 2211 case BT848_CCBARS: /* clear colorbar output */ 2212 bt848->color_ctl_color_bars = 0; 2213 break; 2214 2215 case BT848_GAUDIO: /* get audio channel */ 2216 temp = bktr->audio_mux_select; 2217 if ( bktr->audio_mute_state == TRUE ) 2218 temp |= AUDIO_MUTE; 2219 *(int*)arg = temp; 2220 break; 2221 2222 case BT848_SBTSC: /* set audio channel */ 2223 if ( set_BTSC( bktr, *(int*)arg ) < 0 ) 2224 return( EIO ); 2225 break; 2226 2227 case BT848_WEEPROM: /* write eeprom */ 2228 offset = (((struct eeProm *)arg)->offset); 2229 count = (((struct eeProm *)arg)->count); 2230 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2231 if ( writeEEProm( bktr, offset, count, buf ) < 0 ) 2232 return( EIO ); 2233 break; 2234 2235 case BT848_REEPROM: /* read eeprom */ 2236 offset = (((struct eeProm *)arg)->offset); 2237 count = (((struct eeProm *)arg)->count); 2238 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2239 if ( readEEProm( bktr, offset, count, buf ) < 0 ) 2240 return( EIO ); 2241 break; 2242 2243 case BT848_SIGNATURE: 2244 offset = (((struct eeProm *)arg)->offset); 2245 count = (((struct eeProm *)arg)->count); 2246 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2247 if ( signCard( bktr, offset, count, buf ) < 0 ) 2248 return( EIO ); 2249 break;
|
2250 /* Ioctl's for running the tuner device in radio mode */ 2251#if 0 2252 case RADIO_SETMODE: /* XXX Todo: implement me ... */ 2253 break; 2254 case RADIO_GETFREQ; /* XXX Todo: implement me ... */ 2255 break; 2256#endif 2257 case RADIO_SETFREQ: 2258 /* The argument to this ioctl is NOT freq*16. It is 2259 ** freq*100. 2260 */ |
2261
|
2262 /* The radio in my stereo and the linear regression function 2263 ** in my HP48 have reached the conclusion that in order to 2264 ** set the radio tuner of the FM1216 to f MHz, the value to 2265 ** enter into the PLL is: f*20-407 2266 ** If anyone has the exact values from the spec. sheet 2267 ** please forward them -- fj@login.dknet.dk 2268 */ 2269 temp=(int)*(unsigned long *)arg/5-407 +RADIO_OFFSET; 2270 2271#ifdef BKTR_RADIO_DEBUG 2272 printf("bktr%d: arg=%d temp=%d\n",unit,(int)*(unsigned long *)arg,temp); 2273#endif 2274 2275#ifndef BKTR_RADIO_NOFREQCHECK 2276 /* According to the spec. sheet the band: 87.5MHz-108MHz */ 2277 /* is supported. */ 2278 if(temp<1343+RADIO_OFFSET || temp>1753+RADIO_OFFSET) { 2279 printf("bktr%d: Radio frequency out of range\n",unit); 2280 return(EINVAL); 2281 } 2282#endif 2283 temp_mute( bktr, TRUE ); 2284 temp = tv_freq( bktr, temp ); 2285 temp_mute( bktr, FALSE ); 2286#ifdef BKTR_RADIO_DEBUG 2287 if(temp) 2288 printf("bktr%d: tv_freq returned: %d\n",unit,temp); 2289#endif 2290 if ( temp < 0 ) 2291 return( EINVAL ); 2292 *(unsigned long *)arg = temp; 2293 break; 2294 2295 |
2296 default: 2297 return common_ioctl( bktr, bt848, cmd, arg ); 2298 } 2299 2300 return( 0 ); 2301} 2302 2303 2304/* 2305 * common ioctls 2306 */ 2307int 2308common_ioctl( bktr_ptr_t bktr, bt848_ptr_t bt848, int cmd, caddr_t arg ) 2309{ 2310 int pixfmt; 2311 unsigned int temp; 2312 struct meteor_pixfmt *pf_pub; 2313 2314 switch (cmd) { 2315 2316 case METEORSINPUT: /* set input device */ 2317 switch(*(unsigned long *)arg & METEOR_DEV_MASK) { 2318 2319 /* this is the RCA video input */ 2320 case 0: /* default */ 2321 case METEOR_INPUT_DEV0: 2322 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2323 | METEOR_DEV0; 2324 bt848->iform &= ~BT848_IFORM_MUXSEL; 2325 bt848->iform |= BT848_IFORM_M_MUX1; 2326 bt848->e_control &= ~BT848_E_CONTROL_COMP; 2327 bt848->o_control &= ~BT848_O_CONTROL_COMP; 2328 set_audio( bktr, AUDIO_EXTERN ); 2329 break; 2330 2331 /* this is the tuner input */ 2332 case METEOR_INPUT_DEV1: 2333 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2334 | METEOR_DEV1; 2335 bt848->iform &= ~BT848_IFORM_MUXSEL; 2336 bt848->iform |= BT848_IFORM_M_MUX0; 2337 bt848->e_control &= ~BT848_E_CONTROL_COMP; 2338 bt848->o_control &= ~BT848_O_CONTROL_COMP; 2339 set_audio( bktr, AUDIO_TUNER ); 2340 break; 2341 2342 /* this is the S-VHS input */ 2343 case METEOR_INPUT_DEV2: 2344 case METEOR_INPUT_DEV_SVIDEO: 2345 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2346 | METEOR_DEV2; 2347 bt848->iform &= ~BT848_IFORM_MUXSEL; 2348 bt848->iform |= BT848_IFORM_M_MUX2; 2349 bt848->e_control |= BT848_E_CONTROL_COMP; 2350 bt848->o_control |= BT848_O_CONTROL_COMP; 2351 set_audio( bktr, AUDIO_EXTERN ); 2352 break; 2353 2354 default: 2355 return( EINVAL ); 2356 } 2357 break; 2358 2359 case METEORGINPUT: /* get input device */ 2360 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK; 2361 break; 2362 2363 case METEORSACTPIXFMT: 2364 if (( *(int *)arg < 0 ) || 2365 ( *(int *)arg >= PIXFMT_TABLE_SIZE )) 2366 return( EINVAL ); 2367 2368 bktr->pixfmt = *(int *)arg; 2369 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt ); 2370 bktr->pixfmt_compat = FALSE; 2371 break; 2372 2373 case METEORGACTPIXFMT: 2374 *(int *)arg = bktr->pixfmt; 2375 break; 2376 2377 case METEORGSUPPIXFMT : 2378 pf_pub = (struct meteor_pixfmt *)arg; 2379 pixfmt = pf_pub->index; 2380 2381 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE )) 2382 return( EINVAL ); 2383 2384 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public, 2385 sizeof( *pf_pub ) ); 2386 2387 /* Patch in our format index */ 2388 pf_pub->index = pixfmt; 2389 break; 2390 2391#if defined( STATUS_SUM ) 2392 case BT848_GSTATUS: /* reap status */ 2393 disable_intr(); 2394 temp = status_sum; 2395 status_sum = 0; 2396 enable_intr(); 2397 *(u_int*)arg = temp; 2398 break; 2399#endif /* STATUS_SUM */ 2400 2401 default: 2402 return( ENOTTY ); 2403 } 2404 2405 return( 0 ); 2406} 2407 2408 2409/* 2410 * 2411 */ 2412int 2413bktr_mmap( dev_t dev, int offset, int nprot ) 2414{ 2415 int unit; 2416 bktr_ptr_t bktr; 2417 2418 unit = UNIT(minor(dev)); 2419 2420 if (unit >= NBKTR || MINOR(minor(dev)) > 0)/* could this happen here? */ 2421 return( -1 ); 2422 2423 bktr = &(brooktree[ unit ]); 2424 2425 if (nprot & PROT_EXEC) 2426 return( -1 ); 2427 2428 if (offset >= bktr->alloc_pages * PAGE_SIZE) 2429 return( -1 ); 2430 2431 return( i386_btop(vtophys(bktr->bigbuf) + offset) ); 2432} 2433 2434 2435/****************************************************************************** 2436 * bt848 RISC programming routines: 2437 */ 2438 2439 2440/* 2441 * 2442 */ 2443#ifdef BT848_DEBUG 2444static int 2445dump_bt848( bt848_ptr_t bt848 ) 2446{ 2447 volatile u_char *bt848r = (u_char *)bt848; 2448 int r[60]={ 2449 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94, 2450 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4, 2451 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40, 2452 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60, 2453 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4, 2454 0, 0, 0, 0 2455 }; 2456 int i; 2457 2458 for (i = 0; i < 40; i+=4) { 2459 printf(" Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n", 2460 r[i], bt848r[r[i]], 2461 r[i+1], bt848r[r[i+1]], 2462 r[i+2], bt848r[r[i+2]], 2463 r[i+3], bt848r[r[i+3]]); 2464 } 2465 2466 printf(" INT STAT %x \n", bt848->int_stat); 2467 printf(" Reg INT_MASK %x \n", bt848->int_mask); 2468 printf(" Reg GPIO_DMA_CTL %x \n", bt848->gpio_dma_ctl); 2469 2470 return( 0 ); 2471} 2472 2473#endif 2474 2475/* 2476 * build write instruction 2477 */ 2478#define BKTR_FM1 0x6 /* packed data to follow */ 2479#define BKTR_FM3 0xe /* planar data to follow */ 2480#define BKTR_VRE 0x4 /* even field to follow */ 2481#define BKTR_VRO 0xC /* odd field to follow */ 2482#define BKTR_PXV 0x0 /* valid word (never used) */ 2483#define BKTR_EOL 0x1 /* last dword, 4 bytes */ 2484#define BKTR_SOL 0x2 /* first dword */ 2485 2486#define OP_WRITE (0x1 << 28) 2487#define OP_SKIP (0x2 << 28) 2488#define OP_WRITEC (0x5 << 28) 2489#define OP_JUMP (0x7 << 28) 2490#define OP_SYNC (0x8 << 28) 2491#define OP_WRITE123 (0x9 << 28) 2492#define OP_WRITES123 (0xb << 28) 2493#define OP_SOL (1 << 27) /* first instr for scanline */ 2494#define OP_EOL (1 << 26) 2495 2496bool_t notclipped (bktr_reg_t * bktr, int x, int width) { 2497 int i; 2498 bktr_clip_t * clip_node; 2499 bktr->clip_start = -1; 2500 bktr->last_y = 0; 2501 bktr->y = 0; 2502 bktr->y2 = width; 2503 bktr->line_length = width; 2504 bktr->yclip = -1; 2505 bktr->yclip2 = -1; 2506 bktr->current_col = 0; 2507 2508 if (bktr->max_clip_node == 0 ) return TRUE; 2509 clip_node = (bktr_clip_t *) &bktr->clip_list[0]; 2510 2511 2512 for (i = 0; i < bktr->max_clip_node; i++ ) { 2513 clip_node = (bktr_clip_t *) &bktr->clip_list[i]; 2514 if (x >= clip_node->x_min && x <= clip_node->x_max ) { 2515 bktr->clip_start = i; 2516 return FALSE; 2517 } 2518 } 2519 2520 return TRUE; 2521} 2522 2523bool_t getline(bktr_reg_t *bktr, int x ) { 2524 int i, j; 2525 bktr_clip_t * clip_node ; 2526 2527 if (bktr->line_length == 0 || 2528 bktr->current_col >= bktr->line_length) return FALSE; 2529 2530 bktr->y = min(bktr->last_y, bktr->line_length); 2531 bktr->y2 = bktr->line_length; 2532 2533 bktr->yclip = bktr->yclip2 = -1; 2534 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) { 2535 clip_node = (bktr_clip_t *) &bktr->clip_list[i]; 2536 if (x >= clip_node->x_min && x <= clip_node->x_max) { 2537 if (bktr->last_y <= clip_node->y_min) { 2538 bktr->y = min(bktr->last_y, bktr->line_length); 2539 bktr->y2 = min(clip_node->y_min, bktr->line_length); 2540 bktr->yclip = min(clip_node->y_min, bktr->line_length); 2541 bktr->yclip2 = min(clip_node->y_max, bktr->line_length); 2542 bktr->last_y = bktr->yclip2; 2543 bktr->clip_start = i; 2544 2545 for (j = i+1; j < bktr->max_clip_node; j++ ) { 2546 clip_node = (bktr_clip_t *) &bktr->clip_list[j]; 2547 if (x >= clip_node->x_min && x <= clip_node->x_max) { 2548 if (bktr->last_y >= clip_node->y_min) { 2549 bktr->yclip2 = min(clip_node->y_max, bktr->line_length); 2550 bktr->last_y = bktr->yclip2; 2551 bktr->clip_start = j; 2552 } 2553 } else break ; 2554 } 2555 return TRUE; 2556 } 2557 } 2558 } 2559 2560 if (bktr->current_col <= bktr->line_length) { 2561 bktr->current_col = bktr->line_length; 2562 return TRUE; 2563 } 2564 return FALSE; 2565} 2566 2567static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width , 2568 u_long operation, int pixel_width, 2569 volatile u_char ** target_buffer, int cols ) { 2570 2571 u_long flag, flag2; 2572 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public; 2573 u_int skip, start_skip; 2574 2575 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */ 2576 /* to the 1st byte in the mem dword containing our start addr. */ 2577 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */ 2578 /* must be Blue. */ 2579 start_skip = 0; 2580 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 )) 2581 switch ( ((u_long) *target_buffer) % 4 ) { 2582 case 2 : start_skip = 4 ; break; 2583 case 1 : start_skip = 8 ; break; 2584 } 2585 2586 if ((width * pixel_width) < DMA_BT848_SPLIT ) { 2587 if ( width == cols) { 2588 flag = OP_SOL | OP_EOL; 2589 } else if (bktr->current_col == 0 ) { 2590 flag = OP_SOL; 2591 } else if (bktr->current_col == cols) { 2592 flag = OP_EOL; 2593 } else flag = 0; 2594 2595 skip = 0; 2596 if (( flag & OP_SOL ) && ( start_skip > 0 )) { 2597 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip; 2598 flag &= ~OP_SOL; 2599 skip = start_skip; 2600 } 2601 2602 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip); 2603 if (operation != OP_SKIP ) 2604 *(*dma_prog)++ = (u_long) *target_buffer; 2605 2606 *target_buffer += width * pixel_width; 2607 bktr->current_col += width; 2608 2609 } else { 2610 2611 if (bktr->current_col == 0 && width == cols) { 2612 flag = OP_SOL ; 2613 flag2 = OP_EOL; 2614 } else if (bktr->current_col == 0 ) { 2615 flag = OP_SOL; 2616 flag2 = 0; 2617 } else if (bktr->current_col >= cols) { 2618 flag = 0; 2619 flag2 = OP_EOL; 2620 } else { 2621 flag = 0; 2622 flag2 = 0; 2623 } 2624 2625 skip = 0; 2626 if (( flag & OP_SOL ) && ( start_skip > 0 )) { 2627 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip; 2628 flag &= ~OP_SOL; 2629 skip = start_skip; 2630 } 2631 2632 *(*dma_prog)++ = operation | flag | 2633 (width * pixel_width / 2 - skip); 2634 if (operation != OP_SKIP ) 2635 *(*dma_prog)++ = (u_long ) *target_buffer ; 2636 *target_buffer += (width * pixel_width / 2) ; 2637 2638 if ( operation == OP_WRITE ) 2639 operation = OP_WRITEC; 2640 *(*dma_prog)++ = operation | flag2 | 2641 (width * pixel_width / 2); 2642 *target_buffer += (width * pixel_width / 2) ; 2643 bktr->current_col += width; 2644 2645 } 2646 return TRUE; 2647} 2648 2649 2650 2651 2652static void 2653rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) 2654{ 2655 int i; 2656 bt848_ptr_t bt848; 2657 volatile u_long target_buffer, buffer, target,width; 2658 volatile u_long pitch; 2659 volatile u_long *dma_prog; 2660 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2661 u_int Bpp = pf_int->public.Bpp; 2662 2663 bt848 = bktr->base; 2664 2665 bt848->color_fmt = pf_int->color_fmt; 2666 bt848->vbi_pack_size = 0; 2667 bt848->vbi_pack_del = 0; 2668 bt848->adc = SYNC_LEVEL; 2669 bt848->color_ctl_rgb_ded = 1; 2670 2671 bt848->e_vscale_hi |= 0xc0; 2672 bt848->o_vscale_hi |= 0xc0; 2673 if (cols > 385 ) { 2674 bt848->e_vtc = 0; 2675 bt848->o_vtc = 0; 2676 } else { 2677 bt848->e_vtc = 1; 2678 bt848->o_vtc = 1; 2679 } 2680 bktr->capcontrol = 3 << 2 | 3; 2681 2682 dma_prog = (u_long *) bktr->dma_prog; 2683 2684 /* Construct Write */ 2685 2686 if (bktr->video.addr) { 2687 target_buffer = (u_long) bktr->video.addr; 2688 pitch = bktr->video.width; 2689 } 2690 else { 2691 target_buffer = (u_long) vtophys(bktr->bigbuf); 2692 pitch = cols*Bpp; 2693 } 2694 2695 buffer = target_buffer;
|
2669 if (interlace == 2 && rows < 320 ) target_buffer += pitch;
|
2696
|
2697 |
2698 /* contruct sync : for video packet format */ 2699 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1; 2700 2701 /* sync, mode indicator packed data */ 2702 *dma_prog++ = 0; /* NULL WORD */ 2703 width = cols; 2704 for (i = 0; i < (rows/interlace); i++) { 2705 target = target_buffer; 2706 if ( notclipped(bktr, i, width)) { 2707 split(bktr, (volatile u_long **) &dma_prog, 2708 bktr->y2 - bktr->y, OP_WRITE, 2709 Bpp, (volatile u_char **) &target, cols); 2710 2711 } else { 2712 while(getline(bktr, i)) { 2713 if (bktr->y != bktr->y2 ) { 2714 split(bktr, (volatile u_long **) &dma_prog, 2715 bktr->y2 - bktr->y, OP_WRITE, 2716 Bpp, (volatile u_char **) &target, cols); 2717 } 2718 if (bktr->yclip != bktr->yclip2 ) { 2719 split(bktr,(volatile u_long **) &dma_prog, 2720 bktr->yclip2 - bktr->yclip, 2721 OP_SKIP, 2722 Bpp, (volatile u_char **) &target, cols); 2723 } 2724 } 2725 2726 } 2727 2728 target_buffer += interlace * pitch; 2729 2730 } 2731 2732 switch (i_flag) { 2733 case 1: 2734 /* sync vre */
|
2708 *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE;
|
2735 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; |
2736 *dma_prog++ = 0; /* NULL WORD */ 2737
|
2711 *dma_prog++ = OP_JUMP | 0xC << 24;
|
2738 *dma_prog++ = OP_JUMP; |
2739 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2740 return; 2741 2742 case 2: 2743 /* sync vro */
|
2717 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 20 | BKTR_VRO;
|
2744 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; |
2745 *dma_prog++ = 0; /* NULL WORD */ 2746 2747 *dma_prog++ = OP_JUMP; 2748 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2749 return; 2750 2751 case 3: 2752 /* sync vro */ 2753 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; 2754 *dma_prog++ = 0; /* NULL WORD */
|
2728 *dma_prog++ = OP_JUMP | 0xc << 24 ;
|
2755 *dma_prog++ = OP_JUMP; ; |
2756 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 2757 break; 2758 } 2759 2760 if (interlace == 2) {
|
2734 if (rows < 320 )
2735 target_buffer = buffer ;
2736 else
2737 target_buffer = buffer + pitch;
|
2761
|
2762 target_buffer = buffer + pitch; 2763 |
2764 dma_prog = (u_long *) bktr->odd_dma_prog; 2765 2766 2767 /* sync vre IRQ bit */ 2768 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1; 2769 *dma_prog++ = 0; /* NULL WORD */ 2770 width = cols; 2771 for (i = 0; i < (rows/interlace); i++) { 2772 target = target_buffer; 2773 if ( notclipped(bktr, i, width)) { 2774 split(bktr, (volatile u_long **) &dma_prog, 2775 bktr->y2 - bktr->y, OP_WRITE, 2776 Bpp, (volatile u_char **) &target, cols); 2777 } else { 2778 while(getline(bktr, i)) { 2779 if (bktr->y != bktr->y2 ) { 2780 split(bktr, (volatile u_long **) &dma_prog, 2781 bktr->y2 - bktr->y, OP_WRITE, 2782 Bpp, (volatile u_char **) &target, 2783 cols); 2784 } 2785 if (bktr->yclip != bktr->yclip2 ) { 2786 split(bktr, (volatile u_long **) &dma_prog, 2787 bktr->yclip2 - bktr->yclip, OP_SKIP, 2788 Bpp, (volatile u_char **) &target, cols); 2789 } 2790 2791 } 2792 2793 } 2794 2795 target_buffer += interlace * pitch; 2796 2797 } 2798 } 2799 2800 /* sync vre IRQ bit */ 2801 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; 2802 *dma_prog++ = 0; /* NULL WORD */ 2803 *dma_prog++ = OP_JUMP ; 2804 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; 2805 *dma_prog++ = 0; /* NULL WORD */ 2806} 2807 2808 2809/* 2810 * 2811 */ 2812static void 2813yuvpack_prog( bktr_ptr_t bktr, char i_flag, 2814 int cols, int rows, int interlace ) 2815{ 2816 int i; 2817 volatile unsigned int inst; 2818 volatile unsigned int inst3; 2819 volatile u_long target_buffer, buffer; 2820 bt848_ptr_t bt848; 2821 volatile u_long *dma_prog; 2822 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2823 int b; 2824 2825 bt848 = bktr->base; 2826 2827 bt848->color_fmt = pf_int->color_fmt; 2828 2829 bt848->e_scloop |= BT848_E_SCLOOP_CAGC; /* enable chroma comb */ 2830 bt848->o_scloop |= BT848_O_SCLOOP_CAGC; 2831 2832 bt848->color_ctl_rgb_ded = 1; 2833 bt848->color_ctl_gamma = 1; 2834 bt848->adc = SYNC_LEVEL; 2835 2836 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3; 2837 bktr->capcontrol = 3 << 2 | 3; 2838 2839 dma_prog = (u_long *) bktr->dma_prog; 2840 2841 /* Construct Write */ 2842 2843 /* write , sol, eol */ 2844 inst = OP_WRITE | OP_SOL | (cols); 2845 /* write , sol, eol */ 2846 inst3 = OP_WRITE | OP_EOL | (cols); 2847 2848 if (bktr->video.addr) 2849 target_buffer = (u_long) bktr->video.addr; 2850 else 2851 target_buffer = (u_long) vtophys(bktr->bigbuf); 2852 2853 buffer = target_buffer; 2854 2855 /* contruct sync : for video packet format */ 2856 /* sync, mode indicator packed data */ 2857 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1; 2858 *dma_prog++ = 0; /* NULL WORD */ 2859 2860 b = cols; 2861 2862 for (i = 0; i < (rows/interlace); i++) { 2863 *dma_prog++ = inst; 2864 *dma_prog++ = target_buffer; 2865 *dma_prog++ = inst3; 2866 *dma_prog++ = target_buffer + b; 2867 target_buffer += interlace*(cols * 2); 2868 } 2869 2870 switch (i_flag) { 2871 case 1: 2872 /* sync vre */
|
2848 *dma_prog++ = OP_SYNC | 0xC << 24 | BKTR_VRE;
|
2873 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; |
2874 *dma_prog++ = 0; /* NULL WORD */ 2875 2876 *dma_prog++ = OP_JUMP; 2877 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2878 return; 2879 2880 case 2: 2881 /* sync vro */
|
2857 *dma_prog++ = OP_SYNC | 0xC << 24 | BKTR_VRO;
|
2882 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; |
2883 *dma_prog++ = 0; /* NULL WORD */ 2884 *dma_prog++ = OP_JUMP; 2885 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2886 return; 2887 2888 case 3:
|
2864 /* sync vre */
2865 *dma_prog++ = OP_SYNC | BKTR_VRE;
|
2889 /* sync vro */ 2890 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; |
2891 *dma_prog++ = 0; /* NULL WORD */ 2892 *dma_prog++ = OP_JUMP ; 2893 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 2894 break; 2895 } 2896 2897 if (interlace == 2) { 2898 2899 target_buffer = (u_long) buffer + cols*2; 2900 2901 dma_prog = (u_long * ) bktr->odd_dma_prog; 2902 2903 /* sync vre */ 2904 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1; 2905 *dma_prog++ = 0; /* NULL WORD */ 2906 2907 for (i = 0; i < (rows/interlace) ; i++) { 2908 *dma_prog++ = inst; 2909 *dma_prog++ = target_buffer; 2910 *dma_prog++ = inst3; 2911 *dma_prog++ = target_buffer + b; 2912 target_buffer += interlace * ( cols*2); 2913 } 2914 } 2915 2916 /* sync vro IRQ bit */
|
2892 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
|
2917 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; |
2918 *dma_prog++ = 0; /* NULL WORD */ 2919 *dma_prog++ = OP_JUMP ; 2920 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2921 2922 *dma_prog++ = OP_JUMP; 2923 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2924 *dma_prog++ = 0; /* NULL WORD */ 2925} 2926 2927 2928/* 2929 * 2930 */ 2931static void 2932yuv422_prog( bktr_ptr_t bktr, char i_flag, 2933 int cols, int rows, int interlace ){ 2934 2935 int i; 2936 volatile unsigned int inst; 2937 volatile u_long target_buffer, t1, buffer; 2938 bt848_ptr_t bt848; 2939 volatile u_long *dma_prog; 2940 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2941 2942 bt848 = bktr->base; 2943 2944 bt848->color_fmt = pf_int->color_fmt; 2945 2946 dma_prog = (u_long *) bktr->dma_prog; 2947 2948 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 2949 2950 bt848->adc = SYNC_LEVEL; 2951 bt848->oform = 0x00; 2952 2953 bt848->e_control |= BT848_E_CONTROL_LDEC; /* disable luma decimation */ 2954 bt848->o_control |= BT848_O_CONTROL_LDEC; 2955 2956 bt848->e_scloop |= BT848_O_SCLOOP_CAGC; /* chroma agc enable */ 2957 bt848->o_scloop |= BT848_O_SCLOOP_CAGC; 2958 2959 bt848->e_vscale_hi &= ~0x80; /* clear Ycomb */ 2960 bt848->o_vscale_hi &= ~0x80; 2961 bt848->e_vscale_hi |= 0x40; /* set chroma comb */ 2962 bt848->o_vscale_hi |= 0x40; 2963 2964 /* disable gamma correction removal */ 2965 bt848->color_ctl_gamma = 1; 2966 2967 /* Construct Write */ 2968 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 2969 if (bktr->video.addr) 2970 target_buffer = (u_long) bktr->video.addr; 2971 else 2972 target_buffer = (u_long) vtophys(bktr->bigbuf); 2973 2974 buffer = target_buffer; 2975
|
2951 t1 = target_buffer;
|
2976 t1 = buffer; |
2977 2978 /* contruct sync : for video packet format */ 2979 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ 2980 *dma_prog++ = 0; /* NULL WORD */ 2981
|
2957 for (i = 0; i < (rows/interlace ) - 1; i++) {
|
2982 for (i = 0; i < (rows/interlace ) ; i++) { |
2983 *dma_prog++ = inst; 2984 *dma_prog++ = cols/2 | cols/2 << 16; 2985 *dma_prog++ = target_buffer; 2986 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 2987 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace; 2988 target_buffer += interlace*cols; 2989 } 2990 2991 switch (i_flag) { 2992 case 1:
|
2968 *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRE; /*sync vre*/
|
2993 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ |
2994 *dma_prog++ = 0; /* NULL WORD */ 2995
|
2971 *dma_prog++ = OP_JUMP | 0xc << 24;
|
2996 *dma_prog++ = OP_JUMP ; |
2997 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2998 return; 2999 3000 case 2:
|
2976 *dma_prog++ = OP_SYNC | 0xC << 24 | 1 << 24 | BKTR_VRO; /*sync vre*/
|
3001 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/ |
3002 *dma_prog++ = 0; /* NULL WORD */ 3003 3004 *dma_prog++ = OP_JUMP; 3005 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3006 return; 3007 3008 case 3:
|
2984 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_VRO;
|
3009 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; |
3010 *dma_prog++ = 0; /* NULL WORD */ 3011 3012 *dma_prog++ = OP_JUMP ; 3013 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 3014 break; 3015 } 3016 3017 if (interlace == 2) { 3018 3019 dma_prog = (u_long * ) bktr->odd_dma_prog; 3020 3021 target_buffer = (u_long) buffer + cols;
|
2997 t1 = target_buffer + cols/2;
|
3022 t1 = buffer + cols/2; |
3023 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; 3024 *dma_prog++ = 0; /* NULL WORD */ 3025
|
3001 for (i = 0; i < (rows/interlace ) - 1; i++) {
|
3026 for (i = 0; i < (rows/interlace ) ; i++) { |
3027 *dma_prog++ = inst; 3028 *dma_prog++ = cols/2 | cols/2 << 16; 3029 *dma_prog++ = target_buffer; 3030 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3031 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace; 3032 target_buffer += interlace*cols; 3033 } 3034 } 3035
|
3011 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
|
3036 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; |
3037 *dma_prog++ = 0; /* NULL WORD */ 3038 *dma_prog++ = OP_JUMP ; 3039 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; 3040 *dma_prog++ = 0; /* NULL WORD */ 3041} 3042 3043 3044/* 3045 * 3046 */ 3047static void 3048yuv12_prog( bktr_ptr_t bktr, char i_flag, 3049 int cols, int rows, int interlace ){ 3050
|
3026 int i, k;
|
3051 int i; |
3052 volatile unsigned int inst; 3053 volatile unsigned int inst1; 3054 volatile u_long target_buffer, t1, buffer; 3055 bt848_ptr_t bt848; 3056 volatile u_long *dma_prog; 3057 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3058 3059 bt848 = bktr->base; 3060 3061 bt848->color_fmt = pf_int->color_fmt; 3062 3063 dma_prog = (u_long *) bktr->dma_prog; 3064 3065 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 3066 3067 bt848->adc = SYNC_LEVEL; 3068 bt848->oform = 0x00; 3069 3070 bt848->e_control |= BT848_E_CONTROL_LDEC; /* disable luma decimation */ 3071 bt848->o_control |= BT848_O_CONTROL_LDEC; 3072 3073 bt848->e_scloop |= BT848_O_SCLOOP_CAGC; /* chroma agc enable */ 3074 bt848->o_scloop |= BT848_O_SCLOOP_CAGC; 3075 3076 bt848->e_vscale_hi &= ~0x80; /* clear Ycomb */ 3077 bt848->o_vscale_hi &= ~0x80; 3078 bt848->e_vscale_hi |= 0x40; /* set chroma comb */ 3079 bt848->o_vscale_hi |= 0x40; 3080 3081 /* disable gamma correction removal */ 3082 bt848->color_ctl_gamma = 1; 3083 3084 /* Construct Write */ 3085 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 3086 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols); 3087 if (bktr->video.addr) 3088 target_buffer = (u_long) bktr->video.addr; 3089 else 3090 target_buffer = (u_long) vtophys(bktr->bigbuf); 3091 3092 buffer = target_buffer; 3093 t1 = buffer; 3094 3095 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ 3096 *dma_prog++ = 0; /* NULL WORD */
|
3072 if (i_flag > 2)
3073 k = 1;
3074 else k = 0;
|
3097
|
3076 for (i = 0; i < (rows/interlace )/2 - k; i++) {
|
3098 for (i = 0; i < (rows/interlace )/2 ; i++) { |
3099 *dma_prog++ = inst; 3100 *dma_prog++ = cols/2 | (cols/2 << 16); 3101 *dma_prog++ = target_buffer; 3102 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3103 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace; 3104 target_buffer += interlace*cols; 3105 *dma_prog++ = inst1; 3106 *dma_prog++ = cols/2 | (cols/2 << 16); 3107 *dma_prog++ = target_buffer; 3108 target_buffer += interlace*cols; 3109 3110 } 3111 3112 switch (i_flag) { 3113 case 1:
|
3092 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
|
3114 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ |
3115 *dma_prog++ = 0; /* NULL WORD */
|
3094
3095 *dma_prog++ = OP_JUMP ;
3096 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
|
3116 3117 *dma_prog++ = OP_JUMP; 3118 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); |
3119 return; 3120 3121 case 2:
|
3100 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
|
3122 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/ |
3123 *dma_prog++ = 0; /* NULL WORD */
|
3102
3103 *dma_prog++ = OP_JUMP ;
3104 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
|
3124 3125 *dma_prog++ = OP_JUMP; 3126 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); |
3127 return; 3128 3129 case 3: 3130 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; 3131 *dma_prog++ = 0; /* NULL WORD */
|
3110 *dma_prog++ = OP_JUMP | 0xC << 24;
|
3132 *dma_prog++ = OP_JUMP ; |
3133 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 3134 break; 3135 } 3136 3137 if (interlace == 2) { 3138 3139 dma_prog = (u_long * ) bktr->odd_dma_prog; 3140 3141 target_buffer = (u_long) buffer + cols;
|
3120 t1 = target_buffer + cols/2;
3121 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_FM3;
|
3142 t1 = buffer + cols/2; 3143 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; |
3144 *dma_prog++ = 0; /* NULL WORD */ 3145 3146 for (i = 0; i < ((rows/interlace )/2 ) ; i++) { 3147 *dma_prog++ = inst; 3148 *dma_prog++ = cols/2 | (cols/2 << 16); 3149 *dma_prog++ = target_buffer; 3150 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3151 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace; 3152 target_buffer += interlace*cols; 3153 *dma_prog++ = inst1; 3154 *dma_prog++ = cols/2 | (cols/2 << 16); 3155 *dma_prog++ = target_buffer; 3156 target_buffer += interlace*cols; 3157 3158 } 3159 3160 3161 } 3162 3163 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; 3164 *dma_prog++ = 0; /* NULL WORD */
|
3143 *dma_prog++ = OP_JUMP | 0xC << 24;
|
3165 *dma_prog++ = OP_JUMP; |
3166 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3167 *dma_prog++ = 0; /* NULL WORD */ 3168} 3169 3170 3171 3172/* 3173 * 3174 */ 3175static void 3176build_dma_prog( bktr_ptr_t bktr, char i_flag ) 3177{ 3178 int rows, cols, interlace; 3179 bt848_ptr_t bt848;
|
3180 int tmp_int; 3181 unsigned int temp; 3182 struct format_params *fp; |
3183 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
|
3184 |
3185
|
3186 fp = &format_params[bktr->format_params]; 3187 |
3188 bt848 = bktr->base; 3189 bt848->int_mask = ALL_INTS_DISABLED; 3190 3191 /* disable FIFO & RISC, leave other bits alone */ 3192 bt848->gpio_dma_ctl &= ~FIFO_RISC_ENABLED; 3193
|
3194 /* set video parameters */ 3195 temp = ((quad_t ) fp->htotal* (quad_t) fp->horizontal * 4096 3196 / fp->vertical / bktr->cols) - 4096; 3197 bt848->e_hscale_lo = temp & 0xff; 3198 bt848->o_hscale_lo = temp & 0xff; 3199 bt848->e_hscale_hi = (temp >> 8) & 0xff; 3200 bt848->o_hscale_hi = (temp >> 8) & 0xff; 3201 3202 /* horizontal active */ 3203 temp = bktr->cols; 3204 bt848->e_hactive_lo = temp & 0xff; 3205 bt848->o_hactive_lo = temp & 0xff; 3206 bt848->e_crop &= ~0x3; 3207 bt848->o_crop &= ~0x3; 3208 bt848->e_crop |= (temp >> 8) & 0x3; 3209 bt848->o_crop |= (temp >> 8) & 0x3; 3210 3211 /* horizontal delay */ 3212 temp = (fp->hdelay * bktr->cols) / fp->hactive; 3213 temp = temp & 0x3fe; 3214 bt848->e_delay_lo = temp & 0xff; 3215 bt848->o_delay_lo = temp & 0xff; 3216 bt848->e_crop &= ~0xc; 3217 bt848->o_crop &= ~0xc; 3218 bt848->e_crop |= (temp >> 6) & 0xc; 3219 bt848->o_crop |= (temp >> 6) & 0xc; 3220 3221 /* vertical scale */ 3222 3223 if (bktr->flags & METEOR_ONLY_ODD_FIELDS || 3224 bktr->flags & METEOR_ONLY_EVEN_FIELDS) 3225 tmp_int = 65536 - 3226 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512); 3227 else { 3228 tmp_int = 65536 - 3229 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512); 3230 } 3231 3232 tmp_int &= 0x1fff; 3233 bt848->e_vscale_lo = tmp_int & 0xff; 3234 bt848->o_vscale_lo = tmp_int & 0xff; 3235 bt848->e_vscale_hi &= ~0x1f; 3236 bt848->o_vscale_hi &= ~0x1f; 3237 bt848->e_vscale_hi |= (tmp_int >> 8) & 0x1f; 3238 bt848->o_vscale_hi |= (tmp_int >> 8) & 0x1f; 3239 3240 3241 /* vertical active */ 3242 bt848->e_crop &= ~0x30; 3243 bt848->e_crop |= (fp->vactive >> 4) & 0x30; 3244 bt848->e_vactive_lo = fp->vactive & 0xff; 3245 bt848->o_crop &= ~0x30; 3246 bt848->o_crop |= (fp->vactive >> 4) & 0x30; 3247 bt848->o_vactive_lo = fp->vactive & 0xff; 3248 3249 /* vertical delay */ 3250 bt848->e_vdelay_lo = fp->vdelay; 3251 bt848->o_vdelay_lo = fp->vdelay; 3252 3253 /* end of video params */ 3254 |
3255 /* capture control */ 3256 switch (i_flag) { 3257 case 1: 3258 bktr->bktr_cap_ctl = 3259 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN); 3260 bt848->e_vscale_hi &= ~0x20; 3261 bt848->o_vscale_hi &= ~0x20; 3262 interlace = 1; 3263 break; 3264 case 2: 3265 bktr->bktr_cap_ctl = 3266 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD); 3267 bt848->e_vscale_hi &= ~0x20; 3268 bt848->o_vscale_hi &= ~0x20; 3269 interlace = 1; 3270 break; 3271 default: 3272 bktr->bktr_cap_ctl = 3273 (BT848_CAP_CTL_DITH_FRAME | 3274 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD); 3275 bt848->e_vscale_hi |= 0x20; 3276 bt848->o_vscale_hi |= 0x20; 3277 interlace = 2; 3278 break; 3279 } 3280 3281 bt848->risc_strt_add = vtophys(bktr->dma_prog); 3282 3283 rows = bktr->rows; 3284 cols = bktr->cols; 3285 3286 if ( pf_int->public.type == METEOR_PIXTYPE_RGB ) { 3287 rgb_prog(bktr, i_flag, cols, rows, interlace); 3288 return; 3289 } 3290 3291 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) { 3292 yuv422_prog(bktr, i_flag, cols, rows, interlace); 3293 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt ); 3294 return; 3295 } 3296 3297 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) { 3298 yuvpack_prog(bktr, i_flag, cols, rows, interlace); 3299 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt ); 3300 return; 3301 } 3302 3303 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) { 3304 yuv12_prog(bktr, i_flag, cols, rows, interlace); 3305 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt ); 3306 return; 3307 } 3308 return; 3309} 3310 3311 3312/****************************************************************************** 3313 * video & video capture specific routines: 3314 */ 3315 3316 3317/* 3318 * 3319 */ 3320static void 3321start_capture( bktr_ptr_t bktr, unsigned type ) 3322{ 3323 bt848_ptr_t bt848; 3324 u_char i_flag; 3325 struct format_params *fp; 3326 3327 fp = &format_params[bktr->format_params]; 3328 3329 bt848 = bktr->base; 3330 3331 bt848->dstatus = 0; 3332 bt848->int_stat = bt848->int_stat; 3333 3334 bktr->flags |= type; 3335 bktr->flags &= ~METEOR_WANT_MASK; 3336 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3337 case METEOR_ONLY_EVEN_FIELDS: 3338 bktr->flags |= METEOR_WANT_EVEN; 3339 i_flag = 1; 3340 break; 3341 case METEOR_ONLY_ODD_FIELDS: 3342 bktr->flags |= METEOR_WANT_ODD; 3343 i_flag = 2; 3344 break; 3345 default: 3346 bktr->flags |= METEOR_WANT_MASK; 3347 i_flag = 3; 3348 break; 3349 } 3350 3351 /* TDEC is only valid for continuous captures */ 3352 if ( type == METEOR_SINGLE ) { 3353 u_short fps_save = bktr->fps; 3354 3355 set_fps(bktr, fp->frame_rate); 3356 bktr->fps = fps_save; 3357 } 3358 else 3359 set_fps(bktr, bktr->fps); 3360 3361 if (bktr->dma_prog_loaded == FALSE) { 3362 build_dma_prog(bktr, i_flag); 3363 bktr->dma_prog_loaded = TRUE; 3364 } 3365 3366 3367 bt848->risc_strt_add = vtophys(bktr->dma_prog); 3368 3369} 3370 3371 3372/* 3373 * 3374 */ 3375static void 3376set_fps( bktr_ptr_t bktr, u_short fps ) 3377{ 3378 bt848_ptr_t bt848; 3379 struct format_params *fp; 3380 int i_flag; 3381 3382 fp = &format_params[bktr->format_params]; 3383 3384 bt848 = bktr->base; 3385 3386 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3387 case METEOR_ONLY_EVEN_FIELDS: 3388 bktr->flags |= METEOR_WANT_EVEN; 3389 i_flag = 1; 3390 break; 3391 case METEOR_ONLY_ODD_FIELDS: 3392 bktr->flags |= METEOR_WANT_ODD; 3393 i_flag = 1; 3394 break; 3395 default: 3396 bktr->flags |= METEOR_WANT_MASK; 3397 i_flag = 2; 3398 break; 3399 } 3400 3401 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; 3402 bt848->int_stat = ALL_INTS_CLEARED; 3403 3404 bktr->fps = fps; 3405 bt848->tdec = 0; 3406 3407 if (fps < fp->frame_rate) 3408 bt848->tdec = i_flag*(fp->frame_rate - fps) & 0x3f; 3409 else 3410 bt848->tdec = 0; 3411 return; 3412 3413} 3414 3415 3416/* 3417 * There is also a problem with range checking on the 7116. 3418 * It seems to only work for 22 bits, so the max size we can allocate 3419 * is 22 bits long or 4194304 bytes assuming that we put the beginning 3420 * of the buffer on a 2^24 bit boundary. The range registers will use 3421 * the top 8 bits of the dma start registers along with the bottom 22 3422 * bits of the range register to determine if we go out of range. 3423 * This makes getting memory a real kludge. 3424 * 3425 */ 3426 3427#define RANGE_BOUNDARY (1<<22) 3428static vm_offset_t 3429get_bktr_mem( int unit, unsigned size ) 3430{ 3431 vm_offset_t addr = 0; 3432 3433 addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24); 3434 if (addr == 0) 3435 addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 3436 PAGE_SIZE); 3437 if (addr == 0) { 3438 printf("bktr%d: Unable to allocate %d bytes of memory.\n", 3439 unit, size); 3440 } 3441 3442 return( addr ); 3443} 3444 3445 3446 3447/* 3448 * Given a pixfmt index, compute the bt848 swap_flags necessary to 3449 * achieve the specified swapping. 3450 * Note that without bt swapping, 2Bpp and 3Bpp modes are written 3451 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6 3452 * and read R->L). 3453 * Note also that for 3Bpp, we may additionally need to do some creative 3454 * SKIPing to align the FIFO bytelines with the target buffer (see split()). 3455 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR 3456 * as one would expect. 3457 */ 3458 3459static u_int pixfmt_swap_flags( int pixfmt ) 3460{ 3461 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public; 3462 u_int swapf = 0; 3463 3464 switch ( pf->Bpp ) { 3465 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP ); 3466 break; 3467 3468 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */ 3469 break; 3470 3471 case 4 : if ( pf->swap_bytes ) 3472 swapf = pf->swap_shorts ? 0 : WSWAP; 3473 else 3474 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP); 3475 break; 3476 } 3477 return swapf; 3478} 3479 3480 3481 3482/* 3483 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into 3484 * our pixfmt_table indices. 3485 */ 3486 3487static int oformat_meteor_to_bt( u_long format ) 3488{ 3489 int i; 3490 struct meteor_pixfmt *pf1, *pf2; 3491 3492 /* Find format in compatibility table */ 3493 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ ) 3494 if ( meteor_pixfmt_table[i].meteor_format == format ) 3495 break; 3496 3497 if ( i >= METEOR_PIXFMT_TABLE_SIZE ) 3498 return -1; 3499 pf1 = &meteor_pixfmt_table[i].public; 3500 3501 /* Match it with an entry in master pixel format table */ 3502 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) { 3503 pf2 = &pixfmt_table[i].public; 3504 3505 if (( pf1->type == pf2->type ) && 3506 ( pf1->Bpp == pf2->Bpp ) && 3507 !memcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) && 3508 ( pf1->swap_bytes == pf2->swap_bytes ) && 3509 ( pf1->swap_shorts == pf2->swap_shorts )) 3510 break; 3511 } 3512 if ( i >= PIXFMT_TABLE_SIZE ) 3513 return -1; 3514 3515 return i; 3516} 3517 3518/****************************************************************************** 3519 * i2c primitives: 3520 */ 3521 3522/* */ 3523#define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */ 3524#define I2C_READ 0x01 3525#define I2C_COMMAND (I2CBITTIME | \ 3526 BT848_DATA_CTL_I2CSCL | \ 3527 BT848_DATA_CTL_I2CSDA) 3528 3529/* 3530 * 3531 */ 3532static int 3533i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 ) 3534{ 3535 u_long x; 3536 u_long data; 3537 bt848_ptr_t bt848; 3538 3539 bt848 = bktr->base; 3540 3541 /* clear status bits */ 3542 bt848->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE); 3543 3544 /* build the command datum */ 3545 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND; 3546 if ( byte2 != -1 ) { 3547 data |= ((byte2 & 0xff) << 8); 3548 data |= BT848_DATA_CTL_I2CW3B; 3549 } 3550 3551 /* write the address and data */ 3552 bt848->i2c_data_ctl = data; 3553 3554 /* wait for completion */ 3555 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 3556 if ( bt848->int_stat & BT848_INT_I2CDONE ) 3557 break; 3558 } 3559 3560 /* check for ACK */ 3561 if ( !x || !(bt848->int_stat & BT848_INT_RACK) ) 3562 return( -1 ); 3563 3564 /* return OK */ 3565 return( 0 ); 3566} 3567 3568 3569/* 3570 * 3571 */ 3572static int 3573i2cRead( bktr_ptr_t bktr, int addr ) 3574{ 3575 u_long x; 3576 bt848_ptr_t bt848; 3577 3578 bt848 = bktr->base; 3579 3580 /* clear status bits */ 3581 bt848->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE); 3582 3583 /* write the READ address */ 3584 bt848->i2c_data_ctl = ((addr & 0xff) << 24) | I2C_COMMAND; 3585 3586 /* wait for completion */ 3587 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 3588 if ( bt848->int_stat & BT848_INT_I2CDONE ) 3589 break; 3590 } 3591 3592 /* check for ACK */ 3593 if ( !x || !(bt848->int_stat & BT848_INT_RACK) ) 3594 return( -1 ); 3595 3596 /* it was a read */ 3597 return( (bt848->i2c_data_ctl >> 8) & 0xff ); 3598} 3599 3600 3601#if defined( I2C_SOFTWARE_PROBE ) 3602 3603/* 3604 * we are keeping this around for any parts that we need to probe 3605 * but that CANNOT be probed via an i2c read. 3606 * this is necessary because the hardware i2c mechanism 3607 * cannot be programmed for 1 byte writes. 3608 * currently there are no known i2c parts that we need to probe 3609 * and that cannot be safely read. 3610 */ 3611static int i2cProbe( bktr_ptr_t bktr, int addr ); 3612#define BITD 40 3613#define EXTRA_START 3614 3615/* 3616 * probe for an I2C device at addr. 3617 */ 3618static int 3619i2cProbe( bktr_ptr_t bktr, int addr ) 3620{ 3621 int x, status; 3622 bt848_ptr_t bt848; 3623 3624 bt848 = bktr->base; 3625 3626 /* the START */ 3627#if defined( EXTRA_START ) 3628 bt848->i2c_data_ctl = 1; DELAY( BITD ); /* release data */ 3629 bt848->i2c_data_ctl = 3; DELAY( BITD ); /* release clock */ 3630#endif /* EXTRA_START */ 3631 bt848->i2c_data_ctl = 2; DELAY( BITD ); /* lower data */ 3632 bt848->i2c_data_ctl = 0; DELAY( BITD ); /* lower clock */ 3633 3634 /* write addr */ 3635 for ( x = 7; x >= 0; --x ) { 3636 if ( addr & (1<<x) ) { 3637 bt848->i2c_data_ctl = 1; 3638 DELAY( BITD ); /* assert HI data */ 3639 bt848->i2c_data_ctl = 3; 3640 DELAY( BITD ); /* strobe clock */ 3641 bt848->i2c_data_ctl = 1; 3642 DELAY( BITD ); /* release clock */ 3643 } 3644 else { 3645 bt848->i2c_data_ctl = 0; 3646 DELAY( BITD ); /* assert LO data */ 3647 bt848->i2c_data_ctl = 2; 3648 DELAY( BITD ); /* strobe clock */ 3649 bt848->i2c_data_ctl = 0; 3650 DELAY( BITD ); /* release clock */ 3651 } 3652 } 3653 3654 /* look for an ACK */ 3655 bt848->i2c_data_ctl = 1; DELAY( BITD ); /* float data */ 3656 bt848->i2c_data_ctl = 3; DELAY( BITD ); /* strobe clock */ 3657 status = bt848->i2c_data_ctl & 1; /* read the ACK bit */ 3658 bt848->i2c_data_ctl = 1; DELAY( BITD ); /* release clock */ 3659 3660 /* the STOP */ 3661 bt848->i2c_data_ctl = 0; DELAY( BITD ); /* lower clock & data */ 3662 bt848->i2c_data_ctl = 2; DELAY( BITD ); /* release clock */ 3663 bt848->i2c_data_ctl = 3; DELAY( BITD ); /* release data */ 3664 3665 return( status ); 3666} 3667#undef EXTRA_START 3668#undef BITD 3669 3670#endif /* I2C_SOFTWARE_PROBE */ 3671 3672 3673/* 3674 * 3675 */ 3676static int 3677writeEEProm( bktr_ptr_t bktr, int offset, int count, u_char *data ) 3678{ 3679 return( -1 ); 3680} 3681 3682 3683/* 3684 * 3685 */ 3686static int 3687readEEProm( bktr_ptr_t bktr, int offset, int count, u_char *data ) 3688{ 3689 int x; 3690 int addr; 3691 int max; 3692 int byte; 3693 3694 /* get the address of the EEProm */ 3695 addr = (int)(bktr->card.eepromAddr & 0xff); 3696 if ( addr == 0 ) 3697 return( -1 ); 3698 3699 max = (int)(bktr->card.eepromSize * EEPROMBLOCKSIZE); 3700 if ( (offset + count) > max ) 3701 return( -1 ); 3702 3703 /* set the start address */ 3704 if ( i2cWrite( bktr, addr, offset, -1 ) == -1 ) 3705 return( -1 ); 3706 3707 /* the read cycle */ 3708 for ( x = 0; x < count; ++x ) { 3709 if ( (byte = i2cRead( bktr, (addr | 1) )) == -1 ) 3710 return( -1 ); 3711 data[ x ] = byte; 3712 } 3713 3714 return( 0 ); 3715} 3716 3717 3718/****************************************************************************** 3719 * card probe 3720 */ 3721 3722 3723/* 3724 * the recognized cards, used as indexes of several tables. 3725 * 3726 * if probeCard() fails to detect the proper card on boot you can 3727 * override it by setting the following define to the card you are using: 3728 * 3729#define OVERRIDE_CARD <card type> 3730 * 3731 * where <card type> is one of the following card defines. 3732 */ 3733#define CARD_UNKNOWN 0 3734#define CARD_MIRO 1 3735#define CARD_HAUPPAUGE 2 3736#define CARD_STB 3 3737#define CARD_INTEL 4 3738 3739/* 3740 * the data for each type of card 3741 * 3742 * Note: 3743 * these entried MUST be kept in the order defined by the CARD_XXX defines! 3744 */ 3745const struct CARDTYPE cards[] = { 3746 3747 /* CARD_UNKNOWN */ 3748 { "Unknown", /* the 'name' */ 3749 NULL, /* the tuner */ 3750 0, /* dbx unknown */ 3751 0, 3752 0, /* EEProm unknown */ 3753 0, /* EEProm unknown */ 3754 { 0, 0, 0, 0, 0 } }, 3755 3756 /* CARD_MIRO */ 3757 { "Miro TV", /* the 'name' */ 3758 NULL, /* the tuner */ 3759 0, /* dbx unknown */ 3760 0, 3761 0, /* EEProm unknown */ 3762 0, /* size unknown */ 3763 { 0x02, 0x01, 0x00, 0x0a, 1 } }, /* XXX ??? */ 3764 3765 /* CARD_HAUPPAUGE */ 3766 { "Hauppauge WinCast/TV", /* the 'name' */ 3767 NULL, /* the tuner */ 3768 0, /* dbx is optional */ 3769 0, 3770 PFC8582_WADDR, /* EEProm type */ 3771 (u_char)(256 / EEPROMBLOCKSIZE), /* 256 bytes */ 3772 { 0x00, 0x02, 0x01, 0x01, 1 } }, /* audio MUX values */ 3773 3774 /* CARD_STB */ 3775 { "STB TV/PCI", /* the 'name' */ 3776 NULL, /* the tuner */ 3777 0, /* dbx is optional */ 3778 0, 3779 X24C01_WADDR, /* EEProm type */ 3780 (u_char)(128 / EEPROMBLOCKSIZE), /* 128 bytes */ 3781 { 0x00, 0x01, 0x02, 0x02, 1 } }, /* audio MUX values */ 3782 3783 /* CARD_INTEL */ 3784 { "Intel Smart Video III", /* the 'name' */ 3785 NULL, /* the tuner */ 3786 0, 3787 0, 3788 0, 3789 0, 3790 { 0, 0, 0, 0, 0 } } 3791}; 3792 3793 3794/* 3795 * the data for each type of tuner 3796 * 3797 * if probeCard() fails to detect the proper tuner on boot you can 3798 * override it by setting the following define to the tuner present: 3799 * 3800#define OVERRIDE_TUNER <tuner type> 3801 * 3802 * where <tuner type> is one of the following tuner defines. 3803 */ 3804 3805/* indexes into tuners[] */ 3806#define NO_TUNER 0 3807#define TEMIC_NTSC 1 3808#define TEMIC_PAL 2 3809#define TEMIC_SECAM 3 3810#define PHILIPS_NTSC 4 3811#define PHILIPS_PAL 5 3812#define PHILIPS_SECAM 6 3813#define TEMIC_PALI 7 3814#define PHILIPS_PALI 8 3815#define PHILIPS_FR1236_NTSC 9 3816 3817/* XXX FIXME: this list is incomplete */ 3818 3819/* input types */ 3820#define TTYPE_XXX 0 3821#define TTYPE_NTSC 1 3822#define TTYPE_NTSC_J 2 3823#define TTYPE_PAL 3 3824#define TTYPE_PAL_M 4 3825#define TTYPE_PAL_N 5 3826#define TTYPE_SECAM 6 3827 3828/** 3829struct TUNER { 3830 char* name; 3831 u_char type; 3832 u_char pllAddr; 3833 u_char pllControl; 3834 u_char bandLimits[ 2 ]; 3835 u_char bandAddrs[ 3 ]; 3836}; 3837 */ 3838const struct TUNER tuners[] = { 3839/* XXX FIXME: fill in the band-switch crosspoints */ 3840 /* NO_TUNER */ 3841 { "<none>", /* the 'name' */ 3842 TTYPE_XXX, /* input type */
|
3754 0x00, /* PLL write address */
3755 0x00, /* control byte for PLL */
|
3843 0x00, /* PLL write address */ 3844 { 0x00, /* control byte for PLL */ 3845 0x00, 3846 0x00, 3847 0x00 }, |
3848 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3757 { 0x00, 0x00, 0x00 } }, /* the band-switch values */
|
3849 { 0x00, 0x00, 0x00,0x00} }, /* the band-switch values */ |
3850 3851 /* TEMIC_NTSC */ 3852 { "Temic NTSC", /* the 'name' */ 3853 TTYPE_NTSC, /* input type */ 3854 TEMIC_NTSC_WADDR, /* PLL write address */
|
3763 TSA552x_SCONTROL, /* control byte for PLL */
|
3855 { TSA552x_SCONTROL, /* control byte for PLL */ 3856 TSA552x_SCONTROL, 3857 TSA552x_SCONTROL, 3858 0x00 }, |
3859 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3765 { 0x02, 0x04, 0x01 } }, /* the band-switch values */
|
3860 { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */ |
3861 3862 /* TEMIC_PAL */ 3863 { "Temic PAL", /* the 'name' */ 3864 TTYPE_PAL, /* input type */ 3865 TEMIC_PALI_WADDR, /* PLL write address */
|
3771 TSA552x_SCONTROL, /* control byte for PLL */
|
3866 { TSA552x_SCONTROL, /* control byte for PLL */ 3867 TSA552x_SCONTROL, 3868 TSA552x_SCONTROL, 3869 0x00 }, |
3870 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3773 { 0x02, 0x04, 0x01 } }, /* the band-switch values */
|
3871 { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */ |
3872 3873 /* TEMIC_SECAM */ 3874 { "Temic SECAM", /* the 'name' */ 3875 TTYPE_SECAM, /* input type */ 3876 0x00, /* PLL write address */
|
3779 TSA552x_SCONTROL, /* control byte for PLL */
|
3877 { TSA552x_SCONTROL, /* control byte for PLL */ 3878 TSA552x_SCONTROL, 3879 TSA552x_SCONTROL, 3880 0x00 }, |
3881 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3781 { 0x02, 0x04, 0x01 } }, /* the band-switch values */
|
3882 { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */ |
3883 3884 /* PHILIPS_NTSC */ 3885 { "Philips NTSC", /* the 'name' */ 3886 TTYPE_NTSC, /* input type */ 3887 PHILIPS_NTSC_WADDR, /* PLL write address */
|
3787 TSA552x_SCONTROL, /* control byte for PLL */
|
3888 { TSA552x_SCONTROL, /* control byte for PLL */ 3889 TSA552x_SCONTROL, 3890 TSA552x_SCONTROL, 3891 0x00 }, |
3892 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3789 { 0xa0, 0x90, 0x30 } }, /* the band-switch values */
|
3893 { 0xa0, 0x90, 0x30, 0x00 } }, /* the band-switch values */ |
3894 3895 /* PHILIPS_PAL */ 3896 { "Philips PAL", /* the 'name' */ 3897 TTYPE_PAL, /* input type */
|
3794 0x00, /* PLL write address */
3795 TSA552x_SCONTROL, /* control byte for PLL */
|
3898 PHILIPS_PAL_WADDR, /* PLL write address */ 3899 { TSA552x_FCONTROL, /* control byte for PLL */ 3900 TSA552x_FCONTROL, 3901 TSA552x_FCONTROL, 3902 TSA552x_RADIO }, |
3903 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3797 { 0xa0, 0x90, 0x30 } }, /* the band-switch values */
|
3904 { 0xa0, 0x90, 0x30, 0xa5 } }, /* the band-switch values */ 3905 /* Radio: (for FM1216) 3906 ** 0xa4 sets radiomode 3907 ** bit0 - AFC 3908 ** bit1 - Mono 3909 ** bit3 - Mute */ |
3910 3911 /* PHILIPS_SECAM */ 3912 { "Philips SECAM", /* the 'name' */ 3913 TTYPE_SECAM, /* input type */ 3914 0x00, /* PLL write address */
|
3803 TSA552x_SCONTROL, /* control byte for PLL */
|
3915 { TSA552x_SCONTROL, /* control byte for PLL */ 3916 TSA552x_SCONTROL, 3917 TSA552x_SCONTROL, 3918 0x00 }, |
3919 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3805 { 0xa0, 0x90, 0x30 } }, /* the band-switch values */
|
3920 { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */ |
3921 3922 /* TEMIC_PAL I */ 3923 { "Temic PAL I", /* the 'name' */ 3924 TTYPE_PAL, /* input type */ 3925 TEMIC_PALI_WADDR, /* PLL write address */
|
3811 TSA552x_SCONTROL, /* control byte for PLL */
|
3926 { TSA552x_SCONTROL, /* control byte for PLL */ 3927 TSA552x_SCONTROL, 3928 TSA552x_SCONTROL, 3929 0x00 }, |
3930 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3813 { 0x02, 0x04, 0x01 } }, /* the band-switch values */
|
3931 { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */ |
3932 3933 /* PHILIPS_PAL */ 3934 { "Philips PAL I", /* the 'name' */ 3935 TTYPE_PAL, /* input type */
|
3818 0x00, /* PLL write address */
3819 TSA552x_SCONTROL, /* control byte for PLL */
|
3936 TEMIC_PALI_WADDR, /* PLL write address */ 3937 { TSA552x_SCONTROL, /* control byte for PLL */ 3938 TSA552x_SCONTROL, 3939 TSA552x_SCONTROL, 3940 0x00 }, |
3941 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3821 { 0xa0, 0x90, 0x30 } }, /* the band-switch values */
|
3942 { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */ |
3943 3944 /* PHILIPS_FR1236_NTSC */ 3945 { "Philips FR1236 NTSC FM", /* the 'name' */ 3946 TTYPE_NTSC, /* input type */ 3947 PHILIPS_FR1236_NTSC_WADDR, /* PLL write address */
|
3827 TSA552x_SCONTROL, /* control byte for PLL */
|
3948 { TSA552x_SCONTROL, /* control byte for PLL */ 3949 TSA552x_SCONTROL, 3950 TSA552x_SCONTROL, 3951 0x00}, |
3952 { 0x00, 0x00 }, /* band-switch crosspoints */
|
3829 { 0xa0, 0x90, 0x30 } }, /* the band-switch values */
|
3953 { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */ |
3954}; 3955 3956 3957/* 3958 * get a signature of the card 3959 * read all 128 possible i2c read addresses from 0x01 thru 0xff 3960 * build a bit array with a 1 bit for each i2c device that responds 3961 * 3962 * XXX FIXME: use offset & count args 3963 */ 3964#define ABSENT (-1) 3965static int 3966signCard( bktr_ptr_t bktr, int offset, int count, u_char* sig ) 3967{ 3968 int x; 3969 3970 for ( x = 0; x < 16; ++x ) 3971 sig[ x ] = 0; 3972 3973 for ( x = 0; x < 128; ++x ) { 3974 if ( i2cRead( bktr, (2 * x) + 1 ) != ABSENT ) { 3975 sig[ x / 8 ] |= (1 << (x % 8) ); 3976 } 3977 } 3978 3979 return( 0 ); 3980} 3981#undef ABSENT 3982 3983 3984/* 3985 * determine the card brand/model 3986 */ 3987#define ABSENT (-1) 3988static void 3989probeCard( bktr_ptr_t bktr, int verbose ) 3990{ 3991 int card; 3992 int status; 3993 bt848_ptr_t bt848; 3994 3995 bt848 = bktr->base; 3996 3997#if defined( OVERRIDE_CARD ) 3998 bktr->card = cards[ (card = OVERRIDE_CARD) ]; 3999 goto checkTuner; 4000#endif 4001 4002 bt848->gpio_out_en = 0; 4003 if (bootverbose) 4004 printf("bktr: GPIO is 0x%08x\n", bt848->gpio_data); 4005 4006 /* look for a tuner */ 4007 if ( i2cRead( bktr, TSA552x_RADDR ) == ABSENT ) { 4008 bktr->card = cards[ (card = CARD_INTEL) ]; 4009 bktr->card.tuner = &tuners[ NO_TUNER ]; 4010 goto checkDBX; 4011 } 4012 4013 /* look for a hauppauge card */ 4014 if ( (status = i2cRead( bktr, PFC8582_RADDR )) != ABSENT ) { 4015 bktr->card = cards[ (card = CARD_HAUPPAUGE) ]; 4016 goto checkTuner; 4017 } 4018 4019 /* look for an STB card */ 4020 if ( (status = i2cRead( bktr, X24C01_RADDR )) != ABSENT ) { 4021 bktr->card = cards[ (card = CARD_STB) ]; 4022 goto checkTuner; 4023 } 4024 4025 /* XXX FIXME: (how do I) look for a Miro card */ 4026 bktr->card = cards[ (card = CARD_MIRO) ]; 4027 4028checkTuner: 4029#if defined( OVERRIDE_TUNER ) 4030 bktr->card.tuner = &tuners[ OVERRIDE_TUNER ]; 4031 goto checkDBX; 4032#endif 4033 4034 /* differentiate type of tuner */ 4035 switch (card) { 4036 case CARD_MIRO: 4037 switch (((bt848->gpio_data >> 10)-1)&7) { 4038 case 0: bktr->card.tuner = &tuners[ TEMIC_PAL ]; break; 4039 case 1: bktr->card.tuner = &tuners[ PHILIPS_PAL ]; break; 4040 case 2: bktr->card.tuner = &tuners[ PHILIPS_NTSC ]; break; 4041 case 3: bktr->card.tuner = &tuners[ PHILIPS_SECAM ]; break; 4042 case 4: bktr->card.tuner = &tuners[ NO_TUNER ]; break; 4043 case 5: bktr->card.tuner = &tuners[ PHILIPS_PALI ]; break; 4044 case 6: bktr->card.tuner = &tuners[ TEMIC_NTSC ]; break; 4045 case 7: bktr->card.tuner = &tuners[ TEMIC_PALI ]; break; 4046 } 4047 break; 4048 default: 4049 if ( i2cRead( bktr, TEMIC_NTSC_RADDR ) != ABSENT ) { 4050 bktr->card.tuner = &tuners[ TEMIC_NTSC ]; 4051 goto checkDBX; 4052 } 4053 4054 if ( i2cRead( bktr, PHILIPS_NTSC_RADDR ) != ABSENT ) { 4055 bktr->card.tuner = &tuners[ PHILIPS_NTSC ]; 4056 goto checkDBX; 4057 } 4058 4059 if ( card == CARD_HAUPPAUGE ) { 4060 if ( i2cRead( bktr, TEMIC_PALI_RADDR ) != ABSENT ) { 4061 bktr->card.tuner = &tuners[ TEMIC_PAL ]; 4062 goto checkDBX; 4063 } 4064 } 4065 /* no tuner found */ 4066 bktr->card.tuner = &tuners[ NO_TUNER ]; 4067 } 4068 4069checkDBX: 4070#if defined( OVERRIDE_DBX ) 4071 bktr->card.dbx = OVERRIDE_DBX; 4072 goto end; 4073#endif 4074 /* probe for BTSC (dbx) chips */ 4075 if ( i2cRead( bktr, TDA9850_RADDR ) != ABSENT ) 4076 bktr->card.dbx = 1; 4077 if ( i2cRead( bktr, MSP3400C_RADDR ) != ABSENT ) 4078 bktr->card.msp3400c = 1; 4079 4080 if ( verbose ) { 4081 printf( "%s", bktr->card.name ); 4082 if ( bktr->card.tuner ) 4083 printf( ", %s tuner", bktr->card.tuner->name ); 4084 if ( bktr->card.dbx ) 4085 printf( ", dbx stereo" ); 4086 if ( bktr->card.msp3400c ) 4087 printf( ", msp3400c stereo" ); 4088 printf( ".\n" ); 4089 } 4090} 4091#undef ABSENT 4092 4093 4094/****************************************************************************** 4095 * tuner specific routines: 4096 */ 4097 4098 4099/* scaling factor for frequencies expressed as ints */ 4100#define FREQFACTOR 16 4101 4102/* 4103 * Format: 4104 * entry 0: MAX legal channel 4105 * entry 1: IF frequency 4106 * expressed as fi{mHz} * 16, 4107 * eg 45.75mHz == 45.75 * 16 = 732 4108 * entry 2: [place holder/future] 4109 * entry 3: base of channel record 0 4110 * entry 3 + (x*3): base of channel record 'x' 4111 * entry LAST: NULL channel entry marking end of records 4112 * 4113 * Record: 4114 * int 0: base channel 4115 * int 1: frequency of base channel, 4116 * expressed as fb{mHz} * 16, 4117 * int 2: offset frequency between channels, 4118 * expressed as fo{mHz} * 16, 4119 */ 4120 4121/* 4122 * North American Broadcast Channels: 4123 * 4124 * 2: 55.25 mHz - 4: 67.25 mHz 4125 * 5: 77.25 mHz - 6: 83.25 mHz 4126 * 7: 175.25 mHz - 13: 211.25 mHz 4127 * 14: 471.25 mHz - 83: 885.25 mHz 4128 * 4129 * IF freq: 45.75 mHz 4130 */ 4131#define OFFSET 6.00 4132int nabcst[] = { 4133 83, (int)( 45.75 * FREQFACTOR), 0, 4134 14, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4135 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4136 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4137 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4138 0 4139}; 4140#undef OFFSET 4141 4142/* 4143 * North American Cable Channels, IRC: 4144 * 4145 * 2: 55.25 mHz - 4: 67.25 mHz 4146 * 5: 77.25 mHz - 6: 83.25 mHz 4147 * 7: 175.25 mHz - 13: 211.25 mHz 4148 * 14: 121.25 mHz - 22: 169.25 mHz 4149 * 23: 217.25 mHz - 94: 643.25 mHz 4150 * 95: 91.25 mHz - 99: 115.25 mHz 4151 * 4152 * IF freq: 45.75 mHz 4153 */ 4154#define OFFSET 6.00 4155int irccable[] = { 4156 99, (int)( 45.75 * FREQFACTOR), 0, 4157 95, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4158 23, (int)(217.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4159 14, (int)(121.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4160 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4161 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4162 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4163 0 4164}; 4165#undef OFFSET 4166 4167/* 4168 * North American Cable Channels, HRC: 4169 * 4170 * 2: 54 mHz - 4: 66 mHz 4171 * 5: 78 mHz - 6: 84 mHz 4172 * 7: 174 mHz - 13: 210 mHz 4173 * 14: 120 mHz - 22: 168 mHz 4174 * 23: 216 mHz - 94: 642 mHz 4175 * 95: 90 mHz - 99: 114 mHz 4176 * 4177 * IF freq: 45.75 mHz 4178 */ 4179#define OFFSET 6.00 4180int hrccable[] = { 4181 99, (int)( 45.75 * FREQFACTOR), 0, 4182 95, (int)( 90.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4183 23, (int)(216.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4184 14, (int)(120.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4185 7, (int)(174.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4186 5, (int)( 78.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4187 2, (int)( 54.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4188 0 4189}; 4190#undef OFFSET 4191 4192/* 4193 * Western European broadcast channels: 4194 * 4195 * (there are others that appear to vary between countries - rmt) 4196 * 4197 * here's the table Philips provides: 4198 * caution, some of the offsets don't compute... 4199 * 4200 * 1 4525 700 N21 4201 * 4202 * 2 4825 700 E2 4203 * 3 5525 700 E3 4204 * 4 6225 700 E4 4205 * 4206 * 5 17525 700 E5 4207 * 6 18225 700 E6 4208 * 7 18925 700 E7 4209 * 8 19625 700 E8 4210 * 9 20325 700 E9 4211 * 10 21025 700 E10 4212 * 11 21725 700 E11 4213 * 12 22425 700 E12 4214 * 4215 * 13 5375 700 ITA 4216 * 14 6225 700 ITB 4217 * 4218 * 15 8225 700 ITC 4219 * 4220 * 16 17525 700 ITD 4221 * 17 18325 700 ITE 4222 * 4223 * 18 19225 700 ITF 4224 * 19 20125 700 ITG 4225 * 20 21025 700 ITH 4226 * 4227 * 21 47125 800 E21 4228 * 22 47925 800 E22 4229 * 23 48725 800 E23 4230 * 24 49525 800 E24 4231 * 25 50325 800 E25 4232 * 26 51125 800 E26 4233 * 27 51925 800 E27 4234 * 28 52725 800 E28 4235 * 29 53525 800 E29 4236 * 30 54325 800 E30 4237 * 31 55125 800 E31 4238 * 32 55925 800 E32 4239 * 33 56725 800 E33 4240 * 34 57525 800 E34 4241 * 35 58325 800 E35 4242 * 36 59125 800 E36 4243 * 37 59925 800 E37 4244 * 38 60725 800 E38 4245 * 39 61525 800 E39 4246 * 40 62325 800 E40 4247 * 41 63125 800 E41 4248 * 42 63925 800 E42 4249 * 43 64725 800 E43 4250 * 44 65525 800 E44 4251 * 45 66325 800 E45 4252 * 46 67125 800 E46 4253 * 47 67925 800 E47 4254 * 48 68725 800 E48 4255 * 49 69525 800 E49 4256 * 50 70325 800 E50 4257 * 51 71125 800 E51 4258 * 52 71925 800 E52 4259 * 53 72725 800 E53 4260 * 54 73525 800 E54 4261 * 55 74325 800 E55 4262 * 56 75125 800 E56 4263 * 57 75925 800 E57 4264 * 58 76725 800 E58 4265 * 59 77525 800 E59 4266 * 60 78325 800 E60 4267 * 61 79125 800 E61 4268 * 62 79925 800 E62 4269 * 63 80725 800 E63 4270 * 64 81525 800 E64 4271 * 65 82325 800 E65 4272 * 66 83125 800 E66 4273 * 67 83925 800 E67 4274 * 68 84725 800 E68 4275 * 69 85525 800 E69 4276 * 4277 * 70 4575 800 IA 4278 * 71 5375 800 IB 4279 * 72 6175 800 IC 4280 * 4281 * 74 6925 700 S01 4282 * 75 7625 700 S02 4283 * 76 8325 700 S03 4284 * 4285 * 80 10525 700 S1 4286 * 81 11225 700 S2 4287 * 82 11925 700 S3 4288 * 83 12625 700 S4 4289 * 84 13325 700 S5 4290 * 85 14025 700 S6 4291 * 86 14725 700 S7 4292 * 87 15425 700 S8 4293 * 88 16125 700 S9 4294 * 89 16825 700 S10 4295 * 90 23125 700 S11 4296 * 91 23825 700 S12 4297 * 92 24525 700 S13 4298 * 93 25225 700 S14 4299 * 94 25925 700 S15 4300 * 95 26625 700 S16 4301 * 96 27325 700 S17 4302 * 97 28025 700 S18 4303 * 98 28725 700 S19 4304 * 99 29425 700 S20 4305 * 4306 * 100 3890 000 IFFREQ 4307 * 4308 */ 4309int weurope[] = { 4310 100, (int)( 38.90 * FREQFACTOR), 0, 4311 90, (int)(231.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 4312 80, (int)(105.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 4313 74, (int)( 69.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 4314 21, (int)(471.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 4315 17, (int)(183.25 * FREQFACTOR), (int)(9.00 * FREQFACTOR), 4316 16, (int)(175.25 * FREQFACTOR), (int)(9.00 * FREQFACTOR), 4317 15, (int)(82.25 * FREQFACTOR), (int)(8.50 * FREQFACTOR), 4318 13, (int)(53.75 * FREQFACTOR), (int)(8.50 * FREQFACTOR), 4319 5, (int)(175.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 4320 2, (int)(48.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 4321 0 4322}; 4323 4324/* 4325 * Japanese Broadcast Channels: 4326 * 4327 * 1: 91.25MHz - 3: 103.25MHz 4328 * 4: 171.25MHz - 7: 189.25MHz 4329 * 8: 193.25MHz - 12: 217.25MHz (VHF) 4330 * 13: 471.25MHz - 62: 765.25MHz (UHF) 4331 * 4332 * IF freq: 45.75 mHz 4333 * OR 4334 * IF freq: 58.75 mHz 4335 */ 4336#define OFFSET 6.00 4337#define IF_FREQ 45.75 4338int jpnbcst[] = { 4339 62, (int)(IF_FREQ * FREQFACTOR), 0, 4340 13, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4341 8, (int)(193.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4342 4, (int)(171.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4343 1, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4344 0 4345}; 4346#undef IF_FREQ 4347#undef OFFSET 4348 4349/* 4350 * Japanese Cable Channels: 4351 * 4352 * 1: 91.25MHz - 3: 103.25MHz 4353 * 4: 171.25MHz - 7: 189.25MHz 4354 * 8: 193.25MHz - 12: 217.25MHz 4355 * 13: 109.25MHz - 21: 157.25MHz 4356 * 22: 165.25MHz 4357 * 23: 223.25MHz - 63: 463.25MHz 4358 * 4359 * IF freq: 45.75 mHz 4360 */ 4361#define OFFSET 6.00 4362#define IF_FREQ 45.75 4363int jpncable[] = { 4364 63, (int)(IF_FREQ * FREQFACTOR), 0, 4365 23, (int)(223.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4366 22, (int)(165.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4367 13, (int)(109.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4368 8, (int)(193.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4369 4, (int)(171.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4370 1, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 4371 0 4372}; 4373#undef IF_FREQ 4374#undef OFFSET 4375 4376int* freqTable[] = { 4377 NULL, 4378 nabcst, 4379 irccable, 4380 hrccable, 4381 weurope, 4382 jpnbcst, 4383 jpncable 4384 4385}; 4386 4387 4388#define TBL_CHNL freqTable[ bktr->tuner.chnlset ][ x ] 4389#define TBL_BASE_FREQ freqTable[ bktr->tuner.chnlset ][ x + 1 ] 4390#define TBL_OFFSET freqTable[ bktr->tuner.chnlset ][ x + 2 ] 4391static int 4392frequency_lookup( bktr_ptr_t bktr, int channel ) 4393{ 4394 int x; 4395 4396 /* check for "> MAX channel" */ 4397 x = 0; 4398 if ( channel > TBL_CHNL ) 4399 return( -1 ); 4400 4401 /* search the table for data */ 4402 for ( x = 3; TBL_CHNL; x += 3 ) { 4403 if ( channel >= TBL_CHNL ) { 4404 return( TBL_BASE_FREQ + 4405 ((channel - TBL_CHNL) * TBL_OFFSET) ); 4406 } 4407 } 4408 4409 /* not found, must be below the MIN channel */ 4410 return( -1 ); 4411} 4412#undef TBL_OFFSET 4413#undef TBL_BASE_FREQ 4414#undef TBL_CHNL 4415 4416 4417#define TBL_IF freqTable[ bktr->tuner.chnlset ][ 1 ] 4418/* 4419 * set the frequency of the tuner 4420 */ 4421static int 4422tv_freq( bktr_ptr_t bktr, int frequency ) 4423{ 4424 const struct TUNER* tuner; 4425 u_char addr; 4426 u_char control; 4427 u_char band; 4428 int N; 4429 4430 tuner = bktr->card.tuner; 4431 if ( tuner == NULL ) 4432 return( -1 ); 4433 4434 /* 4435 * select the band based on frequency 4436 * XXX FIXME: get the cross-over points from the tuner struct 4437 */ 4438 if ( frequency < (160 * FREQFACTOR) )
|
4315 band = tuner->bandAddrs[ 0 ];
|
4439 N = 0; |
4440 else if ( frequency < (454 * FREQFACTOR) )
|
4317 band = tuner->bandAddrs[ 1 ];
|
4441 N = 1; |
4442 else
|
4319 band = tuner->bandAddrs[ 2 ];
|
4443 N = 2; |
4444
|
4445 if(frequency > RADIO_OFFSET) { 4446 N=3; 4447 frequency -= RADIO_OFFSET; 4448 } 4449 |
4450 /* set the address of the PLL */
|
4322 addr = tuner->pllAddr;
4323 control = tuner->pllControl;
|
4451 addr = tuner->pllAddr; 4452 control = tuner->pllControl[ N ]; 4453 band = tuner->bandAddrs[ N ]; 4454 if(!(band && control)) /* Don't try to set un- */ 4455 return(-1); /* supported modes. */ |
4456
|
4457 |
4458 /* 4459 * N = 16 * { fRF(pc) + fIF(pc) } 4460 * where: 4461 * pc is picture carrier, fRF & fIF are in mHz 4462 * 4463 * frequency was passed in as mHz * 16 4464 */ 4465#if defined( TEST_TUNER_AFC ) 4466 if ( bktr->tuner.afc ) 4467 frequency -= 4; 4468#endif 4469 N = frequency + TBL_IF; 4470 4471 if ( frequency > bktr->tuner.frequency ) { 4472 i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff ); 4473 i2cWrite( bktr, addr, control, band ); 4474 } 4475 else { 4476 i2cWrite( bktr, addr, control, band ); 4477 i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff ); 4478 } 4479 4480#if defined( TUNER_AFC ) 4481 if ( bktr->tuner.afc == TRUE ) { 4482 if ( (N = do_afc( bktr, addr, N )) < 0 ) { 4483 /* AFC failed, restore requested frequency */ 4484 N = frequency + TBL_IF; 4485 i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff ); 4486 } 4487 else 4488 frequency = N - TBL_IF; 4489 } 4490#endif /* TUNER_AFC */ 4491 4492 /* update frequency */ 4493 bktr->tuner.frequency = frequency; 4494 4495 return( 0 ); 4496} 4497 4498#if defined( TUNER_AFC ) 4499/* 4500 * 4501 */ 4502static int 4503do_afc( bktr_ptr_t bktr, int addr, int frequency ) 4504{ 4505 int step; 4506 int status; 4507 int origFrequency; 4508 4509 origFrequency = frequency; 4510 4511 /* wait for first setting to take effect */ 4512 tsleep( (caddr_t)bktr, PZERO, "tuning", hz/8 ); 4513 4514 if ( (status = i2cRead( bktr, addr + 1 )) < 0 ) 4515 return( -1 ); 4516 4517#if defined( TEST_TUNER_AFC ) 4518 printf( "\nOriginal freq: %d, status: 0x%02x\n", frequency, status ); 4519#endif 4520 for ( step = 0; step < AFC_MAX_STEP; ++step ) { 4521 if ( (status = i2cRead( bktr, addr + 1 )) < 0 ) 4522 goto fubar; 4523 if ( !(status & 0x40) ) { 4524#if defined( TEST_TUNER_AFC ) 4525 printf( "no lock!\n" ); 4526#endif 4527 goto fubar; 4528 } 4529 4530 switch( status & AFC_BITS ) { 4531 case AFC_FREQ_CENTERED: 4532#if defined( TEST_TUNER_AFC ) 4533 printf( "Centered, freq: %d, status: 0x%02x\n", frequency, status ); 4534#endif 4535 return( frequency ); 4536 4537 case AFC_FREQ_MINUS_125: 4538 case AFC_FREQ_MINUS_62: 4539#if defined( TEST_TUNER_AFC ) 4540 printf( "Low, freq: %d, status: 0x%02x\n", frequency, status ); 4541#endif 4542 --frequency; 4543 break; 4544 4545 case AFC_FREQ_PLUS_62: 4546 case AFC_FREQ_PLUS_125: 4547#if defined( TEST_TUNER_AFC ) 4548 printf( "Hi, freq: %d, status: 0x%02x\n", frequency, status ); 4549#endif 4550 ++frequency; 4551 break; 4552 } 4553 4554 i2cWrite( bktr, addr, 4555 (frequency>>8) & 0x7f, frequency & 0xff ); 4556 DELAY( AFC_DELAY ); 4557 } 4558 4559 fubar: 4560 i2cWrite( bktr, addr, 4561 (origFrequency>>8) & 0x7f, origFrequency & 0xff ); 4562 4563 return( -1 ); 4564} 4565#endif /* TUNER_AFC */ 4566#undef TBL_IF 4567 4568 4569/* 4570 * set the channel of the tuner 4571 */ 4572static int 4573tv_channel( bktr_ptr_t bktr, int channel ) 4574{ 4575 int frequency; 4576 4577 /* calculate the frequency according to tuner type */ 4578 if ( (frequency = frequency_lookup( bktr, channel )) < 0 ) 4579 return( -1 ); 4580 4581 /* set the new frequency */ 4582 if ( tv_freq( bktr, frequency ) < 0 ) 4583 return( -1 ); 4584 4585 /* OK to update records */ 4586 return( (bktr->tuner.channel = channel) ); 4587} 4588 4589 4590/****************************************************************************** 4591 * audio specific routines: 4592 */ 4593 4594 4595/* 4596 * 4597 */ 4598#define AUDIOMUX_DISCOVER_NOT 4599static int 4600set_audio( bktr_ptr_t bktr, int cmd ) 4601{ 4602 bt848_ptr_t bt848; 4603 u_long temp; 4604 volatile u_char idx; 4605 4606#if defined( AUDIOMUX_DISCOVER ) 4607 if ( cmd >= 200 ) 4608 cmd -= 200; 4609 else 4610#endif /* AUDIOMUX_DISCOVER */ 4611 4612 /* check for existance of audio MUXes */ 4613 if ( !bktr->card.audiomuxs[ 4 ] ) 4614 return( -1 ); 4615 4616 switch (cmd) { 4617 case AUDIO_TUNER: 4618 bktr->audio_mux_select = 0; 4619 break; 4620 case AUDIO_EXTERN: 4621 bktr->audio_mux_select = 1; 4622 break; 4623 case AUDIO_INTERN: 4624 bktr->audio_mux_select = 2; 4625 break; 4626 case AUDIO_MUTE: 4627 bktr->audio_mute_state = TRUE; /* set mute */ 4628 break; 4629 case AUDIO_UNMUTE: 4630 bktr->audio_mute_state = FALSE; /* clear mute */ 4631 break; 4632 default: 4633 printf("bktr: audio cmd error %02x\n", cmd); 4634 return( -1 ); 4635 } 4636 4637 bt848 = bktr->base; 4638 4639 /* 4640 * Leave the upper bits of the GPIO port alone in case they control 4641 * something like the dbx or teletext chips. This doesn't guarantee 4642 * success, but follows the rule of least astonishment. 4643 */ 4644 4645 /* XXX FIXME: this was an 8 bit reference before new struct ??? */ 4646 bt848->gpio_reg_inp = (~GPIO_AUDIOMUX_BITS & 0xff); 4647 4648 if ( bktr->audio_mute_state == TRUE ) 4649 idx = 3; 4650 else 4651 idx = bktr->audio_mux_select; 4652 4653 temp = bt848->gpio_data & ~GPIO_AUDIOMUX_BITS; 4654 bt848->gpio_data = 4655#if defined( AUDIOMUX_DISCOVER ) 4656 bt848->gpio_data = temp | (cmd & 0xff); 4657 printf("cmd: %d\n", cmd ); 4658#else 4659 temp | bktr->card.audiomuxs[ idx ]; 4660#endif /* AUDIOMUX_DISCOVER */ 4661 4662 return( 0 ); 4663} 4664 4665 4666/* 4667 * 4668 */ 4669static void 4670temp_mute( bktr_ptr_t bktr, int flag ) 4671{ 4672 static int muteState = FALSE; 4673 4674 if ( flag == TRUE ) { 4675 muteState = bktr->audio_mute_state; 4676 set_audio( bktr, AUDIO_MUTE ); /* prevent 'click' */ 4677 } 4678 else { 4679 tsleep( (caddr_t)bktr, PZERO, "tuning", hz/8 ); 4680 if ( muteState == FALSE ) 4681 set_audio( bktr, AUDIO_UNMUTE ); 4682 } 4683} 4684 4685 4686/* 4687 * setup the dbx chip 4688 * XXX FIXME: alot of work to be done here, this merely unmutes it. 4689 */ 4690static int 4691set_BTSC( bktr_ptr_t bktr, int control ) 4692{ 4693 return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) ); 4694} 4695 4696 4697/****************************************************************************** 4698 * magic: 4699 */ 4700 4701 4702#ifdef __FreeBSD__ 4703static bktr_devsw_installed = 0; 4704 4705static void 4706bktr_drvinit( void *unused ) 4707{ 4708 dev_t dev; 4709 4710 if ( ! bktr_devsw_installed ) { 4711 dev = makedev(CDEV_MAJOR, 0); 4712 cdevsw_add(&dev,&bktr_cdevsw, NULL); 4713 bktr_devsw_installed = 1; 4714 } 4715} 4716 4717SYSINIT(bktrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bktr_drvinit,NULL) 4718 4719#endif /* __FreeBSD__ */ 4720#endif /* !defined(__FreeBSD__) || (NBKTR > 0 && NPCI > 0) */ 4721 4722/* Local Variables: */ 4723/* mode: C */ 4724/* c-indent-level: 8 */ 4725/* c-brace-offset: -8 */ 4726/* c-argdecl-indent: 8 */ 4727/* c-label-offset: -8 */ 4728/* c-continued-statement-offset: 8 */ 4729/* c-tab-always-indent: nil */ 4730/* tab-width: 8 */ 4731/* End: */
|