From nobody Sun Feb 8 05:58:00 2026 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C34D61C3BF7; Sun, 8 Jun 2025 18:46:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749408368; cv=none; b=FbcOFgsRFfZyTcmH5pqxGFOlIY9VvHt4vpQBccK6Oe5AVveWGbGgobbFfLkWCyPBZcvE7KaF/9y+9KqiKbhvcpfTh20h74+hOieQ/UcvZdDwFYmk68EmpRN6gHbWP1iQOyx5EiCbR29Q4RBl2vHcvgtsYzQevB2np58FtSqcYR0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749408368; c=relaxed/simple; bh=BoMe2w87VCMZS8u+ptoRh/u+YAr8a/+5Nxt1dp8aSa4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VJec9q1kbyBtCclbSezCBSydQV0IR9oEf1rUjI+ebBPF0jEnjksmHN6xnpHKwtQEZdRpvfudpaVR7F0W45OsUiR9TfeBhVkZAo5czUVBVJ0OwShuDY2gxMIIlveOz1ezQPkY4ZiMaCRxarcpey7X4FStBzAaC6vU6kSE8fzRrh4= 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=NIyFPOa0; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NIyFPOa0" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-450ce671a08so23028515e9.3; Sun, 08 Jun 2025 11:46:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749408365; x=1750013165; 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=o4KSSPvtxQcn1jUN07zB5p3F9NXBdBxtVhggAw+LtFk=; b=NIyFPOa0CyGSkD0HFb7A6Fv/46rbkgXMzUCKCnTv/4JL5ps+1zo3LF4auL9/oC7sl1 gP8OPkZ88IalEqCgRuB82BvEK7Ld+dMFoUkyfUlJeZdtwaeFbGYJuyBARL4rWLHmNUlL 2eYPVgASMmklXZk8Drq7C+VgeHp2/PUBJu+5/tYDcmpMHE9qL52JgeQxwX9g+E6InPop ITCy706s3Baxzz0KpTVdAfyFJOfpf5yVECIU9ZKTblz9heq4UXN1JhBu/3QRO+Vcm97R PklQWlLXiy5mMUJCCLXMU0bBXE4oRm3fFrhxweYaPsGMvvV3peJVJg1QZEj/V3IVFwbV 7Bsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749408365; x=1750013165; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=o4KSSPvtxQcn1jUN07zB5p3F9NXBdBxtVhggAw+LtFk=; b=E2A9H+OQv8FbT9I5qWO1aeO/ZW5fpUe7UxyVPvLS3v2mEaGH+ix2Pkqm1lnZ+5/qCw rJ1UoL5lM20l3cH2wt5oy3XnfaOZQ9vj8ko8AO1LxmvbMqPARK91ra0RQqpgLRbepe6z clzBZasBjY5abnbJT93CYasY968isoan4hrprVKRCYV4xVAfeSRzhi3xuB0Uq7BmHVdR j+f5ldNTBWNYTgm8Oa3Xjnln71JxewZ88CNJcKMPcD6TFgqUlJw7XPwjYQJnQpTcmyEr rWakdLICvnK3d1/an7h1+2hs2I+BRrZFcJdrIbAwexFEP48Cit8fKY45yGJ/MA0ZO7Jd vM4A== X-Forwarded-Encrypted: i=1; AJvYcCWdrZZWIaRrRih6XOUUW3taLsTWvvJy9xmUyWWR0uMaA+GPgAtqhSYUD2XR+ag+kWC4fbDR/4Kek4Ee@vger.kernel.org X-Gm-Message-State: AOJu0YwZXvKFNjEXdbpA7xni2qasLUhdR5xdv/Sq9sRSsRQKDKlT2vvl Sz6i6rrnj6Di0wH2E4amISdBBgIxZh8NF5p0CdbVU3kYSH309/wPKmRPEUZGTvg1 X-Gm-Gg: ASbGncumKYEbPZaJ0ZJjfpFpQZMisryf+W0xPJ+05r9fuNUgBMy+aKnemSyC8X/PBDn houQN9pbLFBsLO7dWRWkvA/JNNu5xg1rHkUTOJuFV87Xe8npnnopZn8MuOk7xv/gfiUtHUBbdS3 ZPR37X4IxiD0sg9weeql6+8Lqx8tuGwTX+R6ODIS31xvu+KDDeK7sT1t2a6SjAnUZPSexEwM8lh n37+8P85ns+YBSP/H9B2VTmUMZs33FqVdqTnEncttQ8DEn1RYyfMGjuhiv3RYPoOdlKA4s07Kpt gIBBK4uZLakaXr8aH6yjthPwFS9jJe3mkbXsIeL00furVWVu1Zk2kH+wIs+kZ7VRpmz6H3pLmGy dvrLurNVNHUVr3A== X-Google-Smtp-Source: AGHT+IHHMvL44I7O3GJl+TF1UTZ0SxxrEBTZ69AbDVYKwnW8VDF2pFsNyumQpewbrGFMOdRzwiq5Wg== X-Received: by 2002:a05:6000:220f:b0:3a3:7387:3078 with SMTP id ffacd0b85a97d-3a53168400dmr8336659f8f.4.1749408364752; Sun, 08 Jun 2025 11:46:04 -0700 (PDT) Received: from masalkhi.. (ip-109-43-113-112.web.vodafone.de. [109.43.113.112]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a5324361ffsm7621418f8f.47.2025.06.08.11.46.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Jun 2025 11:46:03 -0700 (PDT) From: Abd-Alrhman Masalkhi To: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: arnd@arndb.de, gregkh@linuxfoundation.org, W_Armin@gmx.de, luoyifan@cmss.chinamobile.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, abd.masalkhi@gmail.com Subject: [PATCH v4 1/3] dt-bindings: eeprom: Add ST M24LR support Date: Sun, 8 Jun 2025 18:27:12 +0000 Message-ID: <20250608182714.3359441-2-abd.masalkhi@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250608182714.3359441-1-abd.masalkhi@gmail.com> References: <20250608182714.3359441-1-abd.masalkhi@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for STMicroelectronics M24LR RFID/NFC EEPROM chips. These devices use two I2C addresses: the primary address provides access to control and system parameter registers, while the secondary address is used for EEPROM access. Signed-off-by: Abd-Alrhman Masalkhi Reviewed-by: Krzysztof Kozlowski --- Changes in v4: - Moved the binding file to the eeprom/ directory - Updated reg property to use items: with per-address descriptions instead of minItems/maxItems --- .../devicetree/bindings/eeprom/st,m24lr.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/eeprom/st,m24lr.yaml diff --git a/Documentation/devicetree/bindings/eeprom/st,m24lr.yaml b/Docum= entation/devicetree/bindings/eeprom/st,m24lr.yaml new file mode 100644 index 000000000000..0a0820e9d11f --- /dev/null +++ b/Documentation/devicetree/bindings/eeprom/st,m24lr.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/eeprom/st,m24lr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: STMicroelectronics M24LR NFC/RFID EEPROM + +maintainers: + - Abd-Alrhman Masalkhi + +description: + STMicroelectronics M24LR series are dual-interface (RF + I2C) + EEPROM chips. These devices support I2C-based access to both + memory and a system area that controls authentication and configuration. + They expose two I2C addresses, one for the system parameter sector and + one for the EEPROM. + +allOf: + - $ref: /schemas/nvmem/nvmem.yaml# + +properties: + compatible: + enum: + - st,m24lr04e-r + - st,m24lr16e-r + - st,m24lr64e-r + + reg: + items: + - description: I2C address used for control/system registers + - description: I2C address used for EEPROM memory access + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + eeprom@57 { + compatible =3D "st,m24lr04e-r"; + reg =3D <0x57>, /* primary-device */ + <0x53>; /* secondary-device */ + }; + }; +... --=20 2.43.0 From nobody Sun Feb 8 05:58:00 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6EB71373; Sun, 8 Jun 2025 18:46:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749408371; cv=none; b=kpVsU6gyaPpm6kqUihezsWdyvc1/tES0eTNQ3RDug2kOZM2/noVS2qoT/fAPtwPV5logxeiZNXZEpd+KoEWvCEb4fNMER2mEA1hV17B5U7EXqY973/yV6/sIIHPzKLJUGlPxAPWQqWQQ4Q7yAubbVM18xVlRDK/5+5iRMTIJ6w0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749408371; c=relaxed/simple; bh=xo9Wfue/6XWXPe+KdTCPs5f4Kj3PUG7P0WrC8VwS00Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j3h3SpDDE/gWdKpSiulFNIjE4eW2TVffHBNrtvj3HJxYFq+dve3kOYk2NNag8sU/7Omw+rkX91RZDd7pRwNDER80DqHO3jw+8mQbVqFdcNYFnw9Uu37BoyxkdkiWcNHaT4Qt5Swm0fLTYgkXC8QpPIlaHHHtbef3RjHCrZ1Zk+U= 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=b0zx1iai; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="b0zx1iai" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-451d6ade159so30769665e9.1; Sun, 08 Jun 2025 11:46:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749408367; x=1750013167; 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=rO+oIPyDswkdAmSqWbZdSXC8rT6S5JbI2gHwpoZ4JtY=; b=b0zx1iaieoI+WUlicnWzCXyoQZKfNpGwQTB0u50opSD9NlwvVI7SB8Pk4I/NhBkt8G CUs5bJnjYUEPZhjfEWF4xvLhIlOUltCt0XPTFnkuoS6ABE47xBxIJRTTL8f8+r3ytmd7 l1Xk0vCIH4nKUGli20Mq3XENgvqRjLPhX8MgSupzSsbmOnkHgZYt82WCPjmlE8t+2Zx7 AHLgLT9EaeiCIU5j4e16wc/yNzV6tpqL2oXF4cJnicpvWl6lQSYhcvfRNtYwvlaBYgrq hEFYN2pyhA38NrerKtUQbR+g4kgMxK1zQ2sWw6t7iqqCPAkAnjD1pWwPw2pbVaVSpoiT AuIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749408367; x=1750013167; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rO+oIPyDswkdAmSqWbZdSXC8rT6S5JbI2gHwpoZ4JtY=; b=VKAXDjZjJCyuz0GDbVikRsvFgFuvMiI/r8Zno0G6MZJR3sWD2wjc1p9sKtD7rpu/Si fuJFwd5JhH2DsybmKZwwr6Mnw770w5oZMASwMuDoMD8e8Rua4WwNUi/w1cDyXlG9fRGi AWfslk192RBkh35z2juh1beWAIdxXYEeiN9fnITMdoRQpJTx7+76w8VIPsZZH4YJ0lHb Hqu6tknMJRLxEeW3dAVTMNsowSwy24cgyT+AE/82IAs6noxrSJhTi0s8HIjUCffa7iyb e1TB2IpimEf2Q5o21cX0pe9g9D2krDt+NPHVxIBLea3jLY9m/VXTRZW1ngDL5TUS2WTS 5Rxw== X-Forwarded-Encrypted: i=1; AJvYcCUP69tLNEe1MSXcOCctmXNgVN5qWVSDlIYkWmhuHZwB68JAuzLdR1P59VmoBnfz8Xt+4JHLpDgPKrLu@vger.kernel.org X-Gm-Message-State: AOJu0YxugdtswjlWhjzoXjCsnlgr0xB5dp5c5Xzgl9kL9Tv0Q+ExEPwl qZhp/sobkVfOy8JVbGE/WhMnRWzkzV1fIJcj/9JMoResXNiXp8myoM3HBXfAElST X-Gm-Gg: ASbGncutFaT98K0JC9juKx7ZCXAlUECDb8bxYuIxx+WsujbKrDd56phVxSdIDoqfeT6 69c39iZ42Pid6dxinLVMAEdQiXD4ri1e+x+vdiUt0R0QFt59nHzYCXM8M4ZBANqQ93OYoquYODP naZ4Lo/p6sl3yoA9a9AByQ2kY9MK/79rAjRQWIVy9/NmerrZJMqJuVXkCVae3hGHataD+ntIM28 nXgWBAb66+Lr/lE6yNzamGHVbSoboixl3ZJgNstJrTkcud4VErd2vyCMmybkxeQ75Czgqh2yKEG R9w+701/k3HSBOulNh1pDZgDP3RHxjzSvi2CbfOZPJclZUuRkYEF7eUSWia0kyLw3mfB9rvGAKY 5nr5XaJ9XM9/JWvrmAvzJOIDr X-Google-Smtp-Source: AGHT+IFT0GbucqKFkiThM8BoyNN5kHOAglwm9HYmepZvl0+fOQMkUc3Aaj04YjC4OiXEkEK0fF7eMQ== X-Received: by 2002:a05:6000:2084:b0:3a4:ca73:75e3 with SMTP id ffacd0b85a97d-3a53168438bmr9156579f8f.12.1749408366777; Sun, 08 Jun 2025 11:46:06 -0700 (PDT) Received: from masalkhi.. (ip-109-43-113-112.web.vodafone.de. [109.43.113.112]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a5324361ffsm7621418f8f.47.2025.06.08.11.46.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Jun 2025 11:46:06 -0700 (PDT) From: Abd-Alrhman Masalkhi To: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: arnd@arndb.de, gregkh@linuxfoundation.org, W_Armin@gmx.de, luoyifan@cmss.chinamobile.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, abd.masalkhi@gmail.com Subject: [PATCH v4 2/3] eeprom: add driver for ST M24LR series RFID/NFC EEPROM chips Date: Sun, 8 Jun 2025 18:27:13 +0000 Message-ID: <20250608182714.3359441-3-abd.masalkhi@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250608182714.3359441-1-abd.masalkhi@gmail.com> References: <20250608182714.3359441-1-abd.masalkhi@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" adds support for STMicroelectronics M24LRxx devices, which expose two separate I2C addresses: one for system control and one for EEPROM access. The driver implements both a sysfs-based interface for control registers (e.g. UID, password authentication) and an nvmem provider for EEPROM access. Signed-off-by: Abd-Alrhman Masalkhi --- Changes in v4: - Moved the source file to the eeprom/ directory - Removed use of unlikely() macro - Removed use of EIO as a fallback error - Stopped dynamically creating sysfs attributes - Replaced per-sector SSS attributes with a single bin_attribute for all SSS - Introduced total_sectors sysfs attribute to report the number of valid sectors - Avoided sharing a single show/store callback across multiple attribute types --- drivers/misc/eeprom/Kconfig | 18 + drivers/misc/eeprom/Makefile | 1 + drivers/misc/eeprom/m24lr.c | 653 +++++++++++++++++++++++++++++++++++ 3 files changed, 672 insertions(+) create mode 100644 drivers/misc/eeprom/m24lr.c diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index cb1c4b8e7fd3..cb0ce243babd 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -119,4 +119,22 @@ config EEPROM_EE1004 This driver can also be built as a module. If so, the module will be called ee1004. =20 +config EEPROM_M24LR + tristate "STMicroelectronics M24LR RFID/NFC EEPROM support" + depends on I2C && SYSFS + select REGMAP_I2C + select NVMEM + select NVMEM_SYSFS + help + This enables support for STMicroelectronics M24LR RFID/NFC EEPROM + chips. These dual-interface devices expose two I2C addresses: + one for EEPROM memory access and another for control and system + configuration (e.g. UID, password handling). + + This driver provides a sysfs interface for control functions and + integrates with the nvmem subsystem for EEPROM access. + + To compile this driver as a module, choose M here: the + module will be called m24lr. + endmenu diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile index 65794e526d5d..8f311fd6a4ce 100644 --- a/drivers/misc/eeprom/Makefile +++ b/drivers/misc/eeprom/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_EEPROM_93XX46) +=3D eeprom_93xx46.o obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) +=3D digsy_mtc_eeprom.o obj-$(CONFIG_EEPROM_IDT_89HPESX) +=3D idt_89hpesx.o obj-$(CONFIG_EEPROM_EE1004) +=3D ee1004.o +obj-$(CONFIG_EEPROM_M24LR) +=3D m24lr.o diff --git a/drivers/misc/eeprom/m24lr.c b/drivers/misc/eeprom/m24lr.c new file mode 100644 index 000000000000..33c6e8a6cb33 --- /dev/null +++ b/drivers/misc/eeprom/m24lr.c @@ -0,0 +1,653 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * m24lr.c - Sysfs control interface for ST M24LR series RFID/NFC chips + * + * Copyright (c) 2025 Abd-Alrhman Masalkhi + * + * This driver implements both the sysfs-based control interface and EEPROM + * access for STMicroelectronics M24LR series chips (e.g., M24LR04E-R). + * It provides access to control registers for features such as password + * authentication, memory protection, and device configuration. In additio= n, + * it manages read and write operations to the EEPROM region of the chip. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define M24LR_WRITE_TIMEOUT 25u +#define M24LR_READ_TIMEOUT (M24LR_WRITE_TIMEOUT) + +/** + * struct m24lr_chip - describes chip-specific sysfs layout + * @page_size: chip-specific limit on the maximum number of bytes allow= ed + * in a single write operation. + * @eeprom_size: size of the EEPROM in byte + * @sss_len: the length of the sss region + * + * Supports multiple M24LR chip variants (e.g., M24LRxx) by allowing each + * to define its own set of sysfs attributes, depending on its available + * registers and features. + */ +struct m24lr_chip { + unsigned int page_size; + unsigned int eeprom_size; + unsigned int sss_len; +}; + +/** + * struct m24lr - core driver data for M24LR chip control + * @uid: 64 bits unique identifier stored in the device + * @sss_len: the length of the sss region + * @page_size: chip-specific limit on the maximum number of bytes allow= ed + * in a single write operation. + * @eeprom_size: size of the EEPROM in byte + * @ctl_regmap: regmap interface for accessing the system parameter sec= tor + * @eeprom_regmap: regmap interface for accessing the EEPROM + * @lock: mutex to synchronize operations to the device + * + * Central data structure holding the state and resources used by the + * M24LR device driver. + */ +struct m24lr { + u64 uid; + unsigned int sss_len; + unsigned int page_size; + unsigned int eeprom_size; + struct regmap *ctl_regmap; + struct regmap *eeprom_regmap; + struct mutex lock; /* synchronize operations to the device */ +}; + +static const struct regmap_range m24lr_ctl_vo_ranges[] =3D { + regmap_reg_range(0, 63), +}; + +static const struct regmap_access_table m24lr_ctl_vo_table =3D { + .yes_ranges =3D m24lr_ctl_vo_ranges, + .n_yes_ranges =3D ARRAY_SIZE(m24lr_ctl_vo_ranges), +}; + +static const struct regmap_config m24lr_ctl_regmap_conf =3D { + .name =3D "m24lr_ctl", + .reg_stride =3D 1, + .reg_bits =3D 16, + .val_bits =3D 8, + .disable_locking =3D false, + .cache_type =3D REGCACHE_RBTREE,/* Flat can't be used, there's huge gap */ + .volatile_table =3D &m24lr_ctl_vo_table, +}; + +/* Chip descriptor for M24LR04E-R variant */ +static const struct m24lr_chip m24lr04e_r_chip =3D { + .page_size =3D 4, + .eeprom_size =3D 512, + .sss_len =3D 4, +}; + +/* Chip descriptor for M24LR16E-R variant */ +static const struct m24lr_chip m24lr16e_r_chip =3D { + .page_size =3D 4, + .eeprom_size =3D 2048, + .sss_len =3D 16, +}; + +/* Chip descriptor for M24LR64E-R variant */ +static const struct m24lr_chip m24lr64e_r_chip =3D { + .page_size =3D 4, + .eeprom_size =3D 8192, + .sss_len =3D 64, +}; + +static const struct i2c_device_id m24lr_ids[] =3D { + { "m24lr04e-r", (kernel_ulong_t)&m24lr04e_r_chip}, + { "m24lr16e-r", (kernel_ulong_t)&m24lr16e_r_chip}, + { "m24lr64e-r", (kernel_ulong_t)&m24lr64e_r_chip}, + { } +}; +MODULE_DEVICE_TABLE(i2c, m24lr_ids); + +static const struct of_device_id m24lr_of_match[] =3D { + { .compatible =3D "st,m24lr04e-r", .data =3D &m24lr04e_r_chip}, + { .compatible =3D "st,m24lr16e-r", .data =3D &m24lr16e_r_chip}, + { .compatible =3D "st,m24lr64e-r", .data =3D &m24lr64e_r_chip}, + { } +}; +MODULE_DEVICE_TABLE(of, m24lr_of_match); + +/** + * m24lr_parse_le_value - Parse hex string and convert to little-endian bi= nary + * @buf: Input string buffer (hex format) + * @reg_size: Size of the register in bytes (must be 1, 2, 4, or 8) + * @output: Output buffer to store the value in little-endian format + * + * Converts a hexadecimal string to a numeric value of the given register = size + * and writes it in little-endian byte order into the provided buffer. + * + * Return: 0 on success, or negative error code on failure + */ +static __maybe_unused int m24lr_parse_le_value(const char *buf, u32 reg_si= ze, + u8 *output) +{ + int err; + + switch (reg_size) { + case 1: { + u8 tmp; + + err =3D kstrtou8(buf, 16, &tmp); + if (!err) + *output =3D tmp; + break; + } + case 2: { + u16 tmp; + + err =3D kstrtou16(buf, 16, &tmp); + if (!err) + *(__le16 *)output =3D cpu_to_le16(tmp); + break; + } + case 4: { + u32 tmp; + + err =3D kstrtou32(buf, 16, &tmp); + if (!err) + *(__le32 *)output =3D cpu_to_le32(tmp); + break; + } + case 8: { + u64 tmp; + + err =3D kstrtou64(buf, 16, &tmp); + if (!err) + *(__le64 *)output =3D cpu_to_le64(tmp); + break; + } + default: + err =3D -EINVAL; + } + + return err; +} + +/** + * m24lr_regmap_read - read data using regmap with retry on failure + * @regmap: regmap instance for the device + * @buf: buffer to store the read data + * @size: number of bytes to read + * @offset: starting register address + * + * Attempts to read a block of data from the device with retries and timeo= ut. + * Some M24LR chips may transiently NACK reads (e.g., during internal write + * cycles), so this function retries with a short sleep until the timeout + * expires. + * + * Returns: + * Number of bytes read on success, + * -ETIMEDOUT if the read fails within the timeout window. + */ +static ssize_t m24lr_regmap_read(struct regmap *regmap, u8 *buf, + size_t size, unsigned int offset) +{ + int err; + unsigned long timeout, read_time; + ssize_t ret =3D -ETIMEDOUT; + + timeout =3D jiffies + msecs_to_jiffies(M24LR_READ_TIMEOUT); + do { + read_time =3D jiffies; + + err =3D regmap_bulk_read(regmap, offset, buf, size); + if (!err) { + ret =3D size; + break; + } + + usleep_range(1000, 2000); + } while (time_before(read_time, timeout)); + + return ret; +} + +/** + * m24lr_regmap_write - write data using regmap with retry on failure + * @regmap: regmap instance for the device + * @buf: buffer containing the data to write + * @size: number of bytes to write + * @offset: starting register address + * + * Attempts to write a block of data to the device with retries and a time= out. + * Some M24LR devices may NACK I2C writes while an internal write operation + * is in progress. This function retries the write operation with a short = delay + * until it succeeds or the timeout is reached. + * + * Returns: + * Number of bytes written on success, + * -ETIMEDOUT if the write fails within the timeout window. + */ +static ssize_t m24lr_regmap_write(struct regmap *regmap, const u8 *buf, + size_t size, unsigned int offset) +{ + int err; + unsigned long timeout, write_time; + ssize_t ret =3D -ETIMEDOUT; + + timeout =3D jiffies + msecs_to_jiffies(M24LR_WRITE_TIMEOUT); + + do { + write_time =3D jiffies; + + err =3D regmap_bulk_write(regmap, offset, buf, size); + if (!err) { + ret =3D size; + break; + } + + usleep_range(1000, 2000); + } while (time_before(write_time, timeout)); + + return ret; +} + +static ssize_t m24lr_read(struct m24lr *m24lr, u8 *buf, size_t size, + unsigned int offset, bool is_eeprom) +{ + struct regmap *regmap; + long ret; + + if (is_eeprom) + regmap =3D m24lr->eeprom_regmap; + else + regmap =3D m24lr->ctl_regmap; + + mutex_lock(&m24lr->lock); + ret =3D m24lr_regmap_read(regmap, buf, size, offset); + mutex_unlock(&m24lr->lock); + + return ret; +} + +/** + * m24lr_write - write buffer to M24LR device with page alignment handling + * @m24lr: pointer to driver context + * @buf: data buffer to write + * @size: number of bytes to write + * @offset: target register address in the device + * @is_eeprom: true if the write should target the EEPROM, + * false if it should target the system parameters sector. + * + * Writes data to the M24LR device using regmap, split into chunks no larg= er + * than page_size to respect device-specific write limitations (e.g., page + * size or I2C hold-time concerns). Each chunk is aligned to the page boun= dary + * defined by page_size. + * + * Returns: + * Total number of bytes written on success, + * A negative error code if any write fails. + */ +static ssize_t m24lr_write(struct m24lr *m24lr, const u8 *buf, size_t size, + unsigned int offset, bool is_eeprom) +{ + unsigned int n, next_sector; + struct regmap *regmap; + ssize_t ret =3D 0; + long err; + + if (is_eeprom) + regmap =3D m24lr->eeprom_regmap; + else + regmap =3D m24lr->ctl_regmap; + + n =3D min(size, m24lr->page_size); + next_sector =3D roundup(offset + 1, m24lr->page_size); + if (offset + n > next_sector) + n =3D next_sector - offset; + + mutex_lock(&m24lr->lock); + while (n) { + err =3D m24lr_regmap_write(regmap, buf, n, offset); + if (IS_ERR_VALUE(err)) { + mutex_unlock(&m24lr->lock); + if (ret) + return ret; + else + return err; + } + + offset +=3D n; + size -=3D n; + ret +=3D n; + n =3D min(size, m24lr->page_size); + } + mutex_unlock(&m24lr->lock); + + return ret; +} + +/** + * m24lr_write_pass - Write password to M24LR043-R using secure format + * @m24lr: Pointer to device control structure + * @buf: Input buffer containing hex-encoded password + * @count: Number of bytes in @buf + * @code: Operation code to embed between password copies + * + * This function parses a 4-byte password, encodes it in big-endian forma= t, + * and constructs a 9-byte sequence of the form: + * + * [BE(password), code, BE(password)] + * + * The result is written to register 0x0900 (2304), which is the password + * register in M24LR04E-R chip. + * + * Return: Number of bytes written on success, or negative error code on f= ailure + */ +static ssize_t m24lr_write_pass(struct m24lr *m24lr, const char *buf, + size_t count, u8 code) +{ + __be32 be_pass; + u8 output[9]; + long ret; + u32 pass; + int err; + + if (!count) + return -EINVAL; + + if (count > 8) + return -EINVAL; + + err =3D kstrtou32(buf, 16, &pass); + if (err) + return err; + + be_pass =3D cpu_to_be32(pass); + + memcpy(output, &be_pass, sizeof(be_pass)); + output[4] =3D code; + memcpy(output + 5, &be_pass, sizeof(be_pass)); + + mutex_lock(&m24lr->lock); + ret =3D m24lr_regmap_write(m24lr->ctl_regmap, output, 9, 2304); + mutex_unlock(&m24lr->lock); + + return ret; +} + +static ssize_t m24lr_read_reg_le(struct m24lr *m24lr, u64 *val, + unsigned int reg_addr, + unsigned int reg_size) +{ + long ret; + __le64 input =3D 0; + + ret =3D m24lr_read(m24lr, (u8 *)&input, reg_size, reg_addr, false); + if (IS_ERR_VALUE(ret)) + return ret; + + if (ret !=3D reg_size) + return -EINVAL; + + switch (reg_size) { + case 1: + *val =3D *(u8 *)&input; + break; + case 2: + *val =3D le16_to_cpu((__le16)input); + break; + case 4: + *val =3D le32_to_cpu((__le32)input); + break; + case 8: + *val =3D le64_to_cpu((__le64)input); + break; + default: + return -EINVAL; + }; + + return 0; +} + +static int m24lr_nvmem_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct m24lr *m24lr =3D priv; + + if (!bytes) + return bytes; + + if (offset + bytes > m24lr->eeprom_size) + return -EINVAL; + + return m24lr_read(m24lr, val, bytes, offset, true); +} + +static int m24lr_nvmem_write(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct m24lr *m24lr =3D priv; + + if (!bytes) + return -EINVAL; + + if (offset + bytes > m24lr->eeprom_size) + return -EINVAL; + + return m24lr_write(m24lr, val, bytes, offset, true); +} + +static ssize_t m24lr_ctl_sss_read(struct file *filep, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t offset, size_t count) +{ + struct m24lr *m24lr =3D attr->private; + + if (!count) + return count; + + if (offset + count > m24lr->sss_len) + return -EINVAL; + + return m24lr_read(m24lr, buf, count, offset, false); +} + +static ssize_t m24lr_ctl_sss_write(struct file *filep, struct kobject *kob= j, + struct bin_attribute *attr, char *buf, + loff_t offset, size_t count) +{ + struct m24lr *m24lr =3D attr->private; + + if (!count) + return -EINVAL; + + if (offset + count > m24lr->sss_len) + return -EINVAL; + + return m24lr_write(m24lr, buf, count, offset, false); +} +static BIN_ATTR(sss, 0600, m24lr_ctl_sss_read, m24lr_ctl_sss_write, 0); + +static ssize_t new_pass_store(struct device *dev, struct device_attribute = *attr, + const char *buf, size_t count) +{ + struct m24lr *m24lr =3D i2c_get_clientdata(to_i2c_client(dev)); + + return m24lr_write_pass(m24lr, buf, count, 7); +} +static DEVICE_ATTR_WO(new_pass); + +static ssize_t unlock_store(struct device *dev, struct device_attribute *a= ttr, + const char *buf, size_t count) +{ + struct m24lr *m24lr =3D i2c_get_clientdata(to_i2c_client(dev)); + + return m24lr_write_pass(m24lr, buf, count, 9); +} +static DEVICE_ATTR_WO(unlock); + +static ssize_t uid_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct m24lr *m24lr =3D i2c_get_clientdata(to_i2c_client(dev)); + + return sysfs_emit(buf, "%llx\n", m24lr->uid); +} +static DEVICE_ATTR_RO(uid); + +static ssize_t total_sectors_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct m24lr *m24lr =3D i2c_get_clientdata(to_i2c_client(dev)); + + return sysfs_emit(buf, "%x\n", m24lr->sss_len); +} +static DEVICE_ATTR_RO(total_sectors); + +static struct attribute *m24lr_ctl_dev_attrs[] =3D { + &dev_attr_unlock.attr, + &dev_attr_new_pass.attr, + &dev_attr_uid.attr, + &dev_attr_total_sectors.attr, + NULL, +}; + +static const struct m24lr_chip *m24lr_get_chip(struct device *dev) +{ + const struct m24lr_chip *ret; + const struct i2c_device_id *id; + + id =3D i2c_match_id(m24lr_ids, to_i2c_client(dev)); + + if (dev->of_node && of_match_device(m24lr_of_match, dev)) + ret =3D of_device_get_match_data(dev); + else if (id) + ret =3D (void *)id->driver_data; + else + ret =3D acpi_device_get_match_data(dev); + + return ret; +} + +static int m24lr_probe(struct i2c_client *client) +{ + struct regmap_config eeprom_regmap_conf =3D {0}; + struct nvmem_config nvmem_conf =3D {0}; + struct device *dev =3D &client->dev; + struct i2c_client *eeprom_client; + const struct m24lr_chip *chip; + struct regmap *eeprom_regmap; + struct nvmem_device *nvmem; + struct regmap *ctl_regmap; + struct m24lr *m24lr; + u32 regs[2]; + long err; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EOPNOTSUPP; + + chip =3D m24lr_get_chip(dev); + if (!chip) + return -ENODEV; + + m24lr =3D devm_kzalloc(dev, sizeof(struct m24lr), GFP_KERNEL); + if (!m24lr) + return -ENOMEM; + + err =3D device_property_read_u32_array(dev, "reg", regs, ARRAY_SIZE(regs)= ); + if (err) { + dev_err(dev, "device_property_read_u32_array\n"); + return err; + } + /* Create a second I2C client for the eeprom interface */ + eeprom_client =3D devm_i2c_new_dummy_device(dev, client->adapter, regs[1]= ); + if (IS_ERR(eeprom_client)) { + dev_err(dev, + "Failed to create dummy I2C client for the EEPROM\n"); + return PTR_ERR(eeprom_client); + } + + ctl_regmap =3D devm_regmap_init_i2c(client, &m24lr_ctl_regmap_conf); + if (IS_ERR(ctl_regmap)) { + err =3D PTR_ERR(ctl_regmap); + dev_err(dev, "Failed to init regmap\n"); + return err; + } + + eeprom_regmap_conf.name =3D "m24lr_eeprom"; + eeprom_regmap_conf.reg_bits =3D 16; + eeprom_regmap_conf.val_bits =3D 8; + eeprom_regmap_conf.disable_locking =3D true; + eeprom_regmap_conf.max_register =3D chip->eeprom_size - 1; + + eeprom_regmap =3D devm_regmap_init_i2c(eeprom_client, + &eeprom_regmap_conf); + if (IS_ERR(eeprom_regmap)) { + err =3D PTR_ERR(eeprom_regmap); + dev_err(dev, "Failed to init regmap\n"); + return err; + } + + mutex_init(&m24lr->lock); + m24lr->sss_len =3D chip->sss_len; + m24lr->page_size =3D chip->page_size; + m24lr->eeprom_size =3D chip->eeprom_size; + m24lr->eeprom_regmap =3D eeprom_regmap; + m24lr->ctl_regmap =3D ctl_regmap; + + nvmem_conf.dev =3D &eeprom_client->dev; + nvmem_conf.owner =3D THIS_MODULE; + nvmem_conf.type =3D NVMEM_TYPE_EEPROM; + nvmem_conf.reg_read =3D m24lr_nvmem_read; + nvmem_conf.reg_write =3D m24lr_nvmem_write; + nvmem_conf.size =3D chip->eeprom_size; + nvmem_conf.word_size =3D 1; + nvmem_conf.stride =3D 1; + nvmem_conf.priv =3D m24lr; + + nvmem =3D devm_nvmem_register(dev, &nvmem_conf); + if (IS_ERR(nvmem)) + return PTR_ERR(nvmem); + + i2c_set_clientdata(client, m24lr); + i2c_set_clientdata(eeprom_client, m24lr); + + bin_attr_sss.size =3D chip->sss_len; + bin_attr_sss.private =3D m24lr; + err =3D sysfs_create_bin_file(&dev->kobj, &bin_attr_sss); + if (err) + return err; + + /* test by reading the uid, if success store it */ + err =3D m24lr_read_reg_le(m24lr, &m24lr->uid, 2324, sizeof(m24lr->uid)); + if (IS_ERR_VALUE(err)) + return -ENODEV; + + return 0; +} + +static void m24lr_remove(struct i2c_client *client) +{ + sysfs_remove_bin_file(&client->dev.kobj, &bin_attr_sss); +} + +ATTRIBUTE_GROUPS(m24lr_ctl_dev); + +static struct i2c_driver m24lr_driver =3D { + .driver =3D { + .name =3D "m24lr", + .of_match_table =3D m24lr_of_match, + .dev_groups =3D m24lr_ctl_dev_groups, + }, + .probe =3D m24lr_probe, + .remove =3D m24lr_remove, + .id_table =3D m24lr_ids, +}; +module_i2c_driver(m24lr_driver); + +MODULE_AUTHOR("Abd-Alrhman Masalkhi"); +MODULE_DESCRIPTION("st m24lr control driver"); +MODULE_LICENSE("GPL"); --=20 2.43.0 From nobody Sun Feb 8 05:58:00 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1DF351917CD; Sun, 8 Jun 2025 18:46:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749408373; cv=none; b=pdw3xE/qHjIdlXqWtcZ9L5L6kDvlPTVWf0Rj0ybYqcw3mjn7VOTL+SgJ31ZM4ZmAO5ZdtaGo0meFwWfcL/mpO4Q57eTz2uK5ziyiq1yvrWxgsODiIaztGuc2/6BEuupzvmsW9zL7tDGnykJjMmqfhDeRJK9vCqvBuDs0JbN8oUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749408373; c=relaxed/simple; bh=5kinR0KrS7IkPwN9fE1QIIqbPAWuMKnmvKhh7UgyExg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FwMgi29nE7QBdMrGp+ObIq86yRusptsvxYZC/TqyMqsHGTe1nE/9SmAv+hQGUWBDJCkxqarOwysaEuBW9P+1sw0+SvPdYkfg4EZaSNGm4GdYxObdhhDc3VaXLRR/cWPFQ0x+JgldWcGy8gRx24flKJVEtNyEVak+Nu3XNLS4+GQ= 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=OKP2rERf; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OKP2rERf" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-451d3f72391so48835265e9.3; Sun, 08 Jun 2025 11:46:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749408369; x=1750013169; 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=Nf6PjjJ5TJPZ+Dos5EBSJCJYt0quyjq/Hxi+5XwPSFE=; b=OKP2rERfTt/BTPc6FC9MOwiSz1mtitBUgnGyrqKjvmrcu81fasLv4X6IryQgObbf65 0TT5Q4oqADbxuQSGP6UEKRaUYg9yZoKrP3renIpjAkCjZYiJpDIXhRckECZ4+cOCUjKr ECD1F4TdwU5yNMgXC7oLjRSh0L8UJfT3onTGI8uwewFARDTwQyJFK1i5DhsPV3WksP6o 0x2gMydrbYM/NFdhSx7BZMub+aCAgoagS5w4mra4CBmQ7BSSH4DzXHgIunSgRafPai9a Nkz2n4Hc7hon1WNNPLXF+76+K18ijFhzDM/yfnAE3qiKUCY4HWSxKcB1dsR5+M0d4xuJ PE5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749408369; x=1750013169; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Nf6PjjJ5TJPZ+Dos5EBSJCJYt0quyjq/Hxi+5XwPSFE=; b=dGIP33aTo/t5fG/qycSOvWOJGj3EHNycejPIqf7jSnwn63GhCFcKlnebFdqquu8eqb XcOq5b67tubyXjWc4ul2GIYVDTBsQMGKTemNLogp0p3iCWpVfPeqJcs6XAyglwcsIuxF o+WwyS5I7ah20jJkCQ1MGUGFH5yQMQPqLNSL3maEFEOCW19CKidGE1Fy97Aj7gLPH0Ip vBa6MrcTCmQsnxA7Vep9u7CDC9SACakwHBXoA2U5gXz7MU61jWeJnvH1gD5N/hS98oJH p7FJRQiqyNFccdAryc0dgNDMXfdxR33k5cw89x4SXOpD/gxGQAGxCNwlOI6q3JNRn7k6 q/sw== X-Forwarded-Encrypted: i=1; AJvYcCWvgUgQ1PhBVgnX8CdkYHSgLd0WqR0p9UxBIr0XMWFtNrzr20F7IIgmxMurT6SkM+nWgG2bmtkAYF7k@vger.kernel.org X-Gm-Message-State: AOJu0YyAoomKD6RQC+sY8Hl1j8duvDWAtBFkOfkVwUdrmwtwykWiLBHk O7J7OMQoAOj9LWjoWxhDQdShK2l6mIUesyur2wGtyvmLwP1FTe64SsgMPx7w8sQX X-Gm-Gg: ASbGncvkD9ZQTp3pQGfG0EOLcDA4OySZE4VkZKerUR+1s1VBZDwhOVgA8u8p3E7Gw1+ lAk/LxIH6ZN1QKIXtyAguf3FbpwiQKhjp/1mKjSSIykuigarIV6EItN/QBJCpXsxiR/GYSih+yb 8k6eFSBIKwiYc9kG3wLXddb0l47RoBM9R5v0uF35ZLIzd6taYUJIbzlw7gBl7n9juqo3OgtuCJP vEVFUPDkLiFFKI7OuvCHGdvs0pr/GEpb1oguCwQ2Lpj4C25BsR3iu7gIbvJBFQiwe+VkJlqQ+Mc 3Vv/dm6zI70jcfM/Mpj/LECplL+dHcbTONtVUKTLxhdiPtK23ls+kNNhy13f1N1M6UK0TPM9xVG u48U9Ti1sa1bvbQ== X-Google-Smtp-Source: AGHT+IHrh3Ufshadaldzj7/sz/XQbdcLDGkH3q3WMhwjlL84aOnLgw1GRwUTyiJSwD3+kwYZk36QgA== X-Received: by 2002:a05:600c:1c25:b0:44d:a244:4983 with SMTP id 5b1f17b1804b1-45201437a46mr108445675e9.3.1749408369235; Sun, 08 Jun 2025 11:46:09 -0700 (PDT) Received: from masalkhi.. (ip-109-43-113-112.web.vodafone.de. [109.43.113.112]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a5324361ffsm7621418f8f.47.2025.06.08.11.46.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Jun 2025 11:46:08 -0700 (PDT) From: Abd-Alrhman Masalkhi To: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Cc: arnd@arndb.de, gregkh@linuxfoundation.org, W_Armin@gmx.de, luoyifan@cmss.chinamobile.com, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, abd.masalkhi@gmail.com Subject: [PATCH v4 3/3] ABI: sysfs: add documentation for ST M24LR EEPROM and control interface Date: Sun, 8 Jun 2025 18:27:14 +0000 Message-ID: <20250608182714.3359441-4-abd.masalkhi@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250608182714.3359441-1-abd.masalkhi@gmail.com> References: <20250608182714.3359441-1-abd.masalkhi@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 sysfs ABI documentation for the STMicroelectronics M24LR device, covering both the control interface (e.g., unlock, password update, UID, memory size, and SSS entries) and EEPROM access via the nvmem subsystem. Signed-off-by: Abd-Alrhman Masalkhi --- Changes in v4: - Replaced 'sss' entries with a single binary 'sss' attribute - Added 'total_sectors' attribute to report the number of valid SSS bytes - removed 'mem_size' attribute --- .../ABI/testing/sysfs-bus-i2c-devices-m24lr | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-m24lr diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-m24lr b/Docume= ntation/ABI/testing/sysfs-bus-i2c-devices-m24lr new file mode 100644 index 000000000000..0af1afa45ea0 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-m24lr @@ -0,0 +1,100 @@ +What: /sys/bus/i2c/devices/-/unlock +Date: 2025-06-8 +KernelVersion: 6.15 +Contact: Abd-Alrhman Masalkhi +Description: + Write-only attribute used to present a password and unlock + access to protected areas of the M24LR chip, including + configuration registers such as the Sector Security Status + (SSS) bytes. A valid password must be written to enable wr= ite + access to these regions via the I2C interface. + + Format: + - Hexadecimal string representing a 32-bit (4-byte) pass= word + - Accepts 1 to 8 hex digits (e.g., "c", "1F", "a1b2c3d4") + - No "0x" prefix, whitespace, or trailing newline + - Case-insensitive + + Behavior: + - If the password matches the internal stored value, + access to protected memory/configuration is granted + - If the password does not match the internally stored v= alue, + it will fail silently + +What: /sys/bus/i2c/devices/-/new_pass +Date: 2025-06-8 +KernelVersion: 6.15 +Contact: Abd-Alrhman Masalkhi +Description: + Write-only attribute used to update the password required = to + unlock the M24LR chip. + + Format: + - Hexadecimal string representing a new 32-bit password + - Accepts 1 to 8 hex digits (e.g., "1A", "ffff", "c0ffee= 00") + - No "0x" prefix, whitespace, or trailing newline + - Case-insensitive + + Behavior: + - Overwrites the current password stored in the I2C pass= word + register + - Requires the device to be unlocked before changing the + password + - If the device is locked, the write silently fails + +What: /sys/bus/i2c/devices/-/uid +Date: 2025-06-8 +KernelVersion: 6.15 +Contact: Abd-Alrhman Masalkhi +Description: + Read-only attribute that exposes the 8-byte unique identif= ier + programmed into the M24LR chip at the factory. + + Format: + - Lowercase hexadecimal string representing a 64-bit val= ue + - 1 to 16 hex digits (e.g., "e00204f12345678") + - No "0x" prefix + - Includes a trailing newline + +What: /sys/bus/i2c/devices/-/total_sectors +Date: 2025-05-31 +KernelVersion: 6.16 +Contact: Abd-Alrhman Masalkhi +Description: + Read-only attribute that exposes the total number of EEPROM + sectors available in the M24LR chip. + + Format: + - 1 to 2 hex digits (e.g. "F") + - No "0x" prefix + - Includes a trailing newline + + Notes: + - Value is encoded by the chip and corresponds to the EE= PROM + size (e.g., 3 =3D 4 kbit for M24LR04E-R) + +What: /sys/bus/i2c/devices/-/sss +Date: 2025-06-8 +KernelVersion: 6.15 +Contact: Abd-Alrhman Masalkhi +Description: + Read/write binary attribute representing the Sector Securi= ty + Status (SSS) bytes for all EEPROM sectors in STMicroelectr= onics + M24LR chips. + + Each EEPROM sector has one SSS byte, which controls I2C and + RF access through protection bits and optional password + authentication. + + Format: + - The file contains one byte per EEPROM sector + - Byte at offset N corresponds to sector N + - Binary access only; use tools like dd, Python, or C th= at + support byte-level I/O and offset control. + + Notes: + - The number of valid bytes in this file is equal to the + value exposed by 'total_sectors' file + - Write access requires prior password authentication in + I2C mode + - Refer to the M24LR datasheet for full SSS bit layout --=20 2.43.0