ALSA: hda - Add workarounds for CT-IBG controllers
Creative IBG controllers require the playback stream-tags to be started from 1, instead of capture+1. Otherwise the stream stalls. Reported-by: Wai Yew CHAY <wychay@ctl.creative.com> Cc: <stable@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
@@ -1216,6 +1216,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
|
|||||||
struct hda_codec *c;
|
struct hda_codec *c;
|
||||||
struct hda_cvt_setup *p;
|
struct hda_cvt_setup *p;
|
||||||
unsigned int oldval, newval;
|
unsigned int oldval, newval;
|
||||||
|
int type;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!nid)
|
if (!nid)
|
||||||
@@ -1254,10 +1255,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
|
|||||||
p->dirty = 0;
|
p->dirty = 0;
|
||||||
|
|
||||||
/* make other inactive cvts with the same stream-tag dirty */
|
/* make other inactive cvts with the same stream-tag dirty */
|
||||||
|
type = get_wcaps_type(get_wcaps(codec, nid));
|
||||||
list_for_each_entry(c, &codec->bus->codec_list, list) {
|
list_for_each_entry(c, &codec->bus->codec_list, list) {
|
||||||
for (i = 0; i < c->cvt_setups.used; i++) {
|
for (i = 0; i < c->cvt_setups.used; i++) {
|
||||||
p = snd_array_elem(&c->cvt_setups, i);
|
p = snd_array_elem(&c->cvt_setups, i);
|
||||||
if (!p->active && p->stream_tag == stream_tag)
|
if (!p->active && p->stream_tag == stream_tag &&
|
||||||
|
get_wcaps_type(get_wcaps(codec, p->nid)) == type)
|
||||||
p->dirty = 1;
|
p->dirty = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1652,7 +1652,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
|
|||||||
struct azx_dev *azx_dev = get_azx_dev(substream);
|
struct azx_dev *azx_dev = get_azx_dev(substream);
|
||||||
struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
|
struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
unsigned int bufsize, period_bytes, format_val;
|
unsigned int bufsize, period_bytes, format_val, stream_tag;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
azx_stream_reset(chip, azx_dev);
|
azx_stream_reset(chip, azx_dev);
|
||||||
@@ -1694,7 +1694,12 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
|
|||||||
else
|
else
|
||||||
azx_dev->fifo_size = 0;
|
azx_dev->fifo_size = 0;
|
||||||
|
|
||||||
return snd_hda_codec_prepare(apcm->codec, hinfo, azx_dev->stream_tag,
|
stream_tag = azx_dev->stream_tag;
|
||||||
|
/* CA-IBG chips need the playback stream starting from 1 */
|
||||||
|
if (chip->driver_type == AZX_DRIVER_CTX &&
|
||||||
|
stream_tag > chip->capture_streams)
|
||||||
|
stream_tag -= chip->capture_streams;
|
||||||
|
return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
|
||||||
azx_dev->format_val, substream);
|
azx_dev->format_val, substream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user