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.

ALSA: hda/hdmi: Use only dynamic PCM device allocation

Per discussion on the alsa-devel mailing list [1], the legacy PIN to PCM
device mapping is obsolete nowadays. The maximum number of the simultaneously
usable PCM devices is equal to the HDMI codec converters.

Remove the extra PCM devices (beyond the detected converters) and force
the use of the dynamic PCM device allocation. The legacy code is removed.

I believe that all HDMI codecs have the jack sensing feature. Move the check
to the codec probe function and print a warning, if a codec without this
feature is detected.

[1] https://lore.kernel.org/alsa-devel/2f37e0b2-1e82-8c0b-2bbd-1e5038d6ecc6@perex.cz/

Cc: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20220922084017.25925-1-perex@perex.cz
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Jaroslav Kysela and committed by
Takashi Iwai
ef6f5494 af45a0d3

+28 -132
-1
include/sound/hda_codec.h
··· 258 258 unsigned int link_down_at_suspend:1; /* link down at runtime suspend */ 259 259 unsigned int relaxed_resume:1; /* don't resume forcibly for jack */ 260 260 unsigned int forced_resume:1; /* forced resume for jack */ 261 - unsigned int mst_no_extra_pcms:1; /* no backup PCMs for DP-MST */ 262 261 263 262 #ifdef CONFIG_PM 264 263 unsigned long power_on_acct;
+28 -125
sound/pci/hda/patch_hdmi.c
··· 167 167 struct hdmi_ops ops; 168 168 169 169 bool dyn_pin_out; 170 - bool dyn_pcm_assign; 171 - bool dyn_pcm_no_legacy; 172 170 /* hdmi interrupt trigger control flag for Nvidia codec */ 173 171 bool hdmi_intr_trig_ctrl; 174 172 bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */ ··· 1186 1188 spec->ops.pin_cvt_fixup(codec, per_pin, cvt_nid); 1187 1189 } 1188 1190 1189 - /* called in hdmi_pcm_open when no pin is assigned to the PCM 1190 - * in dyn_pcm_assign mode. 1191 - */ 1191 + /* called in hdmi_pcm_open when no pin is assigned to the PCM */ 1192 1192 static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo, 1193 1193 struct hda_codec *codec, 1194 1194 struct snd_pcm_substream *substream) ··· 1254 1258 1255 1259 mutex_lock(&spec->pcm_lock); 1256 1260 pin_idx = hinfo_to_pin_index(codec, hinfo); 1257 - if (!spec->dyn_pcm_assign) { 1258 - if (snd_BUG_ON(pin_idx < 0)) { 1259 - err = -EINVAL; 1260 - goto unlock; 1261 - } 1262 - } else { 1263 - /* no pin is assigned to the PCM 1264 - * PA need pcm open successfully when probe 1265 - */ 1266 - if (pin_idx < 0) { 1267 - err = hdmi_pcm_open_no_pin(hinfo, codec, substream); 1268 - goto unlock; 1269 - } 1261 + /* no pin is assigned to the PCM 1262 + * PA need pcm open successfully when probe 1263 + */ 1264 + if (pin_idx < 0) { 1265 + err = hdmi_pcm_open_no_pin(hinfo, codec, substream); 1266 + goto unlock; 1270 1267 } 1271 1268 1272 1269 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, false); ··· 1364 1375 { 1365 1376 int i; 1366 1377 1367 - /* on the new machines, try to assign the pcm slot dynamically, 1368 - * not use the preferred fixed map (legacy way) anymore. 1369 - */ 1370 - if (spec->dyn_pcm_no_legacy) 1371 - goto last_try; 1372 - 1373 - /* 1374 - * generic_hdmi_build_pcms() may allocate extra PCMs on some 1375 - * platforms (with maximum of 'num_nids + dev_num - 1') 1376 - * 1377 - * The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n 1378 - * if m==0. This guarantees that dynamic pcm assignments are compatible 1379 - * with the legacy static per_pin-pcm assignment that existed in the 1380 - * days before DP-MST. 1381 - * 1382 - * Intel DP-MST prefers this legacy behavior for compatibility, too. 1383 - * 1384 - * per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)). 1385 - */ 1386 - 1387 - if (per_pin->dev_id == 0 || spec->intel_hsw_fixup) { 1388 - if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap)) 1389 - return per_pin->pin_nid_idx; 1390 - } else { 1391 - i = spec->num_nids + (per_pin->dev_id - 1); 1392 - if (i < spec->pcm_used && !(test_bit(i, &spec->pcm_bitmap))) 1393 - return i; 1394 - } 1395 - 1396 - /* have a second try; check the area over num_nids */ 1397 - for (i = spec->num_nids; i < spec->pcm_used; i++) { 1398 - if (!test_bit(i, &spec->pcm_bitmap)) 1399 - return i; 1400 - } 1401 - 1402 - last_try: 1403 - /* the last try; check the empty slots in pins */ 1404 1378 for (i = 0; i < spec->pcm_used; i++) { 1405 1379 if (!test_bit(i, &spec->pcm_bitmap)) 1406 1380 return i; ··· 1525 1573 */ 1526 1574 pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); 1527 1575 1528 - if (spec->dyn_pcm_assign) { 1529 - if (eld->eld_valid) { 1530 - hdmi_attach_hda_pcm(spec, per_pin); 1531 - hdmi_pcm_setup_pin(spec, per_pin); 1532 - } else { 1533 - hdmi_pcm_reset_pin(spec, per_pin); 1534 - hdmi_detach_hda_pcm(spec, per_pin); 1535 - } 1576 + if (eld->eld_valid) { 1577 + hdmi_attach_hda_pcm(spec, per_pin); 1578 + hdmi_pcm_setup_pin(spec, per_pin); 1579 + } else { 1580 + hdmi_pcm_reset_pin(spec, per_pin); 1581 + hdmi_detach_hda_pcm(spec, per_pin); 1536 1582 } 1537 1583 /* if pcm_idx == -1, it means this is in monitor connection event 1538 1584 * we can get the correct pcm_idx now. ··· 1892 1942 * structures based on worst case. 1893 1943 */ 1894 1944 dev_num = spec->dev_num; 1895 - } else if (spec->dyn_pcm_assign && codec->dp_mst) { 1945 + } else if (codec->dp_mst) { 1896 1946 dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1; 1897 1947 /* 1898 1948 * spec->dev_num is the maxinum number of device entries ··· 1917 1967 if (!per_pin) 1918 1968 return -ENOMEM; 1919 1969 1920 - if (spec->dyn_pcm_assign) { 1921 - per_pin->pcm = NULL; 1922 - per_pin->pcm_idx = -1; 1923 - } else { 1924 - per_pin->pcm = get_hdmi_pcm(spec, pin_idx); 1925 - per_pin->pcm_idx = pin_idx; 1926 - } 1970 + per_pin->pcm = NULL; 1971 + per_pin->pcm_idx = -1; 1927 1972 per_pin->pin_nid = pin_nid; 1928 1973 per_pin->pin_nid_idx = spec->num_nids; 1929 1974 per_pin->dev_id = i; ··· 1927 1982 err = hdmi_read_pin_conn(codec, pin_idx); 1928 1983 if (err < 0) 1929 1984 return err; 1985 + if (!is_jack_detectable(codec, pin_nid)) 1986 + codec_warn(codec, "HDMI: pin NID 0x%x - jack not detectable\n", pin_nid); 1930 1987 spec->num_pins++; 1931 1988 } 1932 1989 spec->num_nids++; ··· 2076 2129 2077 2130 mutex_lock(&spec->pcm_lock); 2078 2131 pin_idx = hinfo_to_pin_index(codec, hinfo); 2079 - if (spec->dyn_pcm_assign && pin_idx < 0) { 2080 - /* when dyn_pcm_assign and pcm is not bound to a pin 2081 - * skip pin setup and return 0 to make audio playback 2082 - * be ongoing 2132 + if (pin_idx < 0) { 2133 + /* when pcm is not bound to a pin skip pin setup and return 0 2134 + * to make audio playback be ongoing 2083 2135 */ 2084 2136 pin_cvt_fixup(codec, NULL, cvt_nid); 2085 2137 snd_hda_codec_setup_stream(codec, cvt_nid, ··· 2181 2235 snd_hda_spdif_ctls_unassign(codec, pcm_idx); 2182 2236 clear_bit(pcm_idx, &spec->pcm_in_use); 2183 2237 pin_idx = hinfo_to_pin_index(codec, hinfo); 2184 - if (spec->dyn_pcm_assign && pin_idx < 0) 2238 + if (pin_idx < 0) 2185 2239 goto unlock; 2186 2240 2187 2241 if (snd_BUG_ON(pin_idx < 0)) { ··· 2279 2333 struct hdmi_spec *spec = codec->spec; 2280 2334 int idx, pcm_num; 2281 2335 2282 - /* 2283 - * for non-mst mode, pcm number is the same as before 2284 - * for DP MST mode without extra PCM, pcm number is same 2285 - * for DP MST mode with extra PCMs, pcm number is 2286 - * (nid number + dev_num - 1) 2287 - * dev_num is the device entry number in a pin 2288 - */ 2289 - 2290 - if (spec->dyn_pcm_no_legacy && codec->mst_no_extra_pcms) 2291 - pcm_num = spec->num_cvts; 2292 - else if (codec->mst_no_extra_pcms) 2293 - pcm_num = spec->num_nids; 2294 - else 2295 - pcm_num = spec->num_nids + spec->dev_num - 1; 2296 - 2336 + /* limit the PCM devices to the codec converters */ 2337 + pcm_num = spec->num_cvts; 2297 2338 codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num); 2298 2339 2299 2340 for (idx = 0; idx < pcm_num; idx++) { ··· 2319 2386 { 2320 2387 char hdmi_str[32] = "HDMI/DP"; 2321 2388 struct hdmi_spec *spec = codec->spec; 2322 - struct hdmi_spec_per_pin *per_pin = get_pin(spec, pcm_idx); 2323 2389 struct snd_jack *jack; 2324 2390 int pcmdev = get_pcm_rec(spec, pcm_idx)->device; 2325 2391 int err; 2326 2392 2327 2393 if (pcmdev > 0) 2328 2394 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); 2329 - if (!spec->dyn_pcm_assign && 2330 - !is_jack_detectable(codec, per_pin->pin_nid)) 2331 - strncat(hdmi_str, " Phantom", 2332 - sizeof(hdmi_str) - strlen(hdmi_str) - 1); 2333 2395 2334 2396 err = snd_jack_new(codec->card, hdmi_str, SND_JACK_AVOUT, &jack, 2335 2397 true, false); ··· 2357 2429 /* create the spdif for each pcm 2358 2430 * pin will be bound when monitor is connected 2359 2431 */ 2360 - if (spec->dyn_pcm_assign) 2361 - err = snd_hda_create_dig_out_ctls(codec, 2432 + err = snd_hda_create_dig_out_ctls(codec, 2362 2433 0, spec->cvt_nids[0], 2363 2434 HDA_PCM_TYPE_HDMI); 2364 - else { 2365 - struct hdmi_spec_per_pin *per_pin = 2366 - get_pin(spec, pcm_idx); 2367 - err = snd_hda_create_dig_out_ctls(codec, 2368 - per_pin->pin_nid, 2369 - per_pin->mux_nids[0], 2370 - HDA_PCM_TYPE_HDMI); 2371 - } 2372 2435 if (err < 0) 2373 2436 return err; 2374 2437 snd_hda_spdif_ctls_unassign(codec, pcm_idx); ··· 2479 2560 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) { 2480 2561 if (spec->pcm_rec[pcm_idx].jack == NULL) 2481 2562 continue; 2482 - if (spec->dyn_pcm_assign) 2483 - snd_device_free(codec->card, 2484 - spec->pcm_rec[pcm_idx].jack); 2485 - else 2486 - spec->pcm_rec[pcm_idx].jack = NULL; 2563 + snd_device_free(codec->card, spec->pcm_rec[pcm_idx].jack); 2487 2564 } 2488 2565 2489 2566 generic_spec_free(codec); ··· 2959 3044 return err; 2960 3045 spec = codec->spec; 2961 3046 codec->dp_mst = true; 2962 - spec->dyn_pcm_assign = true; 2963 3047 spec->vendor_nid = vendor_nid; 2964 3048 spec->port_map = port_map; 2965 3049 spec->port_num = port_num; ··· 3022 3108 * the index indicate the port number. 3023 3109 */ 3024 3110 static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; 3025 - int ret; 3026 3111 3027 - ret = intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4, 3028 - enable_silent_stream); 3029 - if (!ret) { 3030 - struct hdmi_spec *spec = codec->spec; 3031 - 3032 - spec->dyn_pcm_no_legacy = true; 3033 - } 3034 - 3035 - return ret; 3112 + return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4, 3113 + enable_silent_stream); 3036 3114 } 3037 3115 3038 3116 static int patch_i915_adlp_hdmi(struct hda_codec *codec) ··· 3664 3758 codec->dp_mst = true; 3665 3759 3666 3760 spec = codec->spec; 3667 - spec->dyn_pcm_assign = true; 3668 3761 3669 3762 err = hdmi_parse_codec(codec); 3670 3763 if (err < 0) { ··· 3943 4038 return err; 3944 4039 3945 4040 codec->dp_mst = true; 3946 - codec->mst_no_extra_pcms = true; 3947 4041 spec = codec->spec; 3948 4042 spec->dyn_pin_out = true; 3949 - spec->dyn_pcm_assign = true; 3950 4043 spec->hdmi_intr_trig_ctrl = true; 3951 4044 3952 4045 return tegra_hdmi_init(codec);
-3
sound/soc/codecs/hda.c
··· 224 224 goto err; 225 225 } 226 226 227 - /* configure codec for 1:1 PCM:DAI mapping */ 228 - codec->mst_no_extra_pcms = 1; 229 - 230 227 ret = snd_hda_codec_parse_pcms(codec); 231 228 if (ret < 0) { 232 229 dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret);
-3
sound/soc/codecs/hdac_hda.c
··· 461 461 dev_dbg(&hdev->dev, "no patch file found\n"); 462 462 } 463 463 464 - /* configure codec for 1:1 PCM:DAI mapping */ 465 - hcodec->mst_no_extra_pcms = 1; 466 - 467 464 ret = snd_hda_codec_parse_pcms(hcodec); 468 465 if (ret < 0) { 469 466 dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret);