diff options
author | Roger Hardiman <roger@FreeBSD.org> | 2000-04-04 16:54:13 +0000 |
---|---|---|
committer | Roger Hardiman <roger@FreeBSD.org> | 2000-04-04 16:54:13 +0000 |
commit | 24cf43ae215d8543917fa588a835061382110799 (patch) | |
tree | c708d92a00907a43a59ceb590fd25ebfdd6a89a9 /sys/dev/bktr/bktr_os.c | |
parent | bcc862e3976f22cd559e392850ca062cfb23c08c (diff) | |
download | src-24cf43ae215d8543917fa588a835061382110799.tar.gz src-24cf43ae215d8543917fa588a835061382110799.zip |
Upgrade the bktr driver from 2.07 to 2.10.
- The driver now uses bus_space() and runs on NetBSD 1.4.2
Submitted by Thomas Klausner <wiz@danbala.ifoer.tuwien.ac.at>
- Remove startup quirks for video and vbi capture for PAL users.
PAL TV users can now run FXTV and Alevt in any order.
- Add support for cable channels >100
Submitted by Scott Presnell <srp@zgi.com>
- New MSP3410/3415 setup code added. This is experimental.
Please set the sysctl hw.bt848.slow_msp_audio to 1 for this.
Submitted by Frank Nobis<fn@radio-do.de>
Notes
Notes:
svn path=/head/; revision=59014
Diffstat (limited to 'sys/dev/bktr/bktr_os.c')
-rw-r--r-- | sys/dev/bktr/bktr_os.c | 583 |
1 files changed, 545 insertions, 38 deletions
diff --git a/sys/dev/bktr/bktr_os.c b/sys/dev/bktr/bktr_os.c index af7948ca698e..12d0c29d1b0b 100644 --- a/sys/dev/bktr/bktr_os.c +++ b/sys/dev/bktr/bktr_os.c @@ -50,14 +50,10 @@ #ifdef __FreeBSD__ #include "bktr.h" -#include "opt_bktr.h" #include "opt_devfs.h" #endif /* __FreeBSD__ */ -#if defined(__NetBSD__) || defined(__OpenBSD__) -#include "bktr.h" -#include "pci.h" -#endif /* __NetBSD__ || __OpenBSD__ */ +#include "opt_bktr.h" /* include any kernel config options */ #define FIFO_RISC_DISABLED 0 #define ALL_INTS_DISABLED 0 @@ -93,18 +89,30 @@ #include <sys/bus.h> /* used by smbus and newbus */ #endif +#if (__FreeBSD_version >=300000) +#include <machine/bus_memio.h> /* used by bus space */ +#include <machine/bus.h> /* used by bus space and newbus */ +#include <sys/bus.h> +#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 */ #endif + #include <machine/clock.h> /* for DELAY */ #include <pci/pcivar.h> #include <pci/pcireg.h> +#endif +#ifdef __NetBSD__ +#include <dev/ic/ioctl_meteor.h> /* NetBSD location for .h files */ +#include <dev/ic/ioctl_bt848.h> +#else /* Traditional location for .h files */ #include <machine/ioctl_meteor.h> #include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ +#endif #include <dev/bktr/bktr_reg.h> #include <dev/bktr/bktr_tuner.h> #include <dev/bktr/bktr_card.h> @@ -112,6 +120,7 @@ #include <dev/bktr/bktr_core.h> #include <dev/bktr/bktr_os.h> +#if defined(__FreeBSD__) #if (NSMBUS > 0) #include <dev/bktr/bktr_i2c.h> #endif @@ -121,22 +130,19 @@ int bt848_card = -1; int bt848_tuner = -1; int bt848_reverse_mute = -1; int bt848_format = -1; +int bt848_slow_msp_audio = -1; SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt"); SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, ""); SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, ""); SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, ""); SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, ""); - -#if (__FreeBSD_version >= 300000) - typedef u_long ioctl_cmd_t; +SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, ""); #endif #if (__FreeBSD__ == 2) -typedef int ioctl_cmd_t; #define PCIR_REVID PCI_CLASS_REG #endif -#endif /* __FreeBSD__ */ /****************/ @@ -150,6 +156,21 @@ typedef int ioctl_cmd_t; /* *** OpenBSD/NetBSD *** */ /**************************/ #if defined(__NetBSD__) || defined(__OpenBSD__) +#include <sys/device.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> + +static int bootverbose = 1; + + +#define BKTR_DEBUG +#ifdef BKTR_DEBUG +int bktr_debug = 0; +#define DPR(x) (bktr_debug ? printf x : 0) +#else +#define DPR(x) +#endif #endif /* __NetBSD__ || __OpenBSD__ */ @@ -247,7 +268,6 @@ bktr_probe( device_t dev ) static int bktr_attach( device_t dev ) { - bt848_ptr_t bt848; u_long latency; u_long fun; u_long val; @@ -282,14 +302,15 @@ bktr_attach( device_t dev ) error = ENXIO; goto fail; } - bktr->base = rman_get_virtual(bktr->res_mem); /* XXX use bus_space */ + bktr->memt = rman_get_bustag(bktr->res_mem); + bktr->memh = rman_get_bushandle(bktr->res_mem); + /* * Disable the brooktree device */ - bt848 = bktr->base; - bt848->int_mask = ALL_INTS_DISABLED; - bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; + OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); + OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); #ifdef BROOKTREE_IRQ /* from the configuration file */ @@ -341,7 +362,7 @@ bktr_attach( device_t dev ) /* XXX call bt848_i2c dependent attach() routine */ #if (NSMBUS > 0) - if (bt848_i2c_attach(unit, bktr->base, &bktr->i2c_sc)) + if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc)) printf("bktr%d: i2c_attach: can't attach\n", unit); #endif @@ -395,12 +416,10 @@ static int bktr_detach( device_t dev ) { struct bktr_softc *bktr = device_get_softc(dev); - bt848_ptr_t bt848; /* Disable the brooktree device */ - bt848 = bktr->base; - bt848->int_mask = ALL_INTS_DISABLED; - bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; + OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); + OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); /* FIXME - Free memory for RISC programs, grab buffer, vbi buffers */ @@ -421,12 +440,10 @@ static int bktr_shutdown( device_t dev ) { struct bktr_softc *bktr = device_get_softc(dev); - bt848_ptr_t bt848; /* Disable the brooktree device */ - bt848 = bktr->base; - bt848->int_mask = ALL_INTS_DISABLED; - bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; + OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); + OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); return 0; } @@ -513,10 +530,14 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) } if (bt848_reverse_mute != -1) { - if (((bt848_reverse_mute >> 8) == unit ) && - ((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) { + if ((bt848_reverse_mute >> 8) == unit ) { bktr->reverse_mute = bt848_reverse_mute & 0xff; - bt848_reverse_mute = -1; + } + } + + if (bt848_slow_msp_audio != -1) { + if ((bt848_slow_msp_audio >> 8) == unit ) { + bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff); } } @@ -806,10 +827,10 @@ 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; + unsigned long base; #ifdef BROOKTREE_IRQ u_long old_irq, new_irq; #endif @@ -837,15 +858,18 @@ bktr_attach( pcici_t tag, int unit ) /* * Map control/status registers */ - pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base, + pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &base, &bktr->phys_base ); +#if (__FreeBSD_version >= 300000) + bktr->memt = I386_BUS_SPACE_MEM; /* XXX should use proper bus space */ + bktr->memh = (bus_space_handle_t)base; /* XXX functions here */ +#endif /* * Disable the brooktree device */ - bt848 = bktr->base; - bt848->int_mask = ALL_INTS_DISABLED; - bt848->gpio_dma_ctl = FIFO_RISC_DISABLED; + OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); + OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); #ifdef BROOKTREE_IRQ /* from the configuration file */ old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); @@ -881,7 +905,7 @@ bktr_attach( pcici_t tag, int unit ) /* XXX call bt848_i2c dependent attach() routine */ #if (NSMBUS > 0) - if (bt848_i2c_attach(unit, bktr->base, &bktr->i2c_sc)) + if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc)) printf("bktr%d: i2c_attach: can't attach\n", unit); #endif @@ -1005,13 +1029,16 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p ) } if (bt848_reverse_mute != -1) { - if (((bt848_reverse_mute >> 8) == unit ) && - ((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) { + if ((bt848_reverse_mute >> 8) == unit ) { bktr->reverse_mute = bt848_reverse_mute & 0xff; - bt848_reverse_mute = -1; } } + if (bt848_slow_msp_audio != -1) { + if ((bt848_slow_msp_audio >> 8) == unit ) { + bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff); + } + } switch ( FUNCTION( minor(dev) ) ) { case VIDEO_DEV: @@ -1192,5 +1219,485 @@ int bktr_poll( dev_t dev, int events, struct proc *p) /* *** OpenBSD / NetBSD *** */ /*****************************/ #if defined(__NetBSD__) || defined(__OpenBSD__) -#endif /* __NetBSD__ || __OpenBSD__ */ + +#define IPL_VIDEO IPL_BIO /* XXX */ + +static int bktr_intr(void *arg) { return common_bktr_intr(arg); } + +#define bktr_open bktropen +#define bktr_close bktrclose +#define bktr_read bktrread +#define bktr_write bktrwrite +#define bktr_ioctl bktrioctl +#define bktr_mmap bktrmmap + +int bktr_open __P((dev_t, int, int, struct proc *)); +int bktr_close __P((dev_t, int, int, struct proc *)); +int bktr_read __P((dev_t, struct uio *, int)); +int bktr_write __P((dev_t, struct uio *, int)); +int bktr_ioctl __P((dev_t, ioctl_cmd_t, caddr_t, int, struct proc*)); +int bktr_mmap __P((dev_t, vm_offset_t, int)); + +vm_offset_t vm_page_alloc_contig(vm_offset_t, vm_offset_t, + vm_offset_t, vm_offset_t); + +#if defined(__BROKEN_INDIRECT_CONFIG) || defined(__OpenBSD__) +static int bktr_probe __P((struct device *, void *, void *)); +#else +static int bktr_probe __P((struct device *, struct cfdata *, void *)); +#endif +static void bktr_attach __P((struct device *, struct device *, void *)); + +struct cfattach bktr_ca = { + sizeof(struct bktr_softc), bktr_probe, bktr_attach +}; + +#if defined(__NetBSD__) +extern struct cfdriver bktr_cd; +#else +struct cfdriver bktr_cd = { + NULL, "bktr", DV_DULL +}; +#endif + +int bktr_probe(parent, match, aux) + struct device *parent; +#if defined(__BROKEN_INDIRECT_CONFIG) || defined(__OpenBSD__) + void *match; +#else + struct cfdata *match; +#endif + void *aux; +{ + struct pci_attach_args *pa = aux; + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROOKTREE && + (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT848 || + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849 || + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT878 || + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT879)) + return 1; + + return 0; +} + + +/* + * the attach routine. + */ +static void +bktr_attach __P((struct device *parent, struct device *self, void *aux)) +{ + bktr_ptr_t bktr; + u_long latency; + u_long fun; + unsigned int rev; + +#if defined(__OpenBSD__) + struct pci_attach_args *pa = aux; + pci_chipset_tag_t pc = pa->pa_pc; + + pci_intr_handle_t ih; + const char *intrstr; + int retval; + int unit; + + bktr = (bktr_ptr_t)self; + unit = bktr->bktr_dev.dv_unit; + + bktr->pc = pa->pa_pc; + bktr->tag = pa->pa_tag; + bktr->dmat = pa->pa_dmat; + + /* + * map memory + */ + bktr->memt = pa->pa_memt; + retval = pci_mem_find(pc, pa->pa_tag, PCI_MAPREG_START, + &bktr->phys_base, &bktr->obmemsz, NULL); + if (!retval) + retval = bus_space_map(pa->pa_memt, bktr->phys_base, + bktr->obmemsz, 0, &bktr->memh); + if (retval) { + printf(": couldn't map memory\n"); + return; + } + + + /* + * map interrupt + */ + if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &ih)) { + printf(": couldn't map interrupt\n"); + return; + } + intrstr = pci_intr_string(pa->pa_pc, ih); + + bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO, + bktr_intr, bktr, bktr->bktr_dev.dv_xname); + if (bktr->ih == NULL) { + printf(": couldn't establish interrupt"); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + return; + } + + if (intrstr != NULL) + printf(": %s\n", intrstr); +#endif /* __OpenBSD__ */ + +#if defined(__NetBSD__) + struct pci_attach_args *pa = aux; + pci_intr_handle_t ih; + const char *intrstr; + int retval; + int unit; + + bktr = (bktr_ptr_t)self; + unit = bktr->bktr_dev.dv_unit; + bktr->dmat = pa->pa_dmat; + + printf("\n"); + + /* + * map memory + */ + retval = pci_mapreg_map(pa, PCI_MAPREG_START, + PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, + &bktr->memt, &bktr->memh, &bktr->phys_base, + &bktr->obmemsz); + DPR(("pci_mapreg_map: memt %x, memh %x, base %x, size %x\n", + bktr->memt, (u_int)bktr->memh, + (u_int)bktr->phys_base, (u_int)bktr->obmemsz)); + if (retval) { + printf("%s: couldn't map memory\n", bktr->bktr_dev.dv_xname); + return; + } + + /* + * Disable the brooktree device + */ + OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); + OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); + + /* + * map interrupt + */ + if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &ih)) { + printf("%s: couldn't map interrupt\n", bktr->bktr_dev.dv_xname); + return; + } + intrstr = pci_intr_string(pa->pa_pc, ih); + bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO, + bktr_intr, bktr); + if (bktr->ih == NULL) { + printf("%s: couldn't establish interrupt", + bktr->bktr_dev.dv_xname); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + return; + } + if (intrstr != NULL) + printf("%s: interrupting at %s\n", bktr->bktr_dev.dv_xname, + intrstr); +#endif /* __NetBSD__ */ + +/* + * 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(pa->pa_pc, pa->pa_tag, PCI_LATENCY_TIMER); + latency = (latency >> 8) & 0xff; + + if ( !latency ) { + if ( bootverbose ) { + printf("%s: PCI bus latency was 0 changing to %d", + bktr->bktr_dev.dv_xname, + BROOKTREE_DEF_LATENCY_VALUE); + } + latency = BROOKTREE_DEF_LATENCY_VALUE; + pci_conf_write(pa->pa_pc, pa->pa_tag, + PCI_LATENCY_TIMER, latency<<8); + } + + + /* Enabled Bus Master and Memory Mapping */ + fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); + pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, fun | 2); + fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); + pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, fun | 4); + + /* read the pci id and determine the card type */ + fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG); + rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0x000000ff; + + common_bktr_attach( bktr, unit, fun, rev ); +} + + +/* + * Special Memory Allocation + */ +vm_offset_t +get_bktr_mem(bktr, dmapp, size) + bktr_ptr_t bktr; + bus_dmamap_t *dmapp; + unsigned int size; +{ + bus_dma_tag_t dmat = bktr->dmat; + bus_dma_segment_t seg; + bus_size_t align; + int rseg; + caddr_t kva; + + /* + * Allocate a DMA area + */ + align = 1 << 24; + if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1, + &rseg, BUS_DMA_NOWAIT)) { + align = PAGE_SIZE; + if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1, + &rseg, BUS_DMA_NOWAIT)) { + printf("bktr%d: Unable to dmamem_alloc of %d bytes\n", + bktr->bktr_dev.dv_unit, size); + return 0; + } + } + if (bus_dmamem_map(dmat, &seg, rseg, size, + &kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { + printf("bktr%d: Unable to dmamem_map of %d bytes\n", + bktr->bktr_dev.dv_unit, size); + bus_dmamem_free(dmat, &seg, rseg); + return 0; + } +#ifdef __OpenBSD__ + bktr->dm_mapsize = size; +#endif + /* + * Create and locd the DMA map for the DMA area + */ + if (bus_dmamap_create(dmat, size, 1, size, 0, BUS_DMA_NOWAIT, dmapp)) { + printf("bktr%d: Unable to dmamap_create of %d bytes\n", + bktr->bktr_dev.dv_unit, size); + bus_dmamem_unmap(dmat, kva, size); + bus_dmamem_free(dmat, &seg, rseg); + return 0; + } + if (bus_dmamap_load(dmat, *dmapp, kva, size, NULL, BUS_DMA_NOWAIT)) { + printf("bktr%d: Unable to dmamap_load of %d bytes\n", + bktr->bktr_dev.dv_unit, size); + bus_dmamem_unmap(dmat, kva, size); + bus_dmamem_free(dmat, &seg, rseg); + bus_dmamap_destroy(dmat, *dmapp); + return 0; + } + return (vm_offset_t)kva; +} + +void +free_bktr_mem(bktr, dmap, kva) + bktr_ptr_t bktr; + bus_dmamap_t dmap; + vm_offset_t kva; +{ + bus_dma_tag_t dmat = bktr->dmat; + +#ifdef __NetBSD__ + bus_dmamem_unmap(dmat, (caddr_t)kva, dmap->dm_mapsize); +#else + bus_dmamem_unmap(dmat, (caddr_t)kva, bktr->dm_mapsize); +#endif + bus_dmamem_free(dmat, dmap->dm_segs, 1); + bus_dmamap_destroy(dmat, dmap); +} + + +/*--------------------------------------------------------- +** +** 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) ); + + /* unit out of range */ + if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL)) + return( ENXIO ); + + bktr = bktr_cd.cd_devs[unit]; + + + if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */ + return( ENXIO ); + + 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; + + unit = UNIT( minor(dev) ); + + /* unit out of range */ + if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL)) + return( ENXIO ); + + bktr = bktr_cd.cd_devs[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)); + + /* unit out of range */ + if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL)) + return( ENXIO ); + + bktr = bktr_cd.cd_devs[unit]; + + switch ( FUNCTION( minor(dev) ) ) { + case VIDEO_DEV: + return( video_read( bktr, unit, dev, uio ) ); + case VBI_DEV: + return( vbi_read( bktr, uio, ioflag ) ); + } + + return( ENXIO ); +} + + +/* + * + */ +int +bktr_write( dev_t dev, struct uio *uio, int ioflag ) +{ + /* operation not supported */ + return( EOPNOTSUPP ); +} + +/* + * + */ +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)); + + /* unit out of range */ + if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL)) + return( ENXIO ); + + bktr = bktr_cd.cd_devs[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 ) ); + } + + return( ENXIO ); +} + +/* + * + */ +int +bktr_mmap( dev_t dev, vm_offset_t offset, int nprot ) +{ + int unit; + bktr_ptr_t bktr; + + unit = UNIT(minor(dev)); + + /* unit out of range */ + if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL)) + return( -1 ); + if (FUNCTION(minor(dev)) > 0) + return( -1 ); + + bktr = bktr_cd.cd_devs[unit]; + + if (offset < 0) + return( -1 ); + + if (offset >= bktr->alloc_pages * PAGE_SIZE) + return( -1 ); + +#ifdef __NetBSD__ + return (bus_dmamem_mmap(bktr->dmat, bktr->dm_mem->dm_segs, 1, + offset, nprot, BUS_DMA_WAITOK)); +#else + return( i386_btop(vtophys(bktr->bigbuf) + offset) ); +#endif +} + +#endif /* __NetBSD__ || __OpenBSD__ */ |