From nobody Fri Dec 19 11:50:10 2025 Received: from mail.subdimension.ro (nalicastle.subdimension.ro [172.105.74.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 678C2235360; Sun, 7 Dec 2025 06:01:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=172.105.74.154 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765087283; cv=none; b=pD+0+t3ADwxtIQpBYOkUiXc/4LbvXG0ETnk5aPXaS+pRetps7NN2YiA0W6w2HBVq8KTsYh/wbY41yPgkY+6i+HcCp0tBgrjWN4BFwkKkZs18AAYCzkjCEvLpbE7bGHQmCEPI/0qqhEwMfqTcXyAJgeuAgSql+JG04Dg7GI1LFAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765087283; c=relaxed/simple; bh=7I+r0kMg2hq+74CBZGAcx0l38flZmO+/7PI7Vw8bvUE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Xfsr3jIhowv4kNLvsIeZgsGysMPZbbRm9RdNde2wALtAt4zo7g7m7eEomc48RpVmO3K0muJSc0jcAnaecs9MKBCA1Vy2Tz0DJdAzHBz1FwEmhfDbMmaxgqrIGuPI3fXJOf3SN6qD/ONkPlFZpDYO7D2KP8dtks745cy/pxP9hhU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=subdimension.ro; spf=pass smtp.mailfrom=subdimension.ro; dkim=pass (2048-bit key) header.d=subdimension.ro header.i=@subdimension.ro header.b=foI3+DwV; arc=none smtp.client-ip=172.105.74.154 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=subdimension.ro Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=subdimension.ro Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=subdimension.ro header.i=@subdimension.ro header.b="foI3+DwV" Received: from sunspire.home.arpa (unknown [IPv6:2a02:2f0e:3402:a400:e2d5:5eff:fed9:f1c4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mail.subdimension.ro (Postfix) with ESMTPSA id 86B5D16020A; Sun, 07 Dec 2025 08:01:11 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=subdimension.ro; s=mail; t=1765087272; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0lb1pcQ5KFG4ZDPQ4IXeDuK579gRShpukXEuWar548c=; b=foI3+DwVk1GObHIG2Df5sE3D5jIXiP/DAt2yqCiygXSBcaY2j+CtvR2nek6qZdNGkfz5yx URWhNP1M3voFUs/6iOB4dI0aRX/qjONC+Q6vLXwKfkZDyrxKjW2E1fEBgPh/xYjNM5nuYj q4l3DBWLzp/lLR3G+uCQsGO1z8VjLMmn2xNyH5uqoO3+wOALIh5h0mZ12jnZc8URc5/9o/ VKfXtj4XF9c5rrFKElVGjAucklmVQXkHqJsW5Xovw8DcvI3sJMcq8rkerSW96vakH+WHad omsrmPmraahrwdplozlIeqHLpzJVFasWda4bjBPnjNZNWWzvGizYlfm+ayUCbg== From: Petre Rodan Date: Sun, 07 Dec 2025 08:00:47 +0200 Subject: [PATCH v4 1/2] dt-bindings: iio: pressure: add honeywell,abp2030pa Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251207-honeywell_abp2_driver-v4-1-b52a4b96bbf7@subdimension.ro> References: <20251207-honeywell_abp2_driver-v4-0-b52a4b96bbf7@subdimension.ro> In-Reply-To: <20251207-honeywell_abp2_driver-v4-0-b52a4b96bbf7@subdimension.ro> To: Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Petre Rodan X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5889; i=petre.rodan@subdimension.ro; h=from:subject:message-id; bh=7I+r0kMg2hq+74CBZGAcx0l38flZmO+/7PI7Vw8bvUE=; b=LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpvd0o0bkFGdEFwTDlrQTBEQUFvQmRDc25wM k02U1dNQnl5WmlBR2sxR0NFSUdJNDlIbXEzc2hsc0xHajV6V3pSCnZrUFNjT2dnQkFsc0loMFJK TWsvWTRrQ013UUFBUW9BSFJZaEJCb2ltQncrRGJ4UXBFNmlkM1FySjZkak9rbGoKQlFKcE5SZ2h BQW9KRUhRcko2ZGpPa2xqTUNZUUFKR2c4MHcyZVhmTW82cXNQUFlDRTd3UGg2VGNrWEVnSVhNNg pFVkc5K0NZOTdZcUg5YmdITm0xdVJxOUhBcC9RamhaQ2QxTWdPdUo2bWVJUHhaNkpnKzVPQXFwZ ytHZVp2Q1pLCmIra2QvWG4wL0dkYmUxSTlEcCs0OTNxdm1VMUZLK1VhTnZWTkM5c2tXNzBCcHA3 SjRhcDladkhqS3p3MG9UcTgKL1J0NXc4Y2tYWWNOb2d0YzBuNjNkenE1QlJOc1FnclFITkYxUUF xQVdEMFdleTFQWnpGWHdGLzF6NXBmZnBZOQpRYm02SGxXVGhsOE0ybW13bGNhUnBsUWt1MWNZWj cwV2lkaWpUSTdVaStWczFIZUMwd1FIMFBpcnExNWNGUEF5CmVucDB6UnY1cEFSVWJsRGowdnNrY nJCS0UvRm5mYy9IbUwzbVZnKzZhcjEzenVucnRkdHdvWmJTU3NNeUp5WUcKUkl1bmlWWCtjemd3 NFJTZ2t6VkxSb2Zralh1eVNEUnBUYVBDKzg4V09WQ3FjVURJZ1BDTzFWamRDbnVWN0lYZAp0aU0 5N2RVYlhrRW0yMkZVNkQrYjRHZ2pvWmc2QlBGTVhySzdSTHZuNDJXYU9vc1Q3Y2dXYmtzWWxJWW tsRjg4CnQyYlU3RCtXQnpUNTFTY3RPRXFLYSt4enAvZk12WWp1a3pqYzZ2Z3JxekRna2RLdWxnS DZRY1VNTTV6V3FHRG4KelVjcGlDVzdmZm9YZHM3bTJzb3paMlhNZitYc3NNNDVKRllQK040cGJX cGpCQWZLcDJMRm5kTUw3RkliOFlHbgpRUkV1dEo4bGhLYTc2bmtFVWcvYzdlbmhFSFdCTUpaWm5 XZTZGSXRUbDNuNlIzQXRTQnhqdGhIYWJQaUU5Tkw2Cm0xTzhGSmI3WDdJZjJBPT0KPXhYODEKLS 0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo= X-Developer-Key: i=petre.rodan@subdimension.ro; a=openpgp; fpr=D80A7FC176151935EC3E5FA9CF269999844E7F30 Adds binding for digital Honeywell ABP2 series pressure and temperature sensors. The i2c address is hardcoded and depends on the part number. There is an optional interrupt that signals the end of conversion. Signed-off-by: Petre Rodan --- v1->v3 unchanged v3->v4 'vdd-supply: true' change requested by Jonathan --- .../bindings/iio/pressure/honeywell,abp2030pa.yaml | 132 +++++++++++++++++= ++++ MAINTAINERS | 6 + 2 files changed, 138 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/pressure/honeywell,abp20= 30pa.yaml b/Documentation/devicetree/bindings/iio/pressure/honeywell,abp203= 0pa.yaml new file mode 100644 index 000000000000..e82897ffac3b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.ya= ml @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/pressure/honeywell,abp2030pa.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Honeywell abp2030pa pressure sensor + +maintainers: + - Petre Rodan + +description: | + Honeywell pressure sensor of model abp2030pa. + + This sensor has an I2C and SPI interface. + + There are many models with different pressure ranges available. The vend= or + calls them "ABP2 series". All of them have an identical programming mode= l and + differ in the pressure range and measurement unit. + + To support different models one needs to specify its pressure triplet. + + For custom silicon chips not covered by the Honeywell ABP2 series datash= eet, + the pressure values can be specified manually via honeywell,pmin-pascal = and + honeywell,pmax-pascal. + + Specifications about the devices can be found at: + https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-u= s/products/sensors/pressure-sensors/board-mount-pressure-sensors/basic-abp2= -series/documents/sps-siot-abp2-series-datasheet-32350268-en.pdf + +properties: + compatible: + const: honeywell,abp2030pa + + reg: + maxItems: 1 + + interrupts: + description: + Optional interrupt for indicating end of conversion. + SPI variants of ABP2 chips do not provide this feature. + maxItems: 1 + + honeywell,pressure-triplet: + description: | + Case-sensitive five character string that defines pressure range, un= it + and type as part of the device nomenclature. In the unlikely case of= a + custom chip, unset and provide pmin-pascal and pmax-pascal instead. + enum: [001BA, 1.6BA, 2.5BA, 004BA, 006BA, 008BA, 010BA, 012BA, 001BD, + 1.6BD, 2.5BD, 004BD, 001BG, 1.6BG, 2.5BG, 004BG, 006BG, 008BG, + 010BG, 012BG, 001GG, 1.2GG, 100KA, 160KA, 250KA, 001KD, 1.6KD, + 2.5KD, 004KD, 006KD, 010KD, 016KD, 025KD, 040KD, 060KD, 100KD, + 160KD, 250KD, 400KD, 001KG, 1.6KG, 2.5KG, 004KG, 006KG, 010KG, + 016KG, 025KG, 040KG, 060KG, 100KG, 160KG, 250KG, 400KG, 600KG, + 800KG, 250LD, 600LD, 600LG, 2.5MD, 006MD, 010MD, 016MD, 025MD, + 040MD, 060MD, 100MD, 160MD, 250MD, 400MD, 600MD, 006MG, 010MG, + 016MG, 025MG, 040MG, 060MG, 100MG, 160MG, 250MG, 400MG, 600MG, + 001ND, 002ND, 004ND, 005ND, 010ND, 020ND, 030ND, 002NG, 004NG, + 005NG, 010NG, 020NG, 030NG, 015PA, 030PA, 060PA, 100PA, 150PA, + 175PA, 001PD, 005PD, 015PD, 030PD, 060PD, 001PG, 005PG, 015PG, + 030PG, 060PG, 100PG, 150PG, 175PG] + $ref: /schemas/types.yaml#/definitions/string + + honeywell,pmin-pascal: + description: + Minimum pressure value the sensor can measure in pascal. + + honeywell,pmax-pascal: + description: + Maximum pressure value the sensor can measure in pascal. + + spi-max-frequency: + maximum: 800000 + + vdd-supply: true + +required: + - compatible + - reg + - vdd-supply + +oneOf: + - required: + - honeywell,pressure-triplet + - required: + - honeywell,pmin-pascal + - honeywell,pmax-pascal + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml + - if: + required: + - honeywell,pressure-triplet + then: + properties: + honeywell,pmin-pascal: false + honeywell,pmax-pascal: false + +additionalProperties: false + +examples: + - | + #include + #include + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + pressure@18 { + compatible =3D "honeywell,abp2030pa"; + reg =3D <0x18>; + interrupt-parent =3D <&gpio3>; + interrupts =3D <21 IRQ_TYPE_EDGE_RISING>; + + honeywell,pressure-triplet =3D "001BA"; + vdd-supply =3D <&vcc_3v3>; + }; + }; + - | + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + + pressure@0 { + compatible =3D "honeywell,abp2030pa"; + reg =3D <0>; + spi-max-frequency =3D <800000>; + + honeywell,pressure-triplet =3D "001PD"; + vdd-supply =3D <&vcc_3v3>; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 31d98efb1ad1..15b92300acbc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11404,6 +11404,12 @@ F: lib/test_hmm* F: mm/hmm* F: tools/testing/selftests/mm/*hmm* =20 +HONEYWELL ABP2030PA PRESSURE SENSOR SERIES IIO DRIVER +M: Petre Rodan +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.yaml + HONEYWELL HSC030PA PRESSURE SENSOR SERIES IIO DRIVER M: Petre Rodan L: linux-iio@vger.kernel.org --=20 2.51.2 From nobody Fri Dec 19 11:50:10 2025 Received: from mail.subdimension.ro (nalicastle.subdimension.ro [172.105.74.154]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 678521DC997; Sun, 7 Dec 2025 06:01:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=172.105.74.154 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765087284; cv=none; b=UkdTstQ+7uRGzvBSnmCoAeuDd8q0+Ahp87w5sJl4Mk33OjU0GVzVH1Q5XMYAKspp0mFWyDSwSyGVtZuXCJYymyyc4DInhpVbWaNns3UawI0tXfYJtmI78DjXYiUADgN0aAOW3Pgh04iqcm41a73wKufAiSREJSqFTB+05lTlBdA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765087284; c=relaxed/simple; bh=cAG6SaYL9QnA+onZsz+17Xdidoeg6Ev9UXHkOvMs22A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sVJB/Cg0J/IxyvbSPNy6uVP7wgEUUoDF0Vxk9KuWzY5LkAjQkPbMTrzahWfriYR2KVF+BD6eCB3ITPaVbF6wgw7H9yOa4op9QinuXy8BQbKLLJUli7XJbTbbSgM0efnDENoXKAJdsnTuC3UyCn84nMBm+70AhgQhFR/6RsuMCzU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=subdimension.ro; spf=pass smtp.mailfrom=subdimension.ro; dkim=pass (2048-bit key) header.d=subdimension.ro header.i=@subdimension.ro header.b=BRl7bAdP; arc=none smtp.client-ip=172.105.74.154 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=subdimension.ro Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=subdimension.ro Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=subdimension.ro header.i=@subdimension.ro header.b="BRl7bAdP" Received: from sunspire.home.arpa (unknown [IPv6:2a02:2f0e:3402:a400:e2d5:5eff:fed9:f1c4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mail.subdimension.ro (Postfix) with ESMTPSA id 6475E16020B; Sun, 07 Dec 2025 08:01:12 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=subdimension.ro; s=mail; t=1765087272; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bao0CkDUTQfxzq2OXRiVJmos8nTGliO7utb2FTPMwzk=; b=BRl7bAdP56eaaJZJ1J1TP6GccwMsH/uaskpPj051QHjqz/Nb22ubH9DidgnwnK2ALMmhLO IoS57kCi6ltIw3DzAZnf+EewYWcU2HN4+7SQlsbg+8PCWMB14cAr95IYBcGqE4B1gIrm65 lgyZzxX97zscStsNtg2PlOX3O4bZ05+BCAgelBpr3lLxhsQ2T0mOjw35qcidVLa8/oOjBD ZoO9bsfKuGILrNfOcVOtz+IWiWt2U/yv12fvqXyjh2vQyd4Id6Kyu2hexlvraz3pKQDTyJ 4k7GevXKsZKcNtNYkJkmWD3R2UOUf1npEzJXicylmleuvVyB1+d8/RXfcxoG/A== From: Petre Rodan Date: Sun, 07 Dec 2025 08:00:48 +0200 Subject: [PATCH v4 2/2] iio: pressure: add Honeywell ABP2 driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251207-honeywell_abp2_driver-v4-2-b52a4b96bbf7@subdimension.ro> References: <20251207-honeywell_abp2_driver-v4-0-b52a4b96bbf7@subdimension.ro> In-Reply-To: <20251207-honeywell_abp2_driver-v4-0-b52a4b96bbf7@subdimension.ro> To: Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Petre Rodan X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=32864; i=petre.rodan@subdimension.ro; h=from:subject:message-id; bh=cAG6SaYL9QnA+onZsz+17Xdidoeg6Ev9UXHkOvMs22A=; b=LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpvd0o0bkFGdEFwTDlrQTBEQUFvQmRDc25wM k02U1dNQnl5WmlBR2sxR0NJaENieko4Z0VuQWVxM2FuREh5TStXCjZ3ZW5ucC9hS2pVd3RxbEZS OE5oZVlrQ013UUFBUW9BSFJZaEJCb2ltQncrRGJ4UXBFNmlkM1FySjZkak9rbGoKQlFKcE5SZ2l BQW9KRUhRcko2ZGpPa2xqTTB3UUFKdWR2T1JOaVlLSDl1bkxFaHRCWTFKUVdmN0VsWVQ3ZE1MSw pGMzJMejBoQWtEWjJMV004YXlJckJ2Z1k2UGdIMnRzUU5XbHYrVzE4WjNYWmlqZmkwcDBRUlVNW Wk1aDdxR3h2CmNvd2NUWDFuckNvckFJWkpQZlNGT2o2SDBVU001cHo4bjdrUzlqak8xTlYxZE5Z NllGTGVaMkFub2h3YllFRDIKTm5iOEdtRFB0c0d6WjhpbWN4aVY5TkpCYUs2ckpSZXZ4eW5FZXB vU2xoaFRxZ0ZmL2JVNGpWRlhpVHJHMzVxWQpiR3JuRUc5dURVc3ROMEp5djBNMGdNQjI3bEh0L1 ROMjVBbnBiTE9PdXhsdkpHV09kZDkzTWk2ODJVcndtd011CkQ3SlRWdk5RNXExZlpRRlNXck8zc E85dFZGZG5yRktzeWVTYXBQZ01HUFUxdWRrK3V3NGsxb2NkVC9IMnJJdjAKelhOMVViN0hKeUYr N2IxbFlKb2pMOFgvT2Y1SUdPYWtvU0ZRMlZDVkcwV1lRQ1ZGbnNhajFIcUFYSm1MTWZkVgpsY0l Xekt5TVh3dGdUUklCc0tmNEloTXFMWTk3SDBQVUY4Tk1CUmxtTnVsL3Y3bGJTa09sZHVHQkYyel h4TVU2ClZVSjR2WWkxem1IdVZwOGNxMzlsTnZSRXREb2pRUHRlSE5PNjNDazFsZGFDQ1ZMWHFOd 2w3UkJJenh5bFgvbjAKWFRXOXNEZUFTenA0d0FSQ0I1cXZKcFBQejdPOVVPd2xpVVhFSmdOMDdL UlJ2Y1FmTk82WkR1OFAyYlhpdE4yUQpQY0RaekhRRTVlTllWYkxPRFo4OXA1MzNoUStJdUpoMm9 Xd0MxYUx1TnVFTkZBRUVrSlVxQXVFd1hnSUZDd1F3Ck9jc25KNytZM1VFYkdBPT0KPWo0L3gKLS 0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo= X-Developer-Key: i=petre.rodan@subdimension.ro; a=openpgp; fpr=D80A7FC176151935EC3E5FA9CF269999844E7F30 Adds driver for digital Honeywell ABP2 series of board mount pressure and temperature sensors. This driver covers 113 different pressure ranges and units on both i2c and SPI buses. The communication protocol involves sending two simple commands to the sensor and there is no register access or a memory map. For this reason the regmap API was not used. The i2c address is hardcoded and depends on the part number. Optional end of conversion interrupt control is present on the i2c variants of the chips. The EOC can also be defined for the SPI variants if a non-ABP2 but compatible chip is to be driven. Tested on two sensors (ABP2MRRT001PDSA3 and ABP2DANT001BA2A3). Datasheet: https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/s= iot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/ba= sic-abp2-series/d ocuments/sps-siot-abp2-series-datasheet-32350268-en.pdf Signed-off-by: Petre Rodan --- v1 -> v2 changes based on Andy's review commit msg: - Datasheet tag - mention the lack of regmap use Kconfig: - user can nicely select bus drivers separately abp2030pa.c: - add a few includes - blank line trimming - enum without assignments - use the recommended trailing in the arrays - less const - comment for the 5 * USEC_PER_MSEC fsleep() - curly braces for else branch - improved error codes - remove INDIO_DIRECT_MODE line - remove call to _ops->init abp2030pa.h: - add completion header - remove a few structs - rename buffer -> rx_buf in abp2_data struct - add tx_buf to abp2_data struct abp2030pa_i2c.c, abp2030pa_spi.c: - remove _init() ops - remove redundant else - remove device.h include from _spi.c v2 -> v3 changes based on Andy's review - move a few private constants from .h to .c - replace ABP2_VARIANTS_MAX with a static_assert - Kconfig select dependencies in _core symbol - move memset call - rename jump label - change indentation - s/IRQF_TRIGGER_RISING/IRQF_ONESHOT/ - add comment about latch-up sensitivity right above the invalid status error v3 -> v4 changes based on Jonathan's review - remove sysfs include - add back INDIO_DIRECT_MODE - add available_scan_masks - tweak cacheline alignment as per Jonathan's input - change abp2_i2c_write() to be more generic, just as it's spi counterpa= rt - zero out xfer struct in abp2_spi_xfer() --- MAINTAINERS | 1 + drivers/iio/pressure/Kconfig | 29 ++ drivers/iio/pressure/Makefile | 3 + drivers/iio/pressure/abp2030pa.c | 544 +++++++++++++++++++++++++++++++= ++++ drivers/iio/pressure/abp2030pa.h | 73 +++++ drivers/iio/pressure/abp2030pa_i2c.c | 90 ++++++ drivers/iio/pressure/abp2030pa_spi.c | 67 +++++ 7 files changed, 807 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 15b92300acbc..0aa9cba68137 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11409,6 +11409,7 @@ M: Petre Rodan L: linux-iio@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.yaml +F: drivers/iio/pressure/abp2030pa* =20 HONEYWELL HSC030PA PRESSURE SENSOR SERIES IIO DRIVER M: Petre Rodan diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 2fe9dc90cceb..b2720be51506 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -16,6 +16,35 @@ config ABP060MG To compile this driver as a module, choose M here: the module will be called abp060mg. =20 +config ABP2030PA + tristate + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + +config ABP2030PA_I2C + tristate "Honeywell ABP2 pressure sensor series I2C driver" + depends on I2C + select ABP2030PA + help + Say Y here to build I2C bus support for the Honeywell ABP2 + series pressure and temperature digital sensor. + + To compile this driver as a module, choose M here: the module + will be called abp2030pa_i2c and you will also get abp2030pa + for the core module. + +config ABP2030PA_SPI + tristate "Honeywell ABP2 pressure sensor series SPI driver" + depends on SPI_MASTER + select ABP2030PA + help + Say Y here to build I2C bus support for the Honeywell ABP2 + series pressure and temperature digital sensor. + + To compile this driver as a module, choose M here: the module + will be called abp2030pa_spi and you will also get abp2030pa + for the core module. + config ROHM_BM1390 tristate "ROHM BM1390GLV-Z pressure sensor driver" depends on I2C diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index a21443e992b9..bc0d11a20acc 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -5,6 +5,9 @@ =20 # When adding new entries keep the list in alphabetical order obj-$(CONFIG_ABP060MG) +=3D abp060mg.o +obj-$(CONFIG_ABP2030PA) +=3D abp2030pa.o +obj-$(CONFIG_ABP2030PA_I2C) +=3D abp2030pa_i2c.o +obj-$(CONFIG_ABP2030PA_SPI) +=3D abp2030pa_spi.o obj-$(CONFIG_ADP810) +=3D adp810.o obj-$(CONFIG_ROHM_BM1390) +=3D rohm-bm1390.o obj-$(CONFIG_BMP280) +=3D bmp280.o diff --git a/drivers/iio/pressure/abp2030pa.c b/drivers/iio/pressure/abp203= 0pa.c new file mode 100644 index 000000000000..be11e28208ec --- /dev/null +++ b/drivers/iio/pressure/abp2030pa.c @@ -0,0 +1,544 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + * + * Datasheet: https://prod-edam.honeywell.com/content/dam/honeywell-edam/s= ps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensor= s/basic-abp2-series/documents/sps-siot-abp2-series-datasheet-32350268-en.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "abp2030pa.h" + +/* Status byte flags */ +#define ABP2_ST_POWER BIT(6) /* 1 if device is powered */ +#define ABP2_ST_BUSY BIT(5) /* 1 if device is busy */ + +#define ABP2_CMD_NOP 0xf0 +#define ABP2_CMD_SYNC 0xaa +#define ABP2_PKT_SYNC_LEN 3 +#define ABP2_PKT_NOP_LEN ABP2_MEASUREMENT_RD_SIZE + +struct abp2_func_spec { + u32 output_min; + u32 output_max; +}; + +/* transfer function A: 10% to 90% of 2^24 */ +static const struct abp2_func_spec abp2_func_spec[] =3D { + [ABP2_FUNCTION_A] =3D { .output_min =3D 1677722, .output_max =3D 15099494= }, +}; + +enum abp2_variants { + ABP2001BA, ABP21_6BA, ABP22_5BA, ABP2004BA, ABP2006BA, ABP2008BA, + ABP2010BA, ABP2012BA, ABP2001BD, ABP21_6BD, ABP22_5BD, ABP2004BD, + ABP2001BG, ABP21_6BG, ABP22_5BG, ABP2004BG, ABP2006BG, ABP2008BG, + ABP2010BG, ABP2012BG, ABP2001GG, ABP21_2GG, ABP2100KA, ABP2160KA, + ABP2250KA, ABP2001KD, ABP21_6KD, ABP22_5KD, ABP2004KD, ABP2006KD, + ABP2010KD, ABP2016KD, ABP2025KD, ABP2040KD, ABP2060KD, ABP2100KD, + ABP2160KD, ABP2250KD, ABP2400KD, ABP2001KG, ABP21_6KG, ABP22_5KG, + ABP2004KG, ABP2006KG, ABP2010KG, ABP2016KG, ABP2025KG, ABP2040KG, + ABP2060KG, ABP2100KG, ABP2160KG, ABP2250KG, ABP2400KG, ABP2600KG, + ABP2800KG, ABP2250LD, ABP2600LD, ABP2600LG, ABP22_5MD, ABP2006MD, + ABP2010MD, ABP2016MD, ABP2025MD, ABP2040MD, ABP2060MD, ABP2100MD, + ABP2160MD, ABP2250MD, ABP2400MD, ABP2600MD, ABP2006MG, ABP2010MG, + ABP2016MG, ABP2025MG, ABP2040MG, ABP2060MG, ABP2100MG, ABP2160MG, + ABP2250MG, ABP2400MG, ABP2600MG, ABP2001ND, ABP2002ND, ABP2004ND, + ABP2005ND, ABP2010ND, ABP2020ND, ABP2030ND, ABP2002NG, ABP2004NG, + ABP2005NG, ABP2010NG, ABP2020NG, ABP2030NG, ABP2015PA, ABP2030PA, + ABP2060PA, ABP2100PA, ABP2150PA, ABP2175PA, ABP2001PD, ABP2005PD, + ABP2015PD, ABP2030PD, ABP2060PD, ABP2001PG, ABP2005PG, ABP2015PG, + ABP2030PG, ABP2060PG, ABP2100PG, ABP2150PG, ABP2175PG, +}; + +static const char * const abp2_triplet_variants[] =3D { + [ABP2001BA] =3D "001BA", [ABP21_6BA] =3D "1.6BA", [ABP22_5BA] =3D "2.5BA", + [ABP2004BA] =3D "004BA", [ABP2006BA] =3D "006BA", [ABP2008BA] =3D "008BA", + [ABP2010BA] =3D "010BA", [ABP2012BA] =3D "012BA", [ABP2001BD] =3D "001BD", + [ABP21_6BD] =3D "1.6BD", [ABP22_5BD] =3D "2.5BD", [ABP2004BD] =3D "004BD", + [ABP2001BG] =3D "001BG", [ABP21_6BG] =3D "1.6BG", [ABP22_5BG] =3D "2.5BG", + [ABP2004BG] =3D "004BG", [ABP2006BG] =3D "006BG", [ABP2008BG] =3D "008BG", + [ABP2010BG] =3D "010BG", [ABP2012BG] =3D "012BG", [ABP2001GG] =3D "001GG", + [ABP21_2GG] =3D "1.2GG", [ABP2100KA] =3D "100KA", [ABP2160KA] =3D "160KA", + [ABP2250KA] =3D "250KA", [ABP2001KD] =3D "001KD", [ABP21_6KD] =3D "1.6KD", + [ABP22_5KD] =3D "2.5KD", [ABP2004KD] =3D "004KD", [ABP2006KD] =3D "006KD", + [ABP2010KD] =3D "010KD", [ABP2016KD] =3D "016KD", [ABP2025KD] =3D "025KD", + [ABP2040KD] =3D "040KD", [ABP2060KD] =3D "060KD", [ABP2100KD] =3D "100KD", + [ABP2160KD] =3D "160KD", [ABP2250KD] =3D "250KD", [ABP2400KD] =3D "400KD", + [ABP2001KG] =3D "001KG", [ABP21_6KG] =3D "1.6KG", [ABP22_5KG] =3D "2.5KG", + [ABP2004KG] =3D "004KG", [ABP2006KG] =3D "006KG", [ABP2010KG] =3D "010KG", + [ABP2016KG] =3D "016KG", [ABP2025KG] =3D "025KG", [ABP2040KG] =3D "040KG", + [ABP2060KG] =3D "060KG", [ABP2100KG] =3D "100KG", [ABP2160KG] =3D "160KG", + [ABP2250KG] =3D "250KG", [ABP2400KG] =3D "400KG", [ABP2600KG] =3D "600KG", + [ABP2800KG] =3D "800KG", [ABP2250LD] =3D "250LD", [ABP2600LD] =3D "600LD", + [ABP2600LG] =3D "600LG", [ABP22_5MD] =3D "2.5MD", [ABP2006MD] =3D "006MD", + [ABP2010MD] =3D "010MD", [ABP2016MD] =3D "016MD", [ABP2025MD] =3D "025MD", + [ABP2040MD] =3D "040MD", [ABP2060MD] =3D "060MD", [ABP2100MD] =3D "100MD", + [ABP2160MD] =3D "160MD", [ABP2250MD] =3D "250MD", [ABP2400MD] =3D "400MD", + [ABP2600MD] =3D "600MD", [ABP2006MG] =3D "006MG", [ABP2010MG] =3D "010MG", + [ABP2016MG] =3D "016MG", [ABP2025MG] =3D "025MG", [ABP2040MG] =3D "040MG", + [ABP2060MG] =3D "060MG", [ABP2100MG] =3D "100MG", [ABP2160MG] =3D "160MG", + [ABP2250MG] =3D "250MG", [ABP2400MG] =3D "400MG", [ABP2600MG] =3D "600MG", + [ABP2001ND] =3D "001ND", [ABP2002ND] =3D "002ND", [ABP2004ND] =3D "004ND", + [ABP2005ND] =3D "005ND", [ABP2010ND] =3D "010ND", [ABP2020ND] =3D "020ND", + [ABP2030ND] =3D "030ND", [ABP2002NG] =3D "002NG", [ABP2004NG] =3D "004NG", + [ABP2005NG] =3D "005NG", [ABP2010NG] =3D "010NG", [ABP2020NG] =3D "020NG", + [ABP2030NG] =3D "030NG", [ABP2015PA] =3D "015PA", [ABP2030PA] =3D "030PA", + [ABP2060PA] =3D "060PA", [ABP2100PA] =3D "100PA", [ABP2150PA] =3D "150PA", + [ABP2175PA] =3D "175PA", [ABP2001PD] =3D "001PD", [ABP2005PD] =3D "005PD", + [ABP2015PD] =3D "015PD", [ABP2030PD] =3D "030PD", [ABP2060PD] =3D "060PD", + [ABP2001PG] =3D "001PG", [ABP2005PG] =3D "005PG", [ABP2015PG] =3D "015PG", + [ABP2030PG] =3D "030PG", [ABP2060PG] =3D "060PG", [ABP2100PG] =3D "100PG", + [ABP2150PG] =3D "150PG", [ABP2175PG] =3D "175PG", +}; + +/** + * struct abp2_range_config - list of pressure ranges based on nomenclature + * @pmin: lowest pressure that can be measured + * @pmax: highest pressure that can be measured + */ +struct abp2_range_config { + s32 pmin; + s32 pmax; +}; + +/* All min max limits have been converted to pascals */ +static const struct abp2_range_config abp2_range_config[] =3D { + [ABP2001BA] =3D { .pmin =3D 0, .pmax =3D 100000 }, + [ABP21_6BA] =3D { .pmin =3D 0, .pmax =3D 160000 }, + [ABP22_5BA] =3D { .pmin =3D 0, .pmax =3D 250000 }, + [ABP2004BA] =3D { .pmin =3D 0, .pmax =3D 400000 }, + [ABP2006BA] =3D { .pmin =3D 0, .pmax =3D 600000 }, + [ABP2008BA] =3D { .pmin =3D 0, .pmax =3D 800000 }, + [ABP2010BA] =3D { .pmin =3D 0, .pmax =3D 1000000 }, + [ABP2012BA] =3D { .pmin =3D 0, .pmax =3D 1200000 }, + [ABP2001BD] =3D { .pmin =3D -100000, .pmax =3D 100000 }, + [ABP21_6BD] =3D { .pmin =3D -160000, .pmax =3D 160000 }, + [ABP22_5BD] =3D { .pmin =3D -250000, .pmax =3D 250000 }, + [ABP2004BD] =3D { .pmin =3D -400000, .pmax =3D 400000 }, + [ABP2001BG] =3D { .pmin =3D 0, .pmax =3D 100000 }, + [ABP21_6BG] =3D { .pmin =3D 0, .pmax =3D 160000 }, + [ABP22_5BG] =3D { .pmin =3D 0, .pmax =3D 250000 }, + [ABP2004BG] =3D { .pmin =3D 0, .pmax =3D 400000 }, + [ABP2006BG] =3D { .pmin =3D 0, .pmax =3D 600000 }, + [ABP2008BG] =3D { .pmin =3D 0, .pmax =3D 800000 }, + [ABP2010BG] =3D { .pmin =3D 0, .pmax =3D 1000000 }, + [ABP2012BG] =3D { .pmin =3D 0, .pmax =3D 1200000 }, + [ABP2001GG] =3D { .pmin =3D 0, .pmax =3D 1000000 }, + [ABP21_2GG] =3D { .pmin =3D 0, .pmax =3D 1200000 }, + [ABP2100KA] =3D { .pmin =3D 0, .pmax =3D 100000 }, + [ABP2160KA] =3D { .pmin =3D 0, .pmax =3D 160000 }, + [ABP2250KA] =3D { .pmin =3D 0, .pmax =3D 250000 }, + [ABP2001KD] =3D { .pmin =3D -1000, .pmax =3D 1000 }, + [ABP21_6KD] =3D { .pmin =3D -1600, .pmax =3D 1600 }, + [ABP22_5KD] =3D { .pmin =3D -2500, .pmax =3D 2500 }, + [ABP2004KD] =3D { .pmin =3D -4000, .pmax =3D 4000 }, + [ABP2006KD] =3D { .pmin =3D -6000, .pmax =3D 6000 }, + [ABP2010KD] =3D { .pmin =3D -10000, .pmax =3D 10000 }, + [ABP2016KD] =3D { .pmin =3D -16000, .pmax =3D 16000 }, + [ABP2025KD] =3D { .pmin =3D -25000, .pmax =3D 25000 }, + [ABP2040KD] =3D { .pmin =3D -40000, .pmax =3D 40000 }, + [ABP2060KD] =3D { .pmin =3D -60000, .pmax =3D 60000 }, + [ABP2100KD] =3D { .pmin =3D -100000, .pmax =3D 100000 }, + [ABP2160KD] =3D { .pmin =3D -160000, .pmax =3D 160000 }, + [ABP2250KD] =3D { .pmin =3D -250000, .pmax =3D 250000 }, + [ABP2400KD] =3D { .pmin =3D -400000, .pmax =3D 400000 }, + [ABP2001KG] =3D { .pmin =3D 0, .pmax =3D 1000 }, + [ABP21_6KG] =3D { .pmin =3D 0, .pmax =3D 1600 }, + [ABP22_5KG] =3D { .pmin =3D 0, .pmax =3D 2500 }, + [ABP2004KG] =3D { .pmin =3D 0, .pmax =3D 4000 }, + [ABP2006KG] =3D { .pmin =3D 0, .pmax =3D 6000 }, + [ABP2010KG] =3D { .pmin =3D 0, .pmax =3D 10000 }, + [ABP2016KG] =3D { .pmin =3D 0, .pmax =3D 16000 }, + [ABP2025KG] =3D { .pmin =3D 0, .pmax =3D 25000 }, + [ABP2040KG] =3D { .pmin =3D 0, .pmax =3D 40000 }, + [ABP2060KG] =3D { .pmin =3D 0, .pmax =3D 60000 }, + [ABP2100KG] =3D { .pmin =3D 0, .pmax =3D 100000 }, + [ABP2160KG] =3D { .pmin =3D 0, .pmax =3D 160000 }, + [ABP2250KG] =3D { .pmin =3D 0, .pmax =3D 250000 }, + [ABP2400KG] =3D { .pmin =3D 0, .pmax =3D 400000 }, + [ABP2600KG] =3D { .pmin =3D 0, .pmax =3D 600000 }, + [ABP2800KG] =3D { .pmin =3D 0, .pmax =3D 800000 }, + [ABP2250LD] =3D { .pmin =3D -250, .pmax =3D 250 }, + [ABP2600LD] =3D { .pmin =3D -600, .pmax =3D 600 }, + [ABP2600LG] =3D { .pmin =3D 0, .pmax =3D 600 }, + [ABP22_5MD] =3D { .pmin =3D -250, .pmax =3D 250 }, + [ABP2006MD] =3D { .pmin =3D -600, .pmax =3D 600 }, + [ABP2010MD] =3D { .pmin =3D -1000, .pmax =3D 1000 }, + [ABP2016MD] =3D { .pmin =3D -1600, .pmax =3D 1600 }, + [ABP2025MD] =3D { .pmin =3D -2500, .pmax =3D 2500 }, + [ABP2040MD] =3D { .pmin =3D -4000, .pmax =3D 4000 }, + [ABP2060MD] =3D { .pmin =3D -6000, .pmax =3D 6000 }, + [ABP2100MD] =3D { .pmin =3D -10000, .pmax =3D 10000 }, + [ABP2160MD] =3D { .pmin =3D -16000, .pmax =3D 16000 }, + [ABP2250MD] =3D { .pmin =3D -25000, .pmax =3D 25000 }, + [ABP2400MD] =3D { .pmin =3D -40000, .pmax =3D 40000 }, + [ABP2600MD] =3D { .pmin =3D -60000, .pmax =3D 60000 }, + [ABP2006MG] =3D { .pmin =3D 0, .pmax =3D 600 }, + [ABP2010MG] =3D { .pmin =3D 0, .pmax =3D 1000 }, + [ABP2016MG] =3D { .pmin =3D 0, .pmax =3D 1600 }, + [ABP2025MG] =3D { .pmin =3D 0, .pmax =3D 2500 }, + [ABP2040MG] =3D { .pmin =3D 0, .pmax =3D 4000 }, + [ABP2060MG] =3D { .pmin =3D 0, .pmax =3D 6000 }, + [ABP2100MG] =3D { .pmin =3D 0, .pmax =3D 10000 }, + [ABP2160MG] =3D { .pmin =3D 0, .pmax =3D 16000 }, + [ABP2250MG] =3D { .pmin =3D 0, .pmax =3D 25000 }, + [ABP2400MG] =3D { .pmin =3D 0, .pmax =3D 40000 }, + [ABP2600MG] =3D { .pmin =3D 0, .pmax =3D 60000 }, + [ABP2001ND] =3D { .pmin =3D -249, .pmax =3D 249 }, + [ABP2002ND] =3D { .pmin =3D -498, .pmax =3D 498 }, + [ABP2004ND] =3D { .pmin =3D -996, .pmax =3D 996 }, + [ABP2005ND] =3D { .pmin =3D -1245, .pmax =3D 1245 }, + [ABP2010ND] =3D { .pmin =3D -2491, .pmax =3D 2491 }, + [ABP2020ND] =3D { .pmin =3D -4982, .pmax =3D 4982 }, + [ABP2030ND] =3D { .pmin =3D -7473, .pmax =3D 7473 }, + [ABP2002NG] =3D { .pmin =3D 0, .pmax =3D 498 }, + [ABP2004NG] =3D { .pmin =3D 0, .pmax =3D 996 }, + [ABP2005NG] =3D { .pmin =3D 0, .pmax =3D 1245 }, + [ABP2010NG] =3D { .pmin =3D 0, .pmax =3D 2491 }, + [ABP2020NG] =3D { .pmin =3D 0, .pmax =3D 4982 }, + [ABP2030NG] =3D { .pmin =3D 0, .pmax =3D 7473 }, + [ABP2015PA] =3D { .pmin =3D 0, .pmax =3D 103421 }, + [ABP2030PA] =3D { .pmin =3D 0, .pmax =3D 206843 }, + [ABP2060PA] =3D { .pmin =3D 0, .pmax =3D 413685 }, + [ABP2100PA] =3D { .pmin =3D 0, .pmax =3D 689476 }, + [ABP2150PA] =3D { .pmin =3D 0, .pmax =3D 1034214 }, + [ABP2175PA] =3D { .pmin =3D 0, .pmax =3D 1206583 }, + [ABP2001PD] =3D { .pmin =3D -6895, .pmax =3D 6895 }, + [ABP2005PD] =3D { .pmin =3D -34474, .pmax =3D 34474 }, + [ABP2015PD] =3D { .pmin =3D -103421, .pmax =3D 103421 }, + [ABP2030PD] =3D { .pmin =3D -206843, .pmax =3D 206843 }, + [ABP2060PD] =3D { .pmin =3D -413685, .pmax =3D 413685 }, + [ABP2001PG] =3D { .pmin =3D 0, .pmax =3D 6895 }, + [ABP2005PG] =3D { .pmin =3D 0, .pmax =3D 34474 }, + [ABP2015PG] =3D { .pmin =3D 0, .pmax =3D 103421 }, + [ABP2030PG] =3D { .pmin =3D 0, .pmax =3D 206843 }, + [ABP2060PG] =3D { .pmin =3D 0, .pmax =3D 413685 }, + [ABP2100PG] =3D { .pmin =3D 0, .pmax =3D 689476 }, + [ABP2150PG] =3D { .pmin =3D 0, .pmax =3D 1034214 }, + [ABP2175PG] =3D { .pmin =3D 0, .pmax =3D 1206583 }, +}; + +static_assert(ARRAY_SIZE(abp2_triplet_variants) =3D=3D ARRAY_SIZE(abp2_ran= ge_config)); + +static int abp2_get_measurement(struct abp2_data *data) +{ + struct device *dev =3D data->dev; + int ret; + + reinit_completion(&data->completion); + + ret =3D data->ops->write(data, ABP2_CMD_SYNC, ABP2_PKT_SYNC_LEN); + if (ret < 0) + return ret; + + if (data->irq > 0) { + ret =3D wait_for_completion_timeout(&data->completion, HZ); + if (!ret) { + dev_err(dev, "timeout waiting for EOC interrupt\n"); + return -ETIMEDOUT; + } + } else { + fsleep(5 * USEC_PER_MSEC); + } + + memset(data->rx_buf, 0, sizeof(data->rx_buf)); + ret =3D data->ops->read(data, ABP2_CMD_NOP, ABP2_PKT_NOP_LEN); + if (ret < 0) + return ret; + + /* + * Status byte flags + * bit7 SANITY_CHK - must always be 0 + * bit6 ABP2_ST_POWER - 1 if device is powered + * bit5 ABP2_ST_BUSY - 1 if device has no new conversion ready + * bit4 SANITY_CHK - must always be 0 + * bit3 SANITY_CHK - must always be 0 + * bit2 MEMORY_ERR - 1 if integrity test has failed + * bit1 SANITY_CHK - must always be 0 + * bit0 MATH_ERR - 1 during internal math saturation error + */ + + if (data->rx_buf[0] =3D=3D (ABP2_ST_POWER | ABP2_ST_BUSY)) + return -EBUSY; + + /* + * The ABP2 sensor series seem to have a noticeable latch-up sensitivity. + * A partial latch-up condition manifests as either + * - output of invalid status bytes + * - zeroed out conversions (despite a normal status byte) + * - the MOSI line being pulled low randomly in sync with the SCLK + * signal (visible during the ABP2_CMD_NOP command). + * https://e2e.ti.com/support/processors-group/processors/f/processors-fo= rum/1588325/am3358-spi-tx-data-corruption + */ + + if (data->rx_buf[0] !=3D ABP2_ST_POWER) { + dev_err(data->dev, + "unexpected status byte 0x%02x\n", data->rx_buf[0]); + return -EIO; + } + + return 0; +} + +static irqreturn_t abp2_eoc_handler(int irq, void *private) +{ + struct abp2_data *data =3D private; + + complete(&data->completion); + + return IRQ_HANDLED; +} + +static irqreturn_t abp2_trigger_handler(int irq, void *private) +{ + int ret; + struct iio_poll_func *pf =3D private; + struct iio_dev *indio_dev =3D pf->indio_dev; + struct abp2_data *data =3D iio_priv(indio_dev); + + ret =3D abp2_get_measurement(data); + if (ret < 0) + goto out_notify_done; + + data->scan.chan[0] =3D get_unaligned_be24(&data->rx_buf[1]); + data->scan.chan[1] =3D get_unaligned_be24(&data->rx_buf[4]); + + iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan), + iio_get_time_ns(indio_dev)); + +out_notify_done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +/* + * IIO ABI expects + * value =3D (conv + offset) * scale + * + * temp[C] =3D conv * a + b + * where a =3D 200/16777215; b =3D -50 + * + * temp[C] =3D (conv + (b/a)) * a * (1000) + * =3D> + * scale =3D a * 1000 =3D .0000119209296 * 1000 =3D .01192092966562 + * offset =3D b/a =3D -50 * 16777215 / 200 =3D -4194303.75 + * + * pressure =3D (conv - Omin) * Q + Pmin =3D + * ((conv - Omin) + Pmin/Q) * Q + * =3D> + * scale =3D Q =3D (Pmax - Pmin) / (Omax - Omin) + * offset =3D Pmin/Q - Omin =3D Pmin * (Omax - Omin) / (Pmax - Pmin) - Om= in + */ +static int abp2_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int *val, + int *val2, long mask) +{ + struct abp2_data *data =3D iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret =3D abp2_get_measurement(data); + if (ret < 0) + return ret; + + switch (channel->type) { + case IIO_PRESSURE: + *val =3D get_unaligned_be24(&data->rx_buf[1]); + return IIO_VAL_INT; + case IIO_TEMP: + *val =3D get_unaligned_be24(&data->rx_buf[4]); + return IIO_VAL_INT; + default: + return -EINVAL; + } + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + switch (channel->type) { + case IIO_TEMP: + *val =3D 0; + *val2 =3D 11920929; + return IIO_VAL_INT_PLUS_NANO; + case IIO_PRESSURE: + *val =3D data->p_scale; + *val2 =3D data->p_scale_dec; + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } + + case IIO_CHAN_INFO_OFFSET: + switch (channel->type) { + case IIO_TEMP: + *val =3D -4194304; + return IIO_VAL_INT; + case IIO_PRESSURE: + *val =3D data->p_offset; + return IIO_VAL_INT; + default: + return -EINVAL; + } + + default: + return -EINVAL; + } +} + +static const struct iio_info abp2_info =3D { + .read_raw =3D &abp2_read_raw, +}; + +static const unsigned long abp2_scan_masks[] =3D {0x3, 0}; + +static const struct iio_chan_spec abp2_channels[] =3D { + { + .type =3D IIO_PRESSURE, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .scan_index =3D 0, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 24, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + }, + { + .type =3D IIO_TEMP, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .scan_index =3D 1, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 24, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + }, + IIO_CHAN_SOFT_TIMESTAMP(2), +}; + +int abp2_common_probe(struct device *dev, const struct abp2_ops *ops, int = irq) +{ + int ret; + struct abp2_data *data; + struct iio_dev *indio_dev; + const char *triplet; + s32 tmp; + s64 odelta, pdelta; + + indio_dev =3D devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data =3D iio_priv(indio_dev); + data->dev =3D dev; + data->ops =3D ops; + data->irq =3D irq; + + init_completion(&data->completion); + + indio_dev->name =3D "abp2030pa"; + indio_dev->info =3D &abp2_info; + indio_dev->channels =3D abp2_channels; + indio_dev->num_channels =3D ARRAY_SIZE(abp2_channels); + indio_dev->modes =3D INDIO_DIRECT_MODE; + indio_dev->available_scan_masks =3D abp2_scan_masks; + + ret =3D devm_regulator_get_enable(dev, "vdd"); + if (ret) + return dev_err_probe(dev, ret, "can't get and enable vdd supply\n"); + + ret =3D device_property_read_string(dev, "honeywell,pressure-triplet", + &triplet); + if (ret) { + ret =3D device_property_read_u32(dev, "honeywell,pmin-pascal", + &data->pmin); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmin-pascal could not be read\n"); + + ret =3D device_property_read_u32(dev, "honeywell,pmax-pascal", + &data->pmax); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmax-pascal could not be read\n"); + } else { + ret =3D device_property_match_property_string(dev, + "honeywell,pressure-triplet", + abp2_triplet_variants, + ARRAY_SIZE(abp2_triplet_variants)); + if (ret < 0) + return dev_err_probe(dev, -EINVAL, "honeywell,pressure-triplet is inval= id\n"); + + data->pmin =3D abp2_range_config[ret].pmin; + data->pmax =3D abp2_range_config[ret].pmax; + } + + if (data->pmin >=3D data->pmax) + return dev_err_probe(dev, -EINVAL, "pressure limits are invalid\n"); + + data->outmin =3D abp2_func_spec[data->function].output_min; + data->outmax =3D abp2_func_spec[data->function].output_max; + + odelta =3D data->outmax - data->outmin; + pdelta =3D data->pmax - data->pmin; + + data->p_scale =3D div_s64_rem(div_s64(pdelta * NANO, odelta), NANO, &tmp); + data->p_scale_dec =3D tmp; + + data->p_offset =3D div_s64(odelta * data->pmin, pdelta) - data->outmin; + + if (data->irq > 0) { + ret =3D devm_request_irq(dev, irq, abp2_eoc_handler, IRQF_ONESHOT, + dev_name(dev), data); + if (ret) + return dev_err_probe(dev, ret, "request irq %d failed\n", data->irq); + } + + ret =3D devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + abp2_trigger_handler, NULL); + if (ret) + return dev_err_probe(dev, ret, "iio triggered buffer setup failed\n"); + + ret =3D devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "unable to register iio device\n"); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(abp2_common_probe, "IIO_HONEYWELL_ABP2030PA"); + +MODULE_AUTHOR("Petre Rodan "); +MODULE_DESCRIPTION("Honeywell ABP2 pressure sensor core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/pressure/abp2030pa.h b/drivers/iio/pressure/abp203= 0pa.h new file mode 100644 index 000000000000..57e5ed784686 --- /dev/null +++ b/drivers/iio/pressure/abp2030pa.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + */ + +#ifndef _ABP2030PA_H +#define _ABP2030PA_H + +#include +#include + +#include + +#define ABP2_MEASUREMENT_RD_SIZE 7 + +struct device; + +struct abp2_data; +struct abp2_ops; + +enum abp2_func_id { + ABP2_FUNCTION_A, +}; + +/** + * struct abp2_data + * @dev: current device structure + * @ops: pointers for bus specific read and write functions + * @pmin: minimal pressure in pascal + * @pmax: maximal pressure in pascal + * @outmin: minimum raw pressure in counts (based on transfer function) + * @outmax: maximum raw pressure in counts (based on transfer function) + * @function: transfer function + * @p_scale: pressure scale + * @p_scale_dec: pressure scale, decimal number + * @p_offset: pressure offset + * @irq: end of conversion - applies only to the i2c sensor + * @completion: handshake from irq to read + * @scan: channel values for buffered mode + * @tx_buf: transmit buffer used during the SPI communication + * @rx_buf: raw data provided by sensor + */ +struct abp2_data { + struct device *dev; + const struct abp2_ops *ops; + s32 pmin; + s32 pmax; + u32 outmin; + u32 outmax; + enum abp2_func_id function; + int p_scale; + int p_scale_dec; + int p_offset; + int irq; + struct completion completion; + struct { + u32 chan[2]; + aligned_s64 timestamp; + } scan; + u8 rx_buf[ABP2_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 tx_buf[ABP2_MEASUREMENT_RD_SIZE]; +}; + +struct abp2_ops { + int (*read)(struct abp2_data *data, u8 cmd, u8 nbytes); + int (*write)(struct abp2_data *data, u8 cmd, u8 nbytes); +}; + +int abp2_common_probe(struct device *dev, const struct abp2_ops *ops, int = irq); + +#endif diff --git a/drivers/iio/pressure/abp2030pa_i2c.c b/drivers/iio/pressure/ab= p2030pa_i2c.c new file mode 100644 index 000000000000..9f1c1c8a9afb --- /dev/null +++ b/drivers/iio/pressure/abp2030pa_i2c.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + */ + +#include +#include +#include +#include +#include +#include + +#include "abp2030pa.h" + +static int abp2_i2c_read(struct abp2_data *data, u8 unused, u8 nbytes) +{ + struct i2c_client *client =3D to_i2c_client(data->dev); + int ret; + + if (nbytes > ABP2_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + ret =3D i2c_master_recv(client, data->rx_buf, nbytes); + if (ret < 0) + return ret; + if (ret !=3D nbytes) + return -EIO; + + return 0; +} + +static int abp2_i2c_write(struct abp2_data *data, u8 cmd, u8 nbytes) +{ + struct i2c_client *client =3D to_i2c_client(data->dev); + int ret; + + if (nbytes > ABP2_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + data->tx_buf[0] =3D cmd; + ret =3D i2c_master_send(client, data->tx_buf, nbytes); + if (ret < 0) + return ret; + if (ret !=3D nbytes) + return -EIO; + + return 0; +} + +static const struct abp2_ops abp2_i2c_ops =3D { + .read =3D abp2_i2c_read, + .write =3D abp2_i2c_write, +}; + +static int abp2_i2c_probe(struct i2c_client *client) +{ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EOPNOTSUPP; + + return abp2_common_probe(&client->dev, &abp2_i2c_ops, client->irq); +} + +static const struct of_device_id abp2_i2c_match[] =3D { + { .compatible =3D "honeywell,abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(of, abp2_i2c_match); + +static const struct i2c_device_id abp2_i2c_id[] =3D { + { "abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, abp2_i2c_id); + +static struct i2c_driver abp2_i2c_driver =3D { + .driver =3D { + .name =3D "abp2030pa", + .of_match_table =3D abp2_i2c_match, + }, + .probe =3D abp2_i2c_probe, + .id_table =3D abp2_i2c_id, +}; +module_i2c_driver(abp2_i2c_driver); + +MODULE_AUTHOR("Petre Rodan "); +MODULE_DESCRIPTION("Honeywell ABP2 pressure sensor i2c driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_HONEYWELL_ABP2030PA"); diff --git a/drivers/iio/pressure/abp2030pa_spi.c b/drivers/iio/pressure/ab= p2030pa_spi.c new file mode 100644 index 000000000000..eaea9a3ebf11 --- /dev/null +++ b/drivers/iio/pressure/abp2030pa_spi.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + */ + +#include +#include +#include +#include +#include + +#include "abp2030pa.h" + +static int abp2_spi_xfer(struct abp2_data *data, u8 cmd, u8 nbytes) +{ + struct spi_device *spi =3D to_spi_device(data->dev); + struct spi_transfer xfer =3D { }; + + if (nbytes > ABP2_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + data->tx_buf[0] =3D cmd; + xfer.tx_buf =3D data->tx_buf; + xfer.rx_buf =3D data->rx_buf; + xfer.len =3D nbytes; + + return spi_sync_transfer(spi, &xfer, 1); +} + +static const struct abp2_ops abp2_spi_ops =3D { + .read =3D abp2_spi_xfer, + .write =3D abp2_spi_xfer, +}; + +static int abp2_spi_probe(struct spi_device *spi) +{ + return abp2_common_probe(&spi->dev, &abp2_spi_ops, spi->irq); +} + +static const struct of_device_id abp2_spi_match[] =3D { + { .compatible =3D "honeywell,abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(of, abp2_spi_match); + +static const struct spi_device_id abp2_spi_id[] =3D { + { "abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(spi, abp2_spi_id); + +static struct spi_driver abp2_spi_driver =3D { + .driver =3D { + .name =3D "abp2030pa", + .of_match_table =3D abp2_spi_match, + }, + .probe =3D abp2_spi_probe, + .id_table =3D abp2_spi_id, +}; +module_spi_driver(abp2_spi_driver); + +MODULE_AUTHOR("Petre Rodan "); +MODULE_DESCRIPTION("Honeywell ABP2 pressure sensor spi driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_HONEYWELL_ABP2030PA"); --=20 2.51.2