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