diff options
author | Vladimir Barinov <vladimir.barinov@cogentembedded.com> | 2018-01-28 02:57:28 +0300 |
---|---|---|
committer | Vladimir Barinov <vladimir.barinov@cogentembedded.com> | 2018-01-28 02:57:28 +0300 |
commit | 0f5e49cd832c4388bc2ddf03295f6f40a527ae1e (patch) | |
tree | 5d3ce07bddbe80bdd2ebfa6c6d86b5af1b7ce3f0 | |
parent | c3071eefebc05eea24ee73250546084e8fd8d3c6 (diff) |
LVDS: add poc-delay dts field
1) add poc-delay field that introduces extra delay after apply
POC-supply power. Default value is 50ms
2) add stability fixes for AP0101-AR014x cameras:
read OTP_ID runtime (do not use cached value at kernel boot time,
since it may read unstable/incorrectly)
-rw-r--r-- | meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch | 108 |
1 files changed, 71 insertions, 37 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch index a2bfd20..67728ff 100644 --- a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch @@ -11,13 +11,13 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> --- drivers/media/i2c/soc_camera/Kconfig | 47 + drivers/media/i2c/soc_camera/Makefile | 7 + - drivers/media/i2c/soc_camera/ap0101_ar014x.c | 581 +++++++++++ + drivers/media/i2c/soc_camera/ap0101_ar014x.c | 588 +++++++++++ drivers/media/i2c/soc_camera/ap0101_ar014x.h | 28 + - drivers/media/i2c/soc_camera/ar0132.c | 581 +++++++++++ + drivers/media/i2c/soc_camera/ar0132.c | 582 +++++++++++ drivers/media/i2c/soc_camera/ar0132.h | 213 ++++ - drivers/media/i2c/soc_camera/max9286.c | 688 +++++++++++++ + drivers/media/i2c/soc_camera/max9286.c | 697 +++++++++++++ drivers/media/i2c/soc_camera/max9286.h | 244 +++++ - drivers/media/i2c/soc_camera/ov10635.c | 758 ++++++++++++++ + drivers/media/i2c/soc_camera/ov10635.c | 759 ++++++++++++++ drivers/media/i2c/soc_camera/ov10635.h | 1139 +++++++++++++++++++++ drivers/media/i2c/soc_camera/ov10635_debug.h | 54 + drivers/media/i2c/soc_camera/ov106xx.c | 117 +++ @@ -25,8 +25,8 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> drivers/media/i2c/soc_camera/ov490_ov10640.h | 102 ++ drivers/media/i2c/soc_camera/ov495_ov2775.c | 658 ++++++++++++ drivers/media/i2c/soc_camera/ov495_ov2775.h | 23 + - drivers/media/i2c/soc_camera/ti954_ti9x3.c | 431 ++++++++ - drivers/media/i2c/soc_camera/ti964_ti9x3.c | 400 ++++++++ + drivers/media/i2c/soc_camera/ti954_ti9x3.c | 439 ++++++++ + drivers/media/i2c/soc_camera/ti964_ti9x3.c | 408 ++++++++ drivers/media/i2c/soc_camera/ti9x4_ti9x3.h | 153 +++ drivers/media/platform/soc_camera/rcar_csi2.c | 297 ++++-- drivers/media/platform/soc_camera/rcar_vin.c | 211 +++- @@ -34,7 +34,7 @@ Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com> drivers/media/platform/soc_camera/soc_mediabus.c | 16 + include/media/drv-intf/soc_mediabus.h | 3 + include/media/soc_camera.h | 1 + - 25 files changed, 7820 insertions(+), 109 deletions(-) + 25 files changed, 7854 insertions(+), 109 deletions(-) create mode 100644 drivers/media/i2c/soc_camera/ap0101_ar014x.c create mode 100644 drivers/media/i2c/soc_camera/ap0101_ar014x.h create mode 100644 drivers/media/i2c/soc_camera/ar0132.c @@ -133,10 +133,10 @@ index 6f994f9..e88f6a9 100644 obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c new file mode 100644 -index 0000000..3ba2a5a +index 0000000..2c6b034 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c -@@ -0,0 +1,581 @@ +@@ -0,0 +1,588 @@ +/* + * ON Semiconductor AP0101-AR014X sensor camera driver + * @@ -168,6 +168,8 @@ index 0000000..3ba2a5a + +#define AP0101_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8 + ++static void ap0101_otp_id_read(struct i2c_client *client); ++ +struct ap0101_priv { + struct v4l2_subdev sd; + struct v4l2_ctrl_handler hdl; @@ -184,7 +186,6 @@ index 0000000..3ba2a5a + int port; + int gpio_resetb; + int gpio_fsin; -+ +}; + +static inline struct ap0101_priv *to_ap0101(const struct i2c_client *client) @@ -201,6 +202,7 @@ index 0000000..3ba2a5a + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -236,6 +238,7 @@ index 0000000..3ba2a5a + usleep_range(100, 150); /* wait 100 us */ + reg16_read16(client, 0xfc00, ®_val); + reg16_write16(client, 0x0040, 0x8d02); ++ usleep_range(100, 150); /* wait 100 us */ + + return reg_val; +} @@ -252,6 +255,7 @@ index 0000000..3ba2a5a + reg16_write16(client, 0x0040, 0x8d08); + usleep_range(100, 150); /* wait 100 us */ + reg16_write16(client, 0x0040, 0x8d02); ++ usleep_range(100, 150); /* wait 100 us */ +} + +static int ap0101_s_stream(struct v4l2_subdev *sd, int enable) @@ -312,6 +316,8 @@ index 0000000..3ba2a5a + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ap0101_priv *priv = to_ap0101(client); + ++ ap0101_otp_id_read(client); ++ + memcpy(edid->edid, priv->id, 6); + + edid->edid[6] = 0xff; @@ -502,6 +508,8 @@ index 0000000..3ba2a5a + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ap0101_priv *priv = to_ap0101(client); + ++ ap0101_otp_id_read(client); ++ + return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n", + priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]); +} @@ -527,7 +535,6 @@ index 0000000..3ba2a5a + + /* Program wizard registers */ + ap0101_set_regs(client, ap0101_regs_wizard, ARRAY_SIZE(ap0101_regs_wizard)); -+ + /* Read OTP IDs */ + ap0101_otp_id_read(client); + @@ -754,10 +761,10 @@ index 0000000..16599a1 +}; diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c new file mode 100644 -index 0000000..bbaeeaae +index 0000000..97d9878 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ar0132.c -@@ -0,0 +1,581 @@ +@@ -0,0 +1,582 @@ +/* + * ON Semiconductor AR0132 sensor camera driver + * @@ -827,6 +834,7 @@ index 0000000..bbaeeaae + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -1560,10 +1568,10 @@ index 0000000..bcee0e5 +}; diff --git a/drivers/media/i2c/soc_camera/max9286.c b/drivers/media/i2c/soc_camera/max9286.c new file mode 100644 -index 0000000..8a62b91 +index 0000000..989c782 --- /dev/null +++ b/drivers/media/i2c/soc_camera/max9286.c -@@ -0,0 +1,688 @@ +@@ -0,0 +1,697 @@ +/* + * MAXIM max9286 GMSL driver + * @@ -1617,6 +1625,7 @@ index 0000000..8a62b91 + int hsync; + int vsync; + int timeout; ++ int poc_delay; + atomic_t use_count; + u32 csi2_outord; + struct i2c_client *client; @@ -1659,6 +1668,10 @@ index 0000000..8a62b91 +module_param(active_low_resetb, int, 0644); +MODULE_PARM_DESC(active_low_resetb, " Serializer GPIO reset level (default: 0 - active high) */"); + ++static int poc_delay; ++module_param(poc_delay, int, 0644); ++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms) */"); ++ +static char* ser_name(int id) +{ + switch (id) { @@ -1786,6 +1799,7 @@ index 0000000..8a62b91 + mdelay(200); + if (regulator_enable(priv->poc_supply[idx])) + dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); ++ mdelay(priv->poc_delay); + } + } + } @@ -1926,6 +1940,7 @@ index 0000000..8a62b91 + if (!IS_ERR(priv->poc_supply[idx])) { + if (regulator_enable(priv->poc_supply[idx])) + dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); ++ mdelay(priv->poc_delay); + } + + ret = max9286_reverse_channel_setup(client, idx); @@ -2073,10 +2088,8 @@ index 0000000..8a62b91 + + if (!of_property_read_u32(np, "maxim,sensor_delay", &sensor_delay)) + mdelay(sensor_delay); -+ + if (of_property_read_string(np, "maxim,fsync-mode", &priv->fsync_mode)) + priv->fsync_mode = fsync_mode_default; -+ + if (of_property_read_u32(np, "maxim,fsync-period", &priv->fsync_period)) + priv->fsync_period = 3200000; /* 96MHz/30fps */ + priv->pclk_rising_edge = true; @@ -2092,6 +2105,8 @@ index 0000000..8a62b91 + priv->hsync = 0; + if (of_property_read_u32(np, "maxim,vsync", &priv->vsync)) + priv->vsync = 1; ++ if (of_property_read_u32(np, "maxim,poc-delay", &priv->poc_delay)) ++ priv->poc_delay = 50; + + /* module params override dts */ + if (him) @@ -2108,6 +2123,8 @@ index 0000000..8a62b91 + priv->gpio_resetb = gpio_resetb; + if (active_low_resetb) + priv->active_low_resetb = active_low_resetb; ++ if (poc_delay) ++ priv->poc_delay = poc_delay; + + for (i = 0; i < priv->links; i++) { + endpoint = of_graph_get_next_endpoint(np, endpoint); @@ -2504,10 +2521,10 @@ index 0000000..6c2a9e0 +#endif /* _MAX9286_MAX9271_H */ diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c new file mode 100644 -index 0000000..c8da1f4 +index 0000000..8c06e59 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov10635.c -@@ -0,0 +1,758 @@ +@@ -0,0 +1,759 @@ +/* + * OmniVision ov10635 sensor camera driver + * @@ -2580,6 +2597,7 @@ index 0000000..c8da1f4 + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -4596,7 +4614,7 @@ index 0000000..4c797f9 +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c new file mode 100644 -index 0000000..690eac0 +index 0000000..f1e34a3 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c @@ -0,0 +1,1160 @@ @@ -4698,7 +4716,7 @@ index 0000000..690eac0 + tmp_addr = client->addr; + client->addr = priv->max9286_addr; /* Deserializer I2C address */ + reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */ -+ usleep_range(2000, 2500); /* wait 2ms */ ++ usleep_range(5000, 5500); /* wait 5ms */ + client->addr = tmp_addr; + }; +} @@ -6563,10 +6581,10 @@ index 0000000..3f53689 +}; diff --git a/drivers/media/i2c/soc_camera/ti954_ti9x3.c b/drivers/media/i2c/soc_camera/ti954_ti9x3.c new file mode 100644 -index 0000000..1672173 +index 0000000..ff84128 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ti954_ti9x3.c -@@ -0,0 +1,431 @@ +@@ -0,0 +1,439 @@ +/* + * TI ti954-(ti913/ti953) FPDLinkIII driver + * @@ -6602,6 +6620,7 @@ index 0000000..1672173 + int csi_rate; + const char *forwarding_mode; + const char *cable_mode; ++ int poc_delay; + atomic_t use_count; + struct i2c_client *client; + int ti9x3_addr_map[4]; @@ -6636,6 +6655,10 @@ index 0000000..1672173 +} +#endif + ++static int poc_delay; ++module_param(poc_delay, int, 0644); ++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms) */"); ++ +static void ti954_ti9x3_read_chipid(struct i2c_client *client) +{ + struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client); @@ -6743,6 +6766,7 @@ index 0000000..1672173 + if (!IS_ERR(priv->poc_supply[idx])) { + if (regulator_enable(priv->poc_supply[idx])) + dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); ++ mdelay(priv->poc_delay); + } + + ti954_ti9x3_fpdlink3_setup(client, idx); @@ -6866,14 +6890,16 @@ index 0000000..1672173 + + if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay)) + mdelay(sensor_delay); -+ -+ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode); -+ if (err) ++ if (of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode)) + priv->forwarding_mode = forwarding_mode_default; -+ -+ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode); -+ if (err) ++ if (of_property_read_string(np, "ti,cable-mode", &priv->cable_mode)) + priv->cable_mode = cable_mode_default; ++ if (of_property_read_u32(np, "ti,poc-delay", &priv->poc_delay)) ++ priv->poc_delay = 50; ++ ++ /* module params override dts */ ++ if (poc_delay) ++ priv->poc_delay = poc_delay; + + for (i = 0; ; i++) { + endpoint = of_graph_get_next_endpoint(np, endpoint); @@ -7000,10 +7026,10 @@ index 0000000..1672173 +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/soc_camera/ti964_ti9x3.c b/drivers/media/i2c/soc_camera/ti964_ti9x3.c new file mode 100644 -index 0000000..bffd7c2 +index 0000000..8393392 --- /dev/null +++ b/drivers/media/i2c/soc_camera/ti964_ti9x3.c -@@ -0,0 +1,400 @@ +@@ -0,0 +1,408 @@ +/* + * TI (ti964/ti960)-(ti913/ti953) FPDLinkIII driver + * @@ -7039,6 +7065,7 @@ index 0000000..bffd7c2 + int csi_rate; + const char *forwarding_mode; + const char *cable_mode; ++ int poc_delay; + atomic_t use_count; + struct i2c_client *client; + int ti9x3_addr_map[4]; @@ -7046,6 +7073,10 @@ index 0000000..bffd7c2 + struct regulator *poc_supply[4]; /* PoC power supply */ +}; + ++static int poc_delay; ++module_param(poc_delay, int, 0644); ++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms) */"); ++ +static void ti964_ti9x3_read_chipid(struct i2c_client *client) +{ + struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client); @@ -7154,6 +7185,7 @@ index 0000000..bffd7c2 + if (!IS_ERR(priv->poc_supply[idx])) { + if (regulator_enable(priv->poc_supply[idx])) + dev_err(&client->dev, "fail to enable POC%d regulator\n", idx); ++ mdelay(priv->poc_delay); + } + + ti964_ti9x3_fpdlink3_setup(client, idx); @@ -7272,14 +7304,16 @@ index 0000000..bffd7c2 + + if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay)) + mdelay(sensor_delay); -+ -+ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode); -+ if (err) ++ if (of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode)) + priv->forwarding_mode = forwarding_mode_default; -+ -+ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode); -+ if (err) ++ if (of_property_read_string(np, "ti,cable-mode", &priv->cable_mode)) + priv->cable_mode = cable_mode_default; ++ if (of_property_read_u32(np, "ti,poc-delay", &priv->poc_delay)) ++ priv->poc_delay = 50; ++ ++ /* module params override dts */ ++ if (poc_delay) ++ priv->poc_delay = poc_delay; + + for (i = 0; ; i++) { + endpoint = of_graph_get_next_endpoint(np, endpoint); |