Advertisement
Guest User

Untitled

a guest
Jun 20th, 2014
603
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.45 KB | None | 0 0
  1. /*
  2. * ILI9341 Framebuffer
  3. *
  4. * ILI9341 chip drive TFT screen up to 320x240.
  5. *
  6. */
  7.  
  8. #include <linux/kernel.h>
  9. #include <linux/device.h>
  10. #include <linux/module.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/mm.h>
  13. #include <linux/vmalloc.h>
  14. #include <linux/fb.h>
  15. #include <asm/io.h>
  16. #include <asm/gpio.h>
  17. #include <linux/gpio.h>
  18. #include <linux/gpio_keys.h>
  19. #include <linux/delay.h>
  20. #include <linux/spi/spi.h>
  21.  
  22. #define DEBUG
  23.  
  24. #define ILI_COMMAND 1
  25. #define ILI_DATA 0
  26.  
  27. #define ILI_GPIO_DC 25
  28.  
  29. static int global_counter = 0;
  30.  
  31. //static struct spi_board_info
  32. // olimex_spi_board = {
  33. //#if defined(CONFIG_SPI_SPIDEV)
  34. // .modalias = "spidev",
  35. //#endif
  36. // .max_speed_hz = 8000000,
  37. // .bus_num = 1,
  38. // .chip_select = 0,
  39. // .controller_data = &spi_stm32_flash_slv__dongle,
  40. //};
  41.  
  42. //static u64 lcdc_dmamask = DMA_BIT_MASK(32);
  43. static struct ili9341 ili9341_data;
  44.  
  45. static struct resource ili9341_resources[] = {
  46. [0] = {
  47. .start = SW_VA_SRAM_BASE,
  48. .end = SW_VA_SRAM_BASE + SZ_4K - 1,
  49. .flags = IORESOURCE_MEM,
  50. },
  51. [1] = {
  52. .start = SW_INT_IRQNO_SPI01,
  53. .end = SW_INT_IRQNO_SPI01,
  54. .flags = IORESOURCE_IRQ,
  55. },
  56. };
  57.  
  58. static struct platform_device ili9341_device = {
  59. .name = "ili9341",
  60. .id = 0,
  61. .dev = {
  62. //.dma_mask = &lcdc_dmamask,
  63. //.coherent_dma_mask = DMA_BIT_MASK(32),
  64. .platform_data = &ili9341_data,
  65. },
  66. .resource = ili9341_resources,
  67. .num_resources = ARRAY_SIZE(ili9341_resources),
  68. };
  69.  
  70.  
  71. struct ili9341_page {
  72. unsigned short x;
  73. unsigned short y;
  74. unsigned short *buffer;
  75. unsigned short len;
  76. int must_update;
  77. };
  78.  
  79. struct ili9341 {
  80. struct device *dev;
  81. struct spi_device *spi;
  82. volatile unsigned short *ctrl_io;
  83. volatile unsigned short *data_io;
  84. struct fb_info *info;
  85. unsigned int pages_count;
  86. struct ili9341_page *pages;
  87. // struct {
  88. // void *buf;
  89. // dma_addr_t dma;
  90. // size_t len;
  91. // } txbuf;
  92. unsigned long pseudo_palette[25];
  93. };
  94.  
  95. static void ili9341_clear_graph(struct ili9341 *item);
  96.  
  97. int ili9341_write_spi(struct ili9341 *item, void *buf, size_t len)
  98. {
  99. struct spi_transfer t = {
  100. .tx_buf = buf,
  101. .len = len,
  102. // .speed_hz = 16000000,
  103. // .cs_change = 0,
  104. // .bits_per_word = 8,
  105. // .delay_usecs = 1,
  106. // .interbyte_usecs = 1
  107. };
  108. struct spi_message m;
  109.  
  110. //printk("%s(len=%d): ", __func__, len);
  111.  
  112. if (!item->spi) {
  113. dev_err(item->info->device,
  114. "%s: par->spi is unexpectedly NULL\n", __func__);
  115. return -1;
  116. }
  117.  
  118. spi_message_init(&m);
  119. // if (item->txbuf.dma && buf == item->txbuf.buf) {
  120. // t.tx_dma = par->txbuf.dma;
  121. // m.is_dma_mapped = 1;
  122. // }
  123. spi_message_add_tail(&t, &m);
  124. return spi_sync(item->spi, &m);
  125. }
  126.  
  127. int ili9341_write_spi_1_byte(struct ili9341 *item, unsigned char byte)
  128. {
  129. unsigned char tmp_byte = byte;
  130.  
  131. struct spi_transfer t = {
  132. .tx_buf = &tmp_byte,
  133. .len = 1,
  134. // .speed_hz = 16000000,
  135. };
  136. struct spi_message m;
  137.  
  138. pr_debug("%s(len=1): ", __func__);
  139.  
  140. if (!item->spi) {
  141. dev_err(item->info->device,
  142. "%s: par->spi is unexpectedly NULL\n", __func__);
  143. return -1;
  144. }
  145.  
  146. spi_message_init(&m);
  147. spi_message_add_tail(&t, &m);
  148. return spi_sync(item->spi, &m);
  149. }
  150.  
  151. static int ili9341_init_gpio(struct ili9341 *item)
  152. {
  153. //DC high - data, DC low - command
  154. return gpio_request_one(ILI_GPIO_DC, GPIOF_OUT_INIT_HIGH,
  155. item->info->device->driver->name);
  156.  
  157. //TODO free_gpio(ILI_GPIO_DC);
  158. }
  159.  
  160. static void ili9341_write_data(struct ili9341 *item, unsigned char dc, unsigned char value) {
  161.  
  162. if (dc == ILI_COMMAND) {
  163. gpio_set_value(ILI_GPIO_DC, 0);
  164. ili9341_write_spi_1_byte(item, value);
  165. gpio_set_value(ILI_GPIO_DC, 1);
  166. } else { //ILI_DATA
  167. ili9341_write_spi_1_byte(item, value);
  168. }
  169.  
  170. }
  171.  
  172. static inline void ili9341_send_rgb_data (struct ili9341 *item, unsigned short color)
  173. {
  174. ili9341_write_data(item, ILI_DATA, color>>8);
  175. ili9341_write_data(item, ILI_DATA, color);
  176. }
  177.  
  178.  
  179. /* Init sequence taken from: Arduino Library for the Adafruit 2.2" display */
  180. static int ili9341_init_display(struct ili9341 *item)
  181. {
  182. printk( "%s()\n", __func__);
  183.  
  184. ili9341_init_gpio(item);
  185.  
  186. /* Software Reset */
  187. ili9341_write_data(item, ILI_COMMAND, 0x01);
  188.  
  189. mdelay(120);
  190.  
  191. /* Display OFF */
  192. ili9341_write_data(item, ILI_COMMAND, 0x28);
  193.  
  194. ili9341_write_data(item, ILI_COMMAND, 0xEF);
  195. ili9341_write_data(item, ILI_DATA, 0x03);
  196. ili9341_write_data(item, ILI_DATA, 0x80);
  197. ili9341_write_data(item, ILI_DATA, 0x02);
  198.  
  199. ili9341_write_data(item, ILI_COMMAND, 0xCF);
  200. ili9341_write_data(item, ILI_DATA, 0x00);
  201. ili9341_write_data(item, ILI_DATA, 0xC1);
  202. ili9341_write_data(item, ILI_DATA, 0x30);
  203.  
  204. ili9341_write_data(item, ILI_COMMAND, 0xED);
  205. ili9341_write_data(item, ILI_DATA, 0x64);
  206. ili9341_write_data(item, ILI_DATA, 0x03);
  207. ili9341_write_data(item, ILI_DATA, 0x12);
  208. ili9341_write_data(item, ILI_DATA, 0x81);
  209.  
  210. ili9341_write_data(item, ILI_COMMAND, 0xE8);
  211. ili9341_write_data(item, ILI_DATA, 0x85);
  212. ili9341_write_data(item, ILI_DATA, 0x00);
  213. ili9341_write_data(item, ILI_DATA, 0x78);
  214.  
  215. ili9341_write_data(item, ILI_COMMAND, 0xCB);
  216. ili9341_write_data(item, ILI_DATA, 0x39);
  217. ili9341_write_data(item, ILI_DATA, 0x2C);
  218. ili9341_write_data(item, ILI_DATA, 0x00);
  219. ili9341_write_data(item, ILI_DATA, 0x34);
  220. ili9341_write_data(item, ILI_DATA, 0x02);
  221.  
  222. ili9341_write_data(item, ILI_COMMAND, 0xF7);
  223. ili9341_write_data(item, ILI_DATA, 0x20);
  224.  
  225. ili9341_write_data(item, ILI_COMMAND, 0xEA);
  226. ili9341_write_data(item, ILI_DATA, 0x00);
  227. ili9341_write_data(item, ILI_DATA, 0x00);
  228.  
  229. /* Power Control 1 */
  230. ili9341_write_data(item, ILI_COMMAND, 0xC0);
  231. ili9341_write_data(item, ILI_DATA, 0x23);
  232.  
  233. /* Power Control 2 */
  234. ili9341_write_data(item, ILI_COMMAND, 0xC1);
  235. ili9341_write_data(item, ILI_DATA, 0x10);
  236.  
  237. /* VCOM Control 1 */
  238. ili9341_write_data(item, ILI_COMMAND, 0xC5);
  239. ili9341_write_data(item, ILI_DATA, 0x3e);
  240. ili9341_write_data(item, ILI_DATA, 0x28);
  241.  
  242. /* VCOM Control 2 */
  243. ili9341_write_data(item, ILI_COMMAND, 0xC7);
  244. ili9341_write_data(item, ILI_DATA, 0x86);
  245.  
  246. /* COLMOD: Pixel Format Set */
  247. /* 16 bits/pixel */
  248. ili9341_write_data(item, ILI_COMMAND, 0x3A);
  249. ili9341_write_data(item, ILI_DATA, 0x55);
  250.  
  251. /* Frame Rate Control */
  252. /* Division ratio = fosc, Frame Rate = 79Hz */
  253. ili9341_write_data(item, ILI_COMMAND, 0xB1);
  254. ili9341_write_data(item, ILI_DATA, 0x00);
  255. ili9341_write_data(item, ILI_DATA, 0x18);
  256.  
  257. /* Display Function Control */
  258. ili9341_write_data(item, ILI_COMMAND, 0xB6);
  259. ili9341_write_data(item, ILI_DATA, 0x08);
  260. ili9341_write_data(item, ILI_DATA, 0x82);
  261. ili9341_write_data(item, ILI_DATA, 0x27);
  262.  
  263. /* MADCTL, required to resolve 'mirroring' effect */
  264. ili9341_write_data(item, ILI_COMMAND, 0x36);
  265. ili9341_write_data(item, ILI_DATA, 0x40);
  266.  
  267. /* Gamma Function Disable */
  268. ili9341_write_data(item, ILI_COMMAND, 0xF2);
  269. ili9341_write_data(item, ILI_DATA, 0x00);
  270.  
  271. /* Gamma curve selected */
  272. ili9341_write_data(item, ILI_COMMAND, 0x26);
  273. ili9341_write_data(item, ILI_DATA, 0x01);
  274.  
  275. /* Positive Gamma Correction */
  276. ili9341_write_data(item, ILI_COMMAND, 0xE0);
  277. ili9341_write_data(item, ILI_DATA, 0x0F);
  278. ili9341_write_data(item, ILI_DATA, 0x31);
  279. ili9341_write_data(item, ILI_DATA, 0x2B);
  280. ili9341_write_data(item, ILI_DATA, 0x0C);
  281. ili9341_write_data(item, ILI_DATA, 0x0E);
  282. ili9341_write_data(item, ILI_DATA, 0x08);
  283. ili9341_write_data(item, ILI_DATA, 0x4E);
  284. ili9341_write_data(item, ILI_DATA, 0xF1);
  285. ili9341_write_data(item, ILI_DATA, 0x37);
  286. ili9341_write_data(item, ILI_DATA, 0x07);
  287. ili9341_write_data(item, ILI_DATA, 0x10);
  288. ili9341_write_data(item, ILI_DATA, 0x03);
  289. ili9341_write_data(item, ILI_DATA, 0x0E);
  290. ili9341_write_data(item, ILI_DATA, 0x09);
  291. ili9341_write_data(item, ILI_DATA, 0x00);
  292.  
  293. /* Negative Gamma Correction */
  294. ili9341_write_data(item, ILI_COMMAND, 0xE1);
  295. ili9341_write_data(item, ILI_DATA, 0x00);
  296. ili9341_write_data(item, ILI_DATA, 0x0E);
  297. ili9341_write_data(item, ILI_DATA, 0x14);
  298. ili9341_write_data(item, ILI_DATA, 0x03);
  299. ili9341_write_data(item, ILI_DATA, 0x11);
  300. ili9341_write_data(item, ILI_DATA, 0x07);
  301. ili9341_write_data(item, ILI_DATA, 0x31);
  302. ili9341_write_data(item, ILI_DATA, 0xC1);
  303. ili9341_write_data(item, ILI_DATA, 0x48);
  304. ili9341_write_data(item, ILI_DATA, 0x08);
  305. ili9341_write_data(item, ILI_DATA, 0x0F);
  306. ili9341_write_data(item, ILI_DATA, 0x0C);
  307. ili9341_write_data(item, ILI_DATA, 0x31);
  308. ili9341_write_data(item, ILI_DATA, 0x36);
  309. ili9341_write_data(item, ILI_DATA, 0x0F);
  310.  
  311. /* Sleep OUT */
  312. ili9341_write_data(item, ILI_COMMAND, 0x11);
  313.  
  314. mdelay(120);
  315.  
  316. /* Display ON */
  317. ili9341_write_data(item, ILI_COMMAND, 0x29);
  318.  
  319. ili9341_clear_graph(item);
  320.  
  321. printk("COLOR LCD driver initialized\n");
  322.  
  323. return 0;
  324. }
  325.  
  326. static void ili9341_set_window(struct ili9341 *item, int xs, int ys, int xe, int ye)
  327. {
  328. printk("%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
  329.  
  330. /* Column address */
  331. ili9341_write_data(item, ILI_COMMAND, 0x2A);
  332. ili9341_write_data(item, ILI_DATA, xs >> 8);
  333. ili9341_write_data(item, ILI_DATA, xs & 0xFF);
  334. ili9341_write_data(item, ILI_DATA, xe >> 8);
  335. ili9341_write_data(item, ILI_DATA, xe & 0xFF);
  336.  
  337. /* Row adress */
  338. ili9341_write_data(item, ILI_COMMAND, 0x2B);
  339. ili9341_write_data(item, ILI_DATA, ys >> 8);
  340. ili9341_write_data(item, ILI_DATA, ys & 0xFF);
  341. ili9341_write_data(item, ILI_DATA, ye >> 8);
  342. ili9341_write_data(item, ILI_DATA, ye & 0xFF);
  343.  
  344. /* Memory write */
  345. ili9341_write_data(item, ILI_COMMAND, 0x2C);
  346. }
  347.  
  348. static void ili9341_clear_graph(struct ili9341 *item)
  349. {
  350. int i;
  351. int length=76800;
  352.  
  353. ili9341_set_window(item, 0x0000, 0x0000, 0x00ef, 0x013f);
  354.  
  355. for(i=0; i<length; i++) {
  356. ili9341_send_rgb_data(item, 0xFFFF);
  357. }
  358. }
  359.  
  360. static void ili9341_touch(struct fb_info *info, int x, int y, int w, int h)
  361. {
  362. struct fb_deferred_io *fbdefio = info->fbdefio;
  363. struct ili9341 *item = (struct ili9341 *)info->par;
  364. int i, ystart, yend;
  365. if (fbdefio) {
  366. //Schedule the deferred IO to kick in after a delay.
  367. schedule_delayed_work(&info->deferred_work, fbdefio->delay);
  368. }
  369. }
  370.  
  371.  
  372. static int __init ili9341_video_alloc(struct ili9341 *item)
  373. {
  374. unsigned int frame_size;
  375.  
  376. dev_dbg(item->dev, "%s: item=0x%p\n", __func__, (void *)item);
  377.  
  378. frame_size = item->info->fix.line_length * item->info->var.yres;
  379. printk(KERN_ALERT "frame_size =%d\n", frame_size);
  380. dev_dbg(item->dev, "%s: item=0x%p frame_size=%u\n",
  381. __func__, (void *)item, frame_size);
  382.  
  383. item->pages_count = frame_size / PAGE_SIZE;
  384. if ((item->pages_count * PAGE_SIZE) < frame_size) {
  385. item->pages_count++;
  386. }
  387. printk(KERN_ALERT "pages_count =%d\n", item->pages_count);
  388. dev_dbg(item->dev, "%s: item=0x%p pages_count=%u\n",
  389. __func__, (void *)item, item->pages_count);
  390.  
  391. item->info->fix.smem_len = item->pages_count * PAGE_SIZE;
  392. item->info->fix.smem_start =
  393. (unsigned short*) vmalloc(item->info->fix.smem_len);
  394. if (!item->info->fix.smem_start) {
  395. dev_err(item->dev, "%s: unable to vmalloc\n", __func__);
  396. return -ENOMEM;
  397. }
  398. memset((void *)item->info->fix.smem_start, 0, item->info->fix.smem_len);
  399.  
  400. return 0;
  401. }
  402.  
  403. static void ili9341_video_free(struct ili9341 *item)
  404. {
  405. dev_dbg(item->dev, "%s: item=0x%p\n", __func__, (void *)item);
  406.  
  407. kfree((void *)item->info->fix.smem_start);
  408. }
  409.  
  410. //This routine will allocate a ili9341_page struct for each vm page in the
  411. //main framebuffer memory. Each struct will contain a pointer to the page
  412. //start, an x- and y-offset, and the length of the pagebuffer which is in the framebuffer.
  413. static int __init ili9341_pages_alloc(struct ili9341 *item)
  414. {
  415. unsigned short pixels_per_page;
  416. unsigned short yoffset_per_page;
  417. unsigned short xoffset_per_page;
  418. unsigned short index;
  419. unsigned short x = 0;
  420. unsigned short y = 0;
  421. unsigned short *buffer;
  422. unsigned int len;
  423.  
  424. dev_dbg(item->dev, "%s: item=0x%p\n", __func__, (void *)item);
  425.  
  426. item->pages = kmalloc(item->pages_count * sizeof(struct ili9341_page),
  427. GFP_KERNEL);
  428. if (!item->pages) {
  429. dev_err(item->dev, "%s: unable to kmalloc for ssd1289_page\n",
  430. __func__);
  431. return -ENOMEM;
  432. }
  433.  
  434. pixels_per_page = PAGE_SIZE / (item->info->var.bits_per_pixel / 8);
  435. yoffset_per_page = pixels_per_page / item->info->var.xres;
  436. xoffset_per_page = pixels_per_page -
  437. (yoffset_per_page * item->info->var.xres);
  438. dev_dbg(item->dev, "%s: item=0x%p pixels_per_page=%hu "
  439. "yoffset_per_page=%hu xoffset_per_page=%hu\n",
  440. __func__, (void *)item, pixels_per_page,
  441. yoffset_per_page, xoffset_per_page);
  442.  
  443. buffer = (unsigned short *)item->info->fix.smem_start;
  444. for (index = 0; index < item->pages_count; index++) {
  445. len = (item->info->var.xres * item->info->var.yres) -
  446. (index * pixels_per_page);
  447. if (len > pixels_per_page) {
  448. len = pixels_per_page;
  449. }
  450. dev_dbg(item->dev,
  451. "%s: page[%d]: x=%3hu y=%3hu buffer=0x%p len=%3hu\n",
  452. __func__, index, x, y, buffer, len);
  453. item->pages[index].x = x;
  454. item->pages[index].y = y;
  455. item->pages[index].buffer = buffer;
  456. item->pages[index].len = len;
  457.  
  458. x += xoffset_per_page;
  459. if (x >= item->info->var.xres) {
  460. y++;
  461. x -= item->info->var.xres;
  462. }
  463. y += yoffset_per_page;
  464. buffer += pixels_per_page;
  465. }
  466.  
  467. return 0;
  468. }
  469.  
  470. static void ili9341_pages_free(struct ili9341 *item)
  471. {
  472. dev_dbg(item->dev, "%s: item=0x%p\n", __func__, (void *)item);
  473.  
  474. kfree(item->pages);
  475. }
  476.  
  477. static void ili9341_update(struct fb_info *info, struct list_head *pagelist)
  478. {
  479. struct ili9341 *item = (struct ili9341 *)info->par;
  480. struct page *page;
  481. int i;
  482.  
  483. unsigned char *tmpbuf = kzalloc(PAGE_SIZE, GFP_KERNEL);
  484.  
  485. //Copy all pages.
  486. for (i=0; i<item->pages_count; i++) {
  487. if(i == 37) {
  488. memcpy(tmpbuf, item->pages[i].buffer, PAGE_SIZE/2);
  489. ili9341_write_spi(item, tmpbuf, PAGE_SIZE/2);
  490. }
  491. else {
  492. memcpy(tmpbuf, item->pages[i].buffer, PAGE_SIZE);
  493. ili9341_write_spi(item, tmpbuf, PAGE_SIZE);
  494. }
  495. }
  496. kfree(tmpbuf);
  497.  
  498. #if 0
  499. unsigned char *tmpbuf = kzalloc(PAGE_SIZE, GFP_KERNEL);
  500.  
  501. if(global_counter%3 == 0) {
  502. for (j=0; j<PAGE_SIZE; j++) tmpbuf[j] = 0x07;
  503. for (i=0; i<item->pages_count; i++) {
  504. if(i == 37)
  505. ili9341_write_spi(item, tmpbuf, PAGE_SIZE/2);
  506. else
  507. ili9341_write_spi(item, tmpbuf, PAGE_SIZE);
  508. }
  509. global_counter++;
  510. }
  511.  
  512. if(global_counter%2 == 0) {
  513. for (j=0; j<PAGE_SIZE; j++) tmpbuf[j] = 0x3E;
  514. for (i=0; i<item->pages_count; i++) {
  515. if(i == 37)
  516. ili9341_write_spi(item, tmpbuf, PAGE_SIZE/2);
  517. else
  518. ili9341_write_spi(item, tmpbuf, PAGE_SIZE);
  519. }
  520. global_counter++;
  521. }
  522.  
  523. if(global_counter%1 == 0) {
  524. for (j=0; j<PAGE_SIZE; j++) tmpbuf[j] = 0xE0;
  525. for (i=0; i<item->pages_count; i++) {
  526. if(i == 37)
  527. ili9341_write_spi(item, tmpbuf, PAGE_SIZE/2);
  528. else
  529. ili9341_write_spi(item, tmpbuf, PAGE_SIZE);
  530. }
  531. global_counter++;
  532. }
  533.  
  534. kfree(tmpbuf);
  535. #endif
  536.  
  537. }
  538.  
  539. static inline __u32 CNVT_TOHW(__u32 val, __u32 width)
  540. {
  541. return ((val<<width) + 0x7FFF - val)>>16;
  542. }
  543.  
  544.  
  545. //This routine is needed because the console driver won't work without it.
  546. static int ili9341_setcolreg(unsigned regno,
  547. unsigned red, unsigned green, unsigned blue,
  548. unsigned transp, struct fb_info *info)
  549. {
  550. int ret = 1;
  551.  
  552. /*
  553. * If greyscale is true, then we convert the RGB value
  554. * to greyscale no matter what visual we are using.
  555. */
  556. if (info->var.grayscale)
  557. red = green = blue = (19595 * red + 38470 * green +
  558. 7471 * blue) >> 16;
  559. switch (info->fix.visual) {
  560. case FB_VISUAL_TRUECOLOR:
  561. if (regno < 16) {
  562. u32 *pal = info->pseudo_palette;
  563. u32 value;
  564.  
  565. red = CNVT_TOHW(red, info->var.red.length);
  566. green = CNVT_TOHW(green, info->var.green.length);
  567. blue = CNVT_TOHW(blue, info->var.blue.length);
  568. transp = CNVT_TOHW(transp, info->var.transp.length);
  569.  
  570. value = (red << info->var.red.offset) |
  571. (green << info->var.green.offset) |
  572. (blue << info->var.blue.offset) |
  573. (transp << info->var.transp.offset);
  574.  
  575. pal[regno] = value;
  576. ret = 0;
  577. }
  578. break;
  579. case FB_VISUAL_STATIC_PSEUDOCOLOR:
  580. case FB_VISUAL_PSEUDOCOLOR:
  581. break;
  582. }
  583. return ret;
  584.  
  585. return 0;
  586. }
  587.  
  588. static int ili9341_blank(int blank_mode, struct fb_info *info)
  589. {
  590. return 0;
  591. }
  592.  
  593. static void ili9341_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
  594. {
  595. sys_fillrect(p, rect);
  596. ili9341_touch(p, rect->dx, rect->dy, rect->width, rect->height);
  597.  
  598. }
  599.  
  600. static void ili9341_imageblit(struct fb_info *p, const struct fb_image *image)
  601. {
  602. sys_imageblit(p, image);
  603. ili9341_touch(p, image->dx, image->dy, image->width, image->height);
  604. }
  605.  
  606. static void ili9341_copyarea(struct fb_info *p, const struct fb_copyarea *area)
  607. {
  608. sys_copyarea(p, area);
  609. ili9341_touch(p, area->dx, area->dy, area->width, area->height);
  610.  
  611. }
  612.  
  613. static ssize_t ili9341_write(struct fb_info *p, const char __user *buf,
  614. size_t count, loff_t *ppos)
  615. {
  616. ssize_t res;
  617. res = fb_sys_write(p, buf, count, ppos);
  618. ili9341_touch(p, 0, 0, p->var.xres, p->var.yres);
  619. return res;
  620. }
  621.  
  622. static struct fb_ops ili9341_fbops = {
  623. .owner = THIS_MODULE,
  624. .fb_read = fb_sys_read,
  625. .fb_write = ili9341_write,
  626. .fb_fillrect = ili9341_fillrect,
  627. .fb_copyarea = ili9341_copyarea,
  628. .fb_imageblit = ili9341_imageblit,
  629. .fb_setcolreg = ili9341_setcolreg,
  630. .fb_blank = ili9341_blank,
  631. };
  632.  
  633. static struct fb_fix_screeninfo ili9341_fix __initdata = {
  634. .id = "ILI9341",
  635. .type = FB_TYPE_PACKED_PIXELS,
  636. .visual = FB_VISUAL_TRUECOLOR,
  637. .accel = FB_ACCEL_NONE,
  638. .line_length = 240 * 2,
  639. };
  640.  
  641. static struct fb_var_screeninfo ili9341_var __initdata = {
  642. .xres = 240,
  643. .yres = 320,
  644. .xres_virtual = 240,
  645. .yres_virtual = 320,
  646. .width = 240,
  647. .height = 320,
  648. .bits_per_pixel = 16,
  649. .red = {11, 5, 0},
  650. .green = {5, 6, 0},
  651. .blue = {0, 5, 0},
  652. .activate = FB_ACTIVATE_NOW,
  653. .vmode = FB_VMODE_NONINTERLACED,
  654. };
  655.  
  656. static struct fb_deferred_io ili9341_defio = {
  657. .delay = HZ / 5,
  658. .deferred_io = &ili9341_update,
  659. };
  660.  
  661. static int __init ili9341_probe(struct platform_device *dev)
  662. {
  663. int ret = 0;
  664. struct ili9341 *item;
  665. struct fb_info *info;
  666.  
  667. //printk( "%s\n", __func__);
  668. dev_dbg(&dev->dev, "ololo%s\n", __func__);
  669.  
  670. item = kzalloc(sizeof(struct ili9341), GFP_KERNEL);
  671. if (!item) {
  672. dev_err(&dev->dev,
  673. "%s: unable to kzalloc for ili9341\n", __func__);
  674. ret = -ENOMEM;
  675. goto out;
  676. }
  677. item->dev = &dev->dev;
  678. dev_set_drvdata(&dev->dev, item);
  679. dev_dbg(&dev->dev, "Before registering SPI\n");
  680.  
  681. printk( "allocate framebuffer\n");
  682.  
  683. info = framebuffer_alloc(sizeof(struct ili9341), &dev->dev);
  684. if (!info) {
  685. ret = -ENOMEM;
  686. dev_err(&dev->dev,
  687. "%s: unable to framebuffer_alloc\n", __func__);
  688. goto out_item;
  689. }
  690. info->pseudo_palette = &item->pseudo_palette;
  691. item->info = info;
  692. info->par = item;
  693. info->dev = &dev->dev;
  694. info->fbops = &ili9341_fbops;
  695. info->flags = FBINFO_FLAG_DEFAULT;
  696. info->fix = ili9341_fix;
  697. info->var = ili9341_var;
  698.  
  699. printk("Before registering SPI\n");
  700. struct device* spidevice = bus_find_device_by_name(&spi_bus_type, NULL, "spi1.0");
  701. item->spi = to_spi_device(spidevice);
  702. if (spidevice)
  703. printk("After registering SPI %p\n", spidevice);
  704. else
  705. printk("Failed to register SPI\n");
  706.  
  707. ili9341_init_display(item);
  708.  
  709. ret = ili9341_video_alloc(item);
  710. if (ret) {
  711. dev_err(&dev->dev,
  712. "%s: unable to ili9341_video_alloc\n", __func__);
  713. goto out_info;
  714. }
  715. info->screen_base = (char __iomem *)item->info->fix.smem_start;
  716. ret = ili9341_pages_alloc(item);
  717. if (ret < 0) {
  718. dev_err(&dev->dev,
  719. "%s: unable to ili9341_pages_init\n", __func__);
  720. goto out_video;
  721. }
  722.  
  723. info->fbdefio = &ili9341_defio;
  724. fb_deferred_io_init(info);
  725.  
  726. ret = register_framebuffer(info);
  727. if (ret < 0) {
  728. dev_err(&dev->dev,
  729. "%s: unable to register_frambuffer\n", __func__);
  730. goto out_pages;
  731. }
  732.  
  733. return ret;
  734.  
  735. out_pages:
  736. ili9341_pages_free(item);
  737. out_video:
  738. ili9341_video_free(item);
  739. out_info:
  740. framebuffer_release(info);
  741. out_item:
  742. kfree(item);
  743. out:
  744. return ret;
  745. }
  746.  
  747.  
  748. static int ili9341_remove(struct platform_device *device)
  749. {
  750. struct fb_info *info = platform_get_drvdata(device);
  751. struct ili9341 *item = (struct ili9341 *)info->par;
  752. if (info) {
  753. unregister_framebuffer(info);
  754. ili9341_pages_free(item);
  755. ili9341_video_free(item);
  756. framebuffer_release(info);
  757. kfree(item);
  758. }
  759. return 0;
  760. }
  761.  
  762.  
  763.  
  764. static struct platform_driver ili9341_driver = {
  765. .probe = ili9341_probe,
  766. .remove = ili9341_remove,
  767. .driver = {
  768. .name = "ili9341",
  769. },
  770. };
  771.  
  772. static int __init ili9341_init(void)
  773. {
  774. int ret = 0;
  775.  
  776. pr_debug("%s\n", __func__);
  777.  
  778. ret = platform_driver_register(&ili9341_driver);
  779.  
  780. if (ret) {
  781. pr_err("%s: unable to platform_driver_register\n", __func__);
  782. }
  783.  
  784. ret = platform_device_register(&ili9341_device);
  785.  
  786. if (ret) {
  787. pr_err("%s: unable to platform_device_register\n", __func__);
  788. }
  789.  
  790. return ret;
  791. }
  792.  
  793. module_init(ili9341_init);
  794.  
  795. MODULE_LICENSE("GPL v2");
  796. MODULE_AUTHOR("Alex Nikitenko, for QibiTech Inc., alex.nikitenko@sirinsoftware.com");
  797. MODULE_DESCRIPTION("Framebuffer Driver for PiTFT with ILI9341");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement