1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (C) 2024 Cirrus Logic, Inc. and 3 // Cirrus Logic International Semiconductor Ltd. 4 5 #include <kunit/device.h> 6 #include <kunit/test.h> 7 #include <linux/module.h> 8 #include <sound/control.h> 9 #include <sound/soc.h> 10 #include <sound/soc-card.h> 11 12 struct soc_card_test_priv { 13 struct device *card_dev; 14 struct snd_soc_card *card; 15 }; 16 17 static const struct snd_kcontrol_new test_card_controls[] = { 18 SOC_SINGLE("Fee", SND_SOC_NOPM, 0, 1, 0), 19 SOC_SINGLE("Fi", SND_SOC_NOPM, 1, 1, 0), 20 SOC_SINGLE("Fo", SND_SOC_NOPM, 2, 1, 0), 21 SOC_SINGLE("Fum", SND_SOC_NOPM, 3, 1, 0), 22 SOC_SINGLE("Left Fee", SND_SOC_NOPM, 4, 1, 0), 23 SOC_SINGLE("Right Fee", SND_SOC_NOPM, 5, 1, 0), 24 SOC_SINGLE("Left Fi", SND_SOC_NOPM, 6, 1, 0), 25 SOC_SINGLE("Right Fi", SND_SOC_NOPM, 7, 1, 0), 26 SOC_SINGLE("Left Fo", SND_SOC_NOPM, 8, 1, 0), 27 SOC_SINGLE("Right Fo", SND_SOC_NOPM, 9, 1, 0), 28 SOC_SINGLE("Left Fum", SND_SOC_NOPM, 10, 1, 0), 29 SOC_SINGLE("Right Fum", SND_SOC_NOPM, 11, 1, 0), 30 }; 31 32 static void test_snd_soc_card_get_kcontrol(struct kunit *test) 33 { 34 struct soc_card_test_priv *priv = test->priv; 35 struct snd_soc_card *card = priv->card; 36 struct snd_kcontrol *kc; 37 struct soc_mixer_control *mc; 38 int i, ret; 39 40 ret = snd_soc_add_card_controls(card, test_card_controls, ARRAY_SIZE(test_card_controls)); 41 KUNIT_ASSERT_EQ(test, ret, 0); 42 43 /* Look up every control */ 44 for (i = 0; i < ARRAY_SIZE(test_card_controls); ++i) { 45 kc = snd_soc_card_get_kcontrol(card, test_card_controls[i].name); 46 KUNIT_EXPECT_NOT_ERR_OR_NULL_MSG(test, kc, "Failed to find '%s'\n", 47 test_card_controls[i].name); 48 if (!kc) 49 continue; 50 51 /* Test that it is the correct control */ 52 mc = (struct soc_mixer_control *)kc->private_value; 53 KUNIT_EXPECT_EQ_MSG(test, mc->shift, i, "For '%s'\n", test_card_controls[i].name); 54 } 55 56 /* Test some names that should not be found */ 57 kc = snd_soc_card_get_kcontrol(card, "None"); 58 KUNIT_EXPECT_NULL(test, kc); 59 60 kc = snd_soc_card_get_kcontrol(card, "Left None"); 61 KUNIT_EXPECT_NULL(test, kc); 62 63 kc = snd_soc_card_get_kcontrol(card, "Left"); 64 KUNIT_EXPECT_NULL(test, kc); 65 66 kc = snd_soc_card_get_kcontrol(card, NULL); 67 KUNIT_EXPECT_NULL(test, kc); 68 } 69 70 static int soc_card_test_case_init(struct kunit *test) 71 { 72 struct soc_card_test_priv *priv; 73 int ret; 74 75 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 76 if (!priv) 77 return -ENOMEM; 78 79 test->priv = priv; 80 81 priv->card = kunit_kzalloc(test, sizeof(*priv->card), GFP_KERNEL); 82 if (!priv->card) 83 return -ENOMEM; 84 85 priv->card_dev = kunit_device_register(test, "sound-soc-card-test"); 86 priv->card_dev = get_device(priv->card_dev); 87 if (!priv->card_dev) 88 return -ENODEV; 89 90 priv->card->name = "soc-card-test"; 91 priv->card->dev = priv->card_dev; 92 priv->card->owner = THIS_MODULE; 93 94 ret = snd_soc_register_card(priv->card); 95 if (ret) { 96 put_device(priv->card_dev); 97 return ret; 98 } 99 100 return 0; 101 } 102 103 static void soc_card_test_case_exit(struct kunit *test) 104 { 105 struct soc_card_test_priv *priv = test->priv; 106 107 if (priv->card) 108 snd_soc_unregister_card(priv->card); 109 110 if (priv->card_dev) 111 put_device(priv->card_dev); 112 } 113 114 static struct kunit_case soc_card_test_cases[] = { 115 KUNIT_CASE(test_snd_soc_card_get_kcontrol), 116 {} 117 }; 118 119 static struct kunit_suite soc_card_test_suite = { 120 .name = "soc-card", 121 .test_cases = soc_card_test_cases, 122 .init = soc_card_test_case_init, 123 .exit = soc_card_test_case_exit, 124 }; 125 126 kunit_test_suites(&soc_card_test_suite); 127 128 MODULE_DESCRIPTION("ASoC soc-card KUnit test"); 129 MODULE_LICENSE("GPL"); 130