📄 zr36067.c
字号:
break; case BUZ_MODE_STILL_DECOMPRESS: reg = ZR36057_JMC_JPGExpMode; break; } reg |= ZR36057_JMC_JPG; if (zr->params.field_per_buff == 1) reg |= ZR36057_JMC_Fld_per_buff; btwrite(reg, ZR36057_JMC); /* vertical */ btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR); reg = (6 << ZR36057_VSP_VsyncSize) | (tvn->Ht << ZR36057_VSP_FrmTot); btwrite(reg, ZR36057_VSP); reg = ((zr->params.img_y + tvn->VStart) << ZR36057_FVAP_NAY) | (zr->params.img_height << ZR36057_FVAP_PAY); btwrite(reg, ZR36057_FVAP); /* horizontal */ btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) | (tvn-> Wt << ZR36057_HSP_LineTot); btwrite(reg, ZR36057_HSP); reg = ((zr->params.img_x + tvn->HStart + 4) << ZR36057_FHAP_NAX) | (zr->params.img_width << ZR36057_FHAP_PAX); btwrite(reg, ZR36057_FHAP); /* field process parameters */ if (zr->params.odd_even) reg = ZR36057_FPP_Odd_Even; else reg = 0; if (mode == BUZ_MODE_MOTION_DECOMPRESS && zr->card != LML33 && zr->card != BUZ) reg ^= ZR36057_FPP_Odd_Even; btwrite(reg, ZR36057_FPP); /* Set proper VCLK Polarity, else colors will be wrong during playback */ //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR); /* code base address */ reg = virt_to_bus(zr->stat_com); btwrite(reg, ZR36057_JCBA); /* FIFO threshold (FIFO is 160. double words) */ /* NOTE: decimal values here */ switch (mode) { case BUZ_MODE_STILL_COMPRESS: case BUZ_MODE_MOTION_COMPRESS: reg = 140; break; case BUZ_MODE_STILL_DECOMPRESS: case BUZ_MODE_MOTION_DECOMPRESS: reg = 20; break; default: reg = 80; break; } btwrite(reg, ZR36057_JCFT); zr36057_adjust_vfe(zr, mode);}#if (DEBUGLEVEL > 2)static void dump_guests(struct zoran *zr){ int i, guest[8]; for (i = 1; i < 8; i++) { // Don't read zr36060 here guest[i] = post_office_read(zr, i, 0); } printk(KERN_INFO "%s: Guests:", zr->name); for (i = 1; i < 8; i++) { printk(" 0x%02x", guest[i]); } printk("\n");}static unsigned long get_time(void){ struct timeval tv; do_gettimeofday(&tv); return (1000000 * tv.tv_sec + tv.tv_usec);}static void detect_guest_activity(struct zoran *zr){ int timeout, i, j, res, guest[8], guest0[8], change[8][3]; unsigned long t0, t1; dump_guests(zr); printk(KERN_INFO "%s: Detecting guests activity, please wait...\n", zr->name); for (i = 1; i < 8; i++) { // Don't read zr36060 here guest0[i] = guest[i] = post_office_read(zr, i, 0); } timeout = 0; j = 0; t0 = get_time(); while (timeout < 10000) { udelay(10); timeout++; for (i = 1; (i < 8) && (j < 8); i++) { res = post_office_read(zr, i, 0); if (res != guest[i]) { t1 = get_time(); change[j][0] = (t1 - t0); t0 = t1; change[j][1] = i; change[j][2] = res; j++; guest[i] = res; } } if (j >= 8) break; } printk(KERN_INFO "%s: Guests:", zr->name); for (i = 1; i < 8; i++) { printk(" 0x%02x", guest0[i]); } printk("\n"); if (j == 0) { printk(KERN_INFO "%s: No activity detected.\n", zr->name); return; } for (i = 0; i < j; i++) { printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", zr->name, change[i][0], change[i][1], change[i][2]); }}#endifstatic void print_interrupts(struct zoran *zr){ int res, noerr; noerr = 0; printk(KERN_INFO "%s: interrupts received:", zr->name); if ((res = zr->field_counter) < -1 || res > 1) { printk(" FD:%d", res); } if ((res = zr->intr_counter_GIRQ1) != 0) { printk(" GIRQ1:%d", res); noerr++; } if ((res = zr->intr_counter_GIRQ0) != 0) { printk(" GIRQ0:%d", res); noerr++; } if ((res = zr->intr_counter_CodRepIRQ) != 0) { printk(" CodRepIRQ:%d", res); noerr++; } if ((res = zr->intr_counter_JPEGRepIRQ) != 0) { printk(" JPEGRepIRQ:%d", res); noerr++; } if (zr->JPEG_max_missed) { printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed, zr->JPEG_min_missed); } if (zr->END_event_missed) { printk(" ENDs missed: %d", zr->END_event_missed); } //if (zr->jpg_queued_num) { printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail, zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head); //} if (!noerr) { printk(": no interrupts detected."); } printk("\n");}static void clear_interrupt_counters(struct zoran *zr){ zr->intr_counter_GIRQ1 = 0; zr->intr_counter_GIRQ0 = 0; zr->intr_counter_CodRepIRQ = 0; zr->intr_counter_JPEGRepIRQ = 0; zr->field_counter = 0; zr->IRQ1_in = 0; zr->IRQ1_out = 0; zr->JPEG_in = 0; zr->JPEG_out = 0; zr->JPEG_0 = 0; zr->JPEG_1 = 0; zr->END_event_missed = 0; zr->JPEG_missed = 0; zr->JPEG_max_missed = 0; zr->JPEG_min_missed = 0x7fffffff;}static u32 count_reset_interrupt(struct zoran *zr){ u32 isr; if ((isr = btread(ZR36057_ISR) & 0x78000000)) { if (isr & ZR36057_ISR_GIRQ1) { btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR); zr->intr_counter_GIRQ1++; } if (isr & ZR36057_ISR_GIRQ0) { btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR); zr->intr_counter_GIRQ0++; } if (isr & ZR36057_ISR_CodRepIRQ) { btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR); zr->intr_counter_CodRepIRQ++; } if (isr & ZR36057_ISR_JPEGRepIRQ) { btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR); zr->intr_counter_JPEGRepIRQ++; } } return isr;}static void jpeg_start(struct zoran *zr){ int reg; zr->frame_num = 0; btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC); // /P_Reset btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // \CFlush btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC); // /CodTrnsEn btwrite(IRQ_MASK, ZR36057_ISR); // Clear IRQs btwrite(IRQ_MASK | ZR36057_ICR_IntPinEn, ZR36057_ICR); // Enable IRQs set_frame(zr, 0); // \FRAME /* JPEG codec guest ID */ reg = (1 << ZR36057_JCGI_JPEGuestID) | (0 << ZR36057_JCGI_JPEGuestReg); btwrite(reg, ZR36057_JCGI); btor(ZR36057_JPC_Active, ZR36057_JPC); // /Active btor(ZR36057_JMC_Go_en, ZR36057_JMC); // /Go_en udelay(30); set_frame(zr, 1); // /FRAME}static void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode){ static int zero = 0; static int one = 1; zr->codec_mode = mode; switch (mode) { case BUZ_MODE_MOTION_COMPRESS: set_videobus_enable(zr, 0); set_videobus_dir(zr, 0); // GPIO(zr, 1, 0); i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one); i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero); set_videobus_enable(zr, 1); zr36060_sleep(zr, 0); zr36060_set_cap(zr, mode); // Load ZR36060 init_jpeg_queue(zr); zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO clear_interrupt_counters(zr); DEBUG1(printk (KERN_INFO "%s: enable_jpg MOTION_COMPRESS\n", zr->name)); break; case BUZ_MODE_MOTION_DECOMPRESS: set_videobus_enable(zr, 0); i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &zero); set_videobus_dir(zr, 1); // GPIO(zr, 1, 1); i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &one); set_videobus_enable(zr, 1); zr36060_sleep(zr, 0); zr36060_set_cap(zr, mode); // Load ZR36060 init_jpeg_queue(zr); zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO clear_interrupt_counters(zr); DEBUG1(printk (KERN_INFO "%s: enable_jpg MOTION_DECOMPRESS\n", zr->name)); break; case BUZ_MODE_IDLE: default: /* shut down processing */ btand(~(cardjpegint[zr->card] | ZR36057_ICR_JPEGRepIRQ), ZR36057_ICR); btwrite(cardjpegint[zr->card] | ZR36057_ICR_JPEGRepIRQ, ZR36057_ISR); btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/20); set_videobus_dir(zr, 0); // GPIO(zr, 1, 0); set_frame(zr, 1); //GPIO(zr, 6, 1); // /FRAME btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC); btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC); zr36060_reset(zr); zr36060_sleep(zr, 1); zr36057_adjust_vfe(zr, mode); set_videobus_enable(zr, 0); i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one); i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero); set_videobus_enable(zr, 1); DEBUG1(printk (KERN_INFO "%s: enable_jpg IDLE\n", zr->name)); break; }}/* * Queue a MJPEG buffer for capture/playback */static int jpg_qbuf(struct zoran *zr, int frame, enum zoran_codec_mode mode){ unsigned long flags; int res; /* Check if buffers are allocated */ if (!zr->jpg_buffers_allocated) { printk(KERN_ERR "%s: jpg_qbuf: buffers not yet allocated\n", zr->name); return -ENOMEM; } /* Does the user want to stop streaming? */ if (frame < 0) { if (zr->codec_mode == mode) { zr36057_enable_jpg(zr, BUZ_MODE_IDLE); return 0; } else { printk(KERN_ERR "%s: jpg_qbuf - stop streaming but not in streaming mode\n", zr->name); return -EINVAL; } } /* No grabbing outside the buffer range! */ if (frame >= zr->jpg_nbufs) { printk(KERN_ERR "%s: jpg_qbuf: buffer %d out of range\n", zr->name, frame); return -EINVAL; } /* what is the codec mode right now? */ if (zr->codec_mode == BUZ_MODE_IDLE) { /* Ok load up the zr36060 */ zr36057_enable_jpg(zr, mode); } else if (zr->codec_mode != mode) { /* wrong codec mode active - invalid */ printk(KERN_ERR "%s: jpg_qbuf - codec in wrong mode\n", zr->name); return -EINVAL; } spin_lock_irqsave(&zr->lock, flags); /* make sure a grab isn't going on currently with this buffer */ switch (zr->jpg_gbuf[frame].state) { case BUZ_STATE_DONE: DEBUG1(printk (KERN_WARNING "%s: Warning: queing frame in BUZ_STATE_DONE state\n", zr->name)); case BUZ_STATE_USER: /* since there is at least one unused buffer there's room for at least one more pend[] entry */ zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = frame; zr->jpg_gbuf[frame].state = BUZ_STATE_PEND; zoran_feed_stat_com(zr); res = 0; break; default: case BUZ_STATE_DMA: case BUZ_STATE_PEND: res = -EBUSY; /* what are you doing? */ break; } spin_unlock_irqrestore(&zr->lock, flags); /* Start the zr36060 when the first frame is queued */ if (zr->jpg_que_head == 1) jpeg_start(zr); return res;}/* * Sync on a MJPEG buffer */static int jpg_sync(struct zoran *zr, struct zoran_sync *bs){ unsigned long flags; int frame, timeout; if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS && zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) { DEBUG1(printk(KERN_ERR "%s: BUZIOCSYNC: - codec not in streaming mode\n", zr->name)); return -EINVAL; } while (zr->jpg_que_tail == zr->jpg_dma_tail) { if (zr->jpg_dma_tail == zr->jpg_dma_head) break; timeout = interruptible_sleep_on_timeout(&zr->jpg_capq, 10 * HZ); if (!timeout) { btand(~ZR36057_JMC_Go_en, ZR36057_JMC); udelay(1); printk(KERN_ERR "%s: timeout: codec isr=0x%02x, csr=0x%02x\n", zr->name, zr36060_read_8(zr, 0x008), zr36060_read_8(zr, 0x001)); return -ETIME; } else if (signal_pending(current)) return -ERESTARTSYS; } spin_lock_irqsave(&zr->lock, flags); if (zr->jpg_dma_tail != zr->jpg_dma_head) frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME]; else frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; /* buffer should now be in BUZ_STATE_DONE */#if(DEBUGLEVEL > 0) if (zr->jpg_gbuf[frame].state != BUZ_STATE_DONE) printk(KERN_ERR "%s: jpg_sync - internal error\n", zr->name);#endif *bs = zr->jpg_gbuf[frame].bs; zr->jpg_gbuf[frame].state = BUZ_STATE_USER; spin_unlock_irqrestore(&zr->lock, flags); return 0;}/* when this is called the spinlock must be held */static void zoran_feed_stat_com(struct zoran *zr){ /* move frames from pending queue to DMA */ int frame, i, max_stat_com; max_stat_com = (zr->params.TmpDcm == 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1); while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com && zr->jpg_dma_head < zr->jpg_que_head) { frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME]; if (zr->params.TmpDcm == 1) { /* fill 1 stat_com entry */ i = (zr->jpg_dma_head - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; if (!(zr->stat_com[i] & 1)) break; zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus; } else { /* fill 2 stat_com entries */ i = ((zr->jpg_dma_head - zr->jpg_err_shift) & 1) * 2; if (!(zr->stat_com[i] & 1)) break; zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus; zr->stat_com[i + 1] = zr->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -