The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pci/brooktree848.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: d5cc6eb811f8625369d2c632ef0372c0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.