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