HDMI: support show edid status.

Use /sys/class/display/HDMI/debug node to
	show sink EDID status and raw status.

Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
This commit is contained in:
Zheng Yang 2015-05-21 13:45:22 +08:00
parent 57fc92cd71
commit 71e8a27d62
4 changed files with 54 additions and 11 deletions

View File

@ -123,7 +123,7 @@ static void hdmi_wq_set_video(struct hdmi *hdmi)
static void hdmi_wq_parse_edid(struct hdmi *hdmi)
{
struct hdmi_edid *pedid;
unsigned char *buff = NULL;
int rc = HDMI_ERROR_SUCESS, extendblock = 0, i, trytimes;
if (hdmi == NULL)
@ -136,8 +136,8 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi)
memset(pedid, 0, sizeof(struct hdmi_edid));
INIT_LIST_HEAD(&pedid->modelist);
buff = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL);
if (buff == NULL) {
pedid->raw[0] = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL);
if (pedid->raw[0] == NULL) {
dev_err(hdmi->dev,
"[%s] can not allocate memory for edid buff.\n",
__func__);
@ -154,15 +154,15 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi)
for (trytimes = 0; trytimes < 3; trytimes++) {
if (trytimes)
msleep(50);
memset(buff, 0 , HDMI_EDID_BLOCK_SIZE);
rc = hdmi->ops->getedid(hdmi, 0, buff);
memset(pedid->raw[0], 0 , HDMI_EDID_BLOCK_SIZE);
rc = hdmi->ops->getedid(hdmi, 0, pedid->raw[0]);
if (rc) {
dev_err(hdmi->dev,
"[HDMI] read edid base block error\n");
continue;
}
rc = hdmi_edid_parse_base(buff, &extendblock, pedid);
rc = hdmi_edid_parse_base(pedid->raw[0], &extendblock, pedid);
if (rc) {
dev_err(hdmi->dev,
"[HDMI] parse edid base block error\n");
@ -174,12 +174,20 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi)
if (rc)
goto out;
for (i = 1; i < extendblock + 1; i++) {
for (i = 1; (i < extendblock + 1) && (i < HDMI_MAX_EDID_BLOCK); i++) {
pedid->raw[i] = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL);
if (pedid->raw[i] == NULL) {
dev_err(hdmi->dev,
"[%s] can not allocate memory for edid buff.\n",
__func__);
rc = HDMI_ERROR_FALSE;
goto out;
}
for (trytimes = 0; trytimes < 3; trytimes++) {
if (trytimes)
msleep(20);
memset(buff, 0 , HDMI_EDID_BLOCK_SIZE);
rc = hdmi->ops->getedid(hdmi, i, buff);
memset(pedid->raw[i], 0 , HDMI_EDID_BLOCK_SIZE);
rc = hdmi->ops->getedid(hdmi, i, pedid->raw[i]);
if (rc) {
dev_err(hdmi->dev,
"[HDMI] read edid block %d error\n",
@ -187,7 +195,7 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi)
continue;
}
rc = hdmi_edid_parse_extensions(buff, pedid);
rc = hdmi_edid_parse_extensions(pedid->raw[i], pedid);
if (rc) {
dev_err(hdmi->dev,
"[HDMI] parse edid block %d error\n",
@ -200,7 +208,6 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi)
}
}
out:
kfree(buff);
rc = hdmi_ouputmode_select(hdmi, rc);
}
@ -234,6 +241,7 @@ static void hdmi_wq_remove(struct hdmi *hdmi)
{
struct list_head *pos, *n;
struct rk_screen screen;
int i;
DBG("%s", __func__);
if (hdmi->ops->remove)
@ -249,6 +257,8 @@ static void hdmi_wq_remove(struct hdmi *hdmi)
list_del(pos);
kfree(pos);
}
for (i = 0; i < HDMI_MAX_EDID_BLOCK; i++)
kfree(hdmi->edid.raw[i]);
kfree(hdmi->edid.audio);
if (hdmi->edid.specs) {
kfree(hdmi->edid.specs->modedb);

View File

@ -532,6 +532,7 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
if (edid_ok != HDMI_ERROR_SUCESS) {
dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!");
hdmi->edid.status = -1;
hdmi->edid.sink_hdmi = 1;
hdmi->edid.baseaudio_support = 1;
hdmi->edid.ycbcr444 = 0;

View File

@ -304,6 +304,33 @@ static int hdmi_get_monspecs(struct rk_display_device *device,
return 0;
}
static int hdmi_get_debug(struct rk_display_device *device, char *buf)
{
struct hdmi *hdmi = device->priv_data;
char *buff;
int i, j, len = 0;
if (!hdmi)
return 0;
len += snprintf(buf+len, PAGE_SIZE, "EDID status:%s\n",
hdmi->edid.status ? "False" : "Okay");
len += snprintf(buf+len, PAGE_SIZE, "Raw Data:");
mutex_lock(&hdmi->lock);
for (i = 0; i < HDMI_MAX_EDID_BLOCK; i++) {
if (!hdmi->edid.raw[i])
break;
buff = hdmi->edid.raw[i];
for (j = 0; j < HDMI_EDID_BLOCK_SIZE; j++) {
if (j % 16 == 0)
len += snprintf(buf+len, PAGE_SIZE, "\n");
len += snprintf(buf+len, PAGE_SIZE, "0x%02x, ",
buff[j]);
}
}
mutex_unlock(&hdmi->lock);
return len;
}
static struct rk_display_ops hdmi_display_ops = {
.setenable = hdmi_set_enable,
.getenable = hdmi_get_enable,
@ -319,6 +346,7 @@ static struct rk_display_ops hdmi_display_ops = {
.getmonspecs = hdmi_get_monspecs,
.setscale = hdmi_set_scale,
.getscale = hdmi_get_scale,
.getdebug = hdmi_get_debug,
};
static int hdmi_display_probe(struct rk_display_device *device, void *devdata)

View File

@ -263,6 +263,7 @@ struct hdmi_audio {
u32 word_length; /*Audio data word length*/
};
#define HDMI_MAX_EDID_BLOCK 8
/* HDMI EDID Information */
struct hdmi_edid {
unsigned char sink_hdmi; /*HDMI display device flag*/
@ -294,6 +295,9 @@ struct hdmi_edid {
unsigned char baseaudio_support;
struct hdmi_audio *audio; /*Device supported audio info*/
unsigned int audio_num; /*Device supported audio type number*/
unsigned int status; /*EDID read status, success or failed*/
char *raw[HDMI_MAX_EDID_BLOCK]; /*Raw EDID Data*/
};
struct hdmi;