diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 949 |
1 files changed, 245 insertions, 704 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7a8fcc4c15f8..c556fe1c25eb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1255,6 +1255,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1255 | codec->addr = codec_addr; | 1255 | codec->addr = codec_addr; |
1256 | mutex_init(&codec->spdif_mutex); | 1256 | mutex_init(&codec->spdif_mutex); |
1257 | mutex_init(&codec->control_mutex); | 1257 | mutex_init(&codec->control_mutex); |
1258 | mutex_init(&codec->hash_mutex); | ||
1258 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | 1259 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); |
1259 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | 1260 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); |
1260 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); | 1261 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); |
@@ -1264,15 +1265,9 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1264 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); | 1265 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); |
1265 | snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); | 1266 | snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); |
1266 | snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); | 1267 | snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); |
1267 | if (codec->bus->modelname) { | ||
1268 | codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); | ||
1269 | if (!codec->modelname) { | ||
1270 | snd_hda_codec_free(codec); | ||
1271 | return -ENODEV; | ||
1272 | } | ||
1273 | } | ||
1274 | 1268 | ||
1275 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1269 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1270 | spin_lock_init(&codec->power_lock); | ||
1276 | INIT_DELAYED_WORK(&codec->power_work, hda_power_work); | 1271 | INIT_DELAYED_WORK(&codec->power_work, hda_power_work); |
1277 | /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. | 1272 | /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. |
1278 | * the caller has to power down appropriatley after initialization | 1273 | * the caller has to power down appropriatley after initialization |
@@ -1281,6 +1276,14 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1281 | hda_keep_power_on(codec); | 1276 | hda_keep_power_on(codec); |
1282 | #endif | 1277 | #endif |
1283 | 1278 | ||
1279 | if (codec->bus->modelname) { | ||
1280 | codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); | ||
1281 | if (!codec->modelname) { | ||
1282 | snd_hda_codec_free(codec); | ||
1283 | return -ENODEV; | ||
1284 | } | ||
1285 | } | ||
1286 | |||
1284 | list_add_tail(&codec->list, &bus->codec_list); | 1287 | list_add_tail(&codec->list, &bus->codec_list); |
1285 | bus->caddr_tbl[codec_addr] = codec; | 1288 | bus->caddr_tbl[codec_addr] = codec; |
1286 | 1289 | ||
@@ -1603,6 +1606,60 @@ get_alloc_amp_hash(struct hda_codec *codec, u32 key) | |||
1603 | return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key); | 1606 | return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key); |
1604 | } | 1607 | } |
1605 | 1608 | ||
1609 | /* overwrite the value with the key in the caps hash */ | ||
1610 | static int write_caps_hash(struct hda_codec *codec, u32 key, unsigned int val) | ||
1611 | { | ||
1612 | struct hda_amp_info *info; | ||
1613 | |||
1614 | mutex_lock(&codec->hash_mutex); | ||
1615 | info = get_alloc_amp_hash(codec, key); | ||
1616 | if (!info) { | ||
1617 | mutex_unlock(&codec->hash_mutex); | ||
1618 | return -EINVAL; | ||
1619 | } | ||
1620 | info->amp_caps = val; | ||
1621 | info->head.val |= INFO_AMP_CAPS; | ||
1622 | mutex_unlock(&codec->hash_mutex); | ||
1623 | return 0; | ||
1624 | } | ||
1625 | |||
1626 | /* query the value from the caps hash; if not found, fetch the current | ||
1627 | * value from the given function and store in the hash | ||
1628 | */ | ||
1629 | static unsigned int | ||
1630 | query_caps_hash(struct hda_codec *codec, hda_nid_t nid, int dir, u32 key, | ||
1631 | unsigned int (*func)(struct hda_codec *, hda_nid_t, int)) | ||
1632 | { | ||
1633 | struct hda_amp_info *info; | ||
1634 | unsigned int val; | ||
1635 | |||
1636 | mutex_lock(&codec->hash_mutex); | ||
1637 | info = get_alloc_amp_hash(codec, key); | ||
1638 | if (!info) { | ||
1639 | mutex_unlock(&codec->hash_mutex); | ||
1640 | return 0; | ||
1641 | } | ||
1642 | if (!(info->head.val & INFO_AMP_CAPS)) { | ||
1643 | mutex_unlock(&codec->hash_mutex); /* for reentrance */ | ||
1644 | val = func(codec, nid, dir); | ||
1645 | write_caps_hash(codec, key, val); | ||
1646 | } else { | ||
1647 | val = info->amp_caps; | ||
1648 | mutex_unlock(&codec->hash_mutex); | ||
1649 | } | ||
1650 | return val; | ||
1651 | } | ||
1652 | |||
1653 | static unsigned int read_amp_cap(struct hda_codec *codec, hda_nid_t nid, | ||
1654 | int direction) | ||
1655 | { | ||
1656 | if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) | ||
1657 | nid = codec->afg; | ||
1658 | return snd_hda_param_read(codec, nid, | ||
1659 | direction == HDA_OUTPUT ? | ||
1660 | AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); | ||
1661 | } | ||
1662 | |||
1606 | /** | 1663 | /** |
1607 | * query_amp_caps - query AMP capabilities | 1664 | * query_amp_caps - query AMP capabilities |
1608 | * @codec: the HD-auio codec | 1665 | * @codec: the HD-auio codec |
@@ -1617,22 +1674,9 @@ get_alloc_amp_hash(struct hda_codec *codec, u32 key) | |||
1617 | */ | 1674 | */ |
1618 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) | 1675 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) |
1619 | { | 1676 | { |
1620 | struct hda_amp_info *info; | 1677 | return query_caps_hash(codec, nid, direction, |
1621 | 1678 | HDA_HASH_KEY(nid, direction, 0), | |
1622 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); | 1679 | read_amp_cap); |
1623 | if (!info) | ||
1624 | return 0; | ||
1625 | if (!(info->head.val & INFO_AMP_CAPS)) { | ||
1626 | if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) | ||
1627 | nid = codec->afg; | ||
1628 | info->amp_caps = snd_hda_param_read(codec, nid, | ||
1629 | direction == HDA_OUTPUT ? | ||
1630 | AC_PAR_AMP_OUT_CAP : | ||
1631 | AC_PAR_AMP_IN_CAP); | ||
1632 | if (info->amp_caps) | ||
1633 | info->head.val |= INFO_AMP_CAPS; | ||
1634 | } | ||
1635 | return info->amp_caps; | ||
1636 | } | 1680 | } |
1637 | EXPORT_SYMBOL_HDA(query_amp_caps); | 1681 | EXPORT_SYMBOL_HDA(query_amp_caps); |
1638 | 1682 | ||
@@ -1652,34 +1696,12 @@ EXPORT_SYMBOL_HDA(query_amp_caps); | |||
1652 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 1696 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, |
1653 | unsigned int caps) | 1697 | unsigned int caps) |
1654 | { | 1698 | { |
1655 | struct hda_amp_info *info; | 1699 | return write_caps_hash(codec, HDA_HASH_KEY(nid, dir, 0), caps); |
1656 | |||
1657 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, dir, 0)); | ||
1658 | if (!info) | ||
1659 | return -EINVAL; | ||
1660 | info->amp_caps = caps; | ||
1661 | info->head.val |= INFO_AMP_CAPS; | ||
1662 | return 0; | ||
1663 | } | 1700 | } |
1664 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); | 1701 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); |
1665 | 1702 | ||
1666 | static unsigned int | 1703 | static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid, |
1667 | query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key, | 1704 | int dir) |
1668 | unsigned int (*func)(struct hda_codec *, hda_nid_t)) | ||
1669 | { | ||
1670 | struct hda_amp_info *info; | ||
1671 | |||
1672 | info = get_alloc_amp_hash(codec, key); | ||
1673 | if (!info) | ||
1674 | return 0; | ||
1675 | if (!info->head.val) { | ||
1676 | info->head.val |= INFO_AMP_CAPS; | ||
1677 | info->amp_caps = func(codec, nid); | ||
1678 | } | ||
1679 | return info->amp_caps; | ||
1680 | } | ||
1681 | |||
1682 | static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid) | ||
1683 | { | 1705 | { |
1684 | return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | 1706 | return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); |
1685 | } | 1707 | } |
@@ -1697,7 +1719,7 @@ static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid) | |||
1697 | */ | 1719 | */ |
1698 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) | 1720 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) |
1699 | { | 1721 | { |
1700 | return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid), | 1722 | return query_caps_hash(codec, nid, 0, HDA_HASH_PINCAP_KEY(nid), |
1701 | read_pin_cap); | 1723 | read_pin_cap); |
1702 | } | 1724 | } |
1703 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); | 1725 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); |
@@ -1715,41 +1737,47 @@ EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); | |||
1715 | int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, | 1737 | int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, |
1716 | unsigned int caps) | 1738 | unsigned int caps) |
1717 | { | 1739 | { |
1718 | struct hda_amp_info *info; | 1740 | return write_caps_hash(codec, HDA_HASH_PINCAP_KEY(nid), caps); |
1719 | info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid)); | ||
1720 | if (!info) | ||
1721 | return -ENOMEM; | ||
1722 | info->amp_caps = caps; | ||
1723 | info->head.val |= INFO_AMP_CAPS; | ||
1724 | return 0; | ||
1725 | } | 1741 | } |
1726 | EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); | 1742 | EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); |
1727 | 1743 | ||
1728 | /* | 1744 | /* read or sync the hash value with the current value; |
1729 | * read the current volume to info | 1745 | * call within hash_mutex |
1730 | * if the cache exists, read the cache value. | ||
1731 | */ | 1746 | */ |
1732 | static unsigned int get_vol_mute(struct hda_codec *codec, | 1747 | static struct hda_amp_info * |
1733 | struct hda_amp_info *info, hda_nid_t nid, | 1748 | update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, |
1734 | int ch, int direction, int index) | 1749 | int direction, int index) |
1735 | { | 1750 | { |
1736 | u32 val, parm; | 1751 | struct hda_amp_info *info; |
1737 | 1752 | unsigned int parm, val = 0; | |
1738 | if (info->head.val & INFO_AMP_VOL(ch)) | 1753 | bool val_read = false; |
1739 | return info->vol[ch]; | ||
1740 | 1754 | ||
1741 | parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; | 1755 | retry: |
1742 | parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; | 1756 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); |
1743 | parm |= index; | 1757 | if (!info) |
1744 | val = snd_hda_codec_read(codec, nid, 0, | 1758 | return NULL; |
1759 | if (!(info->head.val & INFO_AMP_VOL(ch))) { | ||
1760 | if (!val_read) { | ||
1761 | mutex_unlock(&codec->hash_mutex); | ||
1762 | parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; | ||
1763 | parm |= direction == HDA_OUTPUT ? | ||
1764 | AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; | ||
1765 | parm |= index; | ||
1766 | val = snd_hda_codec_read(codec, nid, 0, | ||
1745 | AC_VERB_GET_AMP_GAIN_MUTE, parm); | 1767 | AC_VERB_GET_AMP_GAIN_MUTE, parm); |
1746 | info->vol[ch] = val & 0xff; | 1768 | val &= 0xff; |
1747 | info->head.val |= INFO_AMP_VOL(ch); | 1769 | val_read = true; |
1748 | return info->vol[ch]; | 1770 | mutex_lock(&codec->hash_mutex); |
1771 | goto retry; | ||
1772 | } | ||
1773 | info->vol[ch] = val; | ||
1774 | info->head.val |= INFO_AMP_VOL(ch); | ||
1775 | } | ||
1776 | return info; | ||
1749 | } | 1777 | } |
1750 | 1778 | ||
1751 | /* | 1779 | /* |
1752 | * write the current volume in info to the h/w and update the cache | 1780 | * write the current volume in info to the h/w |
1753 | */ | 1781 | */ |
1754 | static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | 1782 | static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, |
1755 | hda_nid_t nid, int ch, int direction, int index, | 1783 | hda_nid_t nid, int ch, int direction, int index, |
@@ -1766,7 +1794,6 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | |||
1766 | else | 1794 | else |
1767 | parm |= val; | 1795 | parm |= val; |
1768 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); | 1796 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); |
1769 | info->vol[ch] = val; | ||
1770 | } | 1797 | } |
1771 | 1798 | ||
1772 | /** | 1799 | /** |
@@ -1783,10 +1810,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1783 | int direction, int index) | 1810 | int direction, int index) |
1784 | { | 1811 | { |
1785 | struct hda_amp_info *info; | 1812 | struct hda_amp_info *info; |
1786 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); | 1813 | unsigned int val = 0; |
1787 | if (!info) | 1814 | |
1788 | return 0; | 1815 | mutex_lock(&codec->hash_mutex); |
1789 | return get_vol_mute(codec, info, nid, ch, direction, index); | 1816 | info = update_amp_hash(codec, nid, ch, direction, index); |
1817 | if (info) | ||
1818 | val = info->vol[ch]; | ||
1819 | mutex_unlock(&codec->hash_mutex); | ||
1820 | return val; | ||
1790 | } | 1821 | } |
1791 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); | 1822 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); |
1792 | 1823 | ||
@@ -1808,15 +1839,23 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1808 | { | 1839 | { |
1809 | struct hda_amp_info *info; | 1840 | struct hda_amp_info *info; |
1810 | 1841 | ||
1811 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); | ||
1812 | if (!info) | ||
1813 | return 0; | ||
1814 | if (snd_BUG_ON(mask & ~0xff)) | 1842 | if (snd_BUG_ON(mask & ~0xff)) |
1815 | mask &= 0xff; | 1843 | mask &= 0xff; |
1816 | val &= mask; | 1844 | val &= mask; |
1817 | val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; | 1845 | |
1818 | if (info->vol[ch] == val) | 1846 | mutex_lock(&codec->hash_mutex); |
1847 | info = update_amp_hash(codec, nid, ch, direction, idx); | ||
1848 | if (!info) { | ||
1849 | mutex_unlock(&codec->hash_mutex); | ||
1850 | return 0; | ||
1851 | } | ||
1852 | val |= info->vol[ch] & ~mask; | ||
1853 | if (info->vol[ch] == val) { | ||
1854 | mutex_unlock(&codec->hash_mutex); | ||
1819 | return 0; | 1855 | return 0; |
1856 | } | ||
1857 | info->vol[ch] = val; | ||
1858 | mutex_unlock(&codec->hash_mutex); | ||
1820 | put_vol_mute(codec, info, nid, ch, direction, idx, val); | 1859 | put_vol_mute(codec, info, nid, ch, direction, idx, val); |
1821 | return 1; | 1860 | return 1; |
1822 | } | 1861 | } |
@@ -2263,7 +2302,10 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2263 | /* OK, let it free */ | 2302 | /* OK, let it free */ |
2264 | 2303 | ||
2265 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2304 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2266 | cancel_delayed_work(&codec->power_work); | 2305 | cancel_delayed_work_sync(&codec->power_work); |
2306 | codec->power_on = 0; | ||
2307 | codec->power_transition = 0; | ||
2308 | codec->power_jiffies = jiffies; | ||
2267 | flush_workqueue(codec->bus->workq); | 2309 | flush_workqueue(codec->bus->workq); |
2268 | #endif | 2310 | #endif |
2269 | snd_hda_ctls_clear(codec); | 2311 | snd_hda_ctls_clear(codec); |
@@ -2859,12 +2901,15 @@ static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, | |||
2859 | { | 2901 | { |
2860 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2902 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2861 | int idx = kcontrol->private_value; | 2903 | int idx = kcontrol->private_value; |
2862 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 2904 | struct hda_spdif_out *spdif; |
2863 | 2905 | ||
2906 | mutex_lock(&codec->spdif_mutex); | ||
2907 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
2864 | ucontrol->value.iec958.status[0] = spdif->status & 0xff; | 2908 | ucontrol->value.iec958.status[0] = spdif->status & 0xff; |
2865 | ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff; | 2909 | ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff; |
2866 | ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff; | 2910 | ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff; |
2867 | ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff; | 2911 | ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff; |
2912 | mutex_unlock(&codec->spdif_mutex); | ||
2868 | 2913 | ||
2869 | return 0; | 2914 | return 0; |
2870 | } | 2915 | } |
@@ -2950,12 +2995,14 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
2950 | { | 2995 | { |
2951 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2996 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2952 | int idx = kcontrol->private_value; | 2997 | int idx = kcontrol->private_value; |
2953 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 2998 | struct hda_spdif_out *spdif; |
2954 | hda_nid_t nid = spdif->nid; | 2999 | hda_nid_t nid; |
2955 | unsigned short val; | 3000 | unsigned short val; |
2956 | int change; | 3001 | int change; |
2957 | 3002 | ||
2958 | mutex_lock(&codec->spdif_mutex); | 3003 | mutex_lock(&codec->spdif_mutex); |
3004 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
3005 | nid = spdif->nid; | ||
2959 | spdif->status = ucontrol->value.iec958.status[0] | | 3006 | spdif->status = ucontrol->value.iec958.status[0] | |
2960 | ((unsigned int)ucontrol->value.iec958.status[1] << 8) | | 3007 | ((unsigned int)ucontrol->value.iec958.status[1] << 8) | |
2961 | ((unsigned int)ucontrol->value.iec958.status[2] << 16) | | 3008 | ((unsigned int)ucontrol->value.iec958.status[2] << 16) | |
@@ -2977,9 +3024,12 @@ static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, | |||
2977 | { | 3024 | { |
2978 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 3025 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2979 | int idx = kcontrol->private_value; | 3026 | int idx = kcontrol->private_value; |
2980 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3027 | struct hda_spdif_out *spdif; |
2981 | 3028 | ||
3029 | mutex_lock(&codec->spdif_mutex); | ||
3030 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
2982 | ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE; | 3031 | ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE; |
3032 | mutex_unlock(&codec->spdif_mutex); | ||
2983 | return 0; | 3033 | return 0; |
2984 | } | 3034 | } |
2985 | 3035 | ||
@@ -2999,12 +3049,14 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, | |||
2999 | { | 3049 | { |
3000 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 3050 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
3001 | int idx = kcontrol->private_value; | 3051 | int idx = kcontrol->private_value; |
3002 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3052 | struct hda_spdif_out *spdif; |
3003 | hda_nid_t nid = spdif->nid; | 3053 | hda_nid_t nid; |
3004 | unsigned short val; | 3054 | unsigned short val; |
3005 | int change; | 3055 | int change; |
3006 | 3056 | ||
3007 | mutex_lock(&codec->spdif_mutex); | 3057 | mutex_lock(&codec->spdif_mutex); |
3058 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
3059 | nid = spdif->nid; | ||
3008 | val = spdif->ctls & ~AC_DIG1_ENABLE; | 3060 | val = spdif->ctls & ~AC_DIG1_ENABLE; |
3009 | if (ucontrol->value.integer.value[0]) | 3061 | if (ucontrol->value.integer.value[0]) |
3010 | val |= AC_DIG1_ENABLE; | 3062 | val |= AC_DIG1_ENABLE; |
@@ -3092,6 +3144,9 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, | |||
3092 | } | 3144 | } |
3093 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); | 3145 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); |
3094 | 3146 | ||
3147 | /* get the hda_spdif_out entry from the given NID | ||
3148 | * call within spdif_mutex lock | ||
3149 | */ | ||
3095 | struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, | 3150 | struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, |
3096 | hda_nid_t nid) | 3151 | hda_nid_t nid) |
3097 | { | 3152 | { |
@@ -3108,9 +3163,10 @@ EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid); | |||
3108 | 3163 | ||
3109 | void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) | 3164 | void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) |
3110 | { | 3165 | { |
3111 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3166 | struct hda_spdif_out *spdif; |
3112 | 3167 | ||
3113 | mutex_lock(&codec->spdif_mutex); | 3168 | mutex_lock(&codec->spdif_mutex); |
3169 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
3114 | spdif->nid = (u16)-1; | 3170 | spdif->nid = (u16)-1; |
3115 | mutex_unlock(&codec->spdif_mutex); | 3171 | mutex_unlock(&codec->spdif_mutex); |
3116 | } | 3172 | } |
@@ -3118,10 +3174,11 @@ EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_unassign); | |||
3118 | 3174 | ||
3119 | void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) | 3175 | void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) |
3120 | { | 3176 | { |
3121 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3177 | struct hda_spdif_out *spdif; |
3122 | unsigned short val; | 3178 | unsigned short val; |
3123 | 3179 | ||
3124 | mutex_lock(&codec->spdif_mutex); | 3180 | mutex_lock(&codec->spdif_mutex); |
3181 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
3125 | if (spdif->nid != nid) { | 3182 | if (spdif->nid != nid) { |
3126 | spdif->nid = nid; | 3183 | spdif->nid = nid; |
3127 | val = spdif->ctls; | 3184 | val = spdif->ctls; |
@@ -3486,11 +3543,14 @@ static void hda_call_codec_suspend(struct hda_codec *codec) | |||
3486 | codec->afg ? codec->afg : codec->mfg, | 3543 | codec->afg ? codec->afg : codec->mfg, |
3487 | AC_PWRST_D3); | 3544 | AC_PWRST_D3); |
3488 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3545 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3489 | snd_hda_update_power_acct(codec); | ||
3490 | cancel_delayed_work(&codec->power_work); | 3546 | cancel_delayed_work(&codec->power_work); |
3547 | spin_lock(&codec->power_lock); | ||
3548 | snd_hda_update_power_acct(codec); | ||
3549 | trace_hda_power_down(codec); | ||
3491 | codec->power_on = 0; | 3550 | codec->power_on = 0; |
3492 | codec->power_transition = 0; | 3551 | codec->power_transition = 0; |
3493 | codec->power_jiffies = jiffies; | 3552 | codec->power_jiffies = jiffies; |
3553 | spin_unlock(&codec->power_lock); | ||
3494 | #endif | 3554 | #endif |
3495 | } | 3555 | } |
3496 | 3556 | ||
@@ -3499,6 +3559,10 @@ static void hda_call_codec_suspend(struct hda_codec *codec) | |||
3499 | */ | 3559 | */ |
3500 | static void hda_call_codec_resume(struct hda_codec *codec) | 3560 | static void hda_call_codec_resume(struct hda_codec *codec) |
3501 | { | 3561 | { |
3562 | /* set as if powered on for avoiding re-entering the resume | ||
3563 | * in the resume / power-save sequence | ||
3564 | */ | ||
3565 | hda_keep_power_on(codec); | ||
3502 | hda_set_power_state(codec, | 3566 | hda_set_power_state(codec, |
3503 | codec->afg ? codec->afg : codec->mfg, | 3567 | codec->afg ? codec->afg : codec->mfg, |
3504 | AC_PWRST_D0); | 3568 | AC_PWRST_D0); |
@@ -3514,6 +3578,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
3514 | snd_hda_codec_resume_amp(codec); | 3578 | snd_hda_codec_resume_amp(codec); |
3515 | snd_hda_codec_resume_cache(codec); | 3579 | snd_hda_codec_resume_cache(codec); |
3516 | } | 3580 | } |
3581 | snd_hda_power_down(codec); /* flag down before returning */ | ||
3517 | } | 3582 | } |
3518 | #endif /* CONFIG_PM */ | 3583 | #endif /* CONFIG_PM */ |
3519 | 3584 | ||
@@ -3665,7 +3730,8 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
3665 | } | 3730 | } |
3666 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); | 3731 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); |
3667 | 3732 | ||
3668 | static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid) | 3733 | static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid, |
3734 | int dir) | ||
3669 | { | 3735 | { |
3670 | unsigned int val = 0; | 3736 | unsigned int val = 0; |
3671 | if (nid != codec->afg && | 3737 | if (nid != codec->afg && |
@@ -3680,11 +3746,12 @@ static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid) | |||
3680 | 3746 | ||
3681 | static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) | 3747 | static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) |
3682 | { | 3748 | { |
3683 | return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid), | 3749 | return query_caps_hash(codec, nid, 0, HDA_HASH_PARPCM_KEY(nid), |
3684 | get_pcm_param); | 3750 | get_pcm_param); |
3685 | } | 3751 | } |
3686 | 3752 | ||
3687 | static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid) | 3753 | static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid, |
3754 | int dir) | ||
3688 | { | 3755 | { |
3689 | unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 3756 | unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); |
3690 | if (!streams || streams == -1) | 3757 | if (!streams || streams == -1) |
@@ -3696,7 +3763,7 @@ static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid) | |||
3696 | 3763 | ||
3697 | static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) | 3764 | static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) |
3698 | { | 3765 | { |
3699 | return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid), | 3766 | return query_caps_hash(codec, nid, 0, HDA_HASH_PARSTR_KEY(nid), |
3700 | get_stream_param); | 3767 | get_stream_param); |
3701 | } | 3768 | } |
3702 | 3769 | ||
@@ -3775,11 +3842,13 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
3775 | bps = 20; | 3842 | bps = 20; |
3776 | } | 3843 | } |
3777 | } | 3844 | } |
3845 | #if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */ | ||
3778 | if (streams & AC_SUPFMT_FLOAT32) { | 3846 | if (streams & AC_SUPFMT_FLOAT32) { |
3779 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; | 3847 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; |
3780 | if (!bps) | 3848 | if (!bps) |
3781 | bps = 32; | 3849 | bps = 32; |
3782 | } | 3850 | } |
3851 | #endif | ||
3783 | if (streams == AC_SUPFMT_AC3) { | 3852 | if (streams == AC_SUPFMT_AC3) { |
3784 | /* should be exclusive */ | 3853 | /* should be exclusive */ |
3785 | /* temporary hack: we have still no proper support | 3854 | /* temporary hack: we have still no proper support |
@@ -4283,12 +4352,18 @@ static void hda_power_work(struct work_struct *work) | |||
4283 | container_of(work, struct hda_codec, power_work.work); | 4352 | container_of(work, struct hda_codec, power_work.work); |
4284 | struct hda_bus *bus = codec->bus; | 4353 | struct hda_bus *bus = codec->bus; |
4285 | 4354 | ||
4355 | spin_lock(&codec->power_lock); | ||
4356 | if (codec->power_transition > 0) { /* during power-up sequence? */ | ||
4357 | spin_unlock(&codec->power_lock); | ||
4358 | return; | ||
4359 | } | ||
4286 | if (!codec->power_on || codec->power_count) { | 4360 | if (!codec->power_on || codec->power_count) { |
4287 | codec->power_transition = 0; | 4361 | codec->power_transition = 0; |
4362 | spin_unlock(&codec->power_lock); | ||
4288 | return; | 4363 | return; |
4289 | } | 4364 | } |
4365 | spin_unlock(&codec->power_lock); | ||
4290 | 4366 | ||
4291 | trace_hda_power_down(codec); | ||
4292 | hda_call_codec_suspend(codec); | 4367 | hda_call_codec_suspend(codec); |
4293 | if (bus->ops.pm_notify) | 4368 | if (bus->ops.pm_notify) |
4294 | bus->ops.pm_notify(bus); | 4369 | bus->ops.pm_notify(bus); |
@@ -4296,9 +4371,11 @@ static void hda_power_work(struct work_struct *work) | |||
4296 | 4371 | ||
4297 | static void hda_keep_power_on(struct hda_codec *codec) | 4372 | static void hda_keep_power_on(struct hda_codec *codec) |
4298 | { | 4373 | { |
4374 | spin_lock(&codec->power_lock); | ||
4299 | codec->power_count++; | 4375 | codec->power_count++; |
4300 | codec->power_on = 1; | 4376 | codec->power_on = 1; |
4301 | codec->power_jiffies = jiffies; | 4377 | codec->power_jiffies = jiffies; |
4378 | spin_unlock(&codec->power_lock); | ||
4302 | } | 4379 | } |
4303 | 4380 | ||
4304 | /* update the power on/off account with the current jiffies */ | 4381 | /* update the power on/off account with the current jiffies */ |
@@ -4323,19 +4400,31 @@ void snd_hda_power_up(struct hda_codec *codec) | |||
4323 | { | 4400 | { |
4324 | struct hda_bus *bus = codec->bus; | 4401 | struct hda_bus *bus = codec->bus; |
4325 | 4402 | ||
4403 | spin_lock(&codec->power_lock); | ||
4326 | codec->power_count++; | 4404 | codec->power_count++; |
4327 | if (codec->power_on || codec->power_transition) | 4405 | if (codec->power_on || codec->power_transition > 0) { |
4406 | spin_unlock(&codec->power_lock); | ||
4328 | return; | 4407 | return; |
4408 | } | ||
4409 | spin_unlock(&codec->power_lock); | ||
4329 | 4410 | ||
4411 | cancel_delayed_work_sync(&codec->power_work); | ||
4412 | |||
4413 | spin_lock(&codec->power_lock); | ||
4330 | trace_hda_power_up(codec); | 4414 | trace_hda_power_up(codec); |
4331 | snd_hda_update_power_acct(codec); | 4415 | snd_hda_update_power_acct(codec); |
4332 | codec->power_on = 1; | 4416 | codec->power_on = 1; |
4333 | codec->power_jiffies = jiffies; | 4417 | codec->power_jiffies = jiffies; |
4418 | codec->power_transition = 1; /* avoid reentrance */ | ||
4419 | spin_unlock(&codec->power_lock); | ||
4420 | |||
4334 | if (bus->ops.pm_notify) | 4421 | if (bus->ops.pm_notify) |
4335 | bus->ops.pm_notify(bus); | 4422 | bus->ops.pm_notify(bus); |
4336 | hda_call_codec_resume(codec); | 4423 | hda_call_codec_resume(codec); |
4337 | cancel_delayed_work(&codec->power_work); | 4424 | |
4425 | spin_lock(&codec->power_lock); | ||
4338 | codec->power_transition = 0; | 4426 | codec->power_transition = 0; |
4427 | spin_unlock(&codec->power_lock); | ||
4339 | } | 4428 | } |
4340 | EXPORT_SYMBOL_HDA(snd_hda_power_up); | 4429 | EXPORT_SYMBOL_HDA(snd_hda_power_up); |
4341 | 4430 | ||
@@ -4351,14 +4440,18 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up); | |||
4351 | */ | 4440 | */ |
4352 | void snd_hda_power_down(struct hda_codec *codec) | 4441 | void snd_hda_power_down(struct hda_codec *codec) |
4353 | { | 4442 | { |
4443 | spin_lock(&codec->power_lock); | ||
4354 | --codec->power_count; | 4444 | --codec->power_count; |
4355 | if (!codec->power_on || codec->power_count || codec->power_transition) | 4445 | if (!codec->power_on || codec->power_count || codec->power_transition) { |
4446 | spin_unlock(&codec->power_lock); | ||
4356 | return; | 4447 | return; |
4448 | } | ||
4357 | if (power_save(codec)) { | 4449 | if (power_save(codec)) { |
4358 | codec->power_transition = 1; /* avoid reentrance */ | 4450 | codec->power_transition = -1; /* avoid reentrance */ |
4359 | queue_delayed_work(codec->bus->workq, &codec->power_work, | 4451 | queue_delayed_work(codec->bus->workq, &codec->power_work, |
4360 | msecs_to_jiffies(power_save(codec) * 1000)); | 4452 | msecs_to_jiffies(power_save(codec) * 1000)); |
4361 | } | 4453 | } |
4454 | spin_unlock(&codec->power_lock); | ||
4362 | } | 4455 | } |
4363 | EXPORT_SYMBOL_HDA(snd_hda_power_down); | 4456 | EXPORT_SYMBOL_HDA(snd_hda_power_down); |
4364 | 4457 | ||
@@ -4710,11 +4803,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, | |||
4710 | { | 4803 | { |
4711 | const hda_nid_t *nids = mout->dac_nids; | 4804 | const hda_nid_t *nids = mout->dac_nids; |
4712 | int chs = substream->runtime->channels; | 4805 | int chs = substream->runtime->channels; |
4713 | struct hda_spdif_out *spdif = | 4806 | struct hda_spdif_out *spdif; |
4714 | snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid); | ||
4715 | int i; | 4807 | int i; |
4716 | 4808 | ||
4717 | mutex_lock(&codec->spdif_mutex); | 4809 | mutex_lock(&codec->spdif_mutex); |
4810 | spdif = snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid); | ||
4718 | if (mout->dig_out_nid && mout->share_spdif && | 4811 | if (mout->dig_out_nid && mout->share_spdif && |
4719 | mout->dig_out_used != HDA_DIG_EXCLUSIVE) { | 4812 | mout->dig_out_used != HDA_DIG_EXCLUSIVE) { |
4720 | if (chs == 2 && | 4813 | if (chs == 2 && |
@@ -4795,601 +4888,58 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, | |||
4795 | } | 4888 | } |
4796 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); | 4889 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); |
4797 | 4890 | ||
4798 | /* | ||
4799 | * Helper for automatic pin configuration | ||
4800 | */ | ||
4801 | |||
4802 | static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list) | ||
4803 | { | ||
4804 | for (; *list; list++) | ||
4805 | if (*list == nid) | ||
4806 | return 1; | ||
4807 | return 0; | ||
4808 | } | ||
4809 | |||
4810 | |||
4811 | /* | ||
4812 | * Sort an associated group of pins according to their sequence numbers. | ||
4813 | */ | ||
4814 | static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences, | ||
4815 | int num_pins) | ||
4816 | { | ||
4817 | int i, j; | ||
4818 | short seq; | ||
4819 | hda_nid_t nid; | ||
4820 | |||
4821 | for (i = 0; i < num_pins; i++) { | ||
4822 | for (j = i + 1; j < num_pins; j++) { | ||
4823 | if (sequences[i] > sequences[j]) { | ||
4824 | seq = sequences[i]; | ||
4825 | sequences[i] = sequences[j]; | ||
4826 | sequences[j] = seq; | ||
4827 | nid = pins[i]; | ||
4828 | pins[i] = pins[j]; | ||
4829 | pins[j] = nid; | ||
4830 | } | ||
4831 | } | ||
4832 | } | ||
4833 | } | ||
4834 | |||
4835 | |||
4836 | /* add the found input-pin to the cfg->inputs[] table */ | ||
4837 | static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid, | ||
4838 | int type) | ||
4839 | { | ||
4840 | if (cfg->num_inputs < AUTO_CFG_MAX_INS) { | ||
4841 | cfg->inputs[cfg->num_inputs].pin = nid; | ||
4842 | cfg->inputs[cfg->num_inputs].type = type; | ||
4843 | cfg->num_inputs++; | ||
4844 | } | ||
4845 | } | ||
4846 | |||
4847 | /* sort inputs in the order of AUTO_PIN_* type */ | ||
4848 | static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) | ||
4849 | { | ||
4850 | int i, j; | ||
4851 | |||
4852 | for (i = 0; i < cfg->num_inputs; i++) { | ||
4853 | for (j = i + 1; j < cfg->num_inputs; j++) { | ||
4854 | if (cfg->inputs[i].type > cfg->inputs[j].type) { | ||
4855 | struct auto_pin_cfg_item tmp; | ||
4856 | tmp = cfg->inputs[i]; | ||
4857 | cfg->inputs[i] = cfg->inputs[j]; | ||
4858 | cfg->inputs[j] = tmp; | ||
4859 | } | ||
4860 | } | ||
4861 | } | ||
4862 | } | ||
4863 | |||
4864 | /* Reorder the surround channels | ||
4865 | * ALSA sequence is front/surr/clfe/side | ||
4866 | * HDA sequence is: | ||
4867 | * 4-ch: front/surr => OK as it is | ||
4868 | * 6-ch: front/clfe/surr | ||
4869 | * 8-ch: front/clfe/rear/side|fc | ||
4870 | */ | ||
4871 | static void reorder_outputs(unsigned int nums, hda_nid_t *pins) | ||
4872 | { | ||
4873 | hda_nid_t nid; | ||
4874 | |||
4875 | switch (nums) { | ||
4876 | case 3: | ||
4877 | case 4: | ||
4878 | nid = pins[1]; | ||
4879 | pins[1] = pins[2]; | ||
4880 | pins[2] = nid; | ||
4881 | break; | ||
4882 | } | ||
4883 | } | ||
4884 | |||
4885 | /* | ||
4886 | * Parse all pin widgets and store the useful pin nids to cfg | ||
4887 | * | ||
4888 | * The number of line-outs or any primary output is stored in line_outs, | ||
4889 | * and the corresponding output pins are assigned to line_out_pins[], | ||
4890 | * in the order of front, rear, CLFE, side, ... | ||
4891 | * | ||
4892 | * If more extra outputs (speaker and headphone) are found, the pins are | ||
4893 | * assisnged to hp_pins[] and speaker_pins[], respectively. If no line-out jack | ||
4894 | * is detected, one of speaker of HP pins is assigned as the primary | ||
4895 | * output, i.e. to line_out_pins[0]. So, line_outs is always positive | ||
4896 | * if any analog output exists. | ||
4897 | * | ||
4898 | * The analog input pins are assigned to inputs array. | ||
4899 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, | ||
4900 | * respectively. | ||
4901 | */ | ||
4902 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | ||
4903 | struct auto_pin_cfg *cfg, | ||
4904 | const hda_nid_t *ignore_nids, | ||
4905 | unsigned int cond_flags) | ||
4906 | { | ||
4907 | hda_nid_t nid, end_nid; | ||
4908 | short seq, assoc_line_out; | ||
4909 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; | ||
4910 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; | ||
4911 | short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; | ||
4912 | int i; | ||
4913 | |||
4914 | memset(cfg, 0, sizeof(*cfg)); | ||
4915 | |||
4916 | memset(sequences_line_out, 0, sizeof(sequences_line_out)); | ||
4917 | memset(sequences_speaker, 0, sizeof(sequences_speaker)); | ||
4918 | memset(sequences_hp, 0, sizeof(sequences_hp)); | ||
4919 | assoc_line_out = 0; | ||
4920 | |||
4921 | codec->ignore_misc_bit = true; | ||
4922 | end_nid = codec->start_nid + codec->num_nodes; | ||
4923 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
4924 | unsigned int wid_caps = get_wcaps(codec, nid); | ||
4925 | unsigned int wid_type = get_wcaps_type(wid_caps); | ||
4926 | unsigned int def_conf; | ||
4927 | short assoc, loc, conn, dev; | ||
4928 | |||
4929 | /* read all default configuration for pin complex */ | ||
4930 | if (wid_type != AC_WID_PIN) | ||
4931 | continue; | ||
4932 | /* ignore the given nids (e.g. pc-beep returns error) */ | ||
4933 | if (ignore_nids && is_in_nid_list(nid, ignore_nids)) | ||
4934 | continue; | ||
4935 | |||
4936 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
4937 | if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
4938 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
4939 | codec->ignore_misc_bit = false; | ||
4940 | conn = get_defcfg_connect(def_conf); | ||
4941 | if (conn == AC_JACK_PORT_NONE) | ||
4942 | continue; | ||
4943 | loc = get_defcfg_location(def_conf); | ||
4944 | dev = get_defcfg_device(def_conf); | ||
4945 | |||
4946 | /* workaround for buggy BIOS setups */ | ||
4947 | if (dev == AC_JACK_LINE_OUT) { | ||
4948 | if (conn == AC_JACK_PORT_FIXED) | ||
4949 | dev = AC_JACK_SPEAKER; | ||
4950 | } | ||
4951 | |||
4952 | switch (dev) { | ||
4953 | case AC_JACK_LINE_OUT: | ||
4954 | seq = get_defcfg_sequence(def_conf); | ||
4955 | assoc = get_defcfg_association(def_conf); | ||
4956 | |||
4957 | if (!(wid_caps & AC_WCAP_STEREO)) | ||
4958 | if (!cfg->mono_out_pin) | ||
4959 | cfg->mono_out_pin = nid; | ||
4960 | if (!assoc) | ||
4961 | continue; | ||
4962 | if (!assoc_line_out) | ||
4963 | assoc_line_out = assoc; | ||
4964 | else if (assoc_line_out != assoc) | ||
4965 | continue; | ||
4966 | if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) | ||
4967 | continue; | ||
4968 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
4969 | sequences_line_out[cfg->line_outs] = seq; | ||
4970 | cfg->line_outs++; | ||
4971 | break; | ||
4972 | case AC_JACK_SPEAKER: | ||
4973 | seq = get_defcfg_sequence(def_conf); | ||
4974 | assoc = get_defcfg_association(def_conf); | ||
4975 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) | ||
4976 | continue; | ||
4977 | cfg->speaker_pins[cfg->speaker_outs] = nid; | ||
4978 | sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq; | ||
4979 | cfg->speaker_outs++; | ||
4980 | break; | ||
4981 | case AC_JACK_HP_OUT: | ||
4982 | seq = get_defcfg_sequence(def_conf); | ||
4983 | assoc = get_defcfg_association(def_conf); | ||
4984 | if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins)) | ||
4985 | continue; | ||
4986 | cfg->hp_pins[cfg->hp_outs] = nid; | ||
4987 | sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; | ||
4988 | cfg->hp_outs++; | ||
4989 | break; | ||
4990 | case AC_JACK_MIC_IN: | ||
4991 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC); | ||
4992 | break; | ||
4993 | case AC_JACK_LINE_IN: | ||
4994 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN); | ||
4995 | break; | ||
4996 | case AC_JACK_CD: | ||
4997 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD); | ||
4998 | break; | ||
4999 | case AC_JACK_AUX: | ||
5000 | add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX); | ||
5001 | break; | ||
5002 | case AC_JACK_SPDIF_OUT: | ||
5003 | case AC_JACK_DIG_OTHER_OUT: | ||
5004 | if (cfg->dig_outs >= ARRAY_SIZE(cfg->dig_out_pins)) | ||
5005 | continue; | ||
5006 | cfg->dig_out_pins[cfg->dig_outs] = nid; | ||
5007 | cfg->dig_out_type[cfg->dig_outs] = | ||
5008 | (loc == AC_JACK_LOC_HDMI) ? | ||
5009 | HDA_PCM_TYPE_HDMI : HDA_PCM_TYPE_SPDIF; | ||
5010 | cfg->dig_outs++; | ||
5011 | break; | ||
5012 | case AC_JACK_SPDIF_IN: | ||
5013 | case AC_JACK_DIG_OTHER_IN: | ||
5014 | cfg->dig_in_pin = nid; | ||
5015 | if (loc == AC_JACK_LOC_HDMI) | ||
5016 | cfg->dig_in_type = HDA_PCM_TYPE_HDMI; | ||
5017 | else | ||
5018 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; | ||
5019 | break; | ||
5020 | } | ||
5021 | } | ||
5022 | |||
5023 | /* FIX-UP: | ||
5024 | * If no line-out is defined but multiple HPs are found, | ||
5025 | * some of them might be the real line-outs. | ||
5026 | */ | ||
5027 | if (!cfg->line_outs && cfg->hp_outs > 1 && | ||
5028 | !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) { | ||
5029 | int i = 0; | ||
5030 | while (i < cfg->hp_outs) { | ||
5031 | /* The real HPs should have the sequence 0x0f */ | ||
5032 | if ((sequences_hp[i] & 0x0f) == 0x0f) { | ||
5033 | i++; | ||
5034 | continue; | ||
5035 | } | ||
5036 | /* Move it to the line-out table */ | ||
5037 | cfg->line_out_pins[cfg->line_outs] = cfg->hp_pins[i]; | ||
5038 | sequences_line_out[cfg->line_outs] = sequences_hp[i]; | ||
5039 | cfg->line_outs++; | ||
5040 | cfg->hp_outs--; | ||
5041 | memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, | ||
5042 | sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); | ||
5043 | memmove(sequences_hp + i, sequences_hp + i + 1, | ||
5044 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); | ||
5045 | } | ||
5046 | memset(cfg->hp_pins + cfg->hp_outs, 0, | ||
5047 | sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs)); | ||
5048 | if (!cfg->hp_outs) | ||
5049 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
5050 | |||
5051 | } | ||
5052 | |||
5053 | /* sort by sequence */ | ||
5054 | sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out, | ||
5055 | cfg->line_outs); | ||
5056 | sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, | ||
5057 | cfg->speaker_outs); | ||
5058 | sort_pins_by_sequence(cfg->hp_pins, sequences_hp, | ||
5059 | cfg->hp_outs); | ||
5060 | |||
5061 | /* | ||
5062 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin | ||
5063 | * as a primary output | ||
5064 | */ | ||
5065 | if (!cfg->line_outs && | ||
5066 | !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) { | ||
5067 | if (cfg->speaker_outs) { | ||
5068 | cfg->line_outs = cfg->speaker_outs; | ||
5069 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
5070 | sizeof(cfg->speaker_pins)); | ||
5071 | cfg->speaker_outs = 0; | ||
5072 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
5073 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
5074 | } else if (cfg->hp_outs) { | ||
5075 | cfg->line_outs = cfg->hp_outs; | ||
5076 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
5077 | sizeof(cfg->hp_pins)); | ||
5078 | cfg->hp_outs = 0; | ||
5079 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
5080 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
5081 | } | ||
5082 | } | ||
5083 | |||
5084 | reorder_outputs(cfg->line_outs, cfg->line_out_pins); | ||
5085 | reorder_outputs(cfg->hp_outs, cfg->hp_pins); | ||
5086 | reorder_outputs(cfg->speaker_outs, cfg->speaker_pins); | ||
5087 | |||
5088 | sort_autocfg_input_pins(cfg); | ||
5089 | |||
5090 | /* | ||
5091 | * debug prints of the parsed results | ||
5092 | */ | ||
5093 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", | ||
5094 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], | ||
5095 | cfg->line_out_pins[2], cfg->line_out_pins[3], | ||
5096 | cfg->line_out_pins[4], | ||
5097 | cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : | ||
5098 | (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? | ||
5099 | "speaker" : "line")); | ||
5100 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
5101 | cfg->speaker_outs, cfg->speaker_pins[0], | ||
5102 | cfg->speaker_pins[1], cfg->speaker_pins[2], | ||
5103 | cfg->speaker_pins[3], cfg->speaker_pins[4]); | ||
5104 | snd_printd(" hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
5105 | cfg->hp_outs, cfg->hp_pins[0], | ||
5106 | cfg->hp_pins[1], cfg->hp_pins[2], | ||
5107 | cfg->hp_pins[3], cfg->hp_pins[4]); | ||
5108 | snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin); | ||
5109 | if (cfg->dig_outs) | ||
5110 | snd_printd(" dig-out=0x%x/0x%x\n", | ||
5111 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); | ||
5112 | snd_printd(" inputs:"); | ||
5113 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5114 | snd_printd(" %s=0x%x", | ||
5115 | hda_get_autocfg_input_label(codec, cfg, i), | ||
5116 | cfg->inputs[i].pin); | ||
5117 | } | ||
5118 | snd_printd("\n"); | ||
5119 | if (cfg->dig_in_pin) | ||
5120 | snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); | ||
5121 | |||
5122 | return 0; | ||
5123 | } | ||
5124 | EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg); | ||
5125 | |||
5126 | int snd_hda_get_input_pin_attr(unsigned int def_conf) | ||
5127 | { | ||
5128 | unsigned int loc = get_defcfg_location(def_conf); | ||
5129 | unsigned int conn = get_defcfg_connect(def_conf); | ||
5130 | if (conn == AC_JACK_PORT_NONE) | ||
5131 | return INPUT_PIN_ATTR_UNUSED; | ||
5132 | /* Windows may claim the internal mic to be BOTH, too */ | ||
5133 | if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH) | ||
5134 | return INPUT_PIN_ATTR_INT; | ||
5135 | if ((loc & 0x30) == AC_JACK_LOC_INTERNAL) | ||
5136 | return INPUT_PIN_ATTR_INT; | ||
5137 | if ((loc & 0x30) == AC_JACK_LOC_SEPARATE) | ||
5138 | return INPUT_PIN_ATTR_DOCK; | ||
5139 | if (loc == AC_JACK_LOC_REAR) | ||
5140 | return INPUT_PIN_ATTR_REAR; | ||
5141 | if (loc == AC_JACK_LOC_FRONT) | ||
5142 | return INPUT_PIN_ATTR_FRONT; | ||
5143 | return INPUT_PIN_ATTR_NORMAL; | ||
5144 | } | ||
5145 | EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); | ||
5146 | |||
5147 | /** | 4891 | /** |
5148 | * hda_get_input_pin_label - Give a label for the given input pin | 4892 | * snd_hda_get_default_vref - Get the default (mic) VREF pin bits |
5149 | * | 4893 | * |
5150 | * When check_location is true, the function checks the pin location | 4894 | * Guess the suitable VREF pin bits to be set as the pin-control value. |
5151 | * for mic and line-in pins, and set an appropriate prefix like "Front", | 4895 | * Note: the function doesn't set the AC_PINCTL_IN_EN bit. |
5152 | * "Rear", "Internal". | 4896 | */ |
5153 | */ | 4897 | unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin) |
5154 | 4898 | { | |
5155 | static const char *hda_get_input_pin_label(struct hda_codec *codec, | 4899 | unsigned int pincap; |
5156 | hda_nid_t pin, bool check_location) | 4900 | unsigned int oldval; |
5157 | { | 4901 | oldval = snd_hda_codec_read(codec, pin, 0, |
5158 | unsigned int def_conf; | 4902 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
5159 | static const char * const mic_names[] = { | 4903 | pincap = snd_hda_query_pin_caps(codec, pin); |
5160 | "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", | 4904 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
5161 | }; | 4905 | /* Exception: if the default pin setup is vref50, we give it priority */ |
5162 | int attr; | 4906 | if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) |
5163 | 4907 | return AC_PINCTL_VREF_80; | |
5164 | def_conf = snd_hda_codec_get_pincfg(codec, pin); | 4908 | else if (pincap & AC_PINCAP_VREF_50) |
5165 | 4909 | return AC_PINCTL_VREF_50; | |
5166 | switch (get_defcfg_device(def_conf)) { | 4910 | else if (pincap & AC_PINCAP_VREF_100) |
5167 | case AC_JACK_MIC_IN: | 4911 | return AC_PINCTL_VREF_100; |
5168 | if (!check_location) | 4912 | else if (pincap & AC_PINCAP_VREF_GRD) |
5169 | return "Mic"; | 4913 | return AC_PINCTL_VREF_GRD; |
5170 | attr = snd_hda_get_input_pin_attr(def_conf); | 4914 | return AC_PINCTL_VREF_HIZ; |
5171 | if (!attr) | 4915 | } |
5172 | return "None"; | 4916 | EXPORT_SYMBOL_HDA(snd_hda_get_default_vref); |
5173 | return mic_names[attr - 1]; | 4917 | |
5174 | case AC_JACK_LINE_IN: | 4918 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, |
5175 | if (!check_location) | 4919 | unsigned int val, bool cached) |
5176 | return "Line"; | 4920 | { |
5177 | attr = snd_hda_get_input_pin_attr(def_conf); | 4921 | if (val) { |
5178 | if (!attr) | 4922 | unsigned int cap = snd_hda_query_pin_caps(codec, pin); |
5179 | return "None"; | 4923 | if (cap && (val & AC_PINCTL_OUT_EN)) { |
5180 | if (attr == INPUT_PIN_ATTR_DOCK) | 4924 | if (!(cap & AC_PINCAP_OUT)) |
5181 | return "Dock Line"; | 4925 | val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); |
5182 | return "Line"; | 4926 | else if ((val & AC_PINCTL_HP_EN) && |
5183 | case AC_JACK_AUX: | 4927 | !(cap & AC_PINCAP_HP_DRV)) |
5184 | return "Aux"; | 4928 | val &= ~AC_PINCTL_HP_EN; |
5185 | case AC_JACK_CD: | ||
5186 | return "CD"; | ||
5187 | case AC_JACK_SPDIF_IN: | ||
5188 | return "SPDIF In"; | ||
5189 | case AC_JACK_DIG_OTHER_IN: | ||
5190 | return "Digital In"; | ||
5191 | default: | ||
5192 | return "Misc"; | ||
5193 | } | ||
5194 | } | ||
5195 | |||
5196 | /* Check whether the location prefix needs to be added to the label. | ||
5197 | * If all mic-jacks are in the same location (e.g. rear panel), we don't | ||
5198 | * have to put "Front" prefix to each label. In such a case, returns false. | ||
5199 | */ | ||
5200 | static int check_mic_location_need(struct hda_codec *codec, | ||
5201 | const struct auto_pin_cfg *cfg, | ||
5202 | int input) | ||
5203 | { | ||
5204 | unsigned int defc; | ||
5205 | int i, attr, attr2; | ||
5206 | |||
5207 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin); | ||
5208 | attr = snd_hda_get_input_pin_attr(defc); | ||
5209 | /* for internal or docking mics, we need locations */ | ||
5210 | if (attr <= INPUT_PIN_ATTR_NORMAL) | ||
5211 | return 1; | ||
5212 | |||
5213 | attr = 0; | ||
5214 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5215 | defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin); | ||
5216 | attr2 = snd_hda_get_input_pin_attr(defc); | ||
5217 | if (attr2 >= INPUT_PIN_ATTR_NORMAL) { | ||
5218 | if (attr && attr != attr2) | ||
5219 | return 1; /* different locations found */ | ||
5220 | attr = attr2; | ||
5221 | } | 4929 | } |
5222 | } | 4930 | if (cap && (val & AC_PINCTL_IN_EN)) { |
5223 | return 0; | 4931 | if (!(cap & AC_PINCAP_IN)) |
5224 | } | 4932 | val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN); |
5225 | |||
5226 | /** | ||
5227 | * hda_get_autocfg_input_label - Get a label for the given input | ||
5228 | * | ||
5229 | * Get a label for the given input pin defined by the autocfg item. | ||
5230 | * Unlike hda_get_input_pin_label(), this function checks all inputs | ||
5231 | * defined in autocfg and avoids the redundant mic/line prefix as much as | ||
5232 | * possible. | ||
5233 | */ | ||
5234 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | ||
5235 | const struct auto_pin_cfg *cfg, | ||
5236 | int input) | ||
5237 | { | ||
5238 | int type = cfg->inputs[input].type; | ||
5239 | int has_multiple_pins = 0; | ||
5240 | |||
5241 | if ((input > 0 && cfg->inputs[input - 1].type == type) || | ||
5242 | (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type)) | ||
5243 | has_multiple_pins = 1; | ||
5244 | if (has_multiple_pins && type == AUTO_PIN_MIC) | ||
5245 | has_multiple_pins &= check_mic_location_need(codec, cfg, input); | ||
5246 | return hda_get_input_pin_label(codec, cfg->inputs[input].pin, | ||
5247 | has_multiple_pins); | ||
5248 | } | ||
5249 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | ||
5250 | |||
5251 | /* return the position of NID in the list, or -1 if not found */ | ||
5252 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
5253 | { | ||
5254 | int i; | ||
5255 | for (i = 0; i < nums; i++) | ||
5256 | if (list[i] == nid) | ||
5257 | return i; | ||
5258 | return -1; | ||
5259 | } | ||
5260 | |||
5261 | /* get a unique suffix or an index number */ | ||
5262 | static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, | ||
5263 | int num_pins, int *indexp) | ||
5264 | { | ||
5265 | static const char * const channel_sfx[] = { | ||
5266 | " Front", " Surround", " CLFE", " Side" | ||
5267 | }; | ||
5268 | int i; | ||
5269 | |||
5270 | i = find_idx_in_nid_list(nid, pins, num_pins); | ||
5271 | if (i < 0) | ||
5272 | return NULL; | ||
5273 | if (num_pins == 1) | ||
5274 | return ""; | ||
5275 | if (num_pins > ARRAY_SIZE(channel_sfx)) { | ||
5276 | if (indexp) | ||
5277 | *indexp = i; | ||
5278 | return ""; | ||
5279 | } | ||
5280 | return channel_sfx[i]; | ||
5281 | } | ||
5282 | |||
5283 | static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | ||
5284 | const struct auto_pin_cfg *cfg, | ||
5285 | const char *name, char *label, int maxlen, | ||
5286 | int *indexp) | ||
5287 | { | ||
5288 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5289 | int attr = snd_hda_get_input_pin_attr(def_conf); | ||
5290 | const char *pfx = "", *sfx = ""; | ||
5291 | |||
5292 | /* handle as a speaker if it's a fixed line-out */ | ||
5293 | if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT) | ||
5294 | name = "Speaker"; | ||
5295 | /* check the location */ | ||
5296 | switch (attr) { | ||
5297 | case INPUT_PIN_ATTR_DOCK: | ||
5298 | pfx = "Dock "; | ||
5299 | break; | ||
5300 | case INPUT_PIN_ATTR_FRONT: | ||
5301 | pfx = "Front "; | ||
5302 | break; | ||
5303 | } | ||
5304 | if (cfg) { | ||
5305 | /* try to give a unique suffix if needed */ | ||
5306 | sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, | ||
5307 | indexp); | ||
5308 | if (!sfx) | ||
5309 | sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, | ||
5310 | indexp); | ||
5311 | if (!sfx) { | ||
5312 | /* don't add channel suffix for Headphone controls */ | ||
5313 | int idx = find_idx_in_nid_list(nid, cfg->hp_pins, | ||
5314 | cfg->hp_outs); | ||
5315 | if (idx >= 0) | ||
5316 | *indexp = idx; | ||
5317 | sfx = ""; | ||
5318 | } | 4933 | } |
5319 | } | 4934 | } |
5320 | snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); | 4935 | if (cached) |
5321 | return 1; | 4936 | return snd_hda_codec_update_cache(codec, pin, 0, |
5322 | } | 4937 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); |
5323 | 4938 | else | |
5324 | /** | 4939 | return snd_hda_codec_write(codec, pin, 0, |
5325 | * snd_hda_get_pin_label - Get a label for the given I/O pin | 4940 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); |
5326 | * | ||
5327 | * Get a label for the given pin. This function works for both input and | ||
5328 | * output pins. When @cfg is given as non-NULL, the function tries to get | ||
5329 | * an optimized label using hda_get_autocfg_input_label(). | ||
5330 | * | ||
5331 | * This function tries to give a unique label string for the pin as much as | ||
5332 | * possible. For example, when the multiple line-outs are present, it adds | ||
5333 | * the channel suffix like "Front", "Surround", etc (only when @cfg is given). | ||
5334 | * If no unique name with a suffix is available and @indexp is non-NULL, the | ||
5335 | * index number is stored in the pointer. | ||
5336 | */ | ||
5337 | int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | ||
5338 | const struct auto_pin_cfg *cfg, | ||
5339 | char *label, int maxlen, int *indexp) | ||
5340 | { | ||
5341 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); | ||
5342 | const char *name = NULL; | ||
5343 | int i; | ||
5344 | |||
5345 | if (indexp) | ||
5346 | *indexp = 0; | ||
5347 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | ||
5348 | return 0; | ||
5349 | |||
5350 | switch (get_defcfg_device(def_conf)) { | ||
5351 | case AC_JACK_LINE_OUT: | ||
5352 | return fill_audio_out_name(codec, nid, cfg, "Line Out", | ||
5353 | label, maxlen, indexp); | ||
5354 | case AC_JACK_SPEAKER: | ||
5355 | return fill_audio_out_name(codec, nid, cfg, "Speaker", | ||
5356 | label, maxlen, indexp); | ||
5357 | case AC_JACK_HP_OUT: | ||
5358 | return fill_audio_out_name(codec, nid, cfg, "Headphone", | ||
5359 | label, maxlen, indexp); | ||
5360 | case AC_JACK_SPDIF_OUT: | ||
5361 | case AC_JACK_DIG_OTHER_OUT: | ||
5362 | if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) | ||
5363 | name = "HDMI"; | ||
5364 | else | ||
5365 | name = "SPDIF"; | ||
5366 | if (cfg && indexp) { | ||
5367 | i = find_idx_in_nid_list(nid, cfg->dig_out_pins, | ||
5368 | cfg->dig_outs); | ||
5369 | if (i >= 0) | ||
5370 | *indexp = i; | ||
5371 | } | ||
5372 | break; | ||
5373 | default: | ||
5374 | if (cfg) { | ||
5375 | for (i = 0; i < cfg->num_inputs; i++) { | ||
5376 | if (cfg->inputs[i].pin != nid) | ||
5377 | continue; | ||
5378 | name = hda_get_autocfg_input_label(codec, cfg, i); | ||
5379 | if (name) | ||
5380 | break; | ||
5381 | } | ||
5382 | } | ||
5383 | if (!name) | ||
5384 | name = hda_get_input_pin_label(codec, nid, true); | ||
5385 | break; | ||
5386 | } | ||
5387 | if (!name) | ||
5388 | return 0; | ||
5389 | strlcpy(label, name, maxlen); | ||
5390 | return 1; | ||
5391 | } | 4941 | } |
5392 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); | 4942 | EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl); |
5393 | 4943 | ||
5394 | /** | 4944 | /** |
5395 | * snd_hda_add_imux_item - Add an item to input_mux | 4945 | * snd_hda_add_imux_item - Add an item to input_mux |
@@ -5444,12 +4994,6 @@ int snd_hda_suspend(struct hda_bus *bus) | |||
5444 | list_for_each_entry(codec, &bus->codec_list, list) { | 4994 | list_for_each_entry(codec, &bus->codec_list, list) { |
5445 | if (hda_codec_is_power_on(codec)) | 4995 | if (hda_codec_is_power_on(codec)) |
5446 | hda_call_codec_suspend(codec); | 4996 | hda_call_codec_suspend(codec); |
5447 | else /* forcibly change the power to D3 even if not used */ | ||
5448 | hda_set_power_state(codec, | ||
5449 | codec->afg ? codec->afg : codec->mfg, | ||
5450 | AC_PWRST_D3); | ||
5451 | if (codec->patch_ops.post_suspend) | ||
5452 | codec->patch_ops.post_suspend(codec); | ||
5453 | } | 4997 | } |
5454 | return 0; | 4998 | return 0; |
5455 | } | 4999 | } |
@@ -5469,10 +5013,7 @@ int snd_hda_resume(struct hda_bus *bus) | |||
5469 | struct hda_codec *codec; | 5013 | struct hda_codec *codec; |
5470 | 5014 | ||
5471 | list_for_each_entry(codec, &bus->codec_list, list) { | 5015 | list_for_each_entry(codec, &bus->codec_list, list) { |
5472 | if (codec->patch_ops.pre_resume) | 5016 | hda_call_codec_resume(codec); |
5473 | codec->patch_ops.pre_resume(codec); | ||
5474 | if (snd_hda_codec_needs_resume(codec)) | ||
5475 | hda_call_codec_resume(codec); | ||
5476 | } | 5017 | } |
5477 | return 0; | 5018 | return 0; |
5478 | } | 5019 | } |