2 * linux/drivers/video/rockchip/rkfb-sysfs.c
4 * Copyright (C) 2012 Rockchip Corporation
5 * Author: yxj<yxj@rock-chips.com>
7 * Some code and ideas taken from
8 *drivers/video/omap2/omapfb/omapfb-sys.c
9 *driver by Tomi Valkeinen.
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.
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
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/>.
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>
32 #include <asm/div64.h>
33 #include <linux/rk_screen.h>
34 #include <linux/rk_fb.h>
37 static ssize_t show_screen_info(struct device *dev,
38 struct device_attribute *attr, char *buf)
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->screen0;
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);
53 static ssize_t show_disp_info(struct device *dev,
54 struct device_attribute *attr, char *buf)
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 return dev_drv->get_disp_info(dev_drv,buf,layer_id);
66 static ssize_t show_phys(struct device *dev,
67 struct device_attribute *attr, char *buf)
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);
74 static ssize_t show_virt(struct device *dev,
75 struct device_attribute *attr, char *buf)
77 struct fb_info *fbi = dev_get_drvdata(dev);
79 return snprintf(buf, PAGE_SIZE, "0x%p-----0x%x\n",
80 fbi->screen_base,fbi->fix.smem_len);
83 static ssize_t show_fb_state(struct device *dev,
84 struct device_attribute *attr, char *buf)
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");
95 static ssize_t show_dual_mode(struct device *dev,
96 struct device_attribute *attr, char *buf)
99 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
101 #elif defined(CONFIG_DUAL_LCDC_DUAL_DISP_IN_KERNEL)
106 return snprintf(buf, PAGE_SIZE, "%d\n",mode);
110 static ssize_t set_fb_state(struct device *dev,struct device_attribute *attr,
111 const char *buf, size_t count)
113 struct fb_info *fbi = dev_get_drvdata(dev);
114 struct rk_lcdc_device_driver * dev_drv =
115 (struct rk_lcdc_device_driver * )fbi->par;
116 int layer_id = dev_drv->fb_get_layer(dev_drv,fbi->fix.id);
119 ret = kstrtoint(buf, 0, &state);
124 dev_drv->open(dev_drv,layer_id,state);
128 static ssize_t show_overlay(struct device *dev,
129 struct device_attribute *attr, char *buf)
131 struct fb_info *fbi = dev_get_drvdata(dev);
132 struct rk_lcdc_device_driver * dev_drv =
133 (struct rk_lcdc_device_driver * )fbi->par;
135 ovl = dev_drv->ovl_mgr(dev_drv,0,0);
141 return snprintf(buf, PAGE_SIZE, "%s\n",
142 ovl?"win0 on the top of win1":"win1 on the top of win0");
145 static ssize_t set_overlay(struct device *dev,struct device_attribute *attr,
146 const char *buf, size_t count)
148 struct fb_info *fbi = dev_get_drvdata(dev);
149 struct rk_lcdc_device_driver * dev_drv =
150 (struct rk_lcdc_device_driver * )fbi->par;
153 ret = kstrtoint(buf, 0, &ovl);
158 ret = dev_drv->ovl_mgr(dev_drv,ovl,1);
168 static ssize_t show_fps(struct device *dev,
169 struct device_attribute *attr, char *buf)
171 struct fb_info *fbi = dev_get_drvdata(dev);
172 struct rk_lcdc_device_driver * dev_drv =
173 (struct rk_lcdc_device_driver * )fbi->par;
175 fps = dev_drv->fps_mgr(dev_drv,0,0);
181 return snprintf(buf, PAGE_SIZE, "fps:%d\n",fps);
185 static ssize_t set_fps(struct device *dev,struct device_attribute *attr,
186 const char *buf, size_t count)
188 struct fb_info *fbi = dev_get_drvdata(dev);
189 struct rk_lcdc_device_driver * dev_drv =
190 (struct rk_lcdc_device_driver * )fbi->par;
193 ret = kstrtoint(buf, 0, &fps);
198 ret = dev_drv->fps_mgr(dev_drv,fps,1);
207 static ssize_t show_fb_win_map(struct device *dev,
208 struct device_attribute *attr, char *buf)
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;
215 mutex_lock(&dev_drv->fb_win_id_mutex);
216 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,
217 dev_drv->fb2_win_id);
218 mutex_unlock(&dev_drv->fb_win_id_mutex);
224 static ssize_t set_fb_win_map(struct device *dev,struct device_attribute *attr,
225 const char *buf, size_t count)
227 struct fb_info *fbi = dev_get_drvdata(dev);
228 struct rk_lcdc_device_driver * dev_drv =
229 (struct rk_lcdc_device_driver * )fbi->par;
232 ret = kstrtoint(buf, 0, &order);
233 if((order != FB0_WIN2_FB1_WIN1_FB2_WIN0) && (order != FB0_WIN1_FB1_WIN2_FB2_WIN0 ) &&
234 (order != FB0_WIN2_FB1_WIN0_FB2_WIN1) && (order != FB0_WIN0_FB1_WIN2_FB2_WIN1 ) &&
235 (order != FB0_WIN0_FB1_WIN1_FB2_WIN2) && (order != FB0_WIN1_FB1_WIN0_FB2_WIN2 ))
237 printk(KERN_ERR "un support map\nyou can use the following order: \
238 \n201:\nfb0-win1\nfb1-win0\nfb2-win2\n \
239 \n210:\nfb0-win0\nfb1-win1\nfb2-win2\n \
240 \n120:\nfb0-win0\nfb1-win2\nfb2-win1\n \
241 \n102:\nfb0-win2\nfb1-win0\nfb2-win1\n \
242 \n021:\nfb0-win1\nfb1-win2\nfb2-win0\n \
243 \n012:\nfb0-win2\nfb1-win1\nfb2-win0\n");
248 dev_drv->fb_layer_remap(dev_drv,order);
256 static ssize_t show_dsp_lut(struct device *dev,
257 struct device_attribute *attr, char *buf)
261 static ssize_t set_dsp_lut(struct device *dev,struct device_attribute *attr,
262 const char *buf, size_t count)
269 struct fb_info *fbi = dev_get_drvdata(dev);
270 struct rk_lcdc_device_driver * dev_drv =
271 (struct rk_lcdc_device_driver * )fbi->par;
276 dsp_lut[i] = temp + (temp<<8) + (temp<<16); //init by default value
278 //printk("count:%d\n>>%s\n\n",count,start);
281 space_max = 10; //max space number 10;
282 temp = simple_strtoul(start,NULL,10);
288 }while ((*start != ' ')&&space_max);
299 printk("0x%08x ",dsp_lut[i*16+j]);
303 dev_drv->set_dsp_lut(dev_drv,dsp_lut);
309 static struct device_attribute rkfb_attrs[] = {
310 __ATTR(phys_addr, S_IRUGO, show_phys, NULL),
311 __ATTR(virt_addr, S_IRUGO, show_virt, NULL),
312 __ATTR(disp_info, S_IRUGO, show_disp_info, NULL),
313 __ATTR(screen_info, S_IRUGO, show_screen_info, NULL),
314 __ATTR(dual_mode, S_IRUGO, show_dual_mode, NULL),
315 __ATTR(enable, S_IRUGO | S_IWUSR, show_fb_state, set_fb_state),
316 __ATTR(overlay, S_IRUGO | S_IWUSR, show_overlay, set_overlay),
317 __ATTR(fps, S_IRUGO | S_IWUSR, show_fps, set_fps),
318 __ATTR(map, S_IRUGO | S_IWUSR, show_fb_win_map, set_fb_win_map),
319 __ATTR(dsp_lut, S_IRUGO | S_IWUSR, show_dsp_lut, set_dsp_lut),
322 int rkfb_create_sysfs(struct fb_info *fbi)
326 for (t = 0; t < ARRAY_SIZE(rkfb_attrs); t++)
328 r = device_create_file(fbi->dev,&rkfb_attrs[t]);
331 dev_err(fbi->dev, "failed to create sysfs "
341 void rkfb_remove_sysfs(struct rk_fb_inf *inf)
345 for (i = 0; i < inf->num_fb; i++) {
346 for (t = 0; t < ARRAY_SIZE(rkfb_attrs); t++)
347 device_remove_file(inf->fb[i]->dev,