diff options
| author | Ajay Singh Parmar <aparmar@codeaurora.org> | 2014-12-26 14:48:10 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:37:26 -0700 |
| commit | 0b544625b5fa0634c1ee667ef14fc07bb55d7fc2 (patch) | |
| tree | 2156267e355e4a609fd570ae889ba261de6879e5 | |
| parent | 33c63a3a5d371e933bb6a6629be7f08a46cec819 (diff) | |
msm: mdss: hdmi: give multiple resolution info using sysfs node
Provide complete resolution details in a sysfs node "res_info"
limited to PAGE_SIZE. Different modules can query for multiple
resolution details based on the resolution ids received from
EDID of the TV.
In case resolution details exceed PAGE_SIZE, reuse res_info to
get remaining timing details by provide page details.
Change-Id: I3e8e8d4de29f78d22273b3fb8ff6a059a8cb19e1
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_edid.c | 101 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.c | 69 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.h | 1 | ||||
| -rw-r--r-- | include/uapi/video/msm_hdmi_modes.h | 2 |
4 files changed, 103 insertions, 70 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c index 4014589d3ab2..35eefeb42a06 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c @@ -117,6 +117,7 @@ struct hdmi_edid_ctrl { u16 audio_latency; u16 video_latency; u32 present_3d; + u32 page_id; u8 audio_data_block[MAX_NUMBER_ADB * MAX_AUDIO_DATA_BLOCK_SIZE]; int adb_size; u8 spkr_alloc_data_block[MAX_SPKR_ALLOC_DATA_BLOCK_SIZE]; @@ -246,6 +247,103 @@ static ssize_t hdmi_edid_sysfs_rda_modes(struct device *dev, } /* hdmi_edid_sysfs_rda_modes */ static DEVICE_ATTR(edid_modes, S_IRUGO, hdmi_edid_sysfs_rda_modes, NULL); +static ssize_t hdmi_edid_sysfs_wta_res_info(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int rc, page_id; + ssize_t ret = strnlen(buf, PAGE_SIZE); + struct hdmi_edid_ctrl *edid_ctrl = + hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_EDID); + + if (!edid_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return -EINVAL; + } + + rc = kstrtoint(buf, 10, &page_id); + if (rc) { + DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); + return rc; + } + + edid_ctrl->page_id = page_id; + + DEV_DBG("%s: %d\n", __func__, edid_ctrl->page_id); + return ret; +} + +static ssize_t hdmi_edid_sysfs_rda_res_info(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + u32 no_of_elem; + u32 i = 0, j, page; + char *buf_dbg = buf; + struct msm_hdmi_mode_timing_info info = {0}; + struct hdmi_edid_ctrl *edid_ctrl = + hdmi_get_featuredata_from_sysfs_dev(dev, HDMI_TX_FEAT_EDID); + u32 size_to_write = sizeof(info); + struct disp_mode_info *minfo = NULL; + + if (!edid_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return -EINVAL; + } + + minfo = edid_ctrl->sink_data.disp_mode_list; + no_of_elem = edid_ctrl->sink_data.num_of_elements; + + if (edid_ctrl->page_id > MSM_HDMI_INIT_RES_PAGE) { + page = MSM_HDMI_INIT_RES_PAGE; + while (page < edid_ctrl->page_id) { + j = 1; + while (sizeof(info) * j < PAGE_SIZE) { + i++; + j++; + minfo++; + } + page++; + } + } + + for (; i < no_of_elem && size_to_write < PAGE_SIZE; i++) { + ret = hdmi_get_supported_mode(&info, + edid_ctrl->init_data.ds_data, + minfo->video_format); + + minfo++; + if (ret || !info.supported) + continue; + + memcpy(buf, &info, sizeof(info)); + + buf += sizeof(info); + size_to_write += sizeof(info); + } + + for (i = sizeof(info); i < size_to_write; i += sizeof(info)) { + struct msm_hdmi_mode_timing_info info_dbg = {0}; + + memcpy(&info_dbg, buf_dbg, sizeof(info_dbg)); + + DEV_DBG("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + info_dbg.video_format, info_dbg.active_h, + info_dbg.front_porch_h, info_dbg.pulse_width_h, + info_dbg.back_porch_h, info_dbg.active_low_h, + info_dbg.active_v, info_dbg.front_porch_v, + info_dbg.pulse_width_v, info_dbg.back_porch_v, + info_dbg.active_low_v, info_dbg.pixel_freq, + info_dbg.refresh_rate, info_dbg.interlaced, + info_dbg.supported, info_dbg.ar); + + buf_dbg += sizeof(info_dbg); + } + + return size_to_write - sizeof(info); +} +static DEVICE_ATTR(res_info, S_IRUGO | S_IWUSR, hdmi_edid_sysfs_rda_res_info, + hdmi_edid_sysfs_wta_res_info); + static ssize_t hdmi_edid_sysfs_rda_audio_latency(struct device *dev, struct device_attribute *attr, char *buf) { @@ -401,6 +499,7 @@ static struct attribute *hdmi_edid_fs_attrs[] = { &dev_attr_spkr_alloc_data_block.attr, &dev_attr_edid_audio_latency.attr, &dev_attr_edid_video_latency.attr, + &dev_attr_res_info.attr, NULL, }; @@ -1756,6 +1855,8 @@ int hdmi_edid_read(void *input) return -EINVAL; } + edid_ctrl->page_id = MSM_HDMI_INIT_RES_PAGE; + edid_buf = edid_ctrl->edid_buf; edid_ctrl->pt_scan_info = 0; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 5622a07c7cf7..4221e4ee1af9 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -961,72 +961,6 @@ static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev, return ret; } /* hdmi_tx_sysfs_wta_cn_bits */ -static ssize_t hdmi_tx_sysfs_wta_res_info(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int rc, res_info_id; - ssize_t ret = strnlen(buf, PAGE_SIZE); - struct hdmi_tx_ctrl *hdmi_ctrl = NULL; - - hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); - - if (!hdmi_ctrl) { - DEV_ERR("%s: invalid input\n", __func__); - return -EINVAL; - } - - rc = kstrtoint(buf, 10, &res_info_id); - if (rc) { - DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); - return rc; - } - - if (res_info_id >= 0 && res_info_id < HDMI_VFRMT_MAX) - hdmi_ctrl->res_info_id = res_info_id; - else - hdmi_ctrl->res_info_id = 0; - - DEV_DBG("%s: %d\n", __func__, hdmi_ctrl->res_info_id); - return ret; -} - -static ssize_t hdmi_tx_sysfs_rda_res_info(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t ret; - struct msm_hdmi_mode_timing_info info = {0}; - struct hdmi_tx_ctrl *hdmi_ctrl = - hdmi_tx_get_drvdata_from_sysfs_dev(dev); - u32 size = sizeof(info) < PAGE_SIZE ? sizeof(info) : PAGE_SIZE; - - if (!hdmi_ctrl) { - DEV_ERR("%s: invalid input\n", __func__); - return -EINVAL; - } - - if (!hdmi_ctrl->res_info_id) - return -EINVAL; - - ret = hdmi_get_supported_mode(&info, &hdmi_ctrl->ds_data, - hdmi_ctrl->res_info_id); - - if (ret) - return -EINVAL; - - memcpy(buf, &info, size); - - DEV_DBG("%s: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", - __func__, - info.video_format, info.active_h, info.front_porch_h, - info.pulse_width_h, info.back_porch_h, info.active_low_h, - info.active_v, info.front_porch_v, info.pulse_width_v, - info.back_porch_v, info.active_low_v, info.pixel_freq, - info.refresh_rate, info.interlaced, info.supported, - info.ar); - - return size; -} - static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(video_mode, S_IRUGO, hdmi_tx_sysfs_rda_video_mode, NULL); static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_hpd, @@ -1038,8 +972,6 @@ static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_wta_product_description); static DEVICE_ATTR(avi_itc, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_itc); static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn_bits); -static DEVICE_ATTR(res_info, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_res_info, - hdmi_tx_sysfs_wta_res_info); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, @@ -1049,7 +981,6 @@ static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_product_description.attr, &dev_attr_avi_itc.attr, &dev_attr_avi_cn0_1.attr, - &dev_attr_res_info.attr, NULL, }; static struct attribute_group hdmi_tx_fs_attrs_group = { diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.h b/drivers/video/fbdev/msm/mdss_hdmi_tx.h index d6b5fadaf9a7..718a84ade065 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.h @@ -154,7 +154,6 @@ struct hdmi_tx_ctrl { u32 hpd_feature_on; u32 hpd_initialized; u32 vote_hdmi_core_on; - u32 res_info_id; u8 timing_gen_on; u8 mhl_hpd_on; diff --git a/include/uapi/video/msm_hdmi_modes.h b/include/uapi/video/msm_hdmi_modes.h index 9dbda4f512c3..e1dd71f6b6ba 100644 --- a/include/uapi/video/msm_hdmi_modes.h +++ b/include/uapi/video/msm_hdmi_modes.h @@ -23,6 +23,8 @@ struct msm_hdmi_mode_timing_info { uint32_t supported; }; +#define MSM_HDMI_INIT_RES_PAGE 1 + #define MSM_HDMI_MODES_CEA (1 << 0) #define MSM_HDMI_MODES_XTND (1 << 1) #define MSM_HDMI_MODES_DVI (1 << 2) |
