From patchwork Mon Aug 21 22:29:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715619 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 6A1A1EE49A5 for ; Mon, 21 Aug 2023 22:30:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231536AbjHUWaC (ORCPT ); Mon, 21 Aug 2023 18:30:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231401AbjHUWaB (ORCPT ); Mon, 21 Aug 2023 18:30:01 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAA69185 for ; Mon, 21 Aug 2023 15:29:57 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C7A1429C2; Tue, 22 Aug 2023 00:28:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656920; bh=DnKRUGoxmxoPOD7ycrCkMjs4BVwje2pHWfHviYftFtk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f5G4poHKC4hqHWyvBJ4q2XB+ErS5KRRr0SvjEMx6Uon/xm130DoVzyHFdRVuw3XY4 95CVFIG0J4Jxti/41gAENPf02bddhkwdXuwOyPIvqMCZ+5g+HS18/k6sGE11+NWYX9 Px2kuis6s9W48SZ1dNSwHd67IF4Q3cZBz3YhPeHo= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 01/18] media: i2c: imx219: Convert to CCI register access helpers Date: Tue, 22 Aug 2023 01:29:44 +0300 Message-ID: <20230821223001.28480-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Use the new comon CCI register access helpers to replace the private register access helpers in the imx219 driver. This simplifies the driver by reducing the amount of code. Signed-off-by: Laurent Pinchart Reviewed-by: Dave Stevenson --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/imx219.c | 515 ++++++++++++++++--------------------- 2 files changed, 221 insertions(+), 295 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 226454b6a90d..f7cea5c53ead 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -118,6 +118,7 @@ config VIDEO_IMX219 depends on I2C && VIDEO_DEV select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API + select V4L2_CCI_I2C select V4L2_FWNODE help This is a Video4Linux2 sensor driver for the Sony diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index ec53abe2e84e..c5aeec50b9e8 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -21,40 +21,49 @@ #include #include #include + +#include #include #include #include #include #include -#include -#define IMX219_REG_VALUE_08BIT 1 -#define IMX219_REG_VALUE_16BIT 2 +/* Chip ID */ +#define IMX219_REG_CHIP_ID CCI_REG16(0x0000) +#define IMX219_CHIP_ID 0x0219 -#define IMX219_REG_MODE_SELECT 0x0100 +#define IMX219_REG_MODE_SELECT CCI_REG8(0x0100) #define IMX219_MODE_STANDBY 0x00 #define IMX219_MODE_STREAMING 0x01 -/* Chip ID */ -#define IMX219_REG_CHIP_ID 0x0000 -#define IMX219_CHIP_ID 0x0219 - -/* External clock frequency is 24.0M */ -#define IMX219_XCLK_FREQ 24000000 - -/* Pixel rate is fixed for all the modes */ -#define IMX219_PIXEL_RATE 182400000 -#define IMX219_PIXEL_RATE_4LANE 280800000 - -#define IMX219_DEFAULT_LINK_FREQ 456000000 -#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000 - -#define IMX219_REG_CSI_LANE_MODE 0x0114 +#define IMX219_REG_CSI_LANE_MODE CCI_REG8(0x0114) #define IMX219_CSI_2_LANE_MODE 0x01 #define IMX219_CSI_4_LANE_MODE 0x03 +/* Analog gain control */ +#define IMX219_REG_ANALOG_GAIN CCI_REG8(0x0157) +#define IMX219_ANA_GAIN_MIN 0 +#define IMX219_ANA_GAIN_MAX 232 +#define IMX219_ANA_GAIN_STEP 1 +#define IMX219_ANA_GAIN_DEFAULT 0x0 + +/* Digital gain control */ +#define IMX219_REG_DIGITAL_GAIN CCI_REG16(0x0158) +#define IMX219_DGTL_GAIN_MIN 0x0100 +#define IMX219_DGTL_GAIN_MAX 0x0fff +#define IMX219_DGTL_GAIN_DEFAULT 0x0100 +#define IMX219_DGTL_GAIN_STEP 1 + +/* Exposure control */ +#define IMX219_REG_EXPOSURE CCI_REG16(0x015a) +#define IMX219_EXPOSURE_MIN 4 +#define IMX219_EXPOSURE_STEP 1 +#define IMX219_EXPOSURE_DEFAULT 0x640 +#define IMX219_EXPOSURE_MAX 65535 + /* V_TIMING internal */ -#define IMX219_REG_VTS 0x0160 +#define IMX219_REG_VTS CCI_REG16(0x0160) #define IMX219_VTS_15FPS 0x0dc6 #define IMX219_VTS_30FPS_1080P 0x06e3 #define IMX219_VTS_30FPS_BINNED 0x06e3 @@ -72,37 +81,16 @@ /* HBLANK control - read only */ #define IMX219_PPL_DEFAULT 3448 -/* Exposure control */ -#define IMX219_REG_EXPOSURE 0x015a -#define IMX219_EXPOSURE_MIN 4 -#define IMX219_EXPOSURE_STEP 1 -#define IMX219_EXPOSURE_DEFAULT 0x640 -#define IMX219_EXPOSURE_MAX 65535 - -/* Analog gain control */ -#define IMX219_REG_ANALOG_GAIN 0x0157 -#define IMX219_ANA_GAIN_MIN 0 -#define IMX219_ANA_GAIN_MAX 232 -#define IMX219_ANA_GAIN_STEP 1 -#define IMX219_ANA_GAIN_DEFAULT 0x0 - -/* Digital gain control */ -#define IMX219_REG_DIGITAL_GAIN 0x0158 -#define IMX219_DGTL_GAIN_MIN 0x0100 -#define IMX219_DGTL_GAIN_MAX 0x0fff -#define IMX219_DGTL_GAIN_DEFAULT 0x0100 -#define IMX219_DGTL_GAIN_STEP 1 - -#define IMX219_REG_ORIENTATION 0x0172 +#define IMX219_REG_ORIENTATION CCI_REG8(0x0172) /* Binning Mode */ -#define IMX219_REG_BINNING_MODE 0x0174 +#define IMX219_REG_BINNING_MODE CCI_REG16(0x0174) #define IMX219_BINNING_NONE 0x0000 #define IMX219_BINNING_2X2 0x0101 #define IMX219_BINNING_2X2_ANALOG 0x0303 /* Test Pattern Control */ -#define IMX219_REG_TEST_PATTERN 0x0600 +#define IMX219_REG_TEST_PATTERN CCI_REG16(0x0600) #define IMX219_TEST_PATTERN_DISABLE 0 #define IMX219_TEST_PATTERN_SOLID_COLOR 1 #define IMX219_TEST_PATTERN_COLOR_BARS 2 @@ -110,10 +98,10 @@ #define IMX219_TEST_PATTERN_PN9 4 /* Test pattern colour components */ -#define IMX219_REG_TESTP_RED 0x0602 -#define IMX219_REG_TESTP_GREENR 0x0604 -#define IMX219_REG_TESTP_BLUE 0x0606 -#define IMX219_REG_TESTP_GREENB 0x0608 +#define IMX219_REG_TESTP_RED CCI_REG16(0x0602) +#define IMX219_REG_TESTP_GREENR CCI_REG16(0x0604) +#define IMX219_REG_TESTP_BLUE CCI_REG16(0x0606) +#define IMX219_REG_TESTP_GREENB CCI_REG16(0x0608) #define IMX219_TESTP_COLOUR_MIN 0 #define IMX219_TESTP_COLOUR_MAX 0x03ff #define IMX219_TESTP_COLOUR_STEP 1 @@ -122,6 +110,16 @@ #define IMX219_TESTP_BLUE_DEFAULT 0 #define IMX219_TESTP_GREENB_DEFAULT 0 +/* External clock frequency is 24.0M */ +#define IMX219_XCLK_FREQ 24000000 + +/* Pixel rate is fixed for all the modes */ +#define IMX219_PIXEL_RATE 182400000 +#define IMX219_PIXEL_RATE_4LANE 280800000 + +#define IMX219_DEFAULT_LINK_FREQ 456000000 +#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000 + /* IMX219 native and active pixel array size. */ #define IMX219_NATIVE_WIDTH 3296U #define IMX219_NATIVE_HEIGHT 2480U @@ -130,14 +128,9 @@ #define IMX219_PIXEL_ARRAY_WIDTH 3280U #define IMX219_PIXEL_ARRAY_HEIGHT 2464U -struct imx219_reg { - u16 address; - u8 val; -}; - struct imx219_reg_list { unsigned int num_of_regs; - const struct imx219_reg *regs; + const struct cci_reg_sequence *regs; }; /* Mode : resolution and related config&values */ @@ -160,53 +153,53 @@ struct imx219_mode { bool binning; }; -static const struct imx219_reg imx219_common_regs[] = { - {0x0100, 0x00}, /* Mode Select */ +static const struct cci_reg_sequence imx219_common_regs[] = { + { CCI_REG8(0x0100), 0x00 }, /* Mode Select */ /* To Access Addresses 3000-5fff, send the following commands */ - {0x30eb, 0x0c}, - {0x30eb, 0x05}, - {0x300a, 0xff}, - {0x300b, 0xff}, - {0x30eb, 0x05}, - {0x30eb, 0x09}, + { CCI_REG8(0x30eb), 0x0c }, + { CCI_REG8(0x30eb), 0x05 }, + { CCI_REG8(0x300a), 0xff }, + { CCI_REG8(0x300b), 0xff }, + { CCI_REG8(0x30eb), 0x05 }, + { CCI_REG8(0x30eb), 0x09 }, /* PLL Clock Table */ - {0x0301, 0x05}, /* VTPXCK_DIV */ - {0x0303, 0x01}, /* VTSYSCK_DIV */ - {0x0304, 0x03}, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ - {0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ - {0x0306, 0x00}, /* PLL_VT_MPY */ - {0x0307, 0x39}, - {0x030b, 0x01}, /* OP_SYS_CLK_DIV */ - {0x030c, 0x00}, /* PLL_OP_MPY */ - {0x030d, 0x72}, + { CCI_REG8(0x0301), 0x05 }, /* VTPXCK_DIV */ + { CCI_REG8(0x0303), 0x01 }, /* VTSYSCK_DIV */ + { CCI_REG8(0x0304), 0x03 }, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ + { CCI_REG8(0x0305), 0x03 }, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ + { CCI_REG8(0x0306), 0x00 }, /* PLL_VT_MPY */ + { CCI_REG8(0x0307), 0x39 }, + { CCI_REG8(0x030b), 0x01 }, /* OP_SYS_CLK_DIV */ + { CCI_REG8(0x030c), 0x00 }, /* PLL_OP_MPY */ + { CCI_REG8(0x030d), 0x72 }, /* Undocumented registers */ - {0x455e, 0x00}, - {0x471e, 0x4b}, - {0x4767, 0x0f}, - {0x4750, 0x14}, - {0x4540, 0x00}, - {0x47b4, 0x14}, - {0x4713, 0x30}, - {0x478b, 0x10}, - {0x478f, 0x10}, - {0x4793, 0x10}, - {0x4797, 0x0e}, - {0x479b, 0x0e}, + { CCI_REG8(0x455e), 0x00 }, + { CCI_REG8(0x471e), 0x4b }, + { CCI_REG8(0x4767), 0x0f }, + { CCI_REG8(0x4750), 0x14 }, + { CCI_REG8(0x4540), 0x00 }, + { CCI_REG8(0x47b4), 0x14 }, + { CCI_REG8(0x4713), 0x30 }, + { CCI_REG8(0x478b), 0x10 }, + { CCI_REG8(0x478f), 0x10 }, + { CCI_REG8(0x4793), 0x10 }, + { CCI_REG8(0x4797), 0x0e }, + { CCI_REG8(0x479b), 0x0e }, /* Frame Bank Register Group "A" */ - {0x0162, 0x0d}, /* Line_Length_A */ - {0x0163, 0x78}, - {0x0170, 0x01}, /* X_ODD_INC_A */ - {0x0171, 0x01}, /* Y_ODD_INC_A */ + { CCI_REG8(0x0162), 0x0d }, /* Line_Length_A */ + { CCI_REG8(0x0163), 0x78 }, + { CCI_REG8(0x0170), 0x01 }, /* X_ODD_INC_A */ + { CCI_REG8(0x0171), 0x01 }, /* Y_ODD_INC_A */ /* Output setup registers */ - {0x0114, 0x01}, /* CSI 2-Lane Mode */ - {0x0128, 0x00}, /* DPHY Auto Mode */ - {0x012a, 0x18}, /* EXCK_Freq */ - {0x012b, 0x00}, + { CCI_REG8(0x0114), 0x01 }, /* CSI 2-Lane Mode */ + { CCI_REG8(0x0128), 0x00 }, /* DPHY Auto Mode */ + { CCI_REG8(0x012a), 0x18 }, /* EXCK_Freq */ + { CCI_REG8(0x012b), 0x00 }, }; /* @@ -214,92 +207,92 @@ static const struct imx219_reg imx219_common_regs[] = { * driver. * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. */ -static const struct imx219_reg mode_3280x2464_regs[] = { - {0x0164, 0x00}, - {0x0165, 0x00}, - {0x0166, 0x0c}, - {0x0167, 0xcf}, - {0x0168, 0x00}, - {0x0169, 0x00}, - {0x016a, 0x09}, - {0x016b, 0x9f}, - {0x016c, 0x0c}, - {0x016d, 0xd0}, - {0x016e, 0x09}, - {0x016f, 0xa0}, - {0x0624, 0x0c}, - {0x0625, 0xd0}, - {0x0626, 0x09}, - {0x0627, 0xa0}, +static const struct cci_reg_sequence mode_3280x2464_regs[] = { + { CCI_REG8(0x0164), 0x00 }, + { CCI_REG8(0x0165), 0x00 }, + { CCI_REG8(0x0166), 0x0c }, + { CCI_REG8(0x0167), 0xcf }, + { CCI_REG8(0x0168), 0x00 }, + { CCI_REG8(0x0169), 0x00 }, + { CCI_REG8(0x016a), 0x09 }, + { CCI_REG8(0x016b), 0x9f }, + { CCI_REG8(0x016c), 0x0c }, + { CCI_REG8(0x016d), 0xd0 }, + { CCI_REG8(0x016e), 0x09 }, + { CCI_REG8(0x016f), 0xa0 }, + { CCI_REG8(0x0624), 0x0c }, + { CCI_REG8(0x0625), 0xd0 }, + { CCI_REG8(0x0626), 0x09 }, + { CCI_REG8(0x0627), 0xa0 }, }; -static const struct imx219_reg mode_1920_1080_regs[] = { - {0x0164, 0x02}, - {0x0165, 0xa8}, - {0x0166, 0x0a}, - {0x0167, 0x27}, - {0x0168, 0x02}, - {0x0169, 0xb4}, - {0x016a, 0x06}, - {0x016b, 0xeb}, - {0x016c, 0x07}, - {0x016d, 0x80}, - {0x016e, 0x04}, - {0x016f, 0x38}, - {0x0624, 0x07}, - {0x0625, 0x80}, - {0x0626, 0x04}, - {0x0627, 0x38}, +static const struct cci_reg_sequence mode_1920_1080_regs[] = { + { CCI_REG8(0x0164), 0x02 }, + { CCI_REG8(0x0165), 0xa8 }, + { CCI_REG8(0x0166), 0x0a }, + { CCI_REG8(0x0167), 0x27 }, + { CCI_REG8(0x0168), 0x02 }, + { CCI_REG8(0x0169), 0xb4 }, + { CCI_REG8(0x016a), 0x06 }, + { CCI_REG8(0x016b), 0xeb }, + { CCI_REG8(0x016c), 0x07 }, + { CCI_REG8(0x016d), 0x80 }, + { CCI_REG8(0x016e), 0x04 }, + { CCI_REG8(0x016f), 0x38 }, + { CCI_REG8(0x0624), 0x07 }, + { CCI_REG8(0x0625), 0x80 }, + { CCI_REG8(0x0626), 0x04 }, + { CCI_REG8(0x0627), 0x38 }, }; -static const struct imx219_reg mode_1640_1232_regs[] = { - {0x0164, 0x00}, - {0x0165, 0x00}, - {0x0166, 0x0c}, - {0x0167, 0xcf}, - {0x0168, 0x00}, - {0x0169, 0x00}, - {0x016a, 0x09}, - {0x016b, 0x9f}, - {0x016c, 0x06}, - {0x016d, 0x68}, - {0x016e, 0x04}, - {0x016f, 0xd0}, - {0x0624, 0x06}, - {0x0625, 0x68}, - {0x0626, 0x04}, - {0x0627, 0xd0}, +static const struct cci_reg_sequence mode_1640_1232_regs[] = { + { CCI_REG8(0x0164), 0x00 }, + { CCI_REG8(0x0165), 0x00 }, + { CCI_REG8(0x0166), 0x0c }, + { CCI_REG8(0x0167), 0xcf }, + { CCI_REG8(0x0168), 0x00 }, + { CCI_REG8(0x0169), 0x00 }, + { CCI_REG8(0x016a), 0x09 }, + { CCI_REG8(0x016b), 0x9f }, + { CCI_REG8(0x016c), 0x06 }, + { CCI_REG8(0x016d), 0x68 }, + { CCI_REG8(0x016e), 0x04 }, + { CCI_REG8(0x016f), 0xd0 }, + { CCI_REG8(0x0624), 0x06 }, + { CCI_REG8(0x0625), 0x68 }, + { CCI_REG8(0x0626), 0x04 }, + { CCI_REG8(0x0627), 0xd0 }, }; -static const struct imx219_reg mode_640_480_regs[] = { - {0x0164, 0x03}, - {0x0165, 0xe8}, - {0x0166, 0x08}, - {0x0167, 0xe7}, - {0x0168, 0x02}, - {0x0169, 0xf0}, - {0x016a, 0x06}, - {0x016b, 0xaf}, - {0x016c, 0x02}, - {0x016d, 0x80}, - {0x016e, 0x01}, - {0x016f, 0xe0}, - {0x0624, 0x06}, - {0x0625, 0x68}, - {0x0626, 0x04}, - {0x0627, 0xd0}, +static const struct cci_reg_sequence mode_640_480_regs[] = { + { CCI_REG8(0x0164), 0x03 }, + { CCI_REG8(0x0165), 0xe8 }, + { CCI_REG8(0x0166), 0x08 }, + { CCI_REG8(0x0167), 0xe7 }, + { CCI_REG8(0x0168), 0x02 }, + { CCI_REG8(0x0169), 0xf0 }, + { CCI_REG8(0x016a), 0x06 }, + { CCI_REG8(0x016b), 0xaf }, + { CCI_REG8(0x016c), 0x02 }, + { CCI_REG8(0x016d), 0x80 }, + { CCI_REG8(0x016e), 0x01 }, + { CCI_REG8(0x016f), 0xe0 }, + { CCI_REG8(0x0624), 0x06 }, + { CCI_REG8(0x0625), 0x68 }, + { CCI_REG8(0x0626), 0x04 }, + { CCI_REG8(0x0627), 0xd0 }, }; -static const struct imx219_reg raw8_framefmt_regs[] = { - {0x018c, 0x08}, - {0x018d, 0x08}, - {0x0309, 0x08}, +static const struct cci_reg_sequence raw8_framefmt_regs[] = { + { CCI_REG8(0x018c), 0x08 }, + { CCI_REG8(0x018d), 0x08 }, + { CCI_REG8(0x0309), 0x08 }, }; -static const struct imx219_reg raw10_framefmt_regs[] = { - {0x018c, 0x0a}, - {0x018d, 0x0a}, - {0x0309, 0x0a}, +static const struct cci_reg_sequence raw10_framefmt_regs[] = { + { CCI_REG8(0x018c), 0x0a }, + { CCI_REG8(0x018d), 0x0a }, + { CCI_REG8(0x0309), 0x0a }, }; static const s64 imx219_link_freq_menu[] = { @@ -460,6 +453,7 @@ struct imx219 { struct v4l2_subdev sd; struct media_pad pad; + struct regmap *regmap; struct clk *xclk; /* system clock to IMX219 */ u32 xclk_freq; @@ -491,78 +485,6 @@ static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd) return container_of(_sd, struct imx219, sd); } -/* Read registers up to 2 at a time */ -static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - struct i2c_msg msgs[2]; - u8 addr_buf[2] = { reg >> 8, reg & 0xff }; - u8 data_buf[4] = { 0, }; - int ret; - - if (len > 4) - return -EINVAL; - - /* Write register address */ - msgs[0].addr = client->addr; - msgs[0].flags = 0; - msgs[0].len = ARRAY_SIZE(addr_buf); - msgs[0].buf = addr_buf; - - /* Read data from register */ - msgs[1].addr = client->addr; - msgs[1].flags = I2C_M_RD; - msgs[1].len = len; - msgs[1].buf = &data_buf[4 - len]; - - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret != ARRAY_SIZE(msgs)) - return -EIO; - - *val = get_unaligned_be32(data_buf); - - return 0; -} - -/* Write registers up to 2 at a time */ -static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - u8 buf[6]; - - if (len > 4) - return -EINVAL; - - put_unaligned_be16(reg, buf); - put_unaligned_be32(val << (8 * (4 - len)), buf + 2); - if (i2c_master_send(client, buf, len + 2) != len + 2) - return -EIO; - - return 0; -} - -/* Write a list of registers */ -static int imx219_write_regs(struct imx219 *imx219, - const struct imx219_reg *regs, u32 len) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - unsigned int i; - int ret; - - for (i = 0; i < len; i++) { - ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val); - if (ret) { - dev_err_ratelimited(&client->dev, - "Failed to write reg 0x%4.4x. error = %d\n", - regs[i].address, ret); - - return ret; - } - } - - return 0; -} - /* Get bayer order based on flip setting. */ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) { @@ -586,7 +508,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) struct imx219 *imx219 = container_of(ctrl->handler, struct imx219, ctrl_handler); struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - int ret; + int ret = 0; if (ctrl->id == V4L2_CID_VBLANK) { int exposure_max, exposure_def; @@ -610,48 +532,45 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_ANALOGUE_GAIN: - ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN, - IMX219_REG_VALUE_08BIT, ctrl->val); + cci_write(imx219->regmap, IMX219_REG_ANALOG_GAIN, + ctrl->val, &ret); break; case V4L2_CID_EXPOSURE: - ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE, - IMX219_REG_VALUE_16BIT, ctrl->val); + cci_write(imx219->regmap, IMX219_REG_EXPOSURE, + ctrl->val, &ret); break; case V4L2_CID_DIGITAL_GAIN: - ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN, - IMX219_REG_VALUE_16BIT, ctrl->val); + cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN, + ctrl->val, &ret); break; case V4L2_CID_TEST_PATTERN: - ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN, - IMX219_REG_VALUE_16BIT, - imx219_test_pattern_val[ctrl->val]); + cci_write(imx219->regmap, IMX219_REG_TEST_PATTERN, + imx219_test_pattern_val[ctrl->val], &ret); break; case V4L2_CID_HFLIP: case V4L2_CID_VFLIP: - ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1, - imx219->hflip->val | - imx219->vflip->val << 1); + cci_write(imx219->regmap, IMX219_REG_ORIENTATION, + imx219->hflip->val | imx219->vflip->val << 1, &ret); break; case V4L2_CID_VBLANK: - ret = imx219_write_reg(imx219, IMX219_REG_VTS, - IMX219_REG_VALUE_16BIT, - imx219->mode->height + ctrl->val); + cci_write(imx219->regmap, IMX219_REG_VTS, + imx219->mode->height + ctrl->val, &ret); break; case V4L2_CID_TEST_PATTERN_RED: - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED, - IMX219_REG_VALUE_16BIT, ctrl->val); + cci_write(imx219->regmap, IMX219_REG_TESTP_RED, + ctrl->val, &ret); break; case V4L2_CID_TEST_PATTERN_GREENR: - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR, - IMX219_REG_VALUE_16BIT, ctrl->val); + cci_write(imx219->regmap, IMX219_REG_TESTP_GREENR, + ctrl->val, &ret); break; case V4L2_CID_TEST_PATTERN_BLUE: - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE, - IMX219_REG_VALUE_16BIT, ctrl->val); + cci_write(imx219->regmap, IMX219_REG_TESTP_BLUE, + ctrl->val, &ret); break; case V4L2_CID_TEST_PATTERN_GREENB: - ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB, - IMX219_REG_VALUE_16BIT, ctrl->val); + cci_write(imx219->regmap, IMX219_REG_TESTP_GREENB, + ctrl->val, &ret); break; default: dev_info(&client->dev, @@ -802,15 +721,15 @@ static int imx219_set_framefmt(struct imx219 *imx219, case MEDIA_BUS_FMT_SGRBG8_1X8: case MEDIA_BUS_FMT_SGBRG8_1X8: case MEDIA_BUS_FMT_SBGGR8_1X8: - return imx219_write_regs(imx219, raw8_framefmt_regs, - ARRAY_SIZE(raw8_framefmt_regs)); + return cci_multi_reg_write(imx219->regmap, raw8_framefmt_regs, + ARRAY_SIZE(raw8_framefmt_regs), NULL); case MEDIA_BUS_FMT_SRGGB10_1X10: case MEDIA_BUS_FMT_SGRBG10_1X10: case MEDIA_BUS_FMT_SGBRG10_1X10: case MEDIA_BUS_FMT_SBGGR10_1X10: - return imx219_write_regs(imx219, raw10_framefmt_regs, - ARRAY_SIZE(raw10_framefmt_regs)); + return cci_multi_reg_write(imx219->regmap, raw10_framefmt_regs, + ARRAY_SIZE(raw10_framefmt_regs), NULL); } return -EINVAL; @@ -819,28 +738,24 @@ static int imx219_set_framefmt(struct imx219 *imx219, static int imx219_set_binning(struct imx219 *imx219, const struct v4l2_mbus_framefmt *format) { - if (!imx219->mode->binning) { - return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, - IMX219_REG_VALUE_16BIT, - IMX219_BINNING_NONE); - } + if (!imx219->mode->binning) + return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, + IMX219_BINNING_NONE, NULL); switch (format->code) { case MEDIA_BUS_FMT_SRGGB8_1X8: case MEDIA_BUS_FMT_SGRBG8_1X8: case MEDIA_BUS_FMT_SGBRG8_1X8: case MEDIA_BUS_FMT_SBGGR8_1X8: - return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, - IMX219_REG_VALUE_16BIT, - IMX219_BINNING_2X2_ANALOG); + return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, + IMX219_BINNING_2X2_ANALOG, NULL); case MEDIA_BUS_FMT_SRGGB10_1X10: case MEDIA_BUS_FMT_SGRBG10_1X10: case MEDIA_BUS_FMT_SGBRG10_1X10: case MEDIA_BUS_FMT_SBGGR10_1X10: - return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE, - IMX219_REG_VALUE_16BIT, - IMX219_BINNING_2X2); + return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, + IMX219_BINNING_2X2, NULL); } return -EINVAL; @@ -879,9 +794,9 @@ static int imx219_get_selection(struct v4l2_subdev *sd, static int imx219_configure_lanes(struct imx219 *imx219) { - return imx219_write_reg(imx219, IMX219_REG_CSI_LANE_MODE, - IMX219_REG_VALUE_08BIT, (imx219->lanes == 2) ? - IMX219_CSI_2_LANE_MODE : IMX219_CSI_4_LANE_MODE); + return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE, + imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE : + IMX219_CSI_4_LANE_MODE, NULL); }; static int imx219_start_streaming(struct imx219 *imx219, @@ -897,7 +812,8 @@ static int imx219_start_streaming(struct imx219 *imx219, return ret; /* Send all registers that are common to all modes */ - ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs)); + ret = cci_multi_reg_write(imx219->regmap, imx219_common_regs, + ARRAY_SIZE(imx219_common_regs), NULL); if (ret) { dev_err(&client->dev, "%s failed to send mfg header\n", __func__); goto err_rpm_put; @@ -912,7 +828,8 @@ static int imx219_start_streaming(struct imx219 *imx219, /* Apply default values of current mode */ reg_list = &imx219->mode->reg_list; - ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); + ret = cci_multi_reg_write(imx219->regmap, reg_list->regs, + reg_list->num_of_regs, NULL); if (ret) { dev_err(&client->dev, "%s failed to set mode\n", __func__); goto err_rpm_put; @@ -939,8 +856,8 @@ static int imx219_start_streaming(struct imx219 *imx219, goto err_rpm_put; /* set stream on register */ - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, - IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, + IMX219_MODE_STREAMING, NULL); if (ret) goto err_rpm_put; @@ -961,8 +878,8 @@ static void imx219_stop_streaming(struct imx219 *imx219) int ret; /* set stream off register */ - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, - IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY); + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, + IMX219_MODE_STANDBY, NULL); if (ret) dev_err(&client->dev, "%s failed to set stream\n", __func__); @@ -1101,10 +1018,9 @@ static int imx219_identify_module(struct imx219 *imx219) { struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); int ret; - u32 val; + u64 val; - ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID, - IMX219_REG_VALUE_16BIT, &val); + ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL); if (ret) { dev_err(&client->dev, "failed to read chip id %x\n", IMX219_CHIP_ID); @@ -1112,7 +1028,7 @@ static int imx219_identify_module(struct imx219 *imx219) } if (val != IMX219_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x\n", + dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", IMX219_CHIP_ID, val); return -EIO; } @@ -1336,6 +1252,13 @@ static int imx219_probe(struct i2c_client *client) if (imx219_check_hwcfg(dev, imx219)) return -EINVAL; + imx219->regmap = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(imx219->regmap)) { + ret = PTR_ERR(imx219->regmap); + dev_err(dev, "failed to initialize CCI: %d\n", ret); + return ret; + } + /* Get system clock (xclk) */ imx219->xclk = devm_clk_get(dev, NULL); if (IS_ERR(imx219->xclk)) { @@ -1379,17 +1302,19 @@ static int imx219_probe(struct i2c_client *client) * streaming is started, so upon power up switch the modes to: * streaming -> standby */ - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, - IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING); + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, + IMX219_MODE_STREAMING, NULL); if (ret < 0) goto error_power_off; + usleep_range(100, 110); /* put sensor back to standby mode */ - ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, - IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY); + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, + IMX219_MODE_STANDBY, NULL); if (ret < 0) goto error_power_off; + usleep_range(100, 110); ret = imx219_init_controls(imx219); From patchwork Mon Aug 21 22:29:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715618 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 53B03EE4996 for ; Mon, 21 Aug 2023 22:30:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231549AbjHUWaF (ORCPT ); Mon, 21 Aug 2023 18:30:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39320 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231461AbjHUWaF (ORCPT ); Mon, 21 Aug 2023 18:30:05 -0400 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 77E2CE4 for ; Mon, 21 Aug 2023 15:30:02 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ACFD638B3; Tue, 22 Aug 2023 00:28:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656922; bh=0tQWMyhl7CJmU+o2ExT0uf6RJqm8iK7F75ztd6ayIE4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VDvAOu+I2epfSZTdEEAjEAbCJOM1voHqIiLEN+0Zw6P/Dz4A2B2j5eeEkHQDpW5bK mAuV+2hdRKYk1YbmY3Se1Y7VrZqb4Hcc4JliDJYPeSdnWzpCPg+K7me2La0rh26zK7 UDsrtetjjQqLlrnK/5vDNC6B49iB34yh5rzqhfRY= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 03/18] media: i2c: imx219: Replace register addresses with macros Date: Tue, 22 Aug 2023 01:29:46 +0300 Message-ID: <20230821223001.28480-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Define macros for all the known registers used in the register arrays, and use them to replace the numerical addresses. This improves readability. Signed-off-by: Laurent Pinchart Reviewed-by: Dave Stevenson --- drivers/media/i2c/imx219.c | 169 ++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 88 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 229dfe24304b..8cab0251bd6a 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -41,6 +41,13 @@ #define IMX219_CSI_2_LANE_MODE 0x01 #define IMX219_CSI_4_LANE_MODE 0x03 +#define IMX219_REG_DPHY_CTRL CCI_REG8(0x0128) +#define IMX219_DPHY_CTRL_TIMING_AUTO 0 +#define IMX219_DPHY_CTRL_TIMING_MANUAL 1 + +#define IMX219_REG_EXCK_FREQ CCI_REG16(0x012a) +#define IMX219_EXCK_FREQ(n) ((n) * 256) /* n expressed in MHz */ + /* Analog gain control */ #define IMX219_REG_ANALOG_GAIN CCI_REG8(0x0157) #define IMX219_ANA_GAIN_MIN 0 @@ -75,6 +82,15 @@ /* HBLANK control - read only */ #define IMX219_PPL_DEFAULT 3448 +#define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) +#define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) +#define IMX219_REG_X_ADD_END_A CCI_REG16(0x0166) +#define IMX219_REG_Y_ADD_STA_A CCI_REG16(0x0168) +#define IMX219_REG_Y_ADD_END_A CCI_REG16(0x016a) +#define IMX219_REG_X_OUTPUT_SIZE CCI_REG16(0x016c) +#define IMX219_REG_Y_OUTPUT_SIZE CCI_REG16(0x016e) +#define IMX219_REG_X_ODD_INC_A CCI_REG8(0x0170) +#define IMX219_REG_Y_ODD_INC_A CCI_REG8(0x0171) #define IMX219_REG_ORIENTATION CCI_REG8(0x0172) /* Binning Mode */ @@ -83,6 +99,18 @@ #define IMX219_BINNING_2X2 0x0101 #define IMX219_BINNING_2X2_ANALOG 0x0303 +#define IMX219_REG_CSI_DATA_FORMAT_A CCI_REG16(0x018c) + +/* PLL Settings */ +#define IMX219_REG_VTPXCK_DIV CCI_REG8(0x0301) +#define IMX219_REG_VTSYCK_DIV CCI_REG8(0x0303) +#define IMX219_REG_PREPLLCK_VT_DIV CCI_REG8(0x0304) +#define IMX219_REG_PREPLLCK_OP_DIV CCI_REG8(0x0305) +#define IMX219_REG_PLL_VT_MPY CCI_REG16(0x0306) +#define IMX219_REG_OPPXCK_DIV CCI_REG8(0x0309) +#define IMX219_REG_OPSYCK_DIV CCI_REG8(0x030b) +#define IMX219_REG_PLL_OP_MPY CCI_REG16(0x030c) + /* Test Pattern Control */ #define IMX219_REG_TEST_PATTERN CCI_REG16(0x0600) #define IMX219_TEST_PATTERN_DISABLE 0 @@ -100,6 +128,9 @@ #define IMX219_TESTP_COLOUR_MAX 0x03ff #define IMX219_TESTP_COLOUR_STEP 1 +#define IMX219_REG_TP_WINDOW_WIDTH CCI_REG16(0x0624) +#define IMX219_REG_TP_WINDOW_HEIGHT CCI_REG16(0x0626) + /* External clock frequency is 24.0M */ #define IMX219_XCLK_FREQ 24000000 @@ -144,7 +175,7 @@ struct imx219_mode { }; static const struct cci_reg_sequence imx219_common_regs[] = { - { CCI_REG8(0x0100), 0x00 }, /* Mode Select */ + { IMX219_REG_MODE_SELECT, 0x00 }, /* Mode Select */ /* To Access Addresses 3000-5fff, send the following commands */ { CCI_REG8(0x30eb), 0x0c }, @@ -155,15 +186,13 @@ static const struct cci_reg_sequence imx219_common_regs[] = { { CCI_REG8(0x30eb), 0x09 }, /* PLL Clock Table */ - { CCI_REG8(0x0301), 0x05 }, /* VTPXCK_DIV */ - { CCI_REG8(0x0303), 0x01 }, /* VTSYSCK_DIV */ - { CCI_REG8(0x0304), 0x03 }, /* PREPLLCK_VT_DIV 0x03 = AUTO set */ - { CCI_REG8(0x0305), 0x03 }, /* PREPLLCK_OP_DIV 0x03 = AUTO set */ - { CCI_REG8(0x0306), 0x00 }, /* PLL_VT_MPY */ - { CCI_REG8(0x0307), 0x39 }, - { CCI_REG8(0x030b), 0x01 }, /* OP_SYS_CLK_DIV */ - { CCI_REG8(0x030c), 0x00 }, /* PLL_OP_MPY */ - { CCI_REG8(0x030d), 0x72 }, + { IMX219_REG_VTPXCK_DIV, 5 }, + { IMX219_REG_VTSYCK_DIV, 1 }, + { IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */ + { IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */ + { IMX219_REG_PLL_VT_MPY, 57 }, + { IMX219_REG_OPSYCK_DIV, 1 }, + { IMX219_REG_PLL_OP_MPY, 114 }, /* Undocumented registers */ { CCI_REG8(0x455e), 0x00 }, @@ -180,16 +209,14 @@ static const struct cci_reg_sequence imx219_common_regs[] = { { CCI_REG8(0x479b), 0x0e }, /* Frame Bank Register Group "A" */ - { CCI_REG8(0x0162), 0x0d }, /* Line_Length_A */ - { CCI_REG8(0x0163), 0x78 }, - { CCI_REG8(0x0170), 0x01 }, /* X_ODD_INC_A */ - { CCI_REG8(0x0171), 0x01 }, /* Y_ODD_INC_A */ + { IMX219_REG_LINE_LENGTH_A, 3448 }, + { IMX219_REG_X_ODD_INC_A, 1 }, + { IMX219_REG_Y_ODD_INC_A, 1 }, /* Output setup registers */ - { CCI_REG8(0x0114), 0x01 }, /* CSI 2-Lane Mode */ - { CCI_REG8(0x0128), 0x00 }, /* DPHY Auto Mode */ - { CCI_REG8(0x012a), 0x18 }, /* EXCK_Freq */ - { CCI_REG8(0x012b), 0x00 }, + { IMX219_REG_CSI_LANE_MODE, IMX219_CSI_2_LANE_MODE }, + { IMX219_REG_DPHY_CTRL, IMX219_DPHY_CTRL_TIMING_AUTO }, + { IMX219_REG_EXCK_FREQ, IMX219_EXCK_FREQ(24) }, }; /* @@ -198,91 +225,57 @@ static const struct cci_reg_sequence imx219_common_regs[] = { * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. */ static const struct cci_reg_sequence mode_3280x2464_regs[] = { - { CCI_REG8(0x0164), 0x00 }, - { CCI_REG8(0x0165), 0x00 }, - { CCI_REG8(0x0166), 0x0c }, - { CCI_REG8(0x0167), 0xcf }, - { CCI_REG8(0x0168), 0x00 }, - { CCI_REG8(0x0169), 0x00 }, - { CCI_REG8(0x016a), 0x09 }, - { CCI_REG8(0x016b), 0x9f }, - { CCI_REG8(0x016c), 0x0c }, - { CCI_REG8(0x016d), 0xd0 }, - { CCI_REG8(0x016e), 0x09 }, - { CCI_REG8(0x016f), 0xa0 }, - { CCI_REG8(0x0624), 0x0c }, - { CCI_REG8(0x0625), 0xd0 }, - { CCI_REG8(0x0626), 0x09 }, - { CCI_REG8(0x0627), 0xa0 }, + { IMX219_REG_X_ADD_STA_A, 0 }, + { IMX219_REG_X_ADD_END_A, 3279 }, + { IMX219_REG_Y_ADD_STA_A, 0 }, + { IMX219_REG_Y_ADD_END_A, 2463 }, + { IMX219_REG_X_OUTPUT_SIZE, 3280 }, + { IMX219_REG_Y_OUTPUT_SIZE, 2464 }, + { IMX219_REG_TP_WINDOW_WIDTH, 3280 }, + { IMX219_REG_TP_WINDOW_HEIGHT, 2464 }, }; static const struct cci_reg_sequence mode_1920_1080_regs[] = { - { CCI_REG8(0x0164), 0x02 }, - { CCI_REG8(0x0165), 0xa8 }, - { CCI_REG8(0x0166), 0x0a }, - { CCI_REG8(0x0167), 0x27 }, - { CCI_REG8(0x0168), 0x02 }, - { CCI_REG8(0x0169), 0xb4 }, - { CCI_REG8(0x016a), 0x06 }, - { CCI_REG8(0x016b), 0xeb }, - { CCI_REG8(0x016c), 0x07 }, - { CCI_REG8(0x016d), 0x80 }, - { CCI_REG8(0x016e), 0x04 }, - { CCI_REG8(0x016f), 0x38 }, - { CCI_REG8(0x0624), 0x07 }, - { CCI_REG8(0x0625), 0x80 }, - { CCI_REG8(0x0626), 0x04 }, - { CCI_REG8(0x0627), 0x38 }, + { IMX219_REG_X_ADD_STA_A, 680 }, + { IMX219_REG_X_ADD_END_A, 2599 }, + { IMX219_REG_Y_ADD_STA_A, 692 }, + { IMX219_REG_Y_ADD_END_A, 1771 }, + { IMX219_REG_X_OUTPUT_SIZE, 1920 }, + { IMX219_REG_Y_OUTPUT_SIZE, 1080 }, + { IMX219_REG_TP_WINDOW_WIDTH, 1920 }, + { IMX219_REG_TP_WINDOW_HEIGHT, 1080 }, }; static const struct cci_reg_sequence mode_1640_1232_regs[] = { - { CCI_REG8(0x0164), 0x00 }, - { CCI_REG8(0x0165), 0x00 }, - { CCI_REG8(0x0166), 0x0c }, - { CCI_REG8(0x0167), 0xcf }, - { CCI_REG8(0x0168), 0x00 }, - { CCI_REG8(0x0169), 0x00 }, - { CCI_REG8(0x016a), 0x09 }, - { CCI_REG8(0x016b), 0x9f }, - { CCI_REG8(0x016c), 0x06 }, - { CCI_REG8(0x016d), 0x68 }, - { CCI_REG8(0x016e), 0x04 }, - { CCI_REG8(0x016f), 0xd0 }, - { CCI_REG8(0x0624), 0x06 }, - { CCI_REG8(0x0625), 0x68 }, - { CCI_REG8(0x0626), 0x04 }, - { CCI_REG8(0x0627), 0xd0 }, + { IMX219_REG_X_ADD_STA_A, 0 }, + { IMX219_REG_X_ADD_END_A, 3279 }, + { IMX219_REG_Y_ADD_STA_A, 0 }, + { IMX219_REG_Y_ADD_END_A, 2463 }, + { IMX219_REG_X_OUTPUT_SIZE, 1640 }, + { IMX219_REG_Y_OUTPUT_SIZE, 1232 }, + { IMX219_REG_TP_WINDOW_WIDTH, 1640 }, + { IMX219_REG_TP_WINDOW_HEIGHT, 1232 }, }; static const struct cci_reg_sequence mode_640_480_regs[] = { - { CCI_REG8(0x0164), 0x03 }, - { CCI_REG8(0x0165), 0xe8 }, - { CCI_REG8(0x0166), 0x08 }, - { CCI_REG8(0x0167), 0xe7 }, - { CCI_REG8(0x0168), 0x02 }, - { CCI_REG8(0x0169), 0xf0 }, - { CCI_REG8(0x016a), 0x06 }, - { CCI_REG8(0x016b), 0xaf }, - { CCI_REG8(0x016c), 0x02 }, - { CCI_REG8(0x016d), 0x80 }, - { CCI_REG8(0x016e), 0x01 }, - { CCI_REG8(0x016f), 0xe0 }, - { CCI_REG8(0x0624), 0x06 }, - { CCI_REG8(0x0625), 0x68 }, - { CCI_REG8(0x0626), 0x04 }, - { CCI_REG8(0x0627), 0xd0 }, + { IMX219_REG_X_ADD_STA_A, 1000 }, + { IMX219_REG_X_ADD_END_A, 2279 }, + { IMX219_REG_Y_ADD_STA_A, 752 }, + { IMX219_REG_Y_ADD_END_A, 1711 }, + { IMX219_REG_X_OUTPUT_SIZE, 640 }, + { IMX219_REG_Y_OUTPUT_SIZE, 480 }, + { IMX219_REG_TP_WINDOW_WIDTH, 1640 }, + { IMX219_REG_TP_WINDOW_HEIGHT, 1232 }, }; static const struct cci_reg_sequence raw8_framefmt_regs[] = { - { CCI_REG8(0x018c), 0x08 }, - { CCI_REG8(0x018d), 0x08 }, - { CCI_REG8(0x0309), 0x08 }, + { IMX219_REG_CSI_DATA_FORMAT_A, 0x0808 }, + { IMX219_REG_OPPXCK_DIV, 8 }, }; static const struct cci_reg_sequence raw10_framefmt_regs[] = { - { CCI_REG8(0x018c), 0x0a }, - { CCI_REG8(0x018d), 0x0a }, - { CCI_REG8(0x0309), 0x0a }, + { IMX219_REG_CSI_DATA_FORMAT_A, 0x0a0a }, + { IMX219_REG_OPPXCK_DIV, 10 }, }; static const s64 imx219_link_freq_menu[] = { From patchwork Mon Aug 21 22:29:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715617 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 3A71CEE4996 for ; Mon, 21 Aug 2023 22:30:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231550AbjHUWaM (ORCPT ); Mon, 21 Aug 2023 18:30:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231553AbjHUWaL (ORCPT ); Mon, 21 Aug 2023 18:30:11 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBB25183 for ; Mon, 21 Aug 2023 15:30:05 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1F6EE87E0; Tue, 22 Aug 2023 00:28:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656924; bh=K0/sg/fZPdnbgAUoCBYHJTzZK4ZLijvYH9XxAZTLW24=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UI98ll4scf7ANx/WcoJtCEjToMPwgtoZbU3JCkFwcGhfvWs8y6fMmipmKN24QrLya +xCWNlqS1Evpa6K4HWBrCetdczCpIkHWXqRLk43nfVc/MAyhoHrg5WjzjOr9vB4HUu Lfr+Zm0Mg4gBkmxb4FW147I2lBhnH4Zax2b6sO34= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 04/18] media: i2c: imx219: Fix test pattern window for 640x480 mode Date: Tue, 22 Aug 2023 01:29:47 +0300 Message-ID: <20230821223001.28480-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The 640x480 mode specifies incorrect values for the TP_WINDOW_WIDTH and TP_WINDOW_HEIGHT registers, which likely got copied from the 1640x1232 mode. They should be identical to the X_OUTPUT_SIZE and Y_OUTPUT_SIZE registers as for all the other modes, to avoid cropping the test pattern. Fix them. Signed-off-by: Laurent Pinchart Reviewed-by: Dave Stevenson --- drivers/media/i2c/imx219.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 8cab0251bd6a..08011192daa6 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -264,8 +264,8 @@ static const struct cci_reg_sequence mode_640_480_regs[] = { { IMX219_REG_Y_ADD_END_A, 1711 }, { IMX219_REG_X_OUTPUT_SIZE, 640 }, { IMX219_REG_Y_OUTPUT_SIZE, 480 }, - { IMX219_REG_TP_WINDOW_WIDTH, 1640 }, - { IMX219_REG_TP_WINDOW_HEIGHT, 1232 }, + { IMX219_REG_TP_WINDOW_WIDTH, 640 }, + { IMX219_REG_TP_WINDOW_HEIGHT, 480 }, }; static const struct cci_reg_sequence raw8_framefmt_regs[] = { From patchwork Mon Aug 21 22:29:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715616 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 1917DEE4996 for ; Mon, 21 Aug 2023 22:30:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231565AbjHUWaR (ORCPT ); Mon, 21 Aug 2023 18:30:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231553AbjHUWaQ (ORCPT ); Mon, 21 Aug 2023 18:30:16 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E5EA130 for ; Mon, 21 Aug 2023 15:30:12 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EF13A87EA; Tue, 22 Aug 2023 00:28:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656927; bh=YQGy2YgkKdY3TaGKTkOwuHZ6puR65cFydi6R4HwvOnk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZkgQb0jhBF2imCdXUqFZhI22cqFjj+8Sk0n3e4BfbIDjU+kX35FyTsFOqqLAJuOAR AiY2cE2/NZ5n8P4yc6NJiJPlOVhq01LHGSdJDGPre7M1dgxyjS2vhtqk/UV4iCJVsx Aw6Gf8m7ApYMClkWoSL8Zric0sSRQulRbpQoYLVE= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 06/18] media: i2c: imx219: Merge format and binning setting functions Date: Tue, 22 Aug 2023 01:29:49 +0300 Message-ID: <20230821223001.28480-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The imx219_set_binning() function sets registers based on the bpp value, which is computed in imx219_set_framefmt(). As both functions are called from the same place consecutively, and set registers based on the selected mode, merge them together to simplify the code. Signed-off-by: Laurent Pinchart Reviewed-by: Dave Stevenson --- drivers/media/i2c/imx219.c | 43 +++++++++----------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 9490dcba42ab..3a0b082d9ee0 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -618,6 +618,7 @@ static int imx219_set_framefmt(struct imx219 *imx219, { const struct imx219_mode *mode = imx219->mode; unsigned int bpp; + u16 bin_mode; int ret = 0; switch (format->code) { @@ -648,6 +649,15 @@ static int imx219_set_framefmt(struct imx219 *imx219, mode->crop.top - IMX219_PIXEL_ARRAY_TOP + mode->crop.height - 1, &ret); + if (!imx219->mode->binning) + bin_mode = IMX219_BINNING_NONE; + else if (bpp == 8) + bin_mode = IMX219_BINNING_2X2_ANALOG; + else + bin_mode = IMX219_BINNING_2X2; + + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, bin_mode, &ret); + cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, format->width, &ret); cci_write(imx219->regmap, IMX219_REG_Y_OUTPUT_SIZE, @@ -665,32 +675,6 @@ static int imx219_set_framefmt(struct imx219 *imx219, return ret; } -static int imx219_set_binning(struct imx219 *imx219, - const struct v4l2_mbus_framefmt *format) -{ - if (!imx219->mode->binning) - return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, - IMX219_BINNING_NONE, NULL); - - switch (format->code) { - case MEDIA_BUS_FMT_SRGGB8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - case MEDIA_BUS_FMT_SGBRG8_1X8: - case MEDIA_BUS_FMT_SBGGR8_1X8: - return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, - IMX219_BINNING_2X2_ANALOG, NULL); - - case MEDIA_BUS_FMT_SRGGB10_1X10: - case MEDIA_BUS_FMT_SGRBG10_1X10: - case MEDIA_BUS_FMT_SGBRG10_1X10: - case MEDIA_BUS_FMT_SBGGR10_1X10: - return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, - IMX219_BINNING_2X2, NULL); - } - - return -EINVAL; -} - static int imx219_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) @@ -764,13 +748,6 @@ static int imx219_start_streaming(struct imx219 *imx219, goto err_rpm_put; } - ret = imx219_set_binning(imx219, format); - if (ret) { - dev_err(&client->dev, "%s failed to set binning: %d\n", - __func__, ret); - goto err_rpm_put; - } - /* Apply customized values from user */ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); if (ret) From patchwork Mon Aug 21 22:29:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715615 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 AFD42EE49A6 for ; Mon, 21 Aug 2023 22:30:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231569AbjHUWaW (ORCPT ); Mon, 21 Aug 2023 18:30:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34608 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231567AbjHUWaW (ORCPT ); Mon, 21 Aug 2023 18:30:22 -0400 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 2363213D for ; Mon, 21 Aug 2023 15:30:17 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4EA2829C2; Tue, 22 Aug 2023 00:28:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656930; bh=DAe92kQPFYZW1NvWsvcmrlFUoAX3AX+jy2DyuMxtPOo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cPsNPp1Td4Ded0BqTMy9GpgzNRAwBz6k4Qed1S9rZ1E+hKQLhhp+8IrZnZik9XuZl J2E+3FmAykZxALTDNPQvRpCykjeD2mEac2p2z18fhEbMtkuJltkkLXtQ7RErhM2j+4 QlKXYQSD5d4HNZv3kG+DiDOxVWGW9SD4k8NKLHFg= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 08/18] media: i2c: imx219: Use active crop rectangle to configure registers Date: Tue, 22 Aug 2023 01:29:51 +0300 Message-ID: <20230821223001.28480-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Configure the crop-related registers from the values stored in the active crop rectangle instead of the mode structure. This removes usage of the mode from the imx219_set_framefmt(). No functional change is intended. Signed-off-by: Laurent Pinchart --- drivers/media/i2c/imx219.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 16776a3ae84d..1205986ce47e 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -615,9 +615,9 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, } static int imx219_set_framefmt(struct imx219 *imx219, - const struct v4l2_mbus_framefmt *format) + const struct v4l2_mbus_framefmt *format, + const struct v4l2_rect *crop) { - const struct imx219_mode *mode = imx219->mode; unsigned int bpp; u16 bin_mode; int ret = 0; @@ -640,15 +640,13 @@ static int imx219_set_framefmt(struct imx219 *imx219, } cci_write(imx219->regmap, IMX219_REG_X_ADD_STA_A, - mode->crop.left - IMX219_PIXEL_ARRAY_LEFT, &ret); + crop->left - IMX219_PIXEL_ARRAY_LEFT, &ret); cci_write(imx219->regmap, IMX219_REG_X_ADD_END_A, - mode->crop.left - IMX219_PIXEL_ARRAY_LEFT + mode->crop.width - 1, - &ret); + crop->left - IMX219_PIXEL_ARRAY_LEFT + crop->width - 1, &ret); cci_write(imx219->regmap, IMX219_REG_Y_ADD_STA_A, - mode->crop.top - IMX219_PIXEL_ARRAY_TOP, &ret); + crop->top - IMX219_PIXEL_ARRAY_TOP, &ret); cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, - mode->crop.top - IMX219_PIXEL_ARRAY_TOP + mode->crop.height - 1, - &ret); + crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); if (!imx219->mode->binning) bin_mode = IMX219_BINNING_NONE; @@ -719,6 +717,7 @@ static int imx219_start_streaming(struct imx219 *imx219, { struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); const struct v4l2_mbus_framefmt *format; + const struct v4l2_rect *crop; int ret; ret = pm_runtime_resume_and_get(&client->dev); @@ -742,7 +741,8 @@ static int imx219_start_streaming(struct imx219 *imx219, /* Apply format and crop settings. */ format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); - ret = imx219_set_framefmt(imx219, format); + crop = v4l2_subdev_get_pad_crop(&imx219->sd, state, 0); + ret = imx219_set_framefmt(imx219, format, crop); if (ret) { dev_err(&client->dev, "%s failed to set frame format: %d\n", __func__, ret); From patchwork Mon Aug 21 22:29:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715614 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 8438FEE4996 for ; Mon, 21 Aug 2023 22:30:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231567AbjHUWaZ (ORCPT ); Mon, 21 Aug 2023 18:30:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34716 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231571AbjHUWaZ (ORCPT ); Mon, 21 Aug 2023 18:30:25 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 016B0183 for ; Mon, 21 Aug 2023 15:30:22 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 756EA899; Tue, 22 Aug 2023 00:28:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656933; bh=6GMPtfYEuP6O5OQDgQvHzpNDvQNg39W7HQIPfV3RXeY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ev1F34tPlcg7Xq9V50hAb89k9QqNigTBuyiFcLmTx1p68TnzxswSSNSV+ED3LE74B zSv779tNM0N9iokQGZ886e2YPG/8n/aErP/DzkPDTgqOGnwzpDnd3YicuYOfWYCIch fi+A1cFbAdycxQ0Y1e+6Zo0dyM7WpbhRIFMvAatg= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 10/18] media: i2c: imx219: Access height from active format in imx219_set_ctrl Date: Tue, 22 Aug 2023 01:29:53 +0300 Message-ID: <20230821223001.28480-11-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Use the active format height instead of the mode height in imx219_set_ctrl(). This prepares for dropping the mode field from the imx219 structure. The state is retrieved using v4l2_subdev_get_locked_active_state() as the subdev active state and the control handler share the same lock. Signed-off-by: Laurent Pinchart Reviewed-by: Dave Stevenson --- drivers/media/i2c/imx219.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 0c26cbfe58f3..4e9a50117a0a 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -401,13 +401,18 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) struct imx219 *imx219 = container_of(ctrl->handler, struct imx219, ctrl_handler); struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + const struct v4l2_mbus_framefmt *format; + struct v4l2_subdev_state *state; int ret = 0; + state = v4l2_subdev_get_locked_active_state(&imx219->sd); + format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); + if (ctrl->id == V4L2_CID_VBLANK) { int exposure_max, exposure_def; /* Update max exposure while meeting expected vblanking */ - exposure_max = imx219->mode->height + ctrl->val - 4; + exposure_max = format->height + ctrl->val - 4; exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? exposure_max : IMX219_EXPOSURE_DEFAULT; __v4l2_ctrl_modify_range(imx219->exposure, @@ -447,7 +452,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: cci_write(imx219->regmap, IMX219_REG_VTS, - imx219->mode->height + ctrl->val, &ret); + format->height + ctrl->val, &ret); break; case V4L2_CID_TEST_PATTERN_RED: cci_write(imx219->regmap, IMX219_REG_TESTP_RED, From patchwork Mon Aug 21 22:29:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715613 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 1777EEE4996 for ; Mon, 21 Aug 2023 22:30:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231583AbjHUWa3 (ORCPT ); Mon, 21 Aug 2023 18:30:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231575AbjHUWa2 (ORCPT ); Mon, 21 Aug 2023 18:30:28 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED544132 for ; Mon, 21 Aug 2023 15:30:24 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E8A0336B0; Tue, 22 Aug 2023 00:28:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656935; bh=6sZRcwFHnMnC2rIYbnx4/7x1mZzsYCzO0LiGWRLyHQo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DnuANdvEp14f6nYywYpFxFlQUx8MeJyHo4+LOJgEVsbwAUfbBY7CT6hlr/LBxChGH kPCdRobn0Akl3A5Kijd21viEfYl220/VgXyttxMQ4siP2dMaw19E77aQMCUt/rl/3z Qos4Hc7eRnWZ2sxVPDWEM9zMqBVJfuKTYq5MrGtU= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 11/18] media: i2c: imx219: Don't store the current mode in the imx219 structure Date: Tue, 22 Aug 2023 01:29:54 +0300 Message-ID: <20230821223001.28480-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The mode field of the imx219 structure is only used in imx219_init_controls(), after the probe function sets it to point to the default mode. Use the default mode directly when initializing controls, and drop the mode field from the imx219 structure. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- drivers/media/i2c/imx219.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 4e9a50117a0a..67a30dc39641 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -363,9 +363,6 @@ struct imx219 { struct v4l2_ctrl *vblank; struct v4l2_ctrl *hblank; - /* Current mode */ - const struct imx219_mode *mode; - /* Streaming on/off */ bool streaming; @@ -584,7 +581,6 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, *crop = mode->crop; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - imx219->mode = mode; /* Update limits and set FPS to default */ __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, IMX219_VTS_MAX - mode->height, 1, @@ -967,8 +963,8 @@ static unsigned long imx219_get_pixel_rate(struct imx219 *imx219) static int imx219_init_controls(struct imx219 *imx219) { struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + const struct imx219_mode *mode = &supported_modes[0]; struct v4l2_ctrl_handler *ctrl_hdlr; - unsigned int height = imx219->mode->height; struct v4l2_fwnode_device_properties props; int exposure_max, exposure_def, hblank; int i, ret; @@ -997,15 +993,15 @@ static int imx219_init_controls(struct imx219 *imx219) /* Initial vblank/hblank/exposure parameters based on current mode */ imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_VBLANK, IMX219_VBLANK_MIN, - IMX219_VTS_MAX - height, 1, - imx219->mode->vts_def - height); - hblank = IMX219_PPL_DEFAULT - imx219->mode->width; + IMX219_VTS_MAX - mode->height, 1, + mode->vts_def - mode->height); + hblank = IMX219_PPL_DEFAULT - mode->width; imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_HBLANK, hblank, hblank, 1, hblank); if (imx219->hblank) imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - exposure_max = imx219->mode->vts_def - 4; + exposure_max = mode->vts_def - 4; exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? exposure_max : IMX219_EXPOSURE_DEFAULT; imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, @@ -1192,10 +1188,8 @@ static int imx219_probe(struct i2c_client *client) if (ret) goto error_power_off; - /* Set default mode to max resolution */ - imx219->mode = &supported_modes[0]; - - /* sensor doesn't enter LP-11 state upon power up until and unless + /* + * Sensor doesn't enter LP-11 state upon power up until and unless * streaming is started, so upon power up switch the modes to: * streaming -> standby */ From patchwork Mon Aug 21 22:29:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715612 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 807C6EE49A5 for ; Mon, 21 Aug 2023 22:30:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231585AbjHUWai (ORCPT ); Mon, 21 Aug 2023 18:30:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231592AbjHUWag (ORCPT ); Mon, 21 Aug 2023 18:30:36 -0400 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 4754A127 for ; Mon, 21 Aug 2023 15:30:29 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C050138B3; Tue, 22 Aug 2023 00:28:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656938; bh=xUCeAzX3kud3dyd2g9Fr8vJQoLO7bBakB9ZE9CMRYGQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hhxy/0vQOjUPhmIkUQMtkUJpElrHKkbEYtTtZ9Dh7Ly0GxZNaxfIfnAkczVRm+7Nw uV15QJMcySCtiZweNXYJzhzt5uei3vhgsta3k1plxU6XzSfxEyzwX8Izb9f35jqwS6 kQN/g7/pBa+sbScXjpIRctFFrKBbyS+SkG5GGh2c= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 13/18] media: i2c: imx219: Group functions by purpose Date: Tue, 22 Aug 2023 01:29:56 +0300 Message-ID: <20230821223001.28480-14-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Move functions around to group them by purpose, in order to improve readability. No functional change is intended. Signed-off-by: Laurent Pinchart Reviewed-by: Dave Stevenson --- drivers/media/i2c/imx219.c | 649 +++++++++++++++++++------------------ 1 file changed, 332 insertions(+), 317 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 165c5e8473f7..227c227cf4ce 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -389,6 +389,10 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) return imx219_mbus_formats[i]; } +/* ----------------------------------------------------------------------------- + * Controls + */ + static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) { struct imx219 *imx219 = @@ -480,6 +484,308 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = { .s_ctrl = imx219_set_ctrl, }; +static unsigned long imx219_get_pixel_rate(struct imx219 *imx219) +{ + return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE; +} + +/* Initialize control handlers */ +static int imx219_init_controls(struct imx219 *imx219) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + const struct imx219_mode *mode = &supported_modes[0]; + struct v4l2_ctrl_handler *ctrl_hdlr; + struct v4l2_fwnode_device_properties props; + int exposure_max, exposure_def, hblank; + int i, ret; + + ctrl_hdlr = &imx219->ctrl_handler; + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12); + if (ret) + return ret; + + /* By default, PIXEL_RATE is read only */ + imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_PIXEL_RATE, + imx219_get_pixel_rate(imx219), + imx219_get_pixel_rate(imx219), 1, + imx219_get_pixel_rate(imx219)); + + imx219->link_freq = + v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_LINK_FREQ, + ARRAY_SIZE(imx219_link_freq_menu) - 1, 0, + (imx219->lanes == 2) ? imx219_link_freq_menu : + imx219_link_freq_4lane_menu); + if (imx219->link_freq) + imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + /* Initial vblank/hblank/exposure parameters based on current mode */ + imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_VBLANK, IMX219_VBLANK_MIN, + IMX219_VTS_MAX - mode->height, 1, + mode->vts_def - mode->height); + hblank = IMX219_PPL_DEFAULT - mode->width; + imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_HBLANK, hblank, hblank, + 1, hblank); + if (imx219->hblank) + imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + exposure_max = mode->vts_def - 4; + exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? + exposure_max : IMX219_EXPOSURE_DEFAULT; + imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_EXPOSURE, + IMX219_EXPOSURE_MIN, exposure_max, + IMX219_EXPOSURE_STEP, + exposure_def); + + v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, + IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX, + IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT); + + v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN, + IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX, + IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT); + + imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + if (imx219->hflip) + imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + + imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + if (imx219->vflip) + imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(imx219_test_pattern_menu) - 1, + 0, 0, imx219_test_pattern_menu); + for (i = 0; i < 4; i++) { + /* + * The assumption is that + * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1 + * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2 + * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3 + */ + v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_TEST_PATTERN_RED + i, + IMX219_TESTP_COLOUR_MIN, + IMX219_TESTP_COLOUR_MAX, + IMX219_TESTP_COLOUR_STEP, + IMX219_TESTP_COLOUR_MAX); + /* The "Solid color" pattern is white by default */ + } + + if (ctrl_hdlr->error) { + ret = ctrl_hdlr->error; + dev_err(&client->dev, "%s control init failed (%d)\n", + __func__, ret); + goto error; + } + + ret = v4l2_fwnode_device_parse(&client->dev, &props); + if (ret) + goto error; + + ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops, + &props); + if (ret) + goto error; + + imx219->sd.ctrl_handler = ctrl_hdlr; + + return 0; + +error: + v4l2_ctrl_handler_free(ctrl_hdlr); + + return ret; +} + +static void imx219_free_controls(struct imx219 *imx219) +{ + v4l2_ctrl_handler_free(imx219->sd.ctrl_handler); +} + +/* ----------------------------------------------------------------------------- + * Subdev operations + */ + +static int imx219_set_framefmt(struct imx219 *imx219, + const struct v4l2_mbus_framefmt *format, + const struct v4l2_rect *crop) +{ + unsigned int bpp; + u16 bin_mode; + int ret = 0; + + switch (format->code) { + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + bpp = 8; + break; + + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + default: + bpp = 10; + break; + } + + cci_write(imx219->regmap, IMX219_REG_X_ADD_STA_A, + crop->left - IMX219_PIXEL_ARRAY_LEFT, &ret); + cci_write(imx219->regmap, IMX219_REG_X_ADD_END_A, + crop->left - IMX219_PIXEL_ARRAY_LEFT + crop->width - 1, &ret); + cci_write(imx219->regmap, IMX219_REG_Y_ADD_STA_A, + crop->top - IMX219_PIXEL_ARRAY_TOP, &ret); + cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, + crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); + + if (format->width == crop->width && format->height == crop->height) + bin_mode = IMX219_BINNING_NONE; + else if (bpp == 8) + bin_mode = IMX219_BINNING_2X2_ANALOG; + else + bin_mode = IMX219_BINNING_2X2; + + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, bin_mode, &ret); + + cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, + format->width, &ret); + cci_write(imx219->regmap, IMX219_REG_Y_OUTPUT_SIZE, + format->height, &ret); + + cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_WIDTH, + format->width, &ret); + cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_HEIGHT, + format->height, &ret); + + cci_write(imx219->regmap, IMX219_REG_CSI_DATA_FORMAT_A, + (bpp << 8) | bpp, &ret); + cci_write(imx219->regmap, IMX219_REG_OPPXCK_DIV, bpp, &ret); + + return ret; +} + +static int imx219_configure_lanes(struct imx219 *imx219) +{ + return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE, + imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE : + IMX219_CSI_4_LANE_MODE, NULL); +}; + +static int imx219_start_streaming(struct imx219 *imx219, + struct v4l2_subdev_state *state) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + const struct v4l2_mbus_framefmt *format; + const struct v4l2_rect *crop; + int ret; + + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) + return ret; + + /* Send all registers that are common to all modes */ + ret = cci_multi_reg_write(imx219->regmap, imx219_common_regs, + ARRAY_SIZE(imx219_common_regs), NULL); + if (ret) { + dev_err(&client->dev, "%s failed to send mfg header\n", __func__); + goto err_rpm_put; + } + + /* Configure two or four Lane mode */ + ret = imx219_configure_lanes(imx219); + if (ret) { + dev_err(&client->dev, "%s failed to configure lanes\n", __func__); + goto err_rpm_put; + } + + /* Apply format and crop settings. */ + format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); + crop = v4l2_subdev_get_pad_crop(&imx219->sd, state, 0); + ret = imx219_set_framefmt(imx219, format, crop); + if (ret) { + dev_err(&client->dev, "%s failed to set frame format: %d\n", + __func__, ret); + goto err_rpm_put; + } + + /* Apply customized values from user */ + ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); + if (ret) + goto err_rpm_put; + + /* set stream on register */ + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, + IMX219_MODE_STREAMING, NULL); + if (ret) + goto err_rpm_put; + + /* vflip and hflip cannot change during streaming */ + __v4l2_ctrl_grab(imx219->vflip, true); + __v4l2_ctrl_grab(imx219->hflip, true); + + return 0; + +err_rpm_put: + pm_runtime_put(&client->dev); + return ret; +} + +static void imx219_stop_streaming(struct imx219 *imx219) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + int ret; + + /* set stream off register */ + ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, + IMX219_MODE_STANDBY, NULL); + if (ret) + dev_err(&client->dev, "%s failed to set stream\n", __func__); + + __v4l2_ctrl_grab(imx219->vflip, false); + __v4l2_ctrl_grab(imx219->hflip, false); + + pm_runtime_put(&client->dev); +} + +static int imx219_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct imx219 *imx219 = to_imx219(sd); + struct v4l2_subdev_state *state; + int ret = 0; + + state = v4l2_subdev_lock_and_get_active_state(sd); + + if (imx219->streaming == enable) + goto unlock; + + if (enable) { + /* + * Apply default & customized values + * and then start streaming. + */ + ret = imx219_start_streaming(imx219, state); + if (ret) + goto unlock; + } else { + imx219_stop_streaming(imx219); + } + + imx219->streaming = enable; + +unlock: + v4l2_subdev_unlock_state(state); + return ret; +} + static void imx219_update_pad_format(struct imx219 *imx219, const struct imx219_mode *mode, struct v4l2_mbus_framefmt *fmt, u32 code) @@ -604,66 +910,6 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, return 0; } -static int imx219_set_framefmt(struct imx219 *imx219, - const struct v4l2_mbus_framefmt *format, - const struct v4l2_rect *crop) -{ - unsigned int bpp; - u16 bin_mode; - int ret = 0; - - switch (format->code) { - case MEDIA_BUS_FMT_SRGGB8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - case MEDIA_BUS_FMT_SGBRG8_1X8: - case MEDIA_BUS_FMT_SBGGR8_1X8: - bpp = 8; - break; - - case MEDIA_BUS_FMT_SRGGB10_1X10: - case MEDIA_BUS_FMT_SGRBG10_1X10: - case MEDIA_BUS_FMT_SGBRG10_1X10: - case MEDIA_BUS_FMT_SBGGR10_1X10: - default: - bpp = 10; - break; - } - - cci_write(imx219->regmap, IMX219_REG_X_ADD_STA_A, - crop->left - IMX219_PIXEL_ARRAY_LEFT, &ret); - cci_write(imx219->regmap, IMX219_REG_X_ADD_END_A, - crop->left - IMX219_PIXEL_ARRAY_LEFT + crop->width - 1, &ret); - cci_write(imx219->regmap, IMX219_REG_Y_ADD_STA_A, - crop->top - IMX219_PIXEL_ARRAY_TOP, &ret); - cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, - crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); - - if (format->width == crop->width && format->height == crop->height) - bin_mode = IMX219_BINNING_NONE; - else if (bpp == 8) - bin_mode = IMX219_BINNING_2X2_ANALOG; - else - bin_mode = IMX219_BINNING_2X2; - - cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, bin_mode, &ret); - - cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, - format->width, &ret); - cci_write(imx219->regmap, IMX219_REG_Y_OUTPUT_SIZE, - format->height, &ret); - - cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_WIDTH, - format->width, &ret); - cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_HEIGHT, - format->height, &ret); - - cci_write(imx219->regmap, IMX219_REG_CSI_DATA_FORMAT_A, - (bpp << 8) | bpp, &ret); - cci_write(imx219->regmap, IMX219_REG_OPPXCK_DIV, bpp, &ret); - - return ret; -} - static int imx219_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) @@ -695,120 +941,35 @@ static int imx219_get_selection(struct v4l2_subdev *sd, return -EINVAL; } -static int imx219_configure_lanes(struct imx219 *imx219) -{ - return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE, - imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE : - IMX219_CSI_4_LANE_MODE, NULL); +static const struct v4l2_subdev_core_ops imx219_core_ops = { + .subscribe_event = v4l2_ctrl_subdev_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, }; -static int imx219_start_streaming(struct imx219 *imx219, - struct v4l2_subdev_state *state) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - const struct v4l2_mbus_framefmt *format; - const struct v4l2_rect *crop; - int ret; +static const struct v4l2_subdev_video_ops imx219_video_ops = { + .s_stream = imx219_set_stream, +}; - ret = pm_runtime_resume_and_get(&client->dev); - if (ret < 0) - return ret; +static const struct v4l2_subdev_pad_ops imx219_pad_ops = { + .init_cfg = imx219_init_cfg, + .enum_mbus_code = imx219_enum_mbus_code, + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = imx219_set_pad_format, + .get_selection = imx219_get_selection, + .enum_frame_size = imx219_enum_frame_size, +}; - /* Send all registers that are common to all modes */ - ret = cci_multi_reg_write(imx219->regmap, imx219_common_regs, - ARRAY_SIZE(imx219_common_regs), NULL); - if (ret) { - dev_err(&client->dev, "%s failed to send mfg header\n", __func__); - goto err_rpm_put; - } +static const struct v4l2_subdev_ops imx219_subdev_ops = { + .core = &imx219_core_ops, + .video = &imx219_video_ops, + .pad = &imx219_pad_ops, +}; - /* Configure two or four Lane mode */ - ret = imx219_configure_lanes(imx219); - if (ret) { - dev_err(&client->dev, "%s failed to configure lanes\n", __func__); - goto err_rpm_put; - } - /* Apply format and crop settings. */ - format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); - crop = v4l2_subdev_get_pad_crop(&imx219->sd, state, 0); - ret = imx219_set_framefmt(imx219, format, crop); - if (ret) { - dev_err(&client->dev, "%s failed to set frame format: %d\n", - __func__, ret); - goto err_rpm_put; - } +/* ----------------------------------------------------------------------------- + * Power management + */ - /* Apply customized values from user */ - ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); - if (ret) - goto err_rpm_put; - - /* set stream on register */ - ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, - IMX219_MODE_STREAMING, NULL); - if (ret) - goto err_rpm_put; - - /* vflip and hflip cannot change during streaming */ - __v4l2_ctrl_grab(imx219->vflip, true); - __v4l2_ctrl_grab(imx219->hflip, true); - - return 0; - -err_rpm_put: - pm_runtime_put(&client->dev); - return ret; -} - -static void imx219_stop_streaming(struct imx219 *imx219) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - int ret; - - /* set stream off register */ - ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, - IMX219_MODE_STANDBY, NULL); - if (ret) - dev_err(&client->dev, "%s failed to set stream\n", __func__); - - __v4l2_ctrl_grab(imx219->vflip, false); - __v4l2_ctrl_grab(imx219->hflip, false); - - pm_runtime_put(&client->dev); -} - -static int imx219_set_stream(struct v4l2_subdev *sd, int enable) -{ - struct imx219 *imx219 = to_imx219(sd); - struct v4l2_subdev_state *state; - int ret = 0; - - state = v4l2_subdev_lock_and_get_active_state(sd); - - if (imx219->streaming == enable) - goto unlock; - - if (enable) { - /* - * Apply default & customized values - * and then start streaming. - */ - ret = imx219_start_streaming(imx219, state); - if (ret) - goto unlock; - } else { - imx219_stop_streaming(imx219); - } - - imx219->streaming = enable; - -unlock: - v4l2_subdev_unlock_state(state); - return ret; -} - -/* Power/clock management functions */ static int imx219_power_on(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); @@ -889,6 +1050,10 @@ static int __maybe_unused imx219_resume(struct device *dev) return ret; } +/* ----------------------------------------------------------------------------- + * Probe & remove + */ + static int imx219_get_regulators(struct imx219 *imx219) { struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); @@ -925,156 +1090,6 @@ static int imx219_identify_module(struct imx219 *imx219) return 0; } -static const struct v4l2_subdev_core_ops imx219_core_ops = { - .subscribe_event = v4l2_ctrl_subdev_subscribe_event, - .unsubscribe_event = v4l2_event_subdev_unsubscribe, -}; - -static const struct v4l2_subdev_video_ops imx219_video_ops = { - .s_stream = imx219_set_stream, -}; - -static const struct v4l2_subdev_pad_ops imx219_pad_ops = { - .init_cfg = imx219_init_cfg, - .enum_mbus_code = imx219_enum_mbus_code, - .get_fmt = v4l2_subdev_get_fmt, - .set_fmt = imx219_set_pad_format, - .get_selection = imx219_get_selection, - .enum_frame_size = imx219_enum_frame_size, -}; - -static const struct v4l2_subdev_ops imx219_subdev_ops = { - .core = &imx219_core_ops, - .video = &imx219_video_ops, - .pad = &imx219_pad_ops, -}; - - -static unsigned long imx219_get_pixel_rate(struct imx219 *imx219) -{ - return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE; -} - -/* Initialize control handlers */ -static int imx219_init_controls(struct imx219 *imx219) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - const struct imx219_mode *mode = &supported_modes[0]; - struct v4l2_ctrl_handler *ctrl_hdlr; - struct v4l2_fwnode_device_properties props; - int exposure_max, exposure_def, hblank; - int i, ret; - - ctrl_hdlr = &imx219->ctrl_handler; - ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12); - if (ret) - return ret; - - /* By default, PIXEL_RATE is read only */ - imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_PIXEL_RATE, - imx219_get_pixel_rate(imx219), - imx219_get_pixel_rate(imx219), 1, - imx219_get_pixel_rate(imx219)); - - imx219->link_freq = - v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_LINK_FREQ, - ARRAY_SIZE(imx219_link_freq_menu) - 1, 0, - (imx219->lanes == 2) ? imx219_link_freq_menu : - imx219_link_freq_4lane_menu); - if (imx219->link_freq) - imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; - - /* Initial vblank/hblank/exposure parameters based on current mode */ - imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_VBLANK, IMX219_VBLANK_MIN, - IMX219_VTS_MAX - mode->height, 1, - mode->vts_def - mode->height); - hblank = IMX219_PPL_DEFAULT - mode->width; - imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_HBLANK, hblank, hblank, - 1, hblank); - if (imx219->hblank) - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - exposure_max = mode->vts_def - 4; - exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? - exposure_max : IMX219_EXPOSURE_DEFAULT; - imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_EXPOSURE, - IMX219_EXPOSURE_MIN, exposure_max, - IMX219_EXPOSURE_STEP, - exposure_def); - - v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, - IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX, - IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT); - - v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN, - IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX, - IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT); - - imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - if (imx219->hflip) - imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - - imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - if (imx219->vflip) - imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - - v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(imx219_test_pattern_menu) - 1, - 0, 0, imx219_test_pattern_menu); - for (i = 0; i < 4; i++) { - /* - * The assumption is that - * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1 - * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2 - * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3 - */ - v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_TEST_PATTERN_RED + i, - IMX219_TESTP_COLOUR_MIN, - IMX219_TESTP_COLOUR_MAX, - IMX219_TESTP_COLOUR_STEP, - IMX219_TESTP_COLOUR_MAX); - /* The "Solid color" pattern is white by default */ - } - - if (ctrl_hdlr->error) { - ret = ctrl_hdlr->error; - dev_err(&client->dev, "%s control init failed (%d)\n", - __func__, ret); - goto error; - } - - ret = v4l2_fwnode_device_parse(&client->dev, &props); - if (ret) - goto error; - - ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops, - &props); - if (ret) - goto error; - - imx219->sd.ctrl_handler = ctrl_hdlr; - - return 0; - -error: - v4l2_ctrl_handler_free(ctrl_hdlr); - - return ret; -} - -static void imx219_free_controls(struct imx219 *imx219) -{ - v4l2_ctrl_handler_free(imx219->sd.ctrl_handler); -} - static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219) { struct fwnode_handle *endpoint; From patchwork Mon Aug 21 22:29:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715611 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 1BEF5EE49AA for ; Mon, 21 Aug 2023 22:30:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231594AbjHUWan (ORCPT ); Mon, 21 Aug 2023 18:30:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231587AbjHUWam (ORCPT ); Mon, 21 Aug 2023 18:30:42 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA3501AD for ; Mon, 21 Aug 2023 15:30:36 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0F6DB87FC; Tue, 22 Aug 2023 00:29:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656942; bh=xO3QjUyvxcybKSIPzQQT0mLraNA35x3HBdztviI5Cs4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NIdxa0vIpltbzB1wVqCqCPLyHmCX1zoMx/vOWzi8S5t7ETkAHCR5T0UDEOoslxnao 2ZudHTqDc7AzJGFno3qHRa9ODLFzb6wOaaRtwKFbDMhb2PtQ37Ng41OkmlNy0F+wC7 uuCgx8cUtd2DLHSbHvdGlYu40wUnQztghm3BF8Ec= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 16/18] media: i2c: imx219: Calculate crop rectangle dynamically Date: Tue, 22 Aug 2023 01:29:59 +0300 Message-ID: <20230821223001.28480-17-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Calculate the crop rectangle size and location dynamically when setting the format, instead of storing it in the imx219_mode structure. This removes duplicated information from the mode, to guarantee consistency. Signed-off-by: Laurent Pinchart --- drivers/media/i2c/imx219.c | 45 +++++++++++++------------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 646d73d1e6a3..4140d9b78e4c 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -152,9 +153,6 @@ struct imx219_mode { /* Frame height */ unsigned int height; - /* Analog crop rectangle. */ - struct v4l2_rect crop; - /* V-timing */ unsigned int vts_def; }; @@ -292,48 +290,24 @@ static const struct imx219_mode supported_modes[] = { /* 8MPix 15fps mode */ .width = 3280, .height = 2464, - .crop = { - .left = IMX219_PIXEL_ARRAY_LEFT, - .top = IMX219_PIXEL_ARRAY_TOP, - .width = 3280, - .height = 2464 - }, .vts_def = 3526, }, { /* 1080P 30fps cropped */ .width = 1920, .height = 1080, - .crop = { - .left = 688, - .top = 700, - .width = 1920, - .height = 1080 - }, .vts_def = 1763, }, { /* 2x2 binned 30fps mode */ .width = 1640, .height = 1232, - .crop = { - .left = IMX219_PIXEL_ARRAY_LEFT, - .top = IMX219_PIXEL_ARRAY_TOP, - .width = 3280, - .height = 2464 - }, .vts_def = 1763, }, { /* 640x480 30fps mode */ .width = 640, .height = 480, - .crop = { - .left = 1008, - .top = 760, - .width = 1280, - .height = 960 - }, .vts_def = 1763, }, }; @@ -830,6 +804,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, int exposure_max, exposure_def, hblank; struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; + unsigned int bin; mode = v4l2_find_nearest_size(supported_modes, ARRAY_SIZE(supported_modes), @@ -839,10 +814,20 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); format = v4l2_subdev_get_pad_format(sd, sd_state, 0); - crop = v4l2_subdev_get_pad_crop(sd, sd_state, 0); - *format = fmt->format; - *crop = mode->crop; + + /* + * Use binning to maximize the crop rectangle size, and centre it in the + * sensor. Bin by the same factor horizontally and vertically. + */ + bin = min3(IMX219_PIXEL_ARRAY_WIDTH / format->width, + IMX219_PIXEL_ARRAY_HEIGHT / format->height, 2U); + + crop = v4l2_subdev_get_pad_crop(sd, sd_state, 0); + crop->width = format->width * bin; + crop->height = format->height * bin; + crop->left = (IMX219_NATIVE_WIDTH - crop->width) / 2; + crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { /* Update limits and set FPS to default */ From patchwork Mon Aug 21 22:30:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 715610 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 E0492EE49A8 for ; Mon, 21 Aug 2023 22:30:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231596AbjHUWav (ORCPT ); Mon, 21 Aug 2023 18:30:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231605AbjHUWau (ORCPT ); Mon, 21 Aug 2023 18:30:50 -0400 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 51135E4 for ; Mon, 21 Aug 2023 15:30:43 -0700 (PDT) Received: from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi [213.243.189.158]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D1624396B; Tue, 22 Aug 2023 00:29:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1692656945; bh=H8AtSEk0aRBGxZIPIdAkMiG8U+UAINzmSknpzWCG8BU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EC5pjOFQcJwMRFxWsdlXVgX3JyK23H4DOeSjpdSn3pNrXdZXEtgCNas2ZL/SmdyXq MJYXBoZMXZmLJbBJQ8L9Y0njolo6iYK0iYLhBPIfrFtLZamLipavcJZnl54l9So58w bgV8x4aJM5dHtPBX8JaCq0Df0HZTeHhNsNNGxw7A= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Dave Stevenson , Jacopo Mondi , Lad Prabhakar , Hans de Goede Subject: [PATCH v2 18/18] media: i2c: imx219: Move variables to inner scope Date: Tue, 22 Aug 2023 01:30:01 +0300 Message-ID: <20230821223001.28480-19-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> References: <20230821223001.28480-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The exposure_max, exposure_def and hblank variables are only used in an inner scope in the imx219_set_pad_format() function. Move them to that scope to keep them closer to their usage and improve readability. Signed-off-by: Laurent Pinchart Reviewed-by: Dave Stevenson --- drivers/media/i2c/imx219.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index e2f0d3782e7c..69908ebed04a 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -801,7 +801,6 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, { struct imx219 *imx219 = to_imx219(sd); const struct imx219_mode *mode; - int exposure_max, exposure_def, hblank; struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; unsigned int bin; @@ -830,6 +829,10 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + int exposure_max; + int exposure_def; + int hblank; + /* Update limits and set FPS to default */ __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, IMX219_VTS_MAX - mode->height, 1,