|
@@ -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);
|