]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/pci/hda/hda_codec.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[linux-2.6-omap-h63xx.git] / sound / pci / hda / hda_codec.c
index 18bbc87e376f167c5beb9c823ab2ffb3cb0d4f0a..8f34fb4479837087b177c6f0c15d6eeb29caf300 100644 (file)
@@ -52,6 +52,7 @@ struct hda_vendor_id {
 static struct hda_vendor_id hda_vendor_ids[] = {
        { 0x10ec, "Realtek" },
        { 0x1057, "Motorola" },
+       { 0x1106, "VIA" },
        { 0x11d4, "Analog Devices" },
        { 0x13f6, "C-Media" },
        { 0x14f1, "Conexant" },
@@ -262,7 +263,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;
 
-       queue_work(unsol->workq, &unsol->work);
+       schedule_work(&unsol->work);
 
        return 0;
 }
@@ -309,12 +310,6 @@ static int init_unsol_queue(struct hda_bus *bus)
                snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
                return -ENOMEM;
        }
-       unsol->workq = create_singlethread_workqueue("hda_codec");
-       if (! unsol->workq) {
-               snd_printk(KERN_ERR "hda_codec: can't create workqueue\n");
-               kfree(unsol);
-               return -ENOMEM;
-       }
        INIT_WORK(&unsol->work, process_unsol_events);
        unsol->bus = bus;
        bus->unsol = unsol;
@@ -333,7 +328,7 @@ static int snd_hda_bus_free(struct hda_bus *bus)
        if (! bus)
                return 0;
        if (bus->unsol) {
-               destroy_workqueue(bus->unsol->workq);
+               flush_scheduled_work();
                kfree(bus->unsol);
        }
        list_for_each_safe(p, n, &bus->codec_list) {
@@ -1714,6 +1709,8 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
 /**
  * snd_hda_check_board_config - compare the current codec with the config table
  * @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
@@ -1722,33 +1719,44 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
  *
  * If no entries are matching, the function returns a negative value.
  */
-int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl)
-{
-       const struct hda_board_config *c;
-
-       if (codec->bus->modelname) {
-               for (c = tbl; c->modelname || c->pci_subvendor; c++) {
-                       if (c->modelname &&
-                           ! strcmp(codec->bus->modelname, c->modelname)) {
-                               snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname);
-                               return c->config;
+int snd_hda_check_board_config(struct hda_codec *codec,
+                              int num_configs, const char **models,
+                              const struct snd_pci_quirk *tbl)
+{
+       if (codec->bus->modelname && models) {
+               int i;
+               for (i = 0; i < num_configs; i++) {
+                       if (models[i] &&
+                           !strcmp(codec->bus->modelname, models[i])) {
+                               snd_printd(KERN_INFO "hda_codec: model '%s' is "
+                                          "selected\n", models[i]);
+                               return i;
                        }
                }
        }
 
-       if (codec->bus->pci) {
-               u16 subsystem_vendor, subsystem_device;
-               pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
-               pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device);
-               for (c = tbl; c->modelname || c->pci_subvendor; c++) {
-                       if (c->pci_subvendor == subsystem_vendor &&
-                           (! c->pci_subdevice /* all match */||
-                            (c->pci_subdevice == subsystem_device))) {
-                               snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n",
-                                           subsystem_vendor, subsystem_device, c->config);
-                               return c->config;
-                       }
+       if (!codec->bus->pci || !tbl)
+               return -1;
+
+       tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl);
+       if (!tbl)
+               return -1;
+       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;
 }