Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2019, Amarula Solutions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Author: Jagan Teki <jagan@amarulasolutions.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <drm/drm_mipi_dsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <drm/drm_modes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <drm/drm_panel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <video/mipi_display.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /* Command2 BKx selection command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define DSI_CMD2BKX_SEL			0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /* Command2, BK0 commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define DSI_CMD2_BK0_PVGAMCTRL		0xB0 /* Positive Voltage Gamma Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define DSI_CMD2_BK0_NVGAMCTRL		0xB1 /* Negative Voltage Gamma Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DSI_CMD2_BK0_LNESET		0xC0 /* Display Line setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define DSI_CMD2_BK0_PORCTRL		0xC1 /* Porch control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DSI_CMD2_BK0_INVSEL		0xC2 /* Inversion selection, Frame Rate Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* Command2, BK1 commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define DSI_CMD2_BK1_VRHS		0xB0 /* Vop amplitude setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define DSI_CMD2_BK1_VCOM		0xB1 /* VCOM amplitude setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define DSI_CMD2_BK1_VGHSS		0xB2 /* VGH Voltage setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define DSI_CMD2_BK1_TESTCMD		0xB3 /* TEST Command Setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define DSI_CMD2_BK1_VGLS		0xB5 /* VGL Voltage setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define DSI_CMD2_BK1_PWCTLR1		0xB7 /* Power Control 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define DSI_CMD2_BK1_PWCTLR2		0xB8 /* Power Control 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define DSI_CMD2_BK1_SPD1		0xC1 /* Source pre_drive timing set1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define DSI_CMD2_BK1_SPD2		0xC2 /* Source EQ2 Setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define DSI_CMD2_BK1_MIPISET1		0xD0 /* MIPI Setting 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * Command2 with BK function selection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * BIT[4, 0]: [CN2, BKXSEL]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * 10 = CMD2BK0, Command2 BK0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * 11 = CMD2BK1, Command2 BK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * 00 = Command2 disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define DSI_CMD2BK1_SEL			0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define DSI_CMD2BK0_SEL			0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define DSI_CMD2BKX_SEL_NONE		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /* Command2, BK0 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define DSI_LINESET_LINE		0x69
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define DSI_LINESET_LDE_EN		BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define DSI_LINESET_LINEDELTA		GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define DSI_CMD2_BK0_LNESET_B1		DSI_LINESET_LINEDELTA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define DSI_CMD2_BK0_LNESET_B0		(DSI_LINESET_LDE_EN | DSI_LINESET_LINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define DSI_INVSEL_DEFAULT		GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define DSI_INVSEL_NLINV		GENMASK(2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define DSI_INVSEL_RTNI			GENMASK(2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define DSI_CMD2_BK0_INVSEL_B1		DSI_INVSEL_RTNI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define DSI_CMD2_BK0_INVSEL_B0		(DSI_INVSEL_DEFAULT | DSI_INVSEL_NLINV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define DSI_CMD2_BK0_PORCTRL_B0(m)	((m)->vtotal - (m)->vsync_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define DSI_CMD2_BK0_PORCTRL_B1(m)	((m)->vsync_start - (m)->vdisplay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) /* Command2, BK1 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define DSI_CMD2_BK1_VRHA_SET		0x45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define DSI_CMD2_BK1_VCOM_SET		0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define DSI_CMD2_BK1_VGHSS_SET		GENMASK(2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define DSI_CMD2_BK1_TESTCMD_VAL	BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define DSI_VGLS_DEFAULT		BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define DSI_VGLS_SEL			GENMASK(2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define DSI_CMD2_BK1_VGLS_SET		(DSI_VGLS_DEFAULT | DSI_VGLS_SEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define DSI_PWCTLR1_AP			BIT(7) /* Gamma OP bias, max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define DSI_PWCTLR1_APIS		BIT(2) /* Source OP input bias, min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define DSI_PWCTLR1_APOS		BIT(0) /* Source OP output bias, min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define DSI_CMD2_BK1_PWCTLR1_SET	(DSI_PWCTLR1_AP | DSI_PWCTLR1_APIS | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 					DSI_PWCTLR1_APOS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define DSI_PWCTLR2_AVDD		BIT(5) /* AVDD 6.6v */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define DSI_PWCTLR2_AVCL		0x0    /* AVCL -4.4v */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define DSI_CMD2_BK1_PWCTLR2_SET	(DSI_PWCTLR2_AVDD | DSI_PWCTLR2_AVCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define DSI_SPD1_T2D			BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define DSI_CMD2_BK1_SPD1_SET		(GENMASK(6, 4) | DSI_SPD1_T2D)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define DSI_CMD2_BK1_SPD2_SET		DSI_CMD2_BK1_SPD1_SET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define DSI_MIPISET1_EOT_EN		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define DSI_CMD2_BK1_MIPISET1_SET	(BIT(7) | DSI_MIPISET1_EOT_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) struct st7701_panel_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	const struct drm_display_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	unsigned int lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	enum mipi_dsi_pixel_format format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	const char *const *supply_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	unsigned int num_supplies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	unsigned int panel_sleep_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) struct st7701 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct drm_panel panel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	struct mipi_dsi_device *dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	const struct st7701_panel_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	struct regulator_bulk_data *supplies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	struct gpio_desc *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	unsigned int sleep_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static inline struct st7701 *panel_to_st7701(struct drm_panel *panel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return container_of(panel, struct st7701, panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static inline int st7701_dsi_write(struct st7701 *st7701, const void *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				   size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return mipi_dsi_dcs_write_buffer(st7701->dsi, seq, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ST7701_DSI(st7701, seq...)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	{							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		const u8 d[] = { seq };				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		st7701_dsi_write(st7701, d, ARRAY_SIZE(d));	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static void st7701_init_sequence(struct st7701 *st7701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	const struct drm_display_mode *mode = st7701->desc->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	ST7701_DSI(st7701, MIPI_DCS_SOFT_RESET, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	/* We need to wait 5ms before sending new commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	msleep(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	ST7701_DSI(st7701, MIPI_DCS_EXIT_SLEEP_MODE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	msleep(st7701->sleep_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/* Command2, BK0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		   0x77, 0x01, 0x00, 0x00, DSI_CMD2BK0_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	ST7701_DSI(st7701, DSI_CMD2_BK0_PVGAMCTRL, 0x00, 0x0E, 0x15, 0x0F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		   0x11, 0x08, 0x08, 0x08, 0x08, 0x23, 0x04, 0x13, 0x12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		   0x2B, 0x34, 0x1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	ST7701_DSI(st7701, DSI_CMD2_BK0_NVGAMCTRL, 0x00, 0x0E, 0x95, 0x0F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		   0x13, 0x07, 0x09, 0x08, 0x08, 0x22, 0x04, 0x10, 0x0E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		   0x2C, 0x34, 0x1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	ST7701_DSI(st7701, DSI_CMD2_BK0_LNESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		   DSI_CMD2_BK0_LNESET_B0, DSI_CMD2_BK0_LNESET_B1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	ST7701_DSI(st7701, DSI_CMD2_BK0_PORCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		   DSI_CMD2_BK0_PORCTRL_B0(mode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		   DSI_CMD2_BK0_PORCTRL_B1(mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	ST7701_DSI(st7701, DSI_CMD2_BK0_INVSEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		   DSI_CMD2_BK0_INVSEL_B0, DSI_CMD2_BK0_INVSEL_B1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	/* Command2, BK1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			0x77, 0x01, 0x00, 0x00, DSI_CMD2BK1_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	ST7701_DSI(st7701, DSI_CMD2_BK1_VRHS, DSI_CMD2_BK1_VRHA_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	ST7701_DSI(st7701, DSI_CMD2_BK1_VCOM, DSI_CMD2_BK1_VCOM_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	ST7701_DSI(st7701, DSI_CMD2_BK1_VGHSS, DSI_CMD2_BK1_VGHSS_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	ST7701_DSI(st7701, DSI_CMD2_BK1_TESTCMD, DSI_CMD2_BK1_TESTCMD_VAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	ST7701_DSI(st7701, DSI_CMD2_BK1_VGLS, DSI_CMD2_BK1_VGLS_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	ST7701_DSI(st7701, DSI_CMD2_BK1_PWCTLR1, DSI_CMD2_BK1_PWCTLR1_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ST7701_DSI(st7701, DSI_CMD2_BK1_PWCTLR2, DSI_CMD2_BK1_PWCTLR2_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, DSI_CMD2_BK1_SPD1_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	ST7701_DSI(st7701, DSI_CMD2_BK1_SPD2, DSI_CMD2_BK1_SPD2_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	ST7701_DSI(st7701, DSI_CMD2_BK1_MIPISET1, DSI_CMD2_BK1_MIPISET1_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	/**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	 * ST7701_SPEC_V1.2 is unable to provide enough information above this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	 * specific command sequence, so grab the same from vendor BSP driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	ST7701_DSI(st7701, 0xE0, 0x00, 0x00, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	ST7701_DSI(st7701, 0xE1, 0x0B, 0x00, 0x0D, 0x00, 0x0C, 0x00, 0x0E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		   0x00, 0x00, 0x44, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	ST7701_DSI(st7701, 0xE2, 0x33, 0x33, 0x44, 0x44, 0x64, 0x00, 0x66,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		   0x00, 0x65, 0x00, 0x67, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ST7701_DSI(st7701, 0xE3, 0x00, 0x00, 0x33, 0x33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	ST7701_DSI(st7701, 0xE4, 0x44, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	ST7701_DSI(st7701, 0xE5, 0x0C, 0x78, 0x3C, 0xA0, 0x0E, 0x78, 0x3C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		   0xA0, 0x10, 0x78, 0x3C, 0xA0, 0x12, 0x78, 0x3C, 0xA0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	ST7701_DSI(st7701, 0xE6, 0x00, 0x00, 0x33, 0x33);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	ST7701_DSI(st7701, 0xE7, 0x44, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	ST7701_DSI(st7701, 0xE8, 0x0D, 0x78, 0x3C, 0xA0, 0x0F, 0x78, 0x3C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		   0xA0, 0x11, 0x78, 0x3C, 0xA0, 0x13, 0x78, 0x3C, 0xA0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	ST7701_DSI(st7701, 0xEB, 0x02, 0x02, 0x39, 0x39, 0xEE, 0x44, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	ST7701_DSI(st7701, 0xEC, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	ST7701_DSI(st7701, 0xED, 0xFF, 0xF1, 0x04, 0x56, 0x72, 0x3F, 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		   0xFF, 0xFF, 0xFF, 0xF3, 0x27, 0x65, 0x40, 0x1F, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	/* disable Command2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	ST7701_DSI(st7701, DSI_CMD2BKX_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		   0x77, 0x01, 0x00, 0x00, DSI_CMD2BKX_SEL_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int st7701_prepare(struct drm_panel *panel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct st7701 *st7701 = panel_to_st7701(panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	gpiod_set_value(st7701->reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	ret = regulator_bulk_enable(st7701->desc->num_supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				    st7701->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	gpiod_set_value(st7701->reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	msleep(150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	st7701_init_sequence(st7701);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int st7701_enable(struct drm_panel *panel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	struct st7701 *st7701 = panel_to_st7701(panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	ST7701_DSI(st7701, MIPI_DCS_SET_DISPLAY_ON, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int st7701_disable(struct drm_panel *panel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	struct st7701 *st7701 = panel_to_st7701(panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	ST7701_DSI(st7701, MIPI_DCS_SET_DISPLAY_OFF, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int st7701_unprepare(struct drm_panel *panel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	struct st7701 *st7701 = panel_to_st7701(panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	ST7701_DSI(st7701, MIPI_DCS_ENTER_SLEEP_MODE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	msleep(st7701->sleep_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	gpiod_set_value(st7701->reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	/**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	 * During the Resetting period, the display will be blanked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	 * (The display is entering blanking sequence, which maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	 * time is 120 ms, when Reset Starts in Sleep Out –mode. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	 * display remains the blank state in Sleep In –mode.) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	 * then return to Default condition for Hardware Reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	 * So we need wait sleep_delay time to make sure reset completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	msleep(st7701->sleep_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	regulator_bulk_disable(st7701->desc->num_supplies, st7701->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int st7701_get_modes(struct drm_panel *panel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			    struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	struct st7701 *st7701 = panel_to_st7701(panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	const struct drm_display_mode *desc_mode = st7701->desc->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	struct drm_display_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	mode = drm_mode_duplicate(connector->dev, desc_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if (!mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		dev_err(&st7701->dsi->dev, "failed to add mode %ux%u@%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			desc_mode->hdisplay, desc_mode->vdisplay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			drm_mode_vrefresh(desc_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	drm_mode_set_name(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	drm_mode_probed_add(connector, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	connector->display_info.width_mm = desc_mode->width_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	connector->display_info.height_mm = desc_mode->height_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static const struct drm_panel_funcs st7701_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	.disable	= st7701_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	.unprepare	= st7701_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	.prepare	= st7701_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	.enable		= st7701_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	.get_modes	= st7701_get_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static const struct drm_display_mode ts8550b_mode = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	.clock		= 27500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.hdisplay	= 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	.hsync_start	= 480 + 38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.hsync_end	= 480 + 38 + 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	.htotal		= 480 + 38 + 12 + 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	.vdisplay	= 854,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	.vsync_start	= 854 + 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	.vsync_end	= 854 + 18 + 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	.vtotal		= 854 + 18 + 8 + 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	.width_mm	= 69,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	.height_mm	= 139,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static const char * const ts8550b_supply_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	"VCC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	"IOVCC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static const struct st7701_panel_desc ts8550b_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	.mode = &ts8550b_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	.lanes = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	.flags = MIPI_DSI_MODE_VIDEO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	.format = MIPI_DSI_FMT_RGB888,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	.supply_names = ts8550b_supply_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	.num_supplies = ARRAY_SIZE(ts8550b_supply_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	.panel_sleep_delay = 80, /* panel need extra 80ms for sleep out cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	const struct st7701_panel_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	struct st7701 *st7701;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	st7701 = devm_kzalloc(&dsi->dev, sizeof(*st7701), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	if (!st7701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	desc = of_device_get_match_data(&dsi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	dsi->mode_flags = desc->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	dsi->format = desc->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	dsi->lanes = desc->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	st7701->supplies = devm_kcalloc(&dsi->dev, desc->num_supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 					sizeof(*st7701->supplies),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (!st7701->supplies)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	for (i = 0; i < desc->num_supplies; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		st7701->supplies[i].supply = desc->supply_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	ret = devm_regulator_bulk_get(&dsi->dev, desc->num_supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				      st7701->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	st7701->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (IS_ERR(st7701->reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		return PTR_ERR(st7701->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	drm_panel_init(&st7701->panel, &dsi->dev, &st7701_funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		       DRM_MODE_CONNECTOR_DSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	/**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	 * Once sleep out has been issued, ST7701 IC required to wait 120ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	 * before initiating new commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	 * On top of that some panels might need an extra delay to wait, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	 * add panel specific delay for those cases. As now this panel specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	 * delay information is referenced from those panel BSP driver, example
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	 * ts8550b and there is no valid documentation for that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	st7701->sleep_delay = 120 + desc->panel_sleep_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	ret = drm_panel_of_backlight(&st7701->panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	drm_panel_add(&st7701->panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	mipi_dsi_set_drvdata(dsi, st7701);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	st7701->dsi = dsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	st7701->desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	return mipi_dsi_attach(dsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static int st7701_dsi_remove(struct mipi_dsi_device *dsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	struct st7701 *st7701 = mipi_dsi_get_drvdata(dsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	mipi_dsi_detach(dsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	drm_panel_remove(&st7701->panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static const struct of_device_id st7701_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	{ .compatible = "techstar,ts8550b", .data = &ts8550b_desc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) MODULE_DEVICE_TABLE(of, st7701_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static struct mipi_dsi_driver st7701_dsi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	.probe		= st7701_dsi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	.remove		= st7701_dsi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		.name		= "st7701",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		.of_match_table	= st7701_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) module_mipi_dsi_driver(st7701_dsi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) MODULE_DESCRIPTION("Sitronix ST7701 LCD Panel Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) MODULE_LICENSE("GPL");