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);
}
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)
{
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;
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);
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;
.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,
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;i<rr->buffer_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 = {
/* 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);
#include <linux/types.h>
#include <linux/v4l2-subdev.h>
+#include <linux/fb.h>
#include <media/media-entity.h>
#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
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);
/* #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 */
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