diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h index 79e6d427b858..0af7c1674cbf 100644 --- a/include/sound/wm8962.h +++ b/include/sound/wm8962.h @@ -37,6 +37,7 @@ #define WM8962_GPIO_FN_MICSCD 22 struct wm8962_pdata { + struct clk *mclk; int gpio_base; u32 gpio_init[WM8962_MAX_GPIO]; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index ca2fda9d72be..eac29031ae26 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -3541,6 +3542,8 @@ static int wm8962_set_pdata_from_of(struct i2c_client *i2c, pdata->gpio_init[i] = 0x0; } + pdata->mclk = devm_clk_get(&i2c->dev, NULL); + return 0; } @@ -3572,6 +3575,14 @@ static int wm8962_i2c_probe(struct i2c_client *i2c, return ret; } + /* Mark the mclk pointer to NULL if no mclk assigned */ + if (IS_ERR(wm8962->pdata.mclk)) { + /* But do not ignore the request for probe defer */ + if (PTR_ERR(wm8962->pdata.mclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + wm8962->pdata.mclk = NULL; + } + for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) wm8962->supplies[i].supply = wm8962_supply_names[i]; @@ -3780,6 +3791,12 @@ static int wm8962_runtime_resume(struct device *dev) struct wm8962_priv *wm8962 = dev_get_drvdata(dev); int ret; + ret = clk_prepare_enable(wm8962->pdata.mclk); + if (ret) { + dev_err(dev, "Failed to enable MCLK: %d\n", ret); + return ret; + } + ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); if (ret != 0) { @@ -3839,6 +3856,8 @@ static int wm8962_runtime_suspend(struct device *dev) regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); + clk_disable_unprepare(wm8962->pdata.mclk); + return 0; } #endif