From patchwork Fri Apr 14 16:40:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 9681443 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7A89C60388 for ; Fri, 14 Apr 2017 16:51:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 69E95286C7 for ; Fri, 14 Apr 2017 16:51:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5BEE0286D1; Fri, 14 Apr 2017 16:51:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=no version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5FC6286CB for ; Fri, 14 Apr 2017 16:51:22 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 48BA226720B; Fri, 14 Apr 2017 18:41:15 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 9770E26720C; Fri, 14 Apr 2017 18:41:13 +0200 (CEST) Received: from mail-pg0-f54.google.com (mail-pg0-f54.google.com [74.125.83.54]) by alsa0.perex.cz (Postfix) with ESMTP id 431B12671F3 for ; Fri, 14 Apr 2017 18:41:05 +0200 (CEST) Received: by mail-pg0-f54.google.com with SMTP id 72so37058191pge.2 for ; Fri, 14 Apr 2017 09:41:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6kBoQ22MC54yxdPW8+uF1Rp+s2tmNA7S7oSfmqqNwlg=; b=M9yIZVBwe+6eXOfnSpfDSiSGOzb5onc4m7fLce4cqLMZLNArLYBDghF2HSL1yXo7TE xhNh+WLI7SDBjihlIV3iVg64TpZOkTuelTD8New9S8DqN0V63gNT86IndDMTz5e+oSbA XygvOibqxFuFTMnTczso+hHSOKv8+p1wVTwdg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6kBoQ22MC54yxdPW8+uF1Rp+s2tmNA7S7oSfmqqNwlg=; b=kG3cU5W2PoZAoaseBwAHhZZAJPWnaQrXMIZfujEi1ekk4YSkzgwyJgRTsX1KWKL6Uj FnlGrToEmON36nzoB7HyTJoTOVySPyPoM2XuoLNCbHZSG3fo/BC+VIgccXh7bRQMoSX8 mOZKiOdAi9tpbBGULUvXSca4c/tcF9PTIZxVRYkl2v9278pwg19yl7SGHTk17tsijy2Z 6VF1pTZJU68538r/C1vuowsJR0EDOw92zw4TerOErDHw6WstMtl9BQUFXNStuw5rRSx6 EpMT1+UmermZPJNeRN/RPlUHa94iEi1h4OoehXdw136qaVCS9x/ITZFkr2vblu0OZYi1 QRHg== X-Gm-Message-State: AN3rC/6xDQf9+Mu84IMt49wyhKFfXLB2QOFAhzgFzawVAAYsrLhUgIsN 5ND6e/Tje9+eF540 X-Received: by 10.98.107.194 with SMTP id g185mr8013521pfc.22.1492188063002; Fri, 14 Apr 2017 09:41:03 -0700 (PDT) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by smtp.gmail.com with ESMTPSA id h25sm4206166pfk.119.2017.04.14.09.41.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 14 Apr 2017 09:41:02 -0700 (PDT) From: Douglas Anderson To: bardliao@realtek.com, oder_chiou@realtek.com Date: Fri, 14 Apr 2017 09:40:32 -0700 Message-Id: <20170414164033.11681-3-dianders@chromium.org> X-Mailer: git-send-email 2.12.2.762.g0e3151a226-goog In-Reply-To: <20170414164033.11681-1-dianders@chromium.org> References: <20170414164033.11681-1-dianders@chromium.org> Cc: alsa-devel@alsa-project.org, Douglas Anderson , lgirdwood@gmail.com, linux-kernel@vger.kernel.org, tiwai@suse.com, broonie@kernel.org Subject: [alsa-devel] [PATCH 3/3] ASoC: rt5514: Unconfuse the rt5514 at probe / resume time X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP The rt5514 can get confused and incorrectly detect a start bit if the SCL/SDA lines happen to both go low and then high again. This situation has been seen to happen at reboot time and is also theoretically possible during suspend/resume if the rt5514 keeps power but we shut down the i2c connection. When this happens the rt5514 is confused about the state of the i2c bus and won't recognize its own address. That will lead to the rt5514 incorrectly NAKing the first transfer. A single i2c transfer to any address should be enough to get the rt5514 out of this funky state. It is currently believed that this problem should be fixed in the rt5514 driver itself because it seems that the i2c controller in the rt5514 is easily confused. Most i2c devices wouldn't detect a start bit in this case. Signed-off-by: Douglas Anderson --- sound/soc/codecs/rt5514.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 969a05620e04..f91221b1ddf0 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -1084,6 +1084,21 @@ static int rt5514_parse_dt(struct rt5514_priv *rt5514, struct device *dev) return 0; } +static __maybe_unused int rt5514_i2c_resume(struct device *dev) +{ + struct rt5514_priv *rt5514 = dev_get_drvdata(dev); + unsigned int val; + + /* + * Add a bogus read to avoid rt5514's confusion after s2r in case it + * saw glitches on the i2c lines and thought the other side sent a + * start bit. + */ + regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); + + return 0; +} + static int rt5514_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1120,7 +1135,15 @@ static int rt5514_i2c_probe(struct i2c_client *i2c, return ret; } + /* + * The rt5514 can get confused if the i2c lines glitch together, as + * can happen at bootup as regulators are turned off and on. If it's + * in this glitched state the first i2c read will fail, so we'll give + * it one change to retry. + */ ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); + if (ret || val != RT5514_DEVICE_ID) + ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); if (ret || val != RT5514_DEVICE_ID) { dev_err(&i2c->dev, "Device with ID register %x is not rt5514\n", val); @@ -1149,10 +1172,15 @@ static int rt5514_i2c_remove(struct i2c_client *i2c) return 0; } +static const struct dev_pm_ops rt5514_i2_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume) +}; + static struct i2c_driver rt5514_i2c_driver = { .driver = { .name = "rt5514", .of_match_table = of_match_ptr(rt5514_of_match), + .pm = &rt5514_i2_pm_ops, }, .probe = rt5514_i2c_probe, .remove = rt5514_i2c_remove,