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

Configure Feed

Select the types of activity you want to include in your feed.

drm/tegra: hda: Extract HDA format parsing code

This code can be reused for HDMI, so extract it into a reusable
function.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+93 -71
+1
drivers/gpu/drm/tegra/Makefile
··· 10 10 dc.o \ 11 11 output.o \ 12 12 rgb.o \ 13 + hda.o \ 13 14 hdmi.o \ 14 15 mipi-phy.o \ 15 16 dsi.o \
+63
drivers/gpu/drm/tegra/hda.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright (C) 2019 NVIDIA Corporation 4 + */ 5 + 6 + #include <linux/bug.h> 7 + 8 + #include <sound/hda_verbs.h> 9 + 10 + #include "hda.h" 11 + 12 + void tegra_hda_parse_format(unsigned int format, struct tegra_hda_format *fmt) 13 + { 14 + unsigned int mul, div, bits, channels; 15 + 16 + if (format & AC_FMT_TYPE_NON_PCM) 17 + fmt->pcm = false; 18 + else 19 + fmt->pcm = true; 20 + 21 + if (format & AC_FMT_BASE_44K) 22 + fmt->sample_rate = 44100; 23 + else 24 + fmt->sample_rate = 48000; 25 + 26 + mul = (format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT; 27 + div = (format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT; 28 + 29 + fmt->sample_rate *= (mul + 1) / (div + 1); 30 + 31 + switch (format & AC_FMT_BITS_MASK) { 32 + case AC_FMT_BITS_8: 33 + fmt->bits = 8; 34 + break; 35 + 36 + case AC_FMT_BITS_16: 37 + fmt->bits = 16; 38 + break; 39 + 40 + case AC_FMT_BITS_20: 41 + fmt->bits = 20; 42 + break; 43 + 44 + case AC_FMT_BITS_24: 45 + fmt->bits = 24; 46 + break; 47 + 48 + case AC_FMT_BITS_32: 49 + fmt->bits = 32; 50 + break; 51 + 52 + default: 53 + bits = (format & AC_FMT_BITS_MASK) >> AC_FMT_BITS_SHIFT; 54 + WARN(1, "invalid number of bits: %#x\n", bits); 55 + fmt->bits = 8; 56 + break; 57 + } 58 + 59 + channels = (format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT; 60 + 61 + /* channels are encoded as n - 1 */ 62 + fmt->channels = channels + 1; 63 + }
+20
drivers/gpu/drm/tegra/hda.h
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright (C) 2019 NVIDIA Corporation 4 + */ 5 + 6 + #ifndef DRM_TEGRA_HDA_H 7 + #define DRM_TEGRA_HDA_H 1 8 + 9 + #include <linux/types.h> 10 + 11 + struct tegra_hda_format { 12 + unsigned int sample_rate; 13 + unsigned int channels; 14 + unsigned int bits; 15 + bool pcm; 16 + }; 17 + 18 + void tegra_hda_parse_format(unsigned int format, struct tegra_hda_format *fmt); 19 + 20 + #endif
+9 -71
drivers/gpu/drm/tegra/sor.c
··· 19 19 20 20 #include <soc/tegra/pmc.h> 21 21 22 - #include <sound/hda_verbs.h> 23 - 24 22 #include <drm/drm_atomic_helper.h> 25 23 #include <drm/drm_dp_helper.h> 26 24 #include <drm/drm_panel.h> ··· 26 28 27 29 #include "dc.h" 28 30 #include "drm.h" 31 + #include "hda.h" 29 32 #include "sor.h" 30 33 #include "trace.h" 31 34 ··· 392 393 int (*remove)(struct tegra_sor *sor); 393 394 }; 394 395 395 - struct tegra_sor_audio { 396 - unsigned int sample_rate; 397 - unsigned int channels; 398 - unsigned int bits; 399 - bool pcm; 400 - }; 401 - 402 396 struct tegra_sor { 403 397 struct host1x_client client; 404 398 struct tegra_output output; ··· 428 436 struct delayed_work scdc; 429 437 bool scdc_enabled; 430 438 431 - struct tegra_sor_audio audio; 439 + struct tegra_hda_format format; 432 440 }; 433 441 434 442 struct tegra_sor_state { ··· 2181 2189 return err; 2182 2190 } 2183 2191 2184 - frame.channels = sor->audio.channels; 2192 + frame.channels = sor->format.channels; 2185 2193 2186 2194 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); 2187 2195 if (err < 0) { ··· 2210 2218 value |= SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_HDA); 2211 2219 2212 2220 /* inject null samples */ 2213 - if (sor->audio.channels != 2) 2221 + if (sor->format.channels != 2) 2214 2222 value &= ~SOR_AUDIO_CNTRL_INJECT_NULLSMPL; 2215 2223 else 2216 2224 value |= SOR_AUDIO_CNTRL_INJECT_NULLSMPL; ··· 2241 2249 value = SOR_HDMI_AUDIO_N_RESET | SOR_HDMI_AUDIO_N_LOOKUP; 2242 2250 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N); 2243 2251 2244 - value = (24000 * 4096) / (128 * sor->audio.sample_rate / 1000); 2252 + value = (24000 * 4096) / (128 * sor->format.sample_rate / 1000); 2245 2253 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0320); 2246 2254 tegra_sor_writel(sor, 4096, SOR_AUDIO_NVAL_0320); 2247 2255 ··· 2254 2262 tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_1764); 2255 2263 tegra_sor_writel(sor, 18816, SOR_AUDIO_NVAL_1764); 2256 2264 2257 - value = (24000 * 6144) / (128 * sor->audio.sample_rate / 1000); 2265 + value = (24000 * 6144) / (128 * sor->format.sample_rate / 1000); 2258 2266 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0480); 2259 2267 tegra_sor_writel(sor, 6144, SOR_AUDIO_NVAL_0480); 2260 2268 2261 - value = (24000 * 12288) / (128 * sor->audio.sample_rate / 1000); 2269 + value = (24000 * 12288) / (128 * sor->format.sample_rate / 1000); 2262 2270 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0960); 2263 2271 tegra_sor_writel(sor, 12288, SOR_AUDIO_NVAL_0960); 2264 2272 2265 - value = (24000 * 24576) / (128 * sor->audio.sample_rate / 1000); 2273 + value = (24000 * 24576) / (128 * sor->format.sample_rate / 1000); 2266 2274 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_1920); 2267 2275 tegra_sor_writel(sor, 24576, SOR_AUDIO_NVAL_1920); 2268 2276 ··· 3191 3199 return 0; 3192 3200 } 3193 3201 3194 - static void tegra_hda_parse_format(unsigned int format, 3195 - struct tegra_sor_audio *audio) 3196 - { 3197 - unsigned int mul, div, bits, channels; 3198 - 3199 - if (format & AC_FMT_TYPE_NON_PCM) 3200 - audio->pcm = false; 3201 - else 3202 - audio->pcm = true; 3203 - 3204 - if (format & AC_FMT_BASE_44K) 3205 - audio->sample_rate = 44100; 3206 - else 3207 - audio->sample_rate = 48000; 3208 - 3209 - mul = (format & AC_FMT_MULT_MASK) >> AC_FMT_MULT_SHIFT; 3210 - div = (format & AC_FMT_DIV_MASK) >> AC_FMT_DIV_SHIFT; 3211 - 3212 - audio->sample_rate = audio->sample_rate * (mul + 1) / (div + 1); 3213 - 3214 - switch (format & AC_FMT_BITS_MASK) { 3215 - case AC_FMT_BITS_8: 3216 - audio->bits = 8; 3217 - break; 3218 - 3219 - case AC_FMT_BITS_16: 3220 - audio->bits = 16; 3221 - break; 3222 - 3223 - case AC_FMT_BITS_20: 3224 - audio->bits = 20; 3225 - break; 3226 - 3227 - case AC_FMT_BITS_24: 3228 - audio->bits = 24; 3229 - break; 3230 - 3231 - case AC_FMT_BITS_32: 3232 - audio->bits = 32; 3233 - break; 3234 - 3235 - default: 3236 - bits = (format & AC_FMT_BITS_MASK) >> AC_FMT_BITS_SHIFT; 3237 - WARN(1, "invalid number of bits: %#x\n", bits); 3238 - audio->bits = 8; 3239 - break; 3240 - } 3241 - 3242 - channels = (format & AC_FMT_CHAN_MASK) >> AC_FMT_CHAN_SHIFT; 3243 - 3244 - /* channels are encoded as n - 1 */ 3245 - audio->channels = channels + 1; 3246 - } 3247 - 3248 3202 static irqreturn_t tegra_sor_irq(int irq, void *data) 3249 3203 { 3250 3204 struct tegra_sor *sor = data; ··· 3207 3269 3208 3270 format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK; 3209 3271 3210 - tegra_hda_parse_format(format, &sor->audio); 3272 + tegra_hda_parse_format(format, &sor->format); 3211 3273 3212 3274 tegra_sor_hdmi_audio_enable(sor); 3213 3275 } else {