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