From nobody Sun May 24 18:41:54 2026 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BDA90390233 for ; Sun, 24 May 2026 08:53:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612823; cv=none; b=l/uzNvXec4gcMagD2elHNifrni37ku2CekWnueLYMl6nyAxKey67vt59TSSgluOGBtuSL8GxR80VwKpJ65oYv7yJJD6C7jQFmLNWl85TppmC9pgaknrHfNNRz7Vchj5ItspU4YuEsjnr/r2D0XOhXMcrDkkn5geSBtksh5jOePM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612823; c=relaxed/simple; bh=mnbsGdXqPudND64KitG2wVJI1G17JSPfBSazzNlu7eQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ruouVFN52kj/C3Xak8F2L+nnEMlgk51f0GH2TDf7iBhqHWNBhJmoFNAXkycsdg+wznj2n2iOY9ptQ4xhJ/vIZ7nK3nUeqzMowVGfndeyDr3tCkVxyCeQIreBpaS83CTd1q+dsr1YfoQUqNnbDnr/X83CT1MP2XZXqwLwe8lBqnM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MhFg2QyN; arc=none smtp.client-ip=209.85.210.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MhFg2QyN" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-83945063f70so4516840b3a.0 for ; Sun, 24 May 2026 01:53:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779612821; x=1780217621; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2xECuTc1TXvHh4Pd2rPahPYqdqFjRE3a5nhCp5fRA9c=; b=MhFg2QyNj8bcNiH7c2VeqPQexN2Nc6T++/Wqy0R23W3bTy97ZG6u5HiJjHPjDbYahM iOoqxj+3P3BrBvvAQGqooyNC05TAwfa+Nd/F5xq3C4DxSbv1+uAUMho1n3l5M0nXFQGZ GSBzeXqjcxPqk97eefppqw/1RBPj8pKir2xGr4jklGY9Bih6Aa+aBIZKLHn9Q11XkUns 2NnXTexLik9XhUhyp3xJOz9Q0Ix3GTtBbgQBnz43xhC1ZhektMeo+CIRqUf2gpkdPORZ 7N3SaPN/E0EZzy7SAgeUbN9xuFY2r/vtwmHEHhDK4daNJE3OHMdC2anoTF+1Ba1NFoBZ vL9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779612821; x=1780217621; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=2xECuTc1TXvHh4Pd2rPahPYqdqFjRE3a5nhCp5fRA9c=; b=HGoJ0FPQ4BqDb6BmOJeBwm2zpm2GJlOsVmbF09+YO+IsFFfXttYx5CZsNy8v4fInmm BOozLKyz+4ZGDFu00qukvIdVPj7hgHOx4rSIlPuOj6ZxUfU1/R0aUNrK/SvlkAeQVvO7 zfwF6kYDblKHVwqdQUyfFs1zFUtTMb50FZktIejOGO4Y9ZWOgiy8JK5CQOkRh4FiKioI Dw8jtHHzo2+zrTXT0cxQlHu7hU/8r+/lDuYIaZoKLbmudiza7nDKk1TvTrYyUQ5e9qs7 0NxHKK1HfzwG+nCJFIzF/5scqYdRv2U1SWv+ZABANlpug732LkLmffrFh/bflBBcb41x Wqhg== X-Forwarded-Encrypted: i=1; AFNElJ81DViVc4aoMwljWp369NRsf3V+rMYUczbBjCeSaIiv9guLWmL9YlfXml6/2fS17/vbVhO1Bn/ktHv6mnk=@vger.kernel.org X-Gm-Message-State: AOJu0Yxmm8vo6PuxctB7wK3ifSTfk2HF69MCQVKhfXKJmqr4eY/7V9uE vW7Gro6hTFT6edgzZm1vlsxRXslVs1TMgk2mxlLvnaiz7D0vK9eW45yj X-Gm-Gg: Acq92OFrBaanwk1H9gw+tygFfHvgU2myW8nvFNr0EyrSDAkk4woAn/tJB33oR4iIBk1 DD9eMbomDx1lpn8nabj68VwBqv6zQn0s7I99kF44Byh0t2EFjRixt/rlRSyKWaMAn53o1SbBpQj QzQ8EFaS94t4zE4ejpTqz8StbDISmigiHZxE+cy9ULObxz4RqaXvzyOX5ZkaUE8spMogOUuRAwB YbndPU7H7t0hlDtScCo+qqK9f4mvNNgCZeBewyBmELnh+/tsZTXSWyVCcziAA/fUZQiSeM83vrB G9OnJeTyPJE2EMfiZgjQmXnpv4+sMFQiKZ/hoop0XKk7TkGtn8Rx9ZtU9iZhvpdgCe1ob92iCCn JHJR7d3XxKTP6sOjN/Ln/Gimxm7k94mQ+VwAGOWSRX/OPoQOelbHngm7baC2PFP1BecG39lFD16 j2aOLUVrqXWUCHaEu6qkidkMQqDlIz53wxdAcR8D6+jTQAgk+YOxuIsuJXASLiSJRtUezdw39MD /GRmZ6PM0f4vsfrdSliHqdzmqKKzOTisH2DmA== X-Received: by 2002:a05:6a00:8d82:b0:835:7c0e:b530 with SMTP id d2e1a72fcca58-841606f55aemr8287017b3a.0.1779612821128; Sun, 24 May 2026 01:53:41 -0700 (PDT) Received: from DESKTOP-G3E0OSP.localdomain ([112.172.255.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ea4de4sm6353116b3a.35.2026.05.24.01.53.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2026 01:53:40 -0700 (PDT) From: Jinseob Kim To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jinseob Kim Subject: [PATCH RFC v2 1/7] dt-bindings: iio: add Open Sensor Fusion UART device Date: Sun, 24 May 2026 17:53:06 +0900 Message-ID: <20260524085312.15369-2-kimjinseob88@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524085312.15369-1-kimjinseob88@gmail.com> References: <20260524085312.15369-1-kimjinseob88@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a binding for the OSF0 UART-attached sensor aggregation device. Signed-off-by: Jinseob Kim --- .../iio/imu/opensensorfusion,osf-uart.yaml | 33 +++++++++++++++++++ .../devicetree/bindings/vendor-prefixes.yaml | 2 ++ 2 files changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/imu/opensensorfus= ion,osf-uart.yaml diff --git a/Documentation/devicetree/bindings/iio/imu/opensensorfusion,osf= -uart.yaml b/Documentation/devicetree/bindings/iio/imu/opensensorfusion,osf= -uart.yaml new file mode 100644 index 000000000..d4a8f6819 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/opensensorfusion,osf-uart.y= aml @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/opensensorfusion,osf-uart.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Open Sensor Fusion UART sensor aggregation device + +maintainers: + - Jinseob Kim + +description: + UART-attached sensor aggregation device using the OSF0 frame format. + The device sends capability, status, and sample frames to the host. + +properties: + compatible: + const: opensensorfusion,osf-uart + +required: + - compatible + +additionalProperties: false + +examples: + - | + serial { + osf { + compatible =3D "opensensorfusion,osf-uart"; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Docum= entation/devicetree/bindings/vendor-prefixes.yaml index 28784d66a..121b83f70 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1239,6 +1239,8 @@ patternProperties: description: OpenRISC.io "^openwrt,.*": description: OpenWrt + "^opensensorfusion,.*": + description: Open Sensor Fusion project "^option,.*": description: Option NV "^oranth,.*": --=20 2.43.0 From nobody Sun May 24 18:41:54 2026 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9BFF738F928 for ; Sun, 24 May 2026 08:53:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612828; cv=none; b=S9Lcs+jaIYhE7m62WtI5JW2aUeR8m9rJACRG7es+0Y0Ugq13aqZWECbwmELhELNwujyr03KNgRhhKGts9HmrQmOWtEqmAo+SUSyfF6tl/s+Dyp4Jizf9fBY3qvtFAOUYza8sV7XnJ3rnFiiwNlDsSwMKkVGglJl2Zj3GM17sp94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612828; c=relaxed/simple; bh=g1+tHbgrYncMfc1QByZAwPDHezhvG35MPCiAjWaYTGw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S1mi1TB5MNA97awj+xVJVfoY4o9Ehdxh8f/VFF0HOiVC3HYV3YPfp7hJ1CmsXLDfJrlSReZju3Jrd6Lyg6eE2KjRYa8sHWqh+NJaJBebBChAN5iLBwjNA4YnJbbfGG0iUUjN2NLn9AUMUvAnarITDa6khPAjBnGcpYMlRttJIgA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=obbUXyw+; arc=none smtp.client-ip=209.85.215.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="obbUXyw+" Received: by mail-pg1-f180.google.com with SMTP id 41be03b00d2f7-c801d732058so3822439a12.1 for ; Sun, 24 May 2026 01:53:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779612826; x=1780217626; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cR6MVBWrx7Nf/YCvBY1+uoEtosj5P+qxsyQ19bAkpkk=; b=obbUXyw+QNUEGA0qAtV3GTjtQVMw2MbL+UeFF637n/4TcThGXTBleRmaDmRmhpMzJC Xyhdpudd0ZFw5vsunv1/fs0CjpJI89kLfPGK1eDjnOvA//nX12YeHhDz6wlFPqcypCVz 44Stf1XKu0r9LqCBUcJKZjDwxjxrNikH368MQCOTUKWiqH75Wjq2oD+7W/laNN6d/NiE 9YEuQRb+t43LVjoR+1IABptYxqHZARKK1vmZ2jzESF/CuWKXcIh7S6TffIJ6qGdmdGzl cGUV7GkZsFzNCcocCHqq67456Rtx9hvwt0925Lm0Qvg+ZTOioAsoa/n3Sm5t8kfBMGE2 cTLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779612826; x=1780217626; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=cR6MVBWrx7Nf/YCvBY1+uoEtosj5P+qxsyQ19bAkpkk=; b=d2b/pP4hTdMmXbgW26j3Gkw9YXg5Uycw+c1vfVDi/o01NLd4J89k2onyiZlvlksrMJ funNLSYk1MNRnjPxsd3/YDC9fq3pCt7506QTFeOB4axQ51x8SClSkaa0tpReXM+TijlM ST6jBJBCzUa5HCVlNpnx3ufLyPgk+2ga0fJrj+9VzHa0Q44+Wbsh9Sz5JkNhT9Klm5YV pt2PreRah1XbQohXURdxcAU6olNpWtiHVLT/cS5F7sIcXNk9vuovOW69pU8Z2JmJQjk/ o1MvopJcLSXaQdRvx0eMT/0pH9nuuV0FUoV+ltqqyuLeubdcGUnazq2ykeGumYAOH74p YBQQ== X-Forwarded-Encrypted: i=1; AFNElJ/QCMBE21Q1TeyKyE3U7YkSRbWdeVLO2UqOxlvOXfvV9pHCwU5to4KQnqnJNNavpq1qYmCSmKcxlTEGx8g=@vger.kernel.org X-Gm-Message-State: AOJu0Yw4f7PNaWmiIIhLT+raFArFPqY+GaC2gxF+2FhhKN2USy3oYCRC EEkO7KJ+pIHc9nYu3/Mh9/b1DpOpeAdMHnSICWieijPEQaKejUwzszCW X-Gm-Gg: Acq92OFnavqz9roPhWJNGm5GMn5gN8S+91KFzLKLUKSfIYNR2GsvKMtG7NghxpcXdbz os7KxmoYZyRcAhEgvFTbj+CvVWecb0AA8xirGmvLqMLgoyTvPJIhuJRVFtvt4ik/5njo9Gz0V1K OpLPfNEnKrZ0I260Hrfjx2m3osHKSZssAXQaGhkV5bqKi2U353hY4Ks0jsGx1N6c4Nm0miFWXQd wg6G8TEnr9AAShjUUe9VxtWN1LVv/3GxzMvk1bD82ntP+cNbYRHDDd1xtDRbb0zwW2ov0yyONg4 74oeoFVeO/wQUVN+8CRRhj0gvGWeDrWvz+Xdf++TowY7rFqNSa61p3E6bBWUoZeINjqGf1/ymVp yVNFz4x55TF2WXX3zvpPEm5NStD3sAYTpujCsYAARzMsIWz9/Q5Ws64mBueJxuBXyfvxGkexumI 45V4jA9nihGEoLHIjGpw6e87eCQNJGWEfErVrBG5HE1wnC4s2aJn8pKESf7/++eshDFzsrpzkfd Ev3w+fq1XXUIqHTW5spDXx3xV82VnM/VW/Q7PJcismPEq4z X-Received: by 2002:a05:6a20:d80f:b0:3a3:128f:1c77 with SMTP id adf61e73a8af0-3b329541ab3mr8321476637.12.1779612825886; Sun, 24 May 2026 01:53:45 -0700 (PDT) Received: from DESKTOP-G3E0OSP.localdomain ([112.172.255.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ea4de4sm6353116b3a.35.2026.05.24.01.53.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2026 01:53:45 -0700 (PDT) From: Jinseob Kim To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jinseob Kim Subject: [PATCH RFC v2 2/7] Documentation: iio: add Open Sensor Fusion protocol v0 reference Date: Sun, 24 May 2026 17:53:07 +0900 Message-ID: <20260524085312.15369-3-kimjinseob88@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524085312.15369-1-kimjinseob88@gmail.com> References: <20260524085312.15369-1-kimjinseob88@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Document the OSF0 frame format and payloads used by the driver. Signed-off-by: Jinseob Kim --- .../iio/open-sensor-fusion-protocol-v0.rst | 267 ++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 Documentation/iio/open-sensor-fusion-protocol-v0.rst diff --git a/Documentation/iio/open-sensor-fusion-protocol-v0.rst b/Documen= tation/iio/open-sensor-fusion-protocol-v0.rst new file mode 100644 index 000000000..4800a3ce6 --- /dev/null +++ b/Documentation/iio/open-sensor-fusion-protocol-v0.rst @@ -0,0 +1,267 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +Open Sensor Fusion protocol v0 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D + +This document describes the OSF0 UART wire format used by the Linux IIO +driver. It is not a firmware programming interface. + +Device model +------------ + +An Open Sensor Fusion UART device is a sensor aggregation device. It sends +binary frames from the device to the host. The host driver decodes the fra= mes +and maps supported sensors to IIO devices. + +The hardware used for smoke testing is an OSF GREEN prototype with an +STM32F405RGT6 MCU, an ICM42688P-class IMU, and an MMC5983MA magnetometer. = That +hardware is a test target, not part of the binding ABI. + +Transport +--------- + +The transport is UART at 115200 baud, 8 data bits, no parity, and 1 stop b= it. +The Linux transport is serdev. The v0 upstream driver covers device-to-host +frames. Flow control is not used by the tested stream. + +Byte order +---------- + +All multi-byte integer fields are little-endian. Samples use signed 32-bit +little-endian integers when ``sample_format`` is ``S32``. + +Frame format +------------ + +Each frame has a fixed 38-byte header, a payload, and a 4-byte CRC. + +.. list-table:: + :header-rows: 1 + + * - Offset + - Size + - Field + - Description + * - 0 + - 4 + - magic + - ASCII ``OSF0`` + * - 4 + - 1 + - protocol_major + - Must be ``0`` + * - 5 + - 1 + - protocol_minor + - Minor version + * - 6 + - 2 + - header_len + - Must be ``38`` + * - 8 + - 2 + - message_type + - Message type + * - 10 + - 4 + - payload_len + - Payload length in bytes + * - 14 + - 8 + - sequence + - Monotonic device sequence + * - 22 + - 8 + - timestamp_us + - Device timestamp in microseconds + * - 30 + - 4 + - flags + - Message flags + * - 34 + - 4 + - reserved + - Must be zero for v0 + * - 38 + - payload_len + - payload + - Message payload + * - 38 + payload_len + - 4 + - crc32 + - CRC32 over header and payload + +The frame CRC is IEEE CRC32 as implemented by ``crc32_le()`` with initial +value ``0xffffffff`` and final XOR value ``0xffffffff``. The CRC field is = not +included in the CRC input. + +Message types +------------- + +.. list-table:: + :header-rows: 1 + + * - Value + - Name + - Direction + * - ``0x0001`` + - ``SENSOR_SAMPLE`` + - device to host + * - ``0x0002`` + - ``DEVICE_STATUS`` + - device to host + * - ``0x0003`` + - ``CAPABILITY_REPORT`` + - device to host + +Message types ``0x7f00`` through ``0x7fff`` are reserved. Values at or abo= ve +``0x8000`` are vendor private and are ignored by the upstream driver. + +``SENSOR_SAMPLE`` payload +------------------------- + +The base payload size is 16 bytes. + +.. list-table:: + :header-rows: 1 + + * - Offset + - Size + - Field + - Description + * - 0 + - 2 + - sensor_type + - Sensor type ID + * - 2 + - 2 + - sensor_index + - Instance index + * - 4 + - 2 + - channel_count + - Number of S32 channels + * - 6 + - 2 + - sample_format + - Must be ``1`` (``S32``) + * - 8 + - 4 + - scale_nano + - Scale factor in nano-units + * - 12 + - 4 + - reserved + - Must be zero for v0 + * - 16 + - 4 * channel_count + - samples + - Signed 32-bit channel samples + +``DEVICE_STATUS`` payload +------------------------- + +The payload size is 20 bytes. Fields are ``uptime_s``, ``status_flags``, +``error_flags``, ``dropped_frames``, and a reserved field. Each field is +32 bits. + +``CAPABILITY_REPORT`` payload +----------------------------- + +The base payload size is 4 bytes. It contains ``capability_count`` and a +reserved field. Each capability entry is 20 bytes: + +.. list-table:: + :header-rows: 1 + + * - Offset + - Size + - Field + - Description + * - 0 + - 2 + - sensor_type + - Sensor type ID + * - 2 + - 2 + - sensor_index + - Instance index + * - 4 + - 2 + - channel_count + - Number of channels + * - 6 + - 2 + - sample_format + - Must be ``1`` (``S32``) + * - 8 + - 4 + - scale_nano + - Scale factor in nano-units + * - 12 + - 4 + - flags + - Capability flags + * - 16 + - 4 + - reserved + - Must be zero for v0 + +Capability flag bit 0 means enabled by default. Bit 1 means calibrated dat= a can +be provided by the device. Other bits are invalid for v0. + +Sensor type IDs +--------------- + +.. list-table:: + :header-rows: 1 + + * - Value + - Sensor + - IIO mapping + * - ``0x0001`` + - accelerometer + - ``IIO_ACCEL``, X/Y/Z + * - ``0x0002`` + - gyroscope + - ``IIO_ANGL_VEL``, X/Y/Z + * - ``0x0003`` + - magnetometer + - ``IIO_MAGN``, X/Y/Z + * - ``0x0004`` + - barometer + - not mapped in the initial driver + * - ``0x0005`` + - temperature + - ``IIO_TEMP`` + * - ``0x0006`` + - humidity + - not mapped in the initial driver + * - ``0x0007`` + - ambient light + - not mapped in the initial driver + * - ``0x0008`` + - proximity + - not mapped in the initial driver + +Scaling +------- + +``scale_nano`` is the per-channel scale value in nano-units. The Linux dri= ver +maps it to ``IIO_CHAN_INFO_SCALE`` as integer plus nano. The exact physical +unit depends on the IIO channel type. + +Timestamps +---------- + +The frame header carries ``timestamp_us``, a device-side timestamp in +microseconds. v0 transports this value for ordering and diagnostics. The d= river +does not use it as a production-grade host-correlated timestamp. Buffered = IIO +timestamps follow IIO timestamp clock handling. + +Non-goals for v0 upstream +------------------------- + +The v0 upstream driver does not include USB transport, fusion output, +AHRS/Kalman output, calibration command ABI, custom sysfs control surface, +production timestamp correlation, or runtime capability removal. --=20 2.43.0 From nobody Sun May 24 18:41:54 2026 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28FAF390989 for ; Sun, 24 May 2026 08:53:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612832; cv=none; b=CjYtrvdxChYVE300LEJlnVDE6qaZ3J2aMchFfKIXsFbLBVcW9qtS3m3AXif/SvJy3KsdsWWL6BLwnuQ/wMOVi9pGYCdeW+7SYK3fOJuEVAkjfjjSyFbylDj9ytkDhHJ6WBJ00avJf/PAvtbZqCq9fPE8z1y5ngkWxfZ8GvJLfPc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612832; c=relaxed/simple; bh=ZCL6ezRfaQJ8MfsplAkjQLstX77U5p+nsINwl0rR2Zo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lOTpUJ45VLjIczeI5kAsfeVddvcaIDX+Vsj4C/LLNUd+rnmGsLSKq6FAv8R0jWz30D6ItIB6pgOCOgI/1AIFtlXAVY9v5k4Tk17ijdT6CQYVGPIAsGvFEqxd/U9tElbDAdXHQSgazKqwgcef5GVSXooScjdoVu317f3UUwgPRHU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WuaqKoul; arc=none smtp.client-ip=209.85.210.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WuaqKoul" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-83ea84df1d0so2858055b3a.2 for ; Sun, 24 May 2026 01:53:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779612829; x=1780217629; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ymRZGCPEm3o47nC+8rZrU36hS8/8eEcKC15QEK7V6Do=; b=WuaqKoul7l731UTKxm3uJULxGHP3rIIBL+K8v4E94jihHHIyuTU7FgJ57FnDsrHaWx eeW3YPtcuZ3VpLvmQu5lnxOzhRRCyWdB37sf+6ILZJTHsTHtCsdFaceEyIxnSrvbV4at UXLZNfYae5Nus7jM0UuX8qtUePK2jALUwvR049R+jKfJpBpgUozwGdsCEhDitJuIxXoI 61JVPenOUsfbq/yHPHyCBieJjSzRwCWdpKXfV0Is75al0mIugKdRBrfhCf2Pd9RCiyzV /17Pny8A0WIc6QgZmUYSxjUREis3s5+dZzeqekMN6q9IbFp3Y1tU6jRO3L/EPAcI6EyB OuOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779612829; x=1780217629; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ymRZGCPEm3o47nC+8rZrU36hS8/8eEcKC15QEK7V6Do=; b=sySsQiT1oi8OlISAmV63waa12rHwpeYg+uwaHD9E+nYlDiaIdUrmTMNpLJyBBmjs7h i6ISW5ZqEmax4CTn0D2pbgYZ07sXbcC+IeJvwRVD+TAovfM/IZ1Wx4xhc0pYpAekiRdm 46qnCmDUe00+3zl6sdzEKsDOwKKkhajnESrn8335wVWDv2FLi+kScID/d7roVpTnFepl wVBItb99aY7dqO1BBgvVGLUet+bKiwmu3zii7HiPzMC5cVBYJkuxCpS9bjr6g49GhqVj quNInJAa6YaVaCmiFKb3b2y0qXIh/U1NmWnm9H2J9Jk7Hp2zkzFXNrVp1BnsHVo4P/Ms c1PQ== X-Forwarded-Encrypted: i=1; AFNElJ+hqCW4xczBSz5yXMpcZKaqlqKetqJIQvQvNUFUHjtvYpdQqKxIM7/MX7lmy/HQkPqutimsdMZDN1wTUlE=@vger.kernel.org X-Gm-Message-State: AOJu0YxXHIqzsQ+aq/lu7pocgZPnwe+Y/hVZh1REMH5pWMxjdqK7886Q NQ0GE7xCed3U6bO/ZRILUCkr/5oIOpo687UYM4hj9sIMCxy39AP3O/9k X-Gm-Gg: Acq92OGvJA8FfcNyWdwz0yGe0K3becOqo/2zBEzuxxzVpNy0SFfI18brDIqFaW5/iDW QuJzO7ehMnx/SIBKqtZ7s2JhqAZM+M6GoepWWzvT5sDfTZ4fReAmInTZTU5saBvqdbo6yvGf6TO OA9z2dNnLbs7Gy4lLTgctKhfU8XONAZvkisMqoX7ucwJhvbkIqwH7Ki00rxLT1JpFgB3UNYHLLG NbsonOQx31MpKPfg4/FZbZOed6vw6IJV0EIQlKBgVH9EvHaGBhn84gGK43dzyPos+cJh1wKX+jP ky9ehTzRuPO1s3CqN33qdxKC1iW74H7Sil+sGEe+/cqqzQ+pQhKeewRuHYiQ3uyzyiOQlKPTAlA REDGxKpqpKgits7YCQlpzOBwYmwYimF0G0zIAfIaq6e8A1eSHFEeVEfNF6/+1CyZ6OrK5a/vIgS zBiCOIf+XUSly3eefpJ6uAbTFhoScdpXwb6pTXZKJRy6qfMhBkoAhq3oWOhM+rFw9R3RIAZMtbg 9P8FYNQvmFk3pYpPVLioEeH2Wfj9OMgFciBq6SuPOsgXcZjmxCn2zP8dMA= X-Received: by 2002:a05:6a00:949d:b0:841:6414:44ce with SMTP id d2e1a72fcca58-84164147ca5mr7923029b3a.22.1779612829486; Sun, 24 May 2026 01:53:49 -0700 (PDT) Received: from DESKTOP-G3E0OSP.localdomain ([112.172.255.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ea4de4sm6353116b3a.35.2026.05.24.01.53.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2026 01:53:49 -0700 (PDT) From: Jinseob Kim To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jinseob Kim Subject: [PATCH RFC v2 3/7] iio: osf: add protocol v0 decoding Date: Sun, 24 May 2026 17:53:08 +0900 Message-ID: <20260524085312.15369-4-kimjinseob88@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524085312.15369-1-kimjinseob88@gmail.com> References: <20260524085312.15369-1-kimjinseob88@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add OSF0 frame and payload decoders for device-to-host messages. Signed-off-by: Jinseob Kim --- drivers/iio/opensensorfusion/osf_protocol.c | 220 ++++++++++++++++++++ drivers/iio/opensensorfusion/osf_protocol.h | 100 +++++++++ 2 files changed, 320 insertions(+) create mode 100644 drivers/iio/opensensorfusion/osf_protocol.c create mode 100644 drivers/iio/opensensorfusion/osf_protocol.h diff --git a/drivers/iio/opensensorfusion/osf_protocol.c b/drivers/iio/open= sensorfusion/osf_protocol.c new file mode 100644 index 000000000..ac3c37ae2 --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_protocol.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include + +#include "osf_protocol.h" + +#define OSF_CRC32_INIT GENMASK(31, 0) +#define OSF_CRC32_XOROUT GENMASK(31, 0) + +static bool osf_sensor_type_valid(u16 sensor_type) +{ + return sensor_type >=3D OSF_SENSOR_ACCELEROMETER && + sensor_type <=3D OSF_SENSOR_PROXIMITY; +} + +static u32 osf_crc32_ieee(const u8 *buf, size_t len) +{ + return crc32_le(OSF_CRC32_INIT, buf, len) ^ OSF_CRC32_XOROUT; +} + +int osf_protocol_decode_frame(const u8 *buf, size_t len, + struct osf_frame *frame, size_t *frame_len) +{ + u32 expected_crc; + u32 actual_crc; + u32 payload_len; + size_t total_len; + u8 major; + + if (!buf || !frame || !frame_len) + return -EINVAL; + + if (len < OSF_FRAME_MIN_LEN) + return -EMSGSIZE; + + if (buf[0] !=3D 'O' || buf[1] !=3D 'S' || buf[2] !=3D 'F' || buf[3] !=3D = '0') + return -EPROTO; + + major =3D buf[4]; + if (major !=3D OSF_PROTOCOL_MAJOR) + return -EPROTO; + + if (get_unaligned_le16(buf + 6) !=3D OSF_FRAME_HEADER_LEN) + return -EPROTO; + + payload_len =3D get_unaligned_le32(buf + 10); + if (payload_len > len - OSF_FRAME_MIN_LEN) + return -EMSGSIZE; + + total_len =3D OSF_FRAME_HEADER_LEN + payload_len + OSF_FRAME_CRC_LEN; + expected_crc =3D osf_crc32_ieee(buf, OSF_FRAME_HEADER_LEN + payload_len); + actual_crc =3D get_unaligned_le32(buf + OSF_FRAME_HEADER_LEN + payload_le= n); + + if (actual_crc !=3D expected_crc) + return -EBADMSG; + + frame->protocol_minor =3D buf[5]; + frame->message_type =3D get_unaligned_le16(buf + 8); + frame->payload_len =3D payload_len; + frame->sequence =3D get_unaligned_le64(buf + 14); + frame->timestamp_us =3D get_unaligned_le64(buf + 22); + frame->flags =3D get_unaligned_le32(buf + 30); + frame->reserved =3D get_unaligned_le32(buf + 34); + frame->payload =3D buf + OSF_FRAME_HEADER_LEN; + frame->crc =3D actual_crc; + *frame_len =3D total_len; + + return 0; +} + +int osf_protocol_decode_sensor_sample(const struct osf_frame *frame, + struct osf_sensor_sample *sample) +{ + u16 channel_count; + u16 sample_format; + u32 expected_len; + const u8 *payload; + + if (!frame || !sample || !frame->payload) + return -EINVAL; + + if (frame->message_type !=3D OSF_MSG_SENSOR_SAMPLE) + return -EPROTO; + + if (frame->payload_len < OSF_SENSOR_SAMPLE_BASE_LEN) + return -EMSGSIZE; + + payload =3D frame->payload; + channel_count =3D get_unaligned_le16(payload + 4); + sample_format =3D get_unaligned_le16(payload + 6); + + if (sample_format !=3D OSF_SAMPLE_FORMAT_S32) + return -EPROTO; + + expected_len =3D OSF_SENSOR_SAMPLE_BASE_LEN + channel_count * sizeof(s32); + if (frame->payload_len !=3D expected_len) + return -EMSGSIZE; + + sample->sensor_type =3D get_unaligned_le16(payload); + sample->sensor_index =3D get_unaligned_le16(payload + 2); + sample->channel_count =3D channel_count; + sample->sample_format =3D sample_format; + sample->scale_nano =3D get_unaligned_le32(payload + 8); + sample->reserved =3D get_unaligned_le32(payload + 12); + sample->samples =3D payload + OSF_SENSOR_SAMPLE_BASE_LEN; + + return 0; +} + +int osf_protocol_sensor_sample_value(const struct osf_sensor_sample *sampl= e, + unsigned int index, s32 *value) +{ + if (!sample || !sample->samples || !value) + return -EINVAL; + + if (index >=3D sample->channel_count) + return -ERANGE; + + *value =3D (s32)get_unaligned_le32(sample->samples + index * sizeof(s32)); + + return 0; +} + +int osf_protocol_decode_device_status(const struct osf_frame *frame, + struct osf_device_status *status) +{ + const u8 *payload; + + if (!frame || !status || !frame->payload) + return -EINVAL; + + if (frame->message_type !=3D OSF_MSG_DEVICE_STATUS) + return -EPROTO; + + if (frame->payload_len !=3D OSF_DEVICE_STATUS_LEN) + return -EMSGSIZE; + + payload =3D frame->payload; + status->uptime_s =3D get_unaligned_le32(payload); + status->status_flags =3D get_unaligned_le32(payload + 4); + status->error_flags =3D get_unaligned_le32(payload + 8); + status->dropped_frames =3D get_unaligned_le32(payload + 12); + status->reserved =3D get_unaligned_le32(payload + 16); + + return 0; +} + +int osf_protocol_decode_capability_report(const struct osf_frame *frame, + struct osf_capability_report *report) +{ + u16 capability_count; + u32 expected_len; + const u8 *payload; + + if (!frame || !report || !frame->payload) + return -EINVAL; + + if (frame->message_type !=3D OSF_MSG_CAPABILITY_REPORT) + return -EPROTO; + + if (frame->payload_len < OSF_CAP_REPORT_BASE_LEN) + return -EMSGSIZE; + + payload =3D frame->payload; + capability_count =3D get_unaligned_le16(payload); + expected_len =3D OSF_CAP_REPORT_BASE_LEN + + capability_count * OSF_CAP_SENSOR_ENTRY_LEN; + + if (frame->payload_len !=3D expected_len) + return -EMSGSIZE; + + report->capability_count =3D capability_count; + report->reserved =3D get_unaligned_le16(payload + 2); + if (report->reserved) + return -EPROTO; + + report->entries =3D payload + OSF_CAP_REPORT_BASE_LEN; + + return 0; +} + +int osf_protocol_decode_capability_entry(const struct osf_capability_repor= t *report, + unsigned int index, + struct osf_capability_entry *entry) +{ + const u8 *payload; + + if (!report || !report->entries || !entry) + return -EINVAL; + + if (index >=3D report->capability_count) + return -ERANGE; + + payload =3D report->entries + index * OSF_CAP_SENSOR_ENTRY_LEN; + entry->sensor_type =3D get_unaligned_le16(payload); + entry->sensor_index =3D get_unaligned_le16(payload + 2); + entry->channel_count =3D get_unaligned_le16(payload + 4); + entry->sample_format =3D get_unaligned_le16(payload + 6); + entry->scale_nano =3D get_unaligned_le32(payload + 8); + entry->flags =3D get_unaligned_le32(payload + 12); + entry->reserved =3D get_unaligned_le32(payload + 16); + + if (!osf_sensor_type_valid(entry->sensor_type)) + return -EPROTO; + + if (entry->sample_format !=3D OSF_SAMPLE_FORMAT_S32) + return -EPROTO; + + if (entry->flags & ~OSF_CAPABILITY_FLAGS_MASK) + return -EPROTO; + + if (entry->reserved) + return -EPROTO; + + return 0; +} diff --git a/drivers/iio/opensensorfusion/osf_protocol.h b/drivers/iio/open= sensorfusion/osf_protocol.h new file mode 100644 index 000000000..fd6e9581f --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_protocol.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _OSF_PROTOCOL_H +#define _OSF_PROTOCOL_H + +#include + +#define OSF_PROTOCOL_MAJOR 0 +#define OSF_PROTOCOL_MINOR 0 +#define OSF_FRAME_HEADER_LEN 38 +#define OSF_FRAME_CRC_LEN 4 +#define OSF_FRAME_MIN_LEN (OSF_FRAME_HEADER_LEN + OSF_FRAME_CRC_LEN) + +#define OSF_SENSOR_SAMPLE_BASE_LEN 16 +#define OSF_DEVICE_STATUS_LEN 20 +#define OSF_CAP_REPORT_BASE_LEN 4 +#define OSF_CAP_SENSOR_ENTRY_LEN 20 +#define OSF_CAPABILITY_FLAGS_MASK 0x00000003U + +enum osf_message_type { + OSF_MSG_SENSOR_SAMPLE =3D 0x0001, + OSF_MSG_DEVICE_STATUS =3D 0x0002, + OSF_MSG_CAPABILITY_REPORT =3D 0x0003, +}; + +enum osf_sensor_type { + OSF_SENSOR_ACCELEROMETER =3D 0x0001, + OSF_SENSOR_GYROSCOPE =3D 0x0002, + OSF_SENSOR_MAGNETOMETER =3D 0x0003, + OSF_SENSOR_BAROMETER =3D 0x0004, + OSF_SENSOR_TEMPERATURE =3D 0x0005, + OSF_SENSOR_HUMIDITY =3D 0x0006, + OSF_SENSOR_AMBIENT_LIGHT =3D 0x0007, + OSF_SENSOR_PROXIMITY =3D 0x0008, +}; + +enum osf_sample_format { + OSF_SAMPLE_FORMAT_S32 =3D 0x0001, +}; + +struct osf_frame { + u8 protocol_minor; + u16 message_type; + u32 payload_len; + u64 sequence; + u64 timestamp_us; + u32 flags; + u32 reserved; + const u8 *payload; + u32 crc; +}; + +struct osf_sensor_sample { + u16 sensor_type; + u16 sensor_index; + u16 channel_count; + u16 sample_format; + u32 scale_nano; + u32 reserved; + const u8 *samples; +}; + +struct osf_device_status { + u32 uptime_s; + u32 status_flags; + u32 error_flags; + u32 dropped_frames; + u32 reserved; +}; + +struct osf_capability_report { + u16 capability_count; + u16 reserved; + const u8 *entries; +}; + +struct osf_capability_entry { + u16 sensor_type; + u16 sensor_index; + u16 channel_count; + u16 sample_format; + u32 scale_nano; + u32 flags; + u32 reserved; +}; + +int osf_protocol_decode_frame(const u8 *buf, size_t len, + struct osf_frame *frame, size_t *frame_len); +int osf_protocol_decode_sensor_sample(const struct osf_frame *frame, + struct osf_sensor_sample *sample); +int osf_protocol_decode_device_status(const struct osf_frame *frame, + struct osf_device_status *status); +int osf_protocol_decode_capability_report(const struct osf_frame *frame, + struct osf_capability_report *report); +int osf_protocol_decode_capability_entry(const struct osf_capability_repor= t *report, + unsigned int index, + struct osf_capability_entry *entry); +int osf_protocol_sensor_sample_value(const struct osf_sensor_sample *sampl= e, + unsigned int index, s32 *value); + +#endif --=20 2.43.0 From nobody Sun May 24 18:41:54 2026 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 029A538F64E for ; Sun, 24 May 2026 08:53:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612835; cv=none; b=eiXmVVcIVvauTO5U2OHzLCKSzIWxp73WJwiPufeUSQxavYJHqXEXFtiCNLmi7Dmr5jh0h//nXwb1L3UN0gbDYEiQ/FjV4lXdvVpKK5LXEezE2pkuzKOMh6wu2PEKX9y933+4tMugrPQmV8aeF0vtFRgHBw6zQN9vAAesqyh7sEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612835; c=relaxed/simple; bh=JQFcnG2hyCIPDGZsHUJKv/yfIWKH5QAMSCNMowNCIpA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GHMbf158nPbNbA2e/VP5SUYdY6pZ9pOj1VkILwgVJMf2qZATsZ8c33qKOKqEfznE1xDlyYCj4iDVjzN1TKJpO4qvr2u0g+qz3d7TF7nPX1YIKz+zHZEjiEVxlDguk+0B72xikVMvzOPIRVb3jKLmVl2HjafPmbgMWIiQJ5FZX9o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kTd3foSm; arc=none smtp.client-ip=209.85.210.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kTd3foSm" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-836ed29d1e5so3843150b3a.2 for ; Sun, 24 May 2026 01:53:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779612833; x=1780217633; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BLhf9NCIQR8/SjUY7PFqXJOHwil80+JfrtnhSO8qnWs=; b=kTd3foSm0iCzdujau42QPr8qmTHhTf7nPAjh8+QX1zR6heMKVD8BMTswOFkY9yEY7E OPnnpUuCYHG00yVXLElyv5vWk4Sg6cmNPe5ImQqN+256QWSpfYaKkoyNNZkn/6Cn66Zo U95zjM8FAhLonyZyeRBrZZqHbYwJ0pjO9xUSjul9rB+CLjeqa/U2PHh9RbakFJExsC1+ w7GDIjJsf7Mu5CcATRlzJFvKbKZxJoxhYDaHMlBLRaNkU8a/OwsX8tpTVu1InqEMwqgq 83M8ZKYSVdQd9PJOP7jtmTgQEMQyzeRk548wmzoYWDRgI2dGmxC3cuTHLU/AcwEwL8R0 MbJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779612833; x=1780217633; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=BLhf9NCIQR8/SjUY7PFqXJOHwil80+JfrtnhSO8qnWs=; b=h+6zc79WIty5ew0V/zsYm5EizjqZDX5X2Hs3Not4vzu24sVpBU0uzU0tMfmHcaNwre 7hvYZtw1Boxt8aCNPBKtS2odAw9Y64phrWOQmhLxwx27Qf7FzCDlcDcbe6vs0E/Bozs1 Q+/pVTz1Sng7pF2eVZMjJe2Q828mwQ0Oy6+Ybl1yU3w09W90PxTeybuLFtB0QQjvVy7Y BNfDIzJiidrmgd/eJwRB6FOeCjcY8oJmg9xuYwWsWHUBlto7ciLT695HCoXD6BC3/f8u BMyDtlHIHINPf/aIvIhGtMCgzOCM1xprBJzjBjaGf+uZa7GcOCJKuldFbaS6gaTNV6iT QYFA== X-Forwarded-Encrypted: i=1; AFNElJ/iU0Zi7jTrr7N5iI/SNbb15ad/CAg2S1OhR8HXgt09E6nB/HQRYy7WeaPZ6FtRA4vASVG4nKWdrvt2CVg=@vger.kernel.org X-Gm-Message-State: AOJu0YznVApfk/79KcYDa4m5rjXnwxjbeEj/KQjZAY1e2qE7okBgDNrj V3B80yBVXMTXfII5dGMLidOWNoFNSte2P8QrZVC5nhwfJ1m/0KXDLR29 X-Gm-Gg: Acq92OHQWd9Mt7vD//zYnFASIEBVKf3+Md47byaqUsfAtgWFOzUVKvC20TV+BEQ/obz wTmHw+qE1d5Rv171pmYdpoBxCsxpmAsqJQlB0bgOor7vGWUsGfLaOGrZgaK6TxoCZ4seUmKf7jx h37bSF3EDMUaoy0m7KBGE+QlU2LKF85HPVfYbIHGL+Lk1z+1uIjIO0QKJi7mvQ6jmIwCWiZEnEQ zIM0aUlTo4N5CeQcUdEvdWUnh6XKwr6Kcta88r+GKalUcWkcL5MeT6XHM+ElNk7dI336mmx0dFf rQJEPjozHPWgkqFhnWG4TH3LR5cdDvm7DJ41wQc2v5qgJfBFNHT5W+kLe4fIIucn7JpmZYwu4Q9 7YcSPTVY+xuOi8rruTF0b+UkHWusQMY/3hHIH2tXXqPRA7ycFKjaciQIx3B9PEo5LbUXAfaJ3Nf FQ+nYu3M2gH42sHxEgJWnH1+6MTnvGV96RUD7ydHU9foztU/bZvEFFUWAWQLfF94fItAeFhiar5 4eWW0+70iK4CC/FXHMEUklSOeZvkratEcW+5w== X-Received: by 2002:a05:6a00:3923:b0:82c:e60c:f36d with SMTP id d2e1a72fcca58-8415f5983ecmr10120508b3a.48.1779612833389; Sun, 24 May 2026 01:53:53 -0700 (PDT) Received: from DESKTOP-G3E0OSP.localdomain ([112.172.255.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ea4de4sm6353116b3a.35.2026.05.24.01.53.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2026 01:53:53 -0700 (PDT) From: Jinseob Kim To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jinseob Kim Subject: [PATCH RFC v2 4/7] iio: osf: add stream parser Date: Sun, 24 May 2026 17:53:09 +0900 Message-ID: <20260524085312.15369-5-kimjinseob88@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524085312.15369-1-kimjinseob88@gmail.com> References: <20260524085312.15369-1-kimjinseob88@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add byte stream assembly and resync for OSF0 frames. Signed-off-by: Jinseob Kim --- drivers/iio/opensensorfusion/osf_stream.c | 207 ++++++++++++++++++++++ drivers/iio/opensensorfusion/osf_stream.h | 31 ++++ 2 files changed, 238 insertions(+) create mode 100644 drivers/iio/opensensorfusion/osf_stream.c create mode 100644 drivers/iio/opensensorfusion/osf_stream.h diff --git a/drivers/iio/opensensorfusion/osf_stream.c b/drivers/iio/opense= nsorfusion/osf_stream.c new file mode 100644 index 000000000..a2739c987 --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_stream.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include + +#include "osf_core.h" +#include "osf_protocol.h" +#include "osf_stream.h" + +#define OSF_STREAM_MAGIC_LEN 4 +#define OSF_STREAM_MAX_PAYLOAD_LEN \ + (OSF_STREAM_MAX_FRAME_LEN - OSF_FRAME_HEADER_LEN - OSF_FRAME_CRC_LEN) + +static const u8 osf_stream_magic[OSF_STREAM_MAGIC_LEN] =3D { + 'O', 'S', 'F', '0', +}; + +static void osf_stream_discard(struct osf_stream *stream, size_t count) +{ + if (count >=3D stream->len) { + stream->len =3D 0; + return; + } + + memmove(stream->buf, stream->buf + count, stream->len - count); + stream->len -=3D count; +} + +static void osf_stream_drop_invalid_head(struct osf_stream *stream) +{ + osf_stream_discard(stream, 1); +} + +static bool osf_stream_magic_match(const u8 *buf, size_t len) +{ + return !memcmp(buf, osf_stream_magic, len); +} + +static size_t osf_stream_discard_to_magic(struct osf_stream *stream) +{ + size_t old_len =3D stream->len; + size_t match_len; + size_t i; + + for (i =3D 0; i < stream->len; i++) { + match_len =3D stream->len - i; + if (match_len > OSF_STREAM_MAGIC_LEN) + match_len =3D OSF_STREAM_MAGIC_LEN; + + if (osf_stream_magic_match(stream->buf + i, match_len)) { + if (i) + osf_stream_discard(stream, i); + return i; + } + } + + stream->len =3D 0; + return old_len; +} + +static int osf_stream_process(struct osf_stream *stream) +{ + struct osf_frame frame; + size_t decoded_len; + size_t discarded; + size_t frame_len; + u32 payload_len; + int first_err =3D 0; + int ret; + + while (stream->len) { + discarded =3D osf_stream_discard_to_magic(stream); + if (discarded) { + stream->stats.bad_magic_resyncs++; + stream->stats.dropped_bytes +=3D discarded; + if (!first_err) + first_err =3D -EPROTO; + } + + if (!stream->len) + break; + + if (stream->len < OSF_FRAME_HEADER_LEN) { + stream->stats.partial_frames++; + break; + } + + if (get_unaligned_le16(stream->buf + 6) !=3D + OSF_FRAME_HEADER_LEN) { + stream->stats.dropped_bytes++; + osf_stream_drop_invalid_head(stream); + if (!first_err) + first_err =3D -EPROTO; + continue; + } + + payload_len =3D get_unaligned_le32(stream->buf + 10); + if (payload_len > OSF_STREAM_MAX_PAYLOAD_LEN) { + stream->stats.dropped_bytes++; + osf_stream_drop_invalid_head(stream); + if (!first_err) + first_err =3D -EMSGSIZE; + continue; + } + + frame_len =3D OSF_FRAME_HEADER_LEN + payload_len + OSF_FRAME_CRC_LEN; + if (stream->len < frame_len) { + stream->stats.partial_frames++; + break; + } + + ret =3D osf_protocol_decode_frame(stream->buf, frame_len, &frame, + &decoded_len); + if (ret) { + if (ret =3D=3D -EBADMSG) + stream->stats.bad_crc_frames++; + stream->stats.dropped_bytes++; + osf_stream_drop_invalid_head(stream); + if (!first_err) + first_err =3D ret; + continue; + } + + if (decoded_len !=3D frame_len) { + stream->stats.dropped_bytes++; + osf_stream_drop_invalid_head(stream); + if (!first_err) + first_err =3D -EMSGSIZE; + continue; + } + + ret =3D osf_core_receive_frame(stream->osf, stream->buf, frame_len); + if (ret) { + osf_stream_discard(stream, frame_len); + if (!first_err) + first_err =3D ret; + continue; + } + + stream->stats.valid_frames++; + osf_stream_discard(stream, frame_len); + } + + return first_err; +} + +void osf_stream_init(struct osf_stream *stream, struct osf_device *osf) +{ + if (!stream) + return; + + stream->osf =3D osf; + stream->len =3D 0; + memset(&stream->stats, 0, sizeof(stream->stats)); +} + +void osf_stream_reset(struct osf_stream *stream) +{ + if (stream) { + stream->len =3D 0; + memset(&stream->stats, 0, sizeof(stream->stats)); + } +} + +int osf_stream_receive_bytes(struct osf_stream *stream, const u8 *buf, + size_t len) +{ + size_t copy_len; + size_t space; + int first_err =3D 0; + int ret; + + if (!stream || !stream->osf || (!buf && len)) + return -EINVAL; + + if (!len) { + ret =3D osf_stream_process(stream); + if (ret && !first_err) + first_err =3D ret; + return first_err; + } + + while (len) { + space =3D OSF_STREAM_MAX_FRAME_LEN - stream->len; + if (!space) { + stream->stats.dropped_bytes++; + osf_stream_discard(stream, 1); + if (!first_err) + first_err =3D -EMSGSIZE; + continue; + } + + copy_len =3D len < space ? len : space; + memcpy(stream->buf + stream->len, buf, copy_len); + stream->len +=3D copy_len; + buf +=3D copy_len; + len -=3D copy_len; + + ret =3D osf_stream_process(stream); + if (ret && !first_err) + first_err =3D ret; + } + + return first_err; +} diff --git a/drivers/iio/opensensorfusion/osf_stream.h b/drivers/iio/opense= nsorfusion/osf_stream.h new file mode 100644 index 000000000..f7f9477fe --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_stream.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _OSF_STREAM_H +#define _OSF_STREAM_H + +#include + +#define OSF_STREAM_MAX_FRAME_LEN 4096 + +struct osf_device; + +struct osf_stream_stats { + u64 valid_frames; + u64 bad_magic_resyncs; + u64 bad_crc_frames; + u64 partial_frames; + u64 dropped_bytes; +}; + +struct osf_stream { + struct osf_device *osf; + u8 buf[OSF_STREAM_MAX_FRAME_LEN]; + size_t len; + struct osf_stream_stats stats; +}; + +void osf_stream_init(struct osf_stream *stream, struct osf_device *osf); +void osf_stream_reset(struct osf_stream *stream); +int osf_stream_receive_bytes(struct osf_stream *stream, const u8 *buf, + size_t len); + +#endif --=20 2.43.0 From nobody Sun May 24 18:41:54 2026 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0F3038E5F9 for ; Sun, 24 May 2026 08:53:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612839; cv=none; b=T/m1qk1xyCwzs8TLQndcdysFUivTQL07v4DgfmICvFXVK+Wq23iWUC25WeSDVpnvIItXloC70gXDEV9ZXof/WRTL8B13VBNgBzfrIDv6ioZLMO4XfO9GofgbON1fyg3u+guwZk6+rSOUsSameUcszJCoUSyoSKN5/gTG9SbIRUg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612839; c=relaxed/simple; bh=3gOpPRRNnJMdMSXvFzoMff2zE9qGPtKmEvX+FwSqOJ8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cRLhSbhZuM3dQ+G24GjRUgqCxG4dPmHPD9avEcDjEJlaIcFmZNtk39QDHKWEjX38+7n4EBHiqISLMRW5NcPqCp84eCePA9dRwySlFg4/WqjBF1aDqvHuMumBss7y5d57CI8jW13h1TryeAyq389t2RfwhZlbGwnMj+4lI3G3bKI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=dzyS7sRh; arc=none smtp.client-ip=209.85.210.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dzyS7sRh" Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-8419ab3a297so17644b3a.2 for ; Sun, 24 May 2026 01:53:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779612837; x=1780217637; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ODoHNkdYEScxRBQ09YOSCqOJ+T3sjTnVlEMajTXRzCY=; b=dzyS7sRhz0bliFW18Ze+R7Dwbk8Z9PFFGiYLMFDm5AyPgyHie8IOZX2TrMja+mE8Pl 4oil5bLtixrYOFjtKQZrrKrLTzjijG/M1/AzYJou8FBAHuou5/plgnN5sZwLLFQLNGhn bjvlHnyu/ruRoADamuQRzPVdefW+1dMcyBQZUjIyq3Wwyo6/eLR4ddnv5adjrhMzUyjB uL0uXC+AwDqt//j+MuIsffbESQiwfzhqS43CRuV6TXjtOWMCiGG303jZbvK+FRFK8qVa RGrsFNHxZlFbIstrye9f2FGERKrkSWi6WUNb9fkNGmjO0tP0ZWBCaUmHI/IsegPdXloH h6gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779612837; x=1780217637; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ODoHNkdYEScxRBQ09YOSCqOJ+T3sjTnVlEMajTXRzCY=; b=EPaDAjqh9FtBCf8lRftAUGOqNrRmkqQ+HnOLIVwL1amj14a/tqh9Hciq2OGiCpwxbd wbN0xd2dfxb0jHTJYtAWglGvA/IGwYFAj38QrPvdtrBjeaj/rn92vGH2/xcaiDx46hs3 IvHylsSSf8R2BD053tqHY7NLrtO8Fm9Mj8njqZ6UrukrLwheElgw2dVTWFW1r/PnBKmA swXY9i8GWFElWsh3qHVc8wMN7T1/GIB51SIQ7gWN244NXVNZRR1KA5RJ6spenpFDaYse bvA/mnAPuuXa+Pu5y8T0KosXlNslKl4bnppbgDdyE0qBim9ufAhRkWIEu2sgLx2xD9la K/cg== X-Forwarded-Encrypted: i=1; AFNElJ92bj/eJzP64HgBlZIf+Mgq9TrMDfsnD0YueNg1I6BT4eOLahD3/WMkdi5vxugs6IUGzHJ4n/LruVyCwRs=@vger.kernel.org X-Gm-Message-State: AOJu0Ywkk4x1hUag3Gchr11TieiiZUOs7hFDMY8V8ZuybvD2t5Nvg+cR 0diEzKmsVmdFkxAryOk8tuo0DcsIoumVD6Z3uBZkj8nNAZFs+DeSmNdP X-Gm-Gg: Acq92OGsHKigCtpMe8JXMGzf5MaO0Y0AOsBQ82bK+6+4UAXzrIKc8hTiSBb669UIAhd O+wLBVpoWvd3gHWiNRPBIO5x1I0PkRNDa5OF4h5BOly5TdPk1nMc3hBLG16kbctUWwq7c5jbgr+ nYE2ObHXWQlRXnvBN3UWaqhqwWmDYbaaJr9G3aRgm5YXgacrCdJvu7D487smofoIg+0OXKlqML3 FjiRW1Bk2YUa0AZ7hb72VSucDY3PUCnD9GDQdw4XmbIffWC2C4Xj7fBH1hTu25QFEp5eMWCH1fI q7tUDxP0H55ujrcBUPQG92nD9TOuxL+GHnL/gar+RgFeIHGDrPlu0obNDgzYj2s3qgjj9ZafGeD t9hF1XNENy85ebFMT0wO8Y84BdiMBv6H5AnFCBYdGj3eddr1zn8t84O7WLv8Go4jIg6tqwK3WSF S4Gqdqogk+/vP+j8hR1mfoiUE/RNnxdabcoqUX3sDbHlQIu1MTNUCdKi/3nHYOxKaTf0DNxY5QL YSply91te+dd/xx15V1+2o7Z3Geu9Z2Tp9UjjvsYNP67r48 X-Received: by 2002:a05:6a00:849:b0:83e:f228:b112 with SMTP id d2e1a72fcca58-8415f3799aemr9623045b3a.34.1779612836985; Sun, 24 May 2026 01:53:56 -0700 (PDT) Received: from DESKTOP-G3E0OSP.localdomain ([112.172.255.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ea4de4sm6353116b3a.35.2026.05.24.01.53.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2026 01:53:56 -0700 (PDT) From: Jinseob Kim To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jinseob Kim Subject: [PATCH RFC v2 5/7] iio: osf: add UART serdev transport Date: Sun, 24 May 2026 17:53:10 +0900 Message-ID: <20260524085312.15369-6-kimjinseob88@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524085312.15369-1-kimjinseob88@gmail.com> References: <20260524085312.15369-1-kimjinseob88@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the serdev receive path that feeds decoded OSF0 frames to the core. Signed-off-by: Jinseob Kim --- drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/opensensorfusion/Kconfig | 15 +++ drivers/iio/opensensorfusion/Makefile | 5 + drivers/iio/opensensorfusion/osf_core.c | 107 +++++++++++++++++++++ drivers/iio/opensensorfusion/osf_core.h | 18 ++++ drivers/iio/opensensorfusion/osf_serdev.c | 111 ++++++++++++++++++++++ 7 files changed, 258 insertions(+) create mode 100644 drivers/iio/opensensorfusion/Kconfig create mode 100644 drivers/iio/opensensorfusion/Makefile create mode 100644 drivers/iio/opensensorfusion/osf_core.c create mode 100644 drivers/iio/opensensorfusion/osf_core.h create mode 100644 drivers/iio/opensensorfusion/osf_serdev.c diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 661127aed..939f6c546 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -101,6 +101,7 @@ source "drivers/iio/light/Kconfig" source "drivers/iio/magnetometer/Kconfig" source "drivers/iio/multiplexer/Kconfig" source "drivers/iio/orientation/Kconfig" +source "drivers/iio/opensensorfusion/Kconfig" source "drivers/iio/test/Kconfig" if IIO_TRIGGER source "drivers/iio/trigger/Kconfig" diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index cb80ef837..d864fe17b 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -37,6 +37,7 @@ obj-y +=3D light/ obj-y +=3D magnetometer/ obj-y +=3D multiplexer/ obj-y +=3D orientation/ +obj-y +=3D opensensorfusion/ obj-y +=3D position/ obj-y +=3D potentiometer/ obj-y +=3D potentiostat/ diff --git a/drivers/iio/opensensorfusion/Kconfig b/drivers/iio/opensensorf= usion/Kconfig new file mode 100644 index 000000000..360f25b4f --- /dev/null +++ b/drivers/iio/opensensorfusion/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config OPEN_SENSOR_FUSION + tristate "Open Sensor Fusion UART IIO driver" + depends on IIO + depends on SERIAL_DEV_BUS + select CRC32 + help + Build the Open Sensor Fusion UART receive path. + + The driver receives OSF0 frames over a serdev UART. + Frames are decoded and validated before being passed to the + driver core. + This patch only adds the transport path. + IIO device registration is added separately. diff --git a/drivers/iio/opensensorfusion/Makefile b/drivers/iio/opensensor= fusion/Makefile new file mode 100644 index 000000000..940c82edd --- /dev/null +++ b/drivers/iio/opensensorfusion/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_OPEN_SENSOR_FUSION) +=3D open-sensor-fusion.o + +open-sensor-fusion-y :=3D osf_core.o osf_protocol.o osf_serdev.o osf_strea= m.o diff --git a/drivers/iio/opensensorfusion/osf_core.c b/drivers/iio/opensens= orfusion/osf_core.c new file mode 100644 index 000000000..c867b3158 --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_core.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include + +#include "osf_core.h" +#include "osf_protocol.h" + +#define OSF_RESERVED_MSG_FIRST 0x7f00 +#define OSF_RESERVED_MSG_LAST 0x7fff +#define OSF_VENDOR_PRIVATE_FIRST 0x8000 + +void osf_core_init(struct osf_device *osf, struct device *dev) +{ + memset(osf, 0, sizeof(*osf)); + osf->dev =3D dev; +} + +void osf_core_unregister_iio(struct osf_device *osf) +{ +} + +static int osf_core_validate_sensor_sample(const struct osf_frame *frame) +{ + struct osf_sensor_sample sample; + + return osf_protocol_decode_sensor_sample(frame, &sample); +} + +static int osf_core_validate_device_status(const struct osf_frame *frame) +{ + struct osf_device_status status; + int ret; + + ret =3D osf_protocol_decode_device_status(frame, &status); + if (ret) + return ret; + + if (status.reserved) + return -EPROTO; + + return 0; +} + +static int osf_core_validate_capability_report(const struct osf_frame *fra= me) +{ + struct osf_capability_entry entry; + struct osf_capability_report report; + unsigned int i; + int ret; + + ret =3D osf_protocol_decode_capability_report(frame, &report); + if (ret) + return ret; + + for (i =3D 0; i < report.capability_count; i++) { + ret =3D osf_protocol_decode_capability_entry(&report, i, &entry); + if (ret) + return ret; + } + + return 0; +} + +int osf_core_receive_frame(struct osf_device *osf, const u8 *buf, size_t l= en) +{ + struct osf_frame frame; + size_t frame_len; + int ret; + + if (!osf || !buf) + return -EINVAL; + + ret =3D osf_protocol_decode_frame(buf, len, &frame, &frame_len); + if (ret) + return ret; + + if (frame_len !=3D len) + return -EMSGSIZE; + + switch (frame.message_type) { + case OSF_MSG_SENSOR_SAMPLE: + ret =3D osf_core_validate_sensor_sample(&frame); + break; + case OSF_MSG_DEVICE_STATUS: + ret =3D osf_core_validate_device_status(&frame); + break; + case OSF_MSG_CAPABILITY_REPORT: + ret =3D osf_core_validate_capability_report(&frame); + break; + default: + if (frame.message_type >=3D OSF_RESERVED_MSG_FIRST && + frame.message_type <=3D OSF_RESERVED_MSG_LAST) + ret =3D 0; + else if (frame.message_type >=3D OSF_VENDOR_PRIVATE_FIRST) + ret =3D 0; + else + ret =3D -EOPNOTSUPP; + break; + } + + if (!ret) + osf->last_sequence =3D frame.sequence; + + return ret; +} diff --git a/drivers/iio/opensensorfusion/osf_core.h b/drivers/iio/opensens= orfusion/osf_core.h new file mode 100644 index 000000000..3680c8c9b --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_core.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _OSF_CORE_H +#define _OSF_CORE_H + +#include + +struct device; + +struct osf_device { + struct device *dev; + u64 last_sequence; +}; + +void osf_core_init(struct osf_device *osf, struct device *dev); +void osf_core_unregister_iio(struct osf_device *osf); +int osf_core_receive_frame(struct osf_device *osf, const u8 *buf, size_t l= en); + +#endif diff --git a/drivers/iio/opensensorfusion/osf_serdev.c b/drivers/iio/opense= nsorfusion/osf_serdev.c new file mode 100644 index 000000000..f121089ed --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_serdev.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "osf_core.h" +#include "osf_stream.h" + +#define OSF_SERDEV_BAUD 115200 + +struct osf_serdev { + struct serdev_device *serdev; + struct osf_device osf; + struct osf_stream stream; +}; + +static size_t osf_serdev_receive_buf(struct serdev_device *serdev, + const u8 *buf, size_t count) +{ + struct osf_serdev *osf_uart =3D serdev_device_get_drvdata(serdev); + const struct osf_stream_stats *stats; + u64 valid_before; + int ret; + + valid_before =3D osf_uart->stream.stats.valid_frames; + ret =3D osf_stream_receive_bytes(&osf_uart->stream, buf, count); + stats =3D &osf_uart->stream.stats; + + if (ret || stats->valid_frames !=3D valid_before) + dev_dbg_ratelimited(&serdev->dev, + "rx count=3D%zu valid=3D%llu bad_magic=3D%llu bad_crc=3D%llu parti= al=3D%llu dropped=3D%llu ret=3D%d\n", + count, + (unsigned long long)stats->valid_frames, + (unsigned long long)stats->bad_magic_resyncs, + (unsigned long long)stats->bad_crc_frames, + (unsigned long long)stats->partial_frames, + (unsigned long long)stats->dropped_bytes, + ret); + + return count; +} + +static const struct serdev_device_ops osf_serdev_ops =3D { + .receive_buf =3D osf_serdev_receive_buf, +}; + +static int osf_serdev_probe(struct serdev_device *serdev) +{ + struct osf_serdev *osf_uart; + unsigned int baudrate; + int ret; + + osf_uart =3D devm_kzalloc(&serdev->dev, sizeof(*osf_uart), GFP_KERNEL); + if (!osf_uart) + return -ENOMEM; + + osf_uart->serdev =3D serdev; + osf_core_init(&osf_uart->osf, &serdev->dev); + osf_stream_init(&osf_uart->stream, &osf_uart->osf); + + serdev_device_set_drvdata(serdev, osf_uart); + serdev_device_set_client_ops(serdev, &osf_serdev_ops); + + ret =3D serdev_device_open(serdev); + if (ret) + return ret; + + baudrate =3D serdev_device_set_baudrate(serdev, OSF_SERDEV_BAUD); + if (baudrate !=3D OSF_SERDEV_BAUD) + dev_warn(&serdev->dev, "requested %u baud, controller set %u\n", + OSF_SERDEV_BAUD, baudrate); + + serdev_device_set_flow_control(serdev, false); + + return 0; +} + +static void osf_serdev_remove(struct serdev_device *serdev) +{ + struct osf_serdev *osf_uart =3D serdev_device_get_drvdata(serdev); + + serdev_device_close(serdev); + osf_stream_reset(&osf_uart->stream); + osf_core_unregister_iio(&osf_uart->osf); +} + +static const struct of_device_id osf_serdev_of_match[] =3D { + { .compatible =3D "opensensorfusion,osf-uart" }, + { } +}; +MODULE_DEVICE_TABLE(of, osf_serdev_of_match); + +static struct serdev_device_driver osf_serdev_driver =3D { + .probe =3D osf_serdev_probe, + .remove =3D osf_serdev_remove, + .driver =3D { + .name =3D "open-sensor-fusion-uart", + .of_match_table =3D osf_serdev_of_match, + }, +}; + +module_serdev_device_driver(osf_serdev_driver); + +MODULE_DESCRIPTION("Open Sensor Fusion IIO driver"); +MODULE_LICENSE("GPL"); --=20 2.43.0 From nobody Sun May 24 18:41:54 2026 Received: from mail-pf1-f170.google.com (mail-pf1-f170.google.com [209.85.210.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2C1C327280A for ; Sun, 24 May 2026 08:54:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612843; cv=none; b=dBfBy1u36A2sDfeEE5dKrimE4PLCJTnKg7y/cwPR04jYAzw5TdvViih4gITqFBr+Rnb73wnFZHUDfF1gIJ8bKEasokd7XtUZdNGsiz63vPktM4F8EF2vHcDPbssM9yozCJpdU1Wlq7cJBSjan4Ij9v97gJb5fSAg7SG4n18V+24= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612843; c=relaxed/simple; bh=IEHUrDv0ReEeSVylZI18nGNjgbVPFZC+krA8xm9qutQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Th8pB5cRd4buVuxxZhaJbWrkGg9Rj3t0L7780SQs5jStH94WaeECRuWnTKb7/2t5SKIUdXdp5ucQkt97oBnk5CxhITQ0Q/xfdB9SLwLQWIBW+Z9Oetvf1Yd3Dk0qXqoUDD9JJzXfd4jUHEjTx2MkYhrsyEBZq2GyOsH6ryJB2OY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MNG4jnxA; arc=none smtp.client-ip=209.85.210.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MNG4jnxA" Received: by mail-pf1-f170.google.com with SMTP id d2e1a72fcca58-8353fd1cb5fso4262387b3a.0 for ; Sun, 24 May 2026 01:54:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779612841; x=1780217641; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9QOFXjIr+HZLbM31AZYf0y3yl8UOVuhCFlXgFZsmlTY=; b=MNG4jnxABYHwQIlM/64ON4B+FtPYALhnCiLKuDGINQXrNX/xr/gG6Kd4VeajKHvCjX Xi2GFGQ4mx6gehPRj3YniyeCnJGlt5+lUGplqUV+hDLrlIuAFVeo9pOZhtaKlYz2GrAX b/1nO+DxPU8cI/emdlCwnb4XW2/CZZoe6mmDkc1K3ilLOqdGKZzVOFWeYQGYiALXBjVN TFagl7WmRhzLY0EjgRqlkfYaOWgi2fwl72EieGi/ezseUE/Hyu63BnLNNmb16V4OW/g3 YQoiMyqJl5oQPzItQ7qrVNcgnutmu9EcDY4UA//ki40g3xal7I3usES7Ybbarotsslh9 3RtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779612841; x=1780217641; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=9QOFXjIr+HZLbM31AZYf0y3yl8UOVuhCFlXgFZsmlTY=; b=ERw/GuK5KDkDzgJ839U8aFtbtBwPo/5SZXRjEXgXJvwVMXehDDlLzW+rsMEBsFnO/e UwRLxpfGg+QikM41selxhPRXI3pbi431pRJ1MT9oCh08avP/PQGYezqRRIzoZB7C9606 RMud1TMmJ0FosyZUa761hIaJl8HgQBZlJ07S5+Xx1x9jtt1TZhaYQ3pQKSg7EKDYpAR8 gGou84iDSaVLSeVotSmwY+hDRfFAZaERKCGF3AVLQiCpA6kaL67HCDh54czxiIf1lviJ fIjdVsq6ykWv3zYsmJ5OznZUQBtG1ftCpQy8AIOGiyL6EYqhRIEJuGidP4dqaIKlYZ+/ RAtg== X-Forwarded-Encrypted: i=1; AFNElJ9azv/UO/l30jV3a6NBQrVpZyHhC+X6F/MyX5V2HDSkPGgpOfS3HPHmJQvWCi+tFIGAg706Jjjv90p1vb0=@vger.kernel.org X-Gm-Message-State: AOJu0YzF5J6avecd25HrI9WTGFurR2wQpjT0x9WqSnFKHSyVamMe4ysR sz7xPIjZch58yQIeQzmAquwIZ6gqvEj6POleKwDGt87gFT6WRMg9bcH2 X-Gm-Gg: Acq92OFA8LTIQJHgqbGl+XcW6Br6S7aZMjsJK74fXNlYeHT7wmwnTect3xpZWk3Hv21 FEa41REtMITuiBb7k5Bnr7TtHzVufP4XOB/VzsHjhziT/090xPco90dT3QKwl15GMVklYfGoClw dhpRwSmtZxGzf4159pY/hXivtePHxo9NLiSujQWiQIztulRjoAmvTi6+IpUHpbUiQe6SpkLX2oy tusVa0Icb/NkiRJt+/p0m8EfpjeJ63NY6soFkez+qTH9wJ+NTLZfNxqJQepwDjtUFlitVR8OUVO pES76FWAqzLkHbLvd3/S8fXKphWhrvPEuPALaoJBi60v3sGqtcYBpCeYzNUz2hapl1GU97WFn4m I11/mnEkHBc5ORvPS3frwOmGxyckRDHmh1fS1Pu0TIAqEdWoWU/RlqQUCueFBZh++Fe4WshVbz8 0aY8YfsUsKR/J0iqCaS0ucr+j6BV43waEM5SGThkzjHT9dfBjAvtvC5B4/puHFXHrQtwcT+jzc7 RTr/+79BwW78sWd9C+Wl7Jaw0fUO700rxPAo6NWerRwcj/G X-Received: by 2002:a05:6a00:4503:b0:837:c1f8:6e55 with SMTP id d2e1a72fcca58-8416112c734mr7551290b3a.14.1779612840592; Sun, 24 May 2026 01:54:00 -0700 (PDT) Received: from DESKTOP-G3E0OSP.localdomain ([112.172.255.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ea4de4sm6353116b3a.35.2026.05.24.01.53.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2026 01:54:00 -0700 (PDT) From: Jinseob Kim To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jinseob Kim Subject: [PATCH RFC v2 6/7] iio: osf: register IIO devices from capabilities Date: Sun, 24 May 2026 17:53:11 +0900 Message-ID: <20260524085312.15369-7-kimjinseob88@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524085312.15369-1-kimjinseob88@gmail.com> References: <20260524085312.15369-1-kimjinseob88@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Register supported IIO devices from the first valid capability report. Signed-off-by: Jinseob Kim --- drivers/iio/opensensorfusion/Kconfig | 12 +- drivers/iio/opensensorfusion/Makefile | 3 +- drivers/iio/opensensorfusion/osf_core.c | 248 ++++++++++++++++++-- drivers/iio/opensensorfusion/osf_core.h | 49 ++++ drivers/iio/opensensorfusion/osf_iio.c | 288 ++++++++++++++++++++++++ drivers/iio/opensensorfusion/osf_iio.h | 22 ++ 6 files changed, 593 insertions(+), 29 deletions(-) create mode 100644 drivers/iio/opensensorfusion/osf_iio.c create mode 100644 drivers/iio/opensensorfusion/osf_iio.h diff --git a/drivers/iio/opensensorfusion/Kconfig b/drivers/iio/opensensorf= usion/Kconfig index 360f25b4f..004d2aa8a 100644 --- a/drivers/iio/opensensorfusion/Kconfig +++ b/drivers/iio/opensensorfusion/Kconfig @@ -5,11 +5,11 @@ config OPEN_SENSOR_FUSION depends on IIO depends on SERIAL_DEV_BUS select CRC32 + select IIO_KFIFO_BUF help - Build the Open Sensor Fusion UART receive path. + Build the Open Sensor Fusion UART IIO driver. =20 - The driver receives OSF0 frames over a serdev UART. - Frames are decoded and validated before being passed to the - driver core. - This patch only adds the transport path. - IIO device registration is added separately. + The driver receives OSF0 frames over a serdev UART and registers + IIO devices for supported capability entries. + Raw reads use the latest decoded samples. Buffered reads use + fixed scan layouts and IIO timestamps. diff --git a/drivers/iio/opensensorfusion/Makefile b/drivers/iio/opensensor= fusion/Makefile index 940c82edd..b4e03b80c 100644 --- a/drivers/iio/opensensorfusion/Makefile +++ b/drivers/iio/opensensorfusion/Makefile @@ -2,4 +2,5 @@ =20 obj-$(CONFIG_OPEN_SENSOR_FUSION) +=3D open-sensor-fusion.o =20 -open-sensor-fusion-y :=3D osf_core.o osf_protocol.o osf_serdev.o osf_strea= m.o +open-sensor-fusion-y :=3D osf_core.o osf_iio.o osf_protocol.o osf_serdev.o= \ + osf_stream.o diff --git a/drivers/iio/opensensorfusion/osf_core.c b/drivers/iio/opensens= orfusion/osf_core.c index c867b3158..a1e20ede9 100644 --- a/drivers/iio/opensensorfusion/osf_core.c +++ b/drivers/iio/opensensorfusion/osf_core.c @@ -5,7 +5,7 @@ #include =20 #include "osf_core.h" -#include "osf_protocol.h" +#include "osf_iio.h" =20 #define OSF_RESERVED_MSG_FIRST 0x7f00 #define OSF_RESERVED_MSG_LAST 0x7fff @@ -19,17 +19,171 @@ void osf_core_init(struct osf_device *osf, struct devi= ce *dev) =20 void osf_core_unregister_iio(struct osf_device *osf) { + unsigned int i; + + for (i =3D 0; i < osf->iio_dev_count; i++) + osf_iio_unregister_sensor(osf->iio_devs[i].indio_dev); + + osf->iio_dev_count =3D 0; +} + +static struct iio_dev *osf_core_find_iio_dev(struct osf_device *osf, + u16 sensor_type, u16 sensor_index) +{ + const struct osf_iio_binding *binding; + unsigned int i; + + for (i =3D 0; i < osf->iio_dev_count; i++) { + binding =3D &osf->iio_devs[i]; + if (binding->sensor_type =3D=3D sensor_type && + binding->sensor_index =3D=3D sensor_index) + return binding->indio_dev; + } + + return NULL; +} + +static struct osf_latest_sample * +osf_core_find_latest_sample(struct osf_device *osf, u16 sensor_type, + u16 sensor_index) +{ + struct osf_latest_sample *latest; + unsigned int i; + + for (i =3D 0; i < osf->latest_sample_count; i++) { + latest =3D &osf->latest_samples[i]; + if (latest->sensor_type =3D=3D sensor_type && + latest->sensor_index =3D=3D sensor_index) + return latest; + } + + if (osf->latest_sample_count >=3D OSF_MAX_CAPABILITIES) + return NULL; + + return &osf->latest_samples[osf->latest_sample_count++]; +} + +static bool osf_core_capability_duplicate(const struct osf_capability_cach= e *cache, + unsigned int index) +{ + const struct osf_capability_entry *entry =3D &cache->entries[index]; + unsigned int i; + + for (i =3D 0; i < index; i++) { + if (!osf_iio_sensor_supported(cache->entries[i].sensor_type, + cache->entries[i].channel_count)) + continue; + + if (cache->entries[i].sensor_type =3D=3D entry->sensor_type && + cache->entries[i].sensor_index =3D=3D entry->sensor_index) + return true; + } + + return false; +} + +static int osf_core_register_capabilities(struct osf_device *osf, + const struct osf_capability_cache *cache) +{ + struct iio_dev *indio_dev; + unsigned int i; + int ret; + + if (osf->capability_cache.valid) + return 0; + + for (i =3D 0; i < cache->capability_count; i++) { + if (!osf_iio_sensor_supported(cache->entries[i].sensor_type, + cache->entries[i].channel_count)) + continue; + + if (osf_core_capability_duplicate(cache, i)) + return -EEXIST; + } + + for (i =3D 0; i < cache->capability_count; i++) { + if (!osf_iio_sensor_supported(cache->entries[i].sensor_type, + cache->entries[i].channel_count)) + continue; + + ret =3D osf_iio_register_sensor(osf->dev, &cache->entries[i], + osf, &indio_dev); + if (ret) + goto err_unregister; + + osf->iio_devs[osf->iio_dev_count].sensor_type =3D + cache->entries[i].sensor_type; + osf->iio_devs[osf->iio_dev_count].sensor_index =3D + cache->entries[i].sensor_index; + osf->iio_devs[osf->iio_dev_count].indio_dev =3D indio_dev; + osf->iio_dev_count++; + } + + return 0; + +err_unregister: + osf_core_unregister_iio(osf); + + return ret; } =20 -static int osf_core_validate_sensor_sample(const struct osf_frame *frame) +static int osf_core_handle_sensor_sample(struct osf_device *osf, + const struct osf_frame *frame) { + struct osf_latest_sample *latest; struct osf_sensor_sample sample; + struct iio_dev *indio_dev; + unsigned int i; + int ret; =20 - return osf_protocol_decode_sensor_sample(frame, &sample); + ret =3D osf_protocol_decode_sensor_sample(frame, &sample); + if (ret) + return ret; + + if (sample.channel_count > OSF_MAX_SAMPLE_CHANNELS) + return -E2BIG; + + latest =3D osf_core_find_latest_sample(osf, sample.sensor_type, + sample.sensor_index); + if (!latest) + return -E2BIG; + + for (i =3D 0; i < sample.channel_count; i++) { + ret =3D osf_protocol_sensor_sample_value(&sample, i, + &latest->values[i]); + if (ret) + return ret; + } + + for (; i < OSF_MAX_SAMPLE_CHANNELS; i++) + latest->values[i] =3D 0; + + latest->sensor_type =3D sample.sensor_type; + latest->sensor_index =3D sample.sensor_index; + latest->channel_count =3D sample.channel_count; + latest->sample_format =3D sample.sample_format; + latest->scale_nano =3D sample.scale_nano; + latest->sequence =3D frame->sequence; + latest->timestamp_us =3D frame->timestamp_us; + latest->valid =3D true; + osf->last_sequence =3D frame->sequence; + + indio_dev =3D osf_core_find_iio_dev(osf, sample.sensor_type, + sample.sensor_index); + if (indio_dev) { + ret =3D osf_iio_push_sample(indio_dev, latest->values, + latest->channel_count); + if (ret) + return ret; + } + + return 0; } =20 -static int osf_core_validate_device_status(const struct osf_frame *frame) +static int osf_core_handle_device_status(struct osf_device *osf, + const struct osf_frame *frame) { + struct osf_status_cache cache =3D { }; struct osf_device_status status; int ret; =20 @@ -40,12 +194,22 @@ static int osf_core_validate_device_status(const struc= t osf_frame *frame) if (status.reserved) return -EPROTO; =20 + cache.uptime_s =3D status.uptime_s; + cache.status_flags =3D status.status_flags; + cache.error_flags =3D status.error_flags; + cache.dropped_frames =3D status.dropped_frames; + cache.sequence =3D frame->sequence; + cache.valid =3D true; + osf->status_cache =3D cache; + osf->last_sequence =3D frame->sequence; + return 0; } =20 -static int osf_core_validate_capability_report(const struct osf_frame *fra= me) +static int osf_core_handle_capability_report(struct osf_device *osf, + const struct osf_frame *frame) { - struct osf_capability_entry entry; + struct osf_capability_cache cache =3D { }; struct osf_capability_report report; unsigned int i; int ret; @@ -54,12 +218,32 @@ static int osf_core_validate_capability_report(const s= truct osf_frame *frame) if (ret) return ret; =20 + if (report.capability_count > OSF_MAX_CAPABILITIES) + return -E2BIG; + + if (osf->capability_cache.valid) { + osf->last_sequence =3D frame->sequence; + return 0; + } + for (i =3D 0; i < report.capability_count; i++) { - ret =3D osf_protocol_decode_capability_entry(&report, i, &entry); + ret =3D osf_protocol_decode_capability_entry(&report, i, + &cache.entries[i]); if (ret) return ret; } =20 + cache.capability_count =3D report.capability_count; + cache.sequence =3D frame->sequence; + cache.valid =3D true; + + ret =3D osf_core_register_capabilities(osf, &cache); + if (ret) + return ret; + + osf->capability_cache =3D cache; + osf->last_sequence =3D frame->sequence; + return 0; } =20 @@ -81,27 +265,47 @@ int osf_core_receive_frame(struct osf_device *osf, con= st u8 *buf, size_t len) =20 switch (frame.message_type) { case OSF_MSG_SENSOR_SAMPLE: - ret =3D osf_core_validate_sensor_sample(&frame); - break; + return osf_core_handle_sensor_sample(osf, &frame); case OSF_MSG_DEVICE_STATUS: - ret =3D osf_core_validate_device_status(&frame); - break; + return osf_core_handle_device_status(osf, &frame); case OSF_MSG_CAPABILITY_REPORT: - ret =3D osf_core_validate_capability_report(&frame); - break; + return osf_core_handle_capability_report(osf, &frame); default: if (frame.message_type >=3D OSF_RESERVED_MSG_FIRST && frame.message_type <=3D OSF_RESERVED_MSG_LAST) - ret =3D 0; - else if (frame.message_type >=3D OSF_VENDOR_PRIVATE_FIRST) - ret =3D 0; - else - ret =3D -EOPNOTSUPP; - break; + return 0; + if (frame.message_type >=3D OSF_VENDOR_PRIVATE_FIRST) + return 0; + return -EOPNOTSUPP; } +} =20 - if (!ret) - osf->last_sequence =3D frame.sequence; +int osf_core_read_latest_sample(struct osf_device *osf, u16 sensor_type, + u16 sensor_index, unsigned int channel, + s32 *value) +{ + const struct osf_latest_sample *latest; + unsigned int i; =20 - return ret; + if (!osf || !value) + return -EINVAL; + + for (i =3D 0; i < osf->latest_sample_count; i++) { + latest =3D &osf->latest_samples[i]; + if (latest->sensor_type =3D=3D sensor_type && + latest->sensor_index =3D=3D sensor_index) + goto found; + } + + return -ENODATA; + +found: + if (!latest->valid) + return -ENODATA; + if (channel >=3D latest->channel_count) + return -ENODATA; + + *value =3D latest->values[channel]; + + return 0; } diff --git a/drivers/iio/opensensorfusion/osf_core.h b/drivers/iio/opensens= orfusion/osf_core.h index 3680c8c9b..e5c0d5081 100644 --- a/drivers/iio/opensensorfusion/osf_core.h +++ b/drivers/iio/opensensorfusion/osf_core.h @@ -4,15 +4,64 @@ =20 #include =20 +#include "osf_protocol.h" + +#define OSF_MAX_SAMPLE_CHANNELS 3 +#define OSF_MAX_CAPABILITIES 16 + struct device; +struct iio_dev; + +struct osf_latest_sample { + u16 sensor_type; + u16 sensor_index; + u16 channel_count; + u16 sample_format; + u32 scale_nano; + s32 values[OSF_MAX_SAMPLE_CHANNELS]; + u64 sequence; + u64 timestamp_us; + bool valid; +}; + +struct osf_capability_cache { + u16 capability_count; + struct osf_capability_entry entries[OSF_MAX_CAPABILITIES]; + u64 sequence; + bool valid; +}; + +struct osf_status_cache { + u32 uptime_s; + u32 status_flags; + u32 error_flags; + u32 dropped_frames; + u64 sequence; + bool valid; +}; + +struct osf_iio_binding { + u16 sensor_type; + u16 sensor_index; + struct iio_dev *indio_dev; +}; =20 struct osf_device { struct device *dev; + struct osf_latest_sample latest_samples[OSF_MAX_CAPABILITIES]; + unsigned int latest_sample_count; + struct osf_capability_cache capability_cache; + struct osf_status_cache status_cache; + struct osf_iio_binding iio_devs[OSF_MAX_CAPABILITIES]; + unsigned int iio_dev_count; u64 last_sequence; }; =20 void osf_core_init(struct osf_device *osf, struct device *dev); void osf_core_unregister_iio(struct osf_device *osf); int osf_core_receive_frame(struct osf_device *osf, const u8 *buf, size_t l= en); +int osf_core_read_latest_sample(struct osf_device *osf, u16 sensor_type, + u16 sensor_index, unsigned int channel, + s32 *value); =20 #endif diff --git a/drivers/iio/opensensorfusion/osf_iio.c b/drivers/iio/opensenso= rfusion/osf_iio.c new file mode 100644 index 000000000..1f82ec063 --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_iio.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "osf_core.h" +#include "osf_iio.h" + +struct osf_iio_sensor_spec { + u16 sensor_type; + u16 channel_count; + const char *name; + const struct iio_chan_spec *channels; + unsigned int num_channels; + const unsigned long *available_scan_masks; +}; + +struct osf_iio_state { + const struct osf_iio_sensor_spec *spec; + struct iio_buffer *buffer; + u32 scale_nano; + u16 sensor_index; + struct osf_device *osf; +}; + +#define OSF_SCAN_TYPE_S32 \ + { \ + .sign =3D 's', \ + .realbits =3D 32, \ + .storagebits =3D 32, \ + .endianness =3D IIO_CPU, \ + } + +#define OSF_MOD_CHAN(_type, _mod, _idx) \ + { \ + .type =3D (_type), \ + .modified =3D 1, \ + .channel2 =3D (_mod), \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index =3D (_idx), \ + .scan_type =3D OSF_SCAN_TYPE_S32, \ + } + +#define OSF_CHAN(_type, _idx) \ + { \ + .type =3D (_type), \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index =3D (_idx), \ + .scan_type =3D OSF_SCAN_TYPE_S32, \ + } + +static const struct iio_chan_spec osf_accel_channels[] =3D { + OSF_MOD_CHAN(IIO_ACCEL, IIO_MOD_X, 0), + OSF_MOD_CHAN(IIO_ACCEL, IIO_MOD_Y, 1), + OSF_MOD_CHAN(IIO_ACCEL, IIO_MOD_Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static const struct iio_chan_spec osf_gyro_channels[] =3D { + OSF_MOD_CHAN(IIO_ANGL_VEL, IIO_MOD_X, 0), + OSF_MOD_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, 1), + OSF_MOD_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static const struct iio_chan_spec osf_mag_channels[] =3D { + OSF_MOD_CHAN(IIO_MAGN, IIO_MOD_X, 0), + OSF_MOD_CHAN(IIO_MAGN, IIO_MOD_Y, 1), + OSF_MOD_CHAN(IIO_MAGN, IIO_MOD_Z, 2), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static const struct iio_chan_spec osf_temp_channels[] =3D { + OSF_CHAN(IIO_TEMP, 0), + IIO_CHAN_SOFT_TIMESTAMP(1), +}; + +static const unsigned long osf_3axis_available_scan_masks[] =3D { + GENMASK(2, 0), + 0, +}; + +static const unsigned long osf_temp_available_scan_masks[] =3D { + BIT(0), + 0, +}; + +static const struct osf_iio_sensor_spec osf_iio_sensor_specs[] =3D { + { + .sensor_type =3D OSF_SENSOR_ACCELEROMETER, + .channel_count =3D 3, + .name =3D "osf-accel", + .channels =3D osf_accel_channels, + .num_channels =3D ARRAY_SIZE(osf_accel_channels), + .available_scan_masks =3D osf_3axis_available_scan_masks, + }, + { + .sensor_type =3D OSF_SENSOR_GYROSCOPE, + .channel_count =3D 3, + .name =3D "osf-gyro", + .channels =3D osf_gyro_channels, + .num_channels =3D ARRAY_SIZE(osf_gyro_channels), + .available_scan_masks =3D osf_3axis_available_scan_masks, + }, + { + .sensor_type =3D OSF_SENSOR_MAGNETOMETER, + .channel_count =3D 3, + .name =3D "osf-magn", + .channels =3D osf_mag_channels, + .num_channels =3D ARRAY_SIZE(osf_mag_channels), + .available_scan_masks =3D osf_3axis_available_scan_masks, + }, + { + .sensor_type =3D OSF_SENSOR_TEMPERATURE, + .channel_count =3D 1, + .name =3D "osf-temp", + .channels =3D osf_temp_channels, + .num_channels =3D ARRAY_SIZE(osf_temp_channels), + .available_scan_masks =3D osf_temp_available_scan_masks, + }, +}; + +static const struct osf_iio_sensor_spec * +osf_iio_find_sensor_spec(u16 sensor_type, u16 channel_count) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(osf_iio_sensor_specs); i++) { + if (osf_iio_sensor_specs[i].sensor_type =3D=3D sensor_type && + osf_iio_sensor_specs[i].channel_count =3D=3D channel_count) + return &osf_iio_sensor_specs[i]; + } + + return NULL; +} + +bool osf_iio_sensor_supported(u16 sensor_type, u16 channel_count) +{ + return !!osf_iio_find_sensor_spec(sensor_type, channel_count); +} + +const char *osf_iio_sensor_name(u16 sensor_type) +{ + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(osf_iio_sensor_specs); i++) { + if (osf_iio_sensor_specs[i].sensor_type =3D=3D sensor_type) + return osf_iio_sensor_specs[i].name; + } + + return NULL; +} + +static int osf_iio_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val, + int *val2, long mask) +{ + struct osf_iio_state *state =3D iio_priv(indio_dev); + s32 raw; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (!state->osf) + return -ENODATA; + + if (chan->scan_index < 0) + return -EINVAL; + + ret =3D osf_core_read_latest_sample(state->osf, + state->spec->sensor_type, + state->sensor_index, + chan->scan_index, &raw); + if (ret) + return ret; + + *val =3D raw; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val =3D state->scale_nano / NANO; + *val2 =3D state->scale_nano % NANO; + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static const struct iio_info osf_iio_info =3D { + .read_raw =3D osf_iio_read_raw, +}; + +int osf_iio_register_sensor(struct device *dev, + const struct osf_capability_entry *entry, + struct osf_device *osf, struct iio_dev **indio_dev) +{ + const struct osf_iio_sensor_spec *spec; + struct osf_iio_state *state; + struct iio_dev *iio_dev; + int ret; + + spec =3D osf_iio_find_sensor_spec(entry->sensor_type, + entry->channel_count); + if (!spec) + return -EOPNOTSUPP; + + if (entry->sample_format !=3D OSF_SAMPLE_FORMAT_S32) + return -EOPNOTSUPP; + + iio_dev =3D iio_device_alloc(dev, sizeof(*state)); + if (!iio_dev) + return -ENOMEM; + + state =3D iio_priv(iio_dev); + state->spec =3D spec; + state->scale_nano =3D entry->scale_nano; + state->sensor_index =3D entry->sensor_index; + state->osf =3D osf; + + iio_dev->name =3D spec->name; + iio_dev->info =3D &osf_iio_info; + iio_dev->modes =3D INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; + iio_dev->channels =3D spec->channels; + iio_dev->num_channels =3D spec->num_channels; + iio_dev->available_scan_masks =3D spec->available_scan_masks; + + state->buffer =3D iio_kfifo_allocate(); + if (!state->buffer) { + ret =3D -ENOMEM; + goto err_free_iio; + } + + ret =3D iio_device_attach_buffer(iio_dev, state->buffer); + if (ret) + goto err_free_buffer; + + ret =3D iio_device_register(iio_dev); + if (ret) + goto err_free_buffer; + + if (indio_dev) + *indio_dev =3D iio_dev; + + return 0; + +err_free_buffer: + iio_kfifo_free(state->buffer); +err_free_iio: + iio_device_free(iio_dev); + + return ret; +} + +void osf_iio_unregister_sensor(struct iio_dev *indio_dev) +{ + struct osf_iio_state *state; + + if (!indio_dev) + return; + + state =3D iio_priv(indio_dev); + iio_device_unregister(indio_dev); + iio_kfifo_free(state->buffer); + iio_device_free(indio_dev); +} + +int osf_iio_push_sample(struct iio_dev *indio_dev, const s32 *values, + unsigned int channel_count) +{ + s64 timestamp; + + if (!iio_buffer_enabled(indio_dev)) + return 0; + + timestamp =3D iio_get_time_ns(indio_dev); + + return iio_push_to_buffers_with_ts_unaligned(indio_dev, values, + channel_count * sizeof(*values), + timestamp); +} diff --git a/drivers/iio/opensensorfusion/osf_iio.h b/drivers/iio/opensenso= rfusion/osf_iio.h new file mode 100644 index 000000000..d90c58fc4 --- /dev/null +++ b/drivers/iio/opensensorfusion/osf_iio.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _OSF_IIO_H +#define _OSF_IIO_H + +#include + +#include "osf_protocol.h" + +struct device; +struct iio_dev; +struct osf_device; + +int osf_iio_register_sensor(struct device *dev, + const struct osf_capability_entry *entry, + struct osf_device *osf, struct iio_dev **indio_dev); +void osf_iio_unregister_sensor(struct iio_dev *indio_dev); +int osf_iio_push_sample(struct iio_dev *indio_dev, const s32 *values, + unsigned int channel_count); +bool osf_iio_sensor_supported(u16 sensor_type, u16 channel_count); +const char *osf_iio_sensor_name(u16 sensor_type); + +#endif --=20 2.43.0 From nobody Sun May 24 18:41:54 2026 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6CD0C3905E0 for ; Sun, 24 May 2026 08:54:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612845; cv=none; b=OessgUlvlZIohOeMdXlXNC+DF9XMhxZ+j0gWDLfvNo+A5xm8DASNbL9WcVeIU4sMB+PkNF+xITtFwq5jK6aVEx7Ad1UfHzxmxulI4/nBRcimhU+N0jkMXIT2cuhgEehWD9TsMmhjx2F7jMWrH+ALI1i25AcKXF+pGTglKooAbwE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779612845; c=relaxed/simple; bh=KoZohLAP7FkG0DiqRHfnK9gUGT1fB3petwusbNr1K2A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WCXhisxPvr7gQTT8H+R+a+yE05o6pyMnO18uWAO+D85cVsus3tTMxaQauA+gOK40mFM1vEy1dwTjwsblx8spUc9ODgxr3i+uRw2QE3EUzhpR+h69/iwGSH3d17JDeUAxJEQ0Emg+HSRR98xBFfRz1ZLzP2EpK8GkooMPXqiJpeI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=cVypAtYq; arc=none smtp.client-ip=209.85.210.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cVypAtYq" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-83537a80ab6so5996181b3a.1 for ; Sun, 24 May 2026 01:54:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779612844; x=1780217644; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LU/cOHKYJiwHIi210zVuGwmaJ7REyB2Sgsxuvm9SfTg=; b=cVypAtYq0H3iaxgMjzULJipOh4J4C4aXmwdu/PiyIyQmy8YS5xAAS/DT8/cxh2bBu6 qrexfovdHBXPynz2/3RsSvwC9ZwNp1XvC4INqbmMhXPLieyl0kKIJ+KDOgGycTKagDby V4tMF//E+2h+I2LrEMdr1zlxLTxeAFTU0Ad9ALCLQgvZKDyEf9gMCzzpwposYHQi4l3y GE2LXKakOgbH6WqK8w8nEUBzGd39L60jmXCLsSk9pBBaxWrcdX4nauSzuV6clgqXXEaJ gb1pdH7Q+zriQQ9DhEouz+zUYEfpqjwB4hsJDaSAQ/b+PSe+Zmlq+G5Ds0Yem9bJ9+uH mI3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779612844; x=1780217644; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=LU/cOHKYJiwHIi210zVuGwmaJ7REyB2Sgsxuvm9SfTg=; b=BnG2XokD7rytdp5MvfUC5EZzvDJH79i9rTQ0/dtlOsqUXKV+i1JE9mASyOesgBmDQy VwEkpXVqkMczAP/s18vGi06oM7CjOonCIutbkbqWunsRtJ423eam4fppSEwRRR8SKtq+ TvuWeAJnYbb93fYgH1L6nXL4d3AmYKw4S3UjUOL6dk+S95p31m2XxUmbtpQrxEOwBRdw PoTmKOYTwoaOB8Aq2og2mHAlZK5cmfoBJq0eyP7zPai40yedNehHsjR6AupuqRtBa+vI rw9RW3nVWgyTVKSkhGSowdFngELvvmXD6Zz1exBe9xTfGvsx6JF7pZfSe0XrJVaF069/ xw8w== X-Forwarded-Encrypted: i=1; AFNElJ8kLkM10RUDFd95b1DttGArRWXSewGXhmg7SA8zJGJ/x0T+7/J8HlUa6EACPLSOrqBMn5S/hoIBXzd8EGA=@vger.kernel.org X-Gm-Message-State: AOJu0YzL9Xx4h4TR0Htp3vITesDEYHAC3UZduJ5fayeF6VRpWs11KSxg YTbl7z42J8xddahfbS/Cr6+s+CkdsMLqSpES3ZwYqg+wjjY4RyPxvTdu X-Gm-Gg: Acq92OHAiR5V6A1pJWin7OW+oY4R93XjG1O23E0ciENtpnJjabzAqESgqsqJx2ZlGiO 36F5lNKz0HS41ry8zMlSMx3dx4rC8wc7VA9lonkpaQO1T+QEn6Q+2ex7j/sWkGpn+vgUXk9U9iK R/gWT6PPK0XQKVj8ssb/caOKkKbGfyXDnUQSh15wwpG6icW+b65eqnH99Hwd/aTgkMw2b/n4oba 7+F0kE8nr43kYZ25e0cFOFOvlHZHynxrgpNqLZrmxGimwocEvH2WLeAXrxWJCgd8V5nAnWu35ax vowWC3l3SvK1HaLaquQWEVWjlejUYy9y76JZvkdosoUJkomKMWQvJieQ+JI5he/ByS1uwGzeU7Z HV5MH4pFUCnmc8G8ebRyy6SWcDnciU1r4BZvJEw+XeNr4oND/3lLnHpg+kyV1dlBIi6FnmcDknE Ay1vUAa90IfXCPh5KRGSCTXpAyH2A5M/lnqDplo8XAg0+5VQOusJoKLAakh2GTa15VVIOoumzLO 9HbmgAJVN6EwBkXxKa3xsRjByz4IDZbdSjcyQ== X-Received: by 2002:a05:6a00:3d11:b0:839:dd77:3501 with SMTP id d2e1a72fcca58-8415f11f2d9mr10041656b3a.1.1779612843893; Sun, 24 May 2026 01:54:03 -0700 (PDT) Received: from DESKTOP-G3E0OSP.localdomain ([112.172.255.242]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84164ea4de4sm6353116b3a.35.2026.05.24.01.54.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2026 01:54:03 -0700 (PDT) From: Jinseob Kim To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jinseob Kim Subject: [PATCH RFC v2 7/7] MAINTAINERS: add Open Sensor Fusion IIO driver Date: Sun, 24 May 2026 17:53:12 +0900 Message-ID: <20260524085312.15369-8-kimjinseob88@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260524085312.15369-1-kimjinseob88@gmail.com> References: <20260524085312.15369-1-kimjinseob88@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add file patterns for the driver, binding, and protocol reference. Signed-off-by: Jinseob Kim --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c2c6d7927..9238701f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19977,6 +19977,15 @@ F: Documentation/networking/oa-tc6-framework.rst F: drivers/net/ethernet/oa_tc6.c F: include/linux/oa_tc6.h =20 +OPEN SENSOR FUSION IIO DRIVER +M: Jinseob Kim +L: linux-iio@vger.kernel.org +L: devicetree@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/imu/opensensorfusion,osf-uart.yaml +F: Documentation/iio/open-sensor-fusion-protocol-v0.rst +F: drivers/iio/opensensorfusion/ + OPEN FIRMWARE AND FLATTENED DEVICE TREE M: Rob Herring M: Saravana Kannan --=20 2.43.0