RX_498HX_615B.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #if defined(BUILD_LK)
  32. #include <platform/mt_gpio.h>
  33. #include <platform/mt_pmic.h>
  34. #else
  35. #include <mach/mt_gpio.h>
  36. #include <mach/mt_pm_ldo.h>
  37. #endif
  38. #if !defined(BUILD_LK)
  39. #include <linux/string.h>
  40. #else
  41. #include <string.h>
  42. #endif
  43. #include "lcm_drv.h"
  44. #if defined(BUILD_LK)
  45. #define LCM_DEBUG(fmt,arg...) printf("[Eric][lk]""[%s]"fmt"\n",__func__,##arg)
  46. #elif defined(BUILD_UBOOT)
  47. #define LCM_DEBUG(fmt,arg...) printf("[Eric][uboot]""[%s]"fmt"\n",__func__,##arg)
  48. #else
  49. #define LCM_DEBUG(fmt,arg...) printk("[Eric][kernel]""[%s]"fmt"\n",__func__,##arg)
  50. #endif
  51. // ---------------------------------------------------------------------------
  52. // Local Constants
  53. // ---------------------------------------------------------------------------
  54. #define FRAME_WIDTH (480)
  55. #define FRAME_HEIGHT (854)
  56. // ---------------------------------------------------------------------------
  57. // Data ID
  58. // ---------------------------------------------------------------------------
  59. #define DSI_DCS_SHORT_PACKET_ID_0 0x05
  60. #define DSI_DCS_SHORT_PACKET_ID_1 0x15
  61. #define DSI_DCS_LONG_PACKET_ID 0x39
  62. // ---------------------------------------------------------------------------
  63. // Local Variables
  64. // ---------------------------------------------------------------------------
  65. static LCM_UTIL_FUNCS lcm_util = {0};
  66. #define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v)))
  67. #define UDELAY(n) (lcm_util.udelay(n))
  68. #define MDELAY(n) (lcm_util.mdelay(n))
  69. #define REGFLAG_DELAY 0XFE
  70. #define REGFLAG_END_OF_TABLE 0x100 // END OF REGISTERS MARKER
  71. // ---------------------------------------------------------------------------
  72. // Local Functions
  73. // ---------------------------------------------------------------------------
  74. #define dsi_set_cmdq_V3(para_tbl, size, force_update) lcm_util.dsi_set_cmdq_V3(para_tbl, size, force_update)
  75. #define dsi_set_cmdq_V2(cmd, count, ppara, force_update) lcm_util.dsi_set_cmdq_V2(cmd, count, ppara, force_update)
  76. #define dsi_set_cmdq(pdata, queue_size, force_update) lcm_util.dsi_set_cmdq(pdata, queue_size, force_update)
  77. #define wrtie_cmd(cmd) lcm_util.dsi_write_cmd(cmd)
  78. #define write_regs(addr, pdata, byte_nums) lcm_util.dsi_write_regs(addr, pdata, byte_nums)
  79. #define read_reg lcm_util.dsi_read_reg()
  80. #define LCM_DSI_CMD_MODE 0
  81. struct LCM_setting_table {
  82. unsigned cmd;
  83. unsigned char count;
  84. unsigned char para_list[64];
  85. };
  86. static struct LCM_setting_table lcm_initialization_setting[] = {
  87. #if 0
  88. // SET password
  89. {0xB9, 3, {0xFF,0x83,0x79}},
  90. {0xBA, 1, {0x51}},
  91. // Issue DSC NOP command
  92. {
  93. 0xB1, 19, {
  94. 0x00,0x50,0x44,0xEA,0x8D,0x08,0x11,0x11,0x11,0x27,
  95. 0x2F,0x9A,0x1A,0x42,0x0B,0x6E,0xF1,0x00,0xE6
  96. }
  97. },
  98. {
  99. 0xB2, 13, {
  100. 0x00,0x00,0xFE,0x08,0x04,0x19,0x22,0x00,0xFF,0x08,
  101. 0x04,0x19,0x20
  102. }
  103. },
  104. {
  105. 0xB4, 31, {
  106. 0x80,0x08,0x00,0x32,0x10,0x03,0x32,0x13,0x70,0x32,
  107. 0x10,0x08,0x37,0x01,0x28,0x07,0x37,0x08,0x4C,0x20,
  108. 0x44,0x44,0x08,0x00,0x40,0x08,0x28,0x08,0x30,0x30,
  109. 0x04
  110. }
  111. },
  112. {
  113. 0xD5, 47, {
  114. 0x00,0x00,0x0A,0x00,0x01,0x05,0x00,0x03,0x00,0x88,
  115. 0x88,0x88,0x88,0x23,0x01,0x67,0x45,0x02,0x13,0x88,
  116. 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x54,
  117. 0x76,0x10,0x32,0x31,0x20,0x88,0x88,0x88,0x88,0x88,
  118. 0x88,0x00,0x00,0x00,0x00,0x00,0x00
  119. }
  120. },
  121. {
  122. 0xE0, 35, {
  123. 0x79,0x00,0x01,0x02,0x22,0x23,0x30,0x23,0x43,0x00,
  124. 0x01,0x12,0x17,0x19,0x17,0x17,0x13,0x18,0x00,0x01,
  125. 0x02,0x22,0x23,0x30,0x23,0x43,0x00,0x01,0x12,0x17,
  126. 0x19,0x17,0x17,0x13,0x18
  127. }
  128. },
  129. {0xCC, 1, {0x02}},
  130. {0xB6, 4, {0x00,0x88,0x00,0x88}},
  131. // Sleep Out
  132. {0x11, 1, {0X00}},
  133. {REGFLAG_DELAY, 150, {}},
  134. // Display On
  135. {0x29, 1, {0X00}},
  136. {REGFLAG_DELAY, 50, {}},
  137. #else
  138. {0xB9,3,{ 0xFF ,0x83 ,0x79}},
  139. {0xBA,1,{ 0x51}},
  140. {0xB1,19,{ 0x00 ,0x50 ,0x44 ,0xEA ,0x8D ,0x08 ,0x11 ,0x11 ,0x11 ,0x25 ,0x2d ,0x9A ,0x1A ,0x42 ,0x0B ,0x66 ,0xF1 ,0x00 ,0xE6}},
  141. {0xB2,13,{ 0x00 ,0x00 ,0xFE ,0x08 ,0x04 ,0x19 ,0x12 ,0x00 ,0xFF ,0x08 ,0x04 ,0x19 ,0x20}},
  142. {0xB4,31,{ 0x80 ,0x08 ,0x00 ,0x32 ,0x10 ,0x03 ,0x32 ,0x13 ,0x70 ,0x32 ,0x10 ,0x08 ,0x37 ,0x01 ,0x28 ,0x07 ,0x37 ,0x08 ,0x3C ,0x20 ,0x44 ,0x44 ,0x08 ,0x00 ,0x40 ,0x08 ,0x28 ,0x08 ,0x30 ,0x30 ,0x08}},
  143. {0xD5,47,{ 0x00 ,0x00 ,0x0a ,0x00 ,0x01 ,0x05 ,0x00 ,0x03 ,0x00 ,0x88 ,0x88 ,0x88 ,0x88 ,0x23 ,0x01 ,0x67 ,0x45 ,0x02 ,0x13 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x54 ,0x76 ,0x10 ,0x32 ,0x31 ,0x20 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x88 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00}},
  144. {0xE0,35,{ 0x79 ,0x05 ,0x0F ,0x14 ,0x26 ,0x29 ,0x3F ,0x2B ,0x45 ,0x04 ,0x0E ,0x13 ,0x17 ,0x18 ,0x16 ,0x16 ,0x12 ,0x17 ,0x05 ,0x0F ,0x14 ,0x26 ,0x29 ,0x3F ,0x2B ,0x45 ,0x04 ,0x0E ,0x13 ,0x17 ,0x18 ,0x16 ,0x16 ,0x12 ,0x17}},
  145. {0xCC,1,{ 0x02}},
  146. {0xB6,4,{ 0x00 ,0x88 ,0x00 ,0x88}}, //83
  147. {0x36,1,{ 0x00}},
  148. {0x3A,1,{ 0x77}},
  149. {0x11,0,{}},
  150. {REGFLAG_DELAY, 150, {}},
  151. {0x29,0,{}},
  152. {REGFLAG_DELAY, 20, {}},
  153. #endif
  154. };
  155. #if 0
  156. static struct LCM_setting_table lcm_set_window[] = {
  157. {0x2A, 4, {0x00, 0x00, (FRAME_WIDTH>>8), (FRAME_WIDTH&0xFF)}},
  158. {0x2B, 4, {0x00, 0x00, (FRAME_HEIGHT>>8), (FRAME_HEIGHT&0xFF)}},
  159. {REGFLAG_END_OF_TABLE, 0x00, {}}
  160. };
  161. static struct LCM_setting_table lcm_sleep_out_setting[] = {
  162. // Sleep Out
  163. {0x11, 0, {0x00}},
  164. {REGFLAG_DELAY, 120, {}},
  165. // Display ON
  166. {0x29, 0, {0x00}},
  167. {REGFLAG_DELAY, 10, {}},
  168. {REGFLAG_END_OF_TABLE, 0x00, {}}
  169. };
  170. static struct LCM_setting_table lcm_deep_sleep_mode_in_setting[] = {
  171. // Display off sequence
  172. {0x28, 0, {0x00}},
  173. // Sleep Mode On
  174. {0x10, 0, {0x00}},
  175. {REGFLAG_END_OF_TABLE, 0x00, {}}
  176. };
  177. #endif
  178. static struct LCM_setting_table lcm_backlight_level_setting[] = {
  179. {0x51, 1, {0xFF}},
  180. {REGFLAG_END_OF_TABLE, 0x00, {}}
  181. };
  182. static void push_table(struct LCM_setting_table *table, unsigned int count, unsigned char force_update)
  183. {
  184. unsigned int i;
  185. LCM_setting_table_V3 para_tbl[1];
  186. for (i = 0; i < count; i++) {
  187. unsigned cmd;
  188. cmd = table[i].cmd;
  189. switch (cmd) {
  190. case REGFLAG_DELAY :
  191. MDELAY(table[i].count);
  192. break;
  193. case REGFLAG_END_OF_TABLE :
  194. break;
  195. default:
  196. //dsi_set_cmdq_V2(cmd, table[i].count, table[i].para_list, force_update);
  197. para_tbl[0].cmd = table[i].cmd;
  198. para_tbl[0].count = table[i].count;
  199. if (para_tbl[0].count > 1) {
  200. para_tbl[0].id = DSI_DCS_LONG_PACKET_ID;
  201. memcpy(para_tbl[0].para_list,table[i].para_list,para_tbl[0].count);
  202. } else if (para_tbl[0].count == 1) {
  203. para_tbl[0].id = DSI_DCS_SHORT_PACKET_ID_1;
  204. memcpy(para_tbl[0].para_list,table[i].para_list,para_tbl[0].count);
  205. } else if (para_tbl[0].count == 0) {
  206. para_tbl[0].id = DSI_DCS_SHORT_PACKET_ID_0;
  207. }
  208. dsi_set_cmdq_V3(para_tbl,1,1);
  209. }
  210. }
  211. }
  212. // ---------------------------------------------------------------------------
  213. // LCM Driver Implementations
  214. // ---------------------------------------------------------------------------
  215. static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util)
  216. {
  217. memcpy(&lcm_util, util, sizeof(LCM_UTIL_FUNCS));
  218. }
  219. static void lcm_get_params(LCM_PARAMS *params)
  220. {
  221. memset(params, 0, sizeof(LCM_PARAMS));
  222. params->type = LCM_TYPE_DSI;
  223. params->width = FRAME_WIDTH;
  224. params->height = FRAME_HEIGHT;
  225. // enable tearing-free
  226. params->dbi.te_mode = LCM_DBI_TE_MODE_DISABLED; //LCM_DBI_TE_MODE_VSYNC_ONLY;
  227. params->dbi.te_edge_polarity = LCM_POLARITY_RISING;
  228. params->dbi.io_driving_current = LCM_DRIVING_CURRENT_6575_16MA;
  229. params->dbi.data_format.format = 3; // [chenlang], just a flag to idicate command set
  230. #if (LCM_DSI_CMD_MODE)
  231. params->dsi.mode = CMD_MODE;
  232. #else
  233. params->dsi.mode = SYNC_PULSE_VDO_MODE;
  234. #endif
  235. // DSI
  236. /* Command mode setting */
  237. params->dsi.LANE_NUM = LCM_TWO_LANE;
  238. //The following defined the fomat for data coming from LCD engine.
  239. params->dsi.data_format.color_order = LCM_COLOR_ORDER_RGB;
  240. params->dsi.data_format.trans_seq = LCM_DSI_TRANS_SEQ_MSB_FIRST;
  241. params->dsi.data_format.padding = LCM_DSI_PADDING_ON_LSB;
  242. params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888;
  243. params->dsi.word_count=480*3; //DSI CMD mode need set these two bellow params, different to 6577
  244. params->dsi.vertical_active_line=854;
  245. // Highly depends on LCD driver capability.
  246. // Not support in MT6573
  247. params->dsi.packet_size=256;
  248. //params->dsi.intermediat_buffer_num = 0;
  249. // Video mode setting
  250. params->dsi.intermediat_buffer_num = 2;
  251. params->dsi.PS=LCM_PACKED_PS_24BIT_RGB888;
  252. #if 0
  253. params->dsi.vertical_sync_active = 4; //5;
  254. params->dsi.vertical_backporch = 6; //5;
  255. params->dsi.vertical_frontporch = 6; //5;
  256. params->dsi.vertical_active_line = FRAME_HEIGHT;
  257. params->dsi.horizontal_sync_active = 20;
  258. params->dsi.horizontal_backporch = 46;
  259. params->dsi.horizontal_frontporch = 21+10;
  260. params->dsi.horizontal_active_pixel = FRAME_WIDTH;
  261. #else
  262. params->dsi.vertical_sync_active = 4;
  263. params->dsi.vertical_backporch = 7;
  264. params->dsi.vertical_frontporch = 7;
  265. params->dsi.vertical_active_line = FRAME_HEIGHT;
  266. params->dsi.horizontal_sync_active = 78;
  267. params->dsi.horizontal_backporch = 78;
  268. params->dsi.horizontal_frontporch = 78;
  269. params->dsi.horizontal_active_pixel = FRAME_WIDTH;
  270. params->dsi.horizontal_blanking_pixel = 60;
  271. #endif
  272. // Bit rate calculation
  273. params->dsi.pll_div1=1; // div1=0,1,2,3;div1_real=1,2,4,4 ----0: 546Mbps 1:273Mbps
  274. params->dsi.pll_div2=1; // div2=0,1,2,3;div1_real=1,2,4,4
  275. params->dsi.fbk_div =30; // fref=26MHz, fvco=fref*(fbk_div+1)*2/(div1_real*div2_real)
  276. }
  277. static void lcm_init(void)
  278. {
  279. //power on
  280. lcm_util.set_gpio_mode(GPIO20, GPIO_MODE_00);
  281. lcm_util.set_gpio_dir(GPIO20, GPIO_DIR_OUT);
  282. lcm_util.set_gpio_out(GPIO20, GPIO_OUT_ONE);
  283. MDELAY(20);
  284. SET_RESET_PIN(1);
  285. MDELAY(15);
  286. SET_RESET_PIN(0);
  287. MDELAY(5);
  288. SET_RESET_PIN(1);
  289. MDELAY(20);
  290. push_table(lcm_initialization_setting, sizeof(lcm_initialization_setting) / sizeof(struct LCM_setting_table), 1);
  291. }
  292. static void lcm_suspend(void)
  293. {
  294. #if 0
  295. push_table(lcm_deep_sleep_mode_in_setting, sizeof(lcm_deep_sleep_mode_in_setting) / sizeof(struct LCM_setting_table), 1);
  296. MDELAY(20);
  297. SET_RESET_PIN(1);
  298. MDELAY(15);
  299. SET_RESET_PIN(0);
  300. MDELAY(5);
  301. SET_RESET_PIN(1);
  302. MDELAY(20);
  303. #if defined(BUILD_LK)
  304. upmu_set_rg_vgp5_en(0);
  305. #else
  306. hwPowerDown(MT65XX_POWER_LDO_VGP5, "Lance_LCM");
  307. #endif
  308. #else
  309. SET_RESET_PIN(1);
  310. MDELAY(10);
  311. SET_RESET_PIN(0);
  312. MDELAY(10);
  313. SET_RESET_PIN(1); // fix me
  314. MDELAY(10);
  315. #endif
  316. //set power off
  317. lcm_util.set_gpio_mode(GPIO20, GPIO_MODE_00);
  318. lcm_util.set_gpio_dir(GPIO20, GPIO_DIR_OUT);
  319. lcm_util.set_gpio_out(GPIO20, GPIO_OUT_ZERO);
  320. }
  321. static void lcm_resume(void)
  322. {
  323. lcm_init();
  324. }
  325. static void lcm_update(unsigned int x, unsigned int y,
  326. unsigned int width, unsigned int height)
  327. {
  328. unsigned int x0 = x;
  329. unsigned int y0 = y;
  330. unsigned int x1 = x0 + width - 1;
  331. unsigned int y1 = y0 + height - 1;
  332. unsigned char x0_MSB = ((x0>>8)&0xFF);
  333. unsigned char x0_LSB = (x0&0xFF);
  334. unsigned char x1_MSB = ((x1>>8)&0xFF);
  335. unsigned char x1_LSB = (x1&0xFF);
  336. unsigned char y0_MSB = ((y0>>8)&0xFF);
  337. unsigned char y0_LSB = (y0&0xFF);
  338. unsigned char y1_MSB = ((y1>>8)&0xFF);
  339. unsigned char y1_LSB = (y1&0xFF);
  340. unsigned int data_array[16];
  341. data_array[0]= 0x00053902;
  342. data_array[1]= (x1_MSB<<24)|(x0_LSB<<16)|(x0_MSB<<8)|0x2a;
  343. data_array[2]= (x1_LSB);
  344. dsi_set_cmdq(data_array, 3, 1);
  345. data_array[0]= 0x00053902;
  346. data_array[1]= (y1_MSB<<24)|(y0_LSB<<16)|(y0_MSB<<8)|0x2b;
  347. data_array[2]= (y1_LSB);
  348. dsi_set_cmdq(data_array, 3, 1);
  349. data_array[0]= 0x00290508; //HW bug, so need send one HS packet
  350. dsi_set_cmdq(data_array, 1, 1);
  351. data_array[0]= 0x002c3909;
  352. dsi_set_cmdq(data_array, 1, 0);
  353. }
  354. static void lcm_setbacklight(unsigned int level)
  355. {
  356. unsigned int default_level = 145;
  357. unsigned int mapped_level = 0;
  358. //for LGE backlight IC mapping table
  359. if (level > 255)
  360. level = 255;
  361. if (level >0)
  362. mapped_level = default_level+(level)*(255-default_level)/(255);
  363. else
  364. mapped_level=0;
  365. // Refresh value of backlight level.
  366. lcm_backlight_level_setting[0].para_list[0] = mapped_level;
  367. push_table(lcm_backlight_level_setting, sizeof(lcm_backlight_level_setting) / sizeof(struct LCM_setting_table), 1);
  368. }
  369. static void lcm_setpwm(unsigned int divider)
  370. {
  371. // TBD
  372. }
  373. static unsigned int lcm_getpwm(unsigned int divider)
  374. {
  375. // ref freq = 15MHz, B0h setting 0x80, so 80.6% * freq is pwm_clk;
  376. // pwm_clk / 255 / 2(lcm_setpwm() 6th params) = pwm_duration = 23706
  377. unsigned int pwm_clk = 23706 / (1<<divider);
  378. return pwm_clk;
  379. }
  380. LCM_DRIVER RX_498HX_615B_lcm_drv = {
  381. .name = "RX_498HX_615B",
  382. .set_util_funcs = lcm_set_util_funcs,
  383. .get_params = lcm_get_params,
  384. .init = lcm_init,
  385. .suspend = lcm_suspend,
  386. .resume = lcm_resume,
  387. #if (LCM_DSI_CMD_MODE)
  388. .set_backlight = lcm_setbacklight,
  389. .update = lcm_update,
  390. #endif
  391. };