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
next 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