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

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

ALSA: hda - Use common codes for ATI, Nvidia and VIA simple codecs



The code refactoring using the same helper functions for sharing the
codes among ATI, Nvidia and VIA simple_hdmi* stuff.  Except for that
spec->pcm_playback is no longer pointer, the functionality doesn't
change.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 4f0110ce
Loading
Loading
Loading
Loading
+65 −126
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ struct hdmi_spec {
	 * Non-generic ATI/NVIDIA specific
	 */
	struct hda_multi_out multiout;
	const struct hda_pcm_stream *pcm_playback;
	struct hda_pcm_stream pcm_playback;
};


@@ -1367,8 +1367,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
		info->name = get_hdmi_pcm_name(i);
		info->pcm_type = HDA_PCM_TYPE_HDMI;
		pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
		snd_BUG_ON(!spec->pcm_playback);
		*pstr = *spec->pcm_playback;
		*pstr = spec->pcm_playback;
		pstr->nid = spec->cvts[i].cvt_nid;
		if (pstr->channels_max <= 2 && chans && chans <= 16)
			pstr->channels_max = chans;
@@ -1560,6 +1559,49 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
					     stream_tag, format, substream);
}

static const struct hda_pcm_stream simple_pcm_playback = {
	.substreams = 1,
	.channels_min = 2,
	.channels_max = 2,
	.ops = {
		.open = simple_playback_pcm_open,
		.close = simple_playback_pcm_close,
		.prepare = simple_playback_pcm_prepare
	},
};

static const struct hda_codec_ops simple_hdmi_patch_ops = {
	.build_controls = simple_playback_build_controls,
	.build_pcms = simple_playback_build_pcms,
	.init = simple_playback_init,
	.free = simple_playback_free,
};

static int patch_simple_hdmi(struct hda_codec *codec,
			     hda_nid_t cvt_nid, hda_nid_t pin_nid)
{
	struct hdmi_spec *spec;

	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
	if (!spec)
		return -ENOMEM;

	codec->spec = spec;

	spec->multiout.num_dacs = 0;  /* no analog */
	spec->multiout.max_channels = 2;
	spec->multiout.dig_out_nid = cvt_nid;
	spec->num_cvts = 1;
	spec->num_pins = 1;
	spec->cvts[0].cvt_nid = cvt_nid;
	spec->cvts[0].cvt_nid = pin_nid;
	spec->pcm_playback = simple_pcm_playback;

	codec->patch_ops = simple_hdmi_patch_ops;

	return 0;
}

static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec,
						    int channels)
{
@@ -1732,54 +1774,20 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
	},
};

static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
	.substreams = 1,
	.channels_min = 2,
	.channels_max = 2,
	.nid = nvhdmi_master_con_nid_7x,
	.rates = SUPPORTED_RATES,
	.maxbps = SUPPORTED_MAXBPS,
	.formats = SUPPORTED_FORMATS,
	.ops = {
		.open = simple_playback_pcm_open,
		.close = simple_playback_pcm_close,
		.prepare = simple_playback_pcm_prepare
	},
};

static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
	.build_controls = simple_playback_build_controls,
	.build_pcms = simple_playback_build_pcms,
	.init = nvhdmi_7x_init,
	.free = simple_playback_free,
};

static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
	.build_controls = simple_playback_build_controls,
	.build_pcms = simple_playback_build_pcms,
	.init = nvhdmi_7x_init,
	.free = simple_playback_free,
};

static int patch_nvhdmi_2ch(struct hda_codec *codec)
{
	struct hdmi_spec *spec;
	int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x,
				    nvhdmi_master_pin_nid_7x);
	if (err < 0)
		return err;

	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
	if (spec == NULL)
		return -ENOMEM;

	codec->spec = spec;

	spec->multiout.num_dacs = 0;  /* no analog */
	spec->multiout.max_channels = 2;
	spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
	spec->num_cvts = 1;
	spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
	spec->pcm_playback = &nvhdmi_pcm_playback_2ch;

	codec->patch_ops = nvhdmi_patch_ops_2ch;

	codec->patch_ops.init = nvhdmi_7x_init;
	/* override the PCM rates, etc, as the codec doesn't give full list */
	spec = codec->spec;
	spec->pcm_playback.rates = SUPPORTED_RATES;
	spec->pcm_playback.maxbps = SUPPORTED_MAXBPS;
	spec->pcm_playback.formats = SUPPORTED_FORMATS;
	return 0;
}

@@ -1787,13 +1795,11 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
{
	struct hdmi_spec *spec;
	int err = patch_nvhdmi_2ch(codec);

	if (err < 0)
		return err;
	spec = codec->spec;
	spec->multiout.max_channels = 8;
	spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
	codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
	spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x;

	/* Initialize the audio infoframe channel mask and checksum to something
	 * valid */
@@ -1837,47 +1843,14 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
	return 0;
}

static const struct hda_pcm_stream atihdmi_pcm_digital_playback = {
	.substreams = 1,
	.channels_min = 2,
	.channels_max = 2,
	.nid = ATIHDMI_CVT_NID,
	.ops = {
		.open = simple_playback_pcm_open,
		.close = simple_playback_pcm_close,
		.prepare = atihdmi_playback_pcm_prepare
	},
};

static const struct hda_codec_ops atihdmi_patch_ops = {
	.build_controls = simple_playback_build_controls,
	.build_pcms = simple_playback_build_pcms,
	.init = simple_playback_init,
	.free = simple_playback_free,
};


static int patch_atihdmi(struct hda_codec *codec)
{
	struct hdmi_spec *spec;

	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
	if (spec == NULL)
		return -ENOMEM;

	codec->spec = spec;

	spec->multiout.num_dacs = 0;	  /* no analog */
	spec->multiout.max_channels = 2;
	spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
	spec->num_cvts = 1;
	spec->num_pins = 1;
	spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
	spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
	spec->pcm_playback = &atihdmi_pcm_digital_playback;

	codec->patch_ops = atihdmi_patch_ops;

	int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID);
	if (err < 0)
		return err;
	spec = codec->spec;
	spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare;
	return 0;
}

@@ -1885,46 +1858,12 @@ static int patch_atihdmi(struct hda_codec *codec)
#define VIAHDMI_CVT_NID	0x02	/* audio converter1 */
#define VIAHDMI_PIN_NID	0x03	/* HDMI output pin1 */

static const struct hda_codec_ops via_hdmi_patch_ops = {
	.build_controls = simple_playback_build_controls,
	.build_pcms = simple_playback_build_pcms,
	.init = simple_playback_init,
	.free = simple_playback_free,
	.unsol_event = simple_hdmi_unsol_event,
};

static struct hda_pcm_stream via_hdmi_digital_playback = {
	.substreams = 1,
	.channels_min = 2,
	.channels_max = 2,
	.nid = VIAHDMI_CVT_NID, /* NID to query formats and rates*/
	.ops = {
		.open = simple_playback_pcm_open,
		.close = simple_playback_pcm_close,
		.prepare = simple_playback_pcm_prepare
	},
};

static int patch_via_hdmi(struct hda_codec *codec)
{
	struct hdmi_spec *spec;

	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
	if (spec == NULL)
		return -ENOMEM;

	spec->multiout.num_dacs = 0;	  /* no analog */
	spec->multiout.max_channels = 2;
	spec->multiout.dig_out_nid = VIAHDMI_CVT_NID; /* pure-digital case */
	spec->num_cvts = 1;
	spec->num_pins = 1;
	spec->cvts[0].cvt_nid = VIAHDMI_CVT_NID;
	spec->pins[0].pin_nid = VIAHDMI_PIN_NID;
	spec->pcm_playback = &via_hdmi_digital_playback;

	codec->spec = spec;
	codec->patch_ops = via_hdmi_patch_ops;

	int err = patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
	if (err < 0)
		return err;
	codec->patch_ops.unsol_event = simple_hdmi_unsol_event;
	return 0;
}