2121#include <linux/gpio/consumer.h>
2222#include <media/v4l2-device.h>
2323#include <media/v4l2-ctrls.h>
24+ #include <media/v4l2-fwnode.h>
2425#include <media/v4l2-mediabus.h>
2526#include <media/v4l2-image-sizes.h>
2627#include <media/i2c/ov7670.h>
@@ -242,6 +243,7 @@ struct ov7670_info {
242243 struct clk * clk ;
243244 struct gpio_desc * resetb_gpio ;
244245 struct gpio_desc * pwdn_gpio ;
246+ unsigned int mbus_config ; /* Media bus configuration flags */
245247 int min_width ; /* Filter out smaller sizes */
246248 int min_height ; /* Filter out smaller sizes */
247249 int clock_speed ; /* External clock speed (MHz) */
@@ -1014,7 +1016,7 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
10141016#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
10151017 struct v4l2_mbus_framefmt * mbus_fmt ;
10161018#endif
1017- unsigned char com7 ;
1019+ unsigned char com7 , com10 = 0 ;
10181020 int ret ;
10191021
10201022 if (format -> pad )
@@ -1034,7 +1036,6 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
10341036 }
10351037
10361038 ret = ov7670_try_fmt_internal (sd , & format -> format , & ovfmt , & wsize );
1037-
10381039 if (ret )
10391040 return ret ;
10401041 /*
@@ -1045,16 +1046,41 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
10451046 */
10461047 com7 = ovfmt -> regs [0 ].value ;
10471048 com7 |= wsize -> com7_bit ;
1048- ov7670_write (sd , REG_COM7 , com7 );
1049+ ret = ov7670_write (sd , REG_COM7 , com7 );
1050+ if (ret )
1051+ return ret ;
1052+
1053+ /*
1054+ * Configure the media bus through COM10 register
1055+ */
1056+ if (info -> mbus_config & V4L2_MBUS_VSYNC_ACTIVE_LOW )
1057+ com10 |= COM10_VS_NEG ;
1058+ if (info -> mbus_config & V4L2_MBUS_HSYNC_ACTIVE_LOW )
1059+ com10 |= COM10_HREF_REV ;
1060+ if (info -> pclk_hb_disable )
1061+ com10 |= COM10_PCLK_HB ;
1062+ ret = ov7670_write (sd , REG_COM10 , com10 );
1063+ if (ret )
1064+ return ret ;
1065+
10491066 /*
10501067 * Now write the rest of the array. Also store start/stops
10511068 */
1052- ov7670_write_array (sd , ovfmt -> regs + 1 );
1053- ov7670_set_hw (sd , wsize -> hstart , wsize -> hstop , wsize -> vstart ,
1054- wsize -> vstop );
1055- ret = 0 ;
1056- if (wsize -> regs )
1069+ ret = ov7670_write_array (sd , ovfmt -> regs + 1 );
1070+ if (ret )
1071+ return ret ;
1072+
1073+ ret = ov7670_set_hw (sd , wsize -> hstart , wsize -> hstop , wsize -> vstart ,
1074+ wsize -> vstop );
1075+ if (ret )
1076+ return ret ;
1077+
1078+ if (wsize -> regs ) {
10571079 ret = ov7670_write_array (sd , wsize -> regs );
1080+ if (ret )
1081+ return ret ;
1082+ }
1083+
10581084 info -> fmt = ovfmt ;
10591085
10601086 /*
@@ -1067,8 +1093,10 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
10671093 * to write it unconditionally, and that will make the frame
10681094 * rate persistent too.
10691095 */
1070- if (ret == 0 )
1071- ret = ov7670_write (sd , REG_CLKRC , info -> clkrc );
1096+ ret = ov7670_write (sd , REG_CLKRC , info -> clkrc );
1097+ if (ret )
1098+ return ret ;
1099+
10721100 return 0 ;
10731101}
10741102
@@ -1698,6 +1726,45 @@ static int ov7670_init_gpio(struct i2c_client *client, struct ov7670_info *info)
16981726 return 0 ;
16991727}
17001728
1729+ /*
1730+ * ov7670_parse_dt() - Parse device tree to collect mbus configuration
1731+ * properties
1732+ */
1733+ static int ov7670_parse_dt (struct device * dev ,
1734+ struct ov7670_info * info )
1735+ {
1736+ struct fwnode_handle * fwnode = dev_fwnode (dev );
1737+ struct v4l2_fwnode_endpoint bus_cfg ;
1738+ struct fwnode_handle * ep ;
1739+ int ret ;
1740+
1741+ if (!fwnode )
1742+ return - EINVAL ;
1743+
1744+ info -> pclk_hb_disable = false;
1745+ if (fwnode_property_present (fwnode , "ov7670,pclk-hb-disable" ))
1746+ info -> pclk_hb_disable = true;
1747+
1748+ ep = fwnode_graph_get_next_endpoint (fwnode , NULL );
1749+ if (!ep )
1750+ return - EINVAL ;
1751+
1752+ ret = v4l2_fwnode_endpoint_parse (ep , & bus_cfg );
1753+ if (ret ) {
1754+ fwnode_handle_put (ep );
1755+ return ret ;
1756+ }
1757+
1758+ if (bus_cfg .bus_type != V4L2_MBUS_PARALLEL ) {
1759+ dev_err (dev , "Unsupported media bus type\n" );
1760+ fwnode_handle_put (ep );
1761+ return ret ;
1762+ }
1763+ info -> mbus_config = bus_cfg .bus .parallel .flags ;
1764+
1765+ return 0 ;
1766+ }
1767+
17011768static int ov7670_probe (struct i2c_client * client ,
17021769 const struct i2c_device_id * id )
17031770{
@@ -1718,7 +1785,13 @@ static int ov7670_probe(struct i2c_client *client,
17181785#endif
17191786
17201787 info -> clock_speed = 30 ; /* default: a guess */
1721- if (client -> dev .platform_data ) {
1788+
1789+ if (dev_fwnode (& client -> dev )) {
1790+ ret = ov7670_parse_dt (& client -> dev , info );
1791+ if (ret )
1792+ return ret ;
1793+
1794+ } else if (client -> dev .platform_data ) {
17221795 struct ov7670_config * config = client -> dev .platform_data ;
17231796
17241797 /*
@@ -1785,9 +1858,6 @@ static int ov7670_probe(struct i2c_client *client,
17851858 tpf .denominator = 30 ;
17861859 info -> devtype -> set_framerate (sd , & tpf );
17871860
1788- if (info -> pclk_hb_disable )
1789- ov7670_write (sd , REG_COM10 , COM10_PCLK_HB );
1790-
17911861 v4l2_ctrl_handler_init (& info -> hdl , 10 );
17921862 v4l2_ctrl_new_std (& info -> hdl , & ov7670_ctrl_ops ,
17931863 V4L2_CID_BRIGHTNESS , 0 , 255 , 1 , 128 );
0 commit comments