• John Keeping's avatar
    ASoC: rockchip: i2s: fix playback after runtime resume · c66234cf
    John Keeping authored
    When restoring registers during runtime resume, we must not write to
    I2S_TXDR which is the transmit FIFO as this queues up a sample to be
    output and pushes all of the output channels down by one.
    
    This can be demonstrated with the speaker-test utility:
    
    	for i in a b c; do speaker-test -c 2 -s 1; done
    
    which should play a test through the left speaker three times but if the
    I2S hardware starts runtime suspended the first sample will be played
    through the right speaker.
    
    Fix this by marking I2S_TXDR as volatile (which also requires marking it
    as readble, even though it technically isn't).  This seems to be the
    most robust fix, the alternative of giving I2S_TXDR a default value is
    more fragile since it does not prevent regcache writing to the register
    in all circumstances.
    
    While here, also fix the configuration of I2S_RXDR and I2S_FIFOLR; these
    are not writable so they do not suffer from the same problem as I2S_TXDR
    but reading from I2S_RXDR does suffer from a similar problem.
    
    Fixes: f0447f6c ("ASoC: rockchip: i2s: restore register during runtime_suspend/resume cycle", 2016-09-07)
    Signed-off-by: default avatarJohn Keeping <john@metanate.com>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    Cc: stable@vger.kernel.org
    c66234cf
rockchip_i2s.c 16.6 KB