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

Cache object: 6dbc5e86b54a6ac41e1e7ce4b0300882


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