aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan K. Hubbard <jkh@FreeBSD.org>1995-08-28 17:03:18 +0000
committerJordan K. Hubbard <jkh@FreeBSD.org>1995-08-28 17:03:18 +0000
commit1d86961e143aff4d761422bad42b1fe732138e26 (patch)
treea1bc89292563a9defcf366e4f6f3b1b4bbb17b26
parent79f04fe6030bb098e743b16542fab802f7361ffa (diff)
Notes
-rw-r--r--sys/conf/NOTES13
-rw-r--r--sys/dev/bktr/ioctl_meteor.h138
-rw-r--r--sys/i386/conf/LINT13
-rw-r--r--sys/i386/conf/NOTES13
-rw-r--r--sys/i386/include/ioctl_meteor.h138
-rw-r--r--sys/pci/meteor.c1242
-rw-r--r--sys/sys/ioctl_meteor.h138
7 files changed, 1692 insertions, 3 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 9ec301b8dbd0..0b49e7ddeae9 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.195 1995/08/20 15:52:10 ats Exp $
+# $Id: LINT,v 1.196 1995/08/27 14:13:04 joerg Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -662,6 +662,7 @@ device pca0 at isa? port IO_TIMER1 tty
# ctx: Cortex-I frame grabber
# apm: Laptop Advanced Power Management (experimental)
# spigot: The Creative Labs Video Spigot video-aquisition board
+# meteor: Matrox Meteor video capture board
# cy: Cyclades high-speed serial driver (ALPHA QUALITY!)
# gp: National Instruments AT-GPIB and AT-GPIB/TNT board
# gsc: Genius GS-4500 hand scanner.
@@ -727,10 +728,20 @@ device si0 at isa? iomem 0xd0000 tty irq 12 vector siintr
# The PROBE_VERBOSE option enables a long listing of chip set registers
# for supported PCI chip sets (currently only intel Saturn and Mercury).
#
+# The 'meteor' device is a PCI video capture board. It can also have the
+# following options:
+# options "METEOR_ALLOC_PAGES=xxx" preallocate kernel pages for data entry
+# figure (ROWS*COLUMN*BYTES_PER_PIXEL*FRAME+PAGE_SIZE-1)/PAGE_SIZE
+# options METEOR_DEALLOC_PAGES remove all allocated pages on close(2)
+# options "METEOR_DEALLOC_ABOVE=xxx" remove all allocated pages above the
+# specified amount. If this value is below the allocated amount no action
+# taken
+#
controller pci0
device ncr0
device de0
device fpa0
+device meteor0
options PROBE_VERBOSE
#
diff --git a/sys/dev/bktr/ioctl_meteor.h b/sys/dev/bktr/ioctl_meteor.h
new file mode 100644
index 000000000000..e1fed36e5985
--- /dev/null
+++ b/sys/dev/bktr/ioctl_meteor.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1995 Mark Tinguely and Jim Lowe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Tinguely and Jim Lowe
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * ioctl constants for Matrox Meteor Capture card.
+ */
+
+#ifndef _MACHINE_IOCTL_METEOR_H
+#define _MACHINE_IOCTL_METEOR_H
+
+#include <sys/ioctl.h>
+
+struct meteor_capframe {
+ short command; /* see below for valid METEORCAPFRM commands */
+ short signal; /* signal to send to the user program,
+ when a buffer is full */
+ short lowat; /* start transfer if < this number */
+ short hiwat; /* stop transfer if > this number */
+} ;
+
+/* structure for METEOR[GS]ETGEO - get/set geometry */
+struct meteor_geomet {
+ u_short rows;
+ u_short columns;
+ u_short frames;
+ u_long oformat;
+} ;
+
+/* structure for METEORGCOUNT-get count of frames, fifo errors and dma errors */
+struct meteor_counts {
+ u_long fifo_errors; /* count of fifo errors since open */
+ u_long dma_errors; /* count of dma errors since open */
+ u_long frames_captured; /* count of frames captured since open */
+} ;
+
+#define METEORCAPTUR _IOW('x', 1, int) /* capture a frame */
+#define METEORCAPFRM _IOW('x', 2, struct meteor_capframe) /* sync capture */
+#define METEORSETGEO _IOW('x', 3, struct meteor_geomet) /* set geometry */
+#define METEORGETGEO _IOR('x', 4, struct meteor_geomet) /* get geometry */
+#define METEORSTATUS _IOR('x', 5, unsigned short) /* get status */
+#define METEORSHUE _IOW('x', 6, signed char) /* set hue */
+#define METEORGHUE _IOR('x', 6, signed char) /* get hue */
+#define METEORSFMT _IOW('x', 7, unsigned long) /* set format */
+#define METEORGFMT _IOR('x', 7, unsigned long) /* get format */
+#define METEORSINPUT _IOW('x', 8, unsigned long) /* set input dev */
+#define METEORGINPUT _IOR('x', 8, unsigned long) /* get input dev */
+#define METEORSCHCV _IOW('x', 9, unsigned char) /* set uv gain */
+#define METEORGCHCV _IOR('x', 9, unsigned char) /* get uv gain */
+#define METEORSCOUNT _IOW('x',10, struct meteor_counts)
+#define METEORGCOUNT _IOR('x',10, struct meteor_counts)
+
+#define METEOR_STATUS_ID_MASK 0xf000 /* ID of 7196 */
+#define METEOR_STATUS_DIR 0x0800 /* Direction of Expansion port YUV */
+#define METEOR_STATUS_OEF 0x0200 /* Field detected: Even/Odd */
+#define METEOR_STATUS_SVP 0x0100 /* State of VRAM Port:inactive/active */
+#define METEOR_STATUS_STTC 0x0080 /* Time Constant: TV/VCR */
+#define METEOR_STATUS_HCLK 0x0040 /* Horiz PLL: locked/unlocked */
+#define METEOR_STATUS_FIDT 0x0020 /* Field detect: 50/60hz */
+#define METEOR_STATUS_ALTD 0x0002 /* Line alt: no line alt/line alt */
+#define METEOR_STATUS_CODE 0x0001 /* Colour info: no colour/colour */
+
+ /* METEORCAPTUR capture options */
+#define METEOR_CAP_SINGLE 0x0001 /* capture one frame */
+#define METEOR_CAP_CONTINOUS 0x0002 /* contiuously capture */
+#define METEOR_CAP_STOP_CONT 0x0004 /* stop the continous capture */
+
+ /* METEORCAPFRM capture commands */
+#define METEOR_CAP_N_FRAMES 0x0001 /* capture N frames */
+#define METEOR_CAP_STOP_FRAMES 0x0002 /* stop capture N frames */
+
+ /* valid video input formats: */
+#define METEOR_FMT_NTSC 0x00100 /* NTSC -- initialized default */
+#define METEOR_FMT_PAL 0x00200 /* PAL */
+#define METEOR_FMT_SECAM 0x00400 /* SECAM */
+#define METEOR_FMT_AUTOMODE 0x00800 /* auto-mode */
+#define METEOR_INPUT_DEV0 0x01000 /* camera input 0 -- default */
+#define METEOR_INPUT_DEV_RCA METEOR_GEO_DEV0
+#define METEOR_INPUT_DEV1 0x02000 /* camera input 1 */
+#define METEOR_INPUT_DEV2 0x04000 /* camera input 2 */
+#define METEOR_INPUT_DEV3 0x08000 /* camera input 3 */
+#define METEOR_INPUT_DEV_SVIDEO METEOR_GEO_DEV3
+
+ /* valid video output formats: */
+#define METEOR_GEO_RGB16 0x10000 /* packed -- initialized default */
+#define METEOR_GEO_RGB24 0x20000 /* RBG 24 bits packed */
+ /* internally stored in 32 bits */
+#define METEOR_GEO_YUV_PACKED 0x40000 /* 4-2-2 YUV 16 bits packed */
+#define METEOR_GEO_YUV_PLANER 0x80000 /* 4-2-2 YUV 16 bits planer */
+
+ /* following structure is used to coordinate the syncronous */
+
+struct meteor_mem {
+ /* kernel write only */
+ int frame_size; /* row*columns*depth */
+ unsigned num_bufs; /* number of frames in buffer (1-32) */
+ /* user and kernel change these */
+ int signal; /* signal raised to the user program,
+ on completion of frame capture */
+ int lowat; /* kernel starts capture if < this number */
+ int hiwat; /* kernel stops capture if > this number.
+ hiwat <= numbufs */
+ unsigned active; /* bit mask of active frame buffers
+ kernel sets, user clears */
+ int num_active_bufs; /* count of active frame buffer
+ kernel increments, user decrements */
+
+ /* reference to mmapped data */
+ caddr_t buf; /* The real space (virtual addr) */
+} ;
+
+#endif /* ifndef _MACHINE_IOCTL_METEOR_H */
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 9ec301b8dbd0..0b49e7ddeae9 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.195 1995/08/20 15:52:10 ats Exp $
+# $Id: LINT,v 1.196 1995/08/27 14:13:04 joerg Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -662,6 +662,7 @@ device pca0 at isa? port IO_TIMER1 tty
# ctx: Cortex-I frame grabber
# apm: Laptop Advanced Power Management (experimental)
# spigot: The Creative Labs Video Spigot video-aquisition board
+# meteor: Matrox Meteor video capture board
# cy: Cyclades high-speed serial driver (ALPHA QUALITY!)
# gp: National Instruments AT-GPIB and AT-GPIB/TNT board
# gsc: Genius GS-4500 hand scanner.
@@ -727,10 +728,20 @@ device si0 at isa? iomem 0xd0000 tty irq 12 vector siintr
# The PROBE_VERBOSE option enables a long listing of chip set registers
# for supported PCI chip sets (currently only intel Saturn and Mercury).
#
+# The 'meteor' device is a PCI video capture board. It can also have the
+# following options:
+# options "METEOR_ALLOC_PAGES=xxx" preallocate kernel pages for data entry
+# figure (ROWS*COLUMN*BYTES_PER_PIXEL*FRAME+PAGE_SIZE-1)/PAGE_SIZE
+# options METEOR_DEALLOC_PAGES remove all allocated pages on close(2)
+# options "METEOR_DEALLOC_ABOVE=xxx" remove all allocated pages above the
+# specified amount. If this value is below the allocated amount no action
+# taken
+#
controller pci0
device ncr0
device de0
device fpa0
+device meteor0
options PROBE_VERBOSE
#
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 9ec301b8dbd0..0b49e7ddeae9 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.195 1995/08/20 15:52:10 ats Exp $
+# $Id: LINT,v 1.196 1995/08/27 14:13:04 joerg Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -662,6 +662,7 @@ device pca0 at isa? port IO_TIMER1 tty
# ctx: Cortex-I frame grabber
# apm: Laptop Advanced Power Management (experimental)
# spigot: The Creative Labs Video Spigot video-aquisition board
+# meteor: Matrox Meteor video capture board
# cy: Cyclades high-speed serial driver (ALPHA QUALITY!)
# gp: National Instruments AT-GPIB and AT-GPIB/TNT board
# gsc: Genius GS-4500 hand scanner.
@@ -727,10 +728,20 @@ device si0 at isa? iomem 0xd0000 tty irq 12 vector siintr
# The PROBE_VERBOSE option enables a long listing of chip set registers
# for supported PCI chip sets (currently only intel Saturn and Mercury).
#
+# The 'meteor' device is a PCI video capture board. It can also have the
+# following options:
+# options "METEOR_ALLOC_PAGES=xxx" preallocate kernel pages for data entry
+# figure (ROWS*COLUMN*BYTES_PER_PIXEL*FRAME+PAGE_SIZE-1)/PAGE_SIZE
+# options METEOR_DEALLOC_PAGES remove all allocated pages on close(2)
+# options "METEOR_DEALLOC_ABOVE=xxx" remove all allocated pages above the
+# specified amount. If this value is below the allocated amount no action
+# taken
+#
controller pci0
device ncr0
device de0
device fpa0
+device meteor0
options PROBE_VERBOSE
#
diff --git a/sys/i386/include/ioctl_meteor.h b/sys/i386/include/ioctl_meteor.h
new file mode 100644
index 000000000000..e1fed36e5985
--- /dev/null
+++ b/sys/i386/include/ioctl_meteor.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1995 Mark Tinguely and Jim Lowe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Tinguely and Jim Lowe
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * ioctl constants for Matrox Meteor Capture card.
+ */
+
+#ifndef _MACHINE_IOCTL_METEOR_H
+#define _MACHINE_IOCTL_METEOR_H
+
+#include <sys/ioctl.h>
+
+struct meteor_capframe {
+ short command; /* see below for valid METEORCAPFRM commands */
+ short signal; /* signal to send to the user program,
+ when a buffer is full */
+ short lowat; /* start transfer if < this number */
+ short hiwat; /* stop transfer if > this number */
+} ;
+
+/* structure for METEOR[GS]ETGEO - get/set geometry */
+struct meteor_geomet {
+ u_short rows;
+ u_short columns;
+ u_short frames;
+ u_long oformat;
+} ;
+
+/* structure for METEORGCOUNT-get count of frames, fifo errors and dma errors */
+struct meteor_counts {
+ u_long fifo_errors; /* count of fifo errors since open */
+ u_long dma_errors; /* count of dma errors since open */
+ u_long frames_captured; /* count of frames captured since open */
+} ;
+
+#define METEORCAPTUR _IOW('x', 1, int) /* capture a frame */
+#define METEORCAPFRM _IOW('x', 2, struct meteor_capframe) /* sync capture */
+#define METEORSETGEO _IOW('x', 3, struct meteor_geomet) /* set geometry */
+#define METEORGETGEO _IOR('x', 4, struct meteor_geomet) /* get geometry */
+#define METEORSTATUS _IOR('x', 5, unsigned short) /* get status */
+#define METEORSHUE _IOW('x', 6, signed char) /* set hue */
+#define METEORGHUE _IOR('x', 6, signed char) /* get hue */
+#define METEORSFMT _IOW('x', 7, unsigned long) /* set format */
+#define METEORGFMT _IOR('x', 7, unsigned long) /* get format */
+#define METEORSINPUT _IOW('x', 8, unsigned long) /* set input dev */
+#define METEORGINPUT _IOR('x', 8, unsigned long) /* get input dev */
+#define METEORSCHCV _IOW('x', 9, unsigned char) /* set uv gain */
+#define METEORGCHCV _IOR('x', 9, unsigned char) /* get uv gain */
+#define METEORSCOUNT _IOW('x',10, struct meteor_counts)
+#define METEORGCOUNT _IOR('x',10, struct meteor_counts)
+
+#define METEOR_STATUS_ID_MASK 0xf000 /* ID of 7196 */
+#define METEOR_STATUS_DIR 0x0800 /* Direction of Expansion port YUV */
+#define METEOR_STATUS_OEF 0x0200 /* Field detected: Even/Odd */
+#define METEOR_STATUS_SVP 0x0100 /* State of VRAM Port:inactive/active */
+#define METEOR_STATUS_STTC 0x0080 /* Time Constant: TV/VCR */
+#define METEOR_STATUS_HCLK 0x0040 /* Horiz PLL: locked/unlocked */
+#define METEOR_STATUS_FIDT 0x0020 /* Field detect: 50/60hz */
+#define METEOR_STATUS_ALTD 0x0002 /* Line alt: no line alt/line alt */
+#define METEOR_STATUS_CODE 0x0001 /* Colour info: no colour/colour */
+
+ /* METEORCAPTUR capture options */
+#define METEOR_CAP_SINGLE 0x0001 /* capture one frame */
+#define METEOR_CAP_CONTINOUS 0x0002 /* contiuously capture */
+#define METEOR_CAP_STOP_CONT 0x0004 /* stop the continous capture */
+
+ /* METEORCAPFRM capture commands */
+#define METEOR_CAP_N_FRAMES 0x0001 /* capture N frames */
+#define METEOR_CAP_STOP_FRAMES 0x0002 /* stop capture N frames */
+
+ /* valid video input formats: */
+#define METEOR_FMT_NTSC 0x00100 /* NTSC -- initialized default */
+#define METEOR_FMT_PAL 0x00200 /* PAL */
+#define METEOR_FMT_SECAM 0x00400 /* SECAM */
+#define METEOR_FMT_AUTOMODE 0x00800 /* auto-mode */
+#define METEOR_INPUT_DEV0 0x01000 /* camera input 0 -- default */
+#define METEOR_INPUT_DEV_RCA METEOR_GEO_DEV0
+#define METEOR_INPUT_DEV1 0x02000 /* camera input 1 */
+#define METEOR_INPUT_DEV2 0x04000 /* camera input 2 */
+#define METEOR_INPUT_DEV3 0x08000 /* camera input 3 */
+#define METEOR_INPUT_DEV_SVIDEO METEOR_GEO_DEV3
+
+ /* valid video output formats: */
+#define METEOR_GEO_RGB16 0x10000 /* packed -- initialized default */
+#define METEOR_GEO_RGB24 0x20000 /* RBG 24 bits packed */
+ /* internally stored in 32 bits */
+#define METEOR_GEO_YUV_PACKED 0x40000 /* 4-2-2 YUV 16 bits packed */
+#define METEOR_GEO_YUV_PLANER 0x80000 /* 4-2-2 YUV 16 bits planer */
+
+ /* following structure is used to coordinate the syncronous */
+
+struct meteor_mem {
+ /* kernel write only */
+ int frame_size; /* row*columns*depth */
+ unsigned num_bufs; /* number of frames in buffer (1-32) */
+ /* user and kernel change these */
+ int signal; /* signal raised to the user program,
+ on completion of frame capture */
+ int lowat; /* kernel starts capture if < this number */
+ int hiwat; /* kernel stops capture if > this number.
+ hiwat <= numbufs */
+ unsigned active; /* bit mask of active frame buffers
+ kernel sets, user clears */
+ int num_active_bufs; /* count of active frame buffer
+ kernel increments, user decrements */
+
+ /* reference to mmapped data */
+ caddr_t buf; /* The real space (virtual addr) */
+} ;
+
+#endif /* ifndef _MACHINE_IOCTL_METEOR_H */
diff --git a/sys/pci/meteor.c b/sys/pci/meteor.c
new file mode 100644
index 000000000000..afaa1f150380
--- /dev/null
+++ b/sys/pci/meteor.c
@@ -0,0 +1,1242 @@
+/*
+ * Copyright (c) 1995 Mark Tinguely and Jim Lowe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Tinguely and Jim Lowe
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Change History:
+ 8/21/95 Release
+ 8/23/95 On advice from Stefan Esser, added volatile to PCI
+ memory pointers to remove PCI caching .
+*/
+
+#include "meteor.h"
+
+#if NMETEOR > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/devconf.h>
+#include <sys/mman.h>
+#include <machine/clock.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_param.h>
+
+#include <pci.h>
+#if NPCI > 0
+#include <pci/pcivar.h>
+#endif
+#include <machine/ioctl_meteor.h>
+
+ /* enough memory for 640x48 RGB16, or YUV (16 storage bits/pixel) or
+ 450x340 RGB24 (32 storage bits/pixel)
+ options "METEOR_ALLOC_PAGES="
+ */
+#ifndef METEOR_ALLOC_PAGES
+#define METEOR_ALLOC_PAGES 151
+#endif
+#define METEOR_ALLOC (METEOR_ALLOC_PAGES * PAGE_SIZE)
+
+#define NUM_SAA7116_PCI_REGS 37
+#define NUM_SAA7196_I2C_REGS 49
+
+typedef struct {
+ vm_offset_t virt_baseaddr; /* saa7116 register virtual address */
+ vm_offset_t phys_baseaddr; /* saa7116 register physical address */
+ vm_offset_t capt_cntrl; /* capture control register offset 0x40 */
+ vm_offset_t stat_reg; /* status register offset 0x60 */
+ vm_offset_t iic_virt_addr; /* ICC bus register offset 0x64 */
+ pcici_t tag; /* PCI tag, for doing PCI commands */
+ vm_offset_t bigbuf; /* buffer that holds the captured image */
+ int alloc_pages; /* number of pages in bigbuf */
+ struct proc *proc; /* process to receive raised signal */
+ struct meteor_mem *mem; /* used to control sync. multi-frame output */
+ u_long hiwat_cnt; /* mark and count frames lost due to hiwat */
+ short ecurrent; /* even frame number in buffer (1-frames) */
+ short ocurrent; /* odd frame number in buffer (1-frames) */
+ short rows; /* number of rows in a frame */
+ short cols; /* number of columns in a frame */
+ short depth; /* number of byte per pixel */
+ short frames; /* number of frames allocated */
+ int frame_size; /* number of bytes in a frame */
+ u_long fifo_errors; /* number of fifo capture errors since open */
+ u_long dma_errors; /* number of DMA capture errors since open */
+ u_long frames_captured;/* number of frames captured since open */
+ unsigned flags;
+#define METEOR_INITALIZED 0x00000001
+#define METEOR_OPEN 0x00000002
+#define METEOR_MMAP 0x00000004
+#define METEOR_INTR 0x00000008
+#define METEOR_READ 0x00000010
+#define METEOR_SINGLE 0x00000020
+#define METEOR_CONTIN 0x00000040
+#define METEOR_SYNCAP 0x00000080
+#define METEOR_CAP_MASK 0x000000f0
+#define METEOR_NTSC 0x00000100
+#define METEOR_PAL 0x00000200
+#define METEOR_SECAM 0x00000400
+#define METEOR_AUTOMODE 0x00000800
+#define METEOR_FORM_MASK 0x00000f00
+#define METEOR_DEV0 0x00001000
+#define METEOR_DEV1 0x00002000
+#define METEOR_DEV2 0x00004000
+#define METEOR_DEV3 0x00008000
+#define METEOR_DEV_MASK 0x0000f000
+#define METEOR_RGB16 0x00010000
+#define METEOR_RGB24 0x00020000
+#define METEOR_YUV_PACKED 0x00040000
+#define METEOR_YUV_PLANER 0x00080000
+#define METEOR_PRO_MASK 0x000f0000
+#define METEOR_SINGLE_EVEN 0x00100000
+#define METEOR_SINGLE_ODD 0x00200000
+#define METEOR_SINGLE_MASK 0x00300000
+ u_char saa7196_i2c[NUM_SAA7196_I2C_REGS]; /* saa7196 register values */
+} meteor_reg_t;
+
+meteor_reg_t meteor[NMETEOR];
+
+u_long read_intr_wait;
+#define METPRI (PZERO+8)|PCATCH
+
+/*---------------------------------------------------------
+**
+** Meteor PCI probe and initialization routines
+**
+**---------------------------------------------------------
+*/
+
+static char* met_probe (pcici_t tag, pcidi_t type);
+static void met_attach(pcici_t tag, int unit);
+static u_long met_count;
+
+struct pci_device met_device = {
+ "meteor",
+ met_probe,
+ met_attach,
+ &met_count
+};
+
+DATA_SET (pcidevice_set, met_device);
+
+static u_long saa7116_pci_default[NUM_SAA7116_PCI_REGS] = {
+ /* PCI Memory registers */
+ /* BITS Type Description */
+/* 0x00 */ 0x00000000, /* 31:1 e*RW DMA 1 (Even)
+ 0 RO 0x0 */
+/* 0x04 */ 0x00000000, /* 31:2 e*RW DMA 2 (Even)
+ 1:0 RO 0x0 */
+/* 0x08 */ 0x00000000, /* 31:2 e*RW DMA 3 (Even)
+ 1:0 RO 0x0 */
+/* 0x0c */ 0x00000000, /* 31:1 o*RW DMA 1 (Odd)
+ 0 RO 0x0 */
+/* 0x10 */ 0x00000000, /* 31:2 o*RW DMA 2 (Odd)
+ 1:0 RO 0x0 */
+/* 0x14 */ 0x00000000, /* 31:2 o*RW DMA 3 (Odd)
+ 1:0 RO 0x0 */
+/* 0x18 */ 0x00000500, /* 15:2 e*RW Stride 1 (Even)
+ 1:0 RO 0x0 */
+/* 0x1c */ 0x00000000, /* 15:2 e*RW Stride 2 (Even)
+ 1:0 RO 0x0 */
+/* 0x20 */ 0x00000000, /* 15:2 e*RW Stride 3 (Even)
+ 1:0 RO 0x0 */
+/* 0x24 */ 0x00000500, /* 15:2 o*RW Stride 1 (Odd)
+ 1:0 RO 0x0 */
+/* 0x28 */ 0x00000000, /* 15:2 o*RW Stride 2 (Odd)
+ 1:0 RO 0x0 */
+/* 0x2c */ 0x00000000, /* 15:2 o*RW Stride 3 (Odd)
+ 1:0 RO 0x0 */
+/* 0x30 */ 0xeeeeee01, /* 31:8 *RW Route (Even)
+ 7:0 *RW Mode (Even) */
+/* 0x34 */ 0xeeeeee01, /* 31:8 *RW Route (Odd)
+ 7:0 *RW Mode (Odd) */
+/* 0x38 */ 0x00200020, /* 22:16 *RW FIFO Trigger Planer Mode,
+ 6:0 *RW FIFO Trigger Packed Mode */
+/* 0x3c */ 0x00000103, /* 9:8 *RW Reserved (0x0)
+ 2 *RW Field Toggle
+ 1 *RW Reserved (0x1)
+ 0 *RW Reserved (0x1) */
+/* 0x40 */ 0x000000c0, /* 15 *RW Range Enable
+ 14 *RW Corrupt Disable
+ 11 *RR Address Error (Odd)
+ 10 *RR Address Error (Even)
+ 9 *RR Field Corrupt (Odd)
+ 8 *RR Field Corrupt (Even)
+ 7 *RW Fifo Enable
+ 6 *RW VRSTN#
+ 5 *RR Field Done (Odd)
+ 4 *RR Field Done (Even)
+ 3 *RS Single Field Capture (Odd)
+ 2 *RS Single Field Capture (Even)
+ 1 *RW Capture (ODD) Continous
+ 0 *RW Capture (Even) Continous */
+
+/* 0x44 */ 0x00000000, /* 7:0 *RW Retry Wait Counter */
+/* 0x48 */ 0x00000307, /* 10 *RW Interrupt mask, start of field
+ 9 *RW Interrupt mask, end odd field
+ 8 *RW Interrupt mask, end even field
+ 2 *RR Interrupt status, start of field
+ 1 *RR Interrupt status, end of odd
+ 0 *RR Interrupt status, end of even */
+/* 0x4c */ 0x00000001, /* 31:0 *RW Field Mask (Even) continous */
+/* 0x50 */ 0x00000001, /* 31:0 *RW Field Mask (Odd) continous */
+/* 0x54 */ 0x00000000, /* 20:16 *RW Mask Length (Odd)
+ 4:0 *RW Mask Length (Even) */
+/* 0x58 */ 0x0005007c, /* 22:16 *RW FIFO almost empty
+ 6:0 *RW FIFO almost full */
+/* 0x5c */ 0x461e1e0f, /* 31:24 *RW I2C Phase 4
+ 23:16 *RW I2C Phase 3
+ 15:8 *RW I2C Phase 2
+ 7:0 *RW I2C Phase 1 */
+/* 0x60 */ 0x00000300, /* 31:24 *RO I2C Read Data
+ 23:16 **RW I2C Auto Address
+ 11 RO I2C SCL Input
+ 10 RO I2C SDA Input
+ 9 RR I2C Direct Abort
+ 8 RR I2C Auto Abort
+ 3 RW I2C SCL Output
+ 2 RW I2C SDA Output
+ 1 RW I2C Bypass
+ 0 RW I2C Auto Enable */
+/* 0x64 */ 0x00000000, /* 24 RS I2C New Cycle
+ 23:16 **RW I2C Direct Address
+ 15:8 **RW I2C Direct Sub-address
+ 7:0 **RW I2C Direct Write Address */
+/* 0x68 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 1 (Even)
+ 23:16 **RW I2C Auto Data 1 (Even)
+ 15:8 **RW I2C Auto Sub-address 0 (Even)
+ 7:0 **RW I2C Auto Data 0 (Even) */
+/* 0x6c */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 3 (Even)
+ 23:16 **RW I2C Auto Data 3 (Even)
+ 15:8 **RW I2C Auto Sub-address 2 (Even)
+ 7:0 **RW I2C Auto Data 2 (Even) */
+/* 0x70 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 5 (Even)
+ 23:16 **RW I2C Auto Data 5 (Even)
+ 15:8 **RW I2C Auto Sub-address 4 (Even)
+ 7:0 **RW I2C Auto Data 4 (Even) */
+/* 0x74 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 7 (Even)
+ 23:16 **RW I2C Auto Data 7 (Even)
+ 15:8 **RW I2C Auto Sub-address 6 (Even)
+ 7:0 **RW I2C Auto Data 6 (Even) */
+/* 0x78 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 1 (Odd)
+ 23:16 **RW I2C Auto Data 1 (Odd)
+ 15:8 **RW I2C Auto Sub-address 0 (Odd)
+ 7:0 **RW I2C Auto Data 0 (Odd) */
+/* 0x7c */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 3 (Odd)
+ 23:16 **RW I2C Auto Data 3 (Odd)
+ 15:8 **RW I2C Auto Sub-address 2 (Odd)
+ 7:0 **RW I2C Auto Data 2 (Odd) */
+/* 0x80 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 5 (Odd)
+ 23:16 **RW I2C Auto Data 5 (Odd)
+ 15:8 **RW I2C Auto Sub-address 4 (Odd)
+ 7:0 **RW I2C Auto Data 4 (Odd) */
+/* 0x84 */ 0x00000000, /* 31:24 **RW I2C Auto Sub-address 7 (Odd)
+ 23:16 **RW I2C Auto Data 7 (Odd)
+ 15:8 **RW I2C Auto Sub-address 6 (Odd)
+ 7:0 **RW I2C Auto Data 6 (Odd) */
+/* 0x88 */ 0x00000000, /* 23:16 **RW I2C Register Enable (Odd)
+ 7:0 **RW I2C Register Enable (Even) */
+/* 0x8c */ 0x00000000, /* 23:2 e*RW DMA End (Even)
+ 1:0 RO 0x0 */
+/* 0x90 */ 0x00000000 /* 23:2 e*RW DMA End (Odd)
+ 1:0 RO 0x0 */
+};
+
+static u_char saa7196_i2c_default[NUM_SAA7196_I2C_REGS] = {
+ /* SAA7196 I2C bus control */
+ /* BITS Function */
+/* 00 */ 0x50, /* 7:0 Increment Delay */
+/* 01 */ 0x7f, /* 7:0 Horizontal Sync Begin for 50hz */
+/* 02 */ 0x53, /* 7:0 Horizontal Sync Stop for 50hz */
+/* 03 */ 0x43, /* 7:0 Horizontal Sync Clamp Start for 50hz */
+/* 04 */ 0x19, /* 7:0 Horizontal Sync Clamp Stop for 50hz */
+/* 05 */ 0x00, /* 7:0 Horizontal Sync Start after PH1 for 50hz */
+/* 06 */ 0x46, /* 7 Input mode =0 CVBS, =1 S-Video
+ 6 Pre filter
+ 5:4 Aperture Bandpass characteristics
+ 3:2 Coring range for high freq
+ 1:0 Aperture bandpass filter weights */
+/* 07 */ 0x00, /* 7:0 Hue */
+/* 08 */ 0x7f, /* 7:3 Colour-killer threshold QAM (PAL, NTSC) */
+/* 09 */ 0x7f, /* 7:3 Colour-killer threshold SECAM */
+/* 0a */ 0x7f, /* 7:0 PAL switch sensitivity */
+/* 0b */ 0x7f, /* 7:0 SECAM switch sensitivity */
+/* 0c */ 0x40, /* 7 Colour-on bit
+ 6:5 AGC filter */
+/* 0d */ 0x84, /* 7 VTR/TV mode bit = 1->VTR mode
+ 3 Realtime output mode select bit
+ 2 HREF position select
+ 1 Status byte select
+ 0 SECAM mode bit */
+/* 0e */ 0x38, /* 7 Horizontal clock PLL
+ 5 Select interal/external clock source
+ 4 Output enable of Horizontal/Vertical sync
+ 3 Data output YUV enable
+ 2 S-VHS bit
+ 1 GPSW2
+ 0 GPSW1 */
+/* 0f */ 0x50, /* 7 Automatic Field detection
+ 6 Field Select 0 = 50hz, 1=60hz
+ 5 SECAM cross-colour reduction
+ 4 Enable sync and clamping pulse
+ 3:1 Luminance delay compensation */
+/* 10 */ 0x00, /* 2 Select HREF Position
+ 1:0 Vertical noise reduction */
+/* 11 */ 0x2c, /* 7:0 Chrominance gain conrtol for QAM */
+/* 12 */ 0x40, /* 7:0 Chrominance saturation control for VRAM port */
+/* 13 */ 0x40, /* 7:0 Luminance contract control for VRAM port */
+/* 14 */ 0x34, /* 7:0 Horizontal sync begin for 60hz */
+/* 15 */ 0x0c, /* 7:0 Horizontal sync stop for 60hz */
+/* 16 */ 0xfb, /* 7:0 Horizontal clamp begin for 60hz */
+/* 17 */ 0xd4, /* 7:0 Horizontal clamp stop for 60hz */
+/* 18 */ 0xec, /* 7:0 Horizontal sync start after PH1 for 60hz */
+/* 19 */ 0x80, /* 7:0 Luminance brightness control for VRAM port */
+/* 1a */ 0x00,
+/* 1b */ 0x00,
+/* 1c */ 0x00,
+/* 1d */ 0x00,
+/* 1e */ 0x00,
+/* 1f */ 0x00,
+/* 20 */ 0x90, /* 7 ROM table bypass switch
+ 6:5 Set output field mode
+ 4 VRAM port outputs enable
+ 3:2 First pixel position in VRO data
+ 1:0 FIFO output register select */
+/* 21 */ 0x80, /* 7:0 [7:0] Pixel number per line on output */
+/* 22 */ 0x80, /* 7:0 [7:0] Pixel number per line on input */
+/* 23 */ 0x03, /* 7:0 [7:0] Horizontal start position of scaling win*/
+/* 24 */ 0x8a, /* 7:5 Horizontal decimation filter
+ 4 [8] Horizontal start position of scaling win
+ 3:2 [9:8] Pixel number per line on input
+ 1:0 [9:8] Pixel number per line on output */
+/* 25 */ 0xf0, /* 7:0 [7:0] Line number per output field */
+/* 26 */ 0xf0, /* 7:0 [7:0] Line number per input field */
+/* 27 */ 0x0f, /* 7:0 [7:0] Vertical start of scaling window */
+/* 28 */ 0x80, /* 7 Adaptive filter switch
+ 6:5 Vertical luminance data processing
+ 4 [8] Vertical start of scaling window
+ 3:2 [9:8] Line number per input field
+ 1:0 [9:8] Line number per output field */
+/* 29 */ 0x16, /* 7:0 [7:0] Vertical bypass start */
+/* 2a */ 0x00, /* 7:0 [7:0] Vertical bypass count */
+/* 2b */ 0x00, /* 4 [8] Vertical bypass start
+ 2 [8] Vertical bypass count
+ 0 Polarity, internally detected odd even flag */
+/* 2c */ 0x80, /* 7:0 Set lower limit V for colour-keying */
+/* 2d */ 0x7f, /* 7:0 Set upper limit V for colour-keying */
+/* 2e */ 0x80, /* 7:0 Set lower limit U for colour-keying */
+/* 2f */ 0x7f, /* 7:0 Set upper limit U for colour-keying */
+/* 30 */ 0xbf /* 7 VRAM bus output format
+ 6 Adaptive geometrical filter
+ 5 Luminance limiting value
+ 4 Monochrome and two's complement output data sel
+ 3 Line quailifier flag
+ 2 Pixel qualifier flag
+ 1 Transparent data transfer
+ 0 Extended formats enable bit */
+};
+
+/*
+ * i2c_write:
+ * Returns 0 Succesful completion.
+ * Returns 1 If transfer aborted or timeout occured.
+ *
+ */
+#define SAA7196_I2C_ADDR 0x40
+#define I2C_WRITE 0x00
+#define I2C_READ 0x01
+#define SAA7116_IIC_NEW_CYCLE 0x1000000L
+#define IIC_DIRECT_TRANSFER_ABORTED 0x0000200L
+
+#define SAA7196_WRITE(mtr, reg, data) \
+ i2c_write(mtr, SAA7196_I2C_ADDR, I2C_WRITE, reg, data); \
+ mtr->saa7196_i2c[reg] = data
+#define SAA7196_REG(mtr, reg) mtr->saa7196_i2c[reg]
+#define SAA7196_READ(mtr) \
+ i2c_write(mtr, SAA7196_I2C_ADDR, I2C_READ, 0x0, 0x0)
+
+static int
+i2c_write(meteor_reg_t * mtr, u_char slave, u_char rw, u_char reg, u_char data)
+{
+register unsigned long wait_counter = 0x0001ffff;
+register volatile u_long *iic_write_loc = (volatile u_long *)mtr->iic_virt_addr;
+register int err = 0;
+
+ /* Write the data the the i2c write register */
+ *iic_write_loc = SAA7116_IIC_NEW_CYCLE |
+ (((u_long)slave|(u_long)rw) << 16) |
+ ((u_long)reg << 8) | (u_long)data;
+
+ /* Wait until the i2c cycle is compeleted */
+ while((*iic_write_loc & SAA7116_IIC_NEW_CYCLE)) {
+ if(!wait_counter) break;
+ wait_counter--;
+ }
+
+/*#ifdef notdef*/
+ /* it seems the iic_write_loc is cached, until we can
+ figure out how to uncache the pci registers, then we
+ will just ignore the timeout. Hopefully 1ffff will
+ be enough delay time for the i2c cycle to complete */
+ if(!wait_counter) {
+ printf("meteor: saa7116 i2c %s transfer timeout 0x%x",
+ rw ? "read" : "write", *iic_write_loc);
+
+ err=1;
+ }
+/*#endif*/
+
+ /* Check for error on direct write, clear if any */
+ if((*((volatile u_long *)mtr->stat_reg)) & IIC_DIRECT_TRANSFER_ABORTED) {
+ printf("meteor: saa7116 i2c %s tranfer aborted",
+ rw ? "read" : "write" );
+ err= 1;
+ }
+
+ if(err) {
+ printf(" - reg=0x%x, value=0x%x.\n", reg, data);
+ }
+
+ return err;
+}
+
+
+static char*
+met_probe (pcici_t tag, pcidi_t type)
+{
+ switch (type) {
+
+ case 0x12238086ul: /* meteor */
+ return ("Matrox Meteor");
+
+ };
+ return ((char*)0);
+}
+
+ /* interrupt handling routine
+ complete meteor_read() if using interrupts
+ */
+int
+meteor_intr( void *arg)
+{
+ register meteor_reg_t *mtr = (meteor_reg_t *) arg;
+
+ register volatile u_long *cap, *base, *status, cap_err;
+ struct meteor_mem *mm;
+
+ base = (volatile u_long *) mtr->virt_baseaddr;
+ cap = (volatile u_long *) mtr->capt_cntrl; /* capture control ptr */
+ status = base + 18; /* mtr->virt_base + 0x48 save a dereference */
+
+ /* the even field has to make the decision of whether the high water
+ has been reached. If hiwat has been reach do not advance the buffer.
+ continue to save frames on this buffer until we can advance again */
+ if (*status & 0x1) { /* even field */
+ if (mtr->flags & METEOR_SYNCAP) {
+ mm = mtr->mem; /* shared SYNCAP struct */
+ if ((!mtr->hiwat_cnt && mm->num_active_bufs < mm->hiwat) ||
+ (mm->num_active_bufs <= mm->lowat)) {
+ mtr->hiwat_cnt = 0;
+ if (++mtr->ecurrent > mtr->frames) {
+ *base = mtr->bigbuf;
+ mtr->ecurrent = 1;
+ } else {
+ *base = *base + mtr->frame_size;
+ }
+ }
+ else {
+ mtr->hiwat_cnt++;
+ }
+ } else if(mtr->flags & METEOR_SINGLE) {
+ *cap &= 0x0ffe;
+ mtr->flags &= ~METEOR_SINGLE_EVEN;
+ if(!(mtr->flags & METEOR_SINGLE_MASK)) {
+ mtr->frames_captured++ ;
+ wakeup((caddr_t) &read_intr_wait);
+ }
+ }
+ } else { /* odd field */
+ if (mtr->flags & METEOR_SINGLE) {
+ *cap &= 0x0ffd;
+ mtr->flags &= ~ METEOR_SINGLE_ODD;
+ if(!(mtr->flags & METEOR_SINGLE_MASK)) {
+ mtr->frames_captured++ ;
+ wakeup((caddr_t) &read_intr_wait);
+ }
+ } else if (mtr->flags & METEOR_SYNCAP) {
+ mm = mtr->mem; /* shared SYNCAP struct */
+ /* even field decided to advance or not, we
+ simply add stride to that decision */
+ *(base+3) = *base + *(base + 6);
+ if (mtr->ecurrent != mtr->ocurrent) {
+ mm->active |= (1 << (mtr->ocurrent-1));
+ mtr->ocurrent = mtr->ecurrent;
+ mm->num_active_bufs++;
+ if (mtr->proc && mm->signal) {
+ mtr->frames_captured++ ;
+ psignal(mtr->proc, mm->signal);
+ }
+ }
+ }
+ }
+ if (cap_err = (*cap & 0xf00)) {
+ if (cap_err & 0x3)
+ mtr->fifo_errors++ ; /* incrememnt fifo capture errors cnt */
+ if (cap_err & 0xc)
+ mtr->dma_errors++ ; /* increment DMA capture errors cnt */
+ }
+
+ *cap |= 0xf30; /* clear error and field done */
+ *status |= 0xf; /* clear interrupt status */
+
+ return(1);
+}
+
+/*
+ * Initialize the capture card to NTSC RGB 16 640x480
+ */
+static void
+meteor_init ( meteor_reg_t *mtr )
+{
+ volatile u_long *vbase_addr;
+ int i;
+
+ *((volatile u_long *)(mtr->capt_cntrl)) = 0x00000040L;
+
+ vbase_addr = (volatile u_long *) mtr->virt_baseaddr;
+ for (i= 0 ; i < NUM_SAA7116_PCI_REGS; i++)
+ *vbase_addr++ = saa7116_pci_default[i];
+
+ for (i = 0; i < NUM_SAA7196_I2C_REGS; i++) {
+ SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);
+ }
+
+}
+
+static void met_attach(pcici_t tag, int unit)
+{
+#ifdef METEOR_IRQ /* from the meteor.h file */
+ u_long old_irq,new_irq;
+
+#endif METEOR_IRQ /* from the meteor.h file */
+ meteor_reg_t *mtr;
+ vm_offset_t buf;
+
+ if (unit > NMETEOR) {
+ printf("meteor_attach: mx%d: invalid unit number\n");
+ return ;
+ }
+
+ mtr = &meteor[unit];
+ pci_map_mem(tag, 0x10, &(mtr->virt_baseaddr),
+ &(mtr->phys_baseaddr));
+ /* IIC addres at 0x64 offset bytes */
+ mtr->capt_cntrl = mtr->virt_baseaddr + 0x40;
+ mtr->stat_reg = mtr->virt_baseaddr + 0x60;
+ mtr->iic_virt_addr = mtr->virt_baseaddr + 0x64;
+
+#ifdef METEOR_IRQ /* from the meteor.h file */
+ old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
+ pci_conf_write(tag, PCI_INTERRUPT_REG, METEOR_IRQ);
+ new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
+ printf("meteor_attach: irq changed from %d to %d\n", (old_irq & 0xff),
+ (new_irq & 0xff));
+#endif METEOR_IRQ
+
+ meteor_init( mtr ); /* set up saa7116 and saa7196 chips */
+ mtr->tag = tag;
+ /* setup the interrupt handling routine */
+ pci_map_int (tag, meteor_intr, (void*) mtr, &net_imask);
+
+ /* 640*240*3 round up to nearest pag e*/
+ buf = vm_page_alloc_contig(METEOR_ALLOC, 0x100000, 0xffffffff, PAGE_SIZE);
+ if (buf == NULL) {
+ printf("meteor_attach: big buffer allocation failed\n");
+ return;
+ }
+ mtr->bigbuf = buf;
+ mtr->alloc_pages = METEOR_ALLOC_PAGES;
+
+ bzero((caddr_t) buf, METEOR_ALLOC);
+
+ buf = vtophys(buf);
+ *((volatile u_long *) mtr->virt_baseaddr) = buf;
+
+ /* 640x480 RGB 16 */
+ *((volatile u_long *) mtr->virt_baseaddr + 3) = buf + 0x500;
+
+ *((volatile u_long *) mtr->virt_baseaddr + 36) =
+ *((volatile u_long *) mtr->virt_baseaddr + 35) = buf + METEOR_ALLOC;
+ mtr->flags = METEOR_INITALIZED | METEOR_NTSC | METEOR_DEV0 |
+ METEOR_RGB16;
+ /* 1 frame of 640x480 RGB 16 */
+ mtr->cols = 640;
+ mtr->rows = 480;
+ mtr->depth = 2; /* two bytes per pixel */
+ mtr->frames = 1; /* one frame */
+}
+
+static void
+meteor_reset(meteor_reg_t * const sc)
+{
+
+}
+
+/*---------------------------------------------------------
+**
+** Meteor character device driver routines
+**
+**---------------------------------------------------------
+*/
+
+#define UNIT(x) ((x) & 0x07)
+
+int
+meteor_open(dev_t dev, int flag)
+{
+ meteor_reg_t *mtr;
+ int unit;
+ int i;
+
+ unit = UNIT(minor(dev));
+ if (unit > NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+
+ if (!(mtr->flags & METEOR_INITALIZED)) /* device not found */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_OPEN) /* device is busy */
+ return(EBUSY);
+
+ mtr->flags |= METEOR_OPEN;
+ /*
+ * Make sure that the i2c regs are set the same for each open.
+ */
+ for(i=0; i< NUM_SAA7196_I2C_REGS; i++) {
+ SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]);
+ }
+
+ mtr->fifo_errors = 0;
+ mtr->dma_errors = 0;
+ mtr->frames_captured = 0;
+
+ return(0);
+}
+
+int
+meteor_close(dev_t dev, int flag)
+{
+ meteor_reg_t *mtr;
+ int unit;
+ int temp;
+
+ unit = UNIT(minor(dev));
+ if (unit > NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+ mtr->flags &= ~METEOR_OPEN;
+
+ /* XXX stop any capture modes running */
+ switch (mtr->flags & METEOR_CAP_MASK) {
+ case METEOR_SINGLE: /* this should not happen, the read capture
+ should have completed or in the very least
+ recieved a signal before close is called. */
+ mtr->flags &= ~(METEOR_SINGLE|METEOR_SINGLE_MASK);
+ wakeup((caddr_t) &read_intr_wait); /* continue read */
+ break;
+
+ case METEOR_CONTIN: /* continous unsync-ed reading, we can
+ simply turn off the capture */
+ mtr->flags &= ~METEOR_CONTIN;
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff0; /* turn off capture */
+ break;
+ case METEOR_SYNCAP:
+ mtr->flags &= ~METEOR_SYNCAP;
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff0; /* turn off capture */
+ mtr->proc = NULL;
+ mtr->mem = NULL;
+ mtr->ecurrent = mtr->ocurrent = 1;
+ /* re-initalize the even/odd DMA positions to top of buffer */
+ *((volatile u_long *) mtr->virt_baseaddr) = mtr->bigbuf;
+ *((volatile u_long *) mtr->virt_baseaddr +3) =
+ *((volatile u_long *) mtr->virt_baseaddr) +
+ *((volatile u_long *) mtr->virt_baseaddr+6);
+ break;
+ case 0:
+ break;
+ default:
+ printf("meteor_close: bad capture state on close %d\n",
+ mtr->flags & METEOR_CAP_MASK);
+ }
+#ifdef METEOR_DEALLOC_PAGES
+ if (mtr->bigbuf) {
+ kmem_free(kernel_map,mtr->bigbuf,(mtr->alloc_pages*PAGE_SIZE));
+ mtr->bigbuf = NULL;
+ mtr->alloc_pages = 0;
+ }
+#else
+#ifdef METEOR_DEALLOC_ABOVE
+ if (mtr->bigbuf && mtr->alloc_pages > METEOR_DEALLOC_ABOVE) {
+ temp = METEOR_DEALLOC_ABOVE - mtr->alloc_pages;
+ kmem_free(kernel_map,
+ mtr->bigbuf+((mtr->alloc_pages - temp) * PAGE_SIZE),
+ (temp * PAGE_SIZE));
+ mtr->alloc_pages = METEOR_DEALLOC_ABOVE;
+ }
+#endif
+#endif
+ return(0);
+}
+
+int
+meteor_read(dev_t dev, struct uio *uio)
+{
+ meteor_reg_t *mtr;
+ int unit;
+ int status;
+ int count;
+
+ unit = UNIT(minor(dev));
+ if (unit > NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+ if (!mtr->bigbuf) /* no frame buffer allocated (ioctl failed) */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO); /* already capturing */
+
+ count = mtr->rows * mtr->cols * mtr->depth;
+ if (uio->uio_iov->iov_len < count)
+ return(EINVAL);
+
+ mtr->flags |= METEOR_SINGLE | METEOR_SINGLE_MASK;
+
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff3; /* capture */
+
+ status = tsleep((caddr_t) &read_intr_wait, METPRI, "capturing", 0);
+
+ if (!status) /* successful capture */
+ status = uiomove((caddr_t)mtr->bigbuf, count, uio);
+
+ else
+ printf ("meteor_read: bad tsleep\n");
+ mtr->flags &= ~(METEOR_SINGLE | METEOR_SINGLE_MASK);
+ return(status);
+}
+
+int
+meteor_write()
+{
+ return(0);
+}
+
+int
+meteor_ioctl(dev_t dev, int cmd, caddr_t arg, int flag, struct proc *pr)
+{
+ int error;
+ int unit;
+ int temp;
+ meteor_reg_t *mtr;
+ struct meteor_counts *cnt;
+ struct meteor_geomet *geo;
+ struct meteor_mem *mem;
+ struct meteor_capframe *frame;
+ volatile u_long *p;
+ vm_offset_t buf;
+
+ error = 0;
+
+ if (!arg) return(EINVAL);
+ unit = UNIT(minor(dev));
+ if (unit > NMETEOR) /* unit out of range */
+ return(ENXIO);
+
+ mtr = &(meteor[unit]);
+
+ switch (cmd) {
+ case METEORSTATUS: /* get 7196 status */
+ temp = 0;
+ SAA7196_WRITE(mtr, 0x0d, SAA7196_REG(mtr, 0x0d) | 0x02);
+ SAA7196_READ(mtr);
+ temp |= ((*((volatile u_long *)mtr->stat_reg)) & 0xff000000L) >> 24;
+ SAA7196_WRITE(mtr, 0x0d, SAA7196_REG(mtr, 0x0d) & 0x02);
+ SAA7196_READ(mtr);
+ temp |= ((*((volatile u_long *)mtr->stat_reg)) & 0xff000000L) >> 16;
+ *(u_short *)arg = temp;
+ break;
+ case METEORSHUE: /* set hue */
+ SAA7196_WRITE(mtr, 0x07, *(char *)arg);
+ break;
+ case METEORGHUE: /* get hue */
+ *(char *)arg = SAA7196_REG(mtr, 0x07);
+ break;
+ case METEORSCHCV: /* set chrominance gain */
+ SAA7196_WRITE(mtr, 0x11, *(char *)arg);
+ break;
+ case METEORGCHCV: /* get chrominance gain */
+ *(char *)arg = SAA7196_REG(mtr, 0x11);
+ break;
+ case METEORSINPUT: /* set input device */
+ switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
+ case 0: /* default */
+ case METEOR_INPUT_DEV0:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV0;
+
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x0);
+ break;
+ case METEOR_INPUT_DEV1:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV1;
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x1);
+ break;
+ case METEOR_INPUT_DEV2:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV2;
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2);
+ break;
+ case METEOR_INPUT_DEV3:
+ mtr->flags = (mtr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV3;
+ SAA7196_WRITE(mtr, 0x0e,
+ (SAA7196_REG(mtr, 0x0e) | 0x3));
+ break;
+ default:
+ return EINVAL;
+ }
+ break;
+ case METEORGINPUT: /* get input device */
+ *(u_long *)arg = mtr->flags & METEOR_DEV_MASK;
+ break;
+ case METEORSFMT: /* set input format */
+ switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
+ case 0: /* default */
+ case METEOR_FMT_NTSC:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_NTSC;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01));
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xc0) | 0x40);
+ SAA7196_WRITE(mtr, 0x22, 0x80);
+ SAA7196_WRITE(mtr, 0x24,
+ (SAA7196_REG(mtr, 0x24) & ~0x0c) | 0x08);
+ SAA7196_WRITE(mtr, 0x26, 0xf0);
+ SAA7196_WRITE(mtr, 0x28,
+ (SAA7196_REG(mtr, 0x28) & ~0x0c)) ;
+ break;
+ case METEOR_FMT_PAL:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_PAL;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01));
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xc0));
+ SAA7196_WRITE(mtr, 0x22, 0x00);
+ SAA7196_WRITE(mtr, 0x24,
+ (SAA7196_REG(mtr, 0x24) | 0x0c));
+ SAA7196_WRITE(mtr, 0x26, 0x20);
+ SAA7196_WRITE(mtr, 0x28,
+ (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x01) ;
+ break;
+ case METEOR_FMT_SECAM:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_SECAM;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01) | 0x1);
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0xe0);
+ SAA7196_WRITE(mtr, 0x22, 0x00);
+ SAA7196_WRITE(mtr, 0x24,
+ (SAA7196_REG(mtr, 0x24) | 0x0c));
+ SAA7196_WRITE(mtr, 0x26, 0x20);
+ SAA7196_WRITE(mtr, 0x28,
+ (SAA7196_REG(mtr, 0x28) & ~0x0c) | 0x01) ;
+ break;
+ case METEOR_FMT_AUTOMODE:
+ mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) |
+ METEOR_AUTOMODE;
+ SAA7196_WRITE(mtr, 0x0d,
+ (SAA7196_REG(mtr, 0x0d) & ~0x01));
+ SAA7196_WRITE(mtr, 0x0f,
+ (SAA7196_REG(mtr, 0x0f) & ~0xc0) | 0xc0);
+ break;
+ default:
+ return EINVAL;
+ }
+ break;
+ case METEORGFMT: /* get input format */
+ *(u_long *)arg = mtr->flags & METEOR_FORM_MASK;
+ break;
+ case METEORCAPTUR:
+ switch (*(int *) arg) {
+ case METEOR_CAP_SINGLE:
+ if (!mtr->bigbuf) /* no frame buffer allocated */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO); /* already capturing */
+
+ mtr->flags |= METEOR_SINGLE | METEOR_SINGLE_MASK;
+
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff3; /* capture */
+
+ error = tsleep((caddr_t) &read_intr_wait, METPRI,
+ "capturing", 0);
+ mtr->flags &= ~(METEOR_SINGLE| METEOR_SINGLE_MASK);
+ break;
+ case METEOR_CAP_CONTINOUS:
+ if (!mtr->bigbuf) /* no frame buffer allocated */
+ return(ENXIO);
+
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO); /* already capturing */
+
+ mtr->flags |= METEOR_CONTIN;
+
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff3; /* capture */
+ break;
+ case METEOR_CAP_STOP_CONT:
+ if (mtr->flags & METEOR_CONTIN) {
+ mtr->flags &= ~METEOR_CONTIN;
+ /* turn off capture */
+ *((volatile u_long *) mtr->capt_cntrl) = 0x0ff0;
+ }
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ case METEORCAPFRM:
+ frame = (struct meteor_capframe *) arg;
+ if (!frame)
+ return(EINVAL);
+ switch (frame->command) {
+ case METEOR_CAP_N_FRAMES:
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EIO);
+ if (mtr->flags & METEOR_YUV_PLANER)
+ return(EINVAL);
+ if (!mtr->bigbuf)
+ return(ENOMEM);
+ if ((mtr->frames < 2) ||
+ (frame->lowat < 1 || frame->lowat >= mtr->frames) ||
+ (frame->hiwat < 1 || frame->hiwat >= mtr->frames))
+ return(EINVAL);
+ mtr->flags |= METEOR_SYNCAP;
+ mtr->proc = pr;
+ /* meteor_mem structure is on the page after the data */
+ mem = mtr->mem = (struct meteor_mem *) (mtr->bigbuf +
+ ((mtr->rows*mtr->cols * mtr->depth *
+ mtr->frames+PAGE_SIZE-1)/PAGE_SIZE)*PAGE_SIZE);
+ mtr->ecurrent = mtr->ocurrent = 1;
+ mem->signal = frame->signal;
+ mem->num_bufs = mtr->frames;
+ mem->frame_size=
+ mtr->frame_size = mtr->rows * mtr->cols * mtr->depth;
+ /* user and kernel change these */
+ mem->lowat = frame->lowat;
+ mem->hiwat = frame->hiwat;
+ mem->active = 0;
+ mem->num_active_bufs = 0;
+ *((u_long *) mtr->capt_cntrl) = 0x0ff3;
+ break;
+ case METEOR_CAP_STOP_FRAMES:
+ if (mtr->flags & METEOR_SYNCAP) {
+ mtr->flags &= ~METEOR_SYNCAP;
+ /* turn off capture */
+ *((u_long *) mtr->capt_cntrl) = 0x0ff0;
+ mtr->proc = NULL;
+ mtr->mem = NULL;
+ mtr->ecurrent = mtr->ocurrent = 0;
+
+ /* re-initalize the even/odd DMA positions to top of buffer*/
+ /* XXX if a capture is in progress, this may be trouble */
+
+ *((volatile u_long *) mtr->virt_baseaddr) = mtr->bigbuf;
+ *((volatile u_long *) mtr->virt_baseaddr +3) =
+ *((volatile u_long *) mtr->virt_baseaddr) +
+ *((volatile u_long *) mtr->virt_baseaddr+6);
+ }
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+
+ case METEORSETGEO:
+ geo = (struct meteor_geomet *) arg;
+ /* can't change parameters while capturing */
+ if (mtr->flags & METEOR_CAP_MASK)
+ return(EBUSY);
+
+ if ((geo->columns & 0x3fe) != geo->columns) {
+ printf("meteor ioctl: column too large or not even\n");
+ error = EINVAL;
+ }
+ if ((geo->rows & 0x7fe) != geo->rows) {
+ printf("meteor ioctl: rows too large or not even\n");
+ error = EINVAL;
+ }
+ if (geo->frames > 32) {
+ printf("meteor ioctl: frames too large\n");
+ error = EINVAL;
+ }
+ if (!error && (temp=geo->rows*geo->columns * geo->frames *2)) {
+ if (geo->oformat & METEOR_GEO_RGB24)
+ temp = temp * 2;
+
+ /* meteor_mem structure for SYNC Capture */
+ if (geo->frames > 1)
+ temp += PAGE_SIZE;
+
+ temp = (temp + PAGE_SIZE -1)/PAGE_SIZE;
+ if (temp > mtr->alloc_pages) {
+ if (mtr->bigbuf)
+ kmem_free(kernel_map, mtr->bigbuf,
+ (mtr->alloc_pages * PAGE_SIZE));
+ mtr->bigbuf = vm_page_alloc_contig((temp*PAGE_SIZE),
+ 0x100000, 0xffffffff, PAGE_SIZE);
+ mtr->alloc_pages = temp;
+ }
+ if (mtr->bigbuf) {
+ mtr->rows = geo->rows;
+ mtr->cols = geo->columns;
+ mtr->frames = geo->frames;
+ }
+ else {
+ mtr->alloc_pages = 0;
+ printf("meteor_ioctl: buffer allocation failed\n");
+ error = ENOMEM;
+ }
+ }
+
+ p = (volatile u_long *) mtr->virt_baseaddr;
+ if (mtr->bigbuf)
+ buf = vtophys(mtr->bigbuf);
+ else
+ buf = 0;
+ *p++ = buf; /* even y or even RGB */
+ /* set end of buffer location */
+ *(p+36) = *(p+35) = buf + mtr->alloc_pages * PAGE_SIZE;
+
+ switch (geo->oformat & METEOR_PRO_MASK) {
+ case 0: /* default */
+ case METEOR_GEO_RGB16:
+ mtr->depth = 2;
+ if (mtr->flags & METEOR_RGB16 == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB24 |
+ METEOR_YUV_PACKED |
+ METEOR_YUV_PLANER))
+ | METEOR_RGB16;
+ }
+ if (error == 0) {
+ /* recal stride and odd starting point */
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = buf + mtr->cols * 2;
+ *p++ = 0;
+ *p++ = 0;
+ /* stride */
+ *p = *(p+3) = mtr->cols * 2;
+ *(p+6) = *(p+7) = 0xeeeeee01;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x90);
+ }
+ break;
+ case METEOR_GEO_RGB24:
+ mtr->depth = 4;
+ if (mtr->flags & METEOR_RGB24 == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB16 |
+ METEOR_YUV_PACKED |
+ METEOR_YUV_PLANER))
+ | METEOR_RGB24;
+ }
+ if (error == 0 ) {
+ /* recal stride and odd starting point */
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = buf + mtr->cols * 4;
+ /* routes */
+ *p++ = 0;
+ *p++ = 0;
+ /* stride */
+ *p = *(p+3) = mtr->cols * 4;
+ /* routes */
+ *(p+6) = *(p+7) = 0x39393900;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x92);
+ }
+ break;
+ case METEOR_GEO_YUV_PLANER:
+ mtr->depth = 2;
+ if (mtr->flags & METEOR_YUV_PLANER == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB16 |
+ METEOR_RGB24 |
+ METEOR_YUV_PACKED))
+ | METEOR_YUV_PLANER;
+ }
+ if (error == 0 ) {
+ /* recal stride and odd starting point */
+
+ temp = mtr->rows * mtr->cols;
+ /* even u */
+ *p++ = buf + temp;
+ /* even v */
+ *p++ = buf + temp + (temp >> 2);
+ /* odd y */
+ *p++ = buf + mtr->cols;
+ /* odd u */
+ *p++ = buf + temp + (temp >> 1);
+ /* odd v */
+ *p++ = buf + temp + (temp >> 1)
+ + (temp >> 2);
+ /* stride */
+ *p = *(p+3) = mtr->cols;
+ /* routes */
+ *(p+6) = *(p+7) = 0xaaaaffc1;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x91);
+ }
+ break;
+ case METEOR_GEO_YUV_PACKED:
+ mtr->depth = 2;
+ if (mtr->flags & METEOR_YUV_PACKED == 0) {
+ mtr->flags = (mtr->flags & ~(METEOR_RGB16 |
+ METEOR_RGB24 |
+ METEOR_YUV_PLANER))
+ | METEOR_YUV_PACKED;
+ }
+ if (error == 0 ) {
+ /* recal stride and odd starting point */
+
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = buf + mtr->cols * 2;
+ *p++ = 0;
+ *p++ = 0;
+ /* stride */
+ *p = *(p+3) = mtr->cols * 2;
+ /* routes */
+ *(p+6) = *(p+7) = 0xeeeeee41;
+ /* set up the saa7196 */
+ SAA7196_WRITE(mtr, 0x20, 0x91);
+ }
+ break;
+ default:
+ error = EINVAL; /* invalid arguement */
+ printf("meteor_ioctl: invalid output format\n");
+ break;
+ }
+ if (error == 0 ) {
+ /* set cols */
+ SAA7196_WRITE(mtr, 0x21, mtr->cols & 0xff);
+ SAA7196_WRITE(mtr, 0x24,
+ ((SAA7196_REG(mtr, 0x24) & ~0x03) |
+ ((mtr->cols >> 8) & 0x03)));
+ /* set rows */
+ SAA7196_WRITE(mtr, 0x25, ((mtr->rows >> 1) & 0xff));
+ SAA7196_WRITE(mtr, 0x28,
+ ((SAA7196_REG(mtr, 0x28) & ~0x03) |
+ ((mtr->rows >> 9) & 0x03)));
+ }
+ break;
+ case METEORGETGEO:
+ geo = (struct meteor_geomet *) arg;
+ geo->rows = mtr->rows;
+ geo->columns = mtr->cols;
+ geo->frames = mtr->frames;
+ geo->oformat = mtr->flags & METEOR_PRO_MASK;
+ break;
+ case METEORSCOUNT: /* (re)set error counts */
+ cnt = (struct meteor_counts *) arg;
+ mtr->fifo_errors = cnt->fifo_errors;
+ mtr->dma_errors = cnt->dma_errors;
+ mtr->frames_captured = cnt->frames_captured;
+ break;
+ case METEORGCOUNT: /* get error counts */
+ cnt = (struct meteor_counts *) arg;
+ cnt->fifo_errors = mtr->fifo_errors;
+ cnt->dma_errors = mtr->dma_errors;
+ cnt->frames_captured = mtr->frames_captured;
+ break;
+ default:
+ printf("meteor_ioctl: invalid ioctl request\n");
+ error = ENOTTY;
+ break;
+ }
+ return(error);
+}
+
+int
+meteor_mmap(dev_t dev, int offset, int nprot)
+{
+
+ int unit;
+ meteor_reg_t *mtr;
+
+ unit = UNIT(minor(dev));
+ if (unit > NMETEOR) /* at this point could this happen? */
+ return(0);
+
+ mtr = &(meteor[unit]);
+
+
+ if(nprot & PROT_EXEC)
+ return 0;
+
+ if(offset >= mtr->alloc_pages * PAGE_SIZE)
+ return 0;
+
+ return i386_btop((vtophys(mtr->bigbuf) + offset));
+}
+
+#endif /* NMETEOR > 0 */
diff --git a/sys/sys/ioctl_meteor.h b/sys/sys/ioctl_meteor.h
new file mode 100644
index 000000000000..e1fed36e5985
--- /dev/null
+++ b/sys/sys/ioctl_meteor.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 1995 Mark Tinguely and Jim Lowe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Mark Tinguely and Jim Lowe
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * ioctl constants for Matrox Meteor Capture card.
+ */
+
+#ifndef _MACHINE_IOCTL_METEOR_H
+#define _MACHINE_IOCTL_METEOR_H
+
+#include <sys/ioctl.h>
+
+struct meteor_capframe {
+ short command; /* see below for valid METEORCAPFRM commands */
+ short signal; /* signal to send to the user program,
+ when a buffer is full */
+ short lowat; /* start transfer if < this number */
+ short hiwat; /* stop transfer if > this number */
+} ;
+
+/* structure for METEOR[GS]ETGEO - get/set geometry */
+struct meteor_geomet {
+ u_short rows;
+ u_short columns;
+ u_short frames;
+ u_long oformat;
+} ;
+
+/* structure for METEORGCOUNT-get count of frames, fifo errors and dma errors */
+struct meteor_counts {
+ u_long fifo_errors; /* count of fifo errors since open */
+ u_long dma_errors; /* count of dma errors since open */
+ u_long frames_captured; /* count of frames captured since open */
+} ;
+
+#define METEORCAPTUR _IOW('x', 1, int) /* capture a frame */
+#define METEORCAPFRM _IOW('x', 2, struct meteor_capframe) /* sync capture */
+#define METEORSETGEO _IOW('x', 3, struct meteor_geomet) /* set geometry */
+#define METEORGETGEO _IOR('x', 4, struct meteor_geomet) /* get geometry */
+#define METEORSTATUS _IOR('x', 5, unsigned short) /* get status */
+#define METEORSHUE _IOW('x', 6, signed char) /* set hue */
+#define METEORGHUE _IOR('x', 6, signed char) /* get hue */
+#define METEORSFMT _IOW('x', 7, unsigned long) /* set format */
+#define METEORGFMT _IOR('x', 7, unsigned long) /* get format */
+#define METEORSINPUT _IOW('x', 8, unsigned long) /* set input dev */
+#define METEORGINPUT _IOR('x', 8, unsigned long) /* get input dev */
+#define METEORSCHCV _IOW('x', 9, unsigned char) /* set uv gain */
+#define METEORGCHCV _IOR('x', 9, unsigned char) /* get uv gain */
+#define METEORSCOUNT _IOW('x',10, struct meteor_counts)
+#define METEORGCOUNT _IOR('x',10, struct meteor_counts)
+
+#define METEOR_STATUS_ID_MASK 0xf000 /* ID of 7196 */
+#define METEOR_STATUS_DIR 0x0800 /* Direction of Expansion port YUV */
+#define METEOR_STATUS_OEF 0x0200 /* Field detected: Even/Odd */
+#define METEOR_STATUS_SVP 0x0100 /* State of VRAM Port:inactive/active */
+#define METEOR_STATUS_STTC 0x0080 /* Time Constant: TV/VCR */
+#define METEOR_STATUS_HCLK 0x0040 /* Horiz PLL: locked/unlocked */
+#define METEOR_STATUS_FIDT 0x0020 /* Field detect: 50/60hz */
+#define METEOR_STATUS_ALTD 0x0002 /* Line alt: no line alt/line alt */
+#define METEOR_STATUS_CODE 0x0001 /* Colour info: no colour/colour */
+
+ /* METEORCAPTUR capture options */
+#define METEOR_CAP_SINGLE 0x0001 /* capture one frame */
+#define METEOR_CAP_CONTINOUS 0x0002 /* contiuously capture */
+#define METEOR_CAP_STOP_CONT 0x0004 /* stop the continous capture */
+
+ /* METEORCAPFRM capture commands */
+#define METEOR_CAP_N_FRAMES 0x0001 /* capture N frames */
+#define METEOR_CAP_STOP_FRAMES 0x0002 /* stop capture N frames */
+
+ /* valid video input formats: */
+#define METEOR_FMT_NTSC 0x00100 /* NTSC -- initialized default */
+#define METEOR_FMT_PAL 0x00200 /* PAL */
+#define METEOR_FMT_SECAM 0x00400 /* SECAM */
+#define METEOR_FMT_AUTOMODE 0x00800 /* auto-mode */
+#define METEOR_INPUT_DEV0 0x01000 /* camera input 0 -- default */
+#define METEOR_INPUT_DEV_RCA METEOR_GEO_DEV0
+#define METEOR_INPUT_DEV1 0x02000 /* camera input 1 */
+#define METEOR_INPUT_DEV2 0x04000 /* camera input 2 */
+#define METEOR_INPUT_DEV3 0x08000 /* camera input 3 */
+#define METEOR_INPUT_DEV_SVIDEO METEOR_GEO_DEV3
+
+ /* valid video output formats: */
+#define METEOR_GEO_RGB16 0x10000 /* packed -- initialized default */
+#define METEOR_GEO_RGB24 0x20000 /* RBG 24 bits packed */
+ /* internally stored in 32 bits */
+#define METEOR_GEO_YUV_PACKED 0x40000 /* 4-2-2 YUV 16 bits packed */
+#define METEOR_GEO_YUV_PLANER 0x80000 /* 4-2-2 YUV 16 bits planer */
+
+ /* following structure is used to coordinate the syncronous */
+
+struct meteor_mem {
+ /* kernel write only */
+ int frame_size; /* row*columns*depth */
+ unsigned num_bufs; /* number of frames in buffer (1-32) */
+ /* user and kernel change these */
+ int signal; /* signal raised to the user program,
+ on completion of frame capture */
+ int lowat; /* kernel starts capture if < this number */
+ int hiwat; /* kernel stops capture if > this number.
+ hiwat <= numbufs */
+ unsigned active; /* bit mask of active frame buffers
+ kernel sets, user clears */
+ int num_active_bufs; /* count of active frame buffer
+ kernel increments, user decrements */
+
+ /* reference to mmapped data */
+ caddr_t buf; /* The real space (virtual addr) */
+} ;
+
+#endif /* ifndef _MACHINE_IOCTL_METEOR_H */