* [PATCH v2 6/8] ALSA: hda: Add support for Hygon family 18h model 5h HD-Audio
[not found] <cover.1775548724.git.fuhao@open-hieco.net>
@ 2026-04-07 8:24 ` Fu Hao
2026-04-10 22:47 ` Bjorn Helgaas
2026-04-07 8:25 ` [PATCH v2 7/8] ALSA: hda: Fix single byte writing issue for Hygon family 18h model 5h Fu Hao
1 sibling, 1 reply; 3+ messages in thread
From: Fu Hao @ 2026-04-07 8:24 UTC (permalink / raw)
To: bhelgaas, perex, tiwai; +Cc: linux-kernel, linux-sound, linux-pci, Fu Hao
Add the new PCI ID 0x1d94 0x14a9 for Hygon family 18h model 5h
HDA controller.
Signed-off-by: Fu Hao <fuhao@open-hieco.net>
---
include/linux/pci_ids.h | 1 +
sound/hda/controllers/intel.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 406abf629..19d968017 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2613,6 +2613,7 @@
#define PCI_VENDOR_ID_ROCKCHIP 0x1d87
#define PCI_VENDOR_ID_HYGON 0x1d94
+#define PCI_DEVICE_ID_HYGON_18H_M05H_HDA 0x14a9
#define PCI_VENDOR_ID_META 0x1d9b
diff --git a/sound/hda/controllers/intel.c b/sound/hda/controllers/intel.c
index 3f434994c..eb5d48d90 100644
--- a/sound/hda/controllers/intel.c
+++ b/sound/hda/controllers/intel.c
@@ -241,6 +241,7 @@ enum {
AZX_DRIVER_ZHAOXIN,
AZX_DRIVER_ZHAOXINHDMI,
AZX_DRIVER_LOONGSON,
+ AZX_DRIVER_HYGON,
AZX_DRIVER_GENERIC,
AZX_NUM_DRIVERS, /* keep this as last entry */
};
@@ -357,6 +358,7 @@ static const char * const driver_short_names[] = {
[AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin",
[AZX_DRIVER_ZHAOXINHDMI] = "HDA Zhaoxin HDMI",
[AZX_DRIVER_LOONGSON] = "HDA Loongson",
+ [AZX_DRIVER_HYGON] = "HDA Hygon",
[AZX_DRIVER_GENERIC] = "HD-Audio Generic",
};
@@ -2818,6 +2820,9 @@ static const struct pci_device_id azx_ids[] = {
.driver_data = AZX_DRIVER_LOONGSON | AZX_DCAPS_NO_TCSEL },
{ PCI_VDEVICE(LOONGSON, PCI_DEVICE_ID_LOONGSON_HDMI),
.driver_data = AZX_DRIVER_LOONGSON | AZX_DCAPS_NO_TCSEL },
+ /* Hygon HDAudio */
+ { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_HYGON_18H_M05H_HDA),
+ .driver_data = AZX_DRIVER_HYGON | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_NO_MSI },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH v2 7/8] ALSA: hda: Fix single byte writing issue for Hygon family 18h model 5h
[not found] <cover.1775548724.git.fuhao@open-hieco.net>
2026-04-07 8:24 ` [PATCH v2 6/8] ALSA: hda: Add support for Hygon family 18h model 5h HD-Audio Fu Hao
@ 2026-04-07 8:25 ` Fu Hao
1 sibling, 0 replies; 3+ messages in thread
From: Fu Hao @ 2026-04-07 8:25 UTC (permalink / raw)
To: perex, tiwai; +Cc: linux-kernel, linux-sound, Fu Hao
On Hygon family 18h model 5h controller, some registers such as
GCTL, SD_CTL and SD_CTL_3B should be accessed in dword, or the
writing will fail.
Signed-off-by: Fu Hao <fuhao@open-hieco.net>
---
sound/hda/controllers/intel.c | 4 ++++
sound/hda/core/controller.c | 10 +++++++--
sound/hda/core/stream.c | 40 +++++++++++++++++++++++++++--------
3 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/sound/hda/controllers/intel.c b/sound/hda/controllers/intel.c
index eb5d48d90..81797a68e 100644
--- a/sound/hda/controllers/intel.c
+++ b/sound/hda/controllers/intel.c
@@ -1885,6 +1885,10 @@ static int azx_first_init(struct azx *chip)
if (chip->driver_type == AZX_DRIVER_ZHAOXINHDMI)
bus->polling_mode = 1;
+ if (chip->driver_type == AZX_DRIVER_HYGON &&
+ chip->pci->device == PCI_DEVICE_ID_HYGON_18H_M05H_HDA)
+ bus->access_sdnctl_in_dword = 1;
+
bus->remap_addr = pcim_iomap_region(pci, 0, "ICH HD audio");
if (IS_ERR(bus->remap_addr))
return PTR_ERR(bus->remap_addr);
diff --git a/sound/hda/core/controller.c b/sound/hda/core/controller.c
index 69e11d62b..6312ad7af 100644
--- a/sound/hda/core/controller.c
+++ b/sound/hda/core/controller.c
@@ -511,7 +511,10 @@ void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus)
{
unsigned long timeout;
- snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
+ if (bus->access_sdnctl_in_dword)
+ snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
+ else
+ snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
timeout = jiffies + msecs_to_jiffies(100);
while (!snd_hdac_chip_readb(bus, GCTL) && time_before(jiffies, timeout))
@@ -576,7 +579,10 @@ static void azx_int_disable(struct hdac_bus *bus)
/* disable interrupts in stream descriptor */
list_for_each_entry(azx_dev, &bus->stream_list, list)
- snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
+ if (bus->access_sdnctl_in_dword)
+ snd_hdac_stream_updatel(azx_dev, SD_CTL, SD_INT_MASK, 0);
+ else
+ snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
/* disable SIE for all streams & disable controller CIE and GIE */
snd_hdac_chip_writel(bus, INTCTL, 0);
diff --git a/sound/hda/core/stream.c b/sound/hda/core/stream.c
index b471a038b..0091c4ef6 100644
--- a/sound/hda/core/stream.c
+++ b/sound/hda/core/stream.c
@@ -146,8 +146,12 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev)
stripe_ctl = snd_hdac_get_stream_stripe_ctl(bus, azx_dev->substream);
else
stripe_ctl = 0;
- snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
- stripe_ctl);
+ if (bus->access_sdnctl_in_dword)
+ snd_hdac_stream_updatel(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
+ stripe_ctl);
+ else
+ snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
+ stripe_ctl);
}
/* set DMA start and interrupt mask */
if (bus->access_sdnctl_in_dword)
@@ -166,11 +170,22 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_start);
*/
static void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
{
- snd_hdac_stream_updateb(azx_dev, SD_CTL,
- SD_CTL_DMA_START | SD_INT_MASK, 0);
- snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
- if (azx_dev->stripe)
- snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
+ struct hdac_bus *bus = azx_dev->bus;
+
+ if (bus->access_sdnctl_in_dword) {
+ snd_hdac_stream_updatel(azx_dev, SD_CTL,
+ SD_CTL_DMA_START | SD_INT_MASK, 0);
+ snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
+ if (azx_dev->stripe)
+ snd_hdac_stream_updatel(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
+ } else {
+ snd_hdac_stream_updateb(azx_dev, SD_CTL,
+ SD_CTL_DMA_START | SD_INT_MASK, 0);
+ snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
+ if (azx_dev->stripe)
+ snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
+ }
+
azx_dev->running = false;
}
@@ -225,12 +240,16 @@ void snd_hdac_stream_reset(struct hdac_stream *azx_dev)
{
unsigned char val;
int dma_run_state;
+ struct hdac_bus *bus = azx_dev->bus;
snd_hdac_stream_clear(azx_dev);
dma_run_state = snd_hdac_stream_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START;
- snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET);
+ if (bus->access_sdnctl_in_dword)
+ snd_hdac_stream_updatel(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET);
+ else
+ snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET);
/* wait for hardware to report that the stream entered reset */
snd_hdac_stream_readb_poll(azx_dev, SD_CTL, val, (val & SD_CTL_STREAM_RESET), 3, 300);
@@ -238,7 +257,10 @@ void snd_hdac_stream_reset(struct hdac_stream *azx_dev)
if (azx_dev->bus->dma_stop_delay && dma_run_state)
udelay(azx_dev->bus->dma_stop_delay);
- snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0);
+ if (bus->access_sdnctl_in_dword)
+ snd_hdac_stream_updatel(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0);
+ else
+ snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0);
/* wait for hardware to report that the stream is out of reset */
snd_hdac_stream_readb_poll(azx_dev, SD_CTL, val, !(val & SD_CTL_STREAM_RESET), 3, 300);
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread