diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/soc-core.c | 35 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 1 |
2 files changed, 33 insertions, 3 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 91d592ff67b7..2370063b5824 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1255,6 +1255,8 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1255 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); | 1255 | INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients); |
1256 | ret = device_add(rtd->dev); | 1256 | ret = device_add(rtd->dev); |
1257 | if (ret < 0) { | 1257 | if (ret < 0) { |
1258 | /* calling put_device() here to free the rtd->dev */ | ||
1259 | put_device(rtd->dev); | ||
1258 | dev_err(card->dev, | 1260 | dev_err(card->dev, |
1259 | "ASoC: failed to register runtime device: %d\n", ret); | 1261 | "ASoC: failed to register runtime device: %d\n", ret); |
1260 | return ret; | 1262 | return ret; |
@@ -1554,7 +1556,7 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) | |||
1554 | /* unregister the rtd device */ | 1556 | /* unregister the rtd device */ |
1555 | if (rtd->dev_registered) { | 1557 | if (rtd->dev_registered) { |
1556 | device_remove_file(rtd->dev, &dev_attr_codec_reg); | 1558 | device_remove_file(rtd->dev, &dev_attr_codec_reg); |
1557 | device_del(rtd->dev); | 1559 | device_unregister(rtd->dev); |
1558 | rtd->dev_registered = 0; | 1560 | rtd->dev_registered = 0; |
1559 | } | 1561 | } |
1560 | 1562 | ||
@@ -2917,7 +2919,7 @@ int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, | |||
2917 | platform_max = mc->platform_max; | 2919 | platform_max = mc->platform_max; |
2918 | 2920 | ||
2919 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2921 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2920 | uinfo->count = 1; | 2922 | uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; |
2921 | uinfo->value.integer.min = 0; | 2923 | uinfo->value.integer.min = 0; |
2922 | uinfo->value.integer.max = platform_max - min; | 2924 | uinfo->value.integer.max = platform_max - min; |
2923 | 2925 | ||
@@ -2941,12 +2943,14 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | |||
2941 | (struct soc_mixer_control *)kcontrol->private_value; | 2943 | (struct soc_mixer_control *)kcontrol->private_value; |
2942 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2944 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2943 | unsigned int reg = mc->reg; | 2945 | unsigned int reg = mc->reg; |
2946 | unsigned int rreg = mc->rreg; | ||
2944 | unsigned int shift = mc->shift; | 2947 | unsigned int shift = mc->shift; |
2945 | int min = mc->min; | 2948 | int min = mc->min; |
2946 | int max = mc->max; | 2949 | int max = mc->max; |
2947 | unsigned int mask = (1 << fls(max)) - 1; | 2950 | unsigned int mask = (1 << fls(max)) - 1; |
2948 | unsigned int invert = mc->invert; | 2951 | unsigned int invert = mc->invert; |
2949 | unsigned int val, val_mask; | 2952 | unsigned int val, val_mask; |
2953 | int ret; | ||
2950 | 2954 | ||
2951 | val = ((ucontrol->value.integer.value[0] + min) & mask); | 2955 | val = ((ucontrol->value.integer.value[0] + min) & mask); |
2952 | if (invert) | 2956 | if (invert) |
@@ -2954,7 +2958,21 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | |||
2954 | val_mask = mask << shift; | 2958 | val_mask = mask << shift; |
2955 | val = val << shift; | 2959 | val = val << shift; |
2956 | 2960 | ||
2957 | return snd_soc_update_bits_locked(codec, reg, val_mask, val); | 2961 | ret = snd_soc_update_bits_locked(codec, reg, val_mask, val); |
2962 | if (ret != 0) | ||
2963 | return ret; | ||
2964 | |||
2965 | if (snd_soc_volsw_is_stereo(mc)) { | ||
2966 | val = ((ucontrol->value.integer.value[1] + min) & mask); | ||
2967 | if (invert) | ||
2968 | val = max - val; | ||
2969 | val_mask = mask << shift; | ||
2970 | val = val << shift; | ||
2971 | |||
2972 | ret = snd_soc_update_bits_locked(codec, rreg, val_mask, val); | ||
2973 | } | ||
2974 | |||
2975 | return ret; | ||
2958 | } | 2976 | } |
2959 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); | 2977 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); |
2960 | 2978 | ||
@@ -2974,6 +2992,7 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | |||
2974 | (struct soc_mixer_control *)kcontrol->private_value; | 2992 | (struct soc_mixer_control *)kcontrol->private_value; |
2975 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2993 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2976 | unsigned int reg = mc->reg; | 2994 | unsigned int reg = mc->reg; |
2995 | unsigned int rreg = mc->rreg; | ||
2977 | unsigned int shift = mc->shift; | 2996 | unsigned int shift = mc->shift; |
2978 | int min = mc->min; | 2997 | int min = mc->min; |
2979 | int max = mc->max; | 2998 | int max = mc->max; |
@@ -2988,6 +3007,16 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | |||
2988 | ucontrol->value.integer.value[0] = | 3007 | ucontrol->value.integer.value[0] = |
2989 | ucontrol->value.integer.value[0] - min; | 3008 | ucontrol->value.integer.value[0] - min; |
2990 | 3009 | ||
3010 | if (snd_soc_volsw_is_stereo(mc)) { | ||
3011 | ucontrol->value.integer.value[1] = | ||
3012 | (snd_soc_read(codec, rreg) >> shift) & mask; | ||
3013 | if (invert) | ||
3014 | ucontrol->value.integer.value[1] = | ||
3015 | max - ucontrol->value.integer.value[1]; | ||
3016 | ucontrol->value.integer.value[1] = | ||
3017 | ucontrol->value.integer.value[1] - min; | ||
3018 | } | ||
3019 | |||
2991 | return 0; | 3020 | return 0; |
2992 | } | 3021 | } |
2993 | EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); | 3022 | EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index d7711fce119b..cf191e6aebbe 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -1243,6 +1243,7 @@ static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) | |||
1243 | if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && | 1243 | if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && |
1244 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && | 1244 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && |
1245 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && | 1245 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && |
1246 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) && | ||
1246 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) | 1247 | (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) |
1247 | continue; | 1248 | continue; |
1248 | 1249 | ||