Commit ae60f73d authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA CVS update - Takashi Iwai <tiwai@suse.de>

USB generic driver
added fix and workaround for the mixer problem on SB Extigy.
parent 9d15370b
......@@ -136,6 +136,8 @@ struct snd_usb_audio {
struct list_head midi_list; /* list of midi interfaces */
int next_midi_device;
unsigned int ignore_ctl_error; /* for mixer */
};
/*
......
......@@ -667,13 +667,11 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
for (c = 0; c < MAX_CHANNELS; c++) {
if (cval->cmask & (1 << c)) {
err = get_cur_mix_value(cval, c + 1, &val);
#ifdef IGNORE_CTL_ERROR
if (err < 0) {
ucontrol->value.integer.value[0] = cval->min;
return 0;
}
#endif
if (err < 0) {
if (cval->chip->ignore_ctl_error) {
ucontrol->value.integer.value[0] = cval->min;
return 0;
}
snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n", cval->control, c + 1, err);
return err;
}
......@@ -685,13 +683,11 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
} else {
/* master channel */
err = get_cur_mix_value(cval, 0, &val);
#ifdef IGNORE_CTL_ERROR
if (err < 0) {
ucontrol->value.integer.value[0] = cval->min;
return 0;
}
#endif
if (err < 0) {
if (cval->chip->ignore_ctl_error) {
ucontrol->value.integer.value[0] = cval->min;
return 0;
}
snd_printd(KERN_ERR "cannot get current value for control %d master ch: err = %d\n", cval->control, err);
return err;
}
......@@ -713,12 +709,11 @@ static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
for (c = 0; c < MAX_CHANNELS; c++) {
if (cval->cmask & (1 << c)) {
err = get_cur_mix_value(cval, c + 1, &oval);
#ifdef IGNORE_CTL_ERROR
if (err < 0)
return 0;
#endif
if (err < 0)
if (err < 0) {
if (cval->chip->ignore_ctl_error)
return 0;
return err;
}
val = ucontrol->value.integer.value[cnt];
val = get_abs_value(cval, val);
if (oval != val) {
......@@ -732,10 +727,8 @@ static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
} else {
/* master channel */
err = get_cur_mix_value(cval, 0, &oval);
#ifdef IGNORE_CTL_ERROR
if (err < 0)
if (err < 0 && cval->chip->ignore_ctl_error)
return 0;
#endif
if (err < 0)
return err;
val = ucontrol->value.integer.value[0];
......@@ -1025,12 +1018,10 @@ static int mixer_ctl_procunit_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int err, val;
err = get_cur_ctl_value(cval, cval->control << 8, &val);
#ifdef IGNORE_CTL_ERROR
if (err < 0) {
if (err < 0 && cval->chip->ignore_ctl_error) {
ucontrol->value.integer.value[0] = cval->min;
return 0;
}
#endif
if (err < 0)
return err;
val = get_relative_value(cval, val);
......@@ -1045,12 +1036,11 @@ static int mixer_ctl_procunit_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int val, oval, err;
err = get_cur_ctl_value(cval, cval->control << 8, &oval);
#ifdef IGNORE_CTL_ERROR
if (err < 0)
return 0;
#endif
if (err < 0)
if (err < 0) {
if (cval->chip->ignore_ctl_error)
return 0;
return err;
}
val = ucontrol->value.integer.value[0];
val = get_abs_value(cval, val);
if (val != oval) {
......@@ -1274,14 +1264,13 @@ static int mixer_ctl_selector_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int val, err;
err = get_cur_ctl_value(cval, 0, &val);
#ifdef IGNORE_CTL_ERROR
if (err < 0) {
ucontrol->value.enumerated.item[0] = 0;
return 0;
}
#endif
if (err < 0)
if (cval->chip->ignore_ctl_error) {
ucontrol->value.enumerated.item[0] = 0;
return 0;
}
return err;
}
val = get_relative_value(cval, val);
ucontrol->value.enumerated.item[0] = val;
return 0;
......@@ -1294,12 +1283,11 @@ static int mixer_ctl_selector_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int val, oval, err;
err = get_cur_ctl_value(cval, 0, &oval);
#ifdef IGNORE_CTL_ERROR
if (err < 0)
return 0;
#endif
if (err < 0)
if (err < 0) {
if (cval->chip->ignore_ctl_error)
return 0;
return err;
}
val = ucontrol->value.enumerated.item[0];
val = get_abs_value(cval, val);
if (val != oval) {
......@@ -1509,9 +1497,13 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
for (map = usbmix_ctl_maps; map->vendor; map++) {
if (map->vendor == dev->idVendor && map->product == dev->idProduct) {
state.map = map->map;
chip->ignore_ctl_error = map->ignore_ctl_error;
break;
}
}
#ifdef IGNORE_CTL_ERROR
chip->ignore_ctl_error = 1;
#endif
desc = NULL;
while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) {
......
......@@ -30,6 +30,7 @@ struct usbmix_ctl_map {
int vendor;
int product;
const struct usbmix_name_map *map;
int ignore_ctl_error;
};
/*
......@@ -86,6 +87,7 @@ static struct usbmix_name_map extigy_map[] = {
{ 26, "IEC958 Optical Playback" }, /* OT */
{ 27, NULL }, /* DISABLED: EU (for what?) */
/* 28: FU speaker (mute) */
{ 29, NULL }, /* Digital Input Playback Source? */
{ 0 } /* terminator */
};
......@@ -117,8 +119,8 @@ static struct usbmix_name_map justlink_map[] = {
*/
static struct usbmix_ctl_map usbmix_ctl_maps[] = {
{ 0x41e, 0x3000, extigy_map },
{ 0xc45, 0x1158, justlink_map },
{ 0x41e, 0x3000, extigy_map, 1 },
{ 0xc45, 0x1158, justlink_map, 0 },
{ 0 } /* terminator */
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment