From nobody Wed Oct 8 02:16:10 2025 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 8141224468B; Wed, 2 Jul 2025 23:08:26 +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=1751497708; cv=none; b=jHOIRtNdSL1COUyg3jJn2vDXGebomqsp3YCtbVYRwjc3Jd/c+5F1KsqxtkdukL0fVXXZcqsVlNphIi76aQqRLmcU0fOMHgYvAyBdtpGBqBr4JNRRqTOyD74oAlV0awn4ChEY5I5FEOa9VjJu2Dlvkpw5G5eQ+ZXB4stfqs5lXgo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497708; c=relaxed/simple; bh=Z2XacSIID+4lkYZM56GjoTT4Y5pbDnIpPBGUC1jJzOk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NIBaYS2QtPd8RLwkH7+r4gO6NJCw8MuIE4Q11yfgL6MczM7fDNUxZI2UpF/G+Dq6UO538DLt7OytanN6NmKpWgnSG0TByqfMu+ZMPt7j268N3QmNgFVAoRkdONf51d9aFgc97rx5eiCMjCmB9WP4VrHPMePn5bJjCLevAFF4GMc= 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=YSb3wCQH; 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="YSb3wCQH" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-ae34f43be56so76265566b.2; Wed, 02 Jul 2025 16:08:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497705; x=1752102505; 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=7BwLEP9LlzZdfUMh50cIBwDtf2I1quEhp+zF9nPrh4w=; b=YSb3wCQHjisywLOaXoEmS30FbNOAS2kXC9xbZRc2ZtF/APJXKyJ1/agQ8Im2JByzAp 07yBIUOhp6MfZurQZerKCmMYoPBrftp+DygHenVCLvDGoR1irQkriMa8gM6I3b5HJyFO Afi7+OLnk65gyWow3o4xpK0APJUL2/TVOKprfJbpBn5aHxhOq6RGDmX+EvZKu/qQrME8 qaiokBmcPIuAyQdqDdDsjovoDDvRL9MDfRSm+5IXpY5MKBQQB5+ZEPnArDVtIW+MPBI5 p9wuCjH8mdvxIOWnMaq8E92xpz45R31U0KM+dShdkf5lqvUmSSZA+8rTJWlDejhJ8SLG BnKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497705; x=1752102505; 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=7BwLEP9LlzZdfUMh50cIBwDtf2I1quEhp+zF9nPrh4w=; b=rUpAK+9GOz5YtWe6qqj63ifZq7TyTPJnhwiABKlaT5y1+XU9WxWL2bJlKPW81v95Jn H65BBr+B+/7JeaAa4F9mfIOzt/XbZO7u4GiSZTHBm47EvYlQTsqQTlvkZSEAQ0L5mg5P VMgBFaEBXnGQAu+8bdqOgzYgnZavTwcNW5Ae8XbUcScDp6wH9oqhx0nm+fzBFHqeZHj/ QVRUdmaB6gmceKO4j6jK68E9cg38kOstNCZMET5YA+l6pTyf81oij7XXqa7bEHov7+bP PYSI8C7lhfXmxnbrge0T+7cQV75Dw4CChLgYk2XI0zBSiN7Ab8E/kZYsyASkPdjNj8F6 t3zg== X-Forwarded-Encrypted: i=1; AJvYcCU9JuWM//qFeHqp6CTUs38f06p9HmUPHcPMXjJewVeRhiXFjXUvc7ratyNlVU3hhZ4LyMw5hrv2ayaF@vger.kernel.org, AJvYcCVRVRzp9gScl1RYu65n2s7N/g+rjGeX1SMSf/FkeAJo0P+oRyHUj9g3y78yEiLWCWFKuasWd46CssqYrIup@vger.kernel.org, AJvYcCX6W+pZiA+PEyicTN0tZ3DjqoEGPXJyrp1jvWjCgDgyPSLP5Hzem4CJueOj3wShG2JksgwyaH2LSQQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzKHstv5RawTdDcWyQ/ZnxegfBZKFb3UK4suPTNRBISKw1yONQS kx/bMJuHJOENMOtkv6a8j9MCFAIcLtIDl2JSEFoKoF6yV01aHtzx+dPV X-Gm-Gg: ASbGncvgiwzNCLAcbOtntsL4PvEggMWw3AEowt+qlULhUwO3N+r+byjNEhz64TFTJIs 3ueks5Iq6/oZ/SZJ8MDe99HqSPcAsa8atMwivngDO5VB/kVxhJykSjXXFuFMjwdVfBVh/xCBIir ISnsoVHZoesUseQbej1izKOc1lWH9voq/RjVevGIeeF3iIBTBOfo6Zt2bWPYrWwqP5hfUN98lQV 0TpxkyboO1h7aWl303OoXOQhtExViQ6wJ0USy13YFfBGbDjNANASHaxtbT+SYbJr66zOZvaiuaP vQkHIgcyhybc3vj2x5sijRKsnrWU9Yy6C0qi6fle3UX66o8akKG7LvSCPwbk5xRubeOT9g5iwXy 6UZg49oB1as/gxa1CIfKW86HCyQUIH/nK X-Google-Smtp-Source: AGHT+IFt9r/Kfes1GR3sPNDTetl98lRZVJOGcdXz8SB8ozOVeo0OmH7OUn9i5Uur8BS/o+qA8l4AZQ== X-Received: by 2002:a17:906:6a10:b0:ad8:8f5a:9d2b with SMTP id a640c23a62f3a-ae3e2a2a444mr3789066b.16.1751497704653; Wed, 02 Jul 2025 16:08:24 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:24 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 1/8] iio: accel: adxl313: make use of regmap cache Date: Wed, 2 Jul 2025 23:08:12 +0000 Message-Id: <20250702230819.19353-2-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Setup regmap cache to cache register configuration, reducing bus traffic for repeated accesses to non volatile registers. Reviewed-by: Andy Shevchenko Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 3 +++ drivers/iio/accel/adxl313_core.c | 18 ++++++++++++++++++ drivers/iio/accel/adxl313_i2c.c | 6 ++++++ drivers/iio/accel/adxl313_spi.c | 6 ++++++ 4 files changed, 33 insertions(+) diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h index 72f624af4686..2bc86ac8ffd4 100644 --- a/drivers/iio/accel/adxl313.h +++ b/drivers/iio/accel/adxl313.h @@ -22,6 +22,7 @@ #define ADXL313_REG_BW_RATE 0x2C #define ADXL313_REG_POWER_CTL 0x2D #define ADXL313_REG_INT_MAP 0x2F +#define ADXL313_REG_INT_SOURCE 0x30 #define ADXL313_REG_DATA_FORMAT 0x31 #define ADXL313_REG_DATA_AXIS(index) (0x32 + ((index) * 2)) #define ADXL313_REG_FIFO_CTL 0x38 @@ -54,6 +55,8 @@ extern const struct regmap_access_table adxl312_writable_= regs_table; extern const struct regmap_access_table adxl313_writable_regs_table; extern const struct regmap_access_table adxl314_writable_regs_table; =20 +bool adxl313_is_volatile_reg(struct device *dev, unsigned int reg); + enum adxl313_device_type { ADXL312, ADXL313, diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 8996180f1e18..dc5f04b17b29 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -46,6 +46,24 @@ const struct regmap_access_table adxl314_readable_regs_t= able =3D { }; EXPORT_SYMBOL_NS_GPL(adxl314_readable_regs_table, "IIO_ADXL313"); =20 +bool adxl313_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ADXL313_REG_DATA_AXIS(0): + case ADXL313_REG_DATA_AXIS(1): + case ADXL313_REG_DATA_AXIS(2): + case ADXL313_REG_DATA_AXIS(3): + case ADXL313_REG_DATA_AXIS(4): + case ADXL313_REG_DATA_AXIS(5): + case ADXL313_REG_FIFO_STATUS: + case ADXL313_REG_INT_SOURCE: + return true; + default: + return false; + } +} +EXPORT_SYMBOL_NS_GPL(adxl313_is_volatile_reg, "IIO_ADXL313"); + static int adxl312_check_id(struct device *dev, struct adxl313_data *data) { diff --git a/drivers/iio/accel/adxl313_i2c.c b/drivers/iio/accel/adxl313_i2= c.c index dfa51860cd83..b67ff0b4dc54 100644 --- a/drivers/iio/accel/adxl313_i2c.c +++ b/drivers/iio/accel/adxl313_i2c.c @@ -21,6 +21,8 @@ static const struct regmap_config adxl31x_i2c_regmap_conf= ig[] =3D { .rd_table =3D &adxl312_readable_regs_table, .wr_table =3D &adxl312_writable_regs_table, .max_register =3D 0x39, + .volatile_reg =3D adxl313_is_volatile_reg, + .cache_type =3D REGCACHE_MAPLE, }, [ADXL313] =3D { .reg_bits =3D 8, @@ -28,6 +30,8 @@ static const struct regmap_config adxl31x_i2c_regmap_conf= ig[] =3D { .rd_table =3D &adxl313_readable_regs_table, .wr_table =3D &adxl313_writable_regs_table, .max_register =3D 0x39, + .volatile_reg =3D adxl313_is_volatile_reg, + .cache_type =3D REGCACHE_MAPLE, }, [ADXL314] =3D { .reg_bits =3D 8, @@ -35,6 +39,8 @@ static const struct regmap_config adxl31x_i2c_regmap_conf= ig[] =3D { .rd_table =3D &adxl314_readable_regs_table, .wr_table =3D &adxl314_writable_regs_table, .max_register =3D 0x39, + .volatile_reg =3D adxl313_is_volatile_reg, + .cache_type =3D REGCACHE_MAPLE, }, }; =20 diff --git a/drivers/iio/accel/adxl313_spi.c b/drivers/iio/accel/adxl313_sp= i.c index 17b25f3b2027..cb6a676ec7a0 100644 --- a/drivers/iio/accel/adxl313_spi.c +++ b/drivers/iio/accel/adxl313_spi.c @@ -24,6 +24,8 @@ static const struct regmap_config adxl31x_spi_regmap_conf= ig[] =3D { .max_register =3D 0x39, /* Setting bits 7 and 6 enables multiple-byte read */ .read_flag_mask =3D BIT(7) | BIT(6), + .volatile_reg =3D adxl313_is_volatile_reg, + .cache_type =3D REGCACHE_MAPLE, }, [ADXL313] =3D { .reg_bits =3D 8, @@ -33,6 +35,8 @@ static const struct regmap_config adxl31x_spi_regmap_conf= ig[] =3D { .max_register =3D 0x39, /* Setting bits 7 and 6 enables multiple-byte read */ .read_flag_mask =3D BIT(7) | BIT(6), + .volatile_reg =3D adxl313_is_volatile_reg, + .cache_type =3D REGCACHE_MAPLE, }, [ADXL314] =3D { .reg_bits =3D 8, @@ -42,6 +46,8 @@ static const struct regmap_config adxl31x_spi_regmap_conf= ig[] =3D { .max_register =3D 0x39, /* Setting bits 7 and 6 enables multiple-byte read */ .read_flag_mask =3D BIT(7) | BIT(6), + .volatile_reg =3D adxl313_is_volatile_reg, + .cache_type =3D REGCACHE_MAPLE, }, }; =20 --=20 2.39.5 From nobody Wed Oct 8 02:16:10 2025 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD9F22571BC; Wed, 2 Jul 2025 23:08:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497709; cv=none; b=KSnisUD8cug3ivFtyQSmra76d6FyPqCM0Lk9LoB2Bfdaj/i9Kmwb6VpGG59kgr+R4TNtzeovuxXWUrn/OEDrVUGifpQnR7FeRmgPr4McwV9h7jWv819p7hnvDe6V+bQF1joKRAMrFRI6BSAsBXUwDk50Rvz1ETSKqKhAR7XSCfs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497709; c=relaxed/simple; bh=PQAXr6S0XgAhcSXyOgP43eWGaYqusaaZxS53WQKRVDM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=odfoaDvLESiAgTsF8BJ1VzNIDH0OS5T8n6IyYFAtJaJBm8DoQiPssP7F0uTr18EcIsoBx6IZZKSgWtDl41bYl9VoSX+z26wXp5oaThKxK6y//hnJeUlRstrCkleOANxlGAGfOakSZ0cpbhngg9FyugQd//IpH5AymPR+hooLTlU= 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=NDsWE6ku; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NDsWE6ku" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-ae3521a129aso92911066b.3; Wed, 02 Jul 2025 16:08:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497706; x=1752102506; 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=w59lrAsElaWPPoAR9eeFoQ8em27eHSnFV7gwNhlMmW0=; b=NDsWE6kuFHw9WKwQxtWGghDXWMpyIBVixtpU+vYFyQz1sRmvFf48QYnbp/7wz7jO2h NKLAHQuomWgyWJTS4qEkz5aQunRBJUtMvVwtDqAiVDZmaRoISSFaWwFDfW/DrstZzGmx 39v2IA4XgMm86F/tsBirL9JYgC7rnu3EIhLdt3tQD1OODykF9F5pF462RpjstvGbLxos 0SWF8/yNShi7jKr1O8AmPIhdm9eF4bxV894PNJNoFhCAcLgSIxh2Jzj2u9fNLDh0mFF6 FL1GqxDvAjhHnvgtkKbMYTCgsPiLZ3yr+gBF9CcLHCvEqB6GEe/LkqFYXiDPnSd8gmzC fzgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497706; x=1752102506; 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=w59lrAsElaWPPoAR9eeFoQ8em27eHSnFV7gwNhlMmW0=; b=lT7byqnJNCemb6q47eG2pCDq48sOLC7MsIsRM0seh0Zt+dSWCZB443QRo6M4+ZexHk IZU38/BvyGc9lv+/L+xnGZKRfz7zQ44BIl0D5FlPby6nm9fjhzb8+DAXat45TRwPCOgn 0L3wUMGMOeSx8UavijNf3bHF7ALtr52kXYdHhEvg8r2HsQHr+5HayNEx5NoiAexwulIV dmTWAdpgh2HWVlX8ETxUlDnMOFZO258vBvPKpDBLmPgGm8aP1VQTrJkYtW9hjBife0Wv HpyOfEWA9OK58AFl4RTPFWaAmuiknN8QE1dA8/GnlpLks6tPH+wKy8QQgcQAVGc2zs0/ doqQ== X-Forwarded-Encrypted: i=1; AJvYcCUxEJpLJgP8QFy88PE6OhC+bdA5gflfh+R1PUcx/MOVH8Q24fbq4+poG6FrVewLQF56J0VXV2FMby4VH7w4@vger.kernel.org, AJvYcCXSZaCndCVnRAyqmTNgNmQ3AvFirugwTJiDrweiqqd/ma3MtI4N/Y0TM4OsRcRwGfQ5zyZsEvlqj1c=@vger.kernel.org, AJvYcCXrFJscaAOpgSyrq51SphvVX2l5a961J4gUd0MnWfrfS66rgbQn8RczAlKw0Tg50VzLNyOTzwGTXvAB@vger.kernel.org X-Gm-Message-State: AOJu0YyxwIz/U8OVzgf2LeKIclvZUlj4zvGMLE6UzOlU0F8ZNo9MRwLP C+1qT0DyA72j8pnLFdYjNIg0TqvOVpDu2BdYbT/tN5hMuDCDwf6/Zh9Q X-Gm-Gg: ASbGncuLfZZYZZG95SyX2ikz+URwYmg/yShp2UVdAT5hlwVgNoJo8236aM5HH3eNsc3 YGBBVq2/VbKE4TLMX5pD9IiovO5EauPCeTbzZa5m8xzfZDA5SiahqHdW/2THg3bzFH54hsvWW8h ZCpbBu5f+ZvZltJ9Dq9E8iMPZkMoIS4QTQl/pnGLIobikdt4UzkzX5UJccJpXTwEFt9g75ZOBE7 4A5hOxEU8gsmi0xX7RSCXScr1S4/2VgTVqIlV9YOHFF4xF+DtiAywSQdXgqrfKpbzwohMp3A3go 3Zv/tPxfTBW9MWYf4vInGtTasgQTOVHVLTBTBs3AsbjMEP5bRvKc2N5OlybiHMnhzHebqn5SpLW WStnjvCYAI1pcZTyappndMRwIowdoXaHm X-Google-Smtp-Source: AGHT+IHgbc0eU93Rys9qxb7O4vEqYNJOnowhFeldLswrvAa+eYchLBwyICmMgYOlmvXcTbPVEATEaA== X-Received: by 2002:a05:6402:321c:b0:60c:45fe:c6de with SMTP id 4fb4d7f45d1cf-60e764fc980mr20734a12.0.1751497705855; Wed, 02 Jul 2025 16:08:25 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:25 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 2/8] iio: accel: adxl313: add function to enable measurement Date: Wed, 2 Jul 2025 23:08:13 +0000 Message-Id: <20250702230819.19353-3-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Refactor the control of measurement and standby modes for the sensor. Instead of directly writing to the register, encapsulate this operation in a dedicated function that handles enabling and disabling measurement. This approach will reduce code duplication wherever sensor configuration changes are required. In subsequent patches, measurement mode will be set to standby as part of this process. Additionally, simplify the control mask to include only the measurement bit. The sleep bit governs a different behavior=E2=80=94putting the sensor = into sleep mode, not just standby for configuration=E2=80=94and is currently unu= sed. Therefore, there's no need to include both the sleep and measurement bits in the same mask. Reviewed-by: Andy Shevchenko Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 3 +-- drivers/iio/accel/adxl313_core.c | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h index 2bc86ac8ffd4..6958a00f5e8f 100644 --- a/drivers/iio/accel/adxl313.h +++ b/drivers/iio/accel/adxl313.h @@ -37,8 +37,7 @@ #define ADXL313_RATE_MSK GENMASK(3, 0) #define ADXL313_RATE_BASE 6 =20 -#define ADXL313_POWER_CTL_MSK GENMASK(3, 2) -#define ADXL313_MEASUREMENT_MODE BIT(3) +#define ADXL313_POWER_CTL_MSK BIT(3) =20 #define ADXL313_RANGE_MSK GENMASK(1, 0) #define ADXL313_RANGE_MAX 3 diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index dc5f04b17b29..1be4e867f4b2 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -64,6 +64,12 @@ bool adxl313_is_volatile_reg(struct device *dev, unsigne= d int reg) } EXPORT_SYMBOL_NS_GPL(adxl313_is_volatile_reg, "IIO_ADXL313"); =20 +static int adxl313_set_measure_en(struct adxl313_data *data, bool en) +{ + return regmap_assign_bits(data->regmap, ADXL313_REG_POWER_CTL, + ADXL313_POWER_CTL_MSK, en); +} + static int adxl312_check_id(struct device *dev, struct adxl313_data *data) { @@ -398,9 +404,7 @@ static int adxl313_setup(struct device *dev, struct adx= l313_data *data, } =20 /* Enables measurement mode */ - return regmap_update_bits(data->regmap, ADXL313_REG_POWER_CTL, - ADXL313_POWER_CTL_MSK, - ADXL313_MEASUREMENT_MODE); + return adxl313_set_measure_en(data, true); } =20 /** --=20 2.39.5 From nobody Wed Oct 8 02:16:10 2025 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 E4FBE2BE644; Wed, 2 Jul 2025 23:08:28 +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=1751497711; cv=none; b=ijkbEWPFweZ5nuoGSrgWqYmVaUGeYxzUSAXXy+ebxGGtRkbsx4BfcVPPuXu8TbUw49ANh6VR3+NhfLVK50OQOa0SK9p7q23PDOVflUgA4TW3HbeAKa2i3sjAVNbpFVUcNyiqhLGavIg17bN/D5xA7gJEDaEF2xfcz1ObhREGo2g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497711; c=relaxed/simple; bh=W8UnioKDfdx8IP5If9lsSbYY5UctZMdXwbu8U8GxSJU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PON+x+niNSctoslLDLPNYKw8dFolR0IllEIVVVq0IA8GA7fnwFuA0oR5RMUSrKUo7kJ8GceNkR1vAGYsONx+T+wdW3jOCHUeu8isZXCIXc9yEU2EXi1pgTfOgZwigMN/SyZqWOHPvC4QnaWp0v4oLWI35MJmPQE8dCuyQQUD+Ys= 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=O3w7pq5t; 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="O3w7pq5t" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-ae34f43be56so76265666b.2; Wed, 02 Jul 2025 16:08:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497707; x=1752102507; 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=X2YbcLMTJ6lKMMhbKpAMSycC4sdmH5CcU8bHTvj6qNM=; b=O3w7pq5twoyLFg/X3lg7I5FRpRXsTDpWpaYiulTGS+GTGLYeuWYzzlv9aGSVAK0VTp rP/WrUm/fbG12h/b26Hk9PyEhphkvD4BsN5BRhUYv844asHY3Tkhhmle+nKokdEszACr i0eEikG9kBL0AODhm2jxjobY/kGXz6wUFpZnRTy+/XQGf8MoiLMqJSdxZQ/Y0jigOMor ZSclhNlDPoBZjBjXiVHn5UvsW9YEwPFmMcDmSG8Lwz8zgwdtBTJ8VIDZIRIEEMIy8JAL Zm0Ga/EKYKIKPpRjCuf01KP22zTsjtsVd7HQi/0zoLcx3zhAFUjGY71xBLcSe84b32Yn TofA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497707; x=1752102507; 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=X2YbcLMTJ6lKMMhbKpAMSycC4sdmH5CcU8bHTvj6qNM=; b=sYT/jyXqkVuQwFs9+nuPzgh8495AyNVTCWjYHacXNdzn98d2Quzf5fnV90UZlX/nH1 mZSuWrCFGNh0wVh8fPvr43SRrfqOY3qTNuPq9rFSICiEASg0UBz9ecw+u3b71Wgq5FoB Rg+fwKNxHus2zQu1ke/RPlyzjHyvbgtJDqOO4DVbFCOuQMePRVlfvxpiVX05hDJpbYlw LOjS5ZL1T/ooCItOpn3g4msgaSd57cM4Lw/N/yKpnKiEqctqtPbjux8ZJBFeIi9aaL7v bGLlUZXSQ2g/JqF87a8VQ9JgDWaIJxqskNSasrSouEtwto+rT+izjO3DyvQs0itLKvPf 70Gw== X-Forwarded-Encrypted: i=1; AJvYcCUtUR3TAGUjgpNTxWYNeBW8rM5QWTjP/PLPZjyWuXkpeTGyjCuIK1Z3z60luk0lLI/IBQ9m/X/pY+I=@vger.kernel.org, AJvYcCW9DN2KgFDbphqU64XxQj5fAwQJWG5dLFlBHkiGKgHfWT7tVX23vBUenfVCuzM1Wvlwg5EsAqKvrpQD@vger.kernel.org, AJvYcCWftkO0zI0vtDYTXkKpumb86j4klsdx3eAnZBRW+bhmWCRyxZi2QxidZ8P0I5xyEEhTiCKH4LLFyIjsOBBy@vger.kernel.org X-Gm-Message-State: AOJu0Yy5p8LiystMo3PuZ8L1PJqlm14Vhfo6ZRCfGq7/Y5WNKRTiiUdX uUScSM4J7TXFD8JK+Cq4oltnrn2/WxCIfMZE2diqO/9AGu0G8hRJLcxz X-Gm-Gg: ASbGnctcHs3pLRrsOnwwXdREovd+eiyvjxdh+1Q5X3Zil3H9QPs7gX3UHYoefw71zsb 9/4MF54ZzNyuROb+L7i4Rx3VqumuzgFHTuj2BTyq4KB2SFbE7f/kboo/ytvkNPhQ4AXifsqhOQg vZLbdTkzKwzFlPx4+8Oh74DJxkkOJAa/we28vSV9MNkMcuOlpU5XldNLdGjOaBwkSR74Kg6Xvou 1O/u1fSUAPvhKfDSGnHBmHzgVIU5FhtHCQWIk8TiHangNMbbDcbb3DOMI6V9/yH/r4cTTTeJQq1 lztR6DatxDpeFzc06S0AmoRAqkaYu1ceBy3OPjp2YfIn6X8qWi2pGrDl05NgnYQgES2u9fob0Ba WIlbOOfNRq/xfRd7HihwZj+eYrt2ZwRqE X-Google-Smtp-Source: AGHT+IHlKKNOl6+RP+oZRuJOjqNDWG9NmplZVCyQxd86eWd/e1cfkgu/ZaXBRkyK209LuTLcFltnhg== X-Received: by 2002:a17:907:8688:b0:ae0:caeb:276d with SMTP id a640c23a62f3a-ae3e2558432mr6260666b.4.1751497707142; Wed, 02 Jul 2025 16:08:27 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:26 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 3/8] iio: accel: adxl313: add buffered FIFO watermark with interrupt handling Date: Wed, 2 Jul 2025 23:08:14 +0000 Message-Id: <20250702230819.19353-4-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Cover the following tasks: - Add scan_mask and scan_index to the IIO channel configuration. The scan_index sets up buffer usage. According to the datasheet, the ADXL313 uses a 13-bit wide data field in full-resolution mode. Set the signedness, number of storage bits, and endianness accordingly. - Parse the devicetree for an optional interrupt line and configure the interrupt mapping based on its presence. If no interrupt line is specified, keep the FIFO in bypass mode as currently implemented. - Set up the interrupt handler. Add register access to detect and evaluate interrupts. Implement functions to clear status registers and reset the FIFO. - Implement FIFO watermark configuration and handling. Allow the watermark level to be set, evaluate the corresponding interrupt, read the FIFO contents, and push the data to the IIO channel. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 22 +++ drivers/iio/accel/adxl313_core.c | 264 ++++++++++++++++++++++++++++++- 2 files changed, 280 insertions(+), 6 deletions(-) diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h index 6958a00f5e8f..4f4a9fd39f6d 100644 --- a/drivers/iio/accel/adxl313.h +++ b/drivers/iio/accel/adxl313.h @@ -21,6 +21,7 @@ #define ADXL313_REG_ACT_INACT_CTL 0x27 #define ADXL313_REG_BW_RATE 0x2C #define ADXL313_REG_POWER_CTL 0x2D +#define ADXL313_REG_INT_ENABLE 0x2E #define ADXL313_REG_INT_MAP 0x2F #define ADXL313_REG_INT_SOURCE 0x30 #define ADXL313_REG_DATA_FORMAT 0x31 @@ -46,6 +47,25 @@ #define ADXL313_SPI_3WIRE BIT(6) #define ADXL313_I2C_DISABLE BIT(6) =20 +#define ADXL313_INT_OVERRUN BIT(0) +#define ADXL313_INT_WATERMARK BIT(1) +#define ADXL313_INT_INACTIVITY BIT(3) +#define ADXL313_INT_ACTIVITY BIT(4) +#define ADXL313_INT_DREADY BIT(7) + +/* FIFO entries: how many values are stored in the FIFO */ +#define ADXL313_REG_FIFO_STATUS_ENTRIES_MSK GENMASK(5, 0) +/* FIFO samples: number of samples needed for watermark (FIFO mode) */ +#define ADXL313_REG_FIFO_CTL_SAMPLES_MSK GENMASK(4, 0) +#define ADXL313_REG_FIFO_CTL_MODE_MSK GENMASK(7, 6) + +#define ADXL313_FIFO_BYPASS 0 +#define ADXL313_FIFO_STREAM 2 + +#define ADXL313_FIFO_SIZE 32 + +#define ADXL313_NUM_AXIS 3 + extern const struct regmap_access_table adxl312_readable_regs_table; extern const struct regmap_access_table adxl313_readable_regs_table; extern const struct regmap_access_table adxl314_readable_regs_table; @@ -66,7 +86,9 @@ struct adxl313_data { struct regmap *regmap; const struct adxl313_chip_info *chip_info; struct mutex lock; /* lock to protect transf_buf */ + u8 watermark; __le16 transf_buf __aligned(IIO_DMA_MINALIGN); + __le16 fifo_buf[ADXL313_NUM_AXIS * ADXL313_FIFO_SIZE + 1]; }; =20 struct adxl313_chip_info { diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 1be4e867f4b2..04ca8491bb5c 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -8,11 +8,23 @@ */ =20 #include +#include #include +#include +#include #include =20 +#include +#include + #include "adxl313.h" =20 +#define ADXL313_INT_NONE U8_MAX +#define ADXL313_INT1 1 +#define ADXL313_INT2 2 + +#define ADXL313_REG_XYZ_BASE ADXL313_REG_DATA_AXIS(0) + static const struct regmap_range adxl312_readable_reg_range[] =3D { regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_DEVID0), regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), @@ -195,9 +207,10 @@ static const int adxl313_odr_freqs[][2] =3D { [9] =3D { 3200, 0 }, }; =20 -#define ADXL313_ACCEL_CHANNEL(index, axis) { \ +#define ADXL313_ACCEL_CHANNEL(index, reg, axis) { \ .type =3D IIO_ACCEL, \ - .address =3D index, \ + .scan_index =3D (index), \ + .address =3D (reg), \ .modified =3D 1, \ .channel2 =3D IIO_MOD_##axis, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ @@ -207,14 +220,26 @@ static const int adxl313_odr_freqs[][2] =3D { .info_mask_shared_by_type_available =3D \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_type =3D { \ + .sign =3D 's', \ .realbits =3D 13, \ + .storagebits =3D 16, \ + .endianness =3D IIO_BE, \ }, \ } =20 +enum adxl313_chans { + chan_x, chan_y, chan_z, +}; + static const struct iio_chan_spec adxl313_channels[] =3D { - ADXL313_ACCEL_CHANNEL(0, X), - ADXL313_ACCEL_CHANNEL(1, Y), - ADXL313_ACCEL_CHANNEL(2, Z), + ADXL313_ACCEL_CHANNEL(0, chan_x, X), + ADXL313_ACCEL_CHANNEL(1, chan_y, Y), + ADXL313_ACCEL_CHANNEL(2, chan_z, Z), +}; + +static const unsigned long adxl313_scan_masks[] =3D { + BIT(chan_x) | BIT(chan_y) | BIT(chan_z), + 0 }; =20 static int adxl313_set_odr(struct adxl313_data *data, @@ -345,6 +370,173 @@ static int adxl313_write_raw(struct iio_dev *indio_de= v, } } =20 +static int adxl313_set_watermark(struct iio_dev *indio_dev, unsigned int v= alue) +{ + struct adxl313_data *data =3D iio_priv(indio_dev); + int ret; + + value =3D min(value, ADXL313_FIFO_SIZE - 1); + + ret =3D adxl313_set_measure_en(data, false); + if (ret) + return ret; + + ret =3D regmap_update_bits(data->regmap, ADXL313_REG_FIFO_CTL, + ADXL313_REG_FIFO_CTL_MODE_MSK, value); + if (ret) + return ret; + + data->watermark =3D value; + + ret =3D regmap_set_bits(data->regmap, ADXL313_REG_INT_ENABLE, + ADXL313_INT_WATERMARK); + if (ret) + return ret; + + return adxl313_set_measure_en(data, true); +} + +static int adxl313_get_samples(struct adxl313_data *data) +{ + unsigned int regval; + int ret; + + ret =3D regmap_read(data->regmap, ADXL313_REG_FIFO_STATUS, ®val); + if (ret) + return ret; + + return FIELD_GET(ADXL313_REG_FIFO_STATUS_ENTRIES_MSK, regval); +} + +static int adxl313_fifo_transfer(struct adxl313_data *data, int samples) +{ + unsigned int i; + int ret; + + for (i =3D 0; i < samples; i++) { + ret =3D regmap_bulk_read(data->regmap, ADXL313_REG_XYZ_BASE, + data->fifo_buf + (i * ADXL313_NUM_AXIS), + sizeof(data->fifo_buf[0]) * ADXL313_NUM_AXIS); + if (ret) + return ret; + } + + return 0; +} + +/** + * adxl313_fifo_reset() - Reset the FIFO and interrupt status registers. + * @data: The device data. + * + * Reset the FIFO status registers. Reading out status registers clears the + * FIFO and interrupt configuration. Thus do not evaluate regmap return va= lues. + * Ignore particular read register content. Register content is not proces= sed + * any further. Therefore the function returns void. + */ +static void adxl313_fifo_reset(struct adxl313_data *data) +{ + unsigned int regval; + int samples; + + adxl313_set_measure_en(data, false); + + samples =3D adxl313_get_samples(data); + if (samples > 0) + adxl313_fifo_transfer(data, samples); + + regmap_read(data->regmap, ADXL313_REG_INT_SOURCE, ®val); + + adxl313_set_measure_en(data, true); +} + +static int adxl313_buffer_postenable(struct iio_dev *indio_dev) +{ + struct adxl313_data *data =3D iio_priv(indio_dev); + int ret; + + /* Set FIFO modes with measurement turned off, according to datasheet */ + ret =3D adxl313_set_measure_en(data, false); + if (ret) + return ret; + + ret =3D regmap_write(data->regmap, ADXL313_REG_FIFO_CTL, + FIELD_PREP(ADXL313_REG_FIFO_CTL_SAMPLES_MSK, data->watermark) | + FIELD_PREP(ADXL313_REG_FIFO_CTL_MODE_MSK, ADXL313_FIFO_STREAM)); + if (ret) + return ret; + + return adxl313_set_measure_en(data, true); +} + +static int adxl313_buffer_predisable(struct iio_dev *indio_dev) +{ + struct adxl313_data *data =3D iio_priv(indio_dev); + int ret; + + ret =3D adxl313_set_measure_en(data, false); + if (ret) + return ret; + + ret =3D regmap_write(data->regmap, ADXL313_REG_FIFO_CTL, + FIELD_PREP(ADXL313_REG_FIFO_CTL_MODE_MSK, ADXL313_FIFO_BYPASS)); + + ret =3D regmap_write(data->regmap, ADXL313_REG_INT_ENABLE, 0); + if (ret) + return ret; + + return adxl313_set_measure_en(data, true); +} + +static const struct iio_buffer_setup_ops adxl313_buffer_ops =3D { + .postenable =3D adxl313_buffer_postenable, + .predisable =3D adxl313_buffer_predisable, +}; + +static int adxl313_fifo_push(struct iio_dev *indio_dev, int samples) +{ + struct adxl313_data *data =3D iio_priv(indio_dev); + unsigned int i; + int ret; + + ret =3D adxl313_fifo_transfer(data, samples); + if (ret) + return ret; + + for (i =3D 0; i < ADXL313_NUM_AXIS * samples; i +=3D ADXL313_NUM_AXIS) + iio_push_to_buffers(indio_dev, &data->fifo_buf[i]); + + return 0; +} + +static irqreturn_t adxl313_irq_handler(int irq, void *p) +{ + struct iio_dev *indio_dev =3D p; + struct adxl313_data *data =3D iio_priv(indio_dev); + int samples, int_stat; + + if (regmap_read(data->regmap, ADXL313_REG_INT_SOURCE, &int_stat)) + return IRQ_NONE; + + if (FIELD_GET(ADXL313_INT_WATERMARK, int_stat)) { + samples =3D adxl313_get_samples(data); + if (samples < 0) + goto err; + + if (adxl313_fifo_push(indio_dev, samples)) + goto err; + } + + if (FIELD_GET(ADXL313_INT_OVERRUN, int_stat)) + goto err; + + return IRQ_HANDLED; + +err: + adxl313_fifo_reset(data); + + return IRQ_HANDLED; +} + static int adxl313_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, unsigned int *readval) { @@ -359,6 +551,7 @@ static const struct iio_info adxl313_info =3D { .read_raw =3D adxl313_read_raw, .write_raw =3D adxl313_write_raw, .read_avail =3D adxl313_read_freq_avail, + .hwfifo_set_watermark =3D adxl313_set_watermark, .debugfs_reg_access =3D &adxl313_reg_access, }; =20 @@ -407,6 +600,19 @@ static int adxl313_setup(struct device *dev, struct ad= xl313_data *data, return adxl313_set_measure_en(data, true); } =20 +static unsigned int adxl313_get_int_type(struct device *dev, int *irq) +{ + *irq =3D fwnode_irq_get_byname(dev_fwnode(dev), "INT1"); + if (*irq > 0) + return ADXL313_INT1; + + *irq =3D fwnode_irq_get_byname(dev_fwnode(dev), "INT2"); + if (*irq > 0) + return ADXL313_INT2; + + return ADXL313_INT_NONE; +} + /** * adxl313_core_probe() - probe and setup for adxl313 accelerometer * @dev: Driver model representation of the device @@ -424,7 +630,9 @@ int adxl313_core_probe(struct device *dev, { struct adxl313_data *data; struct iio_dev *indio_dev; - int ret; + u8 int_line; + u8 int_map_msk; + int irq, ret; =20 indio_dev =3D devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) @@ -441,6 +649,7 @@ int adxl313_core_probe(struct device *dev, indio_dev->modes =3D INDIO_DIRECT_MODE; indio_dev->channels =3D adxl313_channels; indio_dev->num_channels =3D ARRAY_SIZE(adxl313_channels); + indio_dev->available_scan_masks =3D adxl313_scan_masks; =20 ret =3D adxl313_setup(dev, data, setup); if (ret) { @@ -448,6 +657,49 @@ int adxl313_core_probe(struct device *dev, return ret; } =20 + int_line =3D adxl313_get_int_type(dev, &irq); + if (int_line =3D=3D ADXL313_INT_NONE) { + /* + * FIFO_BYPASSED mode + * + * When no interrupt lines are specified, the driver falls back + * to use the sensor in FIFO_BYPASS mode. This means turning off + * internal FIFO and interrupt generation (since there is no + * line specified). Unmaskable interrupts such as overrun or + * data ready won't interfere. Even that a FIFO_STREAM mode w/o + * connected interrupt line might allow for obtaining raw + * measurements, a fallback to disable interrupts when no + * interrupt lines are connected seems to be the cleaner + * solution. + */ + ret =3D regmap_write(data->regmap, ADXL313_REG_FIFO_CTL, + FIELD_PREP(ADXL313_REG_FIFO_CTL_MODE_MSK, + ADXL313_FIFO_BYPASS)); + if (ret) + return ret; + } else { + /* FIFO_STREAM mode */ + int_map_msk =3D ADXL313_INT_DREADY | ADXL313_INT_ACTIVITY | + ADXL313_INT_INACTIVITY | ADXL313_INT_WATERMARK | + ADXL313_INT_OVERRUN; + ret =3D regmap_assign_bits(data->regmap, ADXL313_REG_INT_MAP, + int_map_msk, int_line =3D=3D ADXL313_INT2); + if (ret) + return ret; + + ret =3D devm_iio_kfifo_buffer_setup(dev, indio_dev, + &adxl313_buffer_ops); + if (ret) + return ret; + + ret =3D devm_request_threaded_irq(dev, irq, NULL, + &adxl313_irq_handler, + IRQF_SHARED | IRQF_ONESHOT, + indio_dev->name, indio_dev); + if (ret) + return ret; + } + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, "IIO_ADXL313"); --=20 2.39.5 From nobody Wed Oct 8 02:16:10 2025 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 0541A2E03FD; Wed, 2 Jul 2025 23:08:29 +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=1751497712; cv=none; b=YRRO4a2kQVY+/8mDppNbJZd17jTaSO7TQiEM1nzedBmUWOpJWUXe26PvAWleW3IzlVKK6+HU3WZCfxcVPwcWmCgAWMauYqqnFUa0T73G0/FDOzAKBs2QJpFl3YEkcdGJ+M6Yg0/9MlFmxzPIl6Th44CVRdEAgZz5nHv48kmgMXU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497712; c=relaxed/simple; bh=h3/a0Q9+9MW7F2bL0/4opJlubTRkyT3fuD/vtomhh/U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Qw5+uDDXl4SQacN8OD7v0nB05KB4c6nb3Pv3/59HzcEVBww08zuwLWXaUEPs1nmnMW6X+7mZGsEQBCknB7AgO6co07PgrlApxJA8IkfiJHLkf3+qy02E0i11EDwoggbKOMogJUdPrsl6JOGvJK/rsZoahmOxrt0sHnvwMq/iF4k= 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=baLz+QVy; 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="baLz+QVy" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-ae3521a129aso92911966b.3; Wed, 02 Jul 2025 16:08:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497708; x=1752102508; 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=FbhLFYMz46xEB1YUu1Q4x0HgQDDSkCjbH4WEeWQ31Jo=; b=baLz+QVy2mdEydBYc4WFfILmQAgI9F9D+TPev1g7ifnDzddvQZ0i6Bm2eJEwi0PHin rh/Tl3eIFzChblr4KIKhsXY2ylLSaSoRsqAWtz/cWwF3Xsa3EPgJm92XsIHpnM2rZ49Q 19ZKQxst4JgvWs5PEKg4juvS922TiS5YYGlGK4/QZeFxC9jUvAGDhgTdDLk9yh3a0M9Q LqxjpY+Bu6iimmNrPV0ZTiIAruLxp7wQZfl1HexuYW8SrhvcezWsEtjVkmUTUjcqGupT 7hWZzgex0Xl1ZuVPMav0o/na39D1OWVS4bMtO8P+JuJFeAkFi932ED2ychFWJwaZ2i/4 c/wA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497708; x=1752102508; 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=FbhLFYMz46xEB1YUu1Q4x0HgQDDSkCjbH4WEeWQ31Jo=; b=vWS0FKuISaP/NESUFaKybtUXpDpqU+cC/pr1zlG82MadEYNc3WPGXmkhMRw+iysT4H UsRy+sCix2UPsRlVAFr5VjpHXuBIt782IxpO6CXUKvEnTsDn2GH6uH1zRDGF5BbYCDkX +0csZ0U7juSHhm28AR5I0WOppNjKUPGcyKSwZL1worHv1kERD4lBT9cwStUOSSLZMYDp 8+1IIQ/r2xkPstSiirweQPcSZr+4N4peLFVHKiuaPUkesakmBaHDdNuQFUP5MmuTjSOF 8fvtWtjawEBHkSNL04kshan4T+3aVCF+mdbDswwIMOzHZ/oGhRc1xjg9twewBmkdq2Rn iuZA== X-Forwarded-Encrypted: i=1; AJvYcCV0JymU0I64OjckeZ6URV2LWJh/rxXoLOqhVqtCmpzNml24WJkwCvqQMrtABQ1dbOPcuNh6RE5wj1d8oGQu@vger.kernel.org, AJvYcCVOAGPs7XC2x4N7uITB8VL+Q17R9qhGbwj1H/oHQg9+2+oh3ByEgGbXy/fhCueeOlIHGfg3EWBr2Ms=@vger.kernel.org, AJvYcCWNWYTWoPdb5gES4svwzDjnV8EGTrPEPl0B2j58NQOc6iSXLTXYW+ntgYm1jse5RHfGPny8PRH4+kXm@vger.kernel.org X-Gm-Message-State: AOJu0Yxdl3DisKqedojnLrPn4ut0Sm05Am8PcE7OhwC3E3Cue+nWjJwJ 6KO7I6iSrzMRd8m17iyMf2ozJr5Ncv2RguAqr6VvesSJq6tB2HGlGmTj X-Gm-Gg: ASbGnctdzCsUVTPC0gJt0GnbVlXCO7t8nXFiCSa3sHjjqTR0d3vN0uQJe8JdccUdSke 6RcUY234hSKWY2ahSHbndhqeAQd9C7uPSUCgHFw9RTGGa+kd006GUTwl8SUWlMyYlf4AVI86sy5 uT0xNnulrAAS2mFIhZqlP4Uegr1JUKQNxN3hthOaFemKKJUkYSxBt1gf8OI4suSCZLpT10hla2v fblx87KMAh0eXY4WnfPSDukdJ/dSKE4psj3eSq/m7r5SPVBfGgzlIjAWxbOT97zmZoDb+O+EEbu tMezyxLMmK/j8E8LB5pDlHLwj6FN9/ojIH30u1ryidpIX3yAuhYavNfZKb4OEzYs8eubKsZnYee gyC7UZ7tmRQ1ge7zKC8NYJukR8J5cEKsS X-Google-Smtp-Source: AGHT+IGGNSVJiF5W6NpTeTSVzdLQhULs/WwAN07w/e1eIli5cu1dA+UGA8jMdtzcRg8pKYDUXrlXWA== X-Received: by 2002:a17:907:7ea0:b0:ad8:882e:38a with SMTP id a640c23a62f3a-ae3e28514b4mr5943566b.14.1751497708281; Wed, 02 Jul 2025 16:08:28 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:27 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 4/8] iio: accel: adxl313: add activity sensing Date: Wed, 2 Jul 2025 23:08:15 +0000 Message-Id: <20250702230819.19353-5-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for configuring an activity detection threshold. Extend the interrupt handler to process activity-related interrupts, and provide functions to set the threshold as well as to enable or disable activity sensing. Additionally, introduce a virtual channel that represents the logical AND of the x, y, and z axes in the IIO channel. This patch serves as a preparatory step; some definitions and functions introduced here are intended to be extended later to support inactivity detection. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313_core.c | 306 +++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 04ca8491bb5c..828b46b2254d 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -13,8 +13,10 @@ #include #include #include +#include =20 #include +#include #include =20 #include "adxl313.h" @@ -25,6 +27,21 @@ =20 #define ADXL313_REG_XYZ_BASE ADXL313_REG_DATA_AXIS(0) =20 +#define ADXL313_ACT_XYZ_EN GENMASK(6, 4) + +/* activity/inactivity */ +enum adxl313_activity_type { + ADXL313_ACTIVITY, +}; + +static const unsigned int adxl313_act_int_reg[] =3D { + [ADXL313_ACTIVITY] =3D ADXL313_INT_ACTIVITY, +}; + +static const unsigned int adxl313_act_thresh_reg[] =3D { + [ADXL313_ACTIVITY] =3D ADXL313_REG_THRESH_ACT, +}; + static const struct regmap_range adxl312_readable_reg_range[] =3D { regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_DEVID0), regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), @@ -227,6 +244,15 @@ static const int adxl313_odr_freqs[][2] =3D { }, \ } =20 +static const struct iio_event_spec adxl313_activity_events[] =3D { + { + .type =3D IIO_EV_TYPE_MAG, + .dir =3D IIO_EV_DIR_RISING, + .mask_separate =3D BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type =3D BIT(IIO_EV_INFO_VALUE), + }, +}; + enum adxl313_chans { chan_x, chan_y, chan_z, }; @@ -235,6 +261,14 @@ static const struct iio_chan_spec adxl313_channels[] = =3D { ADXL313_ACCEL_CHANNEL(0, chan_x, X), ADXL313_ACCEL_CHANNEL(1, chan_y, Y), ADXL313_ACCEL_CHANNEL(2, chan_z, Z), + { + .type =3D IIO_ACCEL, + .modified =3D 1, + .channel2 =3D IIO_MOD_X_OR_Y_OR_Z, + .scan_index =3D -1, /* Fake channel for axis OR'ing */ + .event_spec =3D adxl313_activity_events, + .num_event_specs =3D ARRAY_SIZE(adxl313_activity_events), + }, }; =20 static const unsigned long adxl313_scan_masks[] =3D { @@ -297,6 +331,81 @@ static int adxl313_read_freq_avail(struct iio_dev *ind= io_dev, } } =20 +static int adxl313_is_act_inact_en(struct adxl313_data *data, + enum adxl313_activity_type type) +{ + unsigned int axis_ctrl; + unsigned int regval; + int ret; + + ret =3D regmap_read(data->regmap, ADXL313_REG_ACT_INACT_CTL, &axis_ctrl); + if (ret) + return ret; + + /* Check if axis for activity are enabled */ + switch (type) { + case ADXL313_ACTIVITY: + if (!FIELD_GET(ADXL313_ACT_XYZ_EN, axis_ctrl)) + return false; + break; + default: + return -EINVAL; + } + + /* Check if specific interrupt is enabled */ + ret =3D regmap_read(data->regmap, ADXL313_REG_INT_ENABLE, ®val); + if (ret) + return ret; + + return adxl313_act_int_reg[type] & regval; +} + +static int adxl313_set_act_inact_en(struct adxl313_data *data, + enum adxl313_activity_type type, + bool cmd_en) +{ + unsigned int axis_ctrl; + unsigned int threshold; + int ret; + + if (cmd_en) { + /* When turning on, check if threshold is valid */ + ret =3D regmap_read(data->regmap, adxl313_act_thresh_reg[type], + &threshold); + if (ret) + return ret; + + if (!threshold) /* Just ignore the command if threshold is 0 */ + return 0; + } + + /* Start modifying configuration registers */ + ret =3D adxl313_set_measure_en(data, false); + if (ret) + return ret; + + /* Enable axis according to the command */ + switch (type) { + case ADXL313_ACTIVITY: + axis_ctrl =3D ADXL313_ACT_XYZ_EN; + break; + default: + return -EINVAL; + } + ret =3D regmap_assign_bits(data->regmap, ADXL313_REG_ACT_INACT_CTL, + axis_ctrl, cmd_en); + if (ret) + return ret; + + /* Enable the interrupt line, according to the command */ + ret =3D regmap_assign_bits(data->regmap, ADXL313_REG_INT_ENABLE, + adxl313_act_int_reg[type], cmd_en); + if (ret) + return ret; + + return adxl313_set_measure_en(data, true); +} + static int adxl313_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -370,6 +479,157 @@ static int adxl313_write_raw(struct iio_dev *indio_de= v, } } =20 +static int adxl313_read_mag_config(struct adxl313_data *data, + enum iio_event_direction dir, + enum adxl313_activity_type type_act) +{ + switch (dir) { + case IIO_EV_DIR_RISING: + return !!adxl313_is_act_inact_en(data, type_act); + default: + return -EINVAL; + } +} + +static int adxl313_write_mag_config(struct adxl313_data *data, + enum iio_event_direction dir, + enum adxl313_activity_type type_act, + bool state) +{ + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl313_set_act_inact_en(data, type_act, state); + default: + return -EINVAL; + } +} + +static int adxl313_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 adxl313_data *data =3D iio_priv(indio_dev); + + switch (type) { + case IIO_EV_TYPE_MAG: + return adxl313_read_mag_config(data, dir, + ADXL313_ACTIVITY); + default: + return -EINVAL; + } +} + +static int adxl313_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + struct adxl313_data *data =3D iio_priv(indio_dev); + + switch (type) { + case IIO_EV_TYPE_MAG: + return adxl313_write_mag_config(data, dir, + ADXL313_ACTIVITY, + state); + default: + return -EINVAL; + } +} + +static int adxl313_read_mag_value(struct adxl313_data *data, + enum iio_event_direction dir, + enum iio_event_info info, + enum adxl313_activity_type type_act, + int *val, int *val2) +{ + unsigned int threshold; + int ret; + + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + ret =3D regmap_read(data->regmap, + adxl313_act_thresh_reg[type_act], + &threshold); + if (ret) + return ret; + *val =3D threshold * 15625; + *val2 =3D MICRO; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl313_write_mag_value(struct adxl313_data *data, + enum iio_event_direction dir, + enum iio_event_info info, + enum adxl313_activity_type type_act, + int val, int val2) +{ + unsigned int regval; + + switch (info) { + case IIO_EV_INFO_VALUE: + /* Scale factor 15.625 mg/LSB */ + regval =3D DIV_ROUND_CLOSEST(MICRO * val + val2, 15625); + switch (dir) { + case IIO_EV_DIR_RISING: + return regmap_write(data->regmap, + adxl313_act_thresh_reg[type_act], + regval); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl313_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 adxl313_data *data =3D iio_priv(indio_dev); + + switch (type) { + case IIO_EV_TYPE_MAG: + return adxl313_read_mag_value(data, dir, info, + ADXL313_ACTIVITY, + val, val2); + default: + return -EINVAL; + } +} + +static int adxl313_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 adxl313_data *data =3D iio_priv(indio_dev); + + switch (type) { + case IIO_EV_TYPE_MAG: + return adxl313_write_mag_value(data, dir, info, + ADXL313_ACTIVITY, + val, val2); + default: + return -EINVAL; + } +} + static int adxl313_set_watermark(struct iio_dev *indio_dev, unsigned int v= alue) { struct adxl313_data *data =3D iio_priv(indio_dev); @@ -508,6 +768,25 @@ static int adxl313_fifo_push(struct iio_dev *indio_dev= , int samples) return 0; } =20 +static int adxl313_push_events(struct iio_dev *indio_dev, int int_stat) +{ + s64 ts =3D iio_get_time_ns(indio_dev); + int ret =3D -ENOENT; + + if (FIELD_GET(ADXL313_INT_ACTIVITY, int_stat)) { + ret =3D 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_RISING), + ts); + if (ret) + return ret; + } + + return ret; +} + static irqreturn_t adxl313_irq_handler(int irq, void *p) { struct iio_dev *indio_dev =3D p; @@ -517,6 +796,16 @@ static irqreturn_t adxl313_irq_handler(int irq, void *= p) if (regmap_read(data->regmap, ADXL313_REG_INT_SOURCE, &int_stat)) return IRQ_NONE; =20 + /* + * In cases of sensor events not handled (still not implemented) by + * this driver, the FIFO needs to be drained to become operational + * again. In general the sensor configuration only should issue events + * which were configured by this driver. Anyway a miss-configuration + * easily might end up in a hanging sensor FIFO. + */ + if (adxl313_push_events(indio_dev, int_stat)) + goto err; + if (FIELD_GET(ADXL313_INT_WATERMARK, int_stat)) { samples =3D adxl313_get_samples(data); if (samples < 0) @@ -550,6 +839,10 @@ static int adxl313_reg_access(struct iio_dev *indio_de= v, unsigned int reg, static const struct iio_info adxl313_info =3D { .read_raw =3D adxl313_read_raw, .write_raw =3D adxl313_write_raw, + .read_event_config =3D adxl313_read_event_config, + .write_event_config =3D adxl313_write_event_config, + .read_event_value =3D adxl313_read_event_value, + .write_event_value =3D adxl313_write_event_value, .read_avail =3D adxl313_read_freq_avail, .hwfifo_set_watermark =3D adxl313_set_watermark, .debugfs_reg_access =3D &adxl313_reg_access, @@ -687,6 +980,19 @@ int adxl313_core_probe(struct device *dev, if (ret) return ret; =20 + /* + * Reset or configure the registers with reasonable default + * values. As having 0 in most cases may result in undesirable + * behavior if the interrupts are enabled. + */ + ret =3D regmap_write(data->regmap, ADXL313_REG_ACT_INACT_CTL, 0x00); + if (ret) + return ret; + + ret =3D regmap_write(data->regmap, ADXL313_REG_THRESH_ACT, 0x52); + if (ret) + return ret; + ret =3D devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl313_buffer_ops); if (ret) --=20 2.39.5 From nobody Wed Oct 8 02:16:10 2025 Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E6292F5C55; Wed, 2 Jul 2025 23:08:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497713; cv=none; b=VQw4oWToqQi8vb+irLaXo/PY9rS/x21TBO9o8IO1ygInCuEIQEM26kLEFmkRS0CeVpyS+AuVaYw60Jxue6DTvPs/pAUplW26lhXXC0raj2pG6HjQ5IaFm8T5fC1fXpTQBKB5J4ZGY/TB84FxZmH7q5nzNjoLRtHvTg/gemH9mQw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497713; c=relaxed/simple; bh=eAwHb7oGlBf3N7BjmVMPwsNpP142rZLVOMlcInE+SZE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Jdb5RQllfPVY3VUIizK0IshDGODT9TobM0cWXKRuRpSxzKPcmh5+4aoSe3F2rabstE1L3RNjrlHGmwoGFIPcgRwKbRF72G2l1Jx7luxqgcLm99F3ojRvxJTdTezh2jGfJjDpQcmisM86Dnut7cH1ZtqASKms50pySSRTWPfilwY= 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=hSoe6EYE; arc=none smtp.client-ip=209.85.218.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hSoe6EYE" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ae0b98ccc57so96604066b.0; Wed, 02 Jul 2025 16:08:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497710; x=1752102510; 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=5rV+hcIRu9hiAshsYg5BPxUuS6hHYKbnLNPhgkfY+/M=; b=hSoe6EYEB2M/VLSzddrAswutt4BXDpCynfZ96XZyvT6lZPZwL4SJZhNl1EC6myrfEn 65ahLypzVJcfwWFYRCbpL3lGDkGhFhEnVvGJo/CRR7dEW+U6G7wIkL3yeYG6g650cFwC ytzg7w0bV6dzcuCz+BlEHLl+jx7bvXdYaisBQoHm5FF2lwbUjdF8fA3VJRdS2KjjTPqZ Gd+KFxQNPsGLErim1s4zgR1vXgTwPJUuPBatCHnAPDzx8yu11w0HNuF0UdY4WXJDYaZv a/pUSGQKqyP9MqP2rH/AiJ8bCuAG+k9lKTGLgnOUA6/xqAHqV8TeeKAwlJIaYQ8GmDZr ZslQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497710; x=1752102510; 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=5rV+hcIRu9hiAshsYg5BPxUuS6hHYKbnLNPhgkfY+/M=; b=l14sZmzWKtRw3KMKTg2xqadkBP4j5O9ojwTAdFEEAntD5/utX0UM8xjGfZectAVxT7 xsiE2Nb7QrLyc7ypa3N2clr8XqHNQ9Q6i+ye+6HDoeaGLWFFh5U2zjd1CKRy5Ol1/SmH OWsSsdfYLXyZDDlr/fiim0D1RmQiB+N6QuvAnq9Ucpg7wLaSoZIuJV0gF42QRiXm3Qut U1oxrckR73XvGBrDNXlIjxrT3qnL+2cb7ht/dv3ILi9Tfzo1vy2hnAAqcOK6IYu9/6rK FFn8StpcirZbaOk5J93K+DdXKp2BnxS/LKvi4Rnj9L7QClHFMS+bBT21LMDLyLxq6KSt JKZA== X-Forwarded-Encrypted: i=1; AJvYcCUFyC+M6930vp2fHGYll3BFnndnzr3AKyS1k9z5dHMUaNj+H+i2BdHCejEdsVruXs+R+EqbbnLXM94=@vger.kernel.org, AJvYcCX9LcDxiLMbUDDQ3lQfCMjtQKZKa3/uon1E1pqpi2cMq9QQm/7CFvl2By/jE8blMbs5vfaSCgSzHlv5@vger.kernel.org, AJvYcCXrKsT11Q/2WJL9prLbUHt70+PeZRRjF2IaCRkx49HmiLRXAel2v8aH5BXSTlO/KXwH3PDXuvRptGsokckk@vger.kernel.org X-Gm-Message-State: AOJu0YwJH2bf36KjBaX2JcTktTwy0skfGnjuODcPWaOuza6qZPc9kaFq 81Xm+L5mKVcfrCPNO+CR7MDtH6zL3pecduRTSt1NEY2aAzLVaFm+FZwf X-Gm-Gg: ASbGncsqTmNZ5Dwp7vZMFGvY54HrGOvVzq981O6Ve+fIURaXTsyhk1eg2UoqUTMXij7 Zg/lOE57IcR5LUHUmnXKhSjIeLRePoaFEy1/EOfUBOXOmrqMEyvEnHUrJjvomj6D7f4PcuL+Xii xgMY2ye4TLkqHxyF7DhpDUzuOsdLQfxKrd1dd7ZMvV0dZe643v+f06hgz6B5cdz3mY6QyY5o5k4 vpWEuil+aOvkVUqeIMoYGABJ/iHUp1nYzpm2uIGTrtX6NmA8Ue8XzP3IrSAaBtpoyXpZjrWbXDt 5e3XtfGD4/JVWNy8PGSgF+dF8nNo5+uNP/Avl05mJLwW8yA0DKJhD9jSt1TPnUL272rHwgSpWHH jBz/+M0HiMT99/ojKAIdzKNNCZfFtM8GD X-Google-Smtp-Source: AGHT+IG5radwdNOkIg5iSCE3Xy/+Zuhz2bOwm94BK0tFCBgjvZTTxthhHqwYKpitQWD7+ih+zMs50A== X-Received: by 2002:a17:907:9405:b0:ade:9b52:4d84 with SMTP id a640c23a62f3a-ae3e29d6e00mr6619566b.15.1751497709458; Wed, 02 Jul 2025 16:08:29 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:29 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 5/8] iio: accel: adxl313: add inactivity sensing Date: Wed, 2 Jul 2025 23:08:16 +0000 Message-Id: <20250702230819.19353-6-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Enhance the interrupt handler to process inactivity events. Introduce functions to configure the threshold and period registers for inactivity detection, as well as to enable or disable the inactivity feature. Extend the fake IIO channel to handle inactivity events by combining the x, y, and z axes using a logical AND operation. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 2 + drivers/iio/accel/adxl313_core.c | 110 ++++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h index 4f4a9fd39f6d..d7e8cb44855b 100644 --- a/drivers/iio/accel/adxl313.h +++ b/drivers/iio/accel/adxl313.h @@ -18,6 +18,8 @@ #define ADXL313_REG_SOFT_RESET 0x18 #define ADXL313_REG_OFS_AXIS(index) (0x1E + (index)) #define ADXL313_REG_THRESH_ACT 0x24 +#define ADXL313_REG_THRESH_INACT 0x25 +#define ADXL313_REG_TIME_INACT 0x26 #define ADXL313_REG_ACT_INACT_CTL 0x27 #define ADXL313_REG_BW_RATE 0x2C #define ADXL313_REG_POWER_CTL 0x2D diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 828b46b2254d..e904dee4dc2b 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -28,18 +28,22 @@ #define ADXL313_REG_XYZ_BASE ADXL313_REG_DATA_AXIS(0) =20 #define ADXL313_ACT_XYZ_EN GENMASK(6, 4) +#define ADXL313_INACT_XYZ_EN GENMASK(2, 0) =20 /* activity/inactivity */ enum adxl313_activity_type { ADXL313_ACTIVITY, + ADXL313_INACTIVITY, }; =20 static const unsigned int adxl313_act_int_reg[] =3D { [ADXL313_ACTIVITY] =3D ADXL313_INT_ACTIVITY, + [ADXL313_INACTIVITY] =3D ADXL313_INT_INACTIVITY, }; =20 static const unsigned int adxl313_act_thresh_reg[] =3D { [ADXL313_ACTIVITY] =3D ADXL313_REG_THRESH_ACT, + [ADXL313_INACTIVITY] =3D ADXL313_REG_THRESH_INACT, }; =20 static const struct regmap_range adxl312_readable_reg_range[] =3D { @@ -253,6 +257,17 @@ static const struct iio_event_spec adxl313_activity_ev= ents[] =3D { }, }; =20 +static const struct iio_event_spec adxl313_inactivity_events[] =3D { + { + /* inactivity */ + .type =3D IIO_EV_TYPE_MAG, + .dir =3D IIO_EV_DIR_FALLING, + .mask_separate =3D BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type =3D BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD), + }, +}; + enum adxl313_chans { chan_x, chan_y, chan_z, }; @@ -269,6 +284,14 @@ static const struct iio_chan_spec adxl313_channels[] = =3D { .event_spec =3D adxl313_activity_events, .num_event_specs =3D ARRAY_SIZE(adxl313_activity_events), }, + { + .type =3D IIO_ACCEL, + .modified =3D 1, + .channel2 =3D IIO_MOD_X_AND_Y_AND_Z, + .scan_index =3D -1, /* Fake channel for axis AND'ing */ + .event_spec =3D adxl313_inactivity_events, + .num_event_specs =3D ARRAY_SIZE(adxl313_inactivity_events), + }, }; =20 static const unsigned long adxl313_scan_masks[] =3D { @@ -331,6 +354,15 @@ static int adxl313_read_freq_avail(struct iio_dev *ind= io_dev, } } =20 +static int adxl313_set_inact_time_s(struct adxl313_data *data, + unsigned int val_s) +{ + unsigned int max_boundary =3D U8_MAX; /* by register size */ + unsigned int val =3D min(val_s, max_boundary); + + return regmap_write(data->regmap, ADXL313_REG_TIME_INACT, val); +} + static int adxl313_is_act_inact_en(struct adxl313_data *data, enum adxl313_activity_type type) { @@ -348,6 +380,10 @@ static int adxl313_is_act_inact_en(struct adxl313_data= *data, if (!FIELD_GET(ADXL313_ACT_XYZ_EN, axis_ctrl)) return false; break; + case ADXL313_INACTIVITY: + if (!FIELD_GET(ADXL313_INACT_XYZ_EN, axis_ctrl)) + return false; + break; default: return -EINVAL; } @@ -366,6 +402,7 @@ static int adxl313_set_act_inact_en(struct adxl313_data= *data, { unsigned int axis_ctrl; unsigned int threshold; + unsigned int inact_time_s; int ret; =20 if (cmd_en) { @@ -377,6 +414,18 @@ static int adxl313_set_act_inact_en(struct adxl313_dat= a *data, =20 if (!threshold) /* Just ignore the command if threshold is 0 */ return 0; + + /* When turning on inactivity, check if inact time is valid */ + if (type =3D=3D ADXL313_INACTIVITY) { + ret =3D regmap_read(data->regmap, + ADXL313_REG_TIME_INACT, + &inact_time_s); + if (ret) + return ret; + + if (!inact_time_s) + return 0; + } } =20 /* Start modifying configuration registers */ @@ -389,6 +438,9 @@ static int adxl313_set_act_inact_en(struct adxl313_data= *data, case ADXL313_ACTIVITY: axis_ctrl =3D ADXL313_ACT_XYZ_EN; break; + case ADXL313_INACTIVITY: + axis_ctrl =3D ADXL313_INACT_XYZ_EN; + break; default: return -EINVAL; } @@ -481,11 +533,14 @@ static int adxl313_write_raw(struct iio_dev *indio_de= v, =20 static int adxl313_read_mag_config(struct adxl313_data *data, enum iio_event_direction dir, - enum adxl313_activity_type type_act) + enum adxl313_activity_type type_act, + enum adxl313_activity_type type_inact) { switch (dir) { case IIO_EV_DIR_RISING: return !!adxl313_is_act_inact_en(data, type_act); + case IIO_EV_DIR_FALLING: + return !!adxl313_is_act_inact_en(data, type_inact); default: return -EINVAL; } @@ -494,11 +549,14 @@ static int adxl313_read_mag_config(struct adxl313_dat= a *data, static int adxl313_write_mag_config(struct adxl313_data *data, enum iio_event_direction dir, enum adxl313_activity_type type_act, + enum adxl313_activity_type type_inact, bool state) { switch (dir) { case IIO_EV_DIR_RISING: return adxl313_set_act_inact_en(data, type_act, state); + case IIO_EV_DIR_FALLING: + return adxl313_set_act_inact_en(data, type_inact, state); default: return -EINVAL; } @@ -514,7 +572,8 @@ static int adxl313_read_event_config(struct iio_dev *in= dio_dev, switch (type) { case IIO_EV_TYPE_MAG: return adxl313_read_mag_config(data, dir, - ADXL313_ACTIVITY); + ADXL313_ACTIVITY, + ADXL313_INACTIVITY); default: return -EINVAL; } @@ -532,6 +591,7 @@ static int adxl313_write_event_config(struct iio_dev *i= ndio_dev, case IIO_EV_TYPE_MAG: return adxl313_write_mag_config(data, dir, ADXL313_ACTIVITY, + ADXL313_INACTIVITY, state); default: return -EINVAL; @@ -542,9 +602,11 @@ static int adxl313_read_mag_value(struct adxl313_data = *data, enum iio_event_direction dir, enum iio_event_info info, enum adxl313_activity_type type_act, + enum adxl313_activity_type type_inact, int *val, int *val2) { unsigned int threshold; + unsigned int period; int ret; =20 switch (info) { @@ -559,9 +621,25 @@ static int adxl313_read_mag_value(struct adxl313_data = *data, *val =3D threshold * 15625; *val2 =3D MICRO; return IIO_VAL_FRACTIONAL; + case IIO_EV_DIR_FALLING: + ret =3D regmap_read(data->regmap, + adxl313_act_thresh_reg[type_inact], + &threshold); + if (ret) + return ret; + *val =3D threshold * 15625; + *val2 =3D MICRO; + return IIO_VAL_FRACTIONAL; default: return -EINVAL; } + case IIO_EV_INFO_PERIOD: + ret =3D regmap_read(data->regmap, ADXL313_REG_TIME_INACT, + &period); + if (ret) + return ret; + *val =3D period; + return IIO_VAL_INT; default: return -EINVAL; } @@ -571,6 +649,7 @@ static int adxl313_write_mag_value(struct adxl313_data = *data, enum iio_event_direction dir, enum iio_event_info info, enum adxl313_activity_type type_act, + enum adxl313_activity_type type_inact, int val, int val2) { unsigned int regval; @@ -584,9 +663,15 @@ static int adxl313_write_mag_value(struct adxl313_data= *data, return regmap_write(data->regmap, adxl313_act_thresh_reg[type_act], regval); + case IIO_EV_DIR_FALLING: + return regmap_write(data->regmap, + adxl313_act_thresh_reg[type_inact], + regval); default: return -EINVAL; } + case IIO_EV_INFO_PERIOD: + return adxl313_set_inact_time_s(data, val); default: return -EINVAL; } @@ -605,6 +690,7 @@ static int adxl313_read_event_value(struct iio_dev *ind= io_dev, case IIO_EV_TYPE_MAG: return adxl313_read_mag_value(data, dir, info, ADXL313_ACTIVITY, + ADXL313_INACTIVITY, val, val2); default: return -EINVAL; @@ -624,6 +710,7 @@ static int adxl313_write_event_value(struct iio_dev *in= dio_dev, case IIO_EV_TYPE_MAG: return adxl313_write_mag_value(data, dir, info, ADXL313_ACTIVITY, + ADXL313_INACTIVITY, val, val2); default: return -EINVAL; @@ -784,6 +871,17 @@ static int adxl313_push_events(struct iio_dev *indio_d= ev, int int_stat) return ret; } =20 + if (FIELD_GET(ADXL313_INT_INACTIVITY, int_stat)) { + ret =3D iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_AND_Y_AND_Z, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_FALLING), + ts); + if (ret) + return ret; + } + return ret; } =20 @@ -989,6 +1087,14 @@ int adxl313_core_probe(struct device *dev, if (ret) return ret; =20 + ret =3D regmap_write(data->regmap, ADXL313_REG_TIME_INACT, 5); + if (ret) + return ret; + + ret =3D regmap_write(data->regmap, ADXL313_REG_THRESH_INACT, 0x4f); + if (ret) + return ret; + ret =3D regmap_write(data->regmap, ADXL313_REG_THRESH_ACT, 0x52); if (ret) return ret; --=20 2.39.5 From nobody Wed Oct 8 02:16:10 2025 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 5AC052F6F8F; Wed, 2 Jul 2025 23:08:32 +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=1751497714; cv=none; b=lEW2Lfo+O/4l9uwOoooLxJlFIe/lUFAPpg0BR6J2h/hBODhjAGz5Yr/JVuwnWbzwr/3u+ku7wqGOMh/VcZAVbVqsS+0h+ZBMBv6cgta897EWnBTZyJMYtzbWE3H5nwxfNipxEXTSo64qyZxtd3c+rBPsmPjwYwt3n7jYCArUz64= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497714; c=relaxed/simple; bh=wKtvDQZu6l90x2OlmiXHmRu8/yrPWXsTFGnokuDXXGg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TbqHmenVIu5yhrV4xLx7EM+YgNSLJSP7Ct86q6OEYJmJ2b92bYUBXr/fKT+6VJ19yjpkKB97xoGOwgwSAvYJv0NYPshtkngMI1dv/vPOTvgvGq4AqzVXeia4ZmvoHPhPZ9P+JaP1GTXtqizpa6hMogW3HQ+XwxzDZKAqpUgKJoo= 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=GcCOo5Hz; 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="GcCOo5Hz" Received: by mail-ej1-f42.google.com with SMTP id a640c23a62f3a-ae0cee8c1d2so101259466b.0; Wed, 02 Jul 2025 16:08:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497711; x=1752102511; 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=k6aGXjZeOxHiO0bsZaqRt7xOA1xwQMEIOJ9yT+ooLKs=; b=GcCOo5HzYIzNbZ8IIv4pkig62mMODMWdmUSxCqEAk2/Rrzd2V54uDKdTJoh1/CHSMP 1Fp26qXBJ6836+bZt5vICQPQ+oISDz3NeegtjZs95Skk98EexnJcMda7DAnrIlZMWUpa uUTxalVE3e2wm+5aSZtXMVpECowkonMGHKo8NgNefgYVjwRtUr112UMa9cc/C9IwylDo w9MpDSbyzSCkgXdYb2W60U5mKGthO59cCuoZJ3zuVvPtm1VydoBSOU/ysC/EP06UMpak 8elSGo915FRXz0oxAXW2qxslcPGb1eWN5tAzRqObGR9VsWw+N85Lgf+GVWPt+7OQBgKN 4XHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497711; x=1752102511; 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=k6aGXjZeOxHiO0bsZaqRt7xOA1xwQMEIOJ9yT+ooLKs=; b=DaylUJGqj94hMNfUoDlD7C+gXwFtlUwe/rBwK9Hw2shEIH4Allx20jnp/kVHjrJfwE O3wYKX6ZseNkMrWztXrKHDJILyFLZlDVCyXTsIsTabdFA2zoi9l2UjjST8HZJ0yhOhas wbWg7dRGYKGbEQODC7j6UdFHiFkGZ6pOGWvyM6v08TdWbx3HZ0Bcu6M83BvFT2tKusKk eZ5UY6x8qxR+1XcCGHfwzkP/PlWbSPStC8qxOlU4+WNfvG21UNIZ0ZKm0LnzxMHpR1I9 DW2LI2wov8k3XbagI7QhA9S+qgPvKBt6CmrXRbrZPFkyDbCiq1Q3D5B+YChcBK5iitXh rm+A== X-Forwarded-Encrypted: i=1; AJvYcCUsZaojFy3pwVLkpvbxKlVq89rIbivg2EsqbwEs0YlFUBisA9saofCo+uLfLLeiyYKpLx5GfTwdVPQ=@vger.kernel.org, AJvYcCWZa8qavyVglQXVdevj58y7JERCG/AH1fpDbhC8PWv64C8IuhebtDcsGXhotV5WVXstSZKYzqGCz+3K@vger.kernel.org, AJvYcCXdNL8/+01DA1iGBCOM3nCTOeh7G2vqoIkDyO4Ofr7D89Vkda2SQ0FIWrN7B3YmAnbSWS81c85NHXHr5k4l@vger.kernel.org X-Gm-Message-State: AOJu0YwplDRW587t28kZZUY67brIwBIquVwh+ZktCDnmzakoFk7FyBBu zJNmHSpLVn+hzjkisM9s4YSFs0re+FJmGKVt22+dvBN1vqDxio3emB2d X-Gm-Gg: ASbGncu7ag8wzBvDjStQTnWl0hE/iBilVU9+a4CQ2qYLzjGLndc3QRc4dZ6WV1ahy41 OaBR+PKNt1v89X5ie5PlLg2t4nQAZa49q3Vqfq+Sc6jd9ARaiwDVZW2VH8tjtjqiTUbBLzuvliG C12RPt3tYI0IGFmrzHUZD2KNxkkCT5STw3Uj6aofDoYfQw/NFN7MbtZdYKHAbmrd2/fhwSi8qvW /vtM49oEpsP4Y3pgFIY64CaUbLf51ZDoR8OQ67iLNtzNlmes2g5czCW366hzaeqhxSph/RyR+EU goYbMUGrmJyXeD6RBW7/C+Ec7FgPCz7F/HBgeWlR+R6QbcU+v5FuVo2tOu9EOQgVutcovHLslJP tbOHHK1WWef8hvyLsR7TA21SNU4yalsRH X-Google-Smtp-Source: AGHT+IGK02e4+cfORuOqUVEs88u/QXgtzUIE7b+MGx4nG0xOy+GpaM/2uaZo88uzA5B39T+ZbiKELg== X-Received: by 2002:a17:907:3d8b:b0:ad8:aa3a:772b with SMTP id a640c23a62f3a-ae3e288cd07mr5314166b.15.1751497710543; Wed, 02 Jul 2025 16:08:30 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:30 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 6/8] iio: accel: adxl313: implement power-save on inactivity Date: Wed, 2 Jul 2025 23:08:17 +0000 Message-Id: <20250702230819.19353-7-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Configure the link bit to associate activity and inactivity sensing, allowing the sensor to reflect its internal power-saving state. Additionally, enable the auto-sleep bit to transition the sensor into auto-sleep mode during periods of inactivity, as outlined in the datasheet. Reviewed-by: Andy Shevchenko Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 3 +++ drivers/iio/accel/adxl313_core.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h index d7e8cb44855b..75ef54b60f75 100644 --- a/drivers/iio/accel/adxl313.h +++ b/drivers/iio/accel/adxl313.h @@ -41,6 +41,9 @@ #define ADXL313_RATE_BASE 6 =20 #define ADXL313_POWER_CTL_MSK BIT(3) +#define ADXL313_POWER_CTL_INACT_MSK GENMASK(5, 4) +#define ADXL313_POWER_CTL_LINK BIT(5) +#define ADXL313_POWER_CTL_AUTO_SLEEP BIT(4) =20 #define ADXL313_RANGE_MSK GENMASK(1, 0) #define ADXL313_RANGE_MAX 3 diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index e904dee4dc2b..df10dc430e1c 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -396,6 +396,23 @@ static int adxl313_is_act_inact_en(struct adxl313_data= *data, return adxl313_act_int_reg[type] & regval; } =20 +static int adxl313_set_act_inact_linkbit(struct adxl313_data *data, bool e= n) +{ + int act_en, inact_en; + + act_en =3D adxl313_is_act_inact_en(data, ADXL313_ACTIVITY); + if (act_en < 0) + return act_en; + + inact_en =3D adxl313_is_act_inact_en(data, ADXL313_INACTIVITY); + if (inact_en < 0) + return inact_en; + + return regmap_assign_bits(data->regmap, ADXL313_REG_POWER_CTL, + ADXL313_POWER_CTL_AUTO_SLEEP | ADXL313_POWER_CTL_LINK, + en && act_en && inact_en); +} + static int adxl313_set_act_inact_en(struct adxl313_data *data, enum adxl313_activity_type type, bool cmd_en) @@ -455,6 +472,11 @@ static int adxl313_set_act_inact_en(struct adxl313_dat= a *data, if (ret) return ret; =20 + /* Set link-bit and auto-sleep only when ACT and INACT are enabled */ + ret =3D adxl313_set_act_inact_linkbit(data, cmd_en); + if (ret) + return ret; + return adxl313_set_measure_en(data, true); } =20 --=20 2.39.5 From nobody Wed Oct 8 02:16:10 2025 Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.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 BA8092F6FA9; Wed, 2 Jul 2025 23:08:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497716; cv=none; b=Veh3SdNWqmw7Rl0lCGyvYdmMjPJ0TNs8wc8c7lqimN24lQ61gRWVzSUqiJXCgiLzsyMw6ampebq2sIFYa+1Il+09xz+S7syE7LOoVmIGl/HzqoetnFWyAA4fjI+0Nnp/gwHzEt9ERVeDaOPABcjRvU4jpcMryggI5LRUzEmQwjU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497716; c=relaxed/simple; bh=2NYscPkXH7LujJ6YrvLFy+toBDx7nKVU2gmdbMVK+Ds=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cBPB2hlK+v1kfoCEMUD5Mm0xQHZ+i63SCdxZPxV/7tczWvV7WiiCdLy272k0zjRqyyvhSXpfu22jrIcpa8yrdPBsyFsiZU0m3yFHKK8pUXJ3WjQ5fi77C6qPhabwdvlMJwkpDeYrUvNE7x3QbLlRP3RgC1lSZ46F80R0xPPMiYA= 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=XJy8YVQj; arc=none smtp.client-ip=209.85.208.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="XJy8YVQj" Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-607247169c0so1551209a12.0; Wed, 02 Jul 2025 16:08:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497712; x=1752102512; 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=z4B+iskX/Yrubk1UAIA+RBumAroBgKkhC6vP1mpZ4uc=; b=XJy8YVQjfyH9TIO6xEsuvJ9VekLle0AaOoHUy+a4efLEfoNpd72654JqHqPygqXAo/ OfgltxR7sEg5MzOXsh30oMsmyL/2lLIpMGJ5dOfZeqpjWl9BO0TRG66fviwU2VI0yJpt siO8+oyOXZ0OZCmW58jMD9ekDYZep0hkvuVzIRFB57ff2H6xSMfmicRqfVB7lAjtxWx7 Vr5HXSBqpnasgZ5OhHc0HrZfNnOGBaBfj6CtV7Cn2oWw3qM9Sbs725ZRhPFkqCx2BmvA m/tsSbCyzhk7rcWdofqdMC4r+mwvZ9EILwIu4UOP8v7FSCDb5rz9A7sxMya0zkCekjac UUqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497712; x=1752102512; 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=z4B+iskX/Yrubk1UAIA+RBumAroBgKkhC6vP1mpZ4uc=; b=oC6t7ltBUZxx2YpTh3hK3NlR0y8RL+/FqKU9pHQdOG8SM8S8JS8GafmIVvDwFlW2l/ 2jsPTZXsXgkBFB0jz75UEeVpTiYYx7EJw/XOKWSlTOlz/je56MaTJ5DAu9MEjdMcD3J9 BeGS+q2jVN2HFvsMUECpzDDCD6W2E1hblWIDXlvezpXKgM+IcTwAfk+tKxaSchhqAedf V5RHxRr6FHtZGiLb0oQW9IIa9CRSIyLla7A4mku8B4RqwZS2TU6K/TYypcQ0sdzBJaY+ xUOiL51qL7l4FOM/wwGGGxWZvucv0UB8bwnhHTAAfk1/vI1K3LdiZi6W6ktxGyWkVHb7 jm+g== X-Forwarded-Encrypted: i=1; AJvYcCU0K8z5qCyPdwpqGRIzajXVdM6komB8H9XWEBwEXKxFrNr+Fv+EvU4yTWzAduqfy0B+SKPRls2CnvY=@vger.kernel.org, AJvYcCU9YWVAPha+sSlx98ytPhmB5lsD8Lxac45UzZQkwPFrP/kah+M9RymfC24lvj/mHBE3SURB1P0M1+EZXJjZ@vger.kernel.org, AJvYcCWH79qryta8DbSZ2BYqCGq+rqQOU0C/zHVuVmcJMagWrX06gUae+YFr7LkqDO/PU4IWhx7elz/xyE9S@vger.kernel.org X-Gm-Message-State: AOJu0Yz82INXTexHl1LhVIx7qMUr/bTTvm9Ek2gPuOR+O2nqNzOSSoWL 8z7LCOwnILZsotgxi68F7rTGBNHHFwkR+OokE6b2fbJnITK/v+dQOcPlG4biTg== X-Gm-Gg: ASbGncvjS0F/N+wD1qMPQ7qfEBUgbyXhtNqLpBOTHMEYYnvsmqnD7NUmXLE3TrA2SQy 8YdzrCB+6IHYWQIiFZTQYt1onwbNoO18nC6y0v5q3LmtTp+ixqMjiLsD84+jVAOeL+DfWsdKTsJ 4RMN3VO3A0NPYfXVgq9dViHPup76LqBJYw5RfhE0tcWszUSqxXZ8U6LV9ycTyWaAMzSt6RjvfVo b9mWYb2XKRJCSeWj0JZzznnj1gvDSeNU9oMmAcZxclKlLvCUTtnVMNab8sd09/RPcXI6GLgvddu WgA4tNGvfpNwQAZ8NwypGVAmy/44jje93z+Y+sh6T2qQVlk8kNyDLBU+vNOwmGPSSczicqpRGtq XAhgg6JqwB8teiPDPMZXFd1wpQ117bHMt X-Google-Smtp-Source: AGHT+IHCqgkMJc9oI/BxLtFpKdhNkWt++X1s7AXorGIRhDzVTMYoD7D3Df8ihICyvnd6FKJnzxNWFQ== X-Received: by 2002:a17:907:3e24:b0:ade:902e:7b4b with SMTP id a640c23a62f3a-ae3c2adb981mr146381366b.7.1751497711811; Wed, 02 Jul 2025 16:08:31 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:31 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 7/8] iio: accel: adxl313: add AC coupled activity/inactivity events Date: Wed, 2 Jul 2025 23:08:18 +0000 Message-Id: <20250702230819.19353-8-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce AC-coupled activity and inactivity as MAG_ADAPTIVE events. This adds a new set of threshold and duration configuration options, ensures proper handling of event disabling, and extends the use of the link bit to support complementary event configurations. For example, either ACTIVITY or ACTIVITY_AC can be enabled, but only the most recently set configuration will remain active. Disabling ACTIVITY will have no effect if ACTIVITY_AC is currently enabled, as the event types must match (i.e., ACTIVITY_AC must be explicitly disabled). When either INACTIVITY or INACTIVITY_AC is enabled alongside an activity event, the link bit is set. With the link bit and auto-sleep enabled, activity and inactivity events represent changes in the sensor's power-saving state and are only triggered upon actual state transitions. Since AC coupling uses separate bits for activity and inactivity, each can be configured independently. For instance, ACTIVITY can be linked with INACTIVITY_AC. If one of the linked events is disabled, the link bit is cleared. In that case, the remaining event will no longer reflect a state transition but will instead trigger based on periodic inactivity or whenever the activity threshold is exceeded. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313_core.c | 214 +++++++++++++++++++++++++++++-- 1 file changed, 200 insertions(+), 14 deletions(-) diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index df10dc430e1c..c62e669d41e8 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -30,20 +30,38 @@ #define ADXL313_ACT_XYZ_EN GENMASK(6, 4) #define ADXL313_INACT_XYZ_EN GENMASK(2, 0) =20 +#define ADXL313_REG_ACT_ACDC_MSK BIT(7) +#define ADXL313_REG_INACT_ACDC_MSK BIT(3) +#define ADXL313_COUPLING_DC 0 +#define ADXL313_COUPLING_AC 1 + /* activity/inactivity */ enum adxl313_activity_type { ADXL313_ACTIVITY, ADXL313_INACTIVITY, + ADXL313_ACTIVITY_AC, + ADXL313_INACTIVITY_AC, }; =20 static const unsigned int adxl313_act_int_reg[] =3D { [ADXL313_ACTIVITY] =3D ADXL313_INT_ACTIVITY, [ADXL313_INACTIVITY] =3D ADXL313_INT_INACTIVITY, + [ADXL313_ACTIVITY_AC] =3D ADXL313_INT_ACTIVITY, + [ADXL313_INACTIVITY_AC] =3D ADXL313_INT_INACTIVITY, }; =20 static const unsigned int adxl313_act_thresh_reg[] =3D { [ADXL313_ACTIVITY] =3D ADXL313_REG_THRESH_ACT, [ADXL313_INACTIVITY] =3D ADXL313_REG_THRESH_INACT, + [ADXL313_ACTIVITY_AC] =3D ADXL313_REG_THRESH_ACT, + [ADXL313_INACTIVITY_AC] =3D ADXL313_REG_THRESH_INACT, +}; + +static const unsigned int adxl313_act_acdc_msk[] =3D { + [ADXL313_ACTIVITY] =3D ADXL313_REG_ACT_ACDC_MSK, + [ADXL313_INACTIVITY] =3D ADXL313_REG_INACT_ACDC_MSK, + [ADXL313_ACTIVITY_AC] =3D ADXL313_REG_ACT_ACDC_MSK, + [ADXL313_INACTIVITY_AC] =3D ADXL313_REG_INACT_ACDC_MSK, }; =20 static const struct regmap_range adxl312_readable_reg_range[] =3D { @@ -255,6 +273,13 @@ static const struct iio_event_spec adxl313_activity_ev= ents[] =3D { .mask_separate =3D BIT(IIO_EV_INFO_ENABLE), .mask_shared_by_type =3D BIT(IIO_EV_INFO_VALUE), }, + { + /* activity, AC bit set */ + .type =3D IIO_EV_TYPE_MAG_ADAPTIVE, + .dir =3D IIO_EV_DIR_RISING, + .mask_separate =3D BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type =3D BIT(IIO_EV_INFO_VALUE), + }, }; =20 static const struct iio_event_spec adxl313_inactivity_events[] =3D { @@ -266,6 +291,14 @@ static const struct iio_event_spec adxl313_inactivity_= events[] =3D { .mask_shared_by_type =3D BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_PERIOD), }, + { + /* inactivity, AC bit set */ + .type =3D IIO_EV_TYPE_MAG_ADAPTIVE, + .dir =3D IIO_EV_DIR_FALLING, + .mask_separate =3D BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type =3D BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD), + }, }; =20 enum adxl313_chans { @@ -363,11 +396,72 @@ static int adxl313_set_inact_time_s(struct adxl313_da= ta *data, return regmap_write(data->regmap, ADXL313_REG_TIME_INACT, val); } =20 +/** + * adxl313_is_act_inact_ac() - Check if AC coupling is enabled. + * @data: The device data. + * @type: The activity or inactivity type. + * + * Provide a type of activity or inactivity, combined with either AC coupl= ing + * set, or default to DC coupling. This function verifies if the combinati= on is + * currently enabled or not. + * + * Return: if the provided activity type has AC coupling enabled or a nega= tive + * error value. + */ +static int adxl313_is_act_inact_ac(struct adxl313_data *data, + enum adxl313_activity_type type) +{ + unsigned int regval; + bool coupling; + int ret; + + ret =3D regmap_read(data->regmap, ADXL313_REG_ACT_INACT_CTL, ®val); + if (ret) + return ret; + + coupling =3D adxl313_act_acdc_msk[type] & regval; + + switch (type) { + case ADXL313_ACTIVITY: + case ADXL313_INACTIVITY: + return coupling =3D=3D ADXL313_COUPLING_DC; + case ADXL313_ACTIVITY_AC: + case ADXL313_INACTIVITY_AC: + return coupling =3D=3D ADXL313_COUPLING_AC; + default: + return -EINVAL; + } +} + +static int adxl313_set_act_inact_ac(struct adxl313_data *data, + enum adxl313_activity_type type, + bool cmd_en) +{ + unsigned int act_inact_ac; + + switch (type) { + case ADXL313_ACTIVITY_AC: + case ADXL313_INACTIVITY_AC: + act_inact_ac =3D ADXL313_COUPLING_AC && cmd_en; + break; + case ADXL313_ACTIVITY: + case ADXL313_INACTIVITY: + act_inact_ac =3D ADXL313_COUPLING_DC && cmd_en; + break; + default: + return -EINVAL; + } + + return regmap_assign_bits(data->regmap, ADXL313_REG_ACT_INACT_CTL, + adxl313_act_acdc_msk[type], act_inact_ac); +} + static int adxl313_is_act_inact_en(struct adxl313_data *data, enum adxl313_activity_type type) { unsigned int axis_ctrl; unsigned int regval; + bool int_en; int ret; =20 ret =3D regmap_read(data->regmap, ADXL313_REG_ACT_INACT_CTL, &axis_ctrl); @@ -377,10 +471,12 @@ static int adxl313_is_act_inact_en(struct adxl313_dat= a *data, /* Check if axis for activity are enabled */ switch (type) { case ADXL313_ACTIVITY: + case ADXL313_ACTIVITY_AC: if (!FIELD_GET(ADXL313_ACT_XYZ_EN, axis_ctrl)) return false; break; case ADXL313_INACTIVITY: + case ADXL313_INACTIVITY_AC: if (!FIELD_GET(ADXL313_INACT_XYZ_EN, axis_ctrl)) return false; break; @@ -393,21 +489,39 @@ static int adxl313_is_act_inact_en(struct adxl313_dat= a *data, if (ret) return ret; =20 - return adxl313_act_int_reg[type] & regval; + int_en =3D adxl313_act_int_reg[type] & regval; + if (!int_en) + return false; + + /* Check if configured coupling matches provided type */ + return adxl313_is_act_inact_ac(data, type); } =20 static int adxl313_set_act_inact_linkbit(struct adxl313_data *data, bool e= n) { + int act_ac_en, inact_ac_en; int act_en, inact_en; =20 act_en =3D adxl313_is_act_inact_en(data, ADXL313_ACTIVITY); if (act_en < 0) return act_en; =20 + act_ac_en =3D adxl313_is_act_inact_en(data, ADXL313_ACTIVITY_AC); + if (act_ac_en < 0) + return act_ac_en; + inact_en =3D adxl313_is_act_inact_en(data, ADXL313_INACTIVITY); if (inact_en < 0) return inact_en; =20 + inact_ac_en =3D adxl313_is_act_inact_en(data, ADXL313_INACTIVITY_AC); + if (inact_ac_en < 0) + return inact_ac_en; + + act_en =3D act_en || act_ac_en; + + inact_en =3D inact_en || inact_ac_en; + return regmap_assign_bits(data->regmap, ADXL313_REG_POWER_CTL, ADXL313_POWER_CTL_AUTO_SLEEP | ADXL313_POWER_CTL_LINK, en && act_en && inact_en); @@ -433,7 +547,7 @@ static int adxl313_set_act_inact_en(struct adxl313_data= *data, return 0; =20 /* When turning on inactivity, check if inact time is valid */ - if (type =3D=3D ADXL313_INACTIVITY) { + if (type =3D=3D ADXL313_INACTIVITY || type =3D=3D ADXL313_INACTIVITY_AC)= { ret =3D regmap_read(data->regmap, ADXL313_REG_TIME_INACT, &inact_time_s); @@ -443,6 +557,16 @@ static int adxl313_set_act_inact_en(struct adxl313_dat= a *data, if (!inact_time_s) return 0; } + } else { + /* + * When turning off an activity, ensure that the correct + * coupling event is specified. This step helps prevent misuse - + * for example, if an AC-coupled activity is active and the + * current call attempts to turn off a DC-coupled activity, this + * inconsistency should be detected here. + */ + if (adxl313_is_act_inact_ac(data, type) <=3D 0) + return 0; } =20 /* Start modifying configuration registers */ @@ -453,9 +577,11 @@ static int adxl313_set_act_inact_en(struct adxl313_dat= a *data, /* Enable axis according to the command */ switch (type) { case ADXL313_ACTIVITY: + case ADXL313_ACTIVITY_AC: axis_ctrl =3D ADXL313_ACT_XYZ_EN; break; case ADXL313_INACTIVITY: + case ADXL313_INACTIVITY_AC: axis_ctrl =3D ADXL313_INACT_XYZ_EN; break; default: @@ -466,6 +592,11 @@ static int adxl313_set_act_inact_en(struct adxl313_dat= a *data, if (ret) return ret; =20 + /* Update AC/DC-coupling according to the command */ + ret =3D adxl313_set_act_inact_ac(data, type, cmd_en); + if (ret) + return ret; + /* Enable the interrupt line, according to the command */ ret =3D regmap_assign_bits(data->regmap, ADXL313_REG_INT_ENABLE, adxl313_act_int_reg[type], cmd_en); @@ -596,6 +727,10 @@ static int adxl313_read_event_config(struct iio_dev *i= ndio_dev, return adxl313_read_mag_config(data, dir, ADXL313_ACTIVITY, ADXL313_INACTIVITY); + case IIO_EV_TYPE_MAG_ADAPTIVE: + return adxl313_read_mag_config(data, dir, + ADXL313_ACTIVITY_AC, + ADXL313_INACTIVITY_AC); default: return -EINVAL; } @@ -615,6 +750,11 @@ static int adxl313_write_event_config(struct iio_dev *= indio_dev, ADXL313_ACTIVITY, ADXL313_INACTIVITY, state); + case IIO_EV_TYPE_MAG_ADAPTIVE: + return adxl313_write_mag_config(data, dir, + ADXL313_ACTIVITY_AC, + ADXL313_INACTIVITY_AC, + state); default: return -EINVAL; } @@ -714,6 +854,11 @@ static int adxl313_read_event_value(struct iio_dev *in= dio_dev, ADXL313_ACTIVITY, ADXL313_INACTIVITY, val, val2); + case IIO_EV_TYPE_MAG_ADAPTIVE: + return adxl313_read_mag_value(data, dir, info, + ADXL313_ACTIVITY_AC, + ADXL313_INACTIVITY_AC, + val, val2); default: return -EINVAL; } @@ -734,6 +879,11 @@ static int adxl313_write_event_value(struct iio_dev *i= ndio_dev, ADXL313_ACTIVITY, ADXL313_INACTIVITY, val, val2); + case IIO_EV_TYPE_MAG_ADAPTIVE: + return adxl313_write_mag_value(data, dir, info, + ADXL313_ACTIVITY_AC, + ADXL313_INACTIVITY_AC, + val, val2); default: return -EINVAL; } @@ -880,28 +1030,64 @@ static int adxl313_fifo_push(struct iio_dev *indio_d= ev, int samples) static int adxl313_push_events(struct iio_dev *indio_dev, int int_stat) { s64 ts =3D iio_get_time_ns(indio_dev); + struct adxl313_data *data =3D iio_priv(indio_dev); + unsigned int regval; int ret =3D -ENOENT; =20 if (FIELD_GET(ADXL313_INT_ACTIVITY, int_stat)) { - ret =3D 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_RISING), - ts); + ret =3D regmap_read(data->regmap, ADXL313_REG_ACT_INACT_CTL, ®val); if (ret) return ret; + + if (FIELD_GET(ADXL313_REG_ACT_ACDC_MSK, regval)) { + /* AC coupled */ + ret =3D iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_MAG_ADAPTIVE, + IIO_EV_DIR_RISING), + ts); + if (ret) + return ret; + } else { + /* DC coupled, relying on THRESH */ + ret =3D 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_RISING), + ts); + if (ret) + return ret; + } } =20 if (FIELD_GET(ADXL313_INT_INACTIVITY, int_stat)) { - ret =3D iio_push_event(indio_dev, - IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_MOD_X_AND_Y_AND_Z, - IIO_EV_TYPE_MAG, - IIO_EV_DIR_FALLING), - ts); + ret =3D regmap_read(data->regmap, ADXL313_REG_ACT_INACT_CTL, ®val); if (ret) return ret; + + if (FIELD_GET(ADXL313_REG_INACT_ACDC_MSK, regval)) { + /* AC coupled */ + ret =3D iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_AND_Y_AND_Z, + IIO_EV_TYPE_MAG_ADAPTIVE, + IIO_EV_DIR_FALLING), + ts); + if (ret) + return ret; + } else { + /* DC coupled, relying on THRESH */ + ret =3D iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_AND_Y_AND_Z, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_FALLING), + ts); + if (ret) + return ret; + } } =20 return ret; --=20 2.39.5 From nobody Wed Oct 8 02:16:10 2025 Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.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 1158C2F6F86; Wed, 2 Jul 2025 23:08:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497717; cv=none; b=qV36ivUhtKelfm1B61y0ya/Y1/mGFBVOtisHBTSi5c0YscL1bdaQciZsN8clqlz1nQgeRE8QGUDzxymsLqcBbxBq+8KB8reEylvu4B4SIvIDV48T7377ITcoyOwKJF6tC0pN0Qvo5erhdjbjzZVK6AGxpbsIDM5qN44Pi3ZiMGk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751497717; c=relaxed/simple; bh=jkBbAhmMyc0MVV9hyhNL21f7zsQ0Ubyu8peDPdVynZc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=R3mCtZBbqR6q+CAClgKscHRm5JVY0bayFleh7GtBZ4cx0Eh0o5hU53BxSzYGqeZxXzsILCCVqoWbmmLNTrKqfyqlQYapyHos9lxUeQJxJ15I+ksGTawcF7Bp9VNkU3UcNgETYi8enyPMznFXhdbrqT6iHHPkl/Z4giG97M2Cb4Q= 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=Iel2kQnM; arc=none smtp.client-ip=209.85.208.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="Iel2kQnM" Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-606c6bb1d03so1171402a12.1; Wed, 02 Jul 2025 16:08:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751497713; x=1752102513; 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=OVBwNL6M5w5Yn3pFicOPIVN6N33/P4g9gmRLRuIsmOM=; b=Iel2kQnMvhwk7ebEEFkoXegIe1V5hT9go+MxQf+6HKxhVdS4hkForUCFrGbBicmsd9 eDjzeF60VW+MAfx8jEV6rlIClD4Mv94V9WsRAu6Slkc6brDHqInjTlrrueDH5sy0deaO 8Y4ep6DZapYwvkLZBKv5oB5QEP2fLtHE4hyfpoRhYH6oDWufVG5GfIgefqV065GH+Pla XFc3yA2ZdPUR1AEMMyuU0q5KwigDZwChwdCLqbqC8kjG8EvN7of8CsJ8dZekC1ZIlvBS V8fqmym97wvEsgWlSP+sglEOanzZE1OOgUWGTz+1soCZSSDfFB+anZU3IDRLyboRl+Bs l1pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751497713; x=1752102513; 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=OVBwNL6M5w5Yn3pFicOPIVN6N33/P4g9gmRLRuIsmOM=; b=Iu1xqsSGWfn2MViBkmMR9EfdCsLx1M3vFEVcHezcehynRu9Hy8o8Lgtajvc3IU0mP2 8u0wk+sD0AWagxkk6NtOTh6/40mvw4OM1LpVyYWS5YJGudnD9BgV3cU/6vug/URU1wlX QrAU7ccx6aVHQ2T1UzROF93GrJY6448PAS9ex6YuvpvI+DQ4TM57hzVV0URiHao+uNHR aqI6i0S7JuT7fcW97s2HR2RK5SrA/sq/4pxhDbTqX4LL0+bk1YVYsIsuCqdareA0zOdk a9wnKZDTFRRsWz7Rvg9KyL0O2t+n61j0S+z7mRimaD5+zwjkIcrab6uBn/cSr7vhyLM4 lxrQ== X-Forwarded-Encrypted: i=1; AJvYcCUDqbJAAODfrdjt9XTyX7rGPSvbqURWA/al0e8ncSacY50a8TdEPVmUDMyEiDwoFN15BGjVuXrtNpuUG7Y+@vger.kernel.org, AJvYcCUVq+7Hl+/D0c/LlfxuEnADuiTLp2918MmDKiWE7mKUfVIiF2X46iK2MjU2bk3xYKP7pv0MaJdtBPEz@vger.kernel.org, AJvYcCVF/ANGzv/hb5zS6DB9OyIb7BNAo/gM6+Hd1ZnFgRDMV+sYago6JkHiJGY+Hs6hTOi/vCrf6sBulN0=@vger.kernel.org X-Gm-Message-State: AOJu0YyOmSG3F8jems+uJrNf4f8pZwfHICY02CN7t/QjkgrDB1yDPpTU tdZibKq+NP010RBiPd5vbOlOKQN5w3Ut7CZtI+FN5UZee15M9fuPMPtz X-Gm-Gg: ASbGnctItdoilG+PbmZcaJpHyam0wFAxwF0JGrWdMlhvpQwEXCo71x4PoJPLaaKI9PO tuYp29Fqvpn6Sts0qWPnsqbmhyBSxB/fdlD3JB7ysaGsGCZBAtFOEsObJg7wSXqickp1XRaCiU4 jSq6M2YDHsIoQL2wgmLPpCXqwWvk3xB6vka51w/1hHtkb5Gm5dAb326RIeH0InoAJD0ZvheJ3HE k6NqfW+9j6GtLFC4NL8fUBl6y8fid51MI62zbsb4tbwsZAst5ObDlilGH3qM6wQsEXiaePxA1/k ztSKpJtsd+wG+QjhEOB9J85r6EdC+OabEWQlcWvryINiGwLJWiWx5MqR0qALabfD5uh0w/cDuHc mYnKTxN4oxrACCOD6WlYUA6s3AIzdykZ8 X-Google-Smtp-Source: AGHT+IEpv3HHtORLiwaicK/Hll0VtR5UFuFah+y3+rr4z8H2KVvW5KE6CfAyqZLCfiM/b7L9QwRwUg== X-Received: by 2002:a17:907:3d8c:b0:ae0:ba0e:ae59 with SMTP id a640c23a62f3a-ae3e2587026mr6383966b.7.1751497713121; Wed, 02 Jul 2025 16:08:33 -0700 (PDT) Received: from localhost.localdomain (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae353ca18bbsm1158355566b.151.2025.07.02.16.08.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Jul 2025 16:08:32 -0700 (PDT) From: Lothar Rubusch To: jic23@kernel.org, dlechner@baylibre.com, nuno.sa@analog.com, andy@kernel.org, corbet@lwn.net, lucas.p.stankus@gmail.com, lars@metafoo.de, Michael.Hennerich@analog.com, bagasdotme@gmail.com Cc: l.rubusch@gmail.com, linux-iio@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 8/8] docs: iio: add ADXL313 accelerometer Date: Wed, 2 Jul 2025 23:08:19 +0000 Message-Id: <20250702230819.19353-9-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250702230819.19353-1-l.rubusch@gmail.com> References: <20250702230819.19353-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add documentation for the ADXL313 accelerometer driver. Reviewed-by: Andy Shevchenko Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- Documentation/iio/adxl313.rst | 289 ++++++++++++++++++++++++++++++++++ Documentation/iio/index.rst | 1 + 2 files changed, 290 insertions(+) create mode 100644 Documentation/iio/adxl313.rst diff --git a/Documentation/iio/adxl313.rst b/Documentation/iio/adxl313.rst new file mode 100644 index 000000000000..41b9cc37981c --- /dev/null +++ b/Documentation/iio/adxl313.rst @@ -0,0 +1,289 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +ADXL313 driver +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +This driver supports Analog Device's ADXL313 on SPI/I2C bus. + +1. Supported devices +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +* `ADXL313 `_ + +The ADXL313is a low noise density, low power, 3-axis accelerometer with +selectable measurement ranges. The ADXL313 supports the =C2=B10.5 g, =C2= =B11 g, =C2=B12 g and +=C2=B14 g ranges. + +2. Device attributes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Accelerometer measurements are always provided. + +Each IIO device, has a device folder under ``/sys/bus/iio/devices/iio:devi= ceX``, +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 document= ed in +the IIO ABI documentation. + +The following tables show the adxl313 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_scale | Scale for the accele= rometer channels. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x_calibbias | Calibration offset f= or the X-axis accelerometer channel. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x_raw | Raw X-axis accelerom= eter channel value. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_y_calibbias | y-axis acceleration = offset correction | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_y_raw | Raw Y-axis accelerom= eter channel value. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_z_calibbias | Calibration offset f= or the Z-axis accelerometer channel. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_z_raw | Raw Z-axis accelerom= eter channel value. | ++---------------------------------------------------+---------------------= -------------------------------------+ + ++---------------------------------------+---------------------------------= -------------+ +| Miscellaneous device files | Description = | ++---------------------------------------+---------------------------------= -------------+ +| name | Name of the IIO device. = | ++---------------------------------------+---------------------------------= -------------+ +| in_accel_sampling_frequency | Currently selected sample rate. = | ++---------------------------------------+---------------------------------= -------------+ +| in_accel_sampling_frequency_available | Available sampling frequency con= figurations. | ++---------------------------------------+---------------------------------= -------------+ + +The iio event related settings, found in ``/sys/bus/iio/devices/iio:device= X/events``. + ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_adaptive_falling_period | AC coupled inactivit= y time. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_adaptive_falling_value | AC coupled inactivit= y threshold. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_adaptive_rising_value | AC coupled activity = threshold. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_falling_period | Inactivity time. = | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_falling_value | Inactivity threshold= . | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_rising_value | Activity threshold. = | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\&y\&z_mag_adaptive_falling_en | Enable or disable AC= coupled inactivity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\|y\|z_mag_adaptive_rising_en | Enable or disable AC= coupled activity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\&y\&z_mag_falling_en | Enable or disable in= activity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\|y\|z_mag_rising_en | Enable or disable ac= tivity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ + +The default coupling is DC coupled events. In this case the threshold will +be in place as such, where for the AC coupled case an adaptive threshold +(described in the datasheet) will be applied by the sensor. In general act= ivity, +i.e. ``ACTIVITY`` or ``ACTIVITY_AC`` and inactivity i.e. ``INACTIVITY`` or +``INACTIVITY_AC``, will be linked with auto-sleep enabled when both are en= abled. +This means in particular ``ACTIVITY`` can also be linked to ``INACTIVITY_A= C`` +and vice versa, without problem. + +Note here, that ``ACTIVITY`` and ``ACTIVITY_AC`` are mutually exclusive. T= his +means, that the most recent configuration will be set. For instance, if +``ACTIVITY`` is enabled, and ``ACTIVITY_AC`` will be enabled, the sensor d= river +will have ``ACTIVITY`` disabled, but ``ACTIVITY_AC`` enabled. The same is = valid +for inactivity. In case of turning off an event, it has to match to what is +actually enabled, i.e. enabling ``ACTIVITY_AC`` and then disabling ``ACTIV= ITY`` +is simply ignored as it is already disabled. Or, as if it was any other not +enabled event, too. + +Channels 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 ch= annel, +apply the following formula: + +.. code-block:: + + processed value =3D (_raw + _offset) * _scale + +Where _offset and _scale are device attributes. If no _offset attribute is +present, simply assume its value is 0. + +The ADXL313 driver offers data for a single types of channels, the table b= elow +shows the measurement units for the processed value, which are defined by = the +IIO framework: + ++-------------------------------------+---------------------------+ +| Channel type | Measurement unit | ++-------------------------------------+---------------------------+ +| Acceleration on X, Y, and Z axis | Meters per Second squared | ++-------------------------------------+---------------------------+ + +Usage examples +-------------- + +Show device name: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat name + adxl313 + +Show accelerometer channels value: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_raw + 2 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_y_raw + -57 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_z_raw + 2 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_scale + 0.009576806 + +The accelerometer values will be: + +- X-axis acceleration =3D in_accel_x_raw * in_accel_scale =3D 0.0191536 m/= s^2 +- Y-axis acceleration =3D in_accel_y_raw * in_accel_scale =3D -0.5458779 m= /s^2 +- Z-axis acceleration =3D in_accel_z_raw * in_accel_scale =3D 0.0191536 m/= s^2 + +Set calibration offset for accelerometer channels. Note, that the calibrat= ion +will be rounded according to the graduation of LSB units: + +.. 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_calibb= ias + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 48 + +Set sampling frequency: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_sampling_frequ= ency + 100.000000 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_sampling_frequ= ency_available + 6.250000 12.500000 25.000000 50.000000 100.000000 200.000000 400.0= 00000 800.000000 1600.000000 3200.000000 + + root:/sys/bus/iio/devices/iio:device0> echo 400 > in_accel_samplin= g_frequency + root:/sys/bus/iio/devices/iio:device0> cat in_accel_sampling_frequ= ency + 400.000000 + +3. Device buffers and triggers +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D + +This driver supports IIO buffers. + +All devices support retrieving the raw acceleration measurements using buf= fers. + +Usage examples +-------------- + +Select channels for buffer read: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_a= ccel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_a= ccel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_a= ccel_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:/sys/bus/iio/devices/iio:device0> hexdump -C /dev/iio\:device0 + ... + 000000d0 01 fc 31 00 c7 ff 03 fc 31 00 c7 ff 04 fc 33 00 |..1..= ...1.....3.| + 000000e0 c8 ff 03 fc 32 00 c5 ff ff fc 32 00 c7 ff 0a fc |....2= .....2.....| + 000000f0 30 00 c8 ff 06 fc 33 00 c7 ff 01 fc 2f 00 c8 ff |0....= .3...../...| + 00000100 02 fc 32 00 c6 ff 04 fc 33 00 c8 ff 05 fc 33 00 |..2..= ...3.....3.| + 00000110 ca ff 02 fc 31 00 c7 ff 02 fc 30 00 c9 ff 09 fc |....1= .....0.....| + 00000120 35 00 c9 ff 08 fc 35 00 c8 ff 02 fc 31 00 c5 ff |5....= .5.....1...| + 00000130 03 fc 32 00 c7 ff 04 fc 32 00 c7 ff 02 fc 31 00 |..2..= ...2.....1.| + 00000140 c7 ff 08 fc 30 00 c7 ff 02 fc 32 00 c5 ff ff fc |....0= .....2.....| + 00000150 31 00 c5 ff 04 fc 31 00 c8 ff 03 fc 32 00 c8 ff |1....= .1.....2...| + 00000160 01 fc 31 00 c7 ff 05 fc 31 00 c3 ff 04 fc 31 00 |..1..= ...1.....1.| + 00000170 c5 ff 04 fc 30 00 c7 ff 03 fc 31 00 c9 ff 03 fc |....0= .....1.....| + ... + +Enabling activity detection: + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 1.28125 > ./events/in_= accel_mag_rising_value + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_= x\|y\|z_mag_rising_en + + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + Found IIO device with name adxl313 with device number 0 + + Event: time: 1748795762298351281, type: accel(x|y|z), channel: 0, = evtype: mag, direction: rising + Event: time: 1748795762302653704, type: accel(x|y|z), channel: 0, = evtype: mag, direction: rising + Event: time: 1748795762304340726, type: accel(x|y|z), channel: 0, = evtype: mag, direction: rising + ... + +Disabling activity detection: + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 0 > ./events/in_accel_= x\|y\|z_mag_rising_en + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + + +Enabling inactivity detection: + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 1.234375 > ./events/in= _accel_mag_falling_value + root:/sys/bus/iio/devices/iio:device0> echo 5 > ./events/in_accel_= mag_falling_period + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_= x\&y\&z_mag_falling_en + + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + Found IIO device with name adxl313 with device number 0 + Event: time: 1748796324115962975, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + Event: time: 1748796329329981772, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + Event: time: 1748796334543399706, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + ... + + +Now, enabling activity, e.g. the AC coupled counter-part ``ACTIVITY_AC`` + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 1.28125 > ./events/in_= accel_mag_rising_value + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_= x\|y\|z_mag_rising_en + + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + Found IIO device with name adxl313 with device number 0 + + Event: time: 1748796880354686777, type: accel(x|y|z), channel: 0, = evtype: mag_adaptive, direction: rising + <5s of inactivity, then> + Event: time: 1748796885543252017, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + + Event: time: 1748796887756634678, type: accel(x|y|z), channel: 0, = evtype: mag_adaptive, direction: rising + + Event: time: 1748796892964368352, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + + +Note, when AC coupling is in place, the event type will be of ``mag_adapti= ve``. +AC- or DC-coupled (the default) events are used similarly. + +4. IIO Interfacing Tools +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +See Documentation/iio/iio_tools.rst for the description of the available I= IO +interfacing tools. diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 2d6afc5a8ed5..c106402a91f7 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -31,6 +31,7 @@ Industrial I/O Kernel Drivers adis16475 adis16480 adis16550 + adxl313 adxl380 bno055 ep93xx_adc --=20 2.39.5