GPIO descriptor cleanup for some Wolfson codecs

Merge series from Linus Walleij <linus.walleij@linaro.org>:

This converts the remaining Wolfson ASoC codecs to
use GPIO descriptors.

These Wolfson codecs are mostly used with different
Samsung S3C (especially Cragganmore 6410) board files,
so the in-tree users are fixed up in the process.
This commit is contained in:
Mark Brown 2023-12-09 00:16:04 +00:00
commit 885f68fec0
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0
12 changed files with 209 additions and 304 deletions

View file

@ -32,9 +32,18 @@
#include "crag6410.h"
static struct gpiod_lookup_table wm0010_gpiod_table = {
.dev_id = "spi0.0", /* SPI device name */
.table = {
/* Active high for Glenfarclas Rev 2 */
GPIO_LOOKUP("GPION", 6,
"reset", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct wm0010_pdata wm0010_pdata = {
.gpio_reset = S3C64XX_GPN(6),
.reset_active_high = 1, /* Active high for Glenfarclas Rev 2 */
/* Intentionally left blank */
};
static struct spi_board_info wm1253_devs[] = {
@ -61,10 +70,19 @@ static struct spi_board_info balblair_devs[] = {
},
};
static struct gpiod_lookup_table wm5100_gpiod_table = {
.dev_id = "1-001a", /* Device 001a on I2C bus 1 */
.table = {
GPIO_LOOKUP("GPION", 7,
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("wm5100", 3,
"hp-pol", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct wm5100_pdata wm5100_pdata = {
.ldo_ena = S3C64XX_GPN(7),
.irq_flags = IRQF_TRIGGER_HIGH,
.gpio_base = CODEC_GPIO_BASE,
.in_mode = {
WM5100_IN_DIFF,
@ -73,7 +91,6 @@ static struct wm5100_pdata wm5100_pdata = {
WM5100_IN_SE,
},
.hp_pol = CODEC_GPIO_BASE + 3,
.jack_modes = {
{ WM5100_MICDET_MICBIAS3, 0, 0 },
{ WM5100_MICDET_MICBIAS2, 1, 1 },
@ -110,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,
@ -296,12 +320,20 @@ static const struct i2c_board_info wm6230_i2c_devs[] = {
};
static struct wm2200_pdata wm2200_pdata = {
.ldo_ena = S3C64XX_GPN(7),
.gpio_defaults = {
[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[] = {
{ I2C_BOARD_INFO("wm2200", 0x3a),
.platform_data = &wm2200_pdata, },
@ -337,18 +369,21 @@ static const struct {
{ .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" },
{ .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" },
{ .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin",
.spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
.spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs),
.gpiod_table = &wm0010_gpiod_table },
{ .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" },
{ .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" },
{ .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair",
.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",
.i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
.i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs),
.gpiod_table = &wm5100_gpiod_table },
{ .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
{ .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
.i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs),
@ -362,7 +397,8 @@ static const struct {
.num_spi_devs = ARRAY_SIZE(wm5102_spi_devs),
.gpiod_table = &wm5102_gpiod_table },
{ .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)

View file

@ -39,8 +39,6 @@
#include <linux/mfd/wm831x/irq.h>
#include <linux/mfd/wm831x/gpio.h>
#include <sound/wm1250-ev1.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@ -713,13 +711,16 @@ static struct wm831x_pdata glenfarclas_pmic_pdata = {
.disable_touch = true,
};
static struct wm1250_ev1_pdata wm1250_ev1_pdata = {
.gpios = {
[WM1250_EV1_GPIO_CLK_ENA] = S3C64XX_GPN(12),
[WM1250_EV1_GPIO_CLK_SEL0] = S3C64XX_GPL(12),
[WM1250_EV1_GPIO_CLK_SEL1] = S3C64XX_GPL(13),
[WM1250_EV1_GPIO_OSR] = S3C64XX_GPL(14),
[WM1250_EV1_GPIO_MASTER] = S3C64XX_GPL(8),
static struct gpiod_lookup_table crag_wm1250_ev1_gpiod_table = {
/* The WM1250-EV1 is device 0027 on I2C bus 1 */
.dev_id = "1-0027",
.table = {
GPIO_LOOKUP("GPION", 12, "clk-ena", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("GPIOL", 12, "clk-sel0", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("GPIOL", 13, "clk-sel1", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("GPIOL", 14, "osr", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("GPIOL", 8, "master", GPIO_ACTIVE_HIGH),
{ },
},
};
@ -733,9 +734,7 @@ static struct i2c_board_info i2c_devs1[] = {
{ I2C_BOARD_INFO("wlf-gf-module", 0x24) },
{ I2C_BOARD_INFO("wlf-gf-module", 0x25) },
{ I2C_BOARD_INFO("wlf-gf-module", 0x26) },
{ I2C_BOARD_INFO("wm1250-ev1", 0x27),
.platform_data = &wm1250_ev1_pdata },
{ I2C_BOARD_INFO("wm1250-ev1", 0x27), },
};
static struct s3c2410_platform_i2c i2c1_pdata = {
@ -862,6 +861,7 @@ static void __init crag6410_machine_init(void)
gpiod_add_lookup_table(&crag_pmic_gpiod_table);
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
gpiod_add_lookup_table(&crag_wm1250_ev1_gpiod_table);
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
samsung_keypad_set_platdata(&crag6410_keypad_data);

View file

@ -11,12 +11,6 @@
#define WM0010_PDATA_H
struct wm0010_pdata {
int gpio_reset;
/* Set if there is an inverter between the GPIO controlling
* the reset signal and the device.
*/
int reset_active_high;
int irq_flags;
};

View file

@ -1,24 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/sound/wm1250-ev1.h - Platform data for WM1250-EV1
*
* Copyright 2011 Wolfson Microelectronics. PLC.
*/
#ifndef __LINUX_SND_WM1250_EV1_H
#define __LINUX_SND_WM1250_EV1_H
#define WM1250_EV1_NUM_GPIOS 5
#define WM1250_EV1_GPIO_CLK_ENA 0
#define WM1250_EV1_GPIO_CLK_SEL0 1
#define WM1250_EV1_GPIO_CLK_SEL1 2
#define WM1250_EV1_GPIO_OSR 3
#define WM1250_EV1_GPIO_MASTER 4
struct wm1250_ev1_pdata {
int gpios[WM1250_EV1_NUM_GPIOS];
};
#endif

View file

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

View file

@ -36,11 +36,7 @@ struct wm5100_jack_mode {
#define WM5100_GPIO_SET 0x10000
struct wm5100_pdata {
int reset; /** GPIO controlling /RESET, if any */
int ldo_ena; /** GPIO controlling LODENA, if any */
int hp_pol; /** GPIO controlling headset polarity, if any */
int irq_flags;
int gpio_base;
struct wm5100_jack_mode jack_modes[2];

View file

@ -33,8 +33,6 @@ 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;
@ -42,7 +40,6 @@ struct wm8996_pdata {
u32 spkmute_seq; /** Value for register 0x802 */
int gpio_base;
u32 gpio_default[5];
int num_retune_mobile_cfgs;

View file

@ -18,7 +18,7 @@
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
@ -94,8 +94,7 @@ struct wm0010_priv {
struct wm0010_pdata pdata;
int gpio_reset;
int gpio_reset_value;
struct gpio_desc *reset;
struct regulator_bulk_data core_supplies[2];
struct regulator *dbvdd;
@ -174,8 +173,7 @@ static void wm0010_halt(struct snd_soc_component *component)
case WM0010_STAGE2:
case WM0010_FIRMWARE:
/* Remember to put chip back into reset */
gpio_set_value_cansleep(wm0010->gpio_reset,
wm0010->gpio_reset_value);
gpiod_set_value_cansleep(wm0010->reset, 1);
/* Disable the regulators */
regulator_disable(wm0010->dbvdd);
regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
@ -610,7 +608,7 @@ static int wm0010_boot(struct snd_soc_component *component)
}
/* Release reset */
gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value);
gpiod_set_value_cansleep(wm0010->reset, 0);
spin_lock_irqsave(&wm0010->irq_lock, flags);
wm0010->state = WM0010_OUT_OF_RESET;
spin_unlock_irqrestore(&wm0010->irq_lock, flags);
@ -863,7 +861,6 @@ static int wm0010_probe(struct snd_soc_component *component)
static int wm0010_spi_probe(struct spi_device *spi)
{
unsigned long gpio_flags;
int ret;
int trigger;
int irq;
@ -903,31 +900,11 @@ static int wm0010_spi_probe(struct spi_device *spi)
return ret;
}
if (wm0010->pdata.gpio_reset) {
wm0010->gpio_reset = wm0010->pdata.gpio_reset;
if (wm0010->pdata.reset_active_high)
wm0010->gpio_reset_value = 1;
else
wm0010->gpio_reset_value = 0;
if (wm0010->gpio_reset_value)
gpio_flags = GPIOF_OUT_INIT_HIGH;
else
gpio_flags = GPIOF_OUT_INIT_LOW;
ret = devm_gpio_request_one(wm0010->dev, wm0010->gpio_reset,
gpio_flags, "wm0010 reset");
if (ret < 0) {
dev_err(wm0010->dev,
"Failed to request GPIO for DSP reset: %d\n",
ret);
return ret;
}
} else {
dev_err(wm0010->dev, "No reset GPIO configured\n");
return -EINVAL;
}
wm0010->reset = devm_gpiod_get(wm0010->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(wm0010->reset))
return dev_err_probe(wm0010->dev, PTR_ERR(wm0010->reset),
"could not get RESET GPIO\n");
gpiod_set_consumer_name(wm0010->reset, "wm0010 reset");
wm0010->state = WM0010_POWER_OFF;
@ -972,8 +949,7 @@ static void wm0010_spi_remove(struct spi_device *spi)
{
struct wm0010_priv *wm0010 = spi_get_drvdata(spi);
gpio_set_value_cansleep(wm0010->gpio_reset,
wm0010->gpio_reset_value);
gpiod_set_value_cansleep(wm0010->reset, 1);
irq_set_irq_wake(wm0010->irq, 0);

View file

@ -9,34 +9,23 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/wm1250-ev1.h>
static const char *wm1250_gpio_names[WM1250_EV1_NUM_GPIOS] = {
"WM1250 CLK_ENA",
"WM1250 CLK_SEL0",
"WM1250 CLK_SEL1",
"WM1250 OSR",
"WM1250 MASTER",
};
struct wm1250_priv {
struct gpio gpios[WM1250_EV1_NUM_GPIOS];
struct gpio_desc *clk_ena;
struct gpio_desc *clk_sel0;
struct gpio_desc *clk_sel1;
struct gpio_desc *osr;
struct gpio_desc *master;
};
static int wm1250_ev1_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
struct wm1250_priv *wm1250 = dev_get_drvdata(component->dev);
int ena;
if (wm1250)
ena = wm1250->gpios[WM1250_EV1_GPIO_CLK_ENA].gpio;
else
ena = -1;
switch (level) {
case SND_SOC_BIAS_ON:
@ -46,13 +35,11 @@ static int wm1250_ev1_set_bias_level(struct snd_soc_component *component,
break;
case SND_SOC_BIAS_STANDBY:
if (ena >= 0)
gpio_set_value_cansleep(ena, 1);
gpiod_set_value_cansleep(wm1250->clk_ena, 1);
break;
case SND_SOC_BIAS_OFF:
if (ena >= 0)
gpio_set_value_cansleep(ena, 0);
gpiod_set_value_cansleep(wm1250->clk_ena, 0);
break;
}
@ -80,28 +67,20 @@ static int wm1250_ev1_hw_params(struct snd_pcm_substream *substream,
switch (params_rate(params)) {
case 8000:
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
1);
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
1);
gpiod_set_value(wm1250->clk_sel0, 1);
gpiod_set_value(wm1250->clk_sel1, 1);
break;
case 16000:
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
0);
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
1);
gpiod_set_value(wm1250->clk_sel0, 0);
gpiod_set_value(wm1250->clk_sel1, 1);
break;
case 32000:
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
1);
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
0);
gpiod_set_value(wm1250->clk_sel0, 1);
gpiod_set_value(wm1250->clk_sel1, 0);
break;
case 64000:
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
0);
gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
0);
gpiod_set_value(wm1250->clk_sel0, 0);
gpiod_set_value(wm1250->clk_sel1, 0);
break;
default:
return -EINVAL;
@ -150,45 +129,43 @@ static int wm1250_ev1_pdata(struct i2c_client *i2c)
{
struct wm1250_ev1_pdata *pdata = dev_get_platdata(&i2c->dev);
struct wm1250_priv *wm1250;
int i, ret;
int ret;
if (!pdata)
return 0;
wm1250 = devm_kzalloc(&i2c->dev, sizeof(*wm1250), GFP_KERNEL);
if (!wm1250) {
ret = -ENOMEM;
goto err;
}
if (!wm1250)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(wm1250->gpios); i++) {
wm1250->gpios[i].gpio = pdata->gpios[i];
wm1250->gpios[i].label = wm1250_gpio_names[i];
wm1250->gpios[i].flags = GPIOF_OUT_INIT_LOW;
}
wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].flags = GPIOF_OUT_INIT_HIGH;
wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].flags = GPIOF_OUT_INIT_HIGH;
wm1250->clk_ena = devm_gpiod_get(&i2c->dev, "clk-ena", GPIOD_OUT_LOW);
if (IS_ERR(wm1250->clk_ena))
return dev_err_probe(&i2c->dev, PTR_ERR(wm1250->clk_ena),
"failed to get clock enable GPIO\n");
ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
if (ret != 0) {
dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret);
goto err;
}
wm1250->clk_sel0 = devm_gpiod_get(&i2c->dev, "clk-sel0", GPIOD_OUT_HIGH);
if (IS_ERR(wm1250->clk_sel0))
return dev_err_probe(&i2c->dev, PTR_ERR(wm1250->clk_sel0),
"failed to get clock sel0 GPIO\n");
wm1250->clk_sel1 = devm_gpiod_get(&i2c->dev, "clk-sel1", GPIOD_OUT_HIGH);
if (IS_ERR(wm1250->clk_sel1))
return dev_err_probe(&i2c->dev, PTR_ERR(wm1250->clk_sel1),
"failed to get clock sel1 GPIO\n");
wm1250->osr = devm_gpiod_get(&i2c->dev, "osr", GPIOD_OUT_LOW);
if (IS_ERR(wm1250->osr))
return dev_err_probe(&i2c->dev, PTR_ERR(wm1250->osr),
"failed to get OSR GPIO\n");
wm1250->master = devm_gpiod_get(&i2c->dev, "master", GPIOD_OUT_LOW);
if (IS_ERR(wm1250->master))
return dev_err_probe(&i2c->dev, PTR_ERR(wm1250->master),
"failed to get MASTER GPIO\n");
dev_set_drvdata(&i2c->dev, wm1250);
return ret;
err:
return ret;
}
static void wm1250_ev1_free(struct i2c_client *i2c)
{
struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev);
if (wm1250)
gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
}
static int wm1250_ev1_probe(struct i2c_client *i2c)
@ -221,18 +198,12 @@ static int wm1250_ev1_probe(struct i2c_client *i2c)
&wm1250_ev1_dai, 1);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
wm1250_ev1_free(i2c);
return ret;
}
return 0;
}
static void wm1250_ev1_remove(struct i2c_client *i2c)
{
wm1250_ev1_free(i2c);
}
static const struct i2c_device_id wm1250_ev1_i2c_id[] = {
{ "wm1250-ev1", 0 },
{ }
@ -244,7 +215,6 @@ static struct i2c_driver wm1250_ev1_i2c_driver = {
.name = "wm1250-ev1",
},
.probe = wm1250_ev1_probe,
.remove = wm1250_ev1_remove,
.id_table = wm1250_ev1_i2c_id,
};

View file

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

View file

@ -15,7 +15,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/pm_runtime.h>
#include <linux/regulator/consumer.h>
@ -55,6 +55,9 @@ struct wm5100_priv {
struct snd_soc_component *component;
struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
struct gpio_desc *reset;
struct gpio_desc *ldo_ena;
struct gpio_desc *hp_pol;
int rev;
@ -205,9 +208,9 @@ static void wm5100_free_sr(struct snd_soc_component *component, int rate)
static int wm5100_reset(struct wm5100_priv *wm5100)
{
if (wm5100->pdata.reset) {
gpio_set_value_cansleep(wm5100->pdata.reset, 0);
gpio_set_value_cansleep(wm5100->pdata.reset, 1);
if (wm5100->reset) {
gpiod_set_value_cansleep(wm5100->reset, 1);
gpiod_set_value_cansleep(wm5100->reset, 0);
return 0;
} else {
@ -1974,7 +1977,7 @@ static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
if (WARN_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes)))
return;
gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol);
gpiod_set_value_cansleep(wm5100->hp_pol, mode->hp_pol);
regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1,
WM5100_ACCDET_BIAS_SRC_MASK |
WM5100_ACCDET_SRC,
@ -2299,11 +2302,7 @@ static void wm5100_init_gpio(struct i2c_client *i2c)
wm5100->gpio_chip = wm5100_template_chip;
wm5100->gpio_chip.ngpio = 6;
wm5100->gpio_chip.parent = &i2c->dev;
if (wm5100->pdata.gpio_base)
wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
else
wm5100->gpio_chip.base = -1;
wm5100->gpio_chip.base = -1;
ret = gpiochip_add_data(&wm5100->gpio_chip, wm5100);
if (ret != 0)
@ -2349,35 +2348,20 @@ static int wm5100_probe(struct snd_soc_component *component)
snd_soc_dapm_new_controls(dapm, wm5100_dapm_widgets_noirq,
ARRAY_SIZE(wm5100_dapm_widgets_noirq));
if (wm5100->pdata.hp_pol) {
ret = gpio_request_one(wm5100->pdata.hp_pol,
GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
if (ret < 0) {
dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
wm5100->pdata.hp_pol, ret);
goto err_gpio;
}
wm5100->hp_pol = devm_gpiod_get_optional(&i2c->dev, "hp-pol",
GPIOD_OUT_HIGH);
if (IS_ERR(wm5100->hp_pol)) {
ret = PTR_ERR(wm5100->hp_pol);
dev_err(&i2c->dev, "Failed to request HP_POL GPIO: %d\n",
ret);
return ret;
}
return 0;
err_gpio:
return ret;
}
static void wm5100_remove(struct snd_soc_component *component)
{
struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component);
if (wm5100->pdata.hp_pol) {
gpio_free(wm5100->pdata.hp_pol);
}
}
static const struct snd_soc_component_driver soc_component_dev_wm5100 = {
.probe = wm5100_probe,
.remove = wm5100_remove,
.set_sysclk = wm5100_set_sysclk,
.set_pll = wm5100_set_fll,
.seq_notifier = wm5100_seq_notifier,
@ -2460,26 +2444,26 @@ static int wm5100_i2c_probe(struct i2c_client *i2c)
goto err;
}
if (wm5100->pdata.ldo_ena) {
ret = gpio_request_one(wm5100->pdata.ldo_ena,
GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
if (ret < 0) {
dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
wm5100->pdata.ldo_ena, ret);
goto err_enable;
}
wm5100->ldo_ena = devm_gpiod_get_optional(&i2c->dev, "wlf,ldo1ena",
GPIOD_OUT_HIGH);
if (IS_ERR(wm5100->ldo_ena)) {
ret = PTR_ERR(wm5100->ldo_ena);
dev_err(&i2c->dev, "Failed to request LDOENA GPIO: %d\n", ret);
goto err_enable;
}
if (wm5100->ldo_ena) {
gpiod_set_consumer_name(wm5100->ldo_ena, "WM5100 LDOENA");
msleep(2);
}
if (wm5100->pdata.reset) {
ret = gpio_request_one(wm5100->pdata.reset,
GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
if (ret < 0) {
dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
wm5100->pdata.reset, ret);
goto err_ldo;
}
wm5100->reset = devm_gpiod_get_optional(&i2c->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(wm5100->reset)) {
ret = PTR_ERR(wm5100->reset);
dev_err(&i2c->dev, "Failed to request /RESET GPIO: %d\n", ret);
goto err_ldo;
}
gpiod_set_consumer_name(wm5100->reset, "WM5100 /RESET");
ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg);
if (ret < 0) {
@ -2619,15 +2603,9 @@ static int wm5100_i2c_probe(struct i2c_client *i2c)
if (i2c->irq)
free_irq(i2c->irq, wm5100);
wm5100_free_gpio(i2c);
if (wm5100->pdata.reset) {
gpio_set_value_cansleep(wm5100->pdata.reset, 0);
gpio_free(wm5100->pdata.reset);
}
gpiod_set_value_cansleep(wm5100->reset, 1);
err_ldo:
if (wm5100->pdata.ldo_ena) {
gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
gpio_free(wm5100->pdata.ldo_ena);
}
gpiod_set_value_cansleep(wm5100->ldo_ena, 0);
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
wm5100->core_supplies);
@ -2643,14 +2621,8 @@ static void wm5100_i2c_remove(struct i2c_client *i2c)
if (i2c->irq)
free_irq(i2c->irq, wm5100);
wm5100_free_gpio(i2c);
if (wm5100->pdata.reset) {
gpio_set_value_cansleep(wm5100->pdata.reset, 0);
gpio_free(wm5100->pdata.reset);
}
if (wm5100->pdata.ldo_ena) {
gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
gpio_free(wm5100->pdata.ldo_ena);
}
gpiod_set_value_cansleep(wm5100->reset, 1);
gpiod_set_value_cansleep(wm5100->ldo_ena, 0);
}
#ifdef CONFIG_PM
@ -2660,8 +2632,7 @@ static int wm5100_runtime_suspend(struct device *dev)
regcache_cache_only(wm5100->regmap, true);
regcache_mark_dirty(wm5100->regmap);
if (wm5100->pdata.ldo_ena)
gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
gpiod_set_value_cansleep(wm5100->ldo_ena, 0);
regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
wm5100->core_supplies);
@ -2681,8 +2652,8 @@ static int wm5100_runtime_resume(struct device *dev)
return ret;
}
if (wm5100->pdata.ldo_ena) {
gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1);
if (wm5100->ldo_ena) {
gpiod_set_value_cansleep(wm5100->ldo_ena, 1);
msleep(2);
}

View file

@ -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>
@ -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;
@ -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);
}
@ -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),
@ -2188,6 +2188,8 @@ 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)
@ -2195,14 +2197,8 @@ 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);
@ -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];
@ -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);
}
@ -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,
@ -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;
@ -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[] = {