diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-09-02 17:06:45 +0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-09-02 17:06:45 +0400 |
commit | c8ead4154af3d43635f63a708a2f369c7cce09e7 (patch) | |
tree | 42a96351bbee7996826d1126a85351e42a22dd87 /sound | |
parent | 18e391862cceaf43ddb8eb5cca05e1a83abdebaa (diff) | |
parent | 5df498a27ab385294fdb7cad19c623d4da94a780 (diff) | |
download | linux-c8ead4154af3d43635f63a708a2f369c7cce09e7.tar.xz |
Merge tag 'asoc-v3.12-3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Final updates for v3.12
A few final updates for v3.12 - some cleanups, a bug fix for ssm2602,
pop removal for rt5640 and fixes for the reporting of unidirectional
links in the MXS SGTL5000 driver.
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/rt5640.c | 217 | ||||
-rw-r--r-- | sound/soc/codecs/rt5640.h | 12 | ||||
-rw-r--r-- | sound/soc/codecs/ssm2602.c | 3 | ||||
-rw-r--r-- | sound/soc/fsl/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 12 | ||||
-rw-r--r-- | sound/soc/mxs/mxs-sgtl5000.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 10 |
8 files changed, 198 insertions, 62 deletions
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 4db7314baabc..c26a8f814b18 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -50,8 +50,6 @@ static const struct regmap_range_cfg rt5640_ranges[] = { static struct reg_default init_list[] = { {RT5640_PR_BASE + 0x3d, 0x3600}, - {RT5640_PR_BASE + 0x1c, 0x0D21}, - {RT5640_PR_BASE + 0x1b, 0x0000}, {RT5640_PR_BASE + 0x12, 0x0aa8}, {RT5640_PR_BASE + 0x14, 0x0aaa}, {RT5640_PR_BASE + 0x20, 0x6110}, @@ -384,15 +382,11 @@ static const SOC_ENUM_SINGLE_DECL( static const struct snd_kcontrol_new rt5640_snd_controls[] = { /* Speaker Output Volume */ - SOC_DOUBLE("Speaker Playback Switch", RT5640_SPK_VOL, - RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1), SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL, RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL, RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), /* Headphone Output Volume */ - SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL, - RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1), SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL, RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL, @@ -737,6 +731,22 @@ static const struct snd_kcontrol_new rt5640_mono_mix[] = { RT5640_M_BST1_MM_SFT, 1, 1), }; +static const struct snd_kcontrol_new spk_l_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL, + RT5640_L_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new spk_r_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL, + RT5640_R_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new hp_l_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL, + RT5640_L_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new hp_r_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL, + RT5640_R_MUTE_SFT, 1, 1); + /* Stereo ADC source */ static const char * const rt5640_stereo_adc1_src[] = { "DIG MIX", "ADC" @@ -868,33 +878,6 @@ static const SOC_ENUM_SINGLE_DECL( static const struct snd_kcontrol_new rt5640_sdi_mux = SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); -static int spk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1, - 0x0001, 0x0001); - regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c, - 0xf000, 0xf000); - break; - - case SND_SOC_DAPM_PRE_PMD: - regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c, - 0xf000, 0x0000); - regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1, - 0x0001, 0x0000); - break; - - default: - return 0; - } - return 0; -} - static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -943,6 +926,117 @@ static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w, return 0; } +void hp_amp_power_on(struct snd_soc_codec *codec) +{ + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); + + /* depop parameters */ + regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + + RT5640_CHPUMP_INT_REG1, 0x0700, 0x0200); + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2, + RT5640_DEPOP_MASK, RT5640_DEPOP_MAN); + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1, + RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK, + RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU); + regmap_write(rt5640->regmap, RT5640_PR_BASE + RT5640_HP_DCC_INT1, + 0x9f00); + /* headphone amp power on */ + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1, + RT5640_PWR_FV1 | RT5640_PWR_FV2, 0); + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1, + RT5640_PWR_HA, + RT5640_PWR_HA); + usleep_range(10000, 15000); + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1, + RT5640_PWR_FV1 | RT5640_PWR_FV2 , + RT5640_PWR_FV1 | RT5640_PWR_FV2); +} + +static void rt5640_pmu_depop(struct snd_soc_codec *codec) +{ + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); + + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2, + RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK, + RT5640_DEPOP_AUTO | RT5640_DIG_DP_EN); + regmap_update_bits(rt5640->regmap, RT5640_CHARGE_PUMP, + RT5640_PM_HP_MASK, RT5640_PM_HP_HV); + + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M3, + RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK, + (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ1_SFT) | + (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) | + (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ3_SFT)); + + regmap_write(rt5640->regmap, RT5640_PR_BASE + + RT5640_MAMP_INT_REG2, 0x1c00); + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1, + RT5640_HP_CP_MASK | RT5640_HP_SG_MASK, + RT5640_HP_CP_PD | RT5640_HP_SG_EN); + regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + + RT5640_CHPUMP_INT_REG1, 0x0700, 0x0400); +} + +static int rt5640_hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + rt5640_pmu_depop(codec); + rt5640->hp_mute = 0; + break; + + case SND_SOC_DAPM_PRE_PMD: + rt5640->hp_mute = 1; + usleep_range(70000, 75000); + break; + + default: + return 0; + } + + return 0; +} + +static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + hp_amp_power_on(codec); + break; + default: + return 0; + } + + return 0; +} + +static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (!rt5640->hp_mute) + usleep_range(80000, 85000); + + break; + + default: + return 0; + } + + return 0; +} + static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2, RT5640_PWR_PLL_BIT, 0, NULL, 0), @@ -1132,15 +1226,28 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, RT5640_PWR_MA_BIT, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY("Improve HP Amp Drv", RT5640_PWR_ANLG1, - SND_SOC_NOPM, 0, NULL, 0), - SND_SOC_DAPM_PGA("HP L Amp", RT5640_PWR_ANLG1, + SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM, + 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, + rt5640_hp_event, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_SUPPLY("HP L Amp", RT5640_PWR_ANLG1, RT5640_PWR_HP_L_BIT, 0, NULL, 0), - SND_SOC_DAPM_PGA("HP R Amp", RT5640_PWR_ANLG1, + SND_SOC_DAPM_SUPPLY("HP R Amp", RT5640_PWR_ANLG1, RT5640_PWR_HP_R_BIT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1, - SND_SOC_NOPM, 0, spk_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + RT5640_PWR_CLS_D_BIT, 0, NULL, 0), + + /* Output Switch */ + SND_SOC_DAPM_SWITCH("Speaker L Playback", SND_SOC_NOPM, 0, 0, + &spk_l_enable_control), + SND_SOC_DAPM_SWITCH("Speaker R Playback", SND_SOC_NOPM, 0, 0, + &spk_r_enable_control), + SND_SOC_DAPM_SWITCH("HP L Playback", SND_SOC_NOPM, 0, 0, + &hp_l_enable_control), + SND_SOC_DAPM_SWITCH("HP R Playback", SND_SOC_NOPM, 0, 0, + &hp_r_enable_control), + SND_SOC_DAPM_POST("HP Post", rt5640_hp_post_event), /* Output Lines */ SND_SOC_DAPM_OUTPUT("SPOLP"), SND_SOC_DAPM_OUTPUT("SPOLN"), @@ -1381,9 +1488,11 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, + {"HPO MIX L", NULL, "HP L Amp"}, {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, + {"HPO MIX R", NULL, "HP R Amp"}, {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, @@ -1396,13 +1505,15 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, {"Mono MIX", "BST1 Switch", "BST1"}, - {"HP L Amp", NULL, "HPO MIX L"}, - {"HP R Amp", NULL, "HPO MIX R"}, + {"HP Amp", NULL, "HPO MIX L"}, + {"HP Amp", NULL, "HPO MIX R"}, - {"SPOLP", NULL, "SPOL MIX"}, - {"SPOLN", NULL, "SPOL MIX"}, - {"SPORP", NULL, "SPOR MIX"}, - {"SPORN", NULL, "SPOR MIX"}, + {"Speaker L Playback", "Switch", "SPOL MIX"}, + {"Speaker R Playback", "Switch", "SPOR MIX"}, + {"SPOLP", NULL, "Speaker L Playback"}, + {"SPOLN", NULL, "Speaker L Playback"}, + {"SPORP", NULL, "Speaker R Playback"}, + {"SPORN", NULL, "Speaker R Playback"}, {"SPOLP", NULL, "Improve SPK Amp Drv"}, {"SPOLN", NULL, "Improve SPK Amp Drv"}, @@ -1412,8 +1523,10 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"HPOL", NULL, "Improve HP Amp Drv"}, {"HPOR", NULL, "Improve HP Amp Drv"}, - {"HPOL", NULL, "HP L Amp"}, - {"HPOR", NULL, "HP R Amp"}, + {"HP L Playback", "Switch", "HP Amp"}, + {"HP R Playback", "Switch", "HP Amp"}, + {"HPOL", NULL, "HP L Playback"}, + {"HPOR", NULL, "HP R Playback"}, {"LOUTL", NULL, "LOUT MIX"}, {"LOUTR", NULL, "LOUT MIX"}, {"MONOP", NULL, "Mono MIX"}, @@ -1792,17 +1905,13 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, RT5640_PWR_BG | RT5640_PWR_VREF2, RT5640_PWR_VREF1 | RT5640_PWR_MB | RT5640_PWR_BG | RT5640_PWR_VREF2); - mdelay(10); + usleep_range(10000, 15000); snd_soc_update_bits(codec, RT5640_PWR_ANLG1, RT5640_PWR_FV1 | RT5640_PWR_FV2, RT5640_PWR_FV1 | RT5640_PWR_FV2); regcache_sync(rt5640->regmap); snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); - snd_soc_update_bits(codec, RT5640_DEPOP_M1, - 0x001d, 0x0019); - snd_soc_update_bits(codec, RT5640_DEPOP_M2, - 0x2000, 0x2000); snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); } @@ -1846,8 +1955,6 @@ static int rt5640_probe(struct snd_soc_codec *codec) rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); - snd_soc_update_bits(codec, RT5640_DEPOP_M1, 0x001d, 0x0019); - snd_soc_update_bits(codec, RT5640_DEPOP_M2, 0x2000, 0x2000); snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); @@ -2069,6 +2176,8 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, RT5640_IN_DF2, RT5640_IN_DF2); + rt5640->hp_mute = 1; + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, rt5640_dai, ARRAY_SIZE(rt5640_dai)); if (ret < 0) diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index c48286d7118f..5e8df25a13f3 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -145,6 +145,8 @@ /* Index of Codec Private Register definition */ +#define RT5640_CHPUMP_INT_REG1 0x24 +#define RT5640_MAMP_INT_REG2 0x37 #define RT5640_3D_SPK 0x63 #define RT5640_WND_1 0x6c #define RT5640_WND_2 0x6d @@ -153,6 +155,7 @@ #define RT5640_WND_5 0x70 #define RT5640_WND_8 0x73 #define RT5640_DIP_SPK_INF 0x75 +#define RT5640_HP_DCC_INT1 0x77 #define RT5640_EQ_BW_LOP 0xa0 #define RT5640_EQ_GN_LOP 0xa1 #define RT5640_EQ_FC_BP1 0xa2 @@ -1201,6 +1204,14 @@ #define RT5640_CP_FQ2_SFT 4 #define RT5640_CP_FQ3_MASK (0x7) #define RT5640_CP_FQ3_SFT 0 +#define RT5640_CP_FQ_1_5_KHZ 0 +#define RT5640_CP_FQ_3_KHZ 1 +#define RT5640_CP_FQ_6_KHZ 2 +#define RT5640_CP_FQ_12_KHZ 3 +#define RT5640_CP_FQ_24_KHZ 4 +#define RT5640_CP_FQ_48_KHZ 5 +#define RT5640_CP_FQ_96_KHZ 6 +#define RT5640_CP_FQ_192_KHZ 7 /* HPOUT charge pump (0x91) */ #define RT5640_OSW_L_MASK (0x1 << 11) @@ -2087,6 +2098,7 @@ struct rt5640_priv { int pll_out; int dmic_en; + bool hp_mute; }; #endif diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index f8d30e5f6371..492644e67ace 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -561,8 +561,9 @@ static int ssm2602_suspend(struct snd_soc_codec *codec) static int ssm2602_resume(struct snd_soc_codec *codec) { - snd_soc_cache_sync(codec); + struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); + regcache_sync(ssm2602->regmap); ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index e2aaff717f8a..8db705b0fdf9 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -45,7 +45,7 @@ snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o snd-soc-wm1133-ev1-objs := wm1133-ev1.o snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o snd-soc-imx-wm8962-objs := imx-wm8962.o -snd-soc-imx-spdif-objs :=imx-spdif.o +snd-soc-imx-spdif-objs := imx-spdif.o snd-soc-imx-mc13783-objs := imx-mc13783.o obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index e93dc0dfb0d9..3920c3e849ce 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -411,8 +411,8 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream, return 0; } -int fsl_spdif_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *cpu_dai) +static int fsl_spdif_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); @@ -546,7 +546,7 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream, return 0; } -struct snd_soc_dai_ops fsl_spdif_dai_ops = { +static struct snd_soc_dai_ops fsl_spdif_dai_ops = { .startup = fsl_spdif_startup, .hw_params = fsl_spdif_hw_params, .trigger = fsl_spdif_trigger, @@ -919,7 +919,7 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai) return 0; } -struct snd_soc_dai_driver fsl_spdif_dai = { +static struct snd_soc_dai_driver fsl_spdif_dai = { .probe = &fsl_spdif_dai_probe, .playback = { .channels_min = 2, @@ -1071,9 +1071,9 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, break; } - dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate", + dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n", spdif_priv->txclk_src[index], rate[index]); - dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate", + dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate\n", spdif_priv->txclk_div[index], rate[index]); return 0; diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index ce084eb10c49..4bb273786ff3 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -105,11 +105,13 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { .stream_name = "HiFi Playback", .codec_dai_name = "sgtl5000", .ops = &mxs_sgtl5000_hifi_ops, + .playback_only = true, }, { .name = "HiFi Rx", .stream_name = "HiFi Capture", .codec_dai_name = "sgtl5000", .ops = &mxs_sgtl5000_hifi_ops, + .capture_only = true, }, }; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 548b1c9e875e..c17c14c394df 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -229,6 +229,8 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, template.id = snd_soc_dapm_kcontrol; template.name = kcontrol->id.name; + data->value = template.on_val; + data->widget = snd_soc_dapm_new_control(widget->dapm, &template); if (!data->widget) { diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index fb70fbe26862..330c9a6b5cb5 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2020,6 +2020,16 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) capture = 1; } + if (rtd->dai_link->playback_only) { + playback = 1; + capture = 0; + } + + if (rtd->dai_link->capture_only) { + playback = 0; + capture = 1; + } + /* create the PCM */ if (rtd->dai_link->no_pcm) { snprintf(new_name, sizeof(new_name), "(%s)", |