mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 22:52:35 +02:00
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:
parent
57fc92cd71
commit
71e8a27d62
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user