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