summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorNicolin Chen <b42378@freescale.com>2013-08-05 16:26:16 +0800
committerJason Liu <r64343@freescale.com>2013-08-23 07:30:08 +0800
commit89c6977256c5caf9a3c24e762b38b54e2877287b (patch)
tree2b07fac32567b830642b62bb5b74c3b398984ab5 /sound
parenta9a41814511215bf3a447f6fa12693b043bfc5a0 (diff)
ENGR00273838-8 ASoC: WM8962: Let codec driver enable/disable its MCLK
WM8962 needs its MCLK when powerup -- wm8962_resume(). Thus it's better to control the MCLK in codec driver. Thus remove the clock enable in machine dirver accordingly. Acked-by: Wang Shengjiu <b02247@freescale.com> Signed-off-by: Nicolin Chen <b42378@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm8962.c28
-rw-r--r--sound/soc/fsl/imx-wm8962.c30
2 files changed, 36 insertions, 22 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 4ed218a8ed84..02f0477c3800 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
+#include <linux/clk.h>
#include <linux/gcd.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
@@ -3608,6 +3609,15 @@ static int wm8962_set_pdata_from_of(struct i2c_client *i2c,
pdata->gpio_init[i] = 0x0;
}
+ pdata->codec_mclk = devm_clk_get(&i2c->dev, NULL);
+
+ /*
+ * If clk_get() failed, we assume that clock's enabled by default.
+ * Otherwise, we let driver prepare and control the clock source.
+ */
+ if (IS_ERR(pdata->codec_mclk))
+ pdata->codec_mclk = NULL;
+
return 0;
}
@@ -3639,6 +3649,9 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
return ret;
}
+ if (wm8962->pdata.codec_mclk)
+ clk_prepare(wm8962->pdata.codec_mclk);
+
for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
wm8962->supplies[i].supply = wm8962_supply_names[i];
@@ -3728,11 +3741,19 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
err:
+ if (wm8962->pdata.codec_mclk)
+ clk_unprepare(wm8962->pdata.codec_mclk);
+
return ret;
}
static int wm8962_i2c_remove(struct i2c_client *client)
{
+ struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
+
+ if (wm8962->pdata.codec_mclk)
+ clk_unprepare(wm8962->pdata.codec_mclk);
+
snd_soc_unregister_codec(&client->dev);
return 0;
}
@@ -3743,6 +3764,9 @@ static int wm8962_runtime_resume(struct device *dev)
struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
int ret;
+ if (wm8962->pdata.codec_mclk)
+ clk_enable(wm8962->pdata.codec_mclk);
+
ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
wm8962->supplies);
if (ret != 0) {
@@ -3802,6 +3826,10 @@ static int wm8962_runtime_suspend(struct device *dev)
regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
wm8962->supplies);
+ if (wm8962->pdata.codec_mclk)
+ clk_disable(wm8962->pdata.codec_mclk);
+
+
return 0;
}
#endif
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index f2840d39a31a..1644c6c12b81 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -33,7 +33,6 @@ struct imx_wm8962_data {
struct snd_soc_card card;
char codec_dai_name[DAI_NAME_SIZE];
char platform_name[DAI_NAME_SIZE];
- struct clk *codec_clk;
unsigned int clk_frequency;
};
@@ -185,6 +184,7 @@ static int imx_wm8962_probe(struct platform_device *pdev)
struct imx_priv *priv = &card_priv;
struct i2c_client *codec_dev;
struct imx_wm8962_data *data;
+ struct clk *codec_clk = NULL;
int int_port, ext_port;
int ret;
@@ -256,19 +256,14 @@ static int imx_wm8962_probe(struct platform_device *pdev)
goto fail;
}
- data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
- if (IS_ERR(data->codec_clk)) {
- ret = PTR_ERR(data->codec_clk);
+ codec_clk = devm_clk_get(&codec_dev->dev, NULL);
+ if (IS_ERR(codec_clk)) {
+ ret = PTR_ERR(codec_clk);
dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
goto fail;
}
- data->clk_frequency = clk_get_rate(data->codec_clk);
- ret = clk_prepare_enable(data->codec_clk);
- if (ret) {
- dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
- goto fail;
- }
+ data->clk_frequency = clk_get_rate(codec_clk);
data->dai.name = "HiFi";
data->dai.stream_name = "HiFi";
@@ -283,10 +278,10 @@ static int imx_wm8962_probe(struct platform_device *pdev)
data->card.dev = &pdev->dev;
ret = snd_soc_of_parse_card_name(&data->card, "model");
if (ret)
- goto clk_fail;
+ goto fail;
ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
if (ret)
- goto clk_fail;
+ goto fail;
data->card.num_links = 1;
data->card.dai_link = &data->dai;
data->card.dapm_widgets = imx_wm8962_dapm_widgets;
@@ -297,18 +292,11 @@ static int imx_wm8962_probe(struct platform_device *pdev)
ret = snd_soc_register_card(&data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
- goto clk_fail;
+ goto fail;
}
platform_set_drvdata(pdev, data);
- of_node_put(ssi_np);
- of_node_put(codec_np);
-
- return 0;
-clk_fail:
- if (!IS_ERR(data->codec_clk))
- clk_disable_unprepare(data->codec_clk);
fail:
if (ssi_np)
of_node_put(ssi_np);
@@ -322,8 +310,6 @@ static int imx_wm8962_remove(struct platform_device *pdev)
{
struct imx_wm8962_data *data = platform_get_drvdata(pdev);
- if (!IS_ERR(data->codec_clk))
- clk_disable_unprepare(data->codec_clk);
snd_soc_unregister_card(&data->card);
return 0;