Received: by 2002:ab2:6991:0:b0:1f7:f6c3:9cb1 with SMTP id v17csp57741lqo; Tue, 7 May 2024 12:02:51 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXkQYdkBN5olT8L85bjI/iwEpozKWg7UgsaufgRojLwjE5k5/qW0eNpCxzEtE0Kgb9n9R0FAxt/x0Y1rlYW0yIAjCI9F+seOah3tSrp3A== X-Google-Smtp-Source: AGHT+IF8CdLT8rHFCzYd/Jdphb007+ZRKc6h9kh9kY5b9vzWMxcmD6HfpHiQvCMjX3WNVrpYxo/9 X-Received: by 2002:a05:6358:720f:b0:18d:787a:4155 with SMTP id e5c5f4694b2df-192d2a12e9fmr78154455d.1.1715108571570; Tue, 07 May 2024 12:02:51 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1715108571; cv=pass; d=google.com; s=arc-20160816; b=ny3tpzNsBTVLONTzvBDXRwC/jjBAqS+wQWvUKiMjuC3mbLSMT68HTk/yxGalLt9sOm ka+7yciNQTxciWDbG+HnYdYupENV6pp8aqpV+2dwmFjQpqOdEury/dVxlq4Qroitti52 TVT4CtxYW9tSK+4si7W/hRNXaC3UoqxqJQC6+JqmwtuFvnor8+J2Hb7mWjMvQ5uau3Y4 QHaejLN6enZujABgkSqY7o+PBEAVvxPjZHRK8sYj48F7RwtFsaeXnGzvdo9XyyEMz/sG FnYwYkSwCTRbyaA8pRJymrNB7MCmvLXus5ErBY2Ub8MW7p/Ua6w5a5nd5/BMXbLJ71/G tdIA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=Zva8gT55IALq82V9YRVJAnVfhuhJYt5YJF4Qc5Cxi6Y=; fh=NVuooZqxmifYw0ZqRPqp7p4Ozl1xSMOtW5PLFBWb2DQ=; b=yuwcGz2XpgoBNcq36OTmbc/OLBvwN/qeHG/EU5rb3asMwIA5AX/J8PAak0p0zIFQNO /DHXyFgMR/Cwihs3J9qdpwiINb7SOY65MmR0LghxemTkFNlxA/+ZjcWAW09eHfze+jzn 7lAtGIlDrg2vIJdpsnRqbXCKzknCYq8A23je8fPSduDC4Wj7kzK4VWfCsg1X67iiNhHM uczwgs3i8a/lRWVICpBFVKWi0epN7xrUT6D2AJNEjDf+V/WAZp/gVauXlGoicdjPGYj3 5G6W3rLOb95i8XN5g7dOHN4qo4KyxsR7Q2IeV8ypFXwdgBB+LxGHC20vZvGuVIpnzFbQ cJbA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@baylibre-com.20230601.gappssmtp.com header.s=20230601 header.b="GHvNY/NQ"; arc=pass (i=1 spf=pass spfdomain=baylibre.com dkim=pass dkdomain=baylibre-com.20230601.gappssmtp.com); spf=pass (google.com: domain of linux-kernel+bounces-172028-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-172028-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id h27-20020a056102209b00b0047ef4888a09si2187905vsr.120.2024.05.07.12.02.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 May 2024 12:02:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-172028-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20230601.gappssmtp.com header.s=20230601 header.b="GHvNY/NQ"; arc=pass (i=1 spf=pass spfdomain=baylibre.com dkim=pass dkdomain=baylibre-com.20230601.gappssmtp.com); spf=pass (google.com: domain of linux-kernel+bounces-172028-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-172028-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 388C41C21CEE for ; Tue, 7 May 2024 19:02:51 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9A48E16E885; Tue, 7 May 2024 19:02:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="GHvNY/NQ" Received: from mail-oi1-f180.google.com (mail-oi1-f180.google.com [209.85.167.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 858C316D4F1 for ; Tue, 7 May 2024 19:02:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.180 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715108542; cv=none; b=snIa+M8WzMjSq7r5QyYQLFbpfzSuSZvtyGzVOCi8NOOqoXNowXa2j/TM9ZjtKdnRB/Txzdp0krRe9eKcu4nl/zOtID81SIxbhLNkZHIiriNVEuytUBMb+jkos7cPAb3T7VKyTemO5t54AV3h+m8CXv5kWXXeMFxJYWvq5sYxrP8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715108542; c=relaxed/simple; bh=Fn1xbpXsu4PAcmCL4wCw7+fLXWr43hwXXVU0yqQAbdw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RkuYMAhzTeg3MRG/2yf8S8GniA7HYG40SA9KCy7HqBFGvSTedHqzEkw+n/NtHRGKwpeMUg9WfzUXb2Wd0RkFm16ADZkySeiRrXnRS7kcr/jitzo4gPXfOWItHP5PqrgYSbipxftGrPMjfybpl2DSHMkj49xugGSazW6xuec4Pfk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=GHvNY/NQ; arc=none smtp.client-ip=209.85.167.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Received: by mail-oi1-f180.google.com with SMTP id 5614622812f47-3c86f066256so1990689b6e.2 for ; Tue, 07 May 2024 12:02:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715108539; x=1715713339; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Zva8gT55IALq82V9YRVJAnVfhuhJYt5YJF4Qc5Cxi6Y=; b=GHvNY/NQZo+CQQgda26XuIvNNy6w6ux4LR1BizIemG/ioiNlpQUMAAngs6ljWPgmIg oRrWbsOAB6SPA2kQJvoMIV1lTEvzd7zOjYEhYY65IjmnvrPtxAA7KgZNuTkS5+mvTQPd QuRMOVOJlXjMYm5bsjGkYgzqoeT3veGT2QrM++SBFUqzwJE8IbvF8jZCHRV/qud+7hbw ssZ9zgOlOk+7FFItAFygJ7/axZ3R4U4MnY1hDIg1LYsvUU620s0Xu7KPs9xB7JR2JvhQ lpb/AOYvxghbScH0MBNS8NGqNESZ2Ju7shsqccLNknyMITH3TSpzQoICpsF4nOlb5XTe 6YBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715108539; x=1715713339; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Zva8gT55IALq82V9YRVJAnVfhuhJYt5YJF4Qc5Cxi6Y=; b=LZBWBth6olualg4LaJQBlNp3LdqisIZGnkkEJI3Rt7xX0XzlOk/asZzp1xopT71qrb q1pI0rmLkuVvRGtcN9lBRqKDxoNQMoYv7LcrBJB5vwzmNWpFfsT6DPy80OY0/xNaC0Ya KnncXVVAsJdkpQxEmcPtupb/xwE5F8mn7WYWnd2sNdZy6f45simGEAoN1np8VZvuVluc Ozi+Fp0N9rQlct5eVZ1NeV2j7FcmRqvJx0LaWWtUd+LJbnlGJFcSKd1/Onia8e9Uqcnw ukSjq2wMQoJMWMpxPBHCBghYlUpb7SFC5b0I12AjEcUu4lA06BjPGg7cRkFX6zX88xQx Kzgw== X-Forwarded-Encrypted: i=1; AJvYcCXz/HXjQFt9JkgI6UcrsO97c8VYFhrcXKrEZKt9E/sLUUCva91XCjJgG07OBKuIcieVpFUA6j7hAZ+F0O4OOQwXCq8nAH00wiAOhsyl X-Gm-Message-State: AOJu0Yw6Cper2Ns9AfHVIr8kc/yjFb/kHA2kbruLpN/hhyAVYjAM/mph v/6x5IzzJzfyNcEmoLaJy+P/7H7dDU464HpUsNEhqRHOBjJIve69Yp1HwM3eDE8= X-Received: by 2002:aca:1e06:0:b0:3c5:f4b3:e0e3 with SMTP id 5614622812f47-3c985305afdmr446220b6e.41.1715108539681; Tue, 07 May 2024 12:02:19 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id j14-20020a54480e000000b003c96bbe0e79sm909652oij.13.2024.05.07.12.02.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 May 2024 12:02:19 -0700 (PDT) From: David Lechner To: Jonathan Cameron Cc: David Lechner , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Julien Stephan , Esteban Blanc , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RFC 3/4] iio: add support for multiple scan types per channel Date: Tue, 7 May 2024 14:02:07 -0500 Message-ID: <20240507-iio-add-support-for-multiple-scan-types-v1-3-95ac33ee51e9@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240507-iio-add-support-for-multiple-scan-types-v1-0-95ac33ee51e9@baylibre.com> References: <20240507-iio-add-support-for-multiple-scan-types-v1-0-95ac33ee51e9@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.12.4 Content-Transfer-Encoding: 8bit This adds new fields to the iio_channel structure to support multiple scan types per channel. This is useful for devices that support multiple resolution modes or other modes that require different data formats of the raw data. To make use of this, drivers can still use the old scan_type field for the "default" scan type and use the new scan_type_ext field for any additional scan types. And they must implement the new callback get_current_scan_type() to return the current scan type based on the current state of the device. The buffer code is the only code in the IIO core code that is using the scan_type field. This patch updates the buffer code to use the new iio_channel_validate_scan_type() function to ensure it is returning the correct scan type for the current state of the device when reading the sysfs attributes. The buffer validation code is also update to validate any additional scan types that are set in the scan_type_ext field. Part of that code is refactored to a new function to avoid duplication. Signed-off-by: David Lechner --- drivers/iio/industrialio-buffer.c | 43 +++++++++++++++++++++++++++++---------- include/linux/iio/iio.h | 33 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 08103a9e77f7..ef27ce71ec25 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -365,8 +365,10 @@ static ssize_t iio_show_fixed_type(struct device *dev, struct device_attribute *attr, char *buf) { + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - const struct iio_scan_type *scan_type = &this_attr->c->scan_type; + const struct iio_scan_type *scan_type = + iio_get_current_scan_type(indio_dev, this_attr->c); u8 type = scan_type->endianness; if (type == IIO_CPU) { @@ -699,7 +701,7 @@ static unsigned int iio_storage_bytes_for_si(struct iio_dev *indio_dev, unsigned int bytes; ch = iio_find_channel_from_si(indio_dev, scan_index); - scan_type = &ch->scan_type; + scan_type = iio_get_current_scan_type(indio_dev, ch); bytes = scan_type->storagebits / 8; if (scan_type->repeat > 1) @@ -1597,6 +1599,22 @@ static long iio_device_buffer_ioctl(struct iio_dev *indio_dev, struct file *filp } } +static int iio_channel_validate_scan_type(struct device *dev, int ch, + const struct iio_scan_type *scan_type) +{ + /* Verify that sample bits fit into storage */ + if (scan_type->storagebits < scan_type->realbits + scan_type->shift) { + dev_err(dev, + "Channel %d storagebits (%d) < shifted realbits (%d + %d)\n", + ch, scan_type->storagebits, + scan_type->realbits, + scan_type->shift); + return -EINVAL; + } + + return 0; +} + static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, struct iio_dev *indio_dev, int index) @@ -1622,22 +1640,25 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, /* new magic */ for (i = 0; i < indio_dev->num_channels; i++) { const struct iio_scan_type *scan_type; + int j; if (channels[i].scan_index < 0) continue; scan_type = &channels[i].scan_type; - /* Verify that sample bits fit into storage */ - if (scan_type->storagebits < - scan_type->realbits + scan_type->shift) { - dev_err(&indio_dev->dev, - "Channel %d storagebits (%d) < shifted realbits (%d + %d)\n", - i, scan_type->storagebits, - scan_type->realbits, - scan_type->shift); - ret = -EINVAL; + ret = iio_channel_validate_scan_type(&indio_dev->dev, + i, scan_type); + if (ret) goto error_cleanup_dynamic; + + for (j = 0; j < channels[i].num_ext_scan_type; j++) { + scan_type = &channels[i].ext_scan_type[j]; + + ret = iio_channel_validate_scan_type( + &indio_dev->dev, i, scan_type); + if (ret) + goto error_cleanup_dynamic; } ret = iio_buffer_add_channel_sysfs(indio_dev, buffer, diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 19de573a944a..66f0b4c68f53 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -205,6 +205,9 @@ struct iio_scan_type { * @scan_index: Monotonic index to give ordering in scans when read * from a buffer. * @scan_type: struct describing the scan type + * @ext_scan_type: Used in rare cases where there is more than one scan + * format for a channel. When this is used, omit scan_type. + * @num_ext_scan_type: Number of elements in ext_scan_type. * @info_mask_separate: What information is to be exported that is specific to * this channel. * @info_mask_separate_available: What availability information is to be @@ -256,6 +259,8 @@ struct iio_chan_spec { unsigned long address; int scan_index; struct iio_scan_type scan_type; + const struct iio_scan_type *ext_scan_type; + unsigned int num_ext_scan_type; long info_mask_separate; long info_mask_separate_available; long info_mask_shared_by_type; @@ -435,6 +440,9 @@ struct iio_trigger; /* forward declaration */ * for better event identification. * @validate_trigger: function to validate the trigger when the * current trigger gets changed. + * @get_current_scan_type: must be implemented by drivers that use ext_scan_type + * in the channel spec to return the currently active scan + * type based on the current state of the device. * @update_scan_mode: function to configure device and scan buffer when * channels have changed * @debugfs_reg_access: function to read or write register value of device @@ -519,6 +527,9 @@ struct iio_info { int (*validate_trigger)(struct iio_dev *indio_dev, struct iio_trigger *trig); + const struct iio_scan_type *(*get_current_scan_type)( + const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan); int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask); int (*debugfs_reg_access)(struct iio_dev *indio_dev, @@ -804,6 +815,28 @@ static inline bool iio_read_acpi_mount_matrix(struct device *dev, } #endif +/** + * iio_get_current_scan_type - Get the current scan type for a channel + * @indio_dev: the IIO device to get the scan type for + * @chan: the channel to get the scan type for + * + * Most devices only have one scan type per channel and can just access it + * directly without calling this function. Core IIO code and drivers that + * implement ext_scan_type in the channel spec should use this function to + * get the current scan type for a channel. + * + * Returns: the current scan type for the channel + */ +static inline const struct iio_scan_type *iio_get_current_scan_type( + const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + if (indio_dev->info->get_current_scan_type) + return indio_dev->info->get_current_scan_type(indio_dev, chan); + + return &chan->scan_type; +} + ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals); int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer, -- 2.43.2