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