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


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

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

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

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

Cache object: 5e697552769ae8f20a74c3af353a292a


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