All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/1] iio: mlx90614: Implement filter configuration
@ 2015-07-07 14:44 Crt Mori
  2015-07-08 16:59 ` Jonathan Cameron
  0 siblings, 1 reply; 6+ messages in thread
From: Crt Mori @ 2015-07-07 14:44 UTC (permalink / raw)
  To: linux-iio, Peter Meerwald, Vianney le Clément de Saint-Marcq,
	Johnathan Iain Cameron

[-- Attachment #1: Type: text/plain, Size: 5529 bytes --]

Implemented FIR and IIR filter configuration which are located
within the configuration register of EEPROM. I have used the
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY for FIR settings and
IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY for IIR settings just
to reuse IIO_CHAN_INFO structure with closes resemblance of the
settings (although it would have been better to drop that
3DB_FREQUENCY part).

The diff is made towards togreg branch as that branch seems to have the
most recent updates of mlx90614 driver

Signed-off-by: Crt Mori <cmo@melexis.com>
---
diff --git a/drivers/iio/temperature/mlx90614.c
b/drivers/iio/temperature/mlx90614.c
index 909278a..d767d2f 100644
--- a/drivers/iio/temperature/mlx90614.c
+++ b/drivers/iio/temperature/mlx90614.c
@@ -20,7 +20,6 @@
  * always has a pull-up so we do not need an extra GPIO to drive it high.
If
  * the "wakeup" GPIO is not given, power management will be disabled.
  *
- * TODO: filter configuration
  */

 #include <linux/err.h>
@@ -79,6 +78,25 @@ struct mlx90614_data {
  unsigned long ready_timestamp; /* in jiffies */
 };

+/* Allowed percentage values for IIR filtering */
+static const u8 mlx90614_iir_values[] = {50, 25, 17, 13, 100, 80, 67, 57};
+
+/*
+ * Find the IIR value inside mlx90614_iir_values array and return its
position
+ */
+static inline s32 mlx90614_iir_search(int value)
+{
+ u8 i;
+ if (value < 0 || value > 100)
+ return -EINVAL;
+
+ for (i=0; i < ARRAY_SIZE(mlx90614_iir_values); ++i) {
+ if (value == mlx90614_iir_values[i])
+ return i;
+ }
+ return -EINVAL;
+}
+
 /*
  * Erase an address and write word.
  * The mutex must be locked before calling.
@@ -236,6 +254,31 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
  *val2 = ret * MLX90614_CONST_EMISSIVITY_RESOLUTION;
  }
  return IIO_VAL_INT_PLUS_NANO;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* FIR setting */
+ mlx90614_power_get(data, false);
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_read_word_data(data->client,MLX90614_CONFIG);
+ mutex_unlock(&data->lock);
+ mlx90614_power_put(data);
+
+ if (ret < 0)
+ return ret;
+
+ *val = (ret & MLX90614_CONFIG_FIR_MASK) >>
+ MLX90614_CONFIG_FIR_SHIFT;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: /* IIR setting */
+ mlx90614_power_get(data, false);
+ mutex_lock(&data->lock);
+ ret = i2c_smbus_read_word_data(data->client,MLX90614_CONFIG);
+ mutex_unlock(&data->lock);
+ mlx90614_power_put(data);
+
+ if (ret < 0)
+ return ret;
+
+ *val = mlx90614_iir_values[ret & MLX90614_CONFIG_IIR_MASK];
+ return IIO_VAL_INT;
  default:
  return -EINVAL;
  }
@@ -263,6 +306,52 @@ static int mlx90614_write_raw(struct iio_dev
*indio_dev,
  mlx90614_power_put(data);

  return ret;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: /* FIR Filter */
+ if (val < 0 || val > 7)
+ return -EINVAL;
+
+ mlx90614_power_get(data, false);
+ mutex_lock(&data->lock);
+
+ /* CONFIG register values must not be changed so we must read
+ * them before we actually write changes */
+ ret = i2c_smbus_read_word_data(data->client,MLX90614_CONFIG);
+ if (ret >= 0)
+ {
+ /* Write changed values */
+ ret = mlx90614_write_word(data->client, MLX90614_CONFIG,
+  (val << MLX90614_CONFIG_FIR_SHIFT) |
+  ((u16) ret & (~((u16) MLX90614_CONFIG_FIR_MASK))));
+ }
+ mutex_unlock(&data->lock);
+ mlx90614_power_put(data);
+
+ return ret;
+ case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: /* IIR Filter */
+ ret = mlx90614_iir_search(val);
+ if (ret < 0)
+ return ret;
+ /* If there is no error, then we have a sensor equivalent value
+ * in ret. We need to store it temporary to val, as we still
+ * have more data to save in ret before we can actually write */
+ val = ret;
+
+ mlx90614_power_get(data, false);
+ mutex_lock(&data->lock);
+ /* CONFIG register values must not be changed so we must read
+ * them before we actually write changes*/
+ ret = i2c_smbus_read_word_data(data->client,MLX90614_CONFIG);
+ if (ret >= 0)
+ {
+ /* Write changed values */
+ ret = mlx90614_write_word(data->client, MLX90614_CONFIG,
+  (val << MLX90614_CONFIG_IIR_SHIFT) |
+  ((u16) ret & (~(u16) MLX90614_CONFIG_IIR_MASK)));
+ }
+ mutex_unlock(&data->lock);
+ mlx90614_power_put(data);
+
+ return ret;
  default:
  return -EINVAL;
  }
@@ -275,6 +364,10 @@ static int mlx90614_write_raw_get_fmt(struct iio_dev
*indio_dev,
  switch (mask) {
  case IIO_CHAN_INFO_CALIBEMISSIVITY:
  return IIO_VAL_INT_PLUS_NANO;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
+ return IIO_VAL_INT_PLUS_MICRO;
  default:
  return -EINVAL;
  }
@@ -294,7 +387,9 @@ static const struct iio_chan_spec mlx90614_channels[] =
{
  .modified = 1,
  .channel2 = IIO_MOD_TEMP_OBJECT,
  .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
-    BIT(IIO_CHAN_INFO_CALIBEMISSIVITY),
+    BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) |
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) |
+ BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),
  .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
     BIT(IIO_CHAN_INFO_SCALE),
  },
@@ -305,7 +400,9 @@ static const struct iio_chan_spec mlx90614_channels[] =
{
  .channel = 1,
  .channel2 = IIO_MOD_TEMP_OBJECT,
  .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
-    BIT(IIO_CHAN_INFO_CALIBEMISSIVITY),
+    BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) |
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) |
+ BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY),
  .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
     BIT(IIO_CHAN_INFO_SCALE),
  },

[-- Attachment #2: Type: text/html, Size: 12863 bytes --]

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

end of thread, other threads:[~2015-07-13  7:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-07 14:44 [PATCH 0/1] iio: mlx90614: Implement filter configuration Crt Mori
2015-07-08 16:59 ` Jonathan Cameron
2015-07-08 20:51   ` Crt Mori
2015-07-11 18:23     ` Jonathan Cameron
2015-07-11 21:14       ` Crt Mori
2015-07-13  7:45         ` Jonathan Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.