Linux Sound subsystem development
 help / color / mirror / Atom feed
From: <shumingf@realtek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>
Cc: <linux-sound@vger.kernel.org>, <lars@metafoo.de>,
	<flove@realtek.com>, <oder_chiou@realtek.com>,
	<jack.yu@realtek.com>, <derek.fang@realtek.com>,
	Shuming Fan <shumingf@realtek.com>
Subject: [PATCH] ASoC: rt712: add GPIOs for LED control
Date: Wed, 16 Sep 2026 17:05:13 +0800	[thread overview]
Message-ID: <20260916090513.2294466-1-shumingf@realtek.com> (raw)

From: Shuming Fan <shumingf@realtek.com>

Certain platforms use the RT712 GPIOs to control the microphone mute LED and speaker mute LED.
This patch lets the LED subsystem to handle the GPIO control.

Signed-off-by: Shuming Fan <shumingf@realtek.com>
---
 sound/soc/codecs/rt712-sdca-sdw.h |   3 +
 sound/soc/codecs/rt712-sdca.c     | 106 ++++++++++++++++++++++++++++++
 sound/soc/codecs/rt712-sdca.h     |   6 +-
 3 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/rt712-sdca-sdw.h b/sound/soc/codecs/rt712-sdca-sdw.h
index 7ad25cc27f62..162d62234b68 100644
--- a/sound/soc/codecs/rt712-sdca-sdw.h
+++ b/sound/soc/codecs/rt712-sdca-sdw.h
@@ -46,6 +46,9 @@ static const struct reg_default rt712_sdca_mbq_defaults[] = {
 	{ 0x5b00029, 0x3fff },
 	{ 0x5b0002a, 0xf000 },
 	{ 0x6100000, 0x04e4 },
+	{ 0x6100009, 0x0000 },
+	{ 0x610000a, 0x0000 },
+	{ 0x610000b, 0x0020 },
 	{ 0x610000e, 0x0007 },
 	{ 0x6100045, 0x0860 },
 	{ 0x6100046, 0x0029 },
diff --git a/sound/soc/codecs/rt712-sdca.c b/sound/soc/codecs/rt712-sdca.c
index 38052cb19790..20889c614e47 100644
--- a/sound/soc/codecs/rt712-sdca.c
+++ b/sound/soc/codecs/rt712-sdca.c
@@ -113,6 +113,109 @@ static void rt712_sdca_clk_patch2(struct rt712_sdca_priv *rt712)
 	rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0000);
 }
 
+static int rt712_sdca_gpio_request(struct gpio_chip *chip, unsigned int offset)
+{
+	struct rt712_sdca_priv *rt712 = gpiochip_get_data(chip);
+	unsigned int gpio_pin = offset + 3;
+	int ret;
+
+	dev_dbg(&rt712->slave->dev, "%s: gpio_pin=%d\n", __func__, gpio_pin);
+
+	ret = pm_runtime_resume(rt712->component->dev);
+	if (ret < 0 && ret != -EACCES)
+		return ret;
+
+	/*
+	 * Only support GPIO3 and GPIO4 for now
+	 */
+	switch (gpio_pin) {
+	case 3:
+		break;
+	case 4:
+		rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
+			RT712_HDA_LEGACY_CONFIG_CTL0, 0x000c, 0x0004);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
+		RT712_HDA_GPIO_EN_CTL, (1 << gpio_pin), (1 << gpio_pin));
+	rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
+		RT712_HDA_GPIO_DIRECTION_CTL, (1 << gpio_pin), (1 << gpio_pin));
+
+	return 0;
+}
+
+static int rt712_sdca_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			   int value)
+{
+	struct rt712_sdca_priv *rt712 = gpiochip_get_data(chip);
+	unsigned int gpio_pin = offset + 3;
+	int ret;
+
+	dev_dbg(&rt712->slave->dev, "%s: gpio_pin=%d, value=%d\n", __func__, gpio_pin, value);
+
+	ret = pm_runtime_resume(rt712->component->dev);
+	if (ret < 0 && ret != -EACCES)
+		return ret;
+
+	return rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
+			RT712_HDA_GPIO_SET_CTL, (1 << gpio_pin), (!!value << gpio_pin));
+}
+
+static int rt712_sdca_gpio_direction_out(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	struct rt712_sdca_priv *rt712 = gpiochip_get_data(chip);
+	unsigned int gpio_pin = offset + 3;
+	int ret;
+
+	dev_dbg(&rt712->slave->dev, "%s: gpio_pin=%d, value=%d\n", __func__, gpio_pin, value);
+
+	ret = pm_runtime_resume(rt712->component->dev);
+	if (ret < 0 && ret != -EACCES)
+		return ret;
+
+	switch (gpio_pin) {
+	case 3:
+	case 4:
+		rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
+			RT712_HDA_GPIO_DIRECTION_CTL, (1 << gpio_pin), (1 << gpio_pin));
+		rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
+			RT712_HDA_GPIO_SET_CTL, (1 << gpio_pin), (!!value << gpio_pin));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct gpio_chip rt712_sdca_template_chip = {
+	.label = "rt712-sdca",
+	.owner = THIS_MODULE,
+	.request = rt712_sdca_gpio_request,
+	.direction_output = rt712_sdca_gpio_direction_out,
+	.set = rt712_sdca_gpio_set,
+	.ngpio = 2,
+	.can_sleep = true,
+	.base = -1,
+};
+
+static void rt712_sdca_gpio_init(struct rt712_sdca_priv *rt712)
+{
+	int ret;
+
+	rt712->gpio_chip = rt712_sdca_template_chip;
+	rt712->gpio_chip.parent = &rt712->slave->dev;
+	rt712->gpio_chip.fwnode = dev_fwnode(&rt712->slave->dev);
+
+	ret = devm_gpiochip_add_data(&rt712->slave->dev, &rt712->gpio_chip, rt712);
+	if (ret != 0)
+		dev_err(&rt712->slave->dev, "Failed to add GPIOs: %d\n", ret);
+}
+
 static int rt712_sdca_calibration(struct rt712_sdca_priv *rt712)
 {
 	unsigned int val, loop_rc = 0, loop_dc = 0;
@@ -1101,6 +1204,9 @@ static int rt712_sdca_probe(struct snd_soc_component *component)
 			rt712_sdca_spk_dapm_routes, ARRAY_SIZE(rt712_sdca_spk_dapm_routes));
 	}
 
+	/* initialize GPIOs */
+	rt712_sdca_gpio_init(rt712);
+
 	if (!rt712->first_hw_init)
 		return 0;
 
diff --git a/sound/soc/codecs/rt712-sdca.h b/sound/soc/codecs/rt712-sdca.h
index 6229fe341bb5..362e6226982a 100644
--- a/sound/soc/codecs/rt712-sdca.h
+++ b/sound/soc/codecs/rt712-sdca.h
@@ -14,6 +14,7 @@
 #include <linux/soundwire/sdw_type.h>
 #include <sound/soc.h>
 #include <linux/workqueue.h>
+#include <linux/gpio/driver.h>
 
 struct  rt712_sdca_priv {
 	struct regmap *regmap;
@@ -45,6 +46,7 @@ struct  rt712_sdca_priv {
 	bool fu05_dapm_mute;
 	bool fu05_mixer_l_mute;
 	bool fu05_mixer_r_mute;
+	struct gpio_chip gpio_chip;
 };
 
 struct rt712_dmic_kctrl_priv {
@@ -114,6 +116,9 @@ struct rt712_dmic_kctrl_priv {
 #define RT712_HDA_LEGACY_MUX_CTL0			0x00
 #define RT712_HDA_LEGACY_CONFIG_CTL0			0x06
 #define RT712_HDA_LEGACY_RESET_CTL			0x08
+#define RT712_HDA_GPIO_EN_CTL				0x09
+#define RT712_HDA_GPIO_DIRECTION_CTL			0x0a
+#define RT712_HDA_GPIO_SET_CTL				0x0b
 #define RT712_HDA_LEGACY_GPIO_WAKE_EN_CTL		0x0e
 #define RT712_DMIC_ENT_FLOAT_CTL			0x10
 #define RT712_DMIC_GAIN_ENT_FLOAT_CTL0			0x11
@@ -271,7 +276,6 @@ enum {
 	RT712_CLK_FREQ_22_5792MHZ = 4,
 };
 
-
 int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave);
 int rt712_sdca_init(struct device *dev, struct regmap *regmap,
 			struct regmap *mbq_regmap, struct sdw_slave *slave);
-- 
2.54.0


             reply	other threads:[~2026-09-16  9:05 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16  9:05 shumingf [this message]
2026-09-16 21:39 ` [PATCH] ASoC: rt712: add GPIOs for LED control Mark Brown
2026-09-17  6:24   ` Shuming [范書銘]
2026-09-17 11:05     ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260916090513.2294466-1-shumingf@realtek.com \
    --to=shumingf@realtek.com \
    --cc=broonie@kernel.org \
    --cc=derek.fang@realtek.com \
    --cc=flove@realtek.com \
    --cc=jack.yu@realtek.com \
    --cc=lars@metafoo.de \
    --cc=lgirdwood@gmail.com \
    --cc=linux-sound@vger.kernel.org \
    --cc=oder_chiou@realtek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox