diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/ac97.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/ad1980.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/twl4030.c | 121 | ||||
-rw-r--r-- | sound/soc/codecs/wm9705.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/wm9712.c | 6 | ||||
-rw-r--r-- | sound/soc/codecs/wm9713.c | 6 | ||||
-rw-r--r-- | sound/soc/pxa/Kconfig | 9 | ||||
-rw-r--r-- | sound/soc/pxa/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/pxa/imote2.c | 114 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c-i2s-v2.c | 87 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c64xx-i2s.c | 15 | ||||
-rw-r--r-- | sound/soc/s3c24xx/s3c64xx-i2s.h | 4 |
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 | }; |
65 | EXPORT_SYMBOL_GPL(ac97_dai); | 65 | EXPORT_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 | }; |
148 | EXPORT_SYMBOL_GPL(ad1980_dai); | 148 | EXPORT_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 = | |||
396 | static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = | 396 | static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = |
397 | SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); | 397 | SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); |
398 | 398 | ||
399 | /* Vibra */ | ||
400 | /* Vibra audio path selection */ | ||
401 | static const char *twl4030_vibra_texts[] = | ||
402 | {"AudioL1", "AudioR1", "AudioL2", "AudioR2"}; | ||
403 | |||
404 | static 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 | |||
409 | static const struct snd_kcontrol_new twl4030_dapm_vibra_control = | ||
410 | SOC_DAPM_ENUM("Route", twl4030_vibra_enum); | ||
411 | |||
412 | /* Vibra path selection: local vibrator (PWM) or audio driven */ | ||
413 | static const char *twl4030_vibrapath_texts[] = | ||
414 | {"Local vibrator", "Audio"}; | ||
415 | |||
416 | static 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 | |||
421 | static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control = | ||
422 | SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum); | ||
423 | |||
399 | /* Left analog microphone selection */ | 424 | /* Left analog microphone selection */ |
400 | static const char *twl4030_analoglmic_texts[] = | 425 | static 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 = | |||
468 | static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = | 493 | static 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 */ | ||
497 | static 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 */ |
472 | static const unsigned int twl4030_dapm_dbypass_tlv[] = { | 501 | static 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 | */ | ||
523 | static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1); | ||
524 | |||
525 | /* Digital bypass voice: sidetone (VUL -> VDL)*/ | ||
526 | static 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 | |||
490 | static int micpath_event(struct snd_soc_dapm_widget *w, | 531 | static 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 */ | ||
896 | static const char *twl4030_vibradirmode_texts[] = { | ||
897 | "Vibra H-bridge direction", "Audio data MSB", | ||
898 | }; | ||
899 | |||
900 | static 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 */ | ||
906 | static const char *twl4030_vibradir_texts[] = { | ||
907 | "Positive polarity", "Negative polarity", | ||
908 | }; | ||
909 | |||
910 | static 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 | |||
834 | static const struct snd_kcontrol_new twl4030_snd_controls[] = { | 915 | static 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 | ||
902 | static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { | 986 | static 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 | |||
138 | config 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 | |||
22 | snd-soc-zylonite-objs := zylonite.o | 22 | snd-soc-zylonite-objs := zylonite.o |
23 | snd-soc-magician-objs := magician.o | 23 | snd-soc-magician-objs := magician.o |
24 | snd-soc-mioa701-objs := mioa701_wm9713.o | 24 | snd-soc-mioa701-objs := mioa701_wm9713.o |
25 | snd-soc-imote2-objs := imote2.o | ||
25 | 26 | ||
26 | obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o | 27 | obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o |
27 | obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o | 28 | obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o |
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o | |||
35 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o | 36 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o |
36 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o | 37 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o |
37 | obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o | 38 | obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o |
39 | obj-$(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 | |||
11 | static 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 | |||
60 | static struct snd_soc_ops imote2_asoc_ops = { | ||
61 | .hw_params = imote2_asoc_hw_params, | ||
62 | }; | ||
63 | |||
64 | static 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 | |||
72 | static 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 | |||
79 | static struct snd_soc_device imote2_snd_devdata = { | ||
80 | .card = &snd_soc_imote2, | ||
81 | .codec_dev = &soc_codec_dev_wm8940, | ||
82 | }; | ||
83 | |||
84 | static struct platform_device *imote2_snd_device; | ||
85 | |||
86 | static 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 | } | ||
104 | module_init(imote2_asoc_init); | ||
105 | |||
106 | static void __exit imote2_asoc_exit(void) | ||
107 | { | ||
108 | platform_device_unregister(imote2_snd_device); | ||
109 | } | ||
110 | module_exit(imote2_asoc_exit); | ||
111 | |||
112 | MODULE_AUTHOR("Jonathan Cameron"); | ||
113 | MODULE_DESCRIPTION("ALSA SoC Imote 2"); | ||
114 | MODULE_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 | ||
42 | static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) | 56 | static 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. */ |
78 | void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) | 92 | static 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 | } |
146 | EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl); | ||
147 | 164 | ||
148 | void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) | 165 | static 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 | } |
212 | EXPORT_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 | |||
569 | EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); | 632 | EXPORT_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 | 111 | struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) | |
112 | unsigned 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 | } |
118 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); | 117 | EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); |
119 | 118 | ||
120 | static int s3c64xx_i2s_probe(struct platform_device *pdev, | 119 | static 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 | ||
152 | static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { | 152 | static 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 | ||
18 | struct 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 | ||
27 | extern struct snd_soc_dai s3c64xx_i2s_dai[]; | 29 | extern struct snd_soc_dai s3c64xx_i2s_dai[]; |
28 | 30 | ||
29 | extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); | 31 | extern 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 */ |