int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, u32 status) { u32 int_msk_tmp; struct sram_channel *channel = dev->channels[chan_num].sram_channels; int singlefield_lines = NTSC_FIELD_HEIGHT; int line_size_in_bytes = Y422_LINE_SZ; int odd_risc_prog_size = 0; dma_addr_t risc_phys_jump_addr; __le32 *rp; if (status & FLD_VID_SRC_RISC1) { /* We should only process one program per call */ u32 prog_cnt = cx_read(channel->gpcnt); /* Since we've identified our IRQ, clear our bits from the * interrupt mask and interrupt status registers */ int_msk_tmp = cx_read(channel->int_msk); cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); cx_write(channel->int_stat, _intr_msk); spin_lock(&dev->slock); dev->_frame_index = prog_cnt; queue_work(dev->_irq_queues, &dev->_irq_work_entry); if (dev->_is_first_frame) { dev->_is_first_frame = 0; if (dev->_isNTSC) { singlefield_lines += 1; odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; } else { singlefield_lines = PAL_FIELD_HEIGHT; odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; } if (dev->_dma_virt_start_addr != NULL) { line_size_in_bytes = (dev->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; risc_phys_jump_addr = dev->_dma_phys_start_addr + odd_risc_prog_size; rp = cx25821_update_riscprogram(dev, dev->_dma_virt_start_addr, TOP_OFFSET, line_size_in_bytes, 0x0, singlefield_lines, FIFO_DISABLE, ODD_FIELD); /* Jump to Even Risc program of 1st Frame */ *(rp++) = cpu_to_le32(RISC_JUMP); *(rp++) = cpu_to_le32(risc_phys_jump_addr); *(rp++) = cpu_to_le32(0); } } spin_unlock(&dev->slock); } else { if (status & FLD_VID_SRC_UF) pr_err("%s(): Video Received Underflow Error Interrupt!\n", __func__); if (status & FLD_VID_SRC_SYNC) pr_err("%s(): Video Received Sync Error Interrupt!\n", __func__); if (status & FLD_VID_SRC_OPC_ERR) pr_err("%s(): Video Received OpCode Error Interrupt!\n", __func__); } if (dev->_file_status == END_OF_FILE) { pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count); return -1; } /* ElSE, set the interrupt mask register, re-enable irq. */ int_msk_tmp = cx_read(channel->int_msk); cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); return 0; }
static int i2c_sendbytes(struct i2c_adapter *i2c_adap, const struct i2c_msg *msg, int joined_rlen) { struct cx23885_i2c *bus = i2c_adap->algo_data; struct cx23885_dev *dev = bus->dev; u32 wdata, addr, ctrl; int retval, cnt; if (joined_rlen) dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, msg->len, joined_rlen); else dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); /* Deal with i2c probe functions with zero payload */ if (msg->len == 0) { cx_write(bus->reg_addr, msg->addr << 25); cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2)); if (!i2c_wait_done(i2c_adap)) return -EIO; if (!i2c_slave_did_ack(i2c_adap)) return -ENXIO; dprintk(1, "%s() returns 0\n", __func__); return 0; } /* dev, reg + first byte */ addr = (msg->addr << 25) | msg->buf[0]; wdata = msg->buf[0]; ctrl = bus->i2c_period | (1 << 12) | (1 << 2); if (msg->len > 1) ctrl |= I2C_NOSTOP | I2C_EXTEND; else if (joined_rlen) ctrl |= I2C_NOSTOP; cx_write(bus->reg_addr, addr); cx_write(bus->reg_wdata, wdata); cx_write(bus->reg_ctrl, ctrl); if (!i2c_wait_done(i2c_adap)) goto eio; if (i2c_debug) { printk(KERN_DEBUG " <W %02x %02x", msg->addr << 1, msg->buf[0]); if (!(ctrl & I2C_NOSTOP)) pr_cont(" >\n"); } for (cnt = 1; cnt < msg->len; cnt++) { /* following bytes */ wdata = msg->buf[cnt]; ctrl = bus->i2c_period | (1 << 12) | (1 << 2); if (cnt < msg->len - 1) ctrl |= I2C_NOSTOP | I2C_EXTEND; else if (joined_rlen) ctrl |= I2C_NOSTOP; cx_write(bus->reg_addr, addr); cx_write(bus->reg_wdata, wdata); cx_write(bus->reg_ctrl, ctrl); if (!i2c_wait_done(i2c_adap)) goto eio; if (i2c_debug) { pr_cont(" %02x", msg->buf[cnt]); if (!(ctrl & I2C_NOSTOP)) pr_cont(" >\n"); } } return msg->len; eio: retval = -EIO; if (i2c_debug) pr_err(" ERR: %d\n", retval); return retval; }
int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, struct sram_channel *ch, unsigned int bpl, u32 risc) { unsigned int i, lines; u32 cdt; if (ch->cmds_start == 0) { cx_write(ch->ptr1_reg, 0); cx_write(ch->ptr2_reg, 0); cx_write(ch->cnt2_reg, 0); cx_write(ch->cnt1_reg, 0); return 0; } bpl = (bpl + 7) & ~7; /* alignment */ cdt = ch->cdt; lines = ch->fifo_size / bpl; if (lines > 4) lines = 4; BUG_ON(lines < 2); /* write CDT */ for (i = 0; i < lines; i++) { cx_write(cdt + 16 * i, ch->fifo_start + bpl * i); cx_write(cdt + 16 * i + 4, 0); cx_write(cdt + 16 * i + 8, 0); cx_write(cdt + 16 * i + 12, 0); } /* write CMDS */ cx_write(ch->cmds_start + 0, risc); cx_write(ch->cmds_start + 4, 0); cx_write(ch->cmds_start + 8, cdt); cx_write(ch->cmds_start + 12, (lines * 16) >> 3); cx_write(ch->cmds_start + 16, ch->ctrl_start); cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW); for (i = 24; i < 80; i += 4) cx_write(ch->cmds_start + i, 0); /* fill registers */ cx_write(ch->ptr1_reg, ch->fifo_start); cx_write(ch->ptr2_reg, cdt); cx_write(ch->cnt2_reg, (lines * 16) >> 3); cx_write(ch->cnt1_reg, (bpl >> 3) - 1); return 0; }
/* * IR register block read and write functions */ static inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value) { cx_write(addr, value); return 0; }
void cx23885_gpio_setup(struct cx23885_dev *dev) { switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: /* GPIO-0 cx24227 demodulator reset */ cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ break; case CX23885_BOARD_HAUPPAUGE_HVR1500: /* GPIO-0 cx24227 demodulator */ /* GPIO-2 xc3028 tuner */ /* Put the parts into reset */ cx_set(GP0_IO, 0x00050000); cx_clear(GP0_IO, 0x00000005); msleep(5); /* Bring the parts out of reset */ cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: /* GPIO-0 cx24227 demodulator reset */ /* GPIO-2 xc5000 tuner reset */ cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */ break; case CX23885_BOARD_HAUPPAUGE_HVR1800: /* GPIO-0 656_CLK */ /* GPIO-1 656_D0 */ /* GPIO-2 8295A Reset */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* GPIO-19 IR_RX */ /* CX23417 GPIO's */ /* EIO15 Zilog Reset */ /* EIO14 S5H1409/CX24227 Reset */ /* Force the TDA8295A into reset and back */ cx_set(GP0_IO, 0x00040004); mdelay(20); cx_clear(GP0_IO, 0x00000004); mdelay(20); cx_set(GP0_IO, 0x00040004); mdelay(20); break; case CX23885_BOARD_HAUPPAUGE_HVR1200: /* GPIO-0 tda10048 demodulator reset */ /* GPIO-2 tda18271 tuner reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1700: /* GPIO-0 TDA10048 demodulator reset */ /* GPIO-2 TDA8295A Reset */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* The following GPIO's are on the interna AVCore (cx25840) */ /* GPIO-19 IR_RX */ /* GPIO-20 IR_TX 416/DVBT Select */ /* GPIO-21 IIS DAT */ /* GPIO-22 IIS WCLK */ /* GPIO-23 IIS BCLK */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1400: /* GPIO-0 Dibcom7000p demodulator reset */ /* GPIO-2 xc3028L tuner reset */ /* GPIO-13 LED */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: /* GPIO-0 xc5000 tuner reset i2c bus 0 */ /* GPIO-1 s5h1409 demod reset i2c bus 0 */ /* GPIO-2 xc5000 tuner reset i2c bus 1 */ /* GPIO-3 s5h1409 demod reset i2c bus 0 */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x000f0000); mdelay(20); cx_clear(GP0_IO, 0x0000000f); mdelay(20); cx_set(GP0_IO, 0x000f000f); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: /* GPIO-0 portb xc3028 reset */ /* GPIO-1 portb zl10353 reset */ /* GPIO-2 portc xc3028 reset */ /* GPIO-3 portc zl10353 reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x000f0000); mdelay(20); cx_clear(GP0_IO, 0x0000000f); mdelay(20); cx_set(GP0_IO, 0x000f000f); break; case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: /* GPIO-2 xc3028 tuner reset */ /* The following GPIO's are on the internal AVCore (cx25840) */ /* GPIO-? zl10353 demod reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00040000); mdelay(20); cx_clear(GP0_IO, 0x00000004); mdelay(20); cx_set(GP0_IO, 0x00040004); break; case CX23885_BOARD_TBS_6920: case CX23885_BOARD_TEVII_S470: cx_write(MC417_CTL, 0x00000036); cx_write(MC417_OEN, 0x00001000); cx_write(MC417_RWD, 0x00001800); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: /* GPIO-0 INTA from CiMax1 GPIO-1 INTB from CiMax2 GPIO-2 reset chips GPIO-3 to GPIO-10 data/addr for CA GPIO-11 ~CS0 to CiMax1 GPIO-12 ~CS1 to CiMax2 GPIO-13 ADL0 load LSB addr GPIO-14 ADL1 load MSB addr GPIO-15 ~RDY from CiMax GPIO-17 ~RD to CiMax GPIO-18 ~WR to CiMax */ cx_set(GP0_IO, 0x00040000); /* GPIO as out */ /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */ cx_clear(GP0_IO, 0x00030004); mdelay(100);/* reset delay */ cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ /* GPIO-15 IN as ~ACK, rest as OUT */ cx_write(MC417_OEN, 0x00001000); /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */ cx_write(MC417_RWD, 0x0000c300); /* enable irq */ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ break; } }
static int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num, u32 status) { int i = 0; u32 int_msk_tmp; struct sram_channel *channel = dev->channels[chan_num].sram_channels; dma_addr_t risc_phys_jump_addr; __le32 *rp; if (status & FLD_AUD_SRC_RISCI1) { /* Get interrupt_index of the program that interrupted */ u32 prog_cnt = cx_read(channel->gpcnt); /* Since we've identified our IRQ, clear our bits from the * interrupt mask and interrupt status registers */ cx_write(channel->int_msk, 0); cx_write(channel->int_stat, cx_read(channel->int_stat)); spin_lock(&dev->slock); while (prog_cnt != dev->_last_index_irq) { /* Update _last_index_irq */ if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1)) dev->_last_index_irq++; else dev->_last_index_irq = 0; dev->_audioframe_index = dev->_last_index_irq; queue_work(dev->_irq_audio_queues, &dev->_audio_work_entry); } if (dev->_is_first_audio_frame) { dev->_is_first_audio_frame = 0; if (dev->_risc_virt_start_addr != NULL) { risc_phys_jump_addr = dev->_risc_phys_start_addr + RISC_SYNC_INSTRUCTION_SIZE + AUDIO_RISC_DMA_BUF_SIZE; rp = cx25821_risc_field_upstream_audio(dev, dev->_risc_virt_start_addr + 1, dev->_audiodata_buf_phys_addr, AUDIO_LINE_SIZE, FIFO_DISABLE); if (USE_RISC_NOOP_AUDIO) { for (i = 0; i < NUM_NO_OPS; i++) { *(rp++) = cpu_to_le32(RISC_NOOP); } } /* Jump to 2nd Audio Frame */ *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_RESET); *(rp++) = cpu_to_le32(risc_phys_jump_addr); *(rp++) = cpu_to_le32(0); } } spin_unlock(&dev->slock); } else { if (status & FLD_AUD_SRC_OF) pr_warn("%s(): Audio Received Overflow Error Interrupt!\n", __func__); if (status & FLD_AUD_SRC_SYNC) pr_warn("%s(): Audio Received Sync Error Interrupt!\n", __func__); if (status & FLD_AUD_SRC_OPC_ERR) pr_warn("%s(): Audio Received OpCode Error Interrupt!\n", __func__); /* Read and write back the interrupt status register to clear * our bits */ cx_write(channel->int_stat, cx_read(channel->int_stat)); } if (dev->_audiofile_status == END_OF_FILE) { pr_warn("EOF Channel Audio Framecount = %d\n", dev->_audioframe_count); return -1; } /* ElSE, set the interrupt mask register, re-enable irq. */ int_msk_tmp = cx_read(channel->int_msk); cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); return 0; }
static int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, struct sram_channel *sram_ch) { u32 tmp = 0; int err = 0; /* Set the physical start address of the RISC program in the initial * program counter(IPC) member of the CMDS. */ cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr); /* Risc IPC High 64 bits 63-32 */ cx_write(sram_ch->cmds_start + 4, 0); /* reset counter */ cx_write(sram_ch->gpcnt_ctl, 3); /* Set the line length (It looks like we do not need to set the * line length) */ cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH); /* Set the input mode to 16-bit */ tmp = cx_read(sram_ch->aud_cfg); tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE | FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE; cx_write(sram_ch->aud_cfg, tmp); /* Read and write back the interrupt status register to clear it */ tmp = cx_read(sram_ch->int_stat); cx_write(sram_ch->int_stat, tmp); /* Clear our bits from the interrupt status register. */ cx_write(sram_ch->int_stat, _intr_msk); /* Set the interrupt mask register, enable irq. */ cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp |= _intr_msk); err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio, IRQF_SHARED, dev->name, dev); if (err < 0) { pr_err("%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq); goto fail_irq; } /* Start the DMA engine */ tmp = cx_read(sram_ch->dma_ctl); cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en); dev->_audio_is_running = 1; dev->_is_first_audio_frame = 1; /* The fifo_en bit turns on by the first Risc program */ cx25821_wait_fifo_enable(dev, sram_ch); return 0; fail_irq: cx25821_dev_unregister(dev); return err; }
static int i2c_readbytes(struct i2c_adapter *i2c_adap, const struct i2c_msg *msg, int joined) { struct cx23885_i2c *bus = i2c_adap->algo_data; struct cx23885_dev *dev = bus->dev; u32 ctrl, cnt; int retval; if (i2c_debug && !joined) dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); /* Deal with i2c probe functions with zero payload */ if (msg->len == 0) { cx_write(bus->reg_addr, msg->addr << 25); cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); if (!i2c_wait_done(i2c_adap)) return -EIO; if (!i2c_slave_did_ack(i2c_adap)) return -ENXIO; dprintk(1, "%s() returns 0\n", __func__); return 0; } if (i2c_debug) { if (joined) dprintk(1, " R"); else dprintk(1, " <R %02x", (msg->addr << 1) + 1); } for (cnt = 0; cnt < msg->len; cnt++) { ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; if (cnt < msg->len - 1) ctrl |= I2C_NOSTOP | I2C_EXTEND; cx_write(bus->reg_addr, msg->addr << 25); cx_write(bus->reg_ctrl, ctrl); if (!i2c_wait_done(i2c_adap)) goto eio; if (cnt == 0 && !i2c_slave_did_ack(i2c_adap)) { retval = -ENXIO; goto err; } msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; if (i2c_debug) { dprintk(1, " %02x", msg->buf[cnt]); if (!(ctrl & I2C_NOSTOP)) dprintk(1, " >\n"); } } return msg->len; eio: retval = -EIO; err: if (i2c_debug) printk(KERN_ERR " ERR: %d\n", retval); return retval; }
void cx23885_gpio_setup(struct cx23885_dev *dev) { switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: /* GPIO-0 cx24227 demodulator reset */ cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ break; case CX23885_BOARD_HAUPPAUGE_HVR1500: /* GPIO-0 cx24227 demodulator */ /* GPIO-2 xc3028 tuner */ /* Put the parts into reset */ cx_set(GP0_IO, 0x00050000); cx_clear(GP0_IO, 0x00000005); msleep(5); /* Bring the parts out of reset */ cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1500Q: /* GPIO-0 cx24227 demodulator reset */ /* GPIO-2 xc5000 tuner reset */ cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */ break; case CX23885_BOARD_HAUPPAUGE_HVR1800: /* GPIO-0 656_CLK */ /* GPIO-1 656_D0 */ /* GPIO-2 8295A Reset */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* GPIO-19 IR_RX */ /* CX23417 GPIO's */ /* EIO15 Zilog Reset */ /* EIO14 S5H1409/CX24227 Reset */ mc417_gpio_enable(dev, GPIO_15 | GPIO_14, 1); /* Put the demod into reset and protect the eeprom */ mc417_gpio_clear(dev, GPIO_15 | GPIO_14); mdelay(100); /* Bring the demod and blaster out of reset */ mc417_gpio_set(dev, GPIO_15 | GPIO_14); mdelay(100); /* Force the TDA8295A into reset and back */ cx23885_gpio_enable(dev, GPIO_2, 1); cx23885_gpio_set(dev, GPIO_2); mdelay(20); cx23885_gpio_clear(dev, GPIO_2); mdelay(20); cx23885_gpio_set(dev, GPIO_2); mdelay(20); break; case CX23885_BOARD_HAUPPAUGE_HVR1200: /* GPIO-0 tda10048 demodulator reset */ /* GPIO-2 tda18271 tuner reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1700: /* GPIO-0 TDA10048 demodulator reset */ /* GPIO-2 TDA8295A Reset */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* The following GPIO's are on the interna AVCore (cx25840) */ /* GPIO-19 IR_RX */ /* GPIO-20 IR_TX 416/DVBT Select */ /* GPIO-21 IIS DAT */ /* GPIO-22 IIS WCLK */ /* GPIO-23 IIS BCLK */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_HAUPPAUGE_HVR1400: /* GPIO-0 Dibcom7000p demodulator reset */ /* GPIO-2 xc3028L tuner reset */ /* GPIO-13 LED */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00050000); mdelay(20); cx_clear(GP0_IO, 0x00000005); mdelay(20); cx_set(GP0_IO, 0x00050005); break; case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: /* GPIO-0 xc5000 tuner reset i2c bus 0 */ /* GPIO-1 s5h1409 demod reset i2c bus 0 */ /* GPIO-2 xc5000 tuner reset i2c bus 1 */ /* GPIO-3 s5h1409 demod reset i2c bus 0 */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x000f0000); mdelay(20); cx_clear(GP0_IO, 0x0000000f); mdelay(20); cx_set(GP0_IO, 0x000f000f); break; case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: /* GPIO-0 portb xc3028 reset */ /* GPIO-1 portb zl10353 reset */ /* GPIO-2 portc xc3028 reset */ /* GPIO-3 portc zl10353 reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x000f0000); mdelay(20); cx_clear(GP0_IO, 0x0000000f); mdelay(20); cx_set(GP0_IO, 0x000f000f); break; case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: /* GPIO-2 xc3028 tuner reset */ /* The following GPIO's are on the internal AVCore (cx25840) */ /* GPIO-? zl10353 demod reset */ /* Put the parts into reset and back */ cx_set(GP0_IO, 0x00040000); mdelay(20); cx_clear(GP0_IO, 0x00000004); mdelay(20); cx_set(GP0_IO, 0x00040004); break; case CX23885_BOARD_TBS_6920: cx_write(MC417_CTL, 0x00000036); cx_write(MC417_OEN, 0x00001000); cx_set(MC417_RWD, 0x00000002); mdelay(200); cx_clear(MC417_RWD, 0x00000800); mdelay(200); cx_set(MC417_RWD, 0x00000800); mdelay(200); break; case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: /* GPIO-0 INTA from CiMax1 GPIO-1 INTB from CiMax2 GPIO-2 reset chips GPIO-3 to GPIO-10 data/addr for CA GPIO-11 ~CS0 to CiMax1 GPIO-12 ~CS1 to CiMax2 GPIO-13 ADL0 load LSB addr GPIO-14 ADL1 load MSB addr GPIO-15 ~RDY from CiMax GPIO-17 ~RD to CiMax GPIO-18 ~WR to CiMax */ cx_set(GP0_IO, 0x00040000); /* GPIO as out */ /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */ cx_clear(GP0_IO, 0x00030004); mdelay(100);/* reset delay */ cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ /* GPIO-15 IN as ~ACK, rest as OUT */ cx_write(MC417_OEN, 0x00001000); /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */ cx_write(MC417_RWD, 0x0000c300); /* enable irq */ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ break; case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */ /* GPIO-6 I2C Gate which can isolate the demod from the bus */ /* GPIO-9 Demod reset */ /* Put the parts into reset and back */ cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1); cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5); cx23885_gpio_clear(dev, GPIO_9); mdelay(20); cx23885_gpio_set(dev, GPIO_9); break; case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: /* GPIO-0 (0)Analog / (1)Digital TV */ /* GPIO-1 reset XC5000 */ /* GPIO-2 reset LGS8GL5 / LGS8G75 */ cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1); cx23885_gpio_clear(dev, GPIO_1 | GPIO_2); mdelay(100); cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2); mdelay(100); break; case CX23885_BOARD_MYGICA_X8558PRO: /* GPIO-0 reset first ATBM8830 */ /* GPIO-1 reset second ATBM8830 */ cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1); cx23885_gpio_clear(dev, GPIO_0 | GPIO_1); mdelay(100); cx23885_gpio_set(dev, GPIO_0 | GPIO_1); mdelay(100); break; case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: /* GPIO-0 656_CLK */ /* GPIO-1 656_D0 */ /* GPIO-2 Wake# */ /* GPIO-3-10 cx23417 data0-7 */ /* GPIO-11-14 cx23417 addr0-3 */ /* GPIO-15-18 cx23417 READY, CS, RD, WR */ /* GPIO-19 IR_RX */ /* GPIO-20 C_IR_TX */ /* GPIO-21 I2S DAT */ /* GPIO-22 I2S WCLK */ /* GPIO-23 I2S BCLK */ /* ALT GPIO: EXP GPIO LATCH */ /* CX23417 GPIO's */ /* GPIO-14 S5H1411/CX24228 Reset */ /* GPIO-13 EEPROM write protect */ mc417_gpio_enable(dev, GPIO_14 | GPIO_13, 1); /* Put the demod into reset and protect the eeprom */ mc417_gpio_clear(dev, GPIO_14 | GPIO_13); mdelay(100); /* Bring the demod out of reset */ mc417_gpio_set(dev, GPIO_14); mdelay(100); /* CX24228 GPIO */ /* Connected to IF / Mux */ break; } }
static int philips_fmd1216_pll_init(struct dvb_frontend *fe) { struct cx8802_dev *dev= fe->dvb->priv; /* this message is to set up ATC and ALC */ static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; int err; if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { if (err < 0) return err; else return -EREMOTEIO; } return 0; } static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) { struct cx8802_dev *dev= fe->dvb->priv; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, .buf = pllbuf+1, .len = 4 }; int err; /* Switch PLL to DVB mode */ err = philips_fmd1216_pll_init(fe); if (err) return err; /* Tune PLL */ pllbuf[0] = dev->core->pll_addr << 1; dvb_pll_configure(dev->core->pll_desc, pllbuf+1, params->frequency, params->u.ofdm.bandwidth); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { printk(KERN_WARNING "cx88-dvb: %s error " "(addr %02x <- %02x, err = %i)\n", __FUNCTION__, pllbuf[0], pllbuf[1], err); if (err < 0) return err; else return -EREMOTEIO; } return 0; } static struct mt352_config dntv_live_dvbt_pro_config = { .demod_address = 0x0f, .no_tuner = 1, .demod_init = dntv_live_dvbt_pro_demod_init, .pll_set = dntv_live_dvbt_pro_pll_set, }; #endif #endif #ifdef HAVE_CX22702 static struct cx22702_config connexant_refboard_config = { .demod_address = 0x43, .output_mode = CX22702_SERIAL_OUTPUT, .pll_address = 0x60, .pll_desc = &dvb_pll_thomson_dtt7579, }; static struct cx22702_config hauppauge_novat_config = { .demod_address = 0x43, .output_mode = CX22702_SERIAL_OUTPUT, .pll_address = 0x61, .pll_desc = &dvb_pll_thomson_dtt759x, }; static struct cx22702_config hauppauge_hvr1100_config = { .demod_address = 0x63, .output_mode = CX22702_SERIAL_OUTPUT, .pll_address = 0x61, .pll_desc = &dvb_pll_fmd1216me, }; #endif #ifdef HAVE_OR51132 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } static struct or51132_config pchdtv_hd3000 = { .demod_address = 0x15, .pll_address = 0x61, .pll_desc = &dvb_pll_thomson_dtt7610, .set_ts_params = or51132_set_ts_param, }; #endif #ifdef HAVE_LGDT330X static int lgdt330x_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { /* FIXME make this routine use the tuner-simple code. * It could probably be shared with a number of ATSC * frontends. Many share the same tuner with analog TV. */ struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; u8 buf[4]; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; int err; /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); dvb_pll_configure(core->pll_desc, buf, params->frequency, 0); dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) { printk(KERN_WARNING "cx88-dvb: %s error " "(addr %02x <- %02x, err = %i)\n", __FUNCTION__, buf[0], buf[1], err); if (err < 0) return err; else return -EREMOTEIO; } if (core->tuner_type == TUNER_LG_TDVS_H062F) { /* Set the Auxiliary Byte. */ buf[2] &= ~0x20; buf[2] |= 0x18; buf[3] = 0x50; i2c_transfer(&core->i2c_adap, &msg, 1); } return 0; } static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; dprintk(1, "%s: index = %d\n", __FUNCTION__, index); if (index == 0) cx_clear(MO_GP0_IO, 8); else cx_set(MO_GP0_IO, 8); return 0; } static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; if (is_punctured) dev->ts_gen_cntrl |= 0x04; else dev->ts_gen_cntrl &= ~0x04; return 0; } static struct lgdt330x_config fusionhdtv_3_gold = { .demod_address = 0x0e, .demod_chip = LGDT3302, .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ .pll_set = lgdt330x_pll_set, .set_ts_params = lgdt330x_set_ts_param, }; static struct lgdt330x_config fusionhdtv_5_gold = { .demod_address = 0x0e, .demod_chip = LGDT3303, .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ .pll_set = lgdt330x_pll_set, .set_ts_params = lgdt330x_set_ts_param, }; #endif #ifdef HAVE_NXT200X static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } static int nxt200x_set_pll_input(u8* buf, int input) { if (input) buf[3] |= 0x08; else buf[3] &= ~0x08; return 0; } static struct nxt200x_config ati_hdtvwonder = { .demod_address = 0x0a, .pll_address = 0x61, .pll_desc = &dvb_pll_tuv1236d, .set_pll_input = nxt200x_set_pll_input, .set_ts_params = nxt200x_set_ts_param, }; #endif #ifdef HAVE_CX24123 static int cx24123_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = 0x2; return 0; } static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; if (on) cx_write(MO_GP0_IO, 0x000006f9); else cx_write(MO_GP0_IO, 0x000006fB); } static struct cx24123_config hauppauge_novas_config = { .demod_address = 0x55, .use_isl6421 = 1, .set_ts_params = cx24123_set_ts_param, }; static struct cx24123_config kworld_dvbs_100_config = { .demod_address = 0x15, .use_isl6421 = 0, .set_ts_params = cx24123_set_ts_param, .enable_lnb_voltage = cx24123_enable_lnb_voltage, }; #endif static int dvb_register(struct cx8802_dev *dev) { /* init struct videobuf_dvb */ dev->dvb.name = dev->core->name; dev->ts_gen_cntrl = 0x0c; /* init frontend */ switch (dev->core->board) { #ifdef HAVE_CX22702 case CX88_BOARD_HAUPPAUGE_DVB_T1: dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config, &dev->core->i2c_adap); break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, &dev->core->i2c_adap); break; case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, &dev->core->i2c_adap); break; #endif #ifdef HAVE_MT352 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_lg_z201; dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, &dev->core->i2c_adap); break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: dev->core->pll_addr = 0x60; dev->core->pll_desc = &dvb_pll_thomson_dtt7579; dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv, &dev->core->i2c_adap); break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_unknown_1; dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, &dev->core->i2c_adap); break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #ifdef HAVE_VP3054_I2C dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_fmd1216me; dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, &((struct vp3054_i2c_state *)dev->card_priv)->adap); #else printk("%s: built without vp3054 support\n", dev->core->name); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* The tin box says DEE1601, but it seems to be DTT7579 * compatible, with a slightly different MT352 AGC gain. */ dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_thomson_dtt7579; dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, &dev->core->i2c_adap); break; #endif #ifdef HAVE_OR51132 case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = or51132_attach(&pchdtv_hd3000, &dev->core->i2c_adap); break; #endif #ifdef HAVE_LGDT330X case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); /* Select RF connector callback */ fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_microtune_4042; dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, &dev->core->i2c_adap); } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_thomson_dtt761x; dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, &dev->core->i2c_adap); } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_tdvs_tua6034; dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold, &dev->core->i2c_adap); } break; #endif #ifdef HAVE_NXT200X case CX88_BOARD_ATI_HDTVWONDER: dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder, &dev->core->i2c_adap); break; #endif #ifdef HAVE_CX24123 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, &dev->core->i2c_adap); break; case CX88_BOARD_KWORLD_DVBS_100: dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, &dev->core->i2c_adap); break; #endif default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->core->name); break; } if (NULL == dev->dvb.frontend) { printk("%s: frontend initialization failed\n",dev->core->name); return -1; } if (dev->core->pll_desc) { dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min; dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max; } /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); } /* ----------------------------------------------------------- */ static int __devinit dvb_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { struct cx8802_dev *dev; struct cx88_core *core; int err; /* general setup */ core = cx88_core_get(pci_dev); if (NULL == core) return -EINVAL; err = -ENODEV; if (!cx88_boards[core->board].dvb) goto fail_core; err = -ENOMEM; dev = kzalloc(sizeof(*dev),GFP_KERNEL); if (NULL == dev) goto fail_core; dev->pci = pci_dev; dev->core = core; err = cx8802_init_common(dev); if (0 != err) goto fail_free; #ifdef HAVE_VP3054_I2C err = vp3054_i2c_probe(dev); if (0 != err) goto fail_free; #endif /* dvb stuff */ printk("%s/2: cx2388x based dvb card\n", core->name); videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, dev->pci, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer), dev); err = dvb_register(dev); if (0 != err) goto fail_fini; /* Maintain a reference to cx88-video can query the 8802 device. */ core->dvbdev = dev; return 0; fail_fini: cx8802_fini_common(dev); fail_free: kfree(dev); fail_core: cx88_core_put(core,pci_dev); return err; } static void __devexit dvb_remove(struct pci_dev *pci_dev) { struct cx8802_dev *dev = pci_get_drvdata(pci_dev); /* Destroy any 8802 reference. */ dev->core->dvbdev = NULL; /* dvb */ videobuf_dvb_unregister(&dev->dvb); #ifdef HAVE_VP3054_I2C vp3054_i2c_remove(dev); #endif /* common */ cx8802_fini_common(dev); cx88_core_put(dev->core,dev->pci); kfree(dev); } static struct pci_device_id cx8802_pci_tbl[] = { { .vendor = 0x14f1, .device = 0x8802, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, },{ /* --- end of list --- */ } }; MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); static struct pci_driver dvb_pci_driver = { .name = "cx88-dvb", .id_table = cx8802_pci_tbl, .probe = dvb_probe, .remove = __devexit_p(dvb_remove), .suspend = cx8802_suspend_common, .resume = cx8802_resume_common, }; static int dvb_init(void) { printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, CX88_VERSION_CODE & 0xff); #ifdef SNAPSHOT printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif return pci_register_driver(&dvb_pci_driver); } static void dvb_fini(void) { pci_unregister_driver(&dvb_pci_driver); } module_init(dvb_init); module_exit(dvb_fini);
int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, int pixel_format) { struct sram_channel *sram_ch; u32 tmp; int retval = 0; int err = 0; int data_frame_size = 0; int risc_buffer_size = 0; int str_length = 0; if (dev->_is_running_ch2) { pr_info("Video Channel is still running so return!\n"); return 0; } dev->_channel2_upstream_select = channel_select; sram_ch = dev->channels[channel_select].sram_channels; INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2); dev->_irq_queues_ch2 = create_singlethread_workqueue("cx25821_workqueue2"); if (!dev->_irq_queues_ch2) { pr_err("create_singlethread_workqueue() for Video FAILED!\n"); return -ENOMEM; } /* * 656/VIP SRC Upstream Channel I & J and 7 - * Host Bus Interface for channel A-C */ tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); dev->_is_running_ch2 = 0; dev->_frame_count_ch2 = 0; dev->_file_status_ch2 = RESET_STATUS; dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; dev->_pixel_format_ch2 = pixel_format; dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; risc_buffer_size = dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; if (dev->input_filename_ch2) { str_length = strlen(dev->input_filename_ch2); dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_filename_ch2) goto error; memcpy(dev->_filename_ch2, dev->input_filename_ch2, str_length + 1); } else { str_length = strlen(dev->_defaultname_ch2); dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_filename_ch2) goto error; memcpy(dev->_filename_ch2, dev->_defaultname_ch2, str_length + 1); } /* Default if filename is empty string */ if (strcmp(dev->input_filename_ch2, "") == 0) { if (dev->_isNTSC_ch2) { dev->_filename_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? "/root/vid411.yuv" : "/root/vidtest.yuv"; } else { dev->_filename_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? "/root/pal411.yuv" : "/root/pal422.yuv"; } } retval = cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size_ch2, 0); /* setup fifo + format */ cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2); dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2; dev->upstream_databuf_size_ch2 = data_frame_size * 2; /* Allocating buffers and prepare RISC program */ retval = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, dev->_line_size_ch2); if (retval < 0) { pr_err("%s: Failed to set up Video upstream buffers!\n", dev->name); goto error; } cx25821_start_video_dma_upstream_ch2(dev, sram_ch); return 0; error: cx25821_dev_unregister(dev); return err; }
static int philips_fmd1216_pll_init(struct dvb_frontend *fe) { struct cx8802_dev *dev= fe->dvb->priv; /* this message is to set up ATC and ALC */ static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; int err; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { if (err < 0) return err; else return -EREMOTEIO; } return 0; } static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct cx8802_dev *dev= fe->dvb->priv; u8 buf[4]; struct i2c_msg msg = { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; int err; /* Switch PLL to DVB mode */ err = philips_fmd1216_pll_init(fe); if (err) return err; /* Tune PLL */ dvb_pll_configure(dev->core->pll_desc, buf, params->frequency, params->u.ofdm.bandwidth); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { printk(KERN_WARNING "cx88-dvb: %s error " "(addr %02x <- %02x, err = %i)\n", __FUNCTION__, dev->core->pll_addr, buf[0], err); if (err < 0) return err; else return -EREMOTEIO; } return 0; } static struct mt352_config dntv_live_dvbt_pro_config = { .demod_address = 0x0f, .no_tuner = 1, .demod_init = dntv_live_dvbt_pro_demod_init, }; #endif static struct zl10353_config dvico_fusionhdtv_hybrid = { .demod_address = 0x0f, .no_tuner = 1, }; static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { .demod_address = 0x0f, }; static struct cx22702_config connexant_refboard_config = { .demod_address = 0x43, .output_mode = CX22702_SERIAL_OUTPUT, }; static struct cx22702_config hauppauge_hvr_config = { .demod_address = 0x63, .output_mode = CX22702_SERIAL_OUTPUT, }; static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } static struct or51132_config pchdtv_hd3000 = { .demod_address = 0x15, .set_ts_params = or51132_set_ts_param, }; static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; dprintk(1, "%s: index = %d\n", __FUNCTION__, index); if (index == 0) cx_clear(MO_GP0_IO, 8); else cx_set(MO_GP0_IO, 8); return 0; } static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; if (is_punctured) dev->ts_gen_cntrl |= 0x04; else dev->ts_gen_cntrl &= ~0x04; return 0; } static struct lgdt330x_config fusionhdtv_3_gold = { .demod_address = 0x0e, .demod_chip = LGDT3302, .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ .set_ts_params = lgdt330x_set_ts_param, }; static struct lgdt330x_config fusionhdtv_5_gold = { .demod_address = 0x0e, .demod_chip = LGDT3303, .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ .set_ts_params = lgdt330x_set_ts_param, }; static struct lgdt330x_config pchdtv_hd5500 = { .demod_address = 0x59, .demod_chip = LGDT3303, .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ .set_ts_params = lgdt330x_set_ts_param, }; static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; return 0; } static int nxt200x_set_pll_input(u8* buf, int input) { if (input) buf[3] |= 0x08; else buf[3] &= ~0x08; return 0; } static struct nxt200x_config ati_hdtvwonder = { .demod_address = 0x0a, .set_pll_input = nxt200x_set_pll_input, .set_ts_params = nxt200x_set_ts_param, }; static int cx24123_set_ts_param(struct dvb_frontend* fe, int is_punctured) { struct cx8802_dev *dev= fe->dvb->priv; dev->ts_gen_cntrl = 0x02; return 0; } static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; if (voltage == SEC_VOLTAGE_OFF) cx_write(MO_GP0_IO, 0x000006fb); else cx_write(MO_GP0_IO, 0x000006f9); if (core->prev_set_voltage) return core->prev_set_voltage(fe, voltage); return 0; } static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; if (voltage == SEC_VOLTAGE_OFF) { dprintk(1,"LNB Voltage OFF\n"); cx_write(MO_GP0_IO, 0x0000efff); } if (core->prev_set_voltage) return core->prev_set_voltage(fe, voltage); return 0; } static struct cx24123_config geniatech_dvbs_config = { .demod_address = 0x55, .set_ts_params = cx24123_set_ts_param, }; static struct cx24123_config hauppauge_novas_config = { .demod_address = 0x55, .set_ts_params = cx24123_set_ts_param, }; static struct cx24123_config kworld_dvbs_100_config = { .demod_address = 0x15, .set_ts_params = cx24123_set_ts_param, .lnb_polarity = 1, }; static int dvb_register(struct cx8802_dev *dev) { /* init struct videobuf_dvb */ dev->dvb.name = dev->core->name; dev->ts_gen_cntrl = 0x0c; /* init frontend */ switch (dev->core->board) { case CX88_BOARD_HAUPPAUGE_DVB_T1: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_dtt759x); } break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = dvb_attach(cx22702_attach, &connexant_refboard_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, &dev->core->i2c_adap, &dvb_pll_thomson_dtt7579); } break; case CX88_BOARD_WINFAST_DTV2000H: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_fmd1216me); } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, &dvb_pll_thomson_dtt7579); break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, NULL, &dvb_pll_thomson_dtt7579); } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* The tin box says DEE1601, but it seems to be DTT7579 * compatible, with a slightly different MT352 AGC gain. */ dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv_dual, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_thomson_dtt7579); break; } /* ZL10353 replaces MT352 on later cards */ dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_plus_v1_1, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_thomson_dtt7579); } break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: dev->dvb.frontend = dvb_attach(mt352_attach, &dvico_fusionhdtv, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_lg_z201); } break; case CX88_BOARD_KWORLD_DVB_T: case CX88_BOARD_DNTV_LIVE_DVB_T: case CX88_BOARD_ADSTECH_DVB_T_PCI: dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_unknown_1); } break; case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: #ifdef HAVE_VP3054_I2C dev->core->pll_addr = 0x61; dev->core->pll_desc = &dvb_pll_fmd1216me; dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, &((struct vp3054_i2c_state *)dev->card_priv)->adap); if (dev->dvb.frontend != NULL) { dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params; } #else printk("%s: built without vp3054 support\n", dev->core->name); #endif break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: dev->dvb.frontend = dvb_attach(zl10353_attach, &dvico_fusionhdtv_hybrid, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_fe6600); } break; case CX88_BOARD_PCHDTV_HD3000: dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_dtt761x); } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); /* Select RF connector callback */ fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_microtune_4042); } } break; case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 9); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_3_gold, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_thomson_dtt761x); } } break; case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_gold, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(lgh06xf_attach, dev->dvb.frontend, &dev->core->i2c_adap); } } break; case CX88_BOARD_PCHDTV_HD5500: dev->ts_gen_cntrl = 0x08; { /* Do a hardware reset of chip before using it. */ struct cx88_core *core = dev->core; cx_clear(MO_GP0_IO, 1); mdelay(100); cx_set(MO_GP0_IO, 1); mdelay(200); dev->dvb.frontend = dvb_attach(lgdt330x_attach, &pchdtv_hd5500, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(lgh06xf_attach, dev->dvb.frontend, &dev->core->i2c_adap); } } break; case CX88_BOARD_ATI_HDTVWONDER: dev->dvb.frontend = dvb_attach(nxt200x_attach, &ati_hdtvwonder, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, NULL, &dvb_pll_tuv1236d); } break; case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: dev->dvb.frontend = dvb_attach(cx24123_attach, &hauppauge_novas_config, &dev->core->i2c_adap); if (dev->dvb.frontend) { dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->core->i2c_adap, 0x08, 0x00, 0x00); } break; case CX88_BOARD_KWORLD_DVBS_100: dev->dvb.frontend = dvb_attach(cx24123_attach, &kworld_dvbs_100_config, &dev->core->i2c_adap); if (dev->dvb.frontend) { dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; } break; case CX88_BOARD_GENIATECH_DVBS: dev->dvb.frontend = dvb_attach(cx24123_attach, &geniatech_dvbs_config, &dev->core->i2c_adap); if (dev->dvb.frontend) { dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; } break; case CX88_BOARD_HAUPPAUGE_HVR1300: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_fmd1216me); } break; case CX88_BOARD_HAUPPAUGE_HVR3000: dev->dvb.frontend = dvb_attach(cx22702_attach, &hauppauge_hvr_config, &dev->core->i2c_adap); if (dev->dvb.frontend != NULL) { dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->core->i2c_adap, &dvb_pll_fmd1216me); } break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->core->name); break; } if (NULL == dev->dvb.frontend) { printk("%s: frontend initialization failed\n",dev->core->name); return -1; } if (dev->core->pll_desc) { dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; } /* Ensure all frontends negotiate bus access */ dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; /* Put the analog decoder in standby to keep it quiet */ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); } /* ----------------------------------------------------------- */ /* CX8802 MPEG -> mini driver - We have been given the hardware */ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __FUNCTION__); switch (core->board) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* We arrive here with either the cx23416 or the cx22702 * on the bus. Take the bus from the cx23416 and enable the * cx22702 demod */ cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ cx_clear(MO_GP0_IO, 0x00000004); udelay(1000); break; default: err = -ENODEV; } return err; } /* CX8802 MPEG -> mini driver - We no longer have the hardware */ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; dprintk( 1, "%s\n", __FUNCTION__); switch (core->board) { case CX88_BOARD_HAUPPAUGE_HVR1300: /* Do Nothing, leave the cx22702 on the bus. */ break; default: err = -ENODEV; } return err; } static int cx8802_dvb_probe(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; struct cx8802_dev *dev = drv->core->dvbdev; int err; dprintk( 1, "%s\n", __FUNCTION__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->board, core->name, core->pci_bus, core->pci_slot); err = -ENODEV; if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) goto fail_core; #ifdef HAVE_VP3054_I2C err = vp3054_i2c_probe(dev); if (0 != err) goto fail_core; #endif /* dvb stuff */ printk("%s/2: cx2388x based dvb card\n", core->name); videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, dev->pci, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, sizeof(struct cx88_buffer), dev); err = dvb_register(dev); if (err != 0) printk("%s dvb_register failed err = %d\n", __FUNCTION__, err); fail_core: return err; } static int cx8802_dvb_remove(struct cx8802_driver *drv) { struct cx8802_dev *dev = drv->core->dvbdev; /* dvb */ videobuf_dvb_unregister(&dev->dvb); #ifdef HAVE_VP3054_I2C vp3054_i2c_remove(dev); #endif return 0; } static struct cx8802_driver cx8802_dvb_driver = { .type_id = CX88_MPEG_DVB, .hw_access = CX8802_DRVCTL_SHARED, .probe = cx8802_dvb_probe, .remove = cx8802_dvb_remove, .advise_acquire = cx8802_dvb_advise_acquire, .advise_release = cx8802_dvb_advise_release, }; static int dvb_init(void) { printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, CX88_VERSION_CODE & 0xff); #ifdef SNAPSHOT printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif return cx8802_register_driver(&cx8802_dvb_driver); } static void dvb_fini(void) { cx8802_unregister_driver(&cx8802_dvb_driver); } module_init(dvb_init); module_exit(dvb_fini);
int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num, u32 status) { u32 int_msk_tmp; struct sram_channel *channel = &dev->sram_channels[chan_num]; int singlefield_lines = NTSC_FIELD_HEIGHT; int line_size_in_bytes = Y422_LINE_SZ; int odd_risc_prog_size = 0; dma_addr_t risc_phys_jump_addr; __le32 *rp; if (status & FLD_VID_SRC_RISC1) { // We should only process one program per call u32 prog_cnt = cx_read(channel->gpcnt); //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers int_msk_tmp = cx_read(channel->int_msk); cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); cx_write(channel->int_stat, _intr_msk); spin_lock(&dev->slock); dev->_frame_index_ch2 = prog_cnt; queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2); if (dev->_is_first_frame_ch2) { dev->_is_first_frame_ch2 = 0; if (dev->_isNTSC_ch2) { singlefield_lines += 1; odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; } else { singlefield_lines = PAL_FIELD_HEIGHT; odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; } if (dev->_dma_virt_start_addr_ch2 != NULL) { line_size_in_bytes = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 + odd_risc_prog_size; rp = cx25821_update_riscprogram_ch2(dev, dev-> _dma_virt_start_addr_ch2, TOP_OFFSET, line_size_in_bytes, 0x0, singlefield_lines, FIFO_DISABLE, ODD_FIELD); // Jump to Even Risc program of 1st Frame *(rp++) = cpu_to_le32(RISC_JUMP); *(rp++) = cpu_to_le32(risc_phys_jump_addr); *(rp++) = cpu_to_le32(0); } } spin_unlock(&dev->slock); } if (dev->_file_status_ch2 == END_OF_FILE) { printk("cx25821: EOF Channel 2 Framecount = %d\n", dev->_frame_count_ch2); return -1; } //ElSE, set the interrupt mask register, re-enable irq. int_msk_tmp = cx_read(channel->int_msk); cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); return 0; }
int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format) { struct cx25821_video_out_data *out = chan->out; struct cx25821_dev *dev = chan->dev; const struct sram_channel *sram_ch; u32 tmp; int err = 0; int data_frame_size = 0; int risc_buffer_size = 0; if (out->_is_running) { pr_info("Video Channel is still running so return!\n"); return 0; } sram_ch = chan->sram_channels; out->is_60hz = dev->tvnorm & V4L2_STD_525_60; /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for * channel A-C */ tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); out->_is_running = 0; out->_frame_count = 0; out->_file_status = RESET_STATUS; out->_lines_count = out->is_60hz ? 480 : 576; out->_pixel_format = pixel_format; out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; data_frame_size = out->is_60hz ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; risc_buffer_size = out->is_60hz ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; out->_is_running = 0; out->_frame_count = 0; out->_file_status = RESET_STATUS; out->_lines_count = out->is_60hz ? 480 : 576; out->_pixel_format = pixel_format; out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; out->curpos = 0; init_waitqueue_head(&out->waitq); err = cx25821_sram_channel_setup_upstream(dev, sram_ch, out->_line_size, 0); /* setup fifo + format */ cx25821_set_pixelengine(chan, sram_ch, out->_pixel_format); out->upstream_riscbuf_size = risc_buffer_size * 2; out->upstream_databuf_size = data_frame_size * 2; /* Allocating buffers and prepare RISC program */ err = cx25821_upstream_buffer_prepare(chan, sram_ch, out->_line_size); if (err < 0) { pr_err("%s: Failed to set up Video upstream buffers!\n", dev->name); goto error; } cx25821_start_video_dma_upstream(chan, sram_ch); return 0; error: cx25821_dev_unregister(dev); return err; }