* [PATCH v3 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support
@ 2025-12-01 10:56 joakim.zhang
2025-12-01 10:56 ` [PATCH v3 1/3] ALSA: hda: dt-bindings: " joakim.zhang
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: joakim.zhang @ 2025-12-01 10:56 UTC (permalink / raw)
To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
linux-sound, devicetree
Cc: cix-kernel-upstream, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add CIX IPBLOQ HDA controller support.
---
ChangeLogs:
v1->v2:
- fix dt-binding issues
- remove delayed work for probing
- refine dma address traslation
v2->v3:
- update dt-binding commit title and message
- ASoC: dt-bindings: -> ALSA: hda: dt-bindings
- use full sentences for commit message
- rename cix,ipbloq-hda.yaml to cix,sky1-ipbloq-hda.yaml
- update compatible cix,ipbloq-hda to cix,sky1-ipbloq-hda
- "cix,model" to generic "model"
- change the addr_host_to_hdac bus callback to addr_offset field
Joakim Zhang (3):
ALSA: hda: dt-bindings: add CIX IPBLOQ HDA controller support
ALSA: hda/core: add addr_offset field for bus address translation
ALSA: hda: add CIX IPBLOQ HDA controller support
.../bindings/sound/cix,sky1-ipbloq-hda.yaml | 72 +++
include/sound/hdaudio.h | 3 +
sound/hda/controllers/Kconfig | 14 +
sound/hda/controllers/Makefile | 2 +
sound/hda/controllers/cix-ipbloq.c | 438 ++++++++++++++++++
sound/hda/core/bus.c | 1 +
sound/hda/core/controller.c | 12 +-
sound/hda/core/stream.c | 10 +-
8 files changed, 541 insertions(+), 11 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
create mode 100644 sound/hda/controllers/cix-ipbloq.c
--
2.49.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3 1/3] ALSA: hda: dt-bindings: add CIX IPBLOQ HDA controller support
2025-12-01 10:56 [PATCH v3 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
@ 2025-12-01 10:56 ` joakim.zhang
2025-12-01 10:56 ` [PATCH v3 2/3] ALSA: hda/core: add addr_offset field for bus address translation joakim.zhang
2025-12-01 10:57 ` [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2 siblings, 0 replies; 8+ messages in thread
From: joakim.zhang @ 2025-12-01 10:56 UTC (permalink / raw)
To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
linux-sound, devicetree
Cc: cix-kernel-upstream, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add CIX IPBLOQ HDA controller support, which integrated in
CIX SKY1 SoC.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
.../bindings/sound/cix,sky1-ipbloq-hda.yaml | 72 +++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
diff --git a/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml b/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
new file mode 100644
index 000000000000..b27d47523af3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/cix,sky1-ipbloq-hda.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CIX IPBLOQ HDA controller
+
+description:
+ CIX IPBLOQ High Definition Audio (HDA) Controller
+
+maintainers:
+ - Joakim Zhang <joakim.zhang@cixtech.com>
+
+allOf:
+ - $ref: sound-card-common.yaml#
+
+properties:
+ compatible:
+ const: cix,sky1-ipbloq-hda
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 2
+
+ clock-names:
+ items:
+ - const: sysclk
+ - const: clk48m
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ items:
+ - const: hda
+
+ model:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: The user-visible name of this sound complex
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include<dt-bindings/interrupt-controller/arm-gic.h>
+
+ hda@70c0000 {
+ compatible = "cix,sky1-ipbloq-hda";
+ reg = <0x70c0000 0x10000>;
+ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&audss_clk 7>,
+ <&audss_clk 8>;
+ clock-names = "sysclk", "clk48m";
+ resets = <&audss_rst 14>;
+ reset-names = "hda";
+ model = "CIX SKY1 EVB HDA";
+ };
--
2.49.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 2/3] ALSA: hda/core: add addr_offset field for bus address translation
2025-12-01 10:56 [PATCH v3 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-01 10:56 ` [PATCH v3 1/3] ALSA: hda: dt-bindings: " joakim.zhang
@ 2025-12-01 10:56 ` joakim.zhang
2025-12-01 10:57 ` [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2 siblings, 0 replies; 8+ messages in thread
From: joakim.zhang @ 2025-12-01 10:56 UTC (permalink / raw)
To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
linux-sound, devicetree
Cc: cix-kernel-upstream, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add bus addr_offset field for dma address translation,
for some SoCs such as CIX SKY1 which is ARM64 Arch, HOST
and HDAC has different memory view, so need to do dma address
translation between HOST and HDAC.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
include/sound/hdaudio.h | 3 +++
sound/hda/core/bus.c | 1 +
sound/hda/core/controller.c | 12 ++++++------
sound/hda/core/stream.c | 10 +++++-----
4 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 4e0c1d8af09f..f11bfc6b9f42 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -380,6 +380,9 @@ struct hdac_bus {
/* factor used to derive STRIPE control value */
unsigned int sdo_limit;
+
+ /* address offset between host and hadc */
+ dma_addr_t addr_offset;
};
int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
diff --git a/sound/hda/core/bus.c b/sound/hda/core/bus.c
index 9b196c915f37..81498f1e413e 100644
--- a/sound/hda/core/bus.c
+++ b/sound/hda/core/bus.c
@@ -47,6 +47,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
INIT_LIST_HEAD(&bus->hlink_list);
init_waitqueue_head(&bus->rirb_wq);
bus->irq = -1;
+ bus->addr_offset = 0;
/*
* Default value of '8' is as per the HD audio specification (Rev 1.0a).
diff --git a/sound/hda/core/controller.c b/sound/hda/core/controller.c
index a7c00ad80117..69e11d62bbfa 100644
--- a/sound/hda/core/controller.c
+++ b/sound/hda/core/controller.c
@@ -48,8 +48,8 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
/* CORB set up */
bus->corb.addr = bus->rb.addr;
bus->corb.buf = (__le32 *)bus->rb.area;
- snd_hdac_chip_writel(bus, CORBLBASE, (u32)bus->corb.addr);
- snd_hdac_chip_writel(bus, CORBUBASE, upper_32_bits(bus->corb.addr));
+ snd_hdac_chip_writel(bus, CORBLBASE, (u32)(bus->corb.addr + bus->addr_offset));
+ snd_hdac_chip_writel(bus, CORBUBASE, upper_32_bits(bus->corb.addr + bus->addr_offset));
/* set the corb size to 256 entries (ULI requires explicitly) */
snd_hdac_chip_writeb(bus, CORBSIZE, 0x02);
@@ -70,8 +70,8 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
bus->rirb.buf = (__le32 *)(bus->rb.area + 2048);
bus->rirb.wp = bus->rirb.rp = 0;
memset(bus->rirb.cmds, 0, sizeof(bus->rirb.cmds));
- snd_hdac_chip_writel(bus, RIRBLBASE, (u32)bus->rirb.addr);
- snd_hdac_chip_writel(bus, RIRBUBASE, upper_32_bits(bus->rirb.addr));
+ snd_hdac_chip_writel(bus, RIRBLBASE, (u32)(bus->rirb.addr + bus->addr_offset));
+ snd_hdac_chip_writel(bus, RIRBUBASE, upper_32_bits(bus->rirb.addr + bus->addr_offset));
/* set the rirb size to 256 entries (ULI requires explicitly) */
snd_hdac_chip_writeb(bus, RIRBSIZE, 0x02);
@@ -625,8 +625,8 @@ bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
/* program the position buffer */
if (bus->use_posbuf && bus->posbuf.addr) {
- snd_hdac_chip_writel(bus, DPLBASE, (u32)bus->posbuf.addr);
- snd_hdac_chip_writel(bus, DPUBASE, upper_32_bits(bus->posbuf.addr));
+ snd_hdac_chip_writel(bus, DPLBASE, (u32)(bus->posbuf.addr + bus->addr_offset));
+ snd_hdac_chip_writel(bus, DPUBASE, upper_32_bits(bus->posbuf.addr + bus->addr_offset));
}
bus->chip_init = true;
diff --git a/sound/hda/core/stream.c b/sound/hda/core/stream.c
index 579ec544ef4a..b471a038b314 100644
--- a/sound/hda/core/stream.c
+++ b/sound/hda/core/stream.c
@@ -288,16 +288,16 @@ int snd_hdac_stream_setup(struct hdac_stream *azx_dev, bool code_loading)
/* program the BDL address */
/* lower BDL address */
- snd_hdac_stream_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
+ snd_hdac_stream_writel(azx_dev, SD_BDLPL, (u32)(azx_dev->bdl.addr + bus->addr_offset));
/* upper BDL address */
snd_hdac_stream_writel(azx_dev, SD_BDLPU,
- upper_32_bits(azx_dev->bdl.addr));
+ upper_32_bits(azx_dev->bdl.addr + bus->addr_offset));
/* enable the position buffer */
if (bus->use_posbuf && bus->posbuf.addr) {
if (!(snd_hdac_chip_readl(bus, DPLBASE) & AZX_DPLBASE_ENABLE))
snd_hdac_chip_writel(bus, DPLBASE,
- (u32)bus->posbuf.addr | AZX_DPLBASE_ENABLE);
+ (u32)(bus->posbuf.addr + bus->addr_offset) | AZX_DPLBASE_ENABLE);
}
/* set the interrupt enable bits in the descriptor control register */
@@ -464,8 +464,8 @@ static int setup_bdle(struct hdac_bus *bus,
addr = snd_sgbuf_get_addr(dmab, ofs);
/* program the address field of the BDL entry */
- bdl[0] = cpu_to_le32((u32)addr);
- bdl[1] = cpu_to_le32(upper_32_bits(addr));
+ bdl[0] = cpu_to_le32((u32)(addr + bus->addr_offset));
+ bdl[1] = cpu_to_le32(upper_32_bits(addr + bus->addr_offset));
/* program the size field of the BDL entry */
chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size);
/* one BDLE cannot cross 4K boundary on CTHDA chips */
--
2.49.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
2025-12-01 10:56 [PATCH v3 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-01 10:56 ` [PATCH v3 1/3] ALSA: hda: dt-bindings: " joakim.zhang
2025-12-01 10:56 ` [PATCH v3 2/3] ALSA: hda/core: add addr_offset field for bus address translation joakim.zhang
@ 2025-12-01 10:57 ` joakim.zhang
2025-12-01 12:53 ` Takashi Iwai
` (2 more replies)
2 siblings, 3 replies; 8+ messages in thread
From: joakim.zhang @ 2025-12-01 10:57 UTC (permalink / raw)
To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
linux-sound, devicetree
Cc: cix-kernel-upstream, Joakim Zhang
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add CIX IPBLOQ HDA controller support, which integrated
in CIX SKY1 SoC.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
sound/hda/controllers/Kconfig | 14 +
sound/hda/controllers/Makefile | 2 +
sound/hda/controllers/cix-ipbloq.c | 438 +++++++++++++++++++++++++++++
3 files changed, 454 insertions(+)
create mode 100644 sound/hda/controllers/cix-ipbloq.c
diff --git a/sound/hda/controllers/Kconfig b/sound/hda/controllers/Kconfig
index 34721f50b055..72855f2df451 100644
--- a/sound/hda/controllers/Kconfig
+++ b/sound/hda/controllers/Kconfig
@@ -30,6 +30,20 @@ config SND_HDA_TEGRA
To compile this driver as a module, choose M here: the module
will be called snd-hda-tegra.
+config SND_HDA_CIX_IPBLOQ
+ tristate "CIX IPBLOQ HD Audio"
+ depends on ARCH_CIX || COMPILE_TEST
+ select SND_HDA
+ select SND_HDA_ALIGNED_MMIO
+ help
+ Say Y here to support the HDA controller present in CIX SoCs
+
+ This options enables support for the HD Audio controller
+ present in some CIX SoCs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-hda-cix-ipbloq.
+
config SND_HDA_ACPI
tristate "HD Audio ACPI"
depends on ACPI
diff --git a/sound/hda/controllers/Makefile b/sound/hda/controllers/Makefile
index a4bcd055e9ae..8967b6771d90 100644
--- a/sound/hda/controllers/Makefile
+++ b/sound/hda/controllers/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
snd-hda-intel-y := intel.o
snd-hda-tegra-y := tegra.o
+snd-hda-cix-ipbloq-y := cix-ipbloq.o
snd-hda-acpi-y := acpi.o
subdir-ccflags-y += -I$(src)/../common
@@ -10,4 +11,5 @@ CFLAGS_intel.o := -I$(src)
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
obj-$(CONFIG_SND_HDA_TEGRA) += snd-hda-tegra.o
+obj-$(CONFIG_SND_HDA_CIX_IPBLOQ) += snd-hda-cix-ipbloq.o
obj-$(CONFIG_SND_HDA_ACPI) += snd-hda-acpi.o
diff --git a/sound/hda/controllers/cix-ipbloq.c b/sound/hda/controllers/cix-ipbloq.c
new file mode 100644
index 000000000000..8332bde2d8cb
--- /dev/null
+++ b/sound/hda/controllers/cix-ipbloq.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2025 Cix Technology Group Co., Ltd.
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/string.h>
+
+#include <sound/hda_codec.h>
+#include "hda_controller.h"
+
+#define CIX_IPBLOQ_JACKPOLL_DEFAULT_TIME_MS 1000
+#define CIX_IPBLOQ_POWER_SAVE_DEFAULT_TIME_MS 100
+
+#define CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET (-0x90000000ULL)
+
+struct cix_ipbloq_hda {
+ struct azx chip;
+ struct device *dev;
+ void __iomem *regs;
+
+ struct reset_control_bulk_data resets[1];
+ struct clk_bulk_data clocks[2];
+ unsigned int nresets;
+ unsigned int nclocks;
+};
+
+static const struct hda_controller_ops cix_ipbloq_hda_ops;
+
+static int cix_ipbloq_hda_dev_disconnect(struct snd_device *device)
+{
+ struct azx *chip = device->device_data;
+
+ chip->bus.shutdown = 1;
+
+ return 0;
+}
+
+static int cix_ipbloq_hda_dev_free(struct snd_device *device)
+{
+ struct azx *chip = device->device_data;
+
+ if (azx_bus(chip)->chip_init) {
+ azx_stop_all_streams(chip);
+ azx_stop_chip(chip);
+ }
+
+ azx_free_stream_pages(chip);
+ azx_free_streams(chip);
+ snd_hdac_bus_exit(azx_bus(chip));
+
+ return 0;
+}
+
+static int cix_ipbloq_hda_probe_codec(struct cix_ipbloq_hda *hda)
+{
+ struct azx *chip = &hda->chip;
+ struct hdac_bus *bus = azx_bus(chip);
+ int err;
+
+ to_hda_bus(bus)->bus_probing = 1;
+
+ /* create codec instances */
+ err = azx_probe_codecs(chip, 8);
+ if (err < 0) {
+ dev_err(hda->dev, "probe codecs failed: %d\n", err);
+ return err;
+ }
+
+ err = azx_codec_configure(chip);
+ if (err < 0) {
+ dev_err(hda->dev, "codec configure failed: %d\n", err);
+ return err;
+ }
+
+ err = snd_card_register(chip->card);
+ if (err < 0) {
+ dev_err(hda->dev, "card register failed: %d\n", err);
+ return err;
+ }
+
+ chip->running = 1;
+
+ to_hda_bus(bus)->bus_probing = 0;
+
+ snd_hda_set_power_save(&chip->bus, CIX_IPBLOQ_POWER_SAVE_DEFAULT_TIME_MS);
+
+ return 0;
+}
+
+static int cix_ipbloq_hda_init(struct cix_ipbloq_hda *hda,
+ struct azx *chip,
+ struct platform_device *pdev)
+{
+ const char *sname = NULL, *drv_name = "cix-ipbloq-hda";
+ struct hdac_bus *bus = azx_bus(chip);
+ struct snd_card *card = chip->card;
+ struct resource *res;
+ unsigned short gcap;
+ int irq_id, err;
+
+ hda->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(hda->regs)) {
+ dev_err(hda->dev, "failed to get and ioremap resource\n");
+ return PTR_ERR(hda->regs);
+ }
+ bus->remap_addr = hda->regs;
+ bus->addr = res->start;
+
+ irq_id = platform_get_irq(pdev, 0);
+ if (irq_id < 0) {
+ dev_err(hda->dev, "failed to get the irq, err = %d\n", irq_id);
+ return irq_id;
+ }
+
+ err = devm_request_irq(hda->dev, irq_id, azx_interrupt,
+ 0, KBUILD_MODNAME, chip);
+ if (err < 0)
+ return dev_err_probe(hda->dev, err,
+ "unable to request IRQ %d : err = %d\n", irq_id, err);
+ bus->irq = irq_id;
+ card->sync_irq = bus->irq;
+
+ gcap = azx_readw(chip, GCAP);
+ chip->capture_streams = (gcap >> 8) & 0x0f;
+ chip->playback_streams = (gcap >> 12) & 0x0f;
+ chip->capture_index_offset = 0;
+ chip->playback_index_offset = chip->capture_streams;
+ chip->num_streams = chip->playback_streams + chip->capture_streams;
+
+ /* initialize streams */
+ err = azx_init_streams(chip);
+ if (err < 0) {
+ dev_err(hda->dev, "failed to initialize streams: %d\n", err);
+ return err;
+ }
+
+ err = azx_alloc_stream_pages(chip);
+ if (err < 0) {
+ dev_err(hda->dev, "failed to allocate stream pages: %d\n", err);
+ return err;
+ }
+
+ /* initialize chip */
+ azx_init_chip(chip, 1);
+
+ /* codec detection */
+ if (!bus->codec_mask) {
+ dev_err(hda->dev, "no codecs found\n");
+ return -ENODEV;
+ }
+ dev_dbg(card->dev, "codec detection mask = 0x%lx\n", bus->codec_mask);
+
+ /* driver name */
+ strscpy(card->driver, drv_name, sizeof(card->driver));
+
+ /* shortname for card */
+ sname = of_get_property(pdev->dev.of_node, "model", NULL);
+ if (!sname)
+ sname = drv_name;
+ if (strlen(sname) > sizeof(card->shortname))
+ dev_dbg(card->dev, "truncating shortname for card\n");
+ strscpy(card->shortname, sname, sizeof(card->shortname));
+
+ /* longname for card */
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx irq %i",
+ card->shortname, bus->addr, bus->irq);
+
+ return 0;
+}
+
+static int cix_ipbloq_hda_create(struct cix_ipbloq_hda *hda,
+ struct snd_card *card,
+ unsigned int driver_caps)
+{
+ static const struct snd_device_ops ops = {
+ .dev_disconnect = cix_ipbloq_hda_dev_disconnect,
+ .dev_free = cix_ipbloq_hda_dev_free,
+ };
+ struct azx *chip;
+ int err;
+
+ chip = &hda->chip;
+ chip->card = card;
+ chip->ops = &cix_ipbloq_hda_ops;
+ chip->driver_caps = driver_caps;
+ chip->driver_type = driver_caps & 0xff;
+ chip->dev_index = 0;
+ chip->single_cmd = 0;
+ chip->codec_probe_mask = -1;
+ chip->align_buffer_size = 1;
+ chip->jackpoll_interval = msecs_to_jiffies(CIX_IPBLOQ_JACKPOLL_DEFAULT_TIME_MS);
+ mutex_init(&chip->open_mutex);
+ INIT_LIST_HEAD(&chip->pcm_list);
+
+ /*
+ * HD-audio controllers appear pretty inaccurate about the update-IRQ timing.
+ * The IRQ is issued before actually the data is processed. So use stream
+ * link position by default instead of dma position buffer.
+ */
+ chip->get_position[0] = chip->get_position[1] = azx_get_pos_lpib;
+
+ err = azx_bus_init(chip, NULL);
+ if (err < 0) {
+ dev_err(hda->dev, "failed to init bus, err = %d\n", err);
+ return err;
+ }
+
+ /* RIRBSTS.RINTFL cannot be cleared, cause interrupt storm */
+ chip->bus.core.polling_mode = 1;
+ chip->bus.core.not_use_interrupts = 1;
+
+ chip->bus.core.aligned_mmio = 1;
+ chip->bus.core.dma_stop_delay = 100;
+ chip->bus.core.addr_offset = CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET;
+
+ chip->bus.jackpoll_in_suspend = 1;
+
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
+ dev_err(card->dev, "failed to create device, err = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int cix_ipbloq_hda_probe(struct platform_device *pdev)
+{
+ const unsigned int driver_flags = AZX_DCAPS_PM_RUNTIME;
+ struct cix_ipbloq_hda *hda;
+ struct snd_card *card;
+ struct azx *chip;
+ int err;
+
+ hda = devm_kzalloc(&pdev->dev, sizeof(*hda), GFP_KERNEL);
+ if (!hda)
+ return -ENOMEM;
+ hda->dev = &pdev->dev;
+
+ hda->resets[hda->nresets++].id = "hda";
+ err = devm_reset_control_bulk_get_exclusive(hda->dev, hda->nresets,
+ hda->resets);
+ if (err < 0)
+ return dev_err_probe(hda->dev, err, "failed to get reset, err = %d\n", err);
+
+ hda->clocks[hda->nclocks++].id = "sysclk";
+ hda->clocks[hda->nclocks++].id = "clk48m";
+ err = devm_clk_bulk_get(hda->dev, hda->nclocks, hda->clocks);
+ if (err < 0)
+ return dev_err_probe(hda->dev, err, "failed to get clk, err = %d\n", err);
+
+ dma_set_mask_and_coherent(hda->dev, DMA_BIT_MASK(32));
+
+ err = of_reserved_mem_device_init(hda->dev);
+ if (err < 0 && err != -ENODEV) {
+ dev_err(hda->dev,
+ "failed to init reserved mem for DMA, err = %d\n", err);
+ return err;
+ }
+
+ err = snd_card_new(hda->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+ THIS_MODULE, 0, &card);
+ if (err < 0)
+ return dev_err_probe(hda->dev, err, "failed to crate card, err = %d\n", err);
+
+ err = cix_ipbloq_hda_create(hda, card, driver_flags);
+ if (err < 0)
+ goto out_free_card;
+
+ chip = &hda->chip;
+ card->private_data = chip;
+ dev_set_drvdata(hda->dev, card);
+
+ pm_runtime_enable(hda->dev);
+ if (!azx_has_pm_runtime(chip))
+ pm_runtime_forbid(hda->dev);
+
+ err = pm_runtime_resume_and_get(hda->dev);
+ if (err < 0) {
+ dev_err(hda->dev, "runtime resume and get failed, err = %d\n", err);
+ goto out_free_device;
+ }
+
+ err = cix_ipbloq_hda_init(hda, chip, pdev);
+ if (err < 0)
+ goto out_free_device;
+
+ err = cix_ipbloq_hda_probe_codec(hda);
+ if (err < 0)
+ goto out_free_device;
+
+ pm_runtime_put(hda->dev);
+
+ return 0;
+
+out_free_device:
+ snd_device_free(card, chip);
+out_free_card:
+ snd_card_free(card);
+
+ return err;
+}
+
+static void cix_ipbloq_hda_remove(struct platform_device *pdev)
+{
+ struct snd_card *card = dev_get_drvdata(&pdev->dev);
+ struct azx *chip = card->private_data;
+
+ snd_device_free(card, chip);
+ snd_card_free(card);
+
+ pm_runtime_disable(&pdev->dev);
+}
+
+static void cix_ipbloq_hda_shutdown(struct platform_device *pdev)
+{
+ struct snd_card *card = dev_get_drvdata(&pdev->dev);
+ struct azx *chip;
+
+ if (!card)
+ return;
+
+ chip = card->private_data;
+ if (chip && chip->running)
+ azx_stop_chip(chip);
+}
+
+static int __maybe_unused cix_ipbloq_hda_suspend(struct device *dev)
+{
+ struct snd_card *card = dev_get_drvdata(dev);
+ int rc;
+
+ rc = pm_runtime_force_suspend(dev);
+ if (rc < 0)
+ return rc;
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
+
+ return 0;
+}
+
+static int __maybe_unused cix_ipbloq_hda_resume(struct device *dev)
+{
+ struct snd_card *card = dev_get_drvdata(dev);
+ int rc;
+
+ rc = pm_runtime_force_resume(dev);
+ if (rc < 0)
+ return rc;
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+
+ return 0;
+}
+
+static int __maybe_unused cix_ipbloq_hda_runtime_suspend(struct device *dev)
+{
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct azx *chip = card->private_data;
+ struct cix_ipbloq_hda *hda = container_of(chip, struct cix_ipbloq_hda, chip);
+
+ if (chip && chip->running) {
+ azx_stop_chip(chip);
+ azx_enter_link_reset(chip);
+ }
+
+ clk_bulk_disable_unprepare(hda->nclocks, hda->clocks);
+
+ return 0;
+}
+
+static int __maybe_unused cix_ipbloq_hda_runtime_resume(struct device *dev)
+{
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct azx *chip = card->private_data;
+ struct cix_ipbloq_hda *hda = container_of(chip, struct cix_ipbloq_hda, chip);
+ int rc;
+
+ rc = clk_bulk_prepare_enable(hda->nclocks, hda->clocks);
+ if (rc) {
+ dev_err(dev, "failed to enable clk bulk, rc: %d\n", rc);
+ return rc;
+ }
+
+ rc = reset_control_bulk_assert(hda->nresets, hda->resets);
+ if (rc) {
+ dev_err(dev, "failed to assert reset bulk, rc: %d\n", rc);
+ return rc;
+ }
+
+ rc = reset_control_bulk_deassert(hda->nresets, hda->resets);
+ if (rc) {
+ dev_err(dev, "failed to deassert reset bulk, rc: %d\n", rc);
+ return rc;
+ }
+
+ if (chip && chip->running)
+ azx_init_chip(chip, 1);
+
+ return 0;
+}
+
+static const struct dev_pm_ops cix_ipbloq_hda_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(cix_ipbloq_hda_suspend,
+ cix_ipbloq_hda_resume)
+ SET_RUNTIME_PM_OPS(cix_ipbloq_hda_runtime_suspend,
+ cix_ipbloq_hda_runtime_resume, NULL)
+};
+
+static const struct of_device_id cix_ipbloq_hda_match[] = {
+ { .compatible = "cix,sky1-ipbloq-hda" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, cix_ipbloq_hda_match);
+
+static struct platform_driver cix_ipbloq_hda_driver = {
+ .driver = {
+ .name = "cix-ipbloq-hda",
+ .pm = &cix_ipbloq_hda_pm,
+ .of_match_table = cix_ipbloq_hda_match,
+ },
+ .probe = cix_ipbloq_hda_probe,
+ .remove = cix_ipbloq_hda_remove,
+ .shutdown = cix_ipbloq_hda_shutdown,
+};
+module_platform_driver(cix_ipbloq_hda_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CIX IPBLOQ HDA bus driver");
+MODULE_AUTHOR("Joakim Zhang <joakim.zhang@cixtech.com>");
--
2.49.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
2025-12-01 10:57 ` [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
@ 2025-12-01 12:53 ` Takashi Iwai
2025-12-02 9:45 ` Joakim Zhang
2025-12-02 0:44 ` kernel test robot
2025-12-02 2:10 ` kernel test robot
2 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2025-12-01 12:53 UTC (permalink / raw)
To: joakim.zhang
Cc: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
linux-sound, devicetree, cix-kernel-upstream
On Mon, 01 Dec 2025 11:57:00 +0100,
joakim.zhang@cixtech.com wrote:
>
> From: Joakim Zhang <joakim.zhang@cixtech.com>
>
> Add CIX IPBLOQ HDA controller support, which integrated
> in CIX SKY1 SoC.
It'd be more helpful to describe the characteristics about this chip.
e.g. this chip requires special handling for jack polling, and it
needs the address offset, etc.
> +static int __maybe_unused cix_ipbloq_hda_suspend(struct device *dev)
Those __maybe_unused are superfluous when you use
SYSTEM_SLEEP_PM_OPS() or RUNTIME_PM_OPS() in dev_pm_ops definition.
thanks,
Takashi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
2025-12-01 10:57 ` [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-01 12:53 ` Takashi Iwai
@ 2025-12-02 0:44 ` kernel test robot
2025-12-02 2:10 ` kernel test robot
2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-12-02 0:44 UTC (permalink / raw)
To: joakim.zhang, lgirdwood, broonie, robh, krzk+dt, conor+dt, perex,
tiwai, linux-sound, devicetree
Cc: oe-kbuild-all, cix-kernel-upstream, Joakim Zhang
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on tiwai-sound/for-next]
[also build test WARNING on tiwai-sound/for-linus linus/master v6.18 next-20251201]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/joakim-zhang-cixtech-com/ALSA-hda-dt-bindings-add-CIX-IPBLOQ-HDA-controller-support/20251201-185859
base: https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git for-next
patch link: https://lore.kernel.org/r/20251201105700.832715-4-joakim.zhang%40cixtech.com
patch subject: [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
config: nios2-allmodconfig (https://download.01.org/0day-ci/archive/20251202/202512020810.KrwjSbJ9-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251202/202512020810.KrwjSbJ9-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512020810.KrwjSbJ9-lkp@intel.com/
All warnings (new ones prefixed by >>):
sound/hda/controllers/cix-ipbloq.c: In function 'cix_ipbloq_hda_create':
>> sound/hda/controllers/cix-ipbloq.c:23:57: warning: conversion from 'long long unsigned int' to 'dma_addr_t' {aka 'unsigned int'} changes value from '18446744071293632512' to '1879048192' [-Woverflow]
23 | #define CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET (-0x90000000ULL)
| ^
sound/hda/controllers/cix-ipbloq.c:224:38: note: in expansion of macro 'CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET'
224 | chip->bus.core.addr_offset = CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +23 sound/hda/controllers/cix-ipbloq.c
22
> 23 #define CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET (-0x90000000ULL)
24
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
2025-12-01 10:57 ` [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-01 12:53 ` Takashi Iwai
2025-12-02 0:44 ` kernel test robot
@ 2025-12-02 2:10 ` kernel test robot
2 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-12-02 2:10 UTC (permalink / raw)
To: joakim.zhang, lgirdwood, broonie, robh, krzk+dt, conor+dt, perex,
tiwai, linux-sound, devicetree
Cc: llvm, oe-kbuild-all, cix-kernel-upstream, Joakim Zhang
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on tiwai-sound/for-next]
[also build test WARNING on tiwai-sound/for-linus linus/master v6.18 next-20251201]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/joakim-zhang-cixtech-com/ALSA-hda-dt-bindings-add-CIX-IPBLOQ-HDA-controller-support/20251201-185859
base: https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git for-next
patch link: https://lore.kernel.org/r/20251201105700.832715-4-joakim.zhang%40cixtech.com
patch subject: [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20251202/202512020919.sEEAZ5w1-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251202/202512020919.sEEAZ5w1-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512020919.sEEAZ5w1-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> sound/hda/controllers/cix-ipbloq.c:224:31: warning: implicit conversion from 'unsigned long long' to 'dma_addr_t' (aka 'unsigned int') changes value from 18446744071293632512 to 1879048192 [-Wconstant-conversion]
224 | chip->bus.core.addr_offset = CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET;
| ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sound/hda/controllers/cix-ipbloq.c:23:51: note: expanded from macro 'CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET'
23 | #define CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET (-0x90000000ULL)
| ^~~~~~~~~~~~~~
1 warning generated.
vim +224 sound/hda/controllers/cix-ipbloq.c
180
181 static int cix_ipbloq_hda_create(struct cix_ipbloq_hda *hda,
182 struct snd_card *card,
183 unsigned int driver_caps)
184 {
185 static const struct snd_device_ops ops = {
186 .dev_disconnect = cix_ipbloq_hda_dev_disconnect,
187 .dev_free = cix_ipbloq_hda_dev_free,
188 };
189 struct azx *chip;
190 int err;
191
192 chip = &hda->chip;
193 chip->card = card;
194 chip->ops = &cix_ipbloq_hda_ops;
195 chip->driver_caps = driver_caps;
196 chip->driver_type = driver_caps & 0xff;
197 chip->dev_index = 0;
198 chip->single_cmd = 0;
199 chip->codec_probe_mask = -1;
200 chip->align_buffer_size = 1;
201 chip->jackpoll_interval = msecs_to_jiffies(CIX_IPBLOQ_JACKPOLL_DEFAULT_TIME_MS);
202 mutex_init(&chip->open_mutex);
203 INIT_LIST_HEAD(&chip->pcm_list);
204
205 /*
206 * HD-audio controllers appear pretty inaccurate about the update-IRQ timing.
207 * The IRQ is issued before actually the data is processed. So use stream
208 * link position by default instead of dma position buffer.
209 */
210 chip->get_position[0] = chip->get_position[1] = azx_get_pos_lpib;
211
212 err = azx_bus_init(chip, NULL);
213 if (err < 0) {
214 dev_err(hda->dev, "failed to init bus, err = %d\n", err);
215 return err;
216 }
217
218 /* RIRBSTS.RINTFL cannot be cleared, cause interrupt storm */
219 chip->bus.core.polling_mode = 1;
220 chip->bus.core.not_use_interrupts = 1;
221
222 chip->bus.core.aligned_mmio = 1;
223 chip->bus.core.dma_stop_delay = 100;
> 224 chip->bus.core.addr_offset = CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET;
225
226 chip->bus.jackpoll_in_suspend = 1;
227
228 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
229 if (err < 0) {
230 dev_err(card->dev, "failed to create device, err = %d\n", err);
231 return err;
232 }
233
234 return 0;
235 }
236
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
2025-12-01 12:53 ` Takashi Iwai
@ 2025-12-02 9:45 ` Joakim Zhang
0 siblings, 0 replies; 8+ messages in thread
From: Joakim Zhang @ 2025-12-02 9:45 UTC (permalink / raw)
To: Takashi Iwai
Cc: lgirdwood@gmail.com, broonie@kernel.org, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, perex@perex.cz,
tiwai@suse.com, linux-sound@vger.kernel.org,
devicetree@vger.kernel.org, cix-kernel-upstream
Hello, Takashi
> -----Original Message-----
> From: Takashi Iwai <tiwai@suse.de>
> Sent: Monday, December 1, 2025 8:53 PM
> To: Joakim Zhang <joakim.zhang@cixtech.com>
> Cc: lgirdwood@gmail.com; broonie@kernel.org; robh@kernel.org;
> krzk+dt@kernel.org; conor+dt@kernel.org; perex@perex.cz;
> tiwai@suse.com; linux-sound@vger.kernel.org; devicetree@vger.kernel.org;
> cix-kernel-upstream <cix-kernel-upstream@cixtech.com>
> Subject: Re: [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller
> support
>
> EXTERNAL EMAIL
>
> CAUTION: Suspicious Email from unusual domain.
>
> On Mon, 01 Dec 2025 11:57:00 +0100,
> joakim.zhang@cixtech.com wrote:
> >
> > From: Joakim Zhang <joakim.zhang@cixtech.com>
> >
> > Add CIX IPBLOQ HDA controller support, which integrated in CIX SKY1
> > SoC.
>
> It'd be more helpful to describe the characteristics about this chip.
> e.g. this chip requires special handling for jack polling, and it needs the
> address offset, etc.
>
Fine.
> > +static int __maybe_unused cix_ipbloq_hda_suspend(struct device *dev)
>
> Those __maybe_unused are superfluous when you use
> SYSTEM_SLEEP_PM_OPS() or RUNTIME_PM_OPS() in dev_pm_ops
> definition.
>
OK
Joakim
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-12-02 9:45 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-01 10:56 [PATCH v3 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-01 10:56 ` [PATCH v3 1/3] ALSA: hda: dt-bindings: " joakim.zhang
2025-12-01 10:56 ` [PATCH v3 2/3] ALSA: hda/core: add addr_offset field for bus address translation joakim.zhang
2025-12-01 10:57 ` [PATCH v3 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-01 12:53 ` Takashi Iwai
2025-12-02 9:45 ` Joakim Zhang
2025-12-02 0:44 ` kernel test robot
2025-12-02 2:10 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).