From patchwork Fri Apr 26 15:42:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuno Sa via B4 Relay X-Patchwork-Id: 13645024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D4E3514AD30; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146149; cv=none; b=VCQISMed5CMYpw+e+q4l/vl43XO+s8abufzRt/VoUN+m0Tu9enk3jkqpPZnxcBBVeAS0R+Stpr7IsfeNYo51JmYdIN28wS8eldi6BEjFeLp/rSYwM/5tqUuAK9o5jdAY1ATpZSMcgg736W9RTBxJWmW1Om5tq2nf8XDjUs4wmDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146149; c=relaxed/simple; bh=JiNjdPNxj4XphqoUbNiF6vlkEV4mojbalqzcwjY4iMc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M8xLEHfwj95nbcG2i5OtLkY7mBL30IJ1H/BDvMNlieR8LJaDbHrCHYH+xfIEpfhStPnv64a3FkAC6vP2dopTVNrJCSdCcTC2GaxtbHr+prprCKpA8cLNGYWTulLDKpePPMRWhERtVvM47LUZy80c9YJRxfOpXQXpnHINDxff04c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jJdkianv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jJdkianv" Received: by smtp.kernel.org (Postfix) with ESMTPS id 71D81C116B1; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714146149; bh=JiNjdPNxj4XphqoUbNiF6vlkEV4mojbalqzcwjY4iMc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=jJdkianvnjqfciNIEOIGjGojAOgwFXiPIRgUwFg3Q0ZQtLr/nnAtl856TE7UJrSRg DmwH5WOk8clfXY4SuH/PP5ld9dwiswMOOoTMsEZLhxn3fORqMly5KGHi+21nsWgUyx R/QKcKXIGqLTlCDIx6Qerc1Qkb0+Ts6pzt6pEEZZDIs/PN5hCoaQBctzDDN2YsbaLZ LeUhAwtgMXJ4DNJjD+pMocqajd5+2V+8xUgNBXigzd3iX5VGm08bjdKmJeeK9c2Zhu 0Yq7PkU3pLNZWx4PBQ5DbLKTVYrlrA6w3lVhxzRjS2uKOKItkBibUmUTWsjBG0PyP7 t4KKQyocPmN4Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 695CEC25B4F; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) From: Nuno Sa via B4 Relay Date: Fri, 26 Apr 2024 17:42:10 +0200 Subject: [PATCH v2 1/7] iio: backend: change docs padding Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240426-ad9467-new-features-v2-1-6361fc3ba1cc@analog.com> References: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> In-Reply-To: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Jonathan Cameron , Alexandru Ardelean , Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1714146147; l=9346; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=dqEqcsoqR5bEdYlGMpM4Yqp9dr2hRNwIiyyj5IVyzo8=; b=GT7p0JASWbMoeTWS8vM2J8oK9gC/qyWrnGJ0p4MIqGetiy/m7msLGJoHdHGZ6ZwI5cdEMS8hh FM7xjmDYkH1CwXxEj/qP4CzM3yLZ7OXERM2ZO0RumAP/D8YCYr1hDDe X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: Nuno Sa Reply-To: nuno.sa@analog.com From: Nuno Sa Using tabs and maintaining the start of the docs aligned is a pain and may lead to lot's of unrelated changes when adding new members. Hence, let#s change things now and just have a simple space after the member name. Signed-off-by: Nuno Sa --- drivers/iio/industrialio-backend.c | 76 +++++++++++++++++++------------------- include/linux/iio/backend.h | 38 +++++++++---------- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c index f08ed6d70ae5..c27243e88462 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -115,8 +115,8 @@ static DEFINE_MUTEX(iio_back_lock); /** * iio_backend_chan_enable - Enable a backend channel - * @back: Backend device - * @chan: Channel number + * @back: Backend device + * @chan: Channel number * * RETURNS: * 0 on success, negative error number on failure. @@ -129,8 +129,8 @@ EXPORT_SYMBOL_NS_GPL(iio_backend_chan_enable, IIO_BACKEND); /** * iio_backend_chan_disable - Disable a backend channel - * @back: Backend device - * @chan: Channel number + * @back: Backend device + * @chan: Channel number * * RETURNS: * 0 on success, negative error number on failure. @@ -148,8 +148,8 @@ static void __iio_backend_disable(void *back) /** * devm_iio_backend_enable - Device managed backend enable - * @dev: Consumer device for the backend - * @back: Backend device + * @dev: Consumer device for the backend + * @back: Backend device * * RETURNS: * 0 on success, negative error number on failure. @@ -168,9 +168,9 @@ EXPORT_SYMBOL_NS_GPL(devm_iio_backend_enable, IIO_BACKEND); /** * iio_backend_data_format_set - Configure the channel data format - * @back: Backend device - * @chan: Channel number - * @data: Data format + * @back: Backend device + * @chan: Channel number + * @data: Data format * * Properly configure a channel with respect to the expected data format. A * @struct iio_backend_data_fmt must be passed with the settings. @@ -190,9 +190,9 @@ EXPORT_SYMBOL_NS_GPL(iio_backend_data_format_set, IIO_BACKEND); /** * iio_backend_data_source_set - Select data source - * @back: Backend device - * @chan: Channel number - * @data: Data source + * @back: Backend device + * @chan: Channel number + * @data: Data source * * A given backend may have different sources to stream/sync data. This allows * to choose that source. @@ -212,9 +212,9 @@ EXPORT_SYMBOL_NS_GPL(iio_backend_data_source_set, IIO_BACKEND); /** * iio_backend_set_sampling_freq - Set channel sampling rate - * @back: Backend device - * @chan: Channel number - * @sample_rate_hz: Sample rate + * @back: Backend device + * @chan: Channel number + * @sample_rate_hz: Sample rate * * RETURNS: * 0 on success, negative error number on failure. @@ -235,9 +235,9 @@ static void iio_backend_free_buffer(void *arg) /** * devm_iio_backend_request_buffer - Device managed buffer request - * @dev: Consumer device for the backend - * @back: Backend device - * @indio_dev: IIO device + * @dev: Consumer device for the backend + * @back: Backend device + * @indio_dev: IIO device * * Request an IIO buffer from the backend. The type of the buffer (typically * INDIO_BUFFER_HARDWARE) is up to the backend to decide. This is because, @@ -300,10 +300,10 @@ static struct iio_backend *iio_backend_from_indio_dev_parent(const struct device /** * iio_backend_ext_info_get - IIO ext_info read callback - * @indio_dev: IIO device - * @private: Data private to the driver - * @chan: IIO channel - * @buf: Buffer where to place the attribute data + * @indio_dev: IIO device + * @private: Data private to the driver + * @chan: IIO channel + * @buf: Buffer where to place the attribute data * * This helper is intended to be used by backends that extend an IIO channel * (through iio_backend_extend_chan_spec()) with extended info. In that case, @@ -335,11 +335,11 @@ EXPORT_SYMBOL_NS_GPL(iio_backend_ext_info_get, IIO_BACKEND); /** * iio_backend_ext_info_set - IIO ext_info write callback - * @indio_dev: IIO device - * @private: Data private to the driver - * @chan: IIO channel - * @buf: Buffer holding the sysfs attribute - * @len: Buffer length + * @indio_dev: IIO device + * @private: Data private to the driver + * @chan: IIO channel + * @buf: Buffer holding the sysfs attribute + * @len: Buffer length * * This helper is intended to be used by backends that extend an IIO channel * (trough iio_backend_extend_chan_spec()) with extended info. In that case, @@ -365,9 +365,9 @@ EXPORT_SYMBOL_NS_GPL(iio_backend_ext_info_set, IIO_BACKEND); /** * iio_backend_extend_chan_spec - Extend an IIO channel - * @indio_dev: IIO device - * @back: Backend device - * @chan: IIO channel + * @indio_dev: IIO device + * @back: Backend device + * @chan: IIO channel * * Some backends may have their own functionalities and hence capable of * extending a frontend's channel. @@ -449,8 +449,8 @@ static int __devm_iio_backend_get(struct device *dev, struct iio_backend *back) /** * devm_iio_backend_get - Device managed backend device get - * @dev: Consumer device for the backend - * @name: Backend name + * @dev: Consumer device for the backend + * @name: Backend name * * Get's the backend associated with @dev. * @@ -501,8 +501,8 @@ EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, IIO_BACKEND); /** * __devm_iio_backend_get_from_fwnode_lookup - Device managed fwnode backend device get - * @dev: Consumer device for the backend - * @fwnode: Firmware node of the backend device + * @dev: Consumer device for the backend + * @fwnode: Firmware node of the backend device * * Search the backend list for a device matching @fwnode. * This API should not be used and it's only present for preventing the first @@ -536,7 +536,7 @@ EXPORT_SYMBOL_NS_GPL(__devm_iio_backend_get_from_fwnode_lookup, IIO_BACKEND); /** * iio_backend_get_priv - Get driver private data - * @back: Backend device + * @back: Backend device */ void *iio_backend_get_priv(const struct iio_backend *back) { @@ -554,9 +554,9 @@ static void iio_backend_unregister(void *arg) /** * devm_iio_backend_register - Device managed backend device register - * @dev: Backend device being registered - * @ops: Backend ops - * @priv: Device private data + * @dev: Backend device being registered + * @ops: Backend ops + * @priv: Device private data * * @ops is mandatory. Not providing it results in -EINVAL. * diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h index 9d144631134d..e3e62f65db14 100644 --- a/include/linux/iio/backend.h +++ b/include/linux/iio/backend.h @@ -24,9 +24,9 @@ enum iio_backend_data_source { /** * IIO_BACKEND_EX_INFO - Helper for an IIO extended channel attribute - * @_name: Attribute name - * @_shared: Whether the attribute is shared between all channels - * @_what: Data private to the driver + * @_name: Attribute name + * @_shared: Whether the attribute is shared between all channels + * @_what: Data private to the driver */ #define IIO_BACKEND_EX_INFO(_name, _shared, _what) { \ .name = (_name), \ @@ -38,10 +38,10 @@ enum iio_backend_data_source { /** * struct iio_backend_data_fmt - Backend data format - * @type: Data type. - * @sign_extend: Bool to tell if the data is sign extended. - * @enable: Enable/Disable the data format module. If disabled, - * not formatting will happen. + * @type: Data type. + * @sign_extend: Bool to tell if the data is sign extended. + * @enable: Enable/Disable the data format module. If disabled, + * not formatting will happen. */ struct iio_backend_data_fmt { enum iio_backend_data_type type; @@ -51,18 +51,18 @@ struct iio_backend_data_fmt { /** * struct iio_backend_ops - operations structure for an iio_backend - * @enable: Enable backend. - * @disable: Disable backend. - * @chan_enable: Enable one channel. - * @chan_disable: Disable one channel. - * @data_format_set: Configure the data format for a specific channel. - * @data_source_set: Configure the data source for a specific channel. - * @set_sample_rate: Configure the sampling rate for a specific channel. - * @request_buffer: Request an IIO buffer. - * @free_buffer: Free an IIO buffer. - * @extend_chan_spec: Extend an IIO channel. - * @ext_info_set: Extended info setter. - * @ext_info_get: Extended info getter. + * @enable: Enable backend. + * @disable: Disable backend. + * @chan_enable: Enable one channel. + * @chan_disable: Disable one channel. + * @data_format_set: Configure the data format for a specific channel. + * @data_source_set: Configure the data source for a specific channel. + * @set_sample_rate: Configure the sampling rate for a specific channel. + * @request_buffer: Request an IIO buffer. + * @free_buffer: Free an IIO buffer. + * @extend_chan_spec: Extend an IIO channel. + * @ext_info_set: Extended info setter. + * @ext_info_get: Extended info getter. **/ struct iio_backend_ops { int (*enable)(struct iio_backend *back); From patchwork Fri Apr 26 15:42:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuno Sa via B4 Relay X-Patchwork-Id: 13645023 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D4DAD14A4D2; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146149; cv=none; b=THM8ixQlVeSG01LsmKFW+P86rt93/ZxCdHp/w0hfea9d3OYVqs3R9lDsYbJbvnRElfDrqFImcd4/UI+H41HkuebFqtctDWXYR7oJJWaVGi71TP5KoxRJKHJvlsreKl60e2zMQ92dGmFB/qcg9AGXvD/0vyh4pjQyow5+pvuz/p8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146149; c=relaxed/simple; bh=Z3gkAYW2PvRjX044v4uYLZONVRdduJ/Nc9oceDNoIHY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=trA8QbZH7lS52VRACBgsnzP5yPcskK8VcYJeN7DWr0Ho2bY7IPxIGl3j4jBtrdbOk80MZxkIdNHtmdN2jLn7Jc1Z7XTcHiuTSrP77FX1kSuWSL2Qchn/uRvGzx7C6LYRNsZ4Z4hUalG+77mY1tEP4pEql4yPI6CAppaJYbyOoNk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KxoaaDve; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KxoaaDve" Received: by smtp.kernel.org (Postfix) with ESMTPS id 820CFC2BD10; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714146149; bh=Z3gkAYW2PvRjX044v4uYLZONVRdduJ/Nc9oceDNoIHY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=KxoaaDveIkTqHVaog6WghPlZwOkl+zhhZxHikpDcedLWE5Z3LxUFc8MnqoDWhLTwt 1UMv2G7feSjpHHToKCf5s3e6vzXiJOTbGnumx7T6gkdpu8YCDc4tVcWC2K3zmBSshm UT099+boUwBpjQUXt9EowY1B7UHm9oKTcCrUufH9yoXPxVW7ycZ6tb9nq+fc5w6ijU fMSzpwR6YjMSmEiO3rdhqiFa2JNohqz6AKcZgUTVDzMTHKyE1wUAX5CcujkBnMRMkt FSFMdK3k1+pR+d3dv0d1ypjtLt+Qs/kgdKv4Mt9wa13xQK1Vw4H3+jvvui0Yo6+DaD IltTDuOWvPzYg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A296C19F4F; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) From: Nuno Sa via B4 Relay Date: Fri, 26 Apr 2024 17:42:11 +0200 Subject: [PATCH v2 2/7] iio: backend: add API for interface tuning Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240426-ad9467-new-features-v2-2-6361fc3ba1cc@analog.com> References: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> In-Reply-To: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Jonathan Cameron , Alexandru Ardelean , Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1714146147; l=7643; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=0GW9xMmjZX/fPa2quDrIgkmNJYy8YWt+hDOKn1LWW34=; b=+LcIXxjFLGc6l36uHZlZ2rJd5hGkaWOj2KOj8vmPD/H10yRFlWe1AcHwqFnIA50Y6b921l2YP qvl7l7yn/z9BXMrcnwMakqjGbf0emUOurJDetfiaerlmEwD/PHG12u/ X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: Nuno Sa Reply-To: nuno.sa@analog.com From: Nuno Sa This is in preparation for supporting interface tuning in one for the devices using the axi-adc backend. The new added interfaces are all needed for that calibration: * iio_backend_test_pattern_set(); * iio_backend_chan_status(); * iio_backend_iodelay_set(); * iio_backend_data_sample_trigger(). Interface tuning is the process of going through a set of known points (typically by the frontend), change some clk or data delays (or both) and send/receive some known signal (so called test patterns in this change). The receiving end (either frontend or the backend) is responsible for validating the signal and see if it's good or not. The goal for all of this is to come up with ideal delays at the data interface level so we can have a proper, more reliable data transfer. Also note that for some devices we can change the sampling rate (which typically means changing some reference clock) and that can affect the data interface. In that case, it's import to run the tuning algorithm again as the values we had before may no longer be the best (or even valid) ones. Signed-off-by: Nuno Sa --- drivers/iio/industrialio-backend.c | 86 ++++++++++++++++++++++++++++++++++++++ include/linux/iio/backend.h | 36 ++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c index c27243e88462..929aff4040ed 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -226,6 +226,92 @@ int iio_backend_set_sampling_freq(struct iio_backend *back, unsigned int chan, } EXPORT_SYMBOL_NS_GPL(iio_backend_set_sampling_freq, IIO_BACKEND); +/** + * iio_backend_test_pattern_set - Configure a test pattern + * @back: Backend device + * @chan: Channel number + * @pattern: Test pattern + * + * Configure a test pattern on the backend. This is typically used for + * calibrating the timings on the data digital interface. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_test_pattern_set(struct iio_backend *back, + unsigned int chan, + enum iio_backend_test_pattern pattern) +{ + if (pattern >= IIO_BACKEND_TEST_PATTERN_MAX) + return -EINVAL; + + return iio_backend_op_call(back, test_pattern_set, chan, pattern); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_test_pattern_set, IIO_BACKEND); + +/** + * iio_backend_chan_status - Get the channel status + * @back: Backend device + * @chan: Channel number + * @error: Error indication + * + * Get the current state of the backend channel. Typically used to check if + * there were any errors sending/receiving data. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_chan_status(struct iio_backend *back, unsigned int chan, + bool *error) +{ + return iio_backend_op_call(back, chan_status, chan, error); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_chan_status, IIO_BACKEND); + +/** + * iio_backend_iodelay_set - Set digital I/O delay + * @back: Backend device + * @lane: Lane number + * @taps: Number of taps + * + * Controls delays on sending/receiving data. One usecase for this is to + * calibrate the data digital interface so we get the best results when + * transferring data. Note that @taps has no unit since the actual delay per tap + * is very backend specific. Hence, frontend devices typically should go through + * an array of @taps (the size of that array should typically match the size of + * calibration points on the frontend device) and call this API. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_iodelay_set(struct iio_backend *back, unsigned int lane, + unsigned int taps) +{ + return iio_backend_op_call(back, iodelay_set, lane, taps); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_iodelay_set, IIO_BACKEND); + +/** + * iio_backend_data_sample_trigger - Control when to sample data + * @back: Backend device + * @trigger: Data trigger + * + * Mostly useful for input backends. Configures the backend for when to sample + * data (eg: rising vs falling edge). + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_data_sample_trigger(struct iio_backend *back, + enum iio_backend_sample_trigger trigger) +{ + if (trigger >= IIO_BACKEND_SAMPLE_TRIGGER_MAX) + return -EINVAL; + + return iio_backend_op_call(back, data_sample_trigger, trigger); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_data_sample_trigger, IIO_BACKEND); + static void iio_backend_free_buffer(void *arg) { struct iio_backend_buffer_pair *pair = arg; diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h index e3e62f65db14..8099759d7242 100644 --- a/include/linux/iio/backend.h +++ b/include/linux/iio/backend.h @@ -49,6 +49,20 @@ struct iio_backend_data_fmt { bool enable; }; +/* vendor specific from 32 */ +enum iio_backend_test_pattern { + IIO_BACKEND_NO_TEST_PATTERN, + /* modified prbs9 */ + IIO_BACKEND_ADI_PRBS_9A = 32, + IIO_BACKEND_TEST_PATTERN_MAX +}; + +enum iio_backend_sample_trigger { + IIO_BACKEND_SAMPLE_TRIGGER_EDGE_FALLING, + IIO_BACKEND_SAMPLE_TRIGGER_EDGE_RISING, + IIO_BACKEND_SAMPLE_TRIGGER_MAX +}; + /** * struct iio_backend_ops - operations structure for an iio_backend * @enable: Enable backend. @@ -58,6 +72,10 @@ struct iio_backend_data_fmt { * @data_format_set: Configure the data format for a specific channel. * @data_source_set: Configure the data source for a specific channel. * @set_sample_rate: Configure the sampling rate for a specific channel. + * @test_pattern_set: Configure a test pattern. + * @chan_status: Get the channel status. + * @iodelay_set: Set digital I/O delay. + * @data_sample_trigger: Control when to sample data. * @request_buffer: Request an IIO buffer. * @free_buffer: Free an IIO buffer. * @extend_chan_spec: Extend an IIO channel. @@ -75,6 +93,15 @@ struct iio_backend_ops { enum iio_backend_data_source data); int (*set_sample_rate)(struct iio_backend *back, unsigned int chan, u64 sample_rate_hz); + int (*test_pattern_set)(struct iio_backend *back, + unsigned int chan, + enum iio_backend_test_pattern pattern); + int (*chan_status)(struct iio_backend *back, unsigned int chan, + bool *error); + int (*iodelay_set)(struct iio_backend *back, unsigned int chan, + unsigned int taps); + int (*data_sample_trigger)(struct iio_backend *back, + enum iio_backend_sample_trigger trigger); struct iio_buffer *(*request_buffer)(struct iio_backend *back, struct iio_dev *indio_dev); void (*free_buffer)(struct iio_backend *back, @@ -97,6 +124,15 @@ int iio_backend_data_source_set(struct iio_backend *back, unsigned int chan, enum iio_backend_data_source data); int iio_backend_set_sampling_freq(struct iio_backend *back, unsigned int chan, u64 sample_rate_hz); +int iio_backend_test_pattern_set(struct iio_backend *back, + unsigned int chan, + enum iio_backend_test_pattern pattern); +int iio_backend_chan_status(struct iio_backend *back, unsigned int chan, + bool *error); +int iio_backend_iodelay_set(struct iio_backend *back, unsigned int lane, + unsigned int taps); +int iio_backend_data_sample_trigger(struct iio_backend *back, + enum iio_backend_sample_trigger trigger); int devm_iio_backend_request_buffer(struct device *dev, struct iio_backend *back, struct iio_dev *indio_dev); From patchwork Fri Apr 26 15:42:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuno Sa via B4 Relay X-Patchwork-Id: 13645025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3A2A14AD3D; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; cv=none; b=RhKaD8prc4xJinbapxPd7/A68BM7JCGK/+wOHKxNrWKGE0E7j7AdUpf4yhLwD0yzJ50t+jtnXJZeqnys5EVlke2ivYuidGPNRsAnoUmKPlA6CnAnJba02zDlGK3QtnJTGMJSPRvPKiDDkEDRNI4iXecN2fsRltyoC9fAcF8lMBE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; c=relaxed/simple; bh=4rO3Z460OWVFFUr9q1DYa57hPeqpXtQlX9nHpGrbGDo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=R7f2tMLr9QcCo2f08fXJASydgO+G7LO5gRKEsQy1VSO/TkvN0MGsEOB/6GvLM5qiWmQPWoV/75fv4+a0BrQt+Kgs133XAasz0OKkJyc6jH0X4603IcHyUo0Nkw2bYcWEVEhks1Qb0As2u6/JbV0CcSvSqc4+9MtOuNIseq3fUxE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jCPdsD5Z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jCPdsD5Z" Received: by smtp.kernel.org (Postfix) with ESMTPS id 92AF1C32783; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714146149; bh=4rO3Z460OWVFFUr9q1DYa57hPeqpXtQlX9nHpGrbGDo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=jCPdsD5ZHIrq1lsvdnJzvJJuk+RFsWVFWAuPmYaqNPGmgru6jmAGLPOt7d9xqcDiZ JyKf6o7QCnDOb8+JeCeCmemcoQQ95gW27udq8RT2NidsjkxO9n5K1Uav5pFRAsrf6q mu6HUpolVhekesgqYcI+kZtfUegMA2A6R9j/Txr0+hT0uGeqzS4PNksJpGZCzvXz98 rAHMkMu9Hd5A+XdTRqVGv+Oxg4z/AncVuaJVWaaP6vAe6TNCa9DABuXMvf0k8Vg2S/ MBla9RFxxbf2PCZsrNXHlAUFqTz9B+blzI8Wj5e7qKMv8JLtYQRqKCgBBwdWmRm46V 44ui319l6RJTA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89DB5C25B5C; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) From: Nuno Sa via B4 Relay Date: Fri, 26 Apr 2024 17:42:12 +0200 Subject: [PATCH v2 3/7] dt-bindings: adc: axi-adc: add clocks property Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240426-ad9467-new-features-v2-3-6361fc3ba1cc@analog.com> References: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> In-Reply-To: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Jonathan Cameron , Alexandru Ardelean , Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Krzysztof Kozlowski , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1714146147; l=1362; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=Kji5f67mZEzci00M6vCqK7nqcsD4CPN32lsTL2M54tY=; b=2PLktNW4hBVWhtlf7tXvDHJdFNDsnNv7SWATfWUTWw1p65eSQWZ3Ofj4EWJrA/MDiUSCeQvEh JHwKmwH/XC9DezBpZhQqTbVcd9PbIhzmNpLmhTmpfkTwPDIY/sp+QnH X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: Nuno Sa Reply-To: nuno.sa@analog.com From: Nuno Sa Add a required clock property as we can't access the device registers if the AXI bus clock is not properly enabled. Note this clock is a very fundamental one that is typically enabled pretty early during boot. Independently of that, we should really rely on it to be enabled. Reviewed-by: Krzysztof Kozlowski Fixes: 96553a44e96d ("dt-bindings: iio: adc: add bindings doc for AXI ADC driver") Signed-off-by: Nuno Sa --- Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml index 3d49d21ad33d..e1f450b80db2 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml @@ -28,6 +28,9 @@ properties: reg: maxItems: 1 + clocks: + maxItems: 1 + dmas: maxItems: 1 @@ -48,6 +51,7 @@ required: - compatible - dmas - reg + - clocks additionalProperties: false @@ -58,6 +62,7 @@ examples: reg = <0x44a00000 0x10000>; dmas = <&rx_dma 0>; dma-names = "rx"; + clocks = <&axi_clk>; #io-backend-cells = <0>; }; ... From patchwork Fri Apr 26 15:42:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuno Sa via B4 Relay X-Patchwork-Id: 13645027 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23CFD155A2A; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; cv=none; b=atJx/en9dnrXN8E8JEa0CvXoB4PDTbcSKcxir0TNedtz7iaoIAsoJdGpm92y8pTSCW48mrRgOmW8EVF0QWx2332ZtXDX4Rjicm7hZhzZQlRVUKF3YFbH3pfOr0fxTjoFIOgX66LaADr6MDi1qkG/MqeH89jZTvAkSsmoQiQpt/c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; c=relaxed/simple; bh=Sy/61I4jsVV/SaO4Tqs7G3FDOtNf3pkPBFQ4yg8YP5Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KEU6TS/r/ABNUEwUYsL4F7eEEOM2J5EQeVJvv+H6jFWuKCKIYF2PZgQ0AVeUTkAu1wwwTXoAF8P0rHK0S7Qc0jlq2ZbCFe/nq0OSCMgSMbyyz4a4fXzayf/1CHOeGH8RIIwCz4vtY2840masT9T/jdMkBaUdc/JTIphMZsNeiwU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LP/I1KwP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LP/I1KwP" Received: by smtp.kernel.org (Postfix) with ESMTPS id A9EDFC2BD11; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714146149; bh=Sy/61I4jsVV/SaO4Tqs7G3FDOtNf3pkPBFQ4yg8YP5Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=LP/I1KwPkPAg2w/ZkbqPYQnW8taQKuHJL9Wo0jo7VWljZAToGtayp+p+CM7gQ5g8F PBGkK2qbqSATN0b4G7VEXjDBVp+PstStdbkFW20ezDLReEjfMcCVlQiI34Z6pbR4qq qVEIfIta1bvC2e8VUXqOxciP3g55ly81ZnBw8nSjKBl9sM42kZ8LSldqz618axjvmX ZXOhXvakgtC5voJD1GaSQTRbYZ4qc6K5x5HbOM7LAMzm3ilcpQFcflD8n5QoOKdKVM Yc1COsrs56KE/9RqSfYpOFPrOPYPcX76WmBMjzo/Jj++p3BXakUV3c2MUot03g7eEI Drp6CsSG9iLcA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E5BEC04FFE; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) From: Nuno Sa via B4 Relay Date: Fri, 26 Apr 2024 17:42:13 +0200 Subject: [PATCH v2 4/7] iio: adc: axi-adc: make sure AXI clock is enabled Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240426-ad9467-new-features-v2-4-6361fc3ba1cc@analog.com> References: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> In-Reply-To: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Jonathan Cameron , Alexandru Ardelean , Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1714146147; l=1318; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=wD4frVePbFQZ5GZZY+496L8YqjIUAosy1WOB2P0XRHA=; b=+ecaEiuo3EuEcqcy+s8TO3a9lqzk+HTfyD+VE2WgEpF5kn3+ev0LlrZ5+c2HjWucKesGdp7pt amki9w4q6+OCzkuH13f/dWxH3eTP+NRbl7Zf2YWZ9xiYDM9wwP1Vzc1 X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: Nuno Sa Reply-To: nuno.sa@analog.com From: Nuno Sa We can only access the IP core registers if the bus clock is enabled. As such we need to get and enable it and not rely on anyone else to do it. Note this clock is a very fundamental one that is typically enabled pretty early during boot. Independently of that, we should really rely on it to be enabled. Fixes: ef04070692a2 ("iio: adc: adi-axi-adc: add support for AXI ADC IP core") Signed-off-by: Nuno Sa --- drivers/iio/adc/adi-axi-adc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index a543b91124b0..e3b215882941 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -175,6 +175,7 @@ static int adi_axi_adc_probe(struct platform_device *pdev) struct adi_axi_adc_state *st; void __iomem *base; unsigned int ver; + struct clk *clk; int ret; st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); @@ -195,6 +196,10 @@ static int adi_axi_adc_probe(struct platform_device *pdev) if (!expected_ver) return -ENODEV; + clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + /* * Force disable the core. Up to the frontend to enable us. And we can * still read/write registers... From patchwork Fri Apr 26 15:42:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuno Sa via B4 Relay X-Patchwork-Id: 13645026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 11EB7149C64; Fri, 26 Apr 2024 15:42:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; cv=none; b=ZtKaya4Wpa+BVGxltgBLXDDJkZYfi3YkLjiTYqM5Lc61/cWVDJsvM+vbgpOqB6h2Lm19I1nxrq54rnhELnUMnykTaJiN6M44l/Gt5WQfuHTei3NGbdYhLkk6A7L0ocpoOpZ4QYNszLjzt6SIb5HFNyFVcFzDREkkjfcawvMOPxg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; c=relaxed/simple; bh=/JWoxez/qXAby0DAwjlA0EFETZk3KYQlxkx4cPrQ1b0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VOOICB7b/d9lD/BD7W7G2wvldZzYQeyo07s9CSF+lKMmtrTRGMmmz1fusT9XnX5KLKszF20fbxopuxzQ4oih3ELsbSfz7BUVcwYK7CQZQbwNaaXfyoq4xHEC6CVRfIdFFB6RCX8x0zjMY3eCT70vh+uHRxsLDbmMpGiXDvbknU4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CfWHQNiQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CfWHQNiQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id BE5EEC4AF12; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714146149; bh=/JWoxez/qXAby0DAwjlA0EFETZk3KYQlxkx4cPrQ1b0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=CfWHQNiQl5p7lzmyTWT4O/9PttymFjSmzvvfFmMa3c4z+im2jaSQc+BW8gf5oeJP6 j8sKk20RCvaxqCfYVyHqu+F3h3vPj2/KZ0oc6NA55++hO3wezZuU1pWB3KG+FjD+Ju LYSfEtumKCBoyBRnf9heFGFtTELZvJrsnGky6PPbR2dXbIhc8DOYH/aEYyqWkmhL+T rd6zRKSoi1P7NRWOvFZOeYIWE6w106uCztROmEUzQJSBKGjfrvrC6GI6Eqc/3ZyPEg XNApG7qkFzTvg672ihXplBSqzRYO4tB2qfknTJ1X7Q+vwRL95k+QNTVp6/JfDJv0x2 evVTYyyM+2bJg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B51A4C25B4F; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) From: Nuno Sa via B4 Relay Date: Fri, 26 Apr 2024 17:42:14 +0200 Subject: [PATCH v2 5/7] iio: adc: adi-axi-adc: remove regmap max register Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240426-ad9467-new-features-v2-5-6361fc3ba1cc@analog.com> References: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> In-Reply-To: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Jonathan Cameron , Alexandru Ardelean , Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1714146147; l=813; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=xe0te39dghx3xVo9c0/ZGbv9/Txz1Y4hTt1+Fm8A5ns=; b=o5c0uXvGTGdhYwqp3weFdoAh7f9XAy9ZmUqGbq55yd79pfk2fzAhzvHRPkGwXUMDE3D9be53L CBRg8gZkR2TDGM3i+nD1zs5TfaTe9YN874soCidkODy6JyGtff3ONNt X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: Nuno Sa Reply-To: nuno.sa@analog.com From: Nuno Sa In one of the following patches, we'll have some new functionality that requires reads/writes on registers bigger than 0x8000. Hence, as this is an highly flexible core, don't bother in setting 'max_register' and remove it from regmap_config. Signed-off-by: Nuno Sa --- drivers/iio/adc/adi-axi-adc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index e3b215882941..b312369b7366 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -156,7 +156,6 @@ static const struct regmap_config axi_adc_regmap_config = { .val_bits = 32, .reg_bits = 32, .reg_stride = 4, - .max_register = 0x0800, }; static const struct iio_backend_ops adi_axi_adc_generic = { From patchwork Fri Apr 26 15:42:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuno Sa via B4 Relay X-Patchwork-Id: 13645028 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36712156644; Fri, 26 Apr 2024 15:42:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; cv=none; b=f54OtJ8O29xqI+9QWFRLg/k4r7hkWYCYDPZRN5DxkTBzX/PWo/Jd267DyszKF8IKyAE3R52u1wrBdm6ARC5N1jy7AHfu/sBiifmcXEky4yN8vmelCtxOtJhE6tPxLbLbBWiLtfvtmG6PziZWEFfrJwxNalbseKWwb5Veu/uhlGY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; c=relaxed/simple; bh=rO6uBBdP0jeHvGDQinxUKY6ung2do8FCGlzWFSbNAWg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C9SZAZi5trUf6vcGM34fN4Mz2Il3jo7WAMCrshRCuD7fy5j1EEtEt3nrweX7jywBbnWm4a320Pz2F/Va/wq68WC2YRS93tmB1aWCLiO4BGrYmLYkYUWrUK1FR+dyYY1IuNR/SDZmW6jVnswoXFrpqARoexhvLosH6Kf4VhXifOY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mZogAQAX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mZogAQAX" Received: by smtp.kernel.org (Postfix) with ESMTPS id CCEAAC4AF16; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714146149; bh=rO6uBBdP0jeHvGDQinxUKY6ung2do8FCGlzWFSbNAWg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=mZogAQAXt6qpLt3VDLgfI/Y4fe6ALeCtlRnpkPKE1mX1PBrf5lqJOxdZu5KWqiCz+ gubRxWBGUDHFo/uC73DOBBCwl1h9BC/wQrGXW62XGN41RsZvoRQEDWMurUolB4RpYS u2xeW6mzy/iDWeR9/IECoBy8C9s/gR39b20OtpQCWKoEzJcSgKgT73o/PsFwpnqTNH t4yasDOYSlaMX5K6jDonJfh658Tme7OWHmo7RSzzodVNgbBdVBfGUY/083IW9avnuW TaXQ77FKjOzwxgTC7WccwDO6DlEYSKBv6iaFNqy4QHWM4o8RsYaFUgjFIdzxG5dTNQ Wm7yqJgghnR+A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4730C19F4F; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) From: Nuno Sa via B4 Relay Date: Fri, 26 Apr 2024 17:42:15 +0200 Subject: [PATCH v2 6/7] iio: adc: adi-axi-adc: support digital interface calibration Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240426-ad9467-new-features-v2-6-6361fc3ba1cc@analog.com> References: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> In-Reply-To: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Jonathan Cameron , Alexandru Ardelean , Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1714146147; l=5516; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=aB00ra411xRhssII5y4oXBZqdmEU9tdpGRfh6hUL/eE=; b=m2gp7LN+nCx2Jne7+GiKmRJg3THZW4RMHTNB0PeuU2wzBHwU4X1NO7J76uQN96marJcUYAErZ jAAm/oiGCBtBVZszQMb14XBYgBzuWZg2yqhuRc4ajx1PMy6i3DTHTDX X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: Nuno Sa Reply-To: nuno.sa@analog.com From: Nuno Sa Implement the new IIO backend APIs for calibrating the data digital interfaces. While at it, removed the tabs in 'struct adi_axi_adc_state' and used spaces for the members. Signed-off-by: Nuno Sa --- drivers/iio/adc/adi-axi-adc.c | 121 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index b312369b7366..3a556e72f458 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -7,11 +7,13 @@ */ #include +#include #include #include #include #include #include +#include #include #include #include @@ -37,6 +39,9 @@ #define ADI_AXI_REG_RSTN_MMCM_RSTN BIT(1) #define ADI_AXI_REG_RSTN_RSTN BIT(0) +#define ADI_AXI_ADC_REG_CTRL 0x0044 +#define ADI_AXI_ADC_CTRL_DDR_EDGESEL_MASK BIT(1) + /* ADC Channel controls */ #define ADI_AXI_REG_CHAN_CTRL(c) (0x0400 + (c) * 0x40) @@ -51,14 +56,28 @@ #define ADI_AXI_REG_CHAN_CTRL_PN_TYPE_OWR BIT(1) #define ADI_AXI_REG_CHAN_CTRL_ENABLE BIT(0) +#define ADI_AXI_ADC_REG_CHAN_STATUS(c) (0x0404 + (c) * 0x40) +#define ADI_AXI_ADC_CHAN_STAT_PN_MASK GENMASK(2, 1) + +#define ADI_AXI_ADC_REG_CHAN_CTRL_3(c) (0x0418 + (c) * 0x40) +#define ADI_AXI_ADC_CHAN_PN_SEL_MASK GENMASK(19, 16) + +/* IO Delays */ +#define ADI_AXI_ADC_REG_DELAY(l) (0x0800 + (l) * 0x4) +#define AXI_ADC_DELAY_CTRL_MASK GENMASK(4, 0) + +#define ADI_AXI_ADC_MAX_IO_NUM_LANES 15 + #define ADI_AXI_REG_CHAN_CTRL_DEFAULTS \ (ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT | \ ADI_AXI_REG_CHAN_CTRL_FMT_EN | \ ADI_AXI_REG_CHAN_CTRL_ENABLE) struct adi_axi_adc_state { - struct regmap *regmap; - struct device *dev; + struct regmap *regmap; + struct device *dev; + /* lock to protect multiple accesses to the device registers */ + struct mutex lock; }; static int axi_adc_enable(struct iio_backend *back) @@ -104,6 +123,100 @@ static int axi_adc_data_format_set(struct iio_backend *back, unsigned int chan, ADI_AXI_REG_CHAN_CTRL_FMT_MASK, val); } +static int axi_adc_data_sample_trigger(struct iio_backend *back, + enum iio_backend_sample_trigger trigger) +{ + struct adi_axi_adc_state *st = iio_backend_get_priv(back); + + switch (trigger) { + case IIO_BACKEND_SAMPLE_TRIGGER_EDGE_RISING: + return regmap_clear_bits(st->regmap, ADI_AXI_ADC_REG_CTRL, + ADI_AXI_ADC_CTRL_DDR_EDGESEL_MASK); + case IIO_BACKEND_SAMPLE_TRIGGER_EDGE_FALLING: + return regmap_set_bits(st->regmap, ADI_AXI_ADC_REG_CTRL, + ADI_AXI_ADC_CTRL_DDR_EDGESEL_MASK); + default: + return -EINVAL; + } +} + +static int axi_adc_iodelays_set(struct iio_backend *back, unsigned int lane, + unsigned int tap) +{ + struct adi_axi_adc_state *st = iio_backend_get_priv(back); + int ret; + u32 val; + + if (tap > FIELD_MAX(AXI_ADC_DELAY_CTRL_MASK)) + return -EINVAL; + if (lane > ADI_AXI_ADC_MAX_IO_NUM_LANES) + return -EINVAL; + + guard(mutex)(&st->lock); + ret = regmap_write(st->regmap, ADI_AXI_ADC_REG_DELAY(lane), tap); + if (ret) + return ret; + /* + * If readback is ~0, that means there are issues with the + * delay_clk. + */ + ret = regmap_read(st->regmap, ADI_AXI_ADC_REG_DELAY(lane), &val); + if (ret) + return ret; + if (val == U32_MAX) + return -EIO; + + return 0; +} + +static int axi_adc_test_pattern_set(struct iio_backend *back, + unsigned int chan, + enum iio_backend_test_pattern pattern) +{ + struct adi_axi_adc_state *st = iio_backend_get_priv(back); + + switch (pattern) { + case IIO_BACKEND_NO_TEST_PATTERN: + /* nothing to do */ + return 0; + case IIO_BACKEND_ADI_PRBS_9A: + return regmap_update_bits(st->regmap, ADI_AXI_ADC_REG_CHAN_CTRL_3(chan), + ADI_AXI_ADC_CHAN_PN_SEL_MASK, + FIELD_PREP(ADI_AXI_ADC_CHAN_PN_SEL_MASK, 0)); + default: + return -EINVAL; + } +} + +static int axi_adc_chan_status(struct iio_backend *back, unsigned int chan, + bool *error) +{ + struct adi_axi_adc_state *st = iio_backend_get_priv(back); + int ret; + u32 val; + + guard(mutex)(&st->lock); + /* reset test bits by setting them */ + ret = regmap_write(st->regmap, ADI_AXI_ADC_REG_CHAN_STATUS(chan), + ADI_AXI_ADC_CHAN_STAT_PN_MASK); + if (ret) + return ret; + + /* let's give enough time to validate or erroring the incoming pattern */ + fsleep(1000); + + ret = regmap_read(st->regmap, ADI_AXI_ADC_REG_CHAN_STATUS(chan), &val); + if (ret) + return ret; + + if (ADI_AXI_ADC_CHAN_STAT_PN_MASK & val) + *error = true; + else + *error = false; + + return 0; +} + static int axi_adc_chan_enable(struct iio_backend *back, unsigned int chan) { struct adi_axi_adc_state *st = iio_backend_get_priv(back); @@ -166,6 +279,10 @@ static const struct iio_backend_ops adi_axi_adc_generic = { .chan_disable = axi_adc_chan_disable, .request_buffer = axi_adc_request_buffer, .free_buffer = axi_adc_free_buffer, + .data_sample_trigger = axi_adc_data_sample_trigger, + .iodelay_set = axi_adc_iodelays_set, + .test_pattern_set = axi_adc_test_pattern_set, + .chan_status = axi_adc_chan_status, }; static int adi_axi_adc_probe(struct platform_device *pdev) From patchwork Fri Apr 26 15:42:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nuno Sa via B4 Relay X-Patchwork-Id: 13645029 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 37F9E156647; Fri, 26 Apr 2024 15:42:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; cv=none; b=iU0ufySnb5xaqRR7k6QxYGUXMXY7aZB6sbLyygbORujT56HY8iH33MYuPLBjUU7GzYlUXUw6Q116R2u1FFAXVWCejtdpuj5sTmhjD7eXN7gwUy17kIYAYi6GLPlGJaHT23xVo2SYlYQRkG8KkwmcPJlFJra3S7S6rEyjHNnC+hc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714146150; c=relaxed/simple; bh=bFXzZE8rp8xYtcNt17dPfzmcWbRwDJSvsfBAhSRN8es=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eABtCwQuGPkZYHi96Jy53SGV2IxL4qUziCOTLu/uj18Xz/V+PAwBWQlM0FC2b0fmFKYtlHJ65mXPRLmH9mTFspe/LcRTfvYtnSPrC3KldRLg8GeFQX7kICr0aWnalBtuHRyIdzRmevu6mFFuWsN00XNmcSITfWtvGI5Ry/iuQDc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q0zVGimU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q0zVGimU" Received: by smtp.kernel.org (Postfix) with ESMTPS id E27B1C4AF17; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714146149; bh=bFXzZE8rp8xYtcNt17dPfzmcWbRwDJSvsfBAhSRN8es=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Q0zVGimU3Zi6DoZZ/KMg+weAfhnnR86cAdFa4GjDQDD9jYdZXnYrrQifLDipsJv5k KVN55zxSg1HWfIqmj2nX9UOMqv8n7rYh1VCiBCUEpIV2T4i1yYPHfYNrtlSTPvGlDS EnLrR++7TnKPuvwPy2Bbl4SfVob81lKYgGvamEjUZaYeBuG8MFRWh0jZ+7b4nNpQJN PTUwrPB23itcXW10iUjOeWB2gBapgRY5r9UcGb3+ag9cbT8zwGETvw3K8IHPBq8+He sj0h1F4ioOXApac89+RM7wgZmAYmEpmAxZVVZdY6t0YT5q4u52ZWKKRNz+RPZ6kPZ3 4r5c4WFFSV7+A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D92A7C25B4F; Fri, 26 Apr 2024 15:42:29 +0000 (UTC) From: Nuno Sa via B4 Relay Date: Fri, 26 Apr 2024 17:42:16 +0200 Subject: [PATCH v2 7/7] iio: adc: ad9467: support digital interface calibration Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240426-ad9467-new-features-v2-7-6361fc3ba1cc@analog.com> References: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> In-Reply-To: <20240426-ad9467-new-features-v2-0-6361fc3ba1cc@analog.com> To: linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Jonathan Cameron , Alexandru Ardelean , Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1714146147; l=13813; i=nuno.sa@analog.com; s=20231116; h=from:subject:message-id; bh=i70w3MTt/Sp8zZWwI0DZ2SxpTPdPrQ43/++pS/Ib7LU=; b=/cu8Vn07lNwpvUlfh4ebNQppG0NAgs6aw+8HpXF2t26ME5wCSU4/Mql56K7ya5Fog7bMYZJKh JBGNJNnxi/YB4oAq4nnuJrUrikGWhIkfZaHm+7QZyMFA4q1AZ3PXstO X-Developer-Key: i=nuno.sa@analog.com; a=ed25519; pk=3NQwYA013OUYZsmDFBf8rmyyr5iQlxV/9H4/Df83o1E= X-Endpoint-Received: by B4 Relay for nuno.sa@analog.com/20231116 with auth_id=100 X-Original-From: Nuno Sa Reply-To: nuno.sa@analog.com From: Nuno Sa To make sure that we have the best timings on the serial data interface we should calibrate it. This means going through the device supported values and see for which ones we get a successful result. To do that, we use a prbs test pattern both in the IIO backend and in the frontend devices. Then for each of the test points we see if there are any errors. Note that the backend is responsible to look for those errors. As calibrating the interface also requires that the data format is disabled (the one thing being done in ad9467_setup()), ad9467_setup() was removed and configuring the data fomat is now part of the calibration process. Signed-off-by: Nuno Sa --- drivers/iio/adc/ad9467.c | 374 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 335 insertions(+), 39 deletions(-) diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 7475ec2a56c7..e85b763b9ffc 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -4,7 +4,11 @@ * * Copyright 2012-2020 Analog Devices Inc. */ + +#include +#include #include +#include #include #include #include @@ -100,6 +104,8 @@ #define AD9467_DEF_OUTPUT_MODE 0x08 #define AD9467_REG_VREF_MASK 0x0F +#define AD9647_MAX_TEST_POINTS 32 + struct ad9467_chip_info { const char *name; unsigned int id; @@ -110,6 +116,9 @@ struct ad9467_chip_info { unsigned long max_rate; unsigned int default_output_mode; unsigned int vref_mask; + unsigned int num_lanes; + /* data clock output */ + bool has_dco; }; struct ad9467_state { @@ -119,7 +128,16 @@ struct ad9467_state { struct clk *clk; unsigned int output_mode; unsigned int (*scales)[2]; - + /* + * Times 2 because we may also invert the signal polarity and run the + * calibration again. For some reference on the test points (ad9265) see: + * https://www.analog.com/media/en/technical-documentation/data-sheets/ad9265.pdf + * at page 38 for the dco output delay. On devices as ad9467, the + * calibration is done at the backend level. For the ADI axi-adc: + * https://wiki.analog.com/resources/fpga/docs/axi_adc_ip + * at the io delay control section. + */ + DECLARE_BITMAP(calib_map, AD9647_MAX_TEST_POINTS * 2); struct gpio_desc *pwrdown_gpio; /* ensure consistent state obtained on multiple related accesses */ struct mutex lock; @@ -242,6 +260,7 @@ static const struct ad9467_chip_info ad9467_chip_tbl = { .num_channels = ARRAY_SIZE(ad9467_channels), .default_output_mode = AD9467_DEF_OUTPUT_MODE, .vref_mask = AD9467_REG_VREF_MASK, + .num_lanes = 8, }; static const struct ad9467_chip_info ad9434_chip_tbl = { @@ -254,6 +273,7 @@ static const struct ad9467_chip_info ad9434_chip_tbl = { .num_channels = ARRAY_SIZE(ad9434_channels), .default_output_mode = AD9434_DEF_OUTPUT_MODE, .vref_mask = AD9434_REG_VREF_MASK, + .num_lanes = 6, }; static const struct ad9467_chip_info ad9265_chip_tbl = { @@ -266,6 +286,7 @@ static const struct ad9467_chip_info ad9265_chip_tbl = { .num_channels = ARRAY_SIZE(ad9467_channels), .default_output_mode = AD9265_DEF_OUTPUT_MODE, .vref_mask = AD9265_REG_VREF_MASK, + .has_dco = true, }; static int ad9467_get_scale(struct ad9467_state *st, int *val, int *val2) @@ -321,6 +342,246 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2) return -EINVAL; } +static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) +{ + int ret; + + ret = ad9467_spi_write(spi, AN877_ADC_REG_OUTPUT_MODE, mode); + if (ret < 0) + return ret; + + return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); +} + +static int ad9647_calibrate_prepare(const struct ad9467_state *st) +{ + struct iio_backend_data_fmt data = { + .enable = false, + }; + unsigned int c; + int ret; + + ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TEST_IO, + AN877_ADC_TESTMODE_PN9_SEQ); + if (ret) + return ret; + + ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); + if (ret) + return ret; + + ret = ad9467_outputmode_set(st->spi, st->info->default_output_mode); + if (ret) + return ret; + + for (c = 0; c < st->info->num_channels; c++) { + ret = iio_backend_data_format_set(st->back, c, &data); + if (ret) + return ret; + } + + ret = iio_backend_test_pattern_set(st->back, 0, + IIO_BACKEND_ADI_PRBS_9A); + if (ret) + return ret; + + return iio_backend_chan_enable(st->back, 0); +} + +static int ad9647_calibrate_polarity_set(const struct ad9467_state *st, + bool invert) +{ + enum iio_backend_sample_trigger trigger; + + if (st->info->has_dco) { + unsigned int phase = AN877_ADC_OUTPUT_EVEN_ODD_MODE_EN; + + if (invert) + phase |= AN877_ADC_INVERT_DCO_CLK; + + return ad9467_spi_write(st->spi, AN877_ADC_REG_OUTPUT_PHASE, + phase); + } + + if (invert) + trigger = IIO_BACKEND_SAMPLE_TRIGGER_EDGE_FALLING; + else + trigger = IIO_BACKEND_SAMPLE_TRIGGER_EDGE_RISING; + + return iio_backend_data_sample_trigger(st->back, trigger); +} + +/* + * The idea is pretty simple. Find the max number of successful points in a row + * and get the one in the middle. + */ +static unsigned int ad9467_find_optimal_point(const unsigned long *calib_map, + unsigned int start, + unsigned int nbits, + unsigned int *val) +{ + unsigned int bit = start, end, start_cnt, cnt = 0; + + for_each_clear_bitrange_from(bit, end, calib_map, nbits + start) { + if (end - bit > cnt) { + cnt = end - bit; + start_cnt = bit; + } + } + + if (cnt) + *val = start_cnt + cnt / 2; + + return cnt; +} + +static int ad9467_calibrate_apply(const struct ad9467_state *st, + unsigned int val) +{ + unsigned int lane; + int ret; + + if (st->info->has_dco) { + ret = ad9467_spi_write(st->spi, AN877_ADC_REG_OUTPUT_DELAY, + val); + if (ret) + return ret; + + return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); + } + + for (lane = 0; lane < st->info->num_lanes; lane++) { + ret = iio_backend_iodelay_set(st->back, lane, val); + if (ret) + return ret; + } + + return 0; +} + +static int ad9647_calibrate_stop(const struct ad9467_state *st) +{ + struct iio_backend_data_fmt data = { + .sign_extend = true, + .enable = true, + }; + unsigned int c, mode; + int ret; + + ret = iio_backend_chan_disable(st->back, 0); + if (ret) + return ret; + + ret = iio_backend_test_pattern_set(st->back, 0, + IIO_BACKEND_NO_TEST_PATTERN); + if (ret) + return ret; + + for (c = 0; c < st->info->num_channels; c++) { + ret = iio_backend_data_format_set(st->back, c, &data); + if (ret) + return ret; + } + + mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; + ret = ad9467_outputmode_set(st->spi, mode); + if (ret) + return ret; + + ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TEST_IO, + AN877_ADC_TESTMODE_OFF); + if (ret) + return ret; + + return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); +} + +static int ad9467_calibrate(struct ad9467_state *st) +{ + unsigned int point, val, inv_val, cnt, inv_cnt = 0; + /* + * Half of the bitmap is for the inverted signal. The number of test + * points is the same though... + */ + unsigned int test_points = AD9647_MAX_TEST_POINTS; + unsigned long sample_rate = clk_get_rate(st->clk); + struct device *dev = &st->spi->dev; + bool invert = false, stat; + int ret; + + /* all points invalid */ + bitmap_fill(st->calib_map, BITS_PER_TYPE(st->calib_map)); + + ret = ad9647_calibrate_prepare(st); + if (ret) + return ret; +retune: + ret = ad9647_calibrate_polarity_set(st, invert); + if (ret) + return ret; + + for (point = 0; point < test_points; point++) { + ret = ad9467_calibrate_apply(st, point); + if (ret) + return ret; + + ret = iio_backend_chan_status(st->back, 0, &stat); + if (ret) + return ret; + + __assign_bit(point + invert * test_points, st->calib_map, stat); + } + + if (!invert) { + cnt = ad9467_find_optimal_point(st->calib_map, 0, test_points, + &val); + /* + * We're happy if we find, at least, three good test points in + * a row. + */ + if (cnt < 3) { + invert = true; + goto retune; + } + } else { + inv_cnt = ad9467_find_optimal_point(st->calib_map, test_points, + test_points, &inv_val); + if (!inv_cnt && !cnt) + return -EIO; + } + + if (inv_cnt < cnt) { + ret = ad9647_calibrate_polarity_set(st, false); + if (ret) + return ret; + } else { + /* + * polarity inverted is the last test to run. Hence, there's no + * need to re-do any configuration. We just need to "normalize" + * the selected value. + */ + val = inv_val - test_points; + } + + if (st->info->has_dco) + dev_dbg(dev, "%sDCO 0x%X CLK %lu Hz\n", inv_cnt >= cnt ? "INVERT " : "", + val, sample_rate); + else + dev_dbg(dev, "%sIDELAY 0x%x\n", inv_cnt >= cnt ? "INVERT " : "", + val); + + ret = ad9467_calibrate_apply(st, val); + if (ret) + return ret; + + /* finally apply the optimal value */ + return ad9647_calibrate_stop(st); +} + static int ad9467_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long m) @@ -345,7 +606,9 @@ static int ad9467_write_raw(struct iio_dev *indio_dev, { struct ad9467_state *st = iio_priv(indio_dev); const struct ad9467_chip_info *info = st->info; + unsigned long sample_rate; long r_clk; + int ret; switch (mask) { case IIO_CHAN_INFO_SCALE: @@ -358,7 +621,23 @@ static int ad9467_write_raw(struct iio_dev *indio_dev, return -EINVAL; } - return clk_set_rate(st->clk, r_clk); + sample_rate = clk_get_rate(st->clk); + /* + * clk_set_rate() would also do this but since we would still + * need it for avoiding an unnecessary calibration, do it now. + */ + if (sample_rate == r_clk) + return 0; + + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret = clk_set_rate(st->clk, r_clk); + if (ret) + return ret; + + guard(mutex)(&st->lock); + ret = ad9467_calibrate(st); + } + return ret; default: return -EINVAL; } @@ -411,18 +690,6 @@ static const struct iio_info ad9467_info = { .read_avail = ad9467_read_avail, }; -static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) -{ - int ret; - - ret = ad9467_spi_write(spi, AN877_ADC_REG_OUTPUT_MODE, mode); - if (ret < 0) - return ret; - - return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, - AN877_ADC_TRANSFER_SYNC); -} - static int ad9467_scale_fill(struct ad9467_state *st) { const struct ad9467_chip_info *info = st->info; @@ -442,29 +709,6 @@ static int ad9467_scale_fill(struct ad9467_state *st) return 0; } -static int ad9467_setup(struct ad9467_state *st) -{ - struct iio_backend_data_fmt data = { - .sign_extend = true, - .enable = true, - }; - unsigned int c, mode; - int ret; - - mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; - ret = ad9467_outputmode_set(st->spi, mode); - if (ret) - return ret; - - for (c = 0; c < st->info->num_channels; c++) { - ret = iio_backend_data_format_set(st->back, c, &data); - if (ret) - return ret; - } - - return 0; -} - static int ad9467_reset(struct device *dev) { struct gpio_desc *gpio; @@ -521,6 +765,52 @@ static int ad9467_iio_backend_get(struct ad9467_state *st) return -ENODEV; } +static ssize_t ad9467_dump_calib_table(struct file *file, + char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct ad9467_state *st = file->private_data; + unsigned int bit, size = BITS_PER_TYPE(st->calib_map); + /* +2 for the newline and +1 for the string termination */ + unsigned char map[AD9647_MAX_TEST_POINTS * 2 + 3]; + ssize_t len = 0; + + guard(mutex)(&st->lock); + if (*ppos) + goto out_read; + + for (bit = 0; bit < size; bit++) { + if (bit == size / 2) + len += scnprintf(map + len, sizeof(map) - len, "\n"); + + len += scnprintf(map + len, sizeof(map) - len, "%c", + test_bit(bit, st->calib_map) ? 'x' : 'o'); + } + + len += scnprintf(map + len, sizeof(map) - len, "\n"); +out_read: + return simple_read_from_buffer(userbuf, count, ppos, map, len); +} + +static const struct file_operations ad9467_calib_table_fops = { + .open = simple_open, + .read = ad9467_dump_calib_table, + .llseek = default_llseek, + .owner = THIS_MODULE, +}; + +static void ad9467_debugfs_init(struct iio_dev *indio_dev) +{ + struct dentry *d = iio_get_debugfs_dentry(indio_dev); + struct ad9467_state *st = iio_priv(indio_dev); + + if (!IS_ENABLED(CONFIG_DEBUG_FS)) + return; + + debugfs_create_file("calibration_table_dump", 0400, d, st, + &ad9467_calib_table_fops); +} + static int ad9467_probe(struct spi_device *spi) { struct iio_dev *indio_dev; @@ -580,11 +870,17 @@ static int ad9467_probe(struct spi_device *spi) if (ret) return ret; - ret = ad9467_setup(st); + ret = ad9467_calibrate(st); if (ret) return ret; - return devm_iio_device_register(&spi->dev, indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); + if (ret) + return ret; + + ad9467_debugfs_init(indio_dev); + + return 0; } static const struct of_device_id ad9467_of_match[] = {