/*
 * isp_subdev_init_entities - Initialize V4L2 subdev and media entity
 * @asd: ISP CCDC module
 *
 * Return 0 on success and a negative error code on failure.
 */
static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
{
	struct v4l2_subdev *sd = &asd->subdev;
	struct media_pad *pads = asd->pads;
	struct media_entity *me = &sd->entity;
	int ret;

	asd->input = ATOMISP_SUBDEV_INPUT_NONE;

	v4l2_subdev_init(sd, &isp_subdev_v4l2_ops);
	strlcpy(sd->name, "ATOM ISP SUBDEV", sizeof(sd->name));
	v4l2_set_subdevdata(sd, asd);
	sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;

	pads[ATOMISP_SUBDEV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
	pads[ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW].flags = MEDIA_PAD_FL_SOURCE;
	pads[ATOMISP_SUBDEV_PAD_SOURCE_VF].flags = MEDIA_PAD_FL_SOURCE;
	pads[ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE].flags = MEDIA_PAD_FL_SOURCE;

	asd->fmt[ATOMISP_SUBDEV_PAD_SINK].fmt.code =
		V4L2_MBUS_FMT_SBGGR10_1X10;
	asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW].fmt.code =
		V4L2_MBUS_FMT_SBGGR10_1X10;
	asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_VF].fmt.code =
		V4L2_MBUS_FMT_SBGGR10_1X10;
	asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE].fmt.code =
		V4L2_MBUS_FMT_SBGGR10_1X10;

	me->ops = &isp_subdev_media_ops;
	me->type = MEDIA_ENT_T_V4L2_SUBDEV;
	ret = media_entity_init(me, ATOMISP_SUBDEV_PADS_NUM, pads, 0);
	if (ret < 0)
		return ret;

	atomisp_init_subdev_pipe(asd, &asd->video_in,
			V4L2_BUF_TYPE_VIDEO_OUTPUT);

	atomisp_init_subdev_pipe(asd, &asd->video_out_preview,
			V4L2_BUF_TYPE_VIDEO_CAPTURE);

	atomisp_init_subdev_pipe(asd, &asd->video_out_vf,
			V4L2_BUF_TYPE_VIDEO_CAPTURE);

	atomisp_init_subdev_pipe(asd, &asd->video_out_capture,
			V4L2_BUF_TYPE_VIDEO_CAPTURE);

	ret = atomisp_video_init(&asd->video_in, "MEMORY");
	if (ret < 0)
		return ret;

	ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE");
	if (ret < 0)
		return ret;

	ret = atomisp_video_init(&asd->video_out_vf, "VIEWFINDER");
	if (ret < 0)
		return ret;

	ret = atomisp_video_init(&asd->video_out_preview, "PREVIEW");
	if (ret < 0)
		return ret;

	/* Connect the isp subdev to the video node. */
	ret = media_entity_create_link(&asd->video_in.vdev.entity,
		0, &asd->subdev.entity, ATOMISP_SUBDEV_PAD_SINK, 0);
	if (ret < 0)
		return ret;

	ret = media_entity_create_link(&asd->subdev.entity,
		ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW,
		&asd->video_out_preview.vdev.entity, 0, 0);
	if (ret < 0)
		return ret;

	ret = media_entity_create_link(&asd->subdev.entity,
		ATOMISP_SUBDEV_PAD_SOURCE_VF,
		&asd->video_out_vf.vdev.entity, 0, 0);
	if (ret < 0)
		return ret;

	ret = media_entity_create_link(&asd->subdev.entity,
		ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE,
		&asd->video_out_capture.vdev.entity, 0, 0);
	if (ret < 0)
		return ret;

	ret = v4l2_ctrl_handler_init(&asd->ctrl_handler, 1);
	if (ret)
		return ret;

	asd->fmt_auto = v4l2_ctrl_new_custom(&asd->ctrl_handler,
						    &ctrl_fmt_auto, NULL);
	asd->run_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler,
						    &ctrl_run_mode, NULL);
	asd->vfpp = v4l2_ctrl_new_custom(&asd->ctrl_handler,
						&ctrl_vfpp, NULL);
	asd->continuous_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler,
					     &ctrl_continuous_mode, NULL);
	asd->continuous_viewfinder = v4l2_ctrl_new_custom(&asd->ctrl_handler,
					     &ctrl_continuous_viewfinder,
					     NULL);
	asd->continuous_raw_buffer_size =
			v4l2_ctrl_new_custom(&asd->ctrl_handler,
					     &ctrl_continuous_raw_buffer_size,
					     NULL);

	/* Make controls visible on subdev as well. */
	asd->subdev.ctrl_handler = &asd->ctrl_handler;

	return asd->ctrl_handler.error;
}
Ejemplo n.º 2
0
/*
 * isp_subdev_init_entities - Initialize V4L2 subdev and media entity
 * @isp_subdev: ISP CCDC module
 *
 * Return 0 on success and a negative error code on failure.
 */
static int isp_subdev_init_entities(struct atomisp_sub_device *isp_subdev)
{
    struct v4l2_subdev *sd = &isp_subdev->subdev;
    struct media_pad *pads = isp_subdev->pads;
    struct media_entity *me = &sd->entity;
    int ret;

    isp_subdev->input = ATOMISP_SUBDEV_INPUT_NONE;

    v4l2_subdev_init(sd, &isp_subdev_v4l2_ops);
    strlcpy(sd->name, "ATOM ISP SUBDEV", sizeof(sd->name));
    v4l2_set_subdevdata(sd, isp_subdev);
    sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
    sd->nevents = 16; /* TBD */

    pads[ATOMISP_SUBDEV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
    pads[ATOMISP_SUBDEV_PAD_SOURCE_VF].flags = MEDIA_PAD_FL_SOURCE;
    pads[ATOMISP_SUBDEV_PAD_SOURCE_MO].flags = MEDIA_PAD_FL_SOURCE;

    isp_subdev->formats[ATOMISP_SUBDEV_PAD_SINK].code =
        V4L2_MBUS_FMT_SBGGR10_1X10;
    isp_subdev->formats[ATOMISP_SUBDEV_PAD_SOURCE_VF].code =
        V4L2_MBUS_FMT_SBGGR10_1X10;
    isp_subdev->formats[ATOMISP_SUBDEV_PAD_SOURCE_MO].code =
        V4L2_MBUS_FMT_SBGGR10_1X10;

    me->ops = &isp_subdev_media_ops;
    me->type = MEDIA_ENT_T_V4L2_SUBDEV;
    ret = media_entity_init(me, ATOMISP_SUBDEV_PADS_NUM, pads, 0);
    if (ret < 0)
        return ret;

    isp_subdev->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    isp_subdev->video_in.isp = isp_subdev->isp;
    spin_lock_init(&isp_subdev->video_in.irq_lock);

    isp_subdev->video_out_vf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    isp_subdev->video_out_vf.isp = isp_subdev->isp;
    isp_subdev->video_out_vf.is_main = false;
    spin_lock_init(&isp_subdev->video_out_vf.irq_lock);

    isp_subdev->video_out_mo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    isp_subdev->video_out_mo.isp = isp_subdev->isp;
    isp_subdev->video_out_mo.is_main = true;
    spin_lock_init(&isp_subdev->video_out_mo.irq_lock);

    ret = atomisp_video_init(&isp_subdev->video_in, "MEMORY");
    if (ret < 0)
        return ret;

    ret = atomisp_video_init(&isp_subdev->video_out_mo, "MAINOUTPUT");
    if (ret < 0)
        return ret;

    ret = atomisp_video_init(&isp_subdev->video_out_vf, "VIEWFINDER");
    if (ret < 0)
        return ret;

    /* Connect the isp subdev to the video node. */
    ret = media_entity_create_link(&isp_subdev->video_in.vdev.entity,
                                   0, &isp_subdev->subdev.entity, ATOMISP_SUBDEV_PAD_SINK, 0);
    if (ret < 0)
        return ret;
    ret = media_entity_create_link(&isp_subdev->subdev.entity,
                                   ATOMISP_SUBDEV_PAD_SOURCE_VF,
                                   &isp_subdev->video_out_vf.vdev.entity, 0, 0);
    if (ret < 0)
        return ret;

    ret = media_entity_create_link(&isp_subdev->subdev.entity,
                                   ATOMISP_SUBDEV_PAD_SOURCE_MO,
                                   &isp_subdev->video_out_mo.vdev.entity, 0, 0);
    if (ret < 0)
        return ret;

    return 0;
}