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