Skip to content

Commit

Permalink
ASoC: wm8996: Convert to GPIO descriptors
Browse files Browse the repository at this point in the history
This converts the WM8996 codec to use GPIO descriptors, an a similar
way to WM5100.

The driver is instantiating a GPIO chip named wm8996, and we get
rid of the base address for the GPIO chip from the platform data and
just use dynamic numbering. Move base and ngpio into the static
gpio_chip template.

Fix up the only in-tree user which is the Cragganmore 6410 module.

Signed-off-by: Linus Walleij <[email protected]>
Reviewed-by: Charles Keepax <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
  • Loading branch information
linusw authored and broonie committed Dec 8, 2023
1 parent 8563cfe commit 729f02e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 39 deletions.
14 changes: 11 additions & 3 deletions arch/arm/mach-s3c/mach-crag6410-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,16 @@ static struct wm8996_retune_mobile_config wm8996_retune[] = {
},
};

static struct gpiod_lookup_table wm8996_gpiod_table = {
.dev_id = "1-001a", /* Device 001a on I2C bus 1 */
.table = {
GPIO_LOOKUP("GPION", 7,
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
{ },
},
};

static struct wm8996_pdata wm8996_pdata __initdata = {
.ldo_ena = S3C64XX_GPN(7),
.gpio_base = CODEC_GPIO_BASE,
.micdet_def = 1,
.inl_mode = WM8996_DIFFERRENTIAL_1,
.inr_mode = WM8996_DIFFERRENTIAL_1,
Expand Down Expand Up @@ -370,7 +377,8 @@ static const struct {
.spi_devs = balblair_devs,
.num_spi_devs = ARRAY_SIZE(balblair_devs) },
{ .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu",
.i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
.i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs),
.gpiod_table = &wm8996_gpiod_table },
{ .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory",
.i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
{ .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman",
Expand Down
3 changes: 0 additions & 3 deletions include/sound/wm8996.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,13 @@ struct wm8996_retune_mobile_config {
struct wm8996_pdata {
int irq_flags; /** Set IRQ trigger flags; default active low */

int ldo_ena; /** GPIO for LDO1; -1 for none */

int micdet_def; /** Default MICDET_SRC/HP1FB_SRC/MICD_BIAS */

enum wm8996_inmode inl_mode;
enum wm8996_inmode inr_mode;

u32 spkmute_seq; /** Value for register 0x802 */

int gpio_base;
u32 gpio_default[5];

int num_retune_mobile_cfgs;
Expand Down
58 changes: 25 additions & 33 deletions sound/soc/codecs/wm8996.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <linux/pm.h>
#include <linux/gcd.h>
#include <linux/gpio/driver.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
Expand Down Expand Up @@ -51,7 +51,7 @@ struct wm8996_priv {
struct regmap *regmap;
struct snd_soc_component *component;

int ldo1ena;
struct gpio_desc *ldo_ena;

int sysclk;
int sysclk_src;
Expand Down Expand Up @@ -1596,9 +1596,9 @@ static int wm8996_set_bias_level(struct snd_soc_component *component,
return ret;
}

if (wm8996->pdata.ldo_ena >= 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena,
1);
if (wm8996->ldo_ena) {
gpiod_set_value_cansleep(wm8996->ldo_ena,
1);
msleep(5);
}

Expand All @@ -1615,8 +1615,8 @@ static int wm8996_set_bias_level(struct snd_soc_component *component,

case SND_SOC_BIAS_OFF:
regcache_cache_only(wm8996->regmap, true);
if (wm8996->pdata.ldo_ena >= 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
if (wm8996->ldo_ena) {
gpiod_set_value_cansleep(wm8996->ldo_ena, 0);
regcache_cache_only(wm8996->regmap, true);
}
regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
Expand Down Expand Up @@ -2188,21 +2188,17 @@ static const struct gpio_chip wm8996_template_chip = {
.direction_input = wm8996_gpio_direction_in,
.get = wm8996_gpio_get,
.can_sleep = 1,
.ngpio = 5,
.base = -1,
};

static void wm8996_init_gpio(struct wm8996_priv *wm8996)
{
int ret;

wm8996->gpio_chip = wm8996_template_chip;
wm8996->gpio_chip.ngpio = 5;
wm8996->gpio_chip.parent = wm8996->dev;

if (wm8996->pdata.gpio_base)
wm8996->gpio_chip.base = wm8996->pdata.gpio_base;
else
wm8996->gpio_chip.base = -1;

ret = gpiochip_add_data(&wm8996->gpio_chip, wm8996);
if (ret != 0)
dev_err(wm8996->dev, "Failed to add GPIOs: %d\n", ret);
Expand Down Expand Up @@ -2771,15 +2767,15 @@ static int wm8996_i2c_probe(struct i2c_client *i2c)
memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev),
sizeof(wm8996->pdata));

if (wm8996->pdata.ldo_ena > 0) {
ret = gpio_request_one(wm8996->pdata.ldo_ena,
GPIOF_OUT_INIT_LOW, "WM8996 ENA");
if (ret < 0) {
dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
wm8996->pdata.ldo_ena, ret);
goto err;
}
wm8996->ldo_ena = devm_gpiod_get_optional(&i2c->dev, "wlf,ldo1ena",
GPIOD_OUT_LOW);
if (IS_ERR(wm8996->ldo_ena)) {
ret = PTR_ERR(wm8996->ldo_ena);
dev_err(&i2c->dev, "Failed to request LDO ENA GPIO: %d\n",
ret);
goto err;
}
gpiod_set_consumer_name(wm8996->ldo_ena, "WM8996 ENA");

for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
wm8996->supplies[i].supply = wm8996_supply_names[i];
Expand Down Expand Up @@ -2814,8 +2810,8 @@ static int wm8996_i2c_probe(struct i2c_client *i2c)
goto err_gpio;
}

if (wm8996->pdata.ldo_ena > 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
if (wm8996->ldo_ena) {
gpiod_set_value_cansleep(wm8996->ldo_ena, 1);
msleep(5);
}

Expand Down Expand Up @@ -2847,8 +2843,8 @@ static int wm8996_i2c_probe(struct i2c_client *i2c)
dev_info(&i2c->dev, "revision %c\n",
(reg & WM8996_CHIP_REV_MASK) + 'A');

if (wm8996->pdata.ldo_ena > 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
if (wm8996->ldo_ena) {
gpiod_set_value_cansleep(wm8996->ldo_ena, 0);
regcache_cache_only(wm8996->regmap, true);
} else {
ret = regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
Expand Down Expand Up @@ -3054,12 +3050,10 @@ static int wm8996_i2c_probe(struct i2c_client *i2c)
wm8996_free_gpio(wm8996);
err_regmap:
err_enable:
if (wm8996->pdata.ldo_ena > 0)
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
if (wm8996->ldo_ena)
gpiod_set_value_cansleep(wm8996->ldo_ena, 0);
regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
err_gpio:
if (wm8996->pdata.ldo_ena > 0)
gpio_free(wm8996->pdata.ldo_ena);
err:

return ret;
Expand All @@ -3070,10 +3064,8 @@ static void wm8996_i2c_remove(struct i2c_client *client)
struct wm8996_priv *wm8996 = i2c_get_clientdata(client);

wm8996_free_gpio(wm8996);
if (wm8996->pdata.ldo_ena > 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
gpio_free(wm8996->pdata.ldo_ena);
}
if (wm8996->ldo_ena)
gpiod_set_value_cansleep(wm8996->ldo_ena, 0);
}

static const struct i2c_device_id wm8996_i2c_id[] = {
Expand Down

0 comments on commit 729f02e

Please sign in to comment.