diff options
| author | Jordan K. Hubbard <jkh@FreeBSD.org> | 1995-08-28 17:03:18 +0000 |
|---|---|---|
| committer | Jordan K. Hubbard <jkh@FreeBSD.org> | 1995-08-28 17:03:18 +0000 |
| commit | 1d86961e143aff4d761422bad42b1fe732138e26 (patch) | |
| tree | a1bc89292563a9defcf366e4f6f3b1b4bbb17b26 | |
| parent | 79f04fe6030bb098e743b16542fab802f7361ffa (diff) | |
Notes
| -rw-r--r-- | sys/conf/NOTES | 13 | ||||
| -rw-r--r-- | sys/dev/bktr/ioctl_meteor.h | 138 | ||||
| -rw-r--r-- | sys/i386/conf/LINT | 13 | ||||
| -rw-r--r-- | sys/i386/conf/NOTES | 13 | ||||
| -rw-r--r-- | sys/i386/include/ioctl_meteor.h | 138 | ||||
| -rw-r--r-- | sys/pci/meteor.c | 1242 | ||||
| -rw-r--r-- | sys/sys/ioctl_meteor.h | 138 |
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 */ |
