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