?? meteor.c
字號:
/* 21 */ 0x80, /* 7:0 [7:0] Pixel number per line on output *//* 22 */ 0x80, /* 7:0 [7:0] Pixel number per line on input *//* 23 */ 0x03, /* 7:0 [7:0] Horizontal start position of scaling win*//* 24 */ 0x8a, /* 7:5 Horizontal decimation filter 4 [8] Horizontal start position of scaling win 3:2 [9:8] Pixel number per line on input 1:0 [9:8] Pixel number per line on output *//* 25 */ 0xf0, /* 7:0 [7:0] Line number per output field *//* 26 */ 0xf0, /* 7:0 [7:0] Line number per input field *//* 27 */ 0x0f, /* 7:0 [7:0] Vertical start of scaling window *//* 28 */ 0x80, /* 7 Adaptive filter switch 6:5 Vertical luminance data processing 4 [8] Vertical start of scaling window 3:2 [9:8] Line number per input field 1:0 [9:8] Line number per output field *//* 29 */ 0x16, /* 7:0 [7:0] Vertical bypass start *//* 2a */ 0x00, /* 7:0 [7:0] Vertical bypass count *//* 2b */ 0x00, /* 4 [8] Vertical bypass start 2 [8] Vertical bypass count 0 Polarity, internally detected odd even flag *//* 2c */ 0x80, /* 7:0 Set lower limit V for colour-keying *//* 2d */ 0x7f, /* 7:0 Set upper limit V for colour-keying *//* 2e */ 0x80, /* 7:0 Set lower limit U for colour-keying *//* 2f */ 0x7f, /* 7:0 Set upper limit U for colour-keying *//* 30 */ 0xbf /* 7 VRAM bus output format 6 Adaptive geometrical filter 5 Luminance limiting value 4 Monochrome and two's complement output data sel 3 Line quailifier flag 2 Pixel qualifier flag 1 Transparent data transfer 0 Extended formats enable bit */};static u_char bt254_default[NUM_BT254_REGS] = { 0x00, /* 24 bpp */ 0xa0, 0xa0, 0xa0, 0x50, 0x50, 0x50,} ;/* * i2c_write: * Returns 0 Succesful completion. * Returns 1 If transfer aborted or timeout occured. * */static i2c_print_err = 1;static inti2c_write(meteor_reg_t * mtr, u_char slave, u_char rw, u_char reg, u_char data){register unsigned long wait_counter = 0x0001ffff;register mreg_t * iic_write_loc = &mtr->base->i2c_write;register int err = 0; /* Write the data the the i2c write register */ *iic_write_loc = SAA7116_IIC_NEW_CYCLE | (((u_long)slave|(u_long)rw) << 16) | ((u_long)reg << 8) | (u_long)data; /* Wait until the i2c cycle is compeleted */ while((*iic_write_loc & SAA7116_IIC_NEW_CYCLE)) { if(!wait_counter) break; wait_counter--; } /* 1ffff should be enough delay time for the i2c cycle to complete */ if(!wait_counter) { if(i2c_print_err) printf("meteor%d: %d i2c %s transfer timeout 0x%x", METEOR_NUM(mtr), slave, rw ? "read" : "write", *iic_write_loc); err=1; } /* Check for error on direct write, clear if any */ if(mtr->base->i2c_read & SAA7116_IIC_DIRECT_TRANSFER_ABORTED){ mtr->base->i2c_read |= SAA7116_IIC_DIRECT_TRANSFER_ABORTED; if(i2c_print_err) printf("meteor%d: 0x%x i2c %s tranfer aborted", METEOR_NUM(mtr), slave, rw ? "read" : "write" ); err= 1; } if(err) { if(i2c_print_err) printf(" - reg=0x%x, value=0x%x.\n", reg, data); } return err;}#undef i2c_printstatic const char *met_probe (pcici_t tag, pcidi_t type){ switch (type) { case SAA7116_PHILIPS_ID: /* meteor */ return("Philips SAA 7116"); }; return ((char *)0);} /* interrupt handling routine complete meteor_read() if using interrupts */static voidmeteor_intr(void *arg){ meteor_reg_t *mtr = (meteor_reg_t *) arg; mreg_t *cap = &mtr->base->cap_cntl, *base = &mtr->base->dma1e, *stat = &mtr->base->irq_stat; u_long status = *stat, cap_err = *cap & 0x00000f00,#ifdef METEOR_CHECK_PCI_BUS pci_err = pci_conf_read(mtr->tag, PCI_COMMAND_STATUS_REG),#endif next_base = (u_long)(vtophys(mtr->bigbuf)); /* * Disable future interrupts if a capture mode is not selected. * This can happen when we are in the process of closing or * changing capture modes, otherwise it shouldn't happen. */ if(!(mtr->flags & METEOR_CAP_MASK)) { *cap &= 0x8ff0; /* disable future interrupts */ }#ifdef METEOR_CHECK_PCI_BUS /* * Check for pci bus errors. */#define METEOR_MASTER_ABORT 0x20000000#define METEOR_TARGET_ABORT 0x10000000 if(pci_err & METEOR_MASTER_ABORT) { printf("meteor%d: intr: pci bus master dma abort: 0x%x 0x%x.\n", METEOR_NUM(mtr), *base, *(base+3)); pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err); } if(pci_err & METEOR_TARGET_ABORT) { printf("meteor%d: intr: pci bus target dma abort: 0x%x 0x%x.\n", METEOR_NUM(mtr), *base, *(base+3)); pci_conf_write(mtr->tag, PCI_COMMAND_STATUS_REG, pci_err); }#endif /* * Check for errors. */ if (cap_err) { if (cap_err & 0x300) { if(mtr->fifo_errors % 50 == 0) { printf("meteor%d: capture error", METEOR_NUM(mtr)); printf(": %s FIFO overflow.\n", cap_err&0x0100? "even" : "odd"); } mtr->fifo_errors++ ; /* increment fifo capture errors cnt */ } if (cap_err & 0xc00) { if(mtr->dma_errors % 50 == 0) { printf("meteor%d: capture error", METEOR_NUM(mtr)); printf(": %s DMA address.\n", cap_err&0x0400? "even" : "odd"); } mtr->dma_errors++ ; /* increment DMA capture errors cnt */ } } *cap |= 0x0f30; /* clear error and field done */ /* * In synchronous capture mode we need to know what the address * offset for the next field/frame will be. next_base holds the * value for the even dma buffers (for odd, one must add stride). */ if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait && (mtr->current < mtr->frames)) { /* could be !=, but < is safer */ /* next_base is initialized to mtr->bigbuf */ next_base += mtr->frame_size * mtr->current; if(mtr->flags & METEOR_WANT_TS) next_base += sizeof(struct timeval) * mtr->current; } /* * Count the field and clear the field flag. * * In single mode capture, clear the continuous capture mode. * * In synchronous capture mode, if we have room for another field, * adjust DMA buffer pointers. * When we are above the hi water mark (hiwat), mtr->synch_wait will * be set and we will not bump the DMA buffer pointers. Thus, once * we reach the hi water mark, the driver acts like a continuous mode * capture on the mtr->current frame until we hit the low water * mark (lowat). The user had the option of stopping or halting * the capture if this is not the desired effect. */ if (status & 0x1) { /* even field */ mtr->even_fields_captured++; mtr->flags &= ~METEOR_WANT_EVEN; if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) { *base = next_base; /* XXX should add adjustments for YUV_422 & PLANAR */ } /* * If the user requested to be notified via signal, * let them know the field is complete. */ if(mtr->proc && (mtr->signal & METEOR_SIG_MODE_MASK)) psignal(mtr->proc, mtr->signal&(~METEOR_SIG_MODE_MASK)); } if (status & 0x2) { /* odd field */ mtr->odd_fields_captured++; mtr->flags &= ~METEOR_WANT_ODD; if((mtr->flags & METEOR_SYNCAP) && !mtr->synch_wait) { *(base+3) = next_base + *(base+6); /* XXX should add adjustments for YUV_422 & PLANAR */ } /* * If the user requested to be notified via signal, * let them know the field is complete. */ if(mtr->proc && (mtr->signal & METEOR_SIG_MODE_MASK)) psignal(mtr->proc, mtr->signal&(~METEOR_SIG_MODE_MASK)); } /* * If we have a complete frame. */ if(!(mtr->flags & METEOR_WANT_MASK)) { mtr->frames_captured++; /* * post the completion time. */ if(mtr->flags & METEOR_WANT_TS) { struct timeval *ts; if(mtr->alloc_pages * PAGE_SIZE <= (mtr->frame_size + sizeof(struct timeval))) { ts =(struct timeval *)mtr->bigbuf + mtr->frame_size; /* doesn't work in synch mode except for first frame */ /* XXX */ microtime(ts); } } /* * Wake up the user in single capture mode. */ if(mtr->flags & METEOR_SINGLE) wakeup((caddr_t)mtr); /* * If the user requested to be notified via signal, * let them know the frame is complete. */ if(mtr->proc && !(mtr->signal & METEOR_SIG_MODE_MASK)) psignal(mtr->proc, mtr->signal&(~METEOR_SIG_MODE_MASK)); /* * Reset the want flags if in continuous or * synchronous capture mode. */ if(mtr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) { switch(mtr->flags & METEOR_ONLY_FIELDS_MASK) { case METEOR_ONLY_ODD_FIELDS: mtr->flags |= METEOR_WANT_ODD; break; case METEOR_ONLY_EVEN_FIELDS: mtr->flags |= METEOR_WANT_EVEN; break; default: mtr->flags |= METEOR_WANT_MASK; break; } } /* * Special handling for synchronous capture mode. */ if(mtr->flags & METEOR_SYNCAP) { struct meteor_mem *mm = mtr->mem; /* * Mark the current frame as active. It is up to * the user to clear this, but we will clear it * for the user for the current frame being captured * if we are within the water marks (see below). */ mm->active |= 1 << (mtr->current - 1); /* * Since the user can muck with these values, we need * to check and see if they are sane. If they don't * pass the sanity check, disable the capture mode. * This is rather rude, but then so was the user. * * Do we really need all of this or should we just * eliminate the possiblity of allowing the * user to change hi and lo water marks while it * is running? XXX */ if(mm->num_active_bufs < 0 || mm->num_active_bufs > mtr->frames || mm->lowat < 1 || mm->lowat >= mtr->frames || mm->hiwat < 1 || mm->hiwat >= mtr->frames || mm->lowat > mm->hiwat ) { *cap &= 0x8ff0; mtr->flags &= ~(METEOR_SYNCAP|METEOR_WANT_MASK); } else { /* * Ok, they are sane, now we want to * check the water marks. */ if(mm->num_active_bufs <= mm->lowat) mtr->synch_wait = 0; if(mm->num_active_bufs >= mm->hiwat) mtr->synch_wait = 1; /* * Clear the active frame bit for this frame * and advance the counters if we are within * the banks of the water marks. */ if(!mtr->synch_wait) { mm->active &= ~(1 << mtr->current); mtr->current++; if(mtr->current > mtr->frames) mtr->current = 1; mm->num_active_bufs++; } } } } *stat |= 0x7; /* clear interrupt status */ return;}static voidset_fps(meteor_reg_t *mtr, u_short fps){ struct saa7116_regs *s7116 = mtr->base; unsigned status; unsigned maxfps, mask = 0x1, length = 0; SAA7196_WRITE(mtr, SAA7196_STDC, SAA7196_REG(mtr, SAA7196_STDC) | 0x02); SAA7196_READ(mtr); status = (s7116->i2c_read & 0xff000000L) >> 24; /* * Determine if there is an input signal. Depending on the * frequency we either have a max of 25 fps (50 hz) or 30 fps (60 hz). * If there is no input signal, then we need some defaults. If the * user neglected to specify any defaults, just set to the fps to max. */ if((status & 0x40) == 0) { /* Is there a signal ? */ if(status & 0x20) { maxfps = 30; /* 60 hz system */ } else { maxfps = 25; /* 50 hz system */ } } else { /* We have no signal, check defaults */#if METEOR_SYSTEM_DEFAULT == METEOR_PAL || METEOR_SYSTEM_DEFAULT == METEOR_SECAM maxfps = 25;#elif METEOR_SYSTEM_DEFAULT == METEOR_NTSC maxfps = 30;#else /* Don't really know what to do, just set max */ maxfps = 30; fps = 30;#endif } /* * A little sanity checking... */ if(fps < 1) fps = 1; if(fps > maxfps) fps = maxfps; /* * Compute the mask/length using the fps. */ if(fps == maxfps) { mask = 0x1; length = 0x0; } else if ((float)fps == maxfps/2.0) { mask = 0x1; length = 0x1; } else if (fps > maxfps/2) { float step, b; mask = (1<<maxfps) - 1; length = maxfps - 1; step = (float)(maxfps - 1)/(float)(maxfps - fps); for(b=step; b < maxfps; b += step) { mask &= ~(1<<((int)b)); /* mask out the bth frame */ } } else { /* fps < maxfps/2 */ float step, b; mask = 0x1; length = maxfps - 1; step = (float)(maxfps -1)/(float)(fps); for(b = step + 1; b < maxfps - 1; b += step) { mask |= (1<<((int)b)); /* mask in the bth frame */ } } /* * Set the fps. */ s7116->fme = s7116->fmo = mask; s7116->fml = (length << 16) | length;; mtr->fps = fps; return;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -