diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-10-17 10:50:59 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-10-17 17:39:33 -0400 |
commit | 1bb7e43e22c90262d0fe9a1849a9268b157048f6 (patch) | |
tree | bf57474d2177b26bf06cb2a33f867752952e786e /sound/pci | |
parent | e16fb6d1408bca0c0b36d490688eba3dc924b1fd (diff) |
ALSA: hda/realtek - Cache COEF 0 value
The COEF #0 value represents a sort of device id, so it's supposedly
constant while operation. Better to use the cached value instead of
reading it at each time from the performance POV.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ab6b9fa203d0..f9d24c33ce93 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -197,6 +197,7 @@ struct alc_spec { | |||
197 | /* for PLL fix */ | 197 | /* for PLL fix */ |
198 | hda_nid_t pll_nid; | 198 | hda_nid_t pll_nid; |
199 | unsigned int pll_coef_idx, pll_coef_bit; | 199 | unsigned int pll_coef_idx, pll_coef_bit; |
200 | unsigned int coef0; | ||
200 | 201 | ||
201 | /* fix-up list */ | 202 | /* fix-up list */ |
202 | int fixup_id; | 203 | int fixup_id; |
@@ -1554,6 +1555,15 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, | |||
1554 | coef_val); | 1555 | coef_val); |
1555 | } | 1556 | } |
1556 | 1557 | ||
1558 | /* a special bypass for COEF 0; read the cached value at the second time */ | ||
1559 | static unsigned int alc_get_coef0(struct hda_codec *codec) | ||
1560 | { | ||
1561 | struct alc_spec *spec = codec->spec; | ||
1562 | if (!spec->coef0) | ||
1563 | spec->coef0 = alc_read_coef_idx(codec, 0); | ||
1564 | return spec->coef0; | ||
1565 | } | ||
1566 | |||
1557 | /* | 1567 | /* |
1558 | * Digital I/O handling | 1568 | * Digital I/O handling |
1559 | */ | 1569 | */ |
@@ -2510,13 +2520,11 @@ static struct alc_codec_rename_table rename_tbl[] = { | |||
2510 | static int alc_codec_rename_from_preset(struct hda_codec *codec) | 2520 | static int alc_codec_rename_from_preset(struct hda_codec *codec) |
2511 | { | 2521 | { |
2512 | const struct alc_codec_rename_table *p; | 2522 | const struct alc_codec_rename_table *p; |
2513 | unsigned short coef; | ||
2514 | 2523 | ||
2515 | for (p = rename_tbl; p->vendor_id; p++) { | 2524 | for (p = rename_tbl; p->vendor_id; p++) { |
2516 | if (p->vendor_id != codec->vendor_id) | 2525 | if (p->vendor_id != codec->vendor_id) |
2517 | continue; | 2526 | continue; |
2518 | coef = alc_read_coef_idx(codec, 0); | 2527 | if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) |
2519 | if ((coef & p->coef_mask) == p->coef_bits) | ||
2520 | return alc_codec_rename(codec, p->name); | 2528 | return alc_codec_rename(codec, p->name); |
2521 | } | 2529 | } |
2522 | return 0; | 2530 | return 0; |
@@ -4613,9 +4621,9 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) | |||
4613 | 4621 | ||
4614 | static void alc269_shutup(struct hda_codec *codec) | 4622 | static void alc269_shutup(struct hda_codec *codec) |
4615 | { | 4623 | { |
4616 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) | 4624 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) |
4617 | alc269_toggle_power_output(codec, 0); | 4625 | alc269_toggle_power_output(codec, 0); |
4618 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 4626 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
4619 | alc269_toggle_power_output(codec, 0); | 4627 | alc269_toggle_power_output(codec, 0); |
4620 | msleep(150); | 4628 | msleep(150); |
4621 | } | 4629 | } |
@@ -4624,19 +4632,19 @@ static void alc269_shutup(struct hda_codec *codec) | |||
4624 | #ifdef CONFIG_PM | 4632 | #ifdef CONFIG_PM |
4625 | static int alc269_resume(struct hda_codec *codec) | 4633 | static int alc269_resume(struct hda_codec *codec) |
4626 | { | 4634 | { |
4627 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 4635 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
4628 | alc269_toggle_power_output(codec, 0); | 4636 | alc269_toggle_power_output(codec, 0); |
4629 | msleep(150); | 4637 | msleep(150); |
4630 | } | 4638 | } |
4631 | 4639 | ||
4632 | codec->patch_ops.init(codec); | 4640 | codec->patch_ops.init(codec); |
4633 | 4641 | ||
4634 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | 4642 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
4635 | alc269_toggle_power_output(codec, 1); | 4643 | alc269_toggle_power_output(codec, 1); |
4636 | msleep(200); | 4644 | msleep(200); |
4637 | } | 4645 | } |
4638 | 4646 | ||
4639 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) | 4647 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) |
4640 | alc269_toggle_power_output(codec, 1); | 4648 | alc269_toggle_power_output(codec, 1); |
4641 | 4649 | ||
4642 | snd_hda_codec_resume_amp(codec); | 4650 | snd_hda_codec_resume_amp(codec); |
@@ -4954,23 +4962,23 @@ static int alc269_fill_coef(struct hda_codec *codec) | |||
4954 | { | 4962 | { |
4955 | int val; | 4963 | int val; |
4956 | 4964 | ||
4957 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { | 4965 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
4958 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4966 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4959 | alc_write_coef_idx(codec, 0xe, 0x8817); | 4967 | alc_write_coef_idx(codec, 0xe, 0x8817); |
4960 | } | 4968 | } |
4961 | 4969 | ||
4962 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { | 4970 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { |
4963 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4971 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4964 | alc_write_coef_idx(codec, 0xe, 0x8814); | 4972 | alc_write_coef_idx(codec, 0xe, 0x8814); |
4965 | } | 4973 | } |
4966 | 4974 | ||
4967 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | 4975 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
4968 | val = alc_read_coef_idx(codec, 0x04); | 4976 | val = alc_read_coef_idx(codec, 0x04); |
4969 | /* Power up output pin */ | 4977 | /* Power up output pin */ |
4970 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | 4978 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); |
4971 | } | 4979 | } |
4972 | 4980 | ||
4973 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 4981 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
4974 | val = alc_read_coef_idx(codec, 0xd); | 4982 | val = alc_read_coef_idx(codec, 0xd); |
4975 | if ((val & 0x0c00) >> 10 != 0x1) { | 4983 | if ((val & 0x0c00) >> 10 != 0x1) { |
4976 | /* Capless ramp up clock control */ | 4984 | /* Capless ramp up clock control */ |
@@ -5014,21 +5022,23 @@ static int patch_alc269(struct hda_codec *codec) | |||
5014 | goto error; | 5022 | goto error; |
5015 | 5023 | ||
5016 | if (codec->vendor_id == 0x10ec0269) { | 5024 | if (codec->vendor_id == 0x10ec0269) { |
5017 | unsigned int coef; | ||
5018 | spec->codec_variant = ALC269_TYPE_ALC269VA; | 5025 | spec->codec_variant = ALC269_TYPE_ALC269VA; |
5019 | coef = alc_read_coef_idx(codec, 0); | 5026 | switch (alc_get_coef0(codec) & 0x00f0) { |
5020 | if ((coef & 0x00f0) == 0x0010) { | 5027 | case 0x0010: |
5021 | if (codec->bus->pci->subsystem_vendor == 0x1025 && | 5028 | if (codec->bus->pci->subsystem_vendor == 0x1025 && |
5022 | spec->cdefine.platform_type == 1) | 5029 | spec->cdefine.platform_type == 1) |
5023 | err = alc_codec_rename(codec, "ALC271X"); | 5030 | err = alc_codec_rename(codec, "ALC271X"); |
5024 | spec->codec_variant = ALC269_TYPE_ALC269VB; | 5031 | spec->codec_variant = ALC269_TYPE_ALC269VB; |
5025 | } else if ((coef & 0x00f0) == 0x0020) { | 5032 | break; |
5033 | case 0x0020: | ||
5026 | if (codec->bus->pci->subsystem_vendor == 0x17aa && | 5034 | if (codec->bus->pci->subsystem_vendor == 0x17aa && |
5027 | codec->bus->pci->subsystem_device == 0x21f3) | 5035 | codec->bus->pci->subsystem_device == 0x21f3) |
5028 | err = alc_codec_rename(codec, "ALC3202"); | 5036 | err = alc_codec_rename(codec, "ALC3202"); |
5029 | spec->codec_variant = ALC269_TYPE_ALC269VC; | 5037 | spec->codec_variant = ALC269_TYPE_ALC269VC; |
5030 | } else | 5038 | break; |
5039 | default: | ||
5031 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 5040 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
5041 | } | ||
5032 | if (err < 0) | 5042 | if (err < 0) |
5033 | goto error; | 5043 | goto error; |
5034 | alc269_fill_coef(codec); | 5044 | alc269_fill_coef(codec); |
@@ -5615,7 +5625,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
5615 | { | 5625 | { |
5616 | struct alc_spec *spec; | 5626 | struct alc_spec *spec; |
5617 | int err = 0; | 5627 | int err = 0; |
5618 | int coef; | ||
5619 | 5628 | ||
5620 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5629 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5621 | if (!spec) | 5630 | if (!spec) |
@@ -5636,8 +5645,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
5636 | if (err < 0) | 5645 | if (err < 0) |
5637 | goto error; | 5646 | goto error; |
5638 | 5647 | ||
5639 | coef = alc_read_coef_idx(codec, 0); | 5648 | if ((alc_get_coef0(codec) & (1 << 14)) && |
5640 | if (coef & (1 << 14) && | ||
5641 | codec->bus->pci->subsystem_vendor == 0x1025 && | 5649 | codec->bus->pci->subsystem_vendor == 0x1025 && |
5642 | spec->cdefine.platform_type == 1) { | 5650 | spec->cdefine.platform_type == 1) { |
5643 | if (alc_codec_rename(codec, "ALC272X") < 0) | 5651 | if (alc_codec_rename(codec, "ALC272X") < 0) |