aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolin Chen <b42378@freescale.com>2013-08-05 04:26:16 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:01:02 -0400
commit007d3504914096760124f2ef13d52da206341a66 (patch)
tree90f6ed82c55fbe33cecfe427001e491501c75a43
parent8db9a2f44a5eecd02be2259a3783178a521ef2d2 (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>
-rw-r--r--include/sound/wm8962.h3
-rw-r--r--sound/soc/codecs/wm8962.c28
-rw-r--r--sound/soc/fsl/imx-wm8962.c30
3 files changed, 39 insertions, 22 deletions
diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h
index 79e6d427b858..fb261851da21 100644
--- a/include/sound/wm8962.h
+++ b/include/sound/wm8962.h
@@ -55,6 +55,9 @@ struct wm8962_pdata {
55 * in a DC measurement configuration. 55 * in a DC measurement configuration.
56 */ 56 */
57 bool in4_dc_measure; 57 bool in4_dc_measure;
58
59 /* MCLK for wm8962 */
60 struct clk *codec_mclk;
58}; 61};
59 62
60#endif 63#endif
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index d2e4a3ca44f9..6150875e08fd 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/clk.h>
19#include <linux/gcd.h> 20#include <linux/gcd.h>
20#include <linux/gpio.h> 21#include <linux/gpio.h>
21#include <linux/i2c.h> 22#include <linux/i2c.h>
@@ -3608,6 +3609,15 @@ static int wm8962_set_pdata_from_of(struct i2c_client *i2c,
3608 pdata->gpio_init[i] = 0x0; 3609 pdata->gpio_init[i] = 0x0;
3609 } 3610 }
3610 3611
3612 pdata->codec_mclk = devm_clk_get(&i2c->dev, NULL);
3613
3614 /*
3615 * If clk_get() failed, we assume that clock's enabled by default.
3616 * Otherwise, we let driver prepare and control the clock source.
3617 */
3618 if (IS_ERR(pdata->codec_mclk))
3619 pdata->codec_mclk = NULL;
3620
3611 return 0; 3621 return 0;
3612} 3622}
3613 3623
@@ -3639,6 +3649,9 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3639 return ret; 3649 return ret;
3640 } 3650 }
3641 3651
3652 if (wm8962->pdata.codec_mclk)
3653 clk_prepare(wm8962->pdata.codec_mclk);
3654
3642 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) 3655 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
3643 wm8962->supplies[i].supply = wm8962_supply_names[i]; 3656 wm8962->supplies[i].supply = wm8962_supply_names[i];
3644 3657
@@ -3730,11 +3743,19 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3730err_enable: 3743err_enable:
3731 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); 3744 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
3732err: 3745err:
3746 if (wm8962->pdata.codec_mclk)
3747 clk_unprepare(wm8962->pdata.codec_mclk);
3748
3733 return ret; 3749 return ret;
3734} 3750}
3735 3751
3736static int wm8962_i2c_remove(struct i2c_client *client) 3752static int wm8962_i2c_remove(struct i2c_client *client)
3737{ 3753{
3754 struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
3755
3756 if (wm8962->pdata.codec_mclk)
3757 clk_unprepare(wm8962->pdata.codec_mclk);
3758
3738 snd_soc_unregister_codec(&client->dev); 3759 snd_soc_unregister_codec(&client->dev);
3739 return 0; 3760 return 0;
3740} 3761}
@@ -3745,6 +3766,9 @@ static int wm8962_runtime_resume(struct device *dev)
3745 struct wm8962_priv *wm8962 = dev_get_drvdata(dev); 3766 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3746 int ret; 3767 int ret;
3747 3768
3769 if (wm8962->pdata.codec_mclk)
3770 clk_enable(wm8962->pdata.codec_mclk);
3771
3748 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), 3772 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
3749 wm8962->supplies); 3773 wm8962->supplies);
3750 if (ret != 0) { 3774 if (ret != 0) {
@@ -3804,6 +3828,10 @@ static int wm8962_runtime_suspend(struct device *dev)
3804 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), 3828 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
3805 wm8962->supplies); 3829 wm8962->supplies);
3806 3830
3831 if (wm8962->pdata.codec_mclk)
3832 clk_disable(wm8962->pdata.codec_mclk);
3833
3834
3807 return 0; 3835 return 0;
3808} 3836}
3809#endif 3837#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 {
33 struct snd_soc_card card; 33 struct snd_soc_card card;
34 char codec_dai_name[DAI_NAME_SIZE]; 34 char codec_dai_name[DAI_NAME_SIZE];
35 char platform_name[DAI_NAME_SIZE]; 35 char platform_name[DAI_NAME_SIZE];
36 struct clk *codec_clk;
37 unsigned int clk_frequency; 36 unsigned int clk_frequency;
38}; 37};
39 38
@@ -185,6 +184,7 @@ static int imx_wm8962_probe(struct platform_device *pdev)
185 struct imx_priv *priv = &card_priv; 184 struct imx_priv *priv = &card_priv;
186 struct i2c_client *codec_dev; 185 struct i2c_client *codec_dev;
187 struct imx_wm8962_data *data; 186 struct imx_wm8962_data *data;
187 struct clk *codec_clk = NULL;
188 int int_port, ext_port; 188 int int_port, ext_port;
189 int ret; 189 int ret;
190 190
@@ -256,19 +256,14 @@ static int imx_wm8962_probe(struct platform_device *pdev)
256 goto fail; 256 goto fail;
257 } 257 }
258 258
259 data->codec_clk = devm_clk_get(&codec_dev->dev, NULL); 259 codec_clk = devm_clk_get(&codec_dev->dev, NULL);
260 if (IS_ERR(data->codec_clk)) { 260 if (IS_ERR(codec_clk)) {
261 ret = PTR_ERR(data->codec_clk); 261 ret = PTR_ERR(codec_clk);
262 dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret); 262 dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
263 goto fail; 263 goto fail;
264 } 264 }
265 265
266 data->clk_frequency = clk_get_rate(data->codec_clk); 266 data->clk_frequency = clk_get_rate(codec_clk);
267 ret = clk_prepare_enable(data->codec_clk);
268 if (ret) {
269 dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
270 goto fail;
271 }
272 267
273 data->dai.name = "HiFi"; 268 data->dai.name = "HiFi";
274 data->dai.stream_name = "HiFi"; 269 data->dai.stream_name = "HiFi";
@@ -283,10 +278,10 @@ static int imx_wm8962_probe(struct platform_device *pdev)
283 data->card.dev = &pdev->dev; 278 data->card.dev = &pdev->dev;
284 ret = snd_soc_of_parse_card_name(&data->card, "model"); 279 ret = snd_soc_of_parse_card_name(&data->card, "model");
285 if (ret) 280 if (ret)
286 goto clk_fail; 281 goto fail;
287 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing"); 282 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
288 if (ret) 283 if (ret)
289 goto clk_fail; 284 goto fail;
290 data->card.num_links = 1; 285 data->card.num_links = 1;
291 data->card.dai_link = &data->dai; 286 data->card.dai_link = &data->dai;
292 data->card.dapm_widgets = imx_wm8962_dapm_widgets; 287 data->card.dapm_widgets = imx_wm8962_dapm_widgets;
@@ -297,18 +292,11 @@ static int imx_wm8962_probe(struct platform_device *pdev)
297 ret = snd_soc_register_card(&data->card); 292 ret = snd_soc_register_card(&data->card);
298 if (ret) { 293 if (ret) {
299 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 294 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
300 goto clk_fail; 295 goto fail;
301 } 296 }
302 297
303 platform_set_drvdata(pdev, data); 298 platform_set_drvdata(pdev, data);
304 of_node_put(ssi_np);
305 of_node_put(codec_np);
306
307 return 0;
308 299
309clk_fail:
310 if (!IS_ERR(data->codec_clk))
311 clk_disable_unprepare(data->codec_clk);
312fail: 300fail:
313 if (ssi_np) 301 if (ssi_np)
314 of_node_put(ssi_np); 302 of_node_put(ssi_np);
@@ -322,8 +310,6 @@ static int imx_wm8962_remove(struct platform_device *pdev)
322{ 310{
323 struct imx_wm8962_data *data = platform_get_drvdata(pdev); 311 struct imx_wm8962_data *data = platform_get_drvdata(pdev);
324 312
325 if (!IS_ERR(data->codec_clk))
326 clk_disable_unprepare(data->codec_clk);
327 snd_soc_unregister_card(&data->card); 313 snd_soc_unregister_card(&data->card);
328 314
329 return 0; 315 return 0;