> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SPI

The Serial Peripheral Interface (SPI) is a synchronous, full-duplex, 4-wire serial bus.

<img src="https://mintcdn.com/qualcomm-prod/jy6NQT2Y7J_sAxdX/Linux/images/peripheral-interfaces/spi_protocol.png?fit=max&auto=format&n=jy6NQT2Y7J_sAxdX&q=85&s=2fdb35af0b47a2602919297e94b0200b" width="724" height="426" data-path="Linux/images/peripheral-interfaces/spi_protocol.png" />

## Signals

| Signal   | Description                                                 |
| -------- | ----------------------------------------------------------- |
| **MOSI** | Controller data output, target data input                   |
| **MISO** | Controller data input, target data output                   |
| **SCLK** | Clock generated by the controller                           |
| **CS**   | Chip-select (active low); up to 4 chip-select lines per bus |

## Transfer Modes by Subsystem

| Subsystem | Transfer Modes                | Max Speed | Notes                                       |
| --------- | ----------------------------- | --------- | ------------------------------------------- |
| **Linux** | FIFO, CPU DMA, GSI            | 50 MHz    | 4–32 bits per word; up to 4 CS              |
| **Boot**  | FIFO only                     | 50 MHz    | Polling mode; GSI not supported             |
| **aDSP**  | Full/half duplex, synchronous | 50 MHz    | Raw bit-level; no framing or error checking |

## Interface Components

### Device Tree Sources

| Platform           | File                                    |
| ------------------ | --------------------------------------- |
| Dragonwing IQ-8275 | `arch/arm64/boot/dts/qcom/qcs8300.dtsi` |

### APIs

| Subsystem | Header                                                       |
| --------- | ------------------------------------------------------------ |
| Linux     | `include/uapi/linux/spi/spidev.h`, `include/linux/spi/spi.h` |
| Boot      | `boot_images/boot/QcomPkg/Include/SpiApi.h`                  |
| aDSP      | `adsp_proc/core/api/buses/spi_api.h`                         |

## Software Configuration

### Linux Device Tree Example

```dts theme={null}
spi@a98000 {
    compatible = "qcom,geni-spi";
    reg = <0 0x00a98000 0 0x4000>;
    clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
    clock-names = "se";
    pinctrl-names = "default";
    pinctrl-0 = <&qup_spi14_data_clk>, <&qup_spi14_cs>;
    interrupts = <GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>;
    #address-cells = <1>;
    #size-cells = <0>;
    power-domains = <&rpmhpd SA8295P_CX>;
    dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>,
           <&gpi_dma1 1 6 QCOM_GPI_SPI>;
    dma-names = "tx", "rx";
    status = "disabled";
};
```

### QUPAC Access Control

```c theme={null}
{ QUPV3_0_SE3, QUPV3_PROTOCOL_SPI, QUPV3_MODE_FIFO, AC_HLOS, TRUE,  TRUE, FALSE },
{ QUPV3_1_SE3, QUPV3_PROTOCOL_SPI, QUPV3_MODE_FIFO, AC_HLOS, FALSE, TRUE, TRUE  },
{ QUPV3_1_SE4, QUPV3_PROTOCOL_SPI, QUPV3_MODE_GSI,  AC_TZ,   FALSE, TRUE, TRUE  },
{ QUPV3_1_SE6, QUPV3_PROTOCOL_SPI, QUPV3_MODE_GSI,  AC_HLOS, FALSE, TRUE, FALSE },
```

## Configuration Steps

<Steps>
  <Step title="Enable kernel configurations">
    Edit `kernel_platform/kernel/arch/arm64/configs/qcom_defconfig`:

    ```
    CONFIG_QCOM_GENI_SE=y
    CONFIG_SPI_QCOM_GENI=m
    CONFIG_SPI_SPIDEV=m
    CONFIG_QCOM_GPI_DMA=m
    ```
  </Step>

  <Step title="Enable SPI node in device tree">
    ```dts theme={null}
    &spi1 {
        status = "okay";
    };
    ```
  </Step>

  <Step title="Compile and flash">
    Compile the kernel and device tree changes, then load images to the device.
  </Step>
</Steps>

## Verification

<Steps>
  <Step title="Transfer spidev_test to device">
    ```bash theme={null}
    scp spidev_test root@<IP address>:/usr
    chmod 777 /usr/spidev_test
    ```
  </Step>

  <Step title="Run test">
    ```bash theme={null}
    ./spidev_test -D /dev/spidev1.0
    ```

    **Expected output:**

    ```
    spi mode: 0x0
    bits per word: 8
    max speed: 500000 Hz (500 KHz)
    ```
  </Step>
</Steps>

## Debugging

```bash theme={null}
sudo su
mount -t debugfs none /sys/kernel/debug
echo -n "file spi-geni-qcom.c +p" > /sys/kernel/debug/dynamic_debug/control
echo -n "file spidev.c +p" > /sys/kernel/debug/dynamic_debug/control
echo -n "file gpi.c +p" > /sys/kernel/debug/dynamic_debug/control
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="SPI Device Not Detected">
    ```bash theme={null}
    zcat /proc/config.gz | grep -E 'CONFIG_SPI_SPIDEV|CONFIG_SPI_QCOM_GENI'
    dmesg | grep -i spi
    ```

    * Verify SPI node status is `"okay"` in device tree
    * Verify `QUPAC_Access.c` sets `QUPV3_PROTOCOL_SPI`, `AC_HLOS`, `bLoad=TRUE`
  </Accordion>

  <Accordion title="SPI Transfer Failures">
    ```bash theme={null}
    ./spidev_test -D /dev/spidev1.0 -s 1000000
    ```

    * Check GPIO drive strength and pull configuration
    * Verify clock phase and polarity match the target device
  </Accordion>

  <Accordion title="GSI/DMA Mode Not Working">
    * Verify `CONFIG_QCOM_GPI_DMA=m`
    * Check `dmas` and `dma-names` in device tree
    * Verify `QUPAC_Access.c` sets `QUPV3_MODE_GSI`
  </Accordion>
</AccordionGroup>

## Resources

* [SPI Driver Source](https://github.com/torvalds/linux/blob/master/drivers/spi/spi-geni-qcom.c)
* [SPI Device Tree Bindings](https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/spi/qcom%2Cspi-geni-qcom.yaml)
* [SPI User API](https://github.com/torvalds/linux/blob/master/include/uapi/linux/spi/spidev.h)
