rk30 hdmi:
authorZheng Yang <zhengyang@rock-chips.com>
Wed, 2 May 2012 12:11:46 +0000 (20:11 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Wed, 2 May 2012 12:11:46 +0000 (20:11 +0800)
1. Add sysfs interface to scale hdmi output picture size.
2. When hdmi was removed, disable the source lcdc.

drivers/video/display/display-sys.c
drivers/video/rockchip/hdmi/rk30_hdmi.c
drivers/video/rockchip/hdmi/rk30_hdmi.h
drivers/video/rockchip/hdmi/rk30_hdmi_hw.c
drivers/video/rockchip/hdmi/rk30_hdmi_lcdc.c
drivers/video/rockchip/hdmi/rk30_hdmi_sysfs.c
drivers/video/rockchip/hdmi/rk30_hdmi_task.c
include/linux/display-sys.h [changed mode: 0644->0755]

index ef8d665cb6469682a1ea4f4de073c32003adb4f6..a0e245ec2bead8c95908990623fc963a0838c519 100755 (executable)
@@ -148,6 +148,47 @@ static ssize_t display_store_mode(struct device *dev,
        return -EINVAL;
 }
 
+static ssize_t display_show_scale(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct rk_display_device *dsp = dev_get_drvdata(dev);
+       int xscale, yscale;
+       
+       if(dsp->ops && dsp->ops->getscale) {
+               xscale = dsp->ops->getscale(dsp, DISPLAY_SCALE_X);
+               yscale = dsp->ops->getscale(dsp, DISPLAY_SCALE_Y);
+               if(xscale && yscale)
+                       return snprintf(buf, PAGE_SIZE, "xscale=%d yscale=%d\n", xscale, yscale);
+       }
+       return -EINVAL;
+}
+
+static ssize_t display_store_scale(struct device *dev, 
+                                               struct device_attribute *attr,
+                                               const char *buf, size_t count)
+{
+       struct rk_display_device *dsp = dev_get_drvdata(dev);
+       int scale = 100;
+       
+       if(dsp->ops && dsp->ops->setscale) {
+               if(!strncmp(buf, "xscale", 6)) {
+                       sscanf(buf, "xscale=%d", &scale);
+                       dsp->ops->setscale(dsp, DISPLAY_SCALE_X, scale);
+               }
+               else if(!strncmp(buf, "yscale", 6)) {
+                       sscanf(buf, "yscale=%d", &scale);
+                       dsp->ops->setscale(dsp, DISPLAY_SCALE_Y, scale);
+               }
+               else {
+                       sscanf(buf, "%d", &scale);
+                       dsp->ops->setscale(dsp, DISPLAY_SCALE_X, scale);
+                       dsp->ops->setscale(dsp, DISPLAY_SCALE_Y, scale);
+               }
+               return count;
+       }
+       return -EINVAL;
+}
+
 static struct device_attribute display_attrs[] = {
        __ATTR(name, S_IRUGO, display_show_name, NULL),
        __ATTR(type, S_IRUGO, display_show_type, NULL),
@@ -155,6 +196,7 @@ static struct device_attribute display_attrs[] = {
        __ATTR(connect, S_IRUGO, display_show_connect, NULL),
        __ATTR(modes, S_IRUGO, display_show_modes, NULL),
        __ATTR(mode, 0664, display_show_mode, display_store_mode),
+       __ATTR(scale, 0664, display_show_scale, display_store_scale),
        __ATTR_NULL
 };
 
index ef50f282d87a172c269eceedf961391b9d1264ea..50c9b6783a6c5956a81c7c94791fa330f51360af 100755 (executable)
@@ -109,7 +109,9 @@ static int __devinit rk30_hdmi_probe (struct platform_device *pdev)
                ret = -ENXIO;\r
                goto err0;\r
        }\r
-\r
+       hdmi->xscale = 95;\r
+       hdmi->yscale = 95;\r
+       \r
        hdmi->hclk = clk_get(NULL,"hclk_hdmi");\r
        if(IS_ERR(hdmi->hclk))\r
        {\r
index 7e57f8fc4e259a23162c376f712f262868f2cb5c..f59b887b89b5e4e3ce6474ce76354327ce385c2d 100755 (executable)
@@ -75,7 +75,9 @@ struct hdmi {
        int state;                                      // hdmi state machine status
        int autoconfig;                         // if true, auto config hdmi output mode according to EDID.
        int command;                            // HDMI configuration command
-       int display;                            // HDMI display status  
+       int display;                            // HDMI display status
+       int xscale;                                     // x direction scale value
+       int yscale;                                     // y directoon scale value
 };
 
 extern struct hdmi *hdmi;
index f3c2a3482af07a969efb2b1de1506e2a904865ff..0c3bf081272a64c84d12e842b1a3251a4cdeafb6 100755 (executable)
@@ -116,7 +116,7 @@ int rk30_hdmi_read_edid(int block, unsigned char *buff)
        }
        // Disable edid interrupt
        HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS);
-       msleep(100);
+//     msleep(100);
        return ret;
 }
 
index a12ce060bd20509cfe654c21584fcb8dbb0bdac3..406837e2e20063d14d339691ce2114a9f4668754 100755 (executable)
@@ -507,6 +507,7 @@ int hdmi_switch_fb(struct hdmi *hdmi, int vic)
 
        if(rc == 0) {           
                rk_fb_switch_screen(hdmi->lcdc->screen, 1, HDMI_SOURCE_DEFAULT);
+               rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, HDMI_SOURCE_DEFAULT);
        }
        return rc;
 }
index 873562687d09e2f781860c8d686249b81f68ff50..f811cbabfeb805adaa6a0f8c6ba33eace28a5d17 100755 (executable)
@@ -99,6 +99,38 @@ static int hdmi_get_mode(struct rk_display_device *device, struct fb_videomode *
        return 0;
 }
 
+static int hdmi_set_scale(struct rk_display_device *device, int direction, int value)
+{
+       struct hdmi *hdmi = device->priv_data;
+       
+       if(!hdmi || value < 0 || value > 100)
+               return -1;
+                       
+       if(direction == DISPLAY_SCALE_X)
+               hdmi->xscale = value;
+       else if(direction == DISPLAY_SCALE_Y)
+               hdmi->yscale = value;
+       else
+               return -1;
+       rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, HDMI_SOURCE_DEFAULT);
+       return 0;
+}
+
+static int hdmi_get_scale(struct rk_display_device *device, int direction)
+{
+       struct hdmi *hdmi = device->priv_data;
+       
+       if(!hdmi)
+               return -1;
+               
+       if(direction == DISPLAY_SCALE_X)
+               return hdmi->xscale;
+       else if(direction == DISPLAY_SCALE_Y)
+               return hdmi->yscale;
+       else
+               return -1;
+}
+
 struct rk_display_ops hdmi_display_ops = {
        .setenable = hdmi_set_enable,
        .getenable = hdmi_get_enable,
@@ -106,6 +138,8 @@ struct rk_display_ops hdmi_display_ops = {
        .getmodelist = hdmi_get_modelist,
        .setmode = hdmi_set_mode,
        .getmode = hdmi_get_mode,
+       .setscale = hdmi_set_scale,
+       .getscale = hdmi_get_scale,
 };
 
 #if 1
index 04e46a7c8951afea9353be14a21c68897adcb9d9..03a9b63a80f046effd183420ff5762a7e8e65628 100755 (executable)
@@ -78,6 +78,7 @@ void hdmi_sys_remove(void)
        memset(&hdmi->edid, 0, sizeof(struct hdmi_edid));
        INIT_LIST_HEAD(&hdmi->edid.modelist);
        hdmi->display   = HDMI_DISABLE;
+       rk_fb_switch_screen(hdmi->lcdc->screen, 0, HDMI_SOURCE_DEFAULT);
        kobject_uevent_env(&hdmi->dev->kobj, KOBJ_REMOVE, envp);
        #ifdef CONFIG_SWITCH
        switch_set_state(&(hdmi->switch_hdmi), 0);
old mode 100644 (file)
new mode 100755 (executable)
index 6eb0080..579af11
@@ -15,6 +15,11 @@ enum rk_display_priority {
        DISPLAY_PRIORITY_LCD,
 };
 
+enum {
+       DISPLAY_SCALE_X = 0,
+       DISPLAY_SCALE_Y
+};
+
 /* This structure defines all the properties of a Display. */
 struct rk_display_driver {
        void (*suspend)(struct rk_display_device *, pm_message_t state);
@@ -30,6 +35,8 @@ struct rk_display_ops {
        int (*getmodelist)(struct rk_display_device *, struct list_head **modelist);
        int (*setmode)(struct rk_display_device *, struct fb_videomode *mode);
        int (*getmode)(struct rk_display_device *, struct fb_videomode *mode);
+       int (*setscale)(struct rk_display_device *, int, int);
+       int (*getscale)(struct rk_display_device *, int);
 };
 
 struct rk_display_device {