Commit 85488037 authored by Mark Brown's avatar Mark Brown

ASoC: Add source argument to PLL configuration

More and more devices feature PLLs and FLLs with the ability to select
between multiple input clocks. In order to better support these devices
a new argument, source, has been added to the set_pll() configuration
API. Using set_clkdiv() is often difficult due to the need to stop the
PLL/FLL before any reconfiguration can be done.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 367da152
...@@ -106,7 +106,7 @@ int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, ...@@ -106,7 +106,7 @@ int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
int div_id, int div); int div_id, int div);
int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
int pll_id, unsigned int freq_in, unsigned int freq_out); int pll_id, int source, unsigned int freq_in, unsigned int freq_out);
/* Digital Audio interface formatting */ /* Digital Audio interface formatting */
int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt); int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
...@@ -136,8 +136,8 @@ struct snd_soc_dai_ops { ...@@ -136,8 +136,8 @@ struct snd_soc_dai_ops {
*/ */
int (*set_sysclk)(struct snd_soc_dai *dai, int (*set_sysclk)(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir); int clk_id, unsigned int freq, int dir);
int (*set_pll)(struct snd_soc_dai *dai, int (*set_pll)(struct snd_soc_dai *dai, int pll_id, int source,
int pll_id, unsigned int freq_in, unsigned int freq_out); unsigned int freq_in, unsigned int freq_out);
int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div); int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
/* /*
......
...@@ -268,7 +268,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, ...@@ -268,7 +268,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
ret = snd_soc_dai_set_pll(codec_dai, 0, ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
clk_get_rate(CODEC_CLK), pll_out); clk_get_rate(CODEC_CLK), pll_out);
if (ret < 0) { if (ret < 0) {
pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
......
...@@ -1101,7 +1101,7 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input, ...@@ -1101,7 +1101,7 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
} }
static int wm8350_set_fll(struct snd_soc_dai *codec_dai, static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
int pll_id, unsigned int freq_in, int pll_id, int source, unsigned int freq_in,
unsigned int freq_out) unsigned int freq_out)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
......
...@@ -1011,7 +1011,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors, ...@@ -1011,7 +1011,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
} }
static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in,
unsigned int freq_out)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
struct wm8400_priv *wm8400 = codec->private_data; struct wm8400_priv *wm8400 = codec->private_data;
......
...@@ -271,8 +271,8 @@ static void pll_factors(unsigned int target, unsigned int source) ...@@ -271,8 +271,8 @@ static void pll_factors(unsigned int target, unsigned int source)
pll_div.k = K; pll_div.k = K;
} }
static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
u16 reg; u16 reg;
......
...@@ -407,8 +407,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target, ...@@ -407,8 +407,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
return 0; return 0;
} }
static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
int offset; int offset;
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
......
...@@ -723,8 +723,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target, ...@@ -723,8 +723,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
pll_div->k = K; pll_div->k = K;
} }
static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
u16 reg, enable; u16 reg, enable;
int offset; int offset;
......
...@@ -814,8 +814,8 @@ static int wm8900_set_fll(struct snd_soc_codec *codec, ...@@ -814,8 +814,8 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
return 0; return 0;
} }
static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out); return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
} }
......
...@@ -536,8 +536,8 @@ static void pll_factors(unsigned int target, unsigned int source) ...@@ -536,8 +536,8 @@ static void pll_factors(unsigned int target, unsigned int source)
} }
/* Untested at the moment */ /* Untested at the moment */
static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
u16 reg; u16 reg;
......
...@@ -540,8 +540,8 @@ static int pll_factors(unsigned int source, unsigned int target, ...@@ -540,8 +540,8 @@ static int pll_factors(unsigned int source, unsigned int target,
return 0; return 0;
} }
static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
u16 reg; u16 reg;
......
...@@ -329,8 +329,8 @@ static void pll_factors(unsigned int target, unsigned int source) ...@@ -329,8 +329,8 @@ static void pll_factors(unsigned int target, unsigned int source)
pll_div.k = K; pll_div.k = K;
} }
static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
u16 reg; u16 reg;
......
...@@ -972,8 +972,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target, ...@@ -972,8 +972,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
pll_div->k = K; pll_div->k = K;
} }
static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
u16 reg; u16 reg;
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
......
...@@ -422,7 +422,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, ...@@ -422,7 +422,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
return 0; return 0;
} }
static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
unsigned int Fref, unsigned int Fout) unsigned int Fref, unsigned int Fout)
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
......
...@@ -800,8 +800,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec, ...@@ -800,8 +800,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
return 0; return 0;
} }
static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
return wm9713_set_pll(codec, pll_id, freq_in, freq_out); return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
......
...@@ -157,7 +157,7 @@ static int mx27vis_hifi_hw_params(struct snd_pcm_substream *substream, ...@@ -157,7 +157,7 @@ static int mx27vis_hifi_hw_params(struct snd_pcm_substream *substream,
/* codec PLL input is 25 MHz */ /* codec PLL input is 25 MHz */
ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, IGNORED_ARG,
25000000, pll_out); 25000000, pll_out);
if (ret < 0) { if (ret < 0) {
printk(KERN_ERR "Error when setting PLL input\n"); printk(KERN_ERR "Error when setting PLL input\n");
......
...@@ -213,7 +213,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, ...@@ -213,7 +213,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
/* set SSP audio pll clock */ /* set SSP audio pll clock */
ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, acps); ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, acps);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -305,8 +305,8 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, ...@@ -305,8 +305,8 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
/* /*
* Configure the PLL frequency pxa27x and (afaik - pxa320 only) * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
*/ */
static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
int pll_id, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct ssp_priv *priv = cpu_dai->private_data; struct ssp_priv *priv = cpu_dai->private_data;
struct ssp_device *ssp = priv->dev.ssp; struct ssp_device *ssp = priv->dev.ssp;
......
...@@ -74,7 +74,8 @@ static const struct snd_soc_dapm_route audio_map[] = { ...@@ -74,7 +74,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
static int zylonite_wm9713_init(struct snd_soc_codec *codec) static int zylonite_wm9713_init(struct snd_soc_codec *codec)
{ {
if (clk_pout) if (clk_pout)
snd_soc_dai_set_pll(&codec->dai[0], 0, clk_get_rate(pout), 0); snd_soc_dai_set_pll(&codec->dai[0], 0, 0,
clk_get_rate(pout), 0);
snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
ARRAY_SIZE(zylonite_dapm_widgets)); ARRAY_SIZE(zylonite_dapm_widgets));
...@@ -128,7 +129,7 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream, ...@@ -128,7 +129,7 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out); ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -119,7 +119,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream, ...@@ -119,7 +119,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
/* codec PLL input is PCLK/4 */ /* codec PLL input is PCLK/4 */
ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
iis_clkrate / 4, pll_out); iis_clkrate / 4, pll_out);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -137,7 +137,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, ...@@ -137,7 +137,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
/* codec PLL input is PCLK/4 */ /* codec PLL input is PCLK/4 */
ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
iis_clkrate / 4, pll_out); iis_clkrate / 4, pll_out);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -2197,16 +2197,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv); ...@@ -2197,16 +2197,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
* snd_soc_dai_set_pll - configure DAI PLL. * snd_soc_dai_set_pll - configure DAI PLL.
* @dai: DAI * @dai: DAI
* @pll_id: DAI specific PLL ID * @pll_id: DAI specific PLL ID
* @source: DAI specific source for the PLL
* @freq_in: PLL input clock frequency in Hz * @freq_in: PLL input clock frequency in Hz
* @freq_out: requested PLL output clock frequency in Hz * @freq_out: requested PLL output clock frequency in Hz
* *
* Configures and enables PLL to generate output clock based on input clock. * Configures and enables PLL to generate output clock based on input clock.
*/ */
int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
int pll_id, unsigned int freq_in, unsigned int freq_out) unsigned int freq_in, unsigned int freq_out)
{ {
if (dai->ops && dai->ops->set_pll) if (dai->ops && dai->ops->set_pll)
return dai->ops->set_pll(dai, pll_id, freq_in, freq_out); return dai->ops->set_pll(dai, pll_id, source,
freq_in, freq_out);
else else
return -EINVAL; return -EINVAL;
} }
......
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