diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 0f4b325f2d89030026c8ab49afdf3146aaaa6a43..6ebf58724a0134d27737b015a0acced695252ce0 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -73,6 +73,7 @@ struct cx23885_board cx23885_boards[] = { [CX23885_BOARD_HAUPPAUGE_HVR1800] = { .name = "Hauppauge WinTV-HVR1800", .porta = CX23885_ANALOG_VIDEO, + .portb = CX23885_MPEG_ENCODER, .portc = CX23885_MPEG_DVB, .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = 0x42, /* 0x84 >> 1 */ @@ -336,6 +337,10 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) /* 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); @@ -443,10 +448,25 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; + case CX23885_BOARD_HAUPPAUGE_HVR1800: + /* Defaults for VID B - Analog encoder */ + /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */ + ts1->gen_ctrl_val = 0x10e; + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + + /* APB_TSVALERR_POL (active low)*/ + ts1->vld_misc_val = 0x2000; + ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc); + + /* Defaults for VID C */ + ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1200: case CX23885_BOARD_HAUPPAUGE_HVR1700: diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 7f7446a76465b4a11e6c0ff83f9c1342baf4d118..f24abcd06dea0eb1027630be34ca934daa87d6e8 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -1037,6 +1037,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, struct cx23885_buffer *buf) { struct cx23885_dev *dev = port->dev; + u32 reg; dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, buf->vb.width, buf->vb.height, buf->vb.field); @@ -1062,6 +1063,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port, return -EINVAL; } + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) + cx23885_av_clk(dev, 0); + udelay(100); /* If the port supports SRC SELECT, configure it */ @@ -1079,6 +1083,21 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_write(port->reg_gpcnt_ctl, 3); q->count = 1; + if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + + reg = cx_read(PAD_CTRL); + reg = reg & ~0x1; /* Clear TS1_OE */ + + /* FIXME, bit 2 writing here is questionable */ + /* set TS1_SOP_OE and TS1_OE_HI */ + reg = reg | 0xa; + cx_write(PAD_CTRL, reg); + + /* FIXME and these two registers should be documented. */ + cx_write(CLK_DELAY, cx_read(CLK_DELAY) | 0x80000011); + cx_write(ALT_PIN_OUT_SEL, 0x10100045); + } + switch(dev->bridge) { case CX23885_BRIDGE_885: case CX23885_BRIDGE_887: @@ -1094,6 +1113,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) + cx23885_av_clk(dev, 1); + if (debug > 4) cx23885_tsport_reg_dump(port); @@ -1103,12 +1125,32 @@ static int cx23885_start_dma(struct cx23885_tsport *port, static int cx23885_stop_dma(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; + u32 reg; + dprintk(1, "%s()\n", __func__); /* Stop interrupts and DMA */ cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); cx_clear(port->reg_dma_ctl, port->dma_ctl_val); + if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + + reg = cx_read(PAD_CTRL); + + /* Set TS1_OE */ + reg = reg | 0x1; + + /* clear TS1_SOP_OE and TS1_OE_HI */ + reg = reg & ~0xa; + cx_write(PAD_CTRL, reg); + cx_write(port->reg_src_sel, 0); + cx_write(port->reg_gen_ctrl, 8); + + } + + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) + cx23885_av_clk(dev, 0); + return 0; } @@ -1525,7 +1567,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " "latency: %d, mmio: 0x%llx\n", dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev,0)); + dev->pci_lat, + (unsigned long long)pci_resource_start(pci_dev, 0)); pci_set_master(pci_dev); if (!pci_dma_supported(pci_dev, 0xffffffff)) { diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 3928945df5f58aadfaf7933fdd2d3755796e612b..c6bb0a05bc1c147fd61527ab3a47bdf790577924 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -423,6 +423,29 @@ int cx23885_i2c_unregister(struct cx23885_i2c *bus) return 0; } +void cx23885_av_clk(struct cx23885_dev *dev, int enable) +{ + /* write 0 to bus 2 addr 0x144 via i2x_xfer() */ + char buffer[3]; + struct i2c_msg msg; + dprintk(1, "%s(enabled = %d)\n", __func__, enable); + + /* Register 0x144 */ + buffer[0] = 0x01; + buffer[1] = 0x44; + if (enable == 1) + buffer[2] = 0x05; + else + buffer[2] = 0x00; + + msg.addr = 0x44; + msg.flags = I2C_M_TEN; + msg.len = 3; + msg.buf = buffer; + + i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1); +} + /* ----------------------------------------------------------------------- */ /* diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index e42b6878ba239081e723d451d6fd028de7fb312c..32af87f25e7bbb769a711d1bd6cf125e1bfd3a39 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -446,6 +446,7 @@ extern int cx23885_i2c_register(struct cx23885_i2c *bus); extern int cx23885_i2c_unregister(struct cx23885_i2c *bus); extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, void *arg); +extern void cx23885_av_clk(struct cx23885_dev *dev, int enable); /* ----------------------------------------------------------- */ /* cx23885-417.c */