1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include "ili9341_fb.h"
6 #include "hal_iomux_haas1000.h"
7 
8 #include <stdio.h>
9 #include <sys/ioctl.h>
10 #include <fb.h>
11 #include <devicevfs/devicevfs.h>
12 
13 #define ILI9341_DEVICE_NAME "ili9341_fb"
14 
15 #define CLCD_WIDTH  (ILI9341_WIDTH)
16 #define CLCD_HEIGHT (ILI9341_HEIGHT)
17 
18 ili9341_dev_t dev_ili9341 = {0};
19 
20 struct drv_clcd_device {
21     uint32_t width;
22     uint32_t height;
23 
24     uint8_t *fb;
25 };
26 struct drv_clcd_device _lcd;
27 
28 static int ili9341_open(fb_info_t *info, int user);
29 static int ili9341_release(fb_info_t *info, int user);
30 static ssize_t ili9341_read(fb_info_t *info, char *buf, size_t count);
31 static ssize_t ili9341_write(fb_info_t *info, const char *buf, size_t count);
32 static int ili9341_blank(int blank, fb_info_t *info);
33 static int ili9341_pan_display(fb_var_screeninfo_t *var, fb_info_t *info);
34 static ili9341_ioctl(fb_info_t *info, unsigned int cmd, unsigned long arg);
35 static int ili9341_mmap(fb_info_t *info, size_t size);
36 
37 static const fb_ops_t ili9341_ops = {
38     .fb_open    = ili9341_open,
39     .fb_release    = ili9341_release,
40     .fb_read        = ili9341_read,
41     .fb_write       = ili9341_write,
42     .fb_pan_display    = ili9341_pan_display,
43     .fb_mmap    = ili9341_mmap,
44     .fb_sync    = NULL,
45     .fb_blank    = ili9341_blank,
46     .fb_ioctl    = ili9341_ioctl,
47 };
48 
49 
50 static const fb_fix_screeninfo_t ili9341_fix = {
51     .id         = ILI9341_DEVICE_NAME,
52     .xpanstep    = 0,
53     .ypanstep    = 0,
54     .ywrapstep    = 0,
55     .line_length    = 0,
56     .mmio_start    = 0,    /* Not implemented for char. special, so */
57     .mmio_len    = 0    /* these are set to 0 */
58 };
59 
60 
61 
ili9341_open(fb_info_t * info,int user)62 static int ili9341_open(fb_info_t *info, int user)
63 {
64     return 0;
65 }
66 
ili9341_release(fb_info_t * info,int user)67 static int ili9341_release(fb_info_t *info, int user)
68 {
69     return 0;
70 }
71 
ili9341_read(fb_info_t * info,char * buf,size_t count)72 static ssize_t ili9341_read(fb_info_t *info, char *buf, size_t count)
73 {
74     return 0;
75 }
76 
ili9341_write(fb_info_t * info,const char * buf,size_t count)77 static ssize_t ili9341_write(fb_info_t *info, const char *buf, size_t count)
78 {
79     return 0;
80 }
81 
ili9341_blank(int blank,fb_info_t * info)82 static int ili9341_blank(int blank, fb_info_t *info)
83 {
84     return 0;
85 }
86 
ili9341_pan_display(fb_var_screeninfo_t * var,fb_info_t * info)87 static int ili9341_pan_display(fb_var_screeninfo_t *var, fb_info_t *info)
88 {
89     printf("ili9341 pan display function:0xp\n", info->screen_buffer);
90 
91     ili9341_draw_frame(dev_ili9341, info->screen_buffer);
92     printf("ili9341_draw_frame done\n");
93 
94     return 0;
95 }
96 
ili9341_mmap(fb_info_t * info,size_t size)97 static int ili9341_mmap(fb_info_t *info, size_t size)
98 {
99     // AOS3.3 no need mmap buffer
100     return 0;
101 }
102 
ili9341_ioctl(fb_info_t * info,unsigned int cmd,unsigned long arg)103 static ili9341_ioctl(fb_info_t *info, unsigned int cmd, unsigned long arg)
104 {
105     int ret = 0;
106 
107     switch (cmd) {
108         case FBIO_WAITFORVSYNC:
109             // ret = aos_sem_wait((aos_sem_t *)&vsync_sem, AOS_WAIT_FOREVER);
110             // if (unlikely(ret)) {
111             //     printf("input semaphore wait err\n");
112             // }
113             break;
114         case FBIOPUT_PREFB_ADDR:
115             printf("fbioput buffer setting\n");
116             info->screen_buffer = (uint8_t *)arg;
117             printf("ili9341 ili9341_ioctl function:0xp\n", info->screen_buffer);
118             if (info->screen_buffer == NULL)
119                 return -ENOMEM;
120 
121             break;
122     }
123     return ret;
124 }
125 
126 
ili9341_fb_init(void)127 int ili9341_fb_init(void)
128 {
129     int ret = 0;
130 
131     // set fb params to init
132     dev_ili9341.spi_port = 0;
133     dev_ili9341.spi_freq = 26000000;
134     dev_ili9341.gpio_bgl_id = HAL_GPIO_PIN_P0_6;
135     dev_ili9341.gpio_dc_id = HAL_GPIO_PIN_P0_1;
136     dev_ili9341.gpio_reset_id = HAL_GPIO_PIN_P0_0;
137 
138     ili9341_hw_init(&dev_ili9341);
139 
140     // set rotation
141     ili9341_set_rotation(dev_ili9341, 90);
142 
143     // create fbdev params
144     fb_info_t *info = NULL;
145 
146     /* memset _lcd to zero */
147     memset(&_lcd, 0x0, sizeof(_lcd));
148 
149     _lcd.width  = CLCD_WIDTH;
150     _lcd.height = CLCD_HEIGHT;
151 
152     info = framebuffer_alloc(0);
153 
154     /*set var screeninfo*/
155     memset(&info->var, 0, sizeof(fb_var_screeninfo_t));
156     info->var.xres = _lcd.width;
157     info->var.yres = _lcd.height;
158     info->var.xres_virtual = _lcd.width;
159     info->var.yres_virtual = _lcd.height;
160     info->var.width = _lcd.width;
161     info->var.height = _lcd.height;
162     info->var.rotate = FB_ROTATE_UD; // rotate 0 degrees wiseclock
163 #ifdef RGB_888_FORMAT
164     info->var.bits_per_pixel = 4 * 8;
165 #endif
166 #ifdef RGB_565_FORMAT
167     info->var.bits_per_pixel = 2 * 8;
168 #endif
169     info->screen_size = info->var.xres * info->var.yres * info->var.bits_per_pixel / 8;
170     info->screen_base = _lcd.fb;
171     /*set fb ops function*/
172     info->fbops = &ili9341_ops;
173 
174     /*set fix screeninfo*/
175     info->fix = ili9341_fix;
176     info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8;
177 
178     ret = register_framebuffer(info);
179 
180     printf("ili9341 hardware_init %s\n", ret == 0 ? "success" : "fail");
181 
182     return ret;
183 }
184 
185 LEVEL1_DRIVER_ENTRY(ili9341_fb_init)
186