From nobody Thu Oct 9 01:16:05 2025 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EE6431DED6D; Sun, 22 Jun 2025 12:29:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595385; cv=none; b=I6ISHuaHYy/QFulLTJCXlGuoEDl9kygP1kZ4beI63iEK1sSGGemRzicDGKBWd/oeh1bHcCPkZ+dOMQ3MEc/1w/Wx9BfM3YZUSvRl8gE8GTqq9qSpjearqJrnK1itDkiyYlRrD5cc0baxO/OMe9BKiExshiIZQya5TFdsjO10wYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595385; c=relaxed/simple; bh=x3Tl8ENdDkTbFqKFT8QM98diGnmwQXw3ZGN9E02Igv4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XhoV4GH6dkvg4LUKiycsl90A5awB4KbNYT9RheQLg/+oz6FlcsZrikzTJ7/XWYrBo7r7dVOgL6nG9gI69JwHT+Im2S7j/iNb06OO0h7YRIC+u/l3ZoYdVrm9Qx+4yBcEvxiUOtVu1rVFh5aBV7ufIMG1CChaoMDV9ck26WtNlrA= 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=B9y4N23+; arc=none smtp.client-ip=209.85.218.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="B9y4N23+" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-ade6ef7e6b5so63320166b.3; Sun, 22 Jun 2025 05:29:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595382; x=1751200182; 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=vyMc7SlAsIwQqZXqc0Yozk4T29hi06CER9FeMOKcH+0=; b=B9y4N23+1TxUVc41DWkh+gNI+lt1iyWztb9vz40cxWhFN2aVXMiNgHh/jYOaYZ4rbl CBZqHxs9E8u88lpxPZN0mWRlLa9S/N4H3EE45FsINh9D1OJicMco+OucG2hxT+g8XocM vPvkNJb+Yp4obC+9d9+7gIM0x0sb9oQ8UQF2yF0MYjzqcc4b0RIuz2mOm1V5Ffk1VmSE FpysV1f5m94EWz7fkvRW+z8X2IUMouz9I9tefSzLW1oE/DgOuwFvZFj4yKFS5ICG2IUt c2wwZY1A3scDeITBh8GPq4pYPA38SThH9QQ+vKy+Z/zZVAtHQB5m/WBwr5rJefa2hAu+ pS7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595382; x=1751200182; 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=vyMc7SlAsIwQqZXqc0Yozk4T29hi06CER9FeMOKcH+0=; b=dtnOJLoRVV+mstzhHs49zxWntZvBcV+I6IKkv04Vzb1GOWny2atGKkd341lLxyglN9 SztQ9i6g1lACpuiFxKQWGHa/WLf7VoRGmPGVML7zzTi7oiAnK2fzq3BnVZaLPh1K5HIO AfVNdAqNQEiJULFKZSflKwtF7gQ73GgyMqMO74l2h5AC0qLThi23X9XCimA51036rL9M ea/NrPr8ZIzwC+tlZbNM8BBdA6okqPDa1VH6HrPX4FFFRdo3XXRi0d1bMes7ZVyziCJS xD078kXXaoC38aJS1N6AfPJ8OXxmWHvscEMkqK8gsOmOh0G+91tRWwIPK+1kUHxILmLb SOyg== X-Forwarded-Encrypted: i=1; AJvYcCV0Hjojtp37KFfXaJuSbHHVEQ/Mqmy/BuAsLETYsbuzgxXFPtxSfY5Sqto/tXNjKJ60QvLvUvfYdXBC@vger.kernel.org, AJvYcCV9xLNQqYF/ha3KHxtx/BDSoDLIJUh7bvqLNPEJ9K2V3swiD1j8bQm6CEKFuI7vO4DgyIGNBD2PiJI=@vger.kernel.org, AJvYcCVoWJ4cL7R3NoO7zAL7buCuSqTDa3tTWJiqcTJrG4Tu8uulGEwj5UxpEjPAlzSvtGH+Imb6+RBKlhUKQhQ2@vger.kernel.org X-Gm-Message-State: AOJu0YzxhAyMe9AwACSrcJvwC4qYZZzqxqMPBkQin1YblfYLS665sQ4t FLtKd/mHhVXQZKHH3zIdJCWoCA/bsqALz/GSidvP0YyAoIu8G1X2BVEN X-Gm-Gg: ASbGncvuoXT5uv2ePgAJ5VZ8PW1hUz5vGT+MCn9SxsJRoOtFzVjYvuMJqmLqHQhIT8Z /lacldqSF0VI7iTE6jdlhtDuy9e6gSU4gfV7bhQ0AOGsCYj4riRnp2hOdRuFJClnerzq2OUgSyq J7RR+6i15Jlw9P2QuQqQbI08AvuvPA9Wr4ZNyYKE84dZKgDK8/p8QYoKom1oFR8IHG1fEz9rBNZ GnLUSwXRwBWJ0DsGgJPhpx0P+z1q5cG+6EIC84C7lZxSCrav6/9SIXa6kHm8MOLLSdrvhrNnn6D ETJi7E6oIUgp03d2kBbrpdmsFr03msWGK9fM8yA55F7UDzzggOPSS7DIPsgeqBiDOESYrbDapbR 0GrHi7GWbzTORcuszvkWu8A9b4iNa4JCcWNnoxBKDrgo= X-Google-Smtp-Source: AGHT+IHb13r//By+XO2L1rvSx2zzW4cP/nSWQ2gVEIkMDTpE+0nYpLfCa4LDBZN+WkOVzGXMfHJ72g== X-Received: by 2002:a17:907:c24:b0:adb:1331:a508 with SMTP id a640c23a62f3a-ae0578fbb18mr300664066b.5.1750595381962; Sun, 22 Jun 2025 05:29:41 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:41 -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 v6 1/8] iio: accel: adxl313: make use of regmap cache Date: Sun, 22 Jun 2025 12:29:30 +0000 Message-Id: <20250622122937.156930-2-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- 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 2f26da5857d4..39f16f97bb4a 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 a4cf0cf2c5aa..e8636e8ab14f 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 9a16b40bff34..68e323e81aeb 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 Thu Oct 9 01:16:05 2025 Received: from mail-ed1-f53.google.com (mail-ed1-f53.google.com [209.85.208.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10F201DF268; Sun, 22 Jun 2025 12:29:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595386; cv=none; b=QdjcP4gLntBBHSAgP6SHi9peckwWgJGMGPbSsdFrxxaBBP7WahOCz3a/AWbU3oJ6G+OtpalD+upyt27xV/dh0lRCD/PomrC6VFcM3kobHkPYUa6NPG8mD6LqFIcApzgl3SoRxhBMF+bDZXsf1TGSyzcoDZw6I3T1F6XoeV9SSio= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595386; c=relaxed/simple; bh=UcgcEqCw0PL7brA0ULNFAVG5OCacnVt1+oGOHEMXQJI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=N94wQZ5typsil1gDyrEpNTaw2OQ48WqwurgcCkZyrTeVcC8HXSg4cMqrWB3a71MkaIRMa5Sc/zq8UpLQSt6kNSCsAi6blxmSt1ZOCvzFCx1fqyXjtshmnEhCzb+0kOx0zCcHuHZsxqqc0pZS6wPafKs7ETGppt+sDITKH4W31UM= 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=KSRFNQ0A; arc=none smtp.client-ip=209.85.208.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KSRFNQ0A" Received: by mail-ed1-f53.google.com with SMTP id 4fb4d7f45d1cf-607247169c0so629716a12.0; Sun, 22 Jun 2025 05:29:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595383; x=1751200183; 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=E1N8Kch7jeHatV5Og/Y1cg3se+x+O0T3ohxb4+AYATE=; b=KSRFNQ0AAD6BVaBqjdLZzC0ypCoU2yo74CRNwY6RHv19+0EPA4e4I/1OuOp2sCuR3C gIrtFjrf0dYujgrAC+TDxA6MrpevqX5MDidIa3Ln19IiIjbdLOtnZeE0yLrvA9lxqNsk 3obCNSZPOCdsBgRS88vLLl2TusJApE62hxL1C5X3mUFtjWFhHU4ka0M8LbbYEP0hkaeH F7oTVpJllh2LyUJCxuHpwc6mFcy9AVNKvTYy+CqRaSIKimCHW58M+m2LOjnp9QpmhMg9 nBtVBgR9ZCLkOnghzRfKcOnX5XAJn7OU6+4bmRG+dZu87DGQ2+P8pVZP3pGGd3+VF3rf lSbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595383; x=1751200183; 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=E1N8Kch7jeHatV5Og/Y1cg3se+x+O0T3ohxb4+AYATE=; b=Zxvo5eHKYsAR6AOA/4WKCYoLPJe0uSEYzvAROBFS4VpgHyECDycd/a5pPJab2yGH5k MHlH7oMrGuUhsQKvctei+0wABGhihWaHfewKRdgebGK9p2shXqgwlWvCnzQJIiIsl0QC j+BHTZ+vEw2bgh/E/TIYMfdQwQujjOaYQVVfrg+O6mgxje2A5ei8MBG6GhjYwNtSM8pY WY5hBofXTprgFWwLr2RPRs1Y27Ka0l1ux9TZGjhQUVPyWq0zCtCXNIZJCUfWM1aj8i5S XNDEQ18aVzNHNKXOeRdWCt+CR+uNMgK6DLm1gCRDf9rkAdyNoioV3B0O84zQ20SNYH+l jxbQ== X-Forwarded-Encrypted: i=1; AJvYcCUMyLjZbSwP/CaR6PVIIhN+1A0Lmu7XGsG56K7tS07E6wlTGiDmY9paI0vP0eTMflcMYEa9YvgGYh8=@vger.kernel.org, AJvYcCUcuwTM2mE+YM2AkV7WwF4/1F1STd7cS5tn2yZRkB72B1SA+gBmiZtOhtc59RkRHjK/QIrSLEfcfkHe@vger.kernel.org, AJvYcCW137nsJyAMr+5X1NgoaOu/ETka+g8EcGvwhu/HTMbCBJ3gdwidFmkgAnRl/qONwxY9lga0U1myQGECCWDb@vger.kernel.org X-Gm-Message-State: AOJu0YxdZwvrxajzJZw+eYatLSq6AuFZ5wch1YLZb/qzBWzDzZaKqCb4 lqzsGs+X6eE9rD9DPY3uYnwPysD++aEkVLhm/i1LNJS4k95B8+AM8pG/ X-Gm-Gg: ASbGncvGsw1fHbrIkeX0DeeuNk4FV6T5iS68+nd0VOu20cRntOKyr58Xv0bJbBNq3s6 9f2DL0GIeCxjReU9eDCiiYRM7ADsffYv+fchHbQKdAiKBUbQjzvBgn41Gj2FhDl3fe+BmzwUGFs mRlDf8rA3foGxGL84EBipgW3mK+a2OxvOoN9wQ58WmAbgJUWZJa1yHWb7S0+ZQ2HgCwG/EuFx0/ FoE487Fz/AhW+HjejXqNNQjoU0UWxpRyW9xpcBI7+L/J5TdgEzosV/d+hqz45e93f5Tw7s1Jdu6 kEhKVQfmWDdKM8xH3OYDq9z8Sj/0YZzQg71HsASnDlUSMGzPKmW+PAfBDPE8G3sVakGhEY6IL4M Cp6QbDZYEC3tPj2DNyh9UCl/7uPxO8f9N X-Google-Smtp-Source: AGHT+IGgbo+CyMmgtJwwwuMh/pU6gITZpDTUxtrNwayU3FR0Gk6pS5tnXKxLM8Ia0s6QsOyEwZaqJg== X-Received: by 2002:a17:906:6a18:b0:adb:2f16:7ba1 with SMTP id a640c23a62f3a-ae0579549b1mr290449966b.6.1750595383091; Sun, 22 Jun 2025 05:29:43 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:42 -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 v6 2/8] iio: accel: adxl313: add function to enable measurement Date: Sun, 22 Jun 2025 12:29:31 +0000 Message-Id: <20250622122937.156930-3-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- 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 39f16f97bb4a..99a7f3755031 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 Thu Oct 9 01:16:05 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 66A8D1E1DE0; Sun, 22 Jun 2025 12:29:46 +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=1750595388; cv=none; b=kCyzNbHjocMyqQlDvQEo1uMKFtfc4dZxHj5Fw3sPZhbsMMwKGA9j3+Y/M2JbTqgPQOY+rgIRgpq7LyNTFH7ownZYQqf+tBLzwrTyQP8qrqxAQ8ilg/NIBgcVhsM/e6ivM2mvnQt+wicow7M8XF7l9/HRMVt88Z90Ti6gEPKso1w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595388; c=relaxed/simple; bh=U47VxSsT923AMCM7sAWX1CRj1lPxVzxqNUmpR3XRpgE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iZNHPD5boo9wnvQMqNU24bpsZbUcodNfkaW0+Pff5ss4+R6NIw4YJJlLmFwUAcqNEpfefgcFEhG5kTC+RKl43V33UbZim8qJwOARVcEYTQIAb8Wsfb1I+icNQ/L0Yvrcr+AXqxFaZLO6uPM0RrNy7FgBVZhDRbMWcU5/GWoEZL4= 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=iKMZktcn; 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="iKMZktcn" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-adb37582eb5so39280766b.0; Sun, 22 Jun 2025 05:29:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595385; x=1751200185; 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=qaFDIDY1vn8Zxx88K1R/ijRn1BJi8LoNJ4IVyRpgY6Y=; b=iKMZktcnBGoAPlbdvPKQiRbJycx6bdrZaWt1bdYNeBjBc30ZUT6h8J3AU34lxzDtEj o4TVSp68fHWG9oHQ0cyMPhLLtJPnywovdi00zxyTZxAyZUy5ambAVbL08nn17Vt1G+9m 7j8hKUpe1rFW4Te1Dvav/O/fSMbtWvUJEK1tuqNwfd66vs0mlf/d4vIjMlxtyH4ux4Cb Aw4dCOfwmKDFN2LQ3acPiOgekULFM4UwttaqkxbuuwOryNq3ZA7wZEsvXrO1Wp+9Wila qGEOxDUumt0qrhcP8yA/thVJkbQ7I437OZJ7iFg8LAltzF8bznrcaTBCvM39AeMfq4DK lrNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595385; x=1751200185; 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=qaFDIDY1vn8Zxx88K1R/ijRn1BJi8LoNJ4IVyRpgY6Y=; b=YDH3+0+OrYCM7JZZfetWJoBJ0xCqGSCB8vmYhQjLFGnImUZHG7ZuR8JfWMsbhan9gl Tnoj0Xkkdi0dZWLyaqoPT/4CxxL+B5bEh8bMCghC8PVqWFSRI+zMHXJpTUDPcNz40LTc 6pgWmNfK0p5H108srCZObpk51x9zw9spqiQP6yNUNKLBTzqPlPjXwVAFI6wQjgySX4I9 qQYHn7nZNhdsCc0+HEhfZFw7SzMz6s3kXto+hmg2wv73+F0XiBXO4c5SLR8WKL+3Rzuj 5SXzaeS0BV5/cjB4UlCvypu3cKDyrBOao65rNley6657X91naTG3v7468Wz8D37elpfV TbIg== X-Forwarded-Encrypted: i=1; AJvYcCUSp8/zSLJb6SswdMdAD4zs695snf+p1BQ5mIWVmbdsOSOJCx+EIrwZKWrCCRg/flckskAhQ0O+8CJG@vger.kernel.org, AJvYcCWZIVJ3KZcvxk14EN0aYO5+3Yp7bKmcf3Yv3JwW/0fVmHQ7mR2Z5klYiITXGaz6TkCNVP7XTY8Z/3M=@vger.kernel.org, AJvYcCXkjxSwFBpDfJDpaqerXjb/JzDS5ShOIbDpyGX/IuFcmRSDg//SzHv1deTXhYPczaEfy4EIVmEULcG/Scdx@vger.kernel.org X-Gm-Message-State: AOJu0YxcdvYjTu1WSICUfBMWn70xIjHhA9h0DSZ/6jWnAu+Lrm03TqwI xD5RfoIrTK5Xl7zbs/ciUlpWZNryppjn9JiLLDDGmTVhmAxI9cKhpHs20VsKkQ== X-Gm-Gg: ASbGncsvz+ZqculqzQMhv4FffdgRTPmDMJTa88ZyLqEL/vN2Auk29PQKYe5UMOUBeV1 HARJQ5DiKoiAhKG0cypP8XLePSPU2lbgk1KKm0qRhj+qFL+0guSQUCAx+p2n4F2/WA9PMPZepat uuM23xkOXDstUz8vRHaVqt9sJ1AUw2Tv10XSVzy539LokSn8iz0e2blGtS/8j+DJ1ncP7Udd3YM fnKmY6ObsPP624uWYBcsDVSzlgvwJn3VgtN0uFCY7lTrqxwXuztjW1pkjlj7oseY0U8indGZHgl eXlDADS7FIQ/s2S9sEw5/ECie41HYtg7ldcAt29XJnyxR6OujG88bkAZze0OsMqdDm8WaSbIxxZ davceWlPeMWpwGmOrJwARDdya190OE6p2 X-Google-Smtp-Source: AGHT+IHkyu6JH3YqXYF5ZwF1VgxH+2GYUH2BR2lHFXR45/+JYN5F3YO/iiLS8aSKGJevD+pVZVFMlA== X-Received: by 2002:a17:907:6e8f:b0:adb:2d38:4479 with SMTP id a640c23a62f3a-ae057a50183mr279130566b.10.1750595384245; Sun, 22 Jun 2025 05:29:44 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:43 -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 v6 3/8] iio: accel: adxl313: add buffered FIFO watermark with interrupt handling Date: Sun, 22 Jun 2025 12:29:32 +0000 Message-Id: <20250622122937.156930-4-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- 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 99a7f3755031..ac4cc16399fc 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 _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 _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 Thu Oct 9 01:16:05 2025 Received: from mail-ed1-f54.google.com (mail-ed1-f54.google.com [209.85.208.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 51FC91E51F6; Sun, 22 Jun 2025 12:29:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595389; cv=none; b=f7u8JEX8VZKlJODlEdd/yWbdkljbFdmZvepxr8SO17jKeuV7/QOfUbUuVL8OvUCFTQPlJLA3dAANsjoVHq6RJPJ/lCX2/RVWr4F0OJHcvre/JaF2DyVohMkiJYRzlmEnKYucVm0pP2MWAeM1Ql5x4Yx77FwdG73nUlOCPaoYbVQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595389; c=relaxed/simple; bh=3PoDOckA6GAwKZmOJr93WpM3yDCvhMs2mH3kSrT6B5c=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Upa6j261oMyumeG1oJlEnGXRvx81bEUhdppMx1z5bsZK8Vfr2tJDts5zO54Iy45qWUAqFpKkUc/gUxg3/Dd6kXn8/mYWSwXDbS5ta2OZO/CJC2VWxOiFwAxEFtMQKwRIpKGTNxw4/IAghfLpr4bHAtq1mXx4RnhPVKFJhAtif48= 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=UZksuU9o; arc=none smtp.client-ip=209.85.208.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UZksuU9o" Received: by mail-ed1-f54.google.com with SMTP id 4fb4d7f45d1cf-606a269d440so736809a12.2; Sun, 22 Jun 2025 05:29:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595385; x=1751200185; 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=QHc0u+m8MkMq43EquiBQUz6onUQttHIOsfhVTlhke+Q=; b=UZksuU9oI6Cncmjv33bg6eZiQt8T9rxUme1Y9Tz1of7bzCxtzAjclnei97J1G1gLyn xH9G0EII2WpkkcKfTDmJV0otNpwm8KznF4TnN0idtVbTkydOv2SdYRrl+6vwU52AC+dm aHZLrnoWbruWlr/uHvdRtKx9o2u6pfzAkLuSDkGGdgdFRfOyN9jW0N3KNy/+f7QHE2PP GsaUVQJS1MWP3WVh/omqtOuG6jBE4vpgvBbPgHFtYm+9AvxxAX+lJMk8Jzg3fuh5a03l F9x/EkkbP56mJrRgQOrGqIYRTRCeMNZHgR5b2GLJ1YHqeL4vRuZ1s7pZatTlNcv0enHO eqZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595385; x=1751200185; 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=QHc0u+m8MkMq43EquiBQUz6onUQttHIOsfhVTlhke+Q=; b=VH+JrRTxzGAPaOsBOKt183VAQ8k9YQFe6Fl12jyunwkFUBkw6zlx+ndNcuMWAx/iSE 0icJj5f4uSaWWhcrgiD6l3CuUGjtFsWw68U9ilIIim3ayiyGhdGmPs/hzUiK5j/2sBQB ZuRxvWDmLp7V1BPX237sMjEquAwQwkQaRc09l1/4yHrjXDwvNEU03R90vkQi5mr+eWU3 8ykI+Whg634ZZ0Gmm3Cr9HHL71P32Sa1X7eL1cf7XuBfJ42lZUI6bQ+q8XWg5G0om2ZP khQL+v3PsuQxvbwQYWjkSN5swQoTHauQJcM2j4aIwLqRv5x8cUzPh6D1QbgG3YWFKEZN w/Xw== X-Forwarded-Encrypted: i=1; AJvYcCUV+x8/mfPSPCi1XOB+fYO2Oi6wlY56syKQoYD0dIsZwLjM8s/NiPQepwFXzVrSQAw/a4NFk8hg4rI=@vger.kernel.org, AJvYcCW8p/+ba/gxAhK5rFni58Fy5puIn7T6qjDNnJfln0U+QYkqnCrUKVJGl/dtwgSZSgYGBVQL05/XGYgxmPZw@vger.kernel.org, AJvYcCWgA7mTCIQvvDEJyJm1KAu4BVBEeRdZkB9xGIs6qUUfLTnEzoryVOAJ9Fq/bl2AE8tIlYM8sg6ZgcB6@vger.kernel.org X-Gm-Message-State: AOJu0YzxmHgCoZqcIHy6GUvGXwSkhlq3vcNNg8oq91CIJfVmBlcIuqxp mWRVd02Nd5KLrmKK1IbxOCKci0lEHaiIKpOn47RPue9QKIsmcNWoNB2D X-Gm-Gg: ASbGncslviBjEtpKxLRpIW+M3mLm9FCSgH9pSWpBJWcqc0JVADeKh/Gn5KaiZIV8HRS kGmYLJOQ1OTWPXhIOPdVM0wOzDSeWcVVGHvflTY8FxSEIyVV5uLMLNmiACIcMruFbBLlG7wKrQT OgZ57sRY0eWxmouiXnWlRZ+8oEWXcT3E1XV/Wr0GxaDPLOMl9cVO55vgTS15a/FsALafDGu5sVq m8TWMdxy1Rssmp6fwdwYX1kNNb+CIkfFilalG1S/yuc1TIRhJrb8XI9NNT57FXvLYUfZwQJt+oI TKKpniXMnb8D6yeS3IL9V1zTIlqUIv0Pt4vB7SeM+3lTVCzzzQq4hHk9RgjgrIRCIPA29dmHp6T ZUGJVs0+E4VOFABKqkihuH+Y718i4UCYw X-Google-Smtp-Source: AGHT+IFcnWT8M3ZLiDsb8h9PbHQQ/QKV82O0Diex11Jx9L44sLpvIwp5jwJxu6CsosMO/YUGTRftNQ== X-Received: by 2002:a17:906:ef07:b0:ad8:7eed:44e8 with SMTP id a640c23a62f3a-ae0578f8113mr304491566b.5.1750595385377; Sun, 22 Jun 2025 05:29:45 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:45 -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 v6 4/8] iio: accel: adxl313: add activity sensing Date: Sun, 22 Jun 2025 12:29:33 +0000 Message-Id: <20250622122937.156930-5-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- drivers/iio/accel/adxl313_core.c | 326 +++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index ac4cc16399fc..d2c625f27555 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,177 @@ 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 adxl313_activity_type type_act, + int *val, int *val2) +{ + unsigned int threshold; + int ret; + + 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; + } +} + +static int _adxl313_write_mag_value(struct adxl313_data *data, + enum iio_event_direction dir, + enum adxl313_activity_type type_act, + int val, int val2) +{ + unsigned int regval; + + /* 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; + } +} + +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) +{ + switch (info) { + case IIO_EV_INFO_VALUE: + return _adxl313_read_mag_value(data, dir, + type_act, + val, val2); + 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) +{ + switch (info) { + case IIO_EV_INFO_VALUE: + return _adxl313_write_mag_value(data, dir, + type_act, + val, val2); + 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 +788,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 +816,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 +859,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 +1000,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 Thu Oct 9 01:16:05 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 7D7D71E7660; Sun, 22 Jun 2025 12:29:48 +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=1750595390; cv=none; b=hoxmOB9Kw764JVDNLSMba4610FkMDHrTiU38p+fGbl69+ge98VSUEOjClqWtl7V22DtJgTkFbOT9jqbnXUoQbnMV9lwJd1owDHmKrQmJIJ2+LRmHMTOyQRW44iyJ/o8XqzVQYLjvaowM0RuEg+C5TtCTss0JhWR5Tf3Hiw9isaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595390; c=relaxed/simple; bh=V6SULSuNhoVPBdjDT0FWYzZCo5UzfHrUJy3y2K9faAY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Pg11JByly3vsyzP/1qAYPCKkbCKe3sRAR4ATntnB1Nnffs7NQTytyknz1p+yFYTc+PJ9/GHATLfQG2eGMWwiy6wEpr3foU1QcWNGNKuSIVyXPlCVGjdTxPHQViZ7cIztnCSyLKC950x89xe05TKBC6cDgqILxisSZh99JL0StI0= 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=AoqfHo4t; 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="AoqfHo4t" Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-608964359f9so549003a12.1; Sun, 22 Jun 2025 05:29:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595387; x=1751200187; 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=LMZoP0GLC2kHFths+JzZF27Jj5owFN9ALATO5Vnv0z4=; b=AoqfHo4t8j0WzKg5aro6MGiSpu4kHiBY8CnOy4TqGZ3GwV1Lh4pPx/Ey6eFyQmJSwL giqXYEXTv96WlM8EUEx8jqxwQLMQXlFMUpbgwZuoYS/xaNSD3viWcDIMpSekFgpdiO+N Bw+XLEkLVZPBr4ONWOJPeYU7g/csdyRg+405DGOuXYf2s9mo8+eye79MgXDxa0EWFoKC 3QnPe7HeEF7Hm1ouMN57PNpoyxopJTFLayAse1xEc/EiQbViKxiC89nQRrdoOnwU2n1a 49QoKISF5QlnvDIY2sduBPX9p2GHaFlP7OKMNr3Y0aj+e7f+ijPYJOUR2o6ulo5xN+18 Tngg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595387; x=1751200187; 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=LMZoP0GLC2kHFths+JzZF27Jj5owFN9ALATO5Vnv0z4=; b=HgvTpl7iNYXYokHGdcTpvJDScdV5EEtXmLIYOu54r3EFNd/9N3hLYRBRQrbP7fRTlV 2T4Ii70NkHoXJ9RV8HoY4/kKdjy2sNIjHG0q3w1NhrZ5d2AKF9i8gYELLj2VVyQF5TtC E4pXjUUAiwRfb7QaYtbjPJC+0nChQk66tytNnUsWH0sd9+fbqf2y7RUpM4dAhtwNREo/ RuG6PB+arwY8DevwcIrpXYQrmciyPFGM2JoiUVWBhY82ojeAb0BGoj70s1ncn9lGfQj9 Sad5KTRViPe6qZhvPINia2wlDGebCjzDN+6SwP1MdqjiKY+SuYlCKSIL4coy8xgVOI84 u/Kw== X-Forwarded-Encrypted: i=1; AJvYcCUcZWr+6YzK+kyfBQ2VI9/z7bx5KkYlzDR1dT/ltencnzkC8BTk3D+Uuq0Lrez0ejJg5kl3kYJayPySDGH9@vger.kernel.org, AJvYcCVeRfSUa710ZnTUwo23YD7GPVaWairvVyISwfbIikNlyPvsiQH9iPLJbgN5sit0uemXa4A9ydHyayav@vger.kernel.org, AJvYcCVgWm1uICOoDRhd/klppx+zPRILXQpsyiL0ay/PQFiE4vBdCUdESapBVdTOWLTH9EZGC9OHAP31q6U=@vger.kernel.org X-Gm-Message-State: AOJu0YxA20SHEqrW0GOIrqUD+za2SNKqB6NiB2JLXMW6woLKLhC7EiGt i63Q/ASM1BNXKn244Y1Gb1vsGpMUDJGQXpBfn+ykOPExqkTBF2GuQwu6 X-Gm-Gg: ASbGncv2Fl0ya934IwK3xCCVMTkK1AB/x5wKar5JnLys/iWAkOdjvxA6XBSQncaKSQx 9YGL41hrpAAmk8/Dak0vD860VeY1oyVmznkKDzs1JEYqubYaCxgFePVTBvNR+aHYWZoVpV7JXeN k5KtDi1jI+Ed6Ce4R0d/rgDfWNfg/RmB9wY5p0F/qm5hZnYqLT5bS0IenLzsAsJa0ND0uoYvh41 Ulkt21vI2EPZns7Fp47tjudIkVSXRMSFIJWHEhtQrLykqAOiMlamQbNbZ6PbQyiCHxO94qfbj6I +5wRRCSeTUrqyzlRGezZIZtJutkN/fN1NPKF1KaYg7GuNTojTVdli9poJgYiQEf0JmZdr4stL5z tk/8DaXxmce7ipqtLKRTEcv8vdoapa435MZ2fSzSaYoo= X-Google-Smtp-Source: AGHT+IFunybjhodzz7pRltHxCmkjsMIpRvcCX8BUgoZXMCccEt/CiHZmYtcgQGrHD9b/u4uvJ3L5Sg== X-Received: by 2002:a17:906:9c82:b0:ad8:a43f:305 with SMTP id a640c23a62f3a-ae057927a19mr277025166b.8.1750595386473; Sun, 22 Jun 2025 05:29:46 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:46 -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 v6 5/8] iio: accel: adxl313: add inactivity sensing Date: Sun, 22 Jun 2025 12:29:34 +0000 Message-Id: <20250622122937.156930-6-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- drivers/iio/accel/adxl313.h | 2 + drivers/iio/accel/adxl313_core.c | 116 ++++++++++++++++++++++++++++++- 2 files changed, 116 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 d2c625f27555..36cfd23d2e3c 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; @@ -541,6 +601,7 @@ static int adxl313_write_event_config(struct iio_dev *i= ndio_dev, static int _adxl313_read_mag_value(struct adxl313_data *data, enum iio_event_direction dir, enum adxl313_activity_type type_act, + enum adxl313_activity_type type_inact, int *val, int *val2) { unsigned int threshold; @@ -556,6 +617,15 @@ 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; } @@ -564,6 +634,7 @@ static int _adxl313_read_mag_value(struct adxl313_data = *data, static int _adxl313_write_mag_value(struct adxl313_data *data, enum iio_event_direction dir, enum adxl313_activity_type type_act, + enum adxl313_activity_type type_inact, int val, int val2) { unsigned int regval; @@ -575,6 +646,10 @@ static int _adxl313_write_mag_value(struct adxl313_dat= a *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; } @@ -584,13 +659,25 @@ 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 period; + int ret; + switch (info) { case IIO_EV_INFO_VALUE: return _adxl313_read_mag_value(data, dir, type_act, + type_inact, val, val2); + 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; } @@ -600,13 +687,17 @@ static int adxl313_write_mag_value(struct adxl313_dat= a *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) { switch (info) { case IIO_EV_INFO_VALUE: return _adxl313_write_mag_value(data, dir, type_act, + type_inact, val, val2); + case IIO_EV_INFO_PERIOD: + return adxl313_set_inact_time_s(data, val); default: return -EINVAL; } @@ -625,6 +716,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; @@ -644,6 +736,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; @@ -804,6 +897,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 @@ -1009,6 +1113,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 Thu Oct 9 01:16:05 2025 Received: from mail-ed1-f45.google.com (mail-ed1-f45.google.com [209.85.208.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 494EC1EB5E5; Sun, 22 Jun 2025 12:29:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595391; cv=none; b=IPMyZVmxas4ThnjMP432PVdEfFG65pyry9IK8mjSygvYIZSGDLLUckwa6ckAHcCJK9db3HDDGGz59SX6tnsD079DY8cW6CkVe9iQ+wHu3XDECx6YnN5D6SQx4hi0ylm6GSTBTtq3e+OSVK4An1N3z1Fz+OW108//93aWhXJ3w7E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595391; c=relaxed/simple; bh=1Kw3ofbQtj/HNhdUQ4xAZrkSZ4j/+mkxZBTQo58MRnM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=T3M4+zyAkIReuO7l/ku0+ieIhBKqBfHmNzs+prJ66IOpN06M/pVYZoET7obO2MT/tTJbgAP7OWfLAMwnJOkYudkc54Ho8q8xDgn15yDebuxrGVpV4vXjFAQmbO0qPe1QW3W9ENAqwag6mMgLohkH9PPQExRjduNCNCuNZZbFq4w= 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=aQjm/o/D; arc=none smtp.client-ip=209.85.208.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="aQjm/o/D" Received: by mail-ed1-f45.google.com with SMTP id 4fb4d7f45d1cf-6006cf5000aso619160a12.0; Sun, 22 Jun 2025 05:29:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595388; x=1751200188; 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=Hy/JMiUHyBX0T2DXaBCq2snU5kx4BbgY+BhORUobO1I=; b=aQjm/o/Dx5TaHKlpwpGAaaDEPSnph+v+dO8QEn/S9zA0t9rhWz6TV7Ev005JQYMsMN ECeg9iTky9NisWln2fWvYZqrsRm79rW14p8X//Wey6GCHiMg+AZmepb/bNu2MfK4P/Z+ zrr9MEqcHW9VV2Vv1GpjyxXlZ7m77mfYB7JwMsTbuxxejmXdvq+Phdp34UMK6Tc/gQqN iETpDwvpY20aFGKnbA+UY1aaoc/9fIW0HuDc8hLGNY4CBkYDutpojDiUxWQXNuiT+ZdX GtrMMrePoTQNG6O+fqasCob0FaULtGWcvy7Y0/kjmX9jdrxfNBlBYtU2382DAJGS8nDg HkPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595388; x=1751200188; 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=Hy/JMiUHyBX0T2DXaBCq2snU5kx4BbgY+BhORUobO1I=; b=R/oLoN3zN3WDp02u5jJUNyw25IWfQKjAMJnGOxFP4WWX4/nFG+zvpTk6lcpVoXyx3O DMlo9MAD/1WkRrTNzjVL7QNpEPIB7DxXtEpDn+JOXrtV/bWn+V9RVNluivaB13rkwIgz DSCODpEHk82QWk2+/oIA2L7tZSR9PYXH4rm59mR50YonA5z5ffWywfk7f10uPuCSS0Wz lC502X+EnfdiOIys6uLKsa1Do8qxq0URPZ6CyXSyW/bH7ufdvwBG1V5xV3WA0cZ4Za0H RZEYhip1p1vliduMMdpZhgLNoaz5v1Z7uj2gK1sFNsc0oddaTnksLRu0cmELRW1DyStq sDmA== X-Forwarded-Encrypted: i=1; AJvYcCVhTcpNoCJJ938QibCDJOwaoBB2HCi2iwW0w+Nin0VcpzSESb7HhaXmx6CXbecapvutwySURlKQXnNjkEEQ@vger.kernel.org, AJvYcCVrNqSXAND3GmBa0VAnj+/MKuVsTsWB7ugM7MLXv9JO2YgAFuo4NzzJ2bCjfiEiDlTdp7vQHkf5S1vv@vger.kernel.org, AJvYcCWxpBmbOb+L1va4IRDUdIcoeUM6AhI9HddTQWhaeI8b/WLUhiJICInbnsIyrDvI4mhrPCUi/iMsEmI=@vger.kernel.org X-Gm-Message-State: AOJu0YxU5iMnqslmFZTldm1eXMNbsFotNUWrZ+2KpbuJAlhmCD1MAA7c 2eZ9GbsOoCvyYkEfCQQ1kQLf08Pl9g88qnCtx9/Qm+YBnyAScgWaa680 X-Gm-Gg: ASbGncuPy0s/ArRMc2q2rQ04MFwcviz7JR9Z0N4ZLRnDcM0/i1N1L68zTOnkBRMqdmJ c5ZZqegLhjISHuhq+s1WlEVcmslgP7daSPUbj/zJVmWOjkvtC9t2NvQArv249IU6LNx+9WW4cuU Uj5ljhKaGqCo1l0vYGvZeH4/CAkVEZy7uija0JuA0qKmjynWU93DVpmpY/qht93gAo+F6Okd0Nr o6+IsIMIbYuH5X9smX49ITbLpLBBuPdNn3ff6V9xceDOdOq8HgtWGZB7NzwXM7pJYZ74BHHTC2w YucQvXxLicx28Q8xDuryBcMT+CgUhcihrqnwmreKCCJV6jN4/6Umcox6FQ0GiU1lot76Vp+1pU+ 8jvAW8e+WGXlBmORvywMDKmTbdoHQe4EN X-Google-Smtp-Source: AGHT+IHgEDsO6A8uHrMHxJfoQvLn6dy+g6+7vAN64erFMY4b1AdR9a7gGjkPDvIH7zXh32tSNq2Puw== X-Received: by 2002:a17:907:934a:b0:ad8:8f5a:9d2b with SMTP id a640c23a62f3a-ae057b4f13fmr236526166b.16.1750595387562; Sun, 22 Jun 2025 05:29:47 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:47 -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 v6 6/8] iio: accel: adxl313: implement power-save on inactivity Date: Sun, 22 Jun 2025 12:29:35 +0000 Message-Id: <20250622122937.156930-7-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- 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 36cfd23d2e3c..40c75e90e4bf 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 Thu Oct 9 01:16:05 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 919C61D5CED; Sun, 22 Jun 2025 12:29:50 +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=1750595392; cv=none; b=oPkCTyoS/7uUEqOgdvepuoG72oZ5uOMTDCEuHeg9ukpNihUTOHZiekZs6Z35ogkqNeZvUADwqHhbpYg67HaSibcWHxps3eV/Y2VUaygHgvdE5aLUCryfWLekCQXi2CoRkHXkLSLcbwpbZo6/iK72BtRucxx7DS05bBjMqR13aks= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595392; c=relaxed/simple; bh=e8bYz3hzwlkzVF4SuQhfquBYwv8w3gtTysCPQfbNAug=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mVkO6An2KEQ0ryYkwdsreuX/JPK4DTPjyjFKbj3wd469RAlHLSb1io4qU5z875eX4D/lWaMeSIUqZ5UHc4/CZkjDwHLd2th3HfoBLRaaETXrhwy0xpSzuy839sdVIUAQRagHPxSDzyYFsg0Do5oAO9ysxK5De3TMJYDQg8/TfeI= 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=JLpMlAoA; 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="JLpMlAoA" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ad89c10dfabso109058866b.0; Sun, 22 Jun 2025 05:29:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595389; x=1751200189; 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=2n7CkLovKCebGHHD+J7tZWi3ApS+RBBl80tlgN3FL9g=; b=JLpMlAoAl9n5cROalAqb53YSKPNO3Qnf3RuAKnaGa+p5lsbAGWzUOzpeCBY+Zg2+kx mDExvWzhTrf9d17xYuWP1HrjADqgiWx3UGcK+ZVVmR0RyP15oimxz7wAJ7su3VTHzhcd JvOvVbmeumrbDU4aVVkiX4d7GDZiyVbLHPevf1JhQs19Imm2eUWaEO2K1lvW09Rq9z1I GLpkYWyK0tMCwANPmNGgD6EAdlNPbJp3EGKu64j2LhDcT1ust1dKG9sC6k8EZINF1Xzq cgZc7ociSRLjY/N3UVTr6nop/Cv6Qq6tf3B4b/R0ldXJCd/8bAzyrakc2g2h9aN+2DmS 28pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595389; x=1751200189; 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=2n7CkLovKCebGHHD+J7tZWi3ApS+RBBl80tlgN3FL9g=; b=V002dO0BeSsj8apSJZ+0AboAAfUkDsaaTJ5EB68EEqX40VLVQEG0+sLNPx/1Ln4a17 QPztFxzJp8RAUtlb+It8PfqHHVPoCnr5TMFeouq+r/ZcuxR4w4T06OdMmOsSrHju9PJd Ce3Z3DXidxIjwKqYcAl/QL4cKYmq0HhhG5+XdTxC/VlSO/8GgmEjcA52QkKLSO9reFIp bxdKtZGWl/lqz7Rj9FNzFX4AQ6tVLWSHIFBMhOK01yyhHLbCFHd8iw7jdHcO8LS0mKYg EaPMNyrrT0HoAND8MmFqK1q0bfiTmBqr8ciAxSYWVMflOBB87XUtdo+EqBmIuojA+QS/ la+Q== X-Forwarded-Encrypted: i=1; AJvYcCWVjqSntnPqmYQzWtkHu35foe2T/IyhgSZXq9u4EYVYDfEFFW++WiDewWjlJlmEv96yalAlHtw5b/ykAWCr@vger.kernel.org, AJvYcCXdvh5Tg8J/ztmWRA+6ZGTC3AfHayfnHAKZFqFvJ3B5Ob7F3rlKFSK6SVA7/HWOHzCjYIpPQqF//QQ=@vger.kernel.org, AJvYcCXj9Na+KlqMLCIu2IDlebjPXj2VP+XKHqjLfJ65W5FgNZRFZsr2BKMduBjIk3zmdlmo9EezSgWW3zRw@vger.kernel.org X-Gm-Message-State: AOJu0YzrOybm/CmQ1iAMFkOgyh5o1pqMGoAhPtDE7nIzhlOeVi5lhwdF P5Wjk+9KMDiohN9mEmE90W3HZXYGKr2VlOxaMzisUnsSR78aICYPnR4u X-Gm-Gg: ASbGncssvLiMq+hCOrSaftgsSQpUfCWyj3b0v9KbwX1+/mULUdYmVi8Yq9wOk8zKdf4 jwGJg/+lWR0J269I/M6jvWP/pupX4hFxw9TyvpKLN0YkHWWyqmPiYS31W5T29aYKU0BkVhCAsc3 AnGJp3L0cS9DBN9t1MdW8g6V7S9P/ulB5AemgL5Jq1tqoY2mTD/hePxOSenQRwTIAIdch5/T21b KFHn2S3zkGQgwz9UQ6kLgvgR/P6y+JuphTdtA4E4v+NXKpTcozhj+k5Qj44L/reFQNog0v3D/Il OouycM5HKZa3TYYhR6ZGK4SnPbwZVXl8srNIXKeOaoK+UGp5YgHi3AcNhL+CYxq/V338fpwiIIP TWnUu6PhQhrrr3xhLgsEYzkFBcTugLLDT X-Google-Smtp-Source: AGHT+IGYb57bUanIKual540V1bySFcrnEr0/kOxW2PYXqno3bBFxFBQ/7wiMKqFxnyQPvnKodvebdQ== X-Received: by 2002:a17:907:94c3:b0:ade:8a6:b86b with SMTP id a640c23a62f3a-ae057c3b2b3mr261303466b.16.1750595388685; Sun, 22 Jun 2025 05:29:48 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:48 -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 v6 7/8] iio: accel: adxl313: add AC coupled activity/inactivity events Date: Sun, 22 Jun 2025 12:29:36 +0000 Message-Id: <20250622122937.156930-8-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- drivers/iio/accel/adxl313_core.c | 215 ++++++++++++++++++++++++++++--- 1 file changed, 200 insertions(+), 15 deletions(-) diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 40c75e90e4bf..292528b457b4 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,38 @@ 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_en, inact_en; + int act_en, inact_en, act_ac_en, inact_ac_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 +546,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 +556,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 +576,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 +591,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 +726,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 +749,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; } @@ -740,6 +879,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; } @@ -760,6 +904,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; } @@ -906,28 +1055,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 Thu Oct 9 01:16:05 2025 Received: from mail-ed1-f47.google.com (mail-ed1-f47.google.com [209.85.208.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F3F371E0489; Sun, 22 Jun 2025 12:29:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595394; cv=none; b=psXKa3+D+fhA00AlCd3MITVJMHYwVZkQlrRGTdd6YqXyoAeJ+QPPNzPPq0VWZ36s+wDMqJ7vCe1kn0+U/1AR1yYsNLnQqHMFaRnkT5ONoRpVLwMYQHH2TYrATGVWn/iBYrkh74aDGuPJ5TFKvM1TzCAzsEBVmO8ltTBXOxhzQlo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750595394; c=relaxed/simple; bh=jkBbAhmMyc0MVV9hyhNL21f7zsQ0Ubyu8peDPdVynZc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=XUsI5dAP19FgDLEXbVH+VvzzZGA9kGv0DgA2oZbjnxEx/hWtvdNTK3F34LGrPh/3ib5vHc/qeiE2VSKJeYqNYgfi2KbLIbbEtcl7iq2HX//bnSnAW1dfEx6CB17GoinZwr8JIetZgevZO9uPA7MfcB0b0mp4tXG273l7513d+kw= 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=HCwJUIAy; arc=none smtp.client-ip=209.85.208.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HCwJUIAy" Received: by mail-ed1-f47.google.com with SMTP id 4fb4d7f45d1cf-6071ac68636so712909a12.3; Sun, 22 Jun 2025 05:29:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750595390; x=1751200190; 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=HCwJUIAyZDqCEZQylFbue9UB8cKM/vrpBpFfUtSafcXd6AnqPacv4LI8i2RsySgocb m7tra7M7f7ketrbXmCQ9vslXo55KnomeGkGZJRAihy9flM7+zFpKEComl7B0z9/pXZhE DhFa2jAwVWq+NUKKUzBxe/k4JL6+x1EnSqVVJUmShjx6byIWZR02+XZhV19n3GKMb7me Wf+NApj08yO5iPuHANg3txqfG7Dkh45a4tWzHPDeTQUT1eyg5NgNQYLAhV5R5SJcJTh8 CceKtZO4aQMDSPaAdad+Hsqtff8+XLriWHbFhT5INbSZgVC5t4nRq1rj7ER+0wiau5x5 PK3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750595390; x=1751200190; 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=faFsgm9gtx9JrdnnYEzX83GKpyPgz53PkTkFNUjDycBBa2VFfZHN61M0RN1QQhI11j CU2MuXmFeztN4D6yS4EQGIxXZuTJK3EkvBbTkRoBzAm7TKnsU0GWT8meDopI8pQZBS5l pMmYlWoPQJ9O+LkraIg1HiIJL706UZ7zxhj1f/fcMbucgTUQpaxEIUqmK3ZH6DqKGbtz NjF+aUWiue0b7qEJ6ftEJXY72YGdas26iEu7IQBlfDtAGz7OF0leBwZHLGeAGDUIu2ui r2BywCLpJUfdqHR3sDQnX5tTjFJBdBv5PFJ0QOILcm8ztKMnEm/BbtD1RBmTnSFMDQtg f32g== X-Forwarded-Encrypted: i=1; AJvYcCWDJqZQXwbTj6knghfepVqWGaeTPu3lEm++EtJV+gc1ypoua+kKv+3kLPeP0cskghYTK5Utm7Yc5P7n13is@vger.kernel.org, AJvYcCWNmikYu8/C+aJX0ZKadPajf+ZOeutYRW/UYkaCFI63oPeATAtNxjGN1pXdYEhUF15E2bTqs/KDvGA=@vger.kernel.org, AJvYcCXvBrWp5wQsX3RX9pb6ODcoc2qnE/eGuu4JOEBskHIh242K+d75wPA6ChgCpHjSi9in503ZA+KaqhZh@vger.kernel.org X-Gm-Message-State: AOJu0YwG8CU6+gj417WGC18/o6YpsC5C+zrv8ZusNv+GzZyZ0b+/YSTI 8clCTFZvuzpeiU4IN5LGqrWWOzwU3HRBUzIl8AELeuVzmnosqhvoFbLt X-Gm-Gg: ASbGncvLkCpb9Mw2QlKeIEL+eiP5TeGROhoNGPfjuDVxur/C3rn5tut0va6Ia5U+XWB /j5GLLJ6vDAzp8ZBs1fm/j09q8wxo7jdDpMbj7XRIjLZPglXFN5MC67ryXqVOZWq26hCYJYU6n9 C4E2Tdo/PubPhlTavVPbkqr++YtCRieHz/baj3T56x8D1Dk3JggznCPc67Azyerv9BRhSanJLAg G1FawMXKxqZmof0YJhdHFoG+s0J3eEQJfcYW8Va4qCuKi0EoJ96/WuAnPQPw4dOE3JujwTN3aLK wxUHhIxTG4YL1s2PQQwVAse4TvopidBW4p1gd7tSfWm44CTnXMAmPP//nailtbZ++9RZz5c4EHJ fSCFfYCnEFp0OwuBwa5kT68vH3zrCDaYz X-Google-Smtp-Source: AGHT+IHiVGUwTJbXhSjAreKhmm+w/wc9LHC2qTfHMwo2mrdogo8idyvtH6YcrOM1oE49YwCIoDyqJg== X-Received: by 2002:a17:907:3ea7:b0:ad8:9b93:8579 with SMTP id a640c23a62f3a-ae05741069fmr260425566b.0.1750595389801; Sun, 22 Jun 2025 05:29:49 -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-ae053edc0e9sm533917566b.54.2025.06.22.05.29.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Jun 2025 05:29:49 -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 v6 8/8] docs: iio: add ADXL313 accelerometer Date: Sun, 22 Jun 2025 12:29:37 +0000 Message-Id: <20250622122937.156930-9-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250622122937.156930-1-l.rubusch@gmail.com> References: <20250622122937.156930-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 --- 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