aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorOder Chiou <oder_chiou@realtek.com>2015-03-16 02:39:57 -0400
committerMark Brown <broonie@kernel.org>2015-03-16 08:02:56 -0400
commitc36aa0a1929a1f0f0b8c374276e49cc663e8f957 (patch)
tree806f35c45bd10eef739b2f8c816c96f0b45b5eb8 /sound
parent05a25fd53e75ab893cb7b4a49f01994b877ded2c (diff)
ASoC: rt5677: add API to select ASRC clock source
This patch defines an API to select the clock source for specified filters. Signed-off-by: Oder Chiou <oder_chiou@realtek.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/rt5677.c163
-rw-r--r--sound/soc/codecs/rt5677.h79
2 files changed, 242 insertions, 0 deletions
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index c2a6e4091357..af182586712d 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -1034,6 +1034,169 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
1034 return 0; 1034 return 0;
1035} 1035}
1036 1036
1037/**
1038 * rt5677_sel_asrc_clk_src - select ASRC clock source for a set of filters
1039 * @codec: SoC audio codec device.
1040 * @filter_mask: mask of filters.
1041 * @clk_src: clock source
1042 *
1043 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5677 can
1044 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
1045 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
1046 * ASRC function will track i2s clock and generate a corresponding system clock
1047 * for codec. This function provides an API to select the clock source for a
1048 * set of filters specified by the mask. And the codec driver will turn on ASRC
1049 * for these filters if ASRC is selected as their clock source.
1050 */
1051int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
1052 unsigned int filter_mask, unsigned int clk_src)
1053{
1054 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int asrc3_mask = 0, asrc3_value = 0;
1056 unsigned int asrc4_mask = 0, asrc4_value = 0;
1057 unsigned int asrc5_mask = 0, asrc5_value = 0;
1058 unsigned int asrc6_mask = 0, asrc6_value = 0;
1059 unsigned int asrc7_mask = 0, asrc7_value = 0;
1060
1061 switch (clk_src) {
1062 case RT5677_CLK_SEL_SYS:
1063 case RT5677_CLK_SEL_I2S1_ASRC:
1064 case RT5677_CLK_SEL_I2S2_ASRC:
1065 case RT5677_CLK_SEL_I2S3_ASRC:
1066 case RT5677_CLK_SEL_I2S4_ASRC:
1067 case RT5677_CLK_SEL_I2S5_ASRC:
1068 case RT5677_CLK_SEL_I2S6_ASRC:
1069 case RT5677_CLK_SEL_SYS2:
1070 case RT5677_CLK_SEL_SYS3:
1071 case RT5677_CLK_SEL_SYS4:
1072 case RT5677_CLK_SEL_SYS5:
1073 case RT5677_CLK_SEL_SYS6:
1074 case RT5677_CLK_SEL_SYS7:
1075 break;
1076
1077 default:
1078 return -EINVAL;
1079 }
1080
1081 /* ASRC 3 */
1082 if (filter_mask & RT5677_DA_STEREO_FILTER) {
1083 asrc3_mask |= RT5677_DA_STO_CLK_SEL_MASK;
1084 asrc3_value = (asrc3_value & ~RT5677_DA_STO_CLK_SEL_MASK)
1085 | (clk_src << RT5677_DA_STO_CLK_SEL_SFT);
1086 }
1087
1088 if (filter_mask & RT5677_DA_MONO2_L_FILTER) {
1089 asrc3_mask |= RT5677_DA_MONO2L_CLK_SEL_MASK;
1090 asrc3_value = (asrc3_value & ~RT5677_DA_MONO2L_CLK_SEL_MASK)
1091 | (clk_src << RT5677_DA_MONO2L_CLK_SEL_SFT);
1092 }
1093
1094 if (filter_mask & RT5677_DA_MONO2_R_FILTER) {
1095 asrc3_mask |= RT5677_DA_MONO2R_CLK_SEL_MASK;
1096 asrc3_value = (asrc3_value & ~RT5677_DA_MONO2R_CLK_SEL_MASK)
1097 | (clk_src << RT5677_DA_MONO2R_CLK_SEL_SFT);
1098 }
1099
1100 if (asrc3_mask)
1101 regmap_update_bits(rt5677->regmap, RT5677_ASRC_3, asrc3_mask,
1102 asrc3_value);
1103
1104 /* ASRC 4 */
1105 if (filter_mask & RT5677_DA_MONO3_L_FILTER) {
1106 asrc4_mask |= RT5677_DA_MONO3L_CLK_SEL_MASK;
1107 asrc4_value = (asrc4_value & ~RT5677_DA_MONO3L_CLK_SEL_MASK)
1108 | (clk_src << RT5677_DA_MONO3L_CLK_SEL_SFT);
1109 }
1110
1111 if (filter_mask & RT5677_DA_MONO3_R_FILTER) {
1112 asrc4_mask |= RT5677_DA_MONO3R_CLK_SEL_MASK;
1113 asrc4_value = (asrc4_value & ~RT5677_DA_MONO3R_CLK_SEL_MASK)
1114 | (clk_src << RT5677_DA_MONO3R_CLK_SEL_SFT);
1115 }
1116
1117 if (filter_mask & RT5677_DA_MONO4_L_FILTER) {
1118 asrc4_mask |= RT5677_DA_MONO4L_CLK_SEL_MASK;
1119 asrc4_value = (asrc4_value & ~RT5677_DA_MONO4L_CLK_SEL_MASK)
1120 | (clk_src << RT5677_DA_MONO4L_CLK_SEL_SFT);
1121 }
1122
1123 if (filter_mask & RT5677_DA_MONO4_R_FILTER) {
1124 asrc4_mask |= RT5677_DA_MONO4R_CLK_SEL_MASK;
1125 asrc4_value = (asrc4_value & ~RT5677_DA_MONO4R_CLK_SEL_MASK)
1126 | (clk_src << RT5677_DA_MONO4R_CLK_SEL_SFT);
1127 }
1128
1129 if (asrc4_mask)
1130 regmap_update_bits(rt5677->regmap, RT5677_ASRC_4, asrc4_mask,
1131 asrc4_value);
1132
1133 /* ASRC 5 */
1134 if (filter_mask & RT5677_AD_STEREO1_FILTER) {
1135 asrc5_mask |= RT5677_AD_STO1_CLK_SEL_MASK;
1136 asrc5_value = (asrc5_value & ~RT5677_AD_STO1_CLK_SEL_MASK)
1137 | (clk_src << RT5677_AD_STO1_CLK_SEL_SFT);
1138 }
1139
1140 if (filter_mask & RT5677_AD_STEREO2_FILTER) {
1141 asrc5_mask |= RT5677_AD_STO2_CLK_SEL_MASK;
1142 asrc5_value = (asrc5_value & ~RT5677_AD_STO2_CLK_SEL_MASK)
1143 | (clk_src << RT5677_AD_STO2_CLK_SEL_SFT);
1144 }
1145
1146 if (filter_mask & RT5677_AD_STEREO3_FILTER) {
1147 asrc5_mask |= RT5677_AD_STO3_CLK_SEL_MASK;
1148 asrc5_value = (asrc5_value & ~RT5677_AD_STO3_CLK_SEL_MASK)
1149 | (clk_src << RT5677_AD_STO3_CLK_SEL_SFT);
1150 }
1151
1152 if (filter_mask & RT5677_AD_STEREO4_FILTER) {
1153 asrc5_mask |= RT5677_AD_STO4_CLK_SEL_MASK;
1154 asrc5_value = (asrc5_value & ~RT5677_AD_STO4_CLK_SEL_MASK)
1155 | (clk_src << RT5677_AD_STO4_CLK_SEL_SFT);
1156 }
1157
1158 if (asrc5_mask)
1159 regmap_update_bits(rt5677->regmap, RT5677_ASRC_5, asrc5_mask,
1160 asrc5_value);
1161
1162 /* ASRC 6 */
1163 if (filter_mask & RT5677_AD_MONO_L_FILTER) {
1164 asrc6_mask |= RT5677_AD_MONOL_CLK_SEL_MASK;
1165 asrc6_value = (asrc6_value & ~RT5677_AD_MONOL_CLK_SEL_MASK)
1166 | (clk_src << RT5677_AD_MONOL_CLK_SEL_SFT);
1167 }
1168
1169 if (filter_mask & RT5677_AD_MONO_R_FILTER) {
1170 asrc6_mask |= RT5677_AD_MONOR_CLK_SEL_MASK;
1171 asrc6_value = (asrc6_value & ~RT5677_AD_MONOR_CLK_SEL_MASK)
1172 | (clk_src << RT5677_AD_MONOR_CLK_SEL_SFT);
1173 }
1174
1175 if (asrc6_mask)
1176 regmap_update_bits(rt5677->regmap, RT5677_ASRC_6, asrc6_mask,
1177 asrc6_value);
1178
1179 /* ASRC 7 */
1180 if (filter_mask & RT5677_DSP_OB_0_3_FILTER) {
1181 asrc7_mask |= RT5677_DSP_OB_0_3_CLK_SEL_MASK;
1182 asrc7_value = (asrc7_value & ~RT5677_DSP_OB_0_3_CLK_SEL_MASK)
1183 | (clk_src << RT5677_DSP_OB_0_3_CLK_SEL_SFT);
1184 }
1185
1186 if (filter_mask & RT5677_DSP_OB_4_7_FILTER) {
1187 asrc7_mask |= RT5677_DSP_OB_4_7_CLK_SEL_MASK;
1188 asrc7_value = (asrc7_value & ~RT5677_DSP_OB_4_7_CLK_SEL_MASK)
1189 | (clk_src << RT5677_DSP_OB_4_7_CLK_SEL_SFT);
1190 }
1191
1192 if (asrc7_mask)
1193 regmap_update_bits(rt5677->regmap, RT5677_ASRC_7, asrc7_mask,
1194 asrc7_value);
1195
1196 return 0;
1197}
1198EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src);
1199
1037/* Digital Mixer */ 1200/* Digital Mixer */
1038static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { 1201static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = {
1039 SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, 1202 SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER,
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 07df96b43f59..9dceb41d18ea 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1406,6 +1406,46 @@
1406#define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7) 1406#define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7)
1407#define RT5677_DSP_CLK_SRC_BYPASS (0x1 << 7) 1407#define RT5677_DSP_CLK_SRC_BYPASS (0x1 << 7)
1408 1408
1409/* ASRC Control 3 (0x85) */
1410#define RT5677_DA_STO_CLK_SEL_MASK (0xf << 12)
1411#define RT5677_DA_STO_CLK_SEL_SFT 12
1412#define RT5677_DA_MONO2L_CLK_SEL_MASK (0xf << 4)
1413#define RT5677_DA_MONO2L_CLK_SEL_SFT 4
1414#define RT5677_DA_MONO2R_CLK_SEL_MASK (0xf << 0)
1415#define RT5677_DA_MONO2R_CLK_SEL_SFT 0
1416
1417/* ASRC Control 4 (0x86) */
1418#define RT5677_DA_MONO3L_CLK_SEL_MASK (0xf << 12)
1419#define RT5677_DA_MONO3L_CLK_SEL_SFT 12
1420#define RT5677_DA_MONO3R_CLK_SEL_MASK (0xf << 8)
1421#define RT5677_DA_MONO3R_CLK_SEL_SFT 8
1422#define RT5677_DA_MONO4L_CLK_SEL_MASK (0xf << 4)
1423#define RT5677_DA_MONO4L_CLK_SEL_SFT 4
1424#define RT5677_DA_MONO4R_CLK_SEL_MASK (0xf << 0)
1425#define RT5677_DA_MONO4R_CLK_SEL_SFT 0
1426
1427/* ASRC Control 5 (0x87) */
1428#define RT5677_AD_STO1_CLK_SEL_MASK (0xf << 12)
1429#define RT5677_AD_STO1_CLK_SEL_SFT 12
1430#define RT5677_AD_STO2_CLK_SEL_MASK (0xf << 8)
1431#define RT5677_AD_STO2_CLK_SEL_SFT 8
1432#define RT5677_AD_STO3_CLK_SEL_MASK (0xf << 4)
1433#define RT5677_AD_STO3_CLK_SEL_SFT 4
1434#define RT5677_AD_STO4_CLK_SEL_MASK (0xf << 0)
1435#define RT5677_AD_STO4_CLK_SEL_SFT 0
1436
1437/* ASRC Control 6 (0x88) */
1438#define RT5677_AD_MONOL_CLK_SEL_MASK (0xf << 12)
1439#define RT5677_AD_MONOL_CLK_SEL_SFT 12
1440#define RT5677_AD_MONOR_CLK_SEL_MASK (0xf << 8)
1441#define RT5677_AD_MONOR_CLK_SEL_SFT 8
1442
1443/* ASRC Control 7 (0x89) */
1444#define RT5677_DSP_OB_0_3_CLK_SEL_MASK (0xf << 12)
1445#define RT5677_DSP_OB_0_3_CLK_SEL_SFT 12
1446#define RT5677_DSP_OB_4_7_CLK_SEL_MASK (0xf << 8)
1447#define RT5677_DSP_OB_4_7_CLK_SEL_SFT 8
1448
1409/* VAD Function Control 4 (0x9f) */ 1449/* VAD Function Control 4 (0x9f) */
1410#define RT5677_VAD_SRC_MASK (0x7 << 8) 1450#define RT5677_VAD_SRC_MASK (0x7 << 8)
1411#define RT5677_VAD_SRC_SFT 8 1451#define RT5677_VAD_SRC_SFT 8
@@ -1670,6 +1710,42 @@ enum rt5677_type {
1670 RT5676, 1710 RT5676,
1671}; 1711};
1672 1712
1713/* ASRC clock source selection */
1714enum {
1715 RT5677_CLK_SEL_SYS,
1716 RT5677_CLK_SEL_I2S1_ASRC,
1717 RT5677_CLK_SEL_I2S2_ASRC,
1718 RT5677_CLK_SEL_I2S3_ASRC,
1719 RT5677_CLK_SEL_I2S4_ASRC,
1720 RT5677_CLK_SEL_I2S5_ASRC,
1721 RT5677_CLK_SEL_I2S6_ASRC,
1722 RT5677_CLK_SEL_SYS2,
1723 RT5677_CLK_SEL_SYS3,
1724 RT5677_CLK_SEL_SYS4,
1725 RT5677_CLK_SEL_SYS5,
1726 RT5677_CLK_SEL_SYS6,
1727 RT5677_CLK_SEL_SYS7,
1728};
1729
1730/* filter mask */
1731enum {
1732 RT5677_DA_STEREO_FILTER = 0x1,
1733 RT5677_DA_MONO2_L_FILTER = (0x1 << 1),
1734 RT5677_DA_MONO2_R_FILTER = (0x1 << 2),
1735 RT5677_DA_MONO3_L_FILTER = (0x1 << 3),
1736 RT5677_DA_MONO3_R_FILTER = (0x1 << 4),
1737 RT5677_DA_MONO4_L_FILTER = (0x1 << 5),
1738 RT5677_DA_MONO4_R_FILTER = (0x1 << 6),
1739 RT5677_AD_STEREO1_FILTER = (0x1 << 7),
1740 RT5677_AD_STEREO2_FILTER = (0x1 << 8),
1741 RT5677_AD_STEREO3_FILTER = (0x1 << 9),
1742 RT5677_AD_STEREO4_FILTER = (0x1 << 10),
1743 RT5677_AD_MONO_L_FILTER = (0x1 << 11),
1744 RT5677_AD_MONO_R_FILTER = (0x1 << 12),
1745 RT5677_DSP_OB_0_3_FILTER = (0x1 << 13),
1746 RT5677_DSP_OB_4_7_FILTER = (0x1 << 14),
1747};
1748
1673struct rt5677_priv { 1749struct rt5677_priv {
1674 struct snd_soc_codec *codec; 1750 struct snd_soc_codec *codec;
1675 struct rt5677_platform_data pdata; 1751 struct rt5677_platform_data pdata;
@@ -1696,4 +1772,7 @@ struct rt5677_priv {
1696 bool is_vref_slow; 1772 bool is_vref_slow;
1697}; 1773};
1698 1774
1775int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
1776 unsigned int filter_mask, unsigned int clk_src);
1777
1699#endif /* __RT5677_H__ */ 1778#endif /* __RT5677_H__ */