From patchwork Mon Feb 10 11:01:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967680 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 3D42D187859; Mon, 10 Feb 2025 11:01:36 +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=1739185297; cv=none; b=Zvap2rMnJpkjUe44SiB/UY+3BTOlstBmJhFzL3axQgpASuzUSe+bIAk7N7GmJmp0Bgzhx/4FgppLyAyxpQ/cDKHHy5jHZz2GEd/3n2C6gfccQxPnjpcNC0H5rHqizM641qBqTxApdl8LlIhbXZPqTzMU20kRCwfl/u6xKIqpIls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185297; c=relaxed/simple; bh=N5wPUtEL8GafvraaTitozwAcmvfIG4+F6qsLJt/dB1o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TfMwCbKqPwaC+LGD+xLiZ7XXEoYoHNuIMYe6JhwkVeB9t4W4jFwMW8KKbRkzbloNeUWyZOQ2DvZHymivgRi9gK8H8JDE9kH5w8yz5OwjrBjvtTdakt5aTIE6XmCj7Lz+TJ/6pNdwR4W7/RQGQXqqhafbj3iWCJmw3UaMVYVF1E4= 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=WdQt3vr8; 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="WdQt3vr8" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-ab7bbc14101so11813066b.1; Mon, 10 Feb 2025 03:01:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185294; x=1739790094; 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=WdQt3vr8rbgTHxPk6U6VdW2ECdl3OQJLwlc4T+IVFITpwcdnE2Fl24N92oStoDK28z TbU9wUoraJN0BOyC3HkD41P+n1yZr1FEMIinU/DxD7iZty1qHisi3SJhcZUW1dwZ9IEX VRnSaufHqu60JvRJHIXf97nskfj7QTmUFOxxUpIntrGAXWqSfQLX1YEMpo/13VEKluPN olVEzgnuXRTDoCLIGeKYzb04m8IFJt0cYjmNxkeiUuKjQUbMsP/QZIOLb5UCDZ5r8t0T S05bz4fnPuAH6o0x54Fep1dSgG4NZa9Hm3DQ7qjrKA2GJRac8F/MrNZkeA92A0WDwll6 6mBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185294; x=1739790094; 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=JFNdnrmMv+R/OtmTXb0C0c0dGK8MQTCmNubaibjsZOJgLqlYaIZc6wZOT7w7xYjF8E kHRbNQrOs/VsPY+5VKTqF8oj1mZY978xGep8T6gnUQtFObzy8yPuWKttq/ieHxwx/irB Bg6H5sw4Ptb4VqsZUAq8FRzGQwZsRM0TPRC0tlUzDbELoFiXwjCP2qNfpmSPpPUTRaRz 5TMElkNbab0Pmd4OGHEePS+9QDqOS7t3JH1nnbTI7nlxL5/TgicO4WTE0xznoOfn+3zJ XA3O9gGR10PjlDCVIFQfn909BIowgzVnQg2dwYc4O/VJjBYUj7zm8CncQDZ+aXyG+vN0 Qwyg== X-Forwarded-Encrypted: i=1; AJvYcCWirnvXlu3pxPk5X55dcLCRT+vkBoMoR3VBFGOKn3P4i6Ir4zoum6sr7osEHDUsLBmxYYhDIYu2cS7HsHo=@vger.kernel.org X-Gm-Message-State: AOJu0Yzlv6X6qQYltBu7uXpPGEjAlrCKoTvwGBg7zkAkyIThE561Rmtk Zq7HsIz9Ap7c7jhlH830qHlx5sqaiE5Jhkm6yPpn2jl2ENdUKJ86eYAFRA== X-Gm-Gg: ASbGncthr8kOx0nFU2fhsDYsuvzLygdkqjOwyDSFI3Pgk714LFu35RQpPnlSSKQNd/S fn3OSp8tI0zF50NT7GMYVs6R/qwWV63HVWeFc8+i0huPpfVtCk28ChvXlW0L2AYwSaObES7m8gp 3FlG8O21qNlXkv96AxAqgrNeVlYMtXrufmahL+wm+JvkGW8KsVQmxhBwPv+r9jir6/Delv30bky oaLks72DUmslgYZhm7Aa1JIppT+7jSguuW4II6fBlg8vPgcVb382vMmXJs+C+0A85YJw6IwrA0p dYYCWUnhQU1JPTJVOXLlUSS1myD/q8PMPhWXFifLyCJdHlpRjs+cyLZgP4TK3CMffvR4iw== X-Google-Smtp-Source: AGHT+IEZIhblyA8juUY5dwK6eMaP5FlaJwX0x5Wc+IM2QYYrQZYhbBhVJSIQL0w2PYJ+yjwkSiLz2w== X-Received: by 2002:a17:907:9488:b0:aa6:ab00:7b9d with SMTP id a640c23a62f3a-ab789b4c8c2mr539555066b.4.1739185294146; Mon, 10 Feb 2025 03:01:34 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01:33 -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 v2 01/14] iio: accel: adxl345: reorganize measurement enable Date: Mon, 10 Feb 2025 11:01:06 +0000 Message-Id: <20250210110119.260858-2-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 Mon Feb 10 11:01:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967681 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (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 EEABF1DF98B; Mon, 10 Feb 2025 11:01:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185298; cv=none; b=uM6hkCEC946IqKgTtCbGoGY4EMIvsb5JLozrml+h2liUuIS6aFtEKF1PU3uzlptjCSgnXAIakuJQoaHlXbhJmoxQ79LrpU9MUGHRoowwRiqWw2qXsAZa5orQt2IKVprDZbbdCAju0uiuOp1nFAqiD9g/NlFRzKAyV1+tokW6hxc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185298; c=relaxed/simple; bh=4lgqPxMFIxcu6DJtyKvsa6jPFpK3C+Ewcmj6hhpH5wg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sOz2z3Caq1Hfgh8LLfAQYpj5n+F0EHHi00DX9CdfMpPQT+j/D/ef7qv/uHnHmFy4PDUnyU2Bt+/4+tpw15DOw1Udl4uc0F+6qvlQSAxft6wN5WvQjwzNToAj0XEXKLpNC5F5/571znMM3IABhmLEScGqzGzR1HCURwBmlUDDonM= 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=Lheq0JzT; arc=none smtp.client-ip=209.85.218.49 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="Lheq0JzT" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-ab7b35a004aso22180666b.0; Mon, 10 Feb 2025 03:01:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185295; x=1739790095; 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=Lheq0JzT5+60TiPa6DpCrdE8RrLRtC/LdXgmlpbeBYPtJEqx0gBzUxWHEjx69zNH0a My79yWP4fvi2ytcimfHn/hmAVWtxVmJBpeAJrYyzne8wIlNX/QpIri2ToEF0rBpOmFK7 Nl02Wi2ivZrlo99XnOTLN2BzEMOLXLf9WBigHeNCBFqP1bD7gfpMnTTkJdctIX9Yz05s vqCu93WKUcpGJe2uqr8a1WpMG0xG5w1sPVsPuOvY0TFBRSG0MsK01wvbPkmb6g6XH5QN hhvWTCYE81osqH+9yHSGbQO+UdT4+uIElThEDJ5rKdqHL2b2tf2ow3bNrwXL1hEdr2+R 7gKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185295; x=1739790095; 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=O4qNzae1xh9ttA2+pCx09X9MaFzUEnCVrTlrTlT6djfqtwcUYiS+LYP2l9KSjgkh38 ciF8bhuuoms+BdBCKHh4Quam3O0cM9si5cpB/C1eswJnbKjh5nlHFtUBUJ7YVgO4Ysr7 Ilwo3OTSDeFKZaGmt+CN5qJEEzqZFuxodBSEMPPUIHqosxZlF/dgZ07gaBFXtA/urHrS MSwJ/KEreqjT4BhOy/i9hQyfNxuqxpjZbF1ce0HqdWNidoBOVn1v+/q6mRA6AiAYkMQN aAAo0j+OffRZkrOuWdAyngGCamyv11196Fm1OaRrqQ0KBzumVSGl80c5Zjqsb1caJ7El vQag== X-Forwarded-Encrypted: i=1; AJvYcCWPwXeNONZzI/uKvZaD73a7/7BxuiCOhk6TXqUILfsHc/0nHq9qm59x1FkK7AGOUoCD+Oze8irjfE/9k0w=@vger.kernel.org X-Gm-Message-State: AOJu0YzriI5pzBQekSekuifRSHlju+3cELVBVkvFwcPH6Aj/GwCopKwG 2mIjl2rhz4vTwSSXf61Ox6jqxqwgRYwYkvSJGSMiQ+sJ0+BxBkX+ X-Gm-Gg: ASbGnctYow/SMgQoJMd+cClNXiY3WQDXlCOy4jW7BckPxzKDlT5sfhkr+9v4YCb1ku9 1H8u82WfeMB/nszPaovKzQFz3+JqbOji3YHHMl7WFwn7qOMrjAfjBgvaLrG2T9cbKKOXhXECcdb 5T8trJcxXDTDEjgK/UuVR6+OB+TWh81V/jXUpsArv8fLHE0Pj6o/lwsUG2z9BPUKbbnZpSTTJFc AhiM2Ad8lnP9KgwkPx8Tl9X5lu5q2pDRh74AekAZ/zoQK1cZurGnhYmKkDi3LZeSH3oq2ATaB4J tsBDA0u3oh7f5Lqo3J3sRRTNXZqgilr3OM5nWCrgP6li3gu/aLS5WeHbSN9tWAYjtsFZBw== X-Google-Smtp-Source: AGHT+IHCN8FAOnf074W91FqLK2TJl4jo1arYJwYdZdC+yUBSlpwUlylD99NqUWtXXh70SuLS9ddJJQ== X-Received: by 2002:a17:906:891:b0:ab7:cb76:1b0e with SMTP id a640c23a62f3a-ab7cb768dedmr53984866b.9.1739185295058; Mon, 10 Feb 2025 03:01:35 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01:34 -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 v2 02/14] iio: accel: adxl345: add debug register access Date: Mon, 10 Feb 2025 11:01:07 +0000 Message-Id: <20250210110119.260858-3-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 Mon Feb 10 11:01:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967682 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (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 1B5E31E04BD; Mon, 10 Feb 2025 11:01:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185299; cv=none; b=UYsx4dYvxW16SwH6PahIxcCgquWhEAvtGfuQoody18EJparJXdje/n2txUYLlg3CVICk3GyN+BdpRKHeCUu5eL7nQfaHpy/WSHuaP01gT4b+eg1SHIWHrSC+TeRgX/mpkwxp1I4E/NwLPY4I8LmHyU3+sYwgDtO22OQVMBa5yxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185299; c=relaxed/simple; bh=Ttjnz9CEb4H/zKxyDBnQf37YaeAwFYqFGMLzqwJ1KfA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TswKaQbOTpi+8a96q0WD/EtjaFIrCLKrPpNGhzPTL/rDBvBUKPVTNl0RBYbL+ZKfONj27wnvXWg/eoDeBwkK+DnWGo3FHK0xnvlqBwyi5A5aTZb/mxFlZtdoAUJPLMjaYIO0I3/kfKZpNp5UjMvr3XFY1niZntZHyJewxkqzeAc= 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=d7UeFGUy; arc=none smtp.client-ip=209.85.218.50 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="d7UeFGUy" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-ab7c4350826so8205766b.3; Mon, 10 Feb 2025 03:01:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185296; x=1739790096; 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=LUUYm/3eJ6K4O4SEkRHQKdWxE/3N+ctQ4MV2sEbJtcE=; b=d7UeFGUyHVr4k6y9TPWO4iRmVjldfE5+6Cnm6a284Iq15KGhystkCreX0YFcGt15a1 2/z3SYULBgYaYZha286W6lIKw0RVMAPXzKvk+6bCVw48ULvsxnPpKGZf8/PbbVmThTKn YXu0b0x+WLlXTNb5rTaXZI6NTelVQcRmnijUjovY8sNdViirerxPJfqdG6kVVtCP/7Ts xLYO3zR/2pwUpfvM8Im6FvQZ2fbuWhikampbqOYTYvdNYNXOsNSfoZaf22Iho83AIf28 Ojt/67V3a/Pk1hyoQZsKnveScdLL1WOJNTotPLgP3VKGKVadyNYtAh2y+CCQwXsR8vml rS3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185296; x=1739790096; 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=LUUYm/3eJ6K4O4SEkRHQKdWxE/3N+ctQ4MV2sEbJtcE=; b=wiMMixz15YtZwvJnDSFZyl2rPHV57+UGYuD59K8xnxhBQURQlhn4ghEkTuRO84f/vr I03qbKHrO/FW0auqI4q3H5shSdCuHO3jldsYygi0ZS9STX4HvjdF9L/JYMkHCZVgmfzS VUNPWLaUZ5RNe08J9+zRu5W+VHjrravw9Y4K2HJcxrHaMsDGph6CueIM3aAQ2nD7DbaS o5WNN6NEF/2hf6Q5s+/eFz85wKXNlLoGJMciuuiviLL0z+4DXZmkY2Ks1kHSYonWsedg NqTCndnMSuJPlI76FSjuVdkX8gV8Qhee0wutzjQefSG277U/CRnVctcy6Ogvu0FfbeOT Liog== X-Forwarded-Encrypted: i=1; AJvYcCVNDpmTQINfUVR4fGAgNg34bVYDu3mECWA7/uT6mneHsToyM/aV23yD/XiL0pt7O4kL69QQysWA2cR/efI=@vger.kernel.org X-Gm-Message-State: AOJu0YxxTm+LUzuHB338TVX7WN3F2Wx09hK4FhU27NuphsBiTiM9MseW lAG0MvAdoknJnyw80OsJL1QpXXPbPEll3S4CWtkFl9qCjebjvYgzHz0UTQ== X-Gm-Gg: ASbGncs95DDxfm3KGrFV0mwQiOUG2qEqDZdMpGrDnZyrLMga/XW7N0RN4mPEZGjIF2F VpMXAwxrzhKB9FY3Bj3siOwODeNc7qyOWVa58noekDcTFzZXf0sse1hp47UhHbNkJuFO/TBIayi 0NXaVrVJNmshII56rxyRQTbcwHJK86VI3KQbfszrpx1vA1P+a7hGQ6b08aJyvMDLo8Y1JuR/ofr V+e5BpRV1Qzj5a7MxtciiNwVL9acALPjYcSvOWU07FxNsTZ5ph52HjYkeuMQAqD/wWLMUxA87VW 00vIyvyoJZatiOKRSY0d4b3ktDqt3DYKehY8MlJ2pdjTgmk/4BOx8qgAU0UQp/b1MSE6Vw== X-Google-Smtp-Source: AGHT+IHjj5Y0omCrE5Yx3J43H+N0Jh92ZtUKt8kOk0+UARkJyK/on6u3N4vsH4HMhh6wgTiOMl7cWQ== X-Received: by 2002:a17:907:3f18:b0:ab7:cd83:98bb with SMTP id a640c23a62f3a-ab7cd839b0amr54944766b.5.1739185296106; Mon, 10 Feb 2025 03:01:36 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01:35 -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 v2 03/14] iio: accel: adxl345: reorganize irq handler Date: Mon, 10 Feb 2025 11:01:08 +0000 Message-Id: <20250210110119.260858-4-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 | 26 +++++++++----------------- 2 files changed, 9 insertions(+), 18 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..2928c1c0760f 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,16 +403,9 @@ static const struct iio_buffer_setup_ops adxl345_buffer_ops = { .predisable = adxl345_buffer_predisable, }; -static int adxl345_get_status(struct adxl345_state *st) +static int adxl345_get_status(struct adxl345_state *st, unsigned int *int_stat) { - 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); + return regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, int_stat); } static int adxl345_fifo_push(struct iio_dev *indio_dev, @@ -449,14 +441,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 (adxl345_get_status(st, &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 +452,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 Mon Feb 10 11:01:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967683 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (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 23BCC1E1C3A; Mon, 10 Feb 2025 11:01:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185301; cv=none; b=NiFxq0SY4l61reStE+bVk13gpebSHbmq6gqjJx/FaXrnBkWqKPxBwO1Q9wIEPEL+zFLjWye5lVKdcmwyRZlkksETO+y3+xTFGwQCJV52anJJxfROEX60PlEeZySJm5KL0C2tvvNbvAOHeYYq4yRtuXYTm6iTqMZ12VZJVS75Jq4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185301; c=relaxed/simple; bh=wbt580DwdGlO+aiZPD7DBskEv9+63Kf3XN0LL5B0x/U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hvk54rqgxMZYrwokf2pinqfSuAWezC83Mgri6mr8XNnAbl+PHMwe/J17vcECT6sbTR+aNIroe6K1H4PUbtBGTY0fWXyqoBjtB3o6XrZqKi6BLHJXKFHDAoQqzMuzLEYL9PKlGpE3xaTgOhoAe15LhV3HaYxvNfjIDjZwyxLWMyc= 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=ADNyzkBW; arc=none smtp.client-ip=209.85.218.41 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="ADNyzkBW" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-ab7b35a004aso22181766b.0; Mon, 10 Feb 2025 03:01:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185297; x=1739790097; 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=LIxWhxBWZqa1JG+Bdh4G1uq7jD+PXr0xdm3Jh9JZYbE=; b=ADNyzkBW5DmDF7NkYzude7FIBCjo9ZzO0byy7q3Rw1t58h4aLLbpAhiEbumdQo0EWw n3i68ahJdtWkggP/pn6jcLmSXN6cKFVUzYSqL1vn0T37R9FPmrSjjAOsJWbpLqbC+eGJ 5q4rZpe+F7noP9hlWgIJTFzlGMEYrm+M0SBna8KA79C8CzUmC0vEHgpMQMTrGpMXj9ms TSl/3ByFXuUJksg1Qhn34HaCaTUTWEXvemcSQCGllhXh4UwS+1uvCDOZJlRO9OD79umQ LefgQjHNM1h0qMsAHuVWf84OzgGlvmUYNQFqr4xXT+NVRVhB4Ysukae/qr0ygnUy8V9l pzjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185297; x=1739790097; 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=LIxWhxBWZqa1JG+Bdh4G1uq7jD+PXr0xdm3Jh9JZYbE=; b=lp9e1SDgb+GQMDiF0fmnv+rPY84ZXCQoQDqkGgjkh0maYx0GjeXJn7XzKrgmjmPqNV Hyrr2fjFLPb7hA3+08H1Y3oMxf1lOklnXbB6TKLz4yGdWCG0BDUIErgRjpRfAIrwzcAb cNm1z9AirGuIrdlf+ICU4uIOw6l1SgYFqlyMqK9SYFMErlYkLDX2Gw0JXewKMiUMcq2c TCpP2a0oV6sW6ecH034OldgLQaEXlYwHsEViA+eD9KQhBZUvTNfPmAasYtkhWecuVPPD QuRC+YW1a+eSv1gSxXKlzFBasEHVgduibPBNpDYdRA5n+Ah+wSzw3EKw1DHGSVn8Mthd iYJQ== X-Forwarded-Encrypted: i=1; AJvYcCVtumjBDigG1OaLxQv5UGblDZCrryZImAS66DdEhtin12z5bUQfUuJNnt0hW1DB0f94kdsURS717MSc8ao=@vger.kernel.org X-Gm-Message-State: AOJu0YzhK/NnPZOUqz4ukqUn0JgMw5N+qkZ4uep8wirzrz9+TGCj6aP4 NjcldlI+111nNeHAEXyXPa7z96ugfTNvoKsBpFDsg6VlWHA+tNBH X-Gm-Gg: ASbGnctUBQXgKzZIFxavf7CKhnLbzY2+2q+LfdQCwazhE+2r42hjliVbnJw+LHzBYlN 1sbZvPkdk+Wq2/ODTqUdPUdcrWGm8Pgfex5vs6WModarUI/jpOnf5QywkvM5BDcytTaAjUBa/y/ IRsb23EhHJWY/GVRF/+zGuKxjqzfKcMEF8vYQgYHzQk3u48zmkJNd41fNQaScuqjLsOD3ogMcC0 Ulk1vziU0ONRZDSyQ/9Zok9iejAvfVGmv1OzFA5Uvx0vpAIM4M3qzIUD/ugonRiysx8q79OpOSm f771aKwNXnzft1yan8wh10eQDjJJSVcgTJAwQeopI4VphoG+GqPwY1pX0rmjh1DBR8/OTQ== X-Google-Smtp-Source: AGHT+IEVaL6SBnQKinvH1sjeRcYBCzSbtrfaeDIVkCPPlbuzG+6Oky2lqauFou7N6T50ASwQlMwiXA== X-Received: by 2002:a17:907:1c97:b0:ab7:7c28:5f0 with SMTP id a640c23a62f3a-ab789b25d55mr573000266b.1.1739185297333; Mon, 10 Feb 2025 03:01:37 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01:37 -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 v2 04/14] iio: accel: adxl345: refac set_interrupts and IRQ map Date: Mon, 10 Feb 2025 11:01:09 +0000 Message-Id: <20250210110119.260858-5-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 Split the current set_interrupts() functionality. Separate writing the interrupt map from writing the interrupt enable register. Move writing the interrupt map into the probe(). The interrupt map will setup which event finally will go over the INT line. Thus, all events are mapped to this interrupt line now once at the beginning. On the other side the function set_interrupts() will now be focussed on enabling interrupts for event features. Thus it will be renamed to write_interrupts() to better distinguish from further usage of get/set in the conext of the sensor features. Also, add the missing initial reset of the interrupt enable register. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 46 +++++++++++++++----------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 2928c1c0760f..910ad21279ed 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -14,10 +14,10 @@ #include #include -#include -#include #include +#include #include +#include #include "adxl345.h" @@ -96,26 +96,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) -{ - 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); -} - static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -376,7 +356,7 @@ 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); + ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); if (ret < 0) return ret; @@ -395,7 +375,7 @@ static int adxl345_buffer_predisable(struct iio_dev *indio_dev) return ret; st->int_map = 0x00; - return adxl345_set_interrupts(st); + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); } static const struct iio_buffer_setup_ops adxl345_buffer_ops = { @@ -514,6 +494,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, return -ENODEV; st->fifo_delay = fifo_delay_default; + st->int_map = 0x00; /* reset interrupts */ + indio_dev->name = st->info->name; indio_dev->info = &adxl345_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -521,6 +503,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, st->int_map); + if (ret) + return ret; + if (setup) { /* Perform optional initial bus specific configuration */ ret = setup(dev, st->regmap); @@ -571,6 +558,17 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, } if (st->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 = st->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) From patchwork Mon Feb 10 11:01:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967684 Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) (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 84AA21E376E; Mon, 10 Feb 2025 11:01:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185302; cv=none; b=mQQXadOYnm6feZDseo8yJDVvazhjfqVBvtK+HblR/Z8uy5AEkZwkNiaDrXQw6fu1ZQJjE4cbjBkwHI8L3uO4LLdfq43vGIfBI51JtLGtdg+N1Z4/fwPyV2pAt+m/G/8dMFqZRgfgpmfWeMYHPOLkXwbjphNl7rE2RCHAxHqWUcE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185302; c=relaxed/simple; bh=zo086hz6rka8QSxwW7LEi8pN4iHCWI1Sn1JRIdpPfJI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rPxF6IwNcEog/IdpJRTGt7G9pl+53gN9/ZBSh05wwaiHsfJUVi43mPvDMDaG+CdopzsWllLTPB+G2igqD5MPN0N3MSQN1eAqPVwDfJgzlT2KycR2WQ7CHgLzzEHsv4bjsbsvcWHK16Amc87XL8CSIJ/iG0aQNGl2ojqQmIG/Srk= 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=BYdPFyty; arc=none smtp.client-ip=209.85.218.54 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="BYdPFyty" Received: by mail-ej1-f54.google.com with SMTP id a640c23a62f3a-ab7b5308a4dso27034266b.1; Mon, 10 Feb 2025 03:01:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185299; x=1739790099; 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=Bl/DOFrifvpFKvgqOzrQvHhDtISjLv/tfdgxn7y5stM=; b=BYdPFytyFvvuxt08NpijFDoFWYWH41gSuPl3wrHTk9+6M7t7c94zBc1F92Bco4McVO jgVnYLQc8ktgepvVm7hPpDpZCCaKQH9mBwAfh5dVOMUt6ippTUBBiIKaGgk8oWXYOcAm tRznlrjXMXWoF+Ank/X3+iaXyyLI9XyeVXZpVaEjaWSQ0C5F6V/6VP+a9whfEvuVec/R Q9o1EqAYWB69rStmu3wFBlBx4oSFJg9QIDVPiWoxMCW9uG5gF1e6u5CeAWMANWnrGc1O DnZl2vaqG1ZVnmHDJ/ufub+jMzokVAgg8k/Bg5shioWxFEv3K1O2BsxRKg8wjb4yGTNY pfeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185299; x=1739790099; 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=Bl/DOFrifvpFKvgqOzrQvHhDtISjLv/tfdgxn7y5stM=; b=dnpgYzYG1m/SpVE9V39OuverWf622QcYPKE229ZZSmCCsCKc+H5obxMCljV5oCwp+Q Q5GCU/bTx4DZPyb71C38ER7rS235RgQpCb3uxfS77P30nsLiN/MtovcihWrTti5K7XNi Uk/MimqjO04kY63nf1MfY2xzPPjLn4N5nonDCrydhbU4bgjx/2gCHK++iqU8e4F6rYbG bcAbQixKoSj/hB6R+eeYhPFt4Tsij9qXVe6JFgSFDCn6qfR7n+On3VP1JjGzDs7g4MNy m4cSgW8kTt10J3sRlQIjgwIhEa7vv76nkpCSs25/PHVMryhjqgaaQIRQ1tFHu8fK5cfj /Grw== X-Forwarded-Encrypted: i=1; AJvYcCVuxkstwwf6Y4uTyyAKcSjWby0RbYj/krdPkM8UC0+DNt19EsItPA8wn8AO5JOnQoU4oug+qCrEXkEResk=@vger.kernel.org X-Gm-Message-State: AOJu0YyWSSoaT01mOzn1ntYdybQG27xt+JBQpWgMTcMdXEepMS98dyz2 aXRw7ZqDW5eRLzEzqqiXn5kTXtwminAqAva7Jxo2Z4ph9Kn4kURm X-Gm-Gg: ASbGncvD0ZbQuwHo54ARPshZPtGTyPsxyyJ9AmfEB84cS+ecz3GHFXiuZ9EjDJo+cgI RmC1cHkep8XvAPdsA0JFog1z1/aeFSfRllEsTOIEvFtKZ7Kc2dJcmZIhRJ8T8UsHtEAwZ5yahf3 LFaTtIxht+mHxkakq0wCa0U1dASCdWUCeLsJc3SHRJOD6/rC1UsDherBcejJ54Uv9uNQW7TG/CM n5WFueIxinmXzvnLFqVdYgQC54tCuI7s8eLToLSEU3MvWdxf8oJibPrT6NA9sZzr8gNJpWGDRfy GO9K5IETO1dNiYK3ENOegeOw66g2tfcVgN/nr4uBK5DZw+5tcBfbvkBkFO1j7Rvdgo0P3w== X-Google-Smtp-Source: AGHT+IHyRpBHhYOPuFxmzFrLWDD68ZNdEcFhhR+cQwGKikyUvYwjRfQ4H0FRQPO4b5ScGfwP3+S6vg== X-Received: by 2002:a17:907:7f08:b0:aae:e684:cc75 with SMTP id a640c23a62f3a-ab789c35369mr511015466b.13.1739185298499; Mon, 10 Feb 2025 03:01:38 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01:38 -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 v2 05/14] iio: accel: adxl345: add single tap feature Date: Mon, 10 Feb 2025 11:01:10 +0000 Message-Id: <20250210110119.260858-6-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 and duration using means of IIO ABI. Extend the channels for single enable x/y/z axis of the feature but also initialize 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 | 369 ++++++++++++++++++++++++++++++- 1 file changed, 367 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 910ad21279ed..304147a4ca60 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include +#include #include #include #include @@ -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[2] = { + [ADXL345_SINGLE_TAP] = ADXL345_INT_SINGLE_TAP, +}; + +enum adxl345_tap_time_type { + ADXL345_TAP_TIME_DUR, +}; + +static const unsigned int adxl345_tap_time_reg[3] = { + [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, +}; + struct adxl345_state { const struct adxl345_chip_info *info; struct regmap *regmap; @@ -40,9 +69,25 @@ struct adxl345_state { u8 int_map; u8 watermark; u8 fifo_mode; + + u32 tap_axis_ctrl; + u8 tap_threshold; + u32 tap_duration_us; + __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; +static struct iio_event_spec adxl345_events[] = { + { + /* single tap */ + .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, \ @@ -59,6 +104,8 @@ struct adxl345_state { .storagebits = 16, \ .endianness = IIO_LE, \ }, \ + .event_spec = adxl345_events, \ + .num_event_specs = ARRAY_SIZE(adxl345_events), \ } enum adxl345_chans { @@ -96,6 +143,126 @@ 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) +{ + bool axis_valid; + bool singletap_args_valid = false; + bool en = false; + + axis_valid = FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, st->tap_axis_ctrl) > 0; + + /* + * 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 = st->tap_threshold > 0 && st->tap_duration_us > 0; + + if (type == ADXL345_SINGLE_TAP) + en = axis_valid && singletap_args_valid; + + if (state && en) + __set_bit(ilog2(adxl345_tap_int_reg[type]), + (unsigned long *)&st->int_map); + else + __clear_bit(ilog2(adxl345_tap_int_reg[type]), + (unsigned long *)&st->int_map); + + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->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_threshold(struct adxl345_state *st, u8 val) +{ + int ret; + + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_TAP, min(val, 0xFF)); + if (ret) + return ret; + + st->tap_threshold = val; + + return 0; +} + +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 + return 0; + + 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) @@ -181,6 +348,147 @@ 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; + } + + 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; + } + + 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); + + 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. + */ + *val = sign_extend32(st->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 = adxl345_set_tap_threshold(st, val); + break; + case IIO_EV_INFO_TIMEOUT: + ret = adxl345_set_tap_duration(st, val, val2); + break; + default: + ret = -EINVAL; + } + break; + default: + ret = -EINVAL; + } + + 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) { @@ -383,8 +691,33 @@ static const struct iio_buffer_setup_ops adxl345_buffer_ops = { .predisable = adxl345_buffer_predisable, }; -static int adxl345_get_status(struct adxl345_state *st, unsigned int *int_stat) +static int adxl345_get_status(struct adxl345_state *st, unsigned int *int_stat, + enum iio_modifier *act_tap_dir) { + unsigned int regval; + bool check_tap_stat; + int ret; + + *act_tap_dir = IIO_NO_MOD; + check_tap_stat = FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, st->tap_axis_ctrl) > 0; + + if (check_tap_stat) { + /* ACT_TAP_STATUS should be read before clearing the interrupt */ + ret = regmap_read(st->regmap, ADXL345_REG_ACT_TAP_STATUS, ®val); + if (ret) + return ret; + + if ((FIELD_GET(ADXL345_Z_EN, regval >> 4) + | FIELD_GET(ADXL345_Z_EN, regval)) > 0) + *act_tap_dir = IIO_MOD_Z; + else if ((FIELD_GET(ADXL345_Y_EN, regval >> 4) + | FIELD_GET(ADXL345_Y_EN, regval)) > 0) + *act_tap_dir = IIO_MOD_Y; + else if ((FIELD_GET(ADXL345_X_EN, regval >> 4) + | FIELD_GET(ADXL345_X_EN, regval)) > 0) + *act_tap_dir = IIO_MOD_X; + } + return regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, int_stat); } @@ -407,6 +740,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. @@ -419,11 +772,15 @@ 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; + enum iio_modifier act_tap_dir; int samples; - if (adxl345_get_status(st, &int_stat)) + if (adxl345_get_status(st, &int_stat, &act_tap_dir)) 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) @@ -449,6 +806,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, }; @@ -496,6 +857,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, st->int_map = 0x00; /* reset interrupts */ + /* Init with reasonable values */ + st->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; From patchwork Mon Feb 10 11:01:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967685 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (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 909A81E411C; Mon, 10 Feb 2025 11:01:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185304; cv=none; b=m1WZXqdGfF6zktxJjiQjEGgDFfnqRvdofqS8bFcohNHKpYgW8Li1ozMcyTj328VAmXahcHy5kdWl4JslOeP0QHI9Y4F/BFEfmfiRb1st0/dZp39Eff7IneUifT1See2Lu5l4jwk5nFGc694VXw+G5URM3iXfpH86TlQAYKKWP4o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185304; c=relaxed/simple; bh=cJQBXncRcnbByy/WRb+6/EhlbXvj9i1sJQ+x1kH5WrA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=l6DElg2FguitC7cSguRdgv9M2vsiLtuwN5jlzE5/wgfxe6abhA66CyR5iBAbJseS/BO0KouabvTHEEv+aPb7iM7+n7jF7yW0/bPWigBw9m9mNKo+Jdbo2nYBJUGJ3Ga/NC08rrcCEb3PDz4a2hmaFVvoUu7gU1dzCunDTUVFrn0= 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=NaeylJyA; arc=none smtp.client-ip=209.85.218.41 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="NaeylJyA" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-ab790ca8a87so47701866b.3; Mon, 10 Feb 2025 03:01:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185300; x=1739790100; 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=hiCEHmimT/fs+/V86FGfTGKDk57V8U90fK1w4CaiKvA=; b=NaeylJyA4WrRQ7GInNOUm8yFfVrhnnhyNz4JaBskgk6HGnhdAlDSRAzT4CRhmbQLXV ObJT1arKJuAcevBq/JlaPaQrOAsutoW0Ojrs9Vc9EBCpes7ixNbb9H1wkHCP8KwEn16e PmSQyg5m1fX/bMMOgCpj+BwQ9ERve8/HibtDAIQYgBSC0f6CzMUNtwX5aJ8eKLuHkbD6 zeuH8i/uj6LG4sNvWx8GlXSkjnbh5bMxmUFgLzQW7wHUKARx9c8cOHBmvBrFgmcJlmUB egN+IZ8DeNFb7vdK2MGyhoxCXFerjd+szHLdHlI1KKBgb91t1EsM9pqd4dscUS61Ups9 ghBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185300; x=1739790100; 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=hiCEHmimT/fs+/V86FGfTGKDk57V8U90fK1w4CaiKvA=; b=UIVKB7UPgJCJj2yFo4i2BGUq0Zzb8Q2JHwfXt5wWmmm1+YjeLYonRZnSLZ3UBFqq56 WW6D7nK8P+StgWcwb165XGnYJHrXD9baLIPc5Zz+9MXhG85MdrHwQ0BSaflVe9m1lHFP /l2nj4Dfit66wjetSmmR8TCkd0P/VnPq4WxHIOVqeTfARa5QefXSE1g9hJjh/z0eKbmb WmDl7PqpRL/rrQ96G5T2gc3cEQbZN5eEgO2p5WwniVoEOFsDCd1sX7eZYcNgBbfHAdU2 0RksiYkzdzUZtjy1+zNmd/FBLkNaOmlVvEVidyqY2TYocoglEQXZN0S2t1d/UiB7YxtT 54yA== X-Forwarded-Encrypted: i=1; AJvYcCUz2c0ANY3dyeo0ze06Edd+n/pZxPNSlYOJLdJ0VUSYoR2O0RQ0R4mH4TzSZXH8ZqYjHGHZs4aSIQmEktE=@vger.kernel.org X-Gm-Message-State: AOJu0Yz4TBnNNpW+ysySyXWuqQTGy/s0NOP9gEjv+ETroH/HXxFbjNfB WyJMxFrpRokA726DuEk9B+5ncMERIPkAQiRAMWpsmhA81OGFn7qM X-Gm-Gg: ASbGncsRfJF+vAtXONq+qlYBvygYPyyFIgDOmjrvIgYfild1iusCh1F+bWas18oyMkR +zz7TBB0gmfew/tEfijNutM9pW5cw6M+gD/wBT2SPNNlqFprgcRmDdUAaEnoqi2DIv/PxHR+AwM RFxwelOi6V88dnsZS+PfgFStzfQxclnbrSu9LCffN7PBTHibXIkK3ntEKcrPBozjzmR96sPqLPP tIzbdJ/fCa5wFzOIe4P+r8jCO2o3PD5utrPVGCPSk5I6fdF63j6jT9Qp9t7lDTfIxBQB5h1EdMW uBOWuYQlHTIWtmpwjFe8fldJ1dWJFSrfGdM2diNZWD6Rs/FlrbX54XqBVzvV2iG0EUY/Bg== X-Google-Smtp-Source: AGHT+IFNx1AkxgQEqo3BcZAWVsArR//yZ0DGEJPcW19mY+G9oUIlagb4iXHBQqtmn0elr3fcTvSQyg== X-Received: by 2002:a17:906:f59b:b0:aa6:6f12:aa45 with SMTP id a640c23a62f3a-ab789bc7a21mr553608866b.7.1739185299668; Mon, 10 Feb 2025 03:01:39 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 06/14] iio: accel: adxl345: add double tap feature Date: Mon, 10 Feb 2025 11:01:11 +0000 Message-Id: <20250210110119.260858-7-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 102 ++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 304147a4ca60..cf35a8f9f432 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[2] = { [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[3] = { + [ADXL345_TAP_TIME_LATENT] = ADXL345_REG_LATENT, + [ADXL345_TAP_TIME_WINDOW] = ADXL345_REG_WINDOW, [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; @@ -73,6 +79,8 @@ struct adxl345_state { u32 tap_axis_ctrl; u8 tap_threshold; 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); }; @@ -86,6 +94,14 @@ static struct iio_event_spec adxl345_events[] = { .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_TIMEOUT), }, + { + /* double tap */ + .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) { \ @@ -163,6 +179,7 @@ static int _adxl345_set_tap_int(struct adxl345_state *st, { bool axis_valid; bool singletap_args_valid = false; + bool doubletap_args_valid = false; bool en = false; axis_valid = FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, st->tap_axis_ctrl) > 0; @@ -173,8 +190,16 @@ static int _adxl345_set_tap_int(struct adxl345_state *st, */ singletap_args_valid = st->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) __set_bit(ilog2(adxl345_tap_int_reg[type]), @@ -213,6 +238,11 @@ 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_threshold(struct adxl345_state *st, u8 val) { int ret; @@ -232,6 +262,12 @@ static int _adxl345_set_tap_time(struct adxl345_state *st, 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; @@ -244,7 +280,7 @@ static int _adxl345_set_tap_time(struct adxl345_state *st, if (type == ADXL345_TAP_TIME_DUR) regval = DIV_ROUND_CLOSEST(val_us, 625); else - return 0; + regval = DIV_ROUND_CLOSEST(val_us, 1250); return regmap_write(st->regmap, adxl345_tap_time_reg[type], regval); } @@ -263,6 +299,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) @@ -380,6 +444,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; } @@ -416,6 +485,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; } @@ -444,6 +515,14 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, const struct iio_ *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; } @@ -475,6 +554,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; } @@ -757,6 +842,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; } @@ -860,6 +956,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, /* Init with reasonable values */ st->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 Mon Feb 10 11:01:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967686 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 EE0F21E47B4; Mon, 10 Feb 2025 11:01:42 +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=1739185304; cv=none; b=pmETT5FqffQWRpDBiP9Fyz7JKg7kaCo7WFTqc3WQZDamMJ9i/wB/uuuZb/59Wvh1ywd6mL842+6nse5kjC5wVMbl9gcFJP6uNSx1fYR2U7cdXg9SCcmW2Me1TPIYiaOFWxhDFvfa4wfgRq5c0UgAS4d4MUgW6l92+EsbhPth350= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185304; c=relaxed/simple; bh=CkhotK32JDptjtcWapjSsSJF6V93X4D9d/b7DoqBsKU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OBokpTIe7NYUK0B3MQILZZiNvMGO+qD1SQfUFmkfarW4p5CwAiLYWFgwZ17rgsh1s2nZiW3QuZ9fOdL1rqQjw7YJvWFDKQD9UfHMAs+6P5P/fvnCjNQjVAqD+pz6zc6XR4KwHJD0t5zeKEU29HBzObPtUfDfveW0zR4NIxBaV0w= 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=TjNUDGLh; 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="TjNUDGLh" Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-ab7c4350826so8207266b.3; Mon, 10 Feb 2025 03:01:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185301; x=1739790101; 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=XsBWRk8zfnkA3uoBf9V6a0nw7PSVQIDTY9KmDxfKDmU=; b=TjNUDGLhoncfUg/Xm+LPvHxwkjC17Iyedl4eVkrQjDJDLFUmPxqIjmcUaJLiCfwNEe 58/fnfBHmf+pN995G4NLaXS+7YHBnKVIdtQH4mV48vmwM8CRG50ErLPUFGJS46LG+wCo rnd2WLc7EEkgiQoyQVNlhFGdg5ZRxGgDxddgOJCTQ4R0QR2uXpOzN0B0gdvgE7uAyEgi vx8OcHtiZjNvIzyCyCO1wtwpBpSrTbXTvonykiWF2eRG9oTAtRbDOGTdGg6yAWhU34gf cEvRHXnixhx5Uhr3XxYuXeSNj/Sbwe2yTLiO/GDhZ7EVYrfnN5C8zcM0KYX3sp9nzZ2q YIfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185301; x=1739790101; 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=XsBWRk8zfnkA3uoBf9V6a0nw7PSVQIDTY9KmDxfKDmU=; b=jPisSpSc8aGiyQiY5qNLm4w7iWnlh24PdjKwktz+3yafW7Z8A696ll49T7mNSpibcQ idkwTvtXfuNEf9/lpCg74+cEM4eTH5tcpsZDrp8LlP8UGYQlGH40cV9iw+CFA2iHjpaL 7jr6Xo7XA59qtKd0y8clUHFAE+BjS1Rn5CpWsrwdJNKhi5rh6EvNgUfojttZTIjiQVfB wTg1ZiDs5A/qMea7nHRSCYI964XXQsop1ZaFbeFiZMcPhQ/HGCXISyq1cmGox8i8zZiT TMHhCeTTrDND+QIoJ4r7vGPXNrurrFpzzyE0Dfd3nPwLdvetBx5v9zKDq4S0dXXZUtOK krZw== X-Forwarded-Encrypted: i=1; AJvYcCVy1B5tv1sYi15PIG1ew0g86OFamnwidoaZRdNxPNJqtL2B1rCPOx6n3C+skgWiGzFkiogjv8G4ry+qTdo=@vger.kernel.org X-Gm-Message-State: AOJu0Yx1/ZqLX3De7O+qqOD//HRw50dnn7pcBoJLWdQA2plE8O1UR+hZ fSS8nJ0A6gGhorGECeUewB8VF2chALRKght5P4TSpseGC0s1Tey7 X-Gm-Gg: ASbGncvszeAMGyZiT1vAygL8RkOCKr0KgY73PL8OSNgUVXUvnyHpwGsDsS7FDd0O7tj a1krg9pQBmkF7JNpkc8Pjo9wjITYRTporrrwTY1XRHc5ojpsY++MPFmA9ET1JMpWu//H48xsBcB Dhi2XSowxz/7oKCQgOctvnstqKrYbFK35A9gjNMANYrOjeklAhh31PBzdhTKoqfa9H3BCYm9Lq3 oesr1I1DqZogSZuArXOUKjVCuE8atY7REUIRIUXNiN1X45tT7aRpkztxAsENdvreK1uyEQVuKY+ Bsgiud+uS5WGFQEZLtdcTixsy13d51US8bGO5TDr9Ry5J+NceMs6kCaFRZp1IgZ0DAZSxA== X-Google-Smtp-Source: AGHT+IF9ssgmeS3AEmbjcXyrDfumw80AGCvMhYW3vqQ4mtp2XnoXC4+8KON3DPDQl8m/6DxI8YxRsg== X-Received: by 2002:a17:906:dc95:b0:ab7:5fcd:d4be with SMTP id a640c23a62f3a-ab789adeb97mr548815866b.1.1739185300790; Mon, 10 Feb 2025 03:01:40 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 07/14] iio: accel: adxl345: add double tap suppress bit Date: Mon, 10 Feb 2025 11:01:12 +0000 Message-Id: <20250210110119.260858-8-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 suppress bit feature to the double tap feature. 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. This brings in a new ABI functionality. --- Q: Perhaps there is already some IIO ABI for it? If not, please let me know which ABI documentation to extend. There will be a documentation patch also later in this series. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 82 ++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index cf35a8f9f432..b6966fee3e3d 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), @@ -81,6 +82,7 @@ struct adxl345_state { u32 tap_duration_us; u32 tap_latent_us; u32 tap_window_us; + bool tap_suppressed; __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; @@ -243,6 +245,31 @@ 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_is_suppressed_en(struct adxl345_state *st, bool *en) +{ + *en = st->tap_suppressed; + + return 0; +} + +static int adxl345_set_suppressed_en(struct adxl345_state *st, bool en) +{ + unsigned long regval = 0; + int ret; + + en ? __set_bit(ilog2(ADXL345_TAP_SUPPRESS), ®val) + : __clear_bit(ilog2(ADXL345_TAP_SUPPRESS), ®val); + + ret = regmap_update_bits(st->regmap, ADXL345_REG_TAP_AXIS, + ADXL345_REG_TAP_SUPPRESS_MSK, regval); + if (ret) + return ret; + + st->tap_suppressed = en; + + return 0; +} + static int adxl345_set_tap_threshold(struct adxl345_state *st, u8 val) { int ret; @@ -616,6 +643,60 @@ static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev, } } +static ssize_t in_accel_gesture_doubletap_suppressed_en_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adxl345_state *st = iio_priv(indio_dev); + bool en; + int val, ret; + + ret = adxl345_is_suppressed_en(st, &en); + if (ret) + return ret; + val = en ? 1 : 0; + + return iio_format_value(buf, IIO_VAL_INT, 1, &val); +} + +static ssize_t in_accel_gesture_doubletap_suppressed_en_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adxl345_state *st = iio_priv(indio_dev); + int val, ret; + + ret = kstrtoint(buf, 0, &val); + if (ret) + return ret; + + ret = adxl345_set_measure_en(st, false); + if (ret) + return ret; + + ret = adxl345_set_suppressed_en(st, val > 0); + if (ret) + return ret; + + ret = adxl345_set_measure_en(st, true); + if (ret) + return ret; + + return len; +} +static IIO_DEVICE_ATTR_RW(in_accel_gesture_doubletap_suppressed_en, 0); + +static struct attribute *adxl345_event_attrs[] = { + &iio_dev_attr_in_accel_gesture_doubletap_suppressed_en.dev_attr.attr, + NULL +}; + +static const struct attribute_group adxl345_event_attrs_group = { + .attrs = adxl345_event_attrs, +}; + static void adxl345_powerdown(void *ptr) { struct adxl345_state *st = ptr; @@ -899,6 +980,7 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) static const struct iio_info adxl345_info = { .attrs = &adxl345_attrs_group, + .event_attrs = &adxl345_event_attrs_group, .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, .write_raw_get_fmt = adxl345_write_raw_get_fmt, From patchwork Mon Feb 10 11:01:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967687 Received: from mail-ej1-f42.google.com (mail-ej1-f42.google.com [209.85.218.42]) (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 DF3C01DED6B; Mon, 10 Feb 2025 11:01:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185305; cv=none; b=kmnmIQ03nkiR6QNyQp69q6BWpSmJq/l9pF+A/gTRLxp+HizVE70tgJ40tK521rF64Mi7kCkhxnR5+oNDGL17sTEwfnqqMkpTW0fmkPXzOWKyQI/whCL5jMLsUpfgxi5Cxkv8g+tDKpQyH+N3pzNNVF+Q8fZsb1AB6QQDhN/eFr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185305; c=relaxed/simple; bh=/y7mNfhaGB/ariXDVvyTGgWYdXRldxPNT88Vr6y3RAc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=G+AgxU+AGx110ECOlqnv9Qzy2rc7jsfT3bmfBKooOFGd5C115RrbZey4rMM3x9inhl1glMdM4qknNIjSXGovRsROgB0AFj9Bsopu0RGxECgeXyWh04uXvqKZ6YQao5S+5jgu00L54TTR3qiMYspDr6vYfpyBlRIZ0dSaBpGN7eQ= 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=UvXt7iwh; arc=none smtp.client-ip=209.85.218.42 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="UvXt7iwh" Received: by mail-ej1-f42.google.com with SMTP id a640c23a62f3a-ab7bc75e0a1so25211966b.3; Mon, 10 Feb 2025 03:01:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185302; x=1739790102; 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=tjRt6a7CPtNKaS1cR5u/H3ujmvzx1jBmmAENlUfwYtw=; b=UvXt7iwh3J09JrQAEEpxIgZ3YWzDKAPEKukrs41esyOlEnaJva/l1xdrMSq5uFf+bp XkyzCW8VVekvNdkGNa6tYKiTsfWYOf23AP0yiuqpi9BpYfiThLk6UP346D+/x5VAUvDh V4QQfY61SAx+CCe7VjXNgbjeWgTHG2MWwZmmgO5uttzYol1OnyOAuAunRdnBnc9hDld/ Un2FmuDZr1fgAi6uH74dXpc2DK65O0ms/JR2qpVPRLDbcrAt2ij2jvS6CiyhXqKCGLnZ ELZSMGL4iD0Q4MO2ICoPeuNnQKGehipeuAkGTII1a4ftPcYLcQXw4WlFStgci60Ssi8S ra/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185302; x=1739790102; 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=tjRt6a7CPtNKaS1cR5u/H3ujmvzx1jBmmAENlUfwYtw=; b=eXJQpJUKA/u6/Z7cmYJGUiPK9nSNgkTBQDlDrSQHODHTAvNCbD8zUKTCAyI4G4DA6R mnZwbbmdijPaA7rbxOZjBvnAcMtOHOEevHcejD/vPyUdU7q2n07bewr/okRPsHz922jZ px5Ik/wmf2MOZTU/hJxgoDOFtbBFpztHhNrrRHqUjjw1tyyBO8nvuve0D9zVfD3qYMBl iXB7gSPkzAsbz+JR5IgZF2hwNh99qzmJaa9cAlKfQcD9XY5jEEsgF3rVT5X8rlNndoxH nU2DY6dHtYewPgCsv+yu5RvXdKNAadPyV4Ou16ooq6a3CqDehddW3baAGowGLv0So0X4 W2Fg== X-Forwarded-Encrypted: i=1; AJvYcCXYz/CRqCa9RL91aTEctrLCGhGvk30ITw+zc0jnUJt15oMZgxe9XL4c1udZL1Lp24XRTme1sYJmgbzdbTc=@vger.kernel.org X-Gm-Message-State: AOJu0YxeMfs+SQGcPxt+NxTRQ7nlHqFbw9hU/d08NM9ijUuejOM77+YW rdh+obRzTdIYbmhL9b0u3oDLqz4/ppfjo/VJaALt1E7MLELC9G3Y X-Gm-Gg: ASbGncvupv1iM9BGmbSJtKPB9X9rXTNLoqGGflZbryglBP+Cvij4+gwJR2XSxMacuzA cDCSNg8PFFwehvvgJrMN1bA/SdBwGw0OXr3ttgsCiVP7HT4NvdN6Yy17/GerKBK4kUicFScsahC OecBcrgAW2+/eek3XGavb0GY2ITb1AnLxWkOutzmSqnlC5M6dLAJIvmc+GiL0Sk41TUx5IpxK5r XgSumTSUOWfralJ/SZNSzZQBW44IqWGsoE09RK+Aj3jlx7a9hVzISLA6Lfh1TMHo/7lm/zUGzrv qt3y+yA3sA/BfBJLMAY+N2BIyDl70NDpIMosZtBS24PM8YpTzl7NYA1XxC6E3juzOZhWiQ== X-Google-Smtp-Source: AGHT+IHaPbuitP8xm0ecTUWkh8xi/HrRNIf3CggRcGvS6rdpWF1Z9Hg/vbZ7BDj5hOJn3p4MaiCOOg== X-Received: by 2002:a17:907:1c84:b0:ab7:ce20:5394 with SMTP id a640c23a62f3a-ab7ce2185d2mr52209066b.1.1739185301868; Mon, 10 Feb 2025 03:01:41 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 08/14] iio: accel: adxl345: add freefall feature Date: Mon, 10 Feb 2025 11:01:13 +0000 Message-Id: <20250210110119.260858-9-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 118 +++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index b6966fee3e3d..56c5a4d85d71 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -84,6 +84,9 @@ struct adxl345_state { u32 tap_window_us; bool tap_suppressed; + u8 ff_threshold; + u32 ff_time_ms; + __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; @@ -104,6 +107,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) { \ @@ -354,6 +365,68 @@ 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); } +/* ff */ + +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, st->int_map) > 0; + + return 0; +} + +static int adxl345_set_ff_en(struct adxl345_state *st, bool cmd_en) +{ + bool en = cmd_en && st->ff_threshold > 0 && st->ff_time_ms > 0; + + en ? __set_bit(ilog2(ADXL345_INT_FREE_FALL), (unsigned long *)&st->int_map) + : __clear_bit(ilog2(ADXL345_INT_FREE_FALL), (unsigned long *)&st->int_map); + + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); +} + +static int adxl345_set_ff_threshold(struct adxl345_state *st, u8 val) +{ + int ret; + + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_FF, val); + if (ret) + return ret; + + st->ff_threshold = val; + + return 0; +} + +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) @@ -479,6 +552,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; } @@ -517,6 +595,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; } @@ -553,6 +633,18 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, const struct iio_ default: return -EINVAL; } + case IIO_EV_TYPE_MAG: + switch (info) { + case IIO_EV_INFO_VALUE: + *val = st->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; } @@ -591,6 +683,18 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, ret = -EINVAL; } break; + case IIO_EV_TYPE_MAG: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = adxl345_set_ff_threshold(st, val); + break; + case IIO_EV_INFO_PERIOD: + ret = adxl345_set_ff_time(st, val, val2); + break; + default: + ret = -EINVAL; + } + break; default: ret = -EINVAL; } @@ -934,6 +1038,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; } @@ -1041,6 +1156,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 */ + st->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; From patchwork Mon Feb 10 11:01:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967688 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 DD20A1E5710; Mon, 10 Feb 2025 11:01:44 +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=1739185307; cv=none; b=q2u8Kv+MK1L+LxARkWG/KheMaLOpetrnaBosBr/H+3eBBNL7BUDSbuPSlrVx16PllaCgRJBJ4TQ+DveWc0KEykr51xkcVdysqK7Hf+ujhDFeAWIavNW2Sd6aVZ94hx1xT1lVpMto//kBgq6I+bS1Eev8f+Tb2neUMdONA09QhQo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185307; c=relaxed/simple; bh=C9eyv9H/tjoxiNk52aq4T0byXJgoBJWBuTubeRNVlhE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=t2zlBKr4XIwje6tWlNeKYHq/kybzNU4ByEBUUIsqvygNB6qvi+st8Xbw8SGPE1GWQw5Kv38LWVa9by1zf/siT4C4kPysqtOczoyrHOZ9zXhGCgiZUQqvrM3dwP0hYOHIvJeSdxO4jofsX6+/fm5yAdlJQxc9TNtKir7ZItpLllY= 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=PiJcVO17; 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="PiJcVO17" Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-ab7c3d44ae1so9271866b.2; Mon, 10 Feb 2025 03:01:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185303; x=1739790103; 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=sQaAdDh8ES3cUCJoRDugQc2+aAH/Y7nrVOR0pZe6H9Q=; b=PiJcVO17cpHXHgAyzEybjgeD1/yQnbdEY6mQwvjQhuLfUSfmyPSEygvsr4uuP23hmr rlpgm4uw/1v/ugmSa0tDaVbFvs7ArYTCGLI090tV0KxcnPX6Eb022v4bYC/P8BXRVx8/ vefS7W8qPckwfqTwfhF+Gs+qA9x2eZMU71PD7SzzFFgqUast5giwOBWGpbxN1A3NHaKn zGxca8eWV0XPelZ8EhUWswZQPdyK03p6GK0QSME1i3gzOuWAc+Zb0lBvVB4wVsT3uEMM BDyAKjXVm7rK95jDHMK4EyvfJ6vYjS/31CNDEVSfhvZqYQ2KwAL2lWOh1gsIndhQMN1p QnLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185303; x=1739790103; 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=sQaAdDh8ES3cUCJoRDugQc2+aAH/Y7nrVOR0pZe6H9Q=; b=Gwe04ojxMZbJNJQ3Prntc9pL3LeFDCZmDyAyfaW8HF3GNVvDI9ANuaE8+c2TOM6Naa gkZHgG5gYw7zKClE78WOfVJ+vcZ6BWCC3omKBJ4UEirgl9244w+rJqy3chdllNx+PSqI C6VH9DLTIbiv+7Puk0XKsDbILszD4UiX0/JDsL+uFNmJ1HHBbZrc9gQH35jEK3e4J6qV Qqms7Umc0jnLpeVRbX2J+KhArhLPtW2JF03Va+XlvOAZqxWwV/7G8z4HaQSaQSYeYeJH 2xC/3jhksYcXpZEGVKdKncXQMeHCyc1EM8eIcQrS+PpSy/lVkI5iAp/Ww1hn9z+OxzNX SbwQ== X-Forwarded-Encrypted: i=1; AJvYcCV9U7SDzLD81ewzrp4DjtEhJ6xplgP8q69y3pyCFHeS9GLhE3+FtutCbKAR2tR1CRycFj+SFq5z6nOStgo=@vger.kernel.org X-Gm-Message-State: AOJu0YzZFZYBRihBC9WBeHeRdiolTHMdyYaFm3IMKeqvuQnCcrJfEjxC UHrCyV0lU8YYdRivIlIvfRf6UNsOlNao9NaSdCZex1937YvXpxAUqr9B2A== X-Gm-Gg: ASbGnctqOXGdmpyu3BQY80sTOEcnGrsvZUpLZAoWFK6qosvSqwR3RDGmkZsX89PEwJ/ X9xXMBtwcfOY6I8Ldu9GOFcWCxU6r96oLx4gotwRiRKgeHbUZBzLS1CaOPV04OtlkYc+iK6GaZc 7aKfjlyRYcJD6+gXLd7AXdkM0t0ZqPdW4tkxGGKduu5+tpoaj1bqDJBBtYBHw9/zbjgbC2/zLym bo2dheUD3JfFjC+d4HkAfsZbsfJmvShP+R0cYNg0WB39uFCSIQElKpBvxMNfylckYYsJt9nXYoc VdIRASsGLObWsvFYkoGRqL8BU2RTlkrWm/4lqADrCkiAgdsDqhbJl5ouBkCiQ5PsapGj+A== X-Google-Smtp-Source: AGHT+IEWhktb1mX1G6Pqp9P8f7zZAqhyn0TB5qODywow6LwAYB0fbla+6onmu/7QvFUB15AdAqCTBA== X-Received: by 2002:a17:907:9414:b0:aa6:9407:34e4 with SMTP id a640c23a62f3a-ab789c7f38emr477394266b.12.1739185302801; Mon, 10 Feb 2025 03:01:42 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 09/14] iio: accel: adxl345: extend sample frequency adjustments Date: Mon, 10 Feb 2025 11:01:14 +0000 Message-Id: <20250210110119.260858-10-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345.h | 2 +- drivers/iio/accel/adxl345_core.c | 163 ++++++++++++++++++++++++------- 2 files changed, 127 insertions(+), 38 deletions(-) diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h index bc6d634bd85c..0a549d5898c2 100644 --- a/drivers/iio/accel/adxl345.h +++ b/drivers/iio/accel/adxl345.h @@ -69,7 +69,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 56c5a4d85d71..08ad71875c5e 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[3] = { [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; @@ -77,6 +116,8 @@ struct adxl345_state { u8 watermark; u8 fifo_mode; + enum adxl345_odr odr; + u32 tap_axis_ctrl; u8 tap_threshold; u32 tap_duration_us; @@ -126,6 +167,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', \ @@ -427,13 +469,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; + + st->odr = odr; + + 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; int ret; @@ -469,15 +559,9 @@ 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) - 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; + *val = adxl345_odr_tbl[st->odr][0]; + *val2 = adxl345_odr_tbl[st->odr][1]; + return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; @@ -488,7 +572,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: @@ -496,20 +585,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, @@ -741,7 +834,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; } @@ -808,19 +901,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) { int ret; @@ -1094,10 +1174,10 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) } static const struct iio_info adxl345_info = { - .attrs = &adxl345_attrs_group, .event_attrs = &adxl345_event_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, @@ -1166,6 +1246,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, st->int_map); if (ret) From patchwork Mon Feb 10 11:01:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967689 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 779E31E5B78; Mon, 10 Feb 2025 11:01:46 +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=1739185308; cv=none; b=u1gQ2izf3Qzv+HHe2QZq7mTPkBAufipMlA8QLZrLTGAQnxUn+U8qzVTx/tbEQXC0SfigHZsUj/UjfBM3i3/3MwhKiLlOODdbPqxyptuWE/Rxej2fJA4zipmEKIfujgaaQBk/8UQD96wA9NBYEn4lugNVMKEGmR08cqW8MnUD7c8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185308; c=relaxed/simple; bh=AxduA5N6RniqLvGPR9UTTrkRiYuO3uiymx8fWSoHcWk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=J8TNDfFJWD1eP5ptvjUGF1aEsqNItJSrnDAQger54kwWMGqQiI03xpz8nsB6NnLpWt+pj17SWY1k/hfizLjgfsFBsuQpAUalSfacZavgc3PKiM0t8jlqjemoEaXZckBjlwXLCpLwOSkqGu8JViFpbyM6wIpqKP0ZPWY7T6li2AA= 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=kBQdzRXr; 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="kBQdzRXr" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-ab790ca8a87so47704266b.3; Mon, 10 Feb 2025 03:01:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185305; x=1739790105; 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=xLLUSJLHC8M+tnH5MickWN0AxH4wHkhY6ACxanQQxQg=; b=kBQdzRXrykQU08arQ/O9Z5obP1uMuUft1Vo1OETDFPZqwCLWwNmGt906iRFiUe4Ku0 884GtBT8Ka1T40mNMEaSepI9AUUZvev4NeWDRxUY6DFkgtVyMyBn7iehvW08MXcYAxT9 3/k2IK8Dl9VVsgG8vQY7yYbNV2As1QBcb6YqjFNstMGDlQVK2Fr3qQunywmon6uh00iL n668M/E1jrcGFIxNp8n0oxKwp36EK+nZbwogOXe+Da2eCrJmEd+UqO/BqVbXapzzVsUq MoWdzrUUz8hzkcqyla1ltze1ZX1rbH8mpBrVVLDaS/0pm3u7fiEM0jkeizQ5bfYjOYIe IwdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185305; x=1739790105; 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=xLLUSJLHC8M+tnH5MickWN0AxH4wHkhY6ACxanQQxQg=; b=lVFfOQDEYijuhs3SI+A3mptCoi2X/dl/Sw5BYX/w7otTzfk2OzskG0yzF9z/oJ4pNd ttP6uRX9OA/f5OAgY/ZPqj64wf/ZuzqpV8ywypUs46umUOvwtbe4tMyFDjOx+MEVCLvq hRUUV25bw4jW5JP7VGhr3fbvryBYEGPvxZ9UB/bie5M2Gl7YEGLMvvtDinn4YUFcO/XF FK1nCEVuaWcOOAQSdfw6EzYI+el21h5wgYKmZ47ovYO9SMTdLFrBM6CUdzsPDcxtPVF1 685KFN+las9CZGYYYe4H5lAK52MV6l7MoOu0CaqjDcjSjYZwem50AyqSMZtvuAePw4Jd axcw== X-Forwarded-Encrypted: i=1; AJvYcCUKgAnorNztRng+1XjHmJzJJ6d2TmR8rmCqRCOWLe9pqD4zAU92aiYCLlpv+LARVANTzCse6ocp1qgCdSo=@vger.kernel.org X-Gm-Message-State: AOJu0YzGVGPRgqhfasJMKQjlRdbBkI3mZsFbwnNibYO9PU/CXV12h1If Rvh4a8IEic2DUWsLOnFokVWtb9yyg0amty47hG8GMBS0y9P34d6d X-Gm-Gg: ASbGncvLI4JTuYlhE4JradNbMzglfKsiMqUdirJ6mJUubPcAyX2ZWSXU1nMlC7a815I uO/UFbaeuh+MvwTp27sDGJ/pqWVrcYf0i4yKKiHI4GsSIMDp9XDzI10tvwXx3bCbeSnIZqnnXbv 3t+b6GNK+nkW2UJLlyvvy5jByqaM7Z5pj40nLaJ69WCu6U4tZa6URRIAPh6Y10BlrvyeGoSa/Sc 2d9j+/GQaMe35OxhQCP+j/uL3Au2ibwB2eXKz2XnnPN/tzpWirPKVbCAywUw/+3a+Z5XOpGFNqe LP7Rfti9bsuqUCyG/7I/eG1HdW4m4JOza8pGkCYYCZKCBrmJVijUmaVBDNQkKyQa31sCGA== X-Google-Smtp-Source: AGHT+IFgpFy3p7nzaz1msT1PyoA6FpCcQy+53QvjnVfWBhWssskqUmKSu/trOzSipFwhugpqiPE45A== X-Received: by 2002:a17:906:c146:b0:aae:83c7:fd4e with SMTP id a640c23a62f3a-ab789cb9ee5mr518392666b.13.1739185304452; Mon, 10 Feb 2025 03:01:44 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 10/14] iio: accel: adxl345: add g-range configuration Date: Mon, 10 Feb 2025 11:01:15 +0000 Message-Id: <20250210110119.260858-11-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 | 92 ++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 08ad71875c5e..ea7bfe193d31 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; @@ -117,6 +151,7 @@ struct adxl345_state { u8 fifo_mode; enum adxl345_odr odr; + enum adxl345_range range; u32 tap_axis_ctrl; u8 tap_threshold; @@ -167,7 +202,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', \ @@ -502,12 +538,50 @@ 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; + + st->range = range; + + 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; @@ -543,8 +617,8 @@ 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; + *val = adxl345_fullres_range_tbl[st->range][0]; + *val2 = adxl345_fullres_range_tbl[st->range][1]; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_CALIBBIAS: ret = regmap_read(st->regmap, @@ -572,6 +646,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; @@ -595,6 +670,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; } @@ -833,6 +914,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: @@ -1252,6 +1335,9 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, * undesired behavior. */ ret = adxl345_set_odr(st, ADXL345_ODR_200HZ); + if (ret) + return ret; + ret = adxl345_set_range(st, ADXL345_16G_RANGE); if (ret) return ret; From patchwork Mon Feb 10 11:01:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967690 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 719AA1E7C16; Mon, 10 Feb 2025 11:01: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=1739185309; cv=none; b=K0dIj+PLbiKBQfBQqZLFGWI9Q6qbbFWUvs+LCKj258rfD6pNCTLYVznnhkBcLOwzi0P5dBW0yKRVVoeOHwasfyBIw4CXFSBgZWlpzC3uHhWvHvn52N+7nPI2Yg3Hge1LO3wvBlZLvf2kwmei58uvulwwBqKJEVHyO4/L6WBthwQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185309; c=relaxed/simple; bh=WJ1K0MV0GPmwUg78Q9UmVFYh1d4x/rscQtOAchEHEJg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YoE/o4f0YhgfzIAXKZFYF93l9O6Ki7AL5WT/bXQaITe7yIYebWzPfPJSlog1yDiFj7Qh0IQF0VaQyCQTJUWjJkZdly4D42szGnGxJ+2xnazcjiNav4ViZOTHU6MNFV3sA1ZlFdPGpYiQvlixpi7uslh70SgmiEULuUUgXKJuBS4= 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=chhO50G6; 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="chhO50G6" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-ab7bc75e0a1so25213666b.3; Mon, 10 Feb 2025 03:01:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185306; x=1739790106; 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=ypa1a9Q0yAlaKugbBVm1+t+T3QsoJKO1Wzke7d/Id+0=; b=chhO50G6deLpLp/M05qe25ht30dxWxmT5v9P6EuAy0qqDpe5p6GroY3nFb0oZmg5IW rQaRn252C1pTgKhckadfODohprLIeDG7Gn7lFNaga8C3xGPEwf0xbyb9i7ICypPbC+NN hN+BIXRJLYD3WIB3Vpk+6um+3xCFrc7fFKw3Is/bLwzP3RkmufCLFXjL6ItF1+bWjDsI by1gWq+x9Fnwcy/+7KL1vpcS2WaFH7uVP9rM7fjoIC9yWtO9sFkUWHRylLRquvS5QXHl w45pLQLaHcuD2BsgFUVd3YWaydK+qARf2v0amP2Yd7PVbpXzSB4bQ7tIeq1f/EQdCDvh 6uqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185306; x=1739790106; 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=ypa1a9Q0yAlaKugbBVm1+t+T3QsoJKO1Wzke7d/Id+0=; b=XdQuJWWcTDjiRvvKdzwY7T0h3olTLkyYCh/Y902Cz2DybhIy/cYzHeStxxbGDpsa+X suX/bVHCJ5gfH9n4/niW0bWs/4ihBn+DN4BuJOhcC4raTDriBcQ8DR9uPHJZcyYhgKRJ wfnLgfMd4HsgD45FoE5xhPbO0OBQM9uMRbD8r8jDcBhn8xZ0YcNcoNTTU+y/6ELnj4SX yav7wvtbY2QdPKNY+V64gnywsu4TxQ9/8NKRd0MxuiCyPFmmfngqWpZXbCn/visUqG1c zBlHFjvVZtv3+Q4UHcowWhjfQPPudeKyPvWy134LsaSlnQocb2C8eAWYYBDPTAcf5k+L 33uw== X-Forwarded-Encrypted: i=1; AJvYcCW3NDKryCXvUGSo3GeOMn3o5JqbZYZh+xz3bSvEBGeUuEkCFTBTqBGZ/0OjDcxRv01kdlnpCUKa4PaPI04=@vger.kernel.org X-Gm-Message-State: AOJu0Yx8UuP1/b6iKsc4PO171TaaaTfUcDQ7glhFKpkREDizIHlcDycY PKuV9nXXgBkZMphLGYYPLmGT1F+yxlEcPSHzZ8mhnK45jv4Rkqme X-Gm-Gg: ASbGnctnAxhnGvfOZB5CVwWX9AWFjkyZk63jau+VdCr10zWy5i2cdh7l8qxH5hCFwCW X2TwgpK7Jm+iVJOgRpDTDSCD2NG3aKnWOROegVVJEPkreWW7G7qKVMRBzMm5cB5nA04rp5xOhUr v6Cnv0HoWoMMp/QLk3ZD4EjCjHQabpSDdkFRd28s1po2dDc7TkOpvB93efZlkpA+yEMT4ZvbkcX SpUIR6XWuDeHoj6krBt0UbH6gCClsKCdl3+2mLEr0aBXI4eikjOK4rSrUCiY1dL1r553/1FKnmj L++HUt7T5aBcLTv893QDq9Kd/uUzucvMD3Ik2qheeJwXgXqWMf1/P75g5o3JDW7/Whiiwg== X-Google-Smtp-Source: AGHT+IETrOKcrKDHXefOo3dCvYE1hBgPLbS/J/hYUFWr7dcXR4kyOaMjrCekt8w17T3wG0s+8HA0Xg== X-Received: by 2002:a17:907:7f08:b0:aae:e684:cc75 with SMTP id a640c23a62f3a-ab789c35369mr511033066b.13.1739185305417; Mon, 10 Feb 2025 03:01:45 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 11/14] iio: accel: adxl345: add activity event feature Date: Mon, 10 Feb 2025 11:01:16 +0000 Message-Id: <20250210110119.260858-12-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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. 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 | 172 ++++++++++++++++++++++++++++++- 1 file changed, 171 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index ea7bfe193d31..16dea2a222d9 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[3] = { [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; +/* activity/inactivity */ +enum adxl345_activity_type { + ADXL345_ACTIVITY, +}; + +static const unsigned int adxl345_act_int_reg[2] = { + [ADXL345_ACTIVITY] = ADXL345_INT_ACTIVITY, +}; + +static const unsigned int adxl345_act_thresh_reg[2] = { + [ADXL345_ACTIVITY] = ADXL345_REG_THRESH_ACT, +}; + +static const unsigned int adxl345_act_axis_msk[2] = { + [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, +}; + enum adxl345_odr { ADXL345_ODR_0P10HZ = 0, ADXL345_ODR_0P20HZ, @@ -153,6 +171,9 @@ struct adxl345_state { enum adxl345_odr odr; enum adxl345_range range; + u32 act_axis_ctrl; + u8 act_threshold; + u32 tap_axis_ctrl; u8 tap_threshold; u32 tap_duration_us; @@ -167,6 +188,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), + }, { /* single tap */ .type = IIO_EV_TYPE_GESTURE, @@ -250,6 +278,84 @@ 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; + int ret; + + ret = adxl345_write_act_axis(st, type, cmd_en); + 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 && st->act_threshold > 0; + } + + en ? __set_bit(ilog2(adxl345_act_int_reg[type]), (unsigned long *)&st->int_map) + : __clear_bit(ilog2(adxl345_act_int_reg[type]), (unsigned long *)&st->int_map); + + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); +} + +static int adxl345_set_act_inact_threshold(struct adxl345_state *st, + enum adxl345_activity_type type, u8 val) +{ + int ret; + + ret = regmap_write(st->regmap, adxl345_act_thresh_reg[type], val); + if (ret) + return ret; + + if (type == ADXL345_ACTIVITY) + st->act_threshold = val; + + return 0; +} + /* tap */ static int adxl345_write_tap_axis(struct adxl345_state *st, @@ -697,6 +803,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: @@ -746,6 +862,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: @@ -783,6 +906,19 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, const struct iio_ struct adxl345_state *st = iio_priv(indio_dev); switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + *val = st->act_threshold; + return IIO_VAL_INT; + default: + return -EINVAL; + } + default: + return -EINVAL; + } case IIO_EV_TYPE_GESTURE: switch (info) { case IIO_EV_INFO_VALUE: @@ -839,6 +975,21 @@ 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 = adxl345_set_act_inact_threshold(st, ADXL345_ACTIVITY, val); + break; + default: + ret = -EINVAL; + } + break; + default: + ret = -EINVAL; + } + break; case IIO_EV_TYPE_GESTURE: switch (info) { case IIO_EV_INFO_VALUE: @@ -1129,12 +1280,14 @@ static int adxl345_get_status(struct adxl345_state *st, unsigned int *int_stat, { unsigned int regval; bool check_tap_stat; + bool check_act_stat; int ret; *act_tap_dir = IIO_NO_MOD; check_tap_stat = FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, st->tap_axis_ctrl) > 0; + check_act_stat = FIELD_GET(ADXL345_REG_ACT_AXIS_MSK, st->act_axis_ctrl) > 0; - if (check_tap_stat) { + if (check_tap_stat || check_act_stat) { /* ACT_TAP_STATUS should be read before clearing the interrupt */ ret = regmap_read(st->regmap, ADXL345_REG_ACT_TAP_STATUS, ®val); if (ret) @@ -1201,6 +1354,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, @@ -1311,6 +1475,12 @@ 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; st->int_map = 0x00; /* reset interrupts */ /* Init with reasonable values */ From patchwork Mon Feb 10 11:01:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967691 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (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 94D081E990A; Mon, 10 Feb 2025 11:01:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185310; cv=none; b=dDExxnBzmMjqgWrKVtebw3qYXnuwtEKjMENrh9l1CJBhhmJKeMN6icZgHU2mgAVI0iBYmn2q0AI1vbbTrYLKKKBHfqak4msRvHKfvoW9LILYgGMtdJtnCHRZmy53HPnANF4KhOM5tlYTL/JWSWZ4IPtm3u0aQGanS8vmgsWUHtY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185310; c=relaxed/simple; bh=xFCGQv3SGwTqSapsSEWJ0N08FlJruBGs76wdlSZIxhU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Kp4/PDoe0ajC/Atzmj5xI6z/UZ4rYRwTSldEHQ6YRUY7oQg58fbOZzFckvABw6yFFKo9T9/vVlDupc1inFzfiX38JcnTg/91g/tx58evuRno+A8SkOr4hMMYbzjm1bW6tLzH4srysP55VQHI1RDmh7SWUx+fUTydEM+Q9RROexA= 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=nqWxA1lg; arc=none smtp.client-ip=209.85.218.49 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="nqWxA1lg" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-ab7908ecb31so35115166b.1; Mon, 10 Feb 2025 03:01:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185307; x=1739790107; 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=RIR2sPvBWBJ32kfSECe1rNdqkZ/8/PBESSaLWMDqlxY=; b=nqWxA1lg7wgRPZ0Jpi3RRQB293eACfp/O/TwdakZ1bevjEwvWuThpOG+91965YBTjr hwB0Aba9QJJbwXMpYviOpugavBhVj/lRc1Q6jFUMN0Kkjrxov0oNLRldEReaq8P+0hBc f+oRa9z5b3OHJfzLuOIYhxM6QIYSWer0DHDcRzHNohGf0tGkPhwCL/CQKqND+G3QEakk wQmf4O+lLpLVU/LP27oTCZPsFjdU9AdI7HT72/zASZskhyHnllUObdnLWU1LaLZQxDu3 KdIc3rx0F0BxUbhzvo6RBhU7qtcy8OxvEZ71XU/DC3BafouJ6I/tUZV90yAP9t/XjTG5 mCvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185307; x=1739790107; 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=RIR2sPvBWBJ32kfSECe1rNdqkZ/8/PBESSaLWMDqlxY=; b=CTd/iILmI0M0vYh8fA9G+Z57Fzj4plyScjBQRU9fWZa0JZhRLMh3JJP0e4MoKmCzPA wrlrT2EKm9V2p3Zc5uDnJOburucxlx3ACxME+4a9waV0ZD2sRUEu49Jb57rAGNT5jlyq nD0sYBqhHaYJ4MZAeyf34t1o2JAdQZB5Fk42oXtLL/GzVvKpTxdVwtuy/sWa8tRh/Zit WUpx4CPTRKhRYjEze0R111LggKoc1kchXY1QidT2NZJgqlR/ezNX8hlH9Ab1BwGo0opE LMI6bjRopr1+Wf6z5RwwG80pgu2v9xq57V/dkQ6RZ+tOw33jcM6eS8Srj7i0qB/jaoby cwag== X-Forwarded-Encrypted: i=1; AJvYcCU+MbRV8o/ZONR+iwvr/L4RQU7H6O02W82VnLoMwskd+Q1PeeOeEsUplY+CuWYo9nbVDrSZaI2OiCZZqu0=@vger.kernel.org X-Gm-Message-State: AOJu0YwhOB4anI9YOzKSYU7rfe4dRDEpPwlNu2zL+QpA3kWIwCJOE041 X0CJcLJvhgMR+Ui7mFJaguE5HndqdTmZrtk3cAW9mmBx0JfERpjh X-Gm-Gg: ASbGncs9nXwUqv4z5/O/nsGmUbnQbjiz+2vkovZM2AGQirqx11jkVTs+rQwWQUpuJfj m7NhIQcNhTVZD85w3oHMxPlPi4PWJE9mvyTjO8mnvuOBCloAsmrsD196DJ94/5RYZGXcsZC8nm0 Lac6OXrELFR78+7MMD9pVV4dBmxJv0aSOwY+0e2Xtu73LwG3X6RQRGaBd+01Mcf67Ls4miBMrMJ N36RTNG5dkt9kwbk5E0pfSxdvtv+Oer/VJKZrm1g5wZsri87qKQfM47yLEZvmokhlTHBztY/SUz BBPRa6pyZV4+hD+Ve3j9ar/aNYuNhaGbUOAw7FCIhekLhNNA+hNj7ghS5Kiv7bqa03VkVA== X-Google-Smtp-Source: AGHT+IFZHhp+0uc6ye98f6pWt8fixbtYfy6EpFB95hPLyg0WdOAduUIHsequ2qV2RG8KkStiBluwiw== X-Received: by 2002:a17:907:3f18:b0:ab7:cd83:98bb with SMTP id a640c23a62f3a-ab7cd839b0amr54973066b.5.1739185306705; Mon, 10 Feb 2025 03:01:46 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 12/14] iio: accel: adxl345: add inactivity feature Date: Mon, 10 Feb 2025 11:01:17 +0000 Message-Id: <20250210110119.260858-13-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 is 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, 139 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 16dea2a222d9..7de869fac799 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[3] = { /* activity/inactivity */ enum adxl345_activity_type { ADXL345_ACTIVITY, + ADXL345_INACTIVITY, }; static const unsigned int adxl345_act_int_reg[2] = { [ADXL345_ACTIVITY] = ADXL345_INT_ACTIVITY, + [ADXL345_INACTIVITY] = ADXL345_INT_INACTIVITY, }; static const unsigned int adxl345_act_thresh_reg[2] = { [ADXL345_ACTIVITY] = ADXL345_REG_THRESH_ACT, + [ADXL345_INACTIVITY] = ADXL345_REG_THRESH_INACT, }; static const unsigned int adxl345_act_axis_msk[2] = { [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, + [ADXL345_INACTIVITY] = ADXL345_REG_INACT_AXIS_MSK, }; enum adxl345_odr { @@ -174,6 +180,10 @@ struct adxl345_state { u32 act_axis_ctrl; u8 act_threshold; + u32 inact_axis_ctrl; + u8 inact_threshold; + u8 inact_time_s; + u32 tap_axis_ctrl; u8 tap_threshold; u32 tap_duration_us; @@ -195,6 +205,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), + }, { /* single tap */ .type = IIO_EV_TYPE_GESTURE, @@ -301,6 +319,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; } @@ -324,6 +353,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 long autosleep = 0; int ret; ret = adxl345_write_act_axis(st, type, cmd_en); @@ -333,12 +363,24 @@ 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 && st->act_threshold > 0; + } else { + axis_en = FIELD_GET(ADXL345_REG_INACT_AXIS_MSK, st->inact_axis_ctrl) > 0; + en = axis_en && st->inact_threshold > 0 && + st->inact_time_s > 0; } en ? __set_bit(ilog2(adxl345_act_int_reg[type]), (unsigned long *)&st->int_map) : __clear_bit(ilog2(adxl345_act_int_reg[type]), (unsigned long *)&st->int_map); - return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); + ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); + if (ret) + return ret; + + en ? __set_bit(ilog2(ADXL345_POWER_CTL_INACT_MSK), &autosleep) + : __clear_bit(ilog2(ADXL345_POWER_CTL_INACT_MSK), &autosleep); + + return regmap_update_bits(st->regmap, ADXL345_REG_POWER_CTL, + ADXL345_POWER_CTL_INACT_MSK, autosleep); } static int adxl345_set_act_inact_threshold(struct adxl345_state *st, @@ -352,6 +394,48 @@ static int adxl345_set_act_inact_threshold(struct adxl345_state *st, if (type == ADXL345_ACTIVITY) st->act_threshold = val; + else + st->inact_threshold = val; + + return 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); + int ret; + + if (val == 0) + val = (adxl345_odr_tbl[st->odr][0] > max_boundary) + ? min_boundary : max_boundary - adxl345_odr_tbl[st->odr][0]; + + ret = regmap_write(st->regmap, ADXL345_REG_TIME_INACT, val); + if (ret) + return ret; + + st->inact_time_s = val; return 0; } @@ -641,6 +725,11 @@ static int adxl345_set_odr(struct adxl345_state *st, enum adxl345_odr odr) st->odr = odr; + /* update inactivity time by ODR */ + ret = adxl345_set_inact_time_s(st, 0); + if (ret) + return ret; + return 0; } @@ -672,6 +761,24 @@ static int adxl345_set_range(struct adxl345_state *st, enum adxl345_range range) if (ret) return ret; + st->act_threshold = st->act_threshold + * adxl345_range_factor_tbl[st->range] + / adxl345_range_factor_tbl[range]; + st->act_threshold = min(255, max(1, st->inact_threshold)); + + st->inact_threshold = st->inact_threshold + * adxl345_range_factor_tbl[st->range] + / adxl345_range_factor_tbl[range]; + st->inact_threshold = min(255, max(1, st->inact_threshold)); + + ret = adxl345_set_act_inact_threshold(st, ADXL345_ACTIVITY, st->act_threshold); + if (ret) + return ret; + + ret = adxl345_set_act_inact_threshold(st, ADXL345_INACTIVITY, st->inact_threshold); + if (ret) + return ret; + st->range = range; return 0; @@ -810,6 +917,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; } @@ -866,6 +978,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; } @@ -913,9 +1027,15 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, const struct iio_ case IIO_EV_DIR_RISING: *val = st->act_threshold; return IIO_VAL_INT; + case IIO_EV_DIR_FALLING: + *val = st->inact_threshold; + return IIO_VAL_INT; default: return -EINVAL; } + case IIO_EV_INFO_PERIOD: + *val = st->inact_time_s; + return IIO_VAL_INT; default: return -EINVAL; } @@ -982,10 +1102,16 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, case IIO_EV_DIR_RISING: ret = adxl345_set_act_inact_threshold(st, ADXL345_ACTIVITY, val); break; + case IIO_EV_DIR_FALLING: + ret = adxl345_set_act_inact_threshold(st, 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; } @@ -1365,6 +1491,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, @@ -1481,6 +1618,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; st->int_map = 0x00; /* reset interrupts */ /* Init with reasonable values */ From patchwork Mon Feb 10 11:01:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967692 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 C75001E9B16; Mon, 10 Feb 2025 11:01:49 +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=1739185311; cv=none; b=AUoLXV7o7Sz880RlI9J08IiLmbRBua/Jvd+oEZcZXs4wB1Ow7CkoXQ0hTsUN75zgm7qSyTFZnSwPdRfSR7jPut30ooRWj2hFJNuDqRTJkYdukW0k3VK+NXxjrBP70x9b6W0e3SY4cu+MUe0QoFOQ3y7PDAwgYKM+Qr1WqrOWEZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185311; c=relaxed/simple; bh=K0sV5QSjbhEFIMidR+0tRCTJMWhpB/o+wDTXEIOQwSQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=O91JRh3h2DEVy3UVMv8f6tVSWDjd50rcgondSHld9eMze5ReHv7jTY8vQ1rL8t0AREv8BKCw6+smczvXsymDz7WvMZbufuL0E04M5dwYB/75hVGRuAb9Khki1TEJP1ZowS6kq2qrqKPncCPV21DaKExTmFgKJ3CeRGTlNX5EpHE= 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=dwCd9UHS; 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="dwCd9UHS" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-ab7bccf51e7so7562266b.2; Mon, 10 Feb 2025 03:01:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185308; x=1739790108; 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=rlPwq+dInNhuHvPpkG98tgUSzMHb+EZ1EHAvrMdmAVU=; b=dwCd9UHSKRudE3IsrkKxys0SbVGhmd+HEMlxXfGJ88E+Np/5uD77rLsyDNvmc302nW UehtwnQkR6RhjHKN9H9FHc+IY5nZoniGl6ETFxHZAxJREdnsKr7GiuO4GjXEiJFXbQmG Us6oLNmYNGWOuDtPOuHvapZRscBl1Leqor4wl3BgmhvzGzdCjwtDGaIvaQQ1iTGXfupr xSgDh9TjFCNuo4Llnt2U74clzpmH9VSYZXTmhAo33NpCIwVYlXuA5NiQwR7DdHwhjmSp xVDjusSJg93dOLdlVhlMhjCsD3F267ZOriQKzFFZgRjl42UI8d2S73+k6iV0nYEzUz9q aqBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185308; x=1739790108; 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=rlPwq+dInNhuHvPpkG98tgUSzMHb+EZ1EHAvrMdmAVU=; b=SaIbKtllqztZalGT+TJ9EDCqK4BF44Ex9s09Kx3dw6kGVmhQPGGEyNJgeI/Gvl9sgN fp/vAEk7MknlLVFUJ2MSiotQIj6NO67xaXkgqZOLNKDFM+wmHNIr8DOFtTDAogUyGiu3 1SYSYpqI3ylsXLsqeoOjvEpj3T0ifTD9hXDaWxNd3NLog33/6jjcHvNBnOWeikIdqzXh XiDArqL0BCkOoLiZoZv6pKxYQ0o7JGrjENMdRAkB4CieUkv1r4CTrNPM08/fAO68Cze5 KCsr5XsVOyH23w+mOr3RiNz9f4bQm2/dCXQ0lbTvP2rB6aypuedlgND392c0r5WwwgGU b4HA== X-Forwarded-Encrypted: i=1; AJvYcCW1InOKs/Gfg8ss4OiswuMKdiNinfgmMfik8XFn+or5BBXTaaHQtQSUIvfDAPnQziys8m2Wn7utz/crk/I=@vger.kernel.org X-Gm-Message-State: AOJu0YyZ2OJ5uU9VVqDNF9OIEHBvTuYV2ECPLZx0rS1OLrAriqorl+Yw LuW8IyNehbSn/4idzV/HPRkgdO/chPQcqUnksVA0BJmQp2ai1wN/ X-Gm-Gg: ASbGncsevp0gFA/z4hYmSiW8OMvhLqQZa/4RuxXC/7gBYiYaboGQe312V6yCpaJh1kb yDm64n3Rwd8xP4nhBAfncw4yWHJEENARJkmW1c8MlVfISAYgSqoPhcg16+++J2Fs8CcM1DnVzDz 6DgNRi4hBWRyBDbXRR3znUu0guYjOUgOlX2ZW/eWgrDJ+Cm5Si+WdfxEODSs0dR/hwrL/AvRB4l nhPGwNjxQWJIn2MvlBufRAiDRkzEdAJ2zdQGg3fx2XAiWPJ9OLzFFHnJdKnszm4BfR43sospRY8 zuJihk+tcb7nFUcIaGQGAQ/XilLWCuiKLBTMynYlU3OTFSCtqlnN4JvXsfaB5hy6hA8TOA== X-Google-Smtp-Source: AGHT+IHzmlS3SbYLfzqN4CdGIBdVOXRr91akJDYrtVdYWJztPT9Cl1f1Sgrdgd2FsAF6WgudGarVkQ== X-Received: by 2002:a17:907:1c9f:b0:ab7:6056:7a7f with SMTP id a640c23a62f3a-ab789c5d22emr524033266b.9.1739185307816; Mon, 10 Feb 2025 03:01:47 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 13/14] iio: accel: adxl345: add coupling detection for activity/inactivity Date: Mon, 10 Feb 2025 11:01:18 +0000 Message-Id: <20250210110119.260858-14-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 7de869fac799..411ae7bf6b97 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[2] = { [ADXL345_INACTIVITY] = ADXL345_REG_THRESH_INACT, }; +static const unsigned int adxl345_act_acdc_msk[2] = { + [ADXL345_ACTIVITY] = ADXL345_REG_ACT_ACDC_MSK, + [ADXL345_INACTIVITY] = ADXL345_REG_INACT_ACDC_MSK, +}; + static const unsigned int adxl345_act_axis_msk[2] = { [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, [ADXL345_INACTIVITY] = ADXL345_REG_INACT_AXIS_MSK, @@ -178,9 +185,11 @@ struct adxl345_state { enum adxl345_range range; u32 act_axis_ctrl; + bool act_ac; u8 act_threshold; u32 inact_axis_ctrl; + bool inact_ac; u8 inact_threshold; u8 inact_time_s; @@ -237,6 +246,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) { \ @@ -334,6 +355,35 @@ 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) +{ + if (type == ADXL345_ACTIVITY) + *ac = st->act_ac; + else + *ac = st->inact_ac; + + return 0; +} + +static int adxl345_set_act_inact_ac(struct adxl345_state *st, + enum adxl345_activity_type type, bool ac) +{ + int ret; + + ret = regmap_update_bits(st->regmap, ADXL345_REG_ACT_INACT_CTRL, + adxl345_act_acdc_msk[type], ac); + if (ret) + return ret; + + if (type == ADXL345_ACTIVITY) + st->act_ac = ac; + else + st->inact_ac = ac; + + return 0; +} + static int adxl345_is_act_inact_en(struct adxl345_state *st, enum adxl345_activity_type type, bool *en) { @@ -959,6 +1009,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, &int_en); + if (ret) + return ret; + return int_en; + case IIO_EV_DIR_FALLING: + ret = adxl345_is_act_inact_ac(st, ADXL345_INACTIVITY, &int_en); + if (ret) + return ret; + return int_en; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1008,6 +1073,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; } @@ -1619,6 +1694,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, */ st->act_axis_ctrl = ADXL345_REG_ACT_AXIS_MSK; st->inact_axis_ctrl = ADXL345_REG_INACT_AXIS_MSK; + st->inact_ac = 0; /* 0 [dc] */ + st->act_ac = 0; st->int_map = 0x00; /* reset interrupts */ /* Init with reasonable values */ From patchwork Mon Feb 10 11:01:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 13967693 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (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 2C87F1E9B35; Mon, 10 Feb 2025 11:01:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185313; cv=none; b=bseY8fznB09cWVGdnsspC8OhaKyhFV8Su4EqNz+hxZ1vaXgGHfhxyKjdt7n4ux2b/3CP4DcKwSiphZb1w6ynVXUhAPDu6OL4nEcaFTNXwC3mtj5WJju0lTDjhHqEYxlP3Hnnl57Py1keGIrgbmW6VDPOA6ohd8FNcv505HhbZqY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739185313; c=relaxed/simple; bh=GlyJL0XcEZn35HrmCL7Gqq32/0jqKuhsK3eNZ05OVFY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=JKqRGMXtoGOBjPWUjPPmup/KCVwx23z83Dniyiu95F2Tom6yEn6G9NwXeGDYMKlMDRa1MIpLhtpTaiFhgMrPS3w/00P0ZoDUJkZp4T/fJ26HKA9EgAGz0rvgZVm4XakcesVnP7diplbiWda1IqnTGE72p8sjARegg0QdbS9KznM= 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=NI1hNaNU; arc=none smtp.client-ip=209.85.218.50 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="NI1hNaNU" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-ab7098af6fdso62385566b.2; Mon, 10 Feb 2025 03:01:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739185309; x=1739790109; 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=Eg3WX7zSGjkgXlf4rAiA779+PjmRt/+Yy3S/yTRAhRo=; b=NI1hNaNUkYSnjNTIgR214dHlTrptIt2qocACxGKHGBzkl17FZGGLGEFk/YFEpWsO3v Ko1XOOexE3Pogdgfdj1BnQNxKj0zVM2LOwyVqYPAJnthXoiGib3JoKVqHnqaJkEsYQLk ZgGu/2irj5jX3Eewd+Ejq2dsnDWOeM5x+YqQrBg5oqRieY3cYCcWaFjmUsLLIZkntEN0 +U/gw+y2ZxjOGYtV8eUdZnrti5HIfcZeja8HBJLraW9t4WijhfZArCqJN299lqTvjlvi fI1CNalb1FWkS/QttaDstTqHL3tGTz9FdZO+qSTjYotIgBNt7PupnlEmBHxbh+NqGTpd dEgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739185309; x=1739790109; 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=Eg3WX7zSGjkgXlf4rAiA779+PjmRt/+Yy3S/yTRAhRo=; b=mWV+MOkR4eoXht0v3gZd0dpKDV7sPUFq7v9eJ1d4Ge+HTN5QnghHjOurLsMFG4vKkZ ASqfsBqeFsYQgARLpjr7zg0c4ksZDgy0UJHQqLFBGbRGMJkUtK7p2iZNQi5GBiK9MKRT nMZMuMQOTmnyECF+4lFoQ2bJQ8Z1KVnQGV0P5fpRXj128JXro+GTc/WS/yZ6+KpIIG6r ZlcqJK5qcjFCxn3fz+hjTb22JYHry/eMN/8w5iX5IwmWXXJjCEMqu9LQPJvgGZpXwvdo DLK7kDSuhFXRj2iuaexQnh8lxtRXeka5h+7NPaZiiirC6bXob4IABC715BgvWxSlqffe OecA== X-Forwarded-Encrypted: i=1; AJvYcCUcIfbRHTGULUSxuSp4HKOhHeBUnAyHMnx/qQV72hAVHmqqDSw+1hNIBthI/n/oHw+FaPdUGHcd6i9gYtw=@vger.kernel.org X-Gm-Message-State: AOJu0YyINsQCleqDx8Hlqf9pr8H0t63o7kMlHd2gCT9/7WQQ3sFvec7x S8sipfTLjUbrBChZAyWEMILOXrANNDgN1nfxyM9NRckyFT4H5dEbS9/a5w== X-Gm-Gg: ASbGnctVMHLKUUUPz6NVNxYW/MQ0ElnGAgSidLVdseMiMYI5GA6hS7is+amNYaAXYAq Iotw7YCTzR7J4fqCkmKlMyxg3qxEz2BRQAqQDmbQYVVCl2jHNBHX4WEthjTJWBm4vDUb76uKMd5 TAAmN580IYzEZJwGA0iTnjZNgpCN/8B5ihrs7RJRSX7CB4dnlGS+Q1zhqgUjfd7Uj6VAHYhzMDD ll1VVZ3+TPTWlkqRflMPeh1ehw1sqsv/Bl7bYzb6xgkdEJsbjw0zFuuSnLuKwIRI2ptZCbQOacM EW278NMmsHKZWAlJxlmGzNqIiibPI94RACMXA2AaCmKBDhwGrNKwxC8YMGpVNLfrIhgDHQ== X-Google-Smtp-Source: AGHT+IGM7pZbuhIIL+b4CAZgrZNcn862gyinyl4yFc4Vp+PU6cVXpQ1yiKBgVUMhil7E4pWImkJzWw== X-Received: by 2002:a17:907:36ce:b0:ab7:63fa:e35a with SMTP id a640c23a62f3a-ab789b22caamr490199966b.2.1739185309000; Mon, 10 Feb 2025 03:01:49 -0800 (PST) Received: from d9dabf0abd47.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7a5a78369sm486987266b.136.2025.02.10.03.01.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 03:01: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 v2 14/14] docs: iio: add documentation for adxl345 driver Date: Mon, 10 Feb 2025 11:01:19 +0000 Message-Id: <20250210110119.260858-15-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210110119.260858-1-l.rubusch@gmail.com> References: <20250210110119.260858-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 | 401 ++++++++++++++++++++++++++++++++++ 1 file changed, 401 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..52bea3e7c4ac --- /dev/null +++ b/Documentation/iio/adxl345.rst @@ -0,0 +1,401 @@ +.. 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_suppressedbit_en | Enable double tap suppress bit | ++---------------------------------------------+-----------------------------------------+ +| 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 couple inactivity AC, 0 for DC | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_referenced_rising_en | Set 1 to couple activity AC, 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 enabled, the driver automatically will +set 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. + +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. + +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.