153#include <dev/bktr/bktr_i2c.h> 154#include <dev/smbus/smbconf.h> 155#include <dev/iicbus/iiconf.h> 156#include "smbus_if.h" 157#include "iicbus_if.h" 158#endif 159 160const char * 161bktr_name(bktr_ptr_t bktr) 162{ 163 return bktr->bktr_xname; 164} 165 166 167#if (__FreeBSD__ == 2) 168typedef unsigned int uintptr_t; 169#endif 170#endif /* __FreeBSD__ */ 171 172 173/****************/ 174/* *** BSDI *** */ 175/****************/ 176#ifdef __bsdi__ 177#endif /* __bsdi__ */ 178 179 180/**************************/ 181/* *** OpenBSD/NetBSD *** */ 182/**************************/ 183#if defined(__NetBSD__) || defined(__OpenBSD__) 184 185#include <sys/param.h> 186#include <sys/systm.h> 187#include <sys/kernel.h> 188#include <sys/signalvar.h> 189#include <sys/vnode.h> 190 191#ifdef __NetBSD__ 192#include <uvm/uvm_extern.h> 193#else 194#include <vm/vm.h> 195#include <vm/vm_kern.h> 196#include <vm/pmap.h> 197#include <vm/vm_extern.h> 198#endif 199 200#include <sys/inttypes.h> /* uintptr_t */ 201#include <dev/ic/bt8xx.h> 202#include <dev/pci/bktr/bktr_reg.h> 203#include <dev/pci/bktr/bktr_tuner.h> 204#include <dev/pci/bktr/bktr_card.h> 205#include <dev/pci/bktr/bktr_audio.h> 206#include <dev/pci/bktr/bktr_core.h> 207#include <dev/pci/bktr/bktr_os.h> 208 209static int bt848_format = -1; 210 211const char * 212bktr_name(bktr_ptr_t bktr) 213{ 214 return (bktr->bktr_dev.dv_xname); 215} 216 217#endif /* __NetBSD__ || __OpenBSD__ */ 218 219 220 221typedef u_char bool_t; 222 223#define BKTRPRI (PZERO+8)|PCATCH 224#define VBIPRI (PZERO-4)|PCATCH 225 226 227/* 228 * memory allocated for DMA programs 229 */ 230#define DMA_PROG_ALLOC (8 * PAGE_SIZE) 231 232/* When to split a dma transfer , the bt848 has timing as well as 233 dma transfer size limitations so that we have to split dma 234 transfers into two dma requests 235 */ 236#define DMA_BT848_SPLIT 319*2 237 238/* 239 * Allocate enough memory for: 240 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages 241 * 242 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value" 243 * in your kernel configuration file. 244 */ 245 246#ifndef BROOKTREE_ALLOC_PAGES 247#define BROOKTREE_ALLOC_PAGES 217*4 248#endif 249#define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE) 250 251/* Definitions for VBI capture. 252 * There are 16 VBI lines in a PAL video field (32 in a frame), 253 * and we take 2044 samples from each line (placed in a 2048 byte buffer 254 * for alignment). 255 * VBI lines are held in a circular buffer before being read by a 256 * user program from /dev/vbi. 257 */ 258 259#define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */ 260#define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */ 261#define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */ 262#define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2) 263#define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS) 264 265 266/* Defines for fields */ 267#define ODD_F 0x01 268#define EVEN_F 0x02 269 270 271/* 272 * Parameters describing size of transmitted image. 273 */ 274 275static struct format_params format_params[] = { 276/* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */ 277 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO, 278 12, 1600 }, 279/* # define BT848_IFORM_F_NTSCM (0x1) */ 280 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0, 281 12, 1600 }, 282/* # define BT848_IFORM_F_NTSCJ (0x2) */ 283 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0, 284 12, 1600 }, 285/* # define BT848_IFORM_F_PALBDGHI (0x3) */ 286 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1, 287 16, 2044 }, 288/* # define BT848_IFORM_F_PALM (0x4) */ 289 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0, 290 12, 1600 }, 291/* # define BT848_IFORM_F_PALN (0x5) */ 292 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1, 293 16, 2044 }, 294/* # define BT848_IFORM_F_SECAM (0x6) */ 295 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1, 296 16, 2044 }, 297/* # define BT848_IFORM_F_RSVD (0x7) - ???? */ 298 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0, 299 16, 2044 }, 300}; 301 302/* 303 * Table of supported Pixel Formats 304 */ 305 306static struct meteor_pixfmt_internal { 307 struct meteor_pixfmt public; 308 u_int color_fmt; 309} pixfmt_table[] = { 310 311{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 }, 312{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 }, 313 314{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 }, 315{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 }, 316 317{ { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 }, 318 319{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 }, 320{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 }, 321{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 }, 322{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 }, 323{ { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 }, 324{ { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 }, 325{ { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 }, 326 327}; 328#define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) ) 329 330/* 331 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility) 332 */ 333 334/* FIXME: Also add YUV_422 and YUV_PACKED as well */ 335static struct { 336 u_long meteor_format; 337 struct meteor_pixfmt public; 338} meteor_pixfmt_table[] = { 339 { METEOR_GEO_YUV_12, 340 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 } 341 }, 342 343 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */ 344 { METEOR_GEO_YUV_422, 345 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 } 346 }, 347 { METEOR_GEO_YUV_PACKED, 348 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 } 349 }, 350 { METEOR_GEO_RGB16, 351 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 } 352 }, 353 { METEOR_GEO_RGB24, 354 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 } 355 }, 356 357}; 358#define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \ 359 sizeof(meteor_pixfmt_table[0]) ) 360 361 362#define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN) 363#define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN) 364 365 366 367/* sync detect threshold */ 368#if 0 369#define SYNC_LEVEL (BT848_ADC_RESERVED | \ 370 BT848_ADC_CRUSH) /* threshold ~125 mV */ 371#else 372#define SYNC_LEVEL (BT848_ADC_RESERVED | \ 373 BT848_ADC_SYNC_T) /* threshold ~75 mV */ 374#endif 375 376 377 378 379/* debug utility for holding previous INT_STAT contents */ 380#define STATUS_SUM 381static u_long status_sum = 0; 382 383/* 384 * defines to make certain bit-fiddles understandable 385 */ 386#define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN 387#define RISC_ENABLED BT848_DMA_CTL_RISC_EN 388#define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN) 389#define FIFO_RISC_DISABLED 0 390 391#define ALL_INTS_DISABLED 0 392#define ALL_INTS_CLEARED 0xffffffff 393#define CAPTURE_OFF 0 394 395#define BIT_SEVEN_HIGH (1<<7) 396#define BIT_EIGHT_HIGH (1<<8) 397 398#define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE) 399#define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS) 400 401 402 403static int oformat_meteor_to_bt( u_long format ); 404 405static u_int pixfmt_swap_flags( int pixfmt ); 406 407/* 408 * bt848 RISC programming routines. 409 */ 410#ifdef BT848_DUMP 411static int dump_bt848( bktr_ptr_t bktr ); 412#endif 413 414static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols, 415 int rows, int interlace ); 416static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols, 417 int rows, int interlace ); 418static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols, 419 int rows, int interlace ); 420static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, 421 int rows, int interlace ); 422static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, 423 int rows, int interlace ); 424static void build_dma_prog( bktr_ptr_t bktr, char i_flag ); 425 426static bool_t getline(bktr_reg_t *, int); 427static bool_t notclipped(bktr_reg_t * , int , int); 428static bool_t split(bktr_reg_t *, volatile u_long **, int, u_long, int, 429 volatile u_char ** , int ); 430 431static void start_capture( bktr_ptr_t bktr, unsigned type ); 432static void set_fps( bktr_ptr_t bktr, u_short fps ); 433 434 435 436/* 437 * Remote Control Functions 438 */ 439static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote); 440 441 442/* 443 * ioctls common to both video & tuner. 444 */ 445static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg ); 446 447
|
535 if ( bootverbose ) { 536 printf("%s: buffer size %d, addr 0x%x\n", 537 bktr_name(bktr), BROOKTREE_ALLOC, vtophys(buf)); 538 } 539 540 if ( buf != 0 ) { 541 bktr->bigbuf = buf; 542 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES; 543 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC); 544 } else { 545 bktr->alloc_pages = 0; 546 } 547 548 549 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE | 550 METEOR_DEV0 | METEOR_RGB16; 551 bktr->dma_prog_loaded = FALSE; 552 bktr->cols = 640; 553 bktr->rows = 480; 554 bktr->frames = 1; /* one frame */ 555 bktr->format = METEOR_GEO_RGB16; 556 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 557 bktr->pixfmt_compat = TRUE; 558 559 560 bktr->vbiinsert = 0; 561 bktr->vbistart = 0; 562 bktr->vbisize = 0; 563 bktr->vbiflags = 0; 564 565 566 /* using the pci device id and revision id */ 567 /* and determine the card type */ 568 switch (pci_id) { 569 case BROOKTREE_848_PCI_ID: 570 if (rev == 0x12) bktr->id = BROOKTREE_848A; 571 else bktr->id = BROOKTREE_848; 572 break; 573 case BROOKTREE_849_PCI_ID: 574 bktr->id = BROOKTREE_849A; 575 break; 576 case BROOKTREE_878_PCI_ID: 577 bktr->id = BROOKTREE_878; 578 break; 579 case BROOKTREE_879_PCI_ID: 580 bktr->id = BROOKTREE_879; 581 break; 582 }; 583 584 bktr->clr_on_start = FALSE; 585 586 /* defaults for the tuner section of the card */ 587 bktr->tflags = TUNER_INITALIZED; 588 bktr->tuner.frequency = 0; 589 bktr->tuner.channel = 0; 590 bktr->tuner.chnlset = DEFAULT_CHNLSET; 591 bktr->tuner.afc = 0; 592 bktr->tuner.radio_mode = 0; 593 bktr->audio_mux_select = 0; 594 bktr->audio_mute_state = FALSE; 595 bktr->bt848_card = -1; 596 bktr->bt848_tuner = -1; 597 bktr->reverse_mute = -1; 598 bktr->slow_msp_audio = 0; 599 600 probeCard( bktr, TRUE, unit ); 601 602 /* Initialise any MSP34xx or TDA98xx audio chips */ 603 init_audio_devices( bktr ); 604 605} 606 607 608/* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'. 609 * The circular buffer holds 'n' fixed size data blocks. 610 * vbisize is the number of bytes in the circular buffer 611 * vbiread is the point we reading data out of the circular buffer 612 * vbiinsert is the point we insert data into the circular buffer 613 */ 614static void vbidecode(bktr_ptr_t bktr) { 615 unsigned char *dest; 616 unsigned int *seq_dest; 617 618 /* Check if there is room in the buffer to insert the data. */ 619 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return; 620 621 /* Copy the VBI data into the next free slot in the buffer. */ 622 /* 'dest' is the point in vbibuffer where we want to insert new data */ 623 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert; 624 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE); 625 626 /* Write the VBI sequence number to the end of the vbi data */ 627 /* This is used by the AleVT teletext program */ 628 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer 629 + bktr->vbiinsert 630 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number))); 631 *seq_dest = bktr->vbi_sequence_number; 632 633 /* And increase the VBI sequence number */ 634 /* This can wrap around */ 635 bktr->vbi_sequence_number++; 636 637 638 /* Increment the vbiinsert pointer */ 639 /* This can wrap around */ 640 bktr->vbiinsert += VBI_DATA_SIZE; 641 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE); 642 643 /* And increase the amount of vbi data in the buffer */ 644 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE; 645 646} 647 648 649/* 650 * the common interrupt handler. 651 * Returns a 0 or 1 depending on whether the interrupt has handled. 652 * In the OS specific section, bktr_intr() is defined which calls this 653 * common interrupt handler. 654 */ 655int 656common_bktr_intr( void *arg ) 657{ 658 bktr_ptr_t bktr; 659 u_long bktr_status; 660 u_char dstatus; 661 u_long field; 662 u_long w_field; 663 u_long req_field; 664 665 bktr = (bktr_ptr_t) arg; 666 667 /* 668 * check to see if any interrupts are unmasked on this device. If 669 * none are, then we likely got here by way of being on a PCI shared 670 * interrupt dispatch list. 671 */ 672 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED) 673 return 0; /* bail out now, before we do something we 674 shouldn't */ 675 676 if (!(bktr->flags & METEOR_OPEN)) { 677 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 678 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 679 /* return; ?? */ 680 } 681 682 /* record and clear the INTerrupt status bits */ 683 bktr_status = INL(bktr, BKTR_INT_STAT); 684 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */ 685 686 /* record and clear the device status register */ 687 dstatus = INB(bktr, BKTR_DSTATUS); 688 OUTB(bktr, BKTR_DSTATUS, 0x00); 689 690#if defined( STATUS_SUM ) 691 /* add any new device status or INTerrupt status bits */ 692 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1)); 693 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6); 694#endif /* STATUS_SUM */ 695 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr), 696 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) ); 697 */ 698 699 700 /* if risc was disabled re-start process again */ 701 /* if there was one of the following errors re-start again */ 702 if ( !(bktr_status & BT848_INT_RISC_EN) || 703 ((bktr_status &(/* BT848_INT_FBUS | */ 704 /* BT848_INT_FTRGT | */ 705 /* BT848_INT_FDSR | */ 706 BT848_INT_PPERR | 707 BT848_INT_RIPERR | BT848_INT_PABORT | 708 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0) 709 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) { 710 711 u_short tdec_save = INB(bktr, BKTR_TDEC); 712 713 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 714 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 715 716 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 717 718 /* Reset temporal decimation counter */ 719 OUTB(bktr, BKTR_TDEC, 0); 720 OUTB(bktr, BKTR_TDEC, tdec_save); 721 722 /* Reset to no-fields captured state */ 723 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 724 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 725 case METEOR_ONLY_ODD_FIELDS: 726 bktr->flags |= METEOR_WANT_ODD; 727 break; 728 case METEOR_ONLY_EVEN_FIELDS: 729 bktr->flags |= METEOR_WANT_EVEN; 730 break; 731 default: 732 bktr->flags |= METEOR_WANT_MASK; 733 break; 734 } 735 } 736 737 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog)); 738 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 739 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 740 741 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 742 BT848_INT_RISCI | 743 BT848_INT_VSYNC | 744 BT848_INT_FMTCHG); 745 746 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 747 return 1; 748 } 749 750 /* If this is not a RISC program interrupt, return */ 751 if (!(bktr_status & BT848_INT_RISCI)) 752 return 0; 753 754/** 755 printf( "%s: intr status %x %x %x\n", bktr_name(bktr), 756 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) ); 757 */ 758 759 760 /* 761 * Disable future interrupts if a capture mode is not selected. 762 * This can happen when we are in the process of closing or 763 * changing capture modes, otherwise it shouldn't happen. 764 */ 765 if (!(bktr->flags & METEOR_CAP_MASK)) 766 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 767 768 769 /* Determine which field generated this interrupt */ 770 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F; 771 772 773 /* 774 * Process the VBI data if it is being captured. We do this once 775 * both Odd and Even VBI data is captured. Therefore we do this 776 * in the Even field interrupt handler. 777 */ 778 if ( (bktr->vbiflags & VBI_CAPTURE) 779 &&(bktr->vbiflags & VBI_OPEN) 780 &&(field==EVEN_F)) { 781 /* Put VBI data into circular buffer */ 782 vbidecode(bktr); 783 784 /* If someone is blocked on reading from /dev/vbi, wake them */ 785 if (bktr->vbi_read_blocked) { 786 bktr->vbi_read_blocked = FALSE; 787 wakeup(VBI_SLEEP); 788 } 789 790 /* If someone has a select() on /dev/vbi, inform them */ 791 if (bktr->vbi_select.si_pid) { 792 selwakeup(&bktr->vbi_select); 793 } 794 795 796 } 797 798 799 /* 800 * Register the completed field 801 * (For dual-field mode, require fields from the same frame) 802 */ 803 switch ( bktr->flags & METEOR_WANT_MASK ) { 804 case METEOR_WANT_ODD : w_field = ODD_F ; break; 805 case METEOR_WANT_EVEN : w_field = EVEN_F ; break; 806 default : w_field = (ODD_F|EVEN_F); break; 807 } 808 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) { 809 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break; 810 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break; 811 default : req_field = (ODD_F|EVEN_F); 812 break; 813 } 814 815 if (( field == EVEN_F ) && ( w_field == EVEN_F )) 816 bktr->flags &= ~METEOR_WANT_EVEN; 817 else if (( field == ODD_F ) && ( req_field == ODD_F ) && 818 ( w_field == ODD_F )) 819 bktr->flags &= ~METEOR_WANT_ODD; 820 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) && 821 ( w_field == (ODD_F|EVEN_F) )) 822 bktr->flags &= ~METEOR_WANT_ODD; 823 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) && 824 ( w_field == ODD_F )) { 825 bktr->flags &= ~METEOR_WANT_ODD; 826 bktr->flags |= METEOR_WANT_EVEN; 827 } 828 else { 829 /* We're out of sync. Start over. */ 830 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 831 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 832 case METEOR_ONLY_ODD_FIELDS: 833 bktr->flags |= METEOR_WANT_ODD; 834 break; 835 case METEOR_ONLY_EVEN_FIELDS: 836 bktr->flags |= METEOR_WANT_EVEN; 837 break; 838 default: 839 bktr->flags |= METEOR_WANT_MASK; 840 break; 841 } 842 } 843 return 1; 844 } 845 846 /* 847 * If we have a complete frame. 848 */ 849 if (!(bktr->flags & METEOR_WANT_MASK)) { 850 bktr->frames_captured++; 851 /* 852 * post the completion time. 853 */ 854 if (bktr->flags & METEOR_WANT_TS) { 855 struct timeval *ts; 856 857 if ((u_int) bktr->alloc_pages * PAGE_SIZE 858 <= (bktr->frame_size + sizeof(struct timeval))) { 859 ts =(struct timeval *)bktr->bigbuf + 860 bktr->frame_size; 861 /* doesn't work in synch mode except 862 * for first frame */ 863 /* XXX */ 864 microtime(ts); 865 } 866 } 867 868 869 /* 870 * Wake up the user in single capture mode. 871 */ 872 if (bktr->flags & METEOR_SINGLE) { 873 874 /* stop dma */ 875 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 876 877 /* disable risc, leave fifo running */ 878 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 879 wakeup(BKTR_SLEEP); 880 } 881 882 /* 883 * If the user requested to be notified via signal, 884 * let them know the frame is complete. 885 */ 886 887 if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK)) 888 psignal( bktr->proc, 889 bktr->signal&(~METEOR_SIG_MODE_MASK) ); 890 891 /* 892 * Reset the want flags if in continuous or 893 * synchronous capture mode. 894 */ 895/* 896* XXX NOTE (Luigi): 897* currently we only support 3 capture modes: odd only, even only, 898* odd+even interlaced (odd field first). A fourth mode (non interlaced, 899* either even OR odd) could provide 60 (50 for PAL) pictures per 900* second, but it would require this routine to toggle the desired frame 901* each time, and one more different DMA program for the Bt848. 902* As a consequence, this fourth mode is currently unsupported. 903*/ 904 905 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) { 906 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 907 case METEOR_ONLY_ODD_FIELDS: 908 bktr->flags |= METEOR_WANT_ODD; 909 break; 910 case METEOR_ONLY_EVEN_FIELDS: 911 bktr->flags |= METEOR_WANT_EVEN; 912 break; 913 default: 914 bktr->flags |= METEOR_WANT_MASK; 915 break; 916 } 917 } 918 } 919 920 return 1; 921} 922 923 924 925 926/* 927 * 928 */ 929extern int bt848_format; /* used to set the default format, PAL or NTSC */ 930int 931video_open( bktr_ptr_t bktr ) 932{ 933 int frame_rate, video_format=0; 934 935 if (bktr->flags & METEOR_OPEN) /* device is busy */ 936 return( EBUSY ); 937 938 bktr->flags |= METEOR_OPEN; 939 940#ifdef BT848_DUMP 941 dump_bt848( bt848 ); 942#endif 943 944 bktr->clr_on_start = FALSE; 945 946 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */ 947 948 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 949 950#if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL 951 video_format = 0; 952#else 953 video_format = 1; 954#endif 955 956 if (bt848_format == 0 ) 957 video_format = 0; 958 959 if (bt848_format == 1 ) 960 video_format = 1; 961 962 if (video_format == 1 ) { 963 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM); 964 bktr->format_params = BT848_IFORM_F_NTSCM; 965 966 } else { 967 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI); 968 bktr->format_params = BT848_IFORM_F_PALBDGHI; 969 970 } 971 972 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel); 973 974 /* work around for new Hauppauge 878 cards */ 975 if ((bktr->card.card_id == CARD_HAUPPAUGE) && 976 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) ) 977 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3); 978 else 979 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1); 980 981 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay); 982 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay); 983 frame_rate = format_params[bktr->format_params].frame_rate; 984 985 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */ 986 if (bktr->xtal_pll_mode == BT848_USE_PLL) { 987 OUTB(bktr, BKTR_TGCTRL, 0); 988 OUTB(bktr, BKTR_PLL_F_LO, 0xf9); 989 OUTB(bktr, BKTR_PLL_F_HI, 0xdc); 990 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e); 991 } 992 993 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0; 994 995 bktr->max_clip_node = 0; 996 997 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED); 998 999 OUTB(bktr, BKTR_E_HSCALE_LO, 170); 1000 OUTB(bktr, BKTR_O_HSCALE_LO, 170); 1001 1002 OUTB(bktr, BKTR_E_DELAY_LO, 0x72); 1003 OUTB(bktr, BKTR_O_DELAY_LO, 0x72); 1004 OUTB(bktr, BKTR_E_SCLOOP, 0); 1005 OUTB(bktr, BKTR_O_SCLOOP, 0); 1006 1007 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0); 1008 OUTB(bktr, BKTR_VBI_PACK_DEL, 0); 1009 1010 bktr->fifo_errors = 0; 1011 bktr->dma_errors = 0; 1012 bktr->frames_captured = 0; 1013 bktr->even_fields_captured = 0; 1014 bktr->odd_fields_captured = 0; 1015 bktr->proc = (struct proc *)0; 1016 set_fps(bktr, frame_rate); 1017 bktr->video.addr = 0; 1018 bktr->video.width = 0; 1019 bktr->video.banksize = 0; 1020 bktr->video.ramsize = 0; 1021 bktr->pixfmt_compat = TRUE; 1022 bktr->format = METEOR_GEO_RGB16; 1023 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 1024 1025 bktr->capture_area_enabled = FALSE; 1026 1027 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton 1028 based motherboards will 1029 operate unreliably */ 1030 return( 0 ); 1031} 1032 1033int 1034vbi_open( bktr_ptr_t bktr ) 1035{ 1036 if (bktr->vbiflags & VBI_OPEN) /* device is busy */ 1037 return( EBUSY ); 1038 1039 bktr->vbiflags |= VBI_OPEN; 1040 1041 /* reset the VBI circular buffer pointers and clear the buffers */ 1042 bktr->vbiinsert = 0; 1043 bktr->vbistart = 0; 1044 bktr->vbisize = 0; 1045 bktr->vbi_sequence_number = 0; 1046 bktr->vbi_read_blocked = FALSE; 1047 1048 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE); 1049 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE); 1050 1051 return( 0 ); 1052} 1053 1054/* 1055 * 1056 */ 1057int 1058tuner_open( bktr_ptr_t bktr ) 1059{ 1060 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */ 1061 return( ENXIO ); 1062 1063 if ( bktr->tflags & TUNER_OPEN ) /* already open */ 1064 return( 0 ); 1065 1066 bktr->tflags |= TUNER_OPEN; 1067 bktr->tuner.frequency = 0; 1068 bktr->tuner.channel = 0; 1069 bktr->tuner.chnlset = DEFAULT_CHNLSET; 1070 bktr->tuner.afc = 0; 1071 bktr->tuner.radio_mode = 0; 1072 1073 /* enable drivers on the GPIO port that control the MUXes */ 1074 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits); 1075 1076 /* unmute the audio stream */ 1077 set_audio( bktr, AUDIO_UNMUTE ); 1078 1079 /* Initialise any audio chips, eg MSP34xx or TDA98xx */ 1080 init_audio_devices( bktr ); 1081 1082 return( 0 ); 1083} 1084 1085 1086 1087 1088/* 1089 * 1090 */ 1091int 1092video_close( bktr_ptr_t bktr ) 1093{ 1094 bktr->flags &= ~(METEOR_OPEN | 1095 METEOR_SINGLE | 1096 METEOR_CAP_MASK | 1097 METEOR_WANT_MASK); 1098 1099 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 1100 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 1101 1102 bktr->dma_prog_loaded = FALSE; 1103 OUTB(bktr, BKTR_TDEC, 0); 1104 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1105 1106/** FIXME: is 0xf magic, wouldn't 0x00 work ??? */ 1107 OUTL(bktr, BKTR_SRESET, 0xf); 1108 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 1109 1110 return( 0 ); 1111} 1112 1113 1114/* 1115 * tuner close handle, 1116 * place holder for tuner specific operations on a close. 1117 */ 1118int 1119tuner_close( bktr_ptr_t bktr ) 1120{ 1121 bktr->tflags &= ~TUNER_OPEN; 1122 1123 /* mute the audio by switching the mux */ 1124 set_audio( bktr, AUDIO_MUTE ); 1125 1126 /* disable drivers on the GPIO port that control the MUXes */ 1127 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits); 1128 1129 return( 0 ); 1130} 1131 1132int 1133vbi_close( bktr_ptr_t bktr ) 1134{ 1135 1136 bktr->vbiflags &= ~VBI_OPEN; 1137 1138 return( 0 ); 1139} 1140 1141/* 1142 * 1143 */ 1144int 1145video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio) 1146{ 1147 int status; 1148 int count; 1149 1150 1151 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */ 1152 return( ENOMEM ); 1153 1154 if (bktr->flags & METEOR_CAP_MASK) 1155 return( EIO ); /* already capturing */ 1156 1157 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 1158 1159 1160 count = bktr->rows * bktr->cols * 1161 pixfmt_table[ bktr->pixfmt ].public.Bpp; 1162 1163 if ((int) uio->uio_iov->iov_len < count) 1164 return( EINVAL ); 1165 1166 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK); 1167 1168 /* capture one frame */ 1169 start_capture(bktr, METEOR_SINGLE); 1170 /* wait for capture to complete */ 1171 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 1172 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1173 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1174 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1175 BT848_INT_RISCI | 1176 BT848_INT_VSYNC | 1177 BT848_INT_FMTCHG); 1178 1179 1180 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0); 1181 if (!status) /* successful capture */ 1182 status = uiomove((caddr_t)bktr->bigbuf, count, uio); 1183 else 1184 printf ("%s: read: tsleep error %d\n", 1185 bktr_name(bktr), status); 1186 1187 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK); 1188 1189 return( status ); 1190} 1191 1192/* 1193 * Read VBI data from the vbi circular buffer 1194 * The buffer holds vbi data blocks which are the same size 1195 * vbiinsert is the position we will insert the next item into the buffer 1196 * vbistart is the actual position in the buffer we want to read from 1197 * vbisize is the exact number of bytes in the buffer left to read 1198 */ 1199int 1200vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag) 1201{ 1202 int readsize, readsize2; 1203 int status; 1204 1205 1206 while(bktr->vbisize == 0) { 1207 if (ioflag & IO_NDELAY) { 1208 return EWOULDBLOCK; 1209 } 1210 1211 bktr->vbi_read_blocked = TRUE; 1212 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) { 1213 return status; 1214 } 1215 } 1216 1217 /* Now we have some data to give to the user */ 1218 1219 /* We cannot read more bytes than there are in 1220 * the circular buffer 1221 */ 1222 readsize = (int)uio->uio_iov->iov_len; 1223 1224 if (readsize > bktr->vbisize) readsize = bktr->vbisize; 1225 1226 /* Check if we can read this number of bytes without having 1227 * to wrap around the circular buffer */ 1228 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) { 1229 /* We need to wrap around */ 1230 1231 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart; 1232 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio); 1233 status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio); 1234 } else { 1235 /* We do not need to wrap around */ 1236 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio); 1237 } 1238 1239 /* Update the number of bytes left to read */ 1240 bktr->vbisize -= readsize; 1241 1242 /* Update vbistart */ 1243 bktr->vbistart += readsize; 1244 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */ 1245 1246 return( status ); 1247 1248} 1249 1250 1251 1252/* 1253 * video ioctls 1254 */ 1255int 1256video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr ) 1257{ 1258 volatile u_char c_temp; 1259 unsigned int temp; 1260 unsigned int temp_iform; 1261 unsigned int error; 1262 struct meteor_geomet *geo; 1263 struct meteor_counts *counts; 1264 struct meteor_video *video; 1265 struct bktr_capture_area *cap_area; 1266 vm_offset_t buf; 1267 int i; 1268 char char_temp; 1269 1270 switch ( cmd ) { 1271 1272 case BT848SCLIP: /* set clip region */ 1273 bktr->max_clip_node = 0; 1274 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list)); 1275 1276 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) { 1277 if (bktr->clip_list[i].y_min == 0 && 1278 bktr->clip_list[i].y_max == 0) 1279 break; 1280 } 1281 bktr->max_clip_node = i; 1282 1283 /* make sure that the list contains a valid clip secquence */ 1284 /* the clip rectangles should be sorted by x then by y as the 1285 second order sort key */ 1286 1287 /* clip rectangle list is terminated by y_min and y_max set to 0 */ 1288 1289 /* to disable clipping set y_min and y_max to 0 in the first 1290 clip rectangle . The first clip rectangle is clip_list[0]. 1291 */ 1292 1293 1294 1295 if (bktr->max_clip_node == 0 && 1296 (bktr->clip_list[0].y_min != 0 && 1297 bktr->clip_list[0].y_max != 0)) { 1298 return EINVAL; 1299 } 1300 1301 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) { 1302 if (bktr->clip_list[i].y_min == 0 && 1303 bktr->clip_list[i].y_max == 0) { 1304 break; 1305 } 1306 if ( bktr->clip_list[i+1].y_min != 0 && 1307 bktr->clip_list[i+1].y_max != 0 && 1308 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) { 1309 1310 bktr->max_clip_node = 0; 1311 return (EINVAL); 1312 1313 } 1314 1315 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max || 1316 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max || 1317 bktr->clip_list[i].x_min < 0 || 1318 bktr->clip_list[i].x_max < 0 || 1319 bktr->clip_list[i].y_min < 0 || 1320 bktr->clip_list[i].y_max < 0 ) { 1321 bktr->max_clip_node = 0; 1322 return (EINVAL); 1323 } 1324 } 1325 1326 bktr->dma_prog_loaded = FALSE; 1327 1328 break; 1329 1330 case METEORSTATUS: /* get Bt848 status */ 1331 c_temp = INB(bktr, BKTR_DSTATUS); 1332 temp = 0; 1333 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK; 1334 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT; 1335 *(u_short *)arg = temp; 1336 break; 1337 1338 case BT848SFMT: /* set input format */ 1339 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT; 1340 temp_iform = INB(bktr, BKTR_IFORM); 1341 temp_iform &= ~BT848_IFORM_FORMAT; 1342 temp_iform &= ~BT848_IFORM_XTSEL; 1343 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel)); 1344 switch( temp ) { 1345 case BT848_IFORM_F_AUTO: 1346 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1347 METEOR_AUTOMODE; 1348 break; 1349 1350 case BT848_IFORM_F_NTSCM: 1351 case BT848_IFORM_F_NTSCJ: 1352 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1353 METEOR_NTSC; 1354 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay); 1355 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay); 1356 bktr->format_params = temp; 1357 break; 1358 1359 case BT848_IFORM_F_PALBDGHI: 1360 case BT848_IFORM_F_PALN: 1361 case BT848_IFORM_F_SECAM: 1362 case BT848_IFORM_F_RSVD: 1363 case BT848_IFORM_F_PALM: 1364 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1365 METEOR_PAL; 1366 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay); 1367 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay); 1368 bktr->format_params = temp; 1369 break; 1370 1371 } 1372 bktr->dma_prog_loaded = FALSE; 1373 break; 1374 1375 case METEORSFMT: /* set input format */ 1376 temp_iform = INB(bktr, BKTR_IFORM); 1377 temp_iform &= ~BT848_IFORM_FORMAT; 1378 temp_iform &= ~BT848_IFORM_XTSEL; 1379 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) { 1380 case 0: /* default */ 1381 case METEOR_FMT_NTSC: 1382 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1383 METEOR_NTSC; 1384 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM | 1385 format_params[BT848_IFORM_F_NTSCM].iform_xtsel); 1386 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay); 1387 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay); 1388 bktr->format_params = BT848_IFORM_F_NTSCM; 1389 break; 1390 1391 case METEOR_FMT_PAL: 1392 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1393 METEOR_PAL; 1394 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI | 1395 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel); 1396 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay); 1397 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay); 1398 bktr->format_params = BT848_IFORM_F_PALBDGHI; 1399 break; 1400 1401 case METEOR_FMT_AUTOMODE: 1402 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) | 1403 METEOR_AUTOMODE; 1404 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO | 1405 format_params[BT848_IFORM_F_AUTO].iform_xtsel); 1406 break; 1407 1408 default: 1409 return( EINVAL ); 1410 } 1411 bktr->dma_prog_loaded = FALSE; 1412 break; 1413 1414 case METEORGFMT: /* get input format */ 1415 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK; 1416 break; 1417 1418 1419 case BT848GFMT: /* get input format */ 1420 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT; 1421 break; 1422 1423 case METEORSCOUNT: /* (re)set error counts */ 1424 counts = (struct meteor_counts *) arg; 1425 bktr->fifo_errors = counts->fifo_errors; 1426 bktr->dma_errors = counts->dma_errors; 1427 bktr->frames_captured = counts->frames_captured; 1428 bktr->even_fields_captured = counts->even_fields_captured; 1429 bktr->odd_fields_captured = counts->odd_fields_captured; 1430 break; 1431 1432 case METEORGCOUNT: /* get error counts */ 1433 counts = (struct meteor_counts *) arg; 1434 counts->fifo_errors = bktr->fifo_errors; 1435 counts->dma_errors = bktr->dma_errors; 1436 counts->frames_captured = bktr->frames_captured; 1437 counts->even_fields_captured = bktr->even_fields_captured; 1438 counts->odd_fields_captured = bktr->odd_fields_captured; 1439 break; 1440 1441 case METEORGVIDEO: 1442 video = (struct meteor_video *)arg; 1443 video->addr = bktr->video.addr; 1444 video->width = bktr->video.width; 1445 video->banksize = bktr->video.banksize; 1446 video->ramsize = bktr->video.ramsize; 1447 break; 1448 1449 case METEORSVIDEO: 1450 video = (struct meteor_video *)arg; 1451 bktr->video.addr = video->addr; 1452 bktr->video.width = video->width; 1453 bktr->video.banksize = video->banksize; 1454 bktr->video.ramsize = video->ramsize; 1455 break; 1456 1457 case METEORSFPS: 1458 set_fps(bktr, *(u_short *)arg); 1459 break; 1460 1461 case METEORGFPS: 1462 *(u_short *)arg = bktr->fps; 1463 break; 1464 1465 case METEORSHUE: /* set hue */ 1466 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff); 1467 break; 1468 1469 case METEORGHUE: /* get hue */ 1470 *(u_char *)arg = INB(bktr, BKTR_HUE); 1471 break; 1472 1473 case METEORSBRIG: /* set brightness */ 1474 char_temp = ( *(u_char *)arg & 0xff) - 128; 1475 OUTB(bktr, BKTR_BRIGHT, char_temp); 1476 1477 break; 1478 1479 case METEORGBRIG: /* get brightness */ 1480 *(u_char *)arg = INB(bktr, BKTR_BRIGHT); 1481 break; 1482 1483 case METEORSCSAT: /* set chroma saturation */ 1484 temp = (int)*(u_char *)arg; 1485 1486 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff); 1487 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff); 1488 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) 1489 & ~(BT848_E_CONTROL_SAT_U_MSB 1490 | BT848_E_CONTROL_SAT_V_MSB)); 1491 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) 1492 & ~(BT848_O_CONTROL_SAT_U_MSB | 1493 BT848_O_CONTROL_SAT_V_MSB)); 1494 1495 if ( temp & BIT_SEVEN_HIGH ) { 1496 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) 1497 | (BT848_E_CONTROL_SAT_U_MSB 1498 | BT848_E_CONTROL_SAT_V_MSB)); 1499 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) 1500 | (BT848_O_CONTROL_SAT_U_MSB 1501 | BT848_O_CONTROL_SAT_V_MSB)); 1502 } 1503 break; 1504 1505 case METEORGCSAT: /* get chroma saturation */ 1506 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff; 1507 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB ) 1508 temp |= BIT_SEVEN_HIGH; 1509 *(u_char *)arg = (u_char)temp; 1510 break; 1511 1512 case METEORSCONT: /* set contrast */ 1513 temp = (int)*(u_char *)arg & 0xff; 1514 temp <<= 1; 1515 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff); 1516 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB); 1517 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB); 1518 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | 1519 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB)); 1520 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | 1521 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB)); 1522 break; 1523 1524 case METEORGCONT: /* get contrast */ 1525 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff; 1526 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6; 1527 *(u_char *)arg = (u_char)((temp >> 1) & 0xff); 1528 break; 1529 1530 case BT848SCBUF: /* set Clear-Buffer-on-start flag */ 1531 bktr->clr_on_start = (*(int *)arg != 0); 1532 break; 1533 1534 case BT848GCBUF: /* get Clear-Buffer-on-start flag */ 1535 *(int *)arg = (int) bktr->clr_on_start; 1536 break; 1537 1538 case METEORSSIGNAL: 1539 if(*(int *)arg == 0 || *(int *)arg >= NSIG) { 1540 return( EINVAL ); 1541 break; 1542 } 1543 bktr->signal = *(int *) arg; 1544 bktr->proc = pr; 1545 break; 1546 1547 case METEORGSIGNAL: 1548 *(int *)arg = bktr->signal; 1549 break; 1550 1551 case METEORCAPTUR: 1552 temp = bktr->flags; 1553 switch (*(int *) arg) { 1554 case METEOR_CAP_SINGLE: 1555 1556 if (bktr->bigbuf==0) /* no frame buffer allocated */ 1557 return( ENOMEM ); 1558 /* already capturing */ 1559 if (temp & METEOR_CAP_MASK) 1560 return( EIO ); 1561 1562 1563 1564 start_capture(bktr, METEOR_SINGLE); 1565 1566 /* wait for capture to complete */ 1567 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 1568 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1569 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1570 1571 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1572 BT848_INT_RISCI | 1573 BT848_INT_VSYNC | 1574 BT848_INT_FMTCHG); 1575 1576 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 1577 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz); 1578 if (error && (error != ERESTART)) { 1579 /* Here if we didn't get complete frame */ 1580#ifdef DIAGNOSTIC 1581 printf( "%s: ioctl: tsleep error %d %x\n", 1582 bktr_name(bktr), error, 1583 INL(bktr, BKTR_RISC_COUNT)); 1584#endif 1585 1586 /* stop dma */ 1587 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1588 1589 /* disable risc, leave fifo running */ 1590 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1591 } 1592 1593 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK); 1594 /* FIXME: should we set bt848->int_stat ??? */ 1595 break; 1596 1597 case METEOR_CAP_CONTINOUS: 1598 if (bktr->bigbuf==0) /* no frame buffer allocated */ 1599 return( ENOMEM ); 1600 /* already capturing */ 1601 if (temp & METEOR_CAP_MASK) 1602 return( EIO ); 1603 1604 1605 start_capture(bktr, METEOR_CONTIN); 1606 1607 /* Clear the interrypt status register */ 1608 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT)); 1609 1610 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1611 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1612 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl); 1613 1614 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1615 BT848_INT_RISCI | 1616 BT848_INT_VSYNC | 1617 BT848_INT_FMTCHG); 1618#ifdef BT848_DUMP 1619 dump_bt848( bt848 ); 1620#endif 1621 break; 1622 1623 case METEOR_CAP_STOP_CONT: 1624 if (bktr->flags & METEOR_CONTIN) { 1625 /* turn off capture */ 1626 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 1627 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF); 1628 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1629 bktr->flags &= 1630 ~(METEOR_CONTIN | METEOR_WANT_MASK); 1631 1632 } 1633 } 1634 break; 1635 1636 case METEORSETGEO: 1637 /* can't change parameters while capturing */ 1638 if (bktr->flags & METEOR_CAP_MASK) 1639 return( EBUSY ); 1640 1641 1642 geo = (struct meteor_geomet *) arg; 1643 1644 error = 0; 1645 /* Either even or odd, if even & odd, then these a zero */ 1646 if ((geo->oformat & METEOR_GEO_ODD_ONLY) && 1647 (geo->oformat & METEOR_GEO_EVEN_ONLY)) { 1648 printf( "%s: ioctl: Geometry odd or even only.\n", 1649 bktr_name(bktr)); 1650 return( EINVAL ); 1651 } 1652 1653 /* set/clear even/odd flags */ 1654 if (geo->oformat & METEOR_GEO_ODD_ONLY) 1655 bktr->flags |= METEOR_ONLY_ODD_FIELDS; 1656 else 1657 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS; 1658 if (geo->oformat & METEOR_GEO_EVEN_ONLY) 1659 bktr->flags |= METEOR_ONLY_EVEN_FIELDS; 1660 else 1661 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS; 1662 1663 if (geo->columns <= 0) { 1664 printf( 1665 "%s: ioctl: %d: columns must be greater than zero.\n", 1666 bktr_name(bktr), geo->columns); 1667 error = EINVAL; 1668 } 1669 else if ((geo->columns & 0x3fe) != geo->columns) { 1670 printf( 1671 "%s: ioctl: %d: columns too large or not even.\n", 1672 bktr_name(bktr), geo->columns); 1673 error = EINVAL; 1674 } 1675 1676 if (geo->rows <= 0) { 1677 printf( 1678 "%s: ioctl: %d: rows must be greater than zero.\n", 1679 bktr_name(bktr), geo->rows); 1680 error = EINVAL; 1681 } 1682 else if (((geo->rows & 0x7fe) != geo->rows) || 1683 ((geo->oformat & METEOR_GEO_FIELD_MASK) && 1684 ((geo->rows & 0x3fe) != geo->rows)) ) { 1685 printf( 1686 "%s: ioctl: %d: rows too large or not even.\n", 1687 bktr_name(bktr), geo->rows); 1688 error = EINVAL; 1689 } 1690 1691 if (geo->frames > 32) { 1692 printf("%s: ioctl: too many frames.\n", 1693 bktr_name(bktr)); 1694 1695 error = EINVAL; 1696 } 1697 1698 if (error) 1699 return( error ); 1700 1701 bktr->dma_prog_loaded = FALSE; 1702 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 1703 1704 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 1705 1706 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) { 1707 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2; 1708 1709 /* meteor_mem structure for SYNC Capture */ 1710 if (geo->frames > 1) temp += PAGE_SIZE; 1711 1712 temp = btoc(temp); 1713 if ((int) temp > bktr->alloc_pages 1714 && bktr->video.addr == 0) { 1715 1716/*****************************/ 1717/* *** OS Dependant code *** */ 1718/*****************************/ 1719#if defined(__NetBSD__) || defined(__OpenBSD__) 1720 bus_dmamap_t dmamap; 1721 1722 buf = get_bktr_mem(bktr, &dmamap, 1723 temp * PAGE_SIZE); 1724 if (buf != 0) { 1725 free_bktr_mem(bktr, bktr->dm_mem, 1726 bktr->bigbuf); 1727 bktr->dm_mem = dmamap; 1728 1729#else 1730 buf = get_bktr_mem(unit, temp*PAGE_SIZE); 1731 if (buf != 0) { 1732 kmem_free(kernel_map, bktr->bigbuf, 1733 (bktr->alloc_pages * PAGE_SIZE)); 1734#endif 1735 1736 bktr->bigbuf = buf; 1737 bktr->alloc_pages = temp; 1738 if (bootverbose) 1739 printf( 1740 "%s: ioctl: Allocating %d bytes\n", 1741 bktr_name(bktr), temp*PAGE_SIZE); 1742 } 1743 else 1744 error = ENOMEM; 1745 } 1746 } 1747 1748 if (error) 1749 return error; 1750 1751 bktr->rows = geo->rows; 1752 bktr->cols = geo->columns; 1753 bktr->frames = geo->frames; 1754 1755 /* Pixel format (if in meteor pixfmt compatibility mode) */ 1756 if ( bktr->pixfmt_compat ) { 1757 bktr->format = METEOR_GEO_YUV_422; 1758 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) { 1759 case 0: /* default */ 1760 case METEOR_GEO_RGB16: 1761 bktr->format = METEOR_GEO_RGB16; 1762 break; 1763 case METEOR_GEO_RGB24: 1764 bktr->format = METEOR_GEO_RGB24; 1765 break; 1766 case METEOR_GEO_YUV_422: 1767 bktr->format = METEOR_GEO_YUV_422; 1768 if (geo->oformat & METEOR_GEO_YUV_12) 1769 bktr->format = METEOR_GEO_YUV_12; 1770 break; 1771 case METEOR_GEO_YUV_PACKED: 1772 bktr->format = METEOR_GEO_YUV_PACKED; 1773 break; 1774 } 1775 bktr->pixfmt = oformat_meteor_to_bt( bktr->format ); 1776 } 1777 1778 if (bktr->flags & METEOR_CAP_MASK) { 1779 1780 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) { 1781 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 1782 case METEOR_ONLY_ODD_FIELDS: 1783 bktr->flags |= METEOR_WANT_ODD; 1784 break; 1785 case METEOR_ONLY_EVEN_FIELDS: 1786 bktr->flags |= METEOR_WANT_EVEN; 1787 break; 1788 default: 1789 bktr->flags |= METEOR_WANT_MASK; 1790 break; 1791 } 1792 1793 start_capture(bktr, METEOR_CONTIN); 1794 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT)); 1795 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED); 1796 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol); 1797 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT | 1798 BT848_INT_VSYNC | 1799 BT848_INT_FMTCHG); 1800 } 1801 } 1802 break; 1803 /* end of METEORSETGEO */ 1804 1805 /* FIXME. The Capture Area currently has the following restrictions: 1806 GENERAL 1807 y_offset may need to be even in interlaced modes 1808 RGB24 - Interlaced mode 1809 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols) 1810 y_size must be greater than or equal to METEORSETGEO height (rows) 1811 RGB24 - Even Only (or Odd Only) mode 1812 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols) 1813 y_size must be greater than or equal to 2*METEORSETGEO height (rows) 1814 YUV12 - Interlaced mode 1815 x_size must be greater than or equal to METEORSETGEO width (cols) 1816 y_size must be greater than or equal to METEORSETGEO height (rows) 1817 YUV12 - Even Only (or Odd Only) mode 1818 x_size must be greater than or equal to METEORSETGEO width (cols) 1819 y_size must be greater than or equal to 2*METEORSETGEO height (rows) 1820 */ 1821 1822 case BT848_SCAPAREA: /* set capture area of each video frame */ 1823 /* can't change parameters while capturing */ 1824 if (bktr->flags & METEOR_CAP_MASK) 1825 return( EBUSY ); 1826 1827 cap_area = (struct bktr_capture_area *) arg; 1828 bktr->capture_area_x_offset = cap_area->x_offset; 1829 bktr->capture_area_y_offset = cap_area->y_offset; 1830 bktr->capture_area_x_size = cap_area->x_size; 1831 bktr->capture_area_y_size = cap_area->y_size; 1832 bktr->capture_area_enabled = TRUE; 1833 1834 bktr->dma_prog_loaded = FALSE; 1835 break; 1836 1837 case BT848_GCAPAREA: /* get capture area of each video frame */ 1838 cap_area = (struct bktr_capture_area *) arg; 1839 if (bktr->capture_area_enabled == FALSE) { 1840 cap_area->x_offset = 0; 1841 cap_area->y_offset = 0; 1842 cap_area->x_size = format_params[ 1843 bktr->format_params].scaled_hactive; 1844 cap_area->y_size = format_params[ 1845 bktr->format_params].vactive; 1846 } else { 1847 cap_area->x_offset = bktr->capture_area_x_offset; 1848 cap_area->y_offset = bktr->capture_area_y_offset; 1849 cap_area->x_size = bktr->capture_area_x_size; 1850 cap_area->y_size = bktr->capture_area_y_size; 1851 } 1852 break; 1853 1854 default: 1855 return common_ioctl( bktr, cmd, arg ); 1856 } 1857 1858 return( 0 ); 1859} 1860 1861/* 1862 * tuner ioctls 1863 */ 1864int 1865tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr ) 1866{ 1867 int tmp_int; 1868 unsigned int temp, temp1; 1869 int offset; 1870 int count; 1871 u_char *buf; 1872 u_long par; 1873 u_char write; 1874 int i2c_addr; 1875 int i2c_port; 1876 u_long data; 1877 1878 switch ( cmd ) { 1879 1880 case REMOTE_GETKEY: 1881 /* Read the last key pressed by the Remote Control */ 1882 if (bktr->remote_control == 0) return (EINVAL); 1883 remote_read(bktr, (struct bktr_remote *)arg); 1884 break; 1885 1886#if defined( TUNER_AFC ) 1887 case TVTUNER_SETAFC: 1888 bktr->tuner.afc = (*(int *)arg != 0); 1889 break; 1890 1891 case TVTUNER_GETAFC: 1892 *(int *)arg = bktr->tuner.afc; 1893 /* XXX Perhaps use another bit to indicate AFC success? */ 1894 break; 1895#endif /* TUNER_AFC */ 1896 1897 case TVTUNER_SETCHNL: 1898 temp_mute( bktr, TRUE ); 1899 temp = tv_channel( bktr, (int)*(unsigned long *)arg ); 1900 if ( temp < 0 ) { 1901 temp_mute( bktr, FALSE ); 1902 return( EINVAL ); 1903 } 1904 *(unsigned long *)arg = temp; 1905 1906 /* after every channel change, we must restart the MSP34xx */ 1907 /* audio chip to reselect NICAM STEREO or MONO audio */ 1908 if ( bktr->card.msp3400c ) 1909 msp_autodetect( bktr ); 1910 1911 /* after every channel change, we must restart the DPL35xx */ 1912 if ( bktr->card.dpl3518a ) 1913 dpl_autodetect( bktr ); 1914 1915 temp_mute( bktr, FALSE ); 1916 break; 1917 1918 case TVTUNER_GETCHNL: 1919 *(unsigned long *)arg = bktr->tuner.channel; 1920 break; 1921 1922 case TVTUNER_SETTYPE: 1923 temp = *(unsigned long *)arg; 1924 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) ) 1925 return( EINVAL ); 1926 bktr->tuner.chnlset = temp; 1927 break; 1928 1929 case TVTUNER_GETTYPE: 1930 *(unsigned long *)arg = bktr->tuner.chnlset; 1931 break; 1932 1933 case TVTUNER_GETSTATUS: 1934 temp = get_tuner_status( bktr ); 1935 *(unsigned long *)arg = temp & 0xff; 1936 break; 1937 1938 case TVTUNER_SETFREQ: 1939 temp_mute( bktr, TRUE ); 1940 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY); 1941 temp_mute( bktr, FALSE ); 1942 if ( temp < 0 ) { 1943 temp_mute( bktr, FALSE ); 1944 return( EINVAL ); 1945 } 1946 *(unsigned long *)arg = temp; 1947 1948 /* after every channel change, we must restart the MSP34xx */ 1949 /* audio chip to reselect NICAM STEREO or MONO audio */ 1950 if ( bktr->card.msp3400c ) 1951 msp_autodetect( bktr ); 1952 1953 /* after every channel change, we must restart the DPL35xx */ 1954 if ( bktr->card.dpl3518a ) 1955 dpl_autodetect( bktr ); 1956 1957 temp_mute( bktr, FALSE ); 1958 break; 1959 1960 case TVTUNER_GETFREQ: 1961 *(unsigned long *)arg = bktr->tuner.frequency; 1962 break; 1963 1964 case TVTUNER_GETCHNLSET: 1965 return tuner_getchnlset((struct bktr_chnlset *)arg); 1966 1967 case BT848_SAUDIO: /* set audio channel */ 1968 if ( set_audio( bktr, *(int*)arg ) < 0 ) 1969 return( EIO ); 1970 break; 1971 1972 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */ 1973 case BT848_SHUE: /* set hue */ 1974 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff)); 1975 break; 1976 1977 case BT848_GHUE: /* get hue */ 1978 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff); 1979 break; 1980 1981 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */ 1982 case BT848_SBRIG: /* set brightness */ 1983 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff)); 1984 break; 1985 1986 case BT848_GBRIG: /* get brightness */ 1987 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff); 1988 break; 1989 1990 /* */ 1991 case BT848_SCSAT: /* set chroma saturation */ 1992 tmp_int = *(int*)arg; 1993 1994 temp = INB(bktr, BKTR_E_CONTROL); 1995 temp1 = INB(bktr, BKTR_O_CONTROL); 1996 if ( tmp_int & BIT_EIGHT_HIGH ) { 1997 temp |= (BT848_E_CONTROL_SAT_U_MSB | 1998 BT848_E_CONTROL_SAT_V_MSB); 1999 temp1 |= (BT848_O_CONTROL_SAT_U_MSB | 2000 BT848_O_CONTROL_SAT_V_MSB); 2001 } 2002 else { 2003 temp &= ~(BT848_E_CONTROL_SAT_U_MSB | 2004 BT848_E_CONTROL_SAT_V_MSB); 2005 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB | 2006 BT848_O_CONTROL_SAT_V_MSB); 2007 } 2008 2009 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff)); 2010 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff)); 2011 OUTB(bktr, BKTR_E_CONTROL, temp); 2012 OUTB(bktr, BKTR_O_CONTROL, temp1); 2013 break; 2014 2015 case BT848_GCSAT: /* get chroma saturation */ 2016 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff); 2017 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB ) 2018 tmp_int |= BIT_EIGHT_HIGH; 2019 *(int*)arg = tmp_int; 2020 break; 2021 2022 /* */ 2023 case BT848_SVSAT: /* set chroma V saturation */ 2024 tmp_int = *(int*)arg; 2025 2026 temp = INB(bktr, BKTR_E_CONTROL); 2027 temp1 = INB(bktr, BKTR_O_CONTROL); 2028 if ( tmp_int & BIT_EIGHT_HIGH) { 2029 temp |= BT848_E_CONTROL_SAT_V_MSB; 2030 temp1 |= BT848_O_CONTROL_SAT_V_MSB; 2031 } 2032 else { 2033 temp &= ~BT848_E_CONTROL_SAT_V_MSB; 2034 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB; 2035 } 2036 2037 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff)); 2038 OUTB(bktr, BKTR_E_CONTROL, temp); 2039 OUTB(bktr, BKTR_O_CONTROL, temp1); 2040 break; 2041 2042 case BT848_GVSAT: /* get chroma V saturation */ 2043 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff; 2044 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB ) 2045 tmp_int |= BIT_EIGHT_HIGH; 2046 *(int*)arg = tmp_int; 2047 break; 2048 2049 /* */ 2050 case BT848_SUSAT: /* set chroma U saturation */ 2051 tmp_int = *(int*)arg; 2052 2053 temp = INB(bktr, BKTR_E_CONTROL); 2054 temp1 = INB(bktr, BKTR_O_CONTROL); 2055 if ( tmp_int & BIT_EIGHT_HIGH ) { 2056 temp |= BT848_E_CONTROL_SAT_U_MSB; 2057 temp1 |= BT848_O_CONTROL_SAT_U_MSB; 2058 } 2059 else { 2060 temp &= ~BT848_E_CONTROL_SAT_U_MSB; 2061 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB; 2062 } 2063 2064 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff)); 2065 OUTB(bktr, BKTR_E_CONTROL, temp); 2066 OUTB(bktr, BKTR_O_CONTROL, temp1); 2067 break; 2068 2069 case BT848_GUSAT: /* get chroma U saturation */ 2070 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff; 2071 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB ) 2072 tmp_int |= BIT_EIGHT_HIGH; 2073 *(int*)arg = tmp_int; 2074 break; 2075 2076/* lr 970528 luma notch etc - 3 high bits of e_control/o_control */ 2077 2078 case BT848_SLNOTCH: /* set luma notch */ 2079 tmp_int = (*(int *)arg & 0x7) << 5 ; 2080 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0); 2081 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0); 2082 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int); 2083 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int); 2084 break; 2085 2086 case BT848_GLNOTCH: /* get luma notch */ 2087 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ; 2088 break; 2089 2090 2091 /* */ 2092 case BT848_SCONT: /* set contrast */ 2093 tmp_int = *(int*)arg; 2094 2095 temp = INB(bktr, BKTR_E_CONTROL); 2096 temp1 = INB(bktr, BKTR_O_CONTROL); 2097 if ( tmp_int & BIT_EIGHT_HIGH ) { 2098 temp |= BT848_E_CONTROL_CON_MSB; 2099 temp1 |= BT848_O_CONTROL_CON_MSB; 2100 } 2101 else { 2102 temp &= ~BT848_E_CONTROL_CON_MSB; 2103 temp1 &= ~BT848_O_CONTROL_CON_MSB; 2104 } 2105 2106 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff)); 2107 OUTB(bktr, BKTR_E_CONTROL, temp); 2108 OUTB(bktr, BKTR_O_CONTROL, temp1); 2109 break; 2110 2111 case BT848_GCONT: /* get contrast */ 2112 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff; 2113 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB ) 2114 tmp_int |= BIT_EIGHT_HIGH; 2115 *(int*)arg = tmp_int; 2116 break; 2117 2118 /* FIXME: SCBARS and CCBARS require a valid int * */ 2119 /* argument to succeed, but its not used; consider */ 2120 /* using the arg to store the on/off state so */ 2121 /* there's only one ioctl() needed to turn cbars on/off */ 2122 case BT848_SCBARS: /* set colorbar output */ 2123 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS); 2124 break; 2125 2126 case BT848_CCBARS: /* clear colorbar output */ 2127 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS)); 2128 break; 2129 2130 case BT848_GAUDIO: /* get audio channel */ 2131 temp = bktr->audio_mux_select; 2132 if ( bktr->audio_mute_state == TRUE ) 2133 temp |= AUDIO_MUTE; 2134 *(int*)arg = temp; 2135 break; 2136 2137 case BT848_SBTSC: /* set audio channel */ 2138 if ( set_BTSC( bktr, *(int*)arg ) < 0 ) 2139 return( EIO ); 2140 break; 2141 2142 case BT848_WEEPROM: /* write eeprom */ 2143 offset = (((struct eeProm *)arg)->offset); 2144 count = (((struct eeProm *)arg)->count); 2145 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2146 if ( writeEEProm( bktr, offset, count, buf ) < 0 ) 2147 return( EIO ); 2148 break; 2149 2150 case BT848_REEPROM: /* read eeprom */ 2151 offset = (((struct eeProm *)arg)->offset); 2152 count = (((struct eeProm *)arg)->count); 2153 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2154 if ( readEEProm( bktr, offset, count, buf ) < 0 ) 2155 return( EIO ); 2156 break; 2157 2158 case BT848_SIGNATURE: 2159 offset = (((struct eeProm *)arg)->offset); 2160 count = (((struct eeProm *)arg)->count); 2161 buf = &(((struct eeProm *)arg)->bytes[ 0 ]); 2162 if ( signCard( bktr, offset, count, buf ) < 0 ) 2163 return( EIO ); 2164 break; 2165 2166 /* Ioctl's for direct gpio access */ 2167#ifdef BKTR_GPIO_ACCESS 2168 case BT848_GPIO_GET_EN: 2169 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN); 2170 break; 2171 2172 case BT848_GPIO_SET_EN: 2173 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg); 2174 break; 2175 2176 case BT848_GPIO_GET_DATA: 2177 *(int*)arg = INL(bktr, BKTR_GPIO_DATA); 2178 break; 2179 2180 case BT848_GPIO_SET_DATA: 2181 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg); 2182 break; 2183#endif /* BKTR_GPIO_ACCESS */ 2184 2185 /* Ioctl's for running the tuner device in radio mode */ 2186 2187 case RADIO_GETMODE: 2188 *(unsigned char *)arg = bktr->tuner.radio_mode; 2189 break; 2190 2191 case RADIO_SETMODE: 2192 bktr->tuner.radio_mode = *(unsigned char *)arg; 2193 break; 2194 2195 case RADIO_GETFREQ: 2196 *(unsigned long *)arg = bktr->tuner.frequency; 2197 break; 2198 2199 case RADIO_SETFREQ: 2200 /* The argument to this ioctl is NOT freq*16. It is 2201 ** freq*100. 2202 */ 2203 2204 temp=(int)*(unsigned long *)arg; 2205 2206#ifdef BKTR_RADIO_DEBUG 2207 printf("%s: arg=%d temp=%d\n", bktr_name(bktr), 2208 (int)*(unsigned long *)arg, temp); 2209#endif 2210 2211#ifndef BKTR_RADIO_NOFREQCHECK 2212 /* According to the spec. sheet the band: 87.5MHz-108MHz */ 2213 /* is supported. */ 2214 if(temp<8750 || temp>10800) { 2215 printf("%s: Radio frequency out of range\n", bktr_name(bktr)); 2216 return(EINVAL); 2217 } 2218#endif 2219 temp_mute( bktr, TRUE ); 2220 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY ); 2221 temp_mute( bktr, FALSE ); 2222#ifdef BKTR_RADIO_DEBUG 2223 if(temp) 2224 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp); 2225#endif 2226 if ( temp < 0 ) 2227 return( EINVAL ); 2228 *(unsigned long *)arg = temp; 2229 break; 2230 2231 /* Luigi's I2CWR ioctl */ 2232 case BT848_I2CWR: 2233 par = *(u_long *)arg; 2234 write = (par >> 24) & 0xff ; 2235 i2c_addr = (par >> 16) & 0xff ; 2236 i2c_port = (par >> 8) & 0xff ; 2237 data = (par) & 0xff ; 2238 2239 if (write) { 2240 i2cWrite( bktr, i2c_addr, i2c_port, data); 2241 } else { 2242 data = i2cRead( bktr, i2c_addr); 2243 } 2244 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff ); 2245 break; 2246 2247 2248 default: 2249 return common_ioctl( bktr, cmd, arg ); 2250 } 2251 2252 return( 0 ); 2253} 2254 2255 2256/* 2257 * common ioctls 2258 */ 2259int 2260common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg ) 2261{ 2262 int pixfmt; 2263 unsigned int temp; 2264 struct meteor_pixfmt *pf_pub; 2265 2266 switch (cmd) { 2267 2268 case METEORSINPUT: /* set input device */ 2269 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/ 2270 /* On the original bt848 boards, */ 2271 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */ 2272 /* On the Hauppauge bt878 boards, */ 2273 /* Tuner is MUX0, RCA is MUX3 */ 2274 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */ 2275 /* stick with this system in our Meteor Emulation */ 2276 2277 switch(*(unsigned long *)arg & METEOR_DEV_MASK) { 2278 2279 /* this is the RCA video input */ 2280 case 0: /* default */ 2281 case METEOR_INPUT_DEV0: 2282 /* METEOR_INPUT_DEV_RCA: */ 2283 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2284 | METEOR_DEV0; 2285 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) 2286 & ~BT848_IFORM_MUXSEL); 2287 2288 /* work around for new Hauppauge 878 cards */ 2289 if ((bktr->card.card_id == CARD_HAUPPAUGE) && 2290 (bktr->id==BROOKTREE_878 || 2291 bktr->id==BROOKTREE_879) ) 2292 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3); 2293 else 2294 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1); 2295 2296 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2297 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP); 2298 set_audio( bktr, AUDIO_EXTERN ); 2299 break; 2300 2301 /* this is the tuner input */ 2302 case METEOR_INPUT_DEV1: 2303 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2304 | METEOR_DEV1; 2305 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2306 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0); 2307 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2308 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP); 2309 set_audio( bktr, AUDIO_TUNER ); 2310 break; 2311 2312 /* this is the S-VHS input, but with a composite camera */ 2313 case METEOR_INPUT_DEV2: 2314 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2315 | METEOR_DEV2; 2316 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2317 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2); 2318 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2319 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP); 2320 set_audio( bktr, AUDIO_EXTERN ); 2321 break; 2322 2323 /* this is the S-VHS input */ 2324 case METEOR_INPUT_DEV_SVIDEO: 2325 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2326 | METEOR_DEV_SVIDEO; 2327 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2328 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2); 2329 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP); 2330 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP); 2331 set_audio( bktr, AUDIO_EXTERN ); 2332 break; 2333 2334 case METEOR_INPUT_DEV3: 2335 if ((bktr->id == BROOKTREE_848A) || 2336 (bktr->id == BROOKTREE_849A) || 2337 (bktr->id == BROOKTREE_878) || 2338 (bktr->id == BROOKTREE_879) ) { 2339 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) 2340 | METEOR_DEV3; 2341 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL); 2342 2343 /* work around for new Hauppauge 878 cards */ 2344 if ((bktr->card.card_id == CARD_HAUPPAUGE) && 2345 (bktr->id==BROOKTREE_878 || 2346 bktr->id==BROOKTREE_879) ) 2347 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1); 2348 else 2349 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3); 2350 2351 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP); 2352 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP); 2353 set_audio( bktr, AUDIO_EXTERN ); 2354 2355 break; 2356 } 2357 2358 default: 2359 return( EINVAL ); 2360 } 2361 break; 2362 2363 case METEORGINPUT: /* get input device */ 2364 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK; 2365 break; 2366 2367 case METEORSACTPIXFMT: 2368 if (( *(int *)arg < 0 ) || 2369 ( *(int *)arg >= PIXFMT_TABLE_SIZE )) 2370 return( EINVAL ); 2371 2372 bktr->pixfmt = *(int *)arg; 2373 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 2374 | pixfmt_swap_flags( bktr->pixfmt )); 2375 bktr->pixfmt_compat = FALSE; 2376 break; 2377 2378 case METEORGACTPIXFMT: 2379 *(int *)arg = bktr->pixfmt; 2380 break; 2381 2382 case METEORGSUPPIXFMT : 2383 pf_pub = (struct meteor_pixfmt *)arg; 2384 pixfmt = pf_pub->index; 2385 2386 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE )) 2387 return( EINVAL ); 2388 2389 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public, 2390 sizeof( *pf_pub ) ); 2391 2392 /* Patch in our format index */ 2393 pf_pub->index = pixfmt; 2394 break; 2395 2396#if defined( STATUS_SUM ) 2397 case BT848_GSTATUS: /* reap status */ 2398 { 2399 DECLARE_INTR_MASK(s); 2400 DISABLE_INTR(s); 2401 temp = status_sum; 2402 status_sum = 0; 2403 ENABLE_INTR(s); 2404 *(u_int*)arg = temp; 2405 break; 2406 } 2407#endif /* STATUS_SUM */ 2408 2409 default: 2410 return( ENOTTY ); 2411 } 2412 2413 return( 0 ); 2414} 2415 2416 2417 2418 2419/****************************************************************************** 2420 * bt848 RISC programming routines: 2421 */ 2422 2423 2424/* 2425 * 2426 */ 2427#ifdef BT848_DEBUG 2428static int 2429dump_bt848( bktr_ptr_t bktr ) 2430{ 2431 int r[60]={ 2432 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94, 2433 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4, 2434 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40, 2435 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60, 2436 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4, 2437 0, 0, 0, 0 2438 }; 2439 int i; 2440 2441 for (i = 0; i < 40; i+=4) { 2442 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n", 2443 bktr_name(bktr), 2444 r[i], INL(bktr, r[i]), 2445 r[i+1], INL(bktr, r[i+1]), 2446 r[i+2], INL(bktr, r[i+2]), 2447 r[i+3], INL(bktr, r[i+3]])); 2448 } 2449 2450 printf("%s: INT STAT %x \n", bktr_name(bktr), 2451 INL(bktr, BKTR_INT_STAT)); 2452 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr), 2453 INL(bktr, BKTR_INT_MASK)); 2454 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr), 2455 INW(bktr, BKTR_GPIO_DMA_CTL)); 2456 2457 return( 0 ); 2458} 2459 2460#endif 2461 2462/* 2463 * build write instruction 2464 */ 2465#define BKTR_FM1 0x6 /* packed data to follow */ 2466#define BKTR_FM3 0xe /* planar data to follow */ 2467#define BKTR_VRE 0x4 /* Marks the end of the even field */ 2468#define BKTR_VRO 0xC /* Marks the end of the odd field */ 2469#define BKTR_PXV 0x0 /* valid word (never used) */ 2470#define BKTR_EOL 0x1 /* last dword, 4 bytes */ 2471#define BKTR_SOL 0x2 /* first dword */ 2472 2473#define OP_WRITE (0x1 << 28) 2474#define OP_SKIP (0x2 << 28) 2475#define OP_WRITEC (0x5 << 28) 2476#define OP_JUMP (0x7 << 28) 2477#define OP_SYNC (0x8 << 28) 2478#define OP_WRITE123 (0x9 << 28) 2479#define OP_WRITES123 (0xb << 28) 2480#define OP_SOL (1 << 27) /* first instr for scanline */ 2481#define OP_EOL (1 << 26) 2482 2483#define BKTR_RESYNC (1 << 15) 2484#define BKTR_GEN_IRQ (1 << 24) 2485 2486/* 2487 * The RISC status bits can be set/cleared in the RISC programs 2488 * and tested in the Interrupt Handler 2489 */ 2490#define BKTR_SET_RISC_STATUS_BIT0 (1 << 16) 2491#define BKTR_SET_RISC_STATUS_BIT1 (1 << 17) 2492#define BKTR_SET_RISC_STATUS_BIT2 (1 << 18) 2493#define BKTR_SET_RISC_STATUS_BIT3 (1 << 19) 2494 2495#define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20) 2496#define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21) 2497#define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22) 2498#define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23) 2499 2500#define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28) 2501#define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29) 2502#define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30) 2503#define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31) 2504 2505bool_t notclipped (bktr_reg_t * bktr, int x, int width) { 2506 int i; 2507 bktr_clip_t * clip_node; 2508 bktr->clip_start = -1; 2509 bktr->last_y = 0; 2510 bktr->y = 0; 2511 bktr->y2 = width; 2512 bktr->line_length = width; 2513 bktr->yclip = -1; 2514 bktr->yclip2 = -1; 2515 bktr->current_col = 0; 2516 2517 if (bktr->max_clip_node == 0 ) return TRUE; 2518 clip_node = (bktr_clip_t *) &bktr->clip_list[0]; 2519 2520 2521 for (i = 0; i < bktr->max_clip_node; i++ ) { 2522 clip_node = (bktr_clip_t *) &bktr->clip_list[i]; 2523 if (x >= clip_node->x_min && x <= clip_node->x_max ) { 2524 bktr->clip_start = i; 2525 return FALSE; 2526 } 2527 } 2528 2529 return TRUE; 2530} 2531 2532bool_t getline(bktr_reg_t *bktr, int x ) { 2533 int i, j; 2534 bktr_clip_t * clip_node ; 2535 2536 if (bktr->line_length == 0 || 2537 bktr->current_col >= bktr->line_length) return FALSE; 2538 2539 bktr->y = min(bktr->last_y, bktr->line_length); 2540 bktr->y2 = bktr->line_length; 2541 2542 bktr->yclip = bktr->yclip2 = -1; 2543 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) { 2544 clip_node = (bktr_clip_t *) &bktr->clip_list[i]; 2545 if (x >= clip_node->x_min && x <= clip_node->x_max) { 2546 if (bktr->last_y <= clip_node->y_min) { 2547 bktr->y = min(bktr->last_y, bktr->line_length); 2548 bktr->y2 = min(clip_node->y_min, bktr->line_length); 2549 bktr->yclip = min(clip_node->y_min, bktr->line_length); 2550 bktr->yclip2 = min(clip_node->y_max, bktr->line_length); 2551 bktr->last_y = bktr->yclip2; 2552 bktr->clip_start = i; 2553 2554 for (j = i+1; j < bktr->max_clip_node; j++ ) { 2555 clip_node = (bktr_clip_t *) &bktr->clip_list[j]; 2556 if (x >= clip_node->x_min && x <= clip_node->x_max) { 2557 if (bktr->last_y >= clip_node->y_min) { 2558 bktr->yclip2 = min(clip_node->y_max, bktr->line_length); 2559 bktr->last_y = bktr->yclip2; 2560 bktr->clip_start = j; 2561 } 2562 } else break ; 2563 } 2564 return TRUE; 2565 } 2566 } 2567 } 2568 2569 if (bktr->current_col <= bktr->line_length) { 2570 bktr->current_col = bktr->line_length; 2571 return TRUE; 2572 } 2573 return FALSE; 2574} 2575 2576static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width , 2577 u_long operation, int pixel_width, 2578 volatile u_char ** target_buffer, int cols ) { 2579 2580 u_long flag, flag2; 2581 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public; 2582 u_int skip, start_skip; 2583 2584 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */ 2585 /* to the 1st byte in the mem dword containing our start addr. */ 2586 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */ 2587 /* must be Blue. */ 2588 start_skip = 0; 2589 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 )) 2590 switch ( ((uintptr_t) (volatile void *) *target_buffer) % 4 ) { 2591 case 2 : start_skip = 4 ; break; 2592 case 1 : start_skip = 8 ; break; 2593 } 2594 2595 if ((width * pixel_width) < DMA_BT848_SPLIT ) { 2596 if ( width == cols) { 2597 flag = OP_SOL | OP_EOL; 2598 } else if (bktr->current_col == 0 ) { 2599 flag = OP_SOL; 2600 } else if (bktr->current_col == cols) { 2601 flag = OP_EOL; 2602 } else flag = 0; 2603 2604 skip = 0; 2605 if (( flag & OP_SOL ) && ( start_skip > 0 )) { 2606 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip; 2607 flag &= ~OP_SOL; 2608 skip = start_skip; 2609 } 2610 2611 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip); 2612 if (operation != OP_SKIP ) 2613 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer; 2614 2615 *target_buffer += width * pixel_width; 2616 bktr->current_col += width; 2617 2618 } else { 2619 2620 if (bktr->current_col == 0 && width == cols) { 2621 flag = OP_SOL ; 2622 flag2 = OP_EOL; 2623 } else if (bktr->current_col == 0 ) { 2624 flag = OP_SOL; 2625 flag2 = 0; 2626 } else if (bktr->current_col >= cols) { 2627 flag = 0; 2628 flag2 = OP_EOL; 2629 } else { 2630 flag = 0; 2631 flag2 = 0; 2632 } 2633 2634 skip = 0; 2635 if (( flag & OP_SOL ) && ( start_skip > 0 )) { 2636 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip; 2637 flag &= ~OP_SOL; 2638 skip = start_skip; 2639 } 2640 2641 *(*dma_prog)++ = operation | flag | 2642 (width * pixel_width / 2 - skip); 2643 if (operation != OP_SKIP ) 2644 *(*dma_prog)++ = (uintptr_t) (volatile void *) *target_buffer ; 2645 *target_buffer += (width * pixel_width / 2) ; 2646 2647 if ( operation == OP_WRITE ) 2648 operation = OP_WRITEC; 2649 *(*dma_prog)++ = operation | flag2 | 2650 (width * pixel_width / 2); 2651 *target_buffer += (width * pixel_width / 2) ; 2652 bktr->current_col += width; 2653 2654 } 2655 return TRUE; 2656} 2657 2658 2659/* 2660 * Generate the RISC instructions to capture both VBI and video images 2661 */ 2662static void 2663rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) 2664{ 2665 int i; 2666 volatile u_long target_buffer, buffer, target,width; 2667 volatile u_long pitch; 2668 volatile u_long *dma_prog; /* DMA prog is an array of 2669 32 bit RISC instructions */ 2670 volatile u_long *loop_point; 2671 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2672 u_int Bpp = pf_int->public.Bpp; 2673 unsigned int vbisamples; /* VBI samples per line */ 2674 unsigned int vbilines; /* VBI lines per field */ 2675 unsigned int num_dwords; /* DWORDS per line */ 2676 2677 vbisamples = format_params[bktr->format_params].vbi_num_samples; 2678 vbilines = format_params[bktr->format_params].vbi_num_lines; 2679 num_dwords = vbisamples/4; 2680 2681 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 2682 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 2683 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff); 2684 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */ 2685 /* no ext frame */ 2686 2687 OUTB(bktr, BKTR_OFORM, 0x00); 2688 2689 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */ 2690 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40); 2691 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */ 2692 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80); 2693 2694 /* disable gamma correction removal */ 2695 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA); 2696 2697 if (cols > 385 ) { 2698 OUTB(bktr, BKTR_E_VTC, 0); 2699 OUTB(bktr, BKTR_O_VTC, 0); 2700 } else { 2701 OUTB(bktr, BKTR_E_VTC, 1); 2702 OUTB(bktr, BKTR_O_VTC, 1); 2703 } 2704 bktr->capcontrol = 3 << 2 | 3; 2705 2706 dma_prog = (u_long *) bktr->dma_prog; 2707 2708 /* Construct Write */ 2709 2710 if (bktr->video.addr) { 2711 target_buffer = (u_long) bktr->video.addr; 2712 pitch = bktr->video.width; 2713 } 2714 else { 2715 target_buffer = (u_long) vtophys(bktr->bigbuf); 2716 pitch = cols*Bpp; 2717 } 2718 2719 buffer = target_buffer; 2720 2721 /* Wait for the VRE sync marking the end of the Even and 2722 * the start of the Odd field. Resync here. 2723 */ 2724 *dma_prog++ = OP_SYNC | BKTR_RESYNC |BKTR_VRE; 2725 *dma_prog++ = 0; 2726 2727 loop_point = dma_prog; 2728 2729 /* store the VBI data */ 2730 /* look for sync with packed data */ 2731 *dma_prog++ = OP_SYNC | BKTR_FM1; 2732 *dma_prog++ = 0; 2733 for(i = 0; i < vbilines; i++) { 2734 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples; 2735 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata + 2736 (i * VBI_LINE_SIZE)); 2737 } 2738 2739 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) { 2740 /* store the Odd field video image */ 2741 /* look for sync with packed data */ 2742 *dma_prog++ = OP_SYNC | BKTR_FM1; 2743 *dma_prog++ = 0; /* NULL WORD */ 2744 width = cols; 2745 for (i = 0; i < (rows/interlace); i++) { 2746 target = target_buffer; 2747 if ( notclipped(bktr, i, width)) { 2748 split(bktr, (volatile u_long **) &dma_prog, 2749 bktr->y2 - bktr->y, OP_WRITE, 2750 Bpp, (volatile u_char **) &target, cols); 2751 2752 } else { 2753 while(getline(bktr, i)) { 2754 if (bktr->y != bktr->y2 ) { 2755 split(bktr, (volatile u_long **) &dma_prog, 2756 bktr->y2 - bktr->y, OP_WRITE, 2757 Bpp, (volatile u_char **) &target, cols); 2758 } 2759 if (bktr->yclip != bktr->yclip2 ) { 2760 split(bktr,(volatile u_long **) &dma_prog, 2761 bktr->yclip2 - bktr->yclip, 2762 OP_SKIP, 2763 Bpp, (volatile u_char **) &target, cols); 2764 } 2765 } 2766 2767 } 2768 2769 target_buffer += interlace * pitch; 2770 2771 } 2772 2773 } /* end if */ 2774 2775 /* Grab the Even field */ 2776 /* Look for the VRO, end of Odd field, marker */ 2777 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; 2778 *dma_prog++ = 0; /* NULL WORD */ 2779 2780 /* store the VBI data */ 2781 /* look for sync with packed data */ 2782 *dma_prog++ = OP_SYNC | BKTR_FM1; 2783 *dma_prog++ = 0; 2784 for(i = 0; i < vbilines; i++) { 2785 *dma_prog++ = OP_WRITE | OP_SOL | OP_EOL | vbisamples; 2786 *dma_prog++ = (u_long) vtophys((caddr_t)bktr->vbidata + 2787 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE)); 2788 } 2789 2790 /* store the video image */ 2791 if (i_flag == 1) /*Even Only*/ 2792 target_buffer = buffer; 2793 if (i_flag == 3) /*interlaced*/ 2794 target_buffer = buffer+pitch; 2795 2796 2797 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) { 2798 /* look for sync with packed data */ 2799 *dma_prog++ = OP_SYNC | BKTR_FM1; 2800 *dma_prog++ = 0; /* NULL WORD */ 2801 width = cols; 2802 for (i = 0; i < (rows/interlace); i++) { 2803 target = target_buffer; 2804 if ( notclipped(bktr, i, width)) { 2805 split(bktr, (volatile u_long **) &dma_prog, 2806 bktr->y2 - bktr->y, OP_WRITE, 2807 Bpp, (volatile u_char **) &target, cols); 2808 } else { 2809 while(getline(bktr, i)) { 2810 if (bktr->y != bktr->y2 ) { 2811 split(bktr, (volatile u_long **) &dma_prog, 2812 bktr->y2 - bktr->y, OP_WRITE, 2813 Bpp, (volatile u_char **) &target, 2814 cols); 2815 } 2816 if (bktr->yclip != bktr->yclip2 ) { 2817 split(bktr, (volatile u_long **) &dma_prog, 2818 bktr->yclip2 - bktr->yclip, OP_SKIP, 2819 Bpp, (volatile u_char **) &target, cols); 2820 } 2821 2822 } 2823 2824 } 2825 2826 target_buffer += interlace * pitch; 2827 2828 } 2829 } 2830 2831 /* Look for end of 'Even Field' */ 2832 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; 2833 *dma_prog++ = 0; /* NULL WORD */ 2834 2835 *dma_prog++ = OP_JUMP ; 2836 *dma_prog++ = (u_long ) vtophys(loop_point) ; 2837 *dma_prog++ = 0; /* NULL WORD */ 2838 2839} 2840 2841 2842 2843 2844static void 2845rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace ) 2846{ 2847 int i; 2848 volatile u_long target_buffer, buffer, target,width; 2849 volatile u_long pitch; 2850 volatile u_long *dma_prog; 2851 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 2852 u_int Bpp = pf_int->public.Bpp; 2853 2854 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 2855 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0); 2856 OUTB(bktr, BKTR_VBI_PACK_DEL, 0); 2857 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 2858 2859 OUTB(bktr, BKTR_OFORM, 0x00); 2860 2861 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */ 2862 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40); 2863 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */ 2864 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80); 2865 2866 /* disable gamma correction removal */ 2867 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA); 2868 2869 if (cols > 385 ) { 2870 OUTB(bktr, BKTR_E_VTC, 0); 2871 OUTB(bktr, BKTR_O_VTC, 0); 2872 } else { 2873 OUTB(bktr, BKTR_E_VTC, 1); 2874 OUTB(bktr, BKTR_O_VTC, 1); 2875 } 2876 bktr->capcontrol = 3 << 2 | 3; 2877 2878 dma_prog = (u_long *) bktr->dma_prog; 2879 2880 /* Construct Write */ 2881 2882 if (bktr->video.addr) { 2883 target_buffer = (u_long) bktr->video.addr; 2884 pitch = bktr->video.width; 2885 } 2886 else { 2887 target_buffer = (u_long) vtophys(bktr->bigbuf); 2888 pitch = cols*Bpp; 2889 } 2890 2891 buffer = target_buffer; 2892 2893 /* contruct sync : for video packet format */ 2894 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; 2895 2896 /* sync, mode indicator packed data */ 2897 *dma_prog++ = 0; /* NULL WORD */ 2898 width = cols; 2899 for (i = 0; i < (rows/interlace); i++) { 2900 target = target_buffer; 2901 if ( notclipped(bktr, i, width)) { 2902 split(bktr, (volatile u_long **) &dma_prog, 2903 bktr->y2 - bktr->y, OP_WRITE, 2904 Bpp, (volatile u_char **) &target, cols); 2905 2906 } else { 2907 while(getline(bktr, i)) { 2908 if (bktr->y != bktr->y2 ) { 2909 split(bktr, (volatile u_long **) &dma_prog, 2910 bktr->y2 - bktr->y, OP_WRITE, 2911 Bpp, (volatile u_char **) &target, cols); 2912 } 2913 if (bktr->yclip != bktr->yclip2 ) { 2914 split(bktr,(volatile u_long **) &dma_prog, 2915 bktr->yclip2 - bktr->yclip, 2916 OP_SKIP, 2917 Bpp, (volatile u_char **) &target, cols); 2918 } 2919 } 2920 2921 } 2922 2923 target_buffer += interlace * pitch; 2924 2925 } 2926 2927 switch (i_flag) { 2928 case 1: 2929 /* sync vre */ 2930 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO; 2931 *dma_prog++ = 0; /* NULL WORD */ 2932 2933 *dma_prog++ = OP_JUMP; 2934 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2935 return; 2936 2937 case 2: 2938 /* sync vro */ 2939 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE; 2940 *dma_prog++ = 0; /* NULL WORD */ 2941 2942 *dma_prog++ = OP_JUMP; 2943 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 2944 return; 2945 2946 case 3: 2947 /* sync vro */ 2948 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO; 2949 *dma_prog++ = 0; /* NULL WORD */ 2950 *dma_prog++ = OP_JUMP; ; 2951 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 2952 break; 2953 } 2954 2955 if (interlace == 2) { 2956 2957 target_buffer = buffer + pitch; 2958 2959 dma_prog = (u_long *) bktr->odd_dma_prog; 2960 2961 /* sync vre IRQ bit */ 2962 *dma_prog++ = OP_SYNC | BKTR_RESYNC | BKTR_FM1; 2963 *dma_prog++ = 0; /* NULL WORD */ 2964 width = cols; 2965 for (i = 0; i < (rows/interlace); i++) { 2966 target = target_buffer; 2967 if ( notclipped(bktr, i, width)) { 2968 split(bktr, (volatile u_long **) &dma_prog, 2969 bktr->y2 - bktr->y, OP_WRITE, 2970 Bpp, (volatile u_char **) &target, cols); 2971 } else { 2972 while(getline(bktr, i)) { 2973 if (bktr->y != bktr->y2 ) { 2974 split(bktr, (volatile u_long **) &dma_prog, 2975 bktr->y2 - bktr->y, OP_WRITE, 2976 Bpp, (volatile u_char **) &target, 2977 cols); 2978 } 2979 if (bktr->yclip != bktr->yclip2 ) { 2980 split(bktr, (volatile u_long **) &dma_prog, 2981 bktr->yclip2 - bktr->yclip, OP_SKIP, 2982 Bpp, (volatile u_char **) &target, cols); 2983 } 2984 2985 } 2986 2987 } 2988 2989 target_buffer += interlace * pitch; 2990 2991 } 2992 } 2993 2994 /* sync vre IRQ bit */ 2995 *dma_prog++ = OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE; 2996 *dma_prog++ = 0; /* NULL WORD */ 2997 *dma_prog++ = OP_JUMP ; 2998 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; 2999 *dma_prog++ = 0; /* NULL WORD */ 3000} 3001 3002 3003/* 3004 * 3005 */ 3006static void 3007yuvpack_prog( bktr_ptr_t bktr, char i_flag, 3008 int cols, int rows, int interlace ) 3009{ 3010 int i; 3011 volatile unsigned int inst; 3012 volatile unsigned int inst3; 3013 volatile u_long target_buffer, buffer; 3014 volatile u_long *dma_prog; 3015 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3016 int b; 3017 3018 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 3019 3020 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */ 3021 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC); 3022 3023 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA); 3024 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 3025 3026 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3; 3027 bktr->capcontrol = 3 << 2 | 3; 3028 3029 dma_prog = (u_long *) bktr->dma_prog; 3030 3031 /* Construct Write */ 3032 3033 /* write , sol, eol */ 3034 inst = OP_WRITE | OP_SOL | (cols); 3035 /* write , sol, eol */ 3036 inst3 = OP_WRITE | OP_EOL | (cols); 3037 3038 if (bktr->video.addr) 3039 target_buffer = (u_long) bktr->video.addr; 3040 else 3041 target_buffer = (u_long) vtophys(bktr->bigbuf); 3042 3043 buffer = target_buffer; 3044 3045 /* contruct sync : for video packet format */ 3046 /* sync, mode indicator packed data */ 3047 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1; 3048 *dma_prog++ = 0; /* NULL WORD */ 3049 3050 b = cols; 3051 3052 for (i = 0; i < (rows/interlace); i++) { 3053 *dma_prog++ = inst; 3054 *dma_prog++ = target_buffer; 3055 *dma_prog++ = inst3; 3056 *dma_prog++ = target_buffer + b; 3057 target_buffer += interlace*(cols * 2); 3058 } 3059 3060 switch (i_flag) { 3061 case 1: 3062 /* sync vre */ 3063 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; 3064 *dma_prog++ = 0; /* NULL WORD */ 3065 3066 *dma_prog++ = OP_JUMP; 3067 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3068 return; 3069 3070 case 2: 3071 /* sync vro */ 3072 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; 3073 *dma_prog++ = 0; /* NULL WORD */ 3074 *dma_prog++ = OP_JUMP; 3075 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3076 return; 3077 3078 case 3: 3079 /* sync vro */ 3080 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; 3081 *dma_prog++ = 0; /* NULL WORD */ 3082 *dma_prog++ = OP_JUMP ; 3083 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 3084 break; 3085 } 3086 3087 if (interlace == 2) { 3088 3089 target_buffer = (u_long) buffer + cols*2; 3090 3091 dma_prog = (u_long * ) bktr->odd_dma_prog; 3092 3093 /* sync vre */ 3094 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1; 3095 *dma_prog++ = 0; /* NULL WORD */ 3096 3097 for (i = 0; i < (rows/interlace) ; i++) { 3098 *dma_prog++ = inst; 3099 *dma_prog++ = target_buffer; 3100 *dma_prog++ = inst3; 3101 *dma_prog++ = target_buffer + b; 3102 target_buffer += interlace * ( cols*2); 3103 } 3104 } 3105 3106 /* sync vro IRQ bit */ 3107 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; 3108 *dma_prog++ = 0; /* NULL WORD */ 3109 *dma_prog++ = OP_JUMP ; 3110 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3111 3112 *dma_prog++ = OP_JUMP; 3113 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3114 *dma_prog++ = 0; /* NULL WORD */ 3115} 3116 3117 3118/* 3119 * 3120 */ 3121static void 3122yuv422_prog( bktr_ptr_t bktr, char i_flag, 3123 int cols, int rows, int interlace ){ 3124 3125 int i; 3126 volatile unsigned int inst; 3127 volatile u_long target_buffer, t1, buffer; 3128 volatile u_long *dma_prog; 3129 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3130 3131 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 3132 3133 dma_prog = (u_long *) bktr->dma_prog; 3134 3135 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 3136 3137 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 3138 OUTB(bktr, BKTR_OFORM, 0x00); 3139 3140 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */ 3141 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC); 3142 3143 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */ 3144 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC); 3145 3146 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */ 3147 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80); 3148 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ~0x40); /* set chroma comb */ 3149 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ~0x40); 3150 3151 /* disable gamma correction removal */ 3152 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA); 3153 3154 /* Construct Write */ 3155 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 3156 if (bktr->video.addr) 3157 target_buffer = (u_long) bktr->video.addr; 3158 else 3159 target_buffer = (u_long) vtophys(bktr->bigbuf); 3160 3161 buffer = target_buffer; 3162 3163 t1 = buffer; 3164 3165 /* contruct sync : for video packet format */ 3166 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ 3167 *dma_prog++ = 0; /* NULL WORD */ 3168 3169 for (i = 0; i < (rows/interlace ) ; i++) { 3170 *dma_prog++ = inst; 3171 *dma_prog++ = cols/2 | cols/2 << 16; 3172 *dma_prog++ = target_buffer; 3173 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3174 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace; 3175 target_buffer += interlace*cols; 3176 } 3177 3178 switch (i_flag) { 3179 case 1: 3180 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ 3181 *dma_prog++ = 0; /* NULL WORD */ 3182 3183 *dma_prog++ = OP_JUMP ; 3184 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3185 return; 3186 3187 case 2: 3188 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/ 3189 *dma_prog++ = 0; /* NULL WORD */ 3190 3191 *dma_prog++ = OP_JUMP; 3192 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3193 return; 3194 3195 case 3: 3196 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; 3197 *dma_prog++ = 0; /* NULL WORD */ 3198 3199 *dma_prog++ = OP_JUMP ; 3200 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 3201 break; 3202 } 3203 3204 if (interlace == 2) { 3205 3206 dma_prog = (u_long * ) bktr->odd_dma_prog; 3207 3208 target_buffer = (u_long) buffer + cols; 3209 t1 = buffer + cols/2; 3210 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; 3211 *dma_prog++ = 0; /* NULL WORD */ 3212 3213 for (i = 0; i < (rows/interlace ) ; i++) { 3214 *dma_prog++ = inst; 3215 *dma_prog++ = cols/2 | cols/2 << 16; 3216 *dma_prog++ = target_buffer; 3217 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3218 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace; 3219 target_buffer += interlace*cols; 3220 } 3221 } 3222 3223 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; 3224 *dma_prog++ = 0; /* NULL WORD */ 3225 *dma_prog++ = OP_JUMP ; 3226 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ; 3227 *dma_prog++ = 0; /* NULL WORD */ 3228} 3229 3230 3231/* 3232 * 3233 */ 3234static void 3235yuv12_prog( bktr_ptr_t bktr, char i_flag, 3236 int cols, int rows, int interlace ){ 3237 3238 int i; 3239 volatile unsigned int inst; 3240 volatile unsigned int inst1; 3241 volatile u_long target_buffer, t1, buffer; 3242 volatile u_long *dma_prog; 3243 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3244 3245 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt); 3246 3247 dma_prog = (u_long *) bktr->dma_prog; 3248 3249 bktr->capcontrol = 1 << 6 | 1 << 4 | 3; 3250 3251 OUTB(bktr, BKTR_ADC, SYNC_LEVEL); 3252 OUTB(bktr, BKTR_OFORM, 0x0); 3253 3254 /* Construct Write */ 3255 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols); 3256 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols); 3257 if (bktr->video.addr) 3258 target_buffer = (u_long) bktr->video.addr; 3259 else 3260 target_buffer = (u_long) vtophys(bktr->bigbuf); 3261 3262 buffer = target_buffer; 3263 t1 = buffer; 3264 3265 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/ 3266 *dma_prog++ = 0; /* NULL WORD */ 3267 3268 for (i = 0; i < (rows/interlace )/2 ; i++) { 3269 *dma_prog++ = inst; 3270 *dma_prog++ = cols/2 | (cols/2 << 16); 3271 *dma_prog++ = target_buffer; 3272 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3273 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace; 3274 target_buffer += interlace*cols; 3275 *dma_prog++ = inst1; 3276 *dma_prog++ = cols/2 | (cols/2 << 16); 3277 *dma_prog++ = target_buffer; 3278 target_buffer += interlace*cols; 3279 3280 } 3281 3282 switch (i_flag) { 3283 case 1: 3284 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/ 3285 *dma_prog++ = 0; /* NULL WORD */ 3286 3287 *dma_prog++ = OP_JUMP; 3288 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3289 return; 3290 3291 case 2: 3292 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/ 3293 *dma_prog++ = 0; /* NULL WORD */ 3294 3295 *dma_prog++ = OP_JUMP; 3296 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3297 return; 3298 3299 case 3: 3300 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO; 3301 *dma_prog++ = 0; /* NULL WORD */ 3302 *dma_prog++ = OP_JUMP ; 3303 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog); 3304 break; 3305 } 3306 3307 if (interlace == 2) { 3308 3309 dma_prog = (u_long * ) bktr->odd_dma_prog; 3310 3311 target_buffer = (u_long) buffer + cols; 3312 t1 = buffer + cols/2; 3313 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; 3314 *dma_prog++ = 0; /* NULL WORD */ 3315 3316 for (i = 0; i < ((rows/interlace )/2 ) ; i++) { 3317 *dma_prog++ = inst; 3318 *dma_prog++ = cols/2 | (cols/2 << 16); 3319 *dma_prog++ = target_buffer; 3320 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace; 3321 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace; 3322 target_buffer += interlace*cols; 3323 *dma_prog++ = inst1; 3324 *dma_prog++ = cols/2 | (cols/2 << 16); 3325 *dma_prog++ = target_buffer; 3326 target_buffer += interlace*cols; 3327 3328 } 3329 3330 3331 } 3332 3333 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE; 3334 *dma_prog++ = 0; /* NULL WORD */ 3335 *dma_prog++ = OP_JUMP; 3336 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog); 3337 *dma_prog++ = 0; /* NULL WORD */ 3338} 3339 3340 3341 3342/* 3343 * 3344 */ 3345static void 3346build_dma_prog( bktr_ptr_t bktr, char i_flag ) 3347{ 3348 int rows, cols, interlace; 3349 int tmp_int; 3350 unsigned int temp; 3351 struct format_params *fp; 3352 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ]; 3353 3354 3355 fp = &format_params[bktr->format_params]; 3356 3357 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 3358 3359 /* disable FIFO & RISC, leave other bits alone */ 3360 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED); 3361 3362 /* set video parameters */ 3363 if (bktr->capture_area_enabled) 3364 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096 3365 / fp->scaled_htotal / bktr->cols) - 4096; 3366 else 3367 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096 3368 / fp->scaled_htotal / bktr->cols) - 4096; 3369 3370 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */ 3371 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff); 3372 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff); 3373 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff); 3374 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff); 3375 3376 /* horizontal active */ 3377 temp = bktr->cols; 3378 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */ 3379 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff); 3380 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff); 3381 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3); 3382 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3); 3383 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3)); 3384 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3)); 3385 3386 /* horizontal delay */ 3387 if (bktr->capture_area_enabled) 3388 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal) 3389 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive); 3390 else 3391 temp = (fp->hdelay * bktr->cols) / fp->hactive; 3392 3393 temp = temp & 0x3fe; 3394 3395 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */ 3396 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff); 3397 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff); 3398 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc); 3399 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc); 3400 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc)); 3401 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc)); 3402 3403 /* vertical scale */ 3404 3405 if (bktr->capture_area_enabled) { 3406 if (bktr->flags & METEOR_ONLY_ODD_FIELDS || 3407 bktr->flags & METEOR_ONLY_EVEN_FIELDS) 3408 tmp_int = 65536 - 3409 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512); 3410 else { 3411 tmp_int = 65536 - 3412 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512); 3413 } 3414 } else { 3415 if (bktr->flags & METEOR_ONLY_ODD_FIELDS || 3416 bktr->flags & METEOR_ONLY_EVEN_FIELDS) 3417 tmp_int = 65536 - 3418 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512); 3419 else { 3420 tmp_int = 65536 - 3421 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512); 3422 } 3423 } 3424 3425 tmp_int &= 0x1fff; 3426 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */ 3427 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff); 3428 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff); 3429 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f); 3430 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f); 3431 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f)); 3432 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f)); 3433 3434 3435 /* vertical active */ 3436 if (bktr->capture_area_enabled) 3437 temp = bktr->capture_area_y_size; 3438 else 3439 temp = fp->vactive; 3440 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */ 3441 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30); 3442 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30)); 3443 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff); 3444 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30); 3445 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30)); 3446 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff); 3447 3448 /* vertical delay */ 3449 if (bktr->capture_area_enabled) 3450 temp = fp->vdelay + (bktr->capture_area_y_offset); 3451 else 3452 temp = fp->vdelay; 3453 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */ 3454 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0); 3455 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0)); 3456 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff); 3457 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0); 3458 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0)); 3459 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff); 3460 3461 /* end of video params */ 3462 3463 if ((bktr->xtal_pll_mode == BT848_USE_PLL) 3464 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) { 3465 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */ 3466 } else { 3467 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */ 3468 } 3469 3470 /* capture control */ 3471 switch (i_flag) { 3472 case 1: 3473 bktr->bktr_cap_ctl = 3474 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN); 3475 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20); 3476 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20); 3477 interlace = 1; 3478 break; 3479 case 2: 3480 bktr->bktr_cap_ctl = 3481 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD); 3482 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20); 3483 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20); 3484 interlace = 1; 3485 break; 3486 default: 3487 bktr->bktr_cap_ctl = 3488 (BT848_CAP_CTL_DITH_FRAME | 3489 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD); 3490 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20); 3491 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20); 3492 interlace = 2; 3493 break; 3494 } 3495 3496 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog)); 3497 3498 rows = bktr->rows; 3499 cols = bktr->cols; 3500 3501 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */ 3502 3503 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */ 3504 /* user, then use the rgb_vbi RISC program. */ 3505 /* Otherwise, use the normal rgb RISC program */ 3506 if (pf_int->public.type == METEOR_PIXTYPE_RGB) { 3507 if ( (bktr->vbiflags & VBI_OPEN) 3508 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI) 3509 ||(bktr->format_params == BT848_IFORM_F_SECAM) 3510 ){ 3511 bktr->bktr_cap_ctl |= 3512 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD; 3513 bktr->vbiflags |= VBI_CAPTURE; 3514 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace); 3515 return; 3516 } else { 3517 rgb_prog(bktr, i_flag, cols, rows, interlace); 3518 return; 3519 } 3520 } 3521 3522 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) { 3523 yuv422_prog(bktr, i_flag, cols, rows, interlace); 3524 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3525 | pixfmt_swap_flags( bktr->pixfmt )); 3526 return; 3527 } 3528 3529 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) { 3530 yuvpack_prog(bktr, i_flag, cols, rows, interlace); 3531 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3532 | pixfmt_swap_flags( bktr->pixfmt )); 3533 return; 3534 } 3535 3536 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) { 3537 yuv12_prog(bktr, i_flag, cols, rows, interlace); 3538 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0) 3539 | pixfmt_swap_flags( bktr->pixfmt )); 3540 return; 3541 } 3542 return; 3543} 3544 3545 3546/****************************************************************************** 3547 * video & video capture specific routines: 3548 */ 3549 3550 3551/* 3552 * 3553 */ 3554static void 3555start_capture( bktr_ptr_t bktr, unsigned type ) 3556{ 3557 u_char i_flag; 3558 struct format_params *fp; 3559 3560 fp = &format_params[bktr->format_params]; 3561 3562 /* If requested, clear out capture buf first */ 3563 if (bktr->clr_on_start && (bktr->video.addr == 0)) { 3564 bzero((caddr_t)bktr->bigbuf, 3565 (size_t)bktr->rows * bktr->cols * bktr->frames * 3566 pixfmt_table[ bktr->pixfmt ].public.Bpp); 3567 } 3568 3569 OUTB(bktr, BKTR_DSTATUS, 0); 3570 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT)); 3571 3572 bktr->flags |= type; 3573 bktr->flags &= ~METEOR_WANT_MASK; 3574 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3575 case METEOR_ONLY_EVEN_FIELDS: 3576 bktr->flags |= METEOR_WANT_EVEN; 3577 i_flag = 1; 3578 break; 3579 case METEOR_ONLY_ODD_FIELDS: 3580 bktr->flags |= METEOR_WANT_ODD; 3581 i_flag = 2; 3582 break; 3583 default: 3584 bktr->flags |= METEOR_WANT_MASK; 3585 i_flag = 3; 3586 break; 3587 } 3588 3589 /* TDEC is only valid for continuous captures */ 3590 if ( type == METEOR_SINGLE ) { 3591 u_short fps_save = bktr->fps; 3592 3593 set_fps(bktr, fp->frame_rate); 3594 bktr->fps = fps_save; 3595 } 3596 else 3597 set_fps(bktr, bktr->fps); 3598 3599 if (bktr->dma_prog_loaded == FALSE) { 3600 build_dma_prog(bktr, i_flag); 3601 bktr->dma_prog_loaded = TRUE; 3602 } 3603 3604 3605 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog)); 3606 3607} 3608 3609 3610/* 3611 * 3612 */ 3613static void 3614set_fps( bktr_ptr_t bktr, u_short fps ) 3615{ 3616 struct format_params *fp; 3617 int i_flag; 3618 3619 fp = &format_params[bktr->format_params]; 3620 3621 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) { 3622 case METEOR_ONLY_EVEN_FIELDS: 3623 bktr->flags |= METEOR_WANT_EVEN; 3624 i_flag = 1; 3625 break; 3626 case METEOR_ONLY_ODD_FIELDS: 3627 bktr->flags |= METEOR_WANT_ODD; 3628 i_flag = 1; 3629 break; 3630 default: 3631 bktr->flags |= METEOR_WANT_MASK; 3632 i_flag = 2; 3633 break; 3634 } 3635 3636 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 3637 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED); 3638 3639 bktr->fps = fps; 3640 OUTB(bktr, BKTR_TDEC, 0); 3641 3642 if (fps < fp->frame_rate) 3643 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f); 3644 else 3645 OUTB(bktr, BKTR_TDEC, 0); 3646 return; 3647 3648} 3649 3650 3651 3652 3653 3654/* 3655 * Given a pixfmt index, compute the bt848 swap_flags necessary to 3656 * achieve the specified swapping. 3657 * Note that without bt swapping, 2Bpp and 3Bpp modes are written 3658 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6 3659 * and read R->L). 3660 * Note also that for 3Bpp, we may additionally need to do some creative 3661 * SKIPing to align the FIFO bytelines with the target buffer (see split()). 3662 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR 3663 * as one would expect. 3664 */ 3665 3666static u_int pixfmt_swap_flags( int pixfmt ) 3667{ 3668 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public; 3669 u_int swapf = 0; 3670 3671 switch ( pf->Bpp ) { 3672 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP ); 3673 break; 3674 3675 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */ 3676 break; 3677 3678 case 4 : if ( pf->swap_bytes ) 3679 swapf = pf->swap_shorts ? 0 : WSWAP; 3680 else 3681 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP); 3682 break; 3683 } 3684 return swapf; 3685} 3686 3687 3688 3689/* 3690 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into 3691 * our pixfmt_table indices. 3692 */ 3693 3694static int oformat_meteor_to_bt( u_long format ) 3695{ 3696 int i; 3697 struct meteor_pixfmt *pf1, *pf2; 3698 3699 /* Find format in compatibility table */ 3700 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ ) 3701 if ( meteor_pixfmt_table[i].meteor_format == format ) 3702 break; 3703 3704 if ( i >= METEOR_PIXFMT_TABLE_SIZE ) 3705 return -1; 3706 pf1 = &meteor_pixfmt_table[i].public; 3707 3708 /* Match it with an entry in master pixel format table */ 3709 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) { 3710 pf2 = &pixfmt_table[i].public; 3711 3712 if (( pf1->type == pf2->type ) && 3713 ( pf1->Bpp == pf2->Bpp ) && 3714 !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) && 3715 ( pf1->swap_bytes == pf2->swap_bytes ) && 3716 ( pf1->swap_shorts == pf2->swap_shorts )) 3717 break; 3718 } 3719 if ( i >= PIXFMT_TABLE_SIZE ) 3720 return -1; 3721 3722 return i; 3723} 3724 3725/****************************************************************************** 3726 * i2c primitives: 3727 */ 3728 3729/* */ 3730#define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */ 3731#define I2CBITTIME_878 (1 << 7) 3732#define I2C_READ 0x01 3733#define I2C_COMMAND (I2CBITTIME | \ 3734 BT848_DATA_CTL_I2CSCL | \ 3735 BT848_DATA_CTL_I2CSDA) 3736 3737#define I2C_COMMAND_878 (I2CBITTIME_878 | \ 3738 BT848_DATA_CTL_I2CSCL | \ 3739 BT848_DATA_CTL_I2CSDA) 3740 3741/* Select between old i2c code and new iicbus / smbus code */
|