From 3f3d33b8fd6dafe5aaa47add49bc818e4f0a2bc7 Mon Sep 17 00:00:00 2001 From: Zongdong Jiao Date: Thu, 20 Feb 2020 10:18:38 +0800 Subject: [PATCH] hdmitx: add the real sysfs 'dv_cap2' for hdr_priority [1/1] PD#SWPL-20074 Problem: When the variable hdr_priority is true, the original 'dv_cap' will be masked, and systemcontrol can't get the value under 'HDR Priority/HDR10'. Solution: Add the sysfs 'dv_cap2' no matter what's the 'hdr_priority'. Verify: G12 Change-Id: Ia45e4016c1ce4fa17e5102509195afda95a20804 Signed-off-by: Zongdong Jiao --- .../vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c | 42 ++++++++++------ .../vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c | 50 +++++++++++++++---- .../media/vout/hdmi_tx/hdmi_tx_module.h | 5 ++ 3 files changed, 74 insertions(+), 23 deletions(-) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c index e008025fecb3..38f0cc8302dc 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c @@ -859,11 +859,10 @@ static void Edid_ParsingSpeakerDATABlock(struct hdmitx_info *info, } } -static void Edid_ParsingVendSpec(struct rx_cap *prxcap, - unsigned char *buf) +static void _Edid_ParsingVendSpec(struct dv_info *dv, + struct hdr10_plus_info *hdr10_plus, + unsigned char *buf) { - struct dv_info *dv = &prxcap->dv_info; - struct hdr10_plus_info *hdr10_plus = &prxcap->hdr10plus_info; unsigned char *dat = buf; unsigned char pos = 0; unsigned int ieeeoui = 0; @@ -1041,6 +1040,22 @@ static void Edid_ParsingVendSpec(struct rx_cap *prxcap, pr_info("hdmitx: edid: maybe invalid dv%d data\n", dv->ver); } +static void Edid_ParsingVendSpec(struct hdmitx_dev *hdev, + struct rx_cap *prxcap, + unsigned char *buf) +{ + struct dv_info *dv = &prxcap->dv_info; + struct dv_info *dv2 = &prxcap->dv_info2; + struct hdr10_plus_info *hdr10_plus = &prxcap->hdr10plus_info; + + if (hdev->hdr_priority) { /* skip dv_info parsing */ + _Edid_ParsingVendSpec(dv2, hdr10_plus, buf); + return; + } + _Edid_ParsingVendSpec(dv, hdr10_plus, buf); + _Edid_ParsingVendSpec(dv2, hdr10_plus, buf); +} + /* ----------------------------------------------------------- */ static int Edid_ParsingY420VDBBlock(struct rx_cap *prxcap, unsigned char *buf) @@ -1555,7 +1570,7 @@ static void get_ilatency(struct rx_cap *prxcap, unsigned char *val) prxcap->i_aLatency = val[1] * 2 - 1; } -static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device, +static int hdmitx_edid_block_parse(struct hdmitx_dev *hdev, unsigned char *blockbuf) { unsigned char offset, end; @@ -1563,7 +1578,7 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device, unsigned char tag; int i, tmp, idx; unsigned char *vfpdb_offset = NULL; - struct rx_cap *prxcap = &hdmitx_device->rxcap; + struct rx_cap *prxcap = &hdev->rxcap; unsigned int aud_flag = 0; if (blockbuf[0] != 0x02) @@ -1574,7 +1589,7 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device, prxcap->native_VIC = 0xff; - Edid_Y420CMDB_Reset(&(hdmitx_device->hdmi_info)); + Edid_Y420CMDB_Reset(&(hdev->hdmi_info)); for (offset = 4 ; offset < end ; ) { tag = blockbuf[offset] >> 5; @@ -1676,7 +1691,7 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device, !!(blockbuf[offset + 5] & (1 << 6)); prxcap->lte_340mcsc_scramble = !!(blockbuf[offset + 5] & (1 << 3)); - set_vsdb_dc_420_cap(&hdmitx_device->rxcap, + set_vsdb_dc_420_cap(&hdev->rxcap, &blockbuf[offset]); if (count > 7) { unsigned char b7 = blockbuf[offset + 7]; @@ -1709,8 +1724,7 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device, switch (ext_tag) { case EXTENSION_VENDOR_SPECIFIC: t = &blockbuf[offset]; - if (!hdmitx_device->hdr_priority) - Edid_ParsingVendSpec(prxcap, t); + Edid_ParsingVendSpec(hdev, prxcap, t); break; case EXTENSION_COLORMETRY_TAG: prxcap->colorimetry_data = @@ -1740,7 +1754,7 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device, break; case EXTENSION_Y420_CMDB_TAG: Edid_ParsingY420CMDBBlock( - &(hdmitx_device->hdmi_info), + &(hdev->hdmi_info), &blockbuf[offset]); break; default: @@ -1766,10 +1780,10 @@ static int hdmitx_edid_block_parse(struct hdmitx_dev *hdmitx_device, } if (aud_flag == 0) - hdmitx_edid_set_default_aud(hdmitx_device); + hdmitx_edid_set_default_aud(hdev); - Edid_Y420CMDB_PostProcess(hdmitx_device); - hdmitx_device->vic_count = prxcap->VIC_count; + Edid_Y420CMDB_PostProcess(hdev); + hdev->vic_count = prxcap->VIC_count; idx = blockbuf[3] & 0xf; for (i = 0; i < idx; i++) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index 841d54337a13..cc2390567f31 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -2832,6 +2832,7 @@ static ssize_t show_dc_cap(struct device *dev, int pos = 0; struct rx_cap *prxcap = &hdmitx_device.rxcap; const struct dv_info *dv = &hdmitx_device.rxcap.dv_info; + const struct dv_info *dv2 = &hdmitx_device.rxcap.dv_info2; #if 0 if (prxcap->dc_48bit_420) @@ -2866,9 +2867,11 @@ static ssize_t show_dc_cap(struct device *dev, } next444: if (prxcap->dc_y444) { - if ((prxcap->dc_36bit) || (dv->sup_10b_12b_444 == 0x2)) + if ((prxcap->dc_36bit) || (dv->sup_10b_12b_444 == 0x2) || + (dv2->sup_10b_12b_444 == 0x2)) pos += snprintf(buf + pos, PAGE_SIZE, "444,12bit\n"); - if ((prxcap->dc_30bit) || (dv->sup_10b_12b_444 == 0x1)) { + if ((prxcap->dc_30bit) || (dv->sup_10b_12b_444 == 0x1) || + (dv2->sup_10b_12b_444 == 0x1)) { pos += snprintf(buf + pos, PAGE_SIZE, "444,10bit\n"); pos += snprintf(buf + pos, PAGE_SIZE, "444,8bit\n"); } @@ -2876,7 +2879,8 @@ next444: if (prxcap->dc_48bit) pos += snprintf(buf + pos, PAGE_SIZE, "444,16bit\n"); #endif - if ((prxcap->dc_36bit) || (dv->sup_yuv422_12bit)) + if ((prxcap->dc_36bit) || (dv->sup_yuv422_12bit) || + (dv2->sup_yuv422_12bit)) pos += snprintf(buf + pos, PAGE_SIZE, "422,12bit\n"); if (prxcap->dc_30bit) { pos += snprintf(buf + pos, PAGE_SIZE, "422,10bit\n"); @@ -2894,9 +2898,11 @@ nextrgb: if (prxcap->dc_48bit) pos += snprintf(buf + pos, PAGE_SIZE, "rgb,16bit\n"); #endif - if ((prxcap->dc_36bit) || (dv->sup_10b_12b_444 == 0x2)) + if ((prxcap->dc_36bit) || (dv->sup_10b_12b_444 == 0x2) || + (dv2->sup_10b_12b_444 == 0x2)) pos += snprintf(buf + pos, PAGE_SIZE, "rgb,12bit\n"); - if ((prxcap->dc_30bit) || (dv->sup_10b_12b_444 == 0x1)) + if ((prxcap->dc_30bit) || (dv->sup_10b_12b_444 == 0x1) || + (dv2->sup_10b_12b_444 == 0x1)) pos += snprintf(buf + pos, PAGE_SIZE, "rgb,10bit\n"); pos += snprintf(buf + pos, PAGE_SIZE, "rgb,8bit\n"); return pos; @@ -3138,14 +3144,15 @@ static ssize_t show_hdr_cap(struct device *dev, return pos; } -static ssize_t show_dv_cap(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t _show_dv_cap(struct device *dev, + struct device_attribute *attr, + char *buf, + const struct dv_info *dv) { int pos = 0; int i; - const struct dv_info *dv = &hdmitx_device.rxcap.dv_info; - if (dv->ieeeoui != DV_IEEE_OUI || hdmitx_device.hdr_priority) { + if (dv->ieeeoui != DV_IEEE_OUI) { pos += snprintf(buf + pos, PAGE_SIZE, "The Rx don't support DolbyVision\n"); return pos; @@ -3243,6 +3250,28 @@ static ssize_t show_dv_cap(struct device *dev, return pos; } +static ssize_t show_dv_cap(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int pos = 0; + const struct dv_info *dv = &hdmitx_device.rxcap.dv_info; + + if (dv->ieeeoui != DV_IEEE_OUI || hdmitx_device.hdr_priority) { + pos += snprintf(buf + pos, PAGE_SIZE, + "The Rx don't support DolbyVision\n"); + return pos; + } + return _show_dv_cap(dev, attr, buf, dv); +} + +static ssize_t show_dv_cap2(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const struct dv_info *dv2 = &hdmitx_device.rxcap.dv_info2; + + return _show_dv_cap(dev, attr, buf, dv2); +} + static ssize_t show_aud_ch(struct device *dev, struct device_attribute *attr, char *buf) { @@ -4636,6 +4665,7 @@ static DEVICE_ATTR(aud_cap, 0444, show_aud_cap, NULL); static DEVICE_ATTR(hdmi_hdr_status, 0444, show_hdmi_hdr_status, NULL); static DEVICE_ATTR(hdr_cap, 0444, show_hdr_cap, NULL); static DEVICE_ATTR(dv_cap, 0444, show_dv_cap, NULL); +static DEVICE_ATTR(dv_cap2, 0444, show_dv_cap2, NULL); static DEVICE_ATTR(dc_cap, 0444, show_dc_cap, NULL); static DEVICE_ATTR(valid_mode, 0664, show_valid_mode, store_valid_mode); static DEVICE_ATTR(allm_cap, 0444, show_allm_cap, NULL); @@ -5860,6 +5890,7 @@ static int amhdmitx_probe(struct platform_device *pdev) ret = device_create_file(dev, &dev_attr_hdmi_hdr_status); ret = device_create_file(dev, &dev_attr_hdr_cap); ret = device_create_file(dev, &dev_attr_dv_cap); + ret = device_create_file(dev, &dev_attr_dv_cap2); ret = device_create_file(dev, &dev_attr_aud_ch); ret = device_create_file(dev, &dev_attr_avmute); ret = device_create_file(dev, &dev_attr_swap); @@ -5973,6 +6004,7 @@ static int amhdmitx_remove(struct platform_device *pdev) device_remove_file(dev, &dev_attr_disp_cap_3d); device_remove_file(dev, &dev_attr_hdr_cap); device_remove_file(dev, &dev_attr_dv_cap); + device_remove_file(dev, &dev_attr_dv_cap2); device_remove_file(dev, &dev_attr_dc_cap); device_remove_file(dev, &dev_attr_valid_mode); device_remove_file(dev, &dev_attr_allm_cap); diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h index e352aa123f1c..603563f276e2 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h @@ -160,6 +160,11 @@ struct rx_cap { unsigned char side_by_side; } support_3d_format[VIC_MAX_NUM]; struct dv_info dv_info; + /* When hdr_priority is 1, then dv_info will be all 0 + * And select HDR10 to DolbyVision from HDR priority, + * System won't get real dv_cap, but can get real dv_cap2 + */ + struct dv_info dv_info2; enum hdmi_vic preferred_mode; struct dtd dtd[16]; unsigned char dtd_idx;