mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
hdmitx: add SCDC/CED function [1/1]
PD#SWPL-6361
Problem:
Lack SCDC/CED function to check Rx TMDS status
Solution:
Add SCDC/CED function
By default, this function is not open.
Enable it in board dts file like below:
&amhdmitx {
cedst_en = <1>;
};
Also, you can manually enable it by
'echo 1 > /sys/class/amhdmitx/amhdmitx0/cedst_policy'
Then listen '/sys/class/extcon/hdmi_cedst/uevent'
and check 'cat /sys/class/amhdmitx/amhdmitx0/cedst_count'
Verify:
G12/U212
Change-Id: Ic9c90936bad643ea95d418d7b019eb37210d7123
Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
This commit is contained in:
@@ -1076,6 +1076,7 @@
|
||||
*/
|
||||
ic_type = <10>;
|
||||
dongle_mode = <0>;
|
||||
cedst_en = <0>;
|
||||
vend_data: vend_data{ /* Should modified by Customer */
|
||||
vendor_name = "Amlogic"; /* Max Chars: 8 */
|
||||
/* standards.ieee.org/develop/regauth/oui/oui.txt */
|
||||
|
||||
@@ -109,6 +109,7 @@ struct extcon_dev *hdmitx_extcon_power;
|
||||
struct extcon_dev *hdmitx_extcon_hdr;
|
||||
struct extcon_dev *hdmitx_extcon_rxsense;
|
||||
struct extcon_dev *hdmitx_extcon_hdcp;
|
||||
struct extcon_dev *hdmitx_extcon_cedst;
|
||||
|
||||
static inline void hdmitx_notify_hpd(int hpd)
|
||||
{
|
||||
@@ -477,6 +478,8 @@ static int set_disp_mode_auto(void)
|
||||
hdev->HWOp.CntlConfig(hdev, CONF_CLR_VSDB_PACKET, 0);
|
||||
hdev->HWOp.CntlMisc(hdev, MISC_TMDS_PHY_OP, TMDS_PHY_DISABLE);
|
||||
hdev->para = hdmi_get_fmt_name("invalid", hdev->fmt_attr);
|
||||
if (hdev->cedst_policy)
|
||||
cancel_delayed_work(&hdev->work_cedst);
|
||||
return -1;
|
||||
}
|
||||
strncpy(mode, info->name, sizeof(mode));
|
||||
@@ -573,6 +576,10 @@ static int set_disp_mode_auto(void)
|
||||
}
|
||||
}
|
||||
hdmitx_set_audio(hdev, &(hdev->cur_audio_param));
|
||||
if (hdev->cedst_policy) {
|
||||
cancel_delayed_work(&hdev->work_cedst);
|
||||
queue_delayed_work(hdev->cedst_wq, &hdev->work_cedst, 0);
|
||||
}
|
||||
hdev->output_blank_flag = 1;
|
||||
hdev->ready = 1;
|
||||
return ret;
|
||||
@@ -2996,6 +3003,82 @@ static ssize_t show_rxsense_policy(struct device *dev,
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* cedst_policy: 0, no CED feature
|
||||
* 1, auto mode, depends on RX scdc_present
|
||||
* 2, forced CED feature
|
||||
*/
|
||||
static ssize_t store_cedst_policy(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int val = 0;
|
||||
struct hdmitx_dev *hdev = &hdmitx_device;
|
||||
|
||||
if (isdigit(buf[0])) {
|
||||
val = buf[0] - '0';
|
||||
pr_info("hdmitx: set cedst_policy as %d\n", val);
|
||||
if ((val == 0) || (val == 1) || (val == 2)) {
|
||||
hdev->cedst_policy = val;
|
||||
if (val == 1) { /* Auto mode, depends on Rx */
|
||||
/* check RX scdc_present */
|
||||
if (hdev->RXCap.scdc_present)
|
||||
hdev->cedst_policy = 1;
|
||||
else
|
||||
hdev->cedst_policy = 0;
|
||||
}
|
||||
if (val == 2) /* Force mode */
|
||||
hdev->cedst_policy = 1;
|
||||
} else
|
||||
pr_info("only accept as 0, 1(auto), or 2(force)\n");
|
||||
}
|
||||
if (hdev->cedst_policy)
|
||||
queue_delayed_work(hdev->cedst_wq, &hdev->work_cedst, 0);
|
||||
else
|
||||
cancel_delayed_work(&hdev->work_cedst);
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_cedst_policy(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "%d\n",
|
||||
hdmitx_device.cedst_policy);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static ssize_t show_cedst_count(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int pos = 0;
|
||||
struct ced_cnt *ced = &hdmitx_device.ced_cnt;
|
||||
struct scdc_locked_st *ch_st = &hdmitx_device.chlocked_st;
|
||||
|
||||
if (!ch_st->clock_detected)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "clock undetected\n");
|
||||
if (!ch_st->ch0_locked)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "CH0 unlocked\n");
|
||||
if (!ch_st->ch1_locked)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "CH1 unlocked\n");
|
||||
if (!ch_st->ch2_locked)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "CH2 unlocked\n");
|
||||
if (ced->ch0_valid && ced->ch0_cnt)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "CH0 ErrCnt 0x%x\n",
|
||||
ced->ch0_cnt);
|
||||
if (ced->ch1_valid && ced->ch1_cnt)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "CH1 ErrCnt 0x%x\n",
|
||||
ced->ch1_cnt);
|
||||
if (ced->ch2_valid && ced->ch2_cnt)
|
||||
pos += snprintf(buf + pos, PAGE_SIZE, "CH2 ErrCnt 0x%x\n",
|
||||
ced->ch2_cnt);
|
||||
memset(ced, 0, sizeof(*ced));
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static ssize_t store_sspll(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
@@ -3558,6 +3641,8 @@ static DEVICE_ATTR(sspll, 0664, show_sspll, store_sspll);
|
||||
static DEVICE_ATTR(frac_rate_policy, 0664, show_frac_rate, store_frac_rate);
|
||||
static DEVICE_ATTR(rxsense_policy, 0644, show_rxsense_policy,
|
||||
store_rxsense_policy);
|
||||
static DEVICE_ATTR(cedst_policy, 0664, show_cedst_policy, store_cedst_policy);
|
||||
static DEVICE_ATTR(cedst_count, 0444, show_cedst_count, NULL);
|
||||
static DEVICE_ATTR(hdcp_clkdis, 0664, show_hdcp_clkdis, store_hdcp_clkdis);
|
||||
static DEVICE_ATTR(hdcp_pwr, 0664, show_hdcp_pwr, store_hdcp_pwr);
|
||||
static DEVICE_ATTR(hdcp_byp, 0200, NULL, store_hdcp_byp);
|
||||
@@ -3644,6 +3729,11 @@ static int hdmitx_module_disable(enum vmode_e cur_vmod)
|
||||
hdmitx_disable_vclk2_enci(hdev);
|
||||
hdev->para = hdmi_get_fmt_name("invalid", hdev->fmt_attr);
|
||||
hdmitx_validate_vmode("null");
|
||||
if (hdev->cedst_policy)
|
||||
cancel_delayed_work(&hdev->work_cedst);
|
||||
if (hdev->rxsense_policy)
|
||||
queue_delayed_work(hdmitx_device.rxsense_wq,
|
||||
&hdmitx_device.work_rxsense, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3893,6 +3983,19 @@ static void hdmitx_rxsense_process(struct work_struct *work)
|
||||
queue_delayed_work(hdev->rxsense_wq, &hdev->work_rxsense, HZ);
|
||||
}
|
||||
|
||||
static void hdmitx_cedst_process(struct work_struct *work)
|
||||
{
|
||||
int ced;
|
||||
struct hdmitx_dev *hdev = container_of((struct delayed_work *)work,
|
||||
struct hdmitx_dev, work_cedst);
|
||||
|
||||
ced = hdev->HWOp.CntlMisc(hdev, MISC_TMDS_CEDST, 0);
|
||||
/* firstly send as 0, then real ced, A trigger signal */
|
||||
extcon_set_state_sync(hdmitx_extcon_cedst, EXTCON_DISP_HDMI, 0);
|
||||
extcon_set_state_sync(hdmitx_extcon_cedst, EXTCON_DISP_HDMI, ced);
|
||||
queue_delayed_work(hdev->cedst_wq, &hdev->work_cedst, HZ);
|
||||
}
|
||||
|
||||
static void hdmitx_hpd_plugin_handler(struct work_struct *work)
|
||||
{
|
||||
char bksv_buf[5];
|
||||
@@ -3916,6 +4019,7 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work)
|
||||
if (hdev->repeater_tx)
|
||||
rx_repeat_hpd_state(1);
|
||||
hdmitx_get_edid(hdev);
|
||||
hdev->cedst_policy = hdev->cedst_en & hdev->RXCap.scdc_present;
|
||||
hdmi_physcial_size_update(hdev);
|
||||
if (hdev->RXCap.ieeeoui != HDMI_IEEEOUI)
|
||||
hdev->HWOp.CntlConfig(hdev,
|
||||
@@ -3945,6 +4049,10 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work)
|
||||
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 1);
|
||||
extcon_set_state_sync(hdmitx_extcon_audio, EXTCON_DISP_HDMI, 1);
|
||||
mutex_unlock(&setclk_mutex);
|
||||
/* Should be started at end of output */
|
||||
cancel_delayed_work(&hdev->work_cedst);
|
||||
if (hdev->cedst_policy)
|
||||
queue_delayed_work(hdev->cedst_wq, &hdev->work_cedst, 0);
|
||||
}
|
||||
|
||||
static void clear_rx_vinfo(struct hdmitx_dev *hdev)
|
||||
@@ -3969,6 +4077,8 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work)
|
||||
hdev->HWOp.CntlDDC(hdev, DDC_HDCP_MUX_INIT, 1);
|
||||
hdev->HWOp.CntlDDC(hdev, DDC_HDCP_OP, HDCP14_OFF);
|
||||
mutex_lock(&setclk_mutex);
|
||||
if (hdev->cedst_policy)
|
||||
cancel_delayed_work(&hdev->work_cedst);
|
||||
pr_info(SYS "plugout\n");
|
||||
if (!!(hdev->HWOp.CntlMisc(hdev, MISC_HPD_GPI_ST, 0))) {
|
||||
pr_info(SYS "hpd gpio high\n");
|
||||
@@ -4063,6 +4173,10 @@ static int hdmi_task_handle(void *data)
|
||||
hdmitx_device->rxsense_wq = alloc_workqueue(hdmitx_extcon_rxsense->name,
|
||||
WQ_SYSFS | WQ_FREEZABLE, 0);
|
||||
INIT_DELAYED_WORK(&hdmitx_device->work_rxsense, hdmitx_rxsense_process);
|
||||
/* for cedst feature */
|
||||
hdmitx_device->cedst_wq = alloc_workqueue(hdmitx_extcon_cedst->name,
|
||||
WQ_SYSFS | WQ_FREEZABLE, 0);
|
||||
INIT_DELAYED_WORK(&hdmitx_device->work_cedst, hdmitx_cedst_process);
|
||||
|
||||
hdmitx_device->tx_aud_cfg = 1; /* default audio configure is on */
|
||||
|
||||
@@ -4241,6 +4355,7 @@ void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
|
||||
ret = extcon_dev_register(edev);
|
||||
if (ret < 0) {
|
||||
pr_info(SYS "failed to register hdmitx extcon hdmi\n");
|
||||
extcon_dev_free(edev);
|
||||
return;
|
||||
}
|
||||
hdmitx_extcon_hdmi = edev;
|
||||
@@ -4251,13 +4366,13 @@ void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
|
||||
pr_info(SYS "failed to allocate hdmitx extcon audio\n");
|
||||
return;
|
||||
}
|
||||
|
||||
edev->dev.parent = dev;
|
||||
edev->name = "hdmitx_extcon_audio";
|
||||
dev_set_name(&edev->dev, "hdmi_audio");
|
||||
ret = extcon_dev_register(edev);
|
||||
if (ret < 0) {
|
||||
pr_info(SYS "failed to register hdmitx extcon audio\n");
|
||||
extcon_dev_free(edev);
|
||||
return;
|
||||
}
|
||||
hdmitx_extcon_audio = edev;
|
||||
@@ -4268,13 +4383,13 @@ void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
|
||||
pr_info(SYS "failed to allocate hdmitx extcon power\n");
|
||||
return;
|
||||
}
|
||||
|
||||
edev->dev.parent = dev;
|
||||
edev->name = "hdmitx_extcon_power";
|
||||
dev_set_name(&edev->dev, "hdmi_power");
|
||||
ret = extcon_dev_register(edev);
|
||||
if (ret < 0) {
|
||||
pr_info(SYS "failed to register extcon power\n");
|
||||
extcon_dev_free(edev);
|
||||
return;
|
||||
}
|
||||
hdmitx_extcon_power = edev;
|
||||
@@ -4285,30 +4400,47 @@ void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
|
||||
pr_info(SYS "failed to allocate hdmitx extcon hdr\n");
|
||||
return;
|
||||
}
|
||||
|
||||
edev->dev.parent = dev;
|
||||
edev->name = "hdmitx_extcon_hdr";
|
||||
dev_set_name(&edev->dev, "hdmi_hdr");
|
||||
ret = extcon_dev_register(edev);
|
||||
if (ret < 0) {
|
||||
pr_info(SYS "failed to register hdmitx extcon hdr\n");
|
||||
extcon_dev_free(edev);
|
||||
return;
|
||||
}
|
||||
hdmitx_extcon_hdr = edev;
|
||||
|
||||
/*hdmitx extcon CED */
|
||||
edev = extcon_dev_allocate(hdmi_cable);
|
||||
if (IS_ERR(edev)) {
|
||||
pr_info(SYS "failed to allocate extcon rxsense\n");
|
||||
return;
|
||||
}
|
||||
edev->dev.parent = dev;
|
||||
edev->name = "hdmitx_extcon_cedst";
|
||||
dev_set_name(&edev->dev, "hdmi_cedst");
|
||||
ret = extcon_dev_register(edev);
|
||||
if (ret < 0) {
|
||||
pr_info(SYS "failed to register extcon cedst\n");
|
||||
extcon_dev_free(edev);
|
||||
return;
|
||||
}
|
||||
hdmitx_extcon_cedst = edev;
|
||||
|
||||
/*hdmitx extcon rxsense*/
|
||||
edev = extcon_dev_allocate(hdmi_cable);
|
||||
if (IS_ERR(edev)) {
|
||||
pr_info(SYS "failed to allocate extcon rxsense\n");
|
||||
return;
|
||||
}
|
||||
|
||||
edev->dev.parent = dev;
|
||||
edev->name = "hdmitx_extcon_rxsense";
|
||||
dev_set_name(&edev->dev, "hdmi_rxsense");
|
||||
ret = extcon_dev_register(edev);
|
||||
if (ret < 0) {
|
||||
pr_info(SYS "failed to register extcon rxsense\n");
|
||||
extcon_dev_free(edev);
|
||||
return;
|
||||
}
|
||||
hdmitx_extcon_rxsense = edev;
|
||||
@@ -4319,17 +4451,16 @@ void hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
|
||||
pr_info(SYS "failed to allocate extcon hdcp\n");
|
||||
return;
|
||||
}
|
||||
|
||||
edev->dev.parent = dev;
|
||||
edev->name = "hdmitx_extcon_hdcp";
|
||||
dev_set_name(&edev->dev, "hdcp");
|
||||
ret = extcon_dev_register(edev);
|
||||
if (ret < 0) {
|
||||
pr_info(SYS "failed to register extcon hdcp\n");
|
||||
extcon_dev_free(edev);
|
||||
return;
|
||||
}
|
||||
hdmitx_extcon_hdcp = edev;
|
||||
|
||||
}
|
||||
|
||||
static void hdmitx_init_parameters(struct hdmitx_info *info)
|
||||
@@ -4458,6 +4589,11 @@ static int amhdmitx_get_dt_info(struct platform_device *pdev)
|
||||
hdmitx_device.topo_info = kzalloc(
|
||||
sizeof(*hdmitx_device.topo_info), GFP_KERNEL);
|
||||
|
||||
ret = of_property_read_u32(pdev->dev.of_node,
|
||||
"cedst_en", &val);
|
||||
if (!ret)
|
||||
hdmitx_device.cedst_en = !!val;
|
||||
|
||||
/* Get vendor information */
|
||||
ret = of_property_read_u32(pdev->dev.of_node,
|
||||
"vend-data", &val);
|
||||
@@ -4657,6 +4793,8 @@ static int amhdmitx_probe(struct platform_device *pdev)
|
||||
ret = device_create_file(dev, &dev_attr_frac_rate_policy);
|
||||
ret = device_create_file(dev, &dev_attr_sspll);
|
||||
ret = device_create_file(dev, &dev_attr_rxsense_policy);
|
||||
ret = device_create_file(dev, &dev_attr_cedst_policy);
|
||||
ret = device_create_file(dev, &dev_attr_cedst_count);
|
||||
ret = device_create_file(dev, &dev_attr_hdcp_clkdis);
|
||||
ret = device_create_file(dev, &dev_attr_hdcp_pwr);
|
||||
ret = device_create_file(dev, &dev_attr_hdcp_ksv_info);
|
||||
@@ -4766,6 +4904,8 @@ static int amhdmitx_remove(struct platform_device *pdev)
|
||||
device_remove_file(dev, &dev_attr_frac_rate_policy);
|
||||
device_remove_file(dev, &dev_attr_sspll);
|
||||
device_remove_file(dev, &dev_attr_rxsense_policy);
|
||||
device_remove_file(dev, &dev_attr_cedst_policy);
|
||||
device_remove_file(dev, &dev_attr_cedst_count);
|
||||
device_remove_file(dev, &dev_attr_hdcp_pwr);
|
||||
device_remove_file(dev, &dev_attr_div40);
|
||||
device_remove_file(dev, &dev_attr_hdcp_repeater);
|
||||
|
||||
@@ -25,3 +25,74 @@ void scdc_config(struct hdmitx_dev *hdev)
|
||||
/* TMDS 1/40 & Scramble */
|
||||
scdc_wr_sink(TMDS_CFG, hdev->para->tmds_clk_div40 ? 0x3 : 0);
|
||||
}
|
||||
|
||||
/* update CED, 10.4.1.8 */
|
||||
static int scdc_ced_cnt(struct hdmitx_dev *hdev)
|
||||
{
|
||||
struct ced_cnt *ced = &hdev->ced_cnt;
|
||||
u8 raw[7];
|
||||
u8 chksum;
|
||||
int i;
|
||||
|
||||
memset(raw, 0, sizeof(raw));
|
||||
memset(ced, 0, sizeof(struct ced_cnt));
|
||||
|
||||
chksum = 0;
|
||||
for (i = 0; i < 7; i++) {
|
||||
scdc_rd_sink(ERR_DET_0_L + i, &raw[i]);
|
||||
chksum += raw[i];
|
||||
}
|
||||
|
||||
ced->ch0_cnt = raw[0] + ((raw[1] & 0x7f) << 8);
|
||||
ced->ch0_valid = (raw[1] >> 7) & 0x1;
|
||||
ced->ch1_cnt = raw[2] + ((raw[3] & 0x7f) << 8);
|
||||
ced->ch1_valid = (raw[3] >> 7) & 0x1;
|
||||
ced->ch2_cnt = raw[4] + ((raw[5] & 0x7f) << 8);
|
||||
ced->ch2_valid = (raw[5] >> 7) & 0x1;
|
||||
|
||||
/* Do checksum */
|
||||
if (chksum != 0)
|
||||
pr_info("ced check sum error\n");
|
||||
if (ced->ch0_cnt)
|
||||
pr_info("ced: ch0_cnt = %d %s\n", ced->ch0_cnt,
|
||||
ced->ch0_valid ? "" : "unvalid");
|
||||
if (ced->ch1_cnt)
|
||||
pr_info("ced: ch1_cnt = %d %s\n", ced->ch1_cnt,
|
||||
ced->ch1_valid ? "" : "unvalid");
|
||||
if (ced->ch2_cnt)
|
||||
pr_info("ced: ch2_cnt = %d %s\n", ced->ch2_cnt,
|
||||
ced->ch2_valid ? "" : "unvalid");
|
||||
|
||||
return chksum != 0;
|
||||
}
|
||||
|
||||
/* update scdc status flags, 10.4.1.7 */
|
||||
/* ignore STATUS_FLAGS_1, all bits are RSVD */
|
||||
int scdc_status_flags(struct hdmitx_dev *hdev)
|
||||
{
|
||||
u8 st = 0;
|
||||
u8 locked_st = 0;
|
||||
|
||||
scdc_rd_sink(UPDATE_0, &st);
|
||||
if (st & STATUS_UPDATE) {
|
||||
scdc_rd_sink(STATUS_FLAGS_0, &locked_st);
|
||||
hdev->chlocked_st.clock_detected = locked_st & (1 << 0);
|
||||
hdev->chlocked_st.ch0_locked = !!(locked_st & (1 << 1));
|
||||
hdev->chlocked_st.ch1_locked = !!(locked_st & (2 << 1));
|
||||
hdev->chlocked_st.ch2_locked = !!(locked_st & (3 << 1));
|
||||
}
|
||||
if (st & CED_UPDATE)
|
||||
scdc_ced_cnt(hdev);
|
||||
if (st & (STATUS_UPDATE | CED_UPDATE))
|
||||
scdc_wr_sink(UPDATE_0, st & (STATUS_UPDATE | CED_UPDATE));
|
||||
if (!hdev->chlocked_st.clock_detected)
|
||||
pr_info("ced: clock undetected\n");
|
||||
if (!hdev->chlocked_st.ch0_locked)
|
||||
pr_info("ced: ch0 unlocked\n");
|
||||
if (!hdev->chlocked_st.ch1_locked)
|
||||
pr_info("ced: ch1 unlocked\n");
|
||||
if (!hdev->chlocked_st.ch2_locked)
|
||||
pr_info("ced: ch2 unlocked\n");
|
||||
|
||||
return st & (STATUS_UPDATE | CED_UPDATE);
|
||||
}
|
||||
|
||||
@@ -5009,6 +5009,13 @@ static int hdmitx_tmds_rxsense(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Check from SCDC Status_Flags_0/1 */
|
||||
/* 0 means TMDS ok */
|
||||
static int hdmitx_tmds_cedst(struct hdmitx_dev *hdev)
|
||||
{
|
||||
return scdc_status_flags(hdev);
|
||||
}
|
||||
|
||||
static int hdmitx_cntl_misc(struct hdmitx_dev *hdev, unsigned int cmd,
|
||||
unsigned int argv)
|
||||
{
|
||||
@@ -5039,6 +5046,8 @@ static int hdmitx_cntl_misc(struct hdmitx_dev *hdev, unsigned int cmd,
|
||||
break;
|
||||
case MISC_TMDS_RXSENSE:
|
||||
return hdmitx_tmds_rxsense();
|
||||
case MISC_TMDS_CEDST:
|
||||
return hdmitx_tmds_cedst(hdev);
|
||||
case MISC_ESM_RESET:
|
||||
if (hdev->hdcp_hpd_stick == 1) {
|
||||
pr_info(HW "hdcp: stick mode\n");
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define __HDMI_TX_DDC_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h>
|
||||
#include "hdmi_tx_module.h"
|
||||
|
||||
#define EDID_SLAVE 0x50
|
||||
#define EDIDSEG_ADR 0x30
|
||||
@@ -31,6 +31,9 @@ enum scdc_addr {
|
||||
SINK_VER = 0x01,
|
||||
SOURCE_VER, /* RW */
|
||||
UPDATE_0 = 0x10, /* RW */
|
||||
#define STATUS_UPDATE BIT(0)
|
||||
#define CED_UPDATE BIT(1)
|
||||
#define RR_TEST BIT(2)
|
||||
UPDATE_1, /* RW */
|
||||
TMDS_CFG = 0x20, /* RW */
|
||||
SCRAMBLER_ST,
|
||||
@@ -83,5 +86,6 @@ uint32_t hdcp_rd_hdcp14_ver(void);
|
||||
uint32_t hdcp_rd_hdcp22_ver(void);
|
||||
void scdc_config(struct hdmitx_dev *hdev);
|
||||
void edid_read_head_8bytes(void);
|
||||
int scdc_status_flags(struct hdmitx_dev *hdev);
|
||||
|
||||
#endif /* __HDMI_TX_SCDC_H__ */
|
||||
|
||||
@@ -202,6 +202,23 @@ struct frac_rate_table {
|
||||
u32 sync_den_dec;
|
||||
};
|
||||
|
||||
struct ced_cnt {
|
||||
bool ch0_valid;
|
||||
u16 ch0_cnt:15;
|
||||
bool ch1_valid;
|
||||
u16 ch1_cnt:15;
|
||||
bool ch2_valid;
|
||||
u16 ch2_cnt:15;
|
||||
u8 chksum;
|
||||
};
|
||||
|
||||
struct scdc_locked_st {
|
||||
u8 clock_detected:1;
|
||||
u8 ch0_locked:1;
|
||||
u8 ch1_locked:1;
|
||||
u8 ch2_locked:1;
|
||||
};
|
||||
|
||||
enum hdmi_hdr_transfer {
|
||||
T_UNKNOWN = 0,
|
||||
T_BT709,
|
||||
@@ -302,6 +319,7 @@ struct hdmitx_dev {
|
||||
struct notifier_block nb;
|
||||
struct workqueue_struct *hdmi_wq;
|
||||
struct workqueue_struct *rxsense_wq;
|
||||
struct workqueue_struct *cedst_wq;
|
||||
struct device *hdtx_dev;
|
||||
struct device *pdev; /* for pinctrl*/
|
||||
struct pinctrl_state *pinctrl_i2c;
|
||||
@@ -310,6 +328,7 @@ struct hdmitx_dev {
|
||||
struct delayed_work work_hpd_plugout;
|
||||
struct delayed_work work_rxsense;
|
||||
struct delayed_work work_internal_intr;
|
||||
struct delayed_work work_cedst;
|
||||
struct work_struct work_hdr;
|
||||
struct delayed_work work_do_hdcp;
|
||||
#ifdef CONFIG_AML_HDMI_TX_14
|
||||
@@ -422,6 +441,9 @@ struct hdmitx_dev {
|
||||
/* 0.1% clock shift, 1080p60hz->59.94hz */
|
||||
unsigned int frac_rate_policy;
|
||||
unsigned int rxsense_policy;
|
||||
unsigned int cedst_policy;
|
||||
struct ced_cnt ced_cnt;
|
||||
struct scdc_locked_st chlocked_st;
|
||||
/* allm_mode: 1/game, 2/graphcis, 3/photo, 4/cinema */
|
||||
unsigned int allm_mode;
|
||||
unsigned int sspll;
|
||||
@@ -449,6 +471,7 @@ struct hdmitx_dev {
|
||||
unsigned int flag_3dtb:1;
|
||||
unsigned int flag_3dss:1;
|
||||
unsigned int dongle_mode:1;
|
||||
unsigned int cedst_en:1; /* configure in DTS */
|
||||
unsigned int drm_feature;/*Direct Rander Management*/
|
||||
};
|
||||
|
||||
@@ -564,9 +587,10 @@ struct hdmitx_dev {
|
||||
#define MISC_ESM_RESET (CMD_MISC_OFFSET + 0x0d)
|
||||
#define MISC_HDCP_CLKDIS (CMD_MISC_OFFSET + 0x0e)
|
||||
#define MISC_TMDS_RXSENSE (CMD_MISC_OFFSET + 0x0f)
|
||||
#define MISC_I2C_REACTIVE (CMD_MISC_OFFSET + 0x10)
|
||||
#define MISC_I2C_RESET (CMD_MISC_OFFSET + 0x11)
|
||||
#define MISC_I2C_REACTIVE (CMD_MISC_OFFSET + 0x10) /* For gxl */
|
||||
#define MISC_I2C_RESET (CMD_MISC_OFFSET + 0x11) /* For g12 */
|
||||
#define MISC_READ_AVMUTE_OP (CMD_MISC_OFFSET + 0x12)
|
||||
#define MISC_TMDS_CEDST (CMD_MISC_OFFSET + 0x13)
|
||||
|
||||
/***********************************************************************
|
||||
* Get State //GetState
|
||||
|
||||
Reference in New Issue
Block a user