Skip to content
95 changes: 95 additions & 0 deletions arch/arm/boot/dts/xilinx/zynq-zed-adv7511-adaq23875.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Analog Devices ADAQ23875/LTC2387-16
*
* hdl_project: <adaq2387x/zed with make parameter ADC_RES=16>
* for all config modes, please check the README of the HDL project
* board_revision: <A>
*
* Copyright (C) 2022 - 2025 Analog Devices Inc.
*/
/dts-v1/;

#include "zynq-zed.dtsi"
#include "zynq-zed-adv7511.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pwm/pwm.h>

/ {
vref: regulator-vref {
compatible = "regulator-fixed";
regulator-name = "fixed-supply";
regulator-min-microvolt = <4096000>;
regulator-max-microvolt = <4096000>;
regulator-always-on;
};

clocks {
ext_clk: clock@0 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <100000000>;
};
};
gpio-control@0 {
compatible = "adi,one-bit-adc-dac";
#address-cells = <1>;
#size-cells = <0>;
out-gpios = <&gpio0 86 GPIO_ACTIVE_HIGH>,
<&gpio0 87 GPIO_ACTIVE_HIGH>;
channel@0 {
reg = <0>;
label = "adaq23875_testpat";
};
channel@1 {
reg = <1>;
label = "adaq23875_pd";
};
};
};

&fpga_axi {
rx_dma: dma-controller@44a30000 {
compatible = "adi,axi-dmac-1.00.a";
reg = <0x44a30000 0x1000>;
#dma-cells = <1>;
interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkc 15>;

adi,channels {
#size-cells = <0>;
#address-cells = <1>;

dma-channel@0 {
reg = <0>;
adi,source-bus-width = <16>;
adi,source-bus-type = <2>;
adi,destination-bus-width = <64>;
adi,destination-bus-type = <0>;
};
};
};

axi_pwm_gen: pwm@44a60000 {
compatible = "adi,axi-pwmgen-2.00.a";
reg = <0x44a60000 0x1000>;
label = "adaq23875_if";
#pwm-cells = <2>;
clocks = <&clkc 15>, <&ext_clk>;
clock-names = "axi", "ext";
};

adaq23875@0 {
compatible = "adaq23875";
clocks = <&ext_clk>;
dmas = <&rx_dma 0>;
dma-names = "rx";
pwms = <&axi_pwm_gen 0 0
&axi_pwm_gen 1 0>;
pwm-names = "cnv", "clk_en";
vref-supply = <&vref>;

// uncomment the below command to use in one lane mode
// adi,use-one-lane;
};
};
95 changes: 95 additions & 0 deletions arch/arm/boot/dts/xilinx/zynq-zed-adv7511-adaq23878.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Analog Devices ADAQ23878
*
* hdl_project: <adaq2387x/zed>
* for all config modes, please check the README of the HDL project
* board_revision: <A>
*
* Copyright (C) 2022 - 2025 Analog Devices Inc.
*/
/dts-v1/;

#include "zynq-zed.dtsi"
#include "zynq-zed-adv7511.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pwm/pwm.h>

/ {
vref: regulator-vref {
compatible = "regulator-fixed";
regulator-name = "fixed-supply";
regulator-min-microvolt = <4096000>;
regulator-max-microvolt = <4096000>;
regulator-always-on;
};

clocks {
ext_clk: clock@0 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <100000000>;
};
};
gpio-control@0 {
compatible = "adi,one-bit-adc-dac";
#address-cells = <1>;
#size-cells = <0>;
out-gpios = <&gpio0 86 GPIO_ACTIVE_HIGH>,
<&gpio0 87 GPIO_ACTIVE_HIGH>;
channel@0 {
reg = <0>;
label = "adaq23878_testpat";
};
channel@1 {
reg = <1>;
label = "adaq23878_pd";
};
};
};

&fpga_axi {
rx_dma: dma-controller@44a30000 {
compatible = "adi,axi-dmac-1.00.a";
reg = <0x44a30000 0x1000>;
#dma-cells = <1>;
interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkc 15>;

adi,channels {
#size-cells = <0>;
#address-cells = <1>;

dma-channel@0 {
reg = <0>;
adi,source-bus-width = <32>;
adi,source-bus-type = <2>;
adi,destination-bus-width = <64>;
adi,destination-bus-type = <0>;
};
};
};

axi_pwm_gen: pwm@44a60000 {
compatible = "adi,axi-pwmgen-2.00.a";
reg = <0x44a60000 0x1000>;
label = "adaq23878_if";
#pwm-cells = <2>;
clocks = <&clkc 15>, <&ext_clk>;
clock-names = "axi", "ext";
};

adaq23878@0{
compatible = "adaq23878";
clocks = <&ext_clk>;
dmas = <&rx_dma 0>;
dma-names = "rx";
pwms = <&axi_pwm_gen 0 0
&axi_pwm_gen 1 0>;
pwm-names = "cnv", "clk_en";
vref-supply = <&vref>;

// uncomment the below command to use in one lane mode
// adi,use-one-lane;
};
};
21 changes: 18 additions & 3 deletions arch/arm/boot/dts/xilinx/zynq-zed-adv7511-cn0577.dts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Analog Devices LTC2387
* Analog Devices LTC2387-18
*
* hdl_project: <cn0577/zed>
* for all config modes, please check the README of the HDL project
* board_revision: <A>
*
* Copyright (C) 2022 Analog Devices Inc.
* Copyright (C) 2022 - 2025 Analog Devices Inc.
*/
/dts-v1/;

Expand Down Expand Up @@ -54,6 +55,19 @@
#dma-cells = <1>;
interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkc 15>;

adi,channels {
#size-cells = <0>;
#address-cells = <1>;

dma-channel@0 {
reg = <0>;
adi,source-bus-width = <32>;
adi,source-bus-type = <2>;
adi,destination-bus-width = <64>;
adi,destination-bus-type = <0>;
};
};
};

axi_pwm_gen: pwm@44a60000 {
Expand All @@ -75,6 +89,7 @@
pwm-names = "cnv", "clk_en";
vref-supply = <&vref>;

adi,use-two-lanes;
// uncomment the below command to use in one lane mode
// adi,use-one-lane;
};
};
40 changes: 33 additions & 7 deletions drivers/iio/adc/ltc2387.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,33 +187,55 @@ static int ltc2387_set_sampling_freq(struct ltc2387_dev *ltc, int freq)

cnv_wf.period_length_ns = div_u64_rem((u64)DIV_ROUND_UP(ltc->ref_clk_rate, freq) * NSEC_PER_SEC,
ltc->ref_clk_rate, &rem);
if (rem)
pr_err("\nadaq2387 rem=%u", rem);
pr_err("\nadaq2387 round up=%llu", (u64)DIV_ROUND_UP(ltc->ref_clk_rate, freq));
pr_err("\nadaq2387 ltc->ref_clk_rate=%lu", ltc->ref_clk_rate);
pr_err("\nadaq2387 ref_clk_period_ns=%llu", ref_clk_period_ns);
pr_err("\nadaq2387 cnv_wf.period_length_ns=%llu", cnv_wf.period_length_ns);
pr_err("\nadaq2387 cnv_wf.duty_length_ns=%llu", cnv_wf.duty_length_ns);
pr_err("\nadaq2387 cnv_wf.duty_offset_ns=%llu", cnv_wf.duty_offset_ns);
if (rem) {
cnv_wf.period_length_ns += 1;
pr_err("\nadaq2387 cnv_wf.period_length_ns=%llu", cnv_wf.period_length_ns);
}

ret = pwm_set_waveform_might_sleep(ltc->cnv, &cnv_wf, false);
if (ret < 0)
return ret;

/* Gate the active period of the clock (see page 10-13 for both LTC's) */
if (ltc->lane_mode == TWO_LANES)
if (ltc->lane_mode == TWO_LANES) {
clk_en_time = DIV_ROUND_UP_ULL(ltc->device_info->resolution, 4);
else
pr_err("\nadaq2387 TWOLANE=1\n");
} else {
clk_en_time = DIV_ROUND_UP_ULL(ltc->device_info->resolution, 2);
pr_err("\nadaq2387 TWOLANE=0\n");
}

clk_gate_wf.period_length_ns = cnv_wf.period_length_ns;
clk_gate_wf.duty_length_ns = ref_clk_period_ns * clk_en_time;
clk_gate_wf.duty_offset_ns = LTC2387_T_FIRSTCLK_NS;

if (clk_gate_wf.duty_offset_ns > clk_gate_wf.period_length_ns)
pr_err("\nadaq2387 clk_en_time=%d", clk_en_time);
pr_err("\nadaq2387 clk_gate_wf.period_length_ns=%llu", clk_gate_wf.period_length_ns);
pr_err("\nadaq2387 clk_gate_wf.duty_length_ns=%llu", clk_gate_wf.duty_length_ns);
pr_err("\nadaq2387 clk_gate_wf.duty_offset_ns=%llu", clk_gate_wf.duty_offset_ns);

if (clk_gate_wf.duty_offset_ns >= clk_gate_wf.period_length_ns)
div64_u64_rem(clk_gate_wf.duty_offset_ns, clk_gate_wf.period_length_ns,
&clk_gate_wf.duty_offset_ns);

//if (clk_gate_wf.duty_offset_ns == clk_gate_wf.period_length_ns)
// clk_gate_wf.duty_offset_ns = 0;

pr_err("\nadaq2387 clk_gate_wf.duty_offset_ns=%llu", clk_gate_wf.duty_offset_ns);
ret = pwm_set_waveform_might_sleep(ltc->clk_en, &clk_gate_wf, false);
if (ret < 0)
return ret;

ltc->sampling_freq = freq;
ltc->sampling_freq = (u64)DIV_ROUND_UP(NSEC_PER_SEC, (u32)clk_gate_wf.period_length_ns);

pr_err("\nadaq2387 freq=%ld\n", freq);
return 0;
}

Expand All @@ -222,9 +244,12 @@ static int ltc2387_setup(struct iio_dev *indio_dev)
struct ltc2387_dev *ltc = iio_priv(indio_dev);
struct device *dev = indio_dev->dev.parent;

if (device_property_present(dev, "adi,use-two-lanes"))
ltc->lane_mode = TWO_LANES;
if (device_property_present(dev, "adi,use-one-lane")) {
ltc->lane_mode = ONE_LANE;
return ltc2387_set_sampling_freq(ltc, 7.5 * MHz);
}

ltc->lane_mode = TWO_LANES;
return ltc2387_set_sampling_freq(ltc, 15 * MHz);
}

Expand Down Expand Up @@ -365,6 +390,7 @@ static int ltc2387_probe(struct platform_device *pdev)
if (ret)
return ret;
ltc->ref_clk_rate = clk_get_rate(ltc->ref_clk);
pr_err("\nadaq2387 ltc->ref_clk_rate=%lu", ltc->ref_clk_rate);

ltc->clk_en = devm_pwm_get(&pdev->dev, "clk_en");
if (IS_ERR(ltc->clk_en))
Expand Down
2 changes: 2 additions & 0 deletions drivers/pwm/pwm-axi-pwmgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ static int axi_pwmgen_round_waveform_tohw(struct pwm_chip *chip,
}
}

pr_err("\nadaq2387 din pwmgen: pwm#%u: %lld/%lld [+%lld] @%lu -> PERIOD: %08x, DUTY: %08x, OFFSET: %08x\n", pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
ddata->clk_rate_hz, wfhw->period_cnt, wfhw->duty_cycle_cnt, wfhw->duty_offset_cnt);
dev_dbg(&chip->dev, "pwm#%u: %lld/%lld [+%lld] @%lu -> PERIOD: %08x, DUTY: %08x, OFFSET: %08x\n",
pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
ddata->clk_rate_hz, wfhw->period_cnt, wfhw->duty_cycle_cnt, wfhw->duty_offset_cnt);
Expand Down
Loading