drm/i2c: tda998x: index audio port enable config by route type

Rather than searching an array for the audio format (which we control)
implement indexing by route type.  This avoids iterating over the array
in several locations.

Tested-by: Sven Van Asbroeck <TheSven73@gmail.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
This commit is contained in:
Russell King 2019-03-01 19:52:23 +00:00
parent 82642ab734
commit 7168916072

View File

@ -35,9 +35,10 @@
#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
struct tda998x_audio_port { enum {
u8 format; /* AFMT_xxx */ AUDIO_ROUTE_I2S,
u8 config; /* AP value */ AUDIO_ROUTE_SPDIF,
AUDIO_ROUTE_NUM
}; };
struct tda998x_audio_settings { struct tda998x_audio_settings {
@ -79,7 +80,7 @@ struct tda998x_priv {
struct drm_bridge bridge; struct drm_bridge bridge;
struct drm_connector connector; struct drm_connector connector;
struct tda998x_audio_port audio_port[2]; u8 audio_port_enable[AUDIO_ROUTE_NUM];
struct tda9950_glue cec_glue; struct tda9950_glue cec_glue;
struct gpio_desc *calib; struct gpio_desc *calib;
struct cec_notifier *cec_notify; struct cec_notifier *cec_notify;
@ -1045,7 +1046,7 @@ static int tda998x_audio_hw_params(struct device *dev, void *data,
struct tda998x_priv *priv = dev_get_drvdata(dev); struct tda998x_priv *priv = dev_get_drvdata(dev);
unsigned int bclk_ratio; unsigned int bclk_ratio;
bool spdif = daifmt->fmt == HDMI_SPDIF; bool spdif = daifmt->fmt == HDMI_SPDIF;
int i, ret; int ret;
struct tda998x_audio_settings audio = { struct tda998x_audio_settings audio = {
.params = { .params = {
.sample_width = params->sample_width, .sample_width = params->sample_width,
@ -1077,10 +1078,7 @@ static int tda998x_audio_hw_params(struct device *dev, void *data,
audio.params.format = spdif ? AFMT_SPDIF : AFMT_I2S; audio.params.format = spdif ? AFMT_SPDIF : AFMT_I2S;
for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) audio.ena_ap = priv->audio_port_enable[AUDIO_ROUTE_I2S + spdif];
if (priv->audio_port[i].format == audio.params.format)
audio.ena_ap = priv->audio_port[i].config;
if (audio.ena_ap == 0) { if (audio.ena_ap == 0) {
dev_err(dev, "%s: No audio configuration found\n", __func__); dev_err(dev, "%s: No audio configuration found\n", __func__);
return -EINVAL; return -EINVAL;
@ -1165,16 +1163,11 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
.ops = &audio_codec_ops, .ops = &audio_codec_ops,
.max_i2s_channels = 2, .max_i2s_channels = 2,
}; };
int i;
for (i = 0; i < ARRAY_SIZE(priv->audio_port); i++) { if (priv->audio_port_enable[AUDIO_ROUTE_I2S])
if (priv->audio_port[i].format == AFMT_I2S && codec_data.i2s = 1;
priv->audio_port[i].config != 0) if (priv->audio_port_enable[AUDIO_ROUTE_SPDIF])
codec_data.i2s = 1; codec_data.spdif = 1;
if (priv->audio_port[i].format == AFMT_SPDIF &&
priv->audio_port[i].config != 0)
codec_data.spdif = 1;
}
priv->audio_pdev = platform_device_register_data( priv->audio_pdev = platform_device_register_data(
dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
@ -1657,7 +1650,7 @@ static int tda998x_get_audio_ports(struct tda998x_priv *priv,
return 0; return 0;
size /= sizeof(u32); size /= sizeof(u32);
if (size > 2 * ARRAY_SIZE(priv->audio_port) || size % 2 != 0) { if (size > 2 * ARRAY_SIZE(priv->audio_port_enable) || size % 2 != 0) {
dev_err(&priv->hdmi->dev, dev_err(&priv->hdmi->dev,
"Bad number of elements in audio-ports dt-property\n"); "Bad number of elements in audio-ports dt-property\n");
return -EINVAL; return -EINVAL;
@ -1666,23 +1659,30 @@ static int tda998x_get_audio_ports(struct tda998x_priv *priv,
size /= 2; size /= 2;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
unsigned int route;
u8 afmt = be32_to_cpup(&port_data[2*i]); u8 afmt = be32_to_cpup(&port_data[2*i]);
u8 ena_ap = be32_to_cpup(&port_data[2*i+1]); u8 ena_ap = be32_to_cpup(&port_data[2*i+1]);
if (afmt != AFMT_SPDIF && afmt != AFMT_I2S) { switch (afmt) {
case AFMT_I2S:
route = AUDIO_ROUTE_I2S;
break;
case AFMT_SPDIF:
route = AUDIO_ROUTE_SPDIF;
break;
default:
dev_err(&priv->hdmi->dev, dev_err(&priv->hdmi->dev,
"Bad audio format %u\n", afmt); "Bad audio format %u\n", afmt);
return -EINVAL; return -EINVAL;
} }
priv->audio_port[i].format = afmt; if (priv->audio_port_enable[route]) {
priv->audio_port[i].config = ena_ap; dev_err(&priv->hdmi->dev,
} "There can only be on I2S port and one SPDIF port\n");
return -EINVAL;
}
if (priv->audio_port[0].format == priv->audio_port[1].format) { priv->audio_port_enable[route] = ena_ap;
dev_err(&priv->hdmi->dev,
"There can only be on I2S port and one SPDIF port\n");
return -EINVAL;
} }
return 0; return 0;
} }
@ -1914,7 +1914,8 @@ static int tda998x_create(struct device *dev)
if (ret) if (ret)
goto fail; goto fail;
if (priv->audio_port[0].format != AFMT_UNUSED) if (priv->audio_port_enable[AUDIO_ROUTE_I2S] ||
priv->audio_port_enable[AUDIO_ROUTE_SPDIF])
tda998x_audio_codec_init(priv, &client->dev); tda998x_audio_codec_init(priv, &client->dev);
} else if (dev->platform_data) { } else if (dev->platform_data) {
ret = tda998x_set_config(priv, dev->platform_data); ret = tda998x_set_config(priv, dev->platform_data);