Skip to content

Commit

Permalink
ASoC: ad193x: add set_sysclk entry to support different clock input
Browse files Browse the repository at this point in the history
Signed-off-by: Barry Song <21cnbao@gmail.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Barry Song authored and Mark Brown committed May 21, 2010
1 parent 669be07 commit fab90aa
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
41 changes: 40 additions & 1 deletion sound/soc/codecs/ad193x.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

/* codec private data */
struct ad193x_priv {
unsigned int sysclk;
struct snd_soc_codec codec;
u8 reg_cache[AD193X_NUM_REGS];
};
Expand Down Expand Up @@ -251,15 +252,32 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}

static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = codec_dai->codec;
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
switch (freq) {
case 12288000:
case 18432000:
case 24576000:
case 36864000:
ad193x->sysclk = freq;
return 0;
}
return -EINVAL;
}

static int ad193x_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
int word_len = 0, reg = 0;
int word_len = 0, reg = 0, master_rate = 0;

struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_device *socdev = rtd->socdev;
struct snd_soc_codec *codec = socdev->card->codec;
struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);

/* bit size */
switch (params_format(params)) {
Expand All @@ -275,6 +293,25 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
break;
}

switch (ad193x->sysclk) {
case 12288000:
master_rate = AD193X_PLL_INPUT_256;
break;
case 18432000:
master_rate = AD193X_PLL_INPUT_384;
break;
case 24576000:
master_rate = AD193X_PLL_INPUT_512;
break;
case 36864000:
master_rate = AD193X_PLL_INPUT_768;
break;
}

reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0);
reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate;
snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);

reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
Expand Down Expand Up @@ -348,6 +385,7 @@ static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
/* pll input: mclki/xi */
snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
ad193x->sysclk = 12288000;

ret = snd_soc_register_codec(codec);
if (ret != 0) {
Expand Down Expand Up @@ -383,6 +421,7 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
.hw_params = ad193x_hw_params,
.digital_mute = ad193x_mute,
.set_tdm_slot = ad193x_set_tdm_slot,
.set_sysclk = ad193x_set_dai_sysclk,
.set_fmt = ad193x_set_dai_fmt,
};

Expand Down
5 changes: 5 additions & 0 deletions sound/soc/codecs/ad193x.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

#define AD193X_PLL_CLK_CTRL0 0x800
#define AD193X_PLL_POWERDOWN 0x01
#define AD193X_PLL_INPUT_MASK (~0x6)
#define AD193X_PLL_INPUT_256 (0 << 1)
#define AD193X_PLL_INPUT_384 (1 << 1)
#define AD193X_PLL_INPUT_512 (2 << 1)
#define AD193X_PLL_INPUT_768 (3 << 1)
#define AD193X_PLL_CLK_CTRL1 0x801
#define AD193X_DAC_CTRL0 0x802
#define AD193X_DAC_POWERDOWN 0x01
Expand Down

0 comments on commit fab90aa

Please sign in to comment.