ASoC: wm2200: Convert to GPIO descriptors

This converts the WM2200 codec to use GPIO descriptors.
This is a pretty straight-forward conversion, and it also
switches over the single in-tree user in the S3C
Cragganmore module for S3C 6410.

This coded does not seem to get selected or be selectable
through Kconfig, I had to hack another soundcard Kconfig
entry to select it for compile tests.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20231208-descriptors-sound-wlf-v1-3-c4dab6f521ec@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Linus Walleij 2023-12-08 11:09:27 +01:00 committed by Mark Brown
parent 10a366f36e
commit 0119b2a24e
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
3 changed files with 44 additions and 38 deletions

View File

@ -305,12 +305,20 @@ static const struct i2c_board_info wm6230_i2c_devs[] = {
}; };
static struct wm2200_pdata wm2200_pdata = { static struct wm2200_pdata wm2200_pdata = {
.ldo_ena = S3C64XX_GPN(7),
.gpio_defaults = { .gpio_defaults = {
[2] = 0x0005, /* GPIO3 24.576MHz output clock */ [2] = 0x0005, /* GPIO3 24.576MHz output clock */
}, },
}; };
static struct gpiod_lookup_table wm2200_gpiod_table = {
.dev_id = "1-003a", /* Device 003a on I2C bus 1 */
.table = {
GPIO_LOOKUP("GPION", 7,
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
{ },
},
};
static const struct i2c_board_info wm2200_i2c[] = { static const struct i2c_board_info wm2200_i2c[] = {
{ I2C_BOARD_INFO("wm2200", 0x3a), { I2C_BOARD_INFO("wm2200", 0x3a),
.platform_data = &wm2200_pdata, }, .platform_data = &wm2200_pdata, },
@ -372,7 +380,8 @@ static const struct {
.num_spi_devs = ARRAY_SIZE(wm5102_spi_devs), .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs),
.gpiod_table = &wm5102_gpiod_table }, .gpiod_table = &wm5102_gpiod_table },
{ .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1", { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1",
.i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c) }, .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c),
.gpiod_table = &wm2200_gpiod_table },
}; };
static int wlf_gf_module_probe(struct i2c_client *i2c) static int wlf_gf_module_probe(struct i2c_client *i2c)

View File

@ -42,8 +42,6 @@ struct wm2200_micbias {
}; };
struct wm2200_pdata { struct wm2200_pdata {
int reset; /** GPIO controlling /RESET, if any */
int ldo_ena; /** GPIO controlling LODENA, if any */
int irq_flags; int irq_flags;
int gpio_defaults[4]; int gpio_defaults[4];

View File

@ -14,7 +14,7 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/gcd.h> #include <linux/gcd.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
@ -79,6 +79,8 @@ struct wm2200_priv {
struct snd_soc_component *component; struct snd_soc_component *component;
struct wm2200_pdata pdata; struct wm2200_pdata pdata;
struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES]; struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
struct gpio_desc *ldo_ena;
struct gpio_desc *reset;
struct completion fll_lock; struct completion fll_lock;
int fll_fout; int fll_fout;
@ -975,9 +977,10 @@ static const struct reg_sequence wm2200_reva_patch[] = {
static int wm2200_reset(struct wm2200_priv *wm2200) static int wm2200_reset(struct wm2200_priv *wm2200)
{ {
if (wm2200->pdata.reset) { if (wm2200->reset) {
gpio_set_value_cansleep(wm2200->pdata.reset, 0); /* Descriptor flagged active low, so this will be inverted */
gpio_set_value_cansleep(wm2200->pdata.reset, 1); gpiod_set_value_cansleep(wm2200->reset, 1);
gpiod_set_value_cansleep(wm2200->reset, 0);
return 0; return 0;
} else { } else {
@ -2246,28 +2249,28 @@ static int wm2200_i2c_probe(struct i2c_client *i2c)
return ret; return ret;
} }
if (wm2200->pdata.ldo_ena) { wm2200->ldo_ena = devm_gpiod_get_optional(&i2c->dev, "wlf,ldo1ena",
ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.ldo_ena, GPIOD_OUT_HIGH);
GPIOF_OUT_INIT_HIGH, if (IS_ERR(wm2200->ldo_ena)) {
"WM2200 LDOENA"); ret = PTR_ERR(wm2200->ldo_ena);
if (ret < 0) { dev_err(&i2c->dev, "Failed to request LDOENA GPIO %d\n",
dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", ret);
wm2200->pdata.ldo_ena, ret); goto err_enable;
goto err_enable; }
} if (wm2200->ldo_ena) {
gpiod_set_consumer_name(wm2200->ldo_ena, "WM2200 LDOENA");
msleep(2); msleep(2);
} }
if (wm2200->pdata.reset) { wm2200->reset = devm_gpiod_get_optional(&i2c->dev, "reset",
ret = devm_gpio_request_one(&i2c->dev, wm2200->pdata.reset, GPIOD_OUT_LOW);
GPIOF_OUT_INIT_HIGH, if (IS_ERR(wm2200->reset)) {
"WM2200 /RESET"); ret = PTR_ERR(wm2200->reset);
if (ret < 0) { dev_err(&i2c->dev, "Failed to request RESET GPIO %d\n",
dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", ret);
wm2200->pdata.reset, ret); goto err_ldo;
goto err_ldo;
}
} }
gpiod_set_consumer_name(wm2200->reset, "WM2200 /RESET");
ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg); ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
if (ret < 0) { if (ret < 0) {
@ -2403,11 +2406,9 @@ err_pm_runtime:
if (i2c->irq) if (i2c->irq)
free_irq(i2c->irq, wm2200); free_irq(i2c->irq, wm2200);
err_reset: err_reset:
if (wm2200->pdata.reset) gpiod_set_value_cansleep(wm2200->reset, 1);
gpio_set_value_cansleep(wm2200->pdata.reset, 0);
err_ldo: err_ldo:
if (wm2200->pdata.ldo_ena) gpiod_set_value_cansleep(wm2200->ldo_ena, 0);
gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
err_enable: err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
wm2200->core_supplies); wm2200->core_supplies);
@ -2421,10 +2422,9 @@ static void wm2200_i2c_remove(struct i2c_client *i2c)
pm_runtime_disable(&i2c->dev); pm_runtime_disable(&i2c->dev);
if (i2c->irq) if (i2c->irq)
free_irq(i2c->irq, wm2200); free_irq(i2c->irq, wm2200);
if (wm2200->pdata.reset) /* Assert RESET, disable LDO */
gpio_set_value_cansleep(wm2200->pdata.reset, 0); gpiod_set_value_cansleep(wm2200->reset, 1);
if (wm2200->pdata.ldo_ena) gpiod_set_value_cansleep(wm2200->ldo_ena, 0);
gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
wm2200->core_supplies); wm2200->core_supplies);
} }
@ -2436,8 +2436,7 @@ static int wm2200_runtime_suspend(struct device *dev)
regcache_cache_only(wm2200->regmap, true); regcache_cache_only(wm2200->regmap, true);
regcache_mark_dirty(wm2200->regmap); regcache_mark_dirty(wm2200->regmap);
if (wm2200->pdata.ldo_ena) gpiod_set_value_cansleep(wm2200->ldo_ena, 0);
gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
wm2200->core_supplies); wm2200->core_supplies);
@ -2457,8 +2456,8 @@ static int wm2200_runtime_resume(struct device *dev)
return ret; return ret;
} }
if (wm2200->pdata.ldo_ena) { if (wm2200->ldo_ena) {
gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1); gpiod_set_value_cansleep(wm2200->ldo_ena, 1);
msleep(2); msleep(2);
} }