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