Merge from vendor branch LIBPCAP:
[dragonfly.git] / sys / dev / video / bktr / bktr_os.c
1 /* $FreeBSD: src/sys/dev/bktr/bktr_os.c,v 1.4.2.3 2000/10/27 00:46:09 jhb Exp $ */
2 /* $DragonFly: src/sys/dev/video/bktr/bktr_os.c,v 1.8 2004/05/13 23:49:22 dillon Exp $ */
3
4 /*
5  * This is part of the Driver for Video Capture Cards (Frame grabbers)
6  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
7  * chipset.
8  * Copyright Roger Hardiman and Amancio Hasty.
9  *
10  * bktr_os : This has all the Operating System dependant code,
11  *             probe/attach and open/close/ioctl/read/mmap
12  *             memory allocation
13  *             PCI bus interfacing
14  *             
15  *
16  */
17
18 /*
19  * 1. Redistributions of source code must retain the 
20  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
21  * All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *      This product includes software developed by Amancio Hasty and
34  *      Roger Hardiman
35  * 4. The name of the author may not be used to endorse or promote products 
36  *    derived from this software without specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
40  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
42  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
44  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
47  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48  * POSSIBILITY OF SUCH DAMAGE.
49  */
50
51
52 #if defined(__DragonFly__) || defined(__FreeBSD__)
53 #include "use_bktr.h"
54 #endif /* __FreeBSD__ */
55
56 #include "opt_bktr.h"           /* include any kernel config options */
57
58 #define FIFO_RISC_DISABLED      0
59 #define ALL_INTS_DISABLED       0
60
61
62 /*******************/
63 /* *** FreeBSD *** */
64 /*******************/
65 #if defined(__DragonFly__) || defined(__FreeBSD__)
66
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/conf.h>
70 #include <sys/uio.h>
71 #include <sys/kernel.h>
72 #include <sys/signalvar.h>
73 #include <sys/mman.h>
74 #include <sys/poll.h>
75 #include <sys/select.h>
76 #include <sys/vnode.h>
77
78 #include <vm/vm.h>
79 #include <vm/vm_kern.h>
80 #include <vm/pmap.h>
81 #include <vm/vm_extern.h>
82
83 #if defined(__DragonFly__) || (__FreeBSD_version >=400000) || (NSMBUS > 0)
84 #include <sys/bus.h>            /* used by smbus and newbus */
85 #endif
86
87 #if defined(__DragonFly__) || (__FreeBSD_version >=300000)
88 #include <machine/bus_memio.h>  /* used by bus space */
89 #include <machine/bus.h>        /* used by bus space and newbus */
90 #include <sys/bus.h>
91 #endif
92
93 #if defined(__DragonFly__) || (__FreeBSD_version >=400000)
94 #include <sys/rman.h>           /* used by newbus */
95 #include <machine/resource.h>   /* used by newbus */
96 #endif
97
98 #if defined(__DragonFly__) || (__FreeBSD_version < 500000)
99 #include <machine/clock.h>              /* for DELAY */
100 #endif
101
102 #include <bus/pci/pcivar.h>
103 #include <bus/pci/pcireg.h>
104
105 #include <sys/sysctl.h>
106 int bt848_card = -1; 
107 int bt848_tuner = -1;
108 int bt848_reverse_mute = -1; 
109 int bt848_format = -1;
110 int bt848_slow_msp_audio = -1;
111
112 SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
113 SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
114 SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
115 SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
116 SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
117 SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, "");
118
119 #if defined(__FreeBSD__) && (__FreeBSD__ == 2)
120 #define PCIR_REVID     PCI_CLASS_REG
121 #endif
122
123 #endif /* end freebsd section */
124
125
126
127 /****************/
128 /* *** BSDI *** */
129 /****************/
130 #ifdef __bsdi__
131 #endif /* __bsdi__ */
132
133
134 /**************************/
135 /* *** OpenBSD/NetBSD *** */
136 /**************************/
137 #if defined(__NetBSD__) || defined(__OpenBSD__)
138
139 #include <sys/param.h>
140 #include <sys/systm.h>
141 #include <sys/conf.h>
142 #include <sys/uio.h>
143 #include <sys/kernel.h>
144 #include <sys/signalvar.h>
145 #include <sys/mman.h>
146 #include <sys/poll.h>
147 #include <sys/select.h>
148 #include <sys/vnode.h>
149
150 #include <vm/vm.h>
151
152 #ifndef __NetBSD__
153 #include <vm/vm_kern.h>
154 #include <vm/pmap.h>
155 #include <vm/vm_extern.h>
156 #endif
157
158 #include <sys/device.h>
159 #include <dev/pci/pcivar.h>
160 #include <dev/pci/pcireg.h>
161 #include <dev/pci/pcidevs.h>
162
163 #define BKTR_DEBUG
164 #ifdef BKTR_DEBUG
165 int bktr_debug = 0;
166 #define DPR(x)  (bktr_debug ? printf x : 0)
167 #else
168 #define DPR(x)
169 #endif
170 #endif /* __NetBSD__ || __OpenBSD__ */
171
172
173 #ifdef __NetBSD__
174 #include <dev/ic/bt8xx.h>       /* NetBSD location for .h files */
175 #include <dev/pci/bktr/bktr_reg.h>
176 #include <dev/pci/bktr/bktr_tuner.h>
177 #include <dev/pci/bktr/bktr_card.h>
178 #include <dev/pci/bktr/bktr_audio.h>
179 #include <dev/pci/bktr/bktr_core.h>
180 #include <dev/pci/bktr/bktr_os.h>
181 #else                                   /* Traditional location for .h files */
182 #include <machine/ioctl_meteor.h>
183 #include <machine/ioctl_bt848.h>        /* extensions to ioctl_meteor.h */
184 #include "bktr_reg.h"
185 #include "bktr_tuner.h"
186 #include "bktr_card.h"
187 #include "bktr_audio.h"
188 #include "bktr_core.h"
189 #include "bktr_os.h"
190 #if defined(BKTR_USE_FREEBSD_SMBUS)
191 #include "bktr_i2c.h"
192 #endif
193 #endif
194
195
196
197 /****************************/
198 /* *** FreeBSD 4.x code *** */
199 /****************************/
200 #if defined(__DragonFly__) || (__FreeBSD_version >= 400000)
201
202 static int      bktr_probe( device_t dev );
203 static int      bktr_attach( device_t dev );
204 static int      bktr_detach( device_t dev );
205 static int      bktr_shutdown( device_t dev );
206 static void     bktr_intr(void *arg) { common_bktr_intr(arg); }
207
208 static device_method_t bktr_methods[] = {
209         /* Device interface */
210         DEVMETHOD(device_probe,         bktr_probe),
211         DEVMETHOD(device_attach,        bktr_attach),
212         DEVMETHOD(device_detach,        bktr_detach),
213         DEVMETHOD(device_shutdown,      bktr_shutdown),
214
215         { 0, 0 }
216 };
217
218 static driver_t bktr_driver = {
219         "bktr",
220         bktr_methods,
221         sizeof(struct bktr_softc),
222 };
223
224 static devclass_t bktr_devclass;
225
226 static  d_open_t        bktr_open;
227 static  d_close_t       bktr_close;
228 static  d_read_t        bktr_read;
229 static  d_write_t       bktr_write;
230 static  d_ioctl_t       bktr_ioctl;
231 static  d_mmap_t        bktr_mmap;
232 static  d_poll_t        bktr_poll;
233
234 #define CDEV_MAJOR 92 
235 static struct cdevsw bktr_cdevsw = {
236         /* name */      "bktr",
237         /* maj */       CDEV_MAJOR,
238         /* flags */     0,
239         /* port */      NULL,
240         /* clone */     NULL,
241
242         /* open */      bktr_open,
243         /* close */     bktr_close,
244         /* read */      bktr_read,
245         /* write */     bktr_write,
246         /* ioctl */     bktr_ioctl,
247         /* poll */      bktr_poll,
248         /* mmap */      bktr_mmap,
249         /* strategy */  nostrategy,
250         /* dump */      nodump,
251         /* psize */     nopsize
252 };
253
254 DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, 0, 0);
255 #if defined(__DragonFly__) || (__FreeBSD_version > 410000)
256 MODULE_DEPEND(bktr, bktr_mem, 1,1,1);
257 MODULE_VERSION(bktr, 1);
258 #endif
259
260
261 /*
262  * the boot time probe routine.
263  */
264 static int
265 bktr_probe( device_t dev )
266 {
267         unsigned int type = pci_get_devid(dev);
268         unsigned int rev  = pci_get_revid(dev);
269
270         if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE)
271         {
272                 switch (PCI_PRODUCT(type)) {
273                 case PCI_PRODUCT_BROOKTREE_BT848:
274                         if (rev == 0x12)
275                                 device_set_desc(dev, "BrookTree 848A");
276                         else
277                                 device_set_desc(dev, "BrookTree 848");
278                         return 0;
279                 case PCI_PRODUCT_BROOKTREE_BT849:
280                         device_set_desc(dev, "BrookTree 849A");
281                         return 0;
282                 case PCI_PRODUCT_BROOKTREE_BT878:
283                         device_set_desc(dev, "BrookTree 878");
284                         return 0;
285                 case PCI_PRODUCT_BROOKTREE_BT879:
286                         device_set_desc(dev, "BrookTree 879");
287                         return 0;
288                 }
289         };
290
291         return ENXIO;
292 }
293
294
295 /*
296  * the attach routine.
297  */
298 static int
299 bktr_attach( device_t dev )
300 {
301         u_long          latency;
302         u_long          fun;
303         u_long          val;
304         unsigned int    rev;
305         unsigned int    unit;
306         int             error = 0;
307 #ifdef BROOKTREE_IRQ
308         u_long          old_irq, new_irq;
309 #endif 
310
311         struct bktr_softc *bktr = device_get_softc(dev);
312
313         unit = device_get_unit(dev);
314
315         /* build the device name for bktr_name() */
316         snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit);
317
318         /*
319          * Enable bus mastering and Memory Mapped device
320          */
321         val = pci_read_config(dev, PCIR_COMMAND, 4);
322         val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
323         pci_write_config(dev, PCIR_COMMAND, val, 4);
324
325         /*
326          * Map control/status registers.
327          */
328         bktr->mem_rid = PCIR_MAPS;
329         bktr->res_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &bktr->mem_rid,
330                                         0, ~0, 1, RF_ACTIVE);
331
332
333         if (!bktr->res_mem) {
334                 device_printf(dev, "could not map memory\n");
335                 error = ENXIO;
336                 goto fail;
337         }
338         bktr->memt = rman_get_bustag(bktr->res_mem);
339         bktr->memh = rman_get_bushandle(bktr->res_mem);
340
341
342         /*
343          * Disable the brooktree device
344          */
345         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
346         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
347
348
349 #ifdef BROOKTREE_IRQ            /* from the configuration file */
350         old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
351         pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
352         new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
353         printf("bktr%d: attach: irq changed from %d to %d\n",
354                 unit, (old_irq & 0xff), (new_irq & 0xff));
355 #endif 
356
357         /*
358          * Allocate our interrupt.
359          */
360         bktr->irq_rid = 0;
361         bktr->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &bktr->irq_rid,
362                                 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
363         if (bktr->res_irq == NULL) {
364                 device_printf(dev, "could not map interrupt\n");
365                 error = ENXIO;
366                 goto fail;
367         }
368
369         error = bus_setup_intr(dev, bktr->res_irq, INTR_TYPE_TTY,
370                                bktr_intr, bktr, &bktr->res_ih);
371         if (error) {
372                 device_printf(dev, "could not setup irq\n");
373                 goto fail;
374
375         }
376
377
378         /* Update the Device Control Register */
379         /* on Bt878 and Bt879 cards           */
380         fun = pci_read_config( dev, 0x40, 2);
381         fun = fun | 1;  /* Enable writes to the sub-system vendor ID */
382
383 #if defined( BKTR_430_FX_MODE )
384         if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
385         fun = fun | 2;  /* Enable Intel 430 FX compatibility mode */
386 #endif
387
388 #if defined( BKTR_SIS_VIA_MODE )
389         if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
390         fun = fun | 4;  /* Enable SiS/VIA compatibility mode (usefull for
391                            OPTi chipset motherboards too */
392 #endif
393         pci_write_config(dev, 0x40, fun, 2);
394
395
396         /* XXX call bt848_i2c dependent attach() routine */
397 #if defined(BKTR_USE_FREEBSD_SMBUS)
398         if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
399                 printf("bktr%d: i2c_attach: can't attach\n", unit);
400 #endif
401
402
403 /*
404  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
405  * you have more than four, then 16 would probably be a better value.
406  */
407 #ifndef BROOKTREE_DEF_LATENCY_VALUE
408 #define BROOKTREE_DEF_LATENCY_VALUE     10
409 #endif
410         latency = pci_read_config(dev, PCI_LATENCY_TIMER, 4);
411         latency = (latency >> 8) & 0xff;
412         if ( bootverbose ) {
413                 if (latency)
414                         printf("brooktree%d: PCI bus latency is", unit);
415                 else
416                         printf("brooktree%d: PCI bus latency was 0 changing to",
417                                 unit);
418         }
419         if ( !latency ) {
420                 latency = BROOKTREE_DEF_LATENCY_VALUE;
421                 pci_write_config(dev, PCI_LATENCY_TIMER, latency<<8, 4);
422         }
423         if ( bootverbose ) {
424                 printf(" %d.\n", (int) latency);
425         }
426
427         /* read the pci device id and revision id */
428         fun = pci_get_devid(dev);
429         rev = pci_get_revid(dev);
430
431         /* call the common attach code */
432         common_bktr_attach( bktr, unit, fun, rev );
433
434         /* make the device entries */
435         bktr->bktrdev = make_dev(&bktr_cdevsw, unit,    
436                                 0, 0, 0444, "bktr%d",  unit);
437         bktr->tunerdev= make_dev(&bktr_cdevsw, unit+16,
438                                 0, 0, 0444, "tuner%d", unit);
439         bktr->vbidev  = make_dev(&bktr_cdevsw, unit+32,
440                                 0, 0, 0444, "vbi%d"  , unit);
441
442
443         /* if this is unit 0 (/dev/bktr0, /dev/tuner0, /dev/vbi0) then make */
444         /* alias entries to /dev/bktr /dev/tuner and /dev/vbi */
445 #if defined(__FreeBSD__) && (__FreeBSD_version >=500000)
446         if (unit == 0) {
447                 bktr->bktrdev_alias = make_dev_alias(bktr->bktrdev,  "bktr");
448                 bktr->tunerdev_alias= make_dev_alias(bktr->tunerdev, "tuner");
449                 bktr->vbidev_alias  = make_dev_alias(bktr->vbidev,   "vbi");
450         }
451 #endif
452
453         return 0;
454
455 fail:
456         if (bktr->res_irq)
457                 bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
458         if (bktr->res_mem)
459                 bus_release_resource(dev, SYS_RES_IRQ, bktr->mem_rid, bktr->res_mem);
460         return error;
461
462 }
463
464 /*
465  * the detach routine.
466  */
467 static int
468 bktr_detach( device_t dev )
469 {
470         unsigned int    unit;
471
472         struct bktr_softc *bktr = device_get_softc(dev);
473
474         unit = device_get_unit(dev);
475
476         /* Disable the brooktree device */
477         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
478         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
479
480         /* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
481         /* The memory is retained by the bktr_mem module so we can unload and */
482         /* then reload the main bktr driver module */
483
484         /* Unregister the /dev/bktrN, tunerN and vbiN devices */
485         destroy_dev(bktr->vbidev);
486         destroy_dev(bktr->tunerdev);
487         destroy_dev(bktr->bktrdev);
488
489         /* If this is unit 0, then destroy the alias entries too */
490 #if defined(__FreeBSD__) && (__FreeBSD_version >=500000)
491         if (unit == 0) {
492             destroy_dev(bktr->vbidev_alias);
493             destroy_dev(bktr->tunerdev_alias);
494             destroy_dev(bktr->bktrdev_alias);
495         }
496 #endif
497
498         /*
499          * Deallocate resources.
500          */
501         bus_teardown_intr(dev, bktr->res_irq, bktr->res_ih);
502         bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
503         bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem);
504          
505         return 0;
506 }
507
508 /*
509  * the shutdown routine.
510  */
511 static int
512 bktr_shutdown( device_t dev )
513 {
514         struct bktr_softc *bktr = device_get_softc(dev);
515
516         /* Disable the brooktree device */
517         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
518         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
519
520         return 0;
521 }
522
523
524 /*
525  * Special Memory Allocation
526  */
527 vm_offset_t
528 get_bktr_mem( int unit, unsigned size )
529 {
530         vm_offset_t     addr = 0;
531
532         addr = vm_page_alloc_contig(size, 0, 0xffffffff, 1<<24);
533         if (addr == 0)
534                 addr = vm_page_alloc_contig(size, 0, 0xffffffff, PAGE_SIZE);
535         if (addr == 0) {
536                 printf("bktr%d: Unable to allocate %d bytes of memory.\n",
537                         unit, size);
538         }
539
540         return( addr );
541 }
542
543
544 /*---------------------------------------------------------
545 **
546 **      BrookTree 848 character device driver routines
547 **
548 **---------------------------------------------------------
549 */
550
551 #define VIDEO_DEV       0x00
552 #define TUNER_DEV       0x01
553 #define VBI_DEV         0x02
554
555 #define UNIT(x)         ((x) & 0x0f)
556 #define FUNCTION(x)     (x >> 4)
557
558 /*
559  * 
560  */
561 int
562 bktr_open( dev_t dev, int flags, int fmt, d_thread_t *td)
563 {
564         bktr_ptr_t      bktr;
565         int             unit;
566         int             result;
567
568         unit = UNIT( minor(dev) );
569
570         /* Get the device data */
571         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
572         if (bktr == NULL) {
573                 /* the device is no longer valid/functioning */
574                 return (ENXIO);
575         }
576
577         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
578                 return( ENXIO );        
579
580         /* Record that the device is now busy */
581         device_busy(devclass_get_device(bktr_devclass, unit)); 
582
583
584         if (bt848_card != -1) {
585           if ((bt848_card >> 8   == unit ) &&
586              ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
587             if ( bktr->bt848_card != (bt848_card & 0xff) ) {
588               bktr->bt848_card = (bt848_card & 0xff);
589               probeCard(bktr, FALSE, unit);
590             }
591           }
592         }
593
594         if (bt848_tuner != -1) {
595           if ((bt848_tuner >> 8   == unit ) &&
596              ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
597             if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
598               bktr->bt848_tuner = (bt848_tuner & 0xff);
599               probeCard(bktr, FALSE, unit);
600             }
601           }
602         }
603
604         if (bt848_reverse_mute != -1) {
605           if ((bt848_reverse_mute >> 8)   == unit ) {
606             bktr->reverse_mute = bt848_reverse_mute & 0xff;
607           }
608         }
609
610         if (bt848_slow_msp_audio != -1) {
611           if ((bt848_slow_msp_audio >> 8) == unit ) {
612               bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
613           }
614         }
615
616         switch ( FUNCTION( minor(dev) ) ) {
617         case VIDEO_DEV:
618                 result = video_open( bktr );
619                 break;
620         case TUNER_DEV:
621                 result = tuner_open( bktr );
622                 break;
623         case VBI_DEV:
624                 result = vbi_open( bktr );
625                 break;
626         default:
627                 result = ENXIO;
628                 break;
629         }
630
631         /* If there was an error opening the device, undo the busy status */
632         if (result != 0)
633                 device_unbusy(devclass_get_device(bktr_devclass, unit)); 
634         return( result );
635 }
636
637
638 /*
639  * 
640  */
641 int
642 bktr_close( dev_t dev, int flags, int fmt, d_thread_t *td)
643 {
644         bktr_ptr_t      bktr;
645         int             unit;
646         int             result;
647
648         unit = UNIT( minor(dev) );
649
650         /* Get the device data */
651         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
652         if (bktr == NULL) {
653                 /* the device is no longer valid/functioning */
654                 return (ENXIO);
655         }
656
657         switch ( FUNCTION( minor(dev) ) ) {
658         case VIDEO_DEV:
659                 result = video_close( bktr );
660                 break;
661         case TUNER_DEV:
662                 result = tuner_close( bktr );
663                 break;
664         case VBI_DEV:
665                 result = vbi_close( bktr );
666                 break;
667         default:
668                 return (ENXIO);
669                 break;
670         }
671
672         device_unbusy(devclass_get_device(bktr_devclass, unit)); 
673         return( result );
674 }
675
676
677 /*
678  * 
679  */
680 int
681 bktr_read( dev_t dev, struct uio *uio, int ioflag )
682 {
683         bktr_ptr_t      bktr;
684         int             unit;
685         
686         unit = UNIT(minor(dev));
687
688         /* Get the device data */
689         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
690         if (bktr == NULL) {
691                 /* the device is no longer valid/functioning */
692                 return (ENXIO);
693         }
694
695         switch ( FUNCTION( minor(dev) ) ) {
696         case VIDEO_DEV:
697                 return( video_read( bktr, unit, dev, uio ) );
698         case VBI_DEV:
699                 return( vbi_read( bktr, uio, ioflag ) );
700         }
701         return( ENXIO );
702 }
703
704
705 /*
706  * 
707  */
708 int
709 bktr_write( dev_t dev, struct uio *uio, int ioflag )
710 {
711         return( EINVAL ); /* XXX or ENXIO ? */
712 }
713
714
715 /*
716  * 
717  */
718 int
719 bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td)
720 {
721         bktr_ptr_t      bktr;
722         int             unit;
723
724         unit = UNIT(minor(dev));
725
726         /* Get the device data */
727         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
728         if (bktr == NULL) {
729                 /* the device is no longer valid/functioning */
730                 return (ENXIO);
731         }
732
733         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
734                 return( ENOMEM );
735
736         switch ( FUNCTION( minor(dev) ) ) {
737         case VIDEO_DEV:
738                 return( video_ioctl( bktr, unit, cmd, arg, td ) );
739         case TUNER_DEV:
740                 return( tuner_ioctl( bktr, unit, cmd, arg, td ) );
741         }
742
743         return( ENXIO );
744 }
745
746
747 /*
748  * 
749  */
750 int
751 bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
752 {
753         int             unit;
754         bktr_ptr_t      bktr;
755
756         unit = UNIT(minor(dev));
757
758         if (FUNCTION(minor(dev)) > 0)   /* only allow mmap on /dev/bktr[n] */
759                 return( -1 );
760
761         /* Get the device data */
762         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
763         if (bktr == NULL) {
764                 /* the device is no longer valid/functioning */
765                 return (ENXIO);
766         }
767
768         if (nprot & PROT_EXEC)
769                 return( -1 );
770
771         if (offset < 0)
772                 return( -1 );
773
774         if (offset >= bktr->alloc_pages * PAGE_SIZE)
775                 return( -1 );
776
777         return( atop(vtophys(bktr->bigbuf) + offset) );
778 }
779
780 int bktr_poll( dev_t dev, int events, d_thread_t *td)
781 {
782         int             unit;
783         bktr_ptr_t      bktr;
784         int revents = 0; 
785         DECLARE_INTR_MASK(s);
786
787         unit = UNIT(minor(dev));
788
789         /* Get the device data */
790         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
791         if (bktr == NULL) {
792                 /* the device is no longer valid/functioning */
793                 return (ENXIO);
794         }
795
796         DISABLE_INTR(s);
797
798         if (events & (POLLIN | POLLRDNORM)) {
799
800                 switch ( FUNCTION( minor(dev) ) ) {
801                 case VBI_DEV:
802                         if(bktr->vbisize == 0)
803                                 selrecord(td, &bktr->vbi_select);
804                         else
805                                 revents |= events & (POLLIN | POLLRDNORM);
806                         break;
807                 }
808         }
809
810         ENABLE_INTR(s);
811
812         return (revents);
813 }
814
815 #endif          /* FreeBSD 4.x specific kernel interface routines */
816
817 /**********************************/
818 /* *** FreeBSD 2.2.x and 3.x  *** */
819 /**********************************/
820
821 #if defined(__FreeBSD__) && (((__FreeBSD__ == 2) || (__FreeBSD__ == 3)))
822
823 static bktr_reg_t brooktree[ NBKTR ];
824
825 static const char*      bktr_probe( pcici_t tag, pcidi_t type );
826 static void             bktr_attach( pcici_t tag, int unit );
827 static void             bktr_intr(void *arg) { common_bktr_intr(arg); }
828
829 static u_long   bktr_count;
830
831 static struct   pci_device bktr_device = {
832         "bktr",
833         bktr_probe,
834         bktr_attach,
835         &bktr_count
836 };
837
838 DATA_SET (pcidevice_set, bktr_device);
839
840 static  d_open_t        bktr_open;
841 static  d_close_t       bktr_close;
842 static  d_read_t        bktr_read;
843 static  d_write_t       bktr_write;
844 static  d_ioctl_t       bktr_ioctl;
845 static  d_mmap_t        bktr_mmap;
846 static  d_poll_t        bktr_poll;
847
848 #define CDEV_MAJOR 92 
849 static struct cdevsw bktr_cdevsw = 
850 {
851         bktr_open,      bktr_close,     bktr_read,      bktr_write,
852         bktr_ioctl,     nostop,         nullreset,      nodevtotty,
853         bktr_poll,      bktr_mmap,      NULL,           "bktr",
854         NULL,           -1
855 };
856
857 static int bktr_devsw_installed;
858
859 static void
860 bktr_drvinit( void *unused )
861 {
862         dev_t dev;
863
864         if ( ! bktr_devsw_installed ) {
865                 dev = makedev(CDEV_MAJOR, 0);
866                 cdevsw_add(&dev,&bktr_cdevsw, NULL);
867                 bktr_devsw_installed = 1;
868         }
869 }
870
871 SYSINIT(bktrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bktr_drvinit,NULL)
872
873 /*
874  * the boot time probe routine.
875  */
876 static const char*
877 bktr_probe( pcici_t tag, pcidi_t type )
878 {
879         unsigned int rev = pci_conf_read( tag, PCIR_REVID) & 0x000000ff;
880
881         if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE)
882         {
883                 switch (PCI_PRODUCT(type)) {
884                 case PCI_PRODUCT_BROOKTREE_BT848:
885                         if (rev == 0x12) return("BrookTree 848A");
886                         else             return("BrookTree 848");
887                 case PCI_PRODUCT_BROOKTREE_BT849:
888                         return("BrookTree 849A");
889                 case PCI_PRODUCT_BROOKTREE_BT878:
890                         return("BrookTree 878");
891                 case PCI_PRODUCT_BROOKTREE_BT879:
892                         return("BrookTree 879");
893                 }
894         };
895
896         return ((char *)0);
897 }
898
899 /*
900  * the attach routine.
901  */
902 static  void
903 bktr_attach( pcici_t tag, int unit )
904 {
905         bktr_ptr_t      bktr;
906         u_long          latency;
907         u_long          fun;
908         unsigned int    rev;
909         unsigned long   base;
910 #ifdef BROOKTREE_IRQ
911         u_long          old_irq, new_irq;
912 #endif 
913
914         bktr = &brooktree[unit];
915
916         if (unit >= NBKTR) {
917                 printf("brooktree%d: attach: only %d units configured.\n",
918                         unit, NBKTR);
919                 printf("brooktree%d: attach: invalid unit number.\n", unit);
920                 return;
921         }
922
923         /* build the device name for bktr_name() */
924         snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit);
925
926         /* Enable Memory Mapping */
927         fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
928         pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 2);
929
930         /* Enable Bus Mastering */
931         fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
932         pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 4);
933
934         bktr->tag = tag;
935
936
937         /*
938          * Map control/status registers
939          */
940         pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &base,
941                      &bktr->phys_base );
942 #if defined(__DragonFly__) || (__FreeBSD_version >= 300000)
943         bktr->memt = I386_BUS_SPACE_MEM; /* XXX should use proper bus space */
944         bktr->memh = (bus_space_handle_t)base; /* XXX functions here */
945 #endif
946
947         /*
948          * Disable the brooktree device
949          */
950         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
951         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
952
953 #ifdef BROOKTREE_IRQ            /* from the configuration file */
954         old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
955         pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
956         new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
957         printf("bktr%d: attach: irq changed from %d to %d\n",
958                 unit, (old_irq & 0xff), (new_irq & 0xff));
959 #endif 
960
961         /*
962          * setup the interrupt handling routine
963          */
964         pci_map_int(tag, bktr_intr, (void*) bktr, &tty_imask);
965
966
967         /* Update the Device Control Register */
968         /* on Bt878 and Bt879 cards */
969         fun = pci_conf_read(tag, 0x40);
970         fun = fun | 1;  /* Enable writes to the sub-system vendor ID */
971
972 #if defined( BKTR_430_FX_MODE )
973         if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
974         fun = fun | 2;  /* Enable Intel 430 FX compatibility mode */
975 #endif
976
977 #if defined( BKTR_SIS_VIA_MODE )
978         if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
979         fun = fun | 4;  /* Enable SiS/VIA compatibility mode (usefull for
980                            OPTi chipset motherboards too */
981 #endif
982         pci_conf_write(tag, 0x40, fun);
983
984
985         /* XXX call bt848_i2c dependent attach() routine */
986 #if defined(BKTR_USE_FREEBSD_SMBUS)
987         if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
988                 printf("bktr%d: i2c_attach: can't attach\n", unit);
989 #endif
990
991
992 /*
993  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
994  * you have more than four, then 16 would probably be a better value.
995  */
996 #ifndef BROOKTREE_DEF_LATENCY_VALUE
997 #define BROOKTREE_DEF_LATENCY_VALUE     10
998 #endif
999         latency = pci_conf_read(tag, PCI_LATENCY_TIMER);
1000         latency = (latency >> 8) & 0xff;
1001         if ( bootverbose ) {
1002                 if (latency)
1003                         printf("brooktree%d: PCI bus latency is", unit);
1004                 else
1005                         printf("brooktree%d: PCI bus latency was 0 changing to",
1006                                 unit);
1007         }
1008         if ( !latency ) {
1009                 latency = BROOKTREE_DEF_LATENCY_VALUE;
1010                 pci_conf_write(tag, PCI_LATENCY_TIMER,  latency<<8);
1011         }
1012         if ( bootverbose ) {
1013                 printf(" %d.\n", (int) latency);
1014         }
1015
1016
1017         /* read the pci device id and revision id */
1018         fun = pci_conf_read(tag, PCI_ID_REG);
1019         rev = pci_conf_read(tag, PCIR_REVID) & 0x000000ff;
1020
1021         /* call the common attach code */
1022         common_bktr_attach( bktr, unit, fun, rev );
1023
1024 }
1025
1026
1027 /*
1028  * Special Memory Allocation
1029  */
1030 vm_offset_t
1031 get_bktr_mem( int unit, unsigned size )
1032 {
1033         vm_offset_t     addr = 0;
1034
1035         addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24);
1036         if (addr == 0)
1037                 addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff,
1038                                                                 PAGE_SIZE);
1039         if (addr == 0) {
1040                 printf("bktr%d: Unable to allocate %d bytes of memory.\n",
1041                         unit, size);
1042         }
1043
1044         return( addr );
1045 }
1046
1047 /*---------------------------------------------------------
1048 **
1049 **      BrookTree 848 character device driver routines
1050 **
1051 **---------------------------------------------------------
1052 */
1053
1054
1055 #define VIDEO_DEV       0x00
1056 #define TUNER_DEV       0x01
1057 #define VBI_DEV         0x02
1058
1059 #define UNIT(x)         ((x) & 0x0f)
1060 #define FUNCTION(x)     ((x >> 4) & 0x0f)
1061
1062
1063 /*
1064  * 
1065  */
1066 int
1067 bktr_open( dev_t dev, int flags, int fmt, d_thread_t *td)
1068 {
1069         bktr_ptr_t      bktr;
1070         int             unit;
1071
1072         unit = UNIT( minor(dev) );
1073         if (unit >= NBKTR)                      /* unit out of range */
1074                 return( ENXIO );
1075
1076         bktr = &(brooktree[ unit ]);
1077
1078         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
1079                 return( ENXIO );        
1080
1081
1082         if (bt848_card != -1) {
1083           if ((bt848_card >> 8   == unit ) &&
1084              ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
1085             if ( bktr->bt848_card != (bt848_card & 0xff) ) {
1086               bktr->bt848_card = (bt848_card & 0xff);
1087               probeCard(bktr, FALSE, unit);
1088             }
1089           }
1090         }
1091
1092         if (bt848_tuner != -1) {
1093           if ((bt848_tuner >> 8   == unit ) &&
1094              ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
1095             if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
1096               bktr->bt848_tuner = (bt848_tuner & 0xff);
1097               probeCard(bktr, FALSE, unit);
1098             }
1099           }
1100         }
1101
1102         if (bt848_reverse_mute != -1) {
1103           if ((bt848_reverse_mute >> 8)   == unit ) {
1104             bktr->reverse_mute = bt848_reverse_mute & 0xff;
1105           }
1106         }
1107
1108         if (bt848_slow_msp_audio != -1) {
1109           if ((bt848_slow_msp_audio >> 8) == unit ) {
1110               bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
1111           }
1112         }
1113
1114         switch ( FUNCTION( minor(dev) ) ) {
1115         case VIDEO_DEV:
1116                 return( video_open( bktr ) );
1117         case TUNER_DEV:
1118                 return( tuner_open( bktr ) );
1119         case VBI_DEV:
1120                 return( vbi_open( bktr ) );
1121         }
1122         return( ENXIO );
1123 }
1124
1125
1126 /*
1127  * 
1128  */
1129 int
1130 bktr_close( dev_t dev, int flags, int fmt, d_thread_t *td)
1131 {
1132         bktr_ptr_t      bktr;
1133         int             unit;
1134
1135         unit = UNIT( minor(dev) );
1136         if (unit >= NBKTR)                      /* unit out of range */
1137                 return( ENXIO );
1138
1139         bktr = &(brooktree[ unit ]);
1140
1141         switch ( FUNCTION( minor(dev) ) ) {
1142         case VIDEO_DEV:
1143                 return( video_close( bktr ) );
1144         case TUNER_DEV:
1145                 return( tuner_close( bktr ) );
1146         case VBI_DEV:
1147                 return( vbi_close( bktr ) );
1148         }
1149
1150         return( ENXIO );
1151 }
1152
1153 /*
1154  * 
1155  */
1156 int
1157 bktr_read( dev_t dev, struct uio *uio, int ioflag )
1158 {
1159         bktr_ptr_t      bktr;
1160         int             unit;
1161         
1162         unit = UNIT(minor(dev));
1163         if (unit >= NBKTR)      /* unit out of range */
1164                 return( ENXIO );
1165
1166         bktr = &(brooktree[unit]);
1167
1168         switch ( FUNCTION( minor(dev) ) ) {
1169         case VIDEO_DEV:
1170                 return( video_read( bktr, unit, dev, uio ) );
1171         case VBI_DEV:
1172                 return( vbi_read( bktr, uio, ioflag ) );
1173         }
1174         return( ENXIO );
1175 }
1176
1177
1178 /*
1179  * 
1180  */
1181 int
1182 bktr_write( dev_t dev, struct uio *uio, int ioflag )
1183 {
1184         return( EINVAL ); /* XXX or ENXIO ? */
1185 }
1186
1187 /*
1188  * 
1189  */
1190 int
1191 bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td)
1192 {
1193         bktr_ptr_t      bktr;
1194         int             unit;
1195
1196         unit = UNIT(minor(dev));
1197         if (unit >= NBKTR)      /* unit out of range */
1198                 return( ENXIO );
1199
1200         bktr = &(brooktree[ unit ]);
1201
1202         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
1203                 return( ENOMEM );
1204
1205         switch ( FUNCTION( minor(dev) ) ) {
1206         case VIDEO_DEV:
1207                 return( video_ioctl( bktr, unit, cmd, arg, td ) );
1208         case TUNER_DEV:
1209                 return( tuner_ioctl( bktr, unit, cmd, arg, td ) );
1210         }
1211
1212         return( ENXIO );
1213 }
1214
1215 /*
1216  * bktr_mmap.
1217  * Note: 2.2.5/2.2.6/2.2.7/3.0 users must manually
1218  * edit the line below and change  "vm_offset_t" to "int"
1219  */
1220 int bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
1221
1222 {
1223         int             unit;
1224         bktr_ptr_t      bktr;
1225
1226         unit = UNIT(minor(dev));
1227
1228         if (unit >= NBKTR || FUNCTION(minor(dev)) > 0)
1229                 return( -1 );
1230
1231         bktr = &(brooktree[ unit ]);
1232
1233         if (nprot & PROT_EXEC)
1234                 return( -1 );
1235
1236         if (offset < 0)
1237                 return( -1 );
1238
1239         if (offset >= bktr->alloc_pages * PAGE_SIZE)
1240                 return( -1 );
1241
1242         return( i386_btop(vtophys(bktr->bigbuf) + offset) );
1243 }
1244
1245 int bktr_poll( dev_t dev, int events, d_thread_t *td)
1246 {
1247         int             unit;
1248         bktr_ptr_t      bktr;
1249         int revents = 0; 
1250
1251         unit = UNIT(minor(dev));
1252
1253         if (unit >= NBKTR)
1254                 return( -1 );
1255
1256         bktr = &(brooktree[ unit ]);
1257
1258         disable_intr();
1259
1260         if (events & (POLLIN | POLLRDNORM)) {
1261
1262                 switch ( FUNCTION( minor(dev) ) ) {
1263                 case VBI_DEV:
1264                         if(bktr->vbisize == 0)
1265                                 selrecord(p, &bktr->vbi_select);
1266                         else
1267                                 revents |= events & (POLLIN | POLLRDNORM);
1268                         break;
1269                 }
1270         }
1271
1272         enable_intr();
1273
1274         return (revents);
1275 }
1276
1277
1278 #endif          /* FreeBSD 2.2.x and 3.x specific kernel interface routines */
1279
1280
1281 /*****************/
1282 /* *** BSDI  *** */
1283 /*****************/
1284
1285 #if defined(__bsdi__)
1286 #endif          /* __bsdi__ BSDI specific kernel interface routines */
1287
1288
1289 /*****************************/
1290 /* *** OpenBSD / NetBSD  *** */
1291 /*****************************/
1292 #if defined(__NetBSD__) || defined(__OpenBSD__)
1293
1294 #define IPL_VIDEO       IPL_BIO         /* XXX */
1295
1296 static  int             bktr_intr(void *arg) { return common_bktr_intr(arg); }
1297
1298 #define bktr_open       bktropen
1299 #define bktr_close      bktrclose
1300 #define bktr_read       bktrread
1301 #define bktr_write      bktrwrite
1302 #define bktr_ioctl      bktrioctl
1303 #define bktr_mmap       bktrmmap
1304
1305 vm_offset_t vm_page_alloc_contig(vm_offset_t, vm_offset_t,
1306                                  vm_offset_t, vm_offset_t);
1307
1308 #if defined(__OpenBSD__)
1309 static int      bktr_probe (struct device *, void *, void *);
1310 #else
1311 static int      bktr_probe (struct device *, struct cfdata *, void *);
1312 #endif
1313 static void     bktr_attach (struct device *, struct device *, void *);
1314
1315 struct cfattach bktr_ca = {
1316         sizeof(struct bktr_softc), bktr_probe, bktr_attach
1317 };
1318
1319 #if defined(__NetBSD__)
1320 extern struct cfdriver bktr_cd;
1321 #else
1322 struct cfdriver bktr_cd = {
1323         NULL, "bktr", DV_DULL
1324 };
1325 #endif
1326
1327 int
1328 bktr_probe(parent, match, aux)
1329         struct device *parent;
1330 #if defined(__OpenBSD__)
1331         void *match;
1332 #else
1333         struct cfdata *match;
1334 #endif
1335         void *aux;
1336 {
1337         struct pci_attach_args *pa = aux;
1338
1339         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROOKTREE &&
1340             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT848 ||
1341              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849 ||
1342              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT878 ||
1343              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT879))
1344                 return 1;
1345
1346         return 0;
1347 }
1348
1349
1350 /*
1351  * the attach routine.
1352  */
1353 static void
1354 bktr_attach(struct device *parent, struct device *self, void *aux)
1355 {
1356         bktr_ptr_t      bktr;
1357         u_long          latency;
1358         u_long          fun;
1359         unsigned int    rev;
1360
1361 #if defined(__OpenBSD__)
1362         struct pci_attach_args *pa = aux;
1363         pci_chipset_tag_t pc = pa->pa_pc;
1364
1365         pci_intr_handle_t ih;
1366         const char *intrstr;
1367         int retval;
1368         int unit;
1369
1370         bktr = (bktr_ptr_t)self;
1371         unit = bktr->bktr_dev.dv_unit;
1372
1373         bktr->pc = pa->pa_pc;
1374         bktr->tag = pa->pa_tag;
1375         bktr->dmat = pa->pa_dmat;
1376
1377         /*
1378          * map memory
1379          */
1380         bktr->memt = pa->pa_memt;
1381         retval = pci_mem_find(pc, pa->pa_tag, PCI_MAPREG_START, 
1382                               &bktr->phys_base, &bktr->obmemsz, NULL);
1383         if (!retval)
1384                 retval = bus_space_map(pa->pa_memt, bktr->phys_base,
1385                                        bktr->obmemsz, 0, &bktr->memh);
1386         if (retval) {
1387                 printf(": couldn't map memory\n");
1388                 return;
1389         }
1390
1391
1392         /*
1393          * map interrupt
1394          */
1395         if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
1396                          pa->pa_intrline, &ih)) {
1397                 printf(": couldn't map interrupt\n");
1398                 return;
1399         }
1400         intrstr = pci_intr_string(pa->pa_pc, ih);
1401
1402         bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
1403                                       bktr_intr, bktr, bktr->bktr_dev.dv_xname);
1404         if (bktr->ih == NULL) {
1405                 printf(": couldn't establish interrupt");
1406                 if (intrstr != NULL)    
1407                         printf(" at %s", intrstr);
1408                 printf("\n");
1409                 return;
1410         }
1411
1412         if (intrstr != NULL)
1413                 printf(": %s\n", intrstr);
1414 #endif /* __OpenBSD__ */
1415
1416 #if defined(__NetBSD__) 
1417         struct pci_attach_args *pa = aux;
1418         pci_intr_handle_t ih;
1419         const char *intrstr;
1420         int retval;
1421         int unit;
1422
1423         bktr = (bktr_ptr_t)self;
1424         unit = bktr->bktr_dev.dv_unit;
1425         bktr->dmat = pa->pa_dmat;
1426
1427         printf("\n");
1428
1429         /*
1430          * map memory
1431          */
1432         retval = pci_mapreg_map(pa, PCI_MAPREG_START,
1433                                 PCI_MAPREG_TYPE_MEM
1434                                 | PCI_MAPREG_MEM_TYPE_32BIT, 0,
1435                                 &bktr->memt, &bktr->memh, NULL,
1436                                 &bktr->obmemsz);
1437         DPR(("pci_mapreg_map: memt %x, memh %x, size %x\n",
1438              bktr->memt, (u_int)bktr->memh, (u_int)bktr->obmemsz));
1439         if (retval) {
1440                 printf("%s: couldn't map memory\n", bktr_name(bktr));
1441                 return;
1442         }
1443
1444         /*
1445          * Disable the brooktree device
1446          */
1447         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1448         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1449         
1450         /*
1451          * map interrupt
1452          */
1453         if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
1454                          pa->pa_intrline, &ih)) {
1455                 printf("%s: couldn't map interrupt\n",
1456                        bktr_name(bktr));
1457                 return;
1458         }
1459         intrstr = pci_intr_string(pa->pa_pc, ih);
1460         bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
1461                                       bktr_intr, bktr);
1462         if (bktr->ih == NULL) {
1463                 printf("%s: couldn't establish interrupt",
1464                        bktr_name(bktr));
1465                 if (intrstr != NULL)
1466                         printf(" at %s", intrstr);
1467                 printf("\n");
1468                 return;
1469         }
1470         if (intrstr != NULL)
1471                 printf("%s: interrupting at %s\n", bktr_name(bktr),
1472                        intrstr);
1473 #endif /* __NetBSD__ */
1474         
1475 /*
1476  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
1477  * you have more than four, then 16 would probably be a better value.
1478  */
1479 #ifndef BROOKTREE_DEF_LATENCY_VALUE
1480 #define BROOKTREE_DEF_LATENCY_VALUE     10
1481 #endif
1482         latency = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_LATENCY_TIMER);
1483         latency = (latency >> 8) & 0xff;
1484
1485         if (!latency) {
1486                 if (bootverbose) {
1487                         printf("%s: PCI bus latency was 0 changing to %d",
1488                                bktr_name(bktr), BROOKTREE_DEF_LATENCY_VALUE);
1489                 }
1490                 latency = BROOKTREE_DEF_LATENCY_VALUE;
1491                 pci_conf_write(pa->pa_pc, pa->pa_tag, 
1492                                PCI_LATENCY_TIMER, latency<<8);
1493         }
1494
1495
1496         /* Enabled Bus Master
1497            XXX: check if all old DMA is stopped first (e.g. after warm
1498            boot) */
1499         fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
1500         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
1501                        fun | PCI_COMMAND_MASTER_ENABLE);
1502
1503         /* read the pci id and determine the card type */
1504         fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
1505         rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0x000000ff;
1506
1507         common_bktr_attach(bktr, unit, fun, rev);
1508 }
1509
1510
1511 /*
1512  * Special Memory Allocation
1513  */
1514 vm_offset_t
1515 get_bktr_mem(bktr, dmapp, size)
1516         bktr_ptr_t bktr;
1517         bus_dmamap_t *dmapp;
1518         unsigned int size;
1519 {
1520         bus_dma_tag_t dmat = bktr->dmat;
1521         bus_dma_segment_t seg;
1522         bus_size_t align;
1523         int rseg;
1524         caddr_t kva;
1525
1526         /*
1527          * Allocate a DMA area
1528          */
1529         align = 1 << 24;
1530         if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
1531                              &rseg, BUS_DMA_NOWAIT)) {
1532                 align = PAGE_SIZE;
1533                 if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
1534                                      &rseg, BUS_DMA_NOWAIT)) {
1535                         printf("%s: Unable to dmamem_alloc of %d bytes\n",
1536                                bktr_name(bktr), size);
1537                         return 0;
1538                 }
1539         }
1540         if (bus_dmamem_map(dmat, &seg, rseg, size,
1541                            &kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1542                 printf("%s: Unable to dmamem_map of %d bytes\n",
1543                         bktr_name(bktr), size);
1544                 bus_dmamem_free(dmat, &seg, rseg);
1545                 return 0;
1546         }
1547 #ifdef __OpenBSD__
1548         bktr->dm_mapsize = size;
1549 #endif
1550         /*
1551          * Create and locd the DMA map for the DMA area
1552          */
1553         if (bus_dmamap_create(dmat, size, 1, size, 0, BUS_DMA_NOWAIT, dmapp)) {
1554                 printf("%s: Unable to dmamap_create of %d bytes\n",
1555                         bktr_name(bktr), size);
1556                 bus_dmamem_unmap(dmat, kva, size);
1557                 bus_dmamem_free(dmat, &seg, rseg);
1558                 return 0;
1559         }
1560         if (bus_dmamap_load(dmat, *dmapp, kva, size, NULL, BUS_DMA_NOWAIT)) {
1561                 printf("%s: Unable to dmamap_load of %d bytes\n",
1562                         bktr_name(bktr), size);
1563                 bus_dmamem_unmap(dmat, kva, size);
1564                 bus_dmamem_free(dmat, &seg, rseg);
1565                 bus_dmamap_destroy(dmat, *dmapp);
1566                 return 0;
1567         }
1568         return (vm_offset_t)kva;
1569 }
1570
1571 void
1572 free_bktr_mem(bktr, dmap, kva)
1573         bktr_ptr_t bktr;
1574         bus_dmamap_t dmap;
1575         vm_offset_t kva;
1576 {
1577         bus_dma_tag_t dmat = bktr->dmat;
1578
1579 #ifdef __NetBSD__ 
1580         bus_dmamem_unmap(dmat, (caddr_t)kva, dmap->dm_mapsize);
1581 #else
1582         bus_dmamem_unmap(dmat, (caddr_t)kva, bktr->dm_mapsize);
1583 #endif
1584         bus_dmamem_free(dmat, dmap->dm_segs, 1);
1585         bus_dmamap_destroy(dmat, dmap);
1586 }
1587
1588
1589 /*---------------------------------------------------------
1590 **
1591 **      BrookTree 848 character device driver routines
1592 **
1593 **---------------------------------------------------------
1594 */
1595
1596
1597 #define VIDEO_DEV       0x00
1598 #define TUNER_DEV       0x01
1599 #define VBI_DEV         0x02
1600
1601 #define UNIT(x)         (minor((x) & 0x0f))
1602 #define FUNCTION(x)     (minor((x >> 4) & 0x0f))
1603
1604 /*
1605  * 
1606  */
1607 int
1608 bktr_open(dev_t dev, int flags, int fmt, d_thread_t *td)
1609 {
1610         bktr_ptr_t      bktr;
1611         int             unit;
1612
1613         unit = UNIT(dev);
1614
1615         /* unit out of range */
1616         if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
1617                 return(ENXIO);
1618
1619         bktr = bktr_cd.cd_devs[unit];
1620
1621         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
1622                 return(ENXIO);  
1623
1624         switch (FUNCTION(dev)) {
1625         case VIDEO_DEV:
1626                 return(video_open(bktr));
1627         case TUNER_DEV:
1628                 return(tuner_open(bktr));
1629         case VBI_DEV:
1630                 return(vbi_open(bktr));
1631         }
1632
1633         return(ENXIO);
1634 }
1635
1636
1637 /*
1638  * 
1639  */
1640 int
1641 bktr_close(dev_t dev, int flags, int fmt, d_thread_t *td)
1642 {
1643         bktr_ptr_t      bktr;
1644         int             unit;
1645
1646         unit = UNIT(dev);
1647
1648         bktr = bktr_cd.cd_devs[unit];
1649
1650         switch (FUNCTION(dev)) {
1651         case VIDEO_DEV:
1652                 return(video_close(bktr));
1653         case TUNER_DEV:
1654                 return(tuner_close(bktr));
1655         case VBI_DEV:
1656                 return(vbi_close(bktr));
1657         }
1658
1659         return(ENXIO);
1660 }
1661
1662 /*
1663  * 
1664  */
1665 int
1666 bktr_read(dev_t dev, struct uio *uio, int ioflag)
1667 {
1668         bktr_ptr_t      bktr;
1669         int             unit;
1670         
1671         unit = UNIT(dev);
1672
1673         bktr = bktr_cd.cd_devs[unit];
1674
1675         switch (FUNCTION(dev)) {
1676         case VIDEO_DEV:
1677                 return(video_read(bktr, unit, dev, uio));
1678         case VBI_DEV:
1679                 return(vbi_read(bktr, uio, ioflag));
1680         }
1681
1682         return(ENXIO);
1683 }
1684
1685
1686 /*
1687  * 
1688  */
1689 int
1690 bktr_write(dev_t dev, struct uio *uio, int ioflag)
1691 {
1692         /* operation not supported */
1693         return(EOPNOTSUPP);
1694 }
1695
1696 /*
1697  * 
1698  */
1699 int
1700 bktr_ioctl(dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td)
1701 {
1702         bktr_ptr_t      bktr;
1703         int             unit;
1704
1705         unit = UNIT(dev);
1706
1707         bktr = bktr_cd.cd_devs[unit];
1708
1709         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
1710                 return(ENOMEM);
1711
1712         switch (FUNCTION(dev)) {
1713         case VIDEO_DEV:
1714                 return(video_ioctl(bktr, unit, cmd, arg, td));
1715         case TUNER_DEV:
1716                 return(tuner_ioctl(bktr, unit, cmd, arg, td));
1717         }
1718
1719         return(ENXIO);
1720 }
1721
1722 /*
1723  * 
1724  */
1725 paddr_t
1726 bktr_mmap(dev_t dev, off_t offset, int nprot)
1727 {
1728         int             unit;
1729         bktr_ptr_t      bktr;
1730
1731         unit = UNIT(dev);
1732
1733         if (FUNCTION(dev) > 0)  /* only allow mmap on /dev/bktr[n] */
1734                 return(-1);
1735
1736         bktr = bktr_cd.cd_devs[unit];
1737
1738         if ((vaddr_t)offset < 0)
1739                 return(-1);
1740
1741         if ((vaddr_t)offset >= bktr->alloc_pages * PAGE_SIZE)
1742                 return(-1);
1743
1744 #ifdef __NetBSD__
1745         return (bus_dmamem_mmap(bktr->dmat, bktr->dm_mem->dm_segs, 1,
1746                                 (vaddr_t)offset, nprot, BUS_DMA_WAITOK));
1747 #else
1748         return(i386_btop(vtophys(bktr->bigbuf) + offset));
1749 #endif
1750 }
1751
1752 #endif /* __NetBSD__ || __OpenBSD__ */