[12/12] iio: adc: adi-axi-adc: move to backend framework

Message ID 20231121-dev-iio-backend-v1-12-6a3d542eba35@analog.com
State New
Headers
Series iio: add new backend framework |

Commit Message

Nuno Sa via B4 Relay Nov. 21, 2023, 10:20 a.m. UTC
  From: Nuno Sa <nuno.sa@analog.com>

Move to the IIO backend framework. Devices supported by adi-axi-adc now
register themselves as backend devices.

Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/iio/adc/Kconfig       |   1 +
 drivers/iio/adc/adi-axi-adc.c | 364 ++++++++----------------------------------
 2 files changed, 65 insertions(+), 300 deletions(-)
  

Comments

kernel test robot Nov. 21, 2023, 11:27 p.m. UTC | #1
Hi Nuno,

kernel test robot noticed the following build warnings:

[auto build test WARNING on jic23-iio/togreg]
[also build test WARNING on driver-core/driver-core-testing driver-core/driver-core-next driver-core/driver-core-linus robh/for-next linus/master v6.7-rc2 next-20231121]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Nuno-Sa-via-B4-Relay/driver-core-allow-modifying-device_links-flags/20231121-182010
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
patch link:    https://lore.kernel.org/r/20231121-dev-iio-backend-v1-12-6a3d542eba35%40analog.com
patch subject: [PATCH 12/12] iio: adc: adi-axi-adc: move to backend framework
config: i386-randconfig-141-20231122 (https://download.01.org/0day-ci/archive/20231122/202311220748.T1FnZwoy-lkp@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231122/202311220748.T1FnZwoy-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311220748.T1FnZwoy-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/iio/industrialio-backend.c:123: warning: expecting prototype for iio_backend_chan_enable(). Prototype was for iio_backend_enable() instead
>> drivers/iio/industrialio-backend.c:242: warning: Function parameter or member 'back' not described in 'iio_backend_get_priv'
>> drivers/iio/industrialio-backend.c:274: warning: Function parameter or member 'dev' not described in 'devm_iio_backend_register'
>> drivers/iio/industrialio-backend.c:274: warning: Function parameter or member 'ops' not described in 'devm_iio_backend_register'
>> drivers/iio/industrialio-backend.c:274: warning: Function parameter or member 'priv' not described in 'devm_iio_backend_register'


vim +242 drivers/iio/industrialio-backend.c

67915cd5ae2cc11 Nuno Sa 2023-11-21  114  
67915cd5ae2cc11 Nuno Sa 2023-11-21  115  /**
67915cd5ae2cc11 Nuno Sa 2023-11-21  116   * iio_backend_chan_enable - Enable the backend.
67915cd5ae2cc11 Nuno Sa 2023-11-21  117   * @back:	Backend device
67915cd5ae2cc11 Nuno Sa 2023-11-21  118   *
67915cd5ae2cc11 Nuno Sa 2023-11-21  119   * RETURNS:
67915cd5ae2cc11 Nuno Sa 2023-11-21  120   * 0 on success, negative error number on failure.
67915cd5ae2cc11 Nuno Sa 2023-11-21  121   */
67915cd5ae2cc11 Nuno Sa 2023-11-21  122  int iio_backend_enable(struct iio_backend *back)
67915cd5ae2cc11 Nuno Sa 2023-11-21 @123  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  124  	return iio_backend_op_call(back, enable);
67915cd5ae2cc11 Nuno Sa 2023-11-21  125  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  126  EXPORT_SYMBOL_GPL(iio_backend_enable);
67915cd5ae2cc11 Nuno Sa 2023-11-21  127  
67915cd5ae2cc11 Nuno Sa 2023-11-21  128  /**
67915cd5ae2cc11 Nuno Sa 2023-11-21  129   * iio_backend_disable - Disable the backend.
67915cd5ae2cc11 Nuno Sa 2023-11-21  130   * @back:	Backend device
67915cd5ae2cc11 Nuno Sa 2023-11-21  131   */
67915cd5ae2cc11 Nuno Sa 2023-11-21  132  void iio_backend_disable(struct iio_backend *back)
67915cd5ae2cc11 Nuno Sa 2023-11-21  133  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  134  	iio_backend_void_op_call(back, disable);
67915cd5ae2cc11 Nuno Sa 2023-11-21  135  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  136  EXPORT_SYMBOL_GPL(iio_backend_disable);
67915cd5ae2cc11 Nuno Sa 2023-11-21  137  
67915cd5ae2cc11 Nuno Sa 2023-11-21  138  /**
67915cd5ae2cc11 Nuno Sa 2023-11-21  139   * iio_backend_data_format_set - Configure the channel data format
67915cd5ae2cc11 Nuno Sa 2023-11-21  140   * @back:	Backend device
67915cd5ae2cc11 Nuno Sa 2023-11-21  141   * @chan:	Channel number.
67915cd5ae2cc11 Nuno Sa 2023-11-21  142   * @data:	Data format.
67915cd5ae2cc11 Nuno Sa 2023-11-21  143   *
67915cd5ae2cc11 Nuno Sa 2023-11-21  144   * Properly configure a channel with respect to the expected data format. A
67915cd5ae2cc11 Nuno Sa 2023-11-21  145   * @struct iio_backend_data_fmt must be passed with the settings.
67915cd5ae2cc11 Nuno Sa 2023-11-21  146   *
67915cd5ae2cc11 Nuno Sa 2023-11-21  147   * RETURNS:
67915cd5ae2cc11 Nuno Sa 2023-11-21  148   * 0 on success, negative error number on failure
67915cd5ae2cc11 Nuno Sa 2023-11-21  149   */
67915cd5ae2cc11 Nuno Sa 2023-11-21  150  int iio_backend_data_format_set(struct iio_backend *back, unsigned int chan,
67915cd5ae2cc11 Nuno Sa 2023-11-21  151  				const struct iio_backend_data_fmt *data)
67915cd5ae2cc11 Nuno Sa 2023-11-21  152  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  153  	if (!data || data->type >= IIO_BACKEND_DATA_TYPE_MAX)
67915cd5ae2cc11 Nuno Sa 2023-11-21  154  		return -EINVAL;
67915cd5ae2cc11 Nuno Sa 2023-11-21  155  
67915cd5ae2cc11 Nuno Sa 2023-11-21  156  	return iio_backend_op_call(back, data_format_set, chan, data);
67915cd5ae2cc11 Nuno Sa 2023-11-21  157  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  158  EXPORT_SYMBOL_GPL(iio_backend_data_format_set);
67915cd5ae2cc11 Nuno Sa 2023-11-21  159  
67915cd5ae2cc11 Nuno Sa 2023-11-21  160  static void iio_backend_free(struct kref *ref)
67915cd5ae2cc11 Nuno Sa 2023-11-21  161  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  162  	struct iio_backend *back = container_of(ref, struct iio_backend, ref);
67915cd5ae2cc11 Nuno Sa 2023-11-21  163  
67915cd5ae2cc11 Nuno Sa 2023-11-21  164  	kfree(back);
67915cd5ae2cc11 Nuno Sa 2023-11-21  165  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  166  
67915cd5ae2cc11 Nuno Sa 2023-11-21  167  static void iio_backend_release(void *arg)
67915cd5ae2cc11 Nuno Sa 2023-11-21  168  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  169  	struct iio_backend *back = arg;
67915cd5ae2cc11 Nuno Sa 2023-11-21  170  
67915cd5ae2cc11 Nuno Sa 2023-11-21  171  	module_put(back->owner);
67915cd5ae2cc11 Nuno Sa 2023-11-21  172  	kref_put(&back->ref, iio_backend_free);
67915cd5ae2cc11 Nuno Sa 2023-11-21  173  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  174  
67915cd5ae2cc11 Nuno Sa 2023-11-21  175  /**
67915cd5ae2cc11 Nuno Sa 2023-11-21  176   * devm_iio_backend_get - Get a backend device
67915cd5ae2cc11 Nuno Sa 2023-11-21  177   * @dev:	Device where to look for the backend.
67915cd5ae2cc11 Nuno Sa 2023-11-21  178   * @name:	Backend name.
67915cd5ae2cc11 Nuno Sa 2023-11-21  179   *
67915cd5ae2cc11 Nuno Sa 2023-11-21  180   * Get's the backend associated with @dev.
67915cd5ae2cc11 Nuno Sa 2023-11-21  181   *
67915cd5ae2cc11 Nuno Sa 2023-11-21  182   * RETURNS:
67915cd5ae2cc11 Nuno Sa 2023-11-21  183   * A backend pointer, negative error pointer otherwise.
67915cd5ae2cc11 Nuno Sa 2023-11-21  184   */
67915cd5ae2cc11 Nuno Sa 2023-11-21  185  struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name)
67915cd5ae2cc11 Nuno Sa 2023-11-21  186  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  187  	struct fwnode_handle *fwnode;
67915cd5ae2cc11 Nuno Sa 2023-11-21  188  	struct iio_backend *back;
67915cd5ae2cc11 Nuno Sa 2023-11-21  189  	int index = 0, ret;
67915cd5ae2cc11 Nuno Sa 2023-11-21  190  
67915cd5ae2cc11 Nuno Sa 2023-11-21  191  	if (name) {
67915cd5ae2cc11 Nuno Sa 2023-11-21  192  		index = device_property_match_string(dev, "io-backends-names",
67915cd5ae2cc11 Nuno Sa 2023-11-21  193  						     name);
67915cd5ae2cc11 Nuno Sa 2023-11-21  194  		if (index < 0)
67915cd5ae2cc11 Nuno Sa 2023-11-21  195  			return ERR_PTR(index);
67915cd5ae2cc11 Nuno Sa 2023-11-21  196  	}
67915cd5ae2cc11 Nuno Sa 2023-11-21  197  
67915cd5ae2cc11 Nuno Sa 2023-11-21  198  	fwnode = fwnode_find_reference(dev_fwnode(dev), "io-backends", index);
67915cd5ae2cc11 Nuno Sa 2023-11-21  199  	if (IS_ERR(fwnode)) {
67915cd5ae2cc11 Nuno Sa 2023-11-21  200  		dev_err(dev, "Cannot get Firmware reference\n");
67915cd5ae2cc11 Nuno Sa 2023-11-21  201  		return ERR_CAST(fwnode);
67915cd5ae2cc11 Nuno Sa 2023-11-21  202  	}
67915cd5ae2cc11 Nuno Sa 2023-11-21  203  
67915cd5ae2cc11 Nuno Sa 2023-11-21  204  	guard(mutex)(&iio_back_lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  205  	list_for_each_entry(back, &iio_back_list, entry) {
67915cd5ae2cc11 Nuno Sa 2023-11-21  206  		struct device_link *link;
67915cd5ae2cc11 Nuno Sa 2023-11-21  207  
67915cd5ae2cc11 Nuno Sa 2023-11-21  208  		if (!device_match_fwnode(back->dev, fwnode))
67915cd5ae2cc11 Nuno Sa 2023-11-21  209  			continue;
67915cd5ae2cc11 Nuno Sa 2023-11-21  210  
67915cd5ae2cc11 Nuno Sa 2023-11-21  211  		fwnode_handle_put(fwnode);
67915cd5ae2cc11 Nuno Sa 2023-11-21  212  		kref_get(&back->ref);
67915cd5ae2cc11 Nuno Sa 2023-11-21  213  		if (!try_module_get(back->owner)) {
67915cd5ae2cc11 Nuno Sa 2023-11-21  214  			dev_err(dev, "Cannot get module reference\n");
67915cd5ae2cc11 Nuno Sa 2023-11-21  215  			return ERR_PTR(-ENODEV);
67915cd5ae2cc11 Nuno Sa 2023-11-21  216  		}
67915cd5ae2cc11 Nuno Sa 2023-11-21  217  
67915cd5ae2cc11 Nuno Sa 2023-11-21  218  		ret = devm_add_action_or_reset(dev, iio_backend_release, back);
67915cd5ae2cc11 Nuno Sa 2023-11-21  219  		if (ret)
67915cd5ae2cc11 Nuno Sa 2023-11-21  220  			return ERR_PTR(ret);
67915cd5ae2cc11 Nuno Sa 2023-11-21  221  
67915cd5ae2cc11 Nuno Sa 2023-11-21  222  		link = device_link_add(dev, back->dev,
67915cd5ae2cc11 Nuno Sa 2023-11-21  223  				       DL_FLAG_AUTOREMOVE_CONSUMER);
67915cd5ae2cc11 Nuno Sa 2023-11-21  224  		if (!link)
67915cd5ae2cc11 Nuno Sa 2023-11-21  225  			dev_warn(dev, "Could not link to supplier(%s)\n",
67915cd5ae2cc11 Nuno Sa 2023-11-21  226  				 dev_name(back->dev));
67915cd5ae2cc11 Nuno Sa 2023-11-21  227  
67915cd5ae2cc11 Nuno Sa 2023-11-21  228  		dev_dbg(dev, "Found backend(%s) device\n", dev_name(back->dev));
67915cd5ae2cc11 Nuno Sa 2023-11-21  229  		return back;
67915cd5ae2cc11 Nuno Sa 2023-11-21  230  	}
67915cd5ae2cc11 Nuno Sa 2023-11-21  231  
67915cd5ae2cc11 Nuno Sa 2023-11-21  232  	fwnode_handle_put(fwnode);
67915cd5ae2cc11 Nuno Sa 2023-11-21  233  	return ERR_PTR(-EPROBE_DEFER);
67915cd5ae2cc11 Nuno Sa 2023-11-21  234  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  235  EXPORT_SYMBOL_GPL(devm_iio_backend_get);
67915cd5ae2cc11 Nuno Sa 2023-11-21  236  
67915cd5ae2cc11 Nuno Sa 2023-11-21  237  /**
67915cd5ae2cc11 Nuno Sa 2023-11-21  238   * iio_backend_get_priv - Get driver private data
67915cd5ae2cc11 Nuno Sa 2023-11-21  239   * @back	Backend device
67915cd5ae2cc11 Nuno Sa 2023-11-21  240   */
67915cd5ae2cc11 Nuno Sa 2023-11-21  241  void *iio_backend_get_priv(const struct iio_backend *back)
67915cd5ae2cc11 Nuno Sa 2023-11-21 @242  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  243  	return back->priv;
67915cd5ae2cc11 Nuno Sa 2023-11-21  244  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  245  EXPORT_SYMBOL_GPL(iio_backend_get_priv);
67915cd5ae2cc11 Nuno Sa 2023-11-21  246  
67915cd5ae2cc11 Nuno Sa 2023-11-21  247  static void iio_backend_unregister(void *arg)
67915cd5ae2cc11 Nuno Sa 2023-11-21  248  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  249  	struct iio_backend *back = arg;
67915cd5ae2cc11 Nuno Sa 2023-11-21  250  
67915cd5ae2cc11 Nuno Sa 2023-11-21  251  	mutex_lock(&iio_back_lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  252  	list_del(&back->entry);
67915cd5ae2cc11 Nuno Sa 2023-11-21  253  	mutex_unlock(&iio_back_lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  254  
67915cd5ae2cc11 Nuno Sa 2023-11-21  255  	mutex_lock(&back->lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  256  	back->ops = NULL;
67915cd5ae2cc11 Nuno Sa 2023-11-21  257  	mutex_unlock(&back->lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  258  	kref_put(&back->ref, iio_backend_free);
67915cd5ae2cc11 Nuno Sa 2023-11-21  259  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  260  
67915cd5ae2cc11 Nuno Sa 2023-11-21  261  /**
67915cd5ae2cc11 Nuno Sa 2023-11-21  262   * devm_iio_backend_register - Register a new backend device
67915cd5ae2cc11 Nuno Sa 2023-11-21  263   * @dev		Backend device being registered.
67915cd5ae2cc11 Nuno Sa 2023-11-21  264   * @ops		Backend ops
67915cd5ae2cc11 Nuno Sa 2023-11-21  265   * @priv	Device private data.
67915cd5ae2cc11 Nuno Sa 2023-11-21  266   *
67915cd5ae2cc11 Nuno Sa 2023-11-21  267   * @ops and @priv are both mandatory. Not providing them results in -EINVAL.
67915cd5ae2cc11 Nuno Sa 2023-11-21  268   *
67915cd5ae2cc11 Nuno Sa 2023-11-21  269   * RETURNS:
67915cd5ae2cc11 Nuno Sa 2023-11-21  270   * 0 on success, negative error number on failure.
67915cd5ae2cc11 Nuno Sa 2023-11-21  271   */
67915cd5ae2cc11 Nuno Sa 2023-11-21  272  int devm_iio_backend_register(struct device *dev,
67915cd5ae2cc11 Nuno Sa 2023-11-21  273  			      const struct iio_backend_ops *ops, void *priv)
67915cd5ae2cc11 Nuno Sa 2023-11-21 @274  {
67915cd5ae2cc11 Nuno Sa 2023-11-21  275  	struct iio_backend *back;
67915cd5ae2cc11 Nuno Sa 2023-11-21  276  
67915cd5ae2cc11 Nuno Sa 2023-11-21  277  	if (!ops || !priv) {
67915cd5ae2cc11 Nuno Sa 2023-11-21  278  		dev_err(dev, "No backend ops or private data given\n");
67915cd5ae2cc11 Nuno Sa 2023-11-21  279  		return -EINVAL;
67915cd5ae2cc11 Nuno Sa 2023-11-21  280  	}
67915cd5ae2cc11 Nuno Sa 2023-11-21  281  
67915cd5ae2cc11 Nuno Sa 2023-11-21  282  	back = kzalloc(sizeof(*back), GFP_KERNEL);
67915cd5ae2cc11 Nuno Sa 2023-11-21  283  	if (!back)
67915cd5ae2cc11 Nuno Sa 2023-11-21  284  		return -ENOMEM;
67915cd5ae2cc11 Nuno Sa 2023-11-21  285  
67915cd5ae2cc11 Nuno Sa 2023-11-21  286  	kref_init(&back->ref);
67915cd5ae2cc11 Nuno Sa 2023-11-21  287  	mutex_init(&back->lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  288  	back->ops = ops;
67915cd5ae2cc11 Nuno Sa 2023-11-21  289  	back->owner = dev->driver->owner;
67915cd5ae2cc11 Nuno Sa 2023-11-21  290  	back->dev = dev;
67915cd5ae2cc11 Nuno Sa 2023-11-21  291  	back->priv = priv;
67915cd5ae2cc11 Nuno Sa 2023-11-21  292  	mutex_lock(&iio_back_lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  293  	list_add(&back->entry, &iio_back_list);
67915cd5ae2cc11 Nuno Sa 2023-11-21  294  	mutex_unlock(&iio_back_lock);
67915cd5ae2cc11 Nuno Sa 2023-11-21  295  
67915cd5ae2cc11 Nuno Sa 2023-11-21  296  	return devm_add_action_or_reset(dev, iio_backend_unregister, back);
67915cd5ae2cc11 Nuno Sa 2023-11-21  297  }
67915cd5ae2cc11 Nuno Sa 2023-11-21  298  EXPORT_SYMBOL_GPL(devm_iio_backend_register);
67915cd5ae2cc11 Nuno Sa 2023-11-21  299
  
kernel test robot Nov. 25, 2023, 7:42 a.m. UTC | #2
Hi Nuno,

kernel test robot noticed the following build warnings:

[auto build test WARNING on jic23-iio/togreg]
[also build test WARNING on driver-core/driver-core-testing driver-core/driver-core-next driver-core/driver-core-linus robh/for-next linus/master v6.7-rc2 next-20231124]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Nuno-Sa-via-B4-Relay/driver-core-allow-modifying-device_links-flags/20231121-182010
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg
patch link:    https://lore.kernel.org/r/20231121-dev-iio-backend-v1-12-6a3d542eba35%40analog.com
patch subject: [PATCH 12/12] iio: adc: adi-axi-adc: move to backend framework
config: arm-randconfig-r081-20231123 (https://download.01.org/0day-ci/archive/20231125/202311251430.QfOfg5Ws-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20231125/202311251430.QfOfg5Ws-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311251430.QfOfg5Ws-lkp@intel.com/

smatch warnings:
drivers/iio/adc/adi-axi-adc.c:64 axi_adc_enable() warn: inconsistent indenting

vim +64 drivers/iio/adc/adi-axi-adc.c

    58	
    59	static int axi_adc_enable(struct iio_backend *back)
    60	{
    61		struct adi_axi_adc_state *st = iio_backend_get_priv(back);
    62		int ret;
    63	
  > 64		 ret = regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
    65				       ADI_AXI_REG_RSTN_MMCM_RSTN);
    66		if (ret)
    67			return ret;
    68	
    69		fsleep(10);
    70		return regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
    71				       ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
    72	}
    73
  
David Lechner Nov. 30, 2023, 11:33 p.m. UTC | #3
On Tue, Nov 21, 2023 at 4:17 AM Nuno Sa via B4 Relay
<devnull+nuno.sa.analog.com@kernel.org> wrote:
>
> From: Nuno Sa <nuno.sa@analog.com>
>
> Move to the IIO backend framework. Devices supported by adi-axi-adc now
> register themselves as backend devices.
>
> Signed-off-by: Nuno Sa <nuno.sa@analog.com>
> ---
>  drivers/iio/adc/Kconfig       |   1 +
>  drivers/iio/adc/adi-axi-adc.c | 364 ++++++++----------------------------------
>  2 files changed, 65 insertions(+), 300 deletions(-)
>
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index af56df63beff..cc42a3399c63 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -292,6 +292,7 @@ config ADI_AXI_ADC
>         select IIO_BUFFER
>         select IIO_BUFFER_HW_CONSUMER
>         select IIO_BUFFER_DMAENGINE
> +       select IIO_BACKEND
>         depends on HAS_IOMEM
>         depends on OF
>         help
> diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
> index c247ff1541d2..b2ab2c119efa 100644
> --- a/drivers/iio/adc/adi-axi-adc.c
> +++ b/drivers/iio/adc/adi-axi-adc.c

<snip>

> @@ -390,37 +166,23 @@ static int adi_axi_adc_probe(struct platform_device *pdev)
>         if (ret)
>                 return ret;
>
> -       if (cl->info->version > ver) {
> +       if (*expected_ver > ver) {
>                 dev_err(&pdev->dev,
>                         "IP core version is too old. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n",
> -                       ADI_AXI_PCORE_VER_MAJOR(cl->info->version),
> -                       ADI_AXI_PCORE_VER_MINOR(cl->info->version),
> -                       ADI_AXI_PCORE_VER_PATCH(cl->info->version),
> +                       ADI_AXI_PCORE_VER_MAJOR(*expected_ver),
> +                       ADI_AXI_PCORE_VER_MINOR(*expected_ver),
> +                       ADI_AXI_PCORE_VER_PATCH(*expected_ver),
>                         ADI_AXI_PCORE_VER_MAJOR(ver),
>                         ADI_AXI_PCORE_VER_MINOR(ver),
>                         ADI_AXI_PCORE_VER_PATCH(ver));
>                 return -ENODEV;
>         }
>
> -       indio_dev->info = &adi_axi_adc_info;
> -       indio_dev->name = "adi-axi-adc";
> -       indio_dev->modes = INDIO_DIRECT_MODE;
> -       indio_dev->num_channels = conv->chip_info->num_channels;
> -       indio_dev->channels = conv->chip_info->channels;
> -
> -       ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev);
> +       ret = devm_iio_backend_register(&pdev->dev, &adi_axi_adc_generic, st);
>         if (ret)
>                 return ret;
>
> -       ret = adi_axi_adc_setup_channels(&pdev->dev, st);
> -       if (ret)
> -               return ret;
> -
> -       ret = devm_iio_device_register(&pdev->dev, indio_dev);
> -       if (ret)
> -               return ret;
> -
> -       dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n",
> +       dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%d) probed\n",

Was this format change intentional? There are other places above where
%c is still used.

>                  ADI_AXI_PCORE_VER_MAJOR(ver),
>                  ADI_AXI_PCORE_VER_MINOR(ver),
>                  ADI_AXI_PCORE_VER_PATCH(ver));
> @@ -428,6 +190,8 @@ static int adi_axi_adc_probe(struct platform_device *pdev)
>         return 0;
>  }
>
> +static unsigned int adi_axi_adc_10_0_a_info = ADI_AXI_PCORE_VER(10, 0, 'a');
> +
>  /* Match table for of_platform binding */
>  static const struct of_device_id adi_axi_adc_of_match[] = {
>         { .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info },
>
> --
> 2.42.1
>
>
  
Nuno Sá Dec. 1, 2023, 8:50 a.m. UTC | #4
On Thu, 2023-11-30 at 17:33 -0600, David Lechner wrote:
> On Tue, Nov 21, 2023 at 4:17 AM Nuno Sa via B4 Relay
> <devnull+nuno.sa.analog.com@kernel.org> wrote:
> > 
> > From: Nuno Sa <nuno.sa@analog.com>
> > 
> > Move to the IIO backend framework. Devices supported by adi-axi-adc now
> > register themselves as backend devices.
> > 
> > Signed-off-by: Nuno Sa <nuno.sa@analog.com>
> > ---
> >  drivers/iio/adc/Kconfig       |   1 +
> >  drivers/iio/adc/adi-axi-adc.c | 364 ++++++++----------------------------------
> >  2 files changed, 65 insertions(+), 300 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> > index af56df63beff..cc42a3399c63 100644
> > --- a/drivers/iio/adc/Kconfig
> > +++ b/drivers/iio/adc/Kconfig
> > @@ -292,6 +292,7 @@ config ADI_AXI_ADC
> >         select IIO_BUFFER
> >         select IIO_BUFFER_HW_CONSUMER
> >         select IIO_BUFFER_DMAENGINE
> > +       select IIO_BACKEND
> >         depends on HAS_IOMEM
> >         depends on OF
> >         help
> > diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
> > index c247ff1541d2..b2ab2c119efa 100644
> > --- a/drivers/iio/adc/adi-axi-adc.c
> > +++ b/drivers/iio/adc/adi-axi-adc.c
> 
> <snip>
> 
> > @@ -390,37 +166,23 @@ static int adi_axi_adc_probe(struct platform_device *pdev)
> >         if (ret)
> >                 return ret;
> > 
> > -       if (cl->info->version > ver) {
> > +       if (*expected_ver > ver) {
> >                 dev_err(&pdev->dev,
> >                         "IP core version is too old. Expected %d.%.2d.%c,
> > Reported %d.%.2d.%c\n",
> > -                       ADI_AXI_PCORE_VER_MAJOR(cl->info->version),
> > -                       ADI_AXI_PCORE_VER_MINOR(cl->info->version),
> > -                       ADI_AXI_PCORE_VER_PATCH(cl->info->version),
> > +                       ADI_AXI_PCORE_VER_MAJOR(*expected_ver),
> > +                       ADI_AXI_PCORE_VER_MINOR(*expected_ver),
> > +                       ADI_AXI_PCORE_VER_PATCH(*expected_ver),
> >                         ADI_AXI_PCORE_VER_MAJOR(ver),
> >                         ADI_AXI_PCORE_VER_MINOR(ver),
> >                         ADI_AXI_PCORE_VER_PATCH(ver));
> >                 return -ENODEV;
> >         }
> > 
> > -       indio_dev->info = &adi_axi_adc_info;
> > -       indio_dev->name = "adi-axi-adc";
> > -       indio_dev->modes = INDIO_DIRECT_MODE;
> > -       indio_dev->num_channels = conv->chip_info->num_channels;
> > -       indio_dev->channels = conv->chip_info->channels;
> > -
> > -       ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev);
> > +       ret = devm_iio_backend_register(&pdev->dev, &adi_axi_adc_generic, st);
> >         if (ret)
> >                 return ret;
> > 
> > -       ret = adi_axi_adc_setup_channels(&pdev->dev, st);
> > -       if (ret)
> > -               return ret;
> > -
> > -       ret = devm_iio_device_register(&pdev->dev, indio_dev);
> > -       if (ret)
> > -               return ret;
> > -
> > -       dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n",
> > +       dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%d) probed\n",
> 
> Was this format change intentional? There are other places above where
> %c is still used.
> 

Yes, the output was weird with %c. I guess something changed... Hmm need to look at
the other places.

- Nuno Sá
>
  

Patch

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index af56df63beff..cc42a3399c63 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -292,6 +292,7 @@  config ADI_AXI_ADC
 	select IIO_BUFFER
 	select IIO_BUFFER_HW_CONSUMER
 	select IIO_BUFFER_DMAENGINE
+	select IIO_BACKEND
 	depends on HAS_IOMEM
 	depends on OF
 	help
diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
index c247ff1541d2..b2ab2c119efa 100644
--- a/drivers/iio/adc/adi-axi-adc.c
+++ b/drivers/iio/adc/adi-axi-adc.c
@@ -17,13 +17,9 @@ 
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/buffer-dmaengine.h>
-
 #include <linux/fpga/adi-axi-common.h>
-#include <linux/iio/adc/adi-axi-adc.h>
+#include <linux/iio/backend.h>
+
 
 /*
  * Register definitions:
@@ -44,6 +40,7 @@ 
 #define   ADI_AXI_REG_CHAN_CTRL_PN_SEL_OWR	BIT(10)
 #define   ADI_AXI_REG_CHAN_CTRL_IQCOR_EN	BIT(9)
 #define   ADI_AXI_REG_CHAN_CTRL_DCFILT_EN	BIT(8)
+#define   ADI_AXI_REG_CHAN_CTRL_FMT_MASK	GENMASK(6, 4)
 #define   ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT	BIT(6)
 #define   ADI_AXI_REG_CHAN_CTRL_FMT_TYPE	BIT(5)
 #define   ADI_AXI_REG_CHAN_CTRL_FMT_EN		BIT(4)
@@ -55,286 +52,67 @@ 
 	 ADI_AXI_REG_CHAN_CTRL_FMT_EN |		\
 	 ADI_AXI_REG_CHAN_CTRL_ENABLE)
 
-struct adi_axi_adc_core_info {
-	unsigned int				version;
-};
-
 struct adi_axi_adc_state {
-	struct mutex				lock;
-
-	struct adi_axi_adc_client		*client;
 	struct regmap				*regmap;
 };
 
-struct adi_axi_adc_client {
-	struct list_head			entry;
-	struct adi_axi_adc_conv			conv;
-	struct adi_axi_adc_state		*state;
-	struct device				*dev;
-	const struct adi_axi_adc_core_info	*info;
-};
-
-static LIST_HEAD(registered_clients);
-static DEFINE_MUTEX(registered_clients_lock);
-
-static struct adi_axi_adc_client *conv_to_client(struct adi_axi_adc_conv *conv)
-{
-	return container_of(conv, struct adi_axi_adc_client, conv);
-}
-
-void *adi_axi_adc_conv_priv(struct adi_axi_adc_conv *conv)
-{
-	struct adi_axi_adc_client *cl = conv_to_client(conv);
-
-	return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client),
-				  IIO_DMA_MINALIGN);
-}
-EXPORT_SYMBOL_NS_GPL(adi_axi_adc_conv_priv, IIO_ADI_AXI);
-
-static int adi_axi_adc_config_dma_buffer(struct device *dev,
-					 struct iio_dev *indio_dev)
-{
-	const char *dma_name;
-
-	if (!device_property_present(dev, "dmas"))
-		return 0;
-
-	if (device_property_read_string(dev, "dma-names", &dma_name))
-		dma_name = "rx";
-
-	return devm_iio_dmaengine_buffer_setup(indio_dev->dev.parent,
-					       indio_dev, dma_name);
-}
-
-static int adi_axi_adc_read_raw(struct iio_dev *indio_dev,
-				struct iio_chan_spec const *chan,
-				int *val, int *val2, long mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-
-	if (!conv->read_raw)
-		return -EOPNOTSUPP;
-
-	return conv->read_raw(conv, chan, val, val2, mask);
-}
-
-static int adi_axi_adc_write_raw(struct iio_dev *indio_dev,
-				 struct iio_chan_spec const *chan,
-				 int val, int val2, long mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-
-	if (!conv->write_raw)
-		return -EOPNOTSUPP;
-
-	return conv->write_raw(conv, chan, val, val2, mask);
-}
-
-static int adi_axi_adc_read_avail(struct iio_dev *indio_dev,
-				  struct iio_chan_spec const *chan,
-				  const int **vals, int *type, int *length,
-				  long mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-
-	if (!conv->read_avail)
-		return -EOPNOTSUPP;
-
-	return conv->read_avail(conv, chan, vals, type, length, mask);
-}
-
-static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev,
-					const unsigned long *scan_mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-	unsigned int i;
-	int ret;
-
-	for (i = 0; i < conv->chip_info->num_channels; i++) {
-		if (test_bit(i, scan_mask))
-			ret = regmap_set_bits(st->regmap,
-					      ADI_AXI_REG_CHAN_CTRL(i),
-					      ADI_AXI_REG_CHAN_CTRL_ENABLE);
-		else
-			ret = regmap_clear_bits(st->regmap,
-						ADI_AXI_REG_CHAN_CTRL(i),
-						ADI_AXI_REG_CHAN_CTRL_ENABLE);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static struct adi_axi_adc_conv *adi_axi_adc_conv_register(struct device *dev,
-							  size_t sizeof_priv)
-{
-	struct adi_axi_adc_client *cl;
-	size_t alloc_size;
-
-	alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_DMA_MINALIGN);
-	if (sizeof_priv)
-		alloc_size += ALIGN(sizeof_priv, IIO_DMA_MINALIGN);
-
-	cl = kzalloc(alloc_size, GFP_KERNEL);
-	if (!cl)
-		return ERR_PTR(-ENOMEM);
-
-	mutex_lock(&registered_clients_lock);
-
-	cl->dev = get_device(dev);
-
-	list_add_tail(&cl->entry, &registered_clients);
-
-	mutex_unlock(&registered_clients_lock);
-
-	return &cl->conv;
-}
-
-static void adi_axi_adc_conv_unregister(struct adi_axi_adc_conv *conv)
-{
-	struct adi_axi_adc_client *cl = conv_to_client(conv);
-
-	mutex_lock(&registered_clients_lock);
-
-	list_del(&cl->entry);
-	put_device(cl->dev);
-
-	mutex_unlock(&registered_clients_lock);
-
-	kfree(cl);
-}
-
-static void devm_adi_axi_adc_conv_release(void *conv)
-{
-	adi_axi_adc_conv_unregister(conv);
-}
-
-struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
-							size_t sizeof_priv)
+static int axi_adc_enable(struct iio_backend *back)
 {
-	struct adi_axi_adc_conv *conv;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 	int ret;
 
-	conv = adi_axi_adc_conv_register(dev, sizeof_priv);
-	if (IS_ERR(conv))
-		return conv;
-
-	ret = devm_add_action_or_reset(dev, devm_adi_axi_adc_conv_release,
-				       conv);
+	 ret = regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
+			       ADI_AXI_REG_RSTN_MMCM_RSTN);
 	if (ret)
-		return ERR_PTR(ret);
+		return ret;
 
-	return conv;
+	fsleep(10);
+	return regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
+			       ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
 }
-EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI);
 
-static const struct iio_info adi_axi_adc_info = {
-	.read_raw = &adi_axi_adc_read_raw,
-	.write_raw = &adi_axi_adc_write_raw,
-	.update_scan_mode = &adi_axi_adc_update_scan_mode,
-	.read_avail = &adi_axi_adc_read_avail,
-};
-
-static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = {
-	.version = ADI_AXI_PCORE_VER(10, 0, 'a'),
-};
-
-static struct adi_axi_adc_client *adi_axi_adc_attach_client(struct device *dev)
+static void axi_adc_disable(struct iio_backend *back)
 {
-	const struct adi_axi_adc_core_info *info;
-	struct adi_axi_adc_client *cl;
-	struct device_node *cln;
-
-	info = of_device_get_match_data(dev);
-	if (!info)
-		return ERR_PTR(-ENODEV);
-
-	cln = of_parse_phandle(dev->of_node, "adi,adc-dev", 0);
-	if (!cln) {
-		dev_err(dev, "No 'adi,adc-dev' node defined\n");
-		return ERR_PTR(-ENODEV);
-	}
-
-	mutex_lock(&registered_clients_lock);
-
-	list_for_each_entry(cl, &registered_clients, entry) {
-		if (!cl->dev)
-			continue;
-
-		if (cl->dev->of_node != cln)
-			continue;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 
-		if (!try_module_get(cl->dev->driver->owner)) {
-			mutex_unlock(&registered_clients_lock);
-			of_node_put(cln);
-			return ERR_PTR(-ENODEV);
-		}
-
-		get_device(cl->dev);
-		cl->info = info;
-		mutex_unlock(&registered_clients_lock);
-		of_node_put(cln);
-		return cl;
-	}
-
-	mutex_unlock(&registered_clients_lock);
-	of_node_put(cln);
-
-	return ERR_PTR(-EPROBE_DEFER);
+	regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0);
 }
 
-static int adi_axi_adc_setup_channels(struct device *dev,
-				      struct adi_axi_adc_state *st)
+static int axi_adc_data_format_set(struct iio_backend *back, unsigned int chan,
+				   const struct iio_backend_data_fmt *data)
 {
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-	int i, ret;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+	u32 val;
 
-	if (conv->preenable_setup) {
-		ret = conv->preenable_setup(conv);
-		if (ret)
-			return ret;
-	}
+	if (!data->enable)
+		return regmap_clear_bits(st->regmap,
+					 ADI_AXI_REG_CHAN_CTRL(chan),
+					 ADI_AXI_REG_CHAN_CTRL_FMT_EN);
 
-	for (i = 0; i < conv->chip_info->num_channels; i++) {
-		ret = regmap_write(st->regmap, ADI_AXI_REG_CHAN_CTRL(i),
-				   ADI_AXI_REG_CHAN_CTRL_DEFAULTS);
-		if (ret)
-			return ret;
-	}
+	val = FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_EN, true);
+	if (data->sign_extend)
+		val |= FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT, true);
+	if (data->type == IIO_BACKEND_OFFSET_BINARY)
+		val |= FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_TYPE, true);
 
-	return 0;
+	return regmap_update_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan),
+				  ADI_AXI_REG_CHAN_CTRL_FMT_MASK, val);
 }
 
-static int axi_adc_reset(struct adi_axi_adc_state *st)
+static int axi_adc_chan_enable(struct iio_backend *back, unsigned int chan)
 {
-	int ret;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 
-	ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0);
-	if (ret)
-		return ret;
-
-	mdelay(10);
-	ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN,
-			   ADI_AXI_REG_RSTN_MMCM_RSTN);
-	if (ret)
-		return ret;
-
-	mdelay(10);
-	return regmap_write(st->regmap, ADI_AXI_REG_RSTN,
-			    ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
+	return regmap_set_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan),
+			       ADI_AXI_REG_CHAN_CTRL_ENABLE);
 }
 
-static void adi_axi_adc_cleanup(void *data)
+static int axi_adc_chan_disable(struct iio_backend *back, unsigned int chan)
 {
-	struct adi_axi_adc_client *cl = data;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 
-	put_device(cl->dev);
-	module_put(cl->dev->driver->owner);
+	return regmap_clear_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan),
+				 ADI_AXI_REG_CHAN_CTRL_ENABLE);
 }
 
 static const struct regmap_config axi_adc_regmap_config = {
@@ -344,33 +122,25 @@  static const struct regmap_config axi_adc_regmap_config = {
 	.max_register = 0x0800,
 };
 
+static const struct iio_backend_ops adi_axi_adc_generic = {
+	.enable = axi_adc_enable,
+	.disable = axi_adc_disable,
+	.data_format_set = axi_adc_data_format_set,
+	.chan_enable = axi_adc_chan_enable,
+	.chan_disable = axi_adc_chan_disable,
+};
+
 static int adi_axi_adc_probe(struct platform_device *pdev)
 {
-	struct adi_axi_adc_conv *conv;
-	struct iio_dev *indio_dev;
-	struct adi_axi_adc_client *cl;
 	struct adi_axi_adc_state *st;
 	void __iomem *base;
-	unsigned int ver;
+	unsigned int ver, *expected_ver;
 	int ret;
 
-	cl = adi_axi_adc_attach_client(&pdev->dev);
-	if (IS_ERR(cl))
-		return PTR_ERR(cl);
-
-	ret = devm_add_action_or_reset(&pdev->dev, adi_axi_adc_cleanup, cl);
-	if (ret)
-		return ret;
-
-	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
-	if (indio_dev == NULL)
+	st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL);
+	if (!st)
 		return -ENOMEM;
 
-	st = iio_priv(indio_dev);
-	st->client = cl;
-	cl->state = st;
-	mutex_init(&st->lock);
-
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
@@ -380,9 +150,15 @@  static int adi_axi_adc_probe(struct platform_device *pdev)
 	if (IS_ERR(st->regmap))
 		return PTR_ERR(st->regmap);
 
-	conv = &st->client->conv;
+	expected_ver = (unsigned int *)device_get_match_data(&pdev->dev);
+	if (!expected_ver)
+		return -ENODEV;
 
-	ret = axi_adc_reset(st);
+	/*
+	 * Force disable the core. Up to the frontend to enable us. And we can
+	 * still read/write registers...
+	 */
+	ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0);
 	if (ret)
 		return ret;
 
@@ -390,37 +166,23 @@  static int adi_axi_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	if (cl->info->version > ver) {
+	if (*expected_ver > ver) {
 		dev_err(&pdev->dev,
 			"IP core version is too old. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n",
-			ADI_AXI_PCORE_VER_MAJOR(cl->info->version),
-			ADI_AXI_PCORE_VER_MINOR(cl->info->version),
-			ADI_AXI_PCORE_VER_PATCH(cl->info->version),
+			ADI_AXI_PCORE_VER_MAJOR(*expected_ver),
+			ADI_AXI_PCORE_VER_MINOR(*expected_ver),
+			ADI_AXI_PCORE_VER_PATCH(*expected_ver),
 			ADI_AXI_PCORE_VER_MAJOR(ver),
 			ADI_AXI_PCORE_VER_MINOR(ver),
 			ADI_AXI_PCORE_VER_PATCH(ver));
 		return -ENODEV;
 	}
 
-	indio_dev->info = &adi_axi_adc_info;
-	indio_dev->name = "adi-axi-adc";
-	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->num_channels = conv->chip_info->num_channels;
-	indio_dev->channels = conv->chip_info->channels;
-
-	ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev);
+	ret = devm_iio_backend_register(&pdev->dev, &adi_axi_adc_generic, st);
 	if (ret)
 		return ret;
 
-	ret = adi_axi_adc_setup_channels(&pdev->dev, st);
-	if (ret)
-		return ret;
-
-	ret = devm_iio_device_register(&pdev->dev, indio_dev);
-	if (ret)
-		return ret;
-
-	dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n",
+	dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%d) probed\n",
 		 ADI_AXI_PCORE_VER_MAJOR(ver),
 		 ADI_AXI_PCORE_VER_MINOR(ver),
 		 ADI_AXI_PCORE_VER_PATCH(ver));
@@ -428,6 +190,8 @@  static int adi_axi_adc_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static unsigned int adi_axi_adc_10_0_a_info = ADI_AXI_PCORE_VER(10, 0, 'a');
+
 /* Match table for of_platform binding */
 static const struct of_device_id adi_axi_adc_of_match[] = {
 	{ .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info },