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