From patchwork Thu Mar 13 16:50:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015483 Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13AB61386DA; Thu, 13 Mar 2025 16:51:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884670; cv=none; b=Iv39tpCODBN+DIpSIwOX1riSIrLlSG3dNSr4a4Tlj1nIGKFRuuLjYPHOT7i3G4+C2nw3Mjabo2j4VOW87PyiqNvtq1bEnWQdSLtmFE6jmyrymYULHlnyGQiWl+M1OYZY+O9Ylaun4EXbJ3F5Q5qzMS8C+dfDAjBxvlR+QZXo+g8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884670; c=relaxed/simple; bh=gASdt8h5VIpUlb3Vd3Zh4gCwb5FEXKYIJ8Fe7ic7sSM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RDz7Xd4G5riNbgSw2Eyh7OrWkXOkteAQq34ELceKY5wB0TaFWG2misxM81bQiOXFxoucu1+CQIoR6QrptfJDY6Sq/pom74dy2/choFm6stvZPA7IRP4yKZ9GuPhDMN/xQSHwivjErTj9WYXkfHvg9x93Chnsydle/g7pzjDsDks= 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=YVT8xwq+; arc=none smtp.client-ip=209.85.218.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YVT8xwq+" Received: by mail-ej1-f44.google.com with SMTP id a640c23a62f3a-ab7f9f57192so20393766b.3; Thu, 13 Mar 2025 09:51:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884667; x=1742489467; 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=QCQDcTYoRpdtmyWWmyEYcUe0QuhTYZStwQHeV2Ey30U=; b=YVT8xwq+QzUWttFNok+jOm4zTqfycZasCWdiGB8FHeVDCUuf4Ve0OCqqlQ+z+ddDsr wsORQXVuKpkNk80sccgLv4SyeCb9Odiv7snLAzpQF1XRmD4bHk2LxbL6rfrQ4KO68Man zmET+UR5P9vyNIB1pIs9Qe2aALDb3ivmza+ulQzyUJ1w+BW1GabPG91R4zSoHm1YshB5 NsSHFvHBbeJNI15+wZHG3FtMt4NDG0EYBzKonoi8M/dWeAGoTt8uP1LioEtGTrAn7IiV zCHP4moNL8cqvHppap7roGBihy2BXVXbwze9IUoJKW9669h84FYSkyEseyjr5fCfpeff f2xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884667; x=1742489467; 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=QCQDcTYoRpdtmyWWmyEYcUe0QuhTYZStwQHeV2Ey30U=; b=Be2OPaY/JXo5nQm5BWDx0Yz0bbEHjNU/4oZt9Eq4APXvsr7fN4nLofohb5K0lLyN+J 5Tudpnc1ckJDHGDssp+z1NkYGRy/pV3J+QsuFBwxjzAy9j08Zbv8gzVmrlbsI6O2T3mJ bKn6hN/ltlx3CnXwMCblIz1/w7TfQWCKOPMSOSn7/aqad//85tYeNeu8q9g1RPDcQFfa rUkgXUvvz0X1+JWpjXgblrNkpohtzsV38Gk8GAFUF42NmL2Je8tjzcK6kKrqZMAgSrgX 0dhAR6TZ7qq6PNw4vJ+aDcONW69Yz9FpWZMttWjdT5T1hbFUclZwIyTDZZUlTBxt3OVv RW/w== X-Forwarded-Encrypted: i=1; AJvYcCUZeGiOx3G06VbUOIRxlLORVeuiBhmd+mO9ma+zg5sOIh2gV8qecnmP/swAI78Q+E/Yr6nI3ztm9NGQAt4=@vger.kernel.org X-Gm-Message-State: AOJu0YzgeZjCxJTkEm4RtP5tghvVFuoRDUR/VRfhDEeqYWVvWtyh21E1 D1T+ItKSrp+OmpvrjbfRop3PlcCql9x+n0hw/dR+5LeuiM9CxRXq X-Gm-Gg: ASbGncvJvY/0vU2SwdVXcjlCpGxVma5cWrgfhi5PYL2hWBHpS+zczoN5W+DC3MF8Rmp CpMZEMt+9P2JaJEV9uIEAZq9byKmv5SNtIYSvhaZ9FQUTUugTJoQif3r/o/Xl1EW/1JO5gagVZZ jBOVJEfYwqYpyIObCfKVN8cdmNQ49JicWeYWe9NZPuB7pAfsG/Bj6PagvW5Pcq815bju3UpCPn+ 44f9mQfR9abAYK2ZGBaRgGwx5ptaoE3ANhxba61MOiw94e0KInUH+zp6nWy7QomeOgABSCKqrII n0UaiamvKIXwBmhurqVbNeY+vIR1/QxvO483SDLrFlNrbFgz1+BcAip6Ypu3avAK5QrKrEzehsG EKubqELM/qIglodBtTAe/3Fg= X-Google-Smtp-Source: AGHT+IFoYpY9+p5Pdltw7mEXmmWrymiPL9vL29gk2nTjGAaXP0Cck+MJ0ev8iNlJiErdfM+PTfHxLA== X-Received: by 2002:a17:907:360c:b0:ac0:b71e:44e1 with SMTP id a640c23a62f3a-ac27137e457mr1033506866b.6.1741884666966; Thu, 13 Mar 2025 09:51:06 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:06 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 01/14] iio: accel: adxl345: use regmap cache for INT mapping Date: Thu, 13 Mar 2025 16:50:36 +0000 Message-Id: <20250313165049.48305-2-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use regmap cache to replace the maintenance of the interrupt mapping state by a member variable intio. The interrupt mapping is initialized when the driver is probed, and it is perfectly cacheable. The patch will still leave the function set_interrupts(). A follow up patch takes care of it, when cleaning up the INT enable register variable. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345.h | 4 ++ drivers/iio/accel/adxl345_core.c | 64 ++++++++++++++++++++------------ drivers/iio/accel/adxl345_i2c.c | 2 + drivers/iio/accel/adxl345_spi.c | 2 + 4 files changed, 49 insertions(+), 23 deletions(-) diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h index bc6d634bd85c..7d482dd595fa 100644 --- a/drivers/iio/accel/adxl345.h +++ b/drivers/iio/accel/adxl345.h @@ -111,6 +111,10 @@ */ #define ADXL375_USCALE 480000 +struct regmap; + +bool adxl345_is_volatile_reg(struct device *dev, unsigned int reg); + struct adxl345_chip_info { const char *name; int uscale; diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 22c5a9c08459..6f337b26999a 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,7 +36,6 @@ struct adxl345_state { struct regmap *regmap; bool fifo_delay; /* delay: delay is needed for SPI */ int irq; - u8 intio; u8 int_map; u8 watermark; u8 fifo_mode; @@ -76,6 +75,25 @@ static const unsigned long adxl345_scan_masks[] = { 0 }; +bool adxl345_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ADXL345_REG_DATA_AXIS(0): + case ADXL345_REG_DATA_AXIS(1): + case ADXL345_REG_DATA_AXIS(2): + case ADXL345_REG_DATA_AXIS(3): + case ADXL345_REG_DATA_AXIS(4): + case ADXL345_REG_DATA_AXIS(5): + case ADXL345_REG_ACT_TAP_STATUS: + case ADXL345_REG_FIFO_STATUS: + case ADXL345_REG_INT_SOURCE: + return true; + default: + return false; + } +} +EXPORT_SYMBOL_NS_GPL(adxl345_is_volatile_reg, "IIO_ADXL345"); + /** * adxl345_set_measure_en() - Enable and disable measuring. * @@ -98,22 +116,7 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) static int adxl345_set_interrupts(struct adxl345_state *st) { - int ret; - unsigned int int_enable = st->int_map; - unsigned int int_map; - - /* - * Any bits set to 0 in the INT map register send their respective - * interrupts to the INT1 pin, whereas bits set to 1 send their respective - * interrupts to the INT2 pin. The intio shall convert this accordingly. - */ - int_map = st->intio ? st->int_map : ~st->int_map; - - ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, int_map); - if (ret) - return ret; - - return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, int_enable); + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); } static int adxl345_read_raw(struct iio_dev *indio_dev, @@ -265,6 +268,7 @@ static const struct attribute_group adxl345_attrs_group = { static int adxl345_set_fifo(struct adxl345_state *st) { + unsigned int intio; int ret; /* FIFO should only be configured while in standby mode */ @@ -272,11 +276,14 @@ static int adxl345_set_fifo(struct adxl345_state *st) if (ret < 0) return ret; + ret = regmap_read(st->regmap, ADXL345_REG_INT_MAP, &intio); + if (ret) + return ret; + ret = regmap_write(st->regmap, ADXL345_REG_FIFO_CTL, FIELD_PREP(ADXL345_FIFO_CTL_SAMPLES_MSK, st->watermark) | - FIELD_PREP(ADXL345_FIFO_CTL_TRIGGER_MSK, - st->intio) | + FIELD_PREP(ADXL345_FIFO_CTL_TRIGGER_MSK, intio) | FIELD_PREP(ADXL345_FIFO_CTL_MODE_MSK, st->fifo_mode)); if (ret < 0) @@ -492,6 +499,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, struct adxl345_state *st; struct iio_dev *indio_dev; u32 regval; + u8 intio = ADXL345_INT1; unsigned int data_format_mask = (ADXL345_DATA_FORMAT_RANGE | ADXL345_DATA_FORMAT_JUSTIFY | ADXL345_DATA_FORMAT_FULL_RES | @@ -556,16 +564,26 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret < 0) return ret; - st->intio = ADXL345_INT1; st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1"); if (st->irq < 0) { - st->intio = ADXL345_INT2; + intio = ADXL345_INT2; st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2"); if (st->irq < 0) - st->intio = ADXL345_INT_NONE; + intio = ADXL345_INT_NONE; } - if (st->intio != ADXL345_INT_NONE) { + if (intio != ADXL345_INT_NONE) { + /* + * Any bits set to 0 in the INT map register send their respective + * interrupts to the INT1 pin, whereas bits set to 1 send their respective + * interrupts to the INT2 pin. The intio shall convert this accordingly. + */ + regval = intio ? 0xff : 0; + + ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, regval); + if (ret) + return ret; + /* FIFO_STREAM mode is going to be activated later */ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops); if (ret) diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c index eb3e0aadf51d..6ce567fd3ba6 100644 --- a/drivers/iio/accel/adxl345_i2c.c +++ b/drivers/iio/accel/adxl345_i2c.c @@ -17,6 +17,8 @@ static const struct regmap_config adxl345_i2c_regmap_config = { .reg_bits = 8, .val_bits = 8, + .volatile_reg = adxl345_is_volatile_reg, + .cache_type = REGCACHE_MAPLE, }; static int adxl345_i2c_probe(struct i2c_client *client) diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c index e03915ece8b6..200bdf975518 100644 --- a/drivers/iio/accel/adxl345_spi.c +++ b/drivers/iio/accel/adxl345_spi.c @@ -19,6 +19,8 @@ static const struct regmap_config adxl345_spi_regmap_config = { .val_bits = 8, /* Setting bits 7 and 6 enables multiple-byte read */ .read_flag_mask = BIT(7) | BIT(6), + .volatile_reg = adxl345_is_volatile_reg, + .cache_type = REGCACHE_MAPLE, }; static int adxl345_spi_setup(struct device *dev, struct regmap *regmap) From patchwork Thu Mar 13 16:50:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015484 Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1000D268FED; Thu, 13 Mar 2025 16:51:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884671; cv=none; b=frqn5ATEoZaivAMmrpkDmbNhcr52iYXAfIhlhZut7N2Vkzc/VyJv7nf7mRVBFyw+024TYrK9amQezPGSn12MqEnA+XTK+5IbBtsfrCFZqAd94yhm1Ivyya1M6BRp2y300QneST3/g6u3uZ3Eb9AAeJMjT6Wv5+Jh78ZZvafFAII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884671; c=relaxed/simple; bh=8MP0T+dQsXHgXL5ulZQRNSI8o6NFV2qYmgSyeuqIguo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cmeDeUkPMYmYx6cTaBCbVnfKtJIO60g0XrIgUU+VToJteVzPUa042JVOfz5AkRvuqzV5xC352+1oln1F4HKIYC3YqhmB8CV+t5erCY4oKdo50ctdJ6ccCk/iXa8N1Kmq7RBgYpLa/nMGRs58hfhWJUSKZ7IPlUta5u2nkQThAGM= 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=X21AYDh+; arc=none smtp.client-ip=209.85.218.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="X21AYDh+" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-ac250d158a8so17037466b.2; Thu, 13 Mar 2025 09:51:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884668; x=1742489468; 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=eFwVdVVwUhuklWAEWaQaMN6IvcWIhL+hcr37YQoJJjg=; b=X21AYDh++CzT88Lh5DM96cs/DBzTwcC+uL8Tf3PJwMG0I2FKzDviwCJB2XBDlaoCRl FgrmLslG9pzI+AkGpVKbqg+ZkCVK/PNB/o4OOnNzBmKbyl0xnQK3k/TDJLN5eIQwv4uk 6Y6/6cnQwnwYZqjKfz34RoPgfPu4CFOnEz+LRApT1Jauv7BlCfnhFfAgLB9hPm8if/v0 17gVXCrSErKLArHGEmZO0yGfTht4Af+KUFMAmiNYUBBtq7J9agnk5ddoK1n1ob/GB1ms Z4WR2PuRtWY1sekUJ+HsmkziGNtgn4SmAmicL0msVYEJqtC23/WOqff3zNX6v+/NzS2X sZFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884668; x=1742489468; 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=eFwVdVVwUhuklWAEWaQaMN6IvcWIhL+hcr37YQoJJjg=; b=iMMrNk4hbVULSpMcAON+B9KnhuIYJL4Ktg81F3QN9mOPCahdy568QsOnOCYCZhWUMj GEqUIqBvyJv9tN5D9hlo4WrbwZKlUL05SZ90Pf9vjCG/LEf7glCMfUbvACTnuzA/3gKA LChVI0kxP8YB7djgPbaJdEm/Xvtm24YE+d6NJHNIE6c/O1cl5k4cPUKMGqdjbt+TfReV W4MIg+G5pUxfrV+tDFcYqzC/aDYCrt8YBkTTF7FJtzutK1CA1Fn86sFBa1CC4WRfxg+F Qi8jGarmcm+Qj7IvZdyV1pOruU7CSK9o2vtl67ONEkKVEQAVI2B/X3tuF1fH4MJlis0V Q2Ow== X-Forwarded-Encrypted: i=1; AJvYcCXmYR00c6JSHqaKJlqpUJ6N67sW9+vtrjdaLdo4gkhhnDOkMDvGYrJLHWEseeT1c49JhvgFMDsW6uU372o=@vger.kernel.org X-Gm-Message-State: AOJu0YyiPFwtCOJQKScnK+8wmmlp5TaMXE0sck47m9NuB49/JsgOFNNf FA5MUmmycQx9Vcz4p1gZVWx+OnovT0rozVYgFzKhtXKiKpth9tPEgeb4v9AB X-Gm-Gg: ASbGncsRo5kSSqK8vrZ8AD8+XcFdtHl01qjKN4LUghOy0YEdCKcKgC+R33Wpn/nJ2OB fGkgKcDcyOsKYrSlQf2llvXk2u9yDK9LkxaQVjqT7uKKb7uLuzwsjx3nnWsKpEkhOqcVLLiH215 gRcga21MrPZBHo7gb9chyGsiPGLr6Emv/lDplaAIQ41lOQjH1HcAXm17EY/ZhXkL6uGd2todFo1 +TwLGQTPw7/qoSsyG8cqXJKuU5EkB+l2XDAOd+oD8rmTfOXFZKCbzujCZubBrpfpV+6bhqviklQ lqWRfDBrvYjju63YtRu/EhTFPjCSCMS0AlVR2Q0pk4p+W0TtcgakAyKtenrFETo7PbjcoQfJ9ID 377tEZ5Iqp1AV2U0xvOtN3Ao= X-Google-Smtp-Source: AGHT+IGqN3N58qGCdJYSRSVTs1vGRNIKtSeLmqI2x5AVaYMjqc7fWqymrdwSOe6j/wwJwODL2QiI1g== X-Received: by 2002:a17:907:1c9f:b0:ac2:6bf9:e386 with SMTP id a640c23a62f3a-ac2b9ea161emr669472266b.8.1741884668029; Thu, 13 Mar 2025 09:51:08 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:07 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 02/14] iio: accel: adxl345: move INT enable to regmap cache Date: Thu, 13 Mar 2025 16:50:37 +0000 Message-Id: <20250313165049.48305-3-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Replace the interrupt enable member variable to the regmap cache. This makes the function set_interrupts() obsolete. The interrupt enable register is written when the driver is probed. Thus it is perfectly cacheable. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 6f337b26999a..10e2da7de17e 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,7 +36,6 @@ struct adxl345_state { struct regmap *regmap; bool fifo_delay; /* delay: delay is needed for SPI */ int irq; - u8 int_map; u8 watermark; u8 fifo_mode; __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); @@ -114,11 +113,6 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); } -static int adxl345_set_interrupts(struct adxl345_state *st) -{ - return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, st->int_map); -} - static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -217,7 +211,7 @@ static int adxl345_reg_access(struct iio_dev *indio_dev, unsigned int reg, static int adxl345_set_watermark(struct iio_dev *indio_dev, unsigned int value) { struct adxl345_state *st = iio_priv(indio_dev); - unsigned int fifo_mask = 0x1F; + const unsigned int fifo_mask = 0x1F, watermark_mask = 0x02; int ret; value = min(value, ADXL345_FIFO_SIZE - 1); @@ -227,7 +221,10 @@ static int adxl345_set_watermark(struct iio_dev *indio_dev, unsigned int value) return ret; st->watermark = value; - st->int_map |= ADXL345_INT_WATERMARK; + ret = regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, watermark_mask, + ADXL345_INT_WATERMARK); + if (ret) + return ret; return 0; } @@ -381,11 +378,6 @@ static void adxl345_fifo_reset(struct adxl345_state *st) static int adxl345_buffer_postenable(struct iio_dev *indio_dev) { struct adxl345_state *st = iio_priv(indio_dev); - int ret; - - ret = adxl345_set_interrupts(st); - if (ret < 0) - return ret; st->fifo_mode = ADXL345_FIFO_STREAM; return adxl345_set_fifo(st); @@ -401,8 +393,7 @@ static int adxl345_buffer_predisable(struct iio_dev *indio_dev) if (ret < 0) return ret; - st->int_map = 0x00; - return adxl345_set_interrupts(st); + return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); } static const struct iio_buffer_setup_ops adxl345_buffer_ops = { @@ -524,6 +515,11 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, indio_dev->num_channels = ARRAY_SIZE(adxl345_channels); indio_dev->available_scan_masks = adxl345_scan_masks; + /* Reset interrupts at start up */ + ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); + if (ret) + return ret; + if (setup) { /* Perform optional initial bus specific configuration */ ret = setup(dev, st->regmap); From patchwork Thu Mar 13 16:50:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015485 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 D83B3269B1C; Thu, 13 Mar 2025 16:51:10 +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=1741884672; cv=none; b=adTNB1lfXRAD3Id0MvHvuQJ2F+iDLnDy5dF/lwtPftu9mUOJIrpu44m7eCPIAZsSHj+XLQwchi9GW30zE1P4RjZu2Bu4RGHQjCfcKpNIffvd2lspsWCHWzwI+ccSTdzpCv0FLvFOngv5n1gYpr1iWACHygZRnccCPaLv4K+O26k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884672; c=relaxed/simple; bh=u9G/VADTODvU6o35fILx3AL9lup03EwPP9DMGouxYpg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ohay+1o6HlpRN18XIh66ZgswNOJN5aVVPpFDRl+Ba8mbM6k9OCWLlF0ilNYzuNjAd2AFdmnkbyw9YRPds865YwsMa612MAM8ULxI8CEMVF1MKAnw/xkY9GzHO0epRNBdeCIRVyRM+0eu5rna9hyWg/Zn7ZvHNtbKbwbhLhqvxXM= 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=TzEOZXzD; 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="TzEOZXzD" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-ac250d158a8so17037866b.2; Thu, 13 Mar 2025 09:51:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884669; x=1742489469; 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=3DqhiJj9lWqqTYxoYhDZchLg7FS/oUyFT1jb7mKGMjw=; b=TzEOZXzDaIuQgOA/FXrylaUhsJKjSMTy9nOAb+OuS1vhA1nEhYspL4ZoITYPzYH+E2 whcme6ziceuA98TnlptbWzssV08/sSIaexsYxgno/83715Kdk5kCE5hyAa2iQBIrUN1+ lIpet59jNFg7hDqv+n3R6Igh2YXHl0UIkzy82uAxFtPKppqXtwYG9bSa8NyT8Qy5clMp 3MRQDMAmwmotIqVNYPSpoX3jAjkw6fIFRxzJSrDC0yknjHq1KbbpF9PQ7dGs0WgBTriP cjdX6FaS2BZA3z+HUso24WCAjyVOutTPN3Dx7SqD0541QLHzJMmsYmqviQC46ZgPOcEp AtXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884669; x=1742489469; 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=3DqhiJj9lWqqTYxoYhDZchLg7FS/oUyFT1jb7mKGMjw=; b=PvBUIJ/iOqNWwWLkPX096WV5Tv8Ksvxa+t0JxFNfiFh22QwXguw6bIS1nrhIzygD+z Gw2zuMSEuNkHp4dYIUNMwtDEu0EZgNKkbfWyDhr2zAoytI+iE6mA3lNK9Z2fhmHDbmRk iYqG8mW0SoBTJOm/luZEzgy9cJhJXRdAHOtt8MbpGrSG4kaZDAj3Zzs/+Vgz5YHpOTR8 dy+R/hQSQCVx4f6dtAJviGCJjmts6jhI/WwgFTi+E/UZB6NKIik3IB2OzIDddFsh1eAt Ye1duLtsO1Vizsrjn0EnRWqkpJTMOE24Vk2SmLNpZlgA4EW0GjCYaNJ3OKQ4hWvBINIk Eqcg== X-Forwarded-Encrypted: i=1; AJvYcCWdYLLu+is+cZGg3nGPtEAw+gutqp8bQ2Lf4N1KaZ0oPhyJL04OZM1r8vzKsHHfTOdfgR4YwLBbxpqYNsM=@vger.kernel.org X-Gm-Message-State: AOJu0YyQZsRe32r+F0SJp+IlvRrHsQgPp629c4F2tCDe09RPB5P2HbEd tSJxrf6Kwn65GH0xcrN2OC6iGFkrNE9JXB79GErKu9hkESlxkJ73 X-Gm-Gg: ASbGncsyacAPW6zECVxOB8WoTG/QpefbikY7LfqQqhpmB3cGePr3Gj+Enk/A/vn2vaL kSdGO7LSbm5ikcMmf+P4nm6zM22158QYyocI/EcxRuP1auw0KwT4za9xUU4tFG5SmkDac84J3mH 6hHTy6wa5P6gXav4M/Bw/8uQzgeI8Sr8bf4LFFX1NMNmgjHZ1jsbUtyirC45JuzjIRg0yWouepM aq2CoLYrEgUoUw3PgcK2Qxqhk7LzU33FnTNEYCtjxcTJNRT8hbsxfBf76rtf11decGlQCczUg6s urx3YHJ7Ft6OpSlYnI0kvuIkK67xxEeCM/ro0AzlxVK5HWD07d0mRQjb0vYsQHrtQtIYnnTnhJL Nq9x9i7/8cYNy523z/1i/wOE7fLPObNKr6g== X-Google-Smtp-Source: AGHT+IHZVM76uhneXgTV5Vj4H7et8O5mdc7ynEHne1EuR7N2avQZ5Zrp1UZDw9VYpLDiSBl85E2CjA== X-Received: by 2002:a17:906:7311:b0:abf:6f87:6730 with SMTP id a640c23a62f3a-ac2b9de959fmr607932766b.5.1741884668925; Thu, 13 Mar 2025 09:51:08 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:08 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 03/14] iio: accel: adxl345: cleanup regmap return values Date: Thu, 13 Mar 2025 16:50:38 +0000 Message-Id: <20250313165049.48305-4-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Regmap return values sometimes are checked being less than zero to trigger error handling. Sometimes this is checked for being not zero. Unify the situation and check for not being zero. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 10e2da7de17e..eec3f0e17e1e 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -133,7 +133,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, ret = regmap_bulk_read(st->regmap, ADXL345_REG_DATA_AXIS(chan->address), &accel, sizeof(accel)); - if (ret < 0) + if (ret) return ret; *val = sign_extend32(le16_to_cpu(accel), 12); @@ -145,7 +145,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: ret = regmap_read(st->regmap, ADXL345_REG_OFS_AXIS(chan->address), ®val); - if (ret < 0) + if (ret) return ret; /* * 8-bit resolution at +/- 2g, that is 4x accel data scale @@ -156,7 +156,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ: ret = regmap_read(st->regmap, ADXL345_REG_BW_RATE, ®val); - if (ret < 0) + if (ret) return ret; samp_freq_nhz = ADXL345_BASE_RATE_NANO_HZ << @@ -270,7 +270,7 @@ static int adxl345_set_fifo(struct adxl345_state *st) /* FIFO should only be configured while in standby mode */ ret = adxl345_set_measure_en(st, false); - if (ret < 0) + if (ret) return ret; ret = regmap_read(st->regmap, ADXL345_REG_INT_MAP, &intio); @@ -283,7 +283,7 @@ static int adxl345_set_fifo(struct adxl345_state *st) FIELD_PREP(ADXL345_FIFO_CTL_TRIGGER_MSK, intio) | FIELD_PREP(ADXL345_FIFO_CTL_MODE_MSK, st->fifo_mode)); - if (ret < 0) + if (ret) return ret; return adxl345_set_measure_en(st, true); @@ -304,7 +304,7 @@ static int adxl345_get_samples(struct adxl345_state *st) int ret; ret = regmap_read(st->regmap, ADXL345_REG_FIFO_STATUS, ®val); - if (ret < 0) + if (ret) return ret; return FIELD_GET(ADXL345_REG_FIFO_STATUS_MSK, regval); @@ -332,7 +332,7 @@ static int adxl345_fifo_transfer(struct adxl345_state *st, int samples) /* read 3x 2 byte elements from base address into next fifo_buf position */ ret = regmap_bulk_read(st->regmap, ADXL345_REG_XYZ_BASE, st->fifo_buf + (i * count / 2), count); - if (ret < 0) + if (ret) return ret; /* @@ -390,7 +390,7 @@ static int adxl345_buffer_predisable(struct iio_dev *indio_dev) st->fifo_mode = ADXL345_FIFO_BYPASS; ret = adxl345_set_fifo(st); - if (ret < 0) + if (ret) return ret; return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); @@ -544,7 +544,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, } ret = regmap_read(st->regmap, ADXL345_REG_DEVID, ®val); - if (ret < 0) + if (ret) return dev_err_probe(dev, ret, "Error reading device ID\n"); if (regval != ADXL345_DEVID) @@ -553,11 +553,11 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, /* Enable measurement mode */ ret = adxl345_set_measure_en(st, true); - if (ret < 0) + if (ret) return dev_err_probe(dev, ret, "Failed to enable measurement mode\n"); ret = devm_add_action_or_reset(dev, adxl345_powerdown, st); - if (ret < 0) + if (ret) return ret; st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1"); @@ -595,7 +595,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, ret = regmap_write(st->regmap, ADXL345_REG_FIFO_CTL, FIELD_PREP(ADXL345_FIFO_CTL_MODE_MSK, ADXL345_FIFO_BYPASS)); - if (ret < 0) + if (ret) return ret; } From patchwork Thu Mar 13 16:50:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015486 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 ACA0426A091; Thu, 13 Mar 2025 16:51:11 +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=1741884673; cv=none; b=dG7NBp0oCGwCV6/Yg0fv1KSebwUsF9w02ApsF8icLBgXXRiwyGibZD9vP2Z3xbG9Qt0qxte+VJzGvKlWNpxyDBW84JUlpyrF0T1WkDiVWFMKwUYQADxdxmdhBjEtGB66QxegfmWbz1eSPT/F2nEGmwowZeTSzHjrXbLp2nB/txk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884673; c=relaxed/simple; bh=7Qu6SZ6XREm+6RZDbRGSt55eora3SguJtLGZwWkGwSo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ops8nuuK361y2PMDpJBI+nSc1BMizeqKYI53NoYReDt8QPPdV3s+AfGB9bgT6MNRPrSIMbdghf07+5nSbAlut48Ryf4WUuPuhAgAulcG62bveevCAZ9QCU97zfvktNjnJRLT4+qQUZMFA03DybfkdlTSZH261bNEWche9GzVX5A= 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=ENkyIL0B; 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="ENkyIL0B" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ac250d158a8so17038466b.2; Thu, 13 Mar 2025 09:51:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884670; x=1742489470; 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=kObAZCecIufgb8lKjH8UqZ2pqy/jGsTdnhjnK9Ujr8I=; b=ENkyIL0B94k4YWE/RiCVJSPY2+9374zVghUHqdhKqruvp/t4B3FdhQuPHDH+rt6lil 3hpCQhSNZeqDVwkOKTDIUmSVbFQB4O0wWMYmC0p3yVZPEcuPtX/16Y2u9pzMBqQp2tkz 3yYKyxFD8kGG89WACsE8bheEZVbUnSjfkmQn8oplO5OtvmLM5RnrVTWu6P5MRSysewoM bLOiPLoHzsBk3ICog+B5YGcH+R8R3u1q+blziH+VTr7lQ9tmAI7ySTm7KeHZcSepClaP x6So1rbvY4ph6rEHQWa451Twep+OD8gjeCqycTxwpM3PIywd8mmTYmpAmV7fsdIosXWB J+4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884670; x=1742489470; 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=kObAZCecIufgb8lKjH8UqZ2pqy/jGsTdnhjnK9Ujr8I=; b=Mjlxgolhoch7p7zryNObMPbaCOMHJ1nT6/NC9Rx3zdaDAPuZdaD5BqOEaNUsRG8iHn tRLX8KsqpkeyQY2v0Z4ZyIGGakCcFBht9XmGTxoyai0/ycjGDoXrybkcYhPVwtlKMwsU YptfievwfxfLor48PntDuX5LxjwQu8HgBHjrnmM8BLnrkGPBsdHu3eOwQK5LM+OPtZyX wLLhFKo4kqO+Zm7wev+4OWon68earOGtTgFJWl3Eo9sFdmm6DwyxVE5IDF8moilgNuI4 K3NYEAskxzwaCvisH6UZbIJD4ptpyftZOOKq52bPXo4f8bf+diPBg+VRDLP5QAeXZ7wc ivYA== X-Forwarded-Encrypted: i=1; AJvYcCVAAbsLicIzHrYSgR5y/g3FGYLjzKS1egK7y7s3pOEhqbfVmWU9uDs60AOjTg4G/lN3+FuLpcA5FRVJCUA=@vger.kernel.org X-Gm-Message-State: AOJu0YwazDXsVrE0tdLmvQzSdQ7dN6LrSfnuktj59lmxyohNpPT+Shdg Caxx3XPZHopifqOOvkcTmf4fX4wj/MgEF47ENgxQ2IoaQdl/m+aj X-Gm-Gg: ASbGnct6q2wf2L/kq1GJ9pqFNv3I0wjCChv60IkZi120M9f2In9Hm9qBAom6lSEwogz 2tz7FE3LlJaVPN/S8PrRx8Of5kUEEc3kIPkSURcCh909XE13oVjX+TKsUir5lfFx1jpdA6oXF09 nU2kk6TglxCKXQuzaEMf9S1xSEtSeMdle8xxPO2XclYERDBmdKcdcLCHVkqmk0m6ba/cfUkP4KK WDhM6xUs01h7cExqf+b73Va2IEo8J6DpXstPXmaON/XVALPH2N86nw7GL8WbLfUriGQnC5aSCiN osIP4ok7stNb9c/PrubF5Fnipx9QjkIZeT2Vm8E4+A+haLzLP1Q4YXfYZXEo4pMyaJp4+W+DM1Y n/E9F3F2olXo02jZeEhmBSgk= X-Google-Smtp-Source: AGHT+IGMJe34PpQDvk/nscO0lijzrMROzv1dCtGiunTHz6QfD7rwjm1M6Fdf3soxh1I2CJlG2UT9Gw== X-Received: by 2002:a17:907:7e88:b0:abb:eec3:3937 with SMTP id a640c23a62f3a-ac2b9ea1613mr604191766b.10.1741884669814; Thu, 13 Mar 2025 09:51:09 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:09 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 04/14] iio: accel: adxl345: introduce adxl345_push_event function Date: Thu, 13 Mar 2025 16:50:39 +0000 Message-Id: <20250313165049.48305-5-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Move the fifo handling into a separate function. This is a preparation for a generic handling of the interrupt status register results. The interrupt status register is read into a variable int_stat. It carries status for various sensor events, handling of which is added in follow up patches. Evaluation of the int_stat variable is common for sensor events, such as tap detection, freefall, activity,... and for fifo events, such as data ready, overrun, watermark,... Also, dealing with in case error returns shall be common to all events. Thus migrate fifo read-out and push fifo content to iio channels into this function to be built up with additional event handling. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index eec3f0e17e1e..d4c1a6f1559f 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -420,6 +420,24 @@ static int adxl345_fifo_push(struct iio_dev *indio_dev, return 0; } +static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat) +{ + struct adxl345_state *st = iio_priv(indio_dev); + int samples; + int ret = -ENOENT; + + if (FIELD_GET(ADXL345_INT_WATERMARK, int_stat)) { + samples = adxl345_get_samples(st); + if (samples < 0) + return -EINVAL; + + if (adxl345_fifo_push(indio_dev, samples) < 0) + return -EINVAL; + } + + return ret; +} + /** * adxl345_irq_handler() - Handle irqs of the ADXL345. * @irq: The irq being handled. @@ -432,19 +450,12 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) struct iio_dev *indio_dev = p; struct adxl345_state *st = iio_priv(indio_dev); int int_stat; - int samples; if (regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &int_stat)) return IRQ_NONE; - if (FIELD_GET(ADXL345_INT_WATERMARK, int_stat)) { - samples = adxl345_get_samples(st); - if (samples < 0) - goto err; - - if (adxl345_fifo_push(indio_dev, samples) < 0) - goto err; - } + if (adxl345_push_event(indio_dev, int_stat)) + goto err; if (FIELD_GET(ADXL345_INT_OVERRUN, int_stat)) goto err; From patchwork Thu Mar 13 16:50:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015489 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A5F926A0C2; Thu, 13 Mar 2025 16:51:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884674; cv=none; b=sFc4loBUnvNCkUm4viAcZ96nBTnmNkT/iOazNBmxSdmXC2pXBq6qu76DT7OSzydDwc181aejmPUt+SA8pF1T+YIHIb4llAt4MMHYHCqM5VF+4++6XAuIZB3ZyKg/n+sKacbSwpsNEoVz7sv4gTYbaZeYM+qfB2k/UcUPZqZH1t8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884674; c=relaxed/simple; bh=QgqMeqY151R37Xn33mmJXxb+T/mKP9tSXa4JzJmERq4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZYNGiJGKq2LtPvOFtYmWQV/GPnjvMzSfqNBjLBXkHwTz1ZKNZa1Qfcx6HxTCGY6wa3bhknnJwguZXs5cKhwhbUPQYdMIVsTNA4by1G0e35TFicc5632T3Nj9yXayVitNMNGwIvOjHjDAtbwMwcI0vfn0tolsl1tO09HYTF1tosE= 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=jsbpgs8v; arc=none smtp.client-ip=209.85.218.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jsbpgs8v" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-ac2b8830e2cso16108366b.3; Thu, 13 Mar 2025 09:51:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884671; x=1742489471; 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=LGOpTdRW0Q3gb1VXbKTFRbHBrcj+A0FRnb4cFjcTKX8=; b=jsbpgs8vWowRrfAzowXBp90AdfQgFEZfhu2pWWBGA+Hodlza05MS4G+NR0CzKn9lQQ qaJ9Xf5CofHLoa6W7cIY/IspjVmlMs6EhRET+DjNdVpTUyAAqxDSe5JvxV8r1b4wEwBz ZA2652pGKV1JG0JOxbM+20t+7YTobpjISsHZZ1Dq81JSTKlymraiM2KQWqh9s6p91F8p 97A7k5TtHRQtd4znlPCpsqgtvxsTyD4KmBogvzj6HhCSksqVi4rZr7AR+qxf3D9PXuyE fVEWi88Nc9FWxx3Xw0Y51NTMwlSHiYPcvGDLQPPHZ1jG6F0TNT02oQKmXpOUlvb6NTay qOug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884671; x=1742489471; 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=LGOpTdRW0Q3gb1VXbKTFRbHBrcj+A0FRnb4cFjcTKX8=; b=Sz1Rrp+LwGfhXZ2z8pTupjwJnB4L5sD8YZicccvP1AIzbT1ng2cuOVNK1r9xYk9IOh GyZxoEBCPnWmzvQzF75zJLx/x6CtdyUaCHueJ1kyYtlyZF/4FoqULnvWOAmKfHo8YnW+ oFjZYTo8fgfKRQgDKKULefOK3B2w5F0ntIeZF8Sqfqbrh138D+ln9nxASyJZyKRfd6VO WReAMa8L1asTcJtIPbZs7adAlOdLcj1rvqdJmYPCu66u4HutP6qkiyb/+w0ck0aJtve/ qvv8h7UZdKB9SFX4R3gNyYEJ+oVRoLqizpWJU5DOQ4fptfG5hXfTV38WzkUNjEtcv1+m sf0g== X-Forwarded-Encrypted: i=1; AJvYcCWQE3lPNU4LdXsOBw9LITtj1DGaciULgUltJcDmjtEln27+ifO0NXvome/KsFC4tN0EDAEBb1hG/UwhJkw=@vger.kernel.org X-Gm-Message-State: AOJu0YwzhDQQIMY06InS7ELWIvfi416wYfePsoA5GQ83VRhlnbvdYByy 9hFZbUJRWPbLRhFSpRZJE1A9SZmwfei5Eohd71CFxdgnnjLYu3MA X-Gm-Gg: ASbGnctXH6CdWB9UddnUsiavkRG4NerC2dy0D7enSkEO1/dSp8AEL3KPIgmz2lot92v aqjxLhQxFdYRKWKMHSi6My1406j0X27gyKccNXvg7Xh3pN2FB2v6SVbzl0gS7nZnQv4vyMO7Ghy WgziJCGDNLZTQXrFog+D1P8fGEFb9qupxhYv8cIOqKTiCwAk3wPryAYo5nQeB0pfOa6p7lRoZfg dAqUKjw3gkolnWSP8W2yzhtSclieIYT/MMMRBk01CxSrX+VaI1V3oGoqUDlqoH43MfgDJsCSHvL Sm7J/oxtxJusHlY/EtmJfe1nJgVJbc93El2JmOzGBqPM9OODZWtZ1Y2ucRTgtkLYhamvf4iMXvX 9Vm2Zi7L0L8kE6xM9EnP6dyI= X-Google-Smtp-Source: AGHT+IGwAYsC0/CdwRncTxTWBMndokx47ws+obU0oaAF5IbO0nCc/Nil4NTvVTzzoL9XXBcirSQ3dA== X-Received: by 2002:a17:907:9689:b0:ac1:e752:17be with SMTP id a640c23a62f3a-ac2b9c75ea7mr657600266b.1.1741884670724; Thu, 13 Mar 2025 09:51:10 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:10 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 05/14] iio: accel: adxl345: add single tap feature Date: Thu, 13 Mar 2025 16:50:40 +0000 Message-Id: <20250313165049.48305-6-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the single tap feature with a threshold in 62.5mg/LSB points and a scaled duration in us. Keep singletap threshold in regmap cache but the scaled value of duration in us as member variable. Both use IIO channels for individual enable of the x/y/z axis. Initializes threshold and duration with reasonable content. When an interrupt is caught it will be pushed to the according IIO channel. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 365 ++++++++++++++++++++++++++++++- 1 file changed, 363 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index d4c1a6f1559f..cfdbc73c96b4 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include "adxl345.h" @@ -31,6 +33,33 @@ #define ADXL345_INT1 0 #define ADXL345_INT2 1 +#define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) + +enum adxl345_axis { + ADXL345_Z_EN = BIT(0), + ADXL345_Y_EN = BIT(1), + ADXL345_X_EN = BIT(2), + /* Suppress double tap detection if value > tap threshold */ + ADXL345_TAP_SUPPRESS = BIT(3), +}; + +/* single/double tap */ +enum adxl345_tap_type { + ADXL345_SINGLE_TAP, +}; + +static const unsigned int adxl345_tap_int_reg[] = { + [ADXL345_SINGLE_TAP] = ADXL345_INT_SINGLE_TAP, +}; + +enum adxl345_tap_time_type { + ADXL345_TAP_TIME_DUR, +}; + +static const unsigned int adxl345_tap_time_reg[] = { + [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, +}; + struct adxl345_state { const struct adxl345_chip_info *info; struct regmap *regmap; @@ -38,9 +67,23 @@ struct adxl345_state { int irq; u8 watermark; u8 fifo_mode; + + u32 tap_duration_us; + __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; +static struct iio_event_spec adxl345_events[] = { + { + /* single tap */ + .type = IIO_EV_TYPE_GESTURE, + .dir = IIO_EV_DIR_SINGLETAP, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_TIMEOUT), + }, +}; + #define ADXL345_CHANNEL(index, reg, axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ @@ -57,6 +100,8 @@ struct adxl345_state { .storagebits = 16, \ .endianness = IIO_LE, \ }, \ + .event_spec = adxl345_events, \ + .num_event_specs = ARRAY_SIZE(adxl345_events), \ } enum adxl345_chans { @@ -113,6 +158,150 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); } +/* tap */ + +static int _adxl345_set_tap_int(struct adxl345_state *st, + enum adxl345_tap_type type, bool state) +{ + unsigned int int_map = 0x00; + unsigned int tap_threshold; + bool axis_valid; + bool singletap_args_valid = false; + bool en = false; + u32 tap_axis_ctrl; + int ret; + + ret = regmap_read(st->regmap, ADXL345_REG_TAP_AXIS, &tap_axis_ctrl); + if (ret) + return ret; + + axis_valid = FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, tap_axis_ctrl) > 0; + + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_TAP, &tap_threshold); + if (ret) + return ret; + + /* + * Note: A value of 0 for threshold and/or dur may result in undesirable + * behavior if single tap/double tap interrupts are enabled. + */ + singletap_args_valid = tap_threshold > 0 && st->tap_duration_us > 0; + + if (type == ADXL345_SINGLE_TAP) + en = axis_valid && singletap_args_valid; + + if (state && en) + int_map |= adxl345_tap_int_reg[type]; + + return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + adxl345_tap_int_reg[type], int_map); +} + +static int adxl345_is_tap_en(struct adxl345_state *st, + enum iio_modifier axis, + enum adxl345_tap_type type, bool *en) +{ + unsigned int regval; + bool axis_en; + u32 axis_ctrl; + int ret; + + ret = regmap_read(st->regmap, ADXL345_REG_TAP_AXIS, &axis_ctrl); + if (ret) + return ret; + + switch (axis) { + case IIO_MOD_X: + axis_en = FIELD_GET(ADXL345_X_EN, axis_ctrl); + break; + case IIO_MOD_Y: + axis_en = FIELD_GET(ADXL345_Y_EN, axis_ctrl); + break; + case IIO_MOD_Z: + axis_en = FIELD_GET(ADXL345_Z_EN, axis_ctrl); + break; + default: + return -EINVAL; + } + + ret = regmap_read(st->regmap, ADXL345_REG_INT_ENABLE, ®val); + if (ret) + return ret; + + *en = (adxl345_tap_int_reg[type] & regval) > 0; + + return 0; +} + +static int adxl345_set_singletap_en(struct adxl345_state *st, + enum iio_modifier axis, bool en) +{ + int ret; + enum adxl345_axis axis_ctrl; + + switch (axis) { + case IIO_MOD_X: + axis_ctrl = ADXL345_X_EN; + break; + case IIO_MOD_Y: + axis_ctrl = ADXL345_Y_EN; + break; + case IIO_MOD_Z: + axis_ctrl = ADXL345_Z_EN; + break; + default: + return -EINVAL; + } + + if (en) + ret = regmap_set_bits(st->regmap, ADXL345_REG_TAP_AXIS, + axis_ctrl); + else + ret = regmap_clear_bits(st->regmap, ADXL345_REG_TAP_AXIS, + axis_ctrl); + if (ret) + return ret; + + return _adxl345_set_tap_int(st, ADXL345_SINGLE_TAP, en); +} + +static int _adxl345_set_tap_time(struct adxl345_state *st, + enum adxl345_tap_time_type type, u32 val_us) +{ + unsigned int regval; + + switch (type) { + case ADXL345_TAP_TIME_DUR: + st->tap_duration_us = val_us; + break; + } + + /* + * The scale factor is 1250us / LSB for tap_window_us and tap_latent_us. + * For tap_duration_us the scale factor is 625us / LSB. + */ + if (type == ADXL345_TAP_TIME_DUR) + regval = DIV_ROUND_CLOSEST(val_us, 625); + else + regval = DIV_ROUND_CLOSEST(val_us, 1250); + + return regmap_write(st->regmap, adxl345_tap_time_reg[type], regval); +} + +static int adxl345_set_tap_duration(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + /* + * Max value is 255 * 625 us = 0.159375 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (val_int || val_fract_us > 159375) + return -EINVAL; + + return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_DUR, val_fract_us); +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -198,6 +387,132 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, return -EINVAL; } +static int adxl345_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct adxl345_state *st = iio_priv(indio_dev); + bool int_en; + int ret = -EFAULT; + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (dir) { + case IIO_EV_DIR_SINGLETAP: + ret = adxl345_is_tap_en(st, chan->channel2, + ADXL345_SINGLE_TAP, &int_en); + if (ret) + return ret; + return int_en; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl345_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + int state) +{ + struct adxl345_state *st = iio_priv(indio_dev); + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (dir) { + case IIO_EV_DIR_SINGLETAP: + return adxl345_set_singletap_en(st, chan->channel2, state); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl345_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + struct adxl345_state *st = iio_priv(indio_dev); + unsigned int tap_threshold; + int ret; + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (info) { + case IIO_EV_INFO_VALUE: + /* + * The scale factor would be 62.5mg/LSB (i.e. 0xFF = 16g) but + * not applied here. In context of this general purpose sensor, + * what imports is rather signal intensity than the absolute + * measured g value. + */ + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_TAP, + &tap_threshold); + if (ret) + return ret; + *val = sign_extend32(tap_threshold, 7); + return IIO_VAL_INT; + case IIO_EV_INFO_TIMEOUT: + *val = st->tap_duration_us; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int adxl345_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + struct adxl345_state *st = iio_priv(indio_dev); + int ret; + + ret = adxl345_set_measure_en(st, false); + if (ret) + return ret; + + switch (type) { + case IIO_EV_TYPE_GESTURE: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_TAP, + min(val, 0xFF)); + break; + case IIO_EV_INFO_TIMEOUT: + ret = adxl345_set_tap_duration(st, val, val2); + break; + default: + ret = -EINVAL; + break; + } + break; + default: + ret = -EINVAL; + break; + } + + if (ret) + return ret; /* measurement stays off */ + + return adxl345_set_measure_en(st, true); +} + static int adxl345_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, unsigned int *readval) { @@ -420,12 +735,24 @@ static int adxl345_fifo_push(struct iio_dev *indio_dev, return 0; } -static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat) +static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, + enum iio_modifier tap_dir) { + s64 ts = iio_get_time_ns(indio_dev); struct adxl345_state *st = iio_priv(indio_dev); int samples; int ret = -ENOENT; + if (FIELD_GET(ADXL345_INT_SINGLE_TAP, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, tap_dir, + IIO_EV_TYPE_GESTURE, + IIO_EV_DIR_SINGLETAP), + ts); + if (ret) + return ret; + } + if (FIELD_GET(ADXL345_INT_WATERMARK, int_stat)) { samples = adxl345_get_samples(st); if (samples < 0) @@ -449,12 +776,33 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) { struct iio_dev *indio_dev = p; struct adxl345_state *st = iio_priv(indio_dev); + unsigned int regval; + enum iio_modifier tap_dir = IIO_NO_MOD; + u32 axis_ctrl; int int_stat; + int ret; + + ret = regmap_read(st->regmap, ADXL345_REG_TAP_AXIS, &axis_ctrl); + if (ret) + return IRQ_NONE; + + if (FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, axis_ctrl)) { + ret = regmap_read(st->regmap, ADXL345_REG_ACT_TAP_STATUS, ®val); + if (ret) + return IRQ_NONE; + + if (FIELD_GET(ADXL345_Z_EN, regval)) + tap_dir = IIO_MOD_Z; + else if (FIELD_GET(ADXL345_Y_EN, regval)) + tap_dir = IIO_MOD_Y; + else if (FIELD_GET(ADXL345_X_EN, regval)) + tap_dir = IIO_MOD_X; + } if (regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &int_stat)) return IRQ_NONE; - if (adxl345_push_event(indio_dev, int_stat)) + if (adxl345_push_event(indio_dev, int_stat, tap_dir)) goto err; if (FIELD_GET(ADXL345_INT_OVERRUN, int_stat)) @@ -473,6 +821,10 @@ static const struct iio_info adxl345_info = { .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, .write_raw_get_fmt = adxl345_write_raw_get_fmt, + .read_event_config = adxl345_read_event_config, + .write_event_config = adxl345_write_event_config, + .read_event_value = adxl345_read_event_value, + .write_event_value = adxl345_write_event_value, .debugfs_reg_access = &adxl345_reg_access, .hwfifo_set_watermark = adxl345_set_watermark, }; @@ -506,6 +858,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, ADXL345_DATA_FORMAT_JUSTIFY | ADXL345_DATA_FORMAT_FULL_RES | ADXL345_DATA_FORMAT_SELF_TEST); + unsigned int tap_threshold; int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); @@ -519,6 +872,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, return -ENODEV; st->fifo_delay = fifo_delay_default; + /* Init with reasonable values */ + tap_threshold = 48; /* 48 [0x30] -> ~3g */ + st->tap_duration_us = 16; /* 16 [0x10] -> .010 */ + indio_dev->name = st->info->name; indio_dev->info = &adxl345_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -591,6 +948,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_TAP, tap_threshold); + if (ret) + return ret; + /* FIFO_STREAM mode is going to be activated later */ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops); if (ret) From patchwork Thu Mar 13 16:50:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015490 Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65CF7126C03; Thu, 13 Mar 2025 16:51:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884675; cv=none; b=nJUC9OwaATb4LDOBilBR6aRyD0cbLfUOWQKPCD0oCKomhVCkFk/thacNgVQzMyiLUx7oHJpMPmTXjm9zogOJ4onAuyN08zDVKKrF8+iJ9HqrpFdI3E4sb2ztieEBsJZBSQHsPDHDqtKL+3whp3KJZwEjVN4hA2ZPC+CVINocKi8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884675; c=relaxed/simple; bh=9tXKDE1CnBDmZcG9vK7Y9pAUYZggjYpbTEVRUGfvE+k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bKe2NyID8Y4S8H0iVIuR2BAv2CbuA0CsbqCiBtzzGPxdvpcy0U2qd9TZytTTuXG6dpNkeI4fv0sHdWjyg8hgUiokfSM21ptebINmrggv9VzRMZkJme1BVCIRLdEfz/YVZ/peG/o2WCZSHAoaq6EwPi4YZ9An7tqxcSJRclsWtkk= 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=gPYpQIDe; arc=none smtp.client-ip=209.85.218.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gPYpQIDe" Received: by mail-ej1-f44.google.com with SMTP id a640c23a62f3a-ac30d4ee128so10461966b.0; Thu, 13 Mar 2025 09:51:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884672; x=1742489472; 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=QMmC1rvIEkXaWS15upxpWMXmGh0jkxNvxi3wjmpL1yE=; b=gPYpQIDeGzNkH9CWb/YhMppAm3GpEWwIOJVvbkpycjolgPcdQ4LwOUspNZSJAZgKq6 auRu5lcAGV9p6KNW8uM6brKXHhH4sFqgNpb2vj5xXK5W9+Z9xcAbTndXFoX8UGDN1d8Q ZM+JWPsrzboPcNb7MY/rJMrSoNhvkga4Zxer79iECZiInf0sf6pgAfEdWzIYEtZN8Ekj dhKA9Xve/mjr/bO7t2wWSuNgmibV1cRVsHlbhKTVUREzuv3Z0bdoffAm7eFiD3b67u3W nq8eM10nbk4aw9e/X/bwBw2FZShyjzZeHQLk46J6F/p3SFN61FE+SB7VqZXFyNiliz/W uhjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884672; x=1742489472; 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=QMmC1rvIEkXaWS15upxpWMXmGh0jkxNvxi3wjmpL1yE=; b=eqSvS2ycTK3fATkX0ZsUuk927iNEC5d0BkUeU05tbHkjN5ptqPhbW+FgVEiXB8Wlki B9//LDuVgVPLCl+9JcvUMxjhStVC+QPXXVfpKFY6rbuHoZEDp+p5PUBC0FCSQPmaJojb k1O5Umd61RnHIZCv6urlZ2zZTrkuKAE+4zd6CNMZkeIDFiM0bgdkJXMnp46Dgjd/P/fV UkcdIcO62QQ89uzrUsG2skSeIQk+lbplQT3tJB3iAar8WvFBLy9IDpt9oWuJIqZ5YtTW Zx+5yjJflqMWuKnq4mH5qEnmZRxxAhpPpyKKZOzsVNFK4Cfrb09y+ka2MFhlPua+JUbr GR/w== X-Forwarded-Encrypted: i=1; AJvYcCWQxj7nOmJYyMWPlIZblTTyhn9+qqAmcPw8h4DGhrCa5SNF4da1yw7ADD+JR0sy2I1xWq4IWJMdebsvEag=@vger.kernel.org X-Gm-Message-State: AOJu0Yww9BLa+5jhRHm44O0lXAbE5l6EFRFBiC1mDDlOvFT17uc7I/Er mMTRFtUmoDtQIwO/LanRzyWTcXp1OKA9zcYn6MN8NS1rg+Wzz+vD X-Gm-Gg: ASbGncur62CvtiamGNFLmM7CWlMWbI4oMzdxyjHhkOgVjYpq+j203lO1ohwYluFPhsu wGu44pzELBFEOUNwWuDox4Udn/icK4lAhqZdZJg+p0sb+bKYcgmjbKQvX3UvuU52Hpt5cv8SUGX dvI2fdQ1h/ReA1CcSIE3FhHYXqWvv6FUaJYuW85FaxSz6brRUDZeR1Rke96AkufKLS5vKCe4OqU aDGozhojff+8VwqtATADSq+HLdwP+uu7VMYdYU46sEZ9mAdq8JYF2n6zQGdgGTxAFSOyjV4IHeJ Vj0pQ0pCWeFAs+LcJI3TLfW1K65CPat/dXNutKTDGIV7od4SO/p7+uKUq6+bNYBXScGXIwMsrwR M5GCivNDHacmR6Qbjn5Lb5BU= X-Google-Smtp-Source: AGHT+IFyZQjNLENno+J4b1eF76M6lraPWOq5QsXkRAovwqs0Vyp1eZq9nG17UlrDxqtjuHRXHDFC6Q== X-Received: by 2002:a17:907:724f:b0:abf:663b:22c5 with SMTP id a640c23a62f3a-ac2b9e5ed25mr617884866b.13.1741884671607; Thu, 13 Mar 2025 09:51:11 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:11 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 06/14] iio: accel: adxl345: add double tap feature Date: Thu, 13 Mar 2025 16:50:41 +0000 Message-Id: <20250313165049.48305-7-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the double tap feature of the sensor. The interrupt handler needs to catch and forward the event to the IIO channel. The single tap implementation now is extended to deal with double tap as well. Doubletap introduces window and latency times, both in us. Since both times are scaled, the 8-bit register value is stored in hardware, where the scaled value in [us] is stored as member variable. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 100 ++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index cfdbc73c96b4..eae419cf8d0b 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -46,17 +46,23 @@ enum adxl345_axis { /* single/double tap */ enum adxl345_tap_type { ADXL345_SINGLE_TAP, + ADXL345_DOUBLE_TAP, }; static const unsigned int adxl345_tap_int_reg[] = { [ADXL345_SINGLE_TAP] = ADXL345_INT_SINGLE_TAP, + [ADXL345_DOUBLE_TAP] = ADXL345_INT_DOUBLE_TAP, }; enum adxl345_tap_time_type { + ADXL345_TAP_TIME_LATENT, + ADXL345_TAP_TIME_WINDOW, ADXL345_TAP_TIME_DUR, }; static const unsigned int adxl345_tap_time_reg[] = { + [ADXL345_TAP_TIME_LATENT] = ADXL345_REG_LATENT, + [ADXL345_TAP_TIME_WINDOW] = ADXL345_REG_WINDOW, [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; @@ -69,6 +75,8 @@ struct adxl345_state { u8 fifo_mode; u32 tap_duration_us; + u32 tap_latent_us; + u32 tap_window_us; __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; @@ -82,6 +90,14 @@ static struct iio_event_spec adxl345_events[] = { .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_TIMEOUT), }, + { + /* double tap */ + .type = IIO_EV_TYPE_GESTURE, + .dir = IIO_EV_DIR_DOUBLETAP, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_RESET_TIMEOUT) | + BIT(IIO_EV_INFO_TAP2_MIN_DELAY), + }, }; #define ADXL345_CHANNEL(index, reg, axis) { \ @@ -167,6 +183,7 @@ static int _adxl345_set_tap_int(struct adxl345_state *st, unsigned int tap_threshold; bool axis_valid; bool singletap_args_valid = false; + bool doubletap_args_valid = false; bool en = false; u32 tap_axis_ctrl; int ret; @@ -187,8 +204,16 @@ static int _adxl345_set_tap_int(struct adxl345_state *st, */ singletap_args_valid = tap_threshold > 0 && st->tap_duration_us > 0; - if (type == ADXL345_SINGLE_TAP) + if (type == ADXL345_SINGLE_TAP) { en = axis_valid && singletap_args_valid; + } else { + /* doubletap: Window must be equal or greater than latent! */ + doubletap_args_valid = st->tap_latent_us > 0 && + st->tap_window_us > 0 && + st->tap_window_us >= st->tap_latent_us; + + en = axis_valid && singletap_args_valid && doubletap_args_valid; + } if (state && en) int_map |= adxl345_tap_int_reg[type]; @@ -265,12 +290,23 @@ static int adxl345_set_singletap_en(struct adxl345_state *st, return _adxl345_set_tap_int(st, ADXL345_SINGLE_TAP, en); } +static int adxl345_set_doubletap_en(struct adxl345_state *st, bool en) +{ + return _adxl345_set_tap_int(st, ADXL345_DOUBLE_TAP, en); +} + static int _adxl345_set_tap_time(struct adxl345_state *st, enum adxl345_tap_time_type type, u32 val_us) { unsigned int regval; switch (type) { + case ADXL345_TAP_TIME_WINDOW: + st->tap_window_us = val_us; + break; + case ADXL345_TAP_TIME_LATENT: + st->tap_latent_us = val_us; + break; case ADXL345_TAP_TIME_DUR: st->tap_duration_us = val_us; break; @@ -302,6 +338,34 @@ static int adxl345_set_tap_duration(struct adxl345_state *st, u32 val_int, return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_DUR, val_fract_us); } +static int adxl345_set_tap_window(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + /* + * Max value is 255 * 1250 us = 0.318750 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (val_int || val_fract_us > 318750) + return -EINVAL; + + return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_WINDOW, val_fract_us); +} + +static int adxl345_set_tap_latent(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + /* + * Max value is 255 * 1250 us = 0.318750 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (val_int || val_fract_us > 318750) + return -EINVAL; + + return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_LATENT, val_fract_us); +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -405,6 +469,12 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, if (ret) return ret; return int_en; + case IIO_EV_DIR_DOUBLETAP: + ret = adxl345_is_tap_en(st, chan->channel2, + ADXL345_DOUBLE_TAP, &int_en); + if (ret) + return ret; + return int_en; default: return -EINVAL; } @@ -426,6 +496,8 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, switch (dir) { case IIO_EV_DIR_SINGLETAP: return adxl345_set_singletap_en(st, chan->channel2, state); + case IIO_EV_DIR_DOUBLETAP: + return adxl345_set_doubletap_en(st, state); default: return -EINVAL; } @@ -465,6 +537,14 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, *val = st->tap_duration_us; *val2 = 1000000; return IIO_VAL_FRACTIONAL; + case IIO_EV_INFO_RESET_TIMEOUT: + *val = st->tap_window_us; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; + case IIO_EV_INFO_TAP2_MIN_DELAY: + *val = st->tap_latent_us; + *val2 = 1000000; + return IIO_VAL_FRACTIONAL; default: return -EINVAL; } @@ -497,6 +577,12 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, case IIO_EV_INFO_TIMEOUT: ret = adxl345_set_tap_duration(st, val, val2); break; + case IIO_EV_INFO_RESET_TIMEOUT: + ret = adxl345_set_tap_window(st, val, val2); + break; + case IIO_EV_INFO_TAP2_MIN_DELAY: + ret = adxl345_set_tap_latent(st, val, val2); + break; default: ret = -EINVAL; break; @@ -753,6 +839,16 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_DOUBLE_TAP, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, tap_dir, + IIO_EV_TYPE_GESTURE, + IIO_EV_DIR_DOUBLETAP), + ts); + if (ret) + return ret; + } + if (FIELD_GET(ADXL345_INT_WATERMARK, int_stat)) { samples = adxl345_get_samples(st); if (samples < 0) @@ -875,6 +971,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, /* Init with reasonable values */ tap_threshold = 48; /* 48 [0x30] -> ~3g */ st->tap_duration_us = 16; /* 16 [0x10] -> .010 */ + st->tap_window_us = 64; /* 64 [0x40] -> .080 */ + st->tap_latent_us = 16; /* 16 [0x10] -> .020 */ indio_dev->name = st->info->name; indio_dev->info = &adxl345_info; From patchwork Thu Mar 13 16:50:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015491 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 6697A26A1C1; Thu, 13 Mar 2025 16:51:14 +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=1741884676; cv=none; b=uooBpBwp1TUKRb6NYinNS84LkeLS++AoKK12Qp2oyg+4iXpSJPDjArO6cUm77uQInxS9H9ZydL7aSRpAL2fU5pD6kLkpE1DoBEIkeA5W6Dv2d4+uQq2vqOVo1AK3ky46p9peMmWtGH4gRxNiYdC08Y+pL/hGn58yQqDSKFk7DvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884676; c=relaxed/simple; bh=fH+WgItQJ5QeqHp5GboweniSh+AUhP1VSmPC21hq5IY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=acb7YtBJKfRtUCs+9FRxAe6WF7FX3wSul52xr8z4oph+LVq0x/7BV2pTqleOOkF4FKowXX/kCViCKC4/yrHzEMZ5WzRlA9MrfZmkguZ8nfFxJJyyAmHyEVYqmRaW8aAMJRvXrAK3QhR6XSIvwpkr7XstZUY7VecFFRAI20juGtI= 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=gTj02/Tw; 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="gTj02/Tw" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ac24daf5f32so15087466b.0; Thu, 13 Mar 2025 09:51:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884673; x=1742489473; 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=3A2/dc7iiyTfvwBTBoVMH8GTIaZ5VfQXot2jVROEU34=; b=gTj02/Tw0DRbeeBBSv6Iv7jOfY2WhqnL4lYCyYRcjQvjDmJdSQ55oUpeH0SWevlJUY iQ/E5I9eOQELh6+Xj6n4AHngsTW/urZIcxs0ZwTx3hjNEHLIkgQ9uBOiF632GFCWMMk4 Lqaf7tFr/PIlETV2zwkoagVoacsKqUzJAwtLFOakvSfJrnAYhsFaojUqZnGHqPZO5ZLT y5HS0piJ4Jx5Z9y2SER48fgA0LWuFjoWNYrJkmzwAHMf8cFMb39J5h9VcSHFZRliVN7j Qn6Yip+BRKSU+/OE2dZyAqu7ubgiuWAUKLaGqoGMySchA5QQUdRvd496gH0R/CSkJ0UL xf0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884673; x=1742489473; 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=3A2/dc7iiyTfvwBTBoVMH8GTIaZ5VfQXot2jVROEU34=; b=WD2zRiAldQiP8Q82/lw1kehVdFlRcdh1GEhtLSO+oIzmwvHsX/ZeYqdgwLEUpaacoX qUJLwmsgLv5G3twLXQI9EHALDC+QyVN885Eg6v7UVF/m4SPkPvEnBkzaezn4PEL/G8CU 5S2rwDkULNzcJ1/4WrZH8giF2lrssX927bamYeAA+REVU2siGRH9aJgTu9cQFfONk2aI zLeWmYaO8/+Yp3yehEql1TW4lcKrG7mensFNE264OTNHnCkXdpstAjrSx8pT5WmKXG0J Nhf8+bC6hzdxmPhH7dqqMQTv7fxI+ub/GFFThNc6BksxVrmzSkRiXisQpag2LsjYvu+6 2zhQ== X-Forwarded-Encrypted: i=1; AJvYcCXrhiUbIkqcTP2H9WqYZod+eZeR+SH0ujClTezA+OSBQM88ltH9veskBQzZmOfUHclDPV9aKqq2iKJNqAQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yy7cgS++TCyOnx5YOmwAtgXeee5LxgswTXiPHlgpnKsjUCDsbT7 diw/4l7yxb9OgaYG+45womb3DStFasUK5nCi/xBN8G9Bi5ypvq7f X-Gm-Gg: ASbGncuDsYjJmZLNzK36kdinn03/Xa+X0ZH+uRzwG02L3PI8rkbZBjTxH6wcmmMkwgt CcKbot+beN5ytOXMYvXRUPLUd+uQaK15qIsIQXfAmzIvv2GrW9IlVpQ/J4txdY3p6eaXvl3++Md ddfbWvUoi0O5rRQLzrVxN9/rv/7PMsOYzdycYqGhfB2SvZNdBhIAhWa/Qv0Y7+AUrN2T/V966Ag cSsHytMN7WCpiNTChL/uOUSuDRPD228Lhl5ziJWHulSRQ0IxYyx6mKA6qvDIlguFgnv1vyM8sFW W1SXUtYmzYXmzw8VA4LpLo9T+SiFm2NHK2X/KW94MFI0GvpnlXxseEDZK7O+eioj0Z56WDhu5xZ fVJX+arerqf0ZJYo/X1gKApf0ERHsrfnldQ== X-Google-Smtp-Source: AGHT+IFfsL4WE9ACY7ONw4EWSVGmKjYp5BWArUp5XrgnvuLrglkJP8Pg3VEZkWZSO2Gtmu4wWL2mnA== X-Received: by 2002:a17:907:7e88:b0:abf:6d80:ae1 with SMTP id a640c23a62f3a-ac2b9c75eb3mr636701166b.2.1741884672499; Thu, 13 Mar 2025 09:51:12 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:12 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 07/14] iio: accel: adxl345: set the tap suppress bit permanently Date: Thu, 13 Mar 2025 16:50:42 +0000 Message-Id: <20250313165049.48305-8-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Set the suppress bit feature to the double tap detection, whenever double tap is enabled. This impedes the suppress bit dangling in any state, and thus varying in sensitivity for double tap detection. Any tap event is defined by a rising signal edge above threshold, i.e. duration time starts counting; and the falling edge under threshold within duration time, i.e. then the tap event is issued. This means duration is used individually for each tap event. For double tap detection after a single tap, a latency time needs to be specified. Usually tap events, i.e. spikes above and returning below threshold will be ignored within latency. After latency, the window time starts counting for a second tap detection which has to happen within a duration time. If the suppress bit is not set, spikes within latency time are ignored. Setting the suppress bit will invalidate the double tap function. The sensor will thus be able to save the window time for double tap detection, and follow a more strict definition of what signal qualifies for a double tap. In a summary having the suppress bit set, fewer signal spikes will be considered as double taps. This is an optional add on to double tap, thus a separate patch. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index eae419cf8d0b..9e33236c786a 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -34,6 +34,7 @@ #define ADXL345_INT2 1 #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) +#define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) enum adxl345_axis { ADXL345_Z_EN = BIT(0), @@ -292,6 +293,18 @@ static int adxl345_set_singletap_en(struct adxl345_state *st, static int adxl345_set_doubletap_en(struct adxl345_state *st, bool en) { + int ret; + + /* + * Generally suppress detection of spikes during the latency period as + * double taps here, this is fully optional for double tap detection + */ + ret = regmap_update_bits(st->regmap, ADXL345_REG_TAP_AXIS, + ADXL345_REG_TAP_SUPPRESS_MSK, + en ? ADXL345_TAP_SUPPRESS : 0x00); + if (ret) + return ret; + return _adxl345_set_tap_int(st, ADXL345_DOUBLE_TAP, en); } From patchwork Thu Mar 13 16:50:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015492 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E0C426B082; Thu, 13 Mar 2025 16:51:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884678; cv=none; b=RmrJ9IK+Co7xC/E8ovv9RSVKjUO7Z5Y8hI5tW/5KJ9gozgnBqK+4tBBo/LAn34D2DXR1ZK7ZuzBI5Po2SN1IRDpLc5tXccSOxpRo4tlinuuaUmdyBIV3kXq9T23mK56B5BBMoc8GN5BOMCTOPIK9/PO2lWDElUPq5UIeyKg86KM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884678; c=relaxed/simple; bh=ZgD+ggEIcZvGSmTEh6HZK6oXnQsJrbJ0FFZVMJVYXL4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=S54922DxspbW9y8ftOlYBk1DbnXbWaK3z7Ul9czHSRquuhFnC0B4KjHX8B+lXOjKbT9G1w4DlOECW1kRH6IzSjrub/XIILN0rB9Uji+tYPI7I2oIZH87GosrgqpqaHb6ApKhqz3rA3RZS/BF3urmWdY99J0SJKarmYifu5c+KoU= 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=nqwGGX50; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nqwGGX50" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-ac30d4ee0f5so15650066b.0; Thu, 13 Mar 2025 09:51:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884673; x=1742489473; 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=37rTZ9VYdIOohXqPChjfDU8OspBVgffgmeVDmCtP9bU=; b=nqwGGX50zNAV8TiQBgAKLOORXkE9Sq0/cg+QL9ztNwEFbYjNmgwn/H06ozgliSynfx zVIdlEViyP7vWnA4MeIxE8i1vdmtZKSz3+qbWZhvJnd8SC7BMPINKaETM7m4lXPx2vyT zLjci6pZv9NZL54s6MBMpmI3PjR7soX5OCIgufrAWosKUdfME/tzEdfaXxlpgn8hmVUq sJ4PEbHXmG1cNam3fF0m0TB6KHlb8k73b167/cz/SKJwr7jUzPON6En4RQHMLfGtJe+R vimpq/NbNxrJ8kkeqKiDN4Z1pO6haQZPDMIyZEv09cL4Q7o1PH7DUUmt31cKGKEVSL2y xQkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884673; x=1742489473; 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=37rTZ9VYdIOohXqPChjfDU8OspBVgffgmeVDmCtP9bU=; b=X7qyQtzY9s/vB1XAkaa4wMCr9XeENrIwAkQPnnmsRAIRxYGLqIwOnh4crcT5YtFgBH jPqtg3SzTNNTYhMujJljNROHxm2HOS2kPQP20u8nIeZQr4oUFnr8NyQFEJNmCYDESQJ7 2I8Lq/QKrvlHEogUohXlSsqab5MNmNpU4BxOQR7vRnH+F8bO6s3c4U2can6DmdF5N+3i 0jf+NbbFbKCMOJnabowVQii9txGczwTx+wORncOlt0g9MG+zRwtnd46emZqXpTVnu9Bx JxUCD3lK88NQNmN1pkStWoDaPSM6dYBgkqQAaysdHyZbPs0ODfbMG0YUENgh+0rZQG/h p+eA== X-Forwarded-Encrypted: i=1; AJvYcCV772ElOfWcWr0ULRinf3KeosqO6Gav8LB2/wEqGTZesELKW/HTtsoSvNWD6kwbJ6KUxzhEOEFPGI4eIX4=@vger.kernel.org X-Gm-Message-State: AOJu0YyzKc36hE8eWLh/x9rqZmqBt+9Zt6CTmyk6GTzoiL7PZ+4q8KxY fuAOEfUKKcNKU1I0+hnob7JSWfu4iwR6O61jhquv+tskY4fdZnBD X-Gm-Gg: ASbGncsN0DbTXal6S4ToiFNTlKrqI2JqtQZzxB6lp2m53xh+11QZ9g0/soPQprVmQ8u uRRn0VeCoN7CPEO+D4EKtprkrsdto9epLP+zKld6XoB4B02vf+MeFyHJ8NGKksp7QxI5S719W4Y LT6vx98fPx5UkcY48mOIusAaSMvs7VTlvcgRXQ3aAcoDP1Pmj2LXgd2qL+QHCa5UxlouctSUEN2 vd0z7h9dg/xq8/mKoVPMTmD9IShIJZaBG95RHPMma4q3S+Jg6iRCFmwogOo083Yjv1vwp/EV1kX 6YHZsQxcc64IajOsaoykfH5d5+ZX7bYSocGzd4jcEH+IZlhoJ4zOH5UnK4yua7L+f/GSgXNfS/I K4lbV94enKOVdZG/fKChE1w8= X-Google-Smtp-Source: AGHT+IEqHMw42K5AdfCt9I4LgUiwhZagxRJybAE+sFmFjKbjrlgD0n95lQ/SHgKqXkVdimpI54SGOQ== X-Received: by 2002:a17:907:7243:b0:abb:e5ac:28b2 with SMTP id a640c23a62f3a-ac271639fa7mr987282066b.13.1741884673355; Thu, 13 Mar 2025 09:51:13 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:13 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 08/14] iio: accel: adxl345: add freefall feature Date: Thu, 13 Mar 2025 16:50:43 +0000 Message-Id: <20250313165049.48305-9-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the freefall detection of the sensor together with a threshold and time parameter. A freefall event is detected if the measuring signal falls below the threshold. Introduce a freefall threshold stored in regmap cache, and a freefall time, having the scaled time value stored as a member variable in the state instance. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 122 +++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 9e33236c786a..1a2bf0c630c9 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -78,6 +78,7 @@ struct adxl345_state { u32 tap_duration_us; u32 tap_latent_us; u32 tap_window_us; + u32 ff_time_ms; __le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE + 1] __aligned(IIO_DMA_MINALIGN); }; @@ -99,6 +100,14 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_EV_INFO_RESET_TIMEOUT) | BIT(IIO_EV_INFO_TAP2_MIN_DELAY), }, + { + /* free fall */ + .type = IIO_EV_TYPE_MAG, + .dir = IIO_EV_DIR_FALLING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD), + }, }; #define ADXL345_CHANNEL(index, reg, axis) { \ @@ -379,6 +388,64 @@ static int adxl345_set_tap_latent(struct adxl345_state *st, u32 val_int, return _adxl345_set_tap_time(st, ADXL345_TAP_TIME_LATENT, val_fract_us); } +/* freefall */ + +static int adxl345_is_ff_en(struct adxl345_state *st, bool *en) +{ + int ret; + unsigned int regval; + + ret = regmap_read(st->regmap, ADXL345_REG_INT_ENABLE, ®val); + if (ret) + return ret; + + *en = FIELD_GET(ADXL345_INT_FREE_FALL, regval) > 0; + + return 0; +} + +static int adxl345_set_ff_en(struct adxl345_state *st, bool cmd_en) +{ + unsigned int regval, ff_threshold; + const unsigned int freefall_mask = 0x02; + bool en; + int ret; + + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_FF, &ff_threshold); + if (ret) + return ret; + + en = cmd_en && ff_threshold > 0 && st->ff_time_ms > 0; + + regval = en ? ADXL345_INT_FREE_FALL : 0x00; + + return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + freefall_mask, regval); +} + +static int adxl345_set_ff_time(struct adxl345_state *st, u32 val_int, + u32 val_fract_us) +{ + unsigned int regval; + int val_ms; + + /* + * max value is 255 * 5000 us = 1.275000 seconds + * + * Note: the scaling is similar to the scaling in the ADXL380 + */ + if (1000000 * val_int + val_fract_us > 1275000) + return -EINVAL; + + val_ms = val_int * 1000 + DIV_ROUND_UP(val_fract_us, 1000); + st->ff_time_ms = val_ms; + + regval = DIV_ROUND_CLOSEST(val_ms, 5); + + /* Values between 100ms and 350ms (0x14 to 0x46) are recommended. */ + return regmap_write(st->regmap, ADXL345_REG_TIME_FF, min(regval, 0xff)); +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -491,6 +558,11 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_EV_TYPE_MAG: + ret = adxl345_is_ff_en(st, &int_en); + if (ret) + return ret; + return int_en; default: return -EINVAL; } @@ -514,6 +586,8 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_EV_TYPE_MAG: + return adxl345_set_ff_en(st, state); default: return -EINVAL; } @@ -528,6 +602,7 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, { struct adxl345_state *st = iio_priv(indio_dev); unsigned int tap_threshold; + unsigned int ff_threshold; int ret; switch (type) { @@ -561,6 +636,22 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, default: return -EINVAL; } + case IIO_EV_TYPE_MAG: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_read(st->regmap, ADXL345_REG_THRESH_FF, + &ff_threshold); + if (ret) + return ret; + *val = ff_threshold; + return IIO_VAL_INT; + case IIO_EV_INFO_PERIOD: + *val = st->ff_time_ms; + *val2 = 1000; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -601,6 +692,18 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, break; } break; + case IIO_EV_TYPE_MAG: + switch (info) { + case IIO_EV_INFO_VALUE: + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_FF, val); + break; + case IIO_EV_INFO_PERIOD: + ret = adxl345_set_ff_time(st, val, val2); + break; + default: + ret = -EINVAL; + } + break; default: ret = -EINVAL; break; @@ -862,6 +965,17 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_FREE_FALL, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_MAG, + IIO_EV_DIR_FALLING), + ts); + if (ret) + return ret; + } + if (FIELD_GET(ADXL345_INT_WATERMARK, int_stat)) { samples = adxl345_get_samples(st); if (samples < 0) @@ -968,6 +1082,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, ADXL345_DATA_FORMAT_FULL_RES | ADXL345_DATA_FORMAT_SELF_TEST); unsigned int tap_threshold; + unsigned int ff_threshold; int ret; indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); @@ -987,6 +1102,9 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, st->tap_window_us = 64; /* 64 [0x40] -> .080 */ st->tap_latent_us = 16; /* 16 [0x10] -> .020 */ + ff_threshold = 8; /* 8 [0x08] */ + st->ff_time_ms = 32; /* 32 [0x20] -> 0.16 */ + indio_dev->name = st->info->name; indio_dev->info = &adxl345_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -1063,6 +1181,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_FF, ff_threshold); + if (ret) + return ret; + /* FIFO_STREAM mode is going to be activated later */ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops); if (ret) From patchwork Thu Mar 13 16:50:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015493 Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.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 6BEE526A091; Thu, 13 Mar 2025 16:51:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884679; cv=none; b=kmveaTH1oBsAqmpvb774+VfV/DvB+3YT20IZUaOmt6BEjKcx8tOMRX1lasoBpGpYtzi+RMq/luREo5z4cv1z6l5DmXLf+w9HBKGKdbxcOLxSP7Bl94+wZLD8LjnjWmoV/Nl3Kt5c2JtGI5kfSpfAEvZgtx/VKHYHLF1sxegz2Zs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884679; c=relaxed/simple; bh=WDMnfz2lrKlD97BGdcJfElEY9mv6VWuliK7cOcXCBBU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gt/eTmwCXzJkpWyR4RXXIs98mDt/Pkf9DkiuQe1lKOLUZgL6PYYhHQyF0c4QArC7Zb4qKOI3bEw1hKUCb1OoPKvL8AXc+S6xPDJB67i+yYSV8REUxIPnJtygeW1OEdOTmDoXapV1BugX5wwD8hcnNhEZWK6dplqUPuiFMvK2RX4= 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=eBavY/Ar; arc=none smtp.client-ip=209.85.208.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="eBavY/Ar" Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-5e8484bb895so103064a12.0; Thu, 13 Mar 2025 09:51:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884674; x=1742489474; 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=KqlCbLOC3QTaQS/vmCmZmcBwbGU9HBbdt6rGZi4UwZE=; b=eBavY/ArppC5kCHWhzioNtoQ43aM3cqUyKNFU0URDtZOfmFa7+d2ZxgZm9CJbSYq5V LNAJFSSbwWxgWmzNG5Frj5MBaSnI96hxaQF8f+ezthhQfES2DC3yxQNdo53vBUXnGUdD wFFxMtEJqrxGfggUaPYlf5fIU4pC/Mc1B/CO9/Wp7UV0AnNmvstbhFyniRtjrTzQhpO3 AYChAoLcfoRCkNome+JMyAnX4xC4Cjd1OMyNxMMoj43wkvxMLVT+0hBaqZNZtNm/+cJc YQzY0jo4IVI/uJ9WCUn1XKLyRM6ZCUVsSG3j48kt1ymb7swqUiX5KbEaBzCQhuewX+Rn Hb1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884674; x=1742489474; 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=KqlCbLOC3QTaQS/vmCmZmcBwbGU9HBbdt6rGZi4UwZE=; b=Ryodk625B5BOZS5nkYIP0H2BNwn4yEPPpOzZ7WHQHBjuWaa1EgB2uPT/XDdWZf9bCY oGi9FPsiGhL3A4PmGeu3AxYwhTASGMU0oye4HlOZ0ltlh2w3g7XbJs/8rcolphnwXwOj bEm1+7fdoUaxM+hL16sk2UgoCm0g2DKziIElLOz/j9ITJQne9B9ejQqwCDJ7oPTqk++3 20OwuZ//xS8XI9sA4chswJ1ZTXpxC5sBBERaYWf9RsRToUpwOamFpL0ZWE8wBN1bG+nM lEFaWu8m4Vw4u/rUzzmpSIr8FQCcMbXzgnpXdc6pflOUe1JAsPqRW4ai2mtFI3bmkp8+ FVKg== X-Forwarded-Encrypted: i=1; AJvYcCWiUzIwB9XG2VIHWYeZUsE6RNu76r1qQ3yStT1QZbWGsvu1svEmnrim57NkWMczBbb+VeDzZzUY9qb29no=@vger.kernel.org X-Gm-Message-State: AOJu0YyvJXmzKQbInrPXcsBExPpdIvNQSmYm7QwXJbh+FHhSwrAcKLQ6 KgTrIqVNF9i4Ax/EF9k3OWSVBWMvhvUsFtPb/nmunvJAEa7glVCY6CXVqB40 X-Gm-Gg: ASbGnctl+fwD8JkbQn2Erq6gp78bO28ijdcR7JROQhMJcQkF2AHsrn2t1P8rqqBUFE4 oj7Vxv6n+GktGNXQVBz8KNacTPysamIbhlbKlcKi71smqS7VKozw5VMei5vS2m6lwkoMmF7kvM+ chqrFj/DGbGOkiP2pQw8oTIPRQrEezwPt7WsrsUxu87d/wCdrG+yk/tn7esync0i+QL8ipc8nIw TEwj7RO/37QfkSMRsyETJMt0PAW6/+VSZMHrQ/ndLYZ8CGmw0cbG3dOyJ8MM9ZQQlKI2tuhztbU qhyxVTMqa1ePUtmv4KYabvUIII6pWb40hUCBqkfBS0YhlPAcjGPt4vtkxo0tJnPaNbgWn5XGaO1 7RdSSFXmBjqM4MitG1diHUKk= X-Google-Smtp-Source: AGHT+IEZ6EujTvVNuOm3xDoQYokBsKC2xYQzoaOyZl/HM3zu5wgxhTcyVax7PTxjpX2oAxcd3LCjUA== X-Received: by 2002:a17:906:f5aa:b0:abf:7a26:c45a with SMTP id a640c23a62f3a-ac2b9e55560mr634227466b.11.1741884674226; Thu, 13 Mar 2025 09:51:14 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:13 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 09/14] iio: accel: adxl345: extend sample frequency adjustments Date: Thu, 13 Mar 2025 16:50:44 +0000 Message-Id: <20250313165049.48305-10-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce enums and functions to work with the sample frequency adjustments. Let the sample frequency adjust via IIO and configure a reasonable default. Replace the old static sample frequency handling. The patch is in preparation for activity/inactivity handling. During adjustment of bw registers, measuring is disabled and afterwards enabled again. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345.h | 2 +- drivers/iio/accel/adxl345_core.c | 156 ++++++++++++++++++++++++------- 2 files changed, 124 insertions(+), 34 deletions(-) diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h index 7d482dd595fa..6c1f96406136 100644 --- a/drivers/iio/accel/adxl345.h +++ b/drivers/iio/accel/adxl345.h @@ -69,7 +69,7 @@ * BW_RATE bits - Bandwidth and output data rate. The default value is * 0x0A, which translates to a 100 Hz output data rate */ -#define ADXL345_BW_RATE GENMASK(3, 0) +#define ADXL345_BW_RATE_MSK GENMASK(3, 0) #define ADXL345_BW_LOW_POWER BIT(4) #define ADXL345_BASE_RATE_NANO_HZ 97656250LL diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 1a2bf0c630c9..4c5084497def 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -67,6 +67,45 @@ static const unsigned int adxl345_tap_time_reg[] = { [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; +enum adxl345_odr { + ADXL345_ODR_0P10HZ = 0, + ADXL345_ODR_0P20HZ, + ADXL345_ODR_0P39HZ, + ADXL345_ODR_0P78HZ, + ADXL345_ODR_1P56HZ, + ADXL345_ODR_3P13HZ, + ADXL345_ODR_6P25HZ, + ADXL345_ODR_12P50HZ, + ADXL345_ODR_25HZ, + ADXL345_ODR_50HZ, + ADXL345_ODR_100HZ, + ADXL345_ODR_200HZ, + ADXL345_ODR_400HZ, + ADXL345_ODR_800HZ, + ADXL345_ODR_1600HZ, + ADXL345_ODR_3200HZ, +}; + +/* Certain features recommend 12.5 Hz - 400 Hz ODR */ +static const int adxl345_odr_tbl[][2] = { + [ADXL345_ODR_0P10HZ] = { 0, 97000 }, + [ADXL345_ODR_0P20HZ] = { 0, 195000 }, + [ADXL345_ODR_0P39HZ] = { 0, 390000 }, + [ADXL345_ODR_0P78HZ] = { 0, 781000 }, + [ADXL345_ODR_1P56HZ] = { 1, 562000 }, + [ADXL345_ODR_3P13HZ] = { 3, 125000 }, + [ADXL345_ODR_6P25HZ] = { 6, 250000 }, + [ADXL345_ODR_12P50HZ] = { 12, 500000 }, + [ADXL345_ODR_25HZ] = { 25, 0 }, + [ADXL345_ODR_50HZ] = { 50, 0 }, + [ADXL345_ODR_100HZ] = { 100, 0 }, + [ADXL345_ODR_200HZ] = { 200, 0 }, + [ADXL345_ODR_400HZ] = { 400, 0 }, + [ADXL345_ODR_800HZ] = { 800, 0 }, + [ADXL345_ODR_1600HZ] = { 1600, 0 }, + [ADXL345_ODR_3200HZ] = { 3200, 0 }, +}; + struct adxl345_state { const struct adxl345_chip_info *info; struct regmap *regmap; @@ -119,6 +158,7 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_CHAN_INFO_CALIBBIAS), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = (index), \ .scan_type = { \ .sign = 's', \ @@ -446,14 +486,59 @@ static int adxl345_set_ff_time(struct adxl345_state *st, u32 val_int, return regmap_write(st->regmap, ADXL345_REG_TIME_FF, min(regval, 0xff)); } +static int adxl345_find_odr(struct adxl345_state *st, int val, + int val2, enum adxl345_odr *odr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adxl345_odr_tbl); i++) { + if (val == adxl345_odr_tbl[i][0] && + val2 == adxl345_odr_tbl[i][1]) { + *odr = i; + return 0; + } + } + + return -EINVAL; +} + +static int adxl345_set_odr(struct adxl345_state *st, enum adxl345_odr odr) +{ + int ret; + + ret = regmap_update_bits(st->regmap, ADXL345_REG_BW_RATE, + ADXL345_BW_RATE_MSK, + FIELD_PREP(ADXL345_BW_RATE_MSK, odr)); + if (ret) + return ret; + + return 0; +} + +static int adxl345_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, + int *length, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = (int *)adxl345_odr_tbl; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(adxl345_odr_tbl) * 2; + return IIO_AVAIL_LIST; + } + + return -EINVAL; +} + static int adxl345_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct adxl345_state *st = iio_priv(indio_dev); __le16 accel; - long long samp_freq_nhz; unsigned int regval; + enum adxl345_odr odr; int ret; switch (mask) { @@ -491,12 +576,10 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, ret = regmap_read(st->regmap, ADXL345_REG_BW_RATE, ®val); if (ret) return ret; - - samp_freq_nhz = ADXL345_BASE_RATE_NANO_HZ << - (regval & ADXL345_BW_RATE); - *val = div_s64_rem(samp_freq_nhz, NANOHZ_PER_HZ, val2); - - return IIO_VAL_INT_PLUS_NANO; + odr = FIELD_GET(ADXL345_BW_RATE_MSK, regval); + *val = adxl345_odr_tbl[odr][0]; + *val2 = adxl345_odr_tbl[odr][1]; + return IIO_VAL_INT_PLUS_MICRO; } return -EINVAL; @@ -507,7 +590,12 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct adxl345_state *st = iio_priv(indio_dev); - s64 n; + enum adxl345_odr odr; + int ret; + + ret = adxl345_set_measure_en(st, false); + if (ret) + return ret; switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: @@ -515,20 +603,26 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, * 8-bit resolution at +/- 2g, that is 4x accel data scale * factor */ - return regmap_write(st->regmap, - ADXL345_REG_OFS_AXIS(chan->address), - val / 4); + ret = regmap_write(st->regmap, + ADXL345_REG_OFS_AXIS(chan->address), + val / 4); + if (ret) + return ret; + break; case IIO_CHAN_INFO_SAMP_FREQ: - n = div_s64(val * NANOHZ_PER_HZ + val2, - ADXL345_BASE_RATE_NANO_HZ); + ret = adxl345_find_odr(st, val, val2, &odr); + if (ret) + return ret; - return regmap_update_bits(st->regmap, ADXL345_REG_BW_RATE, - ADXL345_BW_RATE, - clamp_val(ilog2(n), 0, - ADXL345_BW_RATE)); + ret = adxl345_set_odr(st, odr); + if (ret) + return ret; + break; + default: + return -EINVAL; } - return -EINVAL; + return adxl345_set_measure_en(st, true); } static int adxl345_read_event_config(struct iio_dev *indio_dev, @@ -754,7 +848,7 @@ static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ: - return IIO_VAL_INT_PLUS_NANO; + return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; } @@ -767,19 +861,6 @@ static void adxl345_powerdown(void *ptr) adxl345_set_measure_en(st, false); } -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( -"0.09765625 0.1953125 0.390625 0.78125 1.5625 3.125 6.25 12.5 25 50 100 200 400 800 1600 3200" -); - -static struct attribute *adxl345_attrs[] = { - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - NULL -}; - -static const struct attribute_group adxl345_attrs_group = { - .attrs = adxl345_attrs, -}; - static int adxl345_set_fifo(struct adxl345_state *st) { unsigned int intio; @@ -1040,9 +1121,9 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) } static const struct iio_info adxl345_info = { - .attrs = &adxl345_attrs_group, .read_raw = adxl345_read_raw, .write_raw = adxl345_write_raw, + .read_avail = adxl345_read_avail, .write_raw_get_fmt = adxl345_write_raw_get_fmt, .read_event_config = adxl345_read_event_config, .write_event_config = adxl345_write_event_config, @@ -1112,6 +1193,15 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, indio_dev->num_channels = ARRAY_SIZE(adxl345_channels); indio_dev->available_scan_masks = adxl345_scan_masks; + /* + * Using I2C at 100kHz would limit the maximum ODR to 200Hz, operation + * at an output rate above the recommended maximum may result in + * undesired behavior. + */ + ret = adxl345_set_odr(st, ADXL345_ODR_200HZ); + if (ret) + return ret; + /* Reset interrupts at start up */ ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); if (ret) From patchwork Thu Mar 13 16:50:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015494 Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31F2726B2D4; Thu, 13 Mar 2025 16:51:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884680; cv=none; b=bjzd7k7Wbmkp/ceJ6w92QVbI5POTO7SbqKilmwoLujQbx8eo0MnRgp8zKTe8aqSgjPrEpCO5EU4MLU0R03XgYPh29h7rkFHm6kwzI/fGaTnM4ent1Mop2MBL/d27FfSwYCVUvs7B7Kzxlh+RVsr4aq/GKh1dBY34QyrXGp0uoP4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884680; c=relaxed/simple; bh=jqNWEBfkLVFk14WdzeEWu7UNooHmZpSCV9iQkkaTLxI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=t2NkZA7iPRbA6Ozn/0V63NcCrp6KA/t1u91Oev/SDkjtrJvc6hTXV0ZuNHY/lT3ZNOYuuYWFNhkiQ1rbrBls+uOZjZK2CMIYo1WYQQPtDpIngRl9SpE2dsHcAg4jE4+cv4I1ynZoF3KuMi6ir+0hgQ6wnUMr6uQFUr/3s9UsfR8= 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=YzlWtyhE; arc=none smtp.client-ip=209.85.218.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YzlWtyhE" Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-ac30d4ee0f5so15650466b.0; Thu, 13 Mar 2025 09:51:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884675; x=1742489475; 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=TX68PgRmI1fMEh5Bmh8IcZ3GDbagprHUKDeqzIRqfZI=; b=YzlWtyhEy6G0I093t+4ZzN/a1a+ncSyUXomE3V4n9sUZpPB5f53oCazCDxoHg4g5p4 iRIf6xQwQ7wClFrjQ+1OWAKa4QNkVHwsPY/R/DxqzhsvYbVKWKo7WQpbr22pomXt2Uhi D5Yzmvxg6oBMDx/KgXUuxolra1bMeTqrzy+MxwV40IF3+mCy+RRYDQ9RVcfXkstUTYdg TJb5aqDLzfyiDieGUnv12lr2ORQFrX4sOzDZ28aV2duAo5OowfiranoyvFEzQgkX5dre pWujhrygAJs5bd9e0wNKRP0d9POK2jzLRnyGbLmDHV0SZrsS6a0y+8hlNMdOCfvDlASM EJwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884675; x=1742489475; 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=TX68PgRmI1fMEh5Bmh8IcZ3GDbagprHUKDeqzIRqfZI=; b=EomoMkFjClmqsBVeMWtZW3zTHyAhXLElv1Xen0glmjCXfpIQZv6Q/cOGLnSF5258K0 skdoaBRwEEuwGMpfHdoEuh8/uJ+OdHVJskTtE+hMPZhpZy4dvRLfxJ0Z0LTspwFgzm+k 6THJBN0crYhcnrVR8iZjDxAe46pX6bnZ6Cx3AIpbzu4RJZNgghk3SWQG+5S0xdU+AN+q o4WmKKKO/6vt2TJKsPqfrFYgMtw2joZ5oAkeaV3Dk0fT0Fkh/ZVZpLLjwQV43ttkq3pa vM2mvE3axLzN1Q179TW69X3f1xXYHBqVZb/ZIysJ5Sp2DjYLyfS5xLbaTOGGMCNCUBXL /v1g== X-Forwarded-Encrypted: i=1; AJvYcCU7GyzAMdHjpNQJgnCiVYVnfy5GLtyAwVBOaCzlOH98h1EVRu4maQL7y6bk5BcoW9P8lC7Vocj/SVmfD4g=@vger.kernel.org X-Gm-Message-State: AOJu0Ywb++g0kCCNBarJKoN+9GPcW737JyhflowiJ6Dfq0yM4nvRY4wo V95in9ned2BSqf3o/nCwKxSbvZKrXskQVmjidaHNFE3xvxku6k0g X-Gm-Gg: ASbGncsUu6mOxM5NxtH5B8psAmOm2xIJ/FqVcPH9HrxEkUO8H1MZLEnHD28o76gFqSk gq2+Ej1swPhCoWJXNnd2Q4hVe6kVAqNfxsajeHxXLQCOLUtFPgnmQNd7DAYggB/Py1sNzf0s62T 8eunX9SjCfO38pKMjBLwmMcO/F1gjvTEePAjSzRNYJTZ+0h4vwVge4A1R9u/xtxwRLqh9IA6+TK vzCaBrRCRQOtB4NNpQ76u58am+HlHea42XAGFf+vI4UPkleXJ5IPS9vE8pn8TvutdbF9IUpaaG6 RROznzK2rChLH9bN2xROjKSsfgMFvgLgnuTk0Am7E5yjjENmZHlsj7yvyiHn4H4xRITz7IgEKSN Bp7xsHFZIfPSV/DaPNbWcOfw= X-Google-Smtp-Source: AGHT+IF/LzaT7vmd0tTVETJ+e05T3B/0wimsiwvnuVPgHqXHSqHfRqPFeyNn5Wd1DxGgVT7IJpXtJw== X-Received: by 2002:a17:907:86a5:b0:ac2:6d18:ff36 with SMTP id a640c23a62f3a-ac271594e2amr1009568866b.9.1741884675132; Thu, 13 Mar 2025 09:51:15 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:14 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 10/14] iio: accel: adxl345: add g-range configuration Date: Thu, 13 Mar 2025 16:50:45 +0000 Message-Id: <20250313165049.48305-11-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce means to configure and work with the available g-ranges keeping the precision of 13 digits. This is in preparation for the activity/inactivity feature. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 96 +++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 4c5084497def..de9202126f70 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -86,6 +86,13 @@ enum adxl345_odr { ADXL345_ODR_3200HZ, }; +enum adxl345_range { + ADXL345_2G_RANGE = 0, + ADXL345_4G_RANGE, + ADXL345_8G_RANGE, + ADXL345_16G_RANGE, +}; + /* Certain features recommend 12.5 Hz - 400 Hz ODR */ static const int adxl345_odr_tbl[][2] = { [ADXL345_ODR_0P10HZ] = { 0, 97000 }, @@ -106,6 +113,33 @@ static const int adxl345_odr_tbl[][2] = { [ADXL345_ODR_3200HZ] = { 3200, 0 }, }; +/* + * Full resolution frequency table: + * (g * 2 * 9.80665) / (2^(resolution) - 1) + * + * resolution := 13 (full) + * g := 2|4|8|16 + * + * 2g at 13bit: 0.004789 + * 4g at 13bit: 0.009578 + * 8g at 13bit: 0.019156 + * 16g at 16bit: 0.038312 + */ +static const int adxl345_fullres_range_tbl[][2] = { + [ADXL345_2G_RANGE] = { 0, 4789 }, + [ADXL345_4G_RANGE] = { 0, 9578 }, + [ADXL345_8G_RANGE] = { 0, 19156 }, + [ADXL345_16G_RANGE] = { 0, 38312 }, +}; + +/* scaling */ +static const int adxl345_range_factor_tbl[] = { + [ADXL345_2G_RANGE] = 1, + [ADXL345_4G_RANGE] = 2, + [ADXL345_8G_RANGE] = 4, + [ADXL345_16G_RANGE] = 8, +}; + struct adxl345_state { const struct adxl345_chip_info *info; struct regmap *regmap; @@ -158,7 +192,8 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_CHAN_INFO_CALIBBIAS), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = (index), \ .scan_type = { \ .sign = 's', \ @@ -515,12 +550,46 @@ static int adxl345_set_odr(struct adxl345_state *st, enum adxl345_odr odr) return 0; } +static int adxl345_find_range(struct adxl345_state *st, int val, int val2, + enum adxl345_range *range) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(adxl345_fullres_range_tbl); i++) { + if (val == adxl345_fullres_range_tbl[i][0] && + val2 == adxl345_fullres_range_tbl[i][1]) { + *range = i; + return 0; + } + } + + return -EINVAL; +} + +static int adxl345_set_range(struct adxl345_state *st, enum adxl345_range range) +{ + int ret; + + ret = regmap_update_bits(st->regmap, ADXL345_REG_DATA_FORMAT, + ADXL345_DATA_FORMAT_RANGE, + FIELD_PREP(ADXL345_DATA_FORMAT_RANGE, range)); + if (ret) + return ret; + + return 0; +} + static int adxl345_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, const int **vals, int *type, int *length, long mask) { switch (mask) { + case IIO_CHAN_INFO_SCALE: + *vals = (int *)adxl345_fullres_range_tbl; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(adxl345_fullres_range_tbl) * 2; + return IIO_AVAIL_LIST; case IIO_CHAN_INFO_SAMP_FREQ: *vals = (int *)adxl345_odr_tbl; *type = IIO_VAL_INT_PLUS_MICRO; @@ -539,6 +608,7 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, __le16 accel; unsigned int regval; enum adxl345_odr odr; + enum adxl345_range range; int ret; switch (mask) { @@ -557,8 +627,12 @@ static int adxl345_read_raw(struct iio_dev *indio_dev, *val = sign_extend32(le16_to_cpu(accel), 12); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = 0; - *val2 = st->info->uscale; + ret = regmap_read(st->regmap, ADXL345_REG_DATA_FORMAT, ®val); + if (ret) + return ret; + range = FIELD_GET(ADXL345_DATA_FORMAT_RANGE, regval); + *val = adxl345_fullres_range_tbl[range][0]; + *val2 = adxl345_fullres_range_tbl[range][1]; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_CALIBBIAS: ret = regmap_read(st->regmap, @@ -590,6 +664,7 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, int val, int val2, long mask) { struct adxl345_state *st = iio_priv(indio_dev); + enum adxl345_range range; enum adxl345_odr odr; int ret; @@ -618,6 +693,15 @@ static int adxl345_write_raw(struct iio_dev *indio_dev, if (ret) return ret; break; + case IIO_CHAN_INFO_SCALE: + ret = adxl345_find_range(st, val, val2, &range); + if (ret) + return ret; + + ret = adxl345_set_range(st, range); + if (ret) + return ret; + break; default: return -EINVAL; } @@ -847,6 +931,8 @@ static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_SAMP_FREQ: return IIO_VAL_INT_PLUS_MICRO; default: @@ -1202,6 +1288,10 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = adxl345_set_range(st, ADXL345_16G_RANGE); + if (ret) + return ret; + /* Reset interrupts at start up */ ret = regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, 0x00); if (ret) From patchwork Thu Mar 13 16:50:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015495 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 269D926B2D0; Thu, 13 Mar 2025 16:51:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884680; cv=none; b=BDZT0fXLLl1/kKJ0GnivLR+f0l6Tj1vohK7vbppYMu1EFmWHzINyFyvb4Ez9V8ip64VViRM/b6q2JPQeOyogNXPOIfmTFtGVRF2DkOVpOY3+fh5iFyRFX8aS50xvbxvqUzM+VG3LHY3ux9lqP0aj6sX5c3cyIJlCIsG3XeH3vPM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884680; c=relaxed/simple; bh=mZjn8O2vII7ZxYPr65Ie0U6hWdaJ/rr+KTwnmFvv9yk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Hu/JOIY/gLXs2tYreKu2BvkRfmoxRVSZ2sw6CmRDuM+eoL6erU+3wOrB0T0PuladfCuT+o4tj5Of3KJnYp1IaqhK9GfEobMgyeHMHmFXqLjvGuroAM3ghJXJoJtrZRbIG1B35IXUf4T1Bw+jbjnXSQNOhmMbHxFTwUj3/Cp5Etg= 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=betCTGkc; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="betCTGkc" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-ac24daf5f32so15088166b.0; Thu, 13 Mar 2025 09:51:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884676; x=1742489476; 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=Q5UshTE7ACs62k6pf1vEYbB1RAdAT3w5z4Vdq4Vcj3c=; b=betCTGkc64FxuYXLI8SKq+vSrbwBzKzPG+6sUyjIJhcBLO6wvEkqx1/NZAlPqbwQNz YiDll5+wN0uVBnYC7u3tczXvEEm4Xl68bMdD5MTDrJjJT7ilaRZYx6hC4z71L5jq8VSG KkyvzZUAuvoKn8aIFClnOdsrAsUbuQkghDrG9Fahe8+/tSaG2e235ZyZzF++sfFjZGX9 wzepy7sJ+ibMLfnQnqBxWRAEyPZSPVrNLCNLiVeknjfCUp3Wzt8RNNceoG7C/p/yFhvZ Hku7+bg89PWlxglkheCeyc3UT6dnHFnvdcC8t6yRZVuo1NaBQ01wOCFpLhvfVh7z4imB YoVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884676; x=1742489476; 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=Q5UshTE7ACs62k6pf1vEYbB1RAdAT3w5z4Vdq4Vcj3c=; b=gI9e2Xif/R9TqvIFvJPNqHTaXBUYnJt7ZkXjaCyFznqAlQ4iVp2KDESdp/k4s7nwmB Zl+jq5OmU0HGgWoV6PYw9EmlJclbrGh0Fpv9SXlmKAFoB4VCg0FM00kKQTPMn/9R6rBf SqVl1+iO9DmmL4jACf7tmTeF5sX6nCWx0DQqx9uBrXYI8dKXxP+3yubgF9275oaaC/jn euQhItP7XjQU4sFEKXoXxjX/uUO3o2HKZhffHVPQmmYAlG2We8wx8WI+rE8cM3jzkoPI VUc98K+bYlRu+DSzQ5Mp2V2+2A1eQaKro4OUnFOWSSBeaiGpUzlqfOPGBMtjlzFnPnEJ pKVg== X-Forwarded-Encrypted: i=1; AJvYcCUQrvGW4dicF8TZyarHprzxcpkP5RQKuK5OBIMaQxGpfPoqnP5W838f9Lqtsifez5Z4HOm3mAik0TMs10g=@vger.kernel.org X-Gm-Message-State: AOJu0Yw2Yy1bjFA0n94kKdKpi2Mzj/RuIn8lG95pPrXb+UG3+r1jh8KR bo1W5kVxSqAl0+nfnxrO6XGkVBvcIC/BYlvfEY9ZcRJ8aOeilGZu X-Gm-Gg: ASbGnct+0tZYTKjIAymXNhbP28PfkzeeGJdkgDGLJJjaJ0snFCYhaM9zsMsTy6xWzjq F1tkNvrOT5CScyE5eK+mmsD9V0PQysLuj88rfB3ydM6h1UnOFe4YK7vBoVGFd8AMWi6e+6nvOu2 0W/fShO52l2LEkttdIE9f8fZ72GRaZmrl9lrzHZuyx/KsJx6FHgxMdOXP1cbDt+EUg0EAToQ2zO Bxj8i9cHT8LD7OdvvCJKTRnab/LWxCz8ljpKjZLfa9qJwnD6kHfQvq0rwtEVofWRcBsNWvz6HEp szzMC+AwW/JtmWo+xElDza27BTXwnK5gIZsA8AOpa5ZFrhTN+o88xov/gAPvzUyvWXHIjkpZqMt YjroMzY2o5PzT8J/tCLkUix8= X-Google-Smtp-Source: AGHT+IEh+pVooy+awPz0Sh96OuZafg7UDwyx+ZYIsRxfwZwQqUynacEUAR6dFktD7i3MWxtmhFhz8w== X-Received: by 2002:a17:907:1c9f:b0:ab7:bb4b:aa49 with SMTP id a640c23a62f3a-ac2b9d5999bmr574139866b.5.1741884676078; Thu, 13 Mar 2025 09:51:16 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:15 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 11/14] iio: accel: adxl345: add activity event feature Date: Thu, 13 Mar 2025 16:50:46 +0000 Message-Id: <20250313165049.48305-12-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Make the sensor detect and issue interrupts at activity. Activity events are configured by a threshold stored in regmap cache. Initialize the activity threshold register to a reasonable default value in probe. The value is taken from the older ADXL345 input driver, to provide a similar behavior. Reset the activity/inactivity direction enabling register in probe. Reset and initialization shall bring the sensor in a defined initial state to prevent dangling settings when warm restarting the sensor. Activity, ODR configuration together with the range setting prepare the activity/inactivity hystersesis setup, implemented in a follow up patch. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 222 ++++++++++++++++++++++++++++++- 1 file changed, 219 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index de9202126f70..98a781987b63 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -35,6 +35,7 @@ #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) #define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) +#define ADXL345_REG_ACT_AXIS_MSK GENMASK(6, 4) enum adxl345_axis { ADXL345_Z_EN = BIT(0), @@ -67,6 +68,23 @@ static const unsigned int adxl345_tap_time_reg[] = { [ADXL345_TAP_TIME_DUR] = ADXL345_REG_DUR, }; +/* activity/inactivity */ +enum adxl345_activity_type { + ADXL345_ACTIVITY, +}; + +static const unsigned int adxl345_act_int_reg[] = { + [ADXL345_ACTIVITY] = ADXL345_INT_ACTIVITY, +}; + +static const unsigned int adxl345_act_thresh_reg[] = { + [ADXL345_ACTIVITY] = ADXL345_REG_THRESH_ACT, +}; + +static const unsigned int adxl345_act_axis_msk[] = { + [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, +}; + enum adxl345_odr { ADXL345_ODR_0P10HZ = 0, ADXL345_ODR_0P20HZ, @@ -157,6 +175,13 @@ struct adxl345_state { }; static struct iio_event_spec adxl345_events[] = { + { + /* activity */ + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE), + }, { /* single tap */ .type = IIO_EV_TYPE_GESTURE, @@ -259,6 +284,108 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val); } +/* act/inact */ + +static int adxl345_is_act_inact_en(struct adxl345_state *st, + enum iio_modifier axis, + enum adxl345_activity_type type, bool *en) +{ + unsigned int regval; + bool axis_en; + u32 axis_ctrl; + int act_shift; + int ret; + + act_shift = (type == ADXL345_ACTIVITY) ? 4 : 0; + + ret = regmap_read(st->regmap, ADXL345_REG_ACT_INACT_CTRL, &axis_ctrl); + if (ret) + return ret; + + axis_ctrl = axis_ctrl >> act_shift; + + switch (axis) { + case IIO_MOD_X: + axis_en = FIELD_GET(ADXL345_X_EN, axis_ctrl); + break; + case IIO_MOD_Y: + axis_en = FIELD_GET(ADXL345_Y_EN, axis_ctrl); + break; + case IIO_MOD_Z: + axis_en = FIELD_GET(ADXL345_Z_EN, axis_ctrl); + break; + default: + return -EINVAL; + } + + ret = regmap_read(st->regmap, ADXL345_REG_INT_ENABLE, ®val); + if (ret) + return ret; + + *en = (adxl345_act_int_reg[type] & regval) > 0; + + return 0; +} + +static int adxl345_set_act_inact_en(struct adxl345_state *st, + enum iio_modifier axis, + enum adxl345_activity_type type, + bool cmd_en) +{ + bool axis_en, en; + unsigned int threshold; + u32 axis_ctrl; + /* + * Activity and inactivity share the same register for enabling + * directions. Activity uses the four upper bits, where inactivity + * detection uses the lower bits. In order to keep generic x, y + * and z-axis type, it is shifted for initialization of activity. + * NB: Activity and inactivitty axis enable bits are regmap cached. + */ + int act_shift = (type == ADXL345_ACTIVITY) ? 4 : 0; + int ret; + + switch (axis) { + case IIO_MOD_X: + axis_ctrl = ADXL345_X_EN; + break; + case IIO_MOD_Y: + axis_ctrl = ADXL345_Y_EN; + break; + case IIO_MOD_Z: + axis_ctrl = ADXL345_Z_EN; + break; + default: + return -EINVAL; + } + + axis_ctrl = axis_ctrl << act_shift; + + if (cmd_en) + ret = regmap_set_bits(st->regmap, + ADXL345_REG_ACT_INACT_CTRL, axis_ctrl); + else + ret = regmap_clear_bits(st->regmap, + ADXL345_REG_ACT_INACT_CTRL, axis_ctrl); + if (ret) + return ret; + + ret = regmap_read(st->regmap, adxl345_act_thresh_reg[type], &threshold); + if (ret) + return ret; + + en = false; + + if (type == ADXL345_ACTIVITY) { + axis_en = FIELD_GET(ADXL345_REG_ACT_AXIS_MSK, axis_ctrl) > 0; + en = axis_en && threshold > 0; + } + + return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + adxl345_act_int_reg[type], + en ? adxl345_act_int_reg[type] : 0); +} + /* tap */ static int _adxl345_set_tap_int(struct adxl345_state *st, @@ -719,6 +846,18 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, int ret = -EFAULT; switch (type) { + case IIO_EV_TYPE_THRESH: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = adxl345_is_act_inact_en(st, chan->channel2, + ADXL345_ACTIVITY, + &int_en); + if (ret) + return ret; + return int_en; + default: + return -EINVAL; + } case IIO_EV_TYPE_GESTURE: switch (dir) { case IIO_EV_DIR_SINGLETAP: @@ -755,6 +894,14 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, struct adxl345_state *st = iio_priv(indio_dev); switch (type) { + case IIO_EV_TYPE_THRESH: + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl345_set_act_inact_en(st, chan->channel2, + ADXL345_ACTIVITY, state); + default: + return -EINVAL; + } case IIO_EV_TYPE_GESTURE: switch (dir) { case IIO_EV_DIR_SINGLETAP: @@ -779,11 +926,31 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, int *val, int *val2) { struct adxl345_state *st = iio_priv(indio_dev); + unsigned int act_threshold; unsigned int tap_threshold; unsigned int ff_threshold; int ret; switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_ACTIVITY], + &act_threshold); + if (ret) + return ret; + + *val = act_threshold; + return IIO_VAL_INT; + default: + return -EINVAL; + } + default: + return -EINVAL; + } case IIO_EV_TYPE_GESTURE: switch (info) { case IIO_EV_INFO_VALUE: @@ -850,6 +1017,23 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, return ret; switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = regmap_write(st->regmap, + adxl345_act_thresh_reg[ADXL345_ACTIVITY], + val); + break; + default: + ret = -EINVAL; + } + break; + default: + ret = -EINVAL; + } + break; case IIO_EV_TYPE_GESTURE: switch (info) { case IIO_EV_INFO_VALUE: @@ -1105,7 +1289,8 @@ static int adxl345_fifo_push(struct iio_dev *indio_dev, } static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, - enum iio_modifier tap_dir) + enum iio_modifier tap_dir, + enum iio_modifier act_dir) { s64 ts = iio_get_time_ns(indio_dev); struct adxl345_state *st = iio_priv(indio_dev); @@ -1132,6 +1317,16 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_ACTIVITY, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, act_dir, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + ts); + if (ret) + return ret; + } + if (FIELD_GET(ADXL345_INT_FREE_FALL, int_stat)) { ret = iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, @@ -1164,10 +1359,12 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, */ static irqreturn_t adxl345_irq_handler(int irq, void *p) { + const int act_shift = 4; struct iio_dev *indio_dev = p; struct adxl345_state *st = iio_priv(indio_dev); unsigned int regval; enum iio_modifier tap_dir = IIO_NO_MOD; + enum iio_modifier act_dir = IIO_NO_MOD; u32 axis_ctrl; int int_stat; int ret; @@ -1176,7 +1373,8 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) if (ret) return IRQ_NONE; - if (FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, axis_ctrl)) { + if (FIELD_GET(ADXL345_REG_TAP_AXIS_MSK, axis_ctrl) || + FIELD_GET(ADXL345_REG_ACT_AXIS_MSK, axis_ctrl)) { ret = regmap_read(st->regmap, ADXL345_REG_ACT_TAP_STATUS, ®val); if (ret) return IRQ_NONE; @@ -1187,12 +1385,22 @@ static irqreturn_t adxl345_irq_handler(int irq, void *p) tap_dir = IIO_MOD_Y; else if (FIELD_GET(ADXL345_X_EN, regval)) tap_dir = IIO_MOD_X; + + /* Activity direction is stored in the upper four bits */ + regval >>= act_shift; + + if (FIELD_GET(ADXL345_Z_EN, regval)) + act_dir = IIO_MOD_Z; + else if (FIELD_GET(ADXL345_Y_EN, regval)) + act_dir = IIO_MOD_Y; + else if (FIELD_GET(ADXL345_X_EN, regval)) + act_dir = IIO_MOD_X; } if (regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &int_stat)) return IRQ_NONE; - if (adxl345_push_event(indio_dev, int_stat, tap_dir)) + if (adxl345_push_event(indio_dev, int_stat, tap_dir, act_dir)) goto err; if (FIELD_GET(ADXL345_INT_OVERRUN, int_stat)) @@ -1357,6 +1565,14 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = regmap_write(st->regmap, ADXL345_REG_ACT_INACT_CTRL, 0); + if (ret) + return ret; + + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_ACT, 6); + if (ret) + return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_TAP, tap_threshold); if (ret) return ret; From patchwork Thu Mar 13 16:50:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015496 Received: from mail-ej1-f42.google.com (mail-ej1-f42.google.com [209.85.218.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 281ED2698B8; Thu, 13 Mar 2025 16:51:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884681; cv=none; b=SFbjfgu3BMO2Ku6A3aKgtTf/rxPMhoMRrhndpnziOXWsnV/z3n4PYaL7Ntc10eI4qoExosKm0cmC753UqlEisrGlQkZ4l9HPqXbJiSUm8TFO8RltOHfdiaqwSWSvfsmCgt/2BQSzXzDJOyovO7Oqbs1sE1QIVzBDJAp2/xrQ77A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884681; c=relaxed/simple; bh=M6t6mlQ1igVk0UXirkHCfi5PtaQYamY95PHjcgPOe7Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YdUhDKAUFf0hdoh4KxrkyndhL6kqY/0O1EDmvB+HHs+jOVu+fUkeoEZhkj1JxxAKbyezK5UHNd+qyhUsSrIUdoiJiVAc9Wit//kVIwi9JDBm+jykNwiD0XcYKd9DQVKb2KmEDaOcJTMHQCCkzCWPS906VpL6WsBJ8ppndSdtD1E= 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=gZRofeQw; arc=none smtp.client-ip=209.85.218.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gZRofeQw" Received: by mail-ej1-f42.google.com with SMTP id a640c23a62f3a-ac2b8830e2cso16109366b.3; Thu, 13 Mar 2025 09:51:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884677; x=1742489477; 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=UlD6NtdRlPIXybja5Wb352sxVITMXlChHaEZC8CxGjo=; b=gZRofeQwWnRBBJeVHyhNFQpLwh+Vfh18Ml9cf2GoOefV4ZPvJBJAi7PxP/qB2m5cC9 dyJCNJTMIAj5zTEFDqEzIaNaM21MEjIApZjOD/uHyUyv3m64gEGrvCHCkdzOXbpI/EKg bEZgHXgB+jOvWE9pFPpn/tTSYcUyouhDu1q5SUhMq1S65yixkHLfkuyErVFrsYkKLMie BywRIfUyW6HuC5f4LcVFdQTiv6uMhAm/nWMPXwCvORqy79+TZXZOZ2QStaSjXg4jjEX4 w4NR2ldRM3xymvvVli8bgKHpoxHog6R33xQa+Or4vHfkyPfnTdC8exj/JBGg85U0xaAW BGkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884677; x=1742489477; 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=UlD6NtdRlPIXybja5Wb352sxVITMXlChHaEZC8CxGjo=; b=ea5yXZV5xgRrCWpAovi7rxYCTw3LUk/AN5TaGQTlQHcjd4EarncX/+HzqW5k9dmouV jZ1LNvQKmvcmO4goTL07gLtgdyeUZczmB8HsmDGb+8EP2iaNz0JQ0ba6zRPZorKq2xwv 7TneBfBICbCXEi/eCuLxX8rQ+c43MfeO7Ycg8vbvo6lAohwlnXaYCJb8iAyfBl94emxA GCbHsiu+GWxxIzLNUTxThFMCOfWPodRgWz59XimhCeaxsvqgSiE+OyS0rtVT3QJaRHLC nNt6hX2TEYZuiZTPL4pGTOAQwY98TUBrDXJy9uXV5932eSEehbSJ9CT8VMd4E9s153UU //DA== X-Forwarded-Encrypted: i=1; AJvYcCUA2B4LAkUHJSewK/T0wd9Bi809OcOjgZsAZEo90uLD2hahEYUNipjNJH25xvstXkBuYQiyVoHxZalLVRk=@vger.kernel.org X-Gm-Message-State: AOJu0Yyfapzc7OGU0UG/MQR83K0y//URA286Deru5axgLnQ7AAqSXjRJ I8+pPvVNcU9sUI26+9V4vMFgyADfVSxlanXbdL1H6R8ouEa18qdX X-Gm-Gg: ASbGncsznZsCEjCVG1zPLubusV6GKvTy6u/VMd+7g2FzXTZOXy21xNP3UKHoCh1LGPE tyLkCEWq8sT5or6YGBGfpPT3BSEj+i1NaoEPwsEeDOVmy2p//Perys8IlJeggA37zj3Z6UG1/kk W0oGd6bL4F1rH/7rIjbmxPJ36mqtvSU0BVhI07UPCfxZZ2H6wMwBRUD6RcRs665BfG93cCRQ5PI WJXk7zWkRWMQwYWPhpi3DDRCFB5Mwpc00slo6L9beiA2ZrhjN7gkcdloELpeRhtd8iw/ya36xca wXsxsGt/UUZQwS8dLK7uyYOkwDhvMsS5hZifxuUko+/2rK8OSFuatq1iNNPVurY3gGT5gdMMzZL LMwBQi1OuFtwWrtieEk1LNLs= X-Google-Smtp-Source: AGHT+IG2BeFIvvcdHPLelY/Mnf6eRHtTxUs/pQsRDFjxP98eeR4wpl3FtmdFbil1KaTziY1zfS28fw== X-Received: by 2002:a17:907:7b99:b0:ac2:1d34:44ff with SMTP id a640c23a62f3a-ac2b9cfc3fbmr651085666b.4.1741884677022; Thu, 13 Mar 2025 09:51:17 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:16 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 12/14] iio: accel: adxl345: add inactivity feature Date: Thu, 13 Mar 2025 16:50:47 +0000 Message-Id: <20250313165049.48305-13-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add the inactivity feature of the sensor. When activity and inactivity are enabled, a link bit will be set linking activity and inactivity handling. Additionally, the auto-sleep mode will be enabled. Due to the link bit the sensor is going to auto-sleep when inactivity was detected. Inactivity detection needs a threshold to be configured, and a time after which it will go into inactivity state if measurements under threshold. When a ODR is configured this time for inactivity is adjusted with a corresponding reasonable default value, in order to have higher frequencies and lower inactivity times, and lower sample frequency but give more time until inactivity. Both with reasonable upper and lower boundaries, since many of the sensor's features (e.g. auto-sleep) will need to operate beween 12.5 Hz and 400 Hz. This is a default setting when actively changing sample frequency, explicitly setting the time until inactivity will overwrite the default. Similarly, setting the g-range will provide a default value for the activity and inactivity thresholds. Both are implicit defaults, but equally can be overwritten to be explicitly configured. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 132 ++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 4 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index 98a781987b63..c718d529d897 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,6 +36,8 @@ #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) #define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) #define ADXL345_REG_ACT_AXIS_MSK GENMASK(6, 4) +#define ADXL345_REG_INACT_AXIS_MSK GENMASK(2, 0) +#define ADXL345_POWER_CTL_INACT_MSK (ADXL345_POWER_CTL_AUTO_SLEEP | ADXL345_POWER_CTL_LINK) enum adxl345_axis { ADXL345_Z_EN = BIT(0), @@ -71,18 +73,22 @@ static const unsigned int adxl345_tap_time_reg[] = { /* activity/inactivity */ enum adxl345_activity_type { ADXL345_ACTIVITY, + ADXL345_INACTIVITY, }; static const unsigned int adxl345_act_int_reg[] = { [ADXL345_ACTIVITY] = ADXL345_INT_ACTIVITY, + [ADXL345_INACTIVITY] = ADXL345_INT_INACTIVITY, }; static const unsigned int adxl345_act_thresh_reg[] = { [ADXL345_ACTIVITY] = ADXL345_REG_THRESH_ACT, + [ADXL345_INACTIVITY] = ADXL345_REG_THRESH_INACT, }; static const unsigned int adxl345_act_axis_msk[] = { [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, + [ADXL345_INACTIVITY] = ADXL345_REG_INACT_AXIS_MSK, }; enum adxl345_odr { @@ -182,6 +188,14 @@ static struct iio_event_spec adxl345_events[] = { .mask_separate = BIT(IIO_EV_INFO_ENABLE), .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE), }, + { + /* inactivity */ + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_PERIOD), + }, { /* single tap */ .type = IIO_EV_TYPE_GESTURE, @@ -333,6 +347,7 @@ static int adxl345_set_act_inact_en(struct adxl345_state *st, bool cmd_en) { bool axis_en, en; + unsigned int inact_time_s; unsigned int threshold; u32 axis_ctrl; /* @@ -379,11 +394,67 @@ static int adxl345_set_act_inact_en(struct adxl345_state *st, if (type == ADXL345_ACTIVITY) { axis_en = FIELD_GET(ADXL345_REG_ACT_AXIS_MSK, axis_ctrl) > 0; en = axis_en && threshold > 0; + } else { + ret = regmap_read(st->regmap, ADXL345_REG_TIME_INACT, &inact_time_s); + if (ret) + return ret; + + axis_en = FIELD_GET(ADXL345_REG_INACT_AXIS_MSK, axis_ctrl) > 0; + en = axis_en && threshold > 0 && inact_time_s > 0; } - return regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, - adxl345_act_int_reg[type], - en ? adxl345_act_int_reg[type] : 0); + ret = regmap_update_bits(st->regmap, ADXL345_REG_INT_ENABLE, + adxl345_act_int_reg[type], + en ? adxl345_act_int_reg[type] : 0); + if (ret) + return ret; + + return regmap_update_bits(st->regmap, ADXL345_REG_POWER_CTL, + ADXL345_POWER_CTL_INACT_MSK, + en ? (ADXL345_POWER_CTL_AUTO_SLEEP | ADXL345_POWER_CTL_LINK) + : 0); +} + +/** + * adxl345_set_inact_time_s - Configure inactivity time explicitly or by ODR. + * @st: The sensor state instance. + * @val_s: A desired time value, between 0 and 255. + * + * If val_s is 0, a default inactivity time will be computed. It should take + * power consumption into consideration. Thus it shall be shorter for higher + * frequencies and longer for lower frequencies. Hence, frequencies above 255 Hz + * shall default to 10 s and frequencies below 10 Hz shall result in 255 s to + * detect inactivity. + * + * The approach simply subtracts the pre-decimal figure of the configured + * sample frequency from 255 s to compute inactivity time [s]. Sub-Hz are thus + * ignored in this estimation. The recommended ODRs for various features + * (activity/inactivity, sleep modes, free fall, etc.) lie between 12.5 Hz and + * 400 Hz, thus higher or lower frequencies will result in the boundary + * defaults or need to be explicitly specified via val_s. + * + * Return: 0 or error value. + */ +static int adxl345_set_inact_time_s(struct adxl345_state *st, u32 val_s) +{ + unsigned int max_boundary = 255; + unsigned int min_boundary = 10; + unsigned int val = min(val_s, max_boundary); + enum adxl345_odr odr; + unsigned int regval; + int ret; + + if (val == 0) { + ret = regmap_read(st->regmap, ADXL345_REG_BW_RATE, ®val); + if (ret) + return ret; + odr = FIELD_GET(ADXL345_BW_RATE_MSK, regval); + + val = (adxl345_odr_tbl[odr][0] > max_boundary) + ? min_boundary : max_boundary - adxl345_odr_tbl[odr][0]; + } + + return regmap_write(st->regmap, ADXL345_REG_TIME_INACT, val); } /* tap */ @@ -855,6 +926,13 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, if (ret) return ret; return int_en; + case IIO_EV_DIR_FALLING: + ret = adxl345_is_act_inact_en(st, chan->channel2, + ADXL345_INACTIVITY, + &int_en); + if (ret) + return ret; + return int_en; default: return -EINVAL; } @@ -899,6 +977,9 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, case IIO_EV_DIR_RISING: return adxl345_set_act_inact_en(st, chan->channel2, ADXL345_ACTIVITY, state); + case IIO_EV_DIR_FALLING: + return adxl345_set_act_inact_en(st, chan->channel2, + ADXL345_INACTIVITY, state); default: return -EINVAL; } @@ -926,7 +1007,8 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, int *val, int *val2) { struct adxl345_state *st = iio_priv(indio_dev); - unsigned int act_threshold; + unsigned int act_threshold, inact_threshold; + unsigned int inact_time_s; unsigned int tap_threshold; unsigned int ff_threshold; int ret; @@ -945,9 +1027,24 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, *val = act_threshold; return IIO_VAL_INT; + case IIO_EV_DIR_FALLING: + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_INACTIVITY], + &inact_threshold); + if (ret) + return ret; + + *val = inact_threshold; + return IIO_VAL_INT; default: return -EINVAL; } + case IIO_EV_INFO_PERIOD: + ret = regmap_read(st->regmap, ADXL345_REG_TIME_INACT, &inact_time_s); + if (ret) + return ret; + *val = inact_time_s; + return IIO_VAL_INT; default: return -EINVAL; } @@ -1026,10 +1123,18 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, adxl345_act_thresh_reg[ADXL345_ACTIVITY], val); break; + case IIO_EV_DIR_FALLING: + ret = regmap_write(st->regmap, + adxl345_act_thresh_reg[ADXL345_INACTIVITY], + val); + break; default: ret = -EINVAL; } break; + case IIO_EV_INFO_PERIOD: + ret = adxl345_set_inact_time_s(st, val); + break; default: ret = -EINVAL; } @@ -1327,6 +1432,17 @@ static int adxl345_push_event(struct iio_dev *indio_dev, int int_stat, return ret; } + if (FIELD_GET(ADXL345_INT_INACTIVITY, int_stat)) { + ret = iio_push_event(indio_dev, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, + IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + ts); + if (ret) + return ret; + } + if (FIELD_GET(ADXL345_INT_FREE_FALL, int_stat)) { ret = iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, @@ -1569,10 +1685,18 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap, if (ret) return ret; + ret = regmap_write(st->regmap, ADXL345_REG_TIME_INACT, 3); + if (ret) + return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_ACT, 6); if (ret) return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_INACT, 4); + if (ret) + return ret; + ret = regmap_write(st->regmap, ADXL345_REG_THRESH_TAP, tap_threshold); if (ret) return ret; From patchwork Thu Mar 13 16:50:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015497 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 75A50126C03; Thu, 13 Mar 2025 16:51:20 +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=1741884682; cv=none; b=rVpL6l0MjzHjpTm7wX8e/p6Ux41iD/eeYtwAOARK3PJJb9BUCX2ZcJp4K6LIApyjUe0Ok2WZ0/Rq2n63L8W53vQrDc5tSyX1Cv360j/Itg6RStBV0bdhSByNq8gBPCLvP6N9tFx+w2Yvt+6QfF/u3szcqVRTxqztv5HTB9QZJSA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884682; c=relaxed/simple; bh=C9BDPXAoBdCppIJNKsEUjSpGkbDtTojTxqIZj4vm4Vk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=L2PPsjx0TYHbmyWaP3lQy0H6IBXd0e4DSBKiPrcsA1I2jAbFOLwkVeI51xX6f0cJW4UZbJHUFzNydXS3og3p7evuoFYK3f6exjbJqcIEu0iqvjPPuNgh25yD/KLzWmKgFb0VUBwPKVcE9tbdE4s6Y1eUFVILr0p5up1S6UQ1JVs= 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=XYreB1kw; 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="XYreB1kw" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-ac24daf5f32so15088966b.0; Thu, 13 Mar 2025 09:51:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884679; x=1742489479; 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=NXp+p7KoE6pwI0WlNoFYElb0u9k8flDM6qj6UZ8wyYE=; b=XYreB1kwYcf0tiG4DeWtwqP4nUNuMtASfEvrht3xzO2Q2/cri0BQ1g3ybmRgxNiTc8 H7bIDuMJXSOqbu/1X+vpoMjDG/fUTITdOiOp35DkhhezMN70LsJRfgi/txSc2CKGGh+L zWDp69C7CpTdmLepXn+NX4pkJu0FaZEKwGgemPaGziBMe9LUjWra1+mODNqmY2jaywMT g5nrSR9w+sUArbyhj4DYGZUc7Cf3P7QFEKb/3ZrlDf5S4VKeKFMwrS3zkwQUWjVgFYbg Yi/p8+y+ov93vSmBfbHJGBDW5+RgqIH8B2AzZkoE1r1hFelp0DEmRn2h6QpyGkEb0ocz ywFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884679; x=1742489479; 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=NXp+p7KoE6pwI0WlNoFYElb0u9k8flDM6qj6UZ8wyYE=; b=ceIMCagfR2fO4THZglCZyLCiWwD8LdWwpkyWF1OofmCkrgjuFU4AQwbgCdzoFo07/W nw/OBkudKWgbfG3Q2be+whZ+hPF0khGyoCMMdJAZJZ13Ke5GUDpMEWeSy1vFoKbs9ICm yvcQfrRA+lmSslQINm5BKb8Bj++yjxuKf3uOem6kaFALQTzHoUV9Mx6p18fsBr3b5GF+ SjERUOG8aJHJO0fUbxFWABKdNMyUWFKfSA19Cxji9BHRxpNRJnNib2+UJtHKCdo9A9wv 5i+0rVKy0w6Yc6Cd0AGZ3qEM9ptsuMxoxchBLBEBk8r5LhAxprcg/PRhfeA5v7I7c/9H /dvg== X-Forwarded-Encrypted: i=1; AJvYcCVmWqOvbOvXdBCllQpuE5M6fgEUs+WsQfmUyelT74+ForS4x3+DAIViUjZQvx99KVN7kxolxqa2Hm4Aqpg=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3vs3H0+CY0SQDQg+Y1Kw+ahn1G7Wbz2kosSXBuAXFixv1wpgS 7BRRpWY9NvHufSWiqUITlCOBnjo8F5uP1XD5gPPIZBm71Uyx/oM1 X-Gm-Gg: ASbGnctaTNNzSfMAePOvYScCkgnqyeJLRCrBzHlrX+c+qCSZPc/myPKQL9ohiXXffYM 0Yl8Qt29N7qTdKLc9DFCDBPoy8SxdsGfCBY8Y5udxbA4SalVdOkSPPjyaxBxBkBVBfmLS8wHj8I SBaVIbp2RQVEHLRFHyGUT3k6dVZZI/A6Kw3I0B3mCP9Bs857ggzxshj0BYknNC8D1jx94eUT1AR 2PyXgylt39Yppuqw3fVkYBVj1gHi/+G3B9boJA+USw3TmaIy7EvhYp3qltqb8i2/EhNLioUMCha 37HGdDUmTN0pjuG7Kk/98rKkkPyRSDR1K+kfQTMIA0QYbRFJ9Nw02RlctciF5wkV/0qtqHaX4O4 K9wSuXotDwqOKBIWtm8YO1Ww= X-Google-Smtp-Source: AGHT+IHwxtpnkiH3QDVTQd596RDWVcfAkbC47JC09890A1Eex4towAiTcUVxRgzFmP4Jl/XHi+QZmg== X-Received: by 2002:a17:907:c10:b0:ac2:7ce7:cd35 with SMTP id a640c23a62f3a-ac2b9e3a732mr612145466b.10.1741884678575; Thu, 13 Mar 2025 09:51:18 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:18 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 13/14] iio: accel: adxl345: add coupling detection for activity/inactivity Date: Thu, 13 Mar 2025 16:50:48 +0000 Message-Id: <20250313165049.48305-14-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add coupling activity/inactivity detection by the AC/DC bit. This is an addititional enhancement for the detection of activity states and completes the activity / inactivity feature of the ADXL345. Signed-off-by: Lothar Rubusch --- drivers/iio/accel/adxl345_core.c | 150 ++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 2 deletions(-) diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c index c718d529d897..1cbe431cda71 100644 --- a/drivers/iio/accel/adxl345_core.c +++ b/drivers/iio/accel/adxl345_core.c @@ -36,7 +36,9 @@ #define ADXL345_REG_TAP_AXIS_MSK GENMASK(2, 0) #define ADXL345_REG_TAP_SUPPRESS_MSK BIT(3) #define ADXL345_REG_ACT_AXIS_MSK GENMASK(6, 4) +#define ADXL345_REG_ACT_ACDC_MSK BIT(7) #define ADXL345_REG_INACT_AXIS_MSK GENMASK(2, 0) +#define ADXL345_REG_INACT_ACDC_MSK BIT(3) #define ADXL345_POWER_CTL_INACT_MSK (ADXL345_POWER_CTL_AUTO_SLEEP | ADXL345_POWER_CTL_LINK) enum adxl345_axis { @@ -86,6 +88,11 @@ static const unsigned int adxl345_act_thresh_reg[] = { [ADXL345_INACTIVITY] = ADXL345_REG_THRESH_INACT, }; +static const unsigned int adxl345_act_acdc_msk[] = { + [ADXL345_ACTIVITY] = ADXL345_REG_ACT_ACDC_MSK, + [ADXL345_INACTIVITY] = ADXL345_REG_INACT_ACDC_MSK, +}; + static const unsigned int adxl345_act_axis_msk[] = { [ADXL345_ACTIVITY] = ADXL345_REG_ACT_AXIS_MSK, [ADXL345_INACTIVITY] = ADXL345_REG_INACT_AXIS_MSK, @@ -220,6 +227,18 @@ static struct iio_event_spec adxl345_events[] = { BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_PERIOD), }, + { + /* activity, activity - ac bit */ + .type = IIO_EV_TYPE_MAG_REFERENCED, + .dir = IIO_EV_DIR_RISING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE), + }, + { + /* activity, inactivity - ac bit */ + .type = IIO_EV_TYPE_MAG_REFERENCED, + .dir = IIO_EV_DIR_FALLING, + .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE), + }, }; #define ADXL345_CHANNEL(index, reg, axis) { \ @@ -300,6 +319,69 @@ static int adxl345_set_measure_en(struct adxl345_state *st, bool en) /* act/inact */ +static int adxl345_is_act_inact_ac(struct adxl345_state *st, + enum adxl345_activity_type type, bool *ac) +{ + unsigned int regval; + int ret; + + ret = regmap_read(st->regmap, ADXL345_REG_ACT_INACT_CTRL, ®val); + if (ret) + return ret; + + if (type == ADXL345_ACTIVITY) + *ac = (FIELD_GET(ADXL345_REG_ACT_ACDC_MSK, regval) > 0); + else + *ac = (FIELD_GET(ADXL345_REG_INACT_ACDC_MSK, regval) > 0); + + return 0; +} + +static int adxl345_set_act_inact_ac(struct adxl345_state *st, + enum adxl345_activity_type type, bool ac) +{ + unsigned int act_inact_ac = ac ? 0xff : 0x00; + + /* + * A setting of false selects dc-coupled operation, and a setting of + * true enables ac-coupled operation. In dc-coupled operation, the + * current acceleration magnitude is compared directly with + * ADXL345_REG_THRESH_ACT and ADXL345_REG_THRESH_INACT to determine + * whether activity or inactivity is detected. + * + * In ac-coupled operation for activity detection, the acceleration + * value at the start of activity detection is taken as a reference + * value. New samples of acceleration are then compared to this + * reference value, and if the magnitude of the difference exceeds the + * ADXL345_REG_THRESH_ACT value, the device triggers an activity + * interrupt. + * + * Similarly, in ac-coupled operation for inactivity detection, a + * reference value is used for comparison and is updated whenever the + * device exceeds the inactivity threshold. After the reference value + * is selected, the device compares the magnitude of the difference + * between the reference value and the current acceleration with + * ADXL345_REG_THRESH_INACT. If the difference is less than the value in + * ADXL345_REG_THRESH_INACT for the time in ADXL345_REG_TIME_INACT, the + * device is considered inactive and the inactivity interrupt is + * triggered. [quoted from p. 24, ADXL345 datasheet Rev. G] + * + * In a conclusion, the first acceleration snapshot sample which hit the + * threshold in a particular direction is always taken as acceleration + * reference value to that direction. Since for the hardware activity + * and inactivity depend on the x/y/z axis, so do ac and dc coupling. + * Note, this sw driver always enables or disables all three x/y/z axis + * for detection via act_axis_ctrl and inact_axis_ctrl, respectively. + * Where in dc-coupling samples are compared against the thresholds, in + * ac-coupling measurement difference to the first acceleration + * reference value are compared against the threshold. So, ac-coupling + * allows for a bit more dynamic compensation depending on the initial + * sample. + */ + return regmap_update_bits(st->regmap, ADXL345_REG_ACT_INACT_CTRL, + adxl345_act_acdc_msk[type], act_inact_ac); +} + static int adxl345_is_act_inact_en(struct adxl345_state *st, enum iio_modifier axis, enum adxl345_activity_type type, bool *en) @@ -745,7 +827,8 @@ static int adxl345_set_odr(struct adxl345_state *st, enum adxl345_odr odr) if (ret) return ret; - return 0; + /* update inactivity time by ODR */ + return adxl345_set_inact_time_s(st, 0); } static int adxl345_find_range(struct adxl345_state *st, int val, int val2, @@ -766,15 +849,51 @@ static int adxl345_find_range(struct adxl345_state *st, int val, int val2, static int adxl345_set_range(struct adxl345_state *st, enum adxl345_range range) { + unsigned int act_threshold, inact_threshold; + unsigned int range_old; + unsigned int regval; int ret; + ret = regmap_read(st->regmap, ADXL345_REG_DATA_FORMAT, ®val); + if (ret) + return ret; + range_old = FIELD_GET(ADXL345_DATA_FORMAT_RANGE, regval); + + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_ACTIVITY], + &act_threshold); + if (ret) + return ret; + + ret = regmap_read(st->regmap, + adxl345_act_thresh_reg[ADXL345_INACTIVITY], + &inact_threshold); + if (ret) + return ret; + ret = regmap_update_bits(st->regmap, ADXL345_REG_DATA_FORMAT, ADXL345_DATA_FORMAT_RANGE, FIELD_PREP(ADXL345_DATA_FORMAT_RANGE, range)); if (ret) return ret; - return 0; + act_threshold = act_threshold + * adxl345_range_factor_tbl[range_old] + / adxl345_range_factor_tbl[range]; + act_threshold = min(255, max(1, inact_threshold)); + + inact_threshold = inact_threshold + * adxl345_range_factor_tbl[range_old] + / adxl345_range_factor_tbl[range]; + inact_threshold = min(255, max(1, inact_threshold)); + + ret = regmap_write(st->regmap, adxl345_act_thresh_reg[ADXL345_ACTIVITY], + act_threshold); + if (ret) + return ret; + + return regmap_write(st->regmap, adxl345_act_thresh_reg[ADXL345_INACTIVITY], + inact_threshold); } static int adxl345_read_avail(struct iio_dev *indio_dev, @@ -914,6 +1033,8 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, { struct adxl345_state *st = iio_priv(indio_dev); bool int_en; + bool act_ac; + bool inact_ac; int ret = -EFAULT; switch (type) { @@ -958,6 +1079,21 @@ static int adxl345_read_event_config(struct iio_dev *indio_dev, if (ret) return ret; return int_en; + case IIO_EV_TYPE_MAG_REFERENCED: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = adxl345_is_act_inact_ac(st, ADXL345_ACTIVITY, &act_ac); + if (ret) + return ret; + return act_ac; + case IIO_EV_DIR_FALLING: + ret = adxl345_is_act_inact_ac(st, ADXL345_INACTIVITY, &inact_ac); + if (ret) + return ret; + return inact_ac; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -994,6 +1130,16 @@ static int adxl345_write_event_config(struct iio_dev *indio_dev, } case IIO_EV_TYPE_MAG: return adxl345_set_ff_en(st, state); + case IIO_EV_TYPE_MAG_REFERENCED: + switch (dir) { + case IIO_EV_DIR_RISING: + return adxl345_set_act_inact_ac(st, ADXL345_ACTIVITY, state); + case IIO_EV_DIR_FALLING: + return adxl345_set_act_inact_ac(st, ADXL345_INACTIVITY, state); + default: + return -EINVAL; + } + default: return -EINVAL; } From patchwork Thu Mar 13 16:50:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lothar Rubusch X-Patchwork-Id: 14015498 Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B183F269D1A; Thu, 13 Mar 2025 16:51:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884684; cv=none; b=QQEXJxAiGzxsLi9JTCp0rr2wC+xIxZyEvtki2+/vDntnIJSqcq9cEXq/uWkQveCTVKq7mTuE5st6JOMgV+k1hQhJa7IfLOdtILTMa/BtWsClWPZiKkVtb3+OmqLUe7kvQjqry3xlrIYyiLFMzEpUdfXxtIaZNEYCFyigxG23iJE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741884684; c=relaxed/simple; bh=J+gxOK9BmXWp+MSs2VJ9oOXAZgisi21PoNI0mvLG0p4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=HADBXxYDPyqDBUVosuz1Nljd6TLvYAT8RgcmXZ18Q+bsjBQg3nQ8ODRDIo/ixX0cLBNva6u9B41KPypk1/E0njp/tP++qcdsgeh0HMiGg+ts0DWUQQLDqXRdLHZ3HzDdXZFZRMfsNUoB7yRZW8Y4YES+tyjBpW1TDuSmDzAUWWw= 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=Zq4iS+qA; arc=none smtp.client-ip=209.85.218.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Zq4iS+qA" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-abc28af1ba4so16335866b.1; Thu, 13 Mar 2025 09:51:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741884680; x=1742489480; 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=v27Lnlqr3GEvQfW7w8hZ2MQ04yP2vRncP9MW1QBJDBo=; b=Zq4iS+qAmWJ9opfxwKy7qo4uuRwB/IcJZnq3jTfLM7t6+IZ6mr72903Dw9WwWmEuvm ybZusS891fYE/WQ/lyaDZmQsvK4QF1Cc6FeUeJttbCiwEn9HJ3ap6bfhZ8NNUZ8Mz8Iv kvheJq8fMGLe1u+pp7g2TtziW/peEvlScPoMlKJ0irU7L50FZXcabXL6Mtrsz3DFbbJg 8L4b+gAy2p2d5e62POVIGeotxrlcS6k4Jnkhg+SrPQQtV66RDElfuxWTDqEN6IDSRnUZ 6x7hDKzqM+LEQWdIM/FNDLFfrJxbsqwOlpA1hiPnw2rorxpDen2UFQdmA5HjDSjEnaoq QW0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741884680; x=1742489480; 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=v27Lnlqr3GEvQfW7w8hZ2MQ04yP2vRncP9MW1QBJDBo=; b=mQVGhMsrogcWn55r3bPmzpP4S3ThwWinOpBQm3UBLQMshTITl2xeImayyZ4DdNKUHa E8cPmMO0nGzrCJn5V/kaCRargXs1L7B3HE/bG/p9ybcGoMkdWsy49u+iYlJdbFjmpNn7 7z+pPfiD2IKDDNeYPXjAxRglG4ooeX4KARPghWNTkwcGEDl/eYBUVHeAIk8WxCEk4nxy HHuEcwz3lBTL4TGNTrc+cUrPBLJjFrhVhtzN2iBjfZhVg18A8vMyiaXsxs5uAZOUOaj/ miry3u6oudwgQIAYW2OBlmYMfQmVIlQov4010RQau41GWV88ElSd795NTPc9yq+2+eZx 3O4Q== X-Forwarded-Encrypted: i=1; AJvYcCX+mnLNEBN9Yj3Tal5PZt1LYDed+cRsN+zOs0TM5KXYJoc3TVqIghdAFGFnBhe/rrolPDMzxiXqHpCs9Ts=@vger.kernel.org X-Gm-Message-State: AOJu0Yz+mLkXxOfaRCnlF97hOs3oJhPHTrsRhl8AU8Ac9OBuHsSMzIoQ 0D7sdM62NH7wvFzqASp8iXhKbfy0E03DMrh94M0GD7qX0Y2utbC6 X-Gm-Gg: ASbGncvjljRXTVZv93Kmn2xhXKPoiy/zCBqgg1NcKO9T5wT7pDO3cLk+452TIwPX4WP AG5paYQE99e5sv/O6bpdt03zVasJERGmZ0czBIQMUEoycDz0tj3OCeIDvYaVsbluFJCg3POuIcY M9pxcNXkwv7oAt8PxFIirfEC/E4npijtf//3ujmWiFXiOtLBEzpqPl5mkCp0/TYJrb1K0ZNgGeR uHwdJKaMgEJ5IfzfcH/+8iqAAQZHOBRvpj00Utc331n3IoIE3WcUMHBh/43tWf7n8Gx4fTq13gO cDgzK9G18hdS6JMMcuhzjbhoVefLKEetkzl1Ue47Ihn1p61DDs4UDDKQE8E6pjuIWBchHdBL18A qY8FacGqosUF7CKibWiy36OQ= X-Google-Smtp-Source: AGHT+IFscmnFBU+5Va3zkIMZTOguO1Fp1ikJRvLFGRSGUvwFJeGpGM91yNgKvntkmx5/Em5s7lec7g== X-Received: by 2002:a17:907:1c9f:b0:ab7:bb4b:aa49 with SMTP id a640c23a62f3a-ac2b9d5999bmr574146666b.5.1741884679552; Thu, 13 Mar 2025 09:51:19 -0700 (PDT) Received: from 0e1b0684397b.v.cablecom.net (84-72-156-211.dclient.hispeed.ch. [84.72.156.211]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac3147efb0csm101370866b.65.2025.03.13.09.51.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 09:51:19 -0700 (PDT) From: Lothar Rubusch To: lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, eraretuya@gmail.com, l.rubusch@gmail.com Subject: [PATCH v4 14/14] docs: iio: add documentation for adxl345 driver Date: Thu, 13 Mar 2025 16:50:49 +0000 Message-Id: <20250313165049.48305-15-l.rubusch@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250313165049.48305-1-l.rubusch@gmail.com> References: <20250313165049.48305-1-l.rubusch@gmail.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The documentation describes the ADXL345 driver, IIO interface, interface usage and configuration. Signed-off-by: Lothar Rubusch --- Documentation/iio/adxl345.rst | 416 ++++++++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 Documentation/iio/adxl345.rst diff --git a/Documentation/iio/adxl345.rst b/Documentation/iio/adxl345.rst new file mode 100644 index 000000000000..683121c1a435 --- /dev/null +++ b/Documentation/iio/adxl345.rst @@ -0,0 +1,416 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=============== +ADXL345 driver +=============== + +This driver supports Analog Device's ADXL345/375 on SPI/I2C bus. + +1. Supported devices +==================== + +* `ADXL345 `_ +* `ADXL375 `_ + +The ADXL345 is a generic purpose low power, 3-axis accelerometer with selectable +measurement ranges. The ADXL345 supports the ±2 g, ±4 g, ±8 g, and ±16 g ranges. + +2. Device attributes +==================== + +Each IIO device, has a device folder under ``/sys/bus/iio/devices/iio:deviceX``, +where X is the IIO index of the device. Under these folders reside a set of +device files, depending on the characteristics and features of the hardware +device in questions. These files are consistently generalized and documented in +the IIO ABI documentation. + +The following table shows the ADXL345 related device files, found in the +specific device folder path ``/sys/bus/iio/devices/iio:deviceX``. + ++-------------------------------------------+----------------------------------------------------------+ +| 3-Axis Accelerometer related device files | Description | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_sampling_frequency | Currently selected sample rate. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_sampling_frequency_available | Available sampling frequency configurations. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_scale | Scale/range for the accelerometer channels. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_scale_available | Available scale ranges for the accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_x_calibbias | Calibration offset for the X-axis accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_x_raw | Raw X-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_y_calibbias | y-axis acceleration offset correction | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_y_raw | Raw Y-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_z_calibbias | Calibration offset for the Z-axis accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_z_raw | Raw Z-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ + +Channel processed values +------------------------- + +A channel value can be read from its _raw attribute. The value returned is the +raw value as reported by the devices. To get the processed value of the channel, +apply the following formula: + +.. code-block:: bash + + processed value = (_raw + _offset) * _scale + +Where _offset and _scale are device attributes. If no _offset attribute is +present, simply assume its value is 0. + ++-------------------------------------+---------------------------+ +| Channel type | Measurement unit | ++-------------------------------------+---------------------------+ +| Acceleration on X, Y, and Z axis | Meters per second squared | ++-------------------------------------+---------------------------+ + +Sensor events +------------- + +Particular IIO events will be triggered by the corresponding interrupts. The +sensor driver supports no or one active INT line, where the sensor has two +possible INT IOs. Configure the used INT line in the devicetree. If no INT line +is configured, the sensor falls back to FIFO bypass mode and no events are +possible, only X, Y and Z axis measurements are possible. + +The following table shows the ADXL345 related device files, found in the +specific device folder path ``/sys/bus/iio/devices/iio:deviceX/events``. + ++---------------------------------------------+-----------------------------------------+ +| Event handle | Description | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_doubletap_en | Enable double tap detection on all axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_doubletap_reset_timeout | Double tap window in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_doubletap_tap2_min_delay | Double tap latent in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_singletap_timeout | Single tap duration in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_gesture_singletap_value | Single tap threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_falling_en | Enable free fall detection | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_falling_period | Free fall time in [us] | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_falling_value | Free fall threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_referenced_falling_en | Set 1 to AC-coupled inactivity, 0 for DC| ++---------------------------------------------+-----------------------------------------+ +| in_accel_mag_referenced_rising_en | Set 1 to AC-coupled activity, 0 for DC | ++---------------------------------------------+-----------------------------------------+ +| in_accel_x_thresh_falling_en | Enable inactivity detection on X axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_y_thresh_falling_en | Enable inactivity detection on Y axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_z_thresh_falling_en | Enable inactivity detection on Z axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_falling_period | Inactivity time in seconds | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_falling_value | Inactivity threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_x_thresh_rising_en | Enable activity detection on X axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_y_thresh_rising_en | Enable activity detection on Y axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_z_thresh_rising_en | Enable activity detection on Z axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_thresh_rising_value | Activity threshold value in 62.5/LSB | ++---------------------------------------------+-----------------------------------------+ +| in_accel_x_gesture_singletap_en | Enable single tap detection on X axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_y_gesture_singletap_en | Enable single tap detection on Y axis | ++---------------------------------------------+-----------------------------------------+ +| in_accel_z_gesture_singletap_en | Enable single tap detection on Z axis | ++---------------------------------------------+-----------------------------------------+ + +Find a detailed description of a particular functionality in the sensor +datasheet. + +Setting the ODR explicitly will result in estimated adjusted default values +for the inactivity time detection, where higher frequencies shall default to +longer wait periods, and vice versa. It is also possible to explicetly +configure inactivity wait times, if the defaulting approach does not match +application requirements. Setting 0 here, will fall back to default setting. + +The g range configuration also tries to estimate activity and inactivity +thresholds when switching to another g range. The default range will be +factorized by the relation of old range divided by new range. The value never +becomes 0 and will be at least 1 and at most 255 i.e. 62.5g/LSB according to +the datasheet. Nevertheless activity and inactivity thresholds can be +overwritten by explicit values. + +When activity and inactivity events are both enabled, the driver automatically +will implement its hysteresis solution by setting link bit and autosleep bit. +The link bit serially links the activity and inactivity functions. On the other +side, the autosleep function switches the sensor to sleep mode if the +inactivity function is enabled. This will reduce current consumption to the +sub-12.5Hz rate. + +In dc-coupled operation, the current acceleration magnitude is compared +directly with THRESH_ACT and THRESH_INACT registers to determine whether +activity or inactivity was detected. In ac-coupled operation for activity +detection, the acceleration value at the start of activity detection is taken +as a reference value. New samples are then compared to this reference value. +Note, ac-coupling and dc-coupling are individually set for activity and/or +inactivity detection. Activity and inactivity detection are dependent on the +direction, i.e. the x/y/z axis where this driver generally enables all +directions. Also, the direction settings are particular to activity and +inactivity detection, respectively. + +Single tap detection can be configured according to the datasheet by specifying +threshold and duration. If only the single tap is in use, the single tap +interrupt is triggered when the acceleration goes above threshold (i.e. DUR +start) and below the threshold, as long as duration is not exceeded. If single +tap and double tap are in use, the single tap is triggered when the doulbe tap +event has been either validated or invalidated. + +For double tap configure additionally window and latency in [us]. Latency +starts counting when the single tap goes below threshold and is a waiting +period, any spikes here are ignored for double tap detection. After latency, +the window starts. Any rise above threshold, with a consequent fall below +threshold within window time, rises a double tap signal when going below +threshold. + +Double tap event detection is best described in the datasheet. After a +single tap event was detected, a double tap event can be detected. Therefore the +signal must match several criteria, and detection can also considered invalid +for three reasons: +* If the suppress bit is set and when still in the tap latency period, any +measurement of acceleration spike above the tap threshold invalidates double tap +detection immediately, i.e. during latency must not occur spikes for double tap +detection when the suppress bit is set. +* A double tap event is considered invalid, if acceleration lies above the +threshold at the start of the window time for double tap. +* Additionally, double tap detection can be considered invalid, if an +acceleration exceeds the time limit for taps, set by duration register. +Note, since for double tap the same duration counts, i.e. when rising above +threshold, a consequent falling below threshold has to be within duration time. +Also note, the suppress bit is generally set when double tap is enabled. + +A free fall event will be detected if the signal goes below the configured +threshold, for the configured time [us]. + +Note, that activity/inactivy, as also freefall is recommended for 12.5 Hz ODR +up to 400 Hz. + +Usage examples +-------------- + +Show device name: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat name + adxl345 + +Show accelerometer channels value: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_raw + -1 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_y_raw + 2 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_z_raw + -253 + +Set calibration offset for accelerometer channels: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 0 + + root:/sys/bus/iio/devices/iio:device0> echo 50 > in_accel_x_calibbias + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 50 + +Given the 13-bit full resolution, the available ranges are calculated by the +following forumla: + +.. code-block:: bash + + (g * 2 * 9.80665) / (2^(resolution) - 1) * 100; for g := 2|4|8|16 + +Scale range configuration: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale + 0.478899 + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale_available + 0.478899 0.957798 1.915595 3.831190 + + root:/sys/bus/iio/devices/iio:device0> echo 1.915595 > ./in_accel_scale + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale + 1.915595 + +Set output data rate (ODR): + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_sampling_frequency + 200.000000 + + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_sampling_frequency_available + 0.097000 0.195000 0.390000 0.781000 1.562000 3.125000 6.250000 12.500000 25.000000 50.000000 100.000000 200.000000 400.000000 800.000000 1600.000000 3200.000000 + + root:/sys/bus/iio/devices/iio:device0> echo 1.562000 > ./in_accel_sampling_frequency + root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_sampling_frequency + 1.562000 + +Configure one or several events: + +.. code-block:: bash + + root:> cd /sys/bus/iio/devices/iio:device0 + + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./buffer0/in_accel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./buffer0/in_accel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./buffer0/in_accel_z_en + + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./scan_elements/in_accel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./scan_elements/in_accel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./scan_elements/in_accel_z_en + + root:/sys/bus/iio/devices/iio:device0> echo 14 > ./in_accel_x_calibbias + root:/sys/bus/iio/devices/iio:device0> echo 2 > ./in_accel_y_calibbias + root:/sys/bus/iio/devices/iio:device0> echo -250 > ./in_accel_z_calibbias + + root:/sys/bus/iio/devices/iio:device0> echo 24 > ./buffer0/length + + ## activity, threshold [62.5/LSB] + root:/sys/bus/iio/devices/iio:device0> echo 6 > ./events/in_accel_thresh_rising_value + + ## inactivity, threshold, [62.5/LSB] + root:/sys/bus/iio/devices/iio:device0> echo 4 > ./events/in_accel_thresh_falling_value + + ## inactivity, time [s] + root:/sys/bus/iio/devices/iio:device0> echo 3 > ./events/in_accel_thresh_falling_period + + ## singletap, threshold + root:/sys/bus/iio/devices/iio:device0> echo 35 > ./events/in_accel_gesture_singletap_value + + ## singletap, duration [us] + root:/sys/bus/iio/devices/iio:device0> echo 0.001875 > ./events/in_accel_gesture_singletap_timeout + + ## doubletap, window [us] + root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_reset_timeout + + ## doubletap, latent [us] + root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_tap2_min_delay + + ## freefall, threshold [62.5/LSB] + root:/sys/bus/iio/devices/iio:device0> echo 8 > ./events/in_accel_mag_falling_value + + ## freefall, time [ms] + root:/sys/bus/iio/devices/iio:device0> echo 1.25 > ./events/in_accel_mag_falling_period + + ## activity, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_thresh_rising_en + + ## inactivity, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_thresh_falling_en + + ## freefall, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_mag_falling_en + + ## singletap, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_x_gesture_singletap_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_y_gesture_singletap_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_z_gesture_singletap_en + + ## doubletap, enable + root:/sys/bus/iio/devices/iio:device0> echo 1 > ./events/in_accel_gesture_doubletap_en + +Verify incoming events: + +.. code-block:: bash + + root:# iio_event_monitor adxl345 + Found IIO device with name adxl345 with device number 0 + Event: time: 1739063415957073383, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063415963770218, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063416002563061, type: accel(z), channel: 0, evtype: gesture, direction: singletap + Event: time: 1739063426271128739, type: accel(x|y|z), channel: 0, evtype: thresh, direction: falling + Event: time: 1739063436539080713, type: accel(x|y|z), channel: 0, evtype: thresh, direction: falling + Event: time: 1739063438357970381, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446726161586, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446727892670, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446743019768, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446744650696, type: accel(z), channel: 0, evtype: thresh, direction: rising + Event: time: 1739063446763559386, type: accel(z), channel: 0, evtype: gesture, direction: singletap + Event: time: 1739063448818126480, type: accel(x|y|z), channel: 0, evtype: thresh, direction: falling + ... + +3. Device buffers +================= + +This driver supports IIO buffers. + +All devices support retrieving the raw acceleration and temperature measurements +using buffers. + +Usage examples +-------------- + +Select channels for buffer read: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_accel_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_accel_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_accel_z_en + +Set the number of samples to be stored in the buffer: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 10 > buffer/length + +Enable buffer readings: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > buffer/enable + +Obtain buffered data: + +.. code-block:: bash + + root:> iio_readdev -b 16 -s 1024 adxl345 | hexdump -d + WARNING: High-speed mode not enabled + 0000000 00003 00012 00013 00005 00010 00011 00005 00011 + 0000010 00013 00004 00012 00011 00003 00012 00014 00007 + 0000020 00011 00013 00004 00013 00014 00003 00012 00013 + 0000030 00004 00012 00013 00005 00011 00011 00005 00012 + 0000040 00014 00005 00012 00014 00004 00010 00012 00004 + 0000050 00013 00011 00003 00011 00012 00005 00011 00013 + 0000060 00003 00012 00012 00003 00012 00012 00004 00012 + 0000070 00012 00003 00013 00013 00003 00013 00012 00005 + 0000080 00012 00013 00003 00011 00012 00005 00012 00013 + 0000090 00003 00013 00011 00005 00013 00014 00003 00012 + 00000a0 00012 00003 00012 00013 00004 00012 00015 00004 + 00000b0 00014 00011 00003 00014 00013 00004 00012 00011 + 00000c0 00004 00012 00013 00004 00014 00011 00004 00013 + 00000d0 00012 00002 00014 00012 00005 00012 00013 00005 + 00000e0 00013 00013 00003 00013 00013 00005 00012 00013 + 00000f0 00004 00014 00015 00005 00012 00011 00005 00012 + ... + +See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +data is structured. + +4. IIO Interfacing Tools +======================== + +See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO +interfacing tools.