tpo_tj032md01bw.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * linux/drivers/video/mmp/panel/tpo_tj032md01bw.c
  3. * active panel using spi interface to do init
  4. *
  5. * Copyright (C) 2012 Marvell Technology Group Ltd.
  6. * Authors: Guoqing Li <ligq@marvell.com>
  7. * Lisa Du <cldu@marvell.com>
  8. * Zhou Zhu <zzhu3@marvell.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2 of the License, or (at your
  13. * option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  18. * more details.
  19. *
  20. * You should have received a copy of the GNU General Public License along with
  21. * this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. */
  24. #include <linux/module.h>
  25. #include <linux/moduleparam.h>
  26. #include <linux/kernel.h>
  27. #include <linux/errno.h>
  28. #include <linux/string.h>
  29. #include <linux/delay.h>
  30. #include <linux/platform_device.h>
  31. #include <linux/err.h>
  32. #include <linux/spi/spi.h>
  33. #include <video/mmp_disp.h>
  34. static u16 init[] = {
  35. 0x0801,
  36. 0x0800,
  37. 0x0200,
  38. 0x0304,
  39. 0x040e,
  40. 0x0903,
  41. 0x0b18,
  42. 0x0c53,
  43. 0x0d01,
  44. 0x0ee0,
  45. 0x0f01,
  46. 0x1058,
  47. 0x201e,
  48. 0x210a,
  49. 0x220a,
  50. 0x231e,
  51. 0x2400,
  52. 0x2532,
  53. 0x2600,
  54. 0x27ac,
  55. 0x2904,
  56. 0x2aa2,
  57. 0x2b45,
  58. 0x2c45,
  59. 0x2d15,
  60. 0x2e5a,
  61. 0x2fff,
  62. 0x306b,
  63. 0x310d,
  64. 0x3248,
  65. 0x3382,
  66. 0x34bd,
  67. 0x35e7,
  68. 0x3618,
  69. 0x3794,
  70. 0x3801,
  71. 0x395d,
  72. 0x3aae,
  73. 0x3bff,
  74. 0x07c9,
  75. };
  76. static u16 poweroff[] = {
  77. 0x07d9,
  78. };
  79. struct tpohvga_plat_data {
  80. void (*plat_onoff)(int status);
  81. struct spi_device *spi;
  82. };
  83. static void tpohvga_onoff(struct mmp_panel *panel, int status)
  84. {
  85. struct tpohvga_plat_data *plat = panel->plat_data;
  86. int ret;
  87. if (status) {
  88. plat->plat_onoff(1);
  89. ret = spi_write(plat->spi, init, sizeof(init));
  90. if (ret < 0)
  91. dev_warn(panel->dev, "init cmd failed(%d)\n", ret);
  92. } else {
  93. ret = spi_write(plat->spi, poweroff, sizeof(poweroff));
  94. if (ret < 0)
  95. dev_warn(panel->dev, "poweroff cmd failed(%d)\n", ret);
  96. plat->plat_onoff(0);
  97. }
  98. }
  99. static struct mmp_mode mmp_modes_tpohvga[] = {
  100. [0] = {
  101. .pixclock_freq = 10394400,
  102. .refresh = 60,
  103. .xres = 320,
  104. .yres = 480,
  105. .hsync_len = 10,
  106. .left_margin = 15,
  107. .right_margin = 10,
  108. .vsync_len = 2,
  109. .upper_margin = 4,
  110. .lower_margin = 2,
  111. .invert_pixclock = 1,
  112. .pix_fmt_out = PIXFMT_RGB565,
  113. },
  114. };
  115. static int tpohvga_get_modelist(struct mmp_panel *panel,
  116. struct mmp_mode **modelist)
  117. {
  118. *modelist = mmp_modes_tpohvga;
  119. return 1;
  120. }
  121. static struct mmp_panel panel_tpohvga = {
  122. .name = "tpohvga",
  123. .panel_type = PANELTYPE_ACTIVE,
  124. .get_modelist = tpohvga_get_modelist,
  125. .set_onoff = tpohvga_onoff,
  126. };
  127. static int tpohvga_probe(struct spi_device *spi)
  128. {
  129. struct mmp_mach_panel_info *mi;
  130. int ret;
  131. struct tpohvga_plat_data *plat_data;
  132. /* get configs from platform data */
  133. mi = spi->dev.platform_data;
  134. if (mi == NULL) {
  135. dev_err(&spi->dev, "%s: no platform data defined\n", __func__);
  136. return -EINVAL;
  137. }
  138. /* setup spi related info */
  139. spi->bits_per_word = 16;
  140. ret = spi_setup(spi);
  141. if (ret < 0) {
  142. dev_err(&spi->dev, "spi setup failed %d", ret);
  143. return ret;
  144. }
  145. plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL);
  146. if (plat_data == NULL)
  147. return -ENOMEM;
  148. plat_data->spi = spi;
  149. plat_data->plat_onoff = mi->plat_set_onoff;
  150. panel_tpohvga.plat_data = plat_data;
  151. panel_tpohvga.plat_path_name = mi->plat_path_name;
  152. panel_tpohvga.dev = &spi->dev;
  153. mmp_register_panel(&panel_tpohvga);
  154. return 0;
  155. }
  156. static struct spi_driver panel_tpohvga_driver = {
  157. .driver = {
  158. .name = "tpo-hvga",
  159. .owner = THIS_MODULE,
  160. },
  161. .probe = tpohvga_probe,
  162. };
  163. module_spi_driver(panel_tpohvga_driver);
  164. MODULE_AUTHOR("Lisa Du<cldu@marvell.com>");
  165. MODULE_DESCRIPTION("Panel driver for tpohvga");
  166. MODULE_LICENSE("GPL");