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