From: Zheng Yang Date: Wed, 2 May 2012 12:11:46 +0000 (+0800) Subject: rk30 hdmi: X-Git-Tag: firefly_0821_release~9271 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=01d1e48695d15203d7c0d83b3ef45d22e93d60bb;p=firefly-linux-kernel-4.4.55.git rk30 hdmi: 1. Add sysfs interface to scale hdmi output picture size. 2. When hdmi was removed, disable the source lcdc. --- diff --git a/drivers/video/display/display-sys.c b/drivers/video/display/display-sys.c index ef8d665cb646..a0e245ec2bea 100755 --- a/drivers/video/display/display-sys.c +++ b/drivers/video/display/display-sys.c @@ -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 }; diff --git a/drivers/video/rockchip/hdmi/rk30_hdmi.c b/drivers/video/rockchip/hdmi/rk30_hdmi.c index ef50f282d87a..50c9b6783a6c 100755 --- a/drivers/video/rockchip/hdmi/rk30_hdmi.c +++ b/drivers/video/rockchip/hdmi/rk30_hdmi.c @@ -109,7 +109,9 @@ static int __devinit rk30_hdmi_probe (struct platform_device *pdev) ret = -ENXIO; goto err0; } - + hdmi->xscale = 95; + hdmi->yscale = 95; + hdmi->hclk = clk_get(NULL,"hclk_hdmi"); if(IS_ERR(hdmi->hclk)) { diff --git a/drivers/video/rockchip/hdmi/rk30_hdmi.h b/drivers/video/rockchip/hdmi/rk30_hdmi.h index 7e57f8fc4e25..f59b887b89b5 100755 --- a/drivers/video/rockchip/hdmi/rk30_hdmi.h +++ b/drivers/video/rockchip/hdmi/rk30_hdmi.h @@ -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; diff --git a/drivers/video/rockchip/hdmi/rk30_hdmi_hw.c b/drivers/video/rockchip/hdmi/rk30_hdmi_hw.c index f3c2a3482af0..0c3bf081272a 100755 --- a/drivers/video/rockchip/hdmi/rk30_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/rk30_hdmi_hw.c @@ -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; } diff --git a/drivers/video/rockchip/hdmi/rk30_hdmi_lcdc.c b/drivers/video/rockchip/hdmi/rk30_hdmi_lcdc.c index a12ce060bd20..406837e2e200 100755 --- a/drivers/video/rockchip/hdmi/rk30_hdmi_lcdc.c +++ b/drivers/video/rockchip/hdmi/rk30_hdmi_lcdc.c @@ -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; } diff --git a/drivers/video/rockchip/hdmi/rk30_hdmi_sysfs.c b/drivers/video/rockchip/hdmi/rk30_hdmi_sysfs.c index 873562687d09..f811cbabfeb8 100755 --- a/drivers/video/rockchip/hdmi/rk30_hdmi_sysfs.c +++ b/drivers/video/rockchip/hdmi/rk30_hdmi_sysfs.c @@ -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 diff --git a/drivers/video/rockchip/hdmi/rk30_hdmi_task.c b/drivers/video/rockchip/hdmi/rk30_hdmi_task.c index 04e46a7c8951..03a9b63a80f0 100755 --- a/drivers/video/rockchip/hdmi/rk30_hdmi_task.c +++ b/drivers/video/rockchip/hdmi/rk30_hdmi_task.c @@ -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); diff --git a/include/linux/display-sys.h b/include/linux/display-sys.h old mode 100644 new mode 100755 index 6eb0080398e0..579af11cc345 --- a/include/linux/display-sys.h +++ b/include/linux/display-sys.h @@ -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 {