Правильная регистрация SPI-устройства в Device Tree на OrangePi Zero 3

Рейтинг: 0Ответов: 0Опубликовано: 16.08.2025

Я пишу драйвер SPI-устройства для OrangePi Zero 3 с установленной ОС Armbian. В написании драйвера используется API шины SPI в ядре Linux. У меня возникла проблема с активацией шины SPI. Для добавления устройства в Device Tree я использую overlay следующего содержания:

/dts-v1/;
/plugin/;

/ {
    compatible = "allwinner,sun50i-h616";

    fragment@0 {
        target = <&pio>;
        __overlay__ {
            ssd1306_dc_pin: ssd1306-dc-pin {
                pins = "PC7";
                function = "gpio_out";
                output-low; // Начальное состояние (по умолчанию 0)
            };
        };
    };

    fragment@1 {
        target = <&pio>;
        __overlay__ {
            ssd1306_res_pin: ssd1306-res-pin {
                pins = "PC10";
                function = "gpio_out";
                output-high;
            };
        };
    };

    fragment@2 {
        target = <&spi0>; // Указываем целевую шину (SPI0)
        __overlay__ {
            status = "okay";
            #address-cells = <1>;
            #size-cells = <0>;

            display: ssd1306@0 {
                compatible = "duel,ssd1306";
                reg = <0>;          // CS0
                spi-max-frequency = <400000>;
                dc-gpios = <&pio 2 7 0>;
                res-gpios = <&pio 2 10 1>;
            };
        };
    };
};

Данный overlay успешно компилируется, и при подключении модуля происходит вызов соответствующей функции probe, но шина SPI, предположительно, не активируется. Данное предположение вынесено на основе проверки светодиодом: пин CS всегда находится в состоянии 0, пин CLK также всегда находится в этом состоянии (Для проверки CLK в overlay понижалась частота до 4000).

Дополнительные сведения

Для установки overlay используются следующие Bash-команды:

dtc -@ -I dts -O dtb -o ssd1306.dtbo ssd1306-overlay.dts
sudo cp ssd1306.dtbo /boot/dtb/allwinner/overlay/sun50i-h616-ssd1306.dtbo

В armbianEnv.txt при этом добавляется строка: overlays=ssd1306.

Сокращённый исходный код функции probe (в данной версии я ещё не обеспечиваю потокобезопасность):

static int  duel_ssd1306_probe(struct spi_device* spi) {
    struct duel_ssd1306_drvdata* drvdata;
    ssize_t spi_status;
    int result;

    PDEBUG("Duel: probe.\n");
    drvdata = kmalloc(sizeof(struct duel_ssd1306_drvdata), GFP_KERNEL);
    if (!drvdata) {
        printk(KERN_WARNING "Duel: out of memory.\n");
        return -ENOMEM;
    }
    spi_set_drvdata(spi, drvdata);

    result = duel_ssd1306_init_drvdata(drvdata, &spi->dev);
    if (result) {
        duel_ssd1306_free_drvdata(drvdata);
        kfree(drvdata);
        return result;
    }

    PDEBUG("Duel: ssd1306 startup.\n");
    //Эта функция два раза с задержками переключает пин RES.
    duel_ssd1306_hard_reset(drvdata);

    /*
    Здесь также осуществляется инициализация устройства посредством направления серии команд, описанных в datasheet.
    */

    return 0;
}

Ответы

Ответов пока нет.