aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshish Chavan <ashish.chavan@kpitcummins.com>2012-04-17 08:34:06 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-17 09:43:48 -0400
commit570aa7bae5e72900d62915fc56783689d95c3fb3 (patch)
tree70903b1314877c7b38e1f45cfd62327bcae5da11
parent26e6781155482f17847a408e72721f63c7c71cc6 (diff)
ASoC: da7210: Add support for PLL and SRM
Current DA7210 driver does support PLL mode fully. It uses fixed value of input master clock and PLL mode is enabled and disabled based on the sampling frequency being used for playback or recording. It also doesn't support Sample Rate Measurement feature of DA7210 hardware. This patch adds full support for PLL and SRM. Basically following three modes of operation are possible for DA7210 hardware, (1) I2S SLAVE mode with PLL bypassed (2) I2S SLAVE mode with PLL enabled (3) I2S Master mode with PLL enabled This patch adds support for all three modes. Also, in case of SLAVE mode with PLL, it supports SRM (Sample Rate Measurement) feature of the chip. Actually this patch was submitted earlier and received some review comments, but after that the driver got update by other patches. Because of that, I am considering this as new patch and not versioning it based of previous patches. This version tries to take care of all review comments received for earlier submissions. Signed-off-by: Ashish Chavan <ashish.chavan@kpitcummins.com> Signed-off-by: David Dajun Chen <dchen@diasemi.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/da7210.c225
1 files changed, 187 insertions, 38 deletions
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 5dfdf6e7a39..65e666e630d 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -148,6 +148,7 @@
148#define DA7210_DAI_EN (1 << 7) 148#define DA7210_DAI_EN (1 << 7)
149 149
150/*PLL_DIV3 bit fields */ 150/*PLL_DIV3 bit fields */
151#define DA7210_PLL_DIV_L_MASK (0xF << 0)
151#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4) 152#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
152#define DA7210_PLL_BYP (1 << 6) 153#define DA7210_PLL_BYP (1 << 6)
153 154
@@ -164,12 +165,16 @@
164#define DA7210_PLL_FS_48000 (0xB << 0) 165#define DA7210_PLL_FS_48000 (0xB << 0)
165#define DA7210_PLL_FS_88200 (0xE << 0) 166#define DA7210_PLL_FS_88200 (0xE << 0)
166#define DA7210_PLL_FS_96000 (0xF << 0) 167#define DA7210_PLL_FS_96000 (0xF << 0)
168#define DA7210_MCLK_DET_EN (0x1 << 5)
169#define DA7210_MCLK_SRM_EN (0x1 << 6)
167#define DA7210_PLL_EN (0x1 << 7) 170#define DA7210_PLL_EN (0x1 << 7)
168 171
169/* SOFTMUTE bit fields */ 172/* SOFTMUTE bit fields */
170#define DA7210_RAMP_EN (1 << 6) 173#define DA7210_RAMP_EN (1 << 6)
171 174
172/* CONTROL bit fields */ 175/* CONTROL bit fields */
176#define DA7210_REG_EN (1 << 0)
177#define DA7210_BIAS_EN (1 << 2)
173#define DA7210_NOISE_SUP_EN (1 << 3) 178#define DA7210_NOISE_SUP_EN (1 << 3)
174 179
175/* IN_GAIN bit fields */ 180/* IN_GAIN bit fields */
@@ -208,6 +213,47 @@
208#define DA7210_OUT2_OUTMIX_L (1 << 6) 213#define DA7210_OUT2_OUTMIX_L (1 << 6)
209#define DA7210_OUT2_EN (1 << 7) 214#define DA7210_OUT2_EN (1 << 7)
210 215
216struct pll_div {
217 int fref;
218 int fout;
219 u8 div1;
220 u8 div2;
221 u8 div3;
222 u8 mode; /* 0 = slave, 1 = master */
223};
224
225/* PLL dividers table */
226static const struct pll_div da7210_pll_div[] = {
227 /* for MASTER mode, fs = 44.1Khz */
228 { 12000000, 2822400, 0xE8, 0x6C, 0x2, 1}, /* MCLK=12Mhz */
229 { 13000000, 2822400, 0xDF, 0x28, 0xC, 1}, /* MCLK=13Mhz */
230 { 13500000, 2822400, 0xDB, 0x0A, 0xD, 1}, /* MCLK=13.5Mhz */
231 { 14400000, 2822400, 0xD4, 0x5A, 0x2, 1}, /* MCLK=14.4Mhz */
232 { 19200000, 2822400, 0xBB, 0x43, 0x9, 1}, /* MCLK=19.2Mhz */
233 { 19680000, 2822400, 0xB9, 0x6D, 0xA, 1}, /* MCLK=19.68Mhz */
234 { 19800000, 2822400, 0xB8, 0xFB, 0xB, 1}, /* MCLK=19.8Mhz */
235 /* for MASTER mode, fs = 48Khz */
236 { 12000000, 3072000, 0xF3, 0x12, 0x7, 1}, /* MCLK=12Mhz */
237 { 13000000, 3072000, 0xE8, 0xFD, 0x5, 1}, /* MCLK=13Mhz */
238 { 13500000, 3072000, 0xE4, 0x82, 0x3, 1}, /* MCLK=13.5Mhz */
239 { 14400000, 3072000, 0xDD, 0x3A, 0x0, 1}, /* MCLK=14.4Mhz */
240 { 19200000, 3072000, 0xC1, 0xEB, 0x8, 1}, /* MCLK=19.2Mhz */
241 { 19680000, 3072000, 0xBF, 0xEC, 0x0, 1}, /* MCLK=19.68Mhz */
242 { 19800000, 3072000, 0xBF, 0x70, 0x0, 1}, /* MCLK=19.8Mhz */
243 /* for SLAVE mode with SRM */
244 { 12000000, 2822400, 0xED, 0xBF, 0x5, 0}, /* MCLK=12Mhz */
245 { 13000000, 2822400, 0xE4, 0x13, 0x0, 0}, /* MCLK=13Mhz */
246 { 13500000, 2822400, 0xDF, 0xC6, 0x8, 0}, /* MCLK=13.5Mhz */
247 { 14400000, 2822400, 0xD8, 0xCA, 0x1, 0}, /* MCLK=14.4Mhz */
248 { 19200000, 2822400, 0xBE, 0x97, 0x9, 0}, /* MCLK=19.2Mhz */
249 { 19680000, 2822400, 0xBC, 0xAC, 0xD, 0}, /* MCLK=19.68Mhz */
250 { 19800000, 2822400, 0xBC, 0x35, 0xE, 0}, /* MCLK=19.8Mhz */
251};
252
253enum clk_src {
254 DA7210_CLKSRC_MCLK
255};
256
211#define DA7210_VERSION "0.0.1" 257#define DA7210_VERSION "0.0.1"
212 258
213/* 259/*
@@ -630,6 +676,8 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = {
630/* Codec private data */ 676/* Codec private data */
631struct da7210_priv { 677struct da7210_priv {
632 struct regmap *regmap; 678 struct regmap *regmap;
679 unsigned int mclk_rate;
680 int master;
633}; 681};
634 682
635static struct reg_default da7210_reg_defaults[] = { 683static struct reg_default da7210_reg_defaults[] = {
@@ -717,8 +765,9 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
717 struct snd_soc_dai *dai) 765 struct snd_soc_dai *dai)
718{ 766{
719 struct snd_soc_codec *codec = dai->codec; 767 struct snd_soc_codec *codec = dai->codec;
768 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
720 u32 dai_cfg1; 769 u32 dai_cfg1;
721 u32 fs, bypass; 770 u32 fs, sysclk;
722 771
723 /* set DAI source to Left and Right ADC */ 772 /* set DAI source to Left and Right ADC */
724 snd_soc_write(codec, DA7210_DAI_SRC_SEL, 773 snd_soc_write(codec, DA7210_DAI_SRC_SEL,
@@ -751,43 +800,43 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
751 switch (params_rate(params)) { 800 switch (params_rate(params)) {
752 case 8000: 801 case 8000:
753 fs = DA7210_PLL_FS_8000; 802 fs = DA7210_PLL_FS_8000;
754 bypass = DA7210_PLL_BYP; 803 sysclk = 3072000;
755 break; 804 break;
756 case 11025: 805 case 11025:
757 fs = DA7210_PLL_FS_11025; 806 fs = DA7210_PLL_FS_11025;
758 bypass = 0; 807 sysclk = 2822400;
759 break; 808 break;
760 case 12000: 809 case 12000:
761 fs = DA7210_PLL_FS_12000; 810 fs = DA7210_PLL_FS_12000;
762 bypass = DA7210_PLL_BYP; 811 sysclk = 3072000;
763 break; 812 break;
764 case 16000: 813 case 16000:
765 fs = DA7210_PLL_FS_16000; 814 fs = DA7210_PLL_FS_16000;
766 bypass = DA7210_PLL_BYP; 815 sysclk = 3072000;
767 break; 816 break;
768 case 22050: 817 case 22050:
769 fs = DA7210_PLL_FS_22050; 818 fs = DA7210_PLL_FS_22050;
770 bypass = 0; 819 sysclk = 2822400;
771 break; 820 break;
772 case 32000: 821 case 32000:
773 fs = DA7210_PLL_FS_32000; 822 fs = DA7210_PLL_FS_32000;
774 bypass = DA7210_PLL_BYP; 823 sysclk = 3072000;
775 break; 824 break;
776 case 44100: 825 case 44100:
777 fs = DA7210_PLL_FS_44100; 826 fs = DA7210_PLL_FS_44100;
778 bypass = 0; 827 sysclk = 2822400;
779 break; 828 break;
780 case 48000: 829 case 48000:
781 fs = DA7210_PLL_FS_48000; 830 fs = DA7210_PLL_FS_48000;
782 bypass = DA7210_PLL_BYP; 831 sysclk = 3072000;
783 break; 832 break;
784 case 88200: 833 case 88200:
785 fs = DA7210_PLL_FS_88200; 834 fs = DA7210_PLL_FS_88200;
786 bypass = 0; 835 sysclk = 2822400;
787 break; 836 break;
788 case 96000: 837 case 96000:
789 fs = DA7210_PLL_FS_96000; 838 fs = DA7210_PLL_FS_96000;
790 bypass = DA7210_PLL_BYP; 839 sysclk = 3072000;
791 break; 840 break;
792 default: 841 default:
793 return -EINVAL; 842 return -EINVAL;
@@ -797,8 +846,15 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
797 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0); 846 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
798 847
799 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs); 848 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
800 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
801 849
850 if (da7210->mclk_rate && (da7210->mclk_rate != sysclk)) {
851 /* PLL mode, disable PLL bypass */
852 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, 0);
853 } else {
854 /* PLL bypass mode, enable PLL bypass */
855 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP,
856 DA7210_PLL_BYP);
857 }
802 /* Enable active mode */ 858 /* Enable active mode */
803 snd_soc_update_bits(codec, DA7210_STARTUP1, 859 snd_soc_update_bits(codec, DA7210_STARTUP1,
804 DA7210_SC_MST_EN, DA7210_SC_MST_EN); 860 DA7210_SC_MST_EN, DA7210_SC_MST_EN);
@@ -812,17 +868,24 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
812static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) 868static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
813{ 869{
814 struct snd_soc_codec *codec = codec_dai->codec; 870 struct snd_soc_codec *codec = codec_dai->codec;
871 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
815 u32 dai_cfg1; 872 u32 dai_cfg1;
816 u32 dai_cfg3; 873 u32 dai_cfg3;
817 874
818 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1); 875 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
819 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3); 876 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
820 877
878 if ((snd_soc_read(codec, DA7210_PLL) & DA7210_PLL_EN) &&
879 (!(snd_soc_read(codec, DA7210_PLL_DIV3) & DA7210_PLL_BYP)))
880 return -EINVAL;
881
821 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 882 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
822 case SND_SOC_DAIFMT_CBM_CFM: 883 case SND_SOC_DAIFMT_CBM_CFM:
884 da7210->master = 1;
823 dai_cfg1 |= DA7210_DAI_MODE_MASTER; 885 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
824 break; 886 break;
825 case SND_SOC_DAIFMT_CBS_CFS: 887 case SND_SOC_DAIFMT_CBS_CFS:
888 da7210->master = 0;
826 dai_cfg1 |= DA7210_DAI_MODE_SLAVE; 889 dai_cfg1 |= DA7210_DAI_MODE_SLAVE;
827 break; 890 break;
828 default: 891 default:
@@ -874,10 +937,114 @@ static int da7210_mute(struct snd_soc_dai *dai, int mute)
874#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 937#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
875 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 938 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
876 939
940static int da7210_set_dai_sysclk(struct snd_soc_dai *codec_dai,
941 int clk_id, unsigned int freq, int dir)
942{
943 struct snd_soc_codec *codec = codec_dai->codec;
944 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
945
946 switch (clk_id) {
947 case DA7210_CLKSRC_MCLK:
948 switch (freq) {
949 case 12000000:
950 case 13000000:
951 case 13500000:
952 case 14400000:
953 case 19200000:
954 case 19680000:
955 case 19800000:
956 da7210->mclk_rate = freq;
957 return 0;
958 default:
959 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
960 freq);
961 return -EINVAL;
962 }
963 break;
964 default:
965 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
966 return -EINVAL;
967 }
968}
969
970/**
971 * da7210_set_dai_pll :Configure the codec PLL
972 * @param codec_dai : pointer to codec DAI
973 * @param pll_id : da7210 has only one pll, so pll_id is always zero
974 * @param fref : MCLK frequency, should be < 20MHz
975 * @param fout : FsDM value, Refer page 44 & 45 of datasheet
976 * @return int : Zero for success, negative error code for error
977 *
978 * Note: Supported PLL input frequencies are 12MHz, 13MHz, 13.5MHz, 14.4MHz,
979 * 19.2MHz, 19.6MHz and 19.8MHz
980 */
981static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
982 int source, unsigned int fref, unsigned int fout)
983{
984 struct snd_soc_codec *codec = codec_dai->codec;
985 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
986
987 u8 pll_div1, pll_div2, pll_div3, cnt;
988
989 /* In slave mode, there is only one set of divisors */
990 if (!da7210->master)
991 fout = 2822400;
992
993 /* Search pll div array for correct divisors */
994 for (cnt = 0; cnt < ARRAY_SIZE(da7210_pll_div); cnt++) {
995 /* check fref */
996 if (fref == da7210_pll_div[cnt].fref) {
997 /* check mode */
998 if (da7210->master == da7210_pll_div[cnt].mode) {
999 /* check fout */
1000 if (fout == da7210_pll_div[cnt].fout) {
1001 /* all match, pick up divisors */
1002 pll_div1 = da7210_pll_div[cnt].div1;
1003 pll_div2 = da7210_pll_div[cnt].div2;
1004 pll_div3 = da7210_pll_div[cnt].div3;
1005 break;
1006 }
1007 }
1008 }
1009 }
1010 if (cnt >= ARRAY_SIZE(da7210_pll_div))
1011 goto err;
1012
1013 /* Disable active mode */
1014 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
1015 /* Write PLL dividers */
1016 snd_soc_write(codec, DA7210_PLL_DIV1, pll_div1);
1017 snd_soc_write(codec, DA7210_PLL_DIV2, pll_div2);
1018 snd_soc_update_bits(codec, DA7210_PLL_DIV3,
1019 DA7210_PLL_DIV_L_MASK, pll_div3);
1020
1021 if (da7210->master) {
1022 /* In master mode, no need to enable SRM */
1023 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN,
1024 DA7210_PLL_EN);
1025 } else {
1026 /* In slave mode, enable SRM and PLL */
1027 snd_soc_update_bits(codec, DA7210_PLL,
1028 (DA7210_PLL_EN | DA7210_MCLK_SRM_EN |
1029 DA7210_MCLK_DET_EN),
1030 (DA7210_PLL_EN | DA7210_MCLK_SRM_EN |
1031 DA7210_MCLK_DET_EN));
1032 }
1033 /* Enable active mode */
1034 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN,
1035 DA7210_SC_MST_EN);
1036 return 0;
1037err:
1038 dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n", fref);
1039 return -EINVAL;
1040}
1041
877/* DAI operations */ 1042/* DAI operations */
878static const struct snd_soc_dai_ops da7210_dai_ops = { 1043static const struct snd_soc_dai_ops da7210_dai_ops = {
879 .hw_params = da7210_hw_params, 1044 .hw_params = da7210_hw_params,
880 .set_fmt = da7210_set_dai_fmt, 1045 .set_fmt = da7210_set_dai_fmt,
1046 .set_sysclk = da7210_set_dai_sysclk,
1047 .set_pll = da7210_set_dai_pll,
881 .digital_mute = da7210_mute, 1048 .digital_mute = da7210_mute,
882}; 1049};
883 1050
@@ -917,17 +1084,11 @@ static int da7210_probe(struct snd_soc_codec *codec)
917 return ret; 1084 return ret;
918 } 1085 }
919 1086
920 /* FIXME 1087 da7210->mclk_rate = 0; /* This will be set from set_sysclk() */
921 * 1088 da7210->master = 0; /* This will be set from set_fmt() */
922 * This driver use fixed value here 1089
923 * And below settings expects MCLK = 12.288MHz 1090 /* Enable internal regulator & bias current */
924 * 1091 snd_soc_write(codec, DA7210_CONTROL, DA7210_REG_EN | DA7210_BIAS_EN);
925 * When you select different MCLK, please check...
926 * DA7210_PLL_DIV1 val
927 * DA7210_PLL_DIV2 val
928 * DA7210_PLL_DIV3 val
929 * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
930 */
931 1092
932 /* 1093 /*
933 * ADC settings 1094 * ADC settings
@@ -1002,24 +1163,12 @@ static int da7210_probe(struct snd_soc_codec *codec)
1002 /* Enable Aux2 */ 1163 /* Enable Aux2 */
1003 snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN); 1164 snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN);
1004 1165
1166 /* Set PLL Master clock range 10-20 MHz */
1167 snd_soc_write(codec, DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ);
1168
1005 /* Diable PLL and bypass it */ 1169 /* Diable PLL and bypass it */
1006 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); 1170 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
1007 1171
1008 /*
1009 * If 48kHz sound came, it use bypass mode,
1010 * and when it is 44.1kHz, it use PLL.
1011 *
1012 * This time, this driver sets PLL always ON
1013 * and controls bypass/PLL mode by switching
1014 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
1015 * see da7210_hw_params
1016 */
1017 snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
1018 snd_soc_write(codec, DA7210_PLL_DIV2, 0x99);
1019 snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A |
1020 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
1021 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
1022
1023 /* Activate all enabled subsystem */ 1172 /* Activate all enabled subsystem */
1024 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 1173 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
1025 1174