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