* [RFC PATCH 0/7] iio: add iio backend device type
@ 2023-06-23 14:09 Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 3/7] iio: adc: stm32-dfsdm: manage dfsdm as a channel provider Olivier Moysan
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Olivier Moysan @ 2023-06-23 14:09 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Jonathan Cameron, Lars-Peter Clausen,
Frank Rowand, Liam Girdwood, Mark Brown
Cc: Olivier Moysan, devicetree, linux-stm32, linux-arm-kernel,
linux-kernel, linux-iio
This RFC re-opens an old discussion regarding channel scaling
management in STM32 DFSDM driver [1]
The DFSDM is a peripheral provided by the STM32MP1x SoC family.
One objective is also to prepare the introduction of its successor in
the STM32MP12x SoC family: the MDF (Multi-function Digital Filter).
The MDF driver will have the same requirements as the DFSDM regarding
channel scaling management. So, the solution proposed here will apply
also for the future MDF driver.
[1]
https://patchwork.kernel.org/project/linux-iio/patch/20200204101008.11411-5-olivier.moysan@st.com/
As a short reminder of our previous discussion, the two main options
emerging were the following ones:
- Option1: Use the DFSDM as an hardware accelerator and expose the
scaled channels on SD modulator side.
Drawbak: this solution is leading to an very complex datapath, especially
for scan mode.
- Option2: Introduce a new IIO device type (so-called backend)
Retrieve scaling information from SD modulator scaling to expose a single
IIO device on DFSDM side. This solution is derivated from rcar-gyroadc
example, but with a more standard approach.
This was discussed in
https://lore.kernel.org/lkml/20210919191414.09270f4e@jic23-huawei/
The patchset proposed in this RFC implements option2 (backend) solution.
These patches provide a minimal API implemented as a template.
The intented use of this API is illustrated through the DFSDM channel
scaling support basic implementation.
For sake of simplicity I did not include the related DT binding
in this serie.
Below are some use case examples.
* DFSDM with SD modulator backend:
-------------------------------
This use case corresponds to the example implemented in this RFC.
The channel attributes are retrieved from backend by the dfsdm, and
the resulting scaling is exposed through DFSDM IIO device sysfs
- Single channel:
+-------------+ ch attr +--------+ sysfs (compound scaling)
| sd0 backend | ---------> | dfsdm0 | -------------------------->
+-------------+ +--------+
- Scan mode:
+-------------+ ch attr +-------------+ sysfs (compound scaling)
| sd1 backend | ---------> | dfsdm1 | -------------------------->
+-------------+ +-------------+
^
|
+-------------+ ch attr |
| sd2 backend |--------------+
+-------------+
* Voltage divider in front of an adc:
----------------------------------
By way of example, here is a comparison on scaling management with
a iio-rescale device, and how it could be managed with a backend device.
- iio-rescale implementation
Scaling is exposed both on ADC and iio-rescale IIO devices.
On iio-rescale device we get the compound scaling
+---------------------------+ ch attr +------+ sysfs
| iio-rescale (div) | <--------- | adc0 | ------->
+---------------------------+ +------+
|
| sysfs (compound scaling)
v
- Backend implementation:
Compound scaling is exposed on ADC IIO device.
No scaling exposed on backend device
+---------------+ ch attr +------+ sysfs (compound scaling)
| backend (div) | ---------> | adc0 | -------------------------->
+---------------+ +------+
* Cascaded backends:
-----------------
Backends may be cascaded to allow computation of the whole chain scaling
This is not part of this RFC, but it is identified as a potential
future use case.
+---------------+ attr +-------------+ attr +--------+ sysfs
| backend (div) | ------> | sd0 backend | ------> | dfsdm0 | ------->
+---------------+ +-------------+ +--------+
Olivier Moysan (7):
iio: introduce iio backend device
of: property: add device link support for io-backends
iio: adc: stm32-dfsdm: manage dfsdm as a channel provider
iio: adc: stm32-dfsdm: adopt generic channel bindings
iio: adc: sd_adc_modulator: change to iio backend device
iio: adc: stm32-dfsdm: add scaling support to dfsdm
ARM: dts: stm32: add dfsdm iio suppport
arch/arm/boot/dts/stm32mp157c-ev1.dts | 62 +++++++++
drivers/iio/Makefile | 2 +
drivers/iio/adc/sd_adc_modulator.c | 92 +++++++++++---
drivers/iio/adc/stm32-dfsdm-adc.c | 176 ++++++++++++++++----------
drivers/iio/industrialio-backend.c | 59 +++++++++
drivers/of/property.c | 2 +
include/linux/iio/backend.h | 29 +++++
7 files changed, 336 insertions(+), 86 deletions(-)
create mode 100644 drivers/iio/industrialio-backend.c
create mode 100644 include/linux/iio/backend.h
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC PATCH 3/7] iio: adc: stm32-dfsdm: manage dfsdm as a channel provider
2023-06-23 14:09 [RFC PATCH 0/7] iio: add iio backend device type Olivier Moysan
@ 2023-06-23 14:09 ` Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 4/7] iio: adc: stm32-dfsdm: adopt generic channel bindings Olivier Moysan
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Olivier Moysan @ 2023-06-23 14:09 UTC (permalink / raw)
To: Jonathan Cameron, Lars-Peter Clausen, Maxime Coquelin,
Alexandre Torgue
Cc: Olivier Moysan, linux-iio, linux-stm32, linux-arm-kernel,
linux-kernel
The STM32 is currently implemented as a channels consumer
of the sigma delta modulator.
Change the topology to expose a single IIO device for DFSDM
and remove the IIO device associated to the SD modulator.
Manage the DFSDM as a channel provider to allow this change.
Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
---
drivers/iio/adc/stm32-dfsdm-adc.c | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
index a428bdb567d5..20756d496c52 100644
--- a/drivers/iio/adc/stm32-dfsdm-adc.c
+++ b/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -76,7 +76,6 @@ struct stm32_dfsdm_adc {
/* ADC specific */
unsigned int oversamp;
- struct iio_hw_consumer *hwc;
struct completion completion;
u32 *buffer;
@@ -1006,12 +1005,6 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
/* Reset adc buffer index */
adc->bufi = 0;
- if (adc->hwc) {
- ret = iio_hw_consumer_enable(adc->hwc);
- if (ret < 0)
- return ret;
- }
-
ret = stm32_dfsdm_start_dfsdm(adc->dfsdm);
if (ret < 0)
goto err_stop_hwc;
@@ -1035,8 +1028,6 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
stop_dfsdm:
stm32_dfsdm_stop_dfsdm(adc->dfsdm);
err_stop_hwc:
- if (adc->hwc)
- iio_hw_consumer_disable(adc->hwc);
return ret;
}
@@ -1051,9 +1042,6 @@ static int stm32_dfsdm_predisable(struct iio_dev *indio_dev)
stm32_dfsdm_stop_dfsdm(adc->dfsdm);
- if (adc->hwc)
- iio_hw_consumer_disable(adc->hwc);
-
return 0;
}
@@ -1230,7 +1218,6 @@ static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
- ret = iio_hw_consumer_enable(adc->hwc);
if (ret < 0) {
dev_err(&indio_dev->dev,
"%s: IIO enable failed (channel %d)\n",
@@ -1239,7 +1226,6 @@ static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
return ret;
}
ret = stm32_dfsdm_single_conv(indio_dev, chan, val);
- iio_hw_consumer_disable(adc->hwc);
if (ret < 0) {
dev_err(&indio_dev->dev,
"%s: Conversion failed (channel %d)\n",
@@ -1449,11 +1435,6 @@ static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev)
return num_ch < 0 ? num_ch : -EINVAL;
}
- /* Bind to SD modulator IIO device */
- adc->hwc = devm_iio_hw_consumer_alloc(&indio_dev->dev);
- if (IS_ERR(adc->hwc))
- return -EPROBE_DEFER;
-
ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch),
GFP_KERNEL);
if (!ch)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH 4/7] iio: adc: stm32-dfsdm: adopt generic channel bindings
2023-06-23 14:09 [RFC PATCH 0/7] iio: add iio backend device type Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 3/7] iio: adc: stm32-dfsdm: manage dfsdm as a channel provider Olivier Moysan
@ 2023-06-23 14:09 ` Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 6/7] iio: adc: stm32-dfsdm: add scaling support to dfsdm Olivier Moysan
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Olivier Moysan @ 2023-06-23 14:09 UTC (permalink / raw)
To: Jonathan Cameron, Lars-Peter Clausen, Maxime Coquelin,
Alexandre Torgue
Cc: Olivier Moysan, linux-iio, linux-stm32, linux-arm-kernel,
linux-kernel
Adopt the generic channel bindings to ease the configuration
of the DFSDM channels as consumers of the SD modulator backend device.
Also adopt unified device property API in the same patch for this RFC.
Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
---
drivers/iio/adc/stm32-dfsdm-adc.c | 93 ++++++++++++++++---------------
1 file changed, 49 insertions(+), 44 deletions(-)
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
index 20756d496c52..2e76497cee51 100644
--- a/drivers/iio/adc/stm32-dfsdm-adc.c
+++ b/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -595,45 +595,35 @@ static int stm32_dfsdm_filter_configure(struct iio_dev *indio_dev,
static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
struct iio_dev *indio_dev,
+ struct fwnode_handle *node,
struct iio_chan_spec *ch)
{
struct stm32_dfsdm_channel *df_ch;
const char *of_str;
- int chan_idx = ch->scan_index;
int ret, val;
- ret = of_property_read_u32_index(indio_dev->dev.of_node,
- "st,adc-channels", chan_idx,
- &ch->channel);
+ ret = fwnode_property_read_u32(node, "reg", &ch->channel);
if (ret < 0) {
- dev_err(&indio_dev->dev,
- " Error parsing 'st,adc-channels' for idx %d\n",
- chan_idx);
+ dev_err(&indio_dev->dev, "Missing channel index %d\n", ret);
return ret;
}
if (ch->channel >= dfsdm->num_chs) {
- dev_err(&indio_dev->dev,
- " Error bad channel number %d (max = %d)\n",
+ dev_err(&indio_dev->dev, " Error bad channel number %d (max = %d)\n",
ch->channel, dfsdm->num_chs);
return -EINVAL;
}
- ret = of_property_read_string_index(indio_dev->dev.of_node,
- "st,adc-channel-names", chan_idx,
- &ch->datasheet_name);
+ ret = fwnode_property_read_string(node, "label", &ch->datasheet_name);
if (ret < 0) {
dev_err(&indio_dev->dev,
- " Error parsing 'st,adc-channel-names' for idx %d\n",
- chan_idx);
+ " Error parsing 'label' for idx %d\n", ch->channel);
return ret;
}
df_ch = &dfsdm->ch_list[ch->channel];
df_ch->id = ch->channel;
- ret = of_property_read_string_index(indio_dev->dev.of_node,
- "st,adc-channel-types", chan_idx,
- &of_str);
+ ret = fwnode_property_read_string(node, "st,adc-channel-types", &of_str);
if (!ret) {
val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_type);
if (val < 0)
@@ -643,9 +633,7 @@ static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
}
df_ch->type = val;
- ret = of_property_read_string_index(indio_dev->dev.of_node,
- "st,adc-channel-clk-src", chan_idx,
- &of_str);
+ ret = fwnode_property_read_string(node, "st,adc-channel-clk-src", &of_str);
if (!ret) {
val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_src);
if (val < 0)
@@ -655,10 +643,8 @@ static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
}
df_ch->src = val;
- ret = of_property_read_u32_index(indio_dev->dev.of_node,
- "st,adc-alt-channel", chan_idx,
- &df_ch->alt_si);
- if (ret < 0)
+ ret = fwnode_property_read_u32(node, "st,adc-alt-channel", &df_ch->alt_si);
+ if (ret != -EINVAL)
df_ch->alt_si = 0;
return 0;
@@ -1353,14 +1339,17 @@ static int stm32_dfsdm_dma_request(struct device *dev,
}
static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
+ struct fwnode_handle *child,
struct iio_chan_spec *ch)
{
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
int ret;
- ret = stm32_dfsdm_channel_parse_of(adc->dfsdm, indio_dev, ch);
- if (ret < 0)
+ ret = stm32_dfsdm_channel_parse_of(adc->dfsdm, indio_dev, child, ch);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "Failed to parse channel %d\n", ch->scan_index);
return ret;
+ }
ch->type = IIO_VOLTAGE;
ch->indexed = 1;
@@ -1386,6 +1375,31 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
&adc->dfsdm->ch_list[ch->channel]);
}
+static int stm32_dfsdm_generic_chan_init(struct iio_dev *indio_dev, struct stm32_dfsdm_adc *adc,
+ struct iio_chan_spec *channels)
+{
+ struct fwnode_handle *child;
+ int chan_idx = 0, ret;
+
+ device_for_each_child_node(&indio_dev->dev, child) {
+ channels[chan_idx].scan_index = chan_idx;
+ ret = stm32_dfsdm_adc_chan_init_one(indio_dev, child, &channels[chan_idx]);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "Channels init failed\n");
+ goto err;
+ }
+
+ chan_idx++;
+ }
+
+ return chan_idx;
+
+err:
+ fwnode_handle_put(child);
+
+ return ret;
+}
+
static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev)
{
struct iio_chan_spec *ch;
@@ -1399,7 +1413,7 @@ static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev)
ch->scan_index = 0;
- ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch);
+ stm32_dfsdm_generic_chan_init(indio_dev, adc, ch);
if (ret < 0) {
dev_err(&indio_dev->dev, "Channels init failed\n");
return ret;
@@ -1421,33 +1435,24 @@ static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev)
struct iio_chan_spec *ch;
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
int num_ch;
- int ret, chan_idx;
+ int ret;
adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING;
ret = stm32_dfsdm_compute_all_osrs(indio_dev, adc->oversamp);
if (ret < 0)
return ret;
- num_ch = of_property_count_u32_elems(indio_dev->dev.of_node,
- "st,adc-channels");
- if (num_ch < 0 || num_ch > adc->dfsdm->num_chs) {
- dev_err(&indio_dev->dev, "Bad st,adc-channels\n");
- return num_ch < 0 ? num_ch : -EINVAL;
- }
+ num_ch = device_get_child_node_count(&indio_dev->dev);
+ if (!num_ch)
+ return -EINVAL;
- ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch),
- GFP_KERNEL);
+ ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch), GFP_KERNEL);
if (!ch)
return -ENOMEM;
- for (chan_idx = 0; chan_idx < num_ch; chan_idx++) {
- ch[chan_idx].scan_index = chan_idx;
- ret = stm32_dfsdm_adc_chan_init_one(indio_dev, &ch[chan_idx]);
- if (ret < 0) {
- dev_err(&indio_dev->dev, "Channels init failed\n");
- return ret;
- }
- }
+ stm32_dfsdm_generic_chan_init(indio_dev, adc, ch);
+ if (ret < 0)
+ return ret;
indio_dev->num_channels = num_ch;
indio_dev->channels = ch;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH 6/7] iio: adc: stm32-dfsdm: add scaling support to dfsdm
2023-06-23 14:09 [RFC PATCH 0/7] iio: add iio backend device type Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 3/7] iio: adc: stm32-dfsdm: manage dfsdm as a channel provider Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 4/7] iio: adc: stm32-dfsdm: adopt generic channel bindings Olivier Moysan
@ 2023-06-23 14:09 ` Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 7/7] ARM: dts: stm32: add dfsdm iio suppport Olivier Moysan
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Olivier Moysan @ 2023-06-23 14:09 UTC (permalink / raw)
To: Jonathan Cameron, Lars-Peter Clausen, Maxime Coquelin,
Alexandre Torgue, Liam Girdwood, Mark Brown
Cc: Olivier Moysan, linux-iio, linux-kernel, linux-stm32,
linux-arm-kernel
Add scaling support to STM32 DFSDM.
Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
---
drivers/iio/adc/sd_adc_modulator.c | 31 ++++++++++++++-
drivers/iio/adc/stm32-dfsdm-adc.c | 64 ++++++++++++++++++++++++++++--
2 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/sd_adc_modulator.c b/drivers/iio/adc/sd_adc_modulator.c
index 61246a52dc79..749c46da9c72 100644
--- a/drivers/iio/adc/sd_adc_modulator.c
+++ b/drivers/iio/adc/sd_adc_modulator.c
@@ -12,15 +12,23 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
struct iio_sd_mod_priv {
+ struct regulator *vref;
+ int vref_mv;
};
static int sd_mod_enable(struct iio_backend *backend)
{
struct iio_sd_mod_priv *priv = backend->priv;
+ int ret;
/* PM resume */
+ ret = regulator_enable(priv->vref);
+
+ ret = regulator_get_voltage(priv->vref);
+ priv->vref_mv = ret / 1000;
return 0;
};
@@ -30,6 +38,7 @@ static int sd_mod_disable(struct iio_backend *backend)
struct iio_sd_mod_priv *priv = backend->priv;
/* PM suspend */
+ regulator_disable(priv->vref);
return 0;
};
@@ -39,7 +48,15 @@ static int sd_mod_read(struct iio_backend *backend, int *val, int *val2, long ma
struct iio_sd_mod_priv *priv = backend->priv;
switch (mask) {
- /* Process channel info */
+ case IIO_CHAN_INFO_SCALE:
+ *val = priv->vref_mv;
+ *val2 = 0;
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_OFFSET:
+ *val = 0;
+ *val2 = 0;
+ return IIO_VAL_INT;
}
return -EINVAL;
@@ -54,12 +71,24 @@ static const struct iio_backend_ops sd_mod_ops = {
static int iio_sd_mod_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct regulator *vref;
struct iio_backend *backend;
struct iio_sd_mod_priv *priv;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ vref = devm_regulator_get_optional(dev, "vref");
+ if (IS_ERR(vref)) {
+ ret = PTR_ERR(vref);
+ if (ret != -ENODEV) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "vref get failed, %d\n", ret);
+ return ret;
+ }
+ }
+ priv->vref = vref;
+
backend = iio_backend_alloc(dev);
backend->priv = priv;
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
index 2e76497cee51..468d72ab079d 100644
--- a/drivers/iio/adc/stm32-dfsdm-adc.c
+++ b/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -9,6 +9,7 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/iio/adc/stm32-dfsdm-adc.h>
+#include <linux/iio/backend.h>
#include <linux/iio/buffer.h>
#include <linux/iio/hw-consumer.h>
#include <linux/iio/sysfs.h>
@@ -76,6 +77,7 @@ struct stm32_dfsdm_adc {
/* ADC specific */
unsigned int oversamp;
+ struct iio_backend **backend;
struct completion completion;
u32 *buffer;
@@ -599,6 +601,8 @@ static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
struct iio_chan_spec *ch)
{
struct stm32_dfsdm_channel *df_ch;
+ struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
+ struct iio_backend *backend;
const char *of_str;
int ret, val;
@@ -647,6 +651,9 @@ static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
if (ret != -EINVAL)
df_ch->alt_si = 0;
+ backend = iio_backend_get(node->dev);
+ adc->backend[df_ch->id] = backend;
+
return 0;
}
@@ -1090,7 +1097,7 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
{
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
long timeout;
- int ret;
+ int ret, idx = chan->scan_index;
reinit_completion(&adc->completion);
@@ -1100,6 +1107,8 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
+ adc->backend[idx]->ops->enable(adc->backend[idx]);
+
ret = regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(1));
if (ret < 0)
@@ -1133,6 +1142,8 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
stm32_dfsdm_process_data(adc, res);
stop_dfsdm:
+ adc->backend[idx]->ops->disable(adc->backend[idx]);
+
stm32_dfsdm_stop_dfsdm(adc->dfsdm);
return ret;
@@ -1197,7 +1208,14 @@ static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
int *val2, long mask)
{
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
- int ret;
+
+ struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
+ struct stm32_dfsdm_filter_osr *flo = &fl->flo[fl->fast];
+ u32 max = flo->max << (flo->lshift - chan->scan_type.shift);
+ int ret, idx = chan->scan_index;
+
+ if (flo->lshift < chan->scan_type.shift)
+ max = flo->max >> (chan->scan_type.shift - flo->lshift);
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -1231,6 +1249,41 @@ static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
*val = adc->sample_freq;
return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ /*
+ * Scale is expressed in mV.
+ * When fast mode is disabled, actual resolution may be lower
+ * than 2^n, where n=realbits-1.
+ * This leads to underestimating input voltage. To
+ * compensate this deviation, the voltage reference can be
+ * corrected with a factor = realbits resolution / actual max
+ */
+ adc->backend[idx]->ops->read_raw(adc->backend[idx], val, val2, mask);
+
+ *val = div_u64((u64)*val * (u64)BIT(DFSDM_DATA_RES - 1), max);
+ *val2 = chan->scan_type.realbits;
+ if (chan->differential)
+ *val *= 2;
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ case IIO_CHAN_INFO_OFFSET:
+ /*
+ * DFSDM output data are in the range [-2^n,2^n-1],
+ * with n=realbits-1.
+ * - Differential modulator:
+ * Offset correspond to SD modulator offset.
+ * - Single ended modulator:
+ * Input is in [0V,Vref] range, where 0V corresponds to -2^n.
+ * Add 2^n to offset. (i.e. middle of input range)
+ * offset = offset(sd) * vref / res(sd) * max / vref.
+ */
+ adc->backend[idx]->ops->read_raw(adc->backend[idx], val, val2, mask);
+
+ *val = div_u64((u64)max * *val, BIT(*val2 - 1));
+ if (chan->differential)
+ *val += max;
+ return IIO_VAL_INT;
}
return -EINVAL;
@@ -1358,7 +1411,10 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
* IIO_CHAN_INFO_RAW: used to compute regular conversion
* IIO_CHAN_INFO_OVERSAMPLING_RATIO: used to set oversampling
*/
- ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+ ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_OFFSET);
+
ch->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
BIT(IIO_CHAN_INFO_SAMP_FREQ);
@@ -1454,6 +1510,8 @@ static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev)
if (ret < 0)
return ret;
+ adc->backend = devm_kzalloc(&indio_dev->dev, sizeof(*adc->backend) * num_ch, GFP_KERNEL);
+
indio_dev->num_channels = num_ch;
indio_dev->channels = ch;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [RFC PATCH 7/7] ARM: dts: stm32: add dfsdm iio suppport
2023-06-23 14:09 [RFC PATCH 0/7] iio: add iio backend device type Olivier Moysan
` (2 preceding siblings ...)
2023-06-23 14:09 ` [RFC PATCH 6/7] iio: adc: stm32-dfsdm: add scaling support to dfsdm Olivier Moysan
@ 2023-06-23 14:09 ` Olivier Moysan
2023-07-02 10:56 ` [RFC PATCH 0/7] iio: add iio backend device type Jonathan Cameron
2023-07-02 11:00 ` Jonathan Cameron
5 siblings, 0 replies; 8+ messages in thread
From: Olivier Moysan @ 2023-06-23 14:09 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue
Cc: Olivier Moysan, devicetree, linux-stm32, linux-arm-kernel,
linux-kernel
This DT is an example of backend iio device use for STM32 DFSDM.
DFSDM filter0 has a single input channel, while filter1 is configured
for scan mode with two input channels.
Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
---
arch/arm/boot/dts/stm32mp157c-ev1.dts | 62 +++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts b/arch/arm/boot/dts/stm32mp157c-ev1.dts
index ba8e9d9a42fa..ebd67a219df2 100644
--- a/arch/arm/boot/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts
@@ -73,6 +73,24 @@ panel_backlight: panel-backlight {
default-on;
status = "okay";
};
+
+ sd_adc0: simple-sd-adc0 {
+ compatible = "sd-modulator";
+ io-backend-cells = <0>;
+ vref-supply = <&v3v3>;
+ };
+
+ sd_adc1: simple-sd-adc1 {
+ compatible = "sd-modulator";
+ io-backend-cells = <0>;
+ vref-supply = <&v3v3>;
+ };
+
+ sd_adc2: simple-sd-adc2 {
+ compatible = "sd-modulator";
+ io-backend-cells = <0>;
+ vref-supply = <&v3v3>;
+ };
};
&cec {
@@ -99,6 +117,50 @@ dcmi_0: endpoint {
};
};
+&dfsdm {
+ spi-max-frequency = <2048000>;
+
+ clocks = <&rcc DFSDM_K>, <&rcc ADFSDM_K>;
+ clock-names = "dfsdm", "audio";
+ status = "disabled";
+
+ dfsdm0: filter@0 {
+ compatible = "st,stm32-dfsdm-adc";
+ st,filter-order = <3>;
+ status = "okay";
+
+ channel@1 {
+ reg = <1>;
+ label = "in1";
+ st,adc-channel-types = "SPI_R";
+ st,adc-channel-clk-src = "CLKOUT";
+ io-backend = <&sd_adc0>;
+ };
+ };
+
+ dfsdm1: filter@1 {
+ compatible = "st,stm32-dfsdm-adc";
+ st,filter-order = <3>;
+ status = "okay";
+
+ channel@2 {
+ reg = <2>;
+ label = "in2";
+ st,adc-channel-types = "SPI_R";
+ st,adc-channel-clk-src = "CLKOUT";
+ io-backend = <&sd_adc1>;
+ };
+
+ channel@3 {
+ reg = <3>;
+ label = "in3";
+ st,adc-channel-types = "SPI_F";
+ st,adc-channel-clk-src = "CLKOUT";
+ io-backend = <&sd_adc2>;
+ };
+ };
+};
+
&dsi {
phy-dsi-supply = <®18>;
status = "okay";
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 0/7] iio: add iio backend device type
2023-06-23 14:09 [RFC PATCH 0/7] iio: add iio backend device type Olivier Moysan
` (3 preceding siblings ...)
2023-06-23 14:09 ` [RFC PATCH 7/7] ARM: dts: stm32: add dfsdm iio suppport Olivier Moysan
@ 2023-07-02 10:56 ` Jonathan Cameron
2023-07-02 11:07 ` Jonathan Cameron
2023-07-02 11:00 ` Jonathan Cameron
5 siblings, 1 reply; 8+ messages in thread
From: Jonathan Cameron @ 2023-07-02 10:56 UTC (permalink / raw)
To: Olivier Moysan
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Jonathan Cameron, Lars-Peter Clausen,
Frank Rowand, Liam Girdwood, Mark Brown, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, linux-iio
On Fri, 23 Jun 2023 16:09:36 +0200
Olivier Moysan <olivier.moysan@foss.st.com> wrote:
> This RFC re-opens an old discussion regarding channel scaling
> management in STM32 DFSDM driver [1]
>
> The DFSDM is a peripheral provided by the STM32MP1x SoC family.
> One objective is also to prepare the introduction of its successor in
> the STM32MP12x SoC family: the MDF (Multi-function Digital Filter).
> The MDF driver will have the same requirements as the DFSDM regarding
> channel scaling management. So, the solution proposed here will apply
> also for the future MDF driver.
>
> [1]
> https://patchwork.kernel.org/project/linux-iio/patch/20200204101008.11411-5-olivier.moysan@st.com/
>
> As a short reminder of our previous discussion, the two main options
> emerging were the following ones:
>
> - Option1: Use the DFSDM as an hardware accelerator and expose the
> scaled channels on SD modulator side.
> Drawbak: this solution is leading to an very complex datapath, especially
> for scan mode.
>
> - Option2: Introduce a new IIO device type (so-called backend)
> Retrieve scaling information from SD modulator scaling to expose a single
> IIO device on DFSDM side. This solution is derivated from rcar-gyroadc
> example, but with a more standard approach.
> This was discussed in
> https://lore.kernel.org/lkml/20210919191414.09270f4e@jic23-huawei/
Naming probably needs a rethink given the actual hardware we are talking about
here is normally called a frontend and so people will be confused...
I'm traveling at the moment, so only going to take a fairly superficial first
look at what you have here.
Jonathan
>
> The patchset proposed in this RFC implements option2 (backend) solution.
> These patches provide a minimal API implemented as a template.
> The intented use of this API is illustrated through the DFSDM channel
> scaling support basic implementation.
>
> For sake of simplicity I did not include the related DT binding
> in this serie.
>
> Below are some use case examples.
>
> * DFSDM with SD modulator backend:
> -------------------------------
> This use case corresponds to the example implemented in this RFC.
> The channel attributes are retrieved from backend by the dfsdm, and
> the resulting scaling is exposed through DFSDM IIO device sysfs
>
> - Single channel:
> +-------------+ ch attr +--------+ sysfs (compound scaling)
> | sd0 backend | ---------> | dfsdm0 | -------------------------->
> +-------------+ +--------+
>
> - Scan mode:
> +-------------+ ch attr +-------------+ sysfs (compound scaling)
> | sd1 backend | ---------> | dfsdm1 | -------------------------->
> +-------------+ +-------------+
> ^
> |
> +-------------+ ch attr |
> | sd2 backend |--------------+
> +-------------+
>
>
> * Voltage divider in front of an adc:
> ----------------------------------
> By way of example, here is a comparison on scaling management with
> a iio-rescale device, and how it could be managed with a backend device.
>
> - iio-rescale implementation
> Scaling is exposed both on ADC and iio-rescale IIO devices.
> On iio-rescale device we get the compound scaling
>
> +---------------------------+ ch attr +------+ sysfs
> | iio-rescale (div) | <--------- | adc0 | ------->
> +---------------------------+ +------+
> |
> | sysfs (compound scaling)
> v
>
> - Backend implementation:
> Compound scaling is exposed on ADC IIO device.
> No scaling exposed on backend device
>
> +---------------+ ch attr +------+ sysfs (compound scaling)
> | backend (div) | ---------> | adc0 | -------------------------->
> +---------------+ +------+
>
>
> * Cascaded backends:
> -----------------
> Backends may be cascaded to allow computation of the whole chain scaling
> This is not part of this RFC, but it is identified as a potential
> future use case.
>
> +---------------+ attr +-------------+ attr +--------+ sysfs
> | backend (div) | ------> | sd0 backend | ------> | dfsdm0 | ------->
> +---------------+ +-------------+ +--------+
>
> Olivier Moysan (7):
> iio: introduce iio backend device
> of: property: add device link support for io-backends
> iio: adc: stm32-dfsdm: manage dfsdm as a channel provider
> iio: adc: stm32-dfsdm: adopt generic channel bindings
> iio: adc: sd_adc_modulator: change to iio backend device
> iio: adc: stm32-dfsdm: add scaling support to dfsdm
> ARM: dts: stm32: add dfsdm iio suppport
>
> arch/arm/boot/dts/stm32mp157c-ev1.dts | 62 +++++++++
> drivers/iio/Makefile | 2 +
> drivers/iio/adc/sd_adc_modulator.c | 92 +++++++++++---
> drivers/iio/adc/stm32-dfsdm-adc.c | 176 ++++++++++++++++----------
> drivers/iio/industrialio-backend.c | 59 +++++++++
> drivers/of/property.c | 2 +
> include/linux/iio/backend.h | 29 +++++
> 7 files changed, 336 insertions(+), 86 deletions(-)
> create mode 100644 drivers/iio/industrialio-backend.c
> create mode 100644 include/linux/iio/backend.h
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 0/7] iio: add iio backend device type
2023-06-23 14:09 [RFC PATCH 0/7] iio: add iio backend device type Olivier Moysan
` (4 preceding siblings ...)
2023-07-02 10:56 ` [RFC PATCH 0/7] iio: add iio backend device type Jonathan Cameron
@ 2023-07-02 11:00 ` Jonathan Cameron
5 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2023-07-02 11:00 UTC (permalink / raw)
To: Olivier Moysan
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Jonathan Cameron, Lars-Peter Clausen,
Frank Rowand, Liam Girdwood, Mark Brown, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, linux-iio
On Fri, 23 Jun 2023 16:09:36 +0200
Olivier Moysan <olivier.moysan@foss.st.com> wrote:
> This RFC re-opens an old discussion regarding channel scaling
> management in STM32 DFSDM driver [1]
>
> The DFSDM is a peripheral provided by the STM32MP1x SoC family.
> One objective is also to prepare the introduction of its successor in
> the STM32MP12x SoC family: the MDF (Multi-function Digital Filter).
> The MDF driver will have the same requirements as the DFSDM regarding
> channel scaling management. So, the solution proposed here will apply
> also for the future MDF driver.
For next version, please make sure all patches go at least to linux-iio@vger.kernel.org
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 0/7] iio: add iio backend device type
2023-07-02 10:56 ` [RFC PATCH 0/7] iio: add iio backend device type Jonathan Cameron
@ 2023-07-02 11:07 ` Jonathan Cameron
0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2023-07-02 11:07 UTC (permalink / raw)
To: Olivier Moysan
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Jonathan Cameron, Lars-Peter Clausen,
Frank Rowand, Liam Girdwood, Mark Brown, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, linux-iio
On Sun, 2 Jul 2023 18:56:18 +0800
Jonathan Cameron <Jonathan.Cameron@Huawei.com> wrote:
> On Fri, 23 Jun 2023 16:09:36 +0200
> Olivier Moysan <olivier.moysan@foss.st.com> wrote:
>
> > This RFC re-opens an old discussion regarding channel scaling
> > management in STM32 DFSDM driver [1]
> >
> > The DFSDM is a peripheral provided by the STM32MP1x SoC family.
> > One objective is also to prepare the introduction of its successor in
> > the STM32MP12x SoC family: the MDF (Multi-function Digital Filter).
> > The MDF driver will have the same requirements as the DFSDM regarding
> > channel scaling management. So, the solution proposed here will apply
> > also for the future MDF driver.
> >
> > [1]
> > https://patchwork.kernel.org/project/linux-iio/patch/20200204101008.11411-5-olivier.moysan@st.com/
> >
> > As a short reminder of our previous discussion, the two main options
> > emerging were the following ones:
> >
> > - Option1: Use the DFSDM as an hardware accelerator and expose the
> > scaled channels on SD modulator side.
> > Drawbak: this solution is leading to an very complex datapath, especially
> > for scan mode.
> >
> > - Option2: Introduce a new IIO device type (so-called backend)
> > Retrieve scaling information from SD modulator scaling to expose a single
> > IIO device on DFSDM side. This solution is derivated from rcar-gyroadc
> > example, but with a more standard approach.
> > This was discussed in
> > https://lore.kernel.org/lkml/20210919191414.09270f4e@jic23-huawei/
>
> Naming probably needs a rethink given the actual hardware we are talking about
> here is normally called a frontend and so people will be confused...
Hmm. I think the basic approach looks fine but needs fleshing out and
perhaps one or two more examples implemented to be sure that we have
something flexible enough to stand the test of time...
Jonathan
>
> I'm traveling at the moment, so only going to take a fairly superficial first
> look at what you have here.
>
> Jonathan
>
> >
> > The patchset proposed in this RFC implements option2 (backend) solution.
> > These patches provide a minimal API implemented as a template.
> > The intented use of this API is illustrated through the DFSDM channel
> > scaling support basic implementation.
> >
> > For sake of simplicity I did not include the related DT binding
> > in this serie.
> >
> > Below are some use case examples.
> >
> > * DFSDM with SD modulator backend:
> > -------------------------------
> > This use case corresponds to the example implemented in this RFC.
> > The channel attributes are retrieved from backend by the dfsdm, and
> > the resulting scaling is exposed through DFSDM IIO device sysfs
> >
> > - Single channel:
> > +-------------+ ch attr +--------+ sysfs (compound scaling)
> > | sd0 backend | ---------> | dfsdm0 | -------------------------->
> > +-------------+ +--------+
> >
> > - Scan mode:
> > +-------------+ ch attr +-------------+ sysfs (compound scaling)
> > | sd1 backend | ---------> | dfsdm1 | -------------------------->
> > +-------------+ +-------------+
> > ^
> > |
> > +-------------+ ch attr |
> > | sd2 backend |--------------+
> > +-------------+
> >
> >
> > * Voltage divider in front of an adc:
> > ----------------------------------
> > By way of example, here is a comparison on scaling management with
> > a iio-rescale device, and how it could be managed with a backend device.
> >
> > - iio-rescale implementation
> > Scaling is exposed both on ADC and iio-rescale IIO devices.
> > On iio-rescale device we get the compound scaling
> >
> > +---------------------------+ ch attr +------+ sysfs
> > | iio-rescale (div) | <--------- | adc0 | ------->
> > +---------------------------+ +------+
> > |
> > | sysfs (compound scaling)
> > v
> >
> > - Backend implementation:
> > Compound scaling is exposed on ADC IIO device.
> > No scaling exposed on backend device
> >
> > +---------------+ ch attr +------+ sysfs (compound scaling)
> > | backend (div) | ---------> | adc0 | -------------------------->
> > +---------------+ +------+
> >
> >
> > * Cascaded backends:
> > -----------------
> > Backends may be cascaded to allow computation of the whole chain scaling
> > This is not part of this RFC, but it is identified as a potential
> > future use case.
> >
> > +---------------+ attr +-------------+ attr +--------+ sysfs
> > | backend (div) | ------> | sd0 backend | ------> | dfsdm0 | ------->
> > +---------------+ +-------------+ +--------+
> >
> > Olivier Moysan (7):
> > iio: introduce iio backend device
> > of: property: add device link support for io-backends
> > iio: adc: stm32-dfsdm: manage dfsdm as a channel provider
> > iio: adc: stm32-dfsdm: adopt generic channel bindings
> > iio: adc: sd_adc_modulator: change to iio backend device
> > iio: adc: stm32-dfsdm: add scaling support to dfsdm
> > ARM: dts: stm32: add dfsdm iio suppport
> >
> > arch/arm/boot/dts/stm32mp157c-ev1.dts | 62 +++++++++
> > drivers/iio/Makefile | 2 +
> > drivers/iio/adc/sd_adc_modulator.c | 92 +++++++++++---
> > drivers/iio/adc/stm32-dfsdm-adc.c | 176 ++++++++++++++++----------
> > drivers/iio/industrialio-backend.c | 59 +++++++++
> > drivers/of/property.c | 2 +
> > include/linux/iio/backend.h | 29 +++++
> > 7 files changed, 336 insertions(+), 86 deletions(-)
> > create mode 100644 drivers/iio/industrialio-backend.c
> > create mode 100644 include/linux/iio/backend.h
> >
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-07-02 11:07 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-23 14:09 [RFC PATCH 0/7] iio: add iio backend device type Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 3/7] iio: adc: stm32-dfsdm: manage dfsdm as a channel provider Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 4/7] iio: adc: stm32-dfsdm: adopt generic channel bindings Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 6/7] iio: adc: stm32-dfsdm: add scaling support to dfsdm Olivier Moysan
2023-06-23 14:09 ` [RFC PATCH 7/7] ARM: dts: stm32: add dfsdm iio suppport Olivier Moysan
2023-07-02 10:56 ` [RFC PATCH 0/7] iio: add iio backend device type Jonathan Cameron
2023-07-02 11:07 ` Jonathan Cameron
2023-07-02 11:00 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).