diff options
author | imp <imp@FreeBSD.org> | 2003-12-07 04:41:11 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2003-12-07 04:41:11 +0000 |
commit | a7899e4b16f45060cb84886ace0f7125cb1af810 (patch) | |
tree | 41ac8096a4ac5e572443f2668483fa459ccec2fb /sys/pci | |
parent | a83b36de66065d76806ba202f19f8f4fc4c36a31 (diff) | |
download | FreeBSD-src-a7899e4b16f45060cb84886ace0f7125cb1af810.zip FreeBSD-src-a7899e4b16f45060cb84886ace0f7125cb1af810.tar.gz |
Remote meteor driver. It hasn't compiled in over 3 years. If someone
makes it compile again, and can test it, we can restore the driver to
the tree.
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/meteor.c | 2129 | ||||
-rw-r--r-- | sys/pci/meteor_reg.h | 246 |
2 files changed, 0 insertions, 2375 deletions
diff --git a/sys/pci/meteor.c b/sys/pci/meteor.c deleted file mode 100644 index 5c808b5..0000000 --- a/sys/pci/meteor.c +++ /dev/null @@ -1,2129 +0,0 @@ -/* - * 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 . - 8/29/95 Fixes suggested by Bruce Evans. - meteor_mmap should return -1 on error rather than 0. - unit # > NMETEOR should be unit # >= NMETEOR. - 10/24/95 Turn 50 Hz processing for SECAM and 60 Hz processing - off for AUTOMODE. - 11/11/95 Change UV from always begin signed to ioctl selected - to either signed or unsigned. - 12/07/95 Changed 7196 startup codes for 50 Hz as recommended - by Luigi Rizzo (luigi@iet.unipi.it) - 12/08/95 Clear SECAM bit in PAL/NTSC and set input field count - bits for 50 Hz mode (PAL/SECAM) before I was setting the - output count bits. by Luigi Rizzo (luigi@iet.unipi.it) - 12/18/95 Correct odd DMA field (never exceed, but good for safety - Changed 7196 startup codes for 50 Hz as recommended - by Luigi Rizzo (luigi@iet.unipi.it) - 12/19/95 Changed field toggle mode to enable (offset 0x3c) - recommended by luigi@iet.unipi.it - Added in prototyping, include file, staticizing, - and DEVFS changes from FreeBSD team. - Changed the default allocated pages from 151 (NTSC) - to 217 (PAL). - Cleaned up some old comments in iic_write(). - Added a Field (even or odd) only capture mode to - eliminate the high frequency problems with compression - algorithms. Recommended by luigi@iet.unipi.it. - Changed geometry ioctl so if it couldn't allocated a - large enough contiguous space, it wouldn't free the - stuff it already had. - Added new mode called YUV_422 which delivers the - data in planer Y followed by U followed by V. This - differs from the standard YUV_PACKED mode in that - the chrominance (UV) data is in the correct (different) - order. This is for programs like vic and mpeg_encode - so they don't have to reorder the chrominance data. - Added field count to stats. - Increment frame count stat if capturing continuous on - even frame grabs. - Added my email address to these comments - (james@cs.uwm.edu) suggested by (luigi@iet.unipt.it :-). - Changed the user mode signal mechanism to allow the - user program to be interrupted at the end of a frame - in any one of the modes. Added SSIGNAL ioctl. - Added a SFPS/GFPS ioctl so one may set the frames per - second that the card catpures. This code needs to be - completed. - Changed the interrupt routine so synchronous capture - will work on fields or frames and the starting frame - can be either even or odd. - Added HALT_N_FRAMES and CONT_N_FRAMES so one could - stop and continue synchronous capture mode. - Change the tsleep/wakeup function to wait on mtr - rather than &read_intr_wait. - 1/22/96 Add option (METEOR_FreeBSD_210) for FreeBSD 2.1 - to compile. - Changed intr so it only printed errors every 50 times. - Added unit number to error messages. - Added get_meteor_mem and enabled range checking. - 1/30/96 Added prelim test stuff for direct video dma transfers - from Amancio Hasty (hasty@rah.star-gate.com). Until - we get some stuff sorted out, this will be ifdef'ed - with METEOR_DIRECT_VIDEO. This is very dangerous to - use at present since we don't check the address that - is passed by the user!!!!! - 2/26/96 Added special SVIDEO input device type. - 2/27/96 Added meteor_reg.h file and associate types Converted - meteor.c over to using meteor.h file. Prompted by - Lars Jonas Olsson <ljo@po.cwru.edu>. - 2/28/96 Added meteor RGB code from Lars Jonas Olsson - <ljo@po.cwru.edu>. I make some mods to this code, so - I hope it still works as I don't have an rgb card to - test with. - 2/29/96 <ljo@po.cwru.edu> tested the meteor RGB and supplied - me with diffs. Thanks, we now have a working RGB - version of the driver. Still need to clean up this - code. - 3/1/96 Fixed a nasty little bug that was clearing the VTR - mode bit when the 7196 status was requested. - 3/15/96 Fixed bug introduced in previous version that - stopped the only fields mode from working. - Added METEOR{GS}TS ioctl, still needs work. - 3/25/96 Added YUV_9 and YUV_12 modes. Cleaned up some of the - code and converted variables to use the new register - types. - 4/8/96 Fixed the a bug in with the range enable. Pointed - out by Jim Bray. - 5/13/96 Fix the FPS ioctl so it actually sets the frames - per second. Code supplied by ian@robots.ox.ac.uk. - The new code implements a new define: - METEOR_SYSTEM_DEFAULT which should be defined as - METEOR_PAL, METEOR_SECAM, or METEOR_NTSC in your system - configuration file. If METEOR_SYSTEM_DEFAULT isn't - defined, and there is not a signal when set_fps is - called, then the call has no effect. - Changed the spelling of PLANER to PLANAR as pointed - out by Paco Hope <paco@cs.virigina.edu> and define - PLANER to be PLANAR for backward compatibility. - 5/28/95 METEOR_INPUT_DEV_RCA -> METEOR_INPUT_DEV0, not - METEOR_GEO_DEV0. Pointed out by Ian Reid, - <ian@robots.ox.ac.uk>. - METEOR_DEV_MASK should be 0x0000f000 and not - 0x2000f000, otherwise METEOR_RGB gets masked - out. Pointed out by Ian Reid. - Changed the fps code to give even distribution for - low frame rates. Code supplied by Ian Reid. - Fix some problems with the RGB version. Patch supplied - by <ljo@po.cwru.edu>. - Added METEOR_FIELD_MODE to include files for a - future version of this driver. -*/ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#ifdef COMPILING_LINT -#warning "The meteor driver is broken and is not compiled with LINT" -#else - -#include "meteor.h" - -#include "opt_meteor.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/kernel.h> -#include <sys/signalvar.h> -#include <sys/mman.h> -#include <sys/uio.h> - -#if defined(METEOR_FreeBSD_210) -#include <machine/cpu.h> /* bootverbose */ -#endif - -#include <vm/vm.h> -#include <vm/vm_kern.h> -#include <vm/pmap.h> -#include <vm/vm_extern.h> - -#include <dev/pci/pcivar.h> -#include <dev/pci/pcireg.h> -#include <machine/ioctl_meteor.h> -#include <pci/meteor_reg.h> - -#ifndef COMPAT_OLDPCI -#error "The meteor device requires the old pci compatibility shims" -#endif - -static void meteor_intr(void *arg); - -/* - * Allocate enough memory for: - * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages - * - * You may override this using the options "METEOR_ALLOC_PAGES=value" in your - * kernel configuration file. - */ -#ifndef METEOR_ALLOC_PAGES -#define METEOR_ALLOC_PAGES 217 -#endif -#define METEOR_ALLOC (METEOR_ALLOC_PAGES * PAGE_SIZE) - -static meteor_reg_t meteor[NMETEOR]; -#define METEOR_NUM(mtr) ((mtr - &meteor[0])/sizeof(meteor_reg_t)) - -#define METPRI (PZERO+8)|PCATCH - -static const char* met_probe (pcici_t tag, pcidi_t type); -static void met_attach(pcici_t tag, int unit); -static u_long met_count; - -static struct pci_device met_device = { - "meteor", - met_probe, - met_attach, - &met_count -}; - -COMPAT_PCI_DRIVER (meteor, met_device); - -#if defined(METEOR_FreeBSD_210) /* XXX */ -d_open_t meteor_open; -d_close_t meteor_close; -d_read_t meteor_read; -d_write_t meteor_write; -d_ioctl_t meteor_ioctl; -d_mmap_t meteor_mmap; -#else -static d_open_t meteor_open; -static d_close_t meteor_close; -static d_read_t meteor_read; -static d_write_t meteor_write; -static d_ioctl_t meteor_ioctl; -static d_mmap_t meteor_mmap; - -#define CDEV_MAJOR 67 -static struct cdevsw meteor_cdevsw = { - .d_open = meteor_open, - .d_close = meteor_close, - .d_read = meteor_read, - .d_write = meteor_write, - .d_ioctl = meteor_ioctl, - .d_mmap = meteor_mmap, - .d_name = "meteor", - .d_maj = CDEV_MAJOR, -}; -#endif - -static mreg_t saa7116_pci_default[sizeof(struct saa7116_regs)/sizeof(mreg_t)]={ - /* 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 */ 0x00000107, /* 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 */ 0x30, /* 7:0 Horizontal Sync Begin for 50hz */ -/* 02 */ 0x00, /* 7:0 Horizontal Sync Stop for 50hz */ -/* 03 */ 0xe8, /* 7:0 Horizontal Sync Clamp Start for 50hz */ -/* 04 */ 0xb6, /* 7:0 Horizontal Sync Clamp Stop for 50hz */ -/* 05 */ 0xf4, /* 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 */ -#ifdef notdef -/* 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 */ -#else - 0x0a, 0xf4, 0xce, 0xf4, -#endif -/* 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 */ -}; - -static u_char bt254_default[NUM_BT254_REGS] = { - 0x00, /* 24 bpp */ - 0xa0, - 0xa0, - 0xa0, - 0x50, - 0x50, - 0x50, -} ; - -/* - * i2c_write: - * Returns 0 Succesful completion. - * Returns 1 If transfer aborted or timeout occured. - * - */ -static int i2c_print_err = 1; -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 mreg_t * iic_write_loc = &mtr->base->i2c_write; -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--; - } - - /* 1ffff should be enough delay time for the i2c cycle to complete */ - if(!wait_counter) { - if(i2c_print_err) - printf("meteor%d: %d i2c %s transfer timeout 0x%x", - METEOR_NUM(mtr), slave, - rw ? "read" : "write", *iic_write_loc); - - err=1; - } - - /* Check for error on direct write, clear if any */ - if(mtr->base->i2c_read & SAA7116_IIC_DIRECT_TRANSFER_ABORTED){ - mtr->base->i2c_read |= SAA7116_IIC_DIRECT_TRANSFER_ABORTED; - if(i2c_print_err) - printf("meteor%d: 0x%x i2c %s tranfer aborted", - METEOR_NUM(mtr), slave, - rw ? "read" : "write" ); - err= 1; - } - - if(err) { - if(i2c_print_err) - printf(" - reg=0x%x, value=0x%x.\n", reg, data); - } - - return err; -} -#undef i2c_print - -static const char * -met_probe (pcici_t tag, pcidi_t type) -{ - - switch (type) { - case SAA7116_PHILIPS_ID: /* meteor */ - return("Philips SAA 7116"); - }; - return ((char *)0); -} - - /* interrupt handling routine - complete meteor_read() if using interrupts - */ -static void -meteor_intr(void *arg) -{ - meteor_reg_t *mtr = (meteor_reg_t *) arg; - mreg_t *cap = &mtr->base->cap_cntl, - *base = &mtr->base->dma1e, - *stat = &mtr->base->irq_stat; - u_long status = *stat, - cap_err = *cap & 0x00000f00, -#ifdef METEOR_CHECK_PCI_BUS - pci_err = pci_conf_read(mtr->tag, - PCI_COMMAND_STATUS_REG), -#endif - next_base = (u_long)(vtophys(mtr->bigbuf)); - - /* - * Disable future interrupts if a capture mode is not selected. - * This can happen when we are in the process of closing or - * changing capture modes, otherwise it shouldn't happen. - */ - if(!(mtr->flags & METEOR_CAP_MASK)) { - *cap &= 0x8ff0; /* disable future interrupts */ - } -#ifdef METEOR_CHECK_PCI_BUS - /* - * Check for pci bus errors. - */ -#define METEOR_MASTER_ABORT 0x20000000 -#define METEOR_TARGET_ABORT 0x10000000 - if(pci_err & METEOR_MASTER_ABORT) { - printf("meteor%d: intr: pci bus master dma abort: 0x%x 0x%x.\n", - METEOR_NUM(mtr), *base, *(base+3)); - pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err); - } - if(pci_err & METEOR_TARGET_ABORT) { - printf("meteor%d: intr: pci bus target dma abort: 0x%x 0x%x.\n", - METEOR_NUM(mtr), *base, *(base+3)); - pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err); - } -#endif - /* - * Check for errors. - */ - if (cap_err) { - if (cap_err & 0x300) { - if(mtr->fifo_errors % 50 == 0) { - printf("meteor%d: capture error", METEOR_NUM(mtr)); - printf(": %s FIFO overflow.\n", - cap_err&0x0100? "even" : "odd"); - } - mtr->fifo_errors++ ; /* increment fifo capture errors cnt */ - } - if (cap_err & 0xc00) { - if(mtr->dma_errors % 50 == 0) { - printf("meteor%d: capture error", METEOR_NUM(mtr)); - printf(": %s DMA address.\n", - cap_err&0x0400? "even" : "odd"); - } - mtr->dma_errors++ ; /* increment DMA capture errors cnt */ - } - } - *cap |= 0x0f30; /* clear error and field done */ - - /* - * In synchronous capture mode we need to know what the address - * offset for the next field/frame will be. next_base holds the - * value for the even dma buffers (for odd, one must add stride). - */ - if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait && - (mtr->current < mtr->frames)) { /* could be !=, but < is safer */ - /* next_base is initialized to mtr->bigbuf */ - next_base += mtr->frame_size * mtr->current; - if(mtr->flags & METEOR_WANT_TS) - next_base += sizeof(struct timeval) * mtr->current; - } - - /* - * Count the field and clear the field flag. - * - * In single mode capture, clear the continuous capture mode. - * - * In synchronous capture mode, if we have room for another field, - * adjust DMA buffer pointers. - * When we are above the hi water mark (hiwat), mtr->synch_wait will - * be set and we will not bump the DMA buffer pointers. Thus, once - * we reach the hi water mark, the driver acts like a continuous mode - * capture on the mtr->current frame until we hit the low water - * mark (lowat). The user had the option of stopping or halting - * the capture if this is not the desired effect. - */ - if (status & 0x1) { /* even field */ - mtr->even_fields_captured++; - mtr->flags &= ~METEOR_WANT_EVEN; - if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) { - *base = next_base; - /* XXX should add adjustments for YUV_422 & PLANAR */ - } - /* - * If the user requested to be notified via signal, - * let them know the field is complete. - */ - if(mtr->proc != NULL) { - PROC_LOCK(mtr->proc); - psignal(mtr->proc, mtr->signal); - PROC_UNLOCK(mtr->proc); - } - } - if (status & 0x2) { /* odd field */ - mtr->odd_fields_captured++; - mtr->flags &= ~METEOR_WANT_ODD; - if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) { - *(base+3) = next_base + *(base+6); - /* XXX should add adjustments for YUV_422 & PLANAR */ - } - /* - * If the user requested to be notified via signal, - * let them know the field is complete. - */ - if(mtr->proc != NULL) { - PROC_LOCK(mtr->proc); - psignal(mtr->proc, mtr->signal); - PROC_UNLOCK(mtr->proc); - } - } - - /* - * If we have a complete frame. - */ - if(!(mtr->flags & METEOR_WANT_MASK)) { - mtr->frames_captured++; - /* - * post the completion time. - */ - if(mtr->flags & METEOR_WANT_TS) { - struct timeval *ts; - - if(mtr->alloc_pages * PAGE_SIZE <= (mtr->frame_size + - sizeof(struct timeval))) { - ts =(struct timeval *)mtr->bigbuf + - mtr->frame_size; - /* doesn't work in synch mode except for first frame */ - /* XXX */ - microtime(ts); - } - } - /* - * Wake up the user in single capture mode. - */ - if(mtr->flags & METEOR_SINGLE) - wakeup(mtr); - /* - * If the user requested to be notified via signal, - * let them know the frame is complete. - */ - if(mtr->proc != NULL) { - PROC_LOCK(mtr->proc); - psignal(mtr->proc, mtr->signal); - PROC_UNLOCK(mtr->proc); - } - /* - * Reset the want flags if in continuous or - * synchronous capture mode. - */ - if(mtr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) { - switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - case METEOR_ONLY_ODD_FIELDS: - mtr->flags |= METEOR_WANT_ODD; - break; - case METEOR_ONLY_EVEN_FIELDS: - mtr->flags |= METEOR_WANT_EVEN; - break; - default: - mtr->flags |= METEOR_WANT_MASK; - break; - } - } - /* - * Special handling for synchronous capture mode. - */ - if(mtr->flags & METEOR_SYNCAP) { - struct meteor_mem *mm = mtr->mem; - /* - * Mark the current frame as active. It is up to - * the user to clear this, but we will clear it - * for the user for the current frame being captured - * if we are within the water marks (see below). - */ - mm->active |= 1 << (mtr->current - 1); - - /* - * Since the user can muck with these values, we need - * to check and see if they are sane. If they don't - * pass the sanity check, disable the capture mode. - * This is rather rude, but then so was the user. - * - * Do we really need all of this or should we just - * eliminate the possiblity of allowing the - * user to change hi and lo water marks while it - * is running? XXX - */ - if(mm->num_active_bufs < 0 || - mm->num_active_bufs > mtr->frames || - mm->lowat < 1 || mm->lowat >= mtr->frames || - mm->hiwat < 1 || mm->hiwat >= mtr->frames || - mm->lowat > mm->hiwat ) { - *cap &= 0x8ff0; - mtr->flags &= ~(METEOR_SYNCAP|METEOR_WANT_MASK); - } else { - /* - * Ok, they are sane, now we want to - * check the water marks. - */ - if(mm->num_active_bufs <= mm->lowat) - mtr->synch_wait = 0; - if(mm->num_active_bufs >= mm->hiwat) - mtr->synch_wait = 1; - /* - * Clear the active frame bit for this frame - * and advance the counters if we are within - * the banks of the water marks. - */ - if(!mtr->synch_wait) { - mm->active &= ~(1 << mtr->current); - mtr->current++; - if(mtr->current > mtr->frames) - mtr->current = 1; - mm->num_active_bufs++; - } - } - } - } - - *stat |= 0x7; /* clear interrupt status */ - return; -} - -static void -set_fps(meteor_reg_t *mtr, u_short fps) -{ - struct saa7116_regs *s7116 = mtr->base; - unsigned status; - unsigned maxfps, mask = 0x1, length = 0; - - SAA7196_WRITE(mtr, SAA7196_STDC, SAA7196_REG(mtr, SAA7196_STDC) | 0x02); - SAA7196_READ(mtr); - status = (s7116->i2c_read & 0xff000000L) >> 24; - - /* - * Determine if there is an input signal. Depending on the - * frequency we either have a max of 25 fps (50 hz) or 30 fps (60 hz). - * If there is no input signal, then we need some defaults. If the - * user neglected to specify any defaults, just set to the fps to max. - */ - if((status & 0x40) == 0) { /* Is there a signal ? */ - if(status & 0x20) { - maxfps = 30; /* 60 hz system */ - } else { - maxfps = 25; /* 50 hz system */ - } - } else { /* We have no signal, check defaults */ -#if METEOR_SYSTEM_DEFAULT == METEOR_PAL || METEOR_SYSTEM_DEFAULT == METEOR_SECAM - maxfps = 25; -#elif METEOR_SYSTEM_DEFAULT == METEOR_NTSC - maxfps = 30; -#else - /* Don't really know what to do, just set max */ - maxfps = 30; - fps = 30; -#endif - } - - /* - * A little sanity checking... - */ - if(fps < 1) fps = 1; - if(fps > maxfps) fps = maxfps; - - /* - * Compute the mask/length using the fps. - */ - if(fps == maxfps) { - mask = 0x1; - length = 0x0; - } else if ((float)fps == maxfps/2.0) { - mask = 0x1; - length = 0x1; - } else if (fps > maxfps/2) { - float step, b; - - mask = (1<<maxfps) - 1; - length = maxfps - 1; - step = (float)(maxfps - 1)/(float)(maxfps - fps); - for(b=step; b < maxfps; b += step) { - mask &= ~(1<<((int)b)); /* mask out the bth frame */ - } - } else { /* fps < maxfps/2 */ - float step, b; - - mask = 0x1; - length = maxfps - 1; - step = (float)(maxfps -1)/(float)(fps); - for(b = step + 1; b < maxfps - 1; b += step) { - mask |= (1<<((int)b)); /* mask in the bth frame */ - } - } - - /* - * Set the fps. - */ - s7116->fme = s7116->fmo = mask; - s7116->fml = (length << 16) | length;; - - mtr->fps = fps; - - return; - -} - -/* - * There is also a problem with range checking on the 7116. - * It seems to only work for 22 bits, so the max size we can allocate - * is 22 bits long or 4194304 bytes assuming that we put the beginning - * of the buffer on a 2^24 bit boundary. The range registers will use - * the top 8 bits of the dma start registers along with the bottom 22 - * bits of the range register to determine if we go out of range. - * This makes getting memory a real kludge. - * - */ -#define RANGE_BOUNDARY (1<<22) -static vm_offset_t -get_meteor_mem(int unit, unsigned size) -{ -vm_offset_t addr = 0; - - addr = vm_page_alloc_contig(size, 0, 0xffffffff, 1<<24); - if(addr == 0) - addr = vm_page_alloc_contig(size, 0, 0xffffffff, PAGE_SIZE); - if(addr == 0) { - printf("meteor%d: Unable to allocate %d bytes of memory.\n", - unit, size); - } - - return addr; -} - -static void -bt254_write(meteor_reg_t *mtr, u_char addr, u_char data) -{ - addr &= 0x7; /* sanity? */ - mtr->bt254_reg[addr] = data; - PCF8574_DATA_WRITE(mtr, data); /* set data */ - PCF8574_CTRL_WRITE(mtr, (PCF8574_CTRL_REG(mtr) & ~0x7) | addr); - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x10); /* WR/ to 0 */ - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x10); /* WR to 1 */ - PCF8574_DATA_WRITE(mtr, 0xff); /* clr data */ - -} - -static void -bt254_init(meteor_reg_t *mtr) -{ -int i; - - PCF8574_CTRL_WRITE(mtr, 0x7f); - PCF8574_DATA_WRITE(mtr, 0xff); /* data port must be 0xff */ - PCF8574_CTRL_WRITE(mtr, 0x7f); - - /* init RGB module for 24bpp, composite input */ - for(i=0; i<NUM_BT254_REGS; i++) - bt254_write(mtr, i, bt254_default[i]); - - bt254_write(mtr, BT254_COMMAND, 0x00); /* 24 bpp */ -} - -static void -bt254_ntsc(meteor_reg_t *mtr, int arg) -{ - if (arg){ - /* Set NTSC bit */ - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x20); - } - else { - /* reset NTSC bit */ - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) &= ~0x20); - } -} - -static void -select_bt254(meteor_reg_t *mtr) -{ - /* disable saa7196, saaen = 1 */ - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x80); - /* enable Bt254, bten = 0 */ - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x40); -} - -static void -select_saa7196(meteor_reg_t *mtr) -{ - /* disable Bt254, bten = 1 */ - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) | 0x40); - /* enable saa7196, saaen = 0 */ - PCF8574_CTRL_WRITE(mtr, PCF8574_CTRL_REG(mtr) & ~0x80); -} - -/* - * Initialize the 7116, 7196 and the RGB module. - */ -static void -meteor_init ( meteor_reg_t *mtr ) -{ - mreg_t *vbase_addr; - int i; - - /* - * Initialize the Philips SAA7116 - */ - mtr->base->cap_cntl = 0x00000040L; - vbase_addr = &mtr->base->dma1e; - for (i = 0 ; i < (sizeof(struct saa7116_regs)/sizeof(mreg_t)); i++) - *vbase_addr++ = saa7116_pci_default[i]; - - /* - * Check for the Philips SAA7196 - */ - i2c_print_err = 0; - if(i2c_write(mtr, SAA7196_I2C_ADDR, SAA7116_I2C_WRITE, 0, 0xff) == 0) { - i2c_print_err = 1; - /* - * Initialize 7196 - */ - for (i = 0; i < NUM_SAA7196_I2C_REGS; i++) - SAA7196_WRITE(mtr, i, saa7196_i2c_default[i]); - /* - * Get version number. - */ - SAA7196_WRITE(mtr, SAA7196_STDC, - SAA7196_REG(mtr, SAA7196_STDC) & ~0x02); - SAA7196_READ(mtr); - printf("meteor%d: <Philips SAA 7196> rev 0x%x\n", - METEOR_NUM(mtr), - (unsigned)((mtr->base->i2c_read & 0xff000000L) >> 28)); - } else { - i2c_print_err = 1; - printf("meteor%d: <Philips SAA 7196 NOT FOUND>\n", - METEOR_NUM(mtr)); - } - /* - * Check for RGB module, initialized if found. - */ - i2c_print_err = 0; - if(i2c_write(mtr,PCF8574_DATA_I2C_ADDR,SAA7116_I2C_WRITE,0,0xff) == 0) { - i2c_print_err = 1; - printf("meteor%d: <Booktree 254 (RGB module)>\n", - METEOR_NUM(mtr)); /* does this have a rev #? */ - bt254_init(mtr); /* Set up RGB module */ - mtr->flags = METEOR_RGB; - } else { - i2c_print_err = 1; - mtr->flags = 0; - } - - set_fps(mtr, 30); - -} - -static void -met_attach(pcici_t tag, int unit) -{ -#ifdef METEOR_IRQ - u_long old_irq, new_irq; -#endif METEOR_IRQ - meteor_reg_t *mtr; - vm_offset_t buf; - u_long latency; - - if (unit >= NMETEOR) { - printf("meteor%d: attach: only %d units configured.\n", - unit, NMETEOR); - printf("meteor%d: attach: invalid unit number.\n", unit); - return ; - } - - /* - * Check for Meteor/PPB (PCI-PCI Bridge) - * Reprogram IBM Bridge if detected. - * New Meteor cards have an IBM PCI-PCI bridge, creating a secondary - * PCI bus. The SAA chip is connected to this secondary bus. - */ - - /* If we are not on PCI Bus 0, check for the Bridge */ - if ( pci_get_bus_from_tag( tag ) != 0) { - pcici_t bridge_tag; - - /* get tag of parent bridge */ - bridge_tag = pci_get_parent_from_tag( tag ); - - /* Look for IBM 82351, 82352 or 82353 */ - if (pci_conf_read(bridge_tag, PCI_ID_REG) == 0x00221014) { - - if ( bootverbose) - printf("meteor%d: PPB device detected, reprogramming IBM bridge.\n", unit); - - /* disable SERR */ - pci_cfgwrite(bridge_tag, 0x05, 0x00, 1); - /* set LATENCY */ - pci_cfgwrite(bridge_tag, 0x0d, 0x20, 1); - /* write posting enable, prefetch enabled --> GRAB direction */ - pci_cfgwrite(bridge_tag, 0x42, 0x14, 1); - /* set PRTR Primary retry timer register */ - pci_cfgwrite(bridge_tag, 0x4c, 0x10, 1); - } - } - - mtr = &meteor[unit]; - mtr->tag = tag; - pci_map_mem(tag, PCI_MAP_REG_START, (vm_offset_t *)&mtr->base, - &mtr->phys_base); - -#ifdef METEOR_IRQ /* from the configuration 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%d: attach: irq changed from %d to %d\n", - unit, (old_irq & 0xff), (new_irq & 0xff)); -#endif METEOR_IRQ - /* setup the interrupt handling routine */ - pci_map_int(tag, meteor_intr, (void*) mtr, &net_imask); - -/* - * PCI latency timer. 32 is a good value for 4 bus mastering slots, if - * you have more than for, then 16 would probably be a better value. - * - */ -#ifndef METEOR_DEF_LATENCY_VALUE -#define METEOR_DEF_LATENCY_VALUE 32 -#endif - latency = pci_conf_read(tag, PCI_LATENCY_TIMER); - latency = (latency >> 8) & 0xff; - if(bootverbose) { - if(latency) - printf("meteor%d: PCI bus latency is", unit); - else - printf("meteor%d: PCI bus latency was 0 changing to", - unit); - } - if(!latency) { - latency = METEOR_DEF_LATENCY_VALUE; - pci_conf_write(tag, PCI_LATENCY_TIMER, latency<<8); - } - if(bootverbose) { - printf(" %lu.\n", latency); - } - - meteor_init(mtr); /* set up saa7116, saa7196, and rgb module */ - - if(METEOR_ALLOC) - buf = get_meteor_mem(unit, METEOR_ALLOC); - else - buf = 0; - if(bootverbose) { - printf("meteor%d: buffer size %d, addr 0x%x\n", - unit, METEOR_ALLOC, vtophys(buf)); - } - - mtr->bigbuf = buf; - mtr->alloc_pages = METEOR_ALLOC_PAGES; - if(buf != 0) { - bzero((caddr_t) buf, METEOR_ALLOC); - buf = vtophys(buf); - /* 640x480 RGB 16 */ - mtr->base->dma1e = buf; - mtr->base->dma1o = buf + 0x500; - mtr->base->dma_end_e = - mtr->base->dma_end_o = buf + METEOR_ALLOC; - } - /* 1 frame of 640x480 RGB 16 */ - mtr->cols = 640; - mtr->rows = 480; - mtr->depth = 2; /* two bytes per pixel */ - mtr->frames = 1; /* one frame */ - - mtr->flags |= METEOR_INITALIZED | METEOR_AUTOMODE | METEOR_DEV0 | - METEOR_RGB16; - make_dev(&meteor_cdevsw, unit, 0, 0, 0644, "meteor"); -} - -#define UNIT(x) ((x) & 0x07) - -#ifdef unused -static int -meteor_reset(dev_t dev) -{ -int unit = UNIT(minor(dev)); -struct saa7116_regs *m; - - if(unit >= NMETEOR) - return ENXIO; - - m = meteor[unit].base; - - m->cap_cntl = 0x0; - tsleep(m, METPRI, "Mreset", hz/50); - - m->cap_cntl = 0x8ff0; - m->cap_cntl = 0x80c0; - m->cap_cntl = 0x8040; - tsleep(m, METPRI, "Mreset", hz/10); - m->cap_cntl = 0x80c0; - - return 0; - -} -#endif - -/*--------------------------------------------------------- -** -** Meteor character device driver routines -** -**--------------------------------------------------------- -*/ - - -int -meteor_open(dev_t dev, int flags, int fmt, struct thread *td) -{ - 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; - mtr->even_fields_captured = 0; - mtr->odd_fields_captured = 0; - mtr->proc = (struct proc *)0; - set_fps(mtr, 30); -#ifdef METEOR_TEST_VIDEO - mtr->video.addr = 0; - mtr->video.width = 0; - mtr->video.banksize = 0; - mtr->video.ramsize = 0; -#endif - - return(0); -} - -int -meteor_close(dev_t dev, int flags, int fmt, struct thread *td) -{ - meteor_reg_t *mtr; - int unit; -#ifdef METEOR_DEALLOC_ABOVE - int temp; -#endif - - unit = UNIT(minor(dev)); - if (unit >= NMETEOR) /* unit out of range */ - return(ENXIO); - - mtr = &(meteor[unit]); - mtr->flags &= ~METEOR_OPEN; - - if(mtr->flags & METEOR_SINGLE) - /* this should not happen, the read capture - should have completed or in the very least - recieved a signal before close is called. */ - wakeup(mtr); /* continue read */ - /* - * Turn off capture mode. - */ - mtr->base->cap_cntl = 0x8ff0; - mtr->flags &= ~(METEOR_CAP_MASK|METEOR_WANT_MASK); - mtr->proc = (struct proc *)0; - -#ifdef METEOR_DEALLOC_PAGES - if (mtr->bigbuf != NULL) { - 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 != NULL && 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); -} - -static void -start_capture(meteor_reg_t *mtr, unsigned type) -{ -mreg_t *cap = &mtr->base->cap_cntl; - - mtr->flags |= type; - switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - case METEOR_ONLY_EVEN_FIELDS: - mtr->flags |= METEOR_WANT_EVEN; - if(type == METEOR_SINGLE) - *cap = 0x0ff4 | mtr->range_enable; - else - *cap = 0x0ff1 | mtr->range_enable; - break; - case METEOR_ONLY_ODD_FIELDS: - mtr->flags |= METEOR_WANT_ODD; - if(type == METEOR_SINGLE) - *cap = 0x0ff8 | mtr->range_enable; - else - *cap = 0x0ff2 | mtr->range_enable; - break; - default: - mtr->flags |= METEOR_WANT_MASK; - if(type == METEOR_SINGLE) - *cap = 0x0ffc | mtr->range_enable; - else - *cap = 0x0ff3 | mtr->range_enable; - break; - } -} - -int -meteor_read(dev_t dev, struct uio *uio, int ioflag) -{ - 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 == 0)/* no frame buffer allocated (ioctl failed) */ - return(ENOMEM); - - 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); - - /* Start capture */ - start_capture(mtr, METEOR_SINGLE); - - status=tsleep(mtr, METPRI, "capturing", 0); - if (!status) /* successful capture */ - status = uiomove((caddr_t)mtr->bigbuf, count, uio); - else - printf ("meteor%d: read: tsleep error %d\n", unit, status); - - mtr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK); - - return(status); -} - -int -meteor_write(dev_t dev, struct uio *uio, int ioflag) -{ - return(0); -} - -int -meteor_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td) -{ - int error; - int unit; - int sig; - unsigned int temp; - meteor_reg_t *mtr; - struct meteor_counts *cnt; - struct meteor_geomet *geo; - struct meteor_mem *mem; - struct meteor_capframe *frame; -#ifdef METEOR_TEST_VIDEO - struct meteor_video *video; -#endif - vm_offset_t buf; - struct saa7116_regs *base; - - error = 0; - - if (!arg) return(EINVAL); - unit = UNIT(minor(dev)); - if (unit >= NMETEOR) /* unit out of range */ - return(ENXIO); - - mtr = &(meteor[unit]); - base = mtr->base; - - switch (cmd) { - case METEORSTS: - if(*arg) - mtr->flags |= METEOR_WANT_TS; - else - mtr->flags &= ~METEOR_WANT_TS; - break; - case METEORGTS: - if(mtr->flags & METEOR_WANT_TS) - *arg = 1; - else - *arg = 0; - break; -#ifdef METEOR_TEST_VIDEO - case METEORGVIDEO: - video = (struct meteor_video *)arg; - video->addr = mtr->video.addr; - video->width = mtr->video.width; - video->banksize = mtr->video.banksize; - video->ramsize = mtr->video.ramsize; - break; - case METEORSVIDEO: - video = (struct meteor_video *)arg; - mtr->video.addr = video->addr; - mtr->video.width = video->width; - mtr->video.banksize = video->banksize; - mtr->video.ramsize = video->ramsize; - break; -#endif - case METEORSFPS: - set_fps(mtr, *(u_short *)arg); - break; - case METEORGFPS: - *(u_short *)arg = mtr->fps; - break; - case METEORSSIGNAL: - sig = *(int *)arg; - /* Applications use 0 to reset signal delivery. */ - if (sig < 0 || sig > _SIG_MAXSIG) - return (EINVAL); - mtr->signal = sig; - mtr->proc = sig ? td->td_proc : NULL; - break; - case METEORGSIGNAL: - *(int *)arg = mtr->signal; - break; - case METEORSTATUS: /* get 7196 status */ - temp = 0; - SAA7196_WRITE(mtr, SAA7196_STDC, - SAA7196_REG(mtr, SAA7196_STDC) | 0x02); - SAA7196_READ(mtr); - temp |= (base->i2c_read & 0xff000000L) >> 24; - SAA7196_WRITE(mtr, SAA7196_STDC, - SAA7196_REG(mtr, SAA7196_STDC) & ~0x02); - SAA7196_READ(mtr); - temp |= (base->i2c_read & 0xff000000L) >> 16; - *(u_short *)arg = temp; - break; - case METEORSHUE: /* set hue */ - SAA7196_WRITE(mtr, SAA7196_HUEC, *(char *)arg); - break; - case METEORGHUE: /* get hue */ - *(char *)arg = SAA7196_REG(mtr, SAA7196_HUEC); - break; - case METEORSCHCV: /* set chrominance gain */ - SAA7196_WRITE(mtr, SAA7196_CGAINR, *(char *)arg); - break; - case METEORGCHCV: /* get chrominance gain */ - *(char *)arg = SAA7196_REG(mtr, SAA7196_CGAINR); - break; - case METEORSBRIG: /* set brightness */ - SAA7196_WRITE(mtr, SAA7196_BRIG, *(char *)arg); - break; - case METEORGBRIG: /* get brightness */ - *(char *)arg = SAA7196_REG(mtr, SAA7196_BRIG); - break; - case METEORSCSAT: /* set chroma saturation */ - SAA7196_WRITE(mtr, SAA7196_CSAT, *(char *)arg); - break; - case METEORGCSAT: /* get chroma saturation */ - *(char *)arg = SAA7196_REG(mtr, SAA7196_CSAT); - break; - case METEORSCONT: /* set contrast */ - SAA7196_WRITE(mtr, SAA7196_CONT, *(char *)arg); - break; - case METEORGCONT: /* get contrast */ - *(char *)arg = SAA7196_REG(mtr, SAA7196_CONT); - break; - case METEORSBT254: - if((mtr->flags & METEOR_RGB) == 0) - return EINVAL; - temp = *(unsigned short *)arg; - bt254_write(mtr, temp & 0xf, (temp & 0x0ff0) >> 4); - break; - case METEORGBT254: - if((mtr->flags & METEOR_RGB) == 0) - return EINVAL; - temp = *(unsigned short *)arg & 0x7; - *(unsigned short *)arg = mtr->bt254_reg[temp] << 4 | temp; - break; - case METEORSHWS: /* set horizontal window start */ - SAA7196_WRITE(mtr, SAA7196_HWS, *(char *)arg); - break; - case METEORGHWS: /* get horizontal window start */ - *(char *)arg = SAA7196_REG(mtr, SAA7196_HWS); - break; - case METEORSVWS: /* set vertical window start */ - SAA7196_WRITE(mtr, SAA7196_VWS, *(char *)arg); - break; - case METEORGVWS: /* get vertical window start */ - *(char *)arg = SAA7196_REG(mtr, SAA7196_VWS); - break; - case METEORSINPUT: /* set input device */ - switch(*(unsigned long *)arg & METEOR_DEV_MASK) { - case 0: /* default */ - case METEOR_INPUT_DEV0: - if(mtr->flags & METEOR_RGB) - select_saa7196(mtr); - mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) - | METEOR_DEV0; - SAA7196_WRITE(mtr, 0x0e, - (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x0); - SAA7196_WRITE(mtr, 0x06, - (SAA7196_REG(mtr, 0x06) & ~0x80)); - break; - case METEOR_INPUT_DEV1: - if(mtr->flags & METEOR_RGB) - select_saa7196(mtr); - mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) - | METEOR_DEV1; - SAA7196_WRITE(mtr, 0x0e, - (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x1); - SAA7196_WRITE(mtr, 0x06, - (SAA7196_REG(mtr, 0x06) & ~0x80)); - break; - case METEOR_INPUT_DEV2: - if(mtr->flags & METEOR_RGB) - select_saa7196(mtr); - mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) - | METEOR_DEV2; - SAA7196_WRITE(mtr, 0x0e, - (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2); - SAA7196_WRITE(mtr, 0x06, - (SAA7196_REG(mtr, 0x06) & ~0x80)); - break; - case METEOR_INPUT_DEV3: - if(mtr->flags & METEOR_RGB) - select_saa7196(mtr); - mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) - | METEOR_DEV3; - SAA7196_WRITE(mtr, 0x0e, - (SAA7196_REG(mtr, 0x0e) | 0x3)); - SAA7196_WRITE(mtr, 0x06, - (SAA7196_REG(mtr, 0x06) & ~0x80) ); - break; - case METEOR_INPUT_DEV_SVIDEO: - if(mtr->flags & METEOR_RGB) - select_saa7196(mtr); - mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) - | METEOR_DEV_SVIDEO; - SAA7196_WRITE(mtr, 0x0e, - (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x2); - SAA7196_WRITE(mtr, 0x06, - (SAA7196_REG(mtr, 0x06) & ~0x80) | 0x80); - break; - case METEOR_INPUT_DEV_RGB: - if((mtr->flags & METEOR_RGB) == 0) - return EINVAL; - mtr->flags = (mtr->flags & ~METEOR_DEV_MASK) - | METEOR_DEV_RGB; - SAA7196_WRITE(mtr, 0x0e, - (SAA7196_REG(mtr, 0x0e) & ~0x3) | 0x3); - SAA7196_WRITE(mtr, 0x06, - (SAA7196_REG(mtr, 0x06) & ~0x80)); - select_bt254(mtr); - SAA7196_WRITE(mtr, 0x0e, /* chn 3 for synch */ - (SAA7196_REG(mtr, 0x0e) & ~0x3) | 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, SAA7196_STDC, - (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01)); - SAA7196_WRITE(mtr, 0x0f, - (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 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)) ; - if(mtr->flags & METEOR_RGB){ - bt254_ntsc(mtr, 1); - } - break; - case METEOR_FMT_PAL: - mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) | - METEOR_PAL; - SAA7196_WRITE(mtr, SAA7196_STDC, - (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01)); - SAA7196_WRITE(mtr, 0x0f, - (SAA7196_REG(mtr, 0x0f) & ~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) | 0x04) ; - if(mtr->flags & METEOR_RGB){ - bt254_ntsc(mtr, 0); - } - break; - case METEOR_FMT_SECAM: - mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) | - METEOR_SECAM; - SAA7196_WRITE(mtr, SAA7196_STDC, - (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01) | 0x1); - SAA7196_WRITE(mtr, 0x0f, - (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x20); - 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) | 0x04) ; - if(mtr->flags & METEOR_RGB){ - bt254_ntsc(mtr, 0); - } - break; - case METEOR_FMT_AUTOMODE: - mtr->flags = (mtr->flags & ~METEOR_FORM_MASK) | - METEOR_AUTOMODE; - SAA7196_WRITE(mtr, SAA7196_STDC, - (SAA7196_REG(mtr, SAA7196_STDC) & ~0x01)); - SAA7196_WRITE(mtr, 0x0f, - (SAA7196_REG(mtr, 0x0f) & ~0xe0) | 0x80); - break; - default: - return EINVAL; - } - break; - case METEORGFMT: /* get input format */ - *(u_long *)arg = mtr->flags & METEOR_FORM_MASK; - break; - case METEORCAPTUR: - temp = mtr->flags; - switch (*(int *) arg) { - case METEOR_CAP_SINGLE: - if (mtr->bigbuf==0) /* no frame buffer allocated */ - return(ENOMEM); - - if (temp & METEOR_CAP_MASK) - return(EIO); /* already capturing */ - - start_capture(mtr, METEOR_SINGLE); - - /* wait for capture to complete */ - error=tsleep(mtr, METPRI, "capturing", 0); - if(error) - printf("meteor%d: ioctl: tsleep error %d\n", - unit, error); - mtr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK); - break; - case METEOR_CAP_CONTINOUS: - if (mtr->bigbuf==0) /* no frame buffer allocated */ - return(ENOMEM); - - if (temp & METEOR_CAP_MASK) - return(EIO); /* already capturing */ - - start_capture(mtr, METEOR_CONTIN); - - break; - case METEOR_CAP_STOP_CONT: - if (mtr->flags & METEOR_CONTIN) { - /* turn off capture */ - base->cap_cntl = 0x8ff0; - mtr->flags &= ~(METEOR_CONTIN|METEOR_WANT_MASK); - } - 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_PLANAR | METEOR_YUV_422)) /* XXX */ - return(EINVAL); /* should fix intr so we allow these */ - if (mtr->bigbuf == 0) - return(ENOMEM); - if ((mtr->frames < 2) || - (frame->lowat < 1 || frame->lowat >= mtr->frames) || - (frame->hiwat < 1 || frame->hiwat >= mtr->frames) || - (frame->lowat > frame->hiwat)) - return(EINVAL); - /* meteor_mem structure is on the page after the data */ - mem = mtr->mem = (struct meteor_mem *) (mtr->bigbuf + - (round_page(mtr->frame_size * mtr->frames))); - mtr->current = 1; - mtr->synch_wait = 0; - mem->num_bufs = mtr->frames; - mem->frame_size= mtr->frame_size; - /* user and kernel change these */ - mem->lowat = frame->lowat; - mem->hiwat = frame->hiwat; - mem->active = 0; - mem->num_active_bufs = 0; - /* Start capture */ - start_capture(mtr, METEOR_SYNCAP); - break; - case METEOR_CAP_STOP_FRAMES: - if (mtr->flags & METEOR_SYNCAP) { - /* turn off capture */ - base->cap_cntl = 0x8ff0; - mtr->flags &= ~(METEOR_SYNCAP|METEOR_WANT_MASK); - } - break; - case METEOR_HALT_N_FRAMES: - if(mtr->flags & METEOR_SYNCAP) { - base->cap_cntl = 0x8ff0; - mtr->flags &= ~(METEOR_WANT_MASK); - } - break; - case METEOR_CONT_N_FRAMES: - if(!(mtr->flags & METEOR_SYNCAP)) { - error = EINVAL; - break; - } - start_capture(mtr, METEOR_SYNCAP); - break; - default: - error = EINVAL; - break; - } - break; - - case METEORSETGEO: - geo = (struct meteor_geomet *) arg; - - /* Either even or odd, if even & odd, then these a zero */ - if((geo->oformat & METEOR_GEO_ODD_ONLY) && - (geo->oformat & METEOR_GEO_EVEN_ONLY)) { - printf("meteor%d: ioctl: Geometry odd or even only.\n", - unit); - return EINVAL; - } - /* set/clear even/odd flags */ - if(geo->oformat & METEOR_GEO_ODD_ONLY) - mtr->flags |= METEOR_ONLY_ODD_FIELDS; - else - mtr->flags &= ~METEOR_ONLY_ODD_FIELDS; - if(geo->oformat & METEOR_GEO_EVEN_ONLY) - mtr->flags |= METEOR_ONLY_EVEN_FIELDS; - else - mtr->flags &= ~METEOR_ONLY_EVEN_FIELDS; - - /* can't change parameters while capturing */ - if (mtr->flags & METEOR_CAP_MASK) - return(EBUSY); - - if ((geo->columns & 0x3fe) != geo->columns) { - printf( - "meteor%d: ioctl: %d: columns too large or not even.\n", - unit, geo->columns); - error = EINVAL; - } - if (((geo->rows & 0x7fe) != geo->rows) || - ((geo->oformat & METEOR_GEO_FIELD_MASK) && - ((geo->rows & 0x3fe) != geo->rows)) ) { - printf( - "meteor%d: ioctl: %d: rows too large or not even.\n", - unit, geo->rows); - error = EINVAL; - } - if (geo->frames > 32) { - printf("meteor%d: ioctl: too many frames.\n", unit); - error = EINVAL; - } - if(error) return error; - - if ((temp=geo->rows * geo->columns * geo->frames * 2) != 0) { - if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2; - - /* meteor_mem structure for SYNC Capture */ - if (geo->frames > 1) temp += PAGE_SIZE; - - temp = btoc(temp); - if (temp > mtr->alloc_pages -#ifdef METEOR_TEST_VIDEO - && mtr->video.addr == 0 -#endif - ) { - buf = get_meteor_mem(unit, temp*PAGE_SIZE); - if(buf != 0) { - kmem_free(kernel_map, mtr->bigbuf, - (mtr->alloc_pages * PAGE_SIZE)); - mtr->bigbuf = buf; - mtr->alloc_pages = temp; - if(bootverbose) - printf( - "meteor%d: ioctl: Allocating %d bytes\n", - unit, temp*PAGE_SIZE); - } else { - error = ENOMEM; - } - } - } - if(error) return error; - - mtr->rows = geo->rows; - mtr->cols = geo->columns; - mtr->frames = geo->frames; - -#ifdef METEOR_TEST_VIDEO - if(mtr->video.addr) - buf = vtophys(mtr->video.addr); - else -#endif - buf = vtophys(mtr->bigbuf); - - /* set defaults and end of buffer locations */ - base->dma1e = buf; - base->dma2e = buf; - base->dma3e = buf; - base->dma1o = buf; - base->dma2o = buf; - base->dma3o = buf; - base->stride1e = 0; - base->stride2e = 0; - base->stride3e = 0; - base->stride1o = 0; - base->stride2o = 0; - base->stride3o = 0; - /* set end of DMA location, even/odd */ - base->dma_end_e = - base->dma_end_o = buf + mtr->alloc_pages * PAGE_SIZE; - - /* - * Determine if we can use the hardware range detect. - */ - if(mtr->alloc_pages * PAGE_SIZE < RANGE_BOUNDARY && - ((buf & 0xff000000) | base->dma_end_e) == - (buf + mtr->alloc_pages * PAGE_SIZE) ) - mtr->range_enable = 0x8000; - else { - mtr->range_enable = 0x0; - base->dma_end_e = - base->dma_end_o = 0xffffffff; - } - - - switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) { - case 0: /* default */ - case METEOR_GEO_RGB16: - mtr->depth = 2; - mtr->frame_size = mtr->rows * mtr->cols * mtr->depth; - mtr->flags &= ~METEOR_OUTPUT_FMT_MASK; - mtr->flags |= METEOR_RGB16; - temp = mtr->cols * mtr->depth; - /* recal stride and starting point */ - switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - case METEOR_ONLY_ODD_FIELDS: - base->dma1o = buf; -#ifdef METEOR_TEST_VIDEO - if(mtr->video.addr && mtr->video.width) - base->stride1o = mtr->video.width-temp; -#endif - SAA7196_WRITE(mtr, 0x20, 0xd0); - break; - case METEOR_ONLY_EVEN_FIELDS: - base->dma1e = buf; -#ifdef METEOR_TEST_VIDEO - if(mtr->video.addr && mtr->video.width) - base->stride1e = mtr->video.width-temp; -#endif - SAA7196_WRITE(mtr, 0x20, 0xf0); - break; - default: /* interlaced even/odd */ - base->dma1e = buf; - base->dma1o = buf + temp; - base->stride1e = base->stride1o = temp; -#ifdef METEOR_TEST_VIDEO - if(mtr->video.addr && mtr->video.width) { - base->dma1o = buf + mtr->video.width; - base->stride1e = base->stride1o = - mtr->video.width - - temp + mtr->video.width; - } -#endif - SAA7196_WRITE(mtr, 0x20, 0x90); - break; - } - base->routee = base->routeo = 0xeeeeee01; - break; - case METEOR_GEO_RGB24: - mtr->depth = 4; - mtr->frame_size = mtr->rows * mtr->cols * mtr->depth; - mtr->flags &= ~METEOR_OUTPUT_FMT_MASK; - mtr->flags |= METEOR_RGB24; - temp = mtr->cols * mtr->depth; - /* recal stride and starting point */ - switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - case METEOR_ONLY_ODD_FIELDS: - base->dma1o = buf; -#ifdef METEOR_TEST_VIDEO - if(mtr->video.addr && mtr->video.width) - base->stride1o = mtr->video.width-temp; -#endif - SAA7196_WRITE(mtr, 0x20, 0xd2); - break; - case METEOR_ONLY_EVEN_FIELDS: - base->dma1e = buf; -#ifdef METEOR_TEST_VIDEO - if(mtr->video.addr && mtr->video.width) - base->stride1e = mtr->video.width-temp; -#endif - SAA7196_WRITE(mtr, 0x20, 0xf2); - break; - default: /* interlaced even/odd */ - base->dma1e = buf; - base->dma1o = buf + mtr->cols * mtr->depth; - base->stride1e = base->stride1o = - mtr->cols * mtr->depth; -#ifdef METEOR_TEST_VIDEO - if(mtr->video.addr && mtr->video.width) { - base->dma1o = buf + mtr->video.width; - base->stride1e = base->stride1o = - mtr->video.width - - temp + mtr->video.width; - } -#endif - SAA7196_WRITE(mtr, 0x20, 0x92); - break; - } - base->routee= base->routeo= 0x39393900; - break; - case METEOR_GEO_YUV_PLANAR: - mtr->depth = 2; - temp = mtr->rows * mtr->cols; /* compute frame size */ - mtr->frame_size = temp * mtr->depth; - mtr->flags &= ~METEOR_OUTPUT_FMT_MASK; - mtr->flags |= METEOR_YUV_PLANAR; - /* recal stride and starting point */ - switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - case METEOR_ONLY_ODD_FIELDS: - base->dma1o = buf; /* Y Odd */ - base->dma2o = buf + temp; /* U Odd */ - temp >>= 1; - base->dma3o = base->dma2o + temp; /* V Odd */ - SAA7196_WRITE(mtr, 0x20, 0xd1); - break; - case METEOR_ONLY_EVEN_FIELDS: - base->dma1e = buf; /* Y Even */ - base->dma2e = buf + temp; /* U Even */ - temp >>= 1; - base->dma2e= base->dma2e + temp; /* V Even */ - SAA7196_WRITE(mtr, 0x20, 0xf1); - break; - default: /* interlaced even/odd */ - base->dma1e = buf; /* Y Even */ - base->dma2e = buf + temp; /* U Even */ - temp >>= 2; - base->dma3e = base->dma2e + temp; /* V Even */ - base->dma1o = base->dma1e+mtr->cols;/* Y Odd */ - base->dma2o = base->dma3e + temp; /* U Odd */ - base->dma3o = base->dma2o + temp; /* V Odd */ - base->stride1e = base->stride1o = mtr->cols; - SAA7196_WRITE(mtr, 0x20, 0x91); - break; - } - switch (geo->oformat & - (METEOR_GEO_YUV_12 | METEOR_GEO_YUV_9)) { - case METEOR_GEO_YUV_9: - base->routee=base->routeo = 0xaaaaffc3; - break; - case METEOR_GEO_YUV_12: - base->routee=base->routeo = 0xaaaaffc2; - break; - default: - base->routee=base->routeo = 0xaaaaffc1; - break; - } - break; - case METEOR_GEO_YUV_422:/* same as planer, different uv order */ - mtr->depth = 2; - temp = mtr->rows * mtr->cols; /* compute frame size */ - mtr->frame_size = temp * mtr->depth; - mtr->flags &= ~METEOR_OUTPUT_FMT_MASK; - mtr->flags |= METEOR_YUV_422; - switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - case METEOR_ONLY_ODD_FIELDS: - base->dma1o = buf; - base->dma2o = buf + temp; - base->dma3o = base->dma2o + (temp >> 1); - SAA7196_WRITE(mtr, 0x20, 0xd1); - break; - case METEOR_ONLY_EVEN_FIELDS: - base->dma1e = buf; - base->dma2e = buf + temp; - base->dma3e = base->dma2e + (temp >> 1); - SAA7196_WRITE(mtr, 0x20, 0xf1); - break; - default: /* interlaced even/odd */ - base->dma1e = buf; /* Y even */ - base->dma2e = buf + temp; /* U even */ - base->dma3e = - base->dma2e + (temp >> 1);/* V even */ - base->dma1o = base->dma1e+mtr->cols;/* Y odd */ - temp = mtr->cols >> 1; - base->dma2o = base->dma2e+temp; /* U odd */ - base->dma3o = base->dma3e+temp; /* V odd */ - base->stride1e = - base->stride1o = mtr->cols; /* Y stride */ - base->stride2e = - base->stride2o = temp; /* U stride */ - base->stride3e = - base->stride3o = temp; /* V stride */ - SAA7196_WRITE(mtr, 0x20, 0x91); - break; - } - switch (geo->oformat & - (METEOR_GEO_YUV_12 | METEOR_GEO_YUV_9)) { - case METEOR_GEO_YUV_9: - base->routee=base->routeo = 0xaaaaffc3; - break; - case METEOR_GEO_YUV_12: - base->routee=base->routeo = 0xaaaaffc2; - break; - default: - base->routee=base->routeo = 0xaaaaffc1; - break; - } - break; - case METEOR_GEO_YUV_PACKED: - mtr->depth = 2; - mtr->frame_size = mtr->rows * mtr->cols * mtr->depth; - mtr->flags &= ~METEOR_OUTPUT_FMT_MASK; - mtr->flags |= METEOR_YUV_PACKED; - /* recal stride and odd starting point */ - switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - case METEOR_ONLY_ODD_FIELDS: - base->dma1o = buf; - SAA7196_WRITE(mtr, 0x20, 0xd1); - break; - case METEOR_ONLY_EVEN_FIELDS: - base->dma1e = buf; - SAA7196_WRITE(mtr, 0x20, 0xf1); - break; - default: /* interlaced even/odd */ - base->dma1e = buf; - base->dma1o = buf + mtr->cols * mtr->depth; - base->stride1e = base->stride1o = - mtr->cols * mtr->depth; - SAA7196_WRITE(mtr, 0x20, 0x91); - break; - } - base->routee = base->routeo = 0xeeeeee41; - break; - default: - error = EINVAL; /* invalid argument */ - printf("meteor%d: ioctl: invalid output format\n",unit); - break; - } - /* set cols */ - SAA7196_WRITE(mtr, 0x21, mtr->cols & 0xff); - SAA7196_WRITE(mtr, 0x24, - ((SAA7196_REG(mtr, 0x24) & ~0x03) | - ((mtr->cols >> 8) & 0x03))); - /* set rows */ - if(mtr->flags & METEOR_ONLY_FIELDS_MASK) { - SAA7196_WRITE(mtr, 0x25, ((mtr->rows) & 0xff)); - SAA7196_WRITE(mtr, 0x28, - ((SAA7196_REG(mtr, 0x28) & ~0x03) | - ((mtr->rows >> 8) & 0x03))); - } else { /* Interlaced */ - SAA7196_WRITE(mtr, 0x25, ((mtr->rows >> 1) & 0xff)); - SAA7196_WRITE(mtr, 0x28, - ((SAA7196_REG(mtr, 0x28) & ~0x03) | - ((mtr->rows >> 9) & 0x03))); - } - /* set signed/unsigned chrominance */ - SAA7196_WRITE(mtr, 0x30, (SAA7196_REG(mtr, 0x30) & ~0x10) | - ((geo->oformat&METEOR_GEO_UNSIGNED)?0:0x10)); - 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_OUTPUT_FMT_MASK) | - (mtr->flags & METEOR_ONLY_FIELDS_MASK) | - (SAA7196_REG(mtr, 0x30) & 0x10 ? - 0:METEOR_GEO_UNSIGNED); - switch(base->routee & 0xff) { - case 0xc3: - geo->oformat |= METEOR_GEO_YUV_9; - break; - case 0xc2: - geo->oformat |= METEOR_GEO_YUV_12; - break; - default: - break; - } - 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; - mtr->even_fields_captured = cnt->even_fields_captured; - mtr->odd_fields_captured = cnt->odd_fields_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; - cnt->even_fields_captured = mtr->even_fields_captured; - cnt->odd_fields_captured = mtr->odd_fields_captured; - break; - default: - printf("meteor%d: ioctl: invalid ioctl request\n", unit); - error = ENOTTY; - break; - } - return(error); -} - -int -meteor_mmap(dev_t dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) -{ - - int unit; - meteor_reg_t *mtr; - - unit = UNIT(minor(dev)); - if (unit >= NMETEOR) /* at this point could this happen? */ - return(-1); - - mtr = &(meteor[unit]); - - - if(nprot & PROT_EXEC) - return -1; - - if(offset >= mtr->alloc_pages * PAGE_SIZE) - return -1; - - *paddr = vtophys(mtr->bigbuf) + offset; - return 0; -} -#endif diff --git a/sys/pci/meteor_reg.h b/sys/pci/meteor_reg.h deleted file mode 100644 index a1f5ecc..0000000 --- a/sys/pci/meteor_reg.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * 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. - * - * $FreeBSD$ - */ -#ifndef PCI_LATENCY_TIMER -#define PCI_LATENCY_TIMER 0x0c /* pci timer register */ -#endif - -/* - * Definitions for the Philips SAA7116 digital video to pci interface. - */ -#define SAA7116_PHILIPS_ID 0x12238086ul -#define SAA7116_I2C_WRITE 0x00 -#define SAA7116_I2C_READ 0x01 -#define SAA7116_IIC_NEW_CYCLE 0x1000000L -#define SAA7116_IIC_DIRECT_TRANSFER_ABORTED 0x0000200L - -typedef volatile u_int mreg_t; -struct saa7116_regs { - mreg_t dma1e; /* Base address for even field dma chn 1 */ - mreg_t dma2e; /* Base address for even field dma chn 2 */ - mreg_t dma3e; /* Base address for even field dma chn 3 */ - mreg_t dma1o; /* Base address for odd field dma chn 1 */ - mreg_t dma2o; /* Base address for odd field dma chn 2 */ - mreg_t dma3o; /* Base address for odd field dma chn 3 */ - mreg_t stride1e; /* Address stride for even field dma chn 1 */ - mreg_t stride2e; /* Address stride for even field dma chn 2 */ - mreg_t stride3e; /* Address stride for even field dma chn 3 */ - mreg_t stride1o; /* Address stride for odd field dma chn 1 */ - mreg_t stride2o; /* Address stride for odd field dma chn 2 */ - mreg_t stride3o; /* Address stride for odd field dma chn 3 */ - mreg_t routee; /* Route/mode even */ - mreg_t routeo; /* Route/mode odd */ - mreg_t fifo_t; /* FIFO trigger for PCI int */ - mreg_t field_t; /* Field toggle */ - mreg_t cap_cntl; /* Capture control */ - mreg_t retry_wait_cnt; /* Clks for master to wait after disconnect */ - mreg_t irq_stat; /* IRQ mask and status reg */ - mreg_t fme; /* Field Mask even */ - mreg_t fmo; /* Field mask odd */ - mreg_t fml; /* Field mask length */ - mreg_t fifo_t_err; /* FIFO almost empty/almost full ptrs */ - mreg_t i2c_phase; /* i2c phase register */ - mreg_t i2c_read; /* i2c read register */ - mreg_t i2c_write; /* i2c write register */ - mreg_t i2c_auto_a_e; /* i2c auto register a, even */ - mreg_t i2c_auto_b_e; /* i2c auto register b, even */ - mreg_t i2c_auto_c_e; /* i2c auto register c, even */ - mreg_t i2c_auto_d_e; /* i2c auto register d, even */ - mreg_t i2c_auto_a_o; /* i2c auto register a, odd */ - mreg_t i2c_auto_b_o; /* i2c auto register b, odd */ - mreg_t i2c_auto_c_o; /* i2c auto register c, odd */ - mreg_t i2c_auto_d_o; /* i2c auto register d, odd */ - mreg_t i2c_auto_enable;/* enable above auto registers */ - mreg_t dma_end_e; /* DMA end even (range) */ - mreg_t dma_end_o; /* DMA end odd (range) */ -}; - - -/* - * Definitions for the Philips SAA7196 digital video decoder, - * scalar, and clock generator circuit (DESCpro). - */ -#define NUM_SAA7196_I2C_REGS 49 -#define SAA7196_I2C_ADDR 0x40 -#define SAA7196_WRITE(mtr, reg, data) \ - i2c_write(mtr, SAA7196_I2C_ADDR, SAA7116_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, SAA7116_I2C_READ, 0x0, 0x0) - -#define SAA7196_IDEL 0x00 /* Increment delay */ -#define SAA7196_HSB5 0x01 /* H-sync begin; 50 hz */ -#define SAA7196_HSS5 0x02 /* H-sync stop; 50 hz */ -#define SAA7196_HCB5 0x03 /* H-clamp begin; 50 hz */ -#define SAA7196_HCS5 0x04 /* H-clamp stop; 50 hz */ -#define SAA7196_HSP5 0x05 /* H-sync after PHI1; 50 hz */ -#define SAA7196_LUMC 0x06 /* Luminance control */ -#define SAA7196_HUEC 0x07 /* Hue control */ -#define SAA7196_CKTQ 0x08 /* Colour Killer Threshold QAM (PAL, NTSC) */ -#define SAA7196_CKTS 0x09 /* Colour Killer Threshold SECAM */ -#define SAA7196_PALS 0x0a /* PAL switch sensitivity */ -#define SAA7196_SECAMS 0x0b /* SECAM switch sensitivity */ -#define SAA7196_CGAINC 0x0c /* Chroma gain control */ -#define SAA7196_STDC 0x0d /* Standard/Mode control */ -#define SAA7196_IOCC 0x0e /* I/O and Clock Control */ -#define SAA7196_CTRL1 0x0f /* Control #1 */ -#define SAA7196_CTRL2 0x10 /* Control #2 */ -#define SAA7196_CGAINR 0x11 /* Chroma Gain Reference */ -#define SAA7196_CSAT 0x12 /* Chroma Saturation */ -#define SAA7196_CONT 0x13 /* Luminance Contrast */ -#define SAA7196_HSB6 0x14 /* H-sync begin; 60 hz */ -#define SAA7196_HSS6 0x15 /* H-sync stop; 60 hz */ -#define SAA7196_HCB6 0x16 /* H-clamp begin; 60 hz */ -#define SAA7196_HCS6 0x17 /* H-clamp stop; 60 hz */ -#define SAA7196_HSP6 0x18 /* H-sync after PHI1; 60 hz */ -#define SAA7196_BRIG 0x19 /* Luminance Brightness */ -#define SAA7196_FMTS 0x20 /* Formats and sequence */ -#define SAA7196_OUTPIX 0x21 /* Output data pixel/line */ -#define SAA7196_INPIX 0x22 /* Input data pixel/line */ -#define SAA7196_HWS 0x23 /* Horiz. window start */ -#define SAA7196_HFILT 0x24 /* Horiz. filter */ -#define SAA7196_OUTLINE 0x25 /* Output data lines/field */ -#define SAA7196_INLINE 0x26 /* Input data lines/field */ -#define SAA7196_VWS 0x27 /* Vertical window start */ -#define SAA7196_VYP 0x28 /* AFS/vertical Y processing */ -#define SAA7196_VBS 0x29 /* Vertical Bypass start */ -#define SAA7196_VBCNT 0x2a /* Vertical Bypass count */ -#define SAA7196_VBP 0x2b /* veritcal Bypass Polarity */ -#define SAA7196_VLOW 0x2c /* Colour-keying lower V limit */ -#define SAA7196_VHIGH 0x2d /* Colour-keying upper V limit */ -#define SAA7196_ULOW 0x2e /* Colour-keying lower U limit */ -#define SAA7196_UHIGH 0x2f /* Colour-keying upper U limit */ -#define SAA7196_DPATH 0x30 /* Data path setting */ - -/* - * Defines for the PCF8574. - */ -#define NUM_PCF8574_I2C_REGS 2 -#define PCF8574_CTRL_I2C_ADDR 0x70 -#define PCF8574_DATA_I2C_ADDR 0x72 -#define PCF8574_CTRL_WRITE(mtr, data) \ - i2c_write(mtr, PCF8574_CTRL_I2C_ADDR, SAA7116_I2C_WRITE, data, data), \ - mtr->pcf_i2c[0] = data -#define PCF8574_DATA_WRITE(mtr, data) \ - i2c_write(mtr, PCF8574_DATA_I2C_ADDR, SAA7116_I2C_WRITE, data, data), \ - mtr->pcf_i2c[1] = data -#define PCF8574_CTRL_REG(mtr) mtr->pcf_i2c[0] -#define PCF8574_DATA_REG(mtr) mtr->pcf_i2c[1] - - -/* - * Defines for the BT254. - */ -#define NUM_BT254_REGS 7 - -#define BT254_COMMAND 0 -#define BT254_IOUT1 1 -#define BT254_IOUT2 2 -#define BT254_IOUT3 3 -#define BT254_IOUT4 4 -#define BT254_IOUT5 5 -#define BT254_IOUT6 6 - -/* - * Meteor info structure, one per meteor card installed. - */ -typedef struct meteor_softc { - struct saa7116_regs *base; /* saa7116 register virtual address */ - vm_offset_t phys_base; /* saa7116 register physical address */ - 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 */ - int signal; /* signal to send to process */ -#define METEOR_SIG_MODE_MASK 0xffff0000 -#define METEOR_SIG_FIELD_MODE 0x00010000 -#define METEOR_SIG_FRAME_MODE 0x00000000 - struct meteor_mem *mem; /* used to control sync. multi-frame output */ - u_long synch_wait; /* wait for free buffer before continuing */ - short current; /* 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 */ - u_long even_fields_captured; /* number of even fields captured */ - u_long odd_fields_captured; /* number of odd fields captured */ - u_long range_enable; /* enable range checking ?? */ - unsigned flags; -#define METEOR_INITALIZED 0x00000001 -#define METEOR_OPEN 0x00000002 -#define METEOR_MMAP 0x00000004 -#define METEOR_INTR 0x00000008 -#define METEOR_READ 0x00000010 /* XXX never gets referenced */ -#define METEOR_SINGLE 0x00000020 /* get single frame */ -#define METEOR_CONTIN 0x00000040 /* continuously get frames */ -#define METEOR_SYNCAP 0x00000080 /* synchronously get frames */ -#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_SVIDEO 0x00006000 -#define METEOR_DEV_RGB 0x0000a000 -#define METEOR_DEV_MASK 0x0000f000 -#define METEOR_RGB16 0x00010000 -#define METEOR_RGB24 0x00020000 -#define METEOR_YUV_PACKED 0x00040000 -#define METEOR_YUV_PLANAR 0x00080000 -#define METEOR_WANT_EVEN 0x00100000 /* want even frame */ -#define METEOR_WANT_ODD 0x00200000 /* want odd frame */ -#define METEOR_WANT_MASK 0x00300000 -#define METEOR_ONLY_EVEN_FIELDS 0x01000000 -#define METEOR_ONLY_ODD_FIELDS 0x02000000 -#define METEOR_ONLY_FIELDS_MASK 0x03000000 -#define METEOR_YUV_422 0x04000000 -#define METEOR_OUTPUT_FMT_MASK 0x040f0000 -#define METEOR_WANT_TS 0x08000000 /* time-stamp a frame */ -#define METEOR_RGB 0x20000000 /* meteor rgb unit */ -#define METEOR_FIELD_MODE 0x80000000 - u_char saa7196_i2c[NUM_SAA7196_I2C_REGS]; /* saa7196 register values */ - u_char pcf_i2c[NUM_PCF8574_I2C_REGS]; /* PCF8574 register values */ - u_char bt254_reg[NUM_BT254_REGS]; /* BT254 register values */ - u_short fps; /* frames per second */ -#ifdef METEOR_TEST_VIDEO - struct meteor_video video; -#endif -} meteor_reg_t; |