[PATCH 2/4 v2] drm/bridge: adv7511: Add Audio support.

2016-08-30 Thread Laurent Pinchart
Hi John,

Thank you for the patch.

On Monday 29 Aug 2016 16:41:34 John Stultz wrote:
> This patch adds support to Audio for both adv7511 and adv7533
> bridge chips.
> 
> This patch was originally from [1] by Lars-Peter Clausen 
> and was adapted by Archit Taneja  and
> Srinivas Kandagatla .
> 
> Then I heavily reworked it to use the hdmi-codec driver. So credit
> to them, but blame to me.
> 
> [1]
> https://github.com/analogdevicesinc/linux/blob/xcomm_zynq/drivers/gpu/drm/i
> 2c/adv7511_audio.c
> 
> Cc: David Airlie 
> Cc: Archit Taneja 
> Cc: Laurent Pinchart 
> Cc: Wolfram Sang 
> Cc: Srinivas Kandagatla 
> Cc: "Ville Syrjälä" 
> Cc: Boris Brezillon 
> Cc: Andy Green 
> Cc: Dave Long 
> Cc: Guodong Xu 
> Cc: Zhangfei Gao 
> Cc: Mark Brown 
> Cc: Lars-Peter Clausen 
> Cc: Jose Abreu 
> Cc: dri-devel at lists.freedesktop.org
> Signed-off-by: John Stultz 
> ---
> v2: Integrated feedback from Srinivas
> 
>  drivers/gpu/drm/bridge/adv7511/Kconfig |   1 +
>  drivers/gpu/drm/bridge/adv7511/Makefile|   2 +-
>  drivers/gpu/drm/bridge/adv7511/adv7511.h   |   5 +
>  drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 199 ++
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   |   5 +
>  5 files changed, 211 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig
> b/drivers/gpu/drm/bridge/adv7511/Kconfig index d2b0499..e3975e9 100644
> --- a/drivers/gpu/drm/bridge/adv7511/Kconfig
> +++ b/drivers/gpu/drm/bridge/adv7511/Kconfig
> @@ -3,6 +3,7 @@ config DRM_I2C_ADV7511
>   depends on OF
>   select DRM_KMS_HELPER
>   select REGMAP_I2C
> + select SND_SOC_HDMI_CODEC if SND_SOC

Shouldn't sound support be optional ? I can imagine a board that doesn't wire 
up sound to the ADV7511 but still uses SND_SOC for other purposes.

>   help
> Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.
> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/Makefile
> b/drivers/gpu/drm/bridge/adv7511/Makefile index 9019327..ad7245d 100644
> --- a/drivers/gpu/drm/bridge/adv7511/Makefile
> +++ b/drivers/gpu/drm/bridge/adv7511/Makefile
> @@ -1,3 +1,3 @@
> -adv7511-y := adv7511_drv.o
> +adv7511-y := adv7511_drv.o adv7511_audio.o

Could we avoid compiling adv7511_audio.o if sound support isn't desired to 
avoid bloating the kernel ?

>  adv7511-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o
>  obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index c7002a0..2e4d340 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> @@ -23,6 +23,8 @@ struct adv7511;
> 
>  int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet);
>  int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet);
> +int adv7511_audio_init(struct device *dev);
> +void adv7511_audio_exit(struct device *dev);
> 
>  #define ADV7511_REG_CHIP_REVISION0x00
>  #define ADV7511_REG_N0   0x01
> @@ -317,6 +319,8 @@ struct adv7511 {
>   struct drm_display_mode curr_mode;
> 
>   unsigned int f_tmds;
> + unsigned int f_audio;
> + unsigned int audio_source;
> 
>   unsigned int current_edid_segment;
>   uint8_t edid_buf[256];
> @@ -342,6 +346,7 @@ struct adv7511 {
>   bool use_timing_gen;
> 
>   enum adv7511_type type;
> + struct platform_device *audio_pdev;
>  };
> 
>  #ifdef CONFIG_DRM_I2C_ADV7533
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
> b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c new file mode 100644
> index 000..0e0ea6b
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
> @@ -0,0 +1,199 @@
> +/*
> + * Analog Devices ADV7511 HDMI transmitter driver
> + *
> + * Copyright 2012 Analog Devices Inc.
> + * Copyright (c) 2016, Linaro Limited
> + *
> + * Licensed under the GPL-2.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "adv7511.h"
> +
> +static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs,
> +unsigned int *cts, unsigned int *n)
> +{
> + switch (fs) {
> + case 32000:
> + *n = 4096;
> + break;
> + case 44100:
> + *n = 6272;
> + break;
> + case 48000:
> + *n = 6144;
> + break;
> + }
> +
> + *cts = ((f_tmds * *n) / (128 * fs)) * 1000;
> +}
> +
> +static int adv7511_update_cts_n(struct adv7511 *adv7511)
> +{
> + unsigned int cts = 0;
> + unsigned int n = 0;
> +
> + adv7511_calc_cts_n(adv7511->f_tmds, adv7511->f_audio, , );
> +
> + regmap_write(adv7511->regmap, ADV7511_REG_N0, (n >> 16) & 0xf);
> + regmap_write(adv7511->regmap, ADV7511_REG_N1, (n >> 8) & 0xff);
> + regmap_write(adv7511->regmap, ADV7511_REG_N2, n 

[PATCH 2/4 v2] drm/bridge: adv7511: Add Audio support.

2016-08-29 Thread John Stultz
This patch adds support to Audio for both adv7511 and adv7533
bridge chips.

This patch was originally from [1] by Lars-Peter Clausen 
and was adapted by Archit Taneja  and
Srinivas Kandagatla .

Then I heavily reworked it to use the hdmi-codec driver. So credit
to them, but blame to me.

[1] 
https://github.com/analogdevicesinc/linux/blob/xcomm_zynq/drivers/gpu/drm/i2c/adv7511_audio.c

Cc: David Airlie 
Cc: Archit Taneja 
Cc: Laurent Pinchart 
Cc: Wolfram Sang 
Cc: Srinivas Kandagatla 
Cc: "Ville Syrjälä" 
Cc: Boris Brezillon 
Cc: Andy Green 
Cc: Dave Long 
Cc: Guodong Xu 
Cc: Zhangfei Gao 
Cc: Mark Brown 
Cc: Lars-Peter Clausen 
Cc: Jose Abreu 
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: John Stultz 
---
v2: Integrated feedback from Srinivas

 drivers/gpu/drm/bridge/adv7511/Kconfig |   1 +
 drivers/gpu/drm/bridge/adv7511/Makefile|   2 +-
 drivers/gpu/drm/bridge/adv7511/adv7511.h   |   5 +
 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 199 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   |   5 +
 5 files changed, 211 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/bridge/adv7511/adv7511_audio.c

diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig 
b/drivers/gpu/drm/bridge/adv7511/Kconfig
index d2b0499..e3975e9 100644
--- a/drivers/gpu/drm/bridge/adv7511/Kconfig
+++ b/drivers/gpu/drm/bridge/adv7511/Kconfig
@@ -3,6 +3,7 @@ config DRM_I2C_ADV7511
depends on OF
select DRM_KMS_HELPER
select REGMAP_I2C
+   select SND_SOC_HDMI_CODEC if SND_SOC
help
  Support for the Analog Device ADV7511(W) and ADV7513 HDMI encoders.

diff --git a/drivers/gpu/drm/bridge/adv7511/Makefile 
b/drivers/gpu/drm/bridge/adv7511/Makefile
index 9019327..ad7245d 100644
--- a/drivers/gpu/drm/bridge/adv7511/Makefile
+++ b/drivers/gpu/drm/bridge/adv7511/Makefile
@@ -1,3 +1,3 @@
-adv7511-y := adv7511_drv.o
+adv7511-y := adv7511_drv.o adv7511_audio.o
 adv7511-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o
 obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index c7002a0..2e4d340 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -23,6 +23,8 @@ struct adv7511;

 int adv7511_packet_enable(struct adv7511 *adv7511, unsigned int packet);
 int adv7511_packet_disable(struct adv7511 *adv7511, unsigned int packet);
+int adv7511_audio_init(struct device *dev);
+void adv7511_audio_exit(struct device *dev);

 #define ADV7511_REG_CHIP_REVISION  0x00
 #define ADV7511_REG_N0 0x01
@@ -317,6 +319,8 @@ struct adv7511 {
struct drm_display_mode curr_mode;

unsigned int f_tmds;
+   unsigned int f_audio;
+   unsigned int audio_source;

unsigned int current_edid_segment;
uint8_t edid_buf[256];
@@ -342,6 +346,7 @@ struct adv7511 {
bool use_timing_gen;

enum adv7511_type type;
+   struct platform_device *audio_pdev;
 };

 #ifdef CONFIG_DRM_I2C_ADV7533
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
new file mode 100644
index 000..0e0ea6b
--- /dev/null
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -0,0 +1,199 @@
+/*
+ * Analog Devices ADV7511 HDMI transmitter driver
+ *
+ * Copyright 2012 Analog Devices Inc.
+ * Copyright (c) 2016, Linaro Limited
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "adv7511.h"
+
+static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs,
+  unsigned int *cts, unsigned int *n)
+{
+   switch (fs) {
+   case 32000:
+   *n = 4096;
+   break;
+   case 44100:
+   *n = 6272;
+   break;
+   case 48000:
+   *n = 6144;
+   break;
+   }
+
+   *cts = ((f_tmds * *n) / (128 * fs)) * 1000;
+}
+
+static int adv7511_update_cts_n(struct adv7511 *adv7511)
+{
+   unsigned int cts = 0;
+   unsigned int n = 0;
+
+   adv7511_calc_cts_n(adv7511->f_tmds, adv7511->f_audio, , );
+
+   regmap_write(adv7511->regmap, ADV7511_REG_N0, (n >> 16) & 0xf);
+   regmap_write(adv7511->regmap, ADV7511_REG_N1, (n >> 8) & 0xff);
+   regmap_write(adv7511->regmap, ADV7511_REG_N2, n & 0xff);
+
+   regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL0,
+(cts >> 16) & 0xf);
+   regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL1,
+(cts >> 8) & 0xff);
+   regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL2,
+cts & 0xff);
+
+   return 0;
+}
+
+int adv7511_hdmi_hw_params(struct device *dev, void *data,
+   struct hdmi_codec_daifmt *fmt,
+   struct hdmi_codec_params *hparms)
+{
+   struct