lcdc_sharp_wvga_pt.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /* Copyright (c) 2009-2010, 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 <linux/delay.h>
  14. #include <linux/pwm.h>
  15. #ifdef CONFIG_PMIC8058_PWM
  16. #include <linux/mfd/pmic8058.h>
  17. #include <linux/pmic8058-pwm.h>
  18. #endif
  19. #ifdef CONFIG_SPI_QSD
  20. #include <linux/spi/spi.h>
  21. #endif
  22. #include <mach/gpio.h>
  23. #include "msm_fb.h"
  24. #ifdef CONFIG_SPI_QSD
  25. #define LCDC_SHARP_SPI_DEVICE_NAME "lcdc_sharp_ls038y7dx01"
  26. static struct spi_device *lcdc_spi_client;
  27. #endif
  28. static int lcdc_sharp_panel_off(struct platform_device *pdev);
  29. #define BL_MAX 16
  30. #ifdef CONFIG_PMIC8058_PWM
  31. static struct pwm_device *bl_pwm;
  32. #define PWM_PERIOD 1000 /* us, period of 1Khz */
  33. #define DUTY_LEVEL (PWM_PERIOD / BL_MAX)
  34. #endif
  35. #ifndef CONFIG_SPI_QSD
  36. static int spi_cs;
  37. static int spi_sclk;
  38. static int spi_mosi;
  39. static int spi_miso;
  40. static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
  41. (1 << 6),
  42. (1 << 5),
  43. (1 << 4),
  44. (1 << 3),
  45. (1 << 2),
  46. (1 << 1),
  47. (1 << 0) /* LSB */
  48. };
  49. #endif
  50. struct sharp_state_type {
  51. boolean disp_initialized;
  52. boolean display_on;
  53. boolean disp_powered_up;
  54. };
  55. struct sharp_spi_data {
  56. u8 addr;
  57. u8 data;
  58. };
  59. static struct sharp_spi_data init_sequence[] = {
  60. { 15, 0x01 },
  61. { 5, 0x01 },
  62. { 7, 0x10 },
  63. { 9, 0x1E },
  64. { 10, 0x04 },
  65. { 17, 0xFF },
  66. { 21, 0x8A },
  67. { 22, 0x00 },
  68. { 23, 0x82 },
  69. { 24, 0x24 },
  70. { 25, 0x22 },
  71. { 26, 0x6D },
  72. { 27, 0xEB },
  73. { 28, 0xB9 },
  74. { 29, 0x3A },
  75. { 49, 0x1A },
  76. { 50, 0x16 },
  77. { 51, 0x05 },
  78. { 55, 0x7F },
  79. { 56, 0x15 },
  80. { 57, 0x7B },
  81. { 60, 0x05 },
  82. { 61, 0x0C },
  83. { 62, 0x80 },
  84. { 63, 0x00 },
  85. { 92, 0x90 },
  86. { 97, 0x01 },
  87. { 98, 0xFF },
  88. { 113, 0x11 },
  89. { 114, 0x02 },
  90. { 115, 0x08 },
  91. { 123, 0xAB },
  92. { 124, 0x04 },
  93. { 6, 0x02 },
  94. { 133, 0x00 },
  95. { 134, 0xFE },
  96. { 135, 0x22 },
  97. { 136, 0x0B },
  98. { 137, 0xFF },
  99. { 138, 0x0F },
  100. { 139, 0x00 },
  101. { 140, 0xFE },
  102. { 141, 0x22 },
  103. { 142, 0x0B },
  104. { 143, 0xFF },
  105. { 144, 0x0F },
  106. { 145, 0x00 },
  107. { 146, 0xFE },
  108. { 147, 0x22 },
  109. { 148, 0x0B },
  110. { 149, 0xFF },
  111. { 150, 0x0F },
  112. { 202, 0x30 },
  113. { 30, 0x01 },
  114. { 4, 0x01 },
  115. { 31, 0x41 },
  116. };
  117. static struct sharp_state_type sharp_state = { 0 };
  118. static struct msm_panel_common_pdata *lcdc_sharp_pdata;
  119. #ifndef CONFIG_SPI_QSD
  120. static void sharp_spi_write_byte(u8 val)
  121. {
  122. int i;
  123. /* Clock should be Low before entering */
  124. for (i = 0; i < 8; i++) {
  125. /* #1: Drive the Data (High or Low) */
  126. if (val & bit_shift[i])
  127. gpio_set_value(spi_mosi, 1);
  128. else
  129. gpio_set_value(spi_mosi, 0);
  130. /* #2: Drive the Clk High and then Low */
  131. gpio_set_value(spi_sclk, 1);
  132. gpio_set_value(spi_sclk, 0);
  133. }
  134. }
  135. #endif
  136. static int serigo(u8 reg, u8 data)
  137. {
  138. #ifdef CONFIG_SPI_QSD
  139. char tx_buf[2];
  140. int rc;
  141. struct spi_message m;
  142. struct spi_transfer t;
  143. if (!lcdc_spi_client) {
  144. printk(KERN_ERR "%s lcdc_spi_client is NULL\n", __func__);
  145. return -EINVAL;
  146. }
  147. memset(&t, 0, sizeof t);
  148. t.tx_buf = tx_buf;
  149. spi_setup(lcdc_spi_client);
  150. spi_message_init(&m);
  151. spi_message_add_tail(&t, &m);
  152. tx_buf[0] = reg;
  153. tx_buf[1] = data;
  154. t.rx_buf = NULL;
  155. t.len = 2;
  156. rc = spi_sync(lcdc_spi_client, &m);
  157. return rc;
  158. #else
  159. /* Enable the Chip Select - low */
  160. gpio_set_value(spi_cs, 0);
  161. udelay(1);
  162. /* Transmit register address first, then data */
  163. sharp_spi_write_byte(reg);
  164. /* Idle state of MOSI is Low */
  165. gpio_set_value(spi_mosi, 0);
  166. udelay(1);
  167. sharp_spi_write_byte(data);
  168. gpio_set_value(spi_mosi, 0);
  169. gpio_set_value(spi_cs, 1);
  170. return 0;
  171. #endif
  172. }
  173. #ifndef CONFIG_SPI_QSD
  174. static void sharp_spi_init(void)
  175. {
  176. spi_sclk = *(lcdc_sharp_pdata->gpio_num);
  177. spi_cs = *(lcdc_sharp_pdata->gpio_num + 1);
  178. spi_mosi = *(lcdc_sharp_pdata->gpio_num + 2);
  179. spi_miso = *(lcdc_sharp_pdata->gpio_num + 3);
  180. /* Set the output so that we don't disturb the slave device */
  181. gpio_set_value(spi_sclk, 0);
  182. gpio_set_value(spi_mosi, 0);
  183. /* Set the Chip Select deasserted (active low) */
  184. gpio_set_value(spi_cs, 1);
  185. }
  186. #endif
  187. static void sharp_disp_powerup(void)
  188. {
  189. if (!sharp_state.disp_powered_up && !sharp_state.display_on)
  190. sharp_state.disp_powered_up = TRUE;
  191. }
  192. static void sharp_disp_on(void)
  193. {
  194. int i;
  195. if (sharp_state.disp_powered_up && !sharp_state.display_on) {
  196. for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
  197. serigo(init_sequence[i].addr,
  198. init_sequence[i].data);
  199. }
  200. mdelay(10);
  201. serigo(31, 0xC1);
  202. mdelay(10);
  203. serigo(31, 0xD9);
  204. serigo(31, 0xDF);
  205. sharp_state.display_on = TRUE;
  206. }
  207. }
  208. static int lcdc_sharp_panel_on(struct platform_device *pdev)
  209. {
  210. if (!sharp_state.disp_initialized) {
  211. #ifndef CONFIG_SPI_QSD
  212. lcdc_sharp_pdata->panel_config_gpio(1);
  213. sharp_spi_init();
  214. #endif
  215. sharp_disp_powerup();
  216. sharp_disp_on();
  217. sharp_state.disp_initialized = TRUE;
  218. }
  219. return 0;
  220. }
  221. static int lcdc_sharp_panel_off(struct platform_device *pdev)
  222. {
  223. if (sharp_state.disp_powered_up && sharp_state.display_on) {
  224. serigo(4, 0x00);
  225. mdelay(40);
  226. serigo(31, 0xC1);
  227. mdelay(40);
  228. serigo(31, 0x00);
  229. msleep(16);
  230. sharp_state.display_on = FALSE;
  231. sharp_state.disp_initialized = FALSE;
  232. }
  233. return 0;
  234. }
  235. static void lcdc_sharp_panel_set_backlight(struct msm_fb_data_type *mfd)
  236. {
  237. int bl_level;
  238. bl_level = mfd->bl_level;
  239. #ifdef CONFIG_PMIC8058_PWM
  240. if (bl_pwm) {
  241. pwm_config(bl_pwm, DUTY_LEVEL * bl_level, PWM_PERIOD);
  242. pwm_enable(bl_pwm);
  243. }
  244. #endif
  245. }
  246. static int __devinit sharp_probe(struct platform_device *pdev)
  247. {
  248. if (pdev->id == 0) {
  249. lcdc_sharp_pdata = pdev->dev.platform_data;
  250. return 0;
  251. }
  252. #ifdef CONFIG_PMIC8058_PWM
  253. bl_pwm = pwm_request(lcdc_sharp_pdata->gpio, "backlight");
  254. if (bl_pwm == NULL || IS_ERR(bl_pwm)) {
  255. pr_err("%s pwm_request() failed\n", __func__);
  256. bl_pwm = NULL;
  257. }
  258. printk(KERN_INFO "sharp_probe: bl_pwm=%x LPG_chan=%d\n",
  259. (int) bl_pwm, (int)lcdc_sharp_pdata->gpio);
  260. #endif
  261. msm_fb_add_device(pdev);
  262. return 0;
  263. }
  264. #ifdef CONFIG_SPI_QSD
  265. static int __devinit lcdc_sharp_spi_probe(struct spi_device *spi)
  266. {
  267. lcdc_spi_client = spi;
  268. lcdc_spi_client->bits_per_word = 32;
  269. return 0;
  270. }
  271. static int __devexit lcdc_sharp_spi_remove(struct spi_device *spi)
  272. {
  273. lcdc_spi_client = NULL;
  274. return 0;
  275. }
  276. static struct spi_driver lcdc_sharp_spi_driver = {
  277. .driver = {
  278. .name = LCDC_SHARP_SPI_DEVICE_NAME,
  279. .owner = THIS_MODULE,
  280. },
  281. .probe = lcdc_sharp_spi_probe,
  282. .remove = __devexit_p(lcdc_sharp_spi_remove),
  283. };
  284. #endif
  285. static struct platform_driver this_driver = {
  286. .probe = sharp_probe,
  287. .driver = {
  288. .name = "lcdc_sharp_wvga",
  289. },
  290. };
  291. static struct msm_fb_panel_data sharp_panel_data = {
  292. .on = lcdc_sharp_panel_on,
  293. .off = lcdc_sharp_panel_off,
  294. .set_backlight = lcdc_sharp_panel_set_backlight,
  295. };
  296. static struct platform_device this_device = {
  297. .name = "lcdc_sharp_wvga",
  298. .id = 1,
  299. .dev = {
  300. .platform_data = &sharp_panel_data,
  301. }
  302. };
  303. static int __init lcdc_sharp_panel_init(void)
  304. {
  305. int ret;
  306. struct msm_panel_info *pinfo;
  307. #ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
  308. if (msm_fb_detect_client("lcdc_sharp_wvga_pt"))
  309. return 0;
  310. #endif
  311. ret = platform_driver_register(&this_driver);
  312. if (ret)
  313. return ret;
  314. pinfo = &sharp_panel_data.panel_info;
  315. pinfo->xres = 480;
  316. pinfo->yres = 800;
  317. MSM_FB_SINGLE_MODE_PANEL(pinfo);
  318. pinfo->type = LCDC_PANEL;
  319. pinfo->pdest = DISPLAY_1;
  320. pinfo->wait_cycle = 0;
  321. pinfo->bpp = 18;
  322. pinfo->fb_num = 2;
  323. pinfo->clk_rate = 24500000;
  324. pinfo->bl_max = BL_MAX;
  325. pinfo->bl_min = 1;
  326. pinfo->lcdc.h_back_porch = 20;
  327. pinfo->lcdc.h_front_porch = 10;
  328. pinfo->lcdc.h_pulse_width = 10;
  329. pinfo->lcdc.v_back_porch = 2;
  330. pinfo->lcdc.v_front_porch = 2;
  331. pinfo->lcdc.v_pulse_width = 2;
  332. pinfo->lcdc.border_clr = 0;
  333. pinfo->lcdc.underflow_clr = 0xff;
  334. pinfo->lcdc.hsync_skew = 0;
  335. ret = platform_device_register(&this_device);
  336. if (ret) {
  337. printk(KERN_ERR "%s not able to register the device\n",
  338. __func__);
  339. goto fail_driver;
  340. }
  341. #ifdef CONFIG_SPI_QSD
  342. ret = spi_register_driver(&lcdc_sharp_spi_driver);
  343. if (ret) {
  344. printk(KERN_ERR "%s not able to register spi\n", __func__);
  345. goto fail_device;
  346. }
  347. #endif
  348. return ret;
  349. #ifdef CONFIG_SPI_QSD
  350. fail_device:
  351. platform_device_unregister(&this_device);
  352. #endif
  353. fail_driver:
  354. platform_driver_unregister(&this_driver);
  355. return ret;
  356. }
  357. module_init(lcdc_sharp_panel_init);
  358. #ifdef CONFIG_SPI_QSD
  359. static void __exit lcdc_sharp_panel_exit(void)
  360. {
  361. spi_unregister_driver(&lcdc_sharp_spi_driver);
  362. }
  363. module_exit(lcdc_sharp_panel_exit);
  364. #endif