diff options
Diffstat (limited to 'sound/soc/soc-core.c')
| -rw-r--r-- | sound/soc/soc-core.c | 35 | 
1 files changed, 32 insertions, 3 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 91d592ff67b..2370063b582 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,  	INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);  	ret = device_add(rtd->dev);  	if (ret < 0) { +		/* calling put_device() here to free the rtd->dev */ +		put_device(rtd->dev);  		dev_err(card->dev,  			"ASoC: failed to register runtime device: %d\n", ret);  		return ret; @@ -1554,7 +1556,7 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)  	/* unregister the rtd device */  	if (rtd->dev_registered) {  		device_remove_file(rtd->dev, &dev_attr_codec_reg); -		device_del(rtd->dev); +		device_unregister(rtd->dev);  		rtd->dev_registered = 0;  	} @@ -2917,7 +2919,7 @@ int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol,  	platform_max = mc->platform_max;  	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; -	uinfo->count = 1; +	uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;  	uinfo->value.integer.min = 0;  	uinfo->value.integer.max = platform_max - min; @@ -2941,12 +2943,14 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,  		(struct soc_mixer_control *)kcontrol->private_value;  	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);  	unsigned int reg = mc->reg; +	unsigned int rreg = mc->rreg;  	unsigned int shift = mc->shift;  	int min = mc->min;  	int max = mc->max;  	unsigned int mask = (1 << fls(max)) - 1;  	unsigned int invert = mc->invert;  	unsigned int val, val_mask; +	int ret;  	val = ((ucontrol->value.integer.value[0] + min) & mask);  	if (invert) @@ -2954,7 +2958,21 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,  	val_mask = mask << shift;  	val = val << shift; -	return snd_soc_update_bits_locked(codec, reg, val_mask, val); +	ret = snd_soc_update_bits_locked(codec, reg, val_mask, val); +	if (ret != 0) +		return ret; + +	if (snd_soc_volsw_is_stereo(mc)) { +		val = ((ucontrol->value.integer.value[1] + min) & mask); +		if (invert) +			val = max - val; +		val_mask = mask << shift; +		val = val << shift; + +		ret = snd_soc_update_bits_locked(codec, rreg, val_mask, val); +	} + +	return ret;  }  EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); @@ -2974,6 +2992,7 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,  		(struct soc_mixer_control *)kcontrol->private_value;  	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);  	unsigned int reg = mc->reg; +	unsigned int rreg = mc->rreg;  	unsigned int shift = mc->shift;  	int min = mc->min;  	int max = mc->max; @@ -2988,6 +3007,16 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,  	ucontrol->value.integer.value[0] =  		ucontrol->value.integer.value[0] - min; +	if (snd_soc_volsw_is_stereo(mc)) { +		ucontrol->value.integer.value[1] = +			(snd_soc_read(codec, rreg) >> shift) & mask; +		if (invert) +			ucontrol->value.integer.value[1] = +				max - ucontrol->value.integer.value[1]; +		ucontrol->value.integer.value[1] = +			ucontrol->value.integer.value[1] - min; +	} +  	return 0;  }  EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range);  |