From nobody Sat Jul 25 03:46:04 2026 Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.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 4B24D222565 for ; Sat, 18 Jul 2026 23:54:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784418864; cv=none; b=M/6KFHEMElNJEmkGRCbnIisZAchW4Nkm4n+fzpqapviT7uUiWGcO5i0n5zZxfTd8KVoFYiZZAj3rZBxsP0uhgPS6/SoyQxcGsdcRbCJYrK/9RKIwMMpjecqsUE0oWIdUawk4JBKEKMYUJJqQy2dM3MIzTlNy3ZUWhS2PEsByxXE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784418864; c=relaxed/simple; bh=Co22W2ue9qnRS+lhyRup2U96IUjl/bd6w+Px1tSC3k8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bGB2l208vWoWWbl9ji32yRF5dvwJBXO+OiLiXK5tB5F3KnVynx5KpQJ5Q+ErgszS0GSvRjCw+VE2twnkuub5Mi24PEe3oGYWuioJJIGnB07ChL778wq2ISG9ztlggZhnJuYLZBzUymMcuA2zLdIxCECiMwp9bzdA58GS0NGc+bY= 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=jo7D7VTg; arc=none smtp.client-ip=209.85.208.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="jo7D7VTg" Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-39c953950dfso68047281fa.1 for ; Sat, 18 Jul 2026 16:54:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784418860; x=1785023660; 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:content-type; bh=2q65+DC2r/6Txf0Z94ws30H287DZ50UdVjGH6X0cidQ=; b=jo7D7VTgXaZS+mHrZOcy7J/A7GKhJ7B/meGqpJVuNl+siST7oO40XnsxFrOJhglvtb xWupDSrG3E0UGdfvL1z4ZNx7uAkt+aOk09yeoBZft/rbnRp/xjoL4F2IceAW5wgJrDmg BiW5/IrT6hI93qM3tLNheKo62ftUN7X/P1u2NSfS12tGcLko5U+Xe9pDQxCekXUMFv9p msMTmYurTH9hPLQfGtlX8D3B/Iyd55vXiBg4CNhmxqfqSZDgrzva/n5IOfTjxuRabqX4 BaQCfMGS0q0L002cQrXBYxVpmQlAreoqKGrNZBL1oVv6k4aBuDvchJnXnnQFGIcuTQhv VxBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784418860; x=1785023660; 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:content-type; bh=2q65+DC2r/6Txf0Z94ws30H287DZ50UdVjGH6X0cidQ=; b=JN9oCNivgP7Lg3hcLLArv23hZwp5QPtPfJm3+4QNqsGaFyr2BFbMUr0fLzjJvg+Iq6 YeqAuMlRz5qwiHpYpiiCu3YiMB7oTcOPo2ed+F57TPcn1bp2Ulc8oZGZwoj51f7s+eKP /cqElrGR6TyqmjZGXHsDa8+fBAp69SdmAq5tuaKmEtBHLdI/hP7Fr/UwH48YBXVnwVL1 GVk87vqEvh0VWKlzwmDQj/Vf/Qrk5yYZJ7k1/ziAx92Bw0vn+Fn9KLXfDB84kCp4IAZx iWmwLSWO3yHioPTp+hk1MlZ27OdgSB5NDpTR0sTvt0cXfemXkQEhw6J0eFoszXe10gbX iaiQ== X-Forwarded-Encrypted: i=1; AHgh+RrtjwVk/Wqlw/CnGMtGi4aPgiIs18N4tem7phfVpKcAF3O9avqHVXFfLe9GeHvbBXRpBHq7s88kWcPg5v8=@vger.kernel.org X-Gm-Message-State: AOJu0Yw4uwRQdbcsxXU8XRNzU1PrHpsE62ide3uWkWNtc4n1a8PNT/Pu UlxAu65FmTXUOZ4s1EptHJ1QOFbfzVKFSP3cqPfohFc/vuXpy51JMzWN X-Gm-Gg: AfdE7cnfjEy31V1jtnVCHOfnf+FiLI9YFj0g2VXGAtdq6lDR9DNEocP5t3g6ilCiDqO cNZQ9tKK6bpl+lqsCAGLnRv2YDppqUQdwrsTIhOZ7udfoGBprdHE0dek4yUsLKVn9RgHYO/eLy+ OUcUOR79QOi74z6DtKk2adP+GoeK71BSAtLO+LJSt8Kf42Je1F5NPIZYIAC3DmNCrX/spEw/RmF CgE/qk0v16++NGaHdfbQE8seCDnLFkQxtlNe/SqRPHGszEAIjfYe99HbLLNjXg0a9hhrKuVj33p phqj15gXqOazzRDZHru1G/Tg/PxsieMZIDs5SixXQP7ZhNpNoB2NF3lZdYtphIemeoYP2ljJM5n /f9cue9je16JSinDsUtERKN4OF0sar3ex3q6h/PHoIY4DUgbOXJEbszhC/8s5AS4O7cVdcpRjl2 02TcFAa9FmQ2zZkffyTLKkqjQDhNdb8MOAFiM1mMweUNzj52fw3eWE09ng1uYUDdd5HipNiYBJp w== X-Received: by 2002:a2e:a542:0:b0:39c:84cb:ca79 with SMTP id 38308e7fff4ca-39eb289dae6mr18920081fa.40.1784418860007; Sat, 18 Jul 2026 16:54:20 -0700 (PDT) Received: from yantra.. (dsl-trebng21-58c187-236.dhcp.inet.fi. [88.193.135.236]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-39eb4e3371dsm7674481fa.1.2026.07.18.16.54.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Jul 2026 16:54:18 -0700 (PDT) From: Rupesh Majhi To: David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Jonathan Cameron , Petre Rodan , Marcelo Schmitt , Rupesh Majhi , Akhilesh Patil , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Jonathan Cameron , Eddie James Subject: [PATCH v3] iio: pressure: dps310: add triggered buffer support Date: Sun, 19 Jul 2026 02:51:58 +0300 Message-ID: <20260718235203.73699-1-zoone.rupert@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260718224455.38acd927@jic23-huawei> References: <20260718224455.38acd927@jic23-huawei> 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 triggered buffer support so pressure and temperature can be captured into a buffer instead of only through one-shot sysfs reads. Pressure is a processed value in kPa computed from a non-linear calibration polynomial. To keep full resolution in the buffer without disagreeing with the sysfs unit, add raw and scale attributes for pressure (raw in Pa, scale 1/1000 to kPa), following bme680; the existing processed attribute is kept for ABI compatibility. Temperature is already a full-resolution value in its base unit (millidegrees Celsius) and stays a processed channel. Pressure compensation depends on a temperature reading, so both channels are always captured together. The device already runs in continuous background mode, so no buffer setup ops are needed. Sysfs reads and reconfiguration return -EBUSY while the buffer is enabled, as they share the capture path's raw values and configuration. Signed-off-by: Rupesh Majhi --- Changes in v3: - Rework from just enabling the FIFO into proper IIO triggered buffer support, as suggested by Jonathan. - Buffer the pressure and temperature values; add raw + scale for pressure (bme680-style) so buffered pressure keeps full resolution and stays consistent with the sysfs unit. - Drop the unused FIFO enable/flush/read helpers. v2 was a resend that still contained the v1 FIFO-enable code. Note: this touches dps310_probe() near the separately-sent fix "iio: pressure: dps310: fix NULL pointer deref on ACPI probe". It was generated on a plain base tree, so applying it after that fix needs a trivial 3-way merge/rebase - happy to resend in whatever order or branch you prefer. drivers/iio/pressure/Kconfig | 2 + drivers/iio/pressure/dps310.c | 141 ++++++++++++++++++++++++++++++++-- 2 files changed, 136 insertions(+), 7 deletions(-) diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 838a8340c4c0..cef8b90b9ae7 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -112,6 +112,8 @@ config DPS310 tristate "Infineon DPS310 pressure and temperature sensor" depends on I2C select REGMAP_I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Support for the Infineon DPS310 digital barometric pressure sensor. It can be accessed over I2C bus. diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index f45af72a0554..967a2043550b 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -20,8 +20,11 @@ #include #include =20 +#include #include #include +#include +#include =20 #define DPS310_DEV_NAME "dps310" =20 @@ -90,6 +93,12 @@ struct dps310_data { s32 pressure_raw; s32 temp_raw; bool timeout_recovery_failed; + + /* Buffer to hold a scan; timestamp is naturally aligned */ + struct { + s32 chan[2]; + aligned_s64 timestamp; + } scan __aligned(8); }; =20 static const struct iio_chan_spec dps310_channels[] =3D { @@ -98,15 +107,38 @@ static const struct iio_chan_spec dps310_channels[] = =3D { .info_mask_separate =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_PROCESSED), + .scan_index =3D 0, + .scan_type =3D { + .sign =3D 's', + .realbits =3D 32, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, }, { .type =3D IIO_PRESSURE, .info_mask_separate =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | - BIT(IIO_CHAN_INFO_PROCESSED), + BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .scan_index =3D 1, + .scan_type =3D { + .sign =3D 's', + .realbits =3D 32, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, }, + IIO_CHAN_SOFT_TIMESTAMP(2), }; =20 +/* + * Pressure compensation needs a temperature reading, so the trigger + * handler always captures both channels; keep them enabled together. + */ +static const unsigned long dps310_scan_masks[] =3D { GENMASK(1, 0), 0 }; + /* To be called after checking the COEF_RDY bit in MEAS_CFG */ static int dps310_get_coefs(struct dps310_data *data) { @@ -583,8 +615,14 @@ static int dps310_write_raw(struct iio_dev *iio, int rc; struct dps310_data *data =3D iio_priv(iio); =20 - if (mutex_lock_interruptible(&data->lock)) + /* Don't reconfigure the sensor while a buffered capture is running */ + if (!iio_device_claim_direct(iio)) + return -EBUSY; + + if (mutex_lock_interruptible(&data->lock)) { + iio_device_release_direct(iio); return -EINTR; + } =20 switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: @@ -625,6 +663,7 @@ static int dps310_write_raw(struct iio_dev *iio, } =20 mutex_unlock(&data->lock); + iio_device_release_direct(iio); return rc; } =20 @@ -735,6 +774,23 @@ static int dps310_read_pressure(struct dps310_data *da= ta, int *val, int *val2, *val2 =3D 1000; /* Convert Pa to KPa per IIO ABI */ return IIO_VAL_FRACTIONAL; =20 + case IIO_CHAN_INFO_RAW: + rc =3D dps310_read_pres_raw(data); + if (rc) + return rc; + + rc =3D dps310_calculate_pressure(data, val); + if (rc) + return rc; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + /* Raw pressure is in Pa; scale to kPa per IIO ABI */ + *val =3D 1; + *val2 =3D 1000; + return IIO_VAL_FRACTIONAL; + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: rc =3D dps310_get_pres_precision(data, val); if (rc) @@ -804,12 +860,10 @@ static int dps310_read_temp(struct dps310_data *data,= int *val, int *val2, } } =20 -static int dps310_read_raw(struct iio_dev *iio, - struct iio_chan_spec const *chan, - int *val, int *val2, long mask) +static int dps310_read_channel(struct dps310_data *data, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) { - struct dps310_data *data =3D iio_priv(iio); - switch (chan->type) { case IIO_PRESSURE: return dps310_read_pressure(data, val, val2, mask); @@ -822,6 +876,32 @@ static int dps310_read_raw(struct iio_dev *iio, } } =20 +static int dps310_read_raw(struct iio_dev *iio, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct dps310_data *data =3D iio_priv(iio); + int rc; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: + /* + * Reading a sample uses the same raw values as the buffered + * capture path, so only allow it outside of buffered mode. + */ + if (!iio_device_claim_direct(iio)) + return -EBUSY; + + rc =3D dps310_read_channel(data, chan, val, val2, mask); + iio_device_release_direct(iio); + return rc; + + default: + return dps310_read_channel(data, chan, val, val2, mask); + } +} + static void dps310_reset(void *action_data) { struct dps310_data *data =3D action_data; @@ -843,6 +923,46 @@ static const struct iio_info dps310_info =3D { .write_raw =3D dps310_write_raw, }; =20 +static irqreturn_t dps310_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf =3D p; + struct iio_dev *iio =3D pf->indio_dev; + struct dps310_data *data =3D iio_priv(iio); + int rc, pressure, temp; + + /* + * Don't hold data->lock across these calls: the read helpers take it + * themselves and the mutex is not recursive (dps310_calculate_pressure + * also grabs it with mutex_trylock to refresh the temperature). + */ + rc =3D dps310_read_pres_raw(data); + if (rc) + goto out; + + rc =3D dps310_read_temp_raw(data); + if (rc) + goto out; + + rc =3D dps310_calculate_pressure(data, &pressure); + if (rc) + goto out; + + rc =3D dps310_calculate_temp(data, &temp); + if (rc) + goto out; + + data->scan.chan[0] =3D temp; /* millidegrees Celsius */ + data->scan.chan[1] =3D pressure; /* Pascals */ + + iio_push_to_buffers_with_ts(iio, &data->scan, sizeof(data->scan), + pf->timestamp); + +out: + iio_trigger_notify_done(iio->trig); + + return IRQ_HANDLED; +} + static int dps310_probe(struct i2c_client *client) { const struct i2c_device_id *id =3D i2c_client_get_device_id(client); @@ -863,6 +983,7 @@ static int dps310_probe(struct i2c_client *client) iio->num_channels =3D ARRAY_SIZE(dps310_channels); iio->info =3D &dps310_info; iio->modes =3D INDIO_DIRECT_MODE; + iio->available_scan_masks =3D dps310_scan_masks; =20 data->regmap =3D devm_regmap_init_i2c(client, &dps310_regmap_config); if (IS_ERR(data->regmap)) @@ -877,6 +998,12 @@ static int dps310_probe(struct i2c_client *client) if (rc) return rc; =20 + rc =3D devm_iio_triggered_buffer_setup(&client->dev, iio, + iio_pollfunc_store_time, + dps310_trigger_handler, NULL); + if (rc) + return rc; + rc =3D devm_iio_device_register(&client->dev, iio); if (rc) return rc; --=20 2.43.0