Commit fb83b635 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Simplify PCM setup overrides

This patch does two things:
- code refactoring with a local helper function,
- allow codec drivers to provide the specific PCM stream info pointers
  only for overriding the non-NULL entries, instead of copying the
  whole.

This simplifies the codec driver side (currently the only user is
alc269's 44kHz fixed rate).
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 2a557a86
...@@ -5137,6 +5137,33 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, ...@@ -5137,6 +5137,33 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
strlcat(str, sfx, len); strlcat(str, sfx, len);
} }
/* copy PCM stream info from @default_str, and override non-NULL entries
* from @spec_str and @nid
*/
static void setup_pcm_stream(struct hda_pcm_stream *str,
const struct hda_pcm_stream *default_str,
const struct hda_pcm_stream *spec_str,
hda_nid_t nid)
{
*str = *default_str;
if (nid)
str->nid = nid;
if (spec_str) {
if (spec_str->substreams)
str->substreams = spec_str->substreams;
if (spec_str->channels_min)
str->channels_min = spec_str->channels_min;
if (spec_str->channels_max)
str->channels_max = spec_str->channels_max;
if (spec_str->rates)
str->rates = spec_str->rates;
if (spec_str->formats)
str->formats = spec_str->formats;
if (spec_str->maxbps)
str->maxbps = spec_str->maxbps;
}
}
/** /**
* snd_hda_gen_build_pcms - build PCM streams based on the parsed results * snd_hda_gen_build_pcms - build PCM streams based on the parsed results
* @codec: the HDA codec * @codec: the HDA codec
...@@ -5147,7 +5174,6 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) ...@@ -5147,7 +5174,6 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
{ {
struct hda_gen_spec *spec = codec->spec; struct hda_gen_spec *spec = codec->spec;
struct hda_pcm *info; struct hda_pcm *info;
const struct hda_pcm_stream *p;
bool have_multi_adcs; bool have_multi_adcs;
if (spec->no_analog) if (spec->no_analog)
...@@ -5162,11 +5188,10 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) ...@@ -5162,11 +5188,10 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
spec->pcm_rec[0] = info; spec->pcm_rec[0] = info;
if (spec->multiout.num_dacs > 0) { if (spec->multiout.num_dacs > 0) {
p = spec->stream_analog_playback; setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
if (!p) &pcm_analog_playback,
p = &pcm_analog_playback; spec->stream_analog_playback,
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; spec->multiout.dac_nids[0]);
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
spec->multiout.max_channels; spec->multiout.max_channels;
if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
...@@ -5175,15 +5200,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) ...@@ -5175,15 +5200,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
snd_pcm_2_1_chmaps; snd_pcm_2_1_chmaps;
} }
if (spec->num_adc_nids) { if (spec->num_adc_nids) {
p = spec->stream_analog_capture; setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
if (!p) { (spec->dyn_adc_switch ?
if (spec->dyn_adc_switch) &dyn_adc_pcm_analog_capture : &pcm_analog_capture),
p = &dyn_adc_pcm_analog_capture; spec->stream_analog_capture,
else spec->adc_nids[0]);
p = &pcm_analog_capture;
}
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
} }
skip_analog: skip_analog:
...@@ -5202,20 +5223,16 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) ...@@ -5202,20 +5223,16 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
info->pcm_type = spec->dig_out_type; info->pcm_type = spec->dig_out_type;
else else
info->pcm_type = HDA_PCM_TYPE_SPDIF; info->pcm_type = HDA_PCM_TYPE_SPDIF;
if (spec->multiout.dig_out_nid) { if (spec->multiout.dig_out_nid)
p = spec->stream_digital_playback; setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
if (!p) &pcm_digital_playback,
p = &pcm_digital_playback; spec->stream_digital_playback,
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; spec->multiout.dig_out_nid);
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; if (spec->dig_in_nid)
} setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
if (spec->dig_in_nid) { &pcm_digital_capture,
p = spec->stream_digital_capture; spec->stream_digital_capture,
if (!p) spec->dig_in_nid);
p = &pcm_digital_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
}
} }
if (spec->no_analog) if (spec->no_analog)
...@@ -5236,31 +5253,24 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) ...@@ -5236,31 +5253,24 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
spec->pcm_rec[2] = info; spec->pcm_rec[2] = info;
if (spec->alt_dac_nid) { if (spec->alt_dac_nid)
p = spec->stream_analog_alt_playback; setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
if (!p) &pcm_analog_alt_playback,
p = &pcm_analog_alt_playback; spec->stream_analog_alt_playback,
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p; spec->alt_dac_nid);
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = else
spec->alt_dac_nid; setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_PLAYBACK],
} else { &pcm_null_stream, NULL, 0);
info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
pcm_null_stream;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
}
if (have_multi_adcs) { if (have_multi_adcs) {
p = spec->stream_analog_alt_capture; setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
if (!p) &pcm_analog_alt_capture,
p = &pcm_analog_alt_capture; spec->stream_analog_alt_capture,
info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p; spec->adc_nids[1]);
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
spec->adc_nids[1];
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
spec->num_adc_nids - 1; spec->num_adc_nids - 1;
} else { } else {
info->stream[SNDRV_PCM_STREAM_CAPTURE] = setup_pcm_stream(&info->stream[SNDRV_PCM_STREAM_CAPTURE],
pcm_null_stream; &pcm_null_stream, NULL, 0);
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
} }
} }
......
...@@ -2602,53 +2602,12 @@ static int patch_alc268(struct hda_codec *codec) ...@@ -2602,53 +2602,12 @@ static int patch_alc268(struct hda_codec *codec)
* ALC269 * ALC269
*/ */
static int playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct hda_gen_spec *spec = codec->spec;
return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
hinfo);
}
static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
{
struct hda_gen_spec *spec = codec->spec;
return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
stream_tag, format, substream);
}
static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct hda_gen_spec *spec = codec->spec;
return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
}
static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */ .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
/* NID is set in alc_build_pcms */
.ops = {
.open = playback_pcm_open,
.prepare = playback_pcm_prepare,
.cleanup = playback_pcm_cleanup
},
}; };
static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_44100, /* fixed rate */ .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
/* NID is set in alc_build_pcms */
}; };
/* different alc269-variants */ /* different alc269-variants */
......
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