PageRenderTime 49ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/hrp2/target/ev3_gcc/drivers/lcd/linux/drivers/video/st7586fb.c

https://bitbucket.org/sirokujira/toppershrp2_ev3rt_test
C | 605 lines | 461 code | 105 blank | 39 comment | 35 complexity | 58a2b75295a406a113859bcb55c50136 MD5 | raw file
Possible License(s): GPL-2.0, Apache-2.0
  1. /*
  2. * linux/drivers/video/st7856fb.c -- FB driver for ST7856 display controller
  3. *
  4. * Based on st7735fb.c by Matt Porter
  5. * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
  6. *
  7. * Copyright (C) 2011 Matt Porter <matt@ohporter.com>
  8. * Copyright (C) 2011 Texas Instruments
  9. *
  10. * This file is subject to the terms and conditions of the GNU General Public
  11. * License. See the file COPYING in the main directory of this archive for
  12. * more details.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/kernel.h>
  16. #include <linux/errno.h>
  17. #include <linux/string.h>
  18. #include <linux/mm.h>
  19. #include <linux/vmalloc.h>
  20. #include <linux/slab.h>
  21. #include <linux/init.h>
  22. #include <linux/fb.h>
  23. #include <linux/gpio.h>
  24. #include <linux/spi/spi.h>
  25. #include <linux/delay.h>
  26. #include <linux/uaccess.h>
  27. #include <video/st7586fb.h>
  28. static struct st7586_function st7586_cfg_script[] = {
  29. { ST7586_START, ST7586_START},
  30. { ST7586_CMD, ST7586_ARDCTL},
  31. { ST7586_DATA, 0x9f},
  32. { ST7586_CMD, ST7586_OTPRWCTL},
  33. { ST7586_DATA, 0x00},
  34. { ST7586_DELAY, 10},
  35. { ST7586_CMD, ST7586_OTPRD},
  36. { ST7586_DELAY, 20},
  37. { ST7586_CMD, ST7586_OTPCOUT},
  38. { ST7586_CMD, ST7586_SLPOUT},
  39. { ST7586_CMD, ST7586_DISPOFF},
  40. { ST7586_DELAY, 50},
  41. { ST7586_CMD, ST7586_VOPOFF},
  42. { ST7586_DATA, 0x00},
  43. { ST7586_CMD, ST7586_VOP},
  44. { ST7586_DATA, 0xE3},
  45. { ST7586_DATA, 0x00},
  46. { ST7586_CMD, ST7586_BIAS},
  47. { ST7586_DATA, 0x02},
  48. { ST7586_CMD, ST7586_BOOST},
  49. { ST7586_DATA, 0x04},
  50. { ST7586_CMD, ST7586_ANCTL},
  51. { ST7586_DATA, 0x1d},
  52. { ST7586_CMD, ST7586_NLNINV},
  53. { ST7586_DATA, 0x00},
  54. { ST7586_CMD, ST7586_DSPMONO},
  55. { ST7586_CMD, ST7586_RAMENB},
  56. { ST7586_DATA, 0x02},
  57. { ST7586_CMD, ST7586_DSPCTL},
  58. { ST7586_DATA, 0x00},
  59. { ST7586_CMD, ST7586_DSPDUTY},
  60. { ST7586_DATA, 0x7f},
  61. { ST7586_CMD, ST7586_PARDISP},
  62. { ST7586_DATA, 0xa0},
  63. { ST7586_CMD, ST7586_PARAREA},
  64. { ST7586_DATA, 0x00},
  65. { ST7586_DATA, 0x00},
  66. { ST7586_DATA, 0x00},
  67. { ST7586_DATA, 0x77},
  68. { ST7586_CMD, ST7586_INVOFF},
  69. { ST7586_CMD, ST7586_CASET},
  70. { ST7586_DATA, 0x00},
  71. { ST7586_DATA, 0x00},
  72. { ST7586_DATA, 0x00},
  73. { ST7586_DATA, 0x7f},
  74. { ST7586_CMD, ST7586_RASET},
  75. { ST7586_DATA, 0x00},
  76. { ST7586_DATA, 0x00},
  77. { ST7586_DATA, 0x00},
  78. { ST7586_DATA, 0x9f},
  79. { ST7586_CLR, ST7586_CLR},
  80. { ST7586_DELAY, 100},
  81. { ST7586_END, ST7586_END},
  82. };
  83. static bool driver_inited = false;
  84. static struct fb_fix_screeninfo st7586fb_fix __devinitdata = {
  85. .id = "ST7586",
  86. .type = FB_TYPE_PACKED_PIXELS,
  87. .visual = FB_VISUAL_PSEUDOCOLOR,
  88. .xpanstep = 0,
  89. .ypanstep = 0,
  90. .ywrapstep = 0,
  91. .line_length = (WIDTH+2)/3,
  92. .accel = FB_ACCEL_NONE,
  93. };
  94. static struct fb_var_screeninfo st7586fb_var __devinitdata = {
  95. .xres = WIDTH,
  96. .yres = HEIGHT,
  97. .xres_virtual = WIDTH,
  98. .yres_virtual = HEIGHT,
  99. .bits_per_pixel = 2,
  100. .nonstd = 1,
  101. };
  102. static int st7586_write(struct st7586fb_par *par, u8 data)
  103. {
  104. int ret = 0;
  105. /* Assert out-of-band CS */
  106. if (par->cs)
  107. gpio_set_value(par->cs, 0);
  108. par->buf[0] = data;
  109. ret = spi_write(par->spi, par->buf, 1);
  110. /* Deassert out-of-band CS */
  111. if (par->cs)
  112. gpio_set_value(par->cs, 1);
  113. return ret;
  114. }
  115. static void st7586_write_data(struct st7586fb_par *par, u8 data)
  116. {
  117. int ret = 0;
  118. /* Set data mode */
  119. gpio_set_value(par->a0, 1);
  120. ret = st7586_write(par, data);
  121. if (ret < 0)
  122. pr_err("%s: write data %02x failed with status %d\n",
  123. par->info->fix.id, data, ret);
  124. }
  125. static int st7586_write_data_buf(struct st7586fb_par *par,
  126. u8 *txbuf, int size)
  127. {
  128. int ret = 0;
  129. /* Set data mode */
  130. gpio_set_value(par->a0, 1);
  131. /* Assert out-of-band CS */
  132. if (par->cs)
  133. gpio_set_value(par->cs, 0);
  134. /* Write entire buffer */
  135. ret = spi_write(par->spi, txbuf, size);
  136. /* Deassert out-of-band CS */
  137. if (par->cs)
  138. gpio_set_value(par->cs, 1);
  139. return ret;
  140. }
  141. static void st7586_write_cmd(struct st7586fb_par *par, u8 data)
  142. {
  143. int ret = 0;
  144. /* Set command mode */
  145. gpio_set_value(par->a0, 0);
  146. ret = st7586_write(par, data);
  147. if (ret < 0)
  148. pr_err("%s: write command %02x failed with status %d\n",
  149. par->info->fix.id, data, ret);
  150. }
  151. static void st7586_clear_ddrram(struct st7586fb_par *par)
  152. {
  153. u8 *buf;
  154. #if 0 // Not suitable for EV3RT
  155. buf = kzalloc(128*128, GFP_KERNEL);
  156. #else // For EV3RT
  157. static u8 static_buf[128*128];
  158. buf = static_buf;
  159. #endif
  160. st7586_write_cmd(par, ST7586_RAMWR);
  161. st7586_write_data_buf(par, buf, 128*128);
  162. #if 0 // Not suitable for EV3RT
  163. kfree(buf);
  164. #endif
  165. }
  166. static void st7586_run_cfg_script(struct st7586fb_par *par)
  167. {
  168. int i = 0;
  169. int end_script = 0;
  170. do {
  171. switch (st7586_cfg_script[i].cmd)
  172. {
  173. case ST7586_START:
  174. break;
  175. case ST7586_CLR:
  176. st7586_clear_ddrram(par);
  177. break;
  178. case ST7586_CMD:
  179. st7586_write_cmd(par,
  180. st7586_cfg_script[i].data & 0xff);
  181. break;
  182. case ST7586_DATA:
  183. st7586_write_data(par,
  184. st7586_cfg_script[i].data & 0xff);
  185. break;
  186. case ST7586_DELAY:
  187. mdelay(st7586_cfg_script[i].data);
  188. break;
  189. case ST7586_END:
  190. end_script = 1;
  191. }
  192. i++;
  193. } while (!end_script);
  194. }
  195. static void st7586_set_addr_win(struct st7586fb_par *par,
  196. int xs, int ys, int xe, int ye)
  197. {
  198. st7586_write_cmd(par, ST7586_CASET);
  199. st7586_write_data(par, 0x00);
  200. st7586_write_data(par, xs);
  201. st7586_write_data(par, 0x00);
  202. st7586_write_data(par, ((xe+2)/3)-1);
  203. st7586_write_cmd(par, ST7586_RASET);
  204. st7586_write_data(par, 0x00);
  205. st7586_write_data(par, ys);
  206. st7586_write_data(par, 0x00);
  207. st7586_write_data(par, ye-1);
  208. }
  209. static void st7586_reset(struct st7586fb_par *par)
  210. {
  211. /* Reset controller */
  212. gpio_set_value(par->rst, 0);
  213. mdelay(10);
  214. gpio_set_value(par->rst, 1);
  215. mdelay(120);
  216. }
  217. static void st7586fb_update_display(struct st7586fb_par *par)
  218. {
  219. int ret = 0, i=0;
  220. u8 *vmem = (u8*) par->info->screen_base;
  221. // Check if any data has been put into screen buffer.
  222. // In case data written - Select display as inited
  223. if (!driver_inited) {
  224. while ( (!vmem[i]) && (i <(WIDTH+2)/3*HEIGHT)) i++;
  225. if (i != ((WIDTH+2)/3*HEIGHT)) driver_inited = true;
  226. }
  227. if (driver_inited) {
  228. st7586_set_addr_win(par, 0, 0, WIDTH, HEIGHT);
  229. st7586_write_cmd(par, ST7586_RAMWR);
  230. /* Blast framebuffer to ST7586 internal display RAM */
  231. ret = st7586_write_data_buf(par, vmem, (WIDTH+2)/3*HEIGHT);
  232. if (ret < 0)
  233. pr_err("%s: spi_write failed to update display buffer\n",
  234. par->info->fix.id);
  235. }
  236. }
  237. static void st7586fb_deferred_io(struct fb_info *info,
  238. struct list_head *pagelist)
  239. {
  240. st7586fb_update_display(info->par);
  241. }
  242. static int st7586fb_request_gpios(struct st7586fb_par *par)
  243. {
  244. /* TODO: Need some error checking on gpios */
  245. /* Request GPIOs and initialize to default values */
  246. gpio_request(par->rst, "ST7586 Reset Pin");
  247. gpio_direction_output(par->rst, 1);
  248. gpio_request(par->a0, "ST7586 A0 Pin");
  249. gpio_direction_output(par->a0, 0);
  250. if (par->cs) {
  251. gpio_request(par->cs, "ST7586 CS Pin");
  252. gpio_direction_output(par->cs, 1);
  253. }
  254. return 0;
  255. }
  256. static int st7586fb_init_display(struct st7586fb_par *par)
  257. {
  258. st7586_reset(par);
  259. st7586_run_cfg_script(par);
  260. /* Set row/column data window */
  261. st7586_set_addr_win(par, 0, 0, WIDTH, HEIGHT);
  262. st7586_write_cmd(par, ST7586_DISPON);
  263. return 0;
  264. }
  265. int st7586fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  266. {
  267. int retval = -ENOMEM;
  268. struct st7586fb_par *par = info->par;
  269. printk(KERN_ERR "fb%d: Initing display\n", info->node);
  270. switch (cmd)
  271. {
  272. case FB_ST7586_INIT_DISPLAY:
  273. retval = st7586fb_init_display(par);
  274. if (retval < 0) driver_inited = true;
  275. break;
  276. case FB_ST7586_START_DISPLAY:
  277. retval = 0;
  278. driver_inited = true;
  279. default:
  280. break;
  281. }
  282. return retval;
  283. }
  284. static ssize_t st7586fb_write(struct fb_info *info, const char __user *buf,
  285. size_t count, loff_t *ppos)
  286. {
  287. struct st7586fb_par *par = info->par;
  288. unsigned long p = *ppos;
  289. void *dst;
  290. int err = 0;
  291. unsigned long total_size;
  292. if (info->state != FBINFO_STATE_RUNNING)
  293. return -EPERM;
  294. total_size = info->fix.smem_len;
  295. if (p > total_size)
  296. return -EFBIG;
  297. if (count > total_size) {
  298. err = -EFBIG;
  299. count = total_size;
  300. }
  301. if (count + p > total_size) {
  302. if (!err)
  303. err = -ENOSPC;
  304. count = total_size - p;
  305. }
  306. dst = (void __force *) (info->screen_base + p);
  307. if (copy_from_user(dst, buf, count))
  308. err = -EFAULT;
  309. if (!err)
  310. *ppos += count;
  311. st7586fb_update_display(par);
  312. return (err) ? err : count;
  313. }
  314. static struct fb_ops st7586fb_ops = {
  315. .owner = THIS_MODULE,
  316. // .fb_read = fb_sys_read,
  317. .fb_write = st7586fb_write,
  318. // .fb_fillrect = st7586fb_fillrect,
  319. // .fb_copyarea = st7586fb_copyarea,
  320. // .fb_imageblit = st7586fb_imageblit,
  321. .fb_ioctl = st7586fb_ioctl
  322. };
  323. static struct fb_deferred_io st7586fb_defio = {
  324. .delay = HZ / 20,
  325. .deferred_io = st7586fb_deferred_io,
  326. };
  327. static int __devinit st7586fb_probe (struct spi_device *spi)
  328. {
  329. #if 0 // Not suitable for EV3RT
  330. int chip = spi_get_device_id(spi)->driver_data;
  331. struct st7586fb_platform_data *pdata = spi->dev.platform_data;
  332. int vmem_size = (WIDTH+2)/3*HEIGHT;
  333. #else // For EV3RT
  334. const struct st7586fb_platform_data *pdata = &lms2012_st7586fb_data;
  335. #define vmem_size ((WIDTH+2)/3*HEIGHT)
  336. #endif
  337. u8 *vmem;
  338. struct fb_info *info;
  339. struct st7586fb_par *par;
  340. int retval = -ENOMEM;
  341. #if 0 // Not suitable for EV3RT
  342. if (chip != ST7586_DISPLAY_LMS2012_LCD) {
  343. pr_err("%s: only the %s device is supported\n", DRVNAME,
  344. to_spi_driver(spi->dev.driver)->id_table->name);
  345. return -EINVAL;
  346. }
  347. #endif
  348. if (!pdata) {
  349. pr_err("%s: platform data required for rst and a0 info\n",
  350. DRVNAME);
  351. return -EINVAL;
  352. }
  353. #if 0 // Not suitable for EV3RT
  354. vmem = (u8 *)kmalloc(vmem_size, GFP_KERNEL);
  355. if (!vmem)
  356. return retval;
  357. #else // For EV3RT
  358. static u8 static_vmem[vmem_size] __attribute__((section(".lcd_vmem")));
  359. vmem = static_vmem;
  360. #endif
  361. // Zero memory for easy detection if any new data has been written to screenbuffer
  362. memset(vmem, 0, vmem_size);
  363. #if 0 // Not suitable for EV3RT
  364. info = framebuffer_alloc(sizeof(struct st7586fb_par), &spi->dev);
  365. if (!info)
  366. goto fballoc_fail;
  367. #else // For EV3RT
  368. static struct fb_info static_fb_info;
  369. static struct st7586fb_par static_par;
  370. info = &static_fb_info;
  371. info->par = &static_par;
  372. #endif
  373. info->screen_base = (char*)vmem;
  374. info->fbops = &st7586fb_ops;
  375. info->fix = st7586fb_fix;
  376. info->fix.smem_start = (unsigned long)virt_to_phys(vmem);
  377. info->fix.smem_len = vmem_size;
  378. info->var = st7586fb_var;
  379. /* The ST7586 packed pixel format does not translate well here */
  380. /* FIXME - change to mono reporting */
  381. info->var.red.offset = 11;
  382. info->var.red.length = 5;
  383. info->var.green.offset = 5;
  384. info->var.green.length = 6;
  385. info->var.blue.offset = 0;
  386. info->var.blue.length = 5;
  387. info->var.transp.offset = 0;
  388. info->var.transp.length = 0;
  389. info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
  390. info->fbdefio = &st7586fb_defio;
  391. #if 0 // Not suitable for EV3RT
  392. fb_deferred_io_init(info);
  393. #endif
  394. par = info->par;
  395. par->info = info;
  396. par->spi = spi;
  397. par->rst = pdata->rst_gpio;
  398. par->a0 = pdata->a0_gpio;
  399. par->cs = pdata->cs_gpio;
  400. #if 0 // Not suitable for EV3RT
  401. par->buf = kmalloc(1, GFP_KERNEL);
  402. #else // For EV3RT
  403. static u8 static_par_buf;
  404. par->buf = &static_par_buf;
  405. #endif
  406. #if 0 // Not suitable for EV3RT
  407. retval = register_framebuffer(info);
  408. if (retval < 0)
  409. goto fbreg_fail;
  410. #endif
  411. spi_set_drvdata(spi, info);
  412. retval = st7586fb_request_gpios(par);
  413. // Move initing of display to ioctl call to avoid dispaly flickering
  414. // as dispaly has already been inited in uboot
  415. // retval |= st7586fb_init_display(par);
  416. if (retval < 0)
  417. goto init_fail;
  418. printk(KERN_INFO
  419. "fb%d: %s frame buffer device, using %d KiB of video memory\n",
  420. info->node, info->fix.id, vmem_size/1024);
  421. return 0;
  422. #if 0 // Not suitable for EV3RT
  423. init_fail:
  424. spi_set_drvdata(spi, NULL);
  425. fbreg_fail:
  426. kfree(par->buf);
  427. framebuffer_release(info);
  428. fballoc_fail:
  429. kfree(vmem);
  430. #else // For EV3RT
  431. init_fail:
  432. assert(false);
  433. #endif
  434. return retval;
  435. }
  436. #if 0 // Not suitable for EV3RT
  437. static int __devexit st7586fb_remove(struct spi_device *spi)
  438. {
  439. struct fb_info *info = spi_get_drvdata(spi);
  440. spi_set_drvdata(spi, NULL);
  441. if (info) {
  442. struct st7586fb_par *par = info->par;
  443. unregister_framebuffer(info);
  444. kfree(info->screen_base);
  445. kfree(par->buf);
  446. gpio_free(par->rst);
  447. gpio_free(par->a0);
  448. if (par->cs)
  449. gpio_free(par->cs);
  450. framebuffer_release(info);
  451. }
  452. return 0;
  453. }
  454. static const struct spi_device_id st7586fb_ids[] = {
  455. { "lms2012_lcd", ST7586_DISPLAY_LMS2012_LCD },
  456. { },
  457. };
  458. MODULE_DEVICE_TABLE(spi, st7586fb_ids);
  459. static struct spi_driver st7586fb_driver = {
  460. .driver = {
  461. .name = "st7586fb",
  462. .owner = THIS_MODULE,
  463. },
  464. .id_table = st7586fb_ids,
  465. .probe = st7586fb_probe,
  466. .remove = __devexit_p(st7586fb_remove),
  467. };
  468. static int __init st7586fb_init(void)
  469. {
  470. return spi_register_driver(&st7586fb_driver);
  471. }
  472. static void __exit st7586fb_exit(void)
  473. {
  474. spi_unregister_driver(&st7586fb_driver);
  475. }
  476. /* ------------------------------------------------------------------------- */
  477. module_init(st7586fb_init);
  478. module_exit(st7586fb_exit);
  479. MODULE_DESCRIPTION("FB driver for ST7586 display controller");
  480. MODULE_AUTHOR("Matt Porter <mporter@ti.com>");
  481. MODULE_LICENSE("GPL");
  482. void st7586fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
  483. {
  484. struct st7586fb_par *par = info->par;
  485. sys_fillrect(info, rect);
  486. st7586fb_update_display(par);
  487. }
  488. void st7586fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
  489. {
  490. struct st7586fb_par *par = info->par;
  491. sys_copyarea(info, area);
  492. st7586fb_update_display(par);
  493. }
  494. void st7586fb_imageblit(struct fb_info *info, const struct fb_image *image)
  495. {
  496. struct st7586fb_par *par = info->par;
  497. sys_imageblit(info, image);
  498. st7586fb_update_display(par);
  499. }
  500. #endif