📄 stradis.c
字号:
memcpy(saa->dmadebi, saa->vidbuf + saa->vidhead, split); saa->vidhead = 0; vidbytes -= split; } else split = 0; memcpy(saa->dmadebi + split, saa->vidbuf + saa->vidhead, vidbytes); saa->vidhead += vidbytes; saa->vidhead &= 0x7ffff; debiwrite(saa, debVideo, (NewCard ? IBM_MP2_FIFO : IBM_MP2_FIFOW), 0, 30720); wake_up_interruptible(&saa->vidq); } saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER);}static void send_osd_data(struct saa7146 *saa){ int size = saa->osdtail - saa->osdhead; if (size > 30720) size = 30720; /* ensure some multiple of 8 bytes is transferred */ size = 8 * ((size + 8)>>3); if (size) { debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, (saa->osdhead>>3), 2); memcpy(saa->dmadebi, &saa->osdbuf[saa->osdhead], size); saa->osdhead += size; /* block transfer of next 8 bytes to ~32k bytes */ debiwrite(saa, debNormal, IBM_MP2_OSD_DATA, 0, size); } if (saa->osdhead >= saa->osdtail) { saa->osdhead = saa->osdtail = 0; debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2); }}static void saa7146_irq(int irq, void *dev_id, struct pt_regs *regs){ struct saa7146 *saa = (struct saa7146 *) dev_id; u32 stat, astat; int count; count = 0; while (1) { /* get/clear interrupt status bits */ stat = saaread(SAA7146_ISR); astat = stat & saaread(SAA7146_IER); if (!astat) return; saawrite(astat, SAA7146_ISR); if (astat & SAA7146_PSR_DEBI_S) { do_irq_send_data(saa); } if (astat & SAA7146_PSR_PIN1) { int istat; /* the following read will trigger DEBI_S */ istat = debiread(saa, debNormal, IBM_MP2_HOST_INT, 2); if (istat & 1) { saawrite(0, SAA7146_IER); send_osd_data(saa); saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER); } if (istat & 0x20) { /* Video Start */ saa->vidinfo.frame_count++; } if (istat & 0x400) { /* Picture Start */ /* update temporal reference */ } if (istat & 0x200) { /* Picture Resolution Change */ /* read new resolution */ } if (istat & 0x100) { /* New User Data found */ /* read new user data */ } if (istat & 0x1000) { /* new GOP/SMPTE */ /* read new SMPTE */ } if (istat & 0x8000) { /* Sequence Start Code */ /* reset frame counter, load sizes */ saa->vidinfo.frame_count = 0; saa->vidinfo.h_size = 704; saa->vidinfo.v_size = 480;#if 0 if (saa->endmarkhead != saa->endmarktail) { saa->audhead = saa->endmark[saa->endmarkhead]; saa->endmarkhead++; if (saa->endmarkhead >= MAX_MARKS) saa->endmarkhead = 0; }#endif } if (istat & 0x4000) { /* Sequence Error Code */ if (saa->endmarkhead != saa->endmarktail) { saa->audhead = saa->endmark[saa->endmarkhead]; saa->endmarkhead++; if (saa->endmarkhead >= MAX_MARKS) saa->endmarkhead = 0; } } }#ifdef IDEBUG if (astat & SAA7146_PSR_PPEF) { IDEBUG(printk("stradis%d irq: PPEF\n", saa->nr)); } if (astat & SAA7146_PSR_PABO) { IDEBUG(printk("stradis%d irq: PABO\n", saa->nr)); } if (astat & SAA7146_PSR_PPED) { IDEBUG(printk("stradis%d irq: PPED\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_I1) { IDEBUG(printk("stradis%d irq: RPS_I1\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_I0) { IDEBUG(printk("stradis%d irq: RPS_I0\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_LATE1) { IDEBUG(printk("stradis%d irq: RPS_LATE1\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_LATE0) { IDEBUG(printk("stradis%d irq: RPS_LATE0\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_E1) { IDEBUG(printk("stradis%d irq: RPS_E1\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_E0) { IDEBUG(printk("stradis%d irq: RPS_E0\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_TO1) { IDEBUG(printk("stradis%d irq: RPS_TO1\n", saa->nr)); } if (astat & SAA7146_PSR_RPS_TO0) { IDEBUG(printk("stradis%d irq: RPS_TO0\n", saa->nr)); } if (astat & SAA7146_PSR_UPLD) { IDEBUG(printk("stradis%d irq: UPLD\n", saa->nr)); } if (astat & SAA7146_PSR_DEBI_E) { IDEBUG(printk("stradis%d irq: DEBI_E\n", saa->nr)); } if (astat & SAA7146_PSR_I2C_S) { IDEBUG(printk("stradis%d irq: I2C_S\n", saa->nr)); } if (astat & SAA7146_PSR_I2C_E) { IDEBUG(printk("stradis%d irq: I2C_E\n", saa->nr)); } if (astat & SAA7146_PSR_A2_IN) { IDEBUG(printk("stradis%d irq: A2_IN\n", saa->nr)); } if (astat & SAA7146_PSR_A2_OUT) { IDEBUG(printk("stradis%d irq: A2_OUT\n", saa->nr)); } if (astat & SAA7146_PSR_A1_IN) { IDEBUG(printk("stradis%d irq: A1_IN\n", saa->nr)); } if (astat & SAA7146_PSR_A1_OUT) { IDEBUG(printk("stradis%d irq: A1_OUT\n", saa->nr)); } if (astat & SAA7146_PSR_AFOU) { IDEBUG(printk("stradis%d irq: AFOU\n", saa->nr)); } if (astat & SAA7146_PSR_V_PE) { IDEBUG(printk("stradis%d irq: V_PE\n", saa->nr)); } if (astat & SAA7146_PSR_VFOU) { IDEBUG(printk("stradis%d irq: VFOU\n", saa->nr)); } if (astat & SAA7146_PSR_FIDA) { IDEBUG(printk("stradis%d irq: FIDA\n", saa->nr)); } if (astat & SAA7146_PSR_FIDB) { IDEBUG(printk("stradis%d irq: FIDB\n", saa->nr)); } if (astat & SAA7146_PSR_PIN3) { IDEBUG(printk("stradis%d irq: PIN3\n", saa->nr)); } if (astat & SAA7146_PSR_PIN2) { IDEBUG(printk("stradis%d irq: PIN2\n", saa->nr)); } if (astat & SAA7146_PSR_PIN0) { IDEBUG(printk("stradis%d irq: PIN0\n", saa->nr)); } if (astat & SAA7146_PSR_ECS) { IDEBUG(printk("stradis%d irq: ECS\n", saa->nr)); } if (astat & SAA7146_PSR_EC3S) { IDEBUG(printk("stradis%d irq: EC3S\n", saa->nr)); } if (astat & SAA7146_PSR_EC0S) { IDEBUG(printk("stradis%d irq: EC0S\n", saa->nr)); }#endif count++; if (count > 15) printk(KERN_WARNING "stradis%d: irq loop %d\n", saa->nr, count); if (count > 20) { saawrite(0, SAA7146_IER); printk(KERN_ERR "stradis%d: IRQ loop cleared\n", saa->nr); } }}static int ibm_send_command(struct saa7146 *saa, int command, int data, int chain){ int i; if (chain) debiwrite(saa, debNormal, IBM_MP2_COMMAND, (command << 1) | 1, 2); else debiwrite(saa, debNormal, IBM_MP2_COMMAND, command << 1, 2); debiwrite(saa, debNormal, IBM_MP2_CMD_DATA, data, 2); debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 1, 2); for (i = 0; i < 100 && (debiread(saa, debNormal, IBM_MP2_CMD_STAT, 2) & 1); i++) schedule(); if (i == 100) return -1; return 0;}static void cs4341_setlevel(struct saa7146 *saa, int left, int right){ I2CWrite(&(saa->i2c), 0x22, 0x03, left > 94 ? 94 : left, 2); I2CWrite(&(saa->i2c), 0x22, 0x04, right > 94 ? 94 : right, 2);}static void initialize_cs4341(struct saa7146 *saa){ int i; for (i = 0; i < 200; i++) { /* auto mute off, power on, no de-emphasis */ /* I2S data up to 24-bit 64xFs internal SCLK */ I2CWrite(&(saa->i2c), 0x22, 0x01, 0x11, 2); /* ATAPI mixer settings */ I2CWrite(&(saa->i2c), 0x22, 0x02, 0x49, 2); /* attenuation left 3db */ I2CWrite(&(saa->i2c), 0x22, 0x03, 0x00, 2); /* attenuation right 3db */ I2CWrite(&(saa->i2c), 0x22, 0x04, 0x00, 2); I2CWrite(&(saa->i2c), 0x22, 0x01, 0x10, 2); if (I2CRead(&(saa->i2c), 0x22, 0x02, 1) == 0x49) break; schedule(); } printk("stradis%d: CS4341 initialized (%d)\n", saa->nr, i); return;}static void initialize_cs8420(struct saa7146 *saa, int pro){ int i; u8 *sequence; if (pro) sequence = mode8420pro; else sequence = mode8420con; for (i = 0; i < INIT8420LEN; i++) I2CWrite(&(saa->i2c), 0x20, init8420[i * 2], init8420[i * 2 + 1], 2); for (i = 0; i < MODE8420LEN; i++) I2CWrite(&(saa->i2c), 0x20, sequence[i * 2], sequence[i * 2 + 1], 2); printk("stradis%d: CS8420 initialized\n", saa->nr);}static void initialize_saa7121(struct saa7146 *saa, int dopal){ int i, mod; u8 *sequence; if (dopal) sequence = init7121pal; else sequence = init7121ntsc; mod = saaread(SAA7146_PSR) & 0x08; /* initialize PAL/NTSC video encoder */ for (i = 0; i < INIT7121LEN; i++) { if (NewCard) { /* handle new card encoder differences */ if (sequence[i*2] == 0x3a) I2CWrite(&(saa->i2c), 0x88, 0x3a, 0x13, 2); else if (sequence[i*2] == 0x6b) I2CWrite(&(saa->i2c), 0x88, 0x6b, 0x20, 2); else if (sequence[i*2] == 0x6c) I2CWrite(&(saa->i2c), 0x88, 0x6c, dopal ? 0x09 : 0xf5, 2); else if (sequence[i*2] == 0x6d) I2CWrite(&(saa->i2c), 0x88, 0x6d, dopal ? 0x20 : 0x00, 2); else if (sequence[i*2] == 0x7a) I2CWrite(&(saa->i2c), 0x88, 0x7a, dopal ? (PALFirstActive - 1) : (NTSCFirstActive - 4), 2); else if (sequence[i*2] == 0x7b) I2CWrite(&(saa->i2c), 0x88, 0x7b, dopal ? PALLastActive : NTSCLastActive, 2); else I2CWrite(&(saa->i2c), 0x88, sequence[i * 2], sequence[i * 2 + 1], 2); } else { if (sequence[i*2] == 0x6b && mod) I2CWrite(&(saa->i2c), 0x88, 0x6b, (sequence[i * 2 + 1] ^ 0x09), 2); else if (sequence[i*2] == 0x7a) I2CWrite(&(saa->i2c), 0x88, 0x7a, dopal ? (PALFirstActive - 1) : (NTSCFirstActive - 4), 2); else if (sequence[i*2] == 0x7b) I2CWrite(&(saa->i2c), 0x88, 0x7b, dopal ? PALLastActive : NTSCLastActive, 2); else I2CWrite(&(saa->i2c), 0x88, sequence[i * 2], sequence[i * 2 + 1], 2); } }}static void set_genlock_offset(struct saa7146 *saa, int noffset){ int nCode; int PixelsPerLine = 858; if (CurrentMode == VIDEO_MODE_PAL) PixelsPerLine = 864; if (noffset > 500) noffset = 500; else if (noffset < -500) noffset = -500; nCode = noffset + 0x100; if (nCode == 1) nCode = 0x401; else if (nCode < 1) nCode = 0x400 + PixelsPerLine + nCode; debiwrite(saa, debNormal, XILINX_GLDELAY, nCode, 2);}static void set_out_format(struct saa7146 *saa, int mode){ initialize_saa7121(saa, (mode == VIDEO_MODE_NTSC ? 0 : 1)); saa->boardcfg[2] = mode; /* do not adjust analog video parameters here, use saa7121 init */ /* you will affect the SDI output on the new card */ if (mode == VIDEO_MODE_PAL) { /* PAL */ debiwrite(saa, debNormal, XILINX_CTL0, 0x0808, 2); mdelay(50); saawrite(0x012002c0, SAA7146_NUM_LINE_BYTE1); if (NewCard) { debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, 0xe100, 2); mdelay(50); } debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, NewCard ? 0xe500: 0x6500, 2); debiwrite(saa, debNormal, IBM_MP2_DISP_DLY, (1 << 8) | (NewCard ? PALFirstActive : PALFirstActive-6), 2); } else { /* NTSC */ debiwrite(saa, debNormal, XILINX_CTL0, 0x0800, 2); mdelay(50); saawrite(0x00f002c0, SAA7146_NUM_LINE_BYTE1); debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, NewCard ? 0xe100: 0x6100, 2); debiwrite(saa, debNormal, IBM_MP2_DISP_DLY, (1 << 8) | (NewCard ? NTSCFirstActive : NTSCFirstActive-6), 2); }}/* Intialize bitmangler to map from a byte value to the mangled word that * must be output to program the Xilinx part through the DEBI port. * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0 * transfer FPGA code, init IBM chip, transfer IBM microcode * rev2 card mangles: 0->7 1->6 2->5 3->4 4->3 5->2 6->1 7->0 */static u16 bitmangler[256];static int initialize_fpga(struct video_code *bitdata){ int i, num, startindex, failure = 0, loadtwo, loadfile = 0; u16 *dmabuf; u8 *newdma; struct saa7146 *saa; /* verify fpga code */ for (startindex = 0; startindex < bitdata->datasize; startindex++) if (bitdata->data[startindex] == 255) break; if (startindex == bitdata->datasize) { printk(KERN_INFO "stradis: bad fpga code\n"); return -1; } /* initialize all detected cards */ for (num = 0; num < saa_num; num++) { saa = &saa7146s[num]; if (saa->boardcfg[0] > 20) continue; /* card was programmed */ loadtwo = (saa->boardcfg[18] & 0x10); if (!NewCard) /* we have an old board */ for (i = 0; i < 256; i++) bitmangler[i] = ((i & 0x01) << 15) | ((i & 0x02) << 6) | ((i & 0x04) << 4) | ((i & 0x08) << 9) | ((i & 0x10) << 7) | ((i & 0x20) >> 3) | ((i & 0x40) >> 5) | ((i & 0x80) >> 7); else /* else we have a new board */ for (i = 0; i < 256; i++) bitmangler[i] = ((i & 0x01) << 7) | ((i & 0x02) << 5) | ((i & 0x04) << 3) | ((i & 0x08) << 1) | ((i & 0x10) >> 1) | ((i & 0x20) >> 3) | ((i & 0x40) >> 5) | ((i & 0x80) >> 7); dmabuf = (u16 *) saa->dmadebi; newdma = (u8 *) saa->dmadebi; if (NewCard) { /* SDM2xxx */ if (!strncmp(bitdata->loadwhat, "decoder2", 8)) continue; /* fpga not for this card */ if (!strncmp(&saa->boardcfg[42], bitdata->loadwhat, 8)) { loadfile = 1; } else if (loadtwo && !strncmp(&saa->boardcfg[19], bitdata->loadwhat, 8)) { loadfile = 2; } else if (!saa->boardcfg[42] && /* special */ !strncmp("decxl", bitdata->loadwhat, 8)) { loadfile = 1; } else continue; /* fpga not for this card */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -