Re: [PATCH 08/13] drm/i2c: tda998x: move audio routing configuration

2019-06-13 Thread Sven Van Asbroeck
On Tue, Jun 11, 2019 at 7:02 AM Russell King  wrote:
>
> Move the mux and clocking selection out of tda998x_configure_audio()
> into the parent functions, so we can validate this when parameters
> are set outside of the audio mutex.
>
> Signed-off-by: Russell King 
> ---

+/* Configure the TDA998x audio data and clock routing. */
+static int tda998x_derive_routing(struct tda998x_priv *priv,
+ struct tda998x_audio_settings *s,
+ unsigned int route)
+{
+   s->route = _audio_route[route];
+   s->ena_ap = priv->audio_port_enable[route];
+   if (s->ena_ap == 0) {
+   dev_err(>hdmi->dev, "no audio configuration found\n");
+   return -EINVAL;
+   }
+
+   return 0;
+}

Nit: priv is nearly unused in this function.
Maybe delegate the error log to the caller, in that case we could just pass
route and const audio_port_enable to the function. Instead of passing in the
'kitchen sink' priv ?
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 08/13] drm/i2c: tda998x: move audio routing configuration

2019-06-12 Thread Russell King - ARM Linux admin
On Wed, Jun 12, 2019 at 11:36:59AM -0400, Sven Van Asbroeck wrote:
> On Tue, Jun 11, 2019 at 7:02 AM Russell King  
> wrote:
> >
> > Move the mux and clocking selection out of tda998x_configure_audio()
> > into the parent functions, so we can validate this when parameters
> > are set outside of the audio mutex.
> >
> > Signed-off-by: Russell King 
> > ---
> 
> +/* Configure the TDA998x audio data and clock routing. */
> +static int tda998x_derive_routing(struct tda998x_priv *priv,
> + struct tda998x_audio_settings *s,
> + unsigned int route)
> +{
> +   s->route = _audio_route[route];
> +   s->ena_ap = priv->audio_port_enable[route];
> +   if (s->ena_ap == 0) {
> +   dev_err(>hdmi->dev, "no audio configuration found\n");
> +   return -EINVAL;
> +   }
> +
> +   return 0;
> +}
> 
> Nit: priv is nearly unused in this function.
> Maybe delegate the error log to the caller, in that case we could just pass
> route and const audio_port_enable to the function. Instead of passing in the
> 'kitchen sink' priv ?

I don't think that's worth doing.  This way, compilers are free to
emit code to bounds-check the audio_port_enable access since they
know that it is a defined size.  Passing in a const pointer ca
mean that check has to be avoided.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 08/13] drm/i2c: tda998x: move audio routing configuration

2019-06-12 Thread Russell King
Move the mux and clocking selection out of tda998x_configure_audio()
into the parent functions, so we can validate this when parameters
are set outside of the audio mutex.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/i2c/tda998x_drv.c | 78 +++
 1 file changed, 47 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 8b79619ff152..14d1672301ae 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -41,7 +41,14 @@ enum {
AUDIO_ROUTE_NUM
 };
 
+struct tda998x_audio_route {
+   u8 ena_aclk;
+   u8 mux_ap;
+   u8 aip_clksel;
+};
+
 struct tda998x_audio_settings {
+   const struct tda998x_audio_route *route;
struct tda998x_audio_params params;
u8 ena_ap;
u8 i2s_format;
@@ -868,6 +875,34 @@ tda998x_write_avi(struct tda998x_priv *priv, const struct 
drm_display_mode *mode
 
 /* Audio support */
 
+static const struct tda998x_audio_route tda998x_audio_route[AUDIO_ROUTE_NUM] = 
{
+   [AUDIO_ROUTE_I2S] = {
+   .ena_aclk = 1,
+   .mux_ap = MUX_AP_SELECT_I2S,
+   .aip_clksel = AIP_CLKSEL_AIP_I2S | AIP_CLKSEL_FS_ACLK,
+   },
+   [AUDIO_ROUTE_SPDIF] = {
+   .ena_aclk = 0,
+   .mux_ap = MUX_AP_SELECT_SPDIF,
+   .aip_clksel = AIP_CLKSEL_AIP_SPDIF | AIP_CLKSEL_FS_FS64SPDIF,
+   },
+};
+
+/* Configure the TDA998x audio data and clock routing. */
+static int tda998x_derive_routing(struct tda998x_priv *priv,
+ struct tda998x_audio_settings *s,
+ unsigned int route)
+{
+   s->route = _audio_route[route];
+   s->ena_ap = priv->audio_port_enable[route];
+   if (s->ena_ap == 0) {
+   dev_err(>hdmi->dev, "no audio configuration found\n");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 /*
  * The audio clock divisor register controls a divider producing Audio_Clk_Out
  * from SERclk by dividing it by 2^n where 0 <= n <= 5.  We don't know what
@@ -960,7 +995,7 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, 
bool on)
 static int tda998x_configure_audio(struct tda998x_priv *priv,
 const struct tda998x_audio_settings *settings)
 {
-   u8 buf[6], aip_clksel, adiv;
+   u8 buf[6], adiv;
u32 n;
 
/* If audio is not configured, there is nothing to do. */
@@ -971,28 +1006,10 @@ static int tda998x_configure_audio(struct tda998x_priv 
*priv,
 
/* Enable audio ports */
reg_write(priv, REG_ENA_AP, settings->ena_ap);
-
-   /* Set audio input source */
-   switch (settings->params.format) {
-   case AFMT_SPDIF:
-   reg_write(priv, REG_ENA_ACLK, 0);
-   reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF);
-   aip_clksel = AIP_CLKSEL_AIP_SPDIF | AIP_CLKSEL_FS_FS64SPDIF;
-   break;
-
-   case AFMT_I2S:
-   reg_write(priv, REG_ENA_ACLK, 1);
-   reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_I2S);
-   aip_clksel = AIP_CLKSEL_AIP_I2S | AIP_CLKSEL_FS_ACLK;
-   break;
-
-   default:
-   dev_err(>hdmi->dev, "Unsupported I2S format\n");
-   return -EINVAL;
-   }
-
+   reg_write(priv, REG_ENA_ACLK, settings->route->ena_aclk);
+   reg_write(priv, REG_MUX_AP, settings->route->mux_ap);
reg_write(priv, REG_I2S_FORMAT, settings->i2s_format);
-   reg_write(priv, REG_AIP_CLKSEL, aip_clksel);
+   reg_write(priv, REG_AIP_CLKSEL, settings->route->aip_clksel);
reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT |
AIP_CNTRL_0_ACR_MAN);   /* auto CTS */
reg_write(priv, REG_CTS_N, settings->cts_n);
@@ -1071,14 +1088,6 @@ static int tda998x_audio_hw_params(struct device *dev, 
void *data,
return -EINVAL;
}
 
-   audio.params.format = spdif ? AFMT_SPDIF : AFMT_I2S;
-
-   audio.ena_ap = priv->audio_port_enable[AUDIO_ROUTE_I2S + spdif];
-   if (audio.ena_ap == 0) {
-   dev_err(dev, "%s: No audio configuration found\n", __func__);
-   return -EINVAL;
-   }
-
if (!spdif &&
(daifmt->bit_clk_inv || daifmt->frame_clk_inv ||
 daifmt->bit_clk_master || daifmt->frame_clk_master)) {
@@ -1089,6 +1098,10 @@ static int tda998x_audio_hw_params(struct device *dev, 
void *data,
return -EINVAL;
}
 
+   ret = tda998x_derive_routing(priv, , AUDIO_ROUTE_I2S + spdif);
+   if (ret < 0)
+   return ret;
+
bclk_ratio = spdif ? 64 : params->sample_width * 2;
ret = tda998x_derive_cts_n(priv, , bclk_ratio);
if (ret < 0)
@@ -1699,9 +1712,12 @@ static int tda998x_set_config(struct tda998x_priv *priv,
(p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);