summaryrefslogtreecommitdiff
path: root/sound/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/hda')
-rw-r--r--sound/hda/Kconfig14
-rw-r--r--sound/hda/ext/hdac_ext_controller.c37
-rw-r--r--sound/hda/hdac_bus.c23
-rw-r--r--sound/hda/hdac_controller.c14
-rw-r--r--sound/hda/hdac_stream.c5
-rw-r--r--sound/hda/hdac_sysfs.c2
-rw-r--r--sound/hda/intel-dsp-config.c41
7 files changed, 115 insertions, 21 deletions
diff --git a/sound/hda/Kconfig b/sound/hda/Kconfig
index 3bc9224d5e4f..9ed5cfa3c18c 100644
--- a/sound/hda/Kconfig
+++ b/sound/hda/Kconfig
@@ -46,3 +46,17 @@ config SND_INTEL_DSP_CONFIG
select SND_INTEL_NHLT if ACPI
# this config should be selected only for Intel DSP platforms.
# A fallback is provided so that the code compiles in all cases.
+
+config SND_INTEL_BYT_PREFER_SOF
+ bool "Prefer SOF driver over SST on BY/CHT platforms"
+ depends on SND_SST_ATOM_HIFI2_PLATFORM_ACPI && SND_SOC_SOF_BAYTRAIL
+ default n
+ help
+ The kernel has 2 drivers for the Low Power Engine audio-block on
+ Bay- and Cherry-Trail SoCs. The old SST driver and the new SOF
+ driver. If both drivers are enabled then the kernel will default
+ to using the old SST driver, unless told otherwise through the
+ snd_intel_dspcfg.dsp_driver module-parameter.
+
+ Set this option to Y to make the kernel default to the new SOF
+ driver instead.
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
index b0c0ef824d7d..a9bd39b93697 100644
--- a/sound/hda/ext/hdac_ext_controller.c
+++ b/sound/hda/ext/hdac_ext_controller.c
@@ -332,3 +332,40 @@ int snd_hdac_ext_bus_link_put(struct hdac_bus *bus,
return ret;
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put);
+
+static void hdac_ext_codec_link_up(struct hdac_device *codec)
+{
+ const char *devname = dev_name(&codec->dev);
+ struct hdac_ext_link *hlink =
+ snd_hdac_ext_bus_get_link(codec->bus, devname);
+
+ if (hlink)
+ snd_hdac_ext_bus_link_get(codec->bus, hlink);
+}
+
+static void hdac_ext_codec_link_down(struct hdac_device *codec)
+{
+ const char *devname = dev_name(&codec->dev);
+ struct hdac_ext_link *hlink =
+ snd_hdac_ext_bus_get_link(codec->bus, devname);
+
+ if (hlink)
+ snd_hdac_ext_bus_link_put(codec->bus, hlink);
+}
+
+void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable)
+{
+ struct hdac_bus *bus = codec->bus;
+ bool oldstate = test_bit(codec->addr, &bus->codec_powered);
+
+ if (enable == oldstate)
+ return;
+
+ snd_hdac_bus_link_power(codec, enable);
+
+ if (enable)
+ hdac_ext_codec_link_up(codec);
+ else
+ hdac_ext_codec_link_down(codec);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power);
diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c
index 9766f6af8743..71db8592b33d 100644
--- a/sound/hda/hdac_bus.c
+++ b/sound/hda/hdac_bus.c
@@ -17,6 +17,7 @@ static void snd_hdac_bus_process_unsol_events(struct work_struct *work);
static const struct hdac_bus_ops default_ops = {
.command = snd_hdac_bus_send_cmd,
.get_response = snd_hdac_bus_get_response,
+ .link_power = snd_hdac_bus_link_power,
};
/**
@@ -264,3 +265,25 @@ void snd_hdac_aligned_write(unsigned int val, void __iomem *addr,
}
EXPORT_SYMBOL_GPL(snd_hdac_aligned_write);
#endif /* CONFIG_SND_HDA_ALIGNED_MMIO */
+
+void snd_hdac_codec_link_up(struct hdac_device *codec)
+{
+ struct hdac_bus *bus = codec->bus;
+
+ if (bus->ops->link_power)
+ bus->ops->link_power(codec, true);
+ else
+ snd_hdac_bus_link_power(codec, true);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_codec_link_up);
+
+void snd_hdac_codec_link_down(struct hdac_device *codec)
+{
+ struct hdac_bus *bus = codec->bus;
+
+ if (bus->ops->link_power)
+ bus->ops->link_power(codec, false);
+ else
+ snd_hdac_bus_link_power(codec, false);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_codec_link_down);
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index b98449fd92f3..062da7a7a586 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -648,3 +648,17 @@ void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus)
snd_dma_free_pages(&bus->posbuf);
}
EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages);
+
+/**
+ * snd_hdac_bus_link_power - power up/down codec link
+ * @codec: HD-audio device
+ * @enable: whether to power-up the link
+ */
+void snd_hdac_bus_link_power(struct hdac_device *codec, bool enable)
+{
+ if (enable)
+ set_bit(codec->addr, &codec->bus->codec_powered);
+ else
+ clear_bit(codec->addr, &codec->bus->codec_powered);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_bus_link_power);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index abe7a1b16fe1..a6ed3dc35f7e 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -435,12 +435,11 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
pos_adj = bus->bdl_pos_adj;
if (!azx_dev->no_period_wakeup && pos_adj > 0) {
pos_align = pos_adj;
- pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
+ pos_adj = DIV_ROUND_UP(pos_adj * runtime->rate, 48000);
if (!pos_adj)
pos_adj = pos_align;
else
- pos_adj = ((pos_adj + pos_align - 1) / pos_align) *
- pos_align;
+ pos_adj = roundup(pos_adj, pos_align);
pos_adj = frames_to_bytes(runtime, pos_adj);
if (pos_adj >= period_bytes) {
dev_warn(bus->dev, "Too big adjustment %d\n",
diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c
index e56e83325903..0d7771fca9f0 100644
--- a/sound/hda/hdac_sysfs.c
+++ b/sound/hda/hdac_sysfs.c
@@ -66,7 +66,7 @@ static struct attribute *hdac_dev_attrs[] = {
NULL
};
-static struct attribute_group hdac_dev_attr_group = {
+static const struct attribute_group hdac_dev_attr_group = {
.attrs = hdac_dev_attrs,
};
diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
index c45686172517..d1eb9d34993a 100644
--- a/sound/hda/intel-dsp-config.c
+++ b/sound/hda/intel-dsp-config.c
@@ -321,6 +321,18 @@ static const struct config_entry config_table[] = {
},
#endif
+/* Alder Lake */
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)
+ {
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ .device = 0x7ad0,
+ },
+ {
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ .device = 0x51c8,
+ },
+#endif
+
};
static const struct config_entry *snd_intel_dsp_find_config
@@ -452,35 +464,30 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci)
}
EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
+/* Should we default to SOF or SST for BYT/CHT ? */
+#if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \
+ !IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
+#define FLAG_SST_OR_SOF_BYT FLAG_SOF
+#else
+#define FLAG_SST_OR_SOF_BYT FLAG_SST
+#endif
+
/*
* configuration table
* - the order of similar ACPI ID entries is important!
* - the first successful match will win
*/
static const struct config_entry acpi_config_table[] = {
+#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
+ IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
/* BayTrail */
-#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
- {
- .flags = FLAG_SST,
- .acpi_hid = "80860F28",
- },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
{
- .flags = FLAG_SOF,
+ .flags = FLAG_SST_OR_SOF_BYT,
.acpi_hid = "80860F28",
},
-#endif
/* CherryTrail */
-#if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI)
{
- .flags = FLAG_SST,
- .acpi_hid = "808622A8",
- },
-#endif
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
- {
- .flags = FLAG_SOF,
+ .flags = FLAG_SST_OR_SOF_BYT,
.acpi_hid = "808622A8",
},
#endif