diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 1027 |
1 files changed, 282 insertions, 745 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 841475cc13b6..eb09a3348325 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -334,78 +334,67 @@ static hda_nid_t *lookup_conn_list(struct snd_array *array, hda_nid_t nid) | |||
334 | return NULL; | 334 | return NULL; |
335 | } | 335 | } |
336 | 336 | ||
337 | /* read the connection and add to the cache */ | ||
338 | static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) | ||
339 | { | ||
340 | hda_nid_t list[HDA_MAX_CONNECTIONS]; | ||
341 | int len; | ||
342 | |||
343 | len = snd_hda_get_raw_connections(codec, nid, list, ARRAY_SIZE(list)); | ||
344 | if (len < 0) | ||
345 | return len; | ||
346 | return snd_hda_override_conn_list(codec, nid, len, list); | ||
347 | } | ||
348 | |||
337 | /** | 349 | /** |
338 | * snd_hda_get_conn_list - get connection list | 350 | * snd_hda_get_connections - copy connection list |
339 | * @codec: the HDA codec | 351 | * @codec: the HDA codec |
340 | * @nid: NID to parse | 352 | * @nid: NID to parse |
341 | * @listp: the pointer to store NID list | 353 | * @conn_list: connection list array; when NULL, checks only the size |
354 | * @max_conns: max. number of connections to store | ||
342 | * | 355 | * |
343 | * Parses the connection list of the given widget and stores the list | 356 | * Parses the connection list of the given widget and stores the list |
344 | * of NIDs. | 357 | * of NIDs. |
345 | * | 358 | * |
346 | * Returns the number of connections, or a negative error code. | 359 | * Returns the number of connections, or a negative error code. |
347 | */ | 360 | */ |
348 | int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, | 361 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, |
349 | const hda_nid_t **listp) | 362 | hda_nid_t *conn_list, int max_conns) |
350 | { | 363 | { |
351 | struct snd_array *array = &codec->conn_lists; | 364 | struct snd_array *array = &codec->conn_lists; |
352 | int len, err; | 365 | int len; |
353 | hda_nid_t list[HDA_MAX_CONNECTIONS]; | ||
354 | hda_nid_t *p; | 366 | hda_nid_t *p; |
355 | bool added = false; | 367 | bool added = false; |
356 | 368 | ||
357 | again: | 369 | again: |
370 | mutex_lock(&codec->hash_mutex); | ||
371 | len = -1; | ||
358 | /* if the connection-list is already cached, read it */ | 372 | /* if the connection-list is already cached, read it */ |
359 | p = lookup_conn_list(array, nid); | 373 | p = lookup_conn_list(array, nid); |
360 | if (p) { | 374 | if (p) { |
361 | if (listp) | 375 | len = p[1]; |
362 | *listp = p + 2; | 376 | if (conn_list && len > max_conns) { |
363 | return p[1]; | 377 | snd_printk(KERN_ERR "hda_codec: " |
378 | "Too many connections %d for NID 0x%x\n", | ||
379 | len, nid); | ||
380 | mutex_unlock(&codec->hash_mutex); | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | if (conn_list && len) | ||
384 | memcpy(conn_list, p + 2, len * sizeof(hda_nid_t)); | ||
364 | } | 385 | } |
386 | mutex_unlock(&codec->hash_mutex); | ||
387 | if (len >= 0) | ||
388 | return len; | ||
365 | if (snd_BUG_ON(added)) | 389 | if (snd_BUG_ON(added)) |
366 | return -EINVAL; | 390 | return -EINVAL; |
367 | 391 | ||
368 | /* read the connection and add to the cache */ | 392 | len = read_and_add_raw_conns(codec, nid); |
369 | len = snd_hda_get_raw_connections(codec, nid, list, HDA_MAX_CONNECTIONS); | ||
370 | if (len < 0) | 393 | if (len < 0) |
371 | return len; | 394 | return len; |
372 | err = snd_hda_override_conn_list(codec, nid, len, list); | ||
373 | if (err < 0) | ||
374 | return err; | ||
375 | added = true; | 395 | added = true; |
376 | goto again; | 396 | goto again; |
377 | } | 397 | } |
378 | EXPORT_SYMBOL_HDA(snd_hda_get_conn_list); | ||
379 | |||
380 | /** | ||
381 | * snd_hda_get_connections - copy connection list | ||
382 | * @codec: the HDA codec | ||
383 | * @nid: NID to parse | ||
384 | * @conn_list: connection list array | ||
385 | * @max_conns: max. number of connections to store | ||
386 | * | ||
387 | * Parses the connection list of the given widget and stores the list | ||
388 | * of NIDs. | ||
389 | * | ||
390 | * Returns the number of connections, or a negative error code. | ||
391 | */ | ||
392 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | ||
393 | hda_nid_t *conn_list, int max_conns) | ||
394 | { | ||
395 | const hda_nid_t *list; | ||
396 | int len = snd_hda_get_conn_list(codec, nid, &list); | ||
397 | |||
398 | if (len <= 0) | ||
399 | return len; | ||
400 | if (len > max_conns) { | ||
401 | snd_printk(KERN_ERR "hda_codec: " | ||
402 | "Too many connections %d for NID 0x%x\n", | ||
403 | len, nid); | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | memcpy(conn_list, list, len * sizeof(hda_nid_t)); | ||
407 | return len; | ||
408 | } | ||
409 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); | 398 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); |
410 | 399 | ||
411 | /** | 400 | /** |
@@ -543,6 +532,7 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len, | |||
543 | hda_nid_t *p; | 532 | hda_nid_t *p; |
544 | int i, old_used; | 533 | int i, old_used; |
545 | 534 | ||
535 | mutex_lock(&codec->hash_mutex); | ||
546 | p = lookup_conn_list(array, nid); | 536 | p = lookup_conn_list(array, nid); |
547 | if (p) | 537 | if (p) |
548 | *p = -1; /* invalidate the old entry */ | 538 | *p = -1; /* invalidate the old entry */ |
@@ -553,10 +543,12 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len, | |||
553 | for (i = 0; i < len; i++) | 543 | for (i = 0; i < len; i++) |
554 | if (!add_conn_list(array, list[i])) | 544 | if (!add_conn_list(array, list[i])) |
555 | goto error_add; | 545 | goto error_add; |
546 | mutex_unlock(&codec->hash_mutex); | ||
556 | return 0; | 547 | return 0; |
557 | 548 | ||
558 | error_add: | 549 | error_add: |
559 | array->used = old_used; | 550 | array->used = old_used; |
551 | mutex_unlock(&codec->hash_mutex); | ||
560 | return -ENOMEM; | 552 | return -ENOMEM; |
561 | } | 553 | } |
562 | EXPORT_SYMBOL_HDA(snd_hda_override_conn_list); | 554 | EXPORT_SYMBOL_HDA(snd_hda_override_conn_list); |
@@ -1255,6 +1247,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1255 | codec->addr = codec_addr; | 1247 | codec->addr = codec_addr; |
1256 | mutex_init(&codec->spdif_mutex); | 1248 | mutex_init(&codec->spdif_mutex); |
1257 | mutex_init(&codec->control_mutex); | 1249 | mutex_init(&codec->control_mutex); |
1250 | mutex_init(&codec->hash_mutex); | ||
1258 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | 1251 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); |
1259 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | 1252 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); |
1260 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); | 1253 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); |
@@ -1264,15 +1257,9 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1264 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); | 1257 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); |
1265 | snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); | 1258 | snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); |
1266 | snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); | 1259 | 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 | 1260 | ||
1275 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1261 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1262 | spin_lock_init(&codec->power_lock); | ||
1276 | INIT_DELAYED_WORK(&codec->power_work, hda_power_work); | 1263 | 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. | 1264 | /* 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 | 1265 | * the caller has to power down appropriatley after initialization |
@@ -1281,6 +1268,14 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1281 | hda_keep_power_on(codec); | 1268 | hda_keep_power_on(codec); |
1282 | #endif | 1269 | #endif |
1283 | 1270 | ||
1271 | if (codec->bus->modelname) { | ||
1272 | codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); | ||
1273 | if (!codec->modelname) { | ||
1274 | snd_hda_codec_free(codec); | ||
1275 | return -ENODEV; | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1284 | list_add_tail(&codec->list, &bus->codec_list); | 1279 | list_add_tail(&codec->list, &bus->codec_list); |
1285 | bus->caddr_tbl[codec_addr] = codec; | 1280 | bus->caddr_tbl[codec_addr] = codec; |
1286 | 1281 | ||
@@ -1603,6 +1598,60 @@ get_alloc_amp_hash(struct hda_codec *codec, u32 key) | |||
1603 | return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key); | 1598 | return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key); |
1604 | } | 1599 | } |
1605 | 1600 | ||
1601 | /* overwrite the value with the key in the caps hash */ | ||
1602 | static int write_caps_hash(struct hda_codec *codec, u32 key, unsigned int val) | ||
1603 | { | ||
1604 | struct hda_amp_info *info; | ||
1605 | |||
1606 | mutex_lock(&codec->hash_mutex); | ||
1607 | info = get_alloc_amp_hash(codec, key); | ||
1608 | if (!info) { | ||
1609 | mutex_unlock(&codec->hash_mutex); | ||
1610 | return -EINVAL; | ||
1611 | } | ||
1612 | info->amp_caps = val; | ||
1613 | info->head.val |= INFO_AMP_CAPS; | ||
1614 | mutex_unlock(&codec->hash_mutex); | ||
1615 | return 0; | ||
1616 | } | ||
1617 | |||
1618 | /* query the value from the caps hash; if not found, fetch the current | ||
1619 | * value from the given function and store in the hash | ||
1620 | */ | ||
1621 | static unsigned int | ||
1622 | query_caps_hash(struct hda_codec *codec, hda_nid_t nid, int dir, u32 key, | ||
1623 | unsigned int (*func)(struct hda_codec *, hda_nid_t, int)) | ||
1624 | { | ||
1625 | struct hda_amp_info *info; | ||
1626 | unsigned int val; | ||
1627 | |||
1628 | mutex_lock(&codec->hash_mutex); | ||
1629 | info = get_alloc_amp_hash(codec, key); | ||
1630 | if (!info) { | ||
1631 | mutex_unlock(&codec->hash_mutex); | ||
1632 | return 0; | ||
1633 | } | ||
1634 | if (!(info->head.val & INFO_AMP_CAPS)) { | ||
1635 | mutex_unlock(&codec->hash_mutex); /* for reentrance */ | ||
1636 | val = func(codec, nid, dir); | ||
1637 | write_caps_hash(codec, key, val); | ||
1638 | } else { | ||
1639 | val = info->amp_caps; | ||
1640 | mutex_unlock(&codec->hash_mutex); | ||
1641 | } | ||
1642 | return val; | ||
1643 | } | ||
1644 | |||
1645 | static unsigned int read_amp_cap(struct hda_codec *codec, hda_nid_t nid, | ||
1646 | int direction) | ||
1647 | { | ||
1648 | if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) | ||
1649 | nid = codec->afg; | ||
1650 | return snd_hda_param_read(codec, nid, | ||
1651 | direction == HDA_OUTPUT ? | ||
1652 | AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); | ||
1653 | } | ||
1654 | |||
1606 | /** | 1655 | /** |
1607 | * query_amp_caps - query AMP capabilities | 1656 | * query_amp_caps - query AMP capabilities |
1608 | * @codec: the HD-auio codec | 1657 | * @codec: the HD-auio codec |
@@ -1617,22 +1666,9 @@ get_alloc_amp_hash(struct hda_codec *codec, u32 key) | |||
1617 | */ | 1666 | */ |
1618 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) | 1667 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) |
1619 | { | 1668 | { |
1620 | struct hda_amp_info *info; | 1669 | return query_caps_hash(codec, nid, direction, |
1621 | 1670 | HDA_HASH_KEY(nid, direction, 0), | |
1622 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); | 1671 | 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 | } | 1672 | } |
1637 | EXPORT_SYMBOL_HDA(query_amp_caps); | 1673 | EXPORT_SYMBOL_HDA(query_amp_caps); |
1638 | 1674 | ||
@@ -1652,34 +1688,12 @@ EXPORT_SYMBOL_HDA(query_amp_caps); | |||
1652 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 1688 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, |
1653 | unsigned int caps) | 1689 | unsigned int caps) |
1654 | { | 1690 | { |
1655 | struct hda_amp_info *info; | 1691 | 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 | } | 1692 | } |
1664 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); | 1693 | EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); |
1665 | 1694 | ||
1666 | static unsigned int | 1695 | 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, | 1696 | 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 | { | 1697 | { |
1684 | return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | 1698 | return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); |
1685 | } | 1699 | } |
@@ -1697,7 +1711,7 @@ static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid) | |||
1697 | */ | 1711 | */ |
1698 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) | 1712 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) |
1699 | { | 1713 | { |
1700 | return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid), | 1714 | return query_caps_hash(codec, nid, 0, HDA_HASH_PINCAP_KEY(nid), |
1701 | read_pin_cap); | 1715 | read_pin_cap); |
1702 | } | 1716 | } |
1703 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); | 1717 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); |
@@ -1715,41 +1729,47 @@ EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); | |||
1715 | int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, | 1729 | int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, |
1716 | unsigned int caps) | 1730 | unsigned int caps) |
1717 | { | 1731 | { |
1718 | struct hda_amp_info *info; | 1732 | 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 | } | 1733 | } |
1726 | EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); | 1734 | EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); |
1727 | 1735 | ||
1728 | /* | 1736 | /* read or sync the hash value with the current value; |
1729 | * read the current volume to info | 1737 | * call within hash_mutex |
1730 | * if the cache exists, read the cache value. | ||
1731 | */ | 1738 | */ |
1732 | static unsigned int get_vol_mute(struct hda_codec *codec, | 1739 | static struct hda_amp_info * |
1733 | struct hda_amp_info *info, hda_nid_t nid, | 1740 | update_amp_hash(struct hda_codec *codec, hda_nid_t nid, int ch, |
1734 | int ch, int direction, int index) | 1741 | int direction, int index) |
1735 | { | 1742 | { |
1736 | u32 val, parm; | 1743 | struct hda_amp_info *info; |
1737 | 1744 | unsigned int parm, val = 0; | |
1738 | if (info->head.val & INFO_AMP_VOL(ch)) | 1745 | bool val_read = false; |
1739 | return info->vol[ch]; | ||
1740 | 1746 | ||
1741 | parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; | 1747 | retry: |
1742 | parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; | 1748 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); |
1743 | parm |= index; | 1749 | if (!info) |
1744 | val = snd_hda_codec_read(codec, nid, 0, | 1750 | return NULL; |
1751 | if (!(info->head.val & INFO_AMP_VOL(ch))) { | ||
1752 | if (!val_read) { | ||
1753 | mutex_unlock(&codec->hash_mutex); | ||
1754 | parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; | ||
1755 | parm |= direction == HDA_OUTPUT ? | ||
1756 | AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; | ||
1757 | parm |= index; | ||
1758 | val = snd_hda_codec_read(codec, nid, 0, | ||
1745 | AC_VERB_GET_AMP_GAIN_MUTE, parm); | 1759 | AC_VERB_GET_AMP_GAIN_MUTE, parm); |
1746 | info->vol[ch] = val & 0xff; | 1760 | val &= 0xff; |
1747 | info->head.val |= INFO_AMP_VOL(ch); | 1761 | val_read = true; |
1748 | return info->vol[ch]; | 1762 | mutex_lock(&codec->hash_mutex); |
1763 | goto retry; | ||
1764 | } | ||
1765 | info->vol[ch] = val; | ||
1766 | info->head.val |= INFO_AMP_VOL(ch); | ||
1767 | } | ||
1768 | return info; | ||
1749 | } | 1769 | } |
1750 | 1770 | ||
1751 | /* | 1771 | /* |
1752 | * write the current volume in info to the h/w and update the cache | 1772 | * write the current volume in info to the h/w |
1753 | */ | 1773 | */ |
1754 | static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | 1774 | 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, | 1775 | hda_nid_t nid, int ch, int direction, int index, |
@@ -1766,7 +1786,6 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | |||
1766 | else | 1786 | else |
1767 | parm |= val; | 1787 | parm |= val; |
1768 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); | 1788 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); |
1769 | info->vol[ch] = val; | ||
1770 | } | 1789 | } |
1771 | 1790 | ||
1772 | /** | 1791 | /** |
@@ -1783,10 +1802,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1783 | int direction, int index) | 1802 | int direction, int index) |
1784 | { | 1803 | { |
1785 | struct hda_amp_info *info; | 1804 | struct hda_amp_info *info; |
1786 | info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); | 1805 | unsigned int val = 0; |
1787 | if (!info) | 1806 | |
1788 | return 0; | 1807 | mutex_lock(&codec->hash_mutex); |
1789 | return get_vol_mute(codec, info, nid, ch, direction, index); | 1808 | info = update_amp_hash(codec, nid, ch, direction, index); |
1809 | if (info) | ||
1810 | val = info->vol[ch]; | ||
1811 | mutex_unlock(&codec->hash_mutex); | ||
1812 | return val; | ||
1790 | } | 1813 | } |
1791 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); | 1814 | EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); |
1792 | 1815 | ||
@@ -1808,15 +1831,23 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
1808 | { | 1831 | { |
1809 | struct hda_amp_info *info; | 1832 | struct hda_amp_info *info; |
1810 | 1833 | ||
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)) | 1834 | if (snd_BUG_ON(mask & ~0xff)) |
1815 | mask &= 0xff; | 1835 | mask &= 0xff; |
1816 | val &= mask; | 1836 | val &= mask; |
1817 | val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; | 1837 | |
1818 | if (info->vol[ch] == val) | 1838 | mutex_lock(&codec->hash_mutex); |
1839 | info = update_amp_hash(codec, nid, ch, direction, idx); | ||
1840 | if (!info) { | ||
1841 | mutex_unlock(&codec->hash_mutex); | ||
1842 | return 0; | ||
1843 | } | ||
1844 | val |= info->vol[ch] & ~mask; | ||
1845 | if (info->vol[ch] == val) { | ||
1846 | mutex_unlock(&codec->hash_mutex); | ||
1819 | return 0; | 1847 | return 0; |
1848 | } | ||
1849 | info->vol[ch] = val; | ||
1850 | mutex_unlock(&codec->hash_mutex); | ||
1820 | put_vol_mute(codec, info, nid, ch, direction, idx, val); | 1851 | put_vol_mute(codec, info, nid, ch, direction, idx, val); |
1821 | return 1; | 1852 | return 1; |
1822 | } | 1853 | } |
@@ -2263,7 +2294,10 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2263 | /* OK, let it free */ | 2294 | /* OK, let it free */ |
2264 | 2295 | ||
2265 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2296 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2266 | cancel_delayed_work(&codec->power_work); | 2297 | cancel_delayed_work_sync(&codec->power_work); |
2298 | codec->power_on = 0; | ||
2299 | codec->power_transition = 0; | ||
2300 | codec->power_jiffies = jiffies; | ||
2267 | flush_workqueue(codec->bus->workq); | 2301 | flush_workqueue(codec->bus->workq); |
2268 | #endif | 2302 | #endif |
2269 | snd_hda_ctls_clear(codec); | 2303 | snd_hda_ctls_clear(codec); |
@@ -2859,12 +2893,15 @@ static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, | |||
2859 | { | 2893 | { |
2860 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2894 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2861 | int idx = kcontrol->private_value; | 2895 | int idx = kcontrol->private_value; |
2862 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 2896 | struct hda_spdif_out *spdif; |
2863 | 2897 | ||
2898 | mutex_lock(&codec->spdif_mutex); | ||
2899 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
2864 | ucontrol->value.iec958.status[0] = spdif->status & 0xff; | 2900 | ucontrol->value.iec958.status[0] = spdif->status & 0xff; |
2865 | ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff; | 2901 | ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff; |
2866 | ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff; | 2902 | ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff; |
2867 | ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff; | 2903 | ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff; |
2904 | mutex_unlock(&codec->spdif_mutex); | ||
2868 | 2905 | ||
2869 | return 0; | 2906 | return 0; |
2870 | } | 2907 | } |
@@ -2950,12 +2987,14 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
2950 | { | 2987 | { |
2951 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2988 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2952 | int idx = kcontrol->private_value; | 2989 | int idx = kcontrol->private_value; |
2953 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 2990 | struct hda_spdif_out *spdif; |
2954 | hda_nid_t nid = spdif->nid; | 2991 | hda_nid_t nid; |
2955 | unsigned short val; | 2992 | unsigned short val; |
2956 | int change; | 2993 | int change; |
2957 | 2994 | ||
2958 | mutex_lock(&codec->spdif_mutex); | 2995 | mutex_lock(&codec->spdif_mutex); |
2996 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
2997 | nid = spdif->nid; | ||
2959 | spdif->status = ucontrol->value.iec958.status[0] | | 2998 | spdif->status = ucontrol->value.iec958.status[0] | |
2960 | ((unsigned int)ucontrol->value.iec958.status[1] << 8) | | 2999 | ((unsigned int)ucontrol->value.iec958.status[1] << 8) | |
2961 | ((unsigned int)ucontrol->value.iec958.status[2] << 16) | | 3000 | ((unsigned int)ucontrol->value.iec958.status[2] << 16) | |
@@ -2977,9 +3016,12 @@ static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, | |||
2977 | { | 3016 | { |
2978 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 3017 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2979 | int idx = kcontrol->private_value; | 3018 | int idx = kcontrol->private_value; |
2980 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3019 | struct hda_spdif_out *spdif; |
2981 | 3020 | ||
3021 | mutex_lock(&codec->spdif_mutex); | ||
3022 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
2982 | ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE; | 3023 | ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE; |
3024 | mutex_unlock(&codec->spdif_mutex); | ||
2983 | return 0; | 3025 | return 0; |
2984 | } | 3026 | } |
2985 | 3027 | ||
@@ -2999,12 +3041,14 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, | |||
2999 | { | 3041 | { |
3000 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 3042 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
3001 | int idx = kcontrol->private_value; | 3043 | int idx = kcontrol->private_value; |
3002 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3044 | struct hda_spdif_out *spdif; |
3003 | hda_nid_t nid = spdif->nid; | 3045 | hda_nid_t nid; |
3004 | unsigned short val; | 3046 | unsigned short val; |
3005 | int change; | 3047 | int change; |
3006 | 3048 | ||
3007 | mutex_lock(&codec->spdif_mutex); | 3049 | mutex_lock(&codec->spdif_mutex); |
3050 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
3051 | nid = spdif->nid; | ||
3008 | val = spdif->ctls & ~AC_DIG1_ENABLE; | 3052 | val = spdif->ctls & ~AC_DIG1_ENABLE; |
3009 | if (ucontrol->value.integer.value[0]) | 3053 | if (ucontrol->value.integer.value[0]) |
3010 | val |= AC_DIG1_ENABLE; | 3054 | val |= AC_DIG1_ENABLE; |
@@ -3092,6 +3136,9 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, | |||
3092 | } | 3136 | } |
3093 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); | 3137 | EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); |
3094 | 3138 | ||
3139 | /* get the hda_spdif_out entry from the given NID | ||
3140 | * call within spdif_mutex lock | ||
3141 | */ | ||
3095 | struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, | 3142 | struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, |
3096 | hda_nid_t nid) | 3143 | hda_nid_t nid) |
3097 | { | 3144 | { |
@@ -3108,9 +3155,10 @@ EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid); | |||
3108 | 3155 | ||
3109 | void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) | 3156 | void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) |
3110 | { | 3157 | { |
3111 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3158 | struct hda_spdif_out *spdif; |
3112 | 3159 | ||
3113 | mutex_lock(&codec->spdif_mutex); | 3160 | mutex_lock(&codec->spdif_mutex); |
3161 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
3114 | spdif->nid = (u16)-1; | 3162 | spdif->nid = (u16)-1; |
3115 | mutex_unlock(&codec->spdif_mutex); | 3163 | mutex_unlock(&codec->spdif_mutex); |
3116 | } | 3164 | } |
@@ -3118,10 +3166,11 @@ EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_unassign); | |||
3118 | 3166 | ||
3119 | void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) | 3167 | void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) |
3120 | { | 3168 | { |
3121 | struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx); | 3169 | struct hda_spdif_out *spdif; |
3122 | unsigned short val; | 3170 | unsigned short val; |
3123 | 3171 | ||
3124 | mutex_lock(&codec->spdif_mutex); | 3172 | mutex_lock(&codec->spdif_mutex); |
3173 | spdif = snd_array_elem(&codec->spdif_out, idx); | ||
3125 | if (spdif->nid != nid) { | 3174 | if (spdif->nid != nid) { |
3126 | spdif->nid = nid; | 3175 | spdif->nid = nid; |
3127 | val = spdif->ctls; | 3176 | val = spdif->ctls; |
@@ -3486,11 +3535,14 @@ static void hda_call_codec_suspend(struct hda_codec *codec) | |||
3486 | codec->afg ? codec->afg : codec->mfg, | 3535 | codec->afg ? codec->afg : codec->mfg, |
3487 | AC_PWRST_D3); | 3536 | AC_PWRST_D3); |
3488 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3537 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3489 | snd_hda_update_power_acct(codec); | ||
3490 | cancel_delayed_work(&codec->power_work); | 3538 | cancel_delayed_work(&codec->power_work); |
3539 | spin_lock(&codec->power_lock); | ||
3540 | snd_hda_update_power_acct(codec); | ||
3541 | trace_hda_power_down(codec); | ||
3491 | codec->power_on = 0; | 3542 | codec->power_on = 0; |
3492 | codec->power_transition = 0; | 3543 | codec->power_transition = 0; |
3493 | codec->power_jiffies = jiffies; | 3544 | codec->power_jiffies = jiffies; |
3545 | spin_unlock(&codec->power_lock); | ||
3494 | #endif | 3546 | #endif |
3495 | } | 3547 | } |
3496 | 3548 | ||
@@ -3499,6 +3551,10 @@ static void hda_call_codec_suspend(struct hda_codec *codec) | |||
3499 | */ | 3551 | */ |
3500 | static void hda_call_codec_resume(struct hda_codec *codec) | 3552 | static void hda_call_codec_resume(struct hda_codec *codec) |
3501 | { | 3553 | { |
3554 | /* set as if powered on for avoiding re-entering the resume | ||
3555 | * in the resume / power-save sequence | ||
3556 | */ | ||
3557 | hda_keep_power_on(codec); | ||
3502 | hda_set_power_state(codec, | 3558 | hda_set_power_state(codec, |
3503 | codec->afg ? codec->afg : codec->mfg, | 3559 | codec->afg ? codec->afg : codec->mfg, |
3504 | AC_PWRST_D0); | 3560 | AC_PWRST_D0); |
@@ -3514,6 +3570,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) | |||
3514 | snd_hda_codec_resume_amp(codec); | 3570 | snd_hda_codec_resume_amp(codec); |
3515 | snd_hda_codec_resume_cache(codec); | 3571 | snd_hda_codec_resume_cache(codec); |
3516 | } | 3572 | } |
3573 | snd_hda_power_down(codec); /* flag down before returning */ | ||
3517 | } | 3574 | } |
3518 | #endif /* CONFIG_PM */ | 3575 | #endif /* CONFIG_PM */ |
3519 | 3576 | ||
@@ -3665,7 +3722,8 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
3665 | } | 3722 | } |
3666 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); | 3723 | EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); |
3667 | 3724 | ||
3668 | static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid) | 3725 | static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid, |
3726 | int dir) | ||
3669 | { | 3727 | { |
3670 | unsigned int val = 0; | 3728 | unsigned int val = 0; |
3671 | if (nid != codec->afg && | 3729 | if (nid != codec->afg && |
@@ -3680,11 +3738,12 @@ static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid) | |||
3680 | 3738 | ||
3681 | static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) | 3739 | static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) |
3682 | { | 3740 | { |
3683 | return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid), | 3741 | return query_caps_hash(codec, nid, 0, HDA_HASH_PARPCM_KEY(nid), |
3684 | get_pcm_param); | 3742 | get_pcm_param); |
3685 | } | 3743 | } |
3686 | 3744 | ||
3687 | static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid) | 3745 | static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid, |
3746 | int dir) | ||
3688 | { | 3747 | { |
3689 | unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 3748 | unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); |
3690 | if (!streams || streams == -1) | 3749 | if (!streams || streams == -1) |
@@ -3696,7 +3755,7 @@ static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid) | |||
3696 | 3755 | ||
3697 | static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) | 3756 | static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) |
3698 | { | 3757 | { |
3699 | return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid), | 3758 | return query_caps_hash(codec, nid, 0, HDA_HASH_PARSTR_KEY(nid), |
3700 | get_stream_param); | 3759 | get_stream_param); |
3701 | } | 3760 | } |
3702 | 3761 | ||
@@ -3775,11 +3834,13 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
3775 | bps = 20; | 3834 | bps = 20; |
3776 | } | 3835 | } |
3777 | } | 3836 | } |
3837 | #if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */ | ||
3778 | if (streams & AC_SUPFMT_FLOAT32) { | 3838 | if (streams & AC_SUPFMT_FLOAT32) { |
3779 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; | 3839 | formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; |
3780 | if (!bps) | 3840 | if (!bps) |
3781 | bps = 32; | 3841 | bps = 32; |
3782 | } | 3842 | } |
3843 | #endif | ||
3783 | if (streams == AC_SUPFMT_AC3) { | 3844 | if (streams == AC_SUPFMT_AC3) { |
3784 | /* should be exclusive */ | 3845 | /* should be exclusive */ |
3785 | /* temporary hack: we have still no proper support | 3846 | /* temporary hack: we have still no proper support |
@@ -4283,12 +4344,18 @@ static void hda_power_work(struct work_struct *work) | |||
4283 | container_of(work, struct hda_codec, power_work.work); | 4344 | container_of(work, struct hda_codec, power_work.work); |
4284 | struct hda_bus *bus = codec->bus; | 4345 | struct hda_bus *bus = codec->bus; |
4285 | 4346 | ||
4347 | spin_lock(&codec->power_lock); | ||
4348 | if (codec->power_transition > 0) { /* during power-up sequence? */ | ||
4349 | spin_unlock(&codec->power_lock); | ||
4350 | return; | ||
4351 | } | ||
4286 | if (!codec->power_on || codec->power_count) { | 4352 | if (!codec->power_on || codec->power_count) { |
4287 | codec->power_transition = 0; | 4353 | codec->power_transition = 0; |
4354 | spin_unlock(&codec->power_lock); | ||
4288 | return; | 4355 | return; |
4289 | } | 4356 | } |
4357 | spin_unlock(&codec->power_lock); | ||
4290 | 4358 | ||
4291 | trace_hda_power_down(codec); | ||
4292 | hda_call_codec_suspend(codec); | 4359 | hda_call_codec_suspend(codec); |
4293 | if (bus->ops.pm_notify) | 4360 | if (bus->ops.pm_notify) |
4294 | bus->ops.pm_notify(bus); | 4361 | bus->ops.pm_notify(bus); |
@@ -4296,9 +4363,11 @@ static void hda_power_work(struct work_struct *work) | |||
4296 | 4363 | ||
4297 | static void hda_keep_power_on(struct hda_codec *codec) | 4364 | static void hda_keep_power_on(struct hda_codec *codec) |
4298 | { | 4365 | { |
4366 | spin_lock(&codec->power_lock); | ||
4299 | codec->power_count++; | 4367 | codec->power_count++; |
4300 | codec->power_on = 1; | 4368 | codec->power_on = 1; |
4301 | codec->power_jiffies = jiffies; | 4369 | codec->power_jiffies = jiffies; |
4370 | spin_unlock(&codec->power_lock); | ||
4302 | } | 4371 | } |
4303 | 4372 | ||
4304 | /* update the power on/off account with the current jiffies */ | 4373 | /* update the power on/off account with the current jiffies */ |
@@ -4323,19 +4392,31 @@ void snd_hda_power_up(struct hda_codec *codec) | |||
4323 | { | 4392 | { |
4324 | struct hda_bus *bus = codec->bus; | 4393 | struct hda_bus *bus = codec->bus; |
4325 | 4394 | ||
4395 | spin_lock(&codec->power_lock); | ||
4326 | codec->power_count++; | 4396 | codec->power_count++; |
4327 | if (codec->power_on || codec->power_transition) | 4397 | if (codec->power_on || codec->power_transition > 0) { |
4398 | spin_unlock(&codec->power_lock); | ||
4328 | return; | 4399 | return; |
4400 | } | ||
4401 | spin_unlock(&codec->power_lock); | ||
4329 | 4402 | ||
4403 | cancel_delayed_work_sync(&codec->power_work); | ||
4404 | |||
4405 | spin_lock(&codec->power_lock); | ||
4330 | trace_hda_power_up(codec); | 4406 | trace_hda_power_up(codec); |
4331 | snd_hda_update_power_acct(codec); | 4407 | snd_hda_update_power_acct(codec); |
4332 | codec->power_on = 1; | 4408 | codec->power_on = 1; |
4333 | codec->power_jiffies = jiffies; | 4409 | codec->power_jiffies = jiffies; |
4410 | codec->power_transition = 1; /* avoid reentrance */ | ||
4411 | spin_unlock(&codec->power_lock); | ||
4412 | |||
4334 | if (bus->ops.pm_notify) | 4413 | if (bus->ops.pm_notify) |
4335 | bus->ops.pm_notify(bus); | 4414 | bus->ops.pm_notify(bus); |
4336 | hda_call_codec_resume(codec); | 4415 | hda_call_codec_resume(codec); |
4337 | cancel_delayed_work(&codec->power_work); | 4416 | |
4417 | spin_lock(&codec->power_lock); | ||
4338 | codec->power_transition = 0; | 4418 | codec->power_transition = 0; |
4419 | spin_unlock(&codec->power_lock); | ||
4339 | } | 4420 | } |
4340 | EXPORT_SYMBOL_HDA(snd_hda_power_up); | 4421 | EXPORT_SYMBOL_HDA(snd_hda_power_up); |
4341 | 4422 | ||
@@ -4351,14 +4432,18 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up); | |||
4351 | */ | 4432 | */ |
4352 | void snd_hda_power_down(struct hda_codec *codec) | 4433 | void snd_hda_power_down(struct hda_codec *codec) |
4353 | { | 4434 | { |
4435 | spin_lock(&codec->power_lock); | ||
4354 | --codec->power_count; | 4436 | --codec->power_count; |
4355 | if (!codec->power_on || codec->power_count || codec->power_transition) | 4437 | if (!codec->power_on || codec->power_count || codec->power_transition) { |
4438 | spin_unlock(&codec->power_lock); | ||
4356 | return; | 4439 | return; |
4440 | } | ||
4357 | if (power_save(codec)) { | 4441 | if (power_save(codec)) { |
4358 | codec->power_transition = 1; /* avoid reentrance */ | 4442 | codec->power_transition = -1; /* avoid reentrance */ |
4359 | queue_delayed_work(codec->bus->workq, &codec->power_work, | 4443 | queue_delayed_work(codec->bus->workq, &codec->power_work, |
4360 | msecs_to_jiffies(power_save(codec) * 1000)); | 4444 | msecs_to_jiffies(power_save(codec) * 1000)); |
4361 | } | 4445 | } |
4446 | spin_unlock(&codec->power_lock); | ||
4362 | } | 4447 | } |
4363 | EXPORT_SYMBOL_HDA(snd_hda_power_down); | 4448 | EXPORT_SYMBOL_HDA(snd_hda_power_down); |
4364 | 4449 | ||
@@ -4710,11 +4795,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, | |||
4710 | { | 4795 | { |
4711 | const hda_nid_t *nids = mout->dac_nids; | 4796 | const hda_nid_t *nids = mout->dac_nids; |
4712 | int chs = substream->runtime->channels; | 4797 | int chs = substream->runtime->channels; |
4713 | struct hda_spdif_out *spdif = | 4798 | struct hda_spdif_out *spdif; |
4714 | snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid); | ||
4715 | int i; | 4799 | int i; |
4716 | 4800 | ||
4717 | mutex_lock(&codec->spdif_mutex); | 4801 | mutex_lock(&codec->spdif_mutex); |
4802 | spdif = snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid); | ||
4718 | if (mout->dig_out_nid && mout->share_spdif && | 4803 | if (mout->dig_out_nid && mout->share_spdif && |
4719 | mout->dig_out_used != HDA_DIG_EXCLUSIVE) { | 4804 | mout->dig_out_used != HDA_DIG_EXCLUSIVE) { |
4720 | if (chs == 2 && | 4805 | if (chs == 2 && |
@@ -4795,601 +4880,58 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, | |||
4795 | } | 4880 | } |
4796 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); | 4881 | EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); |
4797 | 4882 | ||
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 | /** | ||
5148 | * hda_get_input_pin_label - Give a label for the given input pin | ||
5149 | * | ||
5150 | * When check_location is true, the function checks the pin location | ||
5151 | * for mic and line-in pins, and set an appropriate prefix like "Front", | ||
5152 | * "Rear", "Internal". | ||
5153 | */ | ||
5154 | |||
5155 | static const char *hda_get_input_pin_label(struct hda_codec *codec, | ||
5156 | hda_nid_t pin, bool check_location) | ||
5157 | { | ||
5158 | unsigned int def_conf; | ||
5159 | static const char * const mic_names[] = { | ||
5160 | "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", | ||
5161 | }; | ||
5162 | int attr; | ||
5163 | |||
5164 | def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
5165 | |||
5166 | switch (get_defcfg_device(def_conf)) { | ||
5167 | case AC_JACK_MIC_IN: | ||
5168 | if (!check_location) | ||
5169 | return "Mic"; | ||
5170 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
5171 | if (!attr) | ||
5172 | return "None"; | ||
5173 | return mic_names[attr - 1]; | ||
5174 | case AC_JACK_LINE_IN: | ||
5175 | if (!check_location) | ||
5176 | return "Line"; | ||
5177 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
5178 | if (!attr) | ||
5179 | return "None"; | ||
5180 | if (attr == INPUT_PIN_ATTR_DOCK) | ||
5181 | return "Dock Line"; | ||
5182 | return "Line"; | ||
5183 | case AC_JACK_AUX: | ||
5184 | return "Aux"; | ||
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 | } | ||
5222 | } | ||
5223 | return 0; | ||
5224 | } | ||
5225 | |||
5226 | /** | 4883 | /** |
5227 | * hda_get_autocfg_input_label - Get a label for the given input | 4884 | * snd_hda_get_default_vref - Get the default (mic) VREF pin bits |
5228 | * | 4885 | * |
5229 | * Get a label for the given input pin defined by the autocfg item. | 4886 | * Guess the suitable VREF pin bits to be set as the pin-control value. |
5230 | * Unlike hda_get_input_pin_label(), this function checks all inputs | 4887 | * Note: the function doesn't set the AC_PINCTL_IN_EN bit. |
5231 | * defined in autocfg and avoids the redundant mic/line prefix as much as | 4888 | */ |
5232 | * possible. | 4889 | unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin) |
5233 | */ | 4890 | { |
5234 | const char *hda_get_autocfg_input_label(struct hda_codec *codec, | 4891 | unsigned int pincap; |
5235 | const struct auto_pin_cfg *cfg, | 4892 | unsigned int oldval; |
5236 | int input) | 4893 | oldval = snd_hda_codec_read(codec, pin, 0, |
5237 | { | 4894 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
5238 | int type = cfg->inputs[input].type; | 4895 | pincap = snd_hda_query_pin_caps(codec, pin); |
5239 | int has_multiple_pins = 0; | 4896 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
5240 | 4897 | /* Exception: if the default pin setup is vref50, we give it priority */ | |
5241 | if ((input > 0 && cfg->inputs[input - 1].type == type) || | 4898 | if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) |
5242 | (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type)) | 4899 | return AC_PINCTL_VREF_80; |
5243 | has_multiple_pins = 1; | 4900 | else if (pincap & AC_PINCAP_VREF_50) |
5244 | if (has_multiple_pins && type == AUTO_PIN_MIC) | 4901 | return AC_PINCTL_VREF_50; |
5245 | has_multiple_pins &= check_mic_location_need(codec, cfg, input); | 4902 | else if (pincap & AC_PINCAP_VREF_100) |
5246 | return hda_get_input_pin_label(codec, cfg->inputs[input].pin, | 4903 | return AC_PINCTL_VREF_100; |
5247 | has_multiple_pins); | 4904 | else if (pincap & AC_PINCAP_VREF_GRD) |
5248 | } | 4905 | return AC_PINCTL_VREF_GRD; |
5249 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | 4906 | return AC_PINCTL_VREF_HIZ; |
5250 | 4907 | } | |
5251 | /* return the position of NID in the list, or -1 if not found */ | 4908 | EXPORT_SYMBOL_HDA(snd_hda_get_default_vref); |
5252 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 4909 | |
5253 | { | 4910 | int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, |
5254 | int i; | 4911 | unsigned int val, bool cached) |
5255 | for (i = 0; i < nums; i++) | 4912 | { |
5256 | if (list[i] == nid) | 4913 | if (val) { |
5257 | return i; | 4914 | unsigned int cap = snd_hda_query_pin_caps(codec, pin); |
5258 | return -1; | 4915 | if (cap && (val & AC_PINCTL_OUT_EN)) { |
5259 | } | 4916 | if (!(cap & AC_PINCAP_OUT)) |
5260 | 4917 | val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | |
5261 | /* get a unique suffix or an index number */ | 4918 | else if ((val & AC_PINCTL_HP_EN) && |
5262 | static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, | 4919 | !(cap & AC_PINCAP_HP_DRV)) |
5263 | int num_pins, int *indexp) | 4920 | val &= ~AC_PINCTL_HP_EN; |
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 | } | 4921 | } |
5319 | } | 4922 | if (cap && (val & AC_PINCTL_IN_EN)) { |
5320 | snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); | 4923 | if (!(cap & AC_PINCAP_IN)) |
5321 | return 1; | 4924 | val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN); |
5322 | } | ||
5323 | |||
5324 | /** | ||
5325 | * snd_hda_get_pin_label - Get a label for the given I/O pin | ||
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 | } | 4925 | } |
5383 | if (!name) | ||
5384 | name = hda_get_input_pin_label(codec, nid, true); | ||
5385 | break; | ||
5386 | } | 4926 | } |
5387 | if (!name) | 4927 | if (cached) |
5388 | return 0; | 4928 | return snd_hda_codec_update_cache(codec, pin, 0, |
5389 | strlcpy(label, name, maxlen); | 4929 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); |
5390 | return 1; | 4930 | else |
4931 | return snd_hda_codec_write(codec, pin, 0, | ||
4932 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
5391 | } | 4933 | } |
5392 | EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); | 4934 | EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl); |
5393 | 4935 | ||
5394 | /** | 4936 | /** |
5395 | * snd_hda_add_imux_item - Add an item to input_mux | 4937 | * snd_hda_add_imux_item - Add an item to input_mux |
@@ -5444,8 +4986,6 @@ int snd_hda_suspend(struct hda_bus *bus) | |||
5444 | list_for_each_entry(codec, &bus->codec_list, list) { | 4986 | list_for_each_entry(codec, &bus->codec_list, list) { |
5445 | if (hda_codec_is_power_on(codec)) | 4987 | if (hda_codec_is_power_on(codec)) |
5446 | hda_call_codec_suspend(codec); | 4988 | hda_call_codec_suspend(codec); |
5447 | if (codec->patch_ops.post_suspend) | ||
5448 | codec->patch_ops.post_suspend(codec); | ||
5449 | } | 4989 | } |
5450 | return 0; | 4990 | return 0; |
5451 | } | 4991 | } |
@@ -5465,10 +5005,7 @@ int snd_hda_resume(struct hda_bus *bus) | |||
5465 | struct hda_codec *codec; | 5005 | struct hda_codec *codec; |
5466 | 5006 | ||
5467 | list_for_each_entry(codec, &bus->codec_list, list) { | 5007 | list_for_each_entry(codec, &bus->codec_list, list) { |
5468 | if (codec->patch_ops.pre_resume) | 5008 | hda_call_codec_resume(codec); |
5469 | codec->patch_ops.pre_resume(codec); | ||
5470 | if (snd_hda_codec_needs_resume(codec)) | ||
5471 | hda_call_codec_resume(codec); | ||
5472 | } | 5009 | } |
5473 | return 0; | 5010 | return 0; |
5474 | } | 5011 | } |