1 /*
2  * Allwinner SoCs display driver.
3  *
4  * Copyright (C) 2016 Allwinner.
5  *
6  * This file is licensed under the terms of the GNU General Public
7  * License version 2.  This program is licensed "as is" without any
8  * warranty of any kind, whether express or implied.
9  */
10 
11 #include "default_eink.h"
12 
13 static void EINK_power_on(u32 sel);
14 static void EINK_power_off(u32 sel);
15 
EINK_cfg_panel_info(struct panel_extend_para * info)16 static void EINK_cfg_panel_info(struct panel_extend_para *info)
17 {
18     u32 i = 0, j = 0;
19     u32 items;
20     u8 lcd_gamma_tbl[][2] = {
21         /* {input value, corrected value} */
22         {0, 0},
23         {15, 15},
24         {30, 30},
25         {45, 45},
26         {60, 60},
27         {75, 75},
28         {90, 90},
29         {105, 105},
30         {120, 120},
31         {135, 135},
32         {150, 150},
33         {165, 165},
34         {180, 180},
35         {195, 195},
36         {210, 210},
37         {225, 225},
38         {240, 240},
39         {255, 255},
40     };
41 
42     u32 lcd_cmap_tbl[2][3][4] = {
43         {
44          {LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3},
45          {LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3},
46          {LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3},
47          },
48         {
49          {LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0},
50          {LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0},
51          {LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0},
52          },
53     };
54 
55     items = sizeof(lcd_gamma_tbl) / 2;
56     for (i = 0; i < items - 1; i++) {
57         u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0];
58 
59         for (j = 0; j < num; j++) {
60             u32 value = 0;
61 
62             value =
63                 lcd_gamma_tbl[i][1] +
64                 ((lcd_gamma_tbl[i + 1][1] -
65                   lcd_gamma_tbl[i][1]) * j) / num;
66             info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
67                 (value << 16) + (value << 8) + value;
68         }
69     }
70     info->lcd_gamma_tbl[255] =
71         (lcd_gamma_tbl[items - 1][1] << 16) +
72         (lcd_gamma_tbl[items - 1][1] << 8) + lcd_gamma_tbl[items - 1][1];
73 
74     memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
75 
76 }
77 
EINK_open_flow(u32 sel)78 static s32 EINK_open_flow(u32 sel)
79 {
80     LCD_OPEN_FUNC(sel, EINK_power_on, 2);
81     LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 0);
82     return 0;
83 }
84 
EINK_close_flow(u32 sel)85 static s32 EINK_close_flow(u32 sel)
86 {
87     LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 0);
88     LCD_CLOSE_FUNC(sel, EINK_power_off, 2);
89 
90     return 0;
91 }
92 
EINK_power_on(u32 sel)93 static void EINK_power_on(u32 sel)
94 {
95     /* pwr3 pb2 */
96     sunxi_lcd_gpio_set_value(sel, 0, 1);
97     sunxi_lcd_delay_ms(1);
98     /* pwr0 pb0 */
99     sunxi_lcd_gpio_set_value(sel, 1, 1);
100     sunxi_lcd_delay_ms(1);
101     /* pb1 */
102     sunxi_lcd_gpio_set_value(sel, 2, 1);
103     sunxi_lcd_delay_ms(1);
104     /* pwr2 pd6 */
105     sunxi_lcd_gpio_set_value(sel, 3, 1);
106     sunxi_lcd_delay_ms(1);
107     /* pwr com pd7 */
108     sunxi_lcd_gpio_set_value(sel, 4, 1);
109     sunxi_lcd_delay_ms(1);
110 
111     sunxi_lcd_gpio_set_value(sel, 5, 1);
112     sunxi_lcd_delay_ms(2);
113 
114     sunxi_lcd_pin_cfg(sel, 1);
115 }
116 
EINK_power_off(u32 sel)117 static void EINK_power_off(u32 sel)
118 {
119     sunxi_lcd_pin_cfg(sel, 0);
120 
121     sunxi_lcd_gpio_set_value(sel, 5, 0);
122     sunxi_lcd_delay_ms(1);
123     sunxi_lcd_gpio_set_value(sel, 4, 0);
124     sunxi_lcd_delay_ms(1);
125     sunxi_lcd_gpio_set_value(sel, 3, 0);
126     sunxi_lcd_delay_ms(1);
127     sunxi_lcd_gpio_set_value(sel, 2, 0);
128     sunxi_lcd_delay_ms(1);
129     sunxi_lcd_gpio_set_value(sel, 1, 0);
130     sunxi_lcd_delay_ms(1);
131     sunxi_lcd_gpio_set_value(sel, 0, 0);
132     sunxi_lcd_delay_ms(2);
133 }
134 
135 /* sel: 0:lcd0; 1:lcd1 */
EINK_user_defined_func(u32 sel,u32 para1,u32 para2,u32 para3)136 static s32 EINK_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3)
137 {
138     return 0;
139 }
140 
141 struct __lcd_panel default_eink = {
142     /* panel driver name, must mach the lcd_drv_name in sys_config.fex */
143     .name = "default_eink",
144     .func = {
145          .cfg_panel_info = EINK_cfg_panel_info,
146          .cfg_open_flow = EINK_open_flow,
147          .cfg_close_flow = EINK_close_flow,
148          .lcd_user_defined_func = EINK_user_defined_func,
149          }
150     ,
151 };
152