All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Cercueil <paul@crapouillou.net>
To: Jonathan Cameron <jic23@kernel.org>, Peter Rosin <peda@axentia.se>
Cc: Lars-Peter Clausen <lars@metafoo.de>,
	list@opendingux.net, linux-iio@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Paul Cercueil <paul@crapouillou.net>
Subject: [PATCH 3/4] iio: afe/rescale: Add support for converting scale avail table
Date: Thu, 21 Jul 2022 20:15:25 +0100	[thread overview]
Message-ID: <20220721191526.374152-4-paul@crapouillou.net> (raw)
In-Reply-To: <20220721191526.374152-1-paul@crapouillou.net>

When the IIO channel has a scale_available attribute, we want the values
contained to be properly converted the same way the scale value is.

Since rescale_process_scale() may change the encoding type, we must
convert the IIO_AVAIL_LIST to a IIO_AVAIL_LIST_WITH_TYPE.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
 drivers/iio/afe/iio-rescale.c   | 85 +++++++++++++++++++++++++++++++++
 include/linux/iio/afe/rescale.h |  2 +
 2 files changed, 87 insertions(+)

diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c
index 6949d2151025..5c9970b93384 100644
--- a/drivers/iio/afe/iio-rescale.c
+++ b/drivers/iio/afe/iio-rescale.c
@@ -232,6 +232,18 @@ static int rescale_read_avail(struct iio_dev *indio_dev,
 		*type = IIO_VAL_INT;
 		return iio_read_avail_channel_raw(rescale->source,
 						  vals, length);
+	case IIO_CHAN_INFO_SCALE:
+		if (rescale->chan_processed) {
+			return iio_read_avail_channel_attribute(rescale->source,
+								vals, type,
+								length,
+								IIO_CHAN_INFO_SCALE);
+		} else if (rescale->scale_len) {
+			*length = rescale->scale_len;
+			*vals = rescale->scale_data;
+			return IIO_AVAIL_LIST_WITH_TYPE;
+		}
+		fallthrough;
 	default:
 		return -EINVAL;
 	}
@@ -266,11 +278,74 @@ static ssize_t rescale_write_ext_info(struct iio_dev *indio_dev,
 					  buf, len);
 }
 
+static int rescale_init_scale_avail(struct device *dev, struct rescale *rescale)
+{
+	int ret, type, length, *data;
+	const int *scale_raw;
+	unsigned int i;
+	size_t out_len;
+
+	ret = iio_read_avail_channel_attribute(rescale->source, &scale_raw,
+					       &type, &length,
+					       IIO_CHAN_INFO_SCALE);
+	if (ret < 0)
+		return ret;
+
+	switch (ret) {
+	case IIO_AVAIL_LIST_WITH_TYPE:
+		out_len = length;
+		break;
+	case IIO_AVAIL_LIST:
+		if (type == IIO_VAL_INT)
+			out_len = length * 3 / 1;
+		else
+			out_len = length * 3 / 2;
+		break;
+	default:
+		/* TODO: Support IIO_AVAIL_RANGE */
+		return -EOPNOTSUPP;
+	}
+
+	data = devm_kzalloc(dev, sizeof(*data) * out_len, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	if (ret == IIO_AVAIL_LIST_WITH_TYPE) {
+		memcpy(data, scale_raw, sizeof(*scale_raw) * length);
+	} else if (type == IIO_VAL_INT) {
+		for (i = 0; i < length; i++) {
+			data[i * 3 + 0] = scale_raw[i];
+			data[i * 3 + 2] = IIO_VAL_INT;
+		}
+	} else {
+		for (i = 0; i < length / 2; i++) {
+			data[i * 3 + 0] = scale_raw[i * 2];
+			data[i * 3 + 1] = scale_raw[i * 2 + 1];
+			data[i * 3 + 2] = type;
+		}
+	}
+
+	for (i = 0; i < out_len; i += 3) {
+		ret = rescale_process_scale(rescale, data[i + 2],
+					    &data[i], &data[i + 1]);
+		if (ret < 0)
+			return ret;
+
+		data[i + 2] = ret;
+	}
+
+	rescale->scale_len = out_len;
+	rescale->scale_data = data;
+
+	return 0;
+}
+
 static int rescale_configure_channel(struct device *dev,
 				     struct rescale *rescale)
 {
 	struct iio_chan_spec *chan = &rescale->chan;
 	struct iio_chan_spec const *schan = rescale->source->channel;
+	int ret;
 
 	chan->indexed = 1;
 	chan->output = schan->output;
@@ -303,6 +378,16 @@ static int rescale_configure_channel(struct device *dev,
 	    !rescale->chan_processed)
 		chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW);
 
+	if (iio_channel_has_available(schan, IIO_CHAN_INFO_SCALE)) {
+		chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_SCALE);
+
+		if (!rescale->chan_processed) {
+			ret = rescale_init_scale_avail(dev, rescale);
+			if (ret)
+				return ret;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/include/linux/iio/afe/rescale.h b/include/linux/iio/afe/rescale.h
index 6eecb435488f..74de2962f864 100644
--- a/include/linux/iio/afe/rescale.h
+++ b/include/linux/iio/afe/rescale.h
@@ -26,6 +26,8 @@ struct rescale {
 	s32 numerator;
 	s32 denominator;
 	s32 offset;
+	int scale_len;
+	int *scale_data;
 };
 
 int rescale_process_scale(struct rescale *rescale, int scale_type,
-- 
2.35.1


  parent reply	other threads:[~2022-07-21 19:16 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-21 19:15 [PATCH 0/4] iio: afe/rescale improvements Paul Cercueil
2022-07-21 19:15 ` [PATCH 1/4] iio: inkern: Remove useless argument to iio_channel_read_max() Paul Cercueil
2022-07-31 17:07   ` Jonathan Cameron
2022-07-21 19:15 ` [PATCH 2/4] iio: core: Add support for IIO_AVAIL_LIST_WITH_TYPE Paul Cercueil
2022-07-31 17:22   ` Jonathan Cameron
2022-07-21 19:15 ` Paul Cercueil [this message]
2022-07-21 22:16   ` [PATCH 3/4] iio: afe/rescale: Add support for converting scale avail table Peter Rosin
2022-07-22  8:52     ` Paul Cercueil
2022-07-31 16:58       ` Jonathan Cameron
2022-07-21 19:15 ` [PATCH 4/4] iio: afe/rescale: Implement write_raw Paul Cercueil
2022-07-21 22:16   ` Peter Rosin
2022-07-22  9:33     ` Paul Cercueil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220721191526.374152-4-paul@crapouillou.net \
    --to=paul@crapouillou.net \
    --cc=jic23@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=list@opendingux.net \
    --cc=peda@axentia.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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.