1
2
3
4
5
6
7
8
9
10#include <linux/mutex.h>
11
12#include <sound/core.h>
13#include <sound/ac97_codec.h>
14#include <sound/asoundef.h>
15#include "ac97_local.h"
16#include "ac97_id.h"
17
18
19
20
21
22static void snd_ac97_proc_read_functions(struct snd_ac97 *ac97, struct snd_info_buffer *buffer)
23{
24 int header = 0, function;
25 unsigned short info, sense_info;
26 static const char *function_names[12] = {
27 "Master Out", "AUX Out", "Center/LFE Out", "SPDIF Out",
28 "Phone In", "Mic 1", "Mic 2", "Line In", "CD In", "Video In",
29 "Aux In", "Mono Out"
30 };
31 static const char *locations[8] = {
32 "Rear I/O Panel", "Front Panel", "Motherboard", "Dock/External",
33 "reserved", "reserved", "reserved", "NC/unused"
34 };
35
36 for (function = 0; function < 12; ++function) {
37 snd_ac97_write(ac97, AC97_FUNC_SELECT, function << 1);
38 info = snd_ac97_read(ac97, AC97_FUNC_INFO);
39 if (!(info & 0x0001))
40 continue;
41 if (!header) {
42 snd_iprintf(buffer, "\n Gain Inverted Buffer delay Location\n");
43 header = 1;
44 }
45 sense_info = snd_ac97_read(ac97, AC97_SENSE_INFO);
46 snd_iprintf(buffer, "%-17s: %3d.%d dBV %c %2d/fs %s\n",
47 function_names[function],
48 (info & 0x8000 ? -1 : 1) * ((info & 0x7000) >> 12) * 3 / 2,
49 ((info & 0x0800) >> 11) * 5,
50 info & 0x0400 ? 'X' : '-',
51 (info & 0x03e0) >> 5,
52 locations[sense_info >> 13]);
53 }
54}
55
56static const char *snd_ac97_stereo_enhancements[] =
57{
58 "No 3D Stereo Enhancement",
59 "Analog Devices Phat Stereo",
60 "Creative Stereo Enhancement",
61 "National Semi 3D Stereo Enhancement",
62 "YAMAHA Ymersion",
63 "BBE 3D Stereo Enhancement",
64 "Crystal Semi 3D Stereo Enhancement",
65 "Qsound QXpander",
66 "Spatializer 3D Stereo Enhancement",
67 "SRS 3D Stereo Enhancement",
68 "Platform Tech 3D Stereo Enhancement",
69 "AKM 3D Audio",
70 "Aureal Stereo Enhancement",
71 "Aztech 3D Enhancement",
72 "Binaura 3D Audio Enhancement",
73 "ESS Technology Stereo Enhancement",
74 "Harman International VMAx",
75 "Nvidea/IC Ensemble/KS Waves 3D Stereo Enhancement",
76 "Philips Incredible Sound",
77 "Texas Instruments 3D Stereo Enhancement",
78 "VLSI Technology 3D Stereo Enhancement",
79 "TriTech 3D Stereo Enhancement",
80 "Realtek 3D Stereo Enhancement",
81 "Samsung 3D Stereo Enhancement",
82 "Wolfson Microelectronics 3D Enhancement",
83 "Delta Integration 3D Enhancement",
84 "SigmaTel 3D Enhancement",
85 "IC Ensemble/KS Waves",
86 "Rockwell 3D Stereo Enhancement",
87 "Reserved 29",
88 "Reserved 30",
89 "Reserved 31"
90};
91
92static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
93{
94 char name[64];
95 unsigned short val, tmp, ext, mext;
96 static const char *spdif_slots[4] = { " SPDIF=3/4", " SPDIF=7/8", " SPDIF=6/9", " SPDIF=10/11" };
97 static const char *spdif_rates[4] = { " Rate=44.1kHz", " Rate=res", " Rate=48kHz", " Rate=32kHz" };
98 static const char *spdif_rates_cs4205[4] = { " Rate=48kHz", " Rate=44.1kHz", " Rate=res", " Rate=res" };
99 static const char *double_rate_slots[4] = { "10/11", "7/8", "reserved", "reserved" };
100
101 snd_ac97_get_name(NULL, ac97->id, name, 0);
102 snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
103
104 if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
105 goto __modem;
106
107 snd_iprintf(buffer, "PCI Subsys Vendor: 0x%04x\n",
108 ac97->subsystem_vendor);
109 snd_iprintf(buffer, "PCI Subsys Device: 0x%04x\n\n",
110 ac97->subsystem_device);
111
112 snd_iprintf(buffer, "Flags: %x\n", ac97->flags);
113
114 if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
115 val = snd_ac97_read(ac97, AC97_INT_PAGING);
116 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
117 AC97_PAGE_MASK, AC97_PAGE_1);
118 tmp = snd_ac97_read(ac97, AC97_CODEC_CLASS_REV);
119 snd_iprintf(buffer, "Revision : 0x%02x\n", tmp & 0xff);
120 snd_iprintf(buffer, "Compat. Class : 0x%02x\n", (tmp >> 8) & 0x1f);
121 snd_iprintf(buffer, "Subsys. Vendor ID: 0x%04x\n",
122 snd_ac97_read(ac97, AC97_PCI_SVID));
123 snd_iprintf(buffer, "Subsys. ID : 0x%04x\n\n",
124 snd_ac97_read(ac97, AC97_PCI_SID));
125 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
126 AC97_PAGE_MASK, val & AC97_PAGE_MASK);
127 }
128
129
130 val = ac97->caps;
131 snd_iprintf(buffer, "Capabilities :%s%s%s%s%s%s\n",
132 val & AC97_BC_DEDICATED_MIC ? " -dedicated MIC PCM IN channel-" : "",
133 val & AC97_BC_RESERVED1 ? " -reserved1-" : "",
134 val & AC97_BC_BASS_TREBLE ? " -bass & treble-" : "",
135 val & AC97_BC_SIM_STEREO ? " -simulated stereo-" : "",
136 val & AC97_BC_HEADPHONE ? " -headphone out-" : "",
137 val & AC97_BC_LOUDNESS ? " -loudness-" : "");
138 tmp = ac97->caps & AC97_BC_DAC_MASK;
139 snd_iprintf(buffer, "DAC resolution : %s%s%s%s\n",
140 tmp == AC97_BC_16BIT_DAC ? "16-bit" : "",
141 tmp == AC97_BC_18BIT_DAC ? "18-bit" : "",
142 tmp == AC97_BC_20BIT_DAC ? "20-bit" : "",
143 tmp == AC97_BC_DAC_MASK ? "???" : "");
144 tmp = ac97->caps & AC97_BC_ADC_MASK;
145 snd_iprintf(buffer, "ADC resolution : %s%s%s%s\n",
146 tmp == AC97_BC_16BIT_ADC ? "16-bit" : "",
147 tmp == AC97_BC_18BIT_ADC ? "18-bit" : "",
148 tmp == AC97_BC_20BIT_ADC ? "20-bit" : "",
149 tmp == AC97_BC_ADC_MASK ? "???" : "");
150 snd_iprintf(buffer, "3D enhancement : %s\n",
151 snd_ac97_stereo_enhancements[(val >> 10) & 0x1f]);
152 snd_iprintf(buffer, "\nCurrent setup\n");
153 val = snd_ac97_read(ac97, AC97_MIC);
154 snd_iprintf(buffer, "Mic gain : %s [%s]\n", val & 0x0040 ? "+20dB" : "+0dB", ac97->regs[AC97_MIC] & 0x0040 ? "+20dB" : "+0dB");
155 val = snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
156 snd_iprintf(buffer, "POP path : %s 3D\n"
157 "Sim. stereo : %s\n"
158 "3D enhancement : %s\n"
159 "Loudness : %s\n"
160 "Mono output : %s\n"
161 "Mic select : %s\n"
162 "ADC/DAC loopback : %s\n",
163 val & 0x8000 ? "post" : "pre",
164 val & 0x4000 ? "on" : "off",
165 val & 0x2000 ? "on" : "off",
166 val & 0x1000 ? "on" : "off",
167 val & 0x0200 ? "Mic" : "MIX",
168 val & 0x0100 ? "Mic2" : "Mic1",
169 val & 0x0080 ? "on" : "off");
170 if (ac97->ext_id & AC97_EI_DRA)
171 snd_iprintf(buffer, "Double rate slots: %s\n",
172 double_rate_slots[(val >> 10) & 3]);
173
174 ext = snd_ac97_read(ac97, AC97_EXTENDED_ID);
175 if (ext == 0)
176 goto __modem;
177
178 snd_iprintf(buffer, "Extended ID : codec=%i rev=%i%s%s%s%s DSA=%i%s%s%s%s\n",
179 (ext & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT,
180 (ext & AC97_EI_REV_MASK) >> AC97_EI_REV_SHIFT,
181 ext & AC97_EI_AMAP ? " AMAP" : "",
182 ext & AC97_EI_LDAC ? " LDAC" : "",
183 ext & AC97_EI_SDAC ? " SDAC" : "",
184 ext & AC97_EI_CDAC ? " CDAC" : "",
185 (ext & AC97_EI_DACS_SLOT_MASK) >> AC97_EI_DACS_SLOT_SHIFT,
186 ext & AC97_EI_VRM ? " VRM" : "",
187 ext & AC97_EI_SPDIF ? " SPDIF" : "",
188 ext & AC97_EI_DRA ? " DRA" : "",
189 ext & AC97_EI_VRA ? " VRA" : "");
190 val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
191 snd_iprintf(buffer, "Extended status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
192 val & AC97_EA_PRL ? " PRL" : "",
193 val & AC97_EA_PRK ? " PRK" : "",
194 val & AC97_EA_PRJ ? " PRJ" : "",
195 val & AC97_EA_PRI ? " PRI" : "",
196 val & AC97_EA_SPCV ? " SPCV" : "",
197 val & AC97_EA_MDAC ? " MADC" : "",
198 val & AC97_EA_LDAC ? " LDAC" : "",
199 val & AC97_EA_SDAC ? " SDAC" : "",
200 val & AC97_EA_CDAC ? " CDAC" : "",
201 ext & AC97_EI_SPDIF ? spdif_slots[(val & AC97_EA_SPSA_SLOT_MASK) >> AC97_EA_SPSA_SLOT_SHIFT] : "",
202 val & AC97_EA_VRM ? " VRM" : "",
203 val & AC97_EA_SPDIF ? " SPDIF" : "",
204 val & AC97_EA_DRA ? " DRA" : "",
205 val & AC97_EA_VRA ? " VRA" : "");
206 if (ext & AC97_EI_VRA) {
207 val = snd_ac97_read(ac97, AC97_PCM_FRONT_DAC_RATE);
208 snd_iprintf(buffer, "PCM front DAC : %iHz\n", val);
209 if (ext & AC97_EI_SDAC) {
210 val = snd_ac97_read(ac97, AC97_PCM_SURR_DAC_RATE);
211 snd_iprintf(buffer, "PCM Surr DAC : %iHz\n", val);
212 }
213 if (ext & AC97_EI_LDAC) {
214 val = snd_ac97_read(ac97, AC97_PCM_LFE_DAC_RATE);
215 snd_iprintf(buffer, "PCM LFE DAC : %iHz\n", val);
216 }
217 val = snd_ac97_read(ac97, AC97_PCM_LR_ADC_RATE);
218 snd_iprintf(buffer, "PCM ADC : %iHz\n", val);
219 }
220 if (ext & AC97_EI_VRM) {
221 val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE);
222 snd_iprintf(buffer, "PCM MIC ADC : %iHz\n", val);
223 }
224 if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF) ||
225 (ac97->id == AC97_ID_YMF743)) {
226 if (ac97->flags & AC97_CS_SPDIF)
227 val = snd_ac97_read(ac97, AC97_CSR_SPDIF);
228 else if (ac97->id == AC97_ID_YMF743) {
229 val = snd_ac97_read(ac97, AC97_YMF7X3_DIT_CTRL);
230 val = 0x2000 | (val & 0xff00) >> 4 | (val & 0x38) >> 2;
231 } else
232 val = snd_ac97_read(ac97, AC97_SPDIF);
233
234 snd_iprintf(buffer, "SPDIF Control :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n",
235 val & AC97_SC_PRO ? " PRO" : " Consumer",
236 val & AC97_SC_NAUDIO ? " Non-audio" : " PCM",
237 val & AC97_SC_COPY ? "" : " Copyright",
238 val & AC97_SC_PRE ? " Preemph50/15" : "",
239 (val & AC97_SC_CC_MASK) >> AC97_SC_CC_SHIFT,
240 (val & AC97_SC_L) >> 11,
241 (ac97->flags & AC97_CS_SPDIF) ?
242 spdif_rates_cs4205[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT] :
243 spdif_rates[(val & AC97_SC_SPSR_MASK) >> AC97_SC_SPSR_SHIFT],
244 (ac97->flags & AC97_CS_SPDIF) ?
245 (val & AC97_SC_DRS ? " Validity" : "") :
246 (val & AC97_SC_DRS ? " DRS" : ""),
247 (ac97->flags & AC97_CS_SPDIF) ?
248 (val & AC97_SC_V ? " Enabled" : "") :
249 (val & AC97_SC_V ? " Validity" : ""));
250
251 if ((ac97->id & 0xfffffff0) == 0x414c4720 &&
252 (snd_ac97_read(ac97, AC97_ALC650_CLOCK) & 0x01)) {
253 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
254 if (val & AC97_ALC650_CLOCK_LOCK) {
255 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS1);
256 snd_iprintf(buffer, "SPDIF In Status :%s%s%s%s Category=0x%x Generation=%i",
257 val & AC97_ALC650_PRO ? " PRO" : " Consumer",
258 val & AC97_ALC650_NAUDIO ? " Non-audio" : " PCM",
259 val & AC97_ALC650_COPY ? "" : " Copyright",
260 val & AC97_ALC650_PRE ? " Preemph50/15" : "",
261 (val & AC97_ALC650_CC_MASK) >> AC97_ALC650_CC_SHIFT,
262 (val & AC97_ALC650_L) >> 15);
263 val = snd_ac97_read(ac97, AC97_ALC650_SPDIF_INPUT_STATUS2);
264 snd_iprintf(buffer, "%s Accuracy=%i%s%s\n",
265 spdif_rates[(val & AC97_ALC650_SPSR_MASK) >> AC97_ALC650_SPSR_SHIFT],
266 (val & AC97_ALC650_CLOCK_ACCURACY) >> AC97_ALC650_CLOCK_SHIFT,
267 (val & AC97_ALC650_CLOCK_LOCK ? " Locked" : " Unlocked"),
268 (val & AC97_ALC650_V ? " Validity?" : ""));
269 } else {
270 snd_iprintf(buffer, "SPDIF In Status : Not Locked\n");
271 }
272 }
273 }
274 if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
275 val = snd_ac97_read(ac97, AC97_INT_PAGING);
276 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
277 AC97_PAGE_MASK, AC97_PAGE_1);
278 snd_ac97_proc_read_functions(ac97, buffer);
279 snd_ac97_update_bits(ac97, AC97_INT_PAGING,
280 AC97_PAGE_MASK, val & AC97_PAGE_MASK);
281 }
282
283
284 __modem:
285 mext = snd_ac97_read(ac97, AC97_EXTENDED_MID);
286 if (mext == 0)
287 return;
288
289 snd_iprintf(buffer, "Extended modem ID: codec=%i%s%s%s%s%s\n",
290 (mext & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT,
291 mext & AC97_MEI_CID2 ? " CID2" : "",
292 mext & AC97_MEI_CID1 ? " CID1" : "",
293 mext & AC97_MEI_HANDSET ? " HSET" : "",
294 mext & AC97_MEI_LINE2 ? " LIN2" : "",
295 mext & AC97_MEI_LINE1 ? " LIN1" : "");
296 val = snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS);
297 snd_iprintf(buffer, "Modem status :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
298 val & AC97_MEA_GPIO ? " GPIO" : "",
299 val & AC97_MEA_MREF ? " MREF" : "",
300 val & AC97_MEA_ADC1 ? " ADC1" : "",
301 val & AC97_MEA_DAC1 ? " DAC1" : "",
302 val & AC97_MEA_ADC2 ? " ADC2" : "",
303 val & AC97_MEA_DAC2 ? " DAC2" : "",
304 val & AC97_MEA_HADC ? " HADC" : "",
305 val & AC97_MEA_HDAC ? " HDAC" : "",
306 val & AC97_MEA_PRA ? " PRA(GPIO)" : "",
307 val & AC97_MEA_PRB ? " PRB(res)" : "",
308 val & AC97_MEA_PRC ? " PRC(ADC1)" : "",
309 val & AC97_MEA_PRD ? " PRD(DAC1)" : "",
310 val & AC97_MEA_PRE ? " PRE(ADC2)" : "",
311 val & AC97_MEA_PRF ? " PRF(DAC2)" : "",
312 val & AC97_MEA_PRG ? " PRG(HADC)" : "",
313 val & AC97_MEA_PRH ? " PRH(HDAC)" : "");
314 if (mext & AC97_MEI_LINE1) {
315 val = snd_ac97_read(ac97, AC97_LINE1_RATE);
316 snd_iprintf(buffer, "Line1 rate : %iHz\n", val);
317 }
318 if (mext & AC97_MEI_LINE2) {
319 val = snd_ac97_read(ac97, AC97_LINE2_RATE);
320 snd_iprintf(buffer, "Line2 rate : %iHz\n", val);
321 }
322 if (mext & AC97_MEI_HANDSET) {
323 val = snd_ac97_read(ac97, AC97_HANDSET_RATE);
324 snd_iprintf(buffer, "Headset rate : %iHz\n", val);
325 }
326}
327
328static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
329{
330 struct snd_ac97 *ac97 = entry->private_data;
331
332 mutex_lock(&ac97->page_mutex);
333 if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {
334 int idx;
335 for (idx = 0; idx < 3; idx++)
336 if (ac97->spec.ad18xx.id[idx]) {
337
338 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
339 ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
340 snd_ac97_proc_read_main(ac97, buffer, idx);
341 snd_iprintf(buffer, "\n\n");
342 }
343
344 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
345
346 snd_iprintf(buffer, "\nAD18XX configuration\n");
347 snd_iprintf(buffer, "Unchained : 0x%04x,0x%04x,0x%04x\n",
348 ac97->spec.ad18xx.unchained[0],
349 ac97->spec.ad18xx.unchained[1],
350 ac97->spec.ad18xx.unchained[2]);
351 snd_iprintf(buffer, "Chained : 0x%04x,0x%04x,0x%04x\n",
352 ac97->spec.ad18xx.chained[0],
353 ac97->spec.ad18xx.chained[1],
354 ac97->spec.ad18xx.chained[2]);
355 } else {
356 snd_ac97_proc_read_main(ac97, buffer, 0);
357 }
358 mutex_unlock(&ac97->page_mutex);
359}
360
361#ifdef CONFIG_SND_DEBUG
362
363static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
364{
365 struct snd_ac97 *ac97 = entry->private_data;
366 char line[64];
367 unsigned int reg, val;
368 mutex_lock(&ac97->page_mutex);
369 while (!snd_info_get_line(buffer, line, sizeof(line))) {
370 if (sscanf(line, "%x %x", ®, &val) != 2)
371 continue;
372
373 if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
374 snd_ac97_write_cache(ac97, reg, val);
375 }
376 mutex_unlock(&ac97->page_mutex);
377}
378#endif
379
380static void snd_ac97_proc_regs_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
381{
382 int reg, val;
383
384 for (reg = 0; reg < 0x80; reg += 2) {
385 val = snd_ac97_read(ac97, reg);
386 snd_iprintf(buffer, "%i:%02x = %04x\n", subidx, reg, val);
387 }
388}
389
390static void snd_ac97_proc_regs_read(struct snd_info_entry *entry,
391 struct snd_info_buffer *buffer)
392{
393 struct snd_ac97 *ac97 = entry->private_data;
394
395 mutex_lock(&ac97->page_mutex);
396 if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {
397
398 int idx;
399 for (idx = 0; idx < 3; idx++)
400 if (ac97->spec.ad18xx.id[idx]) {
401
402 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000,
403 ac97->spec.ad18xx.unchained[idx] | ac97->spec.ad18xx.chained[idx]);
404 snd_ac97_proc_regs_read_main(ac97, buffer, idx);
405 }
406
407 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
408 } else {
409 snd_ac97_proc_regs_read_main(ac97, buffer, 0);
410 }
411 mutex_unlock(&ac97->page_mutex);
412}
413
414void snd_ac97_proc_init(struct snd_ac97 * ac97)
415{
416 struct snd_info_entry *entry;
417 char name[32];
418 const char *prefix;
419
420 if (ac97->bus->proc == NULL)
421 return;
422 prefix = ac97_is_audio(ac97) ? "ac97" : "mc97";
423 sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num);
424 entry = snd_info_create_card_entry(ac97->bus->card, name,
425 ac97->bus->proc);
426 if (entry)
427 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read);
428 ac97->proc = entry;
429 sprintf(name, "%s#%d-%d+regs", prefix, ac97->addr, ac97->num);
430 entry = snd_info_create_card_entry(ac97->bus->card, name,
431 ac97->bus->proc);
432 if (entry) {
433 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read);
434#ifdef CONFIG_SND_DEBUG
435 entry->mode |= 0200;
436 entry->c.text.write = snd_ac97_proc_regs_write;
437#endif
438 }
439 ac97->proc_regs = entry;
440}
441
442void snd_ac97_proc_done(struct snd_ac97 * ac97)
443{
444 snd_info_free_entry(ac97->proc_regs);
445 ac97->proc_regs = NULL;
446 snd_info_free_entry(ac97->proc);
447 ac97->proc = NULL;
448}
449
450void snd_ac97_bus_proc_init(struct snd_ac97_bus * bus)
451{
452 struct snd_info_entry *entry;
453 char name[32];
454
455 sprintf(name, "codec97#%d", bus->num);
456 entry = snd_info_create_card_entry(bus->card, name,
457 bus->card->proc_root);
458 if (entry)
459 entry->mode = S_IFDIR | 0555;
460 bus->proc = entry;
461}
462
463void snd_ac97_bus_proc_done(struct snd_ac97_bus * bus)
464{
465 snd_info_free_entry(bus->proc);
466 bus->proc = NULL;
467}
468