[v2,2/2] media: i2c: adv7180: fix adv7280 BT.656-4 compatibility
Commit Message
From: Matthew Michilot <matthew.michilot@gmail.com>
Captured video would be out of sync when using the adv7280 with
the BT.656-4 protocol. Certain registers (0x04, 0x31, 0xE6) had to
be configured properly to ensure BT.656-4 compatibility.
An error in the adv7280 reference manual suggested that EAV/SAV mode
was enabled by default, however upon inspecting register 0x31, it was
determined to be disabled by default.
Signed-off-by: Matthew Michilot <matthew.michilot@gmail.com>
Reviewed-by: Tim Harvey <tharvey@gateworks.com>
[fabio: Introduce "adv,force-bt656-4" to not affect the existing users]
Signed-off-by: Fabio Estevam <festevam@gmail.com>
---
Changes since v1:
- Remove the part number from the property name (Rob)
drivers/media/i2c/adv7180.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
Comments
On Fri, Jun 4, 2021 at 2:22 PM Fabio Estevam <festevam@gmail.com> wrote:
>
> From: Matthew Michilot <matthew.michilot@gmail.com>
>
> Captured video would be out of sync when using the adv7280 with
> the BT.656-4 protocol. Certain registers (0x04, 0x31, 0xE6) had to
> be configured properly to ensure BT.656-4 compatibility.
>
> An error in the adv7280 reference manual suggested that EAV/SAV mode
> was enabled by default, however upon inspecting register 0x31, it was
> determined to be disabled by default.
>
> Signed-off-by: Matthew Michilot <matthew.michilot@gmail.com>
> Reviewed-by: Tim Harvey <tharvey@gateworks.com>
> [fabio: Introduce "adv,force-bt656-4" to not affect the existing users]
> Signed-off-by: Fabio Estevam <festevam@gmail.com>
> ---
> Changes since v1:
> - Remove the part number from the property name (Rob)
>
> drivers/media/i2c/adv7180.c | 30 ++++++++++++++++++++++++++----
> 1 file changed, 26 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
> index 44bb6fe85644..a532df813d74 100644
> --- a/drivers/media/i2c/adv7180.c
> +++ b/drivers/media/i2c/adv7180.c
> @@ -94,6 +94,7 @@
> #define ADV7180_REG_SHAP_FILTER_CTL_1 0x0017
> #define ADV7180_REG_CTRL_2 0x001d
> #define ADV7180_REG_VSYNC_FIELD_CTL_1 0x0031
> +#define ADV7180_VSYNC_FIELD_CTL_1_NEWAV 0x12
> #define ADV7180_REG_MANUAL_WIN_CTL_1 0x003d
> #define ADV7180_REG_MANUAL_WIN_CTL_2 0x003e
> #define ADV7180_REG_MANUAL_WIN_CTL_3 0x003f
> @@ -216,6 +217,7 @@ struct adv7180_state {
> struct i2c_client *vpp_client;
> const struct adv7180_chip_info *chip_info;
> enum v4l2_field field;
> + bool force_bt656_4;
> };
> #define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
> struct adv7180_state, \
> @@ -963,10 +965,26 @@ static int adv7182_init(struct adv7180_state *state)
> 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,
> - ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
> - 0x17);
> + if (state->chip_info->flags & ADV7180_FLAG_V2) {
> + if (state->force_bt656_4) {
> + /* ITU-R BT.656-4 compatible */
> + adv7180_write(state,
> + ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
> + ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
> + /* Manually set NEWAVMODE */
> + adv7180_write(state,
> + ADV7180_REG_VSYNC_FIELD_CTL_1,
> + ADV7180_VSYNC_FIELD_CTL_1_NEWAV);
> + /* Manually set V bit end position in NTSC mode */
> + adv7180_write(state,
> + ADV7180_REG_NTSC_V_BIT_END,
> + ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
> + } else {
> + adv7180_write(state,
> + ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
> + 0x17);
> + }
> + }
> else
> adv7180_write(state,
> ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
> @@ -1314,6 +1332,7 @@ static int init_device(struct adv7180_state *state)
> static int adv7180_probe(struct i2c_client *client,
> const struct i2c_device_id *id)
> {
> + struct device_node *np = client->dev.of_node;
> struct adv7180_state *state;
> struct v4l2_subdev *sd;
> int ret;
> @@ -1338,6 +1357,9 @@ static int adv7180_probe(struct i2c_client *client,
> return ret;
> }
>
> + if (of_property_read_bool(np, "adv,force-bt656-4"))
> + state->force_bt656_4 = true;
> +
> if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
> state->csi_client = i2c_new_dummy_device(client->adapter,
> ADV7180_DEFAULT_CSI_I2C_ADDR);
> --
> 2.25.1
Fabio,
Thanks for the submission. This does resolve NTSC capture on a
GW5410-G with an adv7280.
Reviewed-by: Tim Harvey <tharvey@gateworks.com>
Tested-by: Tim Harvey <tharvey@gateworks.com>
Best regards,
Tim
Hi Hans,
On Thu, Jul 1, 2021 at 3:29 PM Tim Harvey <tharvey@gateworks.com> wrote:
> Fabio,
>
> Thanks for the submission. This does resolve NTSC capture on a
> GW5410-G with an adv7280.
>
> Reviewed-by: Tim Harvey <tharvey@gateworks.com>
> Tested-by: Tim Harvey <tharvey@gateworks.com>
Do you think this series could be applied?
Thanks,
Fabio Estevam
On Mon, Jul 12, 2021 at 12:59 PM Fabio Estevam <festevam@gmail.com> wrote:
>
> Hi Hans,
>
> On Thu, Jul 1, 2021 at 3:29 PM Tim Harvey <tharvey@gateworks.com> wrote:
>
> > Fabio,
> >
> > Thanks for the submission. This does resolve NTSC capture on a
> > GW5410-G with an adv7280.
> >
> > Reviewed-by: Tim Harvey <tharvey@gateworks.com>
> > Tested-by: Tim Harvey <tharvey@gateworks.com>
>
> Do you think this series could be applied?
A gentle ping.
Thanks
@@ -94,6 +94,7 @@
#define ADV7180_REG_SHAP_FILTER_CTL_1 0x0017
#define ADV7180_REG_CTRL_2 0x001d
#define ADV7180_REG_VSYNC_FIELD_CTL_1 0x0031
+#define ADV7180_VSYNC_FIELD_CTL_1_NEWAV 0x12
#define ADV7180_REG_MANUAL_WIN_CTL_1 0x003d
#define ADV7180_REG_MANUAL_WIN_CTL_2 0x003e
#define ADV7180_REG_MANUAL_WIN_CTL_3 0x003f
@@ -216,6 +217,7 @@ struct adv7180_state {
struct i2c_client *vpp_client;
const struct adv7180_chip_info *chip_info;
enum v4l2_field field;
+ bool force_bt656_4;
};
#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
struct adv7180_state, \
@@ -963,10 +965,26 @@ static int adv7182_init(struct adv7180_state *state)
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,
- ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
- 0x17);
+ if (state->chip_info->flags & ADV7180_FLAG_V2) {
+ if (state->force_bt656_4) {
+ /* ITU-R BT.656-4 compatible */
+ adv7180_write(state,
+ ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
+ ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
+ /* Manually set NEWAVMODE */
+ adv7180_write(state,
+ ADV7180_REG_VSYNC_FIELD_CTL_1,
+ ADV7180_VSYNC_FIELD_CTL_1_NEWAV);
+ /* Manually set V bit end position in NTSC mode */
+ adv7180_write(state,
+ ADV7180_REG_NTSC_V_BIT_END,
+ ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
+ } else {
+ adv7180_write(state,
+ ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
+ 0x17);
+ }
+ }
else
adv7180_write(state,
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
@@ -1314,6 +1332,7 @@ static int init_device(struct adv7180_state *state)
static int adv7180_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device_node *np = client->dev.of_node;
struct adv7180_state *state;
struct v4l2_subdev *sd;
int ret;
@@ -1338,6 +1357,9 @@ static int adv7180_probe(struct i2c_client *client,
return ret;
}
+ if (of_property_read_bool(np, "adv,force-bt656-4"))
+ state->force_bt656_4 = true;
+
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
state->csi_client = i2c_new_dummy_device(client->adapter,
ADV7180_DEFAULT_CSI_I2C_ADDR);