From patchwork Mon Dec 18 17:40:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497326 Received: from mail-lf1-f46.google.com (mail-lf1-f46.google.com [209.85.167.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5789371468; Mon, 18 Dec 2023 17:41:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="j0LS66qB" Received: by mail-lf1-f46.google.com with SMTP id 2adb3069b0e04-50e389473fcso1732643e87.2; Mon, 18 Dec 2023 09:40:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921257; x=1703526057; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QvzWqKWWxtF7t1ieAaxj0+EbNjoeBeyf3ul7f1hfdkU=; b=j0LS66qBoldQQ8DRkaluVySVsyyE8lqf8AxBwyCfzg1fEa0rkZNPPs6FBrCsndp1DN h2AvryR7+8tj6kna1M6TwJr71g0h/4woIMR/GGZ23Zwn41czRJSxOpN0CdFSR+VVsXAK +TyCcuYNETrefASly96hrpvJQQm26kRdr+GyQysbskllWUzQvPm6pwf0r+jM0joHiKho AwNIO7I8cKSw8GSQCIoKkgkjAhpThV3bhsi9YQaLTT35blC9sU5GOhRIXqtCc+8QSANa qo955JMLaKaOEVPeFQGK+L7j3hckNw6Dm2Rkdb1/9JwxjxrjWG+DVwgZAaOYEPeFNHGv AbGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921257; x=1703526057; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QvzWqKWWxtF7t1ieAaxj0+EbNjoeBeyf3ul7f1hfdkU=; b=UvA/FLMmQefvKvolub9P35LwhKNALOQi9LLOMQBT/MOlz6STlK7V11D7yQj3ieHvWg VdBMOWRIwJJZPIlUCZf1IN9GrfXJ5D2EZg8Fewi0nEUPQTB3fpXrk46+aShmF+C933Rl l/7EaN60Dkhnd9H1Y9Px81N5R7CW14b02X6RiDou7t3aC7Tgh94x9MNTq3SbmYYJad7N vH3aJRdg8FcUnc1/zW8RGSplNzD//A86nIGlbOR7EJ9PuCO73FHCtQxNyKlWr1G6+oSo jV5m4u+5MlQ8EjDoA/UcN63kfoyb9mrke5kIJzW8aG4Jrv4cxDTBsm1HdYgHDh9yVLA4 raBQ== X-Gm-Message-State: AOJu0Yxt8cVXK7sDqRN/cNzp9DpqGHZf6QKPgdExjGlvXoDDIgxUQ8Cl VXjLHfAEGxqCa4cZLnRXU1chnzma3XpEzQ== X-Google-Smtp-Source: AGHT+IFRZlYiV1RrtKLd/tt7YdaB8WYCS3mHUoi9HVIFDw+Sw/cPdJXGmipZyR1nbzVsPGbdrv/86w== X-Received: by 2002:a05:6512:6e:b0:50e:20fe:2c66 with SMTP id i14-20020a056512006e00b0050e20fe2c66mr1950035lfo.46.1702921257312; Mon, 18 Dec 2023 09:40:57 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id eq24-20020a056512489800b0050e233d2533sm803945lfb.159.2023.12.18.09.40.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:40:57 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 01/20] media: i2c: ov4689: Clean up and annotate the register table Date: Mon, 18 Dec 2023 20:40:22 +0300 Message-ID: <20231218174042.794012-2-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Many values in the register table are actually power-on defaults. Remove those and also unused HDR exposures and gains. Annotate the remaining values using the publicly available datasheet to facilitate further development. No functional change intended. Signed-off-by: Mikhail Rudenko Acked-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 203 +++++++++++++++++++++---------------- 1 file changed, 118 insertions(+), 85 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 403091651885..ff5213862974 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -3,7 +3,7 @@ * ov4689 driver * * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. - * Copyright (C) 2022 Mikhail Rudenko + * Copyright (C) 2022, 2023 Mikhail Rudenko */ #include @@ -123,90 +123,123 @@ struct ov4689_gain_range { * mipi_datarate per lane 1008Mbps */ static const struct regval ov4689_2688x1520_regs[] = { - {0x0103, 0x01}, {0x3638, 0x00}, {0x0300, 0x00}, - {0x0302, 0x2a}, {0x0303, 0x00}, {0x0304, 0x03}, - {0x030b, 0x00}, {0x030d, 0x1e}, {0x030e, 0x04}, - {0x030f, 0x01}, {0x0312, 0x01}, {0x031e, 0x00}, - {0x3000, 0x20}, {0x3002, 0x00}, {0x3018, 0x72}, - {0x3020, 0x93}, {0x3021, 0x03}, {0x3022, 0x01}, - {0x3031, 0x0a}, {0x303f, 0x0c}, {0x3305, 0xf1}, - {0x3307, 0x04}, {0x3309, 0x29}, {0x3500, 0x00}, - {0x3501, 0x60}, {0x3502, 0x00}, {0x3503, 0x04}, - {0x3504, 0x00}, {0x3505, 0x00}, {0x3506, 0x00}, - {0x3507, 0x00}, {0x3508, 0x00}, {0x3509, 0x80}, - {0x350a, 0x00}, {0x350b, 0x00}, {0x350c, 0x00}, - {0x350d, 0x00}, {0x350e, 0x00}, {0x350f, 0x80}, - {0x3510, 0x00}, {0x3511, 0x00}, {0x3512, 0x00}, - {0x3513, 0x00}, {0x3514, 0x00}, {0x3515, 0x80}, - {0x3516, 0x00}, {0x3517, 0x00}, {0x3518, 0x00}, - {0x3519, 0x00}, {0x351a, 0x00}, {0x351b, 0x80}, - {0x351c, 0x00}, {0x351d, 0x00}, {0x351e, 0x00}, - {0x351f, 0x00}, {0x3520, 0x00}, {0x3521, 0x80}, - {0x3522, 0x08}, {0x3524, 0x08}, {0x3526, 0x08}, - {0x3528, 0x08}, {0x352a, 0x08}, {0x3602, 0x00}, - {0x3603, 0x40}, {0x3604, 0x02}, {0x3605, 0x00}, - {0x3606, 0x00}, {0x3607, 0x00}, {0x3609, 0x12}, - {0x360a, 0x40}, {0x360c, 0x08}, {0x360f, 0xe5}, - {0x3608, 0x8f}, {0x3611, 0x00}, {0x3613, 0xf7}, - {0x3616, 0x58}, {0x3619, 0x99}, {0x361b, 0x60}, - {0x361c, 0x7a}, {0x361e, 0x79}, {0x361f, 0x02}, - {0x3632, 0x00}, {0x3633, 0x10}, {0x3634, 0x10}, - {0x3635, 0x10}, {0x3636, 0x15}, {0x3646, 0x86}, - {0x364a, 0x0b}, {0x3700, 0x17}, {0x3701, 0x22}, - {0x3703, 0x10}, {0x370a, 0x37}, {0x3705, 0x00}, - {0x3706, 0x63}, {0x3709, 0x3c}, {0x370b, 0x01}, - {0x370c, 0x30}, {0x3710, 0x24}, {0x3711, 0x0c}, - {0x3716, 0x00}, {0x3720, 0x28}, {0x3729, 0x7b}, - {0x372a, 0x84}, {0x372b, 0xbd}, {0x372c, 0xbc}, - {0x372e, 0x52}, {0x373c, 0x0e}, {0x373e, 0x33}, - {0x3743, 0x10}, {0x3744, 0x88}, {0x3745, 0xc0}, - {0x374a, 0x43}, {0x374c, 0x00}, {0x374e, 0x23}, - {0x3751, 0x7b}, {0x3752, 0x84}, {0x3753, 0xbd}, - {0x3754, 0xbc}, {0x3756, 0x52}, {0x375c, 0x00}, - {0x3760, 0x00}, {0x3761, 0x00}, {0x3762, 0x00}, - {0x3763, 0x00}, {0x3764, 0x00}, {0x3767, 0x04}, - {0x3768, 0x04}, {0x3769, 0x08}, {0x376a, 0x08}, - {0x376b, 0x20}, {0x376c, 0x00}, {0x376d, 0x00}, - {0x376e, 0x00}, {0x3773, 0x00}, {0x3774, 0x51}, - {0x3776, 0xbd}, {0x3777, 0xbd}, {0x3781, 0x18}, - {0x3783, 0x25}, {0x3798, 0x1b}, {0x3800, 0x00}, - {0x3801, 0x08}, {0x3802, 0x00}, {0x3803, 0x04}, - {0x3804, 0x0a}, {0x3805, 0x97}, {0x3806, 0x05}, - {0x3807, 0xfb}, {0x3808, 0x0a}, {0x3809, 0x80}, - {0x380a, 0x05}, {0x380b, 0xf0}, {0x380c, 0x0a}, - {0x380d, 0x0e}, {0x380e, 0x06}, {0x380f, 0x12}, - {0x3810, 0x00}, {0x3811, 0x08}, {0x3812, 0x00}, - {0x3813, 0x04}, {0x3814, 0x01}, {0x3815, 0x01}, - {0x3819, 0x01}, {0x3820, 0x00}, {0x3821, 0x06}, - {0x3829, 0x00}, {0x382a, 0x01}, {0x382b, 0x01}, - {0x382d, 0x7f}, {0x3830, 0x04}, {0x3836, 0x01}, - {0x3837, 0x00}, {0x3841, 0x02}, {0x3846, 0x08}, - {0x3847, 0x07}, {0x3d85, 0x36}, {0x3d8c, 0x71}, - {0x3d8d, 0xcb}, {0x3f0a, 0x00}, {0x4000, 0xf1}, - {0x4001, 0x40}, {0x4002, 0x04}, {0x4003, 0x14}, - {0x400e, 0x00}, {0x4011, 0x00}, {0x401a, 0x00}, - {0x401b, 0x00}, {0x401c, 0x00}, {0x401d, 0x00}, - {0x401f, 0x00}, {0x4020, 0x00}, {0x4021, 0x10}, - {0x4022, 0x07}, {0x4023, 0xcf}, {0x4024, 0x09}, - {0x4025, 0x60}, {0x4026, 0x09}, {0x4027, 0x6f}, - {0x4028, 0x00}, {0x4029, 0x02}, {0x402a, 0x06}, - {0x402b, 0x04}, {0x402c, 0x02}, {0x402d, 0x02}, - {0x402e, 0x0e}, {0x402f, 0x04}, {0x4302, 0xff}, - {0x4303, 0xff}, {0x4304, 0x00}, {0x4305, 0x00}, - {0x4306, 0x00}, {0x4308, 0x02}, {0x4500, 0x6c}, - {0x4501, 0xc4}, {0x4502, 0x40}, {0x4503, 0x01}, - {0x4601, 0xa7}, {0x4800, 0x04}, {0x4813, 0x08}, - {0x481f, 0x40}, {0x4829, 0x78}, {0x4837, 0x10}, - {0x4b00, 0x2a}, {0x4b0d, 0x00}, {0x4d00, 0x04}, - {0x4d01, 0x42}, {0x4d02, 0xd1}, {0x4d03, 0x93}, - {0x4d04, 0xf5}, {0x4d05, 0xc1}, {0x5000, 0xf3}, - {0x5001, 0x11}, {0x5004, 0x00}, {0x500a, 0x00}, - {0x500b, 0x00}, {0x5032, 0x00}, {0x5040, 0x00}, - {0x5050, 0x0c}, {0x5500, 0x00}, {0x5501, 0x10}, - {0x5502, 0x01}, {0x5503, 0x0f}, {0x8000, 0x00}, - {0x8001, 0x00}, {0x8002, 0x00}, {0x8003, 0x00}, - {0x8004, 0x00}, {0x8005, 0x00}, {0x8006, 0x00}, - {0x8007, 0x00}, {0x8008, 0x00}, {0x3638, 0x00}, + /* System control*/ + {0x0103, 0x01}, /* SC_CTRL0103 software_reset = 1 */ + {0x3000, 0x20}, /* SC_CMMN_PAD_OEN0 FSIN_output_enable = 1 */ + {0x3021, 0x03}, /* + * SC_CMMN_MISC_CTRL fst_stby_ctr = 0, + * sleep_no_latch_enable = 0 + */ + + /* AEC PK */ + {0x3503, 0x04}, /* AEC_MANUAL gain_input_as_sensor_gain_format = 1 */ + {0x352a, 0x08}, /* DIG_GAIN_FRAC_LONG dig_gain_long[14:8] = 0x08 (2x) */ + + /* ADC and analog control*/ + {0x3603, 0x40}, + {0x3604, 0x02}, + {0x3609, 0x12}, + {0x360c, 0x08}, + {0x360f, 0xe5}, + {0x3608, 0x8f}, + {0x3611, 0x00}, + {0x3613, 0xf7}, + {0x3616, 0x58}, + {0x3619, 0x99}, + {0x361b, 0x60}, + {0x361e, 0x79}, + {0x3634, 0x10}, + {0x3635, 0x10}, + {0x3636, 0x15}, + {0x3646, 0x86}, + {0x364a, 0x0b}, + + /* Sensor control */ + {0x3700, 0x17}, + {0x3701, 0x22}, + {0x3703, 0x10}, + {0x370a, 0x37}, + {0x3706, 0x63}, + {0x3709, 0x3c}, + {0x370c, 0x30}, + {0x3710, 0x24}, + {0x3720, 0x28}, + {0x3729, 0x7b}, + {0x372b, 0xbd}, + {0x372c, 0xbc}, + {0x372e, 0x52}, + {0x373c, 0x0e}, + {0x373e, 0x33}, + {0x3743, 0x10}, + {0x3744, 0x88}, + {0x3745, 0xc0}, + {0x374c, 0x00}, + {0x374e, 0x23}, + {0x3751, 0x7b}, + {0x3753, 0xbd}, + {0x3754, 0xbc}, + {0x3756, 0x52}, + {0x376b, 0x20}, + {0x3774, 0x51}, + {0x3776, 0xbd}, + {0x3777, 0xbd}, + {0x3781, 0x18}, + {0x3783, 0x25}, + {0x3798, 0x1b}, + + /* Timing control */ + {0x3801, 0x08}, /* H_CROP_START_L h_crop_start[7:0] = 0x08 */ + {0x3805, 0x97}, /* H_CROP_END_L h_crop_end[7:0] = 0x97 */ + {0x380c, 0x0a}, /* TIMING_HTS_H hts[14:8] = 0x0a */ + {0x380d, 0x0e}, /* TIMING_HTS_L hts[7:0] = 0x0e */ + {0x3811, 0x08}, /* H_WIN_OFF_L h_win_off[7:0] = 0x08*/ + {0x3813, 0x04}, /* V_WIN_OFF_L v_win_off[7:0] = 0x04 */ + {0x3819, 0x01}, /* VSYNC_END_L vsync_end_point[7:0] = 0x01 */ + {0x3821, 0x06}, /* TIMING_FORMAT2 array_h_mirror = 1, digital_h_mirror = 1 */ + + /* OTP control */ + {0x3d85, 0x36}, /* OTP_REG85 OTP_power_up_load_setting_enable = 1, + * OTP_power_up_load_data_enable = 1, + * OTP_bist_select = 1 (compare with zero) + */ + {0x3d8c, 0x71}, /* OTP_SETTING_STT_ADDRESS_H */ + {0x3d8d, 0xcb}, /* OTP_SETTING_STT_ADDRESS_L */ + + /* BLC registers*/ + {0x4001, 0x40}, /* DEBUG_MODE */ + {0x401b, 0x00}, /* DEBUG_MODE */ + {0x401d, 0x00}, /* DEBUG_MODE */ + {0x401f, 0x00}, /* DEBUG_MODE */ + {0x4020, 0x00}, /* ANCHOR_LEFT_START_H anchor_left_start[11:8] = 0 */ + {0x4021, 0x10}, /* ANCHOR_LEFT_START_L anchor_left_start[7:0] = 0x10 */ + {0x4022, 0x07}, /* ANCHOR_LEFT_END_H anchor_left_end[11:8] = 0x07 */ + {0x4023, 0xcf}, /* ANCHOR_LEFT_END_L anchor_left_end[7:0] = 0xcf */ + {0x4024, 0x09}, /* ANCHOR_RIGHT_START_H anchor_right_start[11:8] = 0x09 */ + {0x4025, 0x60}, /* ANCHOR_RIGHT_START_L anchor_right_start[7:0] = 0x60 */ + {0x4026, 0x09}, /* ANCHOR_RIGHT_END_H anchor_right_end[11:8] = 0x09 */ + {0x4027, 0x6f}, /* ANCHOR_RIGHT_END_L anchor_right_end[7:0] = 0x6f */ + + /* ADC sync control */ + {0x4500, 0x6c}, /* ADC_SYNC_CTRL */ + {0x4503, 0x01}, /* ADC_SYNC_CTRL */ + + /* VFIFO */ + {0x4601, 0xa7}, /* VFIFO_CTRL_01 r_vfifo_read_start[7:0] = 0xa7 */ + + /* Temperature monitor */ + {0x4d00, 0x04}, /* TPM_CTRL_00 tmp_slope[15:8] = 0x04 */ + {0x4d01, 0x42}, /* TPM_CTRL_01 tmp_slope[7:0] = 0x42 */ + {0x4d02, 0xd1}, /* TPM_CTRL_02 tpm_offset[31:24] = 0xd1 */ + {0x4d03, 0x93}, /* TPM_CTRL_03 tpm_offset[23:16] = 0x93 */ + {0x4d04, 0xf5}, /* TPM_CTRL_04 tpm_offset[15:8] = 0xf5 */ + {0x4d05, 0xc1}, /* TPM_CTRL_05 tpm_offset[7:0] = 0xc1 */ + + /* pre-ISP control */ + {0x5050, 0x0c}, /* DEBUG_MODE */ + + /* OTP-DPC control */ + {0x5501, 0x10}, /* OTP_DPC_START_L otp_start_address[7:0] = 0x10 */ + {0x5503, 0x0f}, /* OTP_DPC_END_L otp_end_address[7:0] = 0x0f */ {REG_NULL, 0x00}, }; From patchwork Mon Dec 18 17:40:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497327 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD75E5D758; Mon, 18 Dec 2023 17:41:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="C1iYIqPT" Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-50e2bd8c396so2410919e87.0; Mon, 18 Dec 2023 09:41:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921259; x=1703526059; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4czKecRr4zUiqvQxmuxZf3Bt0qVxMHQuUS2sRj3gQ9o=; b=C1iYIqPTprmgc3srMBvzf+1LlOOCtfy1qNb8XLA+RoGDnAyPrPcuhfHw28bHgB8xSY +2bTZqTkpGqCqLCq7yE9wzO7E3AWKkd8283uohkM5KKUm61Qvd60StIepgfhYO4Wad4y UkoaavQ8sE+LBDNK7uCckL6/X7G2tlVDedEeDdGud5q+fL8siPEbv45MiZNBmyeki7+S 1TRPwf7EFpm/i/No26Kpc6GVPT8uk+bA0yMVr4s3Dx+MwHDMhh0cWMYAu8+Twae43BiI ko8e4iqisY+v5Ke/vPR07UiQbKQGKWWUeX/YLVA15QUcYJarhR8AIlLdprBpx6MEG0pD x9AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921259; x=1703526059; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4czKecRr4zUiqvQxmuxZf3Bt0qVxMHQuUS2sRj3gQ9o=; b=cKKXg2oa7Dw/rK/69pxSAx5IivYBwRmSBrh0e5LE7UeAaO+q+UJ7rQH41Gftc17doQ NFnVZ6RvnUVOpaEN4KopQFbnwIphfEI0bwp4kP1RfFJ3Mq79ROCoLWvk2GqqNpJ4yF4e HceQfcFGU43SyCU0dhOIZkSaXkzfZQ0AOQmj+9m5x7OZjCbC0X7Bqfaz/PdxiVvVaLq+ ZVYd9Is+CxLi8F26tjvuTwgq2N+hxE6IhqcMJhVboXKQ5FFkZ0OOToRbRl3hQxN0pLDS HxbfJ8AG7YrQpzz4w+/s5j166UdMG6nMtHsLGHAyakZ4rqr/c6hl5EqH8NbsRnjIhUPg RI+Q== X-Gm-Message-State: AOJu0YyUqi9wl1wzpkZN+oouHBocuw+DkvOWTvguxNSu3MXNNYemxI7N wgLKifON83DSup2BRkz+/fX4Dt3u5OSfSg== X-Google-Smtp-Source: AGHT+IF4lP7MpuXlO75JEsjQJQGiM5DfUKgEoAQdcHqU26QULwmPYfDFq1YYAWU3s8IVdwpnwkLHig== X-Received: by 2002:ac2:5f7c:0:b0:50e:2275:59bb with SMTP id c28-20020ac25f7c000000b0050e227559bbmr2351376lfc.44.1702921258994; Mon, 18 Dec 2023 09:40:58 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id dx6-20020a0565122c0600b0050e3cd7444asm226006lfb.15.2023.12.18.09.40.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:40:58 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 02/20] media: i2c: ov4689: Sort register definitions by address Date: Mon, 18 Dec 2023 20:40:23 +0300 Message-ID: <20231218174042.794012-3-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Put register defininitions in the order of increasing register address. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index ff5213862974..1ae6d9b9c9b3 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -19,15 +19,15 @@ #include #include -#define CHIP_ID 0x004688 -#define OV4689_REG_CHIP_ID 0x300a - #define OV4689_XVCLK_FREQ 24000000 #define OV4689_REG_CTRL_MODE 0x0100 #define OV4689_MODE_SW_STANDBY 0x0 #define OV4689_MODE_STREAMING BIT(0) +#define OV4689_REG_CHIP_ID 0x300a +#define CHIP_ID 0x004688 + #define OV4689_REG_EXPOSURE 0x3500 #define OV4689_EXPOSURE_MIN 4 #define OV4689_EXPOSURE_STEP 1 @@ -41,12 +41,12 @@ #define OV4689_GAIN_STEP 1 #define OV4689_GAIN_DEFAULT 0x80 +#define OV4689_REG_VTS 0x380e + #define OV4689_REG_TEST_PATTERN 0x5040 #define OV4689_TEST_PATTERN_ENABLE 0x80 #define OV4689_TEST_PATTERN_DISABLE 0x0 -#define OV4689_REG_VTS 0x380e - #define REG_NULL 0xFFFF #define OV4689_REG_VALUE_08BIT 1 From patchwork Mon Dec 18 17:40:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497328 Received: from mail-lf1-f52.google.com (mail-lf1-f52.google.com [209.85.167.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28ADF5D75A; Mon, 18 Dec 2023 17:41:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SiBl11nX" Received: by mail-lf1-f52.google.com with SMTP id 2adb3069b0e04-50e389473fcso1732707e87.2; Mon, 18 Dec 2023 09:41:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921260; x=1703526060; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lTDInBpm9IOKZKwVJjEBdmix1UD/v8KGld+1PsGVp6w=; b=SiBl11nXBEMHTM5Oe5DpIjlyoSvW9JFsoiLyu4PRkumz9HCk71neQmlVGjuqgr+oCl TdQeuEy4cCmkR8zOgT1HbVPnAR0h4MjgEudfjWCzP53Y26qfDWxCGDWp7YgF4KQVDDVU qNQ4qYayOlC1WcfXvs9zAzgvobdjZnAmRBcKBm7Pkk76mJh+3kCC/RlNPHYKDHIoR+Yb XdpnKHdAtLGyOJcYZ2fKv6jhjzZwQKJlsVEJSGFgAGJPgskTPeSvW8Jkb9HwjynOQbGf Cz2kQxyiWUb/nBpsiSzfS3Va/UGy45SsJ4zzpNnmexOta5j+VNzOtlWrQ0kf9SFDpF5e jiEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921260; x=1703526060; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lTDInBpm9IOKZKwVJjEBdmix1UD/v8KGld+1PsGVp6w=; b=nFmvA/rMl1UKeopbR6X8zBhaaSSNiBTQVu+ssWBDyvb4SKDz6rqsNcqXVV3DtnuSLj zxT++KHIGz6ASK2LOOCUMyhDu4dSqmTAAr41RxCMJ/PEj/FjDK3CG2rHHxboV6M4JI6v uRkHl8CJ2ONWNvsD/JuWQBHu76aIabJc5mfGy/8gRD6yQ/7ALMKUnNjTlC47yL7heCSy 3hnp6nykzVecpHB6+s9juIhVesofn7kU4wahW1wuw0lAPh3F79EbVtjMys01RON7ZV67 oCruYoDON3+GSjEEd+D6mXQ3G0yjhT6UIDfSJl7LBAx23mh9H6nVvimcUZ4AapVcB3/m SzTQ== X-Gm-Message-State: AOJu0Yy+8INZZ3z/J8E2DGxdOq9z8/E2SZKMxgK/keFpy01q0gz+7MSN VOUSJaEdTz4xdNhkZd8bstSJbQQn3LPv4w== X-Google-Smtp-Source: AGHT+IF8m8vP0MsejeJK8yQbMHuQD09w2Ti/wP3cYuz/5CHJeklc0I5BDObhq9cKffHNyB42jbQiIQ== X-Received: by 2002:ac2:46f3:0:b0:50e:24c4:6080 with SMTP id q19-20020ac246f3000000b0050e24c46080mr1815577lfo.7.1702921260303; Mon, 18 Dec 2023 09:41:00 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id k5-20020ac24f05000000b005094486b705sm3016372lfr.16.2023.12.18.09.40.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:00 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 03/20] media: i2c: ov4689: Fix typo in a comment Date: Mon, 18 Dec 2023 20:40:24 +0300 Message-ID: <20231218174042.794012-4-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Fix a spelling error in a comment. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 1ae6d9b9c9b3..7c33961fbb89 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -692,7 +692,7 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_EXPOSURE: - /* 4 least significant bits of expsoure are fractional part */ + /* 4 least significant bits of exposure are fractional part */ ret = ov4689_write_reg(ov4689->client, OV4689_REG_EXPOSURE, OV4689_REG_VALUE_24BIT, ctrl->val << 4); break; From patchwork Mon Dec 18 17:40:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497329 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCBBC7146C; Mon, 18 Dec 2023 17:41:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gvU7vlFc" Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-50e389473fcso1732812e87.2; Mon, 18 Dec 2023 09:41:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921262; x=1703526062; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=b+z53GlwzR6CHam2mzBPbYh2yRBDEISJoZAlKq8qtpo=; b=gvU7vlFc6ex3gCfccLU139DJI9hqOvbeUPCJqzm8DXgvzXYKA8S/DACjd10042LQiT ZEs6BZxZv27fLVmLBosaLaK5Ny13UDssrk3vnQzM97FLGpqfKqeGlT+01RqrIqO/JQs2 TuJU6bP20zibwJlEloPnkvfRIT4opiYXBpSJAqwzWHVVpwyckSe4O0TcnjqqcI+NixdU GXIxLXhvZgOShUCL7Al9o0TISnjXmWs/kT+xFEaPjsGqUysZznM4ku1IcpFCw9J5Ffkc ibU/8clfX7Xasdm0Dto3WlghzmKz9JkhWcfyzp+NPNNXvjoSo4hAKcHFV+CY4YCsJwLG ybJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921262; x=1703526062; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=b+z53GlwzR6CHam2mzBPbYh2yRBDEISJoZAlKq8qtpo=; b=Wcqgmn/kw4S3K5FTNQBIApAhp5sODdSPNciGV9m0GX1n64s5JKVx6n9VzdLYeTyAR4 XjShjNBEIngTeMrC/JpwqDIa1OC9zc0nZb4Bm+3NuechGjnGIYZqU1s16cs4xTuBge9o c40ZuKic2IcdfoIvCV1vvzCs+EvATKG9JDo4U0cfJntjkL1Kv54cHxyVrcMTwU+sxhLc nkEWfTSIXeWNodqIMvj5U7THHdFNsTJ/WMJTfxgOSHaeG4X5vhmTXIqtbJDX53Ptv3QZ eN5rdZXUy9iW/b7a4JGsoJiiIEgpXVxxtHzSbcGbayLSKmLlSdH2cay2nCQ1fVqM3Nzr bo8Q== X-Gm-Message-State: AOJu0YwKPHWP6rwCwx/YJJiKahJ+gnH2yKux29TgQBJwg7u3BKZIz5XP ywTA0jfuGgvIlp6dGldX3jUcGUbR9Bp7Fg== X-Google-Smtp-Source: AGHT+IHkCEt1zwIu/QKcLXDmE2UlRPNSZ8fIUR+HE4LaOSwyldtx15pX9X0FiK/Y2G6+/MluCeLMhA== X-Received: by 2002:a05:6512:6c1:b0:50e:1f22:3110 with SMTP id u1-20020a05651206c100b0050e1f223110mr2838827lff.65.1702921261733; Mon, 18 Dec 2023 09:41:01 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id c13-20020a056512104d00b0050e2036327esm907828lfb.252.2023.12.18.09.41.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:01 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 04/20] media: i2c: ov4689: CCI conversion Date: Mon, 18 Dec 2023 20:40:25 +0300 Message-ID: <20231218174042.794012-5-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Convert the i2c register accesses to utilize the CCI helper library rather than relying on driver-specific functions. Also, set analogue gain in a single 16-bit write instead of two 8-bit writes. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/ov4689.c | 358 ++++++++++++++----------------------- 2 files changed, 133 insertions(+), 226 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 78a87331686e..b3153bb769b7 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -404,6 +404,7 @@ config VIDEO_OV2740 config VIDEO_OV4689 tristate "OmniVision OV4689 sensor support" depends on GPIOLIB + select V4L2_CCI_I2C help This is a Video4Linux2 sensor-level driver for the OmniVision OV4689 camera. diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 7c33961fbb89..6ea1c37323d1 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -15,45 +15,35 @@ #include #include #include +#include #include #include #include -#define OV4689_XVCLK_FREQ 24000000 - -#define OV4689_REG_CTRL_MODE 0x0100 +#define OV4689_REG_CTRL_MODE CCI_REG8(0x0100) #define OV4689_MODE_SW_STANDBY 0x0 #define OV4689_MODE_STREAMING BIT(0) -#define OV4689_REG_CHIP_ID 0x300a +#define OV4689_REG_CHIP_ID CCI_REG16(0x300a) #define CHIP_ID 0x004688 -#define OV4689_REG_EXPOSURE 0x3500 +#define OV4689_REG_EXPOSURE CCI_REG24(0x3500) #define OV4689_EXPOSURE_MIN 4 #define OV4689_EXPOSURE_STEP 1 #define OV4689_VTS_MAX 0x7fff -#define OV4689_REG_GAIN_H 0x3508 -#define OV4689_REG_GAIN_L 0x3509 -#define OV4689_GAIN_H_MASK 0x07 -#define OV4689_GAIN_H_SHIFT 8 -#define OV4689_GAIN_L_MASK 0xff +#define OV4689_REG_GAIN CCI_REG16(0x3508) #define OV4689_GAIN_STEP 1 #define OV4689_GAIN_DEFAULT 0x80 -#define OV4689_REG_VTS 0x380e +#define OV4689_REG_VTS CCI_REG16(0x380e) -#define OV4689_REG_TEST_PATTERN 0x5040 +#define OV4689_REG_TEST_PATTERN CCI_REG8(0x5040) #define OV4689_TEST_PATTERN_ENABLE 0x80 #define OV4689_TEST_PATTERN_DISABLE 0x0 -#define REG_NULL 0xFFFF - -#define OV4689_REG_VALUE_08BIT 1 -#define OV4689_REG_VALUE_16BIT 2 -#define OV4689_REG_VALUE_24BIT 3 - #define OV4689_LANES 4 +#define OV4689_XVCLK_FREQ 24000000 static const char *const ov4689_supply_names[] = { "avdd", /* Analog power */ @@ -61,11 +51,6 @@ static const char *const ov4689_supply_names[] = { "dvdd", /* Digital core power */ }; -struct regval { - u16 addr; - u8 val; -}; - enum ov4689_mode_id { OV4689_MODE_2688_1520 = 0, OV4689_NUM_MODES, @@ -84,11 +69,13 @@ struct ov4689_mode { u32 sensor_height; u32 crop_top; u32 crop_left; - const struct regval *reg_list; + const struct cci_reg_sequence *reg_list; + unsigned int num_regs; }; struct ov4689 { struct i2c_client *client; + struct regmap *regmap; struct clk *xvclk; struct gpio_desc *reset_gpio; struct gpio_desc *pwdn_gpio; @@ -122,125 +109,124 @@ struct ov4689_gain_range { * max_framerate 30fps * mipi_datarate per lane 1008Mbps */ -static const struct regval ov4689_2688x1520_regs[] = { +static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { /* System control*/ - {0x0103, 0x01}, /* SC_CTRL0103 software_reset = 1 */ - {0x3000, 0x20}, /* SC_CMMN_PAD_OEN0 FSIN_output_enable = 1 */ - {0x3021, 0x03}, /* - * SC_CMMN_MISC_CTRL fst_stby_ctr = 0, - * sleep_no_latch_enable = 0 - */ + {CCI_REG8(0x0103), 0x01}, /* SC_CTRL0103 software_reset = 1 */ + {CCI_REG8(0x3000), 0x20}, /* SC_CMMN_PAD_OEN0 FSIN_output_enable = 1 */ + {CCI_REG8(0x3021), 0x03}, /* + * SC_CMMN_MISC_CTRL fst_stby_ctr = 0, + * sleep_no_latch_enable = 0 + */ /* AEC PK */ - {0x3503, 0x04}, /* AEC_MANUAL gain_input_as_sensor_gain_format = 1 */ - {0x352a, 0x08}, /* DIG_GAIN_FRAC_LONG dig_gain_long[14:8] = 0x08 (2x) */ + {CCI_REG8(0x3503), 0x04}, /* AEC_MANUAL gain_input_as_sensor_gain_format = 1 */ + {CCI_REG8(0x352a), 0x08}, /* DIG_GAIN_FRAC_LONG dig_gain_long[14:8] = 0x08 (2x) */ /* ADC and analog control*/ - {0x3603, 0x40}, - {0x3604, 0x02}, - {0x3609, 0x12}, - {0x360c, 0x08}, - {0x360f, 0xe5}, - {0x3608, 0x8f}, - {0x3611, 0x00}, - {0x3613, 0xf7}, - {0x3616, 0x58}, - {0x3619, 0x99}, - {0x361b, 0x60}, - {0x361e, 0x79}, - {0x3634, 0x10}, - {0x3635, 0x10}, - {0x3636, 0x15}, - {0x3646, 0x86}, - {0x364a, 0x0b}, + {CCI_REG8(0x3603), 0x40}, + {CCI_REG8(0x3604), 0x02}, + {CCI_REG8(0x3609), 0x12}, + {CCI_REG8(0x360c), 0x08}, + {CCI_REG8(0x360f), 0xe5}, + {CCI_REG8(0x3608), 0x8f}, + {CCI_REG8(0x3611), 0x00}, + {CCI_REG8(0x3613), 0xf7}, + {CCI_REG8(0x3616), 0x58}, + {CCI_REG8(0x3619), 0x99}, + {CCI_REG8(0x361b), 0x60}, + {CCI_REG8(0x361e), 0x79}, + {CCI_REG8(0x3634), 0x10}, + {CCI_REG8(0x3635), 0x10}, + {CCI_REG8(0x3636), 0x15}, + {CCI_REG8(0x3646), 0x86}, + {CCI_REG8(0x364a), 0x0b}, /* Sensor control */ - {0x3700, 0x17}, - {0x3701, 0x22}, - {0x3703, 0x10}, - {0x370a, 0x37}, - {0x3706, 0x63}, - {0x3709, 0x3c}, - {0x370c, 0x30}, - {0x3710, 0x24}, - {0x3720, 0x28}, - {0x3729, 0x7b}, - {0x372b, 0xbd}, - {0x372c, 0xbc}, - {0x372e, 0x52}, - {0x373c, 0x0e}, - {0x373e, 0x33}, - {0x3743, 0x10}, - {0x3744, 0x88}, - {0x3745, 0xc0}, - {0x374c, 0x00}, - {0x374e, 0x23}, - {0x3751, 0x7b}, - {0x3753, 0xbd}, - {0x3754, 0xbc}, - {0x3756, 0x52}, - {0x376b, 0x20}, - {0x3774, 0x51}, - {0x3776, 0xbd}, - {0x3777, 0xbd}, - {0x3781, 0x18}, - {0x3783, 0x25}, - {0x3798, 0x1b}, + {CCI_REG8(0x3700), 0x17}, + {CCI_REG8(0x3701), 0x22}, + {CCI_REG8(0x3703), 0x10}, + {CCI_REG8(0x370a), 0x37}, + {CCI_REG8(0x3706), 0x63}, + {CCI_REG8(0x3709), 0x3c}, + {CCI_REG8(0x370c), 0x30}, + {CCI_REG8(0x3710), 0x24}, + {CCI_REG8(0x3720), 0x28}, + {CCI_REG8(0x3729), 0x7b}, + {CCI_REG8(0x372b), 0xbd}, + {CCI_REG8(0x372c), 0xbc}, + {CCI_REG8(0x372e), 0x52}, + {CCI_REG8(0x373c), 0x0e}, + {CCI_REG8(0x373e), 0x33}, + {CCI_REG8(0x3743), 0x10}, + {CCI_REG8(0x3744), 0x88}, + {CCI_REG8(0x3745), 0xc0}, + {CCI_REG8(0x374c), 0x00}, + {CCI_REG8(0x374e), 0x23}, + {CCI_REG8(0x3751), 0x7b}, + {CCI_REG8(0x3753), 0xbd}, + {CCI_REG8(0x3754), 0xbc}, + {CCI_REG8(0x3756), 0x52}, + {CCI_REG8(0x376b), 0x20}, + {CCI_REG8(0x3774), 0x51}, + {CCI_REG8(0x3776), 0xbd}, + {CCI_REG8(0x3777), 0xbd}, + {CCI_REG8(0x3781), 0x18}, + {CCI_REG8(0x3783), 0x25}, + {CCI_REG8(0x3798), 0x1b}, /* Timing control */ - {0x3801, 0x08}, /* H_CROP_START_L h_crop_start[7:0] = 0x08 */ - {0x3805, 0x97}, /* H_CROP_END_L h_crop_end[7:0] = 0x97 */ - {0x380c, 0x0a}, /* TIMING_HTS_H hts[14:8] = 0x0a */ - {0x380d, 0x0e}, /* TIMING_HTS_L hts[7:0] = 0x0e */ - {0x3811, 0x08}, /* H_WIN_OFF_L h_win_off[7:0] = 0x08*/ - {0x3813, 0x04}, /* V_WIN_OFF_L v_win_off[7:0] = 0x04 */ - {0x3819, 0x01}, /* VSYNC_END_L vsync_end_point[7:0] = 0x01 */ - {0x3821, 0x06}, /* TIMING_FORMAT2 array_h_mirror = 1, digital_h_mirror = 1 */ + {CCI_REG8(0x3801), 0x08}, /* H_CROP_START_L h_crop_start[7:0] = 0x08 */ + {CCI_REG8(0x3805), 0x97}, /* H_CROP_END_L h_crop_end[7:0] = 0x97 */ + {CCI_REG8(0x380c), 0x0a}, /* TIMING_HTS_H hts[14:8] = 0x0a */ + {CCI_REG8(0x380d), 0x0e}, /* TIMING_HTS_L hts[7:0] = 0x0e */ + {CCI_REG8(0x3811), 0x08}, /* H_WIN_OFF_L h_win_off[7:0] = 0x08*/ + {CCI_REG8(0x3813), 0x04}, /* V_WIN_OFF_L v_win_off[7:0] = 0x04 */ + {CCI_REG8(0x3819), 0x01}, /* VSYNC_END_L vsync_end_point[7:0] = 0x01 */ + {CCI_REG8(0x3821), 0x06}, /* TIMING_FORMAT2 array_h_mirror = 1, digital_h_mirror = 1 */ /* OTP control */ - {0x3d85, 0x36}, /* OTP_REG85 OTP_power_up_load_setting_enable = 1, - * OTP_power_up_load_data_enable = 1, - * OTP_bist_select = 1 (compare with zero) - */ - {0x3d8c, 0x71}, /* OTP_SETTING_STT_ADDRESS_H */ - {0x3d8d, 0xcb}, /* OTP_SETTING_STT_ADDRESS_L */ + {CCI_REG8(0x3d85), 0x36}, /* OTP_REG85 OTP_power_up_load_setting_enable = 1, + * OTP_power_up_load_data_enable = 1, + * OTP_bist_select = 1 (compare with zero) + */ + {CCI_REG8(0x3d8c), 0x71}, /* OTP_SETTING_STT_ADDRESS_H */ + {CCI_REG8(0x3d8d), 0xcb}, /* OTP_SETTING_STT_ADDRESS_L */ /* BLC registers*/ - {0x4001, 0x40}, /* DEBUG_MODE */ - {0x401b, 0x00}, /* DEBUG_MODE */ - {0x401d, 0x00}, /* DEBUG_MODE */ - {0x401f, 0x00}, /* DEBUG_MODE */ - {0x4020, 0x00}, /* ANCHOR_LEFT_START_H anchor_left_start[11:8] = 0 */ - {0x4021, 0x10}, /* ANCHOR_LEFT_START_L anchor_left_start[7:0] = 0x10 */ - {0x4022, 0x07}, /* ANCHOR_LEFT_END_H anchor_left_end[11:8] = 0x07 */ - {0x4023, 0xcf}, /* ANCHOR_LEFT_END_L anchor_left_end[7:0] = 0xcf */ - {0x4024, 0x09}, /* ANCHOR_RIGHT_START_H anchor_right_start[11:8] = 0x09 */ - {0x4025, 0x60}, /* ANCHOR_RIGHT_START_L anchor_right_start[7:0] = 0x60 */ - {0x4026, 0x09}, /* ANCHOR_RIGHT_END_H anchor_right_end[11:8] = 0x09 */ - {0x4027, 0x6f}, /* ANCHOR_RIGHT_END_L anchor_right_end[7:0] = 0x6f */ + {CCI_REG8(0x4001), 0x40}, /* DEBUG_MODE */ + {CCI_REG8(0x401b), 0x00}, /* DEBUG_MODE */ + {CCI_REG8(0x401d), 0x00}, /* DEBUG_MODE */ + {CCI_REG8(0x401f), 0x00}, /* DEBUG_MODE */ + {CCI_REG8(0x4020), 0x00}, /* ANCHOR_LEFT_START_H anchor_left_start[11:8] = 0 */ + {CCI_REG8(0x4021), 0x10}, /* ANCHOR_LEFT_START_L anchor_left_start[7:0] = 0x10 */ + {CCI_REG8(0x4022), 0x07}, /* ANCHOR_LEFT_END_H anchor_left_end[11:8] = 0x07 */ + {CCI_REG8(0x4023), 0xcf}, /* ANCHOR_LEFT_END_L anchor_left_end[7:0] = 0xcf */ + {CCI_REG8(0x4024), 0x09}, /* ANCHOR_RIGHT_START_H anchor_right_start[11:8] = 0x09 */ + {CCI_REG8(0x4025), 0x60}, /* ANCHOR_RIGHT_START_L anchor_right_start[7:0] = 0x60 */ + {CCI_REG8(0x4026), 0x09}, /* ANCHOR_RIGHT_END_H anchor_right_end[11:8] = 0x09 */ + {CCI_REG8(0x4027), 0x6f}, /* ANCHOR_RIGHT_END_L anchor_right_end[7:0] = 0x6f */ /* ADC sync control */ - {0x4500, 0x6c}, /* ADC_SYNC_CTRL */ - {0x4503, 0x01}, /* ADC_SYNC_CTRL */ + {CCI_REG8(0x4500), 0x6c}, /* ADC_SYNC_CTRL */ + {CCI_REG8(0x4503), 0x01}, /* ADC_SYNC_CTRL */ /* VFIFO */ - {0x4601, 0xa7}, /* VFIFO_CTRL_01 r_vfifo_read_start[7:0] = 0xa7 */ + {CCI_REG8(0x4601), 0xa7}, /* VFIFO_CTRL_01 r_vfifo_read_start[7:0] = 0xa7 */ /* Temperature monitor */ - {0x4d00, 0x04}, /* TPM_CTRL_00 tmp_slope[15:8] = 0x04 */ - {0x4d01, 0x42}, /* TPM_CTRL_01 tmp_slope[7:0] = 0x42 */ - {0x4d02, 0xd1}, /* TPM_CTRL_02 tpm_offset[31:24] = 0xd1 */ - {0x4d03, 0x93}, /* TPM_CTRL_03 tpm_offset[23:16] = 0x93 */ - {0x4d04, 0xf5}, /* TPM_CTRL_04 tpm_offset[15:8] = 0xf5 */ - {0x4d05, 0xc1}, /* TPM_CTRL_05 tpm_offset[7:0] = 0xc1 */ + {CCI_REG8(0x4d00), 0x04}, /* TPM_CTRL_00 tmp_slope[15:8] = 0x04 */ + {CCI_REG8(0x4d01), 0x42}, /* TPM_CTRL_01 tmp_slope[7:0] = 0x42 */ + {CCI_REG8(0x4d02), 0xd1}, /* TPM_CTRL_02 tpm_offset[31:24] = 0xd1 */ + {CCI_REG8(0x4d03), 0x93}, /* TPM_CTRL_03 tpm_offset[23:16] = 0x93 */ + {CCI_REG8(0x4d04), 0xf5}, /* TPM_CTRL_04 tpm_offset[15:8] = 0xf5 */ + {CCI_REG8(0x4d05), 0xc1}, /* TPM_CTRL_05 tpm_offset[7:0] = 0xc1 */ /* pre-ISP control */ - {0x5050, 0x0c}, /* DEBUG_MODE */ + {CCI_REG8(0x5050), 0x0c}, /* DEBUG_MODE */ /* OTP-DPC control */ - {0x5501, 0x10}, /* OTP_DPC_START_L otp_start_address[7:0] = 0x10 */ - {0x5503, 0x0f}, /* OTP_DPC_END_L otp_end_address[7:0] = 0x0f */ - {REG_NULL, 0x00}, + {CCI_REG8(0x5501), 0x10}, /* OTP_DPC_START_L otp_start_address[7:0] = 0x10 */ + {CCI_REG8(0x5503), 0x0f}, /* OTP_DPC_END_L otp_end_address[7:0] = 0x0f */ }; static const struct ov4689_mode supported_modes[] = { @@ -258,6 +244,7 @@ static const struct ov4689_mode supported_modes[] = { .vts_def = 1554, .pixel_rate = 480000000, .reg_list = ov4689_2688x1520_regs, + .num_regs = ARRAY_SIZE(ov4689_2688x1520_regs), }, }; @@ -310,83 +297,6 @@ static const struct ov4689_gain_range ov4689_gain_ranges[] = { }, }; -/* Write registers up to 4 at a time */ -static int ov4689_write_reg(struct i2c_client *client, u16 reg, u32 len, - u32 val) -{ - u32 buf_i, val_i; - __be32 val_be; - u8 *val_p; - u8 buf[6]; - - if (len > 4) - return -EINVAL; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - - val_be = cpu_to_be32(val); - val_p = (u8 *)&val_be; - buf_i = 2; - val_i = 4 - len; - - while (val_i < 4) - buf[buf_i++] = val_p[val_i++]; - - if (i2c_master_send(client, buf, len + 2) != len + 2) - return -EIO; - - return 0; -} - -static int ov4689_write_array(struct i2c_client *client, - const struct regval *regs) -{ - int ret = 0; - u32 i; - - for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) - ret = ov4689_write_reg(client, regs[i].addr, - OV4689_REG_VALUE_08BIT, regs[i].val); - - return ret; -} - -/* Read registers up to 4 at a time */ -static int ov4689_read_reg(struct i2c_client *client, u16 reg, unsigned int len, - u32 *val) -{ - __be16 reg_addr_be = cpu_to_be16(reg); - struct i2c_msg msgs[2]; - __be32 data_be = 0; - u8 *data_be_p; - int ret; - - if (len > 4 || !len) - return -EINVAL; - - data_be_p = (u8 *)&data_be; - /* Write register address */ - msgs[0].addr = client->addr; - msgs[0].flags = 0; - msgs[0].len = 2; - msgs[0].buf = (u8 *)®_addr_be; - - /* Read data from register */ - msgs[1].addr = client->addr; - msgs[1].flags = I2C_M_RD; - msgs[1].len = len; - msgs[1].buf = &data_be_p[4 - len]; - - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret != ARRAY_SIZE(msgs)) - return -EIO; - - *val = be32_to_cpu(data_be); - - return 0; -} - static void ov4689_fill_fmt(const struct ov4689_mode *mode, struct v4l2_mbus_framefmt *fmt) { @@ -460,8 +370,8 @@ static int ov4689_enable_test_pattern(struct ov4689 *ov4689, u32 pattern) else val = OV4689_TEST_PATTERN_DISABLE; - return ov4689_write_reg(ov4689->client, OV4689_REG_TEST_PATTERN, - OV4689_REG_VALUE_08BIT, val); + return cci_write(ov4689->regmap, OV4689_REG_TEST_PATTERN, + val, NULL); } static int ov4689_get_selection(struct v4l2_subdev *sd, @@ -505,8 +415,10 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) if (ret < 0) goto unlock_and_return; - ret = ov4689_write_array(ov4689->client, - ov4689->cur_mode->reg_list); + ret = cci_multi_reg_write(ov4689->regmap, + ov4689->cur_mode->reg_list, + ov4689->cur_mode->num_regs, + NULL); if (ret) { pm_runtime_put(&client->dev); goto unlock_and_return; @@ -518,17 +430,15 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) goto unlock_and_return; } - ret = ov4689_write_reg(ov4689->client, OV4689_REG_CTRL_MODE, - OV4689_REG_VALUE_08BIT, - OV4689_MODE_STREAMING); + ret = cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, + OV4689_MODE_STREAMING, NULL); if (ret) { pm_runtime_put(&client->dev); goto unlock_and_return; } } else { - ov4689_write_reg(ov4689->client, OV4689_REG_CTRL_MODE, - OV4689_REG_VALUE_08BIT, - OV4689_MODE_SW_STANDBY); + cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, + OV4689_MODE_SW_STANDBY, NULL); pm_runtime_put(&client->dev); } @@ -693,26 +603,16 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_EXPOSURE: /* 4 least significant bits of exposure are fractional part */ - ret = ov4689_write_reg(ov4689->client, OV4689_REG_EXPOSURE, - OV4689_REG_VALUE_24BIT, ctrl->val << 4); + ret = cci_write(ov4689->regmap, OV4689_REG_EXPOSURE, + ctrl->val << 4, NULL); break; case V4L2_CID_ANALOGUE_GAIN: ret = ov4689_map_gain(ov4689, ctrl->val, &sensor_gain); - - ret = ret ?: - ov4689_write_reg(ov4689->client, OV4689_REG_GAIN_H, - OV4689_REG_VALUE_08BIT, - (sensor_gain >> OV4689_GAIN_H_SHIFT) & - OV4689_GAIN_H_MASK); - ret = ret ?: - ov4689_write_reg(ov4689->client, OV4689_REG_GAIN_L, - OV4689_REG_VALUE_08BIT, - sensor_gain & OV4689_GAIN_L_MASK); + cci_write(ov4689->regmap, OV4689_REG_GAIN, sensor_gain, &ret); break; case V4L2_CID_VBLANK: - ret = ov4689_write_reg(ov4689->client, OV4689_REG_VTS, - OV4689_REG_VALUE_16BIT, - ctrl->val + ov4689->cur_mode->height); + ret = cci_write(ov4689->regmap, OV4689_REG_VTS, + ctrl->val + ov4689->cur_mode->height, NULL); break; case V4L2_CID_TEST_PATTERN: ret = ov4689_enable_test_pattern(ov4689, ctrl->val); @@ -817,18 +717,17 @@ static int ov4689_check_sensor_id(struct ov4689 *ov4689, struct i2c_client *client) { struct device *dev = &ov4689->client->dev; - u32 id = 0; + u64 id = 0; int ret; - ret = ov4689_read_reg(client, OV4689_REG_CHIP_ID, - OV4689_REG_VALUE_16BIT, &id); + ret = cci_read(ov4689->regmap, OV4689_REG_CHIP_ID, &id, NULL); if (ret) { dev_err(dev, "Cannot read sensor ID\n"); return ret; } if (id != CHIP_ID) { - dev_err(dev, "Unexpected sensor ID %06x, expected %06x\n", + dev_err(dev, "Unexpected sensor ID %06llx, expected %06x\n", id, CHIP_ID); return -ENODEV; } @@ -938,6 +837,13 @@ static int ov4689_probe(struct i2c_client *client) return -EINVAL; } + ov4689->regmap = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(ov4689->regmap)) { + ret = PTR_ERR(ov4689->regmap); + dev_err(dev, "failed to initialize CCI: %d\n", ret); + return ret; + } + ov4689->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ov4689->reset_gpio)) { From patchwork Mon Dec 18 17:40:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497331 Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 738E272077; Mon, 18 Dec 2023 17:41:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OgELI1Vk" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-50e3cdcf010so1205263e87.2; Mon, 18 Dec 2023 09:41:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921263; x=1703526063; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GECqqIbmwZQzSgkD0rH9gtwmMolx6aq5Ff6gT7Rc18w=; b=OgELI1Vk+W2KzNTapnFPdr9D1qPmDJ8YzbDGUXxuBHxtsb6SHVFA7KMb/IzD0c26f0 HV0E9ZyF9+iKFKFkbmAJPDs991h09PST2Sc2v6aBNiIrAkfhITDENq1OqqH/k0FOfiUj 5dGTWLqY6FwnD7zksSedN9p8ggbJdmdjCJYTwBCD8n0OJt+exWDOgBN4a1pC45Ci45AI cFl0a5SDQppnm7o/vtb7TDB79rtVjEx9jCssLfQ2ijW9R63FpnJqY43CJqIOUmJrbK/c sDWpcrzT6BxQxCrYq1yEK99YsJx/KwxJRvjUZ0ZMLY/NrCw+88OPr+lB9g223bLUnbkN kXww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921263; x=1703526063; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GECqqIbmwZQzSgkD0rH9gtwmMolx6aq5Ff6gT7Rc18w=; b=nIAhzJaJk2rpnqyzpoYt7mE1kUGp4ecMmlRSIpv/N4XfjIasGDrkOyQIC0pk7liQws ZdG1Wz7rtRMPP088Ju462kORd9EFxrAVGEIjeJvz+BYPetdkIL23BcrdImwApA4PWbFH XWtHAatywOW4PShloEShOyNE+7073zDRppMLIaOSglR/EWjM/FOXnPd4pZx3l3lexbFs 2HUdHgI/V6aD9HCuR2l4W2xF6/Xd5+KlP6GBicdTKb8Bya/w4cGeCw0GGCod2J5QVjgL us2SzfCX7Mz6m+1NdT2f1xvvasXPLtRcEu3sp6SEF29+y6hp0OYI0JCvrFvNLjrJmnp9 BecA== X-Gm-Message-State: AOJu0YxZcKsu3NR86QHP+06/1uizYD1+m4YLWCpSCJ/5uANQLujP4Gda m6+4tykIa2l5Qy0+cQKxwmSjEMAznNSFWQ== X-Google-Smtp-Source: AGHT+IH+6Q93ikV/7PYO3Q+G/bwQHdgApa4/3jJQQUsD51UtW4bsyp0kRfsY8nvSS9xmtw39ltLtdA== X-Received: by 2002:a2e:a588:0:b0:2cb:3169:b348 with SMTP id m8-20020a2ea588000000b002cb3169b348mr4599390ljp.96.1702921263307; Mon, 18 Dec 2023 09:41:03 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id k9-20020a05651c10a900b002cc74569398sm363278ljn.15.2023.12.18.09.41.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:02 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 05/20] media: i2c: ov4689: Remove i2c_client from ov4689 struct Date: Mon, 18 Dec 2023 20:40:26 +0300 Message-ID: <20231218174042.794012-6-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The 'client' field within the 'ov4689' structure is solely used to access its 'dev' member. This commit removes the 'client' field and directly stores a pointer to the 'struct device'. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 6ea1c37323d1..3b20eba59c9c 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -74,7 +74,7 @@ struct ov4689_mode { }; struct ov4689 { - struct i2c_client *client; + struct device *dev; struct regmap *regmap; struct clk *xvclk; struct gpio_desc *reset_gpio; @@ -405,13 +405,13 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, static int ov4689_s_stream(struct v4l2_subdev *sd, int on) { struct ov4689 *ov4689 = to_ov4689(sd); - struct i2c_client *client = ov4689->client; + struct device *dev = ov4689->dev; int ret = 0; mutex_lock(&ov4689->mutex); if (on) { - ret = pm_runtime_resume_and_get(&client->dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) goto unlock_and_return; @@ -420,26 +420,26 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) ov4689->cur_mode->num_regs, NULL); if (ret) { - pm_runtime_put(&client->dev); + pm_runtime_put(dev); goto unlock_and_return; } ret = __v4l2_ctrl_handler_setup(&ov4689->ctrl_handler); if (ret) { - pm_runtime_put(&client->dev); + pm_runtime_put(dev); goto unlock_and_return; } ret = cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, OV4689_MODE_STREAMING, NULL); if (ret) { - pm_runtime_put(&client->dev); + pm_runtime_put(dev); goto unlock_and_return; } } else { cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, OV4689_MODE_SW_STANDBY, NULL); - pm_runtime_put(&client->dev); + pm_runtime_put(dev); } unlock_and_return: @@ -553,7 +553,6 @@ static const struct v4l2_subdev_ops ov4689_subdev_ops = { */ static int ov4689_map_gain(struct ov4689 *ov4689, int logical_gain, int *result) { - const struct device *dev = &ov4689->client->dev; const struct ov4689_gain_range *range; unsigned int n; @@ -564,7 +563,8 @@ static int ov4689_map_gain(struct ov4689 *ov4689, int logical_gain, int *result) } if (n == ARRAY_SIZE(ov4689_gain_ranges)) { - dev_warn_ratelimited(dev, "no mapping found for gain %d\n", + dev_warn_ratelimited(ov4689->dev, + "no mapping found for gain %d\n", logical_gain); return -EINVAL; } @@ -580,7 +580,7 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) { struct ov4689 *ov4689 = container_of(ctrl->handler, struct ov4689, ctrl_handler); - struct i2c_client *client = ov4689->client; + struct device *dev = ov4689->dev; int sensor_gain; s64 max_expo; int ret; @@ -597,7 +597,7 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) break; } - if (!pm_runtime_get_if_in_use(&client->dev)) + if (!pm_runtime_get_if_in_use(dev)) return 0; switch (ctrl->id) { @@ -618,13 +618,13 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) ret = ov4689_enable_test_pattern(ov4689, ctrl->val); break; default: - dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", + dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n", __func__, ctrl->id, ctrl->val); ret = -EINVAL; break; } - pm_runtime_put(&client->dev); + pm_runtime_put(dev); return ret; } @@ -689,8 +689,7 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) if (handler->error) { ret = handler->error; - dev_err(&ov4689->client->dev, "Failed to init controls(%d)\n", - ret); + dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret); goto err_free_handler; } @@ -716,7 +715,7 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) static int ov4689_check_sensor_id(struct ov4689 *ov4689, struct i2c_client *client) { - struct device *dev = &ov4689->client->dev; + struct device *dev = ov4689->dev; u64 id = 0; int ret; @@ -744,7 +743,7 @@ static int ov4689_configure_regulators(struct ov4689 *ov4689) for (i = 0; i < ARRAY_SIZE(ov4689_supply_names); i++) ov4689->supplies[i].supply = ov4689_supply_names[i]; - return devm_regulator_bulk_get(&ov4689->client->dev, + return devm_regulator_bulk_get(ov4689->dev, ARRAY_SIZE(ov4689_supply_names), ov4689->supplies); } @@ -813,7 +812,8 @@ static int ov4689_probe(struct i2c_client *client) if (!ov4689) return -ENOMEM; - ov4689->client = client; + ov4689->dev = dev; + ov4689->cur_mode = &supported_modes[OV4689_MODE_2688_1520]; ov4689->xvclk = devm_clk_get_optional(dev, NULL); From patchwork Mon Dec 18 17:40:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497330 Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6ACB73462; Mon, 18 Dec 2023 17:41:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eNeuCI9/" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-50bf2d9b3fdso4627494e87.3; Mon, 18 Dec 2023 09:41:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921265; x=1703526065; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zRAVS4vC9ni6nFv/TOVO0tDXxMYBMHf0gL/d3MqoeLg=; b=eNeuCI9/n8IPTWNx30Fk1ROiHUtsmOZcgYTGHFJaoRZeqYcl9rCewx58shHDR1REXr yO2PHSUgJMVEkLVD5yeFNdZgyUlTPCUp5/V30l8q9zTcdIC/355B+50lDCScOsTNLCPz oWWvRLkUklIJe9BfjU3Y24Ulhp+xwlss7+uofV/rSGtw3rMXqXqOEmMbzKjBWXbc3Ktg ZInWIk0iumOtGAtN5zKXNwNDDZ5ZN55cnhhtdpEgDRLoTCbZL4gtSJdRLFLFrrGOqXmW 0aa3EGUW8VUyXoOXmy3wnCDShI1zn4sbIwVzjHJYeoZGK9P3OB06f8dFRoNLbL/ZT7N0 f0LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921265; x=1703526065; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zRAVS4vC9ni6nFv/TOVO0tDXxMYBMHf0gL/d3MqoeLg=; b=iYt7o04uzR1mKjf9VeuLd8yDcHfwdlukYQ03SjK4V4GUZFx+Yviln3+gbFkaeMDzVr m6J7f8+3NgY+GLb9N48IQa56GitkaY6JNotUzkO+nzGD1Rguk3Ymh9n3+EonL9dnDyfR AOpS8+qXLnyqO5oxO1NoVpJWvHUt4b9EJ/q/PUixFDLGQRWzadcH7BzhoFm3NHLFy/EW 0hNQyAgukry9m8y4jjG9fsu2ypaZfkIU26asApRtRQGEuZQ9Ay/aEqFb3Og+h2cxeBgC gSLEtyBcLhuvEfnsarhMLC187wTArb8AvZUwVSLBbdT1SOOXl+9VXZmllXkpJ//GyWG9 pDlQ== X-Gm-Message-State: AOJu0YwYuuFCw0ifx3GmIBZpEZrrd7Zn/5T8iwUR1qjkBN7xlbApsFgQ yq+s1oL1M+2TvH8Q/pM7Jou4+f1LHC9xMw== X-Google-Smtp-Source: AGHT+IFuVh3NnbRkHJJQpPto8uz+sG7n1PpAvbfvBBjPePQSJZd4LNqyRfmPpOoi4pv+MbeYIiK9ZA== X-Received: by 2002:a19:6d0b:0:b0:50e:2e79:eb2 with SMTP id i11-20020a196d0b000000b0050e2e790eb2mr1602734lfc.14.1702921265055; Mon, 18 Dec 2023 09:41:05 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id bi6-20020a0565120e8600b0050bf44d0d23sm2947923lfb.20.2023.12.18.09.41.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:04 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 06/20] media: i2c: ov4689: Refactor ov4689_set_ctrl Date: Mon, 18 Dec 2023 20:40:27 +0300 Message-ID: <20231218174042.794012-7-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce local variable for regmap within the ov4689_set_ctrl function. This adjustment eliminates repetition within the function. Signed-off-by: Mikhail Rudenko --- drivers/media/i2c/ov4689.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 3b20eba59c9c..d42f5d1a1ba8 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -580,6 +580,7 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) { struct ov4689 *ov4689 = container_of(ctrl->handler, struct ov4689, ctrl_handler); + struct regmap *regmap = ov4689->regmap; struct device *dev = ov4689->dev; int sensor_gain; s64 max_expo; @@ -603,16 +604,15 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_EXPOSURE: /* 4 least significant bits of exposure are fractional part */ - ret = cci_write(ov4689->regmap, OV4689_REG_EXPOSURE, - ctrl->val << 4, NULL); + cci_write(regmap, OV4689_REG_EXPOSURE, ctrl->val << 4, &ret); break; case V4L2_CID_ANALOGUE_GAIN: ret = ov4689_map_gain(ov4689, ctrl->val, &sensor_gain); - cci_write(ov4689->regmap, OV4689_REG_GAIN, sensor_gain, &ret); + cci_write(regmap, OV4689_REG_GAIN, sensor_gain, &ret); break; case V4L2_CID_VBLANK: - ret = cci_write(ov4689->regmap, OV4689_REG_VTS, - ctrl->val + ov4689->cur_mode->height, NULL); + cci_write(regmap, OV4689_REG_VTS, + ctrl->val + ov4689->cur_mode->height, &ret); break; case V4L2_CID_TEST_PATTERN: ret = ov4689_enable_test_pattern(ov4689, ctrl->val); @@ -625,7 +625,6 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) } pm_runtime_put(dev); - return ret; } From patchwork Mon Dec 18 17:40:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497332 Received: from mail-lf1-f46.google.com (mail-lf1-f46.google.com [209.85.167.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B6F2971477; Mon, 18 Dec 2023 17:41:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PqvXmH1u" Received: by mail-lf1-f46.google.com with SMTP id 2adb3069b0e04-50bf3efe2cbso3901608e87.2; Mon, 18 Dec 2023 09:41:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921266; x=1703526066; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=M0/5NCPPEP08dxHiHIezXLBrilHL+5rztH1UO29obAo=; b=PqvXmH1uUnkEz93haJsEFNRHyvGppMKE/C31snNWw6Mp2zk47O8wZP1wcH4bHbjkIX 0qA81yYknYGq5sQJ9HWHX/qI82mBOhPSnjVWnv5UTIajDY7Q/V0060zW2U96H8MiNbYW 3iOMbj75ja5rQr6QOtEU3gzGZ5uLGSL5kzgWIUOPuH1VuFAf0+9ukeegFq7laIxcUQss HNBLAHu4HL5ETFSkKgsgAKkPU9oT4qvlsSarJ+mIf4MmrHJ2y5qWHAh1lCCh18n3d2dB n2VTlI/cK8gXT/fqituofYxwGA+XBkAzof1zj5CgbXdFNrrVkBo7RNlclIQZryh63Obk 5W5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921266; x=1703526066; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=M0/5NCPPEP08dxHiHIezXLBrilHL+5rztH1UO29obAo=; b=o1pnAVNq/7bbzufwbMKt8P7MO03r85nJfqJLn7vqogwSvCF7rGYKkOf7ijt72KmJwV vpPl0EkYnKUf5J1fPcRZ4rQ6G7mGZNdhKX1RhPTNhc/EOBHjFXnRg9mwDPu+mUPiECfF I2Phe6mBthvxckYOhMzIyCOpetfqE+8sytZJ3PHgZBCm+kMAVZOT5WY55SZ4wffDk8yi EA07YoRCqdt6/6wdomtOUnYJcGh/WF98R7FvE9ujJ8uYLULT+zmx1l4Lpw8Q5NioTXlh OoL0VZbIjOxQEj3Vddm+wBvjRMc0dbE6B1B58nrtOHtIvf2mohWAO+8vAlG4ROD/8K6L aYlw== X-Gm-Message-State: AOJu0Yw+8cETf0IrCn5BYJsllb8t6e8JVKUIIPCWvYyDxKCiO8IN0VlO bFDtdjneZQuRi+DXWTwiuDR3OGQcbYpFdw== X-Google-Smtp-Source: AGHT+IF9ey4UQ6SUMpAGvUqYRTmdaHtMtctv+O6YHO1u0m2u4Rue0WRtBrlpVqU33PMFNKB4V2vFxg== X-Received: by 2002:a05:6512:1586:b0:50e:719:6feb with SMTP id bp6-20020a056512158600b0050e07196febmr4040180lfb.213.1702921266432; Mon, 18 Dec 2023 09:41:06 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id f8-20020a193808000000b0050d12fe487bsm1077566lfa.277.2023.12.18.09.41.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:06 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 07/20] media: i2c: ov4689: Use sub-device active state Date: Mon, 18 Dec 2023 20:40:28 +0300 Message-ID: <20231218174042.794012-8-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use sub-device active state. Employ control handler lock to synchronize access to the active state and s_stream. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 75 ++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index d42f5d1a1ba8..501901aad4ae 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -86,7 +86,6 @@ struct ov4689 { u32 clock_rate; - struct mutex mutex; /* lock to protect ctrls and cur_mode */ struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl *exposure; @@ -319,19 +318,6 @@ static int ov4689_set_fmt(struct v4l2_subdev *sd, return 0; } -static int ov4689_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) -{ - struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; - struct ov4689 *ov4689 = to_ov4689(sd); - - /* only one mode supported for now */ - ov4689_fill_fmt(ov4689->cur_mode, mbus_fmt); - - return 0; -} - static int ov4689_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) @@ -405,10 +391,11 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, static int ov4689_s_stream(struct v4l2_subdev *sd, int on) { struct ov4689 *ov4689 = to_ov4689(sd); + struct v4l2_subdev_state *sd_state; struct device *dev = ov4689->dev; int ret = 0; - mutex_lock(&ov4689->mutex); + sd_state = v4l2_subdev_lock_and_get_active_state(&ov4689->subdev); if (on) { ret = pm_runtime_resume_and_get(dev); @@ -443,7 +430,7 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) } unlock_and_return: - mutex_unlock(&ov4689->mutex); + v4l2_subdev_unlock_state(sd_state); return ret; } @@ -506,18 +493,13 @@ static int __maybe_unused ov4689_power_off(struct device *dev) return 0; } -static int ov4689_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +static int ov4689_init_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) { - struct ov4689 *ov4689 = to_ov4689(sd); - struct v4l2_mbus_framefmt *try_fmt; - - mutex_lock(&ov4689->mutex); - - try_fmt = v4l2_subdev_state_get_format(fh->state, 0); - /* Initialize try_fmt */ - ov4689_fill_fmt(&supported_modes[OV4689_MODE_2688_1520], try_fmt); + struct v4l2_mbus_framefmt *fmt = + v4l2_subdev_state_get_format(sd_state, 0); - mutex_unlock(&ov4689->mutex); + ov4689_fill_fmt(&supported_modes[OV4689_MODE_2688_1520], fmt); return 0; } @@ -526,10 +508,6 @@ static const struct dev_pm_ops ov4689_pm_ops = { SET_RUNTIME_PM_OPS(ov4689_power_off, ov4689_power_on, NULL) }; -static const struct v4l2_subdev_internal_ops ov4689_internal_ops = { - .open = ov4689_open, -}; - static const struct v4l2_subdev_video_ops ov4689_video_ops = { .s_stream = ov4689_s_stream, }; @@ -537,11 +515,15 @@ static const struct v4l2_subdev_video_ops ov4689_video_ops = { static const struct v4l2_subdev_pad_ops ov4689_pad_ops = { .enum_mbus_code = ov4689_enum_mbus_code, .enum_frame_size = ov4689_enum_frame_sizes, - .get_fmt = ov4689_get_fmt, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = ov4689_set_fmt, .get_selection = ov4689_get_selection, }; +static const struct v4l2_subdev_internal_ops ov4689_internal_ops = { + .init_state = ov4689_init_state, +}; + static const struct v4l2_subdev_ops ov4689_subdev_ops = { .video = &ov4689_video_ops, .pad = &ov4689_pad_ops, @@ -648,7 +630,6 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) ret = v4l2_ctrl_handler_init(handler, 10); if (ret) return ret; - handler->lock = &ov4689->mutex; ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, 0, 0, link_freq_menu_items); @@ -861,13 +842,15 @@ static int ov4689_probe(struct i2c_client *client) return dev_err_probe(dev, ret, "Failed to get power regulators\n"); - mutex_init(&ov4689->mutex); - sd = &ov4689->subdev; v4l2_i2c_subdev_init(sd, client, &ov4689_subdev_ops); + sd->internal_ops = &ov4689_internal_ops; + ret = ov4689_initialize_controls(ov4689); - if (ret) - goto err_destroy_mutex; + if (ret) { + dev_err(dev, "Failed to initialize controls\n"); + return ret; + } ret = ov4689_power_on(dev); if (ret) @@ -877,19 +860,26 @@ static int ov4689_probe(struct i2c_client *client) if (ret) goto err_power_off; - sd->internal_ops = &ov4689_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ov4689->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &ov4689->pad); if (ret < 0) goto err_power_off; + sd->state_lock = ov4689->ctrl_handler.lock; + ret = v4l2_subdev_init_finalize(sd); + + if (ret) { + dev_err(dev, "Could not register v4l2 device\n"); + goto err_clean_entity; + } + ret = v4l2_async_register_subdev_sensor(sd); if (ret) { dev_err(dev, "v4l2 async register subdev failed\n"); - goto err_clean_entity; + goto err_clean_subdev; } pm_runtime_set_active(dev); @@ -898,14 +888,14 @@ static int ov4689_probe(struct i2c_client *client) return 0; +err_clean_subdev: + v4l2_subdev_cleanup(sd); err_clean_entity: media_entity_cleanup(&sd->entity); err_power_off: ov4689_power_off(dev); err_free_handler: v4l2_ctrl_handler_free(&ov4689->ctrl_handler); -err_destroy_mutex: - mutex_destroy(&ov4689->mutex); return ret; } @@ -917,9 +907,8 @@ static void ov4689_remove(struct i2c_client *client) v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); - + v4l2_subdev_cleanup(sd); v4l2_ctrl_handler_free(&ov4689->ctrl_handler); - mutex_destroy(&ov4689->mutex); pm_runtime_disable(&client->dev); if (!pm_runtime_status_suspended(&client->dev)) From patchwork Mon Dec 18 17:40:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497333 Received: from mail-lj1-f170.google.com (mail-lj1-f170.google.com [209.85.208.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2F38F7144B; Mon, 18 Dec 2023 17:41:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Xff4szit" Received: by mail-lj1-f170.google.com with SMTP id 38308e7fff4ca-2cc690a3712so21501661fa.3; Mon, 18 Dec 2023 09:41:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921268; x=1703526068; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/lcZDt5QGRhe9n/LLDxuh6IIVZbIKKGFKFqVIvYPe3o=; b=Xff4szitaYWeBor/vHoMfDqoUga6kFfxCFtVavBW2qNnhTwNPQkuakCopuNh4/o0Mx aJ8RuJ9i+9+bZ3j4YxsMbh7jq1WaaJVIy6y+rhLZ+mVs6wUxybIj8z83ismvI84ZsQ4y an0Ss8XfXziyKGKKoG7H/s7A3A4JGDLSRhQwp0s42KWwbrHwj/ckZJVo0SVIkjVm3SbK yimKP/cDeTeMiFGHG4TdGP0hJNbfOAiumEb8xNMoxigzd9tSdnimnaU6Msq5yaBIv6ba wlfwTmgVbQXhuq9yh1Bx/s3CkwdFiznydtwUKbWmv+o11eCnxyizxPTzJkhJ6nYENgmQ WTqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921268; x=1703526068; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/lcZDt5QGRhe9n/LLDxuh6IIVZbIKKGFKFqVIvYPe3o=; b=nS39qulgPNrkmM7DU+NVwroJm82ef0QG8/sArfoqz9pHRqh+AsfgylGgSFdZm8y/z1 5965BhKtQiXgXsbngcGzxxdvyVqWRzaReoq/OPoBPsqVWfm1q3EadbCsSSKbI61Y4Jib Oal/yBteQ6px1ps3tDTMkeQlau1qibYQRWd3Own9G+OR0wgGxqNB9dI2CCDq+UrZW2fD XV1C1E/LdFllJ2kkG42b7ZqSY6WMJOwHzmI6WUUXZyN7XujtshocW5hK+VR66uOBOsgF pKClOeKaQ+5SnkZPxwL/50G5LYaVycbnnKBOox27c9jbbhZiT6y8uB3//YUggvQSShOG 44Mg== X-Gm-Message-State: AOJu0YzfFOQdaREyzEBvomdS9sVVQTNPTmMW+tkcvXSoLvj8dKTgJkYs 7dxXn618oiI4Gups4xRUSgCpZJK4L7PFkQ== X-Google-Smtp-Source: AGHT+IFJ7DMdENSn1mXdrbi/Y7ERcM2t2FtjbfFdZg9Evs/GZ/Fr4tWkWnnVSiXj7M98mEb+GPNomQ== X-Received: by 2002:a2e:9857:0:b0:2cc:7c8c:5748 with SMTP id e23-20020a2e9857000000b002cc7c8c5748mr18239ljj.63.1702921267816; Mon, 18 Dec 2023 09:41:07 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id z5-20020a2ebcc5000000b002cc259a574esm2497812ljp.117.2023.12.18.09.41.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:07 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 08/20] media: i2c: ov4689: Enable runtime PM before registering sub-device Date: Mon, 18 Dec 2023 20:40:29 +0300 Message-ID: <20231218174042.794012-9-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 As the sensor may be accessible right after its async sub-device is registered, enable runtime PM before doing so. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 501901aad4ae..5300e621ff90 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -876,19 +876,21 @@ static int ov4689_probe(struct i2c_client *client) goto err_clean_entity; } + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_idle(dev); + ret = v4l2_async_register_subdev_sensor(sd); if (ret) { dev_err(dev, "v4l2 async register subdev failed\n"); - goto err_clean_subdev; + goto err_clean_subdev_pm; } - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - pm_runtime_idle(dev); - return 0; -err_clean_subdev: +err_clean_subdev_pm: + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); v4l2_subdev_cleanup(sd); err_clean_entity: media_entity_cleanup(&sd->entity); From patchwork Mon Dec 18 17:40:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497336 Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B9F497408A; Mon, 18 Dec 2023 17:41:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hsmO4MPg" Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-2cc4029dc6eso41241111fa.1; Mon, 18 Dec 2023 09:41:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921269; x=1703526069; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Q+AOlN1QWf7zHgr+1BqJOwJHJOoAiKQ8ZouD3wx/nb4=; b=hsmO4MPgEEvT84rvsWcOuG8HLxtbSnqmbwbKWYoBaFgp9Wgx3EgdAls70FT5zxg54+ v+iNXcIRZtHNYcqtDL75wAu5xpwNm6umzKHFbesJQHVRyNehu2Te+DQOuDBEfMxcTQ2C ojqDmfgaezA0sbuiDy7qa5iRJ0ouW6wMoQUR85srW7F9xOUF1nJQnhlSQ4LQIBwgaUJ3 cwbMTiz1CwREdfCfjfF/7VasvwMb+WedEHkhAK3Dxy8BVEQQBBE8Iq3w1VjyTCQQokL/ bZSAczwKtbkMLMKqNLrYsSWrh7WfwQUxWUtUsvJn7s5+3+AOk5wD0GP7jqIOvgN8cJB7 Ia6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921269; x=1703526069; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Q+AOlN1QWf7zHgr+1BqJOwJHJOoAiKQ8ZouD3wx/nb4=; b=i5/vlKX7aJP3PwG4zhEF0fu8LUi62SIkD1P7mE17tJqOrJTU2AULEH0yotYWwBbkIX lSr0VSoPGZBR7rvXC5As9Rgexw5syq8meyJbKOIL0iXALaPL+B89iVXfKx5/VxQmd4+5 98RfjUZthCvhKwtW/fk7+9C6JxLexqsK4xJbVhvIvD9Di7mxwREjX1ocpWThfyhqtLqp RcE1SmAU5FhHAEqNwtEjGHwl2enJV/GZ7TO3UEzWkDPjXC1PHwYOZf97W3iGYK7fchlv JGaHTFkUaec2FX427nJaP5aOsUXSY1jJ8Rc8bAwUQIs5pC4WSt6vzOQ53CK6cF/0oKV0 YlGA== X-Gm-Message-State: AOJu0YzHkB3R7Kzd85CFCm6d2vAS22unW/a5EBo85h1KoKmr8hOv5h3S QS8MHJiuq1wqcgnBk8LptXvE5MQlzXcBGw== X-Google-Smtp-Source: AGHT+IHwpj/ptq03du2UQFOKrRI41kSsBCF0FBxBKU/3tNcFaqP9tLQwjSDhNd/ueoYRbFegnVyQTA== X-Received: by 2002:a2e:bc08:0:b0:2cc:41c9:9c71 with SMTP id b8-20020a2ebc08000000b002cc41c99c71mr5214230ljf.25.1702921269208; Mon, 18 Dec 2023 09:41:09 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id w22-20020a2e9bd6000000b002cc710614besm455091ljj.0.2023.12.18.09.41.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:08 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 09/20] media: i2c: ov4689: Use runtime PM autosuspend Date: Mon, 18 Dec 2023 20:40:30 +0300 Message-ID: <20231218174042.794012-10-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Use runtime PM autosuspend to avoid powering off the sensor during fast stop-reconfigure-restart cycles. Signed-off-by: Mikhail Rudenko --- drivers/media/i2c/ov4689.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 5300e621ff90..64cc6d9e48cc 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -407,26 +407,27 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) ov4689->cur_mode->num_regs, NULL); if (ret) { - pm_runtime_put(dev); + pm_runtime_put_sync(dev); goto unlock_and_return; } ret = __v4l2_ctrl_handler_setup(&ov4689->ctrl_handler); if (ret) { - pm_runtime_put(dev); + pm_runtime_put_sync(dev); goto unlock_and_return; } ret = cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, OV4689_MODE_STREAMING, NULL); if (ret) { - pm_runtime_put(dev); + pm_runtime_put_sync(dev); goto unlock_and_return; } } else { cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, OV4689_MODE_SW_STANDBY, NULL); - pm_runtime_put(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } unlock_and_return: @@ -606,7 +607,9 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) break; } - pm_runtime_put(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; } @@ -877,8 +880,10 @@ static int ov4689_probe(struct i2c_client *client) } pm_runtime_set_active(dev); + pm_runtime_get_noresume(dev); pm_runtime_enable(dev); - pm_runtime_idle(dev); + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); ret = v4l2_async_register_subdev_sensor(sd); if (ret) { @@ -886,11 +891,14 @@ static int ov4689_probe(struct i2c_client *client) goto err_clean_subdev_pm; } + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; err_clean_subdev_pm: pm_runtime_disable(dev); - pm_runtime_set_suspended(dev); + pm_runtime_put_noidle(dev); v4l2_subdev_cleanup(sd); err_clean_entity: media_entity_cleanup(&sd->entity); From patchwork Mon Dec 18 17:40:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497334 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 20987740B2; Mon, 18 Dec 2023 17:41:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XdadFdtp" Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-50e1112b95cso3689125e87.0; Mon, 18 Dec 2023 09:41:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921270; x=1703526070; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=78C4018Wj6QQ6G/TMfHrY+9uEZBmbcTZYvwwuREmiaI=; b=XdadFdtp/8+DeNh9A5xmVYAA3wh/UFHiyaXZTK+jVPAcXB1B+hpytXV/Q8lXTzoz9t D/eOD+Tx4pCW5vpUE+PxEFewrLuhIUnYGYYNlVAPALgHm+q+mD+QwnctpfcpREcTRAwE W36w0ESPMEk00qGn87u07KyHZFyAWa581BKd9c8LOlfWZbGiqReaAH3y5KwYfuQ/Qn6U kc9Mx/vch3tAMSCq0mo/5tjEEiamA4id8BGeue2ywvUhAQtAxguqWxswm9GaV70DAp31 2lRrk8M53qmvoRPMTkN1iE4fRDUDqLvmKuGe+LHVGtikw0gUouDWJNWELtWnxWxnPK+h xN3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921270; x=1703526070; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=78C4018Wj6QQ6G/TMfHrY+9uEZBmbcTZYvwwuREmiaI=; b=QxbC9w7o7zg99GzTi3ftpZb/AnQDEpA2dFaNzF2acGl9Ruq53hTOuZTskGUDqsva5x cJjfI0cEHhTVhNUOry1QJBrmhg8rb7OFIQOJv+PBUJjE2q4ovbtB0l9pG6R1Y8fNr5BG pVk6k2ZhW5SmK7ZbS9hW9ub/dCJEcAMKXhkxOdvBtVhh2mBr1IxhsGxyD+dDYbY7fihk NMqviJ6SqTDVQBegTYUlWnskPUYwUasLSgDu9YKAM+Oi//g/S3a+Az8rAmLaFZW5Y78p VCv0/wn34brVP9J9Pz+ytcWpx2PMqUY47YChOSo9+TB85C5PQm5G03Zoz4DsmAWmWgFk buYg== X-Gm-Message-State: AOJu0YzvJ6T5eJGLy2L1Nh/s+GvW38FaDyP4GSXfgp4qs/kgina+6kqf mdOxoNPRfOlFSju3vbbVOnTani9GGqMHcg== X-Google-Smtp-Source: AGHT+IHoW+UvwA10FafX4ZKJJjhDgqd1FlaW5EV33a76GpIWRud9d485W+bLdB7KmpgrDAKBtd49oQ== X-Received: by 2002:ac2:4e11:0:b0:50b:eadf:f175 with SMTP id e17-20020ac24e11000000b0050beadff175mr5774966lfr.91.1702921270413; Mon, 18 Dec 2023 09:41:10 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id g42-20020a0565123baa00b0050bfe7a602csm2978189lfv.74.2023.12.18.09.41.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:10 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 10/20] media: i2c: ov4689: Remove max_fps field from struct ov4689_mode Date: Mon, 18 Dec 2023 20:40:31 +0300 Message-ID: <20231218174042.794012-11-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 max_fps field of struct ov4689_mode is unused in this driver, so remove it. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 64cc6d9e48cc..cf1303744e7c 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -60,7 +60,6 @@ struct ov4689_mode { enum ov4689_mode_id id; u32 width; u32 height; - u32 max_fps; u32 hts_def; u32 vts_def; u32 exp_def; @@ -237,7 +236,6 @@ static const struct ov4689_mode supported_modes[] = { .sensor_height = 1536, .crop_top = 8, .crop_left = 16, - .max_fps = 30, .exp_def = 1536, .hts_def = 4 * 2574, .vts_def = 1554, From patchwork Mon Dec 18 17:40:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497337 Received: from mail-lf1-f52.google.com (mail-lf1-f52.google.com [209.85.167.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1DDF974E11; Mon, 18 Dec 2023 17:41:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bYK9cAKi" Received: by mail-lf1-f52.google.com with SMTP id 2adb3069b0e04-50e2786e71fso2878247e87.0; Mon, 18 Dec 2023 09:41:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921272; x=1703526072; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=igV7Ve8Ucn2LM2ubX7Qcip8JZf24Gs2gYDiFdHkxUQU=; b=bYK9cAKiLB0u5Z33wLjDshCONzQTSmjs5bRvbSw4RwBxp27hCEsQg3PYwMjdVo8vn2 0o1owbpZaPI9eTQwDnTGATecbKKWCiuykXBIBfFsxSkstJjLSmGQMnvDIkovChAOc8nx tv/mN2IXuxoLNvO9bkClM7jgJZO8umOMAaTt+8osL14tThYK55QjeRGqzMNJ3a5gsVXw +3FoXPWpbVWF/IZZwj7qNyAPoSToz3fZC65LQZLBFkKHI5eFf/3Tz5uvSjXm6GYgyc6v VKbDh1/Dq/3E/3UQE+Q4NjRtY6zmu6utFf2uP/Z/DFKW8WdIE9WaH6+2Aswo4NERFp7E EzmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921272; x=1703526072; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=igV7Ve8Ucn2LM2ubX7Qcip8JZf24Gs2gYDiFdHkxUQU=; b=Zw3jM2rCq3Y1GyJkBek5hlnHc/oQK5sX5wREp7XY2kQ1wfWJk23j5WJLDx/Uolt2Bd LkzYp8ZdJy1uE1UMd+R2sjyTv8Yt4wocSH0xZx0DNwxgSeGzjSDRqEqg7mDMfDl7iZ3D N+eGJFy8bq5ZWjFhXO7LYa0Aa9PPe88UuvNZ+OAsmKin+TeYfECjHf/ulkP+1XtGKt1U f4hrhYpm0eGGUwBfS44zVgIk1bZcqTEoH3uhhtuGGByVTjO5qYd8szJXSBIVFiZTyZaC putZAF5B2aqMC7z1sRKRcRcugVnyPaSXuaP8ihbSqg7ideuBAKKZWLRBDB8jcf12jmEY Zm0Q== X-Gm-Message-State: AOJu0Yw7lYAkTiPGJvoJtItToXJ6ZuWWGU3SFXB9nONJGTJdLyqswkFm jT7Ny/kIvtkL9KPxjyLiWRIJqPDQK2BXtA== X-Google-Smtp-Source: AGHT+IEdIPR+5KEcCNv7f8DKqR65FcwbOO//8A7m0jr26KxioscuwxQg3gDh8JSe61bbNnthGdRrvw== X-Received: by 2002:a05:6512:230d:b0:50e:3758:94d4 with SMTP id o13-20020a056512230d00b0050e375894d4mr1547865lfu.117.1702921271769; Mon, 18 Dec 2023 09:41:11 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id m18-20020a056512115200b0050bf6d3416asm2955631lfg.156.2023.12.18.09.41.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:11 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 11/20] media: i2c: ov4689: Make horizontal blanking configurable Date: Mon, 18 Dec 2023 20:40:32 +0300 Message-ID: <20231218174042.794012-12-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Make horizontal blanking configurable. To do so, set HTS register according to the requested horizontal blanking in ov4689_set_ctrl instead of the register table. Default HTS value is not changed by this patch. Minimal HTS value is found experimentally and corresponds to 90 fps framerate at minimum vertical blanking. Real HTS value is the register value multiplied by 4. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index cf1303744e7c..06ed9d22b2c8 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -30,13 +30,17 @@ #define OV4689_REG_EXPOSURE CCI_REG24(0x3500) #define OV4689_EXPOSURE_MIN 4 #define OV4689_EXPOSURE_STEP 1 -#define OV4689_VTS_MAX 0x7fff #define OV4689_REG_GAIN CCI_REG16(0x3508) #define OV4689_GAIN_STEP 1 #define OV4689_GAIN_DEFAULT 0x80 +#define OV4689_REG_HTS CCI_REG16(0x380c) +#define OV4689_HTS_DIVIDER 4 +#define OV4689_HTS_MAX 0x7fff + #define OV4689_REG_VTS CCI_REG16(0x380e) +#define OV4689_VTS_MAX 0x7fff #define OV4689_REG_TEST_PATTERN CCI_REG8(0x5040) #define OV4689_TEST_PATTERN_ENABLE 0x80 @@ -61,6 +65,7 @@ struct ov4689_mode { u32 width; u32 height; u32 hts_def; + u32 hts_min; u32 vts_def; u32 exp_def; u32 pixel_rate; @@ -104,7 +109,7 @@ struct ov4689_gain_range { /* * Xclk 24Mhz - * max_framerate 30fps + * max_framerate 90fps * mipi_datarate per lane 1008Mbps */ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { @@ -175,8 +180,6 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { /* Timing control */ {CCI_REG8(0x3801), 0x08}, /* H_CROP_START_L h_crop_start[7:0] = 0x08 */ {CCI_REG8(0x3805), 0x97}, /* H_CROP_END_L h_crop_end[7:0] = 0x97 */ - {CCI_REG8(0x380c), 0x0a}, /* TIMING_HTS_H hts[14:8] = 0x0a */ - {CCI_REG8(0x380d), 0x0e}, /* TIMING_HTS_L hts[7:0] = 0x0e */ {CCI_REG8(0x3811), 0x08}, /* H_WIN_OFF_L h_win_off[7:0] = 0x08*/ {CCI_REG8(0x3813), 0x04}, /* V_WIN_OFF_L v_win_off[7:0] = 0x04 */ {CCI_REG8(0x3819), 0x01}, /* VSYNC_END_L vsync_end_point[7:0] = 0x01 */ @@ -237,7 +240,8 @@ static const struct ov4689_mode supported_modes[] = { .crop_top = 8, .crop_left = 16, .exp_def = 1536, - .hts_def = 4 * 2574, + .hts_def = 10296, + .hts_min = 3432, .vts_def = 1554, .pixel_rate = 480000000, .reg_list = ov4689_2688x1520_regs, @@ -598,6 +602,11 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_TEST_PATTERN: ret = ov4689_enable_test_pattern(ov4689, ctrl->val); break; + case V4L2_CID_HBLANK: + cci_write(regmap, OV4689_REG_HTS, + (ctrl->val + ov4689->cur_mode->width) / + OV4689_HTS_DIVIDER, &ret); + break; default: dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n", __func__, ctrl->id, ctrl->val); @@ -622,8 +631,8 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) struct v4l2_ctrl_handler *handler; const struct ov4689_mode *mode; s64 exposure_max, vblank_def; + s64 hblank_def, hblank_min; struct v4l2_ctrl *ctrl; - s64 h_blank_def; int ret; handler = &ov4689->ctrl_handler; @@ -640,11 +649,11 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 0, mode->pixel_rate, 1, mode->pixel_rate); - h_blank_def = mode->hts_def - mode->width; - ctrl = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, h_blank_def, - h_blank_def, 1, h_blank_def); - if (ctrl) - ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + hblank_def = mode->hts_def - mode->width; + hblank_min = mode->hts_min - mode->width; + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HBLANK, + hblank_min, OV4689_HTS_MAX - mode->width, + OV4689_HTS_DIVIDER, hblank_def); vblank_def = mode->vts_def - mode->height; v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VBLANK, From patchwork Mon Dec 18 17:40:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497335 Received: from mail-lj1-f174.google.com (mail-lj1-f174.google.com [209.85.208.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EC0174E3B; Mon, 18 Dec 2023 17:41:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SHhhqRoN" Received: by mail-lj1-f174.google.com with SMTP id 38308e7fff4ca-2cc6b5a8364so17406451fa.2; Mon, 18 Dec 2023 09:41:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921273; x=1703526073; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qdSh6oi/Iw5H+Kb8gikp+vFtU20wx36V3GBFieJ685E=; b=SHhhqRoNIZftU/A3sMPzQ+C5C9VRLXfXm3IMq9yQfvJoopMPe/W3v/7shcP7YjQ45B SYNs7dmvhToSvf2A30amfD7HpHsLW+s/ZlX3H3PKlXpvCKMHTWzbtA9u8rZkBtj8Ldd+ AQAk9h5Ldx1cv+ymKR73O79vtyPQ8zYrCk2miRFOawGA7hxcVBKqC+et+SWR+euj/Bwo UMafa0IgsEvTCJK4rZIfF8ohlJ0XEKuSARfuDaP0CQmFksBXS6ap6r/Tsx6wxhxF0o3y hcoaUbQwfv2ZJTT38DTapVgXgGqT2oD5J9AlSPsZUmwOaUkmo7FQYnUgyroDI3E9FBNh E2JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921273; x=1703526073; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qdSh6oi/Iw5H+Kb8gikp+vFtU20wx36V3GBFieJ685E=; b=J20SG5KeoCgmvtlDfBMby2azUV9nHKXxT8aN1XQO8+izWxe0ErEwqWLsaKds3cpytk ImTjJbZEb7VkXD+itGB6HxsujAyESTpRWNN/BbD8jNkTuRiCawxtiFsct9v0kOvj/T8e oZ8wkyUGvJONuljpCsglX01cbBIG5KbM7ZZOJkkPKp37Dy7cNBHE2EZ3inSkdAzuWJEs yAG7AwjS7npJJCAVAX5zGWyrkim57pwyhGMaZxyrK2bv1EaHUdJfV6m2BbEhHkNE6pqp plNN3R6739O1x9/9uGZGwRve++y3BkOg9q0S8XNU9nJrOsQh7hG38F6ImzyMZVPrYMyz adWA== X-Gm-Message-State: AOJu0YxhIuUaiiHnN6chESz+RLpavDTkl8dMqBvn4wlcyPNvoPm5Vudc ZzK7b5o/OGxwJmoBctD0BKiTesL2sqNGqA== X-Google-Smtp-Source: AGHT+IFqVvCBigspIn7uwDT5zzsfSE7dmH82IPrSC1aeSAceHNjVmNZfRrkSE2tAH9f8by/veLnI3g== X-Received: by 2002:a2e:b892:0:b0:2cb:5b8a:7013 with SMTP id r18-20020a2eb892000000b002cb5b8a7013mr7039683ljp.75.1702921273170; Mon, 18 Dec 2023 09:41:13 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id h4-20020a2ebc84000000b002cc6fa877cesm543853ljf.76.2023.12.18.09.41.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:12 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 12/20] media: i2c: ov4689: Implement vflip/hflip controls Date: Mon, 18 Dec 2023 20:40:33 +0300 Message-ID: <20231218174042.794012-13-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The OV4689 sensor supports horizontal and vertical flipping. Add appropriate controls to the driver. Toggling both array flip and digital flip bits allows to achieve flipping while maintaining output Bayer order. Note that the default value of hflip control corresponds to both bits set, as it was before this patch. Signed-off-by: Mikhail Rudenko --- drivers/media/i2c/ov4689.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 06ed9d22b2c8..6cf986bf305d 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -42,6 +42,14 @@ #define OV4689_REG_VTS CCI_REG16(0x380e) #define OV4689_VTS_MAX 0x7fff +#define OV4689_REG_TIMING_FORMAT1 CCI_REG8(0x3820) +#define OV4689_REG_TIMING_FORMAT2 CCI_REG8(0x3821) +#define OV4689_TIMING_FLIP_MASK GENMASK(2, 1) +#define OV4689_TIMING_FLIP_ARRAY BIT(1) +#define OV4689_TIMING_FLIP_DIGITAL BIT(2) +#define OV4689_TIMING_FLIP_BOTH (OV4689_TIMING_FLIP_ARRAY |\ + OV4689_TIMING_FLIP_DIGITAL) + #define OV4689_REG_TEST_PATTERN CCI_REG8(0x5040) #define OV4689_TEST_PATTERN_ENABLE 0x80 #define OV4689_TEST_PATTERN_DISABLE 0x0 @@ -183,7 +191,6 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { {CCI_REG8(0x3811), 0x08}, /* H_WIN_OFF_L h_win_off[7:0] = 0x08*/ {CCI_REG8(0x3813), 0x04}, /* V_WIN_OFF_L v_win_off[7:0] = 0x04 */ {CCI_REG8(0x3819), 0x01}, /* VSYNC_END_L vsync_end_point[7:0] = 0x01 */ - {CCI_REG8(0x3821), 0x06}, /* TIMING_FORMAT2 array_h_mirror = 1, digital_h_mirror = 1 */ /* OTP control */ {CCI_REG8(0x3d85), 0x36}, /* OTP_REG85 OTP_power_up_load_setting_enable = 1, @@ -607,6 +614,16 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) (ctrl->val + ov4689->cur_mode->width) / OV4689_HTS_DIVIDER, &ret); break; + case V4L2_CID_VFLIP: + cci_update_bits(regmap, OV4689_REG_TIMING_FORMAT1, + OV4689_TIMING_FLIP_MASK, + ctrl->val ? OV4689_TIMING_FLIP_BOTH : 0, &ret); + break; + case V4L2_CID_HFLIP: + cci_update_bits(regmap, OV4689_REG_TIMING_FORMAT2, + OV4689_TIMING_FLIP_MASK, + ctrl->val ? 0 : OV4689_TIMING_FLIP_BOTH, &ret); + break; default: dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n", __func__, ctrl->id, ctrl->val); @@ -637,7 +654,7 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) handler = &ov4689->ctrl_handler; mode = ov4689->cur_mode; - ret = v4l2_ctrl_handler_init(handler, 10); + ret = v4l2_ctrl_handler_init(handler, 12); if (ret) return ret; @@ -677,6 +694,9 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) ARRAY_SIZE(ov4689_test_pattern_menu) - 1, 0, 0, ov4689_test_pattern_menu); + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + if (handler->error) { ret = handler->error; dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret); From patchwork Mon Dec 18 17:40:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497338 Received: from mail-lj1-f179.google.com (mail-lj1-f179.google.com [209.85.208.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 066A574086; Mon, 18 Dec 2023 17:41:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kZypryEv" Received: by mail-lj1-f179.google.com with SMTP id 38308e7fff4ca-2c9f8faf57bso42616961fa.3; Mon, 18 Dec 2023 09:41:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921274; x=1703526074; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JIwzcax46A46ItNbQ7ZCrC54+Ug7OcXYl/iMtTi3jXI=; b=kZypryEvoFfLSzH0Ni241v+8l/vZnN7WareyrSaFiVe22FZ3W3y+05eNBJyOW5rP7+ INtWG37unttZEfblN7UriXKa44CSke4rtNFSSxmYypLMOo7tHXkOY9WhBcTFsQuEI8bs 46vkDkwFq5hAG4NhEk5m2urE+NvFkahiY7c1joWDIhWw21D5ve6VVt6LjQMpD0VjOURM qrKy0BnDb8fHZJrhCTRHvFFW+9gM8pXGD1ABInH5fngdRm6LmDuqedPeViohkna+bfkP HazZe5TRU804aZGlsVJCD9VLj/Z/zYZQrG4Pw+KIL218vpEQ859N3Q2TAkLS3XMtXQc0 Y16g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921274; x=1703526074; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JIwzcax46A46ItNbQ7ZCrC54+Ug7OcXYl/iMtTi3jXI=; b=GpXzkzSMwBillItMc27IRlLC8uZB1+FT7Yf5H55R3cUsma+oYl6exkFy/GinyosAeX qQGefQRzYz7mkEzltW1vG1Hmy8hFrL822C2qzNvr8tj1oNDEDygkUwr5XG1BwKg/pOW7 AXfyzKRyen/SZSOdGpvMR1MVwY2wd+t2mPuVcQdLCkj15Tg/A/5GG0IWL2FTxAfWfCa0 IP6HnuZYIQV9FzWtxgW7gi9/c2AGERfzCeuLLoxGHvX+30u7NJd7Pp32FNnp3R7wW2Q6 T29gWrB3hyBr8/etHSAj3pk4yrs8kMtrFgVCM0iz6QbYEhDXD9yLGS1TAtu4JM4qg5H+ NBjw== X-Gm-Message-State: AOJu0YzIRpBZYed0S/IIs9FYylWL7jowAuAfS1S9T9MeA+VUFmAab+QS rBCjgPLk1JQn2rqvSLeJsdC8Vq+3bDG9Mg== X-Google-Smtp-Source: AGHT+IEBNWfcbcWCGaGFrxIgQ1i2BeJaXMZ+icuzr+MbhXAPm4xz81Q4UnfrAQqpzBb8Q/PWRET/9Q== X-Received: by 2002:a05:651c:149:b0:2cc:671c:a449 with SMTP id c9-20020a05651c014900b002cc671ca449mr1515868ljd.2.1702921274379; Mon, 18 Dec 2023 09:41:14 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id d18-20020a05651c089200b002cc782cf190sm210269ljq.72.2023.12.18.09.41.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:14 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 13/20] media: i2c: ov4689: Implement digital gain control Date: Mon, 18 Dec 2023 20:40:34 +0300 Message-ID: <20231218174042.794012-14-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The OV4689 sensor supports digital gain up to 16x. Implement corresponding control in the driver. Default digital gain value is not modified by this patch. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 6cf986bf305d..579362570ba4 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -35,6 +35,12 @@ #define OV4689_GAIN_STEP 1 #define OV4689_GAIN_DEFAULT 0x80 +#define OV4689_REG_DIG_GAIN CCI_REG16(0x352a) +#define OV4689_DIG_GAIN_MIN 1 +#define OV4689_DIG_GAIN_MAX 0x7fff +#define OV4689_DIG_GAIN_STEP 1 +#define OV4689_DIG_GAIN_DEFAULT 0x800 + #define OV4689_REG_HTS CCI_REG16(0x380c) #define OV4689_HTS_DIVIDER 4 #define OV4689_HTS_MAX 0x7fff @@ -131,7 +137,6 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { /* AEC PK */ {CCI_REG8(0x3503), 0x04}, /* AEC_MANUAL gain_input_as_sensor_gain_format = 1 */ - {CCI_REG8(0x352a), 0x08}, /* DIG_GAIN_FRAC_LONG dig_gain_long[14:8] = 0x08 (2x) */ /* ADC and analog control*/ {CCI_REG8(0x3603), 0x40}, @@ -624,6 +629,9 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) OV4689_TIMING_FLIP_MASK, ctrl->val ? 0 : OV4689_TIMING_FLIP_BOTH, &ret); break; + case V4L2_CID_DIGITAL_GAIN: + cci_write(regmap, OV4689_REG_DIG_GAIN, ctrl->val, &ret); + break; default: dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n", __func__, ctrl->id, ctrl->val); @@ -654,7 +662,7 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) handler = &ov4689->ctrl_handler; mode = ov4689->cur_mode; - ret = v4l2_ctrl_handler_init(handler, 12); + ret = v4l2_ctrl_handler_init(handler, 13); if (ret) return ret; @@ -697,6 +705,10 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_DIGITAL_GAIN, + OV4689_DIG_GAIN_MIN, OV4689_DIG_GAIN_MAX, + OV4689_DIG_GAIN_STEP, OV4689_DIG_GAIN_DEFAULT); + if (handler->error) { ret = handler->error; dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret); From patchwork Mon Dec 18 17:40:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497339 Received: from mail-lj1-f178.google.com (mail-lj1-f178.google.com [209.85.208.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E28BC740BC; Mon, 18 Dec 2023 17:41:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CDib+SPD" Received: by mail-lj1-f178.google.com with SMTP id 38308e7fff4ca-2cc4e15605aso39825581fa.0; Mon, 18 Dec 2023 09:41:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921276; x=1703526076; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7dk2TKVbYraAu74v7NaSM1t18f6z4SZSFZ1EWmH7B+A=; b=CDib+SPD87rYhO6EsoDjcOkOa9D5nY3ajlJLmrSUA0wyDAIf6YousNX5lf1isnD/d2 ZmmGogeQoyj+JEcE2c9U/K/4j/WYgJfNWsCkgq74f8QMaO9Vbco6QeYyCvC0b8IIll9M 1ooU2RrDH3ci9apPmbbno5VzK1241YK4MM7UFzN0RfcsG92av9ddt+8iJYPsUUeqhiKM 1AOFGqGOICeHEuB5WOy/2V503t2nlGcPLYXn9CIAuAuO/L71cG8jwFma829vE/gSJvY0 31Gw/yKPGPpe8A4yrpKZ3jfKFM/cgzwWN4LFpZ7pB38hqEFhFfVvAjZes1V/kz2IEjE9 haeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921276; x=1703526076; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7dk2TKVbYraAu74v7NaSM1t18f6z4SZSFZ1EWmH7B+A=; b=pDYOZAdKJj052vjHI8ZNN43oUdtnSzPG4yc95OH/TkUei9QiBvj1evXE+P0yP0TTws Y2oQrGPxc536h2FOQEZKiYgNwkfuiD9KUODwEgIy+MGjVry49CewiTuCip3fuLOBGtNQ GJ2usShDtuF5omwl5lUv3tM1KVIsaRwZ5jixuVNtNPAw3OeBnXrRXYBofObS+OObUHS6 qEArH3VEM5xQDe5hNa2kShXxFElPkJuljzjTa03TY1R6Gh2rd3Sq8PV499gl96vC5YLu 5XP2EtV+yd+QNmIWl8MEcJaO43ywS9FiwZQkvNi1tVOwCQxNiozWW7A/Ffxr2LMYMR8n SXtw== X-Gm-Message-State: AOJu0YzfwLhjDCGQuSeNSFRX1QcVaWNdkFoZla+9ZVs+nRUgKLDtUI15 QF9SbwAguXOzPACnRwimQu7sSgWA6dbfJg== X-Google-Smtp-Source: AGHT+IGKWDiozrtpr6qFpU+ktcXW+LOrfaN4oJ191M+u5ciwj+4UpK4tleOWT5p4t+1Nr+FPWXmtRA== X-Received: by 2002:a2e:998f:0:b0:2cc:4547:1892 with SMTP id w15-20020a2e998f000000b002cc45471892mr3267791lji.34.1702921275695; Mon, 18 Dec 2023 09:41:15 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id d8-20020a05651c01c800b002ca34ad9e8bsm3563871ljn.138.2023.12.18.09.41.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:15 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 14/20] media: i2c: ov4689: Implement manual color balance controls Date: Mon, 18 Dec 2023 20:40:35 +0300 Message-ID: <20231218174042.794012-15-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The OV4689 sensor has separate red and blue gain settings (up to 4x). Implement appropriate controls in the driver. Default gain values are not modified. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 579362570ba4..b43fb1d7b15f 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -56,6 +56,13 @@ #define OV4689_TIMING_FLIP_BOTH (OV4689_TIMING_FLIP_ARRAY |\ OV4689_TIMING_FLIP_DIGITAL) +#define OV4689_REG_WB_GAIN_RED CCI_REG16(0x500c) +#define OV4689_REG_WB_GAIN_BLUE CCI_REG16(0x5010) +#define OV4689_WB_GAIN_MIN 1 +#define OV4689_WB_GAIN_MAX 0xfff +#define OV4689_WB_GAIN_STEP 1 +#define OV4689_WB_GAIN_DEFAULT 0x400 + #define OV4689_REG_TEST_PATTERN CCI_REG8(0x5040) #define OV4689_TEST_PATTERN_ENABLE 0x80 #define OV4689_TEST_PATTERN_DISABLE 0x0 @@ -632,6 +639,12 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_DIGITAL_GAIN: cci_write(regmap, OV4689_REG_DIG_GAIN, ctrl->val, &ret); break; + case V4L2_CID_RED_BALANCE: + cci_write(regmap, OV4689_REG_WB_GAIN_RED, ctrl->val, &ret); + break; + case V4L2_CID_BLUE_BALANCE: + cci_write(regmap, OV4689_REG_WB_GAIN_BLUE, ctrl->val, &ret); + break; default: dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n", __func__, ctrl->id, ctrl->val); @@ -662,7 +675,7 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) handler = &ov4689->ctrl_handler; mode = ov4689->cur_mode; - ret = v4l2_ctrl_handler_init(handler, 13); + ret = v4l2_ctrl_handler_init(handler, 15); if (ret) return ret; @@ -709,6 +722,14 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) OV4689_DIG_GAIN_MIN, OV4689_DIG_GAIN_MAX, OV4689_DIG_GAIN_STEP, OV4689_DIG_GAIN_DEFAULT); + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_RED_BALANCE, + OV4689_WB_GAIN_MIN, OV4689_WB_GAIN_MAX, + OV4689_WB_GAIN_STEP, OV4689_WB_GAIN_DEFAULT); + + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_BLUE_BALANCE, + OV4689_WB_GAIN_MIN, OV4689_WB_GAIN_MAX, + OV4689_WB_GAIN_STEP, OV4689_WB_GAIN_DEFAULT); + if (handler->error) { ret = handler->error; dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret); From patchwork Mon Dec 18 17:40:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497340 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7826B79955; Mon, 18 Dec 2023 17:41:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NzD3u9KZ" Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-50bf2d9b3fdso4627940e87.3; Mon, 18 Dec 2023 09:41:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921277; x=1703526077; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4SjlvAuV+ITVZU87l8JftGavoBHWbV2WagI03hZeup4=; b=NzD3u9KZ6UbCKI8H7DB1Z3O7fH8g3PkrclL6XA/Wn8Gp4jCt4ozpGz1fQRdG7ykA9c /s4gAaTORzIqOiduM403whLdWgr0dXbK8YHoyVm7oSPjoNU3k5WBkpWkB9/gH7v7OloP mGtM2kc6SEWZSDslkfncHQhnx8vHtZr2ks+nYAc/pbK2h9wLWWuW77bNiRc5HT3TRPRM g2UdkNFe4XP0o6cfaDHakr38O783eQhJQeAtpXn4vU7rcoHR3H5A/f2ufevoO0Nq5SUx nPZPOQ2ct03xuK5BzRd4Bi04xljL4hITeVSwTvGKr/SZlj5oCZ+gvYf/WLrFTL7wAq9t ksdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921277; x=1703526077; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4SjlvAuV+ITVZU87l8JftGavoBHWbV2WagI03hZeup4=; b=Ca3YdSxwHNcqjksxti0zSct4SFbCJAS3unlCIKXOr6YrRCt0kDCfTJCqoVbXqTQb2x mDBdPf+N6iz8nQuWSx6hSHiFo9PF5TuaR7/unq5Kzg/d/GmCcMhJpKBtW1SJ2HYPHJw7 ZwnS9h8m2F4q4b/CgQYg83TlQwLeR32qifHIq6W6DBP9n2X6FSUDOceF00w5jCwJoY/X XDK+Bymk+F619qDkT+62okgs22iHtVoXh9eBberecydnPz0MhlezZWWx7tXRNiK+xax6 tlWt5TtX8uFfm2txN7zF7cX5vSeegreLpq8eY5YUcgu9HQIUfJF3MU/nZneIBivoUcwr uwjg== X-Gm-Message-State: AOJu0YxkLZnLCF4I/s8Web6HdWrwWoGxKkOAVjGiOi8T71lYGZCzsqur 25GHnU0XxIqFkrTTDKojTTMGh05MvGd5xg== X-Google-Smtp-Source: AGHT+IEpHBMcQFNgHrRtF7STxyBad7yeoLMk3qAFvX+/l/O6so3UTpn9p3QJpE9w7exXQyhfLJ9k9w== X-Received: by 2002:ac2:419a:0:b0:50c:222b:2489 with SMTP id z26-20020ac2419a000000b0050c222b2489mr6965947lfh.135.1702921276912; Mon, 18 Dec 2023 09:41:16 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id f9-20020a0565123b0900b0050e3b2646a0sm265645lfv.152.2023.12.18.09.41.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:16 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 15/20] media: i2c: ov4689: Move pixel array size out of struct ov4689_mode Date: Mon, 18 Dec 2023 20:40:36 +0300 Message-ID: <20231218174042.794012-16-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Pixel array dimensions and default crop size do not belong to the ov4689_mode structure, since they are mode independent. Make them defines instead. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index b43fb1d7b15f..475508559e3e 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -70,6 +70,11 @@ #define OV4689_LANES 4 #define OV4689_XVCLK_FREQ 24000000 +#define OV4689_PIXEL_ARRAY_WIDTH 2720 +#define OV4689_PIXEL_ARRAY_HEIGHT 1536 +#define OV4689_DUMMY_ROWS 8 +#define OV4689_DUMMY_COLUMNS 16 + static const char *const ov4689_supply_names[] = { "avdd", /* Analog power */ "dovdd", /* Digital I/O power */ @@ -90,10 +95,6 @@ struct ov4689_mode { u32 vts_def; u32 exp_def; u32 pixel_rate; - u32 sensor_width; - u32 sensor_height; - u32 crop_top; - u32 crop_left; const struct cci_reg_sequence *reg_list; unsigned int num_regs; }; @@ -254,10 +255,6 @@ static const struct ov4689_mode supported_modes[] = { .id = OV4689_MODE_2688_1520, .width = 2688, .height = 1520, - .sensor_width = 2720, - .sensor_height = 1536, - .crop_top = 8, - .crop_left = 16, .exp_def = 1536, .hts_def = 10296, .hts_min = 3432, @@ -385,8 +382,6 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel) { - const struct ov4689_mode *mode = to_ov4689(sd)->cur_mode; - if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; @@ -394,15 +389,17 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, case V4L2_SEL_TGT_CROP_BOUNDS: sel->r.top = 0; sel->r.left = 0; - sel->r.width = mode->sensor_width; - sel->r.height = mode->sensor_height; + sel->r.width = OV4689_PIXEL_ARRAY_WIDTH; + sel->r.height = OV4689_PIXEL_ARRAY_HEIGHT; return 0; case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_CROP_DEFAULT: - sel->r.top = mode->crop_top; - sel->r.left = mode->crop_left; - sel->r.width = mode->width; - sel->r.height = mode->height; + sel->r.top = OV4689_DUMMY_ROWS; + sel->r.left = OV4689_DUMMY_COLUMNS; + sel->r.width = + OV4689_PIXEL_ARRAY_WIDTH - 2 * OV4689_DUMMY_COLUMNS; + sel->r.height = + OV4689_PIXEL_ARRAY_WIDTH - 2 * OV4689_DUMMY_ROWS; return 0; } From patchwork Mon Dec 18 17:40:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497341 Received: from mail-lf1-f45.google.com (mail-lf1-f45.google.com [209.85.167.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A239E7BEE3; Mon, 18 Dec 2023 17:41:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="j8kNAbtN" Received: by mail-lf1-f45.google.com with SMTP id 2adb3069b0e04-50e24e92432so2957279e87.2; Mon, 18 Dec 2023 09:41:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921281; x=1703526081; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=W5pi4djYNxaCEjMPJwbP6idbsJSRFN1lOjcDzQOgWR4=; b=j8kNAbtNnjMj2XxDRPyh0EZ29zeysA/dfD7n5xMMa6rjjENChCW2yHqMYPvyq9Sah+ gxwXHwguJLnpP75OHllozbQaO1TnxQ79XeKSGjFLA7JpjwZOWV4/4pmAt1NQ50KsSufw WiDkxeHbj7ev8zHV+qEykG9OJqxzXElBZdPwM/0KLctru4Koc75pVxJwhiol9o1llB88 ty8hg/Hl095eXtEjlc2QdAowXmuNSLJiKaNpFksCov3fu0UA+r9K4cFANxRqSAWyiSIX OrrVUtF8Xy8hs9D7YtsX5YsspZ6Osm5jO/RxVV+048HO8Sq+OE6totN+eDvhZNVD5cNa 7HHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921281; x=1703526081; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=W5pi4djYNxaCEjMPJwbP6idbsJSRFN1lOjcDzQOgWR4=; b=qoVRrdzFjYn4YDtnAueNnBOwC3KELQ7MefcCs/yzlw2Bc/MaEfQCiV1z6dNF7nGK8q JkKJsYgoUkApYsdYKL0ui2j86SzwsqHgYhO4wByE0cYZwEOMWvLz4M7SkoXBcc8uY6x9 NkJvnzD1jq8EGCmKedcWiOUWREC1FffeQJno6ejV2dkNqVy8zV+ceR1IGmV3ccPY3/8j C/XZ5mtp4pDw05N5wr4XGQmuk201FczblaSoVTyKgp+m9l5BZL0XN7wGca4NfRodKM28 cnS1oGrYqT+uLS1QISMvRetEfNkKcDXjECUkINDGl7NJrlsI7D3g5asMTLDQUYTVKBDP K9qQ== X-Gm-Message-State: AOJu0Yy16F5DXqhpEz2soDvGr2jpsSImCjTzY67b3d/VdowZJXAjoUGC Qz6Ml7XMSbHQYo/y73h603ma7Y6XC98HcA== X-Google-Smtp-Source: AGHT+IHul+BYeWgrfH3xAh5Y8sk8RJ8gwUR9wSYw6i0vNiaJJNOlA7jkIcC1bZs2PHWnfRZOw9nuDQ== X-Received: by 2002:ac2:43d0:0:b0:50e:3afa:7e34 with SMTP id u16-20020ac243d0000000b0050e3afa7e34mr760175lfl.111.1702921278264; Mon, 18 Dec 2023 09:41:18 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id dx6-20020a0565122c0600b0050bca70287esm2957427lfb.50.2023.12.18.09.41.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:17 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 16/20] media: i2c: ov4689: Set timing registers programmatically Date: Mon, 18 Dec 2023 20:40:37 +0300 Message-ID: <20231218174042.794012-17-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Set timing-related and BLC anchor registers via cci calls instead of hardcoding them in the register table. This prepares the driver for implementation of configurable analogue crop and binning. No functional change intended. Signed-off-by: Mikhail Rudenko Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov4689.c | 83 +++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 475508559e3e..3b73ee282761 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -41,6 +41,13 @@ #define OV4689_DIG_GAIN_STEP 1 #define OV4689_DIG_GAIN_DEFAULT 0x800 +#define OV4689_REG_H_CROP_START CCI_REG16(0x3800) +#define OV4689_REG_V_CROP_START CCI_REG16(0x3802) +#define OV4689_REG_H_CROP_END CCI_REG16(0x3804) +#define OV4689_REG_V_CROP_END CCI_REG16(0x3806) +#define OV4689_REG_H_OUTPUT_SIZE CCI_REG16(0x3808) +#define OV4689_REG_V_OUTPUT_SIZE CCI_REG16(0x380a) + #define OV4689_REG_HTS CCI_REG16(0x380c) #define OV4689_HTS_DIVIDER 4 #define OV4689_HTS_MAX 0x7fff @@ -48,6 +55,9 @@ #define OV4689_REG_VTS CCI_REG16(0x380e) #define OV4689_VTS_MAX 0x7fff +#define OV4689_REG_H_WIN_OFF CCI_REG16(0x3810) +#define OV4689_REG_V_WIN_OFF CCI_REG16(0x3812) + #define OV4689_REG_TIMING_FORMAT1 CCI_REG8(0x3820) #define OV4689_REG_TIMING_FORMAT2 CCI_REG8(0x3821) #define OV4689_TIMING_FLIP_MASK GENMASK(2, 1) @@ -56,6 +66,17 @@ #define OV4689_TIMING_FLIP_BOTH (OV4689_TIMING_FLIP_ARRAY |\ OV4689_TIMING_FLIP_DIGITAL) +#define OV4689_REG_ANCHOR_LEFT_START CCI_REG16(0x4020) +#define OV4689_ANCHOR_LEFT_START_DEF 576 +#define OV4689_REG_ANCHOR_LEFT_END CCI_REG16(0x4022) +#define OV4689_ANCHOR_LEFT_END_DEF 831 +#define OV4689_REG_ANCHOR_RIGHT_START CCI_REG16(0x4024) +#define OV4689_ANCHOR_RIGHT_START_DEF 1984 +#define OV4689_REG_ANCHOR_RIGHT_END CCI_REG16(0x4026) +#define OV4689_ANCHOR_RIGHT_END_DEF 2239 + +#define OV4689_REG_VFIFO_CTRL_01 CCI_REG8(0x4601) + #define OV4689_REG_WB_GAIN_RED CCI_REG16(0x500c) #define OV4689_REG_WB_GAIN_BLUE CCI_REG16(0x5010) #define OV4689_WB_GAIN_MIN 1 @@ -199,10 +220,6 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { {CCI_REG8(0x3798), 0x1b}, /* Timing control */ - {CCI_REG8(0x3801), 0x08}, /* H_CROP_START_L h_crop_start[7:0] = 0x08 */ - {CCI_REG8(0x3805), 0x97}, /* H_CROP_END_L h_crop_end[7:0] = 0x97 */ - {CCI_REG8(0x3811), 0x08}, /* H_WIN_OFF_L h_win_off[7:0] = 0x08*/ - {CCI_REG8(0x3813), 0x04}, /* V_WIN_OFF_L v_win_off[7:0] = 0x04 */ {CCI_REG8(0x3819), 0x01}, /* VSYNC_END_L vsync_end_point[7:0] = 0x01 */ /* OTP control */ @@ -218,22 +235,11 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { {CCI_REG8(0x401b), 0x00}, /* DEBUG_MODE */ {CCI_REG8(0x401d), 0x00}, /* DEBUG_MODE */ {CCI_REG8(0x401f), 0x00}, /* DEBUG_MODE */ - {CCI_REG8(0x4020), 0x00}, /* ANCHOR_LEFT_START_H anchor_left_start[11:8] = 0 */ - {CCI_REG8(0x4021), 0x10}, /* ANCHOR_LEFT_START_L anchor_left_start[7:0] = 0x10 */ - {CCI_REG8(0x4022), 0x07}, /* ANCHOR_LEFT_END_H anchor_left_end[11:8] = 0x07 */ - {CCI_REG8(0x4023), 0xcf}, /* ANCHOR_LEFT_END_L anchor_left_end[7:0] = 0xcf */ - {CCI_REG8(0x4024), 0x09}, /* ANCHOR_RIGHT_START_H anchor_right_start[11:8] = 0x09 */ - {CCI_REG8(0x4025), 0x60}, /* ANCHOR_RIGHT_START_L anchor_right_start[7:0] = 0x60 */ - {CCI_REG8(0x4026), 0x09}, /* ANCHOR_RIGHT_END_H anchor_right_end[11:8] = 0x09 */ - {CCI_REG8(0x4027), 0x6f}, /* ANCHOR_RIGHT_END_L anchor_right_end[7:0] = 0x6f */ /* ADC sync control */ {CCI_REG8(0x4500), 0x6c}, /* ADC_SYNC_CTRL */ {CCI_REG8(0x4503), 0x01}, /* ADC_SYNC_CTRL */ - /* VFIFO */ - {CCI_REG8(0x4601), 0xa7}, /* VFIFO_CTRL_01 r_vfifo_read_start[7:0] = 0xa7 */ - /* Temperature monitor */ {CCI_REG8(0x4d00), 0x04}, /* TPM_CTRL_00 tmp_slope[15:8] = 0x04 */ {CCI_REG8(0x4d01), 0x42}, /* TPM_CTRL_01 tmp_slope[7:0] = 0x42 */ @@ -406,6 +412,41 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, return -EINVAL; } +static int ov4689_setup_timings(struct ov4689 *ov4689) +{ + const struct ov4689_mode *mode = ov4689->cur_mode; + struct regmap *rm = ov4689->regmap; + int ret = 0; + + cci_write(rm, OV4689_REG_H_CROP_START, 8, &ret); + cci_write(rm, OV4689_REG_V_CROP_START, 8, &ret); + cci_write(rm, OV4689_REG_H_CROP_END, 2711, &ret); + cci_write(rm, OV4689_REG_V_CROP_END, 1531, &ret); + + cci_write(rm, OV4689_REG_H_OUTPUT_SIZE, mode->width, &ret); + cci_write(rm, OV4689_REG_V_OUTPUT_SIZE, mode->height, &ret); + + cci_write(rm, OV4689_REG_H_WIN_OFF, 8, &ret); + cci_write(rm, OV4689_REG_V_WIN_OFF, 4, &ret); + + cci_write(rm, OV4689_REG_VFIFO_CTRL_01, 167, &ret); + + return ret; +} + +static int ov4689_setup_blc_anchors(struct ov4689 *ov4689) +{ + struct regmap *rm = ov4689->regmap; + int ret = 0; + + cci_write(rm, OV4689_REG_ANCHOR_LEFT_START, 16, &ret); + cci_write(rm, OV4689_REG_ANCHOR_LEFT_END, 1999, &ret); + cci_write(rm, OV4689_REG_ANCHOR_RIGHT_START, 2400, &ret); + cci_write(rm, OV4689_REG_ANCHOR_RIGHT_END, 2415, &ret); + + return ret; +} + static int ov4689_s_stream(struct v4l2_subdev *sd, int on) { struct ov4689 *ov4689 = to_ov4689(sd); @@ -429,6 +470,18 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) goto unlock_and_return; } + ret = ov4689_setup_timings(ov4689); + if (ret) { + pm_runtime_put(dev); + goto unlock_and_return; + } + + ret = ov4689_setup_blc_anchors(ov4689); + if (ret) { + pm_runtime_put(dev); + goto unlock_and_return; + } + ret = __v4l2_ctrl_handler_setup(&ov4689->ctrl_handler); if (ret) { pm_runtime_put_sync(dev); From patchwork Mon Dec 18 17:40:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497342 Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04CBD74E11; Mon, 18 Dec 2023 17:41:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cEh5l6Eh" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-50e2bd8c396so2411514e87.0; Mon, 18 Dec 2023 09:41:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921283; x=1703526083; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KTzwxcQOtEUgdARmaClunNggauUXTYf3+l9k/4G0WNY=; b=cEh5l6EhPDNzOS9ufLgylh0QR3O65Hrq3Q8513vqg2WhQ3Y36xndHvjciIBSMiX8YZ 3uGGd4qzLI9G1jgPFYcDWoPd6NjQWOYUgW4hcl4fDu/+x6lLDJ1p7ycSzEGhJysKyaF4 Y4r/leZ36rN8kSZAa8QGPBG8gYnfSHJFNSYyiaBd35yHBgIL0K75Vbo2IMm4oZNspi19 z0P/zKhh53sq167zpY6YDyDfDEMe+CUUGBEfqis/SwUFKHEpigbVyUxosG9e+cggT3ec lykRuDcygR6zdCAQO4oKmSKg2FAhMQLo7N66HjJKAuRB7Lrc1aa8Aux6bNBR2SM1/WEq vfcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921283; x=1703526083; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KTzwxcQOtEUgdARmaClunNggauUXTYf3+l9k/4G0WNY=; b=Ho4TzWTgjbDPg7Iyagoj0MapJqwiOW9Ewl+g8edEwwDpeKI1HHMDPxjcgsNQQ68SGN xVaxCOx7da86rpQLERplDr5qrdrqGdvNj/ZZbtG0Ydc25BMkuldb/bBLL/vf79Qvv1dI p1bgxjUIRrEL+HXq4SrsA0mgmcLD1YEW3KpyMnVgHaie0Dl0mqwl5c4BPRsNpsnrIFoK guCXWubNCRXCbWKGSNKx/cA3gNsx5sSd+Pw0RPhw8bhY4kc4Qf8zre6XnKIVXfD5sN3v C1S4RDyOF7qIqbmd++JnKkSTvK2ZnT2UuxqiR5fl9SGj6kO9nKn9PCVF4kJPzAhdAbAU juXw== X-Gm-Message-State: AOJu0Yw0BefNjCMzW6pPyn+afT4wCRilflclpZ1Chbo1O+QGr/d439wm abTy/T0y2TeBK79MPm8OT22BfEQPaMCMUg== X-Google-Smtp-Source: AGHT+IFDvucPOD3vVTUe7QGw2qRtwiLqwDJh3p+oGlTMd9PTfm9uN3xmQC7Kc6JCsLFK4DdpB07hOA== X-Received: by 2002:ac2:428b:0:b0:50d:ae2:2a9f with SMTP id m11-20020ac2428b000000b0050d0ae22a9fmr6827246lfh.24.1702921282838; Mon, 18 Dec 2023 09:41:22 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id i18-20020a056512225200b0050bfbb6a388sm2967537lfu.22.2023.12.18.09.41.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:22 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 17/20] media: i2c: ov4689: Configurable analogue crop Date: Mon, 18 Dec 2023 20:40:38 +0300 Message-ID: <20231218174042.794012-18-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement configurable analogue crop via .set_selectiong call. ov4689_init_cfg is modified to initialize default subdev selection. Offsets are aligned to 2 to preserve Bayer order, selection width is aligned to 4 and height to 2 to meet hardware requirements. Experimentally discovered values of the cropping-related registers and vfifo_read_start for various output sizes are used. Default BLC anchor positions are used for the default analogue crop, scaling down proportionally for the smaller crop sizes. When analogue crop is adjusted, several consequential actions take place: the output format is reset, exposure/vblank/hblank control ranges and default values are adjusted accordingly. Additionally, ov4689_set_ctrl utilizes pad crop instead of cur_mode width and height for HTS and VTS calculation. Also, ov4689_enum_frame_sizes is modified to report crop size as available frame size. Signed-off-by: Mikhail Rudenko --- drivers/media/i2c/ov4689.c | 276 ++++++++++++++++++++++++++++--------- 1 file changed, 212 insertions(+), 64 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 3b73ee282761..d2d3e5517576 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -45,8 +45,12 @@ #define OV4689_REG_V_CROP_START CCI_REG16(0x3802) #define OV4689_REG_H_CROP_END CCI_REG16(0x3804) #define OV4689_REG_V_CROP_END CCI_REG16(0x3806) + #define OV4689_REG_H_OUTPUT_SIZE CCI_REG16(0x3808) +#define OV4689_H_OUTPUT_SIZE_DEFAULT 2688 + #define OV4689_REG_V_OUTPUT_SIZE CCI_REG16(0x380a) +#define OV4689_V_OUTPUT_SIZE_DEFAULT 1520 #define OV4689_REG_HTS CCI_REG16(0x380c) #define OV4689_HTS_DIVIDER 4 @@ -96,6 +100,19 @@ #define OV4689_DUMMY_ROWS 8 #define OV4689_DUMMY_COLUMNS 16 +/* + * These values are not hardware limits, but rather the minimums that + * the driver has been tested to. + */ +#define OV4689_H_CROP_MIN 128 +#define OV4689_V_CROP_MIN 128 + +/* + * Minimum working vertical blanking value. Found experimentally at + * minimum HTS values. + */ +#define OV4689_VBLANK_MIN 31 + static const char *const ov4689_supply_names[] = { "avdd", /* Analog power */ "dovdd", /* Digital I/O power */ @@ -134,7 +151,7 @@ struct ov4689 { u32 clock_rate; struct v4l2_ctrl_handler ctrl_handler; - struct v4l2_ctrl *exposure; + struct v4l2_ctrl *exposure, *hblank, *vblank; const struct ov4689_mode *cur_mode; }; @@ -320,24 +337,27 @@ static const struct ov4689_gain_range ov4689_gain_ranges[] = { }, }; -static void ov4689_fill_fmt(const struct ov4689_mode *mode, - struct v4l2_mbus_framefmt *fmt) -{ - fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; - fmt->width = mode->width; - fmt->height = mode->height; - fmt->field = V4L2_FIELD_NONE; -} - static int ov4689_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; - struct ov4689 *ov4689 = to_ov4689(sd); + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + + crop = v4l2_subdev_state_get_crop(sd_state, fmt->pad); + format = v4l2_subdev_state_get_format(sd_state, fmt->pad); + + format->width = crop->width; + format->height = crop->height; - /* only one mode supported for now */ - ov4689_fill_fmt(ov4689->cur_mode, mbus_fmt); + format->code = MEDIA_BUS_FMT_SBGGR10_1X10; + format->field = V4L2_FIELD_NONE; + format->colorspace = V4L2_COLORSPACE_RAW; + format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + format->quantization = V4L2_QUANTIZATION_FULL_RANGE; + format->xfer_func = V4L2_XFER_FUNC_NONE; + + fmt->format = *format; return 0; } @@ -357,16 +377,20 @@ static int ov4689_enum_frame_sizes(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index >= ARRAY_SIZE(supported_modes)) + const struct v4l2_rect *crop; + + if (fse->index >= 1) return -EINVAL; if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10) return -EINVAL; - fse->min_width = supported_modes[fse->index].width; - fse->max_width = supported_modes[fse->index].width; - fse->max_height = supported_modes[fse->index].height; - fse->min_height = supported_modes[fse->index].height; + crop = v4l2_subdev_state_get_crop(sd_state, 0); + + fse->min_width = crop->width; + fse->max_width = crop->width; + fse->max_height = crop->height; + fse->min_height = crop->height; return 0; } @@ -388,20 +412,14 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel) { - if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) - return -EINVAL; - switch (sel->target) { - case V4L2_SEL_TGT_CROP_BOUNDS: - sel->r.top = 0; - sel->r.left = 0; - sel->r.width = OV4689_PIXEL_ARRAY_WIDTH; - sel->r.height = OV4689_PIXEL_ARRAY_HEIGHT; - return 0; case V4L2_SEL_TGT_CROP: + sel->r = *v4l2_subdev_state_get_crop(state, sel->pad); + return 0; + case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_CROP_DEFAULT: - sel->r.top = OV4689_DUMMY_ROWS; sel->r.left = OV4689_DUMMY_COLUMNS; + sel->r.top = OV4689_DUMMY_ROWS; sel->r.width = OV4689_PIXEL_ARRAY_WIDTH - 2 * OV4689_DUMMY_COLUMNS; sel->r.height = @@ -412,37 +430,141 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, return -EINVAL; } -static int ov4689_setup_timings(struct ov4689 *ov4689) +/* + * Minimum working HTS value for given output width (found + * experimentally). + */ +static unsigned int ov4689_hts_min(unsigned int width) +{ + return max_t(unsigned int, 3156, 224 + width * 19 / 16); +} + +static void ov4689_update_ctrl_ranges(struct ov4689 *ov4689, + struct v4l2_rect *crop) +{ + struct v4l2_ctrl *exposure = ov4689->exposure; + struct v4l2_ctrl *vblank = ov4689->vblank; + struct v4l2_ctrl *hblank = ov4689->hblank; + s64 def_val, min_val, max_val; + + min_val = ov4689_hts_min(crop->width) - crop->width; + max_val = OV4689_HTS_MAX - crop->width; + def_val = clamp_t(s64, hblank->default_value, min_val, max_val); + __v4l2_ctrl_modify_range(hblank, min_val, max_val, hblank->step, + def_val); + + min_val = OV4689_VBLANK_MIN; + max_val = OV4689_HTS_MAX - crop->width; + def_val = clamp_t(s64, vblank->default_value, min_val, max_val); + __v4l2_ctrl_modify_range(vblank, min_val, max_val, vblank->step, + def_val); + + min_val = exposure->minimum; + max_val = crop->height + vblank->val - 4; + def_val = clamp_t(s64, exposure->default_value, min_val, max_val); + __v4l2_ctrl_modify_range(exposure, min_val, max_val, exposure->step, + def_val); +} + +static int ov4689_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) { - const struct ov4689_mode *mode = ov4689->cur_mode; + struct ov4689 *ov4689 = to_ov4689(sd); + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + struct v4l2_rect rect; + + if (sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + rect.left = clamp(ALIGN(sel->r.left, 2), OV4689_DUMMY_COLUMNS, + OV4689_PIXEL_ARRAY_WIDTH); + rect.top = clamp(ALIGN(sel->r.top, 2), OV4689_DUMMY_ROWS, + OV4689_PIXEL_ARRAY_HEIGHT); + + rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 4), + OV4689_H_CROP_MIN, OV4689_PIXEL_ARRAY_WIDTH - + 2 * OV4689_DUMMY_COLUMNS); + rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), + OV4689_V_CROP_MIN, OV4689_PIXEL_ARRAY_HEIGHT - + 2 * OV4689_DUMMY_ROWS); + + crop = v4l2_subdev_state_get_crop(state, sel->pad); + + if (rect.width != crop->width || rect.height != crop->height) { + /* + * Reset the output image size if the crop rectangle size has + * been modified. + */ + format = v4l2_subdev_state_get_format(state, sel->pad); + format->width = rect.width; + format->height = rect.height; + + if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) + ov4689_update_ctrl_ranges(ov4689, &rect); + } + + *crop = rect; + sel->r = rect; + + return 0; +} + +static int ov4689_setup_timings(struct ov4689 *ov4689, + struct v4l2_subdev_state *state) +{ + const struct v4l2_mbus_framefmt *format; struct regmap *rm = ov4689->regmap; + const struct v4l2_rect *crop; int ret = 0; - cci_write(rm, OV4689_REG_H_CROP_START, 8, &ret); - cci_write(rm, OV4689_REG_V_CROP_START, 8, &ret); - cci_write(rm, OV4689_REG_H_CROP_END, 2711, &ret); - cci_write(rm, OV4689_REG_V_CROP_END, 1531, &ret); + format = v4l2_subdev_state_get_format(state, 0); + crop = v4l2_subdev_state_get_crop(state, 0); + + cci_write(rm, OV4689_REG_H_CROP_START, crop->left, &ret); + cci_write(rm, OV4689_REG_V_CROP_START, crop->top, &ret); + cci_write(rm, OV4689_REG_H_CROP_END, crop->left + crop->width + 1, &ret); + cci_write(rm, OV4689_REG_V_CROP_END, crop->top + crop->height + 1, &ret); - cci_write(rm, OV4689_REG_H_OUTPUT_SIZE, mode->width, &ret); - cci_write(rm, OV4689_REG_V_OUTPUT_SIZE, mode->height, &ret); + cci_write(rm, OV4689_REG_H_OUTPUT_SIZE, format->width, &ret); + cci_write(rm, OV4689_REG_V_OUTPUT_SIZE, format->height, &ret); - cci_write(rm, OV4689_REG_H_WIN_OFF, 8, &ret); - cci_write(rm, OV4689_REG_V_WIN_OFF, 4, &ret); + cci_write(rm, OV4689_REG_H_WIN_OFF, 0, &ret); + cci_write(rm, OV4689_REG_V_WIN_OFF, 0, &ret); - cci_write(rm, OV4689_REG_VFIFO_CTRL_01, 167, &ret); + /* + * Maximum working value of vfifo_read_start for given output + * width (found experimentally). + */ + cci_write(rm, OV4689_REG_VFIFO_CTRL_01, format->width / 16 - 1, &ret); return ret; } -static int ov4689_setup_blc_anchors(struct ov4689 *ov4689) +/* + * Setup black level compensation anchors. For the default frame width + * default anchors positions are used. For smaller crop sizes they are + * scaled accordingly. + */ +static int ov4689_setup_blc_anchors(struct ov4689 *ov4689, + struct v4l2_subdev_state *state) { + unsigned int width_def = OV4689_H_OUTPUT_SIZE_DEFAULT; struct regmap *rm = ov4689->regmap; + const struct v4l2_rect *crop; int ret = 0; - cci_write(rm, OV4689_REG_ANCHOR_LEFT_START, 16, &ret); - cci_write(rm, OV4689_REG_ANCHOR_LEFT_END, 1999, &ret); - cci_write(rm, OV4689_REG_ANCHOR_RIGHT_START, 2400, &ret); - cci_write(rm, OV4689_REG_ANCHOR_RIGHT_END, 2415, &ret); + crop = v4l2_subdev_state_get_crop(state, 0); + + cci_write(rm, OV4689_REG_ANCHOR_LEFT_START, + OV4689_ANCHOR_LEFT_START_DEF * crop->width / width_def, &ret); + cci_write(rm, OV4689_REG_ANCHOR_LEFT_END, + OV4689_ANCHOR_LEFT_END_DEF * crop->width / width_def, &ret); + cci_write(rm, OV4689_REG_ANCHOR_RIGHT_START, + OV4689_ANCHOR_RIGHT_START_DEF * crop->width / width_def, &ret); + cci_write(rm, OV4689_REG_ANCHOR_RIGHT_END, + OV4689_ANCHOR_RIGHT_END_DEF * crop->width / width_def, &ret); return ret; } @@ -470,13 +592,13 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) goto unlock_and_return; } - ret = ov4689_setup_timings(ov4689); + ret = ov4689_setup_timings(ov4689, sd_state); if (ret) { pm_runtime_put(dev); goto unlock_and_return; } - ret = ov4689_setup_blc_anchors(ov4689); + ret = ov4689_setup_blc_anchors(ov4689, sd_state); if (ret) { pm_runtime_put(dev); goto unlock_and_return; @@ -568,10 +690,25 @@ static int __maybe_unused ov4689_power_off(struct device *dev) static int ov4689_init_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { - struct v4l2_mbus_framefmt *fmt = - v4l2_subdev_state_get_format(sd_state, 0); + u32 width_def = OV4689_H_OUTPUT_SIZE_DEFAULT; + u32 height_def = OV4689_V_OUTPUT_SIZE_DEFAULT; + + struct v4l2_subdev_selection sel = { + .target = V4L2_SEL_TGT_CROP, + .r.left = OV4689_DUMMY_COLUMNS, + .r.top = OV4689_DUMMY_ROWS, + .r.width = width_def, + .r.height = height_def, + }; + struct v4l2_subdev_format format = { + .format = { + .width = width_def, + .height = height_def, + }, + }; - ov4689_fill_fmt(&supported_modes[OV4689_MODE_2688_1520], fmt); + ov4689_set_selection(sd, sd_state, &sel); + ov4689_set_fmt(sd, sd_state, &format); return 0; } @@ -590,6 +727,7 @@ static const struct v4l2_subdev_pad_ops ov4689_pad_ops = { .get_fmt = v4l2_subdev_get_fmt, .set_fmt = ov4689_set_fmt, .get_selection = ov4689_get_selection, + .set_selection = ov4689_set_selection, }; static const struct v4l2_subdev_internal_ops ov4689_internal_ops = { @@ -635,20 +773,28 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) struct ov4689 *ov4689 = container_of(ctrl->handler, struct ov4689, ctrl_handler); struct regmap *regmap = ov4689->regmap; + struct v4l2_subdev_state *sd_state; struct device *dev = ov4689->dev; + struct v4l2_rect *crop; + s64 max_expo, def_expo; int sensor_gain; - s64 max_expo; int ret; + sd_state = v4l2_subdev_get_locked_active_state(&ov4689->subdev); + crop = v4l2_subdev_state_get_crop(sd_state, 0); + /* Propagate change of current control to all related controls */ switch (ctrl->id) { case V4L2_CID_VBLANK: /* Update max exposure while meeting expected vblanking */ - max_expo = ov4689->cur_mode->height + ctrl->val - 4; - __v4l2_ctrl_modify_range(ov4689->exposure, - ov4689->exposure->minimum, max_expo, - ov4689->exposure->step, - ov4689->exposure->default_value); + max_expo = crop->height + ctrl->val - 4; + def_expo = clamp_t(s64, ov4689->exposure->default_value, + ov4689->exposure->minimum, max_expo); + + ret = __v4l2_ctrl_modify_range(ov4689->exposure, + ov4689->exposure->minimum, + max_expo, ov4689->exposure->step, + def_expo); break; } @@ -666,14 +812,14 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: cci_write(regmap, OV4689_REG_VTS, - ctrl->val + ov4689->cur_mode->height, &ret); + ctrl->val + crop->height, &ret); break; case V4L2_CID_TEST_PATTERN: ret = ov4689_enable_test_pattern(ov4689, ctrl->val); break; case V4L2_CID_HBLANK: cci_write(regmap, OV4689_REG_HTS, - (ctrl->val + ov4689->cur_mode->width) / + (ctrl->val + crop->width) / OV4689_HTS_DIVIDER, &ret); break; case V4L2_CID_VFLIP: @@ -739,14 +885,16 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) hblank_def = mode->hts_def - mode->width; hblank_min = mode->hts_min - mode->width; - v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HBLANK, - hblank_min, OV4689_HTS_MAX - mode->width, - OV4689_HTS_DIVIDER, hblank_def); + ov4689->hblank = v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, + V4L2_CID_HBLANK, hblank_min, + OV4689_HTS_MAX - mode->width, + OV4689_HTS_DIVIDER, hblank_def); vblank_def = mode->vts_def - mode->height; - v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VBLANK, - vblank_def, OV4689_VTS_MAX - mode->height, 1, - vblank_def); + ov4689->vblank = v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, + V4L2_CID_VBLANK, OV4689_VBLANK_MIN, + OV4689_VTS_MAX - mode->height, 1, + vblank_def); exposure_max = mode->vts_def - 4; ov4689->exposure = From patchwork Mon Dec 18 17:40:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497343 Received: from mail-lf1-f46.google.com (mail-lf1-f46.google.com [209.85.167.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6570F7BF1E; Mon, 18 Dec 2023 17:41:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KqYJWlQA" Received: by mail-lf1-f46.google.com with SMTP id 2adb3069b0e04-50bf3efe2cbso3902119e87.2; Mon, 18 Dec 2023 09:41:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921284; x=1703526084; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SHqK0z9IV6ZOZWTMnd7JXt+0Ad1t2MqCYHzreFmr3TI=; b=KqYJWlQAqXL44D+SgOZTUKoAR9vXNBoYIPumTOB52XCdswIemi9CDqWxgZWVzg9zvJ HxpfhSiShEToEKVBUZzm/GrCWpxaA/P99Nq7/Qo6SfjRufz58TwVpg4FW6oCSE3w9fmQ IuQyLvp0BCo4S4GY+hxwiD/qvHWutHZaDl8uPlyjzmI4ml2xrJpFnT/D1Ig8zX8mbQD6 EA7WSZJcb2jbJQ1u66HvlnZzEKwX+B1UBNxepsRK89A57psoweL8cCE8g+SUkOlsX+uZ k7jQls4MHC85fyAe3uqhYgP7wyMD92NU3ClqqcYZV8MmlMjCN+fI2WxsUgQZ2bdVy/VE LM9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921284; x=1703526084; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SHqK0z9IV6ZOZWTMnd7JXt+0Ad1t2MqCYHzreFmr3TI=; b=Y7SkKP+ghhjTpN7F7dbW209nsYbMVkEtdC90W4F7v1hTof7YO+6ch8gxtUCXLkOn5K K6I2ktIVYdqZjEFjLLDgdzPI6iWjMP83tpkJ+pCvD3oLqH7mC9CZ4QfXv1tAj6stFDm4 lv06pPoxUrmFdc5uhWMoki95DfCMBS91sMJYgpvOzBFlul1DiCMdrRaWtlVlhmLh/WVV ZkXscd4aF/zdgWSPtOSAQSnWwFsyI6K/2jbuYz9ls5EPCGkIEHvHLoLkUze+bptx/gUS lQCKF0lH5SqxRnQOQoBT6XZEussWYS9kUjmNqJIgMMGU7SPrFpkDNqd3ud6ny11QHmBt cAPA== X-Gm-Message-State: AOJu0YyhMHrlENDptJioij/WjHRBYXppac+/IdT8BSZv+EXlWiApxJfh vt8iz2C9ImolcLODECXIbSjRijPNbR9jHQ== X-Google-Smtp-Source: AGHT+IEpb4sp6Kfh0nmEz0ULo0Gw9gQBAtjjzpl6Cjjh4YC8PN0rOvZ8HtxbANHht7INMJlMwxwMug== X-Received: by 2002:a05:6512:21cf:b0:50b:e29b:2f01 with SMTP id d15-20020a05651221cf00b0050be29b2f01mr3241140lft.264.1702921284219; Mon, 18 Dec 2023 09:41:24 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id b8-20020ac25628000000b0050bfd8cc09bsm2958946lff.149.2023.12.18.09.41.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:23 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 18/20] media: i2c: ov4689: Eliminate struct ov4689_mode Date: Mon, 18 Dec 2023 20:40:39 +0300 Message-ID: <20231218174042.794012-19-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 With the output frame size now controlled by selection rather than cur_mode, this commit relocates pixel rate and default VTS to defines. Consequently, it removes struct ov4689_mode and the cur_mode field from struct ov4689. Signed-off-by: Mikhail Rudenko --- drivers/media/i2c/ov4689.c | 70 +++++++++----------------------------- 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index d2d3e5517576..e997c3231e85 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -57,6 +57,8 @@ #define OV4689_HTS_MAX 0x7fff #define OV4689_REG_VTS CCI_REG16(0x380e) +/* Default VTS corresponds to 30 fps at default crop and minimal HTS */ +#define OV4689_VTS_DEF 4683 #define OV4689_VTS_MAX 0x7fff #define OV4689_REG_H_WIN_OFF CCI_REG16(0x3810) @@ -94,6 +96,7 @@ #define OV4689_LANES 4 #define OV4689_XVCLK_FREQ 24000000 +#define OV4689_PIXEL_RATE 480000000 #define OV4689_PIXEL_ARRAY_WIDTH 2720 #define OV4689_PIXEL_ARRAY_HEIGHT 1536 @@ -119,24 +122,6 @@ static const char *const ov4689_supply_names[] = { "dvdd", /* Digital core power */ }; -enum ov4689_mode_id { - OV4689_MODE_2688_1520 = 0, - OV4689_NUM_MODES, -}; - -struct ov4689_mode { - enum ov4689_mode_id id; - u32 width; - u32 height; - u32 hts_def; - u32 hts_min; - u32 vts_def; - u32 exp_def; - u32 pixel_rate; - const struct cci_reg_sequence *reg_list; - unsigned int num_regs; -}; - struct ov4689 { struct device *dev; struct regmap *regmap; @@ -152,8 +137,6 @@ struct ov4689 { struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl *exposure, *hblank, *vblank; - - const struct ov4689_mode *cur_mode; }; #define to_ov4689(sd) container_of(sd, struct ov4689, subdev) @@ -172,7 +155,7 @@ struct ov4689_gain_range { * max_framerate 90fps * mipi_datarate per lane 1008Mbps */ -static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { +static const struct cci_reg_sequence ov4689_common_regs[] = { /* System control*/ {CCI_REG8(0x0103), 0x01}, /* SC_CTRL0103 software_reset = 1 */ {CCI_REG8(0x3000), 0x20}, /* SC_CMMN_PAD_OEN0 FSIN_output_enable = 1 */ @@ -273,21 +256,6 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = { {CCI_REG8(0x5503), 0x0f}, /* OTP_DPC_END_L otp_end_address[7:0] = 0x0f */ }; -static const struct ov4689_mode supported_modes[] = { - { - .id = OV4689_MODE_2688_1520, - .width = 2688, - .height = 1520, - .exp_def = 1536, - .hts_def = 10296, - .hts_min = 3432, - .vts_def = 1554, - .pixel_rate = 480000000, - .reg_list = ov4689_2688x1520_regs, - .num_regs = ARRAY_SIZE(ov4689_2688x1520_regs), - }, -}; - static const u64 link_freq_menu_items[] = { 504000000 }; static const char *const ov4689_test_pattern_menu[] = { @@ -584,8 +552,8 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) goto unlock_and_return; ret = cci_multi_reg_write(ov4689->regmap, - ov4689->cur_mode->reg_list, - ov4689->cur_mode->num_regs, + ov4689_common_regs, + ARRAY_SIZE(ov4689_common_regs), NULL); if (ret) { pm_runtime_put_sync(dev); @@ -863,14 +831,12 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) struct i2c_client *client = v4l2_get_subdevdata(&ov4689->subdev); struct v4l2_fwnode_device_properties props; struct v4l2_ctrl_handler *handler; - const struct ov4689_mode *mode; s64 exposure_max, vblank_def; - s64 hblank_def, hblank_min; struct v4l2_ctrl *ctrl; + s64 hblank_def; int ret; handler = &ov4689->ctrl_handler; - mode = ov4689->cur_mode; ret = v4l2_ctrl_handler_init(handler, 15); if (ret) return ret; @@ -881,26 +847,26 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689) ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 0, - mode->pixel_rate, 1, mode->pixel_rate); + OV4689_PIXEL_RATE, 1, OV4689_PIXEL_RATE); - hblank_def = mode->hts_def - mode->width; - hblank_min = mode->hts_min - mode->width; + hblank_def = ov4689_hts_min(OV4689_H_OUTPUT_SIZE_DEFAULT) - + OV4689_H_OUTPUT_SIZE_DEFAULT; ov4689->hblank = v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, - V4L2_CID_HBLANK, hblank_min, - OV4689_HTS_MAX - mode->width, + V4L2_CID_HBLANK, hblank_def, + OV4689_HTS_MAX - OV4689_H_OUTPUT_SIZE_DEFAULT, OV4689_HTS_DIVIDER, hblank_def); - vblank_def = mode->vts_def - mode->height; + vblank_def = OV4689_VTS_DEF - OV4689_V_OUTPUT_SIZE_DEFAULT; ov4689->vblank = v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VBLANK, OV4689_VBLANK_MIN, - OV4689_VTS_MAX - mode->height, 1, - vblank_def); + OV4689_VTS_MAX - OV4689_V_OUTPUT_SIZE_DEFAULT, + 1, vblank_def); - exposure_max = mode->vts_def - 4; + exposure_max = OV4689_VTS_DEF - 4; ov4689->exposure = v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_EXPOSURE, OV4689_EXPOSURE_MIN, exposure_max, - OV4689_EXPOSURE_STEP, mode->exp_def); + OV4689_EXPOSURE_STEP, exposure_max); v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, ov4689_gain_ranges[0].logical_min, @@ -1055,8 +1021,6 @@ static int ov4689_probe(struct i2c_client *client) ov4689->dev = dev; - ov4689->cur_mode = &supported_modes[OV4689_MODE_2688_1520]; - ov4689->xvclk = devm_clk_get_optional(dev, NULL); if (IS_ERR(ov4689->xvclk)) return dev_err_probe(dev, PTR_ERR(ov4689->xvclk), From patchwork Mon Dec 18 17:40:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497344 Received: from mail-lj1-f171.google.com (mail-lj1-f171.google.com [209.85.208.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B23F77BF09; Mon, 18 Dec 2023 17:41:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PTG8rUde" Received: by mail-lj1-f171.google.com with SMTP id 38308e7fff4ca-2cc259392a6so40380091fa.2; Mon, 18 Dec 2023 09:41:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921285; x=1703526085; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0Db9zQ/cEzdabx9SHSYCUhC/ZN+6oeRqIuZFUX0OxwU=; b=PTG8rUdeNkGfdmowl5R1KJTy3z+neKeSws7v5yD1wstCvJwJcF4spM55YveLjCSf3D mH1b207EF+Caj+ublnDu8Ap9wfmwnn09pIs85YhdpSjwtHS9Vptv9VgkkQ3fAdsvnXgV 8ZZmZq4WB+C0m+zOFpLoUnoQSDLhl9eTaYOYVNG6Am9j5/PPv4hmNOjOjLHVm8SEh7LW Y60d9OZHnOPMKwWvHdvucp9beBoNXiiKiI7JIzJJmpiViLSu16KJKvvRbdbkk3KSHgvZ 2NU83GoZlwx8G3ZkaUxFUoMj4Dh2J1cKXsEVvm+u6+S1uANnjcPNuTg6/ea0kYuW2V5x bbbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921285; x=1703526085; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0Db9zQ/cEzdabx9SHSYCUhC/ZN+6oeRqIuZFUX0OxwU=; b=r1+xxZonbHKcPBZJYgXt7o5oMJfkaVL3EhCLau8E2XSp8TV7Lx+9chD7kZbSO9Xj6G oMg+T4gQU4KZwb5lGxHerRRgCXbLhIiE/CSRBRJZ+BEz3KXC4Gj0sDQd1U8BkM9tioqy CTgxDxxHbB18dmsBEx2GxoDvoj0VaPjiFIjmExxcXd17MK1qhxsoqr+vRVfVJRqlhpD4 QEKZa7j90LK6w69wbKVpgauPJmlFgmIWanuT2413aMH+ko7z1UaTbYeXx3aMgVmVoZeF TcwpWh347jK65+tCGvi3dTVIHTPjJ07Yk67oqShWg7vpv3ytZhc45MumP02ZfR1sA0ZL H4Dg== X-Gm-Message-State: AOJu0YxetExudEY1aFXulm/cWD+YnyqqbXOwCpyVMT8SUidT/+E6eldx kCxcID1VcP7dIBuDUIzGOZyMObA9EAwseA== X-Google-Smtp-Source: AGHT+IF9vx4KlzpdrYsIUTYLFL8RO+IiPNxkVU/6Y5Pspf+P2xp+K3abQf+H/+3amsy4xccrqY4b+Q== X-Received: by 2002:a2e:8783:0:b0:2cc:5a63:3903 with SMTP id n3-20020a2e8783000000b002cc5a633903mr1994561lji.79.1702921285505; Mon, 18 Dec 2023 09:41:25 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id k11-20020a2e888b000000b002cc5f5fc8cesm866940lji.63.2023.12.18.09.41.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:25 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 19/20] media: i2c: ov4689: Refactor ov4689_s_stream Date: Mon, 18 Dec 2023 20:40:40 +0300 Message-ID: <20231218174042.794012-20-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Remove repetitive pm_runtime_put calls in ov4689_s_stream function, and call pm_runtime_put once at the end of the "on" branch if any error occurred. Signed-off-by: Mikhail Rudenko --- drivers/media/i2c/ov4689.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index e997c3231e85..884761d02119 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -555,35 +555,26 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) ov4689_common_regs, ARRAY_SIZE(ov4689_common_regs), NULL); - if (ret) { - pm_runtime_put_sync(dev); - goto unlock_and_return; - } + if (ret) + goto cleanup_pm; ret = ov4689_setup_timings(ov4689, sd_state); - if (ret) { - pm_runtime_put(dev); - goto unlock_and_return; - } + if (ret) + goto cleanup_pm; ret = ov4689_setup_blc_anchors(ov4689, sd_state); - if (ret) { - pm_runtime_put(dev); - goto unlock_and_return; - } + if (ret) + goto cleanup_pm; ret = __v4l2_ctrl_handler_setup(&ov4689->ctrl_handler); - if (ret) { - pm_runtime_put_sync(dev); - goto unlock_and_return; - } + if (ret) + goto cleanup_pm; ret = cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, OV4689_MODE_STREAMING, NULL); - if (ret) { +cleanup_pm: + if (ret) pm_runtime_put_sync(dev); - goto unlock_and_return; - } } else { cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, OV4689_MODE_SW_STANDBY, NULL); From patchwork Mon Dec 18 17:40:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 13497345 Received: from mail-lf1-f48.google.com (mail-lf1-f48.google.com [209.85.167.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 831AE7CCF4; Mon, 18 Dec 2023 17:41:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VC63NQrh" Received: by mail-lf1-f48.google.com with SMTP id 2adb3069b0e04-50e2bd8c396so2411634e87.0; Mon, 18 Dec 2023 09:41:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702921287; x=1703526087; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IRiTnlqS+wDESwMpvXxncwcX1oS8JZsmO8J22z01ivM=; b=VC63NQrhnZwQKYmC7rk7p1GF5bwCUgshILv4fqKp9c5VUhe3wJbNOoQV71mI6Uv28B ytDmUVMsbvrWMGC+D5XRs1xvcsAW49w8q1vQUn33M0eI5eXJKHqBJcfojNsdY9EKOnql cWFkIHDXdcWZ5F+gXIror/WmgLDKMZ7lbzdCWbNF1g6rFi0HA+12IcIFl1jAiNpcdzqD T8YbaBsIrUI/lxK2CqZz5grhyZuJ6oyaVf6st6oYBJXb/SftRl3jdNqHPyQDYPaue7s5 l0XAwkdJwYGgXsW53tgHIgwvHSglXdCnpntpRoiAObvqSHrftHBYBQNJ1yOWxy9pEn7/ DPfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702921287; x=1703526087; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IRiTnlqS+wDESwMpvXxncwcX1oS8JZsmO8J22z01ivM=; b=MZIdYrgYxpaQDL4q05o+nRMOrymWXR7Po4hvWR8XzMJnLdieNcosJzdB8FZldxY+wE jFaaC+9n31e20T9O7teWTS8ReUFmBDYkg0NhPk+sCJwWZAKdeNO2Lcj41ncoYY8IzDPh aFSPAigr0UXYK8WjYV2uf0UmykbBrJj1FzqiUXIpNzA8eMpIEkypXh1BdURgNWX2zEMT Lqz2KeVkPkDvR4oOXZLkfiA/gnGh4uinUGhkihXk8IG+9NAYZduzlo2UvVueZLLTNrkA 3QT12jAf8eW/LZV7K3WPgoAiaE+V9BGzQ8QuBf4keMcgBL5TJhoNxrngbQUndH5O5ZFT 63kg== X-Gm-Message-State: AOJu0YyhDRGRA5vRKBJBFmW/xUk2SW8EYOBVVV+uGGz84mu6fis4Rukw s1KEinL9+/IaeQn6H/Y0Wk+gmoNmTlkRBQ== X-Google-Smtp-Source: AGHT+IE1+8r4WKMTSPM85YrKNtt+V8K49GkE7Mk39ZvalLb9gXcJVxYyW28dHNt67xFJMGolSMUBJA== X-Received: by 2002:a05:6512:280c:b0:50e:34e3:8f76 with SMTP id cf12-20020a056512280c00b0050e34e38f76mr1612302lfb.11.1702921286700; Mon, 18 Dec 2023 09:41:26 -0800 (PST) Received: from localhost ([83.149.246.185]) by smtp.gmail.com with ESMTPSA id u10-20020a056512128a00b0050bbb90533bsm2977651lfs.186.2023.12.18.09.41.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Dec 2023 09:41:26 -0800 (PST) From: Mikhail Rudenko To: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sakari Ailus , Laurent Pinchart , Jacopo Mondi , Tommaso Merciai , Christophe JAILLET , Dave Stevenson , Mauro Carvalho Chehab , Mikhail Rudenko Subject: [PATCH v2 20/20] media: i2c: ov4689: Implement 2x2 binning Date: Mon, 18 Dec 2023 20:40:41 +0300 Message-ID: <20231218174042.794012-21-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231218174042.794012-1-mike.rudenko@gmail.com> References: <20231218174042.794012-1-mike.rudenko@gmail.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement 2x2 binning support. Compute best binning mode (none or 2x2) from pad crop and pad format in ov4689_set_fmt. Use output frame size instead of analogue crop to compute control ranges and BLC anchors. Also move ov4689_hts_min and ov4689_update_ctrl_ranges, since they are now also called from ov4689_set_fmt. Update frame timings to accommodate the requirements of binning mode and avoid visual artefacts. Additionally, report 2x2 binned mode in addition to non-binned one in ov4689_enum_frame_sizes. Signed-off-by: Mikhail Rudenko --- drivers/media/i2c/ov4689.c | 192 +++++++++++++++++++++++++------------ 1 file changed, 130 insertions(+), 62 deletions(-) diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index 884761d02119..ca4e116bed0e 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -114,7 +114,7 @@ * Minimum working vertical blanking value. Found experimentally at * minimum HTS values. */ -#define OV4689_VBLANK_MIN 31 +#define OV4689_VBLANK_MIN 35 static const char *const ov4689_supply_names[] = { "avdd", /* Analog power */ @@ -256,6 +256,18 @@ static const struct cci_reg_sequence ov4689_common_regs[] = { {CCI_REG8(0x5503), 0x0f}, /* OTP_DPC_END_L otp_end_address[7:0] = 0x0f */ }; +static const struct cci_reg_sequence ov4689_2x2_binning_regs[] = { + {CCI_REG8(0x3632), 0x05}, /* ADC */ + {CCI_REG8(0x376b), 0x40}, /* Sensor control */ + {CCI_REG8(0x3814), 0x03}, /* H_INC_ODD */ + {CCI_REG8(0x3821), 0x07}, /* TIMING_FORMAT_2 hor_binning = 1*/ + {CCI_REG8(0x382a), 0x03}, /* V_INC_ODD */ + {CCI_REG8(0x3830), 0x08}, /* BLC_NUM_OPTION blc_use_num_2 = 1 */ + {CCI_REG8(0x3836), 0x02}, /* TIMING_REG_36 r_zline_use_num_2 = 1 */ + {CCI_REG8(0x4001), 0x50}, /* BLC DEBUG MODE */ + {CCI_REG8(0x4502), 0x44}, /* ADC synch control*/ +}; + static const u64 link_freq_menu_items[] = { 504000000 }; static const char *const ov4689_test_pattern_menu[] = { @@ -305,18 +317,96 @@ static const struct ov4689_gain_range ov4689_gain_ranges[] = { }, }; +/* + * For now, only 2x2 binning implemented in this driver. + */ +static int ov4689_best_binning(struct ov4689 *ov4689, + const struct v4l2_mbus_framefmt *format, + const struct v4l2_rect *crop, + unsigned int *binning) +{ + const struct v4l2_area candidates[] = { + { crop->width, crop->height }, + { crop->width / 2, crop->height / 2 }, + }; + + const struct v4l2_area *best; + int index; + + best = v4l2_find_nearest_size(candidates, ARRAY_SIZE(candidates), width, + height, format->width, format->height); + if (!best) { + dev_err(ov4689->dev, + "failed to find best binning for requested mode\n"); + return -EINVAL; + } + + index = best - candidates; + *binning = index + 1; + + dev_dbg(ov4689->dev, + "best_binning: crop=%dx%d format=%dx%d binning=%d\n", + crop->width, crop->height, format->width, format->height, + *binning); + + return 0; +} + +/* + * Minimum working HTS value for given output width (found + * experimentally). + */ +static unsigned int ov4689_hts_min(unsigned int width) +{ + return max_t(unsigned int, 3156, 224 + width * 19 / 16); +} + +static void ov4689_update_ctrl_ranges(struct ov4689 *ov4689, unsigned int width, + unsigned int height) +{ + struct v4l2_ctrl *exposure = ov4689->exposure; + struct v4l2_ctrl *vblank = ov4689->vblank; + struct v4l2_ctrl *hblank = ov4689->hblank; + s64 def_val, min_val, max_val; + + min_val = ov4689_hts_min(width) - width; + max_val = OV4689_HTS_MAX - width; + def_val = clamp_t(s64, hblank->default_value, min_val, max_val); + __v4l2_ctrl_modify_range(hblank, min_val, max_val, hblank->step, + def_val); + + min_val = OV4689_VBLANK_MIN; + max_val = OV4689_HTS_MAX - width; + def_val = clamp_t(s64, vblank->default_value, min_val, max_val); + __v4l2_ctrl_modify_range(vblank, min_val, max_val, vblank->step, + def_val); + + min_val = exposure->minimum; + max_val = height + vblank->val - 4; + def_val = clamp_t(s64, exposure->default_value, min_val, max_val); + __v4l2_ctrl_modify_range(exposure, min_val, max_val, exposure->step, + def_val); +} + static int ov4689_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { + struct ov4689 *ov4689 = to_ov4689(sd); struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; + unsigned int binning; + int ret; crop = v4l2_subdev_state_get_crop(sd_state, fmt->pad); format = v4l2_subdev_state_get_format(sd_state, fmt->pad); - format->width = crop->width; - format->height = crop->height; + ret = ov4689_best_binning(ov4689, &fmt->format, crop, &binning); + if (ret) + return ret; + + format->width = crop->width / binning; + format->height = crop->height / binning; format->code = MEDIA_BUS_FMT_SBGGR10_1X10; format->field = V4L2_FIELD_NONE; @@ -327,6 +417,9 @@ static int ov4689_set_fmt(struct v4l2_subdev *sd, fmt->format = *format; + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) + ov4689_update_ctrl_ranges(ov4689, format->width, format->height); + return 0; } @@ -346,8 +439,9 @@ static int ov4689_enum_frame_sizes(struct v4l2_subdev *sd, struct v4l2_subdev_frame_size_enum *fse) { const struct v4l2_rect *crop; + int binning; - if (fse->index >= 1) + if (fse->index >= 2) return -EINVAL; if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10) @@ -355,10 +449,11 @@ static int ov4689_enum_frame_sizes(struct v4l2_subdev *sd, crop = v4l2_subdev_state_get_crop(sd_state, 0); - fse->min_width = crop->width; - fse->max_width = crop->width; - fse->max_height = crop->height; - fse->min_height = crop->height; + binning = fse->index + 1; + fse->min_width = crop->width / binning; + fse->max_width = crop->width / binning; + fse->max_height = crop->height / binning; + fse->min_height = crop->height / binning; return 0; } @@ -398,42 +493,6 @@ static int ov4689_get_selection(struct v4l2_subdev *sd, return -EINVAL; } -/* - * Minimum working HTS value for given output width (found - * experimentally). - */ -static unsigned int ov4689_hts_min(unsigned int width) -{ - return max_t(unsigned int, 3156, 224 + width * 19 / 16); -} - -static void ov4689_update_ctrl_ranges(struct ov4689 *ov4689, - struct v4l2_rect *crop) -{ - struct v4l2_ctrl *exposure = ov4689->exposure; - struct v4l2_ctrl *vblank = ov4689->vblank; - struct v4l2_ctrl *hblank = ov4689->hblank; - s64 def_val, min_val, max_val; - - min_val = ov4689_hts_min(crop->width) - crop->width; - max_val = OV4689_HTS_MAX - crop->width; - def_val = clamp_t(s64, hblank->default_value, min_val, max_val); - __v4l2_ctrl_modify_range(hblank, min_val, max_val, hblank->step, - def_val); - - min_val = OV4689_VBLANK_MIN; - max_val = OV4689_HTS_MAX - crop->width; - def_val = clamp_t(s64, vblank->default_value, min_val, max_val); - __v4l2_ctrl_modify_range(vblank, min_val, max_val, vblank->step, - def_val); - - min_val = exposure->minimum; - max_val = crop->height + vblank->val - 4; - def_val = clamp_t(s64, exposure->default_value, min_val, max_val); - __v4l2_ctrl_modify_range(exposure, min_val, max_val, exposure->step, - def_val); -} - static int ov4689_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel) @@ -470,7 +529,8 @@ static int ov4689_set_selection(struct v4l2_subdev *sd, format->height = rect.height; if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) - ov4689_update_ctrl_ranges(ov4689, &rect); + ov4689_update_ctrl_ranges(ov4689, rect.width, + rect.height); } *crop = rect; @@ -485,21 +545,27 @@ static int ov4689_setup_timings(struct ov4689 *ov4689, const struct v4l2_mbus_framefmt *format; struct regmap *rm = ov4689->regmap; const struct v4l2_rect *crop; + const int v_offset = 2; + unsigned int binning; int ret = 0; format = v4l2_subdev_state_get_format(state, 0); crop = v4l2_subdev_state_get_crop(state, 0); + ret = ov4689_best_binning(ov4689, format, crop, &binning); + if (ret) + return ret; + cci_write(rm, OV4689_REG_H_CROP_START, crop->left, &ret); - cci_write(rm, OV4689_REG_V_CROP_START, crop->top, &ret); - cci_write(rm, OV4689_REG_H_CROP_END, crop->left + crop->width + 1, &ret); - cci_write(rm, OV4689_REG_V_CROP_END, crop->top + crop->height + 1, &ret); + cci_write(rm, OV4689_REG_V_CROP_START, crop->top - v_offset, &ret); + cci_write(rm, OV4689_REG_H_CROP_END, crop->left + crop->width + 3, &ret); + cci_write(rm, OV4689_REG_V_CROP_END, crop->top + crop->height + 7, &ret); cci_write(rm, OV4689_REG_H_OUTPUT_SIZE, format->width, &ret); cci_write(rm, OV4689_REG_V_OUTPUT_SIZE, format->height, &ret); cci_write(rm, OV4689_REG_H_WIN_OFF, 0, &ret); - cci_write(rm, OV4689_REG_V_WIN_OFF, 0, &ret); + cci_write(rm, OV4689_REG_V_WIN_OFF, v_offset, &ret); /* * Maximum working value of vfifo_read_start for given output @@ -507,6 +573,10 @@ static int ov4689_setup_timings(struct ov4689 *ov4689, */ cci_write(rm, OV4689_REG_VFIFO_CTRL_01, format->width / 16 - 1, &ret); + if (binning == 2) + cci_multi_reg_write(ov4689->regmap, ov4689_2x2_binning_regs, + ARRAY_SIZE(ov4689_2x2_binning_regs), + &ret); return ret; } @@ -519,20 +589,20 @@ static int ov4689_setup_blc_anchors(struct ov4689 *ov4689, struct v4l2_subdev_state *state) { unsigned int width_def = OV4689_H_OUTPUT_SIZE_DEFAULT; + const struct v4l2_mbus_framefmt *format; struct regmap *rm = ov4689->regmap; - const struct v4l2_rect *crop; int ret = 0; - crop = v4l2_subdev_state_get_crop(state, 0); + format = v4l2_subdev_state_get_format(state, 0); cci_write(rm, OV4689_REG_ANCHOR_LEFT_START, - OV4689_ANCHOR_LEFT_START_DEF * crop->width / width_def, &ret); + OV4689_ANCHOR_LEFT_START_DEF * format->width / width_def, &ret); cci_write(rm, OV4689_REG_ANCHOR_LEFT_END, - OV4689_ANCHOR_LEFT_END_DEF * crop->width / width_def, &ret); + OV4689_ANCHOR_LEFT_END_DEF * format->width / width_def, &ret); cci_write(rm, OV4689_REG_ANCHOR_RIGHT_START, - OV4689_ANCHOR_RIGHT_START_DEF * crop->width / width_def, &ret); + OV4689_ANCHOR_RIGHT_START_DEF * format->width / width_def, &ret); cci_write(rm, OV4689_REG_ANCHOR_RIGHT_END, - OV4689_ANCHOR_RIGHT_END_DEF * crop->width / width_def, &ret); + OV4689_ANCHOR_RIGHT_END_DEF * format->width / width_def, &ret); return ret; } @@ -734,19 +804,19 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) struct regmap *regmap = ov4689->regmap; struct v4l2_subdev_state *sd_state; struct device *dev = ov4689->dev; - struct v4l2_rect *crop; + struct v4l2_mbus_framefmt *fmt; s64 max_expo, def_expo; int sensor_gain; int ret; sd_state = v4l2_subdev_get_locked_active_state(&ov4689->subdev); - crop = v4l2_subdev_state_get_crop(sd_state, 0); + fmt = v4l2_subdev_state_get_format(sd_state, 0); /* Propagate change of current control to all related controls */ switch (ctrl->id) { case V4L2_CID_VBLANK: /* Update max exposure while meeting expected vblanking */ - max_expo = crop->height + ctrl->val - 4; + max_expo = fmt->height + ctrl->val - 4; def_expo = clamp_t(s64, ov4689->exposure->default_value, ov4689->exposure->minimum, max_expo); @@ -770,16 +840,14 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) cci_write(regmap, OV4689_REG_GAIN, sensor_gain, &ret); break; case V4L2_CID_VBLANK: - cci_write(regmap, OV4689_REG_VTS, - ctrl->val + crop->height, &ret); + cci_write(regmap, OV4689_REG_VTS, ctrl->val + fmt->height, &ret); break; case V4L2_CID_TEST_PATTERN: ret = ov4689_enable_test_pattern(ov4689, ctrl->val); break; case V4L2_CID_HBLANK: cci_write(regmap, OV4689_REG_HTS, - (ctrl->val + crop->width) / - OV4689_HTS_DIVIDER, &ret); + (ctrl->val + fmt->width) / OV4689_HTS_DIVIDER, &ret); break; case V4L2_CID_VFLIP: cci_update_bits(regmap, OV4689_REG_TIMING_FORMAT1,