diff options
Diffstat (limited to 'sound/oss/ac97_codec.c')
-rw-r--r-- | sound/oss/ac97_codec.c | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index fef56cac06c8..87a672680761 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c | |||
@@ -189,42 +189,6 @@ static const struct { | |||
189 | {0x57454301, "Winbond 83971D", &null_ops}, | 189 | {0x57454301, "Winbond 83971D", &null_ops}, |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static const char *ac97_stereo_enhancements[] = | ||
193 | { | ||
194 | /* 0 */ "No 3D Stereo Enhancement", | ||
195 | /* 1 */ "Analog Devices Phat Stereo", | ||
196 | /* 2 */ "Creative Stereo Enhancement", | ||
197 | /* 3 */ "National Semi 3D Stereo Enhancement", | ||
198 | /* 4 */ "YAMAHA Ymersion", | ||
199 | /* 5 */ "BBE 3D Stereo Enhancement", | ||
200 | /* 6 */ "Crystal Semi 3D Stereo Enhancement", | ||
201 | /* 7 */ "Qsound QXpander", | ||
202 | /* 8 */ "Spatializer 3D Stereo Enhancement", | ||
203 | /* 9 */ "SRS 3D Stereo Enhancement", | ||
204 | /* 10 */ "Platform Tech 3D Stereo Enhancement", | ||
205 | /* 11 */ "AKM 3D Audio", | ||
206 | /* 12 */ "Aureal Stereo Enhancement", | ||
207 | /* 13 */ "Aztech 3D Enhancement", | ||
208 | /* 14 */ "Binaura 3D Audio Enhancement", | ||
209 | /* 15 */ "ESS Technology Stereo Enhancement", | ||
210 | /* 16 */ "Harman International VMAx", | ||
211 | /* 17 */ "Nvidea 3D Stereo Enhancement", | ||
212 | /* 18 */ "Philips Incredible Sound", | ||
213 | /* 19 */ "Texas Instruments 3D Stereo Enhancement", | ||
214 | /* 20 */ "VLSI Technology 3D Stereo Enhancement", | ||
215 | /* 21 */ "TriTech 3D Stereo Enhancement", | ||
216 | /* 22 */ "Realtek 3D Stereo Enhancement", | ||
217 | /* 23 */ "Samsung 3D Stereo Enhancement", | ||
218 | /* 24 */ "Wolfson Microelectronics 3D Enhancement", | ||
219 | /* 25 */ "Delta Integration 3D Enhancement", | ||
220 | /* 26 */ "SigmaTel 3D Enhancement", | ||
221 | /* 27 */ "Winbond 3D Stereo Enhancement", | ||
222 | /* 28 */ "Rockwell 3D Stereo Enhancement", | ||
223 | /* 29 */ "Reserved 29", | ||
224 | /* 30 */ "Reserved 30", | ||
225 | /* 31 */ "Reserved 31" | ||
226 | }; | ||
227 | |||
228 | /* this table has default mixer values for all OSS mixers. */ | 192 | /* this table has default mixer values for all OSS mixers. */ |
229 | static struct mixer_defaults { | 193 | static struct mixer_defaults { |
230 | int mixer; | 194 | int mixer; |
@@ -614,83 +578,6 @@ static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned | |||
614 | return -EINVAL; | 578 | return -EINVAL; |
615 | } | 579 | } |
616 | 580 | ||
617 | /* entry point for /proc/driver/controller_vendor/ac97/%d */ | ||
618 | int ac97_read_proc (char *page, char **start, off_t off, | ||
619 | int count, int *eof, void *data) | ||
620 | { | ||
621 | int len = 0, cap, extid, val, id1, id2; | ||
622 | struct ac97_codec *codec; | ||
623 | int is_ac97_20 = 0; | ||
624 | |||
625 | if ((codec = data) == NULL) | ||
626 | return -ENODEV; | ||
627 | |||
628 | id1 = codec->codec_read(codec, AC97_VENDOR_ID1); | ||
629 | id2 = codec->codec_read(codec, AC97_VENDOR_ID2); | ||
630 | len += sprintf (page+len, "Vendor name : %s\n", codec->name); | ||
631 | len += sprintf (page+len, "Vendor id : %04X %04X\n", id1, id2); | ||
632 | |||
633 | extid = codec->codec_read(codec, AC97_EXTENDED_ID); | ||
634 | extid &= ~((1<<2)|(1<<4)|(1<<5)|(1<<10)|(1<<11)|(1<<12)|(1<<13)); | ||
635 | len += sprintf (page+len, "AC97 Version : %s\n", | ||
636 | extid ? "2.0 or later" : "1.0"); | ||
637 | if (extid) is_ac97_20 = 1; | ||
638 | |||
639 | cap = codec->codec_read(codec, AC97_RESET); | ||
640 | len += sprintf (page+len, "Capabilities :%s%s%s%s%s%s\n", | ||
641 | cap & 0x0001 ? " -dedicated MIC PCM IN channel-" : "", | ||
642 | cap & 0x0002 ? " -reserved1-" : "", | ||
643 | cap & 0x0004 ? " -bass & treble-" : "", | ||
644 | cap & 0x0008 ? " -simulated stereo-" : "", | ||
645 | cap & 0x0010 ? " -headphone out-" : "", | ||
646 | cap & 0x0020 ? " -loudness-" : ""); | ||
647 | val = cap & 0x00c0; | ||
648 | len += sprintf (page+len, "DAC resolutions :%s%s%s\n", | ||
649 | " -16-bit-", | ||
650 | val & 0x0040 ? " -18-bit-" : "", | ||
651 | val & 0x0080 ? " -20-bit-" : ""); | ||
652 | val = cap & 0x0300; | ||
653 | len += sprintf (page+len, "ADC resolutions :%s%s%s\n", | ||
654 | " -16-bit-", | ||
655 | val & 0x0100 ? " -18-bit-" : "", | ||
656 | val & 0x0200 ? " -20-bit-" : ""); | ||
657 | len += sprintf (page+len, "3D enhancement : %s\n", | ||
658 | ac97_stereo_enhancements[(cap >> 10) & 0x1f]); | ||
659 | |||
660 | val = codec->codec_read(codec, AC97_GENERAL_PURPOSE); | ||
661 | len += sprintf (page+len, "POP path : %s 3D\n" | ||
662 | "Sim. stereo : %s\n" | ||
663 | "3D enhancement : %s\n" | ||
664 | "Loudness : %s\n" | ||
665 | "Mono output : %s\n" | ||
666 | "MIC select : %s\n" | ||
667 | "ADC/DAC loopback : %s\n", | ||
668 | val & 0x8000 ? "post" : "pre", | ||
669 | val & 0x4000 ? "on" : "off", | ||
670 | val & 0x2000 ? "on" : "off", | ||
671 | val & 0x1000 ? "on" : "off", | ||
672 | val & 0x0200 ? "MIC" : "MIX", | ||
673 | val & 0x0100 ? "MIC2" : "MIC1", | ||
674 | val & 0x0080 ? "on" : "off"); | ||
675 | |||
676 | extid = codec->codec_read(codec, AC97_EXTENDED_ID); | ||
677 | cap = extid; | ||
678 | len += sprintf (page+len, "Ext Capabilities :%s%s%s%s%s%s%s\n", | ||
679 | cap & 0x0001 ? " -var rate PCM audio-" : "", | ||
680 | cap & 0x0002 ? " -2x PCM audio out-" : "", | ||
681 | cap & 0x0008 ? " -var rate MIC in-" : "", | ||
682 | cap & 0x0040 ? " -PCM center DAC-" : "", | ||
683 | cap & 0x0080 ? " -PCM surround DAC-" : "", | ||
684 | cap & 0x0100 ? " -PCM LFE DAC-" : "", | ||
685 | cap & 0x0200 ? " -slot/DAC mappings-" : ""); | ||
686 | if (is_ac97_20) { | ||
687 | len += sprintf (page+len, "Front DAC rate : %d\n", | ||
688 | codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)); | ||
689 | } | ||
690 | |||
691 | return len; | ||
692 | } | ||
693 | |||
694 | /** | 581 | /** |
695 | * codec_id - Turn id1/id2 into a PnP string | 582 | * codec_id - Turn id1/id2 into a PnP string |
696 | * @id1: Vendor ID1 | 583 | * @id1: Vendor ID1 |
@@ -1313,176 +1200,5 @@ static int pt101_init(struct ac97_codec * codec) | |||
1313 | #endif | 1200 | #endif |
1314 | 1201 | ||
1315 | 1202 | ||
1316 | EXPORT_SYMBOL(ac97_read_proc); | ||
1317 | EXPORT_SYMBOL(ac97_probe_codec); | 1203 | EXPORT_SYMBOL(ac97_probe_codec); |
1318 | 1204 | ||
1319 | /* | ||
1320 | * AC97 library support routines | ||
1321 | */ | ||
1322 | |||
1323 | /** | ||
1324 | * ac97_set_dac_rate - set codec rate adaption | ||
1325 | * @codec: ac97 code | ||
1326 | * @rate: rate in hertz | ||
1327 | * | ||
1328 | * Set the DAC rate. Assumes the codec supports VRA. The caller is | ||
1329 | * expected to have checked this little detail. | ||
1330 | */ | ||
1331 | |||
1332 | unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate) | ||
1333 | { | ||
1334 | unsigned int new_rate = rate; | ||
1335 | u32 dacp; | ||
1336 | u32 mast_vol, phone_vol, mono_vol, pcm_vol; | ||
1337 | u32 mute_vol = 0x8000; /* The mute volume? */ | ||
1338 | |||
1339 | if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)) | ||
1340 | { | ||
1341 | /* Mute several registers */ | ||
1342 | mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO); | ||
1343 | mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO); | ||
1344 | phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL); | ||
1345 | pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL); | ||
1346 | codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol); | ||
1347 | codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol); | ||
1348 | codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol); | ||
1349 | codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol); | ||
1350 | |||
1351 | /* Power down the DAC */ | ||
1352 | dacp=codec->codec_read(codec, AC97_POWER_CONTROL); | ||
1353 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200); | ||
1354 | /* Load the rate and read the effective rate */ | ||
1355 | codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate); | ||
1356 | new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE); | ||
1357 | /* Power it back up */ | ||
1358 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp); | ||
1359 | |||
1360 | /* Restore volumes */ | ||
1361 | codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol); | ||
1362 | codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol); | ||
1363 | codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol); | ||
1364 | codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol); | ||
1365 | } | ||
1366 | return new_rate; | ||
1367 | } | ||
1368 | |||
1369 | EXPORT_SYMBOL(ac97_set_dac_rate); | ||
1370 | |||
1371 | /** | ||
1372 | * ac97_set_adc_rate - set codec rate adaption | ||
1373 | * @codec: ac97 code | ||
1374 | * @rate: rate in hertz | ||
1375 | * | ||
1376 | * Set the ADC rate. Assumes the codec supports VRA. The caller is | ||
1377 | * expected to have checked this little detail. | ||
1378 | */ | ||
1379 | |||
1380 | unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate) | ||
1381 | { | ||
1382 | unsigned int new_rate = rate; | ||
1383 | u32 dacp; | ||
1384 | |||
1385 | if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE)) | ||
1386 | { | ||
1387 | /* Power down the ADC */ | ||
1388 | dacp=codec->codec_read(codec, AC97_POWER_CONTROL); | ||
1389 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100); | ||
1390 | /* Load the rate and read the effective rate */ | ||
1391 | codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate); | ||
1392 | new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE); | ||
1393 | /* Power it back up */ | ||
1394 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp); | ||
1395 | } | ||
1396 | return new_rate; | ||
1397 | } | ||
1398 | |||
1399 | EXPORT_SYMBOL(ac97_set_adc_rate); | ||
1400 | |||
1401 | static int swap_headphone(int remove_master) | ||
1402 | { | ||
1403 | struct list_head *l; | ||
1404 | struct ac97_codec *c; | ||
1405 | |||
1406 | if (remove_master) { | ||
1407 | mutex_lock(&codec_mutex); | ||
1408 | list_for_each(l, &codecs) | ||
1409 | { | ||
1410 | c = list_entry(l, struct ac97_codec, list); | ||
1411 | if (supported_mixer(c, SOUND_MIXER_PHONEOUT)) | ||
1412 | c->supported_mixers &= ~SOUND_MASK_PHONEOUT; | ||
1413 | } | ||
1414 | mutex_unlock(&codec_mutex); | ||
1415 | } else | ||
1416 | ac97_hw[SOUND_MIXER_PHONEOUT].offset = AC97_MASTER_VOL_STEREO; | ||
1417 | |||
1418 | /* Scale values already match */ | ||
1419 | ac97_hw[SOUND_MIXER_VOLUME].offset = AC97_MASTER_VOL_MONO; | ||
1420 | return 0; | ||
1421 | } | ||
1422 | |||
1423 | static int apply_quirk(int quirk) | ||
1424 | { | ||
1425 | switch (quirk) { | ||
1426 | case AC97_TUNE_NONE: | ||
1427 | return 0; | ||
1428 | case AC97_TUNE_HP_ONLY: | ||
1429 | return swap_headphone(1); | ||
1430 | case AC97_TUNE_SWAP_HP: | ||
1431 | return swap_headphone(0); | ||
1432 | case AC97_TUNE_SWAP_SURROUND: | ||
1433 | return -ENOSYS; /* not yet implemented */ | ||
1434 | case AC97_TUNE_AD_SHARING: | ||
1435 | return -ENOSYS; /* not yet implemented */ | ||
1436 | case AC97_TUNE_ALC_JACK: | ||
1437 | return -ENOSYS; /* not yet implemented */ | ||
1438 | } | ||
1439 | return -EINVAL; | ||
1440 | } | ||
1441 | |||
1442 | /** | ||
1443 | * ac97_tune_hardware - tune up the hardware | ||
1444 | * @pdev: pci_dev pointer | ||
1445 | * @quirk: quirk list | ||
1446 | * @override: explicit quirk value (overrides if not AC97_TUNE_DEFAULT) | ||
1447 | * | ||
1448 | * Do some workaround for each pci device, such as renaming of the | ||
1449 | * headphone (true line-out) control as "Master". | ||
1450 | * The quirk-list must be terminated with a zero-filled entry. | ||
1451 | * | ||
1452 | * Returns zero if successful, or a negative error code on failure. | ||
1453 | */ | ||
1454 | |||
1455 | int ac97_tune_hardware(struct pci_dev *pdev, struct ac97_quirk *quirk, int override) | ||
1456 | { | ||
1457 | int result; | ||
1458 | |||
1459 | if (!quirk) | ||
1460 | return -EINVAL; | ||
1461 | |||
1462 | if (override != AC97_TUNE_DEFAULT) { | ||
1463 | result = apply_quirk(override); | ||
1464 | if (result < 0) | ||
1465 | printk(KERN_ERR "applying quirk type %d failed (%d)\n", override, result); | ||
1466 | return result; | ||
1467 | } | ||
1468 | |||
1469 | for (; quirk->vendor; quirk++) { | ||
1470 | if (quirk->vendor != pdev->subsystem_vendor) | ||
1471 | continue; | ||
1472 | if ((! quirk->mask && quirk->device == pdev->subsystem_device) || | ||
1473 | quirk->device == (quirk->mask & pdev->subsystem_device)) { | ||
1474 | #ifdef DEBUG | ||
1475 | printk("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, pdev->subsystem_device); | ||
1476 | #endif | ||
1477 | result = apply_quirk(quirk->type); | ||
1478 | if (result < 0) | ||
1479 | printk(KERN_ERR "applying quirk type %d for %s failed (%d)\n", quirk->type, quirk->name, result); | ||
1480 | return result; | ||
1481 | } | ||
1482 | } | ||
1483 | return 0; | ||
1484 | } | ||
1485 | |||
1486 | EXPORT_SYMBOL_GPL(ac97_tune_hardware); | ||
1487 | |||
1488 | MODULE_LICENSE("GPL"); | ||