The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/video/bktr/bktr_os.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * 1. Redistributions of source code must retain the 
    3  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Amancio Hasty and
   17  *      Roger Hardiman
   18  * 4. The name of the author may not be used to endorse or promote products 
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   24  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   31  * POSSIBILITY OF SUCH DAMAGE.
   32  *
   33  * $FreeBSD: src/sys/dev/bktr/bktr_os.c,v 1.54 2007/02/23 12:18:34 piso Exp $
   34  */
   35 
   36 /*
   37  * This is part of the Driver for Video Capture Cards (Frame grabbers)
   38  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
   39  * chipset.
   40  * Copyright Roger Hardiman and Amancio Hasty.
   41  *
   42  * bktr_os : This has all the Operating System dependant code,
   43  *             probe/attach and open/close/ioctl/read/mmap
   44  *             memory allocation
   45  *             PCI bus interfacing
   46  */
   47 
   48 #include "opt_bktr.h"           /* include any kernel config options */
   49 
   50 #define FIFO_RISC_DISABLED      0
   51 #define ALL_INTS_DISABLED       0
   52 
   53 #include <sys/param.h>
   54 #include <sys/systm.h>
   55 #include <sys/conf.h>
   56 #include <sys/device.h>
   57 #include <sys/uio.h>
   58 #include <sys/kernel.h>
   59 #include <sys/signalvar.h>
   60 #include <sys/malloc.h>
   61 #include <sys/mman.h>
   62 #include <sys/event.h>
   63 #include <sys/bus.h>
   64 #include <sys/rman.h>
   65 #include <sys/thread2.h>
   66 
   67 #include <vm/vm.h>
   68 #include <vm/vm_kern.h>
   69 #include <vm/pmap.h>
   70 #include <vm/vm_extern.h>
   71 
   72 #include <bus/pci/pcivar.h>
   73 #include <bus/pci/pcireg.h>
   74 #include "pcidevs.h"
   75 
   76 #include <sys/sysctl.h>
   77 int bt848_card = -1; 
   78 int bt848_tuner = -1;
   79 int bt848_reverse_mute = -1; 
   80 int bt848_format = -1;
   81 int bt848_slow_msp_audio = -1;
   82 #ifdef BKTR_NEW_MSP34XX_DRIVER
   83 int bt848_stereo_once = 0;      /* no continuous stereo monitoring */
   84 int bt848_amsound = 0;          /* hard-wire AM sound at 6.5 Hz (france),
   85                                    the autoscan seems work well only with FM... */
   86 int bt848_dolby = 0;
   87 #endif
   88 
   89 SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
   90 SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
   91 SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
   92 SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
   93 SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
   94 SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, "");
   95 #ifdef BKTR_NEW_MSP34XX_DRIVER
   96 SYSCTL_INT(_hw_bt848, OID_AUTO, stereo_once, CTLFLAG_RW, &bt848_stereo_once, 0, "");
   97 SYSCTL_INT(_hw_bt848, OID_AUTO, amsound, CTLFLAG_RW, &bt848_amsound, 0, "");
   98 SYSCTL_INT(_hw_bt848, OID_AUTO, dolby, CTLFLAG_RW, &bt848_dolby, 0, "");
   99 #endif
  100 
  101 #include <dev/video/meteor/ioctl_meteor.h>
  102 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
  103 #include <dev/video/bktr/bktr_reg.h>
  104 #include <dev/video/bktr/bktr_tuner.h>
  105 #include <dev/video/bktr/bktr_card.h>
  106 #include <dev/video/bktr/bktr_audio.h>
  107 #include <dev/video/bktr/bktr_core.h>
  108 #include <dev/video/bktr/bktr_os.h>
  109 
  110 #if defined(BKTR_USE_FREEBSD_SMBUS)
  111 #include <dev/video/bktr/bktr_i2c.h>
  112 
  113 #include "iicbb_if.h"
  114 #include "smbus_if.h"
  115 #endif
  116 
  117 static int      bktr_probe( device_t dev );
  118 static int      bktr_attach( device_t dev );
  119 static int      bktr_detach( device_t dev );
  120 static int      bktr_shutdown( device_t dev );
  121 static void     bktr_intr(void *arg) { common_bktr_intr(arg); }
  122 
  123 static device_method_t bktr_methods[] = {
  124         /* Device interface */
  125         DEVMETHOD(device_probe,         bktr_probe),
  126         DEVMETHOD(device_attach,        bktr_attach),
  127         DEVMETHOD(device_detach,        bktr_detach),
  128         DEVMETHOD(device_shutdown,      bktr_shutdown),
  129 
  130 #if defined(BKTR_USE_FREEBSD_SMBUS)
  131         /* iicbb interface */
  132         DEVMETHOD(iicbb_callback,       bti2c_iic_callback),
  133         DEVMETHOD(iicbb_setsda,         bti2c_iic_setsda),
  134         DEVMETHOD(iicbb_setscl,         bti2c_iic_setscl),
  135         DEVMETHOD(iicbb_getsda,         bti2c_iic_getsda),
  136         DEVMETHOD(iicbb_getscl,         bti2c_iic_getscl),
  137         DEVMETHOD(iicbb_reset,          bti2c_iic_reset),
  138         
  139         /* smbus interface */
  140         DEVMETHOD(smbus_callback,       bti2c_smb_callback),
  141         DEVMETHOD(smbus_writeb,         bti2c_smb_writeb),
  142         DEVMETHOD(smbus_writew,         bti2c_smb_writew),
  143         DEVMETHOD(smbus_readb,          bti2c_smb_readb),
  144 #endif
  145 
  146         DEVMETHOD_END
  147 };
  148 
  149 static driver_t bktr_driver = {
  150         "bktr",
  151         bktr_methods,
  152         sizeof(struct bktr_softc),
  153 };
  154 
  155 static devclass_t bktr_devclass;
  156 
  157 static  d_open_t        bktr_open;
  158 static  d_close_t       bktr_close;
  159 static  d_read_t        bktr_read;
  160 static  d_write_t       bktr_write;
  161 static  d_ioctl_t       bktr_ioctl;
  162 static  d_mmap_t        bktr_mmap;
  163 static  d_kqfilter_t    bktr_kqfilter;
  164 
  165 static void bktr_filter_detach(struct knote *);
  166 static int bktr_filter(struct knote *, long);
  167 
  168 static struct dev_ops bktr_ops = {
  169         { "bktr", 0, 0 },
  170         .d_open =       bktr_open,
  171         .d_close =      bktr_close,
  172         .d_read =       bktr_read,
  173         .d_write =      bktr_write,
  174         .d_ioctl =      bktr_ioctl,
  175         .d_kqfilter =   bktr_kqfilter,
  176         .d_mmap =       bktr_mmap,
  177 };
  178 
  179 DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, NULL, NULL);
  180 MODULE_DEPEND(bktr, bktr_mem, 1,1,1);
  181 MODULE_VERSION(bktr, 1);
  182 
  183 /*
  184  * the boot time probe routine.
  185  */
  186 static int
  187 bktr_probe( device_t dev )
  188 {
  189         unsigned int type = pci_get_devid(dev);
  190         unsigned int rev  = pci_get_revid(dev);
  191 
  192         if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE)
  193         {
  194                 switch (PCI_PRODUCT(type)) {
  195                 case PCI_PRODUCT_BROOKTREE_BT848:
  196                         if (rev == 0x12)
  197                                 device_set_desc(dev, "BrookTree 848A");
  198                         else
  199                                 device_set_desc(dev, "BrookTree 848");
  200                         return BUS_PROBE_DEFAULT;
  201                 case PCI_PRODUCT_BROOKTREE_BT849:
  202                         device_set_desc(dev, "BrookTree 849A");
  203                         return BUS_PROBE_DEFAULT;
  204                 case PCI_PRODUCT_BROOKTREE_BT878:
  205                         device_set_desc(dev, "BrookTree 878");
  206                         return BUS_PROBE_DEFAULT;
  207                 case PCI_PRODUCT_BROOKTREE_BT879:
  208                         device_set_desc(dev, "BrookTree 879");
  209                         return BUS_PROBE_DEFAULT;
  210                 }
  211         };
  212 
  213         return ENXIO;
  214 }
  215 
  216 
  217 /*
  218  * the attach routine.
  219  */
  220 static int
  221 bktr_attach( device_t dev )
  222 {
  223         u_long          latency;
  224         u_long          fun;
  225         u_long          val;
  226         unsigned int    rev;
  227         unsigned int    unit;
  228         int             error = 0;
  229 #ifdef BROOKTREE_IRQ
  230         u_long          old_irq, new_irq;
  231 #endif 
  232 
  233         struct bktr_softc *bktr = device_get_softc(dev);
  234 
  235         unit = device_get_unit(dev);
  236 
  237         /* build the device name for bktr_name() */
  238         ksnprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit);
  239 
  240         /*
  241          * Enable bus mastering and Memory Mapped device
  242          */
  243         val = pci_read_config(dev, PCIR_COMMAND, 4);
  244         val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
  245         pci_write_config(dev, PCIR_COMMAND, val, 4);
  246 
  247         /*
  248          * Map control/status registers.
  249          */
  250         bktr->mem_rid = PCIR_BAR(0);
  251         bktr->res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 
  252                                         &bktr->mem_rid, RF_ACTIVE);
  253 
  254         if (!bktr->res_mem) {
  255                 device_printf(dev, "could not map memory\n");
  256                 error = ENXIO;
  257                 goto fail;
  258         }
  259         bktr->memt = rman_get_bustag(bktr->res_mem);
  260         bktr->memh = rman_get_bushandle(bktr->res_mem);
  261 
  262 
  263         /*
  264          * Disable the brooktree device
  265          */
  266         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
  267         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
  268 
  269 
  270 #ifdef BROOKTREE_IRQ            /* from the configuration file */
  271         old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
  272         pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
  273         new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
  274         kprintf("bktr%d: attach: irq changed from %d to %d\n",
  275                 unit, (old_irq & 0xff), (new_irq & 0xff));
  276 #endif 
  277 
  278         /*
  279          * Allocate our interrupt.
  280          */
  281         bktr->irq_rid = 0;
  282         bktr->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 
  283                                 &bktr->irq_rid, RF_SHAREABLE | RF_ACTIVE);
  284         if (bktr->res_irq == NULL) {
  285                 device_printf(dev, "could not map interrupt\n");
  286                 error = ENXIO;
  287                 goto fail;
  288         }
  289 
  290         error = bus_setup_intr(dev, bktr->res_irq, 0,
  291                                bktr_intr, bktr, &bktr->res_ih, NULL);
  292         if (error) {
  293                 device_printf(dev, "could not setup irq\n");
  294                 goto fail;
  295 
  296         }
  297 
  298 
  299         /* Update the Device Control Register */
  300         /* on Bt878 and Bt879 cards           */
  301         fun = pci_read_config( dev, 0x40, 2);
  302         fun = fun | 1;  /* Enable writes to the sub-system vendor ID */
  303 
  304 #if defined( BKTR_430_FX_MODE )
  305         if (bootverbose) kprintf("Using 430 FX chipset compatibility mode\n");
  306         fun = fun | 2;  /* Enable Intel 430 FX compatibility mode */
  307 #endif
  308 
  309 #if defined( BKTR_SIS_VIA_MODE )
  310         if (bootverbose) kprintf("Using SiS/VIA chipset compatibility mode\n");
  311         fun = fun | 4;  /* Enable SiS/VIA compatibility mode (useful for
  312                            OPTi chipset motherboards too */
  313 #endif
  314         pci_write_config(dev, 0x40, fun, 2);
  315 
  316 #if defined(BKTR_USE_FREEBSD_SMBUS)
  317         if (bt848_i2c_attach(dev))
  318                 kprintf("bktr%d: i2c_attach: can't attach\n", unit);
  319 #endif
  320 
  321 /*
  322  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
  323  * you have more than four, then 16 would probably be a better value.
  324  */
  325 #ifndef BROOKTREE_DEF_LATENCY_VALUE
  326 #define BROOKTREE_DEF_LATENCY_VALUE     10
  327 #endif
  328         latency = pci_read_config(dev, PCI_LATENCY_TIMER, 4);
  329         latency = (latency >> 8) & 0xff;
  330         if ( bootverbose ) {
  331                 if (latency)
  332                         kprintf("brooktree%d: PCI bus latency is", unit);
  333                 else
  334                         kprintf("brooktree%d: PCI bus latency was 0 changing to",
  335                                 unit);
  336         }
  337         if ( !latency ) {
  338                 latency = BROOKTREE_DEF_LATENCY_VALUE;
  339                 pci_write_config(dev, PCI_LATENCY_TIMER, latency<<8, 4);
  340         }
  341         if ( bootverbose ) {
  342                 kprintf(" %d.\n", (int) latency);
  343         }
  344 
  345         /* read the pci device id and revision id */
  346         fun = pci_get_devid(dev);
  347         rev = pci_get_revid(dev);
  348 
  349         /* call the common attach code */
  350         common_bktr_attach( bktr, unit, fun, rev );
  351 
  352         /* make the device entries */
  353         make_dev(&bktr_ops, unit,    0, 0, 0444, "bktr%d",  unit);
  354         make_dev(&bktr_ops, unit+16, 0, 0, 0444, "tuner%d", unit);
  355         make_dev(&bktr_ops, unit+32, 0, 0, 0444, "vbi%d"  , unit);
  356 
  357         return 0;
  358 
  359 fail:
  360         if (bktr->res_irq)
  361                 bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
  362         if (bktr->res_mem)
  363                 bus_release_resource(dev, SYS_RES_IRQ, bktr->mem_rid, bktr->res_mem);
  364         return error;
  365 
  366 }
  367 
  368 /*
  369  * the detach routine.
  370  */
  371 static int
  372 bktr_detach( device_t dev )
  373 {
  374         struct bktr_softc *bktr = device_get_softc(dev);
  375 
  376 #ifdef BKTR_NEW_MSP34XX_DRIVER
  377         /* Disable the soundchip and kernel thread */
  378         if (bktr->msp3400c_info != NULL)
  379                 msp_detach(bktr);
  380 #endif
  381 
  382         /* Disable the brooktree device */
  383         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
  384         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
  385 
  386 #if defined(BKTR_USE_FREEBSD_SMBUS)
  387         if (bt848_i2c_detach(dev))
  388                 kprintf("bktr%d: i2c_attach: can't attach\n",
  389                      device_get_unit(dev));
  390 #endif
  391 #ifdef USE_VBIMUTEX
  392         mtx_destroy(&bktr->vbimutex);
  393 #endif
  394 
  395         /* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
  396         /* The memory is retained by the bktr_mem module so we can unload and */
  397         /* then reload the main bktr driver module */
  398 
  399         /* removing the ops automatically destroys all related devices */
  400         dev_ops_remove_minor(&bktr_ops, /*0x0f, */device_get_unit(dev));
  401 
  402         /*
  403          * Deallocate resources.
  404          */
  405         bus_teardown_intr(dev, bktr->res_irq, bktr->res_ih);
  406         bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
  407         bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem);
  408          
  409         return 0;
  410 }
  411 
  412 /*
  413  * the shutdown routine.
  414  */
  415 static int
  416 bktr_shutdown( device_t dev )
  417 {
  418         struct bktr_softc *bktr = device_get_softc(dev);
  419 
  420         /* Disable the brooktree device */
  421         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
  422         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
  423 
  424         return 0;
  425 }
  426 
  427 
  428 /*
  429  * Special Memory Allocation
  430  */
  431 vm_offset_t
  432 get_bktr_mem( int unit, unsigned size )
  433 {
  434         vm_offset_t     addr = 0;
  435 
  436         addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0,
  437             0xffffffff, 1<<24, 0);
  438         if (addr == 0)
  439                 addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0,
  440                     0xffffffff, PAGE_SIZE, 0);
  441         if (addr == 0) {
  442                 kprintf("bktr%d: Unable to allocate %d bytes of memory.\n",
  443                         unit, size);
  444         }
  445 
  446         return( addr );
  447 }
  448 
  449 
  450 /*---------------------------------------------------------
  451 **
  452 **      BrookTree 848 character device driver routines
  453 **
  454 **---------------------------------------------------------
  455 */
  456 
  457 #define VIDEO_DEV       0x00
  458 #define TUNER_DEV       0x01
  459 #define VBI_DEV         0x02
  460 
  461 #define UNIT(x)         ((x) & 0x0f)
  462 #define FUNCTION(x)     (x >> 4)
  463 
  464 /*
  465  * 
  466  */
  467 static int
  468 bktr_open(struct dev_open_args *ap)
  469 {
  470         cdev_t dev = ap->a_head.a_dev;
  471         bktr_ptr_t      bktr;
  472         int             unit;
  473         int             result;
  474 
  475         unit = UNIT( minor(dev) );
  476 
  477         /* Get the device data */
  478         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  479         if (bktr == NULL) {
  480                 /* the device is no longer valid/functioning */
  481                 return (ENXIO);
  482         }
  483 
  484         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
  485                 return( ENXIO );        
  486 
  487         /* Record that the device is now busy */
  488         device_busy(devclass_get_device(bktr_devclass, unit)); 
  489 
  490 
  491         if (bt848_card != -1) {
  492           if ((bt848_card >> 8   == unit ) &&
  493              ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
  494             if ( bktr->bt848_card != (bt848_card & 0xff) ) {
  495               bktr->bt848_card = (bt848_card & 0xff);
  496               probeCard(bktr, FALSE, unit);
  497             }
  498           }
  499         }
  500 
  501         if (bt848_tuner != -1) {
  502           if ((bt848_tuner >> 8   == unit ) &&
  503              ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
  504             if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
  505               bktr->bt848_tuner = (bt848_tuner & 0xff);
  506               probeCard(bktr, FALSE, unit);
  507             }
  508           }
  509         }
  510 
  511         if (bt848_reverse_mute != -1) {
  512           if ((bt848_reverse_mute >> 8)   == unit ) {
  513             bktr->reverse_mute = bt848_reverse_mute & 0xff;
  514           }
  515         }
  516 
  517         if (bt848_slow_msp_audio != -1) {
  518           if ((bt848_slow_msp_audio >> 8) == unit ) {
  519               bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
  520           }
  521         }
  522 
  523 #ifdef BKTR_NEW_MSP34XX_DRIVER
  524         if (bt848_stereo_once != 0) {
  525           if ((bt848_stereo_once >> 8) == unit ) {
  526               bktr->stereo_once = (bt848_stereo_once & 0xff);
  527           }
  528         }
  529 
  530         if (bt848_amsound != -1) {
  531           if ((bt848_amsound >> 8) == unit ) {
  532               bktr->amsound = (bt848_amsound & 0xff);
  533           }
  534         }
  535 
  536         if (bt848_dolby != -1) {
  537           if ((bt848_dolby >> 8) == unit ) {
  538               bktr->dolby = (bt848_dolby & 0xff);
  539           }
  540         }
  541 #endif
  542 
  543         switch ( FUNCTION( minor(dev) ) ) {
  544         case VIDEO_DEV:
  545                 result = video_open( bktr );
  546                 break;
  547         case TUNER_DEV:
  548                 result = tuner_open( bktr );
  549                 break;
  550         case VBI_DEV:
  551                 result = vbi_open( bktr );
  552                 break;
  553         default:
  554                 result = ENXIO;
  555                 break;
  556         }
  557 
  558         /* If there was an error opening the device, undo the busy status */
  559         if (result != 0)
  560                 device_unbusy(devclass_get_device(bktr_devclass, unit)); 
  561         return( result );
  562 }
  563 
  564 
  565 /*
  566  * 
  567  */
  568 static int
  569 bktr_close(struct dev_close_args *ap)
  570 {
  571         cdev_t dev = ap->a_head.a_dev;
  572         bktr_ptr_t      bktr;
  573         int             unit;
  574         int             result;
  575 
  576         unit = UNIT( minor(dev) );
  577 
  578         /* Get the device data */
  579         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  580         if (bktr == NULL) {
  581                 /* the device is no longer valid/functioning */
  582                 return (ENXIO);
  583         }
  584 
  585         switch ( FUNCTION( minor(dev) ) ) {
  586         case VIDEO_DEV:
  587                 result = video_close( bktr );
  588                 break;
  589         case TUNER_DEV:
  590                 result = tuner_close( bktr );
  591                 break;
  592         case VBI_DEV:
  593                 result = vbi_close( bktr );
  594                 break;
  595         default:
  596                 return (ENXIO);
  597                 break;
  598         }
  599 
  600         device_unbusy(devclass_get_device(bktr_devclass, unit)); 
  601         return( result );
  602 }
  603 
  604 
  605 /*
  606  * 
  607  */
  608 static int
  609 bktr_read(struct dev_read_args *ap)
  610 {
  611         cdev_t dev = ap->a_head.a_dev;
  612         bktr_ptr_t      bktr;
  613         int             unit;
  614         
  615         unit = UNIT(minor(dev));
  616 
  617         /* Get the device data */
  618         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  619         if (bktr == NULL) {
  620                 /* the device is no longer valid/functioning */
  621                 return (ENXIO);
  622         }
  623 
  624         switch ( FUNCTION( minor(dev) ) ) {
  625         case VIDEO_DEV:
  626                 return( video_read( bktr, unit, dev, ap->a_uio ) );
  627         case VBI_DEV:
  628                 return( vbi_read( bktr, ap->a_uio, ap->a_ioflag ) );
  629         }
  630         return( ENXIO );
  631 }
  632 
  633 
  634 /*
  635  * 
  636  */
  637 static int
  638 bktr_write(struct dev_write_args *ap)
  639 {
  640         return( EINVAL ); /* XXX or ENXIO ? */
  641 }
  642 
  643 
  644 /*
  645  * 
  646  */
  647 static int
  648 bktr_ioctl(struct dev_ioctl_args *ap)
  649 {
  650         cdev_t dev = ap->a_head.a_dev;
  651         u_long cmd = ap->a_cmd;
  652         bktr_ptr_t      bktr;
  653         int             unit;
  654 
  655         unit = UNIT(minor(dev));
  656 
  657         /* Get the device data */
  658         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  659         if (bktr == NULL) {
  660                 /* the device is no longer valid/functioning */
  661                 return (ENXIO);
  662         }
  663 
  664 #ifdef BKTR_GPIO_ACCESS
  665         if (bktr->bigbuf == 0 && cmd != BT848_GPIO_GET_EN &&
  666             cmd != BT848_GPIO_SET_EN && cmd != BT848_GPIO_GET_DATA &&
  667             cmd != BT848_GPIO_SET_DATA) /* no frame buffer allocated (ioctl failed) */
  668                 return( ENOMEM );
  669 #else
  670         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
  671                 return( ENOMEM );
  672 #endif
  673 
  674         switch ( FUNCTION( minor(dev) ) ) {
  675         case VIDEO_DEV:
  676                 return( video_ioctl( bktr, unit, cmd, ap->a_data, curthread ) );
  677         case TUNER_DEV:
  678                 return( tuner_ioctl( bktr, unit, cmd, ap->a_data, curthread ) );
  679         }
  680 
  681         return( ENXIO );
  682 }
  683 
  684 
  685 /*
  686  * 
  687  */
  688 static int
  689 bktr_mmap(struct dev_mmap_args *ap)
  690 {
  691         cdev_t dev = ap->a_head.a_dev;
  692         int             unit;
  693         bktr_ptr_t      bktr;
  694 
  695         unit = UNIT(minor(dev));
  696 
  697         if (FUNCTION(minor(dev)) > 0)   /* only allow mmap on /dev/bktr[n] */
  698                 return(EINVAL);
  699 
  700         /* Get the device data */
  701         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  702         if (bktr == NULL) {
  703                 /* the device is no longer valid/functioning */
  704                 return (ENXIO);
  705         }
  706 
  707         if (ap->a_nprot & PROT_EXEC)
  708                 return(EINVAL);
  709 
  710         if (ap->a_offset < 0)
  711                 return(EINVAL);
  712 
  713         if (ap->a_offset >= bktr->alloc_pages * PAGE_SIZE)
  714                 return(EINVAL);
  715 
  716         ap->a_result = atop(vtophys(bktr->bigbuf) + ap->a_offset);
  717         return(0);
  718 }
  719 
  720 static struct filterops bktr_filterops =
  721         { FILTEROP_ISFD, NULL, bktr_filter_detach, bktr_filter };
  722 
  723 static int
  724 bktr_kqfilter(struct dev_kqfilter_args *ap)
  725 {
  726         cdev_t dev = ap->a_head.a_dev;
  727         struct knote *kn = ap->a_kn;
  728         struct klist *klist;
  729         bktr_ptr_t bktr;
  730         int unit;
  731 
  732         ap->a_result = 0;
  733 
  734         switch (kn->kn_filter) {
  735         case EVFILT_READ:
  736                 if (FUNCTION(minor(dev)) == VBI_DEV) {
  737                         unit = UNIT(minor(dev));
  738                         /* Get the device data */
  739                         bktr = (struct bktr_softc *)
  740                             devclass_get_softc(bktr_devclass, unit);
  741                         kn->kn_fop = &bktr_filterops;
  742                         kn->kn_hook = (caddr_t)bktr;
  743                         break;
  744                 }
  745                 /* fall through */
  746         default:
  747                 ap->a_result = EOPNOTSUPP;
  748                 return (0);
  749         }
  750 
  751         klist = &bktr->vbi_kq.ki_note;
  752         knote_insert(klist, kn);
  753 
  754         return (0);
  755 }
  756 
  757 static void
  758 bktr_filter_detach(struct knote *kn)
  759 {
  760         bktr_ptr_t bktr = (bktr_ptr_t)kn->kn_hook;
  761         struct klist *klist;
  762 
  763         klist = &bktr->vbi_kq.ki_note;
  764         knote_insert(klist, kn);
  765 }
  766 
  767 static int
  768 bktr_filter(struct knote *kn, long hint)
  769 {
  770         bktr_ptr_t bktr = (bktr_ptr_t)kn->kn_hook;
  771         int ready = 0;
  772 
  773         if (bktr == NULL) {
  774                 /* the device is no longer valid/functioning */
  775                 kn->kn_flags |= (EV_EOF | EV_NODATA);
  776                 return (1);
  777         }
  778 
  779         LOCK_VBI(bktr);
  780         crit_enter();
  781         if (bktr->vbisize != 0)
  782                 ready = 1;
  783         crit_exit();
  784         UNLOCK_VBI(bktr);
  785 
  786         return (ready);
  787 }

Cache object: 0630e9242690309659132ab3afcfbf09


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.