1 /*
2  * Copyright 2017, 2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_display.h"
10 #include "fsl_rm67191.h"
11 
12 /*******************************************************************************
13  * Definitions
14  ******************************************************************************/
15 #define RM67191_DelayMs VIDEO_DelayMs
16 
17 /*******************************************************************************
18  * Variables
19  ******************************************************************************/
20 static const uint8_t lcmInitSetting[][2] = {
21     {0xFE, 0x0B}, {0x28, 0x40}, {0x29, 0x4F}, {0xFE, 0x0E}, {0x4B, 0x00}, {0x4C, 0x0F}, {0x4D, 0x20}, {0x4E, 0x40},
22     {0x4F, 0x60}, {0x50, 0xA0}, {0x51, 0xC0}, {0x52, 0xE0}, {0x53, 0xFF}, {0xFE, 0x0D}, {0x18, 0x08}, {0x42, 0x00},
23     {0x08, 0x41}, {0x46, 0x02}, {0x72, 0x09}, {0xFE, 0x0A}, {0x24, 0x17}, {0x04, 0x07}, {0x1A, 0x0C}, {0x0F, 0x44},
24     {0xFE, 0x04}, {0x00, 0x0C}, {0x05, 0x08}, {0x06, 0x08}, {0x08, 0x08}, {0x09, 0x08}, {0x0A, 0xE6}, {0x0B, 0x8C},
25     {0x1A, 0x12}, {0x1E, 0xE0}, {0x29, 0x93}, {0x2A, 0x93}, {0x2F, 0x02}, {0x31, 0x02}, {0x33, 0x05}, {0x37, 0x2D},
26     {0x38, 0x2D}, {0x3A, 0x1E}, {0x3B, 0x1E}, {0x3D, 0x27}, {0x3F, 0x80}, {0x40, 0x40}, {0x41, 0xE0}, {0x4F, 0x2F},
27     {0x50, 0x1E}, {0xFE, 0x06}, {0x00, 0xCC}, {0x05, 0x05}, {0x07, 0xA2}, {0x08, 0xCC}, {0x0D, 0x03}, {0x0F, 0xA2},
28     {0x32, 0xCC}, {0x37, 0x05}, {0x39, 0x83}, {0x3A, 0xCC}, {0x41, 0x04}, {0x43, 0x83}, {0x44, 0xCC}, {0x49, 0x05},
29     {0x4B, 0xA2}, {0x4C, 0xCC}, {0x51, 0x03}, {0x53, 0xA2}, {0x75, 0xCC}, {0x7A, 0x03}, {0x7C, 0x83}, {0x7D, 0xCC},
30     {0x82, 0x02}, {0x84, 0x83}, {0x85, 0xEC}, {0x86, 0x0F}, {0x87, 0xFF}, {0x88, 0x00}, {0x8A, 0x02}, {0x8C, 0xA2},
31     {0x8D, 0xEA}, {0x8E, 0x01}, {0x8F, 0xE8}, {0xFE, 0x06}, {0x90, 0x0A}, {0x92, 0x06}, {0x93, 0xA0}, {0x94, 0xA8},
32     {0x95, 0xEC}, {0x96, 0x0F}, {0x97, 0xFF}, {0x98, 0x00}, {0x9A, 0x02}, {0x9C, 0xA2}, {0xAC, 0x04}, {0xFE, 0x06},
33     {0xB1, 0x12}, {0xB2, 0x17}, {0xB3, 0x17}, {0xB4, 0x17}, {0xB5, 0x17}, {0xB6, 0x11}, {0xB7, 0x08}, {0xB8, 0x09},
34     {0xB9, 0x06}, {0xBA, 0x07}, {0xBB, 0x17}, {0xBC, 0x17}, {0xBD, 0x17}, {0xBE, 0x17}, {0xBF, 0x17}, {0xC0, 0x17},
35     {0xC1, 0x17}, {0xC2, 0x17}, {0xC3, 0x17}, {0xC4, 0x0F}, {0xC5, 0x0E}, {0xC6, 0x00}, {0xC7, 0x01}, {0xC8, 0x10},
36     {0xFE, 0x0D}, {0x95, 0xEC}, {0x8D, 0xEE}, {0x44, 0xEC}, {0x4C, 0xEC}, {0x32, 0xEC}, {0x3A, 0xEC}, {0x7D, 0xEC},
37     {0x75, 0xEC}, {0x00, 0xEC}, {0x08, 0xEC}, {0x85, 0xEC}, {0xA6, 0x21}, {0xA7, 0x05}, {0xA9, 0x06}, {0x82, 0x06},
38     {0x41, 0x06}, {0x7A, 0x07}, {0x37, 0x07}, {0x05, 0x06}, {0x49, 0x06}, {0x0D, 0x04}, {0x51, 0x04},
39 };
40 
41 const display_operations_t rm67191_ops = {
42     .init   = RM67191_Init,
43     .deinit = RM67191_Deinit,
44     .start  = RM67191_Start,
45     .stop   = RM67191_Stop,
46 };
47 
48 /*******************************************************************************
49  * Code
50  ******************************************************************************/
51 
RM67191_Init(display_handle_t * handle,const display_config_t * config)52 status_t RM67191_Init(display_handle_t *handle, const display_config_t *config)
53 {
54     uint32_t i;
55     status_t status                    = kStatus_Success;
56     const rm67191_resource_t *resource = (const rm67191_resource_t *)(handle->resource);
57     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
58 
59     /* Perform reset. */
60     resource->pullResetPin(true);
61 
62     RM67191_DelayMs(10);
63 
64     resource->pullResetPin(false);
65 
66     RM67191_DelayMs(5);
67 
68     resource->pullResetPin(true);
69     RM67191_DelayMs(20);
70 
71     /* Set the LCM init settings. */
72     for (i = 0; i < ARRAY_SIZE(lcmInitSetting); i++)
73     {
74         status = MIPI_DSI_GenericWrite(dsiDevice, lcmInitSetting[i], 2);
75 
76         if (kStatus_Success != status)
77         {
78             return status;
79         }
80     }
81 
82     /* Change to send user command. */
83     const uint8_t rm67191UserCmdEntry[] = {RM67191_WRMAUCCTR, 0x00};
84     status = MIPI_DSI_GenericWrite(dsiDevice, rm67191UserCmdEntry, (int32_t)ARRAY_SIZE(rm67191UserCmdEntry));
85     if (kStatus_Success != status)
86     {
87         return status;
88     }
89 
90     /* Software reset */
91     status = MIPI_DSI_DCS_SoftReset(dsiDevice);
92     if (kStatus_Success != status)
93     {
94         return status;
95     }
96 
97     RM67191_DelayMs(100);
98 
99     /* Set DSI mode */
100     const uint8_t rm67191DsiMode[] = {RM67191_SETDSIMODE, 0x03};
101     status = MIPI_DSI_GenericWrite(dsiDevice, rm67191DsiMode, (int32_t)ARRAY_SIZE(rm67191DsiMode));
102     if (kStatus_Success != status)
103     {
104         return status;
105     }
106 
107     /* Brightness. */
108     const uint8_t rm67191Brightness[] = {RM67191_WRDISBV, 0xff};
109     status = MIPI_DSI_GenericWrite(dsiDevice, rm67191Brightness, (int32_t)ARRAY_SIZE(rm67191Brightness));
110     if (kStatus_Success != status)
111     {
112         return status;
113     }
114 
115     /* Exit sleep mode */
116     status = MIPI_DSI_DCS_EnterSleepMode(dsiDevice, false);
117     if (kStatus_Success != status)
118     {
119         return status;
120     }
121 
122     RM67191_DelayMs(120);
123 
124     /* Set display on. */
125     status = MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
126     if (kStatus_Success != status)
127     {
128         return status;
129     }
130 
131     RM67191_DelayMs(100);
132 
133     return kStatus_Success;
134 }
135 
RM67191_Deinit(display_handle_t * handle)136 status_t RM67191_Deinit(display_handle_t *handle)
137 {
138     status_t status;
139     const rm67191_resource_t *resource = (const rm67191_resource_t *)(handle->resource);
140     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
141 
142     status = MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
143     if (kStatus_Success != status)
144     {
145         return status;
146     }
147 
148     resource->pullResetPin(false);
149 
150     return kStatus_Success;
151 }
152 
RM67191_Start(display_handle_t * handle)153 status_t RM67191_Start(display_handle_t *handle)
154 {
155     const rm67191_resource_t *resource = (const rm67191_resource_t *)(handle->resource);
156     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
157 
158     return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
159 }
160 
RM67191_Stop(display_handle_t * handle)161 status_t RM67191_Stop(display_handle_t *handle)
162 {
163     const rm67191_resource_t *resource = (const rm67191_resource_t *)(handle->resource);
164     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
165 
166     return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
167 }
168