diff options
Diffstat (limited to 'sound')
32 files changed, 370 insertions, 354 deletions
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 195cafc5a55..a70ee7f1ed9 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -99,9 +99,6 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) if (hw == NULL) return -ENODEV; - if (!hw->ops.open) - return -ENXIO; - if (!try_module_get(hw->card->module)) return -EFAULT; @@ -113,6 +110,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) err = -EBUSY; break; } + if (!hw->ops.open) { + err = 0; + break; + } err = hw->ops.open(hw, file); if (err >= 0) break; @@ -151,7 +152,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) static int snd_hwdep_release(struct inode *inode, struct file * file) { - int err = -ENXIO; + int err = 0; struct snd_hwdep *hw = file->private_data; struct module *mod = hw->card->module; diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index 8d6362e2d4c..46df8817c18 100644 --- a/sound/drivers/vx/vx_hwdep.c +++ b/sound/drivers/vx/vx_hwdep.c @@ -119,16 +119,6 @@ void snd_vx_free_firmware(struct vx_core *chip) #else /* old style firmware loading */ -static int vx_hwdep_open(struct snd_hwdep *hw, struct file *file) -{ - return 0; -} - -static int vx_hwdep_release(struct snd_hwdep *hw, struct file *file) -{ - return 0; -} - static int vx_hwdep_dsp_status(struct snd_hwdep *hw, struct snd_hwdep_dsp_status *info) { @@ -243,8 +233,6 @@ int snd_vx_setup_firmware(struct vx_core *chip) hw->iface = SNDRV_HWDEP_IFACE_VX; hw->private_data = chip; - hw->ops.open = vx_hwdep_open; - hw->ops.release = vx_hwdep_release; hw->ops.dsp_status = vx_hwdep_dsp_status; hw->ops.dsp_load = vx_hwdep_dsp_load; hw->exclusive = 1; diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 4d45bd63718..57d9f154c88 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c @@ -851,8 +851,9 @@ static int __init AtaIrqInit(void) mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ mfp.tim_ct_a = 8; /* Turn on event counting. */ /* Register interrupt handler. */ - request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound", - AtaInterrupt); + if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound", + AtaInterrupt)) + return 0; mfp.int_en_a |= 0x20; /* Turn interrupt on. */ mfp.int_mk_a |= 0x20; return 1; diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c index 1855b14d90c..99bcb21c228 100644 --- a/sound/oss/dmasound/dmasound_q40.c +++ b/sound/oss/dmasound/dmasound_q40.c @@ -371,8 +371,9 @@ static void Q40Free(void *ptr, unsigned int size) static int __init Q40IrqInit(void) { /* Register interrupt handler. */ - request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, - "DMA sound", Q40Interrupt); + if (request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, + "DMA sound", Q40Interrupt)) + return 0; return(1); } @@ -401,6 +402,7 @@ static void Q40PlayNextFrame(int index) u_char *start; u_long size; u_char speed; + int error; /* used by Q40Play() if all doubts whether there really is something * to be played are already wiped out. @@ -419,11 +421,13 @@ static void Q40PlayNextFrame(int index) master_outb( 0,SAMPLE_ENABLE_REG); free_irq(Q40_IRQ_SAMPLE, Q40Interrupt); if (dmasound.soft.stereo) - request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, - "Q40 sound", Q40Interrupt); + error = request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, + "Q40 sound", Q40Interrupt); else - request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0, - "Q40 sound", Q40Interrupt); + error = request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0, + "Q40 sound", Q40Interrupt); + if (error && printk_ratelimit()) + pr_err("Couldn't register sound interrupt\n"); master_outb( speed, SAMPLE_RATE_REG); master_outb( 1,SAMPLE_CLEAR_REG); diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 6e3a1848447..82b9bddcdcd 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -744,8 +744,8 @@ config SND_VIRTUOSO select SND_OXYGEN_LIB help Say Y here to include support for sound cards based on the - Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X and - HDAV1.3 (Deluxe). + Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X. + Support for the HDAV1.3 (Deluxe) is very experimental. To compile this driver as a module, choose M here: the module will be called snd-virtuoso. diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index e00421c0d8b..960fd797038 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -135,7 +135,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) struct hda_beep *beep = codec->beep; if (beep) { cancel_work_sync(&beep->beep_work); - flush_scheduled_work(); input_unregister_device(beep->dev); kfree(beep); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e16cf63821a..b7bba7dc7cf 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -373,7 +373,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) unsol->queue[wp] = res; unsol->queue[wp + 1] = res_ex; - schedule_work(&unsol->work); + queue_work(bus->workq, &unsol->work); return 0; } @@ -437,15 +437,17 @@ static int snd_hda_bus_free(struct hda_bus *bus) if (!bus) return 0; - if (bus->unsol) { - flush_scheduled_work(); + if (bus->workq) + flush_workqueue(bus->workq); + if (bus->unsol) kfree(bus->unsol); - } list_for_each_entry_safe(codec, n, &bus->codec_list, list) { snd_hda_codec_free(codec); } if (bus->ops.private_free) bus->ops.private_free(bus); + if (bus->workq) + destroy_workqueue(bus->workq); kfree(bus); return 0; } @@ -485,6 +487,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, { struct hda_bus *bus; int err; + char qname[8]; static struct snd_device_ops dev_ops = { .dev_register = snd_hda_bus_dev_register, .dev_free = snd_hda_bus_dev_free, @@ -514,6 +517,14 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, mutex_init(&bus->cmd_mutex); INIT_LIST_HEAD(&bus->codec_list); + snprintf(qname, sizeof(qname), "hda%d", card->number); + bus->workq = create_workqueue(qname); + if (!bus->workq) { + snd_printk(KERN_ERR "cannot create workqueue %s\n", qname); + kfree(bus); + return -ENOMEM; + } + err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); if (err < 0) { snd_hda_bus_free(bus); @@ -684,7 +695,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) return; #ifdef CONFIG_SND_HDA_POWER_SAVE cancel_delayed_work(&codec->power_work); - flush_scheduled_work(); + flush_workqueue(codec->bus->workq); #endif list_del(&codec->list); snd_array_free(&codec->mixers); @@ -735,6 +746,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr codec->bus = bus; codec->addr = codec_addr; mutex_init(&codec->spdif_mutex); + mutex_init(&codec->control_mutex); init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32); @@ -1272,7 +1284,7 @@ void snd_hda_codec_reset(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE cancel_delayed_work(&codec->power_work); - flush_scheduled_work(); + flush_workqueue(codec->bus->workq); #endif snd_hda_ctls_clear(codec); /* relase PCMs */ @@ -1418,12 +1430,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, unsigned long pval; int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); pval = kcontrol->private_value; kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); kcontrol->private_value = pval; - mutex_unlock(&codec->spdif_mutex); + mutex_unlock(&codec->control_mutex); return err; } EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get); @@ -1435,7 +1447,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, unsigned long pval; int i, indices, err = 0, change = 0; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); pval = kcontrol->private_value; indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; for (i = 0; i < indices; i++) { @@ -1447,7 +1459,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, change |= err; } kcontrol->private_value = pval; - mutex_unlock(&codec->spdif_mutex); + mutex_unlock(&codec->control_mutex); return err < 0 ? err : change; } EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put); @@ -1462,12 +1474,12 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, struct hda_bind_ctls *c; int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); c = (struct hda_bind_ctls *)kcontrol->private_value; kcontrol->private_value = *c->values; err = c->ops->info(kcontrol, uinfo); kcontrol->private_value = (long)c; - mutex_unlock(&codec->spdif_mutex); + mutex_unlock(&codec->control_mutex); return err; } EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info); @@ -1479,12 +1491,12 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, struct hda_bind_ctls *c; int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); c = (struct hda_bind_ctls *)kcontrol->private_value; kcontrol->private_value = *c->values; err = c->ops->get(kcontrol, ucontrol); kcontrol->private_value = (long)c; - mutex_unlock(&codec->spdif_mutex); + mutex_unlock(&codec->control_mutex); return err; } EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get); @@ -1497,7 +1509,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, unsigned long *vals; int err = 0, change = 0; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); c = (struct hda_bind_ctls *)kcontrol->private_value; for (vals = c->values; *vals; vals++) { kcontrol->private_value = *vals; @@ -1507,7 +1519,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, change |= err; } kcontrol->private_value = (long)c; - mutex_unlock(&codec->spdif_mutex); + mutex_unlock(&codec->control_mutex); return err < 0 ? err : change; } EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put); @@ -1519,12 +1531,12 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, struct hda_bind_ctls *c; int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); c = (struct hda_bind_ctls *)kcontrol->private_value; kcontrol->private_value = *c->values; err = c->ops->tlv(kcontrol, op_flag, size, tlv); kcontrol->private_value = (long)c; - mutex_unlock(&codec->spdif_mutex); + mutex_unlock(&codec->control_mutex); return err; } EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv); @@ -2712,6 +2724,67 @@ int snd_hda_check_board_config(struct hda_codec *codec, EXPORT_SYMBOL_HDA(snd_hda_check_board_config); /** + * snd_hda_check_board_codec_sid_config - compare the current codec + subsystem ID with the + config table + + This is important for Gateway notebooks with SB450 HDA Audio + where the vendor ID of the PCI device is: + ATI Technologies Inc SB450 HDA Audio [1002:437b] + and the vendor/subvendor are found only at the codec. + + * @codec: the HDA codec + * @num_configs: number of config enums + * @models: array of model name strings + * @tbl: configuration table, terminated by null entries + * + * Compares the modelname or PCI subsystem id of the current codec with the + * given configuration table. If a matching entry is found, returns its + * config value (supposed to be 0 or positive). + * + * If no entries are matching, the function returns a negative value. + */ +int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl) +{ + const struct snd_pci_quirk *q; + + /* Search for codec ID */ + for (q = tbl; q->subvendor; q++) { + unsigned long vendorid = (q->subdevice) | (q->subvendor << 16); + + if (vendorid == codec->subsystem_id) + break; + } + + if (!q->subvendor) + return -1; + + tbl = q; + + if (tbl->value >= 0 && tbl->value < num_configs) { +#ifdef CONFIG_SND_DEBUG_DETECT + char tmp[10]; + const char *model = NULL; + if (models) + model = models[tbl->value]; + if (!model) { + sprintf(tmp, "#%d", tbl->value); + model = tmp; + } + snd_printdd(KERN_INFO "hda_codec: model '%s' is selected " + "for config %x:%x (%s)\n", + model, tbl->subvendor, tbl->subdevice, + (tbl->name ? tbl->name : "Unknown device")); +#endif + return tbl->value; + } + return -1; +} +EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config); + +/** * snd_hda_add_new_ctls - create controls from the array * @codec: the HDA codec * @knew: the array of struct snd_kcontrol_new @@ -2803,7 +2876,7 @@ void snd_hda_power_down(struct hda_codec *codec) return; if (power_save(codec)) { codec->power_transition = 1; /* avoid reentrance */ - schedule_delayed_work(&codec->power_work, + queue_delayed_work(codec->bus->workq, &codec->power_work, msecs_to_jiffies(power_save(codec) * 1000)); } } diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 729fc7642d7..5810ef58840 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -614,6 +614,7 @@ struct hda_bus { /* unsolicited event queue */ struct hda_bus_unsolicited *unsol; + struct workqueue_struct *workq; /* common workqueue for codecs */ /* assigned PCMs */ DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); @@ -771,6 +772,7 @@ struct hda_codec { struct hda_cache_rec cmd_cache; /* cache for other commands */ struct mutex spdif_mutex; + struct mutex control_mutex; unsigned int spdif_status; /* IEC958 status bits */ unsigned short spdif_ctls; /* SPDIF control bits */ unsigned int spdif_in_enable; /* SPDIF input enable? */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ad5df2ae6f7..f9603443f08 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -996,10 +996,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(azx_dev->substream); spin_lock(&chip->reg_lock); - } else { + } else if (chip->bus && chip->bus->workq) { /* bogus IRQ, process it later */ azx_dev->irq_pending = 1; - schedule_work(&chip->irq_pending_work); + queue_work(chip->bus->workq, + &chip->irq_pending_work); } } } @@ -1741,7 +1742,6 @@ static void azx_clear_irq_pending(struct azx *chip) for (i = 0; i < chip->num_streams; i++) chip->azx_dev[i].irq_pending = 0; spin_unlock_irq(&chip->reg_lock); - flush_scheduled_work(); } static struct snd_pcm_ops azx_pcm_ops = { diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 6f2fe0f9fdd..1dd8716c387 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -296,6 +296,9 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen); int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, const char **modelnames, const struct snd_pci_quirk *pci_list); +int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 26247cfe749..2e7371ec2e2 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -3900,6 +3900,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = { static struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP), @@ -4262,13 +4263,13 @@ static int patch_ad1882(struct hda_codec *codec) spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); spec->adc_nids = ad1882_adc_nids; spec->capsrc_nids = ad1882_capsrc_nids; - if (codec->vendor_id == 0x11d1882) + if (codec->vendor_id == 0x11d41882) spec->input_mux = &ad1882_capture_source; else spec->input_mux = &ad1882a_capture_source; spec->num_mixers = 2; spec->mixers[0] = ad1882_base_mixers; - if (codec->vendor_id == 0x11d1882) + if (codec->vendor_id == 0x11d41882) spec->mixers[1] = ad1882_loopback_mixers; else spec->mixers[1] = ad1882a_loopback_mixers; diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 0270fda0bda..d57d8132a06 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -160,14 +160,18 @@ static int patch_nvhdmi(struct hda_codec *codec) */ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, + { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi }, + { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi }, {} /* terminator */ }; MODULE_ALIAS("snd-hda-codec-id:10de0002"); +MODULE_ALIAS("snd-hda-codec-id:10de0006"); MODULE_ALIAS("snd-hda-codec-id:10de0007"); MODULE_ALIAS("snd-hda-codec-id:10de0067"); +MODULE_ALIAS("snd-hda-codec-id:10de8001"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9065ebf9c06..5d249a547fb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1502,11 +1502,11 @@ static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, struct alc_spec *spec = codec->spec; int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); - mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_unlock(&codec->control_mutex); return err; } @@ -1517,11 +1517,11 @@ static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, struct alc_spec *spec = codec->spec; int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT); err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); - mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_unlock(&codec->control_mutex); return err; } @@ -1537,11 +1537,11 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); int err; - mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_lock(&codec->control_mutex); kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 3, 0, HDA_INPUT); err = func(kcontrol, ucontrol); - mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ + mutex_unlock(&codec->control_mutex); return err; } @@ -8461,6 +8461,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", ALC888_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", + ALC888_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", + ALC888_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), @@ -8474,6 +8478,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), @@ -8522,6 +8527,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), + SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), + SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), {} }; @@ -10568,6 +10575,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA), + SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), @@ -11689,6 +11697,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", ALC268_ACER_ASPIRE_ONE), SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), + SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 35b83dc6e19..3dd4eee70b7 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -55,7 +55,8 @@ enum { STAC_9200_DELL_M25, STAC_9200_DELL_M26, STAC_9200_DELL_M27, - STAC_9200_GATEWAY, + STAC_9200_M4, + STAC_9200_M4_2, STAC_9200_PANASONIC, STAC_9200_MODELS }; @@ -80,6 +81,7 @@ enum { enum { STAC_92HD83XXX_REF, + STAC_92HD83XXX_PWR_REF, STAC_92HD83XXX_MODELS }; @@ -89,14 +91,19 @@ enum { STAC_DELL_M4_2, STAC_DELL_M4_3, STAC_HP_M4, + STAC_HP_DV5, STAC_92HD71BXX_MODELS }; enum { STAC_925x_REF, + STAC_M1, + STAC_M1_2, + STAC_M2, STAC_M2_2, - STAC_MA6, - STAC_PA6, + STAC_M3, + STAC_M5, + STAC_M6, STAC_925x_MODELS }; @@ -328,7 +335,11 @@ static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { }; static unsigned int stac92hd83xxx_pwr_mapping[4] = { - 0x03, 0x0c, 0x10, 0x40, + 0x03, 0x0c, 0x20, 0x40, +}; + +static hda_nid_t stac92hd83xxx_amp_nids[1] = { + 0xc, }; static hda_nid_t stac92hd71bxx_pwr_nids[3] = { @@ -831,10 +842,6 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { }; static struct hda_verb stac92hd83xxx_core_init[] = { - /* start of config #1 */ - { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3}, - - /* start of config #2 */ { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, @@ -875,6 +882,8 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = { static struct hda_verb stac925x_core_init[] = { /* set dac0mux for dac converter */ { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* mute the master volume */ + { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, {} }; @@ -1126,6 +1135,8 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { }; static struct snd_kcontrol_new stac925x_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), STAC_INPUT_SOURCE(1), HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), @@ -1334,7 +1345,16 @@ static unsigned int ref9200_pin_configs[8] = { 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; -/* +static unsigned int gateway9200_m4_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; +static unsigned int gateway9200_m4_2_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; + +/* STAC 9200 pin configs for 102801A8 102801DE @@ -1464,6 +1484,8 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, + [STAC_9200_M4] = gateway9200_m4_pin_configs, + [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs, [STAC_9200_PANASONIC] = ref9200_pin_configs, }; @@ -1480,7 +1502,8 @@ static const char *stac9200_models[STAC_9200_MODELS] = { [STAC_9200_DELL_M25] = "dell-m25", [STAC_9200_DELL_M26] = "dell-m26", [STAC_9200_DELL_M27] = "dell-m27", - [STAC_9200_GATEWAY] = "gateway", + [STAC_9200_M4] = "gateway-m4", + [STAC_9200_M4_2] = "gateway-m4-2", [STAC_9200_PANASONIC] = "panasonic", }; @@ -1550,11 +1573,9 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), /* Gateway machines needs EAPD to be set on resume */ - SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY), - SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", - STAC_9200_GATEWAY), - SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", - STAC_9200_GATEWAY), + SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4), + SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2), + SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2), /* OQO Mobile */ SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), {} /* terminator */ @@ -1565,44 +1586,85 @@ static unsigned int ref925x_pin_configs[8] = { 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, }; -static unsigned int stac925x_MA6_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, +static unsigned int stac925xM1_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -static unsigned int stac925x_PA6_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e, +static unsigned int stac925xM1_2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM2_pin_configs[8] = { + 0 |