devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver
@ 2017-12-11  1:31 Wenyou Yang
  2017-12-11  1:31 ` [PATCH v9 1/2] media: ov7740: Document device tree bindings Wenyou Yang
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Wenyou Yang @ 2017-12-11  1:31 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Mark Rutland
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Nicolas Ferre,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Sakari Ailus, Jonathan Corbet,
	Hans Verkuil, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linux Media Mailing List, Wenyou Yang

Add a Video4Linux2 sensor-level driver for the OmniVision OV7740
VGA camera image sensor.

Changes in v9:
 - Use the new SPDX ids.

Changes in v8:
 - As the registers are written at stream start, remove the written
   code from the set fmt function.

Changes in v7:
 - Add Acked-by tag.
 - Fix the wrong handle of default register configuration.
 - Add the missed assignment of ov7740->frmsize.

Changes in v6:
 - Remove unnecessary #include <linux/init>.
 - Remove unnecessary comments and extra newline.
 - Add const for some structures.
 - Add the check of the return value from regmap_write().
 - Simplify the calling of __v4l2_ctrl_handler_setup().
 - Add the default format initialization function.
 - Integrate the set_power() and enable/disable the clock into
   one function.

Changes in v5:
 - Squash the driver and MAINTAINERS entry patches to one.
 - Precede the driver patch with the bindings patch.

Changes in v4:
 - Assign 'val' a initial value to avoid warning: 'val' may be
   used uninitialized.
 - Rename REG_REG15 to avoid warning: "REG_REG15" redefined.

Changes in v3:
 - Explicitly document the "remote-endpoint" property.
 - Put the MAINTAINERS change to a separate patch.

Changes in v2:
 - Split off the bindings into a separate patch.
 - Add a new entry to the MAINTAINERS file.

Wenyou Yang (2):
  media: ov7740: Document device tree bindings
  media: i2c: Add the ov7740 image sensor driver

 .../devicetree/bindings/media/i2c/ov7740.txt       |   47 +
 MAINTAINERS                                        |    8 +
 drivers/media/i2c/Kconfig                          |    8 +
 drivers/media/i2c/Makefile                         |    1 +
 drivers/media/i2c/ov7740.c                         | 1216 ++++++++++++++++++++
 5 files changed, 1280 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7740.txt
 create mode 100644 drivers/media/i2c/ov7740.c

-- 
2.15.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v9 1/2] media: ov7740: Document device tree bindings
  2017-12-11  1:31 [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver Wenyou Yang
@ 2017-12-11  1:31 ` Wenyou Yang
  2017-12-11  1:31 ` [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver Wenyou Yang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 16+ messages in thread
From: Wenyou Yang @ 2017-12-11  1:31 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Mark Rutland
  Cc: linux-kernel, Nicolas Ferre, devicetree, Sakari Ailus,
	Jonathan Corbet, Hans Verkuil, linux-arm-kernel,
	Linux Media Mailing List, Wenyou Yang

Add the device tree binding documentation for the ov7740 sensor driver.

Signed-off-by: Wenyou Yang <wenyou.yang@microchip.com>
Acked-by: Rob Herring <robh@kernel.org>
---

Changes in v9: None
Changes in v8: None
Changes in v7:
 - Add Acked-by tag.

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
 - Explicitly document the "remote-endpoint" property.

Changes in v2: None

 .../devicetree/bindings/media/i2c/ov7740.txt       | 47 ++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7740.txt

diff --git a/Documentation/devicetree/bindings/media/i2c/ov7740.txt b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
new file mode 100644
index 000000000000..af781c3a5f0e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
@@ -0,0 +1,47 @@
+* Omnivision OV7740 CMOS image sensor
+
+The Omnivision OV7740 image sensor supports multiple output image
+size, such as VGA, and QVGA, CIF and any size smaller. It also
+supports the RAW RGB and YUV output formats.
+
+The common video interfaces bindings (see video-interfaces.txt) should
+be used to specify link to the image data receiver. The OV7740 device
+node should contain one 'port' child node with an 'endpoint' subnode.
+
+Required Properties:
+- compatible:	"ovti,ov7740".
+- reg:		I2C slave address of the sensor.
+- clocks:	Reference to the xvclk input clock.
+- clock-names:	"xvclk".
+
+Optional Properties:
+- reset-gpios: Rreference to the GPIO connected to the reset_b pin,
+  if any. Active low with pull-ip resistor.
+- powerdown-gpios: Reference to the GPIO connected to the pwdn pin,
+  if any. Active high with pull-down resistor.
+
+Endpoint node mandatory properties:
+- remote-endpoint: A phandle to the bus receiver's endpoint node.
+
+Example:
+
+	i2c1: i2c@fc028000 {
+		ov7740: camera@21 {
+			compatible = "ovti,ov7740";
+			reg = <0x21>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_sensor_power &pinctrl_sensor_reset>;
+			clocks = <&isc>;
+			clock-names = "xvclk";
+			assigned-clocks = <&isc>;
+			assigned-clock-rates = <24000000>;
+			reset-gpios = <&pioA 43 GPIO_ACTIVE_LOW>;
+			powerdown-gpios = <&pioA 44 GPIO_ACTIVE_HIGH>;
+
+			port {
+				ov7740_0: endpoint {
+					remote-endpoint = <&isc_0>;
+				};
+			};
+		};
+	};
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
  2017-12-11  1:31 [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver Wenyou Yang
  2017-12-11  1:31 ` [PATCH v9 1/2] media: ov7740: Document device tree bindings Wenyou Yang
@ 2017-12-11  1:31 ` Wenyou Yang
       [not found]   ` <20171211013146.2497-3-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
  2017-12-19  9:22   ` Sakari Ailus
       [not found] ` <20171211013146.2497-1-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
  2017-12-15 13:26 ` Wenyou.Yang
  3 siblings, 2 replies; 16+ messages in thread
From: Wenyou Yang @ 2017-12-11  1:31 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Rob Herring, Mark Rutland
  Cc: linux-kernel, Nicolas Ferre, devicetree, Sakari Ailus,
	Jonathan Corbet, Hans Verkuil, linux-arm-kernel,
	Linux Media Mailing List, Wenyou Yang, Songjun Wu

The ov7740 (color) image sensor is a high performance VGA CMOS
image snesor, which supports for output formats: RAW RGB and YUV
and image sizes: VGA, and QVGA, CIF and any size smaller.

Signed-off-by: Songjun Wu <songjun.wu@microchip.com>
Signed-off-by: Wenyou Yang <wenyou.yang@microchip.com>
---

Changes in v9:
 - Use the new SPDX ids.

Changes in v8:
 - As the registers are written at stream start, remove the written
   code from the set fmt function.

Changes in v7:
 - Fix the wrong handle of default register configuration.
 - Add the missed assignment of ov7740->frmsize.

Changes in v6:
 - Remove unnecessary #include <linux/init>.
 - Remove unnecessary comments and extra newline.
 - Add const for some structures.
 - Add the check of the return value from regmap_write().
 - Simplify the calling of __v4l2_ctrl_handler_setup().
 - Add the default format initialization function.
 - Integrate the set_power() and enable/disable the clock into
   one function.

Changes in v5:
 - Squash the driver and MAINTAINERS entry patches to one.
 - Precede the driver patch with the bindings patch.

Changes in v4:
 - Assign 'val' a initial value to avoid warning: 'val' may be
   used uninitialized.
 - Rename REG_REG15 to avoid warning: "REG_REG15" redefined.

Changes in v3:
 - Put the MAINTAINERS change to a separate patch.

Changes in v2:
 - Split off the bindings into a separate patch.
 - Add a new entry to the MAINTAINERS file.

 MAINTAINERS                |    8 +
 drivers/media/i2c/Kconfig  |    8 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/ov7740.c | 1216 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1233 insertions(+)
 create mode 100644 drivers/media/i2c/ov7740.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7a52a66aa991..1de965009b13 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10053,6 +10053,14 @@ S:	Maintained
 F:	drivers/media/i2c/ov7670.c
 F:	Documentation/devicetree/bindings/media/i2c/ov7670.txt
 
+OMNIVISION OV7740 SENSOR DRIVER
+M:	Wenyou Yang <wenyou.yang@microchip.com>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Maintained
+F:	drivers/media/i2c/ov7740.c
+F:	Documentation/devicetree/bindings/media/i2c/ov7740.txt
+
 ONENAND FLASH DRIVER
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 L:	linux-mtd@lists.infradead.org
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cb5d7ff82915..00b1c4c031d4 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -665,6 +665,14 @@ config VIDEO_OV7670
 	  OV7670 VGA camera.  It currently only works with the M88ALP01
 	  controller.
 
+config VIDEO_OV7740
+	tristate "OmniVision OV7740 sensor support"
+	depends on I2C && VIDEO_V4L2
+	depends on MEDIA_CAMERA_SUPPORT
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the OmniVision
+	  OV7740 VGA camera sensor.
+
 config VIDEO_OV9650
 	tristate "OmniVision OV9650/OV9652 sensor support"
 	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 548a9efce966..9b19ec7fcaf4 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
 obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
 obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
 obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
 obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
 obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
new file mode 100644
index 000000000000..0308ba437bbb
--- /dev/null
+++ b/drivers/media/i2c/ov7740.c
@@ -0,0 +1,1216 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Microchip Corporation.
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-image-sizes.h>
+#include <media/v4l2-subdev.h>
+
+#define REG_OUTSIZE_LSB 0x34
+
+/* OV7740 register tables */
+#define REG_GAIN	0x00	/* Gain lower 8 bits (rest in vref) */
+#define REG_BGAIN	0x01	/* blue gain */
+#define REG_RGAIN	0x02	/* red gain */
+#define REG_GGAIN	0x03	/* green gain */
+#define REG_REG04	0x04	/* analog setting, dont change*/
+#define REG_BAVG	0x05	/* b channel average */
+#define REG_GAVG	0x06	/* g channel average */
+#define REG_RAVG	0x07	/* r channel average */
+
+#define REG_REG0C	0x0C	/* filp enable */
+#define REG0C_IMG_FLIP		0x80
+#define REG0C_IMG_MIRROR	0x40
+
+#define REG_REG0E	0x0E	/* blc line */
+#define REG_HAEC	0x0F	/* auto exposure cntrl */
+#define REG_AEC		0x10	/* auto exposure cntrl */
+
+#define REG_CLK		0x11	/* Clock control */
+#define REG_REG55	0x55	/* Clock PLL DIV/PreDiv */
+
+#define REG_REG12	0x12
+
+#define REG_REG13	0x13	/* auto/manual AGC, AEC, Write Balance*/
+#define REG13_AEC_EN	0x01
+#define REG13_AGC_EN	0x04
+
+#define REG_REG14	0x14
+#define REG_CTRL15	0x15
+#define REG15_GAIN_MSB	0x03
+
+#define REG_REG16	0x16
+
+#define REG_MIDH	0x1C	/* manufacture id byte */
+#define REG_MIDL	0x1D	/* manufacture id byre */
+#define REG_PIDH	0x0A	/* Product ID MSB */
+#define REG_PIDL	0x0B	/* Product ID LSB */
+
+#define REG_84		0x84	/* lots of stuff */
+#define REG_REG38	0x38	/* sub-addr */
+
+#define REG_AHSTART	0x17	/* Horiz start high bits */
+#define REG_AHSIZE	0x18
+#define REG_AVSTART	0x19	/* Vert start high bits */
+#define REG_AVSIZE	0x1A
+#define REG_PSHFT	0x1b	/* Pixel delay after HREF */
+
+#define REG_HOUTSIZE	0x31
+#define REG_VOUTSIZE	0x32
+#define REG_HVSIZEOFF	0x33
+#define REG_REG34	0x34	/* DSP output size H/V LSB*/
+
+#define REG_ISP_CTRL00	0x80
+#define ISPCTRL00_AWB_EN	0x10
+#define ISPCTRL00_AWB_GAIN_EN	0x04
+
+#define	REG_YGAIN	0xE2	/* ygain for contrast control */
+
+#define	REG_YBRIGHT	  0xE3
+#define	REG_SGNSET	  0xE4
+#define	SGNSET_YBRIGHT_MASK	  0x08
+
+#define REG_USAT	0xDD
+#define REG_VSAT	0xDE
+
+
+struct ov7740 {
+	struct v4l2_subdev subdev;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	struct media_pad pad;
+#endif
+	struct v4l2_mbus_framefmt format;
+	const struct ov7740_pixfmt *fmt;  /* Current format */
+	const struct ov7740_framesize *frmsize;
+	struct regmap *regmap;
+	struct clk *xvclk;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct {
+		/* gain cluster */
+		struct v4l2_ctrl *auto_gain;
+		struct v4l2_ctrl *gain;
+	};
+	struct {
+		struct v4l2_ctrl *auto_wb;
+		struct v4l2_ctrl *blue_balance;
+		struct v4l2_ctrl *red_balance;
+	};
+	struct {
+		struct v4l2_ctrl *hflip;
+		struct v4l2_ctrl *vflip;
+	};
+	struct {
+		/* exposure cluster */
+		struct v4l2_ctrl *auto_exposure;
+		struct v4l2_ctrl *exposure;
+	};
+	struct {
+		/* saturation/hue cluster */
+		struct v4l2_ctrl *saturation;
+		struct v4l2_ctrl *hue;
+	};
+	struct v4l2_ctrl *brightness;
+	struct v4l2_ctrl *contrast;
+
+	struct mutex mutex;	/* To serialize asynchronus callbacks */
+	bool streaming;		/* Streaming on/off */
+
+	struct gpio_desc *resetb_gpio;
+	struct gpio_desc *pwdn_gpio;
+};
+
+struct ov7740_pixfmt {
+	u32 mbus_code;
+	enum v4l2_colorspace colorspace;
+	const struct reg_sequence *regs;
+	u32 reg_num;
+};
+
+struct ov7740_framesize {
+	u16 width;
+	u16 height;
+	const struct reg_sequence *regs;
+	u32 reg_num;
+};
+
+static const struct reg_sequence ov7740_vga[] = {
+	{0x55, 0x40},
+	{0x11, 0x02},
+
+	{0xd5, 0x10},
+	{0x0c, 0x12},
+	{0x0d, 0x34},
+	{0x17, 0x25},
+	{0x18, 0xa0},
+	{0x19, 0x03},
+	{0x1a, 0xf0},
+	{0x1b, 0x89},
+	{0x22, 0x03},
+	{0x29, 0x18},
+	{0x2b, 0xf8},
+	{0x2c, 0x01},
+	{REG_HOUTSIZE, 0xa0},
+	{REG_VOUTSIZE, 0xf0},
+	{0x33, 0xc4},
+	{REG_OUTSIZE_LSB, 0x0},
+	{0x35, 0x05},
+	{0x04, 0x60},
+	{0x27, 0x80},
+	{0x3d, 0x0f},
+	{0x3e, 0x80},
+	{0x3f, 0x40},
+	{0x40, 0x7f},
+	{0x41, 0x6a},
+	{0x42, 0x29},
+	{0x44, 0x22},
+	{0x45, 0x41},
+	{0x47, 0x02},
+	{0x49, 0x64},
+	{0x4a, 0xa1},
+	{0x4b, 0x40},
+	{0x4c, 0x1a},
+	{0x4d, 0x50},
+	{0x4e, 0x13},
+	{0x64, 0x00},
+	{0x67, 0x88},
+	{0x68, 0x1a},
+
+	{0x14, 0x28},
+	{0x24, 0x3c},
+	{0x25, 0x30},
+	{0x26, 0x72},
+	{0x50, 0x97},
+	{0x51, 0x1f},
+	{0x52, 0x00},
+	{0x53, 0x00},
+	{0x20, 0x00},
+	{0x21, 0xcf},
+	{0x50, 0x4b},
+	{0x38, 0x14},
+	{0xe9, 0x00},
+	{0x56, 0x55},
+	{0x57, 0xff},
+	{0x58, 0xff},
+	{0x59, 0xff},
+	{0x5f, 0x04},
+	{0xec, 0x00},
+	{0x13, 0xff},
+
+	{0x81, 0x3f},
+	{0x82, 0x32},
+	{0x38, 0x11},
+	{0x84, 0x70},
+	{0x85, 0x00},
+	{0x86, 0x03},
+	{0x87, 0x01},
+	{0x88, 0x05},
+	{0x89, 0x30},
+	{0x8d, 0x30},
+	{0x8f, 0x85},
+	{0x93, 0x30},
+	{0x95, 0x85},
+	{0x99, 0x30},
+	{0x9b, 0x85},
+
+	{0x9c, 0x08},
+	{0x9d, 0x12},
+	{0x9e, 0x23},
+	{0x9f, 0x45},
+	{0xa0, 0x55},
+	{0xa1, 0x64},
+	{0xa2, 0x72},
+	{0xa3, 0x7f},
+	{0xa4, 0x8b},
+	{0xa5, 0x95},
+	{0xa6, 0xa7},
+	{0xa7, 0xb5},
+	{0xa8, 0xcb},
+	{0xa9, 0xdd},
+	{0xaa, 0xec},
+	{0xab, 0x1a},
+
+	{0xce, 0x78},
+	{0xcf, 0x6e},
+	{0xd0, 0x0a},
+	{0xd1, 0x0c},
+	{0xd2, 0x84},
+	{0xd3, 0x90},
+	{0xd4, 0x1e},
+
+	{0x5a, 0x24},
+	{0x5b, 0x1f},
+	{0x5c, 0x88},
+	{0x5d, 0x60},
+
+	{0xac, 0x6e},
+	{0xbe, 0xff},
+	{0xbf, 0x00},
+
+	{0x0f, 0x1d},
+	{0x0f, 0x1f},
+};
+
+static const struct ov7740_framesize ov7740_framesizes[] = {
+	{
+		.width		= VGA_WIDTH,
+		.height		= VGA_HEIGHT,
+		.regs		= ov7740_vga,
+		.reg_num	= ARRAY_SIZE(ov7740_vga),
+	},
+};
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov7740_get_register(struct v4l2_subdev *sd,
+			       struct v4l2_dbg_register *reg)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int val = 0;
+	int ret;
+
+	ret = regmap_read(regmap, reg->reg & 0xff, &val);
+	reg->val = val;
+	reg->size = 1;
+
+	return 0;
+}
+
+static int ov7740_set_register(struct v4l2_subdev *sd,
+			       const struct v4l2_dbg_register *reg)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct regmap *regmap = ov7740->regmap;
+
+	regmap_write(regmap, reg->reg & 0xff, reg->val & 0xff);
+
+	return 0;
+}
+#endif
+
+static int ov7740_set_power(struct ov7740 *ov7740, int on)
+{
+	int ret;
+
+	if (on) {
+		ret = clk_prepare_enable(ov7740->xvclk);
+		if (ret)
+			return ret;
+
+		if (ov7740->pwdn_gpio)
+			gpiod_direction_output(ov7740->pwdn_gpio, 0);
+
+		if (ov7740->resetb_gpio) {
+			gpiod_set_value(ov7740->resetb_gpio, 1);
+			usleep_range(500, 1000);
+			gpiod_set_value(ov7740->resetb_gpio, 0);
+			usleep_range(3000, 5000);
+		}
+	} else {
+		clk_disable_unprepare(ov7740->xvclk);
+
+		if (ov7740->pwdn_gpio)
+			gpiod_direction_output(ov7740->pwdn_gpio, 0);
+	}
+
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops ov7740_subdev_core_ops = {
+	.log_status = v4l2_ctrl_subdev_log_status,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = ov7740_get_register,
+	.s_register = ov7740_set_register,
+#endif
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static int ov7740_set_white_balance(struct ov7740 *ov7740, int awb)
+{
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int value;
+	int ret;
+
+	ret = regmap_read(regmap, REG_ISP_CTRL00, &value);
+	if (!ret) {
+		if (awb)
+			value |= (ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
+		else
+			value &= ~(ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
+		ret = regmap_write(regmap, REG_ISP_CTRL00, value);
+		if (ret)
+			return ret;
+	}
+
+	if (!awb) {
+		ret = regmap_write(regmap, REG_BGAIN,
+				   ov7740->blue_balance->val);
+		if (ret)
+			return ret;
+
+		ret = regmap_write(regmap, REG_RGAIN, ov7740->red_balance->val);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int ov7740_set_saturation(struct regmap *regmap, int value)
+{
+	int ret;
+
+	ret = regmap_write(regmap, REG_USAT, (unsigned char)value);
+	if (ret)
+		return ret;
+
+	return regmap_write(regmap, REG_VSAT, (unsigned char)value);
+}
+
+static int ov7740_set_gain(struct regmap *regmap, int value)
+{
+	int ret;
+
+	ret = regmap_write(regmap, REG_GAIN, value & 0xff);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(regmap, REG_CTRL15,
+				 REG15_GAIN_MSB, (value >> 8) & 0x3);
+	if (!ret)
+		ret = regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
+
+	return ret;
+}
+
+static int ov7740_set_autogain(struct regmap *regmap, int value)
+{
+	unsigned int reg;
+	int ret;
+
+	ret = regmap_read(regmap, REG_REG13, &reg);
+	if (ret)
+		return ret;
+	if (value)
+		reg |= REG13_AGC_EN;
+	else
+		reg &= ~REG13_AGC_EN;
+	return regmap_write(regmap, REG_REG13, reg);
+}
+
+static int ov7740_set_brightness(struct regmap *regmap, int value)
+{
+	/* Turn off AEC/AGC */
+	regmap_update_bits(regmap, REG_REG13, REG13_AEC_EN, 0);
+	regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
+
+	if (value >= 0) {
+		regmap_write(regmap, REG_YBRIGHT, (unsigned char)value);
+		regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 0);
+	} else{
+		regmap_write(regmap, REG_YBRIGHT, (unsigned char)(-value));
+		regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 1);
+	}
+
+	return 0;
+}
+
+static int ov7740_set_contrast(struct regmap *regmap, int value)
+{
+	return regmap_write(regmap, REG_YGAIN, (unsigned char)value);
+}
+
+static int ov7740_get_gain(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
+{
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int value0, value1;
+	int ret;
+
+	if (!ctrl->val)
+		return 0;
+
+	ret = regmap_read(regmap, REG_GAIN, &value0);
+	if (ret)
+		return ret;
+	ret = regmap_read(regmap, REG_CTRL15, &value1);
+	if (ret)
+		return ret;
+
+	ov7740->gain->val = (value1 << 8) | (value0 & 0xff);
+
+	return 0;
+}
+
+static int ov7740_set_exp(struct regmap *regmap, int value)
+{
+	int ret;
+
+	/* Turn off AEC/AGC */
+	ret = regmap_update_bits(regmap, REG_REG13,
+				 REG13_AEC_EN | REG13_AGC_EN, 0);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(regmap, REG_AEC, (unsigned char)value);
+	if (ret)
+		return ret;
+
+	return regmap_write(regmap, REG_HAEC, (unsigned char)(value >> 8));
+}
+
+static int ov7740_set_autoexp(struct regmap *regmap,
+			      enum v4l2_exposure_auto_type value)
+{
+	unsigned int reg;
+	int ret;
+
+	ret = regmap_read(regmap, REG_REG13, &reg);
+	if (!ret) {
+		if (value == V4L2_EXPOSURE_AUTO)
+			reg |= (REG13_AEC_EN | REG13_AGC_EN);
+		else
+			reg &= ~(REG13_AEC_EN | REG13_AGC_EN);
+		ret = regmap_write(regmap, REG_REG13, reg);
+	}
+
+	return ret;
+}
+
+
+static int ov7740_get_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov7740 *ov7740 = container_of(ctrl->handler,
+					     struct ov7740, ctrl_handler);
+	int ret;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTOGAIN:
+		ret = ov7740_get_gain(ov7740, ctrl);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov7740 *ov7740 = container_of(ctrl->handler,
+					     struct ov7740, ctrl_handler);
+	struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
+	struct regmap *regmap = ov7740->regmap;
+	int ret;
+	u8 val = 0;
+
+	if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		ret = ov7740_set_white_balance(ov7740, ctrl->val);
+		break;
+	case V4L2_CID_SATURATION:
+		ret = ov7740_set_saturation(regmap, ctrl->val);
+		break;
+	case V4L2_CID_BRIGHTNESS:
+		ret = ov7740_set_brightness(regmap, ctrl->val);
+		break;
+	case V4L2_CID_CONTRAST:
+		ret = ov7740_set_contrast(regmap, ctrl->val);
+		break;
+	case V4L2_CID_VFLIP:
+		ret = regmap_update_bits(regmap, REG_REG0C,
+					 REG0C_IMG_FLIP, val);
+		break;
+	case V4L2_CID_HFLIP:
+		val = ctrl->val ? REG0C_IMG_MIRROR : 0x00;
+		ret = regmap_update_bits(regmap, REG_REG0C,
+					 REG0C_IMG_MIRROR, val);
+		break;
+	case V4L2_CID_AUTOGAIN:
+		if (!ctrl->val)
+			return ov7740_set_gain(regmap, ov7740->gain->val);
+
+		ret = ov7740_set_autogain(regmap, ctrl->val);
+		break;
+
+	case V4L2_CID_EXPOSURE_AUTO:
+		if (ctrl->val == V4L2_EXPOSURE_MANUAL)
+			return ov7740_set_exp(regmap, ov7740->exposure->val);
+
+		ret = ov7740_set_autoexp(regmap, ctrl->val);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops ov7740_ctrl_ops = {
+	.g_volatile_ctrl = ov7740_get_volatile_ctrl,
+	.s_ctrl = ov7740_set_ctrl,
+};
+
+static int ov7740_start_streaming(struct ov7740 *ov7740)
+{
+	int ret;
+
+	if (ov7740->fmt) {
+		ret = regmap_multi_reg_write(ov7740->regmap,
+					     ov7740->fmt->regs,
+					     ov7740->fmt->reg_num);
+		if (ret)
+			return ret;
+	}
+
+	if (ov7740->frmsize) {
+		ret = regmap_multi_reg_write(ov7740->regmap,
+					     ov7740->frmsize->regs,
+					     ov7740->frmsize->reg_num);
+		if (ret)
+			return ret;
+	}
+
+	return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);
+}
+
+static int ov7740_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = 0;
+
+	mutex_lock(&ov7740->mutex);
+	if (ov7740->streaming == enable) {
+		mutex_unlock(&ov7740->mutex);
+		return 0;
+	}
+
+	if (enable) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto err_unlock;
+		}
+
+		ret = ov7740_start_streaming(ov7740);
+		if (ret)
+			goto err_rpm_put;
+	} else {
+		pm_runtime_put(&client->dev);
+	}
+
+	ov7740->streaming = enable;
+
+	mutex_unlock(&ov7740->mutex);
+	return ret;
+
+err_rpm_put:
+	pm_runtime_put(&client->dev);
+err_unlock:
+	mutex_unlock(&ov7740->mutex);
+	return ret;
+}
+
+static int ov7740_get_parm(struct v4l2_subdev *sd,
+			   struct v4l2_streamparm *parms)
+{
+	struct v4l2_captureparm *cp = &parms->parm.capture;
+	struct v4l2_fract *tpf = &cp->timeperframe;
+
+	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	memset(cp, 0, sizeof(struct v4l2_captureparm));
+	cp->capability = V4L2_CAP_TIMEPERFRAME;
+
+	tpf->numerator = 1;
+	tpf->denominator = 60;
+
+	return 0;
+}
+
+static int ov7740_set_parm(struct v4l2_subdev *sd,
+			   struct v4l2_streamparm *parms)
+{
+	struct v4l2_captureparm *cp = &parms->parm.capture;
+	struct v4l2_fract *tpf = &cp->timeperframe;
+
+	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (cp->extendedmode != 0)
+		return -EINVAL;
+
+	cp->capability = V4L2_CAP_TIMEPERFRAME;
+
+	tpf->numerator = 1;
+	tpf->denominator = 60;
+
+	return 0;
+}
+
+static struct v4l2_subdev_video_ops ov7740_subdev_video_ops = {
+	.s_stream = ov7740_set_stream,
+	.s_parm = ov7740_set_parm,
+	.g_parm = ov7740_get_parm,
+};
+
+static const struct reg_sequence ov7740_format_yuyv[] = {
+	{0x12, 0x00},
+	{0x36, 0x3f},
+	{0x80, 0x7f},
+	{0x83, 0x01},
+};
+
+static const struct reg_sequence ov7740_format_bggr8[] = {
+	{0x36, 0x2f},
+	{0x80, 0x01},
+	{0x83, 0x04},
+};
+
+static const struct ov7740_pixfmt ov7740_formats[] = {
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.regs = ov7740_format_yuyv,
+		.reg_num = ARRAY_SIZE(ov7740_format_yuyv),
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.regs = ov7740_format_bggr8,
+		.reg_num = ARRAY_SIZE(ov7740_format_bggr8),
+	}
+};
+#define N_OV7740_FMTS ARRAY_SIZE(ov7740_formats)
+
+static int ov7740_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->pad || code->index >= N_OV7740_FMTS)
+		return -EINVAL;
+
+	code->code = ov7740_formats[code->index].mbus_code;
+
+	return 0;
+}
+
+static int ov7740_enum_frame_interval(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->pad)
+		return -EINVAL;
+
+	if (fie->index >= 1)
+		return -EINVAL;
+
+	if ((fie->width != VGA_WIDTH) || (fie->height != VGA_HEIGHT))
+		return -EINVAL;
+
+	fie->interval.numerator = 1;
+	fie->interval.denominator = 60;
+
+	return 0;
+}
+
+static int ov7740_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->pad)
+		return -EINVAL;
+
+	if (fse->index > 0)
+		return -EINVAL;
+
+	fse->min_width = fse->max_width = VGA_WIDTH;
+	fse->min_height = fse->max_height = VGA_HEIGHT;
+
+	return 0;
+}
+
+static int ov7740_try_fmt_internal(struct v4l2_subdev *sd,
+				   struct v4l2_mbus_framefmt *fmt,
+				   const struct ov7740_pixfmt **ret_fmt,
+				   const struct ov7740_framesize **ret_frmsize)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	const struct ov7740_framesize *fsize = &ov7740_framesizes[0];
+	int index, i;
+
+	for (index = 0; index < N_OV7740_FMTS; index++) {
+		if (ov7740_formats[index].mbus_code == fmt->code)
+			break;
+	}
+	if (index >= N_OV7740_FMTS) {
+		/* default to first format */
+		index = 0;
+		fmt->code = ov7740_formats[0].mbus_code;
+	}
+	if (ret_fmt != NULL)
+		*ret_fmt = ov7740_formats + index;
+
+	for (i = 0; i < ARRAY_SIZE(ov7740_framesizes); i++) {
+		if ((fsize->width >= fmt->width) &&
+		    (fsize->height >= fmt->height)) {
+			fmt->width = fsize->width;
+			fmt->height = fsize->height;
+			break;
+		}
+
+		fsize++;
+	}
+
+	if (ret_frmsize != NULL)
+		*ret_frmsize = fsize;
+
+	fmt->field = V4L2_FIELD_NONE;
+	fmt->colorspace = ov7740_formats[index].colorspace;
+
+	ov7740->format = *fmt;
+
+	return 0;
+}
+
+static int ov7740_set_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *format)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	const struct ov7740_pixfmt *ovfmt;
+	const struct ov7740_framesize *fsize;
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
+	int ret;
+
+	mutex_lock(&ov7740->mutex);
+	if (format->pad) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+		ret = ov7740_try_fmt_internal(sd, &format->format, NULL, NULL);
+		if (ret)
+			goto error;
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
+		*mbus_fmt = format->format;
+
+		mutex_unlock(&ov7740->mutex);
+		return 0;
+#else
+		ret = -ENOTTY;
+		goto error;
+#endif
+	}
+
+	ret = ov7740_try_fmt_internal(sd, &format->format, &ovfmt, &fsize);
+	if (ret)
+		goto error;
+
+	ov7740->fmt = ovfmt;
+	ov7740->frmsize = fsize;
+
+	mutex_unlock(&ov7740->mutex);
+	return 0;
+
+error:
+	mutex_unlock(&ov7740->mutex);
+	return ret;
+}
+
+static int ov7740_get_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *format)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
+	int ret = 0;
+
+	mutex_lock(&ov7740->mutex);
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+		format->format = *mbus_fmt;
+		ret = 0;
+#else
+		ret = -ENOTTY;
+#endif
+	} else {
+		format->format = ov7740->format;
+	}
+	mutex_unlock(&ov7740->mutex);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_pad_ops ov7740_subdev_pad_ops = {
+	.enum_frame_interval = ov7740_enum_frame_interval,
+	.enum_frame_size = ov7740_enum_frame_size,
+	.enum_mbus_code = ov7740_enum_mbus_code,
+	.get_fmt = ov7740_get_fmt,
+	.set_fmt = ov7740_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov7740_subdev_ops = {
+	.core	= &ov7740_subdev_core_ops,
+	.video	= &ov7740_subdev_video_ops,
+	.pad	= &ov7740_subdev_pad_ops,
+};
+
+static void ov7740_get_default_format(struct v4l2_subdev *sd,
+				      struct v4l2_mbus_framefmt *format)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	format->width = ov7740->frmsize->width;
+	format->height = ov7740->frmsize->height;
+	format->colorspace = ov7740->fmt->colorspace;
+	format->code = ov7740->fmt->mbus_code;
+	format->field = V4L2_FIELD_NONE;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct v4l2_mbus_framefmt *format =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+
+	mutex_lock(&ov7740->mutex);
+	ov7740_get_default_format(sd, format);
+	mutex_unlock(&ov7740->mutex);
+
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops ov7740_subdev_internal_ops = {
+	.open = ov7740_open,
+};
+#endif
+
+static int ov7740_probe_dt(struct i2c_client *client,
+			   struct ov7740 *ov7740)
+{
+	ov7740->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+			GPIOD_OUT_HIGH);
+	if (IS_ERR(ov7740->resetb_gpio)) {
+		dev_info(&client->dev, "can't get %s GPIO\n", "reset");
+		return PTR_ERR(ov7740->resetb_gpio);
+	}
+
+	ov7740->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
+			GPIOD_OUT_LOW);
+	if (IS_ERR(ov7740->pwdn_gpio)) {
+		dev_info(&client->dev, "can't get %s GPIO\n", "powerdown");
+		return PTR_ERR(ov7740->pwdn_gpio);
+	}
+
+	return 0;
+}
+
+static int ov7740_detect(struct ov7740 *ov7740)
+{
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int midh, midl, pidh, pidl;
+	int ret;
+
+	ret = regmap_read(regmap, REG_MIDH, &midh);
+	if (ret)
+		return ret;
+	if (midh != 0x7f)
+		return -ENODEV;
+
+	ret = regmap_read(regmap, REG_MIDL, &midl);
+	if (ret)
+		return ret;
+	if (midl != 0xa2)
+		return -ENODEV;
+
+	ret = regmap_read(regmap, REG_PIDH, &pidh);
+	if (ret)
+		return ret;
+	if (pidh != 0x77)
+		return -ENODEV;
+
+	ret = regmap_read(regmap, REG_PIDL, &pidl);
+	if (ret)
+		return ret;
+	if ((pidl != 0x40) && (pidl != 0x41) && (pidl != 0x42))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int ov7740_init_controls(struct ov7740 *ov7740)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
+	struct v4l2_ctrl_handler *ctrl_hdlr = &ov7740->ctrl_handler;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 2);
+	if (ret < 0)
+		return ret;
+
+	ctrl_hdlr->lock = &ov7740->mutex;
+	ov7740->auto_wb = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					  V4L2_CID_AUTO_WHITE_BALANCE,
+					  0, 1, 1, 1);
+	ov7740->blue_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					       V4L2_CID_BLUE_BALANCE,
+					       0, 0xff, 1, 0x80);
+	ov7740->red_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					      V4L2_CID_RED_BALANCE,
+					      0, 0xff, 1, 0x80);
+
+	ov7740->brightness = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					     V4L2_CID_BRIGHTNESS,
+					     -255, 255, 1, 0);
+	ov7740->contrast = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					   V4L2_CID_CONTRAST,
+					   0, 127, 1, 0x20);
+	ov7740->saturation = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+			  V4L2_CID_SATURATION, 0, 256, 1, 0x80);
+	ov7740->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					V4L2_CID_HFLIP, 0, 1, 1, 0);
+	ov7740->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					V4L2_CID_VFLIP, 0, 1, 1, 0);
+	ov7740->gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+				       V4L2_CID_GAIN, 0, 1023, 1, 500);
+	ov7740->auto_gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					    V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+	ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					   V4L2_CID_EXPOSURE, 0, 65535, 1, 500);
+	ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr,
+					&ov7740_ctrl_ops,
+					V4L2_CID_EXPOSURE_AUTO,
+					V4L2_EXPOSURE_MANUAL, 0,
+					V4L2_EXPOSURE_AUTO);
+
+	ov7740->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ov7740->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false);
+	v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
+	v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
+			       V4L2_EXPOSURE_MANUAL, false);
+	v4l2_ctrl_cluster(2, &ov7740->hflip);
+
+	ret = v4l2_ctrl_handler_setup(ctrl_hdlr);
+	if (ret) {
+		dev_err(&client->dev, "%s control init failed (%d)\n",
+			__func__, ret);
+		goto error;
+	}
+
+	ov7740->subdev.ctrl_handler = ctrl_hdlr;
+	return 0;
+
+error:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+	mutex_destroy(&ov7740->mutex);
+	return ret;
+}
+
+static void ov7740_free_controls(struct ov7740 *ov7740)
+{
+	v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+	mutex_destroy(&ov7740->mutex);
+}
+
+#define OV7740_MAX_REGISTER     0xff
+static const struct regmap_config ov7740_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.max_register	= OV7740_MAX_REGISTER,
+};
+
+static int ov7740_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct ov7740 *ov7740;
+	struct v4l2_subdev *sd;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev,
+			"OV7740: I2C-Adapter doesn't support SMBUS\n");
+		return -EIO;
+	}
+
+	ov7740 = devm_kzalloc(&client->dev, sizeof(*ov7740), GFP_KERNEL);
+	if (!ov7740)
+		return -ENOMEM;
+
+	ov7740->xvclk = devm_clk_get(&client->dev, "xvclk");
+	if (IS_ERR(ov7740->xvclk)) {
+		ret = PTR_ERR(ov7740->xvclk);
+		dev_err(&client->dev,
+			"OV7740: fail to get xvclk: %d\n", ret);
+		return ret;
+	}
+
+	ret = ov7740_probe_dt(client, ov7740);
+	if (ret)
+		return ret;
+
+	ov7740->regmap = devm_regmap_init_i2c(client, &ov7740_regmap_config);
+	if (IS_ERR(ov7740->regmap)) {
+		ret = PTR_ERR(ov7740->regmap);
+		dev_err(&client->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	sd = &ov7740->subdev;
+	client->flags |= I2C_CLIENT_SCCB;
+	v4l2_i2c_subdev_init(sd, client, &ov7740_subdev_ops);
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &ov7740_subdev_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	ov7740->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &ov7740->pad);
+	if (ret)
+		return ret;
+#endif
+
+	ret = ov7740_set_power(ov7740, 1);
+	if (ret)
+		return ret;
+
+	ret = ov7740_detect(ov7740);
+	if (ret)
+		goto error_detect;
+
+	mutex_init(&ov7740->mutex);
+
+	ret = ov7740_init_controls(ov7740);
+	if (ret)
+		goto error_init_controls;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	ov7740->fmt = &ov7740_formats[0];
+	ov7740->frmsize = &ov7740_framesizes[0];
+
+	ov7740_get_default_format(sd, &ov7740->format);
+
+	ret = v4l2_async_register_subdev(sd);
+	if (ret)
+		goto error_async_register;
+
+	pm_runtime_set_active(&client->dev);
+	pm_runtime_enable(&client->dev);
+	pm_runtime_idle(&client->dev);
+
+	return 0;
+
+error_async_register:
+	v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+error_init_controls:
+	ov7740_free_controls(ov7740);
+error_detect:
+	ov7740_set_power(ov7740, 0);
+	media_entity_cleanup(&ov7740->subdev.entity);
+
+	return ret;
+}
+
+static int ov7740_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	mutex_destroy(&ov7740->mutex);
+	v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&ov7740->subdev.entity);
+#endif
+	v4l2_async_unregister_subdev(sd);
+	ov7740_free_controls(ov7740);
+
+	pm_runtime_get_sync(&client->dev);
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+
+	ov7740_set_power(ov7740, 0);
+	return 0;
+}
+
+static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	ov7740_set_power(ov7740, 0);
+
+	return 0;
+}
+
+static int __maybe_unused ov7740_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	return ov7740_set_power(ov7740, 1);
+}
+
+static const struct i2c_device_id ov7740_id[] = {
+	{ "ov7740", 0 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, ov7740_id);
+
+static const struct dev_pm_ops ov7740_pm_ops = {
+	SET_RUNTIME_PM_OPS(ov7740_runtime_suspend, ov7740_runtime_resume, NULL)
+};
+
+static const struct of_device_id ov7740_of_match[] = {
+	{.compatible = "ovti,ov7740", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ov7740_of_match);
+
+static struct i2c_driver ov7740_i2c_driver = {
+	.driver = {
+		.name = "ov7740",
+		.pm = &ov7740_pm_ops,
+		.of_match_table = of_match_ptr(ov7740_of_match),
+	},
+	.probe    = ov7740_probe,
+	.remove   = ov7740_remove,
+	.id_table = ov7740_id,
+};
+module_i2c_driver(ov7740_i2c_driver);
+
+MODULE_DESCRIPTION("The V4L2 driver for Omnivision 7740 sensor");
+MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver
       [not found] ` <20171211013146.2497-1-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
@ 2017-12-11  9:02   ` Philippe Ombredanne
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Ombredanne @ 2017-12-11  9:02 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: Mauro Carvalho Chehab, Rob Herring, Mark Rutland, LKML,
	Nicolas Ferre,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Sakari Ailus, Jonathan Corbet, Hans Verkuil,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Linux Media Mailing List

On Mon, Dec 11, 2017 at 2:31 AM, Wenyou Yang <wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org> wrote:
> Add a Video4Linux2 sensor-level driver for the OmniVision OV7740
> VGA camera image sensor.
>
> Changes in v9:
>  - Use the new SPDX ids.

Thank you for this

Acked-by: Philippe Ombredanne <pombredanne-od1rfyK75/E@public.gmane.org>

-- 
Cordially
Philippe Ombredanne
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
       [not found]   ` <20171211013146.2497-3-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
@ 2017-12-13 20:06     ` Sakari Ailus
  2017-12-19  2:11       ` Wenyou.Yang
  0 siblings, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2017-12-13 20:06 UTC (permalink / raw)
  To: Wenyou Yang, Mauro Carvalho Chehab, Rob Herring, Mark Rutland
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Nicolas Ferre,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Jonathan Corbet, Hans Verkuil,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linux Media Mailing List, Songjun Wu

Hi Wenyou,

Wenyou Yang wrote:
...
> +static int ov7740_start_streaming(struct ov7740 *ov7740)
> +{
> +	int ret;
> +
> +	if (ov7740->fmt) {
> +		ret = regmap_multi_reg_write(ov7740->regmap,
> +					     ov7740->fmt->regs,
> +					     ov7740->fmt->reg_num);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if (ov7740->frmsize) {
> +		ret = regmap_multi_reg_write(ov7740->regmap,
> +					     ov7740->frmsize->regs,
> +					     ov7740->frmsize->reg_num);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);

I believe you're still setting the controls after starting streaming.

-- 
Sakari Ailus
sakari.ailus-X3B1VOXEql0@public.gmane.org

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver
  2017-12-11  1:31 [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver Wenyou Yang
                   ` (2 preceding siblings ...)
       [not found] ` <20171211013146.2497-1-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
@ 2017-12-15 13:26 ` Wenyou.Yang
  3 siblings, 0 replies; 16+ messages in thread
From: Wenyou.Yang @ 2017-12-15 13:26 UTC (permalink / raw)
  To: Wenyou.Yang, mchehab, robh+dt, mark.rutland
  Cc: linux-kernel, Nicolas.Ferre, devicetree, sakari.ailus, corbet,
	hverkuil, linux-arm-kernel, linux-media

Hi Sakari,

Do you have some comments on this version?


Best Regards,
Wenyou Yang

> -----Original Message-----
> From: linux-media-owner@vger.kernel.org [mailto:linux-media-
> owner@vger.kernel.org] On Behalf Of Wenyou Yang
> Sent: 2017年12月11日 9:32
> To: Mauro Carvalho Chehab <mchehab@s-opensource.com>; Rob Herring
> <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>
> Cc: linux-kernel@vger.kernel.org; Nicolas Ferre - M43238
> <Nicolas.Ferre@microchip.com>; devicetree@vger.kernel.org; Sakari Ailus
> <sakari.ailus@iki.fi>; Jonathan Corbet <corbet@lwn.net>; Hans Verkuil
> <hverkuil@xs4all.nl>; linux-arm-kernel@lists.infradead.org; Linux Media Mailing List
> <linux-media@vger.kernel.org>; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>
> Subject: [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver
> 
> Add a Video4Linux2 sensor-level driver for the OmniVision OV7740 VGA camera
> image sensor.
> 
> Changes in v9:
>  - Use the new SPDX ids.
> 
> Changes in v8:
>  - As the registers are written at stream start, remove the written
>    code from the set fmt function.
> 
> Changes in v7:
>  - Add Acked-by tag.
>  - Fix the wrong handle of default register configuration.
>  - Add the missed assignment of ov7740->frmsize.
> 
> Changes in v6:
>  - Remove unnecessary #include <linux/init>.
>  - Remove unnecessary comments and extra newline.
>  - Add const for some structures.
>  - Add the check of the return value from regmap_write().
>  - Simplify the calling of __v4l2_ctrl_handler_setup().
>  - Add the default format initialization function.
>  - Integrate the set_power() and enable/disable the clock into
>    one function.
> 
> Changes in v5:
>  - Squash the driver and MAINTAINERS entry patches to one.
>  - Precede the driver patch with the bindings patch.
> 
> Changes in v4:
>  - Assign 'val' a initial value to avoid warning: 'val' may be
>    used uninitialized.
>  - Rename REG_REG15 to avoid warning: "REG_REG15" redefined.
> 
> Changes in v3:
>  - Explicitly document the "remote-endpoint" property.
>  - Put the MAINTAINERS change to a separate patch.
> 
> Changes in v2:
>  - Split off the bindings into a separate patch.
>  - Add a new entry to the MAINTAINERS file.
> 
> Wenyou Yang (2):
>   media: ov7740: Document device tree bindings
>   media: i2c: Add the ov7740 image sensor driver
> 
>  .../devicetree/bindings/media/i2c/ov7740.txt       |   47 +
>  MAINTAINERS                                        |    8 +
>  drivers/media/i2c/Kconfig                          |    8 +
>  drivers/media/i2c/Makefile                         |    1 +
>  drivers/media/i2c/ov7740.c                         | 1216 ++++++++++++++++++++
>  5 files changed, 1280 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/i2c/ov7740.txt
>  create mode 100644 drivers/media/i2c/ov7740.c
> 
> --
> 2.15.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
  2017-12-13 20:06     ` Sakari Ailus
@ 2017-12-19  2:11       ` Wenyou.Yang
       [not found]         ` <F9F4555C4E01D7469D37975B62D0EFBB8DDA56-8fD0d2gESGoGk1ErWP88zX2Vsf1/G1/XQQ4Iyu8u01E@public.gmane.org>
  0 siblings, 1 reply; 16+ messages in thread
From: Wenyou.Yang @ 2017-12-19  2:11 UTC (permalink / raw)
  To: sakari.ailus, mchehab, robh+dt, mark.rutland
  Cc: linux-kernel, Nicolas.Ferre, devicetree, corbet, hverkuil,
	linux-arm-kernel, linux-media

[-- Attachment #1: Type: text/plain, Size: 1641 bytes --]

Hi Sakari,

> -----Original Message-----
> From: Sakari Ailus [mailto:sakari.ailus@iki.fi]
> Sent: 2017年12月14日 4:06
> To: Wenyou Yang - A41535 <Wenyou.Yang@microchip.com>; Mauro Carvalho
> Chehab <mchehab@s-opensource.com>; Rob Herring <robh+dt@kernel.org>;
> Mark Rutland <mark.rutland@arm.com>
> Cc: linux-kernel@vger.kernel.org; Nicolas Ferre - M43238
> <Nicolas.Ferre@microchip.com>; devicetree@vger.kernel.org; Jonathan Corbet
> <corbet@lwn.net>; Hans Verkuil <hverkuil@xs4all.nl>; linux-arm-
> kernel@lists.infradead.org; Linux Media Mailing List <linux-
> media@vger.kernel.org>; Songjun Wu <songjun.wu@microchip.com>
> Subject: Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
> 
> Hi Wenyou,
> 
> Wenyou Yang wrote:
> ...
> > +static int ov7740_start_streaming(struct ov7740 *ov7740) {
> > +	int ret;
> > +
> > +	if (ov7740->fmt) {
> > +		ret = regmap_multi_reg_write(ov7740->regmap,
> > +					     ov7740->fmt->regs,
> > +					     ov7740->fmt->reg_num);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	if (ov7740->frmsize) {
> > +		ret = regmap_multi_reg_write(ov7740->regmap,
> > +					     ov7740->frmsize->regs,
> > +					     ov7740->frmsize->reg_num);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);
> 
> I believe you're still setting the controls after starting streaming.

Yes, it sees it does so.

The OV7740 sensor generates the stream pixel data at the constant frame rate, no such start or stop control. 

> 
> --
> Sakari Ailus
> sakari.ailus@iki.fi

Wenyou Yang

[-- Attachment #2: imx7d-sdb.dtb --]
[-- Type: application/octet-stream, Size: 46918 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
       [not found]         ` <F9F4555C4E01D7469D37975B62D0EFBB8DDA56-8fD0d2gESGoGk1ErWP88zX2Vsf1/G1/XQQ4Iyu8u01E@public.gmane.org>
@ 2017-12-19  9:11           ` Sakari Ailus
  0 siblings, 0 replies; 16+ messages in thread
From: Sakari Ailus @ 2017-12-19  9:11 UTC (permalink / raw)
  To: Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA
  Cc: mchehab-JsYNTwtnfakRB7SZvlqPiA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Nicolas.Ferre-UWL1GkI3JZL3oGB3hsPCZA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, corbet-T1hC0tSOHrs,
	hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-media-u79uwXL29TY76Z2rM5mHXA

Hi Wenyou,

On Tue, Dec 19, 2017 at 02:11:28AM +0000, Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org wrote:
> Hi Sakari,
> 
> > -----Original Message-----
> > From: Sakari Ailus [mailto:sakari.ailus-X3B1VOXEql0@public.gmane.org]
> > Sent: 2017年12月14日 4:06
> > To: Wenyou Yang - A41535 <Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>; Mauro Carvalho
> > Chehab <mchehab-JsYNTwtnfakRB7SZvlqPiA@public.gmane.org>; Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>;
> > Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
> > Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Nicolas Ferre - M43238
> > <Nicolas.Ferre-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>; devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Jonathan Corbet
> > <corbet-T1hC0tSOHrs@public.gmane.org>; Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>; linux-arm-
> > kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org; Linux Media Mailing List <linux-
> > media-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>; Songjun Wu <songjun.wu-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
> > Subject: Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
> > 
> > Hi Wenyou,
> > 
> > Wenyou Yang wrote:
> > ...
> > > +static int ov7740_start_streaming(struct ov7740 *ov7740) {
> > > +	int ret;
> > > +
> > > +	if (ov7740->fmt) {
> > > +		ret = regmap_multi_reg_write(ov7740->regmap,
> > > +					     ov7740->fmt->regs,
> > > +					     ov7740->fmt->reg_num);
> > > +		if (ret)
> > > +			return ret;
> > > +	}
> > > +
> > > +	if (ov7740->frmsize) {
> > > +		ret = regmap_multi_reg_write(ov7740->regmap,
> > > +					     ov7740->frmsize->regs,
> > > +					     ov7740->frmsize->reg_num);
> > > +		if (ret)
> > > +			return ret;
> > > +	}
> > > +
> > > +	return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);
> > 
> > I believe you're still setting the controls after starting streaming.
> 
> Yes, it sees it does so.
> 
> The OV7740 sensor generates the stream pixel data at the constant frame
> rate, no such start or stop control.

That'd be odd but I guess hardware sometimes is. I'll apply the patches.

Thanks!

-- 
Sakari Ailus
e-mail: sakari.ailus-X3B1VOXEql0@public.gmane.org
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
  2017-12-11  1:31 ` [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver Wenyou Yang
       [not found]   ` <20171211013146.2497-3-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
@ 2017-12-19  9:22   ` Sakari Ailus
       [not found]     ` <20171219092246.3usg5mdyi27ivqlq-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
  1 sibling, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2017-12-19  9:22 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: Mauro Carvalho Chehab, Rob Herring, Mark Rutland, linux-kernel,
	Nicolas Ferre, devicetree, Jonathan Corbet, Hans Verkuil,
	linux-arm-kernel, Linux Media Mailing List, Songjun Wu

On Mon, Dec 11, 2017 at 09:31:46AM +0800, Wenyou Yang wrote:
> The ov7740 (color) image sensor is a high performance VGA CMOS
> image snesor, which supports for output formats: RAW RGB and YUV
> and image sizes: VGA, and QVGA, CIF and any size smaller.
> 
> Signed-off-by: Songjun Wu <songjun.wu@microchip.com>
> Signed-off-by: Wenyou Yang <wenyou.yang@microchip.com>

Applied with this diff:

diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 0308ba437bbb..041a77039d70 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -1,5 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2017 Microchip Corporation.
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2017 Microchip Corporation.
+ */
 
 #include <linux/clk.h>
 #include <linux/delay.h>

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* RE: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
       [not found]     ` <20171219092246.3usg5mdyi27ivqlq-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
@ 2017-12-19 11:54       ` Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA
  2017-12-19 12:50       ` Fabio Estevam
  1 sibling, 0 replies; 16+ messages in thread
From: Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA @ 2017-12-19 11:54 UTC (permalink / raw)
  To: sakari.ailus-X3B1VOXEql0
  Cc: mchehab-JsYNTwtnfakRB7SZvlqPiA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Nicolas.Ferre-UWL1GkI3JZL3oGB3hsPCZA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, corbet-T1hC0tSOHrs,
	hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-media-u79uwXL29TY76Z2rM5mHXA

Hi Sakari,

> -----Original Message-----
> From: Sakari Ailus [mailto:sakari.ailus@iki.fi]
> Sent: 2017年12月19日 17:23
> To: Wenyou Yang - A41535 <Wenyou.Yang@microchip.com>
> Cc: Mauro Carvalho Chehab <mchehab@s-opensource.com>; Rob Herring
> <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>; linux-
> kernel@vger.kernel.org; Nicolas Ferre - M43238 <Nicolas.Ferre@microchip.com>;
> devicetree@vger.kernel.org; Jonathan Corbet <corbet@lwn.net>; Hans Verkuil
> <hverkuil@xs4all.nl>; linux-arm-kernel@lists.infradead.org; Linux Media Mailing List
> <linux-media@vger.kernel.org>; Songjun Wu <songjun.wu@microchip.com>
> Subject: Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
> 
> On Mon, Dec 11, 2017 at 09:31:46AM +0800, Wenyou Yang wrote:
> > The ov7740 (color) image sensor is a high performance VGA CMOS image
> > snesor, which supports for output formats: RAW RGB and YUV and image
> > sizes: VGA, and QVGA, CIF and any size smaller.
> >
> > Signed-off-by: Songjun Wu <songjun.wu@microchip.com>
> > Signed-off-by: Wenyou Yang <wenyou.yang@microchip.com>
> 
> Applied with this diff:

Thank you very much.

> 
> diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index
> 0308ba437bbb..041a77039d70 100644
> --- a/drivers/media/i2c/ov7740.c
> +++ b/drivers/media/i2c/ov7740.c
> @@ -1,5 +1,7 @@
> -// SPDX-License-Identifier: GPL-2.0
> -// Copyright (c) 2017 Microchip Corporation.
> +/*
> + * SPDX-License-Identifier: GPL-2.0
> + * Copyright (c) 2017 Microchip Corporation.
> + */
> 
>  #include <linux/clk.h>
>  #include <linux/delay.h>
> 
> --
> Sakari Ailus
> e-mail: sakari.ailus@iki.fi


Best Regards,
Wenyou Yang

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
       [not found]     ` <20171219092246.3usg5mdyi27ivqlq-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
  2017-12-19 11:54       ` Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA
@ 2017-12-19 12:50       ` Fabio Estevam
  2017-12-19 13:05         ` Sakari Ailus
  1 sibling, 1 reply; 16+ messages in thread
From: Fabio Estevam @ 2017-12-19 12:50 UTC (permalink / raw)
  To: Sakari Ailus, Philippe Ombredanne
  Cc: Wenyou Yang, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Jonathan Corbet, linux-kernel, Mauro Carvalho Chehab,
	Rob Herring, Hans Verkuil, Songjun Wu,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linux Media Mailing List

Hi Sakari,

On Tue, Dec 19, 2017 at 7:22 AM, Sakari Ailus <sakari.ailus-X3B1VOXEql0@public.gmane.org> wrote:
> On Mon, Dec 11, 2017 at 09:31:46AM +0800, Wenyou Yang wrote:
>> The ov7740 (color) image sensor is a high performance VGA CMOS
>> image snesor, which supports for output formats: RAW RGB and YUV
>> and image sizes: VGA, and QVGA, CIF and any size smaller.
>>
>> Signed-off-by: Songjun Wu <songjun.wu-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
>> Signed-off-by: Wenyou Yang <wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
>
> Applied with this diff:
>
> diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
> index 0308ba437bbb..041a77039d70 100644
> --- a/drivers/media/i2c/ov7740.c
> +++ b/drivers/media/i2c/ov7740.c
> @@ -1,5 +1,7 @@
> -// SPDX-License-Identifier: GPL-2.0
> -// Copyright (c) 2017 Microchip Corporation.
> +/*
> + * SPDX-License-Identifier: GPL-2.0
> + * Copyright (c) 2017 Microchip Corporation.
> + */

The original version is the recommended format for the SPDX identifier.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
  2017-12-19 12:50       ` Fabio Estevam
@ 2017-12-19 13:05         ` Sakari Ailus
       [not found]           ` <20171219130537.2viv4wjcp4i3mdkj-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
  0 siblings, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2017-12-19 13:05 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Philippe Ombredanne, Wenyou Yang, Mark Rutland, devicetree,
	Jonathan Corbet, linux-kernel, Mauro Carvalho Chehab,
	Rob Herring, Hans Verkuil, Songjun Wu, linux-arm-kernel,
	Linux Media Mailing List

On Tue, Dec 19, 2017 at 10:50:44AM -0200, Fabio Estevam wrote:
> Hi Sakari,
> 
> On Tue, Dec 19, 2017 at 7:22 AM, Sakari Ailus <sakari.ailus@iki.fi> wrote:
> > On Mon, Dec 11, 2017 at 09:31:46AM +0800, Wenyou Yang wrote:
> >> The ov7740 (color) image sensor is a high performance VGA CMOS
> >> image snesor, which supports for output formats: RAW RGB and YUV
> >> and image sizes: VGA, and QVGA, CIF and any size smaller.
> >>
> >> Signed-off-by: Songjun Wu <songjun.wu@microchip.com>
> >> Signed-off-by: Wenyou Yang <wenyou.yang@microchip.com>
> >
> > Applied with this diff:
> >
> > diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
> > index 0308ba437bbb..041a77039d70 100644
> > --- a/drivers/media/i2c/ov7740.c
> > +++ b/drivers/media/i2c/ov7740.c
> > @@ -1,5 +1,7 @@
> > -// SPDX-License-Identifier: GPL-2.0
> > -// Copyright (c) 2017 Microchip Corporation.
> > +/*
> > + * SPDX-License-Identifier: GPL-2.0
> > + * Copyright (c) 2017 Microchip Corporation.
> > + */
> 
> The original version is the recommended format for the SPDX identifier.

I guess it depends on who do you ask and when. Looking at what has been
recently merged to media tree master, the latter is preferred.

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
       [not found]           ` <20171219130537.2viv4wjcp4i3mdkj-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
@ 2017-12-19 13:19             ` Fabio Estevam
  2017-12-19 13:43               ` Sakari Ailus
  0 siblings, 1 reply; 16+ messages in thread
From: Fabio Estevam @ 2017-12-19 13:19 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Philippe Ombredanne, Wenyou Yang, Mark Rutland,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Jonathan Corbet, linux-kernel,
	Mauro Carvalho Chehab, Rob Herring, Hans Verkuil, Songjun Wu,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Linux Media Mailing List

Hi Sakari,

On Tue, Dec 19, 2017 at 11:05 AM, Sakari Ailus <sakari.ailus-X3B1VOXEql0@public.gmane.org> wrote:

> I guess it depends on who do you ask and when. Looking at what has been
> recently merged to media tree master, the latter is preferred.

Just did 'git grep SPDX drivers/media'

and it consistently shows // SPDX style for C files.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
  2017-12-19 13:19             ` Fabio Estevam
@ 2017-12-19 13:43               ` Sakari Ailus
  2017-12-19 14:31                 ` Fabio Estevam
  0 siblings, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2017-12-19 13:43 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Mark Rutland, devicetree, Wenyou Yang, Jonathan Corbet,
	linux-kernel, Songjun Wu, Mauro Carvalho Chehab, Rob Herring,
	Hans Verkuil, Philippe Ombredanne, linux-arm-kernel,
	Linux Media Mailing List

On Tue, Dec 19, 2017 at 11:19:06AM -0200, Fabio Estevam wrote:
> Hi Sakari,
> 
> On Tue, Dec 19, 2017 at 11:05 AM, Sakari Ailus <sakari.ailus@iki.fi> wrote:
> 
> > I guess it depends on who do you ask and when. Looking at what has been
> > recently merged to media tree master, the latter is preferred.
> 
> Just did 'git grep SPDX drivers/media'
> 
> and it consistently shows // SPDX style for C files.

Both seem to exist. See e.g. c3a3d1d6b8b363a02234e5564692db3647f183e6 .

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
  2017-12-19 13:43               ` Sakari Ailus
@ 2017-12-19 14:31                 ` Fabio Estevam
  2017-12-19 16:04                   ` Sakari Ailus
  0 siblings, 1 reply; 16+ messages in thread
From: Fabio Estevam @ 2017-12-19 14:31 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Philippe Ombredanne, Wenyou Yang, Mark Rutland, devicetree,
	Jonathan Corbet, linux-kernel, Mauro Carvalho Chehab,
	Rob Herring, Hans Verkuil, Songjun Wu, linux-arm-kernel,
	Linux Media Mailing List

On Tue, Dec 19, 2017 at 11:43 AM, Sakari Ailus <sakari.ailus@iki.fi> wrote:

> Both seem to exist. See e.g. c3a3d1d6b8b363a02234e5564692db3647f183e6 .

This patch fixes .h files to use /* SPDX style comment, which is the
recommendation.

.c files should use // SPDX style.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver
  2017-12-19 14:31                 ` Fabio Estevam
@ 2017-12-19 16:04                   ` Sakari Ailus
  0 siblings, 0 replies; 16+ messages in thread
From: Sakari Ailus @ 2017-12-19 16:04 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Philippe Ombredanne, Wenyou Yang, Mark Rutland, devicetree,
	Jonathan Corbet, linux-kernel, Mauro Carvalho Chehab,
	Rob Herring, Hans Verkuil, Songjun Wu, linux-arm-kernel,
	Linux Media Mailing List

On Tue, Dec 19, 2017 at 12:31:46PM -0200, Fabio Estevam wrote:
> On Tue, Dec 19, 2017 at 11:43 AM, Sakari Ailus <sakari.ailus@iki.fi> wrote:
> 
> > Both seem to exist. See e.g. c3a3d1d6b8b363a02234e5564692db3647f183e6 .
> 
> This patch fixes .h files to use /* SPDX style comment, which is the
> recommendation.
> 
> .c files should use // SPDX style.

Agreed. I reverted the changes.

Thanks.

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-12-19 16:04 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-11  1:31 [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver Wenyou Yang
2017-12-11  1:31 ` [PATCH v9 1/2] media: ov7740: Document device tree bindings Wenyou Yang
2017-12-11  1:31 ` [PATCH v9 2/2] media: i2c: Add the ov7740 image sensor driver Wenyou Yang
     [not found]   ` <20171211013146.2497-3-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
2017-12-13 20:06     ` Sakari Ailus
2017-12-19  2:11       ` Wenyou.Yang
     [not found]         ` <F9F4555C4E01D7469D37975B62D0EFBB8DDA56-8fD0d2gESGoGk1ErWP88zX2Vsf1/G1/XQQ4Iyu8u01E@public.gmane.org>
2017-12-19  9:11           ` Sakari Ailus
2017-12-19  9:22   ` Sakari Ailus
     [not found]     ` <20171219092246.3usg5mdyi27ivqlq-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
2017-12-19 11:54       ` Wenyou.Yang-UWL1GkI3JZL3oGB3hsPCZA
2017-12-19 12:50       ` Fabio Estevam
2017-12-19 13:05         ` Sakari Ailus
     [not found]           ` <20171219130537.2viv4wjcp4i3mdkj-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
2017-12-19 13:19             ` Fabio Estevam
2017-12-19 13:43               ` Sakari Ailus
2017-12-19 14:31                 ` Fabio Estevam
2017-12-19 16:04                   ` Sakari Ailus
     [not found] ` <20171211013146.2497-1-wenyou.yang-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org>
2017-12-11  9:02   ` [PATCH v9 0/2] media: ov7740: Add a V4L2 sensor-level driver Philippe Ombredanne
2017-12-15 13:26 ` Wenyou.Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).