aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-09 11:24:04 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-09 11:24:04 -0500
commit6026179519896e7d35b2564e7544487d1c8948e7 (patch)
treec78c7032abce24d846423572204f1cd4e97d8efc /sound/pci/hda/hda_codec.c
parentd27146dd5b72ab7d7e641f56f4bee1484dabd0b7 (diff)
parentc2902c8ae06762d941fab64198467f78cab6f8cd (diff)
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (212 commits) [PATCH] Fix breakage with CONFIG_SYSFS_DEPRECATED [ALSA] version 1.0.14rc2 [ALSA] ASoC documentation updates [ALSA] ca0106 - Add missing sysfs device assignment [ALSA] aoa i2sbus: Stop Apple i2s DMA gracefully [ALSA] hda-codec - Add support for Fujitsu PI1556 Realtek ALC880 [ALSA] aoa: remove suspend/resume printks [ALSA] Fix possible deadlocks in sequencer at removal of ports [ALSA] emu10k1 - Fix STAC9758 front channel [ALSA] soc - Clean up with kmemdup() [ALSA] snd-ak4114: Fix two array overflows [ALSA] ac97_bus power management [ALSA] usbaudio - Add support for Edirol UA-101 [ALSA] hda-codec - Add ALC861VD/ALC660VD support [ALSA] soc - ASoC 0.13 Sharp poodle machine [ALSA] soc - ASoC 0.13 Sharp tosa machine [ALSA] soc - ASoC 0.13 spitz machine [ALSA] soc - ASoC Sharp corgi machine [ALSA] soc - ASoC 0.13 pxa2xx DMA [ALSA] soc - ASoC 0.13 pxa2xx AC97 driver ...
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 18bbc87e376f..8f34fb447983 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -52,6 +52,7 @@ struct hda_vendor_id {
52static struct hda_vendor_id hda_vendor_ids[] = { 52static struct hda_vendor_id hda_vendor_ids[] = {
53 { 0x10ec, "Realtek" }, 53 { 0x10ec, "Realtek" },
54 { 0x1057, "Motorola" }, 54 { 0x1057, "Motorola" },
55 { 0x1106, "VIA" },
55 { 0x11d4, "Analog Devices" }, 56 { 0x11d4, "Analog Devices" },
56 { 0x13f6, "C-Media" }, 57 { 0x13f6, "C-Media" },
57 { 0x14f1, "Conexant" }, 58 { 0x14f1, "Conexant" },
@@ -262,7 +263,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
262 unsol->queue[wp] = res; 263 unsol->queue[wp] = res;
263 unsol->queue[wp + 1] = res_ex; 264 unsol->queue[wp + 1] = res_ex;
264 265
265 queue_work(unsol->workq, &unsol->work); 266 schedule_work(&unsol->work);
266 267
267 return 0; 268 return 0;
268} 269}
@@ -309,12 +310,6 @@ static int init_unsol_queue(struct hda_bus *bus)
309 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); 310 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
310 return -ENOMEM; 311 return -ENOMEM;
311 } 312 }
312 unsol->workq = create_singlethread_workqueue("hda_codec");
313 if (! unsol->workq) {
314 snd_printk(KERN_ERR "hda_codec: can't create workqueue\n");
315 kfree(unsol);
316 return -ENOMEM;
317 }
318 INIT_WORK(&unsol->work, process_unsol_events); 313 INIT_WORK(&unsol->work, process_unsol_events);
319 unsol->bus = bus; 314 unsol->bus = bus;
320 bus->unsol = unsol; 315 bus->unsol = unsol;
@@ -333,7 +328,7 @@ static int snd_hda_bus_free(struct hda_bus *bus)
333 if (! bus) 328 if (! bus)
334 return 0; 329 return 0;
335 if (bus->unsol) { 330 if (bus->unsol) {
336 destroy_workqueue(bus->unsol->workq); 331 flush_scheduled_work();
337 kfree(bus->unsol); 332 kfree(bus->unsol);
338 } 333 }
339 list_for_each_safe(p, n, &bus->codec_list) { 334 list_for_each_safe(p, n, &bus->codec_list) {
@@ -1714,6 +1709,8 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
1714/** 1709/**
1715 * snd_hda_check_board_config - compare the current codec with the config table 1710 * snd_hda_check_board_config - compare the current codec with the config table
1716 * @codec: the HDA codec 1711 * @codec: the HDA codec
1712 * @num_configs: number of config enums
1713 * @models: array of model name strings
1717 * @tbl: configuration table, terminated by null entries 1714 * @tbl: configuration table, terminated by null entries
1718 * 1715 *
1719 * Compares the modelname or PCI subsystem id of the current codec with the 1716 * Compares the modelname or PCI subsystem id of the current codec with the
@@ -1722,33 +1719,44 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
1722 * 1719 *
1723 * If no entries are matching, the function returns a negative value. 1720 * If no entries are matching, the function returns a negative value.
1724 */ 1721 */
1725int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl) 1722int snd_hda_check_board_config(struct hda_codec *codec,
1726{ 1723 int num_configs, const char **models,
1727 const struct hda_board_config *c; 1724 const struct snd_pci_quirk *tbl)
1728 1725{
1729 if (codec->bus->modelname) { 1726 if (codec->bus->modelname && models) {
1730 for (c = tbl; c->modelname || c->pci_subvendor; c++) { 1727 int i;
1731 if (c->modelname && 1728 for (i = 0; i < num_configs; i++) {
1732 ! strcmp(codec->bus->modelname, c->modelname)) { 1729 if (models[i] &&
1733 snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname); 1730 !strcmp(codec->bus->modelname, models[i])) {
1734 return c->config; 1731 snd_printd(KERN_INFO "hda_codec: model '%s' is "
1732 "selected\n", models[i]);
1733 return i;
1735 } 1734 }
1736 } 1735 }
1737 } 1736 }
1738 1737
1739 if (codec->bus->pci) { 1738 if (!codec->bus->pci || !tbl)
1740 u16 subsystem_vendor, subsystem_device; 1739 return -1;
1741 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); 1740
1742 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device); 1741 tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl);
1743 for (c = tbl; c->modelname || c->pci_subvendor; c++) { 1742 if (!tbl)
1744 if (c->pci_subvendor == subsystem_vendor && 1743 return -1;
1745 (! c->pci_subdevice /* all match */|| 1744 if (tbl->value >= 0 && tbl->value < num_configs) {
1746 (c->pci_subdevice == subsystem_device))) { 1745#ifdef CONFIG_SND_DEBUG_DETECT
1747 snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n", 1746 char tmp[10];
1748 subsystem_vendor, subsystem_device, c->config); 1747 const char *model = NULL;
1749 return c->config; 1748 if (models)
1750 } 1749 model = models[tbl->value];
1750 if (!model) {
1751 sprintf(tmp, "#%d", tbl->value);
1752 model = tmp;
1751 } 1753 }
1754 snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
1755 "for config %x:%x (%s)\n",
1756 model, tbl->subvendor, tbl->subdevice,
1757 (tbl->name ? tbl->name : "Unknown device"));
1758#endif
1759 return tbl->value;
1752 } 1760 }
1753 return -1; 1761 return -1;
1754} 1762}