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