patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / sound / pci / ac97 / ac97_proc.c
index 2080463..40b3e9f 100644 (file)
  * proc interface
  */
 
+static void snd_ac97_proc_read_functions(ac97_t *ac97, snd_info_buffer_t *buffer)
+{
+       int header = 0, function;
+       unsigned short info, sense_info;
+       static const char *function_names[12] = {
+               "Master Out", "AUX Out", "Center/LFE Out", "SPDIF Out",
+               "Phone In", "Mic 1", "Mic 2", "Line In", "CD In", "Video In",
+               "Aux In", "Mono Out"
+       };
+       static const char *locations[8] = {
+               "Rear I/O Panel", "Front Panel", "Motherboard", "Dock/External",
+               "reserved", "reserved", "reserved", "NC/unused"
+       };
+
+       for (function = 0; function < 12; ++function) {
+               snd_ac97_write(ac97, AC97_FUNC_SELECT, function << 1);
+               info = snd_ac97_read(ac97, AC97_FUNC_INFO);
+               if (!(info & 0x0001))
+                       continue;
+               if (!header) {
+                       snd_iprintf(buffer, "\n                    Gain     Inverted  Buffer delay  Location\n");
+                       header = 1;
+               }
+               sense_info = snd_ac97_read(ac97, AC97_SENSE_INFO);
+               snd_iprintf(buffer, "%-17s: %3d.%d dBV    %c      %2d/fs         %s\n",
+                           function_names[function],
+                           (info & 0x8000 ? -1 : 1) * ((info & 0x7000) >> 12) * 3 / 2,
+                           ((info & 0x0800) >> 11) * 5,
+                           info & 0x0400 ? 'X' : '-',
+                           (info & 0x03e0) >> 5,
+                           locations[sense_info >> 13]);
+       }
+}
+
 static void snd_ac97_proc_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx)
 {
        char name[64];
@@ -47,6 +81,21 @@ static void snd_ac97_proc_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, in
        if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
                goto __modem;
 
+       if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
+               val = snd_ac97_read(ac97, AC97_INT_PAGING);
+               snd_ac97_update_bits(ac97, AC97_INT_PAGING,
+                                    AC97_PAGE_MASK, AC97_PAGE_1);
+               tmp = snd_ac97_read(ac97, AC97_CODEC_CLASS_REV);
+               snd_iprintf(buffer, "Revision         : 0x%02x\n", tmp & 0xff);
+               snd_iprintf(buffer, "Compat. Class    : 0x%02x\n", (tmp >> 8) & 0x1f);
+               snd_iprintf(buffer, "Subsys. Vendor ID: 0x%04x\n",
+                           snd_ac97_read(ac97, AC97_PCI_SVID));
+               snd_iprintf(buffer, "Subsys. ID       : 0x%04x\n\n",
+                           snd_ac97_read(ac97, AC97_PCI_SID));
+               snd_ac97_update_bits(ac97, AC97_INT_PAGING,
+                                    AC97_PAGE_MASK, val & AC97_PAGE_MASK);
+       }
+
        // val = snd_ac97_read(ac97, AC97_RESET);
        val = ac97->caps;
        snd_iprintf(buffer, "Capabilities     :%s%s%s%s%s%s\n",
@@ -185,6 +234,14 @@ static void snd_ac97_proc_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, in
                        }
                }
        }
+       if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
+               val = snd_ac97_read(ac97, AC97_INT_PAGING);
+               snd_ac97_update_bits(ac97, AC97_INT_PAGING,
+                                    AC97_PAGE_MASK, AC97_PAGE_1);
+               snd_ac97_proc_read_functions(ac97, buffer);
+               snd_ac97_update_bits(ac97, AC97_INT_PAGING,
+                                    AC97_PAGE_MASK, val & AC97_PAGE_MASK);
+       }
 
 
       __modem:
@@ -264,6 +321,23 @@ static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buff
        }
 }
 
+#ifdef CONFIG_SND_DEBUG
+/* direct register write for debugging */
+static void snd_ac97_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+{
+       ac97_t *ac97 = snd_magic_cast(ac97_t, entry->private_data, return);
+       char line[64];
+       unsigned int reg, val;
+       while (!snd_info_get_line(buffer, line, sizeof(line))) {
+               if (sscanf(line, "%x %x", &reg, &val) != 2)
+                       continue;
+               /* register must be odd */
+               if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
+                       snd_ac97_write_cache(ac97, reg, val);
+       }
+}
+#endif
+
 static void snd_ac97_proc_regs_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx)
 {
        int reg, val;
@@ -319,6 +393,11 @@ void snd_ac97_proc_init(ac97_t * ac97)
        sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num);
        if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) {
                snd_info_set_text_ops(entry, ac97, 1024, snd_ac97_proc_regs_read);
+#ifdef CONFIG_SND_DEBUG
+               entry->mode |= S_IWUSR;
+               entry->c.text.write_size = 1024;
+               entry->c.text.write = snd_ac97_proc_regs_write;
+#endif
                if (snd_info_register(entry) < 0) {
                        snd_info_free_entry(entry);
                        entry = NULL;