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