Commit cdd8da8c authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Lee Jones

mfd: arizona: Add gating of external MCLKn clocks

This patch adds requesting of the clocks supplied on MCLK1, MCLK2 pins,
gating of the 32k clock is added to the arizona_clk32k_enable(),
arizona_clk32k_disable() helpers.

It's a temporary change until the CODEC's clock controller gets exposed
through the clk API and is helpful for board configurations where the
MCLK clocks are not provided by always on oscillators.
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 29b4817d
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h> #include <linux/gpio.h>
...@@ -49,7 +50,15 @@ int arizona_clk32k_enable(struct arizona *arizona) ...@@ -49,7 +50,15 @@ int arizona_clk32k_enable(struct arizona *arizona)
case ARIZONA_32KZ_MCLK1: case ARIZONA_32KZ_MCLK1:
ret = pm_runtime_get_sync(arizona->dev); ret = pm_runtime_get_sync(arizona->dev);
if (ret != 0) if (ret != 0)
goto out; goto err_ref;
ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
if (ret != 0)
goto err_pm;
break;
case ARIZONA_32KZ_MCLK2:
ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]);
if (ret != 0)
goto err_ref;
break; break;
} }
...@@ -58,7 +67,9 @@ int arizona_clk32k_enable(struct arizona *arizona) ...@@ -58,7 +67,9 @@ int arizona_clk32k_enable(struct arizona *arizona)
ARIZONA_CLK_32K_ENA); ARIZONA_CLK_32K_ENA);
} }
out: err_pm:
pm_runtime_put_sync(arizona->dev);
err_ref:
if (ret != 0) if (ret != 0)
arizona->clk32k_ref--; arizona->clk32k_ref--;
...@@ -83,6 +94,10 @@ int arizona_clk32k_disable(struct arizona *arizona) ...@@ -83,6 +94,10 @@ int arizona_clk32k_disable(struct arizona *arizona)
switch (arizona->pdata.clk32k_src) { switch (arizona->pdata.clk32k_src) {
case ARIZONA_32KZ_MCLK1: case ARIZONA_32KZ_MCLK1:
pm_runtime_put_sync(arizona->dev); pm_runtime_put_sync(arizona->dev);
clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK1]);
break;
case ARIZONA_32KZ_MCLK2:
clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK2]);
break; break;
} }
} }
...@@ -1000,6 +1015,7 @@ static const struct mfd_cell wm8998_devs[] = { ...@@ -1000,6 +1015,7 @@ static const struct mfd_cell wm8998_devs[] = {
int arizona_dev_init(struct arizona *arizona) int arizona_dev_init(struct arizona *arizona)
{ {
const char * const mclk_name[] = { "mclk1", "mclk2" };
struct device *dev = arizona->dev; struct device *dev = arizona->dev;
const char *type_name = NULL; const char *type_name = NULL;
unsigned int reg, val, mask; unsigned int reg, val, mask;
...@@ -1016,6 +1032,16 @@ int arizona_dev_init(struct arizona *arizona) ...@@ -1016,6 +1032,16 @@ int arizona_dev_init(struct arizona *arizona)
else else
arizona_of_get_core_pdata(arizona); arizona_of_get_core_pdata(arizona);
BUILD_BUG_ON(ARRAY_SIZE(arizona->mclk) != ARRAY_SIZE(mclk_name));
for (i = 0; i < ARRAY_SIZE(arizona->mclk); i++) {
arizona->mclk[i] = devm_clk_get(arizona->dev, mclk_name[i]);
if (IS_ERR(arizona->mclk[i])) {
dev_info(arizona->dev, "Failed to get %s: %ld\n",
mclk_name[i], PTR_ERR(arizona->mclk[i]));
arizona->mclk[i] = NULL;
}
}
regcache_cache_only(arizona->regmap, true); regcache_cache_only(arizona->regmap, true);
switch (arizona->type) { switch (arizona->type) {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#ifndef _WM_ARIZONA_CORE_H #ifndef _WM_ARIZONA_CORE_H
#define _WM_ARIZONA_CORE_H #define _WM_ARIZONA_CORE_H
#include <linux/clk.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/regmap.h> #include <linux/regmap.h>
...@@ -21,6 +22,12 @@ ...@@ -21,6 +22,12 @@
#define ARIZONA_MAX_CORE_SUPPLIES 2 #define ARIZONA_MAX_CORE_SUPPLIES 2
enum {
ARIZONA_MCLK1,
ARIZONA_MCLK2,
ARIZONA_NUM_MCLK
};
enum arizona_type { enum arizona_type {
WM5102 = 1, WM5102 = 1,
WM5110 = 2, WM5110 = 2,
...@@ -139,6 +146,8 @@ struct arizona { ...@@ -139,6 +146,8 @@ struct arizona {
struct mutex clk_lock; struct mutex clk_lock;
int clk32k_ref; int clk32k_ref;
struct clk *mclk[ARIZONA_NUM_MCLK];
bool ctrlif_error; bool ctrlif_error;
struct snd_soc_dapm_context *dapm; struct snd_soc_dapm_context *dapm;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment