diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-11 20:45:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-11 20:45:42 -0500 |
commit | fe10e6f4b24ef8ca12cb4d2368deb4861ab1861b (patch) | |
tree | 86f524927ce64b07b3ab18254558e7fa766b0688 | |
parent | f28ad3b44a03892b533cfb503273370033594d9d (diff) | |
parent | d938e66003c9ccc6c0ab10fa31ee23cf27574d66 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: usb-audio: Use kmemdup rather than duplicating its implementation
ALSA: hda - Re-enable the check NO_PRESENCE misc bit
ALSA: vmaster - Free slave-links when freeing the master element
ALSA: hda - Don't add elements of other codecs to vmaster slave
ALSA: intel8x0: improve virtual environment detection
ALSA: intel8x0: move virtual environment detection code into one place
ALSA: snd_usb_audio: add Logitech HD Webcam c510 to quirk-384
ALSA: hda - fix internal mic on Dell Vostro 3500 laptop
ALSA: HDA: Remove quirk for Toshiba T110
ALSA: usb-audio - Fix the missing volume quirks at delayed init
ALSA: hda - Mute unused capture sources for Realtek codecs
ALSA: intel8x0: Improve comments for VM optimization
ASoC: Ensure we get an impedence reported for WM8958 jack detect
ASoC: Don't use wm8994->control_data when requesting IRQs
ASoC: Don't use wm8994->control_data in wm8994_readable_register()
ASoC: Update git repository URL
-rw-r--r-- | Documentation/sound/alsa/HD-Audio-Models.txt | 1 | ||||
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | include/linux/mfd/wm8994/registers.h | 15 | ||||
-rw-r--r-- | sound/core/vmaster.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 64 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 13 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 11 | ||||
-rw-r--r-- | sound/pci/intel8x0.c | 58 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 43 | ||||
-rw-r--r-- | sound/usb/mixer.c | 110 | ||||
-rw-r--r-- | sound/usb/quirks.c | 7 |
14 files changed, 241 insertions, 119 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 4f3443230d89..edad99abec21 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
@@ -349,6 +349,7 @@ STAC92HD83* | |||
349 | ref Reference board | 349 | ref Reference board |
350 | mic-ref Reference board with power management for ports | 350 | mic-ref Reference board with power management for ports |
351 | dell-s14 Dell laptop | 351 | dell-s14 Dell laptop |
352 | dell-vostro-3500 Dell Vostro 3500 laptop | ||
352 | hp HP laptops with (inverted) mute-LED | 353 | hp HP laptops with (inverted) mute-LED |
353 | hp-dv7-4000 HP dv-7 4000 | 354 | hp-dv7-4000 HP dv-7 4000 |
354 | auto BIOS setup (default) | 355 | auto BIOS setup (default) |
diff --git a/MAINTAINERS b/MAINTAINERS index c1b1f3e40c38..3e8bc6163be6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6129,7 +6129,7 @@ F: sound/ | |||
6129 | SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) | 6129 | SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) |
6130 | M: Liam Girdwood <lrg@ti.com> | 6130 | M: Liam Girdwood <lrg@ti.com> |
6131 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6131 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> |
6132 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git | 6132 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git |
6133 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 6133 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
6134 | W: http://alsa-project.org/main/index.php/ASoC | 6134 | W: http://alsa-project.org/main/index.php/ASoC |
6135 | S: Supported | 6135 | S: Supported |
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index fae295048a8b..83a9caec0e43 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h | |||
@@ -1963,6 +1963,21 @@ | |||
1963 | #define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ | 1963 | #define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ |
1964 | 1964 | ||
1965 | /* | 1965 | /* |
1966 | * R210 (0xD2) - Mic Detect 3 | ||
1967 | */ | ||
1968 | #define WM8958_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */ | ||
1969 | #define WM8958_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */ | ||
1970 | #define WM8958_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */ | ||
1971 | #define WM8958_MICD_VALID 0x0002 /* MICD_VALID */ | ||
1972 | #define WM8958_MICD_VALID_MASK 0x0002 /* MICD_VALID */ | ||
1973 | #define WM8958_MICD_VALID_SHIFT 1 /* MICD_VALID */ | ||
1974 | #define WM8958_MICD_VALID_WIDTH 1 /* MICD_VALID */ | ||
1975 | #define WM8958_MICD_STS 0x0001 /* MICD_STS */ | ||
1976 | #define WM8958_MICD_STS_MASK 0x0001 /* MICD_STS */ | ||
1977 | #define WM8958_MICD_STS_SHIFT 0 /* MICD_STS */ | ||
1978 | #define WM8958_MICD_STS_WIDTH 1 /* MICD_STS */ | ||
1979 | |||
1980 | /* | ||
1966 | * R76 (0x4C) - Charge Pump (1) | 1981 | * R76 (0x4C) - Charge Pump (1) |
1967 | */ | 1982 | */ |
1968 | #define WM8994_CP_ENA 0x8000 /* CP_ENA */ | 1983 | #define WM8994_CP_ENA 0x8000 /* CP_ENA */ |
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 5dbab38d04af..130cfe677d60 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c | |||
@@ -52,6 +52,7 @@ struct link_slave { | |||
52 | struct link_ctl_info info; | 52 | struct link_ctl_info info; |
53 | int vals[2]; /* current values */ | 53 | int vals[2]; /* current values */ |
54 | unsigned int flags; | 54 | unsigned int flags; |
55 | struct snd_kcontrol *kctl; /* original kcontrol pointer */ | ||
55 | struct snd_kcontrol slave; /* the copy of original control entry */ | 56 | struct snd_kcontrol slave; /* the copy of original control entry */ |
56 | }; | 57 | }; |
57 | 58 | ||
@@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, | |||
252 | slave->count * sizeof(*slave->vd), GFP_KERNEL); | 253 | slave->count * sizeof(*slave->vd), GFP_KERNEL); |
253 | if (!srec) | 254 | if (!srec) |
254 | return -ENOMEM; | 255 | return -ENOMEM; |
256 | srec->kctl = slave; | ||
255 | srec->slave = *slave; | 257 | srec->slave = *slave; |
256 | memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); | 258 | memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); |
257 | srec->master = master_link; | 259 | srec->master = master_link; |
@@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol, | |||
333 | static void master_free(struct snd_kcontrol *kcontrol) | 335 | static void master_free(struct snd_kcontrol *kcontrol) |
334 | { | 336 | { |
335 | struct link_master *master = snd_kcontrol_chip(kcontrol); | 337 | struct link_master *master = snd_kcontrol_chip(kcontrol); |
336 | struct link_slave *slave; | 338 | struct link_slave *slave, *n; |
337 | 339 | ||
338 | list_for_each_entry(slave, &master->slaves, list) | 340 | /* free all slave links and retore the original slave kctls */ |
339 | slave->master = NULL; | 341 | list_for_each_entry_safe(slave, n, &master->slaves, list) { |
342 | struct snd_kcontrol *sctl = slave->kctl; | ||
343 | struct list_head olist = sctl->list; | ||
344 | memcpy(sctl, &slave->slave, sizeof(*sctl)); | ||
345 | memcpy(sctl->vd, slave->slave.vd, | ||
346 | sctl->count * sizeof(*sctl->vd)); | ||
347 | sctl->list = olist; /* keep the current linked-list */ | ||
348 | kfree(slave); | ||
349 | } | ||
340 | kfree(master); | 350 | kfree(master); |
341 | } | 351 | } |
342 | 352 | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 916a1863af73..e44b107fdc75 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2331,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2331 | return 0; | 2331 | return 0; |
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); | ||
2335 | |||
2336 | /* apply the function to all matching slave ctls in the mixer list */ | ||
2337 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, | ||
2338 | map_slave_func_t func, void *data) | ||
2339 | { | ||
2340 | struct hda_nid_item *items; | ||
2341 | const char * const *s; | ||
2342 | int i, err; | ||
2343 | |||
2344 | items = codec->mixers.list; | ||
2345 | for (i = 0; i < codec->mixers.used; i++) { | ||
2346 | struct snd_kcontrol *sctl = items[i].kctl; | ||
2347 | if (!sctl || !sctl->id.name || | ||
2348 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) | ||
2349 | continue; | ||
2350 | for (s = slaves; *s; s++) { | ||
2351 | if (!strcmp(sctl->id.name, *s)) { | ||
2352 | err = func(data, sctl); | ||
2353 | if (err) | ||
2354 | return err; | ||
2355 | break; | ||
2356 | } | ||
2357 | } | ||
2358 | } | ||
2359 | return 0; | ||
2360 | } | ||
2361 | |||
2362 | static int check_slave_present(void *data, struct snd_kcontrol *sctl) | ||
2363 | { | ||
2364 | return 1; | ||
2365 | } | ||
2366 | |||
2334 | /** | 2367 | /** |
2335 | * snd_hda_add_vmaster - create a virtual master control and add slaves | 2368 | * snd_hda_add_vmaster - create a virtual master control and add slaves |
2336 | * @codec: HD-audio codec | 2369 | * @codec: HD-audio codec |
@@ -2351,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2351 | unsigned int *tlv, const char * const *slaves) | 2384 | unsigned int *tlv, const char * const *slaves) |
2352 | { | 2385 | { |
2353 | struct snd_kcontrol *kctl; | 2386 | struct snd_kcontrol *kctl; |
2354 | const char * const *s; | ||
2355 | int err; | 2387 | int err; |
2356 | 2388 | ||
2357 | for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) | 2389 | err = map_slaves(codec, slaves, check_slave_present, NULL); |
2358 | ; | 2390 | if (err != 1) { |
2359 | if (!*s) { | ||
2360 | snd_printdd("No slave found for %s\n", name); | 2391 | snd_printdd("No slave found for %s\n", name); |
2361 | return 0; | 2392 | return 0; |
2362 | } | 2393 | } |
@@ -2367,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2367 | if (err < 0) | 2398 | if (err < 0) |
2368 | return err; | 2399 | return err; |
2369 | 2400 | ||
2370 | for (s = slaves; *s; s++) { | 2401 | err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, |
2371 | struct snd_kcontrol *sctl; | 2402 | kctl); |
2372 | int i = 0; | 2403 | if (err < 0) |
2373 | for (;;) { | 2404 | return err; |
2374 | sctl = _snd_hda_find_mixer_ctl(codec, *s, i); | ||
2375 | if (!sctl) { | ||
2376 | if (!i) | ||
2377 | snd_printdd("Cannot find slave %s, " | ||
2378 | "skipped\n", *s); | ||
2379 | break; | ||
2380 | } | ||
2381 | err = snd_ctl_add_slave(kctl, sctl); | ||
2382 | if (err < 0) | ||
2383 | return err; | ||
2384 | i++; | ||
2385 | } | ||
2386 | } | ||
2387 | return 0; | 2405 | return 0; |
2388 | } | 2406 | } |
2389 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); | 2407 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); |
@@ -4752,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
4752 | memset(sequences_hp, 0, sizeof(sequences_hp)); | 4770 | memset(sequences_hp, 0, sizeof(sequences_hp)); |
4753 | assoc_line_out = 0; | 4771 | assoc_line_out = 0; |
4754 | 4772 | ||
4773 | codec->ignore_misc_bit = true; | ||
4755 | end_nid = codec->start_nid + codec->num_nodes; | 4774 | end_nid = codec->start_nid + codec->num_nodes; |
4756 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 4775 | for (nid = codec->start_nid; nid < end_nid; nid++) { |
4757 | unsigned int wid_caps = get_wcaps(codec, nid); | 4776 | unsigned int wid_caps = get_wcaps(codec, nid); |
@@ -4767,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
4767 | continue; | 4786 | continue; |
4768 | 4787 | ||
4769 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | 4788 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
4789 | if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
4790 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
4791 | codec->ignore_misc_bit = false; | ||
4770 | conn = get_defcfg_connect(def_conf); | 4792 | conn = get_defcfg_connect(def_conf); |
4771 | if (conn == AC_JACK_PORT_NONE) | 4793 | if (conn == AC_JACK_PORT_NONE) |
4772 | continue; | 4794 | continue; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 755f2b0f9d8e..564471169cae 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -854,6 +854,7 @@ struct hda_codec { | |||
854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ | 854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ |
855 | unsigned int pins_shutup:1; /* pins are shut up */ | 855 | unsigned int pins_shutup:1; /* pins are shut up */ |
856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
857 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | ||
857 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 858 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
858 | unsigned int power_on :1; /* current (global) power-state */ | 859 | unsigned int power_on :1; /* current (global) power-state */ |
859 | unsigned int power_transition :1; /* power-state in transition */ | 860 | unsigned int power_transition :1; /* power-state in transition */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index dcbea0da0fa2..6579e0f2bb57 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | |||
510 | 510 | ||
511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) |
512 | { | 512 | { |
513 | return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && | 513 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) |
514 | /* disable MISC_NO_PRESENCE check because it may break too | 514 | return false; |
515 | * many devices | 515 | if (!codec->ignore_misc_bit && |
516 | */ | 516 | (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & |
517 | /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & | 517 | AC_DEFCFG_MISC_NO_PRESENCE)) |
518 | AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ | 518 | return false; |
519 | (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); | 519 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) |
520 | return false; | ||
521 | return true; | ||
520 | } | 522 | } |
521 | 523 | ||
522 | /* flags for hda_nid_item */ | 524 | /* flags for hda_nid_item */ |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5e706e4d1737..0de21193a2b0 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3062,7 +3062,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3062 | SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), | 3062 | SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), |
3063 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), | 3063 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), |
3064 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 3064 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
3065 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | ||
3066 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", | 3065 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", |
3067 | CXT5066_LAPTOP), | 3066 | CXT5066_LAPTOP), |
3068 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 3067 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a24e068a021b..308bb575bc06 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -284,7 +284,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
284 | struct alc_spec *spec = codec->spec; | 284 | struct alc_spec *spec = codec->spec; |
285 | const struct hda_input_mux *imux; | 285 | const struct hda_input_mux *imux; |
286 | unsigned int mux_idx; | 286 | unsigned int mux_idx; |
287 | int i, type; | 287 | int i, type, num_conns; |
288 | hda_nid_t nid; | 288 | hda_nid_t nid; |
289 | 289 | ||
290 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 290 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
@@ -307,16 +307,17 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
307 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; | 307 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; |
308 | 308 | ||
309 | /* no selection? */ | 309 | /* no selection? */ |
310 | if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) | 310 | num_conns = snd_hda_get_conn_list(codec, nid, NULL); |
311 | if (num_conns <= 1) | ||
311 | return 1; | 312 | return 1; |
312 | 313 | ||
313 | type = get_wcaps_type(get_wcaps(codec, nid)); | 314 | type = get_wcaps_type(get_wcaps(codec, nid)); |
314 | if (type == AC_WID_AUD_MIX) { | 315 | if (type == AC_WID_AUD_MIX) { |
315 | /* Matrix-mixer style (e.g. ALC882) */ | 316 | /* Matrix-mixer style (e.g. ALC882) */ |
316 | for (i = 0; i < imux->num_items; i++) { | 317 | int active = imux->items[idx].index; |
317 | unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; | 318 | for (i = 0; i < num_conns; i++) { |
318 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, | 319 | unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; |
319 | imux->items[i].index, | 320 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, |
320 | HDA_AMP_MUTE, v); | 321 | HDA_AMP_MUTE, v); |
321 | } | 322 | } |
322 | } else { | 323 | } else { |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4e715fefebef..edc2b7bc177c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -95,6 +95,7 @@ enum { | |||
95 | STAC_92HD83XXX_REF, | 95 | STAC_92HD83XXX_REF, |
96 | STAC_92HD83XXX_PWR_REF, | 96 | STAC_92HD83XXX_PWR_REF, |
97 | STAC_DELL_S14, | 97 | STAC_DELL_S14, |
98 | STAC_DELL_VOSTRO_3500, | ||
98 | STAC_92HD83XXX_HP, | 99 | STAC_92HD83XXX_HP, |
99 | STAC_92HD83XXX_HP_cNB11_INTQUAD, | 100 | STAC_92HD83XXX_HP_cNB11_INTQUAD, |
100 | STAC_HP_DV7_4000, | 101 | STAC_HP_DV7_4000, |
@@ -1659,6 +1660,12 @@ static const unsigned int dell_s14_pin_configs[10] = { | |||
1659 | 0x40f000f0, 0x40f000f0, | 1660 | 0x40f000f0, 0x40f000f0, |
1660 | }; | 1661 | }; |
1661 | 1662 | ||
1663 | static const unsigned int dell_vostro_3500_pin_configs[10] = { | ||
1664 | 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, | ||
1665 | 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, | ||
1666 | 0x400000f4, 0x400000f5, | ||
1667 | }; | ||
1668 | |||
1662 | static const unsigned int hp_dv7_4000_pin_configs[10] = { | 1669 | static const unsigned int hp_dv7_4000_pin_configs[10] = { |
1663 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, | 1670 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, |
1664 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, | 1671 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, |
@@ -1675,6 +1682,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | |||
1675 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 1682 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, |
1676 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | 1683 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, |
1677 | [STAC_DELL_S14] = dell_s14_pin_configs, | 1684 | [STAC_DELL_S14] = dell_s14_pin_configs, |
1685 | [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, | ||
1678 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, | 1686 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, |
1679 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, | 1687 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, |
1680 | }; | 1688 | }; |
@@ -1684,6 +1692,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |||
1684 | [STAC_92HD83XXX_REF] = "ref", | 1692 | [STAC_92HD83XXX_REF] = "ref", |
1685 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | 1693 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", |
1686 | [STAC_DELL_S14] = "dell-s14", | 1694 | [STAC_DELL_S14] = "dell-s14", |
1695 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", | ||
1687 | [STAC_92HD83XXX_HP] = "hp", | 1696 | [STAC_92HD83XXX_HP] = "hp", |
1688 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", | 1697 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", |
1689 | [STAC_HP_DV7_4000] = "hp-dv7-4000", | 1698 | [STAC_HP_DV7_4000] = "hp-dv7-4000", |
@@ -1697,6 +1706,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1697 | "DFI LanParty", STAC_92HD83XXX_REF), | 1706 | "DFI LanParty", STAC_92HD83XXX_REF), |
1698 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, | 1707 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, |
1699 | "unknown Dell", STAC_DELL_S14), | 1708 | "unknown Dell", STAC_DELL_S14), |
1709 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, | ||
1710 | "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), | ||
1700 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, | 1711 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, |
1701 | "HP", STAC_92HD83XXX_HP), | 1712 | "HP", STAC_92HD83XXX_HP), |
1702 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, | 1713 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 29e312597f20..11718b49b2e2 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -1077,6 +1077,13 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
1077 | } | 1077 | } |
1078 | if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) | 1078 | if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) |
1079 | continue; | 1079 | continue; |
1080 | |||
1081 | /* IO read operation is very expensive inside virtual machine | ||
1082 | * as it is emulated. The probability that subsequent PICB read | ||
1083 | * will return different result is high enough to loop till | ||
1084 | * timeout here. | ||
1085 | * Same CIV is strict enough condition to be sure that PICB | ||
1086 | * is valid inside VM on emulated card. */ | ||
1080 | if (chip->inside_vm) | 1087 | if (chip->inside_vm) |
1081 | break; | 1088 | break; |
1082 | if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | 1089 | if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) |
@@ -2930,6 +2937,45 @@ static unsigned int sis_codec_bits[3] = { | |||
2930 | ICH_PCR, ICH_SCR, ICH_SIS_TCR | 2937 | ICH_PCR, ICH_SCR, ICH_SIS_TCR |
2931 | }; | 2938 | }; |
2932 | 2939 | ||
2940 | static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci) | ||
2941 | { | ||
2942 | int result = inside_vm; | ||
2943 | char *msg = NULL; | ||
2944 | |||
2945 | /* check module parameter first (override detection) */ | ||
2946 | if (result >= 0) { | ||
2947 | msg = result ? "enable (forced) VM" : "disable (forced) VM"; | ||
2948 | goto fini; | ||
2949 | } | ||
2950 | |||
2951 | /* detect KVM and Parallels virtual environments */ | ||
2952 | result = kvm_para_available(); | ||
2953 | #ifdef X86_FEATURE_HYPERVISOR | ||
2954 | result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
2955 | #endif | ||
2956 | if (!result) | ||
2957 | goto fini; | ||
2958 | |||
2959 | /* check for known (emulated) devices */ | ||
2960 | if (pci->subsystem_vendor == 0x1af4 && | ||
2961 | pci->subsystem_device == 0x1100) { | ||
2962 | /* KVM emulated sound, PCI SSID: 1af4:1100 */ | ||
2963 | msg = "enable KVM"; | ||
2964 | } else if (pci->subsystem_vendor == 0x1ab8) { | ||
2965 | /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */ | ||
2966 | msg = "enable Parallels VM"; | ||
2967 | } else { | ||
2968 | msg = "disable (unknown or VT-d) VM"; | ||
2969 | result = 0; | ||
2970 | } | ||
2971 | |||
2972 | fini: | ||
2973 | if (msg != NULL) | ||
2974 | printk(KERN_INFO "intel8x0: %s optimization\n", msg); | ||
2975 | |||
2976 | return result; | ||
2977 | } | ||
2978 | |||
2933 | static int __devinit snd_intel8x0_create(struct snd_card *card, | 2979 | static int __devinit snd_intel8x0_create(struct snd_card *card, |
2934 | struct pci_dev *pci, | 2980 | struct pci_dev *pci, |
2935 | unsigned long device_type, | 2981 | unsigned long device_type, |
@@ -2997,9 +3043,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
2997 | if (xbox) | 3043 | if (xbox) |
2998 | chip->xbox = 1; | 3044 | chip->xbox = 1; |
2999 | 3045 | ||
3000 | chip->inside_vm = inside_vm; | 3046 | chip->inside_vm = snd_intel8x0_inside_vm(pci); |
3001 | if (inside_vm) | ||
3002 | printk(KERN_INFO "intel8x0: enable KVM optimization\n"); | ||
3003 | 3047 | ||
3004 | if (pci->vendor == PCI_VENDOR_ID_INTEL && | 3048 | if (pci->vendor == PCI_VENDOR_ID_INTEL && |
3005 | pci->device == PCI_DEVICE_ID_INTEL_440MX) | 3049 | pci->device == PCI_DEVICE_ID_INTEL_440MX) |
@@ -3243,14 +3287,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
3243 | buggy_irq = 0; | 3287 | buggy_irq = 0; |
3244 | } | 3288 | } |
3245 | 3289 | ||
3246 | if (inside_vm < 0) { | ||
3247 | /* detect KVM and Parallels virtual environments */ | ||
3248 | inside_vm = kvm_para_available(); | ||
3249 | #if defined(__i386__) || defined(__x86_64__) | ||
3250 | inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
3251 | #endif | ||
3252 | } | ||
3253 | |||
3254 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, | 3290 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, |
3255 | &chip)) < 0) { | 3291 | &chip)) < 0) { |
3256 | snd_card_free(card); | 3292 | snd_card_free(card); |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6b73efd26991..9c982e47eb99 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = { | |||
56 | static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) | 56 | static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) |
57 | { | 57 | { |
58 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 58 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
59 | struct wm8994 *control = wm8994->control_data; | 59 | struct wm8994 *control = codec->control_data; |
60 | 60 | ||
61 | switch (reg) { | 61 | switch (reg) { |
62 | case WM8994_GPIO_1: | 62 | case WM8994_GPIO_1: |
@@ -3030,19 +3030,34 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3030 | { | 3030 | { |
3031 | struct wm8994_priv *wm8994 = data; | 3031 | struct wm8994_priv *wm8994 = data; |
3032 | struct snd_soc_codec *codec = wm8994->codec; | 3032 | struct snd_soc_codec *codec = wm8994->codec; |
3033 | int reg; | 3033 | int reg, count; |
3034 | 3034 | ||
3035 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); | 3035 | /* We may occasionally read a detection without an impedence |
3036 | if (reg < 0) { | 3036 | * range being provided - if that happens loop again. |
3037 | dev_err(codec->dev, "Failed to read mic detect status: %d\n", | 3037 | */ |
3038 | reg); | 3038 | count = 10; |
3039 | return IRQ_NONE; | 3039 | do { |
3040 | } | 3040 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); |
3041 | if (reg < 0) { | ||
3042 | dev_err(codec->dev, | ||
3043 | "Failed to read mic detect status: %d\n", | ||
3044 | reg); | ||
3045 | return IRQ_NONE; | ||
3046 | } | ||
3041 | 3047 | ||
3042 | if (!(reg & WM8958_MICD_VALID)) { | 3048 | if (!(reg & WM8958_MICD_VALID)) { |
3043 | dev_dbg(codec->dev, "Mic detect data not valid\n"); | 3049 | dev_dbg(codec->dev, "Mic detect data not valid\n"); |
3044 | goto out; | 3050 | goto out; |
3045 | } | 3051 | } |
3052 | |||
3053 | if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK)) | ||
3054 | break; | ||
3055 | |||
3056 | msleep(1); | ||
3057 | } while (count--); | ||
3058 | |||
3059 | if (count == 0) | ||
3060 | dev_warn(codec->dev, "No impedence range reported for jack\n"); | ||
3046 | 3061 | ||
3047 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | 3062 | #ifndef CONFIG_SND_SOC_WM8994_MODULE |
3048 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3063 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
@@ -3180,9 +3195,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3180 | 3195 | ||
3181 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, | 3196 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, |
3182 | wm8994_fifo_error, "FIFO error", codec); | 3197 | wm8994_fifo_error, "FIFO error", codec); |
3183 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN, | 3198 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, |
3184 | wm8994_temp_warn, "Thermal warning", codec); | 3199 | wm8994_temp_warn, "Thermal warning", codec); |
3185 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT, | 3200 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, |
3186 | wm8994_temp_shut, "Thermal shutdown", codec); | 3201 | wm8994_temp_shut, "Thermal shutdown", codec); |
3187 | 3202 | ||
3188 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3203 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 60f65ace7474..ab23869c01bb 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -765,10 +765,61 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |||
765 | * interface to ALSA control for feature/mixer units | 765 | * interface to ALSA control for feature/mixer units |
766 | */ | 766 | */ |
767 | 767 | ||
768 | /* volume control quirks */ | ||
769 | static void volume_control_quirks(struct usb_mixer_elem_info *cval, | ||
770 | struct snd_kcontrol *kctl) | ||
771 | { | ||
772 | switch (cval->mixer->chip->usb_id) { | ||
773 | case USB_ID(0x0471, 0x0101): | ||
774 | case USB_ID(0x0471, 0x0104): | ||
775 | case USB_ID(0x0471, 0x0105): | ||
776 | case USB_ID(0x0672, 0x1041): | ||
777 | /* quirk for UDA1321/N101. | ||
778 | * note that detection between firmware 2.1.1.7 (N101) | ||
779 | * and later 2.1.1.21 is not very clear from datasheets. | ||
780 | * I hope that the min value is -15360 for newer firmware --jk | ||
781 | */ | ||
782 | if (!strcmp(kctl->id.name, "PCM Playback Volume") && | ||
783 | cval->min == -15616) { | ||
784 | snd_printk(KERN_INFO | ||
785 | "set volume quirk for UDA1321/N101 chip\n"); | ||
786 | cval->max = -256; | ||
787 | } | ||
788 | break; | ||
789 | |||
790 | case USB_ID(0x046d, 0x09a4): | ||
791 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
792 | snd_printk(KERN_INFO | ||
793 | "set volume quirk for QuickCam E3500\n"); | ||
794 | cval->min = 6080; | ||
795 | cval->max = 8768; | ||
796 | cval->res = 192; | ||
797 | } | ||
798 | break; | ||
799 | |||
800 | case USB_ID(0x046d, 0x0808): | ||
801 | case USB_ID(0x046d, 0x0809): | ||
802 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ | ||
803 | case USB_ID(0x046d, 0x0991): | ||
804 | /* Most audio usb devices lie about volume resolution. | ||
805 | * Most Logitech webcams have res = 384. | ||
806 | * Proboly there is some logitech magic behind this number --fishor | ||
807 | */ | ||
808 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
809 | snd_printk(KERN_INFO | ||
810 | "set resolution quirk: cval->res = 384\n"); | ||
811 | cval->res = 384; | ||
812 | } | ||
813 | break; | ||
814 | |||
815 | } | ||
816 | } | ||
817 | |||
768 | /* | 818 | /* |
769 | * retrieve the minimum and maximum values for the specified control | 819 | * retrieve the minimum and maximum values for the specified control |
770 | */ | 820 | */ |
771 | static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | 821 | static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, |
822 | int default_min, struct snd_kcontrol *kctl) | ||
772 | { | 823 | { |
773 | /* for failsafe */ | 824 | /* for failsafe */ |
774 | cval->min = default_min; | 825 | cval->min = default_min; |
@@ -844,6 +895,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
844 | cval->initialized = 1; | 895 | cval->initialized = 1; |
845 | } | 896 | } |
846 | 897 | ||
898 | if (kctl) | ||
899 | volume_control_quirks(cval, kctl); | ||
900 | |||
847 | /* USB descriptions contain the dB scale in 1/256 dB unit | 901 | /* USB descriptions contain the dB scale in 1/256 dB unit |
848 | * while ALSA TLV contains in 1/100 dB unit | 902 | * while ALSA TLV contains in 1/100 dB unit |
849 | */ | 903 | */ |
@@ -864,6 +918,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
864 | return 0; | 918 | return 0; |
865 | } | 919 | } |
866 | 920 | ||
921 | #define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) | ||
867 | 922 | ||
868 | /* get a feature/mixer unit info */ | 923 | /* get a feature/mixer unit info */ |
869 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 924 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
@@ -882,7 +937,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
882 | uinfo->value.integer.max = 1; | 937 | uinfo->value.integer.max = 1; |
883 | } else { | 938 | } else { |
884 | if (!cval->initialized) { | 939 | if (!cval->initialized) { |
885 | get_min_max(cval, 0); | 940 | get_min_max_with_quirks(cval, 0, kcontrol); |
886 | if (cval->initialized && cval->dBmin >= cval->dBmax) { | 941 | if (cval->initialized && cval->dBmin >= cval->dBmax) { |
887 | kcontrol->vd[0].access &= | 942 | kcontrol->vd[0].access &= |
888 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 943 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
@@ -1045,9 +1100,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1045 | cval->ch_readonly = readonly_mask; | 1100 | cval->ch_readonly = readonly_mask; |
1046 | } | 1101 | } |
1047 | 1102 | ||
1048 | /* get min/max values */ | ||
1049 | get_min_max(cval, 0); | ||
1050 | |||
1051 | /* if all channels in the mask are marked read-only, make the control | 1103 | /* if all channels in the mask are marked read-only, make the control |
1052 | * read-only. set_cur_mix_value() will check the mask again and won't | 1104 | * read-only. set_cur_mix_value() will check the mask again and won't |
1053 | * issue write commands to read-only channels. */ | 1105 | * issue write commands to read-only channels. */ |
@@ -1069,6 +1121,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1069 | len = snd_usb_copy_string_desc(state, nameid, | 1121 | len = snd_usb_copy_string_desc(state, nameid, |
1070 | kctl->id.name, sizeof(kctl->id.name)); | 1122 | kctl->id.name, sizeof(kctl->id.name)); |
1071 | 1123 | ||
1124 | /* get min/max values */ | ||
1125 | get_min_max_with_quirks(cval, 0, kctl); | ||
1126 | |||
1072 | switch (control) { | 1127 | switch (control) { |
1073 | case UAC_FU_MUTE: | 1128 | case UAC_FU_MUTE: |
1074 | case UAC_FU_VOLUME: | 1129 | case UAC_FU_VOLUME: |
@@ -1118,51 +1173,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1118 | break; | 1173 | break; |
1119 | } | 1174 | } |
1120 | 1175 | ||
1121 | /* volume control quirks */ | ||
1122 | switch (state->chip->usb_id) { | ||
1123 | case USB_ID(0x0471, 0x0101): | ||
1124 | case USB_ID(0x0471, 0x0104): | ||
1125 | case USB_ID(0x0471, 0x0105): | ||
1126 | case USB_ID(0x0672, 0x1041): | ||
1127 | /* quirk for UDA1321/N101. | ||
1128 | * note that detection between firmware 2.1.1.7 (N101) | ||
1129 | * and later 2.1.1.21 is not very clear from datasheets. | ||
1130 | * I hope that the min value is -15360 for newer firmware --jk | ||
1131 | */ | ||
1132 | if (!strcmp(kctl->id.name, "PCM Playback Volume") && | ||
1133 | cval->min == -15616) { | ||
1134 | snd_printk(KERN_INFO | ||
1135 | "set volume quirk for UDA1321/N101 chip\n"); | ||
1136 | cval->max = -256; | ||
1137 | } | ||
1138 | break; | ||
1139 | |||
1140 | case USB_ID(0x046d, 0x09a4): | ||
1141 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
1142 | snd_printk(KERN_INFO | ||
1143 | "set volume quirk for QuickCam E3500\n"); | ||
1144 | cval->min = 6080; | ||
1145 | cval->max = 8768; | ||
1146 | cval->res = 192; | ||
1147 | } | ||
1148 | break; | ||
1149 | |||
1150 | case USB_ID(0x046d, 0x0808): | ||
1151 | case USB_ID(0x046d, 0x0809): | ||
1152 | case USB_ID(0x046d, 0x0991): | ||
1153 | /* Most audio usb devices lie about volume resolution. | ||
1154 | * Most Logitech webcams have res = 384. | ||
1155 | * Proboly there is some logitech magic behind this number --fishor | ||
1156 | */ | ||
1157 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
1158 | snd_printk(KERN_INFO | ||
1159 | "set resolution quirk: cval->res = 384\n"); | ||
1160 | cval->res = 384; | ||
1161 | } | ||
1162 | break; | ||
1163 | |||
1164 | } | ||
1165 | |||
1166 | range = (cval->max - cval->min) / cval->res; | 1176 | range = (cval->max - cval->min) / cval->res; |
1167 | /* Are there devices with volume range more than 255? I use a bit more | 1177 | /* Are there devices with volume range more than 255? I use a bit more |
1168 | * to be sure. 384 is a resolution magic number found on Logitech | 1178 | * to be sure. 384 is a resolution magic number found on Logitech |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 2e5bc7344026..a3ddac0deffd 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -137,12 +137,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
137 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | } | 138 | } |
139 | if (fp->nr_rates > 0) { | 139 | if (fp->nr_rates > 0) { |
140 | rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); | 140 | rate_table = kmemdup(fp->rate_table, |
141 | sizeof(int) * fp->nr_rates, GFP_KERNEL); | ||
141 | if (!rate_table) { | 142 | if (!rate_table) { |
142 | kfree(fp); | 143 | kfree(fp); |
143 | return -ENOMEM; | 144 | return -ENOMEM; |
144 | } | 145 | } |
145 | memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates); | ||
146 | fp->rate_table = rate_table; | 146 | fp->rate_table = rate_table; |
147 | } | 147 | } |
148 | 148 | ||
@@ -224,10 +224,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
224 | if (altsd->bNumEndpoints != 1) | 224 | if (altsd->bNumEndpoints != 1) |
225 | return -ENXIO; | 225 | return -ENXIO; |
226 | 226 | ||
227 | fp = kmalloc(sizeof(*fp), GFP_KERNEL); | 227 | fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL); |
228 | if (!fp) | 228 | if (!fp) |
229 | return -ENOMEM; | 229 | return -ENOMEM; |
230 | memcpy(fp, &ua_format, sizeof(*fp)); | ||
231 | 230 | ||
232 | fp->iface = altsd->bInterfaceNumber; | 231 | fp->iface = altsd->bInterfaceNumber; |
233 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 232 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; |