diff options
author | Nicolin Chen <b42378@freescale.com> | 2013-08-05 16:26:16 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2013-08-23 07:30:08 +0800 |
commit | 89c6977256c5caf9a3c24e762b38b54e2877287b (patch) | |
tree | 2b07fac32567b830642b62bb5b74c3b398984ab5 /sound | |
parent | a9a41814511215bf3a447f6fa12693b043bfc5a0 (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.c | 28 | ||||
-rw-r--r-- | sound/soc/fsl/imx-wm8962.c | 30 |
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; |