Distributed Control of AD9361 transceiver

We have a design using an AD9361 transceiver on an AD-FSCOMMS2/3 board where we have distributed control, a user space application which controls a fair amount of transceiver content such as operating state, frequency, etc.  and a Linux custom device driver operating in Linux kernel space that will need to control settings such as data rate quickly, and also needs to be the source and sink of network packets that originate (outgoing and incoming) to the Linux stack. 

Attributes for control of the AD9361 are somewhat orthogonal so in concept, the two processes would not be controlling the same attributes.

We are considering using the No-OS bare metal SPI based driver in the Linux kernel device driver and the exposed exported APIs from ad9361.h from this driver for kernel space access, and using the AD9361 device driver coupled with LibIIO for the user space control.  Notionally, the custom Linux device driver would perform the AD9361  initialization, and the User Space application would change attributes using the "sysfs" exposed interface via LibIIO.

Do you feel that conceptually this design is problematic?  For example, is there an assumption in the design of

of the bare metal SPI interface of singular master for the AD9361.  Since the AD9361 device drive uses the same SPI interface under the covers, are there issues with thread safety or re-entrancy?

The previous discussion addresses the control and status plain, but need for the data plain to be addressed by our custom Linux device driver which will act as a Linux network type of device driver.  It would need to transmit content received from the network stack as Ethernet frames, and the converse, push received frames from the transceiver to the stack.  This brings to mind issues of marking stream content to the AD9261 in such a manner that an Ethernet frame can be reconstituted.   What APIs are available from the AD9361 device driver to support the transfer of data, or is that addressed by a different software component such as the ADCs?

  • 0
    •  Analog Employees 
    on Aug 10, 2016 4:56 PM

    The Linux AD9361-phy driver implements the same functionality as the AD9361 No-OS driver. In fact the No-OS driver is derived from the Linux driver. Your proposed partitioning is in fact very problematic - there must only be one instance controlling a single transceiver (there is some state assumed in the hardware - and many calibrations and setups require strict ordering, - concurrent access may cause failures and unpredicted behavior, etc..

    Things can be logically split into a control (ad9361-phy) and data portion (axi-adc and axi-dds-dac).

    In the current setup the ad9361-phy driver can be optionally used sand-alone. However in our reference example the axi-adc driver acquires a handle to the ad9361-phy driver and vice versa. The axi-adc driver maps the axi-dds-dac register space as well. In fact it's a single HDL core and RX/TX (aka. ADC/DAC) is just spaced 4k apart.

    You can try and route your data via user space using the existing infrastructure, do the processing there and then re-inject the networking packets via TUN/TAP.

    If you require less latency - take a look on how the axi-adc driver interfaces with the ad9361-phy driver. There is a sysfs user access mutex that is held whenever there is a API call, if you use the in-kernel interface - you need to add some additional exports and also try to acquire the mutex.


  • Michael, thanks for the guidance.  Perhaps a couple of points of clarification.

    1.  Looking through the source to the No-OS driver, which has user space references (e.g. stdio, stdlib) because that is probably where this driver was targeted, I can see how the ad9361 content was "extracted" from the original device driver code for use with IIO.  Is it safe to assume that some of the value added functions in ad9361_apis.c/h might with few modifications be used for a kernel mode driver? 

    2.  Since the ADI custom OS has the ad9361 driver built into the kernel, presumably this SPI driver will load when an AD-FSCOMMS2/3 board is plugged into the mezzanine connector, would there be potential collisions between the loaded device driver code and attempts to use ad9361.c/h in our custom kernel mode device driver?  Another way of asking would be that for a kernel mode only solution, the exports from the device driver itself would represent the lowest level SPI interface, and our custom device driver (probably a kernel loadable module) could use the value added functions in ad9361_apis.c/h, but not ad9361.c itself in this custom device driver.

  • 0
    •  Analog Employees 
    on Aug 12, 2016 4:42 AM

    1. If you want to do a kernel mode driver use the existing Linux driver! There is nothing value added in ad9361_api.c. It's mostly wrappers around functions, to replace the sysfs API with a little bit more straight forward function call API.

    You can move some of these function wrappers from the no-OS_api.c into your driver.

    In the ad9361.c kernel mode driver you only need to EXPORT_SYMBOL of the function you need to access.

    linux/ad9361.c at xcomm_zynq · analogdevicesinc/linux · GitHub

    You must guard concurrent access between the sysfs API and in the in-kernel API with a proper MUTEX.

    2. Two driver instances controlling the same piece of HW is not going to work!

    If you don't want to use the AD9361 Linux driver, either don't compile it into your kernel or remove the reference to it from your device tree.


  • 0
    •  Analog Employees 
    on Aug 2, 2018 3:33 PM
    This question has been assumed as answered either offline via email or with a multi-part answer. This question has now been closed out. If you have an inquiry related to this topic please post a new question in the applicable product forum.

    Thank you,
    EZ Admin