Linux-IIO Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/3] iio: max31856: provide more configuration options
@ 2019-09-23 12:17 Andrea Merello
  2019-09-23 12:17 ` [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
                   ` (3 more replies)
  0 siblings, 4 replies; 60+ messages in thread
From: Andrea Merello @ 2019-09-23 12:17 UTC (permalink / raw)
  To: jic23, patrick.havelange, paresh.chaudhary, pmeerw, lars,
	knaack.h, matthew.weber
  Cc: colin.king, linux-iio, Andrea Merello

This patch series makes it possible to configure some HW features at
runtime by introducing new IIO device attributes.

Two hardware features (power mains noise rejection and HW averaging)
were not previously configurable, and one (thermocouple type selection)
was only possible via DT, but in my experience this is quite limiting in
several scenario (see 3/3 commit message for complete explanation).

These patches have been tested backporting the driver on a 4.9 upstream
kernel (Xilinx mpsoc-based board), and then rebased on the IIO testing git
tree.

Andrea Merello (3):
  iio: max31856: add option for setting mains filter rejection frequency
  iio: max31856: add support for configuring the HW averaging
  iio: max31856: add support for runtime-configuring the thermocouple
    type

 drivers/iio/temperature/max31856.c | 136 +++++++++++++++++++++++++++++
 1 file changed, 136 insertions(+)

--
2.17.1

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-09-23 12:17 [PATCH 0/3] iio: max31856: provide more configuration options Andrea Merello
@ 2019-09-23 12:17 ` Andrea Merello
  2019-10-06  7:54   ` Jonathan Cameron
  2019-09-23 12:17 ` [PATCH 2/3] iio: max31856: add support for configuring the HW averaging Andrea Merello
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-09-23 12:17 UTC (permalink / raw)
  To: jic23, patrick.havelange, paresh.chaudhary, pmeerw, lars,
	knaack.h, matthew.weber
  Cc: colin.king, linux-iio, Andrea Merello

This sensor has an embedded notch filter for reducing interferences caused
by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
(and harmonics).

Currently the said setting is left alone (the sensor defaults to 60Hz).
This patch introduces a IIO attribute that allows the user to set the said
filter to the desired frequency.

NOTE: this has been intentionally not tied to any DT property to allow
the configuration of this setting from userspace, e.g. with a GUI or by
reading a configuration file, or maybe reading a GPIO tied to a physical
switch or accessing some device that can autodetect the line frequency.

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index 73ed550e3fc9..d12613f7ba3c 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -23,6 +23,7 @@
 #define MAX31856_CR0_1SHOT         BIT(6)
 #define MAX31856_CR0_OCFAULT       BIT(4)
 #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
+#define MAX31856_CR0_FILTER_50HZ   BIT(0)
 #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
 #define MAX31856_FAULT_OVUV        BIT(1)
 #define MAX31856_FAULT_OPEN        BIT(0)
@@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
 struct max31856_data {
 	struct spi_device *spi;
 	u32 thermocouple_type;
+	bool filter_50hz;
 };
 
 static int max31856_read(struct max31856_data *data, u8 reg,
@@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
 	reg_cr0_val &= ~MAX31856_CR0_1SHOT;
 	reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
 
+	if (data->filter_50hz)
+		reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
+	else
+		reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
+
 	return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
 }
 
@@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
 	return show_fault(dev, MAX31856_FAULT_OPEN, buf);
 }
 
+static ssize_t show_filter(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+
+	return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
+}
+
+static ssize_t set_filter(struct device *dev,
+			  struct device_attribute *attr,
+			  const char *buf,
+			  size_t len)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+	unsigned int freq;
+	int ret;
+
+	ret = kstrtouint(buf, 10, &freq);
+	if (ret)
+		return ret;
+
+	switch (freq) {
+	case 50:
+		data->filter_50hz = true;
+		break;
+	case 60:
+		data->filter_50hz = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	max31856_init(data);
+	return len;
+}
+
 static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
 static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
+static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
 
 static struct attribute *max31856_attributes[] = {
 	&iio_dev_attr_fault_ovuv.dev_attr.attr,
 	&iio_dev_attr_fault_oc.dev_attr.attr,
+	&iio_dev_attr_filter.dev_attr.attr,
 	NULL,
 };
 
@@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
 
 	data = iio_priv(indio_dev);
 	data->spi = spi;
+	data->filter_50hz = false;
 
 	spi_set_drvdata(spi, indio_dev);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 2/3] iio: max31856: add support for configuring the HW averaging
  2019-09-23 12:17 [PATCH 0/3] iio: max31856: provide more configuration options Andrea Merello
  2019-09-23 12:17 ` [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
@ 2019-09-23 12:17 ` Andrea Merello
  2019-10-06  7:55   ` Jonathan Cameron
  2019-09-23 12:17 ` [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
  3 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-09-23 12:17 UTC (permalink / raw)
  To: jic23, patrick.havelange, paresh.chaudhary, pmeerw, lars,
	knaack.h, matthew.weber
  Cc: colin.king, linux-iio, Andrea Merello

This sensor can perform samples averaging in hardware, but currently the
driver leaves this setting alone (default is no averaging).

This patch introduces a new IIO attribute that allows the user to set the
averaging as desired (the HW supports averaging of 2, 5, 8 or 16 samples)

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 43 ++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index d12613f7ba3c..8b2e0102fa5c 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -24,6 +24,8 @@
 #define MAX31856_CR0_OCFAULT       BIT(4)
 #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
 #define MAX31856_CR0_FILTER_50HZ   BIT(0)
+#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
+#define MAX31856_AVERAGING_SHIFT   4
 #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
 #define MAX31856_FAULT_OVUV        BIT(1)
 #define MAX31856_FAULT_OPEN        BIT(0)
@@ -65,6 +67,7 @@ struct max31856_data {
 	struct spi_device *spi;
 	u32 thermocouple_type;
 	bool filter_50hz;
+	int averaging;
 };
 
 static int max31856_read(struct max31856_data *data, u8 reg,
@@ -109,6 +112,10 @@ static int max31856_init(struct max31856_data *data)
 
 	reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
 	reg_cr1_val |= data->thermocouple_type;
+
+	reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
+	reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
+
 	ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
 	if (ret)
 		return ret;
@@ -295,14 +302,50 @@ static ssize_t set_filter(struct device *dev,
 	return len;
 }
 
+static ssize_t show_averaging(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+
+	return sprintf(buf, "%d\n", 1 << data->averaging);
+}
+
+static ssize_t set_averaging(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf,
+			     size_t len)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+	unsigned int nsamples;
+	int shift;
+	int ret;
+
+	ret = kstrtouint(buf, 10, &nsamples);
+	if (ret)
+		return ret;
+
+	shift = fls(nsamples) - 1;
+	if (nsamples > 16 || BIT(shift) != nsamples)
+		return -EINVAL;
+
+	data->averaging = shift;
+	max31856_init(data);
+	return len;
+}
+
 static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
 static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
 static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
+static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
 
 static struct attribute *max31856_attributes[] = {
 	&iio_dev_attr_fault_ovuv.dev_attr.attr,
 	&iio_dev_attr_fault_oc.dev_attr.attr,
 	&iio_dev_attr_filter.dev_attr.attr,
+	&iio_dev_attr_averaging.dev_attr.attr,
 	NULL,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-09-23 12:17 [PATCH 0/3] iio: max31856: provide more configuration options Andrea Merello
  2019-09-23 12:17 ` [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
  2019-09-23 12:17 ` [PATCH 2/3] iio: max31856: add support for configuring the HW averaging Andrea Merello
@ 2019-09-23 12:17 ` Andrea Merello
  2019-10-06  7:58   ` Jonathan Cameron
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
  3 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-09-23 12:17 UTC (permalink / raw)
  To: jic23, patrick.havelange, paresh.chaudhary, pmeerw, lars,
	knaack.h, matthew.weber
  Cc: colin.king, linux-iio, Andrea Merello

The sensor support various thermocouple types (e.g. J, K, N, ...). The
driver allows to configure this parameter using a DT property.

This is useful when i.e. the thermocouple is physically tied to the sensor
and it is usually not removed, or when it is at least known in advace
which sensor will be connected to the circuit.

However, if the user can randomly connect any kind of thermocouples (i.e.
the device exposes a connector, and the user is free to connect its own
sensors), it would be more appropriate to provide a mechanism to
dynamically switch from one thermocouple type to another. This can be i.e.
handled in userspace by a GUI, a configuration file or a program that
detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
or whatever.

This patch adds a IIO attribute that can be used to override, at run-time,
the DT-provided setting (which serves as default).

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 44 ++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index 8b2e0102fa5c..588e791c79a3 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2018-2019 Rockwell Collins
  */
 
+#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -70,6 +71,10 @@ struct max31856_data {
 	int averaging;
 };
 
+const char max31856_tc_types[] = {
+	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
+};
+
 static int max31856_read(struct max31856_data *data, u8 reg,
 			 u8 val[], unsigned int read_size)
 {
@@ -336,16 +341,55 @@ static ssize_t set_averaging(struct device *dev,
 	return len;
 }
 
+static ssize_t show_tc_type(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+
+	return sprintf(buf, "%c\n", max31856_tc_types[data->thermocouple_type]);
+}
+
+static ssize_t set_tc_type(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf,
+			   size_t len)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+	char tmp;
+	int tc_type = -1;
+	int i;
+
+	if (sscanf(buf, "%c\n", &tmp) != 1)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
+		if (max31856_tc_types[i] == toupper(tmp)) {
+			tc_type = i;
+			break;
+		}
+	}
+	if (tc_type < 0)
+		return -EINVAL;
+	data->thermocouple_type = tc_type;
+	max31856_init(data);
+	return len;
+}
+
 static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
 static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
 static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
 static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
+static IIO_DEVICE_ATTR(thermocouple_type, 0644, show_tc_type, set_tc_type, 0);
 
 static struct attribute *max31856_attributes[] = {
 	&iio_dev_attr_fault_ovuv.dev_attr.attr,
 	&iio_dev_attr_fault_oc.dev_attr.attr,
 	&iio_dev_attr_filter.dev_attr.attr,
 	&iio_dev_attr_averaging.dev_attr.attr,
+	&iio_dev_attr_thermocouple_type.dev_attr.attr,
 	NULL,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-09-23 12:17 ` [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
@ 2019-10-06  7:54   ` Jonathan Cameron
  2019-10-16 13:14     ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-06  7:54 UTC (permalink / raw)
  To: Andrea Merello
  Cc: patrick.havelange, paresh.chaudhary, pmeerw, lars, knaack.h,
	matthew.weber, colin.king, linux-iio

On Mon, 23 Sep 2019 14:17:12 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> This sensor has an embedded notch filter for reducing interferences caused
> by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> (and harmonics).
> 
> Currently the said setting is left alone (the sensor defaults to 60Hz).
> This patch introduces a IIO attribute that allows the user to set the said
> filter to the desired frequency.
> 
> NOTE: this has been intentionally not tied to any DT property to allow
> the configuration of this setting from userspace, e.g. with a GUI or by
> reading a configuration file, or maybe reading a GPIO tied to a physical
> switch or accessing some device that can autodetect the line frequency.
> 
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
This one is not something that can be expect to be known from the setup
of the device as it will depend on local mains frequency.

So fine, to have it as a userspace control, but the name is too generic.
We already have a number of filter attributes and we should try to
work out how to bring it inline with them.

in_X_filter_low_pass_3db_frequency
in_X_filter_high_pass_3db_frequency

So would,
in_X_filter_notch_center_frequency work?
( I suppose we should use the American spelling ;)

This kind of ignores the harmonics aspect but at least documents the
main frequency being blocked.

There is a slight complexity that we have devices that have dual
notchfilters (50 and 60Hz) and ones where you can turn it off entirely.

I suppose no value would count as off and we could perhaps use a list
for both on at the same time (though that's a bit horrible).

> ---
>  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
> 
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index 73ed550e3fc9..d12613f7ba3c 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -23,6 +23,7 @@
>  #define MAX31856_CR0_1SHOT         BIT(6)
>  #define MAX31856_CR0_OCFAULT       BIT(4)
>  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
>  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
>  #define MAX31856_FAULT_OVUV        BIT(1)
>  #define MAX31856_FAULT_OPEN        BIT(0)
> @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
>  struct max31856_data {
>  	struct spi_device *spi;
>  	u32 thermocouple_type;
> +	bool filter_50hz;
>  };
>  
>  static int max31856_read(struct max31856_data *data, u8 reg,
> @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
>  	reg_cr0_val &= ~MAX31856_CR0_1SHOT;
>  	reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
>  
> +	if (data->filter_50hz)
> +		reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> +	else
> +		reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> +
>  	return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
>  }
>  
> @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
>  	return show_fault(dev, MAX31856_FAULT_OPEN, buf);
>  }
>  
> +static ssize_t show_filter(struct device *dev,
> +			   struct device_attribute *attr,
> +			   char *buf)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +
> +	return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> +}
> +
> +static ssize_t set_filter(struct device *dev,
> +			  struct device_attribute *attr,
> +			  const char *buf,
> +			  size_t len)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +	unsigned int freq;
> +	int ret;
> +
> +	ret = kstrtouint(buf, 10, &freq);
> +	if (ret)
> +		return ret;
> +
> +	switch (freq) {
> +	case 50:
> +		data->filter_50hz = true;
> +		break;
> +	case 60:
> +		data->filter_50hz = false;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	max31856_init(data);
> +	return len;
> +}
> +
>  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
>  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
>  
>  static struct attribute *max31856_attributes[] = {
>  	&iio_dev_attr_fault_ovuv.dev_attr.attr,
>  	&iio_dev_attr_fault_oc.dev_attr.attr,
> +	&iio_dev_attr_filter.dev_attr.attr,
>  	NULL,
>  };
>  
> @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
>  
>  	data = iio_priv(indio_dev);
>  	data->spi = spi;
> +	data->filter_50hz = false;
>  
>  	spi_set_drvdata(spi, indio_dev);
>  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 2/3] iio: max31856: add support for configuring the HW averaging
  2019-09-23 12:17 ` [PATCH 2/3] iio: max31856: add support for configuring the HW averaging Andrea Merello
@ 2019-10-06  7:55   ` Jonathan Cameron
  2019-10-16 13:33     ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-06  7:55 UTC (permalink / raw)
  To: Andrea Merello
  Cc: patrick.havelange, paresh.chaudhary, pmeerw, lars, knaack.h,
	matthew.weber, colin.king, linux-iio

On Mon, 23 Sep 2019 14:17:13 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> This sensor can perform samples averaging in hardware, but currently the
> driver leaves this setting alone (default is no averaging).
> 
> This patch introduces a new IIO attribute that allows the user to set the
> averaging as desired (the HW supports averaging of 2, 5, 8 or 16 samples)
> 
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>

Sounds like oversampling combined with a lower sampling frequency, so
there is standard ABI for that.

Jonathan

> ---
>  drivers/iio/temperature/max31856.c | 43 ++++++++++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index d12613f7ba3c..8b2e0102fa5c 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -24,6 +24,8 @@
>  #define MAX31856_CR0_OCFAULT       BIT(4)
>  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
>  #define MAX31856_CR0_FILTER_50HZ   BIT(0)
> +#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
> +#define MAX31856_AVERAGING_SHIFT   4
>  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
>  #define MAX31856_FAULT_OVUV        BIT(1)
>  #define MAX31856_FAULT_OPEN        BIT(0)
> @@ -65,6 +67,7 @@ struct max31856_data {
>  	struct spi_device *spi;
>  	u32 thermocouple_type;
>  	bool filter_50hz;
> +	int averaging;
>  };
>  
>  static int max31856_read(struct max31856_data *data, u8 reg,
> @@ -109,6 +112,10 @@ static int max31856_init(struct max31856_data *data)
>  
>  	reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
>  	reg_cr1_val |= data->thermocouple_type;
> +
> +	reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
> +	reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
> +
>  	ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
>  	if (ret)
>  		return ret;
> @@ -295,14 +302,50 @@ static ssize_t set_filter(struct device *dev,
>  	return len;
>  }
>  
> +static ssize_t show_averaging(struct device *dev,
> +			      struct device_attribute *attr,
> +			      char *buf)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +
> +	return sprintf(buf, "%d\n", 1 << data->averaging);
> +}
> +
> +static ssize_t set_averaging(struct device *dev,
> +			     struct device_attribute *attr,
> +			     const char *buf,
> +			     size_t len)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +	unsigned int nsamples;
> +	int shift;
> +	int ret;
> +
> +	ret = kstrtouint(buf, 10, &nsamples);
> +	if (ret)
> +		return ret;
> +
> +	shift = fls(nsamples) - 1;
> +	if (nsamples > 16 || BIT(shift) != nsamples)
> +		return -EINVAL;
> +
> +	data->averaging = shift;
> +	max31856_init(data);
> +	return len;
> +}
> +
>  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
>  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
>  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> +static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
>  
>  static struct attribute *max31856_attributes[] = {
>  	&iio_dev_attr_fault_ovuv.dev_attr.attr,
>  	&iio_dev_attr_fault_oc.dev_attr.attr,
>  	&iio_dev_attr_filter.dev_attr.attr,
> +	&iio_dev_attr_averaging.dev_attr.attr,
>  	NULL,
>  };
>  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-09-23 12:17 ` [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
@ 2019-10-06  7:58   ` Jonathan Cameron
  2019-10-16 13:43     ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-06  7:58 UTC (permalink / raw)
  To: Andrea Merello
  Cc: patrick.havelange, paresh.chaudhary, pmeerw, lars, knaack.h,
	matthew.weber, colin.king, linux-iio

On Mon, 23 Sep 2019 14:17:14 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> The sensor support various thermocouple types (e.g. J, K, N, ...). The
> driver allows to configure this parameter using a DT property.
> 
> This is useful when i.e. the thermocouple is physically tied to the sensor
> and it is usually not removed, or when it is at least known in advace

advance

> which sensor will be connected to the circuit.
> 
> However, if the user can randomly connect any kind of thermocouples (i.e.
> the device exposes a connector, and the user is free to connect its own
> sensors), it would be more appropriate to provide a mechanism to
> dynamically switch from one thermocouple type to another. This can be i.e.
> handled in userspace by a GUI, a configuration file or a program that
> detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
> or whatever.
> 
> This patch adds a IIO attribute that can be used to override, at run-time,
> the DT-provided setting (which serves as default).
> 
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
For now this is device specific ABI so you need to have an entry in
Documentation/ABI/testing/sysfs-bus-iio-max31856

Or we could consider this generic enough to put it in a file
covering other thermocouple to digital sensors.

Thanks,

Jonathan

> ---
>  drivers/iio/temperature/max31856.c | 44 ++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index 8b2e0102fa5c..588e791c79a3 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -6,6 +6,7 @@
>   * Copyright (C) 2018-2019 Rockwell Collins
>   */
>  
> +#include <linux/ctype.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/err.h>
> @@ -70,6 +71,10 @@ struct max31856_data {
>  	int averaging;
>  };
>  
> +const char max31856_tc_types[] = {
> +	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
> +};
> +
>  static int max31856_read(struct max31856_data *data, u8 reg,
>  			 u8 val[], unsigned int read_size)
>  {
> @@ -336,16 +341,55 @@ static ssize_t set_averaging(struct device *dev,
>  	return len;
>  }
>  
> +static ssize_t show_tc_type(struct device *dev,
> +			    struct device_attribute *attr,
> +			    char *buf)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +
> +	return sprintf(buf, "%c\n", max31856_tc_types[data->thermocouple_type]);
> +}
> +
> +static ssize_t set_tc_type(struct device *dev,
> +			   struct device_attribute *attr,
> +			   const char *buf,
> +			   size_t len)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +	char tmp;
> +	int tc_type = -1;
> +	int i;
> +
> +	if (sscanf(buf, "%c\n", &tmp) != 1)
> +		return -EINVAL;
> +
> +	for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
> +		if (max31856_tc_types[i] == toupper(tmp)) {
> +			tc_type = i;
> +			break;
> +		}
> +	}
> +	if (tc_type < 0)
> +		return -EINVAL;
> +	data->thermocouple_type = tc_type;
> +	max31856_init(data);
> +	return len;
> +}
> +
>  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
>  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
>  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
>  static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
> +static IIO_DEVICE_ATTR(thermocouple_type, 0644, show_tc_type, set_tc_type, 0);
>  
>  static struct attribute *max31856_attributes[] = {
>  	&iio_dev_attr_fault_ovuv.dev_attr.attr,
>  	&iio_dev_attr_fault_oc.dev_attr.attr,
>  	&iio_dev_attr_filter.dev_attr.attr,
>  	&iio_dev_attr_averaging.dev_attr.attr,
> +	&iio_dev_attr_thermocouple_type.dev_attr.attr,
>  	NULL,
>  };
>  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-06  7:54   ` Jonathan Cameron
@ 2019-10-16 13:14     ` Andrea Merello
  2019-10-17 12:32       ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-10-16 13:14 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: patrick.havelange, paresh.chaudhary, pmeerw, lars, knaack.h,
	Matthew Weber, Colin King, linux-iio

Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
<jic23@kernel.org> ha scritto:
>
> On Mon, 23 Sep 2019 14:17:12 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > This sensor has an embedded notch filter for reducing interferences caused
> > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > (and harmonics).
> >
> > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > This patch introduces a IIO attribute that allows the user to set the said
> > filter to the desired frequency.
> >
> > NOTE: this has been intentionally not tied to any DT property to allow
> > the configuration of this setting from userspace, e.g. with a GUI or by
> > reading a configuration file, or maybe reading a GPIO tied to a physical
> > switch or accessing some device that can autodetect the line frequency.
> >
> > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> This one is not something that can be expect to be known from the setup
> of the device as it will depend on local mains frequency.
>
> So fine, to have it as a userspace control, but the name is too generic.
> We already have a number of filter attributes and we should try to
> work out how to bring it inline with them.

Sure

> in_X_filter_low_pass_3db_frequency
> in_X_filter_high_pass_3db_frequency
>
> So would,
> in_X_filter_notch_center_frequency work?
> ( I suppose we should use the American spelling ;)

Yes, it seems OK in this case. I will produce a V2 with this modification.

> This kind of ignores the harmonics aspect but at least documents the
> main frequency being blocked.

I think this is perfectly fine: the user wants to set the notch filter
center frequency to either 60Hz or 50Hz to match the line frequency,
then she/he expects the filter to simply "work" somehow; IMO the
harmonic thing does not needed to be explicit.

> There is a slight complexity that we have devices that have dual
> notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
>
> I suppose no value would count as off and we could perhaps use a list
> for both on at the same time (though that's a bit horrible).

IMHO it seems reasonable. Maybe for all-off and both-on conditions we
could also use magic strings like i.e. "all" and "off".

> > ---
> >  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
> >  1 file changed, 49 insertions(+)
> >
> > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > index 73ed550e3fc9..d12613f7ba3c 100644
> > --- a/drivers/iio/temperature/max31856.c
> > +++ b/drivers/iio/temperature/max31856.c
> > @@ -23,6 +23,7 @@
> >  #define MAX31856_CR0_1SHOT         BIT(6)
> >  #define MAX31856_CR0_OCFAULT       BIT(4)
> >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> >  #define MAX31856_FAULT_OVUV        BIT(1)
> >  #define MAX31856_FAULT_OPEN        BIT(0)
> > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> >  struct max31856_data {
> >       struct spi_device *spi;
> >       u32 thermocouple_type;
> > +     bool filter_50hz;
> >  };
> >
> >  static int max31856_read(struct max31856_data *data, u8 reg,
> > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> >       reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> >       reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> >
> > +     if (data->filter_50hz)
> > +             reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > +     else
> > +             reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > +
> >       return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> >  }
> >
> > @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
> >       return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> >  }
> >
> > +static ssize_t show_filter(struct device *dev,
> > +                        struct device_attribute *attr,
> > +                        char *buf)
> > +{
> > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +     struct max31856_data *data = iio_priv(indio_dev);
> > +
> > +     return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > +}
> > +
> > +static ssize_t set_filter(struct device *dev,
> > +                       struct device_attribute *attr,
> > +                       const char *buf,
> > +                       size_t len)
> > +{
> > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +     struct max31856_data *data = iio_priv(indio_dev);
> > +     unsigned int freq;
> > +     int ret;
> > +
> > +     ret = kstrtouint(buf, 10, &freq);
> > +     if (ret)
> > +             return ret;
> > +
> > +     switch (freq) {
> > +     case 50:
> > +             data->filter_50hz = true;
> > +             break;
> > +     case 60:
> > +             data->filter_50hz = false;
> > +             break;
> > +     default:
> > +             return -EINVAL;
> > +     }
> > +
> > +     max31856_init(data);
> > +     return len;
> > +}
> > +
> >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> >
> >  static struct attribute *max31856_attributes[] = {
> >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > +     &iio_dev_attr_filter.dev_attr.attr,
> >       NULL,
> >  };
> >
> > @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
> >
> >       data = iio_priv(indio_dev);
> >       data->spi = spi;
> > +     data->filter_50hz = false;
> >
> >       spi_set_drvdata(spi, indio_dev);
> >
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 2/3] iio: max31856: add support for configuring the HW averaging
  2019-10-06  7:55   ` Jonathan Cameron
@ 2019-10-16 13:33     ` Andrea Merello
  2019-10-17 12:34       ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-10-16 13:33 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: patrick.havelange, paresh.chaudhary, pmeerw, lars, knaack.h,
	Matthew Weber, Colin King, linux-iio

Il giorno dom 6 ott 2019 alle ore 09:55 Jonathan Cameron
<jic23@kernel.org> ha scritto:
>
> On Mon, 23 Sep 2019 14:17:13 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > This sensor can perform samples averaging in hardware, but currently the
> > driver leaves this setting alone (default is no averaging).
> >
> > This patch introduces a new IIO attribute that allows the user to set the
> > averaging as desired (the HW supports averaging of 2, 5, 8 or 16 samples)
> >
> > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
>
> Sounds like oversampling combined with a lower sampling frequency, so
> there is standard ABI for that.

OK. Do you refer to "oversampling_ratio"?

The datasheet says this applies to thermocouple measure, but by doing
some testing with real HW, it seems that this setting affects both
thermocouple and cold-junction measures, so I guess it shouldn't be in
the form "in_temp_raw_oversampling_ratio"; does this sound right to
you?

> Jonathan
>
> > ---
> >  drivers/iio/temperature/max31856.c | 43 ++++++++++++++++++++++++++++++
> >  1 file changed, 43 insertions(+)
> >
> > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > index d12613f7ba3c..8b2e0102fa5c 100644
> > --- a/drivers/iio/temperature/max31856.c
> > +++ b/drivers/iio/temperature/max31856.c
> > @@ -24,6 +24,8 @@
> >  #define MAX31856_CR0_OCFAULT       BIT(4)
> >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> >  #define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > +#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
> > +#define MAX31856_AVERAGING_SHIFT   4
> >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> >  #define MAX31856_FAULT_OVUV        BIT(1)
> >  #define MAX31856_FAULT_OPEN        BIT(0)
> > @@ -65,6 +67,7 @@ struct max31856_data {
> >       struct spi_device *spi;
> >       u32 thermocouple_type;
> >       bool filter_50hz;
> > +     int averaging;
> >  };
> >
> >  static int max31856_read(struct max31856_data *data, u8 reg,
> > @@ -109,6 +112,10 @@ static int max31856_init(struct max31856_data *data)
> >
> >       reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
> >       reg_cr1_val |= data->thermocouple_type;
> > +
> > +     reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
> > +     reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
> > +
> >       ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
> >       if (ret)
> >               return ret;
> > @@ -295,14 +302,50 @@ static ssize_t set_filter(struct device *dev,
> >       return len;
> >  }
> >
> > +static ssize_t show_averaging(struct device *dev,
> > +                           struct device_attribute *attr,
> > +                           char *buf)
> > +{
> > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +     struct max31856_data *data = iio_priv(indio_dev);
> > +
> > +     return sprintf(buf, "%d\n", 1 << data->averaging);
> > +}
> > +
> > +static ssize_t set_averaging(struct device *dev,
> > +                          struct device_attribute *attr,
> > +                          const char *buf,
> > +                          size_t len)
> > +{
> > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +     struct max31856_data *data = iio_priv(indio_dev);
> > +     unsigned int nsamples;
> > +     int shift;
> > +     int ret;
> > +
> > +     ret = kstrtouint(buf, 10, &nsamples);
> > +     if (ret)
> > +             return ret;
> > +
> > +     shift = fls(nsamples) - 1;
> > +     if (nsamples > 16 || BIT(shift) != nsamples)
> > +             return -EINVAL;
> > +
> > +     data->averaging = shift;
> > +     max31856_init(data);
> > +     return len;
> > +}
> > +
> >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> >  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > +static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
> >
> >  static struct attribute *max31856_attributes[] = {
> >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> >       &iio_dev_attr_fault_oc.dev_attr.attr,
> >       &iio_dev_attr_filter.dev_attr.attr,
> > +     &iio_dev_attr_averaging.dev_attr.attr,
> >       NULL,
> >  };
> >
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-10-06  7:58   ` Jonathan Cameron
@ 2019-10-16 13:43     ` Andrea Merello
  2019-10-17 12:35       ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-10-16 13:43 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: patrick.havelange, paresh.chaudhary, pmeerw, lars, knaack.h,
	Matthew Weber, Colin King, linux-iio

Il giorno dom 6 ott 2019 alle ore 09:58 Jonathan Cameron
<jic23@kernel.org> ha scritto:
>
> On Mon, 23 Sep 2019 14:17:14 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > The sensor support various thermocouple types (e.g. J, K, N, ...). The
> > driver allows to configure this parameter using a DT property.
> >
> > This is useful when i.e. the thermocouple is physically tied to the sensor
> > and it is usually not removed, or when it is at least known in advace
>
> advance

OK

> > which sensor will be connected to the circuit.
> >
> > However, if the user can randomly connect any kind of thermocouples (i.e.
> > the device exposes a connector, and the user is free to connect its own
> > sensors), it would be more appropriate to provide a mechanism to
> > dynamically switch from one thermocouple type to another. This can be i.e.
> > handled in userspace by a GUI, a configuration file or a program that
> > detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
> > or whatever.
> >
> > This patch adds a IIO attribute that can be used to override, at run-time,
> > the DT-provided setting (which serves as default).
> >
> > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> For now this is device specific ABI so you need to have an entry in
> Documentation/ABI/testing/sysfs-bus-iio-max31856

OK

> Or we could consider this generic enough to put it in a file
> covering other thermocouple to digital sensors.

Yes, theoretically thermocouple-type is a generic thing that isn't
bound to this specific driver/chip. Currently the others IIO
thermocouple drivers don't need this because they supports chips that
handle just a specific thermocouple type, but if you want to make this
API generic for the future then I can go this way.. It seems
reasonable to me indeed.

> Thanks,
>
> Jonathan
>
> > ---
> >  drivers/iio/temperature/max31856.c | 44 ++++++++++++++++++++++++++++++
> >  1 file changed, 44 insertions(+)
> >
> > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > index 8b2e0102fa5c..588e791c79a3 100644
> > --- a/drivers/iio/temperature/max31856.c
> > +++ b/drivers/iio/temperature/max31856.c
> > @@ -6,6 +6,7 @@
> >   * Copyright (C) 2018-2019 Rockwell Collins
> >   */
> >
> > +#include <linux/ctype.h>
> >  #include <linux/module.h>
> >  #include <linux/init.h>
> >  #include <linux/err.h>
> > @@ -70,6 +71,10 @@ struct max31856_data {
> >       int averaging;
> >  };
> >
> > +const char max31856_tc_types[] = {
> > +     'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
> > +};
> > +
> >  static int max31856_read(struct max31856_data *data, u8 reg,
> >                        u8 val[], unsigned int read_size)
> >  {
> > @@ -336,16 +341,55 @@ static ssize_t set_averaging(struct device *dev,
> >       return len;
> >  }
> >
> > +static ssize_t show_tc_type(struct device *dev,
> > +                         struct device_attribute *attr,
> > +                         char *buf)
> > +{
> > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +     struct max31856_data *data = iio_priv(indio_dev);
> > +
> > +     return sprintf(buf, "%c\n", max31856_tc_types[data->thermocouple_type]);
> > +}
> > +
> > +static ssize_t set_tc_type(struct device *dev,
> > +                        struct device_attribute *attr,
> > +                        const char *buf,
> > +                        size_t len)
> > +{
> > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +     struct max31856_data *data = iio_priv(indio_dev);
> > +     char tmp;
> > +     int tc_type = -1;
> > +     int i;
> > +
> > +     if (sscanf(buf, "%c\n", &tmp) != 1)
> > +             return -EINVAL;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
> > +             if (max31856_tc_types[i] == toupper(tmp)) {
> > +                     tc_type = i;
> > +                     break;
> > +             }
> > +     }
> > +     if (tc_type < 0)
> > +             return -EINVAL;
> > +     data->thermocouple_type = tc_type;
> > +     max31856_init(data);
> > +     return len;
> > +}
> > +
> >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> >  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> >  static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
> > +static IIO_DEVICE_ATTR(thermocouple_type, 0644, show_tc_type, set_tc_type, 0);
> >
> >  static struct attribute *max31856_attributes[] = {
> >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> >       &iio_dev_attr_fault_oc.dev_attr.attr,
> >       &iio_dev_attr_filter.dev_attr.attr,
> >       &iio_dev_attr_averaging.dev_attr.attr,
> > +     &iio_dev_attr_thermocouple_type.dev_attr.attr,
> >       NULL,
> >  };
> >
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-16 13:14     ` Andrea Merello
@ 2019-10-17 12:32       ` Jonathan Cameron
  2019-10-18 13:46         ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-17 12:32 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

On Wed, 16 Oct 2019 15:14:20 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> <jic23@kernel.org> ha scritto:
> >
> > On Mon, 23 Sep 2019 14:17:12 +0200
> > Andrea Merello <andrea.merello@gmail.com> wrote:
> >  
> > > This sensor has an embedded notch filter for reducing interferences caused
> > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > (and harmonics).
> > >
> > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > This patch introduces a IIO attribute that allows the user to set the said
> > > filter to the desired frequency.
> > >
> > > NOTE: this has been intentionally not tied to any DT property to allow
> > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > switch or accessing some device that can autodetect the line frequency.
> > >
> > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>  
> > This one is not something that can be expect to be known from the setup
> > of the device as it will depend on local mains frequency.
> >
> > So fine, to have it as a userspace control, but the name is too generic.
> > We already have a number of filter attributes and we should try to
> > work out how to bring it inline with them.  
> 
> Sure
> 
> > in_X_filter_low_pass_3db_frequency
> > in_X_filter_high_pass_3db_frequency
> >
> > So would,
> > in_X_filter_notch_center_frequency work?
> > ( I suppose we should use the American spelling ;)  
> 
> Yes, it seems OK in this case. I will produce a V2 with this modification.
> 
> > This kind of ignores the harmonics aspect but at least documents the
> > main frequency being blocked.  
> 
> I think this is perfectly fine: the user wants to set the notch filter
> center frequency to either 60Hz or 50Hz to match the line frequency,
> then she/he expects the filter to simply "work" somehow; IMO the
> harmonic thing does not needed to be explicit.
> 
> > There is a slight complexity that we have devices that have dual
> > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> >
> > I suppose no value would count as off and we could perhaps use a list
> > for both on at the same time (though that's a bit horrible).  
> 
> IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> could also use magic strings like i.e. "all" and "off".

I go with 'maybe' on that one.  Need to think about whether that is just
a partial solution as we will probably find a device with 3 options that only
supports any 2 at one time.  That would still need a more complex interface.

Will think on this.

Jonathan

> 
> > > ---
> > >  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
> > >  1 file changed, 49 insertions(+)
> > >
> > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > index 73ed550e3fc9..d12613f7ba3c 100644
> > > --- a/drivers/iio/temperature/max31856.c
> > > +++ b/drivers/iio/temperature/max31856.c
> > > @@ -23,6 +23,7 @@
> > >  #define MAX31856_CR0_1SHOT         BIT(6)
> > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> > >  struct max31856_data {
> > >       struct spi_device *spi;
> > >       u32 thermocouple_type;
> > > +     bool filter_50hz;
> > >  };
> > >
> > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> > >       reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> > >       reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> > >
> > > +     if (data->filter_50hz)
> > > +             reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > > +     else
> > > +             reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > > +
> > >       return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> > >  }
> > >
> > > @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
> > >       return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> > >  }
> > >
> > > +static ssize_t show_filter(struct device *dev,
> > > +                        struct device_attribute *attr,
> > > +                        char *buf)
> > > +{
> > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > +
> > > +     return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > > +}
> > > +
> > > +static ssize_t set_filter(struct device *dev,
> > > +                       struct device_attribute *attr,
> > > +                       const char *buf,
> > > +                       size_t len)
> > > +{
> > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > +     unsigned int freq;
> > > +     int ret;
> > > +
> > > +     ret = kstrtouint(buf, 10, &freq);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     switch (freq) {
> > > +     case 50:
> > > +             data->filter_50hz = true;
> > > +             break;
> > > +     case 60:
> > > +             data->filter_50hz = false;
> > > +             break;
> > > +     default:
> > > +             return -EINVAL;
> > > +     }
> > > +
> > > +     max31856_init(data);
> > > +     return len;
> > > +}
> > > +
> > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > >
> > >  static struct attribute *max31856_attributes[] = {
> > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > +     &iio_dev_attr_filter.dev_attr.attr,
> > >       NULL,
> > >  };
> > >
> > > @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
> > >
> > >       data = iio_priv(indio_dev);
> > >       data->spi = spi;
> > > +     data->filter_50hz = false;
> > >
> > >       spi_set_drvdata(spi, indio_dev);
> > >  
> >  



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 2/3] iio: max31856: add support for configuring the HW averaging
  2019-10-16 13:33     ` Andrea Merello
@ 2019-10-17 12:34       ` Jonathan Cameron
  2019-10-18 13:47         ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-17 12:34 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

On Wed, 16 Oct 2019 15:33:42 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> Il giorno dom 6 ott 2019 alle ore 09:55 Jonathan Cameron
> <jic23@kernel.org> ha scritto:
> >
> > On Mon, 23 Sep 2019 14:17:13 +0200
> > Andrea Merello <andrea.merello@gmail.com> wrote:
> >  
> > > This sensor can perform samples averaging in hardware, but currently the
> > > driver leaves this setting alone (default is no averaging).
> > >
> > > This patch introduces a new IIO attribute that allows the user to set the
> > > averaging as desired (the HW supports averaging of 2, 5, 8 or 16 samples)
> > >
> > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>  
> >
> > Sounds like oversampling combined with a lower sampling frequency, so
> > there is standard ABI for that.  
> 
> OK. Do you refer to "oversampling_ratio"?
> 
> The datasheet says this applies to thermocouple measure, but by doing
> some testing with real HW, it seems that this setting affects both
> thermocouple and cold-junction measures, so I guess it shouldn't be in
> the form "in_temp_raw_oversampling_ratio"; does this sound right to
> you?
Ah yes. oversampling_ratio it is.  I should read our Docs :)

I think
in_temp_oversampling_ratio will be generated if you use the info_mask_shared_by_type
to do this.

_raw is just another type of information about the channel, rather than
part of the channel naming.

Thanks,

Jonathan

> 
> > Jonathan
> >  
> > > ---
> > >  drivers/iio/temperature/max31856.c | 43 ++++++++++++++++++++++++++++++
> > >  1 file changed, 43 insertions(+)
> > >
> > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > index d12613f7ba3c..8b2e0102fa5c 100644
> > > --- a/drivers/iio/temperature/max31856.c
> > > +++ b/drivers/iio/temperature/max31856.c
> > > @@ -24,6 +24,8 @@
> > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > >  #define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > > +#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
> > > +#define MAX31856_AVERAGING_SHIFT   4
> > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > @@ -65,6 +67,7 @@ struct max31856_data {
> > >       struct spi_device *spi;
> > >       u32 thermocouple_type;
> > >       bool filter_50hz;
> > > +     int averaging;
> > >  };
> > >
> > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > @@ -109,6 +112,10 @@ static int max31856_init(struct max31856_data *data)
> > >
> > >       reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
> > >       reg_cr1_val |= data->thermocouple_type;
> > > +
> > > +     reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
> > > +     reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
> > > +
> > >       ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
> > >       if (ret)
> > >               return ret;
> > > @@ -295,14 +302,50 @@ static ssize_t set_filter(struct device *dev,
> > >       return len;
> > >  }
> > >
> > > +static ssize_t show_averaging(struct device *dev,
> > > +                           struct device_attribute *attr,
> > > +                           char *buf)
> > > +{
> > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > +
> > > +     return sprintf(buf, "%d\n", 1 << data->averaging);
> > > +}
> > > +
> > > +static ssize_t set_averaging(struct device *dev,
> > > +                          struct device_attribute *attr,
> > > +                          const char *buf,
> > > +                          size_t len)
> > > +{
> > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > +     unsigned int nsamples;
> > > +     int shift;
> > > +     int ret;
> > > +
> > > +     ret = kstrtouint(buf, 10, &nsamples);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     shift = fls(nsamples) - 1;
> > > +     if (nsamples > 16 || BIT(shift) != nsamples)
> > > +             return -EINVAL;
> > > +
> > > +     data->averaging = shift;
> > > +     max31856_init(data);
> > > +     return len;
> > > +}
> > > +
> > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > >  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > +static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
> > >
> > >  static struct attribute *max31856_attributes[] = {
> > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > >       &iio_dev_attr_filter.dev_attr.attr,
> > > +     &iio_dev_attr_averaging.dev_attr.attr,
> > >       NULL,
> > >  };
> > >  
> >  



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-10-16 13:43     ` Andrea Merello
@ 2019-10-17 12:35       ` Jonathan Cameron
  2019-10-18 13:48         ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-17 12:35 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

On Wed, 16 Oct 2019 15:43:18 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> Il giorno dom 6 ott 2019 alle ore 09:58 Jonathan Cameron
> <jic23@kernel.org> ha scritto:
> >
> > On Mon, 23 Sep 2019 14:17:14 +0200
> > Andrea Merello <andrea.merello@gmail.com> wrote:
> >  
> > > The sensor support various thermocouple types (e.g. J, K, N, ...). The
> > > driver allows to configure this parameter using a DT property.
> > >
> > > This is useful when i.e. the thermocouple is physically tied to the sensor
> > > and it is usually not removed, or when it is at least known in advace  
> >
> > advance  
> 
> OK
> 
> > > which sensor will be connected to the circuit.
> > >
> > > However, if the user can randomly connect any kind of thermocouples (i.e.
> > > the device exposes a connector, and the user is free to connect its own
> > > sensors), it would be more appropriate to provide a mechanism to
> > > dynamically switch from one thermocouple type to another. This can be i.e.
> > > handled in userspace by a GUI, a configuration file or a program that
> > > detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
> > > or whatever.
> > >
> > > This patch adds a IIO attribute that can be used to override, at run-time,
> > > the DT-provided setting (which serves as default).
> > >
> > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>  
> > For now this is device specific ABI so you need to have an entry in
> > Documentation/ABI/testing/sysfs-bus-iio-max31856  
> 
> OK
> 
> > Or we could consider this generic enough to put it in a file
> > covering other thermocouple to digital sensors.  
> 
> Yes, theoretically thermocouple-type is a generic thing that isn't
> bound to this specific driver/chip. Currently the others IIO
> thermocouple drivers don't need this because they supports chips that
> handle just a specific thermocouple type, but if you want to make this
> API generic for the future then I can go this way.. It seems
> reasonable to me indeed.
> 

Lets do it then ;)  We might want to add a read only attrs to the
other drivers to make them self describing.

Thanks,

Jonathan

> > Thanks,
> >
> > Jonathan
> >  
> > > ---
> > >  drivers/iio/temperature/max31856.c | 44 ++++++++++++++++++++++++++++++
> > >  1 file changed, 44 insertions(+)
> > >
> > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > index 8b2e0102fa5c..588e791c79a3 100644
> > > --- a/drivers/iio/temperature/max31856.c
> > > +++ b/drivers/iio/temperature/max31856.c
> > > @@ -6,6 +6,7 @@
> > >   * Copyright (C) 2018-2019 Rockwell Collins
> > >   */
> > >
> > > +#include <linux/ctype.h>
> > >  #include <linux/module.h>
> > >  #include <linux/init.h>
> > >  #include <linux/err.h>
> > > @@ -70,6 +71,10 @@ struct max31856_data {
> > >       int averaging;
> > >  };
> > >
> > > +const char max31856_tc_types[] = {
> > > +     'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
> > > +};
> > > +
> > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > >                        u8 val[], unsigned int read_size)
> > >  {
> > > @@ -336,16 +341,55 @@ static ssize_t set_averaging(struct device *dev,
> > >       return len;
> > >  }
> > >
> > > +static ssize_t show_tc_type(struct device *dev,
> > > +                         struct device_attribute *attr,
> > > +                         char *buf)
> > > +{
> > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > +
> > > +     return sprintf(buf, "%c\n", max31856_tc_types[data->thermocouple_type]);
> > > +}
> > > +
> > > +static ssize_t set_tc_type(struct device *dev,
> > > +                        struct device_attribute *attr,
> > > +                        const char *buf,
> > > +                        size_t len)
> > > +{
> > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > +     char tmp;
> > > +     int tc_type = -1;
> > > +     int i;
> > > +
> > > +     if (sscanf(buf, "%c\n", &tmp) != 1)
> > > +             return -EINVAL;
> > > +
> > > +     for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
> > > +             if (max31856_tc_types[i] == toupper(tmp)) {
> > > +                     tc_type = i;
> > > +                     break;
> > > +             }
> > > +     }
> > > +     if (tc_type < 0)
> > > +             return -EINVAL;
> > > +     data->thermocouple_type = tc_type;
> > > +     max31856_init(data);
> > > +     return len;
> > > +}
> > > +
> > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > >  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > >  static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
> > > +static IIO_DEVICE_ATTR(thermocouple_type, 0644, show_tc_type, set_tc_type, 0);
> > >
> > >  static struct attribute *max31856_attributes[] = {
> > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > >       &iio_dev_attr_filter.dev_attr.attr,
> > >       &iio_dev_attr_averaging.dev_attr.attr,
> > > +     &iio_dev_attr_thermocouple_type.dev_attr.attr,
> > >       NULL,
> > >  };
> > >  
> >  



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-17 12:32       ` Jonathan Cameron
@ 2019-10-18 13:46         ` Andrea Merello
  2019-10-22  9:34           ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-10-18 13:46 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

Il giorno gio 17 ott 2019 alle ore 14:32 Jonathan Cameron
<jonathan.cameron@huawei.com> ha scritto:
>
> On Wed, 16 Oct 2019 15:14:20 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> > <jic23@kernel.org> ha scritto:
> > >
> > > On Mon, 23 Sep 2019 14:17:12 +0200
> > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > >
> > > > This sensor has an embedded notch filter for reducing interferences caused
> > > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > > (and harmonics).
> > > >
> > > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > > This patch introduces a IIO attribute that allows the user to set the said
> > > > filter to the desired frequency.
> > > >
> > > > NOTE: this has been intentionally not tied to any DT property to allow
> > > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > > switch or accessing some device that can autodetect the line frequency.
> > > >
> > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> > > This one is not something that can be expect to be known from the setup
> > > of the device as it will depend on local mains frequency.
> > >
> > > So fine, to have it as a userspace control, but the name is too generic.
> > > We already have a number of filter attributes and we should try to
> > > work out how to bring it inline with them.
> >
> > Sure
> >
> > > in_X_filter_low_pass_3db_frequency
> > > in_X_filter_high_pass_3db_frequency
> > >
> > > So would,
> > > in_X_filter_notch_center_frequency work?
> > > ( I suppose we should use the American spelling ;)
> >
> > Yes, it seems OK in this case. I will produce a V2 with this modification.
> >
> > > This kind of ignores the harmonics aspect but at least documents the
> > > main frequency being blocked.
> >
> > I think this is perfectly fine: the user wants to set the notch filter
> > center frequency to either 60Hz or 50Hz to match the line frequency,
> > then she/he expects the filter to simply "work" somehow; IMO the
> > harmonic thing does not needed to be explicit.
> >
> > > There is a slight complexity that we have devices that have dual
> > > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> > >
> > > I suppose no value would count as off and we could perhaps use a list
> > > for both on at the same time (though that's a bit horrible).
> >
> > IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> > could also use magic strings like i.e. "all" and "off".
>
> I go with 'maybe' on that one.  Need to think about whether that is just
> a partial solution as we will probably find a device with 3 options that only
> supports any 2 at one time.  That would still need a more complex interface.
>
> Will think on this.

I'll keep this patch on hold, waiting for your thoughts. Take the time
you need :)

BTW IMHO:

If we want to address the most possible generic case, then we may
standardize a set of possible attributes for filters (like "enable",
"center_frequency", "width",  "Q" , etc). Of course most filters will
not allow for setting most of those attributes.

Then i.e.  in our case we could have one single filter that allows for
setting the frequency to either 50hz or 60hz; in other cases we could
have i.e. two filters (with 50hz and 60hz center freq respectively),
and they would allow to set only the "enable" attribute; in case you
can i.e. enable only two of three filters, when you try to enable the
3rd it just refuse that. In this scenario probably "center_frequency"
could be just a regular value (not a list).

>
>
> Jonathan
>
> >
> > > > ---
> > > >  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
> > > >  1 file changed, 49 insertions(+)
> > > >
> > > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > > index 73ed550e3fc9..d12613f7ba3c 100644
> > > > --- a/drivers/iio/temperature/max31856.c
> > > > +++ b/drivers/iio/temperature/max31856.c
> > > > @@ -23,6 +23,7 @@
> > > >  #define MAX31856_CR0_1SHOT         BIT(6)
> > > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > > > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> > > >  struct max31856_data {
> > > >       struct spi_device *spi;
> > > >       u32 thermocouple_type;
> > > > +     bool filter_50hz;
> > > >  };
> > > >
> > > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> > > >       reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> > > >       reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> > > >
> > > > +     if (data->filter_50hz)
> > > > +             reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > > > +     else
> > > > +             reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > > > +
> > > >       return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> > > >  }
> > > >
> > > > @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
> > > >       return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> > > >  }
> > > >
> > > > +static ssize_t show_filter(struct device *dev,
> > > > +                        struct device_attribute *attr,
> > > > +                        char *buf)
> > > > +{
> > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > +
> > > > +     return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > > > +}
> > > > +
> > > > +static ssize_t set_filter(struct device *dev,
> > > > +                       struct device_attribute *attr,
> > > > +                       const char *buf,
> > > > +                       size_t len)
> > > > +{
> > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > +     unsigned int freq;
> > > > +     int ret;
> > > > +
> > > > +     ret = kstrtouint(buf, 10, &freq);
> > > > +     if (ret)
> > > > +             return ret;
> > > > +
> > > > +     switch (freq) {
> > > > +     case 50:
> > > > +             data->filter_50hz = true;
> > > > +             break;
> > > > +     case 60:
> > > > +             data->filter_50hz = false;
> > > > +             break;
> > > > +     default:
> > > > +             return -EINVAL;
> > > > +     }
> > > > +
> > > > +     max31856_init(data);
> > > > +     return len;
> > > > +}
> > > > +
> > > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > > +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > >
> > > >  static struct attribute *max31856_attributes[] = {
> > > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > > +     &iio_dev_attr_filter.dev_attr.attr,
> > > >       NULL,
> > > >  };
> > > >
> > > > @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
> > > >
> > > >       data = iio_priv(indio_dev);
> > > >       data->spi = spi;
> > > > +     data->filter_50hz = false;
> > > >
> > > >       spi_set_drvdata(spi, indio_dev);
> > > >
> > >
>
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 2/3] iio: max31856: add support for configuring the HW averaging
  2019-10-17 12:34       ` Jonathan Cameron
@ 2019-10-18 13:47         ` Andrea Merello
  0 siblings, 0 replies; 60+ messages in thread
From: Andrea Merello @ 2019-10-18 13:47 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

Il giorno gio 17 ott 2019 alle ore 14:34 Jonathan Cameron
<jonathan.cameron@huawei.com> ha scritto:
>
> On Wed, 16 Oct 2019 15:33:42 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > Il giorno dom 6 ott 2019 alle ore 09:55 Jonathan Cameron
> > <jic23@kernel.org> ha scritto:
> > >
> > > On Mon, 23 Sep 2019 14:17:13 +0200
> > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > >
> > > > This sensor can perform samples averaging in hardware, but currently the
> > > > driver leaves this setting alone (default is no averaging).
> > > >
> > > > This patch introduces a new IIO attribute that allows the user to set the
> > > > averaging as desired (the HW supports averaging of 2, 5, 8 or 16 samples)
> > > >
> > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> > >
> > > Sounds like oversampling combined with a lower sampling frequency, so
> > > there is standard ABI for that.
> >
> > OK. Do you refer to "oversampling_ratio"?
> >
> > The datasheet says this applies to thermocouple measure, but by doing
> > some testing with real HW, it seems that this setting affects both
> > thermocouple and cold-junction measures, so I guess it shouldn't be in
> > the form "in_temp_raw_oversampling_ratio"; does this sound right to
> > you?
> Ah yes. oversampling_ratio it is.  I should read our Docs :)

OK. I will do a V2 with this.

> I think
> in_temp_oversampling_ratio will be generated if you use the info_mask_shared_by_type
> to do this.
>
> _raw is just another type of information about the channel, rather than
> part of the channel naming.
>
> Thanks,
>
> Jonathan
>
> >
> > > Jonathan
> > >
> > > > ---
> > > >  drivers/iio/temperature/max31856.c | 43 ++++++++++++++++++++++++++++++
> > > >  1 file changed, 43 insertions(+)
> > > >
> > > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > > index d12613f7ba3c..8b2e0102fa5c 100644
> > > > --- a/drivers/iio/temperature/max31856.c
> > > > +++ b/drivers/iio/temperature/max31856.c
> > > > @@ -24,6 +24,8 @@
> > > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > > >  #define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > > > +#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
> > > > +#define MAX31856_AVERAGING_SHIFT   4
> > > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > > @@ -65,6 +67,7 @@ struct max31856_data {
> > > >       struct spi_device *spi;
> > > >       u32 thermocouple_type;
> > > >       bool filter_50hz;
> > > > +     int averaging;
> > > >  };
> > > >
> > > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > > @@ -109,6 +112,10 @@ static int max31856_init(struct max31856_data *data)
> > > >
> > > >       reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
> > > >       reg_cr1_val |= data->thermocouple_type;
> > > > +
> > > > +     reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
> > > > +     reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
> > > > +
> > > >       ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
> > > >       if (ret)
> > > >               return ret;
> > > > @@ -295,14 +302,50 @@ static ssize_t set_filter(struct device *dev,
> > > >       return len;
> > > >  }
> > > >
> > > > +static ssize_t show_averaging(struct device *dev,
> > > > +                           struct device_attribute *attr,
> > > > +                           char *buf)
> > > > +{
> > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > +
> > > > +     return sprintf(buf, "%d\n", 1 << data->averaging);
> > > > +}
> > > > +
> > > > +static ssize_t set_averaging(struct device *dev,
> > > > +                          struct device_attribute *attr,
> > > > +                          const char *buf,
> > > > +                          size_t len)
> > > > +{
> > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > +     unsigned int nsamples;
> > > > +     int shift;
> > > > +     int ret;
> > > > +
> > > > +     ret = kstrtouint(buf, 10, &nsamples);
> > > > +     if (ret)
> > > > +             return ret;
> > > > +
> > > > +     shift = fls(nsamples) - 1;
> > > > +     if (nsamples > 16 || BIT(shift) != nsamples)
> > > > +             return -EINVAL;
> > > > +
> > > > +     data->averaging = shift;
> > > > +     max31856_init(data);
> > > > +     return len;
> > > > +}
> > > > +
> > > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > >  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > > +static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
> > > >
> > > >  static struct attribute *max31856_attributes[] = {
> > > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > >       &iio_dev_attr_filter.dev_attr.attr,
> > > > +     &iio_dev_attr_averaging.dev_attr.attr,
> > > >       NULL,
> > > >  };
> > > >
> > >
>
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-10-17 12:35       ` Jonathan Cameron
@ 2019-10-18 13:48         ` Andrea Merello
  0 siblings, 0 replies; 60+ messages in thread
From: Andrea Merello @ 2019-10-18 13:48 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

Il giorno gio 17 ott 2019 alle ore 14:36 Jonathan Cameron
<jonathan.cameron@huawei.com> ha scritto:
>
> On Wed, 16 Oct 2019 15:43:18 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > Il giorno dom 6 ott 2019 alle ore 09:58 Jonathan Cameron
> > <jic23@kernel.org> ha scritto:
> > >
> > > On Mon, 23 Sep 2019 14:17:14 +0200
> > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > >
> > > > The sensor support various thermocouple types (e.g. J, K, N, ...). The
> > > > driver allows to configure this parameter using a DT property.
> > > >
> > > > This is useful when i.e. the thermocouple is physically tied to the sensor
> > > > and it is usually not removed, or when it is at least known in advace
> > >
> > > advance
> >
> > OK
> >
> > > > which sensor will be connected to the circuit.
> > > >
> > > > However, if the user can randomly connect any kind of thermocouples (i.e.
> > > > the device exposes a connector, and the user is free to connect its own
> > > > sensors), it would be more appropriate to provide a mechanism to
> > > > dynamically switch from one thermocouple type to another. This can be i.e.
> > > > handled in userspace by a GUI, a configuration file or a program that
> > > > detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
> > > > or whatever.
> > > >
> > > > This patch adds a IIO attribute that can be used to override, at run-time,
> > > > the DT-provided setting (which serves as default).
> > > >
> > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> > > For now this is device specific ABI so you need to have an entry in
> > > Documentation/ABI/testing/sysfs-bus-iio-max31856
> >
> > OK
> >
> > > Or we could consider this generic enough to put it in a file
> > > covering other thermocouple to digital sensors.
> >
> > Yes, theoretically thermocouple-type is a generic thing that isn't
> > bound to this specific driver/chip. Currently the others IIO
> > thermocouple drivers don't need this because they supports chips that
> > handle just a specific thermocouple type, but if you want to make this
> > API generic for the future then I can go this way.. It seems
> > reasonable to me indeed.
> >
>
> Lets do it then ;)  We might want to add a read only attrs to the
> other drivers to make them self describing.

Seems good!
Will do.

> Thanks,
>
> Jonathan
>
> > > Thanks,
> > >
> > > Jonathan
> > >
> > > > ---
> > > >  drivers/iio/temperature/max31856.c | 44 ++++++++++++++++++++++++++++++
> > > >  1 file changed, 44 insertions(+)
> > > >
> > > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > > index 8b2e0102fa5c..588e791c79a3 100644
> > > > --- a/drivers/iio/temperature/max31856.c
> > > > +++ b/drivers/iio/temperature/max31856.c
> > > > @@ -6,6 +6,7 @@
> > > >   * Copyright (C) 2018-2019 Rockwell Collins
> > > >   */
> > > >
> > > > +#include <linux/ctype.h>
> > > >  #include <linux/module.h>
> > > >  #include <linux/init.h>
> > > >  #include <linux/err.h>
> > > > @@ -70,6 +71,10 @@ struct max31856_data {
> > > >       int averaging;
> > > >  };
> > > >
> > > > +const char max31856_tc_types[] = {
> > > > +     'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
> > > > +};
> > > > +
> > > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > >                        u8 val[], unsigned int read_size)
> > > >  {
> > > > @@ -336,16 +341,55 @@ static ssize_t set_averaging(struct device *dev,
> > > >       return len;
> > > >  }
> > > >
> > > > +static ssize_t show_tc_type(struct device *dev,
> > > > +                         struct device_attribute *attr,
> > > > +                         char *buf)
> > > > +{
> > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > +
> > > > +     return sprintf(buf, "%c\n", max31856_tc_types[data->thermocouple_type]);
> > > > +}
> > > > +
> > > > +static ssize_t set_tc_type(struct device *dev,
> > > > +                        struct device_attribute *attr,
> > > > +                        const char *buf,
> > > > +                        size_t len)
> > > > +{
> > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > +     char tmp;
> > > > +     int tc_type = -1;
> > > > +     int i;
> > > > +
> > > > +     if (sscanf(buf, "%c\n", &tmp) != 1)
> > > > +             return -EINVAL;
> > > > +
> > > > +     for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
> > > > +             if (max31856_tc_types[i] == toupper(tmp)) {
> > > > +                     tc_type = i;
> > > > +                     break;
> > > > +             }
> > > > +     }
> > > > +     if (tc_type < 0)
> > > > +             return -EINVAL;
> > > > +     data->thermocouple_type = tc_type;
> > > > +     max31856_init(data);
> > > > +     return len;
> > > > +}
> > > > +
> > > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > >  static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > >  static IIO_DEVICE_ATTR(averaging, 0644, show_averaging, set_averaging, 0);
> > > > +static IIO_DEVICE_ATTR(thermocouple_type, 0644, show_tc_type, set_tc_type, 0);
> > > >
> > > >  static struct attribute *max31856_attributes[] = {
> > > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > >       &iio_dev_attr_filter.dev_attr.attr,
> > > >       &iio_dev_attr_averaging.dev_attr.attr,
> > > > +     &iio_dev_attr_thermocouple_type.dev_attr.attr,
> > > >       NULL,
> > > >  };
> > > >
> > >
>
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-18 13:46         ` Andrea Merello
@ 2019-10-22  9:34           ` Jonathan Cameron
  2019-10-23  8:29             ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-22  9:34 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

On Fri, 18 Oct 2019 15:46:32 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> Il giorno gio 17 ott 2019 alle ore 14:32 Jonathan Cameron
> <jonathan.cameron@huawei.com> ha scritto:
> >
> > On Wed, 16 Oct 2019 15:14:20 +0200
> > Andrea Merello <andrea.merello@gmail.com> wrote:
> >  
> > > Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> > > <jic23@kernel.org> ha scritto:  
> > > >
> > > > On Mon, 23 Sep 2019 14:17:12 +0200
> > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > >  
> > > > > This sensor has an embedded notch filter for reducing interferences caused
> > > > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > > > (and harmonics).
> > > > >
> > > > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > > > This patch introduces a IIO attribute that allows the user to set the said
> > > > > filter to the desired frequency.
> > > > >
> > > > > NOTE: this has been intentionally not tied to any DT property to allow
> > > > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > > > switch or accessing some device that can autodetect the line frequency.
> > > > >
> > > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>  
> > > > This one is not something that can be expect to be known from the setup
> > > > of the device as it will depend on local mains frequency.
> > > >
> > > > So fine, to have it as a userspace control, but the name is too generic.
> > > > We already have a number of filter attributes and we should try to
> > > > work out how to bring it inline with them.  
> > >
> > > Sure
> > >  
> > > > in_X_filter_low_pass_3db_frequency
> > > > in_X_filter_high_pass_3db_frequency
> > > >
> > > > So would,
> > > > in_X_filter_notch_center_frequency work?
> > > > ( I suppose we should use the American spelling ;)  
> > >
> > > Yes, it seems OK in this case. I will produce a V2 with this modification.
> > >  
> > > > This kind of ignores the harmonics aspect but at least documents the
> > > > main frequency being blocked.  
> > >
> > > I think this is perfectly fine: the user wants to set the notch filter
> > > center frequency to either 60Hz or 50Hz to match the line frequency,
> > > then she/he expects the filter to simply "work" somehow; IMO the
> > > harmonic thing does not needed to be explicit.
> > >  
> > > > There is a slight complexity that we have devices that have dual
> > > > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> > > >
> > > > I suppose no value would count as off and we could perhaps use a list
> > > > for both on at the same time (though that's a bit horrible).  
> > >
> > > IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> > > could also use magic strings like i.e. "all" and "off".  
> >
> > I go with 'maybe' on that one.  Need to think about whether that is just
> > a partial solution as we will probably find a device with 3 options that only
> > supports any 2 at one time.  That would still need a more complex interface.
> >
> > Will think on this.  
> 
> I'll keep this patch on hold, waiting for your thoughts. Take the time
> you need :)
> 
> BTW IMHO:
> 
> If we want to address the most possible generic case, then we may
> standardize a set of possible attributes for filters (like "enable",
> "center_frequency", "width",  "Q" , etc). Of course most filters will
> not allow for setting most of those attributes.

Absolutely.  We currently have a few defined for low and high pass
filters, but if there are more complex features to define we should
do so.

> 
> Then i.e.  in our case we could have one single filter that allows for
> setting the frequency to either 50hz or 60hz; in other cases we could
> have i.e. two filters (with 50hz and 60hz center freq respectively),
> and they would allow to set only the "enable" attribute; in case you
> can i.e. enable only two of three filters, when you try to enable the
> 3rd it just refuse that. In this scenario probably "center_frequency"
> could be just a regular value (not a list).

Agreed.  The question is whether to index filters.  So allow more
than one of a given type on a given channel. So far we have
only had the one and there isn't a nice way to support multiple
as we currently don't have any indexed parameters of a single channel.

I haven't seen parts that actually do have this level of sophisticated
filtering built in, with the exception of mains filters like this one.

I think we have to allow for the possibility so if you are happy to do
so please propose the ABI additions to support multiple filters of
a type. I would suggest keeping them per type though

e.g.

in_X_filter_low_passY_3db_frequency etc
with Y as the optional index.

For now, lets just implement then using extended attributes rather
than trying to extend the core to generate these automatically.

If this turns out not to be a corner case we can try to figure
out a sane way of generating the multiple indexed versions.


> 
> >
> >
> > Jonathan
> >  
> > >  
> > > > > ---
> > > > >  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
> > > > >  1 file changed, 49 insertions(+)
> > > > >
> > > > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > > > index 73ed550e3fc9..d12613f7ba3c 100644
> > > > > --- a/drivers/iio/temperature/max31856.c
> > > > > +++ b/drivers/iio/temperature/max31856.c
> > > > > @@ -23,6 +23,7 @@
> > > > >  #define MAX31856_CR0_1SHOT         BIT(6)
> > > > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > > > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > > > > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > > > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > > > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > > > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > > > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> > > > >  struct max31856_data {
> > > > >       struct spi_device *spi;
> > > > >       u32 thermocouple_type;
> > > > > +     bool filter_50hz;
> > > > >  };
> > > > >
> > > > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > > > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> > > > >       reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> > > > >       reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> > > > >
> > > > > +     if (data->filter_50hz)
> > > > > +             reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > > > > +     else
> > > > > +             reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > > > > +
> > > > >       return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> > > > >  }
> > > > >
> > > > > @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
> > > > >       return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> > > > >  }
> > > > >
> > > > > +static ssize_t show_filter(struct device *dev,
> > > > > +                        struct device_attribute *attr,
> > > > > +                        char *buf)
> > > > > +{
> > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > +
> > > > > +     return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > > > > +}
> > > > > +
> > > > > +static ssize_t set_filter(struct device *dev,
> > > > > +                       struct device_attribute *attr,
> > > > > +                       const char *buf,
> > > > > +                       size_t len)
> > > > > +{
> > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > +     unsigned int freq;
> > > > > +     int ret;
> > > > > +
> > > > > +     ret = kstrtouint(buf, 10, &freq);
> > > > > +     if (ret)
> > > > > +             return ret;
> > > > > +
> > > > > +     switch (freq) {
> > > > > +     case 50:
> > > > > +             data->filter_50hz = true;
> > > > > +             break;
> > > > > +     case 60:
> > > > > +             data->filter_50hz = false;
> > > > > +             break;
> > > > > +     default:
> > > > > +             return -EINVAL;
> > > > > +     }
> > > > > +
> > > > > +     max31856_init(data);
> > > > > +     return len;
> > > > > +}
> > > > > +
> > > > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > > > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > > > +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > > >
> > > > >  static struct attribute *max31856_attributes[] = {
> > > > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > > > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > > > +     &iio_dev_attr_filter.dev_attr.attr,
> > > > >       NULL,
> > > > >  };
> > > > >
> > > > > @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
> > > > >
> > > > >       data = iio_priv(indio_dev);
> > > > >       data->spi = spi;
> > > > > +     data->filter_50hz = false;
> > > > >
> > > > >       spi_set_drvdata(spi, indio_dev);
> > > > >  
> > > >  
> >
> >  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-22  9:34           ` Jonathan Cameron
@ 2019-10-23  8:29             ` Andrea Merello
  2019-10-27  9:22               ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-10-23  8:29 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

Il giorno mar 22 ott 2019 alle ore 11:35 Jonathan Cameron
<jic23@kernel.org> ha scritto:
>
> On Fri, 18 Oct 2019 15:46:32 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > Il giorno gio 17 ott 2019 alle ore 14:32 Jonathan Cameron
> > <jonathan.cameron@huawei.com> ha scritto:
> > >
> > > On Wed, 16 Oct 2019 15:14:20 +0200
> > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > >
> > > > Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> > > > <jic23@kernel.org> ha scritto:
> > > > >
> > > > > On Mon, 23 Sep 2019 14:17:12 +0200
> > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > >
> > > > > > This sensor has an embedded notch filter for reducing interferences caused
> > > > > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > > > > (and harmonics).
> > > > > >
> > > > > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > > > > This patch introduces a IIO attribute that allows the user to set the said
> > > > > > filter to the desired frequency.
> > > > > >
> > > > > > NOTE: this has been intentionally not tied to any DT property to allow
> > > > > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > > > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > > > > switch or accessing some device that can autodetect the line frequency.
> > > > > >
> > > > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> > > > > This one is not something that can be expect to be known from the setup
> > > > > of the device as it will depend on local mains frequency.
> > > > >
> > > > > So fine, to have it as a userspace control, but the name is too generic.
> > > > > We already have a number of filter attributes and we should try to
> > > > > work out how to bring it inline with them.
> > > >
> > > > Sure
> > > >
> > > > > in_X_filter_low_pass_3db_frequency
> > > > > in_X_filter_high_pass_3db_frequency
> > > > >
> > > > > So would,
> > > > > in_X_filter_notch_center_frequency work?
> > > > > ( I suppose we should use the American spelling ;)
> > > >
> > > > Yes, it seems OK in this case. I will produce a V2 with this modification.
> > > >
> > > > > This kind of ignores the harmonics aspect but at least documents the
> > > > > main frequency being blocked.
> > > >
> > > > I think this is perfectly fine: the user wants to set the notch filter
> > > > center frequency to either 60Hz or 50Hz to match the line frequency,
> > > > then she/he expects the filter to simply "work" somehow; IMO the
> > > > harmonic thing does not needed to be explicit.
> > > >
> > > > > There is a slight complexity that we have devices that have dual
> > > > > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> > > > >
> > > > > I suppose no value would count as off and we could perhaps use a list
> > > > > for both on at the same time (though that's a bit horrible).
> > > >
> > > > IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> > > > could also use magic strings like i.e. "all" and "off".
> > >
> > > I go with 'maybe' on that one.  Need to think about whether that is just
> > > a partial solution as we will probably find a device with 3 options that only
> > > supports any 2 at one time.  That would still need a more complex interface.
> > >
> > > Will think on this.
> >
> > I'll keep this patch on hold, waiting for your thoughts. Take the time
> > you need :)
> >
> > BTW IMHO:
> >
> > If we want to address the most possible generic case, then we may
> > standardize a set of possible attributes for filters (like "enable",
> > "center_frequency", "width",  "Q" , etc). Of course most filters will
> > not allow for setting most of those attributes.
>
> Absolutely.  We currently have a few defined for low and high pass
> filters, but if there are more complex features to define we should
> do so.
>
> >
> > Then i.e.  in our case we could have one single filter that allows for
> > setting the frequency to either 50hz or 60hz; in other cases we could
> > have i.e. two filters (with 50hz and 60hz center freq respectively),
> > and they would allow to set only the "enable" attribute; in case you
> > can i.e. enable only two of three filters, when you try to enable the
> > 3rd it just refuse that. In this scenario probably "center_frequency"
> > could be just a regular value (not a list).
>
> Agreed.  The question is whether to index filters.  So allow more
> than one of a given type on a given channel. So far we have
> only had the one and there isn't a nice way to support multiple
> as we currently don't have any indexed parameters of a single channel.

Yes, being able to indexing filters was the underlying assumption..

> I haven't seen parts that actually do have this level of sophisticated
> filtering built in, with the exception of mains filters like this one.

Yes, I didn't too indeed.

> I think we have to allow for the possibility so if you are happy to do
> so please propose the ABI additions to support multiple filters of
> a type. I would suggest keeping them per type though
>
> e.g.
>
> in_X_filter_low_passY_3db_frequency etc
> with Y as the optional index.

Seems reasonable.

Well the idea is the one you've just explained here, that is adding an
optional index for filters (per type and per ch); I'm not getting what
do you mean about proposing it..

> For now, lets just implement then using extended attributes rather
> than trying to extend the core to generate these automatically.
>
> If this turns out not to be a corner case we can try to figure
> out a sane way of generating the multiple indexed versions.

OK. Let's try not to over-complicate things until it's really needed -
Also, maybe if we'll hit other weird devices that need something like
this, then they could have some exotic features that we haven't in
mind yet now; it might turn out that we need something even more
different, so maybe it's better to wait for real "users" of the ABI
before deciding how to change it..

But indeed, getting back to the patch originally discussed in this
thread: if you are OK whit this, then I'll go with a
"in_temp_filter_notch_center_frequency" attribute.

I may use a specific IIO_DEVIC_ATTR or add it to the core (without
addressing the index thing), as you prefer.

BTW: Looking at other drivers, it seems that for other attributes
(e.g. oversampling_ratio, discussed in 2/3) they tend to round
required values to the closest allowed value, instead of returning an
error. In this specific case, do you want to apply the same logic? For
consistency reasons I would do that, but at the practical side,
requiring a line filter frequency which is not either 50Hz or 60Hz
seems really an error to me..

>
> >
> > >
> > >
> > > Jonathan
> > >
> > > >
> > > > > > ---
> > > > > >  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
> > > > > >  1 file changed, 49 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > > > > index 73ed550e3fc9..d12613f7ba3c 100644
> > > > > > --- a/drivers/iio/temperature/max31856.c
> > > > > > +++ b/drivers/iio/temperature/max31856.c
> > > > > > @@ -23,6 +23,7 @@
> > > > > >  #define MAX31856_CR0_1SHOT         BIT(6)
> > > > > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > > > > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > > > > > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > > > > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > > > > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > > > > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > > > > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> > > > > >  struct max31856_data {
> > > > > >       struct spi_device *spi;
> > > > > >       u32 thermocouple_type;
> > > > > > +     bool filter_50hz;
> > > > > >  };
> > > > > >
> > > > > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > > > > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> > > > > >       reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> > > > > >       reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> > > > > >
> > > > > > +     if (data->filter_50hz)
> > > > > > +             reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > > > > > +     else
> > > > > > +             reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > > > > > +
> > > > > >       return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> > > > > >  }
> > > > > >
> > > > > > @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
> > > > > >       return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> > > > > >  }
> > > > > >
> > > > > > +static ssize_t show_filter(struct device *dev,
> > > > > > +                        struct device_attribute *attr,
> > > > > > +                        char *buf)
> > > > > > +{
> > > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > > +
> > > > > > +     return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > > > > > +}
> > > > > > +
> > > > > > +static ssize_t set_filter(struct device *dev,
> > > > > > +                       struct device_attribute *attr,
> > > > > > +                       const char *buf,
> > > > > > +                       size_t len)
> > > > > > +{
> > > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > > +     unsigned int freq;
> > > > > > +     int ret;
> > > > > > +
> > > > > > +     ret = kstrtouint(buf, 10, &freq);
> > > > > > +     if (ret)
> > > > > > +             return ret;
> > > > > > +
> > > > > > +     switch (freq) {
> > > > > > +     case 50:
> > > > > > +             data->filter_50hz = true;
> > > > > > +             break;
> > > > > > +     case 60:
> > > > > > +             data->filter_50hz = false;
> > > > > > +             break;
> > > > > > +     default:
> > > > > > +             return -EINVAL;
> > > > > > +     }
> > > > > > +
> > > > > > +     max31856_init(data);
> > > > > > +     return len;
> > > > > > +}
> > > > > > +
> > > > > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > > > > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > > > > +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > > > >
> > > > > >  static struct attribute *max31856_attributes[] = {
> > > > > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > > > > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > > > > +     &iio_dev_attr_filter.dev_attr.attr,
> > > > > >       NULL,
> > > > > >  };
> > > > > >
> > > > > > @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
> > > > > >
> > > > > >       data = iio_priv(indio_dev);
> > > > > >       data->spi = spi;
> > > > > > +     data->filter_50hz = false;
> > > > > >
> > > > > >       spi_set_drvdata(spi, indio_dev);
> > > > > >
> > > > >
> > >
> > >
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-23  8:29             ` Andrea Merello
@ 2019-10-27  9:22               ` Jonathan Cameron
  2019-10-28  7:32                 ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-10-27  9:22 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

On Wed, 23 Oct 2019 10:29:07 +0200
Andrea Merello <andrea.merello@gmail.com> wrote:

> Il giorno mar 22 ott 2019 alle ore 11:35 Jonathan Cameron
> <jic23@kernel.org> ha scritto:
> >
> > On Fri, 18 Oct 2019 15:46:32 +0200
> > Andrea Merello <andrea.merello@gmail.com> wrote:
> >  
> > > Il giorno gio 17 ott 2019 alle ore 14:32 Jonathan Cameron
> > > <jonathan.cameron@huawei.com> ha scritto:  
> > > >
> > > > On Wed, 16 Oct 2019 15:14:20 +0200
> > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > >  
> > > > > Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> > > > > <jic23@kernel.org> ha scritto:  
> > > > > >
> > > > > > On Mon, 23 Sep 2019 14:17:12 +0200
> > > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > > >  
> > > > > > > This sensor has an embedded notch filter for reducing interferences caused
> > > > > > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > > > > > (and harmonics).
> > > > > > >
> > > > > > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > > > > > This patch introduces a IIO attribute that allows the user to set the said
> > > > > > > filter to the desired frequency.
> > > > > > >
> > > > > > > NOTE: this has been intentionally not tied to any DT property to allow
> > > > > > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > > > > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > > > > > switch or accessing some device that can autodetect the line frequency.
> > > > > > >
> > > > > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>  
> > > > > > This one is not something that can be expect to be known from the setup
> > > > > > of the device as it will depend on local mains frequency.
> > > > > >
> > > > > > So fine, to have it as a userspace control, but the name is too generic.
> > > > > > We already have a number of filter attributes and we should try to
> > > > > > work out how to bring it inline with them.  
> > > > >
> > > > > Sure
> > > > >  
> > > > > > in_X_filter_low_pass_3db_frequency
> > > > > > in_X_filter_high_pass_3db_frequency
> > > > > >
> > > > > > So would,
> > > > > > in_X_filter_notch_center_frequency work?
> > > > > > ( I suppose we should use the American spelling ;)  
> > > > >
> > > > > Yes, it seems OK in this case. I will produce a V2 with this modification.
> > > > >  
> > > > > > This kind of ignores the harmonics aspect but at least documents the
> > > > > > main frequency being blocked.  
> > > > >
> > > > > I think this is perfectly fine: the user wants to set the notch filter
> > > > > center frequency to either 60Hz or 50Hz to match the line frequency,
> > > > > then she/he expects the filter to simply "work" somehow; IMO the
> > > > > harmonic thing does not needed to be explicit.
> > > > >  
> > > > > > There is a slight complexity that we have devices that have dual
> > > > > > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> > > > > >
> > > > > > I suppose no value would count as off and we could perhaps use a list
> > > > > > for both on at the same time (though that's a bit horrible).  
> > > > >
> > > > > IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> > > > > could also use magic strings like i.e. "all" and "off".  
> > > >
> > > > I go with 'maybe' on that one.  Need to think about whether that is just
> > > > a partial solution as we will probably find a device with 3 options that only
> > > > supports any 2 at one time.  That would still need a more complex interface.
> > > >
> > > > Will think on this.  
> > >
> > > I'll keep this patch on hold, waiting for your thoughts. Take the time
> > > you need :)
> > >
> > > BTW IMHO:
> > >
> > > If we want to address the most possible generic case, then we may
> > > standardize a set of possible attributes for filters (like "enable",
> > > "center_frequency", "width",  "Q" , etc). Of course most filters will
> > > not allow for setting most of those attributes.  
> >
> > Absolutely.  We currently have a few defined for low and high pass
> > filters, but if there are more complex features to define we should
> > do so.
> >  
> > >
> > > Then i.e.  in our case we could have one single filter that allows for
> > > setting the frequency to either 50hz or 60hz; in other cases we could
> > > have i.e. two filters (with 50hz and 60hz center freq respectively),
> > > and they would allow to set only the "enable" attribute; in case you
> > > can i.e. enable only two of three filters, when you try to enable the
> > > 3rd it just refuse that. In this scenario probably "center_frequency"
> > > could be just a regular value (not a list).  
> >
> > Agreed.  The question is whether to index filters.  So allow more
> > than one of a given type on a given channel. So far we have
> > only had the one and there isn't a nice way to support multiple
> > as we currently don't have any indexed parameters of a single channel.  
> 
> Yes, being able to indexing filters was the underlying assumption..
> 
> > I haven't seen parts that actually do have this level of sophisticated
> > filtering built in, with the exception of mains filters like this one.  
> 
> Yes, I didn't too indeed.
> 
> > I think we have to allow for the possibility so if you are happy to do
> > so please propose the ABI additions to support multiple filters of
> > a type. I would suggest keeping them per type though
> >
> > e.g.
> >
> > in_X_filter_low_passY_3db_frequency etc
> > with Y as the optional index.  
> 
> Seems reasonable.
> 
> Well the idea is the one you've just explained here, that is adding an
> optional index for filters (per type and per ch); I'm not getting what
> do you mean about proposing it..
Like all new ABI, needs a formal documentation patch.  Sometimes
we get more review on those than on discussions deep in a thread like
this.

> 
> > For now, lets just implement then using extended attributes rather
> > than trying to extend the core to generate these automatically.
> >
> > If this turns out not to be a corner case we can try to figure
> > out a sane way of generating the multiple indexed versions.  
> 
> OK. Let's try not to over-complicate things until it's really needed -
> Also, maybe if we'll hit other weird devices that need something like
> this, then they could have some exotic features that we haven't in
> mind yet now; it might turn out that we need something even more
> different, so maybe it's better to wait for real "users" of the ABI
> before deciding how to change it..
> 
> But indeed, getting back to the patch originally discussed in this
> thread: if you are OK whit this, then I'll go with a
> "in_temp_filter_notch_center_frequency" attribute.
> 
> I may use a specific IIO_DEVIC_ATTR or add it to the core (without
> addressing the index thing), as you prefer.

Which ever makes most sense to you. Either is fine for a new
attribute, though here don't we need the indexed filters?

> 
> BTW: Looking at other drivers, it seems that for other attributes
> (e.g. oversampling_ratio, discussed in 2/3) they tend to round
> required values to the closest allowed value, instead of returning an
> error. In this specific case, do you want to apply the same logic? For
> consistency reasons I would do that, but at the practical side,
> requiring a line filter frequency which is not either 50Hz or 60Hz
> seems really an error to me..

It can be a bit of a tricky decision but for something like this
where the precise value works, it should reject incorrect ones.

Oversampling is an odd one.  It should probably always round up
as it's usually not a problem to average more results, it just
wastes power.  That only applies if the oversampling_ratio
is independent of other attributes such as sampling frequency.

Still, we have traditionally been relaxed on this as long
as writing the the 'correct' value always works as that's what
userspace ABI should be doing.

Jonathan

> 
> >  
> > >  
> > > >
> > > >
> > > > Jonathan
> > > >  
> > > > >  
> > > > > > > ---
> > > > > > >  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
> > > > > > >  1 file changed, 49 insertions(+)
> > > > > > >
> > > > > > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > > > > > index 73ed550e3fc9..d12613f7ba3c 100644
> > > > > > > --- a/drivers/iio/temperature/max31856.c
> > > > > > > +++ b/drivers/iio/temperature/max31856.c
> > > > > > > @@ -23,6 +23,7 @@
> > > > > > >  #define MAX31856_CR0_1SHOT         BIT(6)
> > > > > > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > > > > > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > > > > > > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > > > > > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > > > > > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > > > > > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > > > > > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> > > > > > >  struct max31856_data {
> > > > > > >       struct spi_device *spi;
> > > > > > >       u32 thermocouple_type;
> > > > > > > +     bool filter_50hz;
> > > > > > >  };
> > > > > > >
> > > > > > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > > > > > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> > > > > > >       reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> > > > > > >       reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> > > > > > >
> > > > > > > +     if (data->filter_50hz)
> > > > > > > +             reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > > > > > > +     else
> > > > > > > +             reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > > > > > > +
> > > > > > >       return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> > > > > > >  }
> > > > > > >
> > > > > > > @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
> > > > > > >       return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> > > > > > >  }
> > > > > > >
> > > > > > > +static ssize_t show_filter(struct device *dev,
> > > > > > > +                        struct device_attribute *attr,
> > > > > > > +                        char *buf)
> > > > > > > +{
> > > > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > > > +
> > > > > > > +     return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > > > > > > +}
> > > > > > > +
> > > > > > > +static ssize_t set_filter(struct device *dev,
> > > > > > > +                       struct device_attribute *attr,
> > > > > > > +                       const char *buf,
> > > > > > > +                       size_t len)
> > > > > > > +{
> > > > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > > > +     unsigned int freq;
> > > > > > > +     int ret;
> > > > > > > +
> > > > > > > +     ret = kstrtouint(buf, 10, &freq);
> > > > > > > +     if (ret)
> > > > > > > +             return ret;
> > > > > > > +
> > > > > > > +     switch (freq) {
> > > > > > > +     case 50:
> > > > > > > +             data->filter_50hz = true;
> > > > > > > +             break;
> > > > > > > +     case 60:
> > > > > > > +             data->filter_50hz = false;
> > > > > > > +             break;
> > > > > > > +     default:
> > > > > > > +             return -EINVAL;
> > > > > > > +     }
> > > > > > > +
> > > > > > > +     max31856_init(data);
> > > > > > > +     return len;
> > > > > > > +}
> > > > > > > +
> > > > > > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > > > > > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > > > > > +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > > > > >
> > > > > > >  static struct attribute *max31856_attributes[] = {
> > > > > > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > > > > > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > > > > > +     &iio_dev_attr_filter.dev_attr.attr,
> > > > > > >       NULL,
> > > > > > >  };
> > > > > > >
> > > > > > > @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
> > > > > > >
> > > > > > >       data = iio_priv(indio_dev);
> > > > > > >       data->spi = spi;
> > > > > > > +     data->filter_50hz = false;
> > > > > > >
> > > > > > >       spi_set_drvdata(spi, indio_dev);
> > > > > > >  
> > > > > >  
> > > >
> > > >  
> >  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-27  9:22               ` Jonathan Cameron
@ 2019-10-28  7:32                 ` Andrea Merello
  2019-11-02 14:17                   ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-10-28  7:32 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

Il giorno dom 27 ott 2019 alle ore 10:23 Jonathan Cameron
<jic23@kernel.org> ha scritto:
>
> On Wed, 23 Oct 2019 10:29:07 +0200
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > Il giorno mar 22 ott 2019 alle ore 11:35 Jonathan Cameron
> > <jic23@kernel.org> ha scritto:
> > >
> > > On Fri, 18 Oct 2019 15:46:32 +0200
> > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > >
> > > > Il giorno gio 17 ott 2019 alle ore 14:32 Jonathan Cameron
> > > > <jonathan.cameron@huawei.com> ha scritto:
> > > > >
> > > > > On Wed, 16 Oct 2019 15:14:20 +0200
> > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > >
> > > > > > Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> > > > > > <jic23@kernel.org> ha scritto:
> > > > > > >
> > > > > > > On Mon, 23 Sep 2019 14:17:12 +0200
> > > > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > > > >
> > > > > > > > This sensor has an embedded notch filter for reducing interferences caused
> > > > > > > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > > > > > > (and harmonics).
> > > > > > > >
> > > > > > > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > > > > > > This patch introduces a IIO attribute that allows the user to set the said
> > > > > > > > filter to the desired frequency.
> > > > > > > >
> > > > > > > > NOTE: this has been intentionally not tied to any DT property to allow
> > > > > > > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > > > > > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > > > > > > switch or accessing some device that can autodetect the line frequency.
> > > > > > > >
> > > > > > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> > > > > > > This one is not something that can be expect to be known from the setup
> > > > > > > of the device as it will depend on local mains frequency.
> > > > > > >
> > > > > > > So fine, to have it as a userspace control, but the name is too generic.
> > > > > > > We already have a number of filter attributes and we should try to
> > > > > > > work out how to bring it inline with them.
> > > > > >
> > > > > > Sure
> > > > > >
> > > > > > > in_X_filter_low_pass_3db_frequency
> > > > > > > in_X_filter_high_pass_3db_frequency
> > > > > > >
> > > > > > > So would,
> > > > > > > in_X_filter_notch_center_frequency work?
> > > > > > > ( I suppose we should use the American spelling ;)
> > > > > >
> > > > > > Yes, it seems OK in this case. I will produce a V2 with this modification.
> > > > > >
> > > > > > > This kind of ignores the harmonics aspect but at least documents the
> > > > > > > main frequency being blocked.
> > > > > >
> > > > > > I think this is perfectly fine: the user wants to set the notch filter
> > > > > > center frequency to either 60Hz or 50Hz to match the line frequency,
> > > > > > then she/he expects the filter to simply "work" somehow; IMO the
> > > > > > harmonic thing does not needed to be explicit.
> > > > > >
> > > > > > > There is a slight complexity that we have devices that have dual
> > > > > > > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> > > > > > >
> > > > > > > I suppose no value would count as off and we could perhaps use a list
> > > > > > > for both on at the same time (though that's a bit horrible).
> > > > > >
> > > > > > IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> > > > > > could also use magic strings like i.e. "all" and "off".
> > > > >
> > > > > I go with 'maybe' on that one.  Need to think about whether that is just
> > > > > a partial solution as we will probably find a device with 3 options that only
> > > > > supports any 2 at one time.  That would still need a more complex interface.
> > > > >
> > > > > Will think on this.
> > > >
> > > > I'll keep this patch on hold, waiting for your thoughts. Take the time
> > > > you need :)
> > > >
> > > > BTW IMHO:
> > > >
> > > > If we want to address the most possible generic case, then we may
> > > > standardize a set of possible attributes for filters (like "enable",
> > > > "center_frequency", "width",  "Q" , etc). Of course most filters will
> > > > not allow for setting most of those attributes.
> > >
> > > Absolutely.  We currently have a few defined for low and high pass
> > > filters, but if there are more complex features to define we should
> > > do so.
> > >
> > > >
> > > > Then i.e.  in our case we could have one single filter that allows for
> > > > setting the frequency to either 50hz or 60hz; in other cases we could
> > > > have i.e. two filters (with 50hz and 60hz center freq respectively),
> > > > and they would allow to set only the "enable" attribute; in case you
> > > > can i.e. enable only two of three filters, when you try to enable the
> > > > 3rd it just refuse that. In this scenario probably "center_frequency"
> > > > could be just a regular value (not a list).
> > >
> > > Agreed.  The question is whether to index filters.  So allow more
> > > than one of a given type on a given channel. So far we have
> > > only had the one and there isn't a nice way to support multiple
> > > as we currently don't have any indexed parameters of a single channel.
> >
> > Yes, being able to indexing filters was the underlying assumption..
> >
> > > I haven't seen parts that actually do have this level of sophisticated
> > > filtering built in, with the exception of mains filters like this one.
> >
> > Yes, I didn't too indeed.
> >
> > > I think we have to allow for the possibility so if you are happy to do
> > > so please propose the ABI additions to support multiple filters of
> > > a type. I would suggest keeping them per type though
> > >
> > > e.g.
> > >
> > > in_X_filter_low_passY_3db_frequency etc
> > > with Y as the optional index.
> >
> > Seems reasonable.
> >
> > Well the idea is the one you've just explained here, that is adding an
> > optional index for filters (per type and per ch); I'm not getting what
> > do you mean about proposing it..
> Like all new ABI, needs a formal documentation patch.  Sometimes
> we get more review on those than on discussions deep in a thread like
> this.

OK, this is honestly a bit out of my scope, but - if this is OK for
you - I may try to do that after getting to some end with those
in-flight patches..

> >
> > > For now, lets just implement then using extended attributes rather
> > > than trying to extend the core to generate these automatically.
> > >
> > > If this turns out not to be a corner case we can try to figure
> > > out a sane way of generating the multiple indexed versions.
> >
> > OK. Let's try not to over-complicate things until it's really needed -
> > Also, maybe if we'll hit other weird devices that need something like
> > this, then they could have some exotic features that we haven't in
> > mind yet now; it might turn out that we need something even more
> > different, so maybe it's better to wait for real "users" of the ABI
> > before deciding how to change it..
> >
> > But indeed, getting back to the patch originally discussed in this
> > thread: if you are OK whit this, then I'll go with a
> > "in_temp_filter_notch_center_frequency" attribute.
> >
> > I may use a specific IIO_DEVIC_ATTR or add it to the core (without
> > addressing the index thing), as you prefer.
>
> Which ever makes most sense to you. Either is fine for a new
> attribute, though here don't we need the indexed filters?

This specific device has only the option to choose either 50Hz
filtering or 60Hz filtering; no option to disable filtering or enable
both frequency. So I would say that here we can expose just one filter
for which the center frequency can be set to either 50Hz or 60Hz (like
the original patch did - but with proper name this time). I would say
that we don't need indexed filters here. Or have I missed something ?

(So I would start with a IIO_DEVICE_ATTR for now then).

> >
> > BTW: Looking at other drivers, it seems that for other attributes
> > (e.g. oversampling_ratio, discussed in 2/3) they tend to round
> > required values to the closest allowed value, instead of returning an
> > error. In this specific case, do you want to apply the same logic? For
> > consistency reasons I would do that, but at the practical side,
> > requiring a line filter frequency which is not either 50Hz or 60Hz
> > seems really an error to me..
>
> It can be a bit of a tricky decision but for something like this
> where the precise value works, it should reject incorrect ones.

OK

> Oversampling is an odd one.  It should probably always round up
> as it's usually not a problem to average more results, it just
> wastes power.  That only applies if the oversampling_ratio
> is independent of other attributes such as sampling frequency.

It actually affects also the sampling rate; the more samples you
average, the slowest output rate you achieve. But actually there is no
attribute for setting the sampling frequency.. it is internally
adjusted by the chip depending by averaging and filter line frequency
(don't know why).

(if we want also this attribute, then I can craft another patch for
adding it; it may be usefult to report the actual sample rate, I'm not
sure if it makes sense to let the user set it, because we can
basically just switch the averaging to one of the few possible values
to get the sample rate to change as a side effect - assuming that one
doesn't want to change the line frequency filter).

BTW What about to round the requested oversampling_ratio to the
closest allowed value (instead of rounding up)?

> Still, we have traditionally been relaxed on this as long
> as writing the the 'correct' value always works as that's what
> userspace ABI should be doing.
>
> Jonathan
>
> >
> > >
> > > >
> > > > >
> > > > >
> > > > > Jonathan
> > > > >
> > > > > >
> > > > > > > > ---
> > > > > > > >  drivers/iio/temperature/max31856.c | 49 ++++++++++++++++++++++++++++++
> > > > > > > >  1 file changed, 49 insertions(+)
> > > > > > > >
> > > > > > > > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > > > > > > > index 73ed550e3fc9..d12613f7ba3c 100644
> > > > > > > > --- a/drivers/iio/temperature/max31856.c
> > > > > > > > +++ b/drivers/iio/temperature/max31856.c
> > > > > > > > @@ -23,6 +23,7 @@
> > > > > > > >  #define MAX31856_CR0_1SHOT         BIT(6)
> > > > > > > >  #define MAX31856_CR0_OCFAULT       BIT(4)
> > > > > > > >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > > > > > > > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> > > > > > > >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> > > > > > > >  #define MAX31856_FAULT_OVUV        BIT(1)
> > > > > > > >  #define MAX31856_FAULT_OPEN        BIT(0)
> > > > > > > > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> > > > > > > >  struct max31856_data {
> > > > > > > >       struct spi_device *spi;
> > > > > > > >       u32 thermocouple_type;
> > > > > > > > +     bool filter_50hz;
> > > > > > > >  };
> > > > > > > >
> > > > > > > >  static int max31856_read(struct max31856_data *data, u8 reg,
> > > > > > > > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> > > > > > > >       reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> > > > > > > >       reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> > > > > > > >
> > > > > > > > +     if (data->filter_50hz)
> > > > > > > > +             reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > > > > > > > +     else
> > > > > > > > +             reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > > > > > > > +
> > > > > > > >       return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> > > > > > > >  }
> > > > > > > >
> > > > > > > > @@ -249,12 +256,53 @@ static ssize_t show_fault_oc(struct device *dev,
> > > > > > > >       return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> > > > > > > >  }
> > > > > > > >
> > > > > > > > +static ssize_t show_filter(struct device *dev,
> > > > > > > > +                        struct device_attribute *attr,
> > > > > > > > +                        char *buf)
> > > > > > > > +{
> > > > > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > > > > +
> > > > > > > > +     return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static ssize_t set_filter(struct device *dev,
> > > > > > > > +                       struct device_attribute *attr,
> > > > > > > > +                       const char *buf,
> > > > > > > > +                       size_t len)
> > > > > > > > +{
> > > > > > > > +     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > > > > > > > +     struct max31856_data *data = iio_priv(indio_dev);
> > > > > > > > +     unsigned int freq;
> > > > > > > > +     int ret;
> > > > > > > > +
> > > > > > > > +     ret = kstrtouint(buf, 10, &freq);
> > > > > > > > +     if (ret)
> > > > > > > > +             return ret;
> > > > > > > > +
> > > > > > > > +     switch (freq) {
> > > > > > > > +     case 50:
> > > > > > > > +             data->filter_50hz = true;
> > > > > > > > +             break;
> > > > > > > > +     case 60:
> > > > > > > > +             data->filter_50hz = false;
> > > > > > > > +             break;
> > > > > > > > +     default:
> > > > > > > > +             return -EINVAL;
> > > > > > > > +     }
> > > > > > > > +
> > > > > > > > +     max31856_init(data);
> > > > > > > > +     return len;
> > > > > > > > +}
> > > > > > > > +
> > > > > > > >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> > > > > > > >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > > > > > > > +static IIO_DEVICE_ATTR(filter, 0644, show_filter, set_filter, 0);
> > > > > > > >
> > > > > > > >  static struct attribute *max31856_attributes[] = {
> > > > > > > >       &iio_dev_attr_fault_ovuv.dev_attr.attr,
> > > > > > > >       &iio_dev_attr_fault_oc.dev_attr.attr,
> > > > > > > > +     &iio_dev_attr_filter.dev_attr.attr,
> > > > > > > >       NULL,
> > > > > > > >  };
> > > > > > > >
> > > > > > > > @@ -280,6 +328,7 @@ static int max31856_probe(struct spi_device *spi)
> > > > > > > >
> > > > > > > >       data = iio_priv(indio_dev);
> > > > > > > >       data->spi = spi;
> > > > > > > > +     data->filter_50hz = false;
> > > > > > > >
> > > > > > > >       spi_set_drvdata(spi, indio_dev);
> > > > > > > >
> > > > > > >
> > > > >
> > > > >
> > >
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-10-28  7:32                 ` Andrea Merello
@ 2019-11-02 14:17                   ` Jonathan Cameron
  2019-11-04 13:51                     ` Andrea Merello
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-02 14:17 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

On Mon, 28 Oct 2019 08:32:48 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> Il giorno dom 27 ott 2019 alle ore 10:23 Jonathan Cameron
> <jic23@kernel.org> ha scritto:
> >
> > On Wed, 23 Oct 2019 10:29:07 +0200
> > Andrea Merello <andrea.merello@gmail.com> wrote:
> >  
> > > Il giorno mar 22 ott 2019 alle ore 11:35 Jonathan Cameron
> > > <jic23@kernel.org> ha scritto:  
> > > >
> > > > On Fri, 18 Oct 2019 15:46:32 +0200
> > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > >  
> > > > > Il giorno gio 17 ott 2019 alle ore 14:32 Jonathan Cameron
> > > > > <jonathan.cameron@huawei.com> ha scritto:  
> > > > > >
> > > > > > On Wed, 16 Oct 2019 15:14:20 +0200
> > > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > > >  
> > > > > > > Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> > > > > > > <jic23@kernel.org> ha scritto:  
> > > > > > > >
> > > > > > > > On Mon, 23 Sep 2019 14:17:12 +0200
> > > > > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > > > > >  
> > > > > > > > > This sensor has an embedded notch filter for reducing interferences caused
> > > > > > > > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > > > > > > > (and harmonics).
> > > > > > > > >
> > > > > > > > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > > > > > > > This patch introduces a IIO attribute that allows the user to set the said
> > > > > > > > > filter to the desired frequency.
> > > > > > > > >
> > > > > > > > > NOTE: this has been intentionally not tied to any DT property to allow
> > > > > > > > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > > > > > > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > > > > > > > switch or accessing some device that can autodetect the line frequency.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>  
> > > > > > > > This one is not something that can be expect to be known from the setup
> > > > > > > > of the device as it will depend on local mains frequency.
> > > > > > > >
> > > > > > > > So fine, to have it as a userspace control, but the name is too generic.
> > > > > > > > We already have a number of filter attributes and we should try to
> > > > > > > > work out how to bring it inline with them.  
> > > > > > >
> > > > > > > Sure
> > > > > > >  
> > > > > > > > in_X_filter_low_pass_3db_frequency
> > > > > > > > in_X_filter_high_pass_3db_frequency
> > > > > > > >
> > > > > > > > So would,
> > > > > > > > in_X_filter_notch_center_frequency work?
> > > > > > > > ( I suppose we should use the American spelling ;)  
> > > > > > >
> > > > > > > Yes, it seems OK in this case. I will produce a V2 with this modification.
> > > > > > >  
> > > > > > > > This kind of ignores the harmonics aspect but at least documents the
> > > > > > > > main frequency being blocked.  
> > > > > > >
> > > > > > > I think this is perfectly fine: the user wants to set the notch filter
> > > > > > > center frequency to either 60Hz or 50Hz to match the line frequency,
> > > > > > > then she/he expects the filter to simply "work" somehow; IMO the
> > > > > > > harmonic thing does not needed to be explicit.
> > > > > > >  
> > > > > > > > There is a slight complexity that we have devices that have dual
> > > > > > > > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> > > > > > > >
> > > > > > > > I suppose no value would count as off and we could perhaps use a list
> > > > > > > > for both on at the same time (though that's a bit horrible).  
> > > > > > >
> > > > > > > IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> > > > > > > could also use magic strings like i.e. "all" and "off".  
> > > > > >
> > > > > > I go with 'maybe' on that one.  Need to think about whether that is just
> > > > > > a partial solution as we will probably find a device with 3 options that only
> > > > > > supports any 2 at one time.  That would still need a more complex interface.
> > > > > >
> > > > > > Will think on this.  
> > > > >
> > > > > I'll keep this patch on hold, waiting for your thoughts. Take the time
> > > > > you need :)
> > > > >
> > > > > BTW IMHO:
> > > > >
> > > > > If we want to address the most possible generic case, then we may
> > > > > standardize a set of possible attributes for filters (like "enable",
> > > > > "center_frequency", "width",  "Q" , etc). Of course most filters will
> > > > > not allow for setting most of those attributes.  
> > > >
> > > > Absolutely.  We currently have a few defined for low and high pass
> > > > filters, but if there are more complex features to define we should
> > > > do so.
> > > >  
> > > > >
> > > > > Then i.e.  in our case we could have one single filter that allows for
> > > > > setting the frequency to either 50hz or 60hz; in other cases we could
> > > > > have i.e. two filters (with 50hz and 60hz center freq respectively),
> > > > > and they would allow to set only the "enable" attribute; in case you
> > > > > can i.e. enable only two of three filters, when you try to enable the
> > > > > 3rd it just refuse that. In this scenario probably "center_frequency"
> > > > > could be just a regular value (not a list).  
> > > >
> > > > Agreed.  The question is whether to index filters.  So allow more
> > > > than one of a given type on a given channel. So far we have
> > > > only had the one and there isn't a nice way to support multiple
> > > > as we currently don't have any indexed parameters of a single channel.  
> > >
> > > Yes, being able to indexing filters was the underlying assumption..
> > >  
> > > > I haven't seen parts that actually do have this level of sophisticated
> > > > filtering built in, with the exception of mains filters like this one.  
> > >
> > > Yes, I didn't too indeed.
> > >  
> > > > I think we have to allow for the possibility so if you are happy to do
> > > > so please propose the ABI additions to support multiple filters of
> > > > a type. I would suggest keeping them per type though
> > > >
> > > > e.g.
> > > >
> > > > in_X_filter_low_passY_3db_frequency etc
> > > > with Y as the optional index.  
> > >
> > > Seems reasonable.
> > >
> > > Well the idea is the one you've just explained here, that is adding an
> > > optional index for filters (per type and per ch); I'm not getting what
> > > do you mean about proposing it..  
> > Like all new ABI, needs a formal documentation patch.  Sometimes
> > we get more review on those than on discussions deep in a thread like
> > this.  
> 
> OK, this is honestly a bit out of my scope, but - if this is OK for
> you - I may try to do that after getting to some end with those
> in-flight patches..

That is fine, but we will need docs for anything that is added
even if it's the version without an index.

Don't have to be detailed etc, just a couple of lines for
Documentation/ABI/testing/sysfs-bus-iio to define what it is and
what it's units are.

> 
> > >  
> > > > For now, lets just implement then using extended attributes rather
> > > > than trying to extend the core to generate these automatically.
> > > >
> > > > If this turns out not to be a corner case we can try to figure
> > > > out a sane way of generating the multiple indexed versions.  
> > >
> > > OK. Let's try not to over-complicate things until it's really needed -
> > > Also, maybe if we'll hit other weird devices that need something like
> > > this, then they could have some exotic features that we haven't in
> > > mind yet now; it might turn out that we need something even more
> > > different, so maybe it's better to wait for real "users" of the ABI
> > > before deciding how to change it..
> > >
> > > But indeed, getting back to the patch originally discussed in this
> > > thread: if you are OK whit this, then I'll go with a
> > > "in_temp_filter_notch_center_frequency" attribute.
> > >
> > > I may use a specific IIO_DEVIC_ATTR or add it to the core (without
> > > addressing the index thing), as you prefer.  
> >
> > Which ever makes most sense to you. Either is fine for a new
> > attribute, though here don't we need the indexed filters?  
> 
> This specific device has only the option to choose either 50Hz
> filtering or 60Hz filtering; no option to disable filtering or enable
> both frequency. So I would say that here we can expose just one filter
> for which the center frequency can be set to either 50Hz or 60Hz (like
> the original patch did - but with proper name this time). I would say
> that we don't need indexed filters here. Or have I missed something ?
> 
> (So I would start with a IIO_DEVICE_ATTR for now then).

That's fine.  I'd somehow gotten it into my head that the part
had two filters :)

> 
> > >
> > > BTW: Looking at other drivers, it seems that for other attributes
> > > (e.g. oversampling_ratio, discussed in 2/3) they tend to round
> > > required values to the closest allowed value, instead of returning an
> > > error. In this specific case, do you want to apply the same logic? For
> > > consistency reasons I would do that, but at the practical side,
> > > requiring a line filter frequency which is not either 50Hz or 60Hz
> > > seems really an error to me..  
> >
> > It can be a bit of a tricky decision but for something like this
> > where the precise value works, it should reject incorrect ones.  
> 
> OK
> 
> > Oversampling is an odd one.  It should probably always round up
> > as it's usually not a problem to average more results, it just
> > wastes power.  That only applies if the oversampling_ratio
> > is independent of other attributes such as sampling frequency.  
> 
> It actually affects also the sampling rate; the more samples you
> average, the slowest output rate you achieve. But actually there is no
> attribute for setting the sampling frequency.. it is internally
> adjusted by the chip depending by averaging and filter line frequency
> (don't know why).
> 
> (if we want also this attribute, then I can craft another patch for
> adding it; it may be usefult to report the actual sample rate, I'm not
> sure if it makes sense to let the user set it, because we can
> basically just switch the averaging to one of the few possible values
> to get the sample rate to change as a side effect - assuming that one
> doesn't want to change the line frequency filter).

OK.  There are no hard rules on which attributes are the 'dominant'
ones so it would be fine to either not expose it or to have it read
only.  It can certainly be useful for fast devices as it lets you
size the buffers, but for a temperature sensor like this one
sampling_frequency probably doesn't matter to anyone.

> 
> BTW What about to round the requested oversampling_ratio to the
> closest allowed value (instead of rounding up)?

If a user has requested a value for oversampling ratio, it will
be to achieve a particular improvement in noise rejection.

As such I'd assume round up was most appropriate, or error on any
value that isn't a precise value.
> 
> > Still, we have traditionally been relaxed on this as long
> > as writing the the 'correct' value always works as that's what
> > userspace ABI should be doing.
> >
> > Jonathan
> >  
Thanks,

Jonathan

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency
  2019-11-02 14:17                   ` Jonathan Cameron
@ 2019-11-04 13:51                     ` Andrea Merello
  0 siblings, 0 replies; 60+ messages in thread
From: Andrea Merello @ 2019-11-04 13:51 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Jonathan Cameron, patrick.havelange, paresh.chaudhary, pmeerw,
	lars, knaack.h, Matthew Weber, Colin King, linux-iio

Il giorno sab 2 nov 2019 alle ore 15:17 Jonathan Cameron
<jic23@kernel.org> ha scritto:
>
> On Mon, 28 Oct 2019 08:32:48 +0100
> Andrea Merello <andrea.merello@gmail.com> wrote:
>
> > Il giorno dom 27 ott 2019 alle ore 10:23 Jonathan Cameron
> > <jic23@kernel.org> ha scritto:
> > >
> > > On Wed, 23 Oct 2019 10:29:07 +0200
> > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > >
> > > > Il giorno mar 22 ott 2019 alle ore 11:35 Jonathan Cameron
> > > > <jic23@kernel.org> ha scritto:
> > > > >
> > > > > On Fri, 18 Oct 2019 15:46:32 +0200
> > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > >
> > > > > > Il giorno gio 17 ott 2019 alle ore 14:32 Jonathan Cameron
> > > > > > <jonathan.cameron@huawei.com> ha scritto:
> > > > > > >
> > > > > > > On Wed, 16 Oct 2019 15:14:20 +0200
> > > > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > > > >
> > > > > > > > Il giorno dom 6 ott 2019 alle ore 09:54 Jonathan Cameron
> > > > > > > > <jic23@kernel.org> ha scritto:
> > > > > > > > >
> > > > > > > > > On Mon, 23 Sep 2019 14:17:12 +0200
> > > > > > > > > Andrea Merello <andrea.merello@gmail.com> wrote:
> > > > > > > > >
> > > > > > > > > > This sensor has an embedded notch filter for reducing interferences caused
> > > > > > > > > > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > > > > > > > > > (and harmonics).
> > > > > > > > > >
> > > > > > > > > > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > > > > > > > > > This patch introduces a IIO attribute that allows the user to set the said
> > > > > > > > > > filter to the desired frequency.
> > > > > > > > > >
> > > > > > > > > > NOTE: this has been intentionally not tied to any DT property to allow
> > > > > > > > > > the configuration of this setting from userspace, e.g. with a GUI or by
> > > > > > > > > > reading a configuration file, or maybe reading a GPIO tied to a physical
> > > > > > > > > > switch or accessing some device that can autodetect the line frequency.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> > > > > > > > > This one is not something that can be expect to be known from the setup
> > > > > > > > > of the device as it will depend on local mains frequency.
> > > > > > > > >
> > > > > > > > > So fine, to have it as a userspace control, but the name is too generic.
> > > > > > > > > We already have a number of filter attributes and we should try to
> > > > > > > > > work out how to bring it inline with them.
> > > > > > > >
> > > > > > > > Sure
> > > > > > > >
> > > > > > > > > in_X_filter_low_pass_3db_frequency
> > > > > > > > > in_X_filter_high_pass_3db_frequency
> > > > > > > > >
> > > > > > > > > So would,
> > > > > > > > > in_X_filter_notch_center_frequency work?
> > > > > > > > > ( I suppose we should use the American spelling ;)
> > > > > > > >
> > > > > > > > Yes, it seems OK in this case. I will produce a V2 with this modification.
> > > > > > > >
> > > > > > > > > This kind of ignores the harmonics aspect but at least documents the
> > > > > > > > > main frequency being blocked.
> > > > > > > >
> > > > > > > > I think this is perfectly fine: the user wants to set the notch filter
> > > > > > > > center frequency to either 60Hz or 50Hz to match the line frequency,
> > > > > > > > then she/he expects the filter to simply "work" somehow; IMO the
> > > > > > > > harmonic thing does not needed to be explicit.
> > > > > > > >
> > > > > > > > > There is a slight complexity that we have devices that have dual
> > > > > > > > > notchfilters (50 and 60Hz) and ones where you can turn it off entirely.
> > > > > > > > >
> > > > > > > > > I suppose no value would count as off and we could perhaps use a list
> > > > > > > > > for both on at the same time (though that's a bit horrible).
> > > > > > > >
> > > > > > > > IMHO it seems reasonable. Maybe for all-off and both-on conditions we
> > > > > > > > could also use magic strings like i.e. "all" and "off".
> > > > > > >
> > > > > > > I go with 'maybe' on that one.  Need to think about whether that is just
> > > > > > > a partial solution as we will probably find a device with 3 options that only
> > > > > > > supports any 2 at one time.  That would still need a more complex interface.
> > > > > > >
> > > > > > > Will think on this.
> > > > > >
> > > > > > I'll keep this patch on hold, waiting for your thoughts. Take the time
> > > > > > you need :)
> > > > > >
> > > > > > BTW IMHO:
> > > > > >
> > > > > > If we want to address the most possible generic case, then we may
> > > > > > standardize a set of possible attributes for filters (like "enable",
> > > > > > "center_frequency", "width",  "Q" , etc). Of course most filters will
> > > > > > not allow for setting most of those attributes.
> > > > >
> > > > > Absolutely.  We currently have a few defined for low and high pass
> > > > > filters, but if there are more complex features to define we should
> > > > > do so.
> > > > >
> > > > > >
> > > > > > Then i.e.  in our case we could have one single filter that allows for
> > > > > > setting the frequency to either 50hz or 60hz; in other cases we could
> > > > > > have i.e. two filters (with 50hz and 60hz center freq respectively),
> > > > > > and they would allow to set only the "enable" attribute; in case you
> > > > > > can i.e. enable only two of three filters, when you try to enable the
> > > > > > 3rd it just refuse that. In this scenario probably "center_frequency"
> > > > > > could be just a regular value (not a list).
> > > > >
> > > > > Agreed.  The question is whether to index filters.  So allow more
> > > > > than one of a given type on a given channel. So far we have
> > > > > only had the one and there isn't a nice way to support multiple
> > > > > as we currently don't have any indexed parameters of a single channel.
> > > >
> > > > Yes, being able to indexing filters was the underlying assumption..
> > > >
> > > > > I haven't seen parts that actually do have this level of sophisticated
> > > > > filtering built in, with the exception of mains filters like this one.
> > > >
> > > > Yes, I didn't too indeed.
> > > >
> > > > > I think we have to allow for the possibility so if you are happy to do
> > > > > so please propose the ABI additions to support multiple filters of
> > > > > a type. I would suggest keeping them per type though
> > > > >
> > > > > e.g.
> > > > >
> > > > > in_X_filter_low_passY_3db_frequency etc
> > > > > with Y as the optional index.
> > > >
> > > > Seems reasonable.
> > > >
> > > > Well the idea is the one you've just explained here, that is adding an
> > > > optional index for filters (per type and per ch); I'm not getting what
> > > > do you mean about proposing it..
> > > Like all new ABI, needs a formal documentation patch.  Sometimes
> > > we get more review on those than on discussions deep in a thread like
> > > this.
> >
> > OK, this is honestly a bit out of my scope, but - if this is OK for
> > you - I may try to do that after getting to some end with those
> > in-flight patches..
>
> That is fine, but we will need docs for anything that is added
> even if it's the version without an index.
>
> Don't have to be detailed etc, just a couple of lines for
> Documentation/ABI/testing/sysfs-bus-iio to define what it is and
> what it's units are.

OK

> >
> > > >
> > > > > For now, lets just implement then using extended attributes rather
> > > > > than trying to extend the core to generate these automatically.
> > > > >
> > > > > If this turns out not to be a corner case we can try to figure
> > > > > out a sane way of generating the multiple indexed versions.
> > > >
> > > > OK. Let's try not to over-complicate things until it's really needed -
> > > > Also, maybe if we'll hit other weird devices that need something like
> > > > this, then they could have some exotic features that we haven't in
> > > > mind yet now; it might turn out that we need something even more
> > > > different, so maybe it's better to wait for real "users" of the ABI
> > > > before deciding how to change it..
> > > >
> > > > But indeed, getting back to the patch originally discussed in this
> > > > thread: if you are OK whit this, then I'll go with a
> > > > "in_temp_filter_notch_center_frequency" attribute.
> > > >
> > > > I may use a specific IIO_DEVIC_ATTR or add it to the core (without
> > > > addressing the index thing), as you prefer.
> > >
> > > Which ever makes most sense to you. Either is fine for a new
> > > attribute, though here don't we need the indexed filters?
> >
> > This specific device has only the option to choose either 50Hz
> > filtering or 60Hz filtering; no option to disable filtering or enable
> > both frequency. So I would say that here we can expose just one filter
> > for which the center frequency can be set to either 50Hz or 60Hz (like
> > the original patch did - but with proper name this time). I would say
> > that we don't need indexed filters here. Or have I missed something ?
> >
> > (So I would start with a IIO_DEVICE_ATTR for now then).
>
> That's fine.  I'd somehow gotten it into my head that the part
> had two filters :)

OK :)

> >
> > > >
> > > > BTW: Looking at other drivers, it seems that for other attributes
> > > > (e.g. oversampling_ratio, discussed in 2/3) they tend to round
> > > > required values to the closest allowed value, instead of returning an
> > > > error. In this specific case, do you want to apply the same logic? For
> > > > consistency reasons I would do that, but at the practical side,
> > > > requiring a line filter frequency which is not either 50Hz or 60Hz
> > > > seems really an error to me..
> > >
> > > It can be a bit of a tricky decision but for something like this
> > > where the precise value works, it should reject incorrect ones.
> >
> > OK
> >
> > > Oversampling is an odd one.  It should probably always round up
> > > as it's usually not a problem to average more results, it just
> > > wastes power.  That only applies if the oversampling_ratio
> > > is independent of other attributes such as sampling frequency.
> >
> > It actually affects also the sampling rate; the more samples you
> > average, the slowest output rate you achieve. But actually there is no
> > attribute for setting the sampling frequency.. it is internally
> > adjusted by the chip depending by averaging and filter line frequency
> > (don't know why).
> >
> > (if we want also this attribute, then I can craft another patch for
> > adding it; it may be usefult to report the actual sample rate, I'm not
> > sure if it makes sense to let the user set it, because we can
> > basically just switch the averaging to one of the few possible values
> > to get the sample rate to change as a side effect - assuming that one
> > doesn't want to change the line frequency filter).
>
> OK.  There are no hard rules on which attributes are the 'dominant'
> ones so it would be fine to either not expose it or to have it read
> only.  It can certainly be useful for fast devices as it lets you
> size the buffers, but for a temperature sensor like this one
> sampling_frequency probably doesn't matter to anyone.

Ok, I will sitck with just adding the filter attribute.

> >
> > BTW What about to round the requested oversampling_ratio to the
> > closest allowed value (instead of rounding up)?
>
> If a user has requested a value for oversampling ratio, it will
> be to achieve a particular improvement in noise rejection.
>
> As such I'd assume round up was most appropriate, or error on any
> value that isn't a precise value.

Both seem reasonable to me. I will think to it a bit more then I'll
make a choice :) .. and then I'll go with a V2 series with all changes
we discussed.

> >
> > > Still, we have traditionally been relaxed on this as long
> > > as writing the the 'correct' value always works as that's what
> > > userspace ABI should be doing.
> > >
> > > Jonathan
> > >
> Thanks,
>
> Jonathan

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 0/9] iio: max31856: provide more configuration options
  2019-09-23 12:17 [PATCH 0/3] iio: max31856: provide more configuration options Andrea Merello
                   ` (2 preceding siblings ...)
  2019-09-23 12:17 ` [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
@ 2019-11-11 15:35 ` Andrea Merello
  2019-11-11 15:35   ` [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
                     ` (9 more replies)
  3 siblings, 10 replies; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

This series was born in order to provide more configuration options for
max31856 devices. In this version, in order to do that, it also extends
the IIO core. While at it, I've also updates maxim_thermocouple driver
to take (little) advantage of the said change.

Two hardware features (power mains noise rejection and HW averaging)
were not previously configurable, and one (thermocouple type selection)
was only possible via DT, but in my experience this is quite limiting in
several scenario (see 3/3 commit message for complete explanation).

These patches have been tested backporting max31856 driver on a 4.19
upstream kernel (Xilinx mpsoc-based board), and then rebased on the
IIO testing git tree.

I have real HW for max31856, while for maxim_thermocouple I've tested my
changes as much as I could just spoofing in the DT (no real HW).

Changes in v2:
- 1/9 and 3/9: changed attribute name to better match IIO naming convention
- 2/9: added separate patch to document new attribute name introduced in 1/9
- 4/9, 5/9, 6/9: new patches to add support to IIO core for handling
  thermocouple_type addribute. Most notably 4/9 introduces support for
  handling 'char' type IIO sysfs attributes; RFC on this.
- 7/9: take advantage of just-added IIO thermocouple_type attribute instead
  of using extended custom attribute
- 8/9 and 9/9: new patches to make maxim_thermocouple driver to export
  (RO) thermocouple_type attribute

Andrea Merello (9):
  iio: max31856: add option for setting mains filter rejection frequency
  Documentation: ABI: document IIO in_temp_filter_notch_center_frequency
    file
  iio: max31856: add support for configuring the HW averaging
  RFC: iio: core: add char type for sysfs attributes
  iio: core: add thermocouple_type standard attribute
  Documentation: ABI: document IIO thermocouple_type file
  iio: max31856: add support for runtime-configuring the thermocouple
    type
  RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs
    attribute
  dt-bindings: iio: maxim_thermocouple: document new 'compatible'
    strings

 Documentation/ABI/testing/sysfs-bus-iio       |  13 ++
 .../iio/temperature/maxim_thermocouple.txt    |   7 +-
 drivers/iio/industrialio-core.c               |  23 ++-
 drivers/iio/temperature/max31856.c            | 133 +++++++++++++++++-
 drivers/iio/temperature/maxim_thermocouple.c  |  45 +++++-
 include/linux/iio/types.h                     |   2 +
 6 files changed, 212 insertions(+), 11 deletions(-)

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org

--
2.17.1

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-11 22:59     ` Matt Ranostay
  2019-11-11 15:35   ` [v2 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file Andrea Merello
                     ` (8 subsequent siblings)
  9 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

This sensor has an embedded notch filter for reducing interferences caused
by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
(and harmonics).

Currently the said setting is left alone (the sensor defaults to 60Hz).
This patch introduces a IIO attribute that allows the user to set the said
filter to the desired frequency.

NOTE: this has been intentionally not tied to any DT property to allow
the configuration of this setting from userspace, e.g. with a GUI or by
reading a configuration file, or maybe reading a GPIO tied to a physical
switch or accessing some device that can autodetect the line frequency.

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 50 ++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index 73ed550e3fc9..d97ba9ee1598 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -23,6 +23,7 @@
 #define MAX31856_CR0_1SHOT         BIT(6)
 #define MAX31856_CR0_OCFAULT       BIT(4)
 #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
+#define MAX31856_CR0_FILTER_50HZ   BIT(0)
 #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
 #define MAX31856_FAULT_OVUV        BIT(1)
 #define MAX31856_FAULT_OPEN        BIT(0)
@@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
 struct max31856_data {
 	struct spi_device *spi;
 	u32 thermocouple_type;
+	bool filter_50hz;
 };
 
 static int max31856_read(struct max31856_data *data, u8 reg,
@@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
 	reg_cr0_val &= ~MAX31856_CR0_1SHOT;
 	reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
 
+	if (data->filter_50hz)
+		reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
+	else
+		reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
+
 	return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
 }
 
@@ -249,12 +256,54 @@ static ssize_t show_fault_oc(struct device *dev,
 	return show_fault(dev, MAX31856_FAULT_OPEN, buf);
 }
 
+static ssize_t show_filter(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+
+	return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
+}
+
+static ssize_t set_filter(struct device *dev,
+			  struct device_attribute *attr,
+			  const char *buf,
+			  size_t len)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+	unsigned int freq;
+	int ret;
+
+	ret = kstrtouint(buf, 10, &freq);
+	if (ret)
+		return ret;
+
+	switch (freq) {
+	case 50:
+		data->filter_50hz = true;
+		break;
+	case 60:
+		data->filter_50hz = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	max31856_init(data);
+	return len;
+}
+
 static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
 static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
+static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
+		       show_filter, set_filter, 0);
 
 static struct attribute *max31856_attributes[] = {
 	&iio_dev_attr_fault_ovuv.dev_attr.attr,
 	&iio_dev_attr_fault_oc.dev_attr.attr,
+	&iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
 	NULL,
 };
 
@@ -280,6 +329,7 @@ static int max31856_probe(struct spi_device *spi)
 
 	data = iio_priv(indio_dev);
 	data->spi = spi;
+	data->filter_50hz = false;
 
 	spi_set_drvdata(spi, indio_dev);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
  2019-11-11 15:35   ` [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-11 15:35   ` [v2 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

max31856 IIO driver introduced a new attribute
"in_temp_filter_notch_center_frequency".
This patch adds it to the list of documented ABI for sysfs-bus-iio

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index faaa2166d741..94f7eb675108 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1726,3 +1726,10 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 		List of valid periods (in seconds) for which the light intensity
 		must be above the threshold level before interrupt is asserted.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_filter_notch_center_frequency
+KernelVersion:	5.5
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Center frequency in Hz for a notch filter. Used i.e. for line
+		noise suppression.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 3/9] iio: max31856: add support for configuring the HW averaging
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
  2019-11-11 15:35   ` [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
  2019-11-11 15:35   ` [v2 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-11 23:01     ` Matt Ranostay
  2019-11-11 15:35   ` [v2 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

This sensor can perform samples averaging in hardware, but currently the
driver leaves this setting alone (default is no averaging).

This patch binds this HW setting to the "oversampling_ratio" IIO attribute
and allows the user to set the averaging as desired (the HW supports
averaging of 2, 5, 8 or 16 samples; in-between values are rounded up).

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 46 +++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index d97ba9ee1598..9f0f4f65dccd 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -12,6 +12,7 @@
 #include <linux/spi/spi.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/util_macros.h>
 #include <dt-bindings/iio/temperature/thermocouple.h>
 /*
  * The MSB of the register value determines whether the following byte will
@@ -24,6 +25,8 @@
 #define MAX31856_CR0_OCFAULT       BIT(4)
 #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
 #define MAX31856_CR0_FILTER_50HZ   BIT(0)
+#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
+#define MAX31856_AVERAGING_SHIFT   4
 #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
 #define MAX31856_FAULT_OVUV        BIT(1)
 #define MAX31856_FAULT_OPEN        BIT(0)
@@ -50,7 +53,10 @@ static const struct iio_chan_spec max31856_channels[] = {
 	{	/* Thermocouple Temperature */
 		.type = IIO_TEMP,
 		.info_mask_separate =
-			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
+		.info_mask_shared_by_type =
+			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
 	},
 	{	/* Cold Junction Temperature */
 		.type = IIO_TEMP,
@@ -58,6 +64,8 @@ static const struct iio_chan_spec max31856_channels[] = {
 		.modified = 1,
 		.info_mask_separate =
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+		.info_mask_shared_by_type =
+			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
 	},
 };
 
@@ -65,6 +73,7 @@ struct max31856_data {
 	struct spi_device *spi;
 	u32 thermocouple_type;
 	bool filter_50hz;
+	int averaging;
 };
 
 static int max31856_read(struct max31856_data *data, u8 reg,
@@ -109,6 +118,10 @@ static int max31856_init(struct max31856_data *data)
 
 	reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
 	reg_cr1_val |= data->thermocouple_type;
+
+	reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
+	reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
+
 	ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
 	if (ret)
 		return ret;
@@ -217,6 +230,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 			return IIO_VAL_INT_PLUS_MICRO;
 		}
 		break;
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		*val = 1 << data->averaging;
+		return IIO_VAL_INT;
 	default:
 		ret = -EINVAL;
 		break;
@@ -225,6 +241,33 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static int max31856_write_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int val, int val2, long mask)
+{
+	struct max31856_data *data = iio_priv(indio_dev);
+	int msb;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		if (val > 16 || val < 1)
+			return -EINVAL;
+		msb = fls(val) - 1;
+		/* Round up to next 2pow if needed */
+		if (BIT(msb) < val)
+			msb++;
+
+		data->averaging = msb;
+		max31856_init(data);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -313,6 +356,7 @@ static const struct attribute_group max31856_group = {
 
 static const struct iio_info max31856_info = {
 	.read_raw = max31856_read_raw,
+	.write_raw = max31856_write_raw,
 	.attrs = &max31856_group,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 4/9] RFC: iio: core: add char type for sysfs attributes
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
                     ` (2 preceding siblings ...)
  2019-11-11 15:35   ` [v2 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-16 14:45     ` Jonathan Cameron
  2019-11-11 15:35   ` [v2 5/9] iio: core: add thermocouple_type standard attribute Andrea Merello
                     ` (5 subsequent siblings)
  9 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

This patch introduces IIO_VAL_CHAR type for standard IIO attributes to
allow for attributes that needs to be represented by character rather
than a number. This is preparatory for introducing a new attribute whose
purpose is to describe thermocouple type, that can be i.e. "J", "K", etc..

The char-type value is stored in the first "value" integer that is passed
to the .[read/write]_raw() callbacks.

Note that in order to make it possible for the IIO core to correctly parse
this type (actually, to avoid integer parsing), it became mandatory for
any driver that wish to use IIO_VAL_CHAR on a writable attribute to
implement .write_raw_get_fmt().

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/industrialio-core.c | 22 ++++++++++++++++++----
 include/linux/iio/types.h       |  1 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index f72c2dc5f703..958b5c48a86f 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -596,6 +596,8 @@ static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type,
 		}
 		return l;
 	}
+	case IIO_VAL_CHAR:
+		return snprintf(buf, len, "%c", (char)vals[0]);
 	default:
 		return 0;
 	}
@@ -837,7 +839,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret, fract_mult = 100000;
-	int integer, fract;
+	int integer, fract = 0;
+	bool is_char = false;
 
 	/* Assumes decimal - precision based on number of digits */
 	if (!indio_dev->info->write_raw)
@@ -855,13 +858,24 @@ static ssize_t iio_write_channel_info(struct device *dev,
 		case IIO_VAL_INT_PLUS_NANO:
 			fract_mult = 100000000;
 			break;
+		case IIO_VAL_CHAR:
+			is_char = true;
+			break;
 		default:
 			return -EINVAL;
 		}
 
-	ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
-	if (ret)
-		return ret;
+	if (is_char) {
+		char ch;
+
+		if (sscanf(buf, "%c", &ch) != 1)
+			return -EINVAL;
+		integer = ch;
+	} else {
+		ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
+		if (ret)
+			return ret;
+	}
 
 	ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
 					 integer, fract, this_attr->address);
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index fa824e160f35..8e0026da38c9 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -25,6 +25,7 @@ enum iio_event_info {
 #define IIO_VAL_INT_MULTIPLE 5
 #define IIO_VAL_FRACTIONAL 10
 #define IIO_VAL_FRACTIONAL_LOG2 11
+#define IIO_VAL_CHAR 12
 
 enum iio_available_type {
 	IIO_AVAIL_LIST,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 5/9] iio: core: add thermocouple_type standard attribute
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
                     ` (3 preceding siblings ...)
  2019-11-11 15:35   ` [v2 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-11 15:35   ` [v2 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

We have a couple of thermocouple IIO drivers, supporting several chips.
Some of them support only one specific thermocouple type (e.g. "K", "J"),
one of them can be configured to work with several different thermocouple
types.

In certain applications thermocouples could be externally connected to the
chip by the user.

This patch introduces a new IIO standard attribute to report the supported
thermocouple type and, where applicable, to allow it to be dynamically set
using sysfs.

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/industrialio-core.c | 1 +
 include/linux/iio/types.h       | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 958b5c48a86f..fa2c3b321bfd 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -161,6 +161,7 @@ static const char * const iio_chan_info_postfix[] = {
 	[IIO_CHAN_INFO_DEBOUNCE_TIME] = "debounce_time",
 	[IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity",
 	[IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio",
+	[IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type",
 };
 
 /**
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 8e0026da38c9..e6fd3645963c 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -58,6 +58,7 @@ enum iio_chan_info_enum {
 	IIO_CHAN_INFO_DEBOUNCE_TIME,
 	IIO_CHAN_INFO_CALIBEMISSIVITY,
 	IIO_CHAN_INFO_OVERSAMPLING_RATIO,
+	IIO_CHAN_INFO_THERMOCOUPLE_TYPE,
 };
 
 #endif /* _IIO_TYPES_H_ */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 6/9] Documentation: ABI: document IIO thermocouple_type file
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
                     ` (4 preceding siblings ...)
  2019-11-11 15:35   ` [v2 5/9] iio: core: add thermocouple_type standard attribute Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-16 14:47     ` Jonathan Cameron
  2019-11-11 15:35   ` [v2 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
                     ` (3 subsequent siblings)
  9 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

IIO core layer gained a new sysfs standard attribute "thermocouple_type".
This patch adds it to the list of documented ABI for sysfs-bus-iio

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-iio | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 94f7eb675108..2cf2c800dba2 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1733,3 +1733,9 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 		Center frequency in Hz for a notch filter. Used i.e. for line
 		noise suppression.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_temp_thermocouple_type
+KernelVersion:	5.5
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Thermocouple type i.e. J, K, R, ...
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 7/9] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
                     ` (5 preceding siblings ...)
  2019-11-11 15:35   ` [v2 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-16 14:49     ` Jonathan Cameron
  2019-11-11 15:35   ` [v2 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
                     ` (2 subsequent siblings)
  9 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio

The sensor support various thermocouple types (e.g. J, K, N, ...). The
driver allows to configure this parameter using a DT property.

This is useful when i.e. the thermocouple is physically tied to the sensor
and it is usually not removed, or when it is at least known in advance
which sensor will be connected to the circuit.

However, if the user can randomly connect any kind of thermocouples (i.e.
the device exposes a connector, and the user is free to connect its own
sensors), it would be more appropriate to provide a mechanism to
dynamically switch from one thermocouple type to another. This can be i.e.
handled in userspace by a GUI, a configuration file or a program that
detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
or whatever.

This patch adds a IIO attribute that can be used to override, at run-time,
the DT-provided setting (which serves as default).

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 39 +++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index 9f0f4f65dccd..6689eab174df 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2018-2019 Rockwell Collins
  */
 
+#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -76,6 +77,10 @@ struct max31856_data {
 	int averaging;
 };
 
+const char max31856_tc_types[] = {
+	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
+};
+
 static int max31856_read(struct max31856_data *data, u8 reg,
 			 u8 val[], unsigned int read_size)
 {
@@ -233,6 +238,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
 		*val = 1 << data->averaging;
 		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+		*val = max31856_tc_types[data->thermocouple_type];
+		return IIO_VAL_CHAR;
 	default:
 		ret = -EINVAL;
 		break;
@@ -241,6 +249,18 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
+				      struct iio_chan_spec const *chan,
+				      long mask)
+{
+	switch (mask) {
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+		return IIO_VAL_CHAR;
+	default:
+		return IIO_VAL_INT;
+	}
+}
+
 static int max31856_write_raw(struct iio_dev *indio_dev,
 			      struct iio_chan_spec const *chan,
 			      int val, int val2, long mask)
@@ -260,7 +280,24 @@ static int max31856_write_raw(struct iio_dev *indio_dev,
 		data->averaging = msb;
 		max31856_init(data);
 		break;
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+	{
+		int tc_type = -1;
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
+			if (max31856_tc_types[i] == toupper(val)) {
+				tc_type = i;
+				break;
+			}
+		}
+		if (tc_type < 0)
+			return -EINVAL;
 
+		data->thermocouple_type = tc_type;
+		max31856_init(data);
+		break;
+	}
 	default:
 		return -EINVAL;
 	}
@@ -333,7 +370,6 @@ static ssize_t set_filter(struct device *dev,
 	default:
 		return -EINVAL;
 	}
-
 	max31856_init(data);
 	return len;
 }
@@ -357,6 +393,7 @@ static const struct attribute_group max31856_group = {
 static const struct iio_info max31856_info = {
 	.read_raw = max31856_read_raw,
 	.write_raw = max31856_write_raw,
+	.write_raw_get_fmt = max31856_write_raw_get_fmt,
 	.attrs = &max31856_group,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
                     ` (6 preceding siblings ...)
  2019-11-11 15:35   ` [v2 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-16 14:51     ` Jonathan Cameron
  2019-11-11 15:35   ` [v2 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
  9 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio, Rob Herring, Mark Rutland, devicetree

We added a sysfs ABI for getting/setting the type of a thermocouple. This
driver supports chips that support specific fixed thermocouple types; we
cannot set it, but still we can add this sysfs attribute in RO mode to
read-back the thermocouple type.

This driver supports actually several chips:
 - max6675
 - max31855[k/j/n/s/t/e/r]asa family

Max6675 supports only K-type thermocouples, so we can just report that.

Each chip in max31855 family supports just one specific thermocouple type
(in the obvious way: i.e. max31855jasa supports J-type). This driver did
accept a generic SPI ID and OF compatible "max31855" which does not give
any clue about which chip is really involved (and unfortunately it seems
we have no way to detect it).

This patch introduces a new set of, more specific, SPI IDs and OF
compatible strings to better match the chip type.

The old, generic, "max31855" binding is kept for compatibility reasons, but
this patch aims to deprecate it, so, should we hit it, a warning is spit.
In such case the reported thermocouple type in sysfs is '?', because we
have no way to know.

Regarding the implementation: the thermocouple type information is stored
in the driver private data and I've kept only two maxim_thermocouple_chip
types in order to avoid a lot of duplications (seven chip types with just
a different thermocouple type).

RFT because I have no real HW to test this.

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/maxim_thermocouple.c | 45 ++++++++++++++++++--
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
index d1360605209c..6fa5ae9fb4ec 100644
--- a/drivers/iio/temperature/maxim_thermocouple.c
+++ b/drivers/iio/temperature/maxim_thermocouple.c
@@ -14,6 +14,7 @@
 #include <linux/of_device.h>
 #include <linux/spi/spi.h>
 #include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/triggered_buffer.h>
@@ -24,13 +25,25 @@
 enum {
 	MAX6675,
 	MAX31855,
+	MAX31855K,
+	MAX31855J,
+	MAX31855N,
+	MAX31855S,
+	MAX31855T,
+	MAX31855E,
+	MAX31855R,
+};
+
+const char maxim_tc_types[] = {
+	'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R'
 };
 
 static const struct iio_chan_spec max6675_channels[] = {
 	{	/* thermocouple temperature */
 		.type = IIO_TEMP,
 		.info_mask_separate =
-			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
 		.scan_index = 0,
 		.scan_type = {
 			.sign = 's',
@@ -48,7 +61,8 @@ static const struct iio_chan_spec max31855_channels[] = {
 		.type = IIO_TEMP,
 		.address = 2,
 		.info_mask_separate =
-			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
 		.scan_index = 0,
 		.scan_type = {
 			.sign = 's',
@@ -110,6 +124,7 @@ struct maxim_thermocouple_data {
 	const struct maxim_thermocouple_chip *chip;
 
 	u8 buffer[16] ____cacheline_aligned;
+	char tc_type;
 };
 
 static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
@@ -196,8 +211,11 @@ static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,
 			ret = IIO_VAL_INT;
 		}
 		break;
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+		*val = data->tc_type;
+		ret = IIO_VAL_CHAR;
+		break;
 	}
-
 	return ret;
 }
 
@@ -210,8 +228,9 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
 	const struct spi_device_id *id = spi_get_device_id(spi);
 	struct iio_dev *indio_dev;
 	struct maxim_thermocouple_data *data;
+	const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855;
 	const struct maxim_thermocouple_chip *chip =
-			&maxim_thermocouple_chips[id->driver_data];
+		&maxim_thermocouple_chips[chip_type];
 	int ret;
 
 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
@@ -229,6 +248,7 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
 	data = iio_priv(indio_dev);
 	data->spi = spi;
 	data->chip = chip;
+	data->tc_type = maxim_tc_types[id->driver_data];
 
 	ret = devm_iio_triggered_buffer_setup(&spi->dev,
 				indio_dev, NULL,
@@ -236,12 +256,22 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
 	if (ret)
 		return ret;
 
+	if (id->driver_data == MAX31855)
+		dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type");
+
 	return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static const struct spi_device_id maxim_thermocouple_id[] = {
 	{"max6675", MAX6675},
 	{"max31855", MAX31855},
+	{"max31855k", MAX31855K},
+	{"max31855j", MAX31855J},
+	{"max31855n", MAX31855N},
+	{"max31855s", MAX31855S},
+	{"max31855t", MAX31855T},
+	{"max31855e", MAX31855E},
+	{"max31855r", MAX31855R},
 	{},
 };
 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
@@ -249,6 +279,13 @@ MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
 static const struct of_device_id maxim_thermocouple_of_match[] = {
         { .compatible = "maxim,max6675" },
         { .compatible = "maxim,max31855" },
+	{ .compatible = "maxim,max31855k" },
+	{ .compatible = "maxim,max31855j" },
+	{ .compatible = "maxim,max31855n" },
+	{ .compatible = "maxim,max31855s" },
+	{ .compatible = "maxim,max31855t" },
+	{ .compatible = "maxim,max31855e" },
+	{ .compatible = "maxim,max31855r" },
         { },
 };
 MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v2 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
                     ` (7 preceding siblings ...)
  2019-11-11 15:35   ` [v2 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
@ 2019-11-11 15:35   ` Andrea Merello
  2019-11-14 22:12     ` Rob Herring
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
  9 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-11 15:35 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio, Rob Herring, Mark Rutland, devicetree

Now the maxim_thermocouple has new, more specific, 'compatible' strings for
better distinguish the various supported chips.

This patch updates the DT bindings documentation accordingly

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 .../bindings/iio/temperature/maxim_thermocouple.txt        | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
index 28bc5c4d965b..bb85cd0e039c 100644
--- a/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
+++ b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
@@ -5,7 +5,10 @@ Maxim thermocouple support
 
 Required properties:
 
-	- compatible: must be "maxim,max31855" or "maxim,max6675"
+	- compatible: must be "maxim,max6675" or one of the following:
+	   "maxim,max31855k", "maxim,max31855j", "maxim,max31855n",
+	   "maxim,max31855s", "maxim,max31855t", "maxim,max31855e",
+	   "maxim,max31855r"; the generic "max,max31855" is deprecated.
 	- reg: SPI chip select number for the device
 	- spi-max-frequency: must be 4300000
 	- spi-cpha: must be defined for max6675 to enable SPI mode 1
@@ -15,7 +18,7 @@ Required properties:
 Example:
 
 	max31855@0 {
-		compatible = "maxim,max31855";
+		compatible = "maxim,max31855k";
 		reg = <0>;
 		spi-max-frequency = <4300000>;
 	};
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency
  2019-11-11 15:35   ` [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
@ 2019-11-11 22:59     ` Matt Ranostay
  2019-11-16 14:29       ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Matt Ranostay @ 2019-11-11 22:59 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Chuhong Yuan, Daniel Gomez,
	open list:IIO SUBSYSTEM AND DRIVERS

On Tue, Nov 12, 2019 at 12:35 AM Andrea Merello
<andrea.merello@gmail.com> wrote:
>
> This sensor has an embedded notch filter for reducing interferences caused
> by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> (and harmonics).
>
> Currently the said setting is left alone (the sensor defaults to 60Hz).
> This patch introduces a IIO attribute that allows the user to set the said
> filter to the desired frequency.
>
> NOTE: this has been intentionally not tied to any DT property to allow
> the configuration of this setting from userspace, e.g. with a GUI or by
> reading a configuration file, or maybe reading a GPIO tied to a physical
> switch or accessing some device that can autodetect the line frequency.
>

Looks good to me. Although this ideal could be a device tree property
as well, but not a big deal.

Reviewed-by: Matt Ranostay <matt.ranostay@konsulko.com>

> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> ---
>  drivers/iio/temperature/max31856.c | 50 ++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index 73ed550e3fc9..d97ba9ee1598 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -23,6 +23,7 @@
>  #define MAX31856_CR0_1SHOT         BIT(6)
>  #define MAX31856_CR0_OCFAULT       BIT(4)
>  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
>  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
>  #define MAX31856_FAULT_OVUV        BIT(1)
>  #define MAX31856_FAULT_OPEN        BIT(0)
> @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
>  struct max31856_data {
>         struct spi_device *spi;
>         u32 thermocouple_type;
> +       bool filter_50hz;
>  };
>
>  static int max31856_read(struct max31856_data *data, u8 reg,
> @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
>         reg_cr0_val &= ~MAX31856_CR0_1SHOT;
>         reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
>
> +       if (data->filter_50hz)
> +               reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> +       else
> +               reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> +
>         return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
>  }
>
> @@ -249,12 +256,54 @@ static ssize_t show_fault_oc(struct device *dev,
>         return show_fault(dev, MAX31856_FAULT_OPEN, buf);
>  }
>
> +static ssize_t show_filter(struct device *dev,
> +                          struct device_attribute *attr,
> +                          char *buf)
> +{
> +       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +       struct max31856_data *data = iio_priv(indio_dev);
> +
> +       return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> +}
> +
> +static ssize_t set_filter(struct device *dev,
> +                         struct device_attribute *attr,
> +                         const char *buf,
> +                         size_t len)
> +{
> +       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +       struct max31856_data *data = iio_priv(indio_dev);
> +       unsigned int freq;
> +       int ret;
> +
> +       ret = kstrtouint(buf, 10, &freq);
> +       if (ret)
> +               return ret;
> +
> +       switch (freq) {
> +       case 50:
> +               data->filter_50hz = true;
> +               break;
> +       case 60:
> +               data->filter_50hz = false;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       max31856_init(data);
> +       return len;
> +}
> +
>  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
>  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> +static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
> +                      show_filter, set_filter, 0);
>
>  static struct attribute *max31856_attributes[] = {
>         &iio_dev_attr_fault_ovuv.dev_attr.attr,
>         &iio_dev_attr_fault_oc.dev_attr.attr,
> +       &iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
>         NULL,
>  };
>
> @@ -280,6 +329,7 @@ static int max31856_probe(struct spi_device *spi)
>
>         data = iio_priv(indio_dev);
>         data->spi = spi;
> +       data->filter_50hz = false;
>
>         spi_set_drvdata(spi, indio_dev);
>
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 3/9] iio: max31856: add support for configuring the HW averaging
  2019-11-11 15:35   ` [v2 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
@ 2019-11-11 23:01     ` Matt Ranostay
  0 siblings, 0 replies; 60+ messages in thread
From: Matt Ranostay @ 2019-11-11 23:01 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Chuhong Yuan, Daniel Gomez,
	open list:IIO SUBSYSTEM AND DRIVERS

On Tue, Nov 12, 2019 at 12:35 AM Andrea Merello
<andrea.merello@gmail.com> wrote:
>
> This sensor can perform samples averaging in hardware, but currently the
> driver leaves this setting alone (default is no averaging).
>
> This patch binds this HW setting to the "oversampling_ratio" IIO attribute
> and allows the user to set the averaging as desired (the HW supports
> averaging of 2, 5, 8 or 16 samples; in-between values are rounded up).
>
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> ---
>  drivers/iio/temperature/max31856.c | 46 +++++++++++++++++++++++++++++-
>  1 file changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index d97ba9ee1598..9f0f4f65dccd 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -12,6 +12,7 @@
>  #include <linux/spi/spi.h>
>  #include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
> +#include <linux/util_macros.h>
>  #include <dt-bindings/iio/temperature/thermocouple.h>
>  /*
>   * The MSB of the register value determines whether the following byte will
> @@ -24,6 +25,8 @@
>  #define MAX31856_CR0_OCFAULT       BIT(4)
>  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
>  #define MAX31856_CR0_FILTER_50HZ   BIT(0)
> +#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
> +#define MAX31856_AVERAGING_SHIFT   4
>  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
>  #define MAX31856_FAULT_OVUV        BIT(1)
>  #define MAX31856_FAULT_OPEN        BIT(0)
> @@ -50,7 +53,10 @@ static const struct iio_chan_spec max31856_channels[] = {
>         {       /* Thermocouple Temperature */
>                 .type = IIO_TEMP,
>                 .info_mask_separate =
> -                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> +                       BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),

Adding IIO_CHAN_INFO_THERMOCOUPLE_TYPE shouldn't happen in this
patchset, since it isn't related
to the oversampling.

- Matt

> +               .info_mask_shared_by_type =
> +                       BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
>         },
>         {       /* Cold Junction Temperature */
>                 .type = IIO_TEMP,
> @@ -58,6 +64,8 @@ static const struct iio_chan_spec max31856_channels[] = {
>                 .modified = 1,
>                 .info_mask_separate =
>                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +               .info_mask_shared_by_type =
> +                       BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
>         },
>  };
>
> @@ -65,6 +73,7 @@ struct max31856_data {
>         struct spi_device *spi;
>         u32 thermocouple_type;
>         bool filter_50hz;
> +       int averaging;
>  };
>
>  static int max31856_read(struct max31856_data *data, u8 reg,
> @@ -109,6 +118,10 @@ static int max31856_init(struct max31856_data *data)
>
>         reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
>         reg_cr1_val |= data->thermocouple_type;
> +
> +       reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
> +       reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
> +
>         ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
>         if (ret)
>                 return ret;
> @@ -217,6 +230,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>                         return IIO_VAL_INT_PLUS_MICRO;
>                 }
>                 break;
> +       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +               *val = 1 << data->averaging;
> +               return IIO_VAL_INT;
>         default:
>                 ret = -EINVAL;
>                 break;
> @@ -225,6 +241,33 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>         return ret;
>  }
>
> +static int max31856_write_raw(struct iio_dev *indio_dev,
> +                             struct iio_chan_spec const *chan,
> +                             int val, int val2, long mask)
> +{
> +       struct max31856_data *data = iio_priv(indio_dev);
> +       int msb;
> +
> +       switch (mask) {
> +       case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +               if (val > 16 || val < 1)
> +                       return -EINVAL;
> +               msb = fls(val) - 1;
> +               /* Round up to next 2pow if needed */
> +               if (BIT(msb) < val)
> +                       msb++;
> +
> +               data->averaging = msb;
> +               max31856_init(data);
> +               break;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
>  static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
>  {
>         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> @@ -313,6 +356,7 @@ static const struct attribute_group max31856_group = {
>
>  static const struct iio_info max31856_info = {
>         .read_raw = max31856_read_raw,
> +       .write_raw = max31856_write_raw,
>         .attrs = &max31856_group,
>  };
>
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings
  2019-11-11 15:35   ` [v2 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
@ 2019-11-14 22:12     ` Rob Herring
  0 siblings, 0 replies; 60+ messages in thread
From: Rob Herring @ 2019-11-14 22:12 UTC (permalink / raw)
  To: Andrea Merello
  Cc: jic23, Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Matt Ranostay, Chuhong Yuan,
	Daniel Gomez, linux-iio, Mark Rutland, devicetree

On Mon, 11 Nov 2019 16:35:17 +0100, Andrea Merello wrote:
> Now the maxim_thermocouple has new, more specific, 'compatible' strings for
> better distinguish the various supported chips.
> 
> This patch updates the DT bindings documentation accordingly
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> ---
>  .../bindings/iio/temperature/maxim_thermocouple.txt        | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency
  2019-11-11 22:59     ` Matt Ranostay
@ 2019-11-16 14:29       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-16 14:29 UTC (permalink / raw)
  To: Matt Ranostay
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Paresh Chaudhary, Matt Weber, Chuhong Yuan, Daniel Gomez,
	open list:IIO SUBSYSTEM AND DRIVERS

On Tue, 12 Nov 2019 07:59:19 +0900
Matt Ranostay <matt.ranostay@konsulko.com> wrote:

> On Tue, Nov 12, 2019 at 12:35 AM Andrea Merello
> <andrea.merello@gmail.com> wrote:
> >
> > This sensor has an embedded notch filter for reducing interferences caused
> > by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> > (and harmonics).
> >
> > Currently the said setting is left alone (the sensor defaults to 60Hz).
> > This patch introduces a IIO attribute that allows the user to set the said
> > filter to the desired frequency.
> >
> > NOTE: this has been intentionally not tied to any DT property to allow
> > the configuration of this setting from userspace, e.g. with a GUI or by
> > reading a configuration file, or maybe reading a GPIO tied to a physical
> > switch or accessing some device that can autodetect the line frequency.
> >  
> 
> Looks good to me. Although this ideal could be a device tree property
> as well, but not a big deal.
> 
> Reviewed-by: Matt Ranostay <matt.ranostay@konsulko.com>
I've no objection to someone following up with DT support for this
as they might have a device that only supports one frequency of powersupply.
However, let's leave it until we have a user that cares.

I'm going to let the patch sit on the list a little longer though as
it introduces new ABI and others may want to review.

If I seem to have lost it in 2 weeks time give me a ping
(normally I don't lose patches, but it's happened a few times in the past!)

Thanks,

Jonathan

> 
> > Cc: Hartmut Knaack <knaack.h@gmx.de>
> > Cc: Lars-Peter Clausen <lars@metafoo.de>
> > Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> > Cc: Colin Ian King <colin.king@canonical.com>
> > Cc: Patrick Havelange <patrick.havelange@essensium.com>
> > Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> > Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> > Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> > Cc: Chuhong Yuan <hslester96@gmail.com>
> > Cc: Daniel Gomez <dagmcr@gmail.com>
> > Cc: linux-iio@vger.kernel.org
> > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> > ---
> >  drivers/iio/temperature/max31856.c | 50 ++++++++++++++++++++++++++++++
> >  1 file changed, 50 insertions(+)
> >
> > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > index 73ed550e3fc9..d97ba9ee1598 100644
> > --- a/drivers/iio/temperature/max31856.c
> > +++ b/drivers/iio/temperature/max31856.c
> > @@ -23,6 +23,7 @@
> >  #define MAX31856_CR0_1SHOT         BIT(6)
> >  #define MAX31856_CR0_OCFAULT       BIT(4)
> >  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> > +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
> >  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
> >  #define MAX31856_FAULT_OVUV        BIT(1)
> >  #define MAX31856_FAULT_OPEN        BIT(0)
> > @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
> >  struct max31856_data {
> >         struct spi_device *spi;
> >         u32 thermocouple_type;
> > +       bool filter_50hz;
> >  };
> >
> >  static int max31856_read(struct max31856_data *data, u8 reg,
> > @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
> >         reg_cr0_val &= ~MAX31856_CR0_1SHOT;
> >         reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
> >
> > +       if (data->filter_50hz)
> > +               reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> > +       else
> > +               reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> > +
> >         return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
> >  }
> >
> > @@ -249,12 +256,54 @@ static ssize_t show_fault_oc(struct device *dev,
> >         return show_fault(dev, MAX31856_FAULT_OPEN, buf);
> >  }
> >
> > +static ssize_t show_filter(struct device *dev,
> > +                          struct device_attribute *attr,
> > +                          char *buf)
> > +{
> > +       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +       struct max31856_data *data = iio_priv(indio_dev);
> > +
> > +       return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> > +}
> > +
> > +static ssize_t set_filter(struct device *dev,
> > +                         struct device_attribute *attr,
> > +                         const char *buf,
> > +                         size_t len)
> > +{
> > +       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> > +       struct max31856_data *data = iio_priv(indio_dev);
> > +       unsigned int freq;
> > +       int ret;
> > +
> > +       ret = kstrtouint(buf, 10, &freq);
> > +       if (ret)
> > +               return ret;
> > +
> > +       switch (freq) {
> > +       case 50:
> > +               data->filter_50hz = true;
> > +               break;
> > +       case 60:
> > +               data->filter_50hz = false;
> > +               break;
> > +       default:
> > +               return -EINVAL;
> > +       }
> > +
> > +       max31856_init(data);
> > +       return len;
> > +}
> > +
> >  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
> >  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> > +static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
> > +                      show_filter, set_filter, 0);
> >
> >  static struct attribute *max31856_attributes[] = {
> >         &iio_dev_attr_fault_ovuv.dev_attr.attr,
> >         &iio_dev_attr_fault_oc.dev_attr.attr,
> > +       &iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
> >         NULL,
> >  };
> >
> > @@ -280,6 +329,7 @@ static int max31856_probe(struct spi_device *spi)
> >
> >         data = iio_priv(indio_dev);
> >         data->spi = spi;
> > +       data->filter_50hz = false;
> >
> >         spi_set_drvdata(spi, indio_dev);
> >
> > --
> > 2.17.1
> >  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 4/9] RFC: iio: core: add char type for sysfs attributes
  2019-11-11 15:35   ` [v2 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
@ 2019-11-16 14:45     ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-16 14:45 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Paresh Chaudhary, Matt Weber,
	Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

On Mon, 11 Nov 2019 16:35:12 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> This patch introduces IIO_VAL_CHAR type for standard IIO attributes to
> allow for attributes that needs to be represented by character rather
> than a number. This is preparatory for introducing a new attribute whose
> purpose is to describe thermocouple type, that can be i.e. "J", "K", etc..
> 
> The char-type value is stored in the first "value" integer that is passed
> to the .[read/write]_raw() callbacks.
> 
> Note that in order to make it possible for the IIO core to correctly parse
> this type (actually, to avoid integer parsing), it became mandatory for
> any driver that wish to use IIO_VAL_CHAR on a writable attribute to
> implement .write_raw_get_fmt().
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
I am a bit in two minds about this.   It is a fairly niche corner case
to support in the core, but conversely it is also very little additional
code.  Hence I'm happy to take it even with minimal usecases.

Anyone else have a strong opinion on this one?

Thanks,

Jonathan

> ---
>  drivers/iio/industrialio-core.c | 22 ++++++++++++++++++----
>  include/linux/iio/types.h       |  1 +
>  2 files changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index f72c2dc5f703..958b5c48a86f 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -596,6 +596,8 @@ static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type,
>  		}
>  		return l;
>  	}
> +	case IIO_VAL_CHAR:
> +		return snprintf(buf, len, "%c", (char)vals[0]);
>  	default:
>  		return 0;
>  	}
> @@ -837,7 +839,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
>  	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
>  	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
>  	int ret, fract_mult = 100000;
> -	int integer, fract;
> +	int integer, fract = 0;
> +	bool is_char = false;
>  
>  	/* Assumes decimal - precision based on number of digits */
>  	if (!indio_dev->info->write_raw)
> @@ -855,13 +858,24 @@ static ssize_t iio_write_channel_info(struct device *dev,
>  		case IIO_VAL_INT_PLUS_NANO:
>  			fract_mult = 100000000;
>  			break;
> +		case IIO_VAL_CHAR:
> +			is_char = true;
> +			break;
>  		default:
>  			return -EINVAL;
>  		}
>  
> -	ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
> -	if (ret)
> -		return ret;
> +	if (is_char) {
> +		char ch;
> +
> +		if (sscanf(buf, "%c", &ch) != 1)
> +			return -EINVAL;
> +		integer = ch;
> +	} else {
> +		ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
>  					 integer, fract, this_attr->address);
> diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
> index fa824e160f35..8e0026da38c9 100644
> --- a/include/linux/iio/types.h
> +++ b/include/linux/iio/types.h
> @@ -25,6 +25,7 @@ enum iio_event_info {
>  #define IIO_VAL_INT_MULTIPLE 5
>  #define IIO_VAL_FRACTIONAL 10
>  #define IIO_VAL_FRACTIONAL_LOG2 11
> +#define IIO_VAL_CHAR 12
>  
>  enum iio_available_type {
>  	IIO_AVAIL_LIST,


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 6/9] Documentation: ABI: document IIO thermocouple_type file
  2019-11-11 15:35   ` [v2 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
@ 2019-11-16 14:47     ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-16 14:47 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Paresh Chaudhary, Matt Weber,
	Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

On Mon, 11 Nov 2019 16:35:14 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> IIO core layer gained a new sysfs standard attribute "thermocouple_type".
> This patch adds it to the list of documented ABI for sysfs-bus-iio
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> ---
>  Documentation/ABI/testing/sysfs-bus-iio | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 94f7eb675108..2cf2c800dba2 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1733,3 +1733,9 @@ Contact:	linux-iio@vger.kernel.org
>  Description:
>  		Center frequency in Hz for a notch filter. Used i.e. for line
>  		noise suppression.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/in_temp_thermocouple_type
> +KernelVersion:	5.5
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Thermocouple type i.e. J, K, R, ...
Don't go with ...  No userspace can be written against unknowns.  How do you test it?

List all the types that existing drivers support and we can add to it if new
types show up.

Thanks,

Jonathan



^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 7/9] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-11-11 15:35   ` [v2 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
@ 2019-11-16 14:49     ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-16 14:49 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Paresh Chaudhary, Matt Weber,
	Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

On Mon, 11 Nov 2019 16:35:15 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> The sensor support various thermocouple types (e.g. J, K, N, ...). The
> driver allows to configure this parameter using a DT property.
> 
> This is useful when i.e. the thermocouple is physically tied to the sensor
> and it is usually not removed, or when it is at least known in advance
> which sensor will be connected to the circuit.
> 
> However, if the user can randomly connect any kind of thermocouples (i.e.
> the device exposes a connector, and the user is free to connect its own
> sensors), it would be more appropriate to provide a mechanism to
> dynamically switch from one thermocouple type to another. This can be i.e.
> handled in userspace by a GUI, a configuration file or a program that
> detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
> or whatever.
> 
> This patch adds a IIO attribute that can be used to override, at run-time,
> the DT-provided setting (which serves as default).
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Trivial comment inline to tody up.  Otherwise looks good.
> ---
>  drivers/iio/temperature/max31856.c | 39 +++++++++++++++++++++++++++++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index 9f0f4f65dccd..6689eab174df 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -6,6 +6,7 @@
>   * Copyright (C) 2018-2019 Rockwell Collins
>   */
>  
> +#include <linux/ctype.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/err.h>
> @@ -76,6 +77,10 @@ struct max31856_data {
>  	int averaging;
>  };
>  
> +const char max31856_tc_types[] = {
> +	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
> +};
> +
>  static int max31856_read(struct max31856_data *data, u8 reg,
>  			 u8 val[], unsigned int read_size)
>  {
> @@ -233,6 +238,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
>  		*val = 1 << data->averaging;
>  		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +		*val = max31856_tc_types[data->thermocouple_type];
> +		return IIO_VAL_CHAR;
>  	default:
>  		ret = -EINVAL;
>  		break;
> @@ -241,6 +249,18 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>  	return ret;
>  }
>  
> +static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
> +				      struct iio_chan_spec const *chan,
> +				      long mask)
> +{
> +	switch (mask) {
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +		return IIO_VAL_CHAR;
> +	default:
> +		return IIO_VAL_INT;
> +	}
> +}
> +
>  static int max31856_write_raw(struct iio_dev *indio_dev,
>  			      struct iio_chan_spec const *chan,
>  			      int val, int val2, long mask)
> @@ -260,7 +280,24 @@ static int max31856_write_raw(struct iio_dev *indio_dev,
>  		data->averaging = msb;
>  		max31856_init(data);
>  		break;
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +	{
> +		int tc_type = -1;
> +		int i;
> +
> +		for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
> +			if (max31856_tc_types[i] == toupper(val)) {
> +				tc_type = i;
> +				break;
> +			}
> +		}
> +		if (tc_type < 0)
> +			return -EINVAL;
>  
> +		data->thermocouple_type = tc_type;
> +		max31856_init(data);
> +		break;
> +	}
>  	default:
>  		return -EINVAL;
>  	}
> @@ -333,7 +370,6 @@ static ssize_t set_filter(struct device *dev,
>  	default:
>  		return -EINVAL;
>  	}
> -

Check your patches for unconnected little changes like this.
It adds noise and mess to the history so please clear them out.

>  	max31856_init(data);
>  	return len;
>  }
> @@ -357,6 +393,7 @@ static const struct attribute_group max31856_group = {
>  static const struct iio_info max31856_info = {
>  	.read_raw = max31856_read_raw,
>  	.write_raw = max31856_write_raw,
> +	.write_raw_get_fmt = max31856_write_raw_get_fmt,
>  	.attrs = &max31856_group,
>  };
>  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v2 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute
  2019-11-11 15:35   ` [v2 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
@ 2019-11-16 14:51     ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-16 14:51 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Paresh Chaudhary, Matt Weber,
	Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio,
	Rob Herring, Mark Rutland, devicetree

On Mon, 11 Nov 2019 16:35:16 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> We added a sysfs ABI for getting/setting the type of a thermocouple. This
> driver supports chips that support specific fixed thermocouple types; we
> cannot set it, but still we can add this sysfs attribute in RO mode to
> read-back the thermocouple type.
> 
> This driver supports actually several chips:
>  - max6675
>  - max31855[k/j/n/s/t/e/r]asa family
> 
> Max6675 supports only K-type thermocouples, so we can just report that.
> 
> Each chip in max31855 family supports just one specific thermocouple type
> (in the obvious way: i.e. max31855jasa supports J-type). This driver did
> accept a generic SPI ID and OF compatible "max31855" which does not give
> any clue about which chip is really involved (and unfortunately it seems
> we have no way to detect it).
> 
> This patch introduces a new set of, more specific, SPI IDs and OF
> compatible strings to better match the chip type.
> 
> The old, generic, "max31855" binding is kept for compatibility reasons, but
> this patch aims to deprecate it, so, should we hit it, a warning is spit.
> In such case the reported thermocouple type in sysfs is '?', because we
> have no way to know.
> 
> Regarding the implementation: the thermocouple type information is stored
> in the driver private data and I've kept only two maxim_thermocouple_chip
> types in order to avoid a lot of duplications (seven chip types with just
> a different thermocouple type).
> 
> RFT because I have no real HW to test this.
Trivial comment inline.

Thanks,

J
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> ---
>  drivers/iio/temperature/maxim_thermocouple.c | 45 ++++++++++++++++++--
>  1 file changed, 41 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
> index d1360605209c..6fa5ae9fb4ec 100644
> --- a/drivers/iio/temperature/maxim_thermocouple.c
> +++ b/drivers/iio/temperature/maxim_thermocouple.c
> @@ -14,6 +14,7 @@
>  #include <linux/of_device.h>
>  #include <linux/spi/spi.h>
>  #include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
>  #include <linux/iio/trigger.h>
>  #include <linux/iio/buffer.h>
>  #include <linux/iio/triggered_buffer.h>
> @@ -24,13 +25,25 @@
>  enum {
>  	MAX6675,
>  	MAX31855,
> +	MAX31855K,
> +	MAX31855J,
> +	MAX31855N,
> +	MAX31855S,
> +	MAX31855T,
> +	MAX31855E,
> +	MAX31855R,
> +};
> +
> +const char maxim_tc_types[] = {
> +	'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R'
>  };
>  
>  static const struct iio_chan_spec max6675_channels[] = {
>  	{	/* thermocouple temperature */
>  		.type = IIO_TEMP,
>  		.info_mask_separate =
> -			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> +			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
>  		.scan_index = 0,
>  		.scan_type = {
>  			.sign = 's',
> @@ -48,7 +61,8 @@ static const struct iio_chan_spec max31855_channels[] = {
>  		.type = IIO_TEMP,
>  		.address = 2,
>  		.info_mask_separate =
> -			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> +			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
>  		.scan_index = 0,
>  		.scan_type = {
>  			.sign = 's',
> @@ -110,6 +124,7 @@ struct maxim_thermocouple_data {
>  	const struct maxim_thermocouple_chip *chip;
>  
>  	u8 buffer[16] ____cacheline_aligned;
> +	char tc_type;
>  };
>  
>  static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
> @@ -196,8 +211,11 @@ static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,
>  			ret = IIO_VAL_INT;
>  		}
>  		break;
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +		*val = data->tc_type;
> +		ret = IIO_VAL_CHAR;
> +		break;
>  	}
> -

Another stray whitespace change. 

>  	return ret;
>  }
>  
> @@ -210,8 +228,9 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
>  	const struct spi_device_id *id = spi_get_device_id(spi);
>  	struct iio_dev *indio_dev;
>  	struct maxim_thermocouple_data *data;
> +	const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855;
>  	const struct maxim_thermocouple_chip *chip =
> -			&maxim_thermocouple_chips[id->driver_data];
> +		&maxim_thermocouple_chips[chip_type];
>  	int ret;
>  
>  	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
> @@ -229,6 +248,7 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
>  	data = iio_priv(indio_dev);
>  	data->spi = spi;
>  	data->chip = chip;
> +	data->tc_type = maxim_tc_types[id->driver_data];
>  
>  	ret = devm_iio_triggered_buffer_setup(&spi->dev,
>  				indio_dev, NULL,
> @@ -236,12 +256,22 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
>  	if (ret)
>  		return ret;
>  
> +	if (id->driver_data == MAX31855)
> +		dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type");
> +
>  	return devm_iio_device_register(&spi->dev, indio_dev);
>  }
>  
>  static const struct spi_device_id maxim_thermocouple_id[] = {
>  	{"max6675", MAX6675},
>  	{"max31855", MAX31855},
> +	{"max31855k", MAX31855K},
> +	{"max31855j", MAX31855J},
> +	{"max31855n", MAX31855N},
> +	{"max31855s", MAX31855S},
> +	{"max31855t", MAX31855T},
> +	{"max31855e", MAX31855E},
> +	{"max31855r", MAX31855R},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
> @@ -249,6 +279,13 @@ MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
>  static const struct of_device_id maxim_thermocouple_of_match[] = {
>          { .compatible = "maxim,max6675" },
>          { .compatible = "maxim,max31855" },
> +	{ .compatible = "maxim,max31855k" },
> +	{ .compatible = "maxim,max31855j" },
> +	{ .compatible = "maxim,max31855n" },
> +	{ .compatible = "maxim,max31855s" },
> +	{ .compatible = "maxim,max31855t" },
> +	{ .compatible = "maxim,max31855e" },
> +	{ .compatible = "maxim,max31855r" },
>          { },
>  };
>  MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match);


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 0/9] iio: max31856: provide more configuration options
  2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
                     ` (8 preceding siblings ...)
  2019-11-11 15:35   ` [v2 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
@ 2019-11-20 14:47   ` Andrea Merello
  2019-11-20 14:47     ` [v3 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
                       ` (8 more replies)
  9 siblings, 9 replies; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio


This series was born in order to provide more configuration options for
max31856 devices. In this version, in order to do that, it also extends
the IIO core. While at it, I've also updated maxim_thermocouple driver
to take (little) advantage of the said change.

Two hardware features (power mains noise rejection and HW averaging)
were not previously configurable, and one (thermocouple type selection)
was only possible via DT, but in my experience this is quite limiting in
several scenario (see 7/9 commit message for complete explanation).

These patches have been tested backporting max31856 driver on a 4.19
upstream kernel (Xilinx mpsoc-based board), and then rebased on the
IIO testing git tree.

I have real HW for max31856, while for maxim_thermocouple I've tested my
changes as much as I could just spoofing in the DT (no real HW).

Changes is v3:
- all: removed a always-failing e-mail address from CC list
- 3/9 and 7/9: fix: a change that should belong to 7/9 was actually contained in 3/9
- 6/9: explicitly list all thermocouple types
- 7/9 and 8/9: killed whitespace/newline stray changes
Beside that:
- 1/9: got a reviewed-by in commit comment
- 9/9: got an acked-by in commit comment
Other patches remained unchanged

Changes in v2:
- 1/9 and 3/9: changed attribute name to better match IIO naming convention
- 2/9: added separate patch to document new attribute name introduced in 1/9
- 4/9, 5/9, 6/9: new patches to add support to IIO core for handling
  thermocouple_type addribute. Most notably 4/9 introduces support for
  handling 'char' type IIO sysfs attributes; RFC on this.
- 7/9: take advantage of just-added IIO thermocouple_type attribute instead
  of using extended custom attribute
- 8/9 and 9/9: new patches to make maxim_thermocouple driver to export
  (RO) thermocouple_type attribute

Andrea Merello (9):
  iio: max31856: add option for setting mains filter rejection frequency
  Documentation: ABI: document IIO in_temp_filter_notch_center_frequency
    file
  iio: max31856: add support for configuring the HW averaging
  RFC: iio: core: add char type for sysfs attributes
  iio: core: add thermocouple_type standard attribute
  Documentation: ABI: document IIO thermocouple_type file
  iio: max31856: add support for runtime-configuring the thermocouple
    type
  RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs
    attribute
  dt-bindings: iio: maxim_thermocouple: document new 'compatible'
    strings

 Documentation/ABI/testing/sysfs-bus-iio       |  13 ++
 .../iio/temperature/maxim_thermocouple.txt    |   7 +-
 drivers/iio/industrialio-core.c               |  23 ++-
 drivers/iio/temperature/max31856.c            | 134 +++++++++++++++++-
 drivers/iio/temperature/maxim_thermocouple.c  |  44 +++++-
 include/linux/iio/types.h                     |   2 +
 6 files changed, 213 insertions(+), 10 deletions(-)

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
--
2.17.1

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 1/9] iio: max31856: add option for setting mains filter rejection frequency
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:30       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file Andrea Merello
                       ` (7 subsequent siblings)
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

This sensor has an embedded notch filter for reducing interferences caused
by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
(and harmonics).

Currently the said setting is left alone (the sensor defaults to 60Hz).
This patch introduces a IIO attribute that allows the user to set the said
filter to the desired frequency.

NOTE: this has been intentionally not tied to any DT property to allow
the configuration of this setting from userspace, e.g. with a GUI or by
reading a configuration file, or maybe reading a GPIO tied to a physical
switch or accessing some device that can autodetect the line frequency.

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Reviewed-by: Matt Ranostay <matt.ranostay@konsulko.com>
---
 drivers/iio/temperature/max31856.c | 50 ++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index 73ed550e3fc9..d97ba9ee1598 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -23,6 +23,7 @@
 #define MAX31856_CR0_1SHOT         BIT(6)
 #define MAX31856_CR0_OCFAULT       BIT(4)
 #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
+#define MAX31856_CR0_FILTER_50HZ   BIT(0)
 #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
 #define MAX31856_FAULT_OVUV        BIT(1)
 #define MAX31856_FAULT_OPEN        BIT(0)
@@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
 struct max31856_data {
 	struct spi_device *spi;
 	u32 thermocouple_type;
+	bool filter_50hz;
 };
 
 static int max31856_read(struct max31856_data *data, u8 reg,
@@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
 	reg_cr0_val &= ~MAX31856_CR0_1SHOT;
 	reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
 
+	if (data->filter_50hz)
+		reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
+	else
+		reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
+
 	return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
 }
 
@@ -249,12 +256,54 @@ static ssize_t show_fault_oc(struct device *dev,
 	return show_fault(dev, MAX31856_FAULT_OPEN, buf);
 }
 
+static ssize_t show_filter(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+
+	return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
+}
+
+static ssize_t set_filter(struct device *dev,
+			  struct device_attribute *attr,
+			  const char *buf,
+			  size_t len)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct max31856_data *data = iio_priv(indio_dev);
+	unsigned int freq;
+	int ret;
+
+	ret = kstrtouint(buf, 10, &freq);
+	if (ret)
+		return ret;
+
+	switch (freq) {
+	case 50:
+		data->filter_50hz = true;
+		break;
+	case 60:
+		data->filter_50hz = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	max31856_init(data);
+	return len;
+}
+
 static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
 static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
+static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
+		       show_filter, set_filter, 0);
 
 static struct attribute *max31856_attributes[] = {
 	&iio_dev_attr_fault_ovuv.dev_attr.attr,
 	&iio_dev_attr_fault_oc.dev_attr.attr,
+	&iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
 	NULL,
 };
 
@@ -280,6 +329,7 @@ static int max31856_probe(struct spi_device *spi)
 
 	data = iio_priv(indio_dev);
 	data->spi = spi;
+	data->filter_50hz = false;
 
 	spi_set_drvdata(spi, indio_dev);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
  2019-11-20 14:47     ` [v3 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:31       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
                       ` (6 subsequent siblings)
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

max31856 IIO driver introduced a new attribute
"in_temp_filter_notch_center_frequency".
This patch adds it to the list of documented ABI for sysfs-bus-iio

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index faaa2166d741..94f7eb675108 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1726,3 +1726,10 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 		List of valid periods (in seconds) for which the light intensity
 		must be above the threshold level before interrupt is asserted.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_filter_notch_center_frequency
+KernelVersion:	5.5
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Center frequency in Hz for a notch filter. Used i.e. for line
+		noise suppression.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 3/9] iio: max31856: add support for configuring the HW averaging
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
  2019-11-20 14:47     ` [v3 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
  2019-11-20 14:47     ` [v3 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:32       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
                       ` (5 subsequent siblings)
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

This sensor can perform samples averaging in hardware, but currently the
driver leaves this setting alone (default is no averaging).

This patch binds this HW setting to the "oversampling_ratio" IIO attribute
and allows the user to set the averaging as desired (the HW supports
averaging of 2, 5, 8 or 16 samples; in-between values are rounded up).

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 43 ++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index d97ba9ee1598..8457ca9ae326 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -12,6 +12,7 @@
 #include <linux/spi/spi.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/util_macros.h>
 #include <dt-bindings/iio/temperature/thermocouple.h>
 /*
  * The MSB of the register value determines whether the following byte will
@@ -24,6 +25,8 @@
 #define MAX31856_CR0_OCFAULT       BIT(4)
 #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
 #define MAX31856_CR0_FILTER_50HZ   BIT(0)
+#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
+#define MAX31856_AVERAGING_SHIFT   4
 #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
 #define MAX31856_FAULT_OVUV        BIT(1)
 #define MAX31856_FAULT_OPEN        BIT(0)
@@ -51,6 +54,8 @@ static const struct iio_chan_spec max31856_channels[] = {
 		.type = IIO_TEMP,
 		.info_mask_separate =
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+		.info_mask_shared_by_type =
+			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
 	},
 	{	/* Cold Junction Temperature */
 		.type = IIO_TEMP,
@@ -58,6 +63,8 @@ static const struct iio_chan_spec max31856_channels[] = {
 		.modified = 1,
 		.info_mask_separate =
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+		.info_mask_shared_by_type =
+			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
 	},
 };
 
@@ -65,6 +72,7 @@ struct max31856_data {
 	struct spi_device *spi;
 	u32 thermocouple_type;
 	bool filter_50hz;
+	int averaging;
 };
 
 static int max31856_read(struct max31856_data *data, u8 reg,
@@ -109,6 +117,10 @@ static int max31856_init(struct max31856_data *data)
 
 	reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
 	reg_cr1_val |= data->thermocouple_type;
+
+	reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
+	reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
+
 	ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
 	if (ret)
 		return ret;
@@ -217,6 +229,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 			return IIO_VAL_INT_PLUS_MICRO;
 		}
 		break;
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		*val = 1 << data->averaging;
+		return IIO_VAL_INT;
 	default:
 		ret = -EINVAL;
 		break;
@@ -225,6 +240,33 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static int max31856_write_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int val, int val2, long mask)
+{
+	struct max31856_data *data = iio_priv(indio_dev);
+	int msb;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		if (val > 16 || val < 1)
+			return -EINVAL;
+		msb = fls(val) - 1;
+		/* Round up to next 2pow if needed */
+		if (BIT(msb) < val)
+			msb++;
+
+		data->averaging = msb;
+		max31856_init(data);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -313,6 +355,7 @@ static const struct attribute_group max31856_group = {
 
 static const struct iio_info max31856_info = {
 	.read_raw = max31856_read_raw,
+	.write_raw = max31856_write_raw,
 	.attrs = &max31856_group,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 4/9] RFC: iio: core: add char type for sysfs attributes
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
                       ` (2 preceding siblings ...)
  2019-11-20 14:47     ` [v3 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:33       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 5/9] iio: core: add thermocouple_type standard attribute Andrea Merello
                       ` (4 subsequent siblings)
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

This patch introduces IIO_VAL_CHAR type for standard IIO attributes to
allow for attributes that needs to be represented by character rather
than a number. This is preparatory for introducing a new attribute whose
purpose is to describe thermocouple type, that can be i.e. "J", "K", etc..

The char-type value is stored in the first "value" integer that is passed
to the .[read/write]_raw() callbacks.

Note that in order to make it possible for the IIO core to correctly parse
this type (actually, to avoid integer parsing), it became mandatory for
any driver that wish to use IIO_VAL_CHAR on a writable attribute to
implement .write_raw_get_fmt().

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/industrialio-core.c | 22 ++++++++++++++++++----
 include/linux/iio/types.h       |  1 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index f72c2dc5f703..958b5c48a86f 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -596,6 +596,8 @@ static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type,
 		}
 		return l;
 	}
+	case IIO_VAL_CHAR:
+		return snprintf(buf, len, "%c", (char)vals[0]);
 	default:
 		return 0;
 	}
@@ -837,7 +839,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret, fract_mult = 100000;
-	int integer, fract;
+	int integer, fract = 0;
+	bool is_char = false;
 
 	/* Assumes decimal - precision based on number of digits */
 	if (!indio_dev->info->write_raw)
@@ -855,13 +858,24 @@ static ssize_t iio_write_channel_info(struct device *dev,
 		case IIO_VAL_INT_PLUS_NANO:
 			fract_mult = 100000000;
 			break;
+		case IIO_VAL_CHAR:
+			is_char = true;
+			break;
 		default:
 			return -EINVAL;
 		}
 
-	ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
-	if (ret)
-		return ret;
+	if (is_char) {
+		char ch;
+
+		if (sscanf(buf, "%c", &ch) != 1)
+			return -EINVAL;
+		integer = ch;
+	} else {
+		ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
+		if (ret)
+			return ret;
+	}
 
 	ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
 					 integer, fract, this_attr->address);
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index fa824e160f35..8e0026da38c9 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -25,6 +25,7 @@ enum iio_event_info {
 #define IIO_VAL_INT_MULTIPLE 5
 #define IIO_VAL_FRACTIONAL 10
 #define IIO_VAL_FRACTIONAL_LOG2 11
+#define IIO_VAL_CHAR 12
 
 enum iio_available_type {
 	IIO_AVAIL_LIST,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 5/9] iio: core: add thermocouple_type standard attribute
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
                       ` (3 preceding siblings ...)
  2019-11-20 14:47     ` [v3 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:36       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
                       ` (3 subsequent siblings)
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

We have a couple of thermocouple IIO drivers, supporting several chips.
Some of them support only one specific thermocouple type (e.g. "K", "J"),
one of them can be configured to work with several different thermocouple
types.

In certain applications thermocouples could be externally connected to the
chip by the user.

This patch introduces a new IIO standard attribute to report the supported
thermocouple type and, where applicable, to allow it to be dynamically set
using sysfs.

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/industrialio-core.c | 1 +
 include/linux/iio/types.h       | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 958b5c48a86f..fa2c3b321bfd 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -161,6 +161,7 @@ static const char * const iio_chan_info_postfix[] = {
 	[IIO_CHAN_INFO_DEBOUNCE_TIME] = "debounce_time",
 	[IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity",
 	[IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio",
+	[IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type",
 };
 
 /**
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 8e0026da38c9..e6fd3645963c 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -58,6 +58,7 @@ enum iio_chan_info_enum {
 	IIO_CHAN_INFO_DEBOUNCE_TIME,
 	IIO_CHAN_INFO_CALIBEMISSIVITY,
 	IIO_CHAN_INFO_OVERSAMPLING_RATIO,
+	IIO_CHAN_INFO_THERMOCOUPLE_TYPE,
 };
 
 #endif /* _IIO_TYPES_H_ */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 6/9] Documentation: ABI: document IIO thermocouple_type file
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
                       ` (4 preceding siblings ...)
  2019-11-20 14:47     ` [v3 5/9] iio: core: add thermocouple_type standard attribute Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:37       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
                       ` (2 subsequent siblings)
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

IIO core layer gained a new sysfs standard attribute "thermocouple_type".
This patch adds it to the list of documented ABI for sysfs-bus-iio

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-iio | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 94f7eb675108..d3e53a6d8331 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1733,3 +1733,9 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 		Center frequency in Hz for a notch filter. Used i.e. for line
 		noise suppression.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_temp_thermocouple_type
+KernelVersion:	5.5
+Contact:	linux-iio@vger.kernel.org
+Description:
+		One of the following thermocouple types: B, E, J, K, N, R, S, T.
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 7/9] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
                       ` (5 preceding siblings ...)
  2019-11-20 14:47     ` [v3 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:40       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
  2019-11-20 14:47     ` [v3 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio

The sensor support various thermocouple types (e.g. J, K, N, ...). The
driver allows to configure this parameter using a DT property.

This is useful when i.e. the thermocouple is physically tied to the sensor
and it is usually not removed, or when it is at least known in advance
which sensor will be connected to the circuit.

However, if the user can randomly connect any kind of thermocouples (i.e.
the device exposes a connector, and the user is free to connect its own
sensors), it would be more appropriate to provide a mechanism to
dynamically switch from one thermocouple type to another. This can be i.e.
handled in userspace by a GUI, a configuration file or a program that
detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
or whatever.

This patch adds a IIO attribute that can be used to override, at run-time,
the DT-provided setting (which serves as default).

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/max31856.c | 41 +++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
index 8457ca9ae326..4952e89c00bb 100644
--- a/drivers/iio/temperature/max31856.c
+++ b/drivers/iio/temperature/max31856.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2018-2019 Rockwell Collins
  */
 
+#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -53,7 +54,8 @@ static const struct iio_chan_spec max31856_channels[] = {
 	{	/* Thermocouple Temperature */
 		.type = IIO_TEMP,
 		.info_mask_separate =
-			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
 		.info_mask_shared_by_type =
 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
 	},
@@ -75,6 +77,10 @@ struct max31856_data {
 	int averaging;
 };
 
+const char max31856_tc_types[] = {
+	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
+};
+
 static int max31856_read(struct max31856_data *data, u8 reg,
 			 u8 val[], unsigned int read_size)
 {
@@ -232,6 +238,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
 		*val = 1 << data->averaging;
 		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+		*val = max31856_tc_types[data->thermocouple_type];
+		return IIO_VAL_CHAR;
 	default:
 		ret = -EINVAL;
 		break;
@@ -240,6 +249,18 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
+				      struct iio_chan_spec const *chan,
+				      long mask)
+{
+	switch (mask) {
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+		return IIO_VAL_CHAR;
+	default:
+		return IIO_VAL_INT;
+	}
+}
+
 static int max31856_write_raw(struct iio_dev *indio_dev,
 			      struct iio_chan_spec const *chan,
 			      int val, int val2, long mask)
@@ -259,7 +280,24 @@ static int max31856_write_raw(struct iio_dev *indio_dev,
 		data->averaging = msb;
 		max31856_init(data);
 		break;
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+	{
+		int tc_type = -1;
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
+			if (max31856_tc_types[i] == toupper(val)) {
+				tc_type = i;
+				break;
+			}
+		}
+		if (tc_type < 0)
+			return -EINVAL;
 
+		data->thermocouple_type = tc_type;
+		max31856_init(data);
+		break;
+	}
 	default:
 		return -EINVAL;
 	}
@@ -356,6 +394,7 @@ static const struct attribute_group max31856_group = {
 static const struct iio_info max31856_info = {
 	.read_raw = max31856_read_raw,
 	.write_raw = max31856_write_raw,
+	.write_raw_get_fmt = max31856_write_raw_get_fmt,
 	.attrs = &max31856_group,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
                       ` (6 preceding siblings ...)
  2019-11-20 14:47     ` [v3 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:46       ` Jonathan Cameron
  2019-11-20 14:47     ` [v3 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio,
	Rob Herring, Mark Rutland, devicetree

We added a sysfs ABI for getting/setting the type of a thermocouple. This
driver supports chips that support specific fixed thermocouple types; we
cannot set it, but still we can add this sysfs attribute in RO mode to
read-back the thermocouple type.

This driver supports actually several chips:
 - max6675
 - max31855[k/j/n/s/t/e/r]asa family

Max6675 supports only K-type thermocouples, so we can just report that.

Each chip in max31855 family supports just one specific thermocouple type
(in the obvious way: i.e. max31855jasa supports J-type). This driver did
accept a generic SPI ID and OF compatible "max31855" which does not give
any clue about which chip is really involved (and unfortunately it seems
we have no way to detect it).

This patch introduces a new set of, more specific, SPI IDs and OF
compatible strings to better match the chip type.

The old, generic, "max31855" binding is kept for compatibility reasons, but
this patch aims to deprecate it, so, should we hit it, a warning is spit.
In such case the reported thermocouple type in sysfs is '?', because we
have no way to know.

Regarding the implementation: the thermocouple type information is stored
in the driver private data and I've kept only two maxim_thermocouple_chip
types in order to avoid a lot of duplications (seven chip types with just
a different thermocouple type).

RFT because I have no real HW to test this.

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
---
 drivers/iio/temperature/maxim_thermocouple.c | 44 ++++++++++++++++++--
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
index d1360605209c..9906b31fe863 100644
--- a/drivers/iio/temperature/maxim_thermocouple.c
+++ b/drivers/iio/temperature/maxim_thermocouple.c
@@ -14,6 +14,7 @@
 #include <linux/of_device.h>
 #include <linux/spi/spi.h>
 #include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/triggered_buffer.h>
@@ -24,13 +25,25 @@
 enum {
 	MAX6675,
 	MAX31855,
+	MAX31855K,
+	MAX31855J,
+	MAX31855N,
+	MAX31855S,
+	MAX31855T,
+	MAX31855E,
+	MAX31855R,
+};
+
+const char maxim_tc_types[] = {
+	'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R'
 };
 
 static const struct iio_chan_spec max6675_channels[] = {
 	{	/* thermocouple temperature */
 		.type = IIO_TEMP,
 		.info_mask_separate =
-			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
 		.scan_index = 0,
 		.scan_type = {
 			.sign = 's',
@@ -48,7 +61,8 @@ static const struct iio_chan_spec max31855_channels[] = {
 		.type = IIO_TEMP,
 		.address = 2,
 		.info_mask_separate =
-			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
 		.scan_index = 0,
 		.scan_type = {
 			.sign = 's',
@@ -110,6 +124,7 @@ struct maxim_thermocouple_data {
 	const struct maxim_thermocouple_chip *chip;
 
 	u8 buffer[16] ____cacheline_aligned;
+	char tc_type;
 };
 
 static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
@@ -196,6 +211,10 @@ static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,
 			ret = IIO_VAL_INT;
 		}
 		break;
+	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
+		*val = data->tc_type;
+		ret = IIO_VAL_CHAR;
+		break;
 	}
 
 	return ret;
@@ -210,8 +229,9 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
 	const struct spi_device_id *id = spi_get_device_id(spi);
 	struct iio_dev *indio_dev;
 	struct maxim_thermocouple_data *data;
+	const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855;
 	const struct maxim_thermocouple_chip *chip =
-			&maxim_thermocouple_chips[id->driver_data];
+		&maxim_thermocouple_chips[chip_type];
 	int ret;
 
 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
@@ -229,6 +249,7 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
 	data = iio_priv(indio_dev);
 	data->spi = spi;
 	data->chip = chip;
+	data->tc_type = maxim_tc_types[id->driver_data];
 
 	ret = devm_iio_triggered_buffer_setup(&spi->dev,
 				indio_dev, NULL,
@@ -236,12 +257,22 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
 	if (ret)
 		return ret;
 
+	if (id->driver_data == MAX31855)
+		dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type");
+
 	return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static const struct spi_device_id maxim_thermocouple_id[] = {
 	{"max6675", MAX6675},
 	{"max31855", MAX31855},
+	{"max31855k", MAX31855K},
+	{"max31855j", MAX31855J},
+	{"max31855n", MAX31855N},
+	{"max31855s", MAX31855S},
+	{"max31855t", MAX31855T},
+	{"max31855e", MAX31855E},
+	{"max31855r", MAX31855R},
 	{},
 };
 MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
@@ -249,6 +280,13 @@ MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
 static const struct of_device_id maxim_thermocouple_of_match[] = {
         { .compatible = "maxim,max6675" },
         { .compatible = "maxim,max31855" },
+	{ .compatible = "maxim,max31855k" },
+	{ .compatible = "maxim,max31855j" },
+	{ .compatible = "maxim,max31855n" },
+	{ .compatible = "maxim,max31855s" },
+	{ .compatible = "maxim,max31855t" },
+	{ .compatible = "maxim,max31855e" },
+	{ .compatible = "maxim,max31855r" },
         { },
 };
 MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [v3 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings
  2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
                       ` (7 preceding siblings ...)
  2019-11-20 14:47     ` [v3 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
@ 2019-11-20 14:47     ` Andrea Merello
  2019-11-23 12:46       ` Jonathan Cameron
  8 siblings, 1 reply; 60+ messages in thread
From: Andrea Merello @ 2019-11-20 14:47 UTC (permalink / raw)
  To: jic23
  Cc: Andrea Merello, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Colin Ian King, Patrick Havelange,
	Matt Weber, Matt Ranostay, Chuhong Yuan, Daniel Gomez, linux-iio,
	Rob Herring, Mark Rutland, devicetree

Now the maxim_thermocouple has new, more specific, 'compatible' strings for
better distinguish the various supported chips.

This patch updates the DT bindings documentation accordingly

Cc: Hartmut Knaack <knaack.h@gmx.de>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Patrick Havelange <patrick.havelange@essensium.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Matt Ranostay <matt.ranostay@konsulko.com>
Cc: Chuhong Yuan <hslester96@gmail.com>
Cc: Daniel Gomez <dagmcr@gmail.com>
Cc: linux-iio@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../bindings/iio/temperature/maxim_thermocouple.txt        | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
index 28bc5c4d965b..bb85cd0e039c 100644
--- a/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
+++ b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
@@ -5,7 +5,10 @@ Maxim thermocouple support
 
 Required properties:
 
-	- compatible: must be "maxim,max31855" or "maxim,max6675"
+	- compatible: must be "maxim,max6675" or one of the following:
+	   "maxim,max31855k", "maxim,max31855j", "maxim,max31855n",
+	   "maxim,max31855s", "maxim,max31855t", "maxim,max31855e",
+	   "maxim,max31855r"; the generic "max,max31855" is deprecated.
 	- reg: SPI chip select number for the device
 	- spi-max-frequency: must be 4300000
 	- spi-cpha: must be defined for max6675 to enable SPI mode 1
@@ -15,7 +18,7 @@ Required properties:
 Example:
 
 	max31855@0 {
-		compatible = "maxim,max31855";
+		compatible = "maxim,max31855k";
 		reg = <0>;
 		spi-max-frequency = <4300000>;
 	};
-- 
2.17.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 1/9] iio: max31856: add option for setting mains filter rejection frequency
  2019-11-20 14:47     ` [v3 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
@ 2019-11-23 12:30       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:30 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Wed, 20 Nov 2019 15:47:48 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> This sensor has an embedded notch filter for reducing interferences caused
> by the power mains. This filter can be tuned to reject either 50Hz or 60Hz
> (and harmonics).
> 
> Currently the said setting is left alone (the sensor defaults to 60Hz).
> This patch introduces a IIO attribute that allows the user to set the said
> filter to the desired frequency.
> 
> NOTE: this has been intentionally not tied to any DT property to allow
> the configuration of this setting from userspace, e.g. with a GUI or by
> reading a configuration file, or maybe reading a GPIO tied to a physical
> switch or accessing some device that can autodetect the line frequency.
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> Reviewed-by: Matt Ranostay <matt.ranostay@konsulko.com>
Applied to the togreg branch of iio.git and pushed out as testing
for the autobuilders to play with it.

Thanks,

Jonathan

> ---
>  drivers/iio/temperature/max31856.c | 50 ++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index 73ed550e3fc9..d97ba9ee1598 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -23,6 +23,7 @@
>  #define MAX31856_CR0_1SHOT         BIT(6)
>  #define MAX31856_CR0_OCFAULT       BIT(4)
>  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
> +#define MAX31856_CR0_FILTER_50HZ   BIT(0)
>  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
>  #define MAX31856_FAULT_OVUV        BIT(1)
>  #define MAX31856_FAULT_OPEN        BIT(0)
> @@ -63,6 +64,7 @@ static const struct iio_chan_spec max31856_channels[] = {
>  struct max31856_data {
>  	struct spi_device *spi;
>  	u32 thermocouple_type;
> +	bool filter_50hz;
>  };
>  
>  static int max31856_read(struct max31856_data *data, u8 reg,
> @@ -123,6 +125,11 @@ static int max31856_init(struct max31856_data *data)
>  	reg_cr0_val &= ~MAX31856_CR0_1SHOT;
>  	reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
>  
> +	if (data->filter_50hz)
> +		reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
> +	else
> +		reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
> +
>  	return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
>  }
>  
> @@ -249,12 +256,54 @@ static ssize_t show_fault_oc(struct device *dev,
>  	return show_fault(dev, MAX31856_FAULT_OPEN, buf);
>  }
>  
> +static ssize_t show_filter(struct device *dev,
> +			   struct device_attribute *attr,
> +			   char *buf)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +
> +	return sprintf(buf, "%d\n", data->filter_50hz ? 50 : 60);
> +}
> +
> +static ssize_t set_filter(struct device *dev,
> +			  struct device_attribute *attr,
> +			  const char *buf,
> +			  size_t len)
> +{
> +	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +	struct max31856_data *data = iio_priv(indio_dev);
> +	unsigned int freq;
> +	int ret;
> +
> +	ret = kstrtouint(buf, 10, &freq);
> +	if (ret)
> +		return ret;
> +
> +	switch (freq) {
> +	case 50:
> +		data->filter_50hz = true;
> +		break;
> +	case 60:
> +		data->filter_50hz = false;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	max31856_init(data);
> +	return len;
> +}
> +
>  static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
>  static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
> +static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
> +		       show_filter, set_filter, 0);
>  
>  static struct attribute *max31856_attributes[] = {
>  	&iio_dev_attr_fault_ovuv.dev_attr.attr,
>  	&iio_dev_attr_fault_oc.dev_attr.attr,
> +	&iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
>  	NULL,
>  };
>  
> @@ -280,6 +329,7 @@ static int max31856_probe(struct spi_device *spi)
>  
>  	data = iio_priv(indio_dev);
>  	data->spi = spi;
> +	data->filter_50hz = false;
>  
>  	spi_set_drvdata(spi, indio_dev);
>  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file
  2019-11-20 14:47     ` [v3 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file Andrea Merello
@ 2019-11-23 12:31       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:31 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Wed, 20 Nov 2019 15:47:49 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> max31856 IIO driver introduced a new attribute
> "in_temp_filter_notch_center_frequency".
> This patch adds it to the list of documented ABI for sysfs-bus-iio
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Applied
> ---
>  Documentation/ABI/testing/sysfs-bus-iio | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index faaa2166d741..94f7eb675108 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1726,3 +1726,10 @@ Contact:	linux-iio@vger.kernel.org
>  Description:
>  		List of valid periods (in seconds) for which the light intensity
>  		must be above the threshold level before interrupt is asserted.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/in_filter_notch_center_frequency
> +KernelVersion:	5.5
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Center frequency in Hz for a notch filter. Used i.e. for line
> +		noise suppression.


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 3/9] iio: max31856: add support for configuring the HW averaging
  2019-11-20 14:47     ` [v3 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
@ 2019-11-23 12:32       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:32 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Wed, 20 Nov 2019 15:47:50 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> This sensor can perform samples averaging in hardware, but currently the
> driver leaves this setting alone (default is no averaging).
> 
> This patch binds this HW setting to the "oversampling_ratio" IIO attribute
> and allows the user to set the averaging as desired (the HW supports
> averaging of 2, 5, 8 or 16 samples; in-between values are rounded up).
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Applied. Thanks,

Jonathan

> ---
>  drivers/iio/temperature/max31856.c | 43 ++++++++++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index d97ba9ee1598..8457ca9ae326 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -12,6 +12,7 @@
>  #include <linux/spi/spi.h>
>  #include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
> +#include <linux/util_macros.h>
>  #include <dt-bindings/iio/temperature/thermocouple.h>
>  /*
>   * The MSB of the register value determines whether the following byte will
> @@ -24,6 +25,8 @@
>  #define MAX31856_CR0_OCFAULT       BIT(4)
>  #define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
>  #define MAX31856_CR0_FILTER_50HZ   BIT(0)
> +#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
> +#define MAX31856_AVERAGING_SHIFT   4
>  #define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
>  #define MAX31856_FAULT_OVUV        BIT(1)
>  #define MAX31856_FAULT_OPEN        BIT(0)
> @@ -51,6 +54,8 @@ static const struct iio_chan_spec max31856_channels[] = {
>  		.type = IIO_TEMP,
>  		.info_mask_separate =
>  			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +		.info_mask_shared_by_type =
> +			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
>  	},
>  	{	/* Cold Junction Temperature */
>  		.type = IIO_TEMP,
> @@ -58,6 +63,8 @@ static const struct iio_chan_spec max31856_channels[] = {
>  		.modified = 1,
>  		.info_mask_separate =
>  			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +		.info_mask_shared_by_type =
> +			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
>  	},
>  };
>  
> @@ -65,6 +72,7 @@ struct max31856_data {
>  	struct spi_device *spi;
>  	u32 thermocouple_type;
>  	bool filter_50hz;
> +	int averaging;
>  };
>  
>  static int max31856_read(struct max31856_data *data, u8 reg,
> @@ -109,6 +117,10 @@ static int max31856_init(struct max31856_data *data)
>  
>  	reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
>  	reg_cr1_val |= data->thermocouple_type;
> +
> +	reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
> +	reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
> +
>  	ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
>  	if (ret)
>  		return ret;
> @@ -217,6 +229,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>  			return IIO_VAL_INT_PLUS_MICRO;
>  		}
>  		break;
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		*val = 1 << data->averaging;
> +		return IIO_VAL_INT;
>  	default:
>  		ret = -EINVAL;
>  		break;
> @@ -225,6 +240,33 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>  	return ret;
>  }
>  
> +static int max31856_write_raw(struct iio_dev *indio_dev,
> +			      struct iio_chan_spec const *chan,
> +			      int val, int val2, long mask)
> +{
> +	struct max31856_data *data = iio_priv(indio_dev);
> +	int msb;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		if (val > 16 || val < 1)
> +			return -EINVAL;
> +		msb = fls(val) - 1;
> +		/* Round up to next 2pow if needed */
> +		if (BIT(msb) < val)
> +			msb++;
> +
> +		data->averaging = msb;
> +		max31856_init(data);
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
>  {
>  	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> @@ -313,6 +355,7 @@ static const struct attribute_group max31856_group = {
>  
>  static const struct iio_info max31856_info = {
>  	.read_raw = max31856_read_raw,
> +	.write_raw = max31856_write_raw,
>  	.attrs = &max31856_group,
>  };
>  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 4/9] RFC: iio: core: add char type for sysfs attributes
  2019-11-20 14:47     ` [v3 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
@ 2019-11-23 12:33       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:33 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Wed, 20 Nov 2019 15:47:51 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> This patch introduces IIO_VAL_CHAR type for standard IIO attributes to
> allow for attributes that needs to be represented by character rather
> than a number. This is preparatory for introducing a new attribute whose
> purpose is to describe thermocouple type, that can be i.e. "J", "K", etc..
> 
> The char-type value is stored in the first "value" integer that is passed
> to the .[read/write]_raw() callbacks.
> 
> Note that in order to make it possible for the IIO core to correctly parse
> this type (actually, to avoid integer parsing), it became mandatory for
> any driver that wish to use IIO_VAL_CHAR on a writable attribute to
> implement .write_raw_get_fmt().
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
applied.  I dropped the RFC part though given it's going in ;)

Thanks,

Jonathan

> ---
>  drivers/iio/industrialio-core.c | 22 ++++++++++++++++++----
>  include/linux/iio/types.h       |  1 +
>  2 files changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index f72c2dc5f703..958b5c48a86f 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -596,6 +596,8 @@ static ssize_t __iio_format_value(char *buf, size_t len, unsigned int type,
>  		}
>  		return l;
>  	}
> +	case IIO_VAL_CHAR:
> +		return snprintf(buf, len, "%c", (char)vals[0]);
>  	default:
>  		return 0;
>  	}
> @@ -837,7 +839,8 @@ static ssize_t iio_write_channel_info(struct device *dev,
>  	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
>  	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
>  	int ret, fract_mult = 100000;
> -	int integer, fract;
> +	int integer, fract = 0;
> +	bool is_char = false;
>  
>  	/* Assumes decimal - precision based on number of digits */
>  	if (!indio_dev->info->write_raw)
> @@ -855,13 +858,24 @@ static ssize_t iio_write_channel_info(struct device *dev,
>  		case IIO_VAL_INT_PLUS_NANO:
>  			fract_mult = 100000000;
>  			break;
> +		case IIO_VAL_CHAR:
> +			is_char = true;
> +			break;
>  		default:
>  			return -EINVAL;
>  		}
>  
> -	ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
> -	if (ret)
> -		return ret;
> +	if (is_char) {
> +		char ch;
> +
> +		if (sscanf(buf, "%c", &ch) != 1)
> +			return -EINVAL;
> +		integer = ch;
> +	} else {
> +		ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
> +		if (ret)
> +			return ret;
> +	}
>  
>  	ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
>  					 integer, fract, this_attr->address);
> diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
> index fa824e160f35..8e0026da38c9 100644
> --- a/include/linux/iio/types.h
> +++ b/include/linux/iio/types.h
> @@ -25,6 +25,7 @@ enum iio_event_info {
>  #define IIO_VAL_INT_MULTIPLE 5
>  #define IIO_VAL_FRACTIONAL 10
>  #define IIO_VAL_FRACTIONAL_LOG2 11
> +#define IIO_VAL_CHAR 12
>  
>  enum iio_available_type {
>  	IIO_AVAIL_LIST,


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 5/9] iio: core: add thermocouple_type standard attribute
  2019-11-20 14:47     ` [v3 5/9] iio: core: add thermocouple_type standard attribute Andrea Merello
@ 2019-11-23 12:36       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:36 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Wed, 20 Nov 2019 15:47:52 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> We have a couple of thermocouple IIO drivers, supporting several chips.
> Some of them support only one specific thermocouple type (e.g. "K", "J"),
> one of them can be configured to work with several different thermocouple
> types.
> 
> In certain applications thermocouples could be externally connected to the
> chip by the user.
> 
> This patch introduces a new IIO standard attribute to report the supported
> thermocouple type and, where applicable, to allow it to be dynamically set
> using sysfs.
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Applied to the togreg branch of iio.git and pushed out as testing.
Not that I can still rebase for now so any last minute comments
or acks/ reviewed-bys can still be acted on.

Thanks,

Jonathan

> ---
>  drivers/iio/industrialio-core.c | 1 +
>  include/linux/iio/types.h       | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 958b5c48a86f..fa2c3b321bfd 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -161,6 +161,7 @@ static const char * const iio_chan_info_postfix[] = {
>  	[IIO_CHAN_INFO_DEBOUNCE_TIME] = "debounce_time",
>  	[IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity",
>  	[IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio",
> +	[IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type",
>  };
>  
>  /**
> diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
> index 8e0026da38c9..e6fd3645963c 100644
> --- a/include/linux/iio/types.h
> +++ b/include/linux/iio/types.h
> @@ -58,6 +58,7 @@ enum iio_chan_info_enum {
>  	IIO_CHAN_INFO_DEBOUNCE_TIME,
>  	IIO_CHAN_INFO_CALIBEMISSIVITY,
>  	IIO_CHAN_INFO_OVERSAMPLING_RATIO,
> +	IIO_CHAN_INFO_THERMOCOUPLE_TYPE,
>  };
>  
>  #endif /* _IIO_TYPES_H_ */


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 6/9] Documentation: ABI: document IIO thermocouple_type file
  2019-11-20 14:47     ` [v3 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
@ 2019-11-23 12:37       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:37 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Wed, 20 Nov 2019 15:47:53 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> IIO core layer gained a new sysfs standard attribute "thermocouple_type".
> This patch adds it to the list of documented ABI for sysfs-bus-iio
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Applied,

Thanks,

Jonathan

> ---
>  Documentation/ABI/testing/sysfs-bus-iio | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 94f7eb675108..d3e53a6d8331 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -1733,3 +1733,9 @@ Contact:	linux-iio@vger.kernel.org
>  Description:
>  		Center frequency in Hz for a notch filter. Used i.e. for line
>  		noise suppression.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/in_temp_thermocouple_type
> +KernelVersion:	5.5
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		One of the following thermocouple types: B, E, J, K, N, R, S, T.


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 7/9] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-11-20 14:47     ` [v3 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
@ 2019-11-23 12:40       ` Jonathan Cameron
  2019-11-23 12:41         ` Jonathan Cameron
  0 siblings, 1 reply; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:40 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Wed, 20 Nov 2019 15:47:54 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> The sensor support various thermocouple types (e.g. J, K, N, ...). The
> driver allows to configure this parameter using a DT property.
> 
> This is useful when i.e. the thermocouple is physically tied to the sensor
> and it is usually not removed, or when it is at least known in advance
> which sensor will be connected to the circuit.
> 
> However, if the user can randomly connect any kind of thermocouples (i.e.
> the device exposes a connector, and the user is free to connect its own
> sensors), it would be more appropriate to provide a mechanism to
> dynamically switch from one thermocouple type to another. This can be i.e.
> handled in userspace by a GUI, a configuration file or a program that
> detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
> or whatever.
> 
> This patch adds a IIO attribute that can be used to override, at run-time,
> the DT-provided setting (which serves as default).
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Applied to the togreg branch of iio.git and pushed out as testing for
the autobuilders to play with it.

thanks,

Jonathan

> ---
>  drivers/iio/temperature/max31856.c | 41 +++++++++++++++++++++++++++++-
>  1 file changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> index 8457ca9ae326..4952e89c00bb 100644
> --- a/drivers/iio/temperature/max31856.c
> +++ b/drivers/iio/temperature/max31856.c
> @@ -6,6 +6,7 @@
>   * Copyright (C) 2018-2019 Rockwell Collins
>   */
>  
> +#include <linux/ctype.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/err.h>
> @@ -53,7 +54,8 @@ static const struct iio_chan_spec max31856_channels[] = {
>  	{	/* Thermocouple Temperature */
>  		.type = IIO_TEMP,
>  		.info_mask_separate =
> -			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> +			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
>  		.info_mask_shared_by_type =
>  			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
>  	},
> @@ -75,6 +77,10 @@ struct max31856_data {
>  	int averaging;
>  };
>  
> +const char max31856_tc_types[] = {
> +	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
> +};
> +
>  static int max31856_read(struct max31856_data *data, u8 reg,
>  			 u8 val[], unsigned int read_size)
>  {
> @@ -232,6 +238,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
>  		*val = 1 << data->averaging;
>  		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +		*val = max31856_tc_types[data->thermocouple_type];
> +		return IIO_VAL_CHAR;
>  	default:
>  		ret = -EINVAL;
>  		break;
> @@ -240,6 +249,18 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
>  	return ret;
>  }
>  
> +static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
> +				      struct iio_chan_spec const *chan,
> +				      long mask)
> +{
> +	switch (mask) {
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +		return IIO_VAL_CHAR;
> +	default:
> +		return IIO_VAL_INT;
> +	}
> +}
> +
>  static int max31856_write_raw(struct iio_dev *indio_dev,
>  			      struct iio_chan_spec const *chan,
>  			      int val, int val2, long mask)
> @@ -259,7 +280,24 @@ static int max31856_write_raw(struct iio_dev *indio_dev,
>  		data->averaging = msb;
>  		max31856_init(data);
>  		break;
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +	{
> +		int tc_type = -1;
> +		int i;
> +
> +		for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
> +			if (max31856_tc_types[i] == toupper(val)) {
> +				tc_type = i;
> +				break;
> +			}
> +		}
> +		if (tc_type < 0)
> +			return -EINVAL;
>  
> +		data->thermocouple_type = tc_type;
> +		max31856_init(data);
> +		break;
> +	}
>  	default:
>  		return -EINVAL;
>  	}
> @@ -356,6 +394,7 @@ static const struct attribute_group max31856_group = {
>  static const struct iio_info max31856_info = {
>  	.read_raw = max31856_read_raw,
>  	.write_raw = max31856_write_raw,
> +	.write_raw_get_fmt = max31856_write_raw_get_fmt,
>  	.attrs = &max31856_group,
>  };
>  


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 7/9] iio: max31856: add support for runtime-configuring the thermocouple type
  2019-11-23 12:40       ` Jonathan Cameron
@ 2019-11-23 12:41         ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:41 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio

On Sat, 23 Nov 2019 12:40:19 +0000
Jonathan Cameron <jic23@kernel.org> wrote:

> On Wed, 20 Nov 2019 15:47:54 +0100
> Andrea Merello <andrea.merello@gmail.com> wrote:
> 
> > The sensor support various thermocouple types (e.g. J, K, N, ...). The
> > driver allows to configure this parameter using a DT property.
> > 
> > This is useful when i.e. the thermocouple is physically tied to the sensor
> > and it is usually not removed, or when it is at least known in advance
> > which sensor will be connected to the circuit.
> > 
> > However, if the user can randomly connect any kind of thermocouples (i.e.
> > the device exposes a connector, and the user is free to connect its own
> > sensors), it would be more appropriate to provide a mechanism to
> > dynamically switch from one thermocouple type to another. This can be i.e.
> > handled in userspace by a GUI, a configuration file or a program that
> > detects the thermocouple type by reading a GPIO, or a eeprom on the probe,
> > or whatever.
> > 
> > This patch adds a IIO attribute that can be used to override, at run-time,
> > the DT-provided setting (which serves as default).
> > 
> > Cc: Hartmut Knaack <knaack.h@gmx.de>
> > Cc: Lars-Peter Clausen <lars@metafoo.de>
> > Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> > Cc: Colin Ian King <colin.king@canonical.com>
> > Cc: Patrick Havelange <patrick.havelange@essensium.com>
> > Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> > Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> > Cc: Chuhong Yuan <hslester96@gmail.com>
> > Cc: Daniel Gomez <dagmcr@gmail.com>
> > Cc: linux-iio@vger.kernel.org
> > Signed-off-by: Andrea Merello <andrea.merello@gmail.com>  
> Applied to the togreg branch of iio.git and pushed out as testing for
> the autobuilders to play with it.
> 
One immediate tweak from my own build tests.  Missing static on the 
types array. I've fixed up.

Jonathan

> thanks,
> 
> Jonathan
> 
> > ---
> >  drivers/iio/temperature/max31856.c | 41 +++++++++++++++++++++++++++++-
> >  1 file changed, 40 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iio/temperature/max31856.c b/drivers/iio/temperature/max31856.c
> > index 8457ca9ae326..4952e89c00bb 100644
> > --- a/drivers/iio/temperature/max31856.c
> > +++ b/drivers/iio/temperature/max31856.c
> > @@ -6,6 +6,7 @@
> >   * Copyright (C) 2018-2019 Rockwell Collins
> >   */
> >  
> > +#include <linux/ctype.h>
> >  #include <linux/module.h>
> >  #include <linux/init.h>
> >  #include <linux/err.h>
> > @@ -53,7 +54,8 @@ static const struct iio_chan_spec max31856_channels[] = {
> >  	{	/* Thermocouple Temperature */
> >  		.type = IIO_TEMP,
> >  		.info_mask_separate =
> > -			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> > +			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> > +			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
> >  		.info_mask_shared_by_type =
> >  			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
> >  	},
> > @@ -75,6 +77,10 @@ struct max31856_data {
> >  	int averaging;
> >  };
> >  
> > +const char max31856_tc_types[] = {
> > +	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
> > +};
> > +
> >  static int max31856_read(struct max31856_data *data, u8 reg,
> >  			 u8 val[], unsigned int read_size)
> >  {
> > @@ -232,6 +238,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
> >  	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> >  		*val = 1 << data->averaging;
> >  		return IIO_VAL_INT;
> > +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> > +		*val = max31856_tc_types[data->thermocouple_type];
> > +		return IIO_VAL_CHAR;
> >  	default:
> >  		ret = -EINVAL;
> >  		break;
> > @@ -240,6 +249,18 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
> >  	return ret;
> >  }
> >  
> > +static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
> > +				      struct iio_chan_spec const *chan,
> > +				      long mask)
> > +{
> > +	switch (mask) {
> > +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> > +		return IIO_VAL_CHAR;
> > +	default:
> > +		return IIO_VAL_INT;
> > +	}
> > +}
> > +
> >  static int max31856_write_raw(struct iio_dev *indio_dev,
> >  			      struct iio_chan_spec const *chan,
> >  			      int val, int val2, long mask)
> > @@ -259,7 +280,24 @@ static int max31856_write_raw(struct iio_dev *indio_dev,
> >  		data->averaging = msb;
> >  		max31856_init(data);
> >  		break;
> > +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> > +	{
> > +		int tc_type = -1;
> > +		int i;
> > +
> > +		for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
> > +			if (max31856_tc_types[i] == toupper(val)) {
> > +				tc_type = i;
> > +				break;
> > +			}
> > +		}
> > +		if (tc_type < 0)
> > +			return -EINVAL;
> >  
> > +		data->thermocouple_type = tc_type;
> > +		max31856_init(data);
> > +		break;
> > +	}
> >  	default:
> >  		return -EINVAL;
> >  	}
> > @@ -356,6 +394,7 @@ static const struct attribute_group max31856_group = {
> >  static const struct iio_info max31856_info = {
> >  	.read_raw = max31856_read_raw,
> >  	.write_raw = max31856_write_raw,
> > +	.write_raw_get_fmt = max31856_write_raw_get_fmt,
> >  	.attrs = &max31856_group,
> >  };
> >    
> 


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute
  2019-11-20 14:47     ` [v3 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
@ 2019-11-23 12:46       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:46 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio, Rob Herring, Mark Rutland,
	devicetree

On Wed, 20 Nov 2019 15:47:55 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> We added a sysfs ABI for getting/setting the type of a thermocouple. This
> driver supports chips that support specific fixed thermocouple types; we
> cannot set it, but still we can add this sysfs attribute in RO mode to
> read-back the thermocouple type.
> 
> This driver supports actually several chips:
>  - max6675
>  - max31855[k/j/n/s/t/e/r]asa family
> 
> Max6675 supports only K-type thermocouples, so we can just report that.
> 
> Each chip in max31855 family supports just one specific thermocouple type
> (in the obvious way: i.e. max31855jasa supports J-type). This driver did
> accept a generic SPI ID and OF compatible "max31855" which does not give
> any clue about which chip is really involved (and unfortunately it seems
> we have no way to detect it).
> 
> This patch introduces a new set of, more specific, SPI IDs and OF
> compatible strings to better match the chip type.
> 
> The old, generic, "max31855" binding is kept for compatibility reasons, but
> this patch aims to deprecate it, so, should we hit it, a warning is spit.
> In such case the reported thermocouple type in sysfs is '?', because we
> have no way to know.
> 
> Regarding the implementation: the thermocouple type information is stored
> in the driver private data and I've kept only two maxim_thermocouple_chip
> types in order to avoid a lot of duplications (seven chip types with just
> a different thermocouple type).
> 
> RFT because I have no real HW to test this.
I'm going to gamble on this as seems fairly obviously correct plus
your DT spoofing tests should have tested the new code.

Obviously actual tests appreciated if anyone with hardware has time.

Applied to the togreg branch of iio.git and pushed out as testing for
the autobuilders to play with it.

Thanks,

Jonathan

> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> ---
>  drivers/iio/temperature/maxim_thermocouple.c | 44 ++++++++++++++++++--
>  1 file changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
> index d1360605209c..9906b31fe863 100644
> --- a/drivers/iio/temperature/maxim_thermocouple.c
> +++ b/drivers/iio/temperature/maxim_thermocouple.c
> @@ -14,6 +14,7 @@
>  #include <linux/of_device.h>
>  #include <linux/spi/spi.h>
>  #include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
>  #include <linux/iio/trigger.h>
>  #include <linux/iio/buffer.h>
>  #include <linux/iio/triggered_buffer.h>
> @@ -24,13 +25,25 @@
>  enum {
>  	MAX6675,
>  	MAX31855,
> +	MAX31855K,
> +	MAX31855J,
> +	MAX31855N,
> +	MAX31855S,
> +	MAX31855T,
> +	MAX31855E,
> +	MAX31855R,
> +};
> +
> +const char maxim_tc_types[] = {
> +	'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R'
>  };
>  
>  static const struct iio_chan_spec max6675_channels[] = {
>  	{	/* thermocouple temperature */
>  		.type = IIO_TEMP,
>  		.info_mask_separate =
> -			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> +			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
>  		.scan_index = 0,
>  		.scan_type = {
>  			.sign = 's',
> @@ -48,7 +61,8 @@ static const struct iio_chan_spec max31855_channels[] = {
>  		.type = IIO_TEMP,
>  		.address = 2,
>  		.info_mask_separate =
> -			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> +			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> +			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
>  		.scan_index = 0,
>  		.scan_type = {
>  			.sign = 's',
> @@ -110,6 +124,7 @@ struct maxim_thermocouple_data {
>  	const struct maxim_thermocouple_chip *chip;
>  
>  	u8 buffer[16] ____cacheline_aligned;
> +	char tc_type;
>  };
>  
>  static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
> @@ -196,6 +211,10 @@ static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,
>  			ret = IIO_VAL_INT;
>  		}
>  		break;
> +	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
> +		*val = data->tc_type;
> +		ret = IIO_VAL_CHAR;
> +		break;
>  	}
>  
>  	return ret;
> @@ -210,8 +229,9 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
>  	const struct spi_device_id *id = spi_get_device_id(spi);
>  	struct iio_dev *indio_dev;
>  	struct maxim_thermocouple_data *data;
> +	const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855;
>  	const struct maxim_thermocouple_chip *chip =
> -			&maxim_thermocouple_chips[id->driver_data];
> +		&maxim_thermocouple_chips[chip_type];
>  	int ret;
>  
>  	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
> @@ -229,6 +249,7 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
>  	data = iio_priv(indio_dev);
>  	data->spi = spi;
>  	data->chip = chip;
> +	data->tc_type = maxim_tc_types[id->driver_data];
>  
>  	ret = devm_iio_triggered_buffer_setup(&spi->dev,
>  				indio_dev, NULL,
> @@ -236,12 +257,22 @@ static int maxim_thermocouple_probe(struct spi_device *spi)
>  	if (ret)
>  		return ret;
>  
> +	if (id->driver_data == MAX31855)
> +		dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type");
> +
>  	return devm_iio_device_register(&spi->dev, indio_dev);
>  }
>  
>  static const struct spi_device_id maxim_thermocouple_id[] = {
>  	{"max6675", MAX6675},
>  	{"max31855", MAX31855},
> +	{"max31855k", MAX31855K},
> +	{"max31855j", MAX31855J},
> +	{"max31855n", MAX31855N},
> +	{"max31855s", MAX31855S},
> +	{"max31855t", MAX31855T},
> +	{"max31855e", MAX31855E},
> +	{"max31855r", MAX31855R},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
> @@ -249,6 +280,13 @@ MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
>  static const struct of_device_id maxim_thermocouple_of_match[] = {
>          { .compatible = "maxim,max6675" },
>          { .compatible = "maxim,max31855" },
> +	{ .compatible = "maxim,max31855k" },
> +	{ .compatible = "maxim,max31855j" },
> +	{ .compatible = "maxim,max31855n" },
> +	{ .compatible = "maxim,max31855s" },
> +	{ .compatible = "maxim,max31855t" },
> +	{ .compatible = "maxim,max31855e" },
> +	{ .compatible = "maxim,max31855r" },
>          { },
>  };
>  MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match);


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [v3 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings
  2019-11-20 14:47     ` [v3 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
@ 2019-11-23 12:46       ` Jonathan Cameron
  0 siblings, 0 replies; 60+ messages in thread
From: Jonathan Cameron @ 2019-11-23 12:46 UTC (permalink / raw)
  To: Andrea Merello
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Colin Ian King, Patrick Havelange, Matt Weber, Matt Ranostay,
	Chuhong Yuan, Daniel Gomez, linux-iio, Rob Herring, Mark Rutland,
	devicetree

On Wed, 20 Nov 2019 15:47:56 +0100
Andrea Merello <andrea.merello@gmail.com> wrote:

> Now the maxim_thermocouple has new, more specific, 'compatible' strings for
> better distinguish the various supported chips.
> 
> This patch updates the DT bindings documentation accordingly
> 
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Patrick Havelange <patrick.havelange@essensium.com>
> Cc: Matt Weber <matthew.weber@rockwellcollins.com>
> Cc: Matt Ranostay <matt.ranostay@konsulko.com>
> Cc: Chuhong Yuan <hslester96@gmail.com>
> Cc: Daniel Gomez <dagmcr@gmail.com>
> Cc: linux-iio@vger.kernel.org
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
> Acked-by: Rob Herring <robh@kernel.org>
Applied,

Thanks,

Jonathan

> ---
>  .../bindings/iio/temperature/maxim_thermocouple.txt        | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
> index 28bc5c4d965b..bb85cd0e039c 100644
> --- a/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
> +++ b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
> @@ -5,7 +5,10 @@ Maxim thermocouple support
>  
>  Required properties:
>  
> -	- compatible: must be "maxim,max31855" or "maxim,max6675"
> +	- compatible: must be "maxim,max6675" or one of the following:
> +	   "maxim,max31855k", "maxim,max31855j", "maxim,max31855n",
> +	   "maxim,max31855s", "maxim,max31855t", "maxim,max31855e",
> +	   "maxim,max31855r"; the generic "max,max31855" is deprecated.
>  	- reg: SPI chip select number for the device
>  	- spi-max-frequency: must be 4300000
>  	- spi-cpha: must be defined for max6675 to enable SPI mode 1
> @@ -15,7 +18,7 @@ Required properties:
>  Example:
>  
>  	max31855@0 {
> -		compatible = "maxim,max31855";
> +		compatible = "maxim,max31855k";
>  		reg = <0>;
>  		spi-max-frequency = <4300000>;
>  	};


^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, back to index

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-23 12:17 [PATCH 0/3] iio: max31856: provide more configuration options Andrea Merello
2019-09-23 12:17 ` [PATCH 1/3] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
2019-10-06  7:54   ` Jonathan Cameron
2019-10-16 13:14     ` Andrea Merello
2019-10-17 12:32       ` Jonathan Cameron
2019-10-18 13:46         ` Andrea Merello
2019-10-22  9:34           ` Jonathan Cameron
2019-10-23  8:29             ` Andrea Merello
2019-10-27  9:22               ` Jonathan Cameron
2019-10-28  7:32                 ` Andrea Merello
2019-11-02 14:17                   ` Jonathan Cameron
2019-11-04 13:51                     ` Andrea Merello
2019-09-23 12:17 ` [PATCH 2/3] iio: max31856: add support for configuring the HW averaging Andrea Merello
2019-10-06  7:55   ` Jonathan Cameron
2019-10-16 13:33     ` Andrea Merello
2019-10-17 12:34       ` Jonathan Cameron
2019-10-18 13:47         ` Andrea Merello
2019-09-23 12:17 ` [PATCH 3/3] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
2019-10-06  7:58   ` Jonathan Cameron
2019-10-16 13:43     ` Andrea Merello
2019-10-17 12:35       ` Jonathan Cameron
2019-10-18 13:48         ` Andrea Merello
2019-11-11 15:35 ` [v2 0/9] iio: max31856: provide more configuration options Andrea Merello
2019-11-11 15:35   ` [v2 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
2019-11-11 22:59     ` Matt Ranostay
2019-11-16 14:29       ` Jonathan Cameron
2019-11-11 15:35   ` [v2 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file Andrea Merello
2019-11-11 15:35   ` [v2 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
2019-11-11 23:01     ` Matt Ranostay
2019-11-11 15:35   ` [v2 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
2019-11-16 14:45     ` Jonathan Cameron
2019-11-11 15:35   ` [v2 5/9] iio: core: add thermocouple_type standard attribute Andrea Merello
2019-11-11 15:35   ` [v2 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
2019-11-16 14:47     ` Jonathan Cameron
2019-11-11 15:35   ` [v2 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
2019-11-16 14:49     ` Jonathan Cameron
2019-11-11 15:35   ` [v2 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
2019-11-16 14:51     ` Jonathan Cameron
2019-11-11 15:35   ` [v2 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
2019-11-14 22:12     ` Rob Herring
2019-11-20 14:47   ` [v3 0/9] iio: max31856: provide more configuration options Andrea Merello
2019-11-20 14:47     ` [v3 1/9] iio: max31856: add option for setting mains filter rejection frequency Andrea Merello
2019-11-23 12:30       ` Jonathan Cameron
2019-11-20 14:47     ` [v3 2/9] Documentation: ABI: document IIO in_temp_filter_notch_center_frequency file Andrea Merello
2019-11-23 12:31       ` Jonathan Cameron
2019-11-20 14:47     ` [v3 3/9] iio: max31856: add support for configuring the HW averaging Andrea Merello
2019-11-23 12:32       ` Jonathan Cameron
2019-11-20 14:47     ` [v3 4/9] RFC: iio: core: add char type for sysfs attributes Andrea Merello
2019-11-23 12:33       ` Jonathan Cameron
2019-11-20 14:47     ` [v3 5/9] iio: core: add thermocouple_type standard attribute Andrea Merello
2019-11-23 12:36       ` Jonathan Cameron
2019-11-20 14:47     ` [v3 6/9] Documentation: ABI: document IIO thermocouple_type file Andrea Merello
2019-11-23 12:37       ` Jonathan Cameron
2019-11-20 14:47     ` [v3 7/9] iio: max31856: add support for runtime-configuring the thermocouple type Andrea Merello
2019-11-23 12:40       ` Jonathan Cameron
2019-11-23 12:41         ` Jonathan Cameron
2019-11-20 14:47     ` [v3 8/9] RFC/RFT: iio: maxim_thermocouple: add thermocouple_type sysfs attribute Andrea Merello
2019-11-23 12:46       ` Jonathan Cameron
2019-11-20 14:47     ` [v3 9/9] dt-bindings: iio: maxim_thermocouple: document new 'compatible' strings Andrea Merello
2019-11-23 12:46       ` Jonathan Cameron

Linux-IIO Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-iio/0 linux-iio/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-iio linux-iio/ https://lore.kernel.org/linux-iio \
		linux-iio@vger.kernel.org
	public-inbox-index linux-iio

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-iio


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git