Skip to content

Commit

Permalink
Merge tag 'sound-3.9' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/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()
  • Loading branch information
torvalds committed Mar 16, 2013
2 parents c7f17de + 6d3073e commit 5cd8846
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 28 deletions.
8 changes: 4 additions & 4 deletions sound/core/seq/seq_timer.c
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions sound/oss/sequencer.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion sound/pci/asihpi/asihpi.c
Expand Up @@ -2549,14 +2549,15 @@ 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;
struct hpi_control hpi_ctl, prev_ctl;

if (snd_BUG_ON(!asihpi))
return -EINVAL;
card = asihpi->card;
strcpy(card->mixername, "Asihpi Mixer");

err =
Expand Down
24 changes: 14 additions & 10 deletions sound/pci/hda/hda_codec.c
Expand Up @@ -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);
}

/**
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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 (conn_list) {
if (conns >= max_conns)
return -ENOSPC;
conn_list[conns] = n;
}
conns++;
}
} else {
if (conn_list) {
if (conns >= max_conns)
return -ENOSPC;
conn_list[conns++] = n;
conn_list[conns] = val;
}
} else {
if (conns >= max_conns)
return -ENOSPC;
conn_list[conns++] = val;
conns++;
}
prev_nid = val;
}
Expand Down
28 changes: 15 additions & 13 deletions sound/pci/hda/patch_ca0132.c
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}

Expand All @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions sound/pci/hda/patch_cirrus.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
29 changes: 29 additions & 0 deletions sound/pci/hda/patch_sigmatel.c
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions sound/usb/card.c
Expand Up @@ -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;
Expand Down

0 comments on commit 5cd8846

Please sign in to comment.