bktr_os.c revision 52995
1/* $FreeBSD: head/sys/dev/bktr/bktr_os.c 52995 1999-11-08 07:20:07Z peter $ */
2
3/*
4 * This is part of the Driver for Video Capture Cards (Frame grabbers)
5 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
6 * chipset.
7 * Copyright Roger Hardiman and Amancio Hasty.
8 *
9 * bktr_os : This has all the Operating System dependant code,
10 *             probe/attach and open/close/ioctl/read/mmap
11 *             memory allocation
12 *             PCI bus interfacing
13 *
14 *
15 */
16
17/*
18 * 1. Redistributions of source code must retain the
19 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 *    notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 *    notice, this list of conditions and the following disclaimer in the
29 *    documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 *    must display the following acknowledgement:
32 *	This product includes software developed by Amancio Hasty and
33 *      Roger Hardiman
34 * 4. The name of the author may not be used to endorse or promote products
35 *    derived from this software without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
41 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
46 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 * POSSIBILITY OF SUCH DAMAGE.
48 */
49
50
51#ifdef __FreeBSD__
52#include "bktr.h"
53#include "opt_bktr.h"
54#include "opt_devfs.h"
55#endif /* __FreeBSD__ */
56
57#if defined(__NetBSD__) || defined(__OpenBSD__)
58#include "bktr.h"
59#include "pci.h"
60#endif /* __NetBSD__  || __OpenBSD__ */
61
62#define FIFO_RISC_DISABLED      0
63#define ALL_INTS_DISABLED       0
64
65#include <sys/param.h>
66#include <sys/systm.h>
67#include <sys/conf.h>
68#include <sys/uio.h>
69#include <sys/kernel.h>
70#include <sys/signalvar.h>
71#include <sys/mman.h>
72#include <sys/poll.h>
73#include <sys/select.h>
74#include <sys/vnode.h>
75
76#include <vm/vm.h>
77#include <vm/vm_kern.h>
78#include <vm/pmap.h>
79#include <vm/vm_extern.h>
80
81/*******************/
82/* *** FreeBSD *** */
83/*******************/
84#ifdef __FreeBSD__
85
86#if (__FreeBSD_version < 400000)
87#ifdef DEVFS
88#include <sys/devfsext.h>
89#endif /* DEVFS */
90#endif
91
92#if (__FreeBSD_version >=400000) || (NSMBUS > 0)
93#include <sys/bus.h>		/* used by smbus and newbus */
94#endif
95
96#if (__FreeBSD_version >=400000)
97#include <machine/bus.h>	/* used by newbus */
98#include <sys/rman.h>		/* used by newbus */
99#include <machine/resource.h>	/* used by newbus */
100#endif
101
102#include <machine/clock.h>      /* for DELAY */
103#include <pci/pcivar.h>
104#include <pci/pcireg.h>
105
106#include <machine/ioctl_meteor.h>
107#include <machine/ioctl_bt848.h>	/* extensions to ioctl_meteor.h */
108#include <dev/bktr/bktr_reg.h>
109#include <dev/bktr/bktr_tuner.h>
110#include <dev/bktr/bktr_card.h>
111#include <dev/bktr/bktr_audio.h>
112#include <dev/bktr/bktr_core.h>
113#include <dev/bktr/bktr_os.h>
114
115#if (NSMBUS > 0)
116#include <dev/bktr/bktr_i2c.h>
117#endif
118
119#include <sys/sysctl.h>
120int bt848_card = -1;
121int bt848_tuner = -1;
122int bt848_reverse_mute = -1;
123int bt848_format = -1;
124
125SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
126SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
127SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
128SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
129SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
130
131#if (__FreeBSD_version >= 300000)
132  typedef u_long ioctl_cmd_t;
133#endif
134
135#if (__FreeBSD__ == 2)
136typedef int ioctl_cmd_t;
137#define PCIR_REVID     PCI_CLASS_REG
138#endif
139#endif  /* __FreeBSD__ */
140
141
142/****************/
143/* *** BSDI *** */
144/****************/
145#ifdef __bsdi__
146#endif /* __bsdi__ */
147
148
149/**************************/
150/* *** OpenBSD/NetBSD *** */
151/**************************/
152#if defined(__NetBSD__) || defined(__OpenBSD__)
153#endif /* __NetBSD__ || __OpenBSD__ */
154
155
156
157/****************************/
158/* *** FreeBSD 4.x code *** */
159/****************************/
160#if (__FreeBSD_version >= 400000)
161
162static int	bktr_probe( device_t dev );
163static int	bktr_attach( device_t dev );
164static int	bktr_detach( device_t dev );
165static int	bktr_shutdown( device_t dev );
166static void	bktr_intr(void *arg) { common_bktr_intr(arg); }
167
168static device_method_t bktr_methods[] = {
169	/* Device interface */
170	DEVMETHOD(device_probe,         bktr_probe),
171	DEVMETHOD(device_attach,        bktr_attach),
172	DEVMETHOD(device_detach,        bktr_detach),
173	DEVMETHOD(device_shutdown,      bktr_shutdown),
174
175	{ 0, 0 }
176};
177
178static driver_t bktr_driver = {
179	"bktr",
180	bktr_methods,
181	sizeof(struct bktr_softc),
182};
183
184static devclass_t bktr_devclass;
185
186static	d_open_t	bktr_open;
187static	d_close_t	bktr_close;
188static	d_read_t	bktr_read;
189static	d_write_t	bktr_write;
190static	d_ioctl_t	bktr_ioctl;
191static	d_mmap_t	bktr_mmap;
192static	d_poll_t	bktr_poll;
193
194#define CDEV_MAJOR 92
195static struct cdevsw bktr_cdevsw = {
196	/* open */	bktr_open,
197	/* close */	bktr_close,
198	/* read */	bktr_read,
199	/* write */	bktr_write,
200	/* ioctl */	bktr_ioctl,
201	/* poll */	bktr_poll,
202	/* mmap */	bktr_mmap,
203	/* strategy */	nostrategy,
204	/* name */	"bktr",
205	/* maj */	CDEV_MAJOR,
206	/* dump */	nodump,
207	/* psize */	nopsize,
208	/* flags */	0,
209	/* bmaj */	-1
210};
211
212DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, 0, 0);
213
214
215/*
216 * the boot time probe routine.
217 */
218static int
219bktr_probe( device_t dev )
220{
221	unsigned int type = pci_get_devid(dev);
222        unsigned int rev  = pci_get_revid(dev);
223
224	switch (type) {
225	case BROOKTREE_848_PCI_ID:
226		if (rev == 0x12) device_set_desc(dev, "BrookTree 848A");
227		else             device_set_desc(dev, "BrookTree 848");
228                return 0;
229        case BROOKTREE_849_PCI_ID:
230                device_set_desc(dev, "BrookTree 849A");
231                return 0;
232        case BROOKTREE_878_PCI_ID:
233                device_set_desc(dev, "BrookTree 878");
234                return 0;
235        case BROOKTREE_879_PCI_ID:
236                device_set_desc(dev, "BrookTree 879");
237                return 0;
238	};
239
240        return ENXIO;
241}
242
243
244/*
245 * the attach routine.
246 */
247static int
248bktr_attach( device_t dev )
249{
250	bt848_ptr_t	bt848;
251	u_long		latency;
252	u_long		fun;
253	u_long		val;
254	unsigned int	rev;
255	unsigned int	unit;
256	int		error = 0;
257	int		rid;
258#ifdef BROOKTREE_IRQ
259	u_long		old_irq, new_irq;
260#endif
261
262        struct bktr_softc *bktr = device_get_softc(dev);
263
264	unit = device_get_unit(dev);
265
266	/*
267	 * Enable bus mastering and Memory Mapped device
268	 */
269	val = pci_read_config(dev, PCIR_COMMAND, 4);
270	val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
271	pci_write_config(dev, PCIR_COMMAND, val, 4);
272
273	/*
274	 * Map control/status registers.
275	 */
276	rid = PCI_MAP_REG_START;
277	bktr->res_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
278                                  0, ~0, 1, RF_ACTIVE);
279
280	if (!bktr->res_mem) {
281		device_printf(dev, "could not map memory\n");
282		error = ENXIO;
283		goto fail;
284	}
285	bktr->base = rman_get_virtual(bktr->res_mem); /* XXX use bus_space */
286
287	/*
288	 * Disable the brooktree device
289	 */
290	bt848 = bktr->base;
291	bt848->int_mask = ALL_INTS_DISABLED;
292	bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
293
294
295#ifdef BROOKTREE_IRQ		/* from the configuration file */
296	old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
297	pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
298	new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
299	printf("bktr%d: attach: irq changed from %d to %d\n",
300		unit, (old_irq & 0xff), (new_irq & 0xff));
301#endif
302
303	/*
304	 * Allocate our interrupt.
305	 */
306	rid = 0;
307	bktr->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
308                                 RF_SHAREABLE | RF_ACTIVE);
309	if (bktr->res_irq == NULL) {
310		device_printf(dev, "could not map interrupt\n");
311		error = ENXIO;
312		goto fail;
313	}
314
315	error = bus_setup_intr(dev, bktr->res_irq, INTR_TYPE_NET,
316                               bktr_intr, bktr, &bktr->res_ih);
317	if (error) {
318		device_printf(dev, "could not setup irq\n");
319		goto fail;
320
321	}
322
323
324	/* Update the Device Control Register */
325	/* on Bt878 and Bt879 cards           */
326	fun = pci_read_config( dev, 0x40, 2);
327        fun = fun | 1;	/* Enable writes to the sub-system vendor ID */
328
329#if defined( BKTR_430_FX_MODE )
330	if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
331        fun = fun | 2;	/* Enable Intel 430 FX compatibility mode */
332#endif
333
334#if defined( BKTR_SIS_VIA_MODE )
335	if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
336        fun = fun | 4;	/* Enable SiS/VIA compatibility mode (usefull for
337                           OPTi chipset motherboards too */
338#endif
339	pci_write_config(dev, 0x40, fun, 2);
340
341
342	/* XXX call bt848_i2c dependent attach() routine */
343#if (NSMBUS > 0)
344	if (bt848_i2c_attach(unit, bktr->base, &bktr->i2c_sc))
345		printf("bktr%d: i2c_attach: can't attach\n", unit);
346#endif
347
348
349/*
350 * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
351 * you have more than four, then 16 would probably be a better value.
352 */
353#ifndef BROOKTREE_DEF_LATENCY_VALUE
354#define BROOKTREE_DEF_LATENCY_VALUE	10
355#endif
356	latency = pci_read_config(dev, PCI_LATENCY_TIMER, 4);
357	latency = (latency >> 8) & 0xff;
358	if ( bootverbose ) {
359		if (latency)
360			printf("brooktree%d: PCI bus latency is", unit);
361		else
362			printf("brooktree%d: PCI bus latency was 0 changing to",
363				unit);
364	}
365	if ( !latency ) {
366		latency = BROOKTREE_DEF_LATENCY_VALUE;
367		pci_write_config(dev, PCI_LATENCY_TIMER, latency<<8, 4);
368	}
369	if ( bootverbose ) {
370		printf(" %d.\n", (int) latency);
371	}
372
373	/* read the pci device id and revision id */
374	fun = pci_get_devid(dev);
375        rev = pci_get_revid(dev);
376
377	/* call the common attach code */
378	common_bktr_attach( bktr, unit, fun, rev );
379
380	make_dev(&bktr_cdevsw, unit,    0, 0, 0444, "bktr%d",  unit);
381	make_dev(&bktr_cdevsw, unit+16, 0, 0, 0444, "tuner%d", unit);
382	make_dev(&bktr_cdevsw, unit+32, 0, 0, 0444, "vbi%d", unit);
383
384	return 0;
385
386fail:
387	return error;
388
389}
390
391/*
392 * the detach routine.
393 */
394static int
395bktr_detach( device_t dev )
396{
397	struct bktr_softc *bktr = device_get_softc(dev);
398	bt848_ptr_t bt848;
399
400	/* Disable the brooktree device */
401	bt848 = bktr->base;
402	bt848->int_mask = ALL_INTS_DISABLED;
403	bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
404
405	/* FIXME - Free memory for RISC programs, grab buffer, vbi buffers */
406
407	/*
408	 * Deallocate resources.
409	 */
410	bus_teardown_intr(dev, bktr->res_irq, bktr->res_ih);
411	bus_release_resource(dev, SYS_RES_IRQ, 0, bktr->res_irq);
412	bus_release_resource(dev, SYS_RES_MEMORY, PCI_MAP_REG_START, bktr->res_mem);
413
414	return 0;
415}
416
417/*
418 * the shutdown routine.
419 */
420static int
421bktr_shutdown( device_t dev )
422{
423	struct bktr_softc *bktr = device_get_softc(dev);
424	bt848_ptr_t bt848;
425
426	/* Disable the brooktree device */
427	bt848 = bktr->base;
428	bt848->int_mask = ALL_INTS_DISABLED;
429	bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
430
431	return 0;
432}
433
434
435/*
436 * Special Memory Allocation
437 */
438vm_offset_t
439get_bktr_mem( int unit, unsigned size )
440{
441	vm_offset_t	addr = 0;
442
443	addr = vm_page_alloc_contig(size, 0, 0xffffffff, 1<<24);
444	if (addr == 0)
445		addr = vm_page_alloc_contig(size, 0, 0xffffffff, PAGE_SIZE);
446	if (addr == 0) {
447		printf("bktr%d: Unable to allocate %d bytes of memory.\n",
448			unit, size);
449	}
450
451	return( addr );
452}
453
454
455/*---------------------------------------------------------
456**
457**	BrookTree 848 character device driver routines
458**
459**---------------------------------------------------------
460*/
461
462#define VIDEO_DEV	0x00
463#define TUNER_DEV	0x01
464#define VBI_DEV		0x02
465
466#define UNIT(x)		((x) & 0x0f)
467#define FUNCTION(x)	(x >> 4)
468
469/*
470 *
471 */
472int
473bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
474{
475	bktr_ptr_t	bktr;
476	int		unit;
477	int		result;
478
479	unit = UNIT( minor(dev) );
480
481	/* Get the device data */
482	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
483	if (bktr == NULL) {
484		/* the device is no longer valid/functioning */
485		return (ENXIO);
486	}
487
488	if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
489		return( ENXIO );
490
491	/* Record that the device is now busy */
492	device_busy(devclass_get_device(bktr_devclass, unit));
493
494
495	if (bt848_card != -1) {
496	  if ((bt848_card >> 8   == unit ) &&
497	     ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
498	    if ( bktr->bt848_card != (bt848_card & 0xff) ) {
499	      bktr->bt848_card = (bt848_card & 0xff);
500	      probeCard(bktr, FALSE, unit);
501	    }
502	  }
503	}
504
505	if (bt848_tuner != -1) {
506	  if ((bt848_tuner >> 8   == unit ) &&
507	     ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
508	    if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
509	      bktr->bt848_tuner = (bt848_tuner & 0xff);
510	      probeCard(bktr, FALSE, unit);
511	    }
512	  }
513	}
514
515	if (bt848_reverse_mute != -1) {
516	  if (((bt848_reverse_mute >> 8)   == unit ) &&
517	      ((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) {
518	    bktr->reverse_mute = bt848_reverse_mute & 0xff;
519	    bt848_reverse_mute = -1;
520	  }
521	}
522
523	switch ( FUNCTION( minor(dev) ) ) {
524	case VIDEO_DEV:
525		result = video_open( bktr );
526		break;
527	case TUNER_DEV:
528		result = tuner_open( bktr );
529		break;
530	case VBI_DEV:
531		result = vbi_open( bktr );
532		break;
533	default:
534		result = ENXIO;
535		break;
536	}
537
538	/* If there was an error opening the device, undo the busy status */
539	if (result != 0)
540		device_unbusy(devclass_get_device(bktr_devclass, unit));
541	return( result );
542}
543
544
545/*
546 *
547 */
548int
549bktr_close( dev_t dev, int flags, int fmt, struct proc *p )
550{
551	bktr_ptr_t	bktr;
552	int		unit;
553	int		result;
554
555	unit = UNIT( minor(dev) );
556
557	/* Get the device data */
558	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
559	if (bktr == NULL) {
560		/* the device is no longer valid/functioning */
561		return (ENXIO);
562	}
563
564	switch ( FUNCTION( minor(dev) ) ) {
565	case VIDEO_DEV:
566		result = video_close( bktr );
567		break;
568	case TUNER_DEV:
569		result = tuner_close( bktr );
570		break;
571	case VBI_DEV:
572		result = vbi_close( bktr );
573		break;
574	default:
575		return (ENXIO);
576		break;
577	}
578
579	device_unbusy(devclass_get_device(bktr_devclass, unit));
580	return( result );
581}
582
583
584/*
585 *
586 */
587int
588bktr_read( dev_t dev, struct uio *uio, int ioflag )
589{
590	bktr_ptr_t	bktr;
591	int		unit;
592
593	unit = UNIT(minor(dev));
594
595	/* Get the device data */
596	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
597	if (bktr == NULL) {
598		/* the device is no longer valid/functioning */
599		return (ENXIO);
600	}
601
602	switch ( FUNCTION( minor(dev) ) ) {
603	case VIDEO_DEV:
604		return( video_read( bktr, unit, dev, uio ) );
605	case VBI_DEV:
606		return( vbi_read( bktr, uio, ioflag ) );
607	}
608        return( ENXIO );
609}
610
611
612/*
613 *
614 */
615int
616bktr_write( dev_t dev, struct uio *uio, int ioflag )
617{
618	return( EINVAL ); /* XXX or ENXIO ? */
619}
620
621
622/*
623 *
624 */
625int
626bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct proc* pr )
627{
628	bktr_ptr_t	bktr;
629	int		unit;
630
631	unit = UNIT(minor(dev));
632
633	/* Get the device data */
634	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
635	if (bktr == NULL) {
636		/* the device is no longer valid/functioning */
637		return (ENXIO);
638	}
639
640	if (bktr->bigbuf == 0)	/* no frame buffer allocated (ioctl failed) */
641		return( ENOMEM );
642
643	switch ( FUNCTION( minor(dev) ) ) {
644	case VIDEO_DEV:
645		return( video_ioctl( bktr, unit, cmd, arg, pr ) );
646	case TUNER_DEV:
647		return( tuner_ioctl( bktr, unit, cmd, arg, pr ) );
648	}
649
650	return( ENXIO );
651}
652
653
654/*
655 *
656 */
657int
658bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
659{
660	int		unit;
661	bktr_ptr_t	bktr;
662
663	unit = UNIT(minor(dev));
664
665	if (FUNCTION(minor(dev)) > 0)	/* only allow mmap on /dev/bktr[n] */
666		return( -1 );
667
668	/* Get the device data */
669	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
670	if (bktr == NULL) {
671		/* the device is no longer valid/functioning */
672		return (ENXIO);
673	}
674
675	if (nprot & PROT_EXEC)
676		return( -1 );
677
678	if (offset < 0)
679		return( -1 );
680
681	if (offset >= bktr->alloc_pages * PAGE_SIZE)
682		return( -1 );
683
684	return( i386_btop(vtophys(bktr->bigbuf) + offset) );
685}
686
687int bktr_poll( dev_t dev, int events, struct proc *p)
688{
689	int		unit;
690	bktr_ptr_t	bktr;
691	int revents = 0;
692
693	unit = UNIT(minor(dev));
694
695	/* Get the device data */
696	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
697	if (bktr == NULL) {
698		/* the device is no longer valid/functioning */
699		return (ENXIO);
700	}
701
702	disable_intr();
703
704	if (events & (POLLIN | POLLRDNORM)) {
705
706		switch ( FUNCTION( minor(dev) ) ) {
707		case VBI_DEV:
708			if(bktr->vbisize == 0)
709				selrecord(p, &bktr->vbi_select);
710			else
711				revents |= events & (POLLIN | POLLRDNORM);
712			break;
713		}
714	}
715
716	enable_intr();
717
718	return (revents);
719}
720
721#endif		/* FreeBSD 4.x specific kernel interface routines */
722
723/**********************************/
724/* *** FreeBSD 2.2.x and 3.x  *** */
725/**********************************/
726
727#if ((__FreeBSD__ == 2) || (__FreeBSD__ == 3))
728
729static bktr_reg_t brooktree[ NBKTR ];
730
731static const char*	bktr_probe( pcici_t tag, pcidi_t type );
732static void		bktr_attach( pcici_t tag, int unit );
733static void		bktr_intr(void *arg) { common_bktr_intr(arg); }
734
735static u_long	bktr_count;
736
737static struct	pci_device bktr_device = {
738	"bktr",
739	bktr_probe,
740	bktr_attach,
741	&bktr_count
742};
743
744DATA_SET (pcidevice_set, bktr_device);
745
746static	d_open_t	bktr_open;
747static	d_close_t	bktr_close;
748static	d_read_t	bktr_read;
749static	d_write_t	bktr_write;
750static	d_ioctl_t	bktr_ioctl;
751static	d_mmap_t	bktr_mmap;
752static	d_poll_t	bktr_poll;
753
754#define CDEV_MAJOR 92
755static struct cdevsw bktr_cdevsw =
756{
757	bktr_open,	bktr_close,	bktr_read,	bktr_write,
758	bktr_ioctl,	nostop,		nullreset,	nodevtotty,
759	bktr_poll,	bktr_mmap,	NULL,		"bktr",
760	NULL,		-1
761};
762
763static int bktr_devsw_installed;
764
765static void
766bktr_drvinit( void *unused )
767{
768	dev_t dev;
769
770	if ( ! bktr_devsw_installed ) {
771		dev = makedev(CDEV_MAJOR, 0);
772		cdevsw_add(&dev,&bktr_cdevsw, NULL);
773		bktr_devsw_installed = 1;
774	}
775}
776
777SYSINIT(bktrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bktr_drvinit,NULL)
778
779/*
780 * the boot time probe routine.
781 */
782static const char*
783bktr_probe( pcici_t tag, pcidi_t type )
784{
785        unsigned int rev = pci_conf_read( tag, PCIR_REVID) & 0x000000ff;
786
787	switch (type) {
788	case BROOKTREE_848_PCI_ID:
789		if (rev == 0x12) return("BrookTree 848A");
790		else             return("BrookTree 848");
791        case BROOKTREE_849_PCI_ID:
792                return("BrookTree 849A");
793        case BROOKTREE_878_PCI_ID:
794                return("BrookTree 878");
795        case BROOKTREE_879_PCI_ID:
796                return("BrookTree 879");
797	};
798
799	return ((char *)0);
800}
801
802/*
803 * the attach routine.
804 */
805static	void
806bktr_attach( pcici_t tag, int unit )
807{
808	bktr_ptr_t	bktr;
809	bt848_ptr_t	bt848;
810	u_long		latency;
811	u_long		fun;
812	unsigned int	rev;
813#ifdef BROOKTREE_IRQ
814	u_long		old_irq, new_irq;
815#endif
816
817	bktr = &brooktree[unit];
818
819	if (unit >= NBKTR) {
820		printf("brooktree%d: attach: only %d units configured.\n",
821		        unit, NBKTR);
822		printf("brooktree%d: attach: invalid unit number.\n", unit);
823		return;
824	}
825
826	/* Enable Memory Mapping */
827	fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
828	pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 2);
829
830	/* Enable Bus Mastering */
831	fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
832	pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 4);
833
834	bktr->tag = tag;
835
836
837	/*
838	 * Map control/status registers
839	 */
840	pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base,
841		     &bktr->phys_base );
842
843	/*
844	 * Disable the brooktree device
845	 */
846	bt848 = bktr->base;
847	bt848->int_mask = ALL_INTS_DISABLED;
848	bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
849
850#ifdef BROOKTREE_IRQ		/* from the configuration file */
851	old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
852	pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
853	new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
854	printf("bktr%d: attach: irq changed from %d to %d\n",
855		unit, (old_irq & 0xff), (new_irq & 0xff));
856#endif
857
858	/*
859	 * setup the interrupt handling routine
860	 */
861	pci_map_int(tag, bktr_intr, (void*) bktr, &net_imask);
862
863
864	/* Update the Device Control Register */
865	/* on Bt878 and Bt879 cards */
866	fun = pci_conf_read(tag, 0x40);
867        fun = fun | 1;	/* Enable writes to the sub-system vendor ID */
868
869#if defined( BKTR_430_FX_MODE )
870	if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
871        fun = fun | 2;	/* Enable Intel 430 FX compatibility mode */
872#endif
873
874#if defined( BKTR_SIS_VIA_MODE )
875	if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
876        fun = fun | 4;	/* Enable SiS/VIA compatibility mode (usefull for
877                           OPTi chipset motherboards too */
878#endif
879	pci_conf_write(tag, 0x40, fun);
880
881
882	/* XXX call bt848_i2c dependent attach() routine */
883#if (NSMBUS > 0)
884	if (bt848_i2c_attach(unit, bktr->base, &bktr->i2c_sc))
885		printf("bktr%d: i2c_attach: can't attach\n", unit);
886#endif
887
888
889/*
890 * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
891 * you have more than four, then 16 would probably be a better value.
892 */
893#ifndef BROOKTREE_DEF_LATENCY_VALUE
894#define BROOKTREE_DEF_LATENCY_VALUE	10
895#endif
896	latency = pci_conf_read(tag, PCI_LATENCY_TIMER);
897	latency = (latency >> 8) & 0xff;
898	if ( bootverbose ) {
899		if (latency)
900			printf("brooktree%d: PCI bus latency is", unit);
901		else
902			printf("brooktree%d: PCI bus latency was 0 changing to",
903				unit);
904	}
905	if ( !latency ) {
906		latency = BROOKTREE_DEF_LATENCY_VALUE;
907		pci_conf_write(tag, PCI_LATENCY_TIMER,	latency<<8);
908	}
909	if ( bootverbose ) {
910		printf(" %d.\n", (int) latency);
911	}
912
913
914	/* read the pci device id and revision id */
915	fun = pci_conf_read(tag, PCI_ID_REG);
916        rev = pci_conf_read(tag, PCIR_REVID) & 0x000000ff;
917
918	/* call the common attach code */
919	common_bktr_attach( bktr, unit, fun, rev );
920
921#ifdef DEVFS
922	/* XXX This just throw away the token, which should probably be fixed when
923	   DEVFS is finally made really operational. */
924	devfs_add_devswf(&bktr_cdevsw, unit,    DV_CHR, 0, 0, 0444, "bktr%d",  unit);
925	devfs_add_devswf(&bktr_cdevsw, unit+16, DV_CHR, 0, 0, 0444, "tuner%d", unit);
926	devfs_add_devswf(&bktr_cdevsw, unit+32, DV_CHR, 0, 0, 0444, "vbi%d", unit);
927#endif /* DEVFS */
928
929}
930
931
932/*
933 * Special Memory Allocation
934 */
935vm_offset_t
936get_bktr_mem( int unit, unsigned size )
937{
938	vm_offset_t	addr = 0;
939
940	addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24);
941	if (addr == 0)
942		addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff,
943								PAGE_SIZE);
944	if (addr == 0) {
945		printf("bktr%d: Unable to allocate %d bytes of memory.\n",
946			unit, size);
947	}
948
949	return( addr );
950}
951
952/*---------------------------------------------------------
953**
954**	BrookTree 848 character device driver routines
955**
956**---------------------------------------------------------
957*/
958
959
960#define VIDEO_DEV	0x00
961#define TUNER_DEV	0x01
962#define VBI_DEV		0x02
963
964#define UNIT(x)		((x) & 0x0f)
965#define FUNCTION(x)	((x >> 4) & 0x0f)
966
967
968/*
969 *
970 */
971int
972bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
973{
974	bktr_ptr_t	bktr;
975	int		unit;
976
977	unit = UNIT( minor(dev) );
978	if (unit >= NBKTR)			/* unit out of range */
979		return( ENXIO );
980
981	bktr = &(brooktree[ unit ]);
982
983	if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
984		return( ENXIO );
985
986
987	if (bt848_card != -1) {
988	  if ((bt848_card >> 8   == unit ) &&
989	     ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
990	    if ( bktr->bt848_card != (bt848_card & 0xff) ) {
991	      bktr->bt848_card = (bt848_card & 0xff);
992	      probeCard(bktr, FALSE, unit);
993	    }
994	  }
995	}
996
997	if (bt848_tuner != -1) {
998	  if ((bt848_tuner >> 8   == unit ) &&
999	     ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
1000	    if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
1001	      bktr->bt848_tuner = (bt848_tuner & 0xff);
1002	      probeCard(bktr, FALSE, unit);
1003	    }
1004	  }
1005	}
1006
1007	if (bt848_reverse_mute != -1) {
1008	  if (((bt848_reverse_mute >> 8)   == unit ) &&
1009	      ((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) {
1010	    bktr->reverse_mute = bt848_reverse_mute & 0xff;
1011	    bt848_reverse_mute = -1;
1012	  }
1013	}
1014
1015
1016	switch ( FUNCTION( minor(dev) ) ) {
1017	case VIDEO_DEV:
1018		return( video_open( bktr ) );
1019	case TUNER_DEV:
1020		return( tuner_open( bktr ) );
1021	case VBI_DEV:
1022		return( vbi_open( bktr ) );
1023	}
1024	return( ENXIO );
1025}
1026
1027
1028/*
1029 *
1030 */
1031int
1032bktr_close( dev_t dev, int flags, int fmt, struct proc *p )
1033{
1034	bktr_ptr_t	bktr;
1035	int		unit;
1036
1037	unit = UNIT( minor(dev) );
1038	if (unit >= NBKTR)			/* unit out of range */
1039		return( ENXIO );
1040
1041	bktr = &(brooktree[ unit ]);
1042
1043	switch ( FUNCTION( minor(dev) ) ) {
1044	case VIDEO_DEV:
1045		return( video_close( bktr ) );
1046	case TUNER_DEV:
1047		return( tuner_close( bktr ) );
1048	case VBI_DEV:
1049		return( vbi_close( bktr ) );
1050	}
1051
1052	return( ENXIO );
1053}
1054
1055/*
1056 *
1057 */
1058int
1059bktr_read( dev_t dev, struct uio *uio, int ioflag )
1060{
1061	bktr_ptr_t	bktr;
1062	int		unit;
1063
1064	unit = UNIT(minor(dev));
1065	if (unit >= NBKTR)	/* unit out of range */
1066		return( ENXIO );
1067
1068	bktr = &(brooktree[unit]);
1069
1070	switch ( FUNCTION( minor(dev) ) ) {
1071	case VIDEO_DEV:
1072		return( video_read( bktr, unit, dev, uio ) );
1073	case VBI_DEV:
1074		return( vbi_read( bktr, uio, ioflag ) );
1075	}
1076        return( ENXIO );
1077}
1078
1079
1080/*
1081 *
1082 */
1083int
1084bktr_write( dev_t dev, struct uio *uio, int ioflag )
1085{
1086	return( EINVAL ); /* XXX or ENXIO ? */
1087}
1088
1089/*
1090 *
1091 */
1092int
1093bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct proc* pr )
1094{
1095	bktr_ptr_t	bktr;
1096	int		unit;
1097
1098	unit = UNIT(minor(dev));
1099	if (unit >= NBKTR)	/* unit out of range */
1100		return( ENXIO );
1101
1102	bktr = &(brooktree[ unit ]);
1103
1104	if (bktr->bigbuf == 0)	/* no frame buffer allocated (ioctl failed) */
1105		return( ENOMEM );
1106
1107	switch ( FUNCTION( minor(dev) ) ) {
1108	case VIDEO_DEV:
1109		return( video_ioctl( bktr, unit, cmd, arg, pr ) );
1110	case TUNER_DEV:
1111		return( tuner_ioctl( bktr, unit, cmd, arg, pr ) );
1112	}
1113
1114	return( ENXIO );
1115}
1116
1117/*
1118 * bktr_mmap.
1119 * Note: 2.2.5/2.2.6/2.2.7/3.0 users must manually
1120 * edit the line below and change  "vm_offset_t" to "int"
1121 */
1122int bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
1123
1124{
1125	int		unit;
1126	bktr_ptr_t	bktr;
1127
1128	unit = UNIT(minor(dev));
1129
1130	if (unit >= NBKTR || FUNCTION(minor(dev)) > 0)
1131		return( -1 );
1132
1133	bktr = &(brooktree[ unit ]);
1134
1135	if (nprot & PROT_EXEC)
1136		return( -1 );
1137
1138	if (offset < 0)
1139		return( -1 );
1140
1141	if (offset >= bktr->alloc_pages * PAGE_SIZE)
1142		return( -1 );
1143
1144	return( i386_btop(vtophys(bktr->bigbuf) + offset) );
1145}
1146
1147int bktr_poll( dev_t dev, int events, struct proc *p)
1148{
1149	int		unit;
1150	bktr_ptr_t	bktr;
1151	int revents = 0;
1152
1153	unit = UNIT(minor(dev));
1154
1155	if (unit >= NBKTR)
1156		return( -1 );
1157
1158	bktr = &(brooktree[ unit ]);
1159
1160	disable_intr();
1161
1162	if (events & (POLLIN | POLLRDNORM)) {
1163
1164		switch ( FUNCTION( minor(dev) ) ) {
1165		case VBI_DEV:
1166			if(bktr->vbisize == 0)
1167				selrecord(p, &bktr->vbi_select);
1168			else
1169				revents |= events & (POLLIN | POLLRDNORM);
1170			break;
1171		}
1172	}
1173
1174	enable_intr();
1175
1176	return (revents);
1177}
1178
1179
1180#endif		/* FreeBSD 2.2.x and 3.x specific kernel interface routines */
1181
1182
1183/*****************/
1184/* *** BSDI  *** */
1185/*****************/
1186
1187#if defined(__bsdi__)
1188#endif		/* __bsdi__ BSDI specific kernel interface routines */
1189
1190
1191/*****************************/
1192/* *** OpenBSD / NetBSD  *** */
1193/*****************************/
1194#if defined(__NetBSD__) || defined(__OpenBSD__)
1195#endif /* __NetBSD__ || __OpenBSD__ */
1196
1197