mdss_qpic_panel.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /* Copyright (c) 2013, 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. #include <linux/module.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/of.h>
  15. #include <linux/of_gpio.h>
  16. #include <linux/gpio.h>
  17. #include <linux/qpnp/pin.h>
  18. #include <linux/delay.h>
  19. #include <linux/slab.h>
  20. #include <linux/leds.h>
  21. #include <linux/regulator/consumer.h>
  22. #include <linux/dma-mapping.h>
  23. #include <linux/uaccess.h>
  24. #include <mach/sps.h>
  25. #include "mdss.h"
  26. #include "mdss_panel.h"
  27. #include "mdss_qpic.h"
  28. #include "mdss_qpic_panel.h"
  29. static u32 panel_is_on;
  30. static u32 panel_refresh_rate;
  31. static int (*qpic_panel_on)(void);
  32. static void (*qpic_panel_off)(void);
  33. static int (*qpic_panel_init)(struct platform_device *pdev,
  34. struct device_node *np);
  35. u32 qpic_panel_get_framerate(void)
  36. {
  37. return panel_refresh_rate;
  38. }
  39. u32 qpic_send_panel_cmd(u32 cmd, u32 *val, u32 length)
  40. {
  41. u32 ret;
  42. u32 cmd_index;
  43. u32 size;
  44. u32 buffer[LCDC_INTERNAL_BUFFER_SIZE];
  45. u32 i;
  46. cmd_index = LCDC_EXTRACT_OP_CMD(cmd);
  47. size = LCDC_EXTRACT_OP_SIZE(cmd);
  48. if (size == INV_SIZE)
  49. size = length;
  50. /* short or pixel data commands need not conversion */
  51. if ((cmd == OP_WRITE_MEMORY_CONTINUE) ||
  52. (cmd == OP_WRITE_MEMORY_START)) {
  53. ret = qpic_flush_buffer(cmd_index, size, val, false);
  54. } else {
  55. if (size > LCDC_INTERNAL_BUFFER_SIZE)
  56. size = LCDC_INTERNAL_BUFFER_SIZE;
  57. /* correcting for encoding issues */
  58. for (i = 0; i < size; i += sizeof(u32)) {
  59. buffer[i] = (val[(i>>2)] >> 0) & 0xff;
  60. buffer[i+1] = (val[(i>>2)] >> 8) & 0xff;
  61. buffer[i+2] = (val[(i>>2)] >> 16) & 0xff;
  62. buffer[i+3] = (val[(i>>2)] >> 24) & 0xff;
  63. }
  64. ret = qpic_flush_buffer(cmd_index,
  65. size * sizeof(u32), buffer, true);
  66. }
  67. return ret;
  68. }
  69. u32 qpic_panel_set_cmd_only(u32 command)
  70. {
  71. u32 param;
  72. return qpic_send_panel_cmd(command, &param, 0);
  73. }
  74. /* write a frame of pixels to a MIPI screen */
  75. u32 qpic_send_frame(u32 x_start,
  76. u32 y_start,
  77. u32 x_end,
  78. u32 y_end,
  79. u32 *data,
  80. u32 total_bytes)
  81. {
  82. u32 param;
  83. u32 status;
  84. u32 start_0_7;
  85. u32 end_0_7;
  86. u32 start_8_15;
  87. u32 end_8_15;
  88. /* convert to 16 bit representation */
  89. x_start = x_start & 0xffff;
  90. y_start = y_start & 0xffff;
  91. x_end = x_end & 0xffff;
  92. y_end = y_end & 0xffff;
  93. /* set column/page */
  94. start_0_7 = x_start & 0xff;
  95. end_0_7 = x_end & 0xff;
  96. start_8_15 = (x_start >> 8) & 0xff;
  97. end_8_15 = (x_end >> 8) & 0xff;
  98. param = (start_8_15 << 0) | (start_0_7 << 8) |
  99. (end_8_15 << 16) | (end_0_7 << 24U);
  100. status = qpic_send_panel_cmd(OP_SET_COLUMN_ADDRESS, &param, 0);
  101. if (status) {
  102. pr_err("Failed to set column address");
  103. return status;
  104. }
  105. start_0_7 = y_start & 0xff;
  106. end_0_7 = y_end & 0xff;
  107. start_8_15 = (y_start >> 8) & 0xff;
  108. end_8_15 = (y_end >> 8) & 0xff;
  109. param = (start_8_15 << 0) | (start_0_7 << 8) |
  110. (end_8_15 << 16) | (end_0_7 << 24U);
  111. status = qpic_send_panel_cmd(OP_SET_PAGE_ADDRESS, &param, 0);
  112. if (status) {
  113. pr_err("Failed to set page address");
  114. return status;
  115. }
  116. status = qpic_send_panel_cmd(OP_WRITE_MEMORY_START,
  117. &(data[0]), total_bytes);
  118. if (status) {
  119. pr_err("Failed to start memory write");
  120. return status;
  121. }
  122. return 0;
  123. }
  124. int mdss_qpic_panel_on(struct mdss_panel_data *pdata)
  125. {
  126. int rc = 0;
  127. if (panel_is_on)
  128. return 0;
  129. mdss_qpic_init();
  130. if (qpic_panel_on)
  131. rc = qpic_panel_on();
  132. if (rc)
  133. return rc;
  134. panel_is_on = true;
  135. return 0;
  136. }
  137. int mdss_qpic_panel_off(struct mdss_panel_data *pdata)
  138. {
  139. if (qpic_panel_off)
  140. qpic_panel_off();
  141. panel_is_on = false;
  142. return 0;
  143. }
  144. static int mdss_panel_parse_dt(struct platform_device *pdev,
  145. struct mdss_panel_data *panel_data)
  146. {
  147. struct device_node *np = pdev->dev.of_node;
  148. u32 res[6], tmp;
  149. int rc;
  150. rc = of_property_read_u32_array(np, "qcom,mdss-pan-res", res, 2);
  151. if (rc) {
  152. pr_err("%s:%d, panel resolution not specified\n",
  153. __func__, __LINE__);
  154. return -EINVAL;
  155. }
  156. panel_data->panel_info.xres = (!rc ? res[0] : 240);
  157. panel_data->panel_info.yres = (!rc ? res[1] : 320);
  158. rc = of_property_read_u32(np, "qcom,mdss-pan-bpp", &tmp);
  159. if (rc) {
  160. pr_err("%s:%d, panel bpp not specified\n",
  161. __func__, __LINE__);
  162. return -EINVAL;
  163. }
  164. panel_data->panel_info.bpp = (!rc ? tmp : 24);
  165. of_property_read_u32(np, "qcom,refresh_rate", &panel_refresh_rate);
  166. panel_data->panel_info.type = EBI2_PANEL;
  167. panel_data->panel_info.pdest = DISPLAY_1;
  168. if (qpic_panel_init)
  169. rc = qpic_panel_init(pdev, np);
  170. return rc;
  171. }
  172. static int __devinit mdss_qpic_panel_probe(struct platform_device *pdev)
  173. {
  174. int rc = 0;
  175. static struct mdss_panel_data vendor_pdata;
  176. static const char *panel_name;
  177. pr_debug("%s:%d, debug info id=%d", __func__, __LINE__, pdev->id);
  178. if (!pdev->dev.of_node)
  179. return -ENODEV;
  180. panel_name = of_get_property(pdev->dev.of_node, "label", NULL);
  181. if (!panel_name)
  182. pr_info("%s:%d, panel name not specified\n",
  183. __func__, __LINE__);
  184. else
  185. pr_info("%s: Panel Name = %s\n", __func__, panel_name);
  186. /* select panel according to label */
  187. qpic_panel_init = ili9341_init;
  188. qpic_panel_on = ili9341_on;
  189. qpic_panel_off = ili9341_off;
  190. rc = mdss_panel_parse_dt(pdev, &vendor_pdata);
  191. if (rc)
  192. return rc;
  193. rc = qpic_register_panel(&vendor_pdata);
  194. if (rc)
  195. return rc;
  196. return 0;
  197. }
  198. static const struct of_device_id mdss_qpic_panel_match[] = {
  199. {.compatible = "qcom,mdss-qpic-panel"},
  200. {}
  201. };
  202. static struct platform_driver this_driver = {
  203. .probe = mdss_qpic_panel_probe,
  204. .driver = {
  205. .name = "qpic_panel",
  206. .of_match_table = mdss_qpic_panel_match,
  207. },
  208. };
  209. static int __init mdss_qpic_panel_init(void)
  210. {
  211. return platform_driver_register(&this_driver);
  212. }
  213. MODULE_DEVICE_TABLE(of, mdss_qpic_panel_match);
  214. module_init(mdss_qpic_panel_init);