LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
SoM / SBC

Jak zastąpić wyświetlacz LCD monitorem HDMI w systemie embedded i.MX6ULL z Linkusem

Sterownik dla systemu Linux

Pomimo iż układ ADV7513 pełni rolę konwertera, do jego prawidłowej pracy potrzebny jest sterownik pracujący w przestrzeni jądra, którego zadaniem jest:

  • odczytanie za pomocą EDID parametrów konfiguracyjnych monitora
  • wybór odpowiedniej rozdzielczości obrazu wspieranej przez monitor
  • wysłanie danych konfiguracyjnych do układu nadajnika

W jądrze mainline począwszy od wersji 4.10 istnieje gotowy sterownik dla podsystemu KMS dla wybranego układu. Niestety sterowniki graficzne dostarczane przez firmę NXP dla układu i.MX6ULL wraz z jądrem nie wykorzystują podsystemu KMS. W związku z tym konieczne stało się opracowanie odrębnego sterownika współpracującego ze sterownikiem mxsfb. Zaprezentowany w artykule sterownik dla uproszczenia umożliwia wyświetlanie obrazu o stałej rozdzielczości, którą możemy konfigurować za pomocą pliku opisu sprzętu Device Tree.

 W opisie drivera HDMI mogą występować odwołania do układu ADV7511 firmy Analog Devices. Użyty w VisionCB-IND-HDMI układ ADV7513 jest jedną z jego zgodnych wersji.

Kod źródłowy sterownika znajduje się w pliku adv7511-fbdev.c, a pliki adv7511.h oraz adv7511_default_regs.h zawierają podstawowe stałe oraz tablice konfiguracyjne rejestrów układu. Diagram sekwencji (rysunek 6) przedstawia sposób interakcji podsystemów jądra Linux ze sterownikiem konwertera.

Rys. 6. Diagram sekwencji prezentujący interakcję podsystemów jądra Linux ze sterownikiem konwertera ADV7513

Sterownik rozpoczyna działanie od wywołania funkcji adv7511_probe, która jest uruchamiana przez podsystem sterowników jądra w momencie odczytania obecności wpisu odnoszącego się ADV7513 w Device Tree. Diagram aktywności dla wspomnianej funkcji przedstawiono na rysunku 7.

Rys. 7. Diagram aktywności funkcji adv7511_probe

Na początku konfigurowany jest kontroler interfejsu I2C, następnie poprzez odczyt rejestru identyfikacyjnego sprawdzamy, czy do wskazanej magistrali dołączony jest układ konwertera. W przypadku niemożności wykrycia układu zgłaszany jest błąd i sterownik kończy działanie. Jeżeli układ zostanie wykryty poprawnie, to odczytywane są wszystkie parametry konfiguracyjne z Device Tree, a następnie do rejestrów układu ADV7513 zapisywane są wartości zgodne z wcześniej odczytanymi parametrami oraz uruchamiany jest układ nadajnika HDMI.

Po zakończeniu konfiguracji sprzętu, w podsystemie FB rejestrowany jest callback, którego zadaniem jest reagowanie na zdarzenia pochodzące od tego podsystemu. Od tego momentu konwerter jest gotowy do pracy. Funkcja adv7511_fb_event wywoływana jest w reakcji na zdarzenia od podsystemu FB w momencie wystąpienia następujących zdarzeń:

  • FB_EVENT_FB_REGISTERED: zdarzenie rejestracji, wywoływana jednorazowo przez podsystem podczas inicjalizacji. Tutaj może być wykonana dodatkowa inicjalizacja związana ze sterownikiem
  • FB_EVENT_MODE_CHANGE: zmiana parametrów VIDEO bufora FB
  • FB_EVENT_BLANK: żądanie wyświetlenia lub wygaszenia wyświetlania obrazu

Kod funkcji obsługującej zdarzenia od podsystemu FB przedstawiono na listingu 1.

static int adv7511_fb_event(struct notifier_block *self, unsigned long val, void *data)
{
    struct fb_event *event = data;
    struct fb_info *fbi = event->info;
    struct adv7511 *state = container_of(self, struct adv7511, nb);

    switch (val) {
    case FB_EVENT_FB_REGISTERED:
            dev_dbg(fbi->dev, "FB_EVENT_FB_REGISTERED\n");
        if (state->fbi == NULL)
            state->fbi = fbi;
        fb_show_logo(fbi, 0);

        break;
    case FB_EVENT_MODE_CHANGE:
        dev_dbg(fbi->dev, "FB_EVENT_MODE_CHANGE\n");
        break;
    case FB_EVENT_BLANK:
        if (*((int *)event->data) == FB_BLANK_UNBLANK) {
            dev_dbg(fbi->dev, "FB_BLANK_UNBLANK\n");
            adv7511_power_on(state);
        } else {
            dev_dbg(fbi->dev, "FB_BLANK_BLANK\n");
            adv7511_power_off(state);
        }
        break;
    }
    return 0;
}

List. 1. Funkcja obsługująca zdarzenia od podsystemu FB

Zdarzenie FB_EVENT_FB_REGISTERED dokonuje jednorazowej inicjalizacji sterownika związanej z FB. W naszym przypadku przypisujemy jedynie kontekst sterownika do odpowiedniej struktury oraz wyświetlamy logo.

Zdarzenie FB_EVENT_MODE_CHANGE nie jest przez nasz sterownik obsługiwane, ponieważ w podstawowej wersji zapewniane jest jedynie wyświetlanie obrazu o ściśle określonej (za pomocą Device Tree) rozdzielczości.

Zdarzenie FB_EVENT_BLANK obsługiwane jest poprzez włączanie lub wyłączenie wysyłania sygnału HDMI przez układ konwertera.

Tagi: projekt, SOM