almost working, colors swapped!

This commit is contained in:
Miguel Fuertes committed 2025-10-15 01:08:36 +02:00
1 parent 54acb95301
commit 1c15ce2987
5 files changed
+81 -312

No files matched your search

+1 -1
View File
@@ -46,7 +46,7 @@ define Device/generic-mf68e
FILESYSTEMS := squashfs
DEVICE_PACKAGES := configs-mf68e wpad-basic-wolfssl rmtfs uci-usb-gadget \
block-mount f2fs-tools prepare-rootfs-data \
msm-firmware-dumper power-button-daemon kmod-fbtft-st7735
msm-firmware-dumper power-button-daemon kmod-fbtft-gc9107 rgb2rbg
endef
TARGET_DEVICES += generic-mf68e
@@ -1,303 +0,0 @@
Index: drivers/staging/fbtft/fb_st7735r.c
===================================================================
--- a/drivers/staging/fbtft/fb_st7735r.c
+++ b/drivers/staging/fbtft/fb_st7735r.c
@@ -14,84 +14,101 @@
#define DRVNAME "fb_st7735r"
#define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
- "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
+ "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
+/*
+ * Init sequence from Android MDSS driver for MF68E device (ST7735S 128x128)
+ * Key differences from standard ST7735R:
+ * - Resolution: 128x128 (not 132x132)
+ * - Vertical offset: 32 lines (RASET 0x20-0x9F instead of 0x00-0x7F)
+ * - MADCTL: 0xD8 (not 0xC8)
+ */
static const s16 default_init_sequence[] = {
- -1, MIPI_DCS_SOFT_RESET,
- -2, 150, /* delay */
+ -1, MIPI_DCS_SOFT_RESET,
+ -2, 150, /* delay */
+
+ -1, MIPI_DCS_EXIT_SLEEP_MODE,
+ -2, 500, /* delay */
+
+ /* FRMCTR1 - frame rate control: normal mode */
+ -1, 0xB1, 0x05, 0x3C, 0x3C,
+
+ /* FRMCTR2 - frame rate control: idle mode */
+ -1, 0xB2, 0x05, 0x3C, 0x3C,
+
+ /* FRMCTR3 - frame rate control - partial mode
+ * dot inversion mode, line inversion mode
+ */
+ -1, 0xB3, 0x05, 0x3C, 0x3C, 0x05, 0x3C, 0x3C,
+
+ /* INVCTR - display inversion control */
+ -1, 0xB4, 0x03,
+
+ /* PWCTR1 - Power Control */
+ -1, 0xC0, 0x0E, 0x0E, 0x04,
+
+ /* PWCTR2 - Power Control */
+ -1, 0xC1, 0xC0,
+
+ /* PWCTR3 - Power Control */
+ -1, 0xC2, 0x0D, 0x00,
+
+ /* PWCTR4 - Power Control */
+ -1, 0xC3, 0x8D, 0x2A,
+
+ /* PWCTR5 - Power Control */
+ -1, 0xC4, 0x8D, 0xEE,
+
+ /* VMCTR1 - Power Control */
+ -1, 0xC5, 0x0C,
+
+ /* Memory Data Access Control - MF68E specific (0xD8 not 0xC8) */
+ -1, MIPI_DCS_SET_ADDRESS_MODE, 0xD8,
+
+ /* Display Invert ON - Required for MF68E panel */
+ -1, MIPI_DCS_ENTER_INVERT_MODE,
+
+ /* Pixel Format - 16 bit */
+ -1, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT,
+
+ /* Gamma correction (positive) */
+ -1, 0xE0, 0x0C, 0x1C, 0x0F, 0x18, 0x36, 0x2F, 0x27, 0x2A,
+ 0x27, 0x25, 0x2D, 0x3C, 0x00, 0x05, 0x03, 0x10,
+
+ /* Gamma correction (negative) */
+ -1, 0xE1, 0x0C, 0x1A, 0x09, 0x09, 0x26, 0x22, 0x1E, 0x25,
+ 0x25, 0x25, 0x2E, 0x3B, 0x00, 0x05, 0x03, 0x10,
+
+ /* Column address set - MF68E uses 0-127 (0x00-0x7F) for 128 pixels */
+ -1, MIPI_DCS_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x00, 0x7F,
- -1, MIPI_DCS_EXIT_SLEEP_MODE,
- -2, 500, /* delay */
+ /* Page address set - MF68E uses 32-159 (0x20-0x9F) with 32-line offset */
+ -1, MIPI_DCS_SET_PAGE_ADDRESS, 0x00, 0x20, 0x00, 0x9F,
- /* FRMCTR1 - frame rate control: normal mode
- * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
- */
- -1, 0xB1, 0x01, 0x2C, 0x2D,
-
- /* FRMCTR2 - frame rate control: idle mode
- * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
- */
- -1, 0xB2, 0x01, 0x2C, 0x2D,
-
- /* FRMCTR3 - frame rate control - partial mode
- * dot inversion mode, line inversion mode
- */
- -1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
-
- /* INVCTR - display inversion control
- * no inversion
- */
- -1, 0xB4, 0x07,
-
- /* PWCTR1 - Power Control
- * -4.6V, AUTO mode
- */
- -1, 0xC0, 0xA2, 0x02, 0x84,
-
- /* PWCTR2 - Power Control
- * VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
- */
- -1, 0xC1, 0xC5,
-
- /* PWCTR3 - Power Control
- * Opamp current small, Boost frequency
- */
- -1, 0xC2, 0x0A, 0x00,
-
- /* PWCTR4 - Power Control
- * BCLK/2, Opamp current small & Medium low
- */
- -1, 0xC3, 0x8A, 0x2A,
-
- /* PWCTR5 - Power Control */
- -1, 0xC4, 0x8A, 0xEE,
-
- /* VMCTR1 - Power Control */
- -1, 0xC5, 0x0E,
-
- -1, MIPI_DCS_EXIT_INVERT_MODE,
-
- -1, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT,
+ /* Write memory start */
+ -1, MIPI_DCS_WRITE_MEMORY_START,
+ -2, 120, /* delay */
- -1, MIPI_DCS_SET_DISPLAY_ON,
- -2, 100, /* delay */
+ -1, MIPI_DCS_ENTER_NORMAL_MODE,
+ -2, 50, /* delay */
- -1, MIPI_DCS_ENTER_NORMAL_MODE,
- -2, 10, /* delay */
+ -1, MIPI_DCS_SET_DISPLAY_ON,
+ -2, 50, /* delay */
- /* end marker */
- -3
+ /* end marker */
+ -3
};
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
- write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
- xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
+ write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
+ xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
- write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
- ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
+ write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
+ (ys + 0x20) >> 8, (ys + 0x20) & 0xFF,
+ (ye + 0x20) >> 8, (ye + 0x20) & 0xFF);
- write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
+ write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
}
#define MY BIT(7)
@@ -99,33 +116,33 @@ static void set_addr_win(struct fbtft_pa
#define MV BIT(5)
static int set_var(struct fbtft_par *par)
{
- /* MADCTL - Memory data access control
- * RGB/BGR:
- * 1. Mode selection pin SRGB
- * RGB H/W pin for color filter setting: 0=RGB, 1=BGR
- * 2. MADCTL RGB bit
- * RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR
- */
- switch (par->info->var.rotate) {
- case 0:
- write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
- MX | MY | (par->bgr << 3));
- break;
- case 270:
- write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
- MY | MV | (par->bgr << 3));
- break;
- case 180:
- write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
- par->bgr << 3);
- break;
- case 90:
- write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
- MX | MV | (par->bgr << 3));
- break;
- }
+ /* MADCTL - Memory data access control
+ * RGB/BGR:
+ * 1. Mode selection pin SRGB
+ * RGB H/W pin for color filter setting: 0=RGB, 1=BGR
+ * 2. MADCTL RGB bit
+ * RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR
+ */
+ switch (par->info->var.rotate) {
+ case 0:
+ write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+ MX | MY | (par->bgr << 3));
+ break;
+ case 270:
+ write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+ MY | MV | (par->bgr << 3));
+ break;
+ case 180:
+ write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+ par->bgr << 3);
+ break;
+ case 90:
+ write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+ MX | MV | (par->bgr << 3));
+ break;
+ }
- return 0;
+ return 0;
}
/*
@@ -136,42 +153,42 @@ static int set_var(struct fbtft_par *par
#define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)]
static int set_gamma(struct fbtft_par *par, u32 *curves)
{
- int i, j;
+ int i, j;
- /* apply mask */
- for (i = 0; i < par->gamma.num_curves; i++)
- for (j = 0; j < par->gamma.num_values; j++)
- CURVE(i, j) &= 0x3f;
-
- for (i = 0; i < par->gamma.num_curves; i++)
- write_reg(par, 0xE0 + i,
- CURVE(i, 0), CURVE(i, 1),
- CURVE(i, 2), CURVE(i, 3),
- CURVE(i, 4), CURVE(i, 5),
- CURVE(i, 6), CURVE(i, 7),
- CURVE(i, 8), CURVE(i, 9),
- CURVE(i, 10), CURVE(i, 11),
- CURVE(i, 12), CURVE(i, 13),
- CURVE(i, 14), CURVE(i, 15));
+ /* apply mask */
+ for (i = 0; i < par->gamma.num_curves; i++)
+ for (j = 0; j < par->gamma.num_values; j++)
+ CURVE(i, j) &= 0x3f;
+
+ for (i = 0; i < par->gamma.num_curves; i++)
+ write_reg(par, 0xE0 + i,
+ CURVE(i, 0), CURVE(i, 1),
+ CURVE(i, 2), CURVE(i, 3),
+ CURVE(i, 4), CURVE(i, 5),
+ CURVE(i, 6), CURVE(i, 7),
+ CURVE(i, 8), CURVE(i, 9),
+ CURVE(i, 10), CURVE(i, 11),
+ CURVE(i, 12), CURVE(i, 13),
+ CURVE(i, 14), CURVE(i, 15));
- return 0;
+ return 0;
}
#undef CURVE
static struct fbtft_display display = {
- .regwidth = 8,
- .width = 128,
- .height = 160,
- .init_sequence = default_init_sequence,
- .gamma_num = 2,
- .gamma_len = 16,
- .gamma = DEFAULT_GAMMA,
- .fbtftops = {
- .set_addr_win = set_addr_win,
- .set_var = set_var,
- .set_gamma = set_gamma,
- },
+ .regwidth = 8,
+ .width = 128,
+ .height = 128,
+ .init_sequence = default_init_sequence,
+ .gamma_num = 2,
+ .gamma_len = 16,
+ .gamma = DEFAULT_GAMMA,
+ .fbtftops = {
+ .set_addr_win = set_addr_win,
+ .set_var = set_var,
+ .set_gamma = set_gamma,
+ },
};
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
@@ -1,14 +1,14 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=fbtft-st7735
PKG_NAME:=fbtft-gc9107
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/fbtft-st7735
define KernelPackage/fbtft-gc9107
SUBMENU:=Video Support
TITLE:=ST7735R/S Framebuffer Driver (Custom for MF68E)
TITLE:=GC9107 Framebuffer Driver
DEPENDS:=@TARGET_msm89xx +kmod-backlight
KCONFIG:= \
CONFIG_FB=y \
@@ -29,15 +29,14 @@ define KernelPackage/fbtft-st7735
FILES:= \
$(LINUX_DIR)/drivers/staging/fbtft/fbtft.ko \
$(LINUX_DIR)/drivers/staging/fbtft/fb_gc9107.ko
AUTOLOAD:=$(call AutoProbe,fbtft fb_st7735r fb_gc9107)
AUTOLOAD:=$(call AutoProbe,fbtft fb_gc9107)
endef
define KernelPackage/fbtft-st7735/description
Custom ST7735R/S framebuffer driver for MF68E device.
Includes proper initialization sequence from Android kernel.
define KernelPackage/fbtft-gc9107/description
GC9107 framebuffer driver for MF68E device.
endef
define Build/Compile
endef
$(eval $(call KernelPackage,fbtft-st7735))
$(eval $(call KernelPackage,fbtft-gc9107))
+42
View File
@@ -0,0 +1,42 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=rgb2rbg
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/rgb2rbg
SECTION:=utils
CATEGORY:=Utilities
TITLE:=RGB565 to RBG converter
endef
define Package/rgb2rbg/description
Converts RGB565 to RBG (swaps Green and Blue channels).
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Configure
endef
define Build/Compile
$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \
-O3 -fomit-frame-pointer -funroll-loops \
-o $(PKG_BUILD_DIR)/rgb2rbg \
$(PKG_BUILD_DIR)/rgb2rbg.c
# $(TARGET_STRIP) $(PKG_BUILD_DIR)/rgb2rbg
endef
define Build/Install
endef
define Package/rgb2rbg/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/rgb2rbg $(1)/usr/bin/
endef
$(eval $(call BuildPackage,rgb2rbg))
+31
View File
@@ -0,0 +1,31 @@
/*
* rgb2rbg.c - RGB565 to RBG converter
* Copyright (C) 2025
* License: GPL-2.0
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#define BUFFER_SIZE 8192
static inline uint16_t swap_gb(uint16_t pixel) {
return (pixel & 0xF800) | // Keep R (bits 15-11)
((pixel & 0x001F) << 5) | // B to G position
((pixel & 0x07E0) >> 5); // G to B position
}
int main(void) {
uint16_t buffer[BUFFER_SIZE];
size_t n;
while ((n = fread(buffer, sizeof(uint16_t), BUFFER_SIZE, stdin)) > 0) {
for (size_t i = 0; i < n; i++) {
buffer[i] = swap_gb(buffer[i]);
}
fwrite(buffer, sizeof(uint16_t), n, stdout);
}
return 0;
}