summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/drivers/media/common/saa7146_fops.c11
-rw-r--r--linux/drivers/media/common/saa7146_hlp.c40
-rw-r--r--linux/drivers/media/common/saa7146_video.c8
3 files changed, 48 insertions, 11 deletions
diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c
index 008c02567..314144245 100644
--- a/linux/drivers/media/common/saa7146_fops.c
+++ b/linux/drivers/media/common/saa7146_fops.c
@@ -106,10 +106,21 @@ void saa7146_buffer_next(struct saa7146_dev *dev,
// fixme: fix this for vflip != 0
saa7146_write(dev, PROT_ADDR1, 0);
+ saa7146_write(dev, MC2, (MASK_02|MASK_18));
+
/* write the address of the rps-program */
saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
/* turn on rps */
saa7146_write(dev, MC1, (MASK_12 | MASK_28));
+
+/*
+ printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
+ printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
+ printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
+ printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
+ printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1));
+ printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
+*/
}
del_timer(&q->timeout);
}
diff --git a/linux/drivers/media/common/saa7146_hlp.c b/linux/drivers/media/common/saa7146_hlp.c
index 6f1912855..e0bb62bb3 100644
--- a/linux/drivers/media/common/saa7146_hlp.c
+++ b/linux/drivers/media/common/saa7146_hlp.c
@@ -242,7 +242,9 @@ static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field
if( 2*out_y >= in_y) {
lpi = 1;
}
- } else if (field == V4L2_FIELD_TOP || field == V4L2_FIELD_BOTTOM) {
+ } else if (field == V4L2_FIELD_TOP
+ || field == V4L2_FIELD_ALTERNATE
+ || field == V4L2_FIELD_BOTTOM) {
if( 4*out_y >= in_y ) {
lpi = 1;
}
@@ -468,9 +470,7 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
*clip_format &= 0xfffffff7;
if (V4L2_FIELD_HAS_BOTH(field)) {
*clip_format |= 0x00000008;
- } else if (field == V4L2_FIELD_TOP) {
- *clip_format |= 0x00000000;
- } else if (field == V4L2_FIELD_BOTTOM) {
+ } else {
*clip_format |= 0x00000000;
}
}
@@ -593,6 +593,10 @@ static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int
}
if (V4L2_FIELD_HAS_BOTH(field)) {
+ } else if (field == V4L2_FIELD_ALTERNATE) {
+ /* fixme */
+ vdma1.base_odd = vdma1.prot_addr;
+ vdma1.pitch /= 2;
} else if (field == V4L2_FIELD_TOP) {
vdma1.base_odd = vdma1.prot_addr;
vdma1.pitch /= 2;
@@ -760,6 +764,10 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
}
if (V4L2_FIELD_HAS_BOTH(field)) {
+ } else if (field == V4L2_FIELD_ALTERNATE) {
+ /* fixme */
+ vdma1.base_odd = vdma1.prot_addr;
+ vdma1.pitch /= 2;
} else if (field == V4L2_FIELD_TOP) {
vdma1.base_odd = vdma1.prot_addr;
vdma1.pitch /= 2;
@@ -896,6 +904,14 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71
}
if (V4L2_FIELD_HAS_BOTH(field)) {
+ } else if (field == V4L2_FIELD_ALTERNATE) {
+ /* fixme */
+ vdma1.base_odd = vdma1.prot_addr;
+ vdma1.pitch /= 2;
+ vdma2.base_odd = vdma2.prot_addr;
+ vdma2.pitch /= 2;
+ vdma3.base_odd = vdma3.prot_addr;
+ vdma3.pitch /= 2;
} else if (field == V4L2_FIELD_TOP) {
vdma1.base_odd = vdma1.prot_addr;
vdma1.pitch /= 2;
@@ -946,11 +962,11 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
o_wait = tmp;
}
- /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 0 is not set*/
+ /* wait for o_fid_a/b / e_fid_a/b toggle only if rps register 0 is not set*/
WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait);
WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait);
- /* set bit 0 */
+ /* set rps register 0 */
WRITE_RPS0(CMD_WR_REG | (1 << 8) | (MC2/4));
WRITE_RPS0(MASK_27 | MASK_11);
@@ -1000,9 +1016,17 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
{
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
-
+ u32 vdma1_prot_addr;
+
DEB_CAP(("buf:%p, next:%p\n",buf,next));
+ vdma1_prot_addr = saa7146_read(dev, PROT_ADDR1);
+ if( 0 == vdma1_prot_addr ) {
+ /* clear out beginning of streaming bit (rps register 0)*/
+ DEB_CAP(("forcing sync to new frame\n"));
+ saa7146_write(dev, MC2, MASK_27 );
+ }
+
saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field);
saa7146_set_output_format(dev, sfmt->trans);
saa7146_disable_clipping(dev);
@@ -1014,7 +1038,7 @@ void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struc
calculate_video_dma_grab_packed(dev, buf);
program_capture_engine(dev,0);
}
-
+
/* write the address of the rps-program */
saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c
index 77c20b528..d67282461 100644
--- a/linux/drivers/media/common/saa7146_video.c
+++ b/linux/drivers/media/common/saa7146_video.c
@@ -137,6 +137,7 @@ static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
switch (field) {
case V4L2_FIELD_TOP:
case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_ALTERNATE:
maxh = maxh / 2;
break;
case V4L2_FIELD_INTERLACED:
@@ -188,6 +189,7 @@ static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
switch (field) {
case V4L2_FIELD_TOP:
case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_ALTERNATE:
maxh = maxh / 2;
break;
case V4L2_FIELD_INTERLACED:
@@ -561,7 +563,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
o1 = size%PAGE_SIZE;
o2 = (size+(size/4))%PAGE_SIZE;
- printk("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2);
+ DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
break;
}
case 16: {
@@ -571,7 +573,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
o1 = size%PAGE_SIZE;
o2 = (size+(size/2))%PAGE_SIZE;
- printk("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2);
+ DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
break;
}
default: {
@@ -674,7 +676,7 @@ static int video_begin(struct saa7146_fh *fh)
spin_lock_irqsave(&dev->slock,flags);
- /* clear out beginning of streaming bit */
+ /* clear out beginning of streaming bit (rps register 0)*/
saa7146_write(dev, MC2, MASK_27 );
/* enable rps0 irqs */