diff options
| -rw-r--r-- | sound/pci/hda/patch_cirrus.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 4ef5efaaaef1..488fd9ade1ba 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
| @@ -972,6 +972,53 @@ static struct hda_verb cs_coef_init_verbs[] = { | |||
| 972 | {} /* terminator */ | 972 | {} /* terminator */ |
| 973 | }; | 973 | }; |
| 974 | 974 | ||
| 975 | /* Errata: CS4207 rev C0/C1/C2 Silicon | ||
| 976 | * | ||
| 977 | * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf | ||
| 978 | * | ||
| 979 | * 6. At high temperature (TA > +85°C), the digital supply current (IVD) | ||
| 980 | * may be excessive (up to an additional 200 μA), which is most easily | ||
| 981 | * observed while the part is being held in reset (RESET# active low). | ||
| 982 | * | ||
| 983 | * Root Cause: At initial powerup of the device, the logic that drives | ||
| 984 | * the clock and write enable to the S/PDIF SRC RAMs is not properly | ||
| 985 | * initialized. | ||
| 986 | * Certain random patterns will cause a steady leakage current in those | ||
| 987 | * RAM cells. The issue will resolve once the SRCs are used (turned on). | ||
| 988 | * | ||
| 989 | * Workaround: The following verb sequence briefly turns on the S/PDIF SRC | ||
| 990 | * blocks, which will alleviate the issue. | ||
| 991 | */ | ||
| 992 | |||
| 993 | static struct hda_verb cs_errata_init_verbs[] = { | ||
| 994 | {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ | ||
| 995 | {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ | ||
| 996 | |||
| 997 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0008}, | ||
| 998 | {0x11, AC_VERB_SET_PROC_COEF, 0x9999}, | ||
| 999 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0017}, | ||
| 1000 | {0x11, AC_VERB_SET_PROC_COEF, 0xa412}, | ||
| 1001 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0001}, | ||
| 1002 | {0x11, AC_VERB_SET_PROC_COEF, 0x0009}, | ||
| 1003 | |||
| 1004 | {0x07, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Rx: D0 */ | ||
| 1005 | {0x08, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Tx: D0 */ | ||
| 1006 | |||
| 1007 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0017}, | ||
| 1008 | {0x11, AC_VERB_SET_PROC_COEF, 0x2412}, | ||
| 1009 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0008}, | ||
| 1010 | {0x11, AC_VERB_SET_PROC_COEF, 0x0000}, | ||
| 1011 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0001}, | ||
| 1012 | {0x11, AC_VERB_SET_PROC_COEF, 0x0008}, | ||
| 1013 | {0x11, AC_VERB_SET_PROC_STATE, 0x00}, | ||
| 1014 | |||
| 1015 | {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */ | ||
| 1016 | {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */ | ||
| 1017 | /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */ | ||
| 1018 | |||
| 1019 | {} /* terminator */ | ||
| 1020 | }; | ||
| 1021 | |||
| 975 | /* SPDIF setup */ | 1022 | /* SPDIF setup */ |
| 976 | static void init_digital(struct hda_codec *codec) | 1023 | static void init_digital(struct hda_codec *codec) |
| 977 | { | 1024 | { |
| @@ -991,6 +1038,9 @@ static int cs_init(struct hda_codec *codec) | |||
| 991 | { | 1038 | { |
| 992 | struct cs_spec *spec = codec->spec; | 1039 | struct cs_spec *spec = codec->spec; |
| 993 | 1040 | ||
| 1041 | /* init_verb sequence for C0/C1/C2 errata*/ | ||
| 1042 | snd_hda_sequence_write(codec, cs_errata_init_verbs); | ||
| 1043 | |||
| 994 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | 1044 | snd_hda_sequence_write(codec, cs_coef_init_verbs); |
| 995 | 1045 | ||
| 996 | if (spec->gpio_mask) { | 1046 | if (spec->gpio_mask) { |
