summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig1
-rw-r--r--sound/soc/codecs/adau1373.c21
-rw-r--r--sound/soc/codecs/adau1761.c2
-rw-r--r--sound/soc/codecs/adau1781.c2
-rw-r--r--sound/soc/codecs/adau17x1.c8
-rw-r--r--sound/soc/codecs/adau17x1.h1
-rw-r--r--sound/soc/codecs/adav80x.c23
-rw-r--r--sound/soc/codecs/es8328.c6
-rw-r--r--sound/soc/codecs/lm49453.c14
-rw-r--r--sound/soc/codecs/rt5677.c187
-rw-r--r--sound/soc/codecs/rt5677.h166
-rw-r--r--sound/soc/codecs/ssm2518.c13
-rw-r--r--sound/soc/codecs/ssm2602.c24
-rw-r--r--sound/soc/codecs/tlv320aic3x.c16
-rw-r--r--sound/soc/codecs/wm5100.c5
-rw-r--r--sound/soc/codecs/wm8804.c19
-rw-r--r--sound/soc/codecs/wm8903.c6
-rw-r--r--sound/soc/codecs/wm8962.c5
-rw-r--r--sound/soc/codecs/wm8995.c19
-rw-r--r--sound/soc/codecs/wm8996.c6
20 files changed, 337 insertions, 207 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 184ee7e2a3d..7678122f8fe 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -57,6 +57,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_DA7213 if I2C
select SND_SOC_DA732X if I2C
select SND_SOC_DA9055 if I2C
+ select SND_SOC_DMIC
select SND_SOC_BT_SCO
select SND_SOC_ES8328_SPI if SPI_MASTER
select SND_SOC_ES8328_I2C if I2C
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 1ff7d4d027e..7c784ad3e8b 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1448,29 +1448,10 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static int adau1373_remove(struct snd_soc_codec *codec)
-{
- adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int adau1373_suspend(struct snd_soc_codec *codec)
-{
- struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regcache_cache_only(adau1373->regmap, true);
-
- return ret;
-}
-
static int adau1373_resume(struct snd_soc_codec *codec)
{
struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
- regcache_cache_only(adau1373->regmap, false);
- adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
regcache_sync(adau1373->regmap);
return 0;
@@ -1501,8 +1482,6 @@ static const struct regmap_config adau1373_regmap_config = {
static struct snd_soc_codec_driver adau1373_codec_driver = {
.probe = adau1373_probe,
- .remove = adau1373_remove,
- .suspend = adau1373_suspend,
.resume = adau1373_resume,
.set_bias_level = adau1373_set_bias_level,
.idle_bias_off = true,
diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c
index 848cab83955..5518ebd6947 100644
--- a/sound/soc/codecs/adau1761.c
+++ b/sound/soc/codecs/adau1761.c
@@ -714,9 +714,9 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
static const struct snd_soc_codec_driver adau1761_codec_driver = {
.probe = adau1761_codec_probe,
- .suspend = adau17x1_suspend,
.resume = adau17x1_resume,
.set_bias_level = adau1761_set_bias_level,
+ .suspend_bias_off = true,
.controls = adau1761_controls,
.num_controls = ARRAY_SIZE(adau1761_controls),
diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c
index 045a6141384..e9fc00fb13d 100644
--- a/sound/soc/codecs/adau1781.c
+++ b/sound/soc/codecs/adau1781.c
@@ -446,9 +446,9 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
static const struct snd_soc_codec_driver adau1781_codec_driver = {
.probe = adau1781_codec_probe,
- .suspend = adau17x1_suspend,
.resume = adau17x1_resume,
.set_bias_level = adau1781_set_bias_level,
+ .suspend_bias_off = true,
.controls = adau1781_controls,
.num_controls = ARRAY_SIZE(adau1781_controls),
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index 0b659704e60..3e16c1c6411 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -815,13 +815,6 @@ int adau17x1_add_routes(struct snd_soc_codec *codec)
}
EXPORT_SYMBOL_GPL(adau17x1_add_routes);
-int adau17x1_suspend(struct snd_soc_codec *codec)
-{
- codec->driver->set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-EXPORT_SYMBOL_GPL(adau17x1_suspend);
-
int adau17x1_resume(struct snd_soc_codec *codec)
{
struct adau *adau = snd_soc_codec_get_drvdata(codec);
@@ -829,7 +822,6 @@ int adau17x1_resume(struct snd_soc_codec *codec)
if (adau->switch_mode)
adau->switch_mode(codec->dev);
- codec->driver->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
regcache_sync(adau->regmap);
return 0;
diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h
index 3ffabaf4c7a..e4a557fd715 100644
--- a/sound/soc/codecs/adau17x1.h
+++ b/sound/soc/codecs/adau17x1.h
@@ -52,7 +52,6 @@ int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
enum adau17x1_micbias_voltage micbias);
bool adau17x1_readable_register(struct device *dev, unsigned int reg);
bool adau17x1_volatile_register(struct device *dev, unsigned int reg);
-int adau17x1_suspend(struct snd_soc_codec *codec);
int adau17x1_resume(struct snd_soc_codec *codec);
extern const struct snd_soc_dai_ops adau17x1_dai_ops;
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index c43b93fdf0d..ce3cdca9fc6 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -812,42 +812,23 @@ static int adav80x_probe(struct snd_soc_codec *codec)
/* Disable DAC zero flag */
regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6);
- return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-}
-
-static int adav80x_suspend(struct snd_soc_codec *codec)
-{
- struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- int ret;
-
- ret = adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- regcache_cache_only(adav80x->regmap, true);
-
- return ret;
+ return 0;
}
static int adav80x_resume(struct snd_soc_codec *codec)
{
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
- regcache_cache_only(adav80x->regmap, false);
- adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
regcache_sync(adav80x->regmap);
return 0;
}
-static int adav80x_remove(struct snd_soc_codec *codec)
-{
- return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
static struct snd_soc_codec_driver adav80x_codec_driver = {
.probe = adav80x_probe,
- .remove = adav80x_remove,
- .suspend = adav80x_suspend,
.resume = adav80x_resume,
.set_bias_level = adav80x_set_bias_level,
+ .suspend_bias_off = true,
.set_pll = adav80x_set_pll,
.set_sysclk = adav80x_set_sysclk,
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index 7a9f65ad183..f27325155ac 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -602,8 +602,6 @@ static int es8328_suspend(struct snd_soc_codec *codec)
es8328 = snd_soc_codec_get_drvdata(codec);
- es8328_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
clk_disable_unprepare(es8328->clk);
ret = regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),
@@ -643,7 +641,6 @@ static int es8328_resume(struct snd_soc_codec *codec)
return ret;
}
- es8328_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
@@ -665,6 +662,7 @@ static int es8328_codec_probe(struct snd_soc_codec *codec)
es8328->clk = devm_clk_get(codec->dev, NULL);
if (IS_ERR(es8328->clk)) {
dev_err(codec->dev, "codec clock missing or invalid\n");
+ ret = PTR_ERR(es8328->clk);
goto clk_fail;
}
@@ -711,6 +709,8 @@ static struct snd_soc_codec_driver es8328_codec_driver = {
.resume = es8328_resume,
.remove = es8328_remove,
.set_bias_level = es8328_set_bias_level,
+ .suspend_bias_off = true,
+
.controls = es8328_snd_controls,
.num_controls = ARRAY_SIZE(es8328_snd_controls),
.dapm_widgets = es8328_dapm_widgets,
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 275b3f72f3f..c1ae5764983 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -1395,18 +1395,6 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
},
};
-static int lm49453_suspend(struct snd_soc_codec *codec)
-{
- lm49453_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int lm49453_resume(struct snd_soc_codec *codec)
-{
- lm49453_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-
/* power down chip */
static int lm49453_remove(struct snd_soc_codec *codec)
{
@@ -1416,8 +1404,6 @@ static int lm49453_remove(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
.remove = lm49453_remove,
- .suspend = lm49453_suspend,
- .resume = lm49453_resume,
.set_bias_level = lm49453_set_bias_level,
.controls = lm49453_snd_controls,
.num_controls = ARRAY_SIZE(lm49453_snd_controls),
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 5337c448b5e..dc978ad59fc 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -19,6 +19,7 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -1700,14 +1701,19 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("Haptic Generator"),
- SND_SOC_DAPM_PGA("DMIC1", RT5677_DMIC_CTRL1, RT5677_DMIC_1_EN_SFT, 0,
- NULL, 0),
- SND_SOC_DAPM_PGA("DMIC2", RT5677_DMIC_CTRL1, RT5677_DMIC_2_EN_SFT, 0,
- NULL, 0),
- SND_SOC_DAPM_PGA("DMIC3", RT5677_DMIC_CTRL1, RT5677_DMIC_3_EN_SFT, 0,
- NULL, 0),
- SND_SOC_DAPM_PGA("DMIC4", RT5677_DMIC_CTRL2, RT5677_DMIC_4_EN_SFT, 0,
- NULL, 0),
+ SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DMIC3", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DMIC4", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SUPPLY("DMIC1 power", RT5677_DMIC_CTRL1,
+ RT5677_DMIC_1_EN_SFT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DMIC2 power", RT5677_DMIC_CTRL1,
+ RT5677_DMIC_2_EN_SFT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DMIC3 power", RT5677_DMIC_CTRL1,
+ RT5677_DMIC_3_EN_SFT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DMIC4 power", RT5677_DMIC_CTRL2,
+ RT5677_DMIC_4_EN_SFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
@@ -2130,6 +2136,13 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
{ "DMIC L4", NULL, "DMIC CLK" },
{ "DMIC R4", NULL, "DMIC CLK" },
+ { "DMIC L1", NULL, "DMIC1 power" },
+ { "DMIC R1", NULL, "DMIC1 power" },
+ { "DMIC L3", NULL, "DMIC3 power" },
+ { "DMIC R3", NULL, "DMIC3 power" },
+ { "DMIC L4", NULL, "DMIC4 power" },
+ { "DMIC R4", NULL, "DMIC4 power" },
+
{ "BST1", NULL, "IN1P" },
{ "BST1", NULL, "IN1N" },
{ "BST2", NULL, "IN2P" },
@@ -2793,6 +2806,16 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
{ "PDM2R", NULL, "PDM2 R Mux" },
};
+static const struct snd_soc_dapm_route rt5677_dmic2_clk_1[] = {
+ { "DMIC L2", NULL, "DMIC1 power" },
+ { "DMIC R2", NULL, "DMIC1 power" },
+};
+
+static const struct snd_soc_dapm_route rt5677_dmic2_clk_2[] = {
+ { "DMIC L2", NULL, "DMIC2 power" },
+ { "DMIC R2", NULL, "DMIC2 power" },
+};
+
static int rt5677_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
@@ -3138,12 +3161,148 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
+#ifdef CONFIG_GPIOLIB
+static inline struct rt5677_priv *gpio_to_rt5677(struct gpio_chip *chip)
+{
+ return container_of(chip, struct rt5677_priv, gpio_chip);
+}
+
+static void rt5677_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct rt5677_priv *rt5677 = gpio_to_rt5677(chip);
+
+ switch (offset) {
+ case RT5677_GPIO1 ... RT5677_GPIO5:
+ regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
+ 0x1 << (offset * 3 + 1), !!value << (offset * 3 + 1));
+ break;
+
+ case RT5677_GPIO6:
+ regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3,
+ RT5677_GPIO6_OUT_MASK, !!value << RT5677_GPIO6_OUT_SFT);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int rt5677_gpio_direction_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct rt5677_priv *rt5677 = gpio_to_rt5677(chip);
+
+ switch (offset) {
+ case RT5677_GPIO1 ... RT5677_GPIO5:
+ regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
+ 0x3 << (offset * 3 + 1),
+ (0x2 | !!value) << (offset * 3 + 1));
+ break;
+
+ case RT5677_GPIO6:
+ regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3,
+ RT5677_GPIO6_DIR_MASK | RT5677_GPIO6_OUT_MASK,
+ RT5677_GPIO6_DIR_OUT | !!value << RT5677_GPIO6_OUT_SFT);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int rt5677_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct rt5677_priv *rt5677 = gpio_to_rt5677(chip);
+ int value, ret;
+
+ ret = regmap_read(rt5677->regmap, RT5677_GPIO_ST, &value);
+ if (ret < 0)
+ return ret;
+
+ return (value & (0x1 << offset)) >> offset;
+}
+
+static int rt5677_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+ struct rt5677_priv *rt5677 = gpio_to_rt5677(chip);
+
+ switch (offset) {
+ case RT5677_GPIO1 ... RT5677_GPIO5:
+ regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
+ 0x1 << (offset * 3 + 2), 0x0);
+ break;
+
+ case RT5677_GPIO6:
+ regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL3,
+ RT5677_GPIO6_DIR_MASK, RT5677_GPIO6_DIR_IN);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static struct gpio_chip rt5677_template_chip = {
+ .label = "rt5677",
+ .owner = THIS_MODULE,
+ .direction_output = rt5677_gpio_direction_out,
+ .set = rt5677_gpio_set,
+ .direction_input = rt5677_gpio_direction_in,
+ .get = rt5677_gpio_get,
+ .can_sleep = 1,
+};
+
+static void rt5677_init_gpio(struct i2c_client *i2c)
+{
+ struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c);
+ int ret;
+
+ rt5677->gpio_chip = rt5677_template_chip;
+ rt5677->gpio_chip.ngpio = RT5677_GPIO_NUM;
+ rt5677->gpio_chip.dev = &i2c->dev;
+ rt5677->gpio_chip.base = -1;
+
+ ret = gpiochip_add(&rt5677->gpio_chip);
+ if (ret != 0)
+ dev_err(&i2c->dev, "Failed to add GPIOs: %d\n", ret);
+}
+
+static void rt5677_free_gpio(struct i2c_client *i2c)
+{
+ struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c);
+
+ gpiochip_remove(&rt5677->gpio_chip);
+}
+#else
+static void rt5677_init_gpio(struct i2c_client *i2c)
+{
+}
+
+static void rt5677_free_gpio(struct i2c_client *i2c)
+{
+}
+#endif
+
static int rt5677_probe(struct snd_soc_codec *codec)
{
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
rt5677->codec = codec;
+ if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) {
+ snd_soc_dapm_add_routes(&codec->dapm,
+ rt5677_dmic2_clk_2,
+ ARRAY_SIZE(rt5677_dmic2_clk_2));
+ } else { /*use dmic1 clock by default*/
+ snd_soc_dapm_add_routes(&codec->dapm,
+ rt5677_dmic2_clk_1,
+ ARRAY_SIZE(rt5677_dmic2_clk_1));
+ }
+
rt5677_set_bias_level(codec, SND_SOC_BIAS_OFF);
regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
@@ -3381,6 +3540,17 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
regmap_update_bits(rt5677->regmap, RT5677_IN1,
RT5677_IN_DF2, RT5677_IN_DF2);
+ if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) {
+ regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL2,
+ RT5677_GPIO5_FUNC_MASK,
+ RT5677_GPIO5_FUNC_DMIC);
+ regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL2,
+ RT5677_GPIO5_DIR_MASK,
+ RT5677_GPIO5_DIR_OUT);
+ }
+
+ rt5677_init_gpio(i2c);
+
return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677,
rt5677_dai, ARRAY_SIZE(rt5677_dai));
}
@@ -3388,6 +3558,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
static int rt5677_i2c_remove(struct i2c_client *i2c)
{
snd_soc_unregister_codec(&i2c->dev);
+ rt5677_free_gpio(i2c);
return 0;
}
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 863393e6209..b61b72cfcbd 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1287,16 +1287,16 @@
#define RT5677_PLL1_PD_SFT 8
#define RT5677_PLL1_PD_1 (0x0 << 8)
#define RT5677_PLL1_PD_2 (0x1 << 8)
-#define RT5671_DAC_OSR_MASK (0x3 << 6)
-#define RT5671_DAC_OSR_SFT 6
-#define RT5671_DAC_OSR_128 (0x0 << 6)
-#define RT5671_DAC_OSR_64 (0x1 << 6)
-#define RT5671_DAC_OSR_32 (0x2 << 6)
-#define RT5671_ADC_OSR_MASK (0x3 << 4)
-#define RT5671_ADC_OSR_SFT 4
-#define RT5671_ADC_OSR_128 (0x0 << 4)
-#define RT5671_ADC_OSR_64 (0x1 << 4)
-#define RT5671_ADC_OSR_32 (0x2 << 4)
+#define RT5677_DAC_OSR_MASK (0x3 << 6)
+#define RT5677_DAC_OSR_SFT 6
+#define RT5677_DAC_OSR_128 (0x0 << 6)
+#define RT5677_DAC_OSR_64 (0x1 << 6)
+#define RT5677_DAC_OSR_32 (0x2 << 6)
+#define RT5677_ADC_OSR_MASK (0x3 << 4)
+#define RT5677_ADC_OSR_SFT 4
+#define RT5677_ADC_OSR_128 (0x0 << 4)
+#define RT5677_ADC_OSR_64 (0x1 << 4)
+#define RT5677_ADC_OSR_32 (0x2 << 4)
/* Global Clock Control 2 (0x81) */
#define RT5677_PLL2_PR_SRC_MASK (0x1 << 15)
@@ -1312,18 +1312,18 @@
#define RT5677_PLL2_SRC_BCLK4 (0x4 << 12)
#define RT5677_PLL2_SRC_RCCLK (0x5 << 12)
#define RT5677_PLL2_SRC_SLIM (0x6 << 12)
-#define RT5671_DSP_ASRC_O_SRC (0x3 << 10)
-#define RT5671_DSP_ASRC_O_SRC_SFT 10
-#define RT5671_DSP_ASRC_O_MCLK (0x0 << 10)
-#define RT5671_DSP_ASRC_O_PLL1 (0x1 << 10)
-#define RT5671_DSP_ASRC_O_SLIM (0x2 << 10)
-#define RT5671_DSP_ASRC_O_RCCLK (0x3 << 10)
-#define RT5671_DSP_ASRC_I_SRC (0x3 << 8)
-#define RT5671_DSP_ASRC_I_SRC_SFT 8
-#define RT5671_DSP_ASRC_I_MCLK (0x0 << 8)
-#define RT5671_DSP_ASRC_I_PLL1 (0x1 << 8)
-#define RT5671_DSP_ASRC_I_SLIM (0x2 << 8)
-#define RT5671_DSP_ASRC_I_RCCLK (0x3 << 8)
+#define RT5677_DSP_ASRC_O_SRC (0x3 << 10)
+#define RT5677_DSP_ASRC_O_SRC_SFT 10
+#define RT5677_DSP_ASRC_O_MCLK (0x0 << 10)
+#define RT5677_DSP_ASRC_O_PLL1 (0x1 << 10)
+#define RT5677_DSP_ASRC_O_SLIM (0x2 << 10)
+#define RT5677_DSP_ASRC_O_RCCLK (0x3 << 10)
+#define RT5677_DSP_ASRC_I_SRC (0x3 << 8)
+#define RT5677_DSP_ASRC_I_SRC_SFT 8
+#define RT5677_DSP_ASRC_I_MCLK (0x0 << 8)
+#define RT5677_DSP_ASRC_I_PLL1 (0x1 << 8)
+#define RT5677_DSP_ASRC_I_SLIM (0x2 << 8)
+#define RT5677_DSP_ASRC_I_RCCLK (0x3 << 8)
#define RT5677_DSP_CLK_SRC_MASK (0x1 << 7)
#define RT5677_DSP_CLK_SRC_SFT 7
#define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7)
@@ -1363,6 +1363,110 @@
#define RT5677_SEL_SRC_IB01 (0x1 << 0)
#define RT5677_SEL_SRC_IB01_SFT 0
+/* GPIO status (0xbf) */
+#define RT5677_GPIO6_STATUS_MASK (0x1 << 5)
+#define RT5677_GPIO6_STATUS_SFT 5
+#define RT5677_GPIO5_STATUS_MASK (0x1 << 4)
+#define RT5677_GPIO5_STATUS_SFT 4
+#define RT5677_GPIO4_STATUS_MASK (0x1 << 3)
+#define RT5677_GPIO4_STATUS_SFT 3
+#define RT5677_GPIO3_STATUS_MASK (0x1 << 2)
+#define RT5677_GPIO3_STATUS_SFT 2
+#define RT5677_GPIO2_STATUS_MASK (0x1 << 1)
+#define RT5677_GPIO2_STATUS_SFT 1
+#define RT5677_GPIO1_STATUS_MASK (0x1 << 0)
+#define RT5677_GPIO1_STATUS_SFT 0
+
+/* GPIO Control 1 (0xc0) */
+#define RT5677_GPIO1_PIN_MASK (0x1 << 15)
+#define RT5677_GPIO1_PIN_SFT 15
+#define RT5677_GPIO1_PIN_GPIO1 (0x0 << 15)
+#define RT5677_GPIO1_PIN_IRQ (0x1 << 15)
+#define RT5677_IPTV_MODE_MASK (0x1 << 14)
+#define RT5677_IPTV_MODE_SFT 14
+#define RT5677_IPTV_MODE_GPIO (0x0 << 14)
+#define RT5677_IPTV_MODE_IPTV (0x1 << 14)
+#define RT5677_FUNC_MODE_MASK (0x1 << 13)
+#define RT5677_FUNC_MODE_SFT 13
+#define RT5677_FUNC_MODE_DMIC_GPIO (0x0 << 13)
+#define RT5677_FUNC_MODE_JTAG (0x1 << 13)
+
+/* GPIO Control 2 (0xc1) */
+#define RT5677_GPIO5_DIR_MASK (0x1 << 14)
+#define RT5677_GPIO5_DIR_SFT 14
+#define RT5677_GPIO5_DIR_IN (0x0 << 14)
+#define RT5677_GPIO5_DIR_OUT (0x1 << 14)
+#define RT5677_GPIO5_OUT_MASK (0x1 << 13)
+#define RT5677_GPIO5_OUT_SFT 13
+#define RT5677_GPIO5_OUT_LO (0x0 << 13)
+#define RT5677_GPIO5_OUT_HI (0x1 << 13)
+#define RT5677_GPIO5_P_MASK (0x1 << 12)
+#define RT5677_GPIO5_P_SFT 12
+#define RT5677_GPIO5_P_NOR (0x0 << 12)
+#define RT5677_GPIO5_P_INV (0x1 << 12)
+#define RT5677_GPIO4_DIR_MASK (0x1 << 11)
+#define RT5677_GPIO4_DIR_SFT 11
+#define RT5677_GPIO4_DIR_IN (0x0 << 11)
+#define RT5677_GPIO4_DIR_OUT (0x1 << 11)
+#define RT5677_GPIO4_OUT_MASK (0x1 << 10)
+#define RT5677_GPIO4_OUT_SFT 10
+#define RT5677_GPIO4_OUT_LO (0x0 << 10)
+#define RT5677_GPIO4_OUT_HI (0x1 << 10)
+#define RT5677_GPIO4_P_MASK (0x1 << 9)
+#define RT5677_GPIO4_P_SFT 9
+#define RT5677_GPIO4_P_NOR (0x0 << 9)
+#define RT5677_GPIO4_P_INV (0x1 << 9)
+#define RT5677_GPIO3_DIR_MASK (0x1 << 8)
+#define RT5677_GPIO3_DIR_SFT 8
+#define RT5677_GPIO3_DIR_IN (0x0 << 8)
+#define RT5677_GPIO3_DIR_OUT (0x1 << 8)
+#define RT5677_GPIO3_OUT_MASK (0x1 << 7)
+#define RT5677_GPIO3_OUT_SFT 7
+#define RT5677_GPIO3_OUT_LO (0x0 << 7)
+#define RT5677_GPIO3_OUT_HI (0x1 << 7)
+#define RT5677_GPIO3_P_MASK (0x1 << 6)
+#define RT5677_GPIO3_P_SFT 6
+#define RT5677_GPIO3_P_NOR (0x0 << 6)
+#define RT5677_GPIO3_P_INV (0x1 << 6)
+#define RT5677_GPIO2_DIR_MASK (0x1 << 5)
+#define RT5677_GPIO2_DIR_SFT 5
+#define RT5677_GPIO2_DIR_IN (0x0 << 5)
+#define RT5677_GPIO2_DIR_OUT (0x1 << 5)
+#define RT5677_GPIO2_OUT_MASK (0x1 << 4)
+#define RT5677_GPIO2_OUT_SFT 4
+#define RT5677_GPIO2_OUT_LO (0x0 << 4)
+#define RT5677_GPIO2_OUT_HI (0x1 << 4)
+#define RT5677_GPIO2_P_MASK (0x1 << 3)
+#define RT5677_GPIO2_P_SFT 3
+#define RT5677_GPIO2_P_NOR (0x0 << 3)
+#define RT5677_GPIO2_P_INV (0x1 << 3)
+#define RT5677_GPIO1_DIR_MASK (0x1 << 2)
+#define RT5677_GPIO1_DIR_SFT 2
+#define RT5677_GPIO1_DIR_IN (0x0 << 2)
+#define RT5677_GPIO1_DIR_OUT (0x1 << 2)
+#define RT5677_GPIO1_OUT_MASK (0x1 << 1)
+#define RT5677_GPIO1_OUT_SFT 1
+#define RT5677_GPIO1_OUT_LO (0x0 << 1)
+#define RT5677_GPIO1_OUT_HI (0x1 << 1)
+#define RT5677_GPIO1_P_MASK (0x1 << 0)
+#define RT5677_GPIO1_P_SFT 0
+#define RT5677_GPIO1_P_NOR (0x0 << 0)
+#define RT5677_GPIO1_P_INV (0x1 << 0)
+
+/* GPIO Control 3 (0xc2) */
+#define RT5677_GPIO6_DIR_MASK (0x1 << 2)
+#define RT5677_GPIO6_DIR_SFT 2
+#define RT5677_GPIO6_DIR_IN (0x0 << 2)
+#define RT5677_GPIO6_DIR_OUT (0x1 << 2)
+#define RT5677_GPIO6_OUT_MASK (0x1 << 1)
+#define RT5677_GPIO6_OUT_SFT 1
+#define RT5677_GPIO6_OUT_LO (0x0 << 1)
+#define RT5677_GPIO6_OUT_HI (0x1 << 1)
+#define RT5677_GPIO6_P_MASK (0x1 << 0)
+#define RT5677_GPIO6_P_SFT 0
+#define RT5677_GPIO6_P_NOR (0x0 << 0)
+#define RT5677_GPIO6_P_INV (0x1 << 0)
+
/* Virtual DSP Mixer Control (0xf7 0xf8 0xf9) */
#define RT5677_DSP_IB_01_H (0x1 << 15)
#define RT5677_DSP_IB_01_H_SFT 15
@@ -1393,6 +1497,11 @@
#define RT5677_DSP_IB_9_L (0x1 << 1)
#define RT5677_DSP_IB_9_L_SFT 1
+/* General Control2 (0xfc)*/
+#define RT5677_GPIO5_FUNC_MASK (0x1 << 9)
+#define RT5677_GPIO5_FUNC_GPIO (0x0 << 9)
+#define RT5677_GPIO5_FUNC_DMIC (0x1 << 9)
+
/* System Clock Source */
enum {
RT5677_SCLK_S_MCLK,
@@ -1418,6 +1527,16 @@ enum {
RT5677_AIFS,
};
+enum {
+ RT5677_GPIO1,
+ RT5677_GPIO2,
+ RT5677_GPIO3,
+ RT5677_GPIO4,
+ RT5677_GPIO5,
+ RT5677_GPIO6,
+ RT5677_GPIO_NUM,
+};
+
struct rt5677_priv {
struct snd_soc_codec *codec;
struct rt5677_platform_data pdata;
@@ -1431,6 +1550,9 @@ struct rt5677_priv {
int pll_src;
int pll_in;
int pll_out;
+#ifdef CONFIG_GPIOLIB
+ struct gpio_chip gpio_chip;
+#endif
};
#endif /* __RT5677_H__ */
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index e8680bea5f8..67ea55adb30 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -646,17 +646,6 @@ static struct snd_soc_dai_driver ssm2518_dai = {
.ops = &ssm2518_dai_ops,
};
-static int ssm2518_probe(struct snd_soc_codec *codec)
-{
- return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
-static int ssm2518_remove(struct snd_soc_codec *codec)
-{
- ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
int source, unsigned int freq, int dir)
{
@@ -727,8 +716,6 @@ static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
}
static struct snd_soc_codec_driver ssm2518_codec_driver = {
- .probe = ssm2518_probe,
- .remove = ssm2518_remove,
.set_bias_level = ssm2518_set_bias_level,
.set_sysclk = ssm2518_set_sysclk,
.idle_bias_off = true,
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 4021cd43574..527de046354 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -502,18 +502,11 @@ static struct snd_soc_dai_driver ssm2602_dai = {
.symmetric_samplebits = 1,
};
-static int ssm2602_suspend(struct snd_soc_codec *codec)
-{
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
static int ssm2602_resume(struct snd_soc_codec *codec)
{
struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
regcache_sync(ssm2602->regmap);
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
@@ -586,27 +579,14 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec)
break;
}
- if (ret)
- return ret;
-
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
-/* remove everything here */
-static int ssm2602_remove(struct snd_soc_codec *codec)
-{
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
+ return ret;
}
static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
.probe = ssm260x_codec_probe,
- .remove = ssm2602_remove,
- .suspend = ssm2602_suspend,
.resume = ssm2602_resume,
.set_bias_level = ssm2602_set_bias_level,
+ .suspend_bias_off = true,
.controls = ssm260x_snd_controls,
.num_controls = ARRAY_SIZE(ssm260x_snd_controls),
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 64f179ee983..f2c416d16b6 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1222,20 +1222,6 @@ static struct snd_soc_dai_driver aic3x_dai = {
.symmetric_rates = 1,
};
-static int aic3x_suspend(struct snd_soc_codec *codec)
-{
- aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int aic3x_resume(struct snd_soc_codec *codec)
-{
- aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-
static void aic3x_mono_init(struct snd_soc_codec *codec)
{
/* DAC to Mono Line Out default volume and route to Output mixer */
@@ -1429,8 +1415,6 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
.idle_bias_off = true,
.probe = aic3x_probe,
.remove = aic3x_remove,
- .suspend = aic3x_suspend,
- .resume = aic3x_resume,
.controls = aic3x_snd_controls,
.num_controls = ARRAY_SIZE(aic3x_snd_controls),
.dapm_widgets = aic3x_dapm_widgets,
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 7bb0d36d4c5..a01ad629ed6 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2319,11 +2319,8 @@ static void wm5100_init_gpio(struct i2c_client *i2c)
static void wm5100_free_gpio(struct i2c_client *i2c)
{
struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
- int ret;
- ret = gpiochip_remove(&wm5100->gpio_chip);
- if (ret != 0)
- dev_err(&i2c->dev, "Failed to remove GPIOs: %d\n", ret);
+ gpiochip_remove(&wm5100->gpio_chip);
}
#else
static void wm5100_init_gpio(struct i2c_client *i2c)
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 0ea01dfcb6e..3addc5fe5cb 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -518,23 +518,6 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-#ifdef CONFIG_PM
-static int wm8804_suspend(struct snd_soc_codec *codec)
-{
- wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8804_resume(struct snd_soc_codec *codec)
-{
- wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8804_suspend NULL
-#define wm8804_resume NULL
-#endif
-
static int wm8804_remove(struct snd_soc_codec *codec)
{
struct wm8804_priv *wm8804;
@@ -671,8 +654,6 @@ static struct snd_soc_dai_driver wm8804_dai = {
static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
.probe = wm8804_probe,
.remove = wm8804_remove,
- .suspend = wm8804_suspend,
- .resume = wm8804_resume,
.set_bias_level = wm8804_set_bias_level,
.idle_bias_off = true,
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index aa0984864e7..c038b3e0439 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1877,11 +1877,7 @@ static void wm8903_init_gpio(struct wm8903_priv *wm8903)
static void wm8903_free_gpio(struct wm8903_priv *wm8903)
{
- int ret;
-
- ret = gpiochip_remove(&wm8903->gpio_chip);
- if (ret != 0)
- dev_err(wm8903->dev, "Failed to remove GPIOs: %d\n", ret);
+ gpiochip_remove(&wm8903->gpio_chip);
}
#else
static void wm8903_init_gpio(struct wm8903_priv *wm8903)
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 1098ae32f1f..9077411e62c 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3398,11 +3398,8 @@ static void wm8962_init_gpio(struct snd_soc_codec *codec)
static void wm8962_free_gpio(struct snd_soc_codec *codec)
{
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
- int ret;
- ret = gpiochip_remove(&wm8962->gpio_chip);
- if (ret != 0)
- dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
+ gpiochip_remove(&wm8962->gpio_chip);
}
#else
static void wm8962_init_gpio(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index cae4ac5a573..1288edeb8c7 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -1998,23 +1998,6 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-#ifdef CONFIG_PM
-static int wm8995_suspend(struct snd_soc_codec *codec)
-{
- wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
-static int wm8995_resume(struct snd_soc_codec *codec)
-{
- wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- return 0;
-}
-#else
-#define wm8995_suspend NULL
-#define wm8995_resume NULL
-#endif
-
static int wm8995_remove(struct snd_soc_codec *codec)
{
struct wm8995_priv *wm8995;
@@ -2220,8 +2203,6 @@ static struct snd_soc_dai_driver wm8995_dai[] = {
static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
.probe = wm8995_probe,
.remove = wm8995_remove,
- .suspend = wm8995_suspend,
- .resume = wm8995_resume,
.set_bias_level = wm8995_set_bias_level,
.idle_bias_off = true,
};
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index f16ff4f5692..b1dcc11c1b2 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2216,11 +2216,7 @@ static void wm8996_init_gpio(struct wm8996_priv *wm8996)
static void wm8996_free_gpio(struct wm8996_priv *wm8996)
{
- int ret;
-
- ret = gpiochip_remove(&wm8996->gpio_chip);
- if (ret != 0)
- dev_err(wm8996->dev, "Failed to remove GPIOs: %d\n", ret);
+ gpiochip_remove(&wm8996->gpio_chip);
}
#else
static void wm8996_init_gpio(struct wm8996_priv *wm8996)