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


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

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

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

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

Cache object: bf228e336085199e5ca5e1d0a0f8c642


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