Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+240 -118
+1
Documentation/sound/alsa/HD-Audio-Models.txt
··· 349 349 ref Reference board 350 350 mic-ref Reference board with power management for ports 351 351 dell-s14 Dell laptop 352 + dell-vostro-3500 Dell Vostro 3500 laptop 352 353 hp HP laptops with (inverted) mute-LED 353 354 hp-dv7-4000 HP dv-7 4000 354 355 auto BIOS setup (default)
+1 -1
MAINTAINERS
··· 6129 6129 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) 6130 6130 M: Liam Girdwood <lrg@ti.com> 6131 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 6133 L: alsa-devel@alsa-project.org (moderated for non-subscribers) 6134 6134 W: http://alsa-project.org/main/index.php/ASoC 6135 6135 S: Supported
+15
include/linux/mfd/wm8994/registers.h
··· 1963 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 1981 * R76 (0x4C) - Charge Pump (1) 1967 1982 */ 1968 1983 #define WM8994_CP_ENA 0x8000 /* CP_ENA */
+13 -3
sound/core/vmaster.c
··· 52 52 struct link_ctl_info info; 53 53 int vals[2]; /* current values */ 54 54 unsigned int flags; 55 + struct snd_kcontrol *kctl; /* original kcontrol pointer */ 55 56 struct snd_kcontrol slave; /* the copy of original control entry */ 56 57 }; 57 58 ··· 253 252 slave->count * sizeof(*slave->vd), GFP_KERNEL); 254 253 if (!srec) 255 254 return -ENOMEM; 255 + srec->kctl = slave; 256 256 srec->slave = *slave; 257 257 memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); 258 258 srec->master = master_link; ··· 335 333 static void master_free(struct snd_kcontrol *kcontrol) 336 334 { 337 335 struct link_master *master = snd_kcontrol_chip(kcontrol); 338 - struct link_slave *slave; 336 + struct link_slave *slave, *n; 339 337 340 - list_for_each_entry(slave, &master->slaves, list) 341 - slave->master = NULL; 338 + /* free all slave links and retore the original slave kctls */ 339 + list_for_each_entry_safe(slave, n, &master->slaves, list) { 340 + struct snd_kcontrol *sctl = slave->kctl; 341 + struct list_head olist = sctl->list; 342 + memcpy(sctl, &slave->slave, sizeof(*sctl)); 343 + memcpy(sctl->vd, slave->slave.vd, 344 + sctl->count * sizeof(*sctl->vd)); 345 + sctl->list = olist; /* keep the current linked-list */ 346 + kfree(slave); 347 + } 342 348 kfree(master); 343 349 } 344 350
+43 -21
sound/pci/hda/hda_codec.c
··· 2331 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 2368 * snd_hda_add_vmaster - create a virtual master control and add slaves 2336 2369 * @codec: HD-audio codec ··· 2384 2351 unsigned int *tlv, const char * const *slaves) 2385 2352 { 2386 2353 struct snd_kcontrol *kctl; 2387 - const char * const *s; 2388 2354 int err; 2389 2355 2390 - for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) 2391 - ; 2392 - if (!*s) { 2356 + err = map_slaves(codec, slaves, check_slave_present, NULL); 2357 + if (err != 1) { 2393 2358 snd_printdd("No slave found for %s\n", name); 2394 2359 return 0; 2395 2360 } ··· 2398 2367 if (err < 0) 2399 2368 return err; 2400 2369 2401 - for (s = slaves; *s; s++) { 2402 - struct snd_kcontrol *sctl; 2403 - int i = 0; 2404 - for (;;) { 2405 - sctl = _snd_hda_find_mixer_ctl(codec, *s, i); 2406 - if (!sctl) { 2407 - if (!i) 2408 - snd_printdd("Cannot find slave %s, " 2409 - "skipped\n", *s); 2410 - break; 2411 - } 2412 - err = snd_ctl_add_slave(kctl, sctl); 2413 - if (err < 0) 2414 - return err; 2415 - i++; 2416 - } 2417 - } 2370 + err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, 2371 + kctl); 2372 + if (err < 0) 2373 + return err; 2418 2374 return 0; 2419 2375 } 2420 2376 EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); ··· 4770 4752 memset(sequences_hp, 0, sizeof(sequences_hp)); 4771 4753 assoc_line_out = 0; 4772 4754 4755 + codec->ignore_misc_bit = true; 4773 4756 end_nid = codec->start_nid + codec->num_nodes; 4774 4757 for (nid = codec->start_nid; nid < end_nid; nid++) { 4775 4758 unsigned int wid_caps = get_wcaps(codec, nid); ··· 4786 4767 continue; 4787 4768 4788 4769 def_conf = snd_hda_codec_get_pincfg(codec, nid); 4770 + if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & 4771 + AC_DEFCFG_MISC_NO_PRESENCE)) 4772 + codec->ignore_misc_bit = false; 4789 4773 conn = get_defcfg_connect(def_conf); 4790 4774 if (conn == AC_JACK_PORT_NONE) 4791 4775 continue;
+1
sound/pci/hda/hda_codec.h
··· 854 854 unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ 855 855 unsigned int pins_shutup:1; /* pins are shut up */ 856 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 858 #ifdef CONFIG_SND_HDA_POWER_SAVE 858 859 unsigned int power_on :1; /* current (global) power-state */ 859 860 unsigned int power_transition :1; /* power-state in transition */
+9 -7
sound/pci/hda/hda_local.h
··· 510 510 511 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) && 514 - /* disable MISC_NO_PRESENCE check because it may break too 515 - * many devices 516 - */ 517 - /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & 518 - AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ 519 - (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); 513 + if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) 514 + return false; 515 + if (!codec->ignore_misc_bit && 516 + (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & 517 + AC_DEFCFG_MISC_NO_PRESENCE)) 518 + return false; 519 + if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) 520 + return false; 521 + return true; 520 522 } 521 523 522 524 /* flags for hda_nid_item */
-1
sound/pci/hda/patch_conexant.c
··· 3062 3062 SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), 3063 3063 SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), 3064 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 3065 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 3067 3066 CXT5066_LAPTOP), 3068 3067 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
+7 -6
sound/pci/hda/patch_realtek.c
··· 284 284 struct alc_spec *spec = codec->spec; 285 285 const struct hda_input_mux *imux; 286 286 unsigned int mux_idx; 287 - int i, type; 287 + int i, type, num_conns; 288 288 hda_nid_t nid; 289 289 290 290 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; ··· 307 307 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 308 308 309 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 312 return 1; 312 313 313 314 type = get_wcaps_type(get_wcaps(codec, nid)); 314 315 if (type == AC_WID_AUD_MIX) { 315 316 /* Matrix-mixer style (e.g. ALC882) */ 316 - for (i = 0; i < imux->num_items; i++) { 317 - unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 318 - snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 319 - imux->items[i].index, 317 + int active = imux->items[idx].index; 318 + for (i = 0; i < num_conns; i++) { 319 + unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; 320 + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, 320 321 HDA_AMP_MUTE, v); 321 322 } 322 323 } else {
+11
sound/pci/hda/patch_sigmatel.c
··· 95 95 STAC_92HD83XXX_REF, 96 96 STAC_92HD83XXX_PWR_REF, 97 97 STAC_DELL_S14, 98 + STAC_DELL_VOSTRO_3500, 98 99 STAC_92HD83XXX_HP, 99 100 STAC_92HD83XXX_HP_cNB11_INTQUAD, 100 101 STAC_HP_DV7_4000, ··· 1660 1659 0x40f000f0, 0x40f000f0, 1661 1660 }; 1662 1661 1662 + static const unsigned int dell_vostro_3500_pin_configs[10] = { 1663 + 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, 1664 + 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, 1665 + 0x400000f4, 0x400000f5, 1666 + }; 1667 + 1663 1668 static const unsigned int hp_dv7_4000_pin_configs[10] = { 1664 1669 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 1665 1670 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, ··· 1682 1675 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1683 1676 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1684 1677 [STAC_DELL_S14] = dell_s14_pin_configs, 1678 + [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, 1685 1679 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, 1686 1680 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1687 1681 }; ··· 1692 1684 [STAC_92HD83XXX_REF] = "ref", 1693 1685 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1694 1686 [STAC_DELL_S14] = "dell-s14", 1687 + [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", 1695 1688 [STAC_92HD83XXX_HP] = "hp", 1696 1689 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", 1697 1690 [STAC_HP_DV7_4000] = "hp-dv7-4000", ··· 1706 1697 "DFI LanParty", STAC_92HD83XXX_REF), 1707 1698 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, 1708 1699 "unknown Dell", STAC_DELL_S14), 1700 + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, 1701 + "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), 1709 1702 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, 1710 1703 "HP", STAC_92HD83XXX_HP), 1711 1704 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
+47 -11
sound/pci/intel8x0.c
··· 1077 1077 } 1078 1078 if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) 1079 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 1087 if (chip->inside_vm) 1081 1088 break; 1082 1089 if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) ··· 2937 2930 ICH_PCR, ICH_SCR, ICH_SIS_TCR 2938 2931 }; 2939 2932 2933 + static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci) 2934 + { 2935 + int result = inside_vm; 2936 + char *msg = NULL; 2937 + 2938 + /* check module parameter first (override detection) */ 2939 + if (result >= 0) { 2940 + msg = result ? "enable (forced) VM" : "disable (forced) VM"; 2941 + goto fini; 2942 + } 2943 + 2944 + /* detect KVM and Parallels virtual environments */ 2945 + result = kvm_para_available(); 2946 + #ifdef X86_FEATURE_HYPERVISOR 2947 + result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR); 2948 + #endif 2949 + if (!result) 2950 + goto fini; 2951 + 2952 + /* check for known (emulated) devices */ 2953 + if (pci->subsystem_vendor == 0x1af4 && 2954 + pci->subsystem_device == 0x1100) { 2955 + /* KVM emulated sound, PCI SSID: 1af4:1100 */ 2956 + msg = "enable KVM"; 2957 + } else if (pci->subsystem_vendor == 0x1ab8) { 2958 + /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */ 2959 + msg = "enable Parallels VM"; 2960 + } else { 2961 + msg = "disable (unknown or VT-d) VM"; 2962 + result = 0; 2963 + } 2964 + 2965 + fini: 2966 + if (msg != NULL) 2967 + printk(KERN_INFO "intel8x0: %s optimization\n", msg); 2968 + 2969 + return result; 2970 + } 2971 + 2940 2972 static int __devinit snd_intel8x0_create(struct snd_card *card, 2941 2973 struct pci_dev *pci, 2942 2974 unsigned long device_type, ··· 3043 2997 if (xbox) 3044 2998 chip->xbox = 1; 3045 2999 3046 - chip->inside_vm = inside_vm; 3047 - if (inside_vm) 3048 - printk(KERN_INFO "intel8x0: enable KVM optimization\n"); 3000 + chip->inside_vm = snd_intel8x0_inside_vm(pci); 3049 3001 3050 3002 if (pci->vendor == PCI_VENDOR_ID_INTEL && 3051 3003 pci->device == PCI_DEVICE_ID_INTEL_440MX) ··· 3285 3241 buggy_irq = 1; 3286 3242 else 3287 3243 buggy_irq = 0; 3288 - } 3289 - 3290 - if (inside_vm < 0) { 3291 - /* detect KVM and Parallels virtual environments */ 3292 - inside_vm = kvm_para_available(); 3293 - #if defined(__i386__) || defined(__x86_64__) 3294 - inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); 3295 - #endif 3296 3244 } 3297 3245 3298 3246 if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
+29 -14
sound/soc/codecs/wm8994.c
··· 56 56 static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) 57 57 { 58 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 61 switch (reg) { 62 62 case WM8994_GPIO_1: ··· 3030 3030 { 3031 3031 struct wm8994_priv *wm8994 = data; 3032 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); 3036 - if (reg < 0) { 3037 - dev_err(codec->dev, "Failed to read mic detect status: %d\n", 3038 - reg); 3039 - return IRQ_NONE; 3040 - } 3035 + /* We may occasionally read a detection without an impedence 3036 + * range being provided - if that happens loop again. 3037 + */ 3038 + count = 10; 3039 + do { 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)) { 3043 - dev_dbg(codec->dev, "Mic detect data not valid\n"); 3044 - goto out; 3045 - } 3048 + if (!(reg & WM8958_MICD_VALID)) { 3049 + dev_dbg(codec->dev, "Mic detect data not valid\n"); 3050 + goto out; 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 3062 #ifndef CONFIG_SND_SOC_WM8994_MODULE 3048 3063 trace_snd_soc_jack_irq(dev_name(codec->dev)); ··· 3195 3180 3196 3181 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, 3197 3182 wm8994_fifo_error, "FIFO error", codec); 3198 - wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN, 3183 + wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, 3199 3184 wm8994_temp_warn, "Thermal warning", codec); 3200 - wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT, 3185 + wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, 3201 3186 wm8994_temp_shut, "Thermal shutdown", codec); 3202 3187 3203 3188 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
+60 -50
sound/usb/mixer.c
··· 765 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 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 824 /* for failsafe */ 774 825 cval->min = default_min; ··· 895 844 cval->initialized = 1; 896 845 } 897 846 847 + if (kctl) 848 + volume_control_quirks(cval, kctl); 849 + 898 850 /* USB descriptions contain the dB scale in 1/256 dB unit 899 851 * while ALSA TLV contains in 1/100 dB unit 900 852 */ ··· 918 864 return 0; 919 865 } 920 866 867 + #define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) 921 868 922 869 /* get a feature/mixer unit info */ 923 870 static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) ··· 937 882 uinfo->value.integer.max = 1; 938 883 } else { 939 884 if (!cval->initialized) { 940 - get_min_max(cval, 0); 885 + get_min_max_with_quirks(cval, 0, kcontrol); 941 886 if (cval->initialized && cval->dBmin >= cval->dBmax) { 942 887 kcontrol->vd[0].access &= 943 888 ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | ··· 1100 1045 cval->ch_readonly = readonly_mask; 1101 1046 } 1102 1047 1103 - /* get min/max values */ 1104 - get_min_max(cval, 0); 1105 - 1106 1048 /* if all channels in the mask are marked read-only, make the control 1107 1049 * read-only. set_cur_mix_value() will check the mask again and won't 1108 1050 * issue write commands to read-only channels. */ ··· 1120 1068 if (! len && nameid) 1121 1069 len = snd_usb_copy_string_desc(state, nameid, 1122 1070 kctl->id.name, sizeof(kctl->id.name)); 1071 + 1072 + /* get min/max values */ 1073 + get_min_max_with_quirks(cval, 0, kctl); 1123 1074 1124 1075 switch (control) { 1125 1076 case UAC_FU_MUTE: ··· 1171 1116 strlcpy(kctl->id.name, audio_feature_info[control-1].name, 1172 1117 sizeof(kctl->id.name)); 1173 1118 break; 1174 - } 1175 - 1176 - /* volume control quirks */ 1177 - switch (state->chip->usb_id) { 1178 - case USB_ID(0x0471, 0x0101): 1179 - case USB_ID(0x0471, 0x0104): 1180 - case USB_ID(0x0471, 0x0105): 1181 - case USB_ID(0x0672, 0x1041): 1182 - /* quirk for UDA1321/N101. 1183 - * note that detection between firmware 2.1.1.7 (N101) 1184 - * and later 2.1.1.21 is not very clear from datasheets. 1185 - * I hope that the min value is -15360 for newer firmware --jk 1186 - */ 1187 - if (!strcmp(kctl->id.name, "PCM Playback Volume") && 1188 - cval->min == -15616) { 1189 - snd_printk(KERN_INFO 1190 - "set volume quirk for UDA1321/N101 chip\n"); 1191 - cval->max = -256; 1192 - } 1193 - break; 1194 - 1195 - case USB_ID(0x046d, 0x09a4): 1196 - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { 1197 - snd_printk(KERN_INFO 1198 - "set volume quirk for QuickCam E3500\n"); 1199 - cval->min = 6080; 1200 - cval->max = 8768; 1201 - cval->res = 192; 1202 - } 1203 - break; 1204 - 1205 - case USB_ID(0x046d, 0x0808): 1206 - case USB_ID(0x046d, 0x0809): 1207 - case USB_ID(0x046d, 0x0991): 1208 - /* Most audio usb devices lie about volume resolution. 1209 - * Most Logitech webcams have res = 384. 1210 - * Proboly there is some logitech magic behind this number --fishor 1211 - */ 1212 - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { 1213 - snd_printk(KERN_INFO 1214 - "set resolution quirk: cval->res = 384\n"); 1215 - cval->res = 384; 1216 - } 1217 - break; 1218 - 1219 1119 } 1220 1120 1221 1121 range = (cval->max - cval->min) / cval->res;
+3 -4
sound/usb/quirks.c
··· 137 137 return -ENOMEM; 138 138 } 139 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 142 if (!rate_table) { 142 143 kfree(fp); 143 144 return -ENOMEM; 144 145 } 145 - memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates); 146 146 fp->rate_table = rate_table; 147 147 } 148 148 ··· 224 224 if (altsd->bNumEndpoints != 1) 225 225 return -ENXIO; 226 226 227 - fp = kmalloc(sizeof(*fp), GFP_KERNEL); 227 + fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL); 228 228 if (!fp) 229 229 return -ENOMEM; 230 - memcpy(fp, &ua_format, sizeof(*fp)); 231 230 232 231 fp->iface = altsd->bInterfaceNumber; 233 232 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;