devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support
@ 2025-12-05 11:16 joakim.zhang
  2025-12-05 11:16 ` [PATCH v5 1/3] ALSA: hda: dt-bindings: " joakim.zhang
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: joakim.zhang @ 2025-12-05 11:16 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
v3->v4:
  - describe more for both dt-binding and driver commit message
  - remove __maybe_unused for pm ops
  - fix robot compile warning for 32bit system
    - Forced type conversion for CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET
v4->v5:
  - rename "clock-names", "sysclk" "clk48m" -> "ipg" "per"
  - remove "reset-names" property
  - remove "model" property
  - additionalProperties: false -> unevaluatedProperties: false
  - update the dirver since "reset-names" removed
    - mostly is devm_reset_control_bulk_get_exclusive to devm_reset_control_get
 
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   |  62 +++
 include/sound/hdaudio.h                       |   3 +
 sound/hda/controllers/Kconfig                 |  14 +
 sound/hda/controllers/Makefile                |   2 +
 sound/hda/controllers/cix-ipbloq.c            | 436 ++++++++++++++++++
 sound/hda/core/bus.c                          |   1 +
 sound/hda/core/controller.c                   |  12 +-
 sound/hda/core/stream.c                       |  10 +-
 8 files changed, 529 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 v5 1/3] ALSA: hda: dt-bindings: add CIX IPBLOQ HDA controller support
  2025-12-05 11:16 [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
@ 2025-12-05 11:16 ` joakim.zhang
  2025-12-05 11:18   ` Krzysztof Kozlowski
  2025-12-05 11:16 ` [PATCH v5 2/3] ALSA: hda/core: add addr_offset field for bus address translation joakim.zhang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: joakim.zhang @ 2025-12-05 11:16 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 is integrated into
CIX SKY1 audio subsystem. HDA controller supports 64bit, but the
audio subsystem can only 32bit transaction. Use jack polling mode
as there is a hardware issue, lead to interrupt strom if the RIRB
interrupt enabled. Host and hdac has different view of memory, so
need do dma address translation.

Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
 .../bindings/sound/cix,sky1-ipbloq-hda.yaml   | 62 +++++++++++++++++++
 1 file changed, 62 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..02ac5f1aa926
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cix,sky1-ipbloq-hda.yaml
@@ -0,0 +1,62 @@
+# 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: ipg
+      - const: per
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+
+unevaluatedProperties: 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 = "ipg", "per";
+        resets = <&audss_rst 14>;
+        model = "CIX SKY1 EVB HDA";
+    };
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v5 2/3] ALSA: hda/core: add addr_offset field for bus address translation
  2025-12-05 11:16 [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
  2025-12-05 11:16 ` [PATCH v5 1/3] ALSA: hda: dt-bindings: " joakim.zhang
@ 2025-12-05 11:16 ` joakim.zhang
  2025-12-05 11:16 ` [PATCH v5 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
  2025-12-05 14:30 ` [PATCH v5 0/3] " Takashi Iwai
  3 siblings, 0 replies; 8+ messages in thread
From: joakim.zhang @ 2025-12-05 11:16 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 v5 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support
  2025-12-05 11:16 [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
  2025-12-05 11:16 ` [PATCH v5 1/3] ALSA: hda: dt-bindings: " joakim.zhang
  2025-12-05 11:16 ` [PATCH v5 2/3] ALSA: hda/core: add addr_offset field for bus address translation joakim.zhang
@ 2025-12-05 11:16 ` joakim.zhang
  2025-12-05 14:30 ` [PATCH v5 0/3] " Takashi Iwai
  3 siblings, 0 replies; 8+ messages in thread
From: joakim.zhang @ 2025-12-05 11:16 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 is integrated into
CIX SKY1 audio subsystem. HDA controller supports 64bit, but the
audio subsystem can only 32bit transaction. Use jack polling mode
as there is a hardware issue, lead to interrupt strom if the RIRB
interrupt enabled. Host and hdac has different view of memory, so
need do dma address translation.

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 | 436 +++++++++++++++++++++++++++++
 3 files changed, 452 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..d1ef0ea679d9
--- /dev/null
+++ b/sound/hda/controllers/cix-ipbloq.c
@@ -0,0 +1,436 @@
+// 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 *reset;
+	struct clk_bulk_data clocks[2];
+	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 = (dma_addr_t)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->reset = devm_reset_control_get(hda->dev, NULL);
+	if (IS_ERR(hda->reset))
+		dev_err_probe(hda->dev, IS_ERR(hda->reset),
+			      "failed to get reset, err = %d\n", IS_ERR(hda->reset));
+
+	hda->clocks[hda->nclocks++].id = "ipg";
+	hda->clocks[hda->nclocks++].id = "per";
+	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 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 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 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 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_assert(hda->reset);
+	if (rc) {
+		dev_err(dev, "failed to assert reset, rc: %d\n", rc);
+		return rc;
+	}
+
+	rc = reset_control_deassert(hda->reset);
+	if (rc) {
+		dev_err(dev, "failed to deassert reset, 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 v5 1/3] ALSA: hda: dt-bindings: add CIX IPBLOQ HDA controller support
  2025-12-05 11:16 ` [PATCH v5 1/3] ALSA: hda: dt-bindings: " joakim.zhang
@ 2025-12-05 11:18   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-12-05 11:18 UTC (permalink / raw)
  To: joakim.zhang, lgirdwood, broonie, robh, krzk+dt, conor+dt, perex,
	tiwai, linux-sound, devicetree
  Cc: cix-kernel-upstream

On 05/12/2025 12:16, joakim.zhang@cixtech.com wrote:
> From: Joakim Zhang <joakim.zhang@cixtech.com>
> 
> Add CIX IPBLOQ HDA controller support, which is integrated into
> CIX SKY1 audio subsystem. HDA controller supports 64bit, but the
> audio subsystem can only 32bit transaction. Use jack polling mode
> as there is a hardware issue, lead to interrupt strom if the RIRB
> interrupt enabled. Host and hdac has different view of memory, so
> need do dma address translation.
> 
> Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
> ---

Thanks,
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>



<form letter>
This is an automated instruction, just in case, because many review tags
are being ignored. If you know the process, just skip it entirely
(please do not feel offended by me posting it here - no bad intentions
intended, no patronizing, I just want to avoid wasted efforts). If you
do not know the process, here is a short explanation:

Please add Acked-by/Reviewed-by/Tested-by tags when posting new versions
of patchset, under or above your Signed-off-by tag, unless patch changed
significantly (e.g. new properties added to the DT bindings). Tag is
"received", when provided in a message replied to you on the mailing
list. Tools like b4 can help here ('b4 trailers -u ...'). However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for tags received on the version they apply.

Full context and explanation:
https://elixir.bootlin.com/linux/v6.15/source/Documentation/process/submitting-patches.rst#L591
</form letter>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support
  2025-12-05 11:16 [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
                   ` (2 preceding siblings ...)
  2025-12-05 11:16 ` [PATCH v5 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
@ 2025-12-05 14:30 ` Takashi Iwai
  2025-12-05 15:45   ` Joakim  Zhang
  3 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2025-12-05 14:30 UTC (permalink / raw)
  To: joakim.zhang
  Cc: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
	linux-sound, devicetree, cix-kernel-upstream

On Fri, 05 Dec 2025 12:16:31 +0100,
joakim.zhang@cixtech.com wrote:
> 
> 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
> v3->v4:
>   - describe more for both dt-binding and driver commit message
>   - remove __maybe_unused for pm ops
>   - fix robot compile warning for 32bit system
>     - Forced type conversion for CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET
> v4->v5:
>   - rename "clock-names", "sysclk" "clk48m" -> "ipg" "per"
>   - remove "reset-names" property
>   - remove "model" property
>   - additionalProperties: false -> unevaluatedProperties: false
>   - update the dirver since "reset-names" removed
>     - mostly is devm_reset_control_bulk_get_exclusive to devm_reset_control_get
>  
> 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

Applied all three patches now.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support
  2025-12-05 14:30 ` [PATCH v5 0/3] " Takashi Iwai
@ 2025-12-05 15:45   ` Joakim  Zhang
  2025-12-05 15:56     ` Takashi Iwai
  0 siblings, 1 reply; 8+ messages in thread
From: Joakim  Zhang @ 2025-12-05 15: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


Hi Takashi,

> -----Original Message-----
> From: Takashi Iwai <tiwai@suse.de>
> Sent: Friday, December 5, 2025 10:30 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 v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller
> support
> 
> EXTERNAL EMAIL
> 
> CAUTION: Suspicious Email from unusual domain.
> 
> On Fri, 05 Dec 2025 12:16:31 +0100,
> joakim.zhang@cixtech.com wrote:
> >
> > 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
> > v3->v4:
> >   - describe more for both dt-binding and driver commit message
> >   - remove __maybe_unused for pm ops
> >   - fix robot compile warning for 32bit system
> >     - Forced type conversion for
> CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET
> > v4->v5:
> >   - rename "clock-names", "sysclk" "clk48m" -> "ipg" "per"
> >   - remove "reset-names" property
> >   - remove "model" property
> >   - additionalProperties: false -> unevaluatedProperties: false
> >   - update the dirver since "reset-names" removed
> >     - mostly is devm_reset_control_bulk_get_exclusive to
> devm_reset_control_get
> >
> > 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
> 
> Applied all three patches now.  Thanks.
> 

Please wait a moment. I am so sorry that I just noticed I made an elementary mistake when update from v4 to v5, an error return was missed when copying and pasting, sending the v6.

Joakim

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support
  2025-12-05 15:45   ` Joakim  Zhang
@ 2025-12-05 15:56     ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2025-12-05 15:56 UTC (permalink / raw)
  To: Joakim  Zhang
  Cc: Takashi Iwai, 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

On Fri, 05 Dec 2025 16:45:50 +0100,
Joakim  Zhang wrote:
> 
> 
> Hi Takashi,
> 
> > -----Original Message-----
> > From: Takashi Iwai <tiwai@suse.de>
> > Sent: Friday, December 5, 2025 10:30 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 v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller
> > support
> >
> > EXTERNAL EMAIL
> >
> > CAUTION: Suspicious Email from unusual domain.
> >
> > On Fri, 05 Dec 2025 12:16:31 +0100,
> > joakim.zhang@cixtech.com wrote:
> > >
> > > 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
> > > v3->v4:
> > >   - describe more for both dt-binding and driver commit message
> > >   - remove __maybe_unused for pm ops
> > >   - fix robot compile warning for 32bit system
> > >     - Forced type conversion for
> > CIX_IPBLOQ_SKY1_ADDR_HOST_TO_HDAC_OFFSET
> > > v4->v5:
> > >   - rename "clock-names", "sysclk" "clk48m" -> "ipg" "per"
> > >   - remove "reset-names" property
> > >   - remove "model" property
> > >   - additionalProperties: false -> unevaluatedProperties: false
> > >   - update the dirver since "reset-names" removed
> > >     - mostly is devm_reset_control_bulk_get_exclusive to
> > devm_reset_control_get
> > >
> > > 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
> >
> > Applied all three patches now.  Thanks.
> >
> 
> Please wait a moment. I am so sorry that I just noticed I made an elementary mistake when update from v4 to v5, an error return was missed when copying and pasting, sending the v6.

OK, now rolled back.


Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-12-05 15:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-05 11:16 [PATCH v5 0/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-05 11:16 ` [PATCH v5 1/3] ALSA: hda: dt-bindings: " joakim.zhang
2025-12-05 11:18   ` Krzysztof Kozlowski
2025-12-05 11:16 ` [PATCH v5 2/3] ALSA: hda/core: add addr_offset field for bus address translation joakim.zhang
2025-12-05 11:16 ` [PATCH v5 3/3] ALSA: hda: add CIX IPBLOQ HDA controller support joakim.zhang
2025-12-05 14:30 ` [PATCH v5 0/3] " Takashi Iwai
2025-12-05 15:45   ` Joakim  Zhang
2025-12-05 15:56     ` Takashi Iwai

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).