diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2016-02-25 15:24:46 -0800 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2016-02-25 15:24:46 -0800 |
commit | c56482b2363615d35a9f4241c0e9069c69085536 (patch) | |
tree | 5244195224bbbe75e5ff223e81fb735872a360b9 /arch | |
parent | a9e6324c87ee7357211714d95da44036bbca9789 (diff) |
ARM: dts: vf610: do not control reset line on warm reset
When entering and resuming from suspend-to-RAM (LPSTOP2), the
current pinmux and the automatic restore of the last GPIO state
lead to an "uncontrolled" hard reset. The wm9712 driver tries
to warm reset the codec, which succeeds due to the previous
hard reset. Since the warm reset succeeded, the wm9712 driver
will not restore the codecs registers, hence those will
accidentially stay in reset state.
To avoid this extra hard reset we need to leave the pad floating
during suspend (the external pull-down will make sure that the
line has a defined state). After suspend snd_soc_ac97_warm_reset
will request the pinctrl states "ac97-warm-reset" and "ac97-running",
we need to make sure that both states do not change the state of
the reset line since it would introduce a similar "uncontrolled"
hard reset. Therefor, remove pinctrl configurations for those
states.
With this change, we disable the output driver of the reset signal
when entering suspend mode ("sleep" pinctrl state).
Current Colibri VF61 1.2A module have an external pull-down, hence
the reset signal will be low during suspend. With this change, the
reset signal will stay low during resume even when the GPIO state
gets restored (since the output driver is still disabled). This
will keep the codec in reset, and the wm9712 drivers warm reset will
fail. The driver will fall back to an explicit cold reset and due
to the cold reset restore the registers properly.
Future Colibri VF61 modules could use an external pull-up. This
would mean that the warm reset on resume will succeed, and the
driver would not need to restore the registers.
Note: pinctrl with the AC97 pin states is rather delicate. It seems
that when playing audio, the stack always selects the "default"
state. Before, the "running" state has been used as "default" state.
However, the "running" state is harmful during boot for initial cold
reset (maybe test mode?). Therefor we use a minimalistic "default"
pinmux. Only when the stack explicitily requests "running", we
actually mux the real functions on the affected pins.
Note 2: If there is a pull-up, we relly on the pull-up after suspend
and resume since the cold reset function does not explicitly set the
GPIO again...
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boot/dts/vf610-colibri.dtsi | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi index 09d46c34fc23..0bd1f7ceb53d 100644 --- a/arch/arm/boot/dts/vf610-colibri.dtsi +++ b/arch/arm/boot/dts/vf610-colibri.dtsi @@ -43,13 +43,13 @@ &sai2 { compatible = "fsl,vf610-sai-ac97"; #sound-dai-cells = <0>; - - pinctrl-names = "default", "ac97-running", "ac97-reset", + pinctrl-names = "default", "sleep", "ac97-running", "ac97-reset", "ac97-warm-reset"; - pinctrl-0 = <&pinctrl_sai2_ac97_running>; - pinctrl-1 = <&pinctrl_sai2_ac97_running>; - pinctrl-2 = <&pinctrl_sai2_ac97_reset>; + pinctrl-0 = <&pinctrl_sai2_ac97_default>; + pinctrl-1 = <&pinctrl_sai2_ac97_sleep>; + pinctrl-2 = <&pinctrl_sai2_ac97_running>; pinctrl-3 = <&pinctrl_sai2_ac97_reset>; + pinctrl-4 = <&pinctrl_sai2_ac97_warm_reset>; ac97-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH &gpio0 8 GPIO_ACTIVE_HIGH &gpio0 13 GPIO_ACTIVE_HIGH>; status = "okay"; @@ -62,20 +62,25 @@ VF610_PAD_PTB23__SAI0_TX_BCLK 0x31C3 >; }; - pinctrl_sai2_ac97_reset: sai2grp_1 { + + pinctrl_sai2_ac97_default: sai2grp_1 { fsl,pins = < /* Pen-down */ VF610_PAD_PTA11__GPIO_4 0x22ed - /* AC97 SData Out (test mode selection) */ - VF610_PAD_PTA18__GPIO_8 0x22ed - /* AC97 Sync (warm reset) */ - VF610_PAD_PTA19__GPIO_9 0x22ed - /* AC97 Reset (cold reset) */ - VF610_PAD_PTA23__GPIO_13 0x22eb + + /* GenIRQ */ + VF610_PAD_PTB2__GPIO_24 0x22e1 >; }; - pinctrl_sai2_ac97_running: sai2grp_2 { + pinctrl_sai2_ac97_sleep: sai2grp_2 { + fsl,pins = < + /* AC97 Reset (cold reset) floating */ + VF610_PAD_PTA23__GPIO_13 0x22c1 + >; + }; + + pinctrl_sai2_ac97_running: sai2grp_3 { fsl,pins = < /* AC97 Bit clock */ VF610_PAD_PTA16__SAI2_TX_BCLK 0x31C3 @@ -88,13 +93,34 @@ /* AC97 SData In */ VF610_PAD_PTA22__SAI2_RX_DATA 0x0041 + >; + }; - /* AC97 Reset (cold reset, keep output buffer on) */ - VF610_PAD_PTA23__GPIO_13 0x22eb + pinctrl_sai2_ac97_reset: sai2grp_4 { + fsl,pins = < + VF610_PAD_PTA16__SAI2_TX_BCLK 0x31C1 - /* GenIRQ */ - VF610_PAD_PTB2__GPIO_24 0x22ed + /* AC97 SData Out (test mode selection) */ + VF610_PAD_PTA18__GPIO_8 0x22c1 + + /* AC97 Sync (warm reset) */ + VF610_PAD_PTA19__GPIO_9 0x22c1 + + /* AC97 Reset (cold reset) */ + VF610_PAD_PTA23__GPIO_13 0x22c1 + >; + }; + + pinctrl_sai2_ac97_warm_reset: sai2grp_5 { + fsl,pins = < + /* AC97 SData Out (test mode selection) */ + VF610_PAD_PTA18__GPIO_8 0x22c1 + + /* AC97 Sync (warm reset) */ + VF610_PAD_PTA19__GPIO_9 0x22c1 >; }; + + }; }; |