From: Fabrice Gasnier <fabrice.gasnier@st.com>
To: <jic23@kernel.org>, <linux@armlinux.org.uk>, <robh+dt@kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <linux-iio@vger.kernel.org>, <mark.rutland@arm.com>,
<mcoquelin.stm32@gmail.com>, <alexandre.torgue@st.com>,
<lars@metafoo.de>, <knaack.h@gmx.de>, <pmeerw@pmeerw.net>,
<fabrice.gasnier@st.com>, <benjamin.gaignard@linaro.org>,
<benjamin.gaignard@st.com>, <linus.walleij@linaro.org>,
<amelie.delaunay@st.com>
Subject: [PATCH 4/4] iio: dac: stm32: add support for waveform generator
Date: Fri, 31 Mar 2017 13:45:07 +0200 [thread overview]
Message-ID: <1490960707-22422-5-git-send-email-fabrice.gasnier@st.com> (raw)
In-Reply-To: <1490960707-22422-1-git-send-email-fabrice.gasnier@st.com>
STM32 DAC has built-in noise or triangle waveform generator.
Waveform generator requires trigger to be configured.
- "wave" extended attribute selects noise or triangle.
- "mamp" extended attribute selects either LFSR (linear feedback
shift register) mask for noise waveform, OR triangle amplitude.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
---
Documentation/ABI/testing/sysfs-bus-iio-dac-stm32 | 32 ++++++
drivers/iio/dac/stm32-dac.c | 124 ++++++++++++++++++++++
2 files changed, 156 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
new file mode 100644
index 0000000..c2432e1
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-dac-stm32
@@ -0,0 +1,32 @@
+What: /sys/bus/iio/devices/iio:deviceX/wave
+What: /sys/bus/iio/devices/iio:deviceX/wave_available
+KernelVersion: 4.12
+Contact: fabrice.gasnier@st.com
+Description:
+ List and/or select waveform generation provided by STM32 DAC:
+ - "none": (default) means normal DAC operations
+ - "noise": select noise waveform
+ - "triangle": select triangle waveform
+ Note: when waveform generator is used, writing _raw sysfs entry
+ adds a DC offset to generated waveform. Reading it reports
+ current output value.
+
+What: /sys/bus/iio/devices/iio:deviceX/mamp
+What: /sys/bus/iio/devices/iio:deviceX/mamp_available
+KernelVersion: 4.12
+Contact: fabrice.gasnier@st.com
+Description:
+ List and select mask/amplitude used for noise/triangle waveform
+ generator, which are:
+ - "0": unmask bit 0 of LFSR / triangle amplitude equal to 1
+ - "1": unmask bit [1:0] of LFSR / triangle amplitude equal to 3
+ - "2": unmask bit [2:0] of LFSR / triangle amplitude equal to 7
+ - "3": unmask bit [3:0] of LFSR / triangle amplitude equal to 15
+ - "4": unmask bit [4:0] of LFSR / triangle amplitude equal to 31
+ - "5": unmask bit [5:0] of LFSR / triangle amplitude equal to 63
+ - "6": unmask bit [6:0] of LFSR / triangle amplitude equal to 127
+ - "7": unmask bit [7:0] of LFSR / triangle amplitude equal to 255
+ - "8": unmask bit [8:0] of LFSR / triangle amplitude equal to 511
+ - "9": unmask bit [9:0] of LFSR / triangle amplitude equal to 1023
+ - "10": unmask bit [10:0] of LFSR / triangle amplitude equal to 2047
+ - "11": unmask bit [11:0] of LFSR / triangle amplitude equal to 4095
diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c
index 62e43e9..d7dda78 100644
--- a/drivers/iio/dac/stm32-dac.c
+++ b/drivers/iio/dac/stm32-dac.c
@@ -41,10 +41,14 @@
/**
* struct stm32_dac - private data of DAC driver
* @common: reference to DAC common data
+ * @wave: waveform generator
+ * @mamp: waveform mask/amplitude
* @swtrig: Using software trigger
*/
struct stm32_dac {
struct stm32_dac_common *common;
+ u32 wave;
+ u32 mamp;
bool swtrig;
};
@@ -157,6 +161,24 @@ static int stm32_dac_is_enabled(struct stm32_dac *dac, int channel)
return !!en;
}
+static int stm32_dac_wavegen(struct stm32_dac *dac, int channel)
+{
+ struct regmap *regmap = dac->common->regmap;
+ u32 mask, val;
+
+ if (channel == STM32_DAC_CHANNEL_1) {
+ val = FIELD_PREP(STM32_DAC_CR_WAVE1, dac->wave) |
+ FIELD_PREP(STM32_DAC_CR_MAMP1, dac->mamp);
+ mask = STM32_DAC_CR_WAVE1 | STM32_DAC_CR_MAMP1;
+ } else {
+ val = FIELD_PREP(STM32_DAC_CR_WAVE2, dac->wave) |
+ FIELD_PREP(STM32_DAC_CR_MAMP2, dac->mamp);
+ mask = STM32_DAC_CR_WAVE2 | STM32_DAC_CR_MAMP2;
+ }
+
+ return regmap_update_bits(regmap, STM32_DAC_CR, mask, val);
+}
+
static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
{
struct stm32_dac *dac = iio_priv(indio_dev);
@@ -164,6 +186,17 @@ static int stm32_dac_enable(struct iio_dev *indio_dev, int channel)
STM32_DAC_CR_EN1 : STM32_DAC_CR_EN2;
int ret;
+ if (dac->wave && !indio_dev->trig) {
+ dev_err(&indio_dev->dev, "Wavegen requires a trigger\n");
+ return -EINVAL;
+ }
+
+ ret = stm32_dac_wavegen(dac, channel);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "Wavegen setup failed\n");
+ return ret;
+ }
+
ret = stm32_dac_set_trig(dac, indio_dev->trig, channel);
if (ret < 0) {
dev_err(&indio_dev->dev, "Trigger setup failed\n");
@@ -291,6 +324,96 @@ static int stm32_dac_debugfs_reg_access(struct iio_dev *indio_dev,
.driver_module = THIS_MODULE,
};
+/* waveform generator wave selection */
+static const char * const stm32_dac_wave_desc[] = {
+ "none",
+ "noise",
+ "triangle",
+};
+
+static int stm32_dac_set_wave(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ unsigned int type)
+{
+ struct stm32_dac *dac = iio_priv(indio_dev);
+
+ if (stm32_dac_is_enabled(dac, chan->channel))
+ return -EBUSY;
+ dac->wave = type;
+
+ return 0;
+}
+
+static int stm32_dac_get_wave(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct stm32_dac *dac = iio_priv(indio_dev);
+
+ return dac->wave;
+}
+
+static const struct iio_enum stm32_dac_wave_enum = {
+ .items = stm32_dac_wave_desc,
+ .num_items = ARRAY_SIZE(stm32_dac_wave_desc),
+ .get = stm32_dac_get_wave,
+ .set = stm32_dac_set_wave,
+};
+
+/*
+ * waveform generator mask/amplitude selection:
+ * - noise: LFSR mask (linear feedback shift register, umasks bit 0, [1:0]...)
+ * - triangle: amplitude (equal to 1, 3, 5, 7... 4095)
+ */
+static const char * const stm32_dac_mamp_desc[] = {
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
+};
+
+static int stm32_dac_set_mamp(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ unsigned int type)
+{
+ struct stm32_dac *dac = iio_priv(indio_dev);
+
+ if (stm32_dac_is_enabled(dac, chan->channel))
+ return -EBUSY;
+ dac->mamp = type;
+
+ return 0;
+}
+
+static int stm32_dac_get_mamp(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct stm32_dac *dac = iio_priv(indio_dev);
+
+ return dac->mamp;
+}
+
+static const struct iio_enum stm32_dac_mamp_enum = {
+ .items = stm32_dac_mamp_desc,
+ .num_items = ARRAY_SIZE(stm32_dac_mamp_desc),
+ .get = stm32_dac_get_mamp,
+ .set = stm32_dac_set_mamp,
+};
+
+static const struct iio_chan_spec_ext_info stm32_dac_ext_info[] = {
+ IIO_ENUM("wave", IIO_SHARED_BY_ALL, &stm32_dac_wave_enum),
+ {
+ .name = "wave_available",
+ .shared = IIO_SHARED_BY_ALL,
+ .read = iio_enum_available_read,
+ .private = (uintptr_t)&stm32_dac_wave_enum,
+ },
+ IIO_ENUM("mamp", IIO_SHARED_BY_ALL, &stm32_dac_mamp_enum),
+ {
+ .name = "mamp_available",
+ .shared = IIO_SHARED_BY_ALL,
+ .read = iio_enum_available_read,
+ .private = (uintptr_t)&stm32_dac_mamp_enum,
+ },
+ {},
+};
+
#define STM32_DAC_CHANNEL(chan, name) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
@@ -306,6 +429,7 @@ static int stm32_dac_debugfs_reg_access(struct iio_dev *indio_dev,
.storagebits = 16, \
}, \
.datasheet_name = name, \
+ .ext_info = stm32_dac_ext_info \
}
static const struct iio_chan_spec stm32_dac_channels[] = {
--
1.9.1
next prev parent reply other threads:[~2017-03-31 11:46 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-31 11:45 [PATCH 0/4] Add STM32H7 DAC driver Fabrice Gasnier
2017-03-31 11:45 ` [PATCH 1/4] dt-bindings: iio: stm32-dac: Add support for STM32 DAC Fabrice Gasnier
2017-04-02 11:16 ` Jonathan Cameron
2017-04-05 14:47 ` Fabrice Gasnier
2017-04-03 16:42 ` Rob Herring
2017-04-05 14:48 ` Fabrice Gasnier
2017-03-31 11:45 ` [PATCH 2/4] iio: dac: add support for stm32 DAC Fabrice Gasnier
2017-04-01 12:34 ` Peter Meerwald-Stadler
2017-04-05 14:55 ` Fabrice Gasnier
2017-04-02 11:32 ` Jonathan Cameron
2017-04-05 15:48 ` Fabrice Gasnier
2017-04-08 17:13 ` Jonathan Cameron
2017-03-31 11:45 ` [PATCH 3/4] iio: dac: stm32: add support for trigger events Fabrice Gasnier
2017-04-02 11:45 ` Jonathan Cameron
2017-04-02 12:21 ` Jonathan Cameron
2017-04-05 16:44 ` Fabrice Gasnier
2017-04-08 17:19 ` Jonathan Cameron
2017-03-31 11:45 ` Fabrice Gasnier [this message]
2017-04-02 12:19 ` [PATCH 4/4] iio: dac: stm32: add support for waveform generator Jonathan Cameron
2017-04-05 16:46 ` Fabrice Gasnier
2017-04-08 17:21 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1490960707-22422-5-git-send-email-fabrice.gasnier@st.com \
--to=fabrice.gasnier@st.com \
--cc=alexandre.torgue@st.com \
--cc=amelie.delaunay@st.com \
--cc=benjamin.gaignard@linaro.org \
--cc=benjamin.gaignard@st.com \
--cc=devicetree@vger.kernel.org \
--cc=jic23@kernel.org \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=mark.rutland@arm.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=pmeerw@pmeerw.net \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).