0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/mutex.h>
0011
0012 #include <sound/core.h>
0013 #include <sound/ac97_codec.h>
0014 #include <sound/asoundef.h>
0015 #include "ac97_local.h"
0016 #include "ac97_id.h"
0017
0018
0019
0020
0021
0022 static void snd_ac97_proc_read_functions(struct snd_ac97 *ac97, struct snd_info_buffer *buffer)
0023 {
0024 int header = 0, function;
0025 unsigned short info, sense_info;
0026 static const char *function_names[12] = {
0027 "Master Out", "AUX Out", "Center/LFE Out", "SPDIF Out",
0028 "Phone In", "Mic 1", "Mic 2", "Line In", "CD In", "Video In",
0029 "Aux In", "Mono Out"
0030 };
0031 static const char *locations[8] = {
0032 "Rear I/O Panel", "Front Panel", "Motherboard", "Dock/External",
0033 "reserved", "reserved", "reserved", "NC/unused"
0034 };
0035
0036 for (function = 0; function < 12; ++function) {
0037 snd_ac97_write(ac97, AC97_FUNC_SELECT, function << 1);
0038 info = snd_ac97_read(ac97, AC97_FUNC_INFO);
0039 if (!(info & 0x0001))
0040 continue;
0041 if (!header) {
0042 snd_iprintf(buffer, "\n Gain Inverted Buffer delay Location\n");
0043 header = 1;
0044 }
0045 sense_info = snd_ac97_read(ac97, AC97_SENSE_INFO);
0046 snd_iprintf(buffer, "%-17s: %3d.%d dBV %c %2d/fs %s\n",
0047 function_names[function],
0048 (info & 0x8000 ? -1 : 1) * ((info & 0x7000) >> 12) * 3 / 2,
0049 ((info & 0x0800) >> 11) * 5,
0050 info & 0x0400 ? 'X' : '-',
0051 (info & 0x03e0) >> 5,
0052 locations[sense_info >> 13]);
0053 }
0054 }
0055
0056 static const char *snd_ac97_stereo_enhancements[] =
0057 {
0058 "No 3D Stereo Enhancement",
0059 "Analog Devices Phat Stereo",
0060 "Creative Stereo Enhancement",
0061 "National Semi 3D Stereo Enhancement",
0062 "YAMAHA Ymersion",
0063 "BBE 3D Stereo Enhancement",
0064 "Crystal Semi 3D Stereo Enhancement",
0065 "Qsound QXpander",
0066 "Spatializer 3D Stereo Enhancement",
0067 "SRS 3D Stereo Enhancement",
0068 "Platform Tech 3D Stereo Enhancement",
0069 "AKM 3D Audio",
0070 "Aureal Stereo Enhancement",
0071 "Aztech 3D Enhancement",
0072 "Binaura 3D Audio Enhancement",
0073 "ESS Technology Stereo Enhancement",
0074 "Harman International VMAx",
0075 "Nvidea/IC Ensemble/KS Waves 3D Stereo Enhancement",
0076 "Philips Incredible Sound",
0077 "Texas Instruments 3D Stereo Enhancement",
0078 "VLSI Technology 3D Stereo Enhancement",
0079 "TriTech 3D Stereo Enhancement",
0080 "Realtek 3D Stereo Enhancement",
0081 "Samsung 3D Stereo Enhancement",
0082 "Wolfson Microelectronics 3D Enhancement",
0083 "Delta Integration 3D Enhancement",
0084 "SigmaTel 3D Enhancement",
0085 "IC Ensemble/KS Waves",
0086 "Rockwell 3D Stereo Enhancement",
0087 "Reserved 29",
0088 "Reserved 30",
0089 "Reserved 31"
0090 };
0091
0092 static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
0093 {
0094 char name[64];
0095 unsigned short val, tmp, ext, mext;
0096 static const char *spdif_slots[4] = { " SPDIF=3/4", " SPDIF=7/8", " SPDIF=6/9", " SPDIF=10/11" };
0097 static const char *spdif_rates[4] = { " Rate=44.1kHz", " Rate=res", " Rate=48kHz", " Rate=32kHz" };
0098 static const char *spdif_rates_cs4205[4] = { " Rate=48kHz", " Rate=44.1kHz", " Rate=res", " Rate=res" };
0099 static const char *double_rate_slots[4] = { "10/11", "7/8", "reserved", "reserved" };
0100
0101 snd_ac97_get_name(NULL, ac97->id, name, 0);
0102 snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
0103
0104 if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
0105 goto __modem;
0106
0107 snd_iprintf(buffer, "PCI Subsys Vendor: 0x%04x\n",
0108 ac97->subsystem_vendor);
0109 snd_iprintf(buffer, "PCI Subsys Device: 0x%04x\n\n",
0110 ac97->subsystem_device);
0111
0112 snd_iprintf(buffer, "Flags: %x\n", ac97->flags);
0113
0114 if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
0115 val = snd_ac97_read(ac97, AC97_INT_PAGING);
0116 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
0117 AC97_PAGE_MASK, AC97_PAGE_1);
0118 tmp = snd_ac97_read(ac97, AC97_CODEC_CLASS_REV);
0119 snd_iprintf(buffer, "Revision : 0x%02x\n", tmp & 0xff);
0120 snd_iprintf(buffer, "Compat. Class : 0x%02x\n", (tmp >> 8) & 0x1f);
0121 snd_iprintf(buffer, "Subsys. Vendor ID: 0x%04x\n",
0122 snd_ac97_read(ac97, AC97_PCI_SVID));
0123 snd_iprintf(buffer, "Subsys. ID : 0x%04x\n\n",
0124 snd_ac97_read(ac97, AC97_PCI_SID));
0125 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
0126 AC97_PAGE_MASK, val & AC97_PAGE_MASK);
0127 }
0128
0129
0130 val = ac97->caps;
0131 snd_iprintf(buffer, "Capabilities :%s%s%s%s%s%s\n",
0132 val & AC97_BC_DEDICATED_MIC ? " -dedicated MIC PCM IN channel-" : "",
0133 val & AC97_BC_RESERVED1 ? " -reserved1-" : "",
0134 val & AC97_BC_BASS_TREBLE ? " -bass & treble-" : "",
0135 val & AC97_BC_SIM_STEREO ? " -simulated stereo-" : "",
0136 val & AC97_BC_HEADPHONE ? " -headphone out-" : "",
0137 val & AC97_BC_LOUDNESS ? " -loudness-" : "");
0138 tmp = ac97->caps & AC97_BC_DAC_MASK;
0139 snd_iprintf(buffer, "DAC resolution : %s%s%s%s\n",
0140 tmp == AC97_BC_16BIT_DAC ? "16-bit" : "",
0141 tmp == AC97_BC_18BIT_DAC ? "18-bit" : "",
0142 tmp == AC97_BC_20BIT_DAC ? "20-bit" : "",
0143 tmp == AC97_BC_DAC_MASK ? "???" : "");
0144 tmp = ac97->caps & AC97_BC_ADC_MASK;
0145 snd_iprintf(buffer, "ADC resolution : %s%s%s%s\n",
0146 tmp == AC97_BC_16BIT_ADC ? "16-bit" : "",
0147 tmp == AC97_BC_18BIT_ADC ? "18-bit" : "",
0148 tmp == AC97_BC_20BIT_ADC ? "20-bit" : "",
0149 tmp == AC97_BC_ADC_MASK ? "???" : "");
0150 snd_iprintf(buffer, "3D enhancement : %s\n",
0151 snd_ac97_stereo_enhancements[(val >> 10) & 0x1f]);
0152 snd_iprintf(buffer, "\nCurrent setup\n");
0153 val = snd_ac97_read(ac97, AC97_MIC);
0154 snd_iprintf(buffer, "Mic gain : %s [%s]\n", val & 0x0040 ? "+20dB" : "+0dB", ac97->regs[AC97_MIC] & 0x0040 ? "+20dB" : "+0dB");
0155 val = snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
0156 snd_iprintf(buffer, "POP path : %s 3D\n"
0157 "Sim. stereo : %s\n"
0158 "3D enhancement : %s\n"
0159 "Loudness : %s\n"
0160 "Mono output : %s\n"
0161 "Mic select : %s\n"
0162 "ADC/DAC loopback : %s\n",
0163 val & 0x8000 ? "post" : "pre",
0164 val & 0x4000 ? "on" : "off",
0165 val & 0x2000 ? "on" : "off",
0166 val & 0x1000 ? "on" : "off",
0167 val & 0x0200 ? "Mic" : "MIX",
0168 val & 0x0100 ? "Mic2" : "Mic1",
0169 val & 0x0080 ? "on" : "off");
0170 if (ac97->ext_id & AC97_EI_DRA)
0171 snd_iprintf(buffer, "Double rate slots: %s\n",
0172 double_rate_slots[(val >> 10) & 3]);
0173
0174 ext = snd_ac97_read(ac97, AC97_EXTENDED_ID);
0175 if (ext == 0)
0176 goto __modem;
0177
0178 snd_iprintf(buffer, "Extended ID : codec=%i rev=%i%s%s%s%s DSA=%i%s%s%s%s\n",
0179 (ext & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT,
0180 (ext & AC97_EI_REV_MASK) >> AC97_EI_REV_SHIFT,
0181 ext & AC97_EI_AMAP ? " AMAP" : "",
0182 ext & AC97_EI_LDAC ? " LDAC" : "",
0183 ext & AC97_EI_SDAC ? " SDAC" : "",
0184 ext & AC97_EI_CDAC ? " CDAC" : "",
0185 (ext & AC97_EI_DACS_SLOT_MASK) >> AC97_EI_DACS_SLOT_SHIFT,
0186 ext & AC97_EI_VRM ? " VRM" : "",
0187 ext & AC97_EI_SPDIF ? " SPDIF" : "",
0188 ext & AC97_EI_DRA ? " DRA" : "",
0189 ext & AC97_EI_VRA ? " VRA" : "");
0190 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
0191 snd_iprintf(buffer, "Extended status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
0192 val & AC97_EA_PRL ? " PRL" : "",
0193 val & AC97_EA_PRK ? " PRK" : "",
0194 val & AC97_EA_PRJ ? " PRJ" : "",
0195 val & AC97_EA_PRI ? " PRI" : "",
0196 val & AC97_EA_SPCV ? " SPCV" : "",
0197 val & AC97_EA_MDAC ? " MADC" : "",
0198 val & AC97_EA_LDAC ? " LDAC" : "",
0199 val & AC97_EA_SDAC ? " SDAC" : "",
0200 val & AC97_EA_CDAC ? " CDAC" : "",
0201 ext & AC97_EI_SPDIF ? spdif_slots[(val & AC97_EA_SPSA_SLOT_MASK) >> AC97_EA_SPSA_SLOT_SHIFT] : "",
0202 val & AC97_EA_VRM ? " VRM" : "",
0203 val & AC97_EA_SPDIF ? " SPDIF" : "",
0204 val & AC97_EA_DRA ? " DRA" : "",
0205 val & AC97_EA_VRA ? " VRA" : "");
0206 if (ext & AC97_EI_VRA) {
0207 val = snd_ac97_read(ac97, AC97_PCM_FRONT_DAC_RATE);
0208 snd_iprintf(buffer, "PCM front DAC : %iHz\n", val);
0209 if (ext & AC97_EI_SDAC) {
0210 val = snd_ac97_read(ac97, AC97_PCM_SURR_DAC_RATE);
0211 snd_iprintf(buffer, "PCM Surr DAC : %iHz\n", val);
0212 }
0213 if (ext & AC97_EI_LDAC) {
0214 val = snd_ac97_read(ac97, AC97_PCM_LFE_DAC_RATE);
0215 snd_iprintf(buffer, "PCM LFE DAC : %iHz\n", val);
0216 }
0217 val = snd_ac97_read(ac97, AC97_PCM_LR_ADC_RATE);
0218 snd_iprintf(buffer, "PCM ADC : %iHz\n", val);
0219 }
0220 if (ext & AC97_EI_VRM) {
0221 val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE);
0222 snd_iprintf(buffer, "PCM MIC ADC : %iHz\n", val);
0223 }
0224 if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF) ||
0225 (ac97->id == AC97_ID_YMF743)) {
0226 if (ac97->flags & AC97_CS_SPDIF)
0227 val = snd_ac97_read(ac97, AC97_CSR_SPDIF);
0228 else if (ac97->id == AC97_ID_YMF743) {
0229 val = snd_ac97_read(ac97, AC97_YMF7X3_DIT_CTRL);
0230 val = 0x2000 | (val & 0xff00) >> 4 | (val & 0x38) >> 2;
0231 } else
0232 val = snd_ac97_read(ac97, AC97_SPDIF);
0233
0234 snd_iprintf(buffer, "SPDIF Control :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n",
0235 val & AC97_SC_PRO ? " PRO" : " Consumer",
0236 val & AC97_SC_NAUDIO ? " Non-audio" : " PCM",
0237 val & AC97_SC_COPY ? "" : " Copyright",
0238 val & AC97_SC_PRE ? " Preemph50/15" : "",
0239 (val & AC97_SC_CC_MASK) >> AC97_SC_CC_SHIFT,
0240 (val & AC97_SC_L) >> 11,
0241 (ac97->flags & AC97_CS_SPDIF) ?
0242 spdif_rates_cs4205[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT] :
0243 spdif_rates[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT],
0244 (ac97->flags & AC97_CS_SPDIF) ?
0245 (val & AC97_SC_DRS ? " Validity" : "") :
0246 (val & AC97_SC_DRS ? " DRS" : ""),
0247 (ac97->flags & AC97_CS_SPDIF) ?
0248 (val & AC97_SC_V ? " Enabled" : "") :
0249 (val & AC97_SC_V ? " Validity" : ""));
0250
0251 if ((ac97->id & 0xfffffff0) == 0x414c4720 &&
0252 (snd_ac97_read(ac97, AC97_ALC650_CLOCK) & 0x01)) {
0253 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
0254 if (val & AC97_ALC650_CLOCK_LOCK) {
0255 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS1);
0256 snd_iprintf(buffer, "SPDIF In Status :%s%s%s%s Category=0x%x Generation=%i",
0257 val & AC97_ALC650_PRO ? " PRO" : " Consumer",
0258 val & AC97_ALC650_NAUDIO ? " Non-audio" : " PCM",
0259 val & AC97_ALC650_COPY ? "" : " Copyright",
0260 val & AC97_ALC650_PRE ? " Preemph50/15" : "",
0261 (val & AC97_ALC650_CC_MASK) >> AC97_ALC650_CC_SHIFT,
0262 (val & AC97_ALC650_L) >> 15);
0263 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
0264 snd_iprintf(buffer, "%s Accuracy=%i%s%s\n",
0265 spdif_rates[(val & AC97_ALC650_SPSR_MASK) >> AC97_ALC650_SPSR_SHIFT],
0266 (val & AC97_ALC650_CLOCK_ACCURACY) >> AC97_ALC650_CLOCK_SHIFT,
0267 (val & AC97_ALC650_CLOCK_LOCK ? " Locked" : " Unlocked"),
0268 (val & AC97_ALC650_V ? " Validity?" : ""));
0269 } else {
0270 snd_iprintf(buffer, "SPDIF In Status : Not Locked\n");
0271 }
0272 }
0273 }
0274 if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
0275 val = snd_ac97_read(ac97, AC97_INT_PAGING);
0276 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
0277 AC97_PAGE_MASK, AC97_PAGE_1);
0278 snd_ac97_proc_read_functions(ac97, buffer);
0279 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
0280 AC97_PAGE_MASK, val & AC97_PAGE_MASK);
0281 }
0282
0283
0284 __modem:
0285 mext = snd_ac97_read(ac97, AC97_EXTENDED_MID);
0286 if (mext == 0)
0287 return;
0288
0289 snd_iprintf(buffer, "Extended modem ID: codec=%i%s%s%s%s%s\n",
0290 (mext & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT,
0291 mext & AC97_MEI_CID2 ? " CID2" : "",
0292 mext & AC97_MEI_CID1 ? " CID1" : "",
0293 mext & AC97_MEI_HANDSET ? " HSET" : "",
0294 mext & AC97_MEI_LINE2 ? " LIN2" : "",
0295 mext & AC97_MEI_LINE1 ? " LIN1" : "");
0296 val = snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS);
0297 snd_iprintf(buffer, "Modem status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
0298 val & AC97_MEA_GPIO ? " GPIO" : "",
0299 val & AC97_MEA_MREF ? " MREF" : "",
0300 val & AC97_MEA_ADC1 ? " ADC1" : "",
0301 val & AC97_MEA_DAC1 ? " DAC1" : "",
0302 val & AC97_MEA_ADC2 ? " ADC2" : "",
0303 val & AC97_MEA_DAC2 ? " DAC2" : "",
0304 val & AC97_MEA_HADC ? " HADC" : "",
0305 val & AC97_MEA_HDAC ? " HDAC" : "",
0306 val & AC97_MEA_PRA ? " PRA(GPIO)" : "",
0307 val & AC97_MEA_PRB ? " PRB(res)" : "",
0308 val & AC97_MEA_PRC ? " PRC(ADC1)" : "",
0309 val & AC97_MEA_PRD ? " PRD(DAC1)" : "",
0310 val & AC97_MEA_PRE ? " PRE(ADC2)" : "",
0311 val & AC97_MEA_PRF ? " PRF(DAC2)" : "",
0312 val & AC97_MEA_PRG ? " PRG(HADC)" : "",
0313 val & AC97_MEA_PRH ? " PRH(HDAC)" : "");
0314 if (mext & AC97_MEI_LINE1) {
0315 val = snd_ac97_read(ac97, AC97_LINE1_RATE);
0316 snd_iprintf(buffer, "Line1 rate : %iHz\n", val);
0317 }
0318 if (mext & AC97_MEI_LINE2) {
0319 val = snd_ac97_read(ac97, AC97_LINE2_RATE);
0320 snd_iprintf(buffer, "Line2 rate : %iHz\n", val);
0321 }
0322 if (mext & AC97_MEI_HANDSET) {
0323 val = snd_ac97_read(ac97, AC97_HANDSET_RATE);
0324 snd_iprintf(buffer, "Headset rate : %iHz\n", val);
0325 }
0326 }
0327
0328 static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
0329 {
0330 struct snd_ac97 *ac97 = entry->private_data;
0331
0332 mutex_lock(&ac97->page_mutex);
0333 if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {
0334 int idx;
0335 for (idx = 0; idx < 3; idx++)
0336 if (ac97->spec.ad18xx.id[idx]) {
0337
0338 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
0339 ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
0340 snd_ac97_proc_read_main(ac97, buffer, idx);
0341 snd_iprintf(buffer, "\n\n");
0342 }
0343
0344 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
0345
0346 snd_iprintf(buffer, "\nAD18XX configuration\n");
0347 snd_iprintf(buffer, "Unchained : 0x%04x,0x%04x,0x%04x\n",
0348 ac97->spec.ad18xx.unchained[0],
0349 ac97->spec.ad18xx.unchained[1],
0350 ac97->spec.ad18xx.unchained[2]);
0351 snd_iprintf(buffer, "Chained : 0x%04x,0x%04x,0x%04x\n",
0352 ac97->spec.ad18xx.chained[0],
0353 ac97->spec.ad18xx.chained[1],
0354 ac97->spec.ad18xx.chained[2]);
0355 } else {
0356 snd_ac97_proc_read_main(ac97, buffer, 0);
0357 }
0358 mutex_unlock(&ac97->page_mutex);
0359 }
0360
0361 #ifdef CONFIG_SND_DEBUG
0362
0363 static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
0364 {
0365 struct snd_ac97 *ac97 = entry->private_data;
0366 char line[64];
0367 unsigned int reg, val;
0368 mutex_lock(&ac97->page_mutex);
0369 while (!snd_info_get_line(buffer, line, sizeof(line))) {
0370 if (sscanf(line, "%x %x", ®, &val) != 2)
0371 continue;
0372
0373 if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
0374 snd_ac97_write_cache(ac97, reg, val);
0375 }
0376 mutex_unlock(&ac97->page_mutex);
0377 }
0378 #endif
0379
0380 static void snd_ac97_proc_regs_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
0381 {
0382 int reg, val;
0383
0384 for (reg = 0; reg < 0x80; reg += 2) {
0385 val = snd_ac97_read(ac97, reg);
0386 snd_iprintf(buffer, "%i:%02x = %04x\n", subidx, reg, val);
0387 }
0388 }
0389
0390 static void snd_ac97_proc_regs_read(struct snd_info_entry *entry,
0391 struct snd_info_buffer *buffer)
0392 {
0393 struct snd_ac97 *ac97 = entry->private_data;
0394
0395 mutex_lock(&ac97->page_mutex);
0396 if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {
0397
0398 int idx;
0399 for (idx = 0; idx < 3; idx++)
0400 if (ac97->spec.ad18xx.id[idx]) {
0401
0402 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
0403 ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
0404 snd_ac97_proc_regs_read_main(ac97, buffer, idx);
0405 }
0406
0407 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
0408 } else {
0409 snd_ac97_proc_regs_read_main(ac97, buffer, 0);
0410 }
0411 mutex_unlock(&ac97->page_mutex);
0412 }
0413
0414 void snd_ac97_proc_init(struct snd_ac97 * ac97)
0415 {
0416 struct snd_info_entry *entry;
0417 char name[32];
0418 const char *prefix;
0419
0420 if (ac97->bus->proc == NULL)
0421 return;
0422 prefix = ac97_is_audio(ac97) ? "ac97" : "mc97";
0423 sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num);
0424 entry = snd_info_create_card_entry(ac97->bus->card, name,
0425 ac97->bus->proc);
0426 if (entry)
0427 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read);
0428 ac97->proc = entry;
0429 sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num);
0430 entry = snd_info_create_card_entry(ac97->bus->card, name,
0431 ac97->bus->proc);
0432 if (entry) {
0433 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read);
0434 #ifdef CONFIG_SND_DEBUG
0435 entry->mode |= 0200;
0436 entry->c.text.write = snd_ac97_proc_regs_write;
0437 #endif
0438 }
0439 ac97->proc_regs = entry;
0440 }
0441
0442 void snd_ac97_proc_done(struct snd_ac97 * ac97)
0443 {
0444 snd_info_free_entry(ac97->proc_regs);
0445 ac97->proc_regs = NULL;
0446 snd_info_free_entry(ac97->proc);
0447 ac97->proc = NULL;
0448 }
0449
0450 void snd_ac97_bus_proc_init(struct snd_ac97_bus * bus)
0451 {
0452 struct snd_info_entry *entry;
0453 char name[32];
0454
0455 sprintf(name, "codec97#%d", bus->num);
0456 entry = snd_info_create_card_entry(bus->card, name,
0457 bus->card->proc_root);
0458 if (entry)
0459 entry->mode = S_IFDIR | 0555;
0460 bus->proc = entry;
0461 }
0462
0463 void snd_ac97_bus_proc_done(struct snd_ac97_bus * bus)
0464 {
0465 snd_info_free_entry(bus->proc);
0466 bus->proc = NULL;
0467 }