diff mbox series

[v10,8/9] media: ivsc: csi: Obtain link frequency from the media pad

Message ID 20250120110157.152732-9-sakari.ailus@linux.intel.com (mailing list archive)
State New
Headers show
Series Use V4L2 mbus config for conveying link frequency | expand

Commit Message

Sakari Ailus Jan. 20, 2025, 11:01 a.m. UTC
Support the use of the media pad for obtaining the link frequency.
Similarly, call the v4l2_get_link_freq() on the media pad, not on the
remote's control handler.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/pci/intel/ivsc/mei_csi.c | 78 +++++++++-----------------
 1 file changed, 26 insertions(+), 52 deletions(-)

Comments

Tomi Valkeinen Jan. 31, 2025, 4:33 p.m. UTC | #1
On 20/01/2025 13:01, Sakari Ailus wrote:
> Support the use of the media pad for obtaining the link frequency.
> Similarly, call the v4l2_get_link_freq() on the media pad, not on the
> remote's control handler.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> ---
>   drivers/media/pci/intel/ivsc/mei_csi.c | 78 +++++++++-----------------
>   1 file changed, 26 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/media/pci/intel/ivsc/mei_csi.c b/drivers/media/pci/intel/ivsc/mei_csi.c
> index 2a9c12c975ca..545de4654609 100644
> --- a/drivers/media/pci/intel/ivsc/mei_csi.c
> +++ b/drivers/media/pci/intel/ivsc/mei_csi.c
> @@ -35,8 +35,6 @@
>   
>   #define MEI_CSI_ENTITY_NAME "Intel IVSC CSI"
>   
> -#define MEI_CSI_LINK_FREQ_400MHZ 400000000ULL
> -
>   /* the 5s used here is based on experiment */
>   #define CSI_CMD_TIMEOUT (5 * HZ)
>   /* to setup CSI-2 link an extra delay needed and determined experimentally */
> @@ -121,14 +119,13 @@ struct mei_csi {
>   	struct mutex lock;
>   
>   	struct v4l2_subdev subdev;
> -	struct v4l2_subdev *remote;
> +	struct media_pad *remote;
>   	struct v4l2_async_notifier notifier;
>   	struct v4l2_ctrl_handler ctrl_handler;
>   	struct v4l2_ctrl *freq_ctrl;
>   	struct v4l2_ctrl *privacy_ctrl;
>   	/* lock for v4l2 controls */
>   	struct mutex ctrl_lock;
> -	unsigned int remote_pad;
>   	/* start streaming or not */
>   	int streaming;
>   
> @@ -147,10 +144,6 @@ static const struct v4l2_mbus_framefmt mei_csi_format_mbus_default = {
>   	.field = V4L2_FIELD_NONE,
>   };
>   
> -static s64 link_freq_menu_items[] = {
> -	MEI_CSI_LINK_FREQ_400MHZ
> -};
> -
>   static inline struct mei_csi *notifier_to_csi(struct v4l2_async_notifier *n)
>   {
>   	return container_of(n, struct mei_csi, notifier);
> @@ -161,11 +154,6 @@ static inline struct mei_csi *sd_to_csi(struct v4l2_subdev *sd)
>   	return container_of(sd, struct mei_csi, subdev);
>   }
>   
> -static inline struct mei_csi *ctrl_to_csi(struct v4l2_ctrl *ctrl)
> -{
> -	return container_of(ctrl->handler, struct mei_csi, ctrl_handler);
> -}
> -
>   /* send a command to firmware and mutex must be held by caller */
>   static int mei_csi_send(struct mei_csi *csi, u8 *buf, size_t len)
>   {
> @@ -286,11 +274,13 @@ static void mei_csi_rx(struct mei_cl_device *cldev)
>   static int mei_csi_set_stream(struct v4l2_subdev *sd, int enable)
>   {
>   	struct mei_csi *csi = sd_to_csi(sd);
> +	struct v4l2_subdev *remote_sd =
> +		media_entity_to_v4l2_subdev(csi->remote->entity);
>   	s64 freq;
>   	int ret;
>   
>   	if (enable && csi->streaming == 0) {
> -		freq = v4l2_get_link_freq(csi->remote->ctrl_handler, 0, 0);
> +		freq = v4l2_get_link_freq(csi->remote, 0, 0);
>   		if (freq < 0) {
>   			dev_err(&csi->cldev->dev,
>   				"error %lld, invalid link_freq\n", freq);
> @@ -309,11 +299,11 @@ static int mei_csi_set_stream(struct v4l2_subdev *sd, int enable)
>   		if (ret < 0)
>   			goto err_switch;
>   
> -		ret = v4l2_subdev_call(csi->remote, video, s_stream, 1);
> +		ret = v4l2_subdev_call(remote_sd, video, s_stream, 1);
>   		if (ret)
>   			goto err_switch;
>   	} else if (!enable && csi->streaming == 1) {
> -		v4l2_subdev_call(csi->remote, video, s_stream, 0);
> +		v4l2_subdev_call(remote_sd, video, s_stream, 0);
>   
>   		/* switch CSI-2 link to IVSC */
>   		ret = csi_set_link_owner(csi, CSI_LINK_IVSC);
> @@ -470,34 +460,30 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
>   	return 0;
>   }
>   
> -static int mei_csi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
> +static int mei_csi_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
> +				   struct v4l2_mbus_config *mbus_config)
>   {
> -	struct mei_csi *csi = ctrl_to_csi(ctrl);
> +	struct mei_csi *csi = sd_to_csi(sd);
> +	unsigned int i;
>   	s64 freq;
>   
> -	if (ctrl->id == V4L2_CID_LINK_FREQ) {
> -		if (!csi->remote)
> -			return -EINVAL;
> +	mbus_config->type = V4L2_MBUS_CSI2_DPHY;
> +	for (i = 0; i < V4L2_MBUS_CSI2_MAX_DATA_LANES; i++)
> +		mbus_config->bus.mipi_csi2.data_lanes[i] = i + 1;
> +	mbus_config->bus.mipi_csi2.num_data_lanes = csi->nr_of_lanes;
>   
> -		freq = v4l2_get_link_freq(csi->remote->ctrl_handler, 0, 0);
> -		if (freq < 0) {
> -			dev_err(&csi->cldev->dev,
> -				"error %lld, invalid link_freq\n", freq);
> -			return -EINVAL;
> -		}
> -
> -		link_freq_menu_items[0] = freq;
> -		ctrl->val = 0;
> -
> -		return 0;
> +	freq = v4l2_get_link_freq(csi->remote, 0, 0);
> +	if (freq < 0) {
> +		dev_err(&csi->cldev->dev,
> +			"error %lld, invalid link_freq\n", freq);
> +		return -EINVAL;
>   	}
>   
> -	return -EINVAL;
> -}
> +	csi->link_freq = freq;
> +	mbus_config->link_freq = freq;
>   
> -static const struct v4l2_ctrl_ops mei_csi_ctrl_ops = {
> -	.g_volatile_ctrl = mei_csi_g_volatile_ctrl,
> -};
> +	return 0;
> +}
>   
>   static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
>   	.s_stream = mei_csi_set_stream,
> @@ -506,6 +492,7 @@ static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
>   static const struct v4l2_subdev_pad_ops mei_csi_pad_ops = {
>   	.get_fmt = v4l2_subdev_get_fmt,
>   	.set_fmt = mei_csi_set_fmt,
> +	.get_mbus_config = mei_csi_get_mbus_config,
>   };
>   
>   static const struct v4l2_subdev_ops mei_csi_subdev_ops = {
> @@ -533,8 +520,7 @@ static int mei_csi_notify_bound(struct v4l2_async_notifier *notifier,
>   	if (pad < 0)
>   		return pad;
>   
> -	csi->remote = subdev;
> -	csi->remote_pad = pad;
> +	csi->remote = &subdev->entity.pads[pad];
>   
>   	return media_create_pad_link(&subdev->entity, pad,
>   				     &csi->subdev.entity, CSI_PAD_SINK,
> @@ -558,28 +544,16 @@ static const struct v4l2_async_notifier_operations mei_csi_notify_ops = {
>   
>   static int mei_csi_init_controls(struct mei_csi *csi)
>   {
> -	u32 max;
>   	int ret;
>   
>   	mutex_init(&csi->ctrl_lock);
>   
> -	ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 2);
> +	ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 1);
>   	if (ret)
>   		return ret;
>   
>   	csi->ctrl_handler.lock = &csi->ctrl_lock;
>   
> -	max = ARRAY_SIZE(link_freq_menu_items) - 1;
> -	csi->freq_ctrl = v4l2_ctrl_new_int_menu(&csi->ctrl_handler,
> -						&mei_csi_ctrl_ops,
> -						V4L2_CID_LINK_FREQ,
> -						max,
> -						0,
> -						link_freq_menu_items);
> -	if (csi->freq_ctrl)
> -		csi->freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY |
> -					 V4L2_CTRL_FLAG_VOLATILE;
> -
>   	csi->privacy_ctrl = v4l2_ctrl_new_std(&csi->ctrl_handler, NULL,
>   					      V4L2_CID_PRIVACY, 0, 1, 1, 0);
>   	if (csi->privacy_ctrl)

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

  Tomi
diff mbox series

Patch

diff --git a/drivers/media/pci/intel/ivsc/mei_csi.c b/drivers/media/pci/intel/ivsc/mei_csi.c
index 2a9c12c975ca..545de4654609 100644
--- a/drivers/media/pci/intel/ivsc/mei_csi.c
+++ b/drivers/media/pci/intel/ivsc/mei_csi.c
@@ -35,8 +35,6 @@ 
 
 #define MEI_CSI_ENTITY_NAME "Intel IVSC CSI"
 
-#define MEI_CSI_LINK_FREQ_400MHZ 400000000ULL
-
 /* the 5s used here is based on experiment */
 #define CSI_CMD_TIMEOUT (5 * HZ)
 /* to setup CSI-2 link an extra delay needed and determined experimentally */
@@ -121,14 +119,13 @@  struct mei_csi {
 	struct mutex lock;
 
 	struct v4l2_subdev subdev;
-	struct v4l2_subdev *remote;
+	struct media_pad *remote;
 	struct v4l2_async_notifier notifier;
 	struct v4l2_ctrl_handler ctrl_handler;
 	struct v4l2_ctrl *freq_ctrl;
 	struct v4l2_ctrl *privacy_ctrl;
 	/* lock for v4l2 controls */
 	struct mutex ctrl_lock;
-	unsigned int remote_pad;
 	/* start streaming or not */
 	int streaming;
 
@@ -147,10 +144,6 @@  static const struct v4l2_mbus_framefmt mei_csi_format_mbus_default = {
 	.field = V4L2_FIELD_NONE,
 };
 
-static s64 link_freq_menu_items[] = {
-	MEI_CSI_LINK_FREQ_400MHZ
-};
-
 static inline struct mei_csi *notifier_to_csi(struct v4l2_async_notifier *n)
 {
 	return container_of(n, struct mei_csi, notifier);
@@ -161,11 +154,6 @@  static inline struct mei_csi *sd_to_csi(struct v4l2_subdev *sd)
 	return container_of(sd, struct mei_csi, subdev);
 }
 
-static inline struct mei_csi *ctrl_to_csi(struct v4l2_ctrl *ctrl)
-{
-	return container_of(ctrl->handler, struct mei_csi, ctrl_handler);
-}
-
 /* send a command to firmware and mutex must be held by caller */
 static int mei_csi_send(struct mei_csi *csi, u8 *buf, size_t len)
 {
@@ -286,11 +274,13 @@  static void mei_csi_rx(struct mei_cl_device *cldev)
 static int mei_csi_set_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct mei_csi *csi = sd_to_csi(sd);
+	struct v4l2_subdev *remote_sd =
+		media_entity_to_v4l2_subdev(csi->remote->entity);
 	s64 freq;
 	int ret;
 
 	if (enable && csi->streaming == 0) {
-		freq = v4l2_get_link_freq(csi->remote->ctrl_handler, 0, 0);
+		freq = v4l2_get_link_freq(csi->remote, 0, 0);
 		if (freq < 0) {
 			dev_err(&csi->cldev->dev,
 				"error %lld, invalid link_freq\n", freq);
@@ -309,11 +299,11 @@  static int mei_csi_set_stream(struct v4l2_subdev *sd, int enable)
 		if (ret < 0)
 			goto err_switch;
 
-		ret = v4l2_subdev_call(csi->remote, video, s_stream, 1);
+		ret = v4l2_subdev_call(remote_sd, video, s_stream, 1);
 		if (ret)
 			goto err_switch;
 	} else if (!enable && csi->streaming == 1) {
-		v4l2_subdev_call(csi->remote, video, s_stream, 0);
+		v4l2_subdev_call(remote_sd, video, s_stream, 0);
 
 		/* switch CSI-2 link to IVSC */
 		ret = csi_set_link_owner(csi, CSI_LINK_IVSC);
@@ -470,34 +460,30 @@  static int mei_csi_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int mei_csi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+static int mei_csi_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
+				   struct v4l2_mbus_config *mbus_config)
 {
-	struct mei_csi *csi = ctrl_to_csi(ctrl);
+	struct mei_csi *csi = sd_to_csi(sd);
+	unsigned int i;
 	s64 freq;
 
-	if (ctrl->id == V4L2_CID_LINK_FREQ) {
-		if (!csi->remote)
-			return -EINVAL;
+	mbus_config->type = V4L2_MBUS_CSI2_DPHY;
+	for (i = 0; i < V4L2_MBUS_CSI2_MAX_DATA_LANES; i++)
+		mbus_config->bus.mipi_csi2.data_lanes[i] = i + 1;
+	mbus_config->bus.mipi_csi2.num_data_lanes = csi->nr_of_lanes;
 
-		freq = v4l2_get_link_freq(csi->remote->ctrl_handler, 0, 0);
-		if (freq < 0) {
-			dev_err(&csi->cldev->dev,
-				"error %lld, invalid link_freq\n", freq);
-			return -EINVAL;
-		}
-
-		link_freq_menu_items[0] = freq;
-		ctrl->val = 0;
-
-		return 0;
+	freq = v4l2_get_link_freq(csi->remote, 0, 0);
+	if (freq < 0) {
+		dev_err(&csi->cldev->dev,
+			"error %lld, invalid link_freq\n", freq);
+		return -EINVAL;
 	}
 
-	return -EINVAL;
-}
+	csi->link_freq = freq;
+	mbus_config->link_freq = freq;
 
-static const struct v4l2_ctrl_ops mei_csi_ctrl_ops = {
-	.g_volatile_ctrl = mei_csi_g_volatile_ctrl,
-};
+	return 0;
+}
 
 static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
 	.s_stream = mei_csi_set_stream,
@@ -506,6 +492,7 @@  static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
 static const struct v4l2_subdev_pad_ops mei_csi_pad_ops = {
 	.get_fmt = v4l2_subdev_get_fmt,
 	.set_fmt = mei_csi_set_fmt,
+	.get_mbus_config = mei_csi_get_mbus_config,
 };
 
 static const struct v4l2_subdev_ops mei_csi_subdev_ops = {
@@ -533,8 +520,7 @@  static int mei_csi_notify_bound(struct v4l2_async_notifier *notifier,
 	if (pad < 0)
 		return pad;
 
-	csi->remote = subdev;
-	csi->remote_pad = pad;
+	csi->remote = &subdev->entity.pads[pad];
 
 	return media_create_pad_link(&subdev->entity, pad,
 				     &csi->subdev.entity, CSI_PAD_SINK,
@@ -558,28 +544,16 @@  static const struct v4l2_async_notifier_operations mei_csi_notify_ops = {
 
 static int mei_csi_init_controls(struct mei_csi *csi)
 {
-	u32 max;
 	int ret;
 
 	mutex_init(&csi->ctrl_lock);
 
-	ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 2);
+	ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 1);
 	if (ret)
 		return ret;
 
 	csi->ctrl_handler.lock = &csi->ctrl_lock;
 
-	max = ARRAY_SIZE(link_freq_menu_items) - 1;
-	csi->freq_ctrl = v4l2_ctrl_new_int_menu(&csi->ctrl_handler,
-						&mei_csi_ctrl_ops,
-						V4L2_CID_LINK_FREQ,
-						max,
-						0,
-						link_freq_menu_items);
-	if (csi->freq_ctrl)
-		csi->freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY |
-					 V4L2_CTRL_FLAG_VOLATILE;
-
 	csi->privacy_ctrl = v4l2_ctrl_new_std(&csi->ctrl_handler, NULL,
 					      V4L2_CID_PRIVACY, 0, 1, 1, 0);
 	if (csi->privacy_ctrl)