From patchwork Tue Jun 23 10:07:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4145 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9B2B2609A3 for ; Tue, 23 Jun 2020 12:05:12 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id A8BE4C000A; Tue, 23 Jun 2020 10:05:08 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:51 +0200 Message-Id: <20200623100815.10674-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 01/25] dt-bindings: media: ov5647: Document pwdn-gpios X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:12 -0000 Document in dt-schema bindings for the ov5647 sensor the optional 'pwdn-gpios' property. Signed-off-by: Jacopo Mondi --- Documentation/devicetree/bindings/media/i2c/ov5647.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml index 067e222e0c7c3..58d64a69e9640 100644 --- a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml @@ -25,6 +25,10 @@ properties: description: Reference to the xclk clock maxItems: 1 + pwdn-gpios: + description: Reference to the GPIO connected to the pwdn pin. Active high. + maxItems: 1 + port: type: object description: |- @@ -61,6 +65,7 @@ additionalProperties: false examples: - | + #include i2c { #address-cells = <1>; @@ -70,6 +75,7 @@ examples: compatible = "ovti,ov5647"; reg = <0x36>; clocks = <&camera_clk>; + pwdn-gpios = <&pioE 29 GPIO_ACTIVE_HIGH>; port { camera_out: endpoint { From patchwork Tue Jun 23 10:07:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4146 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D947F609A3 for ; Tue, 23 Jun 2020 12:05:15 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id BF2B5C0011; Tue, 23 Jun 2020 10:05:12 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:52 +0200 Message-Id: <20200623100815.10674-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 02/25] dt-bindings: media: ov5647: Document clock-noncontinuous X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:16 -0000 Document the optional clock-noncontinuous endpoint property that allows enabling MIPI CSI-2 non-continuous clock operations. Signed-off-by: Jacopo Mondi --- Documentation/devicetree/bindings/media/i2c/ov5647.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml index 58d64a69e9640..68d6998d7180c 100644 --- a/Documentation/devicetree/bindings/media/i2c/ov5647.yaml +++ b/Documentation/devicetree/bindings/media/i2c/ov5647.yaml @@ -45,6 +45,11 @@ properties: description: |- phandle to the video receiver input port + clock-noncontinuous: + type: boolean + description: |- + Set to true to allow MIPI CSI-2 non-continuous clock operations + required: - remote-endpoint From patchwork Tue Jun 23 10:07:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4147 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 63212609A3 for ; Tue, 23 Jun 2020 12:05:19 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 04339C0016; Tue, 23 Jun 2020 10:05:15 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:53 +0200 Message-Id: <20200623100815.10674-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 03/25] media: ov5647: Add support for PWDN GPIO. X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:19 -0000 From: Dave Stevenson Add support for an optional GPIO connected to PWDN on the sensor. This allows the use of hardware standby mode where internal device clock and circuit activities are halted. Please note that power is off when PWDN is high. Signed-off-by: Dave Stevenson Signed-off-by: Roman Kovalivskyi Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index e7d2e5b4ad4b9..105ff7f899b34 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,13 @@ #define SENSOR_NAME "ov5647" +/* + * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes + * high if reset is inserted after PWDN goes high, host can access sensor's + * SCCB to initialize sensor." + */ +#define PWDN_ACTIVE_DELAY_MS 20 + #define MIPI_CTRL00_CLOCK_LANE_GATE BIT(5) #define MIPI_CTRL00_BUS_IDLE BIT(2) #define MIPI_CTRL00_CLOCK_LANE_DISABLE BIT(0) @@ -86,6 +94,7 @@ struct ov5647 { unsigned int height; int power_count; struct clk *xclk; + struct gpio_desc *pwdn; }; static inline struct ov5647 *to_state(struct v4l2_subdev *sd) @@ -355,6 +364,11 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) if (on && !ov5647->power_count) { dev_dbg(&client->dev, "OV5647 power on\n"); + if (ov5647->pwdn) { + gpiod_set_value_cansleep(ov5647->pwdn, 0); + msleep(PWDN_ACTIVE_DELAY_MS); + } + ret = clk_prepare_enable(ov5647->xclk); if (ret < 0) { dev_err(&client->dev, "clk prepare enable failed\n"); @@ -392,6 +406,8 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) dev_dbg(&client->dev, "soft stby failed\n"); clk_disable_unprepare(ov5647->xclk); + + gpiod_set_value_cansleep(ov5647->pwdn, 1); } /* Update the power count. */ @@ -581,6 +597,10 @@ static int ov5647_probe(struct i2c_client *client) return -EINVAL; } + /* Request the power down GPIO asserted */ + sensor->pwdn = devm_gpiod_get_optional(&client->dev, "pwdn", + GPIOD_OUT_HIGH); + mutex_init(&sensor->lock); sd = &sensor->sd; @@ -594,7 +614,15 @@ static int ov5647_probe(struct i2c_client *client) if (ret < 0) goto mutex_remove; + if (sensor->pwdn) { + gpiod_set_value_cansleep(sensor->pwdn, 0); + msleep(PWDN_ACTIVE_DELAY_MS); + } + ret = ov5647_detect(sd); + + gpiod_set_value_cansleep(sensor->pwdn, 1); + if (ret < 0) goto error; From patchwork Tue Jun 23 10:07:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4148 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A9720609A3 for ; Tue, 23 Jun 2020 12:05:22 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 83D24C0006; Tue, 23 Jun 2020 10:05:19 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:54 +0200 Message-Id: <20200623100815.10674-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 04/25] media: ov5647: Add support for non-continuous clock mode X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:22 -0000 From: Dave Stevenson Add support for optional non-continuous clock mode to the ov5647 sensor driver. Non-continuous clock saves a small amount of power and on some SoCs is easier to interface with. Signed-off-by: Dave Stevenson Signed-off-by: Roman Kovalivskyi Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 105ff7f899b34..2d69cd97142d7 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -44,6 +44,7 @@ #define PWDN_ACTIVE_DELAY_MS 20 #define MIPI_CTRL00_CLOCK_LANE_GATE BIT(5) +#define MIPI_CTRL00_LINE_SYNC_ENABLE BIT(4) #define MIPI_CTRL00_BUS_IDLE BIT(2) #define MIPI_CTRL00_CLOCK_LANE_DISABLE BIT(0) @@ -95,6 +96,7 @@ struct ov5647 { int power_count; struct clk *xclk; struct gpio_desc *pwdn; + bool clock_ncont; }; static inline struct ov5647 *to_state(struct v4l2_subdev *sd) @@ -269,9 +271,15 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel) static int ov5647_stream_on(struct v4l2_subdev *sd) { + struct ov5647 *ov5647 = to_state(sd); + u8 val = MIPI_CTRL00_BUS_IDLE; int ret; - ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_BUS_IDLE); + if (ov5647->clock_ncont) + val |= MIPI_CTRL00_CLOCK_LANE_GATE | + MIPI_CTRL00_LINE_SYNC_ENABLE; + + ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, val); if (ret < 0) return ret; @@ -546,9 +554,11 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = { .open = ov5647_open, }; -static int ov5647_parse_dt(struct device_node *np) +static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np) { - struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; + struct v4l2_fwnode_endpoint bus_cfg = { + .bus_type = V4L2_MBUS_CSI2_DPHY, + }; struct device_node *ep; int ret; @@ -558,7 +568,13 @@ static int ov5647_parse_dt(struct device_node *np) return -EINVAL; ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg); + if (ret) + goto out; + sensor->clock_ncont = bus_cfg.bus.mipi_csi2.flags & + V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK; + +out: of_node_put(ep); return ret; } @@ -577,7 +593,7 @@ static int ov5647_probe(struct i2c_client *client) return -ENOMEM; if (IS_ENABLED(CONFIG_OF) && np) { - ret = ov5647_parse_dt(np); + ret = ov5647_parse_dt(sensor, np); if (ret) { dev_err(dev, "DT parsing error: %d\n", ret); return ret; From patchwork Tue Jun 23 10:07:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4149 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DFBC8609A3 for ; Tue, 23 Jun 2020 12:05:25 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id D09B6C000E; Tue, 23 Jun 2020 10:05:22 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:55 +0200 Message-Id: <20200623100815.10674-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/25] media: ov5647: Add set_fmt and get_fmt calls. X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:26 -0000 From: Dave Stevenson There's no way to query the subdevice for the supported resolutions. Add set_fmt and get_fmt implementations. Since there's only one format supported set_fmt does nothing and get returns single format. Signed-off-by: Dave Stevenson Signed-off-by: Roman Kovalivskyi Reviewed-by: Jacopo Mondi Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 2d69cd97142d7..43fecf0ca58f3 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -487,8 +487,27 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, return 0; } +static int ov5647_set_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *fmt = &format->format; + + /* Only one format is supported, so return that */ + memset(fmt, 0, sizeof(*fmt)); + fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + fmt->field = V4L2_FIELD_NONE; + fmt->width = 640; + fmt->height = 480; + + return 0; +} + static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = { .enum_mbus_code = ov5647_enum_mbus_code, + .set_fmt = ov5647_set_get_fmt, + .get_fmt = ov5647_set_get_fmt, }; static const struct v4l2_subdev_ops ov5647_subdev_ops = { From patchwork Tue Jun 23 10:07:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4150 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 30632609A3 for ; Tue, 23 Jun 2020 12:05:29 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 08245C0006; Tue, 23 Jun 2020 10:05:25 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:56 +0200 Message-Id: <20200623100815.10674-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/25] media: ov5647: Fix format initialization X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:29 -0000 The driver currently support a single format. Fix its initialization to use the only supported resolution. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 43fecf0ca58f3..c92856d3aa81c 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -560,9 +560,8 @@ static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) crop->height = OV5647_WINDOW_HEIGHT_DEF; format->code = MEDIA_BUS_FMT_SBGGR8_1X8; - - format->width = OV5647_WINDOW_WIDTH_DEF; - format->height = OV5647_WINDOW_HEIGHT_DEF; + format->width = 640; + format->height = 480; format->field = V4L2_FIELD_NONE; format->colorspace = V4L2_COLORSPACE_SRGB; From patchwork Tue Jun 23 10:07:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4151 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7E9C8609A3 for ; Tue, 23 Jun 2020 12:05:32 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 4E675C0003; Tue, 23 Jun 2020 10:05:29 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:57 +0200 Message-Id: <20200623100815.10674-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/25] media: ov5647: Fix style issues X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:32 -0000 The driver has some obvious style issues which are worth fixing before expanding the driver capabilities. Fix: - Variable declaration order - Function parameters alignment - Multi-line comments and spurious line breaks - Use lowercase for hexadecimal values Cosmetic change, no functional changes intended. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 101 +++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index c92856d3aa81c..e9679382623f9 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -34,8 +34,6 @@ #include #include -#define SENSOR_NAME "ov5647" - /* * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes * high if reset is inserted after PWDN goes high, host can access sensor's @@ -50,9 +48,9 @@ #define OV5647_SW_STANDBY 0x0100 #define OV5647_SW_RESET 0x0103 -#define OV5647_REG_CHIPID_H 0x300A -#define OV5647_REG_CHIPID_L 0x300B -#define OV5640_REG_PAD_OUT 0x300D +#define OV5647_REG_CHIPID_H 0x300a +#define OV5647_REG_CHIPID_L 0x300b +#define OV5640_REG_PAD_OUT 0x300d #define OV5647_REG_FRAME_OFF_NUMBER 0x4202 #define OV5647_REG_MIPI_CTRL00 0x4800 #define OV5647_REG_MIPI_CTRL14 0x4814 @@ -158,7 +156,7 @@ static struct regval_list ov5647_640x480[] = { {0x3808, 0x02}, {0x3809, 0x80}, {0x380a, 0x01}, - {0x380b, 0xE0}, + {0x380b, 0xe0}, {0x3801, 0x00}, {0x3802, 0x00}, {0x3803, 0x00}, @@ -209,9 +207,9 @@ static struct regval_list ov5647_640x480[] = { static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val) { - int ret; unsigned char data[3] = { reg >> 8, reg & 0xff, val}; struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; ret = i2c_master_send(client, data, 3); if (ret < 0) @@ -223,9 +221,9 @@ static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val) static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val) { - int ret; unsigned char data_w[2] = { reg >> 8, reg & 0xff }; struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; ret = i2c_master_send(client, data_w, 2); if (ret < 0) { @@ -243,7 +241,7 @@ static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val) } static int ov5647_write_array(struct v4l2_subdev *sd, - struct regval_list *regs, int array_size) + struct regval_list *regs, int array_size) { int i, ret; @@ -266,6 +264,7 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel) return ret; channel_id &= ~(3 << 6); + return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, channel_id | (channel << 6)); } @@ -294,8 +293,8 @@ static int ov5647_stream_off(struct v4l2_subdev *sd) { int ret; - ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_CLOCK_LANE_GATE - | MIPI_CTRL00_BUS_IDLE | MIPI_CTRL00_CLOCK_LANE_DISABLE); + ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_CLOCK_LANE_GATE | + MIPI_CTRL00_BUS_IDLE | MIPI_CTRL00_CLOCK_LANE_DISABLE); if (ret < 0) return ret; @@ -325,16 +324,16 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby) static int __sensor_init(struct v4l2_subdev *sd) { - int ret; - u8 resetval, rdval; struct i2c_client *client = v4l2_get_subdevdata(sd); + u8 resetval, rdval; + int ret; ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval); if (ret < 0) return ret; ret = ov5647_write_array(sd, ov5647_640x480, - ARRAY_SIZE(ov5647_640x480)); + ARRAY_SIZE(ov5647_640x480)); if (ret < 0) { dev_err(&client->dev, "write sensor default regs error\n"); return ret; @@ -355,17 +354,15 @@ static int __sensor_init(struct v4l2_subdev *sd) return ret; } - /* - * stream off to make the clock lane into LP-11 state. - */ + /* Stream off to make the clock lane into LP-11 state. */ return ov5647_stream_off(sd); } static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) { - int ret = 0; - struct ov5647 *ov5647 = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov5647 *ov5647 = to_state(sd); + int ret = 0; mutex_lock(&ov5647->lock); @@ -384,7 +381,7 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) } ret = ov5647_write_array(sd, sensor_oe_enable_regs, - ARRAY_SIZE(sensor_oe_enable_regs)); + ARRAY_SIZE(sensor_oe_enable_regs)); if (ret < 0) { clk_disable_unprepare(ov5647->xclk); dev_err(&client->dev, @@ -403,18 +400,15 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) dev_dbg(&client->dev, "OV5647 power off\n"); ret = ov5647_write_array(sd, sensor_oe_disable_regs, - ARRAY_SIZE(sensor_oe_disable_regs)); - + ARRAY_SIZE(sensor_oe_disable_regs)); if (ret < 0) dev_dbg(&client->dev, "disable oe failed\n"); ret = set_sw_standby(sd, true); - if (ret < 0) dev_dbg(&client->dev, "soft stby failed\n"); clk_disable_unprepare(ov5647->xclk); - gpiod_set_value_cansleep(ov5647->pwdn, 1); } @@ -430,10 +424,10 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov5647_sensor_get_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + struct v4l2_dbg_register *reg) { - u8 val; int ret; + u8 val; ret = ov5647_read(sd, reg->reg & 0xff, &val); if (ret < 0) @@ -446,15 +440,13 @@ static int ov5647_sensor_get_register(struct v4l2_subdev *sd, } static int ov5647_sensor_set_register(struct v4l2_subdev *sd, - const struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { return ov5647_write(sd, reg->reg & 0xff, reg->val & 0xff); } #endif -/* - * Subdev core operations registration - */ +/* Subdev core operations registration */ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = { .s_power = ov5647_sensor_power, #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -476,8 +468,8 @@ static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = { }; static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) return -EINVAL; @@ -493,7 +485,7 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd, { struct v4l2_mbus_framefmt *fmt = &format->format; - /* Only one format is supported, so return that */ + /* Only one format is supported, so return that. */ memset(fmt, 0, sizeof(*fmt)); fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8; fmt->colorspace = V4L2_COLORSPACE_SRGB; @@ -518,9 +510,9 @@ static const struct v4l2_subdev_ops ov5647_subdev_ops = { static int ov5647_detect(struct v4l2_subdev *sd) { + struct i2c_client *client = v4l2_get_subdevdata(sd); u8 read; int ret; - struct i2c_client *client = v4l2_get_subdevdata(sd); ret = ov5647_write(sd, OV5647_SW_RESET, 0x01); if (ret < 0) @@ -549,10 +541,8 @@ static int ov5647_detect(struct v4l2_subdev *sd) static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct v4l2_mbus_framefmt *format = - v4l2_subdev_get_try_format(sd, fh->pad, 0); - struct v4l2_rect *crop = - v4l2_subdev_get_try_crop(sd, fh->pad, 0); + struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); + struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0); crop->left = OV5647_COLUMN_START_DEF; crop->top = OV5647_ROW_START_DEF; @@ -578,7 +568,6 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np) .bus_type = V4L2_MBUS_CSI2_DPHY, }; struct device_node *ep; - int ret; ep = of_graph_get_next_endpoint(np, NULL); @@ -594,17 +583,18 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np) out: of_node_put(ep); + return ret; } static int ov5647_probe(struct i2c_client *client) { + struct device_node *np = client->dev.of_node; struct device *dev = &client->dev; struct ov5647 *sensor; - int ret; struct v4l2_subdev *sd; - struct device_node *np = client->dev.of_node; u32 xclk_freq; + int ret; sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); if (!sensor) @@ -618,7 +608,6 @@ static int ov5647_probe(struct i2c_client *client) } } - /* get system clock (xclk) */ sensor->xclk = devm_clk_get(dev, NULL); if (IS_ERR(sensor->xclk)) { dev_err(dev, "could not get xclk"); @@ -631,22 +620,21 @@ static int ov5647_probe(struct i2c_client *client) return -EINVAL; } - /* Request the power down GPIO asserted */ - sensor->pwdn = devm_gpiod_get_optional(&client->dev, "pwdn", - GPIOD_OUT_HIGH); + /* Request the power down GPIO asserted. */ + sensor->pwdn = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_HIGH); mutex_init(&sensor->lock); sd = &sensor->sd; v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops); - sensor->sd.internal_ops = &ov5647_subdev_internal_ops; - sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->internal_ops = &ov5647_subdev_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad); if (ret < 0) - goto mutex_remove; + goto mutex_destroy; if (sensor->pwdn) { gpiod_set_value_cansleep(sensor->pwdn, 0); @@ -654,22 +642,23 @@ static int ov5647_probe(struct i2c_client *client) } ret = ov5647_detect(sd); - gpiod_set_value_cansleep(sensor->pwdn, 1); - if (ret < 0) - goto error; + goto entity_cleanup; ret = v4l2_async_register_subdev(sd); if (ret < 0) - goto error; + goto entity_cleanup; dev_dbg(dev, "OmniVision OV5647 camera driver probed\n"); + return 0; -error: + +entity_cleanup: media_entity_cleanup(&sd->entity); -mutex_remove: +mutex_destroy: mutex_destroy(&sensor->lock); + return ret; } @@ -688,7 +677,7 @@ static int ov5647_remove(struct i2c_client *client) static const struct i2c_device_id ov5647_id[] = { { "ov5647", 0 }, - { } + { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, ov5647_id); @@ -703,7 +692,7 @@ MODULE_DEVICE_TABLE(of, ov5647_of_match); static struct i2c_driver ov5647_driver = { .driver = { .of_match_table = of_match_ptr(ov5647_of_match), - .name = SENSOR_NAME, + .name = "ov5647", }, .probe_new = ov5647_probe, .remove = ov5647_remove, From patchwork Tue Jun 23 10:07:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4152 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C2CE9609A3 for ; Tue, 23 Jun 2020 12:05:35 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 9E61EC000A; Tue, 23 Jun 2020 10:05:32 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:58 +0200 Message-Id: <20200623100815.10674-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/25] media: ov5647: Replace license with SPDX identifier X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:35 -0000 Replace the boilerplate license text with the SPDX identifier. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index e9679382623f9..61aa86e507b32 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * A V4L2 driver for OmniVision OV5647 cameras. * @@ -8,15 +9,6 @@ * Copyright (C) 2006-7 Jonathan Corbet * * Copyright (C) 2016, Synopsys, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed .as is. WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include From patchwork Tue Jun 23 10:07:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4153 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F02D5609A3 for ; Tue, 23 Jun 2020 12:05:38 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id E04AAC000F; Tue, 23 Jun 2020 10:05:35 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:07:59 +0200 Message-Id: <20200623100815.10674-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/25] media: ov5647: Fix return value from read/write X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:39 -0000 The ov5647_read()/ov5647_write() return in case of success the number of bytes read or written respectively. This requires callers to check if the return value is less than zero to detect an error. Unfortunately, in several places, callers directly return the result of a read/write call, causing issues when the returned valued is checked to be different from zero to detect an error. Fix this by returning zero if i2c_master_send() and i2c_master_read() return a positive value (the number of bytes written or read). Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 61aa86e507b32..0c88f682de9b9 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -204,11 +204,13 @@ static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val) int ret; ret = i2c_master_send(client, data, 3); - if (ret < 0) + if (ret < 0) { dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n", __func__, reg); + return ret; + } - return ret; + return 0; } static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val) @@ -225,11 +227,13 @@ static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val) } ret = i2c_master_recv(client, val, 1); - if (ret < 0) + if (ret < 0) { dev_dbg(&client->dev, "%s: i2c read error, reg: %x\n", __func__, reg); + return ret; + } - return ret; + return 0; } static int ov5647_write_array(struct v4l2_subdev *sd, From patchwork Tue Jun 23 10:08:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4154 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BAA5A609A3 for ; Tue, 23 Jun 2020 12:05:53 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id AA02D100008; Tue, 23 Jun 2020 10:05:47 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: Jacopo Mondi , mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org Date: Tue, 23 Jun 2020 12:08:00 +0200 Message-Id: <20200623100815.10674-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/25] media: ov5647: Program mode at s_stream(1) time X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 10:05:53 -0000 Rename __sensor_init() function to ov5647_set_mode() as the function is a regular one and the double underscores prefix shall be removed, and then move it to program the mode at s_stream(1) time, not at sensor power up. Break out from __sensor_init() the stream_off() operation call at sensor power up to coax the lanes in LP-11 state. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 81 +++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 0c88f682de9b9..bb9ff77f49fe0 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -264,12 +264,54 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel) return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, channel_id | (channel << 6)); } +static int ov5647_set_mode(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + u8 resetval, rdval; + int ret; + + ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval); + if (ret < 0) + return ret; + + ret = ov5647_write_array(sd, ov5647_640x480, + ARRAY_SIZE(ov5647_640x480)); + if (ret < 0) { + dev_err(&client->dev, "write sensor default regs error\n"); + return ret; + } + + ret = ov5647_set_virtual_channel(sd, 0); + if (ret < 0) + return ret; + + ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval); + if (ret < 0) + return ret; + + if (!(resetval & 0x01)) { + dev_err(&client->dev, "Device was in SW standby"); + ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01); + if (ret < 0) + return ret; + } + + return 0; +} + static int ov5647_stream_on(struct v4l2_subdev *sd) { + struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5647 *ov5647 = to_state(sd); u8 val = MIPI_CTRL00_BUS_IDLE; int ret; + ret = ov5647_set_mode(sd); + if (ret) { + dev_err(&client->dev, "Failed to program sensor mode: %d\n", ret); + return ret; + } + if (ov5647->clock_ncont) val |= MIPI_CTRL00_CLOCK_LANE_GATE | MIPI_CTRL00_LINE_SYNC_ENABLE; @@ -318,42 +360,6 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby) return ov5647_write(sd, OV5647_SW_STANDBY, rdval); } -static int __sensor_init(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u8 resetval, rdval; - int ret; - - ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval); - if (ret < 0) - return ret; - - ret = ov5647_write_array(sd, ov5647_640x480, - ARRAY_SIZE(ov5647_640x480)); - if (ret < 0) { - dev_err(&client->dev, "write sensor default regs error\n"); - return ret; - } - - ret = ov5647_set_virtual_channel(sd, 0); - if (ret < 0) - return ret; - - ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval); - if (ret < 0) - return ret; - - if (!(resetval & 0x01)) { - dev_err(&client->dev, "Device was in SW standby"); - ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01); - if (ret < 0) - return ret; - } - - /* Stream off to make the clock lane into LP-11 state. */ - return ov5647_stream_off(sd); -} - static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -385,7 +391,8 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) goto out; } - ret = __sensor_init(sd); + /* Stream off to coax lanes into LP-11 state. */ + ret = ov5647_stream_off(sd); if (ret < 0) { clk_disable_unprepare(ov5647->xclk); dev_err(&client->dev, From patchwork Tue Jun 23 16:42:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4158 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7727B60103 for ; Tue, 23 Jun 2020 18:39:11 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id CEA776000A; Tue, 23 Jun 2020 16:39:03 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:42:20 +0200 Message-Id: <20200623164224.44476-1-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 11/25] media: ov5647: Implement enum_frame_size() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:39:11 -0000 Implement the .enum_frame_size subdev pad operation. As the driver only supports one format and one resolution at the moment the implementation is trivial. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index bb9ff77f49fe0..859cc5b0d14a3 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -482,6 +482,24 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, return 0; } +static int ov5647_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index) + return -EINVAL; + + if (fse->code != MEDIA_BUS_FMT_SBGGR8_1X8) + return -EINVAL; + + fse->min_width = 640; + fse->max_width = 640; + fse->min_height = 480; + fse->max_height = 480; + + return 0; +} + static int ov5647_set_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *format) @@ -500,9 +518,10 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd, } static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = { - .enum_mbus_code = ov5647_enum_mbus_code, - .set_fmt = ov5647_set_get_fmt, - .get_fmt = ov5647_set_get_fmt, + .enum_mbus_code = ov5647_enum_mbus_code, + .enum_frame_size = ov5647_enum_frame_size, + .set_fmt = ov5647_set_get_fmt, + .get_fmt = ov5647_set_get_fmt, }; static const struct v4l2_subdev_ops ov5647_subdev_ops = { From patchwork Tue Jun 23 16:42:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4159 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BDA3160103 for ; Tue, 23 Jun 2020 18:39:14 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 7FB556000E; Tue, 23 Jun 2020 16:39:11 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:42:21 +0200 Message-Id: <20200623164224.44476-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 12/25] media: ov5647: Protect s_stream() with mutex X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:39:14 -0000 Use the driver mutex to protect s_stream() operations. This will become more relevant once the sensor will support more formats and set_format() could be issue concurrently to s_stream(). Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 859cc5b0d14a3..2d2829f934c3c 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -460,10 +460,17 @@ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = { static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) { + struct ov5647 *sensor = to_state(sd); + int ret; + + mutex_lock(&sensor->lock); if (enable) - return ov5647_stream_on(sd); + ret = ov5647_stream_on(sd); else - return ov5647_stream_off(sd); + ret = ov5647_stream_off(sd); + mutex_unlock(&sensor->lock); + + return ret; } static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = { From patchwork Tue Jun 23 16:42:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4160 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4A903609A5 for ; Tue, 23 Jun 2020 18:39:18 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id D938460009; Tue, 23 Jun 2020 16:39:14 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, David Plowman , Jacopo Mondi Date: Tue, 23 Jun 2020 18:42:22 +0200 Message-Id: <20200623164224.44476-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 13/25] media: ov5647: Support gain, exposure and AWB controls X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:39:18 -0000 From: David Plowman Add controls to support AWB, AEC and AGC. Also add control support to set exposure (in lines) and analogue gain (as a register code). Signed-off-by: David Plowman Signed-off-by: Naushir Patuck Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 170 ++++++++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 2d2829f934c3c..8cfe315cfd00b 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -43,9 +44,16 @@ #define OV5647_REG_CHIPID_H 0x300a #define OV5647_REG_CHIPID_L 0x300b #define OV5640_REG_PAD_OUT 0x300d +#define OV5647_REG_EXP_HI 0x3500 +#define OV5647_REG_EXP_MID 0x3501 +#define OV5647_REG_EXP_LO 0x3502 +#define OV5647_REG_AEC_AGC 0x3503 +#define OV5647_REG_GAIN_HI 0x350a +#define OV5647_REG_GAIN_LO 0x350b #define OV5647_REG_FRAME_OFF_NUMBER 0x4202 #define OV5647_REG_MIPI_CTRL00 0x4800 #define OV5647_REG_MIPI_CTRL14 0x4814 +#define OV5647_REG_AWB 0x5001 #define REG_TERM 0xfffe #define VAL_TERM 0xfe @@ -87,6 +95,7 @@ struct ov5647 { struct clk *xclk; struct gpio_desc *pwdn; bool clock_ncont; + struct v4l2_ctrl_handler ctrls; }; static inline struct ov5647 *to_state(struct v4l2_subdev *sd) @@ -121,7 +130,6 @@ static struct regval_list ov5647_640x480[] = { {0x3612, 0x59}, {0x3618, 0x00}, {0x5000, 0x06}, - {0x5001, 0x01}, {0x5002, 0x41}, {0x5003, 0x08}, {0x5a00, 0x08}, @@ -312,6 +320,11 @@ static int ov5647_stream_on(struct v4l2_subdev *sd) return ret; } + /* Apply customized values from user when stream starts. */ + ret = __v4l2_ctrl_handler_setup(sd->ctrl_handler); + if (ret) + return ret; + if (ov5647->clock_ncont) val |= MIPI_CTRL00_CLOCK_LANE_GATE | MIPI_CTRL00_LINE_SYNC_ENABLE; @@ -591,6 +604,152 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = { .open = ov5647_open, }; +static int ov5647_s_auto_white_balance(struct v4l2_subdev *sd, u32 val) +{ + return ov5647_write(sd, OV5647_REG_AWB, val ? 1 : 0); +} + +static int ov5647_s_autogain(struct v4l2_subdev *sd, u32 val) +{ + int ret; + u8 reg; + + /* Non-zero turns on AGC by clearing bit 1.*/ + ret = ov5647_read(sd, OV5647_REG_AEC_AGC, ®); + if (ret) + return ret; + + return ov5647_write(sd, OV5647_REG_AEC_AGC, val ? reg & ~BIT(1) + : reg | BIT(1)); +} + +static int ov5647_s_exposure_auto(struct v4l2_subdev *sd, u32 val) +{ + int ret; + u8 reg; + + /* + * Everything except V4L2_EXPOSURE_MANUAL turns on AEC by + * clearing bit 0. + */ + ret = ov5647_read(sd, OV5647_REG_AEC_AGC, ®); + if (ret) + return ret; + + return ov5647_write(sd, OV5647_REG_AEC_AGC, val == V4L2_EXPOSURE_MANUAL ? + reg | BIT(0) : reg & ~BIT(0)); +} + +static int ov5647_s_analogue_gain(struct v4l2_subdev *sd, u32 val) +{ + int ret; + + /* 10 bits of gain, 2 in the high register. */ + ret = ov5647_write(sd, OV5647_REG_GAIN_HI, (val >> 8) & 3); + if (ret) + return ret; + + return ov5647_write(sd, OV5647_REG_GAIN_LO, val & 0xff); +} + +static int ov5647_s_exposure(struct v4l2_subdev *sd, u32 val) +{ + int ret; + + /* + * Sensor has 20 bits, but the bottom 4 bits are fractions of a line + * which we leave as zero (and don't receive in "val"). + */ + ret = ov5647_write(sd, OV5647_REG_EXP_HI, (val >> 12) & 0xf); + if (ret) + return ret; + + ret = ov5647_write(sd, OV5647_REG_EXP_MID, (val >> 4) & 0xff); + if (ret) + return ret; + + return ov5647_write(sd, OV5647_REG_EXP_LO, (val & 0xf) << 4); +} + +static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct ov5647 *sensor = container_of(ctrl->handler, + struct ov5647, ctrls); + struct v4l2_subdev *sd = &sensor->sd; + struct i2c_client *client = v4l2_get_subdevdata(sd); + + /* v4l2_ctrl_lock() locks our own mutex */ + + /* + * If the device is not powered up by the host driver do + * not apply any controls to H/W at this time. Instead + * the controls will be restored at s_stream(1) time. + */ + if (!sensor->power_count) + return 0; + + switch (ctrl->id) { + case V4L2_CID_AUTO_WHITE_BALANCE: + return ov5647_s_auto_white_balance(sd, ctrl->val); + case V4L2_CID_AUTOGAIN: + return ov5647_s_autogain(sd, ctrl->val); + case V4L2_CID_EXPOSURE_AUTO: + return ov5647_s_exposure_auto(sd, ctrl->val); + case V4L2_CID_ANALOGUE_GAIN: + return ov5647_s_analogue_gain(sd, ctrl->val); + case V4L2_CID_EXPOSURE: + return ov5647_s_exposure(sd, ctrl->val); + default: + dev_info(&client->dev, + "Control (id:0x%x, val:0x%x) not supported\n", + ctrl->id, ctrl->val); + return -EINVAL; + } + + return 0; +} + +static const struct v4l2_ctrl_ops ov5647_ctrl_ops = { + .s_ctrl = ov5647_s_ctrl, +}; + +static int ov5647_init_controls(struct ov5647 *sensor) +{ + struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); + + v4l2_ctrl_handler_init(&sensor->ctrls, 5); + + v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 0); + + v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 0); + + v4l2_ctrl_new_std_menu(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, + 0, V4L2_EXPOSURE_MANUAL); + + /* min: 4 lines; max: 0xffff lines; default: 1000 lines. */ + v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_EXPOSURE, 4, 65535, 1, 1000); + + /* min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. */ + v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 32); + + if (sensor->ctrls.error) { + dev_err(&client->dev, "%s Controls initialization failed (%d)\n", + __func__, sensor->ctrls.error); + v4l2_ctrl_handler_free(&sensor->ctrls); + + return sensor->ctrls.error; + } + + sensor->sd.ctrl_handler = &sensor->ctrls; + + return 0; +} + static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np) { struct v4l2_fwnode_endpoint bus_cfg = { @@ -654,6 +813,10 @@ static int ov5647_probe(struct i2c_client *client) mutex_init(&sensor->lock); + ret = ov5647_init_controls(sensor); + if (ret) + goto mutex_destroy; + sd = &sensor->sd; v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops); sd->internal_ops = &ov5647_subdev_internal_ops; @@ -663,7 +826,7 @@ static int ov5647_probe(struct i2c_client *client) sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad); if (ret < 0) - goto mutex_destroy; + goto ctrl_handler_free; if (sensor->pwdn) { gpiod_set_value_cansleep(sensor->pwdn, 0); @@ -685,6 +848,8 @@ static int ov5647_probe(struct i2c_client *client) entity_cleanup: media_entity_cleanup(&sd->entity); +ctrl_handler_free: + v4l2_ctrl_handler_free(&sensor->ctrls); mutex_destroy: mutex_destroy(&sensor->lock); @@ -698,6 +863,7 @@ static int ov5647_remove(struct i2c_client *client) v4l2_async_unregister_subdev(&ov5647->sd); media_entity_cleanup(&ov5647->sd.entity); + v4l2_ctrl_handler_free(&ov5647->ctrls); v4l2_device_unregister_subdev(sd); mutex_destroy(&ov5647->lock); From patchwork Tue Jun 23 16:42:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4161 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 18706609A5 for ; Tue, 23 Jun 2020 18:39:22 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 727E460010; Tue, 23 Jun 2020 16:39:18 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:42:23 +0200 Message-Id: <20200623164224.44476-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 14/25] media: ov5647: Rationalize driver structure name X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:39:22 -0000 The driver structure name is referred to with different names ('ov5647', 'state', 'sensor') in different functions in the driver. Polish this up by using 'struct ov5647 *sensor' everywhere. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 8cfe315cfd00b..03f4f1a257ecd 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -98,7 +98,7 @@ struct ov5647 { struct v4l2_ctrl_handler ctrls; }; -static inline struct ov5647 *to_state(struct v4l2_subdev *sd) +static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) { return container_of(sd, struct ov5647, sd); } @@ -310,7 +310,7 @@ static int ov5647_set_mode(struct v4l2_subdev *sd) static int ov5647_stream_on(struct v4l2_subdev *sd) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov5647 *ov5647 = to_state(sd); + struct ov5647 *sensor = to_sensor(sd); u8 val = MIPI_CTRL00_BUS_IDLE; int ret; @@ -325,7 +325,7 @@ static int ov5647_stream_on(struct v4l2_subdev *sd) if (ret) return ret; - if (ov5647->clock_ncont) + if (sensor->clock_ncont) val |= MIPI_CTRL00_CLOCK_LANE_GATE | MIPI_CTRL00_LINE_SYNC_ENABLE; @@ -379,17 +379,17 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) struct ov5647 *ov5647 = to_state(sd); int ret = 0; - mutex_lock(&ov5647->lock); + mutex_lock(&sensor->lock); - if (on && !ov5647->power_count) { + if (on && !sensor->power_count) { dev_dbg(&client->dev, "OV5647 power on\n"); - if (ov5647->pwdn) { - gpiod_set_value_cansleep(ov5647->pwdn, 0); + if (sensor->pwdn) { + gpiod_set_value_cansleep(sensor->pwdn, 0); msleep(PWDN_ACTIVE_DELAY_MS); } - ret = clk_prepare_enable(ov5647->xclk); + ret = clk_prepare_enable(sensor->xclk); if (ret < 0) { dev_err(&client->dev, "clk prepare enable failed\n"); goto out; @@ -398,7 +398,7 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) ret = ov5647_write_array(sd, sensor_oe_enable_regs, ARRAY_SIZE(sensor_oe_enable_regs)); if (ret < 0) { - clk_disable_unprepare(ov5647->xclk); + clk_disable_unprepare(sensor->xclk); dev_err(&client->dev, "write sensor_oe_enable_regs error\n"); goto out; @@ -407,12 +407,12 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) /* Stream off to coax lanes into LP-11 state. */ ret = ov5647_stream_off(sd); if (ret < 0) { - clk_disable_unprepare(ov5647->xclk); + clk_disable_unprepare(sensor->xclk); dev_err(&client->dev, "Camera not available, check Power\n"); goto out; } - } else if (!on && ov5647->power_count == 1) { + } else if (!on && sensor->power_count == 1) { dev_dbg(&client->dev, "OV5647 power off\n"); ret = ov5647_write_array(sd, sensor_oe_disable_regs, @@ -424,16 +424,16 @@ static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) if (ret < 0) dev_dbg(&client->dev, "soft stby failed\n"); - clk_disable_unprepare(ov5647->xclk); - gpiod_set_value_cansleep(ov5647->pwdn, 1); + clk_disable_unprepare(sensor->xclk); + gpiod_set_value_cansleep(sensor->pwdn, 1); } /* Update the power count. */ - ov5647->power_count += on ? 1 : -1; - WARN_ON(ov5647->power_count < 0); + sensor->power_count += on ? 1 : -1; + WARN_ON(sensor->power_count < 0); out: - mutex_unlock(&ov5647->lock); + mutex_unlock(&sensor->lock); return ret; } @@ -473,7 +473,7 @@ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = { static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) { - struct ov5647 *sensor = to_state(sd); + struct ov5647 *sensor = to_sensor(sd); int ret; mutex_lock(&sensor->lock); @@ -859,13 +859,13 @@ static int ov5647_probe(struct i2c_client *client) static int ov5647_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov5647 *ov5647 = to_state(sd); + struct ov5647 *sensor = to_sensor(sd); - v4l2_async_unregister_subdev(&ov5647->sd); - media_entity_cleanup(&ov5647->sd.entity); - v4l2_ctrl_handler_free(&ov5647->ctrls); + v4l2_async_unregister_subdev(&sensor->sd); + media_entity_cleanup(&sensor->sd.entity); + v4l2_ctrl_handler_free(&sensor->ctrls); v4l2_device_unregister_subdev(sd); - mutex_destroy(&ov5647->lock); + mutex_destroy(&sensor->lock); return 0; } From patchwork Tue Jun 23 16:42:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4162 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B577360103 for ; Tue, 23 Jun 2020 18:39:25 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 327ED60006; Tue, 23 Jun 2020 16:39:22 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:42:24 +0200 Message-Id: <20200623164224.44476-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 15/25] media: ov5647: Break out format handling X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:39:25 -0000 Break format handling out from the main driver structure. This commit prepares for the introduction of more sensor formats and resolutions by instrumenting the existing operation to work on multiple modes instead of assuming a single one supported. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 84 +++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 03f4f1a257ecd..a801ed0249aad 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -84,18 +84,28 @@ struct regval_list { u8 data; }; +struct ov5647_mode { + struct v4l2_mbus_framefmt format; + struct regval_list *reg_list; + unsigned int num_regs; +}; + +struct ov5647_format_list { + unsigned int mbus_code; + struct ov5647_mode *modes; + unsigned int num_modes; +}; + struct ov5647 { struct v4l2_subdev sd; struct media_pad pad; struct mutex lock; - struct v4l2_mbus_framefmt format; - unsigned int width; - unsigned int height; int power_count; struct clk *xclk; struct gpio_desc *pwdn; bool clock_ncont; struct v4l2_ctrl_handler ctrls; + struct ov5647_mode *mode; }; static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) @@ -205,6 +215,33 @@ static struct regval_list ov5647_640x480[] = { {0x0100, 0x01}, }; +static struct ov5647_mode ov5647_8bit_modes[] = { + { + .format = { + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + .width = 640, + .height = 480 + }, + .reg_list = ov5647_640x480, + .num_regs = ARRAY_SIZE(ov5647_640x480) + }, +}; + +static const struct ov5647_format_list ov5647_formats[] = { + { + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + .modes = ov5647_8bit_modes, + .num_modes = ARRAY_SIZE(ov5647_8bit_modes), + }, +}; + +#define OV5647_NUM_FORMATS (ARRAY_SIZE(ov5647_formats)) + +#define OV5647_DEFAULT_MODE (&ov5647_formats[0].modes[0]) +#define OV5647_DEFAULT_FORMAT (ov5647_formats[0].modes[0].format) + static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val) { unsigned char data[3] = { reg >> 8, reg & 0xff, val}; @@ -282,8 +319,7 @@ static int ov5647_set_mode(struct v4l2_subdev *sd) if (ret < 0) return ret; - ret = ov5647_write_array(sd, ov5647_640x480, - ARRAY_SIZE(ov5647_640x480)); + ret = ov5647_write_array(sd, sensor->mode->reg_list, sensor->mode->num_regs); if (ret < 0) { dev_err(&client->dev, "write sensor default regs error\n"); return ret; @@ -494,10 +530,10 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { - if (code->index > 0) + if (code->index >= OV5647_NUM_FORMATS) return -EINVAL; - code->code = MEDIA_BUS_FMT_SBGGR8_1X8; + code->code = ov5647_formats[code->index].mbus_code; return 0; } @@ -506,16 +542,24 @@ static int ov5647_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index) + const struct v4l2_mbus_framefmt *fmt; + unsigned int i = 0; + + for (; i < OV5647_NUM_FORMATS; ++i) { + if (ov5647_formats[i].mbus_code == fse->code) + break; + } + if (i == OV5647_NUM_FORMATS) return -EINVAL; - if (fse->code != MEDIA_BUS_FMT_SBGGR8_1X8) + if (fse->index >= ov5647_formats[i].num_modes) return -EINVAL; - fse->min_width = 640; - fse->max_width = 640; - fse->min_height = 480; - fse->max_height = 480; + fmt = &ov5647_formats[i].modes[fse->index].format; + fse->min_width = fmt->width; + fse->max_width = fmt->width; + fse->min_height = fmt->height; + fse->max_height = fmt->height; return 0; } @@ -528,11 +572,7 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd, /* Only one format is supported, so return that. */ memset(fmt, 0, sizeof(*fmt)); - fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8; - fmt->colorspace = V4L2_COLORSPACE_SRGB; - fmt->field = V4L2_FIELD_NONE; - fmt->width = 640; - fmt->height = 480; + *fmt = OV5647_DEFAULT_FORMAT; return 0; } @@ -591,11 +631,7 @@ static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) crop->width = OV5647_WINDOW_WIDTH_DEF; crop->height = OV5647_WINDOW_HEIGHT_DEF; - format->code = MEDIA_BUS_FMT_SBGGR8_1X8; - format->width = 640; - format->height = 480; - format->field = V4L2_FIELD_NONE; - format->colorspace = V4L2_COLORSPACE_SRGB; + *format = OV5647_DEFAULT_FORMAT; return 0; } @@ -813,6 +849,8 @@ static int ov5647_probe(struct i2c_client *client) mutex_init(&sensor->lock); + sensor->mode = OV5647_DEFAULT_MODE; + ret = ov5647_init_controls(sensor); if (ret) goto mutex_destroy; From patchwork Tue Jun 23 16:49:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4163 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 082B260103 for ; Tue, 23 Jun 2020 18:46:14 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 030E0100006; Tue, 23 Jun 2020 16:46:07 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Dave Stevenson , Jacopo Mondi Date: Tue, 23 Jun 2020 18:49:08 +0200 Message-Id: <20200623164911.45147-1-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 16/25] media: ov5647: Add support for get_selection() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:46:14 -0000 From: Dave Stevenson Support the get_selection() pad operation to report the device full pixel array size, the currently applied analogue crop rectangle and the active pixel array dimensions. Signed-off-by: Dave Stevenson Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 95 ++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 24 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index a801ed0249aad..3757f0b10fe93 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -59,25 +59,14 @@ #define VAL_TERM 0xfe #define REG_DLY 0xffff -#define OV5647_ROW_START 0x01 -#define OV5647_ROW_START_MIN 0 -#define OV5647_ROW_START_MAX 2004 -#define OV5647_ROW_START_DEF 54 - -#define OV5647_COLUMN_START 0x02 -#define OV5647_COLUMN_START_MIN 0 -#define OV5647_COLUMN_START_MAX 2750 -#define OV5647_COLUMN_START_DEF 16 - -#define OV5647_WINDOW_HEIGHT 0x03 -#define OV5647_WINDOW_HEIGHT_MIN 2 -#define OV5647_WINDOW_HEIGHT_MAX 2006 -#define OV5647_WINDOW_HEIGHT_DEF 1944 - -#define OV5647_WINDOW_WIDTH 0x04 -#define OV5647_WINDOW_WIDTH_MIN 2 -#define OV5647_WINDOW_WIDTH_MAX 2752 -#define OV5647_WINDOW_WIDTH_DEF 2592 +/* OV5647 native and active pixel array size */ +#define OV5647_NATIVE_WIDTH 2624U +#define OV5647_NATIVE_HEIGHT 1956U + +#define OV5647_PIXEL_ARRAY_LEFT 16U +#define OV5647_PIXEL_ARRAY_TOP 16U +#define OV5647_PIXEL_ARRAY_WIDTH 2592U +#define OV5647_PIXEL_ARRAY_HEIGHT 1944U struct regval_list { u16 addr; @@ -86,6 +75,7 @@ struct regval_list { struct ov5647_mode { struct v4l2_mbus_framefmt format; + struct v4l2_rect crop; struct regval_list *reg_list; unsigned int num_regs; }; @@ -224,6 +214,12 @@ static struct ov5647_mode ov5647_8bit_modes[] = { .width = 640, .height = 480 }, + .crop = { + .left = 0, + .top = 0, + .width = 1280, + .height = 960, + }, .reg_list = ov5647_640x480, .num_regs = ARRAY_SIZE(ov5647_640x480) }, @@ -412,7 +408,7 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby) static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov5647 *ov5647 = to_state(sd); + struct ov5647 *sensor = to_sensor(sd); int ret = 0; mutex_lock(&sensor->lock); @@ -507,6 +503,20 @@ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = { #endif }; +static const struct v4l2_rect * +__ov5647_get_pad_crop(struct ov5647 *ov5647, struct v4l2_subdev_pad_config *cfg, + unsigned int pad, enum v4l2_subdev_format_whence which) +{ + switch (which) { + case V4L2_SUBDEV_FORMAT_TRY: + return v4l2_subdev_get_try_crop(&ov5647->sd, cfg, pad); + case V4L2_SUBDEV_FORMAT_ACTIVE: + return &ov5647->mode->crop; + } + + return NULL; +} + static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) { struct ov5647 *sensor = to_sensor(sd); @@ -577,11 +587,48 @@ static int ov5647_set_get_fmt(struct v4l2_subdev *sd, return 0; } +static int ov5647_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + switch (sel->target) { + case V4L2_SEL_TGT_CROP: { + struct ov5647 *sensor = to_sensor(sd); + + mutex_lock(&sensor->lock); + sel->r = *__ov5647_get_pad_crop(sensor, cfg, sel->pad, + sel->which); + mutex_unlock(&sensor->lock); + + return 0; + } + + case V4L2_SEL_TGT_NATIVE_SIZE: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = OV5647_NATIVE_WIDTH; + sel->r.height = OV5647_NATIVE_HEIGHT; + + return 0; + + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.top = OV5647_PIXEL_ARRAY_TOP; + sel->r.left = OV5647_PIXEL_ARRAY_LEFT; + sel->r.width = OV5647_PIXEL_ARRAY_WIDTH; + sel->r.height = OV5647_PIXEL_ARRAY_HEIGHT; + + return 0; + } + + return -EINVAL; +} + static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = { .enum_mbus_code = ov5647_enum_mbus_code, .enum_frame_size = ov5647_enum_frame_size, .set_fmt = ov5647_set_get_fmt, .get_fmt = ov5647_set_get_fmt, + .get_selection = ov5647_get_selection, }; static const struct v4l2_subdev_ops ov5647_subdev_ops = { @@ -626,10 +673,10 @@ static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0); - crop->left = OV5647_COLUMN_START_DEF; - crop->top = OV5647_ROW_START_DEF; - crop->width = OV5647_WINDOW_WIDTH_DEF; - crop->height = OV5647_WINDOW_HEIGHT_DEF; + crop->left = OV5647_PIXEL_ARRAY_LEFT; + crop->top = OV5647_PIXEL_ARRAY_TOP; + crop->width = OV5647_PIXEL_ARRAY_WIDTH; + crop->height = OV5647_PIXEL_ARRAY_HEIGHT; *format = OV5647_DEFAULT_FORMAT; From patchwork Tue Jun 23 16:49:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4164 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4D93D60103 for ; Tue, 23 Jun 2020 18:46:17 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 1867C100007; Tue, 23 Jun 2020 16:46:13 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:49:09 +0200 Message-Id: <20200623164911.45147-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 17/25] media: ov5647: Rename SBGGR8 VGA mode X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:46:17 -0000 Before adding new modes, rename the only existing one to report the media bus format in the name to distinguish it from future additions. While at it, briefly describe the mode. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 3757f0b10fe93..c36d6b92b97a0 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -115,7 +115,7 @@ static struct regval_list sensor_oe_enable_regs[] = { {0x3002, 0xe4}, }; -static struct regval_list ov5647_640x480[] = { +static struct regval_list ov5647_640x480_sbggr8[] = { {0x0100, 0x00}, {0x0103, 0x01}, {0x3034, 0x08}, @@ -205,7 +205,8 @@ static struct regval_list ov5647_640x480[] = { {0x0100, 0x01}, }; -static struct ov5647_mode ov5647_8bit_modes[] = { +static struct ov5647_mode ov5647_sbggr8_modes[] = { + /* 8-bit VGA mode: Uncentred crop 2x2 binned 1296x972 image. */ { .format = { .code = MEDIA_BUS_FMT_SBGGR8_1X8, @@ -220,16 +221,16 @@ static struct ov5647_mode ov5647_8bit_modes[] = { .width = 1280, .height = 960, }, - .reg_list = ov5647_640x480, - .num_regs = ARRAY_SIZE(ov5647_640x480) + .reg_list = ov5647_640x480_sbggr8, + .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr8) }, }; static const struct ov5647_format_list ov5647_formats[] = { { .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, - .modes = ov5647_8bit_modes, - .num_modes = ARRAY_SIZE(ov5647_8bit_modes), + .modes = ov5647_sbggr8_modes, + .num_modes = ARRAY_SIZE(ov5647_sbggr8_modes), }, }; From patchwork Tue Jun 23 16:49:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4165 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 994A260103 for ; Tue, 23 Jun 2020 18:46:20 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 7385B10000A; Tue, 23 Jun 2020 16:46:17 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:49:10 +0200 Message-Id: <20200623164911.45147-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 18/25] media: ov5647: Add SGGBR10_1X10 modes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:46:20 -0000 Add 4 additional sensor modes in SBGGR10_1X10 format. Add the following resolutions in SBGGR10_1X10 format: - 2592x1944 full resolution - 1920x1080 1080p cropped - 1296x972 2x2 binned - 640x480 2x2 binned, 2x2 subsampled The register lists and modes definition have been upported from the RaspberryPi BSP at revision: commit 581dfda6d0a62 ("media: i2c: ov5647: Advertise the correct exposure range") Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 441 +++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index c36d6b92b97a0..af9e6d43967d8 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -205,6 +205,367 @@ static struct regval_list ov5647_640x480_sbggr8[] = { {0x0100, 0x01}, }; +static struct regval_list ov5647_2592x1944_sbggr10[] = { + {0x0100, 0x00}, + {0x0103, 0x01}, + {0x3034, 0x1a}, + {0x3035, 0x21}, + {0x3036, 0x69}, + {0x303c, 0x11}, + {0x3106, 0xf5}, + {0x3821, 0x06}, + {0x3820, 0x00}, + {0x3827, 0xec}, + {0x370c, 0x03}, + {0x3612, 0x5b}, + {0x3618, 0x04}, + {0x5000, 0x06}, + {0x5002, 0x41}, + {0x5003, 0x08}, + {0x5a00, 0x08}, + {0x3000, 0x00}, + {0x3001, 0x00}, + {0x3002, 0x00}, + {0x3016, 0x08}, + {0x3017, 0xe0}, + {0x3018, 0x44}, + {0x301c, 0xf8}, + {0x301d, 0xf0}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3708, 0x64}, + {0x3709, 0x12}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3811, 0x10}, + {0x3813, 0x06}, + {0x3630, 0x2e}, + {0x3632, 0xe2}, + {0x3633, 0x23}, + {0x3634, 0x44}, + {0x3636, 0x06}, + {0x3620, 0x64}, + {0x3621, 0xe0}, + {0x3600, 0x37}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x3731, 0x02}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3f05, 0x02}, + {0x3f06, 0x10}, + {0x3f01, 0x0a}, + {0x3a08, 0x01}, + {0x3a09, 0x28}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, + {0x3a0f, 0x58}, + {0x3a10, 0x50}, + {0x3a1b, 0x58}, + {0x3a1e, 0x50}, + {0x3a11, 0x60}, + {0x3a1f, 0x28}, + {0x4001, 0x02}, + {0x4004, 0x04}, + {0x4000, 0x09}, + {0x4837, 0x19}, + {0x4800, 0x24}, + {0x3503, 0x03}, + {0x0100, 0x01}, +}; + +static struct regval_list ov5647_1080p30_sbggr10[] = { + {0x0100, 0x00}, + {0x0103, 0x01}, + {0x3034, 0x1a}, + {0x3035, 0x21}, + {0x3036, 0x62}, + {0x303c, 0x11}, + {0x3106, 0xf5}, + {0x3821, 0x06}, + {0x3820, 0x00}, + {0x3827, 0xec}, + {0x370c, 0x03}, + {0x3612, 0x5b}, + {0x3618, 0x04}, + {0x5000, 0x06}, + {0x5002, 0x41}, + {0x5003, 0x08}, + {0x5a00, 0x08}, + {0x3000, 0x00}, + {0x3001, 0x00}, + {0x3002, 0x00}, + {0x3016, 0x08}, + {0x3017, 0xe0}, + {0x3018, 0x44}, + {0x301c, 0xf8}, + {0x301d, 0xf0}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, + {0x380c, 0x09}, + {0x380d, 0x70}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3708, 0x64}, + {0x3709, 0x12}, + {0x3808, 0x07}, + {0x3809, 0x80}, + {0x380a, 0x04}, + {0x380b, 0x38}, + {0x3800, 0x01}, + {0x3801, 0x5c}, + {0x3802, 0x01}, + {0x3803, 0xb2}, + {0x3804, 0x08}, + {0x3805, 0xe3}, + {0x3806, 0x05}, + {0x3807, 0xf1}, + {0x3811, 0x04}, + {0x3813, 0x02}, + {0x3630, 0x2e}, + {0x3632, 0xe2}, + {0x3633, 0x23}, + {0x3634, 0x44}, + {0x3636, 0x06}, + {0x3620, 0x64}, + {0x3621, 0xe0}, + {0x3600, 0x37}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x3731, 0x02}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3f05, 0x02}, + {0x3f06, 0x10}, + {0x3f01, 0x0a}, + {0x3a08, 0x01}, + {0x3a09, 0x4b}, + {0x3a0a, 0x01}, + {0x3a0b, 0x13}, + {0x3a0d, 0x04}, + {0x3a0e, 0x03}, + {0x3a0f, 0x58}, + {0x3a10, 0x50}, + {0x3a1b, 0x58}, + {0x3a1e, 0x50}, + {0x3a11, 0x60}, + {0x3a1f, 0x28}, + {0x4001, 0x02}, + {0x4004, 0x04}, + {0x4000, 0x09}, + {0x4837, 0x19}, + {0x4800, 0x34}, + {0x3503, 0x03}, + {0x0100, 0x01}, +}; + +static struct regval_list ov5647_2x2binned_sbggr10[] = { + {0x0100, 0x00}, + {0x0103, 0x01}, + {0x3034, 0x1a}, + {0x3035, 0x21}, + {0x3036, 0x62}, + {0x303c, 0x11}, + {0x3106, 0xf5}, + {0x3827, 0xec}, + {0x370c, 0x03}, + {0x3612, 0x59}, + {0x3618, 0x00}, + {0x5000, 0x06}, + {0x5002, 0x41}, + {0x5003, 0x08}, + {0x5a00, 0x08}, + {0x3000, 0x00}, + {0x3001, 0x00}, + {0x3002, 0x00}, + {0x3016, 0x08}, + {0x3017, 0xe0}, + {0x3018, 0x44}, + {0x301c, 0xf8}, + {0x301d, 0xf0}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x05}, + {0x3809, 0x10}, + {0x380a, 0x03}, + {0x380b, 0xcc}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x3811, 0x0c}, + {0x3813, 0x06}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3630, 0x2e}, + {0x3632, 0xe2}, + {0x3633, 0x23}, + {0x3634, 0x44}, + {0x3636, 0x06}, + {0x3620, 0x64}, + {0x3621, 0xe0}, + {0x3600, 0x37}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x3731, 0x02}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3f05, 0x02}, + {0x3f06, 0x10}, + {0x3f01, 0x0a}, + {0x3a08, 0x01}, + {0x3a09, 0x28}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, + {0x3a0f, 0x58}, + {0x3a10, 0x50}, + {0x3a1b, 0x58}, + {0x3a1e, 0x50}, + {0x3a11, 0x60}, + {0x3a1f, 0x28}, + {0x4001, 0x02}, + {0x4004, 0x04}, + {0x4000, 0x09}, + {0x4837, 0x16}, + {0x4800, 0x24}, + {0x3503, 0x03}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x350a, 0x00}, + {0x350b, 0x10}, + {0x3500, 0x00}, + {0x3501, 0x1a}, + {0x3502, 0xf0}, + {0x3212, 0xa0}, + {0x0100, 0x01}, +}; + +static struct regval_list ov5647_640x480_sbggr10[] = { + {0x0100, 0x00}, + {0x0103, 0x01}, + {0x3035, 0x11}, + {0x3036, 0x46}, + {0x303c, 0x11}, + {0x3821, 0x07}, + {0x3820, 0x41}, + {0x370c, 0x03}, + {0x3612, 0x59}, + {0x3618, 0x00}, + {0x5000, 0x06}, + {0x5003, 0x08}, + {0x5a00, 0x08}, + {0x3000, 0xff}, + {0x3001, 0xff}, + {0x3002, 0xff}, + {0x301d, 0xf0}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3c01, 0x80}, + {0x3b07, 0x0c}, + {0x380c, 0x07}, + {0x380d, 0x3c}, + {0x3814, 0x35}, + {0x3815, 0x35}, + {0x3708, 0x64}, + {0x3709, 0x52}, + {0x3808, 0x02}, + {0x3809, 0x80}, + {0x380a, 0x01}, + {0x380b, 0xe0}, + {0x3800, 0x00}, + {0x3801, 0x10}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x2f}, + {0x3806, 0x07}, + {0x3807, 0x9f}, + {0x3630, 0x2e}, + {0x3632, 0xe2}, + {0x3633, 0x23}, + {0x3634, 0x44}, + {0x3620, 0x64}, + {0x3621, 0xe0}, + {0x3600, 0x37}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x3731, 0x02}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3f05, 0x02}, + {0x3f06, 0x10}, + {0x3f01, 0x0a}, + {0x3a08, 0x01}, + {0x3a09, 0x2e}, + {0x3a0a, 0x00}, + {0x3a0b, 0xfb}, + {0x3a0d, 0x02}, + {0x3a0e, 0x01}, + {0x3a0f, 0x58}, + {0x3a10, 0x50}, + {0x3a1b, 0x58}, + {0x3a1e, 0x50}, + {0x3a11, 0x60}, + {0x3a1f, 0x28}, + {0x4001, 0x02}, + {0x4004, 0x02}, + {0x4000, 0x09}, + {0x3000, 0x00}, + {0x3001, 0x00}, + {0x3002, 0x00}, + {0x3017, 0xe0}, + {0x301c, 0xfc}, + {0x3636, 0x06}, + {0x3016, 0x08}, + {0x3827, 0xec}, + {0x3018, 0x44}, + {0x3035, 0x21}, + {0x3106, 0xf5}, + {0x3034, 0x1a}, + {0x301c, 0xf8}, + {0x4800, 0x34}, + {0x3503, 0x03}, + {0x0100, 0x01}, +}; + static struct ov5647_mode ov5647_sbggr8_modes[] = { /* 8-bit VGA mode: Uncentred crop 2x2 binned 1296x972 image. */ { @@ -226,12 +587,92 @@ static struct ov5647_mode ov5647_sbggr8_modes[] = { }, }; +static struct ov5647_mode ov5647_sbggr10_modes[] = { + /* 2592x1944 full resolution full FOV 10-bit mode. */ + { + .format = { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + .width = 2592, + .height = 1944 + }, + .crop = { + .left = 0, + .top = 0, + .width = 2592, + .height = 1944 + }, + .reg_list = ov5647_2592x1944_sbggr10, + .num_regs = ARRAY_SIZE(ov5647_2592x1944_sbggr10) + }, + /* 1080p30 10-bit mode. Full resolution centre-cropped down to 1080p. */ + { + .format = { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + .width = 1920, + .height = 1080 + }, + .crop = { + .left = 348, + .top = 434, + .width = 1928, + .height = 1080, + }, + .reg_list = ov5647_1080p30_sbggr10, + .num_regs = ARRAY_SIZE(ov5647_1080p30_sbggr10) + }, + /* 2x2 binned full FOV 10-bit mode. */ + { + .format = { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + .width = 1296, + .height = 972 + }, + .crop = { + .left = 0, + .top = 0, + .width = 2592, + .height = 1944, + }, + .reg_list = ov5647_2x2binned_sbggr10, + .num_regs = ARRAY_SIZE(ov5647_2x2binned_sbggr10) + }, + /* 10-bit VGA full FOV 60fps. 2x2 binned and subsampled down to VGA. */ + { + .format = { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + .width = 640, + .height = 480 + }, + .crop = { + .left = 16, + .top = 0, + .width = 2560, + .height = 1920, + }, + .reg_list = ov5647_640x480_sbggr10, + .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr10) + }, +}; + static const struct ov5647_format_list ov5647_formats[] = { { .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .modes = ov5647_sbggr8_modes, .num_modes = ARRAY_SIZE(ov5647_sbggr8_modes), }, + { + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .modes = ov5647_sbggr10_modes, + .num_modes = ARRAY_SIZE(ov5647_sbggr10_modes), + }, }; #define OV5647_NUM_FORMATS (ARRAY_SIZE(ov5647_formats)) From patchwork Tue Jun 23 16:49:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4166 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DE9AB60103 for ; Tue, 23 Jun 2020 18:46:23 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id BE08F100004; Tue, 23 Jun 2020 16:46:20 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:49:11 +0200 Message-Id: <20200623164911.45147-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 19/25] media: ov5647: Implement set_fmt pad operation X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:46:24 -0000 Now that the driver supports more than a single mode, implement the .set_fmt pad operation and adjust the existing .get_fmt one to report the currently applied format. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 67 +++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index af9e6d43967d8..39e320f321bd8 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -1016,15 +1016,72 @@ static int ov5647_enum_frame_size(struct v4l2_subdev *sd, return 0; } -static int ov5647_set_get_fmt(struct v4l2_subdev *sd, +static int ov5647_get_pad_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; + struct v4l2_mbus_framefmt *sensor_format; + struct ov5647 *sensor = to_sensor(sd); - /* Only one format is supported, so return that. */ + mutex_lock(&sensor->lock); memset(fmt, 0, sizeof(*fmt)); - *fmt = OV5647_DEFAULT_FORMAT; + + switch (format->which) { + case V4L2_SUBDEV_FORMAT_TRY: + sensor_format = v4l2_subdev_get_try_format(sd, cfg, format->pad); + break; + default: + sensor_format = &sensor->mode->format; + break; + } + + *fmt = *sensor_format; + mutex_unlock(&sensor->lock); + + return 0; +} + +static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *fmt = &format->format; + struct ov5647 *sensor = to_sensor(sd); + struct ov5647_mode *ov5647_mode_list; + struct ov5647_mode *mode; + unsigned int num_modes; + + /* + * Default mbus code MEDIA_BUS_FMT_SBGGR10_1X10 if the requested one + * is not supported. + */ + if (fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8) { + ov5647_mode_list = ov5647_sbggr8_modes; + num_modes = ARRAY_SIZE(ov5647_sbggr8_modes); + } else { + ov5647_mode_list = ov5647_sbggr10_modes; + num_modes = ARRAY_SIZE(ov5647_sbggr10_modes); + } + + mode = v4l2_find_nearest_size(ov5647_mode_list, num_modes, + format.width, format.height, + fmt->width, fmt->height); + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + mutex_lock(&sensor->lock); + *v4l2_subdev_get_try_format(sd, cfg, format->pad) = mode->format; + *fmt = mode->format; + mutex_unlock(&sensor->lock); + + return 0; + } + + /* Update the sensor mode and apply at it at streamon time. */ + mutex_lock(&sensor->lock); + sensor->mode = mode; + *fmt = mode->format; + mutex_unlock(&sensor->lock); return 0; } @@ -1068,8 +1125,8 @@ static int ov5647_get_selection(struct v4l2_subdev *sd, static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = { .enum_mbus_code = ov5647_enum_mbus_code, .enum_frame_size = ov5647_enum_frame_size, - .set_fmt = ov5647_set_get_fmt, - .get_fmt = ov5647_set_get_fmt, + .set_fmt = ov5647_set_pad_fmt, + .get_fmt = ov5647_get_pad_fmt, .get_selection = ov5647_get_selection, }; From patchwork Tue Jun 23 16:55:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4167 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4A62C60103 for ; Tue, 23 Jun 2020 18:52:43 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 8EDC4200002; Tue, 23 Jun 2020 16:52:37 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:55:45 +0200 Message-Id: <20200623165550.45835-1-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 20/25] media: ov5647: Program mode only if it has changed X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:52:43 -0000 Store in the driver structure a pointer to the currently applied mode and program a new one at s_stream(1) time only if it has changed. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 39e320f321bd8..ac114269e1c73 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -96,6 +96,7 @@ struct ov5647 { bool clock_ncont; struct v4l2_ctrl_handler ctrls; struct ov5647_mode *mode; + struct ov5647_mode *current_mode; }; static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) @@ -750,9 +751,13 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel) static int ov5647_set_mode(struct v4l2_subdev *sd) { struct i2c_client *client = v4l2_get_subdevdata(sd); + struct ov5647 *sensor = to_sensor(sd); u8 resetval, rdval; int ret; + if (sensor->mode == sensor->current_mode) + return 0; + ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval); if (ret < 0) return ret; @@ -778,6 +783,8 @@ static int ov5647_set_mode(struct v4l2_subdev *sd) return ret; } + sensor->current_mode = sensor->mode; + return 0; } @@ -816,6 +823,7 @@ static int ov5647_stream_on(struct v4l2_subdev *sd) static int ov5647_stream_off(struct v4l2_subdev *sd) { + struct ov5647 *sensor = to_sensor(sd); int ret; ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_CLOCK_LANE_GATE | @@ -827,7 +835,13 @@ static int ov5647_stream_off(struct v4l2_subdev *sd) if (ret < 0) return ret; - return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x01); + ret = ov5647_write(sd, OV5640_REG_PAD_OUT, 0x01); + if (ret < 0) + return ret; + + sensor->current_mode = NULL; + + return 0; } static int set_sw_standby(struct v4l2_subdev *sd, bool standby) From patchwork Tue Jun 23 16:55:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4168 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A50EC60103 for ; Tue, 23 Jun 2020 18:52:46 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 5AEEE20000D; Tue, 23 Jun 2020 16:52:43 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Dave Stevenson , Jacopo Mondi Date: Tue, 23 Jun 2020 18:55:46 +0200 Message-Id: <20200623165550.45835-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 21/25] media: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:52:46 -0000 From: Dave Stevenson The ov5647 subdev can generate control events, therefore set the V4L2_SUBDEV_FL_HAS_EVENTS flag. Signed-off-by: Dave Stevenson Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index ac114269e1c73..35865e56de5f9 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -1418,7 +1418,7 @@ static int ov5647_probe(struct i2c_client *client) sd = &sensor->sd; v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops); sd->internal_ops = &ov5647_subdev_internal_ops; - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; From patchwork Tue Jun 23 16:55:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4169 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 01E5B60103 for ; Tue, 23 Jun 2020 18:52:50 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id C5874200008; Tue, 23 Jun 2020 16:52:46 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Dave Stevenson , Jacopo Mondi Date: Tue, 23 Jun 2020 18:55:47 +0200 Message-Id: <20200623165550.45835-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 22/25] media: ov5647: Support V4L2_CID_PIXEL_RATE X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:52:50 -0000 From: Dave Stevenson Clients need to know the pixel rate in order to compute exposure and frame rate values. Advertise it. Signed-off-by: Dave Stevenson Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 40 +++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 35865e56de5f9..218576a05e66b 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -76,6 +76,7 @@ struct regval_list { struct ov5647_mode { struct v4l2_mbus_framefmt format; struct v4l2_rect crop; + u64 pixel_rate; struct regval_list *reg_list; unsigned int num_regs; }; @@ -97,6 +98,7 @@ struct ov5647 { struct v4l2_ctrl_handler ctrls; struct ov5647_mode *mode; struct ov5647_mode *current_mode; + struct v4l2_ctrl *pixel_rate; }; static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) @@ -583,6 +585,7 @@ static struct ov5647_mode ov5647_sbggr8_modes[] = { .width = 1280, .height = 960, }, + .pixel_rate = 77291670, .reg_list = ov5647_640x480_sbggr8, .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr8) }, @@ -604,6 +607,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .width = 2592, .height = 1944 }, + .pixel_rate = 87500000, .reg_list = ov5647_2592x1944_sbggr10, .num_regs = ARRAY_SIZE(ov5647_2592x1944_sbggr10) }, @@ -622,6 +626,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .width = 1928, .height = 1080, }, + .pixel_rate = 81666700, .reg_list = ov5647_1080p30_sbggr10, .num_regs = ARRAY_SIZE(ov5647_1080p30_sbggr10) }, @@ -640,6 +645,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .width = 2592, .height = 1944, }, + .pixel_rate = 81666700, .reg_list = ov5647_2x2binned_sbggr10, .num_regs = ARRAY_SIZE(ov5647_2x2binned_sbggr10) }, @@ -658,6 +664,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .width = 2560, .height = 1920, }, + .pixel_rate = 55000000, .reg_list = ov5647_640x480_sbggr10, .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr10) }, @@ -1094,6 +1101,10 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, /* Update the sensor mode and apply at it at streamon time. */ mutex_lock(&sensor->lock); sensor->mode = mode; + + __v4l2_ctrl_modify_range(sensor->pixel_rate, mode->pixel_rate, + mode->pixel_rate, 1, mode->pixel_rate); + *fmt = mode->format; mutex_unlock(&sensor->lock); @@ -1295,6 +1306,9 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) return ov5647_s_analogue_gain(sd, ctrl->val); case V4L2_CID_EXPOSURE: return ov5647_s_exposure(sd, ctrl->val); + case V4L2_CID_PIXEL_RATE: + /* Read-only, but we adjust it based on mode. */ + return 0; default: dev_info(&client->dev, "Control (id:0x%x, val:0x%x) not supported\n", @@ -1313,7 +1327,7 @@ static int ov5647_init_controls(struct ov5647 *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); - v4l2_ctrl_handler_init(&sensor->ctrls, 5); + v4l2_ctrl_handler_init(&sensor->ctrls, 6); v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 0); @@ -1333,17 +1347,29 @@ static int ov5647_init_controls(struct ov5647 *sensor) v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 32); - if (sensor->ctrls.error) { - dev_err(&client->dev, "%s Controls initialization failed (%d)\n", - __func__, sensor->ctrls.error); - v4l2_ctrl_handler_free(&sensor->ctrls); + /* By default, PIXEL_RATE is read only, but it does change per mode */ + sensor->pixel_rate = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_PIXEL_RATE, + sensor->mode->pixel_rate, + sensor->mode->pixel_rate, 1, + sensor->mode->pixel_rate); + if (!sensor->pixel_rate) + goto handler_free; + sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; - return sensor->ctrls.error; - } + if (sensor->ctrls.error) + goto handler_free; sensor->sd.ctrl_handler = &sensor->ctrls; return 0; + +handler_free: + dev_err(&client->dev, "%s Controls initialization failed (%d)\n", + __func__, sensor->ctrls.error); + v4l2_ctrl_handler_free(&sensor->ctrls); + + return sensor->ctrls.error; } static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np) From patchwork Tue Jun 23 16:55:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4170 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 760B560103 for ; Tue, 23 Jun 2020 18:52:53 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 1C10A20000A; Tue, 23 Jun 2020 16:52:49 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Jacopo Mondi Date: Tue, 23 Jun 2020 18:55:48 +0200 Message-Id: <20200623165550.45835-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 23/25] media: ov5647: Support V4L2_CID_HBLANK control X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:52:53 -0000 Add support for the V4L2_CID_HBLANK read-only control. The implementation has been upported from RaspberryPi BSP commit: commit d82f202156605 ("media: i2c: ov5647: Set V4L2_SUBDEV_FL_HAS_EVENTS flag") Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 218576a05e66b..3467a8090b38d 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -77,6 +77,7 @@ struct ov5647_mode { struct v4l2_mbus_framefmt format; struct v4l2_rect crop; u64 pixel_rate; + int hts; struct regval_list *reg_list; unsigned int num_regs; }; @@ -99,6 +100,7 @@ struct ov5647 { struct ov5647_mode *mode; struct ov5647_mode *current_mode; struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *hblank; }; static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) @@ -586,6 +588,7 @@ static struct ov5647_mode ov5647_sbggr8_modes[] = { .height = 960, }, .pixel_rate = 77291670, + .hts = 1896, .reg_list = ov5647_640x480_sbggr8, .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr8) }, @@ -608,6 +611,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .height = 1944 }, .pixel_rate = 87500000, + .hts = 2844, .reg_list = ov5647_2592x1944_sbggr10, .num_regs = ARRAY_SIZE(ov5647_2592x1944_sbggr10) }, @@ -627,6 +631,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .height = 1080, }, .pixel_rate = 81666700, + .hts = 2416, .reg_list = ov5647_1080p30_sbggr10, .num_regs = ARRAY_SIZE(ov5647_1080p30_sbggr10) }, @@ -646,6 +651,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .height = 1944, }, .pixel_rate = 81666700, + .hts = 1896, .reg_list = ov5647_2x2binned_sbggr10, .num_regs = ARRAY_SIZE(ov5647_2x2binned_sbggr10) }, @@ -665,6 +671,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { .height = 1920, }, .pixel_rate = 55000000, + .hts = 1852, .reg_list = ov5647_640x480_sbggr10, .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr10) }, @@ -1072,6 +1079,7 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, struct ov5647_mode *ov5647_mode_list; struct ov5647_mode *mode; unsigned int num_modes; + int hblank; /* * Default mbus code MEDIA_BUS_FMT_SBGGR10_1X10 if the requested one @@ -1105,6 +1113,9 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, __v4l2_ctrl_modify_range(sensor->pixel_rate, mode->pixel_rate, mode->pixel_rate, 1, mode->pixel_rate); + hblank = mode->hts - mode->format.width; + __v4l2_ctrl_modify_range(sensor->hblank, hblank, hblank, 1, hblank); + *fmt = mode->format; mutex_unlock(&sensor->lock); @@ -1309,6 +1320,9 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_PIXEL_RATE: /* Read-only, but we adjust it based on mode. */ return 0; + case V4L2_CID_HBLANK: + /* Read-only, but we adjust it based on mode. */ + return 0; default: dev_info(&client->dev, "Control (id:0x%x, val:0x%x) not supported\n", @@ -1326,8 +1340,9 @@ static const struct v4l2_ctrl_ops ov5647_ctrl_ops = { static int ov5647_init_controls(struct ov5647 *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); + int hblank; - v4l2_ctrl_handler_init(&sensor->ctrls, 6); + v4l2_ctrl_handler_init(&sensor->ctrls, 7); v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 0); @@ -1357,6 +1372,15 @@ static int ov5647_init_controls(struct ov5647 *sensor) goto handler_free; sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; + /* By default, HBLANK is read only, but it does change per mode */ + hblank = sensor->mode->hts - sensor->mode->format.width; + sensor->hblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_HBLANK, hblank, hblank, 1, + hblank); + if (!sensor->hblank) + goto handler_free; + sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + if (sensor->ctrls.error) goto handler_free; From patchwork Tue Jun 23 16:55:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4171 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 05E1860103 for ; Tue, 23 Jun 2020 18:52:57 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 95D46200014; Tue, 23 Jun 2020 16:52:53 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Dave Stevenson , Jacopo Mondi Date: Tue, 23 Jun 2020 18:55:49 +0200 Message-Id: <20200623165550.45835-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 24/25] media: ov5647: Support V4L2_CID_VBLANK control X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:52:57 -0000 From: Dave Stevenson Adds vblank control to allow for frame rate control. Signed-off-by: Dave Stevenson Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 46 +++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 3467a8090b38d..209218fb073d6 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -50,6 +50,8 @@ #define OV5647_REG_AEC_AGC 0x3503 #define OV5647_REG_GAIN_HI 0x350a #define OV5647_REG_GAIN_LO 0x350b +#define OV5647_REG_VTS_HI 0x380e +#define OV5647_REG_VTS_LO 0x380f #define OV5647_REG_FRAME_OFF_NUMBER 0x4202 #define OV5647_REG_MIPI_CTRL00 0x4800 #define OV5647_REG_MIPI_CTRL14 0x4814 @@ -68,6 +70,9 @@ #define OV5647_PIXEL_ARRAY_WIDTH 2592U #define OV5647_PIXEL_ARRAY_HEIGHT 1944U +#define OV5647_VBLANK_MIN 4 +#define OV5647_VTS_MAX 32767 + struct regval_list { u16 addr; u8 data; @@ -78,6 +83,7 @@ struct ov5647_mode { struct v4l2_rect crop; u64 pixel_rate; int hts; + int vts; struct regval_list *reg_list; unsigned int num_regs; }; @@ -101,6 +107,7 @@ struct ov5647 { struct ov5647_mode *current_mode; struct v4l2_ctrl *pixel_rate; struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; }; static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) @@ -152,8 +159,6 @@ static struct regval_list ov5647_640x480_sbggr8[] = { {0x3b07, 0x0c}, {0x380c, 0x07}, {0x380d, 0x68}, - {0x380e, 0x03}, - {0x380f, 0xd8}, {0x3814, 0x31}, {0x3815, 0x31}, {0x3708, 0x64}, @@ -589,6 +594,7 @@ static struct ov5647_mode ov5647_sbggr8_modes[] = { }, .pixel_rate = 77291670, .hts = 1896, + .vts = 0x3d8, .reg_list = ov5647_640x480_sbggr8, .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr8) }, @@ -612,6 +618,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { }, .pixel_rate = 87500000, .hts = 2844, + .vts = 0x7b0, .reg_list = ov5647_2592x1944_sbggr10, .num_regs = ARRAY_SIZE(ov5647_2592x1944_sbggr10) }, @@ -632,6 +639,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { }, .pixel_rate = 81666700, .hts = 2416, + .vts = 0x450, .reg_list = ov5647_1080p30_sbggr10, .num_regs = ARRAY_SIZE(ov5647_1080p30_sbggr10) }, @@ -652,6 +660,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { }, .pixel_rate = 81666700, .hts = 1896, + .vts = 0x59b, .reg_list = ov5647_2x2binned_sbggr10, .num_regs = ARRAY_SIZE(ov5647_2x2binned_sbggr10) }, @@ -672,6 +681,7 @@ static struct ov5647_mode ov5647_sbggr10_modes[] = { }, .pixel_rate = 55000000, .hts = 1852, + .vts = 0x1f8, .reg_list = ov5647_640x480_sbggr10, .num_regs = ARRAY_SIZE(ov5647_640x480_sbggr10) }, @@ -695,6 +705,22 @@ static const struct ov5647_format_list ov5647_formats[] = { #define OV5647_DEFAULT_MODE (&ov5647_formats[0].modes[0]) #define OV5647_DEFAULT_FORMAT (ov5647_formats[0].modes[0].format) +static int ov5647_write16(struct v4l2_subdev *sd, u16 reg, u16 val) +{ + unsigned char data[4] = { reg >> 8, reg & 0xff, val >> 8, val & 0xff}; + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret; + + ret = i2c_master_send(client, data, 4); + if (ret < 0) { + dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n", + __func__, reg); + return ret; + } + + return 0; +} + static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val) { unsigned char data[3] = { reg >> 8, reg & 0xff, val}; @@ -1116,6 +1142,11 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, hblank = mode->hts - mode->format.width; __v4l2_ctrl_modify_range(sensor->hblank, hblank, hblank, 1, hblank); + __v4l2_ctrl_modify_range(sensor->vblank, OV5647_VBLANK_MIN, + OV5647_VTS_MAX - mode->format.height, + 1, mode->vts - mode->format.height); + __v4l2_ctrl_s_ctrl(sensor->vblank, mode->vts - mode->format.height); + *fmt = mode->format; mutex_unlock(&sensor->lock); @@ -1323,6 +1354,9 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_HBLANK: /* Read-only, but we adjust it based on mode. */ return 0; + case V4L2_CID_VBLANK: + return ov5647_write16(sd, OV5647_REG_VTS_HI, + sensor->mode->format.height + ctrl->val); default: dev_info(&client->dev, "Control (id:0x%x, val:0x%x) not supported\n", @@ -1342,7 +1376,7 @@ static int ov5647_init_controls(struct ov5647 *sensor) struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); int hblank; - v4l2_ctrl_handler_init(&sensor->ctrls, 7); + v4l2_ctrl_handler_init(&sensor->ctrls, 8); v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 0); @@ -1381,6 +1415,12 @@ static int ov5647_init_controls(struct ov5647 *sensor) goto handler_free; sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + sensor->vblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_VBLANK, OV5647_VBLANK_MIN, + OV5647_VTS_MAX - sensor->mode->format.height, + 1, sensor->mode->vts - + sensor->mode->format.height); + if (sensor->ctrls.error) goto handler_free; From patchwork Tue Jun 23 16:55:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 4172 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D1C74609A5 for ; Tue, 23 Jun 2020 18:53:00 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 2C20F200018; Tue, 23 Jun 2020 16:52:56 +0000 (UTC) From: Jacopo Mondi To: mchehab@kernel.org, sakari.ailus@linux.intel.com, hverkuil@xs4all.nl, laurent.pinchart@ideasonboard.com, roman.kovalivskyi@globallogic.com, dave.stevenson@raspberrypi.org, naush@raspberrypi.com Cc: mrodin@de.adit-jv.com, hugues.fruchet@st.com, mripard@kernel.org, aford173@gmail.com, sudipi@jp.adit-jv.com, andrew_gabbasov@mentor.com, erosca@de.adit-jv.com, linux-media@vger.kernel.org, libcamera-devel@lists.libcamera.org, Dave Stevenson , Jacopo Mondi Date: Tue, 23 Jun 2020 18:55:50 +0200 Message-Id: <20200623165550.45835-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623100815.10674-1-jacopo@jmondi.org> References: <20200623100815.10674-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 25/25] media: ov5647: Advertise the correct exposure range X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2020 16:53:01 -0000 From: Dave Stevenson Exposure is clipped by the VTS of the mode, so it needs to be updated when this is changed. Signed-off-by: Dave Stevenson Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5647.c | 41 ++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 209218fb073d6..8f62415c07aad 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -73,6 +73,11 @@ #define OV5647_VBLANK_MIN 4 #define OV5647_VTS_MAX 32767 +#define OV5647_EXPOSURE_MIN 4 +#define OV5647_EXPOSURE_STEP 1 +#define OV5647_EXPOSURE_DEFAULT 1000 +#define OV5647_EXPOSURE_MAX 65535 + struct regval_list { u16 addr; u8 data; @@ -108,6 +113,7 @@ struct ov5647 { struct v4l2_ctrl *pixel_rate; struct v4l2_ctrl *hblank; struct v4l2_ctrl *vblank; + struct v4l2_ctrl *exposure; }; static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) @@ -1102,10 +1108,10 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, { struct v4l2_mbus_framefmt *fmt = &format->format; struct ov5647 *sensor = to_sensor(sd); + int hblank, exposure_max, exposure_def; struct ov5647_mode *ov5647_mode_list; struct ov5647_mode *mode; unsigned int num_modes; - int hblank; /* * Default mbus code MEDIA_BUS_FMT_SBGGR10_1X10 if the requested one @@ -1147,6 +1153,13 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, 1, mode->vts - mode->format.height); __v4l2_ctrl_s_ctrl(sensor->vblank, mode->vts - mode->format.height); + exposure_max = mode->vts - 4; + exposure_def = exposure_max < OV5647_EXPOSURE_DEFAULT ? exposure_max + : OV5647_EXPOSURE_DEFAULT; + __v4l2_ctrl_modify_range(sensor->exposure, sensor->exposure->minimum, + exposure_max, sensor->exposure->step, + exposure_def); + *fmt = mode->format; mutex_unlock(&sensor->lock); @@ -1329,6 +1342,18 @@ static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) /* v4l2_ctrl_lock() locks our own mutex */ + if (ctrl->id == V4L2_CID_VBLANK) { + int exposure_max, exposure_def; + + /* Update max exposure while meeting expected vblanking */ + exposure_max = sensor->mode->format.height + ctrl->val - 4; + exposure_def = exposure_max < OV5647_EXPOSURE_DEFAULT + ? exposure_max : OV5647_EXPOSURE_DEFAULT; + __v4l2_ctrl_modify_range(sensor->exposure, sensor->exposure->minimum, + exposure_max, sensor->exposure->step, + exposure_def); + } + /* * If the device is not powered up by the host driver do * not apply any controls to H/W at this time. Instead @@ -1374,9 +1399,9 @@ static const struct v4l2_ctrl_ops ov5647_ctrl_ops = { static int ov5647_init_controls(struct ov5647 *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); - int hblank; + int hblank, exposure_max, exposure_def; - v4l2_ctrl_handler_init(&sensor->ctrls, 8); + v4l2_ctrl_handler_init(&sensor->ctrls, 9); v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 0); @@ -1388,9 +1413,13 @@ static int ov5647_init_controls(struct ov5647 *sensor) V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_MANUAL); - /* min: 4 lines; max: 0xffff lines; default: 1000 lines. */ - v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, - V4L2_CID_EXPOSURE, 4, 65535, 1, 1000); + exposure_max = sensor->mode->vts - 4; + exposure_def = exposure_max < OV5647_EXPOSURE_DEFAULT ? exposure_max + : OV5647_EXPOSURE_DEFAULT; + sensor->exposure = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops, + V4L2_CID_EXPOSURE, OV5647_EXPOSURE_MIN, + exposure_max, OV5647_EXPOSURE_STEP, + exposure_def); /* min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. */ v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,