diff options
| author | Ajay Singh Parmar <aparmar@codeaurora.org> | 2013-12-01 00:41:45 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:23:56 -0700 |
| commit | 1d4a32fdf7ecf10371c2aa380e1ff820c1a11489 (patch) | |
| tree | e7ebf3b0d13e21bb18b3f5bce904aba7ba21f8c8 | |
| parent | e9be7342901c7a1e55b118c5781522f116ef6419 (diff) | |
msm: mdss: hdmi: clean up cn/itc bit set/unset
Properly set/unset the ITC/CN bits by using proper mutex,
error checks and other cleanup things.
Change-Id: I2730689dc70df1bce65bb1699938ce7793937688
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.c | 151 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.h | 1 |
2 files changed, 73 insertions, 79 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index fc29ef2ca2af..2aa2d917b3fb 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -67,6 +67,24 @@ static bool hdcp_feature_on = true; #define MSM_HDMI_AUDIO_CHANNEL_6 6 #define MSM_HDMI_AUDIO_CHANNEL_8 8 +#define NUM_MODES_AVI 20 + +/* AVI Infoframe data byte 3, bit 7 (msb) represents ITC bit */ +#define SET_ITC_BIT(byte) (byte = (byte | BIT(7))) +#define CLR_ITC_BIT(byte) (byte = (byte & ~BIT(7))) + +/* + * CN represents IT content type, if ITC bit in infoframe data byte 3 + * is set, CN bits will represent content type as below: + * 0b00 Graphics + * 0b01 Photo + * 0b10 Cinema + * 0b11 Game +*/ +#define CONFIG_CN_BITS(bits, byte) \ + (byte = (byte & ~(BIT(4) | BIT(5))) |\ + ((bits & (BIT(0) | BIT(1))) << 4)) + enum msm_hdmi_supported_audio_sample_rates { AUDIO_SAMPLE_RATE_32KHZ, AUDIO_SAMPLE_RATE_44_1KHZ, @@ -135,12 +153,6 @@ const char *hdmi_pm_name(enum hdmi_tx_power_module_type module) } } /* hdmi_pm_name */ -static DEFINE_MUTEX(avi_iframe_lut_lock); -#define NUM_MODES_AVI 20 -#define SET_ITC_BIT(byte) (byte | 0x80) -#define CLR_ITC_BIT(byte) (byte & 0x7F) -#define CONFIG_CN_BITS(bits, byte) ((byte & ~(0x03 << 4)) | (bits << 4)) - static u8 hdmi_tx_avi_iframe_lut[][NUM_MODES_AVI] = { {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, @@ -208,55 +220,6 @@ static const struct hdmi_tx_audio_acr_arry hdmi_tx_audio_acr_lut[] = { {20480, 247500} } }, }; -/* To statically config ITC bit from sysfs attribute */ -static int hdmi_tx_config_itc_bit(int itc) -{ - int ret = 0, loop = NUM_MODES_AVI; - - if (mutex_lock_interruptible(&avi_iframe_lut_lock)) { - ret = -ERESTARTSYS; - goto signal_intr; - } - - do { - --loop; - if (itc == 0) - hdmi_tx_avi_iframe_lut[2][loop] = - CLR_ITC_BIT(hdmi_tx_avi_iframe_lut[2][loop]); - if (itc == 1) - hdmi_tx_avi_iframe_lut[2][loop] = - SET_ITC_BIT(hdmi_tx_avi_iframe_lut[2][loop]); - } while (loop); - - mutex_unlock(&avi_iframe_lut_lock); - -signal_intr: - return ret; -} - -/* To configure CN0_1 bits from sysfs attribute */ -static int hdmi_tx_config_cn_bits(int cns) -{ - int ret = 0, loop = NUM_MODES_AVI; - - if (mutex_lock_interruptible(&avi_iframe_lut_lock)) { - ret = -ERESTARTSYS; - goto signal_intr; - } - - do { - --loop; - hdmi_tx_avi_iframe_lut[4][loop] = - CONFIG_CN_BITS(cns, hdmi_tx_avi_iframe_lut[4][loop]); - } while (loop); - - mutex_unlock(&avi_iframe_lut_lock); - -signal_intr: - return ret; -} - - static bool hdmi_tx_is_cea_format(int mode) { bool cea_fmt; @@ -680,53 +643,80 @@ static ssize_t hdmi_tx_sysfs_wta_avi_itc(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ssize_t ret = strnlen(buf, PAGE_SIZE); - int err = 0; - int itc = 0, rc = 0; + u8 *avi_byte3 = hdmi_tx_avi_iframe_lut[2]; + struct hdmi_tx_ctrl *hdmi_ctrl = NULL; + int loop = 0, itc = 0, rc = 0; + + 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, &itc); if (rc) { - DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); + DEV_ERR("%s: kstrtoint failed. rc =%d\n", __func__, rc); return rc; } - if (itc == 0 || itc == 1) { - if (hdmi_tx_config_itc_bit(itc)) - ret = err; + if (itc < 0 || itc > 1) { + DEV_ERR("%s: Invalid ITC %d\n", __func__, itc); + return ret; + } + + if (mutex_lock_interruptible(&hdmi_ctrl->lut_lock)) + return -ERESTARTSYS; + + for (loop = 0; loop < NUM_MODES_AVI; loop++) { + if (itc) + SET_ITC_BIT(avi_byte3[loop]); else - DEV_DBG("%s: '%d is configured'!\n", __func__, itc); - } else { - DEV_ERR("%s: unknown ITC '%d', should be either 0 or 1\n", - __func__, itc); + CLR_ITC_BIT(avi_byte3[loop]); } + mutex_unlock(&hdmi_ctrl->lut_lock); + return ret; } /* hdmi_tx_sysfs_wta_avi_itc */ -static ssize_t hdmi_tx_sysfs_wta_avi_cn0_1(struct device *dev, +static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { ssize_t ret = strnlen(buf, PAGE_SIZE); - int err = 0; - int cns = 0, rc = 0; + u8 *avi_byte5 = hdmi_tx_avi_iframe_lut[4]; + struct hdmi_tx_ctrl *hdmi_ctrl = NULL; + int loop = 0, cn_bits = 0, rc = 0; - rc = kstrtoint(buf, 10, &cns); + 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, &cn_bits); if (rc) { DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); return rc; } - if (cns == 0 || cns == 1 || cns == 2 || cns == 3) { - if (hdmi_tx_config_cn_bits(cns)) - ret = err; - else - DEV_DBG("%s: '%d is configured'!\n", __func__, cns); - } else { - DEV_ERR("%s: unknown CN '%d' should be either 0 or 1, 2 ,3\n", - __func__, cns); + /* As per CEA-861-E, CN is a positive number and can be max 3 */ + if (cn_bits < 0 || cn_bits > 3) { + DEV_ERR("%s: Invalid CN %d\n", __func__, cn_bits); + return ret; } + if (mutex_lock_interruptible(&hdmi_ctrl->lut_lock)) + return -ERESTARTSYS; + + for (loop = 0; loop < NUM_MODES_AVI; loop++) + CONFIG_CN_BITS(cn_bits, avi_byte5[loop]); + + mutex_unlock(&hdmi_ctrl->lut_lock); + return ret; -} /* hdmi_tx_sysfs_wta_avi_cn0_1 */ +} /* hdmi_tx_sysfs_wta_cn_bits */ static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_hpd, @@ -737,7 +727,7 @@ static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_product_description, 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_cn0_1); +static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn_bits); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, @@ -2846,6 +2836,7 @@ static void hdmi_tx_dev_deinit(struct hdmi_tx_ctrl *hdmi_ctrl) switch_dev_unregister(&hdmi_ctrl->sdev); if (hdmi_ctrl->workq) destroy_workqueue(hdmi_ctrl->workq); + mutex_destroy(&hdmi_ctrl->lut_lock); mutex_destroy(&hdmi_ctrl->mutex); hdmi_tx_hw.ptr = NULL; @@ -2874,6 +2865,7 @@ static int hdmi_tx_dev_init(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_setup_video_mode_lut(); mutex_init(&hdmi_ctrl->mutex); + mutex_init(&hdmi_ctrl->lut_lock); hdmi_ctrl->workq = create_workqueue("hdmi_tx_workq"); if (!hdmi_ctrl->workq) { DEV_ERR("%s: hdmi_tx_workq creation failed.\n", __func__); @@ -2922,6 +2914,7 @@ fail_audio_switch_dev: fail_create_workq: if (hdmi_ctrl->workq) destroy_workqueue(hdmi_ctrl->workq); + mutex_destroy(&hdmi_ctrl->lut_lock); mutex_destroy(&hdmi_ctrl->mutex); fail_no_hdmi: return rc; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.h b/drivers/video/fbdev/msm/mdss_hdmi_tx.h index 66071e94fce1..0787deeb491a 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.h @@ -54,6 +54,7 @@ struct hdmi_tx_ctrl { struct hdmi_audio audio_data; struct mutex mutex; + struct mutex lut_lock; struct kobject *kobj; struct switch_dev sdev; struct switch_dev audio_sdev; |
