static int video_begin(struct saa7146_fh *fh)
{
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_vv *vv = dev->vv_data;
	struct saa7146_format *fmt = NULL;
	unsigned int resource;
	int ret = 0, err = 0;

	DEB_EE(("dev:%p, fh:%p\n",dev,fh));

	if ((vv->video_status & STATUS_CAPTURE) != 0) {
		if (vv->video_fh == fh) {
			DEB_S(("already capturing.\n"));
			return 0;
		}
		DEB_S(("already capturing in another open.\n"));
		return -EBUSY;
	}

	if ((vv->video_status & STATUS_OVERLAY) != 0) {
		DEB_S(("warning: suspending overlay video for streaming capture.\n"));
		vv->ov_suspend = vv->video_fh;
		err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
		if (0 != err) {
			DEB_D(("suspending video failed. aborting\n"));
			return err;
		}
	}

	fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
	/* we need to have a valid format set here */
	BUG_ON(NULL == fmt);

	if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
		resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
	} else {
		resource = RESOURCE_DMA1_HPS;
	}

	ret = saa7146_res_get(fh, resource);
	if (0 == ret) {
		DEB_S(("cannot get capture resource %d\n",resource));
		if (vv->ov_suspend != NULL) {
			saa7146_start_preview(vv->ov_suspend);
			vv->ov_suspend = NULL;
		}
		return -EBUSY;
	}

	/* clear out beginning of streaming bit (rps register 0)*/
	saa7146_write(dev, MC2, MASK_27 );

	/* enable rps0 irqs */
	SAA7146_IER_ENABLE(dev, MASK_27);

	vv->video_fh = fh;
	vv->video_status = STATUS_CAPTURE;

	return 0;
}
Beispiel #2
0
static int vbi_open(struct saa7146_dev *dev, struct file *file)
{
    struct saa7146_fh *fh = file->private_data;

    u32 arbtr_ctrl	= saa7146_read(dev, PCI_BT_V1);
    int ret = 0;

    DEB_VBI(("dev:%p, fh:%p\n",dev,fh));

    ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
    if (0 == ret) {
        DEB_S(("cannot get vbi RESOURCE_DMA3_BRS resource\n"));
        return -EBUSY;
    }

    /* adjust arbitrition control for video dma 3 */
    arbtr_ctrl &= ~0x1f0000;
    arbtr_ctrl |=  0x1d0000;
    saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
    saa7146_write(dev, MC2, (MASK_04|MASK_20));

    memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));

    fh->vbi_fmt.sampling_rate	= 27000000;
    fh->vbi_fmt.offset		= 248; /* todo */
    fh->vbi_fmt.samples_per_line	= vbi_pixel_to_capture;
    fh->vbi_fmt.sample_format	= V4L2_PIX_FMT_GREY;

    fh->vbi_fmt.start[0] = 5;
    fh->vbi_fmt.count[0] = 16;
    fh->vbi_fmt.start[1] = 312;
    fh->vbi_fmt.count[1] = 16;

    videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
                           &dev->pci->dev, &dev->slock,
                           V4L2_BUF_TYPE_VBI_CAPTURE,
                           V4L2_FIELD_SEQ_TB,
                           sizeof(struct saa7146_buf),
                           file);

    init_timer(&fh->vbi_read_timeout);
    fh->vbi_read_timeout.function = vbi_read_timeout;
    fh->vbi_read_timeout.data = (unsigned long)file;

    /* initialize the brs */
    if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
        saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
    } else {
        saa7146_write(dev, BRS_CTRL, 0x00000001);

        if (0 != (ret = vbi_workaround(dev))) {
            DEB_VBI(("vbi workaround failed!\n"));
            /* return ret;*/
        }
    }

    /* upload brs register */
    saa7146_write(dev, MC2, (MASK_08|MASK_24));
    return 0;
}
int saa7146_start_preview(struct saa7146_fh *fh)
{
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_vv *vv = dev->vv_data;
	struct v4l2_format fmt;
	int ret = 0, err = 0;

	DEB_EE("dev:%p, fh:%p\n", dev, fh);

	/* check if we have overlay information */
	if (vv->ov.fh == NULL) {
		DEB_D("no overlay data available. try S_FMT first.\n");
		return -EAGAIN;
	}

	/* check if streaming capture is running */
	if (IS_CAPTURE_ACTIVE(fh) != 0) {
		DEB_D("streaming capture is active\n");
		return -EBUSY;
	}

	/* check if overlay is running */
	if (IS_OVERLAY_ACTIVE(fh) != 0) {
		if (vv->video_fh == fh) {
			DEB_D("overlay is already active\n");
			return 0;
		}
		DEB_D("overlay is already active in another open\n");
		return -EBUSY;
	}

	if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
		DEB_D("cannot get necessary overlay resources\n");
		return -EBUSY;
	}

	fmt.fmt.win = vv->ov.win;
	err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
	if (0 != err) {
		saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
		return -EBUSY;
	}
	vv->ov.win = fmt.fmt.win;

	DEB_D("%dx%d+%d+%d %s field=%s\n",
	      vv->ov.win.w.width, vv->ov.win.w.height,
	      vv->ov.win.w.left, vv->ov.win.w.top,
	      vv->ov_fmt->name, v4l2_field_names[vv->ov.win.field]);

	if (0 != (ret = saa7146_enable_overlay(fh))) {
		DEB_D("enabling overlay failed: %d\n", ret);
		saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
		return ret;
	}

	vv->video_status = STATUS_OVERLAY;
	vv->video_fh = fh;

	return 0;
}
Beispiel #4
0
static int vbi_open(struct saa7146_dev *dev, struct file *file)
{
	struct saa7146_fh *fh = file->private_data;
	struct saa7146_vv *vv = fh->dev->vv_data;

	u32 arbtr_ctrl	= saa7146_read(dev, PCI_BT_V1);
	int ret = 0;

	DEB_VBI("dev:%p, fh:%p\n", dev, fh);

	ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
	if (0 == ret) {
		DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n");
		return -EBUSY;
	}

	/* adjust arbitrition control for video dma 3 */
	arbtr_ctrl &= ~0x1f0000;
	arbtr_ctrl |=  0x1d0000;
	saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
	saa7146_write(dev, MC2, (MASK_04|MASK_20));

	videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
			    &dev->pci->dev, &dev->slock,
			    V4L2_BUF_TYPE_VBI_CAPTURE,
			    V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
			    sizeof(struct saa7146_buf),
			    file, &dev->v4l2_lock);

	vv->vbi_read_timeout.function = vbi_read_timeout;
	vv->vbi_read_timeout.data = (unsigned long)file;

	/* initialize the brs */
	if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
		saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
	} else {
		saa7146_write(dev, BRS_CTRL, 0x00000001);

		if (0 != (ret = vbi_workaround(dev))) {
			DEB_VBI("vbi workaround failed!\n");
			/* return ret;*/
		}
	}

	/* upload brs register */
	saa7146_write(dev, MC2, (MASK_08|MASK_24));
	return 0;
}