diff mbox

[05/11] media: adv7180: init chip with AD recommended register settings

Message ID 1467846004-12731-6-git-send-email-steve_longerbeam@mentor.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Longerbeam July 6, 2016, 10:59 p.m. UTC
Define and load register tables that conform to Analog Device's
recommended register settings. It loads the default single-ended
CVBS on Ain1 configuration for both ADV7180 and ADV7182 chips.

New register addresses have been defined for the tables. Those new
defines are also used in existing locations where hard-coded addresses
were used.

Note this patch also enables NEWAVMODE, which is also recommended by
Analog Devices. This will likely break any current backends using this
subdev that are expecting different or manually configured AV codes.

Note also that bt.656-4 support has been removed in this patch, but it
will be brought back in a subsequent patch.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 drivers/media/i2c/adv7180.c | 168 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 130 insertions(+), 38 deletions(-)

Comments

Tim Harvey July 7, 2016, 3:23 p.m. UTC | #1
On Wed, Jul 6, 2016 at 3:59 PM, Steve Longerbeam <slongerbeam@gmail.com> wrote:
> Define and load register tables that conform to Analog Device's
> recommended register settings. It loads the default single-ended
> CVBS on Ain1 configuration for both ADV7180 and ADV7182 chips.
>
> New register addresses have been defined for the tables. Those new
> defines are also used in existing locations where hard-coded addresses
> were used.
>
> Note this patch also enables NEWAVMODE, which is also recommended by
> Analog Devices. This will likely break any current backends using this
> subdev that are expecting different or manually configured AV codes.
>
> Note also that bt.656-4 support has been removed in this patch, but it
> will be brought back in a subsequent patch.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
> ---
>  drivers/media/i2c/adv7180.c | 168 ++++++++++++++++++++++++++++++++++----------
>  1 file changed, 130 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
> index 42816d4..92e2f37 100644
> --- a/drivers/media/i2c/adv7180.c
> +++ b/drivers/media/i2c/adv7180.c
> @@ -56,10 +56,11 @@
>
>  #define ADV7182_REG_INPUT_VIDSEL                       0x0002
>
> +#define ADV7180_REG_OUTPUT_CONTROL                     0x0003
>  #define ADV7180_REG_EXTENDED_OUTPUT_CONTROL            0x0004
>  #define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS                0xC5
>
> -#define ADV7180_REG_AUTODETECT_ENABLE                  0x07
> +#define ADV7180_REG_AUTODETECT_ENABLE                  0x0007
>  #define ADV7180_AUTODETECT_DEFAULT                     0x7f
>  /* Contrast */
>  #define ADV7180_REG_CON                0x0008  /*Unsigned */
> @@ -100,6 +101,20 @@
>  #define ADV7180_REG_IDENT 0x0011
>  #define ADV7180_ID_7180 0x18
>
> +#define ADV7180_REG_STATUS3            0x0013
> +#define ADV7180_REG_ANALOG_CLAMP_CTL   0x0014
> +#define ADV7180_REG_SHAP_FILTER_CTL_1  0x0017
> +#define ADV7180_REG_CTRL_2             0x001d
> +#define ADV7180_REG_VSYNC_FIELD_CTL_1  0x0031
> +#define ADV7180_REG_MANUAL_WIN_CTL_1   0x003d
> +#define ADV7180_REG_MANUAL_WIN_CTL_2   0x003e
> +#define ADV7180_REG_MANUAL_WIN_CTL_3   0x003f
> +#define ADV7180_REG_LOCK_CNT           0x0051
> +#define ADV7180_REG_CVBS_TRIM          0x0052
> +#define ADV7180_REG_CLAMP_ADJ          0x005a
> +#define ADV7180_REG_RES_CIR            0x005f
> +#define ADV7180_REG_DIFF_MODE          0x0060
> +
>  #define ADV7180_REG_ICONF1             0x2040
>  #define ADV7180_ICONF1_ACTIVE_LOW      0x01
>  #define ADV7180_ICONF1_PSYNC_ONLY      0x10
> @@ -129,9 +144,15 @@
>  #define ADV7180_REG_VPP_SLAVE_ADDR     0xFD
>  #define ADV7180_REG_CSI_SLAVE_ADDR     0xFE
>
> -#define ADV7180_REG_FLCONTROL 0x40e0
> +#define ADV7180_REG_ACE_CTRL1          0x4080
> +#define ADV7180_REG_ACE_CTRL5          0x4084
> +#define ADV7180_REG_FLCONTROL          0x40e0
>  #define ADV7180_FLCONTROL_FL_ENABLE 0x1
>
> +#define ADV7180_REG_RST_CLAMP  0x809c
> +#define ADV7180_REG_AGC_ADJ1   0x80b6
> +#define ADV7180_REG_AGC_ADJ2   0x80c0
> +
>  #define ADV7180_CSI_REG_PWRDN  0x00
>  #define ADV7180_CSI_PWRDN      0x80
>
> @@ -209,6 +230,11 @@ struct adv7180_state {
>                                             struct adv7180_state,       \
>                                             ctrl_hdl)->sd)
>
> +struct adv7180_reg_tbl_t {
> +       unsigned int reg;
> +       unsigned int val;
> +};
> +
>  static int adv7180_select_page(struct adv7180_state *state, unsigned int page)
>  {
>         if (state->register_page != page) {
> @@ -235,6 +261,20 @@ static int adv7180_read(struct adv7180_state *state, unsigned int reg)
>         return i2c_smbus_read_byte_data(state->client, reg & 0xff);
>  }
>
> +static int adv7180_load_reg_tbl(struct adv7180_state *state,
> +                               const struct adv7180_reg_tbl_t *tbl, int n)
> +{
> +       int ret, i;
> +
> +       for (i = 0; i < n; i++) {
> +               ret = adv7180_write(state, tbl[i].reg, tbl[i].val);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +
>  static int adv7180_csi_write(struct adv7180_state *state, unsigned int reg,
>         unsigned int value)
>  {
> @@ -828,19 +868,36 @@ static irqreturn_t adv7180_irq(int irq, void *devid)
>         return IRQ_HANDLED;
>  }
>
> +/*
> + * This register table conforms to Analog Device's Register Settings
> + * Recommendation for the ADV7180. It configures single-ended CVBS
> + * input on Ain1, and enables NEWAVMODE.
> + */
> +static const struct adv7180_reg_tbl_t adv7180_single_ended_cvbs[] = {
> +       /* Set analog mux for CVBS on Ain1 */
> +       { ADV7180_REG_INPUT_CONTROL, 0x00 },
> +       /* ADI Required Write: Reset Clamp Circuitry */
> +       { ADV7180_REG_ANALOG_CLAMP_CTL, 0x30 },
> +       /* Enable SFL Output */
> +       { ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x57 },
> +       /* Select SH1 Chroma Shaping Filter */
> +       { ADV7180_REG_SHAP_FILTER_CTL_1, 0x41 },
> +       /* Enable NEWAVMODE */
> +       { ADV7180_REG_VSYNC_FIELD_CTL_1, 0x02 },
> +       /* ADI Required Write: optimize windowing function Step 1,2,3 */
> +       { ADV7180_REG_MANUAL_WIN_CTL_1, 0xA2 },
> +       { ADV7180_REG_MANUAL_WIN_CTL_2, 0x6A },
> +       { ADV7180_REG_MANUAL_WIN_CTL_3, 0xA0 },
> +       /* ADI Required Write: Enable ADC step 1,2,3 */
> +       { 0x8055, 0x81 }, /* undocumented register 0x55 */
> +       /* Recommended AFE I BIAS Setting for CVBS mode */
> +       { ADV7180_REG_CVBS_TRIM, 0x0D },
> +};
> +
>  static int adv7180_init(struct adv7180_state *state)
>  {
> -       int ret;
> -
> -       /* ITU-R BT.656-4 compatible */
> -       ret = adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
> -                       ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
> -       if (ret < 0)
> -               return ret;
> -
> -       /* Manually set V bit end position in NTSC mode */
> -       return adv7180_write(state, ADV7180_REG_NTSC_V_BIT_END,
> -                                       ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
> +       return adv7180_load_reg_tbl(state, adv7180_single_ended_cvbs,
> +                                   ARRAY_SIZE(adv7180_single_ended_cvbs));
>  }
>
>  static int adv7180_set_std(struct adv7180_state *state, unsigned int std)
> @@ -862,8 +919,48 @@ static int adv7180_select_input(struct adv7180_state *state, unsigned int input)
>         return adv7180_write(state, ADV7180_REG_INPUT_CONTROL, ret);
>  }
>
> +/*
> + * This register table conforms to Analog Device's Register Settings
> + * Recommendation revision C for the ADV7182. It configures single-ended
> + * CVBS inputs on Ain1, and enables NEWAVMODE.
> + */
> +static const struct adv7180_reg_tbl_t adv7182_single_ended_cvbs[] = {
> +       /* Exit Power Down Mode */
> +       { ADV7180_REG_PWR_MAN, 0x00 },
> +       /* Enable ADV7182 for 28.63636 MHz Crystal Clock Input */
> +       { ADV7180_REG_STATUS3, 0x00 },
> +       /* Set optimized IBIAS for single-ended CVBS input */
> +       { ADV7180_REG_CVBS_TRIM, 0xCD },
> +       /* Switch to single-ended CVBS on AIN1 */
> +       { ADV7180_REG_INPUT_CONTROL, 0x00 },
> +       /* ADI Required Write: Reset Current Clamp Circuitry steps 1,2,3,4 */
> +       { ADV7180_REG_RST_CLAMP, 0x00 },
> +       { ADV7180_REG_RST_CLAMP, 0xFF },
> +       /* Select SH1 Chroma Shaping Filter */
> +       { ADV7180_REG_SHAP_FILTER_CTL_1, 0x41 },
> +       /* Enable Pixel & Sync output drivers */
> +       { ADV7180_REG_OUTPUT_CONTROL, 0x0C },
> +       /* Power-up INTRQ, HS and VS/FIELD/SFL pad */
> +       { ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x07 },
> +       /* Enable LLC Output Driver */
> +       { ADV7180_REG_CTRL_2, 0x40 },
> +       /* Optimize ACE Performance */
> +       { ADV7180_REG_ACE_CTRL5, 0x00 },
> +       /* Enable ACE Feature */
> +       { ADV7180_REG_ACE_CTRL1, 0x80 },
> +       /* Enable NEWAVMODE */
> +       { ADV7180_REG_VSYNC_FIELD_CTL_1, 0x02 },
> +};
> +
>  static int adv7182_init(struct adv7180_state *state)
>  {
> +       int ret;
> +
> +       ret = adv7180_load_reg_tbl(state, adv7182_single_ended_cvbs,
> +                                  ARRAY_SIZE(adv7182_single_ended_cvbs));
> +       if (ret)
> +               return ret;
> +
>         if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
>                 adv7180_write(state, ADV7180_REG_CSI_SLAVE_ADDR,
>                         ADV7180_DEFAULT_CSI_I2C_ADDR << 1);
> @@ -881,20 +978,15 @@ static int adv7182_init(struct adv7180_state *state)
>
>         /* ADI required writes */
>         if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
> -               adv7180_write(state, 0x0003, 0x4e);
> -               adv7180_write(state, 0x0004, 0x57);
> -               adv7180_write(state, 0x001d, 0xc0);
> +               adv7180_write(state, ADV7180_REG_OUTPUT_CONTROL, 0x4e);
> +               adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x57);
> +               adv7180_write(state, ADV7180_REG_CTRL_2, 0xc0);
>         } else {
>                 if (state->chip_info->flags & ADV7180_FLAG_V2)
> -                       adv7180_write(state, 0x0004, 0x17);
> -               else
> -                       adv7180_write(state, 0x0004, 0x07);
> -               adv7180_write(state, 0x0003, 0x0c);
> -               adv7180_write(state, 0x001d, 0x40);
> +                       adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
> +                                     0x17);
>         }
>
> -       adv7180_write(state, 0x0013, 0x00);
> -
>         return 0;
>  }
>
> @@ -967,8 +1059,8 @@ static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
>                 return ret;
>
>         /* Reset clamp circuitry - ADI recommended writes */
> -       adv7180_write(state, 0x809c, 0x00);
> -       adv7180_write(state, 0x809c, 0xff);
> +       adv7180_write(state, ADV7180_REG_RST_CLAMP, 0x00);
> +       adv7180_write(state, ADV7180_REG_RST_CLAMP, 0xff);
>
>         input_type = adv7182_get_input_type(input);
>
> @@ -976,10 +1068,10 @@ static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
>         case ADV7182_INPUT_TYPE_CVBS:
>         case ADV7182_INPUT_TYPE_DIFF_CVBS:
>                 /* ADI recommends to use the SH1 filter */
> -               adv7180_write(state, 0x0017, 0x41);
> +               adv7180_write(state, ADV7180_REG_SHAP_FILTER_CTL_1, 0x41);
>                 break;
>         default:
> -               adv7180_write(state, 0x0017, 0x01);
> +               adv7180_write(state, ADV7180_REG_SHAP_FILTER_CTL_1, 0x01);
>                 break;
>         }
>
> @@ -989,21 +1081,21 @@ static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
>                 lbias = adv7182_lbias_settings[input_type];
>
>         for (i = 0; i < ARRAY_SIZE(adv7182_lbias_settings[0]); i++)
> -               adv7180_write(state, 0x0052 + i, lbias[i]);
> +               adv7180_write(state, ADV7180_REG_CVBS_TRIM + i, lbias[i]);
>
>         if (input_type == ADV7182_INPUT_TYPE_DIFF_CVBS) {
>                 /* ADI required writes to make differential CVBS work */
> -               adv7180_write(state, 0x005f, 0xa8);
> -               adv7180_write(state, 0x005a, 0x90);
> -               adv7180_write(state, 0x0060, 0xb0);
> -               adv7180_write(state, 0x80b6, 0x08);
> -               adv7180_write(state, 0x80c0, 0xa0);
> +               adv7180_write(state, ADV7180_REG_RES_CIR, 0xa8);
> +               adv7180_write(state, ADV7180_REG_CLAMP_ADJ, 0x90);
> +               adv7180_write(state, ADV7180_REG_DIFF_MODE, 0xb0);
> +               adv7180_write(state, ADV7180_REG_AGC_ADJ1, 0x08);
> +               adv7180_write(state, ADV7180_REG_AGC_ADJ2, 0xa0);
>         } else {
> -               adv7180_write(state, 0x005f, 0xf0);
> -               adv7180_write(state, 0x005a, 0xd0);
> -               adv7180_write(state, 0x0060, 0x10);
> -               adv7180_write(state, 0x80b6, 0x9c);
> -               adv7180_write(state, 0x80c0, 0x00);
> +               adv7180_write(state, ADV7180_REG_RES_CIR, 0xf0);
> +               adv7180_write(state, ADV7180_REG_CLAMP_ADJ, 0xd0);
> +               adv7180_write(state, ADV7180_REG_DIFF_MODE, 0x10);
> +               adv7180_write(state, ADV7180_REG_AGC_ADJ1, 0x9c);
> +               adv7180_write(state, ADV7180_REG_AGC_ADJ2, 0x00);
>         }
>
>         return 0;
> --

Steve,

Tested on an IMX6 Gateworks Ventana with IMX6 capture drivers [1].

Tested-by: Tim Harvey <tharvey@gateworks.com>
Acked-by: Tim Harvey <tharvey@gateworks.com>

Added to Cc:
Cc: Lars-Peter Clausen <lars@metafoo.de>

Also adding Cc's to the people who are using the adv7180 on other
boards (renesas r8a779* boards) so we can get some feedback and/or
Tested-by from them:
Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Cc: Simon Horman <horms+renesas@verge.net.au>

I'm wondering if those boards need the bt656-4 which was previously
being enabled per your comment and is now moved to a dt-prop per a
subsequent patch.

Regards,

Tim

[1] - http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/102914
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lars-Peter Clausen July 7, 2016, 3:29 p.m. UTC | #2
On 07/07/2016 12:59 AM, Steve Longerbeam wrote:
> Define and load register tables that conform to Analog Device's
> recommended register settings. It loads the default single-ended
> CVBS on Ain1 configuration for both ADV7180 and ADV7182 chips.

The driver should already setup the recommended configuration based on the
current mode. This patch seems to add a set of register writes that only
apply for a specific mode.

[...]
> Note this patch also enables NEWAVMODE, which is also recommended by
> Analog Devices. This will likely break any current backends using this
> subdev that are expecting different or manually configured AV codes.
> 
> Note also that bt.656-4 support has been removed in this patch, but it
> will be brought back in a subsequent patch.


I'm not sure if we can or should break backwards compatibility in this way.

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

Patch

diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 42816d4..92e2f37 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -56,10 +56,11 @@ 
 
 #define ADV7182_REG_INPUT_VIDSEL			0x0002
 
+#define ADV7180_REG_OUTPUT_CONTROL			0x0003
 #define ADV7180_REG_EXTENDED_OUTPUT_CONTROL		0x0004
 #define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS		0xC5
 
-#define ADV7180_REG_AUTODETECT_ENABLE			0x07
+#define ADV7180_REG_AUTODETECT_ENABLE			0x0007
 #define ADV7180_AUTODETECT_DEFAULT			0x7f
 /* Contrast */
 #define ADV7180_REG_CON		0x0008	/*Unsigned */
@@ -100,6 +101,20 @@ 
 #define ADV7180_REG_IDENT 0x0011
 #define ADV7180_ID_7180 0x18
 
+#define ADV7180_REG_STATUS3		0x0013
+#define ADV7180_REG_ANALOG_CLAMP_CTL	0x0014
+#define ADV7180_REG_SHAP_FILTER_CTL_1	0x0017
+#define ADV7180_REG_CTRL_2		0x001d
+#define ADV7180_REG_VSYNC_FIELD_CTL_1	0x0031
+#define ADV7180_REG_MANUAL_WIN_CTL_1	0x003d
+#define ADV7180_REG_MANUAL_WIN_CTL_2	0x003e
+#define ADV7180_REG_MANUAL_WIN_CTL_3	0x003f
+#define ADV7180_REG_LOCK_CNT		0x0051
+#define ADV7180_REG_CVBS_TRIM		0x0052
+#define ADV7180_REG_CLAMP_ADJ		0x005a
+#define ADV7180_REG_RES_CIR		0x005f
+#define ADV7180_REG_DIFF_MODE		0x0060
+
 #define ADV7180_REG_ICONF1		0x2040
 #define ADV7180_ICONF1_ACTIVE_LOW	0x01
 #define ADV7180_ICONF1_PSYNC_ONLY	0x10
@@ -129,9 +144,15 @@ 
 #define ADV7180_REG_VPP_SLAVE_ADDR	0xFD
 #define ADV7180_REG_CSI_SLAVE_ADDR	0xFE
 
-#define ADV7180_REG_FLCONTROL 0x40e0
+#define ADV7180_REG_ACE_CTRL1		0x4080
+#define ADV7180_REG_ACE_CTRL5		0x4084
+#define ADV7180_REG_FLCONTROL		0x40e0
 #define ADV7180_FLCONTROL_FL_ENABLE 0x1
 
+#define ADV7180_REG_RST_CLAMP	0x809c
+#define ADV7180_REG_AGC_ADJ1	0x80b6
+#define ADV7180_REG_AGC_ADJ2	0x80c0
+
 #define ADV7180_CSI_REG_PWRDN	0x00
 #define ADV7180_CSI_PWRDN	0x80
 
@@ -209,6 +230,11 @@  struct adv7180_state {
 					    struct adv7180_state,	\
 					    ctrl_hdl)->sd)
 
+struct adv7180_reg_tbl_t {
+	unsigned int reg;
+	unsigned int val;
+};
+
 static int adv7180_select_page(struct adv7180_state *state, unsigned int page)
 {
 	if (state->register_page != page) {
@@ -235,6 +261,20 @@  static int adv7180_read(struct adv7180_state *state, unsigned int reg)
 	return i2c_smbus_read_byte_data(state->client, reg & 0xff);
 }
 
+static int adv7180_load_reg_tbl(struct adv7180_state *state,
+				const struct adv7180_reg_tbl_t *tbl, int n)
+{
+	int ret, i;
+
+	for (i = 0; i < n; i++) {
+		ret = adv7180_write(state, tbl[i].reg, tbl[i].val);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int adv7180_csi_write(struct adv7180_state *state, unsigned int reg,
 	unsigned int value)
 {
@@ -828,19 +868,36 @@  static irqreturn_t adv7180_irq(int irq, void *devid)
 	return IRQ_HANDLED;
 }
 
+/*
+ * This register table conforms to Analog Device's Register Settings
+ * Recommendation for the ADV7180. It configures single-ended CVBS
+ * input on Ain1, and enables NEWAVMODE.
+ */
+static const struct adv7180_reg_tbl_t adv7180_single_ended_cvbs[] = {
+	/* Set analog mux for CVBS on Ain1 */
+	{ ADV7180_REG_INPUT_CONTROL, 0x00 },
+	/* ADI Required Write: Reset Clamp Circuitry */
+	{ ADV7180_REG_ANALOG_CLAMP_CTL, 0x30 },
+	/* Enable SFL Output */
+	{ ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x57 },
+	/* Select SH1 Chroma Shaping Filter */
+	{ ADV7180_REG_SHAP_FILTER_CTL_1, 0x41 },
+	/* Enable NEWAVMODE */
+	{ ADV7180_REG_VSYNC_FIELD_CTL_1, 0x02 },
+	/* ADI Required Write: optimize windowing function Step 1,2,3 */
+	{ ADV7180_REG_MANUAL_WIN_CTL_1, 0xA2 },
+	{ ADV7180_REG_MANUAL_WIN_CTL_2, 0x6A },
+	{ ADV7180_REG_MANUAL_WIN_CTL_3, 0xA0 },
+	/* ADI Required Write: Enable ADC step 1,2,3 */
+	{ 0x8055, 0x81 }, /* undocumented register 0x55 */
+	/* Recommended AFE I BIAS Setting for CVBS mode */
+	{ ADV7180_REG_CVBS_TRIM, 0x0D },
+};
+
 static int adv7180_init(struct adv7180_state *state)
 {
-	int ret;
-
-	/* ITU-R BT.656-4 compatible */
-	ret = adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
-			ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
-	if (ret < 0)
-		return ret;
-
-	/* Manually set V bit end position in NTSC mode */
-	return adv7180_write(state, ADV7180_REG_NTSC_V_BIT_END,
-					ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
+	return adv7180_load_reg_tbl(state, adv7180_single_ended_cvbs,
+				    ARRAY_SIZE(adv7180_single_ended_cvbs));
 }
 
 static int adv7180_set_std(struct adv7180_state *state, unsigned int std)
@@ -862,8 +919,48 @@  static int adv7180_select_input(struct adv7180_state *state, unsigned int input)
 	return adv7180_write(state, ADV7180_REG_INPUT_CONTROL, ret);
 }
 
+/*
+ * This register table conforms to Analog Device's Register Settings
+ * Recommendation revision C for the ADV7182. It configures single-ended
+ * CVBS inputs on Ain1, and enables NEWAVMODE.
+ */
+static const struct adv7180_reg_tbl_t adv7182_single_ended_cvbs[] = {
+	/* Exit Power Down Mode */
+	{ ADV7180_REG_PWR_MAN, 0x00 },
+	/* Enable ADV7182 for 28.63636 MHz Crystal Clock Input */
+	{ ADV7180_REG_STATUS3, 0x00 },
+	/* Set optimized IBIAS for single-ended CVBS input */
+	{ ADV7180_REG_CVBS_TRIM, 0xCD },
+	/* Switch to single-ended CVBS on AIN1 */
+	{ ADV7180_REG_INPUT_CONTROL, 0x00 },
+	/* ADI Required Write: Reset Current Clamp Circuitry steps 1,2,3,4 */
+	{ ADV7180_REG_RST_CLAMP, 0x00 },
+	{ ADV7180_REG_RST_CLAMP, 0xFF },
+	/* Select SH1 Chroma Shaping Filter */
+	{ ADV7180_REG_SHAP_FILTER_CTL_1, 0x41 },
+	/* Enable Pixel & Sync output drivers */
+	{ ADV7180_REG_OUTPUT_CONTROL, 0x0C },
+	/* Power-up INTRQ, HS and VS/FIELD/SFL pad */
+	{ ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x07 },
+	/* Enable LLC Output Driver */
+	{ ADV7180_REG_CTRL_2, 0x40 },
+	/* Optimize ACE Performance */
+	{ ADV7180_REG_ACE_CTRL5, 0x00 },
+	/* Enable ACE Feature */
+	{ ADV7180_REG_ACE_CTRL1, 0x80 },
+	/* Enable NEWAVMODE */
+	{ ADV7180_REG_VSYNC_FIELD_CTL_1, 0x02 },
+};
+
 static int adv7182_init(struct adv7180_state *state)
 {
+	int ret;
+
+	ret = adv7180_load_reg_tbl(state, adv7182_single_ended_cvbs,
+				   ARRAY_SIZE(adv7182_single_ended_cvbs));
+	if (ret)
+		return ret;
+
 	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
 		adv7180_write(state, ADV7180_REG_CSI_SLAVE_ADDR,
 			ADV7180_DEFAULT_CSI_I2C_ADDR << 1);
@@ -881,20 +978,15 @@  static int adv7182_init(struct adv7180_state *state)
 
 	/* ADI required writes */
 	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
-		adv7180_write(state, 0x0003, 0x4e);
-		adv7180_write(state, 0x0004, 0x57);
-		adv7180_write(state, 0x001d, 0xc0);
+		adv7180_write(state, ADV7180_REG_OUTPUT_CONTROL, 0x4e);
+		adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x57);
+		adv7180_write(state, ADV7180_REG_CTRL_2, 0xc0);
 	} else {
 		if (state->chip_info->flags & ADV7180_FLAG_V2)
-			adv7180_write(state, 0x0004, 0x17);
-		else
-			adv7180_write(state, 0x0004, 0x07);
-		adv7180_write(state, 0x0003, 0x0c);
-		adv7180_write(state, 0x001d, 0x40);
+			adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
+				      0x17);
 	}
 
-	adv7180_write(state, 0x0013, 0x00);
-
 	return 0;
 }
 
@@ -967,8 +1059,8 @@  static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
 		return ret;
 
 	/* Reset clamp circuitry - ADI recommended writes */
-	adv7180_write(state, 0x809c, 0x00);
-	adv7180_write(state, 0x809c, 0xff);
+	adv7180_write(state, ADV7180_REG_RST_CLAMP, 0x00);
+	adv7180_write(state, ADV7180_REG_RST_CLAMP, 0xff);
 
 	input_type = adv7182_get_input_type(input);
 
@@ -976,10 +1068,10 @@  static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
 	case ADV7182_INPUT_TYPE_CVBS:
 	case ADV7182_INPUT_TYPE_DIFF_CVBS:
 		/* ADI recommends to use the SH1 filter */
-		adv7180_write(state, 0x0017, 0x41);
+		adv7180_write(state, ADV7180_REG_SHAP_FILTER_CTL_1, 0x41);
 		break;
 	default:
-		adv7180_write(state, 0x0017, 0x01);
+		adv7180_write(state, ADV7180_REG_SHAP_FILTER_CTL_1, 0x01);
 		break;
 	}
 
@@ -989,21 +1081,21 @@  static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
 		lbias = adv7182_lbias_settings[input_type];
 
 	for (i = 0; i < ARRAY_SIZE(adv7182_lbias_settings[0]); i++)
-		adv7180_write(state, 0x0052 + i, lbias[i]);
+		adv7180_write(state, ADV7180_REG_CVBS_TRIM + i, lbias[i]);
 
 	if (input_type == ADV7182_INPUT_TYPE_DIFF_CVBS) {
 		/* ADI required writes to make differential CVBS work */
-		adv7180_write(state, 0x005f, 0xa8);
-		adv7180_write(state, 0x005a, 0x90);
-		adv7180_write(state, 0x0060, 0xb0);
-		adv7180_write(state, 0x80b6, 0x08);
-		adv7180_write(state, 0x80c0, 0xa0);
+		adv7180_write(state, ADV7180_REG_RES_CIR, 0xa8);
+		adv7180_write(state, ADV7180_REG_CLAMP_ADJ, 0x90);
+		adv7180_write(state, ADV7180_REG_DIFF_MODE, 0xb0);
+		adv7180_write(state, ADV7180_REG_AGC_ADJ1, 0x08);
+		adv7180_write(state, ADV7180_REG_AGC_ADJ2, 0xa0);
 	} else {
-		adv7180_write(state, 0x005f, 0xf0);
-		adv7180_write(state, 0x005a, 0xd0);
-		adv7180_write(state, 0x0060, 0x10);
-		adv7180_write(state, 0x80b6, 0x9c);
-		adv7180_write(state, 0x80c0, 0x00);
+		adv7180_write(state, ADV7180_REG_RES_CIR, 0xf0);
+		adv7180_write(state, ADV7180_REG_CLAMP_ADJ, 0xd0);
+		adv7180_write(state, ADV7180_REG_DIFF_MODE, 0x10);
+		adv7180_write(state, ADV7180_REG_AGC_ADJ1, 0x9c);
+		adv7180_write(state, ADV7180_REG_AGC_ADJ2, 0x00);
 	}
 
 	return 0;