aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r--sound/pci/hda/patch_hdmi.c99
1 files changed, 92 insertions, 7 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 19cb72db9c3..342540128fb 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -324,6 +324,66 @@ static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid)
324 return -EINVAL; 324 return -EINVAL;
325} 325}
326 326
327static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_info *uinfo)
329{
330 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
331 struct hdmi_spec *spec;
332 int pin_idx;
333
334 spec = codec->spec;
335 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
336
337 pin_idx = kcontrol->private_value;
338 uinfo->count = spec->pins[pin_idx].sink_eld.eld_size;
339
340 return 0;
341}
342
343static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
345{
346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
347 struct hdmi_spec *spec;
348 int pin_idx;
349
350 spec = codec->spec;
351 pin_idx = kcontrol->private_value;
352
353 memcpy(ucontrol->value.bytes.data,
354 spec->pins[pin_idx].sink_eld.eld_buffer, ELD_MAX_SIZE);
355
356 return 0;
357}
358
359static struct snd_kcontrol_new eld_bytes_ctl = {
360 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
361 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
362 .name = "ELD",
363 .info = hdmi_eld_ctl_info,
364 .get = hdmi_eld_ctl_get,
365};
366
367static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
368 int device)
369{
370 struct snd_kcontrol *kctl;
371 struct hdmi_spec *spec = codec->spec;
372 int err;
373
374 kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
375 if (!kctl)
376 return -ENOMEM;
377 kctl->private_value = pin_idx;
378 kctl->id.device = device;
379
380 err = snd_hda_ctl_add(codec, spec->pins[pin_idx].pin_nid, kctl);
381 if (err < 0)
382 return err;
383
384 return 0;
385}
386
327#ifdef BE_PARANOID 387#ifdef BE_PARANOID
328static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, 388static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
329 int *packet_index, int *byte_index) 389 int *packet_index, int *byte_index)
@@ -967,19 +1027,12 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
967 1027
968 per_pin->pin_nid = pin_nid; 1028 per_pin->pin_nid = pin_nid;
969 1029
970 err = snd_hda_input_jack_add(codec, pin_nid,
971 SND_JACK_VIDEOOUT, NULL);
972 if (err < 0)
973 return err;
974
975 err = hdmi_read_pin_conn(codec, pin_idx); 1030 err = hdmi_read_pin_conn(codec, pin_idx);
976 if (err < 0) 1031 if (err < 0)
977 return err; 1032 return err;
978 1033
979 spec->num_pins++; 1034 spec->num_pins++;
980 1035
981 hdmi_present_sense(codec, pin_nid, eld);
982
983 return 0; 1036 return 0;
984} 1037}
985 1038
@@ -1162,6 +1215,25 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
1162 return 0; 1215 return 0;
1163} 1216}
1164 1217
1218static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
1219{
1220 int err;
1221 char hdmi_str[32];
1222 struct hdmi_spec *spec = codec->spec;
1223 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1224 int pcmdev = spec->pcm_rec[pin_idx].device;
1225
1226 snprintf(hdmi_str, sizeof(hdmi_str), "HDMI/DP,pcm=%d", pcmdev);
1227
1228 err = snd_hda_input_jack_add(codec, per_pin->pin_nid,
1229 SND_JACK_VIDEOOUT, pcmdev > 0 ? hdmi_str : NULL);
1230 if (err < 0)
1231 return err;
1232
1233 hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld);
1234 return 0;
1235}
1236
1165static int generic_hdmi_build_controls(struct hda_codec *codec) 1237static int generic_hdmi_build_controls(struct hda_codec *codec)
1166{ 1238{
1167 struct hdmi_spec *spec = codec->spec; 1239 struct hdmi_spec *spec = codec->spec;
@@ -1170,12 +1242,25 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1170 1242
1171 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1243 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1172 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1244 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1245
1246 err = generic_hdmi_build_jack(codec, pin_idx);
1247 if (err < 0)
1248 return err;
1249
1173 err = snd_hda_create_spdif_out_ctls(codec, 1250 err = snd_hda_create_spdif_out_ctls(codec,
1174 per_pin->pin_nid, 1251 per_pin->pin_nid,
1175 per_pin->mux_nids[0]); 1252 per_pin->mux_nids[0]);
1176 if (err < 0) 1253 if (err < 0)
1177 return err; 1254 return err;
1178 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1255 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1256
1257 /* add control for ELD Bytes */
1258 err = hdmi_create_eld_ctl(codec,
1259 pin_idx,
1260 spec->pcm_rec[pin_idx].device);
1261
1262 if (err < 0)
1263 return err;
1179 } 1264 }
1180 1265
1181 return 0; 1266 return 0;