iio: backend: add API for interface tuning

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 <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20240426-ad9467-new-features-v2-2-6361fc3ba1cc@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Nuno Sa 2024-04-26 17:42:11 +02:00 committed by Jonathan Cameron
parent 09415814cd
commit c66eabcc1c
2 changed files with 122 additions and 0 deletions

View File

@ -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); 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) static void iio_backend_free_buffer(void *arg)
{ {
struct iio_backend_buffer_pair *pair = arg; struct iio_backend_buffer_pair *pair = arg;

View File

@ -49,6 +49,20 @@ struct iio_backend_data_fmt {
bool enable; 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 * struct iio_backend_ops - operations structure for an iio_backend
* @enable: Enable 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_format_set: Configure the data format for a specific channel.
* @data_source_set: Configure the data source 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. * @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. * @request_buffer: Request an IIO buffer.
* @free_buffer: Free an IIO buffer. * @free_buffer: Free an IIO buffer.
* @extend_chan_spec: Extend an IIO channel. * @extend_chan_spec: Extend an IIO channel.
@ -75,6 +93,15 @@ struct iio_backend_ops {
enum iio_backend_data_source data); enum iio_backend_data_source data);
int (*set_sample_rate)(struct iio_backend *back, unsigned int chan, int (*set_sample_rate)(struct iio_backend *back, unsigned int chan,
u64 sample_rate_hz); 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_buffer *(*request_buffer)(struct iio_backend *back,
struct iio_dev *indio_dev); struct iio_dev *indio_dev);
void (*free_buffer)(struct iio_backend *back, 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); enum iio_backend_data_source data);
int iio_backend_set_sampling_freq(struct iio_backend *back, unsigned int chan, int iio_backend_set_sampling_freq(struct iio_backend *back, unsigned int chan,
u64 sample_rate_hz); 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, int devm_iio_backend_request_buffer(struct device *dev,
struct iio_backend *back, struct iio_backend *back,
struct iio_dev *indio_dev); struct iio_dev *indio_dev);