From patchwork Thu May 5 13:30:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839559 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7BC5CC433EF for ; Thu, 5 May 2022 13:30:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379512AbiEENeM (ORCPT ); Thu, 5 May 2022 09:34:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379551AbiEENeJ (ORCPT ); Thu, 5 May 2022 09:34:09 -0400 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E42161B7A5; Thu, 5 May 2022 06:30:28 -0700 (PDT) Received: by mail-pg1-x535.google.com with SMTP id x12so3638348pgj.7; Thu, 05 May 2022 06:30:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ScUwdLygZAJBLNzZb5DPx3aH0d7kiLkb+57GQJMLhHA=; b=O1J0ZczFqlulozW3TK0yGqCukjH8F98Zz1I6QTbtsESqDOsOYZPYv/W4c1Bgbk4Gbb bw8mdougfWtlGfdBJf9FuwhWLnAEtr9mUfRaaFaRZx33h1Y2Qq8ebPJlUsyRH9AE3QQQ WNurtbQjyY8z0iJGw4Dd4WQQrIPib1ZtW9Db5tTx7oY3EueesQ/2GdQ2SDLEpOb5kVet IJTeMeyteomOQKFjMMoL4U3ZtjXuEN35/c/Sf/diqCjlRP7u76CxlcDhScfNVVE5xNc5 D0+7VfxGc+5uHZVNKfNfoXIgdXNBio0XjuUIEPtbgnzllgGy2ebEmEmefi0msGffwjX8 01Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ScUwdLygZAJBLNzZb5DPx3aH0d7kiLkb+57GQJMLhHA=; b=igWTr/1GhZL2gEt5YZg9mBtc7HBP2GBg4XRIwYaDDofKur6z0NCsAgvSOd5l9C6tfc FN85fGzZIUk/rwJxCI3ZkyHK/oV9e1qP82jwMSWlKHNcw20X7uEXoq6qksUJrZdWE++S 4m1bkKp3sVAx10Kva1wiiKpWZvdTIRR/8OX2OCTDV2TBwgkjNIc3xj5XowsUHPnK+arg ZiTRguUOmYSpzBgr8cyKtPkVqT/UvuBhI9wpKsyMWRD+2T21o2rPSEkL+tIawT513JVS mizEOFgkK+UUPupe51KsDj5zs0i3uHrv7GQy3DEBg7mrjTTG6KGgGkLceP720ySom1aL Ziiw== X-Gm-Message-State: AOAM531DLwmxAmYUgFNabaS+HWMLk4U+EvC0FwffjH9y7x5ok3ATdwDe Bal7JNjIylOA/yfvDASgrVw= X-Google-Smtp-Source: ABdhPJySIgxdmwQRP2IujD0e+3L/vIqmNvj9kR1ndSvCJc0prO703GqFJWQNamNWvXiHEpH/QxvkFQ== X-Received: by 2002:a63:84c3:0:b0:3aa:f229:45c5 with SMTP id k186-20020a6384c3000000b003aaf22945c5mr21977602pgd.415.1651757428359; Thu, 05 May 2022 06:30:28 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:27 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 01/10] iio: accel: bma400: Fix the scale min and max macro values Date: Thu, 5 May 2022 19:00:12 +0530 Message-Id: <20220505133021.22362-2-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Changing the scale macro values to match the bma400 sensitivity for 1 LSB of all the available ranges. Fixes: 465c811f1f20 ("iio: accel: Add driver for the BMA400") Signed-off-by: Jagath Jog J Reviewed-by: Andy Shevchenko --- drivers/iio/accel/bma400.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index c4c8d74155c2..80330c7ce17f 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -83,8 +83,27 @@ #define BMA400_ACC_ODR_MIN_WHOLE_HZ 25 #define BMA400_ACC_ODR_MIN_HZ 12 -#define BMA400_SCALE_MIN 38357 -#define BMA400_SCALE_MAX 306864 +/* + * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before + * converting to micro values for +-2g range. + * + * For +-2g - 1 LSB = 0.976562 milli g = 0.009576 m/s^2 + * For +-4g - 1 LSB = 1.953125 milli g = 0.019153 m/s^2 + * For +-16g - 1 LSB = 7.8125 milli g = 0.076614 m/s^2 + * + * The raw value which is used to select the different ranges is determined + * by the first bit set position from the scale value, so BMA400_SCALE_MIN + * should be odd. + * + * Scale values for +-2g, +-4g, +-8g and +-16g are populated into bma400_scales + * array by left shifting BMA400_SCALE_MIN. + * e.g.: + * To select +-2g = 9577 << 0 = raw value to write is 0. + * To select +-8g = 9577 << 2 = raw value to write is 2. + * To select +-16g = 9577 << 3 = raw value to write is 3. + */ +#define BMA400_SCALE_MIN 9577 +#define BMA400_SCALE_MAX 76617 #define BMA400_NUM_REGULATORS 2 #define BMA400_VDD_REGULATOR 0 From patchwork Thu May 5 13:30:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839560 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6FD6DC4332F for ; Thu, 5 May 2022 13:30:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379536AbiEENeN (ORCPT ); Thu, 5 May 2022 09:34:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347880AbiEENeK (ORCPT ); Thu, 5 May 2022 09:34:10 -0400 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3740756FA5; Thu, 5 May 2022 06:30:31 -0700 (PDT) Received: by mail-pl1-x62d.google.com with SMTP id i1so4392810plg.7; Thu, 05 May 2022 06:30:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SM9i76rzlNMMohIuFLToG7B0unnUzDqCDVvWZiGt2yk=; b=nmCrClc6I7B/c+cxpGO+mFyf9Qe+in9qQSW7aCB19p3VLwa44gR1RFxw4PB30AEOKQ AAWE5wtJJRafPr90FZcq9H+j3JVjNge3U6Ylq71tkyUO4/ZHGjW+OYagyeVCscy+tAHB AciV79jq1eqSm5t3pMmocT+fH+mrE8NJAerLjYZB0QQJzpCWTa7VmZn6xO8yUK7e0+uf mbalSVD8w256qB3uiBfDyooaFP7MYVE1u5TgKfQFzDG4OtkYFmLlWB4DUAOZvuofIEF3 yJVGsE2x/PfGg1SXEwdDC8kZhNJB4BRdr/TwAsXHoGMFrO/ztX3VWO3cfS1G5q0xlfKt o9zQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SM9i76rzlNMMohIuFLToG7B0unnUzDqCDVvWZiGt2yk=; b=7n0jPHA6eDJh+DnaEHXSpb5yLNHUp67UXPRdVqM+X24HzMYv9lvGP24RrE73bjkqxO C0SSdVm8IVzJxEcK2HT13GXfCwh/VU+DpyTwXKvrd4bVhPQ28JHZvBlaVFh9aBvmxrRF V8bagHxTiuXjk7/OILX5yuLiuoEG0jG1+cXmLoODZWvzIu4DNHdoE9I70GECFwfyKtan shZ8HLWZPNSMkfDc0SB52y34dF+rcquvYnMKhDpk2RiKZQSUlb4y8wk2hm6G5rFPR/Hy YoGAoRNqXwNI3TPTKbr+WetsufqK1C8rG9aaVQ6T2ktj4RHK0anYymBDLLQU5m0cVN2F OTSw== X-Gm-Message-State: AOAM532uKdp6wFkuI+LgakQIS6NNyUpXYFF1ImcYEO4b1GIGnIVfFz98 qbJ4LGuND1XzXYTAqtdWvyk= X-Google-Smtp-Source: ABdhPJzUmTCAtgJFSOMDrOHGgHWNEH/LwXsbyzPk6V11VCzSw6wKQlPIG9DpMJU9FQ7LS792KcIQGw== X-Received: by 2002:a17:90a:7acb:b0:1d9:85a5:e1e3 with SMTP id b11-20020a17090a7acb00b001d985a5e1e3mr6138961pjl.172.1651757430611; Thu, 05 May 2022 06:30:30 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:30 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 02/10] iio: accel: bma400: Reordering of header files Date: Thu, 5 May 2022 19:00:13 +0530 Message-Id: <20220505133021.22362-3-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Reordering of header files and removing the iio/sysfs.h since custom attributes are not being used in the driver. Signed-off-by: Jagath Jog J Reviewed-by: Andy Shevchenko --- drivers/iio/accel/bma400_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 043002fe6f63..25ad1f7339bc 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -13,14 +13,14 @@ #include #include -#include -#include #include #include #include #include #include +#include + #include "bma400.h" /* From patchwork Thu May 5 13:30:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43A8DC4332F for ; Thu, 5 May 2022 13:30:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379562AbiEENeP (ORCPT ); Thu, 5 May 2022 09:34:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45652 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231355AbiEENeO (ORCPT ); Thu, 5 May 2022 09:34:14 -0400 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 707569FFD; Thu, 5 May 2022 06:30:33 -0700 (PDT) Received: by mail-pl1-x62b.google.com with SMTP id n18so4403258plg.5; Thu, 05 May 2022 06:30:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OwclT365pHO8aTYKW7BCzuAnkLe27jWDU+2YGvjkHTQ=; b=ppBz5j6zrLByV2ZZCsuM7HriyRUzYnCB/FcrPOsGOzkr0i1dhTE6pz9ssOQNVaBOEm Z4rfe7SnaKGdXbXYfr9U58lo8r0gRn1vIqEbhSwduqXYi8opG/I4Xc7MPXgu6ViWtcy+ Z9gCtKBsLkm0SCpWI3bZEe5XxyKA7BqOWcgygCB2jUzcpJLw3Cb9oKdOVoENTylQkNEb /VPyDGIQ2s8PZxyCNjUEC/imQR1Xmgf/HjH6CatrPmJ2EzHiJgZUroSoCrJdvQH8nmu1 uYT7pEEeVoKggkjumeKebAVYaXx5yz0iLkg9sdFaU8mjC141Gecy3SqyS12EO6RP+swU OY5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OwclT365pHO8aTYKW7BCzuAnkLe27jWDU+2YGvjkHTQ=; b=EnB4q3yGywSxc+/x4scHcBGklSSsukmtJFNZ93esxVeEgq57lAiQjLgY4dIj77EjVv Po41/nJTtQhFk9p599oqx32IICr7ylHjccQ7qq6tvxaD2lh0yCTv3dBYeOkJ7TE32nXw Rwm0SjeoKkIbz9lg/LNuYpsHXBgyGE7I7wooyZfo1jWY4AvJsD4H6HNvvE5Ei57CpqgU G2EZDmjQuEVRmPwYWlJFCNgO944ko6oAVrpdelAVe9gPAiDPJesbfV/2URt7c1igNKxE AZNKJbDds9M7QdvdUYS42tFb4dS/fRfarBUiXAVdddI0xpO+pfKQUNFZdxnyckaZQaA6 E2LA== X-Gm-Message-State: AOAM533SbWywdJoZxyxSDzbAmi9laUefETjtQmfZfYFkqp+L8aFCHmPu MSR1h0ooRS9mT3drVHNoxkM= X-Google-Smtp-Source: ABdhPJxQk7z8j/mRrV4Xm+laHQxUZi62wMqNu+m6JiDGg67CFE5zic8hZZzRyku61A8/VDdKz3OHNQ== X-Received: by 2002:a17:902:8696:b0:15d:946:2f98 with SMTP id g22-20020a170902869600b0015d09462f98mr27358811plo.82.1651757432839; Thu, 05 May 2022 06:30:32 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:32 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 03/10] iio: accel: bma400: conversion to device-managed function Date: Thu, 5 May 2022 19:00:14 +0530 Message-Id: <20220505133021.22362-4-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This is a conversion to device-managed by using devm_iio_device_register() inside probe function. Previously the bma400 was not put into power down mode in some error paths in probe where it now is, but that should cause no harm. The dev_set_drvdata() call, bma400_remove() function and hooks in the I2C and SPI driver struct is removed as devm_iio_device_register() function is used to automatically unregister on driver detach. Signed-off-by: Jagath Jog J Reviewed-by: Andy Shevchenko --- drivers/iio/accel/bma400.h | 2 - drivers/iio/accel/bma400_core.c | 77 ++++++++++++++++----------------- drivers/iio/accel/bma400_i2c.c | 8 ---- drivers/iio/accel/bma400_spi.c | 6 --- 4 files changed, 38 insertions(+), 55 deletions(-) diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index 80330c7ce17f..1c8c47a9a317 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -113,6 +113,4 @@ extern const struct regmap_config bma400_regmap_config; int bma400_probe(struct device *dev, struct regmap *regmap, const char *name); -void bma400_remove(struct device *dev); - #endif diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 25ad1f7339bc..07674d89d978 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -560,6 +560,26 @@ static void bma400_init_tables(void) } } +static void bma400_regulators_disable(void *data_ptr) +{ + struct bma400_data *data = data_ptr; + + regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); +} + +static void bma400_power_disable(void *data_ptr) +{ + struct bma400_data *data = data_ptr; + int ret; + + mutex_lock(&data->mutex); + ret = bma400_set_power_mode(data, POWER_MODE_SLEEP); + mutex_unlock(&data->mutex); + if (ret) + dev_warn(data->dev, "Failed to put device into sleep mode (%pe)\n", + ERR_PTR(ret)); +} + static int bma400_init(struct bma400_data *data) { unsigned int val; @@ -569,13 +589,12 @@ static int bma400_init(struct bma400_data *data) ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val); if (ret) { dev_err(data->dev, "Failed to read chip id register\n"); - goto out; + return ret; } if (val != BMA400_ID_REG_VAL) { dev_err(data->dev, "Chip ID mismatch\n"); - ret = -ENODEV; - goto out; + return -ENODEV; } data->regulators[BMA400_VDD_REGULATOR].supply = "vdd"; @@ -589,27 +608,31 @@ static int bma400_init(struct bma400_data *data) "Failed to get regulators: %d\n", ret); - goto out; + return ret; } ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators), data->regulators); if (ret) { dev_err(data->dev, "Failed to enable regulators: %d\n", ret); - goto out; + return ret; } + ret = devm_add_action_or_reset(data->dev, bma400_regulators_disable, data); + if (ret) + return ret; + ret = bma400_get_power_mode(data); if (ret) { dev_err(data->dev, "Failed to get the initial power-mode\n"); - goto err_reg_disable; + return ret; } if (data->power_mode != POWER_MODE_NORMAL) { ret = bma400_set_power_mode(data, POWER_MODE_NORMAL); if (ret) { dev_err(data->dev, "Failed to wake up the device\n"); - goto err_reg_disable; + return ret; } /* * TODO: The datasheet waits 1500us here in the example, but @@ -618,19 +641,23 @@ static int bma400_init(struct bma400_data *data) usleep_range(1500, 2000); } + ret = devm_add_action_or_reset(data->dev, bma400_power_disable, data); + if (ret) + return ret; + bma400_init_tables(); ret = bma400_get_accel_output_data_rate(data); if (ret) - goto err_reg_disable; + return ret; ret = bma400_get_accel_oversampling_ratio(data); if (ret) - goto err_reg_disable; + return ret; ret = bma400_get_accel_scale(data); if (ret) - goto err_reg_disable; + return ret; /* * Once the interrupt engine is supported we might use the @@ -639,12 +666,6 @@ static int bma400_init(struct bma400_data *data) * channel. */ return regmap_write(data->regmap, BMA400_ACC_CONFIG2_REG, 0x00); - -err_reg_disable: - regulator_bulk_disable(ARRAY_SIZE(data->regulators), - data->regulators); -out: - return ret; } static int bma400_read_raw(struct iio_dev *indio_dev, @@ -822,32 +843,10 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name) indio_dev->num_channels = ARRAY_SIZE(bma400_channels); indio_dev->modes = INDIO_DIRECT_MODE; - dev_set_drvdata(dev, indio_dev); - - return iio_device_register(indio_dev); + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400); -void bma400_remove(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct bma400_data *data = iio_priv(indio_dev); - int ret; - - mutex_lock(&data->mutex); - ret = bma400_set_power_mode(data, POWER_MODE_SLEEP); - mutex_unlock(&data->mutex); - - if (ret) - dev_warn(dev, "Failed to put device into sleep mode (%pe)\n", ERR_PTR(ret)); - - regulator_bulk_disable(ARRAY_SIZE(data->regulators), - data->regulators); - - iio_device_unregister(indio_dev); -} -EXPORT_SYMBOL_NS(bma400_remove, IIO_BMA400); - MODULE_AUTHOR("Dan Robertson "); MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core"); MODULE_LICENSE("GPL"); diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index da104ffd3fe0..4f6e01a3b3a1 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -27,13 +27,6 @@ static int bma400_i2c_probe(struct i2c_client *client, return bma400_probe(&client->dev, regmap, id->name); } -static int bma400_i2c_remove(struct i2c_client *client) -{ - bma400_remove(&client->dev); - - return 0; -} - static const struct i2c_device_id bma400_i2c_ids[] = { { "bma400", 0 }, { } @@ -52,7 +45,6 @@ static struct i2c_driver bma400_i2c_driver = { .of_match_table = bma400_of_i2c_match, }, .probe = bma400_i2c_probe, - .remove = bma400_i2c_remove, .id_table = bma400_i2c_ids, }; diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c index 51f23bdc0ea5..28e240400a3f 100644 --- a/drivers/iio/accel/bma400_spi.c +++ b/drivers/iio/accel/bma400_spi.c @@ -87,11 +87,6 @@ static int bma400_spi_probe(struct spi_device *spi) return bma400_probe(&spi->dev, regmap, id->name); } -static void bma400_spi_remove(struct spi_device *spi) -{ - bma400_remove(&spi->dev); -} - static const struct spi_device_id bma400_spi_ids[] = { { "bma400", 0 }, { } @@ -110,7 +105,6 @@ static struct spi_driver bma400_spi_driver = { .of_match_table = bma400_of_spi_match, }, .probe = bma400_spi_probe, - .remove = bma400_spi_remove, .id_table = bma400_spi_ids, }; From patchwork Thu May 5 13:30:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839562 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4327CC433EF for ; Thu, 5 May 2022 13:30:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377608AbiEENeR (ORCPT ); Thu, 5 May 2022 09:34:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379573AbiEENeQ (ORCPT ); Thu, 5 May 2022 09:34:16 -0400 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4372F6392; Thu, 5 May 2022 06:30:36 -0700 (PDT) Received: by mail-pj1-x102e.google.com with SMTP id t11-20020a17090ad50b00b001d95bf21996so8039087pju.2; Thu, 05 May 2022 06:30:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VOsDpCo1BwfCUO6tmqAjxhxSfGAbsJAAJ2gXy2+hPIs=; b=HUPUEyV9iFr9RyUXBCA9Z/NjUJeYNzCGRKplEpUfVjgBPBr0x32DF7Fbt1MxRazB82 oCvInmN9DhJb6JU73TgtkgwBPZQII/R/5dyMFEJoOY2NZ7TZeeGu7mCG3iTpurYsn0OT lqF5O4YlZhhI62l+yHiOp6S+oXM/lXypPC0uYI03N5iyVoCudvxZL9B6vZRakLRM6IqC kXRCUUG3oBwNa285KVuGYvINXUBKzFBsF1TLYifsImInic6jtn89C29y2YCDjtIxciN9 MS/E1cOLgHrIUtUhhJWKeuVgqOMGLcDHOZn0JQq9niX7L6z9iu/ys50z97nAtX/YTs8I 3ULw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VOsDpCo1BwfCUO6tmqAjxhxSfGAbsJAAJ2gXy2+hPIs=; b=qZK8tQBriL08ejY0RgUFmjEamfJxqtMDmTzjt8yZYL7UMWoLTcPGrQWG4Lt5bByxNc xwtD93ZMikOW/O7X20tIkS8sq8JQmbly6UGVlcYnnmp2cZK+9WLjPusV32bTCq5+PyBI 4jfODsqLyDh9u7e9gpbwruze4Momrq+ivYy8zCLilBL2q9cZoRXBW1iMrOjlZ9sBfNJU ujY/kX0k8tLWi7n4WoDFGs/b5xOiMY5Qvd653sP2GS/JxSzjwXbJSbuqfpbThv4txDC/ blkxuqNLzqyg4V4NRDAJTtsp45OCQRpXbadK1VhbPMfb3VnHDEwn3z7BGsuZy6pW+8ve oxAg== X-Gm-Message-State: AOAM533XtfPysr30XCCQMSEIe4sBNs1n1mTbXnQSxUZerv5Dvz3dADjM Q7FHswsnutVOQ3k1A/Z4Qag= X-Google-Smtp-Source: ABdhPJzsqk10QRPm5AlrWKJ9hOXOkI7bJCcDcRFtXRrl9yE3hly3n8R/UTl2sSPz2EExmV3V/OU4lw== X-Received: by 2002:a17:902:d487:b0:15e:a0a4:69e3 with SMTP id c7-20020a170902d48700b0015ea0a469e3mr22172382plg.155.1651757435621; Thu, 05 May 2022 06:30:35 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:34 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 04/10] iio: accel: bma400: Add triggered buffer support Date: Thu, 5 May 2022 19:00:15 +0530 Message-Id: <20220505133021.22362-5-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Added trigger buffer support to read continuous acceleration and temperature data from device with data ready interrupt which is mapped to INT1 pin. Signed-off-by: Jagath Jog J Reviewed-by: Andy Shevchenko --- drivers/iio/accel/Kconfig | 2 + drivers/iio/accel/bma400.h | 10 +- drivers/iio/accel/bma400_core.c | 177 +++++++++++++++++++++++++++++++- drivers/iio/accel/bma400_i2c.c | 2 +- drivers/iio/accel/bma400_spi.c | 2 +- 5 files changed, 185 insertions(+), 8 deletions(-) diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index eac3f02662ae..958097814232 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -204,6 +204,8 @@ config BMA220 config BMA400 tristate "Bosch BMA400 3-Axis Accelerometer Driver" select REGMAP + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER select BMA400_I2C if I2C select BMA400_SPI if SPI help diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index 1c8c47a9a317..907e1a6c0a38 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -62,6 +62,13 @@ #define BMA400_ACC_CONFIG2_REG 0x1b #define BMA400_CMD_REG 0x7e +/* Interrupt registers */ +#define BMA400_INT_CONFIG0_REG 0x1f +#define BMA400_INT_CONFIG1_REG 0x20 +#define BMA400_INT1_MAP_REG 0x21 +#define BMA400_INT_IO_CTRL_REG 0x24 +#define BMA400_INT_DRDY_MSK BIT(7) + /* Chip ID of BMA 400 devices found in the chip ID register. */ #define BMA400_ID_REG_VAL 0x90 @@ -111,6 +118,7 @@ extern const struct regmap_config bma400_regmap_config; -int bma400_probe(struct device *dev, struct regmap *regmap, const char *name); +int bma400_probe(struct device *dev, struct regmap *regmap, int irq, + const char *name); #endif diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 07674d89d978..67e102c097bc 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -11,6 +11,7 @@ * - Create channel for sensor time */ +#include #include #include #include @@ -20,6 +21,10 @@ #include #include +#include +#include +#include +#include #include "bma400.h" @@ -46,6 +51,13 @@ enum bma400_power_mode { POWER_MODE_INVALID = 0x03, }; +enum bma400_scan { + BMA400_ACCL_X, + BMA400_ACCL_Y, + BMA400_ACCL_Z, + BMA400_TEMP, +}; + struct bma400_sample_freq { int hz; int uhz; @@ -61,6 +73,14 @@ struct bma400_data { struct bma400_sample_freq sample_freq; int oversampling_ratio; int scale; + struct iio_trigger *trig; + /* Correct time stamp alignment */ + struct { + __le16 buff[3]; + u8 temperature; + s64 ts __aligned(8); + } buffer __aligned(IIO_ALIGN); + __le16 status; }; static bool bma400_is_writable_reg(struct device *dev, unsigned int reg) @@ -152,7 +172,7 @@ static const struct iio_chan_spec_ext_info bma400_ext_info[] = { { } }; -#define BMA400_ACC_CHANNEL(_axis) { \ +#define BMA400_ACC_CHANNEL(_index, _axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = IIO_MOD_##_axis, \ @@ -164,17 +184,32 @@ static const struct iio_chan_spec_ext_info bma400_ext_info[] = { BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .ext_info = bma400_ext_info, \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ } static const struct iio_chan_spec bma400_channels[] = { - BMA400_ACC_CHANNEL(X), - BMA400_ACC_CHANNEL(Y), - BMA400_ACC_CHANNEL(Z), + BMA400_ACC_CHANNEL(0, X), + BMA400_ACC_CHANNEL(1, Y), + BMA400_ACC_CHANNEL(2, Z), { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .scan_index = 3, + .scan_type = { + .sign = 's', + .realbits = 8, + .storagebits = 8, + .endianness = IIO_LE, + }, }, + IIO_CHAN_SOFT_TIMESTAMP(4), }; static int bma400_get_temp_reg(struct bma400_data *data, int *val, int *val2) @@ -659,6 +694,10 @@ static int bma400_init(struct bma400_data *data) if (ret) return ret; + /* Configure INT1 pin to open drain */ + ret = regmap_write(data->regmap, BMA400_INT_IO_CTRL_REG, 0x06); + if (ret) + return ret; /* * Once the interrupt engine is supported we might use the * data_src_reg, but for now ensure this is set to the @@ -807,6 +846,31 @@ static int bma400_write_raw_get_fmt(struct iio_dev *indio_dev, } } +static int bma400_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct bma400_data *data = iio_priv(indio_dev); + int ret; + + ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, + BMA400_INT_DRDY_MSK, + FIELD_PREP(BMA400_INT_DRDY_MSK, state)); + if (ret) + return ret; + + return regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, + BMA400_INT_DRDY_MSK, + FIELD_PREP(BMA400_INT_DRDY_MSK, state)); +} + +static const unsigned long bma400_avail_scan_masks[] = { + BIT(BMA400_ACCL_X) | BIT(BMA400_ACCL_Y) | BIT(BMA400_ACCL_Z), + BIT(BMA400_ACCL_X) | BIT(BMA400_ACCL_Y) | BIT(BMA400_ACCL_Z) + | BIT(BMA400_TEMP), + 0 +}; + static const struct iio_info bma400_info = { .read_raw = bma400_read_raw, .read_avail = bma400_read_avail, @@ -814,7 +878,78 @@ static const struct iio_info bma400_info = { .write_raw_get_fmt = bma400_write_raw_get_fmt, }; -int bma400_probe(struct device *dev, struct regmap *regmap, const char *name) +static const struct iio_trigger_ops bma400_trigger_ops = { + .set_trigger_state = &bma400_data_rdy_trigger_set_state, + .validate_device = &iio_trigger_validate_own_device, +}; + +static irqreturn_t bma400_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct bma400_data *data = iio_priv(indio_dev); + int ret, temp; + + /* Lock to protect the data->buffer */ + mutex_lock(&data->mutex); + + /* bulk read six registers, with the base being the LSB register */ + ret = regmap_bulk_read(data->regmap, BMA400_X_AXIS_LSB_REG, + &data->buffer.buff, sizeof(data->buffer.buff)); + if (ret) + goto unlock_err; + + if (test_bit(BMA400_TEMP, indio_dev->active_scan_mask)) { + ret = regmap_read(data->regmap, BMA400_TEMP_DATA_REG, &temp); + if (ret) + goto unlock_err; + + data->buffer.temperature = temp; + } + + iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, + iio_get_time_ns(indio_dev)); + + mutex_unlock(&data->mutex); + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; + +unlock_err: + mutex_unlock(&data->mutex); + return IRQ_NONE; +} + +static irqreturn_t bma400_interrupt(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct bma400_data *data = iio_priv(indio_dev); + int ret; + + /* Lock to protect the data->status */ + mutex_lock(&data->mutex); + ret = regmap_bulk_read(data->regmap, BMA400_INT_STAT0_REG, + &data->status, + sizeof(data->status)); + /* + * if none of the bit is set in the status register then it is + * spurious interrupt. + */ + if (ret || !data->status) + goto unlock_err; + + if (FIELD_GET(BMA400_INT_DRDY_MSK, le16_to_cpu(data->status))) { + mutex_unlock(&data->mutex); + iio_trigger_poll_chained(data->trig); + return IRQ_HANDLED; + } + +unlock_err: + mutex_unlock(&data->mutex); + return IRQ_NONE; +} + +int bma400_probe(struct device *dev, struct regmap *regmap, int irq, + const char *name) { struct iio_dev *indio_dev; struct bma400_data *data; @@ -841,8 +976,40 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name) indio_dev->info = &bma400_info; indio_dev->channels = bma400_channels; indio_dev->num_channels = ARRAY_SIZE(bma400_channels); + indio_dev->available_scan_masks = bma400_avail_scan_masks; indio_dev->modes = INDIO_DIRECT_MODE; + if (irq > 0) { + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops = &bma400_trigger_ops; + iio_trigger_set_drvdata(data->trig, indio_dev); + + ret = devm_iio_trigger_register(data->dev, data->trig); + if (ret) + return dev_err_probe(data->dev, ret, + "iio trigger register fail\n"); + + indio_dev->trig = iio_trigger_get(data->trig); + ret = devm_request_threaded_irq(dev, irq, NULL, + &bma400_interrupt, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return dev_err_probe(data->dev, ret, + "request irq %d failed\n", irq); + } + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + &bma400_trigger_handler, NULL); + if (ret) + return dev_err_probe(data->dev, ret, + "iio triggered buffer setup failed\n"); + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400); diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c index 4f6e01a3b3a1..1ba2a982ea73 100644 --- a/drivers/iio/accel/bma400_i2c.c +++ b/drivers/iio/accel/bma400_i2c.c @@ -24,7 +24,7 @@ static int bma400_i2c_probe(struct i2c_client *client, return PTR_ERR(regmap); } - return bma400_probe(&client->dev, regmap, id->name); + return bma400_probe(&client->dev, regmap, client->irq, id->name); } static const struct i2c_device_id bma400_i2c_ids[] = { diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c index 28e240400a3f..ec13c044b304 100644 --- a/drivers/iio/accel/bma400_spi.c +++ b/drivers/iio/accel/bma400_spi.c @@ -84,7 +84,7 @@ static int bma400_spi_probe(struct spi_device *spi) if (ret) dev_err(&spi->dev, "Failed to read chip id register\n"); - return bma400_probe(&spi->dev, regmap, id->name); + return bma400_probe(&spi->dev, regmap, spi->irq, id->name); } static const struct spi_device_id bma400_spi_ids[] = { From patchwork Thu May 5 13:30:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDC09C4332F for ; Thu, 5 May 2022 13:30:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379612AbiEENeX (ORCPT ); Thu, 5 May 2022 09:34:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379561AbiEENeS (ORCPT ); Thu, 5 May 2022 09:34:18 -0400 Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A61881277A; Thu, 5 May 2022 06:30:38 -0700 (PDT) Received: by mail-pl1-x634.google.com with SMTP id n8so4417931plh.1; Thu, 05 May 2022 06:30:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=51mDZ0cyY489Y5og5yHEw5jaChmCSfiAiqAL0DmhUXw=; b=W5gfZdBHv3/QtOTMCzdHXm3MH44sEXegpd+TJRM1MCjGjtp6ZnfaKYlOEhrqk8pwvf FjbrczsdeLWAvlf6JDJO4c8bKmMy7HgfOby54F70XX4sla/eF6XAextoZB/jSYPndNUk hMHqHy5ZC0WsFc46XVZli/1pnbpdVY2704avm7L6snqzVKL6as9s4sfVqDHslZBsdJ8j hfYLpthx6qEijc9AX+eKJbuuzcd6BUFkutGLU7K4N0WhUX7zKIIx1U0iqoeQJZIE/l8J +jaB7Xfaio4i2Tqw763L5PHGcE6TrIaw+iuRk4RA5mMKk3Pc55mdiy8BwdmCzXP4L45j LvLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=51mDZ0cyY489Y5og5yHEw5jaChmCSfiAiqAL0DmhUXw=; b=NuBzHRi2TmMCK2mS7y1594MCpioAJc3FqIsHuh94ZgU7ha9rNLQ5f/X/tu2KZ96EBR HicF/f6jp913nCFR4ACENpyDLZ2beq36FBgDHDkX+r9jrHE2A3PE/iVm+MAAgptK1CWv irwG2UNyaFisYUTngEBOgr5Fy/afSWUAuK9IsZJqsOWcBPSgapvU5Jpt055bcXEjJzEf eb3VnSSIqDaPvh4EGPEi/kJvC7sJeecN2C/EAD9lEXbKde6yc81QX8WbFMST5YVBjnlH kATurGHLb4e18U1BKg6zKEW50yMW0pUIcEatQU9nU54IrUWIeNa2t2tnkA0/TqPGuy3j q7PA== X-Gm-Message-State: AOAM532f8T4U1uvCGI0O68S3HIHj9JXO/GNjHfDar1Dp6Yo7IfGJnpWn dNlsKziiCEaS4oMu46fV434= X-Google-Smtp-Source: ABdhPJwSacmVgbxtXPGN4e7Dr103aA7fH/UYZnnVDm5WfNUn6YR8wN/EeVUgfnGA3MWO3PSiWCuxiw== X-Received: by 2002:a17:902:a502:b0:15e:c251:b769 with SMTP id s2-20020a170902a50200b0015ec251b769mr9830558plq.115.1651757438087; Thu, 05 May 2022 06:30:38 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:37 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 05/10] iio: accel: bma400: Add separate channel for step counter Date: Thu, 5 May 2022 19:00:16 +0530 Message-Id: <20220505133021.22362-6-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Added channel for step counter which can be enable or disable through the sysfs interface. Signed-off-by: Jagath Jog J --- drivers/iio/accel/bma400.h | 2 + drivers/iio/accel/bma400_core.c | 69 +++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index 907e1a6c0a38..32c08f8b0b98 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -53,6 +53,8 @@ #define BMA400_STEP_CNT1_REG 0x16 #define BMA400_STEP_CNT3_REG 0x17 #define BMA400_STEP_STAT_REG 0x18 +#define BMA400_STEP_INT_MSK BIT(0) +#define BMA400_STEP_RAW_LEN 0x03 /* * Read-write configuration registers diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 67e102c097bc..fdb7e8bd7b27 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -19,6 +19,9 @@ #include #include #include +#include + +#include #include #include @@ -74,6 +77,7 @@ struct bma400_data { int oversampling_ratio; int scale; struct iio_trigger *trig; + int steps_enabled; /* Correct time stamp alignment */ struct { __le16 buff[3]; @@ -209,6 +213,12 @@ static const struct iio_chan_spec bma400_channels[] = { .endianness = IIO_LE, }, }, + { + .type = IIO_STEPS, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_ENABLE), + .scan_index = -1, /* No buffer support */ + }, IIO_CHAN_SOFT_TIMESTAMP(4), }; @@ -577,6 +587,40 @@ static int bma400_set_power_mode(struct bma400_data *data, return 0; } +static int bma400_enable_steps(struct bma400_data *data, int val) +{ + int ret; + + if (data->steps_enabled == val) + return 0; + + ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG1_REG, + BMA400_STEP_INT_MSK, + FIELD_PREP(BMA400_STEP_INT_MSK, !!val)); + if (ret) + return ret; + data->steps_enabled = val; + return ret; +} + +static int bma400_get_steps_reg(struct bma400_data *data, int *val) +{ + u8 *steps_raw; + int ret; + + steps_raw = kmalloc(BMA400_STEP_RAW_LEN, GFP_KERNEL); + if (!steps_raw) + return -ENOMEM; + + ret = regmap_bulk_read(data->regmap, BMA400_STEP_CNT0_REG, + steps_raw, BMA400_STEP_RAW_LEN); + if (ret) + return ret; + *val = get_unaligned_le24(steps_raw); + kfree(steps_raw); + return IIO_VAL_INT; +} + static void bma400_init_tables(void) { int raw; @@ -716,10 +760,17 @@ static int bma400_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_PROCESSED: - mutex_lock(&data->mutex); - ret = bma400_get_temp_reg(data, val, val2); - mutex_unlock(&data->mutex); - return ret; + switch (chan->type) { + case IIO_TEMP: + mutex_lock(&data->mutex); + ret = bma400_get_temp_reg(data, val, val2); + mutex_unlock(&data->mutex); + return ret; + case IIO_STEPS: + return bma400_get_steps_reg(data, val); + default: + return -EINVAL; + } case IIO_CHAN_INFO_RAW: mutex_lock(&data->mutex); ret = bma400_get_accel_reg(data, chan, val); @@ -760,6 +811,9 @@ static int bma400_read_raw(struct iio_dev *indio_dev, *val = data->oversampling_ratio; return IIO_VAL_INT; + case IIO_CHAN_INFO_ENABLE: + *val = data->steps_enabled; + return IIO_VAL_INT; default: return -EINVAL; } @@ -825,6 +879,11 @@ static int bma400_write_raw(struct iio_dev *indio_dev, ret = bma400_set_accel_oversampling_ratio(data, val); mutex_unlock(&data->mutex); return ret; + case IIO_CHAN_INFO_ENABLE: + mutex_lock(&data->mutex); + ret = bma400_enable_steps(data, val); + mutex_unlock(&data->mutex); + return ret; default: return -EINVAL; } @@ -841,6 +900,8 @@ static int bma400_write_raw_get_fmt(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: return IIO_VAL_INT; + case IIO_CHAN_INFO_ENABLE: + return IIO_VAL_INT; default: return -EINVAL; } From patchwork Thu May 5 13:30:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E590CC433F5 for ; Thu, 5 May 2022 13:30:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379585AbiEENeW (ORCPT ); Thu, 5 May 2022 09:34:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379606AbiEENeU (ORCPT ); Thu, 5 May 2022 09:34:20 -0400 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE25256FA3; Thu, 5 May 2022 06:30:40 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id cx11-20020a17090afd8b00b001d9fe5965b3so8023084pjb.3; Thu, 05 May 2022 06:30:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CB2rfd2EilPcnlni3o0odhm3eEkQ0tXTMQ0Te1eD2zg=; b=dLdj14wEcu4x/F10bBlWfvLmo/KMgqk+O3dLQnSUjl403SQPQoVpo4RrlcG4sIXlVz 6K+NF+LuuZhkUVfnQIcvlZCP3hvKv+kLt7CroGnjRQU2e//OVDMYGYMBbf4SqzvlIw7M lnzc2ZiqcfEYCo8Len5fRLV4hzc+8f/I0cOYPucl9+sBbH+YRz7bZw9BF8GOB4oLxhAS rUnvDuMwafBJtD5nSNvAyf51phWnIaQaF/B2WgoP9F7BSfZ5tthYihxhrIJPRiwWKNk9 DkOxW+lVHMbwNpC/RAbLiV9+f6CVU1l06AEtovqqtPgB4rDoDJ6FMnGDQkCaN40KvDET g+GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CB2rfd2EilPcnlni3o0odhm3eEkQ0tXTMQ0Te1eD2zg=; b=WWflGN1tnn7qLAKU114b/38Q8+XNgoEyUftiOJlZWyRCE9dTw9T2mp8dsjTUR37e9l OEYcCS8mjbqw5Skjo7z7wPn+AlI7zJvZHuPh2+fRbffJYXi2bTi9kYHs7fqv8RtWD7Ma Qe8lM0wsbPla/RtU2bMbOw/7N8WnO5CKT91U98S1DLBkTRGconGaLrpXXfLBsf92z59A OTpKxHeiyxqHGCOrIEdWii4YpSeSBBYoiICmljb20+k67m6arA265QckuqtWw1clF8YA wumCDrdcRGZGjssKUAcG/c7pHTAvXmiMUWP63KaHGuROOmNNA+sxiDSbdgI5/vaxELni chxw== X-Gm-Message-State: AOAM532g46rMt1Bs8DmeBAPCWEFPPHNsaHFdVquKqStJDuz9iV9snxTh i+eCvxRPwpjS95owEKwfyTU= X-Google-Smtp-Source: ABdhPJwXM21cQ241FYJlZ9WYPY6dIUckLfnLrshuo2JkBS30Z0BkhEdhP8w55X5xkivXoAMcg4Zowg== X-Received: by 2002:a17:903:2310:b0:15e:a944:aa52 with SMTP id d16-20020a170903231000b0015ea944aa52mr19724023plh.49.1651757440276; Thu, 05 May 2022 06:30:40 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:39 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 06/10] iio: accel: bma400: Add step change event Date: Thu, 5 May 2022 19:00:17 +0530 Message-Id: <20220505133021.22362-7-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Added support for event when there is a detection of step change. INT1 pin is used to interrupt and event is pushed to userspace. Signed-off-by: Jagath Jog J --- drivers/iio/accel/bma400.h | 2 + drivers/iio/accel/bma400_core.c | 76 +++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index 32c08f8b0b98..0faa40fdbbf8 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -39,6 +39,7 @@ #define BMA400_INT_STAT0_REG 0x0e #define BMA400_INT_STAT1_REG 0x0f #define BMA400_INT_STAT2_REG 0x10 +#define BMA400_INT12_MAP_REG 0x23 /* Temperature register */ #define BMA400_TEMP_DATA_REG 0x11 @@ -55,6 +56,7 @@ #define BMA400_STEP_STAT_REG 0x18 #define BMA400_STEP_INT_MSK BIT(0) #define BMA400_STEP_RAW_LEN 0x03 +#define BMA400_STEP_STAT_MASK GENMASK(9, 8) /* * Read-write configuration registers diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index fdb7e8bd7b27..50932fc1c854 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -78,6 +79,7 @@ struct bma400_data { int scale; struct iio_trigger *trig; int steps_enabled; + bool step_event_en; /* Correct time stamp alignment */ struct { __le16 buff[3]; @@ -176,6 +178,12 @@ static const struct iio_chan_spec_ext_info bma400_ext_info[] = { { } }; +static const struct iio_event_spec bma400_step_detect_event = { + .type = IIO_EV_TYPE_CHANGE, + .dir = IIO_EV_DIR_NONE, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), +}; + #define BMA400_ACC_CHANNEL(_index, _axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ @@ -218,6 +226,8 @@ static const struct iio_chan_spec bma400_channels[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | BIT(IIO_CHAN_INFO_ENABLE), .scan_index = -1, /* No buffer support */ + .event_spec = &bma400_step_detect_event, + .num_event_specs = 1, }, IIO_CHAN_SOFT_TIMESTAMP(4), }; @@ -907,6 +917,58 @@ static int bma400_write_raw_get_fmt(struct iio_dev *indio_dev, } } +static int bma400_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct bma400_data *data = iio_priv(indio_dev); + + switch (chan->type) { + case IIO_STEPS: + return data->step_event_en; + default: + return -EINVAL; + } +} + +static int bma400_steps_event_enable(struct bma400_data *data, int state) +{ + int ret; + + ret = bma400_enable_steps(data, 1); + if (ret) + return ret; + + ret = regmap_update_bits(data->regmap, BMA400_INT12_MAP_REG, + BMA400_STEP_INT_MSK, + FIELD_PREP(BMA400_STEP_INT_MSK, + state)); + if (ret) + return ret; + data->step_event_en = state; + return 0; +} + +static int bma400_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, int state) +{ + struct bma400_data *data = iio_priv(indio_dev); + int ret; + + switch (chan->type) { + case IIO_STEPS: + mutex_lock(&data->mutex); + ret = bma400_steps_event_enable(data, state); + mutex_unlock(&data->mutex); + return ret; + default: + return -EINVAL; + } +} + static int bma400_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { @@ -937,6 +999,8 @@ static const struct iio_info bma400_info = { .read_avail = bma400_read_avail, .write_raw = bma400_write_raw, .write_raw_get_fmt = bma400_write_raw_get_fmt, + .read_event_config = bma400_read_event_config, + .write_event_config = bma400_write_event_config, }; static const struct iio_trigger_ops bma400_trigger_ops = { @@ -984,6 +1048,7 @@ static irqreturn_t bma400_interrupt(int irq, void *private) { struct iio_dev *indio_dev = private; struct bma400_data *data = iio_priv(indio_dev); + s64 timestamp = iio_get_time_ns(indio_dev); int ret; /* Lock to protect the data->status */ @@ -998,12 +1063,23 @@ static irqreturn_t bma400_interrupt(int irq, void *private) if (ret || !data->status) goto unlock_err; + if (FIELD_GET(BMA400_STEP_STAT_MASK, le16_to_cpu(data->status))) { + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, + IIO_EV_TYPE_CHANGE, + IIO_EV_DIR_NONE), + timestamp); + } + if (FIELD_GET(BMA400_INT_DRDY_MSK, le16_to_cpu(data->status))) { mutex_unlock(&data->mutex); iio_trigger_poll_chained(data->trig); return IRQ_HANDLED; } + mutex_unlock(&data->mutex); + return IRQ_HANDLED; + unlock_err: mutex_unlock(&data->mutex); return IRQ_NONE; From patchwork Thu May 5 13:30:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4BE43C433F5 for ; Thu, 5 May 2022 13:30:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379633AbiEENe0 (ORCPT ); Thu, 5 May 2022 09:34:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379637AbiEENeX (ORCPT ); Thu, 5 May 2022 09:34:23 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C99BC1277A; Thu, 5 May 2022 06:30:43 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id o69so4212964pjo.3; Thu, 05 May 2022 06:30:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=H3CkS7Q8uU7MubL4PY7f/qf/85uW9+5JcXDuS6dbHMY=; b=JdYhrJb7mX4+734N1IXgMszUeEgx+WAZ2dR/lmjVqsOUxKkXoaW4Iy20gkxFEhmK8a Y2mTRea2gb7hXAIbVnXKYhy2ubYDAORsCIAiStuy1ctHsn/Ni2RB4nwlnqW37tphhdR3 v6TUqoUpG/CMbJK0S7PqYfNe6Zu7+WZaxzuzUIHu1ZxW/2gjxZTdMqR0pI7Xt8IuONey oRhKBWejpMxipqyuZduPqYKs8ZzlKpl42w0PiT5bFY4HUWUAOCLpZEHEUv8od5DCkapa 2EKRk5gd6zB9Tw++E9Rh0+afGFYAJPFNa2uyp+EqZYAuZYDGKrGCafFNtJBRHLSERztr 0I/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=H3CkS7Q8uU7MubL4PY7f/qf/85uW9+5JcXDuS6dbHMY=; b=QDSZdbADsTyFu2OBAV1ifB/Hag09nHOP5ZloAQAivflrDVYyVmAzb4bbGJg0ztncH9 Q3XnYqw8IKbpUJ/cZHNQwTlfAD/Cxv5CCPFy76xpmv2PBJSKfZJs+eyVUjBM/zvE5SLs Un+nVyq6MIgnc69yD3yjTu5HZ+0CtyDTlp9DmuYAopNHC6tUka5f58diCRYTxE6VYH7k QB/FawL1+JZYtCpxCvUsVmVUx9UP/9AYi4EP545LR2O72QDVuCWT0FTt/Vyv4ch2bcpI Hx3zkaGX908AfBfryopKK+rLE11t+l8q/Rz2hSBqUeLrmZuOX0FaZEJuRYEpF0R13gp/ KRzw== X-Gm-Message-State: AOAM532f9bLUFmKS2YiqLfWUFXhoEXLRTFYb+qi803D8cv/XwZqEkE5h DTSZkfsJ49JYFNlwlhAI57M= X-Google-Smtp-Source: ABdhPJwT2CcSIvf96nOivNSJyRdg9I1448OecKUqWeJk+vGTypo1FQfJDjUL8VIZwDuHM/qkW0y8og== X-Received: by 2002:a17:90a:a393:b0:1d0:e448:811d with SMTP id x19-20020a17090aa39300b001d0e448811dmr6274218pjp.97.1651757443035; Thu, 05 May 2022 06:30:43 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:42 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 07/10] iio: accel: bma400: Add activity recognition support Date: Thu, 5 May 2022 19:00:18 +0530 Message-Id: <20220505133021.22362-8-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add support for activity recognition like STILL, WALKING, RUNNING and these events are pushed to the userspace whenever the STEP interrupt occurs. Signed-off-by: Jagath Jog J --- drivers/iio/accel/bma400_core.c | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 50932fc1c854..1e4923064b63 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -67,6 +67,12 @@ struct bma400_sample_freq { int uhz; }; +enum bma400_activity { + BMA400_STILL, + BMA400_WALKING, + BMA400_RUNNING, +}; + struct bma400_data { struct device *dev; struct regmap *regmap; @@ -80,6 +86,7 @@ struct bma400_data { struct iio_trigger *trig; int steps_enabled; bool step_event_en; + bool activity_event_en; /* Correct time stamp alignment */ struct { __le16 buff[3]; @@ -184,6 +191,12 @@ static const struct iio_event_spec bma400_step_detect_event = { .mask_separate = BIT(IIO_EV_INFO_ENABLE), }; +static const struct iio_event_spec bma400_activity_event = { + .type = IIO_EV_TYPE_CHANGE, + .dir = IIO_EV_DIR_NONE, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE), +}; + #define BMA400_ACC_CHANNEL(_index, _axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ @@ -205,6 +218,16 @@ static const struct iio_event_spec bma400_step_detect_event = { }, \ } +#define BMA400_ACTIVITY_CHANNEL(_chan2) { \ + .type = IIO_ACTIVITY, \ + .modified = 1, \ + .channel2 = _chan2, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ + .scan_index = -1, /* No buffer support */ \ + .event_spec = &bma400_activity_event, \ + .num_event_specs = 1, \ +} + static const struct iio_chan_spec bma400_channels[] = { BMA400_ACC_CHANNEL(0, X), BMA400_ACC_CHANNEL(1, Y), @@ -229,6 +252,9 @@ static const struct iio_chan_spec bma400_channels[] = { .event_spec = &bma400_step_detect_event, .num_event_specs = 1, }, + BMA400_ACTIVITY_CHANNEL(IIO_MOD_STILL), + BMA400_ACTIVITY_CHANNEL(IIO_MOD_WALKING), + BMA400_ACTIVITY_CHANNEL(IIO_MOD_RUNNING), IIO_CHAN_SOFT_TIMESTAMP(4), }; @@ -669,6 +695,20 @@ static void bma400_power_disable(void *data_ptr) ERR_PTR(ret)); } +static enum iio_modifier bma400_act_to_mod(enum bma400_activity activity) +{ + switch (activity) { + case BMA400_STILL: + return IIO_MOD_STILL; + case BMA400_WALKING: + return IIO_MOD_WALKING; + case BMA400_RUNNING: + return IIO_MOD_RUNNING; + default: + return IIO_NO_MOD; + } +} + static int bma400_init(struct bma400_data *data) { unsigned int val; @@ -766,6 +806,7 @@ static int bma400_read_raw(struct iio_dev *indio_dev, int *val2, long mask) { struct bma400_data *data = iio_priv(indio_dev); + unsigned int activity; int ret; switch (mask) { @@ -778,6 +819,21 @@ static int bma400_read_raw(struct iio_dev *indio_dev, return ret; case IIO_STEPS: return bma400_get_steps_reg(data, val); + case IIO_ACTIVITY: + ret = regmap_read(data->regmap, BMA400_STEP_STAT_REG, + &activity); + if (ret) + return ret; + /* + * The device does not support confidence value levels, + * so we will always have 100% for current activity and + * 0% for the others. + */ + if (chan->channel2 == bma400_act_to_mod(activity)) + *val = 100; + else + *val = 0; + return IIO_VAL_INT; default: return -EINVAL; } @@ -927,6 +983,8 @@ static int bma400_read_event_config(struct iio_dev *indio_dev, switch (chan->type) { case IIO_STEPS: return data->step_event_en; + case IIO_ACTIVITY: + return data->activity_event_en; default: return -EINVAL; } @@ -964,6 +1022,18 @@ static int bma400_write_event_config(struct iio_dev *indio_dev, ret = bma400_steps_event_enable(data, state); mutex_unlock(&data->mutex); return ret; + case IIO_ACTIVITY: + mutex_lock(&data->mutex); + if (!data->step_event_en) { + ret = bma400_steps_event_enable(data, true); + if (ret) { + mutex_unlock(&data->mutex); + return ret; + } + } + data->activity_event_en = state; + mutex_unlock(&data->mutex); + return 0; default: return -EINVAL; } @@ -1049,6 +1119,7 @@ static irqreturn_t bma400_interrupt(int irq, void *private) struct iio_dev *indio_dev = private; struct bma400_data *data = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(indio_dev); + unsigned int act; int ret; /* Lock to protect the data->status */ @@ -1069,6 +1140,20 @@ static irqreturn_t bma400_interrupt(int irq, void *private) IIO_EV_TYPE_CHANGE, IIO_EV_DIR_NONE), timestamp); + + if (data->activity_event_en) { + ret = regmap_read(data->regmap, BMA400_STEP_STAT_REG, + &act); + if (ret) + goto unlock_err; + + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACTIVITY, 0, + bma400_act_to_mod(act), + IIO_EV_TYPE_CHANGE, + IIO_EV_DIR_NONE), + timestamp); + } } if (FIELD_GET(BMA400_INT_DRDY_MSK, le16_to_cpu(data->status))) { From patchwork Thu May 5 13:30:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839566 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7BCEBC433F5 for ; Thu, 5 May 2022 13:31:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379714AbiEENeh (ORCPT ); Thu, 5 May 2022 09:34:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379526AbiEENeZ (ORCPT ); Thu, 5 May 2022 09:34:25 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37F231277A; Thu, 5 May 2022 06:30:46 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id w17-20020a17090a529100b001db302efed6so4107737pjh.4; Thu, 05 May 2022 06:30:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mymmciEAh6gGaYaWlOmYlAQretqP2MT5VzSw6yN9VE4=; b=qHVoO/0E54JfprinuqbhxVpBAA7BbE5EL3y/U0JqA3synqCvZgtWQi8mW5EtMY33+p bIwaXTdpMzYxIp/CKyY9e6rBXJglIf2qyS3WjTyU+Iiz+AbKxodkclBq1cOBqV/7cWpJ kyPY8k82NP65YbeN4OCVUNkuFGx+u9EEoi1hLHdaQTMpIkrpluSv/HdgmRnD+3nkb+gu ZK7ydaFcNfbAOhn6uWZjfdsmFsBbfXul9bfLlCRGDtAqT6VwLldLt0oLZSiltnJwq82L r0F7xCqDIC+saRyjj0+9GX8NClp11g4UpR+nz/P4cTr2i21LYiNOWnMVikVybfpwlHqq yGog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=mymmciEAh6gGaYaWlOmYlAQretqP2MT5VzSw6yN9VE4=; b=DVBOeO++QkqqQfN8TnWB1IQSMri7PkRrp5cC4bXnj24lzq4zb3DFMB00mTOW9uwkKi vNUeKC9hxHYJU9cAHRHNHSujrQCEylUE2uhth+ANh8cZi066a+4EcgWA9zJ5NrVjL5xr EOw0vQ/oMuQeCwPH0/BRXuvFYywUpk1SmyWIQaAY/ocKkcAaOP+A2fa5u0JiIoXg7XH0 IbGESDQFVVSgFm7BL+wZuzvnmEQo6AD+sxMoU+BjEjLnOmz1dJScRTGz+pIGQII/HVwr FRdpzzHcFKRRypSvUX57Vytn4o9DP22yuGsNBwUMe1RLt48vnYr/Xzf9CqEFZU8VZqpQ Nxrw== X-Gm-Message-State: AOAM530kJhugoNSCl5YR0q4sUzu9351VzQTyPvSkcaEP2QzakRniE5WG uyMuV+vQeJMtEvKA0A7T14DbORYdXas= X-Google-Smtp-Source: ABdhPJxm9caMGIW0coin59QO5bewsdNO2WtZXVNh0EMHuOD0l9Un5WGYUFlVSFuFPknTKgBBQe+hNQ== X-Received: by 2002:a17:90a:cd06:b0:1cb:8c74:2baf with SMTP id d6-20020a17090acd0600b001cb8c742bafmr6154640pju.214.1651757445577; Thu, 05 May 2022 06:30:45 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:45 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 08/10] iio: accel: bma400: Add support for activity and inactivity events Date: Thu, 5 May 2022 19:00:19 +0530 Message-Id: <20220505133021.22362-9-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add support for activity and inactivity events for all axis based on the threshold, duration and hysteresis value set from the userspace. INT1 pin is used to interrupt and event is pushed to userspace. Signed-off-by: Jagath Jog J --- drivers/iio/accel/bma400.h | 11 ++ drivers/iio/accel/bma400_core.c | 232 +++++++++++++++++++++++++++++++- 2 files changed, 242 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index 0faa40fdbbf8..e8f802a82300 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -94,6 +94,17 @@ #define BMA400_ACC_ODR_MIN_WHOLE_HZ 25 #define BMA400_ACC_ODR_MIN_HZ 12 +/* Generic interrupts register */ +#define BMA400_GEN1INT_CONFIG0 0x3f +#define BMA400_GEN2INT_CONFIG0 0x4A +#define BMA400_GEN_CONFIG1_OFF 0x01 +#define BMA400_GEN_CONFIG2_OFF 0x02 +#define BMA400_GEN_CONFIG3_OFF 0x03 +#define BMA400_GEN_CONFIG31_OFF 0x04 +#define BMA400_INT_GEN1_MSK BIT(2) +#define BMA400_INT_GEN2_MSK BIT(3) +#define BMA400_GEN_HYST_MSK GENMASK(1, 0) + /* * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before * converting to micro values for +-2g range. diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 1e4923064b63..8faff72625b3 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -87,6 +87,7 @@ struct bma400_data { int steps_enabled; bool step_event_en; bool activity_event_en; + unsigned int generic_event_en; /* Correct time stamp alignment */ struct { __le16 buff[3]; @@ -94,6 +95,7 @@ struct bma400_data { s64 ts __aligned(8); } buffer __aligned(IIO_ALIGN); __le16 status; + __be16 duration; }; static bool bma400_is_writable_reg(struct device *dev, unsigned int reg) @@ -197,6 +199,25 @@ static const struct iio_event_spec bma400_activity_event = { .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE), }; +static const struct iio_event_spec bma400_accel_event[] = { + { + .type = IIO_EV_TYPE_MAG, + .dir = IIO_EV_DIR_FALLING, + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD) | + BIT(IIO_EV_INFO_HYSTERESIS) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_MAG, + .dir = IIO_EV_DIR_RISING, + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD) | + BIT(IIO_EV_INFO_HYSTERESIS) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + #define BMA400_ACC_CHANNEL(_index, _axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ @@ -216,6 +237,8 @@ static const struct iio_event_spec bma400_activity_event = { .storagebits = 16, \ .endianness = IIO_LE, \ }, \ + .event_spec = bma400_accel_event, \ + .num_event_specs = ARRAY_SIZE(bma400_accel_event) \ } #define BMA400_ACTIVITY_CHANNEL(_chan2) { \ @@ -981,6 +1004,17 @@ static int bma400_read_event_config(struct iio_dev *indio_dev, struct bma400_data *data = iio_priv(indio_dev); switch (chan->type) { + case IIO_ACCEL: + switch (dir) { + case IIO_EV_DIR_RISING: + return FIELD_GET(BMA400_INT_GEN1_MSK, + data->generic_event_en); + case IIO_EV_DIR_FALLING: + return FIELD_GET(BMA400_INT_GEN2_MSK, + data->generic_event_en); + default: + return -EINVAL; + } case IIO_STEPS: return data->step_event_en; case IIO_ACTIVITY: @@ -1008,6 +1042,65 @@ static int bma400_steps_event_enable(struct bma400_data *data, int state) return 0; } +static int bma400_activity_event_en(struct bma400_data *data, + enum iio_event_direction dir, + int state) +{ + int ret, reg, msk, value, field_value; + + switch (dir) { + case IIO_EV_DIR_RISING: + reg = BMA400_GEN1INT_CONFIG0; + msk = BMA400_INT_GEN1_MSK; + value = 2; + set_mask_bits(&field_value, BMA400_INT_GEN1_MSK, + FIELD_PREP(BMA400_INT_GEN1_MSK, state)); + break; + case IIO_EV_DIR_FALLING: + reg = BMA400_GEN2INT_CONFIG0; + msk = BMA400_INT_GEN2_MSK; + value = 0; + set_mask_bits(&field_value, BMA400_INT_GEN2_MSK, + FIELD_PREP(BMA400_INT_GEN2_MSK, state)); + break; + default: + return -EINVAL; + } + + /* Enabling all axis for interrupt evaluation */ + ret = regmap_write(data->regmap, reg, 0xF8); + if (ret) + return ret; + + /* OR combination of all axis for interrupt evaluation */ + ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG1_OFF, value); + if (ret) + return ret; + + /* Initial value to avoid interrupts while enabling*/ + ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG2_OFF, 0x0A); + if (ret) + return ret; + + /* Initial duration value to avoid interrupts while enabling*/ + ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG31_OFF, 0x0F); + if (ret) + return ret; + + ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, msk, + field_value); + if (ret) + return ret; + + ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, msk, + field_value); + if (ret) + return ret; + + set_mask_bits(&data->generic_event_en, msk, field_value); + return 0; +} + static int bma400_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, @@ -1017,6 +1110,11 @@ static int bma400_write_event_config(struct iio_dev *indio_dev, int ret; switch (chan->type) { + case IIO_ACCEL: + mutex_lock(&data->mutex); + ret = bma400_activity_event_en(data, dir, state); + mutex_unlock(&data->mutex); + return ret; case IIO_STEPS: mutex_lock(&data->mutex); ret = bma400_steps_event_enable(data, state); @@ -1039,6 +1137,122 @@ static int bma400_write_event_config(struct iio_dev *indio_dev, } } +static int get_gen_config_reg(enum iio_event_direction dir) +{ + switch (dir) { + case IIO_EV_DIR_FALLING: + return BMA400_GEN2INT_CONFIG0; + case IIO_EV_DIR_RISING: + return BMA400_GEN1INT_CONFIG0; + default: + return -EINVAL; + } +} + +static int bma400_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + struct bma400_data *data = iio_priv(indio_dev); + int ret, reg; + + switch (chan->type) { + case IIO_ACCEL: + reg = get_gen_config_reg(dir); + if (reg < 0) + return -EINVAL; + + *val2 = 0; + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_read(data->regmap, + reg + BMA400_GEN_CONFIG2_OFF, + val); + if (ret) + return ret; + return IIO_VAL_INT; + case IIO_EV_INFO_PERIOD: + mutex_lock(&data->mutex); + ret = regmap_bulk_read(data->regmap, + reg + BMA400_GEN_CONFIG3_OFF, + &data->duration, + sizeof(data->duration)); + if (ret) { + mutex_unlock(&data->mutex); + return ret; + } + *val = be16_to_cpu(data->duration); + mutex_unlock(&data->mutex); + return IIO_VAL_INT; + case IIO_EV_INFO_HYSTERESIS: + ret = regmap_read(data->regmap, reg, val); + if (ret) + return ret; + *val = FIELD_GET(BMA400_GEN_HYST_MSK, *val); + return IIO_VAL_INT; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int bma400_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + struct bma400_data *data = iio_priv(indio_dev); + int reg, ret; + + switch (chan->type) { + case IIO_ACCEL: + reg = get_gen_config_reg(dir); + if (reg < 0) + return -EINVAL; + + switch (info) { + case IIO_EV_INFO_VALUE: + if (val < 1 || val > 255) + return -EINVAL; + + return regmap_write(data->regmap, + reg + BMA400_GEN_CONFIG2_OFF, + val); + case IIO_EV_INFO_PERIOD: + if (val < 1 || val > 65535) + return -EINVAL; + + mutex_lock(&data->mutex); + put_unaligned_be16(val, &data->duration); + ret = regmap_bulk_write(data->regmap, + reg + BMA400_GEN_CONFIG3_OFF, + &data->duration, + sizeof(data->duration)); + mutex_unlock(&data->mutex); + return ret; + case IIO_EV_INFO_HYSTERESIS: + if (val < 0 || val > 3) + return -EINVAL; + + return regmap_update_bits(data->regmap, reg, + BMA400_GEN_HYST_MSK, + FIELD_PREP(BMA400_GEN_HYST_MSK, + val)); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + static int bma400_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { @@ -1071,6 +1285,8 @@ static const struct iio_info bma400_info = { .write_raw_get_fmt = bma400_write_raw_get_fmt, .read_event_config = bma400_read_event_config, .write_event_config = bma400_write_event_config, + .write_event_value = bma400_write_event_value, + .read_event_value = bma400_read_event_value, }; static const struct iio_trigger_ops bma400_trigger_ops = { @@ -1119,7 +1335,7 @@ static irqreturn_t bma400_interrupt(int irq, void *private) struct iio_dev *indio_dev = private; struct bma400_data *data = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(indio_dev); - unsigned int act; + unsigned int act, ev_dir = IIO_EV_DIR_NONE; int ret; /* Lock to protect the data->status */ @@ -1134,6 +1350,20 @@ static irqreturn_t bma400_interrupt(int irq, void *private) if (ret || !data->status) goto unlock_err; + if (FIELD_GET(BMA400_INT_GEN1_MSK, le16_to_cpu(data->status))) + ev_dir = IIO_EV_DIR_RISING; + + if (FIELD_GET(BMA400_INT_GEN2_MSK, le16_to_cpu(data->status))) + ev_dir = IIO_EV_DIR_FALLING; + + if (ev_dir != IIO_EV_DIR_NONE) { + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_MAG, ev_dir), + timestamp); + } + if (FIELD_GET(BMA400_STEP_STAT_MASK, le16_to_cpu(data->status))) { iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, From patchwork Thu May 5 13:30:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA33FC433EF for ; Thu, 5 May 2022 13:31:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379747AbiEENer (ORCPT ); Thu, 5 May 2022 09:34:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379689AbiEENeh (ORCPT ); Thu, 5 May 2022 09:34:37 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB97057106; Thu, 5 May 2022 06:30:48 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id fv2so4212885pjb.4; Thu, 05 May 2022 06:30:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=I+Ws+ESDCKCSc0iPBoRNljcueto4IcsRpZfCHksopWI=; b=KKXZl6QekOe6xPhmZhMXiPBUGHXK8VbLR/FDyLOh5Gtykp7SquBQOi/n0VsvY+vksg O9nnZ16D//6Hkhi74OJTbA69yp7Q9HkuVBcQBbB0r8IdLQLHLwG/wFK72SANTU7BbfMR jPd0H4Cx1RKKHYSrLUaXRmqFSZGKuqTQ/dxzckloGNbqksafkqcvom0DBOtMpu7tDBRu 2DjUJBH/pWLW7Q08aOfxEURwiB3pd+UkQfqiKAwJjshISynHpXruyTjdMMG3r38eu4B1 gfY8mcPxiOADgiCmJjNswsSSYIbX0Cm9nJiqw2grdb2MIRuj20KAq24jvhHqb2moYOqO uSrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=I+Ws+ESDCKCSc0iPBoRNljcueto4IcsRpZfCHksopWI=; b=zR2iRoQEUitRjZxKHukrf6SwvVliRi0iSTUL6xeJsaeNJEJa9MzfDr6WfhYJj+Y20C +1bZZC0RaGnWko/8vktZ86Bnx6NyVRFvAIQ0LMeGBLjKhIajeKv4FWUZbZIqvZoRVETR xMe0nK+VYfHACuoeawmWy7ubAkJTKovskR/tSY3JsyXFWriKhZv5Uyn8tIEQaF8BjvAj +f/CYWYJHZ8s6sSG6PidP4EwJ0znPcHN8AVmwyOZdaujhwN+4kDP0HVlVpeuNCFxiuUp z/LLcT96jx+lutXPwaxFpVfDSwD1vb1n7xv+TSjOgLu57dwtjmh6ZxnvA7UEoaeTVpb7 HkBg== X-Gm-Message-State: AOAM530jO+vwxiyT1X5j013nw3xfsQJF3BqkXAZ6qu38jCGo11k4D/s9 urEQiKpN2/noAqjgJfAmR7SSr6VKRE4= X-Google-Smtp-Source: ABdhPJzxZA7xB146a0crnbNkUITSiJMAyi8PcuuD5sXnsfMdGvB3WFqxfg3i5IDUDgHSq37Uq33+Yg== X-Received: by 2002:a17:902:f28b:b0:15c:5c21:dc15 with SMTP id k11-20020a170902f28b00b0015c5c21dc15mr27752285plc.16.1651757448350; Thu, 05 May 2022 06:30:48 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:47 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 09/10] iio: Add channel for tap and new modifiers for single and double tap Date: Thu, 5 May 2022 19:00:20 +0530 Message-Id: <20220505133021.22362-10-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add new channel type for tap and also add new modifiers for single and double tap. This channel and modifiers may be used by accelerometer sensors to express single and double tap events. For directional tap, modifiers like IIO_MOD_(X/Y/Z) can be used along with rising and falling direction. Signed-off-by: Jagath Jog J --- Documentation/ABI/testing/sysfs-bus-iio | 11 +++++++++++ drivers/iio/industrialio-core.c | 3 +++ include/uapi/linux/iio/types.h | 3 +++ tools/iio/iio_event_monitor.c | 6 ++++++ 4 files changed, 23 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index d4ccc68fdcf0..bf2d10d6ad9b 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -2030,3 +2030,14 @@ Description: Available range for the forced calibration value, expressed as: - a range specified as "[min step max]" + +What: /sys/.../events/in_tap_single_change_en +What: /sys/.../events/in_tap_double_change_en +KernelVersion: 5.19 +Contact: linux-iio@vger.kernel.org +Description: + Accelerometer device detects single or double taps and generate + events when threshold for minimum tap amplitide passes. + E.g. a single tap event is generated when acceleration value + crosses the minimum tap amplitude value set. Where tap threshold + value is set by using in_tap_change_value. diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e1ed44dec2ab..9b0d7bbd07fc 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -87,6 +87,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_POSITIONRELATIVE] = "positionrelative", [IIO_PHASE] = "phase", [IIO_MASSCONCENTRATION] = "massconcentration", + [IIO_TAP] = "tap" }; static const char * const iio_modifier_names[] = { @@ -134,6 +135,8 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_ETHANOL] = "ethanol", [IIO_MOD_H2] = "h2", [IIO_MOD_O2] = "o2", + [IIO_MOD_TAP_SINGLE] = "single", + [IIO_MOD_TAP_DOUBLE] = "double", }; /* relies on pairs of these shared then separate */ diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index 472cead10d8d..d1e61c84e0d5 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -47,6 +47,7 @@ enum iio_chan_type { IIO_POSITIONRELATIVE, IIO_PHASE, IIO_MASSCONCENTRATION, + IIO_TAP, }; enum iio_modifier { @@ -95,6 +96,8 @@ enum iio_modifier { IIO_MOD_ETHANOL, IIO_MOD_H2, IIO_MOD_O2, + IIO_MOD_TAP_SINGLE, + IIO_MOD_TAP_DOUBLE, }; enum iio_event_type { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index 2f4581658859..7fa7d4285f40 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -59,6 +59,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_POSITIONRELATIVE] = "positionrelative", [IIO_PHASE] = "phase", [IIO_MASSCONCENTRATION] = "massconcentration", + [IIO_TAP] = "tap", }; static const char * const iio_ev_type_text[] = { @@ -122,6 +123,8 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_PM4] = "pm4", [IIO_MOD_PM10] = "pm10", [IIO_MOD_O2] = "o2", + [IIO_MOD_TAP_SINGLE] = "single", + [IIO_MOD_TAP_DOUBLE] = "double", }; static bool event_is_known(struct iio_event_data *event) @@ -164,6 +167,7 @@ static bool event_is_known(struct iio_event_data *event) case IIO_POSITIONRELATIVE: case IIO_PHASE: case IIO_MASSCONCENTRATION: + case IIO_TAP: break; default: return false; @@ -215,6 +219,8 @@ static bool event_is_known(struct iio_event_data *event) case IIO_MOD_PM4: case IIO_MOD_PM10: case IIO_MOD_O2: + case IIO_MOD_TAP_SINGLE: + case IIO_MOD_TAP_DOUBLE: break; default: return false; From patchwork Thu May 5 13:30:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagath Jog J X-Patchwork-Id: 12839570 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89F85C433FE for ; Thu, 5 May 2022 13:31:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379529AbiEENez (ORCPT ); Thu, 5 May 2022 09:34:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46554 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379686AbiEENer (ORCPT ); Thu, 5 May 2022 09:34:47 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B63657121; Thu, 5 May 2022 06:30:51 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id d22so4382279plr.9; Thu, 05 May 2022 06:30:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jTmj4puKmdVMk0iRfeIWNKKz6zyGpK0OFgQNQS/Qxw8=; b=MkeU5c0JkJJ2yJEpkTC2pquTM4atEOHGxLkxWaohMILQSAfkyCSXUYMdD1Xwv2GhT9 kpdlQ0KlRJsgAorJo+fM2rk9xAliZxvLc7tdfwJFe1JiNtl5u/f/yA1esNya2y9b4KmA 2k5Y2qwSPfepCQYBudXIe05zquCOdKD5kb4OIKk0n7GSWuJ7JhHD2mUf8XKyMK20dYan Ee2e3li7xYf3oYJWz7LRTiYWzBFivgnBSBdwrknvCUaJNPcaT1maalZnFoq/jp49hwIN odQnaXV8//AM3eLEeXzWU3jkItuPWqQ3f1bhx1hPVuZVc6QbomCMroswD722tqDkvEAp buBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jTmj4puKmdVMk0iRfeIWNKKz6zyGpK0OFgQNQS/Qxw8=; b=IV9fiv8lPeXSN6rqr0edIPcQPZVULg3vT6+rChE+n/uh5tpBLjCEtvAkN+GP/CHP9x hoJpD6gtoHW8TzroaDxKht3yRw+9ASco1bWAJWa6ka/GhLqqtAONpMhZZiiLbo+YJBHB ZfGMG5/GuoL/fp41IgGg6MAkeFHpK0Tm1P6V3bD3ELwPgbsNoNYe6xivmzeKTzlmV6F/ WSW1sufWqn9mBrir7OKlu62y3yhwTVJEoEp0Ekfgcr3qFl0XFqhntUymb8EN+w4P/znb rgdHaJVOf+tyBHcIUn4hDCVw1qlY9m52x7BY5+0VBaMju/r9bTQK7qEFp/1v9qcmL502 QVLg== X-Gm-Message-State: AOAM533q49N7cxUIhc4VY2GQm8EUOL1qyyb3kj4DeoGJ5UU9UGzup0Et ehvXiR3bY+wIzWS125CJtsk= X-Google-Smtp-Source: ABdhPJwMxjJA+pl9gvb9Hmxl0xJS8E+QM73zjEJyRUQuVFj1ICFkFEPq4Muf5xlEL0jimm3lLBwp0w== X-Received: by 2002:a17:902:c946:b0:15e:9c09:715a with SMTP id i6-20020a170902c94600b0015e9c09715amr22958281pla.168.1651757450941; Thu, 05 May 2022 06:30:50 -0700 (PDT) Received: from localhost.localdomain ([115.99.184.228]) by smtp.gmail.com with ESMTPSA id c64-20020a624e43000000b0050dc7628135sm1420120pfb.15.2022.05.05.06.30.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 May 2022 06:30:50 -0700 (PDT) From: Jagath Jog J To: dan@dlrobertson.com, jic23@kernel.org, andy.shevchenko@gmail.com Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 10/10] iio: accel: bma400: Add support for single and double tap events Date: Thu, 5 May 2022 19:00:21 +0530 Message-Id: <20220505133021.22362-11-jagathjog1996@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220505133021.22362-1-jagathjog1996@gmail.com> References: <20220505133021.22362-1-jagathjog1996@gmail.com> Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add support for single and double tap events based on the tap threshold value and minimum quite time value between the taps. INT1 pin is used to interrupt and event is pushed to userspace. Signed-off-by: Jagath Jog J --- drivers/iio/accel/bma400.h | 11 ++ drivers/iio/accel/bma400_core.c | 176 ++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h index e8f802a82300..7331474433fa 100644 --- a/drivers/iio/accel/bma400.h +++ b/drivers/iio/accel/bma400.h @@ -40,6 +40,7 @@ #define BMA400_INT_STAT1_REG 0x0f #define BMA400_INT_STAT2_REG 0x10 #define BMA400_INT12_MAP_REG 0x23 +#define BMA400_INT_ENG_OVRUN_MSK BIT(4) /* Temperature register */ #define BMA400_TEMP_DATA_REG 0x11 @@ -105,6 +106,16 @@ #define BMA400_INT_GEN2_MSK BIT(3) #define BMA400_GEN_HYST_MSK GENMASK(1, 0) +/* TAP config registers */ +#define BMA400_TAP_CONFIG 0x57 +#define BMA400_TAP_CONFIG1 0x58 +#define BMA400_S_TAP_MSK BIT(2) +#define BMA400_D_TAP_MSK BIT(3) +#define BMA400_INT_S_TAP_MSK BIT(10) +#define BMA400_INT_D_TAP_MSK BIT(11) +#define BMA400_TAP_SEN_MSK GENMASK(2, 0) +#define BMA400_TAP_QUITE_MSK GENMASK(3, 2) + /* * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before * converting to micro values for +-2g range. diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c index 8faff72625b3..9d19a0afd683 100644 --- a/drivers/iio/accel/bma400_core.c +++ b/drivers/iio/accel/bma400_core.c @@ -88,6 +88,7 @@ struct bma400_data { bool step_event_en; bool activity_event_en; unsigned int generic_event_en; + unsigned int tap_event_en; /* Correct time stamp alignment */ struct { __le16 buff[3]; @@ -187,6 +188,14 @@ static const struct iio_chan_spec_ext_info bma400_ext_info[] = { { } }; +static const struct iio_event_spec bma400_tap_event = { + .type = IIO_EV_TYPE_CHANGE, + .dir = IIO_EV_DIR_NONE, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD), +}; + static const struct iio_event_spec bma400_step_detect_event = { .type = IIO_EV_TYPE_CHANGE, .dir = IIO_EV_DIR_NONE, @@ -251,6 +260,19 @@ static const struct iio_event_spec bma400_accel_event[] = { .num_event_specs = 1, \ } +/* + * Single Tap and Double Tap events needs to be captured instantly, so only + * events are being configured. + */ +#define BMA400_TAP_CHANNEL(_chan2) { \ + .type = IIO_TAP, \ + .modified = 1, \ + .channel2 = _chan2, \ + .scan_index = -1, /* No buffer support */ \ + .event_spec = &bma400_tap_event, \ + .num_event_specs = 1, \ +} + static const struct iio_chan_spec bma400_channels[] = { BMA400_ACC_CHANNEL(0, X), BMA400_ACC_CHANNEL(1, Y), @@ -278,6 +300,8 @@ static const struct iio_chan_spec bma400_channels[] = { BMA400_ACTIVITY_CHANNEL(IIO_MOD_STILL), BMA400_ACTIVITY_CHANNEL(IIO_MOD_WALKING), BMA400_ACTIVITY_CHANNEL(IIO_MOD_RUNNING), + BMA400_TAP_CHANNEL(IIO_MOD_TAP_SINGLE), + BMA400_TAP_CHANNEL(IIO_MOD_TAP_DOUBLE), IIO_CHAN_SOFT_TIMESTAMP(4), }; @@ -407,6 +431,14 @@ static int bma400_set_accel_output_data_rate(struct bma400_data *data, unsigned int val; int ret; + /* + * No need to change ODR when tap event is enabled because + * tap interrupt is operating with the data rate of 200Hz. + * See datasheet page 124. + */ + if (data->tap_event_en) + return -EBUSY; + if (hz >= BMA400_ACC_ODR_MIN_WHOLE_HZ) { if (uhz || hz > BMA400_ACC_ODR_MAX_HZ) return -EINVAL; @@ -1019,6 +1051,15 @@ static int bma400_read_event_config(struct iio_dev *indio_dev, return data->step_event_en; case IIO_ACTIVITY: return data->activity_event_en; + case IIO_TAP: + switch (chan->channel2) { + case IIO_MOD_TAP_SINGLE: + return FIELD_GET(BMA400_S_TAP_MSK, data->tap_event_en); + case IIO_MOD_TAP_DOUBLE: + return FIELD_GET(BMA400_D_TAP_MSK, data->tap_event_en); + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1101,6 +1142,74 @@ static int bma400_activity_event_en(struct bma400_data *data, return 0; } +static int bma400_tap_event_enable(struct bma400_data *data, + enum iio_modifier mod, int state) +{ + int ret; + unsigned int mask, field_value; + + if (data->power_mode == POWER_MODE_SLEEP) + return -EBUSY; + + /* + * acc_filt1 is the data source for the tap interrupt and it is + * operating on an input data rate of 200Hz. + */ + if (!data->tap_event_en) { + ret = bma400_set_accel_output_data_rate(data, 200, 0); + if (ret) + return ret; + } + + ret = regmap_update_bits(data->regmap, BMA400_INT12_MAP_REG, + BMA400_S_TAP_MSK, + FIELD_PREP(BMA400_S_TAP_MSK, state)); + if (ret) + return ret; + + switch (mod) { + case IIO_MOD_TAP_SINGLE: + mask = BMA400_S_TAP_MSK; + set_mask_bits(&field_value, BMA400_S_TAP_MSK, + FIELD_PREP(BMA400_S_TAP_MSK, state)); + break; + case IIO_MOD_TAP_DOUBLE: + mask = BMA400_D_TAP_MSK; + set_mask_bits(&field_value, BMA400_D_TAP_MSK, + FIELD_PREP(BMA400_D_TAP_MSK, state)); + break; + default: + return -EINVAL; + } + + ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG1_REG, mask, + field_value); + if (ret) + return ret; + + set_mask_bits(&data->tap_event_en, mask, field_value); + return 0; +} + +static int bma400_disable_adv_interrupt(struct bma400_data *data) +{ + int ret; + + ret = regmap_write(data->regmap, BMA400_INT_CONFIG0_REG, 0); + if (ret) + return ret; + + ret = regmap_write(data->regmap, BMA400_INT_CONFIG1_REG, 0); + if (ret) + return ret; + + data->tap_event_en = 0; + data->generic_event_en = 0; + data->step_event_en = 0; + data->activity_event_en = 0; + return 0; +} + static int bma400_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, @@ -1132,6 +1241,11 @@ static int bma400_write_event_config(struct iio_dev *indio_dev, data->activity_event_en = state; mutex_unlock(&data->mutex); return 0; + case IIO_TAP: + mutex_lock(&data->mutex); + ret = bma400_tap_event_enable(data, chan->channel2, state); + mutex_unlock(&data->mutex); + return ret; default: return -EINVAL; } @@ -1196,6 +1310,23 @@ static int bma400_read_event_value(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_TAP: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_read(data->regmap, BMA400_TAP_CONFIG, val); + if (ret) + return ret; + *val = FIELD_GET(BMA400_TAP_SEN_MSK, *val); + return IIO_VAL_INT; + case IIO_EV_INFO_PERIOD: + ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1, val); + if (ret) + return ret; + *val = FIELD_GET(BMA400_TAP_QUITE_MSK, *val); + return IIO_VAL_INT; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1248,6 +1379,29 @@ static int bma400_write_event_value(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_TAP: + switch (info) { + case IIO_EV_INFO_VALUE: + if (val < 0 || val > 7) + return -EINVAL; + + return regmap_update_bits(data->regmap, + BMA400_TAP_CONFIG, + BMA400_TAP_SEN_MSK, + FIELD_PREP(BMA400_TAP_SEN_MSK, + val)); + case IIO_EV_INFO_PERIOD: + if (val < 0 || val > 3) + return -EINVAL; + + return regmap_update_bits(data->regmap, + BMA400_TAP_CONFIG1, + BMA400_TAP_QUITE_MSK, + FIELD_PREP(BMA400_TAP_QUITE_MSK, + val)); + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1336,6 +1490,7 @@ static irqreturn_t bma400_interrupt(int irq, void *private) struct bma400_data *data = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(indio_dev); unsigned int act, ev_dir = IIO_EV_DIR_NONE; + unsigned int ev_mod = IIO_NO_MOD; int ret; /* Lock to protect the data->status */ @@ -1350,6 +1505,27 @@ static irqreturn_t bma400_interrupt(int irq, void *private) if (ret || !data->status) goto unlock_err; + /* Disable all advance interrupts if interrupt engine overrun occurs */ + if (FIELD_GET(BMA400_INT_ENG_OVRUN_MSK, le16_to_cpu(data->status))) { + bma400_disable_adv_interrupt(data); + dev_err(data->dev, "Interrupt engine overrun\n"); + goto unlock_err; + } + + if (FIELD_GET(BMA400_INT_S_TAP_MSK, le16_to_cpu(data->status))) + ev_mod = IIO_MOD_TAP_SINGLE; + + if (FIELD_GET(BMA400_INT_D_TAP_MSK, le16_to_cpu(data->status))) + ev_mod = IIO_MOD_TAP_DOUBLE; + + if (ev_mod != IIO_NO_MOD) { + iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_TAP, 0, + ev_mod, IIO_EV_TYPE_CHANGE, + IIO_EV_DIR_NONE), + timestamp); + } + if (FIELD_GET(BMA400_INT_GEN1_MSK, le16_to_cpu(data->status))) ev_dir = IIO_EV_DIR_RISING;