Commit 88320b74 authored by Cezary Rojewski's avatar Cezary Rojewski Committed by Takashi Iwai
Browse files

ALSA: hda: Introduce HOST stream setup mechanism



HDAudio stream setup procedure differs between revisions of the
controller device. Currently the differences are handled directly within
AudioDSP platform drivers with if-statements. Implement a more generic
approach and expose a function that a platform driver may use to ensure
the correct procedure is followed each time.

Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20230926080623.43927-3-cezary.rojewski@intel.com


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 2ee2c75c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ struct hdac_ext_stream {
	bool link_locked:1;
	bool link_prepared;

	int (*host_setup)(struct hdac_stream *);

	struct snd_pcm_substream *link_substream;
};

@@ -86,6 +88,7 @@ void snd_hdac_ext_stream_start(struct hdac_ext_stream *hext_stream);
void snd_hdac_ext_stream_clear(struct hdac_ext_stream *hext_stream);
void snd_hdac_ext_stream_reset(struct hdac_ext_stream *hext_stream);
int snd_hdac_ext_stream_setup(struct hdac_ext_stream *hext_stream, int fmt);
int snd_hdac_ext_host_stream_setup(struct hdac_ext_stream *hext_stream);

struct hdac_ext_link {
	struct hdac_bus *bus;
+41 −0
Original line number Diff line number Diff line
@@ -10,12 +10,45 @@
 */

#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/hda_register.h>
#include <sound/hdaudio_ext.h>
#include <sound/compress_driver.h>

/**
 * snd_hdac_ext_host_stream_setup - Setup a HOST stream.
 * @hext_stream: HDAudio stream to set up.
 *
 * Return: Zero on success or negative error code.
 */
int snd_hdac_ext_host_stream_setup(struct hdac_ext_stream *hext_stream)
{
	return hext_stream->host_setup(hdac_stream(hext_stream));
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_host_stream_setup);

/**
 * snd_hdac_apl_host_stream_setup - Setup a HOST stream following procedure
 *                                  recommended for ApolloLake devices.
 * @hstream: HDAudio stream to set up.
 *
 * Return: Zero on success or negative error code.
 */
static int snd_hdac_apl_host_stream_setup(struct hdac_stream *hstream)
{
	struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
	int ret;

	snd_hdac_ext_stream_decouple(hstream->bus, hext_stream, false);
	ret = snd_hdac_stream_setup(hstream);
	snd_hdac_ext_stream_decouple(hstream->bus, hext_stream, true);

	return ret;
}

/**
 * snd_hdac_ext_stream_init - initialize each stream (aka device)
 * @bus: HD-audio core bus
@@ -55,9 +88,16 @@ static void snd_hdac_ext_stream_init(struct hdac_bus *bus,
int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
				 int num_stream, int dir)
{
	struct pci_dev *pci = to_pci_dev(bus->dev);
	int (*setup_op)(struct hdac_stream *);
	int stream_tag = 0;
	int i, tag, idx = start_idx;

	if (pci->device == PCI_DEVICE_ID_INTEL_HDA_APL)
		setup_op = snd_hdac_apl_host_stream_setup;
	else
		setup_op = snd_hdac_stream_setup;

	for (i = 0; i < num_stream; i++) {
		struct hdac_ext_stream *hext_stream =
				kzalloc(sizeof(*hext_stream), GFP_KERNEL);
@@ -66,6 +106,7 @@ int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
		tag = ++stream_tag;
		snd_hdac_ext_stream_init(bus, hext_stream, idx, dir, tag);
		idx++;
		hext_stream->host_setup = setup_op;
	}

	return 0;