st7789v.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /*
  2. * drivers/video/fbdev/sunxi/disp2/disp/lcd/st7789v/st7789v.c
  3. *
  4. * Copyright (c) 2007-2018 Allwinnertech Co., Ltd.
  5. * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. [lcd0]
  17. lcd_used = 1
  18. lcd_driver_name = "st7789v"
  19. lcd_x = 240
  20. lcd_y = 320
  21. lcd_width = 108
  22. lcd_height = 64
  23. lcd_dclk_freq = 19
  24. lcd_pwm_used = 1
  25. lcd_pwm_ch = 8
  26. lcd_pwm_freq = 50000
  27. lcd_pwm_pol = 0
  28. lcd_pwm_max_limit = 255
  29. lcd_hbp = 120
  30. ;10 + 20 + 10 + 240*3 = 760 real set 1000
  31. lcd_ht = 850
  32. lcd_hspw = 2
  33. lcd_vbp = 13
  34. lcd_vt = 373
  35. lcd_vspw = 2
  36. lcd_frm = 1
  37. lcd_if = 0
  38. lcd_hv_if = 8
  39. lcd_hv_clk_phase = 0
  40. lcd_hv_sync_polarity = 0
  41. lcd_hv_srgb_seq = 0
  42. lcd_io_phase = 0x0000
  43. lcd_gamma_en = 0
  44. lcd_bright_curve_en = 1
  45. lcd_cmap_en = 0
  46. lcd_rb_swap = 0
  47. deu_mode = 0
  48. lcdgamma4iep = 22
  49. smart_color = 90
  50. ;lcd_bl_en = port:PB03<1><0><default><1>
  51. lcd_power = "vcc-lcd"
  52. lcd_pin_power = "vcc-pd"
  53. ;reset
  54. lcd_gpio_0 = port:PD09<1><0><default><1>
  55. ;cs
  56. lcd_gpio_1 = port:PD10<1><0><default><0>
  57. ;sda
  58. lcd_gpio_2 = port:PD13<1><0><default><0>
  59. ;sck
  60. lcd_gpio_3 = port:PD12<1><0><default><0>
  61. lcdd5 = port:PD03<2><0><2><default>
  62. lcdd6 = port:PD04<2><0><2><default>
  63. lcdd7 = port:PD05<2><0><2><default>
  64. lcdd10 = port:PD06<2><0><2><default>
  65. lcdd11 = port:PD07<2><0><2><default>
  66. lcdd12 = port:PD08<2><0><2><default>
  67. lcdclk = port:PD18<2><0><3><default>
  68. lcdde = port:PD19<2><0><3><default>
  69. lcdhsync = port:PD20<2><0><3><default>
  70. lcdvsync = port:PD21<2><0><3><default>
  71. [lcd0_suspend]
  72. lcdd5 = port:PD03<7><0><2><default>
  73. lcdd6 = port:PD04<7><0><2><default>
  74. lcdd7 = port:PD05<7><0><2><default>
  75. lcdd10 = port:PD06<7><0><2><default>
  76. lcdd11 = port:PD07<7><0><2><default>
  77. lcdd12 = port:PD08<7><0><2><default>
  78. lcdclk = port:PD18<7><0><3><default>
  79. lcdde = port:PD19<7><0><3><default>
  80. lcdhsync = port:PD20<7><0><3><default>
  81. lcdvsync = port:PD21<7><0><3><default>
  82. */
  83. #include "st7789v.h"
  84. #define spi_scl_1 sunxi_lcd_gpio_set_value(0, 3, 1)
  85. #define spi_scl_0 sunxi_lcd_gpio_set_value(0, 3, 0)
  86. #define spi_sdi_1 sunxi_lcd_gpio_set_value(0, 2, 1)
  87. #define spi_sdi_0 sunxi_lcd_gpio_set_value(0, 2, 0)
  88. #define spi_cs_1 sunxi_lcd_gpio_set_value(0, 1, 1)
  89. #define spi_cs_0 sunxi_lcd_gpio_set_value(0, 1, 0)
  90. static void lcd_panel_st7789v_init(void);
  91. static void LCD_power_on(u32 sel);
  92. static void LCD_power_off(u32 sel);
  93. static void LCD_bl_open(u32 sel);
  94. static void LCD_bl_close(u32 sel);
  95. static void LCD_panel_init(u32 sel);
  96. static void LCD_panel_exit(u32 sel);
  97. static void LCD_cfg_panel_info(struct panel_extend_para *info)
  98. {
  99. u32 i = 0, j = 0;
  100. u32 items;
  101. u8 lcd_gamma_tbl[][2] = {
  102. /* {input value, corrected value} */
  103. {0, 0}, {15, 15}, {30, 30}, {45, 45}, {60, 60},
  104. {75, 75}, {90, 90}, {105, 105}, {120, 120}, {135, 135},
  105. {150, 150}, {165, 165}, {180, 180}, {195, 195}, {210, 210},
  106. {225, 225}, {240, 240}, {255, 255},
  107. };
  108. u32 lcd_cmap_tbl[2][3][4] = {
  109. {
  110. {LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3},
  111. {LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3},
  112. {LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3},
  113. },
  114. {
  115. {LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0},
  116. {LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0},
  117. {LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0},
  118. },
  119. };
  120. items = sizeof(lcd_gamma_tbl) / 2;
  121. for (i = 0; i < items - 1; i++) {
  122. u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0];
  123. for (j = 0; j < num; j++) {
  124. u32 value = 0;
  125. value =
  126. lcd_gamma_tbl[i][1] +
  127. ((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1]) *
  128. j) /
  129. num;
  130. info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
  131. (value << 16) + (value << 8) + value;
  132. }
  133. }
  134. info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) +
  135. (lcd_gamma_tbl[items - 1][1] << 8) +
  136. lcd_gamma_tbl[items - 1][1];
  137. memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
  138. }
  139. static s32 LCD_open_flow(u32 sel)
  140. {
  141. /* open lcd power, and delay 50ms */
  142. LCD_OPEN_FUNC(sel, LCD_power_on, 200);
  143. /* open lcd power, than delay 200ms */
  144. LCD_OPEN_FUNC(sel, LCD_panel_init, 200);
  145. /* open lcd controller, and delay 100ms */
  146. LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 150);
  147. /* open lcd backlight, and delay 0ms */
  148. LCD_OPEN_FUNC(sel, LCD_bl_open, 0);
  149. return 0;
  150. }
  151. static s32 LCD_close_flow(u32 sel)
  152. {
  153. /* close lcd backlight, and delay 0ms */
  154. LCD_CLOSE_FUNC(sel, LCD_bl_close, 50);
  155. /* close lcd controller, and delay 0ms */
  156. LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 10);
  157. /* open lcd power, than delay 200ms */
  158. LCD_CLOSE_FUNC(sel, LCD_panel_exit, 10);
  159. /* close lcd power, and delay 500ms */
  160. LCD_CLOSE_FUNC(sel, LCD_power_off, 10);
  161. return 0;
  162. }
  163. static void LCD_power_on(u32 sel)
  164. {
  165. /* config lcd_power pin to open lcd power0 */
  166. sunxi_lcd_power_enable(sel, 0);
  167. /* pwr_en, active low */
  168. sunxi_lcd_gpio_set_value(sel, 3, 0);
  169. sunxi_lcd_pin_cfg(sel, 1);
  170. }
  171. static void LCD_power_off(u32 sel)
  172. {
  173. sunxi_lcd_pin_cfg(sel, 0);
  174. /* pwr_en, active low */
  175. sunxi_lcd_gpio_set_value(sel, 3, 1);
  176. /* config lcd_power pin to close lcd power0 */
  177. sunxi_lcd_power_disable(sel, 0);
  178. }
  179. static void LCD_bl_open(u32 sel)
  180. {
  181. sunxi_lcd_pwm_enable(sel);
  182. /* config lcd_bl_en pin to open lcd backlight */
  183. sunxi_lcd_backlight_enable(sel);
  184. }
  185. static void LCD_bl_close(u32 sel)
  186. {
  187. /* config lcd_bl_en pin to close lcd backlight */
  188. sunxi_lcd_backlight_disable(sel);
  189. sunxi_lcd_pwm_disable(sel);
  190. }
  191. static void st7789v_spi_write_cmd(u8 value)
  192. {
  193. int i;
  194. spi_cs_0;
  195. spi_scl_0;
  196. spi_sdi_0;
  197. spi_scl_1;
  198. spi_scl_0;
  199. for (i = 0; i < 8; i++) {
  200. if (value & 0x80)
  201. spi_sdi_1;
  202. else
  203. spi_sdi_0;
  204. value <<= 1;
  205. spi_scl_1;
  206. spi_scl_0;
  207. }
  208. spi_cs_1;
  209. }
  210. static void st7789v_spi_write_data(u8 value)
  211. {
  212. int i;
  213. spi_cs_0;
  214. spi_scl_0;
  215. spi_sdi_1;
  216. spi_scl_1;
  217. spi_scl_0;
  218. for (i = 0; i < 8; i++) {
  219. if (value & 0x80)
  220. spi_sdi_1;
  221. else
  222. spi_sdi_0;
  223. value <<= 1;
  224. spi_scl_1;
  225. spi_scl_0;
  226. }
  227. spi_cs_1;
  228. }
  229. static void LCD_panel_init(u32 sel)
  230. {
  231. struct disp_panel_para *info =
  232. kmalloc(sizeof(struct disp_panel_para), GFP_KERNEL | __GFP_ZERO);
  233. bsp_disp_get_panel_info(sel, info);
  234. lcd_panel_st7789v_init();
  235. disp_sys_free(info);
  236. return;
  237. }
  238. static void LCD_panel_exit(u32 sel)
  239. {
  240. struct disp_panel_para *info =
  241. kmalloc(sizeof(struct disp_panel_para), GFP_KERNEL | __GFP_ZERO);
  242. st7789v_spi_write_cmd(0x28);
  243. st7789v_spi_write_cmd(0x10);
  244. sunxi_lcd_delay_ms(300);
  245. bsp_disp_get_panel_info(sel, info);
  246. disp_sys_free(info);
  247. return;
  248. }
  249. static void lcd_panel_st7789v_init(void)
  250. {
  251. /* VCI=3.3V */
  252. /************* Reset LCD Driver ****************/
  253. spi_cs_0;
  254. sunxi_lcd_gpio_set_value(0, 0, 1);
  255. sunxi_lcd_delay_ms(50);
  256. sunxi_lcd_gpio_set_value(0, 0, 0);
  257. /* Delay 10ms, This delay time is necessary */
  258. sunxi_lcd_delay_ms(100);
  259. sunxi_lcd_gpio_set_value(0, 0, 1);
  260. /* Delay 120 ms */
  261. sunxi_lcd_delay_ms(150);
  262. st7789v_spi_write_cmd(0x01);
  263. sunxi_lcd_delay_ms(50);
  264. st7789v_spi_write_cmd(0x11);
  265. sunxi_lcd_delay_ms(120);
  266. st7789v_spi_write_cmd(0x36);
  267. st7789v_spi_write_data(0xd4);
  268. st7789v_spi_write_cmd(0x3a);
  269. st7789v_spi_write_data(0x06);
  270. st7789v_spi_write_cmd(0x20);
  271. st7789v_spi_write_cmd(0xb0);
  272. st7789v_spi_write_data(0x11);
  273. st7789v_spi_write_data(0xe4);
  274. st7789v_spi_write_cmd(0xb1);
  275. st7789v_spi_write_data(0xc0);
  276. st7789v_spi_write_data(0x02);
  277. st7789v_spi_write_data(0x04);
  278. st7789v_spi_write_cmd(0xb7);
  279. st7789v_spi_write_data(0x35);
  280. st7789v_spi_write_cmd(0xbb);
  281. st7789v_spi_write_data(0x20);
  282. st7789v_spi_write_cmd(0xC0);
  283. st7789v_spi_write_data(0x21);
  284. st7789v_spi_write_cmd(0xC2);
  285. /* VDV and VRH Command Enable */
  286. st7789v_spi_write_data(0x01);
  287. st7789v_spi_write_cmd(0xC3);
  288. st7789v_spi_write_data(0x0b);
  289. st7789v_spi_write_cmd(0xC4);
  290. st7789v_spi_write_data(0x20);
  291. st7789v_spi_write_cmd(0xc6);
  292. st7789v_spi_write_data(0x0f);
  293. st7789v_spi_write_cmd(0xd0);
  294. st7789v_spi_write_data(0xa4);
  295. st7789v_spi_write_data(0xa1);
  296. st7789v_spi_write_cmd(0xE0);
  297. st7789v_spi_write_data(0x0D);
  298. st7789v_spi_write_data(0x10);
  299. st7789v_spi_write_data(0x13);
  300. st7789v_spi_write_data(0x08);
  301. st7789v_spi_write_data(0x07);
  302. st7789v_spi_write_data(0x04);
  303. st7789v_spi_write_data(0x2C);
  304. st7789v_spi_write_data(0x33);
  305. st7789v_spi_write_data(0x42);
  306. st7789v_spi_write_data(0x29);
  307. st7789v_spi_write_data(0x17);
  308. st7789v_spi_write_data(0x18);
  309. st7789v_spi_write_data(0x24);
  310. st7789v_spi_write_data(0x28);
  311. st7789v_spi_write_cmd(0xE1);
  312. st7789v_spi_write_data(0x0D);
  313. st7789v_spi_write_data(0x10);
  314. st7789v_spi_write_data(0x12);
  315. st7789v_spi_write_data(0x08);
  316. st7789v_spi_write_data(0x07);
  317. st7789v_spi_write_data(0x03);
  318. st7789v_spi_write_data(0x2B);
  319. st7789v_spi_write_data(0x32);
  320. st7789v_spi_write_data(0x40);
  321. st7789v_spi_write_data(0x28);
  322. st7789v_spi_write_data(0x17);
  323. st7789v_spi_write_data(0x16);
  324. st7789v_spi_write_data(0x26);
  325. st7789v_spi_write_data(0x28);
  326. st7789v_spi_write_cmd(0x2a);
  327. st7789v_spi_write_data(0x00);
  328. st7789v_spi_write_data(0x00);
  329. st7789v_spi_write_data(0x00);
  330. st7789v_spi_write_data(0xef);
  331. st7789v_spi_write_cmd(0x2b);
  332. st7789v_spi_write_data(0x00);
  333. st7789v_spi_write_data(0x00);
  334. st7789v_spi_write_data(0x01);
  335. st7789v_spi_write_data(0x3f);
  336. /* Exit Sleep */
  337. st7789v_spi_write_cmd(0x21);
  338. sunxi_lcd_delay_ms(100);
  339. st7789v_spi_write_cmd(0x11);
  340. sunxi_lcd_delay_ms(50);
  341. st7789v_spi_write_cmd(0x29);
  342. sunxi_lcd_delay_ms(50);
  343. }
  344. /* sel: 0:lcd0; 1:lcd1 */
  345. static s32 LCD_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3)
  346. {
  347. return 0;
  348. }
  349. struct __lcd_panel st7789v_panel = {
  350. /* panel driver name, must mach the name of lcd_drv_name in sys_config.fex
  351. */
  352. .name = "st7789v",
  353. .func = {
  354. .cfg_panel_info = LCD_cfg_panel_info,
  355. .cfg_open_flow = LCD_open_flow,
  356. .cfg_close_flow = LCD_close_flow,
  357. .lcd_user_defined_func = LCD_user_defined_func,
  358. },
  359. };