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


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

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

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

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

Cache object: 46067fd94463007676dc77a55459fcfc


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