[libcamera-devel,03/13] libcamera: pipeline: rkisp1: Setup links as part of configuration

Message ID 20200813005246.3265807-4-niklas.soderlund@ragnatech.se
State Accepted
Headers show
Series
  • libcamera: pipeline: rkisp1: Extend to support two streams
Related show

Commit Message

Niklas Söderlund Aug. 13, 2020, 12:52 a.m. UTC
In preparation of supporting both the main and self path move all link
setup to be part of the configuration step. The main path is still the
only possible path.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
---
 src/libcamera/pipeline/rkisp1/rkisp1.cpp | 79 +++++++++++++-----------
 1 file changed, 42 insertions(+), 37 deletions(-)

Comments

Jacopo Mondi Aug. 20, 2020, 8:20 a.m. UTC | #1
Hi Niklas,

On Thu, Aug 13, 2020 at 02:52:36AM +0200, Niklas Söderlund wrote:
> In preparation of supporting both the main and self path move all link
all links

> setup to be part of the configuration step. The main path is still the
> only possible path.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> ---
>  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 79 +++++++++++++-----------
>  1 file changed, 42 insertions(+), 37 deletions(-)
>
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index a0e36a44d8d91260..38382a6894dac22a 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -211,7 +211,8 @@ private:
>  	friend RkISP1CameraData;
>  	friend RkISP1Frames;
>
> -	int initLinks();
> +	int initLinks(const Camera *camera,
> +		      const RkISP1CameraConfiguration &config);
>  	int createCamera(MediaEntity *sensor);
>  	void tryCompleteRequest(Request *request);
>  	void bufferReady(FrameBuffer *buffer);
> @@ -601,28 +602,9 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
>  	CameraSensor *sensor = data->sensor_;
>  	int ret;
>
> -	/*
> -	 * Configure the sensor links: enable the link corresponding to this
> -	 * camera and disable all the other sensor links.
> -	 */
> -	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> -
> -	for (MediaLink *link : pad->links()) {
> -		bool enable = link->source()->entity() == sensor->entity();
> -
> -		if (!!(link->flags() & MEDIA_LNK_FL_ENABLED) == enable)
> -			continue;
> -
> -		LOG(RkISP1, Debug)
> -			<< (enable ? "Enabling" : "Disabling")
> -			<< " link from sensor '"
> -			<< link->source()->entity()->name()
> -			<< "' to ISP";
> -
> -		ret = link->setEnabled(enable);
> -		if (ret < 0)
> -			return ret;
> -	}
> +	ret = initLinks(camera, *config);
> +	if (ret)
> +		return ret;
>
>  	/*
>  	 * Configure the format on the sensor output and propagate it through
> @@ -924,22 +906,51 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
>   * Match and Setup
>   */
>
> -int PipelineHandlerRkISP1::initLinks()
> +int PipelineHandlerRkISP1::initLinks(const Camera *camera,
> +				     const RkISP1CameraConfiguration &config)
>  {
> -	MediaLink *link;
> +	const RkISP1CameraData *data = cameraData(camera);
> +	const CameraSensor *sensor = data->sensor_;

You could actually pass sensor directly, don't you ?

>  	int ret;
>
>  	ret = media_->disableLinks();
>  	if (ret < 0)
>  		return ret;
>
> -	link = media_->link("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0);
> -	if (!link)
> -		return -ENODEV;
> +	/*
> +	 * Configure the sensor links: enable the link corresponding to this
> +	 * camera.
> +	 */
> +	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> +	for (MediaLink *link : pad->links()) {
> +		if (link->source()->entity() != sensor->entity())
> +			continue;
>
> -	ret = link->setEnabled(true);
> -	if (ret < 0)
> -		return ret;
> +		LOG(RkISP1, Debug)
> +			<< "Enabling link from sensor '"
> +			<< link->source()->entity()->name()
> +			<< "' to ISP";
> +
> +		ret = link->setEnabled(true);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	for (const StreamConfiguration &cfg : config) {
> +		std::string resizer;
> +		if (cfg.stream() == &data->stream_)
> +			resizer = "rkisp1_resizer_mainpath";
> +		else
> +			return -EINVAL;
> +
> +		MediaLink *link = media_->link("rkisp1_isp", 2, resizer, 0);
> +		if (!link)
> +			return -ENODEV;
> +
> +		ret = link->setEnabled(true);
> +		if (ret < 0)
> +			return ret;
> +	}

I also see a significant behaviour change, the code is not only moved.
To be able to actually spot what has changed, could this be broken up
in two patches ? One that moves the existing code to a separate
function, the other that changes it on top ?

>
>  	return 0;
>  }
> @@ -1021,12 +1032,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
>  	stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);
>  	param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);
>
> -	/* Configure default links. */
> -	if (initLinks() < 0) {
> -		LOG(RkISP1, Error) << "Failed to setup links";
> -		return false;
> -	}
> -
>  	/*
>  	 * Enumerate all sensors connected to the ISP and create one
>  	 * camera instance for each of them.
> --
> 2.28.0
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
Laurent Pinchart Aug. 20, 2020, 2:55 p.m. UTC | #2
Hi Niklas,

Thank you for the patch.

On Thu, Aug 13, 2020 at 02:52:36AM +0200, Niklas Söderlund wrote:
> In preparation of supporting both the main and self path move all link
> setup to be part of the configuration step. The main path is still the
> only possible path.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> ---
>  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 79 +++++++++++++-----------
>  1 file changed, 42 insertions(+), 37 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index a0e36a44d8d91260..38382a6894dac22a 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -211,7 +211,8 @@ private:
>  	friend RkISP1CameraData;
>  	friend RkISP1Frames;
>  
> -	int initLinks();
> +	int initLinks(const Camera *camera,
> +		      const RkISP1CameraConfiguration &config);
>  	int createCamera(MediaEntity *sensor);
>  	void tryCompleteRequest(Request *request);
>  	void bufferReady(FrameBuffer *buffer);
> @@ -601,28 +602,9 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
>  	CameraSensor *sensor = data->sensor_;
>  	int ret;
>  
> -	/*
> -	 * Configure the sensor links: enable the link corresponding to this
> -	 * camera and disable all the other sensor links.
> -	 */
> -	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> -
> -	for (MediaLink *link : pad->links()) {
> -		bool enable = link->source()->entity() == sensor->entity();
> -
> -		if (!!(link->flags() & MEDIA_LNK_FL_ENABLED) == enable)
> -			continue;
> -
> -		LOG(RkISP1, Debug)
> -			<< (enable ? "Enabling" : "Disabling")
> -			<< " link from sensor '"
> -			<< link->source()->entity()->name()
> -			<< "' to ISP";
> -
> -		ret = link->setEnabled(enable);
> -		if (ret < 0)
> -			return ret;
> -	}
> +	ret = initLinks(camera, *config);
> +	if (ret)
> +		return ret;
>  
>  	/*
>  	 * Configure the format on the sensor output and propagate it through
> @@ -924,22 +906,51 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
>   * Match and Setup
>   */
>  
> -int PipelineHandlerRkISP1::initLinks()
> +int PipelineHandlerRkISP1::initLinks(const Camera *camera,
> +				     const RkISP1CameraConfiguration &config)
>  {
> -	MediaLink *link;
> +	const RkISP1CameraData *data = cameraData(camera);
> +	const CameraSensor *sensor = data->sensor_;
>  	int ret;
>  
>  	ret = media_->disableLinks();
>  	if (ret < 0)
>  		return ret;
>  
> -	link = media_->link("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0);
> -	if (!link)
> -		return -ENODEV;
> +	/*
> +	 * Configure the sensor links: enable the link corresponding to this
> +	 * camera.
> +	 */
> +	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> +	for (MediaLink *link : pad->links()) {
> +		if (link->source()->entity() != sensor->entity())
> +			continue;
>  
> -	ret = link->setEnabled(true);
> -	if (ret < 0)
> -		return ret;
> +		LOG(RkISP1, Debug)
> +			<< "Enabling link from sensor '"
> +			<< link->source()->entity()->name()
> +			<< "' to ISP";
> +
> +		ret = link->setEnabled(true);
> +		if (ret < 0)
> +			return ret;
> +	}

This will break switching between cameras, as you would have both links
enabled. You not only need to enable the link to the sensor, but disable
links to other sensors. The link disable step needs to happen first, as
the driver won't (or at least shouldn't) allow two links to be enabled
at the same time.

> +
> +	for (const StreamConfiguration &cfg : config) {
> +		std::string resizer;
> +		if (cfg.stream() == &data->stream_)
> +			resizer = "rkisp1_resizer_mainpath";
> +		else
> +			return -EINVAL;

I'm not sure to get this change, it doesn't match the commit message. I
suspect it belongs to a different patch.

> +
> +		MediaLink *link = media_->link("rkisp1_isp", 2, resizer, 0);
> +		if (!link)
> +			return -ENODEV;
> +
> +		ret = link->setEnabled(true);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
>  	return 0;
>  }
> @@ -1021,12 +1032,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
>  	stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);
>  	param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);
>  
> -	/* Configure default links. */
> -	if (initLinks() < 0) {
> -		LOG(RkISP1, Error) << "Failed to setup links";
> -		return false;
> -	}
> -
>  	/*
>  	 * Enumerate all sensors connected to the ISP and create one
>  	 * camera instance for each of them.
Niklas Söderlund Sept. 13, 2020, 1:23 p.m. UTC | #3
Hi Jacopo,

On 2020-08-20 10:20:04 +0200, Jacopo Mondi wrote:
> Hi Niklas,
> 
> On Thu, Aug 13, 2020 at 02:52:36AM +0200, Niklas Söderlund wrote:
> > In preparation of supporting both the main and self path move all link
> all links
> 
> > setup to be part of the configuration step. The main path is still the
> > only possible path.
> >
> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> > ---
> >  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 79 +++++++++++++-----------
> >  1 file changed, 42 insertions(+), 37 deletions(-)
> >
> > diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > index a0e36a44d8d91260..38382a6894dac22a 100644
> > --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > @@ -211,7 +211,8 @@ private:
> >  	friend RkISP1CameraData;
> >  	friend RkISP1Frames;
> >
> > -	int initLinks();
> > +	int initLinks(const Camera *camera,
> > +		      const RkISP1CameraConfiguration &config);
> >  	int createCamera(MediaEntity *sensor);
> >  	void tryCompleteRequest(Request *request);
> >  	void bufferReady(FrameBuffer *buffer);
> > @@ -601,28 +602,9 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
> >  	CameraSensor *sensor = data->sensor_;
> >  	int ret;
> >
> > -	/*
> > -	 * Configure the sensor links: enable the link corresponding to this
> > -	 * camera and disable all the other sensor links.
> > -	 */
> > -	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> > -
> > -	for (MediaLink *link : pad->links()) {
> > -		bool enable = link->source()->entity() == sensor->entity();
> > -
> > -		if (!!(link->flags() & MEDIA_LNK_FL_ENABLED) == enable)
> > -			continue;
> > -
> > -		LOG(RkISP1, Debug)
> > -			<< (enable ? "Enabling" : "Disabling")
> > -			<< " link from sensor '"
> > -			<< link->source()->entity()->name()
> > -			<< "' to ISP";
> > -
> > -		ret = link->setEnabled(enable);
> > -		if (ret < 0)
> > -			return ret;
> > -	}
> > +	ret = initLinks(camera, *config);
> > +	if (ret)
> > +		return ret;
> >
> >  	/*
> >  	 * Configure the format on the sensor output and propagate it through
> > @@ -924,22 +906,51 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
> >   * Match and Setup
> >   */
> >
> > -int PipelineHandlerRkISP1::initLinks()
> > +int PipelineHandlerRkISP1::initLinks(const Camera *camera,
> > +				     const RkISP1CameraConfiguration &config)
> >  {
> > -	MediaLink *link;
> > +	const RkISP1CameraData *data = cameraData(camera);
> > +	const CameraSensor *sensor = data->sensor_;
> 
> You could actually pass sensor directly, don't you ?

Grate idea.

> 
> >  	int ret;
> >
> >  	ret = media_->disableLinks();
> >  	if (ret < 0)
> >  		return ret;
> >
> > -	link = media_->link("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0);
> > -	if (!link)
> > -		return -ENODEV;
> > +	/*
> > +	 * Configure the sensor links: enable the link corresponding to this
> > +	 * camera.
> > +	 */
> > +	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> > +	for (MediaLink *link : pad->links()) {
> > +		if (link->source()->entity() != sensor->entity())
> > +			continue;
> >
> > -	ret = link->setEnabled(true);
> > -	if (ret < 0)
> > -		return ret;
> > +		LOG(RkISP1, Debug)
> > +			<< "Enabling link from sensor '"
> > +			<< link->source()->entity()->name()
> > +			<< "' to ISP";
> > +
> > +		ret = link->setEnabled(true);
> > +		if (ret < 0)
> > +			return ret;
> > +	}
> > +
> > +	for (const StreamConfiguration &cfg : config) {
> > +		std::string resizer;
> > +		if (cfg.stream() == &data->stream_)
> > +			resizer = "rkisp1_resizer_mainpath";
> > +		else
> > +			return -EINVAL;
> > +
> > +		MediaLink *link = media_->link("rkisp1_isp", 2, resizer, 0);
> > +		if (!link)
> > +			return -ENODEV;
> > +
> > +		ret = link->setEnabled(true);
> > +		if (ret < 0)
> > +			return ret;
> > +	}
> 
> I also see a significant behaviour change, the code is not only moved.
> To be able to actually spot what has changed, could this be broken up
> in two patches ? One that moves the existing code to a separate
> function, the other that changes it on top ?

I really can't as the idea is to change the behavior. I will rewrite the 
commit message to better describe this is not simply a movement of code 
but change of behavior. Instead of setting up the link between DMA and 
ISP at match() and sensor and ISP at configure() all links are now setup 
at the configure() time.

> 
> >
> >  	return 0;
> >  }
> > @@ -1021,12 +1032,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
> >  	stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);
> >  	param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);
> >
> > -	/* Configure default links. */
> > -	if (initLinks() < 0) {
> > -		LOG(RkISP1, Error) << "Failed to setup links";
> > -		return false;
> > -	}
> > -
> >  	/*
> >  	 * Enumerate all sensors connected to the ISP and create one
> >  	 * camera instance for each of them.
> > --
> > 2.28.0
> >
> > _______________________________________________
> > libcamera-devel mailing list
> > libcamera-devel@lists.libcamera.org
> > https://lists.libcamera.org/listinfo/libcamera-devel
Niklas Söderlund Sept. 13, 2020, 1:26 p.m. UTC | #4
Hi Laurent,

Thanks for your feedback.

On 2020-08-20 17:55:59 +0300, Laurent Pinchart wrote:
> Hi Niklas,
> 
> Thank you for the patch.
> 
> On Thu, Aug 13, 2020 at 02:52:36AM +0200, Niklas Söderlund wrote:
> > In preparation of supporting both the main and self path move all link
> > setup to be part of the configuration step. The main path is still the
> > only possible path.
> > 
> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> > ---
> >  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 79 +++++++++++++-----------
> >  1 file changed, 42 insertions(+), 37 deletions(-)
> > 
> > diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > index a0e36a44d8d91260..38382a6894dac22a 100644
> > --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > @@ -211,7 +211,8 @@ private:
> >  	friend RkISP1CameraData;
> >  	friend RkISP1Frames;
> >  
> > -	int initLinks();
> > +	int initLinks(const Camera *camera,
> > +		      const RkISP1CameraConfiguration &config);
> >  	int createCamera(MediaEntity *sensor);
> >  	void tryCompleteRequest(Request *request);
> >  	void bufferReady(FrameBuffer *buffer);
> > @@ -601,28 +602,9 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
> >  	CameraSensor *sensor = data->sensor_;
> >  	int ret;
> >  
> > -	/*
> > -	 * Configure the sensor links: enable the link corresponding to this
> > -	 * camera and disable all the other sensor links.
> > -	 */
> > -	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> > -
> > -	for (MediaLink *link : pad->links()) {
> > -		bool enable = link->source()->entity() == sensor->entity();
> > -
> > -		if (!!(link->flags() & MEDIA_LNK_FL_ENABLED) == enable)
> > -			continue;
> > -
> > -		LOG(RkISP1, Debug)
> > -			<< (enable ? "Enabling" : "Disabling")
> > -			<< " link from sensor '"
> > -			<< link->source()->entity()->name()
> > -			<< "' to ISP";
> > -
> > -		ret = link->setEnabled(enable);
> > -		if (ret < 0)
> > -			return ret;
> > -	}
> > +	ret = initLinks(camera, *config);
> > +	if (ret)
> > +		return ret;
> >  
> >  	/*
> >  	 * Configure the format on the sensor output and propagate it through
> > @@ -924,22 +906,51 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
> >   * Match and Setup
> >   */
> >  
> > -int PipelineHandlerRkISP1::initLinks()
> > +int PipelineHandlerRkISP1::initLinks(const Camera *camera,
> > +				     const RkISP1CameraConfiguration &config)
> >  {
> > -	MediaLink *link;
> > +	const RkISP1CameraData *data = cameraData(camera);
> > +	const CameraSensor *sensor = data->sensor_;
> >  	int ret;
> >  
> >  	ret = media_->disableLinks();
> >  	if (ret < 0)
> >  		return ret;
> >  
> > -	link = media_->link("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0);
> > -	if (!link)
> > -		return -ENODEV;
> > +	/*
> > +	 * Configure the sensor links: enable the link corresponding to this
> > +	 * camera.
> > +	 */
> > +	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
> > +	for (MediaLink *link : pad->links()) {
> > +		if (link->source()->entity() != sensor->entity())
> > +			continue;
> >  
> > -	ret = link->setEnabled(true);
> > -	if (ret < 0)
> > -		return ret;
> > +		LOG(RkISP1, Debug)
> > +			<< "Enabling link from sensor '"
> > +			<< link->source()->entity()->name()
> > +			<< "' to ISP";
> > +
> > +		ret = link->setEnabled(true);
> > +		if (ret < 0)
> > +			return ret;
> > +	}
> 
> This will break switching between cameras, as you would have both links
> enabled. You not only need to enable the link to the sensor, but disable
> links to other sensors. The link disable step needs to happen first, as
> the driver won't (or at least shouldn't) allow two links to be enabled
> at the same time.

It's not a change of behavior, but it's accomplished in a different way.  
With this change all links are configured in initLinks() so a first step 
is to disable all links with a call to 'media_->disableLinks()' all that 
is left after that is to enable the desired links.

> 
> > +
> > +	for (const StreamConfiguration &cfg : config) {
> > +		std::string resizer;
> > +		if (cfg.stream() == &data->stream_)
> > +			resizer = "rkisp1_resizer_mainpath";
> > +		else
> > +			return -EINVAL;
> 
> I'm not sure to get this change, it doesn't match the commit message. I
> suspect it belongs to a different patch.

I will update the commit message as this is intended to be a part of 
this change. It may however be reworked to remove the intermediate 
resizer variable and save one LoC ;-)

> 
> > +
> > +		MediaLink *link = media_->link("rkisp1_isp", 2, resizer, 0);
> > +		if (!link)
> > +			return -ENODEV;
> > +
> > +		ret = link->setEnabled(true);
> > +		if (ret < 0)
> > +			return ret;
> > +	}
> >  
> >  	return 0;
> >  }
> > @@ -1021,12 +1032,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
> >  	stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);
> >  	param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);
> >  
> > -	/* Configure default links. */
> > -	if (initLinks() < 0) {
> > -		LOG(RkISP1, Error) << "Failed to setup links";
> > -		return false;
> > -	}
> > -
> >  	/*
> >  	 * Enumerate all sensors connected to the ISP and create one
> >  	 * camera instance for each of them.
> 
> -- 
> Regards,
> 
> Laurent Pinchart

Patch

diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index a0e36a44d8d91260..38382a6894dac22a 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -211,7 +211,8 @@  private:
 	friend RkISP1CameraData;
 	friend RkISP1Frames;
 
-	int initLinks();
+	int initLinks(const Camera *camera,
+		      const RkISP1CameraConfiguration &config);
 	int createCamera(MediaEntity *sensor);
 	void tryCompleteRequest(Request *request);
 	void bufferReady(FrameBuffer *buffer);
@@ -601,28 +602,9 @@  int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
 	CameraSensor *sensor = data->sensor_;
 	int ret;
 
-	/*
-	 * Configure the sensor links: enable the link corresponding to this
-	 * camera and disable all the other sensor links.
-	 */
-	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
-
-	for (MediaLink *link : pad->links()) {
-		bool enable = link->source()->entity() == sensor->entity();
-
-		if (!!(link->flags() & MEDIA_LNK_FL_ENABLED) == enable)
-			continue;
-
-		LOG(RkISP1, Debug)
-			<< (enable ? "Enabling" : "Disabling")
-			<< " link from sensor '"
-			<< link->source()->entity()->name()
-			<< "' to ISP";
-
-		ret = link->setEnabled(enable);
-		if (ret < 0)
-			return ret;
-	}
+	ret = initLinks(camera, *config);
+	if (ret)
+		return ret;
 
 	/*
 	 * Configure the format on the sensor output and propagate it through
@@ -924,22 +906,51 @@  int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
  * Match and Setup
  */
 
-int PipelineHandlerRkISP1::initLinks()
+int PipelineHandlerRkISP1::initLinks(const Camera *camera,
+				     const RkISP1CameraConfiguration &config)
 {
-	MediaLink *link;
+	const RkISP1CameraData *data = cameraData(camera);
+	const CameraSensor *sensor = data->sensor_;
 	int ret;
 
 	ret = media_->disableLinks();
 	if (ret < 0)
 		return ret;
 
-	link = media_->link("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0);
-	if (!link)
-		return -ENODEV;
+	/*
+	 * Configure the sensor links: enable the link corresponding to this
+	 * camera.
+	 */
+	const MediaPad *pad = isp_->entity()->getPadByIndex(0);
+	for (MediaLink *link : pad->links()) {
+		if (link->source()->entity() != sensor->entity())
+			continue;
 
-	ret = link->setEnabled(true);
-	if (ret < 0)
-		return ret;
+		LOG(RkISP1, Debug)
+			<< "Enabling link from sensor '"
+			<< link->source()->entity()->name()
+			<< "' to ISP";
+
+		ret = link->setEnabled(true);
+		if (ret < 0)
+			return ret;
+	}
+
+	for (const StreamConfiguration &cfg : config) {
+		std::string resizer;
+		if (cfg.stream() == &data->stream_)
+			resizer = "rkisp1_resizer_mainpath";
+		else
+			return -EINVAL;
+
+		MediaLink *link = media_->link("rkisp1_isp", 2, resizer, 0);
+		if (!link)
+			return -ENODEV;
+
+		ret = link->setEnabled(true);
+		if (ret < 0)
+			return ret;
+	}
 
 	return 0;
 }
@@ -1021,12 +1032,6 @@  bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
 	stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);
 	param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);
 
-	/* Configure default links. */
-	if (initLinks() < 0) {
-		LOG(RkISP1, Error) << "Failed to setup links";
-		return false;
-	}
-
 	/*
 	 * Enumerate all sensors connected to the ISP and create one
 	 * camera instance for each of them.