mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
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:
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
7
include/linux/display-sys.h
Normal file → Executable 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 {
|
||||
|
||||
Reference in New Issue
Block a user