Merge remote-tracking branch 'origin/develop-3.0' into develop-3.0-jb
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rkfb_sysfs.c
1 /*
2  * linux/drivers/video/rockchip/rkfb-sysfs.c
3  *
4  * Copyright (C) 2012 Rockchip Corporation
5  * Author: yxj<yxj@rock-chips.com>
6  *
7  * Some code and ideas taken from 
8  *drivers/video/omap2/omapfb/omapfb-sys.c
9  *driver by Tomi Valkeinen.
10  *
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License version 2 as published by
14  * the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19  * more details.
20  *
21  * You should have received a copy of the GNU General Public License along with
22  * this program.  If not, see <http://www.gnu.org/licenses/>.
23  */
24
25 #include <linux/fb.h>
26 #include <linux/sysfs.h>
27 #include <linux/device.h>
28 #include <linux/uaccess.h>
29 #include <linux/platform_device.h>
30 #include <linux/kernel.h>
31 #include <linux/mm.h>
32 #include <asm/div64.h>
33 #include <linux/rk_screen.h>
34 #include <linux/rk_fb.h>
35
36
37 static ssize_t show_screen_info(struct device *dev,
38                 struct device_attribute *attr, char *buf)
39 {
40         struct fb_info *fbi = dev_get_drvdata(dev);
41         struct rk_lcdc_device_driver * dev_drv = 
42                 (struct rk_lcdc_device_driver * )fbi->par;
43         rk_screen * screen = dev_drv->screen;
44         int fps;
45         u64 ft = (u64)(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
46                 (screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len)*
47                 (dev_drv->pixclock);       // one frame time ,(pico seconds)
48         fps = div64_u64(1000000000000llu,ft);
49         return snprintf(buf, PAGE_SIZE,"xres:%d\nyres:%d\nfps:%d\n",
50                 screen->x_res,screen->y_res,fps);
51 }
52
53 static ssize_t show_disp_info(struct device *dev,
54                 struct device_attribute *attr, char *buf)
55 {
56         struct fb_info *fbi = dev_get_drvdata(dev);
57         struct rk_lcdc_device_driver * dev_drv = 
58                 (struct rk_lcdc_device_driver * )fbi->par;
59         int layer_id = dev_drv->fb_get_layer(dev_drv,fbi->fix.id);
60         if(dev_drv->get_disp_info)
61                 dev_drv->get_disp_info(dev_drv,layer_id);
62
63         return 0;
64 }
65
66 static ssize_t show_phys(struct device *dev,
67                 struct device_attribute *attr, char *buf)
68 {
69         struct fb_info *fbi = dev_get_drvdata(dev);
70         return snprintf(buf, PAGE_SIZE, "0x%lx-----0x%x\n",
71                 fbi->fix.smem_start,fbi->fix.smem_len);
72 }
73
74 static ssize_t show_virt(struct device *dev,
75                 struct device_attribute *attr, char *buf)
76 {
77         struct fb_info *fbi = dev_get_drvdata(dev);
78
79         return snprintf(buf, PAGE_SIZE, "0x%p-----0x%x\n",
80                 fbi->screen_base,fbi->fix.smem_len);
81 }
82
83 static ssize_t show_fb_state(struct device *dev,
84                 struct device_attribute *attr, char *buf)
85 {
86         struct fb_info *fbi = dev_get_drvdata(dev);
87         struct rk_lcdc_device_driver * dev_drv = 
88                 (struct rk_lcdc_device_driver * )fbi->par;
89         int layer_id = dev_drv->fb_get_layer(dev_drv,fbi->fix.id);
90         int state = dev_drv->get_layer_state(dev_drv,layer_id);
91         return snprintf(buf, PAGE_SIZE, "%s\n",state?"enabled":"disabled");
92         
93 }
94 static ssize_t set_fb_state(struct device *dev,struct device_attribute *attr,
95         const char *buf, size_t count)
96 {
97         struct fb_info *fbi = dev_get_drvdata(dev);
98         struct rk_lcdc_device_driver * dev_drv = 
99                 (struct rk_lcdc_device_driver * )fbi->par;
100         int layer_id = dev_drv->fb_get_layer(dev_drv,fbi->fix.id);
101         int state;
102         int ret;
103         ret = kstrtoint(buf, 0, &state);
104         if(ret)
105         {
106                 return ret;
107         }
108         dev_drv->open(dev_drv,layer_id,state);
109         return count;
110 }
111
112 static ssize_t show_overlay(struct device *dev,
113                 struct device_attribute *attr, char *buf)
114 {
115         struct fb_info *fbi = dev_get_drvdata(dev);
116         struct rk_lcdc_device_driver * dev_drv = 
117                 (struct rk_lcdc_device_driver * )fbi->par;
118         int ovl;
119         ovl =  dev_drv->ovl_mgr(dev_drv,0,0);
120         if(ovl < 0)
121         {
122                 return ovl;
123         }
124
125         return snprintf(buf, PAGE_SIZE, "%s\n",
126                 ovl?"win0 on the top of win1":"win1 on the top of win0");
127         
128 }
129 static ssize_t set_overlay(struct device *dev,struct device_attribute *attr,
130         const char *buf, size_t count)
131 {
132         struct fb_info *fbi = dev_get_drvdata(dev);
133         struct rk_lcdc_device_driver * dev_drv = 
134                 (struct rk_lcdc_device_driver * )fbi->par;
135         int ovl;
136         int ret;
137         ret = kstrtoint(buf, 0, &ovl);
138         if(ret)
139         {
140                 return ret;
141         }
142         ret = dev_drv->ovl_mgr(dev_drv,ovl,1);
143         if(ret < 0)
144         {
145                 return ret;
146         }
147
148         return count;
149 }
150
151
152 static ssize_t show_fps(struct device *dev,
153                 struct device_attribute *attr, char *buf)
154 {
155         struct fb_info *fbi = dev_get_drvdata(dev);
156         struct rk_lcdc_device_driver * dev_drv = 
157                 (struct rk_lcdc_device_driver * )fbi->par;
158         int fps;
159         fps =  dev_drv->fps_mgr(dev_drv,0,0);
160         if(fps < 0)
161         {
162                 return fps;
163         }
164
165         return snprintf(buf, PAGE_SIZE, "fps:%d\n",fps);
166         
167 }
168
169 static ssize_t set_fps(struct device *dev,struct device_attribute *attr,
170         const char *buf, size_t count)
171 {
172         struct fb_info *fbi = dev_get_drvdata(dev);
173         struct rk_lcdc_device_driver * dev_drv = 
174                 (struct rk_lcdc_device_driver * )fbi->par;
175         int fps;
176         int ret;
177         ret = kstrtoint(buf, 0, &fps);
178         if(ret)
179         {
180                 return ret;
181         }
182         ret = dev_drv->fps_mgr(dev_drv,fps,1);
183         if(ret < 0)
184         {
185                 return ret;
186         }
187
188         return count;
189 }
190
191 static ssize_t show_fb_win_map(struct device *dev,
192                 struct device_attribute *attr, char *buf)
193 {
194         int ret;
195         struct fb_info *fbi = dev_get_drvdata(dev);
196         struct rk_lcdc_device_driver * dev_drv = 
197                 (struct rk_lcdc_device_driver * )fbi->par;
198
199         mutex_lock(&dev_drv->fb_win_id_mutex);
200         ret = snprintf(buf, PAGE_SIZE,"fb0:win%d\nfb1:win%d\nfb2:win%d\n",dev_drv->fb0_win_id,dev_drv->fb1_win_id,
201                 dev_drv->fb2_win_id);
202         mutex_unlock(&dev_drv->fb_win_id_mutex);
203
204         return ret;
205         
206 }
207
208 static ssize_t set_fb_win_map(struct device *dev,struct device_attribute *attr,
209         const char *buf, size_t count)
210 {
211         struct fb_info *fbi = dev_get_drvdata(dev);
212         struct rk_lcdc_device_driver * dev_drv = 
213                 (struct rk_lcdc_device_driver * )fbi->par;
214         int order;
215         int ret;
216         ret = kstrtoint(buf, 0, &order);
217         if((order != FB0_WIN2_FB1_WIN1_FB2_WIN0) && (order != FB0_WIN1_FB1_WIN2_FB2_WIN0 ) &&
218            (order != FB0_WIN2_FB1_WIN0_FB2_WIN1) && (order != FB0_WIN0_FB1_WIN2_FB2_WIN1 ) &&
219            (order != FB0_WIN0_FB1_WIN1_FB2_WIN2) && (order != FB0_WIN1_FB1_WIN0_FB2_WIN2 ))
220         {
221                 printk(KERN_ERR "un support map\nyou can use the following order: \
222                         \n201:\nfb0-win1\nfb1-win0\nfb2-win2\n                     \
223                         \n210:\nfb0-win0\nfb1-win1\nfb2-win2\n                    \
224                         \n120:\nfb0-win0\nfb1-win2\nfb2-win1\n                    \
225                         \n102:\nfb0-win2\nfb1-win0\nfb2-win1\n                     \
226                         \n021:\nfb0-win1\nfb1-win2\nfb2-win0\n                     \
227                         \n012:\nfb0-win2\nfb1-win1\nfb2-win0\n");
228                 return count;
229         }
230         else
231         {
232                 dev_drv->fb_layer_remap(dev_drv,order);
233         }
234
235         return count;
236         
237         
238 }
239
240 static struct device_attribute rkfb_attrs[] = {
241         __ATTR(phys_addr, S_IRUGO, show_phys, NULL),
242         __ATTR(virt_addr, S_IRUGO, show_virt, NULL),
243         __ATTR(disp_info, S_IRUGO, show_disp_info, NULL),
244         __ATTR(screen_info, S_IRUGO, show_screen_info, NULL),
245         __ATTR(enable, S_IRUGO | S_IWUSR, show_fb_state, set_fb_state),
246         __ATTR(overlay, S_IRUGO | S_IWUSR, show_overlay, set_overlay),
247         __ATTR(fps, S_IRUGO | S_IWUSR, show_fps, set_fps),
248         __ATTR(map, S_IRUGO | S_IWUSR, show_fb_win_map, set_fb_win_map),
249 };
250
251 int rkfb_create_sysfs(struct fb_info *fbi)
252 {
253         int r;
254         int t;
255         for (t = 0; t < ARRAY_SIZE(rkfb_attrs); t++)
256         {
257                 r = device_create_file(fbi->dev,&rkfb_attrs[t]);
258                 if (r)
259                 {
260                         dev_err(fbi->dev, "failed to create sysfs "
261                                         "file\n");
262                         return r;
263                 }
264         }
265         
266
267         return 0;
268 }
269
270 void rkfb_remove_sysfs(struct rk_fb_inf *inf)
271 {
272         int i, t;
273
274         for (i = 0; i < inf->num_fb; i++) {
275                 for (t = 0; t < ARRAY_SIZE(rkfb_attrs); t++)
276                         device_remove_file(inf->fb[i]->dev,
277                                         &rkfb_attrs[t]);
278         }
279 }
280