# Init sequence sourced from Espressif's esp-bsp repository:
# https://github.com/espressif/esp-bsp/blob/master/bsp/esp_vocat/priv_include/disp_init_data.h
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0

from esphome.components.mipi import MODE_RGB, DriverChip
from esphome.components.spi import TYPE_QUAD
from esphome.const import CONF_INVERTED, CONF_NUMBER

# Init sequence for the ST77916 QSPI display on the ESP-VoCat v1.2 board.
# Source: disp_init_data.h from espressif/esp-bsp (bsp/esp_vocat/priv_include).
# The standard INVON/INVOFF and SLPOUT+DISPON commands (and required delays) are omitted because
# the mipi_spi framework appends them automatically based on the invert_colors and no_slpout settings.
# (So this sequence only contains panel-specific setup commands.)
_ESP_VOCAT_INIT = (
    # Page 1a — startup unlock
    (0xF0, 0x28),
    (0xF2, 0x28),
    (0x73, 0xF0),
    (0x7C, 0xD1),
    (0x83, 0xE0),
    (0x84, 0x61),
    (0xF2, 0x82),
    # Switch to page 0 → page 1
    (0xF0, 0x00),
    (0xF0, 0x01),
    (0xF1, 0x01),
    # Power settings (Bx)
    (0xB0, 0x56),
    (0xB1, 0x4D),
    (0xB2, 0x24),
    (0xB4, 0x87),
    (0xB5, 0x44),
    (0xB6, 0x8B),
    (0xB7, 0x40),
    (0xB8, 0x86),
    (0xBA, 0x00),
    (0xBB, 0x08),
    (0xBC, 0x08),
    (0xBD, 0x00),
    # VCOM / gate settings (Cx)
    (0xC0, 0x80),
    (0xC1, 0x10),
    (0xC2, 0x37),
    (0xC3, 0x80),
    (0xC4, 0x10),
    (0xC5, 0x37),
    (0xC6, 0xA9),
    (0xC7, 0x41),
    (0xC8, 0x01),
    (0xC9, 0xA9),
    (0xCA, 0x41),
    (0xCB, 0x01),
    # Source settings (Dx)
    (0xD0, 0x91),
    (0xD1, 0x68),
    (0xD2, 0x68),
    # Misc
    (0xF5, 0x00, 0xA5),
    (0xDD, 0x4F),
    (0xDE, 0x4F),
    (0xF1, 0x10),
    (0xF0, 0x00),
    # Switch to page 2 — gamma
    (0xF0, 0x02),
    (
        0xE0,
        0xF0,
        0x0A,
        0x10,
        0x09,
        0x09,
        0x36,
        0x35,
        0x33,
        0x4A,
        0x29,
        0x15,
        0x15,
        0x2E,
        0x34,
    ),
    (
        0xE1,
        0xF0,
        0x0A,
        0x0F,
        0x08,
        0x08,
        0x05,
        0x34,
        0x33,
        0x4A,
        0x39,
        0x15,
        0x15,
        0x2D,
        0x33,
    ),
    # Switch to page 10 — GIP / timing
    (0xF0, 0x10),
    (0xF3, 0x10),
    # Page 10: Exxx
    (0xE0, 0x07),
    (0xE1, 0x00),
    (0xE2, 0x00),
    (0xE3, 0x00),
    (0xE4, 0xE0),
    (0xE5, 0x06),
    (0xE6, 0x21),
    (0xE7, 0x01),
    (0xE8, 0x05),
    (0xE9, 0x02),
    (0xEA, 0xDA),
    (0xEB, 0x00),
    (0xEC, 0x00),
    (0xED, 0x0F),
    (0xEE, 0x00),
    (0xEF, 0x00),
    # Page 10: Fxxx
    (0xF8, 0x00),
    (0xF9, 0x00),
    (0xFA, 0x00),
    (0xFB, 0x00),
    (0xFC, 0x00),
    (0xFD, 0x00),
    (0xFE, 0x00),
    (0xFF, 0x00),
    # GIP section A (0x60–0x6B)
    (0x60, 0x40),
    (0x61, 0x04),
    (0x62, 0x00),
    (0x63, 0x42),
    (0x64, 0xD9),
    (0x65, 0x00),
    (0x66, 0x00),
    (0x67, 0x00),
    (0x68, 0x00),
    (0x69, 0x00),
    (0x6A, 0x00),
    (0x6B, 0x00),
    # GIP section B (0x70–0x7B)
    (0x70, 0x40),
    (0x71, 0x03),
    (0x72, 0x00),
    (0x73, 0x42),
    (0x74, 0xD8),
    (0x75, 0x00),
    (0x76, 0x00),
    (0x77, 0x00),
    (0x78, 0x00),
    (0x79, 0x00),
    (0x7A, 0x00),
    (0x7B, 0x00),
    # GIP timing (0x80–0x9F)
    (0x80, 0x48),
    (0x81, 0x00),
    (0x82, 0x06),
    (0x83, 0x02),
    (0x84, 0xD6),
    (0x85, 0x04),
    (0x86, 0x00),
    (0x87, 0x00),
    (0x88, 0x48),
    (0x89, 0x00),
    (0x8A, 0x08),
    (0x8B, 0x02),
    (0x8C, 0xD8),
    (0x8D, 0x04),
    (0x8E, 0x00),
    (0x8F, 0x00),
    (0x90, 0x48),
    (0x91, 0x00),
    (0x92, 0x0A),
    (0x93, 0x02),
    (0x94, 0xDA),
    (0x95, 0x04),
    (0x96, 0x00),
    (0x97, 0x00),
    (0x98, 0x48),
    (0x99, 0x00),
    (0x9A, 0x0C),
    (0x9B, 0x02),
    (0x9C, 0xDC),
    (0x9D, 0x04),
    (0x9E, 0x00),
    (0x9F, 0x00),
    # GIP timing (0xA0–0xBF)
    (0xA0, 0x48),
    (0xA1, 0x00),
    (0xA2, 0x05),
    (0xA3, 0x02),
    (0xA4, 0xD5),
    (0xA5, 0x04),
    (0xA6, 0x00),
    (0xA7, 0x00),
    (0xA8, 0x48),
    (0xA9, 0x00),
    (0xAA, 0x07),
    (0xAB, 0x02),
    (0xAC, 0xD7),
    (0xAD, 0x04),
    (0xAE, 0x00),
    (0xAF, 0x00),
    (0xB0, 0x48),
    (0xB1, 0x00),
    (0xB2, 0x09),
    (0xB3, 0x02),
    (0xB4, 0xD9),
    (0xB5, 0x04),
    (0xB6, 0x00),
    (0xB7, 0x00),
    (0xB8, 0x48),
    (0xB9, 0x00),
    (0xBA, 0x0B),
    (0xBB, 0x02),
    (0xBC, 0xDB),
    (0xBD, 0x04),
    (0xBE, 0x00),
    (0xBF, 0x00),
    # Source timing (0xC0–0xC9)
    (0xC0, 0x10),
    (0xC1, 0x47),
    (0xC2, 0x56),
    (0xC3, 0x65),
    (0xC4, 0x74),
    (0xC5, 0x88),
    (0xC6, 0x99),
    (0xC7, 0x01),
    (0xC8, 0xBB),
    (0xC9, 0xAA),
    # Source timing (0xD0–0xD9)
    (0xD0, 0x10),
    (0xD1, 0x47),
    (0xD2, 0x56),
    (0xD3, 0x65),
    (0xD4, 0x74),
    (0xD5, 0x88),
    (0xD6, 0x99),
    (0xD7, 0x01),
    (0xD8, 0xBB),
    (0xD9, 0xAA),
    # Finalise page 10, return to page 0
    (0xF3, 0x01),
    (0xF0, 0x00),
    # INVON (0x21) and SLPOUT (0x11) are appended by the framework.
)

DriverChip(
    "ESP-VOCAT",
    width=360,
    height=360,
    # SPI pins for the ESP-VoCat v1.2 board.
    # PCLK (GPIO18) and data pins (GPIO46/13/11/12) are configured on the spi: bus.
    cs_pin=14,
    # RST is active-HIGH on this panel; invert the ESPHome pin so the framework's
    # active-low reset pulse (HIGH→LOW→HIGH) maps to the correct physical sequence
    # (LOW→HIGH→LOW) on the wire.
    reset_pin={CONF_NUMBER: 47, CONF_INVERTED: True},
    # Note: GPIO9 behaviour varies by board revision (may be POWER_CTRL, not LCD_EN).
    # Do not set a default enable_pin — manage LCD power in on_boot if needed.
    # GPIO44 is the backlight; manage it separately via an output: or light:.
    bus_mode=TYPE_QUAD,
    data_rate="80MHz",
    invert_colors=True,
    color_order=MODE_RGB,
    requires={"psram"},
    initsequence=_ESP_VOCAT_INIT,
)
