summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-04-28 01:39:16 +0300
committerMark Brown <broonie@kernel.org>2026-04-28 01:39:16 +0300
commitf4d00860e4a70aede0fb95173a5dc12bc89d7ee3 (patch)
treeb320a114491ccbfd50a6458aa3bb7b8714c5a03a
parenta960faa424ae459a7843da2734fa51580814b89a (diff)
parentbfa336cee3324f991e93e9e570e8b827273df97e (diff)
downloadlinux-f4d00860e4a70aede0fb95173a5dc12bc89d7ee3.tar.xz
ASoC: wsa881x: Move custom workaround to gpiolib-of
On a separate branch so we can have a tag shared with gpiolib. Link: https://patch.msgid.link/20260427-asoc-wsa881x-v2-1-9ef965f94624@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/gpio/gpiolib-of.c8
-rw-r--r--sound/soc/codecs/wsa881x.c35
2 files changed, 12 insertions, 31 deletions
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 2c923d17541f..90f6295ab338 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -241,6 +241,14 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np,
*/
{ "ti,tsc2005", "reset-gpios", false },
#endif
+#if IS_ENABLED(CONFIG_SND_SOC_WSA881X)
+ /*
+ * WSA881 powerdown is always active low, but some device trees
+ * missed this when first contributed. It also has a very strange
+ * compatible.
+ */
+ { "sdw10217201000", "powerdown-gpios", false },
+#endif
};
unsigned int i;
diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
index 2fc234adca5f..d15fda648dad 100644
--- a/sound/soc/codecs/wsa881x.c
+++ b/sound/soc/codecs/wsa881x.c
@@ -3,7 +3,6 @@
// Copyright (c) 2019, Linaro Limited
#include <linux/bitops.h>
-#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/regmap.h>
@@ -672,11 +671,6 @@ struct wsa881x_priv {
struct sdw_stream_runtime *sruntime;
struct sdw_port_config port_config[WSA881X_MAX_SWR_PORTS];
struct gpio_desc *sd_n;
- /*
- * Logical state for SD_N GPIO: high for shutdown, low for enable.
- * For backwards compatibility.
- */
- unsigned int sd_n_val;
int active_ports;
bool hw_init;
bool port_prepared[WSA881X_MAX_SWR_PORTS];
@@ -1121,31 +1115,11 @@ static int wsa881x_probe(struct sdw_slave *pdev,
if (!wsa881x)
return -ENOMEM;
- wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown", 0);
+ wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_LOW);
if (IS_ERR(wsa881x->sd_n))
return dev_err_probe(dev, PTR_ERR(wsa881x->sd_n),
"Shutdown Control GPIO not found\n");
- /*
- * Backwards compatibility work-around.
- *
- * The SD_N GPIO is active low, however upstream DTS used always active
- * high. Changing the flag in driver and DTS will break backwards
- * compatibility, so add a simple value inversion to work with both old
- * and new DTS.
- *
- * This won't work properly with DTS using the flags properly in cases:
- * 1. Old DTS with proper ACTIVE_LOW, however such case was broken
- * before as the driver required the active high.
- * 2. New DTS with proper ACTIVE_HIGH (intended), which is rare case
- * (not existing upstream) but possible. This is the price of
- * backwards compatibility, therefore this hack should be removed at
- * some point.
- */
- wsa881x->sd_n_val = gpiod_is_active_low(wsa881x->sd_n);
- if (!wsa881x->sd_n_val)
- dev_warn(dev, "Using ACTIVE_HIGH for shutdown GPIO. Your DTB might be outdated or you use unsupported configuration for the GPIO.");
-
dev_set_drvdata(dev, wsa881x);
wsa881x->slave = pdev;
wsa881x->dev = dev;
@@ -1158,7 +1132,6 @@ static int wsa881x_probe(struct sdw_slave *pdev,
pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
pdev->prop.clk_stop_mode1 = true;
- gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config);
if (IS_ERR(wsa881x->regmap))
@@ -1181,7 +1154,7 @@ static int wsa881x_runtime_suspend(struct device *dev)
struct regmap *regmap = dev_get_regmap(dev, NULL);
struct wsa881x_priv *wsa881x = dev_get_drvdata(dev);
- gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val);
+ gpiod_direction_output(wsa881x->sd_n, 1);
regcache_cache_only(regmap, true);
regcache_mark_dirty(regmap);
@@ -1196,13 +1169,13 @@ static int wsa881x_runtime_resume(struct device *dev)
struct wsa881x_priv *wsa881x = dev_get_drvdata(dev);
unsigned long time;
- gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
+ gpiod_direction_output(wsa881x->sd_n, 0);
time = wait_for_completion_timeout(&slave->initialization_complete,
msecs_to_jiffies(WSA881X_PROBE_TIMEOUT));
if (!time) {
dev_err(dev, "Initialization not complete, timed out\n");
- gpiod_direction_output(wsa881x->sd_n, wsa881x->sd_n_val);
+ gpiod_direction_output(wsa881x->sd_n, 1);
return -ETIMEDOUT;
}