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>
This commit is contained in:
Koro Chen 2015-07-17 11:33:12 +08:00 committed by Mark Brown
parent 5168c5476a
commit 9fc114c5d7
2 changed files with 58 additions and 29 deletions

View File

@ -21,6 +21,7 @@
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/regulator/consumer.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
@ -223,6 +224,38 @@ static const struct reg_default rt5645_reg[] = {
{ 0xff, 0x6308 }, { 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) static int rt5645_reset(struct snd_soc_codec *codec)
{ {
return snd_soc_write(codec, RT5645_RESET, 0); 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_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct rt5645_priv *rt5645; struct rt5645_priv *rt5645;
int ret; int ret, i;
unsigned int val; unsigned int val;
rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv),
@ -3248,6 +3281,24 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
return ret; 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); regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val);
switch (val) { switch (val) {
@ -3261,7 +3312,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
dev_err(&i2c->dev, dev_err(&i2c->dev,
"Device with ID register %#x is not rt5645 or rt5650\n", "Device with ID register %#x is not rt5645 or rt5650\n",
val); val);
return -ENODEV; ret = -ENODEV;
goto err_enable;
} }
if (rt5645->codec_type == CODEC_TYPE_RT5650) { if (rt5645->codec_type == CODEC_TYPE_RT5650) {
@ -3399,7 +3451,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
| IRQF_ONESHOT, "rt5645", rt5645); | IRQF_ONESHOT, "rt5645", rt5645);
if (ret) { if (ret) {
dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", 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: err_irq:
if (rt5645->i2c->irq) if (rt5645->i2c->irq)
free_irq(rt5645->i2c->irq, rt5645); free_irq(rt5645->i2c->irq, rt5645);
err_enable:
regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
return ret; return ret;
} }
@ -3426,6 +3480,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
cancel_delayed_work_sync(&rt5645->jack_detect_work); cancel_delayed_work_sync(&rt5645->jack_detect_work);
snd_soc_unregister_codec(&i2c->dev); snd_soc_unregister_codec(&i2c->dev);
regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
return 0; return 0;
} }

View File

@ -2177,32 +2177,6 @@ enum {
int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec, int rt5645_sel_asrc_clk_src(struct snd_soc_codec *codec,
unsigned int filter_mask, unsigned int clk_src); unsigned int filter_mask, unsigned int clk_src);
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;
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;
};
int rt5645_set_jack_detect(struct snd_soc_codec *codec, int rt5645_set_jack_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack, struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
struct snd_soc_jack *btn_jack); struct snd_soc_jack *btn_jack);