mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
ASoC: wsa881x: Move custom workaround to gpiolib-of
The WSA881x codec driver has a local workaround for old device trees that have the "powerdown" GPIO flagged as active high, despite it is active low. This quirk can be replaced by a single quirk entry in gpiolib-of.c Drop all polarity inversion code and drop the surplus gpiod_direction_output() call in probe() since we now set up the line correctly when getting the GPIO. Also drop the inclusion of the unused <linux/gpio.h>. Signed-off-by: Linus Walleij <linusw@kernel.org> Link: https://patch.msgid.link/20260427-asoc-wsa881x-v2-1-9ef965f94624@kernel.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
committed by
Mark Brown
parent
254f49634e
commit
bfa336cee3
@@ -240,6 +240,14 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np,
|
||||
* treats it as "active low".
|
||||
*/
|
||||
{ "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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user