From patchwork Thu Feb 17 16:26:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750418 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2E41C4332F for ; Thu, 17 Feb 2022 16:27:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243111AbiBQQ1j (ORCPT ); Thu, 17 Feb 2022 11:27:39 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:59848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243105AbiBQQ1i (ORCPT ); Thu, 17 Feb 2022 11:27:38 -0500 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E1259AD9B; Thu, 17 Feb 2022 08:27:23 -0800 (PST) Received: by mail-ed1-x52e.google.com with SMTP id q17so10663196edd.4; Thu, 17 Feb 2022 08:27:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KSuUmbEeDLXS2kqjz3k+0c9MegG2g3h/fyFjY4bgFs8=; b=mSxm2wBBQzSJV97jikv7wxwCMeufivfazFsWydlImISPPEnfh857cWA76sowIR3aja fWJWAulXIkG1xOp3BpwqiBYVbHbCWKFFTY6DLpDdV+BBjdtT0O5FuxVftg3VjrdfS97r AtqlGZfyab+WbEQYD5RCoM6LEF5uDBag3AjlcHcrKxGfpFUXDTUMjrQebqd+33SR7doV G1RURDhxW4CUsGDpyTYHHKI1CyCau6XCYnSFgug+6/pkAm7SBxwCqH6LStIyqGij0QLo MwhCax51GKjbtV/6fD3Z/mU8ceb6u/gofePHvlDTbLrfo6aFDRZI3lg8lSn30ZMI+uss LFkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KSuUmbEeDLXS2kqjz3k+0c9MegG2g3h/fyFjY4bgFs8=; b=4AdJkfpW7IiXPunMAxZD3MuZvYUi+vVdhRoEDgRdBQTPoC3cc3UH54Wn5rzx3YI7fy //m/FrJ6vVnof41fBgimI9K2lamXVSrO4+HFW8bdCXdM1jSnOMpnRtiWpwGUHn43+zAT PaeRB16gTFsqJDRoaRAVjUfapZFLlI5jbhMOzT+qqg2ibh1WxtJNVNJtG/DxCyC2CWeV lo6vlfjGK2JbIfDOZCCwrHVz1XVUUVLN7JiXBj0i5TzGOycwSfloXN0MIRZ7gGVdLYFJ vWOa799Ft6PHeu6ACESpJNeGSpiFJ1i7Vfc4pJ/obQYaD1e3hRBi0A5WmWnecwF+FfA1 mczw== X-Gm-Message-State: AOAM530zQUT/bLyiwiQpTfeW2Hch1UvRLhhbsyLJHXlrzdJl/Y/qzHO0 mZWeJmadPsOmg1J1hfmR6bU= X-Google-Smtp-Source: ABdhPJzkLQa3VdybrilYvKXCKp+OQHX1LXQ2FfusdVo0VE/2wF9mlpVipP1dalBvEXpMNqYLAtU1Ig== X-Received: by 2002:a05:6402:5110:b0:403:dbc0:2a47 with SMTP id m16-20020a056402511000b00403dbc02a47mr3555636edd.197.1645115241997; Thu, 17 Feb 2022 08:27:21 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:21 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 01/13] iio: add modifiers for linear acceleration Date: Thu, 17 Feb 2022 17:26:58 +0100 Message-Id: <20220217162710.33615-2-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch is preparatory for adding the Bosh BNO055 IMU driver. The said IMU can report raw accelerations (among x, y and z axis) as well as the so called "linear accelerations" (again, among x, y and z axis) which is basically the acceleration after subtracting gravity. This patch adds IIO_MOD_LINEAR_X, IIO_MOD_LINEAR_Y and IIO_MOD_LINEAR_Z modifiers to te IIO core. Signed-off-by: Andrea Merello --- drivers/iio/industrialio-core.c | 3 +++ include/uapi/linux/iio/types.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index e1ed44dec2ab..252dbe3444cc 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -134,6 +134,9 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_ETHANOL] = "ethanol", [IIO_MOD_H2] = "h2", [IIO_MOD_O2] = "o2", + [IIO_MOD_LINEAR_X] = "linear_x", + [IIO_MOD_LINEAR_Y] = "linear_y", + [IIO_MOD_LINEAR_Z] = "linear_z", }; /* relies on pairs of these shared then separate */ diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index 48c13147c0a8..387a1b5cd1a9 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -95,6 +95,9 @@ enum iio_modifier { IIO_MOD_ETHANOL, IIO_MOD_H2, IIO_MOD_O2, + IIO_MOD_LINEAR_X, + IIO_MOD_LINEAR_Y, + IIO_MOD_LINEAR_Z, }; enum iio_event_type { @@ -114,4 +117,3 @@ enum iio_event_direction { }; #endif /* _UAPI_IIO_TYPES_H_ */ - From patchwork Thu Feb 17 16:26:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750419 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D8ACC43219 for ; Thu, 17 Feb 2022 16:27:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243115AbiBQQ1l (ORCPT ); Thu, 17 Feb 2022 11:27:41 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:59914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243107AbiBQQ1i (ORCPT ); Thu, 17 Feb 2022 11:27:38 -0500 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76A619A9A3; Thu, 17 Feb 2022 08:27:24 -0800 (PST) Received: by mail-ed1-x535.google.com with SMTP id f17so10666183edd.2; Thu, 17 Feb 2022 08:27:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YEIQSgJVSRiyLY5DqxsBH1nNB/kYSQxeQBbJ8QX8vA0=; b=bvOJLcYKGITSELAcwDgWspmn0xZgmxZI7Nv/X66sLBdVghQz6iPNRclyg2ebH5zXcy npWVakKWsKQVr51V2j8czIaPaWOoWjHA2y03HDVRDC1IhcfsQC2O5z8qpHgQUOPVPmuA PA+CP9zNcWiIGDHKoOOmrs0JtqqJ4HMfATRLHtCnqeyStjnr+nIRNqCXb4hD/JIOtfhl w6aqt7di7XD3ZEYKeWA5E9annkgOsZBzmiCbtyp03aO80L936nn9q+HCj7MhoDmrC3cj cp5VeA6k63TrgbceXIdGlfd+WQ4ujEGd3d0lQM63oXmz/LFiayjiKqtGbcC+A+l1/eiq x7LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YEIQSgJVSRiyLY5DqxsBH1nNB/kYSQxeQBbJ8QX8vA0=; b=Aj3MicKaRy0p1og3uKciHudf9EXVvzfKT2qLgqUsSbFNHbvSo8vi8kMabR1uHi9XZp xKHvaWF0l6qSbt/bHIX7HhRMNFwitJkZzCopiBL4TOQZRRQHVoMemu5S722DOQtHuNUN G6Ny96Pe6OJ3vGsuUs/0mUT6B51LHzyP64I1uJ80taHj1C7u2lerAQs8sEOs1ChbWKG3 rr/UApYIwPDC3K1QNABHwrAViNIknmxoPhQgOS5DrhTSugzHnF0U8pSKPQ5ZQKLYh6j0 OEcI9MlxEl3n8bEzDAFDcZOQzSo6EHWR57Y4KZsRSejAMq8uGDOMpwjr5x5G4x/eRscU KT0A== X-Gm-Message-State: AOAM533Cmh+o6Mky/zCtow5FD9YUmAEW8x2/8C5Pvfz8FaouHk8zeYpl zeV3j3ScfopAEv+beP1zzC4= X-Google-Smtp-Source: ABdhPJxVjoZHB48h1w82ew1WNRxVUjZMMmkdyAg6jnc0RRRtIP3WvKGONRJD+LoRrD6bmxkCOpz3lw== X-Received: by 2002:a05:6402:17d9:b0:410:aaaf:6467 with SMTP id s25-20020a05640217d900b00410aaaf6467mr3590082edy.38.1645115242996; Thu, 17 Feb 2022 08:27:22 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:22 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 02/13] iio: document linear acceleration modifiers Date: Thu, 17 Feb 2022 17:26:59 +0100 Message-Id: <20220217162710.33615-3-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch introduces ABI documentation for new iio modifiers used for reporting "linear acceleration" measures. Signed-off-by: Andrea Merello --- Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index c551301b33f1..b2fb4d9abcd1 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -233,6 +233,15 @@ Description: Has all of the equivalent parameters as per voltageY. Units after application of scale and offset are m/s^2. +What: /sys/bus/iio/devices/iio:deviceX/in_accel_linear_x_raw +What: /sys/bus/iio/devices/iio:deviceX/in_accel_linear_y_raw +What: /sys/bus/iio/devices/iio:deviceX/in_accel_linear_z_raw +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + As per in_accel_X_raw attributes, but minus the gravity + acceleration. + What: /sys/bus/iio/devices/iio:deviceX/in_gravity_x_raw What: /sys/bus/iio/devices/iio:deviceX/in_gravity_y_raw What: /sys/bus/iio/devices/iio:deviceX/in_gravity_z_raw From patchwork Thu Feb 17 16:27:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750420 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C602C4321E for ; Thu, 17 Feb 2022 16:27:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243119AbiBQQ1m (ORCPT ); Thu, 17 Feb 2022 11:27:42 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243112AbiBQQ1l (ORCPT ); Thu, 17 Feb 2022 11:27:41 -0500 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DF1A9A9A3; Thu, 17 Feb 2022 08:27:27 -0800 (PST) Received: by mail-ed1-x52c.google.com with SMTP id c6so7892591edk.12; Thu, 17 Feb 2022 08:27:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AUSQzyWXxaMbI2StNt6fPks9oaF2ya4dbWkQ8oow7Q8=; b=K8tHi1q0F0MS6DAc5fxAjW/gdRCCAZYCmMJAHFtP6RpvEnUE3b+opet9gSno4ViEo6 OD5z2sgTr7j0w19UzkMRzRJEjVkkEeUm0cyzz9/S6KLeaR7yYwseeDGJID/oIxRWWumZ bzeTm5NE5MCoXKR2JgUX8HmyBR6kXcPlfHcOscUqj7Exc81/zR10bMiPf04Yo5JOzmco kS2nfSubtHGnBhsrPyxVYUsl2thHNsA3pe5wvSbn07MnoRm94HQ1+R8oYRh/CozHGGcr CZUAYygKdfMWE7BX7rcLAQ+IXRaVKcideTLWr/aPR6A6sJ6vG9fLxBMLEesqivBOc1iY DnUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AUSQzyWXxaMbI2StNt6fPks9oaF2ya4dbWkQ8oow7Q8=; b=dKZk17kEeKxD9szda2hWk84gsFXTbGgN9S5KUd047p1g9gxVYpO5hutRy/PTmuNcu+ yPYYPZr6to5jItJXxK2Kw+nu2wR4wMkwrlRe2Yj0KHSFnKai5AdaL6Eke8nyFLbRngYn d4cWre1tIkmVA9RnC468PUYpAJ/Z7PPBRl3IlbHSU1nPzKfthtm5jERRJeD/oFytG4GW Xw64a18R4I6KSzRxKPO3OXb8W7d3OA3Hc2wKE996U6m+V5qaBHUULcfd35Hp7M9lr1WM R0kFgUZXxFHWv/KUd1LL4zIgdBYkM7N6dolPPJ4/ZNQXkAEY94JSk8vb17Qq6ZC5mRjW 4efQ== X-Gm-Message-State: AOAM5324qjMSMeOgYhCJfKy3fQ6g7meLwkSRJDgM6+ic2IKqfP4xTOnH OjMXc2Vn+nm2m/z6Ngo4M/8= X-Google-Smtp-Source: ABdhPJwrqGq7kWppBcG1ujF2Syq7eb/BIMxC6J3mTZy1sFxDccRqTGjlc6CR9+J99QAXAutgIc4Ayg== X-Received: by 2002:a05:6402:2922:b0:40f:7241:74d4 with SMTP id ee34-20020a056402292200b0040f724174d4mr3522116edb.43.1645115245788; Thu, 17 Feb 2022 08:27:25 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:23 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 03/13] iio: event_monitor: add linear acceleration modifiers Date: Thu, 17 Feb 2022 17:27:00 +0100 Message-Id: <20220217162710.33615-4-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Signed-off-by: Andrea Merello --- tools/iio/iio_event_monitor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index b94a16ba5c6c..84c90b8fdd91 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -121,6 +121,9 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_PM4] = "pm4", [IIO_MOD_PM10] = "pm10", [IIO_MOD_O2] = "o2", + [IIO_MOD_LINEAR_X] = "linear_x", + [IIO_MOD_LINEAR_Y] = "linear_y", + [IIO_MOD_LINEAR_Z] = "linear_z", }; static bool event_is_known(struct iio_event_data *event) From patchwork Thu Feb 17 16:27:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750421 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DCBFC433FE for ; Thu, 17 Feb 2022 16:27:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243125AbiBQQ1q (ORCPT ); Thu, 17 Feb 2022 11:27:46 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243123AbiBQQ1m (ORCPT ); Thu, 17 Feb 2022 11:27:42 -0500 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16FB19AD9B; Thu, 17 Feb 2022 08:27:28 -0800 (PST) Received: by mail-ej1-x62e.google.com with SMTP id a23so8581664eju.3; Thu, 17 Feb 2022 08:27:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Hw2Jui/kNYseL0KVgLc40Ac/EwZ3g3QErB9gIo0wOQA=; b=gYc3fv2qUFO4rr7likmfGjcDiFRd/MCKILMn9lx45vtGgNRBOEjRGr5N+t0jiMK9z8 1O6KFmPVf2BifwDmhsLc/J7T/5+YNJmNoDlhwVTDiXMFIuAZMXAhp648LpH3e08rDjI2 v9b5QOr99k5wXny8y5kS+AR8NAiU3kVOWXOOX5LXkD2usg8gSgAzgumzRv3eovBUQhk3 2PyirFoxMInET8M5l4cMlMaJrayah4awWIvfmIjiaE6NVWyGWVJFHIUM2v0tQusN75nb oQsX5gmWTjORILkOe0z3TLgXZ6d5BiEBe1yXG18lZN14oXDBrgDmffNb4vLf0sOVP7tp iPsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Hw2Jui/kNYseL0KVgLc40Ac/EwZ3g3QErB9gIo0wOQA=; b=MUE2eOXu9ld9iqF9Q6vH1i56LH7SBp4szgW2YKexIOgmHYNb8ssXRYJOb+dfC6aplQ o487e+d5ubxO4pX31EdataolCBo26aQpjMwEWAAHOn5GtVaQrTk6v7xtonFdh4WX/YS8 UqLnPPksaWtLaPN/ZOIZzVdSbcoWjDcYTvasicigbzAu2SWOyUE+p8qbpk7luG+aECz7 jDOhAeZFRwNPwUJ/NL02pzbAJrwSbTZfwNobdwaiJzPup6URp8iRJCgQ2Yt+5u0gBx++ NftL1EKLzFlTvQOA/uElttDfxBPAwmQd5bxtuWOu60BFnHXXZpMS9CgRQ3LM1SAEYxnt yAGQ== X-Gm-Message-State: AOAM532vvYv6Cq1F5ZfNn4S4FHo1E0Tc0UF0AscpXyM5CFkbx2r1N2x9 rHisZYyUp3LluFez0ByVtDY= X-Google-Smtp-Source: ABdhPJwV2JJ0iu1JHh4CbKZB2JCiDqotDzX1Wvux/dnMjKVBHhliMnFjimIDo/Xvf+cDESseEUJnrw== X-Received: by 2002:a17:906:7714:b0:6ba:8a6a:b464 with SMTP id q20-20020a170906771400b006ba8a6ab464mr2961475ejm.613.1645115246662; Thu, 17 Feb 2022 08:27:26 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:26 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 04/13] iio: add modifers for pitch, yaw, roll Date: Thu, 17 Feb 2022 17:27:01 +0100 Message-Id: <20220217162710.33615-5-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch adds modifiers for reporting rotations as euler angles (i.e. yaw, pitch and roll). Signed-off-by: Andrea Merello --- drivers/iio/industrialio-core.c | 3 +++ include/uapi/linux/iio/types.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 252dbe3444cc..8a5ba32d3963 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -137,6 +137,9 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_LINEAR_X] = "linear_x", [IIO_MOD_LINEAR_Y] = "linear_y", [IIO_MOD_LINEAR_Z] = "linear_z", + [IIO_MOD_PITCH] = "pitch", + [IIO_MOD_YAW] = "yaw", + [IIO_MOD_ROLL] = "roll", }; /* relies on pairs of these shared then separate */ diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index 387a1b5cd1a9..4a7481cdaf7a 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -98,6 +98,9 @@ enum iio_modifier { IIO_MOD_LINEAR_X, IIO_MOD_LINEAR_Y, IIO_MOD_LINEAR_Z, + IIO_MOD_PITCH, + IIO_MOD_YAW, + IIO_MOD_ROLL, }; enum iio_event_type { From patchwork Thu Feb 17 16:27:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750422 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E2A8C4332F for ; Thu, 17 Feb 2022 16:27:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243146AbiBQQ1r (ORCPT ); Thu, 17 Feb 2022 11:27:47 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243131AbiBQQ1n (ORCPT ); Thu, 17 Feb 2022 11:27:43 -0500 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 001109D049; Thu, 17 Feb 2022 08:27:28 -0800 (PST) Received: by mail-ed1-x529.google.com with SMTP id u18so10609758edt.6; Thu, 17 Feb 2022 08:27:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/1lf4FhtmSrjRervVhT4u2h9DSLojyjyGeKukIuGLl8=; b=qA9O4jM8Rpp0h+8je5ee0Y3ZvLuG8MEKeZehi2TTPg4vDluFqwbXuIyxtHN/4SYMPT qYyuhYn5jvDdTfiNJW+Bl/YnFh+pDRiK4v2EdjA0KvW52zAZjHQpoC7d8Y5wyDBdqwlj EbsZOxN1MxFpp5zlRxb2iYjDgUHH6ICEKYRQeQu1fWgUmgtSxYay0zNSrJCehDYwLoAh Yg7mQUSk5kTDMP7STeoiJ/05w0gXMs6BvEsTHIdRin/rCipzA02dWuzo62R2rnVB6BOe zmwWzfGQNrMLP+mo+J3FTH5WB8nIgVkHbIEEoFKq1YPov2uvEKuMqmzT/dTn4qpWnQZW 1Xhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/1lf4FhtmSrjRervVhT4u2h9DSLojyjyGeKukIuGLl8=; b=MsC0h9idjGL60Wf0kYN9vGpGhrAthl9VMhNUUvyWh9mFChA+CXzWbZnl2vg/2UUvX8 pgvO1qSgXR2Q5nMdQQTftz/YOLA9Xoryz2RM9e9P+XBDs7QZcMM8AzPWqJnGP5PccrIj LeYWDif2bqx7QrfC6pQpAklstSswrUrAkA3lmtyqFMKV1cfpZdFmv6uOfFmBrDGN+nyq k4QyBYZr3/VE4VNe6jrxIj7FC66H2o1dLij1A8Va9dOT3S7mJxQhfKsVhAQpcl6s9Ky2 dsWP+Oazes7818H/QZWlgY6NGG3NkBrs7D6YKxdqVDLejbnnK7o642UopnXUYfqiLDzS yJ0g== X-Gm-Message-State: AOAM530MZGk2u1VxV8pF8B/5DVLkcXMpADd9wtcLsjKnwQ+lbYBWokrU TAsfRHTrGLvzyhy7JGtWJeg= X-Google-Smtp-Source: ABdhPJwK0dz8/t+csV+CCPJwfyJJVoOWYDkjjszr0PICbEDBT8ZSjFn9mcwd3hdKEwc3pl66vDdcBg== X-Received: by 2002:a05:6402:518b:b0:412:80a3:fb6e with SMTP id q11-20020a056402518b00b0041280a3fb6emr3588220edd.84.1645115247559; Thu, 17 Feb 2022 08:27:27 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:27 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 05/13] iio: document pitch, yaw, roll modifiers Date: Thu, 17 Feb 2022 17:27:02 +0100 Message-Id: <20220217162710.33615-6-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch introduces ABI documentation for new modifiers used for reporting rotations expressed as euler angles (i.e. yaw, pitch, roll). Signed-off-by: Andrea Merello --- Documentation/ABI/testing/sysfs-bus-iio | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index b2fb4d9abcd1..1b8d77577608 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -2008,3 +2008,12 @@ Description: Available range for the forced calibration value, expressed as: - a range specified as "[min step max]" + +What: /sys/bus/iio/devices/iio:deviceX/in_rot_yaw_raw +What: /sys/bus/iio/devices/iio:deviceX/in_rot_pitch_raw +What: /sys/bus/iio/devices/iio:deviceX/in_rot_roll_raw +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled) euler angles readings. Units after + application of scale are deg. From patchwork Thu Feb 17 16:27:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD601C4321E for ; Thu, 17 Feb 2022 16:27:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243153AbiBQQ1s (ORCPT ); Thu, 17 Feb 2022 11:27:48 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243135AbiBQQ1p (ORCPT ); Thu, 17 Feb 2022 11:27:45 -0500 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04A969D4FD; Thu, 17 Feb 2022 08:27:30 -0800 (PST) Received: by mail-ed1-x52b.google.com with SMTP id x5so10580035edd.11; Thu, 17 Feb 2022 08:27:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fyI2iByz/xYB8pZuuXPhbshZsKIQbcfM5MPfG9RLCsY=; b=nBs7uAcscx9WfUNJY3gcaoQY74z4LftQQuRgfAM8WoeXda5KHoWRwpyj9uvfpdhpYu vqQKGu3W67QhqnxQe/qthsJ5M3vO3kUiXdV69MaANkfZxLuQfqrylYxAACZZ3TLTGube AoNIol/LwnCNCuoPA9Vmpz07hsGheIE6HdWThoiSTzOT8PN0F4BkIaOaA2TKasmDwMZS ma2r+MJKiHyarg/iFhiccHBmTiWYX2aUShrYna0qSeeNV8uYp3D8cYUZueGPaXVK5VHD LEwyTzogmyaQxhVAUIi0CKuV5bbxaeYcdNrlSNDfGuh74hbuvNuwXgBWX7UZNMaMBs6+ tlDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fyI2iByz/xYB8pZuuXPhbshZsKIQbcfM5MPfG9RLCsY=; b=eJxnkxtp261jrXDwSrfIcIblp5l54K0Tn0gcwVQ8bBTq684Z5yAmqBISwhjPJhADNE N4pmrcTQrx0VPZbQq75dzPo4pwyGQRGuWgz0taGMUeDxCTnOdg6mXzYeiUXjSKChDYKR 3nv+Xn1fk+lAxqizTi2gNUr47hkkVQ0vRqwusC2rqMC/Fx/5UvRXuBy4kldy5PYgXbGc dUfIV9kenO+MYwDFhMNXmol1Oob1xWrxWAyqxSVD+Y5EfDQZRyyKhNKgCaN5XsTr3gHg 1GsY9bh529dwrSowRYNh4sJJYItyZJBszxyEELKhOGwYIbvMRxpbLIumxRdZsDKh/O24 lLRw== X-Gm-Message-State: AOAM532uN08CpIx/PBA2Wlc+XL+WVv+OI5ZktJSLcmz9D1nqS8xpyBre Xg4uGUgGXp+lfmcnyUYkbzM= X-Google-Smtp-Source: ABdhPJxSS5KNdV320jE2881gKcYrlsut0U5dhkFGzCu0fABv3gSNNHc+Dso7Q914nGnLlUPwIvWn7Q== X-Received: by 2002:aa7:c98a:0:b0:410:b8fa:6faa with SMTP id c10-20020aa7c98a000000b00410b8fa6faamr3508169edt.117.1645115248595; Thu, 17 Feb 2022 08:27:28 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:28 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 06/13] iio: event_monitor: add pitch, yaw and roll modifiers Date: Thu, 17 Feb 2022 17:27:03 +0100 Message-Id: <20220217162710.33615-7-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Signed-off-by: Andrea Merello --- tools/iio/iio_event_monitor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index 84c90b8fdd91..436ac2f6b907 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -124,6 +124,9 @@ static const char * const iio_modifier_names[] = { [IIO_MOD_LINEAR_X] = "linear_x", [IIO_MOD_LINEAR_Y] = "linear_y", [IIO_MOD_LINEAR_Z] = "linear_z", + [IIO_MOD_PITCH] = "pitch", + [IIO_MOD_YAW] = "yaw", + [IIO_MOD_ROLL] = "roll", }; static bool event_is_known(struct iio_event_data *event) From patchwork Thu Feb 17 16:27:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750427 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E813C433EF for ; Thu, 17 Feb 2022 16:27:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243112AbiBQQ1u (ORCPT ); Thu, 17 Feb 2022 11:27:50 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243150AbiBQQ1s (ORCPT ); Thu, 17 Feb 2022 11:27:48 -0500 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9FF9B1A86; Thu, 17 Feb 2022 08:27:31 -0800 (PST) Received: by mail-ej1-x635.google.com with SMTP id p9so8560809ejd.6; Thu, 17 Feb 2022 08:27:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=A3EjwscuJhX07Anv2LpIcUEeQBanQC9K6pRaBlzmh3M=; b=k58VHC/sKK/NdpRdbTlU3KCN5GuLliMI151egm/aqO6Tzwy3dG3fJLV+JyYZWi4kb2 PsFQKlm9UjmYjXk7LM8DYpCIerROC/rJh0b2HyV03y1AZ+gELgs0oF8enUpHMcLXFQfn 12wO5cL5nsserwhh4ZO2w9f/3EtRuArn5UBXsP2Z+ZPnrbAVH4e2c3IothMvXe8UQr1a 9BJwL+Q+sC8VFDd6qWoYnmVbvON8vWeTMcILQvXLedK3Isy7ASXi1qxOB3F8bCBhoRj8 oszaoS9MJrFypSWmocQVBvWZQEdy9phhy+I1xJuVvn5/G9iOHWapiDm0PrQlC1qPVial whEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=A3EjwscuJhX07Anv2LpIcUEeQBanQC9K6pRaBlzmh3M=; b=4z9UrJAQ4/gNgRu+cKsB+vVHCPgnHN5kn05oeSeUgUTbwn3LSeIDVTLHjHikX/fiSf ZCqglinv6wMusm9X1sPRJDOgx9ZeXpc2No/LVKbxrW6ZtXYowPOrxOAhbaaLMiQ08CBI u5bnMmQY7iVSDDRny4ztR5uB2RUQeJoomxS0Uya5hay2nfRxqRNUuYF7HNT+o6quPEFu cGG4FTdAfA2tvK55D2vBIjkNQJYbpxjbWi6fmLPfauPN/oIN9UFuOJ1huG9EhHVyDrE9 3QDY4kqAPfTKmlc242CWOei+qEKeWImgdEteOSpxEPyRv1XbdFwAgQFQD7LwoDz8kuQf FVvQ== X-Gm-Message-State: AOAM531Qv0AbR9sdOhTHczaNpvJQxyxAc5Vu9L0wXKQtt2h0h12cWfwA D4AYJkrHqw659I4lDRMJ4/E= X-Google-Smtp-Source: ABdhPJyRiNKE9Pkbv1hXousBKmv2Br8Un7jqgW4Tl2dQo4EAgOylO/G5KRFLpgx86tBGeu29ZTrA9A== X-Received: by 2002:a17:906:51d6:b0:6b5:1b44:98a with SMTP id v22-20020a17090651d600b006b51b44098amr2978297ejk.480.1645115249703; Thu, 17 Feb 2022 08:27:29 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:29 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 07/13] iio: imu: add Bosch Sensortec BNO055 core driver Date: Thu, 17 Feb 2022 17:27:04 +0100 Message-Id: <20220217162710.33615-8-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch adds a core driver for the BNO055 IMU from Bosch. This IMU can be connected via both serial and I2C busses; separate patches will add support for them. The driver supports "AMG" (Accelerometer, Magnetometer, Gyroscope) mode, that provides raw data from the said internal sensors, and a couple of "fusion" modes (i.e. the IMU also do calculations in order to provide euler angles, quaternions, linear acceleration and gravity measurements). In fusion modes the AMG data is still available (with some calibration refinements done by the IMU), but certain settings such as low pass filters cut-off frequency and sensors ranges are fixed, while in AMG mode they can be customized; this is why AMG mode can still be interesting. Signed-off-by: Andrea Merello --- drivers/iio/imu/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/bno055/Kconfig | 4 + drivers/iio/imu/bno055/Makefile | 3 + drivers/iio/imu/bno055/bno055.c | 1612 +++++++++++++++++++++++++++++++ drivers/iio/imu/bno055/bno055.h | 12 + 6 files changed, 1633 insertions(+) create mode 100644 drivers/iio/imu/bno055/Kconfig create mode 100644 drivers/iio/imu/bno055/Makefile create mode 100644 drivers/iio/imu/bno055/bno055.c create mode 100644 drivers/iio/imu/bno055/bno055.h diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig index 001ca2c3ff95..f1d7d4b5e222 100644 --- a/drivers/iio/imu/Kconfig +++ b/drivers/iio/imu/Kconfig @@ -52,6 +52,7 @@ config ADIS16480 ADIS16485, ADIS16488 inertial sensors. source "drivers/iio/imu/bmi160/Kconfig" +source "drivers/iio/imu/bno055/Kconfig" config FXOS8700 tristate diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile index c82748096c77..6eb612034722 100644 --- a/drivers/iio/imu/Makefile +++ b/drivers/iio/imu/Makefile @@ -15,6 +15,7 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o obj-y += bmi160/ +obj-y += bno055/ obj-$(CONFIG_FXOS8700) += fxos8700_core.o obj-$(CONFIG_FXOS8700_I2C) += fxos8700_i2c.o diff --git a/drivers/iio/imu/bno055/Kconfig b/drivers/iio/imu/bno055/Kconfig new file mode 100644 index 000000000000..d0ab3221fba5 --- /dev/null +++ b/drivers/iio/imu/bno055/Kconfig @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +config BOSCH_BNO055_IIO + tristate diff --git a/drivers/iio/imu/bno055/Makefile b/drivers/iio/imu/bno055/Makefile new file mode 100644 index 000000000000..56cc4de60a7e --- /dev/null +++ b/drivers/iio/imu/bno055/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o diff --git a/drivers/iio/imu/bno055/bno055.c b/drivers/iio/imu/bno055/bno055.c new file mode 100644 index 000000000000..881d08277356 --- /dev/null +++ b/drivers/iio/imu/bno055/bno055.c @@ -0,0 +1,1612 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IIO driver for Bosch BNO055 IMU + * + * Copyright (C) 2021 Istituto Italiano di Tecnologia + * Electronic Design Laboratory + * Written by Andrea Merello + * + * Portions of this driver are taken from the BNO055 driver patch + * from Vlad Dogaru which is Copyright (c) 2016, Intel Corporation. + * + * This driver is also based on BMI160 driver, which is: + * Copyright (c) 2016, Intel Corporation. + * Copyright (c) 2019, Martin Kelly. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "bno055.h" + +#define BNO055_FW_NAME "bno055-caldata" +#define BNO055_FW_EXT ".dat" +#define BNO055_FW_UID_NAME BNO055_FW_NAME "-%*phN" BNO055_FW_EXT +#define BNO055_FW_GENERIC_NAME (BNO055_FW_NAME BNO055_FW_EXT) + +/* common registers */ +#define BNO055_PAGESEL_REG 0x7 + +/* page 0 registers */ +#define BNO055_CHIP_ID_REG 0x0 +#define BNO055_CHIP_ID_MAGIC 0xA0 +#define BNO055_SW_REV_LSB_REG 0x4 +#define BNO055_SW_REV_MSB_REG 0x5 +#define BNO055_ACC_DATA_X_LSB_REG 0x8 +#define BNO055_ACC_DATA_Y_LSB_REG 0xA +#define BNO055_ACC_DATA_Z_LSB_REG 0xC +#define BNO055_MAG_DATA_X_LSB_REG 0xE +#define BNO055_MAG_DATA_Y_LSB_REG 0x10 +#define BNO055_MAG_DATA_Z_LSB_REG 0x12 +#define BNO055_GYR_DATA_X_LSB_REG 0x14 +#define BNO055_GYR_DATA_Y_LSB_REG 0x16 +#define BNO055_GYR_DATA_Z_LSB_REG 0x18 +#define BNO055_EUL_DATA_X_LSB_REG 0x1A +#define BNO055_EUL_DATA_Y_LSB_REG 0x1C +#define BNO055_EUL_DATA_Z_LSB_REG 0x1E +#define BNO055_QUAT_DATA_W_LSB_REG 0x20 +#define BNO055_LIA_DATA_X_LSB_REG 0x28 +#define BNO055_LIA_DATA_Y_LSB_REG 0x2A +#define BNO055_LIA_DATA_Z_LSB_REG 0x2C +#define BNO055_GRAVITY_DATA_X_LSB_REG 0x2E +#define BNO055_GRAVITY_DATA_Y_LSB_REG 0x30 +#define BNO055_GRAVITY_DATA_Z_LSB_REG 0x32 +#define BNO055_SCAN_CH_COUNT ((BNO055_GRAVITY_DATA_Z_LSB_REG - BNO055_ACC_DATA_X_LSB_REG) / 2) +#define BNO055_TEMP_REG 0x34 +#define BNO055_CALIB_STAT_REG 0x35 +#define BNO055_CALIB_STAT_MASK GENMASK(1, 0) +#define BNO055_CALIB_STAT_MAGN_SHIFT 0 +#define BNO055_CALIB_STAT_ACCEL_SHIFT 2 +#define BNO055_CALIB_STAT_GYRO_SHIFT 4 +#define BNO055_CALIB_STAT_SYS_SHIFT 6 +#define BNO055_SYS_ERR_REG 0x3A +#define BNO055_POWER_MODE_REG 0x3E +#define BNO055_POWER_MODE_NORMAL 0 +#define BNO055_SYS_TRIGGER_REG 0x3F +#define BNO055_SYS_TRIGGER_RST_SYS BIT(5) +#define BNO055_SYS_TRIGGER_CLK_SEL BIT(7) +#define BNO055_OPR_MODE_REG 0x3D +#define BNO055_OPR_MODE_CONFIG 0x0 +#define BNO055_OPR_MODE_AMG 0x7 +#define BNO055_OPR_MODE_FUSION_FMC_OFF 0xB +#define BNO055_OPR_MODE_FUSION 0xC +#define BNO055_UNIT_SEL_REG 0x3B +/* Android orientation mode means: pitch value decreases turning clockwise */ +#define BNO055_UNIT_SEL_ANDROID BIT(7) +#define BNO055_UNIT_SEL_GYR_RPS BIT(1) +#define BNO055_CALDATA_START 0x55 +#define BNO055_CALDATA_END 0x6A +#define BNO055_CALDATA_LEN 22 + +/* + * The difference in address between the register that contains the + * value and the register that contains the offset. This applies for + * accel, gyro and magn channels. + */ +#define BNO055_REG_OFFSET_ADDR 0x4D + +/* page 1 registers */ +#define PG1(x) ((x) | 0x80) +#define BNO055_ACC_CONFIG_REG PG1(0x8) +#define BNO055_ACC_CONFIG_LPF_MASK GENMASK(4, 2) +#define BNO055_ACC_CONFIG_RANGE_MASK GENMASK(1, 0) +#define BNO055_MAG_CONFIG_REG PG1(0x9) +#define BNO055_MAG_CONFIG_HIGHACCURACY 0x18 +#define BNO055_MAG_CONFIG_ODR_MASK GENMASK(2, 0) +#define BNO055_GYR_CONFIG_REG PG1(0xA) +#define BNO055_GYR_CONFIG_RANGE_MASK GENMASK(2, 0) +#define BNO055_GYR_CONFIG_LPF_MASK GENMASK(5, 3) +#define BNO055_GYR_AM_SET_REG PG1(0x1F) +#define BNO055_UID_LOWER_REG PG1(0x50) +#define BNO055_UID_HIGHER_REG PG1(0x5F) +#define BNO055_UID_LEN 16 + +struct bno055_sysfs_attr { + int *vals; + int len; + int *fusion_vals; + int *hw_xlate; + int type; +}; + +#define BNO055_ATTR_VALS(...) \ + .vals = (int[]){ __VA_ARGS__}, \ + .len = ARRAY_SIZE(((int[]){__VA_ARGS__})) + +static struct bno055_sysfs_attr bno055_acc_lpf = { + BNO055_ATTR_VALS(7, 810000, 15, 630000, + 31, 250000, 62, 500000, 125, 0, + 250, 0, 500, 0, 1000, 0), + .fusion_vals = (int[]){62, 500000}, + .type = IIO_VAL_INT_PLUS_MICRO +}; + +static struct bno055_sysfs_attr bno055_acc_range = { + /* G: 2, 4, 8, 16 */ + BNO055_ATTR_VALS(1962, 3924, 7848, 15696), + .fusion_vals = (int[]){3924}, /* 4G */ + .type = IIO_VAL_INT +}; + +/* + * Theoretically the IMU should return data in a given (i.e. fixed) unit + * regardless the range setting. This happens for the accelerometer, but not for + * the gyroscope; the gyroscope range setting affects the scale. + * This is probably due to this[0] bug. + * For this reason we map the internal range setting onto the standard IIO scale + * attribute for gyro. + * Since the bug[0] may be fixed in future, we check for the IMU FW version and + * eventually warn the user. + * Currently we just't don't care about "range" attributes for gyro. + * + * [0] https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BNO055-Wrong-sensitivity-resolution-in-datasheet/td-p/10266 + */ +static struct bno055_sysfs_attr bno055_gyr_scale = { + /* + * dps = hwval * (dps_range/2^15) + * rps = hwval * (rps_range/2^15) + * = hwval * (dps_range/(2^15 * k)) + * where k is rad-to-deg factor + */ + BNO055_ATTR_VALS(125, 1877467, 250, 1877467, + 500, 1877467, 1000, 1877467, + 2000, 1877467), + .fusion_vals = (int[]){1, 900}, + .hw_xlate = (int[]){4, 3, 2, 1, 0}, + .type = IIO_VAL_FRACTIONAL +}; + +static struct bno055_sysfs_attr bno055_gyr_lpf = { + BNO055_ATTR_VALS(12, 23, 32, 47, 64, 116, 230, 523), + .fusion_vals = (int[]){32}, + .hw_xlate = (int[]){5, 4, 7, 3, 6, 2, 1, 0}, + .type = IIO_VAL_INT +}; + +static struct bno055_sysfs_attr bno055_mag_odr = { + BNO055_ATTR_VALS(2, 6, 8, 10, 15, 20, 25, 30), + .fusion_vals = (int[]){20}, + .type = IIO_VAL_INT +}; + +struct bno055_priv { + struct regmap *regmap; + struct device *dev; + struct clk *clk; + int operation_mode; + int xfer_burst_break_thr; + struct mutex lock; + u8 uid[BNO055_UID_LEN]; + struct gpio_desc *reset_gpio; + bool sw_reset; + struct { + __le16 chans[BNO055_SCAN_CH_COUNT]; + s64 timestamp __aligned(8); + } buf; +}; + +static bool bno055_regmap_volatile(struct device *dev, unsigned int reg) +{ + /* data and status registers */ + if (reg >= BNO055_ACC_DATA_X_LSB_REG && reg <= BNO055_SYS_ERR_REG) + return true; + + /* when in fusion mode, config is updated by chip */ + if (reg == BNO055_MAG_CONFIG_REG || + reg == BNO055_ACC_CONFIG_REG || + reg == BNO055_GYR_CONFIG_REG) + return true; + + /* calibration data may be updated by the IMU */ + if (reg >= BNO055_CALDATA_START && reg <= BNO055_CALDATA_END) + return true; + return false; +} + +static bool bno055_regmap_readable(struct device *dev, unsigned int reg) +{ + /* unnamed PG0 reserved areas */ + if ((reg < PG1(0) && reg > BNO055_CALDATA_END) || + reg == 0x3C) + return false; + + /* unnamed PG1 reserved areas */ + if (reg > PG1(BNO055_UID_HIGHER_REG) || + (reg < PG1(BNO055_UID_LOWER_REG) && reg > PG1(BNO055_GYR_AM_SET_REG)) || + reg == PG1(0xE) || + (reg < PG1(BNO055_PAGESEL_REG) && reg >= PG1(0x0))) + return false; + return true; +} + +static bool bno055_regmap_writeable(struct device *dev, unsigned int reg) +{ + /* + * Unreadable registers are indeed reserved; there are no WO regs + * (except for a single bit in SYS_TRIGGER register) + */ + if (!bno055_regmap_readable(dev, reg)) + return false; + + /* data and status registers */ + if (reg >= BNO055_ACC_DATA_X_LSB_REG && reg <= BNO055_SYS_ERR_REG) + return false; + + /* IDs areas */ + if (reg < BNO055_PAGESEL_REG || + (reg <= BNO055_UID_HIGHER_REG && reg >= BNO055_UID_LOWER_REG)) + return false; + + return true; +} + +static const struct regmap_range_cfg bno055_regmap_ranges[] = { + { + .range_min = 0, + .range_max = 0x7f * 2, + .selector_reg = BNO055_PAGESEL_REG, + .selector_mask = GENMASK(7, 0), + .selector_shift = 0, + .window_start = 0, + .window_len = 0x80 + }, +}; + +const struct regmap_config bno055_regmap_config = { + .name = "bno055", + .reg_bits = 8, + .val_bits = 8, + .ranges = bno055_regmap_ranges, + .num_ranges = 1, + .volatile_reg = bno055_regmap_volatile, + .max_register = 0x80 * 2, + .writeable_reg = bno055_regmap_writeable, + .readable_reg = bno055_regmap_readable, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_GPL(bno055_regmap_config); + +/* must be called in configuration mode */ +int bno055_calibration_load(struct bno055_priv *priv, const u8 *data, int len) +{ + if (len != BNO055_CALDATA_LEN) { + dev_dbg(priv->dev, "Invalid calibration file size %zu (expected %d)", + len, BNO055_CALDATA_LEN); + return -EINVAL; + } + + dev_dbg(priv->dev, "loading cal data: %*ph", BNO055_CALDATA_LEN, data); + return regmap_bulk_write(priv->regmap, BNO055_CALDATA_START, + data, BNO055_CALDATA_LEN); +} + +static int bno055_operation_mode_do_set(struct bno055_priv *priv, + int operation_mode) +{ + int ret; + + ret = regmap_write(priv->regmap, BNO055_OPR_MODE_REG, + operation_mode); + if (ret) + return ret; + + msleep(20); + + return 0; +} + +static int bno055_system_reset(struct bno055_priv *priv) +{ + int ret; + + if (priv->reset_gpio) { + gpiod_set_value_cansleep(priv->reset_gpio, 0); + usleep_range(5000, 10000); + gpiod_set_value_cansleep(priv->reset_gpio, 1); + } else { + if (!priv->sw_reset) + return 0; + + ret = regmap_write(priv->regmap, BNO055_SYS_TRIGGER_REG, + BNO055_SYS_TRIGGER_RST_SYS); + if (ret) + return ret; + } + + regcache_drop_region(priv->regmap, 0x0, 0xff); + usleep_range(650000, 700000); + + return 0; +} + +static int bno055_init(struct bno055_priv *priv, const u8 *caldata, int len) +{ + int ret; + + ret = bno055_operation_mode_do_set(priv, BNO055_OPR_MODE_CONFIG); + if (ret) + return ret; + + ret = regmap_write(priv->regmap, BNO055_POWER_MODE_REG, + BNO055_POWER_MODE_NORMAL); + if (ret) + return ret; + + ret = regmap_write(priv->regmap, BNO055_SYS_TRIGGER_REG, + priv->clk ? BNO055_SYS_TRIGGER_CLK_SEL : 0); + if (ret) + return ret; + + /* use standard SI units */ + ret = regmap_write(priv->regmap, BNO055_UNIT_SEL_REG, + BNO055_UNIT_SEL_ANDROID | BNO055_UNIT_SEL_GYR_RPS); + if (ret) + return ret; + + if (caldata) { + ret = bno055_calibration_load(priv, caldata, len); + if (ret) + dev_warn(priv->dev, "failed to load calibration data with error %d", + ret); + } + + return 0; +} + +static ssize_t bno055_operation_mode_set(struct bno055_priv *priv, + int operation_mode) +{ + u8 caldata[BNO055_CALDATA_LEN]; + int ret; + + mutex_lock(&priv->lock); + + ret = bno055_operation_mode_do_set(priv, BNO055_OPR_MODE_CONFIG); + if (ret) + goto exit; + + if (operation_mode == BNO055_OPR_MODE_FUSION || + operation_mode == BNO055_OPR_MODE_FUSION_FMC_OFF) { + /* for entering fusiod mode, reset the chip to clear the algo state */ + ret = regmap_bulk_read(priv->regmap, BNO055_CALDATA_START, caldata, + BNO055_CALDATA_LEN); + if (ret) + goto exit; + + ret = bno055_system_reset(priv); + if (ret) + return ret; + + ret = bno055_init(priv, caldata, BNO055_CALDATA_LEN); + if (ret) + goto exit; + } + + ret = bno055_operation_mode_do_set(priv, operation_mode); + if (ret) + goto exit; + + priv->operation_mode = operation_mode; +exit: + mutex_unlock(&priv->lock); + return ret; +} + +static void bno055_uninit(void *arg) +{ + struct bno055_priv *priv = arg; + + /* stop the IMU */ + bno055_operation_mode_do_set(priv, BNO055_OPR_MODE_CONFIG); +} + +#define BNO055_CHANNEL(_type, _axis, _index, _address, _sep, _sh, _avail) { \ + .address = _address, \ + .type = _type, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | (_sep), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | (_sh), \ + .info_mask_shared_by_type_available = _avail, \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + .repeat = IIO_MOD_##_axis == IIO_MOD_QUATERNION ? 4 : 0 \ + }, \ +} + +/* scan indexes follow DATA register order */ +enum bmi160_scan_axis { + BNO055_SCAN_ACCEL_X, + BNO055_SCAN_ACCEL_Y, + BNO055_SCAN_ACCEL_Z, + BNO055_SCAN_MAGN_X, + BNO055_SCAN_MAGN_Y, + BNO055_SCAN_MAGN_Z, + BNO055_SCAN_GYRO_X, + BNO055_SCAN_GYRO_Y, + BNO055_SCAN_GYRO_Z, + BNO055_SCAN_YAW, + BNO055_SCAN_ROLL, + BNO055_SCAN_PITCH, + BNO055_SCAN_QUATERNION, + BNO055_SCAN_LIA_X, + BNO055_SCAN_LIA_Y, + BNO055_SCAN_LIA_Z, + BNO055_SCAN_GRAVITY_X, + BNO055_SCAN_GRAVITY_Y, + BNO055_SCAN_GRAVITY_Z, + BNO055_SCAN_TIMESTAMP, +}; + +static const struct iio_chan_spec bno055_channels[] = { + /* accelerometer */ + BNO055_CHANNEL(IIO_ACCEL, X, BNO055_SCAN_ACCEL_X, + BNO055_ACC_DATA_X_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY)), + BNO055_CHANNEL(IIO_ACCEL, Y, BNO055_SCAN_ACCEL_Y, + BNO055_ACC_DATA_Y_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY)), + BNO055_CHANNEL(IIO_ACCEL, Z, BNO055_SCAN_ACCEL_Z, + BNO055_ACC_DATA_Z_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY)), + /* gyroscope */ + BNO055_CHANNEL(IIO_ANGL_VEL, X, BNO055_SCAN_GYRO_X, + BNO055_GYR_DATA_X_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | + BIT(IIO_CHAN_INFO_SCALE)), + BNO055_CHANNEL(IIO_ANGL_VEL, Y, BNO055_SCAN_GYRO_Y, + BNO055_GYR_DATA_Y_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | + BIT(IIO_CHAN_INFO_SCALE)), + BNO055_CHANNEL(IIO_ANGL_VEL, Z, BNO055_SCAN_GYRO_Z, + BNO055_GYR_DATA_Z_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | + BIT(IIO_CHAN_INFO_SCALE)), + /* magnetometer */ + BNO055_CHANNEL(IIO_MAGN, X, BNO055_SCAN_MAGN_X, + BNO055_MAG_DATA_X_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ)), + BNO055_CHANNEL(IIO_MAGN, Y, BNO055_SCAN_MAGN_Y, + BNO055_MAG_DATA_Y_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ)), + BNO055_CHANNEL(IIO_MAGN, Z, BNO055_SCAN_MAGN_Z, + BNO055_MAG_DATA_Z_LSB_REG, BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_SAMP_FREQ), BIT(IIO_CHAN_INFO_SAMP_FREQ)), + /* euler angle */ + BNO055_CHANNEL(IIO_ROT, YAW, BNO055_SCAN_YAW, + BNO055_EUL_DATA_X_LSB_REG, 0, 0, 0), + BNO055_CHANNEL(IIO_ROT, ROLL, BNO055_SCAN_ROLL, + BNO055_EUL_DATA_Y_LSB_REG, 0, 0, 0), + BNO055_CHANNEL(IIO_ROT, PITCH, BNO055_SCAN_PITCH, + BNO055_EUL_DATA_Z_LSB_REG, 0, 0, 0), + /* quaternion */ + BNO055_CHANNEL(IIO_ROT, QUATERNION, BNO055_SCAN_QUATERNION, + BNO055_QUAT_DATA_W_LSB_REG, 0, 0, 0), + + /* linear acceleration */ + BNO055_CHANNEL(IIO_ACCEL, LINEAR_X, BNO055_SCAN_LIA_X, + BNO055_LIA_DATA_X_LSB_REG, 0, 0, 0), + BNO055_CHANNEL(IIO_ACCEL, LINEAR_Y, BNO055_SCAN_LIA_Y, + BNO055_LIA_DATA_Y_LSB_REG, 0, 0, 0), + BNO055_CHANNEL(IIO_ACCEL, LINEAR_Z, BNO055_SCAN_LIA_Z, + BNO055_LIA_DATA_Z_LSB_REG, 0, 0, 0), + + /* gravity vector */ + BNO055_CHANNEL(IIO_GRAVITY, X, BNO055_SCAN_GRAVITY_X, + BNO055_GRAVITY_DATA_X_LSB_REG, 0, 0, 0), + BNO055_CHANNEL(IIO_GRAVITY, Y, BNO055_SCAN_GRAVITY_Y, + BNO055_GRAVITY_DATA_Y_LSB_REG, 0, 0, 0), + BNO055_CHANNEL(IIO_GRAVITY, Z, BNO055_SCAN_GRAVITY_Z, + BNO055_GRAVITY_DATA_Z_LSB_REG, 0, 0, 0), + + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .scan_index = -1 + }, + IIO_CHAN_SOFT_TIMESTAMP(BNO055_SCAN_TIMESTAMP), +}; + +static int bno055_get_regmask(struct bno055_priv *priv, int *val, int *val2, + int reg, int mask, struct bno055_sysfs_attr *attr) +{ + const int shift = __ffs(mask); + int hwval, idx; + int ret; + int i; + + ret = regmap_read(priv->regmap, reg, &hwval); + if (ret) + return ret; + + idx = (hwval & mask) >> shift; + if (attr->hw_xlate) + for (i = 0; i < attr->len; i++) + if (attr->hw_xlate[i] == idx) { + idx = i; + break; + } + if (attr->type == IIO_VAL_INT) { + *val = attr->vals[idx]; + } else { /* IIO_VAL_INT_PLUS_MICRO or IIO_VAL_FRACTIONAL */ + *val = attr->vals[idx * 2]; + *val2 = attr->vals[idx * 2 + 1]; + } + + return attr->type; +} + +static int bno055_set_regmask(struct bno055_priv *priv, int val, int val2, + int reg, int mask, struct bno055_sysfs_attr *attr) +{ + const int shift = __ffs(mask); + int best_delta; + int req_val; + int tbl_val; + bool first; + int delta; + int hwval; + int ret; + int len; + int i; + + /* + * The closest value the HW supports is only one in fusion mode, + * and it is autoselected, so don't do anything, just return OK, + * as the closest possible value has been (virtually) selected + */ + if (priv->operation_mode != BNO055_OPR_MODE_AMG) + return 0; + + len = attr->len; + + /* + * We always get a request in INT_PLUS_MICRO, but we + * take care of the micro part only when we really have + * non-integer tables. This prevents 32-bit overflow with + * larger integers contained in integer tables. + */ + req_val = val; + if (attr->type != IIO_VAL_INT) { + if (val > 2147) + val = 2147; + len /= 2; + req_val = val * 1000000 + val2; + } + + first = true; + for (i = 0; i < len; i++) { + switch (attr->type) { + case IIO_VAL_INT: + tbl_val = attr->vals[i]; + break; + case IIO_VAL_INT_PLUS_MICRO: + WARN_ON(attr->vals[i * 2] > 2147); + tbl_val = attr->vals[i * 2] * 1000000 + + attr->vals[i * 2 + 1]; + break; + case IIO_VAL_FRACTIONAL: + WARN_ON(attr->vals[i * 2] > 4294); + tbl_val = attr->vals[i * 2] * 1000000 / + attr->vals[i * 2 + 1]; + break; + default: + return -EINVAL; + } + delta = abs(tbl_val - req_val); + if (first || delta < best_delta) { + best_delta = delta; + hwval = i; + first = false; + } + } + + if (attr->hw_xlate) + hwval = attr->hw_xlate[hwval]; + + ret = bno055_operation_mode_do_set(priv, BNO055_OPR_MODE_CONFIG); + if (ret) + return ret; + + ret = regmap_update_bits(priv->regmap, reg, mask, hwval << shift); + if (ret) + return ret; + + return bno055_operation_mode_do_set(priv, BNO055_OPR_MODE_AMG); +} + +static int bno055_read_simple_chan(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct bno055_priv *priv = iio_priv(indio_dev); + __le16 raw_val; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = regmap_bulk_read(priv->regmap, chan->address, + &raw_val, sizeof(raw_val)); + if (ret < 0) + return ret; + *val = (s16)le16_to_cpu(raw_val); + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + if (priv->operation_mode != BNO055_OPR_MODE_AMG) { + *val = 0; + } else { + ret = regmap_bulk_read(priv->regmap, + chan->address + + BNO055_REG_OFFSET_ADDR, + &raw_val, sizeof(raw_val)); + if (ret < 0) + return ret; + /* + * IMU reports sensor offests; IIO wants correction + * offset, thus we need the 'minus' here. + */ + *val = -(s16)le16_to_cpu(raw_val); + } + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 1; + switch (chan->type) { + case IIO_GRAVITY: + /* Table 3-35: 1 m/s^2 = 100 LSB */ + case IIO_ACCEL: + /* Table 3-17: 1 m/s^2 = 100 LSB */ + *val2 = 100; + break; + case IIO_MAGN: + /* + * Table 3-19: 1 uT = 16 LSB. But we need + * Gauss: 1G = 0.1 uT. + */ + *val2 = 160; + break; + case IIO_ANGL_VEL: + /* + * Table 3-22: 1 Rps = 900 LSB + * .. but this is not exactly true. See comment at the + * beginning of this file. + */ + if (priv->operation_mode != BNO055_OPR_MODE_AMG) { + *val = bno055_gyr_scale.fusion_vals[0]; + *val2 = bno055_gyr_scale.fusion_vals[1]; + return IIO_VAL_FRACTIONAL; + } + + return bno055_get_regmask(priv, val, val2, + BNO055_GYR_CONFIG_REG, + BNO055_GYR_CONFIG_RANGE_MASK, + &bno055_gyr_scale); + break; + case IIO_ROT: + /* Table 3-28: 1 degree = 16 LSB */ + *val2 = 16; + break; + default: + return -EINVAL; + } + return IIO_VAL_FRACTIONAL; + + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->type != IIO_MAGN) + return -EINVAL; + else + return bno055_get_regmask(priv, val, val2, + BNO055_MAG_CONFIG_REG, + BNO055_MAG_CONFIG_ODR_MASK, + &bno055_mag_odr); + + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + switch (chan->type) { + case IIO_ANGL_VEL: + return bno055_get_regmask(priv, val, val2, + BNO055_GYR_CONFIG_REG, + BNO055_GYR_CONFIG_LPF_MASK, + &bno055_gyr_lpf); + case IIO_ACCEL: + return bno055_get_regmask(priv, val, val2, + BNO055_ACC_CONFIG_REG, + BNO055_ACC_CONFIG_LPF_MASK, + &bno055_acc_lpf); + default: + return -EINVAL; + } + + default: + return -EINVAL; + } +} + +int bno055_sysfs_attr_avail(struct bno055_priv *priv, struct bno055_sysfs_attr *attr, + const int **vals, int *length) +{ + if (priv->operation_mode != BNO055_OPR_MODE_AMG) { + /* locked when fusion enabled */ + *vals = attr->fusion_vals; + if (attr->type == IIO_VAL_INT) + *length = 1; + else + *length = 2; /* IIO_VAL_INT_PLUS_MICRO or IIO_VAL_FRACTIONAL*/ + } else { + *vals = attr->vals; + *length = attr->len; + } + + return attr->type; +} + +static int bno055_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct bno055_priv *priv = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + *type = bno055_sysfs_attr_avail(priv, &bno055_gyr_scale, + vals, length); + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + switch (chan->type) { + case IIO_ANGL_VEL: + *type = bno055_sysfs_attr_avail(priv, &bno055_gyr_lpf, + vals, length); + return IIO_AVAIL_LIST; + case IIO_ACCEL: + *type = bno055_sysfs_attr_avail(priv, &bno055_acc_lpf, + vals, length); + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } + + break; + case IIO_CHAN_INFO_SAMP_FREQ: + switch (chan->type) { + case IIO_MAGN: + *type = bno055_sysfs_attr_avail(priv, &bno055_mag_odr, + vals, length); + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int bno055_read_temp_chan(struct iio_dev *indio_dev, int *val) +{ + struct bno055_priv *priv = iio_priv(indio_dev); + unsigned int raw_val; + int ret; + + ret = regmap_read(priv->regmap, BNO055_TEMP_REG, &raw_val); + if (ret < 0) + return ret; + + /* + * Tables 3-36 and 3-37: one byte of priv, signed, 1 LSB = 1C. + * ABI wants milliC. + */ + *val = raw_val * 1000; + + return IIO_VAL_INT; +} + +static int bno055_read_quaternion(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int size, int *vals, int *val_len, + long mask) +{ + struct bno055_priv *priv = iio_priv(indio_dev); + __le16 raw_vals[4]; + int i, ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (size < 4) + return -EINVAL; + ret = regmap_bulk_read(priv->regmap, + BNO055_QUAT_DATA_W_LSB_REG, + raw_vals, sizeof(raw_vals)); + if (ret < 0) + return ret; + for (i = 0; i < 4; i++) + vals[i] = (s16)le16_to_cpu(raw_vals[i]); + *val_len = 4; + return IIO_VAL_INT_MULTIPLE; + case IIO_CHAN_INFO_SCALE: + /* Table 3-31: 1 quaternion = 2^14 LSB */ + if (size < 2) + return -EINVAL; + vals[0] = 1; + vals[1] = 1 << 14; + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static int _bno055_read_raw_multi(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int size, int *vals, int *val_len, + long mask) +{ + switch (chan->type) { + case IIO_MAGN: + case IIO_ACCEL: + case IIO_ANGL_VEL: + case IIO_GRAVITY: + if (size < 2) + return -EINVAL; + *val_len = 2; + return bno055_read_simple_chan(indio_dev, chan, + &vals[0], &vals[1], + mask); + case IIO_TEMP: + *val_len = 1; + return bno055_read_temp_chan(indio_dev, &vals[0]); + case IIO_ROT: + /* + * Rotation is exposed as either a quaternion or three + * Euler angles. + */ + if (chan->channel2 == IIO_MOD_QUATERNION) + return bno055_read_quaternion(indio_dev, chan, + size, vals, + val_len, mask); + if (size < 2) + return -EINVAL; + *val_len = 2; + return bno055_read_simple_chan(indio_dev, chan, + &vals[0], &vals[1], + mask); + default: + return -EINVAL; + } +} + +static int bno055_read_raw_multi(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int size, int *vals, int *val_len, + long mask) +{ + struct bno055_priv *priv = iio_priv(indio_dev); + int ret; + + mutex_lock(&priv->lock); + ret = _bno055_read_raw_multi(indio_dev, chan, size, + vals, val_len, mask); + mutex_unlock(&priv->lock); + return ret; +} + +static int _bno055_write_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct bno055_priv *priv = iio_priv(iio_dev); + + switch (chan->type) { + case IIO_MAGN: + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + return bno055_set_regmask(priv, val, val2, + BNO055_MAG_CONFIG_REG, + BNO055_MAG_CONFIG_ODR_MASK, + &bno055_mag_odr); + default: + return -EINVAL; + } + case IIO_ACCEL: + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return bno055_set_regmask(priv, val, val2, + BNO055_ACC_CONFIG_REG, + BNO055_ACC_CONFIG_LPF_MASK, + &bno055_acc_lpf); + + default: + return -EINVAL; + } + case IIO_ANGL_VEL: + switch (mask) { + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return bno055_set_regmask(priv, val, val2, + BNO055_GYR_CONFIG_REG, + BNO055_GYR_CONFIG_LPF_MASK, + &bno055_gyr_lpf); + case IIO_CHAN_INFO_SCALE: + return bno055_set_regmask(priv, val, val2, + BNO055_GYR_CONFIG_REG, + BNO055_GYR_CONFIG_RANGE_MASK, + &bno055_gyr_scale); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int bno055_write_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct bno055_priv *priv = iio_priv(iio_dev); + int ret; + + mutex_lock(&priv->lock); + ret = _bno055_write_raw(iio_dev, chan, val, val2, mask); + mutex_unlock(&priv->lock); + + return ret; +} + +static ssize_t in_accel_range_raw_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + int len = 0; + int i; + + if (priv->operation_mode != BNO055_OPR_MODE_AMG) + return sysfs_emit(buf, "%d\n", bno055_acc_range.fusion_vals[0]); + + for (i = 0; i < bno055_acc_range.len; i++) + len += sysfs_emit_at(buf, len, "%d%c", bno055_acc_range.vals[i], + (i == bno055_acc_range.len - 1) ? '\n' : ' '); + return len; +} + +static ssize_t bno055_fusion_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + + return sysfs_emit(buf, "%d\n", + priv->operation_mode != BNO055_OPR_MODE_AMG); +} + +static ssize_t bno055_fusion_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + int ret = 0; + + if (sysfs_streq(buf, "0")) { + ret = bno055_operation_mode_set(priv, BNO055_OPR_MODE_AMG); + } else { + /* + * Coming from AMG means the FMC was off, just switch to fusion + * but don't change anything that doesn't belong to us (i.e let. + * FMC stay off. + * Coming from any other fusion mode means we don't need to do + * anything. + */ + if (priv->operation_mode == BNO055_OPR_MODE_AMG) + ret = bno055_operation_mode_set(priv, BNO055_OPR_MODE_FUSION_FMC_OFF); + } + if (ret) + return ret; + return len; +} + +static ssize_t bno055_fmc_enable_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + + return sysfs_emit(buf, "%d\n", + priv->operation_mode == BNO055_OPR_MODE_FUSION); +} + +static ssize_t bno055_fmc_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + int ret; + + if (sysfs_streq(buf, "0")) { + if (priv->operation_mode == BNO055_OPR_MODE_FUSION) { + ret = bno055_operation_mode_set(priv, BNO055_OPR_MODE_FUSION_FMC_OFF); + if (ret) + return ret; + } + } else { + if (priv->operation_mode == BNO055_OPR_MODE_AMG) + return -EINVAL; + + if (priv->operation_mode != BNO055_OPR_MODE_FUSION) { + ret = bno055_operation_mode_set(priv, BNO055_OPR_MODE_FUSION); + if (ret) + return ret; + } + } + + return len; +} + +static ssize_t bno055_in_accel_range_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + int val; + int ret; + + ret = bno055_get_regmask(priv, &val, NULL, + BNO055_ACC_CONFIG_REG, + BNO055_ACC_CONFIG_RANGE_MASK, + &bno055_acc_range); + if (ret < 0) + return ret; + + return sysfs_emit(buf, "%d\n", val); +} + +static ssize_t bno055_in_accel_range_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&priv->lock); + ret = bno055_set_regmask(priv, val, 0, + BNO055_ACC_CONFIG_REG, + BNO055_ACC_CONFIG_RANGE_MASK, + &bno055_acc_range); + mutex_unlock(&priv->lock); + + return ret ?: len; +} + +static ssize_t bno055_get_calib_status(struct device *dev, char *buf, int which) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + int calib; + int ret; + int val; + + if (priv->operation_mode == BNO055_OPR_MODE_AMG || + (priv->operation_mode == BNO055_OPR_MODE_FUSION_FMC_OFF && + which == BNO055_CALIB_STAT_MAGN_SHIFT)) { + calib = 0; + } else { + mutex_lock(&priv->lock); + ret = regmap_read(priv->regmap, BNO055_CALIB_STAT_REG, &val); + mutex_unlock(&priv->lock); + + if (ret) + return -EIO; + + calib = ((val >> which) & BNO055_CALIB_STAT_MASK) + 1; + } + + return sysfs_emit(buf, "%d\n", calib); +} + +static ssize_t serial_number_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + + return sysfs_emit(buf, "%*ph\n", BNO055_UID_LEN, priv->uid); +} + +static ssize_t calibration_data_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct bno055_priv *priv = iio_priv(dev_to_iio_dev(dev)); + u8 data[BNO055_CALDATA_LEN]; + int ret; + + mutex_lock(&priv->lock); + ret = bno055_operation_mode_do_set(priv, BNO055_OPR_MODE_CONFIG); + if (ret) + goto unlock; + + ret = regmap_bulk_read(priv->regmap, BNO055_CALDATA_START, data, + BNO055_CALDATA_LEN); + if (ret) + goto unlock; + + ret = bno055_operation_mode_do_set(priv, priv->operation_mode); + if (ret) + goto unlock; + + memcpy(buf, data, BNO055_CALDATA_LEN); + + ret = BNO055_CALDATA_LEN; +unlock: + mutex_unlock(&priv->lock); + return ret; +} + +static ssize_t sys_calibration_auto_status_show(struct device *dev, + struct device_attribute *a, + char *buf) +{ + return bno055_get_calib_status(dev, buf, BNO055_CALIB_STAT_SYS_SHIFT); +} + +static ssize_t in_accel_calibration_auto_status_show(struct device *dev, + struct device_attribute *a, + char *buf) +{ + return bno055_get_calib_status(dev, buf, BNO055_CALIB_STAT_ACCEL_SHIFT); +} + +static ssize_t in_gyro_calibration_auto_status_show(struct device *dev, + struct device_attribute *a, + char *buf) +{ + return bno055_get_calib_status(dev, buf, BNO055_CALIB_STAT_GYRO_SHIFT); +} + +static ssize_t in_magn_calibration_auto_status_show(struct device *dev, + struct device_attribute *a, + char *buf) +{ + return bno055_get_calib_status(dev, buf, BNO055_CALIB_STAT_MAGN_SHIFT); +} + +#ifdef CONFIG_DEBUG_FS +int bno055_debugfs_reg_access(struct iio_dev *iio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct bno055_priv *priv = iio_priv(iio_dev); + + if (readval) + return regmap_read(priv->regmap, reg, readval); + else + return regmap_write(priv->regmap, reg, writeval); +} + +static ssize_t bno055_show_fw_version(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct bno055_priv *priv = file->private_data; + int rev, ver; + char *buf; + int ret; + + ret = regmap_read(priv->regmap, BNO055_SW_REV_LSB_REG, &rev); + if (ret) + return ret; + + ret = regmap_read(priv->regmap, BNO055_SW_REV_MSB_REG, &ver); + if (ret) + return ret; + + buf = kasprintf(GFP_KERNEL, "ver: 0x%x, rev: 0x%x\n", ver, rev); + if (!buf) + return -ENOMEM; + + ret = simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf)); + kfree(buf); + + return ret; +} + +static const struct file_operations bno055_fw_version_ops = { + .open = simple_open, + .read = bno055_show_fw_version, + .llseek = default_llseek, + .owner = THIS_MODULE, +}; + +static void bno055_debugfs_init(struct iio_dev *iio_dev) +{ + struct bno055_priv *priv = iio_priv(iio_dev); + + debugfs_create_file("firmware_version", 0400, + iio_get_debugfs_dentry(iio_dev), priv, + &bno055_fw_version_ops); +} +#else +static void bno055_debugfs_init(struct iio_dev *iio_dev) +{ +} + +int bno055_debugfs_reg_access(struct iio_dev *iio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + return 0; +} +#endif + +static IIO_DEVICE_ATTR(fusion_enable, 0644, + bno055_fusion_enable_show, + bno055_fusion_enable_store, 0); + +static IIO_DEVICE_ATTR(in_magn_calibration_fast_enable, 0644, + bno055_fmc_enable_show, + bno055_fmc_enable_store, 0); + +static IIO_DEVICE_ATTR(in_accel_range_raw, 0644, + bno055_in_accel_range_show, + bno055_in_accel_range_store, 0); + +static IIO_DEVICE_ATTR_RO(in_accel_range_raw_available, 0); + +static IIO_DEVICE_ATTR_RO(sys_calibration_auto_status, 0); +static IIO_DEVICE_ATTR_RO(in_accel_calibration_auto_status, 0); +static IIO_DEVICE_ATTR_RO(in_gyro_calibration_auto_status, 0); +static IIO_DEVICE_ATTR_RO(in_magn_calibration_auto_status, 0); +static IIO_DEVICE_ATTR_RO(calibration_data, 0); + +static IIO_DEVICE_ATTR_RO(serial_number, 0); + +static struct attribute *bno055_attrs[] = { + &iio_dev_attr_in_accel_range_raw_available.dev_attr.attr, + &iio_dev_attr_in_accel_range_raw.dev_attr.attr, + &iio_dev_attr_fusion_enable.dev_attr.attr, + &iio_dev_attr_in_magn_calibration_fast_enable.dev_attr.attr, + &iio_dev_attr_sys_calibration_auto_status.dev_attr.attr, + &iio_dev_attr_in_accel_calibration_auto_status.dev_attr.attr, + &iio_dev_attr_in_gyro_calibration_auto_status.dev_attr.attr, + &iio_dev_attr_in_magn_calibration_auto_status.dev_attr.attr, + &iio_dev_attr_calibration_data.dev_attr.attr, + &iio_dev_attr_serial_number.dev_attr.attr, + NULL +}; + +static const struct attribute_group bno055_attrs_group = { + .attrs = bno055_attrs, +}; + +static const struct iio_info bno055_info = { + .read_raw_multi = bno055_read_raw_multi, + .read_avail = bno055_read_avail, + .write_raw = bno055_write_raw, + .attrs = &bno055_attrs_group, + .debugfs_reg_access = bno055_debugfs_reg_access, +}; + +/* + * Reads len samples from the HW, stores them in buf starting from buf_idx, + * and applies mask to cull (skip) unneeded samples. + * Updates buf_idx incrementing with the number of stored samples. + * Samples from HW are transferred into buf, then in-place copy on buf is + * performed in order to cull samples that need to be skipped. + * This avoids copies of the first samples until we hit the 1st sample to skip, + * and also avoids having an extra bounce buffer. + * buf must be able to contain len elements in spite of how many samples we are + * going to cull. + */ +static int bno055_scan_xfer(struct bno055_priv *priv, + int start_ch, int len, unsigned long mask, + __le16 *buf, int *buf_idx) +{ + const int base = BNO055_ACC_DATA_X_LSB_REG; + bool quat_in_read = false; + int buf_base = *buf_idx; + __le16 *dst, *src; + int offs_fixup = 0; + int xfer_len = len; + int ret; + int i, n; + + if (!mask) + return 0; + + /* + * All chans are made up 1 16-bit sample, except for quaternion that is + * made up 4 16-bit values. + * For us the quaternion CH is just like 4 regular CHs. + * If our read starts past the quaternion make sure to adjust the + * starting offset; if the quaternion is contained in our scan then make + * sure to adjust the read len. + */ + if (start_ch > BNO055_SCAN_QUATERNION) { + start_ch += 3; + } else if ((start_ch <= BNO055_SCAN_QUATERNION) && + ((start_ch + len) > BNO055_SCAN_QUATERNION)) { + quat_in_read = true; + xfer_len += 3; + } + + ret = regmap_bulk_read(priv->regmap, + base + start_ch * sizeof(__le16), + buf + buf_base, + xfer_len * sizeof(__le16)); + if (ret) + return ret; + + for_each_set_bit(i, &mask, len) { + if (quat_in_read && ((start_ch + i) > BNO055_SCAN_QUATERNION)) + offs_fixup = 3; + + dst = buf + *buf_idx; + src = buf + buf_base + offs_fixup + i; + + n = (start_ch + i == BNO055_SCAN_QUATERNION) ? 4 : 1; + + if (dst != src) + memcpy(dst, src, n * sizeof(__le16)); + + *buf_idx += n; + } + return 0; +} + +static irqreturn_t bno055_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *iio_dev = pf->indio_dev; + struct bno055_priv *priv = iio_priv(iio_dev); + int xfer_start, start, end, prev_end; + unsigned long mask; + int quat_extra_len; + bool first = true; + int buf_idx = 0; + bool thr_hit; + int ret; + + mutex_lock(&priv->lock); + + /* + * Walk the bitmap and eventually perform several transfers. + * Bitmap ones-fileds that are separated by gaps <= xfer_burst_break_thr + * will be included in same transfer. + * Every time the bitmap contains a gap wider than xfer_burst_break_thr + * then we split the transfer, skipping the gap. + */ + for_each_set_bitrange(start, end, iio_dev->active_scan_mask, + iio_dev->masklength) { + /* + * First transfer will start from the beginnig of the first + * ones-field in the bitmap + */ + if (first) + xfer_start = start; + + /* + * We found the next ones-field; check whether to include it in + * the current transfer or not (i.e. let's perform the current + * transfer and prepare for another one). + */ + if (!first) { + /* + * In case the zeros-gap contains the quaternion bit, + * then its length is actually 4 words instead of 1 + * (i.e. +3 wrt other channels). + */ + quat_extra_len = ((start > BNO055_SCAN_QUATERNION) && + (prev_end <= BNO055_SCAN_QUATERNION)) ? 3 : 0; + + /* If the gap is wider than xfer_burst_break_thr then.. */ + thr_hit = (start - prev_end + quat_extra_len) > + priv->xfer_burst_break_thr; + + /* + * .. transfer all the data up to the gap. Then set the + * next transfer start index at right after the gap + * (i.e. at the start of this ones-field). + */ + if (thr_hit) { + mask = *iio_dev->active_scan_mask >> xfer_start; + ret = bno055_scan_xfer(priv, xfer_start, + prev_end - xfer_start, + mask, priv->buf.chans, &buf_idx); + if (ret) + goto done; + xfer_start = start; + } + } + first = false; + prev_end = end; + } + + /* + * We finished walking the bitmap; no more gaps to check for. Just + * perform the current transfer. + */ + mask = *iio_dev->active_scan_mask >> xfer_start; + ret = bno055_scan_xfer(priv, xfer_start, + prev_end - xfer_start, + mask, priv->buf.chans, &buf_idx); + + iio_push_to_buffers_with_timestamp(iio_dev, &priv->buf, pf->timestamp); +done: + mutex_unlock(&priv->lock); + iio_trigger_notify_done(iio_dev->trig); + return IRQ_HANDLED; +} + +static void bno055_clk_disable(void *arg) +{ + clk_disable_unprepare((struct clk *)arg); +} + +int bno055_probe(struct device *dev, struct regmap *regmap, + int xfer_burst_break_thr, bool sw_reset) +{ + const struct firmware *caldata; + struct bno055_priv *priv; + const u8 *caldata_data = NULL; + struct iio_dev *iio_dev; + int caldata_size = 0; + char *fw_name_buf; + unsigned int val; + int rev, ver; + int ret; + + iio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); + if (!iio_dev) + return -ENOMEM; + + iio_dev->name = "bno055"; + priv = iio_priv(iio_dev); + mutex_init(&priv->lock); + priv->regmap = regmap; + priv->dev = dev; + priv->xfer_burst_break_thr = xfer_burst_break_thr; + priv->sw_reset = sw_reset; + + priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(priv->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), "Failed to get reset GPIO"); + + priv->clk = devm_clk_get_optional(dev, "clk"); + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to get CLK"); + + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, bno055_clk_disable, priv->clk); + if (ret) + return ret; + + if (priv->reset_gpio) { + usleep_range(5000, 10000); + gpiod_set_value_cansleep(priv->reset_gpio, 1); + usleep_range(650000, 750000); + } else { + if (!sw_reset) + dev_warn(dev, "No any usable reset metod; IMU may be unreliable"); + } + + ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val); + if (ret) + return ret; + + if (val != BNO055_CHIP_ID_MAGIC) { + dev_err(dev, "Unrecognized chip ID 0x%x", val); + return -ENODEV; + } + + if (!priv->reset_gpio) { + ret = bno055_system_reset(priv); + if (ret) + return ret; + } + + ret = regmap_read(priv->regmap, BNO055_SW_REV_LSB_REG, &rev); + if (ret) + return ret; + + ret = regmap_read(priv->regmap, BNO055_SW_REV_MSB_REG, &ver); + if (ret) + return ret; + + if (ver != 0x3 || rev != 0x11) + dev_warn(dev, "Untested firmware version. Anglvel scale may not work as expected"); + + ret = regmap_bulk_read(priv->regmap, BNO055_UID_LOWER_REG, + priv->uid, BNO055_UID_LEN); + if (ret) + return ret; + + /* + * This has nothing to do with the IMU firmware, this is for sensor + * calibration data. + */ + fw_name_buf = kasprintf(GFP_KERNEL, + BNO055_FW_UID_NAME, + BNO055_UID_LEN, priv->uid); + if (!fw_name_buf) + return -ENOMEM; + + ret = request_firmware(&caldata, fw_name_buf, dev); + kfree(fw_name_buf); + if (ret) + ret = request_firmware(&caldata, BNO055_FW_GENERIC_NAME, dev); + + if (ret) + dev_notice(dev, "Calibration file load failed. See instruction in kernel Documentation"); + + if (caldata) { + caldata_data = caldata->data; + caldata_size = caldata->size; + } + ret = bno055_init(priv, caldata_data, caldata_size); + if (caldata) + release_firmware(caldata); + if (ret) + return ret; + + priv->operation_mode = BNO055_OPR_MODE_FUSION; + ret = bno055_operation_mode_do_set(priv, priv->operation_mode); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, bno055_uninit, priv); + if (ret) + return ret; + + iio_dev->channels = bno055_channels; + iio_dev->num_channels = ARRAY_SIZE(bno055_channels); + iio_dev->info = &bno055_info; + iio_dev->modes = INDIO_DIRECT_MODE; + + ret = devm_iio_triggered_buffer_setup(dev, iio_dev, + iio_pollfunc_store_time, + bno055_trigger_handler, NULL); + if (ret) + return ret; + + ret = devm_iio_device_register(dev, iio_dev); + if (ret) + return ret; + + bno055_debugfs_init(iio_dev); + + return 0; +} +EXPORT_SYMBOL_GPL(bno055_probe); + +MODULE_AUTHOR("Andrea Merello "); +MODULE_DESCRIPTION("Bosch BNO055 driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/imu/bno055/bno055.h b/drivers/iio/imu/bno055/bno055.h new file mode 100644 index 000000000000..2ccb373c61cd --- /dev/null +++ b/drivers/iio/imu/bno055/bno055.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __BNO055_H__ +#define __BNO055_H__ + +#include + +struct device; +int bno055_probe(struct device *dev, struct regmap *regmap, + int xfer_burst_break_thr, bool sw_reset); +extern const struct regmap_config bno055_regmap_config; + +#endif From patchwork Thu Feb 17 16:27:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750426 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C80C8C4167B for ; Thu, 17 Feb 2022 16:27:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243172AbiBQQ1v (ORCPT ); Thu, 17 Feb 2022 11:27:51 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60596 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243144AbiBQQ1q (ORCPT ); Thu, 17 Feb 2022 11:27:46 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3723E9AD9B; Thu, 17 Feb 2022 08:27:32 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id hw13so8510709ejc.9; Thu, 17 Feb 2022 08:27:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pbdipNgGb568BK6JvdFqLj5QbJ/YCdKI9XyfVVughYc=; b=FDGQfbhXaaUO4B926RvwjtMRE/bI9kcTmB98/cTf39VoiK8IP0dTiIinIJLo/YylxV /KFEShizihxLpsRUXGYqHbxFrlnoO0U0+rTq4nmM5waEc+a3kbP8KVMSxp2kO/LeHm/B WXfS/4L8C7bu9HFT3G03cqKAx1KxSU5ha9Bl8alCK4vVSsrhsZYIZXwPsmmlo2gGDQl/ cpPdX74yIN60qPkxD9AdvPVXAn61GiUtOdnLRsXFNM6jPyvQ599S6vD+SsuAHlayIdtF 78CfMLgdqoC6IXvXCvmerVwgPQzPNA3Pq4a80+lSFvaQ2cDTrzFNhAnxBlNIGM43/Mjn j0Fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pbdipNgGb568BK6JvdFqLj5QbJ/YCdKI9XyfVVughYc=; b=hacf/z2dr3ypIAhawvGCuonKD1W7eoONTujCYrkauiOOWqz14p/Lb5azEVGd9drEts pVaYDyN6q2GG9E7NMxZUG6+yulijR2O9SZRWfDjzf9x9cKxwvrwDtH64/+deBijDWMhG q3vXppNbZefjsSyri1nmprur/WQOBr0s0KMi1qg2dAFJ29q26yLqqs7/IQI4RYWj0Y5g 0EYtOHuB514uHIiTRMeH3ZTKgrY3NjjycFCAsNa/9Dkj1ow+JQqCASt90E3YMti/g3Qt UpYTeUf1i/CIUJ9JfyEi0ubeWlBlVZMzg3gqxo30t70yath5vNZ/dbUNr7NsxjRIfmwa YYvg== X-Gm-Message-State: AOAM530FSjPVBUaEku10xopNCYW+k1Ey+cuzR9JPjhe3Ytu7Y1nL0LGB gHA4ziOcNWSZrfVXEareAaM= X-Google-Smtp-Source: ABdhPJy3ChPqp5lo7a3SDO69C5a1yNib9JnENaNKabTlATHZxl+qvDSw+zEVHQ5eHDLiKC8wZDGGcA== X-Received: by 2002:a17:907:213b:b0:6cf:9c02:8964 with SMTP id qo27-20020a170907213b00b006cf9c028964mr2904604ejb.432.1645115250783; Thu, 17 Feb 2022 08:27:30 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:30 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 08/13] iio: document bno055 private sysfs attributes Date: Thu, 17 Feb 2022 17:27:05 +0100 Message-Id: <20220217162710.33615-9-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch adds ABI documentation for bno055 driver private sysfs attributes. Signed-off-by: Andrea Merello --- .../ABI/testing/sysfs-bus-iio-bno055 | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-bno055 diff --git a/Documentation/ABI/testing/sysfs-bus-iio-bno055 b/Documentation/ABI/testing/sysfs-bus-iio-bno055 new file mode 100644 index 000000000000..c239276f2b0f --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-bno055 @@ -0,0 +1,81 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_accel_raw_range +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Range for acceleration readings in m/s^2. Note that this does + not affects the scale (which should be used when changing the + maximum and minimum readable value affects also the reading + scaling factor). + +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_raw_range +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Range for angular velocity readings in radians per second. Note + that this does not affects the scale (which should be used when + changing the maximum and minimum readable value affects also the + reading scaling factor). + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_raw_range_available +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + List of allowed values for in_accel_raw_range attribute + +What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_raw_range_available +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + List of allowed values for in_anglvel_raw_range attribute + +What: /sys/bus/iio/devices/iio:deviceX/in_magn_calibration_fast_enable +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Can be 1 or 0. Enables/disables the "Fast Magnetometer + Calibration" HW function. + +What: /sys/bus/iio/devices/iio:deviceX/fusion_enable +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Can be 1 or 0. Enables/disables the "sensor fusion" (a.k.a. + NDOF) HW function. + +What: /sys/bus/iio/devices/iio:deviceX/calibration_data +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Reports the binary calibration data blob for the IMU sensors. + +What: /sys/bus/iio/devices/iio:deviceX/in_accel_calibration_auto_status +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Reports the autocalibration status for the accelerometer sensor. + Can be 0 (calibration non even enabled) or 1 to 5 where the greater + the number, the better the calibration status. + +What: /sys/bus/iio/devices/iio:deviceX/in_gyro_calibration_auto_status +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Reports the autocalibration status for the gyroscope sensor. + Can be 0 (calibration non even enabled) or 1 to 5 where the greater + the number, the better the calibration status. + +What: /sys/bus/iio/devices/iio:deviceX/in_magn_calibration_auto_status +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Reports the autocalibration status for the magnetometer sensor. + Can be 0 (calibration non even enabled) or 1 to 5 where the greater + the number, the better the calibration status. + +What: /sys/bus/iio/devices/iio:deviceX/sys_calibration_auto_status +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + Reports the status for the IMU overall autocalibration. + Can be 0 (calibration non even enabled) or 1 to 5 where the greater + the number, the better the calibration status. From patchwork Thu Feb 17 16:27:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750425 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD5D7C433FE for ; Thu, 17 Feb 2022 16:27:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243162AbiBQQ1u (ORCPT ); Thu, 17 Feb 2022 11:27:50 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243147AbiBQQ1r (ORCPT ); Thu, 17 Feb 2022 11:27:47 -0500 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E5859BB8A; Thu, 17 Feb 2022 08:27:33 -0800 (PST) Received: by mail-ed1-x535.google.com with SMTP id b13so10729385edn.0; Thu, 17 Feb 2022 08:27:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/GuBSZT3gYUl9WUuyRcBD5kTPc3HH/CTyiu6CHm9clg=; b=Wm8FALi5Hf4NclLp1g8m3iDtxtl6w8nxMgEgI0RyE85tZBf/JzcCJM5F95qY6pW9qf oNw3POdVmOrNecKK5Tm6j3C3P8VzZbBU/XX0/TkyPXgOQeQMyXVwshIR9lMqNQBAKlDM ON9EmoBVc7LoZsF5FFov5dhGo526GzjobehxQora6mdcCgP9FGr5l9QdnIxgCj3MzVjT WUaBn++cNiSNrYvpSjn7qE/4nPNfzSGXFQvTUi6Qnw39Y9uFHIVvF1sGv/XUDxk0+yAB DTTO+1+c8XHAPiCxwRYBQ6U20u/2coUBcSBwTU+sgz5T79ZV5A+ew7zyhSQsAihi+zs3 kI7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/GuBSZT3gYUl9WUuyRcBD5kTPc3HH/CTyiu6CHm9clg=; b=XN0lMV9RMJrXffMPl0lENgG2As5zKcdkhHcv3CKDwRjnjrC1A++emYpAxsbSt9gYmV EOAZiirjLpyXQI59DpHlef3WSA6mIQMGnC+B8cUOq4eAUh07W+Jam0+dOqRZd6fKZ3QB 43A37WDV8JtiDSeTzPTZh9gyftbq+akRGLTngKl1pECxhbS66vTOfsV0Sb75kRhFyUth 5P4nXRajjcdoOsUsC9V1SmRZKHc4XuKX8L1TzCBzQFlEITYfLhcgfp9R9J2V6WRkYUei x3LKUG1H41GDv0ynvlo4Zo2NGI7rbdrE3CCmwemTGqb/CZCFNmyB39BmBNckCsEWqNmz oatw== X-Gm-Message-State: AOAM533cp97/ETeG8Qk+AwesFNtLRe8L4fBBm2zzsYlBLVDBDR+MgJjw Z5LhZT0vBhrPxCK48K5m17EnB/m5DFJEFC8F X-Google-Smtp-Source: ABdhPJzUMjNQN/re+jPHV80Ub6x2ggTg2L7tiNQTBIFCtX39CG5GroijnFzdEuPZKjwpxYpwvaID2w== X-Received: by 2002:a05:6402:cb:b0:410:8094:872b with SMTP id i11-20020a05640200cb00b004108094872bmr3402607edu.378.1645115251649; Thu, 17 Feb 2022 08:27:31 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:31 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 09/13] iio: document "serial_number" sysfs attribute Date: Thu, 17 Feb 2022 17:27:06 +0100 Message-Id: <20220217162710.33615-10-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch adds ABI documentation for the new "serial_number" sysfs attribute. The first user is the bno055 IIO driver. Signed-off-by: Andrea Merello --- Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 1b8d77577608..224585f00147 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -2017,3 +2017,10 @@ Contact: linux-iio@vger.kernel.org Description: Raw (unscaled) euler angles readings. Units after application of scale are deg. + +What: /sys/bus/iio/devices/iio:deviceX/serial_number +KernelVersion: 5.17 +Contact: linux-iio@vger.kernel.org +Description: + 16-bytes, 2-digits-per-byte, HEX-string representing the sensor + unique ID number. From patchwork Thu Feb 17 16:27:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750424 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECF5FC4167D for ; Thu, 17 Feb 2022 16:27:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243160AbiBQQ1u (ORCPT ); Thu, 17 Feb 2022 11:27:50 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60752 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243151AbiBQQ1s (ORCPT ); Thu, 17 Feb 2022 11:27:48 -0500 Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 231B79D049; Thu, 17 Feb 2022 08:27:34 -0800 (PST) Received: by mail-ed1-x532.google.com with SMTP id u18so10610195edt.6; Thu, 17 Feb 2022 08:27:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9TN6KDpHU/fcJsRDPYzJSQRkuj2gxgVh7KPbfIBfiw8=; b=p+Dn1m1iWFHZLCfxSfqbw37qW3cs7g0tWJzQzYwUE48iHIcrr9qbEWPpmKq7uMY80k 3DfUtdJuo9vgbNz0r+b9g4Gy1lmjhX8+4y++U7/dxGVBUp8hf5FqDHJHmr875Mi1M+Ck IqGJQXz/97eNDbHfdTWTgHY/G5hEXDMpPLrSR2BltNqzUVP2G/U2MyWjGz+j3vVCZt72 kxhfsosCnPYjrbxZ4VryMQKyMZpX+qJfLf3NQeseY/yYL/Y7haiF6IarVeA5NuKfyYtl TU9fAhNkTMTn1JtwKg0QCrI2D6sjV9Kk1/46n9BwERFUG9CyUu9ulWpQQWmkrutJr++S IfKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9TN6KDpHU/fcJsRDPYzJSQRkuj2gxgVh7KPbfIBfiw8=; b=Vuc/vPvNzqkenmMDhm6OIAFiUlI0bTzGrYchyoPE8lngxYyq5jbNe7+Ai707mqpCNy ekg86yR9T4vrU+L2P76kMyrUDL4+8Z6hBsEiFB6RtmCvpXwRTkNCEaf1b+wruG15C3kV feDGn+okF1W1pQN1REX1I1QW1jHnLBGPQ2CpDPYbMU8Z2rf95Ncx76MHe4JAQgRrmAdW osw7Oi+a6PKeNq25PhblcHZi6shsZOVZKjp3Rb2mYmYnJEKNFv7KNSN/9+qAoYBc71QI 3WsWPt2LSjNQe6ZPSt7xZrNI7sA7PBuzingBU6hAzecH0c2LAafErQFpL+B2ljueuS1s VENA== X-Gm-Message-State: AOAM533B/XEa0ZErLmkQwgYB6X1xbj4B1hks34oHhfPspe6yoqooiITy v92xfnIr1v48LJWJW3qiOcY= X-Google-Smtp-Source: ABdhPJxR/7Pw26cq0b01F99RPvWseXTpwnZBkO1Hq58klzU0u/bho0hS6nOLnBPDSRBkOuRKgV9L4A== X-Received: by 2002:a50:8713:0:b0:410:db7a:4b2a with SMTP id i19-20020a508713000000b00410db7a4b2amr3443451edb.140.1645115252663; Thu, 17 Feb 2022 08:27:32 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:32 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 10/13] dt-bindings: iio: imu: add documentation for Bosch BNO055 bindings Date: Thu, 17 Feb 2022 17:27:07 +0100 Message-Id: <20220217162710.33615-11-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Introduce new documentation file for the Bosch BNO055 IMU Signed-off-by: Andrea Merello --- .../bindings/iio/imu/bosch,bno055.yaml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml diff --git a/Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml b/Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml new file mode 100644 index 000000000000..e0d06db161a9 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/bosch,bno055.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/bosch,bno055.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bosch BNO055 + +maintainers: + - Andrea Merello + +description: | + Inertial Measurement Unit with Accelerometer, Gyroscope, Magnetometer and + internal MCU for sensor fusion + https://www.bosch-sensortec.com/products/smart-sensors/bno055/ + +properties: + compatible: + enum: + - bosch,bno055 + + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + +additionalProperties: false + +examples: + - | + #include + serial { + imu { + compatible = "bosch,bno055"; + reset-gpios = <&gpio0 54 GPIO_ACTIVE_LOW>; + clocks = <&imu_clk>; + }; + }; + + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + imu@28 { + compatible = "bosch,bno055"; + reg = <0x28>; + reset-gpios = <&gpio0 54 GPIO_ACTIVE_LOW>; + clocks = <&imu_clk>; + }; + }; From patchwork Thu Feb 17 16:27:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750429 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80F8DC4167B for ; Thu, 17 Feb 2022 16:27:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243196AbiBQQ14 (ORCPT ); Thu, 17 Feb 2022 11:27:56 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60884 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243170AbiBQQ1v (ORCPT ); Thu, 17 Feb 2022 11:27:51 -0500 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A2B59D4FD; Thu, 17 Feb 2022 08:27:35 -0800 (PST) Received: by mail-ed1-x52e.google.com with SMTP id x5so10580488edd.11; Thu, 17 Feb 2022 08:27:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Mas+9N7L524k9yXfyt7IyKEXpOJzWr7GYmcRF4hgJzc=; b=IVCA5D8V2+8CayOhBu389rDso1vxrJg8u/MGy0poz/F6x3tocG6VZnVaduzigHWOQQ HDnWaM6FCgqETFrI/x7xvIeh5yBTzXa3hy+kvXkJBkfeHdxxp3F7bG0PcClMN7An2SqB BCbGAr0gAhh3DcE2QhN5GFldjRTl49w6J+loly4gYPNobeegmgoG0XE0OaEdUxYkHmJm 3mz8GeB1smO2emKEbcdw1Rtwn+ItiCbIxrL0XvITGqfofQ49IVBm/q/cs/GNnxEVJ3HN osDMBUn5scBfezUNi4hW1OZcl44V0SEd3Of4kWOd5G4NefSyDT0/A2M0JR7/B9iO3crk hs6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Mas+9N7L524k9yXfyt7IyKEXpOJzWr7GYmcRF4hgJzc=; b=2fvoDlBCkKiMxdflmyK81YwfwAv7aGFGAFnIpqUNX5aYFVKeuPkkjwgnChAq5GU2FT +54/neSKXGEEQXjGKdu1pKgxxvVXN8XzS7imqXE6XvTrSq3yQYxDk45kVjnxcdKlxHtH AEiLbVlKNap7cX/b32oJzHd3ACrWQxb4LaISipz7r2/x5DkXrYF27+AoAkOfSBkH3pXh DTiHGtSvcYFkRxKSPTtE/hTwFCB1GLaLNB8wt2JVGfeV1n6Y7Soi690I8Hy4/XpLRnef JuUL8NbD2/a6DHr/q6pnrAeeut+9TUM5mZcOLBouapno8zSJUme2e3TFOTBNvjt7exYM DBzQ== X-Gm-Message-State: AOAM532F0QKYQX0lMpHMYSYsEnm07gl9CuCYxQQac4UBaNsdaKAJvjAD f9nmSpsxEs+9B5YP6wrsvLVBG9PToMn1fGBu X-Google-Smtp-Source: ABdhPJwpsko3GtJeaQhU1A4dkh7xdLUQyTLul720dd6CMz7UBZ/1sjCG4yxc6VgLL8Yw8IAC3ly1GA== X-Received: by 2002:a05:6402:348b:b0:412:b020:ec83 with SMTP id v11-20020a056402348b00b00412b020ec83mr1906645edc.355.1645115253698; Thu, 17 Feb 2022 08:27:33 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:33 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 11/13] iio: imu: add BNO055 serdev driver Date: Thu, 17 Feb 2022 17:27:08 +0100 Message-Id: <20220217162710.33615-12-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This path adds a serdev driver for communicating to a BNO055 IMU via serial bus, and it enables the BNO055 core driver to work in this scenario. Signed-off-by: Andrea Merello Reported-by: kernel test robot Reported-by: kernel test robot --- drivers/iio/imu/bno055/Kconfig | 10 + drivers/iio/imu/bno055/Makefile | 1 + drivers/iio/imu/bno055/bno055_sl.c | 557 +++++++++++++++++++++++++++++ 3 files changed, 568 insertions(+) create mode 100644 drivers/iio/imu/bno055/bno055_sl.c diff --git a/drivers/iio/imu/bno055/Kconfig b/drivers/iio/imu/bno055/Kconfig index d0ab3221fba5..8a83639ad2a9 100644 --- a/drivers/iio/imu/bno055/Kconfig +++ b/drivers/iio/imu/bno055/Kconfig @@ -2,3 +2,13 @@ config BOSCH_BNO055_IIO tristate + +config BOSCH_BNO055_SERIAL + tristate "Bosch BNO055 attached via serial bus" + depends on SERIAL_DEV_BUS + select BOSCH_BNO055_IIO + help + Enable this to support Bosch BNO055 IMUs attached via serial bus. + + This driver can also be built as a module. If so, the module will be + called bno055_sl. diff --git a/drivers/iio/imu/bno055/Makefile b/drivers/iio/imu/bno055/Makefile index 56cc4de60a7e..416f0ff96de5 100644 --- a/drivers/iio/imu/bno055/Makefile +++ b/drivers/iio/imu/bno055/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o +obj-$(CONFIG_BOSCH_BNO055_SERIAL) += bno055_sl.o diff --git a/drivers/iio/imu/bno055/bno055_sl.c b/drivers/iio/imu/bno055/bno055_sl.c new file mode 100644 index 000000000000..5af44f151389 --- /dev/null +++ b/drivers/iio/imu/bno055/bno055_sl.c @@ -0,0 +1,557 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Serial line interface for Bosh BNO055 IMU (via serdev). + * This file implements serial communication up to the register read/write + * level. + * + * Copyright (C) 2021 Istituto Italiano di Tecnologia + * Electronic Design Laboratory + * Written by Andrea Merello + * + * This driver is besed on + * Plantower PMS7003 particulate matter sensor driver + * Which is + * Copyright (c) Tomasz Duszynski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bno055.h" + +/* + * Register writes cmd have the following format + * +------+------+-----+-----+----- ... ----+ + * | 0xAA | 0xOO | REG | LEN | payload[LEN] | + * +------+------+-----+-----+----- ... ----+ + * + * Register write responses have the following format + * +------+----------+ + * | 0xEE | ERROCODE | + * +------+----------+ + * + * .. except when writing the SYS_RST bit (i.e. triggering a system reset); in + * case the IMU accepts the command, then it resets without responding. We don't + * handle this (yet) here (so we inform the common bno055 code not to perform + * sw resets - bno055 on serial bus basically requires the hw reset pin). + * + * Register read have the following format + * +------+------+-----+-----+ + * | 0xAA | 0xO1 | REG | LEN | + * +------+------+-----+-----+ + * + * Successful register read response have the following format + * +------+-----+----- ... ----+ + * | 0xBB | LEN | payload[LEN] | + * +------+-----+----- ... ----+ + * + * Failed register read response have the following format + * +------+--------+ + * | 0xEE | ERRCODE| (ERRCODE always > 1) + * +------+--------+ + * + * Error codes are + * 01: OK + * 02: read/write FAIL + * 04: invalid address + * 05: write on RO + * 06: wrong start byte + * 07: bus overrun + * 08: len too high + * 09: len too low + * 10: bus RX byte timeout (timeout is 30mS) + * + * + * **WORKAROUND ALERT** + * + * Serial communication seems very fragile: the BNO055 buffer seems to overflow + * very easy; BNO055 seems able to sink few bytes, then it needs a brief pause. + * On the other hand, it is also picky on timeout: if there is a pause > 30mS in + * between two bytes then the transaction fails (IMU internal RX FSM resets). + * + * BNO055 has been seen also failing to process commands in case we send them + * too close each other (or if it is somehow busy?) + * + * In particular I saw these scenarios: + * 1) If we send 2 bytes per time, then the IMU never(?) overflows. + * 2) If we send 4 bytes per time (i.e. the full header), then the IMU could + * overflow, but it seem to sink all 4 bytes, then it returns error. + * 3) If we send more than 4 bytes, the IMU could overflow, and I saw it sending + * error after 4 bytes are sent; we have troubles in synchronizing again, + * because we are still sending data, and the IMU interprets it as the 1st + * byte of a new command. + * + * While we must avoid case 3, we could send 4 bytes per time and eventually + * retry in case of failure; this seemed convenient for reads (which requires + * TXing exactly 4 bytes), however it has been seen that, depending by the IMU + * settings (e.g. LPF), failures became less or more frequent; in certain IMU + * configurations they are very rare, but in certain others we keeps failing + * even after like 30 retries. + * + * So, we just split TXes in [2-bytes + delay] steps, and still keep an eye on + * the IMU response; in case it overflows (which is now unlikely), we retry. + */ + +/* + * Read operation overhead: + * 4 bytes req + 2byte resp hdr. + * 6 bytes = 60 bit (considering 1start + 1stop bits). + * 60/115200 = ~520uS + about 2500mS dealay -> ~3mS + * In 3mS we could read back about 34 bytes that means 17 samples, this means + * that in case of scattered read in which the gap is 17 samples or less it is + * still convenient to go for a burst. + * We have to take into account also IMU response time - IMU seems to be often + * reasonably quick to respond, but sometimes it seems to be in some "critical + * section" in which it delays handling of serial protocol. Because of this we + * round-up to 22, which is the max number of samples, always bursting indeed. + */ +#define BNO055_SL_XFER_BURST_BREAK_THRESHOLD 22 + +struct bno055_sl_priv { + struct serdev_device *serdev; + struct completion cmd_complete; + enum { + CMD_NONE, + CMD_READ, + CMD_WRITE, + } expect_response; + int expected_data_len; + u8 *response_buf; + + /** + * enum cmd_status - represent the status of a command sent to the HW. + * @STATUS_OK: The command executed successfully. + * @STATUS_FAIL: The command failed: HW responded with an error. + * @STATUS_CRIT: The command failed: the serial communication failed. + */ + enum { + STATUS_OK = 0, + STATUS_FAIL = 1, + STATUS_CRIT = -1 + } cmd_status; + struct mutex lock; + + /* Only accessed in RX callback context. No lock needed. */ + struct { + enum { + RX_IDLE, + RX_START, + RX_DATA + } state; + int databuf_count; + int expected_len; + int type; + } rx; + + /* Never accessed in behalf of RX callback context. No lock needed */ + bool cmd_stale; +}; + +static int bno055_sl_send_chunk(struct bno055_sl_priv *priv, u8 *data, int len) +{ + int ret; + + dev_dbg(&priv->serdev->dev, "send (len: %d): %*ph", len, len, data); + ret = serdev_device_write(priv->serdev, data, len, + msecs_to_jiffies(25)); + if (ret < 0) + return ret; + + if (ret < len) + return -EIO; + + return 0; +} + +/* + * Sends a read or write command. + * 'data' can be NULL (used in read case). 'len' parameter is always valid; in + * case 'data' is non-NULL then it must match 'data' size. + */ +static int bno055_sl_do_send_cmd(struct bno055_sl_priv *priv, + bool read, int addr, int len, u8 *data) +{ + u8 hdr[] = {0xAA, read, addr, len}; + int chunk_len; + int i = 0; + int ret; + + while (1) { + ret = bno055_sl_send_chunk(priv, hdr + i * 2, 2); + if (ret) + goto fail; + + if (i++ == 1) + break; + usleep_range(2000, 3000); + } + + if (read) + return 0; + + while (len) { + chunk_len = min(len, 2); + usleep_range(2000, 3000); + ret = bno055_sl_send_chunk(priv, data, chunk_len); + if (ret) + goto fail; + data += chunk_len; + len -= chunk_len; + } + + return 0; +fail: + /* waiting more than 30mS should clear the BNO055 internal state */ + usleep_range(40000, 50000); + return ret; +} + +static int bno_sl_send_cmd(struct bno055_sl_priv *priv, + bool read, int addr, int len, u8 *data) +{ + const int retry_max = 5; + int retry = retry_max; + int ret = 0; + + /* + * In case previous command was interrupted we still neet to wait it to + * complete before we can issue new commands + */ + if (priv->cmd_stale) { + ret = wait_for_completion_interruptible_timeout(&priv->cmd_complete, + msecs_to_jiffies(100)); + if (ret == -ERESTARTSYS) + return -ERESTARTSYS; + + priv->cmd_stale = false; + /* if serial protocol broke, bail out */ + if (priv->cmd_status == STATUS_CRIT) + return -EIO; + } + + /* + * Try to convince the IMU to cooperate.. as explained in the comments + * at the top of this file, the IMU could also refuse the command (i.e. + * it is not ready yet); retry in this case. + */ + while (retry--) { + mutex_lock(&priv->lock); + priv->expect_response = read ? CMD_READ : CMD_WRITE; + reinit_completion(&priv->cmd_complete); + mutex_unlock(&priv->lock); + + if (retry != (retry_max - 1)) + dev_dbg(&priv->serdev->dev, "cmd retry: %d", + retry_max - retry); + ret = bno055_sl_do_send_cmd(priv, read, addr, len, data); + if (ret) + continue; + + ret = wait_for_completion_interruptible_timeout(&priv->cmd_complete, + msecs_to_jiffies(100)); + if (ret == -ERESTARTSYS) { + priv->cmd_stale = true; + return -ERESTARTSYS; + } else if (!ret) { + return -ETIMEDOUT; + } + + if (priv->cmd_status == STATUS_OK) + return 0; + else if (priv->cmd_status == STATUS_CRIT) + return -EIO; + + /* loop in case priv->cmd_status == STATUS_FAIL */ + } + + if (ret < 0) + return ret; + if (priv->cmd_status == STATUS_FAIL) + return -EINVAL; + return 0; +} + +static int bno055_sl_write_reg(void *context, const void *_data, size_t count) +{ + u8 *data = (u8 *)_data; + struct bno055_sl_priv *priv = context; + + if (count < 2) { + dev_err(&priv->serdev->dev, "Invalid write count %zu", count); + return -EINVAL; + } + + dev_dbg(&priv->serdev->dev, "wr reg 0x%x = 0x%x", data[0], data[1]); + return bno_sl_send_cmd(priv, 0, data[0], count - 1, data + 1); +} + +static int bno055_sl_read_reg(void *context, + const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + int ret; + int reg_addr; + struct bno055_sl_priv *priv = context; + + if (val_size > 128) { + dev_err(&priv->serdev->dev, "Invalid read valsize %d", + val_size); + return -EINVAL; + } + + reg_addr = ((u8 *)reg)[0]; + dev_dbg(&priv->serdev->dev, "rd reg 0x%x (len %d)", reg_addr, val_size); + mutex_lock(&priv->lock); + priv->expected_data_len = val_size; + priv->response_buf = val; + mutex_unlock(&priv->lock); + + ret = bno_sl_send_cmd(priv, 1, reg_addr, val_size, NULL); + + mutex_lock(&priv->lock); + priv->response_buf = NULL; + mutex_unlock(&priv->lock); + + return ret; +} + +/* + * Handler for received data; this is called from the reicever callback whenever + * it got some packet from the serial bus. The status tell us whether the + * packet is valid (i.e. header ok && received payload len consistent wrt the + * header). It's now our responsability to check whether this is what we + * expected, of whether we got some unexpected, yet valid, packet. + */ +static void bno055_sl_handle_rx(struct bno055_sl_priv *priv, int status) +{ + mutex_lock(&priv->lock); + switch (priv->expect_response) { + case CMD_NONE: + dev_warn(&priv->serdev->dev, "received unexpected, yet valid, data from sensor"); + mutex_unlock(&priv->lock); + return; + + case CMD_READ: + priv->cmd_status = status; + if (status == STATUS_OK && + priv->rx.databuf_count != priv->expected_data_len) { + /* + * If we got here, then the lower layer serial protocol + * seems consistent with itself; if we got an unexpected + * amount of data then signal it as a non critical error + */ + priv->cmd_status = STATUS_FAIL; + dev_warn(&priv->serdev->dev, "received an unexpected amount of, yet valid, data from sensor"); + } + break; + + case CMD_WRITE: + priv->cmd_status = status; + break; + } + + priv->expect_response = CMD_NONE; + complete(&priv->cmd_complete); + mutex_unlock(&priv->lock); +} + +/* + * Serdev receiver FSM. This tracks the serial communication and parse the + * header. It pushes packets to bno055_sl_handle_rx(), eventually communicating + * failures (i.e. malformed packets). + * Ideally it doesn't know anything about upper layer (i.e. if this is the + * packet we were really expecting), but since we copies the payload into the + * receiver buffer (that is not valid when i.e. we don't expect data), we + * snoop a bit in the upper layer.. + * Also, we assume to RX one pkt per time (i.e. the HW doesn't send anything + * unless we require to AND we don't queue more than one request per time). + */ +static int bno055_sl_receive_buf(struct serdev_device *serdev, + const unsigned char *buf, size_t size) +{ + int status; + struct bno055_sl_priv *priv = serdev_device_get_drvdata(serdev); + int remaining = size; + + if (size == 0) + return 0; + + dev_dbg(&priv->serdev->dev, "recv (len %zu): %*ph ", size, size, buf); + switch (priv->rx.state) { + case RX_IDLE: + /* + * New packet. + * Check for its 1st byte, that identifies the pkt type. + */ + if (buf[0] != 0xEE && buf[0] != 0xBB) { + dev_err(&priv->serdev->dev, + "Invalid packet start %x", buf[0]); + bno055_sl_handle_rx(priv, STATUS_CRIT); + break; + } + priv->rx.type = buf[0]; + priv->rx.state = RX_START; + remaining--; + buf++; + priv->rx.databuf_count = 0; + fallthrough; + + case RX_START: + /* + * Packet RX in progress, we expect either 1-byte len or 1-byte + * status depending by the packet type. + */ + if (remaining == 0) + break; + + if (priv->rx.type == 0xEE) { + if (remaining > 1) { + dev_err(&priv->serdev->dev, "EE pkt. Extra data received"); + status = STATUS_CRIT; + + } else { + status = (buf[0] == 1) ? STATUS_OK : STATUS_FAIL; + } + bno055_sl_handle_rx(priv, status); + priv->rx.state = RX_IDLE; + break; + + } else { + /*priv->rx.type == 0xBB */ + priv->rx.state = RX_DATA; + priv->rx.expected_len = buf[0]; + remaining--; + buf++; + } + fallthrough; + + case RX_DATA: + /* Header parsed; now receiving packet data payload */ + if (remaining == 0) + break; + + if (priv->rx.databuf_count + remaining > priv->rx.expected_len) { + /* + * This is a inconsistency in serial protocol, we lost + * sync and we don't know how to handle further data + */ + dev_err(&priv->serdev->dev, "BB pkt. Extra data received"); + bno055_sl_handle_rx(priv, STATUS_CRIT); + priv->rx.state = RX_IDLE; + break; + } + + mutex_lock(&priv->lock); + /* + * NULL e.g. when read cmd is stale or when no read cmd is + * actually pending. + */ + if (priv->response_buf && + /* + * Snoop on the upper layer protocol stuff to make sure not + * to write to an invalid memory. Apart for this, let's the + * upper layer manage any inconsistency wrt expected data + * len (as long as the serial protocol is consistent wrt + * itself (i.e. response header is consistent with received + * response len. + */ + (priv->rx.databuf_count + remaining <= priv->expected_data_len)) + memcpy(priv->response_buf + priv->rx.databuf_count, + buf, remaining); + mutex_unlock(&priv->lock); + + priv->rx.databuf_count += remaining; + + /* + * Reached expected len advertised by the IMU for the current + * packet. Pass it to the upper layer (for us it is just valid). + */ + if (priv->rx.databuf_count == priv->rx.expected_len) { + bno055_sl_handle_rx(priv, STATUS_OK); + priv->rx.state = RX_IDLE; + } + break; + } + + return size; +} + +static const struct serdev_device_ops bno055_sl_serdev_ops = { + .receive_buf = bno055_sl_receive_buf, + .write_wakeup = serdev_device_write_wakeup, +}; + +static struct regmap_bus bno055_sl_regmap_bus = { + .write = bno055_sl_write_reg, + .read = bno055_sl_read_reg, +}; + +static int bno055_sl_probe(struct serdev_device *serdev) +{ + struct bno055_sl_priv *priv; + struct regmap *regmap; + int ret; + + priv = devm_kzalloc(&serdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + serdev_device_set_drvdata(serdev, priv); + priv->serdev = serdev; + mutex_init(&priv->lock); + init_completion(&priv->cmd_complete); + + serdev_device_set_client_ops(serdev, &bno055_sl_serdev_ops); + ret = devm_serdev_device_open(&serdev->dev, serdev); + if (ret) + return ret; + + if (serdev_device_set_baudrate(serdev, 115200) != 115200) { + dev_err(&serdev->dev, "Cannot set required baud rate"); + return -EIO; + } + + ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE); + if (ret) { + dev_err(&serdev->dev, "Cannot set required parity setting"); + return ret; + } + serdev_device_set_flow_control(serdev, false); + + regmap = devm_regmap_init(&serdev->dev, &bno055_sl_regmap_bus, + priv, &bno055_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&serdev->dev, "Unable to init register map"); + return PTR_ERR(regmap); + } + + return bno055_probe(&serdev->dev, regmap, + BNO055_SL_XFER_BURST_BREAK_THRESHOLD, false); +} + +static const struct of_device_id bno055_sl_of_match[] = { + { .compatible = "bosch,bno055" }, + { } +}; +MODULE_DEVICE_TABLE(of, bno055_sl_of_match); + +static struct serdev_device_driver bno055_sl_driver = { + .driver = { + .name = "bno055-sl", + .of_match_table = bno055_sl_of_match, + }, + .probe = bno055_sl_probe, +}; +module_serdev_device_driver(bno055_sl_driver); + +MODULE_AUTHOR("Andrea Merello "); +MODULE_DESCRIPTION("Bosch BNO055 serdev interface"); +MODULE_LICENSE("GPL v2"); From patchwork Thu Feb 17 16:27:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750428 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF823C433F5 for ; Thu, 17 Feb 2022 16:27:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243193AbiBQQ1z (ORCPT ); Thu, 17 Feb 2022 11:27:55 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60886 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243169AbiBQQ1v (ORCPT ); Thu, 17 Feb 2022 11:27:51 -0500 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54F5F9AD9B; Thu, 17 Feb 2022 08:27:36 -0800 (PST) Received: by mail-ed1-x534.google.com with SMTP id cm8so971039edb.3; Thu, 17 Feb 2022 08:27:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vzovTl/jqBctY9Wgr8NGlwjyey7kAE9qazeOjjaFmFE=; b=Y26qCVcbVhLSulZRd0QT6IR37Qk3jWFZlSoHlq/2WQAJUyOSoz7JsIhOS0Q8y0c+nI yW4QPuJU/nZZEy7UKl3Fg27esghnzTfHf8gJvtK2QcKThwDzFP1uCZdO6tAmFbyRgMrN 8bcIoq4i/4zSDBooGhqN5VizJWAvf1hMA4yJBGCroclO6XI+X4EBK71gx2hNfcuXOjBR I8yzV783dE4fzL1TEBmfGBrzSpU1Sf/vM5TwUfYLwqTvlISwQrTtMUwZ4sr5RQZ8Uj2F FZhkpny5K/OSPbUEyX4kx7XIvknyaExjfBw9IJeZThWwTZgFxXRslcQVCz0qBbRCyu8X oABg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vzovTl/jqBctY9Wgr8NGlwjyey7kAE9qazeOjjaFmFE=; b=djjWQsWeATlOmSXm5Bdcabuf97hJ35YU+mn/6CVPsjiRo0DOKdKbVVCKsIVB8KFvPN H4iL+/oeZAgjGgXf9ojkjubXynAJ6Z4q6AFhUKT+hiC3VAqXvP8E1ILIMEUL5CQa0uLT oh6sx93CjWuvfwRnFibhnYXJvU4gElIeOsiKcdjqiesPOWQO1qEIsCIGkVtUmHtqyaYS wOF+yUe/0tf+xDB+GADRSWSFL6PhzCWNR2aO5uxSNPNb3eDd4Ofi9+kuAazltqdLEBWB Qm0DTm6qvKvTe3lItiduDvzd8kePr0AUknmZWzCpvb/Macd4dwGKmead96x4S52zU6Ec SbRA== X-Gm-Message-State: AOAM533bVYwXpM1RYqriMArSvC9B5KZKuTItHmGuZ6diunewF/ndw0mL EiGn7of5JYXS9SUIBmfVOvs= X-Google-Smtp-Source: ABdhPJw33QZ9iKLv6ORoshM/pjgLfmYsDSLJ9+/KkoQa0lnqJqwD7eHAqlULIgO6+vXzpI+Bm8ASIQ== X-Received: by 2002:aa7:c582:0:b0:40a:92b2:1bc4 with SMTP id g2-20020aa7c582000000b0040a92b21bc4mr3520586edq.202.1645115254750; Thu, 17 Feb 2022 08:27:34 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:34 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 12/13] iio: imu: add BNO055 I2C driver Date: Thu, 17 Feb 2022 17:27:09 +0100 Message-Id: <20220217162710.33615-13-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This path adds an I2C driver for communicating to a BNO055 IMU via I2C bus and it enables the BNO055 core driver to work in this scenario. Signed-off-by: Andrea Merello --- drivers/iio/imu/bno055/Kconfig | 11 +++++++ drivers/iio/imu/bno055/Makefile | 1 + drivers/iio/imu/bno055/bno055_i2c.c | 50 +++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 drivers/iio/imu/bno055/bno055_i2c.c diff --git a/drivers/iio/imu/bno055/Kconfig b/drivers/iio/imu/bno055/Kconfig index 8a83639ad2a9..3693a408e270 100644 --- a/drivers/iio/imu/bno055/Kconfig +++ b/drivers/iio/imu/bno055/Kconfig @@ -12,3 +12,14 @@ config BOSCH_BNO055_SERIAL This driver can also be built as a module. If so, the module will be called bno055_sl. + +config BOSCH_BNO055_I2C + tristate "Bosch BNO055 attached via I2C bus" + depends on I2C + select REGMAP_I2C + select BOSCH_BNO055_IIO + help + Enable this to support Bosch BNO055 IMUs attached via I2C bus. + + This driver can also be built as a module. If so, the module will be + called bno055_i2c. diff --git a/drivers/iio/imu/bno055/Makefile b/drivers/iio/imu/bno055/Makefile index 416f0ff96de5..2fe2b0857903 100644 --- a/drivers/iio/imu/bno055/Makefile +++ b/drivers/iio/imu/bno055/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_BOSCH_BNO055_IIO) += bno055.o obj-$(CONFIG_BOSCH_BNO055_SERIAL) += bno055_sl.o +obj-$(CONFIG_BOSCH_BNO055_I2C) += bno055_i2c.o diff --git a/drivers/iio/imu/bno055/bno055_i2c.c b/drivers/iio/imu/bno055/bno055_i2c.c new file mode 100644 index 000000000000..9900e2a4d905 --- /dev/null +++ b/drivers/iio/imu/bno055/bno055_i2c.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for I2C-interfaced Bosch BNO055 IMU. + * + * Copyright (C) 2021 Istituto Italiano di Tecnologia + * Electronic Design Laboratory + * Written by Andrea Merello + */ + +#include +#include +#include + +#include "bno055.h" + +#define BNO055_I2C_XFER_BURST_BREAK_THRESHOLD 3 /* FIXME */ + +static int bno055_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct regmap *regmap = + devm_regmap_init_i2c(client, &bno055_regmap_config); + + if (IS_ERR(regmap)) { + dev_err(&client->dev, "Unable to init register map"); + return PTR_ERR(regmap); + } + + return bno055_probe(&client->dev, regmap, + BNO055_I2C_XFER_BURST_BREAK_THRESHOLD, true); +} + +static const struct i2c_device_id bno055_i2c_id[] = { + {"bno055", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, bno055_i2c_id); + +static struct i2c_driver bno055_driver = { + .driver = { + .name = "bno055-i2c", + }, + .probe = bno055_i2c_probe, + .id_table = bno055_i2c_id +}; +module_i2c_driver(bno055_driver); + +MODULE_AUTHOR("Andrea Merello"); +MODULE_DESCRIPTION("Bosch BNO055 I2C interface"); +MODULE_LICENSE("GPL v2"); From patchwork Thu Feb 17 16:27:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrea Merello X-Patchwork-Id: 12750430 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3D9CC433EF for ; Thu, 17 Feb 2022 16:27:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243229AbiBQQ17 (ORCPT ); Thu, 17 Feb 2022 11:27:59 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243182AbiBQQ1z (ORCPT ); Thu, 17 Feb 2022 11:27:55 -0500 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 934ABB2E08; Thu, 17 Feb 2022 08:27:37 -0800 (PST) Received: by mail-ej1-x633.google.com with SMTP id d10so8516236eje.10; Thu, 17 Feb 2022 08:27:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=x0CAWbNuIuDfQpbJainmJSxgl05KS6pI1nwvw77TVRY=; b=XYjjMpDhaV3y4guUdwjcp7pgm0CCJvpxAYqNX/uRe1b80YfpnK0ARRNBQuuarUXsmt IuoP9UGADm0phg5YjhICWB2TYsr8Q15w9dvHc8shFxuizpjNbhIo8BnklYElCvt1LVfH aHEjCRuS/wUZhdmJDKGXCXZH2MeGUT5QgqowghefD1jO/9ZYE8o3eZGL/FRNKnJPk8ni ky4p5t2DWKWEzWnNXX/Q+f4T3nvBS9CpocYX9sHIJdlvOprs79hV9JmszQBdz25z9bUi Q2t7B+W8f1RiL4+buQH0S5DKRQ9D5BHYgteg7ctM8Z1DIkqdwZjesChIj/808a++1E4J cu2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=x0CAWbNuIuDfQpbJainmJSxgl05KS6pI1nwvw77TVRY=; b=5v4SbT74eWBvdrpKEuR6C2yACdN6GvJI9LmPptnr80C4XKH56j6k/94iC/fPG0kybQ im6aGSLxQh6uBYqXTxJKmmQtRqO8SNfiSh6xLxyxsSS+Y7jxYXFmHtdhWCrU9c+Sc00p W9FtU3qCKZbP2L0M0GkrqGc/FbJz1XZS7jznZjLfueLvgrKQXi7ddoxlFerWoiEO+W+q DfJhkweC42W6z6eNGN2qZwp5lJpNmhsqJ75Hd7D3hBRDCrDZ1b1Q+6hiHfZese3VHmAl BY8rszViXilMVzRnQ/t8CSYNGgOKTl4kpYoT+Usp9L0nF0fComXmwOQt2Rj0w2+Sduwf eT0Q== X-Gm-Message-State: AOAM533VpJkhagUH9xAj/OKI/SxuLha4CIW8r+BTobfJMbVOCANbwcPT 6W5KizBWCro6mrguGc04n14= X-Google-Smtp-Source: ABdhPJzlwfwiOWxf+goTzxLgaAJ6/r/qIVfSm0JJTyMJULqZyhZQz20H7AUpWOyqFSUm3xkOn6AE4Q== X-Received: by 2002:a17:907:2bf6:b0:6b9:725e:4e1f with SMTP id gv54-20020a1709072bf600b006b9725e4e1fmr2943906ejc.527.1645115256153; Thu, 17 Feb 2022 08:27:36 -0800 (PST) Received: from poker.lan (static.2-229-210-222.ip198.fastwebnet.it. [2.229.210.222]) by smtp.gmail.com with ESMTPSA id j13sm3653742edw.24.2022.02.17.08.27.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Feb 2022 08:27:35 -0800 (PST) From: Andrea Merello To: jic23@kernel.org, mchehab+huawei@kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: lars@metafoo.de, robh+dt@kernel.org, andy.shevchenko@gmail.com, matt.ranostay@konsulko.com, ardeleanalex@gmail.com, jacopo@jmondi.org, Andrea Merello , Andrea Merello Subject: [v3 13/13] docs: iio: add documentation for BNO055 driver Date: Thu, 17 Feb 2022 17:27:10 +0100 Message-Id: <20220217162710.33615-14-andrea.merello@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220217162710.33615-1-andrea.merello@gmail.com> References: <20220217162710.33615-1-andrea.merello@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Signed-off-by: Andrea Merello --- Documentation/iio/bno055.rst | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/iio/bno055.rst diff --git a/Documentation/iio/bno055.rst b/Documentation/iio/bno055.rst new file mode 100644 index 000000000000..4bb185075325 --- /dev/null +++ b/Documentation/iio/bno055.rst @@ -0,0 +1,53 @@ +.. SPDX-License-Identifier: GPL-2.0 +============================== +BNO055 driver +============================== + +1. Overview +=========== + +This driver supports Bosch BNO055 IMUs (on both serial and I2C busses). + +Accelerometer, magnetometer and gyroscope measures are always provided. +When "fusion_enable" sysfs attribute is set to 1, orientation (both Euler +angles and quaternion), linear velocity and gravity vector are also +provided, but some sensor settings (e.g. low pass filtering and range) +became locked (the IMU firmware controls them). + +IIO attributes for unavailable measurements (e.g. Euler angles when fusion +mode is disabled) just read zero. + +This driver supports also IIO buffers. + +2. Calibration +============== + +The IMU continuously performs an autocalibration procedure if (and only if) +operating in fusion mode. The magnetometer autocalibration can however be +disabled writing 0 in the sysfs in_magn_calibration_fast_enable attribute. + +The driver provides access to autocalibration flags (i.e. you can known if +the IMU has successfully autocalibrated) and to the calibration data blob. + +The user can save this blob in a firmware file (i.e. in /lib/firmware) that +the driver looks for at probe time. If found, then the IMU is initialized +with this calibration data. This saves the user from performing the +calibration procedure every time (which consist of moving the IMU in +various way). + +The driver looks for calibration data file using two different names: first +a file whose name is suffixed with the IMU unique ID (exposed in sysfs as +serial_number) is searched for; this is useful when there is more than one +IMU instance. If this file is not found, then a "generic" calibration file +is searched for (which can be used when only one IMU is present, without +struggling with fancy names, that change on each device). + +Valid calibration file names would be e.g. + bno055-caldata-0e7c26a33541515120204a35342b04ff.dat + bno055-caldata.dat + +In non-fusion mode the IIO 'offset' attributes provide access to the +offsets from calibration data (if any), so that the user can apply them to +the accel, angvel and magn IIO attributes. In fusion mode they are not +needed (the IMU firmware internally applies those corrections) and they +read as zero.