mipi_truly.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include "msm_fb.h"
  14. #include "mipi_dsi.h"
  15. #include "mipi_truly.h"
  16. static struct msm_panel_common_pdata *mipi_truly_pdata;
  17. static struct dsi_buf truly_tx_buf;
  18. static struct dsi_buf truly_rx_buf;
  19. #define TRULY_CMD_DELAY 0
  20. #define TRULY_SLEEP_OFF_DELAY 150
  21. #define TRULY_DISPLAY_ON_DELAY 150
  22. #define GPIO_TRULY_LCD_RESET 129
  23. static int prev_bl = 17;
  24. static char extend_cmd_enable[4] = {0xB9, 0xFF, 0x83, 0x69};
  25. static char display_setting[16] = {
  26. 0xB2, 0x00, 0x23, 0x62,
  27. 0x62, 0x70, 0x00, 0xFF,
  28. 0x00, 0x00, 0x00, 0x00,
  29. 0x03, 0x03, 0x00, 0x01,
  30. };
  31. static char wave_cycle_setting[6] = {0xB4, 0x00, 0x1D, 0x5F, 0x0E, 0x06};
  32. static char gip_setting[27] = {
  33. 0xD5, 0x00, 0x04, 0x03,
  34. 0x00, 0x01, 0x05, 0x1C,
  35. 0x70, 0x01, 0x03, 0x00,
  36. 0x00, 0x40, 0x06, 0x51,
  37. 0x07, 0x00, 0x00, 0x41,
  38. 0x06, 0x50, 0x07, 0x07,
  39. 0x0F, 0x04, 0x00,
  40. };
  41. static char power_setting[20] = {
  42. 0xB1, 0x01, 0x00, 0x34,
  43. 0x06, 0x00, 0x0F, 0x0F,
  44. 0x2A, 0x32, 0x3F, 0x3F,
  45. 0x07, 0x3A, 0x01, 0xE6,
  46. 0xE6, 0xE6, 0xE6, 0xE6,
  47. };
  48. static char vcom_setting[3] = {0xB6, 0x56, 0x56};
  49. static char pannel_setting[2] = {0xCC, 0x02};
  50. static char gamma_setting[35] = {
  51. 0xE0, 0x00, 0x1D, 0x22,
  52. 0x38, 0x3D, 0x3F, 0x2E,
  53. 0x4A, 0x06, 0x0D, 0x0F,
  54. 0x13, 0x15, 0x13, 0x16,
  55. 0x10, 0x19, 0x00, 0x1D,
  56. 0x22, 0x38, 0x3D, 0x3F,
  57. 0x2E, 0x4A, 0x06, 0x0D,
  58. 0x0F, 0x13, 0x15, 0x13,
  59. 0x16, 0x10, 0x19,
  60. };
  61. static char mipi_setting[14] = {
  62. 0xBA, 0x00, 0xA0, 0xC6,
  63. 0x00, 0x0A, 0x00, 0x10,
  64. 0x30, 0x6F, 0x02, 0x11,
  65. 0x18, 0x40,
  66. };
  67. static char exit_sleep[2] = {0x11, 0x00};
  68. static char display_on[2] = {0x29, 0x00};
  69. static char display_off[2] = {0x28, 0x00};
  70. static char enter_sleep[2] = {0x10, 0x00};
  71. static struct dsi_cmd_desc truly_display_off_cmds[] = {
  72. {DTYPE_DCS_WRITE, 1, 0, 0, 10, sizeof(display_off), display_off},
  73. {DTYPE_DCS_WRITE, 1, 0, 0, 120, sizeof(enter_sleep), enter_sleep}
  74. };
  75. static struct dsi_cmd_desc truly_display_on_cmds[] = {
  76. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  77. sizeof(extend_cmd_enable), extend_cmd_enable},
  78. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  79. sizeof(display_setting), display_setting},
  80. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  81. sizeof(wave_cycle_setting), wave_cycle_setting},
  82. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  83. sizeof(gip_setting), gip_setting},
  84. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  85. sizeof(power_setting), power_setting},
  86. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  87. sizeof(vcom_setting), vcom_setting},
  88. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  89. sizeof(pannel_setting), pannel_setting},
  90. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  91. sizeof(gamma_setting), gamma_setting},
  92. {DTYPE_GEN_LWRITE, 1, 0, 0, TRULY_CMD_DELAY,
  93. sizeof(mipi_setting), mipi_setting},
  94. {DTYPE_DCS_WRITE, 1, 0, 0, TRULY_SLEEP_OFF_DELAY,
  95. sizeof(exit_sleep), exit_sleep},
  96. {DTYPE_DCS_WRITE, 1, 0, 0, TRULY_DISPLAY_ON_DELAY,
  97. sizeof(display_on), display_on},
  98. };
  99. static int mipi_truly_lcd_on(struct platform_device *pdev)
  100. {
  101. struct msm_fb_data_type *mfd;
  102. struct dcs_cmd_req cmdreq;
  103. mfd = platform_get_drvdata(pdev);
  104. if (!mfd)
  105. return -ENODEV;
  106. if (mfd->key != MFD_KEY)
  107. return -EINVAL;
  108. msleep(20);
  109. memset(&cmdreq, 0, sizeof(cmdreq));
  110. cmdreq.cmds = truly_display_on_cmds;
  111. cmdreq.cmds_cnt = ARRAY_SIZE(truly_display_on_cmds);
  112. cmdreq.flags = CMD_REQ_COMMIT;
  113. cmdreq.rlen = 0;
  114. cmdreq.cb = NULL;
  115. mipi_dsi_cmdlist_put(&cmdreq);
  116. return 0;
  117. }
  118. static int mipi_truly_lcd_off(struct platform_device *pdev)
  119. {
  120. struct msm_fb_data_type *mfd;
  121. struct dcs_cmd_req cmdreq;
  122. mfd = platform_get_drvdata(pdev);
  123. if (!mfd)
  124. return -ENODEV;
  125. if (mfd->key != MFD_KEY)
  126. return -EINVAL;
  127. memset(&cmdreq, 0, sizeof(cmdreq));
  128. cmdreq.cmds = truly_display_off_cmds;
  129. cmdreq.cmds_cnt = ARRAY_SIZE(truly_display_off_cmds);
  130. cmdreq.flags = CMD_REQ_COMMIT;
  131. cmdreq.rlen = 0;
  132. cmdreq.cb = NULL;
  133. mipi_dsi_cmdlist_put(&cmdreq);
  134. return 0;
  135. }
  136. #define BL_LEVEL 17
  137. static void mipi_truly_set_backlight(struct msm_fb_data_type *mfd)
  138. {
  139. int step = 0, i = 0;
  140. int bl_level = mfd->bl_level;
  141. /* real backlight level, 1 - max, 16 - min, 17 - off */
  142. bl_level = BL_LEVEL - bl_level;
  143. if (bl_level > prev_bl) {
  144. step = bl_level - prev_bl;
  145. if (bl_level == BL_LEVEL)
  146. step--;
  147. } else if (bl_level < prev_bl) {
  148. step = bl_level + 16 - prev_bl;
  149. } else {
  150. pr_debug("%s: no change\n", __func__);
  151. return;
  152. }
  153. if (bl_level == BL_LEVEL) {
  154. /* turn off backlight */
  155. mipi_truly_pdata->pmic_backlight(0);
  156. } else {
  157. if (prev_bl == BL_LEVEL) {
  158. /* turn on backlight */
  159. mipi_truly_pdata->pmic_backlight(1);
  160. udelay(30);
  161. }
  162. /* adjust backlight level */
  163. for (i = 0; i < step; i++) {
  164. mipi_truly_pdata->pmic_backlight(0);
  165. udelay(1);
  166. mipi_truly_pdata->pmic_backlight(1);
  167. udelay(1);
  168. }
  169. }
  170. msleep(20);
  171. prev_bl = bl_level;
  172. return;
  173. }
  174. static int __devinit mipi_truly_lcd_probe(struct platform_device *pdev)
  175. {
  176. if (pdev->id == 0) {
  177. mipi_truly_pdata = pdev->dev.platform_data;
  178. return 0;
  179. }
  180. msm_fb_add_device(pdev);
  181. return 0;
  182. }
  183. static struct platform_driver this_driver = {
  184. .probe = mipi_truly_lcd_probe,
  185. .driver = {
  186. .name = "mipi_truly",
  187. },
  188. };
  189. static struct msm_fb_panel_data truly_panel_data = {
  190. .on = mipi_truly_lcd_on,
  191. .off = mipi_truly_lcd_off,
  192. .set_backlight = mipi_truly_set_backlight,
  193. };
  194. static int ch_used[3];
  195. int mipi_truly_device_register(struct msm_panel_info *pinfo,
  196. u32 channel, u32 panel)
  197. {
  198. struct platform_device *pdev = NULL;
  199. int ret;
  200. if ((channel >= 3) || ch_used[channel])
  201. return -ENODEV;
  202. ch_used[channel] = TRUE;
  203. pdev = platform_device_alloc("mipi_truly", (panel << 8)|channel);
  204. if (!pdev)
  205. return -ENOMEM;
  206. truly_panel_data.panel_info = *pinfo;
  207. ret = platform_device_add_data(pdev, &truly_panel_data,
  208. sizeof(truly_panel_data));
  209. if (ret) {
  210. pr_err("%s: platform_device_add_data failed!\n", __func__);
  211. goto err_device_put;
  212. }
  213. ret = platform_device_add(pdev);
  214. if (ret) {
  215. pr_err("%s: platform_device_register failed!\n", __func__);
  216. goto err_device_put;
  217. }
  218. return 0;
  219. err_device_put:
  220. platform_device_put(pdev);
  221. return ret;
  222. }
  223. static int __init mipi_truly_lcd_init(void)
  224. {
  225. mipi_dsi_buf_alloc(&truly_tx_buf, DSI_BUF_SIZE);
  226. mipi_dsi_buf_alloc(&truly_rx_buf, DSI_BUF_SIZE);
  227. return platform_driver_register(&this_driver);
  228. }
  229. module_init(mipi_truly_lcd_init);