hdmi.c (73cd0490819d2a693928c5977280dd31b756cb42) hdmi.c (ad781b550f9a8829e3dae4bd3d18c4a126a53d04)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 *
4 * hdmi.c - routines for HDMI/DisplayPort codecs
5 *
6 * Copyright(c) 2008-2010 Intel Corporation
7 * Copyright (c) 2006 ATI Technologies Inc.
8 * Copyright (c) 2008 NVIDIA Corp. All rights reserved.

--- 2073 unchanged lines hidden (view full) ---

2082 hdmi_array_free(spec);
2083 kfree(spec);
2084 codec->spec = NULL;
2085 }
2086 codec->dp_mst = false;
2087}
2088EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_spec_free, "SND_HDA_CODEC_HDMI");
2089
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 *
4 * hdmi.c - routines for HDMI/DisplayPort codecs
5 *
6 * Copyright(c) 2008-2010 Intel Corporation
7 * Copyright (c) 2006 ATI Technologies Inc.
8 * Copyright (c) 2008 NVIDIA Corp. All rights reserved.

--- 2073 unchanged lines hidden (view full) ---

2082 hdmi_array_free(spec);
2083 kfree(spec);
2084 codec->spec = NULL;
2085 }
2086 codec->dp_mst = false;
2087}
2088EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_spec_free, "SND_HDA_CODEC_HDMI");
2089
2090void snd_hda_hdmi_generic_free(struct hda_codec *codec)
2090void snd_hda_hdmi_generic_remove(struct hda_codec *codec)
2091{
2092 struct hdmi_spec *spec = codec->spec;
2093 int pin_idx, pcm_idx;
2094
2095 if (spec->acomp_registered) {
2096 snd_hdac_acomp_exit(&codec->bus->core);
2097 } else if (codec_has_acomp(codec)) {
2098 snd_hdac_acomp_register_notifier(&codec->bus->core, NULL);

--- 9 unchanged lines hidden (view full) ---

2108 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
2109 if (spec->pcm_rec[pcm_idx].jack == NULL)
2110 continue;
2111 snd_device_free(codec->card, spec->pcm_rec[pcm_idx].jack);
2112 }
2113
2114 snd_hda_hdmi_generic_spec_free(codec);
2115}
2091{
2092 struct hdmi_spec *spec = codec->spec;
2093 int pin_idx, pcm_idx;
2094
2095 if (spec->acomp_registered) {
2096 snd_hdac_acomp_exit(&codec->bus->core);
2097 } else if (codec_has_acomp(codec)) {
2098 snd_hdac_acomp_register_notifier(&codec->bus->core, NULL);

--- 9 unchanged lines hidden (view full) ---

2108 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
2109 if (spec->pcm_rec[pcm_idx].jack == NULL)
2110 continue;
2111 snd_device_free(codec->card, spec->pcm_rec[pcm_idx].jack);
2112 }
2113
2114 snd_hda_hdmi_generic_spec_free(codec);
2115}
2116EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_free, "SND_HDA_CODEC_HDMI");
2116EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_remove, "SND_HDA_CODEC_HDMI");
2117
2118int snd_hda_hdmi_generic_suspend(struct hda_codec *codec)
2119{
2120 struct hdmi_spec *spec = codec->spec;
2121 int pin_idx;
2122
2123 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2124 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2125 cancel_delayed_work_sync(&per_pin->work);
2126 }
2127 return 0;
2128}
2129EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_suspend, "SND_HDA_CODEC_HDMI");
2130
2131int snd_hda_hdmi_generic_resume(struct hda_codec *codec)
2132{
2133 struct hdmi_spec *spec = codec->spec;
2134 int pin_idx;
2135
2117
2118int snd_hda_hdmi_generic_suspend(struct hda_codec *codec)
2119{
2120 struct hdmi_spec *spec = codec->spec;
2121 int pin_idx;
2122
2123 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2124 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2125 cancel_delayed_work_sync(&per_pin->work);
2126 }
2127 return 0;
2128}
2129EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_suspend, "SND_HDA_CODEC_HDMI");
2130
2131int snd_hda_hdmi_generic_resume(struct hda_codec *codec)
2132{
2133 struct hdmi_spec *spec = codec->spec;
2134 int pin_idx;
2135
2136 codec->patch_ops.init(codec);
2136 snd_hda_codec_init(codec);
2137 snd_hda_regmap_sync(codec);
2138
2139 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2140 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2141 hdmi_present_sense(per_pin, 1);
2142 }
2143 return 0;
2144}
2145EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_resume, "SND_HDA_CODEC_HDMI");
2146
2137 snd_hda_regmap_sync(codec);
2138
2139 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2140 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2141 hdmi_present_sense(per_pin, 1);
2142 }
2143 return 0;
2144}
2145EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_resume, "SND_HDA_CODEC_HDMI");
2146
2147static const struct hda_codec_ops generic_hdmi_patch_ops = {
2148 .init = snd_hda_hdmi_generic_init,
2149 .free = snd_hda_hdmi_generic_free,
2150 .build_pcms = snd_hda_hdmi_generic_build_pcms,
2151 .build_controls = snd_hda_hdmi_generic_build_controls,
2152 .unsol_event = snd_hda_hdmi_generic_unsol_event,
2153 .suspend = snd_hda_hdmi_generic_suspend,
2154 .resume = snd_hda_hdmi_generic_resume,
2155};
2156
2157static const struct hdmi_ops generic_standard_hdmi_ops = {
2158 .pin_get_eld = hdmi_pin_get_eld,
2159 .pin_setup_infoframe = hdmi_pin_setup_infoframe,
2160 .pin_hbr_setup = hdmi_pin_hbr_setup,
2161 .setup_stream = snd_hda_hdmi_setup_stream,
2162};
2163
2164/* allocate codec->spec and assign/initialize generic parser ops */

--- 15 unchanged lines hidden (view full) ---

2180 spec->chmap.ops.get_chmap = hdmi_get_chmap;
2181 spec->chmap.ops.set_chmap = hdmi_set_chmap;
2182 spec->chmap.ops.is_pcm_attached = is_hdmi_pcm_attached;
2183 spec->chmap.ops.get_spk_alloc = hdmi_get_spk_alloc;
2184
2185 codec->spec = spec;
2186 hdmi_array_init(spec, 4);
2187
2147static const struct hdmi_ops generic_standard_hdmi_ops = {
2148 .pin_get_eld = hdmi_pin_get_eld,
2149 .pin_setup_infoframe = hdmi_pin_setup_infoframe,
2150 .pin_hbr_setup = hdmi_pin_hbr_setup,
2151 .setup_stream = snd_hda_hdmi_setup_stream,
2152};
2153
2154/* allocate codec->spec and assign/initialize generic parser ops */

--- 15 unchanged lines hidden (view full) ---

2170 spec->chmap.ops.get_chmap = hdmi_get_chmap;
2171 spec->chmap.ops.set_chmap = hdmi_set_chmap;
2172 spec->chmap.ops.is_pcm_attached = is_hdmi_pcm_attached;
2173 spec->chmap.ops.get_spk_alloc = hdmi_get_spk_alloc;
2174
2175 codec->spec = spec;
2176 hdmi_array_init(spec, 4);
2177
2188 codec->patch_ops = generic_hdmi_patch_ops;
2189
2190 return 0;
2191}
2192EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_alloc, "SND_HDA_CODEC_HDMI");
2193
2194/* generic HDMI parser */
2178 return 0;
2179}
2180EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_alloc, "SND_HDA_CODEC_HDMI");
2181
2182/* generic HDMI parser */
2195int patch_generic_hdmi(struct hda_codec *codec)
2183int snd_hda_hdmi_generic_probe(struct hda_codec *codec)
2196{
2197 int err;
2198
2199 err = snd_hda_hdmi_generic_alloc(codec);
2200 if (err < 0)
2201 return err;
2202
2203 err = snd_hda_hdmi_parse_codec(codec);
2204 if (err < 0) {
2205 snd_hda_hdmi_generic_spec_free(codec);
2206 return err;
2207 }
2208
2209 snd_hda_hdmi_generic_init_per_pins(codec);
2210 return 0;
2211}
2184{
2185 int err;
2186
2187 err = snd_hda_hdmi_generic_alloc(codec);
2188 if (err < 0)
2189 return err;
2190
2191 err = snd_hda_hdmi_parse_codec(codec);
2192 if (err < 0) {
2193 snd_hda_hdmi_generic_spec_free(codec);
2194 return err;
2195 }
2196
2197 snd_hda_hdmi_generic_init_per_pins(codec);
2198 return 0;
2199}
2212EXPORT_SYMBOL_NS_GPL(patch_generic_hdmi, "SND_HDA_CODEC_HDMI");
2200EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_generic_probe, "SND_HDA_CODEC_HDMI");
2213
2214/*
2215 * generic audio component binding
2216 */
2217
2218/* turn on / off the unsol event jack detection dynamically */
2219static void reprogram_jack_detect(struct hda_codec *codec, hda_nid_t nid,
2220 int dev_id, bool use_acomp)

--- 120 unchanged lines hidden (view full) ---

2341 spec->acomp_registered = true;
2342 }
2343}
2344EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_acomp_init, "SND_HDA_CODEC_HDMI");
2345
2346/*
2347 */
2348
2201
2202/*
2203 * generic audio component binding
2204 */
2205
2206/* turn on / off the unsol event jack detection dynamically */
2207static void reprogram_jack_detect(struct hda_codec *codec, hda_nid_t nid,
2208 int dev_id, bool use_acomp)

--- 120 unchanged lines hidden (view full) ---

2329 spec->acomp_registered = true;
2330 }
2331}
2332EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_acomp_init, "SND_HDA_CODEC_HDMI");
2333
2334/*
2335 */
2336
2349static int patch_gf_hdmi(struct hda_codec *codec)
2337enum {
2338 MODEL_GENERIC,
2339 MODEL_GF,
2340};
2341
2342static int generichdmi_probe(struct hda_codec *codec,
2343 const struct hda_device_id *id)
2350{
2351 int err;
2352
2344{
2345 int err;
2346
2353 err = patch_generic_hdmi(codec);
2354 if (err)
2347 err = snd_hda_hdmi_generic_probe(codec);
2348 if (err < 0)
2355 return err;
2349 return err;
2356
2357 /*
2358 * Glenfly GPUs have two codecs, stream switches from one codec to
2359 * another, need to do actual clean-ups in codec_cleanup_stream
2360 */
2350 /*
2351 * Glenfly GPUs have two codecs, stream switches from one codec to
2352 * another, need to do actual clean-ups in codec_cleanup_stream
2353 */
2361 codec->no_sticky_stream = 1;
2354 if (id->driver_data == MODEL_GF)
2355 codec->no_sticky_stream = 1;
2356
2362 return 0;
2363}
2364
2357 return 0;
2358}
2359
2360static const struct hda_codec_ops generichdmi_codec_ops = {
2361 .probe = generichdmi_probe,
2362 .remove = snd_hda_hdmi_generic_remove,
2363 .init = snd_hda_hdmi_generic_init,
2364 .build_pcms = snd_hda_hdmi_generic_build_pcms,
2365 .build_controls = snd_hda_hdmi_generic_build_controls,
2366 .unsol_event = snd_hda_hdmi_generic_unsol_event,
2367 .suspend = snd_hda_hdmi_generic_suspend,
2368 .resume = snd_hda_hdmi_generic_resume,
2369};
2370
2365/*
2371/*
2366 * patch entries
2367 */
2372 */
2368static const struct hda_device_id snd_hda_id_hdmi[] = {
2369HDA_CODEC_ENTRY(0x00147a47, "Loongson HDMI", patch_generic_hdmi),
2370HDA_CODEC_ENTRY(0x10951390, "SiI1390 HDMI", patch_generic_hdmi),
2371HDA_CODEC_ENTRY(0x10951392, "SiI1392 HDMI", patch_generic_hdmi),
2372HDA_CODEC_ENTRY(0x17e80047, "Chrontel HDMI", patch_generic_hdmi),
2373HDA_CODEC_ENTRY(0x67663d82, "Arise 82 HDMI/DP", patch_gf_hdmi),
2374HDA_CODEC_ENTRY(0x67663d83, "Arise 83 HDMI/DP", patch_gf_hdmi),
2375HDA_CODEC_ENTRY(0x67663d84, "Arise 84 HDMI/DP", patch_gf_hdmi),
2376HDA_CODEC_ENTRY(0x67663d85, "Arise 85 HDMI/DP", patch_gf_hdmi),
2377HDA_CODEC_ENTRY(0x67663d86, "Arise 86 HDMI/DP", patch_gf_hdmi),
2378HDA_CODEC_ENTRY(0x67663d87, "Arise 87 HDMI/DP", patch_gf_hdmi),
2379HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi),
2380HDA_CODEC_ENTRY(0x11069f85, "VX11 HDMI/DP", patch_generic_hdmi),
2381HDA_CODEC_ENTRY(0x1d179f86, "ZX-100S HDMI/DP", patch_gf_hdmi),
2382HDA_CODEC_ENTRY(0x1d179f87, "ZX-100S HDMI/DP", patch_gf_hdmi),
2383HDA_CODEC_ENTRY(0x1d179f88, "KX-5000 HDMI/DP", patch_gf_hdmi),
2384HDA_CODEC_ENTRY(0x1d179f89, "KX-5000 HDMI/DP", patch_gf_hdmi),
2385HDA_CODEC_ENTRY(0x1d179f8a, "KX-6000 HDMI/DP", patch_gf_hdmi),
2386HDA_CODEC_ENTRY(0x1d179f8b, "KX-6000 HDMI/DP", patch_gf_hdmi),
2387HDA_CODEC_ENTRY(0x1d179f8c, "KX-6000G HDMI/DP", patch_gf_hdmi),
2388HDA_CODEC_ENTRY(0x1d179f8d, "KX-6000G HDMI/DP", patch_gf_hdmi),
2389HDA_CODEC_ENTRY(0x1d179f8e, "KX-7000 HDMI/DP", patch_gf_hdmi),
2390HDA_CODEC_ENTRY(0x1d179f8f, "KX-7000 HDMI/DP", patch_gf_hdmi),
2391HDA_CODEC_ENTRY(0x1d179f90, "KX-7000 HDMI/DP", patch_gf_hdmi),
2392HDA_CODEC_ENTRY(0x80862801, "Bearlake HDMI", patch_generic_hdmi),
2393HDA_CODEC_ENTRY(0x80862802, "Cantiga HDMI", patch_generic_hdmi),
2394HDA_CODEC_ENTRY(0x80862803, "Eaglelake HDMI", patch_generic_hdmi),
2395HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
2396HDA_CODEC_ENTRY(0x808629fb, "Crestline HDMI", patch_generic_hdmi),
2397/* special ID for generic HDMI */
2398HDA_CODEC_ENTRY(HDA_CODEC_ID_GENERIC_HDMI, "Generic HDMI", patch_generic_hdmi),
2399{} /* terminator */
2373static const struct hda_device_id snd_hda_id_generichdmi[] = {
2374 HDA_CODEC_ID_MODEL(0x00147a47, "Loongson HDMI", MODEL_GENERIC),
2375 HDA_CODEC_ID_MODEL(0x10951390, "SiI1390 HDMI", MODEL_GENERIC),
2376 HDA_CODEC_ID_MODEL(0x10951392, "SiI1392 HDMI", MODEL_GENERIC),
2377 HDA_CODEC_ID_MODEL(0x11069f84, "VX11 HDMI/DP", MODEL_GENERIC),
2378 HDA_CODEC_ID_MODEL(0x11069f85, "VX11 HDMI/DP", MODEL_GENERIC),
2379 HDA_CODEC_ID_MODEL(0x17e80047, "Chrontel HDMI", MODEL_GENERIC),
2380 HDA_CODEC_ID_MODEL(0x1d179f86, "ZX-100S HDMI/DP", MODEL_GF),
2381 HDA_CODEC_ID_MODEL(0x1d179f87, "ZX-100S HDMI/DP", MODEL_GF),
2382 HDA_CODEC_ID_MODEL(0x1d179f88, "KX-5000 HDMI/DP", MODEL_GF),
2383 HDA_CODEC_ID_MODEL(0x1d179f89, "KX-5000 HDMI/DP", MODEL_GF),
2384 HDA_CODEC_ID_MODEL(0x1d179f8a, "KX-6000 HDMI/DP", MODEL_GF),
2385 HDA_CODEC_ID_MODEL(0x1d179f8b, "KX-6000 HDMI/DP", MODEL_GF),
2386 HDA_CODEC_ID_MODEL(0x1d179f8c, "KX-6000G HDMI/DP", MODEL_GF),
2387 HDA_CODEC_ID_MODEL(0x1d179f8d, "KX-6000G HDMI/DP", MODEL_GF),
2388 HDA_CODEC_ID_MODEL(0x1d179f8e, "KX-7000 HDMI/DP", MODEL_GF),
2389 HDA_CODEC_ID_MODEL(0x1d179f8f, "KX-7000 HDMI/DP", MODEL_GF),
2390 HDA_CODEC_ID_MODEL(0x1d179f90, "KX-7000 HDMI/DP", MODEL_GF),
2391 HDA_CODEC_ID_MODEL(0x67663d82, "Arise 82 HDMI/DP", MODEL_GF),
2392 HDA_CODEC_ID_MODEL(0x67663d83, "Arise 83 HDMI/DP", MODEL_GF),
2393 HDA_CODEC_ID_MODEL(0x67663d84, "Arise 84 HDMI/DP", MODEL_GF),
2394 HDA_CODEC_ID_MODEL(0x67663d85, "Arise 85 HDMI/DP", MODEL_GF),
2395 HDA_CODEC_ID_MODEL(0x67663d86, "Arise 86 HDMI/DP", MODEL_GF),
2396 HDA_CODEC_ID_MODEL(0x67663d87, "Arise 87 HDMI/DP", MODEL_GF),
2397 HDA_CODEC_ID_MODEL(0x80862801, "Bearlake HDMI", MODEL_GENERIC),
2398 HDA_CODEC_ID_MODEL(0x80862802, "Cantiga HDMI", MODEL_GENERIC),
2399 HDA_CODEC_ID_MODEL(0x80862803, "Eaglelake HDMI", MODEL_GENERIC),
2400 HDA_CODEC_ID_MODEL(0x80862880, "CedarTrail HDMI", MODEL_GENERIC),
2401 HDA_CODEC_ID_MODEL(0x808629fb, "Crestline HDMI", MODEL_GENERIC),
2402 /* special ID for generic HDMI */
2403 HDA_CODEC_ID_MODEL(HDA_CODEC_ID_GENERIC_HDMI, "Generic HDMI", MODEL_GENERIC),
2404 {} /* terminator */
2400};
2405};
2401MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_hdmi);
2406MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_generichdmi);
2402
2403MODULE_LICENSE("GPL");
2407
2408MODULE_LICENSE("GPL");
2404MODULE_DESCRIPTION("HDMI HD-audio codec");
2409MODULE_DESCRIPTION("Generic HDMI HD-audio codec");
2405
2410
2406static struct hda_codec_driver hdmi_driver = {
2407 .id = snd_hda_id_hdmi,
2411static struct hda_codec_driver generichdmi_driver = {
2412 .id = snd_hda_id_generichdmi,
2413 .ops = &generichdmi_codec_ops,
2408};
2409
2414};
2415
2410module_hda_codec_driver(hdmi_driver);
2416module_hda_codec_driver(generichdmi_driver);