[PATCH v11 3/4] drm/bridge: anx7625: add MIPI DPI input feature

2021-10-17 Thread Xin Ji
The basic anx7625 driver only support MIPI DSI rx signal input.
This patch add MIPI DPI rx input configuration support, after apply
this patch, the driver can support DSI rx or DPI rx by adding
'bus-type' in DT.

Reviewed-by: Robert Foss 
Signed-off-by: Xin Ji 
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 246 --
 drivers/gpu/drm/bridge/analogix/anx7625.h |  18 +-
 2 files changed, 204 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 469037f2fd3d..92038c4661ff 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 #include "anx7625.h"
@@ -152,18 +153,18 @@ static int anx7625_write_and(struct anx7625_data *ctx,
return anx7625_reg_write(ctx, client, offset, (val & (mask)));
 }
 
-static int anx7625_write_and_or(struct anx7625_data *ctx,
-   struct i2c_client *client,
-   u8 offset, u8 and_mask, u8 or_mask)
+static int anx7625_config_bit_matrix(struct anx7625_data *ctx)
 {
-   int val;
+   int i, ret;
 
-   val = anx7625_reg_read(ctx, client, offset);
-   if (val < 0)
-   return val;
+   ret = anx7625_write_or(ctx, ctx->i2c.tx_p2_client,
+  AUDIO_CONTROL_REGISTER, 0x80);
+   for (i = 0; i < 13; i++)
+   ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
+VIDEO_BIT_MATRIX_12 + i,
+0x18 + i);
 
-   return anx7625_reg_write(ctx, client,
-offset, (val & and_mask) | (or_mask));
+   return ret;
 }
 
 static int anx7625_read_ctrl_status_p0(struct anx7625_data *ctx)
@@ -221,38 +222,6 @@ static int anx7625_video_mute_control(struct anx7625_data 
*ctx,
return ret;
 }
 
-static int anx7625_config_audio_input(struct anx7625_data *ctx)
-{
-   struct device *dev = >client->dev;
-   int ret;
-
-   /* Channel num */
-   ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_6, I2S_CH_2 << 5);
-
-   /* FS */
-   ret |= anx7625_write_and_or(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_4,
-   0xf0, AUDIO_FS_48K);
-   /* Word length */
-   ret |= anx7625_write_and_or(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_5,
-   0xf0, AUDIO_W_LEN_24_24MAX);
-   /* I2S */
-   ret |= anx7625_write_or(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_6, I2S_SLAVE_MODE);
-   ret |= anx7625_write_and(ctx, ctx->i2c.tx_p2_client,
-AUDIO_CONTROL_REGISTER, ~TDM_TIMING_MODE);
-   /* Audio change flag */
-   ret |= anx7625_write_or(ctx, ctx->i2c.rx_p0_client,
-   AP_AV_STATUS, AP_AUDIO_CHG);
-
-   if (ret < 0)
-   DRM_DEV_ERROR(dev, "fail to config audio.\n");
-
-   return ret;
-}
-
 /* Reduction of fraction a/b */
 static void anx7625_reduction_of_a_fraction(unsigned long *a, unsigned long *b)
 {
@@ -431,7 +400,7 @@ static int anx7625_dsi_video_timing_config(struct 
anx7625_data *ctx)
ret |= anx7625_write_and(ctx, ctx->i2c.rx_p1_client,
MIPI_LANE_CTRL_0, 0xfc);
ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client,
-   MIPI_LANE_CTRL_0, 3);
+   MIPI_LANE_CTRL_0, ctx->pdata.mipi_lanes - 1);
 
/* Htotal */
htotal = ctx->dt.hactive.min + ctx->dt.hfront_porch.min +
@@ -615,6 +584,76 @@ static int anx7625_dsi_config(struct anx7625_data *ctx)
return ret;
 }
 
+static int anx7625_api_dpi_config(struct anx7625_data *ctx)
+{
+   struct device *dev = >client->dev;
+   u16 freq = ctx->dt.pixelclock.min / 1000;
+   int ret;
+
+   /* configure pixel clock */
+   ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
+   PIXEL_CLOCK_L, freq & 0xFF);
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
+PIXEL_CLOCK_H, (freq >> 8));
+
+   /* set DPI mode */
+   /* set to DPI PLL module sel */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
+MIPI_DIGITAL_PLL_9, 0x20);
+   /* power down MIPI */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
+MIPI_LANE_CTRL_10, 0x08);
+   /* enable DPI mode */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
+MIPI_DIGITAL_PLL_18, 0x1C);
+   /* set first edge */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
+ 

[PATCH v11 3/4] drm/bridge: anx7625: add MIPI DPI input feature

2021-08-05 Thread Xin Ji
The basic anx7625 driver only support MIPI DSI rx signal input.
This patch add MIPI DPI rx input configuration support, after apply
this patch, the driver can support DSI rx or DPI rx by adding
'bus-type' in DT.

Reviewed-by: Robert Foss 
Signed-off-by: Xin Ji 
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 246 --
 drivers/gpu/drm/bridge/analogix/anx7625.h |  18 +-
 2 files changed, 204 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 3fc6b7ce7fc7..a5a20cc0f3e0 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 #include "anx7625.h"
@@ -152,18 +153,18 @@ static int anx7625_write_and(struct anx7625_data *ctx,
return anx7625_reg_write(ctx, client, offset, (val & (mask)));
 }
 
-static int anx7625_write_and_or(struct anx7625_data *ctx,
-   struct i2c_client *client,
-   u8 offset, u8 and_mask, u8 or_mask)
+static int anx7625_config_bit_matrix(struct anx7625_data *ctx)
 {
-   int val;
+   int i, ret;
 
-   val = anx7625_reg_read(ctx, client, offset);
-   if (val < 0)
-   return val;
+   ret = anx7625_write_or(ctx, ctx->i2c.tx_p2_client,
+  AUDIO_CONTROL_REGISTER, 0x80);
+   for (i = 0; i < 13; i++)
+   ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
+VIDEO_BIT_MATRIX_12 + i,
+0x18 + i);
 
-   return anx7625_reg_write(ctx, client,
-offset, (val & and_mask) | (or_mask));
+   return ret;
 }
 
 static int anx7625_read_ctrl_status_p0(struct anx7625_data *ctx)
@@ -221,38 +222,6 @@ static int anx7625_video_mute_control(struct anx7625_data 
*ctx,
return ret;
 }
 
-static int anx7625_config_audio_input(struct anx7625_data *ctx)
-{
-   struct device *dev = >client->dev;
-   int ret;
-
-   /* Channel num */
-   ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_6, I2S_CH_2 << 5);
-
-   /* FS */
-   ret |= anx7625_write_and_or(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_4,
-   0xf0, AUDIO_FS_48K);
-   /* Word length */
-   ret |= anx7625_write_and_or(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_5,
-   0xf0, AUDIO_W_LEN_24_24MAX);
-   /* I2S */
-   ret |= anx7625_write_or(ctx, ctx->i2c.tx_p2_client,
-   AUDIO_CHANNEL_STATUS_6, I2S_SLAVE_MODE);
-   ret |= anx7625_write_and(ctx, ctx->i2c.tx_p2_client,
-AUDIO_CONTROL_REGISTER, ~TDM_TIMING_MODE);
-   /* Audio change flag */
-   ret |= anx7625_write_or(ctx, ctx->i2c.rx_p0_client,
-   AP_AV_STATUS, AP_AUDIO_CHG);
-
-   if (ret < 0)
-   DRM_DEV_ERROR(dev, "fail to config audio.\n");
-
-   return ret;
-}
-
 /* Reduction of fraction a/b */
 static void anx7625_reduction_of_a_fraction(unsigned long *a, unsigned long *b)
 {
@@ -412,7 +381,7 @@ static int anx7625_dsi_video_timing_config(struct 
anx7625_data *ctx)
ret |= anx7625_write_and(ctx, ctx->i2c.rx_p1_client,
MIPI_LANE_CTRL_0, 0xfc);
ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client,
-   MIPI_LANE_CTRL_0, 3);
+   MIPI_LANE_CTRL_0, ctx->pdata.mipi_lanes - 1);
 
/* Htotal */
htotal = ctx->dt.hactive.min + ctx->dt.hfront_porch.min +
@@ -597,6 +566,76 @@ static int anx7625_dsi_config(struct anx7625_data *ctx)
return ret;
 }
 
+static int anx7625_api_dpi_config(struct anx7625_data *ctx)
+{
+   struct device *dev = >client->dev;
+   u16 freq = ctx->dt.pixelclock.min / 1000;
+   int ret;
+
+   /* configure pixel clock */
+   ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
+   PIXEL_CLOCK_L, freq & 0xFF);
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
+PIXEL_CLOCK_H, (freq >> 8));
+
+   /* set DPI mode */
+   /* set to DPI PLL module sel */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
+MIPI_DIGITAL_PLL_9, 0x20);
+   /* power down MIPI */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
+MIPI_LANE_CTRL_10, 0x08);
+   /* enable DPI mode */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
+MIPI_DIGITAL_PLL_18, 0x1C);
+   /* set first edge */
+   ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client,
+