diff --git a/drivers/media/platform/tegra/camera/vi/channel.c b/drivers/media/platform/tegra/camera/vi/channel.c index 804ed8e8..61606c62 100644 --- a/drivers/media/platform/tegra/camera/vi/channel.c +++ b/drivers/media/platform/tegra/camera/vi/channel.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1159,11 +1160,19 @@ tegra_channel_g_dv_timings(struct file *file, void *fh, { struct tegra_channel *chan = video_drvdata(file); +#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */ + if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, g_dv_timings)) + return -ENOTTY; + + return v4l2_device_call_until_err(chan->video->v4l2_dev, + chan->grp_id, pad, g_dv_timings, 0, timings); +#else if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, g_dv_timings)) return -ENOTTY; return v4l2_device_call_until_err(chan->video->v4l2_dev, chan->grp_id, video, g_dv_timings, timings); +#endif } static int @@ -1175,7 +1184,11 @@ tegra_channel_s_dv_timings(struct file *file, void *fh, struct v4l2_dv_timings curr_timings; int ret; +#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */ + if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, s_dv_timings)) +#else if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, s_dv_timings)) +#endif return -ENOTTY; ret = tegra_channel_g_dv_timings(file, fh, &curr_timings); @@ -1188,9 +1201,13 @@ tegra_channel_s_dv_timings(struct file *file, void *fh, if (vb2_is_busy(&chan->queue)) return -EBUSY; +#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */ + ret = v4l2_device_call_until_err(chan->video->v4l2_dev, + chan->grp_id, pad, s_dv_timings, 0, timings); +#else ret = v4l2_device_call_until_err(chan->video->v4l2_dev, chan->grp_id, video, s_dv_timings, timings); - +#endif if (!ret) tegra_channel_update_format(chan, bt->width, bt->height, chan->fmtinfo->fourcc, &chan->fmtinfo->bpp, @@ -1208,11 +1225,19 @@ tegra_channel_query_dv_timings(struct file *file, void *fh, { struct tegra_channel *chan = video_drvdata(file); +#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */ + if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, query_dv_timings)) + return -ENOTTY; + + return v4l2_device_call_until_err(chan->video->v4l2_dev, + chan->grp_id, pad, query_dv_timings, 0, timings); +#else if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, query_dv_timings)) return -ENOTTY; return v4l2_device_call_until_err(chan->video->v4l2_dev, chan->grp_id, video, query_dv_timings, timings); +#endif } static int @@ -1849,8 +1874,13 @@ static void tegra_channel_populate_dev_info(struct tegra_camera_dev_info *cdev, if (chan->pg_mode) { /* TPG mode */ cdev->sensor_type = SENSORTYPE_VIRTUAL; +#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */ + } else if (v4l2_subdev_has_op(chan->subdev_on_csi, + pad, g_dv_timings)) { +#else } else if (v4l2_subdev_has_op(chan->subdev_on_csi, video, g_dv_timings)) { +#endif /* HDMI-IN */ cdev->sensor_type = SENSORTYPE_OTHER; pixelclock = tegra_channel_get_max_source_rate(); @@ -2180,7 +2210,11 @@ tegra_channel_enum_input(struct file *file, void *fh, struct v4l2_input *inp) return -ENODEV; inp->type = V4L2_INPUT_TYPE_CAMERA; +#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */ + if (v4l2_subdev_has_op(sd_on_csi, pad, s_dv_timings)) { +#else if (v4l2_subdev_has_op(sd_on_csi, video, s_dv_timings)) { +#endif inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; len = snprintf(inp->name, sizeof(inp->name), "HDMI %u", diff --git a/scripts/conftest/Makefile b/scripts/conftest/Makefile index b186fb31..3e8d04cd 100644 --- a/scripts/conftest/Makefile +++ b/scripts/conftest/Makefile @@ -180,6 +180,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_notifier_init NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_async_nf_init_has_v4l2_dev_arg NV_CONFTEST_FUNCTION_COMPILE_TESTS += __v4l2_async_nf_add_subdev NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_get_frame_interval +NV_CONFTEST_FUNCTION_COMPILE_TESTS += v4l2_subdev_pad_ops_struct_has_dv_timings NV_CONFTEST_FUNCTION_COMPILE_TESTS += vm_area_struct_has_const_vm_flags NV_CONFTEST_GENERIC_COMPILE_TESTS += is_export_symbol_present_drm_gem_prime_fd_to_handle NV_CONFTEST_GENERIC_COMPILE_TESTS += is_export_symbol_present_drm_gem_prime_handle_to_fd diff --git a/scripts/conftest/conftest.sh b/scripts/conftest/conftest.sh index d39f6e85..4a3d6183 100755 --- a/scripts/conftest/conftest.sh +++ b/scripts/conftest/conftest.sh @@ -8014,6 +8014,28 @@ compile_test() { "NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL" "" "types" ;; + v4l2_subdev_pad_ops_struct_has_dv_timings) + # + # Determine if struct v4l2_subdev_pad_ops has the 'g_dv_timings' + # and 's_dv_timings' function pointers. + # + # Commit 009e12561369 ("media: v4l2-subdev: Add pad versions of dv + # timing subdev calls)" added 'g_dv_timings' and 's_dv_timnigs' to + # the v4l2_subdev_pad_ops structure. Commit d8c9a6e204f1 ("media: + # v4l2-subdev: Remove non-pad dv timing callbacks") then removed the + # the original 'g_dv_timings' and 's_dv_timings' from the + # v4l2_subdev_video_ops structure. These changes were made for Linux + # v6.10. + CODE=" + #define _LINUX_EFI_H + #include + int conftest_v4l2_subdev_pad_ops_struct_has_dv_timings(void) { + return offsetof(struct v4l2_subdev_pad_ops, g_dv_timings); + } + " + compile_check_conftest "$CODE" \ + "NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS" "" "types" + ;; crypto_engine_ctx_struct_removed_test) # # Determine if struct 'crypto_engine_ctx' is removed in linux kernel.