summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt5645.c
diff options
context:
space:
mode:
authorKoro Chen <koro.chen@mediatek.com>2015-07-17 05:33:12 +0200
committerMark Brown <broonie@kernel.org>2015-07-17 13:16:01 +0200
commit9fc114c5d7af6cfb72a2d983e16b83161716d6d0 (patch)
tree55bfd76c1e3b512c6054492b4508f912d662d237 /sound/soc/codecs/rt5645.c
parentASoC: rt5645: Fix missing free_irq (diff)
downloadlinux-9fc114c5d7af6cfb72a2d983e16b83161716d6d0.tar.xz
linux-9fc114c5d7af6cfb72a2d983e16b83161716d6d0.zip
ASoC: rt5645: Add regulator support
This adds basic regulator support for rt5645. Signed-off-by: Koro Chen <koro.chen@mediatek.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/rt5645.c')
-rw-r--r--sound/soc/codecs/rt5645.c61
1 files changed, 58 insertions, 3 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 827e3bf82d29..5f5d8adf6f42 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -21,6 +21,7 @@
#include <linux/gpio/consumer.h>
#include <linux/acpi.h>
#include <linux/dmi.h>
+#include <linux/regulator/consumer.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -223,6 +224,38 @@ static const struct reg_default rt5645_reg[] = {
{ 0xff, 0x6308 },
};
+static const char *const rt5645_supply_names[] = {
+ "avdd",
+ "cpvdd",
+};
+
+struct rt5645_priv {
+ struct snd_soc_codec *codec;
+ struct rt5645_platform_data pdata;
+ struct regmap *regmap;
+ struct i2c_client *i2c;
+ struct gpio_desc *gpiod_hp_det;
+ struct snd_soc_jack *hp_jack;
+ struct snd_soc_jack *mic_jack;
+ struct snd_soc_jack *btn_jack;
+ struct delayed_work jack_detect_work;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
+
+ int codec_type;
+ int sysclk;
+ int sysclk_src;
+ int lrck[RT5645_AIFS];
+ int bclk[RT5645_AIFS];
+ int master[RT5645_AIFS];
+
+ int pll_src;
+ int pll_in;
+ int pll_out;
+
+ int jack_type;
+ bool en_button_func;
+};
+
static int rt5645_reset(struct snd_soc_codec *codec)
{
return snd_soc_write(codec, RT5645_RESET, 0);
@@ -3214,7 +3247,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
{
struct rt5645_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct rt5645_priv *rt5645;
- int ret;
+ int ret, i;
unsigned int val;
rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv),
@@ -3248,6 +3281,24 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
return ret;
}
+ for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
+ rt5645->supplies[i].supply = rt5645_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&i2c->dev,
+ ARRAY_SIZE(rt5645->supplies),
+ rt5645->supplies);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(rt5645->supplies),
+ rt5645->supplies);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val);
switch (val) {
@@ -3261,7 +3312,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
dev_err(&i2c->dev,
"Device with ID register %#x is not rt5645 or rt5650\n",
val);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_enable;
}
if (rt5645->codec_type == CODEC_TYPE_RT5650) {
@@ -3399,7 +3451,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
| IRQF_ONESHOT, "rt5645", rt5645);
if (ret) {
dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
- return ret;
+ goto err_enable;
}
}
@@ -3413,6 +3465,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
err_irq:
if (rt5645->i2c->irq)
free_irq(rt5645->i2c->irq, rt5645);
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
return ret;
}
@@ -3426,6 +3480,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
cancel_delayed_work_sync(&rt5645->jack_detect_work);
snd_soc_unregister_codec(&i2c->dev);
+ regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
return 0;
}