aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c144
1 files changed, 13 insertions, 131 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 52962f697825..b27f250088c1 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -929,9 +929,7 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
929 codec->proc_widget_hook = NULL; 929 codec->proc_widget_hook = NULL;
930 codec->spec = NULL; 930 codec->spec = NULL;
931 931
932 free_hda_cache(&codec->amp_cache);
933 free_hda_cache(&codec->cmd_cache); 932 free_hda_cache(&codec->cmd_cache);
934 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
935 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 933 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
936 934
937 /* free only driver_pins so that init_pins + user_pins are restored */ 935 /* free only driver_pins so that init_pins + user_pins are restored */
@@ -996,7 +994,6 @@ static void snd_hda_codec_dev_release(struct device *dev)
996 free_init_pincfgs(codec); 994 free_init_pincfgs(codec);
997 snd_hdac_device_exit(&codec->core); 995 snd_hdac_device_exit(&codec->core);
998 snd_hda_sysfs_clear(codec); 996 snd_hda_sysfs_clear(codec);
999 free_hda_cache(&codec->amp_cache);
1000 free_hda_cache(&codec->cmd_cache); 997 free_hda_cache(&codec->cmd_cache);
1001 kfree(codec->modelname); 998 kfree(codec->modelname);
1002 kfree(codec->wcaps); 999 kfree(codec->wcaps);
@@ -1051,7 +1048,6 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
1051 mutex_init(&codec->spdif_mutex); 1048 mutex_init(&codec->spdif_mutex);
1052 mutex_init(&codec->control_mutex); 1049 mutex_init(&codec->control_mutex);
1053 mutex_init(&codec->hash_mutex); 1050 mutex_init(&codec->hash_mutex);
1054 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
1055 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 1051 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
1056 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); 1052 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
1057 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); 1053 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
@@ -1380,67 +1376,6 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
1380 return info; 1376 return info;
1381} 1377}
1382 1378
1383/* query and allocate an amp hash entry */
1384static inline struct hda_amp_info *
1385get_alloc_amp_hash(struct hda_codec *codec, u32 key)
1386{
1387 return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key);
1388}
1389
1390/* overwrite the value with the key in the caps hash */
1391static int write_caps_hash(struct hda_codec *codec, u32 key, unsigned int val)
1392{
1393 struct hda_amp_info *info;
1394
1395 mutex_lock(&codec->hash_mutex);
1396 info = get_alloc_amp_hash(codec, key);
1397 if (!info) {
1398 mutex_unlock(&codec->hash_mutex);
1399 return -EINVAL;
1400 }
1401 info->amp_caps = val;
1402 info->head.val |= INFO_AMP_CAPS;
1403 mutex_unlock(&codec->hash_mutex);
1404 return 0;
1405}
1406
1407/* query the value from the caps hash; if not found, fetch the current
1408 * value from the given function and store in the hash
1409 */
1410static unsigned int
1411query_caps_hash(struct hda_codec *codec, hda_nid_t nid, int dir, u32 key,
1412 unsigned int (*func)(struct hda_codec *, hda_nid_t, int))
1413{
1414 struct hda_amp_info *info;
1415 unsigned int val;
1416
1417 mutex_lock(&codec->hash_mutex);
1418 info = get_alloc_amp_hash(codec, key);
1419 if (!info) {
1420 mutex_unlock(&codec->hash_mutex);
1421 return 0;
1422 }
1423 if (!(info->head.val & INFO_AMP_CAPS)) {
1424 mutex_unlock(&codec->hash_mutex); /* for reentrance */
1425 val = func(codec, nid, dir);
1426 write_caps_hash(codec, key, val);
1427 } else {
1428 val = info->amp_caps;
1429 mutex_unlock(&codec->hash_mutex);
1430 }
1431 return val;
1432}
1433
1434static unsigned int read_amp_cap(struct hda_codec *codec, hda_nid_t nid,
1435 int direction)
1436{
1437 if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
1438 nid = codec->core.afg;
1439 return snd_hda_param_read(codec, nid,
1440 direction == HDA_OUTPUT ?
1441 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
1442}
1443
1444/** 1379/**
1445 * query_amp_caps - query AMP capabilities 1380 * query_amp_caps - query AMP capabilities
1446 * @codec: the HD-auio codec 1381 * @codec: the HD-auio codec
@@ -1455,9 +1390,11 @@ static unsigned int read_amp_cap(struct hda_codec *codec, hda_nid_t nid,
1455 */ 1390 */
1456u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) 1391u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
1457{ 1392{
1458 return query_caps_hash(codec, nid, direction, 1393 if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
1459 HDA_HASH_KEY(nid, direction, 0), 1394 nid = codec->core.afg;
1460 read_amp_cap); 1395 return snd_hda_param_read(codec, nid,
1396 direction == HDA_OUTPUT ?
1397 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
1461} 1398}
1462EXPORT_SYMBOL_GPL(query_amp_caps); 1399EXPORT_SYMBOL_GPL(query_amp_caps);
1463 1400
@@ -1498,50 +1435,14 @@ EXPORT_SYMBOL_GPL(snd_hda_check_amp_caps);
1498int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 1435int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
1499 unsigned int caps) 1436 unsigned int caps)
1500{ 1437{
1501 return write_caps_hash(codec, HDA_HASH_KEY(nid, dir, 0), caps); 1438 unsigned int parm;
1502}
1503EXPORT_SYMBOL_GPL(snd_hda_override_amp_caps);
1504
1505static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid,
1506 int dir)
1507{
1508 return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
1509}
1510
1511/**
1512 * snd_hda_query_pin_caps - Query PIN capabilities
1513 * @codec: the HD-auio codec
1514 * @nid: the NID to query
1515 *
1516 * Query PIN capabilities for the given widget.
1517 * Returns the obtained capability bits.
1518 *
1519 * When cap bits have been already read, this doesn't read again but
1520 * returns the cached value.
1521 */
1522u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
1523{
1524 return query_caps_hash(codec, nid, 0, HDA_HASH_PINCAP_KEY(nid),
1525 read_pin_cap);
1526}
1527EXPORT_SYMBOL_GPL(snd_hda_query_pin_caps);
1528 1439
1529/** 1440 snd_hda_override_wcaps(codec, nid,
1530 * snd_hda_override_pin_caps - Override the pin capabilities 1441 get_wcaps(codec, nid) | AC_WCAP_AMP_OVRD);
1531 * @codec: the CODEC 1442 parm = dir == HDA_OUTPUT ? AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP;
1532 * @nid: the NID to override 1443 return snd_hdac_override_parm(&codec->core, nid, parm, caps);
1533 * @caps: the capability bits to set
1534 *
1535 * Override the cached PIN capabilitiy bits value by the given one.
1536 *
1537 * Returns zero if successful or a negative error code.
1538 */
1539int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
1540 unsigned int caps)
1541{
1542 return write_caps_hash(codec, HDA_HASH_PINCAP_KEY(nid), caps);
1543} 1444}
1544EXPORT_SYMBOL_GPL(snd_hda_override_pin_caps); 1445EXPORT_SYMBOL_GPL(snd_hda_override_amp_caps);
1545 1446
1546/** 1447/**
1547 * snd_hda_codec_amp_stereo - update the AMP stereo values 1448 * snd_hda_codec_amp_stereo - update the AMP stereo values
@@ -3462,11 +3363,6 @@ static void hda_mark_cmd_cache_dirty(struct hda_codec *codec)
3462 cmd = snd_array_elem(&codec->cmd_cache.buf, i); 3363 cmd = snd_array_elem(&codec->cmd_cache.buf, i);
3463 cmd->dirty = 1; 3364 cmd->dirty = 1;
3464 } 3365 }
3465 for (i = 0; i < codec->amp_cache.buf.used; i++) {
3466 struct hda_amp_info *amp;
3467 amp = snd_array_elem(&codec->amp_cache.buf, i);
3468 amp->head.dirty = 1;
3469 }
3470} 3366}
3471 3367
3472/* 3368/*
@@ -3714,8 +3610,7 @@ unsigned int snd_hda_calc_stream_format(struct hda_codec *codec,
3714} 3610}
3715EXPORT_SYMBOL_GPL(snd_hda_calc_stream_format); 3611EXPORT_SYMBOL_GPL(snd_hda_calc_stream_format);
3716 3612
3717static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid, 3613static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
3718 int dir)
3719{ 3614{
3720 unsigned int val = 0; 3615 unsigned int val = 0;
3721 if (nid != codec->core.afg && 3616 if (nid != codec->core.afg &&
@@ -3728,14 +3623,7 @@ static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid,
3728 return val; 3623 return val;
3729} 3624}
3730 3625
3731static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) 3626static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
3732{
3733 return query_caps_hash(codec, nid, 0, HDA_HASH_PARPCM_KEY(nid),
3734 get_pcm_param);
3735}
3736
3737static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid,
3738 int dir)
3739{ 3627{
3740 unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); 3628 unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
3741 if (!streams || streams == -1) 3629 if (!streams || streams == -1)
@@ -3745,12 +3633,6 @@ static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid,
3745 return streams; 3633 return streams;
3746} 3634}
3747 3635
3748static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
3749{
3750 return query_caps_hash(codec, nid, 0, HDA_HASH_PARSTR_KEY(nid),
3751 get_stream_param);
3752}
3753
3754/** 3636/**
3755 * snd_hda_query_supported_pcm - query the supported PCM rates and formats 3637 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
3756 * @codec: the HDA codec 3638 * @codec: the HDA codec