Sound fixes for 3.9-rc3
A collection of small fixes, as expected for the middle rc: - A couple of fixes for potential NULL dereferences and out-of-range array accesses revealed by static code parsers - A fix for the wrong error handling detected by trinity - A regression fix for missing audio on some MacBooks - CA0132 DSP loader fixes - Fix for EAPD control of IDT codecs on machines w/o speaker - Fix a regression in the HD-audio widget list parser code - Workaround for the NuForce UDH-100 USB audio -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJRQyORAAoJEGwxgFQ9KSmkbvkP/0WEasiViZWqKOFfDTJ4TMEt OI53hJKE4mr+/mitVxlQdhZ2r6q+aWRxFxq0i81uL3oB6FHHzxt+7O1P+hAC9p9Z M4Q0/mgPoosTyWGKQUmnJvhe13qxft4LhGs8t9A1twsb3AfIEbZsTtnFq+blQJQO RPWCSDIVdk1vldFHFhne3IM7SweCjqoPbfpY3dwFPKA1DeA0F6OUcsriWbNJLFys mv4U0XZUlkDK4MAMU6r6ksT7KwqOq2bUkJYhXGPq4kAV88oEpPKaz0BUh2nKA872 N2EjQ7y7vkeW1zwX9DvtXCCNZt+3FeA2xHrGLPmMR8Uv/W/dwyEp08LvaBJyCcmt iuWSg+Y4ayiXbsm5YoIbx5OnNZExZAxchDpFxD+IMY9Oa1V3IUs8Q5ppO/nuEqjI O46ERVltTO4LHg+5/oVz78ASK1qp+MFymxxnQtXH7eZgbjYI8nQtTCnMi/tH+gBq KUX3ejn/gD4L0CCRZ9u4ynALbFL7MNOV9HsZi1O8UeZwGYMwgbNmeQCqlLgloTaI cagaNELLU3hcJQZnS0csz2ak9wlJbl2ud9O4l8u1UUBStiTtTDaf0eyh81GcQvYp A4Fv/RzI3iQiWpr7smVPOOXggRAMAojQKcMLM4gliHj2vuu1B0zIPOF4iJWjcIIV hxPD29F6FoB/TccjNE77 =Zc4C -----END PGP SIGNATURE----- Merge tag 'sound-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A collection of small fixes, as expected for the middle rc: - A couple of fixes for potential NULL dereferences and out-of-range array accesses revealed by static code parsers - A fix for the wrong error handling detected by trinity - A regression fix for missing audio on some MacBooks - CA0132 DSP loader fixes - Fix for EAPD control of IDT codecs on machines w/o speaker - Fix a regression in the HD-audio widget list parser code - Workaround for the NuForce UDH-100 USB audio" * tag 'sound-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - Fix missing EAPD/GPIO setup for Cirrus codecs sound: sequencer: cap array index in seq_chn_common_event() ALSA: hda/ca0132 - Remove extra setting of dsp_state. ALSA: hda/ca0132 - Check download state of DSP. ALSA: hda/ca0132 - Check if dspload_image succeeded. ALSA: hda - Disable IDT eapd_switch if there are no internal speakers ALSA: hda - Fix snd_hda_get_num_raw_conns() to return a correct value ALSA: usb-audio: add a workaround for the NuForce UDH-100 ALSA: asihpi - fix potential NULL pointer dereference ALSA: seq: Fix missing error handling in snd_seq_timer_open()
This commit is contained in:
commit
5cd8846c3b
|
@ -290,10 +290,10 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
|
|||
tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
|
||||
err = snd_timer_open(&t, str, &tid, q->queue);
|
||||
}
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
|
||||
return err;
|
||||
}
|
||||
t->callback = snd_seq_timer_interrupt;
|
||||
t->callback_data = q;
|
||||
|
|
|
@ -545,6 +545,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
|
|||
case MIDI_PGM_CHANGE:
|
||||
if (seq_mode == SEQ_2)
|
||||
{
|
||||
if (chn > 15)
|
||||
break;
|
||||
|
||||
synth_devs[dev]->chn_info[chn].pgm_num = p1;
|
||||
if ((int) dev >= num_synths)
|
||||
synth_devs[dev]->set_instr(dev, chn, p1);
|
||||
|
@ -596,6 +599,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
|
|||
case MIDI_PITCH_BEND:
|
||||
if (seq_mode == SEQ_2)
|
||||
{
|
||||
if (chn > 15)
|
||||
break;
|
||||
|
||||
synth_devs[dev]->chn_info[chn].bender_value = w14;
|
||||
|
||||
if ((int) dev < num_synths)
|
||||
|
|
|
@ -2549,7 +2549,7 @@ static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
|
|||
|
||||
static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
|
||||
{
|
||||
struct snd_card *card = asihpi->card;
|
||||
struct snd_card *card;
|
||||
unsigned int idx = 0;
|
||||
unsigned int subindex = 0;
|
||||
int err;
|
||||
|
@ -2557,6 +2557,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
|
|||
|
||||
if (snd_BUG_ON(!asihpi))
|
||||
return -EINVAL;
|
||||
card = asihpi->card;
|
||||
strcpy(card->mixername, "Asihpi Mixer");
|
||||
|
||||
err =
|
||||
|
|
|
@ -494,7 +494,7 @@ static unsigned int get_num_conns(struct hda_codec *codec, hda_nid_t nid)
|
|||
|
||||
int snd_hda_get_num_raw_conns(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
return get_num_conns(codec, nid) & AC_CLIST_LENGTH;
|
||||
return snd_hda_get_raw_connections(codec, nid, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -517,9 +517,6 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
|
|||
hda_nid_t prev_nid;
|
||||
int null_count = 0;
|
||||
|
||||
if (snd_BUG_ON(!conn_list || max_conns <= 0))
|
||||
return -EINVAL;
|
||||
|
||||
parm = get_num_conns(codec, nid);
|
||||
if (!parm)
|
||||
return 0;
|
||||
|
@ -545,7 +542,8 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
|
|||
AC_VERB_GET_CONNECT_LIST, 0);
|
||||
if (parm == -1 && codec->bus->rirb_error)
|
||||
return -EIO;
|
||||
conn_list[0] = parm & mask;
|
||||
if (conn_list)
|
||||
conn_list[0] = parm & mask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -580,14 +578,20 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
|
|||
continue;
|
||||
}
|
||||
for (n = prev_nid + 1; n <= val; n++) {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns++] = n;
|
||||
if (conn_list) {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns] = n;
|
||||
}
|
||||
conns++;
|
||||
}
|
||||
} else {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns++] = val;
|
||||
if (conn_list) {
|
||||
if (conns >= max_conns)
|
||||
return -ENOSPC;
|
||||
conn_list[conns] = val;
|
||||
}
|
||||
conns++;
|
||||
}
|
||||
prev_nid = val;
|
||||
}
|
||||
|
|
|
@ -3239,7 +3239,7 @@ static int ca0132_set_vipsource(struct hda_codec *codec, int val)
|
|||
struct ca0132_spec *spec = codec->spec;
|
||||
unsigned int tmp;
|
||||
|
||||
if (!dspload_is_loaded(codec))
|
||||
if (spec->dsp_state != DSP_DOWNLOADED)
|
||||
return 0;
|
||||
|
||||
/* if CrystalVoice if off, vipsource should be 0 */
|
||||
|
@ -4267,11 +4267,12 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec)
|
|||
*/
|
||||
static void ca0132_setup_defaults(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
unsigned int tmp;
|
||||
int num_fx;
|
||||
int idx, i;
|
||||
|
||||
if (!dspload_is_loaded(codec))
|
||||
if (spec->dsp_state != DSP_DOWNLOADED)
|
||||
return;
|
||||
|
||||
/* out, in effects + voicefx */
|
||||
|
@ -4351,12 +4352,16 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
|
|||
return false;
|
||||
|
||||
dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
|
||||
dspload_image(codec, dsp_os_image, 0, 0, true, 0);
|
||||
if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
|
||||
pr_err("ca0132 dspload_image failed.\n");
|
||||
goto exit_download;
|
||||
}
|
||||
|
||||
dsp_loaded = dspload_wait_loaded(codec);
|
||||
|
||||
exit_download:
|
||||
release_firmware(fw_entry);
|
||||
|
||||
|
||||
return dsp_loaded;
|
||||
}
|
||||
|
||||
|
@ -4367,16 +4372,13 @@ static void ca0132_download_dsp(struct hda_codec *codec)
|
|||
#ifndef CONFIG_SND_HDA_CODEC_CA0132_DSP
|
||||
return; /* NOP */
|
||||
#endif
|
||||
spec->dsp_state = DSP_DOWNLOAD_INIT;
|
||||
|
||||
if (spec->dsp_state == DSP_DOWNLOAD_INIT) {
|
||||
chipio_enable_clocks(codec);
|
||||
spec->dsp_state = DSP_DOWNLOADING;
|
||||
if (!ca0132_download_dsp_images(codec))
|
||||
spec->dsp_state = DSP_DOWNLOAD_FAILED;
|
||||
else
|
||||
spec->dsp_state = DSP_DOWNLOADED;
|
||||
}
|
||||
chipio_enable_clocks(codec);
|
||||
spec->dsp_state = DSP_DOWNLOADING;
|
||||
if (!ca0132_download_dsp_images(codec))
|
||||
spec->dsp_state = DSP_DOWNLOAD_FAILED;
|
||||
else
|
||||
spec->dsp_state = DSP_DOWNLOADED;
|
||||
|
||||
if (spec->dsp_state == DSP_DOWNLOADED)
|
||||
ca0132_set_dsp_msr(codec, true);
|
||||
|
|
|
@ -506,6 +506,8 @@ static int patch_cs420x(struct hda_codec *codec)
|
|||
if (!spec)
|
||||
return -ENOMEM;
|
||||
|
||||
spec->gen.automute_hook = cs_automute;
|
||||
|
||||
snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
|
||||
cs420x_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
@ -893,6 +895,8 @@ static int patch_cs4210(struct hda_codec *codec)
|
|||
if (!spec)
|
||||
return -ENOMEM;
|
||||
|
||||
spec->gen.automute_hook = cs_automute;
|
||||
|
||||
snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl,
|
||||
cs421x_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
|
|
@ -815,6 +815,29 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* check whether a built-in speaker is included in parsed pins */
|
||||
static bool has_builtin_speaker(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
hda_nid_t *nid_pin;
|
||||
int nids, i;
|
||||
|
||||
if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
|
||||
nid_pin = spec->gen.autocfg.line_out_pins;
|
||||
nids = spec->gen.autocfg.line_outs;
|
||||
} else {
|
||||
nid_pin = spec->gen.autocfg.speaker_pins;
|
||||
nids = spec->gen.autocfg.speaker_outs;
|
||||
}
|
||||
|
||||
for (i = 0; i < nids; i++) {
|
||||
unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
|
||||
if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* PC beep controls
|
||||
*/
|
||||
|
@ -3890,6 +3913,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* Don't GPIO-mute speakers if there are no internal speakers, because
|
||||
* the GPIO might be necessary for Headphone
|
||||
*/
|
||||
if (spec->eapd_switch && !has_builtin_speaker(codec))
|
||||
spec->eapd_switch = 0;
|
||||
|
||||
codec->proc_widget_hook = stac92hd7x_proc_hook;
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
|
|
@ -243,6 +243,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
|
|||
struct usb_interface_assoc_descriptor *assoc =
|
||||
usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
|
||||
|
||||
if (!assoc) {
|
||||
/*
|
||||
* Firmware writers cannot count to three. So to find
|
||||
* the IAD on the NuForce UDH-100, also check the next
|
||||
* interface.
|
||||
*/
|
||||
struct usb_interface *iface =
|
||||
usb_ifnum_to_if(dev, ctrlif + 1);
|
||||
if (iface &&
|
||||
iface->intf_assoc &&
|
||||
iface->intf_assoc->bFunctionClass == USB_CLASS_AUDIO &&
|
||||
iface->intf_assoc->bFunctionProtocol == UAC_VERSION_2)
|
||||
assoc = iface->intf_assoc;
|
||||
}
|
||||
|
||||
if (!assoc) {
|
||||
snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
|
||||
return -EINVAL;
|
||||
|
|
Loading…
Reference in New Issue