Re: [PATCH RFC v3 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality

2015-08-17 Thread Jyri Sarha

On 08/14/15 13:06, Russell King - ARM Linux wrote:

On Fri, Aug 14, 2015 at 12:30:44PM +0300, Jyri Sarha wrote:

+static int tda998x_write_aif(struct tda998x_priv *priv,
+struct hdmi_audio_infoframe *cea)
+{
+   uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+   int len;
+
+   len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf));
+   if (len  0) {
+   dev_err(priv-hdmi-dev,
+   Failed to pack audio infoframe: %d\n, len);
+   return len;
+   }
+
+   /* Write the audio information packet */
+   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len);
+   return 0;
+}
+


I have such a function already queued up, but I can't push it out at the
moment because of too many conflicts across all my DRM work.  I'm waiting
for after 4.3-rc1 before publishing anything from or accepting anything
else into DRM branches.



Ok, is the code available some where? Could take a look so I can align 
my code to that.



  static void
  tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
  {
@@ -670,19 +691,24 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, 
bool on)
}
  }

-static void
+static int
  tda998x_configure_audio(struct tda998x_priv *priv,
-   struct drm_display_mode *mode, struct tda998x_encoder_params *p)
+   int mode_clock,
+   int ena_ap,
+   int dai_format,
+   int sample_width,
+   int sample_rate,
+   const u8 *status)


I don't think this is an improvement.



Still it makes the function more generic and enables its usage in 
HDMI-codec API implementation. I'll try to make it look tidier.



+static int tda998x_audio_get_eld(struct device *dev, uint8_t *buf, size_t len)
+{
+   struct tda998x_priv *priv = dev_get_drvdata(dev);
+   struct drm_mode_config *config = priv-encoder-dev-mode_config;
+   struct drm_connector *connector;
+   int ret = -ENODEV;
+
+   mutex_lock(config.mutex);
+   list_for_each_entry(connector, config-connector_list, head) {
+   if (priv-encoder == connector-encoder) {
+   memcpy(buf, connector-eld,
+  min(sizeof(connector-eld), len));
+   ret = 0;
+   }
+   }
+   mutex_unlock(config.mutex);


Obviously untested.  Should be config-mutex.



Sorry. Should never do these last minute changes. I must have been 
compiling and testing different code version. I first had this function 
using config-connection_mutex, but then - after reading the eld related 
code - found that mode_config mutex should be used instead.



But in any case, when I kill the DRM slave encoder code in here, this
becomes unnecessary.



Ok, The information from ELD needs be passed to audio side constraints 
somehow. I'd love to see the code you have in queue.


Best regards,
Jyri

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RFC v3 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality

2015-08-14 Thread Jyri Sarha
Register ASoC HDMI codec for audio functionality. This is an initial
ASoC audio implementation for tda998x driver and it does not use all
the features provided by hdmi-codec.

HDMI audio info-frame and audio stream header is generated by the ASoC
HDMI codec. The codec also applies constraints for available
sample-rates.

Implementation of audio_startup for hdmi_codec_ops would enable
tda998x driver to abort ongoing playback if the HDMI cable is
unplugged or re-plugged to a device without audio capability.

Signed-off-by: Jyri Sarha jsa...@ti.com
---
 drivers/gpu/drm/i2c/Kconfig   |   1 +
 drivers/gpu/drm/i2c/tda998x_drv.c | 241 +-
 2 files changed, 214 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
index 22c7ed6..088f278 100644
--- a/drivers/gpu/drm/i2c/Kconfig
+++ b/drivers/gpu/drm/i2c/Kconfig
@@ -28,6 +28,7 @@ config DRM_I2C_SIL164
 config DRM_I2C_NXP_TDA998X
tristate NXP Semiconductors TDA998X HDMI encoder
default m if DRM_TILCDC
+   select SND_SOC_HDMI_CODEC if SND_SOC
help
  Support for NXP Semiconductors TDA998X HDMI encoders.
 
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c 
b/drivers/gpu/drm/i2c/tda998x_drv.c
index 4dc2dc0..8444e18 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -20,6 +20,7 @@
 #include linux/module.h
 #include linux/irq.h
 #include sound/asoundef.h
+#include sound/hdmi-codec.h
 
 #include drm/drmP.h
 #include drm/drm_crtc_helper.h
@@ -49,6 +50,8 @@ struct tda998x_priv {
u8 vip_cntrl_2;
struct tda998x_encoder_params params;
 
+   struct platform_device *audio_pdev;
+
wait_queue_head_t wq_edid;
volatile int wq_edid_wait;
struct drm_encoder *encoder;
@@ -435,7 +438,7 @@ out:
 }
 
 static void
-reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt)
+reg_write_range(struct tda998x_priv *priv, uint16_t reg, const u8 *p, int cnt)
 {
struct i2c_client *client = priv-hdmi;
uint8_t buf[cnt+1];
@@ -619,7 +622,7 @@ tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, 
uint16_t addr,
 }
 
 static void
-tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p)
+tda998x_write_raw_aif(struct tda998x_priv *priv, u8 *audio_frame)
 {
u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1];
 
@@ -627,10 +630,10 @@ tda998x_write_aif(struct tda998x_priv *priv, struct 
tda998x_encoder_params *p)
buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO;
buf[HB(1)] = 0x01;
buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE;
-   buf[PB(1)] = p-audio_frame[1]  0x07; /* CC */
-   buf[PB(2)] = p-audio_frame[2]  0x1c; /* SF */
-   buf[PB(4)] = p-audio_frame[4];
-   buf[PB(5)] = p-audio_frame[5]  0xf8; /* DM_INH + LSV */
+   buf[PB(1)] = audio_frame[1]  0x07; /* CC */
+   buf[PB(2)] = audio_frame[2]  0x1c; /* SF */
+   buf[PB(4)] = audio_frame[4];
+   buf[PB(5)] = audio_frame[5]  0xf8; /* DM_INH + LSV */
 
buf[PB(0)] = tda998x_cksum(buf, sizeof(buf));
 
@@ -638,6 +641,24 @@ tda998x_write_aif(struct tda998x_priv *priv, struct 
tda998x_encoder_params *p)
 sizeof(buf));
 }
 
+static int tda998x_write_aif(struct tda998x_priv *priv,
+struct hdmi_audio_infoframe *cea)
+{
+   uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+   int len;
+
+   len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf));
+   if (len  0) {
+   dev_err(priv-hdmi-dev,
+   Failed to pack audio infoframe: %d\n, len);
+   return len;
+   }
+
+   /* Write the audio information packet */
+   tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len);
+   return 0;
+}
+
 static void
 tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
 {
@@ -670,19 +691,24 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, 
bool on)
}
 }
 
-static void
+static int
 tda998x_configure_audio(struct tda998x_priv *priv,
-   struct drm_display_mode *mode, struct tda998x_encoder_params *p)
+   int mode_clock,
+   int ena_ap,
+   int dai_format,
+   int sample_width,
+   int sample_rate,
+   const u8 *status)
 {
uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv;
uint32_t n;
 
/* Enable audio ports */
-   reg_write(priv, REG_ENA_AP, p-audio_cfg);
-   reg_write(priv, REG_ENA_ACLK, p-audio_clk_cfg);
+   reg_write(priv, REG_ENA_AP, ena_ap);
+   reg_write(priv, REG_ENA_ACLK, dai_format == AFMT_SPDIF ? 0 : 1);
 
/* Set audio input source */
-   switch (p-audio_format) {
+   switch (dai_format) {
case AFMT_SPDIF:
reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF);
clksel_aip = 

Re: [PATCH RFC v3 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality

2015-08-14 Thread Russell King - ARM Linux
On Fri, Aug 14, 2015 at 12:30:44PM +0300, Jyri Sarha wrote:
 +static int tda998x_write_aif(struct tda998x_priv *priv,
 +  struct hdmi_audio_infoframe *cea)
 +{
 + uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)];
 + int len;
 +
 + len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf));
 + if (len  0) {
 + dev_err(priv-hdmi-dev,
 + Failed to pack audio infoframe: %d\n, len);
 + return len;
 + }
 +
 + /* Write the audio information packet */
 + tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len);
 + return 0;
 +}
 +

I have such a function already queued up, but I can't push it out at the
moment because of too many conflicts across all my DRM work.  I'm waiting
for after 4.3-rc1 before publishing anything from or accepting anything
else into DRM branches.

  static void
  tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
  {
 @@ -670,19 +691,24 @@ static void tda998x_audio_mute(struct tda998x_priv 
 *priv, bool on)
   }
  }
  
 -static void
 +static int
  tda998x_configure_audio(struct tda998x_priv *priv,
 - struct drm_display_mode *mode, struct tda998x_encoder_params *p)
 + int mode_clock,
 + int ena_ap,
 + int dai_format,
 + int sample_width,
 + int sample_rate,
 + const u8 *status)

I don't think this is an improvement.

 +static int tda998x_audio_get_eld(struct device *dev, uint8_t *buf, size_t 
 len)
 +{
 + struct tda998x_priv *priv = dev_get_drvdata(dev);
 + struct drm_mode_config *config = priv-encoder-dev-mode_config;
 + struct drm_connector *connector;
 + int ret = -ENODEV;
 +
 + mutex_lock(config.mutex);
 + list_for_each_entry(connector, config-connector_list, head) {
 + if (priv-encoder == connector-encoder) {
 + memcpy(buf, connector-eld, 
 +min(sizeof(connector-eld), len));
 + ret = 0;
 + }
 + }
 + mutex_unlock(config.mutex);

Obviously untested.  Should be config-mutex.

But in any case, when I kill the DRM slave encoder code in here, this
becomes unnecessary.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html