aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2017-10-23 08:49:34 -0400
committerInki Dae <inki.dae@samsung.com>2017-10-25 20:06:34 -0400
commit691da76f9c90fa618682b88f386b6a1ef304666e (patch)
tree87762832915e86b65fb74498edefab73fdbfc7a9
parentae58c03e0ee13e37f8f56c0158d55f504ad889d2 (diff)
drm: exynos: Add driver for HDMI audio interface
The hdmi-codec interface added in this patch is required to properly support HDMI audio. Currently the audio part of the SoC internal HDMI transmitter is configured with fixed values, which makes HDMI audio working by chance, only on boards having an external audio codec connected in parallel with the HDMI audio transmitter's input I2S interface. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/Kconfig1
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c250
-rw-r--r--drivers/gpu/drm/exynos/regs-hdmi.h8
3 files changed, 194 insertions, 65 deletions
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 305dc3d4ff77..5a7c9d8abd6b 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -3,6 +3,7 @@ config DRM_EXYNOS
3 depends on OF && DRM && (ARCH_S3C64XX || ARCH_EXYNOS || ARCH_MULTIPLATFORM) 3 depends on OF && DRM && (ARCH_S3C64XX || ARCH_EXYNOS || ARCH_MULTIPLATFORM)
4 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 select VIDEOMODE_HELPERS 5 select VIDEOMODE_HELPERS
6 select SND_SOC_HDMI_CODEC if SND_SOC
6 help 7 help
7 Choose this option if you have a Samsung SoC EXYNOS chipset. 8 Choose this option if you have a Samsung SoC EXYNOS chipset.
8 If M is selected the module will be called exynosdrm. 9 If M is selected the module will be called exynosdrm.
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 1309b1c9e074..82d1b7e2febe 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -40,7 +40,7 @@
40#include <linux/component.h> 40#include <linux/component.h>
41#include <linux/mfd/syscon.h> 41#include <linux/mfd/syscon.h>
42#include <linux/regmap.h> 42#include <linux/regmap.h>
43 43#include <sound/hdmi-codec.h>
44#include <drm/exynos_drm.h> 44#include <drm/exynos_drm.h>
45 45
46#include <media/cec-notifier.h> 46#include <media/cec-notifier.h>
@@ -111,12 +111,18 @@ struct hdmi_driver_data {
111 struct string_array_spec clk_muxes; 111 struct string_array_spec clk_muxes;
112}; 112};
113 113
114struct hdmi_audio {
115 struct platform_device *pdev;
116 struct hdmi_audio_infoframe infoframe;
117 struct hdmi_codec_params params;
118 bool mute;
119};
120
114struct hdmi_context { 121struct hdmi_context {
115 struct drm_encoder encoder; 122 struct drm_encoder encoder;
116 struct device *dev; 123 struct device *dev;
117 struct drm_device *drm_dev; 124 struct drm_device *drm_dev;
118 struct drm_connector connector; 125 struct drm_connector connector;
119 bool powered;
120 bool dvi_mode; 126 bool dvi_mode;
121 struct delayed_work hotplug_work; 127 struct delayed_work hotplug_work;
122 struct cec_notifier *notifier; 128 struct cec_notifier *notifier;
@@ -136,6 +142,11 @@ struct hdmi_context {
136 struct regulator *reg_hdmi_en; 142 struct regulator *reg_hdmi_en;
137 struct exynos_drm_clk phy_clk; 143 struct exynos_drm_clk phy_clk;
138 struct drm_bridge *bridge; 144 struct drm_bridge *bridge;
145
146 /* mutex protecting subsequent fields below */
147 struct mutex mutex;
148 struct hdmi_audio audio;
149 bool powered;
139}; 150};
140 151
141static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e) 152static inline struct hdmi_context *encoder_to_hdmi(struct drm_encoder *e)
@@ -776,6 +787,22 @@ static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
776 return ret; 787 return ret;
777} 788}
778 789
790static int hdmi_audio_infoframe_apply(struct hdmi_context *hdata)
791{
792 struct hdmi_audio_infoframe *infoframe = &hdata->audio.infoframe;
793 u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
794 int len;
795
796 len = hdmi_audio_infoframe_pack(infoframe, buf, sizeof(buf));
797 if (len < 0)
798 return len;
799
800 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
801 hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, len);
802
803 return 0;
804}
805
779static void hdmi_reg_infoframes(struct hdmi_context *hdata) 806static void hdmi_reg_infoframes(struct hdmi_context *hdata)
780{ 807{
781 struct drm_display_mode *m = &hdata->encoder.crtc->state->mode; 808 struct drm_display_mode *m = &hdata->encoder.crtc->state->mode;
@@ -812,15 +839,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata)
812 hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3); 839 hdmi_reg_write_buf(hdata, HDMI_VSI_DATA(0), buf + 3, ret - 3);
813 } 840 }
814 841
815 ret = hdmi_audio_infoframe_init(&frm.audio); 842 hdmi_audio_infoframe_apply(hdata);
816 if (!ret) {
817 frm.audio.channels = 2;
818 ret = hdmi_audio_infoframe_pack(&frm.audio, buf, sizeof(buf));
819 }
820 if (ret > 0) {
821 hdmi_reg_writeb(hdata, HDMI_AUI_CON, HDMI_AUI_CON_EVERY_VSYNC);
822 hdmi_reg_write_buf(hdata, HDMI_AUI_HEADER0, buf, ret);
823 }
824} 843}
825 844
826static enum drm_connector_status hdmi_detect(struct drm_connector *connector, 845static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
@@ -1010,23 +1029,18 @@ static void hdmi_reg_acr(struct hdmi_context *hdata, u32 freq)
1010 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4); 1029 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1011} 1030}
1012 1031
1013static void hdmi_audio_init(struct hdmi_context *hdata) 1032static void hdmi_audio_config(struct hdmi_context *hdata)
1014{ 1033{
1015 u32 sample_rate, bits_per_sample; 1034 u32 bit_ch = 1;
1016 u32 data_num, bit_ch, sample_frq; 1035 u32 data_num, val;
1017 u32 val; 1036 int i;
1018
1019 sample_rate = 44100;
1020 bits_per_sample = 16;
1021 1037
1022 switch (bits_per_sample) { 1038 switch (hdata->audio.params.sample_width) {
1023 case 20: 1039 case 20:
1024 data_num = 2; 1040 data_num = 2;
1025 bit_ch = 1;
1026 break; 1041 break;
1027 case 24: 1042 case 24:
1028 data_num = 3; 1043 data_num = 3;
1029 bit_ch = 1;
1030 break; 1044 break;
1031 default: 1045 default:
1032 data_num = 1; 1046 data_num = 1;
@@ -1034,7 +1048,7 @@ static void hdmi_audio_init(struct hdmi_context *hdata)
1034 break; 1048 break;
1035 } 1049 }
1036 1050
1037 hdmi_reg_acr(hdata, sample_rate); 1051 hdmi_reg_acr(hdata, hdata->audio.params.sample_rate);
1038 1052
1039 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE 1053 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1040 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE 1054 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
@@ -1044,12 +1058,6 @@ static void hdmi_audio_init(struct hdmi_context *hdata)
1044 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN); 1058 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1045 1059
1046 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN); 1060 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1047
1048 sample_frq = (sample_rate == 44100) ? 0 :
1049 (sample_rate == 48000) ? 2 :
1050 (sample_rate == 32000) ? 3 :
1051 (sample_rate == 96000) ? 0xa : 0x0;
1052
1053 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS); 1061 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1054 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN); 1062 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1055 1063
@@ -1073,31 +1081,24 @@ static void hdmi_audio_init(struct hdmi_context *hdata)
1073 | HDMI_I2S_SET_SDATA_BIT(data_num) 1081 | HDMI_I2S_SET_SDATA_BIT(data_num)
1074 | HDMI_I2S_BASIC_FORMAT); 1082 | HDMI_I2S_BASIC_FORMAT);
1075 1083
1076 /* Configure register related to CUV information */ 1084 /* Configuration of the audio channel status registers */
1077 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0 1085 for (i = 0; i < HDMI_I2S_CH_ST_MAXNUM; i++)
1078 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH 1086 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST(i),
1079 | HDMI_I2S_COPYRIGHT 1087 hdata->audio.params.iec.status[i]);
1080 | HDMI_I2S_LINEAR_PCM
1081 | HDMI_I2S_CONSUMER_FORMAT);
1082 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1083 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1084 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1085 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1086 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1087 HDMI_I2S_ORG_SMP_FREQ_44_1
1088 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1089 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1090 1088
1091 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD); 1089 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1092} 1090}
1093 1091
1094static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff) 1092static void hdmi_audio_control(struct hdmi_context *hdata)
1095{ 1093{
1094 bool enable = !hdata->audio.mute;
1095
1096 if (hdata->dvi_mode) 1096 if (hdata->dvi_mode)
1097 return; 1097 return;
1098 1098
1099 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0); 1099 hdmi_reg_writeb(hdata, HDMI_AUI_CON, enable ?
1100 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ? 1100 HDMI_AVI_CON_EVERY_VSYNC : HDMI_AUI_CON_NO_TRAN);
1101 hdmi_reg_writemask(hdata, HDMI_CON_0, enable ?
1101 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK); 1102 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1102} 1103}
1103 1104
@@ -1428,13 +1429,14 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1428 hdmiphy_wait_for_pll(hdata); 1429 hdmiphy_wait_for_pll(hdata);
1429} 1430}
1430 1431
1432/* Should be called with hdata->mutex mutex held */
1431static void hdmi_conf_apply(struct hdmi_context *hdata) 1433static void hdmi_conf_apply(struct hdmi_context *hdata)
1432{ 1434{
1433 hdmi_start(hdata, false); 1435 hdmi_start(hdata, false);
1434 hdmi_conf_init(hdata); 1436 hdmi_conf_init(hdata);
1435 hdmi_audio_init(hdata); 1437 hdmi_audio_config(hdata);
1436 hdmi_mode_apply(hdata); 1438 hdmi_mode_apply(hdata);
1437 hdmi_audio_control(hdata, true); 1439 hdmi_audio_control(hdata);
1438} 1440}
1439 1441
1440static void hdmi_set_refclk(struct hdmi_context *hdata, bool on) 1442static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
@@ -1446,6 +1448,7 @@ static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1446 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0); 1448 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1447} 1449}
1448 1450
1451/* Should be called with hdata->mutex mutex held. */
1449static void hdmiphy_enable(struct hdmi_context *hdata) 1452static void hdmiphy_enable(struct hdmi_context *hdata)
1450{ 1453{
1451 if (hdata->powered) 1454 if (hdata->powered)
@@ -1468,6 +1471,7 @@ static void hdmiphy_enable(struct hdmi_context *hdata)
1468 hdata->powered = true; 1471 hdata->powered = true;
1469} 1472}
1470 1473
1474/* Should be called with hdata->mutex mutex held. */
1471static void hdmiphy_disable(struct hdmi_context *hdata) 1475static void hdmiphy_disable(struct hdmi_context *hdata)
1472{ 1476{
1473 if (!hdata->powered) 1477 if (!hdata->powered)
@@ -1493,28 +1497,38 @@ static void hdmi_enable(struct drm_encoder *encoder)
1493{ 1497{
1494 struct hdmi_context *hdata = encoder_to_hdmi(encoder); 1498 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1495 1499
1500 mutex_lock(&hdata->mutex);
1501
1496 hdmiphy_enable(hdata); 1502 hdmiphy_enable(hdata);
1497 hdmi_conf_apply(hdata); 1503 hdmi_conf_apply(hdata);
1504
1505 mutex_unlock(&hdata->mutex);
1498} 1506}
1499 1507
1500static void hdmi_disable(struct drm_encoder *encoder) 1508static void hdmi_disable(struct drm_encoder *encoder)
1501{ 1509{
1502 struct hdmi_context *hdata = encoder_to_hdmi(encoder); 1510 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
1503 1511
1504 if (!hdata->powered) 1512 mutex_lock(&hdata->mutex);
1513
1514 if (hdata->powered) {
1515 /*
1516 * The SFRs of VP and Mixer are updated by Vertical Sync of
1517 * Timing generator which is a part of HDMI so the sequence
1518 * to disable TV Subsystem should be as following,
1519 * VP -> Mixer -> HDMI
1520 *
1521 * To achieve such sequence HDMI is disabled together with
1522 * HDMI PHY, via pipe clock callback.
1523 */
1524 mutex_unlock(&hdata->mutex);
1525 cancel_delayed_work(&hdata->hotplug_work);
1526 cec_notifier_set_phys_addr(hdata->notifier,
1527 CEC_PHYS_ADDR_INVALID);
1505 return; 1528 return;
1529 }
1506 1530
1507 /* 1531 mutex_unlock(&hdata->mutex);
1508 * The SFRs of VP and Mixer are updated by Vertical Sync of
1509 * Timing generator which is a part of HDMI so the sequence
1510 * to disable TV Subsystem should be as following,
1511 * VP -> Mixer -> HDMI
1512 *
1513 * To achieve such sequence HDMI is disabled together with HDMI PHY, via
1514 * pipe clock callback.
1515 */
1516 cancel_delayed_work(&hdata->hotplug_work);
1517 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
1518} 1532}
1519 1533
1520static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = { 1534static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
@@ -1527,6 +1541,99 @@ static const struct drm_encoder_funcs exynos_hdmi_encoder_funcs = {
1527 .destroy = drm_encoder_cleanup, 1541 .destroy = drm_encoder_cleanup,
1528}; 1542};
1529 1543
1544static void hdmi_audio_shutdown(struct device *dev, void *data)
1545{
1546 struct hdmi_context *hdata = dev_get_drvdata(dev);
1547
1548 mutex_lock(&hdata->mutex);
1549
1550 hdata->audio.mute = true;
1551
1552 if (hdata->powered)
1553 hdmi_audio_control(hdata);
1554
1555 mutex_unlock(&hdata->mutex);
1556}
1557
1558static int hdmi_audio_hw_params(struct device *dev, void *data,
1559 struct hdmi_codec_daifmt *daifmt,
1560 struct hdmi_codec_params *params)
1561{
1562 struct hdmi_context *hdata = dev_get_drvdata(dev);
1563
1564 if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv ||
1565 daifmt->frame_clk_inv || daifmt->bit_clk_master ||
1566 daifmt->frame_clk_master) {
1567 dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__,
1568 daifmt->bit_clk_inv, daifmt->frame_clk_inv,
1569 daifmt->bit_clk_master,
1570 daifmt->frame_clk_master);
1571 return -EINVAL;
1572 }
1573
1574 mutex_lock(&hdata->mutex);
1575
1576 hdata->audio.params = *params;
1577
1578 if (hdata->powered) {
1579 hdmi_audio_config(hdata);
1580 hdmi_audio_infoframe_apply(hdata);
1581 }
1582
1583 mutex_unlock(&hdata->mutex);
1584
1585 return 0;
1586}
1587
1588static int hdmi_audio_digital_mute(struct device *dev, void *data, bool mute)
1589{
1590 struct hdmi_context *hdata = dev_get_drvdata(dev);
1591
1592 mutex_lock(&hdata->mutex);
1593
1594 hdata->audio.mute = mute;
1595
1596 if (hdata->powered)
1597 hdmi_audio_control(hdata);
1598
1599 mutex_unlock(&hdata->mutex);
1600
1601 return 0;
1602}
1603
1604static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
1605 size_t len)
1606{
1607 struct hdmi_context *hdata = dev_get_drvdata(dev);
1608 struct drm_connector *connector = &hdata->connector;
1609
1610 memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
1611
1612 return 0;
1613}
1614
1615static const struct hdmi_codec_ops audio_codec_ops = {
1616 .hw_params = hdmi_audio_hw_params,
1617 .audio_shutdown = hdmi_audio_shutdown,
1618 .digital_mute = hdmi_audio_digital_mute,
1619 .get_eld = hdmi_audio_get_eld,
1620};
1621
1622static int hdmi_register_audio_device(struct hdmi_context *hdata)
1623{
1624 struct hdmi_codec_pdata codec_data = {
1625 .ops = &audio_codec_ops,
1626 .max_i2s_channels = 6,
1627 .i2s = 1,
1628 };
1629
1630 hdata->audio.pdev = platform_device_register_data(
1631 hdata->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
1632 &codec_data, sizeof(codec_data));
1633
1634 return PTR_ERR_OR_ZERO(hdata->audio.pdev);
1635}
1636
1530static void hdmi_hotplug_work_func(struct work_struct *work) 1637static void hdmi_hotplug_work_func(struct work_struct *work)
1531{ 1638{
1532 struct hdmi_context *hdata; 1639 struct hdmi_context *hdata;
@@ -1602,11 +1709,14 @@ static void hdmiphy_clk_enable(struct exynos_drm_clk *clk, bool enable)
1602{ 1709{
1603 struct hdmi_context *hdata = container_of(clk, struct hdmi_context, 1710 struct hdmi_context *hdata = container_of(clk, struct hdmi_context,
1604 phy_clk); 1711 phy_clk);
1712 mutex_lock(&hdata->mutex);
1605 1713
1606 if (enable) 1714 if (enable)
1607 hdmiphy_enable(hdata); 1715 hdmiphy_enable(hdata);
1608 else 1716 else
1609 hdmiphy_disable(hdata); 1717 hdmiphy_disable(hdata);
1718
1719 mutex_unlock(&hdata->mutex);
1610} 1720}
1611 1721
1612static int hdmi_bridge_init(struct hdmi_context *hdata) 1722static int hdmi_bridge_init(struct hdmi_context *hdata)
@@ -1817,6 +1927,7 @@ out:
1817 1927
1818static int hdmi_probe(struct platform_device *pdev) 1928static int hdmi_probe(struct platform_device *pdev)
1819{ 1929{
1930 struct hdmi_audio_infoframe *audio_infoframe;
1820 struct device *dev = &pdev->dev; 1931 struct device *dev = &pdev->dev;
1821 struct hdmi_context *hdata; 1932 struct hdmi_context *hdata;
1822 struct resource *res; 1933 struct resource *res;
@@ -1832,6 +1943,8 @@ static int hdmi_probe(struct platform_device *pdev)
1832 1943
1833 hdata->dev = dev; 1944 hdata->dev = dev;
1834 1945
1946 mutex_init(&hdata->mutex);
1947
1835 ret = hdmi_resources_init(hdata); 1948 ret = hdmi_resources_init(hdata);
1836 if (ret) { 1949 if (ret) {
1837 if (ret != -EPROBE_DEFER) 1950 if (ret != -EPROBE_DEFER)
@@ -1891,12 +2004,26 @@ static int hdmi_probe(struct platform_device *pdev)
1891 2004
1892 pm_runtime_enable(dev); 2005 pm_runtime_enable(dev);
1893 2006
1894 ret = component_add(&pdev->dev, &hdmi_component_ops); 2007 audio_infoframe = &hdata->audio.infoframe;
2008 hdmi_audio_infoframe_init(audio_infoframe);
2009 audio_infoframe->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
2010 audio_infoframe->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
2011 audio_infoframe->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
2012 audio_infoframe->channels = 2;
2013
2014 ret = hdmi_register_audio_device(hdata);
1895 if (ret) 2015 if (ret)
1896 goto err_notifier_put; 2016 goto err_notifier_put;
1897 2017
2018 ret = component_add(&pdev->dev, &hdmi_component_ops);
2019 if (ret)
2020 goto err_unregister_audio;
2021
1898 return ret; 2022 return ret;
1899 2023
2024err_unregister_audio:
2025 platform_device_unregister(hdata->audio.pdev);
2026
1900err_notifier_put: 2027err_notifier_put:
1901 cec_notifier_put(hdata->notifier); 2028 cec_notifier_put(hdata->notifier);
1902 pm_runtime_disable(dev); 2029 pm_runtime_disable(dev);
@@ -1920,6 +2047,7 @@ static int hdmi_remove(struct platform_device *pdev)
1920 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID); 2047 cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
1921 2048
1922 component_del(&pdev->dev, &hdmi_component_ops); 2049 component_del(&pdev->dev, &hdmi_component_ops);
2050 platform_device_unregister(hdata->audio.pdev);
1923 2051
1924 cec_notifier_put(hdata->notifier); 2052 cec_notifier_put(hdata->notifier);
1925 pm_runtime_disable(&pdev->dev); 2053 pm_runtime_disable(&pdev->dev);
@@ -1935,6 +2063,8 @@ static int hdmi_remove(struct platform_device *pdev)
1935 2063
1936 put_device(&hdata->ddc_adpt->dev); 2064 put_device(&hdata->ddc_adpt->dev);
1937 2065
2066 mutex_destroy(&hdata->mutex);
2067
1938 return 0; 2068 return 0;
1939} 2069}
1940 2070
diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h
index a0507dc18d9e..04be0f7e8193 100644
--- a/drivers/gpu/drm/exynos/regs-hdmi.h
+++ b/drivers/gpu/drm/exynos/regs-hdmi.h
@@ -419,11 +419,9 @@
419#define HDMI_I2S_DSD_CON HDMI_I2S_BASE(0x01c) 419#define HDMI_I2S_DSD_CON HDMI_I2S_BASE(0x01c)
420#define HDMI_I2S_MUX_CON HDMI_I2S_BASE(0x020) 420#define HDMI_I2S_MUX_CON HDMI_I2S_BASE(0x020)
421#define HDMI_I2S_CH_ST_CON HDMI_I2S_BASE(0x024) 421#define HDMI_I2S_CH_ST_CON HDMI_I2S_BASE(0x024)
422#define HDMI_I2S_CH_ST_0 HDMI_I2S_BASE(0x028) 422/* n must be within range 0...(HDMI_I2S_CH_ST_MAXNUM - 1) */
423#define HDMI_I2S_CH_ST_1 HDMI_I2S_BASE(0x02c) 423#define HDMI_I2S_CH_ST_MAXNUM 5
424#define HDMI_I2S_CH_ST_2 HDMI_I2S_BASE(0x030) 424#define HDMI_I2S_CH_ST(n) HDMI_I2S_BASE(0x028 + 4 * (n))
425#define HDMI_I2S_CH_ST_3 HDMI_I2S_BASE(0x034)
426#define HDMI_I2S_CH_ST_4 HDMI_I2S_BASE(0x038)
427#define HDMI_I2S_CH_ST_SH_0 HDMI_I2S_BASE(0x03c) 425#define HDMI_I2S_CH_ST_SH_0 HDMI_I2S_BASE(0x03c)
428#define HDMI_I2S_CH_ST_SH_1 HDMI_I2S_BASE(0x040) 426#define HDMI_I2S_CH_ST_SH_1 HDMI_I2S_BASE(0x040)
429#define HDMI_I2S_CH_ST_SH_2 HDMI_I2S_BASE(0x044) 427#define HDMI_I2S_CH_ST_SH_2 HDMI_I2S_BASE(0x044)