Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee81abb6 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Apply a proper chmap for built-in 2.1 speakers



When 2.1 speakers are detected, use the corresponding channel map
instead of the standard map with front+rear surrounds.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f37bc7a8
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -3747,13 +3747,14 @@ static int add_std_chmaps(struct hda_codec *codec)
			struct hda_pcm_stream *hinfo =
				&codec->pcm_info[i].stream[str];
			struct snd_pcm_chmap *chmap;
			const struct snd_pcm_chmap_elem *elem;

			if (codec->pcm_info[i].own_chmap)
				continue;
			if (!pcm || !hinfo->substreams)
				continue;
			err = snd_pcm_add_chmap_ctls(pcm, str,
						     snd_pcm_std_chmaps,
			elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps;
			err = snd_pcm_add_chmap_ctls(pcm, str, elem,
						     hinfo->channels_max,
						     0, &chmap);
			if (err < 0)
@@ -3764,6 +3765,19 @@ static int add_std_chmaps(struct hda_codec *codec)
	return 0;
}

/* default channel maps for 2.1 speakers;
 * since HD-audio supports only stereo, odd number channels are omitted
 */
const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[] = {
	{ .channels = 2,
	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
	{ .channels = 4,
	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
		   SNDRV_CHMAP_LFE, SNDRV_CHMAP_LFE } },
	{ }
};
EXPORT_SYMBOL_GPL(snd_pcm_2_1_chmaps);

int snd_hda_codec_build_controls(struct hda_codec *codec)
{
	int err = 0;
+3 −0
Original line number Diff line number Diff line
@@ -757,6 +757,7 @@ struct hda_pcm_stream {
	u32 rates;	/* supported rates */
	u64 formats;	/* supported formats (SNDRV_PCM_FMTBIT_) */
	unsigned int maxbps;	/* supported max. bit per sample */
	const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
	struct hda_pcm_ops ops;
};

@@ -1026,6 +1027,8 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
				unsigned int format);

extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];

/*
 * Misc
 */
+3 −0
Original line number Diff line number Diff line
@@ -344,6 +344,9 @@ static int cs_build_pcms(struct hda_codec *codec)
	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0];
	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
		spec->multiout.max_channels;
	if (spec->speaker_2_1)
		info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
			snd_pcm_2_1_chmaps;
	info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture;
	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
		spec->adc_nid[spec->cur_input];
+5 −0
Original line number Diff line number Diff line
@@ -337,6 +337,8 @@ static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
	},
};

static bool is_2_1_speaker(struct conexant_spec *spec);

static int conexant_build_pcms(struct hda_codec *codec)
{
	struct conexant_spec *spec = codec->spec;
@@ -351,6 +353,9 @@ static int conexant_build_pcms(struct hda_codec *codec)
		spec->multiout.max_channels;
	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
		spec->multiout.dac_nids[0];
	if (is_2_1_speaker(spec))
		info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
			snd_pcm_2_1_chmaps;
	if (spec->capture_stream)
		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
	else {
+4 −0
Original line number Diff line number Diff line
@@ -2260,6 +2260,10 @@ static int alc_build_pcms(struct hda_codec *codec)
		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
			spec->multiout.max_channels;
		if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
		    spec->autocfg.line_outs == 2)
			info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
				snd_pcm_2_1_chmaps;
	}
	if (spec->adc_nids) {
		p = spec->stream_analog_capture;
Loading