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)
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__);
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");
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",
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",
}
}
out:
- kfree(buff);
rc = hdmi_ouputmode_select(hdmi, rc);
}
{
struct list_head *pos, *n;
struct rk_screen screen;
+ int i;
DBG("%s", __func__);
if (hdmi->ops->remove)
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);
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,
.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)