From patchwork Fri Dec 8 15:07:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485519 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WC41vrzO" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2398D122; Fri, 8 Dec 2023 07:08:09 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AB971552; Fri, 8 Dec 2023 16:07:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048045; bh=z/kiy682Dt+Hkip6mn8zt4qO+eGw8bGSkyh8qcwql68=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WC41vrzOekFmPhEHVuCnAekMz/ew9e1H4kqHTWnFNX//zNFF6JetybSXsIe75nvoL 7ceVRK4Ex8ic5o5I70b4qbKziezV/bI7blVhlgNFOphlruN/Ur4sDl89jEjp53GLTj PuRmewmFl8TQyCYNzRb1gNlEYCXudePy/rqt1W9o= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Kieran Bingham , Umang Jain , Marco Felsch , Conor Dooley , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Bartosz Golaszewski , Sebastian Reichel , Mark Brown , linux-arm-kernel@lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 1/8] media: dt-bindings: media: imx335: Add supply bindings Date: Fri, 8 Dec 2023 20:37:47 +0530 Message-ID: <20231208150756.124720-2-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Kieran Bingham Add the bindings for the supply references used on the IMX335. Reviewed-by: Umang Jain Reviewed-by: Marco Felsch Signed-off-by: Kieran Bingham Acked-by: Conor Dooley --- .../devicetree/bindings/media/i2c/sony,imx335.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml index a167dcdb3a32..106c36ee966d 100644 --- a/Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml +++ b/Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml @@ -32,6 +32,15 @@ properties: description: Clock frequency from 6 to 27 MHz, 37.125MHz, 74.25MHz maxItems: 1 + avdd-supply: + description: Analog power supply (2.9V) + + ovdd-supply: + description: Interface power supply (1.8V) + + dvdd-supply: + description: Digital power supply (1.2V) + reset-gpios: description: Reference to the GPIO connected to the XCLR pin, if any. maxItems: 1 @@ -79,6 +88,10 @@ examples: assigned-clock-parents = <&imx335_clk_parent>; assigned-clock-rates = <24000000>; + avdd-supply = <&camera_vdda_2v9>; + ovdd-supply = <&camera_vddo_1v8>; + dvdd-supply = <&camera_vddd_1v2>; + port { imx335: endpoint { remote-endpoint = <&cam>; From patchwork Fri Dec 8 15:07:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485520 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Zk+f3UPu" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 577A6FB; Fri, 8 Dec 2023 07:08:10 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CFAD3E45; Fri, 8 Dec 2023 16:07:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048047; bh=vdBDEHa63Ev7PN0hPwHFfzuEjM8qmpReQEme7VFbTz4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Zk+f3UPuBgfDy79s3C1zWtBxpXESjbPYw/nLJhxzEWjBrA7lKaPJOtRHBf3gE1fyK 8VAxrcxZcUbBLDKf+WyaQDUGQusk905FJ77giJ8mZ2b5rPK4GqTsjphyuiINkbo9FG tecrhzha1Akabksa+exbINzq8gcDdvpQv8agAKik= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Kieran Bingham , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 2/8] media: i2c: imx335: Fix logging line endings Date: Fri, 8 Dec 2023 20:37:48 +0530 Message-ID: <20231208150756.124720-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Kieran Bingham The use of \n as a line ending throughout the driver is inconsistent. While it is possible for logging messages to automatically have newlines added by the kernel printk mechanisms, this is specifically to support continued lines with PR_CONT and the lack of a new line character indicates that the text is a fragment of a continuation line. As each of these lines are whole and not fragments, explicitly define the newline for consistency. Signed-off-by: Kieran Bingham --- drivers/media/i2c/imx335.c | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index ec729126274b..cbabef968e21 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -396,7 +396,7 @@ static int imx335_update_exp_gain(struct imx335 *imx335, u32 exposure, u32 gain) lpfr = imx335->vblank + imx335->cur_mode->height; shutter = lpfr - exposure; - dev_dbg(imx335->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u", + dev_dbg(imx335->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u\n", exposure, gain, shutter, lpfr); ret = imx335_write_reg(imx335, IMX335_REG_HOLD, 1, 1); @@ -443,7 +443,7 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_VBLANK: imx335->vblank = imx335->vblank_ctrl->val; - dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u", + dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u\n", imx335->vblank, imx335->vblank + imx335->cur_mode->height); @@ -462,7 +462,7 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl) exposure = ctrl->val; analog_gain = imx335->again_ctrl->val; - dev_dbg(imx335->dev, "Received exp %u, analog gain %u", + dev_dbg(imx335->dev, "Received exp %u, analog gain %u\n", exposure, analog_gain); ret = imx335_update_exp_gain(imx335, exposure, analog_gain); @@ -471,7 +471,7 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl) break; default: - dev_err(imx335->dev, "Invalid control %d", ctrl->id); + dev_err(imx335->dev, "Invalid control %d\n", ctrl->id); ret = -EINVAL; } @@ -652,14 +652,14 @@ static int imx335_start_streaming(struct imx335 *imx335) ret = imx335_write_regs(imx335, reg_list->regs, reg_list->num_of_regs); if (ret) { - dev_err(imx335->dev, "fail to write initial registers"); + dev_err(imx335->dev, "fail to write initial registers\n"); return ret; } /* Setup handler will write actual exposure and gain */ ret = __v4l2_ctrl_handler_setup(imx335->sd.ctrl_handler); if (ret) { - dev_err(imx335->dev, "fail to setup handler"); + dev_err(imx335->dev, "fail to setup handler\n"); return ret; } @@ -667,7 +667,7 @@ static int imx335_start_streaming(struct imx335 *imx335) ret = imx335_write_reg(imx335, IMX335_REG_MODE_SELECT, 1, IMX335_MODE_STREAMING); if (ret) { - dev_err(imx335->dev, "fail to start streaming"); + dev_err(imx335->dev, "fail to start streaming\n"); return ret; } @@ -744,7 +744,7 @@ static int imx335_detect(struct imx335 *imx335) return ret; if (val != IMX335_ID) { - dev_err(imx335->dev, "chip id mismatch: %x!=%x", + dev_err(imx335->dev, "chip id mismatch: %x!=%x\n", IMX335_ID, val); return -ENXIO; } @@ -776,7 +776,7 @@ static int imx335_parse_hw_config(struct imx335 *imx335) imx335->reset_gpio = devm_gpiod_get_optional(imx335->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(imx335->reset_gpio)) { - dev_err(imx335->dev, "failed to get reset gpio %ld", + dev_err(imx335->dev, "failed to get reset gpio %ld\n", PTR_ERR(imx335->reset_gpio)); return PTR_ERR(imx335->reset_gpio); } @@ -784,13 +784,13 @@ static int imx335_parse_hw_config(struct imx335 *imx335) /* Get sensor input clock */ imx335->inclk = devm_clk_get(imx335->dev, NULL); if (IS_ERR(imx335->inclk)) { - dev_err(imx335->dev, "could not get inclk"); + dev_err(imx335->dev, "could not get inclk\n"); return PTR_ERR(imx335->inclk); } rate = clk_get_rate(imx335->inclk); if (rate != IMX335_INCLK_RATE) { - dev_err(imx335->dev, "inclk frequency mismatch"); + dev_err(imx335->dev, "inclk frequency mismatch\n"); return -EINVAL; } @@ -805,14 +805,14 @@ static int imx335_parse_hw_config(struct imx335 *imx335) if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX335_NUM_DATA_LANES) { dev_err(imx335->dev, - "number of CSI2 data lanes %d is not supported", + "number of CSI2 data lanes %d is not supported\n", bus_cfg.bus.mipi_csi2.num_data_lanes); ret = -EINVAL; goto done_endpoint_free; } if (!bus_cfg.nr_of_link_frequencies) { - dev_err(imx335->dev, "no link frequencies defined"); + dev_err(imx335->dev, "no link frequencies defined\n"); ret = -EINVAL; goto done_endpoint_free; } @@ -863,7 +863,7 @@ static int imx335_power_on(struct device *dev) ret = clk_prepare_enable(imx335->inclk); if (ret) { - dev_err(imx335->dev, "fail to enable inclk"); + dev_err(imx335->dev, "fail to enable inclk\n"); goto error_reset; } @@ -969,7 +969,7 @@ static int imx335_init_controls(struct imx335 *imx335) imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; if (ctrl_hdlr->error) { - dev_err(imx335->dev, "control init failed: %d", + dev_err(imx335->dev, "control init failed: %d\n", ctrl_hdlr->error); v4l2_ctrl_handler_free(ctrl_hdlr); return ctrl_hdlr->error; @@ -1002,7 +1002,7 @@ static int imx335_probe(struct i2c_client *client) ret = imx335_parse_hw_config(imx335); if (ret) { - dev_err(imx335->dev, "HW configuration is not supported"); + dev_err(imx335->dev, "HW configuration is not supported\n"); return ret; } @@ -1010,14 +1010,14 @@ static int imx335_probe(struct i2c_client *client) ret = imx335_power_on(imx335->dev); if (ret) { - dev_err(imx335->dev, "failed to power-on the sensor"); + dev_err(imx335->dev, "failed to power-on the sensor\n"); goto error_mutex_destroy; } /* Check module identity */ ret = imx335_detect(imx335); if (ret) { - dev_err(imx335->dev, "failed to find sensor: %d", ret); + dev_err(imx335->dev, "failed to find sensor: %d\n", ret); goto error_power_off; } @@ -1027,7 +1027,7 @@ static int imx335_probe(struct i2c_client *client) ret = imx335_init_controls(imx335); if (ret) { - dev_err(imx335->dev, "failed to init controls: %d", ret); + dev_err(imx335->dev, "failed to init controls: %d\n", ret); goto error_power_off; } @@ -1039,14 +1039,14 @@ static int imx335_probe(struct i2c_client *client) imx335->pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_pads_init(&imx335->sd.entity, 1, &imx335->pad); if (ret) { - dev_err(imx335->dev, "failed to init entity pads: %d", ret); + dev_err(imx335->dev, "failed to init entity pads: %d\n", ret); goto error_handler_free; } ret = v4l2_async_register_subdev_sensor(&imx335->sd); if (ret < 0) { dev_err(imx335->dev, - "failed to register async subdev: %d", ret); + "failed to register async subdev: %d\n", ret); goto error_media_entity; } From patchwork Fri Dec 8 15:07:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485521 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gAuvzIPL" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 732FB122; Fri, 8 Dec 2023 07:08:12 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B5801EBA; Fri, 8 Dec 2023 16:07:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048049; bh=nrEAdhHZwA2L0AvxJ6FGfgqEfXwThQSUE+QCVNTuuhs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gAuvzIPLzZbXJAQOVLdFaCDYd4M7E8B4M6iDC4DeTXNdPI1Mc+WFc8omlFcUDmeeJ tuvNgP8E5C3mjtX+vsWmKDvyeLDlRNgHMXfzonSj+Zgw/A+PqS3K7h9oV6LV01NEDb YZaGhlOkwcvLOpu60KBkOgFrLjqmZtzQw+y4W6zc= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Kieran Bingham , Umang Jain , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 3/8] media: i2c: imx335: Improve configuration error reporting Date: Fri, 8 Dec 2023 20:37:49 +0530 Message-ID: <20231208150756.124720-4-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Kieran Bingham The existing imx335_parse_hw_config function has two paths that can be taken without reporting to the user the reason for failing to accept the hardware configuration. Extend the error reporting paths to identify failures when probing the device. Reviewed-by: Umang Jain Signed-off-by: Kieran Bingham --- drivers/media/i2c/imx335.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index cbabef968e21..31c612c6bdd8 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -795,8 +795,10 @@ static int imx335_parse_hw_config(struct imx335 *imx335) } ep = fwnode_graph_get_next_endpoint(fwnode, NULL); - if (!ep) + if (!ep) { + dev_err(imx335->dev, "Failed to get next endpoint\n"); return -ENXIO; + } ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); fwnode_handle_put(ep); @@ -821,6 +823,8 @@ static int imx335_parse_hw_config(struct imx335 *imx335) if (bus_cfg.link_frequencies[i] == IMX335_LINK_FREQ) goto done_endpoint_free; + dev_err(imx335->dev, "no compatible link frequencies found\n"); + ret = -EINVAL; done_endpoint_free: From patchwork Fri Dec 8 15:07:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485522 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="efUR303h" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D19AF1; Fri, 8 Dec 2023 07:08:14 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C23AEEEE; Fri, 8 Dec 2023 16:07:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048051; bh=SUi9QHBg3ssLxhypa1TBo31nHAR/h6rKQLwai92AHS4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=efUR303hy79pBF81cYZCqrlnejeNnguQ9OCCXb52XQOfHrxOd22raF3aL/YRffUp4 dTEJ1PCA4h5Om2LbxkudOAZAYi2SFfiESsPfZ0oH7fUH5ursZ8kjVsItkyxOs7gpKH 17tHrS4TjvgkvazsBJYg94vXTqejgEOhQLGT5KMk= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Kieran Bingham , Umang Jain , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 4/8] media: i2c: imx335: Enable regulator supplies Date: Fri, 8 Dec 2023 20:37:50 +0530 Message-ID: <20231208150756.124720-5-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Kieran Bingham Provide support for enabling and disabling regulator supplies to control power to the camera sensor. While updating the power on function, document that a sleep is represented as 'T4' in the datasheet power on sequence. Signed-off-by: Kieran Bingham Signed-off-by: Umang Jain --- drivers/media/i2c/imx335.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 31c612c6bdd8..b25216b3350e 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -75,6 +75,12 @@ struct imx335_reg_list { const struct imx335_reg *regs; }; +static const char * const imx335_supply_name[] = { + "avdd", /* Analog (2.9V) supply */ + "ovdd", /* Digital I/O (1.8V) supply */ + "dvdd", /* Digital Core (1.2V) supply */ +}; + /** * struct imx335_mode - imx335 sensor mode structure * @width: Frame width @@ -108,6 +114,7 @@ struct imx335_mode { * @sd: V4L2 sub-device * @pad: Media pad. Only one pad supported * @reset_gpio: Sensor reset gpio + * @supplies: Regulator supplies to handle power control * @inclk: Sensor input clock * @ctrl_handler: V4L2 control handler * @link_freq_ctrl: Pointer to link frequency control @@ -126,6 +133,8 @@ struct imx335 { struct v4l2_subdev sd; struct media_pad pad; struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[ARRAY_SIZE(imx335_supply_name)]; + struct clk *inclk; struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl *link_freq_ctrl; @@ -781,6 +790,17 @@ static int imx335_parse_hw_config(struct imx335 *imx335) return PTR_ERR(imx335->reset_gpio); } + for (i = 0; i < ARRAY_SIZE(imx335_supply_name); i++) + imx335->supplies[i].supply = imx335_supply_name[i]; + + ret = devm_regulator_bulk_get(imx335->dev, + ARRAY_SIZE(imx335_supply_name), + imx335->supplies); + if (ret) { + dev_err(imx335->dev, "Failed to get regulators\n"); + return ret; + } + /* Get sensor input clock */ imx335->inclk = devm_clk_get(imx335->dev, NULL); if (IS_ERR(imx335->inclk)) { @@ -863,6 +883,17 @@ static int imx335_power_on(struct device *dev) struct imx335 *imx335 = to_imx335(sd); int ret; + ret = regulator_bulk_enable(ARRAY_SIZE(imx335_supply_name), + imx335->supplies); + if (ret) { + dev_err(dev, "%s: failed to enable regulators\n", + __func__); + return ret; + } + + usleep_range(500, 550); /* Tlow */ + + /* Set XCLR */ gpiod_set_value_cansleep(imx335->reset_gpio, 1); ret = clk_prepare_enable(imx335->inclk); @@ -871,12 +902,13 @@ static int imx335_power_on(struct device *dev) goto error_reset; } - usleep_range(20, 22); + usleep_range(20, 22); /* T4 */ return 0; error_reset: gpiod_set_value_cansleep(imx335->reset_gpio, 0); + regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies); return ret; } @@ -893,8 +925,8 @@ static int imx335_power_off(struct device *dev) struct imx335 *imx335 = to_imx335(sd); gpiod_set_value_cansleep(imx335->reset_gpio, 0); - clk_disable_unprepare(imx335->inclk); + regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies); return 0; } From patchwork Fri Dec 8 15:07:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485523 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GIWbQKZR" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B38010DE; Fri, 8 Dec 2023 07:08:16 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CC0B91435; Fri, 8 Dec 2023 16:07:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048053; bh=v4zXIcoXuUwhPMrAke1jILyP8oPZPN1RS9zYrSyz7ak=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GIWbQKZRW9UuEttt6SO7ArZdTB+5QWb0akEHtalYJZjYnfeLHlIZs2shQQsAWSuDC tgDW287BnP69EfmFnUG/o4om2muBsqVNazehX6Od5F2+SkcXhUj6ZKLgsvnSxSCrVv yOkPLhl7iolYwFcef1ZzmaUQLR2ryogZybm0giqI= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Kieran Bingham , Umang Jain , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 5/8] media: i2c: imx335: Implement get selection API Date: Fri, 8 Dec 2023 20:37:51 +0530 Message-ID: <20231208150756.124720-6-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Kieran Bingham Support reporting of the Sensor Native and Active pixel array areas through the Selection API. The implementation reports a single target crop only for the mode that is presently exposed by the driver. Reviewed-by: Umang Jain Signed-off-by: Kieran Bingham --- drivers/media/i2c/imx335.c | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index b25216b3350e..a924b7222ca3 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -55,6 +55,14 @@ #define IMX335_REG_MIN 0x00 #define IMX335_REG_MAX 0xfffff +/* IMX335 native and active pixel array size. */ +#define IMX335_NATIVE_WIDTH 2616U +#define IMX335_NATIVE_HEIGHT 1964U +#define IMX335_PIXEL_ARRAY_LEFT 12U +#define IMX335_PIXEL_ARRAY_TOP 12U +#define IMX335_PIXEL_ARRAY_WIDTH 2592U +#define IMX335_PIXEL_ARRAY_HEIGHT 1944U + /** * struct imx335_reg - imx335 sensor register * @address: Register address @@ -645,6 +653,41 @@ static int imx335_init_pad_cfg(struct v4l2_subdev *sd, return imx335_set_pad_format(sd, sd_state, &fmt); } +/** + * imx335_get_selection() - Selection API + * @sd: pointer to imx335 V4L2 sub-device structure + * @sd_state: V4L2 sub-device configuration + * @sel: V4L2 selection info + * + * Return: 0 if successful, error code otherwise. + */ +static int imx335_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) +{ + switch (sel->target) { + case V4L2_SEL_TGT_NATIVE_SIZE: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = IMX335_NATIVE_WIDTH; + sel->r.height = IMX335_NATIVE_HEIGHT; + + return 0; + + case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = IMX335_PIXEL_ARRAY_TOP; + sel->r.left = IMX335_PIXEL_ARRAY_LEFT; + sel->r.width = IMX335_PIXEL_ARRAY_WIDTH; + sel->r.height = IMX335_PIXEL_ARRAY_HEIGHT; + + return 0; + } + + return -EINVAL; +} + /** * imx335_start_streaming() - Start sensor stream * @imx335: pointer to imx335 device @@ -862,6 +905,8 @@ static const struct v4l2_subdev_pad_ops imx335_pad_ops = { .init_cfg = imx335_init_pad_cfg, .enum_mbus_code = imx335_enum_mbus_code, .enum_frame_size = imx335_enum_frame_size, + .get_selection = imx335_get_selection, + .set_selection = imx335_get_selection, .get_fmt = imx335_get_pad_format, .set_fmt = imx335_set_pad_format, }; From patchwork Fri Dec 8 15:07:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485524 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tyGQgj8n" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79812173F; Fri, 8 Dec 2023 07:08:18 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D14E8512; Fri, 8 Dec 2023 16:07:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048055; bh=zV/RIEdgSrvIS1kxne2Y4K//Y+viiimnpU5CN163GOE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tyGQgj8n4uQNiTfM7OVFjlS7zUuovDpEqfB4+o1u71fLQCzWKOOUIwkuDPH+J6R44 gKVwvBcNw0ENon/eNAvW4GENPU6dGvyz3dyCRRt/uEEAiTup1nnD2Ei3gIilXU48fP 7hlEsxB9xw4TrpZ8Hb6qt6SNt5GcLzilx8/kf/NA= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Kieran Bingham , Umang Jain , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 6/8] media: i2c: imx335: Fix hblank min/max values Date: Fri, 8 Dec 2023 20:37:52 +0530 Message-ID: <20231208150756.124720-7-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Kieran Bingham The V4L2_CID_HBLANK control is marked as readonly and can only be a single value. Set the minimum and maximum value to match the mode value. Reviewed-by: Umang Jain Signed-off-by: Kieran Bingham --- drivers/media/i2c/imx335.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index a924b7222ca3..f353647a0d4e 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -1043,8 +1043,8 @@ static int imx335_init_controls(struct imx335 *imx335) imx335->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &imx335_ctrl_ops, V4L2_CID_HBLANK, - IMX335_REG_MIN, - IMX335_REG_MAX, + mode->hblank, + mode->hblank, 1, mode->hblank); if (imx335->hblank_ctrl) imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; From patchwork Fri Dec 8 15:07:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485525 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="l/0n+AcI" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61BFF198D; Fri, 8 Dec 2023 07:08:20 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E661E2B0E; Fri, 8 Dec 2023 16:07:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048057; bh=G/9IfFaMvADINkzfAeBFMqozY/6dTqLCfSJ9+yTDVLo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l/0n+AcIGAH5UTQ/u/1+HizMEFLP7da8eD8ONRVmIi9PrlD24ORdOYmccgutYQ7DY ZdcUVCI0IJPv5ClkMC9LcOiXsJTTOMlW1UKOAqLGcWwG5aS2BKmUursVGHvv4NuFFu gulH8UYqM7J7wMMroONfgpII8WLV7/dS9Uk7AJ9A= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Umang Jain , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 7/8] media: i2c: imx335: Support 2592x1940 10-bit mode Date: Fri, 8 Dec 2023 20:37:53 +0530 Message-ID: <20231208150756.124720-8-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 In addition to the existing 2592x1940 12-bit mode, introduce support for 2592x1940 10-bit mode. Following are the register set which control the 10/12 bit mode setting: MDBIT 0x319d ADBIT 0x3050 ADBIT1 0x341c 0x341d Signed-off-by: Umang Jain --- drivers/media/i2c/imx335.c | 77 ++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index f353647a0d4e..76a05624ca94 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -156,6 +156,7 @@ struct imx335 { u32 vblank; const struct imx335_mode *cur_mode; struct mutex mutex; + u32 cur_mbus_code; }; static const s64 link_freq[] = { @@ -250,6 +251,25 @@ static const struct imx335_reg mode_2592x1940_regs[] = { {0x3a00, 0x01}, }; +static const struct imx335_reg raw10_framefmt_regs[] = { + {0x3050, 0x00}, + {0x319d, 0x00}, + {0x341c, 0xff}, + {0x341d, 0x01}, +}; + +static const struct imx335_reg raw12_framefmt_regs[] = { + {0x3050, 0x01}, + {0x319d, 0x01}, + {0x341c, 0x47}, + {0x341d, 0x00}, +}; + +static const u32 imx335_mbus_codes[] = { + MEDIA_BUS_FMT_SRGGB12_1X12, + MEDIA_BUS_FMT_SRGGB10_1X10, +}; + /* Supported sensor mode configurations */ static const struct imx335_mode supported_mode = { .width = 2592, @@ -260,7 +280,6 @@ static const struct imx335_mode supported_mode = { .vblank_max = 133060, .pclk = 396000000, .link_freq_idx = 0, - .code = MEDIA_BUS_FMT_SRGGB12_1X12, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2592x1940_regs), .regs = mode_2592x1940_regs, @@ -500,6 +519,18 @@ static const struct v4l2_ctrl_ops imx335_ctrl_ops = { .s_ctrl = imx335_set_ctrl, }; +static int imx335_get_format_code(struct imx335 *imx335, u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(imx335_mbus_codes); i++) { + if (imx335_mbus_codes[i] == code) + return imx335_mbus_codes[i]; + } + + return imx335_mbus_codes[0]; +} + /** * imx335_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes * @sd: pointer to imx335 V4L2 sub-device structure @@ -512,10 +543,10 @@ static int imx335_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - if (code->index > 0) + if (code->index >= ARRAY_SIZE(imx335_mbus_codes)) return -EINVAL; - code->code = supported_mode.code; + code->code = imx335_mbus_codes[code->index]; return 0; } @@ -532,10 +563,14 @@ static int imx335_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fsize) { - if (fsize->index > 0) + struct imx335 *imx335 = to_imx335(sd); + u32 code; + + if (fsize->index > ARRAY_SIZE(imx335_mbus_codes)) return -EINVAL; - if (fsize->code != supported_mode.code) + code = imx335_get_format_code(imx335, fsize->code); + if (fsize->code != code) return -EINVAL; fsize->min_width = supported_mode.width; @@ -559,7 +594,7 @@ static void imx335_fill_pad_format(struct imx335 *imx335, { fmt->format.width = mode->width; fmt->format.height = mode->height; - fmt->format.code = mode->code; + fmt->format.code = imx335->cur_mbus_code; fmt->format.field = V4L2_FIELD_NONE; fmt->format.colorspace = V4L2_COLORSPACE_RAW; fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; @@ -611,11 +646,16 @@ static int imx335_set_pad_format(struct v4l2_subdev *sd, { struct imx335 *imx335 = to_imx335(sd); const struct imx335_mode *mode; - int ret = 0; + int i, ret = 0; mutex_lock(&imx335->mutex); mode = &supported_mode; + for (i = 0; i < ARRAY_SIZE(imx335_mbus_codes); i++) { + if (imx335_mbus_codes[i] == fmt->format.code) + imx335->cur_mbus_code = imx335_mbus_codes[i]; + } + imx335_fill_pad_format(imx335, mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { @@ -688,6 +728,21 @@ static int imx335_get_selection(struct v4l2_subdev *sd, return -EINVAL; } +static int imx335_set_framefmt(struct imx335 *imx335) +{ + switch (imx335->cur_mbus_code) { + case MEDIA_BUS_FMT_SRGGB10_1X10: + return imx335_write_regs(imx335, raw10_framefmt_regs, + ARRAY_SIZE(raw10_framefmt_regs)); + + case MEDIA_BUS_FMT_SRGGB12_1X12: + return imx335_write_regs(imx335, raw12_framefmt_regs, + ARRAY_SIZE(raw12_framefmt_regs)); + } + + return -EINVAL; +} + /** * imx335_start_streaming() - Start sensor stream * @imx335: pointer to imx335 device @@ -708,6 +763,13 @@ static int imx335_start_streaming(struct imx335 *imx335) return ret; } + ret = imx335_set_framefmt(imx335); + if (ret) { + dev_err(imx335->dev, "%s failed to set frame format: %d\n", + __func__, ret); + return ret; + } + /* Setup handler will write actual exposure and gain */ ret = __v4l2_ctrl_handler_setup(imx335->sd.ctrl_handler); if (ret) { @@ -1104,6 +1166,7 @@ static int imx335_probe(struct i2c_client *client) /* Set default mode to max resolution */ imx335->cur_mode = &supported_mode; + imx335->cur_mbus_code = imx335_mbus_codes[0]; imx335->vblank = imx335->cur_mode->vblank; ret = imx335_init_controls(imx335); From patchwork Fri Dec 8 15:07:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13485526 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="EHxZ3Xqw" Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61358199D; Fri, 8 Dec 2023 07:08:22 -0800 (PST) Received: from umang.jain (unknown [103.251.226.108]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CDFA1552; Fri, 8 Dec 2023 16:07:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1702048059; bh=++pJ6xBSDGmfMWD1Z0+shMY0/qfwngayfbMUOZTJ3Qk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EHxZ3XqwFkWdOzIR92TaKBGQBbRhMtUzARlXvGyyieAbIuoif2i0pfc0bnOlOFuyh hkWN4q51O5w4YeQkofPZ5hxz1kH/4ynidnpryuw7JSqrSCCMI3z36rDydZYCRbQ27f yEkZMv3n9XZsJt6iNa5qaHaYLD+ttI70h+PS16mc= From: Umang Jain To: devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: "Paul J . Murphy" , Daniele Alessandrelli , Sakari Ailus , Mauro Carvalho Chehab , Umang Jain , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v3 8/8] media: i2c: imx335: Support multiple link frequency Date: Fri, 8 Dec 2023 20:37:54 +0530 Message-ID: <20231208150756.124720-9-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231208150756.124720-1-umang.jain@ideasonboard.com> References: <20231208150756.124720-1-umang.jain@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support link frequency of 445MHz in addition to 594MHz. Signed-off-by: Umang Jain --- drivers/media/i2c/imx335.c | 89 +++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 76a05624ca94..1d6dc38e3e6b 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -49,7 +49,8 @@ #define IMX335_INCLK_RATE 24000000 /* CSI2 HW configuration */ -#define IMX335_LINK_FREQ 594000000 +#define IMX335_LINK_FREQ_594MHz 594000000 +#define IMX335_LINK_FREQ_445MHz 445500000 #define IMX335_NUM_DATA_LANES 4 #define IMX335_REG_MIN 0x00 @@ -99,7 +100,6 @@ static const char * const imx335_supply_name[] = { * @vblank_min: Minimum vertical blanking in lines * @vblank_max: Maximum vertical blanking in lines * @pclk: Sensor pixel clock - * @link_freq_idx: Link frequency index * @reg_list: Register list for sensor mode */ struct imx335_mode { @@ -111,7 +111,6 @@ struct imx335_mode { u32 vblank_min; u32 vblank_max; u64 pclk; - u32 link_freq_idx; struct imx335_reg_list reg_list; }; @@ -133,6 +132,7 @@ struct imx335_mode { * @again_ctrl: Pointer to analog gain control * @vblank: Vertical blanking in lines * @cur_mode: Pointer to current selected sensor mode + * @link_freq_idx: Selected link frequency index * @mutex: Mutex for serializing sensor controls */ struct imx335 { @@ -155,20 +155,16 @@ struct imx335 { }; u32 vblank; const struct imx335_mode *cur_mode; + u32 link_freq_idx; struct mutex mutex; u32 cur_mbus_code; }; -static const s64 link_freq[] = { - IMX335_LINK_FREQ, -}; /* Sensor mode registers */ static const struct imx335_reg mode_2592x1940_regs[] = { {0x3000, 0x01}, {0x3002, 0x00}, - {0x300c, 0x3b}, - {0x300d, 0x2a}, {0x3018, 0x04}, {0x302c, 0x3c}, {0x302e, 0x20}, @@ -176,10 +172,6 @@ static const struct imx335_reg mode_2592x1940_regs[] = { {0x3074, 0xc8}, {0x3076, 0x28}, {0x304c, 0x00}, - {0x314c, 0xc6}, - {0x315a, 0x02}, - {0x3168, 0xa0}, - {0x316a, 0x7e}, {0x31a1, 0x00}, {0x3288, 0x21}, {0x328a, 0x02}, @@ -265,6 +257,46 @@ static const struct imx335_reg raw12_framefmt_regs[] = { {0x341d, 0x00}, }; +static const struct imx335_reg mipi_data_rate_1188Mbps[] = { + {0x300c, 0x3b}, + {0x300d, 0x2a}, + {0x314c, 0xc6}, + {0x314d, 0x00}, + {0x315a, 0x02}, + {0x3168, 0xa0}, + {0x316a, 0x7e}, + {0x319e, 0x01}, +}; + +static const struct imx335_reg mipi_data_rate_891Mbps[] = { + {0x300c, 0x3b}, + {0x300d, 0x2a}, + {0x314c, 0x29}, + {0x314d, 0x01}, + {0x315a, 0x06}, + {0x3168, 0xa0}, + {0x316a, 0x7e}, + {0x319e, 0x02}, +}; + +static const s64 link_freq[] = { + /* Corresponds to 1188Mbps data lane rate */ + IMX335_LINK_FREQ_594MHz, + /* Corresponds to 891Mbps data lane rate */ + IMX335_LINK_FREQ_445MHz, +}; + +static const struct imx335_reg_list link_freq_reglist[] = { + { + .num_of_regs = ARRAY_SIZE(mipi_data_rate_1188Mbps), + .regs = mipi_data_rate_1188Mbps, + }, + { + .num_of_regs = ARRAY_SIZE(mipi_data_rate_891Mbps), + .regs = mipi_data_rate_891Mbps, + }, +}; + static const u32 imx335_mbus_codes[] = { MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB10_1X10, @@ -279,7 +311,6 @@ static const struct imx335_mode supported_mode = { .vblank_min = 2560, .vblank_max = 133060, .pclk = 396000000, - .link_freq_idx = 0, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2592x1940_regs), .regs = mode_2592x1940_regs, @@ -404,7 +435,7 @@ static int imx335_update_controls(struct imx335 *imx335, { int ret; - ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl, mode->link_freq_idx); + ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl, imx335->link_freq_idx); if (ret) return ret; @@ -754,6 +785,14 @@ static int imx335_start_streaming(struct imx335 *imx335) const struct imx335_reg_list *reg_list; int ret; + /* Setup PLL */ + reg_list = &link_freq_reglist[imx335->link_freq_idx]; + ret = imx335_write_regs(imx335, reg_list->regs, reg_list->num_of_regs); + if (ret) { + dev_err(imx335->dev, "%s failed to set plls\n", __func__); + return ret; + } + /* Write sensor mode registers */ reg_list = &imx335->cur_mode->reg_list; ret = imx335_write_regs(imx335, reg_list->regs, @@ -880,7 +919,7 @@ static int imx335_parse_hw_config(struct imx335 *imx335) }; struct fwnode_handle *ep; unsigned long rate; - unsigned int i; + unsigned int i, j; int ret; if (!fwnode) @@ -944,13 +983,21 @@ static int imx335_parse_hw_config(struct imx335 *imx335) goto done_endpoint_free; } - for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) - if (bus_cfg.link_frequencies[i] == IMX335_LINK_FREQ) - goto done_endpoint_free; - dev_err(imx335->dev, "no compatible link frequencies found\n"); + for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { + for (j = 0; j < ARRAY_SIZE(link_freq); j++) { + if (bus_cfg.link_frequencies[i] == link_freq[j]) { + imx335->link_freq_idx = j; + break; + } + } - ret = -EINVAL; + if (j == ARRAY_SIZE(link_freq)) { + ret = dev_err_probe(imx335->dev, -EINVAL, + "no supported link freq found\n"); + goto done_endpoint_free; + } + } done_endpoint_free: v4l2_fwnode_endpoint_free(&bus_cfg); @@ -1097,7 +1144,7 @@ static int imx335_init_controls(struct imx335 *imx335) V4L2_CID_LINK_FREQ, ARRAY_SIZE(link_freq) - 1, - mode->link_freq_idx, + imx335->link_freq_idx, link_freq); if (imx335->link_freq_ctrl) imx335->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;