From patchwork Thu Feb 20 10:42:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983691 Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 778AA1CAA9C; Thu, 20 Feb 2025 10:42:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048163; cv=none; b=JiTvBRYqr2kl8TFrrMoE6tsOetFRkIowwOol2sqXHpvmF4GQvB6zRmjif4ekMAeO36gZzO85hwD+3uDSnpmZbGGcdzeYaBDrFpH8GCjXTs2pcbFuS0kSrp6phuUppn94Ro8LCzgk0xVmt3vB1KPh3JkVQZk13il5dXbDhHnSYhs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048163; c=relaxed/simple; bh=N5wPUtEL8GafvraaTitozwAcmvfIG4+F6qsLJt/dB1o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SoEjivoFAvbDEVY2/bqQidnSyExojwc9/+zVm4vaiNaXt/l9KcYan9jWcEfGp9EyLh8TkESkFCXy2dpqjA24vmFApSAOA8UHodLbIGERu76sxvXkxe0VK2NWvk43G8bytvo4n7ZvLxrDQnWv5MKqeBbEp33CPRnEdAy8r7UFYPs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=GyqVRMrn; arc=none smtp.client-ip=209.85.218.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GyqVRMrn" Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-abbb16a0565so12153266b.1; Thu, 20 Feb 2025 02:42:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048160; x=1740652960; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mvbwv18cfnvcZ2p2D0qtMZqem9sYjjTgAWQthVEWC7o=; b=GyqVRMrne+kYaf7I17TOJSxuixUCOFRX1Rv2dtHYiKQvu5gLk/+ZZ6QkWsiCEu/iBK +F4WZudb30jylzr7rMwsgrYxgkUEHHISWij4Gkwb/Mb6/olkRaxcTd+J5SPs+4SFd3+P MQTLZT90kDKv4z0XbOiQenhAwkrF5Mb5c51dX9xTi1nigq0iphgW6xB1Rd4mxPHBX5/h 4d21VaO4mhiL3TOq29IfE6/aVOCBI+X6o4mTdB9omnPQmqsIZjxcdaSlpsbCXx6DQNlJ jDEyAsA37dvAYT5E8hDPkkdsShX8I02dp75gYXRdoAnB0AkagaTpMpHkDxnBUT4KK8ti JYrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048160; x=1740652960; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mvbwv18cfnvcZ2p2D0qtMZqem9sYjjTgAWQthVEWC7o=; b=irmLMnU61QSZsOJ6nJne5/EsGfUVkgBwX/91rI74xSMmlrwWl5AKLnfD4qt8D5jNi1 xty9WYrKuM1atBxupbk2AIRykd4CW2hpQDCEjWAM2/QpbJr+nL0UjPeFd0FVNqiTv35W f6D+s9uj8imp02lFq5zRw9wBL0SNKnYl1gou7rXM6HQwRtxwKyWOt9wpX5QJCiXOKPEV DwHKldfpAtYD9/TDxE6vk/yWgcBu5kFvv/maJoPCfuMuJuJmi8ntoBJdb9nq/1FcRpus bugOfodwSuqI0BjDg4B+Tch6DX5QSaQ9hFVG31xNsglYTTB5vk8g8FSsstsHtWPXG7gO uzyg== X-Forwarded-Encrypted: i=1; AJvYcCUANY+9e6ZkNdNKmNwa9GGcS8vdV3ReAgwzxz8cM2TDYCv6GR8o5zUcfREopJOmY0dgoI7+wSpiZ3RPQ1Q=@vger.kernel.org X-Gm-Message-State: AOJu0Yzyd377k/Dmfp9Hv5j74dThYnjwOz2RP3QGbYIqYLlmwDD7rFxO BTR+tyy66qXvcCnBt5kjvQ/JM2QdmBNYYYatO9YvQoSH6oKHKgVP X-Gm-Gg: ASbGncv6upiyTbXZWCusxG24uC2FoRCeplc3Yz7Nf9A53+1aM8VsFYUnvm9FmNpHcMw e6Q91nZuom1HfTDc08FhNcsWqSRju1kwUL6JVPKf4OrmzlPsATxokaCEhWhBbvIBDH6PunJQTdf 8YcGtWnmO0iPrdRNVHdWmqT1G36M59GTpQ+WsNlVeVMITTT0rsJwfcKtTtG0R63YOsldiq2DrBb R3ONS/AyEo4NBhnmV7iLfVpmsSzhgLO3/PgX4QE0/1QH4P9rRm0rDNlulTzhWis+JOMFP8IvwbR cqQ4V/dtRTy638C4aUhlka/zPncAVFJElL3ott/Od1J6g3a3z1lS9W2jmkQiPl0MTrHksA== X-Google-Smtp-Source: AGHT+IGUI2g+a2PDsMQXCnov2E7hRm5r7BSy/Cm728dhccNNiZNOm8E99POXf14RkcGPt+8ikOjCYg== X-Received: by 2002:a17:907:d8b:b0:ab6:58e4:4fec with SMTP id a640c23a62f3a-abb7093370fmr829356866b.3.1740048159422; Thu, 20 Feb 2025 02:42:39 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:39 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 01/15] iio: accel: adxl345: reorganize measurement enable Date: Thu, 20 Feb 2025 10:42:20 +0000 Message-Id: <20250220104234.40958-2-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Move the measurement enable function up in order to have it generically available. This is a preparation for upcomming patches. Particular features need to have measuring off while changing settings, and turned on again afterwards. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index ed0291bea0f5..c24692c51893 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -76,6 +76,26 @@ static const unsigned long adxl345_scan_masks[] = { 0 }; +/** + * adxl345_set_measure_en() - Enable and disable measuring. + * + * @st: The device data. + * @en: Enable measurements, else standby mode. + * + * For lowest power operation, standby mode can be used. In standby mode, + * current consumption is supposed to be reduced to 0.1uA (typical). In this + * mode no measurements are made. Placing the device into standby mode + * preserves the contents of FIFO. + * + * Return: Returns 0 if successful, or a negative error value. + */ +static int adxl345_set_measure_en(struct adxl345_state *st, bool en) +{ + unsigned int val = en ? ADXL345_POWER_CTL_MEASURE : ADXL345_POWER_CTL_STANDBY; + + return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); +} + static int adxl345_set_interrupts(struct adxl345_state *st) { int ret; @@ -214,26 +234,6 @@ static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev, } } -/** - * adxl345_set_measure_en() - Enable and disable measuring. - * - * @st: The device data. - * @en: Enable measurements, else standby mode. - * - * For lowest power operation, standby mode can be used. In standby mode, - * current consumption is supposed to be reduced to 0.1uA (typical). In this - * mode no measurements are made. Placing the device into standby mode - * preserves the contents of FIFO. - * - * Return: Returns 0 if successful, or a negative error value. - */ -static int adxl345_set_measure_en(struct adxl345_state *st, bool en) -{ - unsigned int val = en ? ADXL345_POWER_CTL_MEASURE : ADXL345_POWER_CTL_STANDBY; - - return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); -} - static void adxl345_powerdown(void *ptr) { struct adxl345_state *st = ptr; From patchwork Thu Feb 20 10:42:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983692 Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 78EF31F03E5; Thu, 20 Feb 2025 10:42:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048164; cv=none; b=g1xDHOa99OUzVBgCtyIxwyrPOFVmISpgcusf8R5j6BbIFseXaJaYylrtEm6BN48Yf1xRY/mxRKeThGeHhWardr8fueJWqeCKNdGnesb/oCNjWMReu7LV3cJhv2uZi0X7kfkzvZaK5z/cEBGNaRgExGLEfKIPM4oR15fdYYCrIuU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048164; c=relaxed/simple; bh=4lgqPxMFIxcu6DJtyKvsa6jPFpK3C+Ewcmj6hhpH5wg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SmnBA1adFt4ZqlgglewJ4653zBkvpDf9iUy3xshN0kV3gZlVKbyg0XfcWTl/2+nTeHbnY+tbM5H5iPjouqeWOT7PT2dM1FE6JwDK7D/AtCp4BWhT1F9RxhvEGflWftXivsMgJIBtUyngT0ciPK3K02l139p5ExuNewQU/DVdcG4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=g8wPpLT8; arc=none smtp.client-ip=209.85.218.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="g8wPpLT8" Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-abb88d2b67eso9750766b.0; Thu, 20 Feb 2025 02:42:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048161; x=1740652961; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4OpRgAIuBhfsxGTEjf/p9nsoY6yTj5Mb2FMWgMOeJw4=; b=g8wPpLT8jlwW9g3Hm3YMP13TCRKythq4GFmeANtsCnjKjwH09usYs97iLbE/vO+bwJ 56N3CGl2zSl1pQ2nNuUYX1rfMXqCqJbylLhrEosJGjrCSkJcvCjKwnJBOxF0B6RB8tvK KMMVFk1BbMq8RTXabEt/ZulIsgA7YuwTHJRdoYbG6FZMK1iT3EqntFxS98/eHD5jiO5x HLoCymBhjpVB2AcVA1qmKUkNHb7XxD/Mw3+mb2giINSqcTJPO5L6XTNR0d0qq2hfMl1O 28iXq4p4nQN4iXS6WcYkY5mrGmDCVT4wasEw/CUbhPYfuGCKjw+IzCs9t4u7PGbDYDcd ZA+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048161; x=1740652961; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4OpRgAIuBhfsxGTEjf/p9nsoY6yTj5Mb2FMWgMOeJw4=; b=ORgfw7/bTyUYd4O9I91pCtqInULMGWF+uxOhxxzDPbtpB8qwC2WfzmdJAWMyXhvk8M XA2DQruK53FilDH6jEcIyryooUwyDCJFvmQK87kYROC++4SQ+rIUJagSW2cpSO7Pgd6p EZ+mGNntlVbOPnse9OWStAcw9cZmDbeiswZYKUDmQ5HW+YvrU8MYMN+B+O5akG21bKvY xzT/QECdgYtrT/tbiRmoS4ddAZPLkop4WtQlzAS1mQwdlgxn+J3Ds1XyuAp2cO38jpS2 k2SQWJRzi2r8Kp9b/4fjwRJwi1VRReBzZncFsp43+wKMMLqJ7kXMCaMGQ2MlKDqkbdLs lpGQ== X-Forwarded-Encrypted: i=1; AJvYcCU9J5QfbEiGY7NHNU08fauUZkM+8vrE8lPwJVwn9zLIfCQUJeOinEwZonHLnINi3EMP83k1jd12yIMN1EE=@vger.kernel.org X-Gm-Message-State: AOJu0YyPKixKCOLWWMb5VpeOJdFIBgyTn5Lt81vU3sTuKvjOM+L7c7FR Z1O6yAxnALOfKN+yjRdc7tyy2jHjTCIBNWgWt9C1CpksE4kRMzVBkIrzToIq X-Gm-Gg: ASbGncumn1FtYm70MzRvk1YsMM8rtAUHCRCO4ZGR8gBGStsibNl+Xda5wFW7BYyzByY 1GfvrwcePYwMxPuXJ7TxyYjOn9TyplWJxEOzjBwX7ZU58aY1hYTOnVmymbwOgACAMZ0fXrk2VMW 1JfOKZSE2M35c8nNFZ7GsvCf+8hQjcSLXJ4ywdJpaLR8oDi2YtQe7bXEWsRRldX5qCr5Jem7AaI cwW5kW4GpUIXkgYdJFVGb34Js7XvYR8W9vbWSI6MUNOcLp9n9lpiZsU0P45szceQW3yJOENq9Si Zpje+qqpsJj/JZBagdAF4R8vH5Jhdxvm9qz8Cmigb9Mw9RVTWyhKSZQSzWP7G/OYD1mjuA== X-Google-Smtp-Source: AGHT+IHnFoe6bIJfsSDBY7fpovozMf7SUh1HcrEqkNrZXuhExvE5KIsUs/T2iEUh7f+0Qg6FZ8yovQ== X-Received: by 2002:a17:907:96a2:b0:ab7:cb76:1b0f with SMTP id a640c23a62f3a-abb70e2a93dmr799471366b.12.1740048160491; Thu, 20 Feb 2025 02:42:40 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:40 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 02/15] iio: accel: adxl345: add debug register access Date: Thu, 20 Feb 2025 10:42:21 +0000 Message-Id: <20250220104234.40958-3-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the possibility to verify the content of the configuration registers of the sensor in preparation for upcomming feature implementations. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index c24692c51893..468d562de227 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -202,6 +202,16 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, return -EINVAL; } +static int adxl345_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct adxl345_state *st = iio_priv(indio_dev); + + if (readval) + return regmap_read(st->regmap, reg, readval); + return regmap_write(st->regmap, reg, writeval); +} + static int adxl345_set_watermark(struct iio_dev *indio_dev, unsigned int value) { struct adxl345_state *st = iio_priv(indio_dev); @@ -467,6 +477,7 @@ static const struct iio_info adxl345_info = { .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, .write_raw_get_fmt = adxl345_write_raw_get_fmt, + .debugfs_reg_access = &adxl345_reg_access, .hwfifo_set_watermark = adxl345_set_watermark, }; From patchwork Thu Feb 20 10:42:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983693 Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FFA01F1501; Thu, 20 Feb 2025 10:42:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048165; cv=none; b=LqJhhr9GgDMPpLLCpWXQKOpEFY1rwSIpYli7+MiXslJubaegSnwPnix6ceSJpTe3u7l1hnqyxjyRty0ErmJxs2tQj/dfhkPIAAYXpP8Gh2QSye4Ms3yXNgAowT/D2ye/hCTfZCRaVGLzkf8WufBVG8wyVWtEjUispWwQ8xodv/A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048165; c=relaxed/simple; bh=wbxfX09TzoIBMSmBgptsO5WWrSNdjcsVRR4ZDcDUhbo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=s/GOesY69MhzXk9e2kUpkcxrJaCvFvHAbTAPLCajEV4bo1WdhsCFAYzTB5b/hOmzE8RhFum3HTWaFgkH7pVXt0NmZ3MSf9/M9q5HMUi1dKU27Aao254NZMOwgm6psx/z+2zNJsVohjA66wJ0aIGnD1devuY/eyc6Sq1ROgtvcd4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JdPrcW0N; arc=none smtp.client-ip=209.85.218.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JdPrcW0N" Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-abb7d5a6577so8420866b.2; Thu, 20 Feb 2025 02:42:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048162; x=1740652962; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8K2ZzOa2Uc4cWyjff2Lb5mmcv1j444GezcCQd7LSPuE=; b=JdPrcW0NdMSc6cF0y+WxeUw1v/V/nBohnjF6jrcVsDuPKKYEQCaaJK9l+Bje/A1r8b f9XNpLjk4pm3YqjeJ6FDyJw/2JCTWZCcIVYLu6XbJRkG/5y6jcoJpjGoi+P2k7GBpy2o h7yJINV6qaZEOiaSp5I+kOo1J+XiZBEd3HclG9i+XqRlGxeyg08unbEykxprvhVJpt8k BJEXtg2lU28o6bWEznmUIf0lFytTmQeHl99BUXNeYHBSIRbK1+d9wJccB82BGiym1Ago bQ6VZEg3bRFCccbtRKPnHzy9CHe8J7jsM78cpxeZsoPVZtS0gIMS0H2DHXUMfgkT7IQK 62hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048162; x=1740652962; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8K2ZzOa2Uc4cWyjff2Lb5mmcv1j444GezcCQd7LSPuE=; b=DMtDPQS2KH7HyVb+QZ4K1rv8DbYM7uPQgiDcKuwpReWRXHzusGiuyOMnF1YLzN2xbH rZ3FDm83nwv2SkMQPo17B7tjR65M9xw2CIumGWnAlTl0yAex4ZiZImADH+6vpMRmxO14 r9wQ/Zl80XIAXibufBwe/VkQmT7RgPDryIq8MAH6LW3v87n8LEJYFZbRZ+541hVpdV9+ nz2vdaAiF+9ytbHj3KropEPldOkP0vyZQ2U2zXwa2BOTL5Td35kymZ1GnN3UE+bI0+N4 7FzjqnjWyoABbElKTlndPsYR/HkSORhRyWBqQsfkLza32c6CD7SsLRezq1gmZ8+86dLG j5Nw== X-Forwarded-Encrypted: i=1; AJvYcCU6y749zyZUnNMn2VH+20wAykL9zX5Sz5E0B22x04/WngZ2t5b+U/GLoFrcVRZ0AMCxZQFskW4uOo+y9Uk=@vger.kernel.org X-Gm-Message-State: AOJu0Ywu3WiyzXkXew1qiYgZjAUYKtvJT7W+6FL/fFpnewGcCT4gjTCu Kn2k/BZW/6RYpJpPQFwyMYcJxFGaBu50RzsoYlJtcu1Ijm6Eb1tK X-Gm-Gg: ASbGncuhV9Fe7nrHRzjzwgapHb6pcitDAnxXbttg9PPEyDS5L1nRTkXJ897gFb1zhdk uFGM5o8Vm+DqR44Nt8/s52ANW13HwG9LlGb13j5PBBxetGoGXRo53gonuRlbMW5QTQZdGoGz/Yf dFHqqoCScFldmHc10qgYGCMU4kENa5OX3GWpkbht7Eg/f0oW4QBwMZzv6Xa7lmKowoYMnMLD4LY 6u3URu8bxOAiK+q9W+4IIoqGADctzW3Gq9vyrY6vulwPeq8I2OzIXbFqdSeM5WwTj+ozDCuGMUc /aUThUbf0EA8F7RDf2hubRWyZrefGhu6lmGmnYWAG1vK7+LiWs1/gsSKkxgo0p8s6RqZTQ== X-Google-Smtp-Source: AGHT+IGT+/snrJ81C+C5modsjEmsHXltWHyhfaacH0dJK/NVjdAEeW5BTNpL5U6oVcNgkPtQke1sEw== X-Received: by 2002:a17:907:3f9a:b0:ab6:d660:c84a with SMTP id a640c23a62f3a-abb70ab8c2dmr829701366b.4.1740048161507; Thu, 20 Feb 2025 02:42:41 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:41 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 03/15] iio: accel: adxl345: reorganize irq handler Date: Thu, 20 Feb 2025 10:42:22 +0000 Message-Id: <20250220104234.40958-4-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Reorganize the IRQ handler. Move the overrun handling to the bottom. Overrun leads to reset the interrupt register. This also happens at evaluation of a particular interrupt event. First evaluate an event if possible, then fall back to overrun handling. Additionally simplify fetching the interrupt status function. Both is in preparation to build interrupt handling up for the handling of different detected events, implemented in follow up patches. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345.h | 1 - drivers/iio/accel/adxl345_core.c | 27 +++++++-------------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h index 517e494ba555..bc6d634bd85c 100644 --- a/drivers/iio/accel/adxl345.h +++ b/drivers/iio/accel/adxl345.h @@ -43,7 +43,6 @@ #define ADXL345_REG_INT_ENABLE 0x2E #define ADXL345_REG_INT_MAP 0x2F #define ADXL345_REG_INT_SOURCE 0x30 -#define ADXL345_REG_INT_SOURCE_MSK 0xFF #define ADXL345_REG_DATA_FORMAT 0x31 #define ADXL345_REG_XYZ_BASE 0x32 #define ADXL345_REG_DATA_AXIS(index) \ diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 468d562de227..22c5a9c08459 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -107,8 +107,7 @@ static int adxl345_set_interrupts(struct adxl345_state *st) * interrupts to the INT1 pin, whereas bits set to 1 send their respective * interrupts to the INT2 pin. The intio shall convert this accordingly. */ - int_map = FIELD_GET(ADXL345_REG_INT_SOURCE_MSK, - st->intio ? st->int_map : ~st->int_map); + int_map = st->intio ? st->int_map : ~st->int_map; ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, int_map); if (ret) @@ -404,18 +403,6 @@ static const struct iio_buffer_setup_ops adxl345_buffer_ops = { .predisable = adxl345_buffer_predisable, }; -static int adxl345_get_status(struct adxl345_state *st) -{ - int ret; - unsigned int regval; - - ret = regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, ®val); - if (ret < 0) - return ret; - - return FIELD_GET(ADXL345_REG_INT_SOURCE_MSK, regval); -} - static int adxl345_fifo_push(struct iio_dev *indio_dev, int samples) { @@ -449,14 +436,10 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) int int_stat; int samples; - int_stat = adxl345_get_status(st); - if (int_stat <= 0) + if (regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &int_stat)) return IRQ_NONE; - if (int_stat & ADXL345_INT_OVERRUN) - goto err; - - if (int_stat & ADXL345_INT_WATERMARK) { + if (FIELD_GET(ADXL345_INT_WATERMARK, int_stat)) { samples = adxl345_get_samples(st); if (samples < 0) goto err; @@ -464,6 +447,10 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) if (adxl345_fifo_push(indio_dev, samples) < 0) goto err; } + + if (FIELD_GET(ADXL345_INT_OVERRUN, int_stat)) + goto err; + return IRQ_HANDLED; err: From patchwork Thu Feb 20 10:42:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983694 Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79E5D1F1521; Thu, 20 Feb 2025 10:42:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048166; cv=none; b=S5IWxdYU2PQFhmxrIORkquyzluikUHmLo/5yNJ0FHlRlbMnuTpC0OBnjttPojxmrvjmLvOPPnf5E9yTBG4ieXbGl0PPCIAsAeQJ9ws/PIxkmqU8MGMY11/ilhVsHQItdMfmWzEqYH3MaquqZnbIi9p5H8XWMVELZ9iViKz0rOb0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048166; c=relaxed/simple; bh=7vddfWcgN5NPgYxESRfdWR+ETzQmOz72tXjE8Ji6AKM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=CQ80rVLW9jFtGtvMMBl5FOqFluGBzuQC/SHv5EEHBTnytXN09AxJ7KCBB/cZFvwJDTdTbZb0mfFudVU5BP4E9rfDy1gFHUzUBrRxhQH1PX58GUhSZeZeoiZGDMklhamPuuunq74ICRhnXGwGE/6f8qhXeJerzWnl/PLRfBWNvlg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=O/jtmgTm; arc=none smtp.client-ip=209.85.218.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="O/jtmgTm" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ab7ee6f5535so12111766b.1; Thu, 20 Feb 2025 02:42:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048163; x=1740652963; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=O6PsnNzOuhiDxjE9qBwgD4F49zf6LzwC4nPLEAzL+KI=; b=O/jtmgTmEO5M5jZu6oiq9Mzn+XwszVw9nA1Tvo8KTfa2WxaUK76+dUIHKd7zyYZrUm ZybUYGuJTWbPZwTRfry6sOodme1UU6NSwXhr+Uj3Vp5Gu3zO3PJBAQzBb6SqNI1qVX+r wiDamsXRDaDliYo20P9gm8MAkte29EWQZPXDSiHJcpa2UNIMsTBC9eJa/PaaayqtnmG/ /qituWdLX1cW0tzJneXDplHdJZhXUa4QUOrODO9eHO+ItvPqvaDpVcB802zhjWohzGCK X1jkuCMi+3pbxe9L8kFJYIKmhEumq9SFXx2AxA2cywjhaxIFZKaelWWPzPCuHl1/kQxO OOeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048163; x=1740652963; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=O6PsnNzOuhiDxjE9qBwgD4F49zf6LzwC4nPLEAzL+KI=; b=Fk6tuquqOQugxHeJ4JkCZgnJAc22J/mSpTBxioaBhxbN9OwPm3PFuutdgBvTSB658U eOb91th4+VPA9uQPZc538Ij8IdK49Hx0xhYo+/cZxMbz9xLdEcgVpR3GcrfcfN7FjYB/ BhJXTQhjzi0HAvSzfAYCSXIZsq5hT6WQqfZ4qjyca5cA0QpNWTHvUuguwiH/eh4Yv5mm I6cZiEVAA3R2vAp866EjohPhT0pIq5gprweUEzdxro9h+M2AcEW9+wtw4/Jrn9kipjmU UQJCpXPiY/gDA8R+yEok82fEky9zmsMl5BtGKURV75cCbKJi6KrgJVjQP4FgZw8zpXxg 88oQ== X-Forwarded-Encrypted: i=1; AJvYcCVhPo+lPviwmcCOQ9Lewz4Ts9ypTKdn6py6utD2zdZilLiHQb4uFh0oJkbzFXRGG10MEpYyQjLeSOSxJUA=@vger.kernel.org X-Gm-Message-State: AOJu0YzHhs0T2xkQtSiHVJ0vJzoUfPVOJQxIZ0L6wixdITkPm7eX0F4d GHhdprhk0QPUz8nmkvMUc3TaImSMA4d89PzWY/jhvVkMGRws8FRQ X-Gm-Gg: ASbGnct907s9QEPZawY47j7OXewRw/NciFVCH3GXbYMpKrRK5XETMWYn/Sdk0JKzT1j HQm10/TpviYol9knbZAQS1CsTltfTdqmDE5zEEgqDQIuOwCfRAMuu25amOXGKxEJETtWetfCoLs HIlzCaRKFRjk0dTzjjKo+lrhES7WkaYOZBLDDu3ux9O5HqEcoI17uXJNwnjdrDXsD6tWVIQZO4+ AnHMF8oX+ovIkczgF1nzQhnr6WOhfCQFL1cp1G/HtGEaW52kO3RXXVDN8PO6jis0x2MMLYL7ZFG yCWDM9vAm1Qx7Ao7z+X2U3cI1KbYt4lNdyW7X0TRezMxIGCkJBhw5U6iTBcY1vhyrMi6FA== X-Google-Smtp-Source: AGHT+IEMnExlFBvdPVupW4U192bMGJot5oRB8i5ec8KWtogtQ7yFXPGlhjc7ng4+XzJkoYHYmK5MnQ== X-Received: by 2002:a17:907:3d8e:b0:aa6:9574:1728 with SMTP id a640c23a62f3a-abb70acbb97mr912473166b.6.1740048162418; Thu, 20 Feb 2025 02:42:42 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:42 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 04/15] iio: accel: adxl345: use regmap cache for INT mapping Date: Thu, 20 Feb 2025 10:42:23 +0000 Message-Id: <20250220104234.40958-5-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use regmap cache to replace maintaining the member variable intio for the interrupt mapping state. The interrupt mapping is initialized when the driver is probed, and it is perfectly cacheable. The patch will still leave the function set_interrupts(). A follow up patch takes care of it, when cleaning up the INT enable register variable. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345.h | 4 ++ drivers/iio/accel/adxl345_core.c | 63 ++++++++++++++++++++------------ drivers/iio/accel/adxl345_i2c.c | 2 + drivers/iio/accel/adxl345_spi.c | 2 + 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h index bc6d634bd85c..a2a81caa292a 100644 --- a/drivers/iio/accel/adxl345.h +++ b/drivers/iio/accel/adxl345.h @@ -8,6 +8,8 @@ #ifndef _ADXL345_H_ #define _ADXL345_H_ +#include + #define ADXL345_REG_DEVID 0x00 #define ADXL345_REG_THRESH_TAP 0x1D #define ADXL345_REG_OFSX 0x1E @@ -111,6 +113,8 @@ */ #define ADXL375_USCALE 480000 +bool adxl345_is_volatile_reg(struct device *dev, unsigned int reg); + struct adxl345_chip_info { const char *name; int uscale; diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 22c5a9c08459..c4cff74a5d10 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,7 +36,6 @@ struct adxl345_state { struct regmap *regmap; bool fifo_delay; /* delay: delay is needed for SPI */ int irq; - u8 intio; u8 int_map; u8 watermark; u8 fifo_mode; @@ -76,6 +75,24 @@ static const unsigned long adxl345_scan_masks[] = { 0 }; +bool adxl345_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ADXL345_REG_DATA_AXIS(0): + case ADXL345_REG_DATA_AXIS(1): + case ADXL345_REG_DATA_AXIS(2): + case ADXL345_REG_DATA_AXIS(3): + case ADXL345_REG_DATA_AXIS(4): + case ADXL345_REG_DATA_AXIS(5): + case ADXL345_REG_FIFO_STATUS: + case ADXL345_REG_INT_SOURCE: + return true; + default: + return false; + } +} +EXPORT_SYMBOL_NS_GPL(adxl345_is_volatile_reg, IIO_ADXL345); + /** * adxl345_set_measure_en() - Enable and disable measuring. * @@ -98,22 +115,7 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) static int adxl345_set_interrupts(struct adxl345_state *st) { - int ret; - unsigned int int_enable = st->int_map; - unsigned int int_map; - - /* - * Any bits set to 0 in the INT map register send their respective - * interrupts to the INT1 pin, whereas bits set to 1 send their respective - * interrupts to the INT2 pin. The intio shall convert this accordingly. - */ - int_map = st->intio ? st->int_map : ~st->int_map; - - ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, int_map); - if (ret) - return ret; - - return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, int_enable); + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); } static int adxl345_read_raw(struct iio_dev *indio_dev, @@ -265,6 +267,7 @@ static const struct attribute_group adxl345_attrs_group = { static int adxl345_set_fifo(struct adxl345_state *st) { + unsigned int intio; int ret; /* FIFO should only be configured while in standby mode */ @@ -272,11 +275,14 @@ static int adxl345_set_fifo(struct adxl345_state *st) if (ret < 0) return ret; + ret = regmap_read(st->regmap, ADXL345_REG_INT_MAP, &intio); + if (ret) + return ret; + ret = regmap_write(st->regmap, ADXL345_REG_FIFO_CTL, FIELD_PREP(ADXL345_FIFO_CTL_SAMPLES_MSK, st->watermark) | - FIELD_PREP(ADXL345_FIFO_CTL_TRIGGER_MSK, - st->intio) | + FIELD_PREP(ADXL345_FIFO_CTL_TRIGGER_MSK, intio) | FIELD_PREP(ADXL345_FIFO_CTL_MODE_MSK, st->fifo_mode)); if (ret < 0) @@ -492,6 +498,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, struct adxl345_state *st; struct iio_dev *indio_dev; u32 regval; + u8 intio = ADXL345_INT1; unsigned int data_format_mask = (ADXL345_DATA_FORMAT_RANGE | ADXL345_DATA_FORMAT_JUSTIFY | ADXL345_DATA_FORMAT_FULL_RES | @@ -556,16 +563,26 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret < 0) return ret; - st->intio = ADXL345_INT1; st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1"); if (st->irq < 0) { - st->intio = ADXL345_INT2; + intio = ADXL345_INT2; st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2"); if (st->irq < 0) - st->intio = ADXL345_INT_NONE; + intio = ADXL345_INT_NONE; } - if (st->intio != ADXL345_INT_NONE) { + if (intio != ADXL345_INT_NONE) { + /* + * Any bits set to 0 in the INT map register send their respective + * interrupts to the INT1 pin, whereas bits set to 1 send their respective + * interrupts to the INT2 pin. The intio shall convert this accordingly. + */ + regval = intio ? 0xff : 0; + + ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, regval); + if (ret) + return ret; + /* FIFO_STREAM mode is going to be activated later */ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops); if (ret) diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c index eb3e0aadf51d..6ce567fd3ba6 100644 --- a/drivers/iio/accel/adxl345_i2c.c +++ b/drivers/iio/accel/adxl345_i2c.c @@ -17,6 +17,8 @@ static const struct regmap_config adxl345_i2c_regmap_config = { .reg_bits = 8, .val_bits = 8, + .volatile_reg = adxl345_is_volatile_reg, + .cache_type = REGCACHE_MAPLE, }; static int adxl345_i2c_probe(struct i2c_client *client) diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c index e03915ece8b6..200bdf975518 100644 --- a/drivers/iio/accel/adxl345_spi.c +++ b/drivers/iio/accel/adxl345_spi.c @@ -19,6 +19,8 @@ static const struct regmap_config adxl345_spi_regmap_config = { .val_bits = 8, /* Setting bits 7 and 6 enables multiple-byte read */ .read_flag_mask = BIT(7) | BIT(6), + .volatile_reg = adxl345_is_volatile_reg, + .cache_type = REGCACHE_MAPLE, }; static int adxl345_spi_setup(struct device *dev, struct regmap *regmap) From patchwork Thu Feb 20 10:42:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983695 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8C4F61F192E; Thu, 20 Feb 2025 10:42:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048167; cv=none; b=rOSlHG5JL9pPPpno2dzP/L4HetJq5BbCrvsZUIK3PU9YH+tBeMHO+JEcsLucvIOnElGmC1jzQsBB/T6U5i4VgPB+tjO5uRsewVjJyzS/MZVAuK4B68ce1Z9JgELjcM2v5QSCI5I+vG35X+BvDl+tqGkvvfJnn99D2tqAbaCaJlE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048167; c=relaxed/simple; bh=D3VACXGiA5izsC3aCkszrBj/SfbyrNkl6NaOpPR6//8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=k17TlzcFRPOc8IEDUm18TpA5zmfh1vx99FiCgYG3Pa8KW5ObIVMPipor0VWtt9mVxBr9TfozjNEm6FktYJNZ9SarIDt9dtIK9LKyW+THHIOlTqEUH0v8IUjSNlc8Wb9ZNtD3r2WxzuQQ12RRQvXzkquqJf/5gMv9ijCOXV5scSI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hjIyOIIh; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hjIyOIIh" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-abb4944fa73so11432666b.3; Thu, 20 Feb 2025 02:42:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048164; x=1740652964; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ofVa9GTeq7YIn1WTJeqPRtWjrDFNSHYQYgeM+emWUQ8=; b=hjIyOIIhLZf9C4YlO0y2X3raHVXuWO/TLBFZL9heH7bElYrFAXDFn9RI7x3lEjgkaj X+y5YDy11QSJH7h70xYgI2qX+H5gDU2Knw1rBUZLZjE0toGQkWzdtamIAWIIqOvdqKcs I50wR8mz0XwvLbDVliqVUW30p+/9HNIXL6eZ2iGZaOIs3uz5wjIf8HIjjt9Ocb+YSxFZ 77FAoIKKa8TbfVv6bm/2JopCX+SAh0IbsxO2IS1KUX7Lo3fV2dkSIIj3FcBdyMCaNBzQ tubOnujH0tc0QLVM3FqHEXC2Dq/i3oHMgvSTyuQXa0gsm9s5nphCTYP6E4ZvkXiX9JCt 4fwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048164; x=1740652964; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ofVa9GTeq7YIn1WTJeqPRtWjrDFNSHYQYgeM+emWUQ8=; b=E0WsMBCfhV3NEdpqGoCj9g1Swlcyqn4+N/3m6QKCoex/0oj1sTX7hJxDtw7109V+Bh YAASQEw3GwK8p/Wk6Hu/bBjKpfr7lstRGrspSis+Rxq3yy0ph2pLMCWgFiPUltpcCoqK enTgOe9+NxmsMpNIepvOvbFOY6MwTLYVdavBmb4BTITcJ/Uu0Q+k/o7DVd1Htp2VhOTa 7GVM/nBnlfSeV2RRH7CqQpHakPlwOAljqpDggfj3Rgf1cIZPKpNeB7imKD7q/JXQTPAD pWMlQSghMBARrndGw7+rTjybqTgq579Nb1y0gQA5WVoLxDftMMCOk2AmkxwXLjA2q/PF tIRA== X-Forwarded-Encrypted: i=1; AJvYcCXa7Vg//vUr+R+JOc84F/846sI8ZxqY5dHLU13YS2FhOPEH1YQM3bJijN9DhGoeyCjzwqCtuIZRce6zTMM=@vger.kernel.org X-Gm-Message-State: AOJu0YygvPPlFoJEQFj98LZqS9axqsikPBMsljRa5Opu/fQDNNmAW2hC TGeYQLGMulC3o1qUxVe6J0suFQkswhKACHKOftiu2wlLV2bQ1mxx X-Gm-Gg: ASbGncvQ+4SKr40JDRgSTnf3K6mGUw5mfOlr9LPay2w55j73nZRs7vN+8Y1yqrmVoeI EGMZ4yL1FVvdiNHLfLRsK0E0oXqwSjvIf2zUs8OVqrv9VXXFHrvHoGZ56GQrm0wjJtJobZxDrKr VQSy1uOm3ZSuweeWG0dUHw0DmwtO+6Hw4X3jpd511snZa4cjNJwdHzm8NhlnVUjbKE563IRy8s7 pWe9fxSGlsfcgWfs7FuB7zNC+oC65/gcB54FVP1MNRppW9RT1WwytLDvZ1C1o9gZqUXgo9dGXhj CgjXXcX9uab3XHG5pdcP9sCxfCGT14pWnw8y3iC3LDGe1h8qMVf1JRmKpXwGUz0Wv4sx4g== X-Google-Smtp-Source: AGHT+IHGRIiu0mrBHT7FfHi01HRyvN+SLp0Aefqt3iwlMU4ugkpcTAyz8Cl7hgoP1RuiE1BRliGzqA== X-Received: by 2002:a17:907:1c8b:b0:ab7:cb76:1ae3 with SMTP id a640c23a62f3a-abb70930221mr805324366b.2.1740048163426; Thu, 20 Feb 2025 02:42:43 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:43 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 05/15] iio: accel: adxl345: move INT enable to regmap cache Date: Thu, 20 Feb 2025 10:42:24 +0000 Message-Id: <20250220104234.40958-6-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Replace the interrupt enable member variable to the regmap cache. This makes the function set_interrupts() obsolete. The interrupt enable register is written when the driver is probed. Thus it is perfectly cacheable. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index c4cff74a5d10..0cee81bc1877 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,7 +36,6 @@ struct adxl345_state { struct regmap *regmap; bool fifo_delay; /* delay: delay is needed for SPI */ int irq; - u8 int_map; u8 watermark; u8 fifo_mode; __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); @@ -113,11 +112,6 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); } -static int adxl345_set_interrupts(struct adxl345_state *st) -{ - return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); -} - static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -216,7 +210,7 @@ static int adxl345_reg_access(struct iio_dev *indio_dev, unsigned int reg, static int adxl345_set_watermark(struct iio_dev *indio_dev, unsigned int value) { struct adxl345_state *st = iio_priv(indio_dev); - unsigned int fifo_mask = 0x1F; + const unsigned int fifo_mask = 0x1F, watermark_mask = 0x02; int ret; value = min(value, ADXL345_FIFO_SIZE - 1); @@ -226,7 +220,10 @@ static int adxl345_set_watermark(struct iio_dev *indio_dev, unsigned int value) return ret; st->watermark = value; - st->int_map |= ADXL345_INT_WATERMARK; + ret = regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, watermark_mask, + ADXL345_INT_WATERMARK); + if (ret) + return ret; return 0; } @@ -380,11 +377,6 @@ static void adxl345_fifo_reset(struct adxl345_state *st) static int adxl345_buffer_postenable(struct iio_dev *indio_dev) { struct adxl345_state *st = iio_priv(indio_dev); - int ret; - - ret = adxl345_set_interrupts(st); - if (ret < 0) - return ret; st->fifo_mode = ADXL345_FIFO_STREAM; return adxl345_set_fifo(st); @@ -400,8 +392,7 @@ static int adxl345_buffer_predisable(struct iio_dev *indio_dev) if (ret < 0) return ret; - st->int_map = 0x00; - return adxl345_set_interrupts(st); + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); } static const struct iio_buffer_setup_ops adxl345_buffer_ops = { @@ -523,6 +514,11 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, indio_dev->num_channels = ARRAY_SIZE(adxl345_channels); indio_dev->available_scan_masks = adxl345_scan_masks; + /* Reset interrupts at start up */ + ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); + if (ret) + return ret; + if (setup) { /* Perform optional initial bus specific configuration */ ret = setup(dev, st->regmap); From patchwork Thu Feb 20 10:42:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983696 Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0C6B1CAA9C; Thu, 20 Feb 2025 10:42:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048168; cv=none; b=IpsB/BHcjeTLOy4Bb2NyMtT4QAKMcfy6exTBAZarI7A53bv6vKF9QA3FrwAoQfBMpIrO5lel8aF6Z8fXyLt+FGG+fMdZTafNhAzBXJvznu6zv3bcsfHaAcEyzYSz2KMfrt+3OLYYABO981jM6ARbGIXlx8mYIwSwjvCA1FY3FIU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048168; c=relaxed/simple; bh=5jyI0GPJq4BjxA7uxkcbW2WX7rH37hTPuEJHW4cYwm0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dw37UqBbmZVt1By0xM3zrsG1rVi/C++XLK3+MvWGtvZO13eH1EElIgawLPR737cHWenyWwm2Q3freqef/YNykzHelNm4myC51pXa9lURSf56oGu/P0OPOIWQNvb4C5JDrAvfGaejOrBx2TIw9NYA/Orb89lCX8wrwvz7iHBmlAY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MhTA+j23; arc=none smtp.client-ip=209.85.218.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MhTA+j23" Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-abb76cc6108so11413066b.0; Thu, 20 Feb 2025 02:42:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048165; x=1740652965; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tbTRB3FoNxAsFddX7uPnXtU8eXUuScjraZJR3tByUSo=; b=MhTA+j23yVG2qZlB+hSRhtkh+A9gqilTjxaeKFQYWRWlhKxOYlGk4XmaOqBGrBso/f o1qRdoHwnwEZTQirloOTYPp6fVQFs9Rle8vdcJX+WiKa5muTmaqaUnH5Pl6k3+ygl4RL 43STSoEiaxV0sImRuDPDaAzX+K7fWHbpn52+AOaMQbVonML0Znp67/l6WiQypW9PSAfh 5AtFnDRB2z2x39Bw6+rb+xxriL4mp6hGKXNoI3d8lwzMwaLgHB88/91iBn52wo95ry56 lbC5RN6oxOecLcxe6Qjp0widsMifLFNZ/N2B92pvOAtK5H1oeo8FUU6EZM4+BL2MYs7Z AxZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048165; x=1740652965; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tbTRB3FoNxAsFddX7uPnXtU8eXUuScjraZJR3tByUSo=; b=n4i2VT4NlqYINi8HLPQFLyytWKoylNOZXccLWMP3ncEN4VvIlh2JiLilsZi8fqMLCs FmVNVMyqLawFxZprD9BMS1W0P/nEs+AL62R0nNZZxFOc6qND6AMIhJ5/xE7nLgh8aIen RVDGd2iB+22Afq1IT8BNQI/8+90e6HNjM2wBfHwpIUqKlfW2XTNEa6T1Pr7pGE5AlATZ bwpIUcnqGjfVOwQaQ02L/7Tg4TcGluGMuImboz/0ugkGfGMelPac6DFUtKVRpXgFGiGR dLKVCaIcnzglu3k1dP4p5G3Nqrp4xRwmf5PybWzUpc4Fe7fEeUTzAf4MDPK3woh9isLV 3/tw== X-Forwarded-Encrypted: i=1; AJvYcCUp6Rme9DLvygEZsV27y2ZcowiZx44/DaGTm64KiUXTvE1hjGztVCexNfPMApgXLna+zgFKaKSWIXEGzV4=@vger.kernel.org X-Gm-Message-State: AOJu0YxtabCBYEEq3syI95nrQfP1OkAZIgF8wf6+7byCVgJadMAObkRg toOfpoGsHhvzGvcneMg4JGeBEhZSGzt1LGalK1xZvMhK5DQKH/i7 X-Gm-Gg: ASbGncuMDNX7PCYDc2WYYv6JCef9ih4aZIEv4bKAmOhbXi7UV0V2pqWIczpoX8Gty4A q14uY8aJKaovBO6CEEp/1YuH0LIszB+l+DIfZwHLyx1Kpn3o1wmJaeGl2eUZOjh9MzqWy43Xg4h L87yUAOU3d15E7lgvWGPm5/O9J58RURo6EWvsrYFwSaxocw/nbQ00e+T5hr4+44AFXX65U9AGUy DBS/yHo/Y6W6P4cUPym3Cq1ifUiG8aGm8wh6T56d/WgOgyoEYRTXuxqtlDhJ6gB3poj2MSuMEBA w+XMZ3vEDYQNgCbeYx6ISpHITHQYgNKCS+L/TLx9bjgGG5crSqMjxtPpmzX7jvYRo3/c+Q== X-Google-Smtp-Source: AGHT+IE2yZjfHtbINlhq1SPgXqpxMlXv73y6RIZijnkxdLfgh0CtCRiSq2SyDKOgOlg5ERfU2+wkXQ== X-Received: by 2002:a17:907:7248:b0:ab7:82a7:bb1f with SMTP id a640c23a62f3a-abb70d96de8mr824232666b.10.1740048164434; Thu, 20 Feb 2025 02:42:44 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:44 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 06/15] iio: accel: adxl345: add single tap feature Date: Thu, 20 Feb 2025 10:42:25 +0000 Message-Id: <20250220104234.40958-7-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the single tap feature with a threshold in 62.5mg/LSB points and a scaled duration in us. Keep singletap threshold in regmap cache but the scaled value of duration in us as member variable. Both use IIO channels for individual enable of the x/y/z axis. Initializes threshold and duration with reasonable content. When an interrupt is caught it will be pushed to the according IIO channel. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 364 ++++++++++++++++++++++++++++++- 1 file changed, 362 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 0cee81bc1877..d05593c0d513 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include "adxl345.h" @@ -31,6 +33,33 @@ #define ADXL345_INT1 0 #define ADXL345_INT2 1 +#define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) + +enum adxl345_axis { + ADXL345_Z_EN = BIT(0), + ADXL345_Y_EN = BIT(1), + ADXL345_X_EN = BIT(2), + /* Suppress double tap detection if value > tap threshold */ + ADXL345_TAP_SUPPRESS = BIT(3), +}; + +/* single/double tap */ +enum adxl345_tap_type { + ADXL345_SINGLE_TAP, +}; + +static const unsigned int adxl345_tap_int_reg[] = { + [ADXL345_SINGLE_TAP] = ADXL345_INT_SINGLE_TAP, +}; + +enum adxl345_tap_time_type { + ADXL345_TAP_TIME_DUR, +}; + +static const unsigned int adxl345_tap_time_reg[] = { + [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, +}; + struct adxl345_state { const struct adxl345_chip_info *info; struct regmap *regmap; @@ -38,9 +67,23 @@ struct adxl345_state { int irq; u8 watermark; u8 fifo_mode; + + u32 tap_axis_ctrl; + u32 tap_duration_us; + __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; +static struct iio_event_spec adxl345_events[] = { + { + .type = IIO_EV_TYPE_GESTURE, + .dir = IIO_EV_DIR_SINGLETAP, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_TIMEOUT), + }, +}; + #define ADXL345_CHANNEL(index, reg, axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ @@ -57,6 +100,8 @@ struct adxl345_state { .storagebits = 16, \ .endianness = IIO_LE, \ }, \ + .event_spec = adxl345_events, \ + .num_event_specs = ARRAY_SIZE(adxl345_events), \ } enum adxl345_chans { @@ -83,6 +128,7 @@ bool adxl345_is_volatile_reg(struct device *dev, unsigned int reg) case ADXL345_REG_DATA_AXIS(3): case ADXL345_REG_DATA_AXIS(4): case ADXL345_REG_DATA_AXIS(5): + case ADXL345_REG_ACT_TAP_STATUS: case ADXL345_REG_FIFO_STATUS: case ADXL345_REG_INT_SOURCE: return true; @@ -112,6 +158,117 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); } +/* tap */ + +static int adxl345_write_tap_axis(struct adxl345_state *st, + enum adxl345_axis axis, bool en) +{ + st->tap_axis_ctrl = FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, + en ? st->tap_axis_ctrl | axis + : st->tap_axis_ctrl & ~axis); + + return regmap_update_bits(st->regmap, ADXL345_REG_TAP_AXIS, + ADXL345_REG_TAP_AXIS_MSK, + FIELD_PREP(ADXL345_REG_TAP_AXIS_MSK, + st->tap_axis_ctrl)); +} + +static int _adxl345_set_tap_int(struct adxl345_state *st, + enum adxl345_tap_type type, bool state) +{ + unsigned int int_map = 0x00; + unsigned int tap_threshold; + bool axis_valid; + bool singletap_args_valid = false; + bool en = false; + int ret; + + axis_valid = FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, st->tap_axis_ctrl) > 0; + + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_TAP, &tap_threshold); + if (ret) + return ret; + + /* + * Note: A value of 0 for threshold and/or dur may result in undesirable + * behavior if single tap/double tap interrupts are enabled. + */ + singletap_args_valid = tap_threshold > 0 && st->tap_duration_us > 0; + + if (type == ADXL345_SINGLE_TAP) + en = axis_valid && singletap_args_valid; + + if (state && en) + int_map |= adxl345_tap_int_reg[type]; + + return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + adxl345_tap_int_reg[type], int_map); +} + +static int adxl345_is_tap_en(struct adxl345_state *st, + enum adxl345_tap_type type, bool *en) +{ + int ret; + unsigned int regval; + + ret = regmap_read(st->regmap, ADXL345_REG_INT_ENABLE, ®val); + if (ret) + return ret; + + *en = (adxl345_tap_int_reg[type] & regval) > 0; + + return 0; +} + +static int adxl345_set_singletap_en(struct adxl345_state *st, + enum adxl345_axis axis, bool en) +{ + int ret; + + ret = adxl345_write_tap_axis(st, axis, en); + if (ret) + return ret; + + return _adxl345_set_tap_int(st, ADXL345_SINGLE_TAP, en); +} + +static int _adxl345_set_tap_time(struct adxl345_state *st, + enum adxl345_tap_time_type type, u32 val_us) +{ + unsigned int regval; + + switch (type) { + case ADXL345_TAP_TIME_DUR: + st->tap_duration_us = val_us; + break; + } + + /* + * The scale factor is 1250us / LSB for tap_window_us and tap_latent_us. + * For tap_duration_us the scale factor is 625us / LSB. + */ + if (type == ADXL345_TAP_TIME_DUR) + regval = DIV_ROUND_CLOSEST(val_us, 625); + else + regval = DIV_ROUND_CLOSEST(val_us, 1250); + + return regmap_write(st->regmap, adxl345_tap_time_reg[type], regval); +} + +static int adxl345_set_tap_duration(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + /* + * Max value is 255 * 625 us = 0.159375 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (val_int || val_fract_us > 159375) + return -EINVAL; + + return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_DUR, val_fract_us); +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -197,6 +354,160 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, return -EINVAL; } +static int adxl345_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 adxl345_state *st = iio_priv(indio_dev); + bool int_en; + bool axis_en; + int ret = -EFAULT; + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (chan->channel2) { + case IIO_MOD_X: + axis_en = FIELD_GET(ADXL345_X_EN, st->tap_axis_ctrl); + break; + case IIO_MOD_Y: + axis_en = FIELD_GET(ADXL345_Y_EN, st->tap_axis_ctrl); + break; + case IIO_MOD_Z: + axis_en = FIELD_GET(ADXL345_Z_EN, st->tap_axis_ctrl); + break; + default: + axis_en = ADXL345_TAP_SUPPRESS; + break; + } + + switch (dir) { + case IIO_EV_DIR_SINGLETAP: + ret = adxl345_is_tap_en(st, ADXL345_SINGLE_TAP, &int_en); + if (ret) + return ret; + return int_en && axis_en; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl345_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 adxl345_state *st = iio_priv(indio_dev); + enum adxl345_axis axis; + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (chan->channel2) { + case IIO_MOD_X: + axis = ADXL345_X_EN; + break; + case IIO_MOD_Y: + axis = ADXL345_Y_EN; + break; + case IIO_MOD_Z: + axis = ADXL345_Z_EN; + break; + default: + axis = ADXL345_TAP_SUPPRESS; + break; + } + + switch (dir) { + case IIO_EV_DIR_SINGLETAP: + return adxl345_set_singletap_en(st, axis, state); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl345_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 adxl345_state *st = iio_priv(indio_dev); + unsigned int tap_threshold; + int ret; + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (info) { + case IIO_EV_INFO_VALUE: + /* + * The scale factor is 62.5mg/LSB (i.e. 0xFF = 16g) but + * not applied here. + */ + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_TAP, &tap_threshold); + if (ret) + return ret; + *val = sign_extend32(tap_threshold, 7); + return IIO_VAL_INT; + case IIO_EV_INFO_TIMEOUT: + *val = st->tap_duration_us; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl345_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 adxl345_state *st = iio_priv(indio_dev); + int ret; + + ret = adxl345_set_measure_en(st, false); + if (ret) + return ret; + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_TAP, + min(val, 0xFF)); + break; + case IIO_EV_INFO_TIMEOUT: + ret = adxl345_set_tap_duration(st, val, val2); + break; + default: + ret = -EINVAL; + break; + } + break; + default: + ret = -EINVAL; + break; + } + + if (ret) + return ret; /* measurement stays off */ + + return adxl345_set_measure_en(st, true); +} + static int adxl345_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, unsigned int *readval) { @@ -419,6 +730,26 @@ static int adxl345_fifo_push(struct iio_dev *indio_dev, return 0; } +static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, + enum iio_modifier act_tap_dir) +{ + s64 ts = iio_get_time_ns(indio_dev); + int ret; + + if (FIELD_GET(ADXL345_INT_SINGLE_TAP, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + act_tap_dir, + IIO_EV_TYPE_GESTURE, + IIO_EV_DIR_SINGLETAP), + ts); + if (ret) + return ret; + } + + return -ENOENT; +} + /** * adxl345_irq_handler() - Handle irqs of the ADXL345. * @irq: The irq being handled. @@ -430,12 +761,28 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) { struct iio_dev *indio_dev = p; struct adxl345_state *st = iio_priv(indio_dev); - int int_stat; - int samples; + unsigned int regval; + enum iio_modifier act_tap_dir = IIO_NO_MOD; + int int_stat, samples, ret; + + if (FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, st->tap_axis_ctrl) > 0) { + ret = regmap_read(st->regmap, ADXL345_REG_ACT_TAP_STATUS, ®val); + if (ret) + return ret; + if (FIELD_GET(ADXL345_Z_EN, regval) > 0) + act_tap_dir = IIO_MOD_Z; + else if (FIELD_GET(ADXL345_Y_EN, regval) > 0) + act_tap_dir = IIO_MOD_Y; + else if (FIELD_GET(ADXL345_X_EN, regval) > 0) + act_tap_dir = IIO_MOD_X; + } if (regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &int_stat)) return IRQ_NONE; + if (adxl345_push_event(indio_dev, int_stat, act_tap_dir) == 0) + return IRQ_HANDLED; + if (FIELD_GET(ADXL345_INT_WATERMARK, int_stat)) { samples = adxl345_get_samples(st); if (samples < 0) @@ -461,6 +808,10 @@ static const struct iio_info adxl345_info = { .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, .write_raw_get_fmt = adxl345_write_raw_get_fmt, + .read_event_config = adxl345_read_event_config, + .write_event_config = adxl345_write_event_config, + .read_event_value = adxl345_read_event_value, + .write_event_value = adxl345_write_event_value, .debugfs_reg_access = &adxl345_reg_access, .hwfifo_set_watermark = adxl345_set_watermark, }; @@ -494,6 +845,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, ADXL345_DATA_FORMAT_JUSTIFY | ADXL345_DATA_FORMAT_FULL_RES | ADXL345_DATA_FORMAT_SELF_TEST); + unsigned int tap_threshold; int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); @@ -507,6 +859,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, return -ENODEV; st->fifo_delay = fifo_delay_default; + /* Init with reasonable values */ + tap_threshold = 48; /* 48 [0x30] -> ~3g */ + st->tap_duration_us = 16; /* 16 [0x10] -> .010 */ + indio_dev->name = st->info->name; indio_dev->info = &adxl345_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -579,6 +935,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_TAP, tap_threshold); + if (ret) + return ret; + /* FIFO_STREAM mode is going to be activated later */ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops); if (ret) From patchwork Thu Feb 20 10:42:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983697 Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 746781F3B9E; Thu, 20 Feb 2025 10:42:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048169; cv=none; b=rMaSpoPQlgkfHvTr3KWQMh4yt4mXkvmO4quSxEoewUPagNqzHHOJKiMl9GZ198VgniQ5dvbPDVyawq+Lf/X/NfnRpf0DfzUBY0AIGyxkb1W3pyGO0gVFuTbto4WeRHQjblOVQ3yqnCCTiIhN2JjEGoMBrqs9T2WFlL9PIX8dEIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048169; c=relaxed/simple; bh=L39niv7e4NppXWE6tN4Vx0S2ojeN4AEe+yM+KuPTEkw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PnjsvkGI+4a6LuAHBd1gyf6pxQJe48XpwEOMGoH/EEnOgWEBONx4POaG+/PWu4XqUorTyMIOuk5ukY/OduqIdtQv0sG5Vi3X/++SwPN/RmWdWvpcndyDdxj2XApDHkI5LVTKrsxnyzEY6SruAD7yMKfcAy8+SVnyDD8lOYwDVGc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lsZwSzjh; arc=none smtp.client-ip=209.85.218.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lsZwSzjh" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-ab7dd005cb0so10750466b.3; Thu, 20 Feb 2025 02:42:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048166; x=1740652966; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ta+2FU81zc6EZR7Nqtyxx9EdNRilRxxat+p3vt2mhcA=; b=lsZwSzjhD5khyCmZpAUkoEpnKj7SRM2IMVeKR24nySOSYyP+4vyHWkd2yGs/gLPrOU BCfMGrotmQAr3L5IJdjU/RFNDBeXucTVMODhQFh3cM0t9qCZ/RCXTGofaIoHuqs16mnC Bv1I5wtxzy1cOKFCt10HiWU9MOqDJjkf+r/LMTAhjAa/51k1QWBpwP1nvyG7gw3I8TAS jcEy/L8HT82pryDE0jKfaxezU1Twe5pOwaQEKL14/G0orqk/k7qRPYoUfEic0LBYNXoN 5hOVnnds8mK8OIhzFxun7j67ts8VF19GcXyFKV2jCm9Lil4/XmEq/RTewD5fBK4WL8/B YZIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048166; x=1740652966; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ta+2FU81zc6EZR7Nqtyxx9EdNRilRxxat+p3vt2mhcA=; b=NUU/Pk4G5vKS+lenjhAeK6xK7FIjsc1ipNyyrN+Y+EqapAxnRGOaCqu4PC+8ckbtVO OAMmkG68NMeXTLR0MQFWCNNr61Eb/3hIIjMwZH1Y3NmDaMo3EAMw3YZSxsuXjauHwAwc JShs8KLn9+G2lZALVu0YiXf42I3sO1OLco330txYUzmcEeC1a2lbXVynlX5rjIuasXzN Vudsb9UNacfcYWz8qTmA7p24q5/1DerSnWOxrONe3I36te9A0VDY9vVvnWeGMbUcAUVk FU+IxULkAeEVCdwuoNvzndsqoX84WgfDPvs+xulLbG83WmIJWOgg5UJRUShSEoZZW24a WqlQ== X-Forwarded-Encrypted: i=1; AJvYcCVPYn+7sBA8cQQuGj94dmg4mGzru3ZUtY2X9ci6k9DwQv2SDDE66vMcTKWRf3H5wqWrUUJ8HvN66oPqhmM=@vger.kernel.org X-Gm-Message-State: AOJu0YwQeNoVbpy+Y+Wk3ebXqFtVO+7jpAI7zvuht4HqxARc6FeEl5hA Ocaq9LjebRlUkRTKOiUd8g1FuOixwyx+3XSArPLmRVxyLlgz4zuTMIYBTJgG X-Gm-Gg: ASbGncu0qO13r12YncOgsQ48HfJ6Bza1UkD03s9+VLCcktZEEPy+wRov9QaDMXwRyA3 NAQoyE12OWUdStLjhhHtS/mAuDtC0iE17znOM4BK+LpCBHs9VLwJMN95cLN0gLDyEQxrTRjbIv6 WG4wyvQthEC/Fv4avHkunziPJxz5czO3Do2+0xnfaJMldj8m/LrQN3hLEgQE1DdQVhWKTxnYkY5 58miiYt2Wbu5FUGf9NZnjIUGh1s4zahelJhHt22WAbbTR7allbkUkMsMCEIS1pfAUaCSEVeF4kb 3Rau+C5MjTVtS1imGDa48+mGjVvnTPYFiKXBHi/cxXajf2b3+ijAcL2Jl1a+KTHdpASpVw== X-Google-Smtp-Source: AGHT+IEfYnwAWlvQ6iXKy35YFsF9pSZriJsMvYRoYjH6QF5UZTSZ0qCwUEZ0SX2Vd8QxG03ChK4FsQ== X-Received: by 2002:a17:907:9494:b0:ab3:2719:ca30 with SMTP id a640c23a62f3a-abb70dc5ca3mr812164766b.10.1740048165367; Thu, 20 Feb 2025 02:42:45 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:45 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 07/15] iio: accel: adxl345: add double tap feature Date: Thu, 20 Feb 2025 10:42:26 +0000 Message-Id: <20250220104234.40958-8-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the double tap feature of the sensor. The interrupt handler needs to catch and forward the event to the IIO channel. The single tap implementation now is extended to deal with double tap as well. Doubletap introduces window and latency times, both in us. Since both times are scaled, the 8-bit register value is stored in hardware, where the scaled value in [us] is stored as member variable. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 99 +++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index d05593c0d513..c014bdf84e66 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -46,17 +46,23 @@ enum adxl345_axis { /* single/double tap */ enum adxl345_tap_type { ADXL345_SINGLE_TAP, + ADXL345_DOUBLE_TAP, }; static const unsigned int adxl345_tap_int_reg[] = { [ADXL345_SINGLE_TAP] = ADXL345_INT_SINGLE_TAP, + [ADXL345_DOUBLE_TAP] = ADXL345_INT_DOUBLE_TAP, }; enum adxl345_tap_time_type { + ADXL345_TAP_TIME_LATENT, + ADXL345_TAP_TIME_WINDOW, ADXL345_TAP_TIME_DUR, }; static const unsigned int adxl345_tap_time_reg[] = { + [ADXL345_TAP_TIME_LATENT] = ADXL345_REG_LATENT, + [ADXL345_TAP_TIME_WINDOW] = ADXL345_REG_WINDOW, [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; @@ -70,6 +76,8 @@ struct adxl345_state { u32 tap_axis_ctrl; u32 tap_duration_us; + u32 tap_latent_us; + u32 tap_window_us; __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; @@ -82,6 +90,13 @@ static struct iio_event_spec adxl345_events[] = { .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_TIMEOUT), }, + { + .type = IIO_EV_TYPE_GESTURE, + .dir = IIO_EV_DIR_DOUBLETAP, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_RESET_TIMEOUT) | + BIT(IIO_EV_INFO_TAP2_MIN_DELAY), + }, }; #define ADXL345_CHANNEL(index, reg, axis) { \ @@ -180,6 +195,7 @@ static int _adxl345_set_tap_int(struct adxl345_state *st, unsigned int tap_threshold; bool axis_valid; bool singletap_args_valid = false; + bool doubletap_args_valid = false; bool en = false; int ret; @@ -195,8 +211,16 @@ static int _adxl345_set_tap_int(struct adxl345_state *st, */ singletap_args_valid = tap_threshold > 0 && st->tap_duration_us > 0; - if (type == ADXL345_SINGLE_TAP) + if (type == ADXL345_SINGLE_TAP) { en = axis_valid && singletap_args_valid; + } else { + /* doubletap: Window must be equal or greater than latent! */ + doubletap_args_valid = st->tap_latent_us > 0 && + st->tap_window_us > 0 && + st->tap_window_us >= st->tap_latent_us; + + en = axis_valid && singletap_args_valid && doubletap_args_valid; + } if (state && en) int_map |= adxl345_tap_int_reg[type]; @@ -232,12 +256,23 @@ static int adxl345_set_singletap_en(struct adxl345_state *st, return _adxl345_set_tap_int(st, ADXL345_SINGLE_TAP, en); } +static int adxl345_set_doubletap_en(struct adxl345_state *st, bool en) +{ + return _adxl345_set_tap_int(st, ADXL345_DOUBLE_TAP, en); +} + static int _adxl345_set_tap_time(struct adxl345_state *st, enum adxl345_tap_time_type type, u32 val_us) { unsigned int regval; switch (type) { + case ADXL345_TAP_TIME_WINDOW: + st->tap_window_us = val_us; + break; + case ADXL345_TAP_TIME_LATENT: + st->tap_latent_us = val_us; + break; case ADXL345_TAP_TIME_DUR: st->tap_duration_us = val_us; break; @@ -269,6 +304,34 @@ static int adxl345_set_tap_duration(struct adxl345_state *st, u32 val_int, return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_DUR, val_fract_us); } +static int adxl345_set_tap_window(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + /* + * Max value is 255 * 1250 us = 0.318750 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (val_int || val_fract_us > 318750) + return -EINVAL; + + return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_WINDOW, val_fract_us); +} + +static int adxl345_set_tap_latent(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + /* + * Max value is 255 * 1250 us = 0.318750 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (val_int || val_fract_us > 318750) + return -EINVAL; + + return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_LATENT, val_fract_us); +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -387,6 +450,11 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, if (ret) return ret; return int_en && axis_en; + case IIO_EV_DIR_DOUBLETAP: + ret = adxl345_is_tap_en(st, ADXL345_DOUBLE_TAP, &int_en); + if (ret) + return ret; + return int_en; default: return -EINVAL; } @@ -424,6 +492,8 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, switch (dir) { case IIO_EV_DIR_SINGLETAP: return adxl345_set_singletap_en(st, axis, state); + case IIO_EV_DIR_DOUBLETAP: + return adxl345_set_doubletap_en(st, state); default: return -EINVAL; } @@ -460,6 +530,14 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, *val = st->tap_duration_us; *val2 = 1000000; return IIO_VAL_FRACTIONAL; + case IIO_EV_INFO_RESET_TIMEOUT: + *val = st->tap_window_us; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + case IIO_EV_INFO_TAP2_MIN_DELAY: + *val = st->tap_latent_us; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; default: return -EINVAL; } @@ -492,6 +570,12 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, case IIO_EV_INFO_TIMEOUT: ret = adxl345_set_tap_duration(st, val, val2); break; + case IIO_EV_INFO_RESET_TIMEOUT: + ret = adxl345_set_tap_window(st, val, val2); + break; + case IIO_EV_INFO_TAP2_MIN_DELAY: + ret = adxl345_set_tap_latent(st, val, val2); + break; default: ret = -EINVAL; break; @@ -747,6 +831,17 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_DOUBLE_TAP, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + act_tap_dir, + IIO_EV_TYPE_GESTURE, + IIO_EV_DIR_DOUBLETAP), + ts); + if (ret) + return ret; + } + return -ENOENT; } @@ -862,6 +957,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, /* Init with reasonable values */ tap_threshold = 48; /* 48 [0x30] -> ~3g */ st->tap_duration_us = 16; /* 16 [0x10] -> .010 */ + st->tap_window_us = 64; /* 64 [0x40] -> .080 */ + st->tap_latent_us = 16; /* 16 [0x10] -> .020 */ indio_dev->name = st->info->name; indio_dev->info = &adxl345_info; From patchwork Thu Feb 20 10:42:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983698 Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 848E51F3D58; Thu, 20 Feb 2025 10:42:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048170; cv=none; b=pFvtneYi/poCAiL51TR3KmsCMRijfv16BId68F06KHHoJDiBKQvicBYt1sgoEGF9FX89nHlsi5N40Lvn7GfSKtPgv93Wivz7gw74JfGudMhFH5f2H9aSIS+Z4zqLtLrIwtPSi0Koi0URE+Fpjfdcy+gCCmI+0NJMid2bHdpVo3k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048170; c=relaxed/simple; bh=hF6T63bWml3OU/pCUTMJjxtyItj0/Ir7pAOwr1SZ1Ww=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RCtHHY6NJYq4x8BgTqDHSCV1mtLmBAh/pPQFa/D/dqsKktND+rqfTqmQoOjE1gBnFqsPfzlVcq91P4hSe9Ki8Eo8ErxUJJ1TWkz6LBld4Ih89kfRkaHOTXvQCR9/S3h2oPeOLLqXKDx+SwZoObnT3sSBzxUwC0i1ufjvxYpcia4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=YuskHnj5; arc=none smtp.client-ip=209.85.218.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YuskHnj5" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-abb76cc6108so11413666b.0; Thu, 20 Feb 2025 02:42:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048167; x=1740652967; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zQU4UsTNREqUeJJB9UI8mNNLlTTknhjQi/yKMyyZlMg=; b=YuskHnj5Fi6Z4rAdbzKj6a4/n3NoqOunEacBrY2jBA5gLNLYL4CdBcoIGjVwtg3Mee UKzqfbLHOiUq3HAzoZ9GOPZeWz+UeNURLC/ibIDP1pzlYktgUfu8gS3qxZqNqqpeBoEM taYdNbPVUdx3u878vsf3bJnlb7gUaVaGMIACzbH2EBMmwgbdiHvGiYTSy5jCQzeHxbu9 //cKk0st8JBVuCWJbzhETF84jM0+YTv7WdHi12TxpUNeqN4Fbx2iUHrC2e4NCeR23R9+ Ws5DB1ktiqdvdXnWM+3CyIHn8zkeuFWX4Fbemj+AsZH0C9hbdtO3uuixT3G8gDK+fTgW ik1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048167; x=1740652967; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zQU4UsTNREqUeJJB9UI8mNNLlTTknhjQi/yKMyyZlMg=; b=VyTOmjam5QzEbNBs/o8w5r0hoz3GO0H853GhdBpcqd7I0avZnI5n/SLBYHjQJGqcfQ 50kKuzjkd26ph2MNU0LEoMix1BCa4Gttpg7hr7fznEfq5xEaxs8EPc+5zc0U5SAok9sw LEXqJfC5JLm/6o+vjx9qZuf4bboQgJU6ApbNokjnLnf2E9AgkNeiwZ0Qpwou4KwnH2wt IYRq0o9a30+Gt2Uv+F+V/KQE1UZEu3frE1BknONQ/Uq5wFkttl9whAK5emLFJLAnqmqn O+7PYJWch9APDkyUzwM4t1HbLilbvqSNYdJjCuq6VguGaSHRz4dzMkAPy9MWtueRcbeW 9o8Q== X-Forwarded-Encrypted: i=1; AJvYcCXZwuIERiGWEQOaOhZcTgIxxFfo0g8QowYLr+A2FBcuuWiEeljeab5WcqBSNn6HsWOwxsvpM8Ix8xJEu64=@vger.kernel.org X-Gm-Message-State: AOJu0Yw8EYqVtrAWzHUSfkmgNT0bgDGSBosZQvHpiEcKy1V49V1nZxbA Pgf4CtpnLI3heeoyRejWNkqpdK+NBrN3mfem1E97+xT/dkMU379d X-Gm-Gg: ASbGncujeToB5wbqiZc2Vybi6epE7OJVNc7nuLLkyq1q9HoRLBfJWDSZSLiXVBC7NDP uR2zbcvTdOFGCQUgOuL6AR1hU5PhmjFHUYedm18+dYPhBeXOfMBwlp3hdvLrslo+aWFmb6UQkRt fkpKQnxxxHKX3pWDZLvEcumkX/tKNP/oIQxuZy2VCsX0MrQhjSHBKIk1kq4RADt3Opdxklb83Ip 7bGrD2M7iK6aLnxi+woo6P/GDkamQkUk4p3S7lgutWtuFL6dvl+r0UzjXrpg/tU8TzYtURzN1eQ DKVMUjpxRMtYuOKcrChDzkPJPTik4Jx3WLwJT0F593vv/S6wGV9/rfMXePe/gpuy1o7JEw== X-Google-Smtp-Source: AGHT+IG4JNx6qXLn8tEdSEb8E1OzlShIKJFW5XGwopzCf1DXZqg1UFtEzp4ih0wCaq0jiXQCMI/NiQ== X-Received: by 2002:a17:906:af09:b0:abb:e5ac:28b2 with SMTP id a640c23a62f3a-abbe5ac2dddmr119606766b.13.1740048166487; Thu, 20 Feb 2025 02:42:46 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:46 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 08/15] iio: accel: adxl345: add double tap suppress bit Date: Thu, 20 Feb 2025 10:42:27 +0000 Message-Id: <20250220104234.40958-9-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Set the suppress bit feature to the double tap detection, whenever double tap is enabled. Any tap event is defined by a rising signal edge above threshold, i.e. duration time starts counting; and the falling edge under threshold within duration time, i.e. then the tap event is issued. This means duration is used individually for each tap event. For double tap detection after a single tap, a latency time needs to be specified. Usually tap events, i.e. spikes above and returning below threshold will be ignored within latency. After latency, the window time starts counting for a second tap detection which has to happen within a duration time. If the suppress bit is not set, spikes within latency time are ignored. Setting the suppress bit will invalidate the double tap function. The sensor will thus be able to save the window time for double tap detection, and follow a more strict definition of what signal qualifies for a double tap. In a summary having the suppress bit set, fewer signal spikes will be considered as double taps. This is an optional add on to double tap, thus a separate patch. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index c014bdf84e66..10cd81dd08bb 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -34,6 +34,7 @@ #define ADXL345_INT2 1 #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) +#define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) enum adxl345_axis { ADXL345_Z_EN = BIT(0), @@ -258,6 +259,18 @@ static int adxl345_set_singletap_en(struct adxl345_state *st, static int adxl345_set_doubletap_en(struct adxl345_state *st, bool en) { + int ret; + + /* + * generally suppress detection of spikes during the latency period as + * double taps here, this is fully optional for double tap detection + */ + ret = regmap_update_bits(st->regmap, ADXL345_REG_TAP_AXIS, + ADXL345_REG_TAP_SUPPRESS_MSK, + en ? ADXL345_TAP_SUPPRESS : 0x00); + if (ret) + return ret; + return _adxl345_set_tap_int(st, ADXL345_DOUBLE_TAP, en); } From patchwork Thu Feb 20 10:42:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983699 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92C7C1F4167; Thu, 20 Feb 2025 10:42:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048171; cv=none; b=VaL+dEXcC9jhqTveDtY6vVkO7AOFEQF2aP0HL3N1xpdwmxVqoyrE5atCNa7IczXeYq6WLfT9anaEf60SEsHgNdpXVlIGAQacG518NzHaAuLx9cCNAl3liSycJ0XkBpCmljWPnK6N1/ujqKYV7D21sVUEKuS23DOP4LisKCGMl5k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048171; c=relaxed/simple; bh=/c13zuYptb0ZWGvmPSo0Ms0ITzJfpzc8HWI5U+Afwok=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HOth7+T1CyROY7qXpfvtNxi8dytf38swQzWnwRCtqs3mTuTTulirYp2nGZI7nt+hLo/UWGsnqGbRLWjGLg6v8qwkSg2ZKnDPNnQYTxdO+TACHqL7z9FKN+pXj7FuywaBA+S3J/jiNn91ukSi9by9iTknv5ve1MKLeQ7V7Gbf/4Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KKvhOZsI; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KKvhOZsI" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-abb7d5a6577so8422166b.2; Thu, 20 Feb 2025 02:42:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048168; x=1740652968; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7tPPQP8puSdAdZPHNmR3ieICP+QZSlGfGIEXG2SGjIY=; b=KKvhOZsItCUoqV26aQ3h65QRmhOpnSHPeE5BaFR5YSvYBUBGK21eXnYJqk23LzJk8t ypeZqHRlpweYg4KXHxQDShWN7CVNyqlM3SW5SLQ4IdHKMs5QsVUDBpQqvCHBrIw8GntZ FSMPdfQTIgIwF49G2duHjViwmDW8qrqc6jXP61e/ZiNVk6FanOyu8+xF3sQqsIufGeTI 8j3Z49a4eWEi9T5SJYEd0riKfLSQVm1OCtZL6X8bq9U0+UE14Qki36wNZhjgge84c5v+ Z36jz66p+xUqdrf7njwhoa8vl/eVD+tdNeYF8vCo812000DKkgAtgHBncQgWkg9ZIqXi v3mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048168; x=1740652968; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7tPPQP8puSdAdZPHNmR3ieICP+QZSlGfGIEXG2SGjIY=; b=ergCIdoqkxQzjFk3AJAKrU54KZWcmvp0ZKwH8ETr+q9/eMbAZFaGj3u82AGGUfLEez QTgiCw+YCkX0HWKTTHKexIhQBtjfmJWq7IKbc3/z7GdVqzzf+5ZZHcPFubk3HFiTWocK e6wg2INRYRKisKkmjP+X3JVkTZrk1HzZB+z95DmYyRFwQdE5HCR24hiFs5OTYVWDU4uO 0tDcPnQAqyviQrt+BI5Fpfa6bHBGB197iSjJh2DcB6aqVdn9urKjDPuJXg1PyflscyP7 TwjTzrMfio4HnnjUDgNN51ID9bYCAKYBkQK2V1VYE8ppRH0VPQ8GNCllZTIr74QOiFh4 XnUQ== X-Forwarded-Encrypted: i=1; AJvYcCVVgRaY2jkLMFEXLa3B2okpsX63TMmo4EWL3KU5xFAQx7jlI0DVOzaqfN1Zpwp1cAbt9pYGdZPoqN8JZ+g=@vger.kernel.org X-Gm-Message-State: AOJu0YwAErdA3esTZOnDFWd2nNykevIA7DFAuofZNyo6+NGHSXHKAKxA A29XibdOAS/yzpdwa5st02wdJenR9g+Kd5VKNpneYlVXtX0qTNTM X-Gm-Gg: ASbGncsATcKxmSy1trJfkKwkb817nHQCIO4DqnGYMIJ4PnQNkLUJvO7Ws1nTv3NFGpM Reh9X3Berwdufw8/wwy7M1am6GyuXFAlTG5VzBlIYhoK2aUgyQQ/XziTmLnR/z6Pigl1jNjmBgj J9orgLzqMunZNqilaJdqtPauI4b37L7Avhsq9KcP4HmqF5mC4fO5s4pmCUB4zh9zG3GugUv2Eo1 myOczX3BvRTq9qlC0yG84u9iHSMec1fpRSkbyOxxaygT8LT+uU62jYu8G8BEpOgBzZ/ERPSd5+/ SPLdXqZYbaA5UplpE98K7H5/hFUIN6vktNmmKUoflMIYqp2Ta31zi0DDNa8Vgh7Aq9MkLg== X-Google-Smtp-Source: AGHT+IG+DEFamWgcrhRCN4CxkKQ+4rgCOVBCw3nbAc01Y7LUIhWNwYpwU4HClBnj2eBqEkVcd0ktAQ== X-Received: by 2002:a17:906:37db:b0:abb:da39:2447 with SMTP id a640c23a62f3a-abbda39282dmr190609366b.7.1740048167474; Thu, 20 Feb 2025 02:42:47 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:47 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 09/15] iio: accel: adxl345: add freefall feature Date: Thu, 20 Feb 2025 10:42:28 +0000 Message-Id: <20250220104234.40958-10-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the freefall detection of the sensor together with a threshold and time parameter. A freefall event is detected if the measuring signal falls below the threshold. Introduce a freefall threshold stored in regmap cache, and a freefall time, having the scaled time value stored as a member variable in the state instance. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 122 +++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 10cd81dd08bb..7f842e7f371a 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -79,6 +79,7 @@ struct adxl345_state { u32 tap_duration_us; u32 tap_latent_us; u32 tap_window_us; + u32 ff_time_ms; __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; @@ -98,6 +99,14 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_EV_INFO_RESET_TIMEOUT) | BIT(IIO_EV_INFO_TAP2_MIN_DELAY), }, + { + /* free fall */ + .type = IIO_EV_TYPE_MAG, + .dir = IIO_EV_DIR_FALLING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD), + }, }; #define ADXL345_CHANNEL(index, reg, axis) { \ @@ -345,6 +354,64 @@ static int adxl345_set_tap_latent(struct adxl345_state *st, u32 val_int, return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_LATENT, val_fract_us); } +/* freefall */ + +static int adxl345_is_ff_en(struct adxl345_state *st, bool *en) +{ + int ret; + unsigned int regval; + + ret = regmap_read(st->regmap, ADXL345_REG_INT_ENABLE, ®val); + if (ret) + return ret; + + *en = FIELD_GET(ADXL345_INT_FREE_FALL, regval) > 0; + + return 0; +} + +static int adxl345_set_ff_en(struct adxl345_state *st, bool cmd_en) +{ + unsigned int regval, ff_threshold; + const unsigned int freefall_mask = 0x02; + bool en; + int ret; + + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_FF, &ff_threshold); + if (ret) + return ret; + + en = cmd_en && ff_threshold > 0 && st->ff_time_ms > 0; + + regval = en ? ADXL345_INT_FREE_FALL : 0x00; + + return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + freefall_mask, regval); +} + +static int adxl345_set_ff_time(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + unsigned int regval; + int val_ms; + + /* + * max value is 255 * 5000 us = 1.275000 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (1000000 * val_int + val_fract_us > 1275000) + return -EINVAL; + + val_ms = val_int * 1000 + DIV_ROUND_UP(val_fract_us, 1000); + st->ff_time_ms = val_ms; + + regval = DIV_ROUND_CLOSEST(val_ms, 5); + + /* Values between 100ms and 350ms (0x14 to 0x46) are recommended. */ + return regmap_write(st->regmap, ADXL345_REG_TIME_FF, min(regval, 0xff)); +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -471,6 +538,11 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_EV_TYPE_MAG: + ret = adxl345_is_ff_en(st, &int_en); + if (ret) + return ret; + return int_en; default: return -EINVAL; } @@ -510,6 +582,8 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_EV_TYPE_MAG: + return adxl345_set_ff_en(st, state); default: return -EINVAL; } @@ -524,6 +598,7 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, { struct adxl345_state *st = iio_priv(indio_dev); unsigned int tap_threshold; + unsigned int ff_threshold; int ret; switch (type) { @@ -554,6 +629,22 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_EV_TYPE_MAG: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_FF, + &ff_threshold); + if (ret) + return ret; + *val = ff_threshold; + return IIO_VAL_INT; + case IIO_EV_INFO_PERIOD: + *val = st->ff_time_ms; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -594,6 +685,18 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, break; } break; + case IIO_EV_TYPE_MAG: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_FF, val); + break; + case IIO_EV_INFO_PERIOD: + ret = adxl345_set_ff_time(st, val, val2); + break; + default: + ret = -EINVAL; + } + break; default: ret = -EINVAL; break; @@ -855,6 +958,17 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_FREE_FALL, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_FALLING), + ts); + if (ret) + return ret; + } + return -ENOENT; } @@ -954,6 +1068,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, ADXL345_DATA_FORMAT_FULL_RES | ADXL345_DATA_FORMAT_SELF_TEST); unsigned int tap_threshold; + unsigned int ff_threshold; int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); @@ -973,6 +1088,9 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, st->tap_window_us = 64; /* 64 [0x40] -> .080 */ st->tap_latent_us = 16; /* 16 [0x10] -> .020 */ + ff_threshold = 8; /* 8 [0x08] */ + st->ff_time_ms = 32; /* 32 [0x20] -> 0.16 */ + indio_dev->name = st->info->name; indio_dev->info = &adxl345_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -1049,6 +1167,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_FF, ff_threshold); + if (ret) + return ret; + /* FIFO_STREAM mode is going to be activated later */ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops); if (ret) From patchwork Thu Feb 20 10:42:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983700 Received: from mail-ed1-f53.google.com (mail-ed1-f53.google.com [209.85.208.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97AB41F428C; Thu, 20 Feb 2025 10:42:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048172; cv=none; b=fD8bKy4vMyRJhWmKIMfPsJVabtQD60rDRv62WXeriLVtASNlAURYk+QoZnWvXcTMQRy3d9Do97FKHGnYGTdpVxxl2/0TtmTneA0aGIOP7nhIgGRHtgiZwrkFW0ORQ8QkyEOGzCs4hDE+jXtarUvZeq86oSiCuXA+vKXbOgUAww4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048172; c=relaxed/simple; bh=lL+hww8qypifEWxDc4Ga7vH211Gpv7Y3QGOVz8+qGkY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BVXhVsNsy2eFxSY5SaMd1KQj7EHNWTU9ou+KctzD1REcZnUB8Dclw4Omw/gpLWgORNA94+4Uq2Meu00ztaFoIovzO1AzIngELVvSgbbgqmwMX2kNc+guS7JvoFHXHuwaR3Xt19PGnGiSClvGHLZeH/CfV3r+TiypBsq8ejJMkyw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CxDrlvyZ; arc=none smtp.client-ip=209.85.208.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CxDrlvyZ" Received: by mail-ed1-f53.google.com with SMTP id 4fb4d7f45d1cf-5e064eff5daso112560a12.3; Thu, 20 Feb 2025 02:42:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048169; x=1740652969; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AUrmgIro4kpHq9lw5fat0MfsUBFGR/sMxiYGfYYR3a8=; b=CxDrlvyZdSS6MJZW9cuITYZZEsB+tZSb4ibhyBNrn4/2vKG5niihQxR1p3C/3+8Kf7 J86fwJ8JMGrFIZc2L6dwHTUmKwwrSxXq4EeBnJIzHealFiG+PyjBIgpNFEFYAI0FJBjx vI1LWLun+XBkPYOJxEHr2cupvbuVXe7NYICgmr3gGvsagxJ+8zADY1uLmgVG3fZwYGcP SqdNVa3jMKl9vdD3bUXLan2nl2RocFBbhYiQg3hKSnwwQvcy4QvcYEHXPY7EA5zOW9Uw 9r0ozFDYoshvgcp/dqZP8/IiV1EpDI4I0MAKgwdfzesrQ+AwO/gNzfoXui3jJAHJBccw YsWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048169; x=1740652969; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AUrmgIro4kpHq9lw5fat0MfsUBFGR/sMxiYGfYYR3a8=; b=mbS6qCadxZtSHfXApXuV4ZJISErn+CHl6h1jVOvEP+MOKbT9qD+U8xJd9zyys3aRao nKvGwNFLhu2T3WKwmEi9CMnvEN3MTfgbfr9LR7UBZ5/UR3WFxEzEY2RvyY6CCy+19jLI o/FTRqy2NOBdwIIWkX3o0Zmt4zPYiv1aArxtolXDymrpQNJV2kNBhxxeSVZBZpdpGn6b lXErKnwQ96DTGdIvTy8UwVcc5lL9Z4//Oc5ZS5jcsvJXYZZcVnpSKWlttQyAPDUGNNiR NSwUxtWQIMgyERxNwT+1qqXIILac+lZ8H7WGOcQg4vQrhRHZarlRv9MzxYhX+P6AJpZ0 2JHA== X-Forwarded-Encrypted: i=1; AJvYcCWsH6+zeAnLEi5RWIyIduCoDvbqt846DbsMcrAVXUatsgfk44Q10adxx1TU8sZGUdFpVVi0bJ9uh7HjPcQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzhFhn3KXyD49oCWUgsbJUeSFXz0ZNTRaXhuTdOq+m+P5123ZI7 v1ZeKiDNeK0cMxkLFYbSerc2puqpVh4aTxkR9x/vctlYdOF+5Q1d X-Gm-Gg: ASbGncuMaE41NibJ7UNe7dtATB+uDVMLziYyvIC1yniyttv7xq8xiSoYonqt3suP07n e8k80Zv6APftjeA8gry2ndVyLl48zhv41jpzCjv0/wZAJCHfexQpvIeEVuOfe/3hGlUw/FeFQbj 9CKYXFsS14Mp91pLZkCqsAeAm6jA/uiFTSKs+hdAg8eE5Sy4vD7HF/eLk3jFaGNc5XlqgiEGLlf 0/dBHt9t1fTuKVaHSm6Rza4tYCny4XASuKYxsXNIcMAIYm1BG/uBZjmUmWc39G2LoqBw7lmEgRX ddTPxGQUvo+qELBOi4RN0ZtqdTvKfPozH76H2YF73iLV1Wxz8GZK0/CHBXjijIRqWsj/cA== X-Google-Smtp-Source: AGHT+IFQs/AO+xL+HxwjZerlmm6Calnmwm0sJ5il+mi62zDy4q1DngZ1QqR1hnwoZetqouF0aMjGeQ== X-Received: by 2002:a17:906:6a0c:b0:aba:6055:9ed1 with SMTP id a640c23a62f3a-abb70ab8b8amr843946566b.6.1740048168539; Thu, 20 Feb 2025 02:42:48 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:48 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 10/15] iio: accel: adxl345: extend sample frequency adjustments Date: Thu, 20 Feb 2025 10:42:29 +0000 Message-Id: <20250220104234.40958-11-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce enums and functions to work with the sample frequency adjustments. Let the sample frequency adjust via IIO and configure a reasonable default. Replace the old static sample frequency handling. The patch is in preparation for activity/inactivity handling. During adjustment of bw registers, measuring is disabled and afterwards enabled again. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345.h | 2 +- drivers/iio/accel/adxl345_core.c | 160 ++++++++++++++++++++++++------- 2 files changed, 126 insertions(+), 36 deletions(-) diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h index a2a81caa292a..56db8f8ba032 100644 --- a/drivers/iio/accel/adxl345.h +++ b/drivers/iio/accel/adxl345.h @@ -71,7 +71,7 @@ * BW_RATE bits - Bandwidth and output data rate. The default value is * 0x0A, which translates to a 100 Hz output data rate */ -#define ADXL345_BW_RATE GENMASK(3, 0) +#define ADXL345_BW_RATE_MSK GENMASK(3, 0) #define ADXL345_BW_LOW_POWER BIT(4) #define ADXL345_BASE_RATE_NANO_HZ 97656250LL diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 7f842e7f371a..fa169cac5c05 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -67,6 +67,45 @@ static const unsigned int adxl345_tap_time_reg[] = { [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; +enum adxl345_odr { + ADXL345_ODR_0P10HZ = 0, + ADXL345_ODR_0P20HZ, + ADXL345_ODR_0P39HZ, + ADXL345_ODR_0P78HZ, + ADXL345_ODR_1P56HZ, + ADXL345_ODR_3P13HZ, + ADXL345_ODR_6P25HZ, + ADXL345_ODR_12P50HZ, + ADXL345_ODR_25HZ, + ADXL345_ODR_50HZ, + ADXL345_ODR_100HZ, + ADXL345_ODR_200HZ, + ADXL345_ODR_400HZ, + ADXL345_ODR_800HZ, + ADXL345_ODR_1600HZ, + ADXL345_ODR_3200HZ, +}; + +/* Certain features recommend 12.5 Hz - 400 Hz ODR */ +static const int adxl345_odr_tbl[][2] = { + [ADXL345_ODR_0P10HZ] = { 0, 97000 }, + [ADXL345_ODR_0P20HZ] = { 0, 195000 }, + [ADXL345_ODR_0P39HZ] = { 0, 390000 }, + [ADXL345_ODR_0P78HZ] = { 0, 781000 }, + [ADXL345_ODR_1P56HZ] = { 1, 562000 }, + [ADXL345_ODR_3P13HZ] = { 3, 125000 }, + [ADXL345_ODR_6P25HZ] = { 6, 250000 }, + [ADXL345_ODR_12P50HZ] = { 12, 500000 }, + [ADXL345_ODR_25HZ] = { 25, 0 }, + [ADXL345_ODR_50HZ] = { 50, 0 }, + [ADXL345_ODR_100HZ] = { 100, 0 }, + [ADXL345_ODR_200HZ] = { 200, 0 }, + [ADXL345_ODR_400HZ] = { 400, 0 }, + [ADXL345_ODR_800HZ] = { 800, 0 }, + [ADXL345_ODR_1600HZ] = { 1600, 0 }, + [ADXL345_ODR_3200HZ] = { 3200, 0 }, +}; + struct adxl345_state { const struct adxl345_chip_info *info; struct regmap *regmap; @@ -118,6 +157,7 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_CHAN_INFO_CALIBBIAS), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = (index), \ .scan_type = { \ .sign = 's', \ @@ -412,14 +452,61 @@ static int adxl345_set_ff_time(struct adxl345_state *st, u32 val_int, return regmap_write(st->regmap, ADXL345_REG_TIME_FF, min(regval, 0xff)); } +static int adxl345_find_odr(struct adxl345_state *st, int val, + int val2, enum adxl345_odr *odr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adxl345_odr_tbl); i++) + if (val == adxl345_odr_tbl[i][0] && + val2 == adxl345_odr_tbl[i][1]) + break; + + if (i == ARRAY_SIZE(adxl345_odr_tbl)) + return -EINVAL; + + *odr = i; + + return 0; +} + +static int adxl345_set_odr(struct adxl345_state *st, enum adxl345_odr odr) +{ + int ret; + + ret = regmap_update_bits(st->regmap, ADXL345_REG_BW_RATE, + ADXL345_BW_RATE_MSK, + FIELD_PREP(ADXL345_BW_RATE_MSK, odr)); + if (ret) + return ret; + + return 0; +} + +static int adxl345_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, + int *length, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = (int *)adxl345_odr_tbl; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(adxl345_odr_tbl) * 2; + return IIO_AVAIL_LIST; + } + + return -EINVAL; +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct adxl345_state *st = iio_priv(indio_dev); __le16 accel; - long long samp_freq_nhz; unsigned int regval; + enum adxl345_odr odr; int ret; switch (mask) { @@ -455,14 +542,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ: ret = regmap_read(st->regmap, ADXL345_REG_BW_RATE, ®val); - if (ret < 0) + if (ret) return ret; - - samp_freq_nhz = ADXL345_BASE_RATE_NANO_HZ << - (regval & ADXL345_BW_RATE); - *val = div_s64_rem(samp_freq_nhz, NANOHZ_PER_HZ, val2); - - return IIO_VAL_INT_PLUS_NANO; + odr = FIELD_GET(ADXL345_BW_RATE_MSK, regval); + *val = adxl345_odr_tbl[odr][0]; + *val2 = adxl345_odr_tbl[odr][1]; + return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; @@ -473,7 +558,12 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct adxl345_state *st = iio_priv(indio_dev); - s64 n; + enum adxl345_odr odr; + int ret; + + ret = adxl345_set_measure_en(st, false); + if (ret) + return ret; switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: @@ -481,20 +571,24 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, * 8-bit resolution at +/- 2g, that is 4x accel data scale * factor */ - return regmap_write(st->regmap, - ADXL345_REG_OFS_AXIS(chan->address), - val / 4); + ret = regmap_write(st->regmap, + ADXL345_REG_OFS_AXIS(chan->address), + val / 4); + break; case IIO_CHAN_INFO_SAMP_FREQ: - n = div_s64(val * NANOHZ_PER_HZ + val2, - ADXL345_BASE_RATE_NANO_HZ); - - return regmap_update_bits(st->regmap, ADXL345_REG_BW_RATE, - ADXL345_BW_RATE, - clamp_val(ilog2(n), 0, - ADXL345_BW_RATE)); + ret = adxl345_find_odr(st, val, val2, &odr); + if (ret) + return ret; + ret = adxl345_set_odr(st, odr); + break; + default: + return -EINVAL; } - return -EINVAL; + if (ret) + return ret; + + return adxl345_set_measure_en(st, true); } static int adxl345_read_event_config(struct iio_dev *indio_dev, @@ -747,7 +841,7 @@ static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ: - return IIO_VAL_INT_PLUS_NANO; + return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } @@ -760,19 +854,6 @@ static void adxl345_powerdown(void *ptr) adxl345_set_measure_en(st, false); } -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( -"0.09765625 0.1953125 0.390625 0.78125 1.5625 3.125 6.25 12.5 25 50 100 200 400 800 1600 3200" -); - -static struct attribute *adxl345_attrs[] = { - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - NULL -}; - -static const struct attribute_group adxl345_attrs_group = { - .attrs = adxl345_attrs, -}; - static int adxl345_set_fifo(struct adxl345_state *st) { unsigned int intio; @@ -1026,9 +1107,9 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) } static const struct iio_info adxl345_info = { - .attrs = &adxl345_attrs_group, .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, + .read_avail = adxl345_read_avail, .write_raw_get_fmt = adxl345_write_raw_get_fmt, .read_event_config = adxl345_read_event_config, .write_event_config = adxl345_write_event_config, @@ -1098,6 +1179,15 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, indio_dev->num_channels = ARRAY_SIZE(adxl345_channels); indio_dev->available_scan_masks = adxl345_scan_masks; + /* + * Using I2C at 100kHz would limit the maximum ODR to 200Hz, operation + * at an output rate above the recommended maximum may result in + * undesired behavior. + */ + ret = adxl345_set_odr(st, ADXL345_ODR_200HZ); + if (ret) + return ret; + /* Reset interrupts at start up */ ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); if (ret) From patchwork Thu Feb 20 10:42:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983701 Received: from mail-ed1-f43.google.com (mail-ed1-f43.google.com [209.85.208.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85F6C1F4615; Thu, 20 Feb 2025 10:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048173; cv=none; b=JmPG1hYffDNRNta7zqOhdLY+nkruFI9EAaY9m/oa2A7qrahsGMoBSRUd3nwWn+NgqzCHqypUWqJANESyooedvXQT7gIfB7PySrV2aBDwPpldcaLleG7A8/Iiqjh37cN+NKwdIkVXMW8a6aXAA0EoPszR6TlHvOz+NS1fp9uL4x4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048173; c=relaxed/simple; bh=LxtIrUFteDDKmKcX/ZnsaTUAF/4mrLvV0rdrAa2Bqjs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=R+puiIFWPCtf10XLn84LoU2DW0Ijlg89wr3q9/T9b9KhXW3CN2BMNABZ/eKtI6H3+CIErGRzHW97SB5EvBDK5R3p+QjVf6Ki8wnygRmtkFRCShwZzl/45RVPrDEGygWZOzvWtaLskYdqQMf3Qu/PyMZZH+Q4x0UiAUSsU4xqCMI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jLx37zRl; arc=none smtp.client-ip=209.85.208.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jLx37zRl" Received: by mail-ed1-f43.google.com with SMTP id 4fb4d7f45d1cf-5e02e77ea3cso114310a12.1; Thu, 20 Feb 2025 02:42:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048170; x=1740652970; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+S7zYlGYeCjAulnCrofN1PfLY/a3p/8tfgmUZCm9Ol8=; b=jLx37zRlAf/8N7Glx1v3IoT+F6VUIpYieGGXN1qmyAmY3nG2e1oNvEXkc1y6f77l77 YEgVZZy8uUPyuJjNMiP46UDsNDkMCs5buklRm7dJ5j9P0DHL3h+3BIYL2RxvTt70DrFK 1Eg4JaTRDl2pzhwpkkGJr7h/9jdmSJwHmyRO9L9NeMLDh0gJ0/T0tdr22fFTYRT9f09D WO/zMwTJIXPwSapRUSEOklH5/rTvPgY8cmuiHTi4gWJk/KmM5MT006P8K8QVuKGqXgdX 6YACn0dHUD9MmWddjLchcRxcwlTcDJp0sHLvDvDu5gQ6A+lqaRqficavR6PKeu8F2roc BqWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048170; x=1740652970; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+S7zYlGYeCjAulnCrofN1PfLY/a3p/8tfgmUZCm9Ol8=; b=GTijNjWvkW38kLI8JbziZPkVlp8IY1YAiuWfNnvBxB7Y9we0OQsp7M6qf6b+ZnCG1b f+YiJyqkYpqDpsH+5IAhMh9JZpLgubgIi1kQkoXjZuxMrmaBwZF590s8DbzTTTy8Jqf8 WBvuBaZbMu4HiQYZGibnHLKkJcr3FO8rjaLSYAPrteydm0YaXYuKY4UOZ8LOleZGrTfN /u/S+5hK8ryqcj/hIoXzMLE+GHkoMnkZJH+Y3jM2UoTMuvwT7TEho+t2Sw+9tpj1UbZZ 1YJzzhYLUC9pwy0nArZkwgpOiyuB2w5spunS3xT7I8vBOXsGl6L5WzyXHW1IYXZsHQfe oWyQ== X-Forwarded-Encrypted: i=1; AJvYcCUovfBslzHg25GEhFXgSi/10vd5pg1VpspV6sddc3t3LH7gABaL04dbNGtvESUJZgGsv3Yf03kL74aPhhc=@vger.kernel.org X-Gm-Message-State: AOJu0Yz1D+UNnH3WZ61u7MtQhV09d9dGkLgOmaRhsHv65gk2pjy0m3Zr xAbmazVqYltZE3NUUpSs59NLMrQq8ecniiarEkBFxzKB1bAbCExF X-Gm-Gg: ASbGncuooKh79Yhdx++MuzEOMEZgVBunIn8n/r8efcp/DKGRk9OsxaNmdwFAfLr3Flp R9W7Z1/ODeLt7rVXMddIG+GbJVEZT39Y7oKd8i078ar7OLk1cY/f+Tej/Zm+TQAgC3VLItfC0hE M+QJu4DZ8rYsGC5P03YTJ4nVyp4/cz4nR40uMj4SE+CWjhx638di9b6r0WG6lFix0CkIcsFbAej kihGtnA1bigr3EPjHUC4YzfIhcdZbcZvMpg0tFeIfHHWkZ65Na7fXD3+BSXj1AnTBAhUHyiCi5q mi8Zkx3mplNd0VUhSfiUsaw/auvM3uN9Yl5mKqyc3VegJF6BZp26tGoOPqE2CqjGk9fNnA== X-Google-Smtp-Source: AGHT+IF6+xN3/oIAflY+Ife4FcQq4ki50NzVMFwj8uXxU3DGU6xQPyEwAsfz9uqcuVi4Gev3p+wObw== X-Received: by 2002:a17:906:3ca:b0:abb:e7b0:5449 with SMTP id a640c23a62f3a-abbe7b05ba2mr103453066b.11.1740048169532; Thu, 20 Feb 2025 02:42:49 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:49 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 11/15] iio: accel: adxl345: add g-range configuration Date: Thu, 20 Feb 2025 10:42:30 +0000 Message-Id: <20250220104234.40958-12-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce means to configure and work with the available g-ranges keeping the precision of 13 digits. This is in preparation for the activity/inactivity feature. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 91 ++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index fa169cac5c05..ab1ab09f348a 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -86,6 +86,13 @@ enum adxl345_odr { ADXL345_ODR_3200HZ, }; +enum adxl345_range { + ADXL345_2G_RANGE = 0, + ADXL345_4G_RANGE, + ADXL345_8G_RANGE, + ADXL345_16G_RANGE, +}; + /* Certain features recommend 12.5 Hz - 400 Hz ODR */ static const int adxl345_odr_tbl[][2] = { [ADXL345_ODR_0P10HZ] = { 0, 97000 }, @@ -106,6 +113,33 @@ static const int adxl345_odr_tbl[][2] = { [ADXL345_ODR_3200HZ] = { 3200, 0 }, }; +/* + * Full resolution frequency table: + * (g * 2 * 9.80665) / (2^(resolution) - 1) + * + * resolution := 13 (full) + * g := 2|4|8|16 + * + * 2g at 13bit: 0.004789 + * 4g at 13bit: 0.009578 + * 8g at 13bit: 0.019156 + * 16g at 16bit: 0.038312 + */ +static const int adxl345_fullres_range_tbl[][2] = { + [ADXL345_2G_RANGE] = { 0, 4789 }, + [ADXL345_4G_RANGE] = { 0, 9578 }, + [ADXL345_8G_RANGE] = { 0, 19156 }, + [ADXL345_16G_RANGE] = { 0, 38312 }, +}; + +/* scaling */ +static const int adxl345_range_factor_tbl[] = { + [ADXL345_2G_RANGE] = 1, + [ADXL345_4G_RANGE] = 2, + [ADXL345_8G_RANGE] = 4, + [ADXL345_16G_RANGE] = 8, +}; + struct adxl345_state { const struct adxl345_chip_info *info; struct regmap *regmap; @@ -157,7 +191,8 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_CHAN_INFO_CALIBBIAS), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = (index), \ .scan_type = { \ .sign = 's', \ @@ -483,12 +518,48 @@ static int adxl345_set_odr(struct adxl345_state *st, enum adxl345_odr odr) return 0; } +static int adxl345_find_range(struct adxl345_state *st, int val, int val2, + enum adxl345_range *range) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adxl345_fullres_range_tbl); i++) + if (val == adxl345_fullres_range_tbl[i][0] && + val2 == adxl345_fullres_range_tbl[i][1]) + break; + + if (i == ARRAY_SIZE(adxl345_fullres_range_tbl)) + return -EINVAL; + + *range = i; + + return 0; +} + +static int adxl345_set_range(struct adxl345_state *st, enum adxl345_range range) +{ + int ret; + + ret = regmap_update_bits(st->regmap, ADXL345_REG_DATA_FORMAT, + ADXL345_DATA_FORMAT_RANGE, + FIELD_PREP(ADXL345_DATA_FORMAT_RANGE, range)); + if (ret) + return ret; + + return 0; +} + static int adxl345_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, const int **vals, int *type, int *length, long mask) { switch (mask) { + case IIO_CHAN_INFO_SCALE: + *vals = (int *)adxl345_fullres_range_tbl; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(adxl345_fullres_range_tbl) * 2; + return IIO_AVAIL_LIST; case IIO_CHAN_INFO_SAMP_FREQ: *vals = (int *)adxl345_odr_tbl; *type = IIO_VAL_INT_PLUS_MICRO; @@ -507,6 +578,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, __le16 accel; unsigned int regval; enum adxl345_odr odr; + enum adxl345_range range; int ret; switch (mask) { @@ -525,8 +597,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, *val = sign_extend32(le16_to_cpu(accel), 12); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = 0; - *val2 = st->info->uscale; + ret = regmap_read(st->regmap, ADXL345_REG_DATA_FORMAT, ®val); + if (ret) + return ret; + range = FIELD_GET(ADXL345_DATA_FORMAT_RANGE, regval); + *val = adxl345_fullres_range_tbl[range][0]; + *val2 = adxl345_fullres_range_tbl[range][1]; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_CALIBBIAS: ret = regmap_read(st->regmap, @@ -558,6 +634,7 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct adxl345_state *st = iio_priv(indio_dev); + enum adxl345_range range; enum adxl345_odr odr; int ret; @@ -581,6 +658,12 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, return ret; ret = adxl345_set_odr(st, odr); break; + case IIO_CHAN_INFO_SCALE: + ret = adxl345_find_range(st, val, val2, &range); + if (ret) + return ret; + ret = adxl345_set_range(st, range); + break; default: return -EINVAL; } @@ -840,6 +923,8 @@ static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_SAMP_FREQ: return IIO_VAL_INT_PLUS_MICRO; default: From patchwork Thu Feb 20 10:42:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983702 Received: from mail-ed1-f44.google.com (mail-ed1-f44.google.com [209.85.208.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 990D71F463B; Thu, 20 Feb 2025 10:42:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048174; cv=none; b=KQgL87w237vlHO/v/P+o4EnAMDH8dhDNUJKXTMsyNZbZW2ADpy+DJ+ubgNx39AalNvDoUpWs3gTMutWB+vv4mnIL8m80Z/rXxbLDSucUuxetC1av2PG0npQ77fvra8H2br91pz74Dh9HtBVIDVukOQDL0+KGy013QES08EvjKIg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048174; c=relaxed/simple; bh=veoJEo01/TYfg9M49Wpt0ngS9B4jMEJA09W/RI4zBEY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=S9DFCi2cNJwqZGDoTZVGugPdCjWfgCPE4qNxBDRc9MdV77iEWDoLpdaa+JdBzayVVogm/S+j22iS8upRZOCM7QQZIl7T4bPe7btI7vPYzabYPIl/Fz37cPQDZ0UAjdkAtJMTSr0cLnx15mX7Ix4vFBdSrfL90S/ZXNgvgg2dsGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KBdy8vCv; arc=none smtp.client-ip=209.85.208.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KBdy8vCv" Received: by mail-ed1-f44.google.com with SMTP id 4fb4d7f45d1cf-5e02e77ea3cso114311a12.1; Thu, 20 Feb 2025 02:42:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048171; x=1740652971; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yEuSZNgL2ESJTm75rVqG1TiF5psoPm0kxIpMbt1HsYc=; b=KBdy8vCvRq6AF9MdnyZrfJcekvgp2hCwM880mvFPX7IrTdA9xOFn6u9u/tTdTC6v0f F8XO2LF4ff0kwwPnAoRYXMu4CTemUELi+zWOG1veBxbWfc9GlECIctfHb8HKj6NHLfgp LJ06/Qs9mL181sYRTknL92kv2KwvBxratIAgSh6Cd1gsViTba7UNf/Abd6h/ulh/9eYh uXoFECCycK8G3pFXCRcFxuddokOHSyKXdhXctyRClniFVIzm/DnPblSGFgrIkDLm4HOC BV4UEN6TTeJaBWzNJRPg2lc5O9FcIoxr4wuXuEKx9kDxAsBbUQG+b1e8nKFDwQcoM7Aj 3pqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048171; x=1740652971; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yEuSZNgL2ESJTm75rVqG1TiF5psoPm0kxIpMbt1HsYc=; b=r6Ce6xVM2UA3tERcdV5QADmiZfW/euso8fKliQHdYhjBrOOQbo1GxNY2vQ/RwSpkHt ssX5sE2NuwFHk5ohr7YknQo1XZ2eUw8jO20bn7ad1GrJPNu8w2wlJJrCIM4pIDJEgFYc cDMCH0ljP+qbFMOajUUphZrB8+nGJm/1poDYPPTZvw2zJt4+ObpE2KBe/lLu+sZTC6D7 kSvw3aAA2WCRb23/ywpoBLkFe4Bs3wxHS4y9vnTCXzaVK3fgWGUjk/Ab2onNtx1SUa50 udExuVPHOjFPe27vp6or9rK2HKVoJ/xFWs3+/z/iiXECOO8iMUVCD/Rb6/ONuZnPWEM8 5sZw== X-Forwarded-Encrypted: i=1; AJvYcCUvKXLFmmf4qxCN3OjN7sn7m93PqXaP0HiXeiK3SOcwiApL6nptG6M0a+8C1E73FFQLt2iqM1QEXKdV+x4=@vger.kernel.org X-Gm-Message-State: AOJu0Ywc+HUFkdvdTXhksMh0AuDN6PJmGKl6JU6KUiWcnhXmhmauXZRJ 1Ma3P/GRmScEFuLsqlHad4dOB+Esc8cpS0iT9Fu70rgetkXbp7TC X-Gm-Gg: ASbGncs7/JNlFjqWfwNxKoaqAno2ZYbZUEQt+udAFpy1XnphKnfFf3A5NMj+/8+4yCQ kU51Cie/rGpQkKuXt0jZ/A0/vrrguEe9lZUgr3z/7QecQDrm63jwZ5TTnIXF/I3CyyMrgHLeI99 hjR9iegOQBeSvD31mQrqFaxz6aIFTGo9oHFJNIvsbfeZEv5uVr7dBeM1UyHgNcP5k8Ub/ZPnOqX 9U2c8keRZR5pO1E+SzCPLSmFhoNxu8cnRtTUDVZf+tsHhJeex36qbH65+1tI4vs9fjeIT7kQcbm c8slquJqPA7jH093yfYwKGxoZ3pOIk7Qdjr08f7yVoPdF3EvNmZeUe92JPra0pzaEMXrvw== X-Google-Smtp-Source: AGHT+IEP4Q+5+zwugRKwDMhtpe2w1LYTE2MhbvCVG88FNINMlPB0sBZu9Zl/nS4C3wkdt+Ez4Xk5jQ== X-Received: by 2002:a17:907:9690:b0:ab6:d575:3c41 with SMTP id a640c23a62f3a-abb7093229dmr749092866b.3.1740048170491; Thu, 20 Feb 2025 02:42:50 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:50 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 12/15] iio: accel: adxl345: add activity event feature Date: Thu, 20 Feb 2025 10:42:31 +0000 Message-Id: <20250220104234.40958-13-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Make the sensor detect and issue interrupts at activity. Activity events are configured by a threshold stored in regmap cache. Activity, together with ODR and range setting are preparing a setup together with inactivity coming in a follow up patch. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 183 +++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index ab1ab09f348a..f1895925a80b 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -35,6 +35,7 @@ #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) #define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) +#define ADXL345_REG_ACT_AXIS_MSK GENMASK(6, 4) enum adxl345_axis { ADXL345_Z_EN = BIT(0), @@ -67,6 +68,23 @@ static const unsigned int adxl345_tap_time_reg[] = { [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; +/* activity/inactivity */ +enum adxl345_activity_type { + ADXL345_ACTIVITY, +}; + +static const unsigned int adxl345_act_int_reg[] = { + [ADXL345_ACTIVITY] = ADXL345_INT_ACTIVITY, +}; + +static const unsigned int adxl345_act_thresh_reg[] = { + [ADXL345_ACTIVITY] = ADXL345_REG_THRESH_ACT, +}; + +static const unsigned int adxl345_act_axis_msk[] = { + [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, +}; + enum adxl345_odr { ADXL345_ODR_0P10HZ = 0, ADXL345_ODR_0P20HZ, @@ -148,6 +166,7 @@ struct adxl345_state { u8 watermark; u8 fifo_mode; + u32 act_axis_ctrl; u32 tap_axis_ctrl; u32 tap_duration_us; u32 tap_latent_us; @@ -158,6 +177,13 @@ struct adxl345_state { }; static struct iio_event_spec adxl345_events[] = { + { + /* activity */ + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_VALUE), + }, { .type = IIO_EV_TYPE_GESTURE, .dir = IIO_EV_DIR_SINGLETAP, @@ -258,6 +284,73 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); } +/* act/inact */ + +static int adxl345_write_act_axis(struct adxl345_state *st, + enum adxl345_activity_type type, bool en) +{ + int ret; + + /* + * The ADXL345 allows for individually enabling/disabling axis for + * activity and inactivity detection, respectively. Here both axis are + * kept in sync, i.e. an axis will be generally enabled or disabled for + * both equally, activity and inactivity detection. + */ + if (type == ADXL345_ACTIVITY) { + st->act_axis_ctrl = en + ? st->act_axis_ctrl | ADXL345_REG_ACT_AXIS_MSK + : st->act_axis_ctrl & ~ADXL345_REG_ACT_AXIS_MSK; + + ret = regmap_update_bits(st->regmap, ADXL345_REG_ACT_INACT_CTRL, + adxl345_act_axis_msk[type], + st->act_axis_ctrl); + if (ret) + return ret; + } + return 0; +} + +static int adxl345_is_act_inact_en(struct adxl345_state *st, + enum adxl345_activity_type type, bool *en) +{ + int ret; + unsigned int regval; + + ret = regmap_read(st->regmap, ADXL345_REG_INT_ENABLE, ®val); + if (ret) + return ret; + + *en = (adxl345_act_int_reg[type] & regval) > 0; + + return 0; +} + +static int adxl345_set_act_inact_en(struct adxl345_state *st, + enum adxl345_activity_type type, bool cmd_en) +{ + bool axis_en, en = false; + unsigned int threshold; + int ret; + + ret = adxl345_write_act_axis(st, type, cmd_en); + if (ret) + return ret; + + ret = regmap_read(st->regmap, adxl345_act_thresh_reg[type], &threshold); + if (ret) + return ret; + + if (type == ADXL345_ACTIVITY) { + axis_en = FIELD_GET(ADXL345_REG_ACT_AXIS_MSK, st->act_axis_ctrl) > 0; + en = axis_en && threshold > 0; + } + + return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + adxl345_act_int_reg[type], + en ? adxl345_act_int_reg[type] : 0); +} + /* tap */ static int adxl345_write_tap_axis(struct adxl345_state *st, @@ -685,6 +778,16 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, int ret = -EFAULT; switch (type) { + case IIO_EV_TYPE_THRESH: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = adxl345_is_act_inact_en(st, ADXL345_ACTIVITY, &int_en); + if (ret) + return ret; + return int_en; + default: + return -EINVAL; + } case IIO_EV_TYPE_GESTURE: switch (chan->channel2) { case IIO_MOD_X: @@ -735,6 +838,13 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, enum adxl345_axis axis; switch (type) { + case IIO_EV_TYPE_THRESH: + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl345_set_act_inact_en(st, ADXL345_ACTIVITY, state); + default: + return -EINVAL; + } case IIO_EV_TYPE_GESTURE: switch (chan->channel2) { case IIO_MOD_X: @@ -776,9 +886,29 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, struct adxl345_state *st = iio_priv(indio_dev); unsigned int tap_threshold; unsigned int ff_threshold; + unsigned int act_threshold; int ret; switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_ACTIVITY], + &act_threshold); + if (ret) + return ret; + + *val = act_threshold; + return IIO_VAL_INT; + default: + return -EINVAL; + } + default: + return -EINVAL; + } case IIO_EV_TYPE_GESTURE: switch (info) { case IIO_EV_INFO_VALUE: @@ -842,6 +972,23 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, return ret; switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = regmap_write(st->regmap, + adxl345_act_thresh_reg[ADXL345_ACTIVITY], + val); + break; + default: + ret = -EINVAL; + } + break; + default: + ret = -EINVAL; + } + break; case IIO_EV_TYPE_GESTURE: switch (info) { case IIO_EV_INFO_VALUE: @@ -1124,6 +1271,17 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_ACTIVITY, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + act_tap_dir, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + ts); + if (ret) + return ret; + } + if (FIELD_GET(ADXL345_INT_FREE_FALL, int_stat)) { ret = iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, @@ -1157,6 +1315,7 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) ret = regmap_read(st->regmap, ADXL345_REG_ACT_TAP_STATUS, ®val); if (ret) return ret; + /* tap direction */ if (FIELD_GET(ADXL345_Z_EN, regval) > 0) act_tap_dir = IIO_MOD_Z; else if (FIELD_GET(ADXL345_Y_EN, regval) > 0) @@ -1165,6 +1324,19 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) act_tap_dir = IIO_MOD_X; } + if (FIELD_GET(ADXL345_REG_ACT_AXIS_MSK, st->act_axis_ctrl) > 0) { + ret = regmap_read(st->regmap, ADXL345_REG_ACT_TAP_STATUS, ®val); + if (ret) + return ret; + /* activity direction */ + if (FIELD_GET(ADXL345_Z_EN, regval >> 4) > 0) + act_tap_dir = IIO_MOD_Z; + else if (FIELD_GET(ADXL345_Y_EN, regval >> 4) > 0) + act_tap_dir = IIO_MOD_Y; + else if (FIELD_GET(ADXL345_X_EN, regval >> 4) > 0) + act_tap_dir = IIO_MOD_X; + } + if (regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &int_stat)) return IRQ_NONE; @@ -1248,6 +1420,13 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, return -ENODEV; st->fifo_delay = fifo_delay_default; + /* + * If the feature is enabled, scan all axis for activity and or + * inactivity, and set activity and inactivity to the same ac / dc + * setup. + */ + st->act_axis_ctrl = ADXL345_REG_ACT_AXIS_MSK; + /* Init with reasonable values */ tap_threshold = 48; /* 48 [0x30] -> ~3g */ st->tap_duration_us = 16; /* 16 [0x10] -> .010 */ @@ -1273,6 +1452,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = adxl345_set_range(st, ADXL345_16G_RANGE); + if (ret) + return ret; + /* Reset interrupts at start up */ ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); if (ret) From patchwork Thu Feb 20 10:42:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983703 Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6ED551F428F; Thu, 20 Feb 2025 10:42:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048175; cv=none; b=HXiG+JPOPNJZ4sHPNHgInzRyvJrQ7Uhg8sNgaUCcjDUvCKCcvDJBEZ3DeZjKvKyKTq3QfF+dAgr5oA8Hro6734qCAVoVVqLfbEcDHKFQtRy87gz5laeny/AZc2jIw6viT3xPjQnH+MdS70XCjVLNZVky4JWHVi7NzqDwLKX5eqk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048175; c=relaxed/simple; bh=xvyhb3hgiV1rOvFtBrj2iSKtA/DZrOVcxHIESnw0vCU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ckhp9dkOWUgsVlf0D1PlYh2tyjtiXxR4FEOV0BNm+3Gh6LP3qeut9xxuNja/9Co5rDZt5VF/C7AsC3WRB71RQ3TGN5XDiosbNHKueabpnYYVXbStK/2vKI2+qvMxfvkSB16bGb3C3nEpv2//Fj9GptgDhmwHTswqXl9cBnrHKr0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=S0fgLmdu; arc=none smtp.client-ip=209.85.218.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="S0fgLmdu" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-ab7f9f57192so10752466b.3; Thu, 20 Feb 2025 02:42:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048172; x=1740652972; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vrAbvaoVsJFBJDRNcyUkhf7FE4bWAv22MmmOmYXI+24=; b=S0fgLmdumG1lK5VLd3bCPe70akmKNsvTImHvqx0lnpltFVH7lyO4HvaAsDo5JVxyRi aYd/+GWXVtz3yxKQIYoAzkpFN1ANxi9Tz89bSf3l2FXr9ZBL20mbe60ksH1xFj1roaXS bc0ShgKN1NwpNN4tHvWIvhnjoImvD48LxRMH+PlGBtembpjrfEjuZIRm6PtDc22s1xDD gllIS1IvTlMXgqblCydeymtxCLbX6quji4JQrBGvwt3Vv6WpH8+OzFDRkRAvx02YCsRh iKWdl6ZG1qgM0XDlLWsfSEl+BpstAPaTj7g2vGCQOkSib1cmy8hWlgc99hdHkfCkM0vp T9UQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048172; x=1740652972; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vrAbvaoVsJFBJDRNcyUkhf7FE4bWAv22MmmOmYXI+24=; b=QsMdgdfMd8RN6qNhBIUiQtzzGgbRqjhXGCzxDCvrH4lgI0w8ya1S/v/kMirOb5q6J5 nQJJM1PmkTsXJKyzruyoZHVMBU3MWkpG3ZWbF/iUYE8e+KjK2Ug51HzMTZlXLGcLHSXF c/shIJWNG+nXl8QJyNfudgUJ6patiJfhih8X3NpLFGM6x7AKz80A6Vb8ql/B8NjHWhTi sGXV7xkfFA53sgD7p8aCc+R92yPrSLJFSplSQsj1Xs5yvDCJGoMUzTsMG88DJ5pakpOJ sxce37OBgqtXyMcsONI3W7rvh6XSthgK+NJkikXeMMPjNi893iN1LykAc2LamvmsaHrv msPw== X-Forwarded-Encrypted: i=1; AJvYcCVAIhPjenrjXeHnRg+R6k3t7wnUOfqhsxlf5ZLS6Q80d16vGxsHEDJUUm+v0rhwdu0gtA0cniHfXv/9tV0=@vger.kernel.org X-Gm-Message-State: AOJu0YxE1n+Z7CXk2X+LsERu1X7hKboKfXn8zyijvpXAq/Br272yNNAI k+dq9i8xujB13JpyezQH9vOaDMMzIkVC2PsccSMjwNF77R0PpHAqnQqLaxdJ X-Gm-Gg: ASbGncuklSdl1405MqWunEIl8BK6K5L7w30+vFvj4jjpbKsY3kOcsYBRBtmol7El6Y4 jRU9XTy13zyoN0/GMQBxaoIPGFwnjh1gBoNCXhnMkrNDu+Gzr74dO4/0uTkThxpnfqT0tLH6aF8 8l5O7CaAmmqFeMDPb7QENg224SuxB2qbiTK5jsro6fRsxnaPOEkowaeHOHCgKT7CZASDKHHeIj6 /op/BUVXCj208WrZXkRilUeOtzyYYO4BIwkGybuKT3QjxodSdOhv8vT9xMAclN0bpwAEw5l7F55 CxN2PnD+GfeguIHDsDgviZ33lEC1VXC9yXwQEtrfbWsiLYMKMSzmXU4gAXTrW7dOgoHbnQ== X-Google-Smtp-Source: AGHT+IGcKQkGABAIpldGYILpIGiAuPBvrOMtnYwQYYfg1Z6+0BJ30vvbzay7EjyveqcJYj/doWJP+A== X-Received: by 2002:a17:907:d8b:b0:ab6:58e4:4fec with SMTP id a640c23a62f3a-abb7093370fmr829379966b.3.1740048171473; Thu, 20 Feb 2025 02:42:51 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:51 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 13/15] iio: accel: adxl345: add inactivity feature Date: Thu, 20 Feb 2025 10:42:32 +0000 Message-Id: <20250220104234.40958-14-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the inactivity feature of the sensor. When activity and inactivity are enabled, a link bit will be set linking activity and inactivity handling. Additionally, the auto-sleep mode will be enabled. Due to the link bit the sensor is going to auto-sleep when inactivity was detected. Inactivity detection needs a threshold to be configured, and a time after which it will go into inactivity state if measurements under threshold. When a ODR is configured this time for inactivity is adjusted with a corresponding reasonable default value, in order to have higher frequencies and lower inactivity times, and lower sample frequency but give more time until inactivity. Both with reasonable upper and lower boundaries, since many of the sensor's features (e.g. auto-sleep) will need to operate beween 12.5 Hz and 400 Hz. This is a default setting when actively changing sample frequency, explicitly setting the time until inactivity will overwrite the default. Similarly, setting the g-range will provide a default value for the activity and inactivity thresholds. Both are implicit defaults, but equally can be overwritten to be explicitly configured. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 140 +++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 5 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index f1895925a80b..40ec06bf2090 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,6 +36,8 @@ #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) #define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) #define ADXL345_REG_ACT_AXIS_MSK GENMASK(6, 4) +#define ADXL345_REG_INACT_AXIS_MSK GENMASK(2, 0) +#define ADXL345_POWER_CTL_INACT_MSK (ADXL345_POWER_CTL_AUTO_SLEEP | ADXL345_POWER_CTL_LINK) enum adxl345_axis { ADXL345_Z_EN = BIT(0), @@ -71,18 +73,22 @@ static const unsigned int adxl345_tap_time_reg[] = { /* activity/inactivity */ enum adxl345_activity_type { ADXL345_ACTIVITY, + ADXL345_INACTIVITY, }; static const unsigned int adxl345_act_int_reg[] = { [ADXL345_ACTIVITY] = ADXL345_INT_ACTIVITY, + [ADXL345_INACTIVITY] = ADXL345_INT_INACTIVITY, }; static const unsigned int adxl345_act_thresh_reg[] = { [ADXL345_ACTIVITY] = ADXL345_REG_THRESH_ACT, + [ADXL345_INACTIVITY] = ADXL345_REG_THRESH_INACT, }; static const unsigned int adxl345_act_axis_msk[] = { [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, + [ADXL345_INACTIVITY] = ADXL345_REG_INACT_AXIS_MSK, }; enum adxl345_odr { @@ -167,6 +173,7 @@ struct adxl345_state { u8 fifo_mode; u32 act_axis_ctrl; + u32 inact_axis_ctrl; u32 tap_axis_ctrl; u32 tap_duration_us; u32 tap_latent_us; @@ -184,6 +191,14 @@ static struct iio_event_spec adxl345_events[] = { .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_VALUE), }, + { + /* inactivity */ + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD), + }, { .type = IIO_EV_TYPE_GESTURE, .dir = IIO_EV_DIR_SINGLETAP, @@ -307,6 +322,17 @@ static int adxl345_write_act_axis(struct adxl345_state *st, st->act_axis_ctrl); if (ret) return ret; + + } else { + st->inact_axis_ctrl = en + ? st->inact_axis_ctrl | ADXL345_REG_INACT_AXIS_MSK + : st->inact_axis_ctrl & ~ADXL345_REG_INACT_AXIS_MSK; + + ret = regmap_update_bits(st->regmap, ADXL345_REG_ACT_INACT_CTRL, + adxl345_act_axis_msk[type], + st->inact_axis_ctrl); + if (ret) + return ret; } return 0; } @@ -330,6 +356,7 @@ static int adxl345_set_act_inact_en(struct adxl345_state *st, enum adxl345_activity_type type, bool cmd_en) { bool axis_en, en = false; + unsigned int inact_time_s; unsigned int threshold; int ret; @@ -344,11 +371,71 @@ static int adxl345_set_act_inact_en(struct adxl345_state *st, if (type == ADXL345_ACTIVITY) { axis_en = FIELD_GET(ADXL345_REG_ACT_AXIS_MSK, st->act_axis_ctrl) > 0; en = axis_en && threshold > 0; + } else { + ret = regmap_read(st->regmap, ADXL345_REG_TIME_INACT, &inact_time_s); + if (ret) + return ret; + + axis_en = FIELD_GET(ADXL345_REG_INACT_AXIS_MSK, st->inact_axis_ctrl) > 0; + en = axis_en && threshold > 0 && inact_time_s > 0; } - return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, - adxl345_act_int_reg[type], - en ? adxl345_act_int_reg[type] : 0); + ret = regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + adxl345_act_int_reg[type], + en ? adxl345_act_int_reg[type] : 0); + if (ret) + return ret; + + return regmap_update_bits(st->regmap, ADXL345_REG_POWER_CTL, + ADXL345_POWER_CTL_INACT_MSK, + en ? (ADXL345_POWER_CTL_AUTO_SLEEP | ADXL345_POWER_CTL_LINK) + : 0); +} + +/** + * adxl345_set_inact_time_s - Configure inactivity time explicitly or by ODR. + * @st: The sensor state instance. + * @val_s: A desired time value, between 0 and 255. + * + * If val_s is 0, a default inactivity time will be computed. It should take + * power consumption into consideration. Thus it shall be shorter for higher + * frequencies and longer for lower frequencies. Hence, frequencies above 255 Hz + * shall default to 10 s and frequencies below 10 Hz shall result in 255 s to + * detect inactivity. + * + * The approach simply subtracts the pre-decimal figure of the configured + * sample frequency from 255 s to compute inactivity time [s]. Sub-Hz are thus + * ignored in this estimation. The recommended ODRs for various features + * (activity/inactivity, sleep modes, free fall, etc.) lie between 12.5 Hz and + * 400 Hz, thus higher or lower frequencies will result in the boundary + * defaults or need to be explicitly specified via val_s. + * + * Return: 0 or error value. + */ +static int adxl345_set_inact_time_s(struct adxl345_state *st, u32 val_s) +{ + unsigned int max_boundary = 255; + unsigned int min_boundary = 10; + unsigned int val = min(val_s, max_boundary); + enum adxl345_odr odr; + unsigned int regval; + int ret; + + if (val == 0) { + ret = regmap_read(st->regmap, ADXL345_REG_BW_RATE, ®val); + if (ret) + return ret; + odr = FIELD_GET(ADXL345_BW_RATE_MSK, regval); + + val = (adxl345_odr_tbl[odr][0] > max_boundary) + ? min_boundary : max_boundary - adxl345_odr_tbl[odr][0]; + } + + ret = regmap_write(st->regmap, ADXL345_REG_TIME_INACT, val); + if (ret) + return ret; + + return 0; } /* tap */ @@ -785,6 +872,11 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, if (ret) return ret; return int_en; + case IIO_EV_DIR_FALLING: + ret = adxl345_is_act_inact_en(st, ADXL345_INACTIVITY, &int_en); + if (ret) + return ret; + return int_en; default: return -EINVAL; } @@ -842,6 +934,8 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, switch (dir) { case IIO_EV_DIR_RISING: return adxl345_set_act_inact_en(st, ADXL345_ACTIVITY, state); + case IIO_EV_DIR_FALLING: + return adxl345_set_act_inact_en(st, ADXL345_INACTIVITY, state); default: return -EINVAL; } @@ -884,9 +978,10 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, int *val, int *val2) { struct adxl345_state *st = iio_priv(indio_dev); - unsigned int tap_threshold; + unsigned int act_threshold, inact_threshold; + unsigned int inact_time_s; unsigned int ff_threshold; - unsigned int act_threshold; + unsigned int tap_threshold; int ret; switch (type) { @@ -903,9 +998,24 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, *val = act_threshold; return IIO_VAL_INT; + case IIO_EV_DIR_FALLING: + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_INACTIVITY], + &inact_threshold); + if (ret) + return ret; + + *val = inact_threshold; + return IIO_VAL_INT; default: return -EINVAL; } + case IIO_EV_INFO_PERIOD: + ret = regmap_read(st->regmap, ADXL345_REG_TIME_INACT, &inact_time_s); + if (ret) + return ret; + *val = inact_time_s; + return IIO_VAL_INT; default: return -EINVAL; } @@ -981,10 +1091,18 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, adxl345_act_thresh_reg[ADXL345_ACTIVITY], val); break; + case IIO_EV_DIR_FALLING: + ret = regmap_write(st->regmap, + adxl345_act_thresh_reg[ADXL345_INACTIVITY], + val); + break; default: ret = -EINVAL; } break; + case IIO_EV_INFO_PERIOD: + ret = adxl345_set_inact_time_s(st, val); + break; default: ret = -EINVAL; } @@ -1282,6 +1400,17 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_INACTIVITY, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + ts); + if (ret) + return ret; + } + if (FIELD_GET(ADXL345_INT_FREE_FALL, int_stat)) { ret = iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, @@ -1426,6 +1555,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, * setup. */ st->act_axis_ctrl = ADXL345_REG_ACT_AXIS_MSK; + st->inact_axis_ctrl = ADXL345_REG_INACT_AXIS_MSK; /* Init with reasonable values */ tap_threshold = 48; /* 48 [0x30] -> ~3g */ From patchwork Thu Feb 20 10:42:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983704 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 707DA1F55FB; Thu, 20 Feb 2025 10:42:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048176; cv=none; b=r921u0YM+yyryDMR9YT/OF65lvjPuGMUl0ogdGChnF1CtnBTqDsvXVckOMQq+mUp+fIPpvyoglWBowhRoaxF07mKTA0USBd6QsnnJB2TDdj3Vy7ApzFJE86wvF7BNLgw/ZwqbKAFumuYWLRfrFkTbdxWezmii/tfTBkR285q+Zg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048176; c=relaxed/simple; bh=7Ev8SZr6ybrSLsNeldDCLMOD3Fq5Vu3fzAVC+a85s+M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RdBHsAPzxviFHS8TP3PTn4UrdD1EgbVfSsiffA37Ou/kS0mKHD7Uv7eJ5g5L9gQ+mwhIb4gtMgHvhO+aZ+zZ5VMzFo4qK2MNfpIOMq3+J8Ceq/y7aKMN6T5AVwGhl3v1tJUcsJcW90ou0ZTupnhtrTDir8z+IjM9w9I+SNvywgk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UxQvny18; arc=none smtp.client-ip=209.85.208.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UxQvny18" Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-5e064eff5daso112570a12.3; Thu, 20 Feb 2025 02:42:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048173; x=1740652973; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PJU2SiuSho+uT/qo2rXEKUSgHCtdBYekR0Np/HxOV+Q=; b=UxQvny18Ayo9PBa07YWkvkY+w3LM3JSjGwucbQ098aI0q2yi3sTjZFeXioRb0bUts6 GzhKf463As3F+xjMTg/WAX8l/iCpC18/Lb27sV/bDJSg9WlMYMRaMTF/bKkr9g+zO4yI tEvnNeB8zvN74poHC5AHtYHU2oz44ozJ0Io/pyiI7h8LQwislw3ljOH/8lCAGsRXsYAK AZ27bM0z8W79KlyTsq5Ciwc2ivQstlgoIp30hbdG1d3u5Hje0f2w9ScQeapXd8D3ZN41 IS+vplQr8Zv+JTiHnnRtm+YO8Qi8dXOD9M6ooB48V+ACznuebfNW7r48tlNYo8ibU2Ah MYdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048173; x=1740652973; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PJU2SiuSho+uT/qo2rXEKUSgHCtdBYekR0Np/HxOV+Q=; b=dotriiBYMQrBLrsHTa2xzZbotHr41gi2L6BueiLYa7vynJjHyLOP58U/YTpUDoJxY6 mZAFjJNhIeOdLvy4iBw0zVHomleV1lNdBzD10mHHAA0z28J0LmXYpHA22HIh8XEq45bc 62wxgwqEdsEBuLKz3Q6OtIh4Fmovw3Z37X3H0S00HOCbuW4PLVPLQvnXd3TSBSWkGsIe OR+qzhQNFTdx7m8yyvexlaiXOuyxHWT0gbElQHGDtOrNdUCeOd69mkD3M/1bxQx585g/ MJVDtdwUrjb4+e+dWj454G3DAVuRXvbKtB6cA1qWRdKCN4Yq6OEswDyeVI1piQIR7ejF bdmQ== X-Forwarded-Encrypted: i=1; AJvYcCUczJplowubgwQMKbGHa4AWzz5YfVckZ48KyEQBf8pmTDqwoFrwIj3gYSXBy1RQlVfWie537jzyJ2/BZTg=@vger.kernel.org X-Gm-Message-State: AOJu0YzSXFfHP7jHSc3CQGDDCmy4sK4RBzDFUSxpMRAqPnBWyD+lFfRv SVm1BJel1TRqBHAoqbUV/MGhWEc3KBZK2KO1vpf3tQxUE2qgPvHC X-Gm-Gg: ASbGncuT31c+eqPVnehU7ZOfKJ03/kqc9PQhRDbQPur2dWKWcmycipdgancx7+trc+U L4cZALgDuZohISA52I4xvUdd/sMGyN+PWepxcUqkdlb4bH5FUzIqcQa7YYBUgxyCUwmrsw5OhW9 FgaFqxMRFn0DtZH1jWhdbL8gLW+CYwQWEdaSEVbpytnHvfbZovMypISyZO8wgSwhzzg8sDErFN0 TePVkSJvN3jitZn5SqIAhm0rbxfucmIOtacw2kg3NVoKTrlY8fSmaVVEYmunOy7I9gNnk/kZyQg lBLNCWxvPbsqAuVRHeLzLbJc1pIP9LO3jbnIs9r2Ohk02Q/huPEalZrGdvAtl5ucDYkrAw== X-Google-Smtp-Source: AGHT+IF0YGG3Ig1iKT77VWOWS2d17YtlmZyMqVnk5gLQkPBg8yJIlQhCVW4NayO0FRVXdeyoB8en5Q== X-Received: by 2002:a17:906:6a0c:b0:aba:6055:9ed1 with SMTP id a640c23a62f3a-abb70ab8b8amr843952966b.6.1740048172407; Thu, 20 Feb 2025 02:42:52 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:52 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 14/15] iio: accel: adxl345: add coupling detection for activity/inactivity Date: Thu, 20 Feb 2025 10:42:33 +0000 Message-Id: <20250220104234.40958-15-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add coupling activity/inactivity detection by the AC/DC bit. This is an addititional enhancement for the detection of activity states and completes the activity / inactivity feature of the ADXL345. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 154 +++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 40ec06bf2090..7ace835e7824 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,7 +36,9 @@ #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) #define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) #define ADXL345_REG_ACT_AXIS_MSK GENMASK(6, 4) +#define ADXL345_REG_ACT_ACDC_MSK BIT(7) #define ADXL345_REG_INACT_AXIS_MSK GENMASK(2, 0) +#define ADXL345_REG_INACT_ACDC_MSK BIT(3) #define ADXL345_POWER_CTL_INACT_MSK (ADXL345_POWER_CTL_AUTO_SLEEP | ADXL345_POWER_CTL_LINK) enum adxl345_axis { @@ -86,6 +88,11 @@ static const unsigned int adxl345_act_thresh_reg[] = { [ADXL345_INACTIVITY] = ADXL345_REG_THRESH_INACT, }; +static const unsigned int adxl345_act_acdc_msk[] = { + [ADXL345_ACTIVITY] = ADXL345_REG_ACT_ACDC_MSK, + [ADXL345_INACTIVITY] = ADXL345_REG_INACT_ACDC_MSK, +}; + static const unsigned int adxl345_act_axis_msk[] = { [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, [ADXL345_INACTIVITY] = ADXL345_REG_INACT_AXIS_MSK, @@ -221,6 +228,18 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_PERIOD), }, + { + /* activity, activity - ac bit */ + .type = IIO_EV_TYPE_MAG_REFERENCED, + .dir = IIO_EV_DIR_RISING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE), + }, + { + /* activity, inactivity - ac bit */ + .type = IIO_EV_TYPE_MAG_REFERENCED, + .dir = IIO_EV_DIR_FALLING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE), + }, }; #define ADXL345_CHANNEL(index, reg, axis) { \ @@ -337,6 +356,69 @@ static int adxl345_write_act_axis(struct adxl345_state *st, return 0; } +static int adxl345_is_act_inact_ac(struct adxl345_state *st, + enum adxl345_activity_type type, bool *ac) +{ + unsigned int regval; + int ret; + + ret = regmap_read(st->regmap, ADXL345_REG_ACT_INACT_CTRL, ®val); + if (ret) + return ret; + + if (type == ADXL345_ACTIVITY) + *ac = (FIELD_GET(ADXL345_REG_ACT_ACDC_MSK, regval) > 0) ? true : false; + else + *ac = (FIELD_GET(ADXL345_REG_INACT_ACDC_MSK, regval) > 0) ? true : false; + + return 0; +} + +static int adxl345_set_act_inact_ac(struct adxl345_state *st, + enum adxl345_activity_type type, bool ac) +{ + unsigned int act_inact_ac = ac ? 0xff : 0x00; + + /* + * A setting of 0 selects dc-coupled operation, and a setting of 1 + * enables ac-coupled operation. In dc-coupled operation, the current + * acceleration magnitude is compared directly with + * ADXL345_REG_THRESH_ACT and ADXL345_REG_THRESH_INACT to determine + * whether activity or inactivity is detected. + * + * In ac-coupled operation for activity detection, the acceleration + * value at the start of activity detection is taken as a reference + * value. New samples of acceleration are then compared to this + * reference value, and if the magnitude of the difference exceeds the + * ADXL345_REG_THRESH_ACT value, the device triggers an activity + * interrupt. + * + * Similarly, in ac-coupled operation for inactivity detection, a + * reference value is used for comparison and is updated whenever the + * device exceeds the inactivity threshold. After the reference value + * is selected, the device compares the magnitude of the difference + * between the reference value and the current acceleration with + * ADXL345_REG_THRESH_INACT. If the difference is less than the value in + * ADXL345_REG_THRESH_INACT for the time in ADXL345_REG_TIME_INACT, the + * device is considered inactive and the inactivity interrupt is + * triggered. [quoted from p. 24, ADXL345 datasheet Rev. G] + * + * In a conclusion, the first acceleration snapshot sample which hit the + * threshold in a particular direction is always taken as acceleration + * reference value to that direction. Since for the hardware activity + * and inactivity depend on the x/y/z axis, so do ac and dc coupling. + * Note, this sw driver always enables or disables all three x/y/z axis + * for detection via act_axis_ctrl and inact_axis_ctrl, respectively. + * Where in dc-coupling samples are compared against the thresholds, in + * ac-coupling measurement difference to the first acceleration + * reference value are compared against the threshold. So, ac-coupling + * allows for a bit more dynamic compensation depending on the initial + * sample. + */ + return regmap_update_bits(st->regmap, ADXL345_REG_ACT_INACT_CTRL, + adxl345_act_acdc_msk[type], act_inact_ac); +} + static int adxl345_is_act_inact_en(struct adxl345_state *st, enum adxl345_activity_type type, bool *en) { @@ -695,6 +777,11 @@ static int adxl345_set_odr(struct adxl345_state *st, enum adxl345_odr odr) if (ret) return ret; + /* update inactivity time by ODR */ + ret = adxl345_set_inact_time_s(st, 0); + if (ret) + return ret; + return 0; } @@ -718,14 +805,54 @@ static int adxl345_find_range(struct adxl345_state *st, int val, int val2, static int adxl345_set_range(struct adxl345_state *st, enum adxl345_range range) { + unsigned int act_threshold, inact_threshold; + unsigned int range_old; + unsigned int regval; int ret; + ret = regmap_read(st->regmap, ADXL345_REG_DATA_FORMAT, ®val); + if (ret) + return ret; + range_old = FIELD_GET(ADXL345_DATA_FORMAT_RANGE, regval); + + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_ACTIVITY], + &act_threshold); + if (ret) + return ret; + + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_INACTIVITY], + &inact_threshold); + if (ret) + return ret; + ret = regmap_update_bits(st->regmap, ADXL345_REG_DATA_FORMAT, ADXL345_DATA_FORMAT_RANGE, FIELD_PREP(ADXL345_DATA_FORMAT_RANGE, range)); if (ret) return ret; + act_threshold = act_threshold + * adxl345_range_factor_tbl[range_old] + / adxl345_range_factor_tbl[range]; + act_threshold = min(255, max(1, inact_threshold)); + + inact_threshold = inact_threshold + * adxl345_range_factor_tbl[range_old] + / adxl345_range_factor_tbl[range]; + inact_threshold = min(255, max(1, inact_threshold)); + + ret = regmap_write(st->regmap, adxl345_act_thresh_reg[ADXL345_ACTIVITY], + act_threshold); + if (ret) + return ret; + + ret = regmap_write(st->regmap, adxl345_act_thresh_reg[ADXL345_INACTIVITY], + inact_threshold); + if (ret) + return ret; + return 0; } @@ -862,6 +989,8 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, struct adxl345_state *st = iio_priv(indio_dev); bool int_en; bool axis_en; + bool act_ac; + bool inact_ac; int ret = -EFAULT; switch (type) { @@ -915,6 +1044,21 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, if (ret) return ret; return int_en; + case IIO_EV_TYPE_MAG_REFERENCED: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = adxl345_is_act_inact_ac(st, ADXL345_ACTIVITY, &act_ac); + if (ret) + return ret; + return act_ac; + case IIO_EV_DIR_FALLING: + ret = adxl345_is_act_inact_ac(st, ADXL345_INACTIVITY, &inact_ac); + if (ret) + return ret; + return inact_ac; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -965,6 +1109,16 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, } case IIO_EV_TYPE_MAG: return adxl345_set_ff_en(st, state); + case IIO_EV_TYPE_MAG_REFERENCED: + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl345_set_act_inact_ac(st, ADXL345_ACTIVITY, state); + case IIO_EV_DIR_FALLING: + return adxl345_set_act_inact_ac(st, ADXL345_INACTIVITY, state); + default: + return -EINVAL; + } + default: return -EINVAL; } From patchwork Thu Feb 20 10:42:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13983705 Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0E171F63C1; Thu, 20 Feb 2025 10:42:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048178; cv=none; b=AyV9JytsaLn0rZ7wiV/O/Zysxe4CpvOf/+nz9/HfvmwBcOsAoOKISyvty6PJJ2FjaNV7yhG9i3R5RocRAypNPtnYQz9wcevLwOJ7EkJ+0gc7CBAc8gbCLwL3czDLw7M4UOhAdcvVdaVI/TXTX9w4MNuglkM/N/p1Z40mGdHhVu8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740048178; c=relaxed/simple; bh=Loxnj/CQlpBGOR4H2Ng5ldAvPnTgcWb9mwEEms3x6g0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=PtHOvfiLviWySRa0Za8uhDinNpIPOtOKv16OneV7h5YP1S/9+I8o5/iXXFTu2TDQa4uNY0Bo6jaT5qMRfD9urv7A18rt7US2KIJQLyz/ZU462wc1e728TUvRPiW3ABFIrHPkVbN8mX6wk3787q+gkSQgn0L+CvzT3/NWuffKA/4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=dKotLB4S; arc=none smtp.client-ip=209.85.218.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dKotLB4S" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-ab7f9f57192so10753066b.3; Thu, 20 Feb 2025 02:42:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740048174; x=1740652974; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZgPYiJZRPy7uKWRXSgBlvHd8ppPVLG9B0HsPViuzHKc=; b=dKotLB4SEptCsZdIqy3qAkOhzQOpczFPdRUatzJBDJ8ZpzRvwLGY0Ga/n4RlioFTrg 8yyB1zNirEPwiwW60QJMmV/Ky1i3yhB8Y/mKLavm7ujoeHPiKVpuZQgjENnnsymrhLus nT+suJy3Asbc1iWQgO9xgwrAey6MAzGWVOEjU4nwb/ezx05n7jHB3JLdQcKTMqGR0D/z B9NDBLsnU9w+wuAAgyKvt0WnS9w+Qr25TIc3W82NZG5nYRglzaE1I6s+WP3aFpL6DmNU 6AezdAqtOSIAl+Ka9vgkxM8Hqq6+ZrQEgQ1en6qDHXyBCZuTVX6BsrjqmOIdHNtx3Qzj mmPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740048174; x=1740652974; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZgPYiJZRPy7uKWRXSgBlvHd8ppPVLG9B0HsPViuzHKc=; b=mvPBhP6d0o3BN2cU14UtRayi6JAtXxM/nQ4yknvYq7j3KL9dSA0rECXng9xo9uYPmR HR8fcNa8JkqShswY167Tu+cI6Roww3v+sxI5oYftAo/pQ+CtPkGx5wlj4mzpIHu8ZKjX regqxoJvMMnhoHW+r7nV2jUcHJxxnddfUVddQIzZWyzXnriLRq3sTITXlkxWqBWx2VyD zLs4vZaGV0LnKhZ5myQFMKav6QS69YXJOfOSJj9Ma5C0lnF22H8qAdnrcZZm5YrX7hjK 8veaI9NosZtPCHNQxYKuB8r0s78EAl3YmME8L/M13QcIwITnaWpv+MRXd5L9lvM/d7i2 OC6g== X-Forwarded-Encrypted: i=1; AJvYcCXFGpT/tT212KmmzWqEEAc+5nAAtvOPKgc3vFV7mFEEUi0LmpAUX/NILYdPf6MAJN39ZJoA5fWUdlpsReY=@vger.kernel.org X-Gm-Message-State: AOJu0YzDgUzwBHi4NIHINh6oOIXvMfYtmKbjtEeeYuj9KoQK1lxgFHYM BuWJazwjbIKShyNzagSJ9tl9/WjW/MQdLFKzT2AQgRumeDUciAez X-Gm-Gg: ASbGncujJPGJodfVHY+xwYBx4bd1wsnPlrBnMGH2wT9D7iPkWi3dxtb6Lh6vclf2Ccb u8shKAEmkbB2UvEE/oGNnjwiH7cJ0C0XiPcd7h1tqr2+90dDccyxScUREbWrFCENQDPsMvwAsLZ IIZUb0Lh96GWwgBSuE2Ylsr8h1+UaibvHZM3DV1nKnrXFo3Lp33DnyVkXIAAo7S627wrWPheuon xNtVSY+2eaYBHSHtb/40xuCoVy203FNofhueVexoU+cSe26fbUE8Fq32h3B6DuCHeQCtZM8O2qZ cAoM2CkwpTmIPx+VjWjmc2BKEousfvxW/+jy/zeOKuK1l4V4lCHOZa80E4kesFoCVp1uYQ== X-Google-Smtp-Source: AGHT+IFpvGROlAqdBqb0U2G46+vmGON9raxtCREQiNWAgKgiGCmB4AFjKg6tbJd1Mpldofdt02ZE7g== X-Received: by 2002:a17:907:d27:b0:ab6:d3b6:d825 with SMTP id a640c23a62f3a-abb70acbb8cmr817116666b.6.1740048173458; Thu, 20 Feb 2025 02:42:53 -0800 (PST) Received: from 0f997e1ceb21.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-abbdfcaed55sm246474866b.137.2025.02.20.02.42.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 02:42:53 -0800 (PST) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v3 15/15] docs: iio: add documentation for adxl345 driver Date: Thu, 20 Feb 2025 10:42:34 +0000 Message-Id: <20250220104234.40958-16-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250220104234.40958-1-l.rubusch@gmail.com> References: <20250220104234.40958-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The documentation describes the ADXL345 driver, IIO interface, interface usage and configuration. Signed-off-by: Lothar Rubusch --- Documentation/iio/adxl345.rst | 406 ++++++++++++++++++++++++++++++++++ 1 file changed, 406 insertions(+) create mode 100644 Documentation/iio/adxl345.rst diff --git a/Documentation/iio/adxl345.rst b/Documentation/iio/adxl345.rst new file mode 100644 index 000000000000..b77c97ef52e5 --- /dev/null +++ b/Documentation/iio/adxl345.rst @@ -0,0 +1,406 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=============== +ADXL345 driver +=============== + +This driver supports Analog Device's ADXL345/375 on SPI/I2C bus. + +1. Supported devices +==================== + +* `ADXL345 `_ +* `ADXL375 `_ + +The ADXL345 is a generic purpose low power, 3-axis accelerometer with selectable +measurement ranges. The ADXL345 supports the ±2 g, ±4 g, ±8 g, and ±16 g ranges. + +2. Device attributes +==================== + +Accelerometer measurements are always provided. + +Each IIO device, has a device folder under ``/sys/bus/iio/devices/iio:deviceX``, +where X is the IIO index of the device. Under these folders reside a set of +device files, depending on the characteristics and features of the hardware +device in questions. These files are consistently generalized and documented in +the IIO ABI documentation. + +The following table shows the ADXL345 related device files, found in the +specific device folder path ``/sys/bus/iio/devices/iio:deviceX``. + ++-------------------------------------------+----------------------------------------------------------+ +| 3-Axis Accelerometer related device files | Description | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_sampling_frequency | Currently selected sample rate. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_sampling_frequency_available | Available sampling frequency configurations. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_scale | Scale/range for the accelerometer channels. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_scale_available | Available scale ranges for the accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_x_calibbias | Calibration offset for the X-axis accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_x_raw | Raw X-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_y_calibbias | y-axis acceleration offset correction | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_y_raw | Raw Y-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_z_calibbias | Calibration offset for the Z-axis accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_z_raw | Raw Z-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ + +Channel processed values +------------------------- + +A channel value can be read from its _raw attribute. The value returned is the +raw value as reported by the devices. To get the processed value of the channel, +apply the following formula: + +.. code-block:: bash + + processed value = (_raw + _offset) * _scale + +Where _offset and _scale are device attributes. If no _offset attribute is +present, simply assume its value is 0. + ++-------------------------------------+---------------------------+ +| Channel type | Measurement unit | ++-------------------------------------+---------------------------+ +| Acceleration on X, Y, and Z axis | Meters per second squared | ++-------------------------------------+---------------------------+ + +Sensor events +------------- + +Particular IIO events will be triggered by the corresponding interrupts. The +sensor driver supports no or one active INT line, where the sensor has two +possible INT IOs. Configure the used INT line in the devicetree. If no INT line +is configured, the sensor falls back to FIFO bypass mode and no events are +possible, only X, Y and Z axis measurements are possible. + +The following table shows the ADXL345 related device files, found in the +specific device folder path ``/sys/bus/iio/devices/iio:deviceX/events``. + ++---------------------------------------------+-----------------------------------------+ +| Event handle | Description | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_doubletap_en | Enable double tap detection on all axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_doubletap_reset_timeout | Double tap window in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_doubletap_tap2_min_delay | Double tap latent in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_singletap_timeout | Single tap duration in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_singletap_value | Single tap threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_falling_en | Enable free fall detection | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_falling_period | Free fall time in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_falling_value | Free fall threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_referenced_falling_en | Set 1 to AC-coupled inactivity, 0 for DC| ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_referenced_rising_en | Set 1 to AC-coupled activity, 0 for DC | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_falling_en | Enable inactivity detection | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_falling_period | Inactivity time in seconds | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_falling_value | Inactivity threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_rising_en | Enable activity detection | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_rising_value | Activity threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_x_gesture_singletap_en | Enable single tap detection on X axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_y_gesture_singletap_en | Enable single tap detection on Y axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_z_gesture_singletap_en | Enable single tap detection on Z axis | ++---------------------------------------------+-----------------------------------------+ + +Find a detailed description of a particular functionality in the sensor +datasheet. + +Setting the ODR explicitly will result in estimated adjusted default values +for the inactivity time detection, where higher frequencies shall default to +longer wait periods, and vice versa. It is also possible to explicetly +configure inactivity wait times, if the defaulting approach does not match +application requirements. Setting 0 here, will fall back to default setting. + +The g range configuration also tries to estimate activity and inactivity +thresholds when switching to another g range. The default range will be +factorized by the relation of old range divided by new range. The value never +becomes 0 and will be at least 1 and at most 255 i.e. 62.5g/LSB according to +the datasheet. Nevertheless activity and inactivity thresholds can be +overwritten by explicit values. + +When activity and inactivity events are both enabled, the driver automatically +will implement its hysteresis solution by setting link bit and autosleep bit. +The link bit serially links the activity and inactivity functions. On the other +side, the autosleep function switches the sensor to sleep mode if the +inactivity function is enabled. This will reduce current consumption to the +sub-12.5Hz rate. + +In dc-coupled operation, the current acceleration magnitude is compared +directly with THRESH_ACT and THRESH_INACT registers to determine whether +activity or inactivity was detected. In ac-coupled operation for activity +detection, the acceleration value at the start of activity detection is taken +as a reference value. New samples are then compared to this reference value. +Note, ac-coupling and dc-coupling are individually set for activity and/or +inactivity detection. Activity and inactivity detection are dependent on the +direction, i.e. the x/y/z axis where this driver generally enables all +directions. Also, the direction settings are particular to activity and +inactivity detection, respectively. + +Single tap detection can be configured according to the datasheet by specifying +threshold and duration. If only the single tap is in use, the single tap +interrupt is triggered when the acceleration goes above threshold (i.e. DUR +start) and below the threshold, as long as duration is not exceeded. If single +tap and double tap are in use, the single tap is triggered when the doulbe tap +event has been either validated or invalidated. + +For double tap configure additionally window and latency in [us]. Latency +starts counting when the single tap goes below threshold and is a waiting +period, any spikes here are ignored for double tap detection. After latency, +the window starts. Any rise above threshold, with a consequent fall below +threshold within window time, rises a double tap signal when going below +threshold. + +A double tap event can be invalidated in three ways: If the suppress bit is set, +any acceleration spike above the threshold already during the latency time +invalidates the double tap detection immediately, i.e. during latence must not +occur spikes for double tap detection with suppress bit set. +A double tap event is invalidated if acceleration lies above the threshold at +the start of the window time for the double tap detection. +Additionally a double tap event can be invalidated if an acceleration exceeds +the time limit for taps, set by duration register, since also for the double +tap the same value for duration counts, i.e. when rising above threshold the +fall below threshold has to be within duration time. Note, the suppress bit is +generally set when double tap is enabled. + +A free fall event will be detected if the signal goes below the configured +threshold, for the configured time [us]. + +Note, that activity/inactivy, as also freefall is recommended for 12.5 Hz ODR +up to 400 Hz. + +Usage examples +-------------- + +Show device name: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat name + adxl345 + +Show accelerometer channels value: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_raw + -1 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_y_raw + 2 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_z_raw + -253 + +Set calibration offset for accelerometer channels: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 0 + + root:/sys/bus/iio/devices/iio:device0> echo 50 > in_accel_x_calibbias + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 50 + +Given the 13-bit full resolution, the available ranges are calculated by the +following forumla: + +.. code-block:: bash + + (g * 2 * 9.80665) / (2^(resolution) - 1) * 100; for g := 2|4|8|16 + +Scale range configuration: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale + 0.478899 + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale_available + 0.478899 0.957798 1.915595 3.831190 + + root:/sys/bus/iio/devices/iio:device0> echo 1.915595 > ./in_accel_scale + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale + 1.915595 + +Set output data rate (ODR): + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_sampling_frequency + 200.000000 + + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_sampling_frequency_available + 0.097000 0.195000 0.390000 0.781000 1.562000 3.125000 6.250000 12.500000 25.000000 50.000000 100.000000 200.000000 400.000000 800.000000 1600.000000 3200.000000 + + root:/sys/bus/iio/devices/iio:device0> echo 1.562000 > ./in_accel_sampling_frequency + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_sampling_frequency + 1.562000 + +Configure one or several events: + +.. code-block:: bash + + root:> cd /sys/bus/iio/devices/iio:device0 + + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./buffer0/in_accel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./buffer0/in_accel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./buffer0/in_accel_z_en + + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./scan_elements/in_accel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./scan_elements/in_accel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./scan_elements/in_accel_z_en + + root:/sys/bus/iio/devices/iio:device0> echo 14 > ./in_accel_x_calibbias + root:/sys/bus/iio/devices/iio:device0> echo 2 > ./in_accel_y_calibbias + root:/sys/bus/iio/devices/iio:device0> echo -250 > ./in_accel_z_calibbias + + root:/sys/bus/iio/devices/iio:device0> echo 24 > ./buffer0/length + + ## activity, threshold [62.5/LSB] + root:/sys/bus/iio/devices/iio:device0> echo 6 > ./events/in_accel_thresh_rising_value + + ## inactivity, threshold, [62.5/LSB] + root:/sys/bus/iio/devices/iio:device0> echo 4 > ./events/in_accel_thresh_falling_value + + ## inactivity, time [s] + root:/sys/bus/iio/devices/iio:device0> echo 3 > ./events/in_accel_thresh_falling_period + + ## singletap, threshold + root:/sys/bus/iio/devices/iio:device0> echo 35 > ./events/in_accel_gesture_singletap_value + + ## singletap, duration [us] + root:/sys/bus/iio/devices/iio:device0> echo 0.001875 > ./events/in_accel_gesture_singletap_timeout + + ## doubletap, window [us] + root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_reset_timeout + + ## doubletap, latent [us] + root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_tap2_min_delay + + ## freefall, threshold [62.5/LSB] + root:/sys/bus/iio/devices/iio:device0> echo 8 > ./events/in_accel_mag_falling_value + + ## freefall, time [ms] + root:/sys/bus/iio/devices/iio:device0> echo 1.25 > ./events/in_accel_mag_falling_period + + ## activity, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_thresh_rising_en + + ## inactivity, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_thresh_falling_en + + ## freefall, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_mag_falling_en + + ## singletap, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_x_gesture_singletap_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_y_gesture_singletap_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_z_gesture_singletap_en + + ## doubletap, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_gesture_doubletap_en + +Verify incoming events: + +.. code-block:: bash + + root:# iio_event_monitor adxl345 + Found IIO device with name adxl345 with device number 0 + Event: time: 1739063415957073383, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063415963770218, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063416002563061, type: accel(z), channel: 0, evtype: gesture, direction: singletap + Event: time: 1739063426271128739, type: accel(x|y|z), channel: 0, evtype: thresh, direction: falling + Event: time: 1739063436539080713, type: accel(x|y|z), channel: 0, evtype: thresh, direction: falling + Event: time: 1739063438357970381, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446726161586, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446727892670, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446743019768, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446744650696, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446763559386, type: accel(z), channel: 0, evtype: gesture, direction: singletap + Event: time: 1739063448818126480, type: accel(x|y|z), channel: 0, evtype: thresh, direction: falling + ... + +3. Device buffers +================= + +This driver supports IIO buffers. + +All devices support retrieving the raw acceleration and temperature measurements +using buffers. + +Usage examples +-------------- + +Select channels for buffer read: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_accel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_accel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_accel_z_en + +Set the number of samples to be stored in the buffer: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 10 > buffer/length + +Enable buffer readings: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > buffer/enable + +Obtain buffered data: + +.. code-block:: bash + + root:> iio_readdev -b 16 -s 1024 adxl345 | hexdump -d + WARNING: High-speed mode not enabled + 0000000 00003 00012 00013 00005 00010 00011 00005 00011 + 0000010 00013 00004 00012 00011 00003 00012 00014 00007 + 0000020 00011 00013 00004 00013 00014 00003 00012 00013 + 0000030 00004 00012 00013 00005 00011 00011 00005 00012 + 0000040 00014 00005 00012 00014 00004 00010 00012 00004 + 0000050 00013 00011 00003 00011 00012 00005 00011 00013 + 0000060 00003 00012 00012 00003 00012 00012 00004 00012 + 0000070 00012 00003 00013 00013 00003 00013 00012 00005 + 0000080 00012 00013 00003 00011 00012 00005 00012 00013 + 0000090 00003 00013 00011 00005 00013 00014 00003 00012 + 00000a0 00012 00003 00012 00013 00004 00012 00015 00004 + 00000b0 00014 00011 00003 00014 00013 00004 00012 00011 + 00000c0 00004 00012 00013 00004 00014 00011 00004 00013 + 00000d0 00012 00002 00014 00012 00005 00012 00013 00005 + 00000e0 00013 00013 00003 00013 00013 00005 00012 00013 + 00000f0 00004 00014 00015 00005 00012 00011 00005 00012 + ... + +See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +data is structured. + +4. IIO Interfacing Tools +======================== + +See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +interfacing tools.