Skip to content

Commit 2bf3c85

Browse files
libinyangtiwai
authored andcommitted
ALSA: hda - hdmi operate spdif based on pcm
Currently, the driver operates the spdif based on pin. This is ok for the current driver as pcm is statically bound to the pin. However, if the driver uses dynamically pcm assignment, this will cause confusion for user space. The patch changes spdif operation from pin based to pcm based. Signed-off-by: Libin Yang <[email protected]> Signed-off-by: Takashi Iwai <[email protected]>
1 parent 42b2987 commit 2bf3c85

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

sound/pci/hda/patch_hdmi.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ struct hdmi_spec {
140140
struct snd_array pins; /* struct hdmi_spec_per_pin */
141141
struct hda_pcm *pcm_rec[16];
142142
struct mutex pcm_lock;
143+
int pcm_used; /* counter of pcm_rec[] */
143144
unsigned int channels_max; /* max over all cvts */
144145

145146
struct hdmi_eld temp_eld;
@@ -387,6 +388,20 @@ static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid)
387388
return -EINVAL;
388389
}
389390

391+
static int hinfo_to_pcm_index(struct hda_codec *codec,
392+
struct hda_pcm_stream *hinfo)
393+
{
394+
struct hdmi_spec *spec = codec->spec;
395+
int pcm_idx;
396+
397+
for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++)
398+
if (get_pcm_rec(spec, pcm_idx)->stream == hinfo)
399+
return pcm_idx;
400+
401+
codec_warn(codec, "HDMI: hinfo %p not registered\n", hinfo);
402+
return -EINVAL;
403+
}
404+
390405
static int hinfo_to_pin_index(struct hda_codec *codec,
391406
struct hda_pcm_stream *hinfo)
392407
{
@@ -1548,13 +1563,17 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
15481563
{
15491564
struct hdmi_spec *spec = codec->spec;
15501565
struct snd_pcm_runtime *runtime = substream->runtime;
1551-
int pin_idx, cvt_idx, mux_idx = 0;
1566+
int pin_idx, cvt_idx, pcm_idx, mux_idx = 0;
15521567
struct hdmi_spec_per_pin *per_pin;
15531568
struct hdmi_eld *eld;
15541569
struct hdmi_spec_per_cvt *per_cvt = NULL;
15551570
int err;
15561571

15571572
/* Validate hinfo */
1573+
pcm_idx = hinfo_to_pcm_index(codec, hinfo);
1574+
if (pcm_idx < 0)
1575+
return -EINVAL;
1576+
15581577
mutex_lock(&spec->pcm_lock);
15591578
pin_idx = hinfo_to_pin_index(codec, hinfo);
15601579
if (!spec->dyn_pcm_assign) {
@@ -1596,7 +1615,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
15961615
if (is_haswell_plus(codec) || is_valleyview_plus(codec))
15971616
intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);
15981617

1599-
snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
1618+
snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid);
16001619

16011620
/* Initially set the converter's capabilities */
16021621
hinfo->channels_min = per_cvt->channels_min;
@@ -1613,7 +1632,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
16131632
!hinfo->rates || !hinfo->formats) {
16141633
per_cvt->assigned = 0;
16151634
hinfo->nid = 0;
1616-
snd_hda_spdif_ctls_unassign(codec, pin_idx);
1635+
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
16171636
mutex_unlock(&spec->pcm_lock);
16181637
return -ENODEV;
16191638
}
@@ -2043,12 +2062,15 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
20432062
struct snd_pcm_substream *substream)
20442063
{
20452064
struct hdmi_spec *spec = codec->spec;
2046-
int cvt_idx, pin_idx;
2065+
int cvt_idx, pin_idx, pcm_idx;
20472066
struct hdmi_spec_per_cvt *per_cvt;
20482067
struct hdmi_spec_per_pin *per_pin;
20492068
int pinctl;
20502069

20512070
if (hinfo->nid) {
2071+
pcm_idx = hinfo_to_pcm_index(codec, hinfo);
2072+
if (snd_BUG_ON(pcm_idx < 0))
2073+
return -EINVAL;
20522074
cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid);
20532075
if (snd_BUG_ON(cvt_idx < 0))
20542076
return -EINVAL;
@@ -2079,7 +2101,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
20792101
pinctl & ~PIN_OUT);
20802102
}
20812103

2082-
snd_hda_spdif_ctls_unassign(codec, pin_idx);
2104+
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
20832105

20842106
mutex_lock(&per_pin->lock);
20852107
per_pin->chmap_set = false;
@@ -2277,6 +2299,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
22772299
per_pin->pcm = info;
22782300
}
22792301
spec->pcm_rec[pin_idx] = info;
2302+
spec->pcm_used++;
22802303
info->pcm_type = HDA_PCM_TYPE_HDMI;
22812304
info->own_chmap = true;
22822305

@@ -2353,6 +2376,7 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
23532376
HDA_PCM_TYPE_HDMI);
23542377
if (err < 0)
23552378
return err;
2379+
/* pin number is the same with pcm number so far */
23562380
snd_hda_spdif_ctls_unassign(codec, pin_idx);
23572381

23582382
/* add control for ELD Bytes */

0 commit comments

Comments
 (0)