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 { ...@@ -136,6 +136,8 @@ struct snd_usb_audio {
struct list_head midi_list; /* list of midi interfaces */ struct list_head midi_list; /* list of midi interfaces */
int next_midi_device; 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 ...@@ -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++) { for (c = 0; c < MAX_CHANNELS; c++) {
if (cval->cmask & (1 << c)) { if (cval->cmask & (1 << c)) {
err = get_cur_mix_value(cval, c + 1, &val); 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 (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); snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n", cval->control, c + 1, err);
return err; return err;
} }
...@@ -685,13 +683,11 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t ...@@ -685,13 +683,11 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
} else { } else {
/* master channel */ /* master channel */
err = get_cur_mix_value(cval, 0, &val); 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 (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); snd_printd(KERN_ERR "cannot get current value for control %d master ch: err = %d\n", cval->control, err);
return err; return err;
} }
...@@ -713,12 +709,11 @@ static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t ...@@ -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++) { for (c = 0; c < MAX_CHANNELS; c++) {
if (cval->cmask & (1 << c)) { if (cval->cmask & (1 << c)) {
err = get_cur_mix_value(cval, c + 1, &oval); err = get_cur_mix_value(cval, c + 1, &oval);
#ifdef IGNORE_CTL_ERROR if (err < 0) {
if (err < 0) if (cval->chip->ignore_ctl_error)
return 0; return 0;
#endif
if (err < 0)
return err; return err;
}
val = ucontrol->value.integer.value[cnt]; val = ucontrol->value.integer.value[cnt];
val = get_abs_value(cval, val); val = get_abs_value(cval, val);
if (oval != val) { if (oval != val) {
...@@ -732,10 +727,8 @@ static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t ...@@ -732,10 +727,8 @@ static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
} else { } else {
/* master channel */ /* master channel */
err = get_cur_mix_value(cval, 0, &oval); err = get_cur_mix_value(cval, 0, &oval);
#ifdef IGNORE_CTL_ERROR if (err < 0 && cval->chip->ignore_ctl_error)
if (err < 0)
return 0; return 0;
#endif
if (err < 0) if (err < 0)
return err; return err;
val = ucontrol->value.integer.value[0]; 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 ...@@ -1025,12 +1018,10 @@ static int mixer_ctl_procunit_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int err, val; int err, val;
err = get_cur_ctl_value(cval, cval->control << 8, &val); err = get_cur_ctl_value(cval, cval->control << 8, &val);
#ifdef IGNORE_CTL_ERROR if (err < 0 && cval->chip->ignore_ctl_error) {
if (err < 0) {
ucontrol->value.integer.value[0] = cval->min; ucontrol->value.integer.value[0] = cval->min;
return 0; return 0;
} }
#endif
if (err < 0) if (err < 0)
return err; return err;
val = get_relative_value(cval, val); 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 ...@@ -1045,12 +1036,11 @@ static int mixer_ctl_procunit_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int val, oval, err; int val, oval, err;
err = get_cur_ctl_value(cval, cval->control << 8, &oval); err = get_cur_ctl_value(cval, cval->control << 8, &oval);
#ifdef IGNORE_CTL_ERROR if (err < 0) {
if (err < 0) if (cval->chip->ignore_ctl_error)
return 0; return 0;
#endif
if (err < 0)
return err; return err;
}
val = ucontrol->value.integer.value[0]; val = ucontrol->value.integer.value[0];
val = get_abs_value(cval, val); val = get_abs_value(cval, val);
if (val != oval) { if (val != oval) {
...@@ -1274,14 +1264,13 @@ static int mixer_ctl_selector_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t ...@@ -1274,14 +1264,13 @@ static int mixer_ctl_selector_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int val, err; int val, err;
err = get_cur_ctl_value(cval, 0, &val); err = get_cur_ctl_value(cval, 0, &val);
#ifdef IGNORE_CTL_ERROR
if (err < 0) { if (err < 0) {
ucontrol->value.enumerated.item[0] = 0; if (cval->chip->ignore_ctl_error) {
return 0; ucontrol->value.enumerated.item[0] = 0;
} return 0;
#endif }
if (err < 0)
return err; return err;
}
val = get_relative_value(cval, val); val = get_relative_value(cval, val);
ucontrol->value.enumerated.item[0] = val; ucontrol->value.enumerated.item[0] = val;
return 0; return 0;
...@@ -1294,12 +1283,11 @@ static int mixer_ctl_selector_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t ...@@ -1294,12 +1283,11 @@ static int mixer_ctl_selector_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
int val, oval, err; int val, oval, err;
err = get_cur_ctl_value(cval, 0, &oval); err = get_cur_ctl_value(cval, 0, &oval);
#ifdef IGNORE_CTL_ERROR if (err < 0) {
if (err < 0) if (cval->chip->ignore_ctl_error)
return 0; return 0;
#endif
if (err < 0)
return err; return err;
}
val = ucontrol->value.enumerated.item[0]; val = ucontrol->value.enumerated.item[0];
val = get_abs_value(cval, val); val = get_abs_value(cval, val);
if (val != oval) { if (val != oval) {
...@@ -1509,9 +1497,13 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif) ...@@ -1509,9 +1497,13 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
for (map = usbmix_ctl_maps; map->vendor; map++) { for (map = usbmix_ctl_maps; map->vendor; map++) {
if (map->vendor == dev->idVendor && map->product == dev->idProduct) { if (map->vendor == dev->idVendor && map->product == dev->idProduct) {
state.map = map->map; state.map = map->map;
chip->ignore_ctl_error = map->ignore_ctl_error;
break; break;
} }
} }
#ifdef IGNORE_CTL_ERROR
chip->ignore_ctl_error = 1;
#endif
desc = NULL; desc = NULL;
while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) { while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) {
......
...@@ -30,6 +30,7 @@ struct usbmix_ctl_map { ...@@ -30,6 +30,7 @@ struct usbmix_ctl_map {
int vendor; int vendor;
int product; int product;
const struct usbmix_name_map *map; const struct usbmix_name_map *map;
int ignore_ctl_error;
}; };
/* /*
...@@ -86,6 +87,7 @@ static struct usbmix_name_map extigy_map[] = { ...@@ -86,6 +87,7 @@ static struct usbmix_name_map extigy_map[] = {
{ 26, "IEC958 Optical Playback" }, /* OT */ { 26, "IEC958 Optical Playback" }, /* OT */
{ 27, NULL }, /* DISABLED: EU (for what?) */ { 27, NULL }, /* DISABLED: EU (for what?) */
/* 28: FU speaker (mute) */ /* 28: FU speaker (mute) */
{ 29, NULL }, /* Digital Input Playback Source? */
{ 0 } /* terminator */ { 0 } /* terminator */
}; };
...@@ -117,8 +119,8 @@ static struct usbmix_name_map justlink_map[] = { ...@@ -117,8 +119,8 @@ static struct usbmix_name_map justlink_map[] = {
*/ */
static struct usbmix_ctl_map usbmix_ctl_maps[] = { static struct usbmix_ctl_map usbmix_ctl_maps[] = {
{ 0x41e, 0x3000, extigy_map }, { 0x41e, 0x3000, extigy_map, 1 },
{ 0xc45, 0x1158, justlink_map }, { 0xc45, 0x1158, justlink_map, 0 },
{ 0 } /* terminator */ { 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