diff options
author | Daniel Mack <zonque@gmail.com> | 2012-10-04 09:08:41 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-10-14 22:24:47 -0400 |
commit | 5b66aa2d0cafd8093e0b8959d32e694c92390b8c (patch) | |
tree | 827af1cbbf3b20babe0d70b2015c770c929b2d7d /sound/soc | |
parent | 4ed8c9b737b61030d7b6ac71294d698de85b5b7e (diff) |
ASoC: McASP: make AHCLK direction configurable
Add a .set_sysclk function to pass the direction of the clock down to
the driver. Only enable AHCLKX in the PDIR register when the CPU is
driving the clock.
This also removes the modification of the AHCLKXE/AHCLKRE bits in the
hw_params callback, and users must set the desired configuration using
snd_soc_dai_set_sysclk(), which this patch also does for the only user
in mainline (davinci-evm).
Signed-off-by: Daniel Mack <zonque@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/davinci/davinci-evm.c | 5 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 26 |
2 files changed, 25 insertions, 6 deletions
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 6fac5af13298..d55e6477bff0 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
@@ -71,6 +71,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream, | |||
71 | if (ret < 0) | 71 | if (ret < 0) |
72 | return ret; | 72 | return ret; |
73 | 73 | ||
74 | /* set the CPU system clock */ | ||
75 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT); | ||
76 | if (ret < 0) | ||
77 | return ret; | ||
78 | |||
74 | return 0; | 79 | return 0; |
75 | } | 80 | } |
76 | 81 | ||
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 9b1920e25564..9f7c2e153ecd 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -486,8 +486,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
486 | mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); | 486 | mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); |
487 | mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); | 487 | mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); |
488 | 488 | ||
489 | mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, | 489 | mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, ACLKX | AFSX); |
490 | ACLKX | AHCLKX | AFSX); | ||
491 | break; | 490 | break; |
492 | case SND_SOC_DAIFMT_CBM_CFS: | 491 | case SND_SOC_DAIFMT_CBM_CFS: |
493 | /* codec is clock master and frame slave */ | 492 | /* codec is clock master and frame slave */ |
@@ -584,6 +583,24 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div | |||
584 | return 0; | 583 | return 0; |
585 | } | 584 | } |
586 | 585 | ||
586 | static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, | ||
587 | unsigned int freq, int dir) | ||
588 | { | ||
589 | struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); | ||
590 | |||
591 | if (dir == SND_SOC_CLOCK_OUT) { | ||
592 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); | ||
593 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | ||
594 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); | ||
595 | } else { | ||
596 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); | ||
597 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | ||
598 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); | ||
599 | } | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
587 | static int davinci_config_channel_size(struct davinci_audio_dev *dev, | 604 | static int davinci_config_channel_size(struct davinci_audio_dev *dev, |
588 | int channel_size) | 605 | int channel_size) |
589 | { | 606 | { |
@@ -739,8 +756,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
739 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 756 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
740 | /* bit stream is MSB first with no delay */ | 757 | /* bit stream is MSB first with no delay */ |
741 | /* DSP_B mode */ | 758 | /* DSP_B mode */ |
742 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, | ||
743 | AHCLKXE); | ||
744 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); | 759 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); |
745 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); | 760 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); |
746 | 761 | ||
@@ -756,8 +771,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
756 | /* bit stream is MSB first with no delay */ | 771 | /* bit stream is MSB first with no delay */ |
757 | /* DSP_B mode */ | 772 | /* DSP_B mode */ |
758 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); | 773 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); |
759 | mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, | ||
760 | AHCLKRE); | ||
761 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); | 774 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); |
762 | 775 | ||
763 | if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) | 776 | if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) |
@@ -911,6 +924,7 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | |||
911 | .hw_params = davinci_mcasp_hw_params, | 924 | .hw_params = davinci_mcasp_hw_params, |
912 | .set_fmt = davinci_mcasp_set_dai_fmt, | 925 | .set_fmt = davinci_mcasp_set_dai_fmt, |
913 | .set_clkdiv = davinci_mcasp_set_clkdiv, | 926 | .set_clkdiv = davinci_mcasp_set_clkdiv, |
927 | .set_sysclk = davinci_mcasp_set_sysclk, | ||
914 | }; | 928 | }; |
915 | 929 | ||
916 | #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ | 930 | #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ |