From patchwork Wed Feb 14 22:02:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Lai X-Patchwork-Id: 10220019 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 8D46F605BA for ; Wed, 14 Feb 2018 22:03:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 78FA221F61 for ; Wed, 14 Feb 2018 22:03:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D63C288B4; Wed, 14 Feb 2018 22:03:25 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2098E21F61 for ; Wed, 14 Feb 2018 22:03:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1031527AbeBNWDT (ORCPT ); Wed, 14 Feb 2018 17:03:19 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:53013 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031487AbeBNWDS (ORCPT ); Wed, 14 Feb 2018 17:03:18 -0500 Received: by mail-wm0-f65.google.com with SMTP id j199so13321065wmj.2 for ; Wed, 14 Feb 2018 14:03:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=richardman-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=h6UG8Hw0VySO3N62YZEAMjqkzctQ+A3PwPUqTt1olDQ=; b=WqPMPZFvm9pDOn9ZSyUab/nEduU+f4QiELNKugLSfDT2BYUV51l6gpr13io+WsqV0S 7W3bNmXhwuLPB4cHgokRUeaKa+zpFq9n4YNLIroV39z2Wo75m6HT9BRWLnRhcAw+YApV M29G30jz0d9KHHiA31FceJXPss49G/CzNK73wfeANXsUQVbixFp4NUubO+kactWlbsdh XTQxgX5NmPtUXk1OgKNvGyUEeHWS18KVcMQurmpZu4tl7uvIsTctSeijyUcCxBXXVIfG PS/UJVtj/+z4igz4gqIjIiwZC2vJgxOkJ06bKUOWiD75FE0nc/m53W0hKb9EJEwV21Dv vFQw== 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; bh=h6UG8Hw0VySO3N62YZEAMjqkzctQ+A3PwPUqTt1olDQ=; b=sxnZVgM6yALLCvI3SSPQON97KP24omCuwM4NrHqJGgpk58pCuORML2sWlooGkEYajl nuJ07+g4WLCRJ6rY489LYaek1mFHfX63nTrsqsbGqYOMlFAHpNyFBKHIye/s9SADgo/T VONfyOYHp8pNW031cogWC0wy2Uivq4tQUr80euLi026WHyDlbVDV5LzJLCF/mkC+ttjf 26a01jMd1L9zO0eQaeP7XJti6/9BoMihaEAFDDMawRaBwQOVq/CmdR/NE2VgAb1Ju8Fr 7C/XowOPom876VAkyf48GAfpa/K0aVHhoKN2orX/pZrZF/tZ8zfG/UtEYbmFqF9KvDC5 RpIA== X-Gm-Message-State: APf1xPAblYbwskTObmB3QvNBbGqfMdAz3LRsQDeu6yRNWszGYaL6pKRT kkBMtAAhIwrqyxFOhnn2lI89dhJeR5k= X-Google-Smtp-Source: AH8x226cVHTeHM8wohYxVN4ZIJULiKvxeeLKgEZ5lNMGNECfyKC+ZAFUS2QEDEiQ10YO48neB0lzXA== X-Received: by 10.28.84.14 with SMTP id i14mr383502wmb.30.1518645796908; Wed, 14 Feb 2018 14:03:16 -0800 (PST) Received: from RICHARDMAN.localdomain (cpc91232-cmbg18-2-0-cust493.5-4.cable.virginm.net. [82.2.125.238]) by smtp.gmail.com with ESMTPSA id 63sm13989177wms.46.2018.02.14.14.03.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 14 Feb 2018 14:03:16 -0800 (PST) From: Richard Lai Cc: richard@richardman.com, Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] iio: chemical: ccs811: Corrected firmware boot/application mode transition Date: Wed, 14 Feb 2018 22:02:36 +0000 Message-Id: <1518645768-2908-1-git-send-email-richard@richardman.com> X-Mailer: git-send-email 2.7.4 To: unlisted-recipients:; (no To-header on input) Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP CCS811 has different I2C register maps in boot and application mode. When CCS811 is in boot mode, register APP_START (0xF4) is used to transit the firmware state from boot to application mode. However, APP_START is not a valid register location when CCS811 is in application mode (refer to "CCS811 Bootloader Register Map" and "CCS811 Application Register Map" in CCS811 datasheet). The driver should not attempt to perform a write to APP_START while CCS811 is in application mode, as this is not a valid or documented register location. When prob function is being called, the driver assumes the CCS811 sensor is in boot mode, and attempts to perform a write to APP_START. Although CCS811 powers-up in boot mode, it may have already been transited to application mode by previous instances, e.g. unload and reload device driver by the system, or explicitly by user. Depending on the system design, CCS811 sensor may be permanently connected to system power source rather than power controlled by GPIO, hence it is possible that the sensor is never power reset, thus the firmware could be in either boot or application mode at any given time when driver prob function is being called. This patch: 1) Checks the STATUS register before attempting to send a write to APP_START. Only if the firmware is not in application mode and has valid firmware application loaded, then it will continue to start transiting the firmware boot to application mode. 2) Adds two macros for checking APP_VALID and FW_MODE bits in the STATUS register of CCS811 sensor. Signed-off-by: Richard Lai --- drivers/iio/chemical/ccs811.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/iio/chemical/ccs811.c b/drivers/iio/chemical/ccs811.c index 840a6cb..4806aed 100644 --- a/drivers/iio/chemical/ccs811.c +++ b/drivers/iio/chemical/ccs811.c @@ -52,6 +52,11 @@ #define CCS811_STATUS_FW_MODE_MASK BIT(7) #define CCS811_STATUS_FW_MODE_APPLICATION BIT(7) +#define IS_APP_VALID_LOADED(x) \ + (CCS811_STATUS_APP_VALID_LOADED == (CCS811_STATUS_APP_VALID_MASK & x)) +#define IS_FW_MODE_APPLICATION(x) \ + (CCS811_STATUS_FW_MODE_APPLICATION == (CCS811_STATUS_FW_MODE_MASK & x)) + /* Measurement modes */ #define CCS811_MODE_IDLE 0x00 #define CCS811_MODE_IAQ_1SEC 0x10 @@ -129,8 +134,10 @@ static int ccs811_start_sensor_application(struct i2c_client *client) if (ret < 0) return ret; - if ((ret & CCS811_STATUS_APP_VALID_MASK) != - CCS811_STATUS_APP_VALID_LOADED) + if (IS_FW_MODE_APPLICATION(ret)) + return 0; + + if (!IS_APP_VALID_LOADED(ret)) return -EIO; ret = i2c_smbus_write_byte(client, CCS811_APP_START); @@ -141,8 +148,7 @@ static int ccs811_start_sensor_application(struct i2c_client *client) if (ret < 0) return ret; - if ((ret & CCS811_STATUS_FW_MODE_MASK) != - CCS811_STATUS_FW_MODE_APPLICATION) { + if (!IS_FW_MODE_APPLICATION(ret)) { dev_err(&client->dev, "Application failed to start. Sensor is still in boot mode.\n"); return -EIO; }