Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/connector: Add a function to lookup a TV mode by its name

As part of the command line parsing rework coming in the next patches,
we'll need to lookup drm_connector_tv_mode values by their name, already
defined in drm_tv_mode_enum_list.

In order to avoid any code duplication, let's do a function that will
perform a lookup of a TV mode name and return its value.

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>
Tested-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
Acked-in-principle-or-something-like-that-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://lore.kernel.org/r/20220728-rpi-analog-tv-properties-v10-7-256dad125326@cerno.tech
Signed-off-by: Maxime Ripard <maxime@cerno.tech>

+103
+24
drivers/gpu/drm/drm_connector.c
··· 995 995 }; 996 996 DRM_ENUM_NAME_FN(drm_get_tv_mode_name, drm_tv_mode_enum_list) 997 997 998 + /** 999 + * drm_get_tv_mode_from_name - Translates a TV mode name into its enum value 1000 + * @name: TV Mode name we want to convert 1001 + * @len: Length of @name 1002 + * 1003 + * Translates @name into an enum drm_connector_tv_mode. 1004 + * 1005 + * Returns: the enum value on success, a negative errno otherwise. 1006 + */ 1007 + int drm_get_tv_mode_from_name(const char *name, size_t len) 1008 + { 1009 + unsigned int i; 1010 + 1011 + for (i = 0; i < ARRAY_SIZE(drm_tv_mode_enum_list); i++) { 1012 + const struct drm_prop_enum_list *item = &drm_tv_mode_enum_list[i]; 1013 + 1014 + if (strlen(item->name) == len && !strncmp(item->name, name, len)) 1015 + return item->type; 1016 + } 1017 + 1018 + return -EINVAL; 1019 + } 1020 + EXPORT_SYMBOL(drm_get_tv_mode_from_name); 1021 + 998 1022 static const struct drm_prop_enum_list drm_tv_select_enum_list[] = { 999 1023 { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ 1000 1024 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
+1
drivers/gpu/drm/tests/Makefile
··· 3 3 obj-$(CONFIG_DRM_KUNIT_TEST) += \ 4 4 drm_buddy_test.o \ 5 5 drm_cmdline_parser_test.o \ 6 + drm_connector_test.o \ 6 7 drm_damage_helper_test.o \ 7 8 drm_dp_mst_helper_test.o \ 8 9 drm_format_helper_test.o \
+76
drivers/gpu/drm/tests/drm_connector_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Kunit test for drm_modes functions 4 + */ 5 + 6 + #include <drm/drm_connector.h> 7 + 8 + #include <kunit/test.h> 9 + 10 + struct drm_get_tv_mode_from_name_test { 11 + const char *name; 12 + enum drm_connector_tv_mode expected_mode; 13 + }; 14 + 15 + #define TV_MODE_NAME(_name, _mode) \ 16 + { \ 17 + .name = _name, \ 18 + .expected_mode = _mode, \ 19 + } 20 + 21 + static void drm_test_get_tv_mode_from_name_valid(struct kunit *test) 22 + { 23 + const struct drm_get_tv_mode_from_name_test *params = test->param_value; 24 + 25 + KUNIT_EXPECT_EQ(test, 26 + drm_get_tv_mode_from_name(params->name, strlen(params->name)), 27 + params->expected_mode); 28 + } 29 + 30 + static const 31 + struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = { 32 + TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC), 33 + TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443), 34 + TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J), 35 + TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL), 36 + TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M), 37 + TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N), 38 + TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM), 39 + }; 40 + 41 + static void 42 + drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t, 43 + char *desc) 44 + { 45 + sprintf(desc, "%s", t->name); 46 + } 47 + 48 + KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid, 49 + drm_get_tv_mode_from_name_valid_tests, 50 + drm_get_tv_mode_from_name_valid_desc); 51 + 52 + static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test) 53 + { 54 + const char *name = "NTS"; 55 + int ret; 56 + 57 + ret = drm_get_tv_mode_from_name(name, strlen(name)); 58 + KUNIT_EXPECT_LT(test, ret, 0); 59 + }; 60 + 61 + static struct kunit_case drm_get_tv_mode_from_name_tests[] = { 62 + KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid, 63 + drm_get_tv_mode_from_name_valid_gen_params), 64 + KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated), 65 + { } 66 + }; 67 + 68 + static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { 69 + .name = "drm_get_tv_mode_from_name", 70 + .test_cases = drm_get_tv_mode_from_name_tests, 71 + }; 72 + 73 + kunit_test_suite(drm_get_tv_mode_from_name_test_suite); 74 + 75 + MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); 76 + MODULE_LICENSE("GPL");
+2
include/drm/drm_connector.h
··· 1878 1878 const char *drm_get_content_protection_name(int val); 1879 1879 const char *drm_get_hdcp_content_type_name(int val); 1880 1880 1881 + int drm_get_tv_mode_from_name(const char *name, size_t len); 1882 + 1881 1883 int drm_mode_create_dvi_i_properties(struct drm_device *dev); 1882 1884 void drm_connector_attach_dp_subconnector_property(struct drm_connector *connector); 1883 1885