浏览代码

iio: make stm32 trigger driver use INDIO_HARDWARE_TRIGGERED mode

Add validate function to be use to use the correct trigger.
Add an attribute to configure device mode like for quadrature and
enable modes

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Benjamin Gaignard 8 年之前
父节点
当前提交
9eba381bf8
共有 2 个文件被更改,包括 76 次插入0 次删除
  1. 15 0
      Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
  2. 61 0
      drivers/iio/trigger/stm32-timer-trigger.c

+ 15 - 0
Documentation/ABI/testing/sysfs-bus-iio-timer-stm32

@@ -138,3 +138,18 @@ Description:
 			Counting is enabled on rising edge of the connected
 			Counting is enabled on rising edge of the connected
 			trigger, and remains enabled for the duration of this
 			trigger, and remains enabled for the duration of this
 			selected mode.
 			selected mode.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_count_trigger_mode_available
+KernelVersion:	4.13
+Contact:	benjamin.gaignard@st.com
+Description:
+		Reading returns the list possible trigger modes.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_count0_trigger_mode
+KernelVersion:	4.13
+Contact:	benjamin.gaignard@st.com
+Description:
+		Configure the device counter trigger mode
+		counting direction is set by in_count0_count_direction
+		attribute and the counter is clocked by the connected trigger
+		rising edges.

+ 61 - 0
drivers/iio/trigger/stm32-timer-trigger.c

@@ -417,12 +417,70 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
+static int stm32_counter_validate_trigger(struct iio_dev *indio_dev,
+					  struct iio_trigger *trig)
+{
+	struct stm32_timer_trigger *priv = iio_priv(indio_dev);
+	const char * const *cur = priv->valids;
+	unsigned int i = 0;
+
+	if (!is_stm32_timer_trigger(trig))
+		return -EINVAL;
+
+	while (cur && *cur) {
+		if (!strncmp(trig->name, *cur, strlen(trig->name))) {
+			regmap_update_bits(priv->regmap,
+					   TIM_SMCR, TIM_SMCR_TS,
+					   i << TIM_SMCR_TS_SHIFT);
+			return 0;
+		}
+		cur++;
+		i++;
+	}
+
+	return -EINVAL;
+}
+
 static const struct iio_info stm32_trigger_info = {
 static const struct iio_info stm32_trigger_info = {
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
+	.validate_trigger = stm32_counter_validate_trigger,
 	.read_raw = stm32_counter_read_raw,
 	.read_raw = stm32_counter_read_raw,
 	.write_raw = stm32_counter_write_raw
 	.write_raw = stm32_counter_write_raw
 };
 };
 
 
+static const char *const stm32_trigger_modes[] = {
+	"trigger",
+};
+
+static int stm32_set_trigger_mode(struct iio_dev *indio_dev,
+				  const struct iio_chan_spec *chan,
+				  unsigned int mode)
+{
+	struct stm32_timer_trigger *priv = iio_priv(indio_dev);
+
+	regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, TIM_SMCR_SMS);
+
+	return 0;
+}
+
+static int stm32_get_trigger_mode(struct iio_dev *indio_dev,
+				  const struct iio_chan_spec *chan)
+{
+	struct stm32_timer_trigger *priv = iio_priv(indio_dev);
+	u32 smcr;
+
+	regmap_read(priv->regmap, TIM_SMCR, &smcr);
+
+	return smcr == TIM_SMCR_SMS ? 0 : -EINVAL;
+}
+
+static const struct iio_enum stm32_trigger_mode_enum = {
+	.items = stm32_trigger_modes,
+	.num_items = ARRAY_SIZE(stm32_trigger_modes),
+	.set = stm32_set_trigger_mode,
+	.get = stm32_get_trigger_mode
+};
+
 static const char *const stm32_enable_modes[] = {
 static const char *const stm32_enable_modes[] = {
 	"always",
 	"always",
 	"gated",
 	"gated",
@@ -606,6 +664,8 @@ static const struct iio_chan_spec_ext_info stm32_trigger_count_info[] = {
 	IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_quadrature_mode_enum),
 	IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_quadrature_mode_enum),
 	IIO_ENUM("enable_mode", IIO_SEPARATE, &stm32_enable_mode_enum),
 	IIO_ENUM("enable_mode", IIO_SEPARATE, &stm32_enable_mode_enum),
 	IIO_ENUM_AVAILABLE("enable_mode", &stm32_enable_mode_enum),
 	IIO_ENUM_AVAILABLE("enable_mode", &stm32_enable_mode_enum),
+	IIO_ENUM("trigger_mode", IIO_SEPARATE, &stm32_trigger_mode_enum),
+	IIO_ENUM_AVAILABLE("trigger_mode", &stm32_trigger_mode_enum),
 	{}
 	{}
 };
 };
 
 
@@ -630,6 +690,7 @@ static struct stm32_timer_trigger *stm32_setup_counter_device(struct device *dev
 	indio_dev->name = dev_name(dev);
 	indio_dev->name = dev_name(dev);
 	indio_dev->dev.parent = dev;
 	indio_dev->dev.parent = dev;
 	indio_dev->info = &stm32_trigger_info;
 	indio_dev->info = &stm32_trigger_info;
+	indio_dev->modes = INDIO_HARDWARE_TRIGGERED;
 	indio_dev->num_channels = 1;
 	indio_dev->num_channels = 1;
 	indio_dev->channels = &stm32_trigger_channel;
 	indio_dev->channels = &stm32_trigger_channel;
 	indio_dev->dev.of_node = dev->of_node;
 	indio_dev->dev.of_node = dev->of_node;