Commit 62b7e5e0 authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarWai Yew CHAY <wychay@ctl.creative.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a74ccea5
...@@ -1216,6 +1216,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment