Post Go back to editing

Enable DDC in FMCDAQ2 + kc705

Hi,

I am using KC705 & FMCDAQ2 combo. I would finally move to ZC706 + FMCDAQ2

I would like enable DDC in AD9680. My preferred configuration is given in ""Table 23. DDC Example Configurations"" Chip decimation ratio is 16 ie no of virtual converters 8.
I have referred to below link.

ez.analog.com/.../412002

In case of HDL design, ""you could modify the design to M=8 ""

Does that mean I need to edit projects\daq2\common\daq2_bd.tcl? What are the other parameters to change?

""
ad_ip_instance util_cpack2 axi_ad9680_cpack { \
NUM_OF_CHANNELS 2 \
SAMPLES_PER_CHANNEL 4 \
SAMPLE_DATA_WIDTH 16 \
}
""

to

""
ad_ip_instance util_cpack2 axi_ad9680_cpack { \
NUM_OF_CHANNELS 8 \
SAMPLES_PER_CHANNEL 1 \
SAMPLE_DATA_WIDTH 16 \
}
""


our requirement is similar to ""Example 2: ADC with DDC Option (Two ADCs Plus Four DDCs)"" in AD9680 data sheet.

As i understand, we may have to reduce no of lanes to 2 from given default 4 lanes in example design to maintain minimum lane rate of >3.125Gbps.

Is there any guidelines to reduce the lane nos in HDL design? Do I need to just edit daq2_bd.tcl?

Parents
  • Hello,

    You just need to edit the daq2_bd.tcl file in the common directory. Since the architecture construction is parameterized you just need to modify the variables defined in the beginning of the file: set RX_NUM_OF_LANES 2 ; # L
                                                                                 set RX_NUM_OF_CONVERTERS 8 ; # M
                                                                                 set RX_SAMPLES_PER_FRAME 1 ; # S
                                                                                 set RX_SAMPLE_WIDTH 16 ; # N/NP

    Best Regards,

    Dan Hotoleanu

  • For hdl_2019_r2 with the above modification in daq2_bd.tcl synthesis failed with following error 

    ""ERROR: [Synth 8-2908] range width must be a positive integer [d:/adi/ddc_ver/projects/daq2/kc705/daq2_kc705.srcs/sources_1/bd/system/ipshared/6295/util_cpack2.v:280]
    ERROR: [Synth 8-6156] failed synthesizing module 'util_cpack2' [d:/adi/ddc_ver/projects/daq2/kc705/daq2_kc705.srcs/sources_1/bd/system/ipshared/6295/util_cpack2.v:38]
    ERROR: [Synth 8-6156] failed synthesizing module 'system_axi_ad9680_cpack_0' [d:/adi/ddc_ver/projects/daq2/kc705/daq2_kc705.srcs/sources_1/bd/system/ip/system_axi_ad9680_cpack_0/synth/system_axi_ad9680_cpack_0.v:57]
    ERROR: [Synth 8-6156] failed synthesizing module 'system' [D:/adi/ddc_ver/projects/daq2/kc705/daq2_kc705.srcs/sources_1/bd/system/synth/system.v:2942]
    ERROR: [Synth 8-6156] failed synthesizing module 'system_wrapper' [D:/adi/ddc_ver/projects/daq2/kc705/daq2_kc705.srcs/sources_1/imports/hdl/system_wrapper.v:12]
    ERROR: [Synth 8-6156] failed synthesizing module 'system_top' [d:/adi/ddc_ver/projects/daq2/kc705/system_top.v:38]

    ""

  • Hello Dan,

    I tried building hdl using Vivado 2020.1

    I encounter the following error while building project.

    ""

    Building axi_clkgen library [/cygdrive/d/adi/Analog_Support/hdl/library/axi_clkgen/axi_clkgen_ip.log] ... OK
    Building axi_hdmi_tx library [/cygdrive/d/adi/Analog_Support/hdl/library/axi_hdmi_tx/axi_hdmi_tx_ip.log] ... OK
    Building axi_spdif_tx library [/cygdrive/d/adi/Analog_Support/hdl/library/axi_spdif_tx/axi_spdif_tx_ip.log] ... OK
    Building axi_adcfifo library [/cygdrive/d/adi/Analog_Support/hdl/library/xilinx/axi_adcfifo/axi_adcfifo_ip.log] ... OK
    Building daq2_zc706 project [/cygdrive/d/adi/Analog_Support/hdl/projects/daq2/zc706/daq2_zc706_vivado.log] ... FAILED
    For details see /cygdrive/d/adi/Analog_Support/hdl/projects/daq2/zc706/daq2_zc706_vivado.log

    make: *** [../../scripts/project-xilinx.mk:61: daq2_zc706.sdk/system_top.hdf] Error 1

    ""0755.daq2_zc706_vivado.log

    Attaching log file

  • Hello,

    Can you please make a fresh clone of the hdl repository on my fork https://github.com/hotoleanudan/hdl and switch to daq2_without_ad9144_proj branch and then build the daq2/zc706 project?

    Thank you.

    Best Regards,

    Dan

  • Hi,

    As of now I do not have zc706 hardware with me. So i tried building for kc705 + fmcdaq2.
    I could build project and boot it on kc705.

    I could observe AD9680 on IIO scope but could not find any waveforms in capture

    In dts file I could not find include for XCVR_REFCLK_DIV1 so edit was follows
    ""
    axi_ad9680_adxcvr: axi-ad9680-adxcvr@44a50000 {
    compatible = "adi,axi-adxcvr-1.0";
    reg = <0x44a50000 0x10000>;

    clocks = <&clk0_ad9523 4>;
    clock-names = "conv";

    adi,sys-clk-select = <XCVR_CPLL>;

    adi,out-clk-select = <XCVR_REFCLK>;
    adi,use-lpm-enable;
    adi,vco-max-khz = <5000000>;
    ""

    I am also attaching boot-up print Linux print


    "jesd204: found 0 devices and 0 topologies" which I have not seen in working versions

    Attachments

    xdc file
    top file
    Linux boot-up print
    dts

    Attachment.rar

  • I attached ILA to util_adcfifo adc_wr data and adc_wr in ILA I could not trigger for adc_wr or adc valid 

    when probed for clock freq I got 

    device_clock = 31.25MHz  i guess it should be 62.5MHz

    Link clock = 250MHz i guess it should be 125 MHz

    I guess In system_top.v

    IBUFDS_GTE2 i_ibufds_tx_ref_clk (
    .CEB (1'd0),
    .I (tx_ref_clk_p),
    .IB (tx_ref_clk_n),
    .O (),
    .ODIV2 (device_clk));

    Could be the issue

    in case of link clock I may have to edit dts for div2

  • I changed 

    device_clk generation in system_top.v to

    IBUFDS_GTE2 i_ibufds_tx_ref_clk (
    .CEB (1'd0),
    .I (tx_ref_clk_p),
    .IB (tx_ref_clk_n),
    .O (device_clk),
    .ODIV2 ());

    in dts

    maintained 

    adi,sys-clk-select = <XCVR_CPLL>;
    adi,out-clk-select = <XCVR_REFCLK_DIV2>;

    Once these changes made

    device_clk = 62.5MHz

    link_clk = 125MHz

    In ILA attached there is still  no data 

  • I guess when I read 

    0x570 register for AD9680 using IIO . it  has a value 0f 0x88 (default configuration)

    This shows 

    L= 4 expected 2

    M = 2 expected 8

    F = 1 expected 8

    So AD9680 may not be configured properly . How to do this??

    While building linux kernel I has used Vivado SDK 2019.1? Will that be the problem

    I also tried capturing data from util_xcvr_rxdata which showed a constant value 

  • Attaching

    scripts/kconfig/conf  --syncconfig Kconfig
      CC      scripts/mod/empty.o
      MKELF   scripts/mod/elfconfig.h
      HOSTCC  scripts/mod/modpost.o
      CC      scripts/mod/devicetable-offsets.s
      HOSTCC  scripts/mod/file2alias.o
      HOSTCC  scripts/mod/sumversion.o
      HOSTLD  scripts/mod/modpost
      CC      kernel/bounds.s
      CC      arch/microblaze/kernel/asm-offsets.s
      CALL    scripts/checksyscalls.sh
      CALL    scripts/atomic/check-atomics.sh
      CC      init/main.o
      CHK     include/generated/compile.h
      UPD     include/generated/compile.h
      CC      init/version.o
      CC      init/do_mounts.o
      CC      init/do_mounts_rd.o
      CC      init/do_mounts_initrd.o
      CC      init/initramfs.o
      CC      init/calibrate.o
      CC      init/init_task.o
      AR      init/built-in.a
      AS      usr/initramfs_data.o
      AR      usr/built-in.a
      CC      arch/microblaze/kernel/dma.o
      CC      arch/microblaze/kernel/exceptions.o
      AS      arch/microblaze/kernel/hw_exception_handler.o
      CC      arch/microblaze/kernel/irq.o
      CC      arch/microblaze/kernel/process.o
      CC      arch/microblaze/kernel/prom.o
      CC      arch/microblaze/kernel/ptrace.o
      CC      arch/microblaze/kernel/reset.o
      CC      arch/microblaze/kernel/setup.o
      CC      arch/microblaze/kernel/signal.o
      CC      arch/microblaze/kernel/sys_microblaze.o
      CC      arch/microblaze/kernel/timer.o
      CC      arch/microblaze/kernel/traps.o
      CC      arch/microblaze/kernel/unwind.o
      CC      arch/microblaze/kernel/cpu/cache.o
      CC      arch/microblaze/kernel/cpu/cpuinfo.o
      CC      arch/microblaze/kernel/cpu/cpuinfo-pvr-full.o
      CC      arch/microblaze/kernel/cpu/cpuinfo-static.o
      CC      arch/microblaze/kernel/cpu/mb.o
      CC      arch/microblaze/kernel/cpu/pvr.o
      AR      arch/microblaze/kernel/cpu/built-in.a
      CC      arch/microblaze/kernel/microblaze_ksyms.o
      CC      arch/microblaze/kernel/module.o
      AS      arch/microblaze/kernel/misc.o
      AS      arch/microblaze/kernel/entry.o
      AR      arch/microblaze/kernel/built-in.a
      AS      arch/microblaze/kernel/head.o
      LDS     arch/microblaze/kernel/vmlinux.lds
      CC      arch/microblaze/mm/consistent.o
      CC      arch/microblaze/mm/init.o
      CC      arch/microblaze/mm/pgtable.o
      CC      arch/microblaze/mm/mmu_context.o
      CC      arch/microblaze/mm/fault.o
      CC      arch/microblaze/mm/highmem.o
      AR      arch/microblaze/mm/built-in.a
      CC      arch/microblaze/pci/pci-common.o
      CC      arch/microblaze/pci/indirect_pci.o
      CC      arch/microblaze/pci/iomap.o
      CC      arch/microblaze/pci/xilinx_pci.o
      AR      arch/microblaze/pci/built-in.a
      DTC     arch/microblaze/boot/dts/kc705_fmcdaq2_ddc.dtb
    arch/microblaze/boot/dts/kc705.dtsi:406.34-419.5: Warning (spi_bus_bridge): /amba_pl/axi_quad_spi@44a70000: node name for SPI buses should be 'spi'
      also defined at arch/microblaze/boot/dts/adi-daq2.dtsi:2.10-137.3
    arch/microblaze/boot/dts/kc705_fmcdaq2_ddc.dtb: Warning (spi_bus_reg): Failed prerequisite 'spi_bus_bridge'
      SHIPPED arch/microblaze/boot/dts/system.dtb
      AS      arch/microblaze/boot/dts/linked_dtb.o
      AR      arch/microblaze/boot/dts/built-in.a
      CC      kernel/fork.o
      CC      kernel/exec_domain.o
      CC      kernel/panic.o
      CC      kernel/cpu.o
      CC      kernel/exit.o
      CC      kernel/softirq.o
      CC      kernel/resource.o
      CC      kernel/sysctl.o
      CC      kernel/sysctl_binary.o
      CC      kernel/capability.o
      CC      kernel/ptrace.o
      CC      kernel/user.o
      CC      kernel/signal.o
      CC      kernel/sys.o
      CC      kernel/umh.o
      CC      kernel/workqueue.o
      CC      kernel/pid.o
      CC      kernel/task_work.o
      CC      kernel/extable.o
      CC      kernel/params.o
      CC      kernel/kthread.o
      CC      kernel/sys_ni.o
      CC      kernel/nsproxy.o
      CC      kernel/notifier.o
      CC      kernel/ksysfs.o
      CC      kernel/cred.o
      CC      kernel/reboot.o
      CC      kernel/async.o
      CC      kernel/range.o
      CC      kernel/smpboot.o
      CC      kernel/ucount.o
      CC      kernel/kmod.o
      CC      kernel/groups.o
      CC      kernel/bpf/core.o
      AR      kernel/bpf/built-in.a
      CC      kernel/dma/mapping.o
      CC      kernel/dma/direct.o
      CC      kernel/dma/dummy.o
      CC      kernel/dma/contiguous.o
      CC      kernel/dma/coherent.o
      CC      kernel/dma/remap.o
      AR      kernel/dma/built-in.a
      CC      kernel/irq/irqdesc.o
      CC      kernel/irq/handle.o
      CC      kernel/irq/manage.o
      CC      kernel/irq/spurious.o
      CC      kernel/irq/resend.o
      CC      kernel/irq/chip.o
      CC      kernel/irq/dummychip.o
      CC      kernel/irq/devres.o
      CC      kernel/irq/autoprobe.o
      CC      kernel/irq/irqdomain.o
      CC      kernel/irq/proc.o
      AR      kernel/irq/built-in.a
      CC      kernel/locking/mutex.o
      CC      kernel/locking/semaphore.o
      CC      kernel/locking/rwsem.o
      CC      kernel/locking/percpu-rwsem.o
      CC      kernel/locking/rtmutex.o
      CC      kernel/locking/spinlock.o
      CC      kernel/locking/spinlock_debug.o
      AR      kernel/locking/built-in.a
      CC      kernel/power/qos.o
      AR      kernel/power/built-in.a
      CC      kernel/printk/printk.o
      CC      kernel/printk/printk_safe.o
      AR      kernel/printk/built-in.a
      CC      kernel/rcu/update.o
      CC      kernel/rcu/sync.o
      CC      kernel/rcu/srcutiny.o
      CC      kernel/rcu/tiny.o
      AR      kernel/rcu/built-in.a
      CC      kernel/sched/core.o
      CC      kernel/sched/loadavg.o
      CC      kernel/sched/clock.o
      CC      kernel/sched/cputime.o
      CC      kernel/sched/idle.o
      CC      kernel/sched/fair.o
      CC      kernel/sched/rt.o
      CC      kernel/sched/deadline.o
      CC      kernel/sched/wait.o
      CC      kernel/sched/wait_bit.o
      CC      kernel/sched/swait.o
      CC      kernel/sched/completion.o
      CC      kernel/sched/debug.o
      CC      kernel/sched/membarrier.o
      AR      kernel/sched/built-in.a
      CC      kernel/time/time.o
      CC      kernel/time/timer.o
      CC      kernel/time/hrtimer.o
      CC      kernel/time/timekeeping.o
      CC      kernel/time/ntp.o
      CC      kernel/time/clocksource.o
      CC      kernel/time/jiffies.o
      CC      kernel/time/timer_list.o
      CC      kernel/time/timeconv.o
      CC      kernel/time/timecounter.o
      CC      kernel/time/alarmtimer.o
      CC      kernel/time/posix-timers.o
      CC      kernel/time/posix-cpu-timers.o
      CC      kernel/time/posix-clock.o
      CC      kernel/time/itimer.o
      CC      kernel/time/clockevents.o
      CC      kernel/time/tick-common.o
      CC      kernel/time/sched_clock.o
      CC      kernel/time/tick-oneshot.o
      CC      kernel/time/tick-sched.o
      CC      kernel/time/timekeeping_debug.o
      AR      kernel/time/built-in.a
      CC      kernel/futex.o
      CC      kernel/up.o
      CC      kernel/module.o
      CC      kernel/kallsyms.o
      GZIP    kernel/config_data.gz
      CC      kernel/configs.o
      CC      kernel/hung_task.o
      CC      kernel/utsname_sysctl.o
      CC      kernel/elfcore.o
      CC      kernel/irq_work.o
      CC      kernel/iomem.o
      AR      kernel/built-in.a
      CC      mm/filemap.o
      CC      mm/mempool.o
      CC      mm/oom_kill.o
      CC      mm/fadvise.o
      CC      mm/maccess.o
      CC      mm/page-writeback.o
      CC      mm/readahead.o
      CC      mm/swap.o
      CC      mm/truncate.o
      CC      mm/vmscan.o
      CC      mm/shmem.o
      CC      mm/util.o
      CC      mm/mmzone.o
      CC      mm/vmstat.o
      CC      mm/backing-dev.o
      CC      mm/mm_init.o
      CC      mm/mmu_context.o
      CC      mm/percpu.o
      CC      mm/slab_common.o
      CC      mm/compaction.o
      CC      mm/vmacache.o
      CC      mm/interval_tree.o
      CC      mm/list_lru.o
      CC      mm/workingset.o
      CC      mm/debug.o
      CC      mm/gup.o
      CC      mm/highmem.o
      CC      mm/memory.o
      CC      mm/mincore.o
      CC      mm/mlock.o
      CC      mm/mmap.o
      CC      mm/mmu_gather.o
      CC      mm/mprotect.o
      CC      mm/mremap.o
      CC      mm/msync.o
      CC      mm/page_vma_mapped.o
      CC      mm/pagewalk.o
      CC      mm/pgtable-generic.o
      CC      mm/rmap.o
      CC      mm/vmalloc.o
      CC      mm/process_vm_access.o
      CC      mm/page_alloc.o
      CC      mm/init-mm.o
      CC      mm/memblock.o
      CC      mm/madvise.o
      CC      mm/dmapool.o
      CC      mm/slab.o
      CC      mm/migrate.o
      CC      mm/page_isolation.o
      CC      mm/cma.o
      CC      mm/memfd.o
      AR      mm/built-in.a
      CC      fs/open.o
      CC      fs/read_write.o
      CC      fs/file_table.o
      CC      fs/super.o
      CC      fs/char_dev.o
      CC      fs/stat.o
      CC      fs/exec.o
      CC      fs/pipe.o
      CC      fs/namei.o
      CC      fs/fcntl.o
      CC      fs/ioctl.o
      CC      fs/readdir.o
      CC      fs/select.o
      CC      fs/dcache.o
      CC      fs/inode.o
      CC      fs/attr.o
      CC      fs/bad_inode.o
      CC      fs/file.o
      CC      fs/filesystems.o
      CC      fs/namespace.o
      CC      fs/seq_file.o
      CC      fs/xattr.o
      CC      fs/libfs.o
      CC      fs/fs-writeback.o
      CC      fs/pnode.o
      CC      fs/splice.o
      CC      fs/sync.o
      CC      fs/utimes.o
      CC      fs/d_path.o
      CC      fs/stack.o
      CC      fs/fs_struct.o
      CC      fs/statfs.o
      CC      fs/fs_pin.o
      CC      fs/nsfs.o
      CC      fs/fs_types.o
      CC      fs/fs_context.o
      CC      fs/fs_parser.o
      CC      fs/fsopen.o
      CC      fs/buffer.o
      CC      fs/block_dev.o
      CC      fs/direct-io.o
      CC      fs/mpage.o
      CC      fs/proc_namespace.o
      CC      fs/cifs/trace.o
      CC      fs/cifs/cifsfs.o
      CC      fs/cifs/cifssmb.o
      CC      fs/cifs/cifs_debug.o
      CC      fs/cifs/connect.o
      CC      fs/cifs/dir.o
      CC      fs/cifs/file.o
      CC      fs/cifs/inode.o
      CC      fs/cifs/link.o
      CC      fs/cifs/misc.o
      CC      fs/cifs/netmisc.o
      CC      fs/cifs/smbencrypt.o
      CC      fs/cifs/transport.o
      CC      fs/cifs/asn1.o
      CC      fs/cifs/cifs_unicode.o
      CC      fs/cifs/nterr.o
      CC      fs/cifs/cifsencrypt.o
      CC      fs/cifs/readdir.o
      CC      fs/cifs/ioctl.o
      CC      fs/cifs/sess.o
      CC      fs/cifs/export.o
      CC      fs/cifs/smb1ops.o
      CC      fs/cifs/winucase.o
      CC      fs/cifs/smb2ops.o
      CC      fs/cifs/smb2maperror.o
      CC      fs/cifs/smb2transport.o
      CC      fs/cifs/smb2misc.o
      CC      fs/cifs/smb2pdu.o
      CC      fs/cifs/smb2inode.o
      CC      fs/cifs/smb2file.o
      CC      fs/cifs/cifsacl.o
      AR      fs/cifs/built-in.a
      CC      fs/cramfs/inode.o
      CC      fs/cramfs/uncompress.o
      AR      fs/cramfs/built-in.a
      CC      fs/debugfs/inode.o
      CC      fs/debugfs/file.o
      AR      fs/debugfs/built-in.a
      CC      fs/devpts/inode.o
      AR      fs/devpts/built-in.a
      CC      fs/exportfs/expfs.o
      AR      fs/exportfs/built-in.a
      CC      fs/ext2/balloc.o
      CC      fs/ext2/dir.o
      CC      fs/ext2/file.o
      CC      fs/ext2/ialloc.o
      CC      fs/ext2/inode.o
      CC      fs/ext2/ioctl.o
      CC      fs/ext2/namei.o
      CC      fs/ext2/super.o
      CC      fs/ext2/symlink.o
      CC      fs/ext2/xattr.o
      CC      fs/ext2/xattr_user.o
      CC      fs/ext2/xattr_trusted.o
      CC      fs/ext2/acl.o
      CC      fs/ext2/xattr_security.o
      AR      fs/ext2/built-in.a
      CC      fs/ext4/balloc.o
      CC      fs/ext4/bitmap.o
      CC      fs/ext4/block_validity.o
      CC      fs/ext4/dir.o
      CC      fs/ext4/ext4_jbd2.o
      CC      fs/ext4/extents.o
      CC      fs/ext4/extents_status.o
      CC      fs/ext4/file.o
      CC      fs/ext4/fsmap.o
      CC      fs/ext4/fsync.o
      CC      fs/ext4/hash.o
      CC      fs/ext4/ialloc.o
      CC      fs/ext4/indirect.o
      CC      fs/ext4/inline.o
      CC      fs/ext4/inode.o
      CC      fs/ext4/ioctl.o
      CC      fs/ext4/mballoc.o
      CC      fs/ext4/migrate.o
      CC      fs/ext4/mmp.o
      CC      fs/ext4/move_extent.o
      CC      fs/ext4/namei.o
      CC      fs/ext4/page-io.o
      CC      fs/ext4/readpage.o
      CC      fs/ext4/resize.o
      CC      fs/ext4/super.o
      CC      fs/ext4/symlink.o
      CC      fs/ext4/sysfs.o
      CC      fs/ext4/xattr.o
      CC      fs/ext4/xattr_trusted.o
      CC      fs/ext4/xattr_user.o
      CC      fs/ext4/acl.o
      CC      fs/ext4/xattr_security.o
      AR      fs/ext4/built-in.a
      CC      fs/iomap/apply.o
      CC      fs/iomap/buffered-io.o
      CC      fs/iomap/direct-io.o
      CC      fs/iomap/fiemap.o
      CC      fs/iomap/seek.o
      AR      fs/iomap/built-in.a
      CC      fs/jbd2/transaction.o
      CC      fs/jbd2/commit.o
      CC      fs/jbd2/recovery.o
      CC      fs/jbd2/checkpoint.o
      CC      fs/jbd2/revoke.o
      CC      fs/jbd2/journal.o
      AR      fs/jbd2/built-in.a
      CC      fs/jffs2/compr.o
      CC      fs/jffs2/dir.o
      CC      fs/jffs2/file.o
      CC      fs/jffs2/ioctl.o
      CC      fs/jffs2/nodelist.o
      CC      fs/jffs2/malloc.o
      CC      fs/jffs2/read.o
      CC      fs/jffs2/nodemgmt.o
      CC      fs/jffs2/readinode.o
      CC      fs/jffs2/write.o
      CC      fs/jffs2/scan.o
      CC      fs/jffs2/gc.o
      CC      fs/jffs2/symlink.o
      CC      fs/jffs2/build.o
      CC      fs/jffs2/erase.o
      CC      fs/jffs2/background.o
      CC      fs/jffs2/fs.o
      CC      fs/jffs2/writev.o
      CC      fs/jffs2/super.o
      CC      fs/jffs2/debug.o
      CC      fs/jffs2/wbuf.o
      CC      fs/jffs2/compr_rtime.o
      CC      fs/jffs2/compr_zlib.o
      CC      fs/jffs2/summary.o
      AR      fs/jffs2/built-in.a
      CC      fs/kernfs/mount.o
      CC      fs/kernfs/inode.o
      CC      fs/kernfs/dir.o
      CC      fs/kernfs/file.o
      CC      fs/kernfs/symlink.o
      AR      fs/kernfs/built-in.a
      CC      fs/lockd/clntlock.o
      CC      fs/lockd/clntproc.o
      CC      fs/lockd/clntxdr.o
      CC      fs/lockd/host.o
      CC      fs/lockd/svc.o
      CC      fs/lockd/svclock.o
      CC      fs/lockd/svcshare.o
      CC      fs/lockd/svcproc.o
      CC      fs/lockd/svcsubs.o
      CC      fs/lockd/mon.o
      CC      fs/lockd/xdr.o
      CC      fs/lockd/clnt4xdr.o
      CC      fs/lockd/xdr4.o
      CC      fs/lockd/svc4proc.o
      CC      fs/lockd/procfs.o
      AR      fs/lockd/built-in.a
      CC      fs/nfs/client.o
      CC      fs/nfs/dir.o
      CC      fs/nfs/file.o
      CC      fs/nfs/getroot.o
      CC      fs/nfs/inode.o
      CC      fs/nfs/super.o
      CC      fs/nfs/io.o
      CC      fs/nfs/direct.o
      CC      fs/nfs/pagelist.o
      CC      fs/nfs/read.o
      CC      fs/nfs/symlink.o
      CC      fs/nfs/unlink.o
      CC      fs/nfs/write.o
      CC      fs/nfs/namespace.o
      CC      fs/nfs/mount_clnt.o
      CC      fs/nfs/nfstrace.o
      CC      fs/nfs/export.o
      CC      fs/nfs/sysfs.o
      CC      fs/nfs/sysctl.o
      CC      fs/nfs/nfs2super.o
      CC      fs/nfs/proc.o
      CC      fs/nfs/nfs2xdr.o
      CC      fs/nfs/nfs3super.o
      CC      fs/nfs/nfs3client.o
      CC      fs/nfs/nfs3proc.o
      CC      fs/nfs/nfs3xdr.o
      AR      fs/nfs/built-in.a
      CC      fs/nfs_common/grace.o
      AR      fs/nfs_common/built-in.a
      CC      fs/nls/nls_base.o
      AR      fs/nls/built-in.a
      CC      fs/notify/fsnotify.o
      CC      fs/notify/notification.o
      CC      fs/notify/group.o
      CC      fs/notify/mark.o
      CC      fs/notify/fdinfo.o
      CC      fs/notify/inotify/inotify_fsnotify.o
      CC      fs/notify/inotify/inotify_user.o
      AR      fs/notify/inotify/built-in.a
      AR      fs/notify/built-in.a
      CC      fs/proc/task_mmu.o
      CC      fs/proc/inode.o
      CC      fs/proc/root.o
      CC      fs/proc/base.o
      CC      fs/proc/generic.o
      CC      fs/proc/array.o
      CC      fs/proc/fd.o
      CC      fs/proc/proc_tty.o
      CC      fs/proc/cmdline.o
      CC      fs/proc/consoles.o
      CC      fs/proc/cpuinfo.o
      CC      fs/proc/devices.o
      CC      fs/proc/interrupts.o
      CC      fs/proc/loadavg.o
      CC      fs/proc/meminfo.o
      CC      fs/proc/stat.o
      CC      fs/proc/uptime.o
      CC      fs/proc/util.o
      CC      fs/proc/version.o
      CC      fs/proc/softirqs.o
      CC      fs/proc/namespaces.o
      CC      fs/proc/self.o
      CC      fs/proc/thread_self.o
      CC      fs/proc/proc_sysctl.o
      CC      fs/proc/proc_net.o
      CC      fs/proc/kmsg.o
      CC      fs/proc/page.o
      AR      fs/proc/built-in.a
      CC      fs/ramfs/inode.o
      CC      fs/ramfs/file-mmu.o
      AR      fs/ramfs/built-in.a
      CC      fs/romfs/storage.o
      CC      fs/romfs/super.o
      AR      fs/romfs/built-in.a
      CC      fs/sysfs/file.o
      CC      fs/sysfs/dir.o
      CC      fs/sysfs/symlink.o
      CC      fs/sysfs/mount.o
      CC      fs/sysfs/group.o
      AR      fs/sysfs/built-in.a
      CC      fs/eventpoll.o
      CC      fs/anon_inodes.o
      CC      fs/signalfd.o
      CC      fs/timerfd.o
      CC      fs/eventfd.o
      CC      fs/aio.o
      CC      fs/io_uring.o
      CC      fs/locks.o
      CC      fs/binfmt_misc.o
      CC      fs/binfmt_script.o
      CC      fs/binfmt_elf.o
      CC      fs/mbcache.o
      CC      fs/posix_acl.o
      CC      fs/coredump.o
      CC      fs/drop_caches.o
      CC      fs/fhandle.o
      AR      fs/built-in.a
      CC      ipc/util.o
      CC      ipc/msgutil.o
      CC      ipc/msg.o
      CC      ipc/sem.o
      CC      ipc/shm.o
      CC      ipc/syscall.o
      CC      ipc/ipc_sysctl.o
      CC      ipc/mqueue.o
      CC      ipc/mq_sysctl.o
      AR      ipc/built-in.a
      CC      security/keys/gc.o
      CC      security/keys/key.o
      CC      security/keys/keyring.o
      CC      security/keys/keyctl.o
      CC      security/keys/permission.o
      CC      security/keys/process_keys.o
      CC      security/keys/request_key.o
      CC      security/keys/request_key_auth.o
      CC      security/keys/user_defined.o
      CC      security/keys/proc.o
      CC      security/keys/sysctl.o
      CC      security/keys/encrypted-keys/encrypted.o
      CC      security/keys/encrypted-keys/ecryptfs_format.o
      AR      security/keys/encrypted-keys/built-in.a
      AR      security/keys/built-in.a
      CC      security/commoncap.o
      CC      security/min_addr.o
      AR      security/built-in.a
      CC      crypto/api.o
      CC      crypto/cipher.o
      CC      crypto/compress.o
      CC      crypto/memneq.o
      CC      crypto/algapi.o
      CC      crypto/scatterwalk.o
      CC      crypto/proc.o
      CC      crypto/aead.o
      CC      crypto/ablkcipher.o
      CC      crypto/blkcipher.o
      CC      crypto/skcipher.o
      CC      crypto/seqiv.o
      CC      crypto/ahash.o
      CC      crypto/shash.o
      CC      crypto/akcipher.o
      CC      crypto/kpp.o
      CC      crypto/acompress.o
      CC      crypto/scompress.o
      CC      crypto/algboss.o
      CC      crypto/testmgr.o
      CC      crypto/cmac.o
      CC      crypto/hmac.o
      CC      crypto/crypto_null.o
      CC      crypto/md4.o
      CC      crypto/md5.o
      CC      crypto/sha256_generic.o
      CC      crypto/sha512_generic.o
      CC      crypto/gf128mul.o
      CC      crypto/ecb.o
      CC      crypto/cbc.o
      CC      crypto/ctr.o
      CC      crypto/gcm.o
      CC      crypto/ccm.o
      CC      crypto/aes_generic.o
      CC      crypto/crc32c_generic.o
      CC      crypto/rng.o
      CC      crypto/drbg.o
      CC      crypto/jitterentropy.o
      CC      crypto/jitterentropy-kcapi.o
      CC      crypto/ghash-generic.o
      AR      crypto/built-in.a
      CC      block/bio.o
      CC      block/elevator.o
      CC      block/blk-core.o
      CC      block/blk-sysfs.o
      CC      block/blk-flush.o
      CC      block/blk-settings.o
      CC      block/blk-ioc.o
      CC      block/blk-map.o
      CC      block/blk-exec.o
      CC      block/blk-merge.o
      CC      block/blk-softirq.o
      CC      block/blk-timeout.o
      CC      block/blk-lib.o
      CC      block/blk-mq.o
      CC      block/blk-mq-tag.o
      CC      block/blk-stat.o
      CC      block/blk-mq-sysfs.o
      CC      block/blk-mq-cpumap.o
      CC      block/blk-mq-sched.o
      CC      block/ioctl.o
      CC      block/genhd.o
      CC      block/partition-generic.o
      CC      block/ioprio.o
      CC      block/badblocks.o
      CC      block/partitions/check.o
      CC      block/partitions/msdos.o
      AR      block/partitions/built-in.a
      CC      block/blk-rq-qos.o
      CC      block/bounce.o
      CC      block/mq-deadline.o
      CC      block/kyber-iosched.o
      CC      block/blk-mq-pci.o
      CC      block/blk-mq-debugfs.o
      AR      block/built-in.a
      CC      drivers/base/component.o
      CC      drivers/base/core.o
      CC      drivers/base/bus.o
      CC      drivers/base/dd.o
      CC      drivers/base/syscore.o
      CC      drivers/base/driver.o
      CC      drivers/base/class.o
      CC      drivers/base/platform.o
      CC      drivers/base/cpu.o
      CC      drivers/base/firmware.o
      CC      drivers/base/init.o
      CC      drivers/base/map.o
      CC      drivers/base/devres.o
      CC      drivers/base/attribute_container.o
      CC      drivers/base/transport_class.o
      CC      drivers/base/topology.o
      CC      drivers/base/container.o
      CC      drivers/base/property.o
      CC      drivers/base/cacheinfo.o
      CC      drivers/base/devcon.o
      CC      drivers/base/swnode.o
      CC      drivers/base/devtmpfs.o
      CC      drivers/base/firmware_loader/main.o
      AS      drivers/base/firmware_loader/builtin/ad9467_intbypass_ad9517.stp.gen.o
      AS      drivers/base/firmware_loader/builtin/ad9517.stp.gen.o
      AS      drivers/base/firmware_loader/builtin/Mykonos_M3.bin.gen.o
      AR      drivers/base/firmware_loader/builtin/built-in.a
      AR      drivers/base/firmware_loader/built-in.a
      CC      drivers/base/power/clock_ops.o
      AR      drivers/base/power/built-in.a
      CC      drivers/base/regmap/regmap.o
      CC      drivers/base/regmap/regcache.o
      CC      drivers/base/regmap/regcache-rbtree.o
      CC      drivers/base/regmap/regcache-flat.o
      CC      drivers/base/regmap/regmap-debugfs.o
      CC      drivers/base/regmap/regmap-i2c.o
      CC      drivers/base/regmap/regmap-spi.o
      CC      drivers/base/regmap/regmap-mmio.o
      AR      drivers/base/regmap/built-in.a
      CC      drivers/base/module.o
      AR      drivers/base/built-in.a
      CC      drivers/block/brd.o
      CC      drivers/block/xsysace.o
      AR      drivers/block/built-in.a
      CC      drivers/char/mem.o
      CC      drivers/char/random.o
      CC      drivers/char/misc.o
      CC      drivers/char/xilinx_hwicap/xilinx_hwicap.o
      CC      drivers/char/xilinx_hwicap/fifo_icap.o
      CC      drivers/char/xilinx_hwicap/buffer_icap.o
      AR      drivers/char/xilinx_hwicap/built-in.a
      AR      drivers/char/built-in.a
      CC      drivers/clk/clk-devres.o
      CC      drivers/clk/clk-bulk.o
      CC      drivers/clk/clkdev.o
      CC      drivers/clk/clk.o
      CC      drivers/clk/clk-divider.o
      CC      drivers/clk/clk-fixed-factor.o
      CC      drivers/clk/clk-fixed-rate.o
      CC      drivers/clk/clk-adjustable-rate.o
      CC      drivers/clk/clk-gate.o
      CC      drivers/clk/clk-multiplier.o
      CC      drivers/clk/clk-mux.o
      CC      drivers/clk/clk-composite.o
      CC      drivers/clk/clk-fractional-divider.o
      CC      drivers/clk/clk-gpio.o
      CC      drivers/clk/clk-conf.o
      CC      drivers/clk/clk-axi-clkgen.o
      AR      drivers/clk/built-in.a
      CC      drivers/clocksource/timer-of.o
      CC      drivers/clocksource/timer-probe.o
      AR      drivers/clocksource/built-in.a
      CC      drivers/dma/dmaengine.o
      CC      drivers/dma/virt-dma.o
      CC      drivers/dma/of-dma.o
      CC      drivers/dma/dma-axi-dmac.o
      AR      drivers/dma/built-in.a
      CC      drivers/gpio/gpiolib.o
      CC      drivers/gpio/gpiolib-devres.o
      CC      drivers/gpio/gpiolib-legacy.o
      CC      drivers/gpio/gpiolib-devprop.o
      CC      drivers/gpio/gpiolib-of.o
      CC      drivers/gpio/gpiolib-sysfs.o
      CC      drivers/gpio/gpio-xilinx.o
      AR      drivers/gpio/built-in.a
      CC      drivers/gpu/vga/vgaarb.o
      AR      drivers/gpu/vga/built-in.a
      AR      drivers/gpu/built-in.a
      CC      drivers/i2c/i2c-boardinfo.o
      CC      drivers/i2c/i2c-core-base.o
      CC      drivers/i2c/i2c-core-smbus.o
      CC      drivers/i2c/i2c-core-of.o
      CC      drivers/i2c/i2c-dev.o
      CC      drivers/i2c/i2c-mux.o
      CC      drivers/i2c/busses/i2c-xiic.o
      AR      drivers/i2c/busses/built-in.a
      CC      drivers/i2c/muxes/i2c-mux-pca954x.o
      AR      drivers/i2c/muxes/built-in.a
      AR      drivers/i2c/built-in.a
      CC      drivers/iio/industrialio-core.o
      CC      drivers/iio/industrialio-event.o
      CC      drivers/iio/inkern.o
      CC      drivers/iio/industrialio-buffer.o
      CC      drivers/iio/adc/ad6676.o
      CC      drivers/iio/adc/ad7291.o
      CC      drivers/iio/adc/adm1177.o
      CC      drivers/iio/adc/cf_axi_adc_core.o
      CC      drivers/iio/adc/ad9208.o
      CC      drivers/iio/adc/ad9208/ad9208_adc_api.o
      CC      drivers/iio/adc/ad9208/ad9208_api.o
      CC      drivers/iio/adc/ad9208/ad9208_jesd_api.o
      CC      drivers/iio/adc/ad9208/ad9208_reg.o
      CC      drivers/iio/adc/ad9208/ad9208_signal_monitor_api.o
      CC      drivers/iio/adc/ad9081.o
      CC      drivers/iio/adc/ad9081/adi_ad9081_adc.o
      CC      drivers/iio/adc/ad9081/adi_ad9081_device.o
      CC      drivers/iio/adc/ad9081/adi_ad9081_jesd.o
      CC      drivers/iio/adc/ad9081/adi_ad9081_hal.o
      CC      drivers/iio/adc/ad9081/adi_ad9081_dac.o
      CC      drivers/iio/adc/ad9083.o
      CC      drivers/iio/adc/ad9083/adi_ad9083_device.o
      CC      drivers/iio/adc/ad9083/adi_ad9083_hal.o
      CC      drivers/iio/adc/ad9083/adi_ad9083_jesd.o
      CC      drivers/iio/adc/ad9083/adi_ad9083_rx.o
      CC      drivers/iio/adc/ad9361.o
      CC      drivers/iio/adc/ad9361_conv.o
      CC      drivers/iio/adc/ad9371.o
      CC      drivers/iio/adc/ad9371_conv.o
      CC      drivers/iio/adc/mykonos/common.o
      CC      drivers/iio/adc/mykonos/mykonos.o
      CC      drivers/iio/adc/mykonos/mykonos_gpio.o
      CC      drivers/iio/adc/mykonos/mykonos_user.o
      CC      drivers/iio/adc/ad9467.o
      CC      drivers/iio/adc/ad9680.o
      CC      drivers/iio/adc/admc_adc.o
      CC      drivers/iio/adc/admc_speed.o
      CC      drivers/iio/adc/admc_ctrl.o
      CC      drivers/iio/adc/ad_adc.o
      CC      drivers/iio/adc/axi_fmcadc5_sync.o
      AR      drivers/iio/adc/built-in.a
      CC      drivers/iio/addac/one-bit-adc-dac.o
      AR      drivers/iio/addac/built-in.a
      CC      drivers/iio/amplifiers/ad8366.o
      CC      drivers/iio/amplifiers/hmc425a.o
      AR      drivers/iio/amplifiers/built-in.a
      CC      drivers/iio/buffer/industrialio-buffer-dma.o
      CC      drivers/iio/buffer/industrialio-buffer-dmaengine.o
      CC      drivers/iio/buffer/industrialio-hw-consumer.o
      CC      drivers/iio/buffer/kfifo_buf.o
      AR      drivers/iio/buffer/built-in.a
      CC      drivers/iio/dac/ad5446.o
      CC      drivers/iio/dac/ad5592r-base.o
      CC      drivers/iio/dac/ad5592r.o
      CC      drivers/iio/dac/ad5593r.o
      AR      drivers/iio/dac/built-in.a
      CC      drivers/iio/frequency/ad9517.o
      CC      drivers/iio/frequency/ad9523.o
      CC      drivers/iio/frequency/ad9528.o
      CC      drivers/iio/frequency/ad9548.o
      CC      drivers/iio/frequency/adf4350.o
      CC      drivers/iio/frequency/adf4371.o
      CC      drivers/iio/frequency/adf5355.o
      CC      drivers/iio/frequency/cf_axi_dds.o
      CC      drivers/iio/frequency/cf_axi_dds_buffer_stream.o
      CC      drivers/iio/frequency/ad9122.o
      CC      drivers/iio/frequency/ad9144.o
      CC      drivers/iio/frequency/ad9739a.o
      CC      drivers/iio/frequency/hmc7044.o
      AR      drivers/iio/frequency/built-in.a
      CC      drivers/iio/jesd204/axi_adxcvr.o
      CC      drivers/iio/jesd204/axi_adxcvr_eyescan.o
      CC      drivers/iio/jesd204/axi_jesd204b_v51.o
      CC      drivers/iio/jesd204/axi_jesd204b_gt.o
      CC      drivers/iio/jesd204/axi_jesd204_rx.o
      CC      drivers/iio/jesd204/axi_jesd204_tx.o
      CC      drivers/iio/jesd204/xilinx_transceiver.o
      AR      drivers/iio/jesd204/built-in.a
      AR      drivers/iio/built-in.a
      CC      drivers/irqchip/irqchip.o
      CC      drivers/irqchip/irq-xilinx-intc.o
      AR      drivers/irqchip/built-in.a
      CC      drivers/jesd204/jesd204-fsm.o
      CC      drivers/jesd204/jesd204-sysfs.o
      CC      drivers/jesd204/jesd204-core.o
      AR      drivers/jesd204/built-in.a
      CC      drivers/misc/ad525x_dpot.o
      CC      drivers/misc/ad525x_dpot-i2c.o
      CC      drivers/misc/ad525x_dpot-spi.o
      CC      drivers/misc/xilinx_lcd.o
      CC      drivers/misc/eeprom/at24.o
      AR      drivers/misc/eeprom/built-in.a
      AR      drivers/misc/built-in.a
      CC      drivers/mtd/mtdcore.o
      CC      drivers/mtd/mtdsuper.o
      CC      drivers/mtd/mtdconcat.o
      CC      drivers/mtd/mtdpart.o
      CC      drivers/mtd/mtdchar.o
      CC      drivers/mtd/chips/chipreg.o
      CC      drivers/mtd/chips/cfi_probe.o
      CC      drivers/mtd/chips/cfi_util.o
      CC      drivers/mtd/chips/cfi_cmdset_0020.o
      CC      drivers/mtd/chips/cfi_cmdset_0002.o
      CC      drivers/mtd/chips/cfi_cmdset_0001.o
      CC      drivers/mtd/chips/gen_probe.o
      CC      drivers/mtd/chips/jedec_probe.o
      CC      drivers/mtd/chips/map_ram.o
      AR      drivers/mtd/chips/built-in.a
      CC      drivers/mtd/maps/map_funcs.o
      CC      drivers/mtd/maps/physmap-core.o
      AR      drivers/mtd/maps/built-in.a
      CC      drivers/mtd/parsers/cmdlinepart.o
      CC      drivers/mtd/parsers/ofpart.o
      AR      drivers/mtd/parsers/built-in.a
      AR      drivers/mtd/built-in.a
      CC      drivers/net/Space.o
      CC      drivers/net/loopback.o
      CC      drivers/net/ethernet/xilinx/ll_temac_main.o
      CC      drivers/net/ethernet/xilinx/ll_temac_mdio.o
      CC      drivers/net/ethernet/xilinx/xilinx_emaclite.o
      CC      drivers/net/ethernet/xilinx/xilinx_axienet_main.o
      CC      drivers/net/ethernet/xilinx/xilinx_axienet_mdio.o
      CC      drivers/net/ethernet/xilinx/xilinx_axienet_dma.o
      AR      drivers/net/ethernet/xilinx/built-in.a
      AR      drivers/net/ethernet/built-in.a
      CC      drivers/net/phy/mdio-boardinfo.o
      CC      drivers/net/phy/phy.o
      CC      drivers/net/phy/phy-c45.o
      CC      drivers/net/phy/phy-core.o
      CC      drivers/net/phy/phy_device.o
      CC      drivers/net/phy/mdio_bus.o
      CC      drivers/net/phy/mdio_device.o
      CC      drivers/net/phy/swphy.o
      CC      drivers/net/phy/dp83867.o
      CC      drivers/net/phy/fixed_phy.o
      CC      drivers/net/phy/marvell.o
      CC      drivers/net/phy/xilinx_phy.o
      AR      drivers/net/phy/built-in.a
      AR      drivers/net/built-in.a
      CC      drivers/nvmem/core.o
      CC      drivers/nvmem/nvmem-sysfs.o
      CC      drivers/nvmem/adi_axi_sysid.o
      AR      drivers/nvmem/built-in.a
      CC      drivers/of/base.o
      CC      drivers/of/device.o
      CC      drivers/of/platform.o
      CC      drivers/of/property.o
      CC      drivers/of/kobj.o
      CC      drivers/of/fdt.o
      CC      drivers/of/fdt_address.o
      CC      drivers/of/address.o
      CC      drivers/of/irq.o
      CC      drivers/of/of_net.o
      CC      drivers/of/of_mdio.o
      CC      drivers/of/of_reserved_mem.o
      AR      drivers/of/built-in.a
      CC      drivers/pci/access.o
      CC      drivers/pci/bus.o
      CC      drivers/pci/probe.o
      CC      drivers/pci/host-bridge.o
      CC      drivers/pci/remove.o
      CC      drivers/pci/pci.o
      CC      drivers/pci/pci-driver.o
      CC      drivers/pci/search.o
      CC      drivers/pci/pci-sysfs.o
      CC      drivers/pci/rom.o
      CC      drivers/pci/setup-res.o
      CC      drivers/pci/irq.o
      CC      drivers/pci/vpd.o
      CC      drivers/pci/setup-bus.o
      CC      drivers/pci/vc.o
      CC      drivers/pci/mmap.o
      CC      drivers/pci/setup-irq.o
      CC      drivers/pci/proc.o
      CC      drivers/pci/slot.o
      CC      drivers/pci/of.o
      CC      drivers/pci/quirks.o
      CC      drivers/pci/syscall.o
      AR      drivers/pci/built-in.a
      CC      drivers/power/reset/gpio-restart.o
      AR      drivers/power/reset/built-in.a
      AR      drivers/power/built-in.a
      CC      drivers/regulator/core.o
      CC      drivers/regulator/dummy.o
      CC      drivers/regulator/fixed-helper.o
      CC      drivers/regulator/helpers.o
      CC      drivers/regulator/devres.o
      CC      drivers/regulator/of_regulator.o
      CC      drivers/regulator/fixed.o
      AR      drivers/regulator/built-in.a
      CC      drivers/spi/spi.o
      CC      drivers/spi/spidev.o
      CC      drivers/spi/spi-bitbang.o
      CC      drivers/spi/spi-xcomm.o
      CC      drivers/spi/spi-ad9250fmc.o
      CC      drivers/spi/spi-xilinx.o
      AR      drivers/spi/built-in.a
      CC      drivers/tty/tty_io.o
      CC      drivers/tty/n_tty.o
      CC      drivers/tty/tty_ioctl.o
      CC      drivers/tty/tty_ldisc.o
      CC      drivers/tty/tty_buffer.o
      CC      drivers/tty/tty_port.o
      CC      drivers/tty/tty_mutex.o
      CC      drivers/tty/tty_ldsem.o
      CC      drivers/tty/tty_baudrate.o
      CC      drivers/tty/tty_jobctrl.o
      CC      drivers/tty/n_null.o
      CC      drivers/tty/pty.o
      CC      drivers/tty/serial/serial_core.o
      CC      drivers/tty/serial/earlycon.o
      CC      drivers/tty/serial/8250/8250_core.o
      CC      drivers/tty/serial/8250/8250_port.o
      CC      drivers/tty/serial/8250/8250_dma.o
      CC      drivers/tty/serial/8250/8250_pci.o
      CC      drivers/tty/serial/8250/8250_exar.o
      CC      drivers/tty/serial/8250/8250_early.o
      CC      drivers/tty/serial/8250/8250_of.o
      AR      drivers/tty/serial/8250/built-in.a
      CC      drivers/tty/serial/uartlite.o
      CC      drivers/tty/serial/serial_mctrl_gpio.o
      AR      drivers/tty/serial/built-in.a
      AR      drivers/tty/built-in.a
      CC      drivers/watchdog/watchdog_core.o
      CC      drivers/watchdog/watchdog_dev.o
      CC      drivers/watchdog/of_xilinx_wdt.o
      AR      drivers/watchdog/built-in.a
      AR      drivers/built-in.a
      CC      net/socket.o
      CC      net/core/sock.o
      CC      net/core/request_sock.o
      CC      net/core/skbuff.o
      CC      net/core/datagram.o
      CC      net/core/stream.o
      CC      net/core/scm.o
      CC      net/core/gen_stats.o
      CC      net/core/gen_estimator.o
      CC      net/core/net_namespace.o
      CC      net/core/secure_seq.o
      CC      net/core/flow_dissector.o
      CC      net/core/sysctl_net_core.o
      CC      net/core/dev.o
      CC      net/core/ethtool.o
      CC      net/core/dev_addr_lists.o
      CC      net/core/dst.o
      CC      net/core/netevent.o
      CC      net/core/neighbour.o
      CC      net/core/rtnetlink.o
      CC      net/core/utils.o
      CC      net/core/link_watch.o
      CC      net/core/filter.o
      CC      net/core/sock_diag.o
      CC      net/core/dev_ioctl.o
      CC      net/core/tso.o
      CC      net/core/sock_reuseport.o
      CC      net/core/fib_notifier.o
      CC      net/core/xdp.o
      CC      net/core/flow_offload.o
      CC      net/core/net-sysfs.o
      CC      net/core/net-procfs.o
      AR      net/core/built-in.a
      CC      net/ethernet/eth.o
      AR      net/ethernet/built-in.a
      CC      net/ipv4/route.o
      CC      net/ipv4/inetpeer.o
      CC      net/ipv4/protocol.o
      CC      net/ipv4/ip_input.o
      CC      net/ipv4/ip_fragment.o
      CC      net/ipv4/ip_forward.o
      CC      net/ipv4/ip_options.o
      CC      net/ipv4/ip_output.o
      CC      net/ipv4/ip_sockglue.o
      CC      net/ipv4/inet_hashtables.o
      CC      net/ipv4/inet_timewait_sock.o
      CC      net/ipv4/inet_connection_sock.o
      CC      net/ipv4/tcp.o
      CC      net/ipv4/tcp_input.o
      CC      net/ipv4/tcp_output.o
      CC      net/ipv4/tcp_timer.o
      CC      net/ipv4/tcp_ipv4.o
      CC      net/ipv4/tcp_minisocks.o
      CC      net/ipv4/tcp_cong.o
      CC      net/ipv4/tcp_metrics.o
      CC      net/ipv4/tcp_fastopen.o
      CC      net/ipv4/tcp_rate.o
      CC      net/ipv4/tcp_recovery.o
      CC      net/ipv4/tcp_ulp.o
      CC      net/ipv4/tcp_offload.o
      CC      net/ipv4/datagram.o
      CC      net/ipv4/raw.o
      CC      net/ipv4/udp.o
      CC      net/ipv4/udplite.o
      CC      net/ipv4/udp_offload.o
      CC      net/ipv4/arp.o
      CC      net/ipv4/icmp.o
      CC      net/ipv4/devinet.o
      CC      net/ipv4/af_inet.o
      CC      net/ipv4/igmp.o
      CC      net/ipv4/fib_frontend.o
      CC      net/ipv4/fib_semantics.o
      CC      net/ipv4/fib_trie.o
      CC      net/ipv4/fib_notifier.o
      CC      net/ipv4/inet_fragment.o
      CC      net/ipv4/ping.o
      CC      net/ipv4/ip_tunnel_core.o
      CC      net/ipv4/gre_offload.o
      CC      net/ipv4/metrics.o
      CC      net/ipv4/netlink.o
      CC      net/ipv4/nexthop.o
      CC      net/ipv4/sysctl_net_ipv4.o
      CC      net/ipv4/proc.o
      CC      net/ipv4/inet_diag.o
      CC      net/ipv4/tcp_diag.o
      CC      net/ipv4/tcp_cubic.o
      AR      net/ipv4/built-in.a
      CC      net/ipv6/addrconf_core.o
      CC      net/ipv6/exthdrs_core.o
      CC      net/ipv6/ip6_checksum.o
      CC      net/ipv6/ip6_icmp.o
      CC      net/ipv6/output_core.o
      CC      net/ipv6/protocol.o
      CC      net/ipv6/ip6_offload.o
      CC      net/ipv6/tcpv6_offload.o
      CC      net/ipv6/exthdrs_offload.o
      AR      net/ipv6/built-in.a
      CC      net/netlink/af_netlink.o
      CC      net/netlink/genetlink.o
      AR      net/netlink/built-in.a
      CC      net/packet/af_packet.o
      AR      net/packet/built-in.a
      CC      net/sched/sch_generic.o
      CC      net/sched/sch_mq.o
      AR      net/sched/built-in.a
      CC      net/sunrpc/clnt.o
      CC      net/sunrpc/xprt.o
      CC      net/sunrpc/socklib.o
      CC      net/sunrpc/xprtsock.o
      CC      net/sunrpc/sched.o
      CC      net/sunrpc/auth.o
      CC      net/sunrpc/auth_null.o
      CC      net/sunrpc/auth_unix.o
      CC      net/sunrpc/svc.o
      CC      net/sunrpc/svcsock.o
      CC      net/sunrpc/svcauth.o
      CC      net/sunrpc/svcauth_unix.o
      CC      net/sunrpc/addr.o
      CC      net/sunrpc/rpcb_clnt.o
      CC      net/sunrpc/timer.o
      CC      net/sunrpc/xdr.o
      CC      net/sunrpc/sunrpc_syms.o
      CC      net/sunrpc/cache.o
      CC      net/sunrpc/rpc_pipe.o
      CC      net/sunrpc/svc_xprt.o
      CC      net/sunrpc/xprtmultipath.o
      CC      net/sunrpc/stats.o
      CC      net/sunrpc/sysctl.o
      AR      net/sunrpc/built-in.a
      CC      net/unix/af_unix.o
      CC      net/unix/garbage.o
      CC      net/unix/sysctl_net_unix.o
      CC      net/unix/scm.o
      AR      net/unix/built-in.a
      CC      net/sysctl_net.o
      AR      net/built-in.a
      CC      lib/lockref.o
      CC      lib/bcd.o
      CC      lib/sort.o
      CC      lib/parser.o
      CC      lib/debug_locks.o
      CC      lib/random32.o
      CC      lib/bust_spinlocks.o
      CC      lib/kasprintf.o
      CC      lib/bitmap.o
      CC      lib/scatterlist.o
      CC      lib/list_sort.o
      CC      lib/uuid.o
      CC      lib/iov_iter.o
      CC      lib/clz_ctz.o
      CC      lib/bsearch.o
      CC      lib/find_bit.o
      CC      lib/llist.o
      CC      lib/memweight.o
      CC      lib/kfifo.o
      CC      lib/percpu-refcount.o
      CC      lib/rhashtable.o
      CC      lib/once.o
      CC      lib/refcount.o
      CC      lib/usercopy.o
      CC      lib/errseq.o
      CC      lib/bucket_locks.o
      CC      lib/generic-radix-tree.o
      CC      lib/string_helpers.o
      CC      lib/hexdump.o
      CC      lib/kstrtox.o
      CC      lib/crypto/aes.o
      CC      lib/crypto/arc4.o
      CC      lib/crypto/des.o
      CC      lib/crypto/sha256.o
      AR      lib/crypto/built-in.a
      CC      lib/lz4/lz4_decompress.o
      AR      lib/lz4/built-in.a
      CC      lib/lzo/lzo1x_decompress_safe.o
      AR      lib/lzo/built-in.a
      CC      lib/math/div64.o
      CC      lib/math/gcd.o
      CC      lib/math/lcm.o
      CC      lib/math/int_pow.o
      CC      lib/math/int_sqrt.o
      CC      lib/math/reciprocal_div.o
      CC      lib/math/rational.o
      AR      lib/math/built-in.a
      CC      lib/xz/xz_dec_syms.o
      CC      lib/xz/xz_dec_stream.o
      CC      lib/xz/xz_dec_lzma2.o
      CC      lib/xz/xz_dec_bcj.o
      AR      lib/xz/built-in.a
      CC      lib/zlib_deflate/deflate.o
      CC      lib/zlib_deflate/deftree.o
      CC      lib/zlib_deflate/deflate_syms.o
      AR      lib/zlib_deflate/built-in.a
      CC      lib/zlib_inflate/inffast.o
      CC      lib/zlib_inflate/inflate.o
      CC      lib/zlib_inflate/infutil.o
      CC      lib/zlib_inflate/inftrees.o
      CC      lib/zlib_inflate/inflate_syms.o
      AR      lib/zlib_inflate/built-in.a
      CC      lib/pci_iomap.o
      CC      lib/iomap_copy.o
      CC      lib/devres.o
      CC      lib/logic_pio.o
      CC      lib/hweight.o
      CC      lib/assoc_array.o
      CC      lib/bitrev.o
      CC      lib/crc16.o
      CC      lib/crc32.o
      CC      lib/genalloc.o
      CC      lib/nlattr.o
      CC      lib/checksum.o
      CC      lib/atomic64.o
      CC      lib/dynamic_queue_limits.o
      CC      lib/net_utils.o
      CC      lib/sbitmap.o
      CC      lib/argv_split.o
      CC      lib/chacha.o
      CC      lib/cmdline.o
      CC      lib/ctype.o
      CC      lib/dec_and_lock.o
      CC      lib/decompress.o
      CC      lib/decompress_bunzip2.o
      CC      lib/decompress_inflate.o
      CC      lib/decompress_unlz4.o
      CC      lib/decompress_unlzma.o
      CC      lib/decompress_unlzo.o
      CC      lib/decompress_unxz.o
      CC      lib/dump_stack.o
      CC      lib/earlycpio.o
      CC      lib/extable.o
      CC      lib/fdt.o
      CC      lib/fdt_empty_tree.o
      CC      lib/fdt_ro.o
      CC      lib/fdt_rw.o
      CC      lib/fdt_strerror.o
      CC      lib/fdt_sw.o
      CC      lib/fdt_wip.o
      CC      lib/flex_proportions.o
      CC      lib/idr.o
      CC      lib/ioremap.o
      CC      lib/irq_regs.o
      CC      lib/is_single_threaded.o
      CC      lib/klist.o
      CC      lib/kobject.o
      CC      lib/kobject_uevent.o
      CC      lib/memcat_p.o
      CC      lib/nmi_backtrace.o
      CC      lib/nodemask.o
      CC      lib/plist.o
      CC      lib/radix-tree.o
      CC      lib/ratelimit.o
      CC      lib/rbtree.o
      CC      lib/seq_buf.o
      CC      lib/sha1.o
      CC      lib/show_mem.o
      CC      lib/siphash.o
      CC      lib/string.o
      CC      lib/timerqueue.o
      CC      lib/vsprintf.o
      CC      lib/win_minmax.o
      CC      lib/xarray.o
      AR      lib/lib.a
      EXPORTS lib/lib-ksyms.o
      AR      lib/built-in.a
      CC      arch/microblaze/lib/ashldi3.o
      CC      arch/microblaze/lib/ashrdi3.o
      CC      arch/microblaze/lib/cmpdi2.o
      AS      arch/microblaze/lib/divsi3.o
      CC      arch/microblaze/lib/lshrdi3.o
      AS      arch/microblaze/lib/modsi3.o
      CC      arch/microblaze/lib/muldi3.o
      AS      arch/microblaze/lib/mulsi3.o
      CC      arch/microblaze/lib/ucmpdi2.o
      AS      arch/microblaze/lib/udivsi3.o
      AS      arch/microblaze/lib/umodsi3.o
      CC      arch/microblaze/lib/memcpy.o
    arch/microblaze/lib/memcpy.c: In function 'memcpy':
    arch/microblaze/lib/memcpy.c:70:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       70 |    --c;
          |    ^~~
    arch/microblaze/lib/memcpy.c:71:3: note: here
       71 |   case 2:
          |   ^~~~
    arch/microblaze/lib/memcpy.c:73:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       73 |    --c;
          |    ^~~
    arch/microblaze/lib/memcpy.c:74:3: note: here
       74 |   case 3:
          |   ^~~~
    arch/microblaze/lib/memcpy.c:178:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      178 |   *dst++ = *src++;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memcpy.c:179:2: note: here
      179 |  case 2:
          |  ^~~~
    arch/microblaze/lib/memcpy.c:180:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      180 |   *dst++ = *src++;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memcpy.c:181:2: note: here
      181 |  case 1:
          |  ^~~~
      CC      arch/microblaze/lib/memmove.o
    arch/microblaze/lib/memmove.c: In function 'memmove':
    arch/microblaze/lib/memmove.c:92:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       92 |    --c;
          |    ^~~
    arch/microblaze/lib/memmove.c:93:3: note: here
       93 |   case 2:
          |   ^~~~
    arch/microblaze/lib/memmove.c:95:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       95 |    --c;
          |    ^~~
    arch/microblaze/lib/memmove.c:96:3: note: here
       96 |   case 1:
          |   ^~~~
    arch/microblaze/lib/memmove.c:203:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      203 |   *--dst = *--src;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memmove.c:204:2: note: here
      204 |  case 3:
          |  ^~~~
    arch/microblaze/lib/memmove.c:205:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      205 |   *--dst = *--src;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memmove.c:206:2: note: here
      206 |  case 2:
          |  ^~~~
    arch/microblaze/lib/memmove.c:207:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      207 |   *--dst = *--src;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memmove.c:208:2: note: here
      208 |  case 1:
          |  ^~~~
      CC      arch/microblaze/lib/memset.o
    arch/microblaze/lib/memset.c: In function 'memset':
    arch/microblaze/lib/memset.c:71:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       71 |    --n;
          |    ^~~
    arch/microblaze/lib/memset.c:72:3: note: here
       72 |   case 2:
          |   ^~~~
    arch/microblaze/lib/memset.c:74:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       74 |    --n;
          |    ^~~
    arch/microblaze/lib/memset.c:75:3: note: here
       75 |   case 3:
          |   ^~~~
      AS      arch/microblaze/lib/uaccess_old.o
      AR      arch/microblaze/lib/lib.a
      EXPORTS arch/microblaze/lib/lib-ksyms.o
      AR      arch/microblaze/lib/built-in.a
      GEN     .version
      CHK     include/generated/compile.h
      UPD     include/generated/compile.h
      CC      init/version.o
      AR      init/built-in.a
      LD      vmlinux.o
      MODPOST vmlinux.o
      MODINFO modules.builtin.modinfo
      LD      .tmp_vmlinux1
      KSYM    .tmp_kallsyms1.o
      LD      .tmp_vmlinux2
      KSYM    .tmp_kallsyms2.o
      LD      vmlinux
      SORTEX  vmlinux
      SYSMAP  System.map
      OBJCOPY arch/microblaze/boot/simpleImage.kc705_fmcdaq2_ddc
      UIMAGE  arch/microblaze/boot/simpleImage.kc705_fmcdaq2_ddc.ub
    Image Name:   Linux-5.4.0-00535-g22306c385556-
    Created:      Mon Sep  6 11:28:01 2021
    Image Type:   MicroBlaze Linux Kernel Image (uncompressed)
    Data Size:    15567540 Bytes = 15202.68 KiB = 14.85 MiB
    Load Address: 80000000
    Entry Point:  80000000
      SHIPPED arch/microblaze/boot/simpleImage.kc705_fmcdaq2_ddc.unstrip
      STRIP   vmlinux arch/microblaze/boot/simpleImage.kc705_fmcdaq2_ddc.strip
    Kernel: arch/microblaze/boot/simpleImage.kc705_fmcdaq2_ddc is ready  (#5)
    

    output for kernel Kernel build

    A have no clue on why this scheme does not work

    In this I could find

    ""

      DTC     arch/microblaze/boot/dts/kc705_fmcdaq2_ddc.dtb
    arch/microblaze/boot/dts/kc705.dtsi:406.34-419.5: Warning (spi_bus_bridge): /amba_pl/axi_quad_spi@44a70000: node name for SPI buses should be 'spi'
      also defined at arch/microblaze/boot/dts/adi-daq2.dtsi:2.10-137.3
    arch/microblaze/boot/dts/kc705_fmcdaq2_ddc.dtb: Warning (spi_bus_reg): Failed prerequisite 'spi_bus_bridge'

    ""

    Also

    "CC      arch/microblaze/lib/memcpy.o
    arch/microblaze/lib/memcpy.c: In function 'memcpy':
    arch/microblaze/lib/memcpy.c:70:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       70 |    --c;
          |    ^~~
    arch/microblaze/lib/memcpy.c:71:3: note: here
       71 |   case 2:
          |   ^~~~
    arch/microblaze/lib/memcpy.c:73:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       73 |    --c;
          |    ^~~
    arch/microblaze/lib/memcpy.c:74:3: note: here
       74 |   case 3:
          |   ^~~~
    arch/microblaze/lib/memcpy.c:178:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      178 |   *dst++ = *src++;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memcpy.c:179:2: note: here
      179 |  case 2:
          |  ^~~~
    arch/microblaze/lib/memcpy.c:180:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      180 |   *dst++ = *src++;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memcpy.c:181:2: note: here
      181 |  case 1:
          |  ^~~~
      CC      arch/microblaze/lib/memmove.o
    arch/microblaze/lib/memmove.c: In function 'memmove':
    arch/microblaze/lib/memmove.c:92:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       92 |    --c;
          |    ^~~
    arch/microblaze/lib/memmove.c:93:3: note: here
       93 |   case 2:
          |   ^~~~
    arch/microblaze/lib/memmove.c:95:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       95 |    --c;
          |    ^~~
    arch/microblaze/lib/memmove.c:96:3: note: here
       96 |   case 1:
          |   ^~~~
    arch/microblaze/lib/memmove.c:203:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      203 |   *--dst = *--src;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memmove.c:204:2: note: here
      204 |  case 3:
          |  ^~~~
    arch/microblaze/lib/memmove.c:205:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      205 |   *--dst = *--src;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memmove.c:206:2: note: here
      206 |  case 2:
          |  ^~~~
    arch/microblaze/lib/memmove.c:207:10: warning: this statement may fall through [-Wimplicit-fallthrough=]
      207 |   *--dst = *--src;
          |   ~~~~~~~^~~~~~~~
    arch/microblaze/lib/memmove.c:208:2: note: here
      208 |  case 1:
          |  ^~~~
      CC      arch/microblaze/lib/memset.o
    arch/microblaze/lib/memset.c: In function 'memset':
    arch/microblaze/lib/memset.c:71:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       71 |    --n;
          |    ^~~
    arch/microblaze/lib/memset.c:72:3: note: here
       72 |   case 2:
          |   ^~~~
    arch/microblaze/lib/memset.c:74:4: warning: this statement may fall through [-Wimplicit-fallthrough=]
       74 |    --n;
          |    ^~~
    arch/microblaze/lib/memset.c:75:3: note: here
       75 |   case 3:
          |   ^~~~"

  • Hello,

    I will test the modified architecture of daq2 on the zc706 board and I will give you a feedback.

    Best Regards,

    Dan

  • I guess the reason for AD9680 to be in default 4 lane mode could be due how these parameters are set in driver ad9680.c

    Here Lane number and other JESD related parameters are hard coded in ad9680.c driver. So in order to configure ADC I may need to edit driver. I have tried editing ad9680.c

    /*
     * Driver for AD9680 and similar high-speed Analog-to-Digital converters
     *
     * Copyright 2012-2017 Analog Devices Inc.
     *
     * Licensed under the GPL-2.
     */
    
    #include <linux/clk.h>
    #include <linux/delay.h>
    #include <linux/device.h>
    #include <linux/err.h>
    #include <linux/gpio/consumer.h>
    #include <linux/interrupt.h>
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/of.h>
    #include <linux/slab.h>
    #include <linux/spi/spi.h>
    
    #include <linux/iio/events.h>
    #include <linux/iio/iio.h>
    #include <linux/iio/sysfs.h>
    
    #include "cf_axi_adc.h"
    
    #define AD9680_REG_CHIP_ID_LOW		0x004
    #define AD9680_REG_CHIP_ID_HIGH		0x005
    #define AD9680_REG_DEVICE_INDEX		0x008
    #define AD9680_REG_PAIR_INDEX		0x009
    #define AD9680_REG_INPUT_FS_RANGE	0x025
    #define AD9680_REG_CHIP_PIN_CTRL	0x040
    
    #define AD9680_REG_OUTPUT_MODE		0x561
    #define AD9680_REG_TEST_MODE		0x550
    
    #define AD9680_REG_THRESH_CTRL		0x245
    #define AD9680_REG_THRESH_HI_LSB	0x247
    #define AD9680_REG_THRESH_HI_MSB	0x248
    #define AD9680_REG_THRESH_LOW_LSB	0x249
    #define AD9680_REG_THRESH_LOW_MSB	0x24A
    
    #define AD9680_REG_CHIP_PIN_CTRL_MASK(chn)	(0x07 << (3 * (chn)))
    
    #define AD9680_TESTMODE_OFF			0x0
    #define AD9680_TESTMODE_MIDSCALE_SHORT		0x1
    #define AD9680_TESTMODE_POS_FULLSCALE		0x2
    #define AD9680_TESTMODE_NEG_FULLSCALE		0x3
    #define AD9680_TESTMODE_ALT_CHECKERBOARD	0x4
    #define AD9680_TESTMODE_PN23_SEQ		0x5
    #define AD9680_TESTMODE_PN9_SEQ			0x6
    #define AD9680_TESTMODE_ONE_ZERO_TOGGLE		0x7
    #define AD9680_TESTMODE_USER			0x8
    #define AD9680_TESTMODE_RAMP			0xF
    
    #define AD9680_OUTPUT_MODE_OFFSET_BINARY	0x0
    #define AD9680_OUTPUT_MODE_TWOS_COMPLEMENT	0x1
    
    #define CHIPID_AD9680			0xC5
    #define CHIPID_AD9684			0xD3
    #define CHIPID_AD9234			0xCE
    #define CHIPID_AD9694			0xDB
    #define CHIPID_AD9094			0xE8
    
    enum {
    	ID_AD9234,
    	ID_AD9680,
    	ID_AD9680_x2,
    	ID_AD9684,
    	ID_AD9694,
    	ID_AD9094,
    };
    
    enum ad9680_sysref_mode {
    	AD9680_SYSREF_DISABLED,
    	AD9680_SYSREF_CONTINUOUS,
    	AD9680_SYSREF_ONESHOT
    };
    
    struct ad9680_sysref_config {
    	enum ad9680_sysref_mode mode;
    	bool capture_falling_edge;
    	bool valid_falling_edge;
    };
    
    struct ad9680_jesd204_link_config {
    	uint8_t did;
    	uint8_t bid;
    
    	uint8_t num_lanes;
    	uint8_t num_converters;
    	uint8_t octets_per_frame;
    	uint8_t frames_per_multiframe;
    
    	uint8_t bits_per_sample;
    	uint8_t converter_resolution;
    
    	uint8_t lid[4];
    	uint8_t lane_mux[4];
    
    	bool scrambling;
    	uint8_t subclass;
    
    	struct ad9680_sysref_config sysref;
    };
    
    static int ad9680_spi_read(struct spi_device *spi, unsigned int reg)
    {
    	unsigned char buf[3];
    	int ret;
    
    	if (spi) {
    		buf[0] = 0x80 | (reg >> 8);
    		buf[1] = reg & 0xFF;
    
    		ret = spi_write_then_read(spi, &buf[0], 2, &buf[2], 1);
    
    		dev_dbg(&spi->dev, "%s: REG: 0x%X VAL: 0x%X (%d)\n",
    			__func__, reg, buf[2], ret);
    
    		if (ret < 0)
    			return ret;
    
    		return buf[2];
    	}
    	return -ENODEV;
    }
    
    static int ad9680_spi_write(struct spi_device *spi, unsigned int reg,
    	unsigned int val)
    {
    	unsigned char buf[3];
    	int ret;
    
    	if (spi) {
    		buf[0] = reg >> 8;
    		buf[1] = reg & 0xFF;
    		buf[2] = val;
    		ret = spi_write_then_read(spi, buf, 3, NULL, 0);
    		if (ret < 0)
    			return ret;
    
    		dev_dbg(&spi->dev, "%s: REG: 0x%X VAL: 0x%X (%d)\n",
    			__func__, reg, val, ret);
    
    		return 0;
    	}
    
    	return -ENODEV;
    }
    
    static int ad9680_reg_access(struct iio_dev *indio_dev, unsigned int reg,
    	unsigned int writeval, unsigned int *readval)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	struct spi_device *spi = conv->spi;
    	int ret;
    
    	if (readval == NULL)
    		return ad9680_spi_write(spi, reg, writeval);
    
    	ret = ad9680_spi_read(spi, reg);
    	if (ret < 0)
    		return ret;
    	*readval = ret;
    
    	return 0;
    }
    
    static int ad9680_select_channel(struct axiadc_converter *conv,
    	int chan)
    {
    	unsigned int device, pair;
    	int ret;
    
    	if (chan >= 0) {
    		device = BIT(chan & 0x1);
    		pair = BIT((chan >> 1) & 1);
    	} else {
    		device = 0x3;
    		pair = 0x3;
    	}
    
    	ret = ad9680_spi_write(conv->spi, AD9680_REG_DEVICE_INDEX, device);
    	if (ret < 0)
    		return ret;
    	return ad9680_spi_write(conv->spi, AD9680_REG_PAIR_INDEX, pair);
    }
    
    static int ad9680_channel_write(struct axiadc_converter *conv,
    	unsigned int chan, unsigned int reg, unsigned int val)
    {
    	int ret;
    
    	ret = ad9680_select_channel(conv, chan);
    	ret |= ad9680_spi_write(conv->spi, reg, val);
    	ret |= ad9680_select_channel(conv, -1);
    
    	return ret;
    }
    
    static int ad9680_channel_read(struct axiadc_converter *conv,
    	unsigned int chan, unsigned int reg)
    {
    	int ret;
    
    	ad9680_select_channel(conv, chan);
    	ret = ad9680_spi_read(conv->spi, reg);
    	ad9680_select_channel(conv, -1);
    
    	return ret;
    }
    
    static unsigned int ad9680_pnsel_to_testmode(enum adc_pn_sel sel)
    {
    	switch (sel) {
    	case ADC_PN9:
    		return AD9680_TESTMODE_PN9_SEQ;
    	case ADC_PN23A:
    		return AD9680_TESTMODE_PN23_SEQ;
    	default:
    		return AD9680_TESTMODE_OFF;
    	}
    }
    
    static int ad9680_outputmode_set(struct spi_device *spi, unsigned int mode)
    {
    	int ret;
    
    	ret = ad9680_spi_write(spi, AD9680_REG_OUTPUT_MODE, mode);
    	if (ret < 0)
    		return ret;
    
    	return ad9680_spi_write(spi, AD9680_REG_TEST_MODE,
    				AD9680_TESTMODE_OFF);
    }
    
    static int ad9680_testmode_set(struct iio_dev *indio_dev, unsigned int chan,
    	unsigned int mode)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    
    	ad9680_channel_write(conv, chan, AD9680_REG_TEST_MODE, mode);
    	conv->testmode[chan] = mode;
    
    	return 0;
    }
    
    static int ad9680_set_pnsel(struct iio_dev *indio_dev, unsigned int chan,
    	enum adc_pn_sel sel)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	unsigned int mode = ad9680_pnsel_to_testmode(sel);
    	unsigned int output_mode;
    	int ret;
    
    	output_mode = conv->adc_output_mode;
    	if (mode != AD9680_TESTMODE_OFF)
    		output_mode &= ~AD9680_OUTPUT_MODE_TWOS_COMPLEMENT;
    
    	ret = ad9680_spi_write(conv->spi, AD9680_REG_OUTPUT_MODE, output_mode);
    	if (ret < 0)
    		return ret;
    
    	return ad9680_testmode_set(indio_dev, chan, mode);
    }
    
    static irqreturn_t ad9680_event_handler(struct axiadc_converter *conv,
    	unsigned int chn)
    {
    	u64 event = IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, chn,
    			IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING);
    	s64 timestamp = iio_get_time_ns(conv->indio_dev);
    
    	if (conv->indio_dev)
    		iio_push_event(conv->indio_dev, event, timestamp);
    
    	return IRQ_HANDLED;
    }
    
    static irqreturn_t ad9680_fdA_handler(int irq, void *private)
    {
    	return ad9680_event_handler(private, 0);
    }
    
    static irqreturn_t ad9680_fdB_handler(int irq, void *private)
    {
    	return ad9680_event_handler(private, 1);
    }
    
    static int ad9680_read_thresh(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan, enum iio_event_type type,
    	enum iio_event_direction dir, enum iio_event_info info, int *val,
    	int *val2)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	struct spi_device *spi = conv->spi;
    	u16 low, high;
    
    	mutex_lock(&indio_dev->mlock);
    	low = (ad9680_spi_read(spi, AD9680_REG_THRESH_LOW_MSB) << 8) |
    		ad9680_spi_read(spi, AD9680_REG_THRESH_LOW_LSB);
    	high = (ad9680_spi_read(spi, AD9680_REG_THRESH_HI_MSB) << 8) |
    		ad9680_spi_read(spi, AD9680_REG_THRESH_HI_LSB);
    	mutex_unlock(&indio_dev->mlock);
    
    	switch (info) {
    	case IIO_EV_INFO_HYSTERESIS:
    		*val = high - low;
    		break;
    	case IIO_EV_INFO_VALUE:
    		*val = high;
    		break;
    	default:
    		return -EINVAL;
    	}
    
    	return IIO_VAL_INT;
    }
    
    static int ad9680_read_thresh_en(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan, enum iio_event_type type,
    	enum iio_event_direction dir)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	struct spi_device *spi = conv->spi;
    	int ret;
    
    	ret = ad9680_spi_read(spi, AD9680_REG_CHIP_PIN_CTRL);
    	if (ret < 0)
    		return ret;
    	else
    		return !(ret & AD9680_REG_CHIP_PIN_CTRL_MASK(chan->channel));
    }
    
    static int ad9680_write_thresh(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan, enum iio_event_type type,
    	enum iio_event_direction dir, enum iio_event_info info, int val,
    	int val2)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	struct spi_device *spi = conv->spi;
    	int ret = 0;
    	int low, high;
    
    	mutex_lock(&indio_dev->mlock);
    	high = (ad9680_spi_read(spi, AD9680_REG_THRESH_HI_MSB) << 8) |
    		ad9680_spi_read(spi, AD9680_REG_THRESH_HI_LSB);
    
    	switch (info) {
    	case IIO_EV_INFO_HYSTERESIS:
    		if (val < 0) {
    			ret = -EINVAL;
    			goto unlock;
    		}
    
    		low = high - val;
    		break;
    
    	case IIO_EV_INFO_VALUE:
    		if (val > 0x7FF) {
    			ret = -EINVAL;
    			goto unlock;
    		}
    
    		ad9680_spi_write(spi, AD9680_REG_THRESH_HI_MSB, val >> 8);
    		ad9680_spi_write(spi, AD9680_REG_THRESH_HI_LSB, val & 0xFF);
    
    		/* Calculate the new lower threshold limit */
    		low = (ad9680_spi_read(spi, AD9680_REG_THRESH_LOW_MSB) << 8) |
    			ad9680_spi_read(spi, AD9680_REG_THRESH_LOW_LSB);
    		low = val - high + low;
    		break;
    
    	default:
    		ret = -EINVAL;
    		goto unlock;
    	}
    
    	if (low < 0)
    		low = 0;
    	ad9680_spi_write(spi, AD9680_REG_THRESH_LOW_MSB, low >> 8);
    	ad9680_spi_write(spi, AD9680_REG_THRESH_LOW_LSB, low & 0xFF);
    
    unlock:
    	mutex_unlock(&indio_dev->mlock);
    	return ret;
    }
    
    static int ad9680_write_thresh_en(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan, enum iio_event_type type,
    	enum iio_event_direction dir, int state)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	struct spi_device *spi = conv->spi;
    	int ret;
    
    	mutex_lock(&indio_dev->mlock);
    
    	ret = ad9680_spi_read(spi, AD9680_REG_CHIP_PIN_CTRL);
    	if (ret < 0)
    		goto err_unlock;
    
    	if (state)
    		ret &= ~AD9680_REG_CHIP_PIN_CTRL_MASK(chan->channel);
    	else
    		ret |= AD9680_REG_CHIP_PIN_CTRL_MASK(chan->channel);
    
    	ret = ad9680_spi_write(spi, AD9680_REG_CHIP_PIN_CTRL, ret);
    err_unlock:
    	mutex_unlock(&indio_dev->mlock);
    	return ret;
    }
    
    static const int ad9680_scale_table[][2] = {
    	{1460, 0x08}, {1580, 0x09}, {1700, 0x0A}, {1820, 0x0B},
    	{1940, 0x00}, {2060, 0x0C},
    };
    
    static const int ad9694_scale_table[][2] = {
    	{1440, 0xa}, {1560, 0xb}, {1680, 0xc}, {1800, 0xd},
    	{1920, 0xe}, {2040, 0xf}, {2160, 0x0},
    };
    
    static void ad9680_scale(struct axiadc_converter *conv, int index,
    	unsigned int *val, unsigned int *val2)
    {
    	unsigned int tmp;
    
    	if (index > conv->chip_info->num_scales) {
    		*val = 0;
    		*val2 = 0;
    		return;
    	}
    
    	tmp = (conv->chip_info->scale_table[index][0] * 1000000ULL) >>
    		    conv->chip_info->channel[0].scan_type.realbits;
    	*val = tmp / 1000000;
    	*val2 = tmp % 1000000;
    }
    
    static ssize_t ad9680_show_scale_available(struct iio_dev *indio_dev,
    	uintptr_t private, const struct iio_chan_spec *chan, char *buf)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	unsigned int scale[2];
    	int i, len = 0;
    
    	for (i = 0; i < conv->chip_info->num_scales; i++) {
    		ad9680_scale(conv, i, &scale[0], &scale[1]);
    		len += sprintf(buf + len, "%u.%06u ", scale[0], scale[1]);
    	}
    
    	/* replace last space with a newline */
    	buf[len - 1] = '\n';
    
    	return len;
    }
    
    static int ad9680_get_scale(struct axiadc_converter *conv,
    	const struct iio_chan_spec *chan, int *val, int *val2)
    {
    	unsigned int vref_val;
    	unsigned int i;
    
    	switch (conv->id) {
    	case CHIPID_AD9694:
    	case CHIPID_AD9094:
    		vref_val = ad9680_channel_read(conv, chan->channel, 0x1910);
    		break;
    	default:
    		vref_val = ad9680_spi_read(conv->spi, AD9680_REG_INPUT_FS_RANGE);
    		break;
    	}
    	vref_val &= 0xf;
    
    	for (i = 0; i < conv->chip_info->num_scales; i++) {
    		if (vref_val == conv->chip_info->scale_table[i][1])
    			break;
    	}
    
    	ad9680_scale(conv, i, val, val2);
    
    	return IIO_VAL_INT_PLUS_MICRO;
    }
    
    static int ad9680_set_scale(struct axiadc_converter *conv,
    	const struct iio_chan_spec *chan, int val, int val2)
    {
    	unsigned int scale_val[2];
    	unsigned int scale_raw;
    	unsigned int i;
    
    	for (i = 0; i < conv->chip_info->num_scales; i++) {
    		ad9680_scale(conv, i, &scale_val[0], &scale_val[1]);
    		if (scale_val[0] != val || scale_val[1] != val2)
    			continue;
    
    		scale_raw = conv->chip_info->scale_table[i][1];
    
    		switch (conv->id) {
    		case CHIPID_AD9694:
    		case CHIPID_AD9094:
    			ad9680_channel_write(conv, chan->channel, 0x1910,
    					     scale_raw);
    			break;
    		default:
    			ad9680_spi_write(conv->spi, AD9680_REG_INPUT_FS_RANGE,
    					 scale_raw);
    			break;
    		}
    		return 0;
    	}
    
    	return -EINVAL;
    }
    
    static int ad9680_testmode_read(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    
    	return conv->testmode[chan->channel];
    }
    
    static int ad9680_testmode_write(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan, unsigned int item)
    {
    	int ret;
    
    	mutex_lock(&indio_dev->mlock);
    	ret = ad9680_testmode_set(indio_dev, chan->channel, item);
    	mutex_unlock(&indio_dev->mlock);
    
    	return ret;
    }
    
    static const char * const ad9680_testmodes[] = {
    	[AD9680_TESTMODE_OFF] = "off",
    	[AD9680_TESTMODE_MIDSCALE_SHORT] = "midscale_short",
    	[AD9680_TESTMODE_POS_FULLSCALE] = "pos_fullscale",
    	[AD9680_TESTMODE_NEG_FULLSCALE] = "neg_fullscale",
    	[AD9680_TESTMODE_ALT_CHECKERBOARD] = "checkerboard",
    	[AD9680_TESTMODE_PN23_SEQ] = "pn_long",
    	[AD9680_TESTMODE_PN9_SEQ] = "pn_short",
    	[AD9680_TESTMODE_ONE_ZERO_TOGGLE] = "one_zero_toggle",
    	[AD9680_TESTMODE_USER] = "user",
    	[AD9680_TESTMODE_RAMP] = "ramp",
    };
    
    static const struct iio_enum ad9680_testmode_enum = {
    	.items = ad9680_testmodes,
    	.num_items = ARRAY_SIZE(ad9680_testmodes),
    	.set = ad9680_testmode_write,
    	.get = ad9680_testmode_read,
    };
    
    static struct iio_chan_spec_ext_info axiadc_ext_info[] = {
    	IIO_ENUM("test_mode", IIO_SEPARATE, &ad9680_testmode_enum),
    	IIO_ENUM_AVAILABLE("test_mode", &ad9680_testmode_enum),
    	{
    		.name = "scale_available",
    		.read = ad9680_show_scale_available,
    		.shared = true,
    	},
    	{},
    };
    
    static const struct iio_event_spec ad9680_events[] = {
    	{
    		.type = IIO_EV_TYPE_THRESH,
    		.dir = IIO_EV_DIR_RISING,
    		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
    				       BIT(IIO_EV_INFO_HYSTERESIS),
    		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
    	},
    };
    
    #define AD9680_CHAN(_chan, _si, _bits, _sign, _shift, _ev, _nb_ev)	\
    	{ .type = IIO_VOLTAGE,						\
    	  .indexed = 1,							\
    	  .channel = _chan,						\
    	  .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
    			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
    	  .ext_info = axiadc_ext_info,			\
    	  .scan_index = _si,						\
    	  .scan_type = {						\
    			.sign = _sign,					\
    			.realbits = _bits,				\
    			.storagebits = 16,				\
    			.shift = _shift,				\
    	  },								\
    	  .event_spec = _ev,						\
    	  .num_event_specs = _nb_ev,					\
    	}
    
    #define AD9694_CHAN(_chan) {						\
    	.type = IIO_VOLTAGE,						\
    	.indexed = 1,							\
    	.channel = _chan,						\
    	.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE),			\
    	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
    	.ext_info = axiadc_ext_info,					\
    	.scan_index = _chan,						\
    	.scan_type = {							\
    		.sign = 'S',						\
    		.realbits = 8,						\
    		.storagebits = 8,					\
    		.shift = 0,						\
    	},								\
    	.event_spec = ad9680_events,					\
    	.num_event_specs = ARRAY_SIZE(ad9680_events),			\
    }
    
    static const struct axiadc_chip_info axiadc_chip_info_tbl[] = {
    	[ID_AD9234] = {
    		.name = "AD9234",
    		.max_rate = 1000000000UL,
    		.scale_table = ad9680_scale_table,
    		.num_scales = ARRAY_SIZE(ad9680_scale_table),
    		.num_channels = 2,
    		.channel[0] = AD9680_CHAN(0, 0, 12, 'S', 0, NULL, 0),
    		.channel[1] = AD9680_CHAN(1, 1, 12, 'S', 0, NULL, 0),
    	},
    	[ID_AD9680] = {
    		.name = "AD9680",
    		.max_rate = 1250000000UL,
    		.scale_table = ad9680_scale_table,
    		.num_scales = ARRAY_SIZE(ad9680_scale_table),
    		.num_channels = 2,
    		.channel[0] = AD9680_CHAN(0, 0, 14, 'S', 0,
    			ad9680_events, ARRAY_SIZE(ad9680_events)),
    		.channel[1] = AD9680_CHAN(1, 1, 14, 'S', 0,
    			ad9680_events, ARRAY_SIZE(ad9680_events)),
    	},
    	[ID_AD9680_x2] = {
    		.name = "AD9680",
    		.max_rate = 1250000000UL,
    		.scale_table = ad9680_scale_table,
    		.num_scales = ARRAY_SIZE(ad9680_scale_table),
    		.num_channels = 4,
    		.num_shadow_slave_channels = 2,
    		.channel[0] = AD9680_CHAN(0, 0, 14, 'S', 0,
    			ad9680_events, ARRAY_SIZE(ad9680_events)),
    		.channel[1] = AD9680_CHAN(1, 1, 14, 'S', 0,
    			ad9680_events, ARRAY_SIZE(ad9680_events)),
    		.channel[2] = AD9680_CHAN(2, 2, 14, 'S', 0,
    			ad9680_events, ARRAY_SIZE(ad9680_events)),
    		.channel[3] = AD9680_CHAN(3, 3, 14, 'S', 0,
    			ad9680_events, ARRAY_SIZE(ad9680_events)),
    	},
    	[ID_AD9684] = {
    		.name = "AD9684",
    		.max_rate = 1250000000UL,
    		.scale_table = ad9680_scale_table,
    		.num_scales = ARRAY_SIZE(ad9680_scale_table),
    		.num_channels = 2,
    		.channel[0] = AD9680_CHAN(0, 0, 14, 'S', 0, NULL, 0),
    		.channel[1] = AD9680_CHAN(1, 1, 14, 'S', 0, NULL, 0),
    	},
    	[ID_AD9694] = {
    		.name = "AD9694",
    		.max_rate = 1000000000UL,
    		.scale_table = ad9694_scale_table,
    		.num_scales = ARRAY_SIZE(ad9694_scale_table),
    		.num_channels = 4,
    		.channel[0] = AD9694_CHAN(0),
    		.channel[1] = AD9694_CHAN(1),
    		.channel[2] = AD9694_CHAN(2),
    		.channel[3] = AD9694_CHAN(3),
    	},
    	[ID_AD9094] = {
    		.name = "AD9094",
    		.max_rate = 1000000000UL,
    		.scale_table = ad9694_scale_table,
    		.num_scales = ARRAY_SIZE(ad9694_scale_table),
    		.num_channels = 4,
    		.channel[0] = AD9694_CHAN(0),
    		.channel[1] = AD9694_CHAN(1),
    		.channel[2] = AD9694_CHAN(2),
    		.channel[3] = AD9694_CHAN(3),
    	},
    };
    
    static bool ad9680_check_sysref_rate(unsigned int lmfc, unsigned int sysref)
    {
    	unsigned int div, mod;
    
    	div = lmfc / sysref;
    	mod = lmfc % sysref;
    
    	/* Ignore minor deviations that can be introduced by rounding. */
    	return mod <= div || mod >= sysref - div;
    }
    
    static int ad9680_update_sysref(struct axiadc_converter *conv,
    				unsigned int lmfc)
    {
    	unsigned int n;
    	int rate;
    
    	/* No clock, no problem */
    	if (!conv->sysref_clk)
    		return 0;
    
    	rate = clk_get_rate(conv->sysref_clk);
    	if (rate < 0)
    		return rate;
    
    	/* If the current rate is OK, keep it */
    	if (ad9680_check_sysref_rate(lmfc, rate))
    		return 0;
    
    	/*
    	 * Try to find a rate that integer divides the LMFC. Starting with a low
    	 * rate is a good idea and then slowly go up in case the clock generator
    	 * can't generate such slow rates.
    	 */
    	for (n = 64; n > 0; n--) {
    		rate = clk_round_rate(conv->sysref_clk, lmfc / n);
    		if (ad9680_check_sysref_rate(lmfc, rate))
    			break;
    	}
    
    	if (n == 0) {
    		dev_err(&conv->spi->dev,
    			"Could not find suitable SYSREF rate for LMFC of %u\n",
    			lmfc);
    		return -EINVAL;
    	}
    
    	return clk_set_rate(conv->sysref_clk, rate);
    }
    
    static ssize_t ad9680_status_read(struct device *dev,
    	struct device_attribute *attr, char *buf)
    {
    	struct axiadc_converter *conv = dev_get_drvdata(dev);
    	const char *hold_setup_desc;
    	unsigned int hold, setup;
    	int val;
    	int ret;
    
    	switch (conv->id) {
    	case CHIPID_AD9694:
    	case CHIPID_AD9094:
    		val = ad9680_spi_read(conv->spi, 0x11b);
    		break;
    	default:
    		val = ad9680_spi_read(conv->spi, 0x11c);
    		break;
    	}
    
    	ret = scnprintf(buf, PAGE_SIZE, "Input clock %sdetected\n",
    		(val & 0x01) ? "" : "not ");
    
    	if (conv->id == CHIPID_AD9684)
    		return ret;
    
    	val = ad9680_spi_read(conv->spi, 0x56f);
    	ret += scnprintf(buf + ret, PAGE_SIZE - ret,
    		"JESD204 PLL is %slocked\n",
    		(val & 0x80) ? "" : "not ");
    
    	val = ad9680_spi_read(conv->spi, 0x12a);
    	ret += scnprintf(buf + ret, PAGE_SIZE - ret,
    		"SYSREF counter: %d\n", val);
    
    	val = ad9680_spi_read(conv->spi, 0x128);
    	hold = (val >> 4) & 0xf;
    	setup = val & 0xf;
    
    	if (hold == 0x0 && setup <= 0x7)
    		hold_setup_desc = "Possible setup error";
    	else if (hold <= 0x8 && setup == 0x8)
    		hold_setup_desc = "No setup or hold error (best hold margin)";
    	else if (hold == 0x8 && setup >= 0x9)
    		hold_setup_desc = "No setup or hold error (best setup and hold margin)";
    	else if (hold == 0x8 && setup == 0x0)
    		hold_setup_desc = "No setup or hold error (best setup margin)";
    	else if (hold >= 0x9 && setup == 0x0)
    		hold_setup_desc = "Possible hold error";
    	else
    		hold_setup_desc = "Possible setup or hold error";
    
    	ret += scnprintf(buf + ret, PAGE_SIZE - ret,
    		"SYSREF hold/setup status: %s (%x/%x)\n",
    		hold_setup_desc, hold, setup);
    
    	return ret;
    }
    
    static DEVICE_ATTR(status, 0444, ad9680_status_read, NULL);
    
    static int ad9680_setup_jesd204_link(struct axiadc_converter *conv,
    	unsigned int sample_rate)
    {
    	unsigned long lane_rate_kHz;
    	unsigned long sysref_rate;
    	int ret;
    
    	sysref_rate = DIV_ROUND_CLOSEST(sample_rate, 32);
    	lane_rate_kHz = DIV_ROUND_CLOSEST(sample_rate, 200);//changed for lane rate 5Gbps rakesh
    	dev_info(&conv->spi->dev, "Lane rate kHz %lu ",
    			lane_rate_kHz );
    	dev_info(&conv->spi->dev, "sysref rate kHz %lu ",
    			sysref_rate );
    
    	if (lane_rate_kHz < 3125000 || lane_rate_kHz > 12500000) {
    		dev_err(&conv->spi->dev, "Lane rate %lu Mbps out of bounds. Must be between 3125 and 12500 Mbps",
    			lane_rate_kHz / 1000);
    		return -EINVAL;
    	}
    
      	if (lane_rate_kHz < 6250000)
    		ad9680_spi_write(conv->spi, 0x56e, 0x10);	// low line rate mode must be enabled
    	else
    		ad9680_spi_write(conv->spi, 0x56e, 0x00);	// low line rate mode must be disabled
    
    	ret = ad9680_update_sysref(conv, sysref_rate);
    	if (ret < 0) {
    		dev_err(&conv->spi->dev, "Failed to set SYSREF clock to %lu kHz: %d\n",
    			sysref_rate / 1000, ret);
    		return ret;
    	}
    
    	ret = clk_set_rate(conv->lane_clk, lane_rate_kHz);
    	if (ret < 0) {
    		dev_err(&conv->spi->dev, "Failed to set lane rate to %lu kHz: %d\n",
    			lane_rate_kHz, ret);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ad9680_set_sample_rate(struct axiadc_converter *conv,
    	unsigned int sample_rate)
    {
    	unsigned int pll_stat;
    	int ret = 0;
    
    	/*
    	 * Minimum ADC samplerate is 300 MSPS. But the minimum lane rate is
    	 * 3.125 Gbps, which results in a minumum ADC samplerate of 312.5 Msps when
    	 * using 4 lanes. Lower the minimum here once support for dynamic lane
    	 * enable/disable has been implemented.
    	 */
    	sample_rate = clamp(sample_rate, 312500000U, 1000000000U);
    	sample_rate = clk_round_rate(conv->clk, sample_rate);
    	
    		dev_info(&conv->spi->dev, "Sample Rate:Rakesh::  %u ",
    			sample_rate );
    
    	/* Disable link */
    	ad9680_spi_write(conv->spi, 0x571, 0x15);
    
    	if (conv->running) {
    		clk_disable_unprepare(conv->lane_clk);
    		clk_disable_unprepare(conv->sysref_clk);
    		clk_disable_unprepare(conv->clk);
    		conv->running = false;
    	}
    
    	ret = clk_set_rate(conv->clk, sample_rate);
    	if (ret) {
    		dev_err(&conv->spi->dev, "Failed to set converter clock rate to %u kHz: %d\n",
    			sample_rate / 1000, ret);
    		return ret;
    	}
    
    	ret = ad9680_setup_jesd204_link(conv, sample_rate);
    	if (ret < 0)
    		return ret;
    
    	ret = clk_prepare_enable(conv->clk);
    	if (ret) {
    		dev_err(&conv->spi->dev, "Failed to enable converter clock: %d\n", ret);
    		return ret;
    	}
    	ret = clk_prepare_enable(conv->sysref_clk);
    	if (ret) {
    		clk_disable_unprepare(conv->clk);
    		dev_err(&conv->spi->dev, "Failed to enable SYSREF clock: %d\n", ret);
    		return ret;
    	}
    
    	// Enable link
    	ad9680_spi_write(conv->spi, 0x571, 0x14);
    
    	mdelay(20);
    	pll_stat = ad9680_spi_read(conv->spi, 0x56f);
    
    	dev_info(&conv->spi->dev, "PLL %s\n",
    		 (pll_stat & 0x80) ? "LOCKED" : "UNLOCKED");
    
    	ret = clk_prepare_enable(conv->lane_clk);
    	if (ret < 0) {
    		clk_disable_unprepare(conv->clk);
    		clk_disable_unprepare(conv->sysref_clk);
    		dev_err(&conv->spi->dev, "Failed to enable JESD204 link: %d\n", ret);
    		return ret;
    	}
    
    	conv->adc_clk = sample_rate;
    	conv->running = true;
    
    	return 0;
    }
    
    static int ad9680_request_clks(struct axiadc_converter *conv)
    {
    	int ret;
    
    	conv->sysref_clk = devm_clk_get(&conv->spi->dev, "adc_sysref");
    	if (IS_ERR(conv->sysref_clk)) {
    		if (PTR_ERR(conv->sysref_clk) != -ENOENT)
    			return PTR_ERR(conv->sysref_clk);
    		conv->sysref_clk = NULL;
    	} else {
    		ret = clk_prepare_enable(conv->sysref_clk);
    		if (ret < 0)
    			return ret;
    	}
    
    	conv->clk = devm_clk_get(&conv->spi->dev, "adc_clk");
    	if (IS_ERR(conv->clk)) {
    		if (PTR_ERR(conv->clk) != -ENOENT) {
    			clk_disable_unprepare(conv->sysref_clk);
    			return PTR_ERR(conv->clk);
    		}
    		conv->clk = NULL;
    	} else {
    		ret = clk_prepare_enable(conv->clk);
    		if (ret < 0) {
    			clk_disable_unprepare(conv->sysref_clk);
    			return ret;
    		}
    
    		conv->adc_clk = clk_get_rate(conv->clk);
    	}
    
    	conv->lane_clk = devm_clk_get(&conv->spi->dev, "jesd_adc_clk");
    	if (IS_ERR(conv->lane_clk)) {
    		if (PTR_ERR(conv->lane_clk) != -ENOENT) {
    			clk_disable_unprepare(conv->clk);
    			clk_disable_unprepare(conv->sysref_clk);
    			return PTR_ERR(conv->lane_clk);
    		}
    		conv->lane_clk = NULL;
    	}
    
    	return 0;
    }
    
    static int ad9680_setup_link(struct spi_device *spi,
    	const struct ad9680_jesd204_link_config *config)
    {
    	unsigned int val;
    	unsigned int i;
    	int ret = 0;
    
    	val = ilog2(config->octets_per_frame);
    	val |= ilog2(config->num_converters) << 3;
    	val |= ilog2(config->num_lanes) << 6;
    
    	ret |= ad9680_spi_write(spi, 0x580, config->did);
    	ret |= ad9680_spi_write(spi, 0x581, config->bid);
    
    	ret = ad9680_spi_write(spi, 0x570, val); // Quick config
    
    	for (i = 0; i < config->num_lanes; i++) {
    		ret |= ad9680_spi_write(spi, 0x583 + i, config->lid[i]);
    
    		val = config->lane_mux[i];
    		val |= val << 4;
    		ret |= ad9680_spi_write(spi, 0x5b2 + i + (i / 2), val);
    	}
    
    	val = config->num_lanes - 1;
    	val |= config->scrambling ? 0x80 : 0x00;
    	ret |= ad9680_spi_write(spi, 0x58b, val);
    
    	ret |= ad9680_spi_write(spi, 0x58d, config->frames_per_multiframe - 1);
    	ret |= ad9680_spi_write(spi, 0x58f, config->converter_resolution - 1);
    
    	val = config->bits_per_sample - 1;
    	val |= config->subclass ? 0x20 : 0x00;
    	ret |= ad9680_spi_write(spi, 0x590, val);
    
    	/* Disable SYSREF */
    	ret |= ad9680_spi_write(spi, 0x120, 0x00);
    
    	ret |= ad9680_spi_write(spi, 0x121, 0x0f);
    
    	switch (config->sysref.mode) {
    	case AD9680_SYSREF_CONTINUOUS:
    		val = 0x02;
    		break;
    	case AD9680_SYSREF_ONESHOT:
    		val = 0x04;
    		break;
    	default:
    		val = 0x00;
    		break;
    	}
    
    	if (config->sysref.capture_falling_edge)
    		val |= 0x08;
    
    	if (config->sysref.valid_falling_edge)
    		val |= 0x10;
    	ret |= ad9680_spi_write(spi, 0x120, val);
    
    	return ret;
    }
    
    static int ad9680_setup(struct spi_device *spi, bool ad9234)
    {
    	struct axiadc_converter *conv = spi_get_drvdata(spi);
    	struct ad9680_jesd204_link_config link_config;
    	unsigned int pll_stat;
    	unsigned int i;
    	int ret, tmp = 1;
    	static const u32 sfdr_optim_regs[] = {
    		0x16, 0x18, 0x19, 0x1A, 0x30, 0x11A, 0x934, 0x935
    	};
    	u32 sfdr_optim_vals[ARRAY_SIZE(sfdr_optim_regs)];
    
    	ret = ad9680_request_clks(conv);
    	if (ret)
    		return ret;
    
    #ifdef CONFIG_OF
    	if (spi->dev.of_node)
    		tmp = of_property_read_u32_array(
    			spi->dev.of_node, "adi,sfdr-optimization-config",
    			sfdr_optim_vals, ARRAY_SIZE(sfdr_optim_regs));
    #endif
    
    	ad9680_spi_write(spi, 0x000, 0x81);	// RESET
    	mdelay(5);
    	ad9680_spi_write(spi, 0x001, 0x01);	// RESET
    	mdelay(1);
    
    	ret = ad9680_spi_write(spi, 0x008, 0x03);	// select both channels
    //Configure DDC rakesh
    	dev_info(&conv->spi->dev, "Configure DDC Start \n");
    	ret = ad9680_spi_write(spi, 0x200, 0x03);	// rakesh Chip application mode for DDC0,DDC1,DDC2,DDC3
    	ret |= ad9680_spi_write(spi, 0x201, 0x04);	// rakesh  full sample rate (decimation = 16)
    	ret = ad9680_spi_write(spi, 0x300, 0x10);	// DDC reset 
    	ret = ad9680_spi_write(spi, 0x310, 0x42);
    	ret = ad9680_spi_write(spi, 0x330, 0x42);
    	ret = ad9680_spi_write(spi, 0x350, 0x42);		
    	ret = ad9680_spi_write(spi, 0x370, 0x42);
    	ret = ad9680_spi_write(spi, 0x311, 0x00);
    	ret = ad9680_spi_write(spi, 0x331, 0x00);
    	ret = ad9680_spi_write(spi, 0x351, 0x05);		
    	ret = ad9680_spi_write(spi, 0x371, 0x05); 
    //	NCO 0x555
    	ret = ad9680_spi_write(spi, 0x314, 0x55);
    	ret = ad9680_spi_write(spi, 0x315, 0x05);
    	ret = ad9680_spi_write(spi, 0x320, 0x00);
    	ret = ad9680_spi_write(spi, 0x321, 0x00);
    //	NCO 0x555
    	ret = ad9680_spi_write(spi, 0x334, 0x55);
    	ret = ad9680_spi_write(spi, 0x335, 0x05);
    	ret = ad9680_spi_write(spi, 0x340, 0x00);
    	ret = ad9680_spi_write(spi, 0x341, 0x00);
    //	NCO 0x555
    	ret = ad9680_spi_write(spi, 0x354, 0x55);
    	ret = ad9680_spi_write(spi, 0x355, 0x05);
    	ret = ad9680_spi_write(spi, 0x360, 0x00);
    	ret = ad9680_spi_write(spi, 0x361, 0x00);
    //	NCO 0x555
    	ret = ad9680_spi_write(spi, 0x374, 0x55);
    	ret = ad9680_spi_write(spi, 0x375, 0x05);
    	ret = ad9680_spi_write(spi, 0x380, 0x00);
    	ret = ad9680_spi_write(spi, 0x381, 0x00);
    	ret = ad9680_spi_write(spi, 0x300, 0x00);	// DDC reset release
    
    
    	if (tmp == 0) {
    		for (; tmp < ARRAY_SIZE(sfdr_optim_regs); tmp++)
    			ret |= ad9680_spi_write(spi, sfdr_optim_regs[tmp],
    						sfdr_optim_vals[tmp]);
    	}
    
    	memset(&link_config, 0x00, sizeof(link_config));
    	link_config.did = 0;
    	link_config.bid = 1;
    	link_config.num_lanes = 2;
    	for (i = 0; i < link_config.num_lanes; i++) {
    		link_config.lid[i] = i;
    		link_config.lane_mux[i] = i;
    	}
    	link_config.num_converters = 8;
    	link_config.octets_per_frame = 8;
    	link_config.frames_per_multiframe = 32;
    	link_config.converter_resolution = ad9234 ? 12 : 14;
    	link_config.bits_per_sample = 16;
    	link_config.scrambling = true;
    
    	if (conv->sysref_clk) {
    		link_config.subclass = 1;
    		link_config.sysref.mode = AD9680_SYSREF_CONTINUOUS;
    	} else {
    		link_config.subclass = 0;
    		link_config.sysref.mode = AD9680_SYSREF_DISABLED;
    	}
    
    	link_config.sysref.capture_falling_edge = true;
    	link_config.sysref.valid_falling_edge = false;
    
    	ret = ad9680_setup_link(spi, &link_config);
    	if (ret < 0)
    		goto err;
    
    	ret = ad9680_setup_jesd204_link(conv, conv->adc_clk);
    	if (ret < 0)
    		goto err;
    	mdelay(20);
    	pll_stat = ad9680_spi_read(conv->spi, 0x56f);
    
    	dev_info(&conv->spi->dev, "AD9680 PLL %s\n",
    		 pll_stat & 0x80 ? "LOCKED" : "UNLOCKED");
    
    	ret = clk_prepare_enable(conv->lane_clk);
    	if (ret < 0) {
    		dev_err(&spi->dev, "Failed to enable JESD204 link: %d\n", ret);
    		goto err;
    	}
    
    	return 0;
    err:
    	clk_disable_unprepare(conv->clk);
    	clk_disable_unprepare(conv->sysref_clk);
    
    	return ret;
    }
    
    static int ad9684_setup(struct spi_device *spi)
    {
    	struct axiadc_converter *conv = spi_get_drvdata(spi);
    	unsigned int clk_stat;
    	int ret;
    
    	conv->clk = devm_clk_get(&spi->dev, NULL);
    	if (IS_ERR(conv->clk))
    		return PTR_ERR(conv->clk);
    
    	ret = ad9680_spi_write(spi, 0x000, 0x81);
    	mdelay(10);
    	ret |= ad9680_spi_write(spi, 0x001, 0x02);
    	mdelay(10);
    
    	ret |= ad9680_spi_write(spi, 0x03f, 0x80);
    	ret |= ad9680_spi_write(spi, 0x040, 0xbf);
    	ret |= ad9680_spi_write(spi, 0x568, 0x01);
    
    	clk_stat = ad9680_spi_read(spi, 0x11c);
    	dev_info(&spi->dev, "AD9684 input clock %s\n",
    		 clk_stat & 0x01 ? "DETECTED" : "NOT DETECTED");
    
    	return ret;
    }
    
    static int ad9694_setup_jesd204_link(struct axiadc_converter *conv,
    	unsigned int sample_rate)
    {
    	unsigned long lane_rate_kHz;
    	unsigned long sysref_rate;
    	unsigned int val;
    	int ret;
    
    	if (conv->id == CHIPID_AD9094)
    		sysref_rate = DIV_ROUND_CLOSEST(sample_rate, 128);
    	else
    		sysref_rate = DIV_ROUND_CLOSEST(sample_rate, 32);
    	lane_rate_kHz = DIV_ROUND_CLOSEST(sample_rate, 100);
    
    	if (lane_rate_kHz < 1687500 || lane_rate_kHz > 15000000) {
    		dev_err(&conv->spi->dev, "Lane rate %lu Mbps out of bounds. Must be between 1687.5 and 15000 Mbps",
    			lane_rate_kHz / 1000);
    		return -EINVAL;;
    	}
    
    	if (lane_rate_kHz < 3375000)
    		val = 0x5;
    	else if (lane_rate_kHz < 6750000)
    		val = 0x1;
    	else if(lane_rate_kHz < 13500000)
    		val = 0x0;
    	else
    		val = 0x3;
    
    	ad9680_spi_write(conv->spi, 0x56e, val << 4); 
    	
    
    	/* Required sequence after link reset */
    	ad9680_spi_write(conv->spi, 0x1228, 0x4f);
    	ad9680_spi_write(conv->spi, 0x1228, 0x0f);
    	ad9680_spi_write(conv->spi, 0x1222, 0x04);
    	ad9680_spi_write(conv->spi, 0x1222, 0x00);
    	ad9680_spi_write(conv->spi, 0x1262, 0x08);
    	ad9680_spi_write(conv->spi, 0x1262, 0x00);
    
    	ret = clk_set_rate(conv->sysref_clk, sysref_rate);
    	if (ret < 0) {
    		dev_err(&conv->spi->dev, "Failed to set SYSREF clock to %lu kHz: %d\n",
    			sysref_rate / 1000, ret);
    		return ret;
    	}
    
    	ret = clk_set_rate(conv->lane_clk, lane_rate_kHz);
    	if (ret < 0) {
    		dev_err(&conv->spi->dev, "Failed to set lane rate to %lu kHz: %d\n",
    			lane_rate_kHz, ret);
    		return ret;
    	}
    
    	return 0;
    }
    
    static int ad9694_setup(struct spi_device *spi)
    {
    	struct axiadc_converter *conv = spi_get_drvdata(spi);
    	struct ad9680_jesd204_link_config link_config;
    	unsigned int pll_stat;
    	unsigned int val;
    	unsigned int i;
    	int ret;
    
    	ret = ad9680_request_clks(conv);
    	if (ret)
    		return ret;
    
    	ad9680_spi_write(spi, 0x000, 0x81); /* RESET */
    	mdelay(5);
    
    	/* Configure A/B */
    	ret |= ad9680_spi_write(spi, 0x009, 0x03); /* select pair A/B */
    	ret |= ad9680_spi_write(spi, 0x008, 0x03); /* select both channels */
    
    	ret |= ad9680_spi_write(spi, 0x108, 0x00); /* Clock divider = 1 */
    
    	memset(&link_config, 0x00, sizeof(link_config));
    	link_config.did = 0;
    	link_config.bid = 0;
    	link_config.num_lanes = 2;
    	for (i = 0; i < link_config.num_lanes; i++) {
    		link_config.lid[i] = i;
    		link_config.lane_mux[i] = i;
    	}
    	link_config.num_converters = 2;
    	link_config.octets_per_frame = 1;
    	link_config.frames_per_multiframe = 32;
    	link_config.converter_resolution = 8;
    	link_config.bits_per_sample = 8;
    	link_config.scrambling = true;
    
    	if (conv->sysref_clk) {
    		link_config.subclass = 1;
    		link_config.sysref.mode = AD9680_SYSREF_ONESHOT;
    	} else {
    		link_config.subclass = 0;
    		link_config.sysref.mode = AD9680_SYSREF_DISABLED;
    	}
    
    	link_config.sysref.capture_falling_edge = true;
    	link_config.sysref.valid_falling_edge = false;
    
    	ret = ad9680_setup_link(spi, &link_config);
    	if (ret < 0)
    		goto err;
    
    	ret |= ad9680_spi_write(spi, 0x001, 0x02); /* datapath soft reset */
    	mdelay(1);
    
    	ret = ad9694_setup_jesd204_link(conv, conv->adc_clk);
    	if (ret < 0)
    		goto err;
    	mdelay(20);
    	pll_stat = ad9680_spi_read(conv->spi, 0x56f);
    
    	dev_info(&conv->spi->dev, "%s PLL %s\n",
    		 (conv->id == CHIPID_AD9094) ? "AD9094" : "AD9694",
    		 pll_stat & 0x80 ? "LOCKED" : "UNLOCKED");
    
    	/* Re-arm the SYSREF in oneshot mode */
    	if (link_config.sysref.mode == AD9680_SYSREF_ONESHOT) {
    		val = 0x04;
    
    		if (link_config.sysref.capture_falling_edge)
    			val |= 0x08;
    
    		if (link_config.sysref.valid_falling_edge)
    			val |= 0x10;
    		ad9680_spi_write(spi, 0x120, val);
    	}
    
    	if (conv->id == CHIPID_AD9094) {
    		/* Export the common-mode voltage to the VCM_CD/VREF */
    		ad9680_spi_write(spi, 0x1908, 0x04);
    		ad9680_spi_write(spi, 0x18A6, 0x00);
    		ad9680_spi_write(spi, 0x18E6, 0x00);
    		ad9680_spi_write(spi, 0x18E0, 0x04);
    		ad9680_spi_write(spi, 0x18E1, 0x1c);
    		ad9680_spi_write(spi, 0x18E2, 0x14);
    		ad9680_spi_write(spi, 0x18E3, 0x56);
    
    		/* Set buffer 1 & 2 currents to 440 uA */
    		ad9680_spi_write(spi, 0x1A4C, 0x16);
    		ad9680_spi_write(spi, 0x1A4D, 0x16);
    
    		/* Set input full-scale range to 2.16Vpp */
    		ad9680_spi_write(spi, 0x1910, 0x00);
    	}
    
    	ret = clk_prepare_enable(conv->lane_clk);
    	if (ret < 0) {
    		dev_err(&spi->dev, "Failed to enable JESD204 link: %d\n", ret);
    		goto err;
    	}
    
    	schedule_delayed_work(&conv->watchdog_work, HZ);
    
    	conv->sample_rate_read_only = true;
    	conv->running = true;
    
    	return 0;
    err:
    	clk_disable_unprepare(conv->clk);
    	clk_disable_unprepare(conv->sysref_clk);
    	return ret;
    }
    
    static void ad9694_serdes_pll_watchdog(struct work_struct *work)
    {
    	struct axiadc_converter *conv =
    		container_of(work, struct axiadc_converter, watchdog_work.work);
    	unsigned int clock_detected, serdes_locked;
    	int ret;
    
    	clock_detected = ad9680_spi_read(conv->spi, 0x11b);
    	serdes_locked = ad9680_spi_read(conv->spi, 0x56f);
    
    	/* Restart if clock is detected, but SERDES is not locked */
    	if ((clock_detected & 0x01) && !(serdes_locked & 0x80)) {
    		dev_err(&conv->spi->dev, "Lost SERDES PLL lock, re-initializing.");
    
    		if (conv->running) {
    			clk_disable_unprepare(conv->lane_clk);
    			conv->running = false;
    		}
    
    		 /* datapath soft reset */
    		ad9680_spi_write(conv->spi, 0x001, 0x02);
    		mdelay(1);
    
    		/* Required sequence after link reset */
    		ad9680_spi_write(conv->spi, 0x1228, 0x4f);
    		ad9680_spi_write(conv->spi, 0x1228, 0x0f);
    		ad9680_spi_write(conv->spi, 0x1222, 0x04);
    		ad9680_spi_write(conv->spi, 0x1222, 0x00);
    		ad9680_spi_write(conv->spi, 0x1262, 0x08);
    		ad9680_spi_write(conv->spi, 0x1262, 0x00);
    
    		mdelay(20);
    		serdes_locked = ad9680_spi_read(conv->spi, 0x56f);
    
    		dev_info(&conv->spi->dev, "AD9694 PLL %s\n",
    			 (serdes_locked & 0x80) ? "LOCKED" : "UNLOCKED");
    
    		ret = clk_prepare_enable(conv->lane_clk);
    		WARN_ON(!!ret);
    		if (ret == 0)
    			conv->running = true;
    	}
    
    	schedule_delayed_work(&conv->watchdog_work, HZ);
    }
    
    
    
    static int ad9680_read_raw(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan, int *val, int *val2, long info)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    
    	switch (info) {
    	case IIO_CHAN_INFO_SCALE:
    		return ad9680_get_scale(conv, chan, val, val2);
    	case IIO_CHAN_INFO_SAMP_FREQ:
    		if (!conv->clk)
    			return -ENODEV;
    
    		*val = conv->adc_clk = clk_get_rate_scaled(conv->clk, &conv->adc_clkscale);
    
    		return IIO_VAL_INT;
    
    	}
    	return -EINVAL;
    }
    
    static int ad9680_write_raw(struct iio_dev *indio_dev,
    	const struct iio_chan_spec *chan, int val, int val2, long info)
    {
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	unsigned long r_clk;
    	int ret;
    
    	switch (info) {
    	case IIO_CHAN_INFO_SCALE:
    		return ad9680_set_scale(conv, chan, val, val2);
    	case IIO_CHAN_INFO_SAMP_FREQ:
    		if (!conv->clk)
    			return -ENODEV;
    
    		if (chan->extend_name)
    			return -ENODEV;
    
    		if (conv->sample_rate_read_only)
    			return -EPERM;
    
    		if (conv->id == CHIPID_AD9680)
    			return ad9680_set_sample_rate(conv, val);
    
    		r_clk = clk_round_rate(conv->clk, val);
    		if (r_clk < 0 || r_clk > conv->chip_info->max_rate) {
    			dev_warn(&conv->spi->dev,
    				 "Error setting ADC sample rate %ld", r_clk);
    			return -EINVAL;
    		}
    
    		ret = clk_set_rate(conv->clk, r_clk);
    		if (ret < 0)
    			return ret;
    		break;
    	default:
    		return -EINVAL;
    	}
    
    	return 0;
    }
    
    static int ad9680_request_fd_irqs(struct axiadc_converter *conv)
    {
    	struct device *dev = &conv->spi->dev;
    	struct gpio_desc *gpio;
    
    	gpio = devm_gpiod_get(dev, "fastdetect-a", GPIOD_IN);
    	if (!IS_ERR(gpio)) {
    		int ret, irq = gpiod_to_irq(gpio);
    		if (irq < 0)
    			return irq;
    
    		ret = devm_request_threaded_irq(dev,
    				irq, NULL, ad9680_fdA_handler,
    				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
    				"fastdetect-a", conv);
    		if (ret < 0)
    			return ret;
    	}
    
    	gpio = devm_gpiod_get(dev, "fastdetect-b", GPIOD_IN);
    	if (!IS_ERR(gpio)) {
    		int ret, irq = gpiod_to_irq(gpio);
    		if (irq < 0)
    			return irq;
    
    		ret = devm_request_threaded_irq(dev,
    				irq, NULL, ad9680_fdB_handler,
    				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
    				"fastdetect-b", conv);
    		if (ret < 0)
    			return ret;
    	}
    
    	return 0;
    }
    
    static int ad9680_post_setup(struct iio_dev *indio_dev)
    {
    	struct axiadc_state *st = iio_priv(indio_dev);
    	struct axiadc_converter *conv = iio_device_get_drvdata(indio_dev);
    	int i;
    
    	for (i = 0; i < conv->chip_info->num_channels; i++) {
    		axiadc_write(st, ADI_REG_CHAN_CNTRL_2(i),
    			     (i & 1) ? 0x00004000 : 0x40000000);
    		axiadc_write(st, ADI_REG_CHAN_CNTRL(i),
    			     ADI_FORMAT_SIGNEXT | ADI_FORMAT_ENABLE |
    			     ADI_IQCOR_ENB | ADI_ENABLE);
    	}
    
    	return 0;
    }
    
    static int ad9680_probe(struct spi_device *spi)
    {
    	bool master_slave_2x_quirk = false;
    	struct axiadc_converter *conv;
    	int ret;
    
    	conv = devm_kzalloc(&spi->dev, sizeof(*conv), GFP_KERNEL);
    	if (conv == NULL)
    		return -ENOMEM;
    
    	conv->adc_clkscale.mult = 1;
    	conv->adc_clkscale.div = 1;
    
    	INIT_DELAYED_WORK(&conv->watchdog_work, ad9694_serdes_pll_watchdog);
    
    	spi_set_drvdata(spi, conv);
    	conv->spi = spi;
    
    	conv->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown",
    		GPIOD_OUT_LOW);
    	if (IS_ERR(conv->pwrdown_gpio))
    		return PTR_ERR(conv->pwrdown_gpio);
    
    	conv->id = ad9680_spi_read(spi, AD9680_REG_CHIP_ID_LOW);
    	if (conv->id != spi_get_device_id(spi)->driver_data) {
    		dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", conv->id);
    		return -ENODEV;
    	}
    
    	switch (conv->id) {
    	case CHIPID_AD9234:
    		conv->chip_info = &axiadc_chip_info_tbl[ID_AD9234];
    		ret = ad9680_setup(spi, true);
    		break;
    	case CHIPID_AD9680:
    #ifdef CONFIG_OF
    		if (spi->dev.of_node)
    			master_slave_2x_quirk = of_property_read_bool(
    				spi->dev.of_node, "adi,master-slave-2x-quirk");
    #endif
    		conv->chip_info = &axiadc_chip_info_tbl[master_slave_2x_quirk ?
    			ID_AD9680_x2 : ID_AD9680];
    		ret = ad9680_setup(spi, false);
    		break;
    	case CHIPID_AD9684:
    		conv->chip_info = &axiadc_chip_info_tbl[ID_AD9684];
    		ret = ad9684_setup(spi);
    		break;
    	case CHIPID_AD9694:
    		conv->chip_info = &axiadc_chip_info_tbl[ID_AD9694];
    		ret = ad9694_setup(spi);
    		break;
    	case CHIPID_AD9094:
    		conv->chip_info = &axiadc_chip_info_tbl[ID_AD9094];
    		ret = ad9694_setup(spi);
    		break;
    	default:
    		dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", conv->id);
    		return -ENODEV;
    	}
    
    	if (ret) {
    		if (ret != -EPROBE_DEFER)
    			dev_err(&spi->dev, "Failed to initialize: %d\n", ret);
    		return ret;
    	}
    
    	conv->adc_output_mode = AD9680_OUTPUT_MODE_TWOS_COMPLEMENT;
    	ret = ad9680_outputmode_set(spi, conv->adc_output_mode);
    	if (ret < 0)
    		return ret;
    
    	conv->reg_access = ad9680_reg_access;
    	conv->write_raw = ad9680_write_raw;
    	conv->read_raw = ad9680_read_raw;
    	conv->read_event_value = ad9680_read_thresh,
    	conv->write_event_value = ad9680_write_thresh,
    	conv->read_event_config = ad9680_read_thresh_en,
    	conv->write_event_config = ad9680_write_thresh_en,
    	conv->post_setup = ad9680_post_setup;
    	conv->set_pnsel = ad9680_set_pnsel;
    
    	device_create_file(&spi->dev, &dev_attr_status);
    
    	if (conv->id == CHIPID_AD9680) {
    		ret = ad9680_request_fd_irqs(conv);
    		if (ret < 0)
    			return ret;
    
    		/* Enable Fast Detect output */
    		ret = ad9680_spi_write(spi, AD9680_REG_THRESH_CTRL, 0x1);
    		if (ret < 0)
    			return ret;
    	}
    
    	return 0;
    }
    
    static int ad9680_remove(struct spi_device *spi)
    {
    	struct axiadc_converter *conv = spi_get_drvdata(spi);
    
    	cancel_delayed_work_sync(&conv->watchdog_work);
    	if (conv->running) {
    		clk_disable_unprepare(conv->lane_clk);
    		clk_disable_unprepare(conv->sysref_clk);
    		clk_disable_unprepare(conv->clk);
    		conv->running = false;
    	}
    
    	return 0;
    }
    
    static const struct spi_device_id ad9680_id[] = {
    	{ "ad9680", CHIPID_AD9680 },
    	{ "ad9234", CHIPID_AD9234 },
    	{ "ad9684", CHIPID_AD9684 },
    	{ "ad9694", CHIPID_AD9694 },
    	{ "ad9094", CHIPID_AD9094 },
    	{}
    };
    MODULE_DEVICE_TABLE(spi, ad9680_id);
    
    static struct spi_driver ad9680_driver = {
    	.driver = {
    		   .name = "ad9680",
    		   .owner = THIS_MODULE,
    	},
    	.probe = ad9680_probe,
    	.remove = ad9680_remove,
    	.id_table = ad9680_id,
    };
    module_spi_driver(ad9680_driver);
    
    MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
    MODULE_DESCRIPTION("Analog Devices AD9680 ADC");
    MODULE_LICENSE("GPL v2");
    

    With this change i could observe proper values in AD9680 registers.

    But still I do not get any output at FPGA side. So i guess AD9680 is not configured properly to transmit data to FPGA.

    Please help

  • Hello Dan,

    Any updates??

    Regards

    Rakesh M.

Reply Children
No Data