From c6b2ec93f9e17263c770a08f56ef410fc3395ba1 Mon Sep 17 00:00:00 2001 From: xingbin Date: Sat, 13 Oct 2018 16:55:36 +0800 Subject: [PATCH] (CR):[Kane]:[factory]tcmd:add lcd disp_util function Change-Id: Ie594844617320a569757256c4a7a1b2c4786df1e Signed-off-by: xingbin --- drivers/video/fbdev/core/fbcmap.c | 30 +++++++++++ drivers/video/fbdev/core/fbmem.c | 52 +++++++++++++++++++ drivers/video/fbdev/exynos/dpu20/decon_core.c | 27 ++++++++++ drivers/video/fbdev/exynos/dpu20/dsim_drv.c | 38 ++++++++++++++ include/linux/fb.h | 2 + include/media/v4l2-subdev.h | 2 + include/uapi/linux/fb.h | 14 +++++ 7 files changed, 165 insertions(+) mode change 100644 => 100755 drivers/video/fbdev/core/fbcmap.c mode change 100644 => 100755 drivers/video/fbdev/core/fbmem.c mode change 100644 => 100755 drivers/video/fbdev/exynos/dpu20/decon_core.c mode change 100644 => 100755 drivers/video/fbdev/exynos/dpu20/dsim_drv.c mode change 100644 => 100755 include/linux/fb.h mode change 100644 => 100755 include/media/v4l2-subdev.h mode change 100644 => 100755 include/uapi/linux/fb.h diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c old mode 100644 new mode 100755 index e8ea76848104..d25c55bee77d --- a/drivers/video/fbdev/core/fbcmap.c +++ b/drivers/video/fbdev/core/fbcmap.c @@ -264,6 +264,36 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) return rc; } +int fb_user_to_kernel(struct fb_regrw_access_t_user *from_rw, struct fb_regrw_access_t **to_rw) +{ + int ret = 0; + printk("fb_user_to_kernel:user_rr.reg = 0x%x,user_rr.cnt = %d, user_rr.hs_mode = %d,user_rr.buf = 0x%8x\n",from_rw->address,from_rw->buffer_size,from_rw->use_hs_mode,from_rw->buffer); + + + *to_rw = kmalloc(sizeof(struct fb_regrw_access_t),GFP_KERNEL); + + if (to_rw == NULL) + return -ENOMEM; + + memset(*to_rw, 0, sizeof(struct fb_regrw_access_t)); + + + (*to_rw)->address = from_rw->address; + (*to_rw)->buffer_size = from_rw->buffer_size; + (*to_rw)->use_hs_mode = from_rw->use_hs_mode; + + (*to_rw)->buffer = kmalloc((*to_rw)->buffer_size*sizeof(__u8), GFP_KERNEL); + if(!((*to_rw)->buffer)) + return -ENOMEM; + + memset((*to_rw)->buffer, 0, (*to_rw)->buffer_size*sizeof(__u8)); + + if (copy_from_user((*to_rw)->buffer, from_rw->buffer, (*to_rw)->buffer_size*sizeof(__u8))) + return -ENOMEM; + + return ret; +} + int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) { int rc, size = cmap->len * sizeof(u16); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c old mode 100644 new mode 100755 index 9087d467cc46..78bc313c012e --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1104,6 +1104,17 @@ fb_blank(struct fb_info *info, int blank) } EXPORT_SYMBOL(fb_blank); +int +fb_read_reg(struct fb_info *info, struct fb_regrw_access_t *rr) +{ + int ret = 0; + + if (info->fbops->fb_read_reg) + ret = info->fbops->fb_read_reg(info, rr); + + return ret; +} + static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { @@ -1367,6 +1378,11 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, struct fb_ops *fb; long ret = -ENOIOCTLCMD; + struct fb_regrw_access_t *rr; + struct fb_regrw_access_t_user user_rr; + int copy_size = 0; + void __user *argp = (void __user *)arg; + if (!info) return -ENODEV; fb = info->fbops; @@ -1390,6 +1406,42 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, ret = fb_getput_cmap(info, cmd, arg); break; + case FB_RGER_IOCTL: + if (copy_from_user(&user_rr, argp, sizeof(user_rr))) + return -EFAULT; + if(user_rr.buffer_size<=0) + user_rr.buffer_size = 1; + if(user_rr.buffer_size>32) + user_rr.buffer_size = 32; + + fb_user_to_kernel(&user_rr,&rr); + if(rr==NULL){ + printk("rr is null\n"); + return -EFAULT; + } + console_lock(); + if (!lock_fb_info(info)) { + console_unlock(); + kfree(rr->buffer); + kfree(rr); + return -ENODEV; + } + if(fb_read_reg(info, rr)) + { + unlock_fb_info(info); + console_unlock(); + kfree(rr->buffer); + kfree(rr); + return -ENODEV; + } + unlock_fb_info(info); + console_unlock(); + copy_size = (0==user_rr.buffer_size*sizeof(__u8)%4) ? user_rr.buffer_size*sizeof(__u8) : user_rr.buffer_size*sizeof(__u8) + (4 - user_rr.buffer_size*sizeof(__u8)%4); + ret = copy_to_user(user_rr.buffer, rr->buffer, copy_size) ? -EFAULT : 0; + kfree(rr->buffer); + kfree(rr); + break; + default: if (fb->fb_compat_ioctl) ret = fb->fb_compat_ioctl(info, cmd, arg); diff --git a/drivers/video/fbdev/exynos/dpu20/decon_core.c b/drivers/video/fbdev/exynos/dpu20/decon_core.c old mode 100644 new mode 100755 index 997775f06e66..fa12f6eda9cf --- a/drivers/video/fbdev/exynos/dpu20/decon_core.c +++ b/drivers/video/fbdev/exynos/dpu20/decon_core.c @@ -3116,6 +3116,32 @@ static ssize_t decon_fb_write(struct fb_info *info, const char __user *buf, return 0; } +static int decon_fb_read_reg(struct fb_info *info, struct fb_regrw_access_t *rr) +{ + struct decon_win *win = info->par; + struct decon_device *decon = win->decon; + + int ret = 0; + int i = 0; + int num_dsi = (decon->dt.dsi_mode == DSI_MODE_DUAL_DSI) ? 2 : 1; + + decon_err("%s in\n",__func__); + + if (DECON_STATE_OFF == decon->state) { + decon_err("lcd has suspend already,couldn't support reg read/write\n"); + return -EFAULT; + } + for (i = 0; i < num_dsi; i++) { + ret = v4l2_subdev_call(decon->out_sd[i], video, reg_read, rr); + if (ret) { + decon_err("stopping stream failed for %s,ret = %d\n", + decon->out_sd[i]->name,ret); + } + } + + return ret; +} + int decon_release(struct fb_info *info, int user) { struct decon_win *win = info->par; @@ -3171,6 +3197,7 @@ static struct fb_ops decon_fb_ops = { .fb_ioctl = decon_ioctl, .fb_read = decon_fb_read, .fb_write = decon_fb_write, + .fb_read_reg = decon_fb_read_reg, .fb_pan_display = decon_pan_display, .fb_mmap = decon_mmap, .fb_release = decon_release, diff --git a/drivers/video/fbdev/exynos/dpu20/dsim_drv.c b/drivers/video/fbdev/exynos/dpu20/dsim_drv.c old mode 100644 new mode 100755 index 9c409c6ebbb3..3e24f4e54d9f --- a/drivers/video/fbdev/exynos/dpu20/dsim_drv.c +++ b/drivers/video/fbdev/exynos/dpu20/dsim_drv.c @@ -1163,12 +1163,50 @@ static long dsim_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return ret; } +static int dsim_reg_read(struct v4l2_subdev *sd, struct fb_regrw_access_t *rr) +{ + int ret = 0; + u32 dsi_package_type = 0; + int i = 0; + + struct dsim_device *dsim = container_of(sd, struct dsim_device, sd); + dsim_err("dsim_reg_read:read reg addr = 0x%x,rw_cnt = %d,use_hs_mode = %d!\n",rr->address,rr->buffer_size,rr->use_hs_mode); + + switch (rr->buffer_size) { + case 0: + case 1: + case 2: + dsi_package_type = MIPI_DSI_DCS_READ; + break; + default: + dsi_package_type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; + break; + } + dsi_package_type = MIPI_DSI_DCS_READ; + /* dsim sends the request for the lcd id and gets it buffer */ + ret = dsim_read_data(dsim, dsi_package_type, + rr->address, rr->buffer_size, rr->buffer); + + if (ret < 0){ + dsim_err("%s:Failed to read panel reg!\n",__func__); + }else{ + dsim_info("%s:Suceeded to read panel reg :0x%x = 0x%x\n",__func__,rr->address,rr->buffer); + ret = 0; + } + + for(i=0;ibuffer_size;i++) + dsim_err("dsim_reg_read@@@@@@@@@@@:rr.buf[%d]=0x%x!\n",i,rr->buffer[i]); + + return ret; +} + static const struct v4l2_subdev_core_ops dsim_sd_core_ops = { .ioctl = dsim_ioctl, }; static const struct v4l2_subdev_video_ops dsim_sd_video_ops = { .s_stream = dsim_s_stream, + .reg_read = dsim_reg_read, }; static const struct v4l2_subdev_ops dsim_subdev_ops = { diff --git a/include/linux/fb.h b/include/linux/fb.h old mode 100644 new mode 100755 index ccd1f74ca6ab..2535da462b5e --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -283,6 +283,8 @@ struct fb_ops { /* blank display */ int (*fb_blank)(int blank, struct fb_info *info); + /* display read */ + int (*fb_read_reg)(struct fb_info *info, struct fb_regrw_access_t *rr); /* pan display */ int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h old mode 100644 new mode 100755 index f825f1d006c7..4824c7b20ff8 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -403,6 +404,7 @@ struct v4l2_subdev_video_ops { int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std); int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); int (*s_stream)(struct v4l2_subdev *sd, int enable); + int (*reg_read)(struct v4l2_subdev *sd, struct fb_regrw_access_t *rr); int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect); int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h old mode 100644 new mode 100755 index 6cd9b198b7c6..8aa88c200eca --- a/include/uapi/linux/fb.h +++ b/include/uapi/linux/fb.h @@ -24,6 +24,7 @@ /* #define FBIOGET_MONITORSPEC 0x460C */ /* #define FBIOPUT_MONITORSPEC 0x460D */ /* #define FBIOSWITCH_MONIBIT 0x460E */ +#define FB_RGER_IOCTL 0xc00c6d40 #define FBIOGET_CON2FBMAP 0x460F #define FBIOPUT_CON2FBMAP 0x4610 #define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */ @@ -393,6 +394,19 @@ struct fb_cursor { struct fb_image image; /* Cursor image */ }; +struct fb_regrw_access_t { + __u8 address; + __u8 use_hs_mode; + __u32 buffer_size; + __u8 *buffer; +}; +struct fb_regrw_access_t_user { + __u8 address; + __u8 use_hs_mode; + __u32 buffer_size; + __u8 __user *buffer; +}; + #ifdef CONFIG_FB_BACKLIGHT /* Settings for the generic backlight code */ #define FB_BACKLIGHT_LEVELS 128 -- 2.20.1