/** * __fimc_pipeline_open - update the pipeline information, enable power * of all pipeline subdevs and the sensor clock * @me: media entity to start graph walk with * @prepare: true to walk the current pipeline and acquire all subdevs * * Called with the graph mutex held. */ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, struct media_entity *me, bool prepare) { struct fimc_md *fmd = entity_to_fimc_mdev(me); struct fimc_pipeline *p = to_fimc_pipeline(ep); struct v4l2_subdev *sd; if (WARN_ON(p == NULL || me == NULL)) return -EINVAL; if (prepare) fimc_pipeline_prepare(p, me); sd = p->subdevs[IDX_SENSOR]; if (sd == NULL) { pr_warn("%s(): No sensor subdev\n", __func__); /* * Pipeline open cannot fail so as to make it possible * for the user space to configure the pipeline. */ return 0; } return __fimc_pipeline_enable(ep, fmd); }
/** * __fimc_pipeline_open - update the pipeline information, enable power * of all pipeline subdevs and the sensor clock * @me: media entity to start graph walk with * @prepare: true to walk the current pipeline and acquire all subdevs * * Called with the graph mutex held. */ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, struct media_entity *me, bool prepare) { struct fimc_md *fmd = entity_to_fimc_mdev(me); struct fimc_pipeline *p = to_fimc_pipeline(ep); struct v4l2_subdev *sd; int ret; if (WARN_ON(p == NULL || me == NULL)) return -EINVAL; if (prepare) fimc_pipeline_prepare(p, me); sd = p->subdevs[IDX_SENSOR]; if (sd == NULL) return -EINVAL; /* Disable PXLASYNC clock if this pipeline includes FIMC-IS */ if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) { ret = clk_prepare_enable(fmd->wbclk[CLK_IDX_WB_B]); if (ret < 0) return ret; } ret = fimc_pipeline_s_power(p, 1); if (!ret) return 0; if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); return ret; }
/** * __fimc_pipeline_initialize - update the pipeline information, enable power * of all pipeline subdevs and the sensor clock * @me: media entity to start graph walk with * @prep: true to acquire sensor (and csis) subdevs * * This function must be called with the graph mutex held. */ static int __fimc_pipeline_initialize(struct fimc_dev *fimc, struct media_entity *me, bool prep) { int ret; if (prep) fimc_pipeline_prepare(fimc, me); if (fimc->pipeline.sensor == NULL) return -EINVAL; ret = fimc_md_set_camclk(fimc->pipeline.sensor, true); if (ret) return ret; return fimc_pipeline_s_power(fimc, 1); }
/** * __fimc_pipeline_open - update the pipeline information, enable power * of all pipeline subdevs and the sensor clock * @me: media entity to start graph walk with * @prep: true to acquire sensor (and csis) subdevs * * This function must be called with the graph mutex held. */ static int __fimc_pipeline_open(struct fimc_pipeline *p, struct media_entity *me, bool prep) { int ret; if (prep) fimc_pipeline_prepare(p, me); if (p->subdevs[IDX_SENSOR] == NULL) return -EINVAL; ret = fimc_md_set_camclk(p->subdevs[IDX_SENSOR], true); if (ret) return ret; return fimc_pipeline_s_power(p, 1); }
/** * __fimc_pipeline_s_stream - call s_stream() on pipeline subdevs * @pipeline: video pipeline structure * @on: passed as the s_stream() callback argument */ static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on) { static const u8 seq[2][IDX_MAX] = { { IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE }, { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP }, }; struct fimc_pipeline *p = to_fimc_pipeline(ep); struct fimc_md *fmd = entity_to_fimc_mdev(&p->subdevs[IDX_CSIS]->entity); enum fimc_subdev_index sd_id; int i, ret = 0; if (p->subdevs[IDX_SENSOR] == NULL) { if (!fmd->user_subdev_api) { /* * Sensor must be already discovered if we * aren't in the user_subdev_api mode */ return -ENODEV; } /* Get pipeline sink entity */ if (p->subdevs[IDX_FIMC]) sd_id = IDX_FIMC; else if (p->subdevs[IDX_IS_ISP]) sd_id = IDX_IS_ISP; else if (p->subdevs[IDX_FLITE]) sd_id = IDX_FLITE; else return -ENODEV; /* * Sensor could have been linked between open and STREAMON - * check if this is the case. */ fimc_pipeline_prepare(p, &p->subdevs[sd_id]->entity); if (p->subdevs[IDX_SENSOR] == NULL) return -ENODEV; ret = __fimc_pipeline_enable(ep, fmd); if (ret < 0) return ret; } for (i = 0; i < IDX_MAX; i++) { unsigned int idx = seq[on][i]; ret = v4l2_subdev_call(p->subdevs[idx], video, s_stream, on); if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) goto error; } return 0; error: fimc_pipeline_s_power(p, !on); for (; i >= 0; i--) { unsigned int idx = seq[on][i]; v4l2_subdev_call(p->subdevs[idx], video, s_stream, !on); } return ret; }