rk30 hdmi:

1. Add sysfs interface to scale hdmi output picture size.
	2. When hdmi was removed, disable the source lcdc.
This commit is contained in:
Zheng Yang
2012-05-02 20:11:46 +08:00
parent e691eb848c
commit 01d1e48695
8 changed files with 92 additions and 3 deletions

View File

@@ -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
};

View File

@@ -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))
{

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);

7
include/linux/display-sys.h Normal file → Executable file
View File

@@ -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 {