From patchwork Fri Mar 15 08:51:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Massot X-Patchwork-Id: 13593182 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48E3317581 for ; Fri, 15 Mar 2024 08:52:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492747; cv=none; b=pGzJIIXUWV2vIIj5hVAg6YDc6sv5+8LGUp3rD2GSZ1ClR+4if1bwYE5awwTzoH1VSmBrJYknKvK7e60gIONmdYAjsBGV6mpl+HXgnu/Uv/k6P2RJTasfoj3RnHZNYiL4PN6xhkj4bMWVIfGte0Zb8pSQoBFrv0AXkWRlqo2sA6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492747; c=relaxed/simple; bh=xvbE61BXNyacirQPmWzpIkFW38J4PRYit33d1n6+rEg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RstBd9YdriGdft+fRijAjnLQ8Qo4YgcuYKqLUTBRCEkywF8JUX7T/LOhVTv+y+ib5UO3h3f9NHAFfHVlFI/k5vedFtrubvrYqS3pKhp4DqDgux7mdINfTiuAiLwUhSYh2o4CHPjK8RDUaWlxPXL0L7VyL0Npr2Gl0QUHFNUx7fY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=Z2iAW8iL; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="Z2iAW8iL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1710492743; bh=xvbE61BXNyacirQPmWzpIkFW38J4PRYit33d1n6+rEg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z2iAW8iLPNM76b8jeNKVSAplNyca91vbzjMgce3u+FGPjJYKIKjcsVruljneab7ZK k3L3FgGAa8bB3lhsuDTAHmjQXiXA6S6KVcAsVzmv1fXi92nLyMVwDTo0MzW2xVwTvq RFSqqB64dJRvtqkfgGRfFsLrJOjX13IhMW7jFP69KreBQExKyiV2hc93AGJMtEHwpF VsmleBoS6lPnxl36vSVb+63T6bM0cFVAf1Waw74BJJoyEwHNKMP0mL82hX+W7tPvlM 5uv7iG27rZdYTHCJe2i1ESVzFPnxmBUskq7/5HblyWZ1qWZYrKh2GLgzrkMNFiilnw pqJu4wObaN/UQ== Received: from stla-brain-8255-1.home (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: jmassot) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 1FD4D37820FD; Fri, 15 Mar 2024 08:52:23 +0000 (UTC) From: Julien Massot To: mchehab@kernel.org, sakari.ailus@linux.intel.com, benjamin.mugnier@foss.st.com, sylvain.petinot@foss.st.com Cc: linux-media@vger.kernel.org, kernel@collabora.com, Julien Massot Subject: [PATCH 1/4] media: i2c: st-vgxy61: Use sub-device active state Date: Fri, 15 Mar 2024 09:51:55 +0100 Message-ID: <20240315085158.1213159-2-julien.massot@collabora.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240315085158.1213159-1-julien.massot@collabora.com> References: <20240315085158.1213159-1-julien.massot@collabora.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use sub-device active state. Rely on control handler lock to serialize access to the active state. Signed-off-by: Julien Massot --- drivers/media/i2c/st-vgxy61.c | 109 ++++++++++++---------------------- 1 file changed, 39 insertions(+), 70 deletions(-) diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c index b9e7c57027b1..733713f909cf 100644 --- a/drivers/media/i2c/st-vgxy61.c +++ b/drivers/media/i2c/st-vgxy61.c @@ -397,8 +397,6 @@ struct vgxy61_dev { u16 line_length; u16 rot_term; bool gpios_polarity; - /* Lock to protect all members below */ - struct mutex lock; struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl *pixel_rate_ctrl; struct v4l2_ctrl *expo_ctrl; @@ -686,27 +684,6 @@ static int vgxy61_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int vgxy61_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct vgxy61_dev *sensor = to_vgxy61_dev(sd); - struct v4l2_mbus_framefmt *fmt; - - mutex_lock(&sensor->lock); - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) - fmt = v4l2_subdev_state_get_format(sd_state, format->pad); - else - fmt = &sensor->fmt; - - format->format = *fmt; - - mutex_unlock(&sensor->lock); - - return 0; -} - static u16 vgxy61_get_vblank_min(struct vgxy61_dev *sensor, enum vgxy61_hdr_mode hdr) { @@ -1167,16 +1144,17 @@ static int vgxy61_stream_disable(struct vgxy61_dev *sensor) static int vgxy61_s_stream(struct v4l2_subdev *sd, int enable) { struct vgxy61_dev *sensor = to_vgxy61_dev(sd); + struct v4l2_subdev_state *sd_state; int ret = 0; - mutex_lock(&sensor->lock); + sd_state = v4l2_subdev_lock_and_get_active_state(&sensor->sd); ret = enable ? vgxy61_stream_enable(sensor) : vgxy61_stream_disable(sensor); if (!ret) sensor->streaming = enable; - mutex_unlock(&sensor->lock); + v4l2_subdev_unlock_state(sd_state); return ret; } @@ -1187,51 +1165,39 @@ static int vgxy61_set_fmt(struct v4l2_subdev *sd, { struct vgxy61_dev *sensor = to_vgxy61_dev(sd); const struct vgxy61_mode_info *new_mode; - struct v4l2_mbus_framefmt *fmt; int ret; - mutex_lock(&sensor->lock); - - if (sensor->streaming) { - ret = -EBUSY; - goto out; - } + if (sensor->streaming) + return -EBUSY; ret = vgxy61_try_fmt_internal(sd, &format->format, &new_mode); if (ret) - goto out; - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt = v4l2_subdev_state_get_format(sd_state, 0); - *fmt = format->format; - } else if (sensor->current_mode != new_mode || - sensor->fmt.code != format->format.code) { - fmt = &sensor->fmt; - *fmt = format->format; - - sensor->current_mode = new_mode; - - /* Reset vblank and framelength to default */ - ret = vgxy61_update_vblank(sensor, - VGXY61_FRAME_LENGTH_DEF - - new_mode->crop.height, - sensor->hdr); - - /* Update controls to reflect new mode */ - __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_ctrl, - get_pixel_rate(sensor)); - __v4l2_ctrl_modify_range(sensor->vblank_ctrl, - sensor->vblank_min, - 0xffff - new_mode->crop.height, - 1, sensor->vblank); - __v4l2_ctrl_s_ctrl(sensor->vblank_ctrl, sensor->vblank); - __v4l2_ctrl_modify_range(sensor->expo_ctrl, sensor->expo_min, - sensor->expo_max, 1, - sensor->expo_long); - } + return ret; + + *v4l2_subdev_state_get_format(sd_state, format->pad) = format->format; -out: - mutex_unlock(&sensor->lock); + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + return 0; + + sensor->current_mode = new_mode; + + /* Reset vblank and framelength to default */ + ret = vgxy61_update_vblank(sensor, + VGXY61_FRAME_LENGTH_DEF - + new_mode->crop.height, + sensor->hdr); + + /* Update controls to reflect new mode */ + __v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_ctrl, + get_pixel_rate(sensor)); + __v4l2_ctrl_modify_range(sensor->vblank_ctrl, + sensor->vblank_min, + 0xffff - new_mode->crop.height, + 1, sensor->vblank); + __v4l2_ctrl_s_ctrl(sensor->vblank_ctrl, sensor->vblank); + __v4l2_ctrl_modify_range(sensor->expo_ctrl, sensor->expo_min, + sensor->expo_max, 1, + sensor->expo_long); return ret; } @@ -1321,8 +1287,6 @@ static int vgxy61_init_controls(struct vgxy61_dev *sensor) int ret; v4l2_ctrl_handler_init(hdl, 16); - /* We can use our own mutex for the ctrl lock */ - hdl->lock = &sensor->lock; v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, 0, 0x1c, 1, sensor->analog_gain); v4l2_ctrl_new_std(hdl, ops, V4L2_CID_DIGITAL_GAIN, 0, 0xfff, 1, @@ -1398,7 +1362,7 @@ static const struct v4l2_subdev_video_ops vgxy61_video_ops = { static const struct v4l2_subdev_pad_ops vgxy61_pad_ops = { .enum_mbus_code = vgxy61_enum_mbus_code, - .get_fmt = vgxy61_get_fmt, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = vgxy61_set_fmt, .get_selection = vgxy61_get_selection, .enum_frame_size = vgxy61_enum_frame_size, @@ -1801,7 +1765,7 @@ static int vgxy61_probe(struct i2c_client *client) vgxy61_fill_framefmt(sensor, sensor->current_mode, &sensor->fmt, VGXY61_MEDIA_BUS_FMT_DEF); - mutex_init(&sensor->lock); + sensor->sd.state_lock = sensor->ctrl_handler.lock; ret = vgxy61_update_hdr(sensor, sensor->hdr); if (ret) @@ -1820,6 +1784,10 @@ static int vgxy61_probe(struct i2c_client *client) goto error_handler_free; } + ret = v4l2_subdev_init_finalize(&sensor->sd); + if (ret) + goto error_media_entity_cleanup; + /* Enable runtime PM and turn off the device */ pm_runtime_set_active(dev); pm_runtime_enable(dev); @@ -1841,11 +1809,12 @@ static int vgxy61_probe(struct i2c_client *client) error_pm_runtime: pm_runtime_disable(&client->dev); pm_runtime_set_suspended(&client->dev); + v4l2_subdev_cleanup(&sensor->sd); +error_media_entity_cleanup: media_entity_cleanup(&sensor->sd.entity); error_handler_free: v4l2_ctrl_handler_free(sensor->sd.ctrl_handler); error_power_off: - mutex_destroy(&sensor->lock); vgxy61_power_off(dev); return ret; @@ -1857,7 +1826,7 @@ static void vgxy61_remove(struct i2c_client *client) struct vgxy61_dev *sensor = to_vgxy61_dev(sd); v4l2_async_unregister_subdev(&sensor->sd); - mutex_destroy(&sensor->lock); + v4l2_subdev_cleanup(&sensor->sd); media_entity_cleanup(&sensor->sd.entity); pm_runtime_disable(&client->dev); From patchwork Fri Mar 15 08:51:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Massot X-Patchwork-Id: 13593183 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB9BB1758B for ; Fri, 15 Mar 2024 08:52:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492747; cv=none; b=m5FoZZ7jodq4C6Fjrsbk6wwOHcl7mcEVeggkoIMEcnGf/+6zzkzuadk9C5HnmZF4Aq02axsQijosSwsUNkrWkK9dIihyZcJV5Ij+YK9C/fQ3fYBhuHrIQN6iSLM0uRFy1Z8AbjpWsd4HxcdwryoILjggWwl15RyTCCIrKA/CHgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492747; c=relaxed/simple; bh=bPQtPsAEdhFmI2JT5tuyADxaD0xprDdvbIyC2AWuL2M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N0Z58J4jWdN2rcFOPKXHPrmz5S9i+MJbLVgrZjuWNeidoos/6noJTXQRFLDFONh2vFMU/jw2+cEA8yLIk0ZwafL1mTnKG/nAQtZq791fFUzGgxuHqfPqRPXJAdMlPx6jXcotX8CDSrynRQ0kT/hBD0TrhsTe1s85tyyxVHD/KUI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=eo6KdCHz; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="eo6KdCHz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1710492744; bh=bPQtPsAEdhFmI2JT5tuyADxaD0xprDdvbIyC2AWuL2M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eo6KdCHzNKonLWyvBwO6GmP+pdeCH0Migl/Uk9hkayDVmM6x/jPRmxfQlEPihG6wz LhjZdNkif3hGlM3nmK8glVxwGvzedjG17lf0OJ81tNtNFF3OD5wtcf7Uuzv7TOHy5T NpDO4MlTreHWkrbXnXI1JCObWFdk1V8ovf7+ZTuRAdhVjAbaYoojry7N2zrflUoBPj 4ZSTC8a06YF2+dgTE7wnHScqDD96FJjqPzMr6rakcyQOv3m+ZXalo4KgMdMsi4Kphk GRFVSVCTgYCVoNBfXur5btxt+qjI7aheXIsxSIh4Zy9ebmjqN5UoCefLVdoT/jmGbD cNqMEg7UvXNxw== Received: from stla-brain-8255-1.home (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: jmassot) by madrid.collaboradmins.com (Postfix) with ESMTPSA id BFE6137820FF; Fri, 15 Mar 2024 08:52:23 +0000 (UTC) From: Julien Massot To: mchehab@kernel.org, sakari.ailus@linux.intel.com, benjamin.mugnier@foss.st.com, sylvain.petinot@foss.st.com Cc: linux-media@vger.kernel.org, kernel@collabora.com, Julien Massot Subject: [PATCH 2/4] media: i2c: st-vgxy61: Add support for embedded data Date: Fri, 15 Mar 2024 09:51:56 +0100 Message-ID: <20240315085158.1213159-3-julien.massot@collabora.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240315085158.1213159-1-julien.massot@collabora.com> References: <20240315085158.1213159-1-julien.massot@collabora.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support for embedded data. This introduces two internal pads for pixel and embedded data streams. The sensor can send ISL data at the begginning of each frame. The ISL data contains information related to the current frame such as: ROI, cropping and orientation, gains, thermal sensors values, frame counter.. The Intelligent Status Line follows the CCS embedded data format definition regarding the tagged data but not for the registers address, therefore the format code is MEDIA_BUS_FMT_META_8 and not MEDIA_BUS_FMT_CCS_EMBEDDED. Signed-off-by: Julien Massot --- drivers/media/i2c/st-vgxy61.c | 172 +++++++++++++++++++++++++++++++--- 1 file changed, 160 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c index 733713f909cf..e8302456a8d9 100644 --- a/drivers/media/i2c/st-vgxy61.c +++ b/drivers/media/i2c/st-vgxy61.c @@ -88,11 +88,16 @@ #define VGXY61_REG_PATGEN_SHORT_DATA_B CCI_REG16_LE(0x0954) #define VGXY61_REG_PATGEN_SHORT_DATA_GB CCI_REG16_LE(0x0956) #define VGXY61_REG_BYPASS_CTRL CCI_REG8(0x0a60) +#define VGXY61_ISL_BYPASS BIT(3) +#define VGXY61_ASIL_BYPASS BIT(2) #define VGX661_WIDTH 1464 #define VGX661_HEIGHT 1104 #define VGX761_WIDTH 1944 #define VGX761_HEIGHT 1204 +/* two status lines (ISL), of 256 bytes each */ +#define VGXY61_META_WIDTH 256 +#define VGXY61_META_HEIGHT 2 #define VGX661_DEFAULT_MODE 1 #define VGX761_DEFAULT_MODE 1 #define VGX661_SHORT_ROT_TERM 93 @@ -112,6 +117,18 @@ #define VGXY61_FWPATCH_REVISION_MINOR 0 #define VGXY61_FWPATCH_REVISION_MICRO 5 +enum { + VGXY61_PAD_SOURCE, + VGXY61_PAD_PIXEL, + VGXY61_PAD_META, + VGXY61_NUM_PADS, +}; + +enum { + VGXY61_STREAM_PIXEL, + VGXY61_STREAM_META, +}; + static const u8 patch_array[] = { 0xbf, 0x00, 0x05, 0x20, 0x06, 0x01, 0xe0, 0xe0, 0x04, 0x80, 0xe6, 0x45, 0xed, 0x6f, 0xfe, 0xff, 0x14, 0x80, 0x1f, 0x84, 0x10, 0x42, 0x05, 0x7c, @@ -382,7 +399,7 @@ struct vgxy61_dev { struct i2c_client *i2c_client; struct regmap *regmap; struct v4l2_subdev sd; - struct media_pad pad; + struct media_pad pads[VGXY61_NUM_PADS]; struct regulator_bulk_data supplies[ARRAY_SIZE(vgxy61_supply_name)]; struct gpio_desc *reset_gpio; struct clk *xclk; @@ -655,6 +672,13 @@ static int vgxy61_get_selection(struct v4l2_subdev *sd, { struct vgxy61_dev *sensor = to_vgxy61_dev(sd); + /* + * The embedded data stream doesn't support selection rectangles, + * neither on the embedded data pad nor on the source pad. + */ + if (sel->pad == VGXY61_PAD_META) + return -EINVAL; + switch (sel->target) { case V4L2_SEL_TGT_CROP: sel->r = sensor->current_mode->crop; @@ -676,6 +700,16 @@ static int vgxy61_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { + if (code->pad == VGXY61_PAD_META || + (code->pad == VGXY61_PAD_SOURCE && + code->stream == VGXY61_STREAM_META)) { + if (code->index > 0) + return -EINVAL; + + code->code = MEDIA_BUS_FMT_META_8; + return 0; + } + if (code->index >= ARRAY_SIZE(vgxy61_supported_codes)) return -EINVAL; @@ -703,6 +737,19 @@ static int vgxy61_enum_frame_size(struct v4l2_subdev *sd, { struct vgxy61_dev *sensor = to_vgxy61_dev(sd); + if (fse->pad == VGXY61_PAD_META || + (fse->pad == VGXY61_PAD_SOURCE && + fse->stream == VGXY61_STREAM_META)) { + if (fse->index > 0) + return -EINVAL; + + fse->min_width = VGXY61_META_WIDTH; + fse->max_width = VGXY61_META_WIDTH; + fse->min_height = VGXY61_META_HEIGHT; + fse->max_height = VGXY61_META_HEIGHT; + return 0; + } + if (fse->index >= sensor->sensor_modes_nb) return -EINVAL; @@ -1159,24 +1206,54 @@ static int vgxy61_s_stream(struct v4l2_subdev *sd, int enable) return ret; } -static int vgxy61_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) +static int __vgxy61_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_mbus_framefmt *format, + enum v4l2_subdev_format_whence which, + unsigned int pad, unsigned int stream) { struct vgxy61_dev *sensor = to_vgxy61_dev(sd); + struct v4l2_mbus_framefmt *src_pix_fmt, *src_meta_fmt, *pix_fmt, + *meta_fmt; const struct vgxy61_mode_info *new_mode; int ret; if (sensor->streaming) return -EBUSY; - ret = vgxy61_try_fmt_internal(sd, &format->format, &new_mode); + /* + * Allow setting format on internal pixel pad as well as the source + * pad's pixel stream (for compatibility). + */ + if ((pad == VGXY61_PAD_SOURCE && stream == VGXY61_STREAM_META) || + pad == VGXY61_PAD_META) { + *format = *v4l2_subdev_state_get_format(sd_state, pad, stream); + return 0; + } + + pix_fmt = v4l2_subdev_state_get_format(sd_state, VGXY61_PAD_PIXEL, 0); + meta_fmt = v4l2_subdev_state_get_format(sd_state, VGXY61_PAD_META, 0); + src_pix_fmt = v4l2_subdev_state_get_format(sd_state, VGXY61_PAD_SOURCE, + VGXY61_STREAM_PIXEL); + src_meta_fmt = v4l2_subdev_state_get_format(sd_state, VGXY61_PAD_SOURCE, + VGXY61_STREAM_META); + + ret = vgxy61_try_fmt_internal(sd, format, &new_mode); if (ret) return ret; - *v4l2_subdev_state_get_format(sd_state, format->pad) = format->format; + pix_fmt->width = format->width; + pix_fmt->height = format->height; + pix_fmt->code = format->code; + pix_fmt->field = V4L2_FIELD_NONE; + + *format = *src_pix_fmt = *pix_fmt; + meta_fmt->code = MEDIA_BUS_FMT_META_8; + meta_fmt->width = VGXY61_META_WIDTH; + meta_fmt->height = VGXY61_META_HEIGHT; + *src_meta_fmt = *meta_fmt; - if (format->which == V4L2_SUBDEV_FORMAT_TRY) + if (which == V4L2_SUBDEV_FORMAT_TRY) return 0; sensor->current_mode = new_mode; @@ -1202,16 +1279,78 @@ static int vgxy61_set_fmt(struct v4l2_subdev *sd, return ret; } +static int vgxy61_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) +{ + return __vgxy61_set_fmt(sd, sd_state, &fmt->format, fmt->which, + fmt->pad, fmt->stream); +} + +static int vgxy61_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *desc) +{ + struct v4l2_subdev_state *sd_state; + struct v4l2_mbus_framefmt *fmt; + + desc->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; + desc->num_entries = 2; + + sd_state = v4l2_subdev_lock_and_get_active_state(sd); + fmt = v4l2_subdev_state_get_format(sd_state, VGXY61_PAD_SOURCE, + VGXY61_STREAM_PIXEL); + v4l2_subdev_unlock_state(sd_state); + + desc->entry[0].stream = VGXY61_STREAM_PIXEL; + desc->entry[0].pixelcode = fmt->code; + desc->entry[0].bus.csi2.dt = get_data_type_by_code(fmt->code); + + desc->entry[1].stream = VGXY61_STREAM_META; + desc->entry[1].pixelcode = MEDIA_BUS_FMT_META_8; + desc->entry[1].bus.csi2.dt = MIPI_CSI2_DT_EMBEDDED_8B; + + return 0; +} + static int vgxy61_init_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { struct vgxy61_dev *sensor = to_vgxy61_dev(sd); struct v4l2_subdev_format fmt = { 0 }; + struct v4l2_subdev_route routes[] = { + { + .sink_pad = VGXY61_PAD_PIXEL, + .source_pad = VGXY61_PAD_SOURCE, + .source_stream = VGXY61_STREAM_PIXEL, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE | + V4L2_SUBDEV_ROUTE_FL_IMMUTABLE, + }, { + .sink_pad = VGXY61_PAD_META, + .source_pad = VGXY61_PAD_SOURCE, + .source_stream = VGXY61_STREAM_META, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + }; + struct v4l2_subdev_krouting routing = { + .routes = routes, + .num_routes = ARRAY_SIZE(routes), + }; + struct v4l2_subdev_state *active_state; + int ret; + + ret = v4l2_subdev_set_routing(sd, sd_state, &routing); + if (ret) + return ret; + + active_state = v4l2_subdev_get_locked_active_state(sd); vgxy61_fill_framefmt(sensor, sensor->current_mode, &fmt.format, VGXY61_MEDIA_BUS_FMT_DEF); - return vgxy61_set_fmt(sd, sd_state, &fmt); + return __vgxy61_set_fmt(sd, sd_state, &fmt.format, + active_state == sd_state ? + V4L2_SUBDEV_FORMAT_ACTIVE : + V4L2_SUBDEV_FORMAT_TRY, VGXY61_PAD_PIXEL, 0); } static int vgxy61_s_ctrl(struct v4l2_ctrl *ctrl) @@ -1364,6 +1503,7 @@ static const struct v4l2_subdev_pad_ops vgxy61_pad_ops = { .enum_mbus_code = vgxy61_enum_mbus_code, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = vgxy61_set_fmt, + .get_frame_desc = vgxy61_get_frame_desc, .get_selection = vgxy61_get_selection, .enum_frame_size = vgxy61_enum_frame_size, }; @@ -1478,7 +1618,8 @@ static int vgxy61_configure(struct vgxy61_dev *sensor) cci_write(sensor->regmap, VGXY61_REG_CLK_SYS_PLL_MULT, mult, &ret); cci_write(sensor->regmap, VGXY61_REG_OIF_CTRL, sensor->oif_ctrl, &ret); cci_write(sensor->regmap, VGXY61_REG_FRAME_CONTENT_CTRL, 0, &ret); - cci_write(sensor->regmap, VGXY61_REG_BYPASS_CTRL, 4, &ret); + cci_write(sensor->regmap, VGXY61_REG_BYPASS_CTRL, VGXY61_ASIL_BYPASS, + &ret); if (ret) return ret; vgxy61_update_gpios_strobe_polarity(sensor, sensor->gpios_polarity); @@ -1743,8 +1884,14 @@ static int vgxy61_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&sensor->sd, client, &vgxy61_subdev_ops); sensor->sd.internal_ops = &vgxy61_internal_ops; sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | - V4L2_SUBDEV_FL_HAS_EVENTS; - sensor->pad.flags = MEDIA_PAD_FL_SOURCE; + V4L2_SUBDEV_FL_HAS_EVENTS | + V4L2_SUBDEV_FL_STREAMS; + sensor->pads[VGXY61_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + sensor->pads[VGXY61_PAD_PIXEL].flags = + MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_INTERNAL; + sensor->pads[VGXY61_PAD_META].flags = + MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_INTERNAL; + sensor->sd.entity.ops = &vgxy61_subdev_entity_ops; sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; @@ -1778,7 +1925,8 @@ static int vgxy61_probe(struct i2c_client *client) goto error_power_off; } - ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); + ret = media_entity_pads_init(&sensor->sd.entity, + ARRAY_SIZE(sensor->pads), sensor->pads); if (ret) { dev_err(&client->dev, "pads init failed %d\n", ret); goto error_handler_free; From patchwork Fri Mar 15 08:51:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Massot X-Patchwork-Id: 13593184 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8469D1757A for ; Fri, 15 Mar 2024 08:52:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492748; cv=none; b=TDzWRjhU9s8zAj9c44GcPp2TA0w/9NTLWq5CrLPFvOQJDskJXaXisN0ePgjlX19vETK7ik93gL3ZQLosP/GASHSZeQsIdGnbpebgEUCL56tgvcRysTZKX88SbLXG097Y9mkR8d6Ln8xhyNswSZvcHNw2+f6GiCcZ70kFzt8dX/E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492748; c=relaxed/simple; bh=DDOtIr3XAoQXaip1wtwaI4NIljM7dI2HA6Kp+jDOJW8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pdxQnt8u+rJLRSBAT4OJFSjH8nlwYao87yUpGZexeo4yLCZ9JE7tYIQndzxBirJLf/6bAW+AoFvr73rYKosvyh4lgpiLJCyk0BZY5CVhOtYpp5qnoobLtM4kSinEB/rle0sqkGpddBaDSDo9rv0IJaYMfzp9ZQRU2eR9e58T+YU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=wTD5x/4Y; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="wTD5x/4Y" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1710492744; bh=DDOtIr3XAoQXaip1wtwaI4NIljM7dI2HA6Kp+jDOJW8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wTD5x/4YcvuJECNsGF2kPOK4740f57OHhkXctDM3e9bk5lURD1TdK8VK9jH/UUBsh DQdvfoymjURrzMZ9mxCGSb6toSKUFgjeqCoRUKPNHwGWI0usGYI3n/SR38R3cnxiE9 xqHJaQrExZzVKe1ZLPwYemdxVWqhMzNlfXUbvC4FD2dQHJfQ2wGavyXcP8Y7nA+uyJ 95ewhsUF8YawzbqhSR/8DSGYt8t0c7AzzyPjz+tbCl2IQB7n2Cqq1+RIwCG2obiMPz XAPjT0B6j0qvR91tBvtQuqYqTaRO9VFTb5Jz3xi9jkXovL5cSGpI7uZK6IA+mQ2FT5 C6JkqKrNQ+tkw== Received: from stla-brain-8255-1.home (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: jmassot) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 706F7378210D; Fri, 15 Mar 2024 08:52:24 +0000 (UTC) From: Julien Massot To: mchehab@kernel.org, sakari.ailus@linux.intel.com, benjamin.mugnier@foss.st.com, sylvain.petinot@foss.st.com Cc: linux-media@vger.kernel.org, kernel@collabora.com, Julien Massot Subject: [PATCH 3/4] media: i2c: st-vgxy61: Switch to {enable,disable}_streams Date: Fri, 15 Mar 2024 09:51:57 +0100 Message-ID: <20240315085158.1213159-4-julien.massot@collabora.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240315085158.1213159-1-julien.massot@collabora.com> References: <20240315085158.1213159-1-julien.massot@collabora.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Switch from s_stream to enable_streams and disable_streams callbacks. Signed-off-by: Julien Massot --- drivers/media/i2c/st-vgxy61.c | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c index e8302456a8d9..754853378ee6 100644 --- a/drivers/media/i2c/st-vgxy61.c +++ b/drivers/media/i2c/st-vgxy61.c @@ -420,7 +420,7 @@ struct vgxy61_dev { struct v4l2_ctrl *vblank_ctrl; struct v4l2_ctrl *vflip_ctrl; struct v4l2_ctrl *hflip_ctrl; - bool streaming; + u8 streaming; struct v4l2_mbus_framefmt fmt; const struct vgxy61_mode_info *sensor_modes; unsigned int sensor_modes_nb; @@ -1188,20 +1188,35 @@ static int vgxy61_stream_disable(struct vgxy61_dev *sensor) return ret; } -static int vgxy61_s_stream(struct v4l2_subdev *sd, int enable) +static int vgxy61_enable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, u32 pad, + u64 streams_mask) { struct vgxy61_dev *sensor = to_vgxy61_dev(sd); - struct v4l2_subdev_state *sd_state; int ret = 0; - sd_state = v4l2_subdev_lock_and_get_active_state(&sensor->sd); - - ret = enable ? vgxy61_stream_enable(sensor) : - vgxy61_stream_disable(sensor); + if (!sensor->streaming) + ret = vgxy61_stream_enable(sensor); if (!ret) - sensor->streaming = enable; + sensor->streaming |= streams_mask; - v4l2_subdev_unlock_state(sd_state); + return ret; +} + +static int vgxy61_disable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, u32 pad, + u64 streams_mask) +{ + struct vgxy61_dev *sensor = to_vgxy61_dev(sd); + int ret; + + sensor->streaming &= ~streams_mask; + if (sensor->streaming) + return 0; + + ret = vgxy61_stream_disable(sensor); + if (!ret) + sensor->streaming = false; return ret; } @@ -1496,7 +1511,7 @@ static const struct v4l2_subdev_core_ops vgxy61_core_ops = { }; static const struct v4l2_subdev_video_ops vgxy61_video_ops = { - .s_stream = vgxy61_s_stream, + .s_stream = v4l2_subdev_s_stream_helper, }; static const struct v4l2_subdev_pad_ops vgxy61_pad_ops = { @@ -1506,6 +1521,8 @@ static const struct v4l2_subdev_pad_ops vgxy61_pad_ops = { .get_frame_desc = vgxy61_get_frame_desc, .get_selection = vgxy61_get_selection, .enum_frame_size = vgxy61_enum_frame_size, + .enable_streams = vgxy61_enable_streams, + .disable_streams = vgxy61_disable_streams, }; static const struct v4l2_subdev_ops vgxy61_subdev_ops = { From patchwork Fri Mar 15 08:51:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Massot X-Patchwork-Id: 13593185 Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3842D175A5 for ; Fri, 15 Mar 2024 08:52:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492748; cv=none; b=S2wRTBWrnYUtkyiQlh+6LCBVcush+kqBwFnVeK/sraxZD91P6wXdWLQbdS4E0tdQfVQNxH+f/jxXfUhMbKnr3/jXZ2Uz8tQDjU5gMQB3HncPsLosvA8ams8bVfROlwBzO3a3YqHCk7ffXR21D9oQ/3ZOHLp48CbtmmB/64Z9vN8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710492748; c=relaxed/simple; bh=WBjcfuW+oYe6hv1ira32Mb7zDoaAk09BrvuRN8CLtrE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DDymE9nv9/2CqmKb2cthYcMk88LGZ68UfRADsg/QvyNBiF5egGt/3/pJwFboFXLctuHQbNRLz/MyPDqKzzce4CxbYSSzhdCJ55VzJ9s33u0IB5LQjwx4SJPpFf6N84sxrZRn0G3u+d5vELg3BuD6Cl7FkhoaE9SZP83SAcNeNu8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=n2Og9Qtb; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="n2Og9Qtb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1710492745; bh=WBjcfuW+oYe6hv1ira32Mb7zDoaAk09BrvuRN8CLtrE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n2Og9QtbZe8RTTvMEDcWU5zU56oK0g5/D68KQjW7makKxwjfJWnpWwk0KH6y+Nf1Z IkdmWT+pOcLkz3PLW57aWDo6mmd9H6W7CeaQxx8kxooJ3KDeKpLY6yAvpQinP8F1Pj yFWyD/YwKSgYT0nZ4uADKCXV6eaoAKFaH3s6M2PF4bQHOUhNPiYDeqtv/YA+juch1g qihY/C58/zhzBPsixBFrD2tIsVpMAkal8SnfG0c/X9YqyaGlnEyBZZhAQVeHh869LD Z15Enqze5uzKU8NHFYJS8y5hHP57W6bkKIi6B6V/wxPZxaFmQNvEkewO6FIG/sZMbu VVvfItnUDGjXA== Received: from stla-brain-8255-1.home (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: jmassot) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 1C7A0378210E; Fri, 15 Mar 2024 08:52:25 +0000 (UTC) From: Julien Massot To: mchehab@kernel.org, sakari.ailus@linux.intel.com, benjamin.mugnier@foss.st.com, sylvain.petinot@foss.st.com Cc: linux-media@vger.kernel.org, kernel@collabora.com, Julien Massot Subject: [PATCH 4/4] media: i2c: st-vgxy61: Implement set_routing callback Date: Fri, 15 Mar 2024 09:51:58 +0100 Message-ID: <20240315085158.1213159-5-julien.massot@collabora.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240315085158.1213159-1-julien.massot@collabora.com> References: <20240315085158.1213159-1-julien.massot@collabora.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 It's possible to bypass the Intelligent Status Line, through the bypass register. Allows to remove the internal route from the meta pad to the source pad. Signed-off-by: Julien Massot --- drivers/media/i2c/st-vgxy61.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c index 754853378ee6..f931c51fddbb 100644 --- a/drivers/media/i2c/st-vgxy61.c +++ b/drivers/media/i2c/st-vgxy61.c @@ -1221,6 +1221,46 @@ static int vgxy61_disable_streams(struct v4l2_subdev *sd, return ret; } +static int vgxy61_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing) +{ + struct vgxy61_dev *sensor = to_vgxy61_dev(sd); + struct device *dev = &sensor->i2c_client->dev; + unsigned int isl_bypass = VGXY61_ISL_BYPASS; + struct v4l2_subdev_route *route; + int ret; + + if (sensor->streaming) + return -EBUSY; + + if (routing->num_routes != 1 && routing->num_routes != 2) + return -EINVAL; + + route = &routing->routes[0]; + if (route->sink_pad != VGXY61_PAD_PIXEL || + route->source_stream != VGXY61_STREAM_PIXEL) { + dev_warn(dev, "Can't disable pixel route\n"); + return -EINVAL; + } + + if (routing->num_routes == 2) { + route = &routing->routes[1]; + if (route->sink_pad != VGXY61_PAD_META || + route->source_stream != VGXY61_STREAM_META) + return -EINVAL; + isl_bypass = 0; + } + + ret = cci_update_bits(sensor->regmap, VGXY61_REG_BYPASS_CTRL, + VGXY61_ISL_BYPASS, isl_bypass, NULL); + if (ret) + return ret; + + return v4l2_subdev_set_routing(sd, state, routing); +} + static int __vgxy61_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_mbus_framefmt *format, @@ -1518,6 +1558,7 @@ static const struct v4l2_subdev_pad_ops vgxy61_pad_ops = { .enum_mbus_code = vgxy61_enum_mbus_code, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = vgxy61_set_fmt, + .set_routing = vgxy61_set_routing, .get_frame_desc = vgxy61_get_frame_desc, .get_selection = vgxy61_get_selection, .enum_frame_size = vgxy61_enum_frame_size,