diff --git a/[refs] b/[refs] index 41a773d1e6d6..6a11627e89b4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 645e903528ca6cd510f9ac71a6a23de1a4d931e3 +refs/heads/master: 68bfcafaaeebdf23fba0edb4e0964bef7d08f92a diff --git a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt index edad99abec21..4f3443230d89 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt @@ -349,7 +349,6 @@ STAC92HD83* ref Reference board mic-ref Reference board with power management for ports dell-s14 Dell laptop - dell-vostro-3500 Dell Vostro 3500 laptop hp HP laptops with (inverted) mute-LED hp-dv7-4000 HP dv-7 4000 auto BIOS setup (default) diff --git a/trunk/Documentation/sound/alsa/HD-Audio.txt b/trunk/Documentation/sound/alsa/HD-Audio.txt index 91fee3b45fb8..03e2771ddeef 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio.txt @@ -579,7 +579,7 @@ Development Tree ~~~~~~~~~~~~~~~~ The latest development codes for HD-audio are found on sound git tree: -- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git +- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git The master branch or for-next branches can be used as the main development branches in general while the HD-audio specific patches @@ -594,7 +594,7 @@ is, installed via the usual spells: configure, make and make install(-modules). See INSTALL in the package. The snapshot tarballs are found at: -- ftp://ftp.suse.com/pub/people/tiwai/snapshot/ +- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/snapshot/ Sending a Bug Report @@ -696,7 +696,7 @@ via hda-verb won't change the mixer value. The hda-verb program is found in the ftp directory: -- ftp://ftp.suse.com/pub/people/tiwai/misc/ +- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/ Also a git repository is available: @@ -764,7 +764,7 @@ operation, the jack plugging simulation, etc. The package is found in: -- ftp://ftp.suse.com/pub/people/tiwai/misc/ +- ftp://ftp.kernel.org/pub/linux/kernel/people/tiwai/misc/ A git repository is available: diff --git a/trunk/sound/core/vmaster.c b/trunk/sound/core/vmaster.c index 130cfe677d60..5dbab38d04af 100644 --- a/trunk/sound/core/vmaster.c +++ b/trunk/sound/core/vmaster.c @@ -52,7 +52,6 @@ struct link_slave { struct link_ctl_info info; int vals[2]; /* current values */ unsigned int flags; - struct snd_kcontrol *kctl; /* original kcontrol pointer */ struct snd_kcontrol slave; /* the copy of original control entry */ }; @@ -253,7 +252,6 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, slave->count * sizeof(*slave->vd), GFP_KERNEL); if (!srec) return -ENOMEM; - srec->kctl = slave; srec->slave = *slave; memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); srec->master = master_link; @@ -335,18 +333,10 @@ static int master_put(struct snd_kcontrol *kcontrol, static void master_free(struct snd_kcontrol *kcontrol) { struct link_master *master = snd_kcontrol_chip(kcontrol); - struct link_slave *slave, *n; - - /* free all slave links and retore the original slave kctls */ - list_for_each_entry_safe(slave, n, &master->slaves, list) { - struct snd_kcontrol *sctl = slave->kctl; - struct list_head olist = sctl->list; - memcpy(sctl, &slave->slave, sizeof(*sctl)); - memcpy(sctl->vd, slave->slave.vd, - sctl->count * sizeof(*sctl->vd)); - sctl->list = olist; /* keep the current linked-list */ - kfree(slave); - } + struct link_slave *slave; + + list_for_each_entry(slave, &master->slaves, list) + slave->master = NULL; kfree(master); } diff --git a/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c b/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c index dbf94b189e75..e083122ca55a 100644 --- a/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -148,7 +148,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au, struct cs5535audio_dma_desc *desc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i]; desc->addr = cpu_to_le32(addr); - desc->size = cpu_to_le16(period_bytes); + desc->size = cpu_to_le32(period_bytes); desc->ctlreserved = cpu_to_le16(PRD_EOP); desc_addr += sizeof(struct cs5535audio_dma_desc); addr += period_bytes; diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 4562e9de6a1a..916a1863af73 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -2331,39 +2331,6 @@ int snd_hda_codec_reset(struct hda_codec *codec) return 0; } -typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); - -/* apply the function to all matching slave ctls in the mixer list */ -static int map_slaves(struct hda_codec *codec, const char * const *slaves, - map_slave_func_t func, void *data) -{ - struct hda_nid_item *items; - const char * const *s; - int i, err; - - items = codec->mixers.list; - for (i = 0; i < codec->mixers.used; i++) { - struct snd_kcontrol *sctl = items[i].kctl; - if (!sctl || !sctl->id.name || - sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) - continue; - for (s = slaves; *s; s++) { - if (!strcmp(sctl->id.name, *s)) { - err = func(data, sctl); - if (err) - return err; - break; - } - } - } - return 0; -} - -static int check_slave_present(void *data, struct snd_kcontrol *sctl) -{ - return 1; -} - /** * snd_hda_add_vmaster - create a virtual master control and add slaves * @codec: HD-audio codec @@ -2384,10 +2351,12 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, unsigned int *tlv, const char * const *slaves) { struct snd_kcontrol *kctl; + const char * const *s; int err; - err = map_slaves(codec, slaves, check_slave_present, NULL); - if (err != 1) { + for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) + ; + if (!*s) { snd_printdd("No slave found for %s\n", name); return 0; } @@ -2398,10 +2367,23 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, if (err < 0) return err; - err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, - kctl); - if (err < 0) - return err; + for (s = slaves; *s; s++) { + struct snd_kcontrol *sctl; + int i = 0; + for (;;) { + sctl = _snd_hda_find_mixer_ctl(codec, *s, i); + if (!sctl) { + if (!i) + snd_printdd("Cannot find slave %s, " + "skipped\n", *s); + break; + } + err = snd_ctl_add_slave(kctl, sctl); + if (err < 0) + return err; + i++; + } + } return 0; } EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); @@ -4046,9 +4028,9 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, /* Search for codec ID */ for (q = tbl; q->subvendor; q++) { - unsigned int mask = 0xffff0000 | q->subdevice_mask; - unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask; - if ((codec->subsystem_id & mask) == id) + unsigned long vendorid = (q->subdevice) | (q->subvendor << 16); + + if (vendorid == codec->subsystem_id) break; } @@ -4770,7 +4752,6 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = 0; - codec->ignore_misc_bit = true; end_nid = codec->start_nid + codec->num_nodes; for (nid = codec->start_nid; nid < end_nid; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); @@ -4786,9 +4767,6 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, continue; def_conf = snd_hda_codec_get_pincfg(codec, nid); - if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & - AC_DEFCFG_MISC_NO_PRESENCE)) - codec->ignore_misc_bit = false; conn = get_defcfg_connect(def_conf); if (conn == AC_JACK_PORT_NONE) continue; diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index 564471169cae..755f2b0f9d8e 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -854,7 +854,6 @@ struct hda_codec { unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ - unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ diff --git a/trunk/sound/pci/hda/hda_eld.c b/trunk/sound/pci/hda/hda_eld.c index c1da422e085a..1c8ddf547a2d 100644 --- a/trunk/sound/pci/hda/hda_eld.c +++ b/trunk/sound/pci/hda/hda_eld.c @@ -297,18 +297,10 @@ static int hdmi_update_eld(struct hdmi_eld *e, buf + ELD_FIXED_BYTES + mnl + 3 * i); } - /* - * HDMI sink's ELD info cannot always be retrieved for now, e.g. - * in console or for audio devices. Assume the highest speakers - * configuration, to _not_ prohibit multi-channel audio playback. - */ - if (!e->spk_alloc) - e->spk_alloc = 0xffff; - - e->eld_valid = true; return 0; out_fail: + e->eld_ver = 0; return -EINVAL; } @@ -331,6 +323,9 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, * ELD is valid, actual eld_size is assigned in hdmi_update_eld() */ + if (!eld->eld_valid) + return -ENOENT; + size = snd_hdmi_get_eld_size(codec, nid); if (size == 0) { /* wfg: workaround for ASUS P5E-VM HDMI board */ @@ -347,28 +342,18 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, for (i = 0; i < size; i++) { unsigned int val = hdmi_get_eld_data(codec, nid, i); - /* - * Graphics driver might be writing to ELD buffer right now. - * Just abort. The caller will repoll after a while. - */ if (!(val & AC_ELDD_ELD_VALID)) { + if (!i) { + snd_printd(KERN_INFO + "HDMI: invalid ELD data\n"); + ret = -EINVAL; + goto error; + } snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n", i); - ret = -EINVAL; - goto error; - } - val &= AC_ELDD_ELD_DATA; - /* - * The first byte cannot be zero. This can happen on some DVI - * connections. Some Intel chips may also need some 250ms delay - * to return non-zero ELD data, even when the graphics driver - * correctly writes ELD content before setting ELD_valid bit. - */ - if (!val && !i) { - snd_printdd(KERN_INFO "HDMI: 0 ELD data\n"); - ret = -EINVAL; - goto error; - } + val = 0; + } else + val &= AC_ELDD_ELD_DATA; buf[i] = val; } diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index c2f79e63124d..096507d2ca9a 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -2507,8 +2507,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), - SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS 1101HA", POS_FIX_LPIB), SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), @@ -2971,8 +2971,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */ - /* ICH */ + AZX_DCAPS_BUFSIZE}, { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_BUFSIZE }, /* ICH6 */ diff --git a/trunk/sound/pci/hda/hda_local.h b/trunk/sound/pci/hda/hda_local.h index 618ddad17236..dcbea0da0fa2 100644 --- a/trunk/sound/pci/hda/hda_local.h +++ b/trunk/sound/pci/hda/hda_local.h @@ -510,15 +510,13 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { - if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) - return false; - if (!codec->ignore_misc_bit && - (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & - AC_DEFCFG_MISC_NO_PRESENCE)) - return false; - if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) - return false; - return true; + return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && + /* disable MISC_NO_PRESENCE check because it may break too + * many devices + */ + /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & + AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ + (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); } /* flags for hda_nid_item */ @@ -653,9 +651,6 @@ struct hdmi_eld { int spk_alloc; int sad_count; struct cea_sad sad[ELD_MAX_SAD]; - /* - * all fields above eld_buffer will be cleared before updating ELD - */ char eld_buffer[ELD_MAX_SIZE]; #ifdef CONFIG_PROC_FS struct snd_info_entry *proc_entry; diff --git a/trunk/sound/pci/hda/patch_cirrus.c b/trunk/sound/pci/hda/patch_cirrus.c index 70a7abda7e22..2a2d8645ba09 100644 --- a/trunk/sound/pci/hda/patch_cirrus.c +++ b/trunk/sound/pci/hda/patch_cirrus.c @@ -58,8 +58,6 @@ struct cs_spec { unsigned int gpio_mask; unsigned int gpio_dir; unsigned int gpio_data; - unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */ - unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */ struct hda_pcm pcm_rec[2]; /* PCM information */ @@ -78,7 +76,6 @@ enum { CS420X_MBP53, CS420X_MBP55, CS420X_IMAC27, - CS420X_APPLE, CS420X_AUTO, CS420X_MODELS }; @@ -240,15 +237,6 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); } -static void cs_update_input_select(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - if (spec->cur_adc) - snd_hda_codec_write(codec, spec->cur_adc, 0, - AC_VERB_SET_CONNECT_SEL, - spec->adc_idx[spec->cur_input]); -} - /* * Analog capture */ @@ -262,7 +250,6 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_adc = spec->adc_nid[spec->cur_input]; spec->cur_adc_stream_tag = stream_tag; spec->cur_adc_format = format; - cs_update_input_select(codec); snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); return 0; } @@ -702,8 +689,10 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx, spec->cur_adc_stream_tag, 0, spec->cur_adc_format); } + snd_hda_codec_write(codec, spec->cur_adc, 0, + AC_VERB_SET_CONNECT_SEL, + spec->adc_idx[idx]); spec->cur_input = idx; - cs_update_input_select(codec); return 1; } @@ -931,9 +920,10 @@ static void cs_automute(struct hda_codec *codec) spdif_present ? 0 : PIN_OUT); } } - if (spec->gpio_eapd_hp) { - unsigned int gpio = hp_present ? - spec->gpio_eapd_hp : spec->gpio_eapd_speaker; + if (spec->board_config == CS420X_MBP53 || + spec->board_config == CS420X_MBP55 || + spec->board_config == CS420X_IMAC27) { + unsigned int gpio = hp_present ? 0x02 : 0x08; snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, gpio); } @@ -983,7 +973,10 @@ static void cs_automic(struct hda_codec *codec) } else { spec->cur_input = spec->last_input; } - cs_update_input_select(codec); + + snd_hda_codec_write_cache(codec, spec->cur_adc, 0, + AC_VERB_SET_CONNECT_SEL, + spec->adc_idx[spec->cur_input]); } else { if (present) change_cur_input(codec, spec->automic_idx, 0); @@ -1080,7 +1073,9 @@ static void init_input(struct hda_codec *codec) cs_automic(codec); else { spec->cur_adc = spec->adc_nid[spec->cur_input]; - cs_update_input_select(codec); + snd_hda_codec_write(codec, spec->cur_adc, 0, + AC_VERB_SET_CONNECT_SEL, + spec->adc_idx[spec->cur_input]); } } else { change_cur_input(codec, spec->cur_input, 1); @@ -1278,7 +1273,6 @@ static const char * const cs420x_models[CS420X_MODELS] = { [CS420X_MBP53] = "mbp53", [CS420X_MBP55] = "mbp55", [CS420X_IMAC27] = "imac27", - [CS420X_APPLE] = "apple", [CS420X_AUTO] = "auto", }; @@ -1288,13 +1282,7 @@ static const struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), - /* this conflicts with too many other models */ - /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ - {} /* terminator */ -}; - -static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = { - SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), + SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), {} /* terminator */ }; @@ -1376,10 +1364,6 @@ static int patch_cs420x(struct hda_codec *codec) spec->board_config = snd_hda_check_board_config(codec, CS420X_MODELS, cs420x_models, cs420x_cfg_tbl); - if (spec->board_config < 0) - spec->board_config = - snd_hda_check_board_codec_sid_config(codec, - CS420X_MODELS, NULL, cs420x_codec_cfg_tbl); if (spec->board_config >= 0) fix_pincfg(codec, spec->board_config, cs_pincfgs); @@ -1387,11 +1371,10 @@ static int patch_cs420x(struct hda_codec *codec) case CS420X_IMAC27: case CS420X_MBP53: case CS420X_MBP55: - case CS420X_APPLE: - spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */ - spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */ - spec->gpio_mask = spec->gpio_dir = - spec->gpio_eapd_hp | spec->gpio_eapd_speaker; + /* GPIO1 = headphones */ + /* GPIO3 = speakers */ + spec->gpio_mask = 0x0a; + spec->gpio_dir = 0x0a; break; } diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index 0de21193a2b0..5e706e4d1737 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -3062,6 +3062,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), + SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", CXT5066_LAPTOP), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), diff --git a/trunk/sound/pci/hda/patch_hdmi.c b/trunk/sound/pci/hda/patch_hdmi.c index c505fd5d338c..81b7b791b3c3 100644 --- a/trunk/sound/pci/hda/patch_hdmi.c +++ b/trunk/sound/pci/hda/patch_hdmi.c @@ -65,11 +65,7 @@ struct hdmi_spec_per_pin { hda_nid_t pin_nid; int num_mux_nids; hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; - - struct hda_codec *codec; struct hdmi_eld sink_eld; - struct delayed_work work; - int repoll_count; }; struct hdmi_spec { @@ -749,7 +745,8 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, * Unsolicited events */ -static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); +static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, + struct hdmi_eld *eld); static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) { @@ -758,6 +755,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) int pd = !!(res & AC_UNSOL_RES_PD); int eldv = !!(res & AC_UNSOL_RES_ELDV); int pin_idx; + struct hdmi_eld *eld; printk(KERN_INFO "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", @@ -766,8 +764,17 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) pin_idx = pin_nid_to_pin_index(spec, pin_nid); if (pin_idx < 0) return; + eld = &spec->pins[pin_idx].sink_eld; + + hdmi_present_sense(codec, pin_nid, eld); - hdmi_present_sense(&spec->pins[pin_idx], 1); + /* + * HDMI sink's ELD info cannot always be retrieved for now, e.g. + * in console or for audio devices. Assume the highest speakers + * configuration, to _not_ prohibit multi-channel audio playback. + */ + if (!eld->spk_alloc) + eld->spk_alloc = 0xffff; } static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -961,11 +968,9 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) return 0; } -static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) +static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, + struct hdmi_eld *eld) { - struct hda_codec *codec = per_pin->codec; - struct hdmi_eld *eld = &per_pin->sink_eld; - hda_nid_t pin_nid = per_pin->pin_nid; /* * Always execute a GetPinSense verb here, even when called from * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited @@ -975,42 +980,26 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) * the unsolicited response to avoid custom WARs. */ int present = snd_hda_pin_sense(codec, pin_nid); - bool eld_valid = false; - memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer)); + memset(eld, 0, sizeof(*eld)); eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); if (eld->monitor_present) - eld_valid = !!(present & AC_PINSENSE_ELDV); + eld->eld_valid = !!(present & AC_PINSENSE_ELDV); + else + eld->eld_valid = 0; printk(KERN_INFO "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, eld->monitor_present, eld_valid); + codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); - if (eld_valid) { + if (eld->eld_valid) if (!snd_hdmi_get_eld(eld, codec, pin_nid)) snd_hdmi_show_eld(eld); - else if (repoll) { - queue_delayed_work(codec->bus->workq, - &per_pin->work, - msecs_to_jiffies(300)); - } - } snd_hda_input_jack_report(codec, pin_nid); } -static void hdmi_repoll_eld(struct work_struct *work) -{ - struct hdmi_spec_per_pin *per_pin = - container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); - - if (per_pin->repoll_count++ > 6) - per_pin->repoll_count = 0; - - hdmi_present_sense(per_pin, per_pin->repoll_count); -} - static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) { struct hdmi_spec *spec = codec->spec; @@ -1239,7 +1228,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) if (err < 0) return err; - hdmi_present_sense(per_pin, 0); + hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld); return 0; } @@ -1290,8 +1279,6 @@ static int generic_hdmi_init(struct hda_codec *codec) AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | pin_nid); - per_pin->codec = codec; - INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); snd_hda_eld_proc_new(codec, eld, pin_idx); } return 0; @@ -1306,12 +1293,10 @@ static void generic_hdmi_free(struct hda_codec *codec) struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; struct hdmi_eld *eld = &per_pin->sink_eld; - cancel_delayed_work(&per_pin->work); snd_hda_eld_proc_free(codec, eld); } snd_hda_input_jack_free(codec); - flush_workqueue(codec->bus->workq); kfree(spec); } diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 1d07e8fa2433..a24e068a021b 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -277,12 +277,6 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) return false; } -static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) -{ - return spec->capsrc_nids ? - spec->capsrc_nids[idx] : spec->adc_nids[idx]; -} - /* select the given imux item; either unmute exclusively or select the route */ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, unsigned int idx, bool force) @@ -290,15 +284,13 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, struct alc_spec *spec = codec->spec; const struct hda_input_mux *imux; unsigned int mux_idx; - int i, type, num_conns; + int i, type; hda_nid_t nid; mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; imux = &spec->input_mux[mux_idx]; if (!imux->num_items && mux_idx > 0) imux = &spec->input_mux[0]; - if (!imux->num_items) - return 0; if (idx >= imux->num_items) idx = imux->num_items - 1; @@ -311,20 +303,20 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, adc_idx = spec->dyn_adc_idx[idx]; } - nid = get_capsrc(spec, adc_idx); + nid = spec->capsrc_nids ? + spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; /* no selection? */ - num_conns = snd_hda_get_conn_list(codec, nid, NULL); - if (num_conns <= 1) + if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) return 1; type = get_wcaps_type(get_wcaps(codec, nid)); if (type == AC_WID_AUD_MIX) { /* Matrix-mixer style (e.g. ALC882) */ - int active = imux->items[idx].index; - for (i = 0; i < num_conns; i++) { - unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; - snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, + for (i = 0; i < imux->num_items; i++) { + unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, + imux->items[i].index, HDA_AMP_MUTE, v); } } else { @@ -1061,19 +1053,8 @@ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) spec->imux_pins[2] = spec->dock_mic_pin; for (i = 0; i < 3; i++) { strcpy(imux->items[i].label, texts[i]); - if (spec->imux_pins[i]) { - hda_nid_t pin = spec->imux_pins[i]; - int c; - for (c = 0; c < spec->num_adc_nids; c++) { - hda_nid_t cap = get_capsrc(spec, c); - int idx = get_connection_index(codec, cap, pin); - if (idx >= 0) { - imux->items[i].index = idx; - break; - } - } + if (spec->imux_pins[i]) imux->num_items = i + 1; - } } spec->num_mux_defs = 1; spec->input_mux = imux; @@ -1470,7 +1451,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) switch (fix->type) { case ALC_FIXUP_SKU: if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) - break; + break;; snd_printdd(KERN_INFO "hda_codec: %s: " "Apply sku override for %s\n", codec->chip_name, modelname); @@ -1975,8 +1956,10 @@ static int alc_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nid(codec, kctl, i, - get_capsrc(spec, i)); + const hda_nid_t *nids = spec->capsrc_nids; + if (!nids) + nids = spec->adc_nids; + err = snd_hda_add_nid(codec, kctl, i, nids[i]); if (err < 0) return err; } @@ -2631,8 +2614,6 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, case AUTO_PIN_SPEAKER_OUT: if (cfg->line_outs == 1) return "Speaker"; - if (cfg->line_outs == 2) - return ch ? "Bass Speaker" : "Speaker"; break; case AUTO_PIN_HP_OUT: /* for multi-io case, only the primary out */ @@ -2765,7 +2746,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) } for (c = 0; c < num_adcs; c++) { - hda_nid_t cap = get_capsrc(spec, c); + hda_nid_t cap = spec->capsrc_nids ? + spec->capsrc_nids[c] : spec->adc_nids[c]; idx = get_connection_index(codec, cap, pin); if (idx >= 0) { spec->imux_pins[imux->num_items] = pin; @@ -2906,7 +2888,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) if (!nid) continue; if (found_in_nid_list(nid, spec->multiout.dac_nids, - ARRAY_SIZE(spec->private_dac_nids))) + spec->multiout.num_dacs)) continue; if (found_in_nid_list(nid, spec->multiout.hp_out_nid, ARRAY_SIZE(spec->multiout.hp_out_nid))) @@ -2927,7 +2909,6 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) return 0; } -/* return 0 if no possible DAC is found, 1 if one or more found */ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, const hda_nid_t *pins, hda_nid_t *dacs) { @@ -2945,7 +2926,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, if (!dacs[i]) dacs[i] = alc_auto_look_for_dac(codec, pins[i]); } - return 1; + return 0; } static int alc_auto_fill_multi_ios(struct hda_codec *codec, @@ -2955,7 +2936,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, static int alc_auto_fill_dac_nids(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; + const struct auto_pin_cfg *cfg = &spec->autocfg; bool redone = false; int i; @@ -2966,7 +2947,6 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) spec->multiout.extra_out_nid[0] = 0; memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); spec->multiout.dac_nids = spec->private_dac_nids; - spec->multi_ios = 0; /* fill hard-wired DACs first */ if (!redone) { @@ -3000,12 +2980,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) for (i = 0; i < cfg->line_outs; i++) { if (spec->private_dac_nids[i]) spec->multiout.num_dacs++; - else { + else memmove(spec->private_dac_nids + i, spec->private_dac_nids + i + 1, sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); - spec->private_dac_nids[cfg->line_outs - 1] = 0; - } } if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { @@ -3027,28 +3005,9 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) if (cfg->line_out_type != AUTO_PIN_HP_OUT) alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, spec->multiout.hp_out_nid); - if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { - int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, - cfg->speaker_pins, - spec->multiout.extra_out_nid); - /* if no speaker volume is assigned, try again as the primary - * output - */ - if (!err && cfg->speaker_outs > 0 && - cfg->line_out_type == AUTO_PIN_HP_OUT) { - cfg->hp_outs = cfg->line_outs; - memcpy(cfg->hp_pins, cfg->line_out_pins, - sizeof(cfg->hp_pins)); - cfg->line_outs = cfg->speaker_outs; - memcpy(cfg->line_out_pins, cfg->speaker_pins, - sizeof(cfg->speaker_pins)); - cfg->speaker_outs = 0; - memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); - cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; - redone = false; - goto again; - } - } + if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) + alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, + spec->multiout.extra_out_nid); return 0; } @@ -3198,8 +3157,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, } static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, - hda_nid_t dac, const char *pfx, - int cidx) + hda_nid_t dac, const char *pfx) { struct alc_spec *spec = codec->spec; hda_nid_t sw, vol; @@ -3215,15 +3173,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, if (is_ctl_used(spec->sw_ctls, val)) return 0; /* already created */ mark_ctl_usage(spec->sw_ctls, val); - return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); + return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); } sw = alc_look_for_out_mute_nid(codec, pin, dac); vol = alc_look_for_out_vol_nid(codec, pin, dac); - err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); + err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); if (err < 0) return err; - err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); + err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); if (err < 0) return err; return 0; @@ -3264,21 +3222,16 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, hda_nid_t dac = *dacs; if (!dac) dac = spec->multiout.dac_nids[0]; - return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); + return alc_auto_create_extra_out(codec, *pins, dac, pfx); } if (dacs[num_pins - 1]) { /* OK, we have a multi-output system with individual volumes */ for (i = 0; i < num_pins; i++) { - if (num_pins >= 3) { - snprintf(name, sizeof(name), "%s %s", - pfx, channel_name[i]); - err = alc_auto_create_extra_out(codec, pins[i], dacs[i], - name, 0); - } else { - err = alc_auto_create_extra_out(codec, pins[i], dacs[i], - pfx, i); - } + snprintf(name, sizeof(name), "%s %s", + pfx, channel_name[i]); + err = alc_auto_create_extra_out(codec, pins[i], dacs[i], + name); if (err < 0) return err; } @@ -3740,7 +3693,8 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) if (!pin) return 0; for (i = 0; i < spec->num_adc_nids; i++) { - hda_nid_t cap = get_capsrc(spec, i); + hda_nid_t cap = spec->capsrc_nids ? + spec->capsrc_nids[i] : spec->adc_nids[i]; int idx; idx = get_connection_index(codec, cap, pin); diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 616678fde486..4e715fefebef 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -95,7 +95,6 @@ enum { STAC_92HD83XXX_REF, STAC_92HD83XXX_PWR_REF, STAC_DELL_S14, - STAC_DELL_VOSTRO_3500, STAC_92HD83XXX_HP, STAC_92HD83XXX_HP_cNB11_INTQUAD, STAC_HP_DV7_4000, @@ -215,7 +214,6 @@ struct sigmatel_spec { unsigned int gpio_mute; unsigned int gpio_led; unsigned int gpio_led_polarity; - unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ unsigned int vref_led; /* stream */ @@ -228,6 +226,7 @@ struct sigmatel_spec { /* power management */ unsigned int num_pwrs; + const unsigned int *pwr_mapping; const hda_nid_t *pwr_nids; const hda_nid_t *dac_list; @@ -374,15 +373,18 @@ static const unsigned long stac92hd73xx_capvols[] = { #define STAC92HD83_DAC_COUNT 3 -static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { - 0x0a, 0x0b, 0x0c, 0xd, 0x0e, - 0x0f, 0x10 +static const hda_nid_t stac92hd83xxx_pwr_nids[4] = { + 0xa, 0xb, 0xd, 0xe, }; static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { 0x1e, 0, }; +static const unsigned int stac92hd83xxx_pwr_mapping[4] = { + 0x03, 0x0c, 0x20, 0x40, +}; + static const hda_nid_t stac92hd83xxx_dmic_nids[] = { 0x11, 0x20, }; @@ -1642,8 +1644,6 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { "Alienware M17x", STAC_ALIENWARE_M17X), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, "Alienware M17x", STAC_ALIENWARE_M17X), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, - "Alienware M17x", STAC_ALIENWARE_M17X), {} /* terminator */ }; @@ -1659,12 +1659,6 @@ static const unsigned int dell_s14_pin_configs[10] = { 0x40f000f0, 0x40f000f0, }; -static const unsigned int dell_vostro_3500_pin_configs[10] = { - 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, - 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, - 0x400000f4, 0x400000f5, -}; - static const unsigned int hp_dv7_4000_pin_configs[10] = { 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, @@ -1681,7 +1675,6 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, [STAC_DELL_S14] = dell_s14_pin_configs, - [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, }; @@ -1691,7 +1684,6 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = "ref", [STAC_92HD83XXX_PWR_REF] = "mic-ref", [STAC_DELL_S14] = "dell-s14", - [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", [STAC_92HD83XXX_HP] = "hp", [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", [STAC_HP_DV7_4000] = "hp-dv7-4000", @@ -1705,8 +1697,6 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "DFI LanParty", STAC_92HD83XXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, "unknown Dell", STAC_DELL_S14), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, - "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, "HP", STAC_92HD83XXX_HP), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, @@ -4319,10 +4309,12 @@ static void stac_store_hints(struct hda_codec *codec) spec->eapd_switch = val; get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { - spec->gpio_mask |= spec->gpio_led; - spec->gpio_dir |= spec->gpio_led; - if (spec->gpio_led_polarity) - spec->gpio_data |= spec->gpio_led; + if (spec->gpio_led <= 8) { + spec->gpio_mask |= spec->gpio_led; + spec->gpio_dir |= spec->gpio_led; + if (spec->gpio_led_polarity) + spec->gpio_data |= spec->gpio_led; + } } } @@ -4440,9 +4432,7 @@ static int stac92xx_init(struct hda_codec *codec) int pinctl, def_conf; /* power on when no jack detection is available */ - /* or when the VREF is used for controlling LED */ - if (!spec->hp_detect || - spec->vref_mute_led_nid == nid) { + if (!spec->hp_detect) { stac_toggle_power_map(codec, nid, 1); continue; } @@ -4469,12 +4459,8 @@ static int stac92xx_init(struct hda_codec *codec) stac_toggle_power_map(codec, nid, 1); continue; } - if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) { + if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) stac_issue_unsol_event(codec, nid); - continue; - } - /* none of the above, turn the port OFF */ - stac_toggle_power_map(codec, nid, 0); } /* sync mute LED */ @@ -4730,7 +4716,11 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, if (idx >= spec->num_pwrs) return; - idx = 1 << idx; + /* several codecs have two power down bits */ + if (spec->pwr_mapping) + idx = spec->pwr_mapping[idx]; + else + idx = 1 << idx; val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; if (enable) @@ -4914,14 +4904,8 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &spec->gpio_led_polarity, &spec->gpio_led) == 2) { - unsigned int max_gpio; - max_gpio = snd_hda_param_read(codec, codec->afg, - AC_PAR_GPIO_CAP); - max_gpio &= AC_GPIO_IO_COUNT; - if (spec->gpio_led < max_gpio) + if (spec->gpio_led < 4) spec->gpio_led = 1 << spec->gpio_led; - else - spec->vref_mute_led_nid = spec->gpio_led; return 1; } if (sscanf(dev->name, "HP_Mute_LED_%d", @@ -4929,12 +4913,6 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) set_hp_led_gpio(codec); return 1; } - /* BIOS bug: unfilled OEM string */ - if (strstr(dev->name, "HP_Mute_LED_P_G")) { - set_hp_led_gpio(codec); - spec->gpio_led_polarity = 1; - return 1; - } } /* @@ -5056,12 +5034,29 @@ static int stac92xx_pre_resume(struct hda_codec *codec) struct sigmatel_spec *spec = codec->spec; /* sync mute LED */ - if (spec->vref_mute_led_nid) - stac_vrefout_set(codec, spec->vref_mute_led_nid, - spec->vref_led); - else if (spec->gpio_led) - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data); + if (spec->gpio_led) { + if (spec->gpio_led <= 8) { + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data); + } else { + stac_vrefout_set(codec, + spec->gpio_led, spec->vref_led); + } + } + return 0; +} + +static int stac92xx_post_suspend(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + if (spec->gpio_led > 8) { + /* with vref-out pin used for mute led control + * codec AFG is prevented from D3 state, but on + * system suspend it can (and should) be used + */ + snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + } return 0; } @@ -5072,7 +5067,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, struct sigmatel_spec *spec = codec->spec; if (power_state == AC_PWRST_D3) { - if (spec->vref_mute_led_nid) { + if (spec->gpio_led > 8) { /* with vref-out pin used for mute led control * codec AFG is prevented from D3 state */ @@ -5125,7 +5120,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) } } /*polarity defines *not* muted state level*/ - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { if (muted) spec->gpio_data &= ~spec->gpio_led; /* orange */ else @@ -5143,8 +5138,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) muted_lvl = spec->gpio_led_polarity ? AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; spec->vref_led = muted ? muted_lvl : notmtd_lvl; - stac_vrefout_set(codec, spec->vref_mute_led_nid, - spec->vref_led); + stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); } return 0; } @@ -5624,6 +5618,9 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); } + /* reset pin power-down; Windows may leave these bits after reboot */ + snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0); + snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); codec->no_trigger_sense = 1; codec->spec = spec; @@ -5633,6 +5630,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->digbeep_nid = 0x21; spec->pwr_nids = stac92hd83xxx_pwr_nids; + spec->pwr_mapping = stac92hd83xxx_pwr_mapping; spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); spec->multiout.dac_nids = spec->dac_nids; spec->init = stac92hd83xxx_core_init; @@ -5649,6 +5647,9 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) stac92xx_set_config_regs(codec, stac92hd83xxx_brd_tbl[spec->board_config]); + if (spec->board_config != STAC_92HD83XXX_PWR_REF) + spec->num_pwrs = 0; + codec->patch_ops = stac92xx_patch_ops; if (find_mute_led_gpio(codec, 0)) @@ -5658,13 +5659,15 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; } else { codec->patch_ops.set_power_state = stac92xx_set_power_state; + codec->patch_ops.post_suspend = + stac92xx_post_suspend; } codec->patch_ops.pre_resume = stac92xx_pre_resume; codec->patch_ops.check_power_status = @@ -5855,6 +5858,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) (codec->revision_id & 0xf) == 1) spec->stream_delay = 40; /* 40 milliseconds */ + /* no output amps */ + spec->num_pwrs = 0; /* disable VSW */ spec->init = stac92hd71bxx_core_init; unmute_init++; @@ -5869,6 +5874,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) if ((codec->revision_id & 0xf) == 1) spec->stream_delay = 40; /* 40 milliseconds */ + /* no output amps */ + spec->num_pwrs = 0; /* fallthru */ default: spec->init = stac92hd71bxx_core_init; @@ -5971,13 +5978,15 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; } else { codec->patch_ops.set_power_state = stac92xx_set_power_state; + codec->patch_ops.post_suspend = + stac92xx_post_suspend; } codec->patch_ops.pre_resume = stac92xx_pre_resume; codec->patch_ops.check_power_status = diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index b5137629f8e9..431c0d417eeb 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -208,7 +208,6 @@ struct via_spec { /* work to check hp jack state */ struct hda_codec *codec; struct delayed_work vt1708_hp_work; - int hp_work_active; int vt1708_jack_detect; int vt1708_hp_present; @@ -306,35 +305,27 @@ enum { static void analog_low_current_mode(struct hda_codec *codec); static bool is_aa_path_mute(struct hda_codec *codec); -#define hp_detect_with_aa(codec) \ - (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \ - !is_aa_path_mute(codec)) - -static void vt1708_stop_hp_work(struct via_spec *spec) +static void vt1708_start_hp_work(struct via_spec *spec) { if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) return; - if (spec->hp_work_active) { - snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1); - cancel_delayed_work_sync(&spec->vt1708_hp_work); - spec->hp_work_active = 0; - } + snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, + !spec->vt1708_jack_detect); + if (!delayed_work_pending(&spec->vt1708_hp_work)) + schedule_delayed_work(&spec->vt1708_hp_work, + msecs_to_jiffies(100)); } -static void vt1708_update_hp_work(struct via_spec *spec) +static void vt1708_stop_hp_work(struct via_spec *spec) { if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) return; - if (spec->vt1708_jack_detect && - (spec->active_streams || hp_detect_with_aa(spec->codec))) { - if (!spec->hp_work_active) { - snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0); - schedule_delayed_work(&spec->vt1708_hp_work, - msecs_to_jiffies(100)); - spec->hp_work_active = 1; - } - } else if (!hp_detect_with_aa(spec->codec)) - vt1708_stop_hp_work(spec); + if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1 + && !is_aa_path_mute(spec->codec)) + return; + snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, + !spec->vt1708_jack_detect); + cancel_delayed_work_sync(&spec->vt1708_hp_work); } static void set_widgets_power_state(struct hda_codec *codec) @@ -352,7 +343,12 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, set_widgets_power_state(codec); analog_low_current_mode(snd_kcontrol_chip(kcontrol)); - vt1708_update_hp_work(codec->spec); + if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { + if (is_aa_path_mute(codec)) + vt1708_start_hp_work(codec->spec); + else + vt1708_stop_hp_work(codec->spec); + } return change; } @@ -1158,7 +1154,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_dac_stream_tag = stream_tag; spec->cur_dac_format = format; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_start_hp_work(spec); return 0; } @@ -1178,7 +1174,7 @@ static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_hp_stream_tag = stream_tag; spec->cur_hp_format = format; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_start_hp_work(spec); return 0; } @@ -1192,7 +1188,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); spec->active_streams &= ~STREAM_MULTI_OUT; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_stop_hp_work(spec); return 0; } @@ -1207,7 +1203,7 @@ static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo, snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0); spec->active_streams &= ~STREAM_INDEP_HP; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_stop_hp_work(spec); return 0; } @@ -1649,8 +1645,7 @@ static void via_hp_automute(struct hda_codec *codec) int nums; struct via_spec *spec = codec->spec; - if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] && - (spec->codec_type != VT1708 || spec->vt1708_jack_detect)) + if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0]) present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); if (spec->smart51_enabled) @@ -2617,6 +2612,8 @@ static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol, if (spec->codec_type != VT1708) return 0; + spec->vt1708_jack_detect = + !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1); ucontrol->value.integer.value[0] = spec->vt1708_jack_detect; return 0; } @@ -2626,22 +2623,18 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct via_spec *spec = codec->spec; - int val; + int change; if (spec->codec_type != VT1708) return 0; - val = !!ucontrol->value.integer.value[0]; - if (spec->vt1708_jack_detect == val) - return 0; - spec->vt1708_jack_detect = val; - if (spec->vt1708_jack_detect && - snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) { + spec->vt1708_jack_detect = ucontrol->value.integer.value[0]; + change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) + == !spec->vt1708_jack_detect; + if (spec->vt1708_jack_detect) { mute_aa_path(codec, 1); notify_aa_path_ctls(codec); } - via_hp_automute(codec); - vt1708_update_hp_work(spec); - return 1; + return change; } static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { @@ -2778,7 +2771,6 @@ static int via_init(struct hda_codec *codec) via_auto_init_unsol_event(codec); via_hp_automute(codec); - vt1708_update_hp_work(spec); return 0; } @@ -2795,9 +2787,7 @@ static void vt1708_update_hp_jack_state(struct work_struct *work) spec->vt1708_hp_present ^= 1; via_hp_automute(spec->codec); } - if (spec->vt1708_jack_detect) - schedule_delayed_work(&spec->vt1708_hp_work, - msecs_to_jiffies(100)); + vt1708_start_hp_work(spec); } static int get_mux_nids(struct hda_codec *codec) diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index 11718b49b2e2..29e312597f20 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -1077,13 +1077,6 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs } if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) continue; - - /* IO read operation is very expensive inside virtual machine - * as it is emulated. The probability that subsequent PICB read - * will return different result is high enough to loop till - * timeout here. - * Same CIV is strict enough condition to be sure that PICB - * is valid inside VM on emulated card. */ if (chip->inside_vm) break; if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) @@ -2937,45 +2930,6 @@ static unsigned int sis_codec_bits[3] = { ICH_PCR, ICH_SCR, ICH_SIS_TCR }; -static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci) -{ - int result = inside_vm; - char *msg = NULL; - - /* check module parameter first (override detection) */ - if (result >= 0) { - msg = result ? "enable (forced) VM" : "disable (forced) VM"; - goto fini; - } - - /* detect KVM and Parallels virtual environments */ - result = kvm_para_available(); -#ifdef X86_FEATURE_HYPERVISOR - result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR); -#endif - if (!result) - goto fini; - - /* check for known (emulated) devices */ - if (pci->subsystem_vendor == 0x1af4 && - pci->subsystem_device == 0x1100) { - /* KVM emulated sound, PCI SSID: 1af4:1100 */ - msg = "enable KVM"; - } else if (pci->subsystem_vendor == 0x1ab8) { - /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */ - msg = "enable Parallels VM"; - } else { - msg = "disable (unknown or VT-d) VM"; - result = 0; - } - -fini: - if (msg != NULL) - printk(KERN_INFO "intel8x0: %s optimization\n", msg); - - return result; -} - static int __devinit snd_intel8x0_create(struct snd_card *card, struct pci_dev *pci, unsigned long device_type, @@ -3043,7 +2997,9 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, if (xbox) chip->xbox = 1; - chip->inside_vm = snd_intel8x0_inside_vm(pci); + chip->inside_vm = inside_vm; + if (inside_vm) + printk(KERN_INFO "intel8x0: enable KVM optimization\n"); if (pci->vendor == PCI_VENDOR_ID_INTEL && pci->device == PCI_DEVICE_ID_INTEL_440MX) @@ -3287,6 +3243,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, buggy_irq = 0; } + if (inside_vm < 0) { + /* detect KVM and Parallels virtual environments */ + inside_vm = kvm_para_available(); +#if defined(__i386__) || defined(__x86_64__) + inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); +#endif + } + if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/lx6464es/lx_core.c b/trunk/sound/pci/lx6464es/lx_core.c index 8c3e7fcefd99..5c8717e29eeb 100644 --- a/trunk/sound/pci/lx6464es/lx_core.c +++ b/trunk/sound/pci/lx6464es/lx_core.c @@ -78,15 +78,10 @@ unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port) return ioread32(address); } -static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, - u32 len) +void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len) { - u32 __iomem *address = lx_dsp_register(chip, port); - int i; - - /* we cannot use memcpy_fromio */ - for (i = 0; i != len; ++i) - data[i] = ioread32(address + i); + void __iomem *address = lx_dsp_register(chip, port); + memcpy_fromio(data, address, len*sizeof(u32)); } @@ -96,15 +91,11 @@ void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data) iowrite32(data, address); } -static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, - const u32 *data, u32 len) +void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, + u32 len) { - u32 __iomem *address = lx_dsp_register(chip, port); - int i; - - /* we cannot use memcpy_to */ - for (i = 0; i != len; ++i) - iowrite32(data[i], address + i); + void __iomem *address = lx_dsp_register(chip, port); + memcpy_toio(address, data, len*sizeof(u32)); } diff --git a/trunk/sound/pci/lx6464es/lx_core.h b/trunk/sound/pci/lx6464es/lx_core.h index 4d7ff797a646..1dd562980b6c 100644 --- a/trunk/sound/pci/lx6464es/lx_core.h +++ b/trunk/sound/pci/lx6464es/lx_core.h @@ -72,7 +72,10 @@ enum { }; unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port); +void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len); void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data); +void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, + u32 len); /* plx register access */ enum { diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 19ee2203cbb5..e760adad9523 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -6518,7 +6518,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, hdspm->io_type = AES32; hdspm->card_name = "RME AES32"; hdspm->midiPorts = 2; - } else if ((hdspm->firmware_rev == 0xd2) || + } else if ((hdspm->firmware_rev == 0xd5) || ((hdspm->firmware_rev >= 0xc8) && (hdspm->firmware_rev <= 0xcf))) { hdspm->io_type = MADI; diff --git a/trunk/sound/pci/sis7019.c b/trunk/sound/pci/sis7019.c index 28dfafb56dd1..a391e622a192 100644 --- a/trunk/sound/pci/sis7019.c +++ b/trunk/sound/pci/sis7019.c @@ -41,7 +41,6 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int enable = 1; -static int codecs = 1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); @@ -49,8 +48,6 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); module_param(enable, bool, 0444); MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); -module_param(codecs, int, 0444); -MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, @@ -143,9 +140,6 @@ struct sis7019 { dma_addr_t silence_dma_addr; }; -/* These values are also used by the module param 'codecs' to indicate - * which codecs should be present. - */ #define SIS_PRIMARY_CODEC_PRESENT 0x0001 #define SIS_SECONDARY_CODEC_PRESENT 0x0002 #define SIS_TERTIARY_CODEC_PRESENT 0x0004 @@ -1084,7 +1078,6 @@ static int sis_chip_init(struct sis7019 *sis) { unsigned long io = sis->ioport; void __iomem *ioaddr = sis->ioaddr; - unsigned long timeout; u16 status; int count; int i; @@ -1111,45 +1104,21 @@ static int sis_chip_init(struct sis7019 *sis) while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) udelay(1); - /* Command complete, we can let go of the semaphore now. - */ - outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); - if (!count) - return -EIO; - /* Now that we've finished the reset, find out what's attached. - * There are some codec/board combinations that take an extremely - * long time to come up. 350+ ms has been observed in the field, - * so we'll give them up to 500ms. */ - sis->codecs_present = 0; - timeout = msecs_to_jiffies(500) + jiffies; - while (time_before_eq(jiffies, timeout)) { - status = inl(io + SIS_AC97_STATUS); - if (status & SIS_AC97_STATUS_CODEC_READY) - sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC2_READY) - sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC3_READY) - sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; - - if (sis->codecs_present == codecs) - break; - - msleep(1); - } - - /* All done, check for errors. + status = inl(io + SIS_AC97_STATUS); + if (status & SIS_AC97_STATUS_CODEC_READY) + sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC2_READY) + sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC3_READY) + sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; + + /* All done, let go of the semaphore, and check for errors */ - if (!sis->codecs_present) { - printk(KERN_ERR "sis7019: could not find any codecs\n"); + outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); + if (!sis->codecs_present || !count) return -EIO; - } - - if (sis->codecs_present != codecs) { - printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n", - sis->codecs_present, codecs); - } /* Let the hardware know that the audio driver is alive, * and enable PCM slots on the AC-link for L/R playback (3 & 4) and @@ -1421,17 +1390,6 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, if (!enable) goto error_out; - /* The user can specify which codecs should be present so that we - * can wait for them to show up if they are slow to recover from - * the AC97 cold reset. We default to a single codec, the primary. - * - * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. - */ - codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | - SIS_TERTIARY_CODEC_PRESENT; - if (!codecs) - codecs = SIS_PRIMARY_CODEC_PRESENT; - rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); if (rc < 0) goto error_out; diff --git a/trunk/sound/soc/codecs/jz4740.c b/trunk/sound/soc/codecs/jz4740.c index e373f8f06907..3e1f4e172bfb 100644 --- a/trunk/sound/soc/codecs/jz4740.c +++ b/trunk/sound/soc/codecs/jz4740.c @@ -15,6 +15,7 @@ #include #include #include +#include #include diff --git a/trunk/sound/usb/mixer.c b/trunk/sound/usb/mixer.c index ab23869c01bb..60f65ace7474 100644 --- a/trunk/sound/usb/mixer.c +++ b/trunk/sound/usb/mixer.c @@ -765,61 +765,10 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) * interface to ALSA control for feature/mixer units */ -/* volume control quirks */ -static void volume_control_quirks(struct usb_mixer_elem_info *cval, - struct snd_kcontrol *kctl) -{ - switch (cval->mixer->chip->usb_id) { - case USB_ID(0x0471, 0x0101): - case USB_ID(0x0471, 0x0104): - case USB_ID(0x0471, 0x0105): - case USB_ID(0x0672, 0x1041): - /* quirk for UDA1321/N101. - * note that detection between firmware 2.1.1.7 (N101) - * and later 2.1.1.21 is not very clear from datasheets. - * I hope that the min value is -15360 for newer firmware --jk - */ - if (!strcmp(kctl->id.name, "PCM Playback Volume") && - cval->min == -15616) { - snd_printk(KERN_INFO - "set volume quirk for UDA1321/N101 chip\n"); - cval->max = -256; - } - break; - - case USB_ID(0x046d, 0x09a4): - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { - snd_printk(KERN_INFO - "set volume quirk for QuickCam E3500\n"); - cval->min = 6080; - cval->max = 8768; - cval->res = 192; - } - break; - - case USB_ID(0x046d, 0x0808): - case USB_ID(0x046d, 0x0809): - case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ - case USB_ID(0x046d, 0x0991): - /* Most audio usb devices lie about volume resolution. - * Most Logitech webcams have res = 384. - * Proboly there is some logitech magic behind this number --fishor - */ - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { - snd_printk(KERN_INFO - "set resolution quirk: cval->res = 384\n"); - cval->res = 384; - } - break; - - } -} - /* * retrieve the minimum and maximum values for the specified control */ -static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, - int default_min, struct snd_kcontrol *kctl) +static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) { /* for failsafe */ cval->min = default_min; @@ -895,9 +844,6 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, cval->initialized = 1; } - if (kctl) - volume_control_quirks(cval, kctl); - /* USB descriptions contain the dB scale in 1/256 dB unit * while ALSA TLV contains in 1/100 dB unit */ @@ -918,7 +864,6 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, return 0; } -#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) /* get a feature/mixer unit info */ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -937,7 +882,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ uinfo->value.integer.max = 1; } else { if (!cval->initialized) { - get_min_max_with_quirks(cval, 0, kcontrol); + get_min_max(cval, 0); if (cval->initialized && cval->dBmin >= cval->dBmax) { kcontrol->vd[0].access &= ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | @@ -1100,6 +1045,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, cval->ch_readonly = readonly_mask; } + /* get min/max values */ + get_min_max(cval, 0); + /* if all channels in the mask are marked read-only, make the control * read-only. set_cur_mix_value() will check the mask again and won't * issue write commands to read-only channels. */ @@ -1121,9 +1069,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); - /* get min/max values */ - get_min_max_with_quirks(cval, 0, kctl); - switch (control) { case UAC_FU_MUTE: case UAC_FU_VOLUME: @@ -1173,6 +1118,51 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, break; } + /* volume control quirks */ + switch (state->chip->usb_id) { + case USB_ID(0x0471, 0x0101): + case USB_ID(0x0471, 0x0104): + case USB_ID(0x0471, 0x0105): + case USB_ID(0x0672, 0x1041): + /* quirk for UDA1321/N101. + * note that detection between firmware 2.1.1.7 (N101) + * and later 2.1.1.21 is not very clear from datasheets. + * I hope that the min value is -15360 for newer firmware --jk + */ + if (!strcmp(kctl->id.name, "PCM Playback Volume") && + cval->min == -15616) { + snd_printk(KERN_INFO + "set volume quirk for UDA1321/N101 chip\n"); + cval->max = -256; + } + break; + + case USB_ID(0x046d, 0x09a4): + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + snd_printk(KERN_INFO + "set volume quirk for QuickCam E3500\n"); + cval->min = 6080; + cval->max = 8768; + cval->res = 192; + } + break; + + case USB_ID(0x046d, 0x0808): + case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x0991): + /* Most audio usb devices lie about volume resolution. + * Most Logitech webcams have res = 384. + * Proboly there is some logitech magic behind this number --fishor + */ + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + snd_printk(KERN_INFO + "set resolution quirk: cval->res = 384\n"); + cval->res = 384; + } + break; + + } + range = (cval->max - cval->min) / cval->res; /* Are there devices with volume range more than 255? I use a bit more * to be sure. 384 is a resolution magic number found on Logitech diff --git a/trunk/sound/usb/quirks-table.h b/trunk/sound/usb/quirks-table.h index 32d2a21f2e3b..b61945f3af9e 100644 --- a/trunk/sound/usb/quirks-table.h +++ b/trunk/sound/usb/quirks-table.h @@ -1632,37 +1632,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, -{ - /* Roland GAIA SH-01 */ - USB_DEVICE(0x0582, 0x0111), - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "GAIA", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const struct snd_usb_audio_quirk[]) { - { - .ifnum = 0, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = &(const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0003, - .in_cables = 0x0003 - } - }, - { - .ifnum = -1 - } - } - } -}, { USB_DEVICE(0x0582, 0x0113), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { diff --git a/trunk/sound/usb/quirks.c b/trunk/sound/usb/quirks.c index a3ddac0deffd..2e5bc7344026 100644 --- a/trunk/sound/usb/quirks.c +++ b/trunk/sound/usb/quirks.c @@ -137,12 +137,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, return -ENOMEM; } if (fp->nr_rates > 0) { - rate_table = kmemdup(fp->rate_table, - sizeof(int) * fp->nr_rates, GFP_KERNEL); + rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); if (!rate_table) { kfree(fp); return -ENOMEM; } + memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates); fp->rate_table = rate_table; } @@ -224,9 +224,10 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, if (altsd->bNumEndpoints != 1) return -ENXIO; - fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL); + fp = kmalloc(sizeof(*fp), GFP_KERNEL); if (!fp) return -ENOMEM; + memcpy(fp, &ua_format, sizeof(*fp)); fp->iface = altsd->bInterfaceNumber; fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;