aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm3216
-rw-r--r--Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt13
-rw-r--r--Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt128
-rw-r--r--Documentation/driver-api/iio/hw-consumer.rst51
-rw-r--r--Documentation/driver-api/iio/index.rst1
-rw-r--r--drivers/iio/adc/Kconfig37
-rw-r--r--drivers/iio/adc/Makefile3
-rw-r--r--drivers/iio/adc/sd_adc_modulator.c68
-rw-r--r--drivers/iio/adc/stm32-dfsdm-adc.c1216
-rw-r--r--drivers/iio/adc/stm32-dfsdm-core.c309
-rw-r--r--drivers/iio/adc/stm32-dfsdm.h310
-rw-r--r--drivers/iio/buffer/Kconfig10
-rw-r--r--drivers/iio/buffer/Makefile1
-rw-r--r--drivers/iio/buffer/industrialio-buffer-cb.c11
-rw-r--r--drivers/iio/buffer/industrialio-hw-consumer.c247
-rw-r--r--drivers/iio/inkern.c17
-rw-r--r--include/linux/iio/adc/stm32-dfsdm-adc.h18
-rw-r--r--include/linux/iio/consumer.h37
-rw-r--r--include/linux/iio/hw-consumer.h21
-rw-r--r--include/linux/iio/iio.h28
-rw-r--r--include/linux/iio/types.h28
21 files changed, 2537 insertions, 33 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32
new file mode 100644
index 000000000000..da9822309f07
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32
@@ -0,0 +1,16 @@
1What: /sys/bus/iio/devices/iio:deviceX/in_voltage_spi_clk_freq
2KernelVersion: 4.14
3Contact: arnaud.pouliquen@st.com
4Description:
5 For audio purpose only.
6 Used by audio driver to set/get the spi input frequency.
7 This is mandatory if DFSDM is slave on SPI bus, to
8 provide information on the SPI clock frequency during runtime
9 Notice that the SPI frequency should be a multiple of sample
10 frequency to ensure the precision.
11 if DFSDM input is SPI master
12 Reading SPI clkout frequency,
13 error on writing
14 If DFSDM input is SPI Slave:
15 Reading returns value previously set.
16 Writing value before starting conversions. \ No newline at end of file
diff --git a/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt
new file mode 100644
index 000000000000..e9ebb8a20e0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt
@@ -0,0 +1,13 @@
1Device-Tree bindings for sigma delta modulator
2
3Required properties:
4- compatible: should be "ads1201", "sd-modulator". "sd-modulator" can be use
5 as a generic SD modulator if modulator not specified in compatible list.
6- #io-channel-cells = <1>: See the IIO bindings section "IIO consumers".
7
8Example node:
9
10 ads1202: adc@0 {
11 compatible = "sd-modulator";
12 #io-channel-cells = <1>;
13 };
diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt
new file mode 100644
index 000000000000..911492da48f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt
@@ -0,0 +1,128 @@
1STMicroelectronics STM32 DFSDM ADC device driver
2
3
4STM32 DFSDM ADC is a sigma delta analog-to-digital converter dedicated to
5interface external sigma delta modulators to STM32 micro controllers.
6It is mainly targeted for:
7- Sigma delta modulators (motor control, metering...)
8- PDM microphones (audio digital microphone)
9
10It features up to 8 serial digital interfaces (SPI or Manchester) and
11up to 4 filters on stm32h7.
12
13Each child node match with a filter instance.
14
15Contents of a STM32 DFSDM root node:
16------------------------------------
17Required properties:
18- compatible: Should be "st,stm32h7-dfsdm".
19- reg: Offset and length of the DFSDM block register set.
20- clocks: IP and serial interfaces clocking. Should be set according
21 to rcc clock ID and "clock-names".
22- clock-names: Input clock name "dfsdm" must be defined,
23 "audio" is optional. If defined CLKOUT is based on the audio
24 clock, else "dfsdm" is used.
25- #interrupt-cells = <1>;
26- #address-cells = <1>;
27- #size-cells = <0>;
28
29Optional properties:
30- spi-max-frequency: Requested only for SPI master mode.
31 SPI clock OUT frequency (Hz). This clock must be set according
32 to "clock" property. Frequency must be a multiple of the rcc
33 clock frequency. If not, SPI CLKOUT frequency will not be
34 accurate.
35
36Contents of a STM32 DFSDM child nodes:
37--------------------------------------
38
39Required properties:
40- compatible: Must be:
41 "st,stm32-dfsdm-adc" for sigma delta ADCs
42 "st,stm32-dfsdm-dmic" for audio digital microphone.
43- reg: Specifies the DFSDM filter instance used.
44- interrupts: IRQ lines connected to each DFSDM filter instance.
45- st,adc-channels: List of single-ended channels muxed for this ADC.
46 valid values:
47 "st,stm32h7-dfsdm" compatibility: 0 to 7.
48- st,adc-channel-names: List of single-ended channel names.
49- st,filter-order: SinC filter order from 0 to 5.
50 0: FastSinC
51 [1-5]: order 1 to 5.
52 For audio purpose it is recommended to use order 3 to 5.
53- #io-channel-cells = <1>: See the IIO bindings section "IIO consumers".
54
55Required properties for "st,stm32-dfsdm-adc" compatibility:
56- io-channels: From common IIO binding. Used to pipe external sigma delta
57 modulator or internal ADC output to DFSDM channel.
58 This is not required for "st,stm32-dfsdm-pdm" compatibility as
59 PDM microphone is binded in Audio DT node.
60
61Required properties for "st,stm32-dfsdm-pdm" compatibility:
62- #sound-dai-cells: Must be set to 0.
63- dma: DMA controller phandle and DMA request line associated to the
64 filter instance (specified by the field "reg")
65- dma-names: Must be "rx"
66
67Optional properties:
68- st,adc-channel-types: Single-ended channel input type.
69 - "SPI_R": SPI with data on rising edge (default)
70 - "SPI_F": SPI with data on falling edge
71 - "MANCH_R": manchester codec, rising edge = logic 0
72 - "MANCH_F": manchester codec, falling edge = logic 1
73- st,adc-channel-clk-src: Conversion clock source.
74 - "CLKIN": external SPI clock (CLKIN x)
75 - "CLKOUT": internal SPI clock (CLKOUT) (default)
76 - "CLKOUT_F": internal SPI clock divided by 2 (falling edge).
77 - "CLKOUT_R": internal SPI clock divided by 2 (rising edge).
78
79- st,adc-alt-channel: Must be defined if two sigma delta modulator are
80 connected on same SPI input.
81 If not set, channel n is connected to SPI input n.
82 If set, channel n is connected to SPI input n + 1.
83
84- st,filter0-sync: Set to 1 to synchronize with DFSDM filter instance 0.
85 Used for multi microphones synchronization.
86
87Example of a sigma delta adc connected on DFSDM SPI port 0
88and a pdm microphone connected on DFSDM SPI port 1:
89
90 ads1202: simple_sd_adc@0 {
91 compatible = "ads1202";
92 #io-channel-cells = <1>;
93 };
94
95 dfsdm: dfsdm@40017000 {
96 compatible = "st,stm32h7-dfsdm";
97 reg = <0x40017000 0x400>;
98 clocks = <&rcc DFSDM1_CK>;
99 clock-names = "dfsdm";
100 #interrupt-cells = <1>;
101 #address-cells = <1>;
102 #size-cells = <0>;
103
104 dfsdm_adc0: filter@0 {
105 compatible = "st,stm32-dfsdm-adc";
106 #io-channel-cells = <1>;
107 reg = <0>;
108 interrupts = <110>;
109 st,adc-channels = <0>;
110 st,adc-channel-names = "sd_adc0";
111 st,adc-channel-types = "SPI_F";
112 st,adc-channel-clk-src = "CLKOUT";
113 io-channels = <&ads1202 0>;
114 st,filter-order = <3>;
115 };
116 dfsdm_pdm1: filter@1 {
117 compatible = "st,stm32-dfsdm-dmic";
118 reg = <1>;
119 interrupts = <111>;
120 dmas = <&dmamux1 102 0x400 0x00>;
121 dma-names = "rx";
122 st,adc-channels = <1>;
123 st,adc-channel-names = "dmic1";
124 st,adc-channel-types = "SPI_R";
125 st,adc-channel-clk-src = "CLKOUT";
126 st,filter-order = <5>;
127 };
128 }
diff --git a/Documentation/driver-api/iio/hw-consumer.rst b/Documentation/driver-api/iio/hw-consumer.rst
new file mode 100644
index 000000000000..8facce6a6733
--- /dev/null
+++ b/Documentation/driver-api/iio/hw-consumer.rst
@@ -0,0 +1,51 @@
1===========
2HW consumer
3===========
4An IIO device can be directly connected to another device in hardware. in this
5case the buffers between IIO provider and IIO consumer are handled by hardware.
6The Industrial I/O HW consumer offers a way to bond these IIO devices without
7software buffer for data. The implementation can be found under
8:file:`drivers/iio/buffer/hw-consumer.c`
9
10
11* struct :c:type:`iio_hw_consumer` — Hardware consumer structure
12* :c:func:`iio_hw_consumer_alloc` — Allocate IIO hardware consumer
13* :c:func:`iio_hw_consumer_free` — Free IIO hardware consumer
14* :c:func:`iio_hw_consumer_enable` — Enable IIO hardware consumer
15* :c:func:`iio_hw_consumer_disable` — Disable IIO hardware consumer
16
17
18HW consumer setup
19=================
20
21As standard IIO device the implementation is based on IIO provider/consumer.
22A typical IIO HW consumer setup looks like this::
23
24 static struct iio_hw_consumer *hwc;
25
26 static const struct iio_info adc_info = {
27 .read_raw = adc_read_raw,
28 };
29
30 static int adc_read_raw(struct iio_dev *indio_dev,
31 struct iio_chan_spec const *chan, int *val,
32 int *val2, long mask)
33 {
34 ret = iio_hw_consumer_enable(hwc);
35
36 /* Acquire data */
37
38 ret = iio_hw_consumer_disable(hwc);
39 }
40
41 static int adc_probe(struct platform_device *pdev)
42 {
43 hwc = devm_iio_hw_consumer_alloc(&iio->dev);
44 }
45
46More details
47============
48.. kernel-doc:: include/linux/iio/hw-consumer.h
49.. kernel-doc:: drivers/iio/buffer/industrialio-hw-consumer.c
50 :export:
51
diff --git a/Documentation/driver-api/iio/index.rst b/Documentation/driver-api/iio/index.rst
index e5c3922d1b6f..7fba341bd8b2 100644
--- a/Documentation/driver-api/iio/index.rst
+++ b/Documentation/driver-api/iio/index.rst
@@ -15,3 +15,4 @@ Contents:
15 buffers 15 buffers
16 triggers 16 triggers
17 triggered-buffers 17 triggered-buffers
18 hw-consumer
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ef86296b8b0d..39e3b345a6c8 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -629,6 +629,18 @@ config SPEAR_ADC
629 To compile this driver as a module, choose M here: the 629 To compile this driver as a module, choose M here: the
630 module will be called spear_adc. 630 module will be called spear_adc.
631 631
632config SD_ADC_MODULATOR
633 tristate "Generic sigma delta modulator"
634 depends on OF
635 select IIO_BUFFER
636 select IIO_TRIGGERED_BUFFER
637 help
638 Select this option to enables sigma delta modulator. This driver can
639 support generic sigma delta modulators.
640
641 This driver can also be built as a module. If so, the module
642 will be called sd_adc_modulator.
643
632config STM32_ADC_CORE 644config STM32_ADC_CORE
633 tristate "STMicroelectronics STM32 adc core" 645 tristate "STMicroelectronics STM32 adc core"
634 depends on ARCH_STM32 || COMPILE_TEST 646 depends on ARCH_STM32 || COMPILE_TEST
@@ -656,6 +668,31 @@ config STM32_ADC
656 This driver can also be built as a module. If so, the module 668 This driver can also be built as a module. If so, the module
657 will be called stm32-adc. 669 will be called stm32-adc.
658 670
671config STM32_DFSDM_CORE
672 tristate "STMicroelectronics STM32 DFSDM core"
673 depends on (ARCH_STM32 && OF) || COMPILE_TEST
674 select REGMAP
675 select REGMAP_MMIO
676 help
677 Select this option to enable the driver for STMicroelectronics
678 STM32 digital filter for sigma delta converter.
679
680 This driver can also be built as a module. If so, the module
681 will be called stm32-dfsdm-core.
682
683config STM32_DFSDM_ADC
684 tristate "STMicroelectronics STM32 dfsdm adc"
685 depends on (ARCH_STM32 && OF) || COMPILE_TEST
686 select STM32_DFSDM_CORE
687 select REGMAP_MMIO
688 select IIO_BUFFER_HW_CONSUMER
689 help
690 Select this option to support ADCSigma delta modulator for
691 STMicroelectronics STM32 digital filter for sigma delta converter.
692
693 This driver can also be built as a module. If so, the module
694 will be called stm32-dfsdm-adc.
695
659config STX104 696config STX104
660 tristate "Apex Embedded Systems STX104 driver" 697 tristate "Apex Embedded Systems STX104 driver"
661 depends on PC104 && X86 && ISA_BUS_API 698 depends on PC104 && X86 && ISA_BUS_API
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 9572c1090f35..28a9423997f3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -64,6 +64,8 @@ obj-$(CONFIG_STX104) += stx104.o
64obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o 64obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
65obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o 65obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
66obj-$(CONFIG_STM32_ADC) += stm32-adc.o 66obj-$(CONFIG_STM32_ADC) += stm32-adc.o
67obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o
68obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o
67obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o 69obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
68obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o 70obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
69obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o 71obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
@@ -82,3 +84,4 @@ obj-$(CONFIG_VF610_ADC) += vf610_adc.o
82obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o 84obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
83xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o 85xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o
84obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o 86obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o
87obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o
diff --git a/drivers/iio/adc/sd_adc_modulator.c b/drivers/iio/adc/sd_adc_modulator.c
new file mode 100644
index 000000000000..560d8c7d9d86
--- /dev/null
+++ b/drivers/iio/adc/sd_adc_modulator.c
@@ -0,0 +1,68 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Generic sigma delta modulator driver
4 *
5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
6 * Author: Arnaud Pouliquen <arnaud.pouliquen@st.com>.
7 */
8
9#include <linux/iio/iio.h>
10#include <linux/iio/triggered_buffer.h>
11#include <linux/module.h>
12#include <linux/of_device.h>
13
14static const struct iio_info iio_sd_mod_iio_info;
15
16static const struct iio_chan_spec iio_sd_mod_ch = {
17 .type = IIO_VOLTAGE,
18 .indexed = 1,
19 .scan_type = {
20 .sign = 'u',
21 .realbits = 1,
22 .shift = 0,
23 },
24};
25
26static int iio_sd_mod_probe(struct platform_device *pdev)
27{
28 struct device *dev = &pdev->dev;
29 struct iio_dev *iio;
30
31 iio = devm_iio_device_alloc(dev, 0);
32 if (!iio)
33 return -ENOMEM;
34
35 iio->dev.parent = dev;
36 iio->dev.of_node = dev->of_node;
37 iio->name = dev_name(dev);
38 iio->info = &iio_sd_mod_iio_info;
39 iio->modes = INDIO_BUFFER_HARDWARE;
40
41 iio->num_channels = 1;
42 iio->channels = &iio_sd_mod_ch;
43
44 platform_set_drvdata(pdev, iio);
45
46 return devm_iio_device_register(&pdev->dev, iio);
47}
48
49static const struct of_device_id sd_adc_of_match[] = {
50 { .compatible = "sd-modulator" },
51 { .compatible = "ads1201" },
52 { }
53};
54MODULE_DEVICE_TABLE(of, sd_adc_of_match);
55
56static struct platform_driver iio_sd_mod_adc = {
57 .driver = {
58 .name = "iio_sd_adc_mod",
59 .of_match_table = of_match_ptr(sd_adc_of_match),
60 },
61 .probe = iio_sd_mod_probe,
62};
63
64module_platform_driver(iio_sd_mod_adc);
65
66MODULE_DESCRIPTION("Basic sigma delta modulator");
67MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
68MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
new file mode 100644
index 000000000000..e628d04d5c77
--- /dev/null
+++ b/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -0,0 +1,1216 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * This file is the ADC part of the STM32 DFSDM driver
4 *
5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
6 * Author: Arnaud Pouliquen <arnaud.pouliquen@st.com>.
7 */
8
9#include <linux/dmaengine.h>
10#include <linux/dma-mapping.h>
11#include <linux/interrupt.h>
12#include <linux/iio/buffer.h>
13#include <linux/iio/hw-consumer.h>
14#include <linux/iio/iio.h>
15#include <linux/iio/sysfs.h>
16#include <linux/module.h>
17#include <linux/of_device.h>
18#include <linux/platform_device.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21
22#include "stm32-dfsdm.h"
23
24#define DFSDM_DMA_BUFFER_SIZE (4 * PAGE_SIZE)
25
26/* Conversion timeout */
27#define DFSDM_TIMEOUT_US 100000
28#define DFSDM_TIMEOUT (msecs_to_jiffies(DFSDM_TIMEOUT_US / 1000))
29
30/* Oversampling attribute default */
31#define DFSDM_DEFAULT_OVERSAMPLING 100
32
33/* Oversampling max values */
34#define DFSDM_MAX_INT_OVERSAMPLING 256
35#define DFSDM_MAX_FL_OVERSAMPLING 1024
36
37/* Max sample resolutions */
38#define DFSDM_MAX_RES BIT(31)
39#define DFSDM_DATA_RES BIT(23)
40
41enum sd_converter_type {
42 DFSDM_AUDIO,
43 DFSDM_IIO,
44};
45
46struct stm32_dfsdm_dev_data {
47 int type;
48 int (*init)(struct iio_dev *indio_dev);
49 unsigned int num_channels;
50 const struct regmap_config *regmap_cfg;
51};
52
53struct stm32_dfsdm_adc {
54 struct stm32_dfsdm *dfsdm;
55 const struct stm32_dfsdm_dev_data *dev_data;
56 unsigned int fl_id;
57 unsigned int ch_id;
58
59 /* ADC specific */
60 unsigned int oversamp;
61 struct iio_hw_consumer *hwc;
62 struct completion completion;
63 u32 *buffer;
64
65 /* Audio specific */
66 unsigned int spi_freq; /* SPI bus clock frequency */
67 unsigned int sample_freq; /* Sample frequency after filter decimation */
68 int (*cb)(const void *data, size_t size, void *cb_priv);
69 void *cb_priv;
70
71 /* DMA */
72 u8 *rx_buf;
73 unsigned int bufi; /* Buffer current position */
74 unsigned int buf_sz; /* Buffer size */
75 struct dma_chan *dma_chan;
76 dma_addr_t dma_buf;
77};
78
79struct stm32_dfsdm_str2field {
80 const char *name;
81 unsigned int val;
82};
83
84/* DFSDM channel serial interface type */
85static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_type[] = {
86 { "SPI_R", 0 }, /* SPI with data on rising edge */
87 { "SPI_F", 1 }, /* SPI with data on falling edge */
88 { "MANCH_R", 2 }, /* Manchester codec, rising edge = logic 0 */
89 { "MANCH_F", 3 }, /* Manchester codec, falling edge = logic 1 */
90 {},
91};
92
93/* DFSDM channel clock source */
94static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_src[] = {
95 /* External SPI clock (CLKIN x) */
96 { "CLKIN", DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL },
97 /* Internal SPI clock (CLKOUT) */
98 { "CLKOUT", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL },
99 /* Internal SPI clock divided by 2 (falling edge) */
100 { "CLKOUT_F", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING },
101 /* Internal SPI clock divided by 2 (falling edge) */
102 { "CLKOUT_R", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING },
103 {},
104};
105
106static int stm32_dfsdm_str2val(const char *str,
107 const struct stm32_dfsdm_str2field *list)
108{
109 const struct stm32_dfsdm_str2field *p = list;
110
111 for (p = list; p && p->name; p++)
112 if (!strcmp(p->name, str))
113 return p->val;
114
115 return -EINVAL;
116}
117
118static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
119 unsigned int fast, unsigned int oversamp)
120{
121 unsigned int i, d, fosr, iosr;
122 u64 res;
123 s64 delta;
124 unsigned int m = 1; /* multiplication factor */
125 unsigned int p = fl->ford; /* filter order (ford) */
126
127 pr_debug("%s: Requested oversampling: %d\n", __func__, oversamp);
128 /*
129 * This function tries to compute filter oversampling and integrator
130 * oversampling, base on oversampling ratio requested by user.
131 *
132 * Decimation d depends on the filter order and the oversampling ratios.
133 * ford: filter order
134 * fosr: filter over sampling ratio
135 * iosr: integrator over sampling ratio
136 */
137 if (fl->ford == DFSDM_FASTSINC_ORDER) {
138 m = 2;
139 p = 2;
140 }
141
142 /*
143 * Look for filter and integrator oversampling ratios which allows
144 * to reach 24 bits data output resolution.
145 * Leave as soon as if exact resolution if reached.
146 * Otherwise the higher resolution below 32 bits is kept.
147 */
148 for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) {
149 for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) {
150 if (fast)
151 d = fosr * iosr;
152 else if (fl->ford == DFSDM_FASTSINC_ORDER)
153 d = fosr * (iosr + 3) + 2;
154 else
155 d = fosr * (iosr - 1 + p) + p;
156
157 if (d > oversamp)
158 break;
159 else if (d != oversamp)
160 continue;
161 /*
162 * Check resolution (limited to signed 32 bits)
163 * res <= 2^31
164 * Sincx filters:
165 * res = m * fosr^p x iosr (with m=1, p=ford)
166 * FastSinc filter
167 * res = m * fosr^p x iosr (with m=2, p=2)
168 */
169 res = fosr;
170 for (i = p - 1; i > 0; i--) {
171 res = res * (u64)fosr;
172 if (res > DFSDM_MAX_RES)
173 break;
174 }
175 if (res > DFSDM_MAX_RES)
176 continue;
177 res = res * (u64)m * (u64)iosr;
178 if (res > DFSDM_MAX_RES)
179 continue;
180
181 delta = res - DFSDM_DATA_RES;
182
183 if (res >= fl->res) {
184 fl->res = res;
185 fl->fosr = fosr;
186 fl->iosr = iosr;
187 fl->fast = fast;
188 pr_debug("%s: fosr = %d, iosr = %d\n",
189 __func__, fl->fosr, fl->iosr);
190 }
191
192 if (!delta)
193 return 0;
194 }
195 }
196
197 if (!fl->fosr)
198 return -EINVAL;
199
200 return 0;
201}
202
203static int stm32_dfsdm_start_channel(struct stm32_dfsdm *dfsdm,
204 unsigned int ch_id)
205{
206 return regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id),
207 DFSDM_CHCFGR1_CHEN_MASK,
208 DFSDM_CHCFGR1_CHEN(1));
209}
210
211static void stm32_dfsdm_stop_channel(struct stm32_dfsdm *dfsdm,
212 unsigned int ch_id)
213{
214 regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id),
215 DFSDM_CHCFGR1_CHEN_MASK, DFSDM_CHCFGR1_CHEN(0));
216}
217
218static int stm32_dfsdm_chan_configure(struct stm32_dfsdm *dfsdm,
219 struct stm32_dfsdm_channel *ch)
220{
221 unsigned int id = ch->id;
222 struct regmap *regmap = dfsdm->regmap;
223 int ret;
224
225 ret = regmap_update_bits(regmap, DFSDM_CHCFGR1(id),
226 DFSDM_CHCFGR1_SITP_MASK,
227 DFSDM_CHCFGR1_SITP(ch->type));
228 if (ret < 0)
229 return ret;
230 ret = regmap_update_bits(regmap, DFSDM_CHCFGR1(id),
231 DFSDM_CHCFGR1_SPICKSEL_MASK,
232 DFSDM_CHCFGR1_SPICKSEL(ch->src));
233 if (ret < 0)
234 return ret;
235 return regmap_update_bits(regmap, DFSDM_CHCFGR1(id),
236 DFSDM_CHCFGR1_CHINSEL_MASK,
237 DFSDM_CHCFGR1_CHINSEL(ch->alt_si));
238}
239
240static int stm32_dfsdm_start_filter(struct stm32_dfsdm *dfsdm,
241 unsigned int fl_id)
242{
243 int ret;
244
245 /* Enable filter */
246 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id),
247 DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(1));
248 if (ret < 0)
249 return ret;
250
251 /* Start conversion */
252 return regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id),
253 DFSDM_CR1_RSWSTART_MASK,
254 DFSDM_CR1_RSWSTART(1));
255}
256
257static void stm32_dfsdm_stop_filter(struct stm32_dfsdm *dfsdm, unsigned int fl_id)
258{
259 /* Disable conversion */
260 regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id),
261 DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(0));
262}
263
264static int stm32_dfsdm_filter_configure(struct stm32_dfsdm *dfsdm,
265 unsigned int fl_id, unsigned int ch_id)
266{
267 struct regmap *regmap = dfsdm->regmap;
268 struct stm32_dfsdm_filter *fl = &dfsdm->fl_list[fl_id];
269 int ret;
270
271 /* Average integrator oversampling */
272 ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_IOSR_MASK,
273 DFSDM_FCR_IOSR(fl->iosr - 1));
274 if (ret)
275 return ret;
276
277 /* Filter order and Oversampling */
278 ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FOSR_MASK,
279 DFSDM_FCR_FOSR(fl->fosr - 1));
280 if (ret)
281 return ret;
282
283 ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FORD_MASK,
284 DFSDM_FCR_FORD(fl->ford));
285 if (ret)
286 return ret;
287
288 /* No scan mode supported for the moment */
289 ret = regmap_update_bits(regmap, DFSDM_CR1(fl_id), DFSDM_CR1_RCH_MASK,
290 DFSDM_CR1_RCH(ch_id));
291 if (ret)
292 return ret;
293
294 return regmap_update_bits(regmap, DFSDM_CR1(fl_id),
295 DFSDM_CR1_RSYNC_MASK,
296 DFSDM_CR1_RSYNC(fl->sync_mode));
297}
298
299static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
300 struct iio_dev *indio_dev,
301 struct iio_chan_spec *ch)
302{
303 struct stm32_dfsdm_channel *df_ch;
304 const char *of_str;
305 int chan_idx = ch->scan_index;
306 int ret, val;
307
308 ret = of_property_read_u32_index(indio_dev->dev.of_node,
309 "st,adc-channels", chan_idx,
310 &ch->channel);
311 if (ret < 0) {
312 dev_err(&indio_dev->dev,
313 " Error parsing 'st,adc-channels' for idx %d\n",
314 chan_idx);
315 return ret;
316 }
317 if (ch->channel >= dfsdm->num_chs) {
318 dev_err(&indio_dev->dev,
319 " Error bad channel number %d (max = %d)\n",
320 ch->channel, dfsdm->num_chs);
321 return -EINVAL;
322 }
323
324 ret = of_property_read_string_index(indio_dev->dev.of_node,
325 "st,adc-channel-names", chan_idx,
326 &ch->datasheet_name);
327 if (ret < 0) {
328 dev_err(&indio_dev->dev,
329 " Error parsing 'st,adc-channel-names' for idx %d\n",
330 chan_idx);
331 return ret;
332 }
333
334 df_ch = &dfsdm->ch_list[ch->channel];
335 df_ch->id = ch->channel;
336
337 ret = of_property_read_string_index(indio_dev->dev.of_node,
338 "st,adc-channel-types", chan_idx,
339 &of_str);
340 if (!ret) {
341 val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_type);
342 if (val < 0)
343 return val;
344 } else {
345 val = 0;
346 }
347 df_ch->type = val;
348
349 ret = of_property_read_string_index(indio_dev->dev.of_node,
350 "st,adc-channel-clk-src", chan_idx,
351 &of_str);
352 if (!ret) {
353 val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_src);
354 if (val < 0)
355 return val;
356 } else {
357 val = 0;
358 }
359 df_ch->src = val;
360
361 ret = of_property_read_u32_index(indio_dev->dev.of_node,
362 "st,adc-alt-channel", chan_idx,
363 &df_ch->alt_si);
364 if (ret < 0)
365 df_ch->alt_si = 0;
366
367 return 0;
368}
369
370static ssize_t dfsdm_adc_audio_get_spiclk(struct iio_dev *indio_dev,
371 uintptr_t priv,
372 const struct iio_chan_spec *chan,
373 char *buf)
374{
375 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
376
377 return snprintf(buf, PAGE_SIZE, "%d\n", adc->spi_freq);
378}
379
380static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev,
381 uintptr_t priv,
382 const struct iio_chan_spec *chan,
383 const char *buf, size_t len)
384{
385 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
386 struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
387 struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id];
388 unsigned int sample_freq = adc->sample_freq;
389 unsigned int spi_freq;
390 int ret;
391
392 dev_err(&indio_dev->dev, "enter %s\n", __func__);
393 /* If DFSDM is master on SPI, SPI freq can not be updated */
394 if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
395 return -EPERM;
396
397 ret = kstrtoint(buf, 0, &spi_freq);
398 if (ret)
399 return ret;
400
401 if (!spi_freq)
402 return -EINVAL;
403
404 if (sample_freq) {
405 if (spi_freq % sample_freq)
406 dev_warn(&indio_dev->dev,
407 "Sampling rate not accurate (%d)\n",
408 spi_freq / (spi_freq / sample_freq));
409
410 ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / sample_freq));
411 if (ret < 0) {
412 dev_err(&indio_dev->dev,
413 "No filter parameters that match!\n");
414 return ret;
415 }
416 }
417 adc->spi_freq = spi_freq;
418
419 return len;
420}
421
422static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma)
423{
424 struct regmap *regmap = adc->dfsdm->regmap;
425 int ret;
426 unsigned int dma_en = 0, cont_en = 0;
427
428 ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id);
429 if (ret < 0)
430 return ret;
431
432 ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id,
433 adc->ch_id);
434 if (ret < 0)
435 goto stop_channels;
436
437 if (dma) {
438 /* Enable DMA transfer*/
439 dma_en = DFSDM_CR1_RDMAEN(1);
440 /* Enable conversion triggered by SPI clock*/
441 cont_en = DFSDM_CR1_RCONT(1);
442 }
443 /* Enable DMA transfer*/
444 ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
445 DFSDM_CR1_RDMAEN_MASK, dma_en);
446 if (ret < 0)
447 goto stop_channels;
448
449 /* Enable conversion triggered by SPI clock*/
450 ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
451 DFSDM_CR1_RCONT_MASK, cont_en);
452 if (ret < 0)
453 goto stop_channels;
454
455 ret = stm32_dfsdm_start_filter(adc->dfsdm, adc->fl_id);
456 if (ret < 0)
457 goto stop_channels;
458
459 return 0;
460
461stop_channels:
462 regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
463 DFSDM_CR1_RDMAEN_MASK, 0);
464
465 regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
466 DFSDM_CR1_RCONT_MASK, 0);
467 stm32_dfsdm_stop_channel(adc->dfsdm, adc->fl_id);
468
469 return ret;
470}
471
472static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc)
473{
474 struct regmap *regmap = adc->dfsdm->regmap;
475
476 stm32_dfsdm_stop_filter(adc->dfsdm, adc->fl_id);
477
478 /* Clean conversion options */
479 regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
480 DFSDM_CR1_RDMAEN_MASK, 0);
481
482 regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
483 DFSDM_CR1_RCONT_MASK, 0);
484
485 stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id);
486}
487
488static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev,
489 unsigned int val)
490{
491 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
492 unsigned int watermark = DFSDM_DMA_BUFFER_SIZE / 2;
493
494 /*
495 * DMA cyclic transfers are used, buffer is split into two periods.
496 * There should be :
497 * - always one buffer (period) DMA is working on
498 * - one buffer (period) driver pushed to ASoC side.
499 */
500 watermark = min(watermark, val * (unsigned int)(sizeof(u32)));
501 adc->buf_sz = watermark * 2;
502
503 return 0;
504}
505
506static unsigned int stm32_dfsdm_adc_dma_residue(struct stm32_dfsdm_adc *adc)
507{
508 struct dma_tx_state state;
509 enum dma_status status;
510
511 status = dmaengine_tx_status(adc->dma_chan,
512 adc->dma_chan->cookie,
513 &state);
514 if (status == DMA_IN_PROGRESS) {
515 /* Residue is size in bytes from end of buffer */
516 unsigned int i = adc->buf_sz - state.residue;
517 unsigned int size;
518
519 /* Return available bytes */
520 if (i >= adc->bufi)
521 size = i - adc->bufi;
522 else
523 size = adc->buf_sz + i - adc->bufi;
524
525 return size;
526 }
527
528 return 0;
529}
530
531static void stm32_dfsdm_audio_dma_buffer_done(void *data)
532{
533 struct iio_dev *indio_dev = data;
534 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
535 int available = stm32_dfsdm_adc_dma_residue(adc);
536 size_t old_pos;
537
538 /*
539 * FIXME: In Kernel interface does not support cyclic DMA buffer,and
540 * offers only an interface to push data samples per samples.
541 * For this reason IIO buffer interface is not used and interface is
542 * bypassed using a private callback registered by ASoC.
543 * This should be a temporary solution waiting a cyclic DMA engine
544 * support in IIO.
545 */
546
547 dev_dbg(&indio_dev->dev, "%s: pos = %d, available = %d\n", __func__,
548 adc->bufi, available);
549 old_pos = adc->bufi;
550
551 while (available >= indio_dev->scan_bytes) {
552 u32 *buffer = (u32 *)&adc->rx_buf[adc->bufi];
553
554 /* Mask 8 LSB that contains the channel ID */
555 *buffer = (*buffer & 0xFFFFFF00) << 8;
556 available -= indio_dev->scan_bytes;
557 adc->bufi += indio_dev->scan_bytes;
558 if (adc->bufi >= adc->buf_sz) {
559 if (adc->cb)
560 adc->cb(&adc->rx_buf[old_pos],
561 adc->buf_sz - old_pos, adc->cb_priv);
562 adc->bufi = 0;
563 old_pos = 0;
564 }
565 }
566 if (adc->cb)
567 adc->cb(&adc->rx_buf[old_pos], adc->bufi - old_pos,
568 adc->cb_priv);
569}
570
571static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev)
572{
573 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
574 struct dma_async_tx_descriptor *desc;
575 dma_cookie_t cookie;
576 int ret;
577
578 if (!adc->dma_chan)
579 return -EINVAL;
580
581 dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__,
582 adc->buf_sz, adc->buf_sz / 2);
583
584 /* Prepare a DMA cyclic transaction */
585 desc = dmaengine_prep_dma_cyclic(adc->dma_chan,
586 adc->dma_buf,
587 adc->buf_sz, adc->buf_sz / 2,
588 DMA_DEV_TO_MEM,
589 DMA_PREP_INTERRUPT);
590 if (!desc)
591 return -EBUSY;
592
593 desc->callback = stm32_dfsdm_audio_dma_buffer_done;
594 desc->callback_param = indio_dev;
595
596 cookie = dmaengine_submit(desc);
597 ret = dma_submit_error(cookie);
598 if (ret) {
599 dmaengine_terminate_all(adc->dma_chan);
600 return ret;
601 }
602
603 /* Issue pending DMA requests */
604 dma_async_issue_pending(adc->dma_chan);
605
606 return 0;
607}
608
609static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
610{
611 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
612 int ret;
613
614 /* Reset adc buffer index */
615 adc->bufi = 0;
616
617 ret = stm32_dfsdm_start_dfsdm(adc->dfsdm);
618 if (ret < 0)
619 return ret;
620
621 ret = stm32_dfsdm_start_conv(adc, true);
622 if (ret) {
623 dev_err(&indio_dev->dev, "Can't start conversion\n");
624 goto stop_dfsdm;
625 }
626
627 if (adc->dma_chan) {
628 ret = stm32_dfsdm_adc_dma_start(indio_dev);
629 if (ret) {
630 dev_err(&indio_dev->dev, "Can't start DMA\n");
631 goto err_stop_conv;
632 }
633 }
634
635 return 0;
636
637err_stop_conv:
638 stm32_dfsdm_stop_conv(adc);
639stop_dfsdm:
640 stm32_dfsdm_stop_dfsdm(adc->dfsdm);
641
642 return ret;
643}
644
645static int stm32_dfsdm_predisable(struct iio_dev *indio_dev)
646{
647 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
648
649 if (adc->dma_chan)
650 dmaengine_terminate_all(adc->dma_chan);
651
652 stm32_dfsdm_stop_conv(adc);
653
654 stm32_dfsdm_stop_dfsdm(adc->dfsdm);
655
656 return 0;
657}
658
659static const struct iio_buffer_setup_ops stm32_dfsdm_buffer_setup_ops = {
660 .postenable = &stm32_dfsdm_postenable,
661 .predisable = &stm32_dfsdm_predisable,
662};
663
664/**
665 * stm32_dfsdm_get_buff_cb() - register a callback that will be called when
666 * DMA transfer period is achieved.
667 *
668 * @iio_dev: Handle to IIO device.
669 * @cb: Pointer to callback function:
670 * - data: pointer to data buffer
671 * - size: size in byte of the data buffer
672 * - private: pointer to consumer private structure.
673 * @private: Pointer to consumer private structure.
674 */
675int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev,
676 int (*cb)(const void *data, size_t size,
677 void *private),
678 void *private)
679{
680 struct stm32_dfsdm_adc *adc;
681
682 if (!iio_dev)
683 return -EINVAL;
684 adc = iio_priv(iio_dev);
685
686 adc->cb = cb;
687 adc->cb_priv = private;
688
689 return 0;
690}
691EXPORT_SYMBOL_GPL(stm32_dfsdm_get_buff_cb);
692
693/**
694 * stm32_dfsdm_release_buff_cb - unregister buffer callback
695 *
696 * @iio_dev: Handle to IIO device.
697 */
698int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev)
699{
700 struct stm32_dfsdm_adc *adc;
701
702 if (!iio_dev)
703 return -EINVAL;
704 adc = iio_priv(iio_dev);
705
706 adc->cb = NULL;
707 adc->cb_priv = NULL;
708
709 return 0;
710}
711EXPORT_SYMBOL_GPL(stm32_dfsdm_release_buff_cb);
712
713static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
714 const struct iio_chan_spec *chan, int *res)
715{
716 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
717 long timeout;
718 int ret;
719
720 reinit_completion(&adc->completion);
721
722 adc->buffer = res;
723
724 ret = stm32_dfsdm_start_dfsdm(adc->dfsdm);
725 if (ret < 0)
726 return ret;
727
728 ret = regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
729 DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(1));
730 if (ret < 0)
731 goto stop_dfsdm;
732
733 ret = stm32_dfsdm_start_conv(adc, false);
734 if (ret < 0) {
735 regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
736 DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0));
737 goto stop_dfsdm;
738 }
739
740 timeout = wait_for_completion_interruptible_timeout(&adc->completion,
741 DFSDM_TIMEOUT);
742
743 /* Mask IRQ for regular conversion achievement*/
744 regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
745 DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0));
746
747 if (timeout == 0)
748 ret = -ETIMEDOUT;
749 else if (timeout < 0)
750 ret = timeout;
751 else
752 ret = IIO_VAL_INT;
753
754 stm32_dfsdm_stop_conv(adc);
755
756stop_dfsdm:
757 stm32_dfsdm_stop_dfsdm(adc->dfsdm);
758
759 return ret;
760}
761
762static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
763 struct iio_chan_spec const *chan,
764 int val, int val2, long mask)
765{
766 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
767 struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
768 struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id];
769 unsigned int spi_freq = adc->spi_freq;
770 int ret = -EINVAL;
771
772 switch (mask) {
773 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
774 ret = stm32_dfsdm_set_osrs(fl, 0, val);
775 if (!ret)
776 adc->oversamp = val;
777
778 return ret;
779
780 case IIO_CHAN_INFO_SAMP_FREQ:
781 if (!val)
782 return -EINVAL;
783 if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
784 spi_freq = adc->dfsdm->spi_master_freq;
785
786 if (spi_freq % val)
787 dev_warn(&indio_dev->dev,
788 "Sampling rate not accurate (%d)\n",
789 spi_freq / (spi_freq / val));
790
791 ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / val));
792 if (ret < 0) {
793 dev_err(&indio_dev->dev,
794 "Not able to find parameter that match!\n");
795 return ret;
796 }
797 adc->sample_freq = val;
798
799 return 0;
800 }
801
802 return -EINVAL;
803}
804
805static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev,
806 struct iio_chan_spec const *chan, int *val,
807 int *val2, long mask)
808{
809 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
810 int ret;
811
812 switch (mask) {
813 case IIO_CHAN_INFO_RAW:
814 ret = iio_hw_consumer_enable(adc->hwc);
815 if (ret < 0) {
816 dev_err(&indio_dev->dev,
817 "%s: IIO enable failed (channel %d)\n",
818 __func__, chan->channel);
819 return ret;
820 }
821 ret = stm32_dfsdm_single_conv(indio_dev, chan, val);
822 iio_hw_consumer_disable(adc->hwc);
823 if (ret < 0) {
824 dev_err(&indio_dev->dev,
825 "%s: Conversion failed (channel %d)\n",
826 __func__, chan->channel);
827 return ret;
828 }
829 return IIO_VAL_INT;
830
831 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
832 *val = adc->oversamp;
833
834 return IIO_VAL_INT;
835
836 case IIO_CHAN_INFO_SAMP_FREQ:
837 *val = adc->sample_freq;
838
839 return IIO_VAL_INT;
840 }
841
842 return -EINVAL;
843}
844
845static const struct iio_info stm32_dfsdm_info_audio = {
846 .hwfifo_set_watermark = stm32_dfsdm_set_watermark,
847 .read_raw = stm32_dfsdm_read_raw,
848 .write_raw = stm32_dfsdm_write_raw,
849};
850
851static const struct iio_info stm32_dfsdm_info_adc = {
852 .read_raw = stm32_dfsdm_read_raw,
853 .write_raw = stm32_dfsdm_write_raw,
854};
855
856static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
857{
858 struct stm32_dfsdm_adc *adc = arg;
859 struct iio_dev *indio_dev = iio_priv_to_dev(adc);
860 struct regmap *regmap = adc->dfsdm->regmap;
861 unsigned int status, int_en;
862
863 regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
864 regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);
865
866 if (status & DFSDM_ISR_REOCF_MASK) {
867 /* Read the data register clean the IRQ status */
868 regmap_read(regmap, DFSDM_RDATAR(adc->fl_id), adc->buffer);
869 complete(&adc->completion);
870 }
871
872 if (status & DFSDM_ISR_ROVRF_MASK) {
873 if (int_en & DFSDM_CR2_ROVRIE_MASK)
874 dev_warn(&indio_dev->dev, "Overrun detected\n");
875 regmap_update_bits(regmap, DFSDM_ICR(adc->fl_id),
876 DFSDM_ICR_CLRROVRF_MASK,
877 DFSDM_ICR_CLRROVRF_MASK);
878 }
879
880 return IRQ_HANDLED;
881}
882
883/*
884 * Define external info for SPI Frequency and audio sampling rate that can be
885 * configured by ASoC driver through consumer.h API
886 */
887static const struct iio_chan_spec_ext_info dfsdm_adc_audio_ext_info[] = {
888 /* spi_clk_freq : clock freq on SPI/manchester bus used by channel */
889 {
890 .name = "spi_clk_freq",
891 .shared = IIO_SHARED_BY_TYPE,
892 .read = dfsdm_adc_audio_get_spiclk,
893 .write = dfsdm_adc_audio_set_spiclk,
894 },
895 {},
896};
897
898static void stm32_dfsdm_dma_release(struct iio_dev *indio_dev)
899{
900 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
901
902 if (adc->dma_chan) {
903 dma_free_coherent(adc->dma_chan->device->dev,
904 DFSDM_DMA_BUFFER_SIZE,
905 adc->rx_buf, adc->dma_buf);
906 dma_release_channel(adc->dma_chan);
907 }
908}
909
910static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev)
911{
912 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
913 struct dma_slave_config config = {
914 .src_addr = (dma_addr_t)adc->dfsdm->phys_base +
915 DFSDM_RDATAR(adc->fl_id),
916 .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
917 };
918 int ret;
919
920 adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx");
921 if (!adc->dma_chan)
922 return -EINVAL;
923
924 adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev,
925 DFSDM_DMA_BUFFER_SIZE,
926 &adc->dma_buf, GFP_KERNEL);
927 if (!adc->rx_buf) {
928 ret = -ENOMEM;
929 goto err_release;
930 }
931
932 ret = dmaengine_slave_config(adc->dma_chan, &config);
933 if (ret)
934 goto err_free;
935
936 return 0;
937
938err_free:
939 dma_free_coherent(adc->dma_chan->device->dev, DFSDM_DMA_BUFFER_SIZE,
940 adc->rx_buf, adc->dma_buf);
941err_release:
942 dma_release_channel(adc->dma_chan);
943
944 return ret;
945}
946
947static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
948 struct iio_chan_spec *ch)
949{
950 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
951 int ret;
952
953 ret = stm32_dfsdm_channel_parse_of(adc->dfsdm, indio_dev, ch);
954 if (ret < 0)
955 return ret;
956
957 ch->type = IIO_VOLTAGE;
958 ch->indexed = 1;
959
960 /*
961 * IIO_CHAN_INFO_RAW: used to compute regular conversion
962 * IIO_CHAN_INFO_OVERSAMPLING_RATIO: used to set oversampling
963 */
964 ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
965 ch->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO);
966
967 if (adc->dev_data->type == DFSDM_AUDIO) {
968 ch->scan_type.sign = 's';
969 ch->ext_info = dfsdm_adc_audio_ext_info;
970 } else {
971 ch->scan_type.sign = 'u';
972 }
973 ch->scan_type.realbits = 24;
974 ch->scan_type.storagebits = 32;
975 adc->ch_id = ch->channel;
976
977 return stm32_dfsdm_chan_configure(adc->dfsdm,
978 &adc->dfsdm->ch_list[ch->channel]);
979}
980
981static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev)
982{
983 struct iio_chan_spec *ch;
984 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
985 struct stm32_dfsdm_channel *d_ch;
986 int ret;
987
988 indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
989 indio_dev->setup_ops = &stm32_dfsdm_buffer_setup_ops;
990
991 ch = devm_kzalloc(&indio_dev->dev, sizeof(*ch), GFP_KERNEL);
992 if (!ch)
993 return -ENOMEM;
994
995 ch->scan_index = 0;
996
997 ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch);
998 if (ret < 0) {
999 dev_err(&indio_dev->dev, "Channels init failed\n");
1000 return ret;
1001 }
1002 ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ);
1003
1004 d_ch = &adc->dfsdm->ch_list[adc->ch_id];
1005 if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
1006 adc->spi_freq = adc->dfsdm->spi_master_freq;
1007
1008 indio_dev->num_channels = 1;
1009 indio_dev->channels = ch;
1010
1011 return stm32_dfsdm_dma_request(indio_dev);
1012}
1013
1014static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
1015{
1016 struct iio_chan_spec *ch;
1017 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
1018 int num_ch;
1019 int ret, chan_idx;
1020
1021 adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING;
1022 ret = stm32_dfsdm_set_osrs(&adc->dfsdm->fl_list[adc->fl_id], 0,
1023 adc->oversamp);
1024 if (ret < 0)
1025 return ret;
1026
1027 num_ch = of_property_count_u32_elems(indio_dev->dev.of_node,
1028 "st,adc-channels");
1029 if (num_ch < 0 || num_ch > adc->dfsdm->num_chs) {
1030 dev_err(&indio_dev->dev, "Bad st,adc-channels\n");
1031 return num_ch < 0 ? num_ch : -EINVAL;
1032 }
1033
1034 /* Bind to SD modulator IIO device */
1035 adc->hwc = devm_iio_hw_consumer_alloc(&indio_dev->dev);
1036 if (IS_ERR(adc->hwc))
1037 return -EPROBE_DEFER;
1038
1039 ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch),
1040 GFP_KERNEL);
1041 if (!ch)
1042 return -ENOMEM;
1043
1044 for (chan_idx = 0; chan_idx < num_ch; chan_idx++) {
1045 ch->scan_index = chan_idx;
1046 ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch);
1047 if (ret < 0) {
1048 dev_err(&indio_dev->dev, "Channels init failed\n");
1049 return ret;
1050 }
1051 }
1052
1053 indio_dev->num_channels = num_ch;
1054 indio_dev->channels = ch;
1055
1056 init_completion(&adc->completion);
1057
1058 return 0;
1059}
1060
1061static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_adc_data = {
1062 .type = DFSDM_IIO,
1063 .init = stm32_dfsdm_adc_init,
1064};
1065
1066static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_audio_data = {
1067 .type = DFSDM_AUDIO,
1068 .init = stm32_dfsdm_audio_init,
1069};
1070
1071static const struct of_device_id stm32_dfsdm_adc_match[] = {
1072 {
1073 .compatible = "st,stm32-dfsdm-adc",
1074 .data = &stm32h7_dfsdm_adc_data,
1075 },
1076 {
1077 .compatible = "st,stm32-dfsdm-dmic",
1078 .data = &stm32h7_dfsdm_audio_data,
1079 },
1080 {}
1081};
1082
1083static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
1084{
1085 struct device *dev = &pdev->dev;
1086 struct stm32_dfsdm_adc *adc;
1087 struct device_node *np = dev->of_node;
1088 const struct stm32_dfsdm_dev_data *dev_data;
1089 struct iio_dev *iio;
1090 const struct of_device_id *of_id;
1091 char *name;
1092 int ret, irq, val;
1093
1094 of_id = of_match_node(stm32_dfsdm_adc_match, np);
1095 if (!of_id->data) {
1096 dev_err(&pdev->dev, "Data associated to device is missing\n");
1097 return -EINVAL;
1098 }
1099
1100 dev_data = (const struct stm32_dfsdm_dev_data *)of_id->data;
1101
1102 iio = devm_iio_device_alloc(dev, sizeof(*adc));
1103 if (IS_ERR(iio)) {
1104 dev_err(dev, "%s: Failed to allocate IIO\n", __func__);
1105 return PTR_ERR(iio);
1106 }
1107
1108 adc = iio_priv(iio);
1109 if (IS_ERR(adc)) {
1110 dev_err(dev, "%s: Failed to allocate ADC\n", __func__);
1111 return PTR_ERR(adc);
1112 }
1113 adc->dfsdm = dev_get_drvdata(dev->parent);
1114
1115 iio->dev.parent = dev;
1116 iio->dev.of_node = np;
1117 iio->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
1118
1119 platform_set_drvdata(pdev, adc);
1120
1121 ret = of_property_read_u32(dev->of_node, "reg", &adc->fl_id);
1122 if (ret != 0) {
1123 dev_err(dev, "Missing reg property\n");
1124 return -EINVAL;
1125 }
1126
1127 name = devm_kzalloc(dev, sizeof("dfsdm-adc0"), GFP_KERNEL);
1128 if (!name)
1129 return -ENOMEM;
1130 if (dev_data->type == DFSDM_AUDIO) {
1131 iio->info = &stm32_dfsdm_info_audio;
1132 snprintf(name, sizeof("dfsdm-pdm0"), "dfsdm-pdm%d", adc->fl_id);
1133 } else {
1134 iio->info = &stm32_dfsdm_info_adc;
1135 snprintf(name, sizeof("dfsdm-adc0"), "dfsdm-adc%d", adc->fl_id);
1136 }
1137 iio->name = name;
1138
1139 /*
1140 * In a first step IRQs generated for channels are not treated.
1141 * So IRQ associated to filter instance 0 is dedicated to the Filter 0.
1142 */
1143 irq = platform_get_irq(pdev, 0);
1144 ret = devm_request_irq(dev, irq, stm32_dfsdm_irq,
1145 0, pdev->name, adc);
1146 if (ret < 0) {
1147 dev_err(dev, "Failed to request IRQ\n");
1148 return ret;
1149 }
1150
1151 ret = of_property_read_u32(dev->of_node, "st,filter-order", &val);
1152 if (ret < 0) {
1153 dev_err(dev, "Failed to set filter order\n");
1154 return ret;
1155 }
1156
1157 adc->dfsdm->fl_list[adc->fl_id].ford = val;
1158
1159 ret = of_property_read_u32(dev->of_node, "st,filter0-sync", &val);
1160 if (!ret)
1161 adc->dfsdm->fl_list[adc->fl_id].sync_mode = val;
1162
1163 adc->dev_data = dev_data;
1164 ret = dev_data->init(iio);
1165 if (ret < 0)
1166 return ret;
1167
1168 ret = iio_device_register(iio);
1169 if (ret < 0)
1170 goto err_cleanup;
1171
1172 dev_err(dev, "of_platform_populate\n");
1173 if (dev_data->type == DFSDM_AUDIO) {
1174 ret = of_platform_populate(np, NULL, NULL, dev);
1175 if (ret < 0) {
1176 dev_err(dev, "Failed to find an audio DAI\n");
1177 goto err_unregister;
1178 }
1179 }
1180
1181 return 0;
1182
1183err_unregister:
1184 iio_device_unregister(iio);
1185err_cleanup:
1186 stm32_dfsdm_dma_release(iio);
1187
1188 return ret;
1189}
1190
1191static int stm32_dfsdm_adc_remove(struct platform_device *pdev)
1192{
1193 struct stm32_dfsdm_adc *adc = platform_get_drvdata(pdev);
1194 struct iio_dev *indio_dev = iio_priv_to_dev(adc);
1195
1196 if (adc->dev_data->type == DFSDM_AUDIO)
1197 of_platform_depopulate(&pdev->dev);
1198 iio_device_unregister(indio_dev);
1199 stm32_dfsdm_dma_release(indio_dev);
1200
1201 return 0;
1202}
1203
1204static struct platform_driver stm32_dfsdm_adc_driver = {
1205 .driver = {
1206 .name = "stm32-dfsdm-adc",
1207 .of_match_table = stm32_dfsdm_adc_match,
1208 },
1209 .probe = stm32_dfsdm_adc_probe,
1210 .remove = stm32_dfsdm_adc_remove,
1211};
1212module_platform_driver(stm32_dfsdm_adc_driver);
1213
1214MODULE_DESCRIPTION("STM32 sigma delta ADC");
1215MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
1216MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c
new file mode 100644
index 000000000000..72427414db7f
--- /dev/null
+++ b/drivers/iio/adc/stm32-dfsdm-core.c
@@ -0,0 +1,309 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * This file is part the core part STM32 DFSDM driver
4 *
5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
6 * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com> for STMicroelectronics.
7 */
8
9#include <linux/clk.h>
10#include <linux/iio/iio.h>
11#include <linux/iio/sysfs.h>
12#include <linux/interrupt.h>
13#include <linux/module.h>
14#include <linux/of_device.h>
15#include <linux/regmap.h>
16#include <linux/slab.h>
17
18#include "stm32-dfsdm.h"
19
20struct stm32_dfsdm_dev_data {
21 unsigned int num_filters;
22 unsigned int num_channels;
23 const struct regmap_config *regmap_cfg;
24};
25
26#define STM32H7_DFSDM_NUM_FILTERS 4
27#define STM32H7_DFSDM_NUM_CHANNELS 8
28
29static bool stm32_dfsdm_volatile_reg(struct device *dev, unsigned int reg)
30{
31 if (reg < DFSDM_FILTER_BASE_ADR)
32 return false;
33
34 /*
35 * Mask is done on register to avoid to list registers of all
36 * filter instances.
37 */
38 switch (reg & DFSDM_FILTER_REG_MASK) {
39 case DFSDM_CR1(0) & DFSDM_FILTER_REG_MASK:
40 case DFSDM_ISR(0) & DFSDM_FILTER_REG_MASK:
41 case DFSDM_JDATAR(0) & DFSDM_FILTER_REG_MASK:
42 case DFSDM_RDATAR(0) & DFSDM_FILTER_REG_MASK:
43 return true;
44 }
45
46 return false;
47}
48
49static const struct regmap_config stm32h7_dfsdm_regmap_cfg = {
50 .reg_bits = 32,
51 .val_bits = 32,
52 .reg_stride = sizeof(u32),
53 .max_register = 0x2B8,
54 .volatile_reg = stm32_dfsdm_volatile_reg,
55 .fast_io = true,
56};
57
58static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_data = {
59 .num_filters = STM32H7_DFSDM_NUM_FILTERS,
60 .num_channels = STM32H7_DFSDM_NUM_CHANNELS,
61 .regmap_cfg = &stm32h7_dfsdm_regmap_cfg,
62};
63
64struct dfsdm_priv {
65 struct platform_device *pdev; /* platform device */
66
67 struct stm32_dfsdm dfsdm; /* common data exported for all instances */
68
69 unsigned int spi_clk_out_div; /* SPI clkout divider value */
70 atomic_t n_active_ch; /* number of current active channels */
71
72 struct clk *clk; /* DFSDM clock */
73 struct clk *aclk; /* audio clock */
74};
75
76/**
77 * stm32_dfsdm_start_dfsdm - start global dfsdm interface.
78 *
79 * Enable interface if n_active_ch is not null.
80 * @dfsdm: Handle used to retrieve dfsdm context.
81 */
82int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm)
83{
84 struct dfsdm_priv *priv = container_of(dfsdm, struct dfsdm_priv, dfsdm);
85 struct device *dev = &priv->pdev->dev;
86 unsigned int clk_div = priv->spi_clk_out_div;
87 int ret;
88
89 if (atomic_inc_return(&priv->n_active_ch) == 1) {
90 ret = clk_prepare_enable(priv->clk);
91 if (ret < 0) {
92 dev_err(dev, "Failed to start clock\n");
93 goto error_ret;
94 }
95 if (priv->aclk) {
96 ret = clk_prepare_enable(priv->aclk);
97 if (ret < 0) {
98 dev_err(dev, "Failed to start audio clock\n");
99 goto disable_clk;
100 }
101 }
102
103 /* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */
104 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
105 DFSDM_CHCFGR1_CKOUTDIV_MASK,
106 DFSDM_CHCFGR1_CKOUTDIV(clk_div));
107 if (ret < 0)
108 goto disable_aclk;
109
110 /* Global enable of DFSDM interface */
111 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
112 DFSDM_CHCFGR1_DFSDMEN_MASK,
113 DFSDM_CHCFGR1_DFSDMEN(1));
114 if (ret < 0)
115 goto disable_aclk;
116 }
117
118 dev_dbg(dev, "%s: n_active_ch %d\n", __func__,
119 atomic_read(&priv->n_active_ch));
120
121 return 0;
122
123disable_aclk:
124 clk_disable_unprepare(priv->aclk);
125disable_clk:
126 clk_disable_unprepare(priv->clk);
127
128error_ret:
129 atomic_dec(&priv->n_active_ch);
130
131 return ret;
132}
133EXPORT_SYMBOL_GPL(stm32_dfsdm_start_dfsdm);
134
135/**
136 * stm32_dfsdm_stop_dfsdm - stop global DFSDM interface.
137 *
138 * Disable interface if n_active_ch is null
139 * @dfsdm: Handle used to retrieve dfsdm context.
140 */
141int stm32_dfsdm_stop_dfsdm(struct stm32_dfsdm *dfsdm)
142{
143 struct dfsdm_priv *priv = container_of(dfsdm, struct dfsdm_priv, dfsdm);
144 int ret;
145
146 if (atomic_dec_and_test(&priv->n_active_ch)) {
147 /* Global disable of DFSDM interface */
148 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
149 DFSDM_CHCFGR1_DFSDMEN_MASK,
150 DFSDM_CHCFGR1_DFSDMEN(0));
151 if (ret < 0)
152 return ret;
153
154 /* Stop SPI CLKOUT */
155 ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0),
156 DFSDM_CHCFGR1_CKOUTDIV_MASK,
157 DFSDM_CHCFGR1_CKOUTDIV(0));
158 if (ret < 0)
159 return ret;
160
161 clk_disable_unprepare(priv->clk);
162 if (priv->aclk)
163 clk_disable_unprepare(priv->aclk);
164 }
165 dev_dbg(&priv->pdev->dev, "%s: n_active_ch %d\n", __func__,
166 atomic_read(&priv->n_active_ch));
167
168 return 0;
169}
170EXPORT_SYMBOL_GPL(stm32_dfsdm_stop_dfsdm);
171
172static int stm32_dfsdm_parse_of(struct platform_device *pdev,
173 struct dfsdm_priv *priv)
174{
175 struct device_node *node = pdev->dev.of_node;
176 struct resource *res;
177 unsigned long clk_freq;
178 unsigned int spi_freq, rem;
179 int ret;
180
181 if (!node)
182 return -EINVAL;
183
184 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
185 if (!res) {
186 dev_err(&pdev->dev, "Failed to get memory resource\n");
187 return -ENODEV;
188 }
189 priv->dfsdm.phys_base = res->start;
190 priv->dfsdm.base = devm_ioremap_resource(&pdev->dev, res);
191
192 /*
193 * "dfsdm" clock is mandatory for DFSDM peripheral clocking.
194 * "dfsdm" or "audio" clocks can be used as source clock for
195 * the SPI clock out signal and internal processing, depending
196 * on use case.
197 */
198 priv->clk = devm_clk_get(&pdev->dev, "dfsdm");
199 if (IS_ERR(priv->clk)) {
200 dev_err(&pdev->dev, "No stm32_dfsdm_clk clock found\n");
201 return -EINVAL;
202 }
203
204 priv->aclk = devm_clk_get(&pdev->dev, "audio");
205 if (IS_ERR(priv->aclk))
206 priv->aclk = NULL;
207
208 if (priv->aclk)
209 clk_freq = clk_get_rate(priv->aclk);
210 else
211 clk_freq = clk_get_rate(priv->clk);
212
213 /* SPI clock out frequency */
214 ret = of_property_read_u32(pdev->dev.of_node, "spi-max-frequency",
215 &spi_freq);
216 if (ret < 0) {
217 /* No SPI master mode */
218 return 0;
219 }
220
221 priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem) - 1;
222 priv->dfsdm.spi_master_freq = spi_freq;
223
224 if (rem) {
225 dev_warn(&pdev->dev, "SPI clock not accurate\n");
226 dev_warn(&pdev->dev, "%ld = %d * %d + %d\n",
227 clk_freq, spi_freq, priv->spi_clk_out_div + 1, rem);
228 }
229
230 return 0;
231};
232
233static const struct of_device_id stm32_dfsdm_of_match[] = {
234 {
235 .compatible = "st,stm32h7-dfsdm",
236 .data = &stm32h7_dfsdm_data,
237 },
238 {}
239};
240MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match);
241
242static int stm32_dfsdm_probe(struct platform_device *pdev)
243{
244 struct dfsdm_priv *priv;
245 struct device_node *pnode = pdev->dev.of_node;
246 const struct of_device_id *of_id;
247 const struct stm32_dfsdm_dev_data *dev_data;
248 struct stm32_dfsdm *dfsdm;
249 int ret;
250
251 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
252 if (!priv)
253 return -ENOMEM;
254
255 priv->pdev = pdev;
256
257 of_id = of_match_node(stm32_dfsdm_of_match, pnode);
258 if (!of_id->data) {
259 dev_err(&pdev->dev, "Data associated to device is missing\n");
260 return -EINVAL;
261 }
262
263 dev_data = (const struct stm32_dfsdm_dev_data *)of_id->data;
264 dfsdm = &priv->dfsdm;
265 dfsdm->fl_list = devm_kcalloc(&pdev->dev, dev_data->num_filters,
266 sizeof(*dfsdm->fl_list), GFP_KERNEL);
267 if (!dfsdm->fl_list)
268 return -ENOMEM;
269
270 dfsdm->num_fls = dev_data->num_filters;
271 dfsdm->ch_list = devm_kcalloc(&pdev->dev, dev_data->num_channels,
272 sizeof(*dfsdm->ch_list),
273 GFP_KERNEL);
274 if (!dfsdm->ch_list)
275 return -ENOMEM;
276 dfsdm->num_chs = dev_data->num_channels;
277
278 ret = stm32_dfsdm_parse_of(pdev, priv);
279 if (ret < 0)
280 return ret;
281
282 dfsdm->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dfsdm",
283 dfsdm->base,
284 &stm32h7_dfsdm_regmap_cfg);
285 if (IS_ERR(dfsdm->regmap)) {
286 ret = PTR_ERR(dfsdm->regmap);
287 dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n",
288 __func__, ret);
289 return ret;
290 }
291
292 platform_set_drvdata(pdev, dfsdm);
293
294 return devm_of_platform_populate(&pdev->dev);
295}
296
297static struct platform_driver stm32_dfsdm_driver = {
298 .probe = stm32_dfsdm_probe,
299 .driver = {
300 .name = "stm32-dfsdm",
301 .of_match_table = stm32_dfsdm_of_match,
302 },
303};
304
305module_platform_driver(stm32_dfsdm_driver);
306
307MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
308MODULE_DESCRIPTION("STMicroelectronics STM32 dfsdm driver");
309MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/stm32-dfsdm.h b/drivers/iio/adc/stm32-dfsdm.h
new file mode 100644
index 000000000000..8708394b0725
--- /dev/null
+++ b/drivers/iio/adc/stm32-dfsdm.h
@@ -0,0 +1,310 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * This file is part of STM32 DFSDM driver
4 *
5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
6 * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com>.
7 */
8
9#ifndef MDF_STM32_DFSDM__H
10#define MDF_STM32_DFSDM__H
11
12#include <linux/bitfield.h>
13
14/*
15 * STM32 DFSDM - global register map
16 * ________________________________________________________
17 * | Offset | Registers block |
18 * --------------------------------------------------------
19 * | 0x000 | CHANNEL 0 + COMMON CHANNEL FIELDS |
20 * --------------------------------------------------------
21 * | 0x020 | CHANNEL 1 |
22 * --------------------------------------------------------
23 * | ... | ..... |
24 * --------------------------------------------------------
25 * | 0x0E0 | CHANNEL 7 |
26 * --------------------------------------------------------
27 * | 0x100 | FILTER 0 + COMMON FILTER FIELDs |
28 * --------------------------------------------------------
29 * | 0x200 | FILTER 1 |
30 * --------------------------------------------------------
31 * | 0x300 | FILTER 2 |
32 * --------------------------------------------------------
33 * | 0x400 | FILTER 3 |
34 * --------------------------------------------------------
35 */
36
37/*
38 * Channels register definitions
39 */
40#define DFSDM_CHCFGR1(y) ((y) * 0x20 + 0x00)
41#define DFSDM_CHCFGR2(y) ((y) * 0x20 + 0x04)
42#define DFSDM_AWSCDR(y) ((y) * 0x20 + 0x08)
43#define DFSDM_CHWDATR(y) ((y) * 0x20 + 0x0C)
44#define DFSDM_CHDATINR(y) ((y) * 0x20 + 0x10)
45
46/* CHCFGR1: Channel configuration register 1 */
47#define DFSDM_CHCFGR1_SITP_MASK GENMASK(1, 0)
48#define DFSDM_CHCFGR1_SITP(v) FIELD_PREP(DFSDM_CHCFGR1_SITP_MASK, v)
49#define DFSDM_CHCFGR1_SPICKSEL_MASK GENMASK(3, 2)
50#define DFSDM_CHCFGR1_SPICKSEL(v) FIELD_PREP(DFSDM_CHCFGR1_SPICKSEL_MASK, v)
51#define DFSDM_CHCFGR1_SCDEN_MASK BIT(5)
52#define DFSDM_CHCFGR1_SCDEN(v) FIELD_PREP(DFSDM_CHCFGR1_SCDEN_MASK, v)
53#define DFSDM_CHCFGR1_CKABEN_MASK BIT(6)
54#define DFSDM_CHCFGR1_CKABEN(v) FIELD_PREP(DFSDM_CHCFGR1_CKABEN_MASK, v)
55#define DFSDM_CHCFGR1_CHEN_MASK BIT(7)
56#define DFSDM_CHCFGR1_CHEN(v) FIELD_PREP(DFSDM_CHCFGR1_CHEN_MASK, v)
57#define DFSDM_CHCFGR1_CHINSEL_MASK BIT(8)
58#define DFSDM_CHCFGR1_CHINSEL(v) FIELD_PREP(DFSDM_CHCFGR1_CHINSEL_MASK, v)
59#define DFSDM_CHCFGR1_DATMPX_MASK GENMASK(13, 12)
60#define DFSDM_CHCFGR1_DATMPX(v) FIELD_PREP(DFSDM_CHCFGR1_DATMPX_MASK, v)
61#define DFSDM_CHCFGR1_DATPACK_MASK GENMASK(15, 14)
62#define DFSDM_CHCFGR1_DATPACK(v) FIELD_PREP(DFSDM_CHCFGR1_DATPACK_MASK, v)
63#define DFSDM_CHCFGR1_CKOUTDIV_MASK GENMASK(23, 16)
64#define DFSDM_CHCFGR1_CKOUTDIV(v) FIELD_PREP(DFSDM_CHCFGR1_CKOUTDIV_MASK, v)
65#define DFSDM_CHCFGR1_CKOUTSRC_MASK BIT(30)
66#define DFSDM_CHCFGR1_CKOUTSRC(v) FIELD_PREP(DFSDM_CHCFGR1_CKOUTSRC_MASK, v)
67#define DFSDM_CHCFGR1_DFSDMEN_MASK BIT(31)
68#define DFSDM_CHCFGR1_DFSDMEN(v) FIELD_PREP(DFSDM_CHCFGR1_DFSDMEN_MASK, v)
69
70/* CHCFGR2: Channel configuration register 2 */
71#define DFSDM_CHCFGR2_DTRBS_MASK GENMASK(7, 3)
72#define DFSDM_CHCFGR2_DTRBS(v) FIELD_PREP(DFSDM_CHCFGR2_DTRBS_MASK, v)
73#define DFSDM_CHCFGR2_OFFSET_MASK GENMASK(31, 8)
74#define DFSDM_CHCFGR2_OFFSET(v) FIELD_PREP(DFSDM_CHCFGR2_OFFSET_MASK, v)
75
76/* AWSCDR: Channel analog watchdog and short circuit detector */
77#define DFSDM_AWSCDR_SCDT_MASK GENMASK(7, 0)
78#define DFSDM_AWSCDR_SCDT(v) FIELD_PREP(DFSDM_AWSCDR_SCDT_MASK, v)
79#define DFSDM_AWSCDR_BKSCD_MASK GENMASK(15, 12)
80#define DFSDM_AWSCDR_BKSCD(v) FIELD_PREP(DFSDM_AWSCDR_BKSCD_MASK, v)
81#define DFSDM_AWSCDR_AWFOSR_MASK GENMASK(20, 16)
82#define DFSDM_AWSCDR_AWFOSR(v) FIELD_PREP(DFSDM_AWSCDR_AWFOSR_MASK, v)
83#define DFSDM_AWSCDR_AWFORD_MASK GENMASK(23, 22)
84#define DFSDM_AWSCDR_AWFORD(v) FIELD_PREP(DFSDM_AWSCDR_AWFORD_MASK, v)
85
86/*
87 * Filters register definitions
88 */
89#define DFSDM_FILTER_BASE_ADR 0x100
90#define DFSDM_FILTER_REG_MASK 0x7F
91#define DFSDM_FILTER_X_BASE_ADR(x) ((x) * 0x80 + DFSDM_FILTER_BASE_ADR)
92
93#define DFSDM_CR1(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x00)
94#define DFSDM_CR2(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x04)
95#define DFSDM_ISR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x08)
96#define DFSDM_ICR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x0C)
97#define DFSDM_JCHGR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x10)
98#define DFSDM_FCR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x14)
99#define DFSDM_JDATAR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x18)
100#define DFSDM_RDATAR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x1C)
101#define DFSDM_AWHTR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x20)
102#define DFSDM_AWLTR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x24)
103#define DFSDM_AWSR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x28)
104#define DFSDM_AWCFR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x2C)
105#define DFSDM_EXMAX(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x30)
106#define DFSDM_EXMIN(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x34)
107#define DFSDM_CNVTIMR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x38)
108
109/* CR1 Control register 1 */
110#define DFSDM_CR1_DFEN_MASK BIT(0)
111#define DFSDM_CR1_DFEN(v) FIELD_PREP(DFSDM_CR1_DFEN_MASK, v)
112#define DFSDM_CR1_JSWSTART_MASK BIT(1)
113#define DFSDM_CR1_JSWSTART(v) FIELD_PREP(DFSDM_CR1_JSWSTART_MASK, v)
114#define DFSDM_CR1_JSYNC_MASK BIT(3)
115#define DFSDM_CR1_JSYNC(v) FIELD_PREP(DFSDM_CR1_JSYNC_MASK, v)
116#define DFSDM_CR1_JSCAN_MASK BIT(4)
117#define DFSDM_CR1_JSCAN(v) FIELD_PREP(DFSDM_CR1_JSCAN_MASK, v)
118#define DFSDM_CR1_JDMAEN_MASK BIT(5)
119#define DFSDM_CR1_JDMAEN(v) FIELD_PREP(DFSDM_CR1_JDMAEN_MASK, v)
120#define DFSDM_CR1_JEXTSEL_MASK GENMASK(12, 8)
121#define DFSDM_CR1_JEXTSEL(v) FIELD_PREP(DFSDM_CR1_JEXTSEL_MASK, v)
122#define DFSDM_CR1_JEXTEN_MASK GENMASK(14, 13)
123#define DFSDM_CR1_JEXTEN(v) FIELD_PREP(DFSDM_CR1_JEXTEN_MASK, v)
124#define DFSDM_CR1_RSWSTART_MASK BIT(17)
125#define DFSDM_CR1_RSWSTART(v) FIELD_PREP(DFSDM_CR1_RSWSTART_MASK, v)
126#define DFSDM_CR1_RCONT_MASK BIT(18)
127#define DFSDM_CR1_RCONT(v) FIELD_PREP(DFSDM_CR1_RCONT_MASK, v)
128#define DFSDM_CR1_RSYNC_MASK BIT(19)
129#define DFSDM_CR1_RSYNC(v) FIELD_PREP(DFSDM_CR1_RSYNC_MASK, v)
130#define DFSDM_CR1_RDMAEN_MASK BIT(21)
131#define DFSDM_CR1_RDMAEN(v) FIELD_PREP(DFSDM_CR1_RDMAEN_MASK, v)
132#define DFSDM_CR1_RCH_MASK GENMASK(26, 24)
133#define DFSDM_CR1_RCH(v) FIELD_PREP(DFSDM_CR1_RCH_MASK, v)
134#define DFSDM_CR1_FAST_MASK BIT(29)
135#define DFSDM_CR1_FAST(v) FIELD_PREP(DFSDM_CR1_FAST_MASK, v)
136#define DFSDM_CR1_AWFSEL_MASK BIT(30)
137#define DFSDM_CR1_AWFSEL(v) FIELD_PREP(DFSDM_CR1_AWFSEL_MASK, v)
138
139/* CR2: Control register 2 */
140#define DFSDM_CR2_IE_MASK GENMASK(6, 0)
141#define DFSDM_CR2_IE(v) FIELD_PREP(DFSDM_CR2_IE_MASK, v)
142#define DFSDM_CR2_JEOCIE_MASK BIT(0)
143#define DFSDM_CR2_JEOCIE(v) FIELD_PREP(DFSDM_CR2_JEOCIE_MASK, v)
144#define DFSDM_CR2_REOCIE_MASK BIT(1)
145#define DFSDM_CR2_REOCIE(v) FIELD_PREP(DFSDM_CR2_REOCIE_MASK, v)
146#define DFSDM_CR2_JOVRIE_MASK BIT(2)
147#define DFSDM_CR2_JOVRIE(v) FIELD_PREP(DFSDM_CR2_JOVRIE_MASK, v)
148#define DFSDM_CR2_ROVRIE_MASK BIT(3)
149#define DFSDM_CR2_ROVRIE(v) FIELD_PREP(DFSDM_CR2_ROVRIE_MASK, v)
150#define DFSDM_CR2_AWDIE_MASK BIT(4)
151#define DFSDM_CR2_AWDIE(v) FIELD_PREP(DFSDM_CR2_AWDIE_MASK, v)
152#define DFSDM_CR2_SCDIE_MASK BIT(5)
153#define DFSDM_CR2_SCDIE(v) FIELD_PREP(DFSDM_CR2_SCDIE_MASK, v)
154#define DFSDM_CR2_CKABIE_MASK BIT(6)
155#define DFSDM_CR2_CKABIE(v) FIELD_PREP(DFSDM_CR2_CKABIE_MASK, v)
156#define DFSDM_CR2_EXCH_MASK GENMASK(15, 8)
157#define DFSDM_CR2_EXCH(v) FIELD_PREP(DFSDM_CR2_EXCH_MASK, v)
158#define DFSDM_CR2_AWDCH_MASK GENMASK(23, 16)
159#define DFSDM_CR2_AWDCH(v) FIELD_PREP(DFSDM_CR2_AWDCH_MASK, v)
160
161/* ISR: Interrupt status register */
162#define DFSDM_ISR_JEOCF_MASK BIT(0)
163#define DFSDM_ISR_JEOCF(v) FIELD_PREP(DFSDM_ISR_JEOCF_MASK, v)
164#define DFSDM_ISR_REOCF_MASK BIT(1)
165#define DFSDM_ISR_REOCF(v) FIELD_PREP(DFSDM_ISR_REOCF_MASK, v)
166#define DFSDM_ISR_JOVRF_MASK BIT(2)
167#define DFSDM_ISR_JOVRF(v) FIELD_PREP(DFSDM_ISR_JOVRF_MASK, v)
168#define DFSDM_ISR_ROVRF_MASK BIT(3)
169#define DFSDM_ISR_ROVRF(v) FIELD_PREP(DFSDM_ISR_ROVRF_MASK, v)
170#define DFSDM_ISR_AWDF_MASK BIT(4)
171#define DFSDM_ISR_AWDF(v) FIELD_PREP(DFSDM_ISR_AWDF_MASK, v)
172#define DFSDM_ISR_JCIP_MASK BIT(13)
173#define DFSDM_ISR_JCIP(v) FIELD_PREP(DFSDM_ISR_JCIP_MASK, v)
174#define DFSDM_ISR_RCIP_MASK BIT(14)
175#define DFSDM_ISR_RCIP(v) FIELD_PREP(DFSDM_ISR_RCIP, v)
176#define DFSDM_ISR_CKABF_MASK GENMASK(23, 16)
177#define DFSDM_ISR_CKABF(v) FIELD_PREP(DFSDM_ISR_CKABF_MASK, v)
178#define DFSDM_ISR_SCDF_MASK GENMASK(31, 24)
179#define DFSDM_ISR_SCDF(v) FIELD_PREP(DFSDM_ISR_SCDF_MASK, v)
180
181/* ICR: Interrupt flag clear register */
182#define DFSDM_ICR_CLRJOVRF_MASK BIT(2)
183#define DFSDM_ICR_CLRJOVRF(v) FIELD_PREP(DFSDM_ICR_CLRJOVRF_MASK, v)
184#define DFSDM_ICR_CLRROVRF_MASK BIT(3)
185#define DFSDM_ICR_CLRROVRF(v) FIELD_PREP(DFSDM_ICR_CLRROVRF_MASK, v)
186#define DFSDM_ICR_CLRCKABF_MASK GENMASK(23, 16)
187#define DFSDM_ICR_CLRCKABF(v) FIELD_PREP(DFSDM_ICR_CLRCKABF_MASK, v)
188#define DFSDM_ICR_CLRCKABF_CH_MASK(y) BIT(16 + (y))
189#define DFSDM_ICR_CLRCKABF_CH(v, y) \
190 (((v) << (16 + (y))) & DFSDM_ICR_CLRCKABF_CH_MASK(y))
191#define DFSDM_ICR_CLRSCDF_MASK GENMASK(31, 24)
192#define DFSDM_ICR_CLRSCDF(v) FIELD_PREP(DFSDM_ICR_CLRSCDF_MASK, v)
193#define DFSDM_ICR_CLRSCDF_CH_MASK(y) BIT(24 + (y))
194#define DFSDM_ICR_CLRSCDF_CH(v, y) \
195 (((v) << (24 + (y))) & DFSDM_ICR_CLRSCDF_MASK(y))
196
197/* FCR: Filter control register */
198#define DFSDM_FCR_IOSR_MASK GENMASK(7, 0)
199#define DFSDM_FCR_IOSR(v) FIELD_PREP(DFSDM_FCR_IOSR_MASK, v)
200#define DFSDM_FCR_FOSR_MASK GENMASK(25, 16)
201#define DFSDM_FCR_FOSR(v) FIELD_PREP(DFSDM_FCR_FOSR_MASK, v)
202#define DFSDM_FCR_FORD_MASK GENMASK(31, 29)
203#define DFSDM_FCR_FORD(v) FIELD_PREP(DFSDM_FCR_FORD_MASK, v)
204
205/* RDATAR: Filter data register for regular channel */
206#define DFSDM_DATAR_CH_MASK GENMASK(2, 0)
207#define DFSDM_DATAR_DATA_OFFSET 8
208#define DFSDM_DATAR_DATA_MASK GENMASK(31, DFSDM_DATAR_DATA_OFFSET)
209
210/* AWLTR: Filter analog watchdog low threshold register */
211#define DFSDM_AWLTR_BKAWL_MASK GENMASK(3, 0)
212#define DFSDM_AWLTR_BKAWL(v) FIELD_PREP(DFSDM_AWLTR_BKAWL_MASK, v)
213#define DFSDM_AWLTR_AWLT_MASK GENMASK(31, 8)
214#define DFSDM_AWLTR_AWLT(v) FIELD_PREP(DFSDM_AWLTR_AWLT_MASK, v)
215
216/* AWHTR: Filter analog watchdog low threshold register */
217#define DFSDM_AWHTR_BKAWH_MASK GENMASK(3, 0)
218#define DFSDM_AWHTR_BKAWH(v) FIELD_PREP(DFSDM_AWHTR_BKAWH_MASK, v)
219#define DFSDM_AWHTR_AWHT_MASK GENMASK(31, 8)
220#define DFSDM_AWHTR_AWHT(v) FIELD_PREP(DFSDM_AWHTR_AWHT_MASK, v)
221
222/* AWSR: Filter watchdog status register */
223#define DFSDM_AWSR_AWLTF_MASK GENMASK(7, 0)
224#define DFSDM_AWSR_AWLTF(v) FIELD_PREP(DFSDM_AWSR_AWLTF_MASK, v)
225#define DFSDM_AWSR_AWHTF_MASK GENMASK(15, 8)
226#define DFSDM_AWSR_AWHTF(v) FIELD_PREP(DFSDM_AWSR_AWHTF_MASK, v)
227
228/* AWCFR: Filter watchdog status register */
229#define DFSDM_AWCFR_AWLTF_MASK GENMASK(7, 0)
230#define DFSDM_AWCFR_AWLTF(v) FIELD_PREP(DFSDM_AWCFR_AWLTF_MASK, v)
231#define DFSDM_AWCFR_AWHTF_MASK GENMASK(15, 8)
232#define DFSDM_AWCFR_AWHTF(v) FIELD_PREP(DFSDM_AWCFR_AWHTF_MASK, v)
233
234/* DFSDM filter order */
235enum stm32_dfsdm_sinc_order {
236 DFSDM_FASTSINC_ORDER, /* FastSinc filter type */
237 DFSDM_SINC1_ORDER, /* Sinc 1 filter type */
238 DFSDM_SINC2_ORDER, /* Sinc 2 filter type */
239 DFSDM_SINC3_ORDER, /* Sinc 3 filter type */
240 DFSDM_SINC4_ORDER, /* Sinc 4 filter type (N.A. for watchdog) */
241 DFSDM_SINC5_ORDER, /* Sinc 5 filter type (N.A. for watchdog) */
242 DFSDM_NB_SINC_ORDER,
243};
244
245/**
246 * struct stm32_dfsdm_filter - structure relative to stm32 FDSDM filter
247 * @iosr: integrator oversampling
248 * @fosr: filter oversampling
249 * @ford: filter order
250 * @res: output sample resolution
251 * @sync_mode: filter synchronized with filter 0
252 * @fast: filter fast mode
253 */
254struct stm32_dfsdm_filter {
255 unsigned int iosr;
256 unsigned int fosr;
257 enum stm32_dfsdm_sinc_order ford;
258 u64 res;
259 unsigned int sync_mode;
260 unsigned int fast;
261};
262
263/**
264 * struct stm32_dfsdm_channel - structure relative to stm32 FDSDM channel
265 * @id: id of the channel
266 * @type: interface type linked to stm32_dfsdm_chan_type
267 * @src: interface type linked to stm32_dfsdm_chan_src
268 * @alt_si: alternative serial input interface
269 */
270struct stm32_dfsdm_channel {
271 unsigned int id;
272 unsigned int type;
273 unsigned int src;
274 unsigned int alt_si;
275};
276
277/**
278 * struct stm32_dfsdm - stm32 FDSDM driver common data (for all instances)
279 * @base: control registers base cpu addr
280 * @phys_base: DFSDM IP register physical address
281 * @regmap: regmap for register read/write
282 * @fl_list: filter resources list
283 * @num_fls: number of filter resources available
284 * @ch_list: channel resources list
285 * @num_chs: number of channel resources available
286 * @spi_master_freq: SPI clock out frequency
287 */
288struct stm32_dfsdm {
289 void __iomem *base;
290 phys_addr_t phys_base;
291 struct regmap *regmap;
292 struct stm32_dfsdm_filter *fl_list;
293 unsigned int num_fls;
294 struct stm32_dfsdm_channel *ch_list;
295 unsigned int num_chs;
296 unsigned int spi_master_freq;
297};
298
299/* DFSDM channel serial spi clock source */
300enum stm32_dfsdm_spi_clk_src {
301 DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL,
302 DFSDM_CHANNEL_SPI_CLOCK_INTERNAL,
303 DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING,
304 DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING
305};
306
307int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm);
308int stm32_dfsdm_stop_dfsdm(struct stm32_dfsdm *dfsdm);
309
310#endif
diff --git a/drivers/iio/buffer/Kconfig b/drivers/iio/buffer/Kconfig
index 4ffd3db7817f..338774cba19b 100644
--- a/drivers/iio/buffer/Kconfig
+++ b/drivers/iio/buffer/Kconfig
@@ -29,6 +29,16 @@ config IIO_BUFFER_DMAENGINE
29 29
30 Should be selected by drivers that want to use this functionality. 30 Should be selected by drivers that want to use this functionality.
31 31
32config IIO_BUFFER_HW_CONSUMER
33 tristate "Industrial I/O HW buffering"
34 help
35 Provides a way to bonding when an IIO device has a direct connection
36 to another device in hardware. In this case buffers for data transfers
37 are handled by hardware.
38
39 Should be selected by drivers that want to use the generic Hw consumer
40 interface.
41
32config IIO_KFIFO_BUF 42config IIO_KFIFO_BUF
33 tristate "Industrial I/O buffering based on kfifo" 43 tristate "Industrial I/O buffering based on kfifo"
34 help 44 help
diff --git a/drivers/iio/buffer/Makefile b/drivers/iio/buffer/Makefile
index 95f9f41c58b7..1403eb2f9409 100644
--- a/drivers/iio/buffer/Makefile
+++ b/drivers/iio/buffer/Makefile
@@ -7,5 +7,6 @@
7obj-$(CONFIG_IIO_BUFFER_CB) += industrialio-buffer-cb.o 7obj-$(CONFIG_IIO_BUFFER_CB) += industrialio-buffer-cb.o
8obj-$(CONFIG_IIO_BUFFER_DMA) += industrialio-buffer-dma.o 8obj-$(CONFIG_IIO_BUFFER_DMA) += industrialio-buffer-dma.o
9obj-$(CONFIG_IIO_BUFFER_DMAENGINE) += industrialio-buffer-dmaengine.o 9obj-$(CONFIG_IIO_BUFFER_DMAENGINE) += industrialio-buffer-dmaengine.o
10obj-$(CONFIG_IIO_BUFFER_HW_CONSUMER) += industrialio-hw-consumer.o
10obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o 11obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o
11obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o 12obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c
index 4847534700e7..ea63c838eeae 100644
--- a/drivers/iio/buffer/industrialio-buffer-cb.c
+++ b/drivers/iio/buffer/industrialio-buffer-cb.c
@@ -104,6 +104,17 @@ error_free_cb_buff:
104} 104}
105EXPORT_SYMBOL_GPL(iio_channel_get_all_cb); 105EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
106 106
107int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer *cb_buff,
108 size_t watermark)
109{
110 if (!watermark)
111 return -EINVAL;
112 cb_buff->buffer.watermark = watermark;
113
114 return 0;
115}
116EXPORT_SYMBOL_GPL(iio_channel_cb_set_buffer_watermark);
117
107int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff) 118int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)
108{ 119{
109 return iio_update_buffers(cb_buff->indio_dev, &cb_buff->buffer, 120 return iio_update_buffers(cb_buff->indio_dev, &cb_buff->buffer,
diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c
new file mode 100644
index 000000000000..95165697d8ae
--- /dev/null
+++ b/drivers/iio/buffer/industrialio-hw-consumer.c
@@ -0,0 +1,247 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2017 Analog Devices Inc.
4 * Author: Lars-Peter Clausen <lars@metafoo.de>
5 */
6
7#include <linux/err.h>
8#include <linux/export.h>
9#include <linux/slab.h>
10#include <linux/module.h>
11
12#include <linux/iio/iio.h>
13#include <linux/iio/consumer.h>
14#include <linux/iio/hw-consumer.h>
15#include <linux/iio/buffer_impl.h>
16
17/**
18 * struct iio_hw_consumer - IIO hw consumer block
19 * @buffers: hardware buffers list head.
20 * @channels: IIO provider channels.
21 */
22struct iio_hw_consumer {
23 struct list_head buffers;
24 struct iio_channel *channels;
25};
26
27struct hw_consumer_buffer {
28 struct list_head head;
29 struct iio_dev *indio_dev;
30 struct iio_buffer buffer;
31 long scan_mask[];
32};
33
34static struct hw_consumer_buffer *iio_buffer_to_hw_consumer_buffer(
35 struct iio_buffer *buffer)
36{
37 return container_of(buffer, struct hw_consumer_buffer, buffer);
38}
39
40static void iio_hw_buf_release(struct iio_buffer *buffer)
41{
42 struct hw_consumer_buffer *hw_buf =
43 iio_buffer_to_hw_consumer_buffer(buffer);
44 kfree(hw_buf);
45}
46
47static const struct iio_buffer_access_funcs iio_hw_buf_access = {
48 .release = &iio_hw_buf_release,
49 .modes = INDIO_BUFFER_HARDWARE,
50};
51
52static struct hw_consumer_buffer *iio_hw_consumer_get_buffer(
53 struct iio_hw_consumer *hwc, struct iio_dev *indio_dev)
54{
55 size_t mask_size = BITS_TO_LONGS(indio_dev->masklength) * sizeof(long);
56 struct hw_consumer_buffer *buf;
57
58 list_for_each_entry(buf, &hwc->buffers, head) {
59 if (buf->indio_dev == indio_dev)
60 return buf;
61 }
62
63 buf = kzalloc(sizeof(*buf) + mask_size, GFP_KERNEL);
64 if (!buf)
65 return NULL;
66
67 buf->buffer.access = &iio_hw_buf_access;
68 buf->indio_dev = indio_dev;
69 buf->buffer.scan_mask = buf->scan_mask;
70
71 iio_buffer_init(&buf->buffer);
72 list_add_tail(&buf->head, &hwc->buffers);
73
74 return buf;
75}
76
77/**
78 * iio_hw_consumer_alloc() - Allocate IIO hardware consumer
79 * @dev: Pointer to consumer device.
80 *
81 * Returns a valid iio_hw_consumer on success or a ERR_PTR() on failure.
82 */
83struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev)
84{
85 struct hw_consumer_buffer *buf;
86 struct iio_hw_consumer *hwc;
87 struct iio_channel *chan;
88 int ret;
89
90 hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
91 if (!hwc)
92 return ERR_PTR(-ENOMEM);
93
94 INIT_LIST_HEAD(&hwc->buffers);
95
96 hwc->channels = iio_channel_get_all(dev);
97 if (IS_ERR(hwc->channels)) {
98 ret = PTR_ERR(hwc->channels);
99 goto err_free_hwc;
100 }
101
102 chan = &hwc->channels[0];
103 while (chan->indio_dev) {
104 buf = iio_hw_consumer_get_buffer(hwc, chan->indio_dev);
105 if (!buf) {
106 ret = -ENOMEM;
107 goto err_put_buffers;
108 }
109 set_bit(chan->channel->scan_index, buf->buffer.scan_mask);
110 chan++;
111 }
112
113 return hwc;
114
115err_put_buffers:
116 list_for_each_entry(buf, &hwc->buffers, head)
117 iio_buffer_put(&buf->buffer);
118 iio_channel_release_all(hwc->channels);
119err_free_hwc:
120 kfree(hwc);
121 return ERR_PTR(ret);
122}
123EXPORT_SYMBOL_GPL(iio_hw_consumer_alloc);
124
125/**
126 * iio_hw_consumer_free() - Free IIO hardware consumer
127 * @hwc: hw consumer to free.
128 */
129void iio_hw_consumer_free(struct iio_hw_consumer *hwc)
130{
131 struct hw_consumer_buffer *buf, *n;
132
133 iio_channel_release_all(hwc->channels);
134 list_for_each_entry_safe(buf, n, &hwc->buffers, head)
135 iio_buffer_put(&buf->buffer);
136 kfree(hwc);
137}
138EXPORT_SYMBOL_GPL(iio_hw_consumer_free);
139
140static void devm_iio_hw_consumer_release(struct device *dev, void *res)
141{
142 iio_hw_consumer_free(*(struct iio_hw_consumer **)res);
143}
144
145static int devm_iio_hw_consumer_match(struct device *dev, void *res, void *data)
146{
147 struct iio_hw_consumer **r = res;
148
149 if (!r || !*r) {
150 WARN_ON(!r || !*r);
151 return 0;
152 }
153 return *r == data;
154}
155
156/**
157 * devm_iio_hw_consumer_alloc - Resource-managed iio_hw_consumer_alloc()
158 * @dev: Pointer to consumer device.
159 *
160 * Managed iio_hw_consumer_alloc. iio_hw_consumer allocated with this function
161 * is automatically freed on driver detach.
162 *
163 * If an iio_hw_consumer allocated with this function needs to be freed
164 * separately, devm_iio_hw_consumer_free() must be used.
165 *
166 * returns pointer to allocated iio_hw_consumer on success, NULL on failure.
167 */
168struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev)
169{
170 struct iio_hw_consumer **ptr, *iio_hwc;
171
172 ptr = devres_alloc(devm_iio_hw_consumer_release, sizeof(*ptr),
173 GFP_KERNEL);
174 if (!ptr)
175 return NULL;
176
177 iio_hwc = iio_hw_consumer_alloc(dev);
178 if (IS_ERR(iio_hwc)) {
179 devres_free(ptr);
180 } else {
181 *ptr = iio_hwc;
182 devres_add(dev, ptr);
183 }
184
185 return iio_hwc;
186}
187EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_alloc);
188
189/**
190 * devm_iio_hw_consumer_free - Resource-managed iio_hw_consumer_free()
191 * @dev: Pointer to consumer device.
192 * @hwc: iio_hw_consumer to free.
193 *
194 * Free iio_hw_consumer allocated with devm_iio_hw_consumer_alloc().
195 */
196void devm_iio_hw_consumer_free(struct device *dev, struct iio_hw_consumer *hwc)
197{
198 int rc;
199
200 rc = devres_release(dev, devm_iio_hw_consumer_release,
201 devm_iio_hw_consumer_match, hwc);
202 WARN_ON(rc);
203}
204EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_free);
205
206/**
207 * iio_hw_consumer_enable() - Enable IIO hardware consumer
208 * @hwc: iio_hw_consumer to enable.
209 *
210 * Returns 0 on success.
211 */
212int iio_hw_consumer_enable(struct iio_hw_consumer *hwc)
213{
214 struct hw_consumer_buffer *buf;
215 int ret;
216
217 list_for_each_entry(buf, &hwc->buffers, head) {
218 ret = iio_update_buffers(buf->indio_dev, &buf->buffer, NULL);
219 if (ret)
220 goto err_disable_buffers;
221 }
222
223 return 0;
224
225err_disable_buffers:
226 list_for_each_entry_continue_reverse(buf, &hwc->buffers, head)
227 iio_update_buffers(buf->indio_dev, NULL, &buf->buffer);
228 return ret;
229}
230EXPORT_SYMBOL_GPL(iio_hw_consumer_enable);
231
232/**
233 * iio_hw_consumer_disable() - Disable IIO hardware consumer
234 * @hwc: iio_hw_consumer to disable.
235 */
236void iio_hw_consumer_disable(struct iio_hw_consumer *hwc)
237{
238 struct hw_consumer_buffer *buf;
239
240 list_for_each_entry(buf, &hwc->buffers, head)
241 iio_update_buffers(buf->indio_dev, NULL, &buf->buffer);
242}
243EXPORT_SYMBOL_GPL(iio_hw_consumer_disable);
244
245MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
246MODULE_DESCRIPTION("Hardware consumer buffer the IIO framework");
247MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 069defcc6d9b..ec98790e2a28 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -664,9 +664,8 @@ err_unlock:
664} 664}
665EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed); 665EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
666 666
667static int iio_read_channel_attribute(struct iio_channel *chan, 667int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
668 int *val, int *val2, 668 enum iio_chan_info_enum attribute)
669 enum iio_chan_info_enum attribute)
670{ 669{
671 int ret; 670 int ret;
672 671
@@ -682,6 +681,7 @@ err_unlock:
682 681
683 return ret; 682 return ret;
684} 683}
684EXPORT_SYMBOL_GPL(iio_read_channel_attribute);
685 685
686int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2) 686int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2)
687{ 687{
@@ -850,7 +850,8 @@ static int iio_channel_write(struct iio_channel *chan, int val, int val2,
850 chan->channel, val, val2, info); 850 chan->channel, val, val2, info);
851} 851}
852 852
853int iio_write_channel_raw(struct iio_channel *chan, int val) 853int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,
854 enum iio_chan_info_enum attribute)
854{ 855{
855 int ret; 856 int ret;
856 857
@@ -860,12 +861,18 @@ int iio_write_channel_raw(struct iio_channel *chan, int val)
860 goto err_unlock; 861 goto err_unlock;
861 } 862 }
862 863
863 ret = iio_channel_write(chan, val, 0, IIO_CHAN_INFO_RAW); 864 ret = iio_channel_write(chan, val, val2, attribute);
864err_unlock: 865err_unlock:
865 mutex_unlock(&chan->indio_dev->info_exist_lock); 866 mutex_unlock(&chan->indio_dev->info_exist_lock);
866 867
867 return ret; 868 return ret;
868} 869}
870EXPORT_SYMBOL_GPL(iio_write_channel_attribute);
871
872int iio_write_channel_raw(struct iio_channel *chan, int val)
873{
874 return iio_write_channel_attribute(chan, val, 0, IIO_CHAN_INFO_RAW);
875}
869EXPORT_SYMBOL_GPL(iio_write_channel_raw); 876EXPORT_SYMBOL_GPL(iio_write_channel_raw);
870 877
871unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan) 878unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan)
diff --git a/include/linux/iio/adc/stm32-dfsdm-adc.h b/include/linux/iio/adc/stm32-dfsdm-adc.h
new file mode 100644
index 000000000000..e7dc7a542a4e
--- /dev/null
+++ b/include/linux/iio/adc/stm32-dfsdm-adc.h
@@ -0,0 +1,18 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * This file discribe the STM32 DFSDM IIO driver API for audio part
4 *
5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
6 * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com>.
7 */
8
9#ifndef STM32_DFSDM_ADC_H
10#define STM32_DFSDM_ADC_H
11
12int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev,
13 int (*cb)(const void *data, size_t size,
14 void *private),
15 void *private);
16int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev);
17
18#endif
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 5e347a9805fd..9887f4f8e2a8 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -134,6 +134,17 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
134 void *private), 134 void *private),
135 void *private); 135 void *private);
136/** 136/**
137 * iio_channel_cb_set_buffer_watermark() - set the buffer watermark.
138 * @cb_buffer: The callback buffer from whom we want the channel
139 * information.
140 * @watermark: buffer watermark in bytes.
141 *
142 * This function allows to configure the buffer watermark.
143 */
144int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer *cb_buffer,
145 size_t watermark);
146
147/**
137 * iio_channel_release_all_cb() - release and unregister the callback. 148 * iio_channel_release_all_cb() - release and unregister the callback.
138 * @cb_buffer: The callback buffer that was allocated. 149 * @cb_buffer: The callback buffer that was allocated.
139 */ 150 */
@@ -216,6 +227,32 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
216int iio_read_channel_processed(struct iio_channel *chan, int *val); 227int iio_read_channel_processed(struct iio_channel *chan, int *val);
217 228
218/** 229/**
230 * iio_write_channel_attribute() - Write values to the device attribute.
231 * @chan: The channel being queried.
232 * @val: Value being written.
233 * @val2: Value being written.val2 use depends on attribute type.
234 * @attribute: info attribute to be read.
235 *
236 * Returns an error code or 0.
237 */
238int iio_write_channel_attribute(struct iio_channel *chan, int val,
239 int val2, enum iio_chan_info_enum attribute);
240
241/**
242 * iio_read_channel_attribute() - Read values from the device attribute.
243 * @chan: The channel being queried.
244 * @val: Value being written.
245 * @val2: Value being written.Val2 use depends on attribute type.
246 * @attribute: info attribute to be written.
247 *
248 * Returns an error code if failed. Else returns a description of what is in val
249 * and val2, such as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val
250 * + val2/1e6
251 */
252int iio_read_channel_attribute(struct iio_channel *chan, int *val,
253 int *val2, enum iio_chan_info_enum attribute);
254
255/**
219 * iio_write_channel_raw() - write to a given channel 256 * iio_write_channel_raw() - write to a given channel
220 * @chan: The channel being queried. 257 * @chan: The channel being queried.
221 * @val: Value being written. 258 * @val: Value being written.
diff --git a/include/linux/iio/hw-consumer.h b/include/linux/iio/hw-consumer.h
new file mode 100644
index 000000000000..44d48bb1d39f
--- /dev/null
+++ b/include/linux/iio/hw-consumer.h
@@ -0,0 +1,21 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Industrial I/O in kernel hardware consumer interface
4 *
5 * Copyright 2017 Analog Devices Inc.
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 */
8
9#ifndef LINUX_IIO_HW_CONSUMER_H
10#define LINUX_IIO_HW_CONSUMER_H
11
12struct iio_hw_consumer;
13
14struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev);
15void iio_hw_consumer_free(struct iio_hw_consumer *hwc);
16struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev);
17void devm_iio_hw_consumer_free(struct device *dev, struct iio_hw_consumer *hwc);
18int iio_hw_consumer_enable(struct iio_hw_consumer *hwc);
19void iio_hw_consumer_disable(struct iio_hw_consumer *hwc);
20
21#endif
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 20b61347ea58..f12a61be1ede 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -20,34 +20,6 @@
20 * Currently assumes nano seconds. 20 * Currently assumes nano seconds.
21 */ 21 */
22 22
23enum iio_chan_info_enum {
24 IIO_CHAN_INFO_RAW = 0,
25 IIO_CHAN_INFO_PROCESSED,
26 IIO_CHAN_INFO_SCALE,
27 IIO_CHAN_INFO_OFFSET,
28 IIO_CHAN_INFO_CALIBSCALE,
29 IIO_CHAN_INFO_CALIBBIAS,
30 IIO_CHAN_INFO_PEAK,
31 IIO_CHAN_INFO_PEAK_SCALE,
32 IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW,
33 IIO_CHAN_INFO_AVERAGE_RAW,
34 IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY,
35 IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY,
36 IIO_CHAN_INFO_SAMP_FREQ,
37 IIO_CHAN_INFO_FREQUENCY,
38 IIO_CHAN_INFO_PHASE,
39 IIO_CHAN_INFO_HARDWAREGAIN,
40 IIO_CHAN_INFO_HYSTERESIS,
41 IIO_CHAN_INFO_INT_TIME,
42 IIO_CHAN_INFO_ENABLE,
43 IIO_CHAN_INFO_CALIBHEIGHT,
44 IIO_CHAN_INFO_CALIBWEIGHT,
45 IIO_CHAN_INFO_DEBOUNCE_COUNT,
46 IIO_CHAN_INFO_DEBOUNCE_TIME,
47 IIO_CHAN_INFO_CALIBEMISSIVITY,
48 IIO_CHAN_INFO_OVERSAMPLING_RATIO,
49};
50
51enum iio_shared_by { 23enum iio_shared_by {
52 IIO_SEPARATE, 24 IIO_SEPARATE,
53 IIO_SHARED_BY_TYPE, 25 IIO_SHARED_BY_TYPE,
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 2aa7b6384d64..6eb3d683ef62 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -34,4 +34,32 @@ enum iio_available_type {
34 IIO_AVAIL_RANGE, 34 IIO_AVAIL_RANGE,
35}; 35};
36 36
37enum iio_chan_info_enum {
38 IIO_CHAN_INFO_RAW = 0,
39 IIO_CHAN_INFO_PROCESSED,
40 IIO_CHAN_INFO_SCALE,
41 IIO_CHAN_INFO_OFFSET,
42 IIO_CHAN_INFO_CALIBSCALE,
43 IIO_CHAN_INFO_CALIBBIAS,
44 IIO_CHAN_INFO_PEAK,
45 IIO_CHAN_INFO_PEAK_SCALE,
46 IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW,
47 IIO_CHAN_INFO_AVERAGE_RAW,
48 IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY,
49 IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY,
50 IIO_CHAN_INFO_SAMP_FREQ,
51 IIO_CHAN_INFO_FREQUENCY,
52 IIO_CHAN_INFO_PHASE,
53 IIO_CHAN_INFO_HARDWAREGAIN,
54 IIO_CHAN_INFO_HYSTERESIS,
55 IIO_CHAN_INFO_INT_TIME,
56 IIO_CHAN_INFO_ENABLE,
57 IIO_CHAN_INFO_CALIBHEIGHT,
58 IIO_CHAN_INFO_CALIBWEIGHT,
59 IIO_CHAN_INFO_DEBOUNCE_COUNT,
60 IIO_CHAN_INFO_DEBOUNCE_TIME,
61 IIO_CHAN_INFO_CALIBEMISSIVITY,
62 IIO_CHAN_INFO_OVERSAMPLING_RATIO,
63};
64
37#endif /* _IIO_TYPES_H_ */ 65#endif /* _IIO_TYPES_H_ */