From patchwork Fri Sep 16 13:57:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 12978563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5803FECAAD8 for ; Fri, 16 Sep 2022 13:57:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229750AbiIPN52 (ORCPT ); Fri, 16 Sep 2022 09:57:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229601AbiIPN50 (ORCPT ); Fri, 16 Sep 2022 09:57:26 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B3282EF34 for ; Fri, 16 Sep 2022 06:57:25 -0700 (PDT) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oZBqJ-0002SU-TD; Fri, 16 Sep 2022 15:57:19 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1oZBqK-0015yN-Kk; Fri, 16 Sep 2022 15:57:19 +0200 Received: from mfe by dude02.red.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from ) id 1oZBqI-000bS0-7l; Fri, 16 Sep 2022 15:57:18 +0200 From: Marco Felsch To: mchehab@kernel.org, sakari.ailus@linux.intel.com, laurent.pinchart+renesas@ideasonboard.com, akinobu.mita@gmail.com, jacopo+renesas@jmondi.org Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] media: mt9m111: add V4L2_CID_LINK_FREQ support Date: Fri, 16 Sep 2022 15:57:11 +0200 Message-Id: <20220916135713.143890-1-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add support to report the link frequency. Signed-off-by: Marco Felsch --- The v1 of this small series can be found here: https://lore.kernel.org/all/20220818144712.997477-1-m.felsch@pengutronix.de/ Thanks a lot to Jacopo for the review feedback on my v1. Changelog: v2: - use V4L2_CID_LINK_FREQ instead of V4L2_CID_PIXEL_RATE --- drivers/media/i2c/mt9m111.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index afc86efa9e3e..52be1c310455 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -1249,6 +1249,8 @@ static int mt9m111_probe(struct i2c_client *client) { struct mt9m111 *mt9m111; struct i2c_adapter *adapter = client->adapter; + static s64 extclk_rate; + struct v4l2_ctrl *ctrl; int ret; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { @@ -1271,6 +1273,13 @@ static int mt9m111_probe(struct i2c_client *client) if (IS_ERR(mt9m111->clk)) return PTR_ERR(mt9m111->clk); + ret = clk_prepare_enable(mt9m111->clk); + if (ret < 0) + return ret; + + extclk_rate = clk_get_rate(mt9m111->clk); + clk_disable_unprepare(mt9m111->clk); + mt9m111->regulator = devm_regulator_get(&client->dev, "vdd"); if (IS_ERR(mt9m111->regulator)) { dev_err(&client->dev, "regulator not found: %ld\n", @@ -1285,7 +1294,7 @@ static int mt9m111_probe(struct i2c_client *client) mt9m111->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; - v4l2_ctrl_handler_init(&mt9m111->hdl, 7); + v4l2_ctrl_handler_init(&mt9m111->hdl, 8); v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops, @@ -1309,6 +1318,16 @@ static int mt9m111_probe(struct i2c_client *client) BIT(V4L2_COLORFX_NEGATIVE) | BIT(V4L2_COLORFX_SOLARIZATION)), V4L2_COLORFX_NONE); + /* + * The extclk rate equals the link freq. if reg default values are used, + * which is the case. This must be adapted as soon as we don't use the + * default values anymore. + */ + ctrl = v4l2_ctrl_new_int_menu(&mt9m111->hdl, &mt9m111_ctrl_ops, + V4L2_CID_LINK_FREQ, 0, 0, &extclk_rate); + if (ctrl) + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + mt9m111->subdev.ctrl_handler = &mt9m111->hdl; if (mt9m111->hdl.error) { ret = mt9m111->hdl.error; From patchwork Fri Sep 16 13:57:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 12978565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7EC8ECAAD8 for ; Fri, 16 Sep 2022 13:57:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229804AbiIPN5a (ORCPT ); Fri, 16 Sep 2022 09:57:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54544 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229881AbiIPN51 (ORCPT ); Fri, 16 Sep 2022 09:57:27 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C33EA3AE68 for ; Fri, 16 Sep 2022 06:57:25 -0700 (PDT) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oZBqK-0002SY-BW; Fri, 16 Sep 2022 15:57:20 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1oZBqL-0015yQ-2y; Fri, 16 Sep 2022 15:57:19 +0200 Received: from mfe by dude02.red.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from ) id 1oZBqI-000bS2-8a; Fri, 16 Sep 2022 15:57:18 +0200 From: Marco Felsch To: mchehab@kernel.org, sakari.ailus@linux.intel.com, laurent.pinchart+renesas@ideasonboard.com, akinobu.mita@gmail.com, jacopo+renesas@jmondi.org Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/3] media: mt9m111: fix device power usage Date: Fri, 16 Sep 2022 15:57:12 +0200 Message-Id: <20220916135713.143890-2-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220916135713.143890-1-m.felsch@pengutronix.de> References: <20220916135713.143890-1-m.felsch@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Currently the driver turn off the power after probe and toggle it during .stream by using the .s_power callback. This is problematic since other callbacks like .set_fmt accessing the hardware as well which will fail. So in the end the default format is the only supported format. Remove the hardware register access from the callbacks and instead sync the state once right before the stream gets enabled to fix this for .set_fmt() and .set_selection(). For the debug register access we need to turn the device on/off before accessing the registers to fix this and finally for the ctrls access we need the device to be powered to fix this. Signed-off-by: Marco Felsch Reviewed-by: Jacopo Mondi --- Changelog: v2: - squash patch 2 and 3 --- drivers/media/i2c/mt9m111.c | 40 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 52be1c310455..8de93ab99cbc 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -455,7 +455,7 @@ static int mt9m111_set_selection(struct v4l2_subdev *sd, struct mt9m111 *mt9m111 = to_mt9m111(client); struct v4l2_rect rect = sel->r; int width, height; - int ret, align = 0; + int align = 0; if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || sel->target != V4L2_SEL_TGT_CROP) @@ -481,14 +481,11 @@ static int mt9m111_set_selection(struct v4l2_subdev *sd, width = min(mt9m111->width, rect.width); height = min(mt9m111->height, rect.height); - ret = mt9m111_setup_geometry(mt9m111, &rect, width, height, mt9m111->fmt->code); - if (!ret) { - mt9m111->rect = rect; - mt9m111->width = width; - mt9m111->height = height; - } + mt9m111->rect = rect; + mt9m111->width = width; + mt9m111->height = height; - return ret; + return 0; } static int mt9m111_get_selection(struct v4l2_subdev *sd, @@ -632,7 +629,6 @@ static int mt9m111_set_fmt(struct v4l2_subdev *sd, const struct mt9m111_datafmt *fmt; struct v4l2_rect *rect = &mt9m111->rect; bool bayer; - int ret; if (mt9m111->is_streaming) return -EBUSY; @@ -681,16 +677,11 @@ static int mt9m111_set_fmt(struct v4l2_subdev *sd, return 0; } - ret = mt9m111_setup_geometry(mt9m111, rect, mf->width, mf->height, mf->code); - if (!ret) - ret = mt9m111_set_pixfmt(mt9m111, mf->code); - if (!ret) { - mt9m111->width = mf->width; - mt9m111->height = mf->height; - mt9m111->fmt = fmt; - } + mt9m111->width = mf->width; + mt9m111->height = mf->height; + mt9m111->fmt = fmt; - return ret; + return 0; } static const struct mt9m111_mode_info * @@ -748,6 +739,8 @@ mt9m111_find_mode(struct mt9m111 *mt9m111, unsigned int req_fps, return mode; } +static int mt9m111_s_power(struct v4l2_subdev *sd, int on); + #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9m111_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -758,10 +751,14 @@ static int mt9m111_g_register(struct v4l2_subdev *sd, if (reg->reg > 0x2ff) return -EINVAL; + mt9m111_s_power(sd, 1); + val = mt9m111_reg_read(client, reg->reg); reg->size = 2; reg->val = (u64)val; + mt9m111_s_power(sd, 0); + if (reg->val > 0xffff) return -EIO; @@ -776,9 +773,13 @@ static int mt9m111_s_register(struct v4l2_subdev *sd, if (reg->reg > 0x2ff) return -EINVAL; + mt9m111_s_power(sd, 1); + if (mt9m111_reg_write(client, reg->reg, reg->val) < 0) return -EIO; + mt9m111_s_power(sd, 0); + return 0; } #endif @@ -891,6 +892,9 @@ static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl) struct mt9m111 *mt9m111 = container_of(ctrl->handler, struct mt9m111, hdl); + if (!mt9m111->is_streaming) + return 0; + switch (ctrl->id) { case V4L2_CID_VFLIP: return mt9m111_set_flip(mt9m111, ctrl->val, From patchwork Fri Sep 16 13:57:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Felsch X-Patchwork-Id: 12978564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5010AC6FA82 for ; Fri, 16 Sep 2022 13:57:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230338AbiIPN53 (ORCPT ); Fri, 16 Sep 2022 09:57:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54544 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229712AbiIPN50 (ORCPT ); Fri, 16 Sep 2022 09:57:26 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C2101FCDD for ; Fri, 16 Sep 2022 06:57:25 -0700 (PDT) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oZBqJ-0002ST-Qg; Fri, 16 Sep 2022 15:57:19 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1oZBqK-0015yK-Bt; Fri, 16 Sep 2022 15:57:18 +0200 Received: from mfe by dude02.red.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from ) id 1oZBqI-000bS5-9I; Fri, 16 Sep 2022 15:57:18 +0200 From: Marco Felsch To: mchehab@kernel.org, sakari.ailus@linux.intel.com, laurent.pinchart+renesas@ideasonboard.com, akinobu.mita@gmail.com, jacopo+renesas@jmondi.org Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] media: mt9m111: don't turn on the output while powering it Date: Fri, 16 Sep 2022 15:57:13 +0200 Message-Id: <20220916135713.143890-3-m.felsch@pengutronix.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220916135713.143890-1-m.felsch@pengutronix.de> References: <20220916135713.143890-1-m.felsch@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mfe@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Currently the .s_power() turn on/off the device and enables/disables the sensor output. This is wrong since it should only handle the power not not the sensor output behaviour. Enabling the sensor output should be part of the .s_stream() callback. Fix this by adding mt9m111_set_output() which gets called by the .s_stream() callback and remove the output register bits from mt9m111_resume/suspend. Signed-off-by: Marco Felsch Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- Changelog: v2: - new patch, replaces: "media: mt9m111: remove .s_power callback" --- drivers/media/i2c/mt9m111.c | 38 ++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 8de93ab99cbc..2cc0b0da7636 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -426,10 +426,25 @@ static int mt9m111_setup_geometry(struct mt9m111 *mt9m111, struct v4l2_rect *rec return ret; } -static int mt9m111_enable(struct mt9m111 *mt9m111) +static int mt9m111_set_output(struct mt9m111 *mt9m111, int on) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); - return reg_write(RESET, MT9M111_RESET_CHIP_ENABLE); + int ret; + + if (on) { + ret = reg_clear(RESET, MT9M111_RESET_OUTPUT_DISABLE); + if (ret) + return ret; + + return reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); + } + + /* disable */ + ret = reg_set(RESET, MT9M111_RESET_OUTPUT_DISABLE); + if (ret) + return ret; + + return reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); } static int mt9m111_reset(struct mt9m111 *mt9m111) @@ -927,10 +942,7 @@ static int mt9m111_suspend(struct mt9m111 *mt9m111) ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); if (!ret) ret = reg_set(RESET, MT9M111_RESET_RESET_SOC | - MT9M111_RESET_OUTPUT_DISABLE | MT9M111_RESET_ANALOG_STANDBY); - if (!ret) - ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); return ret; } @@ -951,9 +963,9 @@ static void mt9m111_restore_state(struct mt9m111 *mt9m111) static int mt9m111_resume(struct mt9m111 *mt9m111) { - int ret = mt9m111_enable(mt9m111); - if (!ret) - ret = mt9m111_reset(mt9m111); + int ret; + + ret = mt9m111_reset(mt9m111); if (!ret) mt9m111_restore_state(mt9m111); @@ -965,9 +977,7 @@ static int mt9m111_init(struct mt9m111 *mt9m111) struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); int ret; - ret = mt9m111_enable(mt9m111); - if (!ret) - ret = mt9m111_reset(mt9m111); + ret = mt9m111_reset(mt9m111); if (!ret) ret = mt9m111_set_context(mt9m111, mt9m111->ctx); if (ret) @@ -1116,8 +1126,14 @@ static int mt9m111_enum_mbus_code(struct v4l2_subdev *sd, static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable) { struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); + int ret; + + ret = mt9m111_set_output(mt9m111, enable); + if (ret) + return ret; mt9m111->is_streaming = !!enable; + return 0; }