Re: [PATCH v2 1/2] dt-bindings: iio: adc: Add AD4000

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 04/20, Jonathan Cameron wrote:
> On Tue, 16 Apr 2024 18:46:11 -0300
> Marcelo Schmitt <marcelo.schmitt1@xxxxxxxxx> wrote:
> 
> > So, I have been trying to make this work, though I haven't been successful so
> > far, and I don't really think using pinctrl is a good solution for this either.
> > 
> > Comments inline.
> > 
> > On 04/14, Jonathan Cameron wrote:
> > > On Sat, 13 Apr 2024 12:33:54 -0500
> > > David Lechner <dlechner@xxxxxxxxxxxx> wrote:
> > >   
> > > > On 4/13/24 11:14 AM, Jonathan Cameron wrote:  
> > > > > On Tue, 9 Apr 2024 12:30:09 -0300
> > > > > Marcelo Schmitt <marcelo.schmitt1@xxxxxxxxx> wrote:
> > > > >     
> > > > >> On 04/08, David Lechner wrote:    
> > > > >>> On Mon, Apr 8, 2024 at 9:32 AM Marcelo Schmitt
> > > > >>> <marcelo.schmitt@xxxxxxxxxx> wrote:      
> > > > >>>>    
> > > > 
> > > > ...
> > > >   
> > 
> > ...
> > 

...

> > 
> > The pinctrl configuration for this ADC would not be meant to change once after
> > boot as it looks to be the usual use case for pinctrl (including mediatek-bluetooth.txt).
> > 
> > Also, no suitable mux for the "3-wire" mode in
> > Documentation/devicetree/bindings/pinctrl/xlnx,pinctrl-zynq.yaml
> > to do it like Documentation/devicetree/bindings/net/mediatek-bluetooth.txt.
> > The zynq pinctrl driver (drivers/pinctrl/pinctrl-zynq.c) would have to be
> > updated to add the new mux function in 
> > static const struct zynq_pinmux_function zynq_pmux_functions[] = {
> > 	DEFINE_ZYNQ_PINMUX_FUNCTION(ethernet0, 1),
> > ...
> > 	DEFINE_ZYNQ_PINMUX_FUNCTION(axi_spi_single, 1),
> > 	DEFINE_ZYNQ_PINMUX_FUNCTION(axi_spi_multi, 2),
> > though this is not really a thing that's on zynq, but one that is related to
> > these ADCs so I'm not sure it should go there.
> 
> 
> I'd argue we are after a specific SPI controller setup for this.
> A controller driver would need modifying to make it work.

Ack, makes sense to me.

> 
> > 
> > > > For example, if we wanted to use 3-wire mode for reading
> > > > data, we would set the pinctrl to "default" to write the
> > > > register to configure the chip during driver probe. Then
> > > > to read data, we would change the pinctrl to "single" before
> > > > doing the SPI xfer to ensure that the ADC SDI pin is pulled
> > > > high independent of what the SDO line of the SPI controller
> > > > is currently doing.  
> > 
> > No, the pin configuration for this ADCs would be expected to change unrestricted
> > amount of times. The pin configuration would have to change every time a sample
> > read is made after a register access transfers and vice-versa. If we decide
> > to support span compression, every change to _scale would lead to pinctrl
> > configuration change.
> > 
> > At pin level, we would want to rise SPI controller SDO line to VIO but then
> > the new SDO pin config would conflict with SPI pin group config.
> > 
> > I included pinctrl properties in my test dts to make use of pinctrl framework.
> > Yet, that doesn't really alternate SPI line configuration we are using because
> > the SPI function that is in the PS (FPGA's Processing System) is not what we are
> > interfacing when using spi-engine. Copy of my test dts at end of email.
> > 
> > Currently, the SPI controller we are using to test with these exotic ADCs
> > is the spi-engine which is implemented in the FPGA as an IP block which
> > owns control of the bus lines (SPI, SDO, CS, ...). To alternate the
> > configuration of SPI lines (pull SDO (ADC SDI) up to VIO, connect controller CS
> > to ADC SDI, etc.) I think it should be done in the HDL project. I don't think
> > it's a good idea to hijack spi-engine lines through pinctrl.
> 
> Such functionality would need to be pushed to the spi controller driver
> which could know if there was any need to do anything like this, or if there
> was simply a register to set.
> 

Ack.

> > 
> > > 
> > > Ah ok.  This is implying that we are switching to a controllable
> > > mode to pull that pin high (or I guess one where it is always
> > > high).  I'm not sure if that's more common than an SPI controller
> > > where you can set the 'don't' care state to high or low.
> > > I assume we can't get away with just setting the output buffer
> > > to all 1s because it won't hold that state between transfers?  
> > 
> > I tried sending the tx buffer filled with 1s when testing this with a RPi4 but
> > it brought the controller SDO (ADC SDI) line low between each 8 bits of transfer
> > (attaching an image (yellow line is SCLK, green lines is controller SDO)).
> 
> Pity - thought that was overly optimistic.
> 
> > Anyway, can we have any guaranties with respect to controller SDO line behaviour
> > when its not clocking out data?
> 
> 
> > 
> > > 
> > > Feels like that could be rolled into the SPI subsystem with
> > > any necessary transitions handled there (maybe)  
> > 
> > To me, this sounds more reasonable than pinctrl.
> > Yeah, if we can set a don't' care state for the SDO line then that should be
> > enough for these ADCs.
> > Otherwise, can we really do anything if the controller can't keep SDO high?
> 
> There is one similar (ish) entry already.
> https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/spi/spi.h#L29
> #define	SPI_3WIRE_HIZ		_BITUL(15)	/* high impedance turnaround */
> in that it is controlling state in what I think would normally be a don't care state.
> 
> I think we could have an
> SPI_SDO_DONT_CARE_HIGH (naming to be improved upon ;) 
> that a driver could advertise support for and the spi device could request.
> 
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/panel/panel-tpo-tpg110.c#L429
> 
> Implement that in the spi-gpio driver as a PoC probably and in your SPI copntoller
> driver.
> 
> Ultimately if the controller really isn't capable (including dances through pin
> mode changes if necessary) then the ADC won't work in this wiring with that host
> controller.
> 
> I'd propose something along these lines and see whether Mark + any other active
> SPI folk think it is reasonable or not?

Sounds promising. Will try implement something like that.

> 
> > 
> > > 
> > > Just to check, this isn't just a case of a missing pull up
> > > resistor to drag that line correctly when it isn't actively
> > > driven (combined with all 1s in the write buffer) etc?  
> > 
> > When using spi-engine, the controller SDO is connected to ADC SDI, controller
> > CS to ADC CNV and, for reg access, it works as conventional SPI.
> > spi-engine leaves the SDO line the state it was after last transfer so it we
> > can make it idle high during sample read. No hardware pull-up needed.
> 
> Fair enough. No multi master support I guess (that is a bit obscure for
> SPI).  A little ugly that it's dependent on the last access - so you would need
> to do a dummy access if the normal last bit was wrong level?

Seems I've been lucky with it but yes, we would need a dummy transfer to put
controller SDO line in the desired state. I'm thinking it should not be
difficult to make spi-engine SDO line always idle high (or idle in a
pre-configured state). I'll talk with the guys in the HDL team and what can be
done about it.

Thanks,
Marcelo

> 
> Jonathan
> 
> > 
> > Marcelo
> > 
> > > 
> > > Jonathan
> > > 
> > >   
> > 
> > The device tree source file I was using for testing with the ADC with the
> > changes for using pinctrl. Didn't really work.
> > 
> > // SPDX-License-Identifier: GPL-2.0
> > /*
> >  * Analog Devices ADAQ4003
> >  * https://wiki.analog.com/resources/tools-software/linux-drivers/iio-adc/ad400x
> >  * https://wiki.analog.com/resources/eval/user-guides/ad400x
> >  *
> >  * hdl_project: <pulsar_adc_pmdz/zed>
> >  * board_revision: <>
> >  *
> >  * Copyright (C) 2016-2023 Analog Devices Inc.
> >  */
> > /dts-v1/;
> > 
> > #include "zynq-zed.dtsi"
> > #include "zynq-zed-adv7511.dtsi"
> > #include <dt-bindings/pinctrl/pinctrl-zynq.h>
> > 
> > / {
> > 	adc_vref: regulator-vref {
> > 		compatible = "regulator-fixed";
> > 		regulator-name = "EVAL 5V Vref";
> > 		regulator-min-microvolt = <5000000>;
> > 		regulator-max-microvolt = <5000000>;
> > 		regulator-always-on;
> > 	};
> > 
> > 	adc_vdd: regulator-vdd {
> > 		compatible = "regulator-fixed";
> > 		regulator-name = "Eval VDD supply";
> > 		regulator-min-microvolt = <1800000>;
> > 		regulator-max-microvolt = <1800000>;
> > 		regulator-always-on;
> > 	};
> > 
> > 	adc_vio: regulator-vio {
> > 		compatible = "regulator-fixed";
> > 		regulator-name = "Eval VIO supply";
> > 		regulator-min-microvolt = <3300000>;
> > 		regulator-max-microvolt = <3300000>;
> > 		regulator-always-on;
> > 	};
> > };
> > 
> > &pinctrl0 {
> > 	/* Restore conventional SPI pin configuration */
> > 	pinctrl_spi_default: default_config {
> > 		mux {
> > 			/* Are these the ones used by spi-engine? */
> > 			groups = "spi0_0_grp";
> > 			function = "spi0";
> > 		};
> > 		conf {
> > 			groups = "spi0_0_grp";
> > 			power-source = <IO_STANDARD_LVCMOS33>;
> > 		};
> > 		conf-spi-sdo {
> > 			pins = "MIO17"; /* SPI0 SDO? */
> > 			bias-disable;
> > 		};
> > 	};
> > 
> > 	/* Pull-up SPI SDO (ADC SDI) to VIO */
> > 	pinctrl_spi_single: single_config {
> > 		conf-spi-sdo {
> > 			pins = "MIO17"; /* Conflicts with SPI0 pin group */
> > 			bias-pull-up;
> > 		};
> > 	};
> > };
> > 
> > &fpga_axi {
> > 	rx_dma: rx-dmac@44a30000 {
> > 		compatible = "adi,axi-dmac-1.00.a";
> > 		reg = <0x44a30000 0x1000>;
> > 		#dma-cells = <1>;
> > 		interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
> > 		clocks = <&clkc 17>;
> > 
> > 		adi,channels {
> > 			#size-cells = <0>;
> > 			#address-cells = <1>;
> > 
> > 			dma-channel@0 {
> > 				reg = <0>;
> > 				adi,source-bus-width = <32>;
> > 				adi,source-bus-type = <1>;
> > 				adi,destination-bus-width = <64>;
> > 				adi,destination-bus-type = <0>;
> > 			};
> > 		};
> > 	};
> > 
> > 	axi_pwm_gen: axi-pwm-gen@ {
> > 		compatible = "adi,axi-pwmgen";
> > 		reg = <0x44b00000 0x1000>;
> > 		label = "cnv";
> > 		#pwm-cells = <2>;
> > 		clocks = <&spi_clk>;
> > 	};
> > 
> > 	spi_clk: axi-clkgen@44a70000 {
> > 		compatible = "adi,axi-clkgen-2.00.a";
> > 		reg = <0x44a70000 0x10000>;
> > 		#clock-cells = <0>;
> > 		clocks = <&clkc 15>, <&clkc 15>;
> > 		clock-names = "s_axi_aclk", "clkin1";
> > 		clock-output-names = "spi_clk";
> > 	};
> > 
> > 	axi_spi_engine_0: spi@44a00000 {
> > 		compatible = "adi,axi-spi-engine-1.00.a";
> > 		reg = <0x44a00000 0x1000>;
> > 		interrupt-parent = <&intc>;
> > 		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
> > 		clocks = <&clkc 15 &spi_clk>;
> > 		clock-names = "s_axi_aclk", "spi_clk";
> > 		num-cs = <1>;
> > 
> > 		#address-cells = <0x1>;
> > 		#size-cells = <0x0>;
> > 
> > 		adaq4003: adc@0 {
> > 			compatible = "adi,adaq4003";
> > 			reg = <0>;
> > 			spi-max-frequency = <102000000>;
> > 			spi-cpha;
> > 			pinctrl-names = "default", "single";
> > 			pinctrl-0 = <&pinctrl_spi_default>;
> > 			pinctrl-1 = <&pinctrl_spi_single>;
> > 			vdd-supply = <&adc_vdd>;
> > 			vio-supply = <&adc_vio>;
> > 			ref-supply = <&adc_vref>;
> > 			adi,high-z-input;
> > 			adi,gain-milli = <454>;
> > 		};
> > 	};
> > };
> 




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux