diff options
| author | Russell King <rmk+kernel@armlinux.org.uk> | 2016-10-23 06:30:56 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@armlinux.org.uk> | 2016-11-17 19:00:40 -0500 |
| commit | ad975f9364a3e1beb0909a009671c122b47763cd (patch) | |
| tree | c6585ded985092c1287907b3ea488cee022efbdf | |
| parent | a2f75662b7c3db2ca2e18aaaa5fa86d5991b0d70 (diff) | |
drm/i2c: tda998x: group audio functions together
Group the TDA998x audio functions together rather than split between
two different locations in the file, keeping like code together.
Tested-by: Jon Medhurst <tixy@linaro.org>
Acked-by: Jon Medhurst <tixy@linaro.org>
Tested-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
| -rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 276 |
1 files changed, 139 insertions, 137 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 44f3a4e9b902..0f604d2dd1c7 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
| @@ -702,6 +702,8 @@ tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) | |||
| 702 | tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame); | 702 | tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame); |
| 703 | } | 703 | } |
| 704 | 704 | ||
| 705 | /* Audio support */ | ||
| 706 | |||
| 705 | static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) | 707 | static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) |
| 706 | { | 708 | { |
| 707 | if (on) { | 709 | if (on) { |
| @@ -820,6 +822,143 @@ tda998x_configure_audio(struct tda998x_priv *priv, | |||
| 820 | return tda998x_write_aif(priv, ¶ms->cea); | 822 | return tda998x_write_aif(priv, ¶ms->cea); |
| 821 | } | 823 | } |
| 822 | 824 | ||
| 825 | static int tda998x_audio_hw_params(struct device *dev, void *data, | ||
| 826 | struct hdmi_codec_daifmt *daifmt, | ||
| 827 | struct hdmi_codec_params *params) | ||
| 828 | { | ||
| 829 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 830 | int i, ret; | ||
| 831 | struct tda998x_audio_params audio = { | ||
| 832 | .sample_width = params->sample_width, | ||
| 833 | .sample_rate = params->sample_rate, | ||
| 834 | .cea = params->cea, | ||
| 835 | }; | ||
| 836 | |||
| 837 | memcpy(audio.status, params->iec.status, | ||
| 838 | min(sizeof(audio.status), sizeof(params->iec.status))); | ||
| 839 | |||
| 840 | switch (daifmt->fmt) { | ||
| 841 | case HDMI_I2S: | ||
| 842 | if (daifmt->bit_clk_inv || daifmt->frame_clk_inv || | ||
| 843 | daifmt->bit_clk_master || daifmt->frame_clk_master) { | ||
| 844 | dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, | ||
| 845 | daifmt->bit_clk_inv, daifmt->frame_clk_inv, | ||
| 846 | daifmt->bit_clk_master, | ||
| 847 | daifmt->frame_clk_master); | ||
| 848 | return -EINVAL; | ||
| 849 | } | ||
| 850 | for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) | ||
| 851 | if (priv->audio_port[i].format == AFMT_I2S) | ||
| 852 | audio.config = priv->audio_port[i].config; | ||
| 853 | audio.format = AFMT_I2S; | ||
| 854 | break; | ||
| 855 | case HDMI_SPDIF: | ||
| 856 | for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) | ||
| 857 | if (priv->audio_port[i].format == AFMT_SPDIF) | ||
| 858 | audio.config = priv->audio_port[i].config; | ||
| 859 | audio.format = AFMT_SPDIF; | ||
| 860 | break; | ||
| 861 | default: | ||
| 862 | dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt); | ||
| 863 | return -EINVAL; | ||
| 864 | } | ||
| 865 | |||
| 866 | if (audio.config == 0) { | ||
| 867 | dev_err(dev, "%s: No audio configutation found\n", __func__); | ||
| 868 | return -EINVAL; | ||
| 869 | } | ||
| 870 | |||
| 871 | mutex_lock(&priv->audio_mutex); | ||
| 872 | if (priv->supports_infoframes && priv->sink_has_audio) | ||
| 873 | ret = tda998x_configure_audio(priv, &audio); | ||
| 874 | else | ||
| 875 | ret = 0; | ||
| 876 | |||
| 877 | if (ret == 0) | ||
| 878 | priv->audio_params = audio; | ||
| 879 | mutex_unlock(&priv->audio_mutex); | ||
| 880 | |||
| 881 | return ret; | ||
| 882 | } | ||
| 883 | |||
| 884 | static void tda998x_audio_shutdown(struct device *dev, void *data) | ||
| 885 | { | ||
| 886 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 887 | |||
| 888 | mutex_lock(&priv->audio_mutex); | ||
| 889 | |||
| 890 | reg_write(priv, REG_ENA_AP, 0); | ||
| 891 | |||
| 892 | priv->audio_params.format = AFMT_UNUSED; | ||
| 893 | |||
| 894 | mutex_unlock(&priv->audio_mutex); | ||
| 895 | } | ||
| 896 | |||
| 897 | int tda998x_audio_digital_mute(struct device *dev, void *data, bool enable) | ||
| 898 | { | ||
| 899 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 900 | |||
| 901 | mutex_lock(&priv->audio_mutex); | ||
| 902 | |||
| 903 | tda998x_audio_mute(priv, enable); | ||
| 904 | |||
| 905 | mutex_unlock(&priv->audio_mutex); | ||
| 906 | return 0; | ||
| 907 | } | ||
| 908 | |||
| 909 | static int tda998x_audio_get_eld(struct device *dev, void *data, | ||
| 910 | uint8_t *buf, size_t len) | ||
| 911 | { | ||
| 912 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 913 | struct drm_mode_config *config = &priv->encoder.dev->mode_config; | ||
| 914 | struct drm_connector *connector; | ||
| 915 | int ret = -ENODEV; | ||
| 916 | |||
| 917 | mutex_lock(&config->mutex); | ||
| 918 | list_for_each_entry(connector, &config->connector_list, head) { | ||
| 919 | if (&priv->encoder == connector->encoder) { | ||
| 920 | memcpy(buf, connector->eld, | ||
| 921 | min(sizeof(connector->eld), len)); | ||
| 922 | ret = 0; | ||
| 923 | } | ||
| 924 | } | ||
| 925 | mutex_unlock(&config->mutex); | ||
| 926 | |||
| 927 | return ret; | ||
| 928 | } | ||
| 929 | |||
| 930 | static const struct hdmi_codec_ops audio_codec_ops = { | ||
| 931 | .hw_params = tda998x_audio_hw_params, | ||
| 932 | .audio_shutdown = tda998x_audio_shutdown, | ||
| 933 | .digital_mute = tda998x_audio_digital_mute, | ||
| 934 | .get_eld = tda998x_audio_get_eld, | ||
| 935 | }; | ||
| 936 | |||
| 937 | static int tda998x_audio_codec_init(struct tda998x_priv *priv, | ||
| 938 | struct device *dev) | ||
| 939 | { | ||
| 940 | struct hdmi_codec_pdata codec_data = { | ||
| 941 | .ops = &audio_codec_ops, | ||
| 942 | .max_i2s_channels = 2, | ||
| 943 | }; | ||
| 944 | int i; | ||
| 945 | |||
| 946 | for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) { | ||
| 947 | if (priv->audio_port[i].format == AFMT_I2S && | ||
| 948 | priv->audio_port[i].config != 0) | ||
| 949 | codec_data.i2s = 1; | ||
| 950 | if (priv->audio_port[i].format == AFMT_SPDIF && | ||
| 951 | priv->audio_port[i].config != 0) | ||
| 952 | codec_data.spdif = 1; | ||
| 953 | } | ||
| 954 | |||
| 955 | priv->audio_pdev = platform_device_register_data( | ||
| 956 | dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, | ||
| 957 | &codec_data, sizeof(codec_data)); | ||
| 958 | |||
| 959 | return PTR_ERR_OR_ZERO(priv->audio_pdev); | ||
| 960 | } | ||
| 961 | |||
| 823 | /* DRM connector functions */ | 962 | /* DRM connector functions */ |
| 824 | 963 | ||
| 825 | static int tda998x_connector_dpms(struct drm_connector *connector, int mode) | 964 | static int tda998x_connector_dpms(struct drm_connector *connector, int mode) |
| @@ -1284,143 +1423,6 @@ static void tda998x_destroy(struct tda998x_priv *priv) | |||
| 1284 | i2c_unregister_device(priv->cec); | 1423 | i2c_unregister_device(priv->cec); |
| 1285 | } | 1424 | } |
| 1286 | 1425 | ||
| 1287 | static int tda998x_audio_hw_params(struct device *dev, void *data, | ||
| 1288 | struct hdmi_codec_daifmt *daifmt, | ||
| 1289 | struct hdmi_codec_params *params) | ||
| 1290 | { | ||
| 1291 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 1292 | int i, ret; | ||
| 1293 | struct tda998x_audio_params audio = { | ||
| 1294 | .sample_width = params->sample_width, | ||
| 1295 | .sample_rate = params->sample_rate, | ||
| 1296 | .cea = params->cea, | ||
| 1297 | }; | ||
| 1298 | |||
| 1299 | memcpy(audio.status, params->iec.status, | ||
| 1300 | min(sizeof(audio.status), sizeof(params->iec.status))); | ||
| 1301 | |||
| 1302 | switch (daifmt->fmt) { | ||
| 1303 | case HDMI_I2S: | ||
| 1304 | if (daifmt->bit_clk_inv || daifmt->frame_clk_inv || | ||
| 1305 | daifmt->bit_clk_master || daifmt->frame_clk_master) { | ||
| 1306 | dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, | ||
| 1307 | daifmt->bit_clk_inv, daifmt->frame_clk_inv, | ||
| 1308 | daifmt->bit_clk_master, | ||
| 1309 | daifmt->frame_clk_master); | ||
| 1310 | return -EINVAL; | ||
| 1311 | } | ||
| 1312 | for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) | ||
| 1313 | if (priv->audio_port[i].format == AFMT_I2S) | ||
| 1314 | audio.config = priv->audio_port[i].config; | ||
| 1315 | audio.format = AFMT_I2S; | ||
| 1316 | break; | ||
| 1317 | case HDMI_SPDIF: | ||
| 1318 | for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) | ||
| 1319 | if (priv->audio_port[i].format == AFMT_SPDIF) | ||
| 1320 | audio.config = priv->audio_port[i].config; | ||
| 1321 | audio.format = AFMT_SPDIF; | ||
| 1322 | break; | ||
| 1323 | default: | ||
| 1324 | dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt); | ||
| 1325 | return -EINVAL; | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | if (audio.config == 0) { | ||
| 1329 | dev_err(dev, "%s: No audio configutation found\n", __func__); | ||
| 1330 | return -EINVAL; | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | mutex_lock(&priv->audio_mutex); | ||
| 1334 | if (priv->supports_infoframes && priv->sink_has_audio) | ||
| 1335 | ret = tda998x_configure_audio(priv, &audio); | ||
| 1336 | else | ||
| 1337 | ret = 0; | ||
| 1338 | |||
| 1339 | if (ret == 0) | ||
| 1340 | priv->audio_params = audio; | ||
| 1341 | mutex_unlock(&priv->audio_mutex); | ||
| 1342 | |||
| 1343 | return ret; | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | static void tda998x_audio_shutdown(struct device *dev, void *data) | ||
| 1347 | { | ||
| 1348 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 1349 | |||
| 1350 | mutex_lock(&priv->audio_mutex); | ||
| 1351 | |||
| 1352 | reg_write(priv, REG_ENA_AP, 0); | ||
| 1353 | |||
| 1354 | priv->audio_params.format = AFMT_UNUSED; | ||
| 1355 | |||
| 1356 | mutex_unlock(&priv->audio_mutex); | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | int tda998x_audio_digital_mute(struct device *dev, void *data, bool enable) | ||
| 1360 | { | ||
| 1361 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 1362 | |||
| 1363 | mutex_lock(&priv->audio_mutex); | ||
| 1364 | |||
| 1365 | tda998x_audio_mute(priv, enable); | ||
| 1366 | |||
| 1367 | mutex_unlock(&priv->audio_mutex); | ||
| 1368 | return 0; | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | static int tda998x_audio_get_eld(struct device *dev, void *data, | ||
| 1372 | uint8_t *buf, size_t len) | ||
| 1373 | { | ||
| 1374 | struct tda998x_priv *priv = dev_get_drvdata(dev); | ||
| 1375 | struct drm_mode_config *config = &priv->encoder.dev->mode_config; | ||
| 1376 | struct drm_connector *connector; | ||
| 1377 | int ret = -ENODEV; | ||
| 1378 | |||
| 1379 | mutex_lock(&config->mutex); | ||
| 1380 | list_for_each_entry(connector, &config->connector_list, head) { | ||
| 1381 | if (&priv->encoder == connector->encoder) { | ||
| 1382 | memcpy(buf, connector->eld, | ||
| 1383 | min(sizeof(connector->eld), len)); | ||
| 1384 | ret = 0; | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | mutex_unlock(&config->mutex); | ||
| 1388 | |||
| 1389 | return ret; | ||
| 1390 | } | ||
| 1391 | |||
| 1392 | static const struct hdmi_codec_ops audio_codec_ops = { | ||
| 1393 | .hw_params = tda998x_audio_hw_params, | ||
| 1394 | .audio_shutdown = tda998x_audio_shutdown, | ||
| 1395 | .digital_mute = tda998x_audio_digital_mute, | ||
| 1396 | .get_eld = tda998x_audio_get_eld, | ||
| 1397 | }; | ||
| 1398 | |||
| 1399 | static int tda998x_audio_codec_init(struct tda998x_priv *priv, | ||
| 1400 | struct device *dev) | ||
| 1401 | { | ||
| 1402 | struct hdmi_codec_pdata codec_data = { | ||
| 1403 | .ops = &audio_codec_ops, | ||
| 1404 | .max_i2s_channels = 2, | ||
| 1405 | }; | ||
| 1406 | int i; | ||
| 1407 | |||
| 1408 | for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) { | ||
| 1409 | if (priv->audio_port[i].format == AFMT_I2S && | ||
| 1410 | priv->audio_port[i].config != 0) | ||
| 1411 | codec_data.i2s = 1; | ||
| 1412 | if (priv->audio_port[i].format == AFMT_SPDIF && | ||
| 1413 | priv->audio_port[i].config != 0) | ||
| 1414 | codec_data.spdif = 1; | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | priv->audio_pdev = platform_device_register_data( | ||
| 1418 | dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, | ||
| 1419 | &codec_data, sizeof(codec_data)); | ||
| 1420 | |||
| 1421 | return PTR_ERR_OR_ZERO(priv->audio_pdev); | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | /* I2C driver functions */ | 1426 | /* I2C driver functions */ |
| 1425 | 1427 | ||
| 1426 | static int tda998x_get_audio_ports(struct tda998x_priv *priv, | 1428 | static int tda998x_get_audio_ports(struct tda998x_priv *priv, |
