aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/core/rawmidi.c42
-rw-r--r--sound/pci/hda/patch_conexant.c15
-rw-r--r--sound/pci/hda/patch_realtek.c11
3 files changed, 38 insertions, 30 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index c0adc14c91f0..70d6f25ba526 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -248,7 +248,8 @@ static int assign_substream(struct snd_rawmidi *rmidi, int subdevice,
248 list_for_each_entry(substream, &s->substreams, list) { 248 list_for_each_entry(substream, &s->substreams, list) {
249 if (substream->opened) { 249 if (substream->opened) {
250 if (stream == SNDRV_RAWMIDI_STREAM_INPUT || 250 if (stream == SNDRV_RAWMIDI_STREAM_INPUT ||
251 !(mode & SNDRV_RAWMIDI_LFLG_APPEND)) 251 !(mode & SNDRV_RAWMIDI_LFLG_APPEND) ||
252 !substream->append)
252 continue; 253 continue;
253 } 254 }
254 if (subdevice < 0 || subdevice == substream->number) { 255 if (subdevice < 0 || subdevice == substream->number) {
@@ -266,17 +267,21 @@ static int open_substream(struct snd_rawmidi *rmidi,
266{ 267{
267 int err; 268 int err;
268 269
269 err = snd_rawmidi_runtime_create(substream); 270 if (substream->use_count == 0) {
270 if (err < 0) 271 err = snd_rawmidi_runtime_create(substream);
271 return err; 272 if (err < 0)
272 err = substream->ops->open(substream); 273 return err;
273 if (err < 0) 274 err = substream->ops->open(substream);
274 return err; 275 if (err < 0) {
275 substream->opened = 1; 276 snd_rawmidi_runtime_free(substream);
276 if (substream->use_count++ == 0) 277 return err;
278 }
279 substream->opened = 1;
277 substream->active_sensing = 0; 280 substream->active_sensing = 0;
278 if (mode & SNDRV_RAWMIDI_LFLG_APPEND) 281 if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
279 substream->append = 1; 282 substream->append = 1;
283 }
284 substream->use_count++;
280 rmidi->streams[substream->stream].substream_opened++; 285 rmidi->streams[substream->stream].substream_opened++;
281 return 0; 286 return 0;
282} 287}
@@ -297,27 +302,27 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
297 SNDRV_RAWMIDI_STREAM_INPUT, 302 SNDRV_RAWMIDI_STREAM_INPUT,
298 mode, &sinput); 303 mode, &sinput);
299 if (err < 0) 304 if (err < 0)
300 goto __error; 305 return err;
301 } 306 }
302 if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) { 307 if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
303 err = assign_substream(rmidi, subdevice, 308 err = assign_substream(rmidi, subdevice,
304 SNDRV_RAWMIDI_STREAM_OUTPUT, 309 SNDRV_RAWMIDI_STREAM_OUTPUT,
305 mode, &soutput); 310 mode, &soutput);
306 if (err < 0) 311 if (err < 0)
307 goto __error; 312 return err;
308 } 313 }
309 314
310 if (sinput) { 315 if (sinput) {
311 err = open_substream(rmidi, sinput, mode); 316 err = open_substream(rmidi, sinput, mode);
312 if (err < 0) 317 if (err < 0)
313 goto __error; 318 return err;
314 } 319 }
315 if (soutput) { 320 if (soutput) {
316 err = open_substream(rmidi, soutput, mode); 321 err = open_substream(rmidi, soutput, mode);
317 if (err < 0) { 322 if (err < 0) {
318 if (sinput) 323 if (sinput)
319 close_substream(rmidi, sinput, 0); 324 close_substream(rmidi, sinput, 0);
320 goto __error; 325 return err;
321 } 326 }
322 } 327 }
323 328
@@ -325,13 +330,6 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
325 rfile->input = sinput; 330 rfile->input = sinput;
326 rfile->output = soutput; 331 rfile->output = soutput;
327 return 0; 332 return 0;
328
329 __error:
330 if (sinput && sinput->runtime)
331 snd_rawmidi_runtime_free(sinput);
332 if (soutput && soutput->runtime)
333 snd_rawmidi_runtime_free(soutput);
334 return err;
335} 333}
336 334
337/* called from sound/core/seq/seq_midi.c */ 335/* called from sound/core/seq/seq_midi.c */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 6479e65858d3..905859d4f4df 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -110,6 +110,7 @@ struct conexant_spec {
110 110
111 unsigned int dell_automute; 111 unsigned int dell_automute;
112 unsigned int port_d_mode; 112 unsigned int port_d_mode;
113 unsigned char ext_mic_bias;
113}; 114};
114 115
115static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 116static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -1927,6 +1928,11 @@ static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1927static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; 1928static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1928#define CXT5066_SPDIF_OUT 0x21 1929#define CXT5066_SPDIF_OUT 0x21
1929 1930
1931/* OLPC's microphone port is DC coupled for use with external sensors,
1932 * therefore we use a 50% mic bias in order to center the input signal with
1933 * the DC input range of the codec. */
1934#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
1935
1930static struct hda_channel_mode cxt5066_modes[1] = { 1936static struct hda_channel_mode cxt5066_modes[1] = {
1931 { 2, NULL }, 1937 { 2, NULL },
1932}; 1938};
@@ -1980,9 +1986,10 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1980/* toggle input of built-in and mic jack appropriately */ 1986/* toggle input of built-in and mic jack appropriately */
1981static void cxt5066_automic(struct hda_codec *codec) 1987static void cxt5066_automic(struct hda_codec *codec)
1982{ 1988{
1983 static struct hda_verb ext_mic_present[] = { 1989 struct conexant_spec *spec = codec->spec;
1990 struct hda_verb ext_mic_present[] = {
1984 /* enable external mic, port B */ 1991 /* enable external mic, port B */
1985 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
1986 1993
1987 /* switch to external mic input */ 1994 /* switch to external mic input */
1988 {0x17, AC_VERB_SET_CONNECT_SEL, 0}, 1995 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
@@ -2235,7 +2242,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = {
2235 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ 2242 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2236 2243
2237 /* Port B: external microphone */ 2244 /* Port B: external microphone */
2238 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2245 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS},
2239 2246
2240 /* Port C: internal microphone */ 2247 /* Port C: internal microphone */
2241 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2248 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -2353,6 +2360,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2353 spec->input_mux = &cxt5066_capture_source; 2360 spec->input_mux = &cxt5066_capture_source;
2354 2361
2355 spec->port_d_mode = PIN_HP; 2362 spec->port_d_mode = PIN_HP;
2363 spec->ext_mic_bias = PIN_VREF80;
2356 2364
2357 spec->num_init_verbs = 1; 2365 spec->num_init_verbs = 1;
2358 spec->init_verbs[0] = cxt5066_init_verbs; 2366 spec->init_verbs[0] = cxt5066_init_verbs;
@@ -2384,6 +2392,7 @@ static int patch_cxt5066(struct hda_codec *codec)
2384 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; 2392 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2385 spec->mixers[spec->num_mixers++] = cxt5066_mixers; 2393 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2386 spec->port_d_mode = 0; 2394 spec->port_d_mode = 0;
2395 spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS;
2387 2396
2388 /* no S/PDIF out */ 2397 /* no S/PDIF out */
2389 spec->multiout.dig_out_nid = 0; 2398 spec->multiout.dig_out_nid = 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ff20048504b6..daf6975b0c2e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4684,9 +4684,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4684 spec->multiout.dig_out_nid = dig_nid; 4684 spec->multiout.dig_out_nid = dig_nid;
4685 else { 4685 else {
4686 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 4686 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4687 spec->slave_dig_outs[i - 1] = dig_nid; 4687 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4688 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4689 break; 4688 break;
4689 spec->slave_dig_outs[i - 1] = dig_nid;
4690 } 4690 }
4691 } 4691 }
4692 if (spec->autocfg.dig_in_pin) 4692 if (spec->autocfg.dig_in_pin)
@@ -6249,7 +6249,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
6249 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 6249 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6250 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 6250 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6251 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 6251 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6252 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), 6252 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6253 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 6253 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6254 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 6254 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6255 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 6255 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
@@ -9813,9 +9813,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
9813 spec->multiout.dig_out_nid = dig_nid; 9813 spec->multiout.dig_out_nid = dig_nid;
9814 else { 9814 else {
9815 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 9815 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
9816 spec->slave_dig_outs[i - 1] = dig_nid; 9816 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
9817 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
9818 break; 9817 break;
9818 spec->slave_dig_outs[i - 1] = dig_nid;
9819 } 9819 }
9820 } 9820 }
9821 if (spec->autocfg.dig_in_pin) 9821 if (spec->autocfg.dig_in_pin)
@@ -11460,6 +11460,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
11460 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 11460 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11461 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 11461 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11462 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 11462 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11463 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
11463 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 11464 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11464 ALC262_SONY_ASSAMD), 11465 ALC262_SONY_ASSAMD),
11465 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 11466 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",