📄 av7110.c
字号:
break; } break; case CI_SWITCH_PRG_REPLY: //av7110->ci_stat=data[1]; break; default: break; }}static inline intDvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len, u8 * buffer2, size_t buffer2_len, struct dvb_demux_filter *dvbdmxfilter, dmx_success_t success, av7110_t *av7110){ if (!dvbdmxfilter->feed->demux->dmx.frontend) return 0; if (dvbdmxfilter->feed->demux->dmx.frontend->source==DMX_MEMORY_FE) return 0; switch(dvbdmxfilter->type) { case DMX_TYPE_SEC: if ((((buffer1[1]<<8)|buffer1[2])&0xfff)+3!=buffer1_len) return 0; if (dvbdmxfilter->doneq) { dmx_section_filter_t *filter=&dvbdmxfilter->filter; int i; u8 xor, neq=0; for (i=0; i<DVB_DEMUX_MASK_MAX; i++) { xor=filter->filter_value[i]^buffer1[i]; neq|=dvbdmxfilter->maskandnotmode[i]&xor; } if (!neq) return 0; } return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, buffer2, buffer2_len, &dvbdmxfilter->filter, DMX_OK); case DMX_TYPE_TS: if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) return 0; if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, buffer2, buffer2_len, &dvbdmxfilter->feed->feed.ts, DMX_OK); else pes_to_ts(buffer1, buffer1_len, dvbdmxfilter->feed->pid, &av7110->p2t_filter[dvbdmxfilter->index]); default: return 0; }}u8 pshead[0x26] = { 0x00, 0x00, 0x01, 0xba, 0x5f, 0xff, 0xfe, 0xe6, 0xc4, 0x01, 0x01, 0x89, 0xc3, 0xf8, 0x00, 0x00, 0x01, 0xbb, 0x00, 0x12, 0x80, 0xc4, 0xe1, 0x00, 0xe1, 0xff, 0xb9, 0xe0, 0xe8, 0xb8, 0xc0, 0x20, 0xbd, 0xe0, 0x44, 0xbf, 0xe0, 0x02,}; static void vpeirq (unsigned long data){ struct av7110_s *av7110 = (struct av7110_s*) data; u8 *mem=(u8 *)(av7110->saa->grabbing); int num; u32 dmapos; dmapos=saa7146_read(av7110->saa_mem, PCI_VDP3); dmapos-=(dmapos%188); if (dmapos >= TS_BUFLEN) return; if (dmapos == av7110->ttbp) return; if (dmapos > av7110->ttbp) { mem+=av7110->ttbp; num=(dmapos-av7110->ttbp)/188; } else { if (av7110->feeding) dvb_dmx_swfilter_packets(&av7110->demux, mem+av7110->ttbp, 1024-av7110->ttbp/188); num=dmapos/188; } av7110->ttbp=dmapos; if (av7110->feeding) dvb_dmx_swfilter_packets(&av7110->demux, mem, num); }staticvoid fidbirq (unsigned long data){}//#define DEBUG_TIMINGinline static void print_time(char *s){#ifdef DEBUG_TIMING struct timeval tv; do_gettimeofday(&tv); printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);#endif}static void ci_get_data(ring_buffer_t *cibuf, u8 *data, int len){ int free, split=0, pread=cibuf->pread; free=pread-cibuf->pwrite; if (free<=0) free+=cibuf->size; if (free<=len+2) return; cibuf->data[cibuf->pwrite]=(len>>8); cibuf->data[(cibuf->pwrite+1)%cibuf->size]=(len&0xff); cibuf->pwrite=(cibuf->pwrite+2)%cibuf->size; if (pread<=cibuf->pwrite) split=cibuf->size-cibuf->pwrite; if (split && split<len) { memcpy(cibuf->data + cibuf->pwrite, data, split); memcpy(cibuf->data, data+split, len-split); } else memcpy(cibuf->data + cibuf->pwrite, data, len); cibuf->pwrite=(cibuf->pwrite+len)%cibuf->size; wake_up_interruptible(&cibuf->queue);}staticvoid debiirq (unsigned long data){ struct av7110_s *av7110 = (struct av7110_s*) data; int type=av7110->debitype; int handle=(type>>8)&0x1f; print_time("debi"); saa7146_write(av7110->saa_mem, IER, saa7146_read(av7110->saa_mem, IER) & ~MASK_19 ); saa7146_write(av7110->saa_mem, ISR, MASK_19 ); if (type==-1) { printk("DEBI irq oops\n"); spin_lock(&av7110->debilock); ARM_ClearMailBox(av7110); ARM_ClearIrq(av7110); spin_unlock(&av7110->debilock); return; } av7110->debitype=-1; switch (type&0xff) { case DATA_TS_RECORD: dvb_dmx_swfilter_packets(&av7110->demux, (const u8 *)av7110->debi_virt, av7110->debilen/188); spin_lock(&av7110->debilock); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock); return; case DATA_PES_RECORD: if (av7110->demux.recording) record_cb(&av7110->p2t[handle], (u8 *)av7110->debi_virt, av7110->debilen); spin_lock(&av7110->debilock); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock); return; case DATA_IPMPE: case DATA_FSECTION: case DATA_PIPING: if (av7110->handle2filter[handle]) DvbDmxFilterCallback((u8 *)av7110->debi_virt, av7110->debilen, 0, 0, av7110->handle2filter[handle], DMX_OK, av7110); spin_lock(&av7110->debilock); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock); return; case DATA_CI_GET: { u8 *data=av7110->debi_virt; if ((data[0]<2) && data[2]==0xff) { int flags=0; if (data[5]>0) flags|=CA_CI_MODULE_PRESENT; if (data[5]>5) flags|=CA_CI_MODULE_READY; av7110->ci_slot[data[0]].flags=flags; } else ci_get_data(&av7110->ci_rbuffer, av7110->debi_virt, av7110->debilen); spin_lock(&av7110->debilock); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock); return; } case DATA_COMMON_INTERFACE: CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);#if 0 { int i; printk("av7110%d: ", av7110->num); printk("%02x ", *(u8 *)av7110->debi_virt); printk("%02x ", *(1+(u8 *)av7110->debi_virt)); for (i=2; i<av7110->debilen; i++) printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt))); for (i=2; i<av7110->debilen; i++) printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt))); printk("\n"); }#endif spin_lock(&av7110->debilock); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock); return; case DATA_DEBUG_MESSAGE: ((s8*)av7110->debi_virt)[Reserved_SIZE-1]=0; printk("%s\n", (s8 *)av7110->debi_virt); spin_lock(&av7110->debilock); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock); return; case DATA_CI_PUT: case DATA_MPEG_PLAY: case DATA_BMP_LOAD: spin_lock(&av7110->debilock); iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock); return; default: break; } spin_lock(&av7110->debilock); ARM_ClearMailBox(av7110); spin_unlock(&av7110->debilock);}static intpes_play(void *dest, ring_buffer_t *buf, int dlen){ int len, split=0; u32 sync; u16 blen; dprintk ("function : %s\n", __FUNCTION__); if (!dlen) { wake_up(&buf->queue); return -1; } while (1) { if ((len=ring_buffer_avail(buf)) < 6) return -1; sync=(buf->data[buf->pread])<<24; sync|=(buf->data[(buf->pread+1)%buf->size]<<16); sync|=(buf->data[(buf->pread+2)%buf->size]<<8); sync|=buf->data[(buf->pread+3)%buf->size]; if (((sync&~0x0f)==0x000001e0) || ((sync&~0x1f)==0x000001c0) || (sync==0x000001bd)) break; printk("resync\n"); buf->pread=(buf->pread+1)%buf->size; } blen=(buf->data[(buf->pread+4)%buf->size]<<8); blen|=buf->data[(buf->pread+5)%buf->size]; blen+=6; if (len<blen || blen > dlen) { //printk("buffer empty\n"); wake_up(&buf->queue); return -1; }/* if (blen>2048) { buf->pread=(buf->pread+blen)%buf->size; printk("packet too large\n"); return -1; }*/ len=blen; if (buf->pread + len > buf->size) split=buf->size-buf->pread; if (split>0) { memcpy(dest, buf->data+buf->pread, split); buf->pread=0; len-=split; } memcpy(split + dest, buf->data + buf->pread, len); buf->pread = (buf->pread +len)%buf->size; dprintk ("function: %s pread=%08x pwrite=%08x\n", __FUNCTION__, buf->pread, buf->pwrite); wake_up(&buf->queue); return blen;}staticvoid gpioirq (unsigned long data){ struct av7110_s *av7110 = (struct av7110_s*) data; u32 rxbuf, txbuf; int len; //printk("GPIO0 irq\n"); if (av7110->debitype !=-1) printk("GPIO0 irq oops\n"); spin_lock(&av7110->debilock); ARM_ClearIrq(av7110); saa7146_write(av7110->saa_mem, IER, saa7146_read(av7110->saa_mem, IER) & ~MASK_19 ); saa7146_write(av7110->saa_mem, ISR, MASK_19 ); av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2); av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); av7110->debibuf = 0; rxbuf=irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); len=(av7110->debilen+3)&(~3); dprintk("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen); print_time("gpio"); dprintk("GPIO0 irq %02x\n", av7110->debitype&0xff); switch (av7110->debitype&0xff) { case DATA_MPEG_VIDEO_EVENT: { u32 h_ar; struct video_event event; av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2); h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2); iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); av7110->video_size.h = h_ar & 0xfff; dprintk("%s: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", __FUNCTION__, av7110->video_size.w, av7110->video_size.h, av7110->video_size.aspect_ratio); event.type = VIDEO_EVENT_SIZE_CHANGED; event.u.size.w = av7110->video_size.w; event.u.size.h = av7110->video_size.h; switch ((h_ar >> 12) & 0xf) { case 3: av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9; event.u.size.aspect_ratio = VIDEO_FORMAT_16_9; av7110->videostate.video_format = VIDEO_FORMAT_16_9; break; case 4: av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1; event.u.size.aspect_ratio = VIDEO_FORMAT_221_1; av7110->videostate.video_format = VIDEO_FORMAT_221_1; break; default: av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3; event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; av7110->videostate.video_format = VIDEO_FORMAT_4_3; } dvb_video_add_event(av7110, &event); break; } case DATA_TS_PLAY: case DATA_PES_PLAY: break; case DATA_CI_PUT: { int avail, split=0, pwrite; ring_buffer_t *cibuf=&av7110->ci_wbuffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -