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/meteor.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 /*
    2  * Copyright (c) 1995 Mark Tinguely and Jim Lowe
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Mark Tinguely and Jim Lowe
   16  * 4. The name of the author may not be used to endorse or promote products 
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   22  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*              Change History:
   33         8/21/95         Release
   34         8/23/95         On advice from Stefan Esser, added volatile to PCI
   35                         memory pointers to remove PCI caching .
   36         8/29/95         Fixes suggested by Bruce Evans.
   37                         meteor_mmap should return -1 on error rather than 0.
   38                         unit # > NMETEOR should be unit # >= NMETEOR.
   39         10/24/95        Turn 50 Hz processing for SECAM and 60 Hz processing
   40                         off for AUTOMODE.
   41         11/11/95        Change UV from always begin signed to ioctl selected
   42                         to either signed or unsigned.
   43         12/07/95        Changed 7196 startup codes for 50 Hz as recommended
   44                         by Luigi Rizzo (luigi@iet.unipi.it)
   45         12/08/95        Clear SECAM bit in PAL/NTSC and set input field count
   46                         bits for 50 Hz mode (PAL/SECAM) before I was setting the
   47                         output count bits. by Luigi Rizzo (luigi@iet.unipi.it)
   48         12/18/95        Correct odd DMA field (never exceed, but good for safety
   49                         Changed 7196 startup codes for 50 Hz as recommended
   50                         by Luigi Rizzo (luigi@iet.unipi.it)
   51         12/19/95        Changed field toggle mode to enable (offset 0x3c)
   52                         recommended by luigi@iet.unipi.it
   53                         Added in prototyping, include file, staticizing,
   54                         and DEVFS changes from FreeBSD team.
   55                         Changed the default allocated pages from 151 (NTSC)
   56                         to 217 (PAL).
   57                         Cleaned up some old comments in iic_write().
   58                         Added a Field (even or odd) only capture mode to 
   59                         eliminate the high frequency problems with compression
   60                         algorithms.  Recommended by luigi@iet.unipi.it.
   61                         Changed geometry ioctl so if it couldn't allocated a
   62                         large enough contiguous space, it wouldn't free the
   63                         stuff it already had.
   64                         Added new mode called YUV_422 which delivers the
   65                         data in planer Y followed by U followed by V. This
   66                         differs from the standard YUV_PACKED mode in that
   67                         the chrominance (UV) data is in the correct (different)
   68                         order. This is for programs like vic and mpeg_encode
   69                         so they don't have to reorder the chrominance data.
   70                         Added field count to stats.
   71                         Increment frame count stat if capturing continuous on
   72                         even frame grabs.
   73                         Added my email address to these comments
   74                         (james@cs.uwm.edu) suggested by (luigi@iet.unipt.it :-).
   75                         Changed the user mode signal mechanism to allow the
   76                         user program to be interrupted at the end of a frame
   77                         in any one of the modes.  Added SSIGNAL ioctl.
   78                         Added a SFPS/GFPS ioctl so one may set the frames per
   79                         second that the card catpures.  This code needs to be
   80                         completed.
   81                         Changed the interrupt routine so synchronous capture
   82                         will work on fields or frames and the starting frame
   83                         can be either even or odd.
   84                         Added HALT_N_FRAMES and CONT_N_FRAMES so one could
   85                         stop and continue synchronous capture mode.
   86                         Change the tsleep/wakeup function to wait on mtr
   87                         rather than &read_intr_wait.
   88         1/22/96         Add option (METEOR_FreeBSD_210) for FreeBSD 2.1
   89                         to compile.
   90                         Changed intr so it only printed errors every 50 times.
   91                         Added unit number to error messages.
   92                         Added get_meteor_mem and enabled range checking.
   93         1/30/96         Added prelim test stuff for direct video dma transfers
   94                         from Amancio Hasty (hasty@rah.star-gate.com).  Until
   95                         we get some stuff sorted out, this will be ifdef'ed
   96                         with METEOR_DIRECT_VIDEO.  This is very dangerous to
   97                         use at present since we don't check the address that
   98                         is passed by the user!!!!!
   99         2/26/96         Added special SVIDEO input device type.
  100         2/27/96         Added meteor_reg.h file and associate types Converted
  101                         meteor.c over to using meteor.h file.  Prompted by
  102                         Lars Jonas Olsson <ljo@po.cwru.edu>.
  103         2/28/96         Added meteor RGB code from Lars Jonas Olsson
  104                         <ljo@po.cwru.edu>.  I make some mods to this code, so
  105                         I hope it still works as I don't have an rgb card to
  106                         test with.
  107         2/29/96         <ljo@po.cwru.edu> tested the meteor RGB and supplied
  108                         me with diffs.  Thanks, we now have a working RGB
  109                         version of the driver.  Still need to clean up this
  110                         code.
  111         3/1/96          Fixed a nasty little bug that was clearing the VTR
  112                         mode bit when the 7196 status was requested.
  113         3/15/96         Fixed bug introduced in previous version that
  114                         stopped the only fields mode from working.
  115                         Added METEOR{GS}TS ioctl, still needs work.
  116         3/25/96         Added YUV_9 and YUV_12 modes.  Cleaned up some of the
  117                         code and converted variables to use the new register
  118                         types.
  119         4/8/96          Fixed the a bug in with the range enable.  Pointed
  120                         out by Jim Bray.
  121         5/13/96         Fix the FPS ioctl so it actually sets the frames
  122                         per second.  Code supplied by ian@robots.ox.ac.uk.
  123                         The new code implements a new define:
  124                         METEOR_SYSTEM_DEFAULT  which should be defined as
  125                         METEOR_PAL, METEOR_SECAM, or METEOR_NTSC in your system
  126                         configuration file.  If METEOR_SYSTEM_DEFAULT isn't
  127                         defined, and there is not a signal when set_fps is
  128                         called, then the call has no effect.
  129                         Changed the spelling of PLANER to PLANAR as pointed
  130                         out by Paco Hope <paco@cs.virigina.edu> and define
  131                         PLANER to be PLANAR for backward compatibility.
  132         5/28/95         METEOR_INPUT_DEV_RCA -> METEOR_INPUT_DEV0, not
  133                         METEOR_GEO_DEV0.  Pointed out by Ian Reid,
  134                         <ian@robots.ox.ac.uk>.
  135                         METEOR_DEV_MASK should be 0x0000f000 and not 
  136                         0x2000f000, otherwise METEOR_RGB gets masked
  137                         out.  Pointed out by Ian Reid.
  138                         Changed the fps code to give even distribution for
  139                         low frame rates.  Code supplied by Ian Reid.
  140                         Fix some problems with the RGB version.  Patch supplied
  141                         by <ljo@po.cwru.edu>.
  142                         Added METEOR_FIELD_MODE to include files for a 
  143                         future version of this driver.
  144 */
  145 
  146 #include <sys/cdefs.h>
  147 __FBSDID("$FreeBSD: releng/5.2/sys/pci/meteor.c 119493 2003-08-26 16:57:24Z nectar $");
  148 
  149 #ifdef COMPILING_LINT
  150 #warning "The meteor driver is broken and is not compiled with LINT"
  151 #else
  152 
  153 #include "meteor.h"
  154 
  155 #include "opt_meteor.h"
  156 
  157 #include <sys/param.h>
  158 #include <sys/systm.h>
  159 #include <sys/conf.h>
  160 #include <sys/kernel.h>
  161 #include <sys/signalvar.h>
  162 #include <sys/mman.h>
  163 #include <sys/uio.h>
  164 
  165 #if defined(METEOR_FreeBSD_210)
  166 #include <machine/cpu.h>        /* bootverbose */
  167 #endif
  168 
  169 #include <vm/vm.h>
  170 #include <vm/vm_kern.h>
  171 #include <vm/pmap.h>
  172 #include <vm/vm_extern.h>
  173 
  174 #include <dev/pci/pcivar.h>
  175 #include <dev/pci/pcireg.h>
  176 #include <machine/ioctl_meteor.h>
  177 #include <pci/meteor_reg.h>
  178 
  179 #ifndef COMPAT_OLDPCI
  180 #error "The meteor device requires the old pci compatibility shims"
  181 #endif
  182 
  183 static void meteor_intr(void *arg);
  184 
  185 /* 
  186  * Allocate enough memory for:
  187  *      768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
  188  *
  189  * You may override this using the options "METEOR_ALLOC_PAGES=value" in your
  190  * kernel configuration file.
  191  */
  192 #ifndef METEOR_ALLOC_PAGES
  193 #define METEOR_ALLOC_PAGES 217
  194 #endif
  195 #define METEOR_ALLOC (METEOR_ALLOC_PAGES * PAGE_SIZE)
  196 
  197 static meteor_reg_t meteor[NMETEOR];
  198 #define METEOR_NUM(mtr) ((mtr - &meteor[0])/sizeof(meteor_reg_t))
  199 
  200 #define METPRI (PZERO+8)|PCATCH
  201 
  202 static  const char*     met_probe (pcici_t tag, pcidi_t type);
  203 static  void    met_attach(pcici_t tag, int unit);
  204 static  u_long  met_count;
  205 
  206 static struct   pci_device met_device = {
  207         "meteor",
  208         met_probe,
  209         met_attach,
  210         &met_count
  211 };
  212 
  213 COMPAT_PCI_DRIVER (meteor, met_device);
  214 
  215 #if defined(METEOR_FreeBSD_210) /* XXX */
  216 d_open_t        meteor_open;
  217 d_close_t       meteor_close;
  218 d_read_t        meteor_read;
  219 d_write_t       meteor_write;
  220 d_ioctl_t       meteor_ioctl;
  221 d_mmap_t        meteor_mmap;
  222 #else
  223 static  d_open_t        meteor_open;
  224 static  d_close_t       meteor_close;
  225 static  d_read_t        meteor_read;
  226 static  d_write_t       meteor_write;
  227 static  d_ioctl_t       meteor_ioctl;
  228 static  d_mmap_t        meteor_mmap;
  229 
  230 #define CDEV_MAJOR 67
  231 static struct cdevsw meteor_cdevsw = {
  232         .d_open =       meteor_open,
  233         .d_close =      meteor_close,
  234         .d_read =       meteor_read,
  235         .d_write =      meteor_write,
  236         .d_ioctl =      meteor_ioctl,
  237         .d_mmap =       meteor_mmap,
  238         .d_name =       "meteor",
  239         .d_maj =        CDEV_MAJOR,
  240 };
  241 #endif
  242 
  243 static mreg_t saa7116_pci_default[sizeof(struct saa7116_regs)/sizeof(mreg_t)]={
  244                                 /* PCI Memory registers         */
  245                                 /* BITS   Type  Description     */
  246 /* 0x00 */      0x00000000,     /* 31:1   e*RW  DMA 1 (Even)
  247                                       0   RO    0x0             */
  248 /* 0x04 */      0x00000000,     /* 31:2   e*RW  DMA 2 (Even)
  249                                     1:0   RO    0x0             */
  250 /* 0x08 */      0x00000000,     /* 31:2   e*RW  DMA 3 (Even)
  251                                     1:0   RO    0x0             */
  252 /* 0x0c */      0x00000000,     /* 31:1   o*RW  DMA 1 (Odd)
  253                                       0   RO    0x0             */
  254 /* 0x10 */      0x00000000,     /* 31:2   o*RW  DMA 2 (Odd)
  255                                     1:0   RO    0x0             */
  256 /* 0x14 */      0x00000000,     /* 31:2   o*RW  DMA 3 (Odd)
  257                                     1:0   RO    0x0             */
  258 /* 0x18 */      0x00000500,     /* 15:2   e*RW  Stride 1 (Even)
  259                                     1:0   RO    0x0             */
  260 /* 0x1c */      0x00000000,     /* 15:2   e*RW  Stride 2 (Even)
  261                                     1:0   RO    0x0             */
  262 /* 0x20 */      0x00000000,     /* 15:2   e*RW  Stride 3 (Even)
  263                                     1:0   RO    0x0             */
  264 /* 0x24 */      0x00000500,     /* 15:2   o*RW  Stride 1 (Odd)
  265                                     1:0   RO    0x0             */
  266 /* 0x28 */      0x00000000,     /* 15:2   o*RW  Stride 2 (Odd)
  267                                     1:0   RO    0x0             */
  268 /* 0x2c */      0x00000000,     /* 15:2   o*RW  Stride 3 (Odd)
  269                                     1:0   RO    0x0             */
  270 /* 0x30 */      0xeeeeee01,     /* 31:8   *RW   Route (Even)
  271                                     7:0   *RW   Mode (Even)     */
  272 /* 0x34 */      0xeeeeee01,     /* 31:8   *RW   Route (Odd)
  273                                     7:0   *RW   Mode (Odd)      */
  274 /* 0x38 */      0x00200020,     /* 22:16  *RW   FIFO Trigger Planer Mode,
  275                                     6:0   *RW   FIFO Trigger Packed Mode */
  276 /* 0x3c */      0x00000107,     /*  9:8   *RW   Reserved (0x0)
  277                                       2   *RW   Field Toggle
  278                                       1   *RW   Reserved (0x1)
  279                                       0   *RW   Reserved (0x1)          */
  280 /* 0x40 */      0x000000c0,     /*    15  *RW   Range Enable
  281                                       14  *RW   Corrupt Disable
  282                                       11  *RR   Address Error (Odd)
  283                                       10  *RR   Address Error (Even)
  284                                       9   *RR   Field Corrupt (Odd)
  285                                       8   *RR   Field Corrupt (Even)
  286                                       7   *RW   Fifo Enable
  287                                       6   *RW   VRSTN#
  288                                       5   *RR   Field Done (Odd)
  289                                       4   *RR   Field Done (Even)
  290                                       3   *RS   Single Field Capture (Odd)
  291                                       2   *RS   Single Field Capture (Even)
  292                                       1   *RW   Capture (ODD) Continous
  293                                       0   *RW   Capture (Even) Continous */
  294 /* 0x44 */      0x00000000,     /*  7:0   *RW   Retry Wait Counter */
  295 /* 0x48 */      0x00000307,     /*    10  *RW   Interrupt mask, start of field
  296                                       9   *RW   Interrupt mask, end odd field
  297                                       8   *RW   Interrupt mask, end even field
  298                                       2   *RR   Interrupt status, start of field
  299                                       1   *RR   Interrupt status, end of odd
  300                                       0   *RR   Interrupt status, end of even */
  301 /* 0x4c */      0x00000001,     /* 31:0   *RW   Field Mask (Even) continous */
  302 /* 0x50 */      0x00000001,     /* 31:0   *RW   Field Mask (Odd) continous */
  303 /* 0x54 */      0x00000000,     /* 20:16  *RW   Mask Length (Odd)
  304                                     4:0   *RW   Mask Length (Even)      */
  305 /* 0x58 */      0x0005007c,     /* 22:16  *RW   FIFO almost empty
  306                                     6:0   *RW   FIFO almost full        */
  307 /* 0x5c */      0x461e1e0f,     /* 31:24  *RW   I2C Phase 4
  308                                    23:16  *RW   I2C Phase 3
  309                                    15:8   *RW   I2C Phase 2
  310                                     7:0   *RW   I2C Phase 1     */
  311 /* 0x60 */      0x00000300,     /* 31:24  *RO   I2C Read Data
  312                                    23:16  **RW  I2C Auto Address
  313                                       11  RO    I2C SCL Input
  314                                       10  RO    I2C SDA Input
  315                                       9   RR    I2C Direct Abort
  316                                       8   RR    I2C Auto Abort
  317                                       3   RW    I2C SCL Output
  318                                       2   RW    I2C SDA Output
  319                                       1   RW    I2C Bypass
  320                                       0   RW    I2C Auto Enable */
  321 /* 0x64 */      0x00000000,     /*    24  RS    I2C New Cycle
  322                                    23:16  **RW  I2C Direct Address
  323                                    15:8   **RW  I2C Direct Sub-address
  324                                     7:0   **RW  I2C Direct Write Address */
  325 /* 0x68 */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 1 (Even)
  326                                    23:16  **RW  I2C Auto Data 1 (Even)
  327                                    15:8   **RW  I2C Auto Sub-address 0 (Even)
  328                                     7:0   **RW  I2C Auto Data 0 (Even) */
  329 /* 0x6c */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 3 (Even)
  330                                    23:16  **RW  I2C Auto Data 3 (Even)
  331                                    15:8   **RW  I2C Auto Sub-address 2 (Even)
  332                                     7:0   **RW  I2C Auto Data 2 (Even) */
  333 /* 0x70 */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 5 (Even)
  334                                    23:16  **RW  I2C Auto Data 5 (Even)
  335                                    15:8   **RW  I2C Auto Sub-address 4 (Even)
  336                                     7:0   **RW  I2C Auto Data 4 (Even) */
  337 /* 0x74 */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 7 (Even)
  338                                    23:16  **RW  I2C Auto Data 7 (Even)
  339                                    15:8   **RW  I2C Auto Sub-address 6 (Even)
  340                                     7:0   **RW  I2C Auto Data 6 (Even) */
  341 /* 0x78 */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 1 (Odd)
  342                                    23:16  **RW  I2C Auto Data 1 (Odd)
  343                                    15:8   **RW  I2C Auto Sub-address 0 (Odd)
  344                                     7:0   **RW  I2C Auto Data 0 (Odd) */
  345 /* 0x7c */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 3 (Odd)
  346                                    23:16  **RW  I2C Auto Data 3 (Odd)
  347                                    15:8   **RW  I2C Auto Sub-address 2 (Odd)
  348                                     7:0   **RW  I2C Auto Data 2 (Odd) */
  349 /* 0x80 */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 5 (Odd)
  350                                    23:16  **RW  I2C Auto Data 5 (Odd)
  351                                    15:8   **RW  I2C Auto Sub-address 4 (Odd)
  352                                     7:0   **RW  I2C Auto Data 4 (Odd) */
  353 /* 0x84 */      0x00000000,     /* 31:24  **RW  I2C Auto Sub-address 7 (Odd)
  354                                    23:16  **RW  I2C Auto Data 7 (Odd)
  355                                    15:8   **RW  I2C Auto Sub-address 6 (Odd)
  356                                     7:0   **RW  I2C Auto Data 6 (Odd) */
  357 /* 0x88 */      0x00000000,     /* 23:16  **RW  I2C Register Enable (Odd)
  358                                     7:0   **RW  I2C Register Enable (Even) */
  359 /* 0x8c */      0x00000000,     /* 23:2   e*RW  DMA End (Even)
  360                                     1:0   RO    0x0     */
  361 /* 0x90 */      0x00000000      /* 23:2   e*RW  DMA End (Odd)
  362                                     1:0   RO    0x0     */
  363 };
  364 
  365 static u_char saa7196_i2c_default[NUM_SAA7196_I2C_REGS] = {
  366                         /* SAA7196 I2C bus control                      */
  367                         /* BITS Function                                */
  368 /* 00 */        0x50,   /* 7:0  Increment Delay                         */
  369 /* 01 */        0x30,   /* 7:0  Horizontal Sync Begin for 50hz          */
  370 /* 02 */        0x00,   /* 7:0  Horizontal Sync Stop for 50hz           */
  371 /* 03 */        0xe8,   /* 7:0  Horizontal Sync Clamp Start for 50hz    */
  372 /* 04 */        0xb6,   /* 7:0  Horizontal Sync Clamp Stop for 50hz     */
  373 /* 05 */        0xf4,   /* 7:0  Horizontal Sync Start after PH1 for 50hz */
  374 /* 06 */        0x46,   /*   7  Input mode =0 CVBS, =1 S-Video 
  375                              6  Pre filter
  376                            5:4  Aperture Bandpass characteristics
  377                            3:2  Coring range for high freq
  378                            1:0  Aperture bandpass filter weights        */
  379 /* 07 */        0x00,   /* 7:0  Hue                                     */
  380 /* 08 */        0x7f,   /* 7:3  Colour-killer threshold QAM (PAL, NTSC) */
  381 /* 09 */        0x7f,   /* 7:3  Colour-killer threshold SECAM           */
  382 /* 0a */        0x7f,   /* 7:0  PAL switch sensitivity                  */
  383 /* 0b */        0x7f,   /* 7:0  SECAM switch sensitivity                */
  384 /* 0c */        0x40,   /*   7  Colour-on bit
  385                            6:5  AGC filter                              */
  386 /* 0d */        0x84,   /*   7  VTR/TV mode bit = 1->VTR mode
  387                              3  Realtime output mode select bit
  388                              2  HREF position select
  389                              1  Status byte select
  390                              0  SECAM mode bit                          */
  391 /* 0e */        0x38,   /*   7  Horizontal clock PLL
  392                              5  Select interal/external clock source
  393                              4  Output enable of Horizontal/Vertical sync
  394                              3  Data output YUV enable
  395                              2  S-VHS bit
  396                              1  GPSW2
  397                              0  GPSW1                                   */
  398 /* 0f */        0x50,   /*   7  Automatic Field detection
  399                              6  Field Select 0 = 50hz, 1=60hz
  400                              5  SECAM cross-colour reduction
  401                              4  Enable sync and clamping pulse
  402                            3:1  Luminance delay compensation            */
  403 /* 10 */        0x00,   /*   2  Select HREF Position
  404                            1:0  Vertical noise reduction                */
  405 /* 11 */        0x2c,   /* 7:0  Chrominance gain conrtol for QAM        */
  406 /* 12 */        0x40,   /* 7:0  Chrominance saturation control for VRAM port */
  407 /* 13 */        0x40,   /* 7:0  Luminance contract control for VRAM port */
  408 /* 14 */        0x34,   /* 7:0  Horizontal sync begin for 60hz          */
  409 #ifdef notdef
  410 /* 15 */        0x0c,   /* 7:0  Horizontal sync stop for 60hz           */
  411 /* 16 */        0xfb,   /* 7:0  Horizontal clamp begin for 60hz         */
  412 /* 17 */        0xd4,   /* 7:0  Horizontal clamp stop for 60hz          */
  413 /* 18 */        0xec,   /* 7:0  Horizontal sync start after PH1 for 60hz */
  414 #else
  415                 0x0a, 0xf4, 0xce, 0xf4,
  416 #endif
  417 /* 19 */        0x80,   /* 7:0  Luminance brightness control for VRAM port */
  418 /* 1a */        0x00,
  419 /* 1b */        0x00,
  420 /* 1c */        0x00,
  421 /* 1d */        0x00,
  422 /* 1e */        0x00,
  423 /* 1f */        0x00,
  424 /* 20 */        0x90,   /*   7  ROM table bypass switch
  425                            6:5  Set output field mode
  426                              4  VRAM port outputs enable
  427                            3:2  First pixel position in VRO data
  428                            1:0  FIFO output register select             */
  429 /* 21 */        0x80,   /* 7:0  [7:0] Pixel number per line on output   */
  430 /* 22 */        0x80,   /* 7:0  [7:0] Pixel number per line on input    */
  431 /* 23 */        0x03,   /* 7:0  [7:0] Horizontal start position of scaling win*/
  432 /* 24 */        0x8a,   /* 7:5  Horizontal decimation filter
  433                              4  [8] Horizontal start position of scaling win
  434                            3:2  [9:8] Pixel number per line on input
  435                            1:0  [9:8] Pixel number per line on output   */
  436 /* 25 */        0xf0,   /* 7:0  [7:0] Line number per output field      */
  437 /* 26 */        0xf0,   /* 7:0  [7:0] Line number per input field       */
  438 /* 27 */        0x0f,   /* 7:0  [7:0] Vertical start of scaling window  */
  439 /* 28 */        0x80,   /*   7  Adaptive filter switch
  440                            6:5  Vertical luminance data processing
  441                              4  [8] Vertical start of scaling window 
  442                            3:2  [9:8] Line number per input field
  443                            1:0  [9:8] Line number per output field      */
  444 /* 29 */        0x16,   /* 7:0  [7:0] Vertical bypass start             */
  445 /* 2a */        0x00,   /* 7:0  [7:0] Vertical bypass count             */
  446 /* 2b */        0x00,   /*   4  [8] Vertical bypass start
  447                              2  [8] Vertical bypass count
  448                              0  Polarity, internally detected odd even flag */
  449 /* 2c */        0x80,   /* 7:0  Set lower limit V for colour-keying     */
  450 /* 2d */        0x7f,   /* 7:0  Set upper limit V for colour-keying     */
  451 /* 2e */        0x80,   /* 7:0  Set lower limit U for colour-keying     */
  452 /* 2f */        0x7f,   /* 7:0  Set upper limit U for colour-keying     */
  453 /* 30 */        0xbf    /*   7  VRAM bus output format
  454                              6  Adaptive geometrical filter
  455                              5  Luminance limiting value
  456                              4  Monochrome and two's complement output data sel
  457                              3  Line quailifier flag
  458                              2  Pixel qualifier flag
  459                              1  Transparent data transfer
  460                              0  Extended formats enable bit             */
  461 };
  462 
  463 static u_char bt254_default[NUM_BT254_REGS] = {
  464         0x00,   /* 24 bpp */
  465         0xa0,
  466         0xa0,
  467         0xa0,
  468         0x50,
  469         0x50,
  470         0x50,
  471 } ;
  472 
  473 /*
  474  * i2c_write:
  475  * Returns      0       Succesful completion.
  476  * Returns      1       If transfer aborted or timeout occured.
  477  *
  478  */
  479 static int i2c_print_err = 1;
  480 static int
  481 i2c_write(meteor_reg_t * mtr, u_char slave, u_char rw, u_char reg, u_char data)
  482 {
  483 register unsigned long  wait_counter = 0x0001ffff;
  484 register mreg_t *       iic_write_loc = &mtr->base->i2c_write;
  485 register int            err = 0;
  486 
  487 
  488         /* Write the data the the i2c write register */
  489         *iic_write_loc = SAA7116_IIC_NEW_CYCLE |
  490                 (((u_long)slave|(u_long)rw) << 16) |
  491                 ((u_long)reg << 8) | (u_long)data;
  492 
  493         /* Wait until the i2c cycle is compeleted */
  494         while((*iic_write_loc & SAA7116_IIC_NEW_CYCLE)) {
  495                 if(!wait_counter) break;
  496                 wait_counter--;
  497         }
  498 
  499         /* 1ffff should be enough delay time for the i2c cycle to complete */
  500         if(!wait_counter) {
  501                 if(i2c_print_err)
  502                         printf("meteor%d: %d i2c %s transfer timeout 0x%x",
  503                                 METEOR_NUM(mtr), slave, 
  504                                 rw ? "read" : "write", *iic_write_loc);
  505                         
  506                 err=1;
  507         } 
  508 
  509         /* Check for error on direct write, clear if any */
  510         if(mtr->base->i2c_read & SAA7116_IIC_DIRECT_TRANSFER_ABORTED){
  511                 mtr->base->i2c_read |= SAA7116_IIC_DIRECT_TRANSFER_ABORTED;
  512                 if(i2c_print_err)
  513                         printf("meteor%d: 0x%x i2c %s tranfer aborted",
  514                                 METEOR_NUM(mtr), slave,
  515                                 rw ? "read" : "write" );
  516                 err= 1;
  517         }
  518 
  519         if(err) {
  520                 if(i2c_print_err)
  521                         printf(" - reg=0x%x, value=0x%x.\n", reg, data);
  522         }
  523                 
  524         return err;
  525 }
  526 #undef i2c_print
  527 
  528 static  const char *
  529 met_probe (pcici_t tag, pcidi_t type)
  530 {
  531         
  532         switch (type) {
  533         case SAA7116_PHILIPS_ID:        /* meteor */
  534                 return("Philips SAA 7116");
  535         };
  536         return ((char *)0);
  537 }
  538 
  539         /* interrupt handling routine 
  540            complete meteor_read() if using interrupts
  541         */
  542 static void
  543 meteor_intr(void *arg)
  544 {
  545         meteor_reg_t    *mtr       = (meteor_reg_t *) arg;
  546         mreg_t          *cap       = &mtr->base->cap_cntl,
  547                         *base      = &mtr->base->dma1e,
  548                         *stat      = &mtr->base->irq_stat;
  549         u_long          status     = *stat,
  550                         cap_err    = *cap & 0x00000f00,
  551 #ifdef METEOR_CHECK_PCI_BUS
  552                         pci_err    = pci_conf_read(mtr->tag,
  553                                                 PCI_COMMAND_STATUS_REG),
  554 #endif
  555                         next_base  = (u_long)(vtophys(mtr->bigbuf));
  556 
  557         /*
  558          * Disable future interrupts if a capture mode is not selected.
  559          * This can happen when we are in the process of closing or 
  560          * changing capture modes, otherwise it shouldn't happen.
  561          */
  562         if(!(mtr->flags & METEOR_CAP_MASK)) {
  563                 *cap &= 0x8ff0; /* disable future interrupts */
  564         }
  565 #ifdef METEOR_CHECK_PCI_BUS
  566         /*
  567          * Check for pci bus errors.
  568          */
  569 #define METEOR_MASTER_ABORT     0x20000000
  570 #define METEOR_TARGET_ABORT     0x10000000
  571         if(pci_err & METEOR_MASTER_ABORT) {
  572                 printf("meteor%d: intr: pci bus master dma abort: 0x%x 0x%x.\n",
  573                         METEOR_NUM(mtr), *base, *(base+3));
  574                 pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err);
  575         }
  576         if(pci_err & METEOR_TARGET_ABORT) {
  577                 printf("meteor%d: intr: pci bus target dma abort: 0x%x 0x%x.\n",
  578                         METEOR_NUM(mtr), *base, *(base+3));
  579                 pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err);
  580         }
  581 #endif
  582         /*
  583          * Check for errors.
  584          */
  585         if (cap_err) {
  586            if (cap_err & 0x300) {
  587                 if(mtr->fifo_errors % 50 == 0) {
  588                         printf("meteor%d: capture error", METEOR_NUM(mtr));
  589                         printf(": %s FIFO overflow.\n",
  590                                 cap_err&0x0100? "even" : "odd");
  591                 }
  592                 mtr->fifo_errors++ ;    /* increment fifo capture errors cnt */
  593            }
  594            if (cap_err & 0xc00) {
  595                 if(mtr->dma_errors % 50 == 0) {
  596                         printf("meteor%d: capture error", METEOR_NUM(mtr));
  597                         printf(": %s DMA address.\n",
  598                                 cap_err&0x0400? "even" : "odd");
  599                 }
  600                 mtr->dma_errors++ ;     /* increment DMA capture errors cnt */
  601            }
  602         }
  603         *cap |= 0x0f30;         /* clear error and field done */
  604 
  605         /*
  606          * In synchronous capture mode we need to know what the address
  607          * offset for the next field/frame will be.  next_base holds the
  608          * value for the even dma buffers (for odd, one must add stride).
  609          */
  610         if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait &&
  611            (mtr->current < mtr->frames)) { /* could be !=, but < is safer */
  612                 /* next_base is initialized to mtr->bigbuf */
  613                 next_base += mtr->frame_size * mtr->current;
  614                 if(mtr->flags & METEOR_WANT_TS)
  615                         next_base += sizeof(struct timeval) * mtr->current;
  616         }
  617 
  618         /*
  619          * Count the field and clear the field flag.
  620          *
  621          * In single mode capture, clear the continuous capture mode.
  622          *
  623          * In synchronous capture mode, if we have room for another field,
  624          * adjust DMA buffer pointers.
  625          * When we are above the hi water mark (hiwat), mtr->synch_wait will
  626          * be set and we will not bump the DMA buffer pointers.  Thus, once
  627          * we reach the hi water mark,  the driver acts like a continuous mode
  628          * capture on the mtr->current frame until we hit the low water
  629          * mark (lowat).  The user had the option of stopping or halting
  630          * the capture if this is not the desired effect.
  631          */
  632         if (status & 0x1) {             /* even field */
  633                 mtr->even_fields_captured++;
  634                 mtr->flags &= ~METEOR_WANT_EVEN;
  635                 if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) {
  636                         *base = next_base;
  637                         /* XXX should add adjustments for YUV_422 & PLANAR */
  638                 }
  639                 /*
  640                  * If the user requested to be notified via signal,
  641                  * let them know the field is complete.
  642                  */
  643                 if(mtr->proc != NULL) {
  644                         PROC_LOCK(mtr->proc);
  645                         psignal(mtr->proc, mtr->signal);
  646                         PROC_UNLOCK(mtr->proc);
  647                 }
  648         }
  649         if (status & 0x2) {             /* odd field */
  650                 mtr->odd_fields_captured++;
  651                 mtr->flags &= ~METEOR_WANT_ODD;
  652                 if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) {
  653                         *(base+3) = next_base + *(base+6);
  654                         /* XXX should add adjustments for YUV_422 & PLANAR */
  655                 }
  656                 /*
  657                  * If the user requested to be notified via signal,
  658                  * let them know the field is complete.
  659                  */
  660                 if(mtr->proc != NULL) {
  661                         PROC_LOCK(mtr->proc);
  662                         psignal(mtr->proc, mtr->signal);
  663                         PROC_UNLOCK(mtr->proc);
  664                 }
  665         }
  666 
  667         /*
  668          * If we have a complete frame.
  669          */
  670         if(!(mtr->flags & METEOR_WANT_MASK)) {
  671                 mtr->frames_captured++;
  672                 /*
  673                  * post the completion time. 
  674                  */
  675                 if(mtr->flags & METEOR_WANT_TS) {
  676                         struct timeval *ts;
  677                         
  678                         if(mtr->alloc_pages * PAGE_SIZE <= (mtr->frame_size +
  679                                         sizeof(struct timeval))) {
  680                                 ts =(struct timeval *)mtr->bigbuf +
  681                                                         mtr->frame_size;
  682                         /* doesn't work in synch mode except for first frame */
  683                         /* XXX */
  684                                 microtime(ts);
  685                         }
  686                 }
  687                 /*
  688                  * Wake up the user in single capture mode.
  689                  */
  690                 if(mtr->flags & METEOR_SINGLE)
  691                         wakeup(mtr);
  692                 /*
  693                  * If the user requested to be notified via signal,
  694                  * let them know the frame is complete.
  695                  */
  696                 if(mtr->proc != NULL) {
  697                         PROC_LOCK(mtr->proc);
  698                         psignal(mtr->proc, mtr->signal);
  699                         PROC_UNLOCK(mtr->proc);
  700                 }
  701                 /*
  702                  * Reset the want flags if in continuous or
  703                  * synchronous capture mode.
  704                  */
  705                 if(mtr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
  706                         switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
  707                         case METEOR_ONLY_ODD_FIELDS:
  708                                 mtr->flags |= METEOR_WANT_ODD;
  709                                 break;
  710                         case METEOR_ONLY_EVEN_FIELDS:
  711                                 mtr->flags |= METEOR_WANT_EVEN;
  712                                 break;
  713                         default:
  714                                 mtr->flags |= METEOR_WANT_MASK;
  715                                 break;
  716                         }
  717                 }
  718                 /*
  719                  * Special handling for synchronous capture mode.
  720                  */
  721                 if(mtr->flags & METEOR_SYNCAP) {
  722                         struct meteor_mem *mm = mtr->mem;
  723                         /*
  724                          * Mark the current frame as active.  It is up to
  725                          * the user to clear this, but we will clear it
  726                          * for the user for the current frame being captured
  727                          * if we are within the water marks (see below).
  728                          */
  729                         mm->active |= 1 << (mtr->current - 1);
  730 
  731                         /*
  732                          * Since the user can muck with these values, we need
  733                          * to check and see if they are sane. If they don't
  734                          * pass the sanity check, disable the capture mode.
  735                          * This is rather rude, but then so was the user.
  736                          *
  737                          * Do we really need all of this or should we just
  738                          * eliminate the possiblity of allowing the
  739                          * user to change hi and lo water marks while it
  740                          * is running? XXX
  741                          */
  742                         if(mm->num_active_bufs < 0 ||
  743                            mm->num_active_bufs > mtr->frames ||
  744                            mm->lowat < 1 || mm->lowat >= mtr->frames ||
  745                            mm->hiwat < 1 || mm->hiwat >= mtr->frames ||
  746                            mm->lowat > mm->hiwat ) {
  747                                 *cap &= 0x8ff0;
  748                                 mtr->flags &= ~(METEOR_SYNCAP|METEOR_WANT_MASK);
  749                         } else {
  750                                 /*
  751                                  * Ok, they are sane, now we want to
  752                                  * check the water marks.
  753                                  */
  754                                 if(mm->num_active_bufs <= mm->lowat)
  755                                         mtr->synch_wait = 0;
  756                                 if(mm->num_active_bufs >= mm->hiwat)
  757                                         mtr->synch_wait = 1;
  758                                 /*
  759                                  * Clear the active frame bit for this frame
  760                                  * and advance the counters if we are within
  761                                  * the banks of the water marks. 
  762                                  */
  763                                 if(!mtr->synch_wait) {
  764                                         mm->active &= ~(1 << mtr->current);
  765                                         mtr->current++;
  766                                         if(mtr->current > mtr->frames)
  767                                                 mtr->current = 1;
  768                                         mm->num_active_bufs++;
  769                                 }
  770                         }
  771                 }
  772         }
  773 
  774         *stat |=  0x7;          /* clear interrupt status */
  775         return;
  776 }
  777 
  778 static void
  779 set_fps(meteor_reg_t *mtr, u_short fps)
  780 {
  781         struct saa7116_regs *s7116 = mtr->base;
  782         unsigned status;
  783         unsigned maxfps, mask = 0x1, length = 0;
  784 
  785         SAA7196_WRITE(mtr, SAA7196_STDC, SAA7196_REG(mtr, SAA7196_STDC) | 0x02);
  786         SAA7196_READ(mtr);
  787         status = (s7116->i2c_read & 0xff000000L) >> 24;
  788 
  789         /*
  790          * Determine if there is an input signal.  Depending on the
  791          * frequency we either have a max of 25 fps (50 hz) or 30 fps (60 hz).
  792          * If there is no input signal, then we need some defaults.  If the
  793          * user neglected to specify any defaults, just set to the fps to max.
  794          */
  795         if((status & 0x40) == 0) {      /* Is there a signal ? */
  796                 if(status & 0x20) {
  797                         maxfps = 30;    /* 60 hz system */
  798                 } else {
  799                         maxfps = 25;    /* 50 hz system */
  800                 }
  801         } else {                        /* We have no signal, check defaults */
  802 #if METEOR_SYSTEM_DEFAULT == METEOR_PAL || METEOR_SYSTEM_DEFAULT == METEOR_SECAM
  803                 maxfps = 25;
  804 #elif METEOR_SYSTEM_DEFAULT == METEOR_NTSC
  805                 maxfps = 30;
  806 #else
  807                 /* Don't really know what to do, just set max */
  808                 maxfps = 30;
  809                 fps = 30;
  810 #endif
  811         }
  812 
  813         /*
  814          * A little sanity checking...
  815          */
  816         if(fps <  1)      fps = 1;
  817         if(fps > maxfps) fps = maxfps;
  818 
  819         /*
  820          * Compute the mask/length using the fps.
  821          */
  822         if(fps == maxfps) {
  823                 mask = 0x1;
  824                 length = 0x0;
  825         } else if ((float)fps == maxfps/2.0) {  
  826                 mask = 0x1;
  827                 length = 0x1;
  828         } else if (fps > maxfps/2) {
  829                 float step, b;
  830 
  831                 mask = (1<<maxfps) - 1;
  832                 length = maxfps - 1;
  833                 step = (float)(maxfps - 1)/(float)(maxfps - fps);
  834                 for(b=step; b < maxfps; b += step) {
  835                         mask &= ~(1<<((int)b)); /* mask out the bth frame */
  836                 }
  837         } else {        /* fps < maxfps/2 */
  838                 float step, b;
  839 
  840                 mask = 0x1;
  841                 length = maxfps - 1;
  842                 step = (float)(maxfps -1)/(float)(fps);
  843                 for(b = step + 1; b < maxfps - 1; b += step) {
  844                         mask |= (1<<((int)b));  /* mask in the bth frame */
  845                 }
  846         }
  847 
  848         /*
  849          * Set the fps.
  850          */
  851         s7116->fme = s7116->fmo = mask;
  852         s7116->fml = (length << 16) | length;;
  853 
  854         mtr->fps = fps;
  855 
  856         return;
  857 
  858 }
  859 
  860 /*
  861  * There is also a problem with range checking on the 7116.
  862  * It seems to only work for 22 bits, so the max size we can allocate
  863  * is 22 bits long or 4194304 bytes assuming that we put the beginning
  864  * of the buffer on a 2^24 bit boundary.  The range registers will use
  865  * the top 8 bits of the dma start registers along with the bottom 22
  866  * bits of the range register to determine if we go out of range.
  867  * This makes getting memory a real kludge.
  868  *
  869  */
  870 #define RANGE_BOUNDARY  (1<<22)
  871 static vm_offset_t
  872 get_meteor_mem(int unit, unsigned size)
  873 {
  874 vm_offset_t     addr = 0;
  875 
  876         addr = vm_page_alloc_contig(size, 0, 0xffffffff, 1<<24);
  877         if(addr == 0)
  878                 addr = vm_page_alloc_contig(size, 0, 0xffffffff, PAGE_SIZE);
  879         if(addr == 0) {
  880                 printf("meteor%d: Unable to allocate %d bytes of memory.\n",
  881                         unit, size);
  882         }
  883 
  884         return addr;
  885 }
  886 
  887 static void
  888 bt254_write(meteor_reg_t *mtr, u_char addr, u_char data)
  889 {
  890         addr &= 0x7;                                            /* sanity? */
  891         mtr->bt254_reg[addr] = data;
  892         PCF8574_DATA_WRITE(mtr, data);                          /* set data */
  893         PCF8574_CTRL_WRITE(mtr, (PCF8574_CTRL_REG(mtr) & ~0x7) | addr);
  894         PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x10); /* WR/ to 0 */
  895         PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x10);  /* WR to 1 */
  896         PCF8574_DATA_WRITE(mtr, 0xff);                          /* clr data */
  897 
  898 }
  899 
  900 static void
  901 bt254_init(meteor_reg_t *mtr)
  902 {
  903 int     i;
  904 
  905         PCF8574_CTRL_WRITE(mtr, 0x7f);
  906         PCF8574_DATA_WRITE(mtr, 0xff);  /* data port must be 0xff */
  907         PCF8574_CTRL_WRITE(mtr, 0x7f);
  908 
  909         /* init RGB module for 24bpp, composite input */
  910         for(i=0; i<NUM_BT254_REGS; i++)
  911                 bt254_write(mtr, i, bt254_default[i]);
  912 
  913         bt254_write(mtr, BT254_COMMAND, 0x00);  /* 24 bpp */
  914 }
  915 
  916 static void
  917 bt254_ntsc(meteor_reg_t *mtr, int arg)
  918 {
  919         if (arg){
  920           /* Set NTSC bit */
  921           PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x20);
  922         }
  923         else {
  924           /* reset NTSC bit */
  925           PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) &= ~0x20);
  926         }
  927 }
  928 
  929 static void
  930 select_bt254(meteor_reg_t *mtr)
  931 {
  932         /* disable saa7196, saaen = 1 */
  933         PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x80);
  934         /* enable Bt254, bten = 0 */
  935         PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x40);
  936 }
  937 
  938 static void
  939 select_saa7196(meteor_reg_t *mtr)
  940 {
  941         /* disable Bt254, bten = 1 */
  942         PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x40);
  943         /* enable saa7196, saaen = 0 */
  944         PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x80);
  945 }
  946 
  947 /*
  948  * Initialize the 7116, 7196 and the RGB module.
  949  */
  950 static void
  951 meteor_init ( meteor_reg_t *mtr )
  952 {
  953         mreg_t  *vbase_addr;
  954         int     i;
  955 
  956         /*
  957          * Initialize the Philips SAA7116
  958          */
  959         mtr->base->cap_cntl = 0x00000040L;
  960         vbase_addr = &mtr->base->dma1e;
  961         for (i = 0 ; i < (sizeof(struct saa7116_regs)/sizeof(mreg_t)); i++)
  962                 *vbase_addr++ = saa7116_pci_default[i];
  963 
  964         /*
  965          * Check for the Philips SAA7196
  966          */
  967         i2c_print_err = 0;
  968         if(i2c_write(mtr, SAA7196_I2C_ADDR, SAA7116_I2C_WRITE, 0, 0xff) == 0) {
  969                 i2c_print_err = 1;
  970                 /*
  971                  * Initialize 7196
  972                  */
  973                 for (i = 0; i < NUM_SAA7196_I2C_REGS; i++) 
  974                         SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);
  975                 /*
  976                  * Get version number.
  977                  */
  978                 SAA7196_WRITE(mtr, SAA7196_STDC,
  979                         SAA7196_REG(mtr, SAA7196_STDC) & ~0x02);
  980                 SAA7196_READ(mtr);
  981                 printf("meteor%d: <Philips SAA 7196> rev 0x%x\n",
  982                         METEOR_NUM(mtr),
  983                         (unsigned)((mtr->base->i2c_read & 0xff000000L) >> 28));
  984         } else {
  985                 i2c_print_err = 1;
  986                 printf("meteor%d: <Philips SAA 7196 NOT FOUND>\n",
  987                         METEOR_NUM(mtr));
  988         }
  989         /*
  990          * Check for RGB module, initialized if found.
  991          */
  992         i2c_print_err = 0;
  993         if(i2c_write(mtr,PCF8574_DATA_I2C_ADDR,SAA7116_I2C_WRITE,0,0xff) == 0) {
  994                 i2c_print_err = 1;
  995                 printf("meteor%d: <Booktree 254 (RGB module)>\n",
  996                         METEOR_NUM(mtr));       /* does this have a rev #? */
  997                 bt254_init(mtr);        /* Set up RGB module */
  998                 mtr->flags = METEOR_RGB;
  999         } else {
 1000                 i2c_print_err = 1;
 1001                 mtr->flags = 0;
 1002         }
 1003 
 1004         set_fps(mtr, 30);
 1005 
 1006 }
 1007 
 1008 static  void
 1009 met_attach(pcici_t tag, int unit)
 1010 {
 1011 #ifdef METEOR_IRQ
 1012         u_long old_irq, new_irq;
 1013 #endif METEOR_IRQ
 1014         meteor_reg_t *mtr;
 1015         vm_offset_t buf;
 1016         u_long latency;
 1017 
 1018         if (unit >= NMETEOR) {
 1019                 printf("meteor%d: attach: only %d units configured.\n",
 1020                                 unit, NMETEOR);
 1021                 printf("meteor%d: attach: invalid unit number.\n", unit);
 1022                 return ;
 1023         }
 1024 
 1025         /*
 1026          * Check for Meteor/PPB (PCI-PCI Bridge)
 1027          * Reprogram IBM Bridge if detected.
 1028          * New Meteor cards have an IBM PCI-PCI bridge, creating a secondary
 1029          * PCI bus. The SAA chip is connected to this secondary bus.
 1030          */
 1031 
 1032         /* If we are not on PCI Bus 0, check for the Bridge */
 1033         if ( pci_get_bus_from_tag( tag ) != 0) {
 1034                 pcici_t bridge_tag;
 1035 
 1036                 /* get tag of parent bridge */
 1037                 bridge_tag = pci_get_parent_from_tag( tag );
 1038 
 1039                 /* Look for IBM 82351, 82352 or 82353 */
 1040                 if (pci_conf_read(bridge_tag, PCI_ID_REG) == 0x00221014) {
 1041 
 1042                         if ( bootverbose)
 1043                                 printf("meteor%d: PPB device detected, reprogramming IBM bridge.\n", unit);
 1044 
 1045                         /* disable SERR */
 1046                         pci_cfgwrite(bridge_tag, 0x05, 0x00, 1);
 1047                         /* set LATENCY */
 1048                         pci_cfgwrite(bridge_tag, 0x0d, 0x20, 1);
 1049                         /* write posting enable, prefetch enabled --> GRAB direction */
 1050                         pci_cfgwrite(bridge_tag, 0x42, 0x14, 1);
 1051                         /* set PRTR Primary retry timer register */
 1052                         pci_cfgwrite(bridge_tag, 0x4c, 0x10, 1);
 1053                 }
 1054         }
 1055 
 1056         mtr = &meteor[unit];
 1057         mtr->tag = tag;
 1058         pci_map_mem(tag, PCI_MAP_REG_START, (vm_offset_t *)&mtr->base,
 1059                                 &mtr->phys_base);
 1060 
 1061 #ifdef METEOR_IRQ               /* from the configuration file */
 1062         old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
 1063         pci_conf_write(tag, PCI_INTERRUPT_REG, METEOR_IRQ);
 1064         new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
 1065         printf("meteor%d: attach: irq changed from %d to %d\n",
 1066                 unit, (old_irq & 0xff), (new_irq & 0xff));
 1067 #endif METEOR_IRQ
 1068                                 /* setup the interrupt handling routine */
 1069         pci_map_int(tag, meteor_intr, (void*) mtr, &net_imask); 
 1070 
 1071 /*
 1072  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
 1073  * you have more than for, then 16 would probably be a better value.
 1074  *
 1075  */
 1076 #ifndef METEOR_DEF_LATENCY_VALUE
 1077 #define METEOR_DEF_LATENCY_VALUE        32      
 1078 #endif
 1079         latency = pci_conf_read(tag, PCI_LATENCY_TIMER);
 1080         latency = (latency >> 8) & 0xff;
 1081         if(bootverbose) {
 1082                 if(latency)
 1083                         printf("meteor%d: PCI bus latency is", unit);
 1084                 else
 1085                         printf("meteor%d: PCI bus latency was 0 changing to",
 1086                                 unit);
 1087         }
 1088         if(!latency) {
 1089                 latency = METEOR_DEF_LATENCY_VALUE;
 1090                 pci_conf_write(tag, PCI_LATENCY_TIMER,  latency<<8);
 1091         }
 1092         if(bootverbose) {
 1093                 printf(" %lu.\n", latency);
 1094         }
 1095 
 1096         meteor_init(mtr);       /* set up saa7116, saa7196, and rgb module */
 1097 
 1098         if(METEOR_ALLOC)
 1099                 buf = get_meteor_mem(unit, METEOR_ALLOC);
 1100         else
 1101                 buf = 0;
 1102         if(bootverbose) {
 1103                 printf("meteor%d: buffer size %d, addr 0x%x\n",
 1104                         unit, METEOR_ALLOC, vtophys(buf));
 1105         }
 1106 
 1107         mtr->bigbuf = buf;
 1108         mtr->alloc_pages = METEOR_ALLOC_PAGES;
 1109         if(buf != 0) {
 1110                 bzero((caddr_t) buf, METEOR_ALLOC);
 1111                 buf = vtophys(buf);
 1112                                         /* 640x480 RGB 16 */
 1113                 mtr->base->dma1e = buf;
 1114                 mtr->base->dma1o = buf + 0x500;
 1115                 mtr->base->dma_end_e = 
 1116                 mtr->base->dma_end_o = buf + METEOR_ALLOC;
 1117         }
 1118         /* 1 frame of 640x480 RGB 16 */
 1119         mtr->cols = 640;
 1120         mtr->rows = 480;
 1121         mtr->depth = 2;         /* two bytes per pixel */
 1122         mtr->frames = 1;        /* one frame */
 1123 
 1124         mtr->flags |= METEOR_INITALIZED | METEOR_AUTOMODE | METEOR_DEV0 |
 1125                    METEOR_RGB16;
 1126         make_dev(&meteor_cdevsw, unit, 0, 0, 0644, "meteor");
 1127 }
 1128 
 1129 #define UNIT(x) ((x) & 0x07)
 1130 
 1131 #ifdef unused
 1132 static int
 1133 meteor_reset(dev_t dev)
 1134 {
 1135 int                     unit = UNIT(minor(dev));
 1136 struct  saa7116_regs    *m;
 1137 
 1138         if(unit >= NMETEOR)
 1139                 return ENXIO;
 1140 
 1141         m = meteor[unit].base;
 1142 
 1143         m->cap_cntl = 0x0;
 1144         tsleep(m, METPRI, "Mreset", hz/50);
 1145 
 1146         m->cap_cntl = 0x8ff0;
 1147         m->cap_cntl = 0x80c0;
 1148         m->cap_cntl = 0x8040;
 1149         tsleep(m, METPRI, "Mreset", hz/10);
 1150         m->cap_cntl = 0x80c0;
 1151 
 1152         return 0;
 1153 
 1154 }
 1155 #endif
 1156 
 1157 /*---------------------------------------------------------
 1158 **
 1159 **      Meteor character device driver routines
 1160 **
 1161 **---------------------------------------------------------
 1162 */
 1163 
 1164 
 1165 int
 1166 meteor_open(dev_t dev, int flags, int fmt, struct thread *td)
 1167 {
 1168         meteor_reg_t *mtr;
 1169         int     unit; 
 1170         int     i;
 1171 
 1172         unit = UNIT(minor(dev));
 1173         if (unit >= NMETEOR)    /* unit out of range */
 1174                 return(ENXIO);
 1175 
 1176         mtr = &(meteor[unit]);
 1177 
 1178         if (!(mtr->flags & METEOR_INITALIZED))  /* device not found */
 1179                 return(ENXIO);
 1180 
 1181         if (mtr->flags & METEOR_OPEN)           /* device is busy */
 1182                 return(EBUSY);
 1183 
 1184         mtr->flags |= METEOR_OPEN;
 1185         /*
 1186          * Make sure that the i2c regs are set the same for each open.
 1187          */
 1188         for(i=0; i< NUM_SAA7196_I2C_REGS; i++) {
 1189                 SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);
 1190         }
 1191 
 1192         mtr->fifo_errors = 0;
 1193         mtr->dma_errors = 0;
 1194         mtr->frames_captured = 0;
 1195         mtr->even_fields_captured = 0;
 1196         mtr->odd_fields_captured = 0;
 1197         mtr->proc = (struct proc *)0;
 1198         set_fps(mtr, 30);
 1199 #ifdef METEOR_TEST_VIDEO
 1200         mtr->video.addr = 0;
 1201         mtr->video.width = 0;
 1202         mtr->video.banksize = 0;
 1203         mtr->video.ramsize = 0;
 1204 #endif
 1205 
 1206         return(0);
 1207 }
 1208 
 1209 int
 1210 meteor_close(dev_t dev, int flags, int fmt, struct thread *td)
 1211 {
 1212         meteor_reg_t *mtr;
 1213         int     unit; 
 1214 #ifdef METEOR_DEALLOC_ABOVE
 1215         int     temp;
 1216 #endif
 1217 
 1218         unit = UNIT(minor(dev));
 1219         if (unit >= NMETEOR)    /* unit out of range */
 1220                 return(ENXIO);
 1221 
 1222         mtr = &(meteor[unit]);
 1223         mtr->flags &= ~METEOR_OPEN;
 1224 
 1225         if(mtr->flags & METEOR_SINGLE)
 1226                                 /* this should not happen, the read capture 
 1227                                   should have completed or in the very least
 1228                                   recieved a signal before close is called. */
 1229                 wakeup(mtr);    /* continue read */
 1230         /*
 1231          * Turn off capture mode.
 1232          */
 1233         mtr->base->cap_cntl = 0x8ff0;
 1234         mtr->flags &= ~(METEOR_CAP_MASK|METEOR_WANT_MASK);
 1235         mtr->proc = (struct proc *)0;
 1236 
 1237 #ifdef METEOR_DEALLOC_PAGES
 1238         if (mtr->bigbuf != NULL) {
 1239                 kmem_free(kernel_map,mtr->bigbuf,(mtr->alloc_pages*PAGE_SIZE));
 1240                 mtr->bigbuf = NULL;
 1241                 mtr->alloc_pages = 0;
 1242         }
 1243 #else
 1244 #ifdef METEOR_DEALLOC_ABOVE
 1245         if (mtr->bigbuf != NULL && mtr->alloc_pages > METEOR_DEALLOC_ABOVE) {
 1246                 temp = METEOR_DEALLOC_ABOVE - mtr->alloc_pages;
 1247                 kmem_free(kernel_map,
 1248                           mtr->bigbuf+((mtr->alloc_pages - temp) * PAGE_SIZE),
 1249                           (temp * PAGE_SIZE));
 1250                 mtr->alloc_pages = METEOR_DEALLOC_ABOVE;
 1251         }
 1252 #endif
 1253 #endif
 1254 
 1255         return(0);
 1256 }
 1257 
 1258 static void
 1259 start_capture(meteor_reg_t *mtr, unsigned type)
 1260 {
 1261 mreg_t *cap = &mtr->base->cap_cntl;
 1262 
 1263         mtr->flags |= type;
 1264         switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
 1265         case METEOR_ONLY_EVEN_FIELDS:
 1266                 mtr->flags |= METEOR_WANT_EVEN;
 1267                 if(type == METEOR_SINGLE)
 1268                         *cap = 0x0ff4 | mtr->range_enable;
 1269                 else
 1270                         *cap = 0x0ff1 | mtr->range_enable;
 1271                 break;
 1272         case METEOR_ONLY_ODD_FIELDS:
 1273                 mtr->flags |= METEOR_WANT_ODD;
 1274                 if(type == METEOR_SINGLE)
 1275                         *cap = 0x0ff8 | mtr->range_enable;
 1276                 else
 1277                         *cap = 0x0ff2 | mtr->range_enable;
 1278                 break;
 1279         default:
 1280                 mtr->flags |= METEOR_WANT_MASK;
 1281                 if(type == METEOR_SINGLE)
 1282                         *cap = 0x0ffc | mtr->range_enable;
 1283                 else
 1284                         *cap = 0x0ff3 | mtr->range_enable;
 1285                 break;
 1286         }
 1287 }
 1288 
 1289 int
 1290 meteor_read(dev_t dev, struct uio *uio, int ioflag)
 1291 {
 1292         meteor_reg_t *mtr;
 1293         int     unit; 
 1294         int     status;
 1295         int     count;
 1296 
 1297         unit = UNIT(minor(dev));
 1298         if (unit >= NMETEOR)    /* unit out of range */
 1299                 return(ENXIO);
 1300 
 1301         mtr = &(meteor[unit]);
 1302         if (mtr->bigbuf == 0)/* no frame buffer allocated (ioctl failed) */
 1303                 return(ENOMEM);
 1304 
 1305         if (mtr->flags & METEOR_CAP_MASK)
 1306                 return(EIO);            /* already capturing */
 1307 
 1308         count = mtr->rows * mtr->cols * mtr->depth;
 1309         if (uio->uio_iov->iov_len < count)
 1310                 return(EINVAL);
 1311 
 1312         /* Start capture */
 1313         start_capture(mtr, METEOR_SINGLE);
 1314 
 1315         status=tsleep(mtr, METPRI, "capturing", 0);
 1316         if (!status)            /* successful capture */
 1317                 status = uiomove((caddr_t)mtr->bigbuf, count, uio);
 1318         else
 1319                 printf ("meteor%d: read: tsleep error %d\n", unit, status);
 1320 
 1321         mtr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
 1322 
 1323         return(status);
 1324 }
 1325 
 1326 int
 1327 meteor_write(dev_t dev, struct uio *uio, int ioflag)
 1328 {
 1329         return(0);
 1330 }
 1331 
 1332 int
 1333 meteor_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
 1334 {
 1335         int     error;  
 1336         int     unit;   
 1337         int     sig;
 1338         unsigned int    temp;
 1339         meteor_reg_t *mtr;
 1340         struct meteor_counts *cnt;
 1341         struct meteor_geomet *geo;
 1342         struct meteor_mem *mem;
 1343         struct meteor_capframe *frame;
 1344 #ifdef METEOR_TEST_VIDEO
 1345         struct meteor_video *video;
 1346 #endif
 1347         vm_offset_t buf;
 1348         struct saa7116_regs *base;
 1349 
 1350         error = 0;
 1351 
 1352         if (!arg) return(EINVAL);
 1353         unit = UNIT(minor(dev));
 1354         if (unit >= NMETEOR)    /* unit out of range */
 1355                 return(ENXIO);
 1356 
 1357         mtr = &(meteor[unit]);
 1358         base = mtr->base;
 1359 
 1360         switch (cmd) {
 1361         case METEORSTS:
 1362                 if(*arg)
 1363                         mtr->flags |= METEOR_WANT_TS;
 1364                 else
 1365                         mtr->flags &= ~METEOR_WANT_TS;
 1366                 break;
 1367         case METEORGTS:
 1368                 if(mtr->flags & METEOR_WANT_TS)
 1369                         *arg = 1;
 1370                 else
 1371                         *arg = 0;
 1372                 break;
 1373 #ifdef METEOR_TEST_VIDEO
 1374         case METEORGVIDEO:
 1375                 video = (struct meteor_video *)arg;
 1376                 video->addr = mtr->video.addr;
 1377                 video->width = mtr->video.width;
 1378                 video->banksize = mtr->video.banksize;
 1379                 video->ramsize = mtr->video.ramsize;
 1380                 break;
 1381         case METEORSVIDEO:
 1382                 video = (struct meteor_video *)arg;
 1383                 mtr->video.addr = video->addr;
 1384                 mtr->video.width = video->width;
 1385                 mtr->video.banksize = video->banksize;
 1386                 mtr->video.ramsize = video->ramsize;
 1387                 break;
 1388 #endif
 1389         case METEORSFPS:
 1390                 set_fps(mtr, *(u_short *)arg);
 1391                 break;
 1392         case METEORGFPS:
 1393                 *(u_short *)arg = mtr->fps;
 1394                 break;
 1395         case METEORSSIGNAL:
 1396                 sig = *(int *)arg;
 1397                 /* Applications use 0 to reset signal delivery. */
 1398                 if (sig < 0 || sig > _SIG_MAXSIG)
 1399                         return (EINVAL);
 1400                 mtr->signal = sig;
 1401                 mtr->proc = sig ? td->td_proc : NULL;
 1402                 break;
 1403         case METEORGSIGNAL:
 1404                 *(int *)arg = mtr->signal;
 1405                 break;
 1406         case METEORSTATUS:      /* get 7196 status */
 1407                 temp = 0;
 1408                 SAA7196_WRITE(mtr, SAA7196_STDC,
 1409                         SAA7196_REG(mtr, SAA7196_STDC) | 0x02);
 1410                 SAA7196_READ(mtr);
 1411                 temp |= (base->i2c_read & 0xff000000L) >> 24;
 1412                 SAA7196_WRITE(mtr, SAA7196_STDC,
 1413                         SAA7196_REG(mtr, SAA7196_STDC) & ~0x02);
 1414                 SAA7196_READ(mtr);
 1415                 temp |= (base->i2c_read & 0xff000000L) >> 16;
 1416                 *(u_short *)arg = temp;
 1417                 break;
 1418         case METEORSHUE:        /* set hue */
 1419                 SAA7196_WRITE(mtr, SAA7196_HUEC, *(char *)arg);
 1420                 break;
 1421         case METEORGHUE:        /* get hue */
 1422                 *(char *)arg = SAA7196_REG(mtr, SAA7196_HUEC);
 1423                 break;
 1424         case METEORSCHCV:       /* set chrominance gain */
 1425                 SAA7196_WRITE(mtr, SAA7196_CGAINR, *(char *)arg);
 1426                 break;
 1427         case METEORGCHCV:       /* get chrominance gain */
 1428                 *(char *)arg = SAA7196_REG(mtr, SAA7196_CGAINR);
 1429                 break;
 1430         case METEORSBRIG:       /* set brightness */
 1431                 SAA7196_WRITE(mtr, SAA7196_BRIG, *(char *)arg);
 1432                 break;
 1433         case METEORGBRIG:       /* get brightness */
 1434                 *(char *)arg = SAA7196_REG(mtr, SAA7196_BRIG);
 1435                 break;
 1436         case METEORSCSAT:       /* set chroma saturation */
 1437                 SAA7196_WRITE(mtr, SAA7196_CSAT, *(char *)arg);
 1438                 break;
 1439         case METEORGCSAT:       /* get chroma saturation */
 1440                 *(char *)arg = SAA7196_REG(mtr, SAA7196_CSAT);
 1441                 break;
 1442         case METEORSCONT:       /* set contrast */
 1443                 SAA7196_WRITE(mtr, SAA7196_CONT, *(char *)arg);
 1444                 break;
 1445         case METEORGCONT:       /* get contrast */
 1446                 *(char *)arg = SAA7196_REG(mtr, SAA7196_CONT);
 1447                 break;
 1448         case METEORSBT254:
 1449                 if((mtr->flags & METEOR_RGB) == 0)
 1450                         return EINVAL;
 1451                 temp = *(unsigned short *)arg;
 1452                 bt254_write(mtr, temp & 0xf, (temp & 0x0ff0) >> 4);
 1453                 break;
 1454         case METEORGBT254:
 1455                 if((mtr->flags & METEOR_RGB) == 0)
 1456                         return EINVAL;
 1457                 temp = *(unsigned short *)arg & 0x7;
 1458                 *(unsigned short *)arg = mtr->bt254_reg[temp] << 4 | temp;
 1459                 break;
 1460         case METEORSHWS:        /* set horizontal window start */
 1461                 SAA7196_WRITE(mtr, SAA7196_HWS, *(char *)arg);
 1462                 break;
 1463         case METEORGHWS:        /* get horizontal window start */
 1464                 *(char *)arg = SAA7196_REG(mtr, SAA7196_HWS);
 1465                 break;
 1466         case METEORSVWS:        /* set vertical window start */
 1467                 SAA7196_WRITE(mtr, SAA7196_VWS, *(char *)arg);
 1468                 break;
 1469         case METEORGVWS:        /* get vertical window start */
 1470                 *(char *)arg = SAA7196_REG(mtr, SAA7196_VWS);
 1471                 break;
 1472         case METEORSINPUT:      /* set input device */
 1473                 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
 1474                 case 0:                 /* default */
 1475                 case METEOR_INPUT_DEV0:
 1476                         if(mtr->flags & METEOR_RGB)
 1477                                 select_saa7196(mtr);
 1478                         mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
 1479                                 | METEOR_DEV0;
 1480                         SAA7196_WRITE(mtr, 0x0e,
 1481                                 (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x0);
 1482                         SAA7196_WRITE(mtr, 0x06,
 1483                                 (SAA7196_REG(mtr, 0x06) & ~0x80));
 1484                         break;
 1485                 case METEOR_INPUT_DEV1:
 1486                         if(mtr->flags & METEOR_RGB)
 1487                                 select_saa7196(mtr);
 1488                         mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
 1489                                                | METEOR_DEV1;
 1490                         SAA7196_WRITE(mtr, 0x0e,
 1491                                 (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x1);
 1492                         SAA7196_WRITE(mtr, 0x06,
 1493                                 (SAA7196_REG(mtr, 0x06) & ~0x80));
 1494                         break;
 1495                 case METEOR_INPUT_DEV2:
 1496                         if(mtr->flags & METEOR_RGB)
 1497                                 select_saa7196(mtr);
 1498                         mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
 1499                                                | METEOR_DEV2;
 1500                         SAA7196_WRITE(mtr, 0x0e,
 1501                                 (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2);
 1502                         SAA7196_WRITE(mtr, 0x06,
 1503                                 (SAA7196_REG(mtr, 0x06) & ~0x80));
 1504                         break;
 1505                 case METEOR_INPUT_DEV3:
 1506                         if(mtr->flags & METEOR_RGB)
 1507                                 select_saa7196(mtr);
 1508                         mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
 1509                                                | METEOR_DEV3;
 1510                         SAA7196_WRITE(mtr, 0x0e,
 1511                                 (SAA7196_REG(mtr, 0x0e) | 0x3));
 1512                         SAA7196_WRITE(mtr, 0x06,
 1513                                 (SAA7196_REG(mtr, 0x06) & ~0x80) );
 1514                         break;
 1515                 case METEOR_INPUT_DEV_SVIDEO:
 1516                         if(mtr->flags & METEOR_RGB)
 1517                                 select_saa7196(mtr);
 1518                         mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
 1519                                                | METEOR_DEV_SVIDEO;
 1520                         SAA7196_WRITE(mtr, 0x0e,
 1521                                 (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2);
 1522                         SAA7196_WRITE(mtr, 0x06,
 1523                                 (SAA7196_REG(mtr, 0x06) & ~0x80) | 0x80);
 1524                         break;
 1525                 case METEOR_INPUT_DEV_RGB:
 1526                         if((mtr->flags & METEOR_RGB) == 0)
 1527                                 return EINVAL;
 1528                         mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
 1529                                                | METEOR_DEV_RGB;
 1530                         SAA7196_WRITE(mtr, 0x0e,
 1531                                 (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x3);
 1532                         SAA7196_WRITE(mtr, 0x06,
 1533                                 (SAA7196_REG(mtr, 0x06) & ~0x80));
 1534                         select_bt254(mtr);
 1535                         SAA7196_WRITE(mtr, 0x0e,        /* chn 3 for synch */
 1536                                 (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x3);
 1537                         break;
 1538                 default:
 1539                         return EINVAL;
 1540                 }
 1541                 break;
 1542         case METEORGINPUT:      /* get input device */
 1543                 *(u_long *)arg = mtr->flags & METEOR_DEV_MASK;
 1544                 break;
 1545         case METEORSFMT:        /* set input format */
 1546                 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
 1547                 case 0:                 /* default */
 1548                 case METEOR_FMT_NTSC:
 1549                         mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
 1550                                 METEOR_NTSC;
 1551                         SAA7196_WRITE(mtr, SAA7196_STDC, 
 1552                                 (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01));
 1553                         SAA7196_WRITE(mtr, 0x0f,
 1554                                 (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x40);
 1555                         SAA7196_WRITE(mtr, 0x22, 0x80);
 1556                         SAA7196_WRITE(mtr, 0x24, 
 1557                                 (SAA7196_REG(mtr, 0x24) & ~0x0c) | 0x08);
 1558                         SAA7196_WRITE(mtr, 0x26, 0xf0);
 1559                         SAA7196_WRITE(mtr, 0x28, 
 1560                                 (SAA7196_REG(mtr, 0x28) & ~0x0c)) ;
 1561                         if(mtr->flags & METEOR_RGB){
 1562                           bt254_ntsc(mtr, 1);                     
 1563                         }
 1564                 break;
 1565                 case METEOR_FMT_PAL:
 1566                         mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
 1567                                 METEOR_PAL;
 1568                         SAA7196_WRITE(mtr, SAA7196_STDC, 
 1569                                 (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01));
 1570                         SAA7196_WRITE(mtr, 0x0f, 
 1571                                 (SAA7196_REG(mtr, 0x0f) & ~0xe0));
 1572                         SAA7196_WRITE(mtr, 0x22, 0x00);
 1573                         SAA7196_WRITE(mtr, 0x24, 
 1574                                 (SAA7196_REG(mtr, 0x24) | 0x0c));
 1575                         SAA7196_WRITE(mtr, 0x26, 0x20);
 1576                         SAA7196_WRITE(mtr, 0x28, 
 1577                                 (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x04) ;
 1578                         if(mtr->flags & METEOR_RGB){
 1579                           bt254_ntsc(mtr, 0);                     
 1580                         }
 1581                 break;
 1582                 case METEOR_FMT_SECAM:
 1583                         mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
 1584                                 METEOR_SECAM;
 1585                         SAA7196_WRITE(mtr, SAA7196_STDC, 
 1586                                 (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01) | 0x1);
 1587                         SAA7196_WRITE(mtr, 0x0f, 
 1588                                 (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x20);
 1589                         SAA7196_WRITE(mtr, 0x22, 0x00);
 1590                         SAA7196_WRITE(mtr, 0x24, 
 1591                                 (SAA7196_REG(mtr, 0x24) | 0x0c));
 1592                         SAA7196_WRITE(mtr, 0x26, 0x20);
 1593                         SAA7196_WRITE(mtr, 0x28, 
 1594                                 (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x04) ;
 1595                         if(mtr->flags & METEOR_RGB){
 1596                           bt254_ntsc(mtr, 0);
 1597                         }
 1598                 break;
 1599                 case METEOR_FMT_AUTOMODE:
 1600                         mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
 1601                                 METEOR_AUTOMODE;
 1602                         SAA7196_WRITE(mtr, SAA7196_STDC, 
 1603                                 (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01));
 1604                         SAA7196_WRITE(mtr, 0x0f, 
 1605                                 (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x80);
 1606                 break;
 1607                 default:
 1608                         return EINVAL;
 1609                 }
 1610                 break;
 1611         case METEORGFMT:        /* get input format */
 1612                 *(u_long *)arg = mtr->flags & METEOR_FORM_MASK;
 1613                 break;
 1614         case METEORCAPTUR:
 1615                 temp = mtr->flags;
 1616                 switch (*(int *) arg) {
 1617                 case METEOR_CAP_SINGLE:
 1618                         if (mtr->bigbuf==0)     /* no frame buffer allocated */
 1619                                 return(ENOMEM);
 1620 
 1621                         if (temp & METEOR_CAP_MASK)
 1622                                 return(EIO);            /* already capturing */
 1623 
 1624                         start_capture(mtr, METEOR_SINGLE);
 1625 
 1626                         /* wait for capture to complete */
 1627                         error=tsleep(mtr, METPRI, "capturing", 0);
 1628                         if(error)
 1629                                 printf("meteor%d: ioctl: tsleep error %d\n",
 1630                                         unit, error);
 1631                         mtr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
 1632                         break;
 1633                 case METEOR_CAP_CONTINOUS:
 1634                         if (mtr->bigbuf==0)     /* no frame buffer allocated */
 1635                                 return(ENOMEM);
 1636 
 1637                         if (temp & METEOR_CAP_MASK)
 1638                                 return(EIO);            /* already capturing */
 1639 
 1640                         start_capture(mtr, METEOR_CONTIN);
 1641 
 1642                         break;
 1643                 case METEOR_CAP_STOP_CONT:
 1644                         if (mtr->flags & METEOR_CONTIN) {
 1645                                                         /* turn off capture */
 1646                                 base->cap_cntl = 0x8ff0;
 1647                                 mtr->flags &= ~(METEOR_CONTIN|METEOR_WANT_MASK);
 1648                         }
 1649                         break;
 1650         
 1651                 default:
 1652                         error = EINVAL;
 1653                         break;
 1654                 }
 1655                 break;
 1656         case METEORCAPFRM:
 1657             frame = (struct meteor_capframe *) arg;
 1658             if (!frame) 
 1659                 return(EINVAL);
 1660             switch (frame->command) {
 1661             case METEOR_CAP_N_FRAMES:
 1662                 if (mtr->flags & METEOR_CAP_MASK)
 1663                         return(EIO);
 1664                 if (mtr->flags & (METEOR_YUV_PLANAR | METEOR_YUV_422)) /* XXX */
 1665                         return(EINVAL); /* should fix intr so we allow these */
 1666                 if (mtr->bigbuf == 0)
 1667                         return(ENOMEM);
 1668                 if ((mtr->frames < 2) ||
 1669                     (frame->lowat < 1 || frame->lowat >= mtr->frames) ||
 1670                     (frame->hiwat < 1 || frame->hiwat >= mtr->frames) ||
 1671                     (frame->lowat > frame->hiwat)) 
 1672                         return(EINVAL);
 1673                         /* meteor_mem structure is on the page after the data */
 1674                 mem = mtr->mem = (struct meteor_mem *) (mtr->bigbuf +
 1675                                 (round_page(mtr->frame_size * mtr->frames)));
 1676                 mtr->current = 1;
 1677                 mtr->synch_wait = 0;
 1678                 mem->num_bufs = mtr->frames;
 1679                 mem->frame_size= mtr->frame_size;
 1680                 /* user and kernel change these */ 
 1681                 mem->lowat = frame->lowat;
 1682                 mem->hiwat = frame->hiwat;
 1683                 mem->active = 0;
 1684                 mem->num_active_bufs = 0;
 1685                 /* Start capture */
 1686                 start_capture(mtr, METEOR_SYNCAP);
 1687                 break;
 1688             case METEOR_CAP_STOP_FRAMES:
 1689                 if (mtr->flags & METEOR_SYNCAP) {
 1690                                                 /* turn off capture */
 1691                         base->cap_cntl = 0x8ff0;
 1692                         mtr->flags &= ~(METEOR_SYNCAP|METEOR_WANT_MASK);
 1693                 }
 1694                 break;
 1695             case METEOR_HALT_N_FRAMES:
 1696                 if(mtr->flags & METEOR_SYNCAP) {
 1697                         base->cap_cntl = 0x8ff0;
 1698                         mtr->flags &= ~(METEOR_WANT_MASK);
 1699                 }
 1700                 break;
 1701             case METEOR_CONT_N_FRAMES:
 1702                 if(!(mtr->flags & METEOR_SYNCAP)) {
 1703                         error = EINVAL;
 1704                         break;
 1705                 }
 1706                 start_capture(mtr, METEOR_SYNCAP);
 1707                 break;
 1708             default:
 1709                 error = EINVAL;
 1710                 break;
 1711             }
 1712             break;
 1713  
 1714         case METEORSETGEO:
 1715                 geo = (struct meteor_geomet *) arg;
 1716 
 1717                 /* Either even or odd, if even & odd, then these a zero */
 1718                 if((geo->oformat & METEOR_GEO_ODD_ONLY) &&
 1719                         (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
 1720                         printf("meteor%d: ioctl: Geometry odd or even only.\n",
 1721                                 unit);
 1722                         return EINVAL;
 1723                 }
 1724                 /* set/clear even/odd flags */
 1725                 if(geo->oformat & METEOR_GEO_ODD_ONLY)
 1726                         mtr->flags |= METEOR_ONLY_ODD_FIELDS;
 1727                 else
 1728                         mtr->flags &= ~METEOR_ONLY_ODD_FIELDS;
 1729                 if(geo->oformat & METEOR_GEO_EVEN_ONLY)
 1730                         mtr->flags |= METEOR_ONLY_EVEN_FIELDS;
 1731                 else
 1732                         mtr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
 1733 
 1734                 /* can't change parameters while capturing */
 1735                 if (mtr->flags & METEOR_CAP_MASK)
 1736                         return(EBUSY);
 1737 
 1738                 if ((geo->columns & 0x3fe) != geo->columns) {
 1739                         printf(
 1740                         "meteor%d: ioctl: %d: columns too large or not even.\n",
 1741                                 unit, geo->columns);
 1742                         error = EINVAL;
 1743                 }
 1744                 if (((geo->rows & 0x7fe) != geo->rows) ||
 1745                         ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
 1746                                 ((geo->rows & 0x3fe) != geo->rows)) ) {
 1747                         printf(
 1748                         "meteor%d: ioctl: %d: rows too large or not even.\n",
 1749                                 unit, geo->rows);
 1750                         error = EINVAL;
 1751                 }
 1752                 if (geo->frames > 32) {
 1753                         printf("meteor%d: ioctl: too many frames.\n", unit);
 1754                         error = EINVAL;
 1755                 }
 1756                 if(error) return error;
 1757 
 1758                 if ((temp=geo->rows * geo->columns * geo->frames * 2) != 0) {
 1759                         if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
 1760 
 1761                         /* meteor_mem structure for SYNC Capture */
 1762                         if (geo->frames > 1) temp += PAGE_SIZE;
 1763 
 1764                         temp = btoc(temp);
 1765                         if (temp > mtr->alloc_pages
 1766 #ifdef METEOR_TEST_VIDEO
 1767                             && mtr->video.addr == 0
 1768 #endif
 1769                         ) {
 1770                                 buf = get_meteor_mem(unit, temp*PAGE_SIZE);
 1771                                 if(buf != 0) {
 1772                                         kmem_free(kernel_map, mtr->bigbuf,
 1773                                           (mtr->alloc_pages * PAGE_SIZE));
 1774                                         mtr->bigbuf = buf;
 1775                                         mtr->alloc_pages = temp;
 1776                                         if(bootverbose)
 1777                                                 printf(
 1778                                 "meteor%d: ioctl: Allocating %d bytes\n",
 1779                                                         unit, temp*PAGE_SIZE);
 1780                                 } else {
 1781                                         error = ENOMEM;
 1782                                 }
 1783                         }
 1784                 }
 1785                 if(error) return error;
 1786 
 1787                 mtr->rows = geo->rows;
 1788                 mtr->cols = geo->columns;
 1789                 mtr->frames = geo->frames;
 1790 
 1791 #ifdef METEOR_TEST_VIDEO
 1792                 if(mtr->video.addr)
 1793                         buf = vtophys(mtr->video.addr);
 1794                 else
 1795 #endif
 1796                         buf = vtophys(mtr->bigbuf);
 1797 
 1798                 /* set defaults and end of buffer locations */
 1799                 base->dma1e = buf;
 1800                 base->dma2e = buf;
 1801                 base->dma3e = buf;
 1802                 base->dma1o = buf;
 1803                 base->dma2o = buf;
 1804                 base->dma3o = buf;
 1805                 base->stride1e = 0;
 1806                 base->stride2e = 0;
 1807                 base->stride3e = 0;
 1808                 base->stride1o = 0;
 1809                 base->stride2o = 0;
 1810                 base->stride3o = 0;
 1811                                 /* set end of DMA location, even/odd */
 1812                 base->dma_end_e =
 1813                 base->dma_end_o = buf + mtr->alloc_pages * PAGE_SIZE;
 1814 
 1815                 /*
 1816                  * Determine if we can use the hardware range detect.
 1817                  */
 1818                 if(mtr->alloc_pages * PAGE_SIZE < RANGE_BOUNDARY &&
 1819                   ((buf & 0xff000000) | base->dma_end_e) ==
 1820                         (buf + mtr->alloc_pages * PAGE_SIZE) )
 1821                         mtr->range_enable = 0x8000;
 1822                 else {
 1823                         mtr->range_enable = 0x0;
 1824                         base->dma_end_e =
 1825                         base->dma_end_o = 0xffffffff;
 1826                 }
 1827 
 1828 
 1829                 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
 1830                 case 0:                 /* default */
 1831                 case METEOR_GEO_RGB16:
 1832                         mtr->depth = 2;
 1833                         mtr->frame_size = mtr->rows * mtr->cols * mtr->depth;
 1834                         mtr->flags &= ~METEOR_OUTPUT_FMT_MASK;
 1835                         mtr->flags |= METEOR_RGB16;
 1836                         temp = mtr->cols * mtr->depth;
 1837                         /* recal stride and starting point */
 1838                         switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
 1839                         case METEOR_ONLY_ODD_FIELDS:
 1840                                 base->dma1o = buf;
 1841 #ifdef METEOR_TEST_VIDEO
 1842                                 if(mtr->video.addr && mtr->video.width) 
 1843                                         base->stride1o = mtr->video.width-temp;
 1844 #endif
 1845                                 SAA7196_WRITE(mtr, 0x20, 0xd0);
 1846                                 break;
 1847                         case METEOR_ONLY_EVEN_FIELDS:
 1848                                 base->dma1e = buf;
 1849 #ifdef METEOR_TEST_VIDEO
 1850                                 if(mtr->video.addr && mtr->video.width) 
 1851                                         base->stride1e = mtr->video.width-temp;
 1852 #endif
 1853                                 SAA7196_WRITE(mtr, 0x20, 0xf0);
 1854                                 break;
 1855                         default: /* interlaced even/odd */
 1856                                 base->dma1e = buf;              
 1857                                 base->dma1o = buf + temp;
 1858                                 base->stride1e = base->stride1o = temp;
 1859 #ifdef METEOR_TEST_VIDEO
 1860                                 if(mtr->video.addr && mtr->video.width) {
 1861                                         base->dma1o = buf + mtr->video.width;
 1862                                         base->stride1e = base->stride1o =
 1863                                                 mtr->video.width -
 1864                                                 temp + mtr->video.width;
 1865                                 }
 1866 #endif
 1867                                 SAA7196_WRITE(mtr, 0x20, 0x90);
 1868                                 break;
 1869                         }
 1870                         base->routee = base->routeo  = 0xeeeeee01;
 1871                         break;
 1872                 case METEOR_GEO_RGB24:
 1873                         mtr->depth = 4;
 1874                         mtr->frame_size = mtr->rows * mtr->cols * mtr->depth;
 1875                         mtr->flags &= ~METEOR_OUTPUT_FMT_MASK;
 1876                         mtr->flags |= METEOR_RGB24;
 1877                         temp = mtr->cols * mtr->depth;
 1878                         /* recal stride and starting point */
 1879                         switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
 1880                         case METEOR_ONLY_ODD_FIELDS:
 1881                                 base->dma1o = buf;
 1882 #ifdef METEOR_TEST_VIDEO
 1883                                 if(mtr->video.addr && mtr->video.width) 
 1884                                         base->stride1o = mtr->video.width-temp;
 1885 #endif
 1886                                 SAA7196_WRITE(mtr, 0x20, 0xd2);
 1887                                 break;
 1888                         case METEOR_ONLY_EVEN_FIELDS:
 1889                                 base->dma1e = buf;
 1890 #ifdef METEOR_TEST_VIDEO
 1891                                 if(mtr->video.addr && mtr->video.width) 
 1892                                         base->stride1e = mtr->video.width-temp;
 1893 #endif
 1894                                 SAA7196_WRITE(mtr, 0x20, 0xf2);
 1895                                 break;
 1896                         default: /* interlaced even/odd */
 1897                                 base->dma1e = buf;
 1898                                 base->dma1o = buf + mtr->cols * mtr->depth;
 1899                                 base->stride1e = base->stride1o =
 1900                                         mtr->cols * mtr->depth;
 1901 #ifdef METEOR_TEST_VIDEO
 1902                                 if(mtr->video.addr && mtr->video.width) {
 1903                                         base->dma1o = buf + mtr->video.width;
 1904                                         base->stride1e = base->stride1o = 
 1905                                                 mtr->video.width -
 1906                                                 temp + mtr->video.width;
 1907                                 }
 1908 #endif
 1909                                 SAA7196_WRITE(mtr, 0x20, 0x92);
 1910                                 break;
 1911                         }
 1912                         base->routee= base->routeo= 0x39393900;
 1913                         break;
 1914                 case METEOR_GEO_YUV_PLANAR:
 1915                         mtr->depth = 2;
 1916                         temp = mtr->rows * mtr->cols;   /* compute frame size */
 1917                         mtr->frame_size = temp * mtr->depth;
 1918                         mtr->flags &= ~METEOR_OUTPUT_FMT_MASK;
 1919                         mtr->flags |= METEOR_YUV_PLANAR;
 1920                         /* recal stride and starting point */
 1921                         switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
 1922                         case METEOR_ONLY_ODD_FIELDS:
 1923                                 base->dma1o = buf;              /* Y Odd */
 1924                                 base->dma2o = buf + temp;       /* U Odd */
 1925                                 temp >>= 1;
 1926                                 base->dma3o = base->dma2o + temp; /* V Odd */
 1927                                 SAA7196_WRITE(mtr, 0x20, 0xd1);
 1928                                 break;
 1929                         case METEOR_ONLY_EVEN_FIELDS:
 1930                                 base->dma1e = buf;              /* Y Even */
 1931                                 base->dma2e = buf + temp;       /* U Even */
 1932                                 temp >>= 1;
 1933                                 base->dma2e= base->dma2e + temp; /* V Even */
 1934                                 SAA7196_WRITE(mtr, 0x20, 0xf1);
 1935                                 break;
 1936                         default: /* interlaced even/odd */
 1937                                 base->dma1e = buf;              /* Y Even */
 1938                                 base->dma2e = buf + temp;       /* U Even */
 1939                                 temp >>= 2;
 1940                                 base->dma3e = base->dma2e + temp; /* V Even */
 1941                                 base->dma1o = base->dma1e+mtr->cols;/* Y Odd */
 1942                                 base->dma2o = base->dma3e + temp; /* U Odd */
 1943                                 base->dma3o = base->dma2o + temp; /* V Odd */
 1944                                 base->stride1e = base->stride1o = mtr->cols;
 1945                                 SAA7196_WRITE(mtr, 0x20, 0x91);
 1946                                 break;
 1947                         }
 1948                         switch (geo->oformat &
 1949                                 (METEOR_GEO_YUV_12 | METEOR_GEO_YUV_9)) {
 1950                                 case METEOR_GEO_YUV_9:
 1951                                         base->routee=base->routeo = 0xaaaaffc3;
 1952                                         break;
 1953                                 case METEOR_GEO_YUV_12:
 1954                                         base->routee=base->routeo = 0xaaaaffc2;
 1955                                         break;
 1956                                 default:
 1957                                         base->routee=base->routeo = 0xaaaaffc1;
 1958                                         break;
 1959                         }
 1960                         break;
 1961                 case METEOR_GEO_YUV_422:/* same as planer, different uv order */
 1962                         mtr->depth = 2;
 1963                         temp = mtr->rows * mtr->cols;   /* compute frame size */
 1964                         mtr->frame_size = temp * mtr->depth;
 1965                         mtr->flags &= ~METEOR_OUTPUT_FMT_MASK;
 1966                         mtr->flags |= METEOR_YUV_422;
 1967                         switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
 1968                         case METEOR_ONLY_ODD_FIELDS:
 1969                                 base->dma1o = buf;
 1970                                 base->dma2o = buf + temp;
 1971                                 base->dma3o = base->dma2o  + (temp >> 1);
 1972                                 SAA7196_WRITE(mtr, 0x20, 0xd1);
 1973                                 break;
 1974                         case METEOR_ONLY_EVEN_FIELDS:
 1975                                 base->dma1e = buf;
 1976                                 base->dma2e = buf + temp;
 1977                                 base->dma3e = base->dma2e + (temp >> 1);
 1978                                 SAA7196_WRITE(mtr, 0x20, 0xf1);
 1979                                 break;
 1980                         default: /* interlaced even/odd */
 1981                                 base->dma1e = buf;              /* Y even */
 1982                                 base->dma2e = buf + temp;       /* U even */
 1983                                 base->dma3e =
 1984                                         base->dma2e + (temp >> 1);/* V even */
 1985                                 base->dma1o = base->dma1e+mtr->cols;/* Y odd */
 1986                                 temp = mtr->cols >> 1;
 1987                                 base->dma2o = base->dma2e+temp; /* U odd */
 1988                                 base->dma3o = base->dma3e+temp; /* V odd */
 1989                                 base->stride1e =
 1990                                 base->stride1o = mtr->cols;     /* Y stride */
 1991                                 base->stride2e = 
 1992                                 base->stride2o = temp;          /* U stride */
 1993                                 base->stride3e =
 1994                                 base->stride3o = temp;          /* V stride */
 1995                                 SAA7196_WRITE(mtr, 0x20, 0x91);
 1996                                 break;
 1997                         }
 1998                         switch (geo->oformat &
 1999                                 (METEOR_GEO_YUV_12 | METEOR_GEO_YUV_9)) {
 2000                                 case METEOR_GEO_YUV_9:
 2001                                         base->routee=base->routeo = 0xaaaaffc3;
 2002                                         break;
 2003                                 case METEOR_GEO_YUV_12:
 2004                                         base->routee=base->routeo = 0xaaaaffc2;
 2005                                         break;
 2006                                 default:
 2007                                         base->routee=base->routeo = 0xaaaaffc1;
 2008                                         break;
 2009                         }
 2010                         break;
 2011                 case METEOR_GEO_YUV_PACKED:
 2012                         mtr->depth = 2;
 2013                         mtr->frame_size = mtr->rows * mtr->cols * mtr->depth;
 2014                         mtr->flags &= ~METEOR_OUTPUT_FMT_MASK;
 2015                         mtr->flags |= METEOR_YUV_PACKED;
 2016                         /* recal stride and odd starting point */
 2017                         switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
 2018                         case METEOR_ONLY_ODD_FIELDS:
 2019                                 base->dma1o = buf;
 2020                                 SAA7196_WRITE(mtr, 0x20, 0xd1);
 2021                                 break;
 2022                         case METEOR_ONLY_EVEN_FIELDS:
 2023                                 base->dma1e = buf;
 2024                                 SAA7196_WRITE(mtr, 0x20, 0xf1);
 2025                                 break;
 2026                         default: /* interlaced even/odd */
 2027                                 base->dma1e = buf;
 2028                                 base->dma1o = buf + mtr->cols * mtr->depth;
 2029                                 base->stride1e = base->stride1o =
 2030                                         mtr->cols * mtr->depth;
 2031                                 SAA7196_WRITE(mtr, 0x20, 0x91);
 2032                                 break;
 2033                         }
 2034                         base->routee = base->routeo = 0xeeeeee41;
 2035                         break;
 2036                 default:
 2037                         error = EINVAL; /* invalid argument */
 2038                         printf("meteor%d: ioctl: invalid output format\n",unit);
 2039                         break;
 2040                 }
 2041                 /* set cols */
 2042                 SAA7196_WRITE(mtr, 0x21, mtr->cols & 0xff);
 2043                 SAA7196_WRITE(mtr, 0x24,
 2044                                 ((SAA7196_REG(mtr, 0x24) & ~0x03) |
 2045                                 ((mtr->cols >> 8) & 0x03)));
 2046                 /* set rows */
 2047                 if(mtr->flags & METEOR_ONLY_FIELDS_MASK) {
 2048                         SAA7196_WRITE(mtr, 0x25, ((mtr->rows) & 0xff));
 2049                         SAA7196_WRITE(mtr, 0x28,
 2050                                         ((SAA7196_REG(mtr, 0x28) & ~0x03) |
 2051                                         ((mtr->rows >> 8) & 0x03)));
 2052                 } else {        /* Interlaced */
 2053                         SAA7196_WRITE(mtr, 0x25, ((mtr->rows >> 1) & 0xff));
 2054                         SAA7196_WRITE(mtr, 0x28,
 2055                                         ((SAA7196_REG(mtr, 0x28) & ~0x03) |
 2056                                         ((mtr->rows >> 9) & 0x03)));
 2057                 }
 2058                 /* set signed/unsigned chrominance */
 2059                 SAA7196_WRITE(mtr, 0x30, (SAA7196_REG(mtr, 0x30) & ~0x10) |
 2060                                 ((geo->oformat&METEOR_GEO_UNSIGNED)?0:0x10));
 2061                 break;
 2062         case METEORGETGEO:
 2063                 geo = (struct meteor_geomet *) arg;
 2064                 geo->rows = mtr->rows;
 2065                 geo->columns = mtr->cols;
 2066                 geo->frames = mtr->frames;
 2067                 geo->oformat = (mtr->flags & METEOR_OUTPUT_FMT_MASK) |
 2068                                (mtr->flags & METEOR_ONLY_FIELDS_MASK) |
 2069                                (SAA7196_REG(mtr, 0x30) & 0x10 ? 
 2070                                 0:METEOR_GEO_UNSIGNED);
 2071                 switch(base->routee & 0xff) {
 2072                 case    0xc3:
 2073                         geo->oformat |=  METEOR_GEO_YUV_9;
 2074                         break;
 2075                 case    0xc2:
 2076                         geo->oformat |=  METEOR_GEO_YUV_12;
 2077                         break;
 2078                 default:
 2079                         break;
 2080                 }
 2081                 break;
 2082         case METEORSCOUNT:      /* (re)set error counts */
 2083                 cnt = (struct meteor_counts *) arg;
 2084                 mtr->fifo_errors = cnt->fifo_errors;
 2085                 mtr->dma_errors = cnt->dma_errors;
 2086                 mtr->frames_captured = cnt->frames_captured;
 2087                 mtr->even_fields_captured = cnt->even_fields_captured;
 2088                 mtr->odd_fields_captured = cnt->odd_fields_captured;
 2089                 break;
 2090         case METEORGCOUNT:      /* get error counts */
 2091                 cnt = (struct meteor_counts *) arg;
 2092                 cnt->fifo_errors = mtr->fifo_errors;
 2093                 cnt->dma_errors = mtr->dma_errors;
 2094                 cnt->frames_captured = mtr->frames_captured;
 2095                 cnt->even_fields_captured = mtr->even_fields_captured;
 2096                 cnt->odd_fields_captured = mtr->odd_fields_captured;
 2097                 break;
 2098         default:
 2099                 printf("meteor%d: ioctl: invalid ioctl request\n", unit);
 2100                 error = ENOTTY;
 2101                 break;
 2102         }
 2103         return(error);
 2104 }
 2105 
 2106 int
 2107 meteor_mmap(dev_t dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
 2108 {
 2109 
 2110         int     unit;
 2111         meteor_reg_t *mtr;
 2112 
 2113         unit = UNIT(minor(dev));
 2114         if (unit >= NMETEOR)            /* at this point could this happen? */
 2115                 return(-1);
 2116 
 2117         mtr = &(meteor[unit]);
 2118 
 2119 
 2120         if(nprot & PROT_EXEC)
 2121                 return -1;
 2122 
 2123         if(offset >= mtr->alloc_pages * PAGE_SIZE)
 2124                 return -1;
 2125 
 2126         *paddr = vtophys(mtr->bigbuf) + offset;
 2127         return 0;
 2128 }
 2129 #endif

Cache object: f36bfdca1dc0534da194dc8124a0ce92


[ 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.