aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/ac97.c4
-rw-r--r--sound/soc/codecs/ad1980.c4
-rw-r--r--sound/soc/codecs/twl4030.c121
-rw-r--r--sound/soc/codecs/wm9705.c4
-rw-r--r--sound/soc/codecs/wm9712.c6
-rw-r--r--sound/soc/codecs/wm9713.c6
-rw-r--r--sound/soc/pxa/Kconfig9
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/imote2.c114
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c87
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c15
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h4
12 files changed, 337 insertions, 39 deletions
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index b0d4af145b87..932299bb5d1e 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -53,13 +53,13 @@ struct snd_soc_dai ac97_dai = {
53 .channels_min = 1, 53 .channels_min = 1,
54 .channels_max = 2, 54 .channels_max = 2,
55 .rates = STD_AC97_RATES, 55 .rates = STD_AC97_RATES,
56 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 56 .formats = SND_SOC_STD_AC97_FMTS,},
57 .capture = { 57 .capture = {
58 .stream_name = "AC97 Capture", 58 .stream_name = "AC97 Capture",
59 .channels_min = 1, 59 .channels_min = 1,
60 .channels_max = 2, 60 .channels_max = 2,
61 .rates = STD_AC97_RATES, 61 .rates = STD_AC97_RATES,
62 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 62 .formats = SND_SOC_STD_AC97_FMTS,},
63 .ops = &ac97_dai_ops, 63 .ops = &ac97_dai_ops,
64}; 64};
65EXPORT_SYMBOL_GPL(ac97_dai); 65EXPORT_SYMBOL_GPL(ac97_dai);
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index ddb3b08ac23c..d7440a982d22 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -137,13 +137,13 @@ struct snd_soc_dai ad1980_dai = {
137 .channels_min = 2, 137 .channels_min = 2,
138 .channels_max = 6, 138 .channels_max = 6,
139 .rates = SNDRV_PCM_RATE_48000, 139 .rates = SNDRV_PCM_RATE_48000,
140 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 140 .formats = SND_SOC_STD_AC97_FMTS, },
141 .capture = { 141 .capture = {
142 .stream_name = "Capture", 142 .stream_name = "Capture",
143 .channels_min = 2, 143 .channels_min = 2,
144 .channels_max = 2, 144 .channels_max = 2,
145 .rates = SNDRV_PCM_RATE_48000, 145 .rates = SNDRV_PCM_RATE_48000,
146 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 146 .formats = SND_SOC_STD_AC97_FMTS, },
147}; 147};
148EXPORT_SYMBOL_GPL(ad1980_dai); 148EXPORT_SYMBOL_GPL(ad1980_dai);
149 149
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index efa1a80b806c..1a00e4b20390 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -396,6 +396,31 @@ static const struct soc_enum twl4030_handsfreer_enum =
396static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = 396static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
397SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); 397SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
398 398
399/* Vibra */
400/* Vibra audio path selection */
401static const char *twl4030_vibra_texts[] =
402 {"AudioL1", "AudioR1", "AudioL2", "AudioR2"};
403
404static const struct soc_enum twl4030_vibra_enum =
405 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2,
406 ARRAY_SIZE(twl4030_vibra_texts),
407 twl4030_vibra_texts);
408
409static const struct snd_kcontrol_new twl4030_dapm_vibra_control =
410SOC_DAPM_ENUM("Route", twl4030_vibra_enum);
411
412/* Vibra path selection: local vibrator (PWM) or audio driven */
413static const char *twl4030_vibrapath_texts[] =
414 {"Local vibrator", "Audio"};
415
416static const struct soc_enum twl4030_vibrapath_enum =
417 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4,
418 ARRAY_SIZE(twl4030_vibrapath_texts),
419 twl4030_vibrapath_texts);
420
421static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control =
422SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
423
399/* Left analog microphone selection */ 424/* Left analog microphone selection */
400static const char *twl4030_analoglmic_texts[] = 425static const char *twl4030_analoglmic_texts[] =
401 {"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"}; 426 {"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"};
@@ -468,6 +493,10 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
468static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = 493static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
469 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0); 494 SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
470 495
496/* Analog bypass for Voice */
497static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
498 SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
499
471/* Digital bypass gain, 0 mutes the bypass */ 500/* Digital bypass gain, 0 mutes the bypass */
472static const unsigned int twl4030_dapm_dbypass_tlv[] = { 501static const unsigned int twl4030_dapm_dbypass_tlv[] = {
473 TLV_DB_RANGE_HEAD(2), 502 TLV_DB_RANGE_HEAD(2),
@@ -487,6 +516,18 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control =
487 TWL4030_REG_ATX2ARXPGA, 0, 7, 0, 516 TWL4030_REG_ATX2ARXPGA, 0, 7, 0,
488 twl4030_dapm_dbypass_tlv); 517 twl4030_dapm_dbypass_tlv);
489 518
519/*
520 * Voice Sidetone GAIN volume control:
521 * from -51 to -10 dB in 1 dB steps (mute instead of -51 dB)
522 */
523static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1);
524
525/* Digital bypass voice: sidetone (VUL -> VDL)*/
526static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
527 SOC_DAPM_SINGLE_TLV("Volume",
528 TWL4030_REG_VSTPGA, 0, 0x29, 0,
529 twl4030_dapm_dbypassv_tlv);
530
490static int micpath_event(struct snd_soc_dapm_widget *w, 531static int micpath_event(struct snd_soc_dapm_widget *w,
491 struct snd_kcontrol *kcontrol, int event) 532 struct snd_kcontrol *kcontrol, int event)
492{ 533{
@@ -585,7 +626,7 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
585 struct soc_mixer_control *m = 626 struct soc_mixer_control *m =
586 (struct soc_mixer_control *)w->kcontrols->private_value; 627 (struct soc_mixer_control *)w->kcontrols->private_value;
587 struct twl4030_priv *twl4030 = w->codec->private_data; 628 struct twl4030_priv *twl4030 = w->codec->private_data;
588 unsigned char reg; 629 unsigned char reg, misc;
589 630
590 reg = twl4030_read_reg_cache(w->codec, m->reg); 631 reg = twl4030_read_reg_cache(w->codec, m->reg);
591 632
@@ -597,14 +638,34 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
597 else 638 else
598 twl4030->bypass_state &= 639 twl4030->bypass_state &=
599 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); 640 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
641 } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
642 /* Analog voice bypass */
643 if (reg & (1 << m->shift))
644 twl4030->bypass_state |= (1 << 4);
645 else
646 twl4030->bypass_state &= ~(1 << 4);
647 } else if (m->reg == TWL4030_REG_VSTPGA) {
648 /* Voice digital bypass */
649 if (reg)
650 twl4030->bypass_state |= (1 << 5);
651 else
652 twl4030->bypass_state &= ~(1 << 5);
600 } else { 653 } else {
601 /* Digital bypass */ 654 /* Digital bypass */
602 if (reg & (0x7 << m->shift)) 655 if (reg & (0x7 << m->shift))
603 twl4030->bypass_state |= (1 << (m->shift ? 5 : 4)); 656 twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
604 else 657 else
605 twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4)); 658 twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
606 } 659 }
607 660
661 /* Enable master analog loopback mode if any analog switch is enabled*/
662 misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
663 if (twl4030->bypass_state & 0x1F)
664 misc |= TWL4030_FMLOOP_EN;
665 else
666 misc &= ~TWL4030_FMLOOP_EN;
667 twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
668
608 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) { 669 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
609 if (twl4030->bypass_state) 670 if (twl4030->bypass_state)
610 twl4030_codec_mute(w->codec, 0); 671 twl4030_codec_mute(w->codec, 0);
@@ -831,6 +892,26 @@ static const struct soc_enum twl4030_rampdelay_enum =
831 ARRAY_SIZE(twl4030_rampdelay_texts), 892 ARRAY_SIZE(twl4030_rampdelay_texts),
832 twl4030_rampdelay_texts); 893 twl4030_rampdelay_texts);
833 894
895/* Vibra H-bridge direction mode */
896static const char *twl4030_vibradirmode_texts[] = {
897 "Vibra H-bridge direction", "Audio data MSB",
898};
899
900static const struct soc_enum twl4030_vibradirmode_enum =
901 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5,
902 ARRAY_SIZE(twl4030_vibradirmode_texts),
903 twl4030_vibradirmode_texts);
904
905/* Vibra H-bridge direction */
906static const char *twl4030_vibradir_texts[] = {
907 "Positive polarity", "Negative polarity",
908};
909
910static const struct soc_enum twl4030_vibradir_enum =
911 SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1,
912 ARRAY_SIZE(twl4030_vibradir_texts),
913 twl4030_vibradir_texts);
914
834static const struct snd_kcontrol_new twl4030_snd_controls[] = { 915static const struct snd_kcontrol_new twl4030_snd_controls[] = {
835 /* Common playback gain controls */ 916 /* Common playback gain controls */
836 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume", 917 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
@@ -897,6 +978,9 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
897 0, 3, 5, 0, input_gain_tlv), 978 0, 3, 5, 0, input_gain_tlv),
898 979
899 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum), 980 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
981
982 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
983 SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
900}; 984};
901 985
902static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { 986static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
@@ -924,6 +1008,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
924 SND_SOC_DAPM_OUTPUT("CARKITR"), 1008 SND_SOC_DAPM_OUTPUT("CARKITR"),
925 SND_SOC_DAPM_OUTPUT("HFL"), 1009 SND_SOC_DAPM_OUTPUT("HFL"),
926 SND_SOC_DAPM_OUTPUT("HFR"), 1010 SND_SOC_DAPM_OUTPUT("HFR"),
1011 SND_SOC_DAPM_OUTPUT("VIBRA"),
927 1012
928 /* DACs */ 1013 /* DACs */
929 SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", 1014 SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
@@ -935,7 +1020,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
935 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", 1020 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
936 SND_SOC_NOPM, 0, 0), 1021 SND_SOC_NOPM, 0, 0),
937 SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback", 1022 SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
938 TWL4030_REG_AVDAC_CTL, 4, 0), 1023 SND_SOC_NOPM, 0, 0),
939 1024
940 /* Analog PGAs */ 1025 /* Analog PGAs */
941 SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, 1026 SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
@@ -962,6 +1047,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
962 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1047 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
963 &twl4030_dapm_abypassl2_control, 1048 &twl4030_dapm_abypassl2_control,
964 bypass_event, SND_SOC_DAPM_POST_REG), 1049 bypass_event, SND_SOC_DAPM_POST_REG),
1050 SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1051 &twl4030_dapm_abypassv_control,
1052 bypass_event, SND_SOC_DAPM_POST_REG),
965 1053
966 /* Digital bypasses */ 1054 /* Digital bypasses */
967 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, 1055 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
@@ -970,6 +1058,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
970 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, 1058 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
971 &twl4030_dapm_dbypassr_control, bypass_event, 1059 &twl4030_dapm_dbypassr_control, bypass_event,
972 SND_SOC_DAPM_POST_REG), 1060 SND_SOC_DAPM_POST_REG),
1061 SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1062 &twl4030_dapm_dbypassv_control, bypass_event,
1063 SND_SOC_DAPM_POST_REG),
973 1064
974 SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL, 1065 SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL,
975 0, 0, NULL, 0), 1066 0, 0, NULL, 0),
@@ -979,6 +1070,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
979 2, 0, NULL, 0), 1070 2, 0, NULL, 0),
980 SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, 1071 SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
981 3, 0, NULL, 0), 1072 3, 0, NULL, 0),
1073 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", TWL4030_REG_AVDAC_CTL,
1074 4, 0, NULL, 0),
982 1075
983 /* Output MIXER controls */ 1076 /* Output MIXER controls */
984 /* Earpiece */ 1077 /* Earpiece */
@@ -1016,6 +1109,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1016 SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0, 1109 SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
1017 &twl4030_dapm_handsfreer_control, handsfree_event, 1110 &twl4030_dapm_handsfreer_control, handsfree_event,
1018 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1111 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1112 /* Vibra */
1113 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1114 &twl4030_dapm_vibra_control),
1115 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1116 &twl4030_dapm_vibrapath_control),
1019 1117
1020 /* Introducing four virtual ADC, since TWL4030 have four channel for 1118 /* Introducing four virtual ADC, since TWL4030 have four channel for
1021 capture */ 1119 capture */
@@ -1067,13 +1165,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1067 {"Analog R1 Playback Mixer", NULL, "DAC Right1"}, 1165 {"Analog R1 Playback Mixer", NULL, "DAC Right1"},
1068 {"Analog L2 Playback Mixer", NULL, "DAC Left2"}, 1166 {"Analog L2 Playback Mixer", NULL, "DAC Left2"},
1069 {"Analog R2 Playback Mixer", NULL, "DAC Right2"}, 1167 {"Analog R2 Playback Mixer", NULL, "DAC Right2"},
1168 {"Analog Voice Playback Mixer", NULL, "DAC Voice"},
1070 1169
1071 {"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"}, 1170 {"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"},
1072 {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"}, 1171 {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"},
1073 {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"}, 1172 {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"},
1074 {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"}, 1173 {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"},
1075 1174 {"VDL_APGA", NULL, "Analog Voice Playback Mixer"},
1076 {"VDL_APGA", NULL, "DAC Voice"},
1077 1175
1078 /* Internal playback routings */ 1176 /* Internal playback routings */
1079 /* Earpiece */ 1177 /* Earpiece */
@@ -1117,6 +1215,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1117 {"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"}, 1215 {"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"},
1118 {"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"}, 1216 {"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"},
1119 {"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"}, 1217 {"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"},
1218 /* Vibra */
1219 {"Vibra Mux", "AudioL1", "DAC Left1"},
1220 {"Vibra Mux", "AudioR1", "DAC Right1"},
1221 {"Vibra Mux", "AudioL2", "DAC Left2"},
1222 {"Vibra Mux", "AudioR2", "DAC Right2"},
1120 1223
1121 /* outputs */ 1224 /* outputs */
1122 {"OUTL", NULL, "ARXL2_APGA"}, 1225 {"OUTL", NULL, "ARXL2_APGA"},
@@ -1130,6 +1233,8 @@ static const struct snd_soc_dapm_route intercon[] = {
1130 {"CARKITR", NULL, "CarkitR Mixer"}, 1233 {"CARKITR", NULL, "CarkitR Mixer"},
1131 {"HFL", NULL, "HandsfreeL Mux"}, 1234 {"HFL", NULL, "HandsfreeL Mux"},
1132 {"HFR", NULL, "HandsfreeR Mux"}, 1235 {"HFR", NULL, "HandsfreeR Mux"},
1236 {"Vibra Route", "Audio", "Vibra Mux"},
1237 {"VIBRA", NULL, "Vibra Route"},
1133 1238
1134 /* Capture path */ 1239 /* Capture path */
1135 {"Analog Left Capture Route", "Main mic", "MAINMIC"}, 1240 {"Analog Left Capture Route", "Main mic", "MAINMIC"},
@@ -1169,18 +1274,22 @@ static const struct snd_soc_dapm_route intercon[] = {
1169 {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1274 {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"},
1170 {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, 1275 {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"},
1171 {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1276 {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"},
1277 {"Voice Analog Loopback", "Switch", "Analog Left Capture Route"},
1172 1278
1173 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1279 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1174 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1280 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1175 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, 1281 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
1176 {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"}, 1282 {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
1283 {"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
1177 1284
1178 /* Digital bypass routes */ 1285 /* Digital bypass routes */
1179 {"Right Digital Loopback", "Volume", "TX1 Capture Route"}, 1286 {"Right Digital Loopback", "Volume", "TX1 Capture Route"},
1180 {"Left Digital Loopback", "Volume", "TX1 Capture Route"}, 1287 {"Left Digital Loopback", "Volume", "TX1 Capture Route"},
1288 {"Voice Digital Loopback", "Volume", "TX2 Capture Route"},
1181 1289
1182 {"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"}, 1290 {"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"},
1183 {"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"}, 1291 {"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"},
1292 {"Analog Voice Playback Mixer", NULL, "Voice Digital Loopback"},
1184 1293
1185}; 1294};
1186 1295
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index c2d1a7a18fa3..fa88b463e71f 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -282,14 +282,14 @@ struct snd_soc_dai wm9705_dai[] = {
282 .channels_min = 1, 282 .channels_min = 1,
283 .channels_max = 2, 283 .channels_max = 2,
284 .rates = WM9705_AC97_RATES, 284 .rates = WM9705_AC97_RATES,
285 .formats = SNDRV_PCM_FMTBIT_S16_LE, 285 .formats = SND_SOC_STD_AC97_FMTS,
286 }, 286 },
287 .capture = { 287 .capture = {
288 .stream_name = "HiFi Capture", 288 .stream_name = "HiFi Capture",
289 .channels_min = 1, 289 .channels_min = 1,
290 .channels_max = 2, 290 .channels_max = 2,
291 .rates = WM9705_AC97_RATES, 291 .rates = WM9705_AC97_RATES,
292 .formats = SNDRV_PCM_FMTBIT_S16_LE, 292 .formats = SND_SOC_STD_AC97_FMTS,
293 }, 293 },
294 .ops = &wm9705_dai_ops, 294 .ops = &wm9705_dai_ops,
295 }, 295 },
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 765cf1e7369e..550c903f23bf 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -534,13 +534,13 @@ struct snd_soc_dai wm9712_dai[] = {
534 .channels_min = 1, 534 .channels_min = 1,
535 .channels_max = 2, 535 .channels_max = 2,
536 .rates = WM9712_AC97_RATES, 536 .rates = WM9712_AC97_RATES,
537 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 537 .formats = SND_SOC_STD_AC97_FMTS,},
538 .capture = { 538 .capture = {
539 .stream_name = "HiFi Capture", 539 .stream_name = "HiFi Capture",
540 .channels_min = 1, 540 .channels_min = 1,
541 .channels_max = 2, 541 .channels_max = 2,
542 .rates = WM9712_AC97_RATES, 542 .rates = WM9712_AC97_RATES,
543 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 543 .formats = SND_SOC_STD_AC97_FMTS,},
544 .ops = &wm9712_dai_ops_hifi, 544 .ops = &wm9712_dai_ops_hifi,
545}, 545},
546{ 546{
@@ -550,7 +550,7 @@ struct snd_soc_dai wm9712_dai[] = {
550 .channels_min = 1, 550 .channels_min = 1,
551 .channels_max = 1, 551 .channels_max = 1,
552 .rates = WM9712_AC97_RATES, 552 .rates = WM9712_AC97_RATES,
553 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 553 .formats = SND_SOC_STD_AC97_FMTS,},
554 .ops = &wm9712_dai_ops_aux, 554 .ops = &wm9712_dai_ops_aux,
555} 555}
556}; 556};
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index a6feb7842314..d1744e96f303 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1040,13 +1040,13 @@ struct snd_soc_dai wm9713_dai[] = {
1040 .channels_min = 1, 1040 .channels_min = 1,
1041 .channels_max = 2, 1041 .channels_max = 2,
1042 .rates = WM9713_RATES, 1042 .rates = WM9713_RATES,
1043 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1043 .formats = SND_SOC_STD_AC97_FMTS,},
1044 .capture = { 1044 .capture = {
1045 .stream_name = "HiFi Capture", 1045 .stream_name = "HiFi Capture",
1046 .channels_min = 1, 1046 .channels_min = 1,
1047 .channels_max = 2, 1047 .channels_max = 2,
1048 .rates = WM9713_RATES, 1048 .rates = WM9713_RATES,
1049 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1049 .formats = SND_SOC_STD_AC97_FMTS,},
1050 .ops = &wm9713_dai_ops_hifi, 1050 .ops = &wm9713_dai_ops_hifi,
1051 }, 1051 },
1052 { 1052 {
@@ -1056,7 +1056,7 @@ struct snd_soc_dai wm9713_dai[] = {
1056 .channels_min = 1, 1056 .channels_min = 1,
1057 .channels_max = 1, 1057 .channels_max = 1,
1058 .rates = WM9713_RATES, 1058 .rates = WM9713_RATES,
1059 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1059 .formats = SND_SOC_STD_AC97_FMTS,},
1060 .ops = &wm9713_dai_ops_aux, 1060 .ops = &wm9713_dai_ops_aux,
1061 }, 1061 },
1062 { 1062 {
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index ad8a10fe6298..eb75a1c061aa 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -134,3 +134,12 @@ config SND_PXA2XX_SOC_MIOA701
134 help 134 help
135 Say Y if you want to add support for SoC audio on the 135 Say Y if you want to add support for SoC audio on the
136 MIO A701. 136 MIO A701.
137
138config SND_PXA2XX_SOC_IMOTE2
139 tristate "SoC Audio support for IMote 2"
140 depends on SND_PXA2XX_SOC && MACH_INTELMOTE2
141 select SND_PXA2XX_SOC_I2S
142 select SND_SOC_WM8940
143 help
144 Say Y if you want to add support for SoC audio on the
145 IMote 2.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 4b90c3ccae45..6e096b480335 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
22snd-soc-zylonite-objs := zylonite.o 22snd-soc-zylonite-objs := zylonite.o
23snd-soc-magician-objs := magician.o 23snd-soc-magician-objs := magician.o
24snd-soc-mioa701-objs := mioa701_wm9713.o 24snd-soc-mioa701-objs := mioa701_wm9713.o
25snd-soc-imote2-objs := imote2.o
25 26
26obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 27obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
27obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 28obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
35obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 36obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
36obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 37obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
37obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 38obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
39obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
new file mode 100644
index 000000000000..405587a01160
--- /dev/null
+++ b/sound/soc/pxa/imote2.c
@@ -0,0 +1,114 @@
1
2#include <linux/module.h>
3#include <sound/soc.h>
4
5#include <asm/mach-types.h>
6
7#include "../codecs/wm8940.h"
8#include "pxa2xx-i2s.h"
9#include "pxa2xx-pcm.h"
10
11static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
12 struct snd_pcm_hw_params *params)
13{
14 struct snd_soc_pcm_runtime *rtd = substream->private_data;
15 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
16 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
17 unsigned int clk = 0;
18 int ret;
19
20 switch (params_rate(params)) {
21 case 8000:
22 case 16000:
23 case 48000:
24 case 96000:
25 clk = 12288000;
26 break;
27 case 11025:
28 case 22050:
29 case 44100:
30 clk = 11289600;
31 break;
32 }
33
34 /* set codec DAI configuration */
35 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
36 | SND_SOC_DAIFMT_NB_NF
37 | SND_SOC_DAIFMT_CBS_CFS);
38 if (ret < 0)
39 return ret;
40
41 /* CPU should be clock master */
42 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
43 | SND_SOC_DAIFMT_NB_NF
44 | SND_SOC_DAIFMT_CBS_CFS);
45 if (ret < 0)
46 return ret;
47
48 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
49 SND_SOC_CLOCK_IN);
50 if (ret < 0)
51 return ret;
52
53 /* set the I2S system clock as input (unused) */
54 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, clk,
55 SND_SOC_CLOCK_OUT);
56
57 return ret;
58}
59
60static struct snd_soc_ops imote2_asoc_ops = {
61 .hw_params = imote2_asoc_hw_params,
62};
63
64static struct snd_soc_dai_link imote2_dai = {
65 .name = "WM8940",
66 .stream_name = "WM8940",
67 .cpu_dai = &pxa_i2s_dai,
68 .codec_dai = &wm8940_dai,
69 .ops = &imote2_asoc_ops,
70};
71
72static struct snd_soc_card snd_soc_imote2 = {
73 .name = "Imote2",
74 .platform = &pxa2xx_soc_platform,
75 .dai_link = &imote2_dai,
76 .num_links = 1,
77};
78
79static struct snd_soc_device imote2_snd_devdata = {
80 .card = &snd_soc_imote2,
81 .codec_dev = &soc_codec_dev_wm8940,
82};
83
84static struct platform_device *imote2_snd_device;
85
86static int __init imote2_asoc_init(void)
87{
88 int ret;
89
90 if (!machine_is_intelmote2())
91 return -ENODEV;
92 imote2_snd_device = platform_device_alloc("soc-audio", -1);
93 if (!imote2_snd_device)
94 return -ENOMEM;
95
96 platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata);
97 imote2_snd_devdata.dev = &imote2_snd_device->dev;
98 ret = platform_device_add(imote2_snd_device);
99 if (ret)
100 platform_device_put(imote2_snd_device);
101
102 return ret;
103}
104module_init(imote2_asoc_init);
105
106static void __exit imote2_asoc_exit(void)
107{
108 platform_device_unregister(imote2_snd_device);
109}
110module_exit(imote2_asoc_exit);
111
112MODULE_AUTHOR("Jonathan Cameron");
113MODULE_DESCRIPTION("ALSA SoC Imote 2");
114MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index ab680aac3fcb..972c27684198 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -37,6 +37,20 @@
37 37
38#include "s3c-i2s-v2.h" 38#include "s3c-i2s-v2.h"
39 39
40#undef S3C_IIS_V2_SUPPORTED
41
42#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
43#define S3C_IIS_V2_SUPPORTED
44#endif
45
46#ifdef CONFIG_PLAT_S3C64XX
47#define S3C_IIS_V2_SUPPORTED
48#endif
49
50#ifndef S3C_IIS_V2_SUPPORTED
51#error Unsupported CPU model
52#endif
53
40#define S3C2412_I2S_DEBUG_CON 0 54#define S3C2412_I2S_DEBUG_CON 0
41 55
42static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) 56static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
@@ -75,7 +89,7 @@ static inline void dbg_showcon(const char *fn, u32 con)
75 89
76 90
77/* Turn on or off the transmission path. */ 91/* Turn on or off the transmission path. */
78void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) 92static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
79{ 93{
80 void __iomem *regs = i2s->regs; 94 void __iomem *regs = i2s->regs;
81 u32 fic, con, mod; 95 u32 fic, con, mod;
@@ -105,7 +119,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
105 break; 119 break;
106 120
107 default: 121 default:
108 dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); 122 dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n",
123 mod & S3C2412_IISMOD_MODE_MASK);
124 break;
109 } 125 }
110 126
111 writel(con, regs + S3C2412_IISCON); 127 writel(con, regs + S3C2412_IISCON);
@@ -132,7 +148,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
132 break; 148 break;
133 149
134 default: 150 default:
135 dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); 151 dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n",
152 mod & S3C2412_IISMOD_MODE_MASK);
153 break;
136 } 154 }
137 155
138 writel(mod, regs + S3C2412_IISMOD); 156 writel(mod, regs + S3C2412_IISMOD);
@@ -143,9 +161,8 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
143 dbg_showcon(__func__, con); 161 dbg_showcon(__func__, con);
144 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); 162 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
145} 163}
146EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl);
147 164
148void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) 165static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
149{ 166{
150 void __iomem *regs = i2s->regs; 167 void __iomem *regs = i2s->regs;
151 u32 fic, con, mod; 168 u32 fic, con, mod;
@@ -175,7 +192,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
175 break; 192 break;
176 193
177 default: 194 default:
178 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); 195 dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n",
196 mod & S3C2412_IISMOD_MODE_MASK);
179 } 197 }
180 198
181 writel(mod, regs + S3C2412_IISMOD); 199 writel(mod, regs + S3C2412_IISMOD);
@@ -199,7 +217,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
199 break; 217 break;
200 218
201 default: 219 default:
202 dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); 220 dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n",
221 mod & S3C2412_IISMOD_MODE_MASK);
203 } 222 }
204 223
205 writel(con, regs + S3C2412_IISCON); 224 writel(con, regs + S3C2412_IISCON);
@@ -209,7 +228,6 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
209 fic = readl(regs + S3C2412_IISFIC); 228 fic = readl(regs + S3C2412_IISFIC);
210 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); 229 pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
211} 230}
212EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl);
213 231
214/* 232/*
215 * Wait for the LR signal to allow synchronisation to the L/R clock 233 * Wait for the LR signal to allow synchronisation to the L/R clock
@@ -266,7 +284,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
266 */ 284 */
267#define IISMOD_MASTER_MASK (1 << 11) 285#define IISMOD_MASTER_MASK (1 << 11)
268#define IISMOD_SLAVE (1 << 11) 286#define IISMOD_SLAVE (1 << 11)
269#define IISMOD_MASTER (0x0) 287#define IISMOD_MASTER (0 << 11)
270#endif 288#endif
271 289
272 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 290 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -281,7 +299,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
281 iismod |= IISMOD_MASTER; 299 iismod |= IISMOD_MASTER;
282 break; 300 break;
283 default: 301 default:
284 pr_debug("unknwon master/slave format\n"); 302 pr_err("unknwon master/slave format\n");
285 return -EINVAL; 303 return -EINVAL;
286 } 304 }
287 305
@@ -298,7 +316,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
298 iismod |= S3C2412_IISMOD_SDF_IIS; 316 iismod |= S3C2412_IISMOD_SDF_IIS;
299 break; 317 break;
300 default: 318 default:
301 pr_debug("Unknown data format\n"); 319 pr_err("Unknown data format\n");
302 return -EINVAL; 320 return -EINVAL;
303 } 321 }
304 322
@@ -327,6 +345,7 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
327 iismod = readl(i2s->regs + S3C2412_IISMOD); 345 iismod = readl(i2s->regs + S3C2412_IISMOD);
328 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); 346 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
329 347
348#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
330 switch (params_format(params)) { 349 switch (params_format(params)) {
331 case SNDRV_PCM_FORMAT_S8: 350 case SNDRV_PCM_FORMAT_S8:
332 iismod |= S3C2412_IISMOD_8BIT; 351 iismod |= S3C2412_IISMOD_8BIT;
@@ -335,6 +354,25 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
335 iismod &= ~S3C2412_IISMOD_8BIT; 354 iismod &= ~S3C2412_IISMOD_8BIT;
336 break; 355 break;
337 } 356 }
357#endif
358
359#ifdef CONFIG_PLAT_S3C64XX
360 iismod &= ~0x606;
361 /* Sample size */
362 switch (params_format(params)) {
363 case SNDRV_PCM_FORMAT_S8:
364 /* 8 bit sample, 16fs BCLK */
365 iismod |= 0x2004;
366 break;
367 case SNDRV_PCM_FORMAT_S16_LE:
368 /* 16 bit sample, 32fs BCLK */
369 break;
370 case SNDRV_PCM_FORMAT_S24_LE:
371 /* 24 bit sample, 48fs BCLK */
372 iismod |= 0x4002;
373 break;
374 }
375#endif
338 376
339 writel(iismod, i2s->regs + S3C2412_IISMOD); 377 writel(iismod, i2s->regs + S3C2412_IISMOD);
340 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); 378 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
@@ -489,6 +527,8 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
489 unsigned int best_rate = 0; 527 unsigned int best_rate = 0;
490 unsigned int best_deviation = INT_MAX; 528 unsigned int best_deviation = INT_MAX;
491 529
530 pr_debug("Input clock rate %ldHz\n", clkrate);
531
492 if (fstab == NULL) 532 if (fstab == NULL)
493 fstab = iis_fs_tab; 533 fstab = iis_fs_tab;
494 534
@@ -539,12 +579,31 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
539 unsigned long base) 579 unsigned long base)
540{ 580{
541 struct device *dev = &pdev->dev; 581 struct device *dev = &pdev->dev;
582 unsigned int iismod;
542 583
543 i2s->dev = dev; 584 i2s->dev = dev;
544 585
545 /* record our i2s structure for later use in the callbacks */ 586 /* record our i2s structure for later use in the callbacks */
546 dai->private_data = i2s; 587 dai->private_data = i2s;
547 588
589 if (!base) {
590 struct resource *res = platform_get_resource(pdev,
591 IORESOURCE_MEM,
592 0);
593 if (!res) {
594 dev_err(dev, "Unable to get register resource\n");
595 return -ENXIO;
596 }
597
598 if (!request_mem_region(res->start, resource_size(res),
599 "s3c64xx-i2s-v4")) {
600 dev_err(dev, "Unable to request register region\n");
601 return -EBUSY;
602 }
603
604 base = res->start;
605 }
606
548 i2s->regs = ioremap(base, 0x100); 607 i2s->regs = ioremap(base, 0x100);
549 if (i2s->regs == NULL) { 608 if (i2s->regs == NULL) {
550 dev_err(dev, "cannot ioremap registers\n"); 609 dev_err(dev, "cannot ioremap registers\n");
@@ -560,12 +619,16 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
560 619
561 clk_enable(i2s->iis_pclk); 620 clk_enable(i2s->iis_pclk);
562 621
622 /* Mark ourselves as in TXRX mode so we can run through our cleanup
623 * process without warnings. */
624 iismod = readl(i2s->regs + S3C2412_IISMOD);
625 iismod |= S3C2412_IISMOD_MODE_TXRX;
626 writel(iismod, i2s->regs + S3C2412_IISMOD);
563 s3c2412_snd_txctrl(i2s, 0); 627 s3c2412_snd_txctrl(i2s, 0);
564 s3c2412_snd_rxctrl(i2s, 0); 628 s3c2412_snd_rxctrl(i2s, 0);
565 629
566 return 0; 630 return 0;
567} 631}
568
569EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); 632EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
570 633
571#ifdef CONFIG_PM 634#ifdef CONFIG_PM
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 1345fbdca700..3c06c401d0fb 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -108,14 +108,13 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
108 return 0; 108 return 0;
109} 109}
110 110
111 111struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
112unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai)
113{ 112{
114 struct s3c_i2sv2_info *i2s = to_info(dai); 113 struct s3c_i2sv2_info *i2s = to_info(dai);
115 114
116 return clk_get_rate(i2s->iis_cclk); 115 return i2s->iis_cclk;
117} 116}
118EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); 117EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
119 118
120static int s3c64xx_i2s_probe(struct platform_device *pdev, 119static int s3c64xx_i2s_probe(struct platform_device *pdev,
121 struct snd_soc_dai *dai) 120 struct snd_soc_dai *dai)
@@ -147,7 +146,8 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev,
147 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 146 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
148 147
149#define S3C64XX_I2S_FMTS \ 148#define S3C64XX_I2S_FMTS \
150 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) 149 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
150 SNDRV_PCM_FMTBIT_S24_LE)
151 151
152static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { 152static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
153 .set_sysclk = s3c64xx_i2s_set_sysclk, 153 .set_sysclk = s3c64xx_i2s_set_sysclk,
@@ -215,13 +215,12 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
215 215
216 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); 216 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
217 if (IS_ERR(i2s->iis_cclk)) { 217 if (IS_ERR(i2s->iis_cclk)) {
218 dev_err(&pdev->dev, "failed to get audio-bus"); 218 dev_err(&pdev->dev, "failed to get audio-bus\n");
219 ret = PTR_ERR(i2s->iis_cclk); 219 ret = PTR_ERR(i2s->iis_cclk);
220 goto err; 220 goto err;
221 } 221 }
222 222
223 ret = s3c_i2sv2_probe(pdev, dai, i2s, 223 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
224 dai->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0);
225 if (ret) 224 if (ret)
226 goto err_clk; 225 goto err_clk;
227 226
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index 597822a4658f..02148cee2613 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -15,6 +15,8 @@
15#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H 15#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H
16#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ 16#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
17 17
18struct clk;
19
18#include "s3c-i2s-v2.h" 20#include "s3c-i2s-v2.h"
19 21
20#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK 22#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
@@ -26,6 +28,6 @@
26 28
27extern struct snd_soc_dai s3c64xx_i2s_dai[]; 29extern struct snd_soc_dai s3c64xx_i2s_dai[];
28 30
29extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); 31extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
30 32
31#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ 33#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */