1 #include <linux/string.h>
6 // ---------------------------------------------------------------------------
8 // ---------------------------------------------------------------------------
10 #define FRAME_WIDTH (240)
11 #define FRAME_HEIGHT (400)
13 // ---------------------------------------------------------------------------
15 // ---------------------------------------------------------------------------
17 static LCM_UTIL_FUNCS lcm_util
= {0};
19 #define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v)))
21 #define UDELAY(n) (lcm_util.udelay(n))
22 #define MDELAY(n) (lcm_util.mdelay(n))
25 // ---------------------------------------------------------------------------
27 // ---------------------------------------------------------------------------
29 static __inline
unsigned int LOW_BYTE(unsigned int x
)
34 static __inline
unsigned int HIGH_BYTE(unsigned int x
)
36 return ((x
>> 8) & 0xFF);
39 static __inline
void send_ctrl_cmd(unsigned int cmd
)
41 lcm_util
.send_cmd(cmd
);
44 static __inline
void send_data_cmd(unsigned int data
)
46 lcm_util
.send_data(data
);
49 static __inline
unsigned int read_data_cmd(void)
51 return lcm_util
.read_data();
54 static __inline
void set_lcm_register(unsigned int regIndex
,
57 send_ctrl_cmd(regIndex
);
58 send_data_cmd(regData
);
62 static void init_lcm_registers(void)
64 set_lcm_register(0x83, 0x02); // TESTTM=1
65 set_lcm_register(0x85, 0x03); // VDC_SEL=011
66 set_lcm_register(0x8c, 0x93);
67 set_lcm_register(0x91, 0x01); // pre:0x01
68 set_lcm_register(0x83, 0x00);
71 set_lcm_register(0x3E, 0xB0);
72 set_lcm_register(0x3F, 0x03);
73 set_lcm_register(0x40, 0x10);
74 set_lcm_register(0x41, 0x56);
75 set_lcm_register(0x42, 0x13);
76 set_lcm_register(0x43, 0x46);
77 set_lcm_register(0x44, 0x23);
78 set_lcm_register(0x45, 0x76);
79 set_lcm_register(0x46, 0x00);
80 set_lcm_register(0x47, 0x5e);
81 set_lcm_register(0x48, 0x4f);
82 set_lcm_register(0x49, 0x40);
84 // Power Supply Setting
85 set_lcm_register(0x17, 0x91); // RADJ = 1010(7.5MHz x 100%), OSC_EN = 1
86 set_lcm_register(0x23, 0x01); // TE ON, new added
87 set_lcm_register(0x2B, 0xF9); // N_DCDC = 0xF9
90 set_lcm_register(0x1B, 0x16); // BT = 0001, AP = 100
91 set_lcm_register(0x1A, 0x11); // VC3 = 001, VC1 = 001
92 set_lcm_register(0x1C, 0x0D); // VRH = 1101
93 set_lcm_register(0x1F, 0x42); // VCM = 100_0010
96 set_lcm_register(0x19, 0x0A); // GASENB=0,PON=0,DK=1,XDK=0,VLCD_TRI=1,STB=0
97 set_lcm_register(0x19, 0x1A); // GASENB=0,PON=1,DK=1,XDK=0,VLCD_TRI=1,STB=0
99 set_lcm_register(0x19, 0x12); // GASENB=0,PON=1,DK=0,XDK=0,VLCD_TRI=1,STB=0
101 set_lcm_register(0x1E, 0x2C); // VCOMG=1,VDV=0_1100
103 set_lcm_register(0x3C, 0x60);
104 set_lcm_register(0x3D, 0x40);
105 set_lcm_register(0x34, 0x38);
106 set_lcm_register(0x35, 0x38);
107 set_lcm_register(0x24, 0x38);
109 set_lcm_register(0x24, 0x3C);
110 set_lcm_register(0x16, 0x08); // pre:C8
111 set_lcm_register(0x01, 0x02);
112 set_lcm_register(0x55, 0x00);
116 // ---------------------------------------------------------------------------
117 // LCM Driver Implementations
118 // ---------------------------------------------------------------------------
120 static void lcm_set_util_funcs(const LCM_UTIL_FUNCS
*util
)
122 memcpy(&lcm_util
, util
, sizeof(LCM_UTIL_FUNCS
));
126 static void lcm_get_params(LCM_PARAMS
*params
)
128 memset(params
, 0, sizeof(LCM_PARAMS
));
130 params
->type
= LCM_TYPE_DBI
;
131 params
->ctrl
= LCM_CTRL_PARALLEL_DBI
;
132 params
->width
= FRAME_WIDTH
;
133 params
->height
= FRAME_HEIGHT
;
135 params
->dbi
.port
= 0;
136 params
->dbi
.clock_freq
= LCM_DBI_CLOCK_FREQ_52M
;
137 params
->dbi
.data_width
= LCM_DBI_DATA_WIDTH_18BITS
;
138 params
->dbi
.data_format
.color_order
= LCM_COLOR_ORDER_RGB
;
139 params
->dbi
.data_format
.trans_seq
= LCM_DBI_TRANS_SEQ_LSB_FIRST
;
140 params
->dbi
.data_format
.padding
= LCM_DBI_PADDING_ON_MSB
;
141 params
->dbi
.data_format
.format
= LCM_DBI_FORMAT_RGB666
;
142 params
->dbi
.data_format
.width
= LCM_DBI_DATA_WIDTH_18BITS
;
143 params
->dbi
.cpu_write_bits
= LCM_DBI_CPU_WRITE_32_BITS
;
144 params
->dbi
.io_driving_current
= 0;
146 params
->dbi
.te_mode
= LCM_DBI_TE_MODE_VSYNC_OR_HSYNC
;
147 params
->dbi
.te_edge_polarity
= LCM_POLARITY_RISING
;
148 params
->dbi
.te_hs_delay_cnt
= 50;
149 params
->dbi
.te_vs_width_cnt
= 277;
150 params
->dbi
.te_vs_width_cnt_div
= LCM_DBI_TE_VS_WIDTH_CNT_DIV_16
;
152 params
->dbi
.parallel
.write_setup
= 2;
153 params
->dbi
.parallel
.write_hold
= 2;
154 params
->dbi
.parallel
.write_wait
= 4;
155 params
->dbi
.parallel
.read_setup
= 2;
156 params
->dbi
.parallel
.read_latency
= 9;
157 params
->dbi
.parallel
.wait_period
= 0;
161 static void lcm_init(void)
168 init_lcm_registers();
170 // Enable tearing control signal
172 set_lcm_register(0x23, 0x03); // enable TEMODE = 1
176 static void lcm_suspend(void)
178 set_lcm_register(0x24, 0x38); // PT=00,GON=1, DTE=1, D=11
180 set_lcm_register(0x24, 0x28); // PT=00,GON=1, DTE=1, D=11
182 set_lcm_register(0x24, 0x20); // PT=00,GON=1, DTE=1, D=11
183 set_lcm_register(0x3C, 0x00); // N_SAP=0000 0000
184 set_lcm_register(0x1B, 0x10); // BT=0001, AP=000
185 set_lcm_register(0x19, 0x0A); // PON=0, DK=1
186 set_lcm_register(0x1E, 0x00); // VCOMG=1,
187 set_lcm_register(0x19, 0x01); // STB=1
188 set_lcm_register(0x17, 0x00); // OSC_EN=0
192 static void lcm_resume(void)
194 set_lcm_register(0x17, 0x91); // RADJ=1010(7.5MHz x 100%), OSC_EN=1
195 set_lcm_register(0x2B, 0xF9); // N_DCDC=0xF9.
197 set_lcm_register(0x1B, 0x14); // BT=0001, AP=100
198 set_lcm_register(0x1A, 0x11); // VC3=001, VC1=001
199 set_lcm_register(0x1C, 0x0D); // VRH=1101
200 set_lcm_register(0x1F, 0x42); // VCM=100_0010
202 set_lcm_register(0x19, 0x0A); // GASENB=0, PON=0, DK=1, XDK=0,VLCD_TRI=1, STB=0
203 set_lcm_register(0x19, 0x1A); // GASENB=0, PON=1, DK=1, XDK=0,VLCD_TRI=1, STB=0
205 set_lcm_register(0x19, 0x12); // GASENB=0, PON=1, DK=0, XDK=0,VLCD_TRI=1, STB=0
207 set_lcm_register(0x1E, 0x2C); // VCOMG=1, VDV=0_1100
210 // Display ON Setting
211 set_lcm_register(0x3C, 0x60); // N_SAP=0110 0000
212 set_lcm_register(0x3D, 0x40); // I_SAP =0100 0000
213 set_lcm_register(0x34, 0x38); // EQS=0011 1000
214 set_lcm_register(0x35, 0x38); // EQP=0011 1000
215 set_lcm_register(0x24, 0x38); // PT=00,GON=1, DTE=1, D=10
217 set_lcm_register(0x24, 0x3C); // PT=00,GON=1, DTE=1, D=11
218 set_lcm_register(0x16, 0x08); // MY=1,MX=1,MV=0,GS=0,BGR=1,SS=0,SRL_EN=0,SM=0
219 set_lcm_register(0x01, 0x02); // IDMON=0,INVON=0,NORNO=1,PTLON=0
220 set_lcm_register(0x55, 0x00); // SM_PANEL=0,SS_PANEL=0,GS_PANEL=0,REV_PANEL=0,BGR_PANEL=0
222 // Enable tearing control signal
224 set_lcm_register(0x23, 0x03); // enable TEMODE = 1
228 static void lcm_update(unsigned int x
, unsigned int y
,
229 unsigned int width
, unsigned int height
)
233 unsigned int x1
= x0
+ width
- 1;
234 unsigned int y1
= y0
+ height
- 1;
236 set_lcm_register(0x02, HIGH_BYTE(x0
));
237 set_lcm_register(0x03, LOW_BYTE(x0
));
238 set_lcm_register(0x04, HIGH_BYTE(x1
));
239 set_lcm_register(0x05, LOW_BYTE(x1
));
240 set_lcm_register(0x06, HIGH_BYTE(y0
));
241 set_lcm_register(0x07, LOW_BYTE(y0
));
242 set_lcm_register(0x08, HIGH_BYTE(y1
));
243 set_lcm_register(0x09, LOW_BYTE(y1
));
248 static unsigned int lcm_compare_id(void)
251 return (LCM_ID
== read_data_cmd())?1:0;
255 // ---------------------------------------------------------------------------
256 // Get LCM Driver Hooks
257 // ---------------------------------------------------------------------------
259 LCM_DRIVER bm8578_lcm_drv
=
262 .set_util_funcs
= lcm_set_util_funcs
,
263 .get_params
= lcm_get_params
,
265 .suspend
= lcm_suspend
,
266 .resume
= lcm_resume
,
267 .update
= lcm_update
,
268 .compare_id
= lcm_compare_id