@@ -75,6 +75,8 @@ struct hdmi_spec_per_cvt {
75
75
76
76
struct hdmi_spec_per_pin {
77
77
hda_nid_t pin_nid ;
78
+ /* pin idx, different device entries on the same pin use the same idx */
79
+ int pin_nid_idx ;
78
80
int num_mux_nids ;
79
81
hda_nid_t mux_nids [HDA_MAX_CONNECTIONS ];
80
82
int mux_idx ;
@@ -87,6 +89,7 @@ struct hdmi_spec_per_pin {
87
89
struct snd_kcontrol * eld_ctl ;
88
90
struct snd_jack * acomp_jack ; /* jack via audio component */
89
91
struct hda_pcm * pcm ; /* pointer to spec->pcm_rec[n] dynamically*/
92
+ int pcm_idx ; /* which pcm is attached. -1 means no pcm is attached */
90
93
int repoll_count ;
91
94
bool setup ; /* the stream has been set up by prepare callback */
92
95
int channels ; /* current number of channels */
@@ -140,6 +143,8 @@ struct hdmi_spec {
140
143
struct snd_array pins ; /* struct hdmi_spec_per_pin */
141
144
struct hda_pcm * pcm_rec [16 ];
142
145
struct mutex pcm_lock ;
146
+ /* pcm_bitmap means which pcms have been assigned to pins*/
147
+ unsigned long pcm_bitmap ;
143
148
int pcm_used ; /* counter of pcm_rec[] */
144
149
unsigned int channels_max ; /* max over all cvts */
145
150
@@ -1673,6 +1678,60 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
1673
1678
return 0 ;
1674
1679
}
1675
1680
1681
+ static int hdmi_find_pcm_slot (struct hdmi_spec * spec ,
1682
+ struct hdmi_spec_per_pin * per_pin )
1683
+ {
1684
+ int i ;
1685
+
1686
+ /* try the prefer PCM */
1687
+ if (!test_bit (per_pin -> pin_nid_idx , & spec -> pcm_bitmap ))
1688
+ return per_pin -> pin_nid_idx ;
1689
+
1690
+ /* have a second try; check the "reserved area" over num_pins */
1691
+ for (i = spec -> num_pins ; i < spec -> pcm_used ; i ++ ) {
1692
+ if (!test_bit (i , & spec -> pcm_bitmap ))
1693
+ return i ;
1694
+ }
1695
+
1696
+ /* the last try; check the empty slots in pins */
1697
+ for (i = 0 ; i < spec -> num_pins ; i ++ ) {
1698
+ if (!test_bit (i , & spec -> pcm_bitmap ))
1699
+ return i ;
1700
+ }
1701
+ return - EBUSY ;
1702
+ }
1703
+
1704
+ static void hdmi_attach_hda_pcm (struct hdmi_spec * spec ,
1705
+ struct hdmi_spec_per_pin * per_pin )
1706
+ {
1707
+ int idx ;
1708
+
1709
+ /* pcm already be attached to the pin */
1710
+ if (per_pin -> pcm )
1711
+ return ;
1712
+ idx = hdmi_find_pcm_slot (spec , per_pin );
1713
+ if (idx == - ENODEV )
1714
+ return ;
1715
+ per_pin -> pcm_idx = idx ;
1716
+ per_pin -> pcm = spec -> pcm_rec [idx ];
1717
+ set_bit (idx , & spec -> pcm_bitmap );
1718
+ }
1719
+
1720
+ static void hdmi_detach_hda_pcm (struct hdmi_spec * spec ,
1721
+ struct hdmi_spec_per_pin * per_pin )
1722
+ {
1723
+ int idx ;
1724
+
1725
+ /* pcm already be detached from the pin */
1726
+ if (!per_pin -> pcm )
1727
+ return ;
1728
+ idx = per_pin -> pcm_idx ;
1729
+ per_pin -> pcm_idx = -1 ;
1730
+ per_pin -> pcm = NULL ;
1731
+ if (idx >= 0 && idx < spec -> pcm_used )
1732
+ clear_bit (idx , & spec -> pcm_bitmap );
1733
+ }
1734
+
1676
1735
/* update per_pin ELD from the given new ELD;
1677
1736
* setup info frame and notification accordingly
1678
1737
*/
@@ -1681,9 +1740,17 @@ static void update_eld(struct hda_codec *codec,
1681
1740
struct hdmi_eld * eld )
1682
1741
{
1683
1742
struct hdmi_eld * pin_eld = & per_pin -> sink_eld ;
1743
+ struct hdmi_spec * spec = codec -> spec ;
1684
1744
bool old_eld_valid = pin_eld -> eld_valid ;
1685
1745
bool eld_changed ;
1686
1746
1747
+ if (spec -> dyn_pcm_assign ) {
1748
+ if (eld -> eld_valid )
1749
+ hdmi_attach_hda_pcm (spec , per_pin );
1750
+ else
1751
+ hdmi_detach_hda_pcm (spec , per_pin );
1752
+ }
1753
+
1687
1754
if (eld -> eld_valid )
1688
1755
snd_hdmi_show_eld (codec , & eld -> info );
1689
1756
@@ -1827,13 +1894,19 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
1827
1894
static bool hdmi_present_sense (struct hdmi_spec_per_pin * per_pin , int repoll )
1828
1895
{
1829
1896
struct hda_codec * codec = per_pin -> codec ;
1897
+ struct hdmi_spec * spec = codec -> spec ;
1898
+ int ret ;
1830
1899
1900
+ mutex_lock (& spec -> pcm_lock );
1831
1901
if (codec_has_acomp (codec )) {
1832
1902
sync_eld_via_acomp (codec , per_pin );
1833
- return false; /* don't call snd_hda_jack_report_sync() */
1903
+ ret = false; /* don't call snd_hda_jack_report_sync() */
1834
1904
} else {
1835
- return hdmi_present_sense_via_verbs (per_pin , repoll );
1905
+ ret = hdmi_present_sense_via_verbs (per_pin , repoll );
1836
1906
}
1907
+ mutex_unlock (& spec -> pcm_lock );
1908
+
1909
+ return ret ;
1837
1910
}
1838
1911
1839
1912
static void hdmi_repoll_eld (struct work_struct * work )
@@ -1877,6 +1950,11 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1877
1950
1878
1951
per_pin -> pin_nid = pin_nid ;
1879
1952
per_pin -> non_pcm = false;
1953
+ if (spec -> dyn_pcm_assign )
1954
+ per_pin -> pcm_idx = -1 ;
1955
+ else
1956
+ per_pin -> pcm_idx = pin_idx ;
1957
+ per_pin -> pin_nid_idx = pin_idx ;
1880
1958
1881
1959
err = hdmi_read_pin_conn (codec , pin_idx );
1882
1960
if (err < 0 )
0 commit comments