summaryrefslogtreecommitdiffstats
path: root/drivers/counter
diff options
context:
space:
mode:
authorFabrice Gasnier <fabrice.gasnier@foss.st.com>2021-01-29 14:22:22 +0100
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2021-03-11 21:46:56 +0100
commit01f68f067dc39df9c9d95d759ee61517eb4b0fcf (patch)
tree852742e5321381cfed290d5577725e41be475b49 /drivers/counter
parentiio:adc:stm32-adc: Add HAS_IOMEM dependency (diff)
downloadlinux-01f68f067dc39df9c9d95d759ee61517eb4b0fcf.tar.xz
linux-01f68f067dc39df9c9d95d759ee61517eb4b0fcf.zip
counter: stm32-lptimer-cnt: remove iio counter abi
Currently, the STM32 LP Timer counter driver registers into both IIO and counter subsystems, which is redundant. Remove the IIO counter ABI and IIO registration from the STM32 LP Timer counter driver since it's been superseded by the Counter subsystem as discussed in [1]. Keep only the counter subsystem related part. Move a part of the ABI documentation into a driver comment. This also removes a duplicate ABI warning $ scripts/get_abi.pl validate ... /sys/bus/iio/devices/iio:deviceX/in_count0_preset is defined 2 times: ./Documentation/ABI/testing/sysfs-bus-iio-timer-stm32:100 ./Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32:0 [1] https://lkml.org/lkml/2021/1/19/347 Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com> Link: https://lore.kernel.org/r/1611926542-2490-1-git-send-email-fabrice.gasnier@foss.st.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/counter')
-rw-r--r--drivers/counter/Kconfig2
-rw-r--r--drivers/counter/stm32-lptimer-cnt.c297
2 files changed, 37 insertions, 262 deletions
diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index 2de53ab0dd25..cbdf84200e27 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -41,7 +41,7 @@ config STM32_TIMER_CNT
config STM32_LPTIMER_CNT
tristate "STM32 LP Timer encoder counter driver"
- depends on (MFD_STM32_LPTIMER || COMPILE_TEST) && IIO
+ depends on MFD_STM32_LPTIMER || COMPILE_TEST
help
Select this option to enable STM32 Low-Power Timer quadrature encoder
and counter driver.
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index fd6828e2d34f..937439635d53 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -12,8 +12,8 @@
#include <linux/bitfield.h>
#include <linux/counter.h>
-#include <linux/iio/iio.h>
#include <linux/mfd/stm32-lptimer.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
@@ -107,249 +107,27 @@ static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
}
-static int stm32_lptim_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val, int val2, long mask)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
- int ret;
-
- switch (mask) {
- case IIO_CHAN_INFO_ENABLE:
- if (val < 0 || val > 1)
- return -EINVAL;
-
- /* Check nobody uses the timer, or already disabled/enabled */
- ret = stm32_lptim_is_enabled(priv);
- if ((ret < 0) || (!ret && !val))
- return ret;
- if (val && ret)
- return -EBUSY;
-
- ret = stm32_lptim_setup(priv, val);
- if (ret)
- return ret;
- return stm32_lptim_set_enable_state(priv, val);
-
- default:
- return -EINVAL;
- }
-}
-
-static int stm32_lptim_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
- u32 dat;
- int ret;
-
- switch (mask) {
- case IIO_CHAN_INFO_RAW:
- ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &dat);
- if (ret)
- return ret;
- *val = dat;
- return IIO_VAL_INT;
-
- case IIO_CHAN_INFO_ENABLE:
- ret = stm32_lptim_is_enabled(priv);
- if (ret < 0)
- return ret;
- *val = ret;
- return IIO_VAL_INT;
-
- case IIO_CHAN_INFO_SCALE:
- /* Non-quadrature mode: scale = 1 */
- *val = 1;
- *val2 = 0;
- if (priv->quadrature_mode) {
- /*
- * Quadrature encoder mode:
- * - both edges, quarter cycle, scale is 0.25
- * - either rising/falling edge scale is 0.5
- */
- if (priv->polarity > 1)
- *val2 = 2;
- else
- *val2 = 1;
- }
- return IIO_VAL_FRACTIONAL_LOG2;
-
- default:
- return -EINVAL;
- }
-}
-
-static const struct iio_info stm32_lptim_cnt_iio_info = {
- .read_raw = stm32_lptim_read_raw,
- .write_raw = stm32_lptim_write_raw,
-};
-
-static const char *const stm32_lptim_quadrature_modes[] = {
- "non-quadrature",
- "quadrature",
-};
-
-static int stm32_lptim_get_quadrature_mode(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
- return priv->quadrature_mode;
-}
-
-static int stm32_lptim_set_quadrature_mode(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- unsigned int type)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
- if (stm32_lptim_is_enabled(priv))
- return -EBUSY;
-
- priv->quadrature_mode = type;
-
- return 0;
-}
-
-static const struct iio_enum stm32_lptim_quadrature_mode_en = {
- .items = stm32_lptim_quadrature_modes,
- .num_items = ARRAY_SIZE(stm32_lptim_quadrature_modes),
- .get = stm32_lptim_get_quadrature_mode,
- .set = stm32_lptim_set_quadrature_mode,
-};
-
-static const char * const stm32_lptim_cnt_polarity[] = {
- "rising-edge", "falling-edge", "both-edges",
-};
-
-static int stm32_lptim_cnt_get_polarity(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
- return priv->polarity;
-}
-
-static int stm32_lptim_cnt_set_polarity(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- unsigned int type)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
- if (stm32_lptim_is_enabled(priv))
- return -EBUSY;
-
- priv->polarity = type;
-
- return 0;
-}
-
-static const struct iio_enum stm32_lptim_cnt_polarity_en = {
- .items = stm32_lptim_cnt_polarity,
- .num_items = ARRAY_SIZE(stm32_lptim_cnt_polarity),
- .get = stm32_lptim_cnt_get_polarity,
- .set = stm32_lptim_cnt_set_polarity,
-};
-
-static ssize_t stm32_lptim_cnt_get_ceiling(struct stm32_lptim_cnt *priv,
- char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%u\n", priv->ceiling);
-}
-
-static ssize_t stm32_lptim_cnt_set_ceiling(struct stm32_lptim_cnt *priv,
- const char *buf, size_t len)
-{
- int ret;
-
- if (stm32_lptim_is_enabled(priv))
- return -EBUSY;
-
- ret = kstrtouint(buf, 0, &priv->ceiling);
- if (ret)
- return ret;
-
- if (priv->ceiling > STM32_LPTIM_MAX_ARR)
- return -EINVAL;
-
- return len;
-}
-
-static ssize_t stm32_lptim_cnt_get_preset_iio(struct iio_dev *indio_dev,
- uintptr_t private,
- const struct iio_chan_spec *chan,
- char *buf)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
- return stm32_lptim_cnt_get_ceiling(priv, buf);
-}
-
-static ssize_t stm32_lptim_cnt_set_preset_iio(struct iio_dev *indio_dev,
- uintptr_t private,
- const struct iio_chan_spec *chan,
- const char *buf, size_t len)
-{
- struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
-
- return stm32_lptim_cnt_set_ceiling(priv, buf, len);
-}
-
-/* LP timer with encoder */
-static const struct iio_chan_spec_ext_info stm32_lptim_enc_ext_info[] = {
- {
- .name = "preset",
- .shared = IIO_SEPARATE,
- .read = stm32_lptim_cnt_get_preset_iio,
- .write = stm32_lptim_cnt_set_preset_iio,
- },
- IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
- IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
- IIO_ENUM("quadrature_mode", IIO_SEPARATE,
- &stm32_lptim_quadrature_mode_en),
- IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_lptim_quadrature_mode_en),
- {}
-};
-
-static const struct iio_chan_spec stm32_lptim_enc_channels = {
- .type = IIO_COUNT,
- .channel = 0,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
- BIT(IIO_CHAN_INFO_ENABLE) |
- BIT(IIO_CHAN_INFO_SCALE),
- .ext_info = stm32_lptim_enc_ext_info,
- .indexed = 1,
-};
-
-/* LP timer without encoder (counter only) */
-static const struct iio_chan_spec_ext_info stm32_lptim_cnt_ext_info[] = {
- {
- .name = "preset",
- .shared = IIO_SEPARATE,
- .read = stm32_lptim_cnt_get_preset_iio,
- .write = stm32_lptim_cnt_set_preset_iio,
- },
- IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
- IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
- {}
-};
-
-static const struct iio_chan_spec stm32_lptim_cnt_channels = {
- .type = IIO_COUNT,
- .channel = 0,
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
- BIT(IIO_CHAN_INFO_ENABLE) |
- BIT(IIO_CHAN_INFO_SCALE),
- .ext_info = stm32_lptim_cnt_ext_info,
- .indexed = 1,
-};
-
/**
* enum stm32_lptim_cnt_function - enumerates LPTimer counter & encoder modes
* @STM32_LPTIM_COUNTER_INCREASE: up count on IN1 rising, falling or both edges
* @STM32_LPTIM_ENCODER_BOTH_EDGE: count on both edges (IN1 & IN2 quadrature)
+ *
+ * In non-quadrature mode, device counts up on active edge.
+ * In quadrature mode, encoder counting scenarios are as follows:
+ * +---------+----------+--------------------+--------------------+
+ * | Active | Level on | IN1 signal | IN2 signal |
+ * | edge | opposite +----------+---------+----------+---------+
+ * | | signal | Rising | Falling | Rising | Falling |
+ * +---------+----------+----------+---------+----------+---------+
+ * | Rising | High -> | Down | - | Up | - |
+ * | edge | Low -> | Up | - | Down | - |
+ * +---------+----------+----------+---------+----------+---------+
+ * | Falling | High -> | - | Up | - | Down |
+ * | edge | Low -> | - | Down | - | Up |
+ * +---------+----------+----------+---------+----------+---------+
+ * | Both | High -> | Down | Up | Up | Down |
+ * | edges | Low -> | Up | Down | Down | Up |
+ * +---------+----------+----------+---------+----------+---------+
*/
enum stm32_lptim_cnt_function {
STM32_LPTIM_COUNTER_INCREASE,
@@ -484,7 +262,7 @@ static ssize_t stm32_lptim_cnt_ceiling_read(struct counter_device *counter,
{
struct stm32_lptim_cnt *const priv = counter->priv;
- return stm32_lptim_cnt_get_ceiling(priv, buf);
+ return snprintf(buf, PAGE_SIZE, "%u\n", priv->ceiling);
}
static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
@@ -493,8 +271,22 @@ static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
const char *buf, size_t len)
{
struct stm32_lptim_cnt *const priv = counter->priv;
+ unsigned int ceiling;
+ int ret;
+
+ if (stm32_lptim_is_enabled(priv))
+ return -EBUSY;
+
+ ret = kstrtouint(buf, 0, &ceiling);
+ if (ret)
+ return ret;
+
+ if (ceiling > STM32_LPTIM_MAX_ARR)
+ return -EINVAL;
+
+ priv->ceiling = ceiling;
- return stm32_lptim_cnt_set_ceiling(priv, buf, len);
+ return len;
}
static const struct counter_count_ext stm32_lptim_cnt_ext[] = {
@@ -630,32 +422,19 @@ static int stm32_lptim_cnt_probe(struct platform_device *pdev)
{
struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
struct stm32_lptim_cnt *priv;
- struct iio_dev *indio_dev;
- int ret;
if (IS_ERR_OR_NULL(ddata))
return -EINVAL;
- indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
- if (!indio_dev)
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
- priv = iio_priv(indio_dev);
priv->dev = &pdev->dev;
priv->regmap = ddata->regmap;
priv->clk = ddata->clk;
priv->ceiling = STM32_LPTIM_MAX_ARR;
- /* Initialize IIO device */
- indio_dev->name = dev_name(&pdev->dev);
- indio_dev->dev.of_node = pdev->dev.of_node;
- indio_dev->info = &stm32_lptim_cnt_iio_info;
- if (ddata->has_encoder)
- indio_dev->channels = &stm32_lptim_enc_channels;
- else
- indio_dev->channels = &stm32_lptim_cnt_channels;
- indio_dev->num_channels = 1;
-
/* Initialize Counter device */
priv->counter.name = dev_name(&pdev->dev);
priv->counter.parent = &pdev->dev;
@@ -673,10 +452,6 @@ static int stm32_lptim_cnt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
- ret = devm_iio_device_register(&pdev->dev, indio_dev);
- if (ret)
- return ret;
-
return devm_counter_register(&pdev->dev, &priv->counter);
}