diff options
| author | Roger Hardiman <roger@FreeBSD.org> | 1999-08-31 10:29:42 +0000 |
|---|---|---|
| committer | Roger Hardiman <roger@FreeBSD.org> | 1999-08-31 10:29:42 +0000 |
| commit | 2271cf26df5cbaa7d2a86c33d20c7a92c0479f16 (patch) | |
| tree | 6f08896439404a3bca7c4625498b49469847b614 /sys/pci | |
| parent | 8e831169b9417412b5105ebb23ed7fb68adc25dc (diff) | |
Notes
Diffstat (limited to 'sys/pci')
| -rw-r--r-- | sys/pci/brktree_reg.h | 12 | ||||
| -rw-r--r-- | sys/pci/brooktree848.c | 825 |
2 files changed, 274 insertions, 563 deletions
diff --git a/sys/pci/brktree_reg.h b/sys/pci/brktree_reg.h index 643d3f353f58..7449a393cce6 100644 --- a/sys/pci/brktree_reg.h +++ b/sys/pci/brktree_reg.h @@ -30,7 +30,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD$ + * $Id: brktree_reg.h,v 1.29 1999/06/12 14:54:56 roger Exp $ */ #ifndef PCI_LATENCY_TIMER #define PCI_LATENCY_TIMER 0x0c /* pci timer register */ @@ -412,6 +412,8 @@ struct bktr_softc { bus_dmamap_t dm_prog; bus_dmamap_t dm_oprog; bus_dmamap_t dm_mem; + bus_dmamap_t dm_vbidata; + bus_dmamap_t dm_vbibuffer; vm_offset_t phys_base; /* Bt848 register physical address */ #endif @@ -425,6 +427,8 @@ struct bktr_softc { bus_dmamap_t dm_prog; bus_dmamap_t dm_oprog; bus_dmamap_t dm_mem; + bus_dmamap_t dm_vbidata; + bus_dmamap_t dm_vbibuffer; size_t dm_mapsize; pci_chipset_tag_t pc; /* Opaque PCI chipset tag */ pcitag_t tag; /* PCI tag, for doing PCI commands */ @@ -450,11 +454,17 @@ struct bktr_softc { bt848_ptr_t base; /* Bt848 register physical address */ vm_offset_t bigbuf; /* buffer that holds the captured image */ int alloc_pages; /* number of pages in bigbuf */ + vm_offset_t vbidata; /* RISC program puts VBI data from the current frame here */ vm_offset_t vbibuffer; /* Circular buffer holding VBI data for the user */ int vbiinsert; /* Position for next write into circular buffer */ int vbistart; /* Position of last read from circular buffer */ int vbisize; /* Number of bytes in the circular buffer */ + u_long vbi_sequence_number; /* sequence number for VBI */ + int vbi_read_blocked; /* user process blocked on read() from /dev/vbi */ + struct selinfo vbi_select; /* Data used by select() on /dev/vbi */ + + struct proc *proc; /* process to receive raised signal */ int signal; /* signal to send to process */ int clr_on_start; /* clear cap buf on capture start? */ diff --git a/sys/pci/brooktree848.c b/sys/pci/brooktree848.c index 71c38fd2c311..b0df4cc23a52 100644 --- a/sys/pci/brooktree848.c +++ b/sys/pci/brooktree848.c @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $Id: brooktree848.c,v 1.85 1999/06/12 14:54:54 roger Exp $ */ /* BT848 Driver for Brooktree's Bt848, Bt848A, Bt849A, Bt878, Bt879 based cards. The Brooktree BT848 Driver driver is based upon Mark Tinguely and Jim Lowe's driver for the Matrox Meteor PCI card . The @@ -439,12 +439,22 @@ They are unrelated to Revision Control numbering of FreeBSD or any other system. Added TDA9850 initialisation code taken from Linux bttv. Juha.Nurmela@quicknet.inet.fi found/fixed bug in VBI_SLEEP. Matt Brown <matt@dqc.org> added MSP3430G DBX initialisation. + +1.71 30 Aug 1999 Roger Hardiman <roger@freebsd.org> + Small cleanup of OS dependant code. Remove NPCI usage. + Fix bug in AVerMedia detection. + Update VBI support for the AleVT Teletext package. Parts + from Juha Nurmela's driver <Juha.Nurmela@quicknet.inet.fi> + Add support for Hauppauge 627 and Temic 4006 submitted + by Maurice Castro <maurice@atum.castro.aus.net> + Tom Jansen <tom@unhooked.net> added BSDi support again. + */ #ifdef __FreeBSD__ #include "bktr.h" #include "opt_bktr.h" -#include "pci.h" +#include "opt_devfs.h" #endif /* __FreeBSD__ */ #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -453,7 +463,7 @@ They are unrelated to Revision Control numbering of FreeBSD or any other system. #endif /* __NetBSD__ || __OpenBSD__ */ #if ( \ - ( (defined(__FreeBSD__)) && (NBKTR > 0) && (NPCI > 0) ) \ + (defined(__FreeBSD__) && (NBKTR > 0)) \ || (defined(__bsdi__)) \ || (defined(__OpenBSD__)) \ || (defined(__NetBSD__)) \ @@ -466,6 +476,9 @@ They are unrelated to Revision Control numbering of FreeBSD or any other system. #include <sys/kernel.h> #include <sys/signalvar.h> #include <sys/mman.h> +#include <sys/poll.h> +#include <sys/select.h> +#include <sys/vnode.h> #include <vm/vm.h> #include <vm/vm_kern.h> @@ -479,19 +492,25 @@ They are unrelated to Revision Control numbering of FreeBSD or any other system. /* Read NSMBUS on FreeBSD 3.1 or later */ #if (__FreeBSD_version >= 310000) - #include "smbus.h" +#include "smbus.h" #else - #define NSMBUS 0 +#define NSMBUS 0 +#endif + +#if (__FreeBSD_version < 400000) +#ifdef DEVFS +#include <sys/devfsext.h> +#endif /* DEVFS */ #endif #if (__FreeBSD_version >=400000) || (NSMBUS > 0) - #include <sys/bus.h> /* used by smbus and newbus */ +#include <sys/bus.h> /* used by smbus and newbus */ #endif #if (__FreeBSD_version >=400000) - #include <machine/bus.h> /* used by newbus */ - #include <sys/rman.h> /* used by newbus */ - #include <machine/resource.h> /* used by newbus */ +#include <machine/bus.h> /* used by newbus */ +#include <sys/rman.h> /* used by newbus */ +#include <machine/resource.h> /* used by newbus */ #endif #include <machine/clock.h> /* for DELAY */ @@ -503,11 +522,11 @@ They are unrelated to Revision Control numbering of FreeBSD or any other system. #include <pci/brktree_reg.h> #if (NSMBUS > 0) - #include <pci/bt848_i2c.h> - #include <dev/smbus/smbconf.h> - #include <dev/iicbus/iiconf.h> - #include "smbus_if.h" - #include "iicbus_if.h" +#include <pci/bt848_i2c.h> +#include <dev/smbus/smbconf.h> +#include <dev/iicbus/iiconf.h> +#include "smbus_if.h" +#include "iicbus_if.h" #endif #include <sys/sysctl.h> @@ -527,16 +546,32 @@ SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, ""); #endif #if (__FreeBSD__ == 2) - typedef int ioctl_cmd_t; - typedef unsigned int uintptr_t; - #define PCIR_REVID PCI_CLASS_REG +typedef int ioctl_cmd_t; +typedef unsigned int uintptr_t; +#define PCIR_REVID PCI_CLASS_REG #endif #endif /* __FreeBSD__ */ +/****************/ +/* *** BSDI *** */ +/****************/ +#ifdef __bsdi__ +#endif /* __bsdi__ */ + + +/**************************/ +/* *** OpenBSD/NetBSD *** */ +/**************************/ +#if defined(__NetBSD__) || defined(__OpenBSD__) +#endif /* __NetBSD__ || __OpenBSD__ */ + + + typedef u_char bool_t; #define BKTRPRI (PZERO+8)|PCATCH +#define VBIPRI (PZERO-4)|PCATCH /* @@ -935,7 +970,7 @@ static const struct TUNER tuners[] = { { 0x00, 0x00 }, /* band-switch crosspoints */ { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */ - /* PHILIPS_PAL */ + /* PHILIPS_PALI */ { "Philips PAL I", /* the 'name' */ TTYPE_PAL, /* input type */ { TSA552x_SCONTROL, /* control byte for Tuner PLL */ @@ -1214,7 +1249,7 @@ static u_long status_sum = 0; */ static int signCard( bktr_ptr_t bktr, int offset, int count, u_char* sig ); -static void probeCard( bktr_ptr_t bktr, int verbose ); +static void probeCard( bktr_ptr_t bktr, int verbose, int unit); static void common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ); @@ -1293,7 +1328,7 @@ static int do_afc( bktr_ptr_t bktr, int addr, int frequency ); */ static int vbi_open( bktr_ptr_t bktr ); static int vbi_close( bktr_ptr_t bktr ); -static int vbi_read( bktr_ptr_t bktr, dev_t dev, struct uio *uio ); +static int vbi_read( bktr_ptr_t bktr, struct uio *uio, int ioflag ); /* * audio specific functions. @@ -1305,7 +1340,7 @@ static void init_BTSC( bktr_ptr_t bktr ); static int set_BTSC( bktr_ptr_t bktr, int control ); static void msp_autodetect( bktr_ptr_t bktr ); -static void msp_read_id( bktr_ptr_t bktr ); +static void msp_read_id( bktr_ptr_t bktr, int unit ); static void msp_reset( bktr_ptr_t bktr ); static unsigned int msp_read(bktr_ptr_t bktr, unsigned char dev, unsigned int addr); @@ -1354,7 +1389,7 @@ static void bctv_gpio_write( bktr_ptr_t bktr, int port, int val ); /* - * the common attarch code, used by all OS versions. + * the common attach code, used by all OS versions. */ static void common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ) @@ -1369,13 +1404,12 @@ common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ) /***************************************/ #if defined(__NetBSD__) || defined(__OpenBSD__) /* allocate space for dma program */ - bktr->dmat = pa->pa_dmat; bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog, DMA_PROG_ALLOC); bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog, DMA_PROG_ALLOC) ; /* allocte space for the VBI buffer */ - bktr->vbidata = get_bktr_mem(bktr, &bktr->vbidata, VBI_DATA_SIZE); - bktr->vbibuffer = get_bktr_mem(bktr, &bktr->vbibuffer, VBI_BUFFER_SIZE); + bktr->vbidata = get_bktr_mem(bktr, &bktr->dm_vbidata, VBI_DATA_SIZE); + bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer, VBI_BUFFER_SIZE); /* allocate space for pixel buffer */ if ( BROOKTREE_ALLOC ) @@ -1462,11 +1496,11 @@ common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ) bktr->bt848_tuner = -1; bktr->reverse_mute = -1; - probeCard( bktr, TRUE ); + probeCard( bktr, TRUE, unit ); /* If there is an MSP Audio device, reset it and display the model */ if (bktr->card.msp3400c)msp_reset(bktr); - if (bktr->card.msp3400c)msp_read_id(bktr); + if (bktr->card.msp3400c)msp_read_id(bktr, unit); } @@ -1479,6 +1513,7 @@ common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev ) */ static void vbidecode(bktr_ptr_t bktr) { unsigned char *dest; + unsigned int *seq_dest; /* Check if there is room in the buffer to insert the data. */ if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return; @@ -1486,10 +1521,19 @@ static void vbidecode(bktr_ptr_t bktr) { /* Copy the VBI data into the next free slot in the buffer. */ /* 'dest' is the point in vbibuffer where we want to insert new data */ dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert; - - /* block copy the vbi data into the buffer */ memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE); + /* Write the VBI sequence number to the end of the vbi data */ + /* This is used by the AleVT teletext program */ + seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer + bktr->vbiinsert + + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number))); + *seq_dest = bktr->vbi_sequence_number; + + /* And increase the VBI sequence number */ + /* This can wrap around */ + bktr->vbi_sequence_number++; + + /* Increment the vbiinsert pointer */ /* This can wrap around */ bktr->vbiinsert += VBI_DATA_SIZE; @@ -1497,6 +1541,7 @@ static void vbidecode(bktr_ptr_t bktr) { /* And increase the amount of vbi data in the buffer */ bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE; + } @@ -1554,16 +1599,15 @@ common_bktr_intr( void *arg ) /* if risc was disabled re-start process again */ + /* if there was one of the following errors re-start again */ if ( !(bktr_status & BT848_INT_RISC_EN) || - ((bktr_status &(BT848_INT_FBUS | - BT848_INT_FTRGT | - BT848_INT_FDSR | + ((bktr_status &(/* BT848_INT_FBUS | */ + /* BT848_INT_FTRGT | */ + /* BT848_INT_FDSR | */ BT848_INT_PPERR | - BT848_INT_RIPERR | - BT848_INT_PABORT | - BT848_INT_OCERR | - BT848_INT_SCERR) ) != 0) || - ((bt848->tdec == 0) && (bktr_status & TDEC_BITS)) ) { + BT848_INT_RIPERR | BT848_INT_PABORT | + BT848_INT_OCERR | BT848_INT_SCERR) ) != 0) + || ((bt848->tdec == 0) && (bktr_status & TDEC_BITS)) ) { u_short tdec_save = bt848->tdec; @@ -1621,11 +1665,39 @@ common_bktr_intr( void *arg ) if (!(bktr->flags & METEOR_CAP_MASK)) bt848->cap_ctl = CAPTURE_OFF; + + /* Determine which field generated this interrupt */ + field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F; + + + /* + * Process the VBI data if it is being captured. We do this once + * both Odd and Even VBI data is captured. Therefore we do this + * in the Even field interrupt handler. + */ + if ((bktr->vbiflags & VBI_CAPTURE)&&(field==EVEN_F)) { + /* Put VBI data into circular buffer */ + vbidecode(bktr); + + /* If someone is blocked on reading from /dev/vbi, wake them */ + if (bktr->vbi_read_blocked) { + bktr->vbi_read_blocked = FALSE; + wakeup(VBI_SLEEP); + } + + /* If someone has a select() on /dev/vbi, inform them */ + if (bktr->vbi_select.si_pid) { + selwakeup(&bktr->vbi_select); + } + + + } + + /* * Register the completed field * (For dual-field mode, require fields from the same frame) */ - field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F; switch ( bktr->flags & METEOR_WANT_MASK ) { case METEOR_WANT_ODD : w_field = ODD_F ; break; case METEOR_WANT_EVEN : w_field = EVEN_F ; break; @@ -1691,13 +1763,6 @@ common_bktr_intr( void *arg ) } } - /* - * Process the VBI data if it is being captured - */ - if (bktr->vbiflags & VBI_CAPTURE) { - vbidecode(bktr); - wakeup(VBI_SLEEP); - } /* * Wake up the user in single capture mode. @@ -1881,6 +1946,8 @@ vbi_open( bktr_ptr_t bktr ) bktr->vbiinsert = 0; bktr->vbistart = 0; bktr->vbisize = 0; + bktr->vbi_sequence_number = 0; + bktr->vbi_read_blocked = FALSE; bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE); bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE); @@ -2040,39 +2107,53 @@ video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio) * vbisize is the exact number of bytes in the buffer left to read */ static int -vbi_read(bktr_ptr_t bktr, dev_t dev, struct uio *uio) +vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag) { int readsize, readsize2; int status; - if(bktr->vbisize == 0) - status = tsleep(VBI_SLEEP, BKTRPRI, "vbi", 0); + while(bktr->vbisize == 0) { + if (ioflag & IO_NDELAY) { + return EWOULDBLOCK; + } + + bktr->vbi_read_blocked = TRUE; + if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) { + return status; + } + } + + /* Now we have some data to give to the user */ + + /* We cannot read more bytes than there are in + * the circular buffer + */ readsize = (int)uio->uio_iov->iov_len; - /* We cannot read more bytes than there are in the circular buffer */ if (readsize > bktr->vbisize) readsize = bktr->vbisize; - /* Check if we can read this number of bytes without having to wrap around the circular buffer */ + /* Check if we can read this number of bytes without having + * to wrap around the circular buffer */ if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) { /* We need to wrap around */ - readsize2 = VBI_BUFFER_SIZE - bktr->vbistart; - status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio); - status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio); - } else { + readsize2 = VBI_BUFFER_SIZE - bktr->vbistart; + status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio); + status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio); + } else { /* We do not need to wrap around */ - status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio); - } + status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio); + } /* Update the number of bytes left to read */ - bktr->vbisize -= readsize; + bktr->vbisize -= readsize; /* Update vbistart */ - bktr->vbistart += readsize; + bktr->vbistart += readsize; bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */ - return( status ); +return( status ); } @@ -2090,7 +2171,7 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr ) unsigned int temp_iform; unsigned int error; struct meteor_geomet *geo; - struct meteor_counts *cnt; + struct meteor_counts *counts; struct meteor_video *video; struct bktr_capture_area *cap_area; vm_offset_t buf; @@ -2253,21 +2334,21 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr ) break; case METEORSCOUNT: /* (re)set error counts */ - cnt = (struct meteor_counts *) arg; - bktr->fifo_errors = cnt->fifo_errors; - bktr->dma_errors = cnt->dma_errors; - bktr->frames_captured = cnt->frames_captured; - bktr->even_fields_captured = cnt->even_fields_captured; - bktr->odd_fields_captured = cnt->odd_fields_captured; + counts = (struct meteor_counts *) arg; + bktr->fifo_errors = counts->fifo_errors; + bktr->dma_errors = counts->dma_errors; + bktr->frames_captured = counts->frames_captured; + bktr->even_fields_captured = counts->even_fields_captured; + bktr->odd_fields_captured = counts->odd_fields_captured; break; case METEORGCOUNT: /* get error counts */ - cnt = (struct meteor_counts *) arg; - cnt->fifo_errors = bktr->fifo_errors; - cnt->dma_errors = bktr->dma_errors; - cnt->frames_captured = bktr->frames_captured; - cnt->even_fields_captured = bktr->even_fields_captured; - cnt->odd_fields_captured = bktr->odd_fields_captured; + counts = (struct meteor_counts *) arg; + counts->fifo_errors = bktr->fifo_errors; + counts->dma_errors = bktr->dma_errors; + counts->frames_captured = bktr->frames_captured; + counts->even_fields_captured = bktr->even_fields_captured; + counts->odd_fields_captured = bktr->odd_fields_captured; break; case METEORGVIDEO: @@ -3482,6 +3563,7 @@ rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) volatile u_long target_buffer, buffer, target,width; volatile u_long pitch; volatile u_long *dma_prog; + vm_offset_t loop_point; struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; u_int Bpp = pf_int->public.Bpp; unsigned int vbisamples; /* VBI samples per line */ @@ -3535,10 +3617,17 @@ rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) buffer = target_buffer; + /* Wait for the VRE sync marking the end of the Even and + * the start of the Odd field. Resync here. + */ + *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE; + *dma_prog++ = 0; + + loop_point = dma_prog; /* store the VBI data */ /* look for sync with packed data */ - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; + *dma_prog++ = OP_SYNC | BKTR_FM1; *dma_prog++ = 0; for(i = 0; i < vbilines; i++) { *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples; @@ -3546,97 +3635,67 @@ rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) (i * VBI_LINE_SIZE)); } - /* store the video image */ - /* look for sync with packed data */ - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; - *dma_prog++ = 0; /* NULL WORD */ - width = cols; - for (i = 0; i < (rows/interlace); i++) { - target = target_buffer; - if ( notclipped(bktr, i, width)) { - split(bktr, (volatile u_long **) &dma_prog, - bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); - - } else { - while(getline(bktr, i)) { - if (bktr->y != bktr->y2 ) { + if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) { + /* store the Odd field video image */ + /* look for sync with packed data */ + *dma_prog++ = OP_SYNC | BKTR_FM1; + *dma_prog++ = 0; /* NULL WORD */ + width = cols; + for (i = 0; i < (rows/interlace); i++) { + target = target_buffer; + if ( notclipped(bktr, i, width)) { split(bktr, (volatile u_long **) &dma_prog, bktr->y2 - bktr->y, OP_WRITE, - Bpp, (volatile u_char **) &target, cols); - } - if (bktr->yclip != bktr->yclip2 ) { - split(bktr,(volatile u_long **) &dma_prog, - bktr->yclip2 - bktr->yclip, - OP_SKIP, Bpp, (volatile u_char **) &target, cols); + + } else { + while(getline(bktr, i)) { + if (bktr->y != bktr->y2 ) { + split(bktr, (volatile u_long **) &dma_prog, + bktr->y2 - bktr->y, OP_WRITE, + Bpp, (volatile u_char **) &target, cols); + } + if (bktr->yclip != bktr->yclip2 ) { + split(bktr,(volatile u_long **) &dma_prog, + bktr->yclip2 - bktr->yclip, + OP_SKIP, + Bpp, (volatile u_char **) &target, cols); + } + } + } + + target_buffer += interlace * pitch; + } - } - - target_buffer += interlace * pitch; - - } - - switch (i_flag) { - case 1: - /* EVEN field grabs. Look for end of 'Even Field' Marker - * We cannot look for VRO, because we have not enabled ODD - * field capture - */ - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); - return; + } /* end if */ - case 2: - /* ODD field grabs. Look for end of 'Odd Field' Marker - * We cannot look for VRE, because we have not enabled EVEN - * field capture - */ - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; - *dma_prog++ = 0; /* NULL WORD */ - - *dma_prog++ = OP_JUMP; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); - return; - - case 3: - /* INTERLACED grabs (ODD then EVEN). We have read the old field - * so look for the end of 'Odd Field' Marker. - * Then jump to the 'odd_dma_prog' which actually captures - * the EVEN field! - */ - *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; - *dma_prog++ = 0; /* NULL WORD */ + /* Grab the Even field */ + /* Look for the VRO, end of Odd field, marker */ + *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; + *dma_prog++ = 0; /* NULL WORD */ - *dma_prog++ = OP_JUMP; - *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); - break; + /* store the VBI data */ + /* look for sync with packed data */ + *dma_prog++ = OP_SYNC | BKTR_FM1; + *dma_prog++ = 0; + for(i = 0; i < vbilines; i++) { + *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples; + *dma_prog++ = (u_long) vtophys(bktr->vbidata + + ((i+MAX_VBI_LINES) * VBI_LINE_SIZE)); } - if (interlace == 2) { - - target_buffer = buffer + pitch; - - dma_prog = (u_long *) bktr->odd_dma_prog; + /* store the video image */ + if (i_flag == 1) /*Even Only*/ + target_buffer = buffer; + if (i_flag == 3) /*interlaced*/ + target_buffer = buffer+pitch; - /* store the VBI data */ - /* look for sync with packed data */ - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; - *dma_prog++ = 0; - for(i = 0; i < vbilines; i++) { - *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples; - *dma_prog++ = (u_long) vtophys(bktr->vbidata + - ((i+MAX_VBI_LINES) * VBI_LINE_SIZE)); - } - /* store the video image */ + if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) { /* look for sync with packed data */ - *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; + *dma_prog++ = OP_SYNC | BKTR_FM1; *dma_prog++ = 0; /* NULL WORD */ width = cols; for (i = 0; i < (rows/interlace); i++) { @@ -3673,7 +3732,7 @@ rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) *dma_prog++ = 0; /* NULL WORD */ *dma_prog++ = OP_JUMP ; - *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; + *dma_prog++ = (u_long ) vtophys(loop_point) ; *dma_prog++ = 0; /* NULL WORD */ } @@ -4363,6 +4422,8 @@ build_dma_prog( bktr_ptr_t bktr, char i_flag ) if (i_flag==2) bktr->bktr_cap_ctl |= BT848_CAP_CTL_VBI_ODD; if (i_flag==3) bktr->bktr_cap_ctl |= BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD; + bktr->bktr_cap_ctl |= + BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD; bktr->vbiflags |= VBI_CAPTURE; rgb_vbi_prog(bktr, i_flag, cols, rows, interlace); return; @@ -5248,13 +5309,13 @@ static int locate_eeprom_address( bktr_ptr_t bktr) { * stereo chips. */ -#define VENDOR_AVER_MEDIA 0x1431 +#define VENDOR_AVER_MEDIA 0x1461 #define VENDOR_HAUPPAUGE 0x0070 #define VENDOR_FLYVIDEO 0x1851 #define VENDOR_STB 0x10B4 static void -probeCard( bktr_ptr_t bktr, int verbose ) +probeCard( bktr_ptr_t bktr, int verbose, int unit ) { int card, i,j, card_found; int status; @@ -5567,7 +5628,7 @@ checkTuner: 1a Temic 4036FY5 MN - FI1236 MK2 clone 1b Samsung TCPN9082D MN 1c Samsung TCPM9092P Pal BG/I/DK - 1d Temic 4006FH5 BG + 1d Temic 4006FH5 BG PHILIPS_PALI clone 1e Samsung TCPN9085D MN/Radio 1f Samsung TCPB9085P Pal BG/I/DK / Radio 20 Samsung TCPL9091P Pal BG & Secam L/L' @@ -5585,7 +5646,8 @@ checkTuner: model = (eeprom[12] << 8 | eeprom[11]); revision = (eeprom[15] << 16 | eeprom[14] << 8 | eeprom[13]); if (verbose) - printf("Hauppauge Model %d %c%c%c%c\n", + printf("bktr%d: Hauppauge Model %d %c%c%c%c\n", + unit, model, ((revision >> 18) & 0x3f) + 32, ((revision >> 12) & 0x3f) + 32, @@ -5610,6 +5672,7 @@ checkTuner: case 0x8: case 0xb: + case 0x1d: bktr->card.tuner = &tuners[ PHILIPS_PALI ]; goto checkDBX; @@ -6677,7 +6740,7 @@ bctv_gpio_read( bktr_ptr_t bktr, int port ) */ /* Read the MSP version string */ -static void msp_read_id( bktr_ptr_t bktr ){ +static void msp_read_id( bktr_ptr_t bktr, int unit ){ int rev1=0, rev2=0; rev1 = msp_read(bktr, 0x12, 0x001e); rev2 = msp_read(bktr, 0x12, 0x001f); @@ -6685,7 +6748,7 @@ static void msp_read_id( bktr_ptr_t bktr ){ sprintf(bktr->msp_version_string, "34%02d%c-%c%d", (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); - printf("Detected a MSP%s\n",bktr->msp_version_string); + printf("bktr%d: Detected a MSP%s\n",unit,bktr->msp_version_string); } @@ -6760,6 +6823,7 @@ static d_read_t bktr_read; static d_write_t bktr_write; static d_ioctl_t bktr_ioctl; static d_mmap_t bktr_mmap; +static d_poll_t bktr_poll; #define CDEV_MAJOR 92 static struct cdevsw bktr_cdevsw = { @@ -6771,7 +6835,7 @@ static struct cdevsw bktr_cdevsw = { /* stop */ nostop, /* reset */ noreset, /* devtotty */ nodevtotty, - /* poll */ nopoll, + /* poll */ bktr_poll, /* mmap */ bktr_mmap, /* strategy */ nostrategy, /* name */ "bktr", @@ -7076,7 +7140,7 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) ( (bt848_card & 0xff) < Bt848_MAX_CARD )) { if ( bktr->bt848_card != (bt848_card & 0xff) ) { bktr->bt848_card = (bt848_card & 0xff); - probeCard(bktr, FALSE); + probeCard(bktr, FALSE, unit); } } } @@ -7086,7 +7150,7 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) { if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) { bktr->bt848_tuner = (bt848_tuner & 0xff); - probeCard(bktr, FALSE); + probeCard(bktr, FALSE, unit); } } } @@ -7182,7 +7246,7 @@ bktr_read( dev_t dev, struct uio *uio, int ioflag ) case VIDEO_DEV: return( video_read( bktr, unit, dev, uio ) ); case VBI_DEV: - return( vbi_read( bktr, dev, uio ) ); + return( vbi_read( bktr, uio, ioflag ) ); } return( ENXIO ); } @@ -7263,432 +7327,69 @@ bktr_mmap( dev_t dev, vm_offset_t offset, int nprot ) return( i386_btop(vtophys(bktr->bigbuf) + offset) ); } -#endif /* FreeBSD 4.x specific kernel interface routines */ - - -/**********************************/ -/* *** FreeBSD 2.2.x and 3.x *** */ -/**********************************/ - -#if ((__FreeBSD__ == 2) || (__FreeBSD__ == 3)) - -static bktr_reg_t brooktree[ NBKTR ]; - -static const char* bktr_probe( pcici_t tag, pcidi_t type ); -static void bktr_attach( pcici_t tag, int unit ); -static void bktr_intr(void *arg) { common_bktr_intr(arg); } - -static u_long bktr_count; - -static struct pci_device bktr_device = { - "bktr", - bktr_probe, - bktr_attach, - &bktr_count -}; - -DATA_SET (pcidevice_set, bktr_device); - -static d_open_t bktr_open; -static d_close_t bktr_close; -static d_read_t bktr_read; -static d_write_t bktr_write; -static d_ioctl_t bktr_ioctl; -static d_mmap_t bktr_mmap; - -#define CDEV_MAJOR 92 -static struct cdevsw bktr_cdevsw = -{ - bktr_open, bktr_close, bktr_read, bktr_write, - bktr_ioctl, nostop, nullreset, nodevtotty, - seltrue, bktr_mmap, NULL, "bktr", - NULL, -1 -}; - -static int bktr_devsw_installed; - -static void -bktr_drvinit( void *unused ) -{ - dev_t dev; - - if ( ! bktr_devsw_installed ) { - dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev,&bktr_cdevsw, NULL); - bktr_devsw_installed = 1; - } -} - -SYSINIT(bktrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bktr_drvinit,NULL) - -/* - * the boot time probe routine. - */ -static const char* -bktr_probe( pcici_t tag, pcidi_t type ) +int bktr_poll( dev_t dev, int events, struct proc *p) { - unsigned int rev = pci_conf_read( tag, PCIR_REVID) & 0x000000ff; - - switch (type) { - case BROOKTREE_848_PCI_ID: - if (rev == 0x12) return("BrookTree 848A"); - else return("BrookTree 848"); - case BROOKTREE_849_PCI_ID: - return("BrookTree 849A"); - case BROOKTREE_878_PCI_ID: - return("BrookTree 878"); - case BROOKTREE_879_PCI_ID: - return("BrookTree 879"); - }; - - return ((char *)0); -} - -/* - * the attach routine. - */ -static void -bktr_attach( pcici_t tag, int unit ) -{ - bktr_ptr_t bktr; - bt848_ptr_t bt848; - u_long latency; - u_long fun; - unsigned int rev; -#ifdef BROOKTREE_IRQ - u_long old_irq, new_irq; -#endif - - bktr = &brooktree[unit]; - - if (unit >= NBKTR) { - printf("brooktree%d: attach: only %d units configured.\n", - unit, NBKTR); - printf("brooktree%d: attach: invalid unit number.\n", unit); - return; - } - - /* Enable Memory Mapping */ - fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); - pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 2); - - /* Enable Bus Mastering */ - fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); - pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 4); - - bktr->tag = tag; - - - /* - * Map control/status registers - */ - pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base, - &bktr->phys_base ); - - /* - * Disable the brooktree device - */ - bt848 = bktr->base; - bt848->int_mask = ALL_INTS_DISABLED; - bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; - -#ifdef BROOKTREE_IRQ /* from the configuration file */ - old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); - pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ); - new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); - printf("bktr%d: attach: irq changed from %d to %d\n", - unit, (old_irq & 0xff), (new_irq & 0xff)); -#endif - - /* - * setup the interrupt handling routine - */ - pci_map_int(tag, bktr_intr, (void*) bktr, &net_imask); - - - /* Update the Device Control Register */ - /* on Bt878 and Bt879 cards */ - fun = pci_conf_read(tag, 0x40); - fun = fun | 1; /* Enable writes to the sub-system vendor ID */ - -#if defined( BKTR_430_FX_MODE ) - if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n"); - fun = fun | 2; /* Enable Intel 430 FX compatibility mode */ -#endif - -#if defined( BKTR_SIS_VIA_MODE ) - if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n"); - fun = fun | 4; /* Enable SiS/VIA compatibility mode (usefull for - OPTi chipset motherboards too */ -#endif - pci_conf_write(tag, 0x40, fun); - - - /* XXX call bt848_i2c dependent attach() routine */ -#if (NSMBUS > 0) - if (bt848_i2c_attach(unit, bktr->base, &bktr->i2c_sc)) - printf("bktr%d: i2c_attach: can't attach\n", unit); -#endif - - -/* - * PCI latency timer. 32 is a good value for 4 bus mastering slots, if - * you have more than four, then 16 would probably be a better value. - */ -#ifndef BROOKTREE_DEF_LATENCY_VALUE -#define BROOKTREE_DEF_LATENCY_VALUE 10 -#endif - latency = pci_conf_read(tag, PCI_LATENCY_TIMER); - latency = (latency >> 8) & 0xff; - if ( bootverbose ) { - if (latency) - printf("brooktree%d: PCI bus latency is", unit); - else - printf("brooktree%d: PCI bus latency was 0 changing to", - unit); - } - if ( !latency ) { - latency = BROOKTREE_DEF_LATENCY_VALUE; - pci_conf_write(tag, PCI_LATENCY_TIMER, latency<<8); - } - if ( bootverbose ) { - printf(" %d.\n", (int) latency); - } - - - /* read the pci device id and revision id */ - fun = pci_conf_read(tag, PCI_ID_REG); - rev = pci_conf_read(tag, PCIR_REVID) & 0x000000ff; - - /* call the common attach code */ - common_bktr_attach( bktr, unit, fun, rev ); - - make_dev(&bktr_cdevsw, unit, 0, 0, 0444, "bktr%d", unit); - make_dev(&bktr_cdevsw, unit+16, 0, 0, 0444, "tuner%d", unit); - make_dev(&bktr_cdevsw, unit+32, 0, 0, 0444, "vbi%d", unit); - -} - - -/* - * Special Memory Allocation - */ -static vm_offset_t -get_bktr_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("bktr%d: Unable to allocate %d bytes of memory.\n", - unit, size); - } - - return( addr ); -} - -/*--------------------------------------------------------- -** -** BrookTree 848 character device driver routines -** -**--------------------------------------------------------- -*/ - - -#define VIDEO_DEV 0x00 -#define TUNER_DEV 0x01 -#define VBI_DEV 0x02 - -#define UNIT(x) ((x) & 0x0f) -#define FUNCTION(x) ((x >> 4) & 0x0f) - - -/* - * - */ -int -bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) -{ - bktr_ptr_t bktr; int unit; - - unit = UNIT( minor(dev) ); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - - bktr = &(brooktree[ unit ]); - - if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */ - return( ENXIO ); - - - if (bt848_card != -1) { - if ((bt848_card >> 8 == unit ) && - ( (bt848_card & 0xff) < Bt848_MAX_CARD )) { - if ( bktr->bt848_card != (bt848_card & 0xff) ) { - bktr->bt848_card = (bt848_card & 0xff); - probeCard(bktr, FALSE); - } - } - } - - if (bt848_tuner != -1) { - if ((bt848_tuner >> 8 == unit ) && - ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) { - if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) { - bktr->bt848_tuner = (bt848_tuner & 0xff); - probeCard(bktr, FALSE); - } - } - } - - if (bt848_reverse_mute != -1) { - if (((bt848_reverse_mute >> 8) == unit ) && - ((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) { - bktr->reverse_mute = bt848_reverse_mute & 0xff; - bt848_reverse_mute = -1; - } - } - - - switch ( FUNCTION( minor(dev) ) ) { - case VIDEO_DEV: - return( video_open( bktr ) ); - case TUNER_DEV: - return( tuner_open( bktr ) ); - case VBI_DEV: - return( vbi_open( bktr ) ); - } - return( ENXIO ); -} - - -/* - * - */ -int -bktr_close( dev_t dev, int flags, int fmt, struct proc *p ) -{ bktr_ptr_t bktr; - int unit; + int revents = 0; - unit = UNIT( minor(dev) ); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - - bktr = &(brooktree[ unit ]); - - switch ( FUNCTION( minor(dev) ) ) { - case VIDEO_DEV: - return( video_close( bktr ) ); - case TUNER_DEV: - return( tuner_close( bktr ) ); - case VBI_DEV: - return( vbi_close( bktr ) ); - } - - return( ENXIO ); -} - -/* - * - */ -int -bktr_read( dev_t dev, struct uio *uio, int ioflag ) -{ - bktr_ptr_t bktr; - int unit; - unit = UNIT(minor(dev)); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - bktr = &(brooktree[unit]); - - switch ( FUNCTION( minor(dev) ) ) { - case VIDEO_DEV: - return( video_read( bktr, unit, dev, uio ) ); - case VBI_DEV: - return( vbi_read( bktr, dev, uio ) ); + /* Get the device data */ + bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); + if (bktr == NULL) { + /* the device is no longer valid/functioning */ + return (ENXIO); } - return( ENXIO ); -} + disable_intr(); -/* - * - */ -int -bktr_write( dev_t dev, struct uio *uio, int ioflag ) -{ - return( EINVAL ); /* XXX or ENXIO ? */ -} + if (events & (POLLIN | POLLRDNORM)) { -/* - * - */ -int -bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct proc* pr ) -{ - bktr_ptr_t bktr; - int unit; - - unit = UNIT(minor(dev)); - if (unit >= NBKTR) /* unit out of range */ - return( ENXIO ); - - bktr = &(brooktree[ unit ]); - - if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */ - return( ENOMEM ); - - switch ( FUNCTION( minor(dev) ) ) { - case VIDEO_DEV: - return( video_ioctl( bktr, unit, cmd, arg, pr ) ); - case TUNER_DEV: - return( tuner_ioctl( bktr, unit, cmd, arg, pr ) ); + switch ( FUNCTION( minor(dev) ) ) { + case VBI_DEV: + if(bktr->vbisize == 0) + selrecord(p, &bktr->vbi_select); + else + revents |= events & (POLLIN | POLLRDNORM); + break; + } } - return( ENXIO ); + enable_intr(); + + return (revents); } -/* - * bktr_mmap. - * Note: 2.2.5/2.2.6/2.2.7/3.0 users must manually - * edit the following line and change "vm_offset_t" to "int"" - */ -int bktr_mmap( dev_t dev, vm_offset_t offset, int nprot ) +#endif /* FreeBSD 4.x specific kernel interface routines */ -{ - int unit; - bktr_ptr_t bktr; - unit = UNIT(minor(dev)); +/**********************************/ +/* *** FreeBSD 2.2.x and 3.x *** */ +/**********************************/ - if (unit >= NBKTR || FUNCTION(minor(dev)) > 0) - return( -1 ); +#if ((__FreeBSD__ == 2) || (__FreeBSD__ == 3)) +#endif /* FreeBSD 2.2.x and 3.x specific kernel interface routines */ - bktr = &(brooktree[ unit ]); - if (nprot & PROT_EXEC) - return( -1 ); +/*****************/ +/* *** BSDI *** */ +/*****************/ - if (offset < 0) - return( -1 ); +#if defined(__bsdi__) +#endif /* __bsdi__ BSDI specific kernel interface routines */ - if (offset >= bktr->alloc_pages * PAGE_SIZE) - return( -1 ); - return( i386_btop(vtophys(bktr->bigbuf) + offset) ); -} +/*****************************/ +/* *** OpenBSD / NetBSD *** */ +/*****************************/ +#if defined(__NetBSD__) || defined(__OpenBSD__) +#endif /* __NetBSD__ || __OpenBSD__ */ -#endif /* FreeBSD 2.2.x and 3.x specific kernel interface routines */ +#endif /* FreeBSD, BSDI, NetBSD, OpenBSD */ -#endif /* !defined(__FreeBSD__) || (NBKTR > 0 && NPCI > 0) */ /* Local Variables: */ /* mode: C */ |
