From nobody Fri Oct 10 04:00:27 2025 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 50EE21E4BE; Sun, 15 Jun 2025 22:23:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026190; cv=none; b=pjoJIdKrXnzANctv/97MMZcntxWXm4kOm59KM2TnV7gXUVWRlsTJxCdlU6ffQ5Yf9+fRIKmrrzqKsFooDPVa6M1KJ4zkCMNkBcNo0N1RkjVifdKUvenbxQuEultxI2Qv2VT/9cViQUvO1xjlN5pE1rPL9c+Kcus0aMm7M+CwwG4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026190; c=relaxed/simple; bh=XjCwok4P/lRUHSEGFzqQ/bP+tTBFIbWyVqSF2e0Toj8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tT1Rm9Sw9Cgm/R1YjZQ/60mtsfOhgzAga38ilGu2N6hyJ/lfVby5eyRE4hVUDw8VUi4yGONlPPdDSiOFAgu58N/T9E8weXUJNx82FI4oEvQBJ8jJ3xBluPQ1H8VLkMjII4nUBTOkhLYMW+zFd/jgkYAh8E27hzr/vFn8M89nyag= 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=hx1jMFxH; arc=none smtp.client-ip=209.85.218.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hx1jMFxH" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-ad89c10dfabso109807366b.0; Sun, 15 Jun 2025 15:23:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026187; x=1750630987; 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=ZSSTsxLI9eNEfTQkHUSiZwxVDDndT1QNIjJcXV88c3g=; b=hx1jMFxH+c4DHC488UTLEY3FCNbjGhnpQN49JeJwDx85gikXP9twDfWTdogBcpOwkd 99OmFNzzX3SLSblyv/QHzwDKGb4gIBeCbqWmn99z6YB8XXOldyz+ED4BYCQncabmzNUW aHJHO41TPjCyD/chw0mNlMaQ2uiF9SL4/6/bzG3Jjw61JKiW4T1jR4gSAhTPg73i34WE MXyFRYgzO1c/aE7ycHl2yN0THQyEpm7B3sxwLBCYs/ugWtfRxaz6xNOJ3i4epns8d5Jh Z/jrZhhbTIRDazDlPODdLgv1Nqq79UfjEUyJldnrZoZAHA8FLS/20mR741+gf9wD81So 5nxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026187; x=1750630987; 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=ZSSTsxLI9eNEfTQkHUSiZwxVDDndT1QNIjJcXV88c3g=; b=gbo9xCz6s4/2R5O4CN7bSbPsBusnFNFCgdnB5T2itwD/cBM38dklHv5Ia0xxX45A3N 8PiWaGqik8YSdAH4qHvsvP9nhRNi3NCPO5YLS/SZxFjnwI1czo6/oZxReDaAW/wRYgQE +0RFIPH5BjWbdgKuStYCZkIMj14q/+NEObHSEqS8skgZNy3+2rbS0JPcVK7aTkX6d6AI iR3HNkS+wKATdlcoRTYdFbx2XFa+szrxZYw+NfRg8qlyAado5MAv6VjL6EiptDKlEMcI uvj7HZ+CkdaK56z/sJnxfiOT9HDStt/+3bngPrqeoYEPP8EkeIeAjPaReSWAmfUJZ5c9 PUlw== X-Forwarded-Encrypted: i=1; AJvYcCUoiXLuIfKpDFGxWH+L+Pir1yKRrJVO7I+Hi7KauF8+W9k9D9xuKyBBXCDPqCrTiW0tWhaWEyHsQ5ZY@vger.kernel.org, AJvYcCVqAslqP3D5hQBJzQ+/L2bar1mKlXV5RWsRvN9E/TYrgDWyLYZ2heJxrCvjJ8bCMsp3E+DcIuTyyRg/nCJM@vger.kernel.org, AJvYcCX2bjPw75kDde0kWZ7VX48fg2MnND7DbS+T83G4gQO2EfmbgiMfFVIfbDQ2so7veMmBF/qzFuEDQXM=@vger.kernel.org X-Gm-Message-State: AOJu0YwwG0tz8jyIQwqjF3GAxANwb0ZDtAe4Q0S0eax3gcjOJBsSzlnX 2kEWC2dkWsFVcjUhZsZLTmll83sQpRLjH6Hjw5kS58P4cI4iHdjtsoZz X-Gm-Gg: ASbGncs708ol50OOAE5WQlAbzBPp+2UmnrkuZWaVsc1iyrP2r65K+s7UrsUhXkLOphI MEs2qNDw5uFMU7zlxh7RRvUvkF3EcZI8aue53kSwAX0nrbf60/Ml8k1QOcvry5Sv7+EmRYBtSCo SFgiYOpWBOSFiHYO+RI1MPHywm2YhGM+6K9tgfrSDgK6bZwIzj0zr4g6ccZJtRKJyupA+UkKKuS jN7VZmgCTfAEniZxJMTiGGlLrhabATX3eQvDiglMMwmHzG2zdUPhV0ssS4aeEnjKL31qLEuKZ41 z1P8AYzpiyWBluyoMY88xynso56zhvEHe9ueKCgULMMqsbYuRgh7Mjpuagp5IBK8+OUlaYj6guH ITIh19hGQbYocGPQ4MHeA7EHdLm11+xAM X-Google-Smtp-Source: AGHT+IEmHk2xK58T3WeDA20lR3opzcP/HZi1SuNRlKyxsiqwVg4AvnoOJHI3JoyZZ/x3ZBpz54TINg== X-Received: by 2002:a17:907:70b:b0:ad8:8189:2563 with SMTP id a640c23a62f3a-adfad550105mr218303466b.12.1750026186603; Sun, 15 Jun 2025 15:23:06 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:06 -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 v5 1/8] iio: accel: adxl313: make use of regmap cache Date: Sun, 15 Jun 2025 22:22:51 +0000 Message-Id: <20250615222258.117771-2-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-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. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 3 +++ drivers/iio/accel/adxl313_core.c | 18 ++++++++++++++++++ drivers/iio/accel/adxl313_i2c.c | 6 ++++++ drivers/iio/accel/adxl313_spi.c | 6 ++++++ 4 files changed, 33 insertions(+) diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h index 72f624af4686..2bc86ac8ffd4 100644 --- a/drivers/iio/accel/adxl313.h +++ b/drivers/iio/accel/adxl313.h @@ -22,6 +22,7 @@ #define ADXL313_REG_BW_RATE 0x2C #define ADXL313_REG_POWER_CTL 0x2D #define ADXL313_REG_INT_MAP 0x2F +#define ADXL313_REG_INT_SOURCE 0x30 #define ADXL313_REG_DATA_FORMAT 0x31 #define ADXL313_REG_DATA_AXIS(index) (0x32 + ((index) * 2)) #define ADXL313_REG_FIFO_CTL 0x38 @@ -54,6 +55,8 @@ extern const struct regmap_access_table adxl312_writable_= regs_table; extern const struct regmap_access_table adxl313_writable_regs_table; extern const struct regmap_access_table adxl314_writable_regs_table; =20 +bool adxl313_is_volatile_reg(struct device *dev, unsigned int reg); + enum adxl313_device_type { ADXL312, ADXL313, diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 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 Fri Oct 10 04:00:27 2025 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 74E5A16A395; Sun, 15 Jun 2025 22:23:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026191; cv=none; b=hrz63/Torvdxiuob3RWpqgTKmf/tN2TD3vLcGqpuUvW1yv0JsC9ni3Pte6AsvjZyh9mSfMruJi99A5Hg2Dxi097S8YOB1eW9Lvvr5rsl2lRXGIpOhow+aezT7r7sAeS1fwGwjUYcAPuBEIGhev6Ni64ZXe337jhnjprnxPEzsTU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026191; c=relaxed/simple; bh=OcSzxWcylbf9O9uMPY784h9WuCm/MYyruFaYVs4CfFA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=IZfhhc80SbBAvs18QGb81/rpm9izucf+sM4qDAWj304xkr36hQ8UbQA574LJtflSRk08PPjX39sx1UwXVXlEdHOruYMSVKHo6yqkSOmm6jk+9R9u9+AoyW97sxpgakyI9Y1ucGZ5lwG4bI6rgb6hQCR39w8Oz09NsqNoLXq/E6Q= 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=m8KRZUr5; arc=none smtp.client-ip=209.85.218.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="m8KRZUr5" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-ad89c10dfabso109807966b.0; Sun, 15 Jun 2025 15:23:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026188; x=1750630988; 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=P6yHXBtbTqJtfka5dx4vNKxwWBJhinite9xksxFtKWw=; b=m8KRZUr5oTtdwPujpL8vWNayi4KaS5uI8XRTAJFZUvpIADQd8hy6cqSM1tGam4GEHF ud797eBrbZ5f7Md428sa7L+9mVRtTl3+ZDX/RCouVYwNXpcDPnv8VogRivn8ytVjzFQu bAgTo8cE+X3H/ckU+uINzLIZgGGiJiTsZ5NJWGuCtSRB1hgK+2/j+rki56KppHn9INYG YtAxVFATSPvYb8lwmYNq+cM9lRXhiqc7XM41f98HSrBfHkPRb47HgOdAa+4L1VDpU6NE gW7KH8foBmKYVQjVmIFrlUBDEfmwVRUUHCVRfChldjl7Wc/ceNgnCT8MiXa/hkhKFO0g uR0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026188; x=1750630988; 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=P6yHXBtbTqJtfka5dx4vNKxwWBJhinite9xksxFtKWw=; b=luF8IzF20Ddst0XR0YAUr3QVN2x6e+teToxq7zJhXwIeTh41j6RBzB1p2Wo3RPFv9S rDZ2g1WxmOJZJ9P5gndfhqGb3EanyQkX3h7IZfMlYgcI2yjtnUp2Ub4fefnl1sO7SQpH WywD1g17TCqo30H5XZu7EFnhyZyKSGb0y+QPDNMCvO9kiMKbfezGs/3UZdWoNnW9nQDX hPd3qtYKOl0I7gh6rnJ2Eq77eTMabr6Jiz/aveBMXqNvpBKjuRufFE2tTMPDaKlTLud7 RrM51v2/jckPO4cgYzea6UTrnjdq/2SvMPkxy3XL6GPNFposXHBq0MUL+gunBXYiu2jV SC7g== X-Forwarded-Encrypted: i=1; AJvYcCV0L9D3OGk0AW3uqhyRblqh5iQCWghcDQs1P6fHgTHPDZvyMo2vVRLySCB3DqwPgXkV3QGVSRCy16t0iyu9@vger.kernel.org, AJvYcCVZUoZMunyqwg1gMBcIESkco5GjA1fnt2evKa42bzL58o+3K4RASBpafy32a77plqp9X7IC+nrOJKjY@vger.kernel.org, AJvYcCVbhjlLi55DeK4EwPhKAM6Wtw6F5b1pWE8/YJfjG8M/W0sI1naYuZgsqtQk8+G4vMzFTth9CPb0ouU=@vger.kernel.org X-Gm-Message-State: AOJu0Ywpj8SlyxetLVCMS+TZoMEn7LMK83NawNo1BHvvkT5w8QRGkOOc OCmcelmVZ6hcpCkuqq9SjUcnntp1KzXcwAVjz97UIRmzBhbLc/iAjifSHBgBSQ== X-Gm-Gg: ASbGncsUxBwWoe116rtCyu3pbdLMpxEocK9h7yI8PlpyO1hBbkQTGHKZtnjYJS+0IXg V16Cb/MpKOw2SlLJ1S/7gHUPLrw+iGvtMf1Oui5AE7X8AMfF2xgadiyRHa8m3CxmxR7I0TCQdB3 PpdVQMvs5Mz94mipc4kKg950Q/sTC1hBvByLibzXwqEg6EaTxCvAcR9AECOQoJOO/SSRWOwtT85 E7Ab9w0XjL65saWLBRoDo1bc8Ur78Y2UeNpQ46Um6UbLgDH1uQhoKHRFp6hfmTGwgwAup/KKFHD FxiHDsw1Zx0flhVwUHzBcLjw6zfL7g1JpN/mk0Dv+AJ6uaPKWYIxRYAoSGZz6Ngk1eGiBeA/Wau A4i9f/e7vUd8YtPCtSr/8vPvyvIIoSaXm1FV/6fuS8Yg= X-Google-Smtp-Source: AGHT+IGPm/dy11DrihiPe93ZRWMDPohUokRWcDe3USXe7mGw7ypUnYnuu0i7rqAwFd6fbg4th9ix1g== X-Received: by 2002:a17:906:c10c:b0:ad8:aa3a:772b with SMTP id a640c23a62f3a-adfad5a2dcamr244629466b.15.1750026187666; Sun, 15 Jun 2025 15:23:07 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:07 -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 v5 2/8] iio: accel: adxl313: add function to enable measurement Date: Sun, 15 Jun 2025 22:22:52 +0000 Message-Id: <20250615222258.117771-3-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-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. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 3 +-- drivers/iio/accel/adxl313_core.c | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h index 2bc86ac8ffd4..6958a00f5e8f 100644 --- a/drivers/iio/accel/adxl313.h +++ b/drivers/iio/accel/adxl313.h @@ -37,8 +37,7 @@ #define ADXL313_RATE_MSK GENMASK(3, 0) #define ADXL313_RATE_BASE 6 =20 -#define ADXL313_POWER_CTL_MSK GENMASK(3, 2) -#define ADXL313_MEASUREMENT_MODE BIT(3) +#define ADXL313_POWER_CTL_MSK BIT(3) =20 #define ADXL313_RANGE_MSK GENMASK(1, 0) #define ADXL313_RANGE_MAX 3 diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 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 Fri Oct 10 04:00:27 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 A3AA2280301; Sun, 15 Jun 2025 22:23:10 +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=1750026192; cv=none; b=gl6ZvYep3tI02KrzXHbq2LQpXEYGDCseQmQF8LaqlrWEwqOXhdHJr+XrDfB3WhOoRFKfMjCIRwxYHmaCudVOgyO3MogkIKM+dV8oqE6UvUvUnDlz04qmx3fGnjuWsSCt+cn0r1SPmPBKsqIgtzATgCZLQ8UbXYoksaUarq+/xjU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026192; c=relaxed/simple; bh=2YMJ7UOnPjBvbkE9LymwgPGrArWHl8ZAFVVwd8pqE6g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=n+UOyj60gQ8JX0zBhLp42WDXuTA/FJ8ZyxWqCoPU4it0AIkGcfrhbiUb1DYwe6D+ER/NC1aCsPup3bVWpVUBOBUN1lJtZ21FFP9YhoVQupbaXmv3Fuj09B5lvjtFkHgGdDFUUZRpHz3bbNYj43un+uvDnZ862rVcRnRVzwee0H0= 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=kRX1r0qg; 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="kRX1r0qg" Received: by mail-ed1-f53.google.com with SMTP id 4fb4d7f45d1cf-606c6bb1d03so761273a12.1; Sun, 15 Jun 2025 15:23:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026189; x=1750630989; 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=hMDc+t5xygTJE1b6UIKAgGNP+xPRAmJjlUXum5RQ7AQ=; b=kRX1r0qgccFFHwuswfsm1LdDR7sphAHFBd5jrUdNcFzila9tAU5bS5DVcCJHdwrt93 rDIfmPpLFHzPhP/Q1rTWRvarKYl4WjJQ/mhRYcSadeBAcK7r3hAwIiPMzBLbSLkyc4Oy bItdJgLKlIcv17ewCSed6uoaZLBVcwEcjQV9S+JcwuMTOX6JcXtwOvEsV/Pchi5JHGzG DJIyWrHKOCUq93rSn4Thecggyg5ulR0t4aBuBzdInBKpSCJIyeVotPiEuHqqtYNye7GF N3RIt9yPQO6KFLgV9jkFJuX+wep6y4AJzX8LmBs1nlaCrHoIidzHY9lnDgggf8ir0O5G yGdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026189; x=1750630989; 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=hMDc+t5xygTJE1b6UIKAgGNP+xPRAmJjlUXum5RQ7AQ=; b=hne5ImgUfgsaX/izhQfLhvEhJ9jDcAE92AxO9pcmhL5JOMPsJndqCMRC6Ybwcr4Q73 fH30KjXnCOHSEc/9Ri77JqmYxL2tik7cSetYke+9mYH0F0TANvSpryHzQRFfNTrRRf9o l2XT3SVk2M51pUw3i0eYoCzgFXcJG8nmfjCxbc5Nv52vYKVl3Xx2SeEA7A/uYmhlN96J ysJmaBcaQcHUGDY5KrA97E2dlpvFakBAu1JRUtnvVhtAEfRMte5LM1RtMuiTT237eyzd UHZDglYLICbwPSHgAaRxPZBATMLV+shHHgFb6HWj+dpAZTix0EgiqePjA23zsKolETEU ekOw== X-Forwarded-Encrypted: i=1; AJvYcCUlsUvsf45yrQGdpyYCgwXj+oTcJl86jo5TCZmFNo7oNqXR5jKqAETtaFM77MgsLcAMOdxbBE4f8Ozz@vger.kernel.org, AJvYcCVE9fPn06MDoI57A1OKvY24L712iCn6xMQ1FLkC3n/2Wyvc2a7wHfllP/zcI6PDWM4dCnaTQ7BG35CON0tB@vger.kernel.org, AJvYcCVW4OWTIW+zn5h462dK+8FLRX51KuR/XLDiEWhc0MgpOsNw64sfi2InQyl5NCgiggC9DRK1NTavUHk=@vger.kernel.org X-Gm-Message-State: AOJu0Yw3QKZqNjvt2vDuUHZ4Vv4BE1skCniyhlG3ti4W1yrXLhNqq0r8 t2HvKrCaSJXG2bEuemDU8hNwPKjqUmGWH8vJ0fzZ7pcCNW84AYvIkl7tbFeJfQ== X-Gm-Gg: ASbGncsEuKySQZBIlIx111jH7xIINhkyRKHfgfAXKv6BCQAETpvBotZwbtHP9m2Ats7 PIzt4ZGACEAVwl5F7bdITa0+6GvB4KtFYkBMw2BOy1zlgrASyyp/8hB7K173PpOn8OCHA8bJ41m mkDjcADMeO90ZcrDRLZWKBC06h869jFKmD0SBxQwjXAVN0+4baG/JqneJ069Bxra89LItIHuoMg m+3v/9zT6ixMofABY/vEsdcWm2Po7uOn+zxM47DQY6WsVEgXL02U3w2+m07D5BPPLiANeeH/0M4 6LpHIN66VinTlvLBi2TUevZq5jHNauLKDhduxCKVcetvh7F9cxB2v/cvfjBFTRwePK17B+kSimA LiFoUw0Hfpw8NTmHqUyFu40WAQwgMIpiW X-Google-Smtp-Source: AGHT+IEFTK8VpxpCoXvVhAWC7ciyNgxeMzUADIVqzNkkJrw9YIjBGk9xDV+IccpOanlz/H3DbwByaA== X-Received: by 2002:a17:906:c148:b0:ad8:9744:d0e2 with SMTP id a640c23a62f3a-adfad335350mr221079066b.1.1750026188854; Sun, 15 Jun 2025 15:23:08 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:08 -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 v5 3/8] iio: accel: adxl313: add buffered FIFO watermark with interrupt handling Date: Sun, 15 Jun 2025 22:22:53 +0000 Message-Id: <20250615222258.117771-4-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-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 Cover the following tasks: =E2=80=93 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. =E2=80=93 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. =E2=80=93 Set up the interrupt handler. Add register access to detect and evaluate interrupts. Implement functions to clear status registers and reset the FIFO. =E2=80=93 Implement FIFO watermark configuration and handling. Allow the watermark level to be set, evaluate the corresponding interrupt, read the FIFO contents, and push the data to the IIO channel. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 22 +++ drivers/iio/accel/adxl313_core.c | 259 ++++++++++++++++++++++++++++++- 2 files changed, 275 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..488680807a8f 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), + 2 * 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 @@ -424,7 +617,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 +636,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 +644,57 @@ int adxl313_core_probe(struct device *dev, return ret; } =20 + int_line =3D ADXL313_INT1; + irq =3D fwnode_irq_get_byname(dev_fwnode(dev), "INT1"); + if (irq < 0) { + int_line =3D ADXL313_INT2; + irq =3D fwnode_irq_get_byname(dev_fwnode(dev), "INT2"); + if (irq < 0) + int_line =3D ADXL313_INT_NONE; + } + + if (int_line !=3D ADXL313_INT_NONE) { + /* 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; + } else { + /* + * 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; + } + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, IIO_ADXL313); --=20 2.39.5 From nobody Fri Oct 10 04:00:27 2025 Received: from mail-ed1-f43.google.com (mail-ed1-f43.google.com [209.85.208.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D9CCE280A3B; Sun, 15 Jun 2025 22:23:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026193; cv=none; b=ny23u0C7CrO99+tdzU7mCRpvGFiV4WcY/yGC/FBMuuX9gYekq4TnuAc3soblKSjJJptv1wYQJms7PhUoodAjE18fh5s0AFx7Is64QMF1rlSUxN0McxxMBBvf7Pak8Kff77rUxP5ug/FgqzXONzMNnW3rzLi1Y45T+akQzv3Ayb4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026193; c=relaxed/simple; bh=CDzC+Dab/5nnNCzsDwpBRd0tqjx1D9QHKg7fh/0UfAY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gaidIQiAGXCMcvMQEHcS0+8rr+LP881MepmHA7VBUz32xZjZPLJITZ0porSKGsQK35TDtnLbXKnEWa5w03GpaiggRKHJPqfegpodnSloRB7pTllUkxyuUjFjpgdxp8l35Nrs0WxECF10DHuUANM+x+qiQfOBqNEX3Ja2UUlxxLo= 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=ffe6/wse; arc=none smtp.client-ip=209.85.208.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ffe6/wse" Received: by mail-ed1-f43.google.com with SMTP id 4fb4d7f45d1cf-606c6bb1d03so761278a12.1; Sun, 15 Jun 2025 15:23:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026190; x=1750630990; 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=c/ftbtqWVPSKTntyYUcVvhlj9HI4YnADjK65oS2i45k=; b=ffe6/wseMLyWsaOmDGwTm85rIBd8mt6cHH9vcSfkD1BDjmia5fRp1VWDfxrDSGZTwY U925/n8rEqiz5oEN+ngBZIsVPkOPV1Kcqq9KynwFNhbX5EzxllHA84iOUq3x3rk+ZqYl cpNnB4cqvCju/Agndvlbq79LDOD3zACNoaTponEdEos2z5EJ3HjkWD/QEeL7ZAFBcjbG MPmGeUQQ9rDrpZLdz5qoKUnxsYVnV33vmmmQdjqNslJVGF11al0HoMkswaU//wuEtSpy JtqXF2TXuO6OyOceghov2zK3iCPXOyFvf8fxh2excmNbB68ln9kBA6vIqNYHJ+zNrF5g n0TQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026190; x=1750630990; 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=c/ftbtqWVPSKTntyYUcVvhlj9HI4YnADjK65oS2i45k=; b=OsWN14s8gXbsVuOWUZvSFTExMi8anf6WjPi5iOOB7J9WZw88sPdtTxXjVEgOXYJ6Zt CFtRRe7LjxyikD6LuwF2Rv5R0TCmkvfD5fC0KZlJJXuMqfMddP8AAlVpL0XqUyjdK5Ra q6cNiMviCP2eFQ67fsUgYUAEk4dV3k6oDYNice+/xb8+L7ObyDL5Gr7DFO9nZAE8lDpu gABSUjHU42CPa/ZTj1Hy7wh3PRj4+xIVyBxB4s/haiM4MUitiEQzEOAwp8naUH+gPLOS f1HqcsMR37MgOBj+Rr+hHIvlGD7GbvV36nEzeiaKsJqXuWPUrO/iKGfyECdXpfER2yVe LPHQ== X-Forwarded-Encrypted: i=1; AJvYcCUaEkPGiceP3mq3LB4Os9zJZIu5xovTryUmRHGoS3qudyQXLWGoLRYIyP8uI7cF06mI5cjAOxK80og=@vger.kernel.org, AJvYcCVCql2ACjF9hvAxSwQL3EifbubVvrYGEp6mKrPMQg4UCzLOg0OVMfb+2re0Ehd7m4+6EIScQHrDUhZa@vger.kernel.org, AJvYcCX5BYYW+zIwZqBm+BWtiw5hcMK7p/+KPyScDWa7bwP1OH6WLaKt2G9eABFTooUZ8047djlvKtwz3/QTZPvB@vger.kernel.org X-Gm-Message-State: AOJu0YwFNZ7xS6oXxvMBwJOg9rHFaqLFOcFQUwZ+aq4YpE/bsIwhTcXC DRXge0H0F+xy9Qg+Hks2fWZZvYxeWRc6UK9mxxpuozk8R/lLJzSdyzjxPuxLmQ== X-Gm-Gg: ASbGncvmEFFYlQoiXCaf7k+tAUZRZmPKmbbjXbS655YCcYcXpZ3dD9VYRqmUpg2WzAF 0rh2YHln4iISl6YCCw81Se2yP6e47GOrCsv+cM5UtRhnTZWL5sHfwnO1waQfWnngygHhIJlBde0 GNSUS6nnKpRBWWpF7P5zCdD0s4j8ColXJa16JO9h9PeEHiRu+v1yf41FFpLVY5L6JygoyZ1livy KNtlRpMZwerQreKEjASmH854zpLP7G2zn+dJN7SraaEIHSZqIdNUG3x5NA2xc79SY1HBsylJA/n 7DnyqrP7zg4kH9AJKL2JDa1c1X3E7+PA2VxGYd67LNZCFd7kZGFS46Owl+R/+V4It5PK931GFSg en4dgthYLYLv42nM5qgd/boVfYpzrnUDs X-Google-Smtp-Source: AGHT+IEm62cvsAxWVl+gwFFGA56IsUa3Qv87CztVk6WvXnlwbq3Sn3mAbFXaHrg0cq3VYgLhxEemvA== X-Received: by 2002:a17:907:9814:b0:ad8:8200:ecfc with SMTP id a640c23a62f3a-adfad37aea7mr234148666b.5.1750026189898; Sun, 15 Jun 2025 15:23:09 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:09 -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 v5 4/8] iio: accel: adxl313: add activity sensing Date: Sun, 15 Jun 2025 22:22:54 +0000 Message-Id: <20250615222258.117771-5-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for configuring an activity detection threshold. Extend the interrupt handler to process activity-related interrupts, and provide functions to set the threshold as well as to enable or disable activity sensing. Additionally, introduce a virtual channel that represents the logical AND of the x, y, and z axes in the IIO channel. This patch serves as a preparatory step; some definitions and functions introduced here are intended to be extended later to support inactivity detection. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313_core.c | 244 +++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index 488680807a8f..b0d14ce60f01 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,73 @@ 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 axis_en, ret; + + ret =3D regmap_read(data->regmap, ADXL313_REG_ACT_INACT_CTL, &axis_ctrl); + if (ret) + return ret; + + axis_en =3D FIELD_GET(ADXL313_ACT_XYZ_EN, axis_ctrl); + + if (!axis_en) + return false; + + /* 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 (type !=3D ADXL313_ACTIVITY) + return 0; + + 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 */ + axis_ctrl =3D ADXL313_ACT_XYZ_EN; + 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 +471,103 @@ static int adxl313_write_raw(struct iio_dev *indio_de= v, } } =20 +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); + + if (type !=3D IIO_EV_TYPE_MAG) + return -EINVAL; + + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl313_is_act_inact_en(data, 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); + + if (type !=3D IIO_EV_TYPE_MAG) + return -EINVAL; + + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl313_set_act_inact_en(data, ADXL313_ACTIVITY, state); + 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); + unsigned int act_threshold; + int ret; + + if (type !=3D IIO_EV_TYPE_MAG) + return -EINVAL; + + if (info !=3D IIO_EV_INFO_VALUE) + return -EINVAL; + + switch (dir) { + case IIO_EV_DIR_RISING: + ret =3D regmap_read(data->regmap, + adxl313_act_thresh_reg[ADXL313_ACTIVITY], + &act_threshold); + if (ret) + return ret; + *val =3D act_threshold * 15625; + *val2 =3D MICRO; + return IIO_VAL_FRACTIONAL; + 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); + unsigned int regval; + + if (type !=3D IIO_EV_TYPE_MAG) + return -EINVAL; + + if (info !=3D IIO_EV_INFO_VALUE) + return -EINVAL; + + /* Scale factor 15.625 mg/LSB */ + regval =3D DIV_ROUND_CLOSEST(val * MICRO + val2, 15625); + switch (dir) { + case IIO_EV_DIR_RISING: + return regmap_write(data->regmap, + adxl313_act_thresh_reg[ADXL313_ACTIVITY], + regval); + 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 +706,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 +734,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 +777,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, @@ -663,6 +894,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 Fri Oct 10 04:00:27 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 D52E2281532; Sun, 15 Jun 2025 22:23:12 +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=1750026194; cv=none; b=YkeFTBlOFRmLIpm8yy/2ecRDjmM4FZquC7pQ6ZkbtNEjhvXIxkBY6Swov1lsG00fg8waRt5BGLRFMbWJ27yWTMWNsUPWWbVTUpMMhkL813UfkEHa+EasNPHDB1jQNm9tBVImSYUDNeKVAEdbTojEv75BZQ7GkY55rwsoFNYtlqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026194; c=relaxed/simple; bh=NAnRvIZtABoeGKL4mT8NGeLUQXUGt3Db1dF5FBbw5Jk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Q3pLxnAuRjtW3QNDUCRYs1cTyy6cdEqXFUCAz6hd1Ph3gU0hERcuTK6jWs6wjZ/eWX7ORQMCkriAuzwP7tAGZWGkH4eIWAsY8UW6crkcv2iZnKfmFPZJtcCLUJU//C0fqVMpZYQ8TOVDmGkDLGHxt3w+NEuh1Zl8FWNsfYumf6Y= 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=PphRo7Zw; 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="PphRo7Zw" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ade6ef7e6b5so66344066b.3; Sun, 15 Jun 2025 15:23:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026191; x=1750630991; 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=k7lx5bSlxHCR3yMcw5WqOUP1Em37abE5TKB7VY91trM=; b=PphRo7ZwuYmbC/aLdGr5MqeadFxcVP5Y67xXsudPdEVAYnW1lel0JPTf/zHGRXMMtj enMp9VrrbmgjXnzcLUN4NS/iJAU1YEyS95vb/0y2ODS/PKqzZsi83qVd3wHJxqA6yTAY oTojSWz9WSNj9+28sQe4voC15nM0yGFyKOoHg9/69eUz5VzUeEWs68flIQ2ruWqUdRXQ ZpstcKswrgCdb7n6kdhVXYV2XNACQw/ktLN14uO3HiLbkZRi2xPTK6VtXKSCt+Jgx9pT aqIAGZmJSPSwc9CPJGDRRhvEo6om/n4VGSF2CFm5EZlST7R8R/+LYz+a1Quc/TuHngAY NnNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026191; x=1750630991; 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=k7lx5bSlxHCR3yMcw5WqOUP1Em37abE5TKB7VY91trM=; b=UTBa2IykTvKSP/TtFEZ6KHkoZbzD/mHZDDsRwDdDfxFuBq+/z8x2LBDoulAG17RAP/ SJV8sD4LFN9jX9mtyjXbZGFtfPvozb3fMgLgS8SEh8pkXWikVV8kFB/EFXN+LDz7NeD6 DGTYHzrBANaZ6s111rZZIE9mtVlYT2sKZYyrJGri26dkJHymNOSJM1Z8P6AbvvQ3a8di MRPc6EDu3t5nYp7EExswMM18WBxhkuagPzFxlqe6nLv7gI3qsKpgWhuGxNfbX+MHngBM SBz8rMMY3HKo+rfpDu6iKobaI06tq3ZVvHXAwyWrFqTmXqHqeysX0b/DfciDfUYnEFNR v2TA== X-Forwarded-Encrypted: i=1; AJvYcCVzYPuql11SjGdiwQsLUWz2p3RhLYoYe1mkBaKvKS3lE/YBGHg4D67mgjD9Ah2XAWYELlOwp5SgZ/I=@vger.kernel.org, AJvYcCWGTLPQqMKCgwW8oM19EH/EfZtOKHs45EqIFoqW2l1g3LVP+/BpC/SH20yBXMLaQCpJoC5PEopagRSXSmCr@vger.kernel.org, AJvYcCXuSHGkAEWd6tEyt50M9N9mUnKKEcB9XcgBM3T26Bhv4erSoOPICreyFfxV/bfgA0snpFnfEFTdLK/J@vger.kernel.org X-Gm-Message-State: AOJu0YyTSk+y6wA9anAmTSbURyYP3bLXwV6KG7nB1/aTDWyYH3NJ91cd zeHT+bg6wVbHM3MVoIu//S89kZQIDbQzisukfaE2SuIWCbqLijzpP7A+BLWdjg== X-Gm-Gg: ASbGnctfgVrCvfD94ghC0CdLiwj3oTYXNSSG2vNhftv2VOHhAeMuoaXVjR8P+x5H8VL DW+3iu4IlEk58uefCbAkZHOvJbe7rjFnJPxF28SQ4HDCOqorCdBGtaGYQIfOvu4Gdmtmd6n4oZ2 9RwSFZFBgOkBhvmJmAGl7ozHIWt3PBmJtgzoNYmuiiyrrwYYAiOCbDH/1Wo1VJ4RKkhY4qH+0Xi AWcCTMtEXt5FAFLtrQUehfZjkM/UykQR1JT6OTyoqh9aNvOO2ttQEftfwvAKzpGU9qgok8ULWjE btHMaGS3uTDwavtPem/7CLFXswHWCpCMAIPjd/q3qqmXvFAL+WNIB1MZBWQEfelMFwUg/60QyTH sN8zvVoS7W4wPIsejKcNrdld7tR63kNnb X-Google-Smtp-Source: AGHT+IFl1yUBAVahJrUDF2mZttrG/hGvZmBvDQqccpdKN5iF6+AwaUNB728y2v5g7Pxa3ZXHkjmJQg== X-Received: by 2002:a17:907:3d88:b0:ad8:8940:b3ad with SMTP id a640c23a62f3a-adfad3a3429mr218352066b.4.1750026191077; Sun, 15 Jun 2025 15:23:11 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:10 -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 v5 5/8] iio: accel: adxl313: add inactivity sensing Date: Sun, 15 Jun 2025 22:22:55 +0000 Message-Id: <20250615222258.117771-6-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Enhance the interrupt handler to process inactivity events. Introduce functions to configure the threshold and period registers for inactivity detection, as well as to enable or disable the inactivity feature. Extend the fake IIO channel to handle inactivity events by combining the x, y, and z axes using a logical AND operation. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 2 + drivers/iio/accel/adxl313_core.c | 161 ++++++++++++++++++++++++++----- 2 files changed, 137 insertions(+), 26 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 b0d14ce60f01..95f52c95682a 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,16 @@ static const struct iio_event_spec adxl313_activity_ev= ents[] =3D { }, }; =20 +static const struct iio_event_spec adxl313_inactivity_events[] =3D { + { + .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 +283,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 +353,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) { @@ -342,7 +373,17 @@ static int adxl313_is_act_inact_en(struct adxl313_data= *data, if (ret) return ret; =20 - axis_en =3D FIELD_GET(ADXL313_ACT_XYZ_EN, axis_ctrl); + /* Check if axis for activity are enabled */ + switch (type) { + case ADXL313_ACTIVITY: + axis_en =3D FIELD_GET(ADXL313_ACT_XYZ_EN, axis_ctrl); + break; + case ADXL313_INACTIVITY: + axis_en =3D FIELD_GET(ADXL313_INACT_XYZ_EN, axis_ctrl); + break; + default: + return -EINVAL; + } =20 if (!axis_en) return false; @@ -361,11 +402,9 @@ static int adxl313_set_act_inact_en(struct adxl313_dat= a *data, { unsigned int axis_ctrl; unsigned int threshold; + unsigned int inact_time_s; int ret; =20 - if (type !=3D ADXL313_ACTIVITY) - return 0; - if (cmd_en) { /* When turning on, check if threshold is valid */ ret =3D regmap_read(data->regmap, adxl313_act_thresh_reg[type], @@ -375,15 +414,33 @@ static int adxl313_set_act_inact_en(struct adxl313_da= ta *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 */ ret =3D adxl313_set_measure_en(data, false); if (ret) return ret; =20 /* Enable axis according to the command */ - axis_ctrl =3D ADXL313_ACT_XYZ_EN; + switch (type) { + 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; + } ret =3D regmap_assign_bits(data->regmap, ADXL313_REG_ACT_INACT_CTL, axis_ctrl, cmd_en); if (ret) @@ -484,6 +541,8 @@ static int adxl313_read_event_config(struct iio_dev *in= dio_dev, switch (dir) { case IIO_EV_DIR_RISING: return adxl313_is_act_inact_en(data, ADXL313_ACTIVITY); + case IIO_EV_DIR_FALLING: + return adxl313_is_act_inact_en(data, ADXL313_INACTIVITY); default: return -EINVAL; } @@ -503,6 +562,8 @@ static int adxl313_write_event_config(struct iio_dev *i= ndio_dev, switch (dir) { case IIO_EV_DIR_RISING: return adxl313_set_act_inact_en(data, ADXL313_ACTIVITY, state); + case IIO_EV_DIR_FALLING: + return adxl313_set_act_inact_en(data, ADXL313_INACTIVITY, state); default: return -EINVAL; } @@ -517,24 +578,45 @@ static int adxl313_read_event_value(struct iio_dev *i= ndio_dev, { struct adxl313_data *data =3D iio_priv(indio_dev); unsigned int act_threshold; + unsigned int inact_threshold; + unsigned int inact_time_s; int ret; =20 if (type !=3D IIO_EV_TYPE_MAG) return -EINVAL; =20 - if (info !=3D IIO_EV_INFO_VALUE) - return -EINVAL; - - switch (dir) { - case IIO_EV_DIR_RISING: + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + ret =3D regmap_read(data->regmap, + adxl313_act_thresh_reg[ADXL313_ACTIVITY], + &act_threshold); + if (ret) + return ret; + *val =3D act_threshold * 15625; + *val2 =3D MICRO; + return IIO_VAL_FRACTIONAL; + case IIO_EV_DIR_FALLING: + ret =3D regmap_read(data->regmap, + adxl313_act_thresh_reg[ADXL313_INACTIVITY], + &inact_threshold); + if (ret) + return ret; + *val =3D inact_threshold * 15625; + *val2 =3D MICRO; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_EV_INFO_PERIOD: ret =3D regmap_read(data->regmap, - adxl313_act_thresh_reg[ADXL313_ACTIVITY], - &act_threshold); + ADXL313_REG_TIME_INACT, + &inact_time_s); if (ret) return ret; - *val =3D act_threshold * 15625; - *val2 =3D MICRO; - return IIO_VAL_FRACTIONAL; + *val =3D inact_time_s; + return IIO_VAL_INT; default: return -EINVAL; } @@ -553,16 +635,24 @@ static int adxl313_write_event_value(struct iio_dev *= indio_dev, if (type !=3D IIO_EV_TYPE_MAG) return -EINVAL; =20 - if (info !=3D IIO_EV_INFO_VALUE) - return -EINVAL; - - /* Scale factor 15.625 mg/LSB */ - regval =3D DIV_ROUND_CLOSEST(val * MICRO + val2, 15625); - switch (dir) { - case IIO_EV_DIR_RISING: - return regmap_write(data->regmap, - adxl313_act_thresh_reg[ADXL313_ACTIVITY], - regval); + switch (info) { + case IIO_EV_INFO_VALUE: + /* Scale factor 15.625 mg/LSB */ + regval =3D DIV_ROUND_CLOSEST(MICRO * val + val2, 15625); + switch (dir) { + case IIO_EV_DIR_RISING: + return regmap_write(data->regmap, + adxl313_act_thresh_reg[ADXL313_ACTIVITY], + regval); + case IIO_EV_DIR_FALLING: + return regmap_write(data->regmap, + adxl313_act_thresh_reg[ADXL313_INACTIVITY], + regval); + default: + return -EINVAL; + } + case IIO_EV_INFO_PERIOD: + return adxl313_set_inact_time_s(data, val); default: return -EINVAL; } @@ -722,6 +812,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 @@ -903,6 +1004,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 Fri Oct 10 04:00:27 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 014BC283141; Sun, 15 Jun 2025 22:23:13 +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=1750026195; cv=none; b=DKBF4K5Ji7bIQjFC4LNLICyb1fM5PdAIdl7IKTBEZ41vVsvjddJHeB9EGPGwhEJCYzz5QTD+xlIebk4Rrd3JIHReHgtVg/tlWwnuNRPoQgTJFC3suvoVBGg+zRhNa/4RPwVrl8o95XDApBompZxRgx1TvvioYft75ju94E63Nfc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026195; c=relaxed/simple; bh=IL6WIr/r7jeZg+QTWPfJIlpuxYVavKG6r0rAqIAG6GM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=igxDedsuJE64RpNHQk9JQojXbwSiaLkd0sOoRzaF9G3JkeK775PCyLV6Ru8m/Ysj8v6lIniX9MwLyZpKtWvWiUc0Udn8fvt+P4LEWMnsxHsFfZTxgUXp3fXecz4wJeG+mqDU5KIhDZV4iijt7ec7tCmGyRfZwwkV57wTDukA97o= 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=KwlDKOFn; 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="KwlDKOFn" Received: by mail-ed1-f47.google.com with SMTP id 4fb4d7f45d1cf-606b39b19b6so714731a12.1; Sun, 15 Jun 2025 15:23:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026192; x=1750630992; 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=Y+SUvETOXPqWlMOnYdfvPk8HDZj5mET+aHB1oxq4dN8=; b=KwlDKOFnWv3azrei4/7DKe6cjj0lE/PeCW5am0b88I8AWPGL3LLRIaEpDQwgnvrEmo vtcn/9s89UjtX2Ak0ImKIxzVXgTsSfjOzy/RuIGZ9YhxSjwh2vX134x+u8rKgvfYecQs 1uwTbFY64sdM+dQaijBEHew9n+WA5tx6UjLxuuJupYw5Y+/LPS4Y9PT1eVnIbmpeufQe W9Lw7xm18gRykvoOsOZh/yyhSyZ6mP6gcyTaNIveynloSk1Lem+LEg/dPtKF0Dvo6a9P xs9pYUCiqlx8MjXeoLmHihHGujJL2kKRO7Fz5aeDWBzAJXnrMW3OGoHwEDxPe/ZalRdz /IjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026192; x=1750630992; 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=Y+SUvETOXPqWlMOnYdfvPk8HDZj5mET+aHB1oxq4dN8=; b=VfNFxL7UhcIbGmPcOfvPG/8OOwD7EYcV6ZYfj/s7rrm8JJHtSulw5uZFaBfSNOr8Dk /FN8S4Q4V+CkdHbJXniMhpLrKqysqb+ubMuL7Gd4DNfqTw136yWL/eXfCoDGxy7hLzg8 Jc1jAJFPqkCNel/kQ2kOio9OyXT/RY3qcIi/Fuh5WrnVJ4T/UuFkLqwNJ+pDoq8LINUs OfmpCmeTcqfeJi9SeL6D2ovn4h6UQ/9PicJK5qxJbm3hVSkYZQ2KWNXexMEOo4Lp4wq9 yAJ8xD7sBkBxlOffcyGVXczrAc7XFgBSFujv+OrDz68SFtlheTWdNudW93MiYppxxFwJ c1/g== X-Forwarded-Encrypted: i=1; AJvYcCVCu05qislSQEBl2TTWOIk62f21oYJWwtnxut7CeAo3MYEjcDPbxLCfALAw1RJK1r5mmEzgPpJaU4OjMY0/@vger.kernel.org, AJvYcCVzfG1y8bjZ54VTWsuB+u2GDkx+KlQQ4KXvTe9JGtMvJZrXj+Yduq24f6M1OfDivhpPo4Y2FmVXgl2T@vger.kernel.org, AJvYcCX/zdNLTdy5/W6RRWXegMNC8cwU9MSuB8nvWnZDuGL9q0pUq4walwoFynDuBEB0VmWEIdXeoHDFAUE=@vger.kernel.org X-Gm-Message-State: AOJu0YyhuwczUcA3P7xg9oKmt8WqNMJL96C4nWZ658tJdCFAnfDjOdYo SHq55rAQdrbrTf4pMUVf4IGrMTFPjRlsjwtQrKVr3blIOuZXSiuJVKEf X-Gm-Gg: ASbGncuCvKqGD1qiBpEPlfsLA6VSX3fTp3k0DPYSptvp9Pl6uvhS+kp5XwEjfB5gqjS yrgPpHCUNtd7FOAW8RDo3SJnq/vNpJDVh4PqIFIQ4UcHORhhipSobQx+0IRbe89BmxjF2SwcIZ9 oQxl2ccLFPQo1KNW6QmKJgU9Cd450NZcIqtqS6z1/Vk9QiqTWipGYxagc05eoHXAbQuWvnC9cTm 6qJ+9N4EGioNU8d7C2FeABlTkd/ZSMQ6k9gqmh3ZHr6etcvp+fHEd26vW5mTr/umBXxd/M+zJ9g sqSn7/HDZN1L7axw3e9pVk+Rei2e02QVcLCZhJf25w1rA/JwxlqZpkaESbWG7muk3Mtqlqt9L9N cmVX2Xj2lBeO6Rxthqaj3spnoGbJDyZRA X-Google-Smtp-Source: AGHT+IEy3L4/XFdDbLFlohkIV5DuAV8vLjy2DIONEp2lUnN/oMZnh01EvZyQN6PCkyjGeCzqhVPy1Q== X-Received: by 2002:a17:906:c154:b0:ad8:a2d0:8f8a with SMTP id a640c23a62f3a-adfad5b5198mr214070266b.16.1750026192167; Sun, 15 Jun 2025 15:23:12 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:11 -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 v5 6/8] iio: accel: adxl313: implement power-save on inactivity Date: Sun, 15 Jun 2025 22:22:56 +0000 Message-Id: <20250615222258.117771-7-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-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. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313.h | 3 +++ drivers/iio/accel/adxl313_core.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 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 95f52c95682a..d8a263b2a6f6 100644 --- a/drivers/iio/accel/adxl313_core.c +++ b/drivers/iio/accel/adxl313_core.c @@ -396,6 +396,25 @@ 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; + + en =3D en && act_en && inact_en; + + return regmap_assign_bits(data->regmap, ADXL313_REG_POWER_CTL, + (ADXL313_POWER_CTL_AUTO_SLEEP | ADXL313_POWER_CTL_LINK), + en); +} + static int adxl313_set_act_inact_en(struct adxl313_data *data, enum adxl313_activity_type type, bool cmd_en) @@ -426,6 +445,7 @@ static int adxl313_set_act_inact_en(struct adxl313_data= *data, } } =20 + /* Start modifying configuration registers */ ret =3D adxl313_set_measure_en(data, false); if (ret) return ret; @@ -452,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 Fri Oct 10 04:00:27 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 2765E283FD6; Sun, 15 Jun 2025 22:23:14 +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=1750026197; cv=none; b=kGM81t49RghMwFSOXKFFzgakJEBd7tKMsxfSdMnlOb7iql0topRDjNDfgZY40EN7KVwpBqnwEB6F1RxjBxvR+uUE4iZgFuggiQYrtb/ZG8dz3SpywPcAVQ97AvPU24yP8pwtNdvnyqjMyTz1ZuFabEqh9/iQWTx0b8s4Rz+Lvac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026197; c=relaxed/simple; bh=5zmq67RrbidWvGT+nU8mPVUwsnFqWPDMndHHaEb9/Ro=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tWYzeComvvtZaCo7+11kWSGu4ZGmZHvYEffK5bCIbh4zXS6EmBP6s2hjJjqLWIfP82A28muF3mP3mmVF95+ByTra2kl/W2PDOiVTWjFrcjuWri11mWevxRKuIGiWZMvI0BzV9ikXh3lT3Yy2Gva0GnUcR6OLR0fRsfMRtQVaI+Q= 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=TNFzkMJA; 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="TNFzkMJA" Received: by mail-ed1-f54.google.com with SMTP id 4fb4d7f45d1cf-6006cf5000aso590186a12.0; Sun, 15 Jun 2025 15:23:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026193; x=1750630993; 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=CGHcozTw568gdp3NNjBkf4aWTLbK4Gw6qR5VfaroyFw=; b=TNFzkMJAk8pdWgT/lG6T95dRgaxFw8b3R3Pu+hyifmLvhZ5uO2nKgUY5fy0PmRZ4gC u5mcP1HTJbSIesThlvjyR4DsR9Jima4dvuO8C0MeyjdGCCS/WDLbkdOx/gXdDvsJ+zWe 7gvuEKmm+EoopoBj0UqY/51TEKvC2gLVrsHTXfRyg8d1Q2WpJPEwbdK9PkYhtNbhPVWi Lvk7tideFbNzAmc+xlam+uuwNw4T2K20k1tibVE0jFYpk4HLUoy5KSAr4UJWwye5f/zU iggaePMA4Y2PO78amknhCbLveTpFIvSFgPGuSITR3a3PlZQ5p9/Gz97KTKrKRUOlbl9T tgAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026193; x=1750630993; 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=CGHcozTw568gdp3NNjBkf4aWTLbK4Gw6qR5VfaroyFw=; b=vMfNOTVp9k/2tAzTqZa9ABtlwRM42dtWDvpvFKeLVKbxlEM4LsOB0b7ZET/CYoXLXq fNe+NvrobYiGX4L6efcGf9COrcBv7vKGv1dWeDCGLY9EfUKbTeC0isaNr7hXRvOjTg1q W/niYMIhFUzR1WYWqqFpbBStG8WNLc02Bb66bHhKNZH2AJXwaJqHvsnV1XptzuXKJtaM 1xcU+c7nPY7RaUN0SsQq21NKd6osmlBomXuQeBNCObXiVp+QVVLQ43VJP0KeI19+T9Hw bIKB5Cyw+ZHNb7MLPLa7JJeU3yPVHH1ahesp6OpdDP8dp/jNTYFgL1quofDwBYAgcz9H o8pg== X-Forwarded-Encrypted: i=1; AJvYcCVSOq2zfWqN38RovRQoqjRL+c9wn49khMWAR+axSSGlkx/cnl7cVoUUj2Qgzcnsooq8ZTz4Z9B0m1H7@vger.kernel.org, AJvYcCVU6SBTOm3FcGhSq4gZK3lK9o+O9TtC/Rqp16GMQaYwLvpjW0aG/ggccwJ1Dqkncw9KPgPLWLqkll/43c/Y@vger.kernel.org, AJvYcCWRji8RMOPcoS4wxnj50GLwtU4k8njWkcQUh/ZGA3MPHXtXiMUZvfuW+xlP6UtEObdTUspYPtEfMnM=@vger.kernel.org X-Gm-Message-State: AOJu0YxQFeCycsOETGhmttvYb8ey8QUsO5ES33EtKADt+wXalpguRQoQ N4qsBrTv03CHQhNb1vLh9klEv8L+zCTZLHrQ4AkPPYo0ssRzvzX2Gjk0 X-Gm-Gg: ASbGncszA0BAMQqb6qIpLBOE3cQcMEePW0s8FMPx6AjOdNFhFYkyklzbUnKlgHyT+5q 8X8ea08IieGsIbAWclObySvfOY6t7ItNIbaU6vTig/bxB8S4HUQsTd2OZI3wP2+b86tJTMRAkWq 35tMqMxydhhvsSTQhcZDv6XU9coNbuBA32IAjamc5y0l77GJLHMLSB7roxfEd2wcGq2vN2Vcf4R Iup/9CFwhRTbukCBg0WAbGosf8Hn1yu9vvxS0ABvBR3SyD+8gA1aXmYHvijh/CqaSmycwqZ/r75 uprUMyi4o6QYH9u/jLWw6Ua3GSB380AYljks1sgPlkfFC0MzRWmCsJhR00Axyy1g0R4Dnut+cJz JfbUcvw2zKUHL7YnzZXputW6/ZANXmN9V X-Google-Smtp-Source: AGHT+IGq1YyyLSTwX05SLsNZo3BZaqX+E9QYjc+fO7jg/QIhpa/1Z+d1DQXHFH0o4AEyNAES9k7W5w== X-Received: by 2002:a17:907:7e84:b0:adb:5985:5b58 with SMTP id a640c23a62f3a-adfad2f3e2amr226171866b.1.1750026193270; Sun, 15 Jun 2025 15:23:13 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:12 -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 v5 7/8] iio: accel: adxl313: add AC coupled activity/inactivity events Date: Sun, 15 Jun 2025 22:22:57 +0000 Message-Id: <20250615222258.117771-8-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce AC-coupled activity and inactivity as MAG_ADAPTIVE events. This adds a new set of threshold and duration configuration options, ensures proper handling of event disabling, and extends the use of the link bit to support complementary event configurations. For example, either ACTIVITY or ACTIVITY_AC can be enabled, but only the most recently set configuration will remain active. Disabling ACTIVITY will have no effect if ACTIVITY_AC is currently enabled, as the event types must match (i.e., ACTIVITY_AC must be explicitly disabled). When either INACTIVITY or INACTIVITY_AC is enabled alongside an activity event, the link bit is set. With the link bit and auto-sleep enabled, activity and inactivity events represent changes in the sensor's power-saving state and are only triggered upon actual state transitions. Since AC coupling uses separate bits for activity and inactivity, each can be configured independently. For instance, ACTIVITY can be linked with INACTIVITY_AC. If one of the linked events is disabled, the link bit is cleared. In that case, the remaining event will no longer reflect a state transition but will instead trigger based on periodic inactivity or whenever the activity threshold is exceeded. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- drivers/iio/accel/adxl313_core.c | 361 +++++++++++++++++++++++++------ 1 file changed, 296 insertions(+), 65 deletions(-) diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_c= ore.c index d8a263b2a6f6..a04f28049f3e 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 { @@ -265,6 +290,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 { @@ -362,12 +395,50 @@ 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 combinat= ion 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_is_act_inact_en(struct adxl313_data *data, enum adxl313_activity_type type) { unsigned int axis_ctrl; unsigned int regval; - int axis_en, ret; + bool axis_en, int_en; + int ret; =20 ret =3D regmap_read(data->regmap, ADXL313_REG_ACT_INACT_CTL, &axis_ctrl); if (ret) @@ -376,9 +447,11 @@ static int adxl313_is_act_inact_en(struct adxl313_data= *data, /* Check if axis for activity are enabled */ switch (type) { case ADXL313_ACTIVITY: + case ADXL313_ACTIVITY_AC: axis_en =3D FIELD_GET(ADXL313_ACT_XYZ_EN, axis_ctrl); break; case ADXL313_INACTIVITY: + case ADXL313_INACTIVITY_AC: axis_en =3D FIELD_GET(ADXL313_INACT_XYZ_EN, axis_ctrl); break; default: @@ -393,21 +466,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; + + act_en =3D act_en || 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; + + inact_en =3D inact_en || inact_ac_en; + en =3D en && act_en && inact_en; =20 return regmap_assign_bits(data->regmap, ADXL313_REG_POWER_CTL, @@ -422,6 +512,7 @@ static int adxl313_set_act_inact_en(struct adxl313_data= *data, unsigned int axis_ctrl; unsigned int threshold; unsigned int inact_time_s; + bool act_inact_ac; int ret; =20 if (cmd_en) { @@ -435,7 +526,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= ); if (ret) return ret; @@ -443,6 +534,14 @@ static int adxl313_set_act_inact_en(struct adxl313_dat= a *data, if (!inact_time_s) return 0; } + } else { + /* When turning off, check if the correct coupling event was + * specified, this can be misused, e.g.: Having AC-coupled + * activity turned on, and in current call trying to turning off + * a DC-coupled activity shall be caught here. + */ + if (adxl313_is_act_inact_ac(data, type) <=3D 0) + return 0; } =20 /* Start modifying configuration registers */ @@ -453,9 +552,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 +567,25 @@ 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 */ + 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; + } + + ret =3D regmap_assign_bits(data->regmap, ADXL313_REG_ACT_INACT_CTL, + adxl313_act_acdc_msk[type], act_inact_ac); + 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); @@ -553,6 +673,37 @@ static int adxl313_write_raw(struct iio_dev *indio_dev, } } =20 +static int adxl313_read_mag_config(struct adxl313_data *data, + enum iio_event_direction dir, + enum adxl313_activity_type act_type, + enum adxl313_activity_type inact_type) +{ + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl313_is_act_inact_en(data, act_type); + case IIO_EV_DIR_FALLING: + return adxl313_is_act_inact_en(data, inact_type); + default: + return -EINVAL; + } +} + +static int adxl313_write_mag_config(struct adxl313_data *data, + enum iio_event_direction dir, + enum adxl313_activity_type act_type, + enum adxl313_activity_type inact_type, + bool state) +{ + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl313_set_act_inact_en(data, act_type, state); + case IIO_EV_DIR_FALLING: + return adxl313_set_act_inact_en(data, inact_type, 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, @@ -560,14 +711,15 @@ static int adxl313_read_event_config(struct iio_dev *= indio_dev, { struct adxl313_data *data =3D iio_priv(indio_dev); =20 - if (type !=3D IIO_EV_TYPE_MAG) - return -EINVAL; - - switch (dir) { - case IIO_EV_DIR_RISING: - return adxl313_is_act_inact_en(data, ADXL313_ACTIVITY); - case IIO_EV_DIR_FALLING: - return adxl313_is_act_inact_en(data, ADXL313_INACTIVITY); + switch (type) { + case IIO_EV_TYPE_MAG: + 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; } @@ -581,54 +733,51 @@ static int adxl313_write_event_config(struct iio_dev = *indio_dev, { struct adxl313_data *data =3D iio_priv(indio_dev); =20 - if (type !=3D IIO_EV_TYPE_MAG) - return -EINVAL; - - switch (dir) { - case IIO_EV_DIR_RISING: - return adxl313_set_act_inact_en(data, ADXL313_ACTIVITY, state); - case IIO_EV_DIR_FALLING: - return adxl313_set_act_inact_en(data, ADXL313_INACTIVITY, state); + switch (type) { + case IIO_EV_TYPE_MAG: + return adxl313_write_mag_config(data, dir, + 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; } } =20 -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) +static int adxl313_read_mag_value(struct adxl313_data *data, + enum iio_event_direction dir, + enum iio_event_info info, + enum adxl313_activity_type act_type, + enum adxl313_activity_type inact_type, + int *val, int *val2) { - struct adxl313_data *data =3D iio_priv(indio_dev); - unsigned int act_threshold; - unsigned int inact_threshold; - unsigned int inact_time_s; + unsigned int threshold, period; int ret; =20 - if (type !=3D IIO_EV_TYPE_MAG) - return -EINVAL; - switch (info) { case IIO_EV_INFO_VALUE: switch (dir) { case IIO_EV_DIR_RISING: ret =3D regmap_read(data->regmap, - adxl313_act_thresh_reg[ADXL313_ACTIVITY], - &act_threshold); + adxl313_act_thresh_reg[act_type], + &threshold); if (ret) return ret; - *val =3D act_threshold * 15625; + *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[ADXL313_INACTIVITY], - &inact_threshold); + adxl313_act_thresh_reg[inact_type], + &threshold); if (ret) return ret; - *val =3D inact_threshold * 15625; + *val =3D threshold * 15625; *val2 =3D MICRO; return IIO_VAL_FRACTIONAL; default: @@ -637,29 +786,25 @@ static int adxl313_read_event_value(struct iio_dev *i= ndio_dev, case IIO_EV_INFO_PERIOD: ret =3D regmap_read(data->regmap, ADXL313_REG_TIME_INACT, - &inact_time_s); + &period); if (ret) return ret; - *val =3D inact_time_s; + *val =3D period; return IIO_VAL_INT; default: return -EINVAL; } } =20 -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) +static int adxl313_write_mag_value(struct adxl313_data *data, + enum iio_event_direction dir, + enum iio_event_info info, + enum adxl313_activity_type act_type, + enum adxl313_activity_type inact_type, + int val, int val2) { - struct adxl313_data *data =3D iio_priv(indio_dev); unsigned int regval; =20 - if (type !=3D IIO_EV_TYPE_MAG) - return -EINVAL; - switch (info) { case IIO_EV_INFO_VALUE: /* Scale factor 15.625 mg/LSB */ @@ -667,11 +812,11 @@ static int adxl313_write_event_value(struct iio_dev *= indio_dev, switch (dir) { case IIO_EV_DIR_RISING: return regmap_write(data->regmap, - adxl313_act_thresh_reg[ADXL313_ACTIVITY], + adxl313_act_thresh_reg[act_type], regval); case IIO_EV_DIR_FALLING: return regmap_write(data->regmap, - adxl313_act_thresh_reg[ADXL313_INACTIVITY], + adxl313_act_thresh_reg[inact_type], regval); default: return -EINVAL; @@ -683,6 +828,56 @@ static int adxl313_write_event_value(struct iio_dev *i= ndio_dev, } } =20 +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, + 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; + } +} + +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, + 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; + } +} + static int adxl313_set_watermark(struct iio_dev *indio_dev, unsigned int v= alue) { struct adxl313_data *data =3D iio_priv(indio_dev); @@ -824,28 +1019,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 Fri Oct 10 04:00:27 2025 Received: from mail-ed1-f43.google.com (mail-ed1-f43.google.com [209.85.208.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76E0B26AA88; Sun, 15 Jun 2025 22:23:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026198; cv=none; b=fw96vOakDavTHJmjj1/jyGxotQQwjkdDxujBZgXDJ3+nk6JJhrT5MIopSe6W+1gpRyhP7Zl7sjXp1GJhWak4XpkcsQ08yLVQ+O7kg6I2aT5/OIoat5+vQIRwocMXW295GqG6liUPyRzRxW0bgVy10t+8RuTrZVuQJfUz5+dFVMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750026198; c=relaxed/simple; bh=WsfajTQgWR/cO00C+SHnb24AI3fAbG4PiwTdh6tZxV4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=iIWczycs/mVwXc1RtXwzAPrh9hanldp07qDA3lXUT43zdGEEX5fXCZBMe+sUTJRZk46KgcNCnGTtzgSBIOUNkw5vkBSrrzlBxDEEbwKKwE3ARGR7Fkx4EmU7qQEqBMaknBN0g9lCH4yTg1ylr+6w4jNmTdngDtofqPmdYncsCZU= 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=X03PuSvB; arc=none smtp.client-ip=209.85.208.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="X03PuSvB" Received: by mail-ed1-f43.google.com with SMTP id 4fb4d7f45d1cf-6075ca6d617so806353a12.0; Sun, 15 Jun 2025 15:23:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750026195; x=1750630995; 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=BBUCh6MSsIltfKv0dnHBoCIz5u9pOT6OITU6c8QQY3w=; b=X03PuSvBtSzmTFXj9Bv+XgZTc3t0/NiXnUyLLnlTZnXLNnvH7Ne51p2r9Ug3pjZRWz DyT8Q/WZA9lskBMFoqIco6kIBPluRuOeNFZnPuEEiP1w+uFIRV1tVNqmdk93GZHpGb7Q fuv1LC4VkPgdYgLKkrsBHoFv7R+QoE7qeTUR4J+ikiG9H8NuVMasDVKGQzWTuclaitGC KnSoA28OBpjvzGQuwP8ufxY/LqOT4fzDtWzqNo7UBvVVQvnnuRG2713ztQcRbAIGc8Cq huonf8Eo1FbvWIcgR/GPD0vaV4aVY6QlGbwwerTF6xfz9IcAcccv1yCP8z3bInlh1qA0 Vbyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750026195; x=1750630995; 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=BBUCh6MSsIltfKv0dnHBoCIz5u9pOT6OITU6c8QQY3w=; b=hOohgP4Zm9I45fyRYrW+uoICpz2CSzyZN8Hvbq8JesvFbLdYrLrOs76gAC7gSZfnZw UFnwlq+OXWvE0g6rnAUTV/ZghrvtqUTGPezloU+vnrYPuFRD5U28u3Xgpp/HEV2k18Kq +16/MpvJos4OJiDTBbYxI13A10ZHGbCIDUxpZ8iHMO6c3WprFE8d7p3qn8YWnCChDClq 7A0SgpSwregwOQhAyRfQjFFz9XyO7ZlgttRtY8TBnXuvmOGc/m4jLV4gCpPhEw0RDQv1 JZ2xC/rYt6jQXt3U2/GO/8A5d7pT7GRsEZjA6niDDZJUmkEJN6L0mtER9V7cs0VrP0f9 1AuA== X-Forwarded-Encrypted: i=1; AJvYcCVkHRpYpDBx8Fd4HRUgaDUFTbFTy8Q49/8vJVUf9pUvJXjD2kRdvRFQ0ypjp12pNAK9mDOaO1qraA/6RcsY@vger.kernel.org, AJvYcCWmqq6JPZbslv1SEwwkAl8hj2zqd9x2s2K9Jy5fJBKx3DNnmkeg648WUysYOnhtmfHZuLcKLRpzvGzy@vger.kernel.org, AJvYcCWrFV1RUt0ZUPq14r/X9Tc42mO00mzGfUu5snsq3bLTBlOE2+ya9rQcPyKE4sVAdwMuyCR+SS41L9U=@vger.kernel.org X-Gm-Message-State: AOJu0Yw+TUEZlE00pLxaErI3ptaynVoj08pYcXmfCBUz+pBtv6LAGfAg S3vvNJztEq7sIsww5RIUyzkflQxoK9WWOgEEY1dF6dgSUkQuRDzzceBR X-Gm-Gg: ASbGncvyGHo+7RlE4rRi6BWIvqaVKslkHYU107C6iBdwb2CnxfII4xpyZBMsUpjUKIj 8Q75oAtiFIS0yF8Y4jZvDR/4whiJDV0y4CBVOUHBkcKw4LhE/rRkzH8ORTnZBLEi77qPnx6np6t 6AYJUBnXAhUCJTSsO0nlue8cKnF/SAjnzLBt07wvkgVpKzkxW3zbVRKUPrxWD1djRqPzBnewGn+ SwT3Zdqnnmh1U4XHolVtK06Cs2SxBjQU0iGxf0DNy1dyNQBX34C8HNMDx3aTAemSynSL1zIPuc+ GtGj4yQI3l4wQItGhc/D5M9uOQQsTUX0V52CaArNfkZNcAYDrgMv7oRICCaEOUmtCR4yh2iaL1d VAyFmD+aaJdqSs4g0XpeXV6bzhIWSfh2F X-Google-Smtp-Source: AGHT+IGHzbbjTwNk7IiJC4hws7/ahBBcI73kBW5rdkHRxxDDMvs0h9622Ak9r9hg3k36TUriCgMMOg== X-Received: by 2002:a17:906:c148:b0:ad8:9744:d0e2 with SMTP id a640c23a62f3a-adfad335350mr221083366b.1.1750026194401; Sun, 15 Jun 2025 15:23:14 -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-adf8b393ea8sm412692766b.159.2025.06.15.15.23.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jun 2025 15:23:14 -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 v5 8/8] docs: iio: add ADXL313 accelerometer Date: Sun, 15 Jun 2025 22:22:58 +0000 Message-Id: <20250615222258.117771-9-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250615222258.117771-1-l.rubusch@gmail.com> References: <20250615222258.117771-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. Signed-off-by: Lothar Rubusch Reviewed-by: Andy Shevchenko --- Documentation/iio/adxl313.rst | 289 ++++++++++++++++++++++++++++++++++ Documentation/iio/index.rst | 1 + 2 files changed, 290 insertions(+) create mode 100644 Documentation/iio/adxl313.rst diff --git a/Documentation/iio/adxl313.rst b/Documentation/iio/adxl313.rst new file mode 100644 index 000000000000..41b9cc37981c --- /dev/null +++ b/Documentation/iio/adxl313.rst @@ -0,0 +1,289 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +ADXL313 driver +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +This driver supports Analog Device's ADXL313 on SPI/I2C bus. + +1. Supported devices +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +* `ADXL313 `_ + +The ADXL313is a low noise density, low power, 3-axis accelerometer with +selectable measurement ranges. The ADXL313 supports the =C2=B10.5 g, =C2= =B11 g, =C2=B12 g and +=C2=B14 g ranges. + +2. Device attributes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Accelerometer measurements are always provided. + +Each IIO device, has a device folder under ``/sys/bus/iio/devices/iio:devi= ceX``, +where X is the IIO index of the device. Under these folders reside a set of +device files, depending on the characteristics and features of the hardware +device in questions. These files are consistently generalized and document= ed in +the IIO ABI documentation. + +The following tables show the adxl313 related device files, found in the +specific device folder path ``/sys/bus/iio/devices/iio:deviceX``. + ++---------------------------------------------------+---------------------= -------------------------------------+ +| 3-Axis Accelerometer related device files | Description = | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_scale | Scale for the accele= rometer channels. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x_calibbias | Calibration offset f= or the X-axis accelerometer channel. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x_raw | Raw X-axis accelerom= eter channel value. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_y_calibbias | y-axis acceleration = offset correction | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_y_raw | Raw Y-axis accelerom= eter channel value. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_z_calibbias | Calibration offset f= or the Z-axis accelerometer channel. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_z_raw | Raw Z-axis accelerom= eter channel value. | ++---------------------------------------------------+---------------------= -------------------------------------+ + ++---------------------------------------+---------------------------------= -------------+ +| Miscellaneous device files | Description = | ++---------------------------------------+---------------------------------= -------------+ +| name | Name of the IIO device. = | ++---------------------------------------+---------------------------------= -------------+ +| in_accel_sampling_frequency | Currently selected sample rate. = | ++---------------------------------------+---------------------------------= -------------+ +| in_accel_sampling_frequency_available | Available sampling frequency con= figurations. | ++---------------------------------------+---------------------------------= -------------+ + +The iio event related settings, found in ``/sys/bus/iio/devices/iio:device= X/events``. + ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_adaptive_falling_period | AC coupled inactivit= y time. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_adaptive_falling_value | AC coupled inactivit= y threshold. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_adaptive_rising_value | AC coupled activity = threshold. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_falling_period | Inactivity time. = | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_falling_value | Inactivity threshold= . | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_mag_rising_value | Activity threshold. = | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\&y\&z_mag_adaptive_falling_en | Enable or disable AC= coupled inactivity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\|y\|z_mag_adaptive_rising_en | Enable or disable AC= coupled activity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\&y\&z_mag_falling_en | Enable or disable in= activity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ +| in_accel_x\|y\|z_mag_rising_en | Enable or disable ac= tivity events. | ++---------------------------------------------------+---------------------= -------------------------------------+ + +The default coupling is DC coupled events. In this case the threshold will +be in place as such, where for the AC coupled case an adaptive threshold +(described in the datasheet) will be applied by the sensor. In general act= ivity, +i.e. ``ACTIVITY`` or ``ACTIVITY_AC`` and inactivity i.e. ``INACTIVITY`` or +``INACTIVITY_AC``, will be linked with auto-sleep enabled when both are en= abled. +This means in particular ``ACTIVITY`` can also be linked to ``INACTIVITY_A= C`` +and vice versa, without problem. + +Note here, that ``ACTIVITY`` and ``ACTIVITY_AC`` are mutually exclusive. T= his +means, that the most recent configuration will be set. For instance, if +``ACTIVITY`` is enabled, and ``ACTIVITY_AC`` will be enabled, the sensor d= river +will have ``ACTIVITY`` disabled, but ``ACTIVITY_AC`` enabled. The same is = valid +for inactivity. In case of turning off an event, it has to match to what is +actually enabled, i.e. enabling ``ACTIVITY_AC`` and then disabling ``ACTIV= ITY`` +is simply ignored as it is already disabled. Or, as if it was any other not +enabled event, too. + +Channels processed values +------------------------- + +A channel value can be read from its _raw attribute. The value returned is= the +raw value as reported by the devices. To get the processed value of the ch= annel, +apply the following formula: + +.. code-block:: + + processed value =3D (_raw + _offset) * _scale + +Where _offset and _scale are device attributes. If no _offset attribute is +present, simply assume its value is 0. + +The ADXL313 driver offers data for a single types of channels, the table b= elow +shows the measurement units for the processed value, which are defined by = the +IIO framework: + ++-------------------------------------+---------------------------+ +| Channel type | Measurement unit | ++-------------------------------------+---------------------------+ +| Acceleration on X, Y, and Z axis | Meters per Second squared | ++-------------------------------------+---------------------------+ + +Usage examples +-------------- + +Show device name: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat name + adxl313 + +Show accelerometer channels value: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_raw + 2 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_y_raw + -57 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_z_raw + 2 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_scale + 0.009576806 + +The accelerometer values will be: + +- X-axis acceleration =3D in_accel_x_raw * in_accel_scale =3D 0.0191536 m/= s^2 +- Y-axis acceleration =3D in_accel_y_raw * in_accel_scale =3D -0.5458779 m= /s^2 +- Z-axis acceleration =3D in_accel_z_raw * in_accel_scale =3D 0.0191536 m/= s^2 + +Set calibration offset for accelerometer channels. Note, that the calibrat= ion +will be rounded according to the graduation of LSB units: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 0 + + root:/sys/bus/iio/devices/iio:device0> echo 50 > in_accel_x_calibb= ias + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 48 + +Set sampling frequency: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_sampling_frequ= ency + 100.000000 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_sampling_frequ= ency_available + 6.250000 12.500000 25.000000 50.000000 100.000000 200.000000 400.0= 00000 800.000000 1600.000000 3200.000000 + + root:/sys/bus/iio/devices/iio:device0> echo 400 > in_accel_samplin= g_frequency + root:/sys/bus/iio/devices/iio:device0> cat in_accel_sampling_frequ= ency + 400.000000 + +3. Device buffers and triggers +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D + +This driver supports IIO buffers. + +All devices support retrieving the raw acceleration measurements using buf= fers. + +Usage examples +-------------- + +Select channels for buffer read: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_a= ccel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_a= ccel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_a= ccel_z_en + +Set the number of samples to be stored in the buffer: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 10 > buffer/length + +Enable buffer readings: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > buffer/enable + +Obtain buffered data: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> hexdump -C /dev/iio\:device0 + ... + 000000d0 01 fc 31 00 c7 ff 03 fc 31 00 c7 ff 04 fc 33 00 |..1..= ...1.....3.| + 000000e0 c8 ff 03 fc 32 00 c5 ff ff fc 32 00 c7 ff 0a fc |....2= .....2.....| + 000000f0 30 00 c8 ff 06 fc 33 00 c7 ff 01 fc 2f 00 c8 ff |0....= .3...../...| + 00000100 02 fc 32 00 c6 ff 04 fc 33 00 c8 ff 05 fc 33 00 |..2..= ...3.....3.| + 00000110 ca ff 02 fc 31 00 c7 ff 02 fc 30 00 c9 ff 09 fc |....1= .....0.....| + 00000120 35 00 c9 ff 08 fc 35 00 c8 ff 02 fc 31 00 c5 ff |5....= .5.....1...| + 00000130 03 fc 32 00 c7 ff 04 fc 32 00 c7 ff 02 fc 31 00 |..2..= ...2.....1.| + 00000140 c7 ff 08 fc 30 00 c7 ff 02 fc 32 00 c5 ff ff fc |....0= .....2.....| + 00000150 31 00 c5 ff 04 fc 31 00 c8 ff 03 fc 32 00 c8 ff |1....= .1.....2...| + 00000160 01 fc 31 00 c7 ff 05 fc 31 00 c3 ff 04 fc 31 00 |..1..= ...1.....1.| + 00000170 c5 ff 04 fc 30 00 c7 ff 03 fc 31 00 c9 ff 03 fc |....0= .....1.....| + ... + +Enabling activity detection: + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 1.28125 > ./events/in_= accel_mag_rising_value + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_= x\|y\|z_mag_rising_en + + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + Found IIO device with name adxl313 with device number 0 + + Event: time: 1748795762298351281, type: accel(x|y|z), channel: 0, = evtype: mag, direction: rising + Event: time: 1748795762302653704, type: accel(x|y|z), channel: 0, = evtype: mag, direction: rising + Event: time: 1748795762304340726, type: accel(x|y|z), channel: 0, = evtype: mag, direction: rising + ... + +Disabling activity detection: + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 0 > ./events/in_accel_= x\|y\|z_mag_rising_en + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + + +Enabling inactivity detection: + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 1.234375 > ./events/in= _accel_mag_falling_value + root:/sys/bus/iio/devices/iio:device0> echo 5 > ./events/in_accel_= mag_falling_period + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_= x\&y\&z_mag_falling_en + + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + Found IIO device with name adxl313 with device number 0 + Event: time: 1748796324115962975, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + Event: time: 1748796329329981772, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + Event: time: 1748796334543399706, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + ... + + +Now, enabling activity, e.g. the AC coupled counter-part ``ACTIVITY_AC`` + +.. code-block:: bash + root:/sys/bus/iio/devices/iio:device0> echo 1.28125 > ./events/in_= accel_mag_rising_value + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_= x\|y\|z_mag_rising_en + + root:/sys/bus/iio/devices/iio:device0> iio_event_monitor adxl313 + Found IIO device with name adxl313 with device number 0 + + Event: time: 1748796880354686777, type: accel(x|y|z), channel: 0, = evtype: mag_adaptive, direction: rising + <5s of inactivity, then> + Event: time: 1748796885543252017, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + + Event: time: 1748796887756634678, type: accel(x|y|z), channel: 0, = evtype: mag_adaptive, direction: rising + + Event: time: 1748796892964368352, type: accel(x&y&z), channel: 0, = evtype: mag, direction: falling + + +Note, when AC coupling is in place, the event type will be of ``mag_adapti= ve``. +AC- or DC-coupled (the default) events are used similarly. + +4. IIO Interfacing Tools +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +See Documentation/iio/iio_tools.rst for the description of the available I= IO +interfacing tools. diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 2d6afc5a8ed5..c106402a91f7 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -31,6 +31,7 @@ Industrial I/O Kernel Drivers adis16475 adis16480 adis16550 + adxl313 adxl380 bno055 ep93xx_adc --=20 2.39.5