From 0987e0158d63711b01a2435fa515d80a5b540422 Mon Sep 17 00:00:00 2001
From: Alan <Alan>
Date: Sat, 20 May 2023 14:33:52 +0800
Subject: Add: FB_TFT ST7796S driver

---
 drivers/staging/fbtft/Kconfig      |  10 +++
 drivers/staging/fbtft/Makefile     |   1 +
 drivers/staging/fbtft/fb_st7796s.c | 100 +++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+)
 create mode 100644 drivers/staging/fbtft/fb_st7796s.c

diff --git a/drivers/staging/fbtft/Kconfig b/drivers/staging/fbtft/Kconfig
index dcf6a70455cc..42fe4b73aa3f 100644
--- a/drivers/staging/fbtft/Kconfig
+++ b/drivers/staging/fbtft/Kconfig
@@ -169,6 +169,16 @@ config FB_TFT_ST7789V
 
 	  Say Y if you have such a display that utilizes this controller.
 
+config FB_TFT_ST7796S
+	tristate "FB driver for the ST7796S LCD Controller"
+	depends on FB_TFT
+	help
+	  This enables generic framebuffer support for the Sitronix ST7796S
+	  display controller. The controller is intended for small color
+	  displays with a resolution of up to 480x320 pixels.
+
+	  Say Y if you have such a display that utilizes this controller.
+
 config FB_TFT_TINYLCD
 	tristate "FB driver for tinylcd.com display"
 	depends on FB_TFT
diff --git a/drivers/staging/fbtft/Makefile b/drivers/staging/fbtft/Makefile
index e9cdf0f0a7da..7b2098b8a1bd 100644
--- a/drivers/staging/fbtft/Makefile
+++ b/drivers/staging/fbtft/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_FB_TFT_SSD1331)     += fb_ssd1331.o
 obj-$(CONFIG_FB_TFT_SSD1351)     += fb_ssd1351.o
 obj-$(CONFIG_FB_TFT_ST7735R)     += fb_st7735r.o
 obj-$(CONFIG_FB_TFT_ST7789V)     += fb_st7789v.o
+obj-$(CONFIG_FB_TFT_ST7796S)     += fb_st7796s.o
 obj-$(CONFIG_FB_TFT_TINYLCD)     += fb_tinylcd.o
 obj-$(CONFIG_FB_TFT_TLS8204)     += fb_tls8204.o
 obj-$(CONFIG_FB_TFT_UC1611)      += fb_uc1611.o
diff --git a/drivers/staging/fbtft/fb_st7796s.c b/drivers/staging/fbtft/fb_st7796s.c
new file mode 100644
index 000000000000..cad489cef595
--- /dev/null
+++ b/drivers/staging/fbtft/fb_st7796s.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * FB driver for the ST7796S LCD Controller
+ *
+ * Copyright (c) 2023 Alan Ma
+ * Copyright (c) 2014 Petr Olivka
+ * Copyright (c) 2013 Noralf Tronnes
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <video/mipi_display.h>
+
+#include "fbtft.h"
+
+#define DRVNAME	"fb_st7796s"
+#define WIDTH		480
+#define HEIGHT		320
+
+static const s16 default_init_sequence[] = {
+	-1, 0xC0, 0x0C, 0x02,
+	-1, 0xC1, 0x44,
+	-1, 0xC5, 0x00, 0x16, 0x80,
+	-1, 0x36, 0x28,
+	/* Interface Mode Control */
+	-1, 0x3A, 0x55,
+	-1, 0XB0, 0x00,
+	/* Frame rate 70HZ */
+	-1, 0xB1, 0xB0,
+	-1, 0xB4, 0x02,
+	/* RGB/MCU Interface Control */
+	-1, 0xB6, 0x02, 0x02,
+	-1, 0xE9, 0x00,
+	-1, 0XF7, 0xA9, 0x51, 0x2C, 0x82,
+	/* SLP_OUT - Sleep out */
+	-1, MIPI_DCS_EXIT_SLEEP_MODE,
+	-2, 50,
+	/* DISP_ON */
+	-1, MIPI_DCS_SET_DISPLAY_ON,
+	-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_PAGE_ADDRESS,
+		  ys >> 8, ys & 0xff, ye >> 8, ye & 0xff);
+
+	write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	switch (par->info->var.rotate) {
+	case 270:
+		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+			  0x80 | (par->bgr << 3));
+		break;
+	case 180:
+		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+			  0xE0 | (par->bgr << 3));
+		break;
+	case 90:
+		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+			  0x40 | (par->bgr << 3));
+		break;
+	default:
+		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
+			  0x20 | (par->bgr << 3));
+		break;
+	}
+
+	return 0;
+}
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.init_sequence = default_init_sequence,
+	.fbtftops = {
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+
+FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7796s", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:st7796s");
+MODULE_ALIAS("platform:st7796s");
+
+MODULE_DESCRIPTION("FB driver for the ST7796S LCD Controller");
+MODULE_AUTHOR("Alan Ma");
+MODULE_LICENSE("GPL");
-- 
2.35.3

