📄 av7110.c
字号:
{ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) p2t->priv; if (!(dvbdmxfeed->ts_type & TS_PACKET)) return 0; if (buf[3]==0xe0) // video PES do not have a length in TS buf[4]=buf[5]=0; if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) return dvbdmxfeed->cb.ts(buf, len, 0, 0, &dvbdmxfeed->feed.ts, DMX_OK); else return dvb_filter_pes2ts(p2t, buf, len);}static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data){ struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) priv; dvbdmxfeed->cb.ts(data, 188, 0, 0, &dvbdmxfeed->feed.ts, DMX_OK); return 0;}static int AV_StartRecord(av7110_t *av7110, int av, struct dvb_demux_feed *dvbdmxfeed){ struct dvb_demux *dvbdmx=dvbdmxfeed->demux; if (av7110->playing||(av7110->rec_mode&av)) return -EBUSY; outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0); dvbdmx->recording=1; av7110->rec_mode|=av; switch (av7110->rec_mode) { case RP_AUDIO: dvb_filter_pes2ts_init (&av7110->p2t[0], dvbdmx->pesfilter[0]->pid, dvb_filter_pes2ts_cb, (void *)dvbdmx->pesfilter[0]); outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); break; case RP_VIDEO: dvb_filter_pes2ts_init (&av7110->p2t[1], dvbdmx->pesfilter[1]->pid, dvb_filter_pes2ts_cb, (void *)dvbdmx->pesfilter[1]); outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); break; case RP_AV: dvb_filter_pes2ts_init (&av7110->p2t[0], dvbdmx->pesfilter[0]->pid, dvb_filter_pes2ts_cb, (void *)dvbdmx->pesfilter[0]); dvb_filter_pes2ts_init (&av7110->p2t[1], dvbdmx->pesfilter[1]->pid, dvb_filter_pes2ts_cb, (void *)dvbdmx->pesfilter[1]); outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); break; } return 0;}static int AV_StartPlay(av7110_t *av7110, int av){ if (av7110->rec_mode) return -EBUSY; if (av7110->playing&av) return -EBUSY; outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0); if (av7110->playing == RP_NONE) { dvb_filter_ipack_reset(&av7110->ipack[0]); dvb_filter_ipack_reset(&av7110->ipack[1]); } av7110->playing|=av; switch (av7110->playing) { case RP_AUDIO: outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); break; case RP_VIDEO: outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); av7110->sinfo=0; break; case RP_AV: av7110->sinfo=0; outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); break; } return av7110->playing;}static void AV_Stop(av7110_t *av7110, int av){ if (!(av7110->playing&av) && !(av7110->rec_mode&av)) return; outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0); if (av7110->playing) { av7110->playing&=~av; switch (av7110->playing) { case RP_AUDIO: outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); break; case RP_VIDEO: outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); break; case RP_NONE: SetMode(av7110, av7110->vidmode); break; } } else { av7110->rec_mode&=~av; switch (av7110->rec_mode) { case RP_AUDIO: outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); break; case RP_VIDEO: outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); break; case RP_NONE: break; } }}/**************************************************************************** * Buffer handling ****************************************************************************/static inline void ring_buffer_flush(ring_buffer_t *rbuf){ spin_lock_irq(&rbuf->lock); rbuf->pwrite=rbuf->pread; spin_unlock_irq(&rbuf->lock); wake_up(&rbuf->queue);}static inline void ring_buffer_init(ring_buffer_t *rbuf, u8 *data, int len){ rbuf->pread=rbuf->pwrite=0; rbuf->data=data; rbuf->size=len; init_waitqueue_head(&rbuf->queue); spin_lock_init(&(rbuf->lock)); rbuf->lock=SPIN_LOCK_UNLOCKED; sema_init(&(rbuf->sema), 1);}static inline int ring_buffer_empty(ring_buffer_t *rbuf){ return (rbuf->pread==rbuf->pwrite);}static inline int ring_buffer_free(ring_buffer_t *rbuf){ int free; free=rbuf->pread - rbuf->pwrite; if (free<=0) free+=rbuf->size; return free;}static inline int ring_buffer_avail(ring_buffer_t *rbuf){ int avail; avail=rbuf->pwrite - rbuf->pread; if (avail<0) avail+=rbuf->size; return avail;}#if 0static voidring_buffer_block(ring_buffer_t *rbuf, unsigned long count){ if (ring_buffer_free(rbuf)>=count) return; while (!wait_event_interruptible(rbuf->queue, (ring_buffer_free(rbuf)>=count)));}#endifstatic long ring_buffer_write(ring_buffer_t *rbuf, const char *buf, unsigned long count, int nonblock, int usermem){ unsigned long todo = count; int free, split; while (todo > 0) { if (ring_buffer_free(rbuf)<=2048) { if (nonblock) return count-todo; if (wait_event_interruptible(rbuf->queue, (ring_buffer_free(rbuf)>2048))) return count-todo; } dprintk ("function: %s pread=%08x pwrite=%08x\n", __FUNCTION__, rbuf->pread, rbuf->pwrite); //mdelay(2); free = rbuf->pread - rbuf->pwrite; split=rbuf->size; if (free<=0) { free+=rbuf->size; split-=rbuf->pwrite; } if (free > todo) free = todo; if (split < free) { if (!usermem) memcpy(rbuf->data+rbuf->pwrite, buf, split); else if (copy_from_user(rbuf->data+rbuf->pwrite, buf, split)) return -EFAULT; buf += split; todo -= split; free -= split; rbuf->pwrite = 0; } if (!usermem) memcpy(rbuf->data+rbuf->pwrite, buf, free); else if (copy_from_user(rbuf->data+rbuf->pwrite, buf, free)) return -EFAULT; rbuf->pwrite = (rbuf->pwrite + free)%rbuf->size; todo -= free; buf += free; } return count-todo;}#if 0static voidring_buffer_put(ring_buffer_t *db, u8 *buf, int len){ int split, fsize; fsize=db->pread - db->pwrite; if (fsize <= 0) { fsize+=db->size; split=db->size-db->pwrite; } else split=0; if (len>=fsize) { dprintk("buffer overflow\n"); return; } if (split>=len) split=0; if (split) { memcpy(db->data + db->pwrite, buf, split); len-=split; db->pwrite=0; } memcpy(db->data + db->pwrite, split + buf, len); db->pwrite=(db->pwrite+len)%db->size;}#endif/**************************************************************************** * TT budget / WinTV Nova ****************************************************************************/static int TTBStop(av7110_t *av7110){ if (--av7110->feeding) return av7110->feeding; saa7146_write(av7110->saa_mem, MC1, MASK_20); // DMA3 off saa7146_write(av7110->saa_mem, MC1, MASK_28); // RPS0 off saa7146_write(av7110->saa_mem, IER, saa7146_read(av7110->saa_mem, IER) & ~MASK_10 ); saa7146_write(av7110->saa_mem, IER, saa7146_read(av7110->saa_mem, IER)& ~MASK_07); return 0;}#define TS_WIDTH (4*188)#define TS_HEIGHT (1024/4)#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)static intTTBStart(av7110_t *av7110){ struct saa7146 *saa=av7110->saa; //printk ("function : %s\n", __FUNCTION__); if (av7110->feeding) return ++av7110->feeding; saa7146_write(saa->mem, MC1, MASK_20); // DMA3 off memset(saa->grabbing, 0x00, TS_BUFLEN); saa7146_write(saa->mem, PCI_BT_V1, 0x001c0000); av7110->ttbp=0; saa7146_write(saa->mem, DD1_INIT, 0x02000600); saa7146_write(saa->mem, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); saa7146_write(saa->mem, BRS_CTRL, 0x60000000); saa7146_write(saa->mem, MC2, (MASK_08 | MASK_24)); mdelay(10); saa7146_write(saa->mem, BASE_ODD3, 0); saa7146_write(saa->mem, BASE_EVEN3, 0); saa7146_write(saa->mem, PROT_ADDR3, TS_BUFLEN); saa7146_write(saa->mem, BASE_PAGE3, virt_to_bus(saa->page_table[0])|ME1|0x90); saa7146_write(saa->mem, PITCH3, TS_WIDTH); saa7146_write(saa->mem, NUM_LINE_BYTE3, (TS_HEIGHT<<16)|TS_WIDTH); saa7146_write(saa->mem, MC2, (MASK_04 | MASK_20)); // VPE saa7146_write(saa->mem, IER, saa7146_read(saa->mem, IER)|MASK_10); saa7146_write(saa->mem, MC1, (MASK_04 | MASK_20)); // DMA3 on // FIDB saa7146_write(saa->mem, IER, saa7146_read(saa->mem, IER)|MASK_07); return ++av7110->feeding;}/** * Hack! we save the last av7110 ptr. This should be ok, since * you rarely will use more then one IR control. * * If we want to support multiple controls we would have to do much more... */void av7110_setup_irc_config (av7110_t *av7110, u32 ir_config){ static av7110_t *last; if (!av7110) av7110 = last; else last = av7110; if (av7110) { outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); av7110->ir_config = ir_config; }}static void (*irc_handler)(u32);void av7110_register_irc_handler(void (*func)(u32)) { //dprintk("registering %08x\n",func); irc_handler = func;}void av7110_unregister_irc_handler(void (*func)(u32)) { //dprintk("unregistering %08x\n",func); irc_handler = NULL;}void run_handlers(unsigned long ircom) { if (irc_handler != NULL) (*irc_handler)((u32) ircom);}DECLARE_TASKLET(irtask,run_handlers,0);void IR_handle(av7110_t *av7110, u32 ircom){ dprintk("av7110: ircommand = %08x\n", ircom); irtask.data = (unsigned long) ircom; tasklet_schedule(&irtask);}/**************************************************************************** * IRQ handling ****************************************************************************/void CI_handle(av7110_t *av7110, u8 *data, u16 len) { //CI_out(av7110, data, len); if (len<3) return; switch (data[0]) { case CI_MSG_CI_INFO: if (data[2]!=1 && data[2]!=2) break; switch (data[1]) { case 0: av7110->ci_slot[data[2]-1].flags=0; break; case 1: av7110->ci_slot[data[2]-1].flags|=CA_CI_MODULE_PRESENT; break; case 2: av7110->ci_slot[data[2]-1].flags|=CA_CI_MODULE_READY;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -