0001
0002
0003
0004
0005 #include <kunit/test.h>
0006 #include <linux/module.h>
0007 #include <sound/pcm.h>
0008 #include <sound/pcm_params.h>
0009 #include <sound/soc.h>
0010 #include <uapi/sound/asound.h>
0011
0012 static const struct {
0013 u32 rate;
0014 snd_pcm_format_t fmt;
0015 u8 channels;
0016 u8 tdm_width;
0017 u8 tdm_slots;
0018 u8 slot_multiple;
0019 u32 bclk;
0020 } tdm_params_to_bclk_cases[] = {
0021
0022
0023
0024 { 8000, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 0, 0, 128000 },
0025 { 8000, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 0, 0, 256000 },
0026 { 8000, SNDRV_PCM_FORMAT_S24_LE, 1, 0, 0, 0, 192000 },
0027 { 8000, SNDRV_PCM_FORMAT_S24_LE, 2, 0, 0, 0, 384000 },
0028 { 8000, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 0, 0, 256000 },
0029 { 8000, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 0, 0, 512000 },
0030 { 44100, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 0, 0, 705600 },
0031 { 44100, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 0, 0, 1411200 },
0032 { 44100, SNDRV_PCM_FORMAT_S24_LE, 1, 0, 0, 0, 1058400 },
0033 { 44100, SNDRV_PCM_FORMAT_S24_LE, 2, 0, 0, 0, 2116800 },
0034 { 44100, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 0, 0, 1411200 },
0035 { 44100, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 0, 0, 2822400 },
0036 { 384000, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 0, 0, 6144000 },
0037 { 384000, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 0, 0, 12288000 },
0038 { 384000, SNDRV_PCM_FORMAT_S24_LE, 1, 0, 0, 0, 9216000 },
0039 { 384000, SNDRV_PCM_FORMAT_S24_LE, 2, 0, 0, 0, 18432000 },
0040 { 384000, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 0, 0, 12288000 },
0041 { 384000, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 0, 0, 24576000 },
0042
0043
0044 { 8000, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 0, 2, 256000 },
0045 { 8000, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 0, 2, 256000 },
0046 { 8000, SNDRV_PCM_FORMAT_S24_LE, 1, 0, 0, 2, 384000 },
0047 { 8000, SNDRV_PCM_FORMAT_S24_LE, 2, 0, 0, 2, 384000 },
0048 { 8000, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 0, 2, 512000 },
0049 { 8000, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 0, 2, 512000 },
0050 { 44100, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 0, 2, 1411200 },
0051 { 44100, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 0, 2, 1411200 },
0052 { 44100, SNDRV_PCM_FORMAT_S24_LE, 1, 0, 0, 2, 2116800 },
0053 { 44100, SNDRV_PCM_FORMAT_S24_LE, 2, 0, 0, 2, 2116800 },
0054 { 44100, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 0, 2, 2822400 },
0055 { 44100, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 0, 2, 2822400 },
0056 { 384000, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 0, 2, 12288000 },
0057 { 384000, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 0, 2, 12288000 },
0058 { 384000, SNDRV_PCM_FORMAT_S24_LE, 1, 0, 0, 2, 18432000 },
0059 { 384000, SNDRV_PCM_FORMAT_S24_LE, 2, 0, 0, 2, 18432000 },
0060 { 384000, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 0, 2, 24576000 },
0061 { 384000, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 0, 2, 24576000 },
0062
0063
0064 { 8000, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 8, 0, 1024000 },
0065 { 8000, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 8, 0, 1024000 },
0066 { 8000, SNDRV_PCM_FORMAT_S16_LE, 3, 0, 8, 0, 1024000 },
0067 { 8000, SNDRV_PCM_FORMAT_S16_LE, 4, 0, 8, 0, 1024000 },
0068 { 8000, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 8, 0, 2048000 },
0069 { 8000, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 8, 0, 2048000 },
0070 { 8000, SNDRV_PCM_FORMAT_S32_LE, 3, 0, 8, 0, 2048000 },
0071 { 8000, SNDRV_PCM_FORMAT_S32_LE, 4, 0, 8, 0, 2048000 },
0072 { 384000, SNDRV_PCM_FORMAT_S16_LE, 1, 0, 8, 0, 49152000 },
0073 { 384000, SNDRV_PCM_FORMAT_S16_LE, 2, 0, 8, 0, 49152000 },
0074 { 384000, SNDRV_PCM_FORMAT_S16_LE, 3, 0, 8, 0, 49152000 },
0075 { 384000, SNDRV_PCM_FORMAT_S16_LE, 4, 0, 8, 0, 49152000 },
0076 { 384000, SNDRV_PCM_FORMAT_S32_LE, 1, 0, 8, 0, 98304000 },
0077 { 384000, SNDRV_PCM_FORMAT_S32_LE, 2, 0, 8, 0, 98304000 },
0078 { 384000, SNDRV_PCM_FORMAT_S32_LE, 3, 0, 8, 0, 98304000 },
0079 { 384000, SNDRV_PCM_FORMAT_S32_LE, 4, 0, 8, 0, 98304000 },
0080
0081
0082 { 8000, SNDRV_PCM_FORMAT_S16_LE, 1, 32, 0, 0, 256000 },
0083 { 8000, SNDRV_PCM_FORMAT_S16_LE, 2, 32, 0, 0, 512000 },
0084 { 8000, SNDRV_PCM_FORMAT_S16_LE, 3, 32, 0, 0, 768000 },
0085 { 8000, SNDRV_PCM_FORMAT_S16_LE, 4, 32, 0, 0, 1024000 },
0086 { 8000, SNDRV_PCM_FORMAT_S32_LE, 1, 32, 0, 0, 256000 },
0087 { 8000, SNDRV_PCM_FORMAT_S32_LE, 2, 32, 0, 0, 512000 },
0088 { 8000, SNDRV_PCM_FORMAT_S32_LE, 3, 32, 0, 0, 768000 },
0089 { 8000, SNDRV_PCM_FORMAT_S32_LE, 4, 32, 0, 0, 1024000 },
0090 { 384000, SNDRV_PCM_FORMAT_S16_LE, 1, 32, 0, 0, 12288000 },
0091 { 384000, SNDRV_PCM_FORMAT_S16_LE, 2, 32, 0, 0, 24576000 },
0092 { 384000, SNDRV_PCM_FORMAT_S16_LE, 3, 32, 0, 0, 36864000 },
0093 { 384000, SNDRV_PCM_FORMAT_S16_LE, 4, 32, 0, 0, 49152000 },
0094 { 384000, SNDRV_PCM_FORMAT_S32_LE, 1, 32, 0, 0, 12288000 },
0095 { 384000, SNDRV_PCM_FORMAT_S32_LE, 2, 32, 0, 0, 24576000 },
0096 { 384000, SNDRV_PCM_FORMAT_S32_LE, 3, 32, 0, 0, 36864000 },
0097 { 384000, SNDRV_PCM_FORMAT_S32_LE, 4, 32, 0, 0, 49152000 },
0098
0099
0100 { 8000, SNDRV_PCM_FORMAT_S16_LE, 1, 24, 6, 0, 1152000 },
0101 { 8000, SNDRV_PCM_FORMAT_S16_LE, 2, 24, 6, 0, 1152000 },
0102 { 8000, SNDRV_PCM_FORMAT_S16_LE, 3, 24, 6, 0, 1152000 },
0103 { 8000, SNDRV_PCM_FORMAT_S16_LE, 4, 24, 6, 0, 1152000 },
0104 { 8000, SNDRV_PCM_FORMAT_S24_LE, 1, 24, 6, 0, 1152000 },
0105 { 8000, SNDRV_PCM_FORMAT_S24_LE, 2, 24, 6, 0, 1152000 },
0106 { 8000, SNDRV_PCM_FORMAT_S24_LE, 3, 24, 6, 0, 1152000 },
0107 { 8000, SNDRV_PCM_FORMAT_S24_LE, 4, 24, 6, 0, 1152000 },
0108 { 192000, SNDRV_PCM_FORMAT_S16_LE, 1, 24, 6, 0, 27648000 },
0109 { 192000, SNDRV_PCM_FORMAT_S16_LE, 2, 24, 6, 0, 27648000 },
0110 { 192000, SNDRV_PCM_FORMAT_S16_LE, 3, 24, 6, 0, 27648000 },
0111 { 192000, SNDRV_PCM_FORMAT_S16_LE, 4, 24, 6, 0, 27648000 },
0112 { 192000, SNDRV_PCM_FORMAT_S24_LE, 1, 24, 6, 0, 27648000 },
0113 { 192000, SNDRV_PCM_FORMAT_S24_LE, 2, 24, 6, 0, 27648000 },
0114 { 192000, SNDRV_PCM_FORMAT_S24_LE, 3, 24, 6, 0, 27648000 },
0115 { 192000, SNDRV_PCM_FORMAT_S24_LE, 4, 24, 6, 0, 27648000 },
0116 };
0117
0118 static void test_tdm_params_to_bclk_one(struct kunit *test,
0119 unsigned int rate, snd_pcm_format_t fmt,
0120 unsigned int channels,
0121 unsigned int tdm_width, unsigned int tdm_slots,
0122 unsigned int slot_multiple,
0123 unsigned int expected_bclk)
0124 {
0125 struct snd_pcm_hw_params params;
0126 int got_bclk;
0127
0128 _snd_pcm_hw_params_any(¶ms);
0129 snd_mask_none(hw_param_mask(¶ms, SNDRV_PCM_HW_PARAM_FORMAT));
0130 hw_param_interval(¶ms, SNDRV_PCM_HW_PARAM_RATE)->min = rate;
0131 hw_param_interval(¶ms, SNDRV_PCM_HW_PARAM_RATE)->max = rate;
0132 hw_param_interval(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS)->min = channels;
0133 hw_param_interval(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS)->max = channels;
0134 params_set_format(¶ms, fmt);
0135
0136 got_bclk = snd_soc_tdm_params_to_bclk(¶ms, tdm_width, tdm_slots, slot_multiple);
0137 pr_debug("%s: r=%u sb=%u ch=%u tw=%u ts=%u sm=%u expected=%u got=%d\n",
0138 __func__,
0139 rate, params_width(¶ms), channels, tdm_width, tdm_slots, slot_multiple,
0140 expected_bclk, got_bclk);
0141 KUNIT_ASSERT_EQ(test, expected_bclk, (unsigned int)got_bclk);
0142 }
0143
0144 static void test_tdm_params_to_bclk(struct kunit *test)
0145 {
0146 int i;
0147
0148 for (i = 0; i < ARRAY_SIZE(tdm_params_to_bclk_cases); ++i) {
0149 test_tdm_params_to_bclk_one(test,
0150 tdm_params_to_bclk_cases[i].rate,
0151 tdm_params_to_bclk_cases[i].fmt,
0152 tdm_params_to_bclk_cases[i].channels,
0153 tdm_params_to_bclk_cases[i].tdm_width,
0154 tdm_params_to_bclk_cases[i].tdm_slots,
0155 tdm_params_to_bclk_cases[i].slot_multiple,
0156 tdm_params_to_bclk_cases[i].bclk);
0157
0158 if (tdm_params_to_bclk_cases[i].slot_multiple > 0)
0159 continue;
0160
0161
0162 test_tdm_params_to_bclk_one(test,
0163 tdm_params_to_bclk_cases[i].rate,
0164 tdm_params_to_bclk_cases[i].fmt,
0165 tdm_params_to_bclk_cases[i].channels,
0166 tdm_params_to_bclk_cases[i].tdm_width,
0167 tdm_params_to_bclk_cases[i].tdm_slots,
0168 1,
0169 tdm_params_to_bclk_cases[i].bclk);
0170 }
0171 }
0172
0173 static struct kunit_case soc_utils_test_cases[] = {
0174 KUNIT_CASE(test_tdm_params_to_bclk),
0175 {}
0176 };
0177
0178 static struct kunit_suite soc_utils_test_suite = {
0179 .name = "soc-utils",
0180 .test_cases = soc_utils_test_cases,
0181 };
0182
0183 kunit_test_suites(&soc_utils_test_suite);
0184
0185 MODULE_DESCRIPTION("ASoC soc-utils kunit test");
0186 MODULE_LICENSE("GPL");