diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-07-04 09:48:04 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-07-04 09:48:04 -0400 |
commit | bd450dcc357646cc277c560ab24b35f940efa585 (patch) | |
tree | 4d6dff989de63465f92434798679b028d35e658f /sound/pci/hda/patch_analog.c | |
parent | 5ccc618fee67f0f0b2122dd4b32a02fd2b6a1569 (diff) |
ALSA: hda - Remove static quirks for AD1981 and AD1983 codecs
These are relatively easy ones, as we already converted all static
quirks to the generic parser.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 684 |
1 files changed, 2 insertions, 682 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index bfa8f532841d..4fedd9dfd85a 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -1427,161 +1427,6 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1427 | * AD1983 specific | 1427 | * AD1983 specific |
1428 | */ | 1428 | */ |
1429 | 1429 | ||
1430 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1431 | #define AD1983_SPDIF_OUT 0x02 | ||
1432 | #define AD1983_DAC 0x03 | ||
1433 | #define AD1983_ADC 0x04 | ||
1434 | |||
1435 | static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; | ||
1436 | static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; | ||
1437 | static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; | ||
1438 | |||
1439 | static const struct hda_input_mux ad1983_capture_source = { | ||
1440 | .num_items = 4, | ||
1441 | .items = { | ||
1442 | { "Mic", 0x0 }, | ||
1443 | { "Line", 0x1 }, | ||
1444 | { "Mix", 0x2 }, | ||
1445 | { "Mix Mono", 0x3 }, | ||
1446 | }, | ||
1447 | }; | ||
1448 | |||
1449 | /* | ||
1450 | * SPDIF playback route | ||
1451 | */ | ||
1452 | static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
1453 | { | ||
1454 | static const char * const texts[] = { "PCM", "ADC" }; | ||
1455 | |||
1456 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1457 | uinfo->count = 1; | ||
1458 | uinfo->value.enumerated.items = 2; | ||
1459 | if (uinfo->value.enumerated.item > 1) | ||
1460 | uinfo->value.enumerated.item = 1; | ||
1461 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1462 | return 0; | ||
1463 | } | ||
1464 | |||
1465 | static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1466 | { | ||
1467 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1468 | struct ad198x_spec *spec = codec->spec; | ||
1469 | |||
1470 | ucontrol->value.enumerated.item[0] = spec->spdif_route; | ||
1471 | return 0; | ||
1472 | } | ||
1473 | |||
1474 | static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1475 | { | ||
1476 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1477 | struct ad198x_spec *spec = codec->spec; | ||
1478 | |||
1479 | if (ucontrol->value.enumerated.item[0] > 1) | ||
1480 | return -EINVAL; | ||
1481 | if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { | ||
1482 | spec->spdif_route = ucontrol->value.enumerated.item[0]; | ||
1483 | snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0, | ||
1484 | AC_VERB_SET_CONNECT_SEL, | ||
1485 | spec->spdif_route); | ||
1486 | return 1; | ||
1487 | } | ||
1488 | return 0; | ||
1489 | } | ||
1490 | |||
1491 | static const struct snd_kcontrol_new ad1983_mixers[] = { | ||
1492 | HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), | ||
1493 | HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), | ||
1494 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), | ||
1495 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
1496 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), | ||
1497 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), | ||
1498 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), | ||
1499 | HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
1500 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), | ||
1501 | HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
1502 | HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
1503 | HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
1504 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1505 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), | ||
1506 | HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), | ||
1507 | { | ||
1508 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1509 | .name = "Capture Source", | ||
1510 | .info = ad198x_mux_enum_info, | ||
1511 | .get = ad198x_mux_enum_get, | ||
1512 | .put = ad198x_mux_enum_put, | ||
1513 | }, | ||
1514 | { | ||
1515 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1516 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", | ||
1517 | .info = ad1983_spdif_route_info, | ||
1518 | .get = ad1983_spdif_route_get, | ||
1519 | .put = ad1983_spdif_route_put, | ||
1520 | }, | ||
1521 | { } /* end */ | ||
1522 | }; | ||
1523 | |||
1524 | static const struct hda_verb ad1983_init_verbs[] = { | ||
1525 | /* Front, HP, Mono; mute as default */ | ||
1526 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1527 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1528 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1529 | /* Beep, PCM, Mic, Line-In: mute */ | ||
1530 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1531 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1532 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1533 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1534 | /* Front, HP selectors; from Mix */ | ||
1535 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1536 | {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1537 | /* Mono selector; from Mix */ | ||
1538 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
1539 | /* Mic selector; Mic */ | ||
1540 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1541 | /* Line-in selector: Line-in */ | ||
1542 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1543 | /* Mic boost: 0dB */ | ||
1544 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
1545 | /* Record selector: mic */ | ||
1546 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1547 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1548 | /* SPDIF route: PCM */ | ||
1549 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1550 | /* Front Pin */ | ||
1551 | {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
1552 | /* HP Pin */ | ||
1553 | {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | ||
1554 | /* Mono Pin */ | ||
1555 | {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
1556 | /* Mic Pin */ | ||
1557 | {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
1558 | /* Line Pin */ | ||
1559 | {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
1560 | { } /* end */ | ||
1561 | }; | ||
1562 | |||
1563 | #ifdef CONFIG_PM | ||
1564 | static const struct hda_amp_list ad1983_loopbacks[] = { | ||
1565 | { 0x12, HDA_OUTPUT, 0 }, /* Mic */ | ||
1566 | { 0x13, HDA_OUTPUT, 0 }, /* Line */ | ||
1567 | { } /* end */ | ||
1568 | }; | ||
1569 | #endif | ||
1570 | |||
1571 | /* models */ | ||
1572 | enum { | ||
1573 | AD1983_AUTO, | ||
1574 | AD1983_BASIC, | ||
1575 | AD1983_MODELS | ||
1576 | }; | ||
1577 | |||
1578 | static const char * const ad1983_models[AD1983_MODELS] = { | ||
1579 | [AD1983_AUTO] = "auto", | ||
1580 | [AD1983_BASIC] = "basic", | ||
1581 | }; | ||
1582 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
1583 | |||
1584 | |||
1585 | /* | 1430 | /* |
1586 | * SPDIF mux control for AD1983 auto-parser | 1431 | * SPDIF mux control for AD1983 auto-parser |
1587 | */ | 1432 | */ |
@@ -1656,7 +1501,7 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec) | |||
1656 | return 0; | 1501 | return 0; |
1657 | } | 1502 | } |
1658 | 1503 | ||
1659 | static int ad1983_parse_auto_config(struct hda_codec *codec) | 1504 | static int patch_ad1983(struct hda_codec *codec) |
1660 | { | 1505 | { |
1661 | struct ad198x_spec *spec; | 1506 | struct ad198x_spec *spec; |
1662 | int err; | 1507 | int err; |
@@ -1681,432 +1526,11 @@ static int ad1983_parse_auto_config(struct hda_codec *codec) | |||
1681 | return err; | 1526 | return err; |
1682 | } | 1527 | } |
1683 | 1528 | ||
1684 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1685 | static int patch_ad1983(struct hda_codec *codec) | ||
1686 | { | ||
1687 | struct ad198x_spec *spec; | ||
1688 | int board_config; | ||
1689 | int err; | ||
1690 | |||
1691 | board_config = snd_hda_check_board_config(codec, AD1983_MODELS, | ||
1692 | ad1983_models, NULL); | ||
1693 | if (board_config < 0) { | ||
1694 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
1695 | codec->chip_name); | ||
1696 | board_config = AD1983_AUTO; | ||
1697 | } | ||
1698 | |||
1699 | if (board_config == AD1983_AUTO) | ||
1700 | return ad1983_parse_auto_config(codec); | ||
1701 | |||
1702 | err = alloc_ad_spec(codec); | ||
1703 | if (err < 0) | ||
1704 | return err; | ||
1705 | spec = codec->spec; | ||
1706 | |||
1707 | err = snd_hda_attach_beep_device(codec, 0x10); | ||
1708 | if (err < 0) { | ||
1709 | ad198x_free(codec); | ||
1710 | return err; | ||
1711 | } | ||
1712 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | ||
1713 | |||
1714 | spec->multiout.max_channels = 2; | ||
1715 | spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); | ||
1716 | spec->multiout.dac_nids = ad1983_dac_nids; | ||
1717 | spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; | ||
1718 | spec->num_adc_nids = 1; | ||
1719 | spec->adc_nids = ad1983_adc_nids; | ||
1720 | spec->capsrc_nids = ad1983_capsrc_nids; | ||
1721 | spec->input_mux = &ad1983_capture_source; | ||
1722 | spec->num_mixers = 1; | ||
1723 | spec->mixers[0] = ad1983_mixers; | ||
1724 | spec->num_init_verbs = 1; | ||
1725 | spec->init_verbs[0] = ad1983_init_verbs; | ||
1726 | spec->spdif_route = 0; | ||
1727 | #ifdef CONFIG_PM | ||
1728 | spec->loopback.amplist = ad1983_loopbacks; | ||
1729 | #endif | ||
1730 | spec->vmaster_nid = 0x05; | ||
1731 | |||
1732 | codec->patch_ops = ad198x_patch_ops; | ||
1733 | |||
1734 | codec->no_trigger_sense = 1; | ||
1735 | codec->no_sticky_stream = 1; | ||
1736 | |||
1737 | return 0; | ||
1738 | } | ||
1739 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
1740 | #define patch_ad1983 ad1983_parse_auto_config | ||
1741 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
1742 | |||
1743 | 1529 | ||
1744 | /* | 1530 | /* |
1745 | * AD1981 HD specific | 1531 | * AD1981 HD specific |
1746 | */ | 1532 | */ |
1747 | 1533 | ||
1748 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
1749 | #define AD1981_SPDIF_OUT 0x02 | ||
1750 | #define AD1981_DAC 0x03 | ||
1751 | #define AD1981_ADC 0x04 | ||
1752 | |||
1753 | static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; | ||
1754 | static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; | ||
1755 | static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; | ||
1756 | |||
1757 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ | ||
1758 | static const struct hda_input_mux ad1981_capture_source = { | ||
1759 | .num_items = 7, | ||
1760 | .items = { | ||
1761 | { "Front Mic", 0x0 }, | ||
1762 | { "Line", 0x1 }, | ||
1763 | { "Mix", 0x2 }, | ||
1764 | { "Mix Mono", 0x3 }, | ||
1765 | { "CD", 0x4 }, | ||
1766 | { "Mic", 0x6 }, | ||
1767 | { "Aux", 0x7 }, | ||
1768 | }, | ||
1769 | }; | ||
1770 | |||
1771 | static const struct snd_kcontrol_new ad1981_mixers[] = { | ||
1772 | HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), | ||
1773 | HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), | ||
1774 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), | ||
1775 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
1776 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), | ||
1777 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), | ||
1778 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), | ||
1779 | HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
1780 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), | ||
1781 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
1782 | HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
1783 | HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
1784 | HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
1785 | HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
1786 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), | ||
1787 | HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), | ||
1788 | HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | ||
1789 | HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), | ||
1790 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT), | ||
1791 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT), | ||
1792 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), | ||
1793 | HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), | ||
1794 | { | ||
1795 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1796 | .name = "Capture Source", | ||
1797 | .info = ad198x_mux_enum_info, | ||
1798 | .get = ad198x_mux_enum_get, | ||
1799 | .put = ad198x_mux_enum_put, | ||
1800 | }, | ||
1801 | /* identical with AD1983 */ | ||
1802 | { | ||
1803 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1804 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", | ||
1805 | .info = ad1983_spdif_route_info, | ||
1806 | .get = ad1983_spdif_route_get, | ||
1807 | .put = ad1983_spdif_route_put, | ||
1808 | }, | ||
1809 | { } /* end */ | ||
1810 | }; | ||
1811 | |||
1812 | static const struct hda_verb ad1981_init_verbs[] = { | ||
1813 | /* Front, HP, Mono; mute as default */ | ||
1814 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1815 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1816 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1817 | /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */ | ||
1818 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1819 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1820 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1821 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1822 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1823 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1824 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1825 | /* Front, HP selectors; from Mix */ | ||
1826 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1827 | {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1828 | /* Mono selector; from Mix */ | ||
1829 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
1830 | /* Mic Mixer; select Front Mic */ | ||
1831 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
1832 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1833 | /* Mic boost: 0dB */ | ||
1834 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1835 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1836 | /* Record selector: Front mic */ | ||
1837 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1838 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1839 | /* SPDIF route: PCM */ | ||
1840 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
1841 | /* Front Pin */ | ||
1842 | {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
1843 | /* HP Pin */ | ||
1844 | {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | ||
1845 | /* Mono Pin */ | ||
1846 | {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
1847 | /* Front & Rear Mic Pins */ | ||
1848 | {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
1849 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
1850 | /* Line Pin */ | ||
1851 | {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
1852 | /* Digital Beep */ | ||
1853 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1854 | /* Line-Out as Input: disabled */ | ||
1855 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1856 | { } /* end */ | ||
1857 | }; | ||
1858 | |||
1859 | #ifdef CONFIG_PM | ||
1860 | static const struct hda_amp_list ad1981_loopbacks[] = { | ||
1861 | { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ | ||
1862 | { 0x13, HDA_OUTPUT, 0 }, /* Line */ | ||
1863 | { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ | ||
1864 | { 0x1c, HDA_OUTPUT, 0 }, /* Mic */ | ||
1865 | { 0x1d, HDA_OUTPUT, 0 }, /* CD */ | ||
1866 | { } /* end */ | ||
1867 | }; | ||
1868 | #endif | ||
1869 | |||
1870 | /* | ||
1871 | * Patch for HP nx6320 | ||
1872 | * | ||
1873 | * nx6320 uses EAPD in the reverse way - EAPD-on means the internal | ||
1874 | * speaker output enabled _and_ mute-LED off. | ||
1875 | */ | ||
1876 | |||
1877 | #define AD1981_HP_EVENT 0x37 | ||
1878 | #define AD1981_MIC_EVENT 0x38 | ||
1879 | |||
1880 | static const struct hda_verb ad1981_hp_init_verbs[] = { | ||
1881 | {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ | ||
1882 | /* pin sensing on HP and Mic jacks */ | ||
1883 | {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, | ||
1884 | {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, | ||
1885 | {} | ||
1886 | }; | ||
1887 | |||
1888 | /* turn on/off EAPD (+ mute HP) as a master switch */ | ||
1889 | static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, | ||
1890 | struct snd_ctl_elem_value *ucontrol) | ||
1891 | { | ||
1892 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1893 | struct ad198x_spec *spec = codec->spec; | ||
1894 | |||
1895 | if (! ad198x_eapd_put(kcontrol, ucontrol)) | ||
1896 | return 0; | ||
1897 | /* change speaker pin appropriately */ | ||
1898 | snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0); | ||
1899 | /* toggle HP mute appropriately */ | ||
1900 | snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0, | ||
1901 | HDA_AMP_MUTE, | ||
1902 | spec->cur_eapd ? 0 : HDA_AMP_MUTE); | ||
1903 | return 1; | ||
1904 | } | ||
1905 | |||
1906 | /* bind volumes of both NID 0x05 and 0x06 */ | ||
1907 | static const struct hda_bind_ctls ad1981_hp_bind_master_vol = { | ||
1908 | .ops = &snd_hda_bind_vol, | ||
1909 | .values = { | ||
1910 | HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), | ||
1911 | HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT), | ||
1912 | 0 | ||
1913 | }, | ||
1914 | }; | ||
1915 | |||
1916 | /* mute internal speaker if HP is plugged */ | ||
1917 | static void ad1981_hp_automute(struct hda_codec *codec) | ||
1918 | { | ||
1919 | unsigned int present; | ||
1920 | |||
1921 | present = snd_hda_jack_detect(codec, 0x06); | ||
1922 | snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0, | ||
1923 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
1924 | } | ||
1925 | |||
1926 | /* toggle input of built-in and mic jack appropriately */ | ||
1927 | static void ad1981_hp_automic(struct hda_codec *codec) | ||
1928 | { | ||
1929 | static const struct hda_verb mic_jack_on[] = { | ||
1930 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1931 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
1932 | {} | ||
1933 | }; | ||
1934 | static const struct hda_verb mic_jack_off[] = { | ||
1935 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1936 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
1937 | {} | ||
1938 | }; | ||
1939 | unsigned int present; | ||
1940 | |||
1941 | present = snd_hda_jack_detect(codec, 0x08); | ||
1942 | if (present) | ||
1943 | snd_hda_sequence_write(codec, mic_jack_on); | ||
1944 | else | ||
1945 | snd_hda_sequence_write(codec, mic_jack_off); | ||
1946 | } | ||
1947 | |||
1948 | /* unsolicited event for HP jack sensing */ | ||
1949 | static void ad1981_hp_unsol_event(struct hda_codec *codec, | ||
1950 | unsigned int res) | ||
1951 | { | ||
1952 | res >>= 26; | ||
1953 | switch (res) { | ||
1954 | case AD1981_HP_EVENT: | ||
1955 | ad1981_hp_automute(codec); | ||
1956 | break; | ||
1957 | case AD1981_MIC_EVENT: | ||
1958 | ad1981_hp_automic(codec); | ||
1959 | break; | ||
1960 | } | ||
1961 | } | ||
1962 | |||
1963 | static const struct hda_input_mux ad1981_hp_capture_source = { | ||
1964 | .num_items = 3, | ||
1965 | .items = { | ||
1966 | { "Mic", 0x0 }, | ||
1967 | { "Dock Mic", 0x1 }, | ||
1968 | { "Mix", 0x2 }, | ||
1969 | }, | ||
1970 | }; | ||
1971 | |||
1972 | static const struct snd_kcontrol_new ad1981_hp_mixers[] = { | ||
1973 | HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), | ||
1974 | { | ||
1975 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1976 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x05, | ||
1977 | .name = "Master Playback Switch", | ||
1978 | .info = ad198x_eapd_info, | ||
1979 | .get = ad198x_eapd_get, | ||
1980 | .put = ad1981_hp_master_sw_put, | ||
1981 | .private_value = 0x05, | ||
1982 | }, | ||
1983 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), | ||
1984 | HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
1985 | #if 0 | ||
1986 | /* FIXME: analog mic/line loopback doesn't work with my tests... | ||
1987 | * (although recording is OK) | ||
1988 | */ | ||
1989 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), | ||
1990 | HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
1991 | HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
1992 | HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
1993 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), | ||
1994 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), | ||
1995 | /* FIXME: does this laptop have analog CD connection? */ | ||
1996 | HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | ||
1997 | HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), | ||
1998 | #endif | ||
1999 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), | ||
2000 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT), | ||
2001 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), | ||
2002 | HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), | ||
2003 | { | ||
2004 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2005 | .name = "Capture Source", | ||
2006 | .info = ad198x_mux_enum_info, | ||
2007 | .get = ad198x_mux_enum_get, | ||
2008 | .put = ad198x_mux_enum_put, | ||
2009 | }, | ||
2010 | { } /* end */ | ||
2011 | }; | ||
2012 | |||
2013 | /* initialize jack-sensing, too */ | ||
2014 | static int ad1981_hp_init(struct hda_codec *codec) | ||
2015 | { | ||
2016 | ad198x_init(codec); | ||
2017 | ad1981_hp_automute(codec); | ||
2018 | ad1981_hp_automic(codec); | ||
2019 | return 0; | ||
2020 | } | ||
2021 | |||
2022 | /* configuration for Toshiba Laptops */ | ||
2023 | static const struct hda_verb ad1981_toshiba_init_verbs[] = { | ||
2024 | {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ | ||
2025 | /* pin sensing on HP and Mic jacks */ | ||
2026 | {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, | ||
2027 | {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, | ||
2028 | {} | ||
2029 | }; | ||
2030 | |||
2031 | static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = { | ||
2032 | HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), | ||
2033 | HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), | ||
2034 | { } | ||
2035 | }; | ||
2036 | |||
2037 | /* configuration for Lenovo Thinkpad T60 */ | ||
2038 | static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { | ||
2039 | HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), | ||
2040 | HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), | ||
2041 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), | ||
2042 | HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
2043 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), | ||
2044 | HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
2045 | HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | ||
2046 | HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), | ||
2047 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), | ||
2048 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), | ||
2049 | HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), | ||
2050 | { | ||
2051 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2052 | .name = "Capture Source", | ||
2053 | .info = ad198x_mux_enum_info, | ||
2054 | .get = ad198x_mux_enum_get, | ||
2055 | .put = ad198x_mux_enum_put, | ||
2056 | }, | ||
2057 | /* identical with AD1983 */ | ||
2058 | { | ||
2059 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2060 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", | ||
2061 | .info = ad1983_spdif_route_info, | ||
2062 | .get = ad1983_spdif_route_get, | ||
2063 | .put = ad1983_spdif_route_put, | ||
2064 | }, | ||
2065 | { } /* end */ | ||
2066 | }; | ||
2067 | |||
2068 | static const struct hda_input_mux ad1981_thinkpad_capture_source = { | ||
2069 | .num_items = 3, | ||
2070 | .items = { | ||
2071 | { "Mic", 0x0 }, | ||
2072 | { "Mix", 0x2 }, | ||
2073 | { "CD", 0x4 }, | ||
2074 | }, | ||
2075 | }; | ||
2076 | |||
2077 | /* models */ | ||
2078 | enum { | ||
2079 | AD1981_AUTO, | ||
2080 | AD1981_BASIC, | ||
2081 | AD1981_HP, | ||
2082 | AD1981_THINKPAD, | ||
2083 | AD1981_TOSHIBA, | ||
2084 | AD1981_MODELS | ||
2085 | }; | ||
2086 | |||
2087 | static const char * const ad1981_models[AD1981_MODELS] = { | ||
2088 | [AD1981_AUTO] = "auto", | ||
2089 | [AD1981_HP] = "hp", | ||
2090 | [AD1981_THINKPAD] = "thinkpad", | ||
2091 | [AD1981_BASIC] = "basic", | ||
2092 | [AD1981_TOSHIBA] = "toshiba" | ||
2093 | }; | ||
2094 | |||
2095 | static const struct snd_pci_quirk ad1981_cfg_tbl[] = { | ||
2096 | SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), | ||
2097 | SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), | ||
2098 | /* All HP models */ | ||
2099 | SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP), | ||
2100 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), | ||
2101 | /* Lenovo Thinkpad T60/X60/Z6xx */ | ||
2102 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD), | ||
2103 | /* HP nx6320 (reversed SSID, H/W bug) */ | ||
2104 | SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP), | ||
2105 | {} | ||
2106 | }; | ||
2107 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
2108 | |||
2109 | |||
2110 | /* follow EAPD via vmaster hook */ | 1534 | /* follow EAPD via vmaster hook */ |
2111 | static void ad_vmaster_eapd_hook(void *private_data, int enabled) | 1535 | static void ad_vmaster_eapd_hook(void *private_data, int enabled) |
2112 | { | 1536 | { |
@@ -2172,7 +1596,7 @@ static const struct snd_pci_quirk ad1981_fixup_tbl[] = { | |||
2172 | {} | 1596 | {} |
2173 | }; | 1597 | }; |
2174 | 1598 | ||
2175 | static int ad1981_parse_auto_config(struct hda_codec *codec) | 1599 | static int patch_ad1981(struct hda_codec *codec) |
2176 | { | 1600 | { |
2177 | struct ad198x_spec *spec; | 1601 | struct ad198x_spec *spec; |
2178 | int err; | 1602 | int err; |
@@ -2205,110 +1629,6 @@ static int ad1981_parse_auto_config(struct hda_codec *codec) | |||
2205 | return err; | 1629 | return err; |
2206 | } | 1630 | } |
2207 | 1631 | ||
2208 | #ifdef ENABLE_AD_STATIC_QUIRKS | ||
2209 | static int patch_ad1981(struct hda_codec *codec) | ||
2210 | { | ||
2211 | struct ad198x_spec *spec; | ||
2212 | int err, board_config; | ||
2213 | |||
2214 | board_config = snd_hda_check_board_config(codec, AD1981_MODELS, | ||
2215 | ad1981_models, | ||
2216 | ad1981_cfg_tbl); | ||
2217 | if (board_config < 0) { | ||
2218 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
2219 | codec->chip_name); | ||
2220 | board_config = AD1981_AUTO; | ||
2221 | } | ||
2222 | |||
2223 | if (board_config == AD1981_AUTO) | ||
2224 | return ad1981_parse_auto_config(codec); | ||
2225 | |||
2226 | err = alloc_ad_spec(codec); | ||
2227 | if (err < 0) | ||
2228 | return -ENOMEM; | ||
2229 | spec = codec->spec; | ||
2230 | |||
2231 | err = snd_hda_attach_beep_device(codec, 0x10); | ||
2232 | if (err < 0) { | ||
2233 | ad198x_free(codec); | ||
2234 | return err; | ||
2235 | } | ||
2236 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); | ||
2237 | |||
2238 | spec->multiout.max_channels = 2; | ||
2239 | spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); | ||
2240 | spec->multiout.dac_nids = ad1981_dac_nids; | ||
2241 | spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; | ||
2242 | spec->num_adc_nids = 1; | ||
2243 | spec->adc_nids = ad1981_adc_nids; | ||
2244 | spec->capsrc_nids = ad1981_capsrc_nids; | ||
2245 | spec->input_mux = &ad1981_capture_source; | ||
2246 | spec->num_mixers = 1; | ||
2247 | spec->mixers[0] = ad1981_mixers; | ||
2248 | spec->num_init_verbs = 1; | ||
2249 | spec->init_verbs[0] = ad1981_init_verbs; | ||
2250 | spec->spdif_route = 0; | ||
2251 | #ifdef CONFIG_PM | ||
2252 | spec->loopback.amplist = ad1981_loopbacks; | ||
2253 | #endif | ||
2254 | spec->vmaster_nid = 0x05; | ||
2255 | |||
2256 | codec->patch_ops = ad198x_patch_ops; | ||
2257 | |||
2258 | /* override some parameters */ | ||
2259 | switch (board_config) { | ||
2260 | case AD1981_HP: | ||
2261 | spec->mixers[0] = ad1981_hp_mixers; | ||
2262 | spec->num_init_verbs = 2; | ||
2263 | spec->init_verbs[1] = ad1981_hp_init_verbs; | ||
2264 | if (!is_jack_available(codec, 0x0a)) | ||
2265 | spec->multiout.dig_out_nid = 0; | ||
2266 | spec->input_mux = &ad1981_hp_capture_source; | ||
2267 | |||
2268 | codec->patch_ops.init = ad1981_hp_init; | ||
2269 | codec->patch_ops.unsol_event = ad1981_hp_unsol_event; | ||
2270 | /* set the upper-limit for mixer amp to 0dB for avoiding the | ||
2271 | * possible damage by overloading | ||
2272 | */ | ||
2273 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, | ||
2274 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
2275 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
2276 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
2277 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
2278 | break; | ||
2279 | case AD1981_THINKPAD: | ||
2280 | spec->mixers[0] = ad1981_thinkpad_mixers; | ||
2281 | spec->input_mux = &ad1981_thinkpad_capture_source; | ||
2282 | /* set the upper-limit for mixer amp to 0dB for avoiding the | ||
2283 | * possible damage by overloading | ||
2284 | */ | ||
2285 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, | ||
2286 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
2287 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
2288 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
2289 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
2290 | break; | ||
2291 | case AD1981_TOSHIBA: | ||
2292 | spec->mixers[0] = ad1981_hp_mixers; | ||
2293 | spec->mixers[1] = ad1981_toshiba_mixers; | ||
2294 | spec->num_init_verbs = 2; | ||
2295 | spec->init_verbs[1] = ad1981_toshiba_init_verbs; | ||
2296 | spec->multiout.dig_out_nid = 0; | ||
2297 | spec->input_mux = &ad1981_hp_capture_source; | ||
2298 | codec->patch_ops.init = ad1981_hp_init; | ||
2299 | codec->patch_ops.unsol_event = ad1981_hp_unsol_event; | ||
2300 | break; | ||
2301 | } | ||
2302 | |||
2303 | codec->no_trigger_sense = 1; | ||
2304 | codec->no_sticky_stream = 1; | ||
2305 | |||
2306 | return 0; | ||
2307 | } | ||
2308 | #else /* ENABLE_AD_STATIC_QUIRKS */ | ||
2309 | #define patch_ad1981 ad1981_parse_auto_config | ||
2310 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | ||
2311 | |||
2312 | 1632 | ||
2313 | /* | 1633 | /* |
2314 | * AD1988 | 1634 | * AD1988 |