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