aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r--sound/usb/mixer.c75
1 files changed, 47 insertions, 28 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 43bc59575a6e..6e7bac8203ba 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -361,9 +361,8 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
memset(buf, 0, sizeof(buf));
- ret = snd_usb_lock_shutdown(chip) ? -EIO : 0;
- if (ret)
- goto error;
+ if (snd_usb_lock_shutdown(chip))
+ return -EIO;
idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
@@ -372,8 +371,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
snd_usb_unlock_shutdown(chip);
if (ret < 0) {
-error:
- usb_audio_err(chip,
+ usb_audio_dbg(chip,
"cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
request, validx, idx, cval->val_type);
return ret;
@@ -1198,15 +1196,42 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
cval->res = 1;
}
break;
+ case USB_ID(0x1224, 0x2a25): /* Jieli Technology USB PHY 2.0 */
+ if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
+ usb_audio_info(chip,
+ "set resolution quirk: cval->res = 16\n");
+ cval->res = 16;
+ }
+ break;
}
}
+/* forcibly initialize the current mixer value; if GET_CUR fails, set to
+ * the minimum as default
+ */
+static void init_cur_mix_raw(struct usb_mixer_elem_info *cval, int ch, int idx)
+{
+ int val, err;
+
+ err = snd_usb_get_cur_mix_value(cval, ch, idx, &val);
+ if (!err)
+ return;
+ if (!cval->head.mixer->ignore_ctl_error)
+ usb_audio_warn(cval->head.mixer->chip,
+ "%d:%d: failed to get current value for ch %d (%d)\n",
+ cval->head.id, mixer_ctrl_intf(cval->head.mixer),
+ ch, err);
+ snd_usb_set_cur_mix_value(cval, ch, idx, cval->min);
+}
+
/*
* retrieve the minimum and maximum values for the specified control
*/
static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
int default_min, struct snd_kcontrol *kctl)
{
+ int i, idx;
+
/* for failsafe */
cval->min = default_min;
cval->max = cval->min + 1;
@@ -1219,7 +1244,6 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
} else {
int minchn = 0;
if (cval->cmask) {
- int i;
for (i = 0; i < MAX_CHANNELS; i++)
if (cval->cmask & (1 << i)) {
minchn = i + 1;
@@ -1320,6 +1344,19 @@ no_res_check:
}
}
+ /* initialize all elements */
+ if (!cval->cmask) {
+ init_cur_mix_raw(cval, 0, 0);
+ } else {
+ idx = 0;
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (cval->cmask & (1 << i)) {
+ init_cur_mix_raw(cval, i + 1, idx);
+ idx++;
+ }
+ }
+ }
+
return 0;
}
@@ -3653,33 +3690,16 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
return 0;
}
-static int default_mixer_reset_resume(struct usb_mixer_elem_list *list)
-{
- int err;
-
- if (list->resume) {
- err = list->resume(list);
- if (err < 0)
- return err;
- }
- return restore_mixer_value(list);
-}
-
-int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
+int snd_usb_mixer_resume(struct usb_mixer_interface *mixer)
{
struct usb_mixer_elem_list *list;
- usb_mixer_elem_resume_func_t f;
int id, err;
/* restore cached mixer values */
for (id = 0; id < MAX_ID_ELEMS; id++) {
for_each_mixer_elem(list, mixer, id) {
- if (reset_resume)
- f = list->reset_resume;
- else
- f = list->resume;
- if (f) {
- err = f(list);
+ if (list->resume) {
+ err = list->resume(list);
if (err < 0)
return err;
}
@@ -3700,7 +3720,6 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
list->id = unitid;
list->dump = snd_usb_mixer_dump_cval;
#ifdef CONFIG_PM
- list->resume = NULL;
- list->reset_resume = default_mixer_reset_resume;
+ list->resume = restore_mixer_value;
#endif
}