1

I'm trying to enable two instances of AD7606 SPI driver for AD7606C. In order for ADC to start the conversion GPIO pins for CONVST (conversion start), interrupt pin (BUSY pin) and RESET pin have to be defined in the device tree for the driver to use.

Two ADCs are on the SPI bus, each ADC has it's own chip select pin and interrupt/BUSY pin but CONVST and RESET are hardwired and shared between two ADCs, on the same pins.

Device tree is given below, and platform used is STM32MP157C Odyssey.

&spi2 {
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi2_pins_mx>;
pinctrl-1 = <&spi2_sleep_pins_mx>;
status = "okay";

num-cs = <2>;
cs-gpios = <&gpiob 12 GPIO_ACTIVE_LOW>, // ADC CS1
            <&gpiod 4 GPIO_ACTIVE_LOW>; // ADC CS2

adc0@0 {
    compatible = "adi,ad7606b";
    reg = <0>;
    spi-max-frequency = <10000000>; // <60MHz if Vdrive > 2.7V, <40MHz if < 2.7V
    spi-cpol;
    spi-cpha;
    avcc-supply = <&vref>;
    interrupts = <10 IRQ_TYPE_EDGE_FALLING>;    // Port and pin number where BUSY pin is connected
    interrupt-parent = <&gpioe>;
    adi,conversion-start-gpios = <&gpiof 10 GPIO_ACTIVE_HIGH>;
    reset-gpios = <&gpioc 0 GPIO_ACTIVE_HIGH>;
    adi,sw-mode;
};

adc1@1 {
    compatible = "adi,ad7606b";
    reg = <1>;
    spi-max-frequency = <10000000>;
    spi-cpol;
    spi-cpha;
    avcc-supply = <&vref>;
    interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
    interrupt-parent = <&gpiod>;
    adi,conversion-start-gpios = <&gpiof 10 GPIO_ACTIVE_HIGH>;
    reset-gpios = <&gpioc 0 GPIO_ACTIVE_HIGH>;
    adi,sw-mode;
};
};

The second driver returns probe error -16 (Device or resource busy) because it can't use CONVST and RESET pins that previous driver already allocated.

The second ADC actually works if I assign some random unused GPIOs, read the value from the first ADC (in order to activate CONVST pin), then read the value from second ADC. This is a workaround used currently.

My question is, is it possible somehow to share GPIO pins between two instances of the same driver in Linux?

0andriy
  • 4,183
  • 1
  • 24
  • 37
  • Nice question and nice catch! I dunno if your PCB-level design is correct (to me sounds it’s not), but to answer your question it’s not possible until the driver is written in the different form, I.o.w. you need to modify or write another driver for such case. The sharing is possible on upper layers such as regulator framework, but it’s definitely not what the pins are representing. – 0andriy Jan 07 '22 at 22:32
  • Thanks for the info, it makes sense. This is a non standard use case. I was not involved in the PCB design, but I presume it was done because there were not enough pins available. We may be switching the ADC read to the Cortex M4 available on the STM32MP1, where this kind of "hacks" are easier to implement in bare metal C. – Darko Alavanja Jan 08 '22 at 10:21
  • With this design you may not use more than one ADC in General Purpose OS like Linux. It's broken. Yes, it's possible to introduce a set of hacks (to the **existing** code), but it becomes not a solution, just something which may easily fail. So, it means you need **a custom driver** that will serialize the accesses and conversions. As a side effect the `libiio` probably won't work with this setup. – 0andriy Jan 08 '22 at 18:20

0 Answers0