1 /*
2  * Copyright 2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_display.h"
9 #include "fsl_rpi.h"
10 
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 #define RPI_DelayMs    VIDEO_DelayMs
15 #define RPI_PWRON_ADDR 0x85U
16 #define RPI_PORTB_ADDR 0x82U
17 #define RPI_PWM_ADDR   0x86U
18 /*******************************************************************************
19  * Variables
20  ******************************************************************************/
21 const display_operations_t rpi_ops = {
22     .init   = RPI_Init,
23     .deinit = RPI_Deinit,
24     .start  = RPI_Start,
25     .stop   = RPI_Stop,
26 };
27 
28 static const uint8_t s_rpiCmds[11][6] = {
29     {0x10U, 0x02U, 0x03U, 0x00U, 0x00U, 0x00U}, {0x64U, 0x01U, 0x05U, 0x00U, 0x00U, 0x00U},
30     {0x68U, 0x01U, 0x05U, 0x00U, 0x00U, 0x00U}, {0x44U, 0x01U, 0x00U, 0x00U, 0x00U, 0x00U},
31     {0x48U, 0x01U, 0x00U, 0x00U, 0x00U, 0x00U}, {0x14U, 0x01U, 0x03U, 0x00U, 0x00U, 0x00U},
32     {0x50U, 0x04U, 0x00U, 0x00U, 0x00U, 0x00U}, {0x20U, 0x04U, 0x50U, 0x01U, 0x10U, 0x00U},
33     {0x64U, 0x04U, 0x0fU, 0x04U, 0x00U, 0x00U}, {0x04U, 0x01U, 0x01U, 0x00U, 0x00U, 0x00U},
34     {0x04U, 0x02U, 0x01U, 0x00U, 0x00U, 0x00U}};
35 /*******************************************************************************
36  * Code
37  ******************************************************************************/
38 
RPI_Init(display_handle_t * handle,const display_config_t * config)39 status_t RPI_Init(display_handle_t *handle, const display_config_t *config)
40 {
41     status_t status                = kStatus_Success;
42     const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
43     mipi_dsi_device_t *dsiDevice   = resource->dsiDevice;
44     uint8_t regVal                 = 0U;
45 
46     /* Only support one set of resolution. */
47     if (config->resolution != FSL_VIDEO_RESOLUTION(800, 480))
48     {
49         return kStatus_InvalidArgument;
50     }
51 
52     /* Reset panel. */
53     if (resource->writeRegister(RPI_PWRON_ADDR, 0x0U) != kStatus_Success)
54     {
55         return kStatus_Fail;
56     }
57     VIDEO_DelayMs(400);
58     if (resource->writeRegister(RPI_PWRON_ADDR, 0x1U) != kStatus_Success)
59     {
60         return kStatus_Fail;
61     }
62     VIDEO_DelayMs(400);
63 
64     /* Wait for power on done. */
65     while ((regVal & 0x1U) == 0U)
66     {
67         if (resource->readStatus(RPI_PORTB_ADDR, &regVal) != kStatus_Success)
68         {
69             return kStatus_Fail;
70         }
71     }
72 
73     /* Set backlight. */
74     if (resource->writeRegister(RPI_PWM_ADDR, 0x80U) != kStatus_Success)
75     {
76         return kStatus_Fail;
77     }
78 
79     for (uint8_t i = 0; i < ARRAY_SIZE(s_rpiCmds); i++)
80     {
81         status = MIPI_DSI_GenericWrite(dsiDevice, s_rpiCmds[i], 6);
82 
83         if (kStatus_Success != status)
84         {
85             break;
86         }
87 
88         if ((i == 8U) || (i == 10U))
89         {
90             RPI_DelayMs(100);
91         }
92     }
93 
94     return status;
95 }
96 
RPI_Deinit(display_handle_t * handle)97 status_t RPI_Deinit(display_handle_t *handle)
98 {
99     const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
100     mipi_dsi_device_t *dsiDevice   = resource->dsiDevice;
101 
102     (void)MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
103 
104     return kStatus_Success;
105 }
106 
RPI_Start(display_handle_t * handle)107 status_t RPI_Start(display_handle_t *handle)
108 {
109     const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
110     mipi_dsi_device_t *dsiDevice   = resource->dsiDevice;
111 
112     return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
113 }
114 
RPI_Stop(display_handle_t * handle)115 status_t RPI_Stop(display_handle_t *handle)
116 {
117     const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
118     mipi_dsi_device_t *dsiDevice   = resource->dsiDevice;
119 
120     return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
121 }
122